京东后端开发岗面经:RAG 知识库、写热点优化与 Java 八股
- 轮次
- 多轮面试合集
- 时间
- 2026-09
- 来源
- 牛客网
《面试题目》
面经 01(9 月 23 日)
- 项目部分:RAG 知识库的业务场景是什么?
- 针对高并发写热点问题,你有哪些优化思路?
- 向量库为什么选 Milvus?
- 你了解过 Code Graph 这类开源项目吗?
- 知识库更新后,怎么保证内容及时同步?
- Agent 怎么识别用户意图?
- 项目的核心创新点是什么?
- 简历写了性能提升,具体怎么测出来的?
- 如果线上检索结果不准,怎么定位问题?
- Java 八股:CAS 是什么,有什么问题?
- ABA 问题怎么解决?
- 线程池核心参数怎么设置?
- ThreadLocal 底层原理。
- B+ 树为什么适合做 MySQL 索引?
- 慢 SQL 怎么排查和优化?
- 平时是否会使用 AI 工具辅助开发?你认为目前 AI Coding 最大的问题是什么?
- 缓存击穿怎么解决?
- Kafka 如何保证消息顺序?
面经 02(原帖在此处被截断)
- 问了最有挑战的地方,深入追问了一些东西。
- 使用过哪些 AI 工具?
- Codex 和 Cursor 有什么区别?
- 使用 AI 工具的时候开发流程是怎样的?
- 会自己写开发流程吗?Agent 为什么会按照这个流程去做事情?
- 项目中印象最深的点是什么?
- 订单对账怎么做的?
- 订单 id 什么时候生成?
- 为什么使用……(原帖截断)
《参考解析》
1. RAG 的业务场景与价值。 适合「知识量大、更新频繁、答案需要引用出处」的场景,比如内部制度问答、产品文档检索、客服知识库、代码库问答。判断标准:知识超出模型训练数据、需要权限隔离、答错代价高(要能给出处)、以及更新频率高于模型迭代。不适合的场景:需要复杂推理而不只是检索、数据量很小(直接塞进上下文即可)、或者对延迟极敏感。落地时要把「检索质量」和「生成质量」分开评测:召回率/命中率看检索,答案正确性与引用一致性看生成,否则出了问题不知道该改哪一层。
2. 高并发写热点。 热点写(同一行库存、同一个计数、同一个大 V 的订单)会让行锁排队、CPU 飙高。优化手段分四层:① 拆分——把一行拆成 N 个分片(如库存分桶),写请求按 hash 打到不同分片,读时求和;② 异步——写请求进 MQ 串行/批量落库,前端返回受理;③ 合并——把短时间内的多次写合并成一次(计数用 Redis INCR 再定时回写);④ 削峰——令牌桶限流 + 队列缓冲。业务上还要做幂等和防重(唯一键、去重表),否则重试会把热点放大。选方案要看「能不能接受最终一致」和「读是否要求强一致」。
3. Milvus 选型与知识库同步。 选 Milvus 的理由通常是:开源可自建、支持 IVF/HNSW/DiskANN 多种索引、能水平扩展、支持标量过滤与混合查询、生态成熟。对比 Faiss(库,不是服务,缺持久化和分布式)、pgvector(简单但大规模性能有限)、Elasticsearch(向量能力较新、资源占用高)。同步方案:文档变更走 CDC(监听数据库 binlog 或对象存储事件)→ 解析切分 → 生成 embedding → 按文档 id 先删后插(或 upsert)→ 更新索引;要保证「删除也同步」,否则旧内容会一直命中。增量更新用版本号 + 软删标记,全量重建走离线任务并双写切换。
4. 检索不准怎么定位。 分三层查:① 数据层——原文是否正确解析(PDF 表格、扫描件)、切分是否把答案切断、embedding 是否生成成功;② 检索层——用原文里的关键词直接搜能否命中(判断是索引问题还是语义问题)、换不同 query 看召回是否稳定、检查过滤条件是否把正确结果排除了;③ 排序层——看 rerank 前后的排名变化,是否被相似但无关的块挤掉。定位手段是「构造已知答案的评测集」:每条 query 标注应命中的文档块,算 Recall@K 和 MRR,逐条看 bad case 落在哪一层,而不是凭感觉调参。
5. 性能提升怎么测。 要有基线、有对照、有统计口径:压测工具(JMeter/wrk)固定并发和数据集,记录 P50/P95/P99、QPS、错误率、CPU/内存/GC;对比优化前后的同一接口、同一数据量、同一机器规格;排除干扰(缓存预热、JIT 预热、其他服务占用)。如果声称「提升 30%」,要能说明是延迟还是吞吐、在哪个分位、样本量多少、是否可复现。线上则用灰度 + APM 对比真实流量,别只拿本地跑分。
6. Java 八股。 CAS 是「比较并交换」,靠 CPU 的 cmpxchg 指令保证原子性,优点是无需阻塞,问题是 ABA、自旋开销、只能保证单变量;ABA 用版本号(AtomicStampedReference)解决。线程池参数按任务类型定:CPU 密集约 核数 + 1,IO 密集按 核数 × (1 + 等待/计算),队列必须有界,拒绝策略按业务选(抛异常/调用方执行/落库补偿)。ThreadLocal 的原理是每个 Thread 持有 ThreadLocalMap,key 是 ThreadLocal 的弱引用,value 是强引用;key 被回收后 value 还在,所以线程池里必须 remove(),否则内存泄漏且会串数据。B+ 树适合做索引是因为:多叉树降低树高(磁盘 IO 次数少)、非叶子节点只存键(一页能放更多索引项)、叶子节点用链表连接(范围查询和排序友好)、以及数据都在叶子层(查询稳定)。
7. 缓存击穿与 Kafka 顺序。 击穿是热点 key 过期瞬间大量请求打到 DB:解法是互斥锁(只让一个请求回源,其余等待)、逻辑过期(不设 TTL,异步刷新)、或热点永不过期 + 后台更新。穿透是查不存在的数据,用空值缓存或布隆过滤器;雪崩是大量 key 同时过期,用随机 TTL + 多级缓存 + 限流。Kafka 顺序保证:同一 key 进同一 partition(默认按 key hash),消费端单分区单线程或按 key 分发到固定 worker;跨分区不保证顺序,需要全局有序就只能单分区(牺牲吞吐)。重试也会打乱顺序,所以要么关闭重试、要么用幂等 + 版本号在消费端纠正。
8. 订单与对账。 订单号在下单请求进入时生成(而不是支付时),因为要作为幂等键和后续所有链路的关联 id;生成方式常见是「雪花算法(时间 + 机器 + 序列)」或「业务前缀 + 日期 + 分片 + 序列」,要保证全局唯一、趋势递增、不暴露业务量。对账是 T+1 把本地订单流水与支付渠道账单逐笔比对:金额、状态、手续费,差异分为「本地有渠道无」「渠道有本地无」「金额不一致」「状态不一致」,分别走补单、退款、人工核查。实现上按渠道下载账单文件 → 解析入库 → 与订单表 full outer join → 生成差异表 → 告警/自动处理,关键是幂等和可重跑。
9. AI Coding 的问题与流程。 当前最大的问题不是「写不出代码」,而是「上下文不足 + 验证不足」:模型不知道项目约定、改了 A 处漏了 B 处、生成的东西看起来对但边界没覆盖。可靠的流程是:先让它读相关文件和规范 → 出方案(改哪些文件、为什么)→ 人确认 → 小步修改 → 跑测试/类型检查/lint → 失败把错误回灌 → 最后人 review 关键逻辑。Codex 偏「在终端里执行任务、能跑命令和改多文件」,Cursor 偏「IDE 内的补全与对话」,前者适合批量改造,后者适合边写边问;选择取决于任务粒度和是否需要执行反馈。