《面試官不講武德》對Java初級程序猿死命摩擦Http協議

《面試官不講武德》對Java初級程序猿死命摩擦Http協議

前言

我被Hr領進了一個小黑屋,讓我在這裏等面試官,過來一會,一位穿着拖鞋的中年男子走了進來,看着他絕頂聰明的髮際線,知道這肯定是位大佬,我心裏倍感到了壓力;

《面試官不講武德》對Java初級程序猿死命摩擦Http協議

面試官果然不是蓋的,剛坐下後就開始立即暴力輸出了


面試官:我看你簡歷上寫了熟悉Http協議,當我們使用瀏覽器訪問網址: https://silently9527.cn會發生什麼?

我:(這尼瑪就是怕被搞事情所以沒寫精通,這也被搞。會發生什麼,當然是展示出網頁啊,大腦飛速旋轉,脖子快斷的時候,終於想到面試官可能想要問什麼了)

我:英俊瀟灑的面試官,你好!

首先瀏覽器會去訪問DNS服務器,查詢到域名對應的ip地址是多少,然後瀏覽器再去訪問這個ip地址;如果還要往底層在說的話,就會涉及到tcp/ip的分層,我還是來畫張圖吧。

《面試官不講武德》對Java初級程序猿死命摩擦Http協議

服務器返回資源的過程也是類似的方式


面試官:你剛纔有談到tcp/ip的分層,能詳細說下嗎?

我:(還好前前大學女友沒把我當年上課的筆記給扔掉,剛好昨晚找回來溫習了一下,溫故而知新!只是筆記而已,大家別想歪了!)
插圖

我:TCP/IP協議族分爲4層:應用層、傳輸層、網絡層、數據鏈路層

  • 應用層:主要是與應用通信使用到的協議,比如:FTP、DNS、HTTP
  • 傳輸層:爲應用層提供在兩臺機器之間數據傳輸,有兩種協議:TCP、UDP
  • 網絡層:兩臺機器之間在傳輸的過程中會經過多個路由器有多條路線,網絡層主要是從中選擇一條路線
  • 數據鏈路層:用來處理連接網絡的硬件部分,比如說網卡、設備驅動等

面試官:在tcp/ip的分層裏面,當客戶端發起http請求到達服務端的過程中,數據包的封裝以及解包的過程是怎樣的?

《面試官不講武德》對Java初級程序猿死命摩擦Http協議

我:在這個分層中,每次網絡請求都會按照分層的順序與對方進行通信,發送端從應用層往下走,接收端從數據鏈路層往上走;以Http來舉例的話:

  1. 客戶端在應用層(Http協議)發起一個HTTP請求
  2. 在傳輸層(TCP協議)把從應用層收到的Http請求數據包分隔成小的數據包,並打好序
  3. 網絡層(IP協議)收到數據包後選擇發送路徑
  4. 服務器收到數據後按照順序往上發送,直到應用層收到數據

《面試官不講武德》對Java初級程序猿死命摩擦Http協議

在發送方每經過一層,就會被加上該層的首部信息,當接收方接受到數據後,在每一個層會去掉對應的首部信息


面試官:TCP如何保證數據可靠到達目的地?

我:TCP協議採用的三次握手策略

  • 第一次握手:建立連接時,客戶端發送 syn 包(syn=j)到服務器,並進入 SYN_SEND 狀態,等待服務器確認;
  • 第二次握手:服務器收到 syn 包,必須確認客戶的 SYN(ack=j+1),同時自己也發送一個 SYN 包(syn=k),即 SYN+ACK 包,此時服務器進入 SYN_RECV 狀態;
  • 第三次握手:客戶端收到服務器的 SYN+ACK 包,向服務器發送確認包 ACK(ack=k+1),此包發送完畢,客戶端和服務器進入 ESTABLISHED 狀態,完成三次握手。

《面試官不講武德》對Java初級程序猿死命摩擦Http協議

《面試官不講武德》對Java初級程序猿死命摩擦Http協議


面試官:爲什麼是三次握手,而不是兩次或者4次呢?

我:假如說是兩次握手,如果客戶端自己處理異常或者是服務器返回的ack消息丟失,那麼客服端會認爲連接建立失敗,再次重新發送請求建立連接,但是服務端卻無感知,以爲連接以及正常建立,導致服務器建立無用的連接,浪費資源

假如四次握手,如果三次已經足夠,那就不需要四次了。如果四次的話,最後一個ACK丟失,那麼又會出現兩次握手的問題。


面試官:竟然都到說了三次握手,那就說說四次揮手吧?

《面試官不講武德》對Java初級程序猿死命摩擦Http協議

