Quick Overview

This question evaluates a candidate's competence in concurrent programming, atomic state updates, and class-level account management for basic monetary operations.

Implement deposit, withdraw, and transfer in a class

Company: Capital One

Role: Software Engineer

Category: Coding & Algorithms

Difficulty: medium

Interview Round: Onsite

## Problem Implement a class `AccountService` that supports basic money operations on accounts. ### Operations - `deposit(accountId, amount)` - `withdraw(accountId, amount)` - `transfer(fromAccountId, toAccountId, amount)` - `getBalance(accountId)` ### Rules - `amount` is a positive integer. - `withdraw` must fail (return `false` or throw) if the account has insufficient funds. - `transfer` must be **atomic**: either both balances change, or neither changes. - If an account does not exist, treat its initial balance as 0 (or explicitly create on first use). ### Concurrency (if discussed) Assume these methods may be called concurrently from multiple threads. Make the implementation thread-safe and avoid deadlocks. ### Input/Output This is an in-memory class design question; you do not need to build a database or persistence.

Quick Answer: This question evaluates a candidate's competence in concurrent programming, atomic state updates, and class-level account management for basic monetary operations.

You are asked to model an in-memory `AccountService` that supports basic money operations. To make the class-design problem executable in a coding interview, implement a function `solution(operations)` that processes a sequence of method calls and returns the result of each call in order. Each operation is one of: - `('deposit', accountId, amount)` - `('withdraw', accountId, amount)` - `('transfer', fromAccountId, toAccountId, amount)` - `('getBalance', accountId)` Rules: - `amount` is always a positive integer. - If an account does not exist yet, its balance should be treated as `0`. - `withdraw` succeeds only if the account has enough money. - `transfer` must be atomic: either money is moved from one account to the other, or no balance changes at all. - Return one result per operation: - `deposit` returns the new balance of that account. - `withdraw` returns `True` if it succeeds, otherwise `False`. - `transfer` returns `True` if it succeeds, otherwise `False`. - `getBalance` returns the current balance. Note: Real interview follow-up discussion may ask how to make this thread-safe and deadlock-free. For this coding task, process the operations sequentially while preserving correct account behavior and atomic transfers.

Constraints

  • 0 <= len(operations) <= 200000
  • 1 <= amount <= 10^9 for deposit, withdraw, and transfer operations
  • Account IDs are strings
  • All operation names are valid and all amounts are positive integers

Examples

Input: [('deposit', 'A', 100), ('deposit', 'B', 40), ('transfer', 'A', 'B', 30), ('getBalance', 'A'), ('getBalance', 'B'), ('withdraw', 'B', 50), ('getBalance', 'B')]

Expected Output: [100, 40, True, 70, 70, True, 20]

Explanation: A gets 100, B gets 40, then 30 is transferred from A to B. After that B successfully withdraws 50, leaving balance 20.

Input: [('withdraw', 'X', 10), ('getBalance', 'X'), ('transfer', 'X', 'Y', 5), ('getBalance', 'Y')]

Expected Output: [False, 0, False, 0]

Explanation: Nonexistent accounts start with balance 0. The withdraw fails, the transfer also fails, and Y still has 0.

Hints

  1. Use a hash map (dictionary) from account ID to current balance so each operation can be processed in O(1) average time.
  2. For a transfer, first check whether the source account has enough money. Only update balances if the transfer can fully succeed.

Loading coding console...