面灵AI→

美团后端开发岗面经合集:从 Skill 路由到支付幂等与分布式锁

轮次
多轮面试合集
时间
2026-09
来源
牛客网

《面试题目》

面经 01(9 月 23 日)

  1. 手撕:合并有序数组。
  2. SQL:查到某门课的平均值,按平均值和课程号排序。
  3. 设计模式有哪些,用过哪些?
  4. HashMap 为什么线程不安全,怎么安全?
  5. 头插法尾插法有什么区别?
  6. Java 里有哪些容器?
  7. 聊项目,难点,怎么解决?
  8. 聊实习,难点,怎么解决?

面经 02(9 月 14 日)

  1. 上一段实习项目是独立开发还是团队合作?你具体负责哪些部分?
  2. 原有固定 Workflow 是怎样工作的?
  3. Skill 相比 Workflow 有什么优势,具体如何降低维护成本?
  4. 系统有多个 Skill 时,怎样把用户问题路由到正确的 Skill?
  5. 同一产品存在多个 Skill 时,如何处理路由冲突?
  6. 随着 Skill 增多,如何持续提升路由准确率?
  7. Skill 增多导致模型上下文膨胀时怎么办?
  8. Skill 开发过程中遇到的主要挑战是什么?
  9. 与确定性代码相比,自然语言 Skill 应该怎样测试和调试?
  10. 是否会回放历史问题或注入已知故障,验证端到端效果?
  11. 这套 Skill 使用什么大模型、Harness 和执行框架?
  12. 是否了解 PI Agent 或 DeepSeek Harness?
  13. Agent Loop 在哪些条件下终止?
  14. 你现在还亲自写代码吗?最近一次手写代码是什么时候?
  15. 怎么看待程序员只使用 AI、不手写代码?
  16. AI 生成速度超过人工 Review 速度时怎么办?
  17. 长期来看,程序员更应培养代码审美,还是加强对 Agent 的操控?
  18. 在实习工作中,你的传统编程能力或代码审美有哪些具体提升?请举例。
  19. 请介绍一下云服务器产品及其核心能力。
  20. 裸金属服务器是否提供虚拟化,还是直接以物理机形式交付?
  21. 云服务器如何实现 Region 级或 AZ 级容灾?
  22. 给定一个数组和整数 K,统计和为 K 的连续子数组数量。
  23. AI 快速发展会怎样影响后端程序员的岗位和职业生涯?
  24. 当安全、架构等经验逐渐被 AI 内化后,资深工程师的经验是否仍有价值?

面经 03(9 月 14 日)

  1. 实习中做了什么?如何推进开发、保证开发正确,并借助 AI 辅助开发?
  2. 数据库事务的默认隔离级别是什么?
  3. 如何解决幻读?
  4. volatile 和 synchronized 分别解决什么问题?
  5. synchronized 可以修饰什么?如何保证原子性?
  6. 商城项目从订单支付到库存扣减的完整流程是什么?
  7. 支付的具体流程是怎样的?
  8. 如何保证支付回调不会重复扣减库存?
  9. Redis 在项目中用于哪些场景?
  10. Spring 事务的原理是什么?
  11. @Transactional 注解在哪些情况下会失效?
  12. 如何解决 @Transactional 自调用导致的失效?
  13. 平时使用什么 AI 工具?如何使用?
  14. 对比 Qoder 和 Claude Code 的使用体验。
  15. 手撕:最小覆盖子串。

面经 04(9 月 10 日)

  1. 讲一下项目。
  2. Lua 脚本作用?
  3. Caffeine + Redis 两级缓存怎么做的?怎么减少回源?
  4. 怎么保证数据一致性?如果没缓存只有数据库怎么办?
  5. Kafka 用用户 ID 做 key 会遇到什么问题?怎么扩容?
  6. Zset 怎么用过吗?原理?为什么用跳表?
  7. 慢 SQL 怎么优化?
  8. binlog 有什么模式,分别写的什么?主从复制会出现哪些问题?
  9. Redisson 分布式锁怎么续期?怎么避免死锁?
  10. 设计周报发送。
  11. 讲下怎么设计的。

