ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

8月Java面试核心考点:并发、Spring与AI应用备考主线

8月Java面试核心考点:并发、Spring与AI应用备考主线 8月是Java开发者跳槽和秋招求职的高峰期。这个时候打开招聘平台会发现大量岗位JD里同时写着Spring、并发编程、分布式、大模型和Agent。很多候选人会纠结过去背熟的Java八股文还有没有用大模型方向又该准备到什么深度。从实际面试反馈来看能连续通过多轮Java面试并拿到Offer的人并不是每道题都背过而是把Java基础、JVM、并发、Spring原理和新话题整理成了一条清晰的知识主线同时形成了一套回答场景题的方法。这篇内容围绕8月Java求职面试的备考主线展开按“考点分层、八股文、并发编程、Spring原理、大模型与Agent、场景题、简历与复盘”的顺序组织。文章里会出现大量面试真题风格的问题、代码示例和排查路径。如果你正在准备跳槽或者校招建议先对照每一章做一次自测把答不上的点标记出来再按文章给出的方法补齐。1. 8月Java面试的考点结构决定了你该先准备什么1.1 面试考核的四层结构Java面试不是单纯考察知识量而是通过不同层次的问题判断候选人“能不能写代码、能不能讲原理、能不能做设计”。从实际面试反馈看可以把常见问题分成四层。层级典型考察点准备重点建议时间占比基础能力Java基础、集合、JVM、并发、网络能画流程、能写出关键代码30%框架原理Spring、Spring Boot、Spring Cloud理解生命周期和设计思想25%场景设计高并发、缓存、消息、分库分表、幂等固定框架加项目结合30%增量方向大模型、Agent、Spring AI、RAG能演示、能讲落地15%这个比例不是绝对标准但能说明一个现象只背八股文已经很难通过面试。面试官更关心你能否把基础知识和实际场景连接起来。比如HashMap的底层结构属于基础层但“多线程并发put会出现什么问题”就属于场景层。再往下问“你会怎么解决”就进入设计层。1.2 面试官先过滤“背题式候选人”很多候选人在准备面试时喜欢背标准答案。面试官只需要连续追问两轮就能判断你是真的理解还是只记住了结论。举个例子候选人背了“HashMap在JDK8中使用数组加链表加红黑树”。面试官如果继续问为什么链表转红黑树选在8这个阈值为什么红黑树的节点数低于6时会转回链表多线程扩容时会不会丢数据如果你来设计一个线程安全的HashMap你会怎么做这些追问没有一个能靠背结论回答。能答好的候选人通常都画过HashMap的存储结构亲手触发过链表转红黑树也看过多线程场景下的异常现象。这类经验不一定是大型项目有时候自己写一个小Demo就能获得。1.3 拿到“10面9过”结果的人是怎么准备的我观察过很多面试结果稳定的候选人他们通常不是刷题最多的而是有一套稳定的备考流程。第一步是建立知识地图。把所有可能被问到的考点整理成问题清单而不是按大纲抄一遍。例如并发模块可以整理成线程池参数、任务执行链路、拒绝策略、synchronized锁升级、AQS原理、volatile可见性、CAS与原子类、ThreadLocal内存泄漏。第二步是每次面试后都做复盘。记录被问到的问题、答不上的点、面试官追问的方向。三天后重新看这些问题如果还是答不好说明没有真正理解。第三步是场景模拟。每学一个原理马上设计一个实际场景。学了分布式锁就想想“集群环境下定时任务重复执行怎么办”学了线程池就想想“订单导出任务突然大量积压怎么处理”。把原理翻译成场景是面试答题能力的核心。这里可以给出一个备考自检清单能不用IDE写出HashMap的put流程和扩容条件。能说清ThreadPoolExecutor七个参数对任务执行的影响。能画出Spring创建Bean的主要步骤。能解释Spring为什么用三级缓存解决循环依赖。能说明RAG和模型微调的区别。能当场写出一个并发库存扣减SQL。能列出JVM OOM时的排查命令和思路。能完整描述自己项目中的一个技术难点和一个业务细节。2. Java基础和JVM考点先整理成能推导的知识网2.1 HashMap不只是背源码关键要画出流程HashMap在Java面试中出现频率很高。它的核心价值在于一次HashMap的提问能同时考察哈希算法、数据结构、并发安全、版本演进和工程取舍。可以把HashMap的put过程拆成下面几步put(key, value) 的大致流程 1. 根据 key 计算 hashCode再做扰动计算得到数组下标。 2. 如果 table[i] 为空直接放入节点。 3. 如果 table[i] 非空遍历链表或红黑树。 4. 如果 key 已存在替换 value 并返回旧值。 5. 如果 key 不存在插入尾部并判断是否需要树化。 6. 树化阈值 TREEIFY_THRESHOLD 默认是 8且数组长度大于等于 64。 7. 插入完成后如果节点总数超过 threshold触发扩容。这里有几个容易混淆的点。第一链表转红黑树需要两个条件某个桶上的链表长度达到8同时数组长度达到64。如果数组长度没到64会优先扩容而不是转红黑树。第二红黑树的节点数降低到6时会转回链表中间留下7这个缓冲值是为了避免在边界上反复转换。第三JDK7的扩容在并发场景下可能形成循环链表JDK8中退化成链表时也可能丢失数据所以HashMap依然不是线程安全的。2.2 JVM内存区域与对象分配JVM是Java面试的高频区。面试官不会只问“堆存什么、栈存什么”更常见的是把内存区域和OOM现象、内存泄漏、GC日志结合起来问。常用内存区域可以整理成一张速查表内存区域存储内容常见异常程序计数器当前线程执行字节码的行号无虚拟机栈局部变量表、操作数栈、方法调用StackOverflowError本地方法栈native方法调用StackOverflowError堆对象实例、数组OutOfMemoryError: Java heap space元空间类元信息、常量、静态变量OutOfMemoryError: Metaspace对象创建过程也可以按顺序说出来类加载检查、分配内存、内存空间初始化零值、设置对象头、执行构造方法。这个顺序在Java面试中很常见因为后面会自然引出“为什么对象属性有默认值”这类问题。2.3 经典OOM排查路径在命令行或IDE里看到java: OutOfMemoryError: insufficient memory时第一步不是改大内存而是判断内存到底去哪了。这个错误信息比较笼统可能是Java堆空间不足也可能是线程栈过多还可能是容器内存限制导致进程无法申请内存。常规排查命令如下# 查看Java进程pid jps # 查看GC情况每1秒输出一次 jstat -gcutil pid 1000 # 查看当前堆配置 jmap -heap pid # 导出堆快照供MAT分析 jmap -dump:formatb,fileheap.hprof pid # 查看线程栈 jstack pid # 新版本JDK更推荐用jcmd导出堆 jcmd pid GC.heap_dump /tmp/heap.hprof如果是在IDEA里本地运行出现“insufficient memory”先检查启动配置里的-Xmx是否设置过大同时确认本机可用内存是否充足。生产环境则要检查JVM参数、容器内存上限、应用的GC日志和内存增长曲线。推荐在启动参数里加上-XX:HeapDumpOnOutOfMemoryError -XX:HeapDumpPath/opt/logs这样OOM发生时能自动留下堆快照后续用MAT或JProfiler分析更高效。2.4 常见坑Lombok与编译器版本不兼容本地编译时如果出现类似java: you arent using a compiler supported by lombok, so lombok will not work的错误先不要改业务代码。这个错误的常见原因是Lombok版本和当前JDK版本不匹配或者IDE内置编译器与Lombok不兼容。处理顺序是先看项目JDK版本再看Lombok版本然后检查IDE的Java Compiler设置是否和项目一致。Maven项目中可以在pom里显式指定Lombok版本dependency groupIdorg.projectlombok/groupId artifactIdlombok/artifactId version1.18.34/version scopeprovided/scope /dependency注意版本号只是示例实际选择时要结合JDK版本确认兼容性。另一个预防方式是在CI环境里统一JDK版本避免本地用JDK21编译、CI用JDK17编译导致行为不同。3. 并发编程是拉开差距的板块线程池和锁原理必须能讲清楚3.1 线程池从参数到执行链路并发编程是Java面试中区分度最高的板块。很多候选人能说出线程池的参数但问到“任务提交后到底走哪条分支”时就开始混乱。线程池的执行链路其实只有四步调用 execute(command) 时 1. 如果当前工作线程数 corePoolSize创建核心线程执行任务。 2. 如果核心线程已满任务进入 workQueue。 3. 如果队列已满且工作线程数 maximumPoolSize创建非核心线程。 4. 如果线程数已达到 maximumPoolSize执行拒绝策略。ThreadPoolExecutor的核心参数可以整理成表格参数作用注意点corePoolSize核心线程数核心线程默认不会回收maximumPoolSize最大线程数必须大于 corePoolSizekeepAliveTime非核心线程空闲存活时间配合 TimeUnit 使用workQueue任务队列有界队列和无界队列差别很大threadFactory线程工厂建议必填用于区分线程名handler拒绝策略默认是 AbortPolicy实际开发中推荐创建带线程名的ThreadPoolExecutor方便排查线程问题。一个参考写法ThreadPoolExecutor executor new ThreadPoolExecutor( 4, 8, 60L, TimeUnit.SECONDS, new ArrayBlockingQueue(1000), new ThreadFactoryBuilder().setNameFormat(order-task-%d).build(), new ThreadPoolExecutor.CallerRunsPolicy() );这种配置适合“请求量有波动但整体可控”的业务。核心线程4个、最大8个、队列1000意味着突发流量先排队把并发控制在合理范围。拒绝策略用CallerRunsPolicy时会让提交任务的线程自己执行任务这样不会丢任务但会阻塞调用方需要评估是否影响主流程。3.2 volatile、synchronized与AQSvolatile解决的是可见性和有序性问题核心是内存屏障。它不保证原子性。面试官经常问“volatile能不能替代synchronized”答案是不能因为volatile无法保证多个线程对同一变量的复合操作是原子的。synchronized从JDK6开始有锁升级过程无锁、偏向锁、轻量级锁、重量级锁。锁升级的设计目的是让锁在竞争不激烈时开销更小。面试时可以补充一个观点偏向锁在JDK15之后已经被标记为废弃说明锁竞争的判断策略也在演进不能只背旧结论。AQS是ReentrantLock、Semaphore、CountDownLatch的底层基础。它的核心是一个volatile int类型的state状态值和一个双向队列。理解AQS不需要背每个源码方法关键是想清楚获取锁失败时线程如何进入队列释放锁时如何唤醒后继节点。3.3 并发场景题怎么答并发场景题通常不是单个知识点而是多个知识的组合。比如“秒杀库存扣减怎么实现”需要同时考虑原子性、数据库压力、超卖和用户体验。一个稳妥的回答路径是先确认边界条件库存量多少、并发量多大、允许少量超卖吗。然后给出分层设计请求先行限流库存扣减走Redis的原子操作最终数据库做一致性保证。数据库层的经典写法是UPDATE t_stock SET stock stock - 1 WHERE sku_id #{skuId} AND stock 0;执行后返回更新行数如果大于0说明扣减成功等于0说明库存不足。这样的SQL能避免先查询再更新带来的超卖问题。更复杂的场景还要考虑Redis库存和数据库库存的一致性以及消息队列对订单流程的异步削峰。3.4 常见坑拒绝策略与线程池滥用很多候选人在项目中只是new了一个固定线程池从没考虑过拒绝策略。面试官如果问到“线程池满了会怎样”就很容易答不上来。四种JDK自带拒绝策略对比如下策略行为适用场景AbortPolicy直接抛出 RejectedExecutionException必须马上发现问题的场景CallerRunsPolicy调用方线程自己执行任务不想丢任务可接受阻塞DiscardPolicy直接丢弃任务不推荐用于核心业务DiscardOldestPolicy丢弃队列中最老的任务可接受部分任务被丢弃实际项目里不建议使用默认的AbortPolicy因为直接抛异常可能导致调用方不稳定。更安全的做法是自定义拒绝策略在任务无法执行时记录日志并发送告警至少保留排查线索。另一个常见坑是使用无界队列。new LinkedBlockingQueue(没有指定容量)会把所有任务堆积在队列里maximumPoolSize形同虚设。更危险的是内存不受控制服务可能因为任务积压而OOM。核心业务场景建议使用有界队列并配合监控观察队列长度。4. Spring原理三级缓存不是必须背而是要能解释为什么4.1 Bean生命周期和三级缓存Spring面试题中最容易被追问的就是三级缓存。很多候选人能背出三个缓存的名称却说不清为什么要设计成三级。这里先明确Bean生命周期里和循环依赖相关的几个阶段实例化、属性填充、初始化。循环依赖发生时A需要注入BB又需要注入A。如果A在实例化之后马上把对象引用暴露出去B就能提前拿到A完成属性填充。三个缓存的职责可以这样理解一级缓存singletonObjects存放完整的、已经完成初始化的单例Bean。二级缓存earlySingletonObjects存放提前暴露的早期对象。三级缓存singletonFactories存放对象工厂用来在必要时生成代理对象。Spring在获取单例Bean时会按一级、二级、三级缓存的顺序查找。简化后的逻辑如下protected Object getSingleton(String beanName, boolean allowEarlyReference) { Object singletonObject this.singletonObjects.get(beanName); if (singletonObject null isSingletonCurrentlyInCreation(beanName)) { singletonObject this.earlySingletonObjects.get(beanName); if (singletonObject null allowEarlyReference) { ObjectFactory? singletonFactory this.singletonFactories.get(beanName); if (singletonFactory ! null) { singletonObject singletonFactory.getObject(); this.earlySingletonObjects.put(beanName, singletonObject); this.singletonFactories.remove(beanName); } } } return singletonObject; }这段代码里最关键的是最后一步从三级缓存拿到ObjectFactory后会立即把结果放入二级缓存并移除三级缓存。这是为了确保同一个Bean在循环依赖中只会被提前初始化一次避免后续拿到不同的对象。4.2 为什么不能只用一级或二级缓存如果只用一级缓存Bean还没有完成初始化就直接放进单例池后续其他线程可能拿到半成品对象这显然不行。如果只用二级缓存理论上可以解决普通对象和代理对象的提前暴露问题但前提是创建代理的逻辑必须发生在属性填充之前。Spring创建Bean时AOP代理通常是在BeanPostProcessor的后置处理阶段生成的而属性填充又发生在这个阶段之前。于是Spring用三级缓存保存一个ObjectFactory在真正需要提前引用时由ObjectFactory决定返回普通对象还是代理对象。这个过程兼顾了循环依赖和AOP代理的时序问题。面试时能回答到“三级缓存是为了让AOP代理在循环依赖场景下也能正确生成”就已经超过了大多数候选人。4.3 Spring AI与Spring Cloud的面试增量随着大模型应用进入后端开发日常Spring AI开始出现在岗位JD里。Spring AI可以理解为一个站在模型和业务之间的应用框架它封装了模型调用、Prompt模板、结构化输出和向量数据库集成让Java开发者可以用更统一的方式接入大模型。如果项目里用到Spring AI面试官很可能会追问结构化输出。比如让模型返回一个固定JSON结构并且直接映射成Java实体类可以这样设计public record OrderInfo( String orderId, String status, Integer amount ) {}调用时把实体类信息传给模型框架负责约束模型输出格式再反序列化为对象。这种写法比直接解析字符串更稳定也更容易在代码里做后续处理。Spring Cloud依然是中高级岗位的高频考点。注册中心、配置中心、网关、熔断、链路追踪这些概念不能只停留在名词层面至少要能说出选型依据和常见问题。比如Nacos配置修改后为什么有时候不生效就要从客户端加载配置、监听器刷新和本地缓存三个层面分析。5. 大模型与Agent从“听过”到“能聊深”5.1 面试官为什么问大模型大模型已经成为很多Java岗位的加分项甚至部分岗位把“熟悉Agent开发”写在JD里。面试官考察的其实不是让候选人去训练模型而是看候选人是否具备AI应用落地的基础认知。能讲清楚调用大模型接口、处理上下文、接入知识库、搭建Agent已经可以证明学习能力。如果完全没有准备遇到大模型问题直接说“我还没有做过”也可以接受但最好提前做一个最小Demo因为8月的竞争环境中有AI经验的人比例正在提升。5.2 必须掌握的三个概念Token是模型处理文本的最基本单位。中英文、数字、符号都会占用不同数量的Token面试中不需要深入分词细节但要能说明上下文窗口和Token长度的关系。上下文窗口决定了模型一次能接收多少内容。窗口有限时长文本需要做切片、摘要或检索。RAGRetrieval-Augmented Generation检索增强生成就是在生成前先从外部知识库检索相关片段把片段拼进提示词再让模型基于参考内容回答。RAG和微调的区别很常见可以这样理解RAG不改变模型权重适合知识库和实时信息更新微调会调整模型权重适合固定风格、固定格式或特定领域的输出。很多面试场景下RAG是更快的落地方案微调成本更高不一定适合每次需求。5.3 本地部署大模型与Spring AI集成如果个人电脑有独立显卡可以尝试本地部署一个相对轻量的开源模型再通过Spring AI接入。本地部署的完整步骤会涉及模型下载、量化方式和推理框架选择。不同环境差异很大面试时不需要背版本号但要能说出自己部署时用了什么模型、显存占用多少、推理速度如何。Spring AI接入本地模型的配置可以参考下面这种结构具体地址和模型名要按实际服务调整spring: ai: openai: base-url: http://localhost:11434/v1 api-key: local-key chat: options: model: qwen2.5:7b这里的base-url指向本地模型服务的OpenAI兼容接口。Java代码里可以通过ChatClient完成一次对话调用。结构化输出示例ChatClient chatClient ...; OrderInfo info chatClient.prompt() .user(从下面订单描述中提取订单号、状态和金额客户A下单成功金额200元) .entities(OrderInfo.class) .call();运行前要确认模型服务正常、实体类字段和模型输出一致不然反序列化会失败。这个例子很小但足以让候选人在面试时说清楚“我调用过模型接口并且处理过结构化输出”。5.4 Agent开发的常见问题Agent是当前大模型应用开发的热点。它的本质可以概括为“模型加规划、记忆和工具调用”。面试官问Agent项目时通常关注几个问题Agent如何选择工具如何管理多轮对话记忆如何避免模型陷入无效循环。实际运行中一个很典型的问题是超时。如果看到the agent execution provider did not respond in time这类错误说明执行器在指定时间内没有返回结果。可能的原因包括模型推理时间过长、外部工具执行卡住、网络超时。处理优先级是先确认模型服务健康状态再检查工具调用链条然后调整超时时间和重试策略。Agent开发在学习环境中可以先用固定流程跑通用户输入、模型判断意图、调用指定工具、把结果返回给模型、模型生成最终回答。不要一开始就设计过于复杂的自主规划否则排错难度会大幅上升。5.5 常见坑把大模型能力说成部署过面试中最容易翻车的写法是简历里写“熟悉大模型部署”但被问到具体参数时讲不清楚。如果只跑过Demo就写“了解”或“初步尝试”。面试官并不要求每个人都本地部署过70B以上参数的大模型更看重候选人是否理解部署成本、量化精度和显存约束。另一个坑是混淆本地部署和API调用。本地部署意味着模型运行在自己的服务器或电脑上需要考虑显存、CPU、推理框架和并发能力API调用是远程服务需要关注接口协议、鉴权和成本。这两个方向侧重点不同不要混着讲。6. 场景题和系统设计题用一套固定框架应答6.1 场景题通用四步场景题考察的是候选人面对不熟悉的问题时如何拆解和设计。很多候选人答不好是因为拿到题目直接给方案忽略了边界条件。推荐使用下面四步明确边界并发量大概多少数据量级是多少一致性要求是什么能否接受短暂不可用。选型根据边界选择缓存、消息队列、数据库、分布式锁等组件。画流程说清请求进来后经过哪些模块数据如何流转。说兜底重试、降级、补偿、监控和报警怎么做。例如“秒杀系统怎么设计”这道题直接回答“用Redis”会很单薄。如果先问“参与人数多少、库存多少、是否允许排队”再给出限流、扣库存、下单、支付的设计质量会完全不同。6.2 高频场景题三个第一个是接口幂等。支付回调、订单提交这类接口必须幂等。常见方案有每次请求带唯一token并缓存token、在数据库表中用唯一键约束、使用乐观锁或状态机判断。具体选哪种要看业务是不是对性能敏感。第二个是MQ消息积压。先确认消费者的消费速度和生产速度的差距再决定扩容消费者、批量消费还是关闭下游耗时的逻辑。排查时要关注消费者是否阻塞、是否有异常重试导致消息不断消费失败以及队列积压量是否触发告警。第三个是缓存穿透、击穿、雪崩。穿透可以用布隆过滤器或缓存空值击穿可以用互斥锁或逻辑过期雪崩可以从过期时间上规避比如给缓存设置随机过期时间。// 给缓存过期时间增加随机值避免同一批key同时失效 long expire baseTtl ThreadLocalRandom.current().nextLong(300, 600);回答这类题时不要只背方案名称要说出每种方案的成本和局限。比如布隆过滤器存在误判空值缓存会有短暂不一致互斥锁会降低并发量。这些取舍才是面试官真正想听的。6.3 系统设计题如何展示能力系统设计题通常只有30到40分钟候选人不可能把完整工程讲完。关键是展示设计思路和结构感。建议先画模块图再写清楚每个模块的职责最后落到存储选型和扩展方式。比如设计一个短链接系统可以从生成短码、存储映射、重定向、统计访问量、清理过期链接几个模块展开。存储上可以选择数据库存储映射关系再用Redis做热点访问缓存。如果进一步讨论分库分表就要说明采用什么分片键、为什么选它。能说出“我的Redis和MySQL数据可能不一致但可以通过过期时间或消息队列补偿”这样的思考比背一套标准架构更有价值。7. 简历项目和面试节奏是最后的安全网7.1 简历项目怎么写技术能力准备得再充分简历写不好也容易在筛选阶段被刷掉。项目经验的写法建议用“背景、任务、行动、结果”的结构不要只写“我负责了订单模块开发”这种流水账。可以用一张表格呈现项目里最容易被追问的内容项目模块技术点面试官可能追问库存扣减Redis缓存、数据库乐观锁超卖、缓存一致性、降级AI客服Spring AI、RAG召回质量、上下文管理、性能审批流状态机、异步任务状态流转、事务边界、重试每个项目写上去之前都要问自己如果面试官从第一行问到最后一行的参数和日志我能不能答上来。不能答上来的内容不要写因为面试官更关注你是否对每个细节负责而不是项目数量多不多。7.2 面试复盘面试复盘比面试本身更重要。一次面试结束后立刻记录这些问题面试官问了哪些问题。哪些问题没答好。没答好是因为“不知道”还是“表达混乱”。回答过程中有没有被明显打断。下次回答同一个问题时第一句该说什么。连续复盘三到五场面试之后通常能发现自己固定的短板。有些人卡在JVM参数有些人卡在并发场景题有些人卡在项目细节讲不清楚。发现短板后花两天集中补齐再做下一轮投递。7.3 8月期间的求职节奏建议不要把投简历和面试排得太密集。建议先花一周整理知识主线和项目Demo再开始投递。同一天不要安排三场以上面试否则没有足够时间复盘。算法题的准备要保持手感。不需要每天刷很多难题而是定期练习链表反转、二叉树遍历、动态规划基础题型和冒泡排序这类必须熟练掌握的题目。面试中算法题卡壳时先讲暴力解再逐步优化比直接沉默更有利于通过。如果目标是短期拿到Offer优先保证以下几件事能当场写出线程池配置和库存扣减SQL能把Spring三级缓存讲清楚能本地跑通一个Spring AI调用模型的小Demo能对简历里每个技术点解释“为什么这么做”。这四项覆盖了Java面试最核心的区分点补齐之后面试的成功率会明显提高。面试不是把所有题背下来而是把知识点变成可推导、可演示、可延伸的能力。8月这个时间窗口机会多竞争也激烈。花一周整理主线再用项目经历支撑表达比盲目刷题更有效。对准备大模型方向的候选人建议从本地部署一个开源模型开始用它跑通Spring AI的调用和结构化输出。这一步会让面试中很多新话题都落地到真实经验上。
返回列表