面灵AI→

蚂蚁集团大模型应用面经合集:业务中台与 RAG 知识库

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

《面试题目》

面经 01 · 大模型应用开发(2026-04-15)

  1. 如果让你设计一个面向跨境售后纠纷的智能工单中台,整体架构怎么落?
  2. 单机服务迁移到集群后,订单类接口最先暴露的问题通常是什么?
  3. 防重复下单为什么不能只靠数据库唯一索引?
  4. 幂等 Token 的生成、传递和过期策略应该怎么定?
  5. 为什么很多分布式 ID 方案最后还是会回到雪花算法或它的变体?
  6. 雪花算法在时钟回拨下为什么危险,工程上怎么补?
  7. 订单状态机设计时,为什么「中间态」往往比终态更重要?
  8. 在网络乱序、重复投递、回调延迟同时存在时,怎么保证状态不被错误覆盖?
  9. 评论系统做分库分表时,分片键为什么经常选内容主体 ID 而不是评论 ID?
  10. 爆款内容下评论热点倾斜怎么治理?
  11. 一级评论表和二级回复表拆开设计,和统一单表设计各自的边界在哪里?
  12. 评论计数这类高频字段为什么不建议每次都直写数据库?

面经 02 · 智能体与大模型应用(2026-04-14)

  1. Agent 究竟解决了一个什么问题?为什么我们要选择 Agent 而不是直接用大模型?
  2. 平时会关注哪些 AI 前沿技术?
  3. 自己写过或实际用过 Skill 吗?

面经 03 · 智能体与大模型应用工程(2026-04-14)

  1. 介绍一下你的项目,并接受追问。
  2. 拿一个 AI 做 code review,你认为它最擅长和最不擅长的是哪方面?
  3. 介绍下 ThreadLocal 的工作原理。
  4. ThreadLocal 的内存泄漏,什么场景下会产生内存泄漏?
  5. 解释一下 Redis 中的缓存穿透、缓存击穿、缓存雪崩。
  6. 怎么保证 Redis 缓存和 DB 数据一致?
  7. 解释一下 CAS 的底层原理。
  8. MVCC 是什么?
  9. 英文问答:你通过了英语六级考试了吗?
  10. 英文问答:你平常在学习生活中是怎么练习或者使用英语的?
  11. 英文问答:你怎么用英语向一个新人解释 StringBuilder 和 StringBuffer 的区别?
  12. 英文问答:你怎么用英文介绍你的项目?
  13. 在研究生的时候学过什么课程?
  14. 笔试的 AI coding,你是怎么开始一个大模型编程的?
  15. 有没有学过软件工程,从需求开始到最终交付,中间经历哪些过程?
  16. 自己平时 AI coding 用的多吗?
  17. 讲一下笔试的 AI coding 过程。
  18. 是通过功能对话去优化还是自己手动优化?

