天下無難試之HTTP協議面試刁難大全

小編是一個非典型面試官,對於HTTP協議的第一個問題,一般人會問常用的狀態碼有哪些。小編不這麼問,小編的問題是HTTP的全稱是什麼,把英語給我說出來!

HTTP的全稱是什麼?

超文本傳輸協議,HyperText Transfer Protocol,這幾個單詞可別發走音了。所謂的超文本就是帶標記的文本,剛開始的時候是指HTML。現在HTTP協議傳輸的東西可不只是HTML了,什麼表單啊JSON啊XML啊文件啊都可以傳輸。

HTTP常用的狀態碼有哪些?

大部分同學都知道200、404、500、302錯誤。如果連404都不知道,是要被小編鄙視的。500錯誤為什麼這麼常見呢,因為在開發的時候老是出bug,一個大異常拋出來,瀏覽器就500了。500表示InternalServerError,也就是內部伺服器錯誤,如果不是bug,一般就是資料庫掛了。

再多問幾個狀態碼很多人就不知道了,因為大多數公司的軟體服務沒有走標準的HTTP狀態碼,很多狀態碼從來就不會出現,同學們自然也不會知道。

400 Bad Request 用於參數驗證,少了一個參數或者參數類型錯誤之類的。

502 Bad Gateway 後端服務掛掉或者壓力過大的時候, Nginx接到的請求無法及時傳遞給後端的服務進行處理,這個時候就會出現502錯誤。這個也非常常見,知乎豆瓣網站經常開小差的時候發生的錯誤就是這個。

304 Not Modified 極少人知道這個錯誤,因為大部分後端開發者的前端Javascript開發經驗都嚴重不足。當你用Chrome打開一個經常訪問的網站,看看Network傳輸的靜態資源就可以看到很多304狀態碼。它表示該資源被瀏覽器緩存了不需要重新請求伺服器。

401 Unauthorized 許可權不足,這個很好理解,就是資源存在但是不讓你訪問。

403 Forbidden 資源禁止訪問,如果你的IP列為黑名單了,就會發生這種錯誤。

其實還有很多狀態碼,小編也沒去好好研究了,因為實在不會在工作中用到。感興趣的請繼續閱讀維基百科

HTTP有哪些Method?

GET 不解釋,如果讀者不知道,建議別在IT圈混了。

POST 一般用於創建或者修改資源,在RESTFUL規範裡面POST只用來創建資源,並返回201 Created狀態碼錶示創建成功。不過大多數網站都不遵循嚴格的RESTFUL規範,POST拿來做修改資源的事也是非常常見的。

PUT 用於修改資源,比如修改資源的某個具體屬性。

DELETE 用於刪除資源。

HEAD 不常用,跟GET差不多,區別就是不返回Body內容,只返回HTTP頭信息。一般用於獲取資源的元信息,比如長度,修改時間等

OPTIONS 小編沒用過。

TRACE 小編沒用過。

CONNECT 小編沒用過。

後面三個感興趣的去閱讀一下RPC規範。小編大概看了一下,表示沒怎麼看懂,你行你上去挑戰一下。

HTTP協議格式是怎樣的?

HTTP的請求和響應的消息協議是一樣的,分為三個部分,起始行、消息頭和消息體。這三個部分以CRLF作為分隔符。最後一個消息頭有兩個CRLF,用來表示消息頭部的結束。

HTTP請求的起始行稱為請求行,形如GET /index.html HTTP/1.1

HTTP響應的起始行稱為狀態行,形如200 ok

消息頭部有很多鍵值對組成,多個鍵值對之間使用CRLF作為分隔符,也可以完全沒有鍵值對。形如Content-Encoding: gzip

消息體是一個字元串,字元串的長度是由消息頭部的Content-Length鍵指定的。如果沒有Content-Length欄位說明沒有消息體,譬如GET請求就是沒有消息體的,POST請求的消息體一般用來放置表單數據。GET請求的響應返回的頁面內容也是放在消息體裡面的。我們平時調用API返回的JSON內容都是放在消息體裡面的。

什麼是分塊傳送?

當瀏覽器向伺服器請求一個資源時,這個資源是一個動態資源,伺服器無法提前預知資源的大小,這個時候就可以使用分塊傳輸。

伺服器先生成一個chunk,發送這個chunk,再生成一個chunk,再發送一個chunk,直到全部資源傳送完成。

分塊傳送需要在請求頭增加一個特殊的鍵值對transfer-encoding: chunked,那麼消息體的內容便是分塊傳送的。

chunked傳輸格式如圖所示,由一段一段的分塊組合而成,每個塊由一個長度行和一個分塊體組成,最後一個分塊長度為0表示結束。

持久連接的機制是怎樣的?

HTTP早期版本中每個請求都會發起一個連接,一個網頁除了頁面的HTML之外還會有很多靜態資源以及諸多的API調用,如果每個請求都一個連接,勢必網頁的一次載入就會和伺服器創建多次連接,這是非常浪費伺服器資源的,同時也讓客戶端的訪問速度慢了不少。HTTP1.0之後引入了Keep-Alive持久連接,在HTTP1.1版本中成為默認選項。它使得HTTP的一個連接可以連續服務多個請求,有效節省了資源,增加了客戶端頁面的載入速度。

持久連接也不宜一直保持,畢竟每個連接都會佔用伺服器資源,如果打開網頁的人太多,那伺服器資源也會緊張,所以一般伺服器都會配置一個KeepAlive Timeout參數和KeepAlive Requests參數限制單個連接持續時長和最多服務的請求次數。

如果伺服器設置的timeout時長為0,就退化到非持久連接。非持久連接會在響應頭部增加一個頭信息Connection: Close通知客戶端在接受完當前響應後連接需要立即關閉。

同樣瀏覽器也不會因為伺服器將KeepAlive Timeout配置了無限長就不管不問一直持續保持連接。每個瀏覽器都有它自己的內置限制,具體限制瀏覽器廠商各有不同。

什麼叫Pipeline管線化?

HTTP1.0不支持管線化,同一個連接處理請求的順序是逐個應答模式,處理一個請求就需要耗費一個TTL,也就是客戶端到伺服器的往返時間,處理N個請求就是N個TTL時長。當頁面的請求非常多時,頁面載入速度就會非常緩慢。

從HTTP1.1開始要求伺服器支持管線化,可以同時將多個請求發送到伺服器,然後逐個讀取響應。這個管線化和Redis的管線化原理是一樣的,響應的順序必須和請求的順序保持一致。

如何理解HTTP協議的無狀態性?

所謂HTTP協議的無狀態性是指伺服器的協議層無需為不同的請求之間建立任何相關關係,它特指的是協議層的無狀態性。但是這並不代表建立在HTTP協議之上的應用程序就無法維持狀態。應用層可以通過會話Session來跟蹤用戶請求之間的相關性,伺服器會為每個會話對象綁定一個唯一的會話ID,瀏覽器可以將會話ID記錄在本地緩存LocalStorage或者Cookie,在後續的請求都帶上這個會話ID,伺服器就可以為每個請求找到相應的會話狀態。

閱讀相關文章,關注知乎專欄【碼洞】


推薦閱讀:

IPsec
BGP 協議配置
鮮為人知的HTTP協議頭欄位詳解大全

TAG:HTTP | 面試 | 網路協議 |