Problem framing
Design a building elevator system: passengers request rides from hall panels (external) or press floor buttons inside the cabin (internal). The controller assigns requests to elevators and moves cars efficiently. Tests state modeling, request scheduling, and Strategy for dispatch — a step up from vending-machine state because multiple elevators and competing requests interact.
| Entity | Responsibility |
|---|---|
ElevatorController | Facade: requestElevator(floor, direction), routes to an elevator |
Elevator | One shaft/car: current floor, direction, open/closed door, request queues |
Request | floor, direction (UP/DOWN), source (INTERNAL/EXTERNAL) |
ElevatorState | IDLE, MOVING_UP, MOVING_DOWN, DOOR_OPEN |
DispatchStrategy | Pick which elevator serves an external request |
Request types
External (hall) — passenger on floor F presses Up or Down. Elevator must stop at F while moving in the matching direction (or idle nearby). Internal (cabin) — passenger selects destination floor; always honored while car is in service.
Keep two sets per elevator: upStops and downStops (sorted sets or priority queues) — classic interview simplification.
Scheduling algorithms (Strategy)
| Algorithm | Behavior | Interview use |
|---|---|---|
| Nearest car | Assign request to closest idle/nearest elevator | Simple default; starves distant cars |
| SCAN / elevator algorithm | Continue current direction, service all stops, then reverse | Fair, easy to explain on whiteboard |
| LOOK | SCAN but don't go to last floor if no requests | Slight optimization |
Encapsulate in DispatchStrategy so ElevatorController stays thin. For a single elevator interview, skip multi-car dispatch and focus on stop ordering inside one Elevator.
Core flows
requestElevator(floor, direction) — controller selects elevator via strategy → enqueue stop on that car's up/down queue → wake dispatcher if idle.
step() / tick() — simulation driver moves car one floor toward target, opens door at stops, clears served requests. In LLD you often expose move() and openDoor() rather than a real-time loop.
selectFloor(floor) — internal request from current passenger; add to queue for current direction.
State machine
IDLE → (request) → MOVING_UP / MOVING_DOWN
MOVING_* → (at stop) → DOOR_OPEN → (timer/closeDoor) → MOVING_* or IDLE
Use State pattern only if interviewer pushes multiple modes with different rules; otherwise enum + switch is fine — mention State if adding MaintenanceMode or FireServiceMode.
Senior-level signal
Clarify scope: number of elevators, max floors, disabled weight/capacity, emergency override. Discuss why SCAN beats greedy nearest for fairness. For concurrency: one thread per elevator vs centralized dispatcher with locks — single-threaded simulation is enough; note synchronized on request queues for multi-threaded extension.
Mention out of scope: building security integration, destination dispatch (passenger enters destination at lobby before boarding), predictive AI dispatch.
Where this goes next
Online Chess shifts from physical resource scheduling to rules engines — polymorphic piece behavior and game-state invariants without a monolithic Board class.
Further Reading
Practice Tasks (Optional)
Design or implement locally in any language — no autograding. Focus on class structure, extensibility, and being able to explain trade-offs out loud.
- Design elevator dispatch for one shaft45m
Classes: ElevatorController, Elevator, Request (floor, direction, source). API: requestElevator(floor, direction), selectFloor(floor). Walk through: external up-request on floor 3 while elevator at 1 moving up with stops at 2 and 5. Sketch SCAN vs nearest-car.