Skip to content

Commit 5b024f2

Browse files
committed
feat: 更新图片链接
1 parent b0400e2 commit 5b024f2

22 files changed

+347
-358
lines changed

docs/B树和B+树详解.md

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ B树是一种平衡的多叉树,通常我们说m阶的B树,它必须满足
2626

2727
B树中一个节点的子节点数目的最大值,用m表示,假如最大值为4,则为4阶,如图
2828

29-
![](https://gitee.com/wardseptember/images/raw/master/imgs/20200926202114.png)
29+
![](../imgs/20200926202114.png)
3030

3131
所有节点中,节点【13,16,19】拥有的子节点数目最多,四个子节点(灰色节点),所以可以定义上面的图片为4阶B树,现在懂什么是阶了吧
3232

@@ -59,47 +59,47 @@ B树中一个节点的子节点数目的最大值,用m表示,假如最大值
5959
- 1<=根节点元素个数<=4
6060
- 2<=非根节点元素个数<=4
6161

62-
![](https://gitee.com/wardseptember/images/raw/master/imgs/20200926202239.png)
62+
![](../imgs/20200926202239.png)
6363

64-
![](https://gitee.com/wardseptember/images/raw/master/imgs/20200926202335.png)
64+
![](../imgs/20200926202335.png)
6565

6666
​ 插入8
6767

6868
图(1)插入元素【8】后变为图(2),此时根节点元素个数为5,不符合 1<=根节点元素个数<=4,进行分裂(真实情况是先分裂,然后插入元素,这里是为了直观而先插入元素,下面的操作都一样,不再赘述),取节点中间元素【7】,加入到父节点,左右分裂为2个节点,如图(3)
6969

70-
<div align="center"> <img src="https://gitee.com/wardseptember/images/raw/master/imgs/20201030151640.png" width="600"/> </div><br>
70+
<div align="center"> <img src="../imgs/20201030151640.png" width="600"/> </div><br>
7171

7272
接着插入元素【5】,【11】,【17】时,不需要任何分裂操作,如图(4)
7373

74-
![](https://gitee.com/wardseptember/images/raw/master/imgs/20200926202722.png)
74+
![](../imgs/20200926202722.png)
7575

7676
插入元素【13】
7777

78-
![](https://gitee.com/wardseptember/images/raw/master/imgs/20200926202810.png)
78+
![](../imgs/20200926202810.png)
7979

8080
节点元素超出最大数量,进行分裂,提取中间元素【13】,插入到父节点当中,如图(6)
8181

82-
![](https://gitee.com/wardseptember/images/raw/master/imgs/20200926202839.png)
82+
![](../imgs/20200926202839.png)
8383

8484

8585

8686
接着插入元素【6】,【12】,【20】,【23】时,不需要任何分裂操作,如图(7)
8787

88-
![](https://gitee.com/wardseptember/images/raw/master/imgs/20200926202910.png)
88+
![](../imgs/20200926202910.png)
8989

9090
插入【26】时,最右的叶子结点空间满了,需要进行分裂操作,中间元素【20】上移到父节点中,注意通过上移中间元素,树最终还是保持平衡,分裂结果的结点存在2个关键字元素。
9191

92-
![](https://gitee.com/wardseptember/images/raw/master/imgs/20200926202928.png)
92+
![](../imgs/20200926202928.png)
9393

9494

9595

9696
插入【4】时,导致最左边的叶子结点被分裂,【4】恰好也是中间元素,上移到父节点中,然后元素【16】,【18】,【24】,【25】陆续插入不需要任何分裂操作
9797

98-
![](https://gitee.com/wardseptember/images/raw/master/imgs/20200926202952.png)
98+
![](../imgs/20200926202952.png)
9999

100100
最后,当插入【19】时,含有【14】,【16】,【17】,【18】的结点需要分裂,把中间元素【17】上移到父节点中,但是情况来了,父节点中空间已经满了,所以也要进行分裂,将父节点中的中间元素【13】上移到新形成的根结点中,这样具体插入操作的完成。
101101

102-
![](https://gitee.com/wardseptember/images/raw/master/imgs/20200926203022.png)
102+
![](../imgs/20200926203022.png)
103103

104104
## **删除**
105105

@@ -115,27 +115,27 @@ B树中一个节点的子节点数目的最大值,用m表示,假如最大值
115115

116116
如图依次删除依次删除【8】,【20】,【18】,【5】
117117

118-
![](https://gitee.com/wardseptember/images/raw/master/imgs/20200926203135.png)
118+
![](../imgs/20200926203135.png)
119119

120120
首先删除元素【8】,当然首先查找【8】,【8】在一个叶子结点中,删除后该叶子结点元素个数为2,符合B树规则,操作很简单,咱们只需要移动【11】至原来【8】的位置,移动【12】至【11】的位置(也就是结点中删除元素后面的元素向前移动)
121121

122-
![](https://gitee.com/wardseptember/images/raw/master/imgs/20200926203202.png)
122+
![](../imgs/20200926203202.png)
123123

124124
下一步,删除【20】,因为【20】没有在叶子结点中,而是在中间结点中找到,咱们发现他的继承者【23】(字母升序的下个元素),将【23】上移到【20】的位置,然后将孩子结点中的【23】进行删除,这里恰好删除后,该孩子结点中元素个数大于2,无需进行合并操作。
125125

126-
![](https://gitee.com/wardseptember/images/raw/master/imgs/20200926203219.png)
126+
![](../imgs/20200926203219.png)
127127

128128
下一步删除【18】,【18】在叶子结点中,但是该结点中元素数目为2,删除导致只有1个元素,已经小于最小元素数目2,而由前面我们已经知道:如果其某个相邻兄弟结点中比较丰满(元素个数大于ceil(5/2)-1=2),则可以向父结点借一个元素,然后将最丰满的相邻兄弟结点中上移最后或最前一个元素到父节点中,在这个实例中,右相邻兄弟结点中比较丰满(3个元素大于2),所以先向父节点借一个元素【23】下移到该叶子结点中,代替原来【19】的位置,【19】前移;然【24】在相邻右兄弟结点中上移到父结点中,最后在相邻右兄弟结点中删除【24】,后面元素前移。
129129

130-
<div align="center"> <img src="https://gitee.com/wardseptember/images/raw/master/imgs/20201030151726.png" width="600"/> </div><br>
130+
<div align="center"> <img src="../imgs/20201030151726.png" width="600"/> </div><br>
131131

132132
最后一步删除【5】, 删除后会导致很多问题,因为【5】所在的结点数目刚好达标,刚好满足最小元素个数(ceil(5/2)-1=2),而相邻的兄弟结点也是同样的情况,删除一个元素都不能满足条件,所以需要该节点与某相邻兄弟结点进行合并操作;首先移动父结点中的元素(该元素在两个需要合并的两个结点元素之间)下移到其子结点中,然后将这两个结点进行合并成一个结点。所以在该实例中,咱们首先将父节点中的元素【4】下移到已经删除【5】而只有【6】的结点中,然后将含有【4】和【6】的结点和含有【1】,【3】的相邻兄弟结点进行合并成一个结点。
133-
![](https://gitee.com/wardseptember/images/raw/master/imgs/20200926203302.png)
133+
![](../imgs/20200926203302.png)
134134

135135

136136

137137
也许你认为这样删除操作已经结束了,其实不然,在看看上图,对于这种特殊情况,你立即会发现父节点只包含一个元素【7】,没达标(因为非根节点包括叶子结点的元素K必须满足于2=<K<=4,而此处的K=1),这是不能够接受的。如果这个问题结点的相邻兄弟比较丰满,则可以向父结点借一个元素。而此时兄弟节点元素刚好为2,刚刚满足,只能进行合并,而根结点中的唯一元素【13】下移到子结点,这样,树的高度减少一层。
138-
![](https://gitee.com/wardseptember/images/raw/master/imgs/20200926203320.png)
138+
![](../imgs/20200926203320.png)
139139

140140
看完插入,删除,想必也把B树的特征掌握了。
141141

@@ -147,7 +147,7 @@ B树中一个节点的子节点数目的最大值,用m表示,假如最大值
147147

148148
  外存储器即为磁盘读取,磁盘读取数据靠的是机械运动,每次读取数据花费的时间可以分为寻道时间、旋转延迟、传输时间三个部分,寻道时间指的是磁臂移动到指定磁道所需要的时间,主流磁盘一般在5ms以下;旋转延迟就是我们经常听说的磁盘转速,比如一个磁盘7200转,表示每分钟能转7200次,也就是说1秒钟能转120次,旋转延迟就是1/120/2 = 4.17ms;传输时间指的是从磁盘读出或将数据写入磁盘的时间,一般在零点几毫秒,相对于前两个时间可以忽略不计。那么访问一次磁盘的时间,即一次磁盘IO的时间约等于5+4.17 = 9ms左右,听起来还挺不错的,但要知道一台500 -MIPS的机器每秒可以执行5亿条指令,因为指令依靠的是电的性质,换句话说执行一次IO的时间可以执行40万条指令,数据库动辄十万百万乃至千万级数据,每次9毫秒的时间,显然是个灾难。下图是计算机硬件延迟的对比图,供大家参考:
149149

150-
![](https://gitee.com/wardseptember/images/raw/master/imgs/20200926210045.png)
150+
![](../imgs/20200926210045.png)
151151

152152
考虑到磁盘IO是非常高昂的操作,计算机操作系统做了一些优化,当一次IO时,不光把当前磁盘地址的数据,而是把相邻的数据也都读取到内存缓冲区内,因为局部预读性原理告诉我们,当计算机访问一个地址的数据的时候,与其相邻的数据也会很快被访问到。每一次IO读取的数据我们称之为一页(page)。具体一页有多大数据跟操作系统有关,一般为4k或8k,也就是我们读取一页内的数据时候,实际上才发生了一次IO,这个理论对于索引的数据结构设计非常有帮助。
153153

@@ -171,7 +171,7 @@ B树中一个节点的子节点数目的最大值,用m表示,假如最大值
171171

172172
算法如下
173173

174-
![](https://gitee.com/wardseptember/images/raw/master/imgs/20200926210134.png)
174+
![](../imgs/20200926210134.png)
175175

176176
# B+树
177177

@@ -207,11 +207,11 @@ B树中一个节点的子节点数目的最大值,用m表示,假如最大值
207207

208208
B+树如下:
209209

210-
![](https://gitee.com/wardseptember/images/raw/master/imgs/20200926212656.png)
210+
![](../imgs/20200926212656.png)
211211

212-
![](https://gitee.com/wardseptember/images/raw/master/imgs/20200926212831.png)
212+
![](../imgs/20200926212831.png)
213213

214-
![](https://gitee.com/wardseptember/images/raw/master/imgs/20200926213019.png)
214+
![](../imgs/20200926213019.png)
215215

216216
# 参考链接
217217

docs/Java基础笔记.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ JRE 是 Java运行时环境。它是运行已编译 Java 程序所需的所有
1616

1717
简单地说,JRE就是运行Java字节码的虚拟机。但是,如果只有Java源码,要编译成Java字节码,就需要JDK,因为JDK除了包含JRE,还提供了编译器、调试器等开发工具。
1818

19-
![image-20200302140334046](https://gitee.com/wardseptember/images/raw/master/imgs/FkFHBGhlwkvD7j7wPFUnRCjrOHSX)
19+
![image-20200302140334046](../imgs/FkFHBGhlwkvD7j7wPFUnRCjrOHSX)
2020

2121
我们需要格外注意的是 .class->机器码 这一步。在这一步 JVM 类加载器首先加载字节码文件,然后通过解释器逐行解释执行,这种方式的执行速度会相对比较慢。而且,有些方法和代码块是经常需要被调用的(也就是所谓的热点代码),所以后面引进了 JIT 编译器,而JIT 属于运行时编译。当 JIT 编译器完成第一次编译后,其会将字节码对应的机器码保存下来,下次可以直接使用。而我们知道,机器码的运行效率肯定是高于 Java 解释器的。这也解释了我们为什么经常会说 Java 是编译与解释共存的语言。
2222

@@ -151,8 +151,6 @@ if (r < 0.00001) {
151151

152152
## 面向对象基础
153153

154-
155-
156154
### 可变参数
157155

158156
可变参数用`类型...`定义,可变参数相当于数组类型:
@@ -2300,7 +2298,7 @@ Java标准库自带的`java.util`包提供了集合类:`Collection`,它是
23002298
- `Set`:一种保证没有重复元素的集合,例如,所有无重复名称的`Student`的`Set`;
23012299
- `Map`:一种通过键值(key-value)查找的映射表集合,例如,根据`Student`的`name`查找对应`Student`的`Map`。
23022300

2303-
<div align="center"> <img src="https://gitee.com/wardseptember/images/raw/master/imgs/FgPceiQ8m6EUWxVQtN6Riy5-FSYo" width="600"/> </div><br>
2301+
<div align="center"> <img src="../imgs/FgPceiQ8m6EUWxVQtN6Riy5-FSYo" width="600"/> </div><br>
23042302

23052303
最后,Java访问集合总是通过统一的方式——迭代器(Iterator)来实现,它最明显的好处在于无需知道集合内部元素是按什么方式存储的。
23062304

docs/Mysql/mysql调优笔记.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## Mysql体系结构——概述
44

5-
![](https://gitee.com/wardseptember/images/raw/master/imgs/20200925110039.png)
5+
![](../../imgs/20200925110039.png)
66

77
MySQL 从概念上分为四层,这四层自顶向下分别是网络连接层,服务层(核心层),存储引擎层,系统文件层。我们自顶向下开始讲解。
88

@@ -196,11 +196,11 @@ syslog_tag = stock#mysqld_stock
196196

197197
那么,通过查询日志一般用来做什么呢?通用查询日志一般用来做审计用的,用于记录 MySQL 的所有操作,可以追踪用户的登录信息、操作信息等。比如公司有一个财务工资库,只有一个人有权限,这个时候就需要使用审计功能了。
198198

199-
![](https://gitee.com/wardseptember/images/raw/master/imgs/20200927194525.png)
199+
![](../../imgs/20200927194525.png)
200200

201201
开启通用查询日志后,MySQL 性能损耗太大,MySQL 官方企业版提供了 MySQL Enterprise Audit 插件,这个是需要收费的。Audit 插件是异步记录日志的,所以性能比较高,不会像通用查询日志这样性能损耗比较大。
202202

203-
![](https://gitee.com/wardseptember/images/raw/master/imgs/20200927194601.png)
203+
![](../../imgs/20200927194601.png)
204204

205205
MariaDB 官方提供了 Audit 插件,是免费的,可以兼容 MySQL。参考地址:
206206

@@ -236,11 +236,11 @@ show master logs;
236236

237237
MySQL 的配置文件 my.cnf 中有一个参数 datadir,配置了 MySQL 数据文件的存放位置,如下图所示。
238238

239-
![](https://gitee.com/wardseptember/images/raw/master/imgs/20200927194628.png)
239+
![](../../imgs/20200927194628.png)
240240

241241
比如我们要看 engine 数据库的文件内容,如下图所示。
242242

243-
![](https://gitee.com/wardseptember/images/raw/master/imgs/20200927194719.png)
243+
![](../../imgs/20200927194719.png)
244244

245245
ibdata1 文件是系统表空间(数据文件)undo 段,文件存放在 datadir 目录下。
246246

docs/Nginx学习笔记.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -522,9 +522,9 @@ systemctl start keepalived.service
522522

523523
# Nginx的原理解析
524524

525-
![](http://wardseptember.top/20200730215209.png)
525+
![](../imgs/20200730215209.png)
526526

527-
![](http://wardseptember.top/20200730215348.png)
527+
![](../imgs/20200730215348.png)
528528

529529
一个master和多个worker的好处:
530530

docs/Redis原理笔记.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ redis4.0相对与3.X版本其中一个比较大的变化是4.0添加了新的混
219219

220220
混合持久化同样也是通过bgrewriteaof完成的,不同的是当开启混合持久化时,fork出的子进程先将共享的内存副本全量的以RDB方式写入aof文件,然后在将重写缓冲区的增量命令以AOF方式写入到文件,写入完成后通知主进程更新统计信息,并将新的含有RDB格式和AOF格式的AOF文件替换旧的的AOF文件。简单的说:新的AOF文件前半段是RDB格式的全量数据后半段是AOF格式的增量数据,如下图:
221221

222-
<div align="center"> <img src="https://gitee.com/wardseptember/images/raw/master/imgs/20201030131617.png" width="600"/> </div><br>
222+
<div align="center"> <img src="../imgs/20201030131617.png" width="600"/> </div><br>
223223

224224
### 数据恢复
225225

docs/Socket.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -381,13 +381,13 @@ DatagramChannel: UDP
381381

382382
Bufer顾名思义,它是一个缓冲区,实际上是一个容器,一个连续数组。Channel提供从文件、网络读取数据的渠道,但是读写的数据都必须经过Buffer。
383383

384-
![](http://wardseptember.top/20200712142636.png)
384+
![](../imgs/20200712142636.png)
385385

386386
Buffer缓冲区本质上是一块可以写入数据,然后可以从中读取数据的内存。这块内存被包装成NIO Buffer对象,并提供了一组方法,用来方便的访问该模块内存。为了理解Buffer的工作原理,需要熟悉它的三个属性:capacity、position和limit。
387387

388388
position和limit的含义取决于Buffer处在读模式还是写模式。不管Buffer处在什么模式,capacity的含义总是一样的。见下图:
389389

390-
![](http://wardseptember.top/20200712142706.png)
390+
![](../imgs/20200712142706.png)
391391

392392
* capacity:作为一个内存块,Buffer有固定的大小值,也叫作“capacity”,只能往其中写入capacity个byte、long、char等类型。一旦Buffer满了,需要将其清空(通过读数据或者清楚数据)才能继续写数据。
393393

@@ -454,4 +454,3 @@ Selector与Channel是相互配合使用的,将Channel注册在Selector上之
454454
- [林亚希](https://www.jianshu.com/u/56856a29baac)
455455
- [CS-Notes](https://cyc2018.github.io/CS-Notes/#/notes/Socket)
456456

457-

docs/spring/Spring Cloud教程.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,19 @@
66

77
spring cloud是一系列服务的集合。
88

9-
![](https://gitee.com/wardseptember/images/raw/master/imgs/Flfun7Y203z43PkT4NLcp7DkLBOm)
9+
![](../../imgs/Flfun7Y203z43PkT4NLcp7DkLBOm)
1010

11-
![](https://gitee.com/wardseptember/images/raw/master/imgs/Fng5_6HiV4ECmNG-lNQgAfkgnJbI)
11+
![](../../imgs/Fng5_6HiV4ECmNG-lNQgAfkgnJbI)
1212

1313

1414

1515
## Spring boot和Cloud版本选择
1616

1717
因为教程原因,请选择以下版本,自己学完以后可以再升级。
1818

19-
![](https://gitee.com/wardseptember/images/raw/master/imgs/Foo8uNSJ3DdjSvtvK0vCpUszNl1Q)
19+
![](../../imgs/Foo8uNSJ3DdjSvtvK0vCpUszNl1Q)
2020

21-
![](https://gitee.com/wardseptember/images/raw/master/imgs/Fvb2CVnLQjB7H0k6ZJXreMPLadln)
21+
![](../../imgs/Fvb2CVnLQjB7H0k6ZJXreMPLadln)
2222

2323
Spring cloud官网教程
2424

@@ -36,14 +36,14 @@ Spring cloud官网教程
3636

3737
## 服务降级
3838

39-
![](https://gitee.com/wardseptember/images/raw/master/imgs/FrqaOjyW6bEaYePwdGJDot7J3pv1)
39+
![](../../imgs/FrqaOjyW6bEaYePwdGJDot7J3pv1)
4040

4141
## 服务熔断
4242

43-
![](https://gitee.com/wardseptember/images/raw/master/imgs/FilUMzjhnIHlhhF4tUwUTmGDmwPQ)
43+
![](../../imgs/FilUMzjhnIHlhhF4tUwUTmGDmwPQ)
4444

4545

4646

4747
## 服务限流
4848

49-
![](https://gitee.com/wardseptember/images/raw/master/imgs/FvgRcixwspGoJQSeY4UcpCw0hriX)
49+
![](../../imgs/FvgRcixwspGoJQSeY4UcpCw0hriX)

docs/spring/Spring Framework.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
<div align="center"> <img src="https://gitee.com/wardseptember/images/raw/master/imgs/20201230161420.png" width="400"/> </div><br>
1+
<div align="center"> <img src="../../imgs/20201230161420.png" width="400"/> </div><br>
22

docs/spring/Spring源码.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,7 @@ Bean生命周期主要为四个阶段
391391

392392
如果同时使用上面三种方法和实现BeanPostProcessor,他们的执行顺序如下图:
393393

394-
<div align="center"> <img src="https://gitee.com/wardseptember/images/raw/master/imgs/Xnip2021-01-22_18-34-41.jpg" width="600" height = "1500"/> </div><br>
394+
<div align="center"> <img src="../../imgs/Xnip2021-01-22_18-34-41.jpg" width="600" height = "1500"/> </div><br>
395395

396396
### Bean生命周期
397397

@@ -466,7 +466,7 @@ AOP(Aspect-Oriented Programming:面向切面编程)能够将那些与业务无
466466

467467
**Spring AOP就是基于动态代理的**,如果要代理的对象,实现了某个接口,那么Spring AOP会使用**JDK Proxy**,去创建代理对象,而对于没有实现接口的对象,就无法使用 JDK Proxy 去进行代理了,这时候Spring AOP会使用**Cglib** ,这时候Spring AOP会使用 **Cglib** 生成一个被代理对象的子类来作为代理,如下图所示:
468468

469-
![](https://gitee.com/wardseptember/images/raw/master/imgs/20201013201004.png)
469+
![](../../imgs/20201013201004.png)
470470

471471
当然你也可以使用 AspectJ ,Spring AOP 已经集成了AspectJ ,AspectJ 应该算的上是 Java 生态系统中最完整的 AOP 框架了。
472472

0 commit comments

Comments
 (0)