Skip to content

Commit ebb518f

Browse files
committed
间隙锁
1 parent 4d31b01 commit ebb518f

File tree

7 files changed

+167
-53
lines changed

7 files changed

+167
-53
lines changed

docs/src/sidebar/sanfene/javase.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2247,15 +2247,15 @@ public class ByteBufferExample {
22472247

22482248
推荐阅读:[Java NIO 比传统 IO 强在哪里?](https://javabetter.cn/nio/nio-better-io.html)
22492249

2250-
Java 提供了多种 IO 模型来处理输入和输出操作,包括传统的阻塞 IO、非阻塞 IO 和异步 IO
2250+
Java 常见的 IO 模型有三种:BIO、NIO 和 AIO
22512251

22522252
![二哥的 Java 进阶之路:IO 分类](https://cdn.tobebetterjavaer.com/stutymore/javase-20240404103618.png)
22532253

2254-
BIO(Blocking I/O):采用阻塞式 I/O 模型,线程在执行 I/O 操作时被阻塞,无法处理其他任务,适用于连接数较少的场景。
2254+
BIO:采用阻塞式 I/O 模型,线程在执行 I/O 操作时被阻塞,无法处理其他任务,适用于连接数较少的场景。
22552255

2256-
NIO(New I/O 或 Non-blocking I/O):采用非阻塞 I/O 模型,线程在等待 I/O 时可执行其他任务,通过 Selector 监控多个 Channel 上的事件,适用于连接数多但连接时间短的场景。
2256+
NIO:采用非阻塞 I/O 模型,线程在等待 I/O 时可执行其他任务,通过 Selector 监控多个 Channel 上的事件,适用于连接数多但连接时间短的场景。
22572257

2258-
AIO(Asynchronous I/O):使用异步 I/O 模型,线程发起 I/O 请求后立即返回,当 I/O 操作完成时通过回调函数通知线程,适用于连接数多且连接时间长的场景。
2258+
AIO:使用异步 I/O 模型,线程发起 I/O 请求后立即返回,当 I/O 操作完成时通过回调函数通知线程,适用于连接数多且连接时间长的场景。
22592259

22602260
#### 简单说一下 BIO?
22612261

@@ -2297,6 +2297,7 @@ while (!result.isDone()) {
22972297
> 1. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的比亚迪面经同学 3 Java 技术一面面试原题:BIO NIO 的区别
22982298
> 2. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的美团面经同学 2 Java 后端技术一面面试原题:BIO、NIO、AIO 的区别?
22992299
> 3. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的 360 面经同学 3 Java 后端技术一面面试原题:说一下阻塞非阻塞 IO -说了下 BIO 和 NIO
2300+
> 4. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的阿里云面经同学 22 面经:介绍NIO BIO AIO
23002301
23012302
## 序列化
23022303

docs/src/sidebar/sanfene/javathread.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,42 @@ stop 方法用来强制线程停止执行,目前已经处于废弃状态,因
412412

413413
![三分恶面渣逆袭:Java线程状态变化](https://cdn.tobebetterjavaer.com/tobebetterjavaer/images/sidebar/sanfene/javathread-7.png)
414414

415+
#### 如何做到强制终止线程?
416+
417+
设置线程的中断标志,通知线程优雅地终止。
418+
419+
```java
420+
class MyTask implements Runnable {
421+
@Override
422+
public void run() {
423+
while (!Thread.currentThread().isInterrupted()) {
424+
try {
425+
System.out.println("Running...");
426+
Thread.sleep(1000); // 模拟工作
427+
} catch (InterruptedException e) {
428+
// 捕获中断异常后,重置中断状态
429+
Thread.currentThread().interrupt();
430+
System.out.println("Thread interrupted, exiting...");
431+
break;
432+
}
433+
}
434+
}
435+
}
436+
437+
public class Main {
438+
public static void main(String[] args) throws InterruptedException {
439+
Thread thread = new Thread(new MyTask());
440+
thread.start();
441+
Thread.sleep(3000); // 主线程等待3秒
442+
thread.interrupt(); // 请求终止线程
443+
}
444+
}
445+
```
446+
447+
中断结果:
448+
449+
![二哥的Java 进阶之路:线程中断](https://cdn.tobebetterjavaer.com/stutymore/javathread-20241215110907.png)
450+
415451
> 1. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的招商银行面经同学 6 招银网络科技面试原题:线程的生命周期和状态?
416452
> 2. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的快手同学 2 一面面试原题:线程有哪些状态?
417453
> 3. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的 OPPO 面经同学 1 面试原题:Java里线程的生命周期

docs/src/sidebar/sanfene/jvm.md

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
title: JVM面试题,54道Java虚拟机八股文(1.5万字51张手绘图),面渣逆袭必看👍
33
shortTitle: 面渣逆袭-JVM
44
author: 三分恶
5-
date: 2024-10-20
5+
date: 2024-12-15
66
category:
77
- 面渣逆袭
88
tag:
@@ -1173,13 +1173,17 @@ Parallel Old 是 Parallel Scavenge 收集器的老年代版本,支持多线程
11731173

11741174
#### 说说 CMS 收集器?
11751175

1176-
以获取最短回收停顿时间为目标,采用“标记-清除”算法,分 4 大步进行垃圾收集,其中初始标记和重新标记会 STW,JDK 1.5 时引入,JDK9 被标记弃用,JDK14 被移除。
1176+
CMS 在 JDK 1.5 时引入,JDK 9 时被标记弃用,JDK 14 时被移除。
1177+
1178+
CMS 是一种低延迟的垃圾收集器,采用标记-清除算法,分为初始标记、并发标记、重新标记和并发清除四个阶段,优点是停顿时间短,适合延迟敏感的应用,但容易产生内存碎片,可能触发 Full GC。
11771179

11781180
![小潘:CMS](https://cdn.tobebetterjavaer.com/stutymore/gc-collector-20231228211056.png)
11791181

1180-
#### 说说 Garbage First 收集器?
1182+
#### 说说 G1 收集器?
1183+
1184+
G1 在 JDK 1.7 时引入,在 JDK 9 时取代 CMS 成为默认的垃圾收集器。
11811185

1182-
G1(Garbage-First Garbage Collector)在 JDK 1.7 时引入,在 JDK 9 时取代 CMS 成为了默认的垃圾收集器。G1 有五个属性:分代、增量、并行、标记整理、STW
1186+
G1 是一种面向大内存、高吞吐场景的垃圾收集器,它将堆划分为多个小的 Region,通过标记-整理算法,避免了内存碎片问题。优点是停顿时间可控,适合大堆场景,但调优较复杂
11831187

11841188
![有梦想的肥宅:G1](https://cdn.tobebetterjavaer.com/stutymore/gc-collector-20231228213824.png)
11851189

@@ -1207,6 +1211,7 @@ ZGC 是 JDK 11 时引入的一款低延迟的垃圾收集器,最大特点是
12071211
> 3. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的携程面经同学 10 Java 暑期实习一面面试原题:有哪些垃圾回收器,选一个讲一下垃圾回收的流程
12081212
> 4. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的京东同学 4 云实习面试原题:常见的 7 个 GC 回收器
12091213
> 5. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的美团面经同学 15 点评后端技术面试原题:讲一下知道的垃圾回收器,问知不知道ZGC回收器(不知道)
1214+
> 6. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的阿里云面经同学 22 面经:cms和g1的区别
12101215
12111216
### 32.能详细说一下 CMS 收集器的垃圾收集过程吗?
12121217

@@ -1715,12 +1720,13 @@ JVM 的操作对象是 Class 文件,JVM 把 Class 文件中描述类的数据
17151720
![三分恶面渣逆袭:双亲委派模型](https://cdn.tobebetterjavaer.com/tobebetterjavaer/images/sidebar/sanfene/jvm-46.png)
17161721

17171722
- 当一个类加载器需要加载某个类时,它首先会请求其父类加载器加载这个类。
1718-
- 这个过程会一直向上递归,也就是说,从子加载器到父加载器,再到更上层的加载器,一直到最顶层的启动类加载器(Bootstrap ClassLoader)
1723+
- 这个过程会一直向上递归,也就是说,从子加载器到父加载器,再到更上层的加载器,一直到最顶层的启动类加载器。
17191724
- 启动类加载器会尝试加载这个类。如果它能够加载这个类,就直接返回;如果它不能加载这个类(因为这个类不在它的搜索范围内),就会将加载任务返回给委托它的子加载器。
17201725
- 子加载器接着尝试加载这个类。如果子加载器也无法加载这个类,它就会继续向下传递这个加载任务,依此类推。
17211726
- 这个过程会继续,直到某个加载器能够加载这个类,或者所有加载器都无法加载这个类,最终抛出 ClassNotFoundException。
17221727

17231728
> 1. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的小米暑期实习同学 E 一面面试原题:你了解类的加载机制吗?
1729+
> 2. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的阿里云面经同学 22 面经:双亲委派机制
17241730
17251731
### 49.为什么要用双亲委派模型?
17261732

docs/src/sidebar/sanfene/linux.md

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,22 @@ head:
1818

1919
推荐阅读:[常用高频 Linux 速查备忘手册](https://javabetter.cn/pdf/linux.html)
2020

21-
我自己常用的 Linux 命令有 top 查看系统资源、ps 查看进程、netstat 查看网络连接、ping 测试网络连通性、find 查找文件、chmod 修改文件权限、kill 终止进程、df 查看磁盘空间、free 查看内存使用、service 启动服务、mkdir 创建目录、rm 删除文件、rmdir 删除目录、cp 复制文件、mv 移动文件、zip 压缩文件、unzip 解压文件等等这些。
21+
我自己常用的 Linux 命令有:
22+
23+
- top 用来查看系统资源
24+
- `ps -ef | grep java` 查看 Java 进程
25+
- `netstat` 查看网络连接
26+
- ping 测试网络连通性
27+
- find 查找文件
28+
- chmod 修改文件权限
29+
- kill 终止进程
30+
- df 查看磁盘空间
31+
- mkdir 创建目录、rm 删除文件、cp 复制文件、mv 移动文件
32+
- zip 压缩文件、unzip 解压文件等等这些。
2233

2334
> 1. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的作业帮面经同学 1 Java 后端一面面试原题:常用linux命令
2435
> 2. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的虾皮面经同学 13 一面面试原题:常见的linux命令
36+
> 3. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的阿里云面经同学 22 面经:linux常用命令
2537
2638
### 文件操作的命令有哪些?
2739

@@ -136,6 +148,12 @@ Linux 中的权限可以应用于三种类别的用户:
136148
- chmod 755 file:使得文件所有者有读写执行(7)权限,组用户和其他用户有读和执行(5)权限。
137149
- chmod 644 file:使得文件所有者有读写(6)权限,而组用户和其他用户只有读(4)权限。
138150

151+
#### `kill -9` 中的 9 是什么意思?
152+
153+
`kill -9 PID` 是一种强制终止进程的方式,其中的 9 表示信号编号,代表 SIGKILL 信号。
154+
155+
> 1. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的阿里云面经同学 22 面经:kill -9 9的意义是什么
156+
139157
### 网络管理的命令有哪些?
140158

141159
- `ping`:检查与远程服务器的连接。

docs/src/sidebar/sanfene/mysql.md

Lines changed: 80 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
title: MySQL面试题,84道MySQL八股文(1.8万字69张手绘图),面渣逆袭必看👍
33
shortTitle: 面渣逆袭-MySQL
44
description: 下载次数超 1 万次,1.8 万字 69 张手绘图,详解 84 道 MySQL 面试高频题(让天下没有难背的八股),面渣背会这些 MySQL 八股文,这次吊打面试官,我觉得稳了(手动 dog)。
5-
date: 2024-11-22
5+
date: 2024-12-25
66
author: 三分恶
77
category:
88
- 面渣逆袭
@@ -2815,13 +2815,6 @@ InnoDB 的行锁的主要实现如下:
28152815

28162816
![三分恶面渣逆袭:记录锁](https://cdn.tobebetterjavaer.com/tobebetterjavaer/images/sidebar/sanfene/mysql-8989ac27-e442-4c14-81ad-6bc133d78bfd.jpg)
28172817

2818-
②、**Gap Lock 间隙锁**
2819-
2820-
间隙锁(Gap Locks) 的间隙指的是两个记录之间逻辑上尚未填入数据的部分,是一个**左开右开空间**
2821-
2822-
![三分恶面渣逆袭:间隙锁](https://cdn.tobebetterjavaer.com/tobebetterjavaer/images/sidebar/sanfene/mysql-d60f3a42-4b0f-4612-b7ad-65191fecb852.jpg)
2823-
2824-
间隙锁就是锁定某些间隙区间的。当我们使用用等值查询或者范围查询,并且没有命中任何一个`record`,此时就会将对应的间隙区间锁定。例如`select * from t where id =3 for update;`或者`select * from t where id > 1 and id < 6 for update;`就会将(1,6)区间锁定。
28252818

28262819
③、**Next-key Lock 临键锁**
28272820

@@ -2852,6 +2845,66 @@ MySQL 默认行锁类型就是`临键锁(Next-Key Locks)`。当使用唯一性
28522845
> 1. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的美团面经同学 3 Java 后端技术一面面试原题:数据库中的全局锁 表锁 行级锁 每种锁的应用场景有哪些
28532846
> 2. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的招银网络科技面经同学 9 Java 后端技术一面面试原题:select for update 加锁有什么需要注意的
28542847
2848+
### 85. 间隙锁了解吗?(补充)
2849+
2850+
> 2024 年 12 月 15 日增补。
2851+
2852+
间隙锁用于在范围查询时锁定记录之间的“间隙”,防止其他事务在该范围内插入新记录。
2853+
2854+
假设表 test_gaplock 有 id、age、name 三个字段,其中 id 是主键,age 上有索引,并插入了 4 条数据。
2855+
2856+
```sql
2857+
CREATE TABLE `test_gaplock` (
2858+
`id` int(11) NOT NULL,
2859+
`age` int(11) DEFAULT NULL,
2860+
`name` varchar(20) DEFAULT NULL,
2861+
PRIMARY KEY (`id`),
2862+
KEY `age` (`age`)
2863+
) ENGINE=InnoDB;
2864+
2865+
insert into test_gaplock values(1,1,'张三'),(6,6,'吴老二'),(8,8,'赵四'),(12,12,'熊大');
2866+
```
2867+
2868+
间隙锁会锁住以下范围:
2869+
2870+
- (−∞, 1):在最小记录之前的间隙。
2871+
- (1, 6)、(6, 8)、(8, 12):记录之间的间隙。
2872+
- (12, +∞):在最大记录之后的间隙。
2873+
2874+
![三分恶面渣逆袭:间隙锁](https://cdn.tobebetterjavaer.com/tobebetterjavaer/images/sidebar/sanfene/mysql-d60f3a42-4b0f-4612-b7ad-65191fecb852.jpg)
2875+
2876+
假设有两个事务,T1 执行以下语句:
2877+
2878+
```sql
2879+
START TRANSACTION;
2880+
SELECT * FROM test_gaplock WHERE age > 5 FOR UPDATE;
2881+
```
2882+
2883+
T2 执行以下语句:
2884+
2885+
```sql
2886+
START TRANSACTION;
2887+
INSERT INTO test_gaplock VALUES (7, 7, '王五');
2888+
```
2889+
2890+
T1 会锁住 (6, 8) 的间隙,防止其他事务在这个范围内插入新记录。
2891+
2892+
T2 在插入 (7, 7, '王五') 时,会被阻塞,可以在另外一个回话中执行 `SHOW ENGINE INNODB STATUS` 查看间隙锁的信息。
2893+
2894+
![二哥的Java 进阶之路:间隙锁](https://cdn.tobebetterjavaer.com/stutymore/mysql-20241215095640.png)
2895+
2896+
推荐阅读:[六个案例搞懂间隙锁](https://www.51cto.com/article/779551.html)[MySQL中间隙锁的加锁机制](https://blog.csdn.net/javaanddonet/article/details/111187345)
2897+
2898+
#### 执行什么命令会加上间隙锁?
2899+
2900+
当范围查询与锁定操作(如 FOR UPDATE)结合时,InnoDB 会对查询范围内的记录间隙加上间隙锁。
2901+
2902+
```sql
2903+
SELECT * FROM table WHERE column > 10 and column < 20 FOR UPDATE;
2904+
```
2905+
2906+
> 1. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的阿里云面经同学 22 面经:mysql的什么命令会加上间隙锁
2907+
28552908
### 56.意向锁是什么知道吗?
28562909

28572910
意向锁是一个表级锁,不要和插入意向锁搞混。
@@ -3024,7 +3077,7 @@ redo log 是一种物理日志,当执行写操作时,MySQL 会先将更改
30243077
30253078
### 61.事务的隔离级别有哪些?
30263079

3027-
事务的隔离级别定了一个事务可能受其他事务影响的程度,MySQL 支持的四种隔离级别分别是:读未提交、读已提交、可重复读和串行化。
3080+
事务的隔离级别定了一个事务可能受其他事务影响的程度,MySQL 支持四种隔离级别,分别是:读未提交、读已提交、可重复读和串行化。
30283081

30293082
![三分恶面渣逆袭:事务的四个隔离级别](https://cdn.tobebetterjavaer.com/tobebetterjavaer/images/sidebar/sanfene/mysql-99942529-4a91-420b-9ce2-4149e747f64d.jpg)
30303083

@@ -3038,15 +3091,13 @@ redo log 是一种物理日志,当执行写操作时,MySQL 会先将更改
30383091

30393092
#### 什么是可重复读?
30403093

3041-
可重复读能够确保在同一事务中多次读取相同记录的结果是一致的,即使其他事务对这条记录进行了修改,也不会影响到当前事务
3094+
可重复读是指一个事务在执行过程中看到的数据,一直跟这个事务启动时看到的数据是一致的
30423095

3043-
可重复读是 MySQL 默认的隔离级别,避免了“脏读”和“不可重复读”,但可能会出现幻读
3096+
**可重复读是 MySQL 默认的隔离级别**,避免了“脏读”和“不可重复读”,也能在一定程度上避免幻读
30443097

30453098
#### 什么是串行化?
30463099

3047-
串行化是最高的隔离级别,通过强制事务串行执行来避免并发问题,可以解决“脏读”、“不可重复读”和“幻读”问题。
3048-
3049-
但会导致大量的超时和锁竞争问题。
3100+
串行化是最高的隔离级别,通过强制事务串行执行来解决“脏读”、“不可重复读”和“幻读”问题。但会导致大量的锁竞争问题。
30503101

30513102
#### A 事务未提交,B 事务上查询到的是旧值还是新值?
30523103

@@ -3130,6 +3181,14 @@ COMMIT;
31303181

31313182
需要解决幻读的场景一般是对数据一致性要求较高的业务,例如银行转账、库存管理等,而在一些只要求最终一致性的应用场景中(如统计功能),可以忽略幻读问题。
31323183

3184+
#### 如何避免幻读?
3185+
3186+
①、直接使用最高的隔离级别串行化,但会导致大量的锁竞争。
3187+
3188+
②、使用间隙锁,防止其他事务在间隙范围内插入数据。
3189+
3190+
③、在可重复读的隔离级别下,MVCC 机制会为每个事务维护一个快照,事务在读取数据时,只能读取到快照中的数据,而不会读取到其他事务插入的数据。
3191+
31333192
#### 不同的隔离级别,在并发事务下可能会发生什么问题?
31343193

31353194
| 隔离级别 | 脏读 | 不可重复读 | 幻读 |
@@ -3140,6 +3199,7 @@ COMMIT;
31403199
| Serialzable 可串行化 ||||
31413200

31423201
> 1. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的京东面经同学 7 京东到家面试原题:mysql事务隔离级别,默认隔离级别,如何避免幻读
3202+
> 2. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的阿里云面经同学 22 面经:事务隔离级别,幻读和脏读的区别,如何防止幻读,事务的mvcc机制
31433203
31443204
### 63.事务的隔离级别是如何实现的?
31453205

@@ -3158,13 +3218,15 @@ COMMIT;
31583218
31593219
### 64.MVCC 了解吗?怎么实现的?
31603220

3161-
MVCC 指的是多版本并发控制,主要用来解决数据库的并发问题
3221+
MVCC 指的是多版本并发控制,简单来说,就是给我们的 MySQL 数据拍个“快照”,定格某个时刻数据库的状态
31623222

3163-
当多个用户同时访问数据时,每个用户都可以看到一个在某一时间点之前的数据库快照,并且能够无阻塞地执行查询和修改操作,而不会相互干扰
3223+
在 MySQL 中,MVCC 是通过版本链和 ReadView 机制来实现的
31643224

3165-
MVCC 允许读操作访问数据的一个旧版本快照,同时写操作创建一个新的版本,这样读写操作就可以并行进行,不必等待对方完成。
3225+
![天瑕:undo log 版本链和 ReadView](https://cdn.tobebetterjavaer.com/stutymore/mysql-20241215073837.png)
31663226

3167-
在 MySQL 中,特别是 InnoDB 存储引擎,MVCC 是通过版本链和 ReadView 机制来实现的。
3227+
1. 每条记录包含两个隐藏列:最近修改的事务 ID 和指向 Undo Log 的指针,用于构成版本链。
3228+
2. 每次更新数据时,会生成一个新的数据版本,并将旧版本的数据保存到 Undo Log 中。
3229+
3. 每次读取数据时,会生成一个 ReadView,用于判断哪个版本的数据对当前事务可见。
31683230

31693231
#### 什么是版本链?
31703232

0 commit comments

Comments
 (0)