SWE(汇总帖未给具体岗位) · OOD / Technical Coding 题型汇总

Netflix Movie History:Add、按顺序读取与 Clear

根据 Netflix 技术题汇总公开的三个 movie history 接口,给出保留重复浏览的每用户列表训练实现,并扩展并发、分片与事件历史语义。

题目重点:根据 Netflix 技术题汇总公开的三个 movie history 接口,给出保留重复浏览的每用户列表训练实现,并扩展并发、分片与事件历史语义。

题意与假设

这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。

  • 训练版按 user_id 维护历史,电影可重复出现,add 追加到末尾、get 返回完整列表副本、clear 删除该用户列表;题目未明确多用户 API 参数。
  • 历史顺序以调用完成顺序为准;如果输入携带 event_time 且可能乱序,需另设排序与迟到策略。
  • 空用户 get 返回空列表;clear 是当前列表清空,不代表从合规审计账本删除所有历史。

解题路线

  1. 用 `user_id→list[movie_id]` 保存每用户追加序列;add 在末尾追加,get 返回副本保护内部状态,clear 移除 key。
  2. 如果只需最后 K 部,可用有界 deque 降低内存,但会改变 get 全历史的语义;完整历史可写 append-only event log,查询侧按用户分区建索引。
  3. 并发多设备浏览时要明确同一用户事件顺序:用服务端单调序列或分区 offset;重试带 event id 防重复。clear 与并发 add 竞态需定义线性化/版本;隐私删除还需传播到备份和缓存。

手动走一遍

训练例用户 U add A、B、A 后 get 返回 [A,B,A],最近浏览的 A 在末尾。clear(U) 后 get 为 [];先前 get 的返回副本不会随内部 clear 改变。

Python 参考实现

下面的代码按上文假设实现,适合本地运行并追加自己的测试用例。

代码区可横向滚动;使用键盘时,先聚焦代码区再按方向键查看。

class MovieHistory:
    """Per-user append history; repeated movies are preserved."""

    def __init__(self):
        self._history = {}

    def add(self, user_id, movie_id):
        self._history.setdefault(user_id, []).append(movie_id)

    def get(self, user_id):
        return list(self._history.get(user_id, ()))

    def clear(self, user_id):
        self._history.pop(user_id, None)

复杂度

add 预期 O(1) 均摊;get 一名用户 H 条历史为 O(H) 时间/结果空间;clear 删除映射 O(1) 入口,但实际内存回收需释放该列表 O(H) 个引用。全部空间与保留事件数成正比。

易错点与追问

容易失分的边界

  • 把历史做成 set 或按电影去重,丢掉重复浏览与顺序。
  • get 直接返回内部可变列表,调用者可绕过 add 改写状态。
  • clear 当前状态与合规删除/审计保留混为一谈。
  • 跨设备事件乱序时只凭客户端时间排序,容易被时钟偏差误导。
  • 把这题与 q13 最后 K 部电影配对或 q7 ID 查重当成同一个接口题。

继续深挖

  • 按用户最后 K 部查询如何建索引?
  • 多设备同时浏览怎样定义稳定顺序?
  • 重试 add 如何防同一个事件重复入历史?
  • 用户删除历史时离线推荐特征如何同步失效?
✓已复制微信号!