面经 05(9 月 2 日)

  1. 询问实习有留用吗?
  2. 实习做了些什么,PHP 接口迁 Java 怎么做的,怎么确保迁移成功?
  3. Agent 项目是什么,你做了些什么?
  4. 数据库用的是什么,怎么用的?
  5. RAG 怎么做的?
  6. 工具注册的单例怎么做的?
  7. 为什么用单例,单例有什么好处,不用单例有什么问题?
  8. MySQL 用过吗,讲一下慢查询怎么办。
  9. 什么情况 MySQL 优化会不走索引变成全表扫描?
  10. 索引什么情况会失效?
  11. 商城项目的支付是怎么做的?
  12. 如果一个订单支付两次你怎么处理?
  13. 你具体是怎么做上一个问题的幂等性处理的?
  14. 手撕第 k 大的数,限制时间复杂度。

面经 06(原帖在此处被截断)

  1. 我看你第一志愿填了 AI 全栈,为什么选择后端方向?这些项目有上线的吗?
  2. 简单介绍一下这个项目的业务?为什么选择用 RabbitMQ?项目里的幂等怎么实现的?如果队列消费出重复的任务是怎么处理的?(原帖截断)

《参考解析》

1. HashMap 与容器。 HashMap 线程不安全有两个层面:并发 put 可能覆盖彼此的写入(读-改-写不是原子操作),JDK 1.7 的头插法在扩容时还可能形成环形链表导致 get 死循环;1.8 改成尾插避免了环,但仍会丢更新、size 计数不准。线程安全用 ConcurrentHashMap(分段/CAS + synchronized 桶头,读不加锁),或者外部加锁,不要用 Collections.synchronizedMap 做高并发。头插/尾插的区别在扩容迁移时:头插把旧链表逆序搬到新桶,实现简单但并发下容易出现环;尾插保持原顺序,1.8 还引入红黑树(链表长度 ≥8 且容量 ≥64 时树化)把最坏查找从 O(n) 降到 O(log n)。Java 容器分 List/Set/Map/Queue 四条线,常用实现和选型见「ArrayList vs LinkedList」「HashSet/LinkedHashSet/TreeSet」「HashMap/LinkedHashMap/TreeMap」「ArrayDeque/PriorityQueue」。

2. Skill 与 Workflow 的取舍、路由与测试。 Workflow 把步骤写死在代码里,稳定但每次需求变化都要改代码、发版;Skill 把「这类任务怎么做」写成可加载的自然语言流程加脚本,模型按需读取,新增场景只要加一个 Skill 文件,维护成本低、上下文占用也可控(只加载命中的那个)。代价是行为不完全确定,需要更强的评测。多 Skill 路由的做法:先给每个 Skill 写清「适用场景 / 不适用场景 / 关键词」的元数据,路由用「规则 + 语义相似度 + 模型判断」三层,冲突时用优先级或让模型在候选里选并给出理由;Skill 变多后路由准确率靠混淆矩阵找易混对、补充反例描述、拆分过粗的 Skill 来提升。上下文膨胀的解法是「索引化」:主提示词只放 Skill 目录(名称 + 一句话),命中后再加载正文,正文里再按步骤懒加载参考资料。测试上,确定性代码用单测,Skill 用「断言行为而非字句」的评测:准备历史问题集、注入已知故障、检查是否走到正确工具、是否满足约束、结果是否可用;再配人工抽检和线上埋点。

3. Agent Loop 的终止条件。 至少四类:任务完成(模型输出最终答案且校验通过)、预算耗尽(最大步数、最大 token、wall-clock 超时)、不可恢复错误(工具连续失败、权限拒绝、参数非法且无法补全)、需要人工介入(副作用操作待确认、信息缺失需用户补充)。工程上还要加「无进展检测」:连续几步调用相同工具、参数相同、结果相同,就判定空转并终止;以及「重复输出检测」防止模型原地打转。终止时必须把已完成的部分、失败原因、建议下一步写进结果,不能静默返回空。

4. 云服务器、裸金属与容灾。 云服务器是把物理资源虚拟化后按需交付的实例,核心能力是弹性伸缩、镜像与快照、按量/包年计费、VPC 网络与安全组、以及挂载云盘。裸金属不提供虚拟化,直接交付物理机(部分产品支持带外管理),适合高性能计算、数据库、以及需要独占硬件或特殊授权的场景。容灾分层:单机用多副本云盘 + 快照;AZ 级把实例分布在同一地域的多个可用区,靠负载均衡和跨 AZ 复制;Region 级做异地多活或冷备,靠数据异步复制 + DNS/全局流量调度切换,RPO/RTO 取决于复制方式。要讲清「备份不等于容灾」——备份解决误删,容灾解决机房级故障。

