vishal maurya

LLD Interview Framework (45-60 minute round)

Overview

Part of the Interview Prep series. Dotted-underline words are glossary terms: hover for the meaning or open the Glossary. Track your progress on the Interview Prep tracker. Series index: Start here.

Goal: show structured thinking, clean OO modeling, working code, and awareness of extensibility/concurrency. Interviewers rarely want a perfect system; they want a runnable core with sound design and clear trade-offs.

Time budget (60 min; compress proportionally for 45)

MinPhaseOutput
0-51. Clarify requirementsWritten list of functional + non-functional + out-of-scope
5-102. Entities, behaviors, relationshipsNouns/verbs table, rough class diagram
10-153. Patterns, APIs, package layoutInterfaces and public method signatures
15-454. Code core flowCompiling classes, in-memory storage, a main/demo
45-525. Extensibility + concurrencyVerbal walk-through, small code changes
52-606. Testing, edge cases, Q&ATest cases listed, complexity discussed

Step 1: Clarify requirements (never skip)

Ask, then write them down in the doc/editor and confirm.

  • Actors: who uses it (customer, admin, merchant, system)?
  • Core use cases (top 3-5): e.g. ATM: insert card, auth PIN, withdraw, check balance, deposit.
  • Scope: what is out (UI, real DB, real network, auth)? "Single JVM, in-memory" is the usual answer.
  • Rules/constraints: pricing, limits, capacity, expiry, priority, max retries.
  • Non-functional: concurrency expected? latency? scale? consistency? extensibility axes ("new payment method next quarter?").
  • Failure behavior: insufficient funds, timeouts, duplicate request?
  • Money questions (fintech): currency? precision (BigDecimal/paise long)? refunds? idempotency? audit trail?

Template to say aloud: "I'll assume X, Y. Out of scope: Z. I'll design for extension on A and B. Sound good?"

Step 2: Identify entities (nouns) and behaviors (verbs)

Underline nouns in the requirements -> candidate classes; verbs -> methods; adjectives/enums -> attributes/types.

Example (wallet): "Users have wallets, add money from bank, pay merchants, and view transactions."

NounBecomesVerbOwner
UserentityaddMoneyWallet
Walletentity (holds balance)payWalletService (coordinates 2 wallets)
Transactionentity/value, immutableview historyTransactionRepository
Moneyvalue object

