Backend coding interview
Marketplace Escrow System Coding Interview Problem
What this interview round tests
Every marketplace has money in limbo: the buyer paid, the seller has not been paid, and the platform holds the difference in escrow until delivery confirms or a dispute resolves. This problem implements that limbo — holds placed, released to sellers, refunded to buyers, or auto-released at a deadline — with the one rule that defines escrow: the same held rupee can leave exactly once.
It is a favourite senior-round problem at marketplace and fintech companies because it compounds two hard things. The concurrency half: a buyer’s refund claim racing the deadline-based auto-release, both trying to move the same held amount to different parties. The accounting half: a ledger that must prove, at any moment, that held plus released plus refunded equals exactly what was ever captured. Passing one half without the other is the standard partial credit.
The scenario
You are handed an escrow service: payments create holds, delivery confirmation releases funds to sellers, disputes refund buyers, and holds past their deadline auto-release. All four paths exist, and the test suite exposes the money leaking between them.
A refund racing an auto-release pays both the buyer and the seller, released holds can be released again, terminal states are re-entered by late operations, and the ledger drifts from the balances it is supposed to explain. Your job is to make every hold resolve exactly once and keep the books provable.
What you’ll practice
- Hold lifecycle: held → released | refunded as one-way, terminal transitions
- The release-versus-refund race: two resolutions, one hold, exactly one winner
- Deadline-based auto-release that cannot double-pay a just-resolved hold
- Terminal-state guards: late or repeated operations rejected cleanly
- Ledger reconciliation: held + released + refunded ≡ captured, always
- Atomic failure: a rejected resolution leaves the hold and ledger untouched
How to approach it
Make resolution a single compare-and-transition on the hold: an operation wins only if it finds the hold still in HELD and flips it to its terminal state in the same atomic step. Release, refund, and the deadline sweeper all go through that gate, so whichever serializes first wins and every other resolution becomes a clean rejection rather than a second payout.
Anchor the money in ledger entries written in the same step as the transition: one entry when funds are captured into the hold, one when they leave. Balances are then derived, and the reconciliation invariant becomes checkable arithmetic. The tests run racing resolutions and then audit the books to the exact minor unit — a design where state and ledger can disagree, even briefly, cannot pass.
The starter repository ships with a failing test suite and a bundled verify.sh. Reviewed reference solutions are part of Gronex Pro — this page stays spoiler-free on purpose.
FAQ
How does escrow differ from the wallet problem?
A wallet moves money between a user and the system; escrow parks money between two users with the platform as referee. The new difficulty is contested resolution — refund and release are competing claims on the same funds — plus a clock (the auto-release deadline) acting as a third claimant.
Why is the deadline sweep the dangerous part?
Because it is a background actor mutating the same holds users are resolving in the foreground. A sweep that reads "past deadline, still held" and releases without re-checking state atomically will eventually double-pay a hold that a refund resolved a millisecond earlier. The sweep must go through the same atomic gate as everyone else.
What does the test suite audit?
It races refunds against releases and the deadline sweeper, then checks that each hold reached exactly one terminal state, no money left twice, late operations were rejected, and the ledger reconciles to the captured total exactly — in Java, Python, or C++.