本文最后更新于 2 分钟前,文中所描述的信息可能已发生改变。
- 1. Java 里常用的集合有哪些? ✅ 2025-09-15
常用的集合有:List,Map,Set,Queue,PriorityQueue 等/
List:ArrayList、LinkedList
Set:HashSet、TreeSet、LinkedHashSet
Map:HashMap、TreeMap、ConcurrentHashMap
2. 数组的底层原理是啥? ✅ 2025-09-15
通过在内存中分配一块连续的区域,数组中元素内存地址依次递增,能够通过起始位置快速索引元素。
连续的内存空间,支持下标随机访问(O(1))。
插入、删除元素需要移动大量数据(O(n))。
3. ArrayList 是怎么扩容的?
首先根据数组长度重新创建新数组,再将旧数组中元素复制到新数组,后释放旧数组内存。>具体扩容是将数组长度翻倍。
默认初始容量 10。
扩容时新容量 = 原容量的 1.5 倍。
通过
Arrays.copyOf复制数据到新数组。4. ArrayList 在哪些场景下不太好用? ✅ 2025-09-15
频繁插入或删除元素。
元素频繁插入/删除(中间位置)。
大量数据时,扩容成本高。
多线程环境下不安全。
5. HashMap 是怎么解决哈希冲突的?
采用 hashcode()和 equal()方法。
JDK 1.8 以前:拉链法(数组 + 链表)。
JDK 1.8 以后:链表长度 > 8 时转成红黑树。
6. 讲讲快速排序。 ✅ 2025-09-15
分治思想,选择基准值,分区交换。
平均 O(n log n),最坏 O(n^2)。
非稳定排序。
7. 讲讲堆排序。 ✅ 2025-09-15
基于大顶堆/小顶堆。
建堆 + 调整。
时间复杂度 O(n log n),不稳定排序。
8. Java 里的
sort方法用的是什么排序算法?基本类型数组:双轴快排(Dual-Pivot Quicksort)。
对象数组、集合:TimSort(归并 + 插入排序优化,稳定)。
9.
final关键字有什么用?修饰类:不能被继承。
修饰方法:不能被重写。
修饰变量:常量,不能再赋值。
10. Java 实现多线程有几种方式? ✅ 2025-09-15
- new Thread();
2. extends Callable(); 3. implements Runnable()。
继承 Thread 类。
实现 Runnable 接口。
实现 Callable 接口 + FutureTask。
使用线程池。
11. 线程池的主要参数有哪些?
核心线程数,最大线程数…
corePoolSize(核心线程数)
maximumPoolSize(最大线程数)
keepAliveTime(空闲线程存活时间)
workQueue(阻塞队列)
threadFactory(线程工厂)
handler(拒绝策略)
12. 线程池的拒绝策略有哪些?
AbortPolicy(抛异常)
CallerRunsPolicy(调用者执行)
DiscardPolicy(直接丢弃)
DiscardOldestPolicy(丢弃最老任务)
13. 除了线程池,还接触过其他开启多线程的方式吗?
ForkJoinPool
CompletableFuture
并行流(parallelStream)
14.
synchronized和ReentrantLock有什么区别?synchronized:JVM 实现,简单易用,自动释放锁。
ReentrantLock:基于 AQS,支持可重入、公平锁、可中断、条件变量。
15. 介绍一下
ReentrantLock底层的 AQS。AQS 维护一个 state(锁状态)和 FIFO 队列。
通过 CAS 修改 state 实现加锁/释放锁。
队列中节点自旋 + 阻塞等待唤醒。
16. CAS 底层用的是什么技术?
CPU 的原子指令(如 x86 的
cmpxchg)。保证比较并交换的原子性。
17. 听说过无锁吗?
基于 CAS 实现的并发控制。
不需要互斥锁,提高并发性能。
18.
ThreadLocal用过吗? ✅ 2025-09-15为每个线程提供独立副本,线程之间数据隔离。
19. 用
ThreadLocal的时候要注意什么问题? ✅ 2025-09-15
及时回收不在使用 ThreadLocal 对象,防止内存泄漏。
内存泄漏问题。
线程池复用线程时要手动清理。
20. 怎么保证
ThreadLocal的remove方法一定会被执行?在
finally块中调用remove()。21. 调用
remove方法的目的是什么? ✅ 2025-09-15防止线程复用导致数据错乱。
避免内存泄漏。
22. 数据库的事务隔离级别有哪些? ✅ 2025-09-15
读未提交,读已提交,可重复读,串行化。
- 23. MySQL 默认的事务隔离级别是哪个? ✅ 2025-09-15
可重复读。
- 24. MySQL 是怎么解决不可重复读问题的? ✅ 2025-09-15
基于 MVCC 的快照读,实现读进程读取的记录不会被修改。
- 25. 幻读问题解决了吗? ✅ 2025-09-15
大体上解决了,但是还存在部分 bug。如:快照锁升级导致可重复读失效。
可重复读依赖 MVCC 的快照读,如果事务中显式加锁(for update / lock in share mode),快照会升级为当前读,从而读取到最新数据,导致“可重复读失效”的现象。
- 26. 算法题:用三个线程按顺序打印 A、B、C(用两个线程按顺序打印奇偶数)。
- 使用
synchronized+wait/notify。 - 或
Lock+Condition。 - 或
Semaphore控制顺序。
public class Printer {
private int count = 0;
private final int maxCount = 200;
private final Object lock = new Object();
private boolean isOdd = false;
public static void main(String[] args) {
Printer printer = new Printer();
Thread oddThread = new Thread(() -> {
printer.print("Thread Odd", true);
});
Thread evenThread = new Thread(() -> {
printer.print("Thread Even", false);
});
oddThread.start();
evenThread.start();
}
public void print(String name, boolean isOdd) {
synchronized (lock) {
while (count < maxCount) {
if (this.isOdd != isOdd) {
try {
lock.wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
System.out.println(name + ": " + count);
count++;
this.isOdd = !this.isOdd;
lock.notifyAll();
}
}
}
}