Heuristics: entity has identity & lifecycle (Account); value object is immutable and compared by value (Money); service is stateless coordination (TransferService); enum for closed sets (TxnStatus); interface where behavior varies. Put behavior on the object that owns the data (Tell, Don't Ask); use a service only when logic spans multiple entities.

Step 3: Relationships

  • Association (uses), Aggregation (has-a, independent lifetime), Composition (owns, dies together), Inheritance (is-a), Realization (implements).
  • Decide cardinality (1..*), ownership, and which side holds the reference.
  • Prefer composition + interfaces; inheritance only for true is-a.

Step 4: Class diagram (ASCII/UML cheat-sheet)

+------------------+        +----------------------+
| <<interface>>    |        | Wallet               |
| PaymentMethod    |        |----------------------|
|------------------|  1   * | - id: String         |
| + pay(Money)     |<>------| - balance: Money     |
+------------------+        | + debit(Money)       |
      ^        ^            | + credit(Money)      |
      |        |            +----------------------+
  UpiMethod  CardMethod            |  1
                                   | has
                                   v  *
                            +--------------+
                            | Transaction  |
                            +--------------+
Legend:  -|>  extends   ..|> implements   <>--  composition/aggregation   -->  association
Visibility: + public  - private  # protected

Draw only: classes, key fields, public methods, relationships. Takes <5 minutes. Then show the main flow as a sequence in one line: Client -> WalletService.transfer -> lock(from,to) -> from.debit -> to.credit -> repo.save(txn).

Step 5: Pick patterns (justify with the problem)

Signal in requirementsPattern
"different pricing/algorithms/payment types"Strategy
"object behaves differently by status"State
"create X depending on type/config"Factory
"notify multiple parties when Y happens"Observer
"undo/redo, queue operations"Command
"validate through several steps"Chain of Responsibility
"add features in combinations"Decorator
"single shared instance"Singleton (state why; mention DI alternative)
"wrap third-party API"Adapter
"simple entry point over many services"Facade
Do not stack patterns for show. Two well-justified beats six decorative.

Step 6: Define APIs before bodies

Write the public interface (method names, parameters, return, exceptions). Example:

interface WalletService {
    Wallet createWallet(String userId);
    void addMoney(String walletId, Money amt, String idempotencyKey);
    Transaction transfer(String from, String to, Money amt, String idempotencyKey) throws InsufficientFundsException;
    List<Transaction> history(String walletId, int limit);
}

Guidelines: return domain objects/Optional, not null; typed exceptions for business failures; immutability for results; idempotency key on mutations (fintech); no UI/IO inside the domain.

Step 7: Code

Order: enums/value objects -> entities -> interfaces -> core implementation -> repository (in-memory) -> service/facade -> Main demo.

  • Code the happy path end-to-end first, then edge cases. A working vertical slice beats many half classes.
  • Package-private/private final by default; constructor injection; no static mutable state.
  • Collections: Map for lookup by id, Deque for history/LRU, PriorityQueue for scheduling, EnumMap for transitions.
  • Meaningful names; small methods; no commented-out code; consistent exceptions.
  • Skip boilerplate verbally ("getters omitted") to save time; ask if allowed.
  • Finish with a runnable main showing 2-3 scenarios + a failure case.

Step 8: Extensibility (say it, show 1 example)

"To add a new payment method: implement PaymentMethod, register in factory. No change in CheckoutService (OCP)." Prepare answers for: new type, new rule, new notification channel, new pricing, persistence swap (Repository), multi-currency, pluggable policy at runtime.

Step 9: Concurrency (almost always asked in fintech)

Identify shared mutable state and invariants, then pick granularity:

  1. What's shared? (balance, seats, inventory, counters, cache)
  2. What invariant? (no negative balance, no double booking, total conserved)
  3. Choose: per-entity lock (ReentrantLock) with lock ordering for multi-entity, ConcurrentHashMap atomic ops, atomics/CAS for counters, optimistic versioning for low contention, BlockingQueue for async work.
  4. Idempotency for duplicate requests; atomicity of compound operations (check-then-act).
  5. Mention: deadlock, visibility (volatile), immutability, lock scope minimal, never call external code under a lock. See 00-concurrency-for-lld.md.

Step 10: Testing and edge cases

  • Unit: each class with fakes (DI makes this easy); table of inputs/expected.
  • Edge: null/empty, zero/negative amount, boundary limits, duplicates, insufficient funds, expired items, capacity full, same-account transfer, rollbacks on partial failure.
  • Concurrency: N threads x M ops, assert invariants; stress with latches.
  • State machines: every illegal transition rejected.
  • State complexity (time/space) of the core operations (e.g. LRU get/put O(1)).

What interviewers evaluate

  1. Requirement handling: asks the right questions, states assumptions.
  2. Object modeling: sensible entities, responsibilities, relationships; not one God class.
  3. Principles/patterns: SOLID applied, patterns justified.
  4. Code quality: compiles, readable, naming, error handling, immutability, Java idioms.
  5. Extensibility: new requirement handled with minimal change.
  6. Concurrency & correctness: race conditions, atomicity, money correctness.
  7. Testability and edge cases.
  8. Communication: structured, collaborative, accepts hints, explains trade-offs.
  9. Time management: working solution within time.

Common mistakes

  • Jumping straight to code without clarifying; designing for imaginary requirements (over-engineering).
  • One giant class; or 30 classes with nothing running.
  • if/else on type everywhere; public mutable fields; static globals.
  • double for money; ignoring currency/rounding.
  • Ignoring concurrency or locking the whole world with one synchronized.
  • Naming a pattern but implementing something else; forcing Singleton everywhere.
  • Silent failures (returning false/null for everything); swallowing exceptions.
  • Mixing I/O (printing) into domain logic; no demo/test.
  • Not handling "what if two requests arrive together?" in a payment system.
  • Defensive silence when stuck: instead think aloud and propose a simpler version.

How to talk while coding

  • Narrate intent, not syntax: "I'm making Money immutable so I can share it across threads safely."
  • State trade-offs: "HashMap now; I'd swap to a DB behind this Repository."
  • Flag shortcuts: "I'm skipping getters/validation here; in production I'd add X."
  • Check in: after requirements, after the diagram, after the API ("OK to proceed?").
  • When a hint is given, take it graciously and adjust; do not argue.
  • Say what you'll do next, then do it. Leave 1-2 min to summarize design + known gaps.
  • If blanking: write the interface first; state the invariants; implement the simplest correct version.

Scoring rubric (typical 1-4 per dimension; hire usually needs ~3 average with no 1s)

Dimension1 (No)2 (Weak)3 (Good)4 (Strong)
Requirementsnone askedfew, not recordedclear scope & assumptionsprobes edge cases, NFRs, money rules
ModelingGod classsome classes, blurred rolesclean entities/servicesright abstractions, value objects, invariants
Patterns/SOLIDnone / misusednamed, loosely appliedfits problem, justifiedminimal and elegant, knows alternatives
Codedoesn't compilepartial, messyworking core, readableidiomatic, tested flow, error handling
Extensibilityrewrite neededwith big editssmall localized editsseams already in design
Concurrencynot consideredmentions synchronizedcorrect locks/atomicsordering, granularity, idempotency, trade-offs
Communicationsilentone-waystructuredcollaborative, drives discussion

One-page checklist (memorize)

Clarify -> Entities -> Relations -> Diagram -> Patterns -> APIs -> Code (happy path first) -> Edge cases -> Extensibility -> Concurrency -> Tests -> Summary