網(wǎng)絡(luò)篇:朋友面試之TCP/IP,回去等通知吧
前言
最近和一同學(xué)聊天,他想換工作,然后去面了一家大廠。當時,他在簡歷上寫著精通TCP/IP,本著對TCP協(xié)議稍有了解,面試官也不會深問的想法,就寫了精通二字。沒想到,大意了
開場
朋友約的是十點半的面試,提前了十分鐘到,然后安靜地坐在沙發(fā)等待,順便回憶下之前看的資料。快到十點半時,一個高瘦,穿著格子衫的男子推開門而進,說了句“你好,我們來開始面試吧!”,朋友不失禮貌地笑著回了句“行”
面試官:看你簡歷說精通TCP和IP,那我們來討論下網(wǎng)絡(luò)模型和TCP、IP協(xié)議,講下你的理解先
朋友(怎么一上來就問TCP,不按套路出牌啊,不該問問java基礎(chǔ)嗎?不過常規(guī)題,我還行)
朋友:網(wǎng)絡(luò)模型一般分七層:應(yīng)用層、表示層、會話層、傳輸層、網(wǎng)絡(luò)層、數(shù)據(jù)鏈路層、物理層。應(yīng)用層的協(xié)議包括HTTP、FTP、SMTP,而TCP屬于傳輸層,IP協(xié)議則屬于網(wǎng)絡(luò)層
朋友:TCP/IP網(wǎng)絡(luò)模型層次由上到下,層層包裝,每一層都對應(yīng)不同的協(xié)議解析,我來畫個圖

面試官:看你畫的圖,TCP有自己的首部結(jié)構(gòu),這都有哪些字段,最好說說它們的作用
朋友(什么鬼!當我百度詞典,這怎么記得住?等等,昨天晚上好像看過,有印象)
朋友:繼續(xù)畫個圖,直觀點

朋友:TCP首部結(jié)構(gòu)先是16位的源端口號和目標端口號、接著是32位的序列號和確認號。再下面就是4bit的頭部長度和6個bit的保留位及6bit的標志位
朋友:16位的屬性則有窗口大小(控制發(fā)送窗口),檢驗和(校驗數(shù)據(jù)段是否未被修改)及緊急指針。最后是選項,其長度由頭部長度決定
朋友:詳細說下序列號,它是TCP報文段的一數(shù)字編號,為保證TCP可靠連接,每一個發(fā)送的數(shù)據(jù)段都要加上序列號。建立連接時,兩端都會隨機生成一個初始序列號。而確認號是和序列號配合使用的,應(yīng)答某次請求時,則返回一個確認號,它的值等于對方請求序列號加1
朋友:而6個標志位分別是,URG:這是條緊急信息,ACK:應(yīng)答消息,PSH:緩沖區(qū)尚未填滿,RST:重置連接,SYN:建立連接消息標志,F(xiàn)IN:連接關(guān)閉通知信息
朋友:窗口大小是接收端用來控制發(fā)送端的滑動窗口大小
面試官:那TCP和UDP有什么區(qū)別
朋友(松了一口氣)
朋友:1)連接方面:TCP面向連接。UDP是無連接的,發(fā)送數(shù)據(jù)之前不需要建立連接
朋友:2)安全方面:TCP提供可靠的服務(wù),保證傳送的數(shù)據(jù),無差錯,不丟失,不重復(fù),且按序到達。UDP則是盡最大努力交付,不保證可靠交付
朋友:3)傳輸效率:TCP傳輸效率相對較低,UDP傳輸效率高
面試官:剛才你說TCP是可靠的連接,它是怎么實現(xiàn)的
朋友:TCP的連接是基于三次握手,而斷開則是四次揮手
朋友:為了保障數(shù)據(jù)不丟失及錯誤(可靠性),它有報文校驗、ACK應(yīng)答、超時重傳(發(fā)送方)、失序數(shù)據(jù)重傳(接收方)、丟棄重復(fù)數(shù)據(jù)、流量控制(滑動窗口)和擁塞控制等機制
面試官:具體說一說三次握手和四次揮手機制
朋友(又是常規(guī)題,曬曬水啦)
朋友:TCP是可靠的雙向通道,所以需要三次握手和四次揮手,我來畫個圖
三次握手

