面灵AI

字节后端面经:广告去重、知识图谱发布与 Saga 补偿

时间
2026-09
来源
牛客网

《面试题目》

后端开发,9 月 3 日

  1. 面对十亿级用户、百万级广告,如何以较低内存成本实现广告曝光频控和去重?
  2. 是否需要为每个用户维护 RoaringBitmap,百万级广告怎样容纳?
  3. 如果用 ZSet,以广告 ID 为 Key 时用户维度怎样保存?以用户 ID 和日期为 Key 时又怎样保存广告和判重?
  4. 平时主要写 Go 还是 Java?
  5. 基于 RAG 的 Agent 可以从哪些方面提升召回质量和最终效果?
  6. Kafka 怎样做负载均衡,10 个消费者实例中有 3 个宕机时会发生什么?

抖音电商开发,9 月 3 日

  1. 实习什么时候开始,两个多月主要负责知识图谱平台的哪些工作?
  2. 原有系统使用 RAG 还是知识图谱,接口背后是业务系统还是文档检索,是否替换了原知识库?
  3. 多文档关联检索具体是什么?
  4. “字节跳动公司”“北京字节跳动公司”“字节跳动”等实体如何去重,怎样防止误合并,是否需要人工审核?
  5. “苹果”同时表示水果和公司时怎样消歧,是否有模型判断之外的系统化管理方式?
  6. 为什么采用 KB、Document、Revision、Snapshot、Artifact、Deployment 这样的分层?
  7. 构建失败能否断点续跑,发布后能否回滚?
  8. 一个知识库能否并行构建,两个任务同时到达发布节点或其中一个失败时怎样处理?
  9. Qdrant 和 Neo4j 为什么需要同时使用,一边写入成功、另一边失败时怎样处理,线上以哪个版本为准?
  10. Dense、Sparse 和 RRF 分别是什么?
  11. 图谱扩展为什么限制三跳而非四跳,是否有数据集评估依据?
  12. 两个任务怎样避免竞争更新同一个状态?
  13. Agent 的约束分别怎样通过程序和提示词实现,校验能覆盖哪些异常?
  14. 上下文压缩如何评估质量,怎样避免重复压缩?
  15. Agent 是否基于开源框架,怎样防止死循环和连续工具超时?
  16. 工具怎样分类,工具始终超时该怎样处理,跳过自有工具会有什么影响?
  17. 怎样优化 CLI 或 MCP 交互?工具执行要 100 秒,但 Agent 只能等待 50 秒时怎么办?
  18. 主节点必须拿到结果才能继续时,怎样处理长任务,是否提供心跳和进度?
  19. 平台的数据来自哪里,怎样保证一致性?
  20. 原始数据已经结构化,为什么还需要知识图谱,用 API 网关聚合能否替代图数据库?
  21. MySQL 与 Redis 怎样保持一致,删除缓存后如何防止大量请求冲向数据库?
  22. 乐观锁和悲观锁有什么区别,高并发订单更新怎样选型?
  23. 为什么还需要 Redis 锁,怎样设计获取与释放时机?
  24. 查询时数据是 A,真正修改前变成 B,应该怎样处理?

国际化广告后端,9 月 2 日

  1. 能否做一下自我介绍,说明电商微服务项目的性能优化措施?
  2. 项目中 Redis 与数据库怎样保持一致?
  3. 令牌桶限流怎样实现,还了解哪些限流算法?
  4. 分布式事务怎样实现,除 Saga 外还有哪些方案,为什么选择 Saga?
  5. Saga 的哪些失败会影响最终一致性,补偿操作失败时怎样处理?

后端开发,9 月 2 日

  1. 能否介绍个人背景和项目?
  2. 文档切片大小怎样确定,过大或过小分别有什么问题?
  3. 查询重写解决什么问题,召回流程怎样组织?
  4. 模型回答错误时怎样定位原因?
  5. 向量检索和元数据过滤怎样安排先后顺序?
  6. ReAct 的核心循环是什么,怎样避免无限执行并应对攻击性指令?
  7. 团购点评平台有哪些功能,主要业务流程是什么?
  8. 先更新数据库再删除缓存是否保证强一致,删除失败时怎样处理?
  9. 事务是什么,有哪些隔离级别?
  10. Redis 有哪些持久化机制,相关后台持久化为什么使用子进程而非子线程?
  11. 消息队列解决什么问题,如何处理重复消费、首次失败和再次执行的业务副作用?
  12. Java 与 Python 有什么区别,Python 是否需要编译?

《参考解析》

广告频控先确定时间窗口与误差要求

“看过就永远不展示”和“同一天最多出现若干次”需要不同的数据。先明确保留多久、是否允许误判、是否需要计数,再讨论结构。可以按活跃用户与时间窗口保存近期曝光,避免给每个注册用户永久分配一份完整广告空间。

RoaringBitmap 对不同分布采用不同容器,实际大小取决于 ID 分布和数量;不能仅凭广告总量估算压缩率。ZSet 可以用广告 ID 作为成员、曝光时间作为分数,但对象开销也要计入。需要精确次数时,还要有相应计数。上线方案应使用真实曝光分布测量内存和查询延迟。

多存储发布可以统一在版本入口切换

一个可行设计是让每次构建生成不可变版本,在两个存储里都写入该版本,校验完整后再修改线上版本指针。只完成一边的版本保持不可见,失败后可重试或清理。读请求先确定版本,再将同一版本带入两边查询。

并发发布需要比较预期旧版本和任务状态,只有获准的任务才能推进指针。回滚也是切回保留完整的旧版本。这要求存储、索引、缓存与查询都支持版本隔离;仅增加一个版本字段并不能自动获得一致性。

实体合并与检索效果要分别评估

实体名相近只能用来生成候选。还应核对类型、上下文、稳定标识与来源,低置信结果保留为待确认关系,避免错误合并污染整张图。检索侧分别测量相关材料有没有被召回、排序是否靠前,以及答案是否引用正确材料。

图谱跳数只是控制查询成本的一种参数。三跳是否足够,要看问题集上的收益与代价;不能把一次选型写成普遍规律。RRF 则按各路结果的排名融合,常见形式为各路 1 / (k + rank) 相加,不要求向量分数和关键词分数处于相同尺度。

长任务把等待状态保存下来

如果调用链只容许等待 50 秒,100 秒的工具应返回任务标识,由调用者查询状态或在完成后接收通知。Agent 的待办步骤、输入和任务标识需要持久化,恢复执行时才能接着处理结果。心跳能报告存活,但无法越过链路中的绝对执行期限。

Saga 补偿也是会失败的业务操作

每一步都记录执行结果与补偿状态,补偿操作要可重复执行,并对乱序和重复请求有明确处理方式。短暂失败可以重试;超过次数或遇到不可自动恢复的业务冲突,要进入可追踪的异常处理流程。Saga 依赖各步骤的语义补偿,不能让已经发生的外部事实自动消失。

先更新数据库再删除缓存同样不能保证强一致:并发读写和删除失败仍会产生窗口。应说明允许多长时间的旧数据、失败如何可靠重试;对严格一致的关键判断,直接使用具备事务约束的权威存储。