Skip to main content

Documentation Index

Fetch the complete documentation index at: https://resources.devweekends.com/llms.txt

Use this file to discover all available pages before exploring further.

Low Level Design

🚀 What is Low Level Design?

Low Level Design (LLD) is the bridge between system architecture and working code. While High Level Design (HLD) answers “what components do we need?”, LLD answers “how do we implement each component with clean, maintainable, extensible code?”. Think of it this way: HLD is the city plan that decides where to place hospitals, schools, and roads. LLD is the architectural blueprint for each individual building — the floor plan, wiring, plumbing, and structural engineering. Both are essential, but LLD is where abstract ideas become concrete, testable, production-grade software.

Classes & Objects

Design classes, interfaces, and their relationships using OOP principles

Design Patterns

Apply proven Gang of Four solutions to common problems

Clean Code

Write maintainable, extensible, testable code using SOLID
LLD vs HLD: HLD deals with services, databases, and infrastructure at 10,000 feet. LLD zooms into a single service to design classes, methods, and code structure. Master both for complete system design interviews!

📊 Course Stats

6+

Case Studies

23

Design Patterns

5

SOLID Principles

45 min

Interview Framework

✅ Prerequisites

Before diving into LLD, make sure you’re comfortable with:
  • Variables, functions, loops, conditionals
  • Basic data structures (arrays, dictionaries, sets)
  • At least one OOP language (Python, Java, C++, TypeScript)
  • Classes and objects
  • Methods and attributes
  • Basic inheritance
Don’t worry if you’re rusty - we cover these in depth!

🎯 Learning Path

Follow this structured 4-week journey to master LLD:
1

Week 1: Master OOP Fundamentals

Goal: Build a rock-solid foundation with the four pillars of OOP

OOP Concepts

Encapsulation, Abstraction, Inheritance, Polymorphism

OOP Deep Dive

Beginner-friendly explanations with real-world examples
Practice: Build a simple BankAccount class with proper encapsulation
2

Week 2: Learn SOLID Principles

Goal: Write code that’s easy to maintain, test, and extend

SOLID in Practice

Real refactoring examples for each principle

SOLID Deep Dive

Step-by-step guide with before/after comparisons
Practice: Refactor a “God class” into well-separated components
3

Week 3: Study Design Patterns

Goal: Learn the Gang of Four patterns and when to apply them

Design Patterns

Creational, Structural, and Behavioral patterns

UML Diagrams

Class diagrams and sequence diagrams for interviews
Focus on: Factory, Strategy, Observer, State, Singleton (covers 80% of interviews)
4

Week 4: Practice Case Studies

Goal: Apply everything to real-world problems under time pressure

Parking Lot

🟢 Beginner

Vending Machine

🟢 Beginner - State Pattern

LRU Cache

🟡 Intermediate - Data Structures

Movie Ticket

🟡 Intermediate - Concurrency

Chess Game

🟡 Intermediate

Elevator

🔴 Advanced
Practice: Time yourself - complete each case study in 45 minutes

🏆 Why LLD Matters for Interviews

LLD rounds are make-or-break at top tech companies. They test if you can translate high-level ideas into working, maintainable, production-ready code. Unlike algorithm rounds that test raw problem-solving, LLD rounds reveal how you think about software at scale — your instincts about where to draw class boundaries, when to reach for a pattern, and how to communicate trade-offs. This is the round that separates engineers who write code from engineers who design systems.
Companies with LLD Rounds: Google, Amazon, Microsoft, Meta, Apple, Uber, Airbnb, Stripe, and most Series B+ startups include LLD in their interview process.

Object-Oriented Thinking

Can you identify the right abstractions and model real-world entities as classes?

Pattern Recognition

Do you recognize when to apply Factory, Strategy, Observer, State patterns?

Code Quality

Is your code clean, readable, following naming conventions and best practices?

Trade-off Analysis

Can you explain WHY you chose one approach over another with pros/cons?

Extensibility

Can your design handle new requirements without rewriting existing code?

Edge Case Handling

Do you consider concurrency, errors, null cases, and boundary conditions?

What Interviewers Actually Evaluate