5. 支付到库存的幂等链路。 下单时生成全局唯一的订单号并落库(状态待支付),支付回调携带订单号 + 支付流水号;服务端先按流水号做唯一索引/Redis SETNX 去重,再用「条件更新」把订单从待支付改为已支付(update ... where order_id=? and status='PENDING',影响行数为 1 才继续),成功后发扣库存消息。扣库存同样幂等:库存表按 (sku_id, order_id) 建唯一约束,或用「扣减流水表 + 唯一键」,重复消息直接被数据库拒绝。整条链路是「本地事务 + 可靠消息 + 消费端幂等」,任何一步失败都能重试而不会重复扣减。@Transactional 失效的常见原因:自调用(不走代理)、方法非 public、异常被 catch 没抛出、抛的是检查异常而默认只回滚 RuntimeException、类没被 Spring 管理、以及多数据源/多线程里事务不传播。自调用失效的解法是注入自身代理、AopContext.currentProxy() 或拆到另一个 Bean。

6. 两级缓存与一致性。 Caffeine 本地缓存挡热点、Redis 分布式缓存挡回源,读顺序是「本地 → Redis → DB」,回源后依次回填。减少回源靠:热点探测与预热、空值缓存防穿透、随机过期时间防雪崩、逻辑过期 + 异步刷新避免击穿。一致性用「先更新 DB,再删缓存」(Cache Aside),删除失败靠重试/消息补偿;强一致要求高时用延迟双删或订阅 binlog(Canal)异步失效。只有数据库时,一致性靠事务和唯一约束保证,缓存只是加速层,任何缓存缺失都必须能回源。Kafka 用用户 ID 做 key 能保证同一用户有序,但会造成分区倾斜(大 V 用户打爆一个分区);扩容时新增分区会改变 key 到分区的映射,顺序保证被破坏,所以要么提前规划分区数、要么用「业务键 + 版本号」在消费端做幂等与重排。

7. ZSet、慢 SQL 与 binlog。 ZSet 用哈希表(member → score)+ 跳表(按 score 有序),跳表通过多级索引把查找/插入做到期望 O(log n),比红黑树实现简单、范围查询更自然,代价是空间常数更大。慢 SQL 优化顺序:先定位(慢查询日志、EXPLAIN 看 type/key/rows/Extra),再看索引(是否缺索引、是否失效、能否覆盖),然后改 SQL(避免 select *、拆大 join、分页优化),最后才是架构(读写分离、分库分表、归档)。binlog 三种模式:STATEMENT 记录 SQL 语句(日志小,但函数/时间等不确定语句会导致主从不一致)、ROW 记录每行变更(最安全,日志大)、MIXED 由系统选择。主从复制的常见问题:延迟(大事务、单线程回放)、中断(网络/权限)、数据不一致(非 ROW 模式)、以及主库宕机时未同步的 binlog 丢失。

8. Redisson 续期与死锁。 Redisson 加锁成功后启动看门狗,默认每 10 秒把锁的过期时间续到 30 秒,只要客户端活着锁就不会因业务超时释放;只有不显式指定 leaseTime 时才启用看门狗。避免死锁:锁必须带过期时间、加锁用 tryLock 带等待超时、解锁放在 finally、解锁前校验持有者(Lua 原子删除);业务侧还要防「锁住后调用外部服务卡死」,给外部调用设超时。Redisson 的看门狗依赖 JVM 存活,进程被 kill -9 或长时间 GC 仍可能丢锁,所以最终一致性要靠数据库条件更新兜底。

9. 周报发送的设计。 先拆需求:谁收、什么时间发、内容从哪来、失败怎么办。方案:定时任务(XXL-Job/ cron)在周五 18:00 触发,按部门分片拉取数据(本周工时、需求完成、线上问题),用模板渲染成邮件/IM 卡片,投递到消息队列后由消费者发送,发送结果落表(成功/失败/重试次数),失败的进重试队列并告警。关键点:幂等(同一周同一人只发一次,用唯一键)、限流(避免一次打爆邮件服务)、可重试、以及内容为空时的降级(发「本周无更新」或跳过)。规模大时按用户分片并行,任务状态可查询、可手动补发。

10. 算法题。 和为 K 的连续子数组:前缀和 + 哈希表,遍历时把 prefix - K 的出现次数累加,O(n)。最小覆盖子串:滑动窗口 + 计数表,右扩直到覆盖所有字符,再左缩更新最优,O(n)。第 K 大:快速选择(partition 后只递归一侧)平均 O(n),或小顶堆 O(n log k);面试要能说出最坏 O(n²) 以及随机化 pivot 的改进。