Skip to content

Commit 1067e9a

Browse files
authored
Merge branch 'Snailclimb:main' into main
2 parents 217ce16 + 20b64fc commit 1067e9a

File tree

16 files changed

+336
-31
lines changed

16 files changed

+336
-31
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,7 @@ JVM 这部分内容主要参考 [JVM 虚拟机规范-Java8 ](https://docs.oracle
294294

295295
**重要知识点详解**
296296

297+
- [IoC & AOP详解(快速搞懂)](./docs/system-design/framework/spring/ioc-and-aop.md)
297298
- [Spring 事务详解](./docs/system-design/framework/spring/spring-transaction.md)
298299
- [Spring 中的设计模式详解](./docs/system-design/framework/spring/spring-design-patterns-summary.md)
299300
- [SpringBoot 自动装配原理详解](./docs/system-design/framework/spring/spring-boot-auto-assembly-principles.md)

docs/.vuepress/sidebar/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,7 @@ export default sidebar({
401401
icon: "star",
402402
collapsible: true,
403403
children: [
404+
"ioc-and-aop",
404405
"spring-transaction",
405406
"spring-design-patterns-summary",
406407
"spring-boot-auto-assembly-principles",

docs/.vuepress/theme.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,14 @@ export default hopeTheme({
5151

5252
plugins: {
5353
blog: true,
54-
copyright: true,
54+
copyright: {
55+
author: "JavaGuide(javaguide.cn)",
56+
license: "MIT",
57+
triggerLength: 100,
58+
maxLength: 700,
59+
canonical: "https://javaguide.cn/",
60+
global:true
61+
},
5562
mdEnhance: {
5663
align: true,
5764
codetabs: true,

docs/cs-basics/data-structure/tree.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,8 +176,8 @@ public void postOrder(TreeNode root){
176176
if(root == null){
177177
return;
178178
}
179+
postOrder(root.left);
179180
postOrder(root.right);
180-
postOrder(root.left);
181181
system.out.println(root.data);
182182
}
183183
```

docs/cs-basics/network/other-network-questions.md

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,11 +196,17 @@ HTTP 状态码用于描述 HTTP 请求的结果,比如 2xx 就代表请求被
196196

197197
![HTTP/1.0 和 HTTP/1.1 对比](https://oss.javaguide.cn/github/javaguide/cs-basics/network/http1.1-vs-http2.0.png)
198198

199-
- **IO 多路复用(Multiplexing)**:HTTP/2.0 在同一连接上可以同时传输多个请求和响应(可以看作是 HTTP/1.1 中长链接的升级版本)。HTTP/1.1 则使用串行方式,每个请求和响应都需要独立的连接。这使得 HTTP/2.0 在处理多个请求时更加高效,减少了网络延迟和提高了性能。
199+
- **多路复用(Multiplexing)**:HTTP/2.0 在同一连接上可以同时传输多个请求和响应(可以看作是 HTTP/1.1 中长链接的升级版本),互不干扰。HTTP/1.1 则使用串行方式,每个请求和响应都需要独立的连接,而浏览器为了控制资源会有 6-8 个 TCP 连接都限制。。这使得 HTTP/2.0 在处理多个请求时更加高效,减少了网络延迟和提高了性能。
200200
- **二进制帧(Binary Frames)**:HTTP/2.0 使用二进制帧进行数据传输,而 HTTP/1.1 则使用文本格式的报文。二进制帧更加紧凑和高效,减少了传输的数据量和带宽消耗。
201-
- **头部压缩(Header Compression)**:HTTP/1.1 支持`Body`压缩,`Header`不支持压缩。HTTP/2.0 支持对`Header`压缩,减少了网络开销。
201+
- **头部压缩(Header Compression)**:HTTP/1.1 支持`Body`压缩,`Header`不支持压缩。HTTP/2.0 支持对`Header`压缩,使用了专门为`Header`压缩而设计的 HPACK 算法,减少了网络开销。
202202
- **服务器推送(Server Push)**:HTTP/2.0 支持服务器推送,可以在客户端请求一个资源时,将其他相关资源一并推送给客户端,从而减少了客户端的请求次数和延迟。而 HTTP/1.1 需要客户端自己发送请求来获取相关资源。
203203

204+
HTTP/2.0 多路复用效果图(图源: [HTTP/2 For Web Developers](https://blog.cloudflare.com/http-2-for-web-developers/)):
205+
206+
![HTTP/2 Multiplexing](https://oss.javaguide.cn/github/javaguide/cs-basics/network/http2.0-multiplexing.png)
207+
208+
可以看到,HTTP/2.0 的多路复用使得不同的请求可以共用一个 TCP 连接,避免建立多个连接带来不必要的额外开销,而 HTTP/1.1 中的每个请求都会建立一个单独的连接
209+
204210
### HTTP/2.0 和 HTTP/3.0 有什么区别?
205211

206212
![HTTP/2.0 和 HTTP/3.0 对比](https://oss.javaguide.cn/github/javaguide/cs-basics/network/http2.0-vs-http3.0.png)
@@ -211,6 +217,12 @@ HTTP 状态码用于描述 HTTP 请求的结果,比如 2xx 就代表请求被
211217
- **错误恢复**:HTTP/3.0 具有更好的错误恢复机制,当出现丢包、延迟等网络问题时,可以更快地进行恢复和重传。而 HTTP/2.0 则需要依赖于 TCP 的错误恢复机制。
212218
- **安全性**:HTTP/2.0 和 HTTP/3.0 在安全性上都有较高的要求,支持加密通信,但在实现上有所不同。HTTP/2.0 使用 TLS 协议进行加密,而 HTTP/3.0 基于 QUIC 协议,包含了内置的加密和身份验证机制,可以提供更强的安全性。
213219

220+
HTTP/1.0、HTTP/2.0 和 HTTP/3.0 的协议栈比较:
221+
222+
![http-3-implementation](https://oss.javaguide.cn/github/javaguide/cs-basics/network/http-3-implementation.png)
223+
224+
关于 HTTP/1.0 -> HTTP/3.0 更详细的演进介绍,推荐阅读[HTTP1 到 HTTP3 的工程优化](https://dbwu.tech/posts/http_evolution/)
225+
214226
### HTTP 是不保存状态的协议, 如何保存用户状态?
215227

216228
HTTP 是一种不保存状态,即无状态(stateless)协议。也就是说 HTTP 协议自身不对请求和响应之间的通信状态进行保存。那么我们如何保存用户状态呢?Session 机制的存在就是为了解决这个问题,Session 的主要作用就是通过服务端记录用户的状态。典型的场景是购物车,当你要添加商品到购物车的时候,系统不知道是哪个用户操作的,因为 HTTP 协议是无状态的。服务端给特定的用户创建特定的 Session 之后就可以标识这个用户并且跟踪这个用户了(一般情况下,服务器会在一定时间内保存这个 Session,过了时间限制,就会销毁这个 Session)。

docs/database/mysql/mysql-high-performance-optimization-specification-recommendations.md

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ tag:
77

88
> 作者: 听风 原文地址: <https://www.cnblogs.com/huchong/p/10219318.html>
99
>
10-
> JavaGuide 已获得作者授权,并对原文内容进行了完善
10+
> JavaGuide 已获得作者授权,并对原文内容进行了完善补充
1111
1212
## 数据库命名规范
1313

@@ -29,10 +29,7 @@ InnoDB 支持事务,支持行级锁,更好的恢复性,高并发下性能
2929

3030
兼容性更好,统一字符集可以避免由于字符集转换产生的乱码,不同的字符集进行比较前需要进行转换会造成索引失效,如果数据库中有存储 emoji 表情的需要,字符集需要采用 utf8mb4 字符集。
3131

32-
参考文章:
33-
34-
- [MySQL 字符集不一致导致索引失效的一个真实案例](https://blog.csdn.net/horses/article/details/107243447)
35-
- [MySQL 字符集详解](../character-set.md)
32+
推荐阅读一下我写的这篇文章:[MySQL 字符集详解](../character-set.md)
3633

3734
### 所有表和字段都需要添加注释
3835

@@ -135,18 +132,19 @@ MySQL 内存临时表不支持 TEXT、BLOB 这样的大数据类型,如果查
135132

136133
相关阅读:[技术分享 | MySQL 默认值选型(是空,还是 NULL)](https://opensource.actionsky.com/20190710-mysql/)
137134

138-
### 使用 TIMESTAMP(4 个字节) 或 DATETIME 类型 (8 个字节) 存储时间
139-
140-
TIMESTAMP 存储的时间范围 1970-01-01 00:00:01 ~ 2038-01-19-03:14:07
135+
### 一定不要用字符串存储日期
141136

142-
TIMESTAMP 占用 4 字节和 INT 相同,但比 INT 可读性高
137+
对于日期类型来说, 一定不要用字符串存储日期。可以考虑 DATETIME、TIMESTAMP 和 数值型时间戳。
143138

144-
超出 TIMESTAMP 取值范围的使用 DATETIME 类型存储
139+
这三种种方式都有各自的优势,根据实际场景选择最合适的才是王道。下面再对这三种方式做一个简单的对比,以供大家实际开发中选择正确的存放时间的数据类型:
145140

146-
**经常会有人用字符串存储日期型的数据(不正确的做法)**
141+
| 类型 | 存储空间 | 日期格式 | 日期范围 | 是否带时区信息 |
142+
| ------------ | -------- | ------------------------------ | ------------------------------------------------------------ | -------------- |
143+
| DATETIME | 5~8字节 | YYYY-MM-DD hh:mm:ss[.fraction] | 1000-01-01 00:00:00[.000000] ~ 9999-12-31 23:59:59[.999999] ||
144+
| TIMESTAMP | 4~7字节 | YYYY-MM-DD hh:mm:ss[.fraction] | 1970-01-01 00:00:01[.000000] ~ 2038-01-19 03:14:07[.999999] ||
145+
| 数值型时间戳 | 4字节 | 全数字如1578707612 | 1970-01-01 00:00:01之后的时间 ||
147146

148-
- 缺点 1:无法用日期函数进行计算和比较
149-
- 缺点 2:用字符串存储日期要占用更多的空间
147+
MySQL 时间类型选择的详细介绍请看这篇:[MySQL时间类型数据存储建议](https://javaguide.cn/database/mysql/some-thoughts-on-database-storage-time.html)
150148

151149
### 同财务相关的金额类数据必须使用 decimal 类型
152150

@@ -230,9 +228,13 @@ InnoDB 是按照主键索引的顺序来组织表的
230228

231229
## 数据库 SQL 开发规范
232230

231+
### 尽量不在数据库做运算,复杂运算需移到业务应用里完成
232+
233+
尽量不在数据库做运算,复杂运算需移到业务应用里完成。这样可以避免数据库的负担过重,影响数据库的性能和稳定性。数据库的主要作用是存储和管理数据,而不是处理数据。
234+
233235
### 优化对性能影响较大的 SQL 语句
234236

235-
要找到最需要优化的 SQL 语句。要么是使用最频繁的语句,要么是优化后提高最明显的语句,可以通过查询 MySQL 的慢查询日志来发现需要进行优化的 SQL 语句
237+
要找到最需要优化的 SQL 语句。要么是使用最频繁的语句,要么是优化后提高最明显的语句,可以通过查询 MySQL 的慢查询日志来发现需要进行优化的 SQL 语句
236238

237239
### 充分利用表上已经存在的索引
238240

@@ -244,9 +246,10 @@ InnoDB 是按照主键索引的顺序来组织表的
244246

245247
### 禁止使用 SELECT \* 必须使用 SELECT <字段列表> 查询
246248

247-
- `SELECT *` 消耗更多的 CPU 和 IO 以网络带宽资源
248-
- `SELECT *` 无法使用覆盖索引
249-
- `SELECT <字段列表>` 可减少表结构变更带来的影响
249+
- `SELECT *` 会消耗更多的 CPU。
250+
- `SELECT *` 无用字段增加网络带宽资源消耗,增加数据传输时间,尤其是大字段(如 varchar、blob、text)。
251+
- `SELECT *` 无法使用 MySQL 优化器覆盖索引的优化(基于 MySQL 优化器的“覆盖索引”策略又是速度极快,效率极高,业界极为推荐的查询优化方式)
252+
- `SELECT <字段列表>` 可减少表结构变更带来的影响、
250253

251254
### 禁止使用不含字段列表的 INSERT 语句
252255

@@ -378,4 +381,9 @@ pt-online-schema-change 它会首先建立一个与原表结构相同的新表
378381
- 程序使用数据库账号只能在一个 DB 下使用,不准跨库
379382
- 程序使用的账号原则上不准有 drop 权限
380383

384+
## 推荐阅读
385+
386+
- [技术同学必会的MySQL设计规约,都是惨痛的教训 - 阿里开发者](https://mp.weixin.qq.com/s/XC8e5iuQtfsrEOERffEZ-Q)
387+
- [聊聊数据库建表的15个小技巧](https://mp.weixin.qq.com/s/NM-aHaW6TXrnO6la6Jfl5A)
388+
381389
<!-- @include: @article-footer.snippet.md -->

docs/distributed-system/api-gateway.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ category: 分布式
2121

2222
## 网关能提供哪些功能?
2323

24-
绝大部分网关可以提供下面这些功能:
24+
绝大部分网关可以提供下面这些功能(有一些功能需要借助其他框架或者中间件)
2525

2626
- **请求转发**:将请求转发到目标微服务。
2727
- **负载均衡**:根据各个微服务实例的负载情况或者具体的负载均衡策略配置对请求实现动态的负载均衡。
@@ -37,6 +37,7 @@ category: 分布式
3737
- **异常处理**:对于业务服务返回的异常响应,可以在网关层在返回给用户之前做转换处理。这样可以把一些业务侧返回的异常细节隐藏,转换成用户友好的错误提示返回。
3838
- **API 文档:** 如果计划将 API 暴露给组织以外的开发人员,那么必须考虑使用 API 文档,例如 Swagger 或 OpenAPI。
3939
- **协议转换**:通过协议转换整合后台基于 REST、AMQP、Dubbo 等不同风格和实现技术的微服务,面向 Web Mobile、开放平台等特定客户端提供统一服务。
40+
- **证书管理**:将 SSL 证书部署到 API 网关,由一个统一的入口管理接口,降低了证书更换时的复杂度。
4041

4142
下图来源于[百亿规模 API 网关服务 Shepherd 的设计与实现 - 美团技术团队 - 2021](https://mp.weixin.qq.com/s/iITqdIiHi3XGKq6u6FRVdg)这篇文章。
4243

docs/high-availability/timeout-and-retry.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,20 @@ category: 高可用
5050

5151
重试的核心思想是通过消耗服务器的资源来尽可能获得请求更大概率被成功处理。由于瞬态故障和偶然性故障是很少发生的,因此,重试对于服务器的资源消耗几乎是可以被忽略的。
5252

53+
### 常见的重试策略有哪些?
54+
55+
常见的重试策略有两种:
56+
57+
1. **固定间隔时间重试**:每次重试之间都使用相同的时间间隔,比如每隔1.5秒进行一次重试。这种重试策略的优点是实现起来比较简单,不需要考虑重试次数和时间的关系,也不需要维护额外的状态信息。但是这种重试策略的缺点是可能会导致重试过于频繁或过于稀疏,从而影响系统的性能和效率。如果重试间隔太短,可能会对目标系统造成过大的压力,导致雪崩效应;如果重试间隔太长,可能会导致用户等待时间过长,影响用户体验。
58+
2. **梯度间隔重试**:根据重试次数的增加去延长下次重试时间,比如第一次重试间隔为1秒,第二次为2秒,第三次为4秒,以此类推。这种重试策略的优点是能够有效提高重试成功的几率(随着重试次数增加,但是重试依然不成功,说明目标系统恢复时间比较长,因此可以根据重试次数延长下次重试时间),也能通过柔性化的重试避免对下游系统造成更大压力。但是这种重试策略的缺点是实现起来比较复杂,需要考虑重试次数和时间的关系,以及设置合理的上限和下限值。另外,这种重试策略也可能会导致用户等待时间过长,影响用户体验。
59+
60+
这两种适合的场景各不相同。固定间隔时间重试适用于目标系统恢复时间比较稳定和可预测的场景,比如网络波动或服务重启。梯度间隔重试适用于目标系统恢复时间比较长或不可预测的场景,比如网络故障和服务故障。
61+
5362
### 重试的次数如何设置?
5463

5564
重试的次数不宜过多,否则依然会对系统负载造成比较大的压力。
5665

57-
重试的次数通常建议设为 3 次。并且,我们通常还会设置重试的间隔,比如说我们要重试 3 次的话,第 1 次请求失败后,等待 1 秒再进行重试,第 2 次请求失败后,等待 2 秒再进行重试,第 3 次请求失败后,等待 3 秒再进行重试。
66+
重试的次数通常建议设为 3 次。大部分情况下,我们还是更建议使用梯度间隔重试策略,比如说我们要重试 3 次的话,第 1 次请求失败后,等待 1 秒再进行重试,第 2 次请求失败后,等待 2 秒再进行重试,第 3 次请求失败后,等待 3 秒再进行重试。
5867

5968
### 重试幂等
6069

docs/high-performance/load-balancing.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,12 @@ Java 领域主流的微服务框架 Dubbo、Spring Cloud 等都内置了开箱
123123

124124
最小连接法可以尽可能最大地使请求分配更加合理化,提高服务器的利用率。不过,这种方法实现起来也最复杂,需要监控每一台服务器处理的请求连接数。
125125

126+
### 两次随机法
127+
128+
两次随机法在随机法的基础上多增加了一次随机,多选出一个服务器。随后再根据两台服务器的负载等情况,从其中选择出一个最合适的服务器。
129+
130+
两次随机法的好处是可以动态地调节后端节点的负载,使其更加均衡。如果只使用一次随机法,可能会导致某些服务器过载,而某些服务器空闲。
131+
126132
## 七层负载均衡可以怎么做?
127133

128134
简单介绍两种项目中常用的七层负载均衡解决方案:DNS 解析和反向代理。

docs/home.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,7 @@ JVM 这部分内容主要参考 [JVM 虚拟机规范-Java8](https://docs.oracle.
290290

291291
**重要知识点详解**
292292

293+
- [IoC & AOP详解(快速搞懂)](./system-design/framework/spring/ioc-and-aop.md)
293294
- [Spring 事务详解](./system-design/framework/spring/spring-transaction.md)
294295
- [Spring 中的设计模式详解](./system-design/framework/spring/spring-design-patterns-summary.md)
295296
- [SpringBoot 自动装配原理详解](./system-design/framework/spring/spring-boot-auto-assembly-principles.md)

0 commit comments

Comments
 (0)