Design questions ask you to maintain a contract over a sequence of operations. One isolated read proves little. A cache must distinguish a miss from a stored zero, refresh recency at the correct moments, and choose the right eviction victim after later updates. An iterator must leave its next value available after peek and hasNext, even across empty pages.
These exercises encode operations as arrays so each complete trace runs through one function in the code workspace. Keep state across the operations in that call, then return only the requested observations. This tests the same data-structure rules without requiring a custom class harness in each language.
Write the invariant before selecting containers. Ordered maps track cache recency; per-client queues track exact rolling windows; sorted per-key histories support historical reads; frequency buckets combine counts with recency ties. Trace a boundary example before implementation and include a sequence that changes which item should be returned or evicted.
capacity 2:
put(1,10), put(2,20) -> recency [1,2]
get(1) returns 10 -> recency [2,1]
put(3,30) -> evict 2; recency [1,3]
get(2) returns -1.
An insertion-only queue would evict 1 incorrectly.
Preserve invariants across cache accesses, time boundaries, and iterator operations.