Java 校招必备八股文

Java 校招面试里,真正高频的内容其实很集中。你不需要一上来把所有框架源码都啃完,先把基础八股打牢,已经能覆盖大部分一面、二面的提问范围。通常会围绕这几块展开:Java 基础、集合、并发、JVM、数据库、Spring、MySQL、Redis、网络。

这篇文章按校招常考思路来写,尽量讲清“是什么、为什么、怎么考”。

一、Java 基础

Java 为什么跨平台?

因为 Java 代码先编译成字节码,运行时由 JVM 解释或编译执行。不同平台安装不同的 JVM,就能实现“一次编写,到处运行”。

JDK、JRE、JVM 的区别:

  • JVM 是 Java 虚拟机,负责运行字节码。
  • JRE 是 Java 运行环境,包含 JVM 和基础类库。
  • JDK 是开发工具包,包含 JRE 以及编译、调试等工具。

==equals() 的区别:

  • == 比较的是基本类型的值,或引用类型的地址。
  • equals() 默认也是比较地址,但很多类比如 String 重写后比较的是内容。

hashCode()equals() 的关系:

  • 如果两个对象 equals()true,那么它们的 hashCode() 必须相等。
  • hashCode() 相等,不一定 equals()true

为什么要同时重写?

因为哈希容器如 HashMapHashSet 会先用 hashCode() 找桶,再用 equals() 判断是不是同一个对象。

String、StringBuilder、StringBuffer 的区别:

  • String 不可变。
  • StringBuilder 可变,线程不安全,但效率高。
  • StringBuffer 可变,线程安全,但效率略低。

为什么 String 不可变?

  • 便于缓存哈希值。
  • 更安全,适合作为常量和键。
  • 适合字符串常量池复用。

重载和重写的区别:

  • 重载:同一个类中,方法名相同,参数列表不同。
  • 重写:子类对父类方法重新实现,方法名和参数基本一致。

更多全面的java大厂面试题和必备八股文都收录在专栏里面了:

https://www.nowcoder.com/creation/manager/columnDetail/0n9XOd

二、面向对象三大特性

封装:

把属性和方法放在类里,对外隐藏实现细节。

继承:

子类继承父类,复用父类已有能力。

多态:

同一个父类引用,指向不同子类对象,调用同一个方法会表现出不同结果。

多态的前提:

  • 有继承关系
  • 子类重写父类方法
  • 父类引用指向子类对象

三、集合高频

Java 集合主要分两大类:

  • Collection
  • Map

ListSetMap 的区别:

  • List 有序,可重复。
  • Set 无序或有序,不可重复。
  • Map 存键值对,key 不可重复。

ArrayList 和 LinkedList 区别:

  • ArrayList 底层是动态数组,查询快,尾插效率高。
  • LinkedList 底层是双向链表,插入删除方便,但查询慢。

校招面试常见回答:

  • 随机访问多,用 ArrayList
  • 中间插删多,用 LinkedList
  • 实际开发中 ArrayList 更常用

HashMap 底层原理:

JDK 1.8 中,HashMap 底层是“数组 + 链表 + 红黑树”。

存储过程:

  1. 先根据 key 的 hashCode() 计算哈希值
  2. 定位到数组下标
  3. 如果该位置为空,直接插入
  4. 如果发生哈希冲突,放入链表或红黑树中

为什么 JDK 1.8 要引入红黑树?

因为链表过长时,查询效率会退化到 O(n),转成红黑树后可以优化到 O(logn)

HashMap 和 Hashtable 的区别:

  • HashMap 线程不安全,效率高。
  • Hashtable 线程安全,但基本已经很少用了。
  • HashMap 允许 null 键和 null 值,Hashtable 不允许。

HashSet 为什么不能重复?

因为底层是基于 HashMap 实现的,元素作为 key 存储。插入时先比较 hashCode(),再比较 equals(),相同则认为重复。

ConcurrentHashMap 为什么线程安全?

JDK 1.7 用分段锁。JDK 1.8 主要用 CAS + synchronized,锁粒度更细,并发性能更好。

四、并发编程高频

线程和进程的区别:

  • 进程是资源分配的基本单位。
  • 线程是 CPU 调度的基本单位。
  • 一个进程可以有多个线程,线程共享进程资源。

创建线程的方式:

  1. 继承 Thread
  2. 实现 Runnable
  3. 实现 Callable
  4. 线程池创建

为什么更推荐线程池?

  • 减少线程频繁创建和销毁的开销
  • 更方便统一管理线程
  • 能控制并发数量,提高稳定性

