Design a Parking Lot
You'll learn to
- -Model spots, levels, tickets, and vehicle types as a class hierarchy that stays open to new vehicle/spot types
- -Handle concurrent spot assignment correctly so two cars never get the same spot
Design a Parking Lot is one of the most-asked LLD prompts precisely because it packs several fundamentals into one problem: a class hierarchy for varying vehicle/spot types, a concurrency-sensitive resource-assignment step, and a natural extensibility follow-up (add payment, add multiple entry gates). Working through it end to end ties together nearly everything covered so far in this course.
Step 1: Clarify Requirements
- -What vehicle types does the lot support? (motorcycle, car, bus - each may need a different spot size)
- -Does the lot have multiple levels/floors?
- -Do we need to track payment, or just entry/exit and spot assignment?
- -What happens when the lot is full? Should the design support parking spot reservation ahead of time, or only walk-up assignment?
Assume the answers: three vehicle types (Motorcycle, Car, Bus), multiple levels, each level has spots of different sizes, and payment is out of scope for this first pass (a natural place for the interviewer to follow up later).
Step 2: Identify Classes
from enum import Enum
class VehicleType(Enum):
MOTORCYCLE = "motorcycle"
CAR = "car"
BUS = "bus"
class Vehicle(ABC):
def __init__(self, license_plate: str):
self.license_plate = license_plate
@property
@abstractmethod
def type(self) -> VehicleType: ...
class Car(Vehicle):
@property
def type(self) -> VehicleType: return VehicleType.CAR
class SpotSize(Enum):
SMALL = 1 # motorcycles only
MEDIUM = 2 # cars (and motorcycles)
LARGE = 3 # buses (and cars, and motorcycles)
class ParkingSpot:
def __init__(self, spot_id: str, size: SpotSize):
self.spot_id = spot_id
self.size = size
self.vehicle: Vehicle | None = None
def can_fit(self, vehicle: Vehicle) -> bool:
required = {VehicleType.MOTORCYCLE: SpotSize.SMALL,
VehicleType.CAR: SpotSize.MEDIUM,
VehicleType.BUS: SpotSize.LARGE}[vehicle.type]
return self.size.value >= required.value
def is_free(self) -> bool:
return self.vehicle is NoneStep 3: The Concurrency-Safe Assignment Logic
This is the part a naive solution gets wrong - finding a free spot and assigning it must be one atomic operation, exactly the check-then-act shape from the Concurrency module. A ParkingLevel owns its spots and a lock around the search-and-assign step.
import threading
class ParkingLevel:
def __init__(self, spots: list[ParkingSpot]):
self._spots = spots
self._lock = threading.Lock()
def park(self, vehicle: Vehicle) -> ParkingSpot | None:
with self._lock: # find AND assign, atomically
for spot in self._spots:
if spot.is_free() and spot.can_fit(vehicle):
spot.vehicle = vehicle
return spot
return None # this level is full for this vehicle type
class ParkingLot:
def __init__(self, levels: list[ParkingLevel]):
self._levels = levels
def park_vehicle(self, vehicle: Vehicle) -> "Ticket | None":
for level in self._levels:
spot = level.park(vehicle)
if spot:
return Ticket(vehicle, spot)
return None # lot is fullStep 4: Ticket and Extensibility
A Ticket ties a Vehicle to the ParkingSpot it was assigned, plus an entry timestamp - the natural object to extend later with payment (duration * hourly_rate) without touching ParkingLevel or ParkingSpot at all. Notice the design has already absorbed the two most common follow-ups for free: "add a new vehicle type" means adding one VehicleType enum value and one Vehicle subclass, and "add payment" means extending Ticket, neither of which requires touching the atomic assignment logic in ParkingLevel.
A strong closing move on this problem: proactively mention the SpotSize.can_fit() logic uses ">=" so a motorcycle can use a MEDIUM or LARGE spot as a fallback when SMALL is full - a small detail that shows you thought about lot utilization, not just correctness.
Interview Signal is part of Pro
See a real weak answer next to a real strong one for this exact topic.
Quiz is part of Pro
Test what you just read with a short quiz, and bank the XP.