Design a transaction class for deposits/withdrawals
Capital OneSoftware Engineer · Technical ScreenLast updated
This problem tests your ability to design a robust, thread-safe class for managing bank account transactions, focusing on atomicity and data consistency.
Problem Statement
Design a BankAccount class that supports deposits, withdrawals, and retrieving a transaction history. The class must be thread-safe, ensuring that multiple concurrent operations do not lead to race conditions or inconsistent states.
Requirements
deposit(amount): Adds funds to the balance. Must be a positive value.withdraw(amount): Subtracts funds if the balance is sufficient. Must be a positive value.get_balance(): Returns the current balance.get_transaction_history(): Returns a chronological list of all successful transactions.
Constraints
- The system must handle concurrent calls from multiple threads.
- Withdrawals must fail (or return an error) if the
amountexceeds theget_balance(). - You must maintain a record of all operations for the history.
Example
account = BankAccount(initial_balance=100)
account.deposit(50) # Balance: 150
account.withdraw(20) # Balance: 130
account.withdraw(200) # Should handle gracefully (e.g., return False or raise Exception)
print(account.get_transaction_history())
# Output: [{'type': 'deposit', 'amount': 50}, {'type': 'withdrawal', 'amount': 20}]
Edge Cases to Consider
- Negative input values.
- Concurrent withdrawals attempting to drain the account simultaneously.
- Ensuring the balance update and history entry are atomic.
Hints
Hint 1
Use a reentrant lock or a primitive mutex to protect the shared state during read-modify-write operations.
Hint 2
Consider using an immutable data structure for each transaction record to prevent external modification of the history.
Hint 3
Think about the difference between locking the entire class instance versus using atomic primitives like Compare-And-Swap (CAS).
Follow-up questions
- How would you modify your design if you needed to support atomic transfers between two different BankAccount instances?
- How would this design change if you needed to persist the transaction history to a database while ensuring zero data loss during system crashes?
- If the system expects thousands of concurrent transactions per second, how would you optimize to reduce lock contention?
Solution walkthrough is for members
Get the full walkthrough with reference code and complexity analysis, plus Kitty Coach at 300 messages a day. Hints, the code runner and community answers stay free.