面经 04 · AI 应用(2026-04-13)

  1. 请讲一下 RAG 系统整体的技术架构是什么样的?你项目中对应每一块是怎么做的?
  2. 项目背后的知识库是怎么构建的?怎么采集、怎么更新?
  3. 你是在 C 端问答的时候调用网页,而不是在知识采集的时候调用,对吗?
  4. 知识库是项目自己实现的吗?
  5. 怎么选择性增加知识库内容?具体流程是什么?
  6. 时效性强的信息为什么要存进知识库,而不是直接实时检索网页?
  7. 你怎么理解 RAG 静态知识库和动态网页检索之间的关系?
  8. 哪些场景适合用静态知识库,哪些场景只需要动态 Web Search + Web Fetch 就够了?
  9. 你判断哪些知识可以从动态转为静态存入知识库的标准是什么?
  10. 网页实时更新后,静态知识库内容滞后,这部分影响怎么消除?
  11. 如果让你设计情感咨询类的静态知识库,应该采集哪些静态知识?大概怎么采集、怎么更新?
  12. 请设计这套知识库系统的框架。
  13. 检索端应该采用哪些措施做优化,让检索更准确、知识覆盖更广?
  14. 你项目中的图 RAG 是怎么构建的?
  15. 大模型识别实体的原则是什么?
  16. 知识增多后实体可能泛化、不统一,怎么控制实体的内聚性?
  17. 相同含义但表述不同的实体,怎么合并成同一个实体?
  18. 图构建过程中,怎么抽取实体和实体关系?怎么选择上级节点?
  19. 用大模型抽取实体不可控、不准确,怎么解决这个问题?
  20. OpenManus 和你的系统是什么关系?
  21. 你项目中定义的工具有哪些?
  22. OpenManus 整体技术架构分几层?分别是哪几层?
  23. OpenManus 处理 Memory 吗?
  24. 为什么没有用 OpenManus 自身的 Memory 管理,而是用 Spring AI 实现?
  25. Spring AI 是怎么处理历史上下文、记忆记录的?具体机制是什么?
  26. Spring AI 实现的记忆机制和 OpenManus 原生的 Memory、State 管理机制在功能上有什么区别?
  27. OpenManus 提供的 Memory 和 State 管理机制有哪些缺点,导致你放弃使用?
  28. 你了解 OpenManus 的 Memory 管理是怎么处理上下文超限问题的吗?
  29. OpenManus 的 Memory 分几层?怎么做记忆的晋升和提取?
  30. 如果让你自己设计 Memory 晋升机制,会怎么设计?短期记忆到长期记忆的晋升按迭代次数还是按时间?
  31. 长期记忆的遗忘机制是怎么设计的?
  32. 项目是多 Agent 架构吗?
  33. OpenManus 怎么处理不同 Agent、不同任务之间的数据依赖、静态条件、竞争条件?
  34. 单 Agent 为什么要选用 OpenManus 框架?

《参考解析》

面经 01 · 业务中台与高并发设计

1. 单机服务迁到集群后订单接口最先暴露的问题:最典型的是原来依赖单机状态的假设被打破。一是本地锁与进程内缓存失效(synchronized、ConcurrentHashMap 缓存、本地限流计数在多副本下各算各的),需要换成分布式锁或 Redis 计数;二是会话与定时任务重复执行,多台机器同时跑同一个调度把任务做了多遍;三是数据库连接数随副本数线性放大,容易打满 DB 最大连接;四是 ID 生成与时间戳依赖单机时钟,多机时钟不一致会直接产出重复 ID 或乱序;五是日志分散导致排障困难,超时与重试放大了重复请求。所以迁移前要把「有状态的地方」列出来:锁、缓存、会话、调度、ID、限流,逐个改成外部化或幂等设计,而不是先扩容再说。

2. 防重复下单为什么不能只靠唯一索引:唯一索引只能保证「同一行数据不会被插两次」,它管不了三件事:一是重复请求在插入之前就已经产生了副作用,比如先扣了库存、发了消息、调了下游,插入失败时钱或库存已经动了;二是唯一键必须能唯一标识一次业务意图,如果键是「用户 ID + 商品 ID」,用户想合法地再买一单也会被挡掉,如果键是自增主键,那根本起不到幂等作用;三是失败重试可能命中不同的分库分表分片,唯一约束只在单表内生效,分片键选错就跨片失效。更完整的设计是「幂等 Token + 唯一索引 + 状态机」:前置下发 Token,服务端先占位再执行业务,用行内状态区分处理中与已完成,重复请求直接返回首次结果,未完成时明确告知重试,而不是把唯一索引当作全部。

3. 雪花算法与时钟回拨治理:雪花算法把 64 位拆成「1 位符号 + 41 位毫秒时间戳 + 10 位机器 ID + 12 位序列号」,本地生成无网络开销、趋势递增、天然适合做索引友好的主键,所以多数方案最后都会回到它或它的变体(号段 + 雪花混合、Leaf、百度 UidGenerator)。危险点在于它把时间当唯一性来源:NTP 校时或虚拟机暂停会让本机时钟回拨,同一毫秒的序列号可能被重新发放,直接产生重复 ID,而且重复是「静默」的,往往等到主键冲突或数据错乱才发现。工程补法:始终用「上次发号的最大时间戳」而不是当前时钟来推进,回拨幅度小就自旋等待,回拨幅度大就拒绝服务并告警;机器 ID 由 etcd/ZK/配置中心分配并持久化,重启不换号;序列号耗尽自旋到下一毫秒;上线前把 NTP 配置成禁止大步长回调(slew 而非 step)。极端要求下改用号段模式,把唯一性交给数据库的原子自增。

