網路篇:朋友面試之TCP/IP,回去等通知吧
阿新 • • 發佈:2020-11-29
# 前言
最近和一同學聊天,他想換工作,然後去面了一家大廠。當時,他在簡歷上寫著精通TCP/IP,本著對TCP協議稍有了解,面試官也不會深問的想法,就寫了精通二字。沒想到,大意了
**關注公眾號,一起交流,微信搜一搜: 潛行前行**
---
# 開場
朋友約的是十點半的面試,提前了十分鐘到,然後安靜地坐在沙發等待,順便回憶下之前看的資料。快到十點半時,一個高瘦,穿著格子衫的男子推開門而進,說了句“你好,我們來開始面試吧!”,朋友不失禮貌地笑著回了句“行”
![](https://img-blog.csdnimg.cn/img_convert/c8c85bc46effc8ae573178c841eb7bdd.png)
### 面試官:看你簡歷說精通TCP和IP,那我們來討論下網路模型和TCP、IP協議,講下你的理解先
- 朋友(怎麼一上來就問TCP,不按套路出牌啊,不該問問java基礎嗎?不過常規題,我還行)
![](https://img-blog.csdnimg.cn/img_convert/23f43787215be08ef2be25a8f0f8041e.png)
- 朋友:網路模型一般分七層:應用層、表示層、會話層、傳輸層、網路層、資料鏈路層、物理層。應用層的協議包括HTTP、FTP、SMTP,而TCP屬於傳輸層,IP協議則屬於網路層
- 朋友:TCP/IP網路模型層次由上到下,層層包裝,每一層都對應不同的協議解析,我來畫個圖
![](https://img-blog.csdnimg.cn/img_convert/73f0ace294dd14cd4a647c82ac428ec8.png)
### 面試官:看你畫的圖,TCP有自己的首部結構,這都有哪些欄位,最好說說它們的作用
- 朋友(什麼鬼!當我百度詞典,這怎麼記得住?等等,昨天晚上好像看過,有印象)
![](https://img-blog.csdnimg.cn/img_convert/f459af980d9d408d00d4e88130deeca0.png)
- 朋友:繼續畫個圖,直觀點
![](https://img-blog.csdnimg.cn/img_convert/abba85798111dd4aed3250dfa6804ee2.png)
- 朋友:TCP首部結構先是16位的源埠號和目標埠號、接著是32位的序列號和確認號。再下面就是4bit的頭部長度和6個bit的保留位及6bit的標誌位
- 朋友:16位的屬性則有視窗大小(控制傳送視窗),檢驗和(校驗資料段是否未被修改)及緊急指標。最後是選項,其長度由頭部長度決定
- 朋友:詳細說下序列號,它是TCP報文段的一數字編號,為保證TCP可靠連線,每一個傳送的資料段都要加上序列號。建立連線時,兩端都會隨機生成一個初始序列號。而確認號而是和序列號配合使用的,應答某次請求時,則返回一個確認號,它的值等於對方請求序列號加1
- 朋友:而6個標誌位分別是,URG:這是條緊急資訊,ACK:應答訊息,PSH:緩衝區尚未填滿,RST:重置連線,SYN:建立連線訊息標誌,FIN:連線關閉通知資訊
- 朋友:視窗大小是接收端用來控制傳送端的滑動視窗大小
### 面試官:那TCP和UDP有什麼區別
![](https://img-blog.csdnimg.cn/img_convert/9a9b014373d3c5013ea55ee8f489874c.png)
- 朋友(鬆了一口氣)
- 朋友:1)連線方面:TCP面向連線。UDP是無連線的,傳送資料之前不需要建立連線
- 朋友:2)安全方面:TCP提供可靠的服務,保證傳送的資料,無差錯,不丟失,不重複,且按序到達。UDP則是盡最大努力交付,不保證可靠交付
- 朋友:3)傳輸效率:TCP傳輸效率相對較低,UDP傳輸效率高
### 面試官:剛才你說TCP是可靠的連線,它是怎麼實現的
![](https://img-blog.csdnimg.cn/img_convert/ecdcb68359c8c54e68a1cf67b750ab1b.gif)
- 朋友:TCP的連線是基於三次握手,而斷開則是四次揮手
- 朋友:為了保障資料不丟失及錯誤(可靠性),它有報文校驗、ACK應答、超時重傳(傳送方)、失序資料重傳(接收方)、丟棄重複資料、流量控制(滑動視窗)和擁塞控制等機制
### 面試官:具體說一說三次握手和四次揮手機制
- 朋友(又是常規題,晒晒水啦)
- 朋友:TCP是可靠的雙向通道,所以需要三次握手和四次揮手,我來畫個圖
- 三次握手
![](https://img-blog.csdnimg.cn/img_convert/8ac917b801b7d3c81bc293d1ae9449de.png)
- 四次揮手
![](https://img-blog.csdnimg.cn/img_convert/3803f2df4089791d4f745f1c2f3960c3.png)
- 朋友:提前搶答下,關閉連線時需要四次揮手,比建立時多一次,是因為被動關閉端或許還有資料沒被送出去,不能像握手時一樣,第二次握手既是發起握手也是響應握手
### 面試官:如果沒有三次握手會有什麼問題呢
- 朋友:如果只有兩次握手,client發連線請求後不會再ACK服務端的SYN
- 朋友:此時若客戶端因為自身原因判斷建立連線失敗,可能會重複建立TCP連線,而服務端卻會認為那些被client丟棄的TCP還是有效,會白白浪費資源
### 面試官:TIME_WAIT和CLOSE_WAIT的區別在哪
![](https://img-blog.csdnimg.cn/img_convert/f24a1b06860b1fc98c531bfe096d67be.png)
![](https://img-blog.csdnimg.cn/img_convert/3803f2df4089791d4f745f1c2f3960c3.png)
- 朋友:CLOSE_WAIT是被動關閉形成的;當對方close socket而傳送FIN報文過來時,迴應ACK之後進入CLOSE_WAIT狀態。隨後檢查是否存在未傳輸資料,如果沒有則發起第三次揮手,傳送FIN報文給對方,進入LAST_ACK狀態並等待對方ACK報文到來
- 朋友:TIME_WAIT是主動關閉連線方式形成的;處於FIN_WAIT_2狀態時,收到對方FIN報文後進入TIME_WAIT狀態;之後再等待兩個MSL(Maximum Segment Lifetime:報文最大生存時間)
### 面試官:TIME_WAIT的作用呢,還有為啥狀態時間要保持兩個MSL
![](https://img-blog.csdnimg.cn/img_convert/c8e7d0c51294c23717fb3777d888cd2d.gif)
- 朋友(這問得太深了吧,老哥。還好昨天偷偷補課了)
- 朋友:1)TIME_WAIT的作用是為了保證最後一次揮手的ACK報文能送達給對方,如果ACK丟失,對方會超時重傳FIN,主動關閉端會再次響應ACK過去;如果沒有TIME_WAIT狀態,直接關閉,對方重傳的FIN報文則被響應一個RST報文,此RST會被動關閉端被解析成錯誤
- 朋友:2)存在兩個連線,第一個連線正常關閉,第二相同的連線緊接著建立;如果第一個連線的迷路報文到來,則會干擾第二連線,等待兩個MSL則可以讓上次連線的報文資料消逝在網路後
### 面試官:剛才你還有提到擁塞控制,TCP協議用什麼方式去解決擁塞的
- 朋友:**第一方式是慢啟動和擁塞避免**
- 朋友:1)慢啟動,TCP傳送端會維護一個擁塞視窗(congestionwindow),簡稱為cwnd。擁塞視窗初始為1個報文段,每經過一次RTT(資料完全傳送完到確認的時間),視窗大小翻倍(指數增長,只是前期慢)
- 朋友:2)擁塞避免,它思路是讓擁塞視窗cwnd緩慢增大,傳送方的cwnd達到閥值ssthresh(初始值由系統決定的)之後,每經過一個RTT就把擁塞視窗加一,而不是加倍(收到兩個或四個確認,都是cwnd+1),cwnd呈線性增加(加法增大)
- 朋友:(畫個圖好解析)
![](https://img-blog.csdnimg.cn/img_convert/ea262d615dc645c0bd721d1ae701424e.png)
- 朋友:如果遇到網路擁塞,擁塞視窗閥值ssthresh減半,cwnd設定為1,重新進入慢啟動階段
### 面試官:那擁塞控制還有其他什麼方式呢
![](https://img-blog.csdnimg.cn/img_convert/7a7643f53d09357bf9d9e393379ab312.gif)
- 朋友:**快重傳和快恢復**
- 朋友:1)快重傳是當接收方收到了一個失序的報文,則立馬報告給傳送方,趕緊重傳
- 朋友:假如接收方M1收到了,M2沒有收到,之後的M3、M4、M5又傳送了,此時接收方一共連續給傳送方反饋了3個M1確認報文。那麼快重傳規定,傳送方只要連續收到3個重複確認,立即重傳對方發來的M2(重複確認報文的後一個報文)
![](https://img-blog.csdnimg.cn/img_convert/3ebf0ed25f3f407e3fc96c80ca098e3d.png)
- 朋友:2)快恢復
- 朋友:當傳送方連續收到三個重複確認,ssthresh減半;由於傳送方可能認為網路現在沒有擁塞,因此與慢啟動不同,把cwnd值設定為ssthresh減半之後的值,然後執行擁塞避免演算法,cwnd線性增大
- 朋友:(再來一圖)
![](https://img-blog.csdnimg.cn/img_convert/f56c1d1ee79c69b14f7bc2c2d3fb2405.png)
### 面試官:知道滑動視窗不,客戶端和服務端控制滑動視窗的過程是怎樣的
![](https://img-blog.csdnimg.cn/img_convert/aeafc263f5db7859e66f6401cfa2c746.png)
- 朋友:接收端將自己可以接收的緩衝區大小放入TCP首部中的“視窗大小”欄位,通過ACK報文來通知傳送端,滑動視窗是接收端用來控制傳送端傳送資料的大小,從而達到流量控制
- 朋友:其實發送方的視窗上限,是取值擁塞視窗和滑動視窗兩者的最小值
### 面試官:那你知道滑動視窗和擁塞視窗有什麼區別不
![](https://img-blog.csdnimg.cn/img_convert/69b556a45967a6e743298eca90bb111b.png)
- 朋友:相同點都是控制丟包現象,實現機制都是讓傳送方發得慢一點
- 朋友:不同點在於控制的物件不同
- 朋友:1)流量控制的物件是接收方,怕傳送方發的太快,使得接收方來不及處理
- 朋友:2)擁塞控制的物件是網路,怕傳送方發的太快,造成網路擁塞,使得網路來不及處理
### 面試官:TCP的粘包和拆包問題,你怎麼看
- 朋友:程式需要傳送的資料大小和TCP報文段能傳送MSS(Maximum Segment Size,最大報文長度)是不一樣的
- 朋友:大於MSS時,而需要把程式資料拆分為多個TCP報文段,稱之為拆包;小於時,則會考慮合併多個程式資料為一個TCP報文段,則是粘包;其中MSS = TCP報文段長度-TCP首部長度
- 朋友:在IP協議層或者鏈路層、物理層,都存在拆包、粘包現象
### 面試官:那解決粘包和拆包的方法都有哪些?
![](https://img-blog.csdnimg.cn/img_convert/e19700031b30d10d6c180174e6720a82.png)
- 朋友:1)在資料尾部增加特殊字元進行分割
- 朋友:2)將資料定為固定大小
- 朋友:3)將資料分為兩部分,一部分是頭部,一部分是內容體;其中頭部結構大小固定,且有一個欄位宣告內容體的大小
### 面試官:SYN Flood瞭解嗎
![](https://img-blog.csdnimg.cn/img_convert/cf5fb874f44ea8f9051893c1057150f4.png)
- 朋友:SYN Flood 偽造 SYN 報文向伺服器發起連線,伺服器在收到報文後用 SYN_ACK 應答,此應答發出去後,不會收到 ACK 報文,造成一個半連線
- 朋友:若攻擊者傳送大量這樣的報文,會在被攻擊主機上出現大量的半連線,耗盡其資源,使正常的使用者無法訪問,直到半連線超時
### 面試官:對TCP的掌握挺不錯的,下面問下HTTP的知識。你知道一次HTTP請求,程式一般經歷了哪幾個步驟?
- 朋友:1)解析域名 -> 2)發起TCP三次握手,建立連線 -> 3)基於TCP發起HTTP請求 -> 4)伺服器響應HTTP請求,並返回資料 -> 5)客戶端解析返回資料
![](https://img-blog.csdnimg.cn/img_convert/f165e3fae41e237a704e0642701c7b08.png)
### 面試官:HTTP有哪幾種響應狀態碼,列舉幾個你熟悉的
- 朋友:大概有以下幾種
* 200:表示成功正常請求
* 400:語義有誤,一般是請求格式不對
* 401:需求使用者驗證許可權,一般是證書token沒通過認證
* 403:拒絕提供服務
* 404:資源不存在
* 500:伺服器錯誤
* 503:伺服器臨時維護,過載;可恢復
### 面試官:不錯,再考考你,session和cookie有什麼區別
![](https://img-blog.csdnimg.cn/img_convert/59e5dde74a120d836b243cce62b51b38.png)
- 朋友:1)儲存位置不同,cookie是儲存在客戶端的資料;session的資料存放在伺服器上
- 朋友:2)儲存容量不同,單個cookie儲存的資料小,一個站點最多儲存20個Cookie;對於session來說並沒有上限
- 朋友:3)儲存方式不同,cookie中只能保管ASCII字串;session中能夠儲存任何型別的資料
- 朋友:4)隱私策略不同,cookie對客戶端是可見的;session儲存在伺服器上,對客戶端是透明對
- 朋友:5)有效期上不同,cookie可以長期有效存在;session依賴於名為JSESSIONID的cookie,過期時間預設為-1,只需關閉視窗該session就會失效
- 朋友:6)跨域支援上不同,cookie支援跨域名訪問;session不支援跨域名訪問
### 面試官:不錯,那你瞭解什麼是HTTP分塊傳送嗎
- 朋友:分塊傳送是HTTP的一種傳輸機制,允許服務端傳送給客戶端的資料分成多個部分,該協議在HTTP/1.1提供
### 面試官:HTTP分塊傳送有什麼好處
![](https://img-blog.csdnimg.cn/img_convert/46889f71b8ea173fa763a6f9dec727db.png)
- 朋友:HTTP分塊傳輸編碼允許伺服器為動態生成的內容維持HTTP持久連線
- 朋友:分塊傳輸編碼允許伺服器在最後傳送訊息頭欄位。對於那些頭欄位值在內容被生成之前無法知道的情形非常重要,例如訊息的內容要使用雜湊進行簽名
- 朋友:HTTP伺服器有時使用壓縮 (gzip或deflate)以縮短傳輸花費的時間。分塊傳輸編碼可以用來分隔壓縮物件的多個部分。在這種情況下,塊不是分別壓縮的,而是整個負載進行壓縮。分塊編碼有利於一邊進行壓縮一邊傳送資料
![](https://img-blog.csdnimg.cn/img_convert/8357d39a6b1ac0199cb2b7ce565c436a.gif)
### 面試官:HTTP的長連線你怎麼理解
- 朋友:長連線是指客戶端和服務建立TCP連線後,它們之間的連線會持續存在,不會因為一次HTTP請求後關閉,後續的請求也是用這個連線
- 朋友:長連線可以省去TCP的建立和關閉操作,對於頻繁請求的客戶端適合使用長連線,但是注意惡意的長連線導致服務受損(建議內部服務之間使用)
### 面試官:HTTP是安全的嗎?怎麼做到安全的HTTP協議傳輸
![](https://img-blog.csdnimg.cn/img_convert/606dc4808bf8946232143d3b580fb8df.png)
- 朋友:並非安全,HTTP傳輸的資料都是明文的,容易被第三方擷取;要做安全傳輸資料,可以使用HTTP的升級版HTTPS協議
### 面試官:HTTPS和HTTP的區別,你是怎麼理解的
- 朋友:1)http協議的連線是無狀態的,明文傳輸
- 朋友:2)HTTPS則是由SSL/TLS+HTTP協議構建的有加密傳輸、身份認證的網路協議
### 面試官:SSL/TLS是什麼,HTTPS的安全性是怎樣實現的?
- 朋友:SSL(Secure Socket Layer 安全套接層)是基於HTTPS下的一個協議加密層,保障資料私密性。TLS(Transport Layer Security)則是升級版的SSL
- 朋友:https在http基礎加了一層安全認證及加密層TLS或者SSL,它首先會通過安全層進行ca證書認證,正確獲取服務端的公鑰
- 朋友:接著客戶端會通過公鑰和服務端確認一種加密演算法,後面的資料則可以使用該加密演算法對資料進行加密
### 面試官:你能詳細說下TLS/SSL的認證過程不...(此時面試官放在桌面的手機震動了起來,他下意識看了看手機,停頓下)
### 朋友面試暫時告一段落(下回繼續)
![](https://img-blog.csdnimg.cn/img_convert/49410aa0a2969759ed69055b8517cadb.png)
歡迎指正文中錯誤
---
# 參考文章
- [騰訊面試HTTP與TCP/IP20連問,你能答出多少](https://blog.csdn.net/weixin_48182198/article/details/107611341)
- [什麼是TCP/IP協議?](https://blog.csdn.net/bjweimengshu/article/details/79214572)
- [太厲害了,終於有人能把TCP/IP協議講的明明白白了!](https://developer.51cto.com/art/201906/597961.htm)
- [TCP的滑動視窗與擁塞視窗](https://blog.csdn.net/ligupeng7929/article/details/7