四次揮手

朋友:提前搶答下,關(guān)閉連接時需要四次揮手,比建立時多一次,是因為被動關(guān)閉端或許還有數(shù)據(jù)沒被送出去,不能像握手時一樣,第二次握手既是發(fā)起握手也是響應(yīng)握手
面試官:如果沒有三次握手會有什么問題呢
朋友:如果只有兩次握手,client發(fā)連接請求后不會再ACK服務(wù)端的SYN
朋友:此時若客戶端因為自身原因判斷建立連接失敗,可能會重復(fù)建立TCP連接,而服務(wù)端卻會認為那些被client丟棄的TCP還是有效,會白白浪費資源
面試官:TIME_WAIT和CLOSE_WAIT的區(qū)別在哪

朋友:CLOSE_WAIT是被動關(guān)閉形成的;當對方close socket而發(fā)送FIN報文過來時,回應(yīng)ACK之后進入CLOSE_WAIT狀態(tài)。隨后檢查是否存在未傳輸數(shù)據(jù),如果沒有則發(fā)起第三次揮手,發(fā)送FIN報文給對方,進入LAST_ACK狀態(tài)并等待對方ACK報文到來
朋友:TIME_WAIT是主動關(guān)閉連接方式形成的;處于FIN_WAIT_2狀態(tài)時,收到對方FIN報文后進入TIME_WAIT狀態(tài);之后再等待兩個MSL(Maximum Segment Lifetime:報文最大生存時間)
面試官:TIME_WAIT的作用呢,還有為啥狀態(tài)時間要保持兩個MSL
朋友(這問得太深了吧,老哥。還好昨天偷偷補課了)
朋友:1)TIME_WAIT的作用是為了保證最后一次揮手的ACK報文能送達給對方,如果ACK丟失,對方會超時重傳FIN,主動關(guān)閉端會再次響應(yīng)ACK過去;如果沒有TIME_WAIT狀態(tài),直接關(guān)閉,對方重傳的FIN報文則被響應(yīng)一個RST報文,此RST會被動關(guān)閉端被解析成錯誤
朋友:2)存在兩個連接,第一個連接正常關(guān)閉,第二相同的連接緊接著建立;如果第一個連接的迷路報文到來,則會干擾第二連接,等待兩個MSL則可以讓上次連接的報文數(shù)據(jù)消逝在網(wǎng)絡(luò)
面試官:剛才你還有提到擁塞控制,TCP協(xié)議用什么方式去解決擁塞的
朋友:第一方式是慢啟動和擁塞避免
朋友:1)慢啟動,TCP發(fā)送端會維護一個擁塞窗口(congestionwindow),簡稱為cwnd。擁塞窗口初始為1個報文段,每經(jīng)過一次RTT(數(shù)據(jù)完全發(fā)送完到確認的時間),窗口大小翻倍(指數(shù)增長,只是前期慢)
朋友:2)擁塞避免,它思路是讓擁塞窗口cwnd緩慢增大,發(fā)送方的cwnd達到閥值ssthresh(初始值由系統(tǒng)決定的)之后,每經(jīng)過一個RTT就把擁塞窗口加一,而不是加倍(收到兩個或四個確認,都是cwnd+1),cwnd呈線性增加(加法增大)
朋友:(畫個圖好解析)

朋友:如果遇到網(wǎng)絡(luò)擁塞,擁塞窗口閥值ssthresh減半,cwnd設(shè)置為1,重新進入慢啟動階段
面試官:那擁塞控制還有其他什么方式呢
朋友:快重傳和快恢復(fù)
朋友:1)快重傳是當接收方收到了一個失序的報文,則立馬報告給發(fā)送方,趕緊重傳
朋友:假如接收方M1收到了,M2沒有收到,之后的M3、M4、M5又發(fā)送了,此時接收方一共連續(xù)給發(fā)送方反饋了3個M1確認報文。那么快重傳規(guī)定,發(fā)送方只要連續(xù)收到3個重復(fù)確認,立即重傳對方發(fā)來的M2(重復(fù)確認報文的后一個報文)

