cswork / libraryOpen practice workspace

Computer science concepts

Atomic State Updates And Concurrency

This evaluates correct, atomic state updates under concurrent access and practical concurrency control for money operations (deposit, withdraw, transfer).

What's being tested

This evaluates correct, atomic state updates under concurrent access and practical concurrency control for money operations (deposit, withdraw, transfer). Interviewers probe safe invariants (no negative balances, total-sum preservation), race-condition avoidance, and efficient lock/transaction strategies an SWE would implement.

Patterns & templates

  • Per-account locking: use a per-resource mutex (e.g., threading.Lock, synchronized) to make deposit/withdraw O(1) while avoiding global contention.

  • Canonical lock ordering: always lock accounts by a stable key (account ID) to avoid deadlock when transferring between two accounts.

  • Optimistic retry with CAS: use compare-and-swap (AtomicLong, Interlocked) for low-latency non-blocking updates; retry on conflict, fail after N attempts.

  • Database row-level transactions: wrap operations in a DB transaction with SELECT ... FOR UPDATE or SERIALIZABLE when using Postgres to delegate concurrency to the DB.

  • Validate-then-commit: check invariants (balance >= amount) while holding locks or within the same transaction to prevent lost-update bugs.

  • Idempotent APIs: implement idempotency keys for retries so network failures don’t double-apply operations.

  • Avoid floats for money: store cents as integers (long) to prevent precision and comparison errors.

Common pitfalls

Pitfall: Using a single global lock scales poorly and hides the need for finer-grained concurrency; performance suffers under contention.

Pitfall: Locking two accounts without a consistent ordering causes intermittent deadlocks that are hard to reproduce.

Pitfall: Using float/double for balances causes rounding errors and invariant violations under concurrent updates.