1. 程式人生 > >網路篇:朋友面試之TCP/IP,回去等通知吧

網路篇:朋友面試之TCP/IP,回去等通知吧

# 前言 最近和一同學聊天,他想換工作,然後去面了一家大廠。當時,他在簡歷上寫著精通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