synchronizedLock 的区别:

  • synchronized 是 Java 关键字,使用简单,自动释放锁。
  • Lock 是接口,功能更灵活,比如可中断、可超时、公平锁等。
  • 复杂并发控制通常更适合 Lock

volatile 的作用:

  • 保证可见性
  • 禁止指令重排
  • 不保证原子性

为什么 i++ 不是线程安全的?

因为它不是原子操作,本质上分为读取、加一、写回三步,多线程下可能发生竞争。

CAS 是什么?

CAS 即 Compare And Swap,比较并交换。它是一种无锁原子操作,常用于实现原子类和并发容器。

AQS 是什么?

AQS 即 AbstractQueuedSynchronizer,是很多同步器的基础框架,比如:

  • ReentrantLock
  • CountDownLatch
  • Semaphore
  • ReentrantReadWriteLock

线程池核心参数:

  • corePoolSize:核心线程数
  • maximumPoolSize:最大线程数
  • keepAliveTime:非核心线程空闲存活时间
  • workQueue:任务队列
  • threadFactory:线程工厂
  • handler:拒绝策略

线程池执行流程很常考:

  1. 线程数小于核心线程数,创建核心线程执行任务
  2. 否则放入阻塞队列
  3. 队列满了且线程数小于最大线程数,创建非核心线程
  4. 还满了就执行拒绝策略

常见拒绝策略:

  • 直接抛异常
  • 调用者自己执行
  • 丢弃当前任务
  • 丢弃最旧任务

五、JVM 必考

JVM 内存区域:

  • 程序计数器
  • Java 虚拟机栈
  • 本地方法栈
  • 方法区

堆中主要放对象实例,栈中主要放局部变量、方法调用信息。

为什么会栈溢出?

递归太深或者局部变量过大,导致栈空间不够。

为什么会堆溢出?

创建对象太多,堆空间不够,且垃圾回收后仍无法释放足够内存。

类加载过程:

  1. 加载
  2. 验证
  3. 准备
  4. 解析
  5. 初始化

双亲委派模型:

一个类加载器接到类加载请求后,会先委托父加载器去加载,父加载器加载不了,自己再加载。

好处:

  • 防止类重复加载
  • 保证核心类库安全

垃圾回收主要回收哪里?

主要回收堆和方法区中的无用对象。

如何判断对象是否可回收?

主流思路是可达性分析。若对象和 GC Roots 没有引用链相连,则可认为可回收。

常见垃圾回收算法:

  • 标记清除
  • 标记整理
  • 复制算法
  • 分代收集

为什么要分代?

因为不同对象生命周期不同:

  • 新生代对象大多朝生夕死,适合复制算法
  • 老年代对象存活率高,适合标记清除或标记整理

常见垃圾收集器:

  • Serial
  • ParNew
  • CMS
  • G1

校招里一般说清 CMS 和 G1 就够了。

CMS:

  • 以获取最短停顿时间为目标
  • 会有内存碎片问题

G1:

  • 面向服务端
  • 将堆分成多个 Region
  • 可预测停顿时间
  • 适合大内存场景

六、MySQL 高频

事务四大特性 ACID:

  • 原子性
  • 一致性
  • 隔离性
  • 持久性

事务并发问题:

  • 脏读
  • 不可重复读
  • 幻读

MySQL 四种隔离级别:

  • 读未提交
  • 读已提交
  • 可重复读
  • 串行化

MySQL 默认隔离级别:

  • Repeatable Read,可重复读

为什么会有幻读?

同一个事务里前后两次范围查询,第二次查到了第一次没有的行,像“幻觉”一样。

索引是什么?

索引是帮助数据库快速查找数据的数据结构,MySQL InnoDB 常用 B+ 树索引。

为什么不用红黑树而用 B+ 树?

  • B+ 树更适合磁盘 IO
  • 高度更低
  • 范围查询效率高
  • 叶子节点天然有序,便于区间查询

聚簇索引和非聚簇索引:

  • 聚簇索引:数据和索引放在一起,InnoDB 主键索引就是聚簇索引
  • 非聚簇索引:索引和数据分开存,需要回表

什么是回表?

通过二级索引找到主键后,再去主键索引中查完整数据。

什么情况会导致索引失效?

  • 对索引列使用函数
  • 隐式类型转换
  • 最左前缀不满足
  • like% 开头
  • 使用 or 且某些字段无索引

七、Redis 高频

