Implement a Time-Aware Banking System

Quick Overview

Build an incremental in-memory banking system with accounts, transfers, spender rankings, scheduled payments, cancellation, merging, and historical balances. Across all levels, the design must preserve deterministic ordering, atomic money movement, settlement boundaries, idempotency, derived state, pending-work rebinding, as-of history, and cross-level tests.

Implement a Time-Aware Banking System

Company: Airbnb

Role: Software Engineer

Category: Software Engineering Fundamentals

Difficulty: hard

Interview Round: Take-home Project

## Implement a Time-Aware Banking System Design an in-memory banking component in four increments. It must create accounts, accept deposits, transfer funds, rank accounts by outgoing spend, schedule and cancel future payments, merge accounts, and answer historical-balance queries. The original exercise leaves several ordering and merge rules open. State a deterministic contract before implementing them. The following assumptions form one valid practice contract; call out any rule you would change in a real requirements discussion. ### Constraints & Assumptions - Account IDs are stable strings, and monetary amounts are positive integers in minor currency units. - Every operation has a nondecreasing logical timestamp. Before handling an operation at time `t`, the system processes every scheduled payment due at or before `t`. - A deposit, transfer, or scheduled payment changes state only if the whole operation succeeds. Insufficient funds must not create a partial debit. - Outgoing-spend totals include successful transfers and successful scheduled payments, but not rejected or canceled payments. - Scheduled payments due at the same timestamp use a deterministic creation order. - The merge contract must define which account ID survives and how balances, spend totals, pending payments, and historical queries are carried forward. ### Clarifying Questions to Ask - What should duplicate account creation and references to missing accounts return? - May a transfer send money to the same account, and does it count as outgoing spend? - If a scheduled payment lacks funds at its due time, is it skipped permanently or retried? - Does cancellation at the exact due timestamp happen before or after settlement? - After a merge, may callers use the retired account ID, and what should its historical balance mean? ### Part 1 — Accounts, Deposits, and Transfers Define the public operations and internal state for creating an account, depositing money, and transferring money between two accounts. Preserve atomicity and deterministic error behavior. #### What This Part Should Cover - Account existence and duplicate-creation rules. - Balance validation and an all-or-nothing transfer. - A consistent return contract for success and failure. - Invariants for conservation of money during transfers. ```hint Keep validation ahead of mutation List every condition that can reject a transfer, then change both balances only after all conditions pass. ``` ### Part 2 — Rank the Top Spenders Add an operation that returns the top `N` accounts by cumulative successful outgoing spend. Define the tie-breaker and explain whether ranking is computed on demand or maintained incrementally. #### What This Part Should Cover - Exactly which operations contribute to outgoing spend. - Descending spend order with a stable account-ID tie-breaker. - Behavior when `N` exceeds the number of active accounts. - The update-versus-query cost of the chosen index. ```hint Treat ranking as derived state The balance answers how much remains; a separate counter is needed to answer how much successfully left the account. ``` ### Part 3 — Schedule and Cancel Payments Support creation of a payment for a future timestamp and cancellation by payment ID. Add one settlement routine that earlier operations call so due work is applied before they inspect or mutate account state. #### What This Part Should Cover - Unique payment identity, due-time ordering, and cancellation state. - Efficient discovery of due payments without scanning every scheduled item. - The insufficient-funds rule at execution time. - Why every timestamped public operation shares the same settlement boundary. ```hint Centralize time advancement If each public method handles due work differently, two calls at the same logical time can observe inconsistent balances. ``` ### Part 4 — Merge Accounts and Query Historical Balances Add account merging and a query for an account's balance at a specified historical time. Explain how a merge affects active identity, pending payments, outgoing-spend ranking, and history on both sides of the merge. #### What This Part Should Cover - A precise surviving-account and retired-account policy. - No loss or double counting of balance and outgoing spend. - Rebinding or otherwise resolving pending scheduled payments. - An append-only history representation and an efficient as-of lookup. ```hint Separate current identity from past events A merge changes which account is active now, but it should not rewrite the timestamps at which earlier balance changes occurred. ``` ### What a Strong Answer Covers - Explicit contracts for every ambiguous ordering, failure, cancellation, and merge case. - Atomic balance changes and one consistent mechanism for settling due work. - Correct derived spend totals, deterministic ranking, and time-indexed history. - Complexity analysis and tests spanning multiple levels rather than testing each feature in isolation. ### Follow-up Questions 1. How would you make settlement safe if two operations with the same timestamp execute concurrently? 2. How could top-spender queries avoid sorting every account on every request? 3. What test proves that a canceled payment never affects either balance or spend totals? 4. How would you persist the system so a crash during settlement cannot apply one payment twice?