4. 订单状态机的中间态与乱序覆盖:终态只回答「成了还是没成」,中间态才承载业务事实:已支付待发货、退款中、部分退款、待对账,这些状态决定了钱和货的实际位置,也决定了失败时能不能补偿。设计要点:一是状态迁移必须有向图而不是散落的 if-else,非法迁移直接拒绝并记录;二是每次迁移带版本号或自增序列做 CAS(update … where status = 旧状态 and version = n),避免并发覆盖;三是所有外部回调先落库再驱动状态机,回调只做「事件登记」,不在回调里直接改状态,这样乱序、重复、延迟都能靠事件表重放纠正;四是用业务流水做最终裁决,把「最新事件」和「最新合法状态」分开,时间戳只作参考,不能作依据;五是给中间态设置超时兜底,比如支付中超过 N 分钟主动查单并推进或关闭,避免订单卡死在中间态。

5. 评论系统分库分表的分片键与热点治理:分片键选内容主体 ID(文章、视频、商品)而不是评论 ID,原因是绝大多数查询都是「按内容拉评论列表」,以内容 ID 分片能让同一篇内容的所有评论落在同一分片,查询是单分片操作,不需要跨片聚合和二次排序;若按评论 ID 分片,读列表就要广播到所有分片再归并,分页与计数都会退化成全库扫描。代价是热点:爆款内容的评论全压在一个分片上。治理手段是分层——热内容单独路由到独立分片或独立集群(按内容 ID 做热度映射),列表页做多级缓存(本地缓存 + Redis,按「内容 ID + 游标」缓存首页),写侧用消息队列削峰并合并计数更新,读侧限制深分页、只支持游标翻页,再配合降级(只展示热评、折叠早期评论)。此外要预留扩容方案:一致性哈希加虚拟节点,或按内容 ID 取模后再映射到逻辑组,扩容时以内容为单位迁移。

6. 评论表拆分边界与计数优化:一级评论和二级回复拆表的收益是层级清晰、二级表可以按一级评论 ID 分片或单独存储、热点更集中可控;统一单表的好处是查询简单、一次扫描就能拼出完整楼层、不用处理跨表分页。判断边界看三件事:二级回复量级是否远大于一级(差异大就拆)、产品是否需要「只看发布者」「按热度排一级 + 按时间排二级」这类差异化排序(需要就拆)、是否有回复的回复(超过两层,单表反而更容易做递归)。评论计数(点赞、回复数、浏览数)不建议每次直写数据库,因为这类字段写放大严重、还会频繁更新同一行造成锁竞争与 redo 膨胀。常见做法是 Redis 计数 + 定时/阈值触发异步落库,读时以缓存为准并以 DB 做兜底;对账靠定期全量或增量校准任务修正漂移,同时明确「允许短暂不一致」的业务口径。

7. 跨境售后智能工单中台的架构落法:按「接入层、工单域、智能层、集成层」分。接入层对接多渠道来源(邮件、IM、平台站内信、客服系统),统一转成标准工单事件;工单域用状态机管理工单生命周期,分派策略按国家、时区、品类、语言路由到合适队列,SLA 计时与升级规则内置;智能层做意图识别、知识检索与回复草稿生成,检索走 RAG 加政策库(退换货规则、时效、关税),生成结果必须带引用与置信度,低置信度或涉及金额的走人工审核;集成层对接订单、物流、支付、退款等下游系统,所有写操作要幂等且可追溯,异步用消息队列解耦。跨境特有的约束要提前设计:多语言与多时区(SLA 按本地工作时间算)、数据合规与跨境传输(敏感字段脱敏、分区存储)、汇率与税费口径统一、下游系统不可用时的降级(先建工单后补同步,不能丢单)。可观测性上要有按国家/渠道的工单量、首次响应时长、一次解决率、AI 草稿采纳率。

面经 02 / 03 · Agent、Java 基础与工程素养

