面灵AI→

字节跳动全栈一面面经:项目追问、AI 工具与消息可靠下发

轮次
一面
时间
2026-10
来源
牛客网

《面试题目》

  1. 自我介绍。
  2. 挑简历里最出色的部分介绍一下。
  3. 问题排查和体验优化是独立承担的吗?
  4. 再挑一个项目讲讲。
  5. AI 相关的工具使用情况?
  6. 不同 coding agent 的使用区别和个人偏好?
  7. 常用的 AI 技能有哪些?
  8. 假设用户发信息时网络断了,要设计一套系统保证信息不丢失、网络恢复后能去重下发,怎么设计?
  9. 列表、链表、数组的区别?
  10. 数据库的事务 ACID 特性?
  11. 死锁的条件?
  12. 同步和异步的区别?为什么要有异步?
  13. 手撕:合并两个有序数组为一个有序数组,不能用内置排序。

《参考解析》

断网不丢消息 + 重连去重下发:核心是「消息不能只活在连接里」。先把链路拆成发送端、服务端、接收端三段。发送端为每条消息生成客户端 ID(UUID 或雪花号)并本地落盘,状态先记 pending;服务端收到后先持久化(写库或写消息队列)再回 ACK,只有拿到 ACK 客户端才把本地那条标成已发送,没拿到就按退避策略重发——这是「不丢」的一半。断网期间服务端把该会话的新消息按序落库并维护单调递增的会话序号;客户端重连时带上「我已收到的最大序号」作为游标,服务端把游标之后的消息补发。去重靠两边都按消息 ID 做唯一约束:服务端把重复投递的写请求交给唯一索引变成 upsert(先查后写在并发下不可靠),客户端维护已收 ID 集合丢弃重复项。再补两点加分项:连接是有状态的,重连可能落到另一台机器,所以订阅关系要放共享存储(Redis 或 MQ)而不是进程内存;流式消息要把「正在生成」的部分也持久化成可续写状态,否则用户重连后会看到半句话消失。

项目追问:要给出数字,也要守住「我没做」的边界。「问题排查和体验优化是独立承担的吗」这类题,本质是在验证简历真实性和个人贡献度。准备方法是给每个项目备三层信息:背景与我的角色(方案谁定的、我改的是哪一块、和谁协作)、可量化的结果(耗时、失败率、QPS、内存占用,以及这些数字是怎么测出来的)、以及复盘(当时的取舍、现在会怎么改)。被问到独立还是团队时不要夸大,把边界讲清楚反而更可信。面试官让你「挑最出色的」再「挑另一个项目讲讲」,说明他在横向比对不同项目的深度是否一致,所以别只准备一个王牌项目,每段实习和每个侧项目都要能讲到技术细节与踩过的坑。项目追问没记全也没关系,面试前把每个项目写成三句话的提纲,临场按提纲展开即可。

AI 工具与 coding agent:讲清分工与取舍,而不是报工具名。这组问题(常用 AI 工具、不同 coding agent 的区别、常用 AI 技能)考的是你有没有把 AI 真正嵌进工作流。有效的答法是按场景分层:需求澄清与方案对比用什么、写样板代码与单测用什么、排查线上问题(读日志、定位堆栈、写复现脚本)用什么、代码评审与重构用什么;再讲选择依据——上下文窗口与仓库理解能力、是否支持工具调用与多文件编辑、补全延迟与 IDE 集成度、以及数据合规要求。个人偏好要落到具体习惯上,比如先让它输出改动计划再动手、要求它给出可运行的验证命令、小步提交便于回滚。可以顺带提一句风险控制:生成代码必须自己读懂再提交、敏感信息不进提示词、关键路径不交给模型判断。

基础八股:把「定义—机制—边界—例子」四步讲全。数组、链表、列表的区别要落到存储结构与访问代价上:数组是连续内存,随机访问 O(1)、插入删除 O(n)、有扩容与拷贝成本;链表是离散节点加指针,插入删除 O(1)、随机访问 O(n)、缓存局部性差、每节点有额外指针开销;「列表」在不同语言里含义不同(Java 的 List 是接口,Python 的 list 是动态数组),答的时候点明这层差异会显得更严谨。ACID 要逐项讲清各自解决什么问题以及靠什么实现:原子性靠 undo log、一致性是结果约束、隔离性靠锁与 MVCC、持久性靠 redo log 与刷盘策略。死锁的四个必要条件(互斥、占有并等待、不可剥夺、循环等待)与破坏其中任意一条的工程手段(统一加锁顺序、锁超时、一次性申请)要能对应上。同步异步则要讲清阻塞与非阻塞、调用方是否等待结果、以及异步带来的复杂度(回调或协程的上下文管理、错误传播、可观测性)。

手撕「合并两个有序数组」:双指针是标准解,但边界与写法决定印象。经典做法是双指针从前向后遍历,谁小取谁,剩余部分整体拷贝;如果题目给的数组有额外空间(如保证 A 尾部预留了足够容量),从后向前填充能免去整体搬移,这是常见的追问方向。写的时候注意这几点:先确认「能不能用内置排序」的约束,向面试官复述一遍输入输出与是否允许额外空间;空数组、其中一个数组全部小于另一个、相等元素取哪个(是否要求稳定)都要覆盖;用 while 而不是嵌套 for,避免下标越界。写完主动跑两三个用例口述结果,再补一句复杂度:时间 O(m+n)、空间 O(1)(原地尾部填充)或 O(m+n)(新数组)。如果面试官继续追问「有序链表合并怎么做」或「找两个有序数组的中位数」,前者的解法与本场笔试完全同构,后者是这道题的分治升级版,提前想一层就能接得住。