Build a React Parking Lot Manager
Company: Uber
Role: Frontend Engineer
Category: Software Engineering Fundamentals
Difficulty: medium
Interview Round: Technical Screen
Build a React single-page application that a parking-lot attendant can use to run a small lot from a single screen. The lot has a **configurable number of spaces**, and every space has a **type** — `compact`, `regular`, or `large`.
The application must let the attendant:
- See current occupancy at a glance (total, occupied, and available — broken down by space type).
- **Check a vehicle in**: the attendant enters the vehicle (e.g. license plate and vehicle type), and the app assigns the **nearest compatible available space** (a smaller vehicle may use an equal-or-larger space; a larger vehicle may **not** use a smaller one).
- **Check a vehicle out**, freeing its space.
- **Calculate the parking fee** from the entry and exit time.
- View a **history of completed parking sessions**.
All state lives in the browser — **no backend is required**. Use **functional components and hooks**, and design the code so it is **easy to extend** with new pricing rules or new vehicle types. Be ready to walk through your component tree, your state shape, the space-assignment algorithm, the fee function, and how the design absorbs new pricing rules or vehicle types without rewrites.
```hint Atomic mutations
A single check-in (or check-out) touches several pieces of state at once. If you reach for a separate `useState` per slice, what happens when one setter runs and another doesn't? Think about what keeps those updates consistent.
```
```hint Where derived values live
Occupancy counts (total / occupied / available per type) can be *stored* or *computed*. One of those choices quietly drifts out of sync the moment a check-in updates spaces but forgets to update a count. Which do you trust?
```
```hint Comparing sizes
"A smaller vehicle may use an equal-or-larger space" hints that vehicle and space sizes can be compared. What representation of size turns "fits?" into one comparison — and lets you add a new vehicle type without rewriting the compatibility check?
```
```hint Keeping pricing out of the UI
Imagine the interviewer asks for per-vehicle-type rates, a grace period, and a cap mid-interview. If those live inside your components, every change is a JSX edit. Where could pricing live so that adding a rule is a config change, not a component change?
```
```hint Edge cases to guard
Duplicate plate already parked, missing/invalid form fields, a full (or full-for-this-size) lot, double check-out, and a zero/negative duration. Prefer disabling invalid actions and surfacing actionable errors over throwing.
```
### Constraints & Assumptions
- Single-page React app, client-side only. No server, no auth; persistence beyond a page refresh is optional (call it out if you add it).
- Lot size is configurable at startup (e.g. 20–500 spaces is plenty for a demo); the UI should remain usable at that size.
- "Nearest" means lowest-distance space — model distance as the space's numeric id/index (space `0` is closest to the entrance) unless you justify another metric.
- A vehicle occupies exactly one space; a space holds at most one vehicle at a time.
- Time can be taken from the system clock (`Date.now()`), but the fee logic should accept explicit start/end timestamps so it is testable.
- A plate is treated as a unique identifier for an *active* session; it may appear again after check-out.
### Clarifying Questions to Ask
- What's the pricing model — flat per-entry, per-hour, per-started-hour, tiered, or different rates per vehicle type? Is there a grace period or daily cap?
- Should "nearest" be by physical proximity to the entrance, or is lowest space id an acceptable proxy? Is minimizing wasted capacity (don't put a compact car in a large space) a goal?
- Does the lot have multiple floors/zones now, or should I just keep the model open to it?
- Should completed-session history and current state survive a page refresh (local storage), or is in-memory fine?
- Roughly how many spaces should the UI handle, and do you want a visual grid or a summary-only view?
- Is there any concept of reservations, or is it purely walk-up check-in?
### What a Strong Answer Covers
- **Component decomposition**: a sensible tree (summary, grid/list, check-in form, active sessions, history) with clear ownership of state and one-way data flow.
- **State shape**: normalized separation of spaces and sessions; derived values computed, not stored.
- **Atomic mutations**: check-in/check-out implemented as reducer actions so multi-field updates stay consistent.
- **Assignment correctness**: respects size compatibility and the "nearest" rule, with a clear answer for "lot full for this size."
- **Fee logic**: a pure, testable function decoupled from the UI, with explicit timestamps.
- **Extensibility**: a real seam (config/strategy) for new pricing rules and vehicle types, not hard-coded `if` ladders.
- **Edge-case handling & UX**: validation, disabled invalid actions, clear errors, predictable updates.
- **React hygiene**: correct hook usage, stable keys, memoization where it matters, no derived-state-in-state.
### Follow-up Questions
- How would you add a **multi-floor** lot, or **reserved** spaces, with minimal changes to your model?
- The lot grows to thousands of spaces and check-ins are frequent — how do you keep assignment fast and the grid render performant?
- How would you make the fee engine support **per-vehicle-type rates**, a **daily cap**, and a **grace period** without touching component code?
- How would you unit-test the assignment and fee logic, and what would you mock to test check-in/check-out end-to-end?
- If you later add a backend, what changes in your component contract, and how do you handle optimistic updates and conflicts?
Quick Answer: This question evaluates frontend engineering skills in React, including functional components and hooks, client-side state management, UI design, algorithmic space-assignment, pricing and billing logic, data modeling for vehicle and space types, and extensibility for new rules.