8. Agent 解决的是什么问题:单次大模型调用是「输入 → 输出」的无状态映射,它无法主动获取新信息、无法执行副作用、无法在长任务中自我纠错,也无法把大问题拆成可验证的小步骤。Agent 补的正是这一层:通过工具调用获得外部行动能力(查数据库、调 API、写文件),通过循环获得多步执行与基于结果的自我修正能力,通过记忆管理获得跨轮次的状态保持,通过规划把模糊目标拆成可执行子任务。所以它不是「更强的大模型」,而是一个把模型放在控制回路里的运行时——模型负责决策,工程负责边界:最大步数、超时、工具权限、失败重试与人工兜底。该不该上 Agent 的判断标准也很清楚:路径可预测、错误代价高的任务用固定 workflow 更稳;需要动态决策、信息不完备、可容忍试错的任务才用自主 Agent。没有边界设计的 Agent 在生产上只会表现为烧 token、原地打转和不可复现的失败。

9. ThreadLocal 的原理与内存泄漏:ThreadLocal 本身不存值,每个 Thread 内部持有 ThreadLocalMap,key 是指向 ThreadLocal 对象的弱引用,value 是强引用。get/set 时以当前线程为入口,用 ThreadLocal 的哈希找 Entry。内存泄漏的成因是 key 被 GC 回收后 Entry 变成 key=null 但 value 仍被线程强引用持有,如果线程长期存活(线程池场景)这块 value 就永远回收不掉。具体高发场景:线程池里用完不 remove、把大对象(连接、缓存、用户上下文)塞进 ThreadLocal、Web 容器里请求结束没清理、异步任务继承上下文后忘了清。规避方式只有一条硬规则:用完必须 remove,放在 finally 里;能用方法参数传的就别用 ThreadLocal;需要跨线程传递时用 InheritableThreadLocal 或阿里 TTL(TransmittableThreadLocal)并同样保证清理。线程池场景最好配合统一的上下文包装器,进入任务时 set、退出时 remove。

10. Redis 缓存穿透、击穿、雪崩与一致性:穿透是查不存在的数据,缓存与 DB 都没有,请求全部压到 DB——解法是缓存空值(短过期)或布隆过滤器前置拦截,同时做参数校验挡住明显非法键。击穿是单个热点 key 过期瞬间大量请求同时回源——解法是逻辑过期(value 里带过期时间,异步刷新,先返回旧值)、单飞(mutex/分布式锁只放一个请求回源)或热点 key 永不过期。雪崩是大量 key 同时过期或 Redis 整体不可用——解法是过期时间加随机抖动、多级缓存(本地 + Redis)、限流降级加熔断,以及缓存集群高可用。一致性上要先明确选择:Cache-Aside 下「先更新 DB 再删除缓存」比「先删缓存再更新 DB」更稳,因为并发读回填脏数据的窗口更小;要强一点就用延迟双删、订阅 binlog 异步失效(Canal),或者对一致性要求高的数据直接读 DB。最终一致是常态,关键是把不一致窗口控制在业务可接受范围内,并做好监控与对账。

面经 04 · RAG 知识库与 Memory

11. RAG 架构与知识库的构建更新:完整链路分三段:离线索引(数据采集 → 清洗去噪 → 分块 → 元数据抽取 → 向量化 → 入向量库,必要时建关键词索引与图谱)、在线检索(查询改写 → 召回 → 融合/重排 → 上下文裁剪 → 生成)、以及反馈闭环(命中率、引用正确率、人工反馈回流到分块与评测集)。知识库构建的关键不是「把文档切了就完事」,而是先定知识模型:哪些是稳定事实(政策、条款、产品说明)、哪些是时效信息(价格、库存、活动)、哪些必须实时查(订单状态、物流)。采集要保留来源、版本、生效时间、地域等元数据,更新走增量而非全量重建——用文档 ID + 内容哈希判断变更,只重建受影响的 chunk,删除时同步清理向量与索引,并保留一次可回滚的版本。工程上还要给检索加过滤条件(地域、语言、生效期),否则跨境场景会召回别国政策。

