‹ 全部面经
Amazon 26NG OOD 面经:设计多电梯调度系统 Elevator
Amazon 26NG OOD 轮复盘:BQ 考紧急需求插队与任务分配;OOD 设计多电梯调度系统,覆盖请求队列、上下行调度、超载判断、调度策略抽象,Follow-up 高峰期、VIP、消防模式。
Amazon
VO
面试概况
分享一轮七月份 26NG 的 OOD 设计。
BQ
- 紧急需求插队时如何处理?
- 团队任务分配与进度对齐。
OOD:多电梯调度系统
印度裔面试官给了一段描述,其实就是设计一个多电梯调度系统,需要支持:
- 请求楼层
- 上下行调度
- 到达停靠
- 超载判断
- 请求队列管理
- 调度策略抽象
- 多电梯协同
核心类设计
| 类 | 职责 |
|---|---|
Request |
一次呼叫:楼层、方向、是否 VIP |
Elevator |
单部电梯的状态:当前楼层、方向、载重、待停靠楼层 |
DispatchStrategy |
调度策略接口,决定把请求分给哪部电梯 |
ElevatorController |
管理所有电梯和请求队列,负责派单和模式切换 |
参考骨架
import heapq
from abc import ABC, abstractmethod
from dataclasses import dataclass, field
from enum import Enum
class Direction(Enum):
UP = 1
DOWN = -1
IDLE = 0
@dataclass(order=True)
class Request:
priority: int # VIP = 0,普通 = 1,数字越小越先处理
floor: int = field(compare=False)
direction: Direction = field(compare=False)
class Elevator:
def __init__(self, eid, capacity_kg):
self.id, self.capacity_kg = eid, capacity_kg
self.floor, self.load_kg = 0, 0
self.direction = Direction.IDLE
self.stops = set()
def is_overloaded(self):
return self.load_kg > self.capacity_kg
def add_stop(self, floor):
self.stops.add(floor)
def step(self):
"""每个时间单位移动一层;到达停靠层则开门"""
if self.is_overloaded():
return # 超载:不关门、不移动
if not self.stops:
self.direction = Direction.IDLE
return
target = min(self.stops, key=lambda f: abs(f - self.floor))
if target != self.floor:
self.direction = Direction.UP if target > self.floor else Direction.DOWN
self.floor += self.direction.value
self.stops.discard(self.floor)
class DispatchStrategy(ABC):
@abstractmethod
def choose(self, elevators, request): ...
class NearestCarStrategy(DispatchStrategy):
"""选距离最近、且空闲或顺路的电梯"""
def choose(self, elevators, request):
def cost(e):
on_the_way = e.direction in (Direction.IDLE, request.direction)
return abs(e.floor - request.floor) + (0 if on_the_way else 100)
candidates = [e for e in elevators if not e.is_overloaded()]
return min(candidates, key=cost) if candidates else None
class ElevatorController:
def __init__(self, elevators, strategy: DispatchStrategy):
self.elevators, self.strategy = elevators, strategy
self.pending = [] # 优先队列:VIP 先派
self.fire_mode = False
def request(self, req: Request):
if not self.fire_mode:
heapq.heappush(self.pending, req)
def set_strategy(self, strategy: DispatchStrategy):
self.strategy = strategy # 高峰期等场景直接替换策略
def enter_fire_mode(self):
self.fire_mode, self.pending = True, []
for e in self.elevators:
e.stops = {0} # 全部回到一楼,停止接单
def tick(self):
while self.pending:
req = self.pending[0]
car = self.strategy.choose(self.elevators, req)
if car is None:
break # 暂时没有可用电梯,下个 tick 再派
heapq.heappop(self.pending)
car.add_stop(req.floor)
for e in self.elevators:
e.step()
设计要点
- 策略模式:调度算法抽象成
DispatchStrategy,新增算法不需要改 Controller。 - 优先队列:请求队列按优先级出队,天然支持 VIP。
- 模式切换:消防模式集中在 Controller 里处理,清空队列、所有电梯回到一楼。
Follow-up
如果要支持下面这些场景,应该怎么设计?
| 场景 | 设计思路 |
|---|---|
| 高峰期调度 | 新增 PeakHourStrategy(比如早高峰让空闲电梯回到大堂待命),用 set_strategy 按时间段切换 |
| VIP 优先 | Request.priority 设为更高优先级,在队列中优先派单;也可以给 VIP 预留专用电梯 |
| 消防模式 | 用状态模式(State Pattern)管理 Normal / Fire 模式:进入消防模式时清空请求、全部回到一楼、只响应消防员指令 |