☰
java 面试题
2026/9/28 18:45:03 网站建设 项目流程

一、基础核心(必问)

1. Java 中的值传递和引用传递有什么区别?

答案:Java 中只有值传递,不存在引用传递:

  • 值传递:方法接收的是实参的拷贝,方法内对参数的修改不会影响原实参(如基本数据类型int、char等)。
  • 引用传递(误区):对于对象类型,方法接收的是对象引用的拷贝(值),如果修改的是引用指向的对象内容(如对象属性),会影响原对象;但如果直接修改引用本身(如重新new一个对象),不会影响原引用。

示例代码:

java

运行

public class PassTest { // 基本类型:值传递 public static void changeInt(int a) { a = 10; } // 对象类型:传递引用的拷贝 public static void changeObj(User user) { user.setName("新名字"); // 修改对象内容,影响原对象 user = new User("无关"); // 修改引用本身,不影响原引用 } static class User { private String name; public User(String name) { this.name = name; } // getter/setter 省略 } public static void main(String[] args) { int num = 1; changeInt(num); System.out.println(num); // 输出 1(未改变) User u = new User("旧名字"); changeObj(u); System.out.println(u.getName()); // 输出 新名字(对象内容被改) } }
2. == 和 equals () 的区别?

答案:

  • ==:
    • 比较基本类型:判断值是否相等;
    • 比较引用类型:判断引用是否指向同一个对象(内存地址是否相同)。
  • equals():
    • 是Object类的方法,默认实现等价于==(比较地址);
    • 常用类(如String、Integer)重写了equals(),改为比较内容;
    • 自定义类如需按内容比较,需重写equals()(建议同时重写hashCode())。
3. String、StringBuffer、StringBuilder 的区别?
特性StringStringBufferStringBuilder
可变性不可变(final)可变可变
线程安全安全(不可变)安全(同步方法)不安全
性能低(频繁创建)中高
适用场景少量字符串操作多线程字符串操作单线程字符串操作

二、面向对象(核心)

1. 接口和抽象类的区别?
维度抽象类接口
继承 / 实现单继承多实现
方法可含抽象 / 非抽象方法JDK8 + 可含默认 / 静态方法,其余抽象
成员变量可含任意变量只能是public static final
构造方法有无
设计理念体现 "is-a"(继承)体现 "has-a"(能力)
2. 重载(Overload)和重写(Override)的区别?
  • 重载:
    • 发生在同一个类中;
    • 方法名相同,参数列表(个数 / 类型 / 顺序)不同;
    • 返回值、访问修饰符不影响重载;
    • 编译期确定(静态绑定)。
  • 重写:
    • 发生在父子类中;
    • 方法名、参数列表、返回值(协变)完全相同;
    • 子类方法访问修饰符不能比父类更严格;
    • 不能重写final、static方法;
    • 运行期确定(动态绑定)。

三、JVM(高频)

1. JVM 内存模型(运行时数据区)?

JVM 运行时数据区分为 5 个部分:

  • 程序计数器:线程私有,记录当前线程执行的字节码行号,无 OOM;
  • 虚拟机栈:线程私有,存储方法栈帧(局部变量、操作数栈等),栈溢出(StackOverflowError)或 OOM;
  • 本地方法栈:线程私有,为 Native 方法服务,同虚拟机栈;
  • 堆:线程共享,存储对象实例,GC 核心区域,OOM 高发区(分新生代、老年代);
  • 方法区:线程共享,存储类信息、常量、静态变量等,JDK8 后改为元空间(本地内存),仍可能 OOM。
2. GC 垃圾回收的判断方法?
  • 引用计数法:给对象加引用计数器,引用 + 1,释放 - 1,计数器为 0 则回收;缺点:无法解决循环引用。
  • 可达性分析算法:以 GC Roots(如虚拟机栈引用、静态变量、本地方法栈引用)为起点,遍历对象引用链,不可达的对象标记为可回收。
3. 常见的 GC 收集器?
  • Serial GC:单线程,适合小内存、单核心(客户端);
  • Parallel GC:多线程,注重吞吐量(默认 JVM 收集器);
  • CMS GC:并发标记清除,注重低延迟,缺点:内存碎片、CPU 占用高;
  • G1 GC:分区收集,兼顾吞吐量和延迟,适合大内存(JDK9 默认)。

四、并发编程(高频)

1. synchronized 和 Lock 的区别?
维度synchronizedLock(如 ReentrantLock)
实现方式JVM 层面(关键字)JDK 层面(接口)
释放锁自动释放(异常 / 方法结束)手动释放(finally)
可中断不可中断可中断(lockInterruptibly)
超时获取锁不支持支持(tryLock (time))
公平锁非公平可指定公平 / 非公平
条件变量单一多条件(Condition)
2. 线程池的核心参数(ThreadPoolExecutor)?

核心参数共 7 个,关键 5 个:

  • corePoolSize:核心线程数(常驻线程);
  • maximumPoolSize:最大线程数;
  • keepAliveTime:非核心线程空闲超时时间;
  • workQueue:任务队列(如 ArrayBlockingQueue、LinkedBlockingQueue);
  • threadFactory:线程创建工厂;
  • handler:拒绝策略(如 AbortPolicy、CallerRunsPolicy)。

五、集合(必问)

1. HashMap 的底层实现(JDK8)?
  • 底层:数组 + 链表 + 红黑树(链表长度≥8 且数组长度≥64 时转红黑树);
  • 哈希计算:hash(key) = key.hashCode() ^ (key.hashCode() >>> 16),再与数组长度 - 1 取模;
  • 扩容:默认初始容量 16,负载因子 0.75,扩容为 2 倍,重新哈希;
  • 线程安全:非线程安全,并发场景用 ConcurrentHashMap(JDK8 用 CAS+synchronized)。
2. ArrayList 和 LinkedList 的区别?
维度ArrayListLinkedList
底层实现动态数组双向链表
随机访问快(O (1))慢(O (n))
增删操作慢(需移动元素)快(仅改指针)
内存占用连续内存,有扩容冗余每个节点存前后指针,占用更多
适用场景大量读取、少量增删大量增删、少量读取

总结

  1. 基础核心:重点掌握值传递 / 引用传递、==/equals、String 相关、OOP 特性(封装 / 继承 / 多态);
  2. 高频进阶:JVM 内存模型、GC 机制、HashMap 实现、线程池、并发锁(synchronized/Lock)是面试重中之重;
  3. 答题技巧:回答时先给出核心结论,再补充细节 / 示例,结合使用场景说明(如 "HashMap 非线程安全,所以高并发下用 ConcurrentHashMap")。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询