【Linux-網絡】深入拆解TCP核心機制與UDP的無狀態設計

?52bc67966cad45eda96494d9b411954d.png

🎬?個人主頁:誰在夜里看海.

📖?個人專欄:《C++系列》《Linux系列》《算法系列》

???道阻且長,行則將至


目錄

📚引言

📚一、UDP協議

📖 1.概述

📖 2.特點

📚二、TCP協議?

📖 1.概述

📖 2.機制

🔖確認應答(ACK)

🔖超時重傳

🔖連接管理

🔖滑動窗口

🔖流量控制

🔖擁塞控制

🔖延遲、捎帶應答

📖3.總結


📚引言

在之前的一篇文章中,我們詳細介紹了 socket網絡編程(基于 TCPUDP),并且在應用層,我們已經能夠熟練地調用API來編寫簡單的服務器和客戶端應用。然而,要更好地理解網絡編程,我們必須深入了解這兩種協議的傳輸機制和它們的工作原理。今天,我們將通過對 TCPUDP協議的進一步剖析,探索它們在實際傳輸中的差異、優勢和局限性。

🔗文章鏈接:《【Linux-網絡】初識計算機網絡 & Socket套接字 & TCP/UDP協議(包含Socket編程實戰)》

📚一、UDP協議

📖 1.概述

UDP(User Datagram Protocol,用戶數據報協議)是面向報文的協議,即數據是通過報文的形式進行傳輸,類似于寄信。與 TCP 協議相比,它更加簡潔和高效,體現在更少的報文段信息以及沒有TCP協議的各種機制。

下面是UDP報文段的標準格式:

UDP數據報由 頭部數據部分 兩部分組成:

UDP頭部(8字節)

① 源端口號(16位):表示發送數據的應用端口。

② 目的端口號(16位):表示接收數據的應用端口。

③ 長度(16位):表示整個UDP報文的長度,包括頭部和數據部分的總長度。最大值為64k字節。

④ 校驗和(16位):用于檢測傳輸過程中的數據完整性。雖然UDP是可選的,但如果IPv6被使用,校驗和是必須的。

UDP數據部分:包括從源應用傳來的數據,數據部分的大小由上面提到的 長度字段 決定。

???由于UDP數據包的最大長度為64k,當要數據大于這個長度時,就需要進行分包傳輸。

📖 2.特點

與 UDP 的簡潔性相對應地,UDP是 無連接的不可靠的

1???面向報文:UDP是面向報文的協議,意味著每次發送的數據包都是一個獨立的單位。

2???較小的頭部開銷:UDP頭部僅包含 8個字節,相比TCP的20字節頭部,UDP的頭部開銷更小。

3???不可靠性:UDP不保證數據的可靠傳輸,也不保證數據的順序。如果數據丟失,發送方沒有重傳機制,接收方無法知道數據丟失。

由于UDP協議的 低延遲簡潔性,它特別適合用于對實時性要求高、但對數據可靠性要求較低的場景,例如實時視頻通話、在線游戲等。

UDP協議提供的是一種不可靠的數據傳輸方式,適用于對實時性要求高的場景。然而,當我們需要確保數據包的可靠傳輸,避免丟包時,TCP協議則成為更合適的選擇。?

📚二、TCP協議?

📖 1.概述

TCP(Transmission Control Protocol,傳輸控制協議)是一種面向連接、可靠的傳輸層協議。它確保數據能夠準確、按順序地傳輸到目的地。為了保證數據傳輸的可靠性和穩定性,TCP報文段就需要包含更多信息。

下面是TCP報文段的標準格式:

其中序列號、確認號、標志位(ACK、SYN等)、窗口大小這些數據段需要結合TCP的特殊傳輸機制來理解,這里我們先區分一下UDP的報文長度TCP的首部長度

?前者表示整個報文段的長度,后者僅表示報文頭的長度,這是為什么呢?

?UDP中報文長度這一數據段的作用是使接收方可以正確提取數據,而在TCP中這一職責由序列號+首部長度共同完成,其中序列號表示的是數據區的長度。之所以要標明報頭長度是因為,TCP報頭是不定長的,除了固定數據段之外,還有可選數據段。

TCP的選項數據段是TCP頭部的可選字段,允許在連接建立后對TCP連接進行進一步的配置和優化。選項字段用于擴展TCP協議的功能,提供額外的控制信息,以適應不同的應用需求。

