hard apple general · part of Practice Questions · Senior SWE Roadmap

Requirements to clarify

  • Functional: hold a balance, transfer money between wallets, top up from an external source, pay out.
  • Non-functional: correctness is non-negotiable (money can’t be created or lost), auditability, must handle concurrent transactions on the same wallet safely.

Core components

  • Double-entry ledger: every transaction records both a debit and a credit (e.g., debit sender, credit receiver) so the books always balance and every historical state is reconstructable — the standard accounting-correct pattern, not just a single mutable “balance” field.
  • Balance as a derived value: the “current balance” is computed (or cached) from the ledger’s transaction history, not stored as the sole source of truth — this makes the system auditable and recoverable from any point.
  • Concurrency control on transfers: prevent race conditions where two simultaneous debits both read a stale balance and both succeed when only one should (row-level locking or optimistic concurrency with balance checks inside the transaction).
  • Idempotency: every transfer request has an idempotency key so retries (e.g., after a network timeout) don’t double-transfer.

Key tradeoffs

  • Storing balance as a simple mutable counter is simpler and faster but loses auditability and is more fragile under concurrent access — the ledger-based approach is slower per-read (or needs caching) but is the correct foundation for anything involving real money.

Approach / Notes