简介:这是一份面向Java初学者与应届培训生的面试复习资料,围绕初级岗位常见考点整理成体系化题库,帮助缺乏项目经验的求职者快速建立知识框架、应对技术面试。资源为单个docx文档,压缩包约155KB,内容按十八个模块编排,涵盖Java基础、多线程、反射、对象拷贝、JavaWeb、异常、网络、设计模式、Spring/Spring MVC、Spring Boot/SpringCloud、Hibernate、MyBatis、RabbitMQ、Kafka、Zookeeper、MySQL、Redis、JVM等方向,共收录208道面试题并附参考答案。其中Java基础部分对JDK与JRE区别、==与equals差异、hashCode与equals关系、final关键字、Math.round取值、String类型归属等高频题给出了代码示例与源码解读,便于理解底层原理。目前已有620人学习,适合作为面试前的查漏补缺清单与知识点速查手册。
1. 初级 Java 岗面试的真相:208 道题里真正拉分的是哪几类
很多人准备 Java 初级面试的方式是打开一份“Java 面试题大全”,从第一题开始背,背到 JVM 就放弃了。问题不在毅力,在于没搞清楚这场面试到底考什么。初级岗面试的底层逻辑其实很清晰:面试官要在 40 分钟内判断三件事——你的 Java 基础是不是扎实、你写过多线程代码没有、你对主流框架和数据库是不是只会调 API。这份 208 道题的清单按十八个模块切分,恰好对应了这三条判断线。Java 基础、集合、异常、IO 这些是筛子,多线程和 JVM 是分水岭,Spring、MyBatis、MySQL、Redis 是加分项。换句话说,前六个模块答不好直接出局,后十二个模块答得好才能谈薪资。这篇文章不按题号顺序讲,而是按“面试官怎么问、你怎么答、哪里容易翻车”来拆,适合刚出学校或者刚培训完、准备投初级岗的人。
2. Java 基础与集合:从 == 到 HashMap 的必答链条
2.1 JDK/JRE、==/equals、hashCode 这三题为什么总被连着问
面试官问“JDK 和 JRE 有什么区别”,不是想听你背定义,而是想看你能不能把“开发”和“运行”这两个场景分开。标准答法是:JDK 是开发工具包,包含 JRE 加上 javac 编译器和调试分析工具;JRE 只是运行环境。如果你要运行 Java 程序,装 JRE 就够;要写 Java 程序,必须装 JDK。这题答完,面试官通常会顺势问==和equals。
这题的关键在于分类型讨论。基本类型用==比值,引用类型用==比引用地址。equals默认就是==,但 String、Integer 这些类重写了它,变成了值比较。看这段代码:
String x = "string"; String y = "string"; String z = new String("string"); System.out.println(x == y); // true,常量池同一个引用 System.out.println(x == z); // false,new 出来的是堆上新对象 System.out.println(x.equals(y)); // true,String 重写了 equals,比值 System.out.println(x.equals(z)); // true面试官最想听的是你主动补一句:new String()会在堆上开辟新空间,而字面量赋值走常量池。如果你还能说出“自定义类不重写 equals,两个同值对象比较返回 false”,这题就答满了。
紧接着的陷阱题是:“两个对象 hashCode() 相同,equals() 也一定为 true 吗?”答案是不一定。反例是字符串“通话”和“重地”,它们的 hashCode 相同,但 equals 返回 false。原因是哈希值相等只说明散列位置可能相同,不代表键值对相等。这题考的是你有没有真正理解散列表的冲突机制,而不是背结论。
2.2 String 三兄弟与集合选型:面试官在听你的“选择理由”
String、StringBuffer、StringBuilder 的区别,几乎每场初级面试都会出现。答题结构应该是:String 不可变,每次操作生成新对象;StringBuffer 和 StringBuilder 可以在原对象上改;StringBuffer 线程安全但慢,StringBuilder 非线程安全但快。单线程用 StringBuilder,多线程用 StringBuffer。如果你只答“一个安全一个不安全”,面试官会追问“为什么安全就慢”,你要能说出 synchronized 修饰带来的开销。
集合部分是初级岗的重灾区。List、Set、Map 的区别,核心就两个维度:有序性和是否允许重复。List 有序可重复,Set 无序不可重复,Map 是键值对、键不可重复。面试官接着会问 HashMap 和 Hashtable 的区别:HashMap 允许 null 键值、非线程安全;Hashtable 不允许 null、线程安全但已不推荐使用,多线程场景应该用 ConcurrentHashMap。
HashMap 的实现原理是这一模块的压轴题。答题要点:基于哈希算法,put 时根据 key 的 hashCode 算 hash 值定位 bucket;hash 冲突时用链表存储,冲突个数多时转红黑树。这里有个容易翻车的追问:“链表转红黑树的条件是什么?”如果你只答“冲突多的时候”,面试官会认为你没看过源码。准确说法是链表长度超过阈值且数组容量达到一定值才转。
ArrayList 和 LinkedList 的区别也要用场景来答:ArrayList 是动态数组,随机访问快,增删要移动下标;LinkedList 是双向链表,增删快,随机访问要遍历。频繁读取用 ArrayList,频繁插入删除用 LinkedList。面试官如果问“ArrayList 和 Vector 的区别”,补一句 Vector 用 synchronized 实现线程安全、扩容翻倍而 ArrayList 扩容 50% 就够了。
提示:集合类题目不要只背结论,每答一个区别就带一个使用场景,面试官会认为你是真用过而不是背的。
3. 多线程与并发:初级岗最容易被追问到崩的模块
3.1 线程创建、状态与 sleep/wait 的经典三连
多线程是初级面试的分水岭。第一题通常是“创建线程有哪几种方式”,标准答案三种:继承 Thread 重写 run、实现 Runnable 接口、实现 Callable 接口。面试官会追问 Runnable 和 Callable 的区别:Runnable 没有返回值,Callable 可以拿到返回值,是 Runnable 的补充。
线程状态这题要能说出六种:NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING、TERMINATED。不要只背名字,要能对应场景——BLOCKED 是被同步锁或 IO 阻塞,WAITING 是永久等待,TIMED_WAITING 是限时等待。
sleep() 和 wait() 的区别是必考题,答题要分三个维度:sleep 来自 Thread,wait 来自 Object;sleep 不释放锁,wait 释放锁;sleep 时间到自动恢复,wait 需要 notify/notifyAll 唤醒。这题答错“释放锁”这一条,基本就暴露了没写过多线程代码。
// 典型 wait/notify 使用结构 synchronized (lock) { while (条件不满足) { lock.wait(); // 释放锁并等待 } // 条件满足,执行逻辑 lock.notifyAll(); // 唤醒其他等待线程 }这段代码的关键点是 wait 必须放在 synchronized 块里,且判断条件要用 while 而不是 if,防止虚假唤醒。面试官如果问“为什么用 while”,你要能说出线程被唤醒后条件可能又不满足了,需要重新检查。
3.2 线程池、锁升级与死锁:答出“为什么”才算过关
线程池的创建方式是高频题。七种方式里,最核心的是 ThreadPoolExecutor,前面几种都是对它的封装。newSingleThreadExecutor 保证顺序执行,newCachedThreadPool 处理大量短任务、闲置 60 秒回收,newFixedThreadPool 固定线程数、无界队列。面试官会追问 submit() 和 execute() 的区别:execute 只能执行 Runnable,submit 可以执行 Runnable 和 Callable,且 Callable 能拿返回值。
synchronized 锁升级原理是拉开差距的题。答题链条:对象头里有 threadid 字段,第一次访问时为空,JVM 让其持有偏向锁并写入线程 id;再次进入先判断 threadid 是否一致,一致直接用;不一致升级为轻量级锁,通过自旋获取;自旋一定次数还拿不到,升级为重量级锁。锁升级的目的是降低锁带来的性能消耗。如果你能补一句“Java 6 之后对 synchronized 做了大量优化”,面试官会认为你了解版本演进。
死锁这题要能说清四个必要条件,但初级岗更常问“怎么防止死锁”。答题要点:用 tryLock 设置超时时间,超时退出;用 java.util.concurrent 并发类代替手写锁;降低锁粒度;减少同步代码块。面试官最想听的是“设置超时”这一条,因为它是可落地的。
synchronized 和 volatile 的区别也要能答:volatile 是变量修饰符,只保证可见性不保证原子性,不阻塞线程;synchronized 修饰类、方法、代码块,保证可见性和原子性,可能阻塞线程。synchronized 和 Lock 的区别:synchronized 自动获取释放锁、异常自动释放;Lock 需要手动 lock/unlock,使用不当会死锁,但可以知道有没有获取到锁。
注意:多线程题目答“是什么”只能拿基础分,答“为什么这样设计”和“什么场景用哪个”才能拿高分。
4. 框架与中间件:Spring、MyBatis、MySQL、Redis 的常考套路
4.1 Spring 全家桶与 ORM 框架:IOC、AOP 和 MyBatis 的答题模板
Spring 是初级岗必问的框架。核心考点两个:IOC 和 AOP。IOC 是控制反转,把对象的创建和依赖管理交给容器,你只需要声明需要什么。AOP 是面向切面编程,把日志、事务这些横切逻辑从业务代码里抽出来。面试官常问“Spring 事务的传播行为”,初级岗至少要能说出 REQUIRED 和 REQUIRES_NEW 的区别:REQUIRED 有事务就加入,没有就新建;REQUIRES_NEW 总是新建事务,挂起当前事务。
Spring MVC 的请求流程也是高频题。答题链条:请求到 DispatcherServlet,它查 HandlerMapping 找到对应 Controller,Controller 处理完返回 ModelAndView,ViewResolver 解析视图,最后渲染返回。不要背得太细,抓住“前端控制器分发”这个核心就行。
MyBatis 的考点集中在#{}和${}的区别:#{}是预编译参数,能防止 SQL 注入;${}是字符串拼接,有注入风险。面试官会追问“什么时候必须用${}”,答案是动态表名或动态列名这种预编译不支持的地方。Hibernate 和 MyBatis 的区别也常问:Hibernate 是全自动 ORM,MyBatis 是半自动,需要手写 SQL,更灵活。
4.2 MySQL、Redis 与消息队列:初级岗也要会的存储与缓存题
MySQL 的考点集中在索引和事务。索引这题要能说出 B+ 树结构、聚簇索引和非聚簇索引的区别。事务的 ACID 四个特性要能展开:原子性、一致性、隔离性、持久性。隔离级别四种:读未提交、读已提交、可重复读、串行化,MySQL 默认是可重复读。面试官会追问“可重复读怎么解决幻读”,答案是 MVCC 加间隙锁。
Redis 的常考题是数据类型和缓存问题。五种基本类型:String、Hash、List、Set、ZSet。缓存穿透、缓存击穿、缓存雪崩的区别要能说清:穿透是查不存在的数据,击穿是热点 key 过期,雪崩是大量 key 同时过期。解决方案分别是布隆过滤器、互斥锁、过期时间加随机值。
RabbitMQ 和 Kafka 的区别也是初级岗会问的:RabbitMQ 适合业务解耦、延迟低;Kafka 适合高吞吐日志采集。Zookeeper 的考点是分布式协调,初级岗知道它是用来做配置管理、命名服务、分布式锁的就够了。
提示:框架题不要只背概念,每个框架准备一个“我在项目里怎么用的”例子,哪怕项目是模拟的,也要能说清解决了什么问题。
5. 易错点:这五道题初级岗最容易答错
5.1 错在哪:Math.round(-1.5) 答成 -2
很多人凭直觉认为四舍五入就是 -2,实际结果是 -1。原因是在数轴上取值时,中间值 0.5 向右取整,正 0.5 往上,负 0.5 直接舍弃。正确答法是先说出结果 -1,再解释“向右取整”的规则。这题考的是你有没有真正理解 round 的实现,而不是背结论。
5.2 错在哪:抽象类必须有抽象方法
这是概念性错误。抽象类不一定有抽象方法,完全可以只包含具体方法。反过来说,有抽象方法的类必须是抽象类。面试官问这题是想看你有没有被“抽象类”这个名字误导。正确答法:抽象类可以有抽象方法也可以没有,但不能被实例化;普通类不能包含抽象方法。
5.3 错在哪:final 能修饰抽象类
不能。抽象类存在的意义就是被继承,final 修饰的类不能被继承,两者矛盾。这题考的是你对修饰符语义的理解。正确答法:final 修饰类表示最终类不可继承,修饰方法表示不可重写,修饰变量表示常量必须初始化且不可修改。抽象类不能用 final 修饰。
5.4 错在哪:hashCode 相同 equals 就相同
前面已经讲过,这是反直觉但必考的点。错在把哈希值相等等同于对象相等。正确答法:hashCode 相同 equals 不一定 true,散列表里哈希值相等只说明位置可能相同,键值对不一定相等。反例是“通话”和“重地”。
5.5 错在哪:Iterator 遍历时用集合的 remove
Iterator 遍历过程中如果直接用集合的 remove 方法,会抛出 ConcurrentModificationException。原因是 Iterator 内部维护了 modCount,集合结构被修改后 modCount 变化,Iterator 检查到不一致就抛异常。正确做法是用 Iterator 自己的 remove 方法。这题考的是你有没有踩过这个坑。
6. 答题节奏与押题思路:把 208 道题变成你的武器
准备这份题库的正确方式不是从头背到尾,而是按“出现频率 × 你的薄弱程度”排序。我的做法是把十八个模块分成三档:第一档是 Java 基础、集合、多线程、异常、IO,这些是每场必问,必须做到脱口而出;第二档是 Spring、MyBatis、MySQL、Redis,这些是初级岗的加分项,要能结合场景说;第三档是 RabbitMQ、Kafka、Zookeeper、JVM 调优,初级岗问得少,但问到就是拉开差距的机会。
答题节奏上,每道题控制在 40 秒到 1 分钟。结构是“结论 + 原因 + 场景”。比如问 HashMap 原理,先说“基于哈希算法,数组加链表加红黑树”,再说“put 时算 hash 定位,冲突用链表,多了转红黑树”,最后补“所以查询效率接近 O(1)”。不要一上来就背源码,面试官没耐心听。
押题思路方面,初级岗面试有个规律:面试官会从你的简历项目出发问基础。你写了“用了 Redis 做缓存”,他就会问缓存穿透和雪崩;你写了“用了线程池”,他就会问七种创建方式和 submit/execute 区别。所以准备题库的时候,每道题都要想一下“这个知识点能挂在我项目的哪个地方”。
最后说一个我自己的教训。我刚开始准备面试的时候,把 208 道题从头背了一遍,结果面试官问“synchronized 和 Lock 的区别”,我背出了五条,但他追问“那你项目里为什么用 Lock 不用 synchronized”,我答不上来。从那以后我每次准备面试题,都强制走一遍“结论 → 原因 → 我项目里怎么用的”三步,哪怕项目是模拟的,也要能说清选择理由。希望帮到你。
本文还有配套的精品资源,点击获取