Skip to content

AI+Java中级开发面试题库 ​

生成时间:2026-05-21 00:17 | 题目数:10 | AI:Java ≈ 5:5


【面试题】1. RAG系统中,检索到的文档片段和用户问题相关性不高时,有哪些优化手段? ​

【标准答案】我一般从三个层面优化。检索层:换用混合检索,把关键词检索(BM25)和向量检索的结果做RRF融合,比纯向量检索鲁棒很多;同时调优chunk策略,按语义段落切分而非固定token数,避免关键信息被截断。召回后处理层:加一个Re-rank模块,比如用bge-reranker对top-k结果重排序,把真正相关的片段提上来;也可以用大模型做一次相关性判断,过滤掉噪声片段。生成层:在prompt里明确告诉模型"如果检索内容与问题无关,请基于自身知识回答并标注",避免模型硬编无关信息。实际项目中,加Re-rank这一步性价比最高,通常能把准确率提升15-20%。

【面试题】2. Java中ConcurrentHashMap在JDK1.8相比1.7有哪些核心改进?为什么不再用Segment分段锁? ​

【标准答案】JDK1.7用的是Segment分段锁,每个Segment继承ReentrantLock,默认16个段,并发度固定。1.8做了三个关键改进:第一,弃用Segment,改用CAS+synchronized,锁粒度从Segment级别降到单个桶(Node),并发度从固定的16变成和桶数量一致,理论上无限。第二,数据结构从Segment+HashEntry数组改成Node数组+链表/红黑树,链表长度超过8转红黑树,查询从O(n)降到O(logn)。第三,扩容支持多线程协同迁移,每个线程负责一段桶的迁移,不会阻塞其他线程的读操作。弃用Segment的原因就是它的并发度上限固定,而实际场景中并发线程数往往远超16,CAS+synchronized更灵活,JVM对synchronized的锁升级优化也让它的性能不输ReentrantLock。

【面试题】3. 什么是AI Agent?和普通的LLM调用有什么本质区别? ​

【标准答案】普通LLM调用是一次性的:你给prompt,它给回复,没有自主性。AI Agent的核心区别在于自主决策循环——它有感知、规划、行动、反思四个环节构成闭环。具体来说:Agent能根据目标自动拆解任务、选择调用哪个工具(搜索、代码执行、数据库查询等)、观察执行结果、决定下一步动作,而不是人一步步指挥。技术上,Agent通常由LLM作为推理引擎,配合工具定义(Function Calling)、记忆模块(短期对话+长期向量存储)、规划策略(ReAct、Plan-and-Execute等)组成。举个实际例子:用户说"帮我分析竞品定价策略",普通LLM只能基于训练数据编,Agent会自己去搜索竞品信息、提取价格、生成对比表、再总结建议。本质区别就是从工具变成了有自主行动能力的数字员工。

【面试题】4. Spring Boot中@Transactional失效的常见场景有哪些?怎么排查? ​

【标准答案】我遇到过五种典型失效场景:第一,同类方法内部调用,A方法调B方法,B上的@Transactional不生效,因为没走代理,这是最常见的坑。解决方案是注入自身代理或者用AopContext.currentProxy()。第二,方法不是public,Spring AOP默认只代理public方法。第三,异常被catch吞掉了,事务没收到异常就不会回滚。第四,抛出的是checked异常,默认只回滚RuntimeException和Error,需要指定rollbackFor=Exception.class。第五,数据库引擎是MyISAM不支持事务,要换成InnoDB。排查思路:先看日志有没有开启事务的debug信息,再打断点看是不是代理对象调用,最后直接检查这五个点逐一排除。

【面试题】5. 向量数据库选型时,Milvus、Pinecone、Weaviate各适合什么场景? ​

【标准答案】Milvus适合大规模、自部署场景,支持十亿级向量检索,提供丰富的索引类型(IVF、HNSW、DiskANN),社区活跃,和LangChain集成好,但对运维有要求,需要部署依赖组件。Pinecone是全托管服务,零运维,API简单,适合快速上线、团队没有向量数据库运维经验的场景,缺点是数据在别人云上,定制性弱,成本随规模上升快。Weaviate的特点是支持多模态搜索(向量+关键词+过滤),内置向量化模块可以直接存文本自动embedding,适合需要混合检索且不想额外部署embedding服务的场景,体量中等,单机部署简单。总结:自建大集群选Milvus,快速上线选Pinecone,混合检索+轻量部署选Weaviate。

【面试题】6. MySQL中InnoDB的MVCC是怎么实现的?ReadView的可见性判断规则是什么? ​

