Card 1 of 50
Front. Lost Increment. Two workers each read a counter as 10 and then write 11. What operation was missing?
These cards are original study material. They are not questions from a named employer or a live hiring loop.
All 50 cards in this deck
1.Lost Increment
Two workers each read a counter as 10 and then write 11. What operation was missing?
An atomic read-modify-write or a lock covering the complete update. Making individual reads and writes atomic does not make their composition an atomic increment.
2.Check Act
A thread-safe map contains session IDs. Why can contains(id) followed by put(id, session) still race?
Another worker can insert between the calls. Use an atomic insert-if-absent operation when uniqueness or single creation is the invariant.
3.Multi Field
Why can two independent atomic fields still expose an invalid account state?
A reader can observe one updated field and one old field. Protect the joint invariant with one lock, an immutable snapshot swap, or another operation that updates the pair atomically.
4.Race Versus Order
Can a program with no data races still have a concurrency bug?
Yes. Two correctly synchronized operations can occur in the wrong logical order, such as closing a resource before another task acquires its use permit. Race freedom does not establish workflow correctness.
5.Publish Object
Why must publishing a newly initialized shared object use synchronization defined by the language?
A pointer becoming visible does not by itself guarantee visibility of prior field writes. Use a lock, channel, or documented atomic publication mechanism establishing the required ordering.
6.Go Completion
In Go, does returning from a goroutine guarantee another goroutine sees its writes?
No. Establish synchronization through a channel, WaitGroup, lock, or suitable atomic operation. Goroutine termination alone is not a visibility signal.
7.Immutable Snapshot
How can a service update routing configuration without locking every reader for the entire lookup?
Build a complete immutable snapshot, publish it through a suitable synchronized reference, and have each request retain one snapshot. Never mutate the published data underneath readers.
8.Copy Reference
Why is returning a mutable map from inside a locked getter unsafe?
The lock protects only the getter's execution. Callers can later mutate or iterate the same map without synchronization. Return a copy, immutable view with enforced ownership, or an API that controls access.
9.Lock Scope
Why should a lock usually not be held while calling a slow remote service?
Its latency blocks every contender and callbacks may acquire other locks. Capture needed state, release the lock, perform I/O, then revalidate before applying results.
10.Revalidation
A worker releases a lock to compute a result. What must it check after reacquiring the lock?
Whether the state version or assumptions used by the computation still hold. If not, discard or recompute the result rather than overwriting intervening changes.
11.Lock Order
Two handlers acquire account locks in opposite orders. What policy prevents this deadlock pattern?
Acquire all required account locks in a shared total order, such as ascending account ID. Apply the rule across every code path, including rollback and cleanup paths.
12.Lock Upgrade
Why can two readers deadlock when both try to upgrade a read lock to a write lock?
Each may retain its read lock while waiting for all readers to leave. Use a documented upgrade mechanism or release, acquire the write lock, and recheck the state.
13.Condition Loop
Why should a condition-variable wait be inside a loop checking the predicate?
A wakeup does not guarantee the predicate holds when the lock is reacquired; another worker may consume the resource, and spurious wakeups may occur. Recheck under the associated lock.
14.Lost Notification
Why must checking a condition and entering its wait protocol be coordinated with the same lock?
Otherwise a producer can signal after the check but before the waiter sleeps, leaving it asleep despite available work. The condition API atomically releases the lock and begins waiting.
15.Notify Choice
When can signaling one arbitrary waiter fail to make progress?
When waiters need different predicates and the awakened waiter cannot proceed. Use separate conditions or wake all relevant waiters, each of which rechecks its predicate.
16.Semaphore Scope
A semaphore allows 20 outbound calls per process. Does deploying 10 replicas cap global concurrency at 20?
No; the aggregate can reach 200. Choose per-instance limits from dependency capacity or coordinate a shared limit when the global bound is essential.
17.Permit Leak
What resource-management pattern prevents semaphore permits leaking on exceptions or cancellation?
Release exactly once in a finally or scoped cleanup after successful acquisition. Do not release when acquisition failed or never completed.
18.Rate Versus Concurrency
Why can a service obey a requests-per-second limit and still overload a slow dependency?
In-flight requests grow as latency rises. A rate limit bounds arrivals; a concurrency limit bounds outstanding work. Often both are needed.
19.Bounded Queue
What must an executor define when its bounded work queue fills?
An explicit policy: reject, block with a deadline, shed lower-priority work, or route elsewhere. Silent unbounded fallback defeats the memory and latency bound.
20.Queue Deadline
Why should a queued request be checked for expiry before a worker starts it?
It may have spent its entire deadline waiting. Starting obsolete work wastes capacity and can trigger effects after the caller has given up.
21.Thread Pool Deadlock
Every worker submits a child task to the same fixed pool and waits for it. Why can the system stop?
All threads are occupied by parents, leaving no thread to run children. Avoid blocking nested submission, use asynchronous composition, or provide an execution model that guarantees progress.
22.Blocking Loop
Why does one synchronous file read harm unrelated requests on a single event-loop thread?
While that thread blocks, it cannot dispatch other ready callbacks. Use supported asynchronous I/O or move blocking work to a bounded worker pool.
23.Cpu Async
Why does declaring a CPU-heavy function async not automatically let other requests run?
Execution must actually yield, and CPU instructions still occupy the executing thread. Partition the computation or offload it to suitable bounded compute workers.
24.Cancel Cooperation
Does cancelling a task necessarily stop its database query or HTTP call?
No. Cancellation must propagate through supported APIs, and remote work may continue or already have committed. Track ambiguous effects and ensure cleanup occurs.
25.Structured Lifetime
What request-lifetime bug does structured concurrency help prevent?
Child tasks silently outliving the request while holding resources or mutating state. A parent scope owns child completion and cancellation; intentional background work needs a separate durable owner.
26.Fanout Limit
A handler calls 500 accounts concurrently to reduce latency. What should constrain its fan-out?
Dependency capacity, per-request memory, connection limits, and the request deadline. Use bounded parallelism and a policy for partial failure rather than launching all operations immediately.
27.Fanout Failure
One required child call fails while nine others are running. What should the parent do?
Cancel work whose result is no longer useful, await or otherwise safely own cleanup, and return a defined failure. Do not leave unobserved exceptions or assume cancellation reverses completed effects.
28.Shared Cancel
Several requests share one single-flight cache fill. Why should the first caller's cancellation not necessarily cancel the fill?
Other callers still need it. Separate waiter lifetimes from the shared operation's lifetime, with a deliberate policy for cancelling when no interested callers remain.
29.Single Flight
What does per-key single-flight suppress, and what does it not guarantee?
It coalesces concurrent local computations for one key. It does not automatically coordinate replicas, cache successful results permanently, or provide business-operation idempotency.
30.Cache Invalidation Race
A cache fill reads old data, an update invalidates the cache, and the fill then writes. What failure occurs?
The old value is reintroduced after invalidation. Use version checks, a suitable synchronization protocol, or bounded staleness with an explicitly accepted consistency model.
31.Optimistic Version
How does a version predicate prevent lost updates in SQL?
Update using WHERE id = ? AND version = expected, incrementing version atomically. Zero affected rows means the assumption was stale; reread and recompute rather than blindly retrying the old write.
32.Retry Purity
Why must a compare-and-swap retry loop avoid sending an email inside its speculative computation?
The computation may run several times before one update succeeds. Keep retries free of irreversible effects and dispatch the effect only through a durable committed intent.
33.Aba
What can a compare-and-swap miss when a value changes from A to B and back to A?
It sees the same current value despite intervening changes. A version tag can distinguish generations; lock-free pointer structures also need safe memory reclamation.
34.Lock Free Progress
Does lock-free mean every individual request finishes within a bounded time?
No. It guarantees system-wide progress under the algorithm's assumptions, while an individual participant may starve. Wait-free algorithms provide a stronger per-operation progress guarantee.
35.False Sharing
Why can independent counters on the same cache line contend even when no lock is shared?
Writes cause cache-coherence traffic for the shared line across cores. Profile before padding or sharding; logical independence does not imply independent hardware access.
36.Sharded Counters
What tradeoff appears when replacing one exact global counter with per-worker counters?
Updates contend less, but aggregating a concurrently changing set may not yield a single instantaneous total. Decide whether approximate metrics or exact admission control is required.
37.Lease Expiry
A worker pauses longer than its distributed lock's TTL. Why can it later act concurrently with the new owner?
Expiry permits a new owner but does not stop the old process. The protected resource must reject stale ownership, or operations must otherwise tolerate duplicate execution.
38.Fencing
How does a monotonically increasing fencing token protect a storage write?
Each owner receives a newer token, and storage rejects writes with older tokens after accepting a newer owner. Checking ownership only in the worker leaves a pause-and-resume race.
39.Lock Release
Why must deleting a Redis lock key check its owner token atomically?
An expired owner could otherwise delete a newer owner's lock. Use an atomic compare-and-delete operation tied to the acquisition token.
40.Lease Renewal
What should a lease holder do when renewal cannot be confirmed?
Treat ownership as uncertain and stop initiating protected work according to the lease protocol. Previously issued operations may still finish, so resource-side protection remains necessary.
41.Local Mutex
Why does adding a process-local mutex not fix duplicate scheduled jobs across replicas?
Each replica owns a separate mutex. Coordinate job ownership durably or make executions idempotent; local exclusion only protects threads within that process.
42.Shutdown Order
What order supports graceful shutdown of a worker service?
Stop accepting new work, signal cancellation or drain within a deadline, finish durable acknowledgements for completed work, then close shared resources. Preserve retryability of unfinished jobs.
43.Resource Close
Why can closing a shared connection pool as soon as shutdown starts cause avoidable failures?
In-flight handlers may still need it to finish or commit. Tie resource lifetime to active users and close after draining, subject to a bounded shutdown policy.
44.Channel Close
Who should own closing a channel used by multiple producers?
A coordinator that knows all sends are finished, or a clearly designated owner. Letting any consumer close it while producers run can cause send-on-closed-channel failures.
45.Backpressure Chain
How can a bounded queue fail to bound memory if callers spawn a task before attempting to enqueue?
The blocked producer tasks themselves accumulate. Apply admission control before creating expensive tasks and count all waiting work, not only queue contents.
46.Priority Starvation
Why can strict priority scheduling indefinitely delay normal requests?
A sustained stream of high-priority work always wins. Reserve capacity, use aging, or adopt weighted fairness when lower-priority work needs a completion guarantee.
47.Tenant Fairness
What happens when one tenant fills a shared FIFO with thousands of slow jobs?
Other tenants wait behind that backlog despite being within their limits. Per-tenant queues or fair scheduling can isolate waiting time while enforcing a global capacity bound.
48.Deterministic Race
How can a test reproduce a lost-update race without relying on arbitrary sleeps?
Use barriers to make both workers read the old value before either writes, then release them. Assert the invariant after completion; explicitly controlled interleavings make failures reproducible.
49.Race Detector
Why does a clean dynamic race-detector run not prove a service is concurrency-correct?
It only observes executed paths and schedules, and logical ordering bugs can use synchronization correctly. Combine it with invariant tests, controlled interleavings, and failure injection.
50.Contention Diagnosis
What distinguishes lock contention from CPU saturation in a slow service?
Compare runnable CPU work with blocked-thread stacks, lock wait duration, and hold duration. Low CPU with many waiters suggests serialization; adding threads may worsen it.