Quick Answer: Build an incremental in-memory banking system with accounts, transfers, spender rankings, scheduled payments, cancellation, merging, and historical balances. Across all levels, the design must preserve deterministic ordering, atomic money movement, settlement boundaries, idempotency, derived state, pending-work rebinding, as-of history, and cross-level tests.

|Home/Software Engineering Fundamentals/Airbnb
Airbnb logo
Airbnb
Jul 21, 2026, 12:00 AM
hardSoftware EngineerTake-home ProjectSoftware Engineering Fundamentals
1
0

Implement a Time-Aware Banking System

Design an in-memory banking component in four increments. It must create accounts, accept deposits, transfer funds, rank accounts by outgoing spend, schedule and cancel future payments, merge accounts, and answer historical-balance queries.

The original exercise leaves several ordering and merge rules open. State a deterministic contract before implementing them. The following assumptions form one valid practice contract; call out any rule you would change in a real requirements discussion.

Constraints & Assumptions

  • Account IDs are stable strings, and monetary amounts are positive integers in minor currency units.
  • Every operation has a nondecreasing logical timestamp. Before handling an operation at time t , the system processes every scheduled payment due at or before t .
  • A deposit, transfer, or scheduled payment changes state only if the whole operation succeeds. Insufficient funds must not create a partial debit.
  • Outgoing-spend totals include successful transfers and successful scheduled payments, but not rejected or canceled payments.
  • Scheduled payments due at the same timestamp use a deterministic creation order.
  • The merge contract must define which account ID survives and how balances, spend totals, pending payments, and historical queries are carried forward.

Clarifying Questions to Ask Guidance

  • What should duplicate account creation and references to missing accounts return?
  • May a transfer send money to the same account, and does it count as outgoing spend?
  • If a scheduled payment lacks funds at its due time, is it skipped permanently or retried?
  • Does cancellation at the exact due timestamp happen before or after settlement?
  • After a merge, may callers use the retired account ID, and what should its historical balance mean?

Part 1 — Accounts, Deposits, and Transfers

Define the public operations and internal state for creating an account, depositing money, and transferring money between two accounts. Preserve atomicity and deterministic error behavior.

What This Part Should Cover Guidance

  • Account existence and duplicate-creation rules.
  • Balance validation and an all-or-nothing transfer.
  • A consistent return contract for success and failure.
  • Invariants for conservation of money during transfers.

Part 2 — Rank the Top Spenders

Add an operation that returns the top N accounts by cumulative successful outgoing spend. Define the tie-breaker and explain whether ranking is computed on demand or maintained incrementally.

What This Part Should Cover Guidance

  • Exactly which operations contribute to outgoing spend.
  • Descending spend order with a stable account-ID tie-breaker.
  • Behavior when N exceeds the number of active accounts.
  • The update-versus-query cost of the chosen index.

Part 3 — Schedule and Cancel Payments

Support creation of a payment for a future timestamp and cancellation by payment ID. Add one settlement routine that earlier operations call so due work is applied before they inspect or mutate account state.

What This Part Should Cover Guidance

  • Unique payment identity, due-time ordering, and cancellation state.
  • Efficient discovery of due payments without scanning every scheduled item.
  • The insufficient-funds rule at execution time.
  • Why every timestamped public operation shares the same settlement boundary.

Part 4 — Merge Accounts and Query Historical Balances

Add account merging and a query for an account's balance at a specified historical time. Explain how a merge affects active identity, pending payments, outgoing-spend ranking, and history on both sides of the merge.

What This Part Should Cover Guidance

  • A precise surviving-account and retired-account policy.
  • No loss or double counting of balance and outgoing spend.
  • Rebinding or otherwise resolving pending scheduled payments.
  • An append-only history representation and an efficient as-of lookup.

What a Strong Answer Covers Guidance

  • Explicit contracts for every ambiguous ordering, failure, cancellation, and merge case.
  • Atomic balance changes and one consistent mechanism for settling due work.
  • Correct derived spend totals, deterministic ranking, and time-indexed history.
  • Complexity analysis and tests spanning multiple levels rather than testing each feature in isolation.

Follow-up Questions Guidance

  1. How would you make settlement safe if two operations with the same timestamp execute concurrently?
  2. How could top-spender queries avoid sorting every account on every request?
  3. What test proves that a canceled payment never affects either balance or spend totals?
  4. How would you persist the system so a crash during settlement cannot apply one payment twice?
Loading comments...