Design a Parking Lot
Company: Uber
Role: Software Engineer
Category: Software Engineering Fundamentals
Difficulty: medium
Interview Round: Onsite
## Problem
In an AI-assisted coding round, design the **core object model and APIs for a parking lot system**.
The system should support:
- **Multiple floors**, each containing many parking spots.
- **Multiple spot types** (e.g. motorcycle, compact, large).
- **Multiple vehicle types** such as motorcycle, car, and truck.
- **Assigning a valid spot** to a vehicle when it enters (respecting which spot types each vehicle can occupy).
- **Issuing a parking ticket** on entry.
- **Releasing the spot** when the vehicle exits.
- **Calculating the parking fee** based on duration.
- **Querying current availability**.
Explain the **main classes**, their **relationships**, the **key methods**, and — critically — how you would handle **concurrent vehicle entry** so that two vehicles can never claim the same spot.
```hint Where to start
Identify the nouns before the verbs, and decide for each pair of entities whether the relationship is *ownership* or *type modeling*. For the small, fixed sets of "kinds" in this problem, ask whether you really need a class hierarchy or whether something lighter-weight captures the variation.
```
```hint Compatibility without if-chains
The "which vehicle fits which spot" rule will be consulted in several places. Think about where that rule should *live* so it isn't duplicated as conditionals scattered through the entry path.
```
```hint Keeping the design flexible
Two things in this problem are likely to change later: how you pick which spot to assign, and how you compute the fee. Consider how to structure the code so the entry/exit flow stays stable while those policies vary independently.
```
```hint Answering availability fast
A few thousand spots and many entries per minute means you don't want to re-examine every spot on each request. Think about what state you could maintain so that "find a free spot" and "how many are free?" don't both become full scans.
```
```hint Concurrency — the crux
The straightforward "find a free spot, then mark it taken" is two separate steps. Picture two gate threads running those steps at the same time on the *same* last free spot — what can go wrong, and what would have to be true about the "mark it taken" step for it to be safe? Also think about what a thread that loses such a contest should do next, and how much of the lot you're willing to block while one entry is in progress.
```
### Constraints & Assumptions
State your assumptions explicitly; reasonable defaults include:
- A single physical lot with up to ~10 floors and a few thousand spots total. In-process design (not a distributed cluster) unless you choose to extend it.
- Vehicle-to-spot compatibility rule (you may refine it): a **motorcycle** fits a motorcycle/compact/large spot; a **car** fits a compact/large spot; a **truck** fits only a large spot.
- A vehicle occupies exactly one spot (multi-spot oversized vehicles are an optional extension, not a base requirement).
- Many gates may admit vehicles **concurrently** (multiple threads), so spot reservation must be race-free.
- Fees are time-based; the exact rate table is up to you but should be encapsulated, not hard-coded into the assignment logic.
- The interviewer cares more about clean abstractions, correctness under concurrency, and extensibility than about an exhaustive feature list.
### Clarifying Questions to Ask
- Is this an in-memory single-process design, or must state survive restarts / scale across multiple gate servers (persistence and distributed locking)?
- What is the exact vehicle-to-spot compatibility matrix, and can a vehicle occupy more than one spot (e.g. a truck spanning two spots)?
- How is the fee computed — flat per-hour, tiered by vehicle type, free grace period, daily cap, or dynamic pricing?
- What spot-assignment policy is desired (nearest entrance, first available, cheapest), and must it be configurable?
- What is the expected scale (floors, spots, peak concurrent entries/exits) so I can pick the right data structures and locking granularity?
- Are payments in scope, or does the design stop at computing the fee and releasing the spot?
### What a Strong Answer Covers
- **Clean class boundaries**: `ParkingLot` / `Floor` / `ParkingSpot` / `Vehicle` / `Ticket` / pricing, with composition vs. inheritance/enum used appropriately (small fixed type sets → enums, not deep hierarchies).
- **Encapsulated compatibility rules** in one place (no scattered conditionals).
- A **clear public API** for entry, exit, and availability, with the entry/exit flows spelled out step by step.
- A **pluggable assignment strategy** (Strategy pattern) and an **encapsulated pricing policy**.
- A **concurrency-safe reservation** that the candidate can defend: where the atomicity lives (CAS / atomic poll / per-spot lock), why the naive find-then-mark is racy, and the retry-on-contention path. Awareness of lock granularity (per-spot vs. per-floor) and avoiding a global lock.
- **Efficient availability**: free-spot indexes/counters so assignment and `getAvailability()` aren't O(total spots).
- **Edge cases**: lot full, no compatible spot, unknown/already-closed ticket, double exit, clock handling for fees.
- **Extensibility**: how EV charging spots, reserved/handicapped spots, dynamic pricing, or persistence slot in without rewrites.
### Follow-up Questions
- The lot now spans **multiple gate servers** sharing one source of truth. How does your atomic, in-memory reservation translate to a database or distributed setting (optimistic vs. pessimistic locking, conditional `UPDATE`, or a distributed lock)?
- Add **electric-vehicle charging spots** and **reserved/handicapped spots**. Which classes change, and does your compatibility/assignment logic need new abstractions or just new data?
- Support **dynamic, surge-based pricing** that depends on real-time occupancy. Where does that fit, and how do you keep it testable and isolated from spot assignment?
- A truck needs **two adjacent spots**. How does atomic reservation and rollback change when a claim spans multiple spots that must all succeed or all be released?
Quick Answer: This question evaluates object-oriented modeling, API design, resource allocation, and concurrency control by asking for classes, relationships, key methods, and a thread-safe spot assignment strategy for a multi-floor parking lot.