← All problems

Coding Prep

Solution Shape Atlas

A compact map of five practical coding shapes, their first state choices, failure modes, and speed drills.

Free~10 min

Use this page when a practical coding prompt feels familiar but you cannot yet name the state model quickly. It is not a catalog of every interview pattern. It is a short list of starting shapes that stop you from designing a small system from zero under the clock.

Start by naming the shape, then say the state and first operation out loud. If you cannot do that in a minute, do a shape-snap drill before another full mock.

The map

ShapePrompt signalState to name firstStart with
Stateful API"Build a class that supports..."primary map plus any essential indexone write and one read
Expiring state"...with TTL, expiration, active count"value plus deadline and expiry orderinglazy cleanup on read
Dependency graph"...formulas, propagation, affected nodes"forward and reverse edgesupdate one node and propagate
Resumable iterator"...next, checkpoint, resume"minimal serializable cursorround-trip saved state
Grid or graph traversal"...spread, cluster, shortest path"queue or stack plus visited setone frontier expansion

Shape 1: Stateful API

Use this for an object with operations over shared state: a key-value store, session manager, account tracker, or small in-memory database.

  1. Name the primary key and domain value.
  2. List the public operations in the order you can make them work.
  3. Add a secondary index only when an operation needs a second lookup direction.
class SessionStore:
    def __init__(self) -> None:
        self._sessions: dict[str, str] = {}
 
    def put(self, token: str, user_id: str) -> None:
        self._sessions[token] = user_id
Note
Use domain names early - _sessions tells you more than _data and makes the next method easier to write.

Try it with KV Store or Credit Tracker.

Shape 2: Expiring state

Add this shape when values expire. Keep the current value and deadline together, then use an expiry-ordered structure to clean stale entries when a read needs a fresh answer.

self._store: dict[str, tuple[str, float]] = {}
self._expiry: list[tuple[float, str]] = []
 
def get(self, key: str) -> str | None:
    self._evict_expired()
    entry = self._store.get(key)
    return entry[0] if entry else None

The critical test is an update: the old expiry record can remain in the heap, so cleanup must verify that the stored deadline is still the expired one before deleting. Use a deque only when insertion order is guaranteed to match expiry order.

Try it with Time-Based KV or Auth Manager TTL.

Shape 3: Dependency graph

Use this when a change must reach only the values that depend on it: spreadsheet cells, configuration inheritance, derived counters, or build targets.

Keep both directions. Forward edges explain what a node reads; reverse edges identify who must be revisited when the node changes. Remove old reverse edges before replacing a formula or dependency list.

Note
Visited is not ordering - a visited set prevents loops and duplicate work, but a diamond dependency may still need topological ordering before you recompute values.

Try it with Spreadsheet or Unix cd.

Shape 4: Resumable iterator

Use this for an object that must pause and continue. The cursor is the smallest state that reproduces the next result, not a copy of every result already seen.

def get_state(self) -> int:
    return self._current
 
def set_state(self, state: int) -> None:
    self._current = state

Prove the contract with one round trip: save the state, restore it, and confirm the next item is unchanged.

Try it with Resumable Iterator or IPv4 Iterator.

Shape 5: Grid or graph traversal

Use a queue for levels, steps, or unweighted shortest paths. Use a stack or recursive traversal when you only need reachability or enumeration.

queue = deque([source])
visited = {source}
while queue:
    node = queue.popleft()
    for neighbor in neighbors(node):
        if neighbor not in visited:
            visited.add(neighbor)
            queue.append(neighbor)

Mark a node visited when you enqueue it. Waiting until dequeue lets several predecessors add the same node and hides avoidable work.

Try it with Disease Spread or N-ary Cluster Count.

Two short drills

Shape snap

Set 60 seconds for an unfamiliar prompt. Name the shape, primary state, public operations, and one failure mode. Do not code. Repeat five prompts and record the moment you hesitated.

Skeleton drill

Choose one shape and type only its smallest useful skeleton from memory. Stop after the state and one operation. The goal is a reliable start, not a full reference implementation.

Use it in a real rep

Run the interview protocol first. Once you can name the shape, choose a challenge and build the thin slice under a timer.

Done reading? Mark it so it sticks in your dashboard.

Next in CodingArrays