定位:Java / 后端开发岗面试速通。
用法:每个模块先看"核心结论",再看"面试题",最后对照"易踩坑"。


一、Java 基础

1.1 面向对象三大特性

特性说明面试要点
封装隐藏实现,暴露接口访问修饰符 private/protected/public
继承子类复用父类单继承;super 调用父类构造;方法重写
多态父类引用指向子类对象编译看左、运行看右;重写实现运行时绑定

1.2 重载 vs 重写

  • 重载(overload):同一类、同名、参数列表不同(个数/类型/顺序),与返回值和访问修饰符无关。
  • 重写(override):子类覆盖父类方法,方法签名一致;访问权限不能更严,抛出的异常不能更宽。

1.3 数据类型

  • 8 种基本类型:byte short int long float double char boolean,其余均为引用类型。
  • 装箱/拆箱:Integer 等包装类缓存 -128~127(IntegerCache),== 比较该区间会命中缓存。
  • String 不可变:底层 final char[](JDK9 后为 byte[]),+ 拼接编译器优化为 StringBuilder

1.4 ==equals / hashCode

  • ==:基本类型比值,引用类型比地址。
  • equals:默认比地址,重写后比内容(String 已重写)。
  • hashCode:相等对象 hashCode 必相等;hashCode 相等对象不一定 equals 相等。重写 equals 必须重写 hashCode(否则 HashMap 失效)。

二、集合框架

2.1 体系概览

Collection
 ├─ List(有序可重复):ArrayList / LinkedList / Vector
 └─ Set(不可重复):HashSet / LinkedHashSet / TreeSet
Map(键值对):HashMap / LinkedHashMap / TreeMap / Hashtable / ConcurrentHashMap

2.2 ArrayList vs LinkedList

维度ArrayListLinkedList
底层动态数组双向链表
随机访问O(1)O(n)
插入删除(中间)O(n) 搬移O(1) 改指针
内存连续,省节点额外开销

2.3 HashMap(必考)

  • JDK 1.8 结构:数组 + 链表 + 红黑树。默认容量 16,负载因子 0.75,阈值 = 容量 × 0.75。
  • 扩容:超过阈值 resize 为 2 倍,元素重新散列(低位/高位拆分,无需重算 hash)。
  • 链表树化:链表长度 ≥ 8 且数组容量 ≥ 64 转为红黑树;树节点 ≤ 6 退化为链表。
  • 线程不安全:并发 put 可能数据覆盖或死循环(1.7 头插;1.8 已修复死循环但仍不安全)。

2.4 ConcurrentHashMap

  • JDK 1.7Segment 分段锁(继承 ReentrantLock),默认 16 段并发度 16。
  • JDK 1.8Node 数组 + 链表/红黑树,putCAS + synchronized(锁单个桶头节点),更细粒度,效率更高。

三、并发编程(重灾区)

3.1 线程的创建

  • 继承 Thread / 实现 Runnable / 实现 Callable(有返回值、Future 获取)/ 线程池。

3.2 线程状态

NEW → RUNNABLE → BLOCKED / WAITING / TIMED_WAITING → TERMINATED

  • sleep:不释放锁,休眠后自动恢复。
  • wait:释放锁,需 notify/notifyAll 唤醒(必须在 synchronized 内)。

3.3 synchronizedReentrantLock

维度synchronizedReentrantLock
实现JVM 内置(监视器锁)API 层面(AQS)
释放自动(代码块结束/异常)手动 unlock(放 finally)
公平非公平可公平/非公平
中断不可中断可中断 lockInterruptibly
条件单一等待队列Condition

synchronized 锁升级:无锁 → 偏向锁 → 轻量级锁(CAS 自旋)→ 重量级锁(操作系统互斥)。

3.4 线程池(必考)

7 个参数

  1. corePoolSize 核心线程数
  2. maximumPoolSize 最大线程数
  3. keepAliveTime 空闲线程存活时间
  4. unit 时间单位
  5. workQueue 任务队列(ArrayBlockingQueue / LinkedBlockingQueue / SynchronousQueue)
  6. threadFactory 线程工厂
  7. handler 拒绝策略

处理流程:核心线程满 → 入队 → 队列满 → 开非核心线程 → 达最大线程 → 触发拒绝策略。
4 种拒绝策略AbortPolicy(抛异常,默认)/ CallerRunsPolicy(调用者线程执行)/ DiscardPolicy(丢弃)/ DiscardOldestPolicy(丢最旧)。

3.5 JMM 与三大特性

  • 原子性synchronizedLock、原子类(AtomicInteger)。
  • 可见性volatilesynchronizedfinal
  • 有序性volatile 禁止指令重排(happens-before 原则)。
  • volatile 不保证原子性(如 i++ 非原子),适合状态标志位。
  • CAS:比较并交换,无锁乐观;ABA 问题用 AtomicStampedReference 加版本号解决。
  • AQS:抽象队列同步器,ReentrantLock/Semaphore/CountDownLatch 的底层基础(state + CLH 队列)。

