Skip to content
Low Level Design Mastery Logo
LowLevelDesign Mastery

Steps in LLD Interview

Master the systematic approach to ace any LLD interview problem!

When faced with an LLD interview problem, it’s crucial to follow a systematic approach. Jumping straight to code is a common mistake that leads to poor designs. Instead, follow these proven steps to create clean, maintainable solutions.

Diagram

Before you start designing, make sure you understand the problem!

Jumping to solutions without understanding requirements leads to:

  • ❌ Missing important features
  • ❌ Over-engineering
  • ❌ Wrong assumptions
  • ❌ Wasted time

Functional Requirements:

  • What are the core features?
  • What are the use cases?
  • What are the constraints?

Non-Functional Requirements:

  • Scale requirements?
  • Performance expectations?
  • Availability needs?

Edge Cases:

  • What happens in error scenarios?
  • What are the boundary conditions?

Interviewer: “Design a Parking Lot System

Good Questions to Ask:

  1. “What types of vehicles are supported?” (Car, Motorcycle, Truck)
  2. “How many spots are there?” (Fixed number or configurable?)
  3. “Do we need to track parking duration?” (For billing)
  4. “What happens when the lot is full?” (Reject or waitlist?)
  5. “Do we need different pricing for different vehicle types?”
  6. “Do we need to support multiple parking lots?”

Bad Approach:

  • “I’ll assume cars only and 100 spots”
  • “Let me start coding right away”
Diagram

Actors are the users or external systems that interact with your system.

Actors represent:

  • Users - People who use the system
  • External Systems - Other systems that interact with yours
  • Administrators - People who manage the system

Ask yourself:

  • Who will use this system?
  • What are their roles?
  • What actions can they perform?

Actors:

  1. Driver - Parks and retrieves vehicles
  2. Admin - Manages parking lot (add spots, view reports)
  3. System - Automated processes (billing, notifications)
Diagram
SystemActors
Library ManagementLibrarian, Member, System
RestaurantCustomer, Waiter, Chef, Manager
ATMCustomer, Bank, System
ElevatorPassenger, Maintenance, System

Entities are the core objects/concepts in your system that have data and behavior.

Entities represent:

  • Core Objects - Main concepts in your system
  • Data Holders - Objects that store information
  • Business Objects - Objects that represent business concepts

Look for:

  • Nouns in the problem statement
  • Things that have properties
  • Objects that need to be tracked
  • Concepts that have state

Entities:

  1. ParkingLot - The parking lot itself
  2. ParkingSpot - Individual parking spaces
  3. Vehicle - Cars, motorcycles, trucks
  4. Ticket - Parking ticket issued to driver
  5. Payment - Payment transaction
Diagram

Key Difference:

  • Actor = External user/system that interacts with your system
  • Entity = Internal object/concept within your system

Example:

  • Driver (Actor) uses ParkingLot (Entity)
  • Admin (Actor) manages ParkingSpot (Entity)

Each class should have a single, well-defined responsibility (Single Responsibility Principle).

Proper responsibility assignment leads to:

  • Maintainable code - Easy to understand and modify
  • Testable code - Easy to write unit tests
  • Reusable code - Classes can be reused
  • SOLID principles - Follows best practices

For each entity, ask:

  • What does this entity do?
  • What data does it hold?
  • What operations does it perform?

ParkingLot Responsibilities:

  • Manage parking spots
  • Assign spots to vehicles
  • Find available spots
  • Release spots when vehicles leave

ParkingSpot Responsibilities:

  • Track its own state (occupied/available)
  • Know its type (car/motorcycle/truck)
  • Know its location/ID

Ticket Responsibilities:

  • Store entry time
  • Store vehicle information
  • Calculate parking duration

Payment Responsibilities:

  • Process payment
  • Calculate amount based on duration
  • Store payment details
Diagram

For each class, ensure:

  • Single Responsibility - One reason to change
  • Cohesive - Methods are related
  • Focused - Not doing too much
  • Clear Purpose - Easy to understand what it does

Class diagrams show the structure of your system - classes, their attributes, methods, and relationships.

Class diagrams help you:

  • Visualize structure - See how classes relate
  • Identify relationships - Inheritance, composition, association
  • Plan implementation - Know what to code
  • Communicate design - Share your design with interviewer
  1. Classes - With attributes and methods
  2. Relationships - Inheritance, composition, association
  3. Interfaces - Abstract contracts
  4. Access Modifiers - Public, private, protected
