Complete Interview Guide | SOLID Principles | Design Patterns | Production-Ready Architecture
Introduction
The Parking Lot is one of the most frequently asked Low-Level Design (LLD) interview questions at companies like Amazon, Microsoft, Uber, Walmart, Oracle, Adobe, Atlassian, and Flipkart.
It tests a candidate's understanding of:
- Object-Oriented Design (OOD)
- SOLID Principles
- Design Patterns
- Object Relationships
- Extensibility
- Clean Code
- Domain Modeling
Unlike algorithm questions, the focus is on designing a flexible, maintainable, and scalable system.
Problem Statement
Design a Parking Lot System that supports:
- Multiple parking floors
- Multiple parking spot types
- Multiple vehicle types
- Parking ticket generation
- Vehicle entry and exit
- Fee calculation
- Display available parking spaces
- Multiple payment methods
- Reservation support (optional)
Functional Requirements
Core Features
- Park a vehicle
- Unpark a vehicle
- Generate parking ticket
- Calculate parking fee
- Find nearest available parking spot
- Display available spots
- Track occupied spots
Optional Features
- EV charging spots
- Reserved parking
- VIP parking
- Online booking
- Dynamic pricing
- Lost ticket handling
- License plate recognition
- Multi-entry/multi-exit gates
Non-Functional Requirements
- High Availability
- Thread Safety
- Scalability
- Extensibility
- Low Latency
- Fault Tolerance
- Maintainability
Real-World Examples
- Airport Parking
- Shopping Mall
- IT Parks
- Hospitals
- Railway Stations
- Apartment Complexes
- Smart City Parking
- Event Parking
High-Level Architecture
Client
│
▼
ParkingLotFacade
│
┌──────────────┼──────────────┐
▼ ▼ ▼
Entry Gate Exit Gate Display Board
│ │
▼ ▼
TicketService PaymentService
│ │
└──────┬───────┘
▼
ParkingManager
│
┌────────┴─────────┐
▼ ▼
Parking Floors Spot Allocation
│
▼
Parking Spots
Core Components
| Component | Responsibility |
|---|---|
| ParkingLot | Root aggregate |
| ParkingFloor | Contains parking spots |
| ParkingSpot | Represents a parking space |
| Vehicle | Vehicle details |
| Ticket | Parking ticket |
| Gate | Entry/Exit management |
| Payment | Fee collection |
| PricingStrategy | Parking fee calculation |
Domain Model
+--------------------+
| ParkingLot |
+--------------------+
| id |
| name |
+---------+----------+
|
1 | *
|
▼
+--------------------+
| ParkingFloor |
+--------------------+
| floorNo |
+---------+----------+
|
1 | *
|
▼
+--------------------+
| ParkingSpot |
+--------------------+
| spotId |
| type |
| occupied |
+---------+----------+
|
|
▼
+--------------------+
| Vehicle |
+--------------------+
Design Patterns Used
| Pattern | Purpose |
|---|---|
| Facade | Single entry point (ParkingLotFacade) |
| Strategy | Spot allocation, pricing, payment |
| Factory | Create vehicles and tickets |
| State | Parking spot state |
| Observer | Display board updates |
| Singleton | Parking lot configuration |
| Builder | Ticket creation |
| Repository | Data persistence abstraction |
Enumerations
Vehicle Type
public enum VehicleType {
MOTORCYCLE,
CAR,
SUV,
BUS,
TRUCK,
ELECTRIC
}
Spot Type
public enum SpotType {
MOTORCYCLE,
COMPACT,
LARGE,
ELECTRIC,
HANDICAPPED
}
Spot Status
public enum SpotStatus {
AVAILABLE,
OCCUPIED,
RESERVED,
OUT_OF_SERVICE
}
Vehicle
public abstract class Vehicle {
private final String registrationNumber;
private final VehicleType vehicleType;
protected Vehicle(String registrationNumber,
VehicleType vehicleType) {
this.registrationNumber = registrationNumber;
this.vehicleType = vehicleType;
}
public String getRegistrationNumber() {
return registrationNumber;
}
public VehicleType getVehicleType() {
return vehicleType;
}
}
Parking Spot
public class ParkingSpot {
private final String spotId;
private final SpotType spotType;
private SpotStatus status;
public ParkingSpot(String spotId,
SpotType spotType) {
this.spotId = spotId;
this.spotType = spotType;
this.status = SpotStatus.AVAILABLE;
}
public boolean isAvailable() {
return status == SpotStatus.AVAILABLE;
}
public void occupy() {
status = SpotStatus.OCCUPIED;
}
public void release() {
status = SpotStatus.AVAILABLE;
}
}
Ticket
import java.time.Instant;
import java.util.UUID;
public class ParkingTicket {
private final String ticketId;
private final Vehicle vehicle;
private final ParkingSpot parkingSpot;
private final Instant entryTime;
public ParkingTicket(Vehicle vehicle,
ParkingSpot parkingSpot) {
this.ticketId = UUID.randomUUID().toString();
this.vehicle = vehicle;
this.parkingSpot = parkingSpot;
this.entryTime = Instant.now();
}
// getters
}
Spot Allocation Strategy
public interface SpotAllocationStrategy {
ParkingSpot allocate(
Vehicle vehicle,
ParkingFloor floor);
}
Example implementations:
- NearestSpotStrategy
- FirstAvailableStrategy
- RandomSpotStrategy
- EVPriorityStrategy
Pricing Strategy
import java.math.BigDecimal;
import java.time.Duration;
public interface PricingStrategy {
BigDecimal calculateFee(
Vehicle vehicle,
Duration duration);
}
Possible implementations:
- HourlyPricingStrategy
- FlatRatePricingStrategy
- WeekendPricingStrategy
- DynamicPricingStrategy
Payment Strategy
import java.math.BigDecimal;
public interface PaymentStrategy {
void pay(BigDecimal amount);
}
Implementations:
- CashPayment
- CardPayment
- UpiPayment
- WalletPayment
Parking Manager
public interface ParkingManager {
ParkingTicket park(Vehicle vehicle);
void unpark(String ticketId);
}
The manager coordinates:
- Spot allocation
- Ticket generation
- Spot release
- Fee calculation
- Payment
Parking Flow
Vehicle Arrives
│
▼
Entry Gate
│
▼
Find Available Spot
│
▼
Allocate Spot
│
▼
Generate Ticket
│
▼
Open Barrier
Exit Flow
Vehicle Arrives
│
▼
Scan Ticket
│
▼
Calculate Fee
│
▼
Process Payment
│
▼
Release Spot
│
▼
Open Barrier
Display Board
The display board observes parking spot changes.
Floor 1
Compact : 12
Large : 5
Electric : 3
Motorcycle : 18
This is a good use case for the Observer Pattern, where display boards update automatically when spot availability changes.
Thread Safety
Use:
-
ConcurrentHashMapfor active tickets -
ReentrantLockor synchronized blocks for spot allocation - Atomic operations when updating availability
- Database transactions for ticket creation and payment
Avoid:
- Two vehicles acquiring the same spot simultaneously
- Global synchronization across the entire parking lot
Database Design
Parking Spot
| Column | Type |
|---|---|
| spot_id | VARCHAR |
| floor_id | VARCHAR |
| spot_type | ENUM |
| status | ENUM |
Parking Ticket
| Column | Type |
|---|---|
| ticket_id | UUID |
| vehicle_number | VARCHAR |
| spot_id | VARCHAR |
| entry_time | TIMESTAMP |
| exit_time | TIMESTAMP |
| amount | DECIMAL |
Payment
| Column | Type |
|---|---|
| payment_id | UUID |
| ticket_id | UUID |
| payment_type | ENUM |
| amount | DECIMAL |
| status | ENUM |
SOLID Principles
| Principle | Application |
|---|---|
| Single Responsibility | Separate classes for allocation, pricing, payment, and ticketing. |
| Open/Closed | Add new pricing or allocation strategies without modifying existing code. |
| Liskov Substitution | Any pricing or payment strategy can be substituted. |
| Interface Segregation | Small interfaces (PricingStrategy, PaymentStrategy, SpotAllocationStrategy). |
| Dependency Inversion |
ParkingManager depends on abstractions rather than concrete implementations. |
Production Enhancements
- Multi-gate synchronization
- Distributed parking management
- QR-code or RFID tickets
- ANPR (Automatic Number Plate Recognition)
- EV charging reservations
- Online pre-booking
- Lost ticket workflow
- Dynamic surge pricing
- Occupancy analytics
- Mobile app integration
- Event-driven notifications
- Integration with payment gateways
Complexity Analysis
| Operation | Complexity |
|---|---|
| Find Spot | O(log n) or O(1)* |
| Park Vehicle | O(log n) |
| Unpark Vehicle | O(1) |
| Generate Ticket | O(1) |
| Calculate Fee | O(1) |
*With indexed free-spot structures (e.g., per-floor priority queues or maps), spot lookup can approach O(1). A naive linear scan is O(n).
Common Interview Follow-up Questions
- How would you prevent two vehicles from getting the same parking spot?
- How would you support multiple entry and exit gates concurrently?
- How would you implement the "nearest available spot" algorithm?
- How would you reserve parking spots for VIPs or disabled users?
- How would you support electric vehicle charging stations?
- How would you implement dynamic pricing during peak hours?
- How would you recover if payment succeeds but the exit gate fails to open?
- How would you design the system for multiple parking lots across different cities?
- How would you handle a lost parking ticket?
- How would you keep display boards synchronized with real-time spot availability?
Interview Tips
Focus on Extensibility
Instead of hardcoding:
- Vehicle types
- Pricing rules
- Spot allocation logic
- Payment methods
Abstract them behind interfaces and use the Strategy Pattern.
Explain Why the Facade Pattern Fits
ParkingLotFacade provides a simple API such as:
ParkingTicket park(Vehicle vehicle);
Receipt unpark(String ticketId);
Internally it coordinates:
- Spot allocation
- Ticket generation
- Pricing
- Payment
- Display updates
This keeps client code simple while hiding implementation complexity.
Key Takeaways
- Model the domain with clear entities:
ParkingLot,ParkingFloor,ParkingSpot,Vehicle, andParkingTicket. - Use Strategy Pattern for spot allocation, pricing, and payment to support future extensions.
- Use Facade Pattern to expose a simple API while coordinating multiple subsystems.
- Design for concurrency to avoid duplicate spot allocation.
- Discuss production concerns like multi-gate coordination, reservations, dynamic pricing, analytics, and distributed deployment to demonstrate senior-level design thinking.
Top comments (0)