01 JVM 与 Java 基础

这一块在面试里是干什么的

主要用来判断:

  • 你是不是只会写业务代码
  • 你对 Java 运行机制是否有基本理解
  • 出线上问题时能不能定位方向

先记住这几个关键词

  • JDK:开发工具包,包含 javacjava 等工具
  • JRE:运行 Java 程序需要的环境
  • JVM:真正执行 Java 字节码的虚拟机

一句话:

“Java 代码先编译成字节码,再由 JVM 执行。”

Java 为什么跨平台

因为 Java 编译后的产物是字节码,不直接依赖操作系统。

不同平台只要有对应的 JVM,就能执行同一份字节码。

==equals

  • ==:比较地址,基本类型时比较值
  • equals:比较内容,默认还是比较地址,很多类比如 String 重写后比较值

面试回答:

== 更偏向判断是不是同一个对象,equals 更偏向判断内容是否相等。”

String 为什么不可变

原因:

  • 线程安全
  • 可以缓存 hash
  • 适合作为 map key
  • 字符串常量池可以复用对象

常见追问:

  • StringBuilder:可变,单线程快
  • StringBuffer:可变,方法带同步

集合先记最常问的

ArrayListLinkedList

  • ArrayList:基于数组,查询快,插入删除慢
  • LinkedList:基于链表,插入删除相对方便,查询慢

大部分业务场景优先用 ArrayList

HashMapConcurrentHashMap

  • HashMap:线程不安全
  • ConcurrentHashMap:线程安全,适合并发场景

面向对象先会说什么

四大特性:

  • 封装
  • 继承
  • 多态
  • 抽象

最容易被问的是多态。

一句话:

“父类引用指向子类对象,运行时调用子类实现,这就是多态。”

JVM 内存区域

先记主干,不要一开始背太细:

  • 堆:放对象实例,是垃圾回收主战场
  • 栈:放局部变量、方法调用信息
  • 方法区:放类信息、常量、静态变量等
  • 程序计数器:记录当前线程执行到哪里

常见高频题:

对象主要放哪

一般放在堆里。

局部变量放哪

一般在线程栈里。

什么是垃圾回收

JVM 自动回收不再使用的对象,减少手动释放内存的成本。

如何判断对象是否可回收

主流答案是“可达性分析”。

一句话:

“如果一个对象从 GC Roots 出发不可达,就可以认为它可以被回收。”

常见 GC

短期先知道名字和特点:

  • Serial:单线程,简单
  • Parallel:吞吐量优先
  • CMS:低停顿,已逐渐淡出
  • G1:现在最常见,兼顾吞吐和停顿

高频面试一句话:

“G1 把堆划分成多个 Region,目标是在可控停顿时间下完成回收。”

什么是 OOM

Out Of Memory,内存溢出。

常见原因:

  • 堆内存不够
  • 内存泄漏
  • 大对象太多
  • 无限创建对象

什么是内存泄漏

对象已经没用了,但仍然被引用,导致 GC 无法回收。

finalfinallyfinalize

  • final:关键字,修饰类/方法/变量
  • finally:异常处理里一定会执行的代码块
  • finalize:对象回收前的方法,已不推荐依赖

异常体系

  • Exception:可处理异常
  • RuntimeException:运行时异常,可以不显式捕获
  • Error:严重错误,应用一般不处理

高频题:

throwthrows

  • throw:真的抛出异常
  • throws:声明这个方法可能抛出异常

高频快答

重载和重写

  • 重载:同一个类中,方法名相同,参数不同
  • 重写:子类重写父类方法

HashMap 为什么快

通过 hash 定位桶,再在桶内查找,平均时间复杂度接近 O(1)

ArrayList 默认扩容

面试不用背死数值,记住“底层是动态数组,容量不够会扩容并拷贝旧数据”即可。

这一章最小记忆包

  • Java 跨平台靠字节码 + JVM
  • == 比地址,equals 比内容
  • String 不可变
  • 对象一般在堆,局部变量一般在栈
  • GC 通过可达性分析判断是否回收
  • G1 是当前常见垃圾回收器
  • OOM 是内存溢出,内存泄漏是对象没用但回收不了