今天分享一道比较典型的 Uber 后端 / Full Stack 面试风格题。
这类题本身算法不算特别难,重点更多在于:面对一个看起来很普通的业务需求,能不能先把规则理清楚,再设计出一个方便扩展的实现。
Interview Question
Design and implement an order status aggregator.
You are given a stream of order status updates:
(orderId, status, timestamp)
Possible statuses include:
CREATED
ACCEPTED
PICKED_UP
DELIVERED
CANCELLED
Implement a service that can return the latest valid status for each order.
Example:
Input:
(101, CREATED, 10:00)
(101, ACCEPTED, 10:02)
(102, CREATED, 10:03)
(101, PICKED_UP, 10:10)
(102, CANCELLED, 10:11)
(101, DELIVERED, 10:25)
Expected result:
101 -> DELIVERED
102 -> CANCELLED
接下来 interviewer 又追加了几个要求:
- status update 可能乱序到达
- 同一个事件可能重复发送
- DELIVERED 和 CANCELLED 属于 terminal status
- 已经结束的订单不能重新回到 CREATED / ACCEPTED
- 数据量可能持续增长
中文简述
简单来说,就是系统不断收到订单状态变化,需要维护每个订单当前真正有效的状态。
第一眼看起来可能就是:
Map<OrderId, Status>
每收到一个 update 就覆盖。
但这么写很快就会遇到问题。
比如:
10:10 PICKED_UP
10:02 ACCEPTED
如果 ACCEPTED 因为网络延迟后到,直接覆盖就会让订单状态发生倒退。
所以这道题真正需要解决的是:
事件到达顺序,不一定等于事件发生顺序。
思路
比较自然的做法,是为每个订单保存当前状态以及对应的 timestamp。
新的事件到来时,先比较时间:
newTimestamp > currentTimestamp
才考虑更新状态。
但只比较 timestamp 还不够。
例如:
10:20 DELIVERED
10:25 ACCEPTED
虽然 ACCEPTED 时间更新,但这个状态转换本身就是非法的。
所以还需要维护一套状态转换规则,例如:
CREATED -> ACCEPTED
ACCEPTED -> PICKED_UP
PICKED_UP -> DELIVERED
CREATED -> CANCELLED
ACCEPTED -> CANCELLED
而:
DELIVERED -> ACCEPTED
CANCELLED -> PICKED_UP
应该直接忽略。
这样整个处理流程就比较清楚:
收到事件
↓
检查是否重复
↓
比较 timestamp
↓
检查状态转换是否合法
↓
更新订单当前状态
一个容易被追问的地方
Interviewer 问:
What if two updates have the same timestamp?
这里最好不要直接假设这种情况不会出现。
可以继续确认系统有没有:
eventId
sequenceNumber
version
如果有 sequence number,就可以使用:
(timestamp, sequenceNumber)
共同决定事件顺序。
如果什么都没有,那么仅靠现有信息实际上无法百分之百确定两个事件的先后关系。
这个时候指出数据模型本身存在限制,反而比自己随便规定一个顺序更合理。
Follow-up
后面又进一步问:
What if this service needs to handle millions of active orders?
这时问题就开始从 coding 往 system design 靠了。
单机里的:
HashMap<OrderId, OrderState>
肯定不能无限增长。
可以考虑按照:
hash(orderId)
进行 partition,让同一个 orderId 的事件始终进入同一个 partition。
这样每个 worker 只维护一部分订单。
对于已经:
DELIVERED
CANCELLED
的订单,也没有必要永久保存在内存里,可以在一定时间后持久化并清理。
如果整个系统是 event-driven 的,还可以进一步讨论:
Kafka
↓
Order Status Processor
↓
State Store
↓
Query API
不过面试里不一定需要一开始就把架构铺得特别大。
先把单个订单状态处理正确,再根据 interviewer 的 follow-up 逐步扩展,通常会更自然。
这道题容易出问题的地方
比较常见的是一上来就直接:
map[orderId] = status
只考虑最后收到的事件,没有考虑乱序。
另一种情况是为了防止乱序,只比较 timestamp,却忘了状态机本身也有限制。
真正比较完整的答案应该同时考虑:
时间顺序 + 状态转换规则 + 幂等处理。
这类题也是现在大厂面试里比较常见的一种形式。
表面上像一道简单 coding 题,但 interviewer 会不断增加:
out-of-order events
duplicate events
concurrency
scalability
failure recovery
最后慢慢变成一个小型 system design。
如果你最近也在准备 Uber、Google、Meta、Stripe、Amazon 这类公司的技术面试,csoahelp 可以提供实时文本面试辅助以及 Mock Interview。
实际面试中,很多题真正困难的地方并不是代码,而是 interviewer 不断追加条件之后,如何快速判断他想考察的方向,并保持回答结构清晰。
Mock 面试也会尽量按照这种形式进行:先给基础问题,再逐步加入 follow-up,而不是提前把所有条件一次性告诉你。
我们也有代面试,面试辅助,OA代写等服务助您早日上岸~