12. 静态知识库与动态网页检索的取舍:静态知识库的价值是稳定、低成本、可评测、可控延迟:内容相对稳定、复用率高、需要严格口径(政策、合规、话术)的知识适合入库,检索一次几十到几百毫秒,且能保证引用可追溯。动态 Web Search + Fetch 的价值是新鲜与覆盖:一次性、长尾、时效强、无法预知的问题适合现查,代价是延迟高、结果不可控、页面可能抓不到或被改版。判断「动态转静态」的标准可以量化为三条:同一知识在近期被反复问到(频次高)、内容在一定周期内基本不变(半衰期长)、答案需要统一口径与引用(一致性要求高)——满足两条以上就值得入库。滞后的消除不能靠提高刷新频率硬扛,而是分层:入库时记录版本与生效时间,检索时按时间过滤;对时效敏感的问题在回答里显式标注知识与网页的来源和时间;把「可能过期」的知识标记为需二次确认,并让 Agent 在必要时并行做一次动态检索比对,冲突时以更新的来源为准并给出提示。

13. 检索端优化与评测:检索优化分四层。数据层:分块按语义边界(标题层级、段落、表格单独处理),块大小按业务调(问答型 300~800 字常见),带重叠防止切断上下文,给每块补标题与摘要提升向量质量。查询层:查询改写(口语转书面、补全指代、拆多意图)、HyDE、多查询扩展、按元数据预过滤。召回层:向量 + 关键词(BM25)混合召回再用 RRF 融合,避免纯向量漏掉精确术语与编号;加 rerank 模型精排,召回多、精排少。生成层:上下文去重与压缩、强制引用、检索不到就明确说不知道而不是硬答。评测要分开看:召回率与 MRR 衡量检索,引用正确率与 faithfulness 衡量生成,最终用带标准答案的评测集做端到端回归;排查问题时按「数据是否入库 → 分块是否合理 → 召回到没到 → 排序对不对 → 模型是否用上了上下文」逐环节定位,而不是一上来就换模型。

14. 图 RAG 的构建与实体一致性:图 RAG 的构建流程是:分块后让模型做实体与关系抽取(实体类型先定义 schema,比如产品、政策、地域、角色、事件),把实体做归一化(别名、简称、多语言、大小写、单复数)后写入实体表,关系连同来源 chunk 与置信度写入边表,再按业务需要的层级聚成社群/主题节点形成上层结构,检索时用「向量召回实体 → 图上做多跳扩展 → 取回关联 chunk」补足跨文档推理。实体抽取不可控的解法是用 schema 约束输出(枚举类型 + JSON 校验)、给 few-shot 示例、对低置信度结果做二次校验,并把抽取结果落库而不是只在内存里用。控制内聚性的关键是建立实体规范库:统一 ID 与别名表、同义实体靠「规范化名称 + 向量相似 + 上下文类型」三步合并、人工审核高风险合并;知识增长后要定期跑实体去重与冲突检测任务,并给每个实体保留来源与更新时间,发现泛化时优先收窄类型定义而不是继续堆同义词。

15. Agent Memory 的分层、晋升与遗忘:合理的分层是「工作记忆 + 短期会话 + 长期记忆」:工作记忆是当前任务的状态与中间结果(结构化、随任务结束销毁),短期会话是最近若干轮的对话(保留原文或轻摘要),长期记忆是跨会话稳定的用户事实与偏好(结构化存储 + 向量索引)。晋升机制不能只看迭代次数或只看时间,通常是复合触发:信息被重复提及(频次)、被显式确认(用户说「记住」)、对后续任务有复用价值(用模型判一次「是否值得长期保留」),满足条件才写长期;单纯按轮次晋升会把大量噪声写进去,单纯按时间则会把重要信息遗忘。遗忘要分级:硬过期(有时效的事实,如当前项目、临时偏好)、衰减(长期未召回则降低权重并归档)、覆盖(新事实替换旧事实并保留历史版本)。存储上,结构化字段放关系库便于精确过滤,语义内容走向量库;历史记录量很大时要按用户/时间分区、只对近期与命中率高的记忆建索引,召回先做元数据过滤再做向量检索,避免全量扫描。