Uber 面试题模拟|实时订单状态聚合– 面试真题 – VO help – 代面试 – 一亩三分地

今天分享一道比较典型的 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代写等服务助您早日上岸~

Leave a Reply

Your email address will not be published. Required fields are marked *