Chapter 09 · Article 43 of 55
How to Approach a Low-Level Design (LLD) Interview
A Low-Level Design interview evaluates your ability to translate a vague problem statement into a well-structured, extensible object-oriented solution within 45-60 minutes. Unli…
Article outline15 sections on this page+
Overview
A Low-Level Design interview evaluates your ability to translate a vague problem statement into a well-structured, extensible object-oriented solution within 45-60 minutes. Unlike system design (HLD) rounds that focus on distributed systems and scalability, LLD rounds test your mastery of OOP principles, design patterns, clean code, and the ability to think through edge cases methodically.
What Interviewers Evaluate
- Object-Oriented Thinking - Can you model real-world entities as classes with clear responsibilities?
- Design Pattern Application - Do you reach for the right pattern without over-engineering?
- Extensibility - Can your design accommodate new requirements without rewriting core logic?
- Code Quality - Are your naming conventions, method signatures, and class hierarchies clean?
- Communication - Can you articulate trade-offs and walk through your thought process?
How LLD Rounds Differ Across Companies
| Company Type | Duration | Expectation | Format |
|---|---|---|---|
| FAANG | 45-60 min | Full working code in IDE, tested | Live coding + design discussion |
| Startups | 30-45 min | Class diagram + key method implementations | Whiteboard or shared doc |
| Product Companies | 45-60 min | Complete design with extensibility discussion | IDE or whiteboard |
| Service Companies | 30 min | UML diagram + pattern identification | Verbal + diagram |
At FAANG, you're expected to write compilable code. At startups, demonstrating clear thinking matters more than perfect syntax. Product companies often want both - a solid design and working core logic.
Step-by-Step Framework
Use this 45-minute framework to structure your approach consistently:
┌─────────────────────────────────────────────────────────────────────────┐
│ 45-MINUTE LLD INTERVIEW TIMELINE │
├────────┬────────┬────────┬──────────────┬──────────────────┬────────────┤
│ Step 1 │ Step 2 │ Step 3 │ Step 4 │ Step 5 │ Step 6 │
│Clarify │Entities│Relations│ Class Design │ Implement Core │ Extensions │
│ Reqs │ │ │ │ Logic │ │
│ 5 min │ 5 min │ 5 min │ 10 min │ 15 min │ 5 min │
├────────┼────────┼────────┼──────────────┼──────────────────┼────────────┤
│ 0 │ 5 │ 10 │ 15 │ 25 │ 40 45 │
└────────┴────────┴────────┴──────────────┴──────────────────┴────────────┘
Step 1: Clarify Requirements (5 min)
Never jump into design immediately. Ask targeted questions to narrow scope.
Functional Requirements - Ask:
- What are the core use cases? (e.g., "Should the system support reservations or only walk-ins?")
- What are the actors? (admin, user, system)
- What are the key operations? (CRUD, search, notifications)
- Are there business rules? (limits, priorities, constraints)
Non-Functional Requirements - Ask:
- Is concurrency a concern? (multi-threaded access)
- Do we need persistence or is in-memory acceptable?
- What scale are we designing for? (single instance vs distributed)
- Are there latency requirements for any operation?
Pro tip: Write down 4-6 bullet points of confirmed requirements. This becomes your contract with the interviewer and prevents scope creep.
Step 2: Identify Core Entities (5 min)
Use noun extraction from the problem statement. Every significant noun is a potential class.
Entity vs Value Object:
- Entity - Has identity, lifecycle, and behavior (User, Order, Vehicle)
- Value Object - Immutable, defined by attributes only (Address, Money, DateRange)
Technique: List all nouns, then filter:
- Remove duplicates and synonyms
- Remove attributes (these become fields, not classes)
- Group related nouns under a single entity if they share lifecycle
Example for "Design a Parking Lot":
- Nouns: parking lot, floor, spot, vehicle, car, truck, motorcycle, ticket, payment
- Entities: ParkingLot, ParkingFloor, ParkingSpot, Vehicle, Ticket, Payment
- Value Objects: Address, SpotSize
Step 3: Define Relationships (5 min)
Map how entities interact:
| Relationship | Meaning | Example |
|---|---|---|
| Composition | Part cannot exist without whole | ParkingFloor → ParkingLot |
| Aggregation | Part can exist independently | Vehicle → ParkingSpot |
| Association | Uses/references | Ticket → Vehicle |
| Inheritance | IS-A relationship | Car extends Vehicle |
| Implementation | Implements contract | ParkingSpot implements Parkable |
Cardinality: Define 1:1, 1:N, M:N relationships explicitly. This prevents ambiguity in your class design.
Step 4: Design Class Diagram (10 min)
Now structure your classes:
- Define interfaces for behaviors that vary (PaymentStrategy, NotificationService)
- Use abstract classes for shared state + partial implementation (Vehicle with licensePlate)
- List key methods - focus on public API, not internal helpers
- Apply SOLID principles:
- Single Responsibility: One reason to change per class
- Open/Closed: New vehicle types shouldn't modify ParkingSpot
- Liskov Substitution: Any Vehicle subclass works where Vehicle is expected
- Interface Segregation: Don't force classes to implement unused methods
- Dependency Inversion: Depend on abstractions, not concretions
Step 5: Implement Core Logic (15 min)
You cannot code everything. Prioritize:
Always implement:
- The main business operation (park a vehicle, place an order, make a move)
- One design pattern in action (Strategy, Observer, Factory)
- Any algorithm-heavy method (allocation strategy, matching logic)
Skip or pseudocode:
- Getters/setters
- Input validation boilerplate
- Database/persistence layer
- UI/API layer
Depth guideline: Write real code for 3-4 core methods. Use comments like // similar logic for other vehicle types to indicate awareness without wasting time.
Step 6: Discuss Extensions (5 min)
Proactively mention how your design handles:
- Adding a new entity type (new vehicle, new payment method)
- Changing business rules (dynamic pricing, priority changes)
- Scaling concerns (thread safety, caching)
This demonstrates forward-thinking and earns bonus points even if you don't implement it.
What Interviewers Look For
| Criteria | Weight | Excellent (5) | Acceptable (3) | Poor (1) |
|---|---|---|---|---|
| Requirement Gathering | 15% | Asks clarifying questions, documents assumptions | Asks a few questions | Jumps straight to code |
| OOP Design | 25% | Clean hierarchy, proper encapsulation, SOLID | Reasonable classes, minor violations | God classes, no encapsulation |
| Design Patterns | 20% | Applies 2-3 patterns naturally with justification | Uses 1 pattern correctly | No patterns or forced usage |
| Extensibility | 15% | Design accommodates 2+ extensions without changes | Can extend with minor refactoring | Requires rewrite for changes |
| Communication | 15% | Thinks aloud, explains trade-offs, seeks feedback | Explains when asked | Silent coding, no explanation |
| Trade-off Analysis | 10% | Discusses alternatives and why one was chosen | Mentions one alternative | No awareness of alternatives |
Common Mistakes
| Mistake | Impact | Fix |
|---|---|---|
| Starting to code immediately | Miss requirements, redesign mid-interview | Spend first 5 min on requirements |
| God class with all logic | Violates SRP, impossible to extend | Split by responsibility |
| Over-engineering with patterns | Wastes time, adds complexity | Use patterns only when they solve a real problem |
| Ignoring edge cases | Shows lack of thoroughness | List 2-3 edge cases before coding |
| Not using enums for fixed sets | Stringly-typed code, error-prone | Use enums for types, statuses, sizes |
| Tight coupling between classes | Cannot extend or test independently | Program to interfaces |
| No access modifiers | Everything public, no encapsulation | Default to private, expose minimally |
| Implementing everything | Runs out of time on boilerplate | Prioritize core logic, pseudocode the rest |
| Ignoring concurrency when asked | Misses thread-safety requirements | Use synchronized blocks, locks, or concurrent collections |
| Not validating inputs | Null pointers, invalid state | Add guards at public method boundaries |
Communication Tips
Think Aloud
Narrate your thought process: "I'm considering using a Strategy pattern here because the pricing logic varies by vehicle type and could change independently."
When to Ask vs Decide
- Ask when the decision changes the scope significantly (e.g., "Should I support multiple parking lots?")
- Decide when it's an implementation detail (e.g., "I'll use a HashMap for O(1) spot lookup")
When You're Stuck
- Don't go silent. Say: "Let me think about this for a moment."
- Decompose: Break the problem into smaller sub-problems.
- Start simple: Implement the naive solution, then refine.
- Ask for a hint: "Would you like me to focus on the allocation strategy or the payment flow?"
Framing Trade-offs
Use this template: "I chose X over Y because [reason]. The trade-off is [downside], which is acceptable here because [justification]."
Structuring Your Explanation
When presenting your design, follow this order:
- High-level overview - "The system has these 4 main components..."
- Zoom into each component - "The ParkingSpot class is responsible for..."
- Show interactions - "When a vehicle arrives, the flow is..."
- Highlight design decisions - "I used Strategy here because..."
Body Language and Confidence
- Maintain a steady pace - rushing signals nervousness
- Use the whiteboard/screen as a visual anchor while explaining
- Pause before answering follow-ups - it shows deliberation, not hesitation
- If you realize a mistake, correct it openly: "Actually, let me reconsider this - a better approach would be..."
Design Patterns Cheat Sheet
| # | Problem/Scenario | Pattern | Example |
|---|---|---|---|
| 1 | Multiple object creation logic | Factory Method | VehicleFactory.create(type) |
| 2 | Complex object with many optional fields | Builder | Ticket.builder().vehicle(v).build() |
| 3 | Only one instance needed globally | Singleton | ParkingLotManager.getInstance() |
| 4 | Algorithm varies at runtime | Strategy | PricingStrategy (hourly, flat, dynamic) |
| 5 | React to state changes | Observer | NotifyUser on spot availability |
| 6 | Add behavior without modifying class | Decorator | LoggingDecorator on PaymentService |
| 7 | Simplify complex subsystem access | Facade | ParkingService wrapping floor/spot/ticket |
| 8 | Represent hierarchies (part-whole) | Composite | Menu with MenuItems and SubMenus |
| 9 | Control access to an object | Proxy | CachedParkingSpotProxy |
| 10 | Convert incompatible interfaces | Adapter | ThirdPartyPaymentAdapter |
| 11 | Decouple request sender from handler | Chain of Responsibility | Validation chain, approval workflow |
| 12 | Encapsulate actions as objects | Command | UndoableAction, OrderCommand |
| 13 | Traverse collection without exposing internals | Iterator | FloorIterator over spots |
| 14 | Define skeleton algorithm, defer steps | Template Method | GameFlow with initialize/play/end |
| 15 | Object state changes behavior | State | VendingMachine states (Idle, Dispensing) |
| 16 | Manage object lifecycle/reuse | Object Pool | ConnectionPool, ThreadPool |
| 17 | Notify multiple subscribers | Pub/Sub (Observer variant) | EventBus for notifications |
| 18 | Separate construction from representation | Abstract Factory | UIFactory (DarkTheme, LightTheme) |
| 19 | Share common state across objects | Flyweight | ChessPiece shared textures |
| 20 | Snapshot and restore object state | Memento | Undo in text editor |
| 21 | Define grammar and interpret sentences | Interpreter | Rule engine, query parser |
| 22 | Decouple abstraction from implementation | Bridge | Shape + Renderer separation |
| 23 | Provide default behavior for interface | Null Object | NullLogger, GuestUser |
| 24 | Lazy initialization of heavy objects | Virtual Proxy | LazyLoadImage |
Time Management
Pacing Rules
- If you're at 15 min and haven't started class design - you've over-discussed. Summarize requirements and move on.
- If you're at 30 min and haven't written code - skip the perfect diagram and start implementing.
- If you're at 40 min and still coding - wrap up current method, move to extensions discussion.
What to Prioritize
- Core business logic (the "main" operation)
- One well-applied design pattern
- Clean class hierarchy with proper relationships
What to Skip
- Exhaustive error handling
- Logging infrastructure
- Database schema
- Complete getters/setters
- UI/Controller layer
Handling Follow-up Questions
Follow-ups test your design's flexibility. Common ones:
| Follow-up | How to Respond |
|---|---|
| "Add concurrency support" | Identify shared mutable state, add synchronization (locks, concurrent collections), discuss race conditions |
| "Add a new feature (e.g., EV charging spots)" | Show how your design accommodates it via inheritance/composition without modifying existing classes (Open/Closed) |
| "Scale it to multiple locations" | Extract location-specific logic, introduce a registry/manager pattern, discuss data partitioning |
| "Add real-time notifications" | Introduce Observer pattern, discuss push vs pull, event-driven architecture |
| "Handle payment failures" | Add retry logic, state machine for payment status, compensating transactions |
| "Support undo operations" | Command pattern with undo stack, Memento for state snapshots |
Response framework:
- Acknowledge the requirement
- Identify which class/interface needs to change
- Explain the minimal change needed
- Mention the pattern that enables it
Practice Strategy
Which Problems to Practice
Start with these categories in order:
- Structural - Parking Lot, Library Management, Hotel Booking
- Behavioral - Vending Machine, ATM, Elevator System
- Game-based - Chess, Tic-Tac-Toe, Snake & Ladder
- Real-world - Splitwise, BookMyShow, Food Delivery
How Often
- Weeks 1-2: 1 problem per day (focus on framework adherence)
- Weeks 3-4: 1 problem every 2 days (focus on speed and patterns)
- Week 5+: Mock interviews with timer (45 min strict)
Self-Evaluation Criteria
After each practice session, score yourself:
- Did I clarify requirements before designing? (Y/N)
- Can I add a new type without modifying existing code? (Y/N)
- Did I apply at least 2 design patterns appropriately? (Y/N)
- Is my code readable without comments? (Y/N)
- Did I finish within 45 minutes? (Y/N)
- Can I explain every design decision? (Y/N)
Mock Interview Tips
- Record yourself solving a problem and watch it back - you'll notice verbal tics, long silences, and unclear explanations
- Practice with a peer who can ask follow-up questions unpredictably
- Simulate real conditions: use a timer, don't look up documentation, use a plain editor
- After each mock, write down: what went well, what didn't, and one specific improvement for next time
Building Pattern Recognition
The fastest way to improve is to solve the same problem twice:
- First attempt: struggle through it, make mistakes, learn
- Second attempt (3 days later): apply lessons, aim for clean execution under time pressure
This spaced repetition builds the muscle memory needed to recognize patterns instantly during real interviews.
Sample Interview Walkthrough: Parking Lot
Step 1 - Clarify: "How many floors? Vehicle types? Payment methods? Is it multi-entry/exit?" → Confirmed: Multi-floor, 3 vehicle types (car, truck, motorcycle), hourly billing, single entry/exit.
Step 2 - Entities: ParkingLot, ParkingFloor, ParkingSpot, Vehicle (abstract), Car, Truck, Motorcycle, Ticket, Payment.
Step 3 - Relationships:
- ParkingLot composes multiple ParkingFloors
- ParkingFloor composes multiple ParkingSpots
- Ticket associates with Vehicle and ParkingSpot
- Payment associates with Ticket
Step 4 - Class Design:
interface ParkingStrategy { ParkingSpot findSpot(Vehicle v); }
abstract class Vehicle { String licensePlate; VehicleType type; }
class ParkingSpot { SpotSize size; boolean isOccupied; Vehicle currentVehicle; }
class Ticket { String id; Vehicle vehicle; ParkingSpot spot; LocalDateTime entryTime; }
class ParkingLot { List<ParkingFloor> floors; ParkingStrategy strategy; }
Step 5 - Core Logic: Implement parkVehicle() using Strategy pattern for spot allocation, unparkVehicle() with billing calculation.
Step 6 - Extensions: "If we needed EV charging, I'd add a ChargingSpot extends ParkingSpot with a ChargingStrategy. No existing code changes needed."
Red Flags That Fail Candidates
| Red Flag | Why It Fails You |
|---|---|
| Writing 500+ lines of boilerplate | Shows inability to prioritize |
| Single class with all methods | No understanding of OOP |
| No interfaces or abstractions | Design cannot evolve |
| Copy-pasting logic across classes | Violates DRY, misses inheritance/composition |
| Arguing with interviewer's suggestions | Poor collaboration signal |
| Cannot explain own code | Suggests copied solution |
| Ignoring stated requirements | Shows poor listening |
| Using design patterns incorrectly | Worse than not using them |
| No consideration of edge cases | Lacks engineering rigor |
| Refusing to simplify when asked | Inflexibility, ego over pragmatism |
Interview Follow-ups
Q&A
Q1: How much code do interviewers actually expect in 45 minutes? A: Typically 150-250 lines of meaningful code. Focus on core classes and 3-4 key methods. Interviewers prefer clean, well-structured partial implementations over complete but messy code.
Q2: Should I use a specific programming language? A: Use the language you're most fluent in. Java and Python are most common for LLD. The interviewer cares about design thinking, not language-specific syntax. However, if the job requires a specific language, use that.
Q3: What if my design has a flaw and the interviewer points it out? A: Acknowledge it gracefully: "Good point - that violates Open/Closed. Let me refactor by introducing an interface here." Interviewers test how you respond to feedback, not whether your first attempt is perfect.
Hints Only
H1: How do you decide between inheritance and composition in an interview? Think about whether the relationship is "is-a" or "has-a". Consider what changes more frequently - behavior or identity. Remember the principle: "Favor composition over inheritance."
H2: When should you proactively bring up design patterns vs wait to be asked? Consider the natural points in your design where a pattern solves a real problem. Think about whether naming the pattern adds clarity to your explanation or sounds like name-dropping.
Counter Questions to Ask Interviewer
Asking thoughtful questions signals seniority and genuine interest:
- "What does a typical LLD challenge look like on the team - greenfield design or evolving existing systems?" - Shows you think about real work context.
- "How does the team approach design reviews? Is there a formal process?" - Signals you value collaboration.
- "What's the most complex domain model the team manages?" - Shows curiosity about technical depth.
- "How do you balance design purity with delivery speed?" - Demonstrates pragmatism.
- "What testing strategy does the team use for complex business logic?" - Shows quality mindset.
References
Books
- Head First Design Patterns - Freeman & Robson (beginner-friendly)
- Design Patterns: Elements of Reusable Object-Oriented Software - Gang of Four (reference)
- Clean Code - Robert C. Martin (code quality)
- Refactoring - Martin Fowler (improving existing designs)
YouTube Channels
- Concept && Coding - LLD problems with Java implementations
- Sudocode - Visual explanations of design patterns
- Tech Dummies - Interview-focused LLD walkthroughs
- Christopher Okhravi - Design patterns deep dives
Practice Platforms
- GitHub LLD repositories (search "awesome-low-level-design")
- Educative.io - Grokking the Object-Oriented Design Interview
- InterviewReady - LLD module with video solutions
Related Topics
- SOLID Principles in Practice
- Design Patterns Overview
- Parking Lot Design
- Library Management System
- Elevator System Design
- Vending Machine Design
- Chess Game Design
- Splitwise Design
- BookMyShow Design
- Snake and Ladder Design
- Hotel Booking System
- Food Delivery System
- ATM Machine Design
- Tic-Tac-Toe Design
- LLD Best Practices
- Common LLD Anti-Patterns