Design a parking lot system. Walk me through your approach.
Fast recall
Quick revision
Core answer
Ability to decompose a real-world system into cohesive classes and identify correct relationships (composition, inheritance, aggregation).
Creating a single God class that does everything or missing key entities like ParkingTicket, leading to difficulty tracking vehicle entry/exit times.
Mention explicit concurrency handling for spot assignment and justify each design pattern choice with the specific problem it solves in this domain.
Interview-ready guide
Interview answer
I'd start by clarifying scope — multiple floors, what vehicle types, and whether pricing is hourly. Then I find the nouns in the problem, because nouns usually become classes. Here that's ParkingLot, ParkingFloor, ParkingSpot, Vehicle, ParkingTicket, and a FeeCalculator. The verbs — park, unpark, calculate fee — become the methods.
The most important modelling decision is the relationships. A ParkingLot has a list of floors, and each floor has a list of spots — that's composition, because a spot can't exist without its floor. Vehicles are different: Car, Motorcycle, and Truck all inherit from an abstract Vehicle class, because each one is-a vehicle. I'd give Vehicle an abstract method like requiredSize so each subclass declares what spot it needs, instead of writing if-else chains on the type.
For the flow: on entry, the lot searches floors for a free spot that fits, marks it occupied, and issues a ParkingTicket that records the vehicle, the spot, and the entry time. On exit, the customer hands back the ticket, the FeeCalculator works out the charge from the duration, payment is taken, and the spot is freed.
Then I'd layer in patterns where they earn their place: Strategy for the FeeCalculator when pricing rules vary, Observer when several displays react to spot changes, and Factory only when vehicle creation has real validation or setup. I'd also mention that spot assignment must be thread-safe, since multiple gates operate at once — a synchronized claim on the spot stops two cars taking the same place. That shows I'm thinking about behaviour, not just structure.
Design a parking lot system. Walk me through your approach.
Direct Answer
A parking lot system needs ParkingLot (manages floors), ParkingFloor (manages spots), ParkingSpot (tracks occupancy), Vehicle hierarchy (Car, Motorcycle, Truck), ParkingTicket (entry/exit tracking), and FeeCalculator (pricing logic). Use Singleton for ParkingLot, Strategy for fee calculation, and Factory for vehicle creation.
Code Example
enum VehicleType { CAR, MOTORCYCLE, TRUCK }
enum SpotSize { COMPACT, REGULAR, LARGE }
// Inheritance: every vehicle IS-A Vehicle
abstract class Vehicle {
private final String plate;
private final VehicleType type;
Vehicle(String plate, VehicleType type) { this.plate = plate; this.type = type; }
abstract SpotSize requiredSize();
}
class Car extends Vehicle {
Car(String plate) { super(plate, VehicleType.CAR); }
SpotSize requiredSize() { return SpotSize.REGULAR; }
}
class ParkingSpot {
private final String id;
private final SpotSize size;
private Vehicle vehicle; // null = free
boolean isFree() { return vehicle == null; }
synchronized boolean park(Vehicle v) { // thread-safe claim
if (vehicle != null || v.requiredSize().ordinal() > size.ordinal()) return false;
vehicle = v; return true;
}
}
record ParkingTicket(String id, Vehicle vehicle, ParkingSpot spot, LocalDateTime entry) {}
class ParkingLot { // Composition: lot HAS floors HAS spots
private final List<ParkingFloor> floors = new ArrayList<>();
private final FeeCalculator feeCalculator = new HourlyFeeCalculator();
Optional<ParkingTicket> park(Vehicle v) {
for (ParkingFloor f : floors) {
Optional<ParkingSpot> spot = f.findFree(v.requiredSize());
if (spot.isPresent() && spot.get().park(v))
return Optional.of(new ParkingTicket(UUID.randomUUID().toString(), v, spot.get(), LocalDateTime.now()));
}
return Optional.empty(); // lot full
}
}
The record for the ticket and the abstract Vehicle keep the model small but expressive.
Common Mistakes & Pitfalls
- The God class — one
ParkingLotManagerdoing spots, tickets, and fees. Split by responsibility (SRP) so each class has one reason to change. - Forgetting the ParkingTicket — without a ticket capturing entry time, you can't compute the fee on exit. The ticket is the contract between customer and system.
- if-else on vehicle type —
if (type == CAR) ... else if (type == TRUCK)scattered everywhere. Use polymorphism (requiredSize()) so a new type is one new class. - Ignoring concurrency — two gates can grab the same spot. A
synchronizedclaim on the spot prevents double-booking.
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.