The design itself wasn't the hard part, I had a reasonable mental model pretty fast.
Start by clarifying core requirements (users, groups, expenses, splits, balances) and then design a minimal data model with users, groups, expenses, and balances. Implement a working prototype focusing on the happy path: adding an expense with equal/unequal splits and updating balances, using an in-memory store for speed. Discuss trade-offs like consistency vs. availability and how you'd scale to Uber's scale.
Pro tip: Prioritize a working end-to-end flow over perfect code; demonstrate you can make pragmatic trade-offs under time pressure. Mention how you'd handle concurrency and idempotency in a real system.
Ask clarifying questions to define MVP: user management, group creation, expense recording with splits (equal, exact, percentage), and balance calculation. Confirm whether to include debt simplification and persistence.
Sketch entities: User, Group, Expense, Split, Balance. Define key operations: addExpense, getBalances, settleUp. Choose an in-memory store (e.g., dictionaries) for speed.
Code the happy path: create users/groups, add an expense with splits, update balances. Use a simple algorithm to compute net balances per user per group.
Run a quick test scenario: add users, create group, add expenses, print balances. Ensure the code runs and handles basic edge cases like zero amounts.
Explain design decisions: in-memory vs. persistent, consistency models, and how to scale (sharding by group, caching balances). Mention concurrency control (e.g., optimistic locking) and idempotency.
AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.