1. 什么是锁的重入,为什么要锁重入?
锁重入的含义
锁重入(Reentrant Lock)指的是同一个线程在持有锁的情况下,可以多次获得该锁而不会发生死锁。
Java 中的 ReentrantLock
就是一种可重入锁,而 synchronized
关键字本质上也是可重入的。
为什么需要锁重入?
如果锁不能重入,线程在递归调用或父类方法调用子类方法时,会因再次申请相同的锁而发生死锁。
示例 1:递归调用
public synchronized void method1() {
method2(); // 如果锁不能重入,这里会死锁
}
public synchronized void method2() {
System.out.println("method2 called");
}
method1()
已经持有了锁,再调用method2()
时,如果锁不可重入,就会阻塞在method2()
上。- 可重入锁避免了这种问题,保证同一线程能多次获得锁。
业务场景举例
- 递归算法实现:例如计算斐波那契数列时,递归方法需要多次申请锁。
- 父类与子类方法调用:子类重写父类方法,调用
super.method()
需要再次申请锁。
2. 什么是 PSYNC?
PSYNC 的含义
PSYNC 是 Redis 复制机制中的一种增量同步命令,Partial Resynchronization(部分同步) 的缩写。
它用于主从服务器之间同步数据,避免全量复制,提升效率。
PSYNC 的两种模式
- PSYNC with backlog(增量同步)
主从服务器通过复制积压缓冲区(replication backlog buffer)记录增量数据,从服务器只需要同步自上次断开以来的数据。 - PSYNC full resync(全量同步)
当增量数据丢失或积压缓冲区过小无法存储所有更新时,进行全量复制,传输整个 RDB 文件。
3. BGSAVE 全称与作用
BGSAVE 的全称
BGSAVE(Background Save),即后台持久化保存。
作用
BGSAVE
命令会在后台创建 Redis 数据的 RDB 快照(持久化文件),用于备份或数据恢复。
- 优点:不会阻塞主线程,Redis 仍能处理请求。
- 缺点:在磁盘 I/O 压力较大时,可能导致性能下降。
4. 上下文切换与竞争条件
上下文切换(Context Switch)
上下文切换指的是 CPU 从执行一个线程,切换到另一个线程时的过程。
上下文切换带来的开销:
- 保存当前线程状态(寄存器、程序计数器、堆栈等)。
- 加载新线程状态,并恢复到运行状态。
实例解释
假设有两个线程 A 和 B 争抢 CPU:
- 当线程 A 正在执行时,线程 B 需要 CPU 资源,于是操作系统暂停线程 A,切换到线程 B。
- 这种频繁切换会导致 CPU 开销增加,降低系统性能。
竞争条件(Race Condition)
竞争条件是指多个线程在无同步机制的情况下,访问共享资源,导致结果不可预期。
实例
两个线程同时更新一个共享变量 count
:
count = count + 1;
- 如果没有加锁,两个线程可能会同时读取相同的
count
值,导致结果错误。
5. 主键查询与主键索引查询的区别
主键查询
主键查询是通过主键值直接定位到数据行的查询方式。它是 MySQL 查询中最快的一种方式。
主键索引查询
主键索引查询是通过主键索引树来查找数据的过程。
区别
- 主键查询只会返回一条记录。
- 主键索引查询是通过 B+ 树索引来定位记录,但如果索引树较深,查询时间可能略有增加。
6. eq_ref 的含义与全称
eq_ref 的全称
eq_ref
中的 eq
代表 equal(等于),ref
代表 reference(引用)。
eq_ref 的特点
eq_ref
是 MySQL 中 Join 查询中最精准的一种连接类型。- 适用于 唯一索引或主键查询,每次查询最多返回一条结果。
7. 什么是回表?
回表的含义
回表指的是在索引查询时,MySQL 通过二级索引找到主键值后,再到聚簇索引(数据表)中查找完整记录的过程。
为什么回表会影响性能?
回表增加了额外的磁盘 I/O 操作,尤其当数据量较大时,性能下降明显。
如何避免回表?
- 使用覆盖索引(
index-only
):即查询的数据完全可以通过索引获取,避免回表。 - 减少查询的字段,只查询必要的列。
8. key_len 的作用
key_len 的含义
key_len
是 MySQL EXPLAIN
结果中的一个字段,表示MySQL 使用的索引长度(字节数)。
作用
key_len
可以帮助判断 MySQL 是否正确使用了索引。- 它反映了查询时索引的利用程度,以及是否使用了联合索引的所有字段。
9. 全索引扫描与唯一索引扫描的区别
全索引扫描
- 顺序扫描索引树的所有叶子节点,逐条检查是否符合条件。
- 性能较低,接近全表扫描,时间复杂度为 O(n)。
唯一索引扫描
- 通过唯一索引直接定位到目标记录,只需一次查找操作。
- 性能极高,时间复杂度接近 O(1)。
10. ref 索引查询与 index 索引树扫描的区别
ref 索引查询
- 通过索引精准定位小范围数据,只扫描符合条件的记录范围,效率较高。
- 适用于非唯一索引或联合索引的前缀字段查询。
index 索引树扫描
- 顺序扫描整个索引树,从第一个叶子节点到最后一个节点,检查所有记录。
- 性能较低,时间复杂度为 O(n)。
性能差异原因
- ref 查询 只扫描有限的索引范围,减少 I/O 开销。
- index 扫描 需要读取所有索引记录,耗费更多时间。