Low Level Design (LLD) Interview Questions 2026: Top 20 Designs [Solved]

What changed in 2026 drives
Mass-recruiter offer letters are flatter for 2026 batch - the 4-5 LPA ASE band has barely budged in three years while inflation eats real wages. Premium tracks (Digital, Pro, Elite, Specialist) are still where the differential lives, and they are entirely test-driven. If you are aiming higher than the default offer, the coding round is not optional pageantry - it is the entire interview.
What I'd actually study for this
- 01Two solid coding-round answers (1 medium-hard DSA each, with edge-case discussion) > five half-baked ones
- 02One real project you can defend end-to-end - file paths, design decisions, and what you would change
- 03One DBMS schema you actually built (not a textbook ER diagram), with at least 3 join-heavy queries written from memory
- 04Three behavioural STAR stories: failure recovered, conflict handled, ownership taken
Where most candidates trip up
The single biggest mistake is treating company-specific guides as primary prep and DSA as secondary. It is the opposite. Mass recruiters use the test as a filter, but premium tracks at every IT services company use coding to allocate offer band. Spend 70% of prep time on DSA + system fundamentals, 20% on company-specific patterns, 10% on HR rehearsal. Reverse that ratio and you collect the default offer.
Editorial commentary by Aditya Sharma · written for PapersAdda · not generated, not aggregated.
Last Updated: June 2026
Why LLD Rounds Are Critical in 2026
Candidates report LLD rounds as the deciding factor in roughly 30-40% of SDE-2 and senior engineer offers at companies like Flipkart, Paytm, Swiggy, Zomato, Razorpay, and Amazon India. Based on public preparation resources and candidate-reported interview threads, LLD rounds have become standard not just at product companies but at late-stage startups.
The LLD round tests whether you can translate requirements into maintainable, extensible code before writing a single line. Interviewers assess your object-oriented thinking, SOLID adherence, and ability to identify the right design patterns.
The LLD Interview Framework
1. Gather Requirements (5 min)
- Functional: what does the system do?
- Non-functional: concurrency, scalability needs?
- Out of scope: what will you NOT design today?
2. Identify Entities (5 min)
- List nouns from requirements -> candidate classes
- Identify relationships: has-a, is-a, uses
3. Define Interfaces and Abstract Classes (5 min)
- What behaviors are common across variants?
- Where do you need polymorphism?
4. Design Classes (15 min)
- Attributes, methods, access modifiers
- Which design pattern fits?
5. Handle Edge Cases and Concurrency (5 min)
- Thread safety, locks, atomic operations
- Null checks, empty states
SOLID Principles Quick Reference
| Principle | One-line rule | Common violation |
|---|---|---|
| Single Responsibility | One class, one reason to change | God class that does everything |
| Open/Closed | Extend via inheritance, not modification | Switching on type instead of polymorphism |
| Liskov Substitution | Subclass must work wherever parent works | Override that changes behavior silently |
| Interface Segregation | Many small interfaces over one fat one | Interface with 20 methods, most unimplemented |
| Dependency Inversion | Depend on abstractions, not concretions | New ClassName() deep in business logic |
Design 1: Parking Lot
Asked at: Amazon, Flipkart, Paytm, Swiggy, Uber
Requirements:
- Multiple floors, multiple spots per floor
- Spot types: Compact, Large, Handicapped, Motorcycle
- Vehicle types: Car, Truck, Motorcycle
- Issue/validate tickets, calculate fee on exit
- Real-time availability tracking
from enum import Enum
from datetime import datetime
import threading
class SpotType(Enum):
MOTORCYCLE = 1
COMPACT = 2
LARGE = 3
HANDICAPPED = 4
class VehicleType(Enum):
MOTORCYCLE = 1
CAR = 2
TRUCK = 3
class Vehicle:
def __init__(self, license_plate, vehicle_type):
self.license_plate = license_plate
self.vehicle_type = vehicle_type
class ParkingSpot:
def __init__(self, spot_id, spot_type, floor):
self.spot_id = spot_id
self.spot_type = spot_type
self.floor = floor
self.is_available = True
self.vehicle = None
def park(self, vehicle):
self.vehicle = vehicle
self.is_available = False
def unpark(self):
self.vehicle = None
self.is_available = True
class Ticket:
def __init__(self, ticket_id, vehicle, spot, entry_time):
self.ticket_id = ticket_id
self.vehicle = vehicle
self.spot = spot
self.entry_time = entry_time
self.exit_time = None
class PricingStrategy:
def calculate_fee(self, duration_hours, vehicle_type):
raise NotImplementedError
class FlatRatePricing(PricingStrategy):
def calculate_fee(self, duration_hours, vehicle_type):
rates = {VehicleType.MOTORCYCLE: 20, VehicleType.CAR: 40, VehicleType.TRUCK: 80}
return rates[vehicle_type] * max(1, int(duration_hours))
class ParkingLot:
"""
Strategy pattern for pricing. Thread-safe entry/exit.
"""
def __init__(self, pricing_strategy=None):
self.floors = []
self.tickets = {}
self.lock = threading.Lock()
self.pricing = pricing_strategy or FlatRatePricing()
self._ticket_counter = 0
def add_floor(self, floor):
self.floors.append(floor)
def _find_spot(self, vehicle_type):
# Vehicle -> compatible spot types
compatible = {
VehicleType.MOTORCYCLE: [SpotType.MOTORCYCLE, SpotType.COMPACT],
VehicleType.CAR: [SpotType.COMPACT, SpotType.LARGE],
VehicleType.TRUCK: [SpotType.LARGE]
}
valid_types = compatible[vehicle_type]
for floor in self.floors:
for spot in floor:
if spot.is_available and spot.spot_type in valid_types:
return spot
return None
def park_vehicle(self, vehicle):
with self.lock:
spot = self._find_spot(vehicle.vehicle_type)
if not spot:
return None # lot is full
spot.park(vehicle)
self._ticket_counter += 1
ticket = Ticket(self._ticket_counter, vehicle, spot, datetime.now())
self.tickets[self._ticket_counter] = ticket
return ticket
def exit_vehicle(self, ticket_id):
with self.lock:
ticket = self.tickets.get(ticket_id)
if not ticket:
return None
ticket.exit_time = datetime.now()
duration = (ticket.exit_time - ticket.entry_time).total_seconds() / 3600
fee = self.pricing.calculate_fee(duration, ticket.vehicle.vehicle_type)
ticket.spot.unpark()
return fee
Design patterns used: Strategy (pricing), Factory (implicit in vehicle creation), Iterator (searching spots)
Design 2: Library Management System
Asked at: TCS Digital, Infosys Power Programmer, Amazon India
Requirements: Books, members, borrowing/returning, fines, reservations
from datetime import date, timedelta
from collections import defaultdict
class BookStatus(Enum):
AVAILABLE = 1
BORROWED = 2
RESERVED = 3
class Book:
def __init__(self, isbn, title, author):
self.isbn = isbn
self.title = title
self.author = author
self.status = BookStatus.AVAILABLE
class Member:
MAX_BOOKS = 5
FINE_PER_DAY = 5
def __init__(self, member_id, name):
self.member_id = member_id
self.name = name
self.borrowed_books = {} # isbn -> borrow_date
self.fines = 0
def can_borrow(self):
return len(self.borrowed_books) < self.MAX_BOOKS
def calculate_fine(self, isbn, due_days=14):
if isbn not in self.borrowed_books:
return 0
borrow_date = self.borrowed_books[isbn]
due_date = borrow_date + timedelta(days=due_days)
today = date.today()
if today > due_date:
return (today - due_date).days * self.FINE_PER_DAY
return 0
class LibraryCatalog:
def __init__(self):
self.books = {} # isbn -> Book
self.search_index = defaultdict(list) # title/author -> [isbn]
def add_book(self, book):
self.books[book.isbn] = book
for word in (book.title + ' ' + book.author).lower().split():
self.search_index[word].append(book.isbn)
def search(self, query):
results = set()
for word in query.lower().split():
results.update(self.search_index.get(word, []))
return [self.books[isbn] for isbn in results if isbn in self.books]
Design 3: ATM System
Asked at: Amazon, Wipro, Infosys
Requirements: Card insertion, PIN verification, balance check, withdraw, deposit
class ATMState(Enum):
IDLE = 1
CARD_INSERTED = 2
PIN_VERIFIED = 3
TRANSACTION = 4
class ATM:
"""
State pattern: ATM behavior changes based on its state.
"""
def __init__(self, cash_available):
self.state = ATMState.IDLE
self.cash = cash_available
self.current_card = None
self.current_account = None
def insert_card(self, card):
if self.state != ATMState.IDLE:
raise Exception("ATM is busy")
self.current_card = card
self.state = ATMState.CARD_INSERTED
return "Card inserted. Enter PIN."
def enter_pin(self, pin, account_service):
if self.state != ATMState.CARD_INSERTED:
raise Exception("Insert card first")
account = account_service.authenticate(self.current_card, pin)
if account:
self.current_account = account
self.state = ATMState.PIN_VERIFIED
return f"Authenticated. Balance: {account.balance}"
else:
return "Wrong PIN"
def withdraw(self, amount):
if self.state != ATMState.PIN_VERIFIED:
raise Exception("Not authenticated")
if amount > self.cash:
return "ATM has insufficient cash"
if amount > self.current_account.balance:
return "Insufficient account balance"
self.current_account.balance -= amount
self.cash -= amount
return f"Dispensed {amount}. Remaining balance: {self.current_account.balance}"
def eject_card(self):
self.state = ATMState.IDLE
self.current_card = None
self.current_account = None
return "Card ejected"
Design patterns used: State, Service Layer, Repository (implied in account_service)
Design 4: Elevator System
Asked at: Google, Amazon, Goldman Sachs
Requirements: Multiple elevators, multiple floors, direction tracking, optimal dispatch
class Direction(Enum):
UP = 1
DOWN = 2
IDLE = 3
class Elevator:
def __init__(self, elevator_id, total_floors):
self.id = elevator_id
self.current_floor = 0
self.direction = Direction.IDLE
self.requests = set()
def add_request(self, floor):
self.requests.add(floor)
def step(self):
"""Move one floor in current direction."""
if not self.requests:
self.direction = Direction.IDLE
return
target = min(self.requests) if self.direction == Direction.UP else max(self.requests)
if self.current_floor < target:
self.current_floor += 1
self.direction = Direction.UP
elif self.current_floor > target:
self.current_floor -= 1
self.direction = Direction.DOWN
if self.current_floor in self.requests:
self.requests.remove(self.current_floor)
def cost_to_serve(self, floor):
"""Estimate cost (floors to travel) to serve this request."""
return abs(self.current_floor - floor)
class ElevatorController:
"""
Dispatch strategy: assign to elevator with minimum cost.
"""
def __init__(self, num_elevators, total_floors):
self.elevators = [Elevator(i, total_floors) for i in range(num_elevators)]
def request_elevator(self, floor):
best = min(self.elevators, key=lambda e: e.cost_to_serve(floor))
best.add_request(floor)
return best.id
Design 5: Vending Machine
Asked at: Amazon, Walmart, PhonePe
Requirements: Select product, insert coins, dispense product and change, handle out-of-stock. This is the canonical State pattern problem: the machine behaves differently depending on whether it is idle, has money inserted, or is dispensing.
class VendingMachine:
"""
State pattern. The machine delegates behavior to its current state.
Each state knows the valid transitions out of itself.
"""
def __init__(self, inventory):
self.inventory = inventory # product_code -> (count, price)
self.balance = 0
self.selected = None
self.state = IdleState(self)
def select_product(self, code):
return self.state.select_product(code)
def insert_coin(self, amount):
return self.state.insert_coin(amount)
def dispense(self):
return self.state.dispense()
class State:
def __init__(self, machine):
self.m = machine
def select_product(self, code): raise Exception("Invalid action")
def insert_coin(self, amount): raise Exception("Invalid action")
def dispense(self): raise Exception("Invalid action")
class IdleState(State):
def select_product(self, code):
count, price = self.m.inventory.get(code, (0, 0))
if count <= 0:
return "Out of stock"
self.m.selected = code
self.m.state = HasSelectionState(self.m)
return f"Selected {code}. Price {price}. Insert coins."
class HasSelectionState(State):
def insert_coin(self, amount):
self.m.balance += amount
_, price = self.m.inventory[self.m.selected]
if self.m.balance >= price:
self.m.state = DispenseState(self.m)
return "Payment complete. Dispensing."
return f"Inserted. Need {price - self.m.balance} more."
class DispenseState(State):
def dispense(self):
code = self.m.selected
count, price = self.m.inventory[code]
self.m.inventory[code] = (count - 1, price)
change = self.m.balance - price
self.m.balance = 0
self.m.selected = None
self.m.state = IdleState(self.m)
return f"Dispensed {code}. Change: {change}"
The strength of the State pattern here is that illegal actions (inserting a coin before selecting, dispensing before paying) are rejected by the base State's default methods rather than scattered if-checks. Adding a "maintenance" state later is a new class, not edits across the machine.
Design patterns used: State (machine lifecycle), Strategy (could plug in different change-making algorithms)
Design 6: Logging Framework
Asked at: Microsoft, Atlassian, Uber
Requirements: Multiple log levels, multiple output sinks (console, file, remote), filtering by level. This is the canonical Chain of Responsibility plus Strategy problem.
class LogLevel(Enum):
DEBUG = 1
INFO = 2
WARN = 3
ERROR = 4
class LogSink(ABC):
@abstractmethod
def write(self, level, message): pass
class ConsoleSink(LogSink):
def write(self, level, message):
print(f"[{level.name}] {message}")
class FileSink(LogSink):
def __init__(self, path):
self.path = path
def write(self, level, message):
with open(self.path, "a") as f:
f.write(f"[{level.name}] {message}\n")
class Logger:
"""
Strategy for sinks; threshold filtering before dispatch.
Multiple sinks receive each qualifying message (fan-out).
"""
def __init__(self, min_level=LogLevel.INFO):
self.min_level = min_level
self.sinks = []
def add_sink(self, sink):
self.sinks.append(sink)
def log(self, level, message):
if level.value < self.min_level.value:
return # filtered out
for sink in self.sinks:
sink.write(level, message)
def info(self, msg): self.log(LogLevel.INFO, msg)
def error(self, msg): self.log(LogLevel.ERROR, msg)
The design separates three concerns cleanly: the level threshold (filtering), the sinks (where output goes), and the Logger (orchestration). Adding a remote sink (HTTP, Kafka) is a new LogSink subclass with zero changes to Logger. Asynchronous logging is added by wrapping a sink in a queue-backed AsyncSink decorator, which is the Decorator pattern layered on top.
Design patterns used: Strategy (sinks), Chain of Responsibility (level filtering), Decorator (async wrapper), Singleton (often one global logger)
Concurrency in LLD: The Part Candidates Skip
Most LLD candidates write single-threaded code and lose points when the interviewer asks "what if two threads call this at once." The three concurrency tools you should reach for, in order of preference:
First, prefer immutability. If an object never changes after construction (a Ticket, a Booking record), it needs no locking because there is no shared mutable state to corrupt. Design for immutable value objects wherever possible.
Second, use fine-grained locks, not one global lock. In the parking lot, lock per floor, not per lot, so concurrent entries on different floors do not serialize. A global lock turns your whole system into a single-threaded bottleneck under load.
Third, prefer atomic operations over locks for simple counters. A ticket-id counter should use an atomic increment (AtomicInteger in Java, a database sequence, or Redis INCR) rather than a lock around a plain integer. Atomics are lock-free and faster under contention.
The critical-section rule to state aloud: find-and-reserve must be a single atomic operation. The bug is checking availability, then assigning in a separate step, because two threads can both pass the check before either assigns. Combine the check and the mutation under one lock or one atomic compare-and-set.
Top 10 LLD Problems You Must Know
| Problem | Key patterns | Key classes |
|---|---|---|
| Parking Lot | Strategy (pricing), Observer (availability) | Vehicle, Spot, Floor, Ticket, ParkingLot |
| Library Management | Repository, Iterator | Book, Member, Catalog, Loan, Fine |
| ATM System | State, Service Layer | ATM, Card, Account, Transaction |
| Elevator System | Strategy (dispatch) | Elevator, Controller, Request |
| Chess Game | Strategy (piece moves) | Board, Piece, Player, Move |
| Hotel Booking | Repository, Observer | Room, Booking, Guest, RoomType |
| Ride Share (Uber/Lyft) | Strategy, Observer | Driver, Rider, Trip, PricingEngine |
| Movie Booking | Repository, Facade | Movie, Show, Seat, Booking |
| Food Delivery | Observer, Chain of Responsibility | Order, Restaurant, Delivery, Payment |
| Social Media Feed | Observer, Factory | Post, User, Feed, NotificationService |
Design Pattern Cheat Sheet for LLD
| Pattern | Use when | Example in LLD |
|---|---|---|
| Singleton | Only one instance needed | ParkingLot, DatabaseConnection |
| Factory | Hide object creation logic | VehicleFactory, PaymentFactory |
| Strategy | Multiple interchangeable algorithms | PricingStrategy, DispatchStrategy |
| Observer | Notify on state change | Availability alerts, order status |
| State | Behavior depends on current state | ATM, Order lifecycle |
| Command | Encapsulate requests as objects | ElevatorRequest, Transaction |
| Decorator | Add responsibilities dynamically | LoggingWrapper, CachingWrapper |
What Interviewers Want to See
Candidates report that interviewers stop the coding early and ask "why did you choose this pattern?" more often than they let candidates fully implement the system. The signal is not whether you write complete working code, but whether you can articulate design decisions. Based on public preparation resources and candidate-reported LLD interviews, the most valued answers explain what would change if a requirement changed, and which parts of the design absorb that change without breaking others.
A weak answer: "I used a class hierarchy because that is what OOP teaches."
A strong answer: "I made PricingStrategy an interface so that we can plug in hourly, flat-rate, or surge pricing without touching the ParkingLot class. Adding a new pricing model is a one-file change."
Related Articles
Methodology applied to this articlelast verified 8 Jun 2026
- No fabricated salary numbers or success rates. If we quote a range, it's sourced.
- No noun-substituted templates. This article was not generated by swapping company names in a stock prompt.
- No paid placements, sponsored coaching links, or affiliate-shilled course pushes.
Explore this topic cluster
More resources in Interview Questions
Use the category hub to browse similar questions, exam patterns, salary guides, and preparation resources related to this topic.
Paid contributor programme
Sat this this year? Share your story, earn ₹500.
First-person experience reports help future candidates prep smarter. We pay verified contributors ₹500 via UPI per accepted story - with byline.
Submit your story →Ready to practice?
Take a free timed mock test
Put what you learned into practice. Our mock tests match the 2026 pattern with timer, navigator, reveal, and score breakdown. No signup.
Start Free Mock Test →Related Articles
Airbnb Interview Questions 2026: Top Tech, HR & Behavioural Q&As for Freshers
Clearing Airbnb's fresher loop in 2026 comes down to preparing for the exact mix of questions across technical, behavioural,...
Airtel Interview Questions 2026: Top Tech, HR & Behavioural Q&As for Freshers
Clearing Airtel's fresher loop in 2026 comes down to preparing for the exact mix of questions across technical, behavioural,...
AMD Interview Questions 2026: Top Tech, HR & Behavioural Q&As for Freshers
Clearing AMD's fresher loop in 2026 comes down to preparing for the exact mix of questions across technical, behavioural,...
Atlassian Interview Questions 2026: Top Tech, HR & Behavioural Q&As for Freshers
Clearing Atlassian's fresher loop in 2026 comes down to preparing for the exact mix of questions across technical,...
Barclays Interview Questions 2026
_Last verified by [Aditya Sharma](/author/aditya-sharma/) · cross-checked against PapersAdda Hiring Pulse and...
More from PapersAdda
Top 15 Product Companies Hiring Freshers India 2026: Compensation + Bar + Interview Loop
Accenture Interview Process 2026: Rounds & Prep
Accenture Interview Questions 2026 (with Answers for Freshers)
Adobe Interview Process 2026: Rounds, OA & Aptitude