1.arraylist和linklist的区别
操作 | ArrayList | LinkedList |
---|---|---|
查第n个元素 | ⚡ 超快 (直接定位) | 🐢 慢 (要一个个数) |
在末尾添加 | ⚡ 快 | ⚡ 快 |
在中间插入/删除 | 🐢 慢 (要移动后面所有元素) | ⚡ 快 (改个链接就行) |
内存占用 | ✅ 省 (只存数据) | ❌ 费 (还要存前后指针) |
2.hashMap1.7和hashMap1.8的区别
特性 | HashMap 1.7 | HashMap 1.8 |
---|---|---|
数据结构 | 数组 + 单链表 | 数组 + 链表/红黑树 |
插入方式 | 头插法(新元素放链表头部) | 尾插法(新元素放链表尾部) |
哈希冲突 | 链表可能很长,查询变慢 | 链表超8转红黑树,查询更快 |
扩容时机 | 先扩容再插入 | 先插入再判断扩容 |
死锁问题 | ❌ 多线程可能死锁 | ✅ 减少死锁风险 |
-
DK 1.7:像单行道 – 车多就堵死,还容易出事故(死锁)
-
JDK 1.8:像智能立交 – 车多时自动开启高架(红黑树),通行更高效
3.ConcurrentHashMap 与 HashMap、Hashtable 对比
特性 | HashMap | Hashtable | ConcurrentHashMap |
---|---|---|---|
线程安全 | ❌ 不安全 | ✅ 安全 | ✅ 安全 |
性能 | ⚡ 最快 | 🐢 最慢 | ⚡ 很快 |
锁机制 | 无锁 | 全表锁 | 分段锁/CAS |
多线程 | 会出错 | 安全但慢 | 安全且快 |
-
HashMap:自由市场 – 谁都能买卖,但可能混乱
-
Hashtable:只有一个门的仓库 – 安全但效率低,一次只能进一个人
-
ConcurrentHashMap:现代化超市 – 多个收银台,不同柜台可以同时结账
4.ConcurrentHashMap1.7和ConcurrentHashMap1.8的区别
特性 | ConcurrentHashMap 1.7 | ConcurrentHashMap 1.8 |
---|---|---|
锁粒度 | 段锁(锁一个Segment) | 桶锁(锁单个数组元素) |
锁机制 | ReentrantLock | CAS + synchronized |
数据结构 | 数组 + 链表 | 数组 + 链表/红黑树 |
并发度 | Segment数量决定 | 桶数量决定,更高 |
哈希冲突 | 链表可能很长 | 链表超8转红黑树 |
-
JDK 1.7:传统大商场 – 分成几个大区,每个区一个收银台
-
JDK 1.8:现代超市 – 每个货架都有自助扫码,真正并行结算
5.线程和进程的区别
方面 | 进程 (Process) | 线程 (Thread) |
---|---|---|
资源占用 | 大(独立内存空间) | 小(共享进程内存) |
创建销毁 | 慢(重量级) | 快(轻量级) |
切换成本 | 高(要切换整个环境) | 低(只需切换少量上下文) |
通信方式 | 复杂(管道、消息队列等) | 简单(直接读写共享内存) |
独立性 | 独立,一个崩溃不影响其他 | 相互影响,一个线程崩溃可能导致整个进程崩溃 |
资源 | 拥有独立的内存、文件句柄等 | 共享进程的资源 |
-
进程:独立的公司 – 有自己独立的办公室、资金、资源
-
线程:公司里的员工 – 共享办公室资源,一起完成任务
进程是资源分配的单位,线程是CPU调度的单位。线程轻量,共享资源;进程重量,资源独立。
6.Java创建对象的方式
- new 关键字(最常用)
- Person person = new Person();
- 反射(通过类名创建)
- Person person = Person.class.newInstance();
- clone()(复制对象)
- Person person2 = (Person) person1.clone();
- 反序列化(从文件恢复对象)
- Person person = (Person) objectInputStream.readObject();
- 工厂方法(通过方法创建)
- Person person = Person.create();
7.单例模式懒汉式
// 懒汉式
public class Singleton {
// 延迟加载保证多线程安全
Private volatile static Singleton singleton; // 第1行:声明单例实例
private Singleton(){} // 第2行:私有构造方法
public static Singleton getInstance(){ // 第3行:获取实例的公共方法
if(singleton == null){ // 第4行:第一次检查
synchronized(Singleton.class){ // 第5行:加锁
if(singleton == null){ // 第6行:第二次检查
singleton = new Singleton(); // 第7行:创建实例
}
}
}
return singleton; // 第8行:返回实例
}
}
总结:
-
延迟加载:只有调用
getInstance()
时才创建对象 -
线程安全:通过双重检查和同步锁保证
-
性能优化:只有第一次创建时需要同步,后续调用直接返回实例
8.JVM
- JVM 是什么?
JVM(Java虚拟机) – 就像一台”虚拟的电脑”,专门用来运行Java程序。
- JVM 的三大核心功能:
-
内存管理 – 自动分配和回收内存
-
跨平台 – “一次编译,到处运行”
垃圾回收 – 自动清理不再使用的对象
区域 | 存放什么 | 特点 |
---|---|---|
堆 | 所有对象 | 最大,GC主要区域 |
栈 | 局部变量、方法调用 | 线程私有,速度快 |
方法区 | 类信息、常量 | 共享,存放元数据 |
- 记住核心:
- new 的对象 → 放在堆中
- 局部变量 → 放在栈中
- 类信息、常量 → 放在方法区
- GC → 主要清理堆中的对象
9.synchronized 锁升级的过程
为什么要有锁升级:性能优化!
-
无竞争:用偏向锁,开销最小
-
轻度竞争:用自旋锁,避免线程切换
-
激烈竞争:用重量级锁,避免CPU空转
简单总结:
锁状态 | 适用场景 | 特点 | 开销 |
---|---|---|---|
无锁 | 新创建对象 | 直接访问 | 无 |
偏向锁 | 单线程访问 | 记录线程ID | 很小 |
轻量级锁 | 轻度竞争 | 自旋等待 | 中等 |
重量级锁 | 激烈竞争 | 线程阻塞 | 很大 |
核心思想:根据竞争激烈程度,自动选择最合适的锁级别,平衡性能和功能!
10.CAS
CAS 是什么?
- CAS(Compare And Swap) – 比较并交换,是一种无锁的原子操作。
CAS 原理
// CAS 的三个参数: // V:要更新的变量(内存值) // E:期望的值(我认为应该的值) // N:新值(我要设置的值) boolean CAS(V, E, N) { if (V == E) { // 比较:内存值是否等于期望值 V = N; // 交换:如果相等就更新为新值 return true; // 成功 } return false; // 失败 }
优点:
-
高性能:无锁,避免线程阻塞和切换
- 线程安全:保证原子性操作
缺点:
- ABA问题
- 循环时间长开销大
- 只能保证一个变量的原子性