Design an in-memory banking system
Company: Coinbase
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Take-home Project
Implement an in-memory banking system (e.g., in Java) that supports the following operations on user accounts. Assume user IDs are unique strings and monetary amounts are positive integers.
Core requirements:
1) **Account creation and money movement**
- `addUser(userId)`: create a new user/account.
- `deposit(userId, amount)`: add funds to a user.
- `transfer(fromUserId, toUserId, amount)`: move funds between users.
- Define and handle error cases (unknown user, insufficient funds, invalid amount, etc.).
2) **Rank accounts by spending**
- Provide a method like `getTopSpenders(k)` that returns the top `k` accounts ranked by their **total spending**.
- Clearly define “spending” (e.g., total outgoing money via transfers and executed payments), and specify tie-breaking rules (e.g., by userId).
- Aim for an efficient approach (a heap/priority queue is acceptable).
3) **Scheduled payments with cancellation**
- `schedulePayment(fromUserId, toUserId, amount, executeAtTimestamp)` creates a future payment and returns a `paymentId`.
- `cancelPayment(paymentId)` cancels a scheduled payment if it has not executed yet.
- Provide a way to advance time / process due payments (e.g., `processPaymentsUpTo(timestamp)`), executing all payments whose execution time is reached.
4) **Merge users while preserving history**
- `mergeUsers(sourceUserId, targetUserId)` merges `source` into `target`.
- After merging, balances are combined, the source user no longer exists, and **payment/transfer history is preserved** in a sensible way (describe what the history contains and how it is represented after merge).
- Define how scheduled payments involving the source user are handled after the merge.
You may assume single-threaded execution unless otherwise specified. Design appropriate data structures and APIs, and ensure correctness for edge cases.
Quick Answer: This question evaluates the ability to design and implement a stateful in-memory banking system, testing skills in data structures, algorithms, API design, transaction semantics, scheduling, and correctness under edge cases within the coding and algorithms domain, and it focuses primarily on practical application with conceptual system-design considerations. It is commonly asked to assess reasoning about state management, invariants, error handling, efficiency (e.g., top-k ranking), time-based scheduled events and cancellation semantics, and preserving operation history during merges, highlighting attention to edge cases and performance trade-offs.