Skip to content

Commit 7e7fb51

Browse files
committed
spring源码
1 parent 5dda342 commit 7e7fb51

30 files changed

+6135
-7
lines changed

docs/advance/distributed/2-distributed-lock.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,8 @@ public class RedisTest {
181181

182182
前面的方案是基于**Redis单机版**的分布式锁讨论,还不是很完美。因为Redis一般都是集群部署的。
183183

184+
![](http://img.topjavaer.cn/img/202308202338736.png)
185+
184186
如果线程一在`Redis``master`节点上拿到了锁,但是加锁的`key`还没同步到`slave`节点。恰好这时,`master`节点发生故障,一个`slave`节点就会升级为`master`节点。线程二就可以顺理成章获取同个`key`的锁啦,但线程一也已经拿到锁了,锁的安全性就没了。
185187

186188
为了解决这个问题,Redis作者antirez提出一种高级的分布式锁算法:**Redlock**。它的核心思想是这样的:
@@ -189,6 +191,8 @@ public class RedisTest {
189191

190192
我们假设当前有5个Redis master节点,在5台服务器上面运行这些Redis实例。
191193

194+
![](http://img.topjavaer.cn/img/202308202339712.png)
195+
192196
RedLock的实现步骤:
193197

194198
1. 获取当前时间,以毫秒为单位。
@@ -204,6 +208,8 @@ RedLock的实现步骤:
204208
- 如果大于等于3个节点加锁成功,并且使用的时间小于锁的有效期,即可认定加锁成功啦。
205209
- 如果获取锁失败,解锁!
206210

211+
Redisson 实现了 redLock 版本的锁,有兴趣的小伙伴,可以去了解一下。
212+
207213
### 基于ZooKeeper的实现方式
208214

209215
ZooKeeper是一个为分布式应用提供一致性服务的开源组件,它内部是一个分层的文件系统目录树结构,规定同一个目录下只能有一个唯一文件名。基于ZooKeeper实现分布式锁的步骤如下:

docs/advance/distributed/4-micro-service.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,15 @@ head:
4747

4848
## 分布式和微服务的区别
4949

50-
从概念理解,分布式服务架构强调的是服务化以及服务的**分散化**,微服务则更强调服务的**专业化和精细分工**
50+
微服务解决的是系统复杂度问题,一般来说是业务问题,即在一个系统中承担职责太多了,需要打散,便于理解和维护,进而提升系统的开发效率和运行效率,微服务一般来说是针对应用层面的。
5151

52-
从实践的角度来看,**微服务架构通常是分布式服务架构**,反之则未必成立。
52+
分布式解决的是系统性能问题,即解决系统部署上单点的问题,尽量让组成系统的子系统分散在不同的机器上进而提高系统的吞吐能力。
53+
54+
两者概念层面也是不一样的,微服务是设计层面的东西,一般考虑如何将系统从逻辑上进行拆分,也就是垂直拆分;
55+
56+
而分布式是部署层面的东西,即强调物理层面的组成,即系统的各子系统部署在不同计算机上。
57+
58+
微服务可以是分布式的,即可以将不同服务部署在不同计算机上,当然如果量小也可以部署在单机上。
5359

5460
一句话概括:分布式:分散部署;微服务:分散能力。
5561

docs/advance/system-design/README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626

2727
怎么加入[知识星球](https://topjavaer.cn/zsxq/introduce.html)
2828

29-
**扫描以下二维码**领取50元的优惠券即可加入。星球定价**158**元,减去**50**元的优惠券,等于说只需要**108**元的价格就可以加入,服务期一年,**每天不到三毛钱**(0.29元),相比培训班几万块的学费,非常值了,星球提供的服务可以说**远超**门票价格了。
29+
**扫描以下二维码**领取50元的优惠券即可加入。星球定价**188**元,减去**50**元的优惠券,等于说只需要**138**元的价格就可以加入,服务期一年,**每天只要三毛钱**(0.37元),相比培训班几万块的学费,非常值了,星球提供的服务可以说**远超**门票价格了。
30+
31+
随着星球内容不断积累,星球定价也会不断**上涨**(最初原价**68**元,现在涨到**188**元了,后面还会持续**上涨**),所以,想提升自己的小伙伴要趁早加入,**早就是优势**(优惠券只有50个名额,用完就恢复**原价**了)。
3032

3133
![](http://img.topjavaer.cn/img/202304212233017.png)

docs/computer-basic/network.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ head:
4141

4242
怎么加入[知识星球](https://topjavaer.cn/zsxq/introduce.html)
4343

44-
**扫描以下二维码**领取50元的优惠券即可加入。星球定价**158**元,减去**50**元的优惠券,等于说只需要**108**元的价格就可以加入,服务期一年,**每天不到三毛钱**(0.29元),相比培训班几万块的学费,非常值了,星球提供的服务可以说**远超**门票价格了。
44+
**扫描以下二维码**领取50元的优惠券即可加入。星球定价**188**元,减去**50**元的优惠券,等于说只需要**138**元的价格就可以加入,服务期一年,**每天只要三毛钱**(0.37元),相比培训班几万块的学费,非常值了,星球提供的服务可以说**远超**门票价格了。
45+
46+
随着星球内容不断积累,星球定价也会不断**上涨**(最初原价**68**元,现在涨到**188**元了,后面还会持续**上涨**),所以,想提升自己的小伙伴要趁早加入,**早就是优势**(优惠券只有50个名额,用完就恢复**原价**了)。
4547

4648
![](http://img.topjavaer.cn/img/202304212233017.png)

docs/database/mysql.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1180,4 +1180,38 @@ COUNT(`*`)是SQL92定义的标准统计行数的语法,效率高,MySQL对它
11801180

11811181
所以,建议使用COUNT(\*)查询表的行数!
11821182

1183+
## 存储MD5值应该用VARCHAR还是用CHAR?
1184+
1185+
首先说说CHAR和VARCHAR的区别:
1186+
1187+
1、存储长度:
1188+
1189+
CHAR类型的长度是固定的
1190+
1191+
当我们当定义CHAR(10),输入的值是"abc",但是它占用的空间一样是10个字节,会包含7个空字节。当输入的字符长度超过指定的数时,CHAR会截取超出的字符。而且,当存储为CHAR的时候,MySQL会自动删除输入字符串末尾的空格。
1192+
1193+
VARCHAR的长度是可变的
1194+
1195+
比如VARCHAR(10),然后输入abc三个字符,那么实际存储大小为3个字节。
1196+
1197+
除此之外,VARCHAR还会保留1个或2个额外的字节来记录字符串的实际长度。如果定义的最大长度小于等于255个字节,那么,就会预留1个字节;如果定义的最大长度大于255个字节,那么就会预留2个字节。
1198+
1199+
2、存储效率
1200+
1201+
CHAR类型每次修改后的数据长度不变,效率更高。
1202+
1203+
VARCHAR每次修改的数据要更新数据长度,效率更低。
1204+
1205+
3、存储空间
1206+
1207+
CHAR存储空间是初始的预计长度字符串再加上一个记录字符串长度的字节,可能会存在多余的空间。
1208+
1209+
VARCHAR存储空间的时候是实际字符串再加上一个记录字符串长度的字节,占用空间较小。
1210+
1211+
1212+
1213+
根据以上的分析,由于MD5是一个定长的值,所以MD5值适合使用CHAR存储。对于固定长度的非常短的列,CHAR比VARCHAR效率也更高。
1214+
1215+
1216+
11831217
![](http://img.topjavaer.cn/img/20220612101342.png)

docs/java/java-basic.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,8 @@ Integer x = 1; // 装箱 调⽤ Integer.valueOf(1)
274274
int y = x; // 拆箱 调⽤了 X.intValue()
275275
```
276276

277+
## 两个Integer 用== 比较不相等的原因
278+
277279
下面看一道常见的面试题:
278280

279281
```java

docs/java/java-concurrent.md

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,14 @@ executor提供一个原生函数isTerminated()来判断线程池中的任务是
231231
- 调用new Thread()创建的线程缺乏管理,可以无限制的创建,线程之间的相互竞争会导致过多占用系统资源而导致系统瘫痪
232232
- 直接使用new Thread()启动的线程不利于扩展,比如定时执行、定期执行、定时定期执行、线程中断等都不好实现
233233

234+
## execute和submit的区别
235+
236+
execute只能提交Runnable类型的任务,无返回值。submit既可以提交Runnable类型的任务,也可以提交Callable类型的任务,会有一个类型为Future的返回值,但当任务类型为Runnable时,返回值为null。
237+
238+
execute在执行任务时,如果遇到异常会直接抛出,而submit不会直接抛出,只有在使用Future的get方法获取返回值时,才会抛出异常
239+
240+
execute所属顶层接口是Executor,submit所属顶层接口是ExecutorService,实现类ThreadPoolExecutor重写了execute方法,抽象类AbstractExecutorService重写了submit方法。
241+
234242
## 进程线程
235243

236244
进程是指一个内存中运行的应用程序,每个进程都有自己独立的一块内存空间。
@@ -1238,4 +1246,115 @@ epoll的时间复杂度O(1)。epoll可以理解为event poll,不同于忙轮
12381246

12391247
> 参考链接:https://blog.csdn.net/u014209205/article/details/80598209
12401248
1249+
## ReadWriteLock 和 StampedLock 的区别
1250+
1251+
在多线程编程中,对于共享资源的访问控制是一个非常重要的问题。在并发环境下,多个线程同时访问共享资源可能会导致数据不一致的问题,因此需要一种机制来保证数据的一致性和并发性。
1252+
1253+
Java提供了多种机制来实现并发控制,其中 ReadWriteLock 和 StampedLock 是两个常用的锁类。本文将分别介绍这两个类的特性、使用场景以及示例代码。
1254+
1255+
**ReadWriteLock**
1256+
1257+
ReadWriteLock 是Java提供的一个接口,全类名:`java.util.concurrent.locks.ReentrantLock`。它允许多个线程同时读取共享资源,但只允许一个线程写入共享资源。这种机制可以提高读取操作的并发性,但写入操作需要独占资源。
1258+
1259+
**特性**
1260+
1261+
- 多个线程可以同时获取读锁,但只有一个线程可以获取写锁。
1262+
- 当一个线程持有写锁时,其他线程无法获取读锁和写锁,读写互斥。
1263+
- 当一个线程持有读锁时,其他线程可以同时获取读锁,读读共享。
1264+
1265+
**使用场景**
1266+
1267+
**ReadWriteLock** 适用于读多写少的场景,例如缓存系统、数据库连接池等。在这些场景中,读取操作占据大部分时间,而写入操作较少。
1268+
1269+
**示例代码**
1270+
1271+
下面是一个使用 ReadWriteLock 的示例,实现了一个简单的缓存系统:
1272+
1273+
```java
1274+
public class Cache {
1275+
private Map<String, Object> data = new HashMap<>();
1276+
private ReadWriteLock lock = new ReentrantReadWriteLock();
1277+
1278+
public Object get(String key) {
1279+
lock.readLock().lock();
1280+
try {
1281+
return data.get(key);
1282+
} finally {
1283+
lock.readLock().unlock();
1284+
}
1285+
}
1286+
1287+
public void put(String key, Object value) {
1288+
lock.writeLock().lock();
1289+
try {
1290+
data.put(key, value);
1291+
} finally {
1292+
lock.writeLock().unlock();
1293+
}
1294+
}
1295+
}
1296+
```
1297+
1298+
在上述示例中,Cache 类使用 ReadWriteLock 来实现对 data 的并发访问控制。get 方法获取读锁并读取数据,put 方法获取写锁并写入数据。
1299+
1300+
**StampedLock**
1301+
1302+
StampedLock 是Java 8 中引入的一种新的锁机制,全类名:`java.util.concurrent.locks.StampedLock`,它提供了一种乐观读的机制,可以进一步提升读取操作的并发性能。
1303+
1304+
**特性**
1305+
1306+
- 与 ReadWriteLock 类似,StampedLock 也支持多个线程同时获取读锁,但只允许一个线程获取写锁。
1307+
- 与 ReadWriteLock 不同的是,StampedLock 还提供了一个乐观读锁(Optimistic Read Lock),即不阻塞其他线程的写操作,但在读取完成后需要验证数据的一致性。
1308+
1309+
**使用场景**
1310+
1311+
StampedLock 适用于读远远大于写的场景,并且对数据的一致性要求不高,例如统计数据、监控系统等。
1312+
1313+
**示例代码**
1314+
1315+
下面是一个使用 StampedLock 的示例,实现了一个计数器:
1316+
1317+
```java
1318+
public class Counter {
1319+
private int count = 0;
1320+
private StampedLock lock = new StampedLock();
1321+
1322+
public int getCount() {
1323+
long stamp = lock.tryOptimisticRead();
1324+
int value = count;
1325+
if (!lock.validate(stamp)) {
1326+
stamp = lock.readLock();
1327+
try {
1328+
value = count;
1329+
} finally {
1330+
lock.unlockRead(stamp);
1331+
}
1332+
}
1333+
return value;
1334+
}
1335+
1336+
public void increment() {
1337+
long stamp = lock.writeLock();
1338+
try {
1339+
count++;
1340+
} finally {
1341+
lock.unlockWrite(stamp);
1342+
}
1343+
}
1344+
}
1345+
```
1346+
1347+
在上述示例中,Counter 类使用 StampedLock 来实现对计数器的并发访问控制。getCount 方法首先尝试获取乐观读锁,并读取计数器的值,然后通过 validate 方法验证数据的一致性。如果验证失败,则获取悲观读锁,并重新读取计数器的值。increment 方法获取写锁,并对计数器进行递增操作。
1348+
1349+
**总结**
1350+
1351+
**ReadWriteLock****StampedLock** 都是Java中用于并发控制的重要机制。
1352+
1353+
- **ReadWriteLock** 适用于读多写少的场景;
1354+
- **StampedLock** 则适用于读远远大于写的场景,并且对数据的一致性要求不高;
1355+
1356+
在实际应用中,我们需要根据具体场景来选择合适的锁机制。通过合理使用这些锁机制,我们可以提高并发程序的性能和可靠性。
1357+
1358+
1359+
12411360
![](http://img.topjavaer.cn/img/20220612101342.png)

docs/java/jvm.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626

2727
怎么加入[知识星球](https://topjavaer.cn/zsxq/introduce.html)
2828

29-
**扫描以下二维码**领取50元的优惠券即可加入。星球定价**158**元,减去**50**元的优惠券,等于说只需要**108**元的价格就可以加入,服务期一年,**每天不到三毛钱**(0.29元),相比培训班几万块的学费,非常值了,星球提供的服务可以说**远超**门票价格了。
29+
**扫描以下二维码**领取50元的优惠券即可加入。星球定价**188**元,减去**50**元的优惠券,等于说只需要**138**元的价格就可以加入,服务期一年,**每天只要三毛钱**(0.37元),相比培训班几万块的学费,非常值了,星球提供的服务可以说**远超**门票价格了。
30+
31+
随着星球内容不断积累,星球定价也会不断**上涨**(最初原价**68**元,现在涨到**188**元了,后面还会持续**上涨**),所以,想提升自己的小伙伴要趁早加入,**早就是优势**(优惠券只有50个名额,用完就恢复**原价**了)。
3032

3133
![](http://img.topjavaer.cn/img/202304212233017.png)

docs/note/README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
- [一小时彻底吃透Redis](https://topjavaer.cn/note/redis-note.html)
2+
- [21个写SQL的好习惯](https://topjavaer.cn/note/write-sql.html)
3+
- [Docker详解与部署微服务实战](https://topjavaer.cn/note/docker-note.html)
4+
- [计算机专业的同学都看看这几点建议](https://topjavaer.cn/note/computor-advice.html)
5+
- [建议计算机专业同学都看看这门课](https://topjavaer.cn/note/computor-advice.html)
6+

docs/note/redis-note.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
::: tip 这是一则或许对你有帮助的信息
2+
3+
- **面试手册**:这是一份大彬精心整理的[**大厂面试手册**](https://topjavaer.cn/zsxq/mianshishouce.html)最新版,目前已经更新迭代了**19**个版本,质量很高(专为面试打造)
4+
- **知识星球****专属面试手册/一对一交流/简历修改/超棒的学习氛围/学习路线规划**,欢迎加入[大彬的知识星球](https://topjavaer.cn/zsxq/introduce.html)(点击链接查看星球的详细介绍)
5+
6+
:::
7+
8+
## 一小时彻底吃透Redis
9+
10+
![1](http://img.topjavaer.cn/img/202308210012725.png)
11+
12+
![](http://img.topjavaer.cn/img/202308210012963.png)
13+
14+
![3](http://img.topjavaer.cn/img/202308210013864.png)
15+
16+
17+
18+
![4](http://img.topjavaer.cn/img/202308210013844.png)
19+
20+
![5](http://img.topjavaer.cn/img/202308210013997.png)
21+
22+
![6](http://img.topjavaer.cn/img/202308210013008.png)
23+
24+
![7](http://img.topjavaer.cn/img/202308210013799.png)
25+
26+
![8](http://img.topjavaer.cn/img/202308210013103.png)
27+
28+
![9](http://img.topjavaer.cn/img/202308210013210.png)

0 commit comments

Comments
 (0)