classDiagram
    class ParkingLot {
        -List~ParkingSpot~ spots
        -int capacity
        +parkVehicle(vehicle: Vehicle) Ticket
        +unparkVehicle(ticket: Ticket) Payment
        +findAvailableSpot(vehicleType: VehicleType) ParkingSpot
    }
    
    class ParkingSpot {
        -String spotId
        -VehicleType spotType
        -boolean isOccupied
        -Vehicle vehicle
        +parkVehicle(vehicle: Vehicle) void
        +unparkVehicle() Vehicle
        +isAvailable() boolean
    }
    
    class Vehicle {
        <<abstract>>
        -String licensePlate
        -VehicleType vehicleType
        +getVehicleType() VehicleType
    }
    
    class Car {
        +getVehicleType() VehicleType
    }
    
    class Motorcycle {
        +getVehicleType() VehicleType
    }
    
    class Ticket {
        -String ticketId
        -DateTime entryTime
        -Vehicle vehicle
        -ParkingSpot spot
        +calculateDuration() Duration
    }
    
    class Payment {
        -String paymentId
        -float amount
        -DateTime paymentTime
        -Ticket ticket
        +processPayment() boolean
    }
    
    ParkingLot "1" *-- "many" ParkingSpot : contains
    ParkingLot --> Ticket : creates
    ParkingLot --> Payment : creates
    Ticket --> Vehicle : references
    Ticket --> ParkingSpot : references
    Payment --> Ticket : references
    Vehicle <|-- Car : extends
    Vehicle <|-- Motorcycle : extends
    ParkingSpot --> Vehicle : contains
Diagram

Contracts define how classes interact - method signatures, interfaces, and API contracts.

Well-defined contracts:

  • Enable testing - Clear interfaces to mock
  • Enable flexibility - Can swap implementations
  • Document behavior - Clear what methods do
  • Prevent errors - Compile-time checks
  1. Method Signatures - Parameters, return types, exceptions
  2. Interfaces - Abstract contracts for classes
  3. API Contracts - If designing APIs, define endpoints
  4. Preconditions/Postconditions - What’s expected

ParkingLot Interface:

parking_lot_interface.py
class ParkingLot:
def park_vehicle(self, vehicle: Vehicle) -> Ticket:
"""
Parks a vehicle and returns a ticket.
Args:
vehicle: Vehicle to park
Returns:
Ticket: Parking ticket with entry details
Raises:
ParkingLotFullException: If no spots available
InvalidVehicleException: If vehicle type not supported
"""
pass
def unpark_vehicle(self, ticket: Ticket) -> Payment:
"""
Unparks a vehicle and processes payment.
Args:
ticket: Parking ticket
Returns:
Payment: Payment transaction details
Raises:
InvalidTicketException: If ticket is invalid
"""
pass

Payment Interface:

payment_processor.py
class PaymentProcessor:
def process_payment(self, ticket: Ticket) -> Payment:
"""
Processes payment for parking.
Args:
ticket: Parking ticket
Returns:
Payment: Payment details
Raises:
PaymentFailedException: If payment fails
"""
pass
def calculate_amount(self, ticket: Ticket) -> float:
"""
Calculates parking fee based on duration.
Args:
ticket: Parking ticket
Returns:
float: Amount to be paid
"""
pass
Diagram

Edge cases are scenarios that might not be obvious but are important to handle.

Handling edge cases shows:

  • Mature thinking - You consider all scenarios
  • Production readiness - Real systems have edge cases
  • Attention to detail - You think thoroughly
  • Error handling - You plan for failures
  1. Null/Empty Inputs - What if input is null or empty?
  2. Boundary Conditions - What if at limits?
  3. Concurrent Access - What if multiple users?
  4. Error Scenarios - What if something fails?
  5. Invalid States - What if system is in wrong state?

Edge Cases to Handle:

  1. Parking lot is full

    • Return appropriate exception
    • Don’t crash
  2. Invalid vehicle type

    • Validate vehicle type
    • Return clear error message
  3. Invalid ticket

    • Validate ticket exists
    • Check ticket hasn’t been used
  4. Concurrent parking

    • Handle race conditions
    • Use locks/synchronization
  5. Payment failure

    • Handle payment errors
    • Don’t release spot if payment fails
Diagram

Finally, implement your design in code (or pseudo-code).

  1. Follow your design - Implement what you designed
  2. Clean code - Readable, maintainable
  3. SOLID principles - Apply what you learned
  4. Design patterns - Use appropriate patterns
  5. Error handling - Handle edge cases
