Software Engineer.

Standard Notes v/s Day One


    • Day One: all the note-taking features of SN; offers social media integration; and, offers some features not available on SN.
    • Standard Notes: has all the note-taking features of D1; has some features not available on D1; but, is way better for privacy.
    • Day One: lacks in Privacy and Security compared to SN.
    • Standard Notes: all the same note-taking features but lacks some UI features and social media integration option offered by Day One. 


    • ❌ feature unavailable  ☠ 
    • ✅ Feature Available ◎
    • ✔ Feature Available But Comparatively Not As Convenient As The Other App ⚛

    Evaluation CategorySubcategoryFunctionDay OneStandard NotesNote
    SafetyNotes PrivacyNotes End-to-End Encryption✅ ✔❌

    Day One:

    1. ✔notes content is encrypted when sent from your device to Day One Servers,
    2. ✅Notes are encrypted on Day One Servers; BUT
    4. ❌notes metadata is NOT ENCRYPTED on servers.

    SN: standard notes encrypts data on your device, over the network, and on its server.

    1. You need to use App Passcode for SN to encrypt data on your device.
    2. Without app passcode, app data is stored in plaintext on the device.

    SafetyNotes PrivacyEncrypted Note Metadata

    Day One tracks following Note Metadata which is NOT ENCRYPTED ❌:

    1. Note Create Datetime ❌
    2. Note Edit Datetime ❌
    3. Names of Journals ❌
    4. Total Number of Journals ❌
    5. Total Number of Notes ❌
    6. Total Number of Images ❌
    7. Attachment Image Type & Size ❌
    8. Device Info ❌

    Source: https://dayoneapp.com/blog/end-to-end-encryption-for-day-one-sync

    SN does NOT ENCRYPT the following Note metadata:

    1. Note Create Datetime❌
    2. Note Modified Datetime ❌
    3. Note Type (Note or Tag/Folder) ❌
    4. Browser ❌
    SafetyUser PrivacySafe Personal Info

    Day One collects and shares Name, Address, IP Address, Location, Device ID.

    SN: collects no user information.

    SafetyUser PrivacyNo Tracking

    Day One Tracks Location, Time, Day to add to note.

    SN: collects no user information.

    User PrivacySafe Behavior Info

    Day One uses Google Analytics to track and analyze your behavior.

    SN: does not run any analytics software, BUT

    1. To avoid spamming, SN Servers Firewall stores IP Address for 5 Minutes, but the IP addresses are not logged in long-term storage.
    SafetyApp SecurityApp Password 

    App SecurityBiometrics Password

    DevicesApp UsabilityUnlimited Number of Devices

    Integrate with SM

    Day One integrates Instagram
    SN offers no integration.
    FeaturesNotes-StorageUnlimited Notes

    FeaturesNotes-StorageUnlimited Cloud Backup


    Notes-StorageExport Backup

    Notes-StorageExport Encrypted Backup

    Notes-CreationRich Formatting Editors

    Notes-CreationPublish Note To Blog

    Notes-CreationOffline Notes


    Note-CreationNote Templates

    Day One; provides note templates like "Meal logging note".

    SN; has a built-in Spreadsheet editor which allows you to create notes in in-app spreadsheets.

    • Spreadsheet in one note is limited to 70 rows, but allows multiple sheets/tabs within a single note.

    Day One: Needs to be checked.

    Note-InfoNote Statistics

    Word and character counts for a note.
    Notes-BrowsingSearch By Note Content

    Notes BrowsingSearch By Tag

    Day One: Search Function allows searching by tags out-of-the-box.

    Standard Notes: has Smart Tags which allows you to create "Views" to "View All Notes With This Tag" in a single place.

    Notes Browsing
    Activity Feed

    Day One: has an in-built UI for activity wall.

    SN: has Smart Tags instead of UI elements that allow you to create any sort of "Views"  view your activity like "All Notes Created/Updated On-This-Day/Days/Years/Weeks/Days Ago" in a single place.
    Notes-BrowsingCalendar View

    Day One: has an in-built Calendar view which shows the days on which notes were taken.

    SN: no in-built Calendar View, but allows you to create "Views" using smart tags/folders to View Activity like "All Notes Created/Updated On This Day A Years/Weeks/Days Ago" in a single place.

    Notes-BrowsingMap View

    Day One: Show locations of notes.

    SN: does not track location data.

    AttachmentsUnlimited Images Attachment

    Standard Notes has a file size limit of 50 MB on attachments.

    Day One: Needs to be checked.


    Encrypted Images Attachment

    AttachmentsUnlimited Audio/Video Attachment

    SN: Attachment file-size limit of 50MB
    AttachmentsUnlimited File Attachment

    FeaturesToolsIn-built 2FA App

    SN: has a built-in 2FA editor which can be used to generate 2FA OTP for other apps/websites/accounts.

    ToolsBrowser Extensions

    ToolsSiri Shortcuts


    Day One: allows integration with Apple Health App to track the time spent on the app as "mindful time".

    Day One: allows you to import data from YouTube, Facebook, Spotify, Twitter, Fitbit etc.
    Customer Support
    Regular Support

    Customer Support
    Ephemeral Support

    SN: allows you to send support requests which get deleted after a time (set by you) by using the ProtonMail Disappearing Mail functionality: they offer a SN ProtonMail email support account.
    AvailabilityAccount & Data Lifespan

    Day One:

    1. will sell your data in case of merger or take over. 
    2. no information available about what happens to your data if the company shuts down.


    1. does not analyze or share data.
    2. provides tool to retain and keep using the app in case the company shuts down.
      1. provides a self-hosting option.

    Books: Notes From PowerSexSuicide By Nick Lane

    Mitochondria and Egg Cells: Why (mostly) uniparental inheritence?

    • The Mitochondria in a cell is almost always, but not always, inherited from the mother to eliminate the cytoplasmic competition between two different cytoplasmic components (from different gametes).
      • Mitochondrial DNA gets recombined, when needed, with the damaged genes getting replaced with copies from other chromosomes.
      • Yeasts, Rats, and Bats can recombine mitchondrial DNA
      • There's a recorded case of a human having heart cells containing mitochondria from the father.
    • In a fertilized egg, the mitochondria from the male is either eliminated or selectively silenced, almost always.
    • The zygote (the fertilized egg cell) contains 100,000 mitochondria 99.99% coming from the mother.
    • The zygote divides a number of times within first two weeks to form the embryo: every time the zygote divides the 100,000 mitochondria are distributed among the new cells.
    • Until mitochondria themselves start dividing (asexual reproduction), no new mitochondria are formed during this (first two weeks') period, and the new embryo cells must utilise whatever mitochondria are available to them for their development: any embryo cells that cannot do this die.
    • If the embryo is a female embryo, the egg cells start forming after two/three weeks, and contain around 10 mitochondria, each containing just a single copy of the chromosomes: there's variation in the mitochondrial sequences within these oocytes, and more than 50% contain errors in the DNA sequence.
      • The mitochondrial DNA is verified for a match against the nuclear DNA
    • The number of egg cells formed in a female embryo is around 100 after the first three weeks --> seven million after five months --> two million after birth --> 300,000 by menstruation --> 25,000 by age 40: only 200 of which ovulate during female's reproductive life.

    Mitochondria and Ageing: Anti-oxidants do not increase lifespan

    • Denham Harman proposed relation between free-radicals and ageing in 1972: theorized that higher metabolism rate leads to higher free-radicals which cause higher cell damage leading to cell death and, consequently, ageing.
    • Richard Cutler, in 1980's, showed -- erroneously -- that long-lived animals have a higher levels on anti-oxidants in their cells, and conversely, short-lived animals have lower anti-oxidant levels: the data was flawed since he divided the number of anti-oxidants by the metabolic rate in the respective organism, which has the following problems:
      • Opposite is true: a short-lived rat with higher metabolic rate (7 times human metabolic rate) also has a higher anti-oxidant concentration.
      • Several independent studies have confirmed a negative correlation between the antioxidant level and lifespan i.e. the lifespan decreases with the increase in antioxidants: a correlation not causation, since the lifespan is independent of antioxidant concentration.
      • The levels of antioxidant is maintained wrt the metabolic rate: low-for-low/high-for-high to maintain a flexible redox state within the cell.

    Java: Serialization

    Notes and Format

    • What: Convert an object into a stream of bytes by storing the state of the object.
    • What gets stored in the byte stream:
      • The member variables/fields
      • function signature (but NOT the function's code) impacts the bytes created for the object
    • How: "The default serialization mechanism for an object writes the class of the
      object, the class signature, and the values of all non-transient and
      non-static fields. References to other objects (except in transient or
      static fields) cause those objects to be written also. Multiple references
      to a single object are encoded using a reference sharing mechanism so that
      graphs of objects can be restored to the same shape as when the original was
    • How: "The default deserialization mechanism for objects restores the contents
      of each field to the value and type it had when it was written. Fields
      declared as transient or static are ignored by the deserialization process.
      References to other objects cause those objects to be read from the stream
      as necessary. Graphs of objects are restored correctly using a reference
      sharing mechanism. New objects are always allocated when deserializing,
      which prevents existing objects from being overwritten."

      "Reading an object is analogous to running the constructors of a new
      object. Memory is allocated for the object and initialized to zero (NULL).
      No-arg constructors are invoked for the non-serializable classes and then
      the fields of the serializable classes are restored from the stream starting
      with the serializable class closest to java.lang.object and finishing with
      the object's most specific class. "  

    • Important: With respect to byte streams, notes on closing the streams:
      • For an output stream, calling close() ensures that the data gets written to its destination (file or whathaveyou); not closing the stream will result in the data being in the buffer without being written to its destination.
      • For an input stream, a file descriptor is associated with the stream, and is stored in the file descriptor table; consequently, the file descriptor table can run out of space if there is a lot of unclosed file streams, and may stop the program from opening new files -- which can be problematic. Close your input file streams.
    • Important: it introduces vulnreability in the code since the serialized byte stream can be easily edited to change bytes such that some invariant of the serialized object is broken.
    • source https://docs.oracle.com/javase/7/docs/platform/serialization/spec/protocol.html#10258

    Stream Format:

    • Stream Format For Classes

      Magic NumberVersion UIDclassNameserialVersionUIDhandleclassDescFlags bytefield1TypeCode field1NamefieldNTypeCode fieldNName <classNameForFieldOfObjectType>

    • Stream Format For Objects        

    Magic NumberVersion UIDclassNameserialVersionUIDhandleclassDescFlags bytefield1TypeCode field1NamefieldNTypeCode fieldNName <classNameForFieldOfObjectType>

    classData[]: fieldsInClass, bytesForPrimitives

    magic version contents

    content contents content

    object: classes, outputStream Objects, Enums

    blockdata: primitive dataTypes

    • "All of the write methods for primitive types encode their values using a DataOutputStream to put them in the standard stream format. The bytes are buffered into block data records so they can be distinguished from the encoding of objects. This buffering allows primitive data to be skipped if necessary for class versioning. It also allows the stream to be parsed without invoking class-specific methods."

    Codes used in the serialized data:


    B = byte

    C = char

    D = double

    F = float

    I = integer

    J =long

    S = short

    Z = boolean


    [ = array

    L = object

    final static short STREAMMAGIC = (short)0xaced;
        final static short STREAMVERSION = 5;
        final static byte TCNULL = (byte)0x70;
        final static byte TCREFERENCE = (byte)0x71;
        final static byte TCCLASSDESC = (byte)0x72;
        final static byte TCOBJECT = (byte)0x73;
        final static byte TCSTRING = (byte)0x74;
        final static byte TCARRAY = (byte)0x75;
        final static byte TCCLASS = (byte)0x76;
        final static byte TCBLOCKDATA = (byte)0x77;
        final static byte TCENDBLOCKDATA = (byte)0x78;
        final static byte TCRESET = (byte)0x79;
        final static byte TCBLOCKDATALONG = (byte)0x7A;
        final static byte TCEXCEPTION = (byte)0x7B;
        final static byte TCLONGSTRING = (byte) 0x7C;
        final static byte TCPROXYCLASSDESC = (byte) 0x7D;
        final static byte TC_ENUM = (byte) 0x7E;
        final static  int   baseWireHandle = 0x7E0000;

    Serialization Vulnerability Demonstration Code:
    <add after lunch>

    Java: Volatile and Synchronized

    Gist: a volatile variable isn't enough synchronization.

    In Java, a "volatile" field is often presented as a weaker form of synchronization: a field that's specifically indicated to the compiler and runtime as "not-to-be-reordered", which, consequently, doesn't get cached; it is guaranteed to return the most recent write on the field to any threads accessing that field.

    Because "most recent write" doesn't always imply "every write", using volatile as a form of synchronization could become problematic.

    Consider the code below where the starting balance (represented by volatile member variable balance) is 0; two threads (the main thread, and another created (thread) change the balance to add 100 and 51000 respectively. After execution, one'd expect the final balance to be 51100 (100+51000) for a synchronized operation; however, that isn't what happens: on my machine, the final balance takes values like 51100, 51099, 51000 etc. See the output following the code.

    import java.lang.Thread;
    /* Over several executions of the program,
     a write to the  volatile variable "balance" 
     either by the main thread or by the created thread 
     is lost i.e. overwritten*/
    public class ThreadTest
    volatile int balance = 0;
    public void deposit(int val)
    balance = balance+val;

    public void credit(int val)
    balance = balance-val;
    public void debit(int val) 
    Thread internalThread = new Thread(new Runnable(){
    public void run()
    System.out.println("pre-change balance in second thread is: "+Integer.toString(balance));

    System.out.println("post-change balance in second thread is: "+Integer.toString(balance));
    catch(Exception ioe)
    System.out.println("error in debit thread run.");

    catch(Exception ioe)
    System.out.println("error in debit().");

    public static void main(String[] args)  throws InterruptedException
    System.out.println("Main Thread started");
    ThreadTest tt = new ThreadTest();

    System.out.println("Main Thread starting balance is: "+Integer.toString(tt.balance));

    // alter balance from a new thread

    // alter balance from the main thread
    for(int i = 1;i<=51000; i++)

    System.out.println("Main Thread changed balance is: "+Integer.toString(tt.balance));

    [my-pc java]$ java ThreadTest  
    Main Thread started
    Main Thread starting balance is: 0
    pre-change balance in second thread is: 1420
    post-change balance in second thread is: 2837
    Main Thread changed balance is: 51000
    [my-pc java]$ java ThreadTest        
    Main Thread started
    Main Thread starting balance is: 0
    pre-change balance in second thread is: 935
    post-change balance in second thread is: 1619
    Main Thread changed balance is: 51100

    In the same code, simply marking the method "deposit()" as synchronized ensures that the final balance is always 51100. Of course, the choice of using a synchronized method or a synchronized block is situational.