SWE · System / Product Design

Meta 公司新闻聚合:RSS抓取、去重与最新Top X

从RSS获取多家公司新闻,提供指定公司最新X条,并处理重复、修订与抓取延迟。

题目重点:从RSS获取多家公司新闻,提供指定公司最新X条,并处理重复、修订与抓取延迟。

题意与假设

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

  • 训练以一个RSS源开始,可扩多个;公司归属由受控实体表与可核对内容决定,不简单对标题substring匹配。
  • “最新”按publishTime还是ingestionTime必须明确;示例按可信publishTime降序、同刻articleId稳定排序。缺失或未来异常时间需独立处理。
  • 新闻版权内容按许可保存摘要与链接;本文讨论索引架构,不虚构可无限转载的权限。

解题路线

  1. poller带ETag/Last-Modified条件抓取,失败指数backoff,记录source水位和fetch版本。每item用(source,guid)去重,guid缺失时以规范URL/hash生成训练标识,同时防不同文章碰撞。
  2. 保留articleId、canonicalUrl、publishTime、firstSeenAt、contentVersion与companyMappings。标题/摘要修订更新版本而非新增排名项;URL追踪参数去除规则应受控,不能删除有意义参数。
  3. 按(companyId,publishTime DESC,articleId)建索引;GET companyNews(limit,cursor)走keyset,响应带dataAsOf/sourceLag。公司别名合并由实体ID保持稳定,多公司新闻可多对多映射。
  4. source时间错误不能让未来新闻永久占榜,暂存待核或单列uncertainTimestamp;乱序抓取与延迟文章仍按publishTime插入。删文/撤稿作为可见状态更新,并使列表缓存失效。
  5. cache最新TopN高频公司,索引版本变更更新或失效;不同X截取同快照,分页cursor含epoch。监控feed freshness而非只有poller HTTP成功。

手动走一遍

一条guid=G新闻首抓标题A、次抓标题B,应更新同article版本而非在TopX出现两次。公司A/B共同并购新闻可以属于两家公司,属于A查询只算该article一次。

规模与取舍

每公司索引TopX查询O(log M+X);入库按公司映射数量插入索引,候选公司识别成本与文本长度/实体表有关。poll频率决定最低新闻延迟,不能以缓存命中率承诺实时。

易错点与追问

容易失分的边界

  • RSS item顺序不一定是发布时间顺序,也可能缺项;不能只处理第一条作为水位。
  • 只以标题去重会把不同公司相似标题错合,也会让标题修订变新文章。

继续深挖

  • 扩到多个feed后,如何合并同一新闻不同转载?保留source provenance与article clustering,去重置信度不足时不强行删除。
  • 一家公司改名时旧新闻如何继续可查?实体ID不变,别名带生效区间,避免名字被另一家公司复用。
✓已复制微信号!