本文共 1817 字,大约阅读时间需要 6 分钟。
Java面试核心笔记
一、多线程基础
1. 进程与线程的区别
- 进程是程序运行的基本单位,拥有独立的内存空间。
- 线程是比进程更小的执行单元,共享进程内存,开销更低。
2. 并发与并行的区别
- 并发:同一时间处理多个任务,线程轮流执行。
- 并行:同一时间处理多个任务,多核CPU同时执行。
3. 创建线程方式
继承Thread类:new Thread(new Runnable() { ... })
实现Runnable接口:new Thread(runnable)
实现Callable接口:new Thread(new Callable<V>() { ... }).start()
使用线程池:executorService.submit(runnable)
4. Runnable与Callable的区别
- Runnable的
run
方法无返回值,适合不需要返回结果的任务。 - Callable的
call
方法有返回值,适合需要结果的任务。
5. run与start的区别
- start方法启动线程,线程运行
run
方法。 - run方法可以在多次调用。
6. 线程状态
新建、可执行、阻塞、等待、计时等待、死亡。
7. 线程同步
- synchronized:互斥锁,基于 Monitor机制。
- lock:可重入锁,提供更多同步选项,如公平锁、可中断等待。
8. CAS原理
- 原子操作:确保多线程环境下操作的原子性。
- 优点:高效,但存在ABA问题和循环开销。
二、JVM基础
1. JVM主要组成部分
- 类加载器:加载.class文件。
- 运行时数据区:堆、方法区、程序计数器、虚拟机栈、本地方法栈。
- 执行引擎:字节码到机器码的翻译。
- 本地方法接口:与C/C++接口沟通。
2. 运行时数据区组成
- 方法区:存储类信息、常量、静态变量。
- 堆:存储对象实例、数组。
- 程序计数器:记录当前线程执行位置。
- 虚拟机栈:存储局部变量、方法参数。
- 本地方法栈:支持本地方法。
3. 垃圾回收
- 堆是垃圾回收的主要区域。
- 栈中的对象一般在方法结束时被回收。
4. 栈内存管理
- 栈溢出:方法调用深度过大或内存不足。
- 默认栈内存大小:1MB。
三、并发编程
1. 线程池核心参数
- 核心线程数(
corePoolSize
):控制核心线程数量。 - 最大线程数(
maximumPoolSize
):核心线程+救急线程最大数量。 - 队列(
workQueue
):默认使用LinkedBlockingQueue。 - 夜间线程存活时间(
keepAliveTime
):默认为无限。
2. 线程池创建方式
固定线程池:核心线程数固定,适合已知任务总量。 单例线程池:核心线程数为1,适合按顺序执行任务。 可缓存线程池:核心线程数为0,适合任务密集型场景。 定时执行线程池:执行定期任务。 3. 线程池拒绝策略
- 直接拒绝:默认策略。
- 抛弃策略:丢弃任务记录。
- 抢占策略:强制终止任务。
- 重新路线:重试执行任务。
四、ThreadLocal内存泄漏
1. ThreadLocal原理
- 每个线程维护一个ThreadLocalMap存储变量。
- 内存泄漏:未及时清除ThreadLocal中的变量。
2. 解决方法
- 及时调用
ThreadLocal.remove()
清除变量。 - 避免使用ThreadLocal存储大型对象。
五、JVM性能调优
1. 堆大小设置
- 默认初始堆大小为XMB,最小堆大小为XMB。
- 增大堆大小:优化内存使用,但增加GC开销。
2. 课程主类设置
-Xms
:初始堆大小。 -Xmx
:最大堆大小。 -Xmn
:年轻代大小。
3. GC优化
- 使用
-XX:+UseParallelGC
优化吞吐量。 - 调整
-XX:ParallelGCThreads
控制并行收集线程数。
4. 内存分配优化
- 使用
-XX:+UseTLAB
减少TLAB分配时间。
六、其他技术要点
1. ThreadLocal与线程安全
- ThreadLocal确保线程隔离,但需谨慎使用。
2. 线程池与异步调用
- 使用
@EnableAsync
注释启动类,定义自定义线程池。
3. 任务调度
- 使用
CountDownLatch
实现任务顺序执行。
4. 线程间通信
- 使用
Object
类的wait
/notify
方法。 - 使用
Lock
和Condition
实现更高级锁机制。
七、总结
Java多线程和并发编程是核心技能,理解线程池、锁机制、内存管理至关重要。
转载地址:http://orxoz.baihongyu.com/