In-memory note-taking system with keyword search

0
Sign in

Design an in-memory note-taking system, SecondBrainSystem. Each note gets a unique id and carries metadata about when it was created and last modified. Callers pass the current time into every write, so behavior is deterministic.

API

class SecondBrainSystem:
    def __init__(self) -> None: ...
    def create_note(self, timestamp: int, title: str, content: str) -> str: ...
    def get_note(self, note_id: str) -> Note | None: ...
    def update_note(self, timestamp: int, note_id: str,
                    title: str | None = None, content: str | None = None) -> bool: ...
    def delete_note(self, note_id: str) -> bool: ...
    def list_notes(self) -> list[str]: ...
    def search(self, query: str) -> list[str]: ...
  • create_note returns a new id: "note1", "note2", and so on. Ids are never reused, even after a delete. Both created_at and modified_at are set to timestamp.
  • get_note returns the note (id, title, content, created_at, modified_at), or None if it does not exist. Changing the returned object must not change the stored note.
  • update_note changes only the fields that are given and sets modified_at to timestamp. It returns False for an unknown id. A call with no fields changes nothing. Raise ValueError if timestamp is earlier than the note's modified_at.
  • delete_note returns True if the note existed, else False.
  • list_notes returns all ids, most recently modified first. Ties go to the note created first.
  • search splits the query into lowercase words of letters and digits. It returns the ids of notes whose title or content contains every query word, in the same order as list_notes. An empty query returns [].

Example

create_note(1, "Raft notes", "Leader election uses randomized timeouts.")  -> "note1"
create_note(2, "Groceries", "eggs, milk, leader brand coffee")             -> "note2"
search("leader")            -> ["note2", "note1"]
search("LEADER election")   -> ["note1"]
update_note(5, "note1", content="Log replication.") -> True
search("election")          -> []
get_note("note1")           -> title "Raft notes", created_at 1, modified_at 5
delete_note("note2")        -> True
create_note(8, "c", "")     -> "note3"

Constraints

  • Up to 10^5 notes and 10^5 operations. Notes are up to 10^4 characters.
  • Searches are frequent, so a full scan per query is too slow. State the time and space cost of each operation.
  • Expect follow-up parts (for example tags, version history, or links between notes). Keep the design easy to extend.

Reconstructed from the reported question; details may differ from what interviewers ask.

AnthropicCodingMedium

Sign in to see the worked answer

The full answer, chapter by chapter, with what interviewers expect at each level. Free with an account: one full answer per company.