下面我們來一一介紹TCP的各種機制。

📖 2.機制

🔖確認應答(ACK)

我們提到,TCP協議提供的是可靠傳輸,這當中非常重要的一點是,要避免數據丟包問題,由于網絡是不穩定的,數據丟包是很正常的現象。那么發送方怎么知道發送的數據有沒有丟失呢?很簡單,讓接收方接受數據后回應一下,表示數據收到了,這就是TCP的確認應答機制

但是當發送方發送多個數據包后,怎么知道收到的應答是對應哪個數據包的呢,這就需要TCP中的確認號序列號字段了。

序列號每個發送的數據段都被賦予一個唯一的序列號,用于標識數據流中的每一個字節。這個序列號是TCP可靠傳輸的基礎,接收方根據序列號判斷數據是否丟失或者是否按正確順序到達。

確認號接收方使用確認號來告訴發送方,自己已經成功接收到的數據的最后一個字節的序列號。確認號是接收方期望接收的下一個字節的序列號。

每一個ACK都帶有對應的確認序列號,表示已接收了哪些數據,下一個數據應該從哪里開始。

🔖超時重傳

基于確認應答機制,當發送方過了一段時間后,還沒有收到來自接收方的確認應答,就可以判定數據包丟失了,此時就需要重新發送數據包,這就是超時重傳機制

這里的丟包分為兩種情況:

① 發送的數據包本身丟失了;② 接收方的確認應答丟失了。

無論是哪種情況,都需要重新發送數據包,而對于第二種情況,接收方會收到兩個相同的數據包,這個時候根據序列號判斷,如果序列號相同,則認為兩個數據包相同,會將重復的數據包丟棄,并不影響。

?這個超時的時間該如何確定呢?

數據包傳輸到達的時間是會受網絡環境影響變化的,如果超時時間設置的太長,會影響重傳的效率;如果超時時間設置的過短,則有可能會頻繁發送重復的數據包。

?TCP為了保證在任何環境下都能比較高性能的通信,會動態計算這個超時時間。

以Linux為例,超時時間以500ms為單位,如果重傳一次還沒有得到應答,則等待2*500ms后再進行重傳;之后還得不到應到,則等待4*500ms......直到累計一定的重傳次數后,TCP判定網絡或目標主機出現異常,強制關閉連接

🔖連接管理

基于TCP協議進行通信的雙方,一個基本的前提條件就是,雙方都確保能正常發送和接受數據,這樣才能保證通信的穩定與可靠性。所以在通信發生之前,需要對雙方的發送、接受能力進行驗證;同樣地,在通信結束時,也需要確保雙方都已關閉連接信道,避免單方面發送數據卻不能被接收也等不到應答的情況。這就是三次握手與四次揮手機制。?

在理解三次握手與四次揮手之前,我們需要了解一個預備知識,那就是TCP報文段的標志位

TCP報文段中的標志位(也叫控制位)用于控制TCP連接的建立、維護和終止。每個TCP報文段中都有一個6位的標志字段,分別是:

① URG(緊急標志):用于指示數據段中有緊急數據需要處理

② ACK(確認標志):表示確認號字段有效,即接收方通過確認號來告知發送方它期望接收的下一個字節的序列號

③ PSH(推送標志):表示接收方應該立即將數據推送給應用層

④ RST(重置標志):強制斷開TCP連接,用于一方出現錯誤或不可恢復的異常的情況

⑤ SYN(同步標志):用于連接的建立,表示請求連接或響應連接請求

⑥ FIN(終止標志):用于連接的斷開,表示發送方沒有數據要發送,并請求關閉連接

在TCP三次握手過程中,SYN標志位會在第一次和第二次握手時被使用:

1?? 客戶端發起連接時,會發送一個帶SYN標志的報文,表示請求建立連接。

2?? 服務器響應客戶端請求時,也會發送一個帶SYN標志的報文來表示同意連接。

在TCP四次揮手過程中,FIN標志位被用來發起和響應連接的終止

1?? 主動關閉連接的一方會發送帶有FIN標志的報文,表示它已經完成數據傳輸并希望關閉連接。

2?? 被動關閉的一方也會發送帶有FIN標志的報文作為確認,表示它同意終止連接。?

下面是三次握手的全過程:

