← Questions

Thread-safe in-memory key-value store

0
NetflixCodingLast asked Nov 2025

Inside one process, many worker threads share a simple in-memory key-value store, and any thread can read, write or delete keys at any time. Design and implement a thread-safe store, discuss how to reduce lock contention, and explain how you would show it is correct.

Interface

Unless you agree on a different interface with the interviewer, assume:

  • put(key: str, value: Any) -> None inserts or overwrites.
  • get(key: str) -> Any | None returns the current value or None.
  • delete(key: str) -> bool removes the key and returns whether it existed.
  • Each operation is atomic: no lost updates, no torn or corrupted internal state.

Example

store.put("model", "v1")
store.get("model")        ->  "v1"
store.put("model", "v2")
store.delete("model")     ->  True
store.delete("model")     ->  False
store.get("model")        ->  None

Under concurrency: if 8 threads each put 10,000 distinct keys, the store ends with exactly 80,000 keys.

Constraints

  • Single process, multiple threads; no distribution.
  • Keys are strings; values are arbitrary objects.
  • Implement it in a language without a built-in concurrent map (for example Python with a plain dict).

Clarifying questions

  • What is the read/write ratio, and how many threads?
  • Do callers need compound atomic operations such as put_if_absent or compare-and-set?
  • Is iteration over all keys needed, and must it be a consistent snapshot?
  • Are there memory limits, TTLs or persistence requirements?

What a strong answer covers

  • The data structure: a hash map, and why.
  • Synchronization options with trade-offs: one global lock (simple, contended), a reader-writer lock, lock striping (N locks chosen by hash(key) % N, each guarding its own sub-map), per-key locks and their memory cost, and lock-free or copy-on-write approaches.
  • An implementation of put, get and delete with striping, and how compound operations stay atomic within a stripe.
  • Testing: unit tests, concurrent stress tests that check invariants afterwards, randomized interleavings, and tools such as thread sanitizers where the language has them.
  • Production concerns: input validation, metrics on lock wait time, capacity limits, logging, and persistence if needed.

Follow-ups

  • Add compare_and_set(key, expected, new).
  • Add an atomic size() and a consistent snapshot iterator.
  • Add LRU eviction under a capacity limit: what happens to your striping?
Write and test your solution herePython in your browser, the question's tests level by level, every submission kept for you.Sign in to start coding