PracHub
QuestionsCoachesLearningGuidesInterview Prep

Quick Overview

Implement a versioned in-memory database with TTL-aware writes, tombstones, prefix scans, and historical reads. The exercise emphasizes deterministic same-timestamp ordering, atomic validation, indexed per-key history, and clear performance trade-offs.

  • hard
  • Anthropic
  • Coding & Algorithms
  • Software Engineer

Build a Versioned In-Memory Database

Company: Anthropic

Role: Software Engineer

Category: Coding & Algorithms

Difficulty: hard

Interview Round: Onsite

# Build a Versioned In-Memory Database The source reports a four-stage in-memory database exercise but does not provide its exact method signatures. The following driver, return values, and error rules are a deterministic practice contract. Implement `VersionedDatabase` with these methods: ```python class VersionedDatabase: def set(self, timestamp: int, key: str, value: str, ttl: int | None = None) -> bool: ... def get(self, timestamp: int, key: str) -> str | None: ... def delete(self, timestamp: int, key: str) -> bool: ... def scan_prefix(self, timestamp: int, prefix: str) -> list[list[str]]: ... def get_at(self, timestamp: int, key: str, as_of_timestamp: int) -> str | None: ... ``` Also implement the literal-input console driver: ```python def run_versioned_database(operations: list[list[object]]) -> list[object]: ... ``` Process operations in list order and return one result per operation: - `["SET", timestamp, key, value]` calls `set(..., ttl=None)` and returns `True`. - `["SET", timestamp, key, value, ttl]` creates a version visible on `[timestamp, timestamp + ttl)` and returns `True`. - `["GET", timestamp, key]` returns the visible value or `None`. - `["DELETE", timestamp, key]` returns `True` and writes a tombstone only when the key is visible at that point. It returns `False` and writes nothing when the key is absent or expired. - `["SCAN_PREFIX", timestamp, prefix]` returns `[[key, value], ...]` for all visible keys beginning with `prefix`, ordered by key ascending. An empty prefix matches every visible key. - `["GET_AT", timestamp, key, as_of_timestamp]` returns the value visible at `as_of_timestamp`, or `None` if the key had no live version then. Every write, overwrite, and successful delete is an immutable version. A later version supersedes an earlier one for current reads but does not erase history. A non-expiring write stays live until superseded. Expiration does not delete history. Historical lookup chooses the most recent already-processed version whose `(timestamp, operation order)` is at or before the requested time and then applies that version's TTL and tombstone state. ## Deterministic Ordering and Errors - Operation timestamps and `as_of_timestamp` values are nonnegative integers. Operation timestamps are nondecreasing; operations sharing a timestamp take effect in list order. - A query observes only operations processed before that query. Because operation timestamps never decrease, a later query for an earlier timestamp sees every operation at that earlier timestamp that has already appeared in the list. - `as_of_timestamp` must not exceed the query's `timestamp`. - Keys and values are strings; keys and values may be empty. TTL, when present, is a positive integer. - A malformed operation, unknown command, decreasing timestamp, invalid TTL, or future `as_of_timestamp` raises `ValueError`. Validate such an operation before changing state. Ordinary misses use the `None` or `False` results above and are not exceptions. ## Performance Expectations Discuss the cost of point reads and writes, prefix scans, and historical reads. Historical lookup should use per-key ordered history rather than replaying the full database log. Test exact expiration boundaries, overwrites at the same timestamp, expired deletes, delete-then-recreate, empty prefixes, and queries before the first version.

Quick Answer: Implement a versioned in-memory database with TTL-aware writes, tombstones, prefix scans, and historical reads. The exercise emphasizes deterministic same-timestamp ordering, atomic validation, indexed per-key history, and clear performance trade-offs.

Process a sequence of operations against a versioned in-memory key-value database and return **one result per operation**, in order. Each operation is a list whose first element is the command name and whose second element is an integer `timestamp`. Timestamps are **nondecreasing** across the sequence. - `["SET", t, key, value]` or `["SET", t, key, value, ttl]` — store a new immutable version of `key`. With `ttl` (a positive integer), the version is valid for the half-open interval `[t, t + ttl)` — it expires **exactly at** `t + ttl`. Result: `True`. - `["GET", t, key]` — the value of `key` visible at time `t`, or `None` if the key has no visible value (never set, deleted, or expired). - `["DELETE", t, key]` — if `key` has a visible value at `t`, record a tombstone (reads at time `>= t` see nothing) and return `True`; otherwise return `False`. Earlier versions remain readable through `GET_AT`. - `["SCAN_PREFIX", t, prefix]` — every `[key, value]` pair whose key starts with `prefix` and is visible at `t`, sorted by key ascending. - `["GET_AT", t, key, as_of]` — **historical read**: the value that was visible at time `as_of` (`0 <= as_of <= t`), considering only versions written at timestamps `<= as_of`. Tombstones and TTL expiry are evaluated as of `as_of`. Returns `None` if nothing was visible then. **Visibility rule** (shared by `GET`, `SCAN_PREFIX`, and `GET_AT`): the most recently written version with version timestamp `<=` the read time wins; the result is `None` when that version is a tombstone or the read time is `>=` its expiry.

Constraints

  • Operation timestamps are nonnegative integers in nondecreasing order; equal timestamps execute in list order.
  • SET accepts string keys and values and an optional positive integer TTL.
  • GET_AT may not request a time later than its query timestamp.
  • SCAN_PREFIX returns visible key-value pairs sorted by key.
  • Malformed operations raise ValueError before changing state.

Examples

Input: ([["SET", 1, "a", "x"], ["GET", 1, "a"]],)

Expected Output: [True, "x"]

Explanation: A value is visible immediately at the write timestamp.

Input: ([["SET", 2, "a", "x", 3], ["GET", 4, "a"], ["GET", 5, "a"]],)

Expected Output: [True, "x", None]

Explanation: TTL validity is half-open, so expiration occurs exactly at timestamp 5.

Hints

  1. Store an ordered version history per key instead of replaying the entire log.
  2. A historical lookup can scan backward from the newest version at or before the requested timestamp.
  3. Treat expiration as half-open and tombstones as ordinary immutable versions.
Last updated: Jul 15, 2026

Loading coding console...

PracHub

Master your tech interviews with 8,500+ real questions from top companies.

Product

  • Questions
  • Learning Tracks
  • Interview Guides
  • Resources
  • Premium
  • For Universities

Browse

  • By Company
  • By Role
  • By Category
  • Topic Hubs
  • SQL Questions
  • AI Coding Questions
  • Compare Platforms
  • Discord Community

Support

  • support@prachub.com
  • (916) 541-4762

Legal

  • Privacy Policy
  • Terms of Service
  • About Us

© 2026 PracHub. All rights reserved.

Related Coding Questions

  • Build a Progressive Employee Tracker - Anthropic (hard)
  • Build a Progressive Banking Ledger - Anthropic (hard)
  • Simulate Threshold Infection Efficiently - Anthropic (hard)
  • Build a Progressive Cloud Storage System - Anthropic (hard)