蚂蚁集团大模型应用面经合集:业务中台与 RAG 知识库
- 轮次
- 多轮面试合集
- 时间
- 2026-09
- 来源
- 牛客网
《面试题目》
面经 01 · 大模型应用开发(2026-04-15)
- 如果让你设计一个面向跨境售后纠纷的智能工单中台,整体架构怎么落?
- 单机服务迁移到集群后,订单类接口最先暴露的问题通常是什么?
- 防重复下单为什么不能只靠数据库唯一索引?
- 幂等 Token 的生成、传递和过期策略应该怎么定?
- 为什么很多分布式 ID 方案最后还是会回到雪花算法或它的变体?
- 雪花算法在时钟回拨下为什么危险,工程上怎么补?
- 订单状态机设计时,为什么「中间态」往往比终态更重要?
- 在网络乱序、重复投递、回调延迟同时存在时,怎么保证状态不被错误覆盖?
- 评论系统做分库分表时,分片键为什么经常选内容主体 ID 而不是评论 ID?
- 爆款内容下评论热点倾斜怎么治理?
- 一级评论表和二级回复表拆开设计,和统一单表设计各自的边界在哪里?
- 评论计数这类高频字段为什么不建议每次都直写数据库?
面经 02 · 智能体与大模型应用(2026-04-14)
- Agent 究竟解决了一个什么问题?为什么我们要选择 Agent 而不是直接用大模型?
- 平时会关注哪些 AI 前沿技术?
- 自己写过或实际用过 Skill 吗?
面经 03 · 智能体与大模型应用工程(2026-04-14)
- 介绍一下你的项目,并接受追问。
- 拿一个 AI 做 code review,你认为它最擅长和最不擅长的是哪方面?
- 介绍下 ThreadLocal 的工作原理。
- ThreadLocal 的内存泄漏,什么场景下会产生内存泄漏?
- 解释一下 Redis 中的缓存穿透、缓存击穿、缓存雪崩。
- 怎么保证 Redis 缓存和 DB 数据一致?
- 解释一下 CAS 的底层原理。
- MVCC 是什么?
- 英文问答:你通过了英语六级考试了吗?
- 英文问答:你平常在学习生活中是怎么练习或者使用英语的?
- 英文问答:你怎么用英语向一个新人解释 StringBuilder 和 StringBuffer 的区别?
- 英文问答:你怎么用英文介绍你的项目?
- 在研究生的时候学过什么课程?
- 笔试的 AI coding,你是怎么开始一个大模型编程的?
- 有没有学过软件工程,从需求开始到最终交付,中间经历哪些过程?
- 自己平时 AI coding 用的多吗?
- 讲一下笔试的 AI coding 过程。
- 是通过功能对话去优化还是自己手动优化?
面经 04 · AI 应用(2026-04-13)
- 请讲一下 RAG 系统整体的技术架构是什么样的?你项目中对应每一块是怎么做的?
- 项目背后的知识库是怎么构建的?怎么采集、怎么更新?
- 你是在 C 端问答的时候调用网页,而不是在知识采集的时候调用,对吗?
- 知识库是项目自己实现的吗?
- 怎么选择性增加知识库内容?具体流程是什么?
- 时效性强的信息为什么要存进知识库,而不是直接实时检索网页?
- 你怎么理解 RAG 静态知识库和动态网页检索之间的关系?
- 哪些场景适合用静态知识库,哪些场景只需要动态 Web Search + Web Fetch 就够了?
- 你判断哪些知识可以从动态转为静态存入知识库的标准是什么?
- 网页实时更新后,静态知识库内容滞后,这部分影响怎么消除?
- 如果让你设计情感咨询类的静态知识库,应该采集哪些静态知识?大概怎么采集、怎么更新?
- 请设计这套知识库系统的框架。
- 检索端应该采用哪些措施做优化,让检索更准确、知识覆盖更广?
- 你项目中的图 RAG 是怎么构建的?
- 大模型识别实体的原则是什么?
- 知识增多后实体可能泛化、不统一,怎么控制实体的内聚性?
- 相同含义但表述不同的实体,怎么合并成同一个实体?
- 图构建过程中,怎么抽取实体和实体关系?怎么选择上级节点?
- 用大模型抽取实体不可控、不准确,怎么解决这个问题?
- OpenManus 和你的系统是什么关系?
- 你项目中定义的工具有哪些?
- OpenManus 整体技术架构分几层?分别是哪几层?
- OpenManus 处理 Memory 吗?
- 为什么没有用 OpenManus 自身的 Memory 管理,而是用 Spring AI 实现?
- Spring AI 是怎么处理历史上下文、记忆记录的?具体机制是什么?
- Spring AI 实现的记忆机制和 OpenManus 原生的 Memory、State 管理机制在功能上有什么区别?
- OpenManus 提供的 Memory 和 State 管理机制有哪些缺点,导致你放弃使用?
- 你了解 OpenManus 的 Memory 管理是怎么处理上下文超限问题的吗?
- OpenManus 的 Memory 分几层?怎么做记忆的晋升和提取?
- 如果让你自己设计 Memory 晋升机制,会怎么设计?短期记忆到长期记忆的晋升按迭代次数还是按时间?
- 长期记忆的遗忘机制是怎么设计的?
- 项目是多 Agent 架构吗?
- OpenManus 怎么处理不同 Agent、不同任务之间的数据依赖、静态条件、竞争条件?
- 单 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 的分层、晋升与遗忘:合理的分层是「工作记忆 + 短期会话 + 长期记忆」:工作记忆是当前任务的状态与中间结果(结构化、随任务结束销毁),短期会话是最近若干轮的对话(保留原文或轻摘要),长期记忆是跨会话稳定的用户事实与偏好(结构化存储 + 向量索引)。晋升机制不能只看迭代次数或只看时间,通常是复合触发:信息被重复提及(频次)、被显式确认(用户说「记住」)、对后续任务有复用价值(用模型判一次「是否值得长期保留」),满足条件才写长期;单纯按轮次晋升会把大量噪声写进去,单纯按时间则会把重要信息遗忘。遗忘要分级:硬过期(有时效的事实,如当前项目、临时偏好)、衰减(长期未召回则降低权重并归档)、覆盖(新事实替换旧事实并保留历史版本)。存储上,结构化字段放关系库便于精确过滤,语义内容走向量库;历史记录量很大时要按用户/时间分区、只对近期与命中率高的记忆建索引,召回先做元数据过滤再做向量检索,避免全量扫描。