四、JVM(高频)

4.1 运行时数据区

  • 线程私有:程序计数器、虚拟机栈(栈帧/局部变量表)、本地方法栈。
  • 线程共享:堆(对象实例,GC 主战场)、方法区(JDK8 后为元空间 Metaspace,存类信息/常量/静态变量)。

4.2 垃圾回收

  • 判断存活:引用计数(循环引用失效)/ 可达性分析(GC Roots 不可达即回收,主流)。
  • GC Roots:栈帧局部变量、静态变量、常量、JNI 引用。
  • 回收算法:标记-清除(碎片)/ 标记-整理(慢)/ 复制(新生代,效率高)。
  • 分代收集:新生代(Eden + 2 Survivor,Minor GC,复制算法)→ 老年代(Major/Full GC,标记-整理)。
  • 垃圾回收器:Serial(单线程)/ Parallel(吞吐优先)/ CMS(并发标记清除,低停顿,已弃用)/ G1(Region 化,可预测停顿,主流)/ ZGC(TB 级、亚毫秒停顿)。

4.3 类加载

  • 双亲委派:自底向上委托父加载器,父不能加载才自己加载;避免类重复、保证核心类安全。
  • 破坏场景:SPI(JDBC)、热部署、Tomcat WebAppClassLoader。
  • OOM 常见:堆溢出(-Xmx 调大/查内存泄漏)、栈溢出(递归过深)、元空间溢出(类加载过多)。

五、异常

  • ThrowableError(严重,不可捕获,如 OOM)/ Exception
  • ExceptionRuntimeException(非受检,空指针/越界)/ 受检异常(必须 try 或 throws,如 IOException)。
  • finally 始终执行(除非 System.exit);return 前先执行 finally(finally 的 return 会覆盖)。

六、反射与注解

  • 反射:运行时获取类信息并操作(Class.forName / getDeclaredMethod / setAccessible(true) 突破私有)。代价:性能略低、破坏封装。
  • 注解@Override / @Deprecated / @FunctionalInterface;元注解 @Target @Retention @Documented @Inherited@Retention(RUNTIME) 才能反射读取。

七、Java 8+ 新特性

  • Lambda:函数式接口(@FunctionalInterface,仅一个抽象方法)。
  • Stream APIfilter/map/reduce/collect,惰性求值、可并行(parallelStream)。
  • Optional:优雅判空,避免 NPE。
  • 接口默认方法default 方法、静态方法。
  • 新日期 APILocalDate/LocalDateTime/DateTimeFormatter(线程安全,替代 SimpleDateFormat)。
  • 方法引用::

八、IO 与 NIO

  • BIO:流(InputStream/OutputStream),阻塞、面向流。
  • NIOChannel + Buffer + Selector,非阻塞、多路复用,适合高并发(Netty 基础)。
  • AIO(NIO.2):异步回调。

九、易踩坑清单

现象解决
遍历 List 时 removeConcurrentModificationException用迭代器 removeremoveIf
substring 内存泄漏(JDK6)长字符串截取后旧大字符串不释放JDK7+ 已修复(新建数组)
== 比包装类-128~127 外为 falseequals
重写 equals 不写 hashCodeHashMap 查找失败成对重写
i++ 多线程结果不对AtomicInteger/synchronized
SimpleDateFormat 多线程日期错乱局部变量 / DateTimeFormatter
线程池用 Executors 创建OOM 风险(无界队列/无限线程)ThreadPoolExecutor 自定义
HashMap 并发写数据丢失ConcurrentHashMap

十、高频面试题 30 连击

  1. 面向对象三大特性?
  2. 重载和重写区别?
  3. ==equals 区别?为何重写 equals 要重写 hashCode?
  4. String 为什么不可变?
  5. Integer 缓存范围?
  6. ArrayList 与 LinkedList 区别?
  7. HashMap 底层结构与扩容?
  8. 为何链表 8 转红黑树?
  9. ConcurrentHashMap 1.7 与 1.8 区别?
  10. 创建线程有几种方式?
  11. sleep 与 wait 区别?
  12. synchronized 锁升级过程?
  13. synchronized 与 ReentrantLock 区别?
  14. volatile 能保证原子性吗?
  15. 线程池 7 参数与处理流程?
  16. 四种拒绝策略?
  17. 为什么不建议用 Executors 创建线程池?
  18. CAS 是什么?ABA 怎么解决?
  19. AQS 原理?
  20. JVM 内存区域划分?
  21. 何时发生栈溢出 / 堆溢出?
  22. 如何判断对象可回收?
  23. 垃圾回收算法有哪些?
  24. G1 与 CMS 区别?
  25. 双亲委派模型及破坏场景?
  26. 类加载过程?
  27. 受检与非受检异常区别?
  28. 反射的原理与代价?
  29. Java 8 有哪些新特性?
  30. BIO、NIO、AIO 区别?
Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