题目重点:统一爬取/发布入口、文章去重、全局趋势、订阅召回和热点作者扩散,保留不同面经的发布与点击跳转变体。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 将文章正文主要保留在原发布站,feed 存 canonical URL、publisher/topic、标题/摘要与时间; 明确文章可以只是链接,爬取版 需遵循 publisher 的接入协议。
- 50,000×100=5,000,000 篇/日约 58 篇/秒均值,仅源于 的该轮面试数字;实际峰值、正文大小和用户刷新频率未知,不把 100k 同时在线直接当请求每秒。
解题路线
- 摄入:publisher API/RSS/授权爬取各有 adapter,标准化 article_id、canonical URL、发布时间、topic、语言;以 publisher+源 ID 或 canonical URL 去重,保留更新版本与失败重试。
- 存储与检索:文章元数据写持久库,按时间和 topic/publisher 建索引;订阅关系单独存 UserFollow(user,topic/publisher)。访客走全局/地区趋势,登录用户先召回关注发布源和 topic,再混合趋势与质量约束排序。
- 全局趋势从曝光/点击事件按 publisher/article 分区聚合,明确时间窗、去重与作弊过滤;publisher 是否 celebrity 应看粉丝数、写入 fanout 成本与突发热度,不应只用点击数猜固定阈值。
- 的 breaking news 变体要求所有主页可见:由受控编辑/事件通道给文章设范围、优先级、有效时间与撤回状态,读取 feed 时在个性化结果前合并当前有效热点;全站硬推应防过期、误报与重复,用户刷新缓存需有失效或短 TTL。
- Feed fanout 对普通源可预推部分 inbox;热点源写一次、读时按关注关系 pull/混排,避免一篇文章推送给海量用户。热点榜与个性化缓存分别定 TTL 和失效,文章撤回要清理索引/缓存。
- 系统数据库选择依据访问模式:订阅关系强一致、文章元数据、事件分析的主键和查询不同;不要因为‘大规模’一词统一改用 NoSQL、列存或 Flink。按实际延迟/成本测量决定消息流和流处理。
手动走一遍
发布源 P 新发 URL A,adapter 标准化并去重,索引后 P 的关注者能在 feed 召回;同时点击事件使 A 进入候选趋势榜。若 P 拥有 500 万关注者,采用读取时合并或有限预推,避免每篇写 500 万 inbox。访客无法用用户订阅,返回带地区/语言过滤的全局榜。
规模与取舍
公开示例入站约 5M 文章/日、平均 58/s;保存元数据、索引与事件的容量由字段大小和保留期决定。单用户读取可用按来源候选的 top K 归并,成本取决于关注源数 F、每源候选数与 K,不能仅由 MAU 算出固定 QPS。
易错点与追问
容易失分的边界
- 把 MAU 或并发在线人数直接当 QPS。
- 混淆文章来源爬取与只存链接的不同接入协议。
- 为 celebrity 文章对所有粉丝做同步 fanout。
- 趋势榜只累加点击、不处理重复事件或作弊。
- 个性化只按关注返回,忽略访客与全局热点要求。
继续深挖
- 用户刚关注 publisher,旧文章何时进入 feed?
- Publisher 撤稿或 URL 改变,缓存和搜索索引如何同步?
- 如何识别真实热点与机器人点击?
- 何时需要列式存储,何时事务型关系库更合适?
