Design a bank system with scheduling and rankings
Company: Meta
Role: Software Engineer
Category: System Design
Difficulty: hard
Interview Round: Technical Screen
Design an in-memory bank system with the following APIs and guarantees:
1) createAccount(accountId, initialBalance=
0) -> void: Create a new account.
2) deposit(accountId, amount) -> bool: Increase balance; return false if accountId does not exist or amount <= 0.
3) withdraw(accountId, amount) -> bool: Transfer out funds; reject if insufficient balance or invalid input. Maintain each account’s cumulativeTransferredOut.
4) getTopSpenders(n) -> List<accountId>: Return the n accounts with the highest cumulativeTransferredOut. Break ties by smaller accountId. Results must reflect all successful withdraws and executed scheduled payments at the time of the call.
5) schedulePayment(accountId, amount, timestamp, delay) -> paymentId: Schedule a withdraw to execute at executeAt = timestamp + delay (timestamps are integers; delay >=
0). The payment counts toward cumulativeTransferredOut only upon successful execution.
6) cancel(paymentId) -> bool: Cancel a not-yet-executed payment.
7) process(nowTimestamp) -> string: Execute all due scheduled payments with executeAt <= nowTimestamp in ascending executeAt order; when executeAt ties, order by increasing paymentId. For each successfully executed payment, update balances and cumulativeTransferredOut. Return a single string that concatenates executed accounts’ IDs in that exact order, separated by commas (return an empty string if none executed).
Edge cases and rules:
- Amounts are positive integers; balances cannot go negative; failed executions (e.g., insufficient funds) do not affect cumulativeTransferredOut and are not included in the process() return string.
- Repeated operations may interleave arbitrarily. Assume single-threaded execution unless you choose to discuss concurrency controls.
- Complexity targets: O(
1) average-time for create/deposit/withdraw lookups and updates; O(log M) for scheduling/canceling/executing due payments using an appropriate priority structure where M is the number of pending payments; getTopSpenders(n) should be efficient for variable n queries (propose and justify a data structure choice and its trade-offs).
- Specify data structures, method signatures, and invariants. Describe how you would test correctness, handle idempotency (e.g., duplicate payment scheduling), and recover from partial failures (optional).
Quick Answer: Design a bank system with scheduling and rankings evaluates requirements, scale assumptions, API/data design, architecture, trade-offs, failure modes, and rollout in a realistic interview setting. A strong answer states assumptions, handles edge cases, explains trade-offs, and shows how to validate the result clearly.