京东 算法工程师 笔试+一面 商品问答 RAG 深挖
- 轮次
- 笔试+一面
- 结果
- 已通过(转组后)
- 时间
- 2026-09
- 来源
- 牛客网
《面试题目》
- 笔试(90 分钟):订单金额按城市汇总,边界怎么处理?
- AICoding 笔试:题干给了一堆需求,你第一步做什么?
- 一面(40 分钟):讲一下你做的商品问答 RAG,整体链路怎么搭?
- 召回不准怎么办?
- 商品知识频繁更新,索引和缓存怎么保持一致?
- 召回率怎么提升?
- 向量库选型为什么用 HNSW?它在在线更新上的代价是什么?
- 反问环节问了什么?
《参考解析》
汇总类笔试题的边界比算法本身值钱:按城市汇总金额用哈希聚合就是 O(n),真正扣分的是边界:城市字段为空/串号(要不要归到「未知」桶)、退款导致的负金额(不能简单丢,也不能直接混进 GMV)、金额精度(用「分」存整数或 Decimal,别用 float)、城市名不归一(「北京市」和「北京」会被拆成两个桶)、数据量大到内存放不下(流式读 + 分批聚合)。先画处理流程再写代码,把这几条写进注释,比直接堆代码稳。
AICoding 题第一步是拆解,不是生成:先把题干拆成对象(实体和字段)、流程(先做什么后做什么)、接口(输入输出与约束)三块,写清最小可运行骨架,再补边界和异常分支。直接让模型整段生成,一旦需求有隐含约束就会整体跑偏,返工比手写还慢。
RAG 召回不准的常规解法:单路向量召回必然漏,工程上是三件事叠加。一是双路召回,关键词/BM25 管精确词(型号、规格、错误码),向量管语义泛化,两路结果融合。二是加重排,用 cross-encoder 类重排模型对粗排的 top-50100 精排,取 top-35 进 prompt,顺序必须是「召回→重排→生成」。三是切块策略,长文档拆父子块,用小子块(200~400 token)做检索、返回父块(或兄弟块)给模型,命中和上下文完整性都保住。
知识增量更新要管住索引和缓存两头:索引侧走增量 upsert 而不是全量重建,每条文档带 doc_id + 版本号 + 生效时间,删除用软删或 tombstone,后台定期合并重建图结构。缓存侧按 doc_id 精确失效,别用全量 flush,同时给旧版本设 TTL 过期,防止旧文档在 reindex 完成前被错误召回。热点商品单独做一层短 TTL 缓存,命中直接返回。
召回率怎么提升:查询侧做改写和扩展(同义词词典、把口语问法改写成商品术语、HyDE 先生成假设答案再检索);数据侧做负样本挖掘去微调 embedding 或重排模型;切块侧调 chunk 大小与重叠度、做多路召回取并集;评估侧先建一套带标注的评测集,算 recall@k 和 MRR,任何改动都对着这套集子看涨跌,不然全是拍脑袋。
HNSW 的选型与代价:HNSW 是分层可导航小世界图,查询从上层稀疏图快速下钻,M 控制每个节点的邻居数、efConstruction 控制建图质量、efSearch 控制查询时的候选宽度,三者一起决定召回率和延迟。它的代价主要在写:插入要为节点连边,高并发写入下建图会拖慢并推高内存;删除一般只能标记删除,图会逐渐膨胀并留下垃圾边,需要周期性重建;内存占用是原始向量加整张图,比 IVF 系更吃内存。所以「读多写少、要低延迟高召回」选 HNSW,「频繁增删」要么换方案,要么接受重建成本。