CriteriaWeightWhat They Look For
Requirement Gathering10%Do you ask the right clarifying questions?
Class Design25%Are your classes well-named, single-purpose, properly related?
Design Patterns20%Do you apply appropriate patterns without over-engineering?
Code Quality20%Is your code clean, readable, and following conventions?
SOLID Principles15%Does your design follow SOLID? Can you explain violations?
Communication10%Did you explain your thinking throughout the process?

📋 The LLD Interview Framework (45 min)

Master this framework to ace any LLD interview:
┌─────────────────────────────────────────────────────────────┐
│  PHASE 1: Requirements (5 min)                              │
│  ├── Clarify scope and constraints                         │
│  └── Identify actors and use cases                         │
├─────────────────────────────────────────────────────────────┤
│  PHASE 2: Core Design (20 min)                              │
│  ├── Identify entities and relationships                   │
│  ├── Draw class diagram                                     │
│  └── Define key interfaces and methods                     │
├─────────────────────────────────────────────────────────────┤
│  PHASE 3: Deep Dive (15 min)                                │
│  ├── Implement core logic                                   │
│  ├── Apply design patterns                                  │
│  └── Handle edge cases                                      │
├─────────────────────────────────────────────────────────────┤
│  PHASE 4: Discussion (5 min)                                │
│  ├── Explain trade-offs                                     │
│  └── Discuss extensions                                     │
└─────────────────────────────────────────────────────────────┘

📚 Common LLD Interview Problems

By Difficulty Level

ProblemKey ConceptsCase Study
Parking LotOOP basics, Strategy patternView →
Library ManagementCRUD, RelationshipsView →
Vending MachineState pattern, InventoryComing Soon
ATM SystemState pattern, TransactionsView →
ProblemKey ConceptsCase Study
Elevator SystemState pattern, SchedulingView →
Chess GamePolymorphism, CommandView →
Hotel BookingReservation, ConcurrencyView →
Movie Ticket BookingSeat allocation, TransactionsStart →
Food Delivery AppMultiple actors, StateComing Soon
Online Shopping CartOrder flow, DiscountsComing Soon
ProblemKey ConceptsCase Study
Ride Sharing (Uber/Ola)Matching, Real-time, LocationComing Soon
Social Media FeedObserver, Timeline, CachingComing Soon
Stock ExchangeOrder matching, ConcurrencyComing Soon
SplitwiseGraph, Debt simplificationComing Soon
Rate LimiterToken bucket, Sliding windowComing Soon

By Design Pattern Focus

PatternBest Practice Problems
StrategyPayment processing, Shipping methods, Pricing
FactoryVehicle creation, Notification channels
ObserverStock alerts, Order status, Movie Booking
StateOrder lifecycle, Elevator, Vending Machine
DecoratorCoffee shop, Pizza toppings, Permissions
SingletonDatabase connection, Configuration, Logger
HashMap + DLLLRU Cache, Browser History

🔧 Quick Reference: Core Concepts

The Four Pillars of OOP

# ENCAPSULATION - Hide internal state
class BankAccount:
    def __init__(self):
        self.__balance = 0  # Private
    
    def deposit(self, amount):  # Controlled access
        if amount > 0:
            self.__balance += amount

# ABSTRACTION - Hide complexity
class PaymentProcessor(ABC):
    @abstractmethod
    def process(self, amount): pass  # What, not how

# INHERITANCE - Share behavior
class Car(Vehicle):
    def __init__(self):
        super().__init__()  # Reuse parent

# POLYMORPHISM - Same interface, different behavior
def make_sound(animal: Animal):
    animal.speak()  # Works for Dog, Cat, Bird...

SOLID Principles One-Liners

PrincipleRuleExample
Single ResponsibilityOne class, one reason to changeOrder shouldn’t send emails
Open/ClosedExtend, don’t modifyAdd new PaymentMethod, don’t edit old ones
Liskov SubstitutionSubtypes are substitutablePenguin shouldn’t break Bird.fly()
Interface SegregationSmall, focused interfacesReadable vs ReadableWritable
Dependency InversionDepend on abstractionsInject Database, not PostgreSQL

Pattern Quick Reference

# SINGLETON - One instance
class Logger:
    _instance = None
    def __new__(cls):
        if not cls._instance:
            cls._instance = super().__new__(cls)
        return cls._instance