【标准答案】MVCC依赖两个隐藏列:trx_id(最后修改该行的事务ID)和roll_pointer(指向undo log中的前版本链)。ReadView是事务开始时创建的快照,包含四个关键字段:creator_trx_id(当前事务ID)、m_ids(创建时所有活跃事务ID列表)、min_trx_id(m_ids最小值)、max_trx_id(下一个将分配的事务ID)。可见性判断规则:如果trx_id < min_trx_id,说明修改在ReadView创建前已提交,可见;如果trx_id >= max_trx_id,说明修改在ReadView创建后才开始,不可见;如果min_trx_id <= trx_id < max_trx_id,看trx_id是否在m_ids中,在则说明事务还未提交,不可见,不在则已提交,可见。如果不可见,就顺着undo log版本链往前找,直到找到可见版本。这就是RC级别每次查询都创建新ReadView、RR级别只在首次查询创建的原因,导致RR级别可重复读。

【面试题】7. 提示词工程中,Chain-of-Thought和Few-shot各自适用什么场景?能否结合使用? ​

【标准答案】Chain-of-Thought(CoT)适用于需要推理的任务,比如数学计算、逻辑分析、多步骤决策,通过引导模型"一步步思考"来提升推理准确率。自动CoT甚至不需要手动写推理过程,只加一句"Let's think step by step"就有效。Few-shot适用于输出格式或任务模式需要明确示范的场景,比如特定格式的文本抽取、分类任务、代码生成风格统一,通过给几个示例让模型理解你期望的输入输出模式。两者完全可以结合——在Few-shot示例中包含完整的推理过程(即CoT形式的示例),这叫Few-shot CoT,效果比单独使用任何一种都好。实际项目中我最常用的就是:给2-3个带推理过程的示例,再对新问题触发CoT,既规范了输出格式又保证推理质量。

【面试题】8. Redis分布式锁用SETNX实现有什么问题?RedLock算法怎么解决的?生产环境推荐什么方案? ​

【标准答案】基础SETNX有三个问题:锁过期但业务未完成导致别人拿到锁——用看门狗续期解决;主从同步延迟导致锁丢失——主节点加锁后宕机,从节点未同步,新主没有锁信息——这是RedLock要解决的;不可重入——同一个线程无法重复获取同一把锁。RedLock的方案是向N个独立Redis实例加锁,超过半数成功才算获取锁,释放时向所有实例发释放。但RedLock有争议:Martin Kleppmann指出它在时钟跳变、进程暂停等场景下仍不安全。生产环境推荐:如果公司有etcd或ZooKeeper,用它们的分布式锁更可靠(基于Raft/ZAB共识);如果必须用Redis,推荐Redisson的看门狗模式(单实例+续期),大多数场景够用;对极端一致性要求才考虑RedLock,但要清楚它的边界。

【面试题】9. Spring AI和LangChain在AI应用开发上各自的优劣势是什么?Java团队该怎么选? ​

【标准答案】LangChain是Python生态的事实标准,优势在于生态极其丰富——集成模型最多、社区方案最多、教程和案例海量,新模型新功能第一时间支持。劣势是对Java团队来说需要切换语言栈,和现有Spring微服务集成有额外成本。Spring AI是Spring生态的AI框架,优势在于和Spring Boot无缝集成,用Java开发者的习惯(依赖注入、配置管理、自动装配)来构建AI应用,支持Prompt Template、Function Calling、RAG、向量存储等核心能力,0.8版本后功能已比较完善。劣势是生态和社区比LangChain小,模型支持有延迟,遇到问题可参考的资料少。选型建议:如果团队以Java为主、AI功能是业务系统的一部分(比如客服系统的智能问答),选Spring AI,技术栈统一、运维简单;如果团队要做AI原生产品、需要快速实验各种模型和方案,或者团队有Python能力,选LangChain更灵活。

【面试题】10. Kafka如何保证消息的精确一次语义(Exactly-Once)?生产环境中怎么实现? ​

【标准答案】Kafka的Exactly-Once依赖三个机制配合:第一,幂等性Producer,通过Producer ID和Sequence Number,Broker对重复消息自动去重,解决单分区内单会话的重复问题。开启方式:enable.idempotence=true。第二,事务机制,跨分区、跨会话的原子写入,Producer发送消息到多个分区,要么全部成功要么全部回滚,Consumer设置isolation.level=read_committed只读已提交消息。第三,Consumer端的幂等处理,Kafka本身只能保证"消费+提交"的原子性(consume-transform-produce模式),纯消费端需要业务层自行保证幂等,比如用唯一ID去重表、或业务状态机判断。生产环境最佳实践:Producer开启幂等+事务,Consumer用read_committed隔离级别,消费逻辑做幂等设计(去重表或业务天然幂等),三者缺一不可。