我:

  • 客戶端向服務器發送FIN希望斷開連接請求。
  • 服務器向客戶端發送ACK,表示同意釋放連接。
  • 服務器向客戶端發送一個FIN表示希望斷開連接。
  • 客戶端向服務器返回一個ACK表示同意釋放連接。

《面試官不講武德》對Java初級程序猿死命摩擦Http協議


面試官:爲什麼斷開連接需要四次而不是三次呢?

我:因爲當服務器收到客戶端斷開連接的請求後,服務器不能立即斷開連接,因爲可能服務器端還有數據未發送完成,所以只能回覆一個ACK表示我已收到消息;等服務器端數據發送完成之後再發送一個FIN希望端開連接的消息,客戶端回覆ACK之後,就可以安全斷開了


面試官:爲什麼說Http協議無狀態協議?怎麼解決Http協議無狀態?

《面試官不講武德》對Java初級程序猿死命摩擦Http協議

我:本身HTTP協議是不保存狀態的,自身不對請求和響應直接的通信狀態進行保存,所以是無狀態的協議。因爲在有些場景下我們需要保存用戶的登錄信息,所以引入了cookie來管理狀態。客戶端第一次請求服務器的時候,服務器會生成cookie添加在響應頭裏面,以後客戶端的每次請求都會帶上這個cookie信息。

《面試官不講武德》對Java初級程序猿死命摩擦Http協議


面試官:Cookie與Session有什麼區別?

我:

  • Cookie是有服務器生成,寫入到請求的響應頭中,瀏覽器會保存;服務器通過Set-Cookie字段向客戶端設置Cookie,屬性:
    1. Name=value 設置cookie的名字和值
    2. expires 設置Cookie的有效期
    3. domain=域名 表示只能在哪個域名下生效
    4. secure表示只能在Https的通信時才發送cookie
    5. HttpOnly 表示不能被javascript訪問
  • Session也是服務器生成的,表示服務器中的一片內存,每個客服端對應一個Session,客戶端之間的Session相互獨立;每次客戶端發起請求,都會帶上Cookie,Cookie裏面一般都會有一個JSESSIONID,服務器就是通過這個JESSIONID來找到客戶端對應Session,所以一般用戶的登錄信息都會存放在Session;這樣也解決了Http協議無狀態的問題

面試官:Http協議中有那些請求方式?如何選擇使用什麼方法?

我:

  • GET : 獲取資源; 所以查詢操作一般用GET
  • POST: 傳輸實體主體, 創建更新操作用POST
  • PUT: 傳輸文件
  • HEAD: 獲取報文首部,如果想要查詢某個請求的頭信息可以用這個方法
  • DELETE: 刪除資源,所以刪除操作用DELETE
  • OPTIONS: 詢問服務器支持哪些方法,響應頭中返回 Allow: GET,POST,HEAD
  • TRACE: 追蹤路徑;在請求頭中在Max-Forwards字段設置數字,每經過一個服務器該數字就減一,當到0的時候就直接返回,一般通過該方法檢查請求發送出去是否被篡改

面試官:Http如何實現持久連接的呢?

《面試官不講武德》對Java初級程序猿死命摩擦Http協議

我:(毛線啊,我只是個來面試Java的初級程序員,幹嘛要反覆拿Http來摩擦我呢?!不過沒事,我皮的很,這道題我又會)
我:在HTTP協議的早期,每進行一次HTTP通信就要斷開一次tcp連接,當時傳輸的內容少還能接受,現在每個網頁一般的會包含大量的圖片,每次請求都會造成TCP連接的連接和斷開,增加通信的開銷。

《面試官不講武德》對Java初級程序猿死命摩擦Http協議

爲了解決這個問題所以想出了持久連接的方法,也叫做keep-alive,只要一端沒有提出斷開連接就會一直保持TCP連接的狀態。持久化連接使的客戶端可以同時併發發送多個請求,不用一個接着一個的等待響應。


面試官:大文件的斷點續傳是如何實現的呢?

《面試官不講武德》對Java初級程序猿死命摩擦Http協議

我:HTTP請求頭有個Range字段;我們下載文件的時候如果遇到網絡中斷,如果重頭開始下載會浪費時間,所以我們可以從上一次中斷處繼續開始下載;具體的操作:

Range: bytes=5001-10000

或者指定5001以後的所有數據

Range: bytes=5001-

響應返回的狀態碼是206


面試官:剛纔你有提到狀態碼,那常見Http協議狀態碼有哪些?

我:(面試官我簡歷上忘記寫了,我曾經是學霸,記憶力好,背書沒輸過)

《面試官不講武德》對Java初級程序猿死命摩擦Http協議