# FACTORY - Create without specifying class
def create_vehicle(type: str) -> Vehicle:
    return {"car": Car, "bike": Bike}[type]()

# STRATEGY - Swappable algorithms
class PaymentContext:
    def __init__(self, strategy: PaymentStrategy):
        self.strategy = strategy
    def pay(self, amount):
        return self.strategy.process(amount)

# OBSERVER - Notify on changes
class Stock:
    def __init__(self):
        self.observers = []
    def notify(self):
        for obs in self.observers:
            obs.update(self)

📖 Case Studies

🅿️ Parking Lot System

Multi-floor parking with different vehicle types, pricing, and slot allocation
Beginner Strategy Pattern

📚 Library Management

Books, members, borrowing, fines, and reservations with search
Beginner CRUD

🛗 Elevator System

Multiple elevators with smart scheduling algorithms
Intermediate State Pattern

♟️ Chess Game

Full chess implementation with piece movement and game rules
Intermediate Polymorphism

🏨 Hotel Booking

Room booking, reservations, and cancellation with concurrency
Intermediate Transactions

🏧 ATM System

Cash withdrawal, deposits, and balance inquiry with state machine
Beginner State Pattern

💡 Pro Tips for LLD Interviews

Don’t try to build the perfect design upfront. Start with core classes that work, then add complexity. Interviewers want to see your iterative thinking. A senior engineer at Uber once described this as “make it work, make it right, make it extensible” — in that exact order. Showing this progression in 45 minutes is what gets you a strong hire signal.
Explain your reasoning as you design. “I’m making this an interface because we might have multiple implementations” shows depth. The best candidates narrate their decision-making: “I could use inheritance here, but composition gives me more flexibility since payment methods change frequently.” This signals that you are not just coding from memory — you are making deliberate engineering trade-offs.
Don’t assume. Ask about scale, users, and constraints. This shows you think like a senior engineer.
Memorize when to use Factory, Strategy, Observer, and State. These cover 80% of LLD interviews.
Design so new requirements don’t require rewriting. “If we need to add X later, we just create a new class implementing Y.”
Mention concurrency, null checks, and error handling. Even if you don’t implement them, show you’re aware. A simple “I’d add a lock here to prevent two users from booking the same seat” demonstrates production-readiness thinking that separates mid-level from senior candidates. Interviewers at companies like Amazon specifically look for this awareness — they call it “operational excellence.”

OOP Concepts

Foundation

SOLID Principles

Clean Code

Design Patterns

Solutions

UML Diagrams

Visualization

Interview Cheat Sheet

Quick Reference

Case Studies

Practice

Interview Deep-Dive

Strong Answer:
  • I follow a four-phase framework. First, I spend about five minutes on requirements: clarifying scope, identifying actors, and asking what is explicitly out of scope. This prevents over-engineering.
  • Second, I spend twenty minutes on core design. I list nouns from the problem statement, which become classes. I list verbs, which become methods. I then map relationships: is-a for inheritance, has-a for composition, and uses for dependency. I sketch a class diagram with key attributes and methods only — no boilerplate.
  • Third, I spend fifteen minutes on implementation. I code the happy path first, then layer in design patterns where they solve a real problem (not to show off). I mention edge cases even if I do not fully implement them.
  • Fourth, I spend five minutes discussing trade-offs: why I chose one approach over another, how the design handles new requirements, and where I would add caching, logging, or concurrency controls in production.
  • The key insight is that I start simple and iterate. An interviewer would rather see a clean three-class design that you evolve than a ten-class over-engineered design that you cannot explain.
