最近帮几位朋友做模拟面试明显感受到2026年Java后端面试和两三年前有一个非常大的变化面试官不再只关心“HashMap怎么扩容”“MySQL索引为什么失效”这类纯八股题而是会把问题拉回到真实的业务和故障里比如“你们线上OOM是怎么定位的”“订单超时关闭用的什么方案”“项目里怎么接入大模型的”。这意味着单纯背八股文已经不够了。面试考察的是你对Java场景问题的理解、线上故障排查的实战能力、项目落地时的技术选型能力以及最近两年新增的AI大模型应用能力。很多在职或刚被优化、正在找工作的同学反而容易在“AI新增考点”和“线上故障实战”这两块卡住因为这些内容在平时业务开发里很少被系统整理过。本文围绕这几个方向整理了一份Java后端2026面试大全覆盖Java核心基础、Spring/Spring Boot、数据库与缓存、线上故障排查、项目落地场景题、AI大模型新增考点。内容偏实战尽量以面试官真实的提问角度拆解并给出可以直接复用的代码示例和排查命令。无论你现在是在职看机会、被裁员后重新求职还是应届生查漏补缺这份指南都能帮你快速建立面试知识框架。1. 2026年Java后端面试趋势与考点地图先聊趋势。如果只看两年前的面试题你可能会觉得后端面试还是老三样Java集合、JVM、Spring。但从2026年的岗位要求和面试反馈来看考点已经悄然转向“工程能力”和“AI落地能力”。1.1 从“背八股”到“讲场景”过去很多Java面试是八股文模式HashMap、JVM、Spring AOP轮流问谁背得熟谁拿分。现在面试官更关心你能不能把知识点放进项目里解释。同样一个问题问法完全不一样了线程池不能只背参数要能解释为什么项目里用ThreadPoolExecutor而不是Executors以及线程池满了之后任务到底去了哪里。MySQL索引不能只说“最左前缀”要能结合慢SQL和EXPLAIN分析为什么没走索引。分布式锁不能只说“Redis SETNX”要讨论锁续期、误删、主从切换等边界情况。所以准备面试时每道题都要从“原理 场景 代码 坑”四个维度准备而不是只记结论。1.2 线上故障排查成为必考项从最近搜索热度可以看到“kubernetes线上故障排查实战”“java outofmemoryerror insufficient memory”这类词被大量搜索。面试官会拿一个线上事故原型来提问CPU飙高怎么定位是哪行代码堆内存一直涨怎么判断是否有内存泄漏接口偶发超时你会从哪些链路去排查这类问题没有标准答案考察的是你的排查方法、命令行工具熟练度和判断逻辑。如果只是背过概念、没有真实排查经验面试时很容易卡壳。所以本文第5章会重点展开OOM、CPU飙升、接口超时和Kubernetes环境下的常见故障。1.3 AI大模型成为Java后端新增考点2026年很多Java后端岗位要求会用大模型API、了解RAG、能设计AI问答应用。面试开始出现大量AI相关新题RAG的基本链路是什么Java怎么调用大模型接口向量数据库怎么选如何设计一个能调用后端接口的Agent这些原本属于算法或AI工程师的题目现在已经变成了后端岗位的加分项甚至部分公司直接列入必考。好消息是Java后端做AI应用开发并不需要重新学习深度学习重点在于掌握API调用、RAG链路、Prompt构造和流式输出这些工程化能力。1.4 高频考点地图下面这张表可以作为自查清单建议收藏后逐项打勾考点分类代表性问题优先级Java基础HashMap、ConcurrentHashMap、线程池、JVM内存结构必考Spring生态Bean生命周期、事务失效、自动配置原理必考数据库索引失效、MVCC、事务隔离级别、SQL优化必考缓存穿透、击穿、雪崩、分布式锁高频分布式消息积压、幂等、分布式事务高频线上故障OOM、CPU飙升、接口超时、Pod重启高频新增项目落地订单超时、防超卖、灰度发布高频AI应用RAG、Function Calling、本地部署、Prompt新增考点2. Java核心基础高频面试题Java基础是面试的“基本盘”这部分如果答不好后面框架题答得再漂亮也会被压分。下面挑几个最高频、也最容易被问出深度的考点展开。2.1 HashMap底层原理面试官通常从“HashMap底层数据结构”切入然后一步步追问到扩容和红黑树。回答时要体现版本差异。JDK 1.7的HashMap底层是数组加链表插入使用头插法扩容时在多线程环境下可能出现环形链表导致死循环。JDK 1.8改成了数组加链表加红黑树链表长度超过8且数组长度超过64时转红黑树插入使用尾插法解决了死循环问题但依然不是线程安全的。扩容机制也是重点。默认初始容量16负载因子0.75当元素个数超过容量乘以负载因子时触发扩容。扩容时容量翻倍元素重新计算位置。这里可以补充一个细节为什么链表转红黑树的阈值是8因为红黑树节点占用空间约是普通节点的两倍链表长度在绝大多数情况下不会超过8所以只有在极端哈希冲突时才转树避免空间浪费。2.2 ConcurrentHashMap如何保证线程安全ConcurrentHashMap在JDK 1.7和1.8的实现差异很大。1.7采用Segment分段锁每一把锁锁住一段数据理论上支持Segment数量的并发写。1.8放弃了Segment改用CAS加synchronized控制桶节点锁粒度更细并发度更高。具体来说1.8在插入元素时如果桶为空用CAS尝试插入如果桶不为空则对桶的头节点加synchronized锁。读操作不加锁靠volatile保证可见性。扩容时支持多线程协同迁移也是常见的追问点。面试时可以补充一句ConcurrentHashMap的size()在不同版本实现也不同1.8先用baseCount累加竞争激烈时再用CounterCell数组分散计数最后求和。这能体现你对源码细节有过研究。2.3 线程池核心参数与拒绝策略线程池是Java并发面试的必考题也是工作中最容易踩坑的地方。核心参数包括corePoolSize核心线程数通常不会被回收。maximumPoolSize最大线程数超过核心线程且队列满时会创建新线程。keepAliveTime非核心线程的空闲存活时间。workQueue任务队列常用ArrayBlockingQueue或LinkedBlockingQueue。threadFactory线程工厂用于命名线程。handler拒绝策略队列满且线程数达到最大值时触发。四个拒绝策略分别是AbortPolicy直接抛异常、CallerRunsPolicy让提交任务的线程自己执行、DiscardPolicy丢弃任务、DiscardOldestPolicy丢弃队列中最旧的任务。面试高频追问是“为什么尽量不要用Executors创建线程池”。因为Executors.newFixedThreadPool和newSingleThreadExecutor使用的LinkedBlockingQueue默认容量是Integer.MAX_VALUE任务可以无限堆积极端情况下导致OOM。newCachedThreadPool的maximumPoolSize是Integer.MAX_VALUE线程数可能无限增长。所以在生产环境更推荐手动new ThreadPoolExecutor并根据业务设置合理的队列长度和拒绝策略。下面给一个完整可运行的示例// 文件路径com/example/interview/ThreadPoolDemo.java import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; public class ThreadPoolDemo { public static void main(String[] args) { ThreadPoolExecutor pool new ThreadPoolExecutor( 4, // 核心线程数 8, // 最大线程数 30L, // 非核心线程存活时间 TimeUnit.SECONDS, // 时间单位 new ArrayBlockingQueue(100), // 有界队列 new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略 ); for (int i 0; i 200; i) { final int taskId i; pool.execute(() - { System.out.println(Thread.currentThread().getName() 执行任务: taskId); }); } pool.shutdown(); } }这个例子中核心线程4个队列最多100个最大线程8个。当200个任务同时提交时4个核心线程先处理100个任务进入队列队列满后再创建4个非核心线程剩下的任务触发CallerRunsPolicy由main线程执行。运行后观察输出线程名就能直观理解线程池的排队机制。2.4 JVM内存结构与OOM类型JVM内存结构主要分五块堆、虚拟机栈、本地方法栈、方法区元空间、程序计数器。其中堆存放对象实例是GC的主要区域虚拟机栈对应Java方法调用栈帧包含局部变量表、操作数栈等元空间存放类元数据。OOM常见类型有java.lang.OutOfMemoryError: Java heap space堆内存不足多由大对象或内存泄漏导致。java.lang.OutOfMemoryError: Metaspace元空间不足常见于动态生成类过多的场景。java.lang.OutOfMemoryError: Unable to create new native thread线程数超过操作系统限制。java.lang.OutOfMemoryError: Insufficient memory这个报错经常出现在容器环境进程尝试申请内存时被cgroup限制拦截底层无法分配足够内存。面试时被问到OOM不要只答“加内存”要给出完整的排查思路。第5章会详细展开。3. Spring/Spring Boot核心面试考点Spring面试题通常围绕Bean生命周期、事务、自动配置和循环依赖展开。这些内容看似基础但面试官通过连续追问能快速判断你对框架的理解深度。3.1 Bean生命周期简化版的生命周期可以这样回答实例化 - 属性填充 - Aware接口回调 - BeanPostProcessor前置处理 - 初始化方法 - BeanPostProcessor后置处理 - 使用 - 销毁。Aware接口包括BeanNameAware、BeanFactoryAware、ApplicationContextAware等用于让Bean感知Spring容器。BeanPostProcessor是扩展点AOP就是在这里通过动态代理生成代理对象的。初始化方法包括PostConstruct、InitializingBean.afterPropertiesSet和自定义init-method它们的执行顺序是PostConstruct - afterPropertiesSet - init-method。回答时把顺序说准确再补充“Spring在依赖注入后会回调BeanPostProcessor代理对象在这里生成”面试官通常就会满意。3.2 事务失效的典型场景Spring事务失效是线上高频问题也是面试必考。典型场景包括同类内部方法调用由于Spring事务基于代理同类内通过this调用不会经过代理Transactional不生效。方法不是publicSpring默认使用CGLIB或JDK动态代理private和final方法无法被代理。异常被try-catch吞掉Spring默认只回滚RuntimeException和Error如果捕获异常不抛出事务不会回滚。数据库引擎不支持事务比如MyISAM引擎本身不支持事务。传播行为设置错误比如外层方法没有事务内层REQUIRES_NEW单独开启事务。下面是一个典型的自调用失效示例// 文件路径com/example/interview/OrderService.java import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; Service public class OrderService { Transactional public void outerMethod() { updateOrder(); throw new RuntimeException(发生异常); } public void updateOrder() { System.out.println(更新订单); } }这个例子中outerMethod调用updateOrder时是通过this调用updateOrder上的Transactional不会生效。解决方案有三种把updateOrder拆到另一个Service中通过ApplicationContext获取代理对象再调用或者自己注入自己。面试时能主动说出“自调用导致代理绕行”就能证明你真正理解Spring事务的原理。3.3 Spring Boot自动配置原理Spring Boot最核心的优点是自动配置。回答时从入口注解展开SpringBootApplication由SpringBootConfiguration、EnableAutoConfiguration和ComponentScan组成。其中EnableAutoConfiguration通过AutoConfigurationImportSelector加载META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件里的自动配置类。自动配置类通常配合条件注解生效比如ConditionalOnClass判断依赖是否存在ConditionalOnMissingBean判断用户是否已经自定义Bean。这就是为什么Spring Boot能根据classpath自动装配Redis、DataSource、Kafka等组件。补充一句新版Spring Boot用.imports文件替代了旧版的spring.factories面试时如果提到这个细节会显得你一直在跟进版本变化。3.4 循环依赖为什么用三级缓存Spring通过三级缓存解决单例Bean之间的循环依赖一级缓存singletonObjects存放完整Bean。二级缓存earlySingletonObjects存放早期Bean也就是对象已经创建但属性还未填充完。三级缓存singletonFactories存放ObjectFactory用来提前生成AOP代理对象。循环依赖的解决过程是A创建时发现需要注入B于是先把A的早期引用放入三级缓存然后去创建BB创建时发现需要注入A从三级缓存拿到A的ObjectFactory生成早期Bean放入二级缓存并注入到BB创建完成后A再从缓存中拿到B完成注入。注意构造器注入无法解决循环依赖因为构造函数阶段连早期Bean都无法暴露。这也是Spring官方推荐使用构造器注入后在遇到循环依赖时报错的原因。4. 数据库与缓存面试重点数据库和缓存是后端面试的重头戏权重非常高。下面挑几个必考题展开。4.1 MySQL索引失效场景索引失效是开发中最常见的问题。面试高频场景包括对索引列使用函数WHERE DATE(create_time) 2026-01-01DATE函数导致索引失效。隐式类型转换例如索引列是varchar却传入整数条件。前导模糊查询LIKE %abc无法使用索引LIKE abc%可以。OR连接非索引列OR前后的条件有一个没索引整个查询可能走全表扫描。不满足最左前缀联合索引(a,b,c)如果查询条件没有a则无法使用索引。给一个典型的优化示例-- 优化前对索引列使用函数索引失效 SELECT * FROM orders WHERE DATE(create_time) 2026-01-01; -- 优化后范围查询可以正常走索引 SELECT * FROM orders WHERE create_time 2026-01-01 AND create_time 2026-01-02;回答时最好补充说明优化后的SQL走的是范围索引扫描比全表扫描快很多。如果面试官继续追问可以提到覆盖索引和索引下推。4.2 事务隔离级别与MVCCMySQL的四种隔离级别读未提交、读已提交、可重复读、串行化。MySQL默认是可重复读。MVCC是面试重点。MVCC通过undo log版本链和ReadView实现快照读。读已提交和可重复读的区别在于生成ReadView的时机读已提交每次执行SELECT都会生成新的ReadView所以能读到其他事务已提交的数据可重复读只在第一次SELECT时生成ReadView之后复用因此避免了不可重复读。当前读SELECT ... FOR UPDATE、UPDATE、DELETE会使用最新的版本并加锁。这也是为什么可重复读下依然可能出现幻读因为当前读读取的是最新数据。面试时能区分快照读和当前读基本就能过关。4.3 Redis缓存穿透、击穿、雪崩这组问题是Redis面试的“三板斧”必须掌握。缓存穿透查询一个不存在的数据缓存和数据库都没有每次请求都打到数据库。方案缓存空值、布隆过滤器。缓存击穿某个热点key过期大量请求同时打到数据库。方案互斥锁、逻辑过期。缓存雪崩大量key同时过期或Redis宕机导致数据库压力暴涨。方案过期时间加随机数、多级缓存、限流降级。回答时最好结合业务。比如“秒杀系统里商品详情是热点key如果过期瞬间有10万请求进来怎么处理”这时候要说互斥重建缓存并设置逻辑过期时间避免同一时刻所有请求都去查数据库。4.4 分页深翻页优化LIMIT 100000, 20这类深分页在数据量大时性能极差因为MySQL要扫描前100000行再丢弃。优化方案有两种一种是游标查询-- 优化前深分页扫描大量行 SELECT * FROM orders ORDER BY id LIMIT 100000, 20; -- 优化后基于上一页最大id查询 SELECT * FROM orders WHERE id 100000 ORDER BY id LIMIT 20;另一种是覆盖索引延迟关联SELECT o.* FROM orders o INNER JOIN ( SELECT id FROM orders ORDER BY id LIMIT 100000, 20 ) t ON o.id t.id;第一种适合按顺序翻页的场景第二种适合需要保留随机跳页的场景。5. 线上故障排查实战场景线上故障排查已经成为Java后端面试的高频区因为它最能体现真实工程能力。这里按最常见的三类故障展开OOM、CPU飙升、接口超时。最后补充Kubernetes环境下的排查要点。5.1 内存溢出OutOfMemoryError排查先看现象。日志里出现java.lang.OutOfMemoryError: Java heap space或者GC overhead limit exceeded说明堆内存已经极度过剩GC无法有效回收。还会出现java.lang.OutOfMemoryError: Insufficient memory这个报错常见于容器环境进程申请内存时被cgroup限制拦截底层无法分配足够内存。排查步骤第一步确认是否真的堆内存不足。查看监控中的堆使用曲线和GC频率。如果GC越来越频繁Full GC后内存无法回落大概率存在内存泄漏。第二步保留现场。如果服务还能启动可以加上JVM参数在OOM时自动导出堆快照# 在启动命令中加入以下参数OOM时自动导出堆快照并打印堆信息 -XX:HeapDumpOnOutOfMemoryError -XX:HeapDumpPath/tmp/heap.hprof第三步分析堆快照。使用MAT、VisualVM或Arthas。先看Dominator Tree找占用内存最大的对象再看GC Roots引用链判断是否被集合类长期引用。常用排查命令# 查看Java进程 jps -l # 查看堆内存概况 jmap -heap pid # 导出堆快照注意生产环境执行jmap dump会触发STW建议低峰期操作 jmap -dump:formatb,file/tmp/heap.hprof pid # 实时查看GC情况每秒刷新一次 jstat -gcutil pid 1000这里有一个注意事项jmap -dump在生产环境会暂停应用所以更推荐提前开启HeapDumpOnOutOfMemoryError或者使用Arthas的heapdump命令。任何生产环境操作都应在测试环境验证后再执行。5.2 CPU飙高排查CPU飙高是另一个高频问题。典型场景是死循环、频繁GC、正则回溯或某个热点方法占用大量CPU。排查流程如下# 第一步定位CPU占用高的进程 top -c # 第二步查看进程内哪些线程占用CPU高 top -Hp pid # 第三步将线程ID转十六进制 printf %x\n threadId # 第四步导出线程栈并查找对应线程 jstack pid thread_dump.txt grep -A 30 0x十六进制线程ID thread_dump.txt看到线程栈后重点找RUNNABLE状态的线程在做什么或者在等待什么锁。如果是GC线程导致CPU高结合jstat -gcutil确认GC频率如果是业务代码死循环直接定位到对应代码行。回答这道题时最重要的是把命令执行顺序说清楚这比背结论更有说服力。5.3 接口超时与慢链路排查接口偶发超时是最难排查的问题之一因为没有固定的复现路径。推荐按下面的顺序排查排查层关注点常用手段客户端超时时间设置是否合理抓包、网关日志应用层线程池排队、CPU竞争、GC停顿监控线程池活跃数、GC日志数据库慢SQL、锁等待开启慢查询日志查information_schema锁表缓存大key、hotkey、慢命令Redis慢日志、bigkeys扫描外部依赖下游接口变慢或异常链路追踪、Feign超时配置如果是Kubernetes部署还要额外检查PodCPU是否被限流throttling、是否频繁发生OOMKilled重启。5.4 Kubernetes环境下的故障排查要点公司上云后后端岗位的线上故障大概率会结合K8s场景。高频问题包括Pod一直重启、发布后接口报错、服务无法发现。常见命令# 查看Pod运行状态 kubectl get pods -n namespace # 查看Pod上次崩溃日志 kubectl logs pod-name -n namespace --previous # 查看Pod详细事件包括镜像拉取失败、探针失败原因 kubectl describe pod pod-name -n namespace如果Pod的OOMKilled次数持续增加说明容器内存超过limit需要结合JVM堆配置一起看。这里有一个常见的坑JVM默认的MaxHeapSize是物理内存的1/4在容器里可能超过容器limit导致容器被kill。解决办法是显式设置-Xmx并使用兼容容器内存的JDK选项。6. 项目落地与高频场景设计题场景设计题考察的是项目经验和工程决策能力。相比基础题这类题没有唯一答案面试官更在意你能否给出方案对比和取舍。6.1 订单超时关闭怎么设计这是一个非常经典的业务场景题。候选方案有三种定时轮询每30秒扫描一次超时订单简单但存在延迟和数据库压力。延迟队列使用RabbitMQ延迟插件或Redis过期事件触发及时但Redis过期事件存在延迟和丢失可能。时间轮适合高并发、低延迟场景但实现复杂度高。面试时的推荐回答是组合方案用Redis过期事件或延迟队列作为第一层触发配合定时任务做兜底扫描避免Redis key过期事件丢消息导致订单漏关。还可以补充订单关闭后需要异步通知用户因此需要设计可靠的消息投递机制。6.2 分布式锁面试官常问“如何用Redis实现分布式锁”。简单回答“SET NX”只能拿基础分要答出细节才算完整。加锁时要保证原子性SET NX EX可以一步完成。锁的value要使用唯一标识比如UUID这样释放时才能确认是自己的锁避免误删其他线程的锁。释放时要使用Lua脚本保证判断和删除的原子性。还需要考虑锁过期时间如果业务执行时间超过锁的过期时间需要自动续期工程上可以使用Redisson的看门狗机制。伪代码示例// 文件路径com/example/interview/DistributedLockDemo.java String lockKey order:pay: orderId; String requestId UUID.randomUUID().toString(); // 加锁SET key value NX EX seconds Boolean locked redisTemplate.opsForValue() .setIfAbsent(lockKey, requestId, 30, TimeUnit.SECONDS); if (Boolean.TRUE.equals(locked)) { try { doBusiness(); } finally { // 释放锁使用Lua脚本保证“判断身份 删除”原子性 String luaScript if redis.call(get, KEYS[1]) ARGV[1] then return redis.call(del, KEYS[1]) else return 0 end; redisTemplate.execute( new DefaultRedisScript(luaScript, Long.class), List.of(lockKey), requestId ); } }最后提一句如果对可靠性要求极高可以使用ZooKeeper的临时顺序节点实现分布式锁性能比Redis略低但不会出现主从切换导致锁丢失的问题。6.3 消息积压怎么处理消息积压的常见原因包括消费者服务宕机、消费速度慢、消息量突增。处理步骤第一步先确认积压量级和影响范围看监控中消费位点落后多少。第二步如果消费者服务已经挂了先恢复服务保证消息不再继续积压。第三步评估是否需要扩容消费者实例如果Topic分区数限制了消费并行度可能需要临时创建新的Topic增加分区数后让消费者重新消费。对于下游处理慢导致的积压可以关闭非核心业务逻辑比如减少写日志、临时关闭某些回调通知先把核心消息消费掉。对于极端积压可以把消息转储到临时队列或大表业务恢复后再重放。面试时强调“先保证不丢消息再恢复消费顺序”这个原则会比较加分。6.4 高并发下单防超卖防超卖的核心是保证“判断库存充足”和“扣减库存”两个操作是原子性的。最简单可靠的方式是数据库乐观锁UPDATE stock SET stock stock - 1 WHERE id #{skuId} AND stock 0;受影响行数为1说明扣减成功为0说明库存不足。但高并发下数据库压力大所以常用Redis预扣减。Redis配合Lua脚本可以保证原子性-- 扣减库存Lua脚本判断库存充足并扣减两步操作原子完成 if tonumber(redis.call(get, KEYS[1])) tonumber(ARGV[1]) then return redis.call(decrby, KEYS[1], ARGV[1]) else return -1 endJava侧通过RedisTemplate执行这段脚本返回值大于等于0表示扣减成功返回-1表示库存不足。Redis扣减成功后再异步发送消息更新数据库库存最终以数据库为准。这样既保证性能又保证最终一致性。面试时能把这个链路说完整说明你有真实的高并发项目经验。7. AI大模型新增考点这是2026年Java后端面试最大的变化点。AI大模型相关内容已经从“了解即可”变成了“必须会”。下面逐个拆解高频考点。7.1 面试官为什么开始问大模型核心原因是业务需求变了。企业都在做AI应用包括智能客服、知识库问答、AI辅助编程、智能工单等。Java后端工程师的职责不再只是CRUD而是要把AI能力集成到业务系统里。具体来说对接大模型API处理请求和流式响应。搭建RAG链路让模型基于企业知识库回答问题。设计Agent应用让模型能调用后端接口完成真实业务操作。做好限流、缓存、内容安全和成本控制。所以面试官问大模型不是想考你算法推导而是想知道你能不能把AI能力落到工程上。7.2 RAG的基本链路RAG是检索增强生成核心思路不直接让模型盲答而是先从知识库中检索相关内容拼进Prompt后让模型基于上下文回答。RAG链路通常包含以下步骤文档加载解析PDF、Word、TXT、HTML等格式。文本切分按段落或固定长度切分成chunk避免超出模型上下文窗口。Embedding向量化调用Embedding模型把每个chunk转成向量。存入向量数据库如Milvus、Qdrant、pgvector、Elasticsearch。用户提问后向量化问题在向量库中检索Top-K相似chunk。将用户问题与检索结果拼接成Prompt。调用大模型生成回答。返回答案通常配合流式输出降低首字延迟。面试官可能会追问“RAG和微调的区别”。回答RAG适合知识实时更新、需要可追溯来源的场景成本低、不需要训练模型微调适合改变模型风格、能力和输出格式的场景但需要训练数据和算力。实际项目中RAG落地周期更短也是Java后端最容易上手的方案。7.3 Java调用大模型API示例Java调用大模型API并不难只要模型服务提供OpenAI兼容协议就可以用HttpClient直接调用。下面是一个完整示例调用/v1/chat/completions接口// 文件路径com/example/interview/LlmApiDemo.java import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.time.Duration; public class LlmApiDemo { public static void main(String[] args) throws Exception { // 本地使用Ollama时可以填写 http://localhost:11434/v1/chat/completions String apiKey YOUR_API_KEY; String endpoint http://localhost:11434/v1/chat/completions; String jsonBody { model: qwen2.5:7b, messages: [ {role: system, content: 你是一个Java后端工程师助手。}, {role: user, content: 请用一句话解释RAG。} ], stream: false } ; HttpClient client HttpClient.newBuilder() .connectTimeout(Duration.ofSeconds(10)) .build(); HttpRequest request HttpRequest.newBuilder() .uri(URI.create(endpoint)) .timeout(Duration.ofSeconds(60)) .header(Content-Type, application/json) .header(Authorization, Bearer apiKey) .POST(HttpRequest.BodyPublishers.ofString(jsonBody)) .build(); HttpResponseString response client.send(request, HttpResponse.BodyHandlers.ofString()); System.out.println(response.body()); } }运行后可以看到模型返回的JSON结构其中choices[0].message.content就是生成结果。面试时可以主动说明生产环境不要硬编码API Key需要放到配置中心或密钥管理服务同时要设置合理的超时时间和重试策略。7.4 本地部署大模型数据敏感或离线环境通常需要本地部署大模型。目前最简单的方式是使用Ollama一条命令就能拉取模型并启动服务默认会在11434端口暴露OpenAI兼容接口# 拉取模型并启动模型名和版本以Ollama官方库为准 ollama pull qwen2.5:7b ollama run qwen2.5:7b # 验证API是否可用 curl http://localhost:11434/v1/chat/completions \ -H Content-Type: application/json \ -d {model:qwen2.5:7b,messages:[{role:user,content:你好}],stream:false}本地部署时要注意显存和内存限制7B模型和14B模型对机器配置要求差异很大。面试时如果被问到可以补充一句本地部署优先考虑Ollama、vLLM等工具Java侧直接使用OpenAI兼容协议接入业务代码不需要改。7.5 Function Calling工具调用Function Calling是大模型Agent的核心能力。简单说就是在请求中描述可用的函数列表模型判断需要调用函数时返回函数名和参数后端解析后执行真实接口把结果返回模型模型再根据结果生成