朋友:2)快恢復(fù)
朋友:當發(fā)送方連續(xù)收到三個重復(fù)確認,ssthresh減半;由于發(fā)送方可能認為網(wǎng)絡(luò)現(xiàn)在沒有擁塞,因此與慢啟動不同,把cwnd值設(shè)置為ssthresh減半之后的值,然后執(zhí)行擁塞避免算法,cwnd線性增大
朋友:(再來一圖)

面試官:知道滑動窗口不,客戶端和服務(wù)端控制滑動窗口的過程是怎樣的
朋友:接收端將自己可以接收的緩沖區(qū)大小放入TCP首部中的“窗口大小”字段,通過ACK報文來通知發(fā)送端,滑動窗口是接收端用來控制發(fā)送端發(fā)送數(shù)據(jù)的大小,從而達到流量控制
朋友:其實發(fā)送方的窗口上限,是取值擁塞窗口和滑動窗口兩者的最小值
面試官:那你知道滑動窗口和擁塞窗口有什么區(qū)別不
朋友:相同點都是控制丟包現(xiàn)象,實現(xiàn)機制都是讓發(fā)送方發(fā)得慢一點
朋友:不同點在于控制的對象不同
朋友:1)流量控制的對象是接收方,怕發(fā)送方發(fā)的太快,使得接收方來不及處理
朋友:2)擁塞控制的對象是網(wǎng)絡(luò),怕發(fā)送方發(fā)的太快,造成網(wǎng)絡(luò)擁塞,使得網(wǎng)絡(luò)來不及處理
面試官:TCP的粘包和拆包問題,你怎么看
朋友:程序需要發(fā)送的數(shù)據(jù)大小和TCP報文段能發(fā)送MSS(Maximum Segment Size,最大報文長度)是不一樣的
朋友:大于MSS時,而需要把程序數(shù)據(jù)拆分為多個TCP報文段,稱之為拆包;小于時,則會考慮合并多個程序數(shù)據(jù)為一個TCP報文段,則是粘包;其中MSS = TCP報文段長度-TCP首部長度
朋友:在IP協(xié)議層或者鏈路層、物理層,都存在拆包、粘包現(xiàn)象
面試官:那解決粘包和拆包的方法都有哪些?
朋友:1)在數(shù)據(jù)尾部增加特殊字符進行分割
朋友:2)將數(shù)據(jù)定為固定大小
朋友:3)將數(shù)據(jù)分為兩部分,一部分是頭部,一部分是內(nèi)容體;其中頭部結(jié)構(gòu)大小固定,且有一個字段聲明內(nèi)容體的大小
面試官:SYN Flood了解嗎
朋友:SYN Flood 偽造 SYN 報文向服務(wù)器發(fā)起連接,服務(wù)器在收到報文后用 SYN_ACK 應(yīng)答,此應(yīng)答發(fā)出去后,不會收到 ACK 報文,造成一個半連接
朋友:若攻擊者發(fā)送大量這樣的報文,會在被攻擊主機上出現(xiàn)大量的半連接,耗盡其資源,使正常的用戶無法訪問,直到半連接超時
面試官:對TCP的掌握挺不錯的,下面問下HTTP的知識。你知道一次HTTP請求,程序一般經(jīng)歷了哪幾個步驟?
朋友:1)解析域名 -> 2)發(fā)起TCP三次握手,建立連接 -> 3)基于TCP發(fā)起HTTP請求 -> 4)服務(wù)器響應(yīng)HTTP請求,并返回數(shù)據(jù) -> 5)客戶端解析返回數(shù)據(jù)