Redis 为什么快?

  • 基于内存
  • 单线程模型避免线程切换开销
  • IO 多路复用
  • 数据结构高效

Redis 常见数据类型:

  • String
  • Hash
  • List
  • Set
  • ZSet

应用场景:

  • String:缓存、计数器
  • Hash:对象属性存储
  • List:消息队列、列表
  • Set:去重、共同好友
  • ZSet:排行榜、延迟队列

缓存穿透、击穿、雪崩:

缓存穿透:

  • 查询不存在的数据,请求直接打到数据库

解决:

  • 缓存空值
  • 布隆过滤器

缓存击穿:

  • 某个热点 key 突然失效,大量请求打到数据库

解决:

  • 热点 key 永不过期
  • 加互斥锁

缓存雪崩:

  • 大量 key 同时过期,大量请求涌向数据库

解决:

  • 过期时间加随机值
  • 多级缓存
  • 限流降级

Redis 持久化:

  • RDB:快照
  • AOF:追加日志

区别:

  • RDB 恢复快,但可能丢失最后一次快照后的数据
  • AOF 更安全,但文件更大,恢复较慢

八、Spring 高频

Spring 的核心是什么?

最核心是:

  • IOC
  • AOP

IOC 是什么?

IOC 即控制反转,把对象创建和依赖管理交给 Spring 容器,而不是自己 new

DI 是什么?

DI 即依赖注入,是 IOC 的具体实现方式。

AOP 是什么?

AOP 即面向切面编程,在不修改业务代码的前提下,统一处理日志、事务、权限等横切逻辑。

Spring Bean 的生命周期简版:

  1. 实例化
  2. 属性注入
  3. 调用各种感知接口
  4. 执行初始化方法
  5. 使用 Bean
  6. 容器关闭时执行销毁方法

Spring 事务失效场景是高频题:

  • 方法不是 public
  • 自调用导致代理失效
  • 异常被吃掉
  • 数据库引擎不支持事务
  • 没有被 Spring 管理

Spring Boot 为什么方便?

因为它提供了:

  • 自动配置
  • 起步依赖
  • 内嵌 Tomcat
  • 简化配置和开发流程

九、网络八股

TCP 和 UDP 的区别:

  • TCP 面向连接,可靠传输
  • UDP 无连接,不保证可靠性,但更快

TCP 为什么可靠?

  • 三次握手建立连接
  • 序号机制
  • 确认应答
  • 超时重传
  • 滑动窗口
  • 流量控制
  • 拥塞控制

为什么三次握手不是两次?

因为三次握手可以让双方都确认“自己能发、也能收”,从而保证连接建立是可靠的。

为什么四次挥手?

因为 TCP 是全双工,双方都要单独关闭发送通道,所以通常需要四次。

HTTP 和 HTTPS 区别:

  • HTTP 明文传输,不安全
  • HTTPS = HTTP + SSL/TLS,加密传输,更安全

Session 和 Cookie 的区别:

  • Cookie 存在客户端
  • Session 存在服务端
  • Session 通常依赖 Cookie 中的 SessionId 进行识别

十、校招面试怎么背最有效

如果你时间有限,优先按这个顺序准备:

  1. Java 基础
  2. 集合
  3. 并发
  4. JVM
  5. MySQL
  6. Redis
  7. Spring

因为这几块几乎是 Java 校招的主战场。

建议你背八股时,不要只背定义,要用“三段式”回答:

  1. 先说结论
  2. 再说原理
  3. 最后补应用场景或对比

比如问 “HashMap 为什么线程不安全?”

可以这么答:

先说结论,HashMap 是线程不安全的,多线程下可能出现数据覆盖、读取异常等问题。然后说原因,因为它内部没有加锁,多个线程同时 put 或扩容时会竞争共享数据。最后补一句,如果并发场景下需要线程安全,一般用 ConcurrentHashMap

这样回答会比只说一句“因为没加锁”好很多。

十一、最后的速记版

Java 校招最该背住的几个点:

  • == 比地址,equals() 比内容
  • HashMap 底层是数组 + 链表 + 红黑树
  • ArrayList 底层是动态数组
  • volatile 保证可见性,不保证原子性
  • 线程池比手动创建线程更推荐
  • JVM 重点是内存区域、类加载、GC
  • MySQL 索引用 B+ 树
  • Redis 快是因为内存 + 单线程 + IO 多路复用
  • Spring 核心是 IOC 和 AOP
  • TCP 可靠,UDP 快

如果这些主干你能讲顺,再配合项目经历,已经足够应对大多数校招面试。

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务