① 第一次握手:通信發起方向接收方發送SYN報文,請求連接(打開寫端,表示我要寫數據了)

② 第二次握手:接收方收到SYN報文,回復ACK報文,表示同意連接請求(打開讀端,表示我能收到數據);并同時也發送SYN報文(打開寫端,我也要寫數據了)

③ 第三次握手;發起方收到SYN報文,同意回復ACK報文(打開讀端,表示我也能收到數據)

四次揮手的全過程:

① 第一次揮手:斷開連接發起方向接收方發送FIN報文,表示希望關閉連接(關閉寫端,表示不再寫數據了)

② 第二次揮手:接收方收到FIN請求,回復ACK表示同意(關閉讀端,我不再等待接收數據了)

③ 第三次揮手:接收方發送FIN請求(關閉寫端,我也不寫數據了)?

④ 第四次揮手:發起方收到FIN請求,回復ACK表示同意(關閉讀端,我也不等待接收數據了)

從上面的步驟來看,其實第二次握手是包含兩步的:接收方打開讀端與寫端,這與第二次揮手、第三次揮手是對應上的,問題來了:

?① 為什么要把接收方打開讀端與寫端的操作合并為一步;② 為什么接收方斷開讀端和寫端的操作不能合并成一步。

?先回答第一個問題,我們要知道,每一個標志位的獨立發送都需要獨立的報文段,接收方要分別發送ACK與SYN的話就需要占用兩個報文段,既然如此,為什么不把這兩步合成一步,節省資源呢,于是就有了第二次握手。

?對于第二個問題,斷開連接發起方發送FIN報文的意思是,不會再發送數據了,也就是關閉了寫端,但這并不意味著讀端也關閉了;同樣地,接收方在收到FIN報文后回復ACK的意思是,關閉讀端,但也不意味著寫端就要一并關閉,相反地,它依舊可以發送數據,對方也依舊可以收到數據,因此二、三揮手要分開來執行。

在TCP協議中,連接的建立與斷開遵循嚴格的狀態變化流程。理解連接發起方、接收方以及斷開發起方、接收方的狀態變化對理解TCP的三次握手(連接建立)和四次揮手(連接終止)至關重要。

連接建立(TCP三次握手)

① 連接發起方(客戶端)

? ? ? ? 初始狀態:CLOSED(連接關閉);

????????發送SYN請求:客戶端進入 SYN_SENT 狀態,發送一個SYN報文;

????????接收ACK響應?確認連接建立,進入 ESTABLISHED 狀態,開始數據的雙向傳輸。

②?連接接收方(服務器)

????????初始狀態:LISTEN(監聽狀態)

????????接收SYN請求:?進入 SYN_RCVD 狀態,并發送一個帶有SYN和ACK標志的響應報文(SYN-ACK),表示同意建立連接。

????????等待確認:?收到客戶端的確認ACK報文后,連接成功建立,進入 ESTABLISHED 狀態,開始數據的雙向傳輸。

三次握手過程狀態變化圖

  • 客戶端(發起方): CLOSEDSYN_SENTESTABLISHED
  • 服務器(接收方): LISTENSYN_RCVDESTABLISHED

連接斷開(TCP四次揮手)?

① 連接斷開發起方(客戶端/服務器)

1. 初始狀態:ESTABLISHED(已建立連接);

2. 發送FIN請求:此時,該端點的寫端被關閉,進入 FIN_WAIT_1 狀態;

3. 等待ACK響應: 主動關閉方在 FIN_WAIT_1 狀態等待接收方的ACK報文確認其斷開請

4. 等待接收方的FIN:?此時,主動關閉方進入 TIME_WAIT 狀態,等待足夠的時間確保接收方收到了最后的ACK報文。

②?連接斷開接收方(服務器/客戶端)

1. 初始狀態:ESTABLISHED(已建立連接);

2. 接收FIN請求: 被動關閉的一方在 ESTABLISHED 狀態收到主動關閉方的FIN報文后,進入 CLOSE_WAIT 狀態,表示確認收到對方的斷開請求,并準備關閉自己的寫端。

3. 發送ACK響應: 被動關閉方發送ACK報文,確認收到對方的FIN報文。此時,它的寫端被關閉,但接收端仍然保持開放,允許接收剩余的數據。

