水滴 AI 全栈工程师一面:Go 调度、SSE 流式与 Kafka 异步链路
- 轮次
- 一面
- 时间
- 2026-10
- 来源
- 牛客网
《面试题目》
- 自我介绍,并选择最近的一段项目经历,介绍其中的关键技术点、技术难点以及最能体现个人能力的部分。
- 你现在是否还在上一家公司实习?为什么离职?
- 你的硕士研究方向是什么?研究方向和求职方向是否一致?
- 你之前做过前端开发,目前是前端能力更突出,还是全栈能力更突出?
- 你目前主要使用哪些开发语言?Go、Java、JavaScript 分别掌握到什么程度?
- 介绍一下进程和线程的区别。
- 为什么进程切换的开销通常比线程切换大?
- Go 中的协程和操作系统线程有什么区别?
- 介绍一下 Goroutine。
- 介绍一下 Go 的 GMP 调度模型。
- Go 调度器中的 Work Stealing 是怎么实现的?
- 并发和并行是一回事吗?二者有什么区别?
- 你项目中的批量数据导入为什么要由同步处理改成异步处理?
- 这个数据导入场景属于高并发场景吗?
- 数据导入链路中,真正耗时的节点在哪里?你是如何定位和验证的?
- 上传的数据是什么格式?单个文件的数据量大概有多大?
- 从文件上传、算法处理到最终数据落库,完整链路是怎样的?
- 异步任务执行过程中,如果某个节点发生故障、服务宕机或者文件丢失,应该怎么处理?
- 原始文件和任务中间状态存储在哪里?
- Kafka 消息中存放的是原始数据,还是任务 ID?
- 如何保证异步任务的数据一致性?
- 如果任务执行失败,如何进行重试、恢复和补偿?
- 这个数据处理链路属于 CPU 密集型还是 I/O 密集型?为什么?
- 你在 RAG/Agent 工作流平台中使用的是 SSE 还是 WebSocket?为什么?
- SSE 和 WebSocket 有什么区别?
- 当前场景能否使用 WebSocket 实现?为什么最终选择 SSE?
- 用户在接收 SSE 流式响应时刷新页面,会发生什么?
- SSE 连接中断以后,后端任务是否还会继续执行?
- 如何实现 SSE 的断线重连、消息续传和消息去重?
- Redis Stream 在流式对话场景中起什么作用?
- Agent 对话的短期记忆和长期记忆分别如何保存?
- 为什么短期记忆使用 Redis,长期记忆使用 MongoDB?
- 介绍一下 MySQL 的聚簇索引和非聚簇索引。
- 什么是回表查询?
- 什么是覆盖索引?覆盖索引为什么能够减少回表?
- MySQL 为什么使用 B+ 树作为索引结构?
- B+ 树相比二叉树、B 树等结构有什么优势?
- B+ 树为什么适合范围查询?
- 介绍一下数据库事务的 ACID,原子性、一致性、隔离性和持久性分别是什么意思?
- Kafka 在什么情况下会出现消息重复投递?
- 生产者没有收到 ACK 时会发生什么?
- 消费者宕机或者 Offset 提交失败时,为什么可能导致重复消费?
- 如何保证 Kafka 消费端的幂等性?
- 如何使用唯一业务 ID、状态表或数据库唯一约束实现消息去重?
- 你的项目中使用 Kafka,主要是为了解决高并发,还是作为异步任务触发器?
- Kafka 除了异步解耦,还适合哪些业务场景?
- Kafka 为什么具有较高的吞吐量?
- Kafka 的顺序写磁盘、分区和消费者组分别起什么作用?
- Kafka 和 RabbitMQ 有什么区别?分别适合什么场景?
- Kafka 是如何实现削峰填谷的?如何先承接瞬时大流量,再让消费者按照较低速度慢慢处理?
- 消费者的消费速度应该如何控制?
- Kafka Consumer Group 是如何工作的?
- 什么情况下会触发 Kafka Rebalance?
- Rebalance 可能带来哪些问题?
- Redis 缓存穿透、缓存击穿和缓存雪崩分别是什么?
- 如何解决缓存穿透?
- 如何解决缓存击穿?
- 如何解决缓存雪崩?
- 布隆过滤器的原理是什么?
- 布隆过滤器能否百分之百判断一个元素存在?
- 为什么布隆过滤器判断「不存在」时一定不存在,而判断「存在」时却不一定真的存在?
- 介绍一下你参与的 RAG/Agent 工作流平台。
- 这个项目的团队规模有多大?人员是如何分工的?
- 你在这个项目中具体负责哪些模块?
- 项目中的前端和后端功能有哪些是你亲自实现的?
- 你平时使用哪些 AI 编程工具?
- Codex、Claude Code 和 Cursor 分别使用过哪些?
- 目前主要使用哪个 AI 编程工具?为什么选择它?
- 平时除了写代码,还会使用哪些 AI 产品?
- 豆包、Codex 和企业内部 RAG 工作流平台,在产品形态上有什么本质区别?
- 通用聊天机器人和 AI Agent 有什么区别?
- 为什么说 Codex 不只是一个聊天机器人,而是一个可以执行任务的 Agent?
- Agent 中的工具调用能力是如何实现的?
- 什么是 Function Calling?
- 什么是 MCP?
- MCP Host、MCP Client 和 MCP Server 分别是什么?
- 你项目中的 MCP Server 是自己开发的吗?
- MCP Server 中注册了哪些工具?
- MCP 在你的项目中具体用来查询或处理什么业务数据?
- 如何通过 MCP 查询业务订单、任务进度以及任务成功或失败状态?
- Function Calling 和 MCP 有什么区别和联系?
- 模型生成 Function Call 后,系统如何调用本地工具或 MCP 工具?
- Agent Loop 的基本执行流程是什么?
- ReAct、Plan-and-Execute 等 Agent 模式了解吗?
- 最近关注了哪些新的 AI、RAG 或 Agent 技术?
- 介绍一下知识图谱式检索或 GraphRAG 的基本思路。
- 普通 RAG 和图结构检索有什么区别?
- 知识图谱式检索能否完全替代传统 RAG?
- 什么场景更适合传统向量 RAG?
- 什么场景更适合图结构检索?
- 如果涉及跨文档、跨实体、多跳关系查询,普通向量检索可能存在哪些问题?
- 图结构检索在构建成本和增量更新方面有什么缺点?
- 如果企业知识库中的规则长期稳定,应该选择传统 RAG、图结构检索,还是两者结合?
- 多步骤 Agent 为什么会出现准确率逐层下降的问题?
- 如何减少 Agent 的决策步骤,提高复杂任务的成功率?
- 你有什么问题想了解公司的?
《参考解析》
Go 的 GMP 与 Work Stealing:G 是 goroutine,M 是内核线程,P 是持有本地队列的调度上下文,数量等于 GOMAXPROCS。M 绑定 P 才能执行 G,并发度与线程数解耦,G 在用户态切换、栈很小,开销远低于线程。P 的本地队列空时先取全局队列,再随机偷另一个 P 一半的 G,CAS 保证只有一个窃取者;M 阻塞在系统调用时会把 P 交出。
SSE 断线重连与消息续传:SSE 是服务端到客户端的单向 HTTP 流,实现比 WebSocket 简单,而这里只需推 token。连接断开不影响任务:任务作为独立协程运行,产出按会话写入 Redis Stream 并分配递增序号;重连时带 Last-Event-ID,服务端从该位置重放,客户端按序号去重。
缓存穿透、击穿、雪崩:穿透是查不存在的 key,用布隆过滤器或空值缓存挡在库前;它用多个哈希映射比特数组,判「不存在」一定准、判「存在」有误判。击穿是热点 key 失效瞬间流量回源,用互斥锁只放一个请求回源,或逻辑过期先返回旧值、后台刷新。雪崩是大批 key 同时过期,过期时间加随机抖动并限流降级。
Kafka 重复消费与幂等:默认语义是至少一次,重复来自三处:生产者没收到 ACK 而重试、消费者处理完但 Offset 提交失败或提交前宕机、Rebalance 后分区重放。解法是消费端幂等:用业务唯一 ID 建去重表加唯一索引,让数据库约束挡掉并发重复。生产者开 enable.idempotence=true 配 acks=all 消除重试重复。
Function Calling、MCP 与 Agent Loop:Function Calling 是模型侧能力,给模型工具名、描述和参数 Schema,模型输出结构化调用意图,宿主执行后回填结果。MCP 是协议层,规定工具与资源如何被发现和调用:Host 发起,Client 维护与 Server 的会话,Server 暴露能力;MCP 工具最终也通过一次工具调用被选中。Agent Loop 是「推理、调工具、回填观察、再推理」的循环,直到给出答案或触达步数上限;ReAct 边想边做,Plan-and-Execute 先规划再执行。