parking_lot.py
from abc import ABC, abstractmethod
from datetime import datetime
from enum import Enum
from typing import Optional, List
class VehicleType(Enum):
CAR = "CAR"
MOTORCYCLE = "MOTORCYCLE"
TRUCK = "TRUCK"
class Vehicle(ABC):
def __init__(self, license_plate: str):
self.license_plate = license_plate
@abstractmethod
def get_vehicle_type(self) -> VehicleType:
pass
class Car(Vehicle):
def get_vehicle_type(self) -> VehicleType:
return VehicleType.CAR
class ParkingSpot:
def __init__(self, spot_id: str, spot_type: VehicleType):
self.spot_id = spot_id
self.spot_type = spot_type
self.is_occupied = False
self.vehicle: Optional[Vehicle] = None
def park_vehicle(self, vehicle: Vehicle) -> None:
if not self.is_available():
raise ValueError("Spot is already occupied")
if vehicle.get_vehicle_type() != self.spot_type:
raise ValueError("Vehicle type doesn't match spot type")
self.vehicle = vehicle
self.is_occupied = True
def unpark_vehicle(self) -> Vehicle:
if not self.is_occupied:
raise ValueError("Spot is not occupied")
vehicle = self.vehicle
self.vehicle = None
self.is_occupied = False
return vehicle
def is_available(self) -> bool:
return not self.is_occupied
class Ticket:
def __init__(self, ticket_id: str, vehicle: Vehicle, spot: ParkingSpot):
self.ticket_id = ticket_id
self.vehicle = vehicle
self.spot = spot
self.entry_time = datetime.now()
def calculate_duration(self) -> float:
return (datetime.now() - self.entry_time).total_seconds() / 3600
class ParkingLot:
def __init__(self, capacity: int):
self.capacity = capacity
self.spots: List[ParkingSpot] = []
self.tickets: dict[str, Ticket] = {}
def park_vehicle(self, vehicle: Vehicle) -> Ticket:
# Find available spot
spot = self._find_available_spot(vehicle.get_vehicle_type())
if not spot:
raise ValueError("Parking lot is full")
# Park vehicle
spot.park_vehicle(vehicle)
# Create ticket
ticket_id = f"TICKET_{len(self.tickets) + 1}"
ticket = Ticket(ticket_id, vehicle, spot)
self.tickets[ticket_id] = ticket
return ticket
def unpark_vehicle(self, ticket_id: str) -> float:
if ticket_id not in self.tickets:
raise ValueError("Invalid ticket")
ticket = self.tickets[ticket_id]
ticket.spot.unpark_vehicle()
# Calculate payment
duration = ticket.calculate_duration()
amount = duration * 10 # $10 per hour
del self.tickets[ticket_id]
return amount
def _find_available_spot(self, vehicle_type: VehicleType) -> Optional[ParkingSpot]:
for spot in self.spots:
if spot.spot_type == vehicle_type and spot.is_available():
return spot
return None

graph TD
    A[Problem Statement] --> B[1. Clarify Requirements]
    B --> C[2. Identify Actors]
    C --> D[3. Identify Entities]
    D --> E[4. Assign Responsibilities]
    E --> F[5. Design Class Diagrams]
    F --> G[6. Define Contracts & APIs]
    G --> H[7. Handle Edge Cases]
    H --> I[8. Code Implementation]

Use this checklist for every LLD interview:

  • Step 1: Clarify requirements - Ask questions
  • Step 2: Identify actors - Who uses the system?
  • Step 3: Identify entities - What are the core objects?
  • Step 4: Assign responsibilities - What does each class do?
  • Step 5: Design class diagrams - Show relationships
  • Step 6: Define contracts & APIs - Method signatures
  • Step 7: Handle edge cases - Error scenarios
  • Step 8: Code implementation - Write clean code

Now that you understand the high-level process, let’s dive deep into each step:

Next: Identifying Actors & Entities →

This next guide will teach you how to systematically identify actors and entities with detailed examples and visual diagrams!


Follow a systematic approach - Don’t jump to code
Clarify requirements first - Ask questions
Identify actors - Who uses the system?
Identify entities - What are the core objects?
Assign responsibilities - Single Responsibility Principle
Design class diagrams - Visualize structure
Define contracts - Clear interfaces
Handle edge cases - Think about errors
Implement cleanly - Follow your design

LLD interviews are about demonstrating:

  • Systematic thinking
  • Clean design skills
  • Communication ability
  • Production-ready mindset

Master these steps, and you’ll excel in any LLD interview! 🚀