4. 發送FIN: 當被動關閉方完成數據接收后,主動發送帶有FIN標志的報文,表示自己也沒有數據要發送了,進入 LAST_ACK 狀態。

5. 等待確認: 被動關閉方等待對方的ACK確認,確認連接完全斷開后,進入 CLOSED 狀態。

四次揮手過程狀態變化圖

  • 主動關閉方:
    • ESTABLISHEDFIN_WAIT_1FIN_WAIT_2TIME_WAITCLOSED
  • 被動關閉方:
    • ESTABLISHEDCLOSE_WAITLAST_ACKCLOSED

🔖滑動窗口

基于確認應答機制,如果每發送一次報文,都需要等待應答,收到ACK后再發送下一個報文,這樣做會大大影響性能。于是我們可以一次性發送多個報文,并且同時等待多個應答,因為發送的報文是基于序列號順序發送的,所以可以看作一個滑動窗口,窗口內部是已發送但還未收到應答的報文,當收到應答后,右移窗口的左端;發送新報文后,右移動窗口右端。這就是滑動窗口機制。

?如果在發送過程中出現丟包,該如何解決?這里分兩種情況:

① 數據包已抵達,但ACK丟了。這種情況下,基于超時重傳機制,發送方會重新發送數據包,直到接收到相應的ACK為止

② 數據包丟失了。例如,發送方一共發送了序列號為1~5000的數據包,但是當中1001~2000的數據包丟失了,其余的沒有丟失。在這種情況下,接收方返回的確認序列號會一直為1001,表示1001開頭的報文沒有收到,此時發送方得知后會重新發送1001~2000的數據包,此時接收方返回的確認序列號為5001(因為2001~5000的數據包已經收到了)。

這種機制被稱為“高并發重傳機制”。

🔖流量控制

接收方收到數據包后時并不會立即處理,而是暫存在接收緩沖區中,而緩沖區的空間時有限的,這就意味著如果發送方一次性發送過多數據包,就會出現由于緩沖區空間不足而丟包的情況。?為了避免這種情況的發送,發送方就需要控制發送速度,就需要借助流量控制機制

控制速度的依據是接收方的緩沖區剩余空間大小,而發送方該怎么得知這一信息呢,就需要借助TCP報文段中的“窗口大小”字段。

接收方依據緩沖區剩余空間,設置窗口大小并通過ACK應答報文告知發送方,如果窗口大小變小,發送方就會減緩發送速度;如果窗口大小為0,發送方就停止發送數據,但是會時不時發送窗口探測,用于探測請求接收方窗口更新。

?即使發送方不進行窗口探測,接受方在緩沖區有空間剩余之后還是會發送窗口更新報文,但是為什么發送方還是需要時不時進行探測呢?

?因為接收方的窗口更新報文有可能丟失,如果發送方不探測,接收方就不會重傳

🔖擁塞控制

基于流量控制機制,發送方在數據發送的過程中可以很好地控制速度,但是還存在一個問題,那就是在剛建立通信連接,第一次發送數據時,并不知道接收方的緩沖區情況,此時并不能確定該發送多少數據。于是TCP引入慢啟動機制,即一開始只發送少量數據,目的是探測對方的“吞吐量”大小,清楚情況后,再決定用什么速度傳輸數據。

那么這個傳輸速度具體該如何確定呢?這里要引入“擁塞窗口”的概念:

數據發送開始時,擁塞窗口為1;此后每收到一個ACK,擁塞窗口加1,并取擁塞窗口與ACK中窗口大小的較小值作為本次發送數據的大小。

如此一來,數據發送速率是呈指數級增長的,但是這到了后面,速度會變得很不可控,并且很大概率會出現丟包(發送速度過快),因此要對速度進行限制,就需要借助“慢啟動閾值”這一概念。

當擁塞窗口超過閾值時,就不再按指數級增長,而是按線性增長。這個閾值初始為窗口最大值,之后每發送一次超時重傳,閾值變為原來的一半,并且擁塞窗口置為1(將閾值慢慢逼近一個合理值,既保證了傳輸效率,又減少了出現丟包的可能性)

🔖延遲、捎帶應答

接收方在ACK應答的同時,也在處理緩沖區的數據,也就是說,如果ACK立即應答,其時效性會比較低下(剩余空間遠大于窗口值,因為一部分數據已被處理),于是TCP引入了延遲應答機制接收方在接收數據之后,會等待一段時間再發送ACK應答,這樣在一定程度上可以確保窗口大小的時效性

