[八股速成]計網操作系統篇
前言
我之前整理過計網操作系統超詳細八股筆記:http://fangfengwang8.cn/discuss/581630972664332288?sourceSSR=users ,但是說實話因為這份這份八股資料過于詳細,內容過于充實,給背記帶來了很大的挑戰(zhàn),所以我準備再出一系列帖子,內容就是我根據自己的面試經歷和網上的面經,去篩選八股里面哪些是最常被問到的問題把它們整理出來,這樣也能省去大家自己整理和篩選的時間,大家可以在面試前一兩個小時快速把這一系列最常問八股的帖子拿出來看看,臨時抱佛腳的效果應該很好。后面這系列帖子我會放入專欄http://fangfengwang8.cn/creation/manager/columnDetail/0ybvLm,歡迎大家訂閱。最后我想說,速成雖好,但是還是建議有時間就去看看我詳細的八股筆記帖子。
計網
基礎知識
1.OSI 七層模型
2.TCP/IP模型
由以下 4 層組成:
- 應用層
- 傳輸層
- 網絡層
- 網絡接口層
TCP和UDP
0.udp
1.tcp的單播和udp的多播和廣播
- 單播:兩個主機間單對單的通信
- 廣播:一個主機對整個局域網上所有主機上的數據通信(網絡地址全1)
單播和廣播是兩個極端,要么對一個主機進行通信,要么對整個局域網的主機進行通信
? 3.多播:實際情況下,經常需要對一組特定的主機進行通信,而不是所有局域網上的主機
2.udp怎么解決數據包順序錯亂和丟包的問題/怎么保證可靠傳輸?
UDP(用戶數據報協議)是一種無連接的傳輸層協議,它提供了不可靠的數據報服務。這意味著UDP本身并不保證數據包的順序或防止數據包丟失。然而,可以在應用層上實現一些機制來解決這些問題。以下是一些常用的方法:
解決數據包順序錯亂的問題
- 序列號機制: 給每個發(fā)送的數據包分配一個唯一的序列號。接收端可以根據序列號重新排序接收到的數據包,確保它們按照正確的順序處理。
- 確認應答(ACK)機制: 發(fā)送方為每個數據包設置一個定時器,并等待接收方的確認。如果在定時器超時前沒有收到確認,則可以假設數據包已丟失,并重新發(fā)送該數據包。接收方在接收到數據包后,會根據序列號發(fā)送確認信息給發(fā)送方,以告知哪些數據包已經正確接收。
- 滑動窗口協議: 滑動窗口協議允許發(fā)送方連續(xù)發(fā)送多個數據包而不需要為每一個數據包等待確認。接收方可以使用序列號來識別亂序到達的數據包,并通過累積確認告訴發(fā)送方哪些數據包已經被成功接收。
解決數據包丟失的問題
- 超時重傳: 結合上述的序列號和確認機制,如果發(fā)送方在一定時間內未收到確認,則認為數據包丟失并進行重傳。
- 冗余編碼: 在發(fā)送數據時加入一定的冗余信息(如前向糾錯碼FEC),這樣即使某些數據包丟失,接收端也可以利用剩余的數據包和冗余信息恢復原始數據。
- 混合ARQ(自動重傳請求): 結合前向糾錯(FEC)與傳統的ARQ技術,允許接收方在檢測到丟失或錯誤時嘗試自行糾正錯誤,同時對于無法糾正的情況請求重傳。
這些方法都需要在應用程序層面實現,因為UDP本身并沒有提供這樣的功能。實際上,許多實時通信系統,比如VoIP和視頻流媒體服務,都會在其協議棧中包含類似的機制來應對UDP的不可靠性。
1.TCP和UDP的區(qū)別?
TCP:傳輸控制協議,UDP:用戶數據報協議。
區(qū)別:
1.TCP面向連接,即使用TCP通信雙方傳輸前要三次握手來簡歷TCP連接;UDP是無連接的,即發(fā)送數據之前不需要建立連接,可以隨時發(fā)送數據。
2.TCP僅支持單播(即一對一通信);UDP支持單播、多播和廣播;
3.TCP提供可靠的服務(即不會出現無碼、丟失等傳輸差錯);UDP提供不可靠服務。因此,TCP適用于要求可靠傳輸且對實時性要求不高的應用,如文件傳輸和電子郵件;而UDP適合視頻會議等實時應用。
4.TCP面向字節(jié)流,即把應用報文看成一連串無結構的字節(jié)流;UDP是面向報文的,即對應用保溫既不合并也不拆分而是保留報文的邊界。
5.TCP有擁塞控制;UDP沒有擁塞控制,因此網絡出現擁塞不會使源主機的發(fā)送速率降低(對實時應用很有用,如實時視頻會議等)。
6.TCP首部開銷20字節(jié);UDP的首部開銷小,只有8個字節(jié)。
3.TCP 協議是如何保證可靠傳輸的?
- 數據包校驗:目的是檢測數據在傳輸過程中的任何變化,若校驗出包有錯,則丟棄報文段并且不給出響應,這時 TCP 發(fā)送數據端超時后會重發(fā)數據;
- 對失序數據包重排序:既然 TCP 報文段作為 IP 數據報來傳輸,而 IP 數據報的到達可能會失序,因此 TCP 報文段的到達也可能會失序。TCP 將對失序數據進行重新排序,然后才交給應用層;
- 丟棄重復數據:對于重復數據,能夠丟棄重復數據;
- 應答機制:當 TCP 收到發(fā)自 TCP 連接另一端的數據,它將發(fā)送一個確認。這個確認不是立即發(fā)送,通常將推遲幾分之一秒;
- 超時重傳:TCP在發(fā)送一個數據之后,就開啟一個定時器,若是在這個時間內沒有收到發(fā)送數據的ACK確認報文,則對該報文進行重傳,在達到一定次數還沒有成功時放棄并發(fā)送一個復位信號。
- 流量控制:TCP 連接的每一方都有固定大小的緩沖空間。TCP 的接收端只允許另一端發(fā)送接收端緩沖區(qū)所能接納的數據,這可以防止較快主機致使較慢主機的緩沖區(qū)溢出,這就是流量控制。TCP 使用的流量控制協議是可變大小的滑動窗口協議。
- 擁塞控制 : 當網絡擁塞時,減少數據的發(fā)送。TCP 在發(fā)送數據的時候,需要考慮兩個因素:一是接收方的接收能力,二是網絡的擁塞程度。接收方的接收能力由滑動窗口表示,表示接收方還有多少緩沖區(qū)可以用來接收數據。網絡的擁塞程度由擁塞窗口表示,它是發(fā)送方根據網絡狀況自己維護的一個值,表示發(fā)送方認為可以在網絡中傳輸的數據量。發(fā)送方發(fā)送數據的大小是滑動窗口和擁塞窗口的最小值,這樣可以保證發(fā)送方既不會超過接收方的接收能力,也不會造成網絡的過度擁塞。
4.TCP怎么實現流量控制(滑動窗口)
TCP 利用滑動窗口實現流量控制。流量控制是為了控制發(fā)送方發(fā)送速率,保證接收方來得及接收。接收方發(fā)送的確認報文中的窗口字段可以用來控制發(fā)送方窗口大小,從而影響發(fā)送方的發(fā)送速率。將窗口字段設置為 0,則發(fā)送方不能發(fā)送數據。
以下是TCP滑動窗口流量控制的基本工作原理:
- 窗口大小:在TCP連接建立時,雙方會協商一個初始窗口大小。這個窗口大小是以字節(jié)為單位的,并且在數據傳輸過程中可以動態(tài)調整。接收方會在每個ACK(確認)報文中包含當前可用窗口大小的信息。
- 累積確認:當接收方收到數據段后,它不會立即對每一個數據段都發(fā)送一個確認,而是等待一段時間看是否能接收到后續(xù)的數據段,然后一次性確認所有已經正確到達的數據。這種方式提高了效率,減少了網絡上的確認報文數量。
- 流量控制:發(fā)送方根據接收到的接收方的窗口大小來決定接下來可以發(fā)送多少數據。如果接收方處理不過來,它可以減小窗口大小,甚至設置為0來暫停發(fā)送方的數據發(fā)送。當接收方處理完一些數據后,它可以再次增加窗口大小,允許發(fā)送方繼續(xù)發(fā)送數據。
- 選擇性確認(SACK):除了基本的累積確認外,TCP還支持選擇性確認。這意味著接收方可以告訴發(fā)送方哪些特定的數據塊已經成功接收,這樣發(fā)送方就只需要重傳那些確實丟失的數據段,而不是從最后一個確認的序列號開始重傳所有數據。
- 快速重傳與恢復:當發(fā)送方檢測到數據包丟失時,它不需要等到超時重傳計時器到期就可以重傳丟失的數據包。這是通過接收到三個重復的ACK來觸發(fā)的,表明接收方正在等待某個特定的數據包。發(fā)送方會立即重傳丟失的數據包,并進入快速恢復算法以調整其擁塞窗口大小。
其他流量控制方法(令牌桶和漏桶)
令牌桶和漏桶是兩種流量控制算法,它們各自有不同的特性和適用場景。具體來說:
- 令牌桶:令牌桶通過以固定的速率向桶中添加令牌來控制流量,每個請求都需要消耗一個令牌。如果桶中有可用的令牌,則請求被允許通過;如果桶中沒有令牌,則請求會被限制或拒絕。令牌桶能夠應對一定程度的突發(fā)流量,因為它可以累積令牌,從而在短時間內處理更多的請求。
- 漏桶:漏桶則是以固定容量的桶來控制流量,請求像水流一樣以一定的速率流入桶中,超過桶的容量部分會被丟棄。漏桶算法能夠平滑地限制請求的速率,但不適合應對突發(fā)流量,因為它的容量是固定的,無法臨時處理超過平均速率的請求。
在實際應用中,選擇使用令牌桶還是漏桶取決于具體的業(yè)務需求和流量特性:
- 對于需要限制平均速率的場景:可以選擇漏桶,因為它能夠確保請求的處理速度不會超過預設的速率。
- 對于需要處理突發(fā)流量的場景:令牌桶更為合適,因為它允許在短時間內處理更多的請求,只要這些請求在之前的時間窗口內有足夠的令牌積累。
總結來說,令牌桶更適合處理突發(fā)流量,而漏桶更適合平滑限制流量。在實際應用中,應根據系統的承受能力和業(yè)務需求來選擇合適的流量控制算法。
5.TCP的重傳機制是什么?
TCP在發(fā)送一個數據之后,就開啟一個定時器,若是在這個時間內沒有收到發(fā)送數據的ACK確認報文,則對該報文進行重傳,在達到一定次數還沒有成功時放棄并發(fā)送一個復位信號。
6.TCP 的擁塞控制是怎么實現的?
擁塞控制是為了防止過多的數據注入到網絡中讓網絡過載
為了進行擁塞控制,TCP 發(fā)送方要維持一個 擁塞窗口(cwnd) 的狀態(tài)變量。擁塞控制窗口的大小取決于網絡的擁塞程度,并且動態(tài)變化。發(fā)送方讓自己的發(fā)送窗口取為擁塞窗口和接收方的接受窗口中較小的一個。
TCP 的擁塞控制采用了四種算法,即 慢開始、 擁塞避免、快重傳 和 快恢復。在網絡層也可以使路由器采用適當的分組丟棄策略(如主動隊列管理 AQM),以減少網絡擁塞的發(fā)生。
- 慢開始: 慢開始算法的思路是當主機開始發(fā)送數據時,如果立即把大量數據字節(jié)注入到網絡,那么可能會引起網絡阻塞,因為現在還不知道網絡的符合情況。經驗表明,較好的方法是先探測一下,即由小到大逐漸增大發(fā)送窗口,也就是由小到大逐漸增大擁塞窗口數值。cwnd 初始值為 1,每經過一個傳播輪次,cwnd 加倍。
- 擁塞避免: 擁塞避免算法的思路是讓擁塞窗口 cwnd 緩慢增大,即每經過一個往返時間 RTT 就把發(fā)送方的 cwnd 加 1.
- 快重傳與快恢復: 在 TCP/IP 中,快速重傳和恢復(fast retransmit and recovery,FRR)是一種擁塞控制算法,它能快速恢復丟失的數據包。沒有 FRR,如果數據包丟失了,TCP 將會使用定時器來要求傳輸暫停。在暫停的這段時間內,沒有新的或復制的數據包被發(fā)送。有了 FRR,如果接收機接收到一個不按順序的數據段,它會立即給發(fā)送機發(fā)送一個重復確認。如果發(fā)送機接收到三個重復確認,它會假定確認件指出的數據段丟失了,并立即重傳這些丟失的數據段。有了 FRR,就不會因為重傳時要求的暫停被耽誤。 當有單獨的數據包丟失時,快速重傳和恢復(FRR)能最有效地工作。當有多個數據信息包在某一段很短的時間內丟失時,它則不能很有效地工作。
7.說說TCP的三次握手
(序號字段seq:本TCP報文段數據載荷的第一個字節(jié)的序號;
確認號字段ack:指出希望受到對方下一個TCP報文段的數據載荷的第一個字節(jié)的序號,同時也是對之前收到的數據的確認;
確認標志位ACK:值為1表示確認號字段有效;
同步標志位SYN:SYN=1且ACK=0表示是個TCP連接請求報文段;SYN=1且ACK=1表示同意連接請求報文段)
假設發(fā)送端為客戶端,接收端為服務端。開始時客戶端和服務端的狀態(tài)都是CLOSED
。
- 第一次握手:客戶端向服務端發(fā)起建立連接請求,客戶端會隨機生成一個起始序列號x,客戶端向服務端發(fā)送連接請求報文,其中包含標志位
SYN=1
,序列號seq=x
。第一次握手前客戶端的狀態(tài)為CLOSE
,第一次握手后客戶端的狀態(tài)為SYN-SENT
。此時服務端的狀態(tài)為LISTEN
。 - 第二次握手:服務端在收到客戶端發(fā)來的連接請求報文后,會隨機生成一個服務端的起始序列號y,然后給客戶端回復確認報文段,其中包括標志位
SYN=1
,確認標志位ACK=1
(表示這是個TCP連接請求確認報文段),序列號seq=y
,確認號ack=x+1
。第二次握手前服務端的狀態(tài)為LISTEN
,第二次握手后服務端的狀態(tài)為SYN-RCVD
,此時客戶端的狀態(tài)為SYN-SENT
。 - 第三次握手:客戶端收到服務端發(fā)來的報文后,會再向服務端發(fā)送確認報文段,其中包含確認標志位
ACK=1
,序列號seq=x+1
,確認號ack=y+1
。第三次握手前客戶端的狀態(tài)為SYN-SENT
,第三次握手后客戶端和服務端的狀態(tài)都為ESTABLISHED
。此時連接建立完成。
為什么不是兩次握手?
之所以需要第三次握手,主要為了防止已失效的連接請求報文段突然又傳輸到了服務端,導致產生問題。
- 比如客戶端A發(fā)出連接請求,可能因為網絡阻塞原因,A沒有收到確認報文,于是A再重傳一次連接請求。
- 然后連接成功,等待數據傳輸完畢后,就釋放了連接。
- A發(fā)出的第一個連接請求等到連接釋放以后的某個時間才到達服務端B,此時B誤認為A又發(fā)出一次新的連接請求,于是就向A發(fā)出確認報文段。
- 如果不采用三次握手,只要B發(fā)出確認,就建立新的連接了,此時A不會響應B的確認且A不發(fā)送數據,這時候B處于SYN-RECV狀態(tài)一直等待A發(fā)送數據,浪費資源。
8.TCP的4次揮手
客戶端先向其TCP發(fā)出連接釋放報文段(FIN=1,seq=u
),并停止再發(fā)送數據,主動關閉TCP連接,進入FIN-WAIT-1
(終止等待1)狀態(tài),等待服務端的確認。
服務端收到連接釋放報文段后即發(fā)出確認報文段(ACK=1,ack=u+1,seq=v
),服務端進入CLOSE-WAIT
(關閉等待)狀態(tài),此時的TCP處于半關閉狀態(tài),A到B的連接釋放。
A收到B的確認后,進入FIN-WAIT-2
(終止等待2)狀態(tài),等待B發(fā)出的連接釋放報文段。
B發(fā)送完數據,就會發(fā)出連接釋放報文段(FIN=1,ACK=1,seq=w,ack=u+1
),B進入LAST-ACK
(最后確認)狀態(tài),等待A的確認。
A收到B的連接釋放報文段后,對此發(fā)出確認報文段(ACK=1,seq=u+1,ack=w+1
),A進入TIME-WAIT
(時間等待)狀態(tài)。此時TCP未釋放掉,需要經過時間等待計時器設置的時間2MSL
(最大報文段生存時間)后,A才進入CLOSED
狀態(tài)。B收到A發(fā)出的確認報文段后關閉連接,若沒收到A發(fā)出的確認報文段,B就會重傳連接釋放報文段。
第四次揮手為什么客戶端要等待2MSL才進入Closed狀態(tài)?
保證A發(fā)送的最后一個ACK報文段能夠到達B。這個ACK
報文段有可能丟失,B收不到這個確認報文,就會超時重傳連接釋放報文段,然后A可以在2MSL
時間內收到這個重傳的連接釋放報文段,接著A重傳一次確認,重新啟動2MSL計時器,最后A和B都進入到CLOSED
狀態(tài),若A在TIME-WAIT
狀態(tài)不等待一段時間,而是發(fā)送完ACK報文段后直接進入Closed狀態(tài),則A無法收到B重傳的連接釋放報文段,然后B就會反復重傳連接釋放報文段而不會進入Closed狀態(tài)。
為什么是四次揮手?
在關閉連接時,當Server端收到Client端發(fā)出的連接釋放報文時,很可能并不會立即關閉SOCKET,即服務端的報文還沒有發(fā)完,所以Server端先回復一個ACK
確認報文,告訴Client端我收到你的連接釋放報文了。只有等到Server端所有的報文都發(fā)送完了,這時Server端才能發(fā)送連接釋放報文,之后兩邊才會真正的斷開連接。故需要四次揮手。
9.TIME-WAIT
為什么出現TIME-WAIT?
主動關閉連接的一方在發(fā)送最后一個ACK后進入的一個臨時狀態(tài),持續(xù)2MSL(1MSL是報文的存活時間)的時間長度。
當兩個系統通過 TCP 協議進行通信,并且一方決定關閉連接時,會經過一個四次揮手的過程來完成連接的終止。在最后一次確認(ACK)發(fā)送之后,主動關閉連接的一方并不會立即釋放端口并允許新的連接使用該端口,而是將該連接標記為 TIME_WAIT 狀態(tài),并等待一段時間(通常是兩倍的最大段生存時間,即 2MSL),以確保最后一個 ACK 已經被被動關閉連接的一方正確接收。這段時間過后,連接才會被完全關閉,并且端口號可以被重新分配給其他服務。
1.TIME_WAIT 狀態(tài)會導致什么問題
從網絡資源的角度看,該狀態(tài)下的TCP連接占用了本地端口,無法立即釋放。由于端口資源有限,大量處于TIME_WAIT狀態(tài)的連接可能會導致端口資源枯竭,從而影響新的連接建立。尤其是在高并發(fā)、短連接的場景下,這個問題尤為顯著。例如,服務器可能會因為大量的TIME_WAIT狀態(tài)而導致新的客戶端無法連接。
2.有很多 TIME-WAIT 狀態(tài)如何解決
當系統中有大量連接進入 TIME_WAIT 狀態(tài)時,可以通過多種方法來減輕這種狀態(tài)帶來的負面影響。以下是一些常見的解決方案:
- 優(yōu)化應用邏輯: 減少短連接:盡可能將短連接轉換成長連接。例如,Web 應用可以使用 HTTP/1.1 的 keep-alive 特性,這樣客戶端和服務器之間可以保持一個長期的連接,多次請求復用同一個連接,減少了連接建立和關閉的次數。批量處理請求:在客戶端,可以嘗試將多個請求打包成一個較大的請求,從而減少連接建立和關閉的次數。
- 使用 SO_REUSEADDR 或 SO_REUSEPORT: 服務器可以設置 SO_REUSEADDR 套接字選項來通知內核,如果端口被占用,但 TCP 連接位于 TIME_WAIT 狀態(tài)時可以重用端口。
10.TCP的粘包和拆包問題及其解決方案
TCP是面向流,沒有界限的一串數據。TCP底層并不了解上層業(yè)務數據的具體含義,它會根據TCP緩沖區(qū)的實際情況進行包的劃分,所以在業(yè)務上認為,一個完整的包可能會被TCP拆分成多個包進行發(fā)送,也有可能把多個小的包封裝成一個大的數據包發(fā)送,這就是所謂的TCP粘包和拆包問題。
為什么會產生粘包和拆包呢?
- 要發(fā)送的數據小于TCP發(fā)送緩沖區(qū)的大小,TCP將多次寫入緩沖區(qū)的數據一次發(fā)送出去,將會發(fā)生粘包;
- 接收數據端的應用層沒有及時讀取接收緩沖區(qū)中的數據,將發(fā)生粘包;
- 要發(fā)送的數據大于TCP發(fā)送緩沖區(qū)剩余空間大小,將會發(fā)生拆包;
- 待發(fā)送數據大于MSS(最大報文長度),TCP在傳輸前將進行拆包。即TCP報文長度-TCP頭部長度>MSS。
解決方案:
- 發(fā)送端將每個數據包封裝為固定長度
- 在數據尾部增加特殊字符進行分割
- 將數據分為兩部分,一部分是頭部,一部分是內容體;其中頭部結構大小固定,且有一個字段聲明內容體的大小
HTTP
1.HTTP狀態(tài)碼
101 切換請求協議,從 HTTP 切換到 WebSocket
200 請求成功,有響應體
什么是重定向?
重定向(Redirect)是指通過各種方式將網絡請求重新定義,使其轉向其他位置的過程。這種機制在互聯網中廣泛應用,例如:
- 網頁重定向:當用戶訪問的URL已經不再使用或內容已遷移至新的URL時,服務器會返回一個重定向狀態(tài)碼(如301永久重定向或302臨時重定向),并告知瀏覽器新的URL,瀏覽器會自動跳轉到新地址。
- 域名重定向:當一個域名被設置為另一個域名的別名時,所有對該域名的請求都會被自動轉發(fā)到主域名。
- 路由重定向:在網絡路由中,數據包的路徑選擇變化也可以視為一種重定向,即數據包被重新導向至新的路徑以到達目的地。
2.POST和GET有哪些區(qū)別?各自應用場景?
1.使用場景:GET 用于獲取資源,而 POST 用于傳輸實體主體。
2.參數:GET 和 POST 的請求都能使用額外的參數,但是 GET 的參數是以查詢字符串出現在 URL 中,而 POST 的參數存儲在實體主體中。
3.安全性:安全的 HTTP 方法不會改變服務器狀態(tài),也就是說它只是可讀的。GET 方法是安全的,而 POST 卻不是,因為 POST 的目的是傳送實體主體內容,這個內容可能是用戶上傳的表單數據,上傳成功之后,服務器可能把這個數據存儲到數據庫中,因此狀態(tài)也就發(fā)生了改變。
4.冪等性:冪等的 HTTP 方法,同樣的請求被執(zhí)行一次與連續(xù)執(zhí)行多次的效果是一樣的,服務器的狀態(tài)也是一樣的。換句話說就是,冪等方法不應該具有副作用(統計用途除外)。所有的安全方法也都是冪等的。即GET冪等,POST不冪等。
3.HTTP各版本的比較
(這部分看上去沒什么問的價值,但根據我的面試經歷問的很多很多,就是想考你的基礎知識的廣度)
1.HTTP/1.0 和 HTTP/1.1 有什么區(qū)別?
- 連接方式 : HTTP/1.0 為短連接,HTTP/1.1 支持長連接。
- 狀態(tài)響應碼 : HTTP/1.1 中新加入了大量的狀態(tài)碼,光是錯誤響應狀態(tài)碼就新增了 24 種。比如說,
100 (Continue)
——在請求大資源前的預熱請求,206 (Partial Content)
——范圍請求的標識碼,409 (Conflict)
——請求與當前資源的規(guī)定沖突,410 (Gone)
——資源已被永久轉移,而且沒有任何已知的轉發(fā)地址。
剩余60%內容,訂閱專欄后可繼續(xù)查看/也可單篇購買
本專欄價格永遠為19.9元! 不想當架構師的后端開發(fā)工程師不是好碼農! 此專欄一方面用于存放我的架構設計學習筆記, 另外我會在本專欄加入一系列最常問八股問題帖子,內容就是我根據自己的面試經歷和網上的面經,去篩選八股里面哪些是最常被問到的問題把它們整理出來,大家可以在面試前一兩個小時快速把這一系列最常問八股的帖子拿出來看看,臨時抱佛腳的效果應該很好