Start the round by pinning down scope out loud, because a parking lot can balloon into a payments platform if you let it. State the functional core and the assumptions you are choosing, then build only to that line.
Functional requirements:
- Park a vehicle and issue a ticket at entry.
- Unpark a vehicle and charge a fee at exit.
- Support multiple vehicle sizes (motorcycle, car, truck).
- Support multiple levels, each holding many spots.
- Track availability so a full lot rejects entry cleanly.
Assumptions worth saying aloud (each one prunes work):
- One vehicle occupies exactly one spot; no oversize spanning for now.
- A vehicle fits a spot of equal or larger size (car fits a large spot).
- Payment succeeds synchronously; no gateway modeling yet.
- Single process owns the lot state; we revisit concurrency in the last tab.
From those requirements the core entities fall out. Name them before you write methods so the interviewer sees the model, not just syntax:
enum VehicleSize { MOTORCYCLE, CAR, TRUCK }
enum SpotSize { SMALL, MEDIUM, LARGE }
class Ticket {
final String id;
final String plate;
final ParkingSpot spot;
final long entryEpochMs;
}
class ParkingSpot { /* size, occupancy — next tab */ }
class Level { /* holds spots, knows availability — next tab */ }
class ParkingLot { /* orchestrates park/unpark — later tabs */ }
The Ticket is deliberately immutable and holds a direct reference to the ParkingSpot
it was issued for. That reference is what makes exit O(1): you never search the lot to
free a spot, you follow the ticket straight back to it.