From c0535df01c9d6006227e11e483d7d822a2c515d8 Mon Sep 17 00:00:00 2001 From: Guide Date: Tue, 13 Aug 2024 16:01:02 +0800 Subject: [PATCH] =?UTF-8?q?[docs=20update]=E5=AE=8C=E5=96=84HTTP/2.0=20?= =?UTF-8?q?=E5=92=8C=20HTTP/3.0=20=E7=9A=84=E5=AF=B9=E6=AF=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../network/other-network-questions.md | 13 +++++++++- .../java-collection-questions-02.md | 26 +++++++++---------- .../framework/spring/ioc-and-aop.md | 2 +- 3 files changed, 26 insertions(+), 15 deletions(-) diff --git a/docs/cs-basics/network/other-network-questions.md b/docs/cs-basics/network/other-network-questions.md index 8650ad5c..74830a47 100644 --- a/docs/cs-basics/network/other-network-questions.md +++ b/docs/cs-basics/network/other-network-questions.md @@ -211,14 +211,25 @@ HTTP/2.0 多路复用效果图(图源: [HTTP/2 For Web Developers](https://b - **传输协议**:HTTP/2.0 是基于 TCP 协议实现的,HTTP/3.0 新增了 QUIC(Quick UDP Internet Connections) 协议来实现可靠的传输,提供与 TLS/SSL 相当的安全性,具有较低的连接和传输延迟。你可以将 QUIC 看作是 UDP 的升级版本,在其基础上新增了很多功能比如加密、重传等等。HTTP/3.0 之前名为 HTTP-over-QUIC,从这个名字中我们也可以发现,HTTP/3 最大的改造就是使用了 QUIC。 - **连接建立**:HTTP/2.0 需要经过经典的 TCP 三次握手过程(由于安全的 HTTPS 连接建立还需要 TLS 握手,共需要大约 3 个 RTT)。由于 QUIC 协议的特性(TLS 1.3,TLS 1.3 除了支持 1 个 RTT 的握手,还支持 0 个 RTT 的握手)连接建立仅需 0-RTT 或者 1-RTT。这意味着 QUIC 在最佳情况下不需要任何的额外往返时间就可以建立新连接。 +- **头部压缩**:HTTP/2.0 使用 HPACK 算法进行头部压缩,而 HTTP/3.0 使用更高效的 QPACK 头压缩算法。 - **队头阻塞**:HTTP/2.0 多请求复用一个 TCP 连接,一旦发生丢包,就会阻塞住所有的 HTTP 请求。由于 QUIC 协议的特性,HTTP/3.0 在一定程度上解决了队头阻塞(Head-of-Line blocking, 简写:HOL blocking)问题,一个连接建立多个不同的数据流,这些数据流之间独立互不影响,某个数据流发生丢包了,其数据流不受影响(本质上是多路复用+轮询)。 +- **连接迁移**:HTTP/3.0 支持连接迁移,因为 QUIC 使用 64 位 ID 标识连接,只要 ID 不变就不会中断,网络环境改变时(如从 Wi-Fi 切换到移动数据)也能保持连接。而 TCP 连接是由(源 IP,源端口,目的 IP,目的端口)组成,这个四元组中一旦有一项值发生改变,这个连接也就不能用了。 - **错误恢复**:HTTP/3.0 具有更好的错误恢复机制,当出现丢包、延迟等网络问题时,可以更快地进行恢复和重传。而 HTTP/2.0 则需要依赖于 TCP 的错误恢复机制。 -- **安全性**:HTTP/2.0 和 HTTP/3.0 在安全性上都有较高的要求,支持加密通信,但在实现上有所不同。HTTP/2.0 使用 TLS 协议进行加密,而 HTTP/3.0 基于 QUIC 协议,包含了内置的加密和身份验证机制,可以提供更强的安全性。 +- **安全性**:HTTP/2.0 和 HTTP/3.0 都支持加密通信,但实现方式不同。HTTP/2.0 依赖 TLS 协议加密,而 HTTP/3.0 基于 QUIC 协议,QUIC 内置了 TLS 1.3,能更快建立连接,并减少网络报头信息暴露,提升了安全性和隐私性。 HTTP/1.0、HTTP/2.0 和 HTTP/3.0 的协议栈比较: ![http-3-implementation](https://oss.javaguide.cn/github/javaguide/cs-basics/network/http-3-implementation.png) +下图是一个更详细的 HTTP/2.0 和 HTTP/3.0 对比图: + +![HTTP/2.0 和 HTTP/3.0 详细对比图](https://oss.javaguide.cn/github/javaguide/cs-basics/network/http2-and-http3-stacks-comparison.png) + +从上图可以看出: + +- **HTTP/2.0**:使用 TCP 作为传输协议、使用 HPACK 进行头部压缩、依赖 TLS 进行加密。 +- **HTTP/3.0**:使用基于 UDP 的 QUIC 协议、使用更高效的 QPACK 进行头部压缩、在 QUIC 中直接集成了 TLS。QUIC 协议具备连接迁移、拥塞控制与避免、流量控制等特性。 + 关于 HTTP/1.0 -> HTTP/3.0 更详细的演进介绍,推荐阅读[HTTP1 到 HTTP3 的工程优化](https://dbwu.tech/posts/http_evolution/)。 ### HTTP 是不保存状态的协议, 如何保存用户状态? diff --git a/docs/java/collection/java-collection-questions-02.md b/docs/java/collection/java-collection-questions-02.md index 1fae392f..931161bf 100644 --- a/docs/java/collection/java-collection-questions-02.md +++ b/docs/java/collection/java-collection-questions-02.md @@ -48,18 +48,18 @@ head: 下面这个方法保证了 `HashMap` 总是使用 2 的幂作为哈希表的大小。 ```java - /** - * Returns a power of two size for the given target capacity. - */ - static final int tableSizeFor(int cap) { - int n = cap - 1; - n |= n >>> 1; - n |= n >>> 2; - n |= n >>> 4; - n |= n >>> 8; - n |= n >>> 16; - return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1; - } +/** + * Returns a power of two size for the given target capacity. + */ +static final int tableSizeFor(int cap) { + int n = cap - 1; + n |= n >>> 1; + n |= n >>> 2; + n |= n >>> 4; + n |= n >>> 8; + n |= n >>> 16; + return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1; +} ``` ### HashMap 和 HashSet 区别 @@ -304,7 +304,7 @@ final void treeifyBin(Node[] tab, int hash) { 这里列举一个例子: -``` +```plain 假设有一个元素的哈希值为 10101100 旧数组元素位置计算: diff --git a/docs/system-design/framework/spring/ioc-and-aop.md b/docs/system-design/framework/spring/ioc-and-aop.md index 2e99a150..a53e08bf 100644 --- a/docs/system-design/framework/spring/ioc-and-aop.md +++ b/docs/system-design/framework/spring/ioc-and-aop.md @@ -94,7 +94,7 @@ AOP 之所以叫面向切面编程,是因为它的核心思想就是将横切 - **连接点(JoinPoint)**:连接点是方法调用或者方法执行时的某个特定时刻(如方法调用、异常抛出等)。 - **通知(Advice)**:通知就是切面在某个连接点要执行的操作。通知有五种类型,分别是前置通知(Before)、后置通知(After)、返回通知(AfterReturning)、异常通知(AfterThrowing)和环绕通知(Around)。前四种通知都是在目标方法的前后执行,而环绕通知可以控制目标方法的执行过程。 - **切点(Pointcut)**:一个切点是一个表达式,它用来匹配哪些连接点需要被切面所增强。切点可以通过注解、正则表达式、逻辑运算等方式来定义。比如 `execution(* com.xyz.service..*(..))`匹配 `com.xyz.service` 包及其子包下的类或接口。 -- **织入(Weaving)**:织入是将切面和目标对象连接起来的过程,也就是将通知应用到切点匹配的连接点上。常见的织入时机有两种,分别是编译期织入(AspectJ)和运行期织入(AspectJ)。 +- **织入(Weaving)**:织入是将切面和目标对象连接起来的过程,也就是将通知应用到切点匹配的连接点上。常见的织入时机有两种,分别是编译期织入(Compile-Time Weaving 如:AspectJ)和运行期织入(Runtime Weaving 如:AspectJ、Spring AOP)。 ### AOP 解决了什么问题?