我:HTTP的狀態碼主要分爲了四類:

  • 2xx: 成功狀態碼,表示請求正常處理完畢
  • 3xx: 重定向狀態碼,表示需要附加操作才能完成成請求
  • 4xx: 客戶端錯誤狀態碼
  • 5xx: 服務器錯誤狀態碼

常見的狀態碼有: 200(請求正常處理完成)、204(請求處理成功,但是沒有資源返回)、206(表示客戶端進行了範圍請求,響應報文中包含了Content-Range)、301(永久性重定向,請求的資源以及被分配到了新的地址)、302(臨時重定向,希望用戶並且請求新地址)、400(客戶端請求報文出現錯誤,通常是參數錯誤)、401(客戶端未認證錯誤)、403(沒有權限訪問該資源)、404(未找到請求的資源)、405(不支持該請求方法,如果服務器支持GET,客戶端用POST請求就會出現這個錯誤碼)、500(服務器異常)、503(服務器不能提供服務)

我:(這我都能記住,是不是的給我點個贊)(已瘋狂暗示兄弟們點贊,不要白嫖哦)


面試官:HTTP報文由哪些部分組成?

《面試官不講武德》對Java初級程序猿死命摩擦Http協議

我:報文的類型分爲了請求報文和響應報文兩種;

  • 請求報文包含三部分:

    1. 請求行:包含請求方法、URI、HTTP版本信息
    2. 請求首部字段
    3. 請求內容實體
  • 響應報文包含三部分:
    1. 狀態行:包含HTTP版本、狀態碼、狀態碼的原因短語
    2. 響應首部字段
    3. 響應內容實體

面試官:Http有哪些問題,什麼是https?

我:Http的問題

  • 通信使用明文不加密,內容可能被竊聽
  • 不驗證通信方身份,可能遭到僞裝
  • 無法驗證報文完整性,可能被篡改
    HTTPS就是HTTP加上SSL加密處理(一般是SSL安全通信線路)+認證+完整性保護

面試官:HTTPS是如何保證數據安全的?

《面試官不講武德》對Java初級程序猿死命摩擦Http協議

我:首先需要說到兩種加密機制

  • 對稱加密:客戶端和服務器都使用了同一個密鑰加密,效率較高
  • 非對稱加密:分爲了公開密鑰和私有密鑰,公開密鑰可以在網絡上傳輸,使用公開密鑰加密後的內容只有私有密鑰才能解密,效率較低

由於這兩個加密的特別,HTTPS採用的時候混合加密機制,在交換密鑰的階段使用的是非對稱加密,在建立通信交換報文階段採用的是對稱加密

以訪問 https://silently9527.cn 舉例

  1. 瀏覽器向服務器發起請求,服務器在接收到請求之後,返回證書和密鑰
  2. 瀏覽器向第三方證書機構驗證證書是否合法,如果不合法瀏覽器將會彈出警告頁面,讓用戶選擇是否繼續訪問
  3. 如果證書合法瀏覽器生成隨機串,使用公鑰加密發送給服務器,服務器使用私鑰解密出隨機串,服務器使用隨機串加密內容返回給客戶端
  4. 之後客戶端和服務器端都將通過隨機串進行對稱加密

《面試官不講武德》對Java初級程序猿死命摩擦Http協議


面試官:爲什麼需要證書認證機構,不要https就不安全了嗎?

我:雖然https是可以加密的,但是因爲請求還是可以被攔截,如何讓客戶端知道返回給自己的公鑰是真實服務器給的而不是***者給的;這就需要驗證證書的合法性,所以需要引入第三方認證機構。通常https的證書需要到第三方機構去申請購買,如果是我們自己生成的https證書瀏覽器驗證不過會彈出警告。


面試官:那瀏覽器是如何保證證書驗證的過程是安全的呢?

《面試官不講武德》對Java初級程序猿死命摩擦Http協議
我:瀏覽器在向證書認證中心驗證證書的過程使用的也是非對稱加密,這裏想要讓公鑰能夠安全的轉交給客戶端,是非常困難的,所以瀏覽器的開發商通常會在瀏覽器內部植入常用認證機構的公開密鑰


面試官:http相關的協議掌握的還可以,我們繼續聊聊Java.....

能撐到現在,你自己都忍不住自己給自己點個讚了!(再次暗示點贊)


寫到最後(點關注,不迷路)

本篇面試故事純屬虛構,請大家不要當真,玩笑歸玩笑,莫拿面試開玩笑。

文中或許會存在或多或少的不足、錯誤之處,有建議或者意見也非常歡迎大家在評論交流。

最後,白嫖不好,創作不易,希望朋友們可以點贊評論關注三連,因爲這些就是我分享的全部動力來源

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章