基于延遲應答,接收方的數據包發送和ACK應答可以共用一個數據段,這樣可以大大節約資源,第二次握手就是很好的例子。?

📖3.總結

TCP協議通過以上多種機制確保了數據傳輸的可靠性,并且通過一系列優化手段提升傳輸性能。因此,以上機制可以大致分為兩類:可靠性機制性能優化機制

? ? ? ? ? ? ? ? ? ? ? ? ? ? ?可靠性機制? ? ? ? ? ? ? ? ? ? ? ? ? 性能優化機制
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 校驗和? ? ? ? ? ? ? ? ? ? ? ? ? ? ?滑動窗口
? ? ? ? ? ? ? ? ? ? ? ? 序列號(按序到達)? ? ? ? ? ? ? ? ? ? ? ? ? ? ?快速重傳
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?確認應答? ? ? ? ? ? ? ? ? ? ? ? ? ? ?延遲應答
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?超時重發? ? ? ? ? ? ? ? ? ? ? ? ? ? ?捎帶應答
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?連接管理
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?流量控制
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?擁塞控制

以上就是【深入拆解TCP核心機制與UDP的無狀態設計】的全部內容,歡迎指正~?

碼文不易,還請多多關注支持,這是我持續創作的最大動力!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/86335.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/86335.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/86335.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

(nice!!!)(LeetCode 每日一題) 2081. k 鏡像數字的和 (枚舉)

題目:2081. k 鏡像數字的和 思路:枚舉10進制的回文串,然后來判斷對應的k進制數是否是回文串。直到有n個滿意即可。 而枚舉10進制的回文串,從基數p(1、10、100… )開始,長度為奇數的回文串,長度為偶數的回文…

Java面試題027:一文深入了解數據庫Redis(3)

Java面試題025:一文深入了解數據庫Redis(1) Java面試題026:一文深入了解數據庫Redis(2) 本節我們整理一下Redis高可用和消息隊列使用場景的重點原理,讓大家在面試或者實際工作中遇到這類問題時…

算法打卡 day4

4 . 高精度算法 性質:數組或者容器從低位往高位依次存儲大整數,方便進位。 4.1 高精度加法 給定兩個正整數(不含前導 0),計算它們的和。 輸入格式 共兩行,每行包含一個整數。 輸出格式 共一行,…

【筆記】Docker 配置阿里云鏡像加速(公共地址即開即用,無需手動創建實例)

2025年06月25日記 【好用但慎用】Windows 系統中將所有 WSL 發行版從 C 盤遷移到 非系統 盤的完整筆記(附 異常處理)-CSDN博客 【筆記】解決 WSL 遷移后 Docker 出現 “starting services: initializing Docker API Proxy: setting up docker ap” 問題…

day35-Django(1)

day35-Django 3.2 前言 之前我們介紹過web應用程序和http協議,簡單了解過web開發的概念。Web應用程序的本質 接收并解析HTTP請求,獲取具體的請求信息處理本次HTTP請求,即完成本次請求的業務邏輯處理構造并返回處理結果——HTTP響應import socketserver = socket.socket() …

PostgreSQL全棧部署指南:從零構建企業級高可用數據庫集群

PostgreSQL全棧部署指南:從零構建企業級數據庫集群 前言: 本文詳解了**PostgreSQL**所有的部署方式,如 yum 安裝、源碼編譯安裝、RPM包手動安裝,以及如何選擇適合的安裝方式。適合不同的場景應用。通過高可用部署詳細了解安裝思路及過程,包括內網環境下的配置、主節點的創…

MQTT 和 HTTP 有什么本質區別?

MQTT 和 HTTP 的本質區別在于它們設計的初衷和核心工作模式完全不同。它們是為解決不同問題而創造的兩種工具。 簡單來說: HTTP 就像是去圖書館問問題:你(客戶端)主動去找圖書管理員(服務器),…

GtkSharp跨平臺WinForm實現

文章目錄 跨平臺架構設計跨平臺項目配置GtkSharp串口通訊實現跨平臺部署配置Linux系統配置macOS系統配置 相關學習資源GTK#跨平臺開發跨平臺.NET開發Linux開發環境macOS開發環境跨平臺UI框架對比容器化部署開源項目參考性能優化與調試 跨平臺架構設計 基于GTKSystem.Windows.F…

