Data Platform · R2 VO Problem Solving

Netflix 电影轮播:分数更新与每周期只展示一次

从 Data Platform VO 的 score update 和无重复 rotation 出发,给出可验证的简单实现,并推导两个有序集合支持高效更新与多线程。

题目重点:从 Data Platform VO 的 score update 和无重复 rotation 出发,给出可验证的简单实现,并推导两个有序集合支持高效更新与多线程。

题意与假设

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

  • 训练版电影集合固定,分数可更新,get/next 选本轮尚未展示电影中的最高分,同分按 movie id 稳定排序;题目只说支持 score update 与 rotation,没有给排序和同分规则。
  • 更新已展示电影的分数只影响下一轮;更新未展示电影的分数影响本轮后续选择。空集合返回 None。
  • 本地单进程版本不支持 add/remove;若要动态增删,必须约定新片在当前轮还是下轮加入。

解题路线

  1. 维护 scores 与 shown。每次 next 从 `scores−shown` 选择最高分,返回后标记 shown;当 shown 覆盖全部电影时清空,开启下一轮。参考代码用线性扫描先保证语义容易验证。
  2. 生产优化维护两个按 `(score,id)` 有序的结构:available 存本轮未展示,shown 存已展示。next 从 available 取最高并移到 shown;更新分数时在对应结构中删除旧键并插入新键;available 为空时交换两结构开启下一轮。平衡树或 TreeMap/SortedList 支持 O(log M) 操作,单纯 heap 对任意 score update 要版本化惰性删除并注意内存增长。
  3. 多线程下 next 与轮回切换、score 更新必须在同一一致性边界内;可先用全局 mutex 保正确,再用分区/单 owner actor 处理吞吐。分布式持久化需保存两集合状态和分数版本,重复请求要幂等。

手动走一遍

训练例 A:9、B:5、C:2,依次 next 得 A、B;此时把 C 改为 10,下次仍得 C,因为本轮只剩 C。再 next 时新一轮开始,C 以 10 分最先出现。同分用 id 排序只属训练约定。

Python 参考实现

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

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

class MovieRotation:
    """Simple reference: highest score among unseen movies, stable ID tie-break."""

    def __init__(self, scores):
        self.scores = dict(scores)
        self.shown = set()

    def update_score(self, movie_id, score):
        if movie_id not in self.scores:
            raise KeyError(movie_id)
        self.scores[movie_id] = score

    def next_movie(self):
        if not self.scores:
            return None
        if len(self.shown) == len(self.scores):
            self.shown.clear()
        eligible = (movie_id for movie_id in self.scores if movie_id not in self.shown)
        movie_id = min(eligible, key=lambda item: (-self.scores[item], item))
        self.shown.add(movie_id)
        return movie_id

复杂度

参考代码每次 next 扫描 M 部电影 O(M),update O(1),存储 O(M)。两个平衡有序集合的 next 与 update O(log M),轮次切换可交换引用 O(1);若需要复制不可变快照或分布式事务,成本更高。

易错点与追问

容易失分的边界

  • 每次直接从全体最高分取片,导致高分电影重复霸屏。
  • 更新已展示片后立即让其再次返回,违反每轮一次。
  • 只使用一个 heap,无法简单做 score update 与已展示集合的循环切换。
  • 同分没有稳定规则,多线程请求顺序难复现。
  • 把 的外链题面细节直接当作 的完整同题证据。

继续深挖

  • 多线程同时请求最后一部片时如何只触发一次轮次切换?
  • 动态加入新片时插入当前轮还是下一轮,用户体验有何差别?
  • 分布式多个展示节点共享轮播状态,如何平衡严格无重复与延迟?
✓已复制微信号!