面灵AI→

字节国际化广告后端实习一二面凉经:Coding Agent 与 RabbitMQ

轮次
一二面
结果
挂
时间
2026-09
来源
牛客网

《面试题目》

一面

  1. 自我介绍。
  2. MySQL 怎么保证事务中的操作全部成功或全部失败?undo log 和 redo log 有什么区别?redo log 的底层机制是什么?
  3. 如果让你设计 Agent 的短期记忆和长期记忆,你会怎么做?怎么处理记忆的遗忘和过期?
  4. 你自己做的 Coding Agent 与普通的通用 Agent 有什么区别?
  5. 子 Agent 是怎么实现的?在一个会话里,Agent 怎么创建一个子 Agent,又怎么管理它?
  6. Agent 执行复杂任务时可能耗时很长、步骤很多,如果中间出错、退出或者中断,应该怎么处理?
  7. 你的 Agent 怎么防止陷入死循环?
  8. 我看你的项目都是从今年三月份开始做的,之前没有做过其他事情吗?
  9. MySQL 和 Elasticsearch 有什么区别?两者的索引有什么区别?
  10. 现在有一个联合索引 (A, B),查询条件是 B=1 AND A=2,对于 MySQL 来说,能利用这个索引吗?为什么这样写查询条件也能利用?
  11. 算法:K 个一组反转链表的变种题(不足 k 个也要反转)。
  12. 反问。

二面

  1. 什么是数据库的联合索引?使用联合索引时有什么需要注意的地方?
  2. 讲一下你的 Coding Agent 项目。有评测过吗?如果让你评测,可以从哪些角度出发?稳定性怎么测?
  3. 你这套是单 Agent 的,对吧?多个 Agent 之间的上下文,你是怎么协调的?
  4. 你有哪些子 Agent?代码审查这类 Agent 需要特殊的上下文处理吗?具体怎么做?
  5. 谁来告诉代码审查 Agent 要检查什么、达到什么效果?
  6. 可以无限创建子 Agent 吗?子 Agent 可以再创建自己的子 Agent 吗?为什么不允许?
  7. 如果允许子 Agent 创建子 Agent,怎么防止无限递归?如果允许递归深度大于 2,应该怎么防止?
  8. 这是你的 Harness 应该处理的逻辑,为什么要交给根 Agent 判断?
  9. 如果几个子 Agent 形成死循环,比如三个工具互相调用、谁都停不下来,你怎么让它们及时停止?你怎么感知循环调用?怎么区分合理的循环调用和死循环?什么时候应该把它们喊停?
  10. 你这套方案与直接使用 Codex 相比,有什么优势?
  11. 你的项目亮点是什么?
  12. RabbitMQ 的生产消费模型是怎样的?消费失败了怎么办?有死信队列之类的设计吗?这是 RabbitMQ 自带的死信队列吗?死信队列最多能接受多少条消息、有上限吗?如果需要重试的消息超过了死信队列的最大容量,应该怎么设计?
  13. 算法:十六进制大数相乘。

《参考解析》

redo log 与 undo log 的分工。undo log 记的是”数据修改前的旧值”,用于回滚和 MVCC 读旧版本,逻辑日志、按行记录;redo log 记的是”数据页上做了什么物理修改”,用于崩溃恢复,物理逻辑日志、顺序写、固定大小循环复用。事务提交时写 redo(WAL,先写日志再刷盘)保证持久性,回滚时用 undo 保证原子性。底层机制上,redo 采用环形缓冲区 + checkpoint:LSN 单调递增标记进度,checkpoint 之前的日志可以被覆盖,崩溃恢复时从 checkpoint 往后重放。

子 Agent 的创建与递归边界。主流实现有两种:一是”进程 / 会话级隔离”,子 Agent 是独立上下文的新会话,根 Agent 只拿到它的最终输出;二是”同一会话内的角色切换”,共用部分上下文但用不同的系统提示与工具集。管理的核心是三件事:生命周期(何时创建、何时回收,避免会话泄漏)、上下文传递(子 Agent 需要哪些信息,只传必要的最小集,否则 token 成本失控)、结果归并(子 Agent 的输出要不要结构化、根 Agent 怎么判断它是否可信)。递归一定要设硬上限,理由是组合爆炸与不可控:每层都可能失败重试,深度一放开,成本、时延、状态一致性都失去可预测性。防无限递归的手段是限制深度 + 全局预算(步数 / token / 时长)+ 调用指纹去重,且这些限制应该由 harness 在工具调用层强制执行,而不是”交给根 Agent 自己判断”——模型可能被诱导、也可能判断错,把安全边界交给被约束对象本身是不成立的。

死循环的判定与停止。硬约束三件套:最大步数、最大 token、整体超时。软判定有三类信号:状态重复(把关键状态归一化后取指纹,连续出现同一指纹说明原地打转)、调用指纹重复(同工具同参数连续调用 N 次)、进展为负(同一子目标连续失败、错误信息不再变化)。区分”合理的循环”与”死循环”要看是否产生新信息:轮询等待外部状态变化、逐条处理列表这类循环,每轮输入在变、进度在推进,是合理的;反复读同一文件、反复调同一接口且参数不变,才是死循环。喊停的时机可以定成”同一指纹第三次出现就中断并降级收尾”,并把已完成步骤与卡点一并交回。

Coding Agent 的评测角度。可分四层:任务完成度(能否通过预先写好的测试、编译是否通过、lint 是否干净)、过程质量(改动文件数、diff 行数、是否绕开问题去打补丁、有没有留下调试代码)、稳定性(同一任务重复跑多次的成功率与方差,比单次成功更重要)、成本与时延(token 消耗、工具调用次数、wall time)。稳定性测试尤其重要,因为 Agent 的失败往往是概率性的,只跑一次通过说明不了问题。

MySQL 与 Elasticsearch 的索引差异。MySQL 默认是 B+ 树,索引与数据同源、支持事务与强一致,擅长按精确值和范围做低延迟点查与范围扫描,写入时还要维护二级索引,代价高;ES 是倒排索引 + doc_values 列存,按词项建 posting list,擅长全文检索、相关性打分与聚合分析,写入是近实时的(refresh 才可见),事务与强一致不是它的目标。选型上常见组合是”MySQL 存权威数据、ES 做检索”,通过 binlog 同步,接受秒级延迟。

死信队列的容量与溢出。RabbitMQ 的死信队列本质是一个普通队列——它没有特殊容量上限,受内存、磁盘和 max-length / TTL 等策略约束。也就是说”死信队列能装多少”取决于你给这个队列配了什么策略,不配就是不设限但可能把 broker 撑爆;配了 x-max-length 就会按策略丢弃或拒绝。所以设计上应该主动给它设上界,并且超过容量要有明确归宿:常见做法是死信队列只作”人工排查入口”,容量较小 + TTL 较短,溢出的消息落到数据库或对象存储里留档,再由定时任务按分类重放。重试本身要分级——用多级延迟队列做递进退避(1min / 5min / 30min),超过最大重试次数才进死信,同时记录失败原因,避免”重试风暴”打垮下游。