【閑談】對于c++未來的看法

對于C未來看法 C 作為一門誕生于上世紀的編程語言,在軟件工業發展史上扮演了不可替代的角色。盡管近年來諸如 Rust、Go、Swift、Kotlin 等現代語言相繼崛起,C 依然在系統軟件、高性能服務、嵌入式等關鍵領域中發揮著主力作用。本文將從 C 的當前應用前景…

【論文】云原生事件驅動架構在智能風控系統中的實踐與思考

摘要 2023年6月至2024年3月,我作為某頭部證券公司新一代極速交易系統的首席架構師,主導設計并落地了基于云原生事件驅動架構的全新交易風控平臺。該項目旨在攻克原有系統無法支撐峰值20萬筆/秒交易量、風控延遲超過3秒以及行情劇烈波動時系統崩潰等核心痛點。通過構建以Kube…

opensbi從0到1入門學習

最近要在RV64的平臺上把Linux給bringup起來,由于當下的工作主要集中在底層硬件接口驅動、CPU的操作及RTOS應用等,雖然之前搞過Arm Linux的開發工作,但是比較基礎的玩的比較少,所以真正要搞把系統bringup起來,我之前的知…

Python打卡:Day36

復習日 浙大疏錦行

開發過程中的時空權衡:如何優雅地平衡時間與空間效率

文章目錄 恒的開發者困境一、理解時間與空間的基本概念1. 時間復雜度2. 空間復雜度 二、時空權衡的基本原則1. 硬件環境決定優先級2. 應用場景決定策略3. 數據規模的影響 三、實際開發中的權衡策略1. 緩存為王:用空間換時間2. 壓縮數據:用時間換空間3. 預…

RAG 應用實戰指南:從商業目標到系統落地與運營 E2E 實踐

專欄入口 前言 在當今信息爆炸的時代,如何高效地從海量數據中提取有用信息并提供智能問答服務,成為眾多企業關注的焦點。檢索增強生成(Retrieval-Augmented Generation, RAG)技術以其結合了檢索模型的精準性和生成模型的靈活性&a…

關于晨脈的概念解釋

晨脈(Resting Morning Pulse)是指??人體在清晨清醒后、未進行任何活動前??,于臥床狀態下測量的每分鐘脈搏或心率次數。它反映了人體在無運動消耗、無神經干擾時的基礎代謝狀態,是評估心臟功能、身體恢復情況及運動適應性的重要…

自然語言處理入門

一、概念 自然語言處理(Natural Language Processing, 簡稱NLP)是計算機科學與語言中關注于計算機與人類語言間轉換的領域。 二、發展史 2012年:深度學習的崛起 Word2Vec的提出(Mikolov等,2013年正式發表&#xff0c…

【算法 day12】LeetCode 226.翻轉二叉樹 |101. 對稱二叉樹 |104.二叉樹的最大深度|111.二叉樹的最小深度

226.翻轉二叉樹 (前序,后序) 題目鏈接 | 文檔講解 |視頻講解 : 鏈接 1.思路: 翻轉的是指針,不是數值 前序遍歷和后序遍歷都可以 中序不行,中序遍歷的順序是左中右,反轉左指針后,到根節點,…

Spring Boot 整合 Swagger3 如何生成接口文檔?

前后端分離的項目,接口文檔的存在十分重要。與手動編寫接口文檔不同,swagger是一個自動生成接口文檔的工具,在需求不斷變更的環境下,手動編寫文檔的效率實在太低。與新版的swagger3相比swagger2配置更少,使用更加方便。…

Rust 的智能指針

在 Rust 中,智能指針是一種特殊的數據結構,它不僅存儲數據的地址,還提供了額外的功能,如自動內存管理、引用計數等。智能指針在 Rust 中非常重要,因為它們幫助開發者管理內存,同時保持代碼的安全性和效率。…

Redis RDB 持久化:原理、觸發方式與優缺點全解析

引言 作為 Redis 最經典的持久化機制之一,RDB(Redis DataBase)憑借高效的快照生成能力和快速的恢復速度,一直是開發者的心頭好。但很多人對它的底層原理、觸發時機和適用場景仍存在疑惑。今天咱們就對RDB進行全解析,幫…