经典20道Java面试题系列(一)

一、基础与语法

  1. 为什么说Java语言是"编译与解释并存"的?

    考察对Java运行机制的理解。Java代码先通过javac编译成字节码(.class),运行时JVM再将字节码解释成机器码执行;JIT编译器会将热点代码编译为机器码以提升性能。

  2. ==equals()的区别是什么?

    考察基本数据类型与对象的比较。==比较的是内存地址(基本类型比较值);equals()是方法,默认比较地址,但StringInteger等类重写了它用于比较内容。

  3. String为什么被设计为不可变类?

    考察对设计思想的理解。不可变带来的好处包括:字符串常量池的安全复用、线程安全、以及作为HashMap键时的哈希值稳定性。

  4. 方法重载(Overload)和方法重写(Override)的区别是什么?

    考察面向对象多态特性。重载发生在同类中,参数列表不同,与返回值和修饰符无关;重写发生在子类中,方法签名必须一致,遵循"两同两小一大"规则。

  5. static关键字的作用是什么?

    考察对类加载和内存布局的理解。static修饰的成员属于类而非实例,在类加载时初始化,可通过类名直接访问。

二、面向对象与设计

  1. 抽象类和接口有什么区别?在Java 8之后有哪些变化?

    考察对抽象与多继承设计的理解。抽象类可以有状态和构造器,是"is-a"关系;接口是"can-do"关系。Java 8后接口可以有defaultstatic方法,Java 9支持私有方法,Java 17进一步强化了密封类等特性。

  2. 深拷贝和浅拷贝有什么区别?如何实现深拷贝?

    考察对象复制机制。浅拷贝只复制引用,深拷贝递归复制整个对象图。实现方式包括:重写clone()、序列化、或使用拷贝构造器。

  3. 谈谈你对面向对象五大基本原则(SOLID)的理解。

    考察设计原则的掌握程度。分别是:单一职责、开闭原则、里氏替换、接口隔离、依赖倒置。

三、集合框架

  1. ArrayListLinkedList的区别是什么?分别适用于什么场景?

    考察底层数据结构差异。ArrayList基于数组,随机访问快,增删慢;LinkedList基于双向链表,适合频繁插入删除。实际开发中ArrayList使用更广,因为内存连续且缓存友好。

  2. HashMap的底层数据结构是怎样的?在JDK 1.7和1.8中有什么变化?

    考察对核心源码的理解。1.7是"数组+链表",头插法;1.8改为"数组+链表/红黑树",尾插法,当链表长度≥8且数组≥64时树化,解决了哈希冲突时的性能退化问题。

  3. HashSet如何保证元素不重复?

    考察对Set底层实现的理解。HashSet底层依赖HashMap,将元素作为Key存入,Value是一个固定占位对象,利用HashMap的键唯一性来保证不重复。

  4. 哪些集合是线程安全的?ConcurrentHashMap是如何保证线程安全的?

    考察并发集合知识。早期的VectorHashtable已过时,推荐使用ConcurrentHashMap,它采用分段锁(1.7)或CAS+synchronized(1.8)实现高并发读写。

四、并发编程

  1. synchronizedReentrantLock有什么区别?

    考察锁机制的掌握。前者是JVM关键字,使用方便且会自动释放锁;后者是API层面的锁,提供公平锁、可中断锁、多条件绑定等更灵活的功能。

  2. volatile关键字的作用是什么?它能保证原子性吗?

    考察对并发可见性和有序性的理解。volatile保证内存可见性并禁止指令重排,但不能保证原子性,例如count++操作依然需要加锁。

  3. 线程池的核心参数有哪些?任务提交后,线程池的执行流程是怎样的?

    考察对ThreadPoolExecutor源码的掌握。核心参数包括核心线程数、最大线程数、存活时间、阻塞队列、拒绝策略等。执行流程大致是:核心线程 → 阻塞队列 → 非核心线程 → 拒绝策略。

  4. sleep()wait()有什么区别?

    考察线程状态转换。sleep()不释放锁,属于Thread方法;wait()释放锁,属于Object方法,必须配合synchronized使用。

五、JVM与内存模型

  1. JVM的内存区域(运行时数据区)是如何划分的?

    考察对JVM内存结构的掌握。分为线程私有的程序计数器、虚拟机栈、本地方法栈,以及线程共享的堆、方法区(元空间)。堆是GC主要管理区域。

  2. 什么情况下会发生栈内存溢出(StackOverflowError)和堆内存溢出(OutOfMemoryError)?

    考察对内存分配场景的理解。栈溢出通常由递归过深或大量局部变量引起;堆溢出多因对象无法回收,如内存泄漏或数据量过大。

  3. 你了解哪些垃圾回收器?G1相比CMS有哪些优势?

    考察对GC演进的认知。常见的包括Serial、Parallel、CMS、G1以及ZGC。G1通过分Region和可预测停顿模型,解决了CMS的内存碎片化和停顿时间不可控问题。

  4. 如何排查JVM内存泄漏问题?

    考察线上问题定位能力。常用工具包括jmapjstatjstack、MAT(Memory Analyzer)等,基本思路是:监控GC情况 → 导出堆转储 → 分析大对象和引用链。

相关推荐
孟陬1 小时前
为什么国外技术大神都爱自己搭博客,而国内程序员却挤在微信公众号或掘金?
java·typescript·前端框架
GawynKing1 小时前
Java文件传输利器:MultipartFile介绍
java·开发语言
yhole1 小时前
Spring Boot整合Redisson的两种方式
java·spring boot·后端
sthnyph2 小时前
Spring Boot 集成 Kettle
java·spring boot·后端
MyBFuture2 小时前
Halcon 图像处理技巧:抠图与形态学操作指南
开发语言·halcon
sxhcwgcy2 小时前
Spring.factories
java·数据库·spring
Mike117.2 小时前
GBase 8a 数据同步实践:从 T+1 同步、实时镜像到一写多读的落地思路
java·服务器·数据库
qq_416018722 小时前
移动平台C++开发指南
开发语言·c++·算法
Nyarlathotep01132 小时前
LongAdder为什么那么快?
java·后端