AI+Java中级开发面试题库
生成时间:2026-05-20 23:42 | 题目数:10 | AI:Java = 5:5
【面试题】1. RAG系统中检索召回率低,你一般从哪些维度优化?
【标准答案】RAG召回率低,我从三个层面优化。第一,Chunk策略:不要无脑固定长度切分,按语义段落切,chunk size根据业务调,一般256-512 token,overlap留10%-15%防断句。第二,Embedding模型:通用模型在垂直领域效果差,用领域数据微调embedding,或者换bge-large、text-embedding-3这些更强的模型。第三,检索策略:单路向量检索不够,加关键词检索(BM25)做混合检索,再用Reranker二次排序。另外元数据过滤也很关键——比如只搜最近三个月的文档,精度直接上来。实际项目中,混合检索+Rerank这套组合拳,召回率通常能提升20%-30%。
【面试题】2. Java中synchronized和ReentrantLock的核心区别是什么?什么场景下选ReentrantLock?
【标准答案】三个核心区别:第一,实现层面——synchronized是JVM层面的内置锁,ReentrantLock是API层面的乐观锁(基于AQS)。第二,功能层面——ReentrantLock支持公平锁、可中断获取锁(lockInterruptibly)、多条件变量(Condition)、超时获取(tryLock带时间),synchronized都不支持。第三,释放方式——synchronized自动释放,ReentrantLock必须手动unlock,一般放finally块里。选ReentrantLock的场景:需要公平锁排队、需要尝试获取锁不阻塞、需要多个等待队列(Condition)、需要中断正在等锁的线程。如果就是简单互斥,synchronized更简洁,JDK6之后有偏向锁、轻量级锁优化,性能差距不大。
【面试题】3. Spring AI中如何设计一个支持多轮对话和工具调用的AI Agent?
【标准答案】Spring AI做Agent,核心是ChatClient + Function Calling。多轮对话:维护一个ChatMemory(内置有InMemoryChatMemory和RedisChatMemory),每次请求把历史消息列表塞进Prompt,对话上下文就续上了。工具调用:定义一个带@Description注解的Java函数,注册为Function Callback,模型会判断何时调用,Spring AI自动执行函数并把结果回填给模型继续生成。架构上,Controller层接收用户输入,Service层编排ChatClient调用链,包括:组装System Prompt + 历史消息 → 调用模型 → 解析是否需要调工具 → 执行工具 → 再次调用模型 → 返回结果。关键点是System Prompt要写清楚Agent的角色和可用工具的边界,避免模型乱调工具。生产环境建议用Redis存ChatMemory,支持分布式部署。
【面试题】4. JVM中垃圾收集器G1和ZGC各自的适用场景是什么?线上怎么选?
【标准答案】G1适合中等堆(4-16G),通过Region分代收集,可以设期望停顿时间(-XX:MaxGCPauseMillis),大多数场景够用。ZGC适合大堆(16G以上),核心优势是STW停顿极低,通常亚毫秒级,因为它做的是并发整理,读屏障+染色指针实现。选型逻辑:堆6G以内用G1没问题,追求吞吐可以用Parallel;堆超16G或对延迟极度敏感(如金融交易),上ZGC。注意ZGC从JDK15生产可用,JDK21有分代ZGC,效果更好。线上实际看GC日志的停顿时间和频率,如果G1的Young GC停顿已经超标,就该考虑ZGC了。迁移时注意ZGC不支持某些JVM参数,比如不支持MaxGCPauseMillis。
【面试题】5. 提示词工程中,Chain-of-Thought(CoT)和Few-Shot分别解决什么问题?能不能结合使用?
【标准答案】CoT解决的是复杂推理问题——模型直接给答案容易出错,但让它"一步步想",中间推理过程显式化,准确率显著提升,特别适合数学、逻辑推理类任务。Few-Shot解决的是格式和风格对齐问题——给几个示例,模型就知道你要什么格式的输出,不需要微调就能适配新任务。两者可以结合,叫Few-Shot CoT:示例里不只给输入输出,还给推理过程。比如给3个示例,每个示例都包含"思考过程→最终答案"的完整链路,模型就学会了既按格式输出又做推理。实际应用中,我推荐先写System Prompt定义角色,再给2-3个Few-Shot CoT示例,比单纯指令效果好很多。
【面试题】6. MySQL中联合索引(a,b,c),下列哪些查询能用上索引?explain一下原因。
① SELECT * FROM t WHERE a=1 AND b=2 AND c=3 ② SELECT * FROM t WHERE b=2 AND c=3 ③ SELECT * FROM t WHERE a=1 AND c=3 ④ SELECT * FROM t WHERE a>1 AND b=2
【标准答案】①能完全用上,a=b=c三列等值查询,完美匹配联合索引最左前缀。②用不上,跳过了最左列a,索引树无法定位起点。③只能用a列,a是等值匹配走索引,c跳过了b所以用不上——最左前缀原则要求连续。④a走范围扫描,但b用不上,因为a是范围条件后,后面的列无法继续在索引中精确定位。核心就一句话:联合索引遵循最左前缀匹配,遇到范围查询(>、<、BETWEEN、LIKE前缀)就停止匹配后续列。优化建议:把等值条件的列放前面,范围条件列放最后。如果③是高频查询,考虑建(a,c)的辅助索引。
【面试题】7. AI Agent开发中,ReAct模式和Plan-Then-Execute模式有什么区别?各自适合什么场景?
【标准答案】ReAct是"边想边做"——每一步都是Thought(分析)→ Action(调用工具)→ Observation(观察结果)→ 再Thought循环,动态决策下一步。Plan-Then-Execute是"先规划后执行"——先让模型生成完整计划(拆成多个子任务),然后按计划依次执行,执行中不再调整。ReAct适合开放性任务,比如调研分析,因为每步结果不确定,需要根据反馈调整策略。Plan-Then-Execute适合确定性高的流水线任务,比如"先搜索、再摘要、最后生成报告",步骤固定不需要动态调整。实际项目中可以混合用:先Plan生成大致框架,执行中用ReAct微调。LangChain的Plan-and-Execute Agent就是这个思路。ReAct的缺点是token消耗大(多轮推理),Plan模式更省token但灵活性差。
【面试题】8. Redis分布式锁用SETNX实现有什么坑?Redlock算法解决了什么问题?
【标准答案】SETNX三大坑:第一,锁过期但业务没执行完——锁自动释放,其他线程拿到锁,导致并发问题。解决:开看门狗线程自动续期(Redisson就是这么干的)。第二,释放了别人的锁——线程A的锁过期了,线程B拿到了,线程A执行完直接DEL把B的锁删了。解决:SET时value设唯一标识(UUID),释放时先比较再删,用Lua脚本保证原子性。第三,主从切换丢锁——主节点加锁成功但还没同步给从节点就挂了,从升主后锁丢失。Redlock就是解决这个问题的:向N个独立Redis实例同时加锁,超过半数成功才算获取锁,避免单点故障。但Redlock争议很大,Martin Kleppmann写过文章质疑它的时钟假设,实际生产中如果是主从架构,用Redisson的看门狗+Lua释放就够了;如果对正确性要求极高,建议用Zookeeper或etcd。
【面试题】9. 大模型微调中,LoRA和全量微调的取舍标准是什么?什么情况下LoRA不够用?
【标准答案】LoRA的核心思想是冻结原始权重,只训练低秩分解矩阵(A和B),参数量减少到原来的0.1%-1%,显存占用大幅降低,单卡就能跑。取舍标准:数据量小(几千到几万条)、任务和预训练领域接近、资源有限——选LoRA。数据量大(10万+)、任务和预训练差异大(比如从通用到医疗诊断)、需要模型深度改变行为——全量微调更稳。LoRA不够用的场景:第一,模型需要学全新的输出格式或语言,低秩矩阵表达能力不够。第二,训练数据和预训练数据分布差异极大,比如用通用模型微调做代码生成,LoRA可能学不深。第三,对准确率要求极高的生产场景,LoRA可能有1-3个点的性能gap。实际建议:先LoRA试,效果不够再逐步加大rank(8→16→64),还不行就全量微调。QLoRA也是个折中方案——4bit量化+LoRA,显存友好且效果接近全量。
【面试题】10. Spring Cloud微服务中,服务A调用服务B,B调用服务C,C超时了,如何防止级联故障?
【标准答案】核心是三层防护。第一层,超时控制:每个调用的Feign/RestTemplate必须设合理超时,不要用默认值。比如B调C设3秒超时,C没响应B快速失败,不会一直占着线程。第二层,熔断器:用Sentinel或Resilience4j,当C的失败率超阈值,熔断器打开,B直接走降级逻辑,不再调C,给C恢复时间。半开状态放少量请求试探,成功就关闭熔断。第三层,隔离策略:信号量隔离或线程池隔离,控制对C的并发调用数,即使C全挂了也不会把B的线程池耗尽。降级逻辑要提前设计,比如返回缓存数据、默认值、或者友好提示。另外全局层面,如果用的是Hystrix/Sentinel,配合Dashboard监控各服务熔断状态,运维能快速定位。一句话总结:超时兜底、熔断保护、隔离限流、降级保活。