跳到主要内容Java面试:基础、并发与容器高频考点整理 | 极客日志Javajava
Java面试:基础、并发与容器高频考点整理
涵盖Java基础、容器、多线程等面试高频问题,从JDK/JRE区别到容器选择、线程安全机制与反射原理,配合代码示例解析典型易错点。
整理了一些 Java 面试中基础、并发与容器部分的高频问题,每个点都配了简答和代码,方便快速回顾。
Java 基础
JDK 和 JRE 有什么区别?
JDK 是开发工具包,包含了 JRE 和编译器、调试工具;JRE 是运行时环境。只运行 Java 程序时装 JRE 就行,要开发必须装 JDK。
== 和 equals 的区别是什么?
对于基本类型,== 比较的是值;对于引用类型,== 比较的是地址。equals 默认是比较地址,但 String、Integer 等类重写了它,改成比较值。看个例子:
String x = "string";
String y = "string";
String z = new String("string");
System.out.println(x == y);
System.out.println(x == z);
System.out.println(x.equals(y));
System.out.println(x.equals(z));
x 和 y 指向常量池里的同一个引用,所以 == 为 true;new String() 在堆上新开内存,地址不同。而 equals 重写后只比字符序列。
两个对象的 hashCode() 相同,则 equals() 也一定为 true,对吗?
不一定,hashCode 相等只说明哈希值相同,实际内容可能不同,这叫哈希冲突。比如 "通话" 和 "重地" 的 hashCode 一样,但 equals 是 false。
String str1 = "通话";
String str2 = "重地";
System.out.println(str1.hashCode() == str2.hashCode());
System.out.println(str1.equals(str2));
final 在 Java 中有什么作用?
修饰类:类不能被继承。修饰方法:方法不能被重写。修饰变量:变量变成常量,必须初始化且值不能改。
Math.round(-1.5) 等于多少?
等于 -1。数轴上取整时,中间值向右走,所以负数时 -1.5 取 -1,正数 1.5 取 2。
String 属于基础数据类型吗?
不属于。基础类型共八种:byte、boolean、char、short、int、float、long、double,String 是个不可变对象。
Java 中操作字符串都有哪些类?它们之间有什么区别?
常用的有 String、StringBuffer、StringBuilder。String 是不可变的,每次操作都会生成新对象;StringBuffer 和 StringBuilder 可以在原对象上修改。StringBuffer 线程安全、StringBuilder 线程不安全但快一点。一般单线程用 StringBuilder,多线程用 StringBuffer。
String str="i" 与 String str=new String("i") 一样吗?
不一样。"i" 直接放常量池,new String("i") 在堆上创建对象。
如何将字符串反转?
用 StringBuilder 或 StringBuffer 的 reverse()。
StringBuilder sb = new StringBuilder();
sb.append("abcdefg");
System.out.println(sb.reverse());
String 类的常用方法有哪些?
indexOf、charAt、replace、trim、split、getBytes、length、toLowerCase / toUpperCase、substring、equals 等。
抽象类必须要有抽象方法吗?
不必。抽象类可以没有任何抽象方法。
abstract class Cat {
public static void sayHi() {
System.out.println("hi~");
}
}
普通类和抽象类有哪些区别?
普通类不能有抽象方法,抽象类可以有;抽象类不能直接 new 实例化,普通类可以。
抽象类能使用 final 修饰吗?
不能。final 禁止继承,抽象类就是为了被继承,矛盾。
接口和抽象类有什么区别?
抽象类用 extends,接口用 implements;抽象类可以有构造器,接口没有;一个类可实现多个接口,但只能继承一个抽象类;接口方法默认 public,抽象类方法可以用各种修饰符。
Java 中 IO 流分为几种?
按功能分输入流、输出流;按类型分字节流和字符流。字节流按 8 位传输,字符流按 16 位传输。
BIO、NIO、AIO 有什么区别?
BIO 是同步阻塞式,简单但并发能力低;NIO 是同步非阻塞,通过 Channel 通讯,支持多路复用;AIO 是异步非阻塞,基于事件和回调。
Files 的常用方法有哪些?
exists、createFile / createDirectory、delete、copy、move、size、read、write 等。
容器
Java 容器都有哪些?
主要分 Collection 和 Map 两大类。Collection 下有 List(ArrayList, LinkedList, Vector, Stack)、Set(HashSet, LinkedHashSet, TreeSet);Map 下有 HashMap, LinkedHashMap, TreeMap, ConcurrentHashMap, Hashtable。
Collection 和 Collections 有什么区别?
Collection 是集合接口,所有单列集合都实现它;Collections 是个工具类,提供 sort 等静态方法,不能实例化。
List、Set、Map 之间的区别是什么?
List 有序可重复,Set 通常无序不可重复,Map 键值对,键唯一值可重复。
HashMap 和 Hashtable 有什么区别?
HashMap 允许 key/value 为 null,Hashtable 不允许;Hashtable 线程安全,HashMap 非线程安全。Hashtable 是遗留类,单线程用 HashMap,多线程推荐 ConcurrentHashMap。
如何决定使用 HashMap 还是 TreeMap?
插入、删除、定位操作频繁用 HashMap,效率更高;需要对 key 进行有序遍历时用 TreeMap。
说一下 HashMap 的实现原理?
基于哈希。put 时计算 key 的 hash 值定位桶,冲突时用链表或红黑树存储。链表长度超过阈值会转为红黑树。
说一下 HashSet 的实现原理?
底层就是基于 HashMap,元素作为 HashMap 的 key,value 是一个常量对象。所以元素不能重复。
ArrayList 和 LinkedList 的区别是什么?
ArrayList 是动态数组,随机访问快;LinkedList 是双向链表,增删元素(非首尾)更快。频繁读取用 ArrayList,频繁增删用 LinkedList。
如何实现数组和 List 之间的转换?
数组转 List:Arrays.asList(array)。List 转数组:list.toArray()。
List<String> list = new ArrayList<>();
list.add("王磊");
list.toArray();
String[] array = {"王磊", "的博客"};
Arrays.asList(array);
ArrayList 和 Vector 的区别是什么?
Vector 线程安全(方法加了 synchronized),ArrayList 非线程安全;ArrayList 扩容 50%,Vector 扩容 1 倍;一般用 ArrayList,多线程场景考虑并发集合。
Array 和 ArrayList 有何区别?
Array 可以存基本类型和对象,ArrayList 只能存对象;Array 大小固定,ArrayList 自动扩展;Array 提供的基础方法少,ArrayList 有丰富的集合操作。
在 Queue 中 poll() 和 remove() 有什么区别?
都返回并删除队头元素。空队列时 poll() 返回 null,remove() 抛出 NoSuchElementException。
哪些集合类是线程安全的?
Vector、Hashtable、Stack 是线程安全的,但通常不推荐,JDK 1.5 后 concurrent 包里提供了更高效的并发集合,比如 ConcurrentHashMap。
迭代器 Iterator 是什么?
提供遍历 Collection 集合的统一接口,允许在迭代过程中安全移除元素。
List<String> list = new ArrayList<>();
Iterator<String> it = list.iterator();
while (it.hasNext()) {
String obj = it.next();
System.out.println(obj);
}
遍历时如果集合被其他线程修改,会快速抛出 ConcurrentModificationException。
Iterator 和 ListIterator 有什么区别?
Iterator 可遍历 Set 和 List,单向移动;ListIterator 只能遍历 List,可双向移动,还支持添加、替换元素和获取索引。
怎么确保一个集合不能被修改?
用 Collections.unmodifiableCollection(Collection c) 生成只读视图,任何修改操作会抛出 UnsupportedOperationException。
多线程
并行和并发有什么区别?
并行是多核同时执行多个任务;并发是单核通过快速切换任务实现'同时'执行的假象。
线程和进程的区别?
一个程序至少一个进程,一个进程至少一个线程。进程是资源分配的单位,线程是调度的基本单位。
守护线程是什么?
后台运行的服务线程,比如 GC 线程。当所有非守护线程结束时,JVM 自动退出。
- 继承 Thread 重写 run();2. 实现 Runnable 接口;3. 实现 Callable 接口(可返回结果)。
runnable 和 callable 有什么区别?
Runnable 无返回值,Callable 可以返回结果。Callable 常配合 Future 使用。
线程有哪些状态?
NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING、TERMINATED。
sleep() 和 wait() 有什么区别?
sleep() 是 Thread 的方法,不释放锁,时间到自动唤醒;wait() 是 Object 的方法,会释放锁,需要 notify 或 notifyAll 唤醒。
notify() 和 notifyAll() 有什么区别?
notify 随机唤醒一个等待线程,notifyAll 唤醒所有等待线程,让它们重新竞争锁。
线程的 run() 和 start() 有什么区别?
start() 会启动新线程并执行 run() 里的代码;直接调用 run() 只是普通方法调用,不会启动新线程。start() 只能调用一次。
创建线程池有哪几种方式?
核心是 ThreadPoolExecutor,常见封装有:newSingleThreadExecutor(单线程)、newCachedThreadPool(灵活大小)、newFixedThreadPool(固定大小)、newScheduledThreadPool(定时调度)、newWorkStealingPool(Java 8,利用 ForkJoinPool)。
线程池都有哪些状态?
RUNNING、SHUTDOWN、STOP、TIDYING、TERMINATED。转换过程有严格顺序。
submit() 和 execute() 有什么区别?
execute 只接受 Runnable;submit 接受 Runnable 或 Callable,且提交 Callable 后可以拿到 Future 获取返回结果。
怎么保证多线程的运行安全?
使用 java.util.concurrent 包下的安全类、用 synchronized 加锁、或者用 Lock 手动锁。
Lock lock = new ReentrantLock();
lock.lock();
try {
System.out.println("获得锁");
} finally {
lock.unlock();
}
多线程中 synchronized 锁升级的原理是什么?
为了减少性能开销,Java 6 后加入偏向锁、轻量级锁、重量级锁。偏向锁优先,轻量级锁通过自旋尝试获取,失败才膨胀到重量级锁,依赖操作系统互斥。
什么是死锁?
两个线程互相持有对方需要的锁并等待,导致谁也动不了。
怎么防止死锁?
设置 tryLock 超时,使用并发类代替手动锁,降低锁粒度,尽量让加锁顺序一致。
ThreadLocal 是什么?有哪些使用场景?
为每个线程提供独立的变量副本,避免共享。典型场景:数据库连接管理、Session 管理。
说一下 synchronized 底层实现原理?
基于 monitorenter/monitorexit 指令。早期是重量级锁依赖 OS 互斥,Java 6 后引入偏向、轻量级等优化。
synchronized 和 volatile 的区别是什么?
volatile 仅保证可见性,不保证原子性;synchronized 两者都保证。volatile 只修饰变量,synchronized 可修饰方法、代码块。
synchronized 和 Lock 有什么区别?
synchronized 自动释放锁,Lock 必须手动 unlock;Lock 可以尝试获取锁、可中断;synchronized 适用范围更广,可修饰方法,Lock 只能修饰代码块。
synchronized 和 ReentrantLock 区别是什么?
ReentrantLock 更灵活,支持公平锁、可绑定多个条件,但必须手动释放。synchronized 是关键字,语法简单,JVM 自动管理。
说一下 atomic 的原理?
利用 CAS(Compare And Swap)和 volatile 保证原子性,避免重量级锁,底层是 native 方法。
反射
什么是反射?
运行时动态获取类的属性和方法,并可以动态调用对象方法。
什么是 Java 序列化?什么情况下需要序列化?
将对象状态保存为字节流,以便存储到文件、数据库或网络传输。典型场景:RMI、分布式对象、持久化。
动态代理是什么?有哪些应用?
运行时动态生成代理类。常见于 Spring AOP、RPC 框架、Hibernate、单元测试 Mock。
怎么实现动态代理?
JDK 动态代理要求被代理类实现接口;CGLIB 通过继承目标类生成子类,不依赖接口。
对象拷贝
为什么要使用克隆?
当需要创建一个与已有对象状态相同的新对象,且不依赖于原有构造逻辑时,克隆更直接。
如何实现对象克隆?
实现 Cloneable 接口并重写 clone() 方法(浅拷贝);或通过序列化和反序列化实现深拷贝。
深拷贝和浅拷贝区别是什么?
浅拷贝复制基本类型和对象引用,指向同一块内存;深拷贝把引用指向的对象也复制一份,完全独立。
Java Web
JSP 和 servlet 有什么区别?
JSP 本质上是 Servlet,但编写方式不同。Servlet 在 Java 代码里拼 HTML,JSP 在 HTML 里嵌入 Java。JSP 侧重视图,Servlet 侧重控制逻辑。
JSP 有哪些内置对象?作用分别是什么?
request、response、pageContext、session、application、out、config、page、exception,共 9 个,分别用于获取请求、响应、作用域等。
说一下 JSP 的 4 种作用域?
page(当前页面)、request(一次请求)、session(一次会话)、application(整个 Web 应用)。按需使用。
session 和 cookie 有什么区别?
session 数据在服务端,较安全,可存复杂对象;cookie 在浏览器端,有大小和数量限制,容易被篡改。session 依赖 cookie 或 URL 重写维持。
相关免费在线工具
- Keycode 信息
查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
- Escape 与 Native 编解码
JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
- JavaScript / HTML 格式化
使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
- JavaScript 压缩与混淆
Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
- Base64 文件转换器
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online