class ParkingLot:
The round: a frequently reported Uber object-oriented design question (eight reports here), in phone screens, onsite coding rounds and one AI-assisted coding round. The reported core: a parking lot with park, unpark and checkCar, where motorcycle spots take only motorcycles and regular spots take both motorcycles and cars. Another report names the operations check-in and check-out; another calls it a parking building. In one screening round the candidate first designed the high-level structure with black-box components, then was asked for fully runnable code, with the focus on data structure choice, code quality and performance. One candidate who had not prepared it did not finish the code. Two graded parts here: one lot, then a multi-level building that stays fast at scale.
Part 1 — park, unpark, check_car, with spot types
class ParkingLot:
def __init__(self, spots: list[str]): ... # spots[i] is "motorcycle" or "car"
def park(self, plate: str, vehicle: str) -> int | None: ... # vehicle is "motorcycle" or "car"
def unpark(self, plate: str) -> int | None: ...
def check_car(self, spot: int) -> str | None: ...
"motorcycle" spot takes only motorcycles. A "car" spot takes cars and motorcycles.park returns the spot index it used. A car takes the lowest-numbered free car spot. A motorcycle takes the lowest-numbered free motorcycle spot, and only if there is none, the lowest-numbered free car spot. If no allowed spot is free, return None.unpark frees the vehicle's spot and returns its index, or None if that plate is not parked.check_car returns the plate in a spot, or None if the spot is empty.ValueError for an unknown vehicle type, a plate that is already parked, or a spot index that does not exist.Notes: the reports give the operations and the spot rule, not an interface. The class and method names, string vehicle types, spot numbering, "lowest free spot first", a motorcycle preferring a motorcycle spot, None for a full lot or an unknown plate, and the ValueError cases are ours. The reference also accepts check_in and check_out as names for park and unpark.
In one screening round the interviewer moved from a high-level class design with black-box components to a request for fully runnable code. Reported versions cover park, unpark and checkcar (or check-in and check-out), with motorcycle spots taking only motorcycles and regular spots taking both. One candidate who did not finish the code failed; another wrote runnable code covering edge cases and was still rejected.
Standard explanation — no candidate report records what the interviewer accepted here.
Keep free spots per spot type (and per floor in a multi-story lot) in sets, queues or a min-heap by spot id, plus a map from vehicle or ticket to spot. That makes park and unpark O(1) or O(log n) instead of scanning every spot, and makes checkcar a single map lookup.
Eight reports in our data. It came up in phone screens (one started with behavioural questions and spent the second half on the parking lot OOD), in onsite coding rounds, as the parking-building question, and as the AI-assisted coding round of one onsite. The most specific report gives the rule used here: park, unpark and checkCar, with motorcycle spots for motorcycles only and regular spots for both; that candidate also had a meeting-room question recording how many rooms are in use per time slot. In one screening round the interviewer first wanted a high-level structure with many black-box components, then fully runnable code, and the report lists data structure choice, code quality and performance optimisation as the focus. Finishing is not the whole bar: one candidate wrote runnable code covering edge cases in every coding round, this one included, and was still rejected, which they put down to the system design round. Another candidate had skipped this question while preparing, had not written OOD in a long time, did not finish, and failed. A separate frontend loop asked for a parking lot built in React; that is a different exercise and is not what this page covers.
Also reported as Parking Lot OOD · Parking Lot Design
The round: a frequently reported Uber object-oriented design question (eight reports here), in phone screens, onsite coding rounds and one AI-assisted coding round. The reported core: a parking lot with park, unpark and checkCar, where motorcycle spots take only motorcycles and regular spots take both motorcycles and cars. Another report names the operations check-in and check-out; another calls it a parking building. In one screening round the candidate first designed the high-level structure with black-box components, then was asked for fully runnable code, with the focus on data structure choice, code quality and performance. One candidate who had not prepared it did not finish the code. Two graded parts here: one lot, then a multi-level building that stays fast at scale.
Part 1 — park, unpark, check_car, with spot types
class ParkingLot:
def __init__(self, spots: list[str]): ... # spots[i] is "motorcycle" or "car"
def park(self, plate: str, vehicle: str) -> int | None: ... # vehicle is "motorcycle" or "car"
def unpark(self, plate: str) -> int | None: ...
def check_car(self, spot: int) -> str | None: ...
"motorcycle" spot takes only motorcycles. A "car" spot takes cars and motorcycles.park returns the spot index it used. A car takes the lowest-numbered free car spot. A motorcycle takes the lowest-numbered free motorcycle spot, and only if there is none, the lowest-numbered free car spot. If no allowed spot is free, return None.unpark frees the vehicle's spot and returns its index, or None if that plate is not parked.check_car returns the plate in a spot, or None if the spot is empty.ValueError for an unknown vehicle type, a plate that is already parked, or a spot index that does not exist.Part 2 — a multi-level parking building, fast at scale
class ParkingBuilding:
def __init__(self, levels: list[list[str]]): ... # levels[l][i] is the type of spot i on level l
def park(self, plate: str, vehicle: str) -> tuple[int, int] | None: ...
def unpark(self, plate: str) -> tuple[int, int] | None: ...
def check_car(self, level: int, spot: int) -> str | None: ...
(level, index), and "lowest" means lowest level first, then lowest index. A motorcycle still takes any free motorcycle spot in the building before a car spot.park and unpark must stay fast: the tests fill 200,000 spots and then run 100,000 departures and arrivals. Scanning for a free spot on every park is too slow.Notes: the reports give the operations and the spot rule, not an interface. The class and method names, string vehicle types, spot numbering, "lowest free spot first", a motorcycle preferring a motorcycle spot, None for a full lot or an unknown plate, and the ValueError cases are ours. The reference also accepts check_in and check_out as names for park and unpark.
Now write fully runnable code, not just the skeleton.
What data structures did you choose and why? How does this affect performance?
| Approach | Notes |
|---|---|
| Linear scan for a free spot | simplest; O(S) per park, fine for a small lot. |
| A min-heap of free spots per spot type | O(log S) park and unpark; always hands out the lowest spot. |
| Per-level free counters | O(levels) to find a level with space; enough when the exact spot does not matter. |
Common mistakes: One candidate who had skipped this question while preparing and had not written OOD in a long time did not finish the code and failed.; Finishing is not the whole bar: one candidate wrote runnable code covering edge cases in every coding round, including this one, and was still rejected; they guessed their system design answer was the reason.
Interviewer hints: In one screening round the interviewer first asked only for a high-level structure with black-box components assumed, then asked for fully runnable code.; One report lists the round's focus as data structure choice, code quality and performance optimization.; In one onsite the question was a multi-story parking building.; One report names the operations check-in and check-out.
Edge cases to test: Motorcycle parking in a regular spot (allowed).; Regular car attempting to park in a motorcycle spot (rejected).; Parking lot is full: decide what park() returns or throws.; Unparking a plate that is not parked, or checking a spot that does not exist.; The same plate parked twice.; Multiple floors in a parking building: which spot is handed out first.
Send them this page. It is free to read, no account needed.
What you just read — canonical solution, follow-up arc, what passing candidates actually did — exists for all 83 Uber questions, refreshed monthly from new candidate reports.