Skip to content

Commit e8c68e9

Browse files
committed
update: tcp和udp面试题润色优化
1 parent 8f3b0c8 commit e8c68e9

File tree

6 files changed

+53
-24
lines changed

6 files changed

+53
-24
lines changed
Binary file not shown.

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ NAT 不光可以缓解 IPv4 地址资源短缺的问题,还可以隐藏内部
232232

233233
MAC 地址的全称是 **媒体访问控制地址(Media Access Control Address)**。如果说,互联网中每一个资源都由 IP 地址唯一标识(IP 协议内容),那么一切网络设备都由 MAC 地址唯一标识。
234234

235-
![路由器的背面就会注明 MAC 位址](./images/arp/2008410143049281.png)
235+
![路由器的背面就会注明 MAC 位址](https://oss.javaguide.cn/github/javaguide/cs-basics/network/router-back-will-indicate-mac-address.png)
236236

237237
可以理解为,MAC 地址是一个网络设备真正的身份证号,IP 地址只是一种不重复的定位方式(比如说住在某省某市某街道的张三,这种逻辑定位是 IP 地址,他的身份证号才是他的 MAC 地址),也可以理解为 MAC 地址是身份证号,IP 地址是邮政地址。MAC 地址也有一些别称,如 LAN 地址、物理地址、以太网地址等。
238238

docs/cs-basics/network/tcp-connection-and-disconnection.md

Lines changed: 43 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,40 +5,64 @@ tag:
55
- 计算机网络
66
---
77

8-
为了准确无误地把数据送达目标处,TCP 协议采用了三次握手策略
8+
TCP 是一种面向连接的、可靠的传输层协议。为了在两个不可靠的端点之间建立一个可靠的连接,TCP 采用了三次握手(Three-way Handshake)的策略
99

1010
## 建立连接-TCP 三次握手
1111

1212
![TCP 三次握手图解](https://oss.javaguide.cn/github/javaguide/cs-basics/network/tcp-shakes-hands-three-times.png)
1313

1414
建立一个 TCP 连接需要“三次握手”,缺一不可:
1515

16-
- **一次握手**:客户端发送带有 SYN(SEQ=x) 标志的数据包 -> 服务端,然后客户端进入 **SYN_SEND** 状态,等待服务端的确认;
17-
- **二次握手**:服务端发送带有 SYN+ACK(SEQ=y,ACK=x+1) 标志的数据包 –> 客户端,然后服务端进入 **SYN_RECV** 状态;
18-
- **三次握手**:客户端发送带有 ACK(ACK=y+1) 标志的数据包 –> 服务端,然后客户端和服务端都进入**ESTABLISHED** 状态,完成 TCP 三次握手。
16+
1. **第一次握手 (SYN)**: 客户端向服务端发送一个 SYN(Synchronize Sequence Numbers)报文段,其中包含一个由客户端随机生成的初始序列号(Initial Sequence Number, ISN),例如 seq=x。发送后,客户端进入 **SYN_SEND** 状态,等待服务端的确认。
17+
2. **第二次握手 (SYN+ACK)**: 服务端收到 SYN 报文段后,如果同意建立连接,会向客户端回复一个确认报文段。该报文段包含两个关键信息:
18+
- **SYN**:服务端也需要同步自己的初始序列号,因此报文段中也包含一个由服务端随机生成的初始序列号,例如 seq=y。
19+
- **ACK** (Acknowledgement):用于确认收到了客户端的请求。其确认号被设置为客户端初始序列号加一,即 ack=x+1。
20+
- 发送该报文段后,服务端进入 **SYN_RECV** 状态。
21+
3. **第三次握手 (ACK)**: 客户端收到服务端的 SYN+ACK 报文段后,会向服务端发送一个最终的确认报文段。该报文段包含确认号 ack=y+1。发送后,客户端进入 **ESTABLISHED** 状态。服务端收到这个 ACK 报文段后,也进入 **ESTABLISHED** 状态。
1922

20-
当建立了 3 次握手之后,客户端和服务端就可以传输数据啦!
23+
至此,双方都确认了连接的建立,TCP 连接成功创建,可以开始进行双向数据传输。
2124

2225
### 什么是半连接队列和全连接队列?
2326

24-
在 TCP 三次握手过程中,Linux 内核会维护两个队列来管理连接请求
27+
在 TCP 三次握手过程中,服务端内核会使用两个队列来管理连接请求
2528

26-
1. **半连接队列**(也称 SYN Queue):当服务端收到客户端的 SYN 请求时,此时双方还没有完全建立连接,它会把半连接状态的连接放在半连接队列
29+
1. **半连接队列**(也称 SYN Queue):当服务端收到客户端的 SYN 请求并回复 SYN+ACK 后,连接会处于 SYN_RECV 状态。此时,这个连接信息会被放入半连接队列。这个队列存储的是尚未完成三次握手的连接
2730
2. **全连接队列**(也称 Accept Queue):当服务端收到客户端对 ACK 响应时,意味着三次握手成功完成,服务端会将该连接从半连接队列移动到全连接队列。如果未收到客户端的 ACK 响应,会进行重传,重传的等待时间通常是指数增长的。如果重传次数超过系统规定的最大重传次数,系统将从半连接队列中删除该连接信息。
2831

29-
这两个队列的存在是为了处理并发连接请求,确保服务端能够有效地管理新的连接请求。另外,新的连接请求被拒绝或忽略除了和每个队列的大小限制有关系之外,还和很多其他因素有关系,这里就不详细介绍了,整体逻辑比较复杂。
32+
这两个队列的存在是为了处理并发连接请求,确保服务端能够有效地管理新的连接请求。
33+
34+
如果全连接队列满了,新的已完成握手的连接可能会被丢弃,或者触发其他策略。这两个队列的大小都受系统参数控制,它们的容量限制是影响服务器处理高并发连接能力的重要因素,也是 SYN 泛洪攻击(SYN Flood)所针对的目标。
3035

3136
### 为什么要三次握手?
3237

33-
三次握手的目的是建立可靠的通信信道,说到通讯,简单来说就是数据的发送与接收,而三次握手最主要的目的就是双方确认自己与对方的发送与接收是正常的。
38+
TCP 三次握手的核心目的是为了在客户端和服务器之间建立一个**可靠的****全双工的**通信信道。这需要实现两个主要目标:
39+
40+
**1. 确认双方的收发能力,并同步初始序列号 (ISN)**
41+
42+
TCP 通信依赖序列号来保证数据的有序和可靠。三次握手是双方交换和确认彼此初始序列号(ISN)的过程,通过这个过程,双方也间接验证了各自的收发能力。
43+
44+
- **第一次握手 (客户端 → 服务器)** :客户端发送 SYN 包。
45+
- 服务器:能确认客户端的发送能力正常,自己的接收能力正常。
46+
- 客户端:无法确认任何事。
47+
- **第二次握手 (服务器 → 客户端)** :服务器回复 SYN+ACK 包。
48+
- 客户端:能确认自己的发送和接收能力正常,服务器的接收和发送能力正常。
49+
- 服务端:能确认对方发送能力正常,自己接收能力正常
50+
- **第三次握手 (客户端 → 服务器)** :客户端发送 ACK 包。
51+
- 客户端:能确认双方发送和接收能力正常。
52+
- 服务端:能确认双方发送和接收能力正常。
53+
54+
经过这三次交互,双方都确认了彼此的收发功能完好,并完成了初始序列号的同步,为后续可靠的数据传输奠定了基础。
55+
56+
**2. 防止已失效的连接请求被错误地建立**
57+
58+
这是“为什么不能是两次握手”的关键原因。
3459

35-
1. **第一次握手**:Client 什么都不能确认;Server 确认了对方发送正常,自己接收正常
36-
2. **第二次握手**:Client 确认了:自己发送、接收正常,对方发送、接收正常;Server 确认了:对方发送正常,自己接收正常
37-
3. **第三次握手**:Client 确认了:自己发送、接收正常,对方发送、接收正常;Server 确认了:自己发送、接收正常,对方发送、接收正常
60+
设想一个场景:客户端发送的第一个连接请求(SYN1)因网络延迟而滞留,于是客户端重发了第二个请求(SYN2)并成功建立了连接,数据传输完毕后连接被释放。此时,延迟的 SYN1 才到达服务端。
3861

39-
三次握手就能确认双方收发功能都正常,缺一不可。
62+
- **如果是两次握手**:服务端收到这个失效的 SYN1 后,会误认为是一个新的连接请求,并立即分配资源、建立连接。但这将导致服务端单方面维持一个无效连接,白白浪费系统资源,因为客户端并不会有任何响应。
63+
- **有了第三次握手**:服务端收到失效的 SYN1 并回复 SYN+ACK 后,会等待客户端的最终确认(ACK)。由于客户端当前并没有发起连接的意图,它会忽略这个 SYN+ACK 或者发送一个 RST (Reset) 报文。这样,服务端就无法收到第三次握手的 ACK,最终会超时关闭这个错误的连接,从而避免了资源浪费。
4064

41-
更详细的解答可以看这个:[TCP 为什么是三次握手,而不是两次或四次? - 车小胖的回答 - 知乎](https://www.zhihu.com/question/24853633/answer/115173386)
65+
因此,三次握手是确保 TCP 连接可靠性的**最小且必需**的步骤。它不仅确认了双方的通信能力,更重要的是增加了一个最终确认环节,以防止网络中延迟、重复的历史请求对连接建立造成干扰
4266

4367
### 第 2 次握手传回了 ACK,为什么还要传回 SYN?
4468

@@ -58,10 +82,10 @@ tag:
5882

5983
断开一个 TCP 连接则需要“四次挥手”,缺一不可:
6084

61-
1. **第一次挥手**:客户端发送一个 FIN(SEQ=x) 标志的数据包->服务端,用来关闭客户端到服务端的数据传送。然后客户端进入 **FIN-WAIT-1** 状态。
62-
2. **第二次挥手**:服务端收到这个 FIN(SEQ=X) 标志的数据包,它发送一个 ACK (ACK=x+1)标志的数据包->客户端 。然后服务端进入 **CLOSE-WAIT** 状态,客户端进入 **FIN-WAIT-2** 状态。
63-
3. **第三次挥手**:服务端发送一个 FIN (SEQ=y)标志的数据包->客户端,请求关闭连接,然后服务端进入 **LAST-ACK** 状态。
64-
4. **第四次挥手**:客户端发送 ACK (ACK=y+1)标志的数据包->服务端,然后客户端进入**TIME-WAIT**状态,服务端在收到 ACK (ACK=y+1)标志的数据包后进入 CLOSE 状态。此时如果客户端等待 **2MSL** 后依然没有收到回复,就证明服务端已正常关闭,随后客户端也可以关闭连接了
85+
1. **第一次挥手 (FIN)**:当客户端(或任何一方)决定关闭连接时,它会向服务端发送一个 **FIN**(Finish)标志的报文段,表示自己已经没有数据要发送了。该报文段包含一个序列号 seq=u。发送后,客户端进入 **FIN-WAIT-1** 状态。
86+
2. **第二次挥手 (ACK)**:服务端收到 FIN 报文段后,会立即回复一个 **ACK** 确认报文段。其确认号为 ack=u+1。发送后,服务端进入 **CLOSE-WAIT** 状态。客户端收到这个 ACK 后,进入 **FIN-WAIT-2** 状态。此时,TCP 连接处于**半关闭(Half-Close)**状态:客户端到服务端的发送通道已关闭,但服务端到客户端的发送通道仍然可以传输数据
87+
3. **第三次挥手 (FIN)**:当服务端确认所有待发送的数据都已发送完毕后,它也会向客户端发送一个 **FIN** 报文段,表示自己也准备关闭连接。该报文段同样包含一个序列号 seq=y。发送后,服务端进入 **LAST-ACK** 状态,等待客户端的最终确认
88+
4. **第四次挥手**:客户端收到服务端的 FIN 报文段后,会回复一个最终的 **ACK** 确认报文段,确认号为 ack=y+1。发送后,客户端进入 **TIME-WAIT** 状态。服务端在收到这个 ACK 后,立即进入 **CLOSED** 状态,完成连接关闭。客户端则会在 **TIME-WAIT** 状态下等待 **2MSL**(Maximum Segment Lifetime,报文段最大生存时间)后,才最终进入 **CLOSED** 状态
6589

6690
**只要四次挥手没有结束,客户端和服务端就可以继续传输数据!**
6791

@@ -82,7 +106,7 @@ TCP 是全双工通信,可以双向传输数据。任何一方都可以在数
82106

83107
### 如果第二次挥手时服务端的 ACK 没有送达客户端,会怎样?
84108

85-
客户端没有收到 ACK 确认,会重新发送 FIN 请求
109+
客户端在发送 FIN 后会启动一个重传计时器。如果在计时器超时之前没有收到服务端的 ACK,客户端会认为 FIN 报文丢失,并重新发送 FIN 报文
86110

87111
### 为什么第四次挥手客户端需要等待 2\*MSL(报文段最长寿命)时间后才进入 CLOSED 状态?
88112

docs/interview-preparation/project-experience-guide.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,9 @@ GitHub 或者码云上面有很多实战类别项目,你可以选择一个来
7272

7373
## 有没有还不错的项目推荐?
7474

75-
**[《Java 面试指北》](../zhuanlan/java-mian-shi-zhi-bei.md)** 的「面试准备篇」中有一篇文章专门整理了一些比较高质量的实战项目,非常适合用来学习或者作为项目经验。
75+
**[《Java 面试指北》](../zhuanlan/java-mian-shi-zhi-bei.md)** 的「面试准备篇」中有一篇文章专门整理了一些比较高质量的实战项目,包含业务项目、轮子项目、国外公开课 Lab 和视频类实战项目教程推荐,非常适合用来学习或者作为项目经验。
7676

77-
![](https://oss.javaguide.cn/javamianshizhibei/project-experience-guide.png)
77+
![优质 Java 实战项目推荐](https://oss.javaguide.cn/javamianshizhibei/project-experience-guide.png)
7878

7979
这篇文章一共推荐了 15+ 个实战项目,有业务类的,也有轮子类的,有开源项目、也有视频教程。对于参加校招的小伙伴,我更建议做一个业务类项目加上一个轮子类的项目。
8080

docs/interview-preparation/teach-you-how-to-prepare-for-the-interview-hand-in-hand.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ Java 后端面试复习的重点请看这篇文章:[Java 面试重点总结(
138138

139139
一定不要抱着一种思想,觉得八股文或者基础问题的考查意义不大。如果你抱着这种思想复习的话,那效果可能不会太好。实际上,个人认为还是很有意义的,八股文或者基础性的知识在日常开发中也会需要经常用到。例如,线程池这块的拒绝策略、核心参数配置什么的,如果你不了解,实际项目中使用线程池可能就用的不是很明白,容易出现问题。而且,其实这种基础性的问题是最容易准备的,像各种底层原理、系统设计、场景题以及深挖你的项目这类才是最难的!
140140

141-
八股文资料首推我的 [《Java 面试指北》](https://t.zsxq.com/11rZ6D7Wk) (配合 JavaGuide 使用,会根据每一年的面试情况对内容进行更新完善)和 [JavaGuide](https://javaguide.cn/) 。里面不仅仅是原创八股文,还有很多对实际开发有帮助的干货。除了我的资料之外,你还可以去网上找一些其他的优质的文章、视频来看。
141+
八股文资料首推我的 [《Java 面试指北》](https://javaguide.cn/zhuanlan/java-mian-shi-zhi-bei.html) (配合 JavaGuide 使用,会根据每一年的面试情况对内容进行更新完善)和 [JavaGuide](https://javaguide.cn/) 。里面不仅仅是原创八股文,还有很多对实际开发有帮助的干货。除了我的资料之外,你还可以去网上找一些其他的优质的文章、视频来看。
142142

143143
![《Java 面试指北》内容概览](https://oss.javaguide.cn/javamianshizhibei/javamianshizhibei-content-overview.png)
144144

docs/zhuanlan/java-mian-shi-zhi-bei.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,12 @@ star: 5
4848

4949
**「面经篇」** 主要会分享一些高质量的 Java 后端面经,有校招的,也有社招的,有大厂的,也有中小厂的。
5050

51-
如果你是非科班的同学,也能在这些文章中找到对应的非科班的同学写的面经。
51+
**为何推荐选择我整理的面经?**
52+
53+
与牛客网等平台上海量的面经信息相比,《Java面试指北》中提供的面经在质量筛选和价值挖掘上投入了更多精力。每一份被收录的面经,都力求:
54+
55+
- **内容真实、有启发性**: 优先选择那些能反映实际面试场景、考察重点和面试官思路的经验。
56+
- **提供深度学习资源**: 针对面经中出现的关键问题,会精心提供高质量的参考资料(通常是我撰写的深度解析文章)或直接给出核心参考答案。
5257

5358
![《Java 面试指北》面经篇](https://oss.javaguide.cn/javamianshizhibei/thinkimage-20220612185810480.png)
5459

0 commit comments

Comments
 (0)