System Design: In-Memory Account Management with Transfers, Payments, and Cashback
Design and implement an in-memory account management service that supports atomic balance updates, delayed cashback, and a leaderboard of top transfer spenders. All timestamps should be treated as integers (e.g., seconds since epoch) and all monetary amounts as integers representing the smallest currency unit (e.g., cents).
Explicit Assumptions
- Amounts must be positive integers; operations with non-positive amounts will fail.
- Timestamps are provided by the caller and are used to determine when cashback is due.
- 2% cashback is computed using integer math:
floor(0.02 × amount)which can be implemented as(amount * 2) / 100. - For any failure condition (e.g., missing account, insufficient funds, invalid input),
Optional.empty()should be returned, unless explicitly stated otherwise. - Transfer spending for the
topSpendersleaderboard should only count outgoing transfer amounts from thetransferoperation and explicitly exclude amounts frompayoperations and cashback credits.
Required Operations
Implement the following operations with their specified semantics:
1. createAccount(int timestamp, String accountId)
- Creates a new account with an initial balance of 0.
- Returns
falseif an account with the givenaccountIdalready exists; otherwise, returnstrue.
2. deposit(int timestamp, String accountId, int amount)
- Deposits the specified
amountinto an existing account. - Returns
Optional.of(newBalance)on successful deposit. - Returns
Optional.empty()if the account does not exist or ifamountis less than or equal to 0.
3. transfer(int timestamp, String sourceAccountId, String targetAccountId, int amount)
- Transfers the specified
amountbetween two distinct, existing accounts, provided the source account has a sufficient balance. - On success, returns
Optional.of(sourceNewBalance). - Returns
Optional.empty()if any precondition fails (e.g., missing source or target accounts, identical source and target accounts,amountless than or equal to 0, or insufficient funds in the source account). - This operation must increase only the source account's cumulative outgoing transfer total, which is used for the
topSpendersleaderboard.
4. topSpenders(int timestamp, int n)
- Returns a
List<String>containing up tonaccountIds with the highest cumulative outgoing transfer totals. - If fewer than
naccounts exist, all available accounts should be returned. - In case of a tie in cumulative outgoing transfer totals, use a deterministic tie-break (e.g., lexicographic
accountIdascending).
5. pay(int timestamp, String accountId, int amount)
- Deducts the specified
amountfrom the account if sufficient funds are available. - On success, returns
Optional.of(uniquePaymentId). - Returns
Optional.empty()on failure (e.g., missing account,amountless than or equal to 0, or insufficient funds). - Automatically schedules a 2% cashback credit to the account after 24 hours (86,400 seconds) from the provided
timestamp. - The cashback credit resulting from this operation must not affect the
topSpendersleaderboard calculations.
6. getPaymentStatus(int timestamp, String accountId, String paymentId)
- Returns
Optional.of("IN_PROGRESS")if the cashback associated with thepaymentIdhas not yet been applied. - Returns
Optional.of("CASHBACK_RECEIVED")after the cashback has been successfully applied. - Returns
Optional.empty()if theaccountIdorpaymentIdis invalid or if thepaymentIddoes not match theaccountId.
Additional Requirements
- Ensure atomicity and correctness under concurrency; funds must not be lost or double-counted during operations.
- Each API call must first process any due cashbacks up to the
timestampprovided in that call before executing its primary operation.
AI interview prep
Core dilemma
Maintaining strong consistency and atomicity across multiple, interdependent operations (transfers, payments, delayed cashbacks) within an in-memory, concurrent system, while also efficiently managing scheduled tasks and a dynamic leaderboard under varying load conditions.
3 tradeoffs and 3 stress tests locked
Interview prep
Unlock the interviewer X-Ray rubric, tradeoff matrix, stress tests, clarifying questions, and key concepts.
System Design: In-Memory Account Management with Transfers, Payments, and Cashback
Design and implement an in-memory account management service that supports atomic balance updates, delayed cashback, and a leaderboard of top transfer spenders. All timestamps should be treated as integers (e.g., seconds since epoch) and all monetary amounts as integers representing the smallest currency unit (e.g., cents).
Explicit Assumptions
- Amounts must be positive integers; operations with non-positive amounts will fail.
- Timestamps are provided by the caller and are used to determine when cashback is due.
- 2% cashback is computed using integer math:
floor(0.02 × amount)which can be implemented as(amount * 2) / 100. - For any failure condition (e.g., missing account, insufficient funds, invalid input),
Optional.empty()should be returned, unless explicitly stated otherwise. - Transfer spending for the
topSpendersleaderboard should only count outgoing transfer amounts from thetransferoperation and explicitly exclude amounts frompayoperations and cashback credits.
Required Operations
Implement the following operations with their specified semantics:
1. createAccount(int timestamp, String accountId)
- Creates a new account with an initial balance of 0.
- Returns
falseif an account with the givenaccountIdalready exists; otherwise, returnstrue.
2. deposit(int timestamp, String accountId, int amount)
- Deposits the specified
amountinto an existing account. - Returns
Optional.of(newBalance)on successful deposit. - Returns
Optional.empty()if the account does not exist or ifamountis less than or equal to 0.
3. transfer(int timestamp, String sourceAccountId, String targetAccountId, int amount)
- Transfers the specified
amountbetween two distinct, existing accounts, provided the source account has a sufficient balance. - On success, returns
Optional.of(sourceNewBalance). - Returns
Optional.empty()if any precondition fails (e.g., missing source or target accounts, identical source and target accounts,amountless than or equal to 0, or insufficient funds in the source account). - This operation must increase only the source account's cumulative outgoing transfer total, which is used for the
topSpendersleaderboard.
4. topSpenders(int timestamp, int n)
- Returns a
List<String>containing up tonaccountIds with the highest cumulative outgoing transfer totals. - If fewer than
naccounts exist, all available accounts should be returned. - In case of a tie in cumulative outgoing transfer totals, use a deterministic tie-break (e.g., lexicographic
accountIdascending).
5. pay(int timestamp, String accountId, int amount)
- Deducts the specified
amountfrom the account if sufficient funds are available. - On success, returns
Optional.of(uniquePaymentId). - Returns
Optional.empty()on failure (e.g., missing account,amountless than or equal to 0, or insufficient funds). - Automatically schedules a 2% cashback credit to the account after 24 hours (86,400 seconds) from the provided
timestamp. - The cashback credit resulting from this operation must not affect the
topSpendersleaderboard calculations.
6. getPaymentStatus(int timestamp, String accountId, String paymentId)
- Returns
Optional.of("IN_PROGRESS")if the cashback associated with thepaymentIdhas not yet been applied. - Returns
Optional.of("CASHBACK_RECEIVED")after the cashback has been successfully applied. - Returns
Optional.empty()if theaccountIdorpaymentIdis invalid or if thepaymentIddoes not match theaccountId.
Additional Requirements
- Ensure atomicity and correctness under concurrency; funds must not be lost or double-counted during operations.
- Each API call must first process any due cashbacks up to the
timestampprovided in that call before executing its primary operation.