Follow-up: How do you decide whether to use inheritance or composition when modeling relationships?I apply the “is-a” test strictly. If the relationship is genuinely an identity relationship that will remain stable over time — for example, a Dog is-a Animal — inheritance is appropriate. But if the relationship involves behaviors that might change or be mixed at runtime — for example, payment methods or notification channels — I reach for composition and the Strategy pattern. The Gang of Four guideline “favor composition over inheritance” exists because inheritance creates tight coupling that is expensive to undo. In a real interview, I would say something like: “I could use inheritance here, but the payment method might change at runtime, so composition gives me the flexibility to swap strategies without modifying existing classes.”
Strong Answer:
  • A God class is one that has accumulated too many responsibilities. The fix is systematic application of the Single Responsibility Principle. I would identify each distinct “reason to change” in the class — for example, if an OrderManager handles data persistence, email notifications, pricing calculations, and PDF generation, those are four separate reasons to change.
  • I would extract each responsibility into its own class: OrderRepository for persistence, NotificationService for emails, PricingService for calculations, InvoiceExporter for PDF generation. The original class becomes a thin coordinator (sometimes called a Facade) that delegates to these focused services.
  • The practical benefit is testability. A God class with five responsibilities requires mocking five different external systems to unit test. Five focused classes each require mocking at most one or two dependencies.
  • In an interview, I would physically draw the extraction on the whiteboard: show the original class, draw arrows to the new classes, and explain how each extracted class has a single, clear reason to change.
Follow-up: Is there ever a case where having a larger class is acceptable?Yes. SRP does not mean every class should have one method. It means one reason to change. A PricingService might have methods for calculating discounts, applying taxes, and converting currencies — but they all change for the same reason: pricing rules change. Over-splitting creates “class explosion” where you have dozens of tiny classes that are harder to navigate than one well-organized class. The judgment call is: would this class need to change for genuinely different reasons owned by different teams? If not, keeping related logic together is fine.
Strong Answer:
  • I draw a class diagram as my primary artifact. I start with three to five core classes showing just the class name and the relationship arrows. Then I progressively add key attributes and method signatures as the conversation evolves. I use proper UML notation for relationships: filled diamond for composition, open diamond for aggregation, dashed arrow with open triangle for interface implementation, and solid arrow with open triangle for inheritance.
  • I annotate multiplicity on every relationship. Saying “Customer has Orders” is vague. Writing “1 to 0..*” is precise and shows the interviewer I think about cardinality.
  • I would skip sequence diagrams unless the interviewer specifically asks about a complex interaction flow (like a checkout process with multiple services). I would also skip use case diagrams entirely — they are too high-level for LLD.
  • What I would not skip: visibility markers (+ for public, - for private, # for protected). Getting these right shows I am thinking about encapsulation at the design level, not just at the code level.
Follow-up: How do you decide between composition and aggregation in your class diagram?The distinction is lifecycle ownership. Composition (filled diamond) means the contained object cannot exist without the container. If I delete an Order, the OrderItems die with it — that is composition. Aggregation (open diamond) means the contained object has an independent lifecycle. If I dissolve a Team, the Players still exist — that is aggregation. In practice, most relationships in LLD interviews are composition. I default to composition unless there is a clear reason why the contained object should outlive its container.
Strong Answer:
  • Factory, Strategy, Observer, State, and Singleton. These five cover roughly eighty to ninety percent of LLD interview scenarios.
  • Factory is essential because almost every system needs to create objects without coupling to concrete types. When the interviewer asks “how would you add a new vehicle type,” Factory is the answer.
  • Strategy is the workhorse pattern for the Open/Closed Principle. Whenever you have interchangeable algorithms — pricing rules, payment methods, sorting strategies, scheduling algorithms — Strategy lets you add new behavior without modifying existing code.
  • Observer handles event-driven requirements: notifying users of stock price changes, sending order status updates, or broadcasting system alerts. It decouples the publisher from the subscriber.
  • State eliminates sprawling if/elif chains by modeling each state as its own class. ATM machines, elevator systems, vending machines, and order lifecycles are all state machine problems.
  • Singleton is simple but frequently tested. Database connections, configuration managers, and loggers are classic Singleton use cases. The key is knowing when Singleton is appropriate and when dependency injection is a better alternative.
  • I would mention Builder as a bonus for complex object construction, and Decorator for layered behavior (middleware, permissions), but those appear less frequently in interviews.
Follow-up: What is the difference between Strategy and State, since they look structurally similar?They are structurally identical — both delegate to an interface that has multiple implementations. The difference is intent and control flow. With Strategy, the client explicitly chooses which algorithm to use, and the choice is usually stable for the duration of an operation. With State, the object itself transitions between states, and the current state determines behavior. The state object typically triggers its own transitions. A good heuristic: if the behavior swap is driven by external configuration or user choice, it is Strategy. If the behavior swap is driven by internal lifecycle events, it is State.