面試官:HTTP有哪幾種響應(yīng)狀態(tài)碼,列舉幾個你熟悉的
朋友:大概有以下幾種
200:表示成功正常請求
400:語義有誤,一般是請求格式不對
401:需求用戶驗證權(quán)限,一般是證書token沒通過認證
403:拒絕提供服務(wù)
404:資源不存在
500:服務(wù)器錯誤
503:服務(wù)器臨時維護,過載;可恢復(fù)
面試官:不錯,再考考你,session和cookie有什么區(qū)別
朋友:1)存儲位置不同,cookie是保存在客戶端的數(shù)據(jù);session的數(shù)據(jù)存放在服務(wù)器上
朋友:2)存儲容量不同,單個cookie保存的數(shù)據(jù)小,一個站點最多保存20個Cookie;對于session來說并沒有上限
朋友:3)存儲方式不同,cookie中只能保管ASCII字符串;session中能夠存儲任何類型的數(shù)據(jù)
朋友:4)隱私策略不同,cookie對客戶端是可見的;session存儲在服務(wù)器上,對客戶端是透明對
朋友:5)有效期上不同,cookie可以長期有效存在;session依賴于名為JSESSIONID的cookie,過期時間默認為-1,只需關(guān)閉窗口該session就會失效
朋友:6)跨域支持上不同,cookie支持跨域名訪問;session不支持跨域名訪問
面試官:不錯,那你了解什么是HTTP分塊傳送嗎
朋友:分塊傳送是HTTP的一種傳輸機制,允許服務(wù)端發(fā)送給客戶端的數(shù)據(jù)分成多個部分,該協(xié)議在HTTP/1.1提供
面試官:HTTP分塊傳送有什么好處
朋友:HTTP分塊傳輸編碼允許服務(wù)器為動態(tài)生成的內(nèi)容維持HTTP持久連接
朋友:分塊傳輸編碼允許服務(wù)器在最后發(fā)送消息頭字段。對于那些頭字段值在內(nèi)容被生成之前無法知道的情形非常重要,例如消息的內(nèi)容要使用散列進行簽名
朋友:HTTP服務(wù)器有時使用壓縮 (gzip或deflate)以縮短傳輸花費的時間。分塊傳輸編碼可以用來分隔壓縮對象的多個部分。在這種情況下,塊不是分別壓縮的,而是整個負載進行壓縮。分塊編碼有利于一邊進行壓縮一邊發(fā)送數(shù)據(jù)
面試官:HTTP的長連接你怎么理解
朋友:長連接是指客戶端和服務(wù)建立TCP連接后,它們之間的連接會持續(xù)存在,不會因為一次HTTP請求后關(guān)閉,后續(xù)的請求也是用這個連接
朋友:長連接可以省去TCP的建立和關(guān)閉操作,對于頻繁請求的客戶端適合使用長連接,但是注意惡意的長連接導(dǎo)致服務(wù)受損(建議內(nèi)部服務(wù)之間使用)
面試官:HTTP是安全的嗎?怎么做到安全的HTTP協(xié)議傳輸
朋友:并非安全,HTTP傳輸?shù)臄?shù)據(jù)都是明文的,容易被第三方截取;要做安全傳輸數(shù)據(jù),可以使用HTTP的升級版HTTPS協(xié)議
面試官:HTTPS和HTTP的區(qū)別,你是怎么理解的
朋友:1)http協(xié)議的連接是無狀態(tài)的,明文傳輸
朋友:2)HTTPS則是由SSL/TLS+HTTP協(xié)議構(gòu)建的有加密傳輸、身份認證的網(wǎng)絡(luò)協(xié)議
面試官:SSL/TLS是什么,HTTPS的安全性是怎樣實現(xiàn)的?
朋友:SSL(Secure Socket Layer 安全套接層)是基于HTTPS下的一個協(xié)議加密層,保障數(shù)據(jù)私密性。TLS(Transport Layer Security)則是升級版的SSL
朋友:https在http基礎(chǔ)加了一層安全認證及加密層TLS或者SSL,它首先會通過安全層進行ca證書認證,正確獲取服務(wù)端的公鑰
朋友:接著客戶端會通過公鑰和服務(wù)端確認一種加密算法,后面的數(shù)據(jù)則可以使用該加密算法對數(shù)據(jù)進行加密
參考資料
[1]
騰訊面試HTTP與TCP/IP20連問,你能答出多少: https://blog.csdn.net/weixin_48182198/article/details/107611341
[2]
什么是TCP/IP協(xié)議?: https://blog.csdn.net/bjweimengshu/article/details/79214572
[3]
太厲害了,終于有人能把TCP/IP協(xié)議講的明明白白了!: https://developer.51cto.com/art/201906/597961.htm
[4]
TCP的滑動窗口與擁塞窗口: https://blog.csdn.net/ligupeng7929/article/details/79597423
有道無術(shù),術(shù)可成;有術(shù)無道,止于術(shù)
歡迎大家關(guān)注Java之道公眾號
好文章,我在看??
