刷到这个标题的多半是正在准备Java面试而且多半心里没底。我先说句实话15天突击Java面试这事儿能成但有前提——你不是零基础。如果你连环境变量配置、面向对象编程、数组越界异常这类基础都还没整明白那15天突击的不是面试是玄学。这篇文章就是给那些有Java基础但没系统刷过题、时间又紧的人准备的我按真实面试场景把高频考点、答题思路、以及一份能直接照抄的15天排期全摊开讲每一块都是我自己面试别人和被别人面试时验证过的干货。1. 先泼盆冷水15天突击不是速成而是有基础的人的系统化止损很多人一上来就搜Java面试八股文大全然后一头扎进去背。这个方向不对。15天的时间窗口里你最该做的不是学新东西而是把已经会的东西重新组织成面试官想听的答案。面试官视角下所谓基础扎实指的不是你背了多少题而是三个能力能不能把一个知识点从上到下讲清楚比如从ArrayList扩容讲到数组拷贝原理、能不能把多个知识点串起来从synchronized讲到锁升级再讲到AQS、能不能在追问下不慌突然问一句那HashMap为什么不安全你就卡壳前面积累的好感全没了。所以15天本质上是止损——把刷题、背答案的无效努力收一收换成有优先级、有反馈的刻意练习。这个阶段最忌讳三件事瞎刷题每天看二十道题一道都没吃透纯属自欺欺人。抱着八股文死背背下来了但理解是断层的面试官换个角度问就露馅。把时间浪费在环境配置上如果你还在折腾JDK版本、IDE插件之类的说明你基础远没到能突击的水平先去补基础。突击的前提是底子已经在了。比如运算符优先级、标识符命名规则、数组越界这种基础题如果你还要翻书那说明你要补的不是面试题是Java SE本身。下面默认你已经过了这一关。2. 第一周主线集合、并发、JVM这三座大山这么啃才有效第一周的目标很明确把面试区分度最高的三块——集合源码、并发编程、JVM——全部过一遍并且要求自己能脱离笔记讲出来。这三块是Java面试的必考重点也是最能拉开差距的地方。2.1 集合类源码ArrayList扩容、HashMap的put流程必须能背能画集合类是Java基础面试题的开胃硬菜几乎场场必考。我说几个最核心的你对照自测一下ArrayList扩容机制底层是Object数组默认无参构造的容量是0第一次add时扩容为10之后每次扩容按1.5倍oldCapacity oldCapacity 1最后用Arrays.copyOf底层是System.arraycopy拷贝到新数组。面试官常追问的坑点在于ArrayList的默认容量是多少答不上来或者答成10都是错的是0懒加载。HashMap是重头戏。JDK8版本的底层结构是数组链表红黑树。put流程要能画出来先对key的hashCode做扰动hash函数(h key.hashCode()) ^ (h 16)然后通过 (n - 1) hash 定位到桶下标如果桶是空的直接newNode放入如果不为空判断首节点key是否相同相同就覆盖否则判断当前节点是不是红黑树节点是就走红黑树插入不是就遍历链表插入链表长度超过8且数组长度超过64才转红黑树最后检查size是否超过threshold数组长度*负载因子0.75超过就resize扩容为两倍。面试官随便换个角度问你就能判断你是背的还是理解的比如HashMap为什么线程不安全——JDK7扩容时头插法可能形成环形链表导致死循环JDK8改成尾插法但put时多线程同时执行modCount赋值操作count会丢失而且并发resize也会出问题。ConcurrentHashMap的演进也是高频JDK7是分段锁SegmentJDK8改成CAS synchronized锁头节点。为什么要改分段锁粒度太大锁的竞争还是集中在Segment上JDK8锁粒度细化到桶并发度几乎是之前数倍。2.2 并发编程别死背synchronized和Lock的区别要会讲从锁升级到AQS并发这一块面试官最反感的就是你上来背synchronized是悲观锁Lock是乐观锁这种贴标签式的答案。正确讲法是从锁升级说起。synchronized在JDK6之后引入了偏向锁、轻量级锁、重量级锁的升级路径锁对象头里Mark Word会记录锁状态。无竞争时偏向锁单个线程反复获取一旦出现竞争升级为轻量级锁自旋CAS尝试获取自旋超过阈值或线程数过多升级为重量级锁阻塞挂起。所以现在的synchronized并不是无脑重量级。Lock体系的核心是AQSAbstractQueuedSynchronizer。你只要能讲清楚AQS的本质就够了一个volatile的state状态位 一个双向CLH队列加锁失败就入队阻塞释放锁就唤醒队首节点。ReentrantLock、Semaphore、CountDownLatch、ReentrantReadWriteLock全部基于它。线程池这块也必须滚瓜烂熟。核心参数七个核心线程数、最大线程数、空闲存活时间、时间单位、阻塞队列、线程工厂、拒绝策略。执行流程一句话版本提交任务时核心线程没满就开新线程满了进阻塞队列队列满了开非核心线程线程数到最大了执行拒绝策略。拒绝策略有四种AbortPolicy抛异常、CallerRunsPolicy调用者自己执行、DiscardPolicy悄悄丢掉、DiscardOldestPolicy丢最旧的。ThrealLocal也是个经典考点。核心是每个线程有一个ThreadLocalMap以ThreadLocal为key。面试追问的高频坑是内存泄漏key是弱引用value是强引用如果ThreadLocal对象被回收但线程还在value永远清不掉所以用完记得remove。2.3 JVM内存模型和GC问题用讲故事的方式答而不是背结论JVM是很多人的噩梦但其实面试其实只会在几个点上深挖。你必须能画出来或者说清楚运行时数据区堆Heap对象实例主要分配在这里也是GC的主战场内部又分新生代Eden、Survivor From、Survivor To和老年代。虚拟机栈VM Stack每个线程私有里面存栈帧局部变量表、操作数栈、动态链接、方法返回地址。方法区Method Area类信息、常量、静态变量JDK8之后由元空间实现。程序计数器记录当前线程执行的字节码行号。本地方法栈native方法。GC的判断核心是可达性分析从GC Roots出发向下搜索不可达的对象判定为可回收。那GC Roots包括哪些栈帧中的局部变量引用、静态变量引用、JNI引用、常量引用。这里注意一个高频陷阱引用计数法为什么不行循环引用会导致误判——A引用B、B引用A但没有其他引用时两者都该被回收引用计数却判断为1。垃圾收集器这块JDK8默认是Parallel Scavenge Parallel OldJDK9以后G1成了默认。CMS在JDK14被移除。G1的特点是Region分区可预测停顿时间把堆分成很多相等Region通过维护RSet来跟踪跨Region引用。你至少要能答出G1和CMS的区别、G1的remember set是干嘛的、什么时候会触发Full GC晋升失败、元空间不足、System.gc调用等。类加载过程五步加载、验证、准备、解析、初始化。双亲委派模型要讲明白类加载器收到加载请求先委派给父加载器父加载器加载不了才自己加载。好处是什么防止核心类被篡改比如你自己写个java.lang.String也加载不了会被引导类加载器拦截。热词里还有个java: OutOfMemoryError: insufficient memory其实面试更常考的是OutOfMemoryError和StackOverflowError的区别以及OOM的几种类型堆溢出、栈溢出、元空间溢出、直接内存溢出遇到OOM第一反应是用jmap dump堆转储、再用MAT分析。2.4 Java语言基础面向对象、枚举、Lambda这些送分题别丢分这一节是保底分但很多人在简单题上翻车。面向对象三大特性封装、继承、多态。多态的实现机制是动态绑定——编译看左边运行看右边通过方法表和方法重写实现。重载是编译期静态分派重写是运行期动态分派很多人连这个区别都说不全。接口与抽象类的区别别只用有没有构造方法、能不能多继承这种肤浅的答法。核心是设计理念抽象类是是什么的关系is-a接口是能做什么的关系has-a/behavable接口强调的是行为契约而且JDK8之后接口可以有default方法和静态方法。Java是单继承多实现目的就是规避菱形继承问题。枚举类型的使用也常出小题枚举本质上是一个final的类声明的每个枚举常量都是该类的静态final实例。可以带字段、构造方法、抽象方法。常见考点枚举如何保证单例枚举在序列化和反射场景下天然防漏——序列化通过readResolve保证单例反射的newInstance对枚举直接抛异常。这都是我面试时最喜欢拿出来问的细节点。Lambda表达式和函数式接口也是标配。一个函数式接口就是只有一个抽象方法的接口比如Runnable、Comparator、Predicate。Lambda本质是语法糖编译后生成invokedynamic调用实际是创建了函数式接口的实例。Stream API最常用的操作filter、map、flatMap、distinct、sorted、peek、limit、skip、reduce、collect注意流是惰性求值的中间操作不会真正执行只有遇到终端操作才触发。3. 第二周主线Spring、MySQL、Redis、项目经验一天一块硬骨头第二周开始从语言切换到生态。现在Java岗位面试Spring、MySQL、Redis几乎是三驾马车哪个都有可能成为压垮你的最后一根稻草。3.1 Spring Bean生命周期从源码角度拆别只顾着背口诀网上流传那个实例化、属性赋值、初始化、销毁四步口诀只能说勉强及格。面试官更想听到的是BeanDefinition读取与注册 → 实例化构造器或工厂方法→ 属性填充populateBean依赖注入发生在这里→ 各种Aware接口回调BeanNameAware、BeanFactoryAware、ApplicationContextAware→ BeanPostProcessor的postProcessBeforeInitialization → PostConstruct / InitializingBean.afterPropertiesSet / 自定义init-method → BeanPostProcessor的postProcessAfterInitializationAOP代理通常在这里生成→ 使用 → 销毁PreDestroy / DisposableBean.destroy。Spring循环依赖也是必问。需要能讲清楚三级缓存是怎么回事一级缓存singletonObjects放成品对象二级缓存earlySingletonObjects放提前暴露的半成品三级缓存singletonFactories放对象的ObjectFactory工厂。核心逻辑是A创建时发现依赖B于是把A的工厂放进三级缓存B创建时依赖A从三级缓存拿到A的工厂生成早期引用放到二级缓存B完成创建后A从二级缓存拿到B完成注入。为什么是三级不是二级因为需要给AOP代理留机会——如果A被代理了早期暴露的应该是代理对象而不是原始对象。Spring事务的传播行为也要能答出几个常用的REQUIRED默认有事务就加入没有就新建、REQUIRES_NEW挂起当前新建、NESTED嵌套事务。失效场景常考方法自调用不走代理、方法不是public、异常被try-catch吞掉、propagation配置错误、数据库引擎不支持事务。Spring Boot自动装配原理SpringBootApplication里包含EnableAutoConfiguration它通过AutoConfigurationImportSelector加载META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports里的所有配置类再按ConditionalOnClass、ConditionalOnMissingBean等条件注解决定是否生效。核心是约定大于配置。3.2 MySQL索引与SQL优化面试官最爱扔给你的场景题MySQL这块索引是绝对核心。你要能讲清楚为什么用B树因为B树非叶子节点只存索引不存数据一个页能存更多索引树高度低叶子节点用链表串起来范围查询高效天然有序排序和分组也能用到。红黑树为什么不行高度太高IO次数多。哈希索引为什么不行不支持范围查询。接着是聚簇索引vs二级索引、回表和覆盖索引。InnoDB主键是聚簇索引叶子节点直接存整行数据二级索引叶子节点存主键值。所以查询通过二级索引时先找到主键值再回聚簇索引查整行这就是回表。覆盖索引就是查询字段都在二级索引里不用回表。最左前缀原则联合索引(a,b,c)查询条件里有a才能用到这个索引a、b有也还行直接查b是用不到的。最佳实践区分度高的列放前面、频繁查询的列放前面、范围查询的列放后面。SQL优化现场肯定会让你说几条explain看执行计划的typeconst eq_ref ref range index ALL、避免select *、where中避免对索引列做函数运算如where YEAR(create_time)2024这样索引会失效、like %xxx走不了索引但like xxx%可以、order by/group by尽量索引覆盖。3.3 Redis缓存穿透、击穿、雪崩用一套电商案例串起来Redis面试题的套路就是缓存三兄弟一个分布式锁。三个问题本质是对缓存失效的三种不同场景缓存穿透查一个不存在的key每次请求都打到数据库。解决办法对空值也缓存短期、布隆过滤器拦截。缓存击穿某个热点key突然过期大量并发打到数据库。解决办法热点key不设置过期时间或设置逻辑过期、加互斥锁分布式锁、后台刷新。缓存雪崩大量key同一时间过期或者Redis宕机。解决办法过期时间加随机值、多级缓存、Redis集群高可用。持久化也要会讲RDB快照、AOF追加日志。AOF的三种刷盘策略always每次写命令都同步、everysec每秒同步、no交给操作系统。面试爱问如果Redis宕机恢复如何保证数据不丢或者少丢一般答AOF 定期RDB全量备份混合持久化Redis 4.0以后默认开了aof-use-rdb-preamble。分布式锁的经典实现是SETNX 过期时间需要注意原子性问题设置值和设置过期时间必须原子SET key value NX EX 1000释放锁时要先比较value再删除防止误删别人的锁value可以用UUID。进阶一步就是用Redisson的看门狗机制自动续期。3.4 项目经验怎么讲STAR法则在Java面试中的变体第二周的最后一天必须把项目这块理顺。这是很多人翻车最严重的地方——技术问题全答对了一聊项目就讲流水账我做了个管理系统有用户模块、订单模块……。正确的讲法是【背景-难点-方案-结果】四段式。先一句话说项目背景比如用户量从1万涨到100万再说你遇到的最大技术难点比如高峰期订单查询慢然后说你的方案怎么优化索引、加了Redis缓存、做了读写分离最后说结果接口响应时间从2秒降到200ms。不要面面俱到挑2-3个有技术含量的点深度讲。我之前面过一个候选人项目里有个分布式定时任务重复执行的问题他能从SchedulerLock讲到Redis分布式锁再讲到xxl-job的选主机制这种深度比做一堆功能有用多了。还有一个坑简历上写了的技术栈你一定要能扛住追问。写了熟悉JVM调优结果连jstat、jmap、jstack怎么用都说不出来面试官对你的信任直接崩塌。宁可少写不要写虚的。4. 最后两三天算法冲刺、错题复盘、模拟面试一个都不能少很多人的第15天是在焦虑和刷手机里度过的。其实最后的72小时安排好了提分空间比前面两周还大。4.1 高频手撕算法不是刷题是按题型过Java面试的手撕代码考的主要是基础数据结构和简单算法几乎不会出ACM难度。热词里出现了冒泡排序java和快速排序java实现这其实透露出一个信号排序算法是手撕代码的重灾区。我建议按题型过而不是按题号刷。每个题型练熟2-3道题再找同类题快速过。优先级大概是数组与双指针两数之和、三数之和、移动零→ 链表反转链表、合并两个有序链表、环形链表→ 二叉树前中后序遍历递归和非递归、层序遍历、最近公共祖先→ 字符串最长回文子串、无重复字符的最长子串→ 栈和队列有效括号、最小栈→ 排序快速排序、归并排序、堆排序有时间再看到动态规划爬楼梯、最长递增子序列、01背包。快速排序必须能手写。核心思想是分治Partition要能讲清楚为什么平均复杂度是O(n log n)、最坏为什么退化成O(n^2)每次选的pivot是最大或最小值、怎么优化随机选pivot、三数取中、短子数组改插入排序。一段能直接用的双路快排代码在下面这个写法不容易出bugpublic class QuickSort { public void quickSort(int[] nums, int left, int right) { if (left right) return; // 随机选pivot避免最坏情况退化成O(n^2) int idx left new Random().nextInt(right - left 1); swap(nums, left, idx); int pivot nums[left]; int i left, j right; while (i j) { while (i j nums[j] pivot) j--; while (i j nums[i] pivot) i; if (i j) swap(nums, i, j); } nums[left] nums[i]; nums[i] pivot; quickSort(nums, left, i - 1); quickSort(nums, i 1, right); } private void swap(int[] nums, int i, int j) { int tmp nums[i]; nums[i] nums[j]; nums[j] tmp; } }4.2 模拟面试怎么还原真实面试场景模拟面试一定要做这是15天里性价比最高的事。具体怎么做找人帮你面朋友、同事、群友都行或者自己对着录音设备讲。每次模拟45分钟模拟真实面试节奏先自我介绍1分钟然后基础知识问答20分钟再手撕代码10分钟最后情景题10分钟全程录音。模拟完回放录音你的问题全在细节里是不是答到一半开始嗯啊半天是不是第一句话就暴露答案错误是不是题目听都没听完就开始作答我见过太多人心里懂但嘴上说不清这只能靠练。练的时候注意两点不要背答案用先结论后展开的方式组织语言先说是什么再说原理最后说应用场景被追问就顺势往下讲不会就坦白这块我目前了解得比较浅但我理解的XX部分是……千万不要编。最后一天做两件事把之前做过的模拟面试录音重新听一遍整理出自己反复卡壳的知识点单独记一页考前速记然后把简历过一遍确保每个技术名词都能展开至少3分钟的讲述。这两项做完你上考场的底气会完全不一样。5. 那些让我印象深刻的Java面试题看似简单处处是坑这个章节我挑几道面试现场出现频率高、又特别容易答翻车的题给出完整的答题思路你可以直接拿去对照练。5.1 final、finally、finalize三兄弟的区分这是经典中的经典。final是修饰符可以修饰类不能被继承、方法不能被重写、变量引用不能变或者值不能变注意引用类型的final只是引用不可变对象内容可变。finally是try-catch-finally里的兜底块不管是否异常都会执行但有特例System.exit()会终止JVMfinally不会执行。finalize是Object类的一个方法在对象被GC回收前调用但JDK9之后已经标记为废弃因为调用时机不确定且可能复活对象早就不用它做资源清理了。答题时最后可以补一句资源清理用try-with-resources实现了AutoCloseable瞬间拉升层次。5.2 Integer缓存与比较题目通常是Integer a 100; Integer b 100; a b 结果是Integer c 200; Integer d 200; c d 结果是答案是true和false。原因Integer内部有缓存-128到127范围内的值通过valueOf返回的是缓存对象所以a和b指向同一个对象比较地址相等超出范围的每次new一个新对象c和d地址不同。更深一层Integer使用享元模式设计用缓存减少对象创建。这种题一出现很多人栽在比较的是引用这一点上。如果把第三题改成a.equals(b)那就一律true因为Integer重写了equals比较的是int值。5.3 从输入URL到页面展示这个老八股还能怎么答出区分度这个是Java面试八股文里的常青树。常规答法是DNS解析→TCP三次握手→HTTP请求→服务器处理→HTTP响应→浏览器渲染这种答案只能得及格分。你能往上加分的地方在于把DNS解析说细客户端缓存、本地hosts、递归/迭代查询在TCP三次握手前强调先查HTTP缓存、判断是否走HTTPS加一次TLS握手描述服务端接收到请求后Java程序的处理链路Tomcat线程池→Servlet容器→DispatcherServlet→Controller→Service→ORM→Database数据库返回后再说出Spring的返回机制、HTTP响应状态码。每个环节被追问时你都能接住这道题就能让面试官对你好感大增。5.4 线上系统突然OOM了怎么排查热词里出现了java: outofmemoryerror: insufficient memory虽然这句更像是编译器报错但OOM如何排查是Java面试里非常典型的场景题压力题。完整的排查思路是先别乱重启保留现场。用jps找到进程号再用jmap -dump:formatb,fileheap.bin 导出堆转储然后用MAT或者JProfiler分析大对象、深堆、支配树看是不是某个集合对象无脑往里面放数据没清空配合jstack看线程栈是否有阻塞最后根据堆内存类型判断是堆溢出java.lang.OutOfMemoryError: Java heap space还是元空间溢出Metaspace还是直接内存溢出。答题的核心是展现有排查方法论而不是直接背命令。5.5 重载和重写怎么在30秒内讲得比所有人都清楚这道题太基础了以至于很多人不屑于准备结果面试时答得支离破碎。你需要能在30秒内讲清楚重载Overload是同一个类中方法名相同、参数列表不同个数、类型、顺序与返回值无关编译期确定属于静态分派重写Override是子类对父类方法的重新实现方法签名必须一致方法名参数列表访问权限不能比父类更低抛出的异常不能比父类更宽运行期确定属于动态分派。最后补一句重写是面向对象多态的基础重载是语法层面的便利完美收尾。6. 15天冲刺时间表可以直接照抄的排期不多废话直接上表。每天晚上预留1小时复盘当天卡壳的知识点别把当天的问题留到第二天。天数日期主题上午3小时下午4小时晚上1小时第1天摸底与语言基础自测Java语法、运算符、标识符、数组越界面向对象、接口抽象类、枚举、异常体系整理错题产出基础题答题模板第2天集合框架ArrayList、LinkedList源码对比HashMap、ConcurrentHashMap、HashSet手动画HashMap put流程图第3天并发编程synchronized、volatile、锁升级AQS、ReentrantLock、线程池参数自己讲一遍线程池执行流程第4天JVM内存与GC运行时数据区、对象创建过程GC算法、垃圾收集器、OOM场景用jmap/jstack自己模拟一次排查第5天类加载与实战类加载过程、双亲委派模拟面试Java基础集合并发JVM复盘修复表达漏洞第6天Spring核心Bean生命周期、循环依赖三级缓存AOP原理、事务失效场景画Spring Bean生命周期时序图第7天Spring Boot自动装配原理、条件注解手写一个starter理解流程整理Spring高频追问清单第8天MySQL索引数据结构、聚簇/二级索引执行计划、SQL优化场景题造数据跑一遍慢查询优化第9天Redis缓存穿透/击穿/雪崩持久化、分布式锁、过期策略用一个电商案例串讲全流程第10天项目梳理挑2-3个技术难点详写项目讲解简历逐项自问录音讲一遍项目回放改问题第11天算法专项数组、双指针、字符串链表、二叉树手写快速排序、归并排序第12天算法设计栈、队列、排序温习常见设计模式单例、工厂、代理做一套前端面到后端完整卷子第13天全真模拟模拟面试1基础SpringMySQL复盘错题补弱项整理一页纸速记第14天全真模拟模拟面试2Redis项目手撕算法复盘针对卡壳点专项突击重听两次模拟录音第15天考前冲刺过一遍速记只看错题轻量复习不学新东西早点睡觉7. 最后再分享几个小技巧都是我踩过的坑我这些年面试过不少Java候选人自己也经历过好几次突击式求职有几个细节是很多人忽略的。别把简历上的技术栈写成技术全家桶。很多人的简历上从Spring Cloud写到消息队列、搜索引擎、容器化看起来无所不知面试官随便挑一个深挖就露馅。正确做法是围绕你的项目经历只写你真正踩过坑、能聊到原理层面的技术。写一条熟悉Kafka至少要把分区、副本、消费者组、消息不丢失的机制讲清楚不然就是给自己埋雷。先给结论再展开是面试回答的通用姿势。被问到HashMap为什么线程不安全别上来就从数据结构开始铺垫。先说JDK7的扩容头插法会造成环形链表JDK8改尾插法后仍有数据覆盖丢失问题然后再展开细节。面试官一天面很多人他们需要快速判断你是否在点子上结论前置是对双方时间的尊重。不会的题诚实承认比硬编更稳妥。我见过有人在不会的题目上绕了三分钟最后漏洞百出。你坦诚说这块我了解不深但我知道与之相关的XX是……然后把话题引到你熟悉的方向反而能赢回印象分。不是每道题都要答出来但你要让面试官看到你思考问题的方式。15天不是终点但能让你有底气走进面试室。突击准备的最大价值不是让你把八股文背得滚瓜烂熟而是逼着你把零散的知识整理成体系把好像会变成能讲明白。进了面试室你需要的是一颗不慌的心——大部分内容你都见过了剩下的就当成一次和老朋友聊技术的机会吧。