~/problems

Problems

Basics first, then the classics, then company-style assessments. Every problem has tests you run right here; multi-level ones unlock as you go. See the roadmap.

Streams & durability

Serialization and durability

Length-prefixed encodings, write-ahead logs, checkpoints and recovery.

Notes

Recognise it when: you persist a key-value store to disk, need crash recovery, or design a binary format and must handle arbitrary bytes, including delimiters inside values.

  • Length-prefixed encoding: len(key) | key | len(value) | value, with fixed-width lengths (struct.pack(">I", n)). Never use delimiters; the data may contain them.
  • Write-ahead log: append the operation, flush (and os.fsync for real durability), then apply it in memory. On startup, replay the log. Compact periodically by writing a snapshot, then truncating the log.
  • Torn writes: a crash mid-record leaves a partial tail. Detect it with the length and a checksum (zlib.crc32) and truncate.
  • Chunking: split large values into bounded chunks with sequence numbers, and reassemble them in order.
  • Checkpointing iterators or batchers: persist the minimal state needed to resume exactly (cursor, RNG state, epoch).

Gotchas: endianness, the str vs bytes distinction, and flush vs fsync.

5 problems

Practical systems

Streams & durability Rate counters, serialization, retrying work queues.

esc