超詳細的HTTP面試題

Hello,我是 Alex 007,爲啥是007呢?因爲叫 Alex 的人太多了,再加上每天007的生活,Alex 007就誕生了。

01.HTTP是什麼?(初級)

  1. HTTP協議是Hyper Text Transfer Protocol(超文本傳輸協議)的縮寫,是用於從萬維網(WWW:World Wide Web )服務器傳輸超文本到本地瀏覽器的傳送協議。

  2. HTTP協議是一個基於TCP/IP通信協議來傳遞數據(HTML 文件, 圖片文件, 查詢結果等)。

  3. HTTP協議是一個屬於應用層的面向對象的協議。

  4. HTTP協議工作於客戶端和服務端架構上,瀏覽器作爲HTTP客戶端通過URL向HTTP服務器發送請求,服務器根據接收到的請求後,向客戶端發送響應信息。

特點:

  • 基於TCP/IP

雙方建立通信的順序,以及Web頁面顯示需要 處理的步驟,等等。

像這樣把與互聯網相關聯的協議集合起來總稱爲 TCP/IP。

而HTTP協議是基於TCP/IP協議之上的應用層協議。

  • 基於請求-響應模式

HTTP協議規定,請求從客戶端發出,最後服務器響應該請求並返回。

  • 無狀態保存

HTTP是一種無狀態協議。HTTP協議不對請求和響應之間的通信狀態進行保存,不做持久化處理。這是爲了更快地處理大量事務,確保協議的可伸縮性,而特意把HTTP協議設計成 如此簡單的。


02.HTTP請求報文與響應報文格式?(初級)

請求報文包含三部分:

  1. 請求首行(包括請求方法、URL、HTTP版本)

  2. 請求首部字段

  3. 請求內容實體

響應報文包含三部分:

  1. 響應首行(包括狀態碼、狀態信息、HTTP版本)

  2. 響應首部字段

  3. 響應內容實體


03.HTTP常見首部字段有哪些?(初級)

  1. 通用首部字段(請求報文與響應報文都會使用的首部字段)
字段 字段描述
Date 創建報文時間
Connection 連接的管理
Cache-Control 緩存的控制
Transfer-Encoding 報文主體的傳輸編碼方式
  1. 請求首部字段(請求報文會使用的首部字段)
字段 字段描述
Host 請求資源所在服務器
Accept 可處理的媒體類型
Accept-Charset 可接收的字符集
Accept-Encoding 可接受的內容編碼
Accept-Language 可接受的自然語言
  1. 響應首部字段(響應報文會使用的首部字段)
字段 字段描述
Accept-Ranges 可接受的字節範圍
Location 令客戶端重新定向到的URI
Server HTTP服務器的安裝信息
  1. 實體首部字段(請求報文與響應實體部分使用的首部字段)
字段 字段描述
Allow 資源可支持的HTTP方法
Content-Type 實體主類的類型
Content-Encoding 實體主體適用的編碼方式
Content-Language 實體主體的自然語言
Content-Length 實體主體的的字節數
Content-Range 實體主體的位置範圍,一般用於發出部分請求時使用

04.HTTP與HTTPS的區別?(初級)

  • HTTP協議傳輸的數據都是明文、未加密的,因此使用HTTP協議傳輸隱私信息非常不安全。

  • HTTPS協議是由HTTP+SSL構建的網絡協議,可進行加密傳輸、身份認證,要比HTTP協議安全。

不同點 HTTP HTTPS
安全證書 不需要 需要到ca申請證書(免費/付費可選)
是否加密 不加密,信息是明文傳輸 具有安全性的ssl加密傳輸協議
驗證數據 不驗證數據,可能遭到僞裝
無法驗證報文完整性,可能被篡改
驗證數據且對數據完整性保護
連接方式 無狀態連接 HTTPS協議是由HTTP+SSL協議構建的
可進行加密傳輸、身份認證的網絡協議,比HTTP協議安全。
默認端口 80 443
安全性 不安全 安全

05.列舉HTTP請求中常見的請求方式(初級)

方法名稱 定義
GET 向特定的路徑資源發出請求
POST 向指定路徑資源提交數據進行處理請求(一般用於提交表單或者上傳文件)
PUT 從客戶端向服務器傳送數據更新指定的資源
PATCH 從客戶端向服務器傳送數據更新部分指定的資源
DELETE 請求服務器刪除指定的資源
HEAD 向服務器索要與GET一樣的請求,但是不返回返回體。
這個方法可以在不必傳輸整個響應內容的情況下,獲取包含在響應消息頭中的元信息
OPTIONS 查詢相應URL支持的HTTP方法
TRACE 返回服務器收到的請求,主要用於測試或診斷
CONNECT HTTP/1.1協議中預留給能夠將連接改爲管道方式的代理服務

06.GET方法與POST方法的區別?(初級)

不同點 GET POST
本質 產生1個TCP數據包,只跑1次
瀏覽器會把HTTP header和data一併發送出去,服務器響應200(返回數據)
產生2個TCP數據包,來回各1次(共2次)
瀏覽器先發送header,服務器響應100 continue,瀏覽器再發送data,服務器響應200 ok(返回數據)
請求形式 參數通過URL傳遞 把數據放在Request的body中
安全性 因爲URL是可見的,可能會泄露私密信息,
如賬號密碼等,所以不安全
數據在request中,用戶不可見,較get安全性較高
傳輸數據量 傳輸的數據量小,因爲受URL長度最多是1024字節,但效率較高; 可以傳輸大量數據,所以上傳文件時只能用Post方式;
支持編碼 只能進行url編碼 支持多種編碼
字符格式 只能支持ASCII字符,向服務器傳的中文字符可能會亂碼。 支持標準字符集,可以正確傳遞中文字符。
瀏覽器處理 請求會被瀏覽器主動cache,請求參數會被完整保留在瀏覽器歷史記錄裏 瀏覽器不會主動cache,參數不會被保留,除非手動設置
業務應用 常用在從服務器上獲取數據 常用在向服務器發送數據

** GET只需要跑一趟就把信息送到了,而POST得跑兩趟。第一趟,先去和服務器打個招呼“嗨,我等下要送一消息來,你們打開門迎接我”,然後再回頭把數據送過去。**

因爲POST需要兩步,時間上消耗的要多一點,所以看起來GET比POST更有效,但事實上不是,在網絡環境好的情況下,發一次包的時間和發兩次包的時間差別基本可以無視。

而在網絡環境差的情況下,兩次包的TCP在驗證數據包完整性上,有非常大的優點。

而且並非所有瀏覽器都會在POST中發送兩次包,Firefox瀏覽器就只發送一次。


07.常見的HTTP相應狀態碼(初級)

1XX:指示信息–表示請求已接收,繼續處理。

2XX Success(成功狀態碼):成功–表示請求已被成功接收、理解、接受。

200 表示從客戶端發來的請求在服務器端被正常處理
204 該狀態碼錶示服務器接收的請求已成功處理,但在返回的響應報文中不含實體的主體部分
206 該狀態碼錶示客戶端進行了範圍請求,而服務器成功執行了這部分的GET請求

3XX Redirection(重定向狀態碼):重定向–要完成請求必須進行更進一步的操作。

301 永久性重定向
302 臨時性重定向

4XX Client Error(客戶端錯誤狀態碼):客戶端錯誤–請求有語法錯誤或請求無法實現。

400 該狀態碼錶示請求報文中存在語法錯誤
401 該狀態碼錶示發送的請求需要有通過HTTP認證的認證信息
403 該狀態碼錶明對請求資源的訪問被服務器拒絕了
404 該狀態碼錶明服務器上無法找到請求的資源

5XX Server Error(服務器錯誤狀態碼):服務器端錯誤–服務器未能實現合法的請求。

500 該狀態碼錶明服務器端在執行請求時發生了錯誤。
503 該狀態碼錶明服務器暫時處於超負載或正在進行停機維護,現在無法處理請求。

08.如何對HTTP進行優化?(中級)

  1. TCP複用

TCP連接複用是將多個客戶端的HTTP請求複用到一個服務器端的TCP連接上。

HTTP複用是指一個客戶端的多個HTTP請求通過一個TCP連接進行處理。

  1. 內容緩存

將經常用到的內容進行緩存到瀏覽器中,那麼客戶端就可以直接在內存中獲取響應的數據。

  1. 壓縮

將文本數據進行壓縮,減少帶寬。

  1. SSL加速

使用SSL協議對HTTP協議進行加密,在通道內加密並加速。


09.TCP與UDP的區別?(初級)

TCP協議和UDP協議都是傳輸層協議。

  • TCP(Transmission ControlProtocol,傳輸控制協議)提供的是面向連接,可靠的字節流服務。

客戶和服務器交換數據前,必須現在雙方之間建立一個TCP連接,之後才能傳輸數據。

並提供超時重發、丟棄重複數據,檢驗數據,流量控制等功能,保證數據能完整地從一端傳到另一端。

簡單說就是必須要建立連接後才能傳輸數據,確保傳輸完整性,類比現實當中的打電話。

  • UDP(User Data Protocol,用戶數據報協議)是一個簡單的面向數據報的運輸層協議。

它不提供可靠性,只是把應用程序傳給IP層的數據報發送出去,但是不能保證它們能到達目的地。

由於UDP在傳輸數據報前不用再客戶和服務器之間建立一個連接,且沒有超時重發等機制,所以傳輸速度很快。

簡單說就是單向把程序中的信息發送了,但也不知道對方收到沒有,類比現實當中的寄信。


10.請介紹TCP的3次握手和4次揮手流程(初級)

建立雙工通信,確保雙方都能收到對方的信息,所以需要3次握手

在這裏插入圖片描述
第1次握手:建立連接時,客戶端發送syn包(syn=x)到服務器,並進入同步已發送狀態,等待服務器確認;SYN:同步序列編號。

第2次握手:服務器收到syn包,必須確認客戶的SYN(ack=x+1),同時自己也發送一個SYN包(syn=y),即SYN+ACK包,此時服務器進入同步已接受狀態;

第3次握手:客戶端收到服務器的SYN+ACK包,向服務器發送確認包ACK(ack=y+1),此包發送完畢,客戶端和服務器進入ESTABLISHED(TCP連接成功)狀態,完成三次握手。

全雙工關閉需要客戶端和服務器發送和接受都關閉,但是關閉連接時,當Server端收到FIN報文時,很可能並不會立即關閉SOCKET,只能先回復一個ACK報文,所以需要4次揮手

在這裏插入圖片描述
第1次揮手:客戶端進程發出連接釋放報文,並且停止發送數據。此時,客戶端進入FIN-WAIT-1(終止等待1)狀態。

第2次揮手:服務器收到連接釋放報文,發出確認報文。服務端就進入了CLOSE-WAIT(關閉等待)狀態。TCP服務器通知高層的應用進程,客戶端向服務器的方向就釋放了,這時候處於半關閉狀態,即客戶端已經沒有數據要發送了,但是服務器若發送數據,客戶端依然要接受。這個狀態還要持續一段時間,也就是整個CLOSE-WAIT狀態持續的時間。

客戶端收到服務器的確認請求後,此時,客戶端就進入FIN-WAIT-2(終止等待2)狀態,等待服務器發送連接釋放報文(在這之前還需要接受服務器發送的最後的數據)。

第3次揮手:服務器將最後的數據發送完畢後,就向客戶端發送連接釋放報文,FIN=1,ack=u+1,由於在半關閉狀態,服務器很可能又發送了一些數據,假定此時的序列號爲seq=w,此時,服務器就進入了LAST-ACK(最後確認)狀態,等待客戶端的確認。

第4次揮手:客戶端收到服務器的連接釋放報文後,必須發出確認,ACK=1,ack=w+1,而自己的序列號是seq=u+1,此時,客戶端就進入了TIME-WAIT(時間等待)狀態。注意此時TCP連接還沒有釋放,必須經過2MSL(最長報文段壽命)的時間後,當客戶端撤銷相應的TCB後,才進入CLOSED狀態。

服務器只要收到了客戶端發出的確認,立即進入CLOSED狀態。同樣,撤銷TCB後,就結束了這次的TCP連接。可以看到,服務器結束TCP連接的時間要比客戶端早一些。


11.爲什麼TCP連接的時候是3次握手,關閉的時候卻是4次握手?(初級)

因爲當Server端收到Client端的SYN連接請求報文後,可以直接發送SYN+ACK報文。

其中ACK報文是用來應答的,SYN報文是用來同步的。

但是關閉連接時,當Server端收到FIN報文時,很可能並不會立即關閉SOCKET,所以只能先回復一個ACK報文,告訴Client端,“你發的FIN報文我收到了”。

只有等到我Server端所有的報文都發送完了,我才能發送FIN報文,因此不能一起發送。故需要四步握手。


12.TCP爲什麼會分包和粘包?(高級)

TCP是以段(Segment)爲單位發送數據的,建立TCP鏈接後,有一個最大消息長度(MSS)。

如果應用層數據包超過MSS,就會把應用層數據包拆分,分成兩個段來發送。

這個時候接收端的應用層就要拼接這兩個TCP包,才能正確處理數據。

有時候,TCP爲了提高網絡的利用率,會使用一個叫做Nagle的算法。

該算法是指,發送端即使有要發送的數據,如果很少的話,會延遲發送。

如果應用層給TCP傳送數據很快的話,就會把兩個應用層數據包“粘”在一起,TCP最後只發一個TCP數據包給接收端.


13.HTTP和websocket的區別?(中級)

WebSocket允許服務端主動向客戶端推送數據。

在WebSocket協議中,客戶端瀏覽器和服務器只需要完成一次握手就可以創建持久性的鏈接,並在瀏覽器和服務器之間進行雙向的數據傳輸。

在這裏插入圖片描述

  • 最大的區別就是HTTP只能由客戶端推送信息給被動的服務端,而websocket既可以讓客戶端發送消息給服務端,也可以讓服務端主動推送消息到客戶端,實現雙工通信

  • http協議是用在應用層的協議,他是基於tcp協議的,http協議建立鏈接也必須要有三次握手才能發送信息。

http鏈接分爲短鏈接,長鏈接,短鏈接是每次請求都要三次握手才能發送自己的信息。即每一個request對應一個response。長鏈接是在一定的期限內保持鏈接。保持TCP連接不斷開。客戶端與服務器通信,必須要由客戶端發起然後服務器返回結果。客戶端是主動的,服務器是被動的。

  • WebSocket是爲解決客戶端與服務端實時通信。瀏覽器和服務器只需要做1個握手的動作,在建立連接之後,雙方可以在任意時刻,相互推送信息。同時,服務器與客戶端之間交換的頭信息很小。

建立了WebSocket之後服務器不必在瀏覽器發送request請求之後才能發送信息到瀏覽器。這時的服務器已有主動權想什麼時候發就可以發送信息到服務器。而且信息當中不必在帶有head的部分信息了與http的長鏈接通信來說,這種方式,不僅能降低服務器的壓力。而且信息當中也減少了部分多餘的信息。


14.HTTP的長連接與websocket的持久連接的區別?(高級)

  • HTTP1.1的連接默認使用長連接(persistent connection)

HTTP 1.1默認進行持久連接。在1次 TCP 連接中可以完成多個 HTTP 請求,但是對每個請求仍然要單獨發 header,Keep-Alive不會永久保持連接,它有一個保持時間,可以在不同的服務器軟件(如Nginx)中設定這個時間。這種長連接是一種“僞鏈接”

  • WebSocket的持久連接

WebSocket 是一個持久化的協議,只需建立1次Request/Response消息對,之後都是TCP連接,避免了需要多次建立Request/Response消息對而產生的冗餘頭部信息。


15.什麼是cookie?其特點和應用場景有哪些?其如何獲取、設置?(中級)

在這裏插入圖片描述

  • cookie是一種會話跟蹤技術,由服務器生成,然後通過響應發送給客戶端的一個鍵值對。

    1.cookie是一個標準的python字典,以鍵值對方式進行存儲,鍵值都是字符串
    
    2.通過瀏覽器訪問一個網站時,瀏覽器會將存儲該網站相關的所有cookie信息發送給該網站的服務器,request.COOKIES
    
    3.cookie是基於域名安全的
     
    4.cookie是有過期時間的,如果不指定,默認關閉瀏覽器後cookie就會過期
      
    5.單個Cookie保存的數據不能超過4K,很多瀏覽器都限制一個站點最多保存20個Cookie。
    
  • 應用場景:記住用戶名和密碼,安全性要求不高

response.set_cookie("is_login",True)    # 獲取

request.COOKIES.get("is_login")         # 設置

16.什麼是session?其特點和應用場景有哪些?其如何設置、獲取、清空?(中級)

在這裏插入圖片描述

  • Session是服務器端技術,它保存在服務器上。客戶端瀏覽器訪問服務器的時候,服務器把客戶端信息以某種形式記錄在服務器上。這就是 Session。客戶端瀏覽器再次訪問時只需要從該 Session 中查找該客戶的狀態就可以了。

    1.它是以已鍵值對進行存儲
      
    2.它依賴cookie,唯一的標識碼session ID保存在cookie中
      
    3.它也是有過期時間,如果不指定,默認兩週就會過期
      
    4.它是用base64加密
    
  • 應用場景:涉及到安全性要求比較高的數據,銀行卡賬戶、密碼

request.session["is_login"] = True          # 設置

is_login = request.session.get("is_login")  # 獲取

request.session.flush()                     # 清空

17.session和cookie的相同點和區別?(中級)

  • 相同點
cookie/session
跟蹤技術 都是追蹤瀏覽器用戶身份的會話方式
生成地點 都在服務器
存儲形式 都是鍵值對
過期時間 都可自定義
  • 不同點
cookie session
存放地點 瀏覽器 服務器
安全性 不安全,他人可通過分析存放在本地的cookie並進行Cookie欺騙 比較安全,因數據在服務器中,且用base64加密
依賴性 依賴cookie,唯一的標識碼session ID保存在cookie中
過期時間 默認關閉瀏覽器後就會過期 默認兩週就會過期

18.什麼是JWT,有什麼特點?(初級)

JWT 全稱 JSON Web Tokens,它定義了一種以JSON 對象形式的安全通信方法。它由頭部、負載和簽名3部分組成。它具有2個特點:

  • 簡潔:可以通過URL, POST 參數或者在 HTTP header 發送,因爲數據量小,傳輸速度快

  • 自包含:負載中包含了所有用戶所需要的信息,避免了多次查詢數據庫


19.簡述JWT的工作原理(初級)

在這裏插入圖片描述

  1. 客戶端通過Web表單將正確的用戶名和密碼發送到服務端的接口。這一過程一般是POST請求。建議的方式是通過SSL加密的傳輸(https協議),從而避免敏感信息被嗅探。

  2. 服務端覈對用戶名和密碼成功後,將用戶的id等其他信息作爲JWT Payload(負載),將其與頭部分別進行Base64編碼拼接後簽名,形成一個JWT。形成的JWT就是一個形同lll.zzz.xxx的字符串,並設置有效時間。

  3. 服務端將JWT字符串作爲登錄成功的返回結果返回給客戶端。

  4. 客戶端將返回的JWT以cookie的形式保存在瀏覽器上,並設置cookie的有效時間(建議客戶端cookie和服務端JWT的有效時間設置爲一致),用戶登出時客戶端需刪除cookie。

  5. 客戶端在每次請求時將JWT放入HTTP Header中的Authorization位。(解決XSS和XSRF問題)

  6. 服務端對收到的JWT進行解密和校驗,如檢查簽名是否正確、Token是否過期、Token的接收方是否是自己等。

  7. 驗證通過後服務端使用JWT中包含的用戶信息進行其他邏輯操作,返回相應結果,否則返回401。


20.傳統Session方式存儲ID和JWT的區別?(初級)

  1. Session是保存在服務端的,而JWT是保存在客戶端的。

  2. Session方式存儲用戶id的最大弊病在於Session是存儲在服務器端的,所以需要佔用大量服務器內存,對於較大型應用而言可能還要保存許多的狀態。 一般而言,大型應用還需要藉助一些KV數據庫和緩存機制來實現Session的存儲。

  3. JWT方式將用戶狀態分散到了客戶端中,可以減少服務器查詢數據庫的次數和減輕服務端的內存壓力。除了用戶id之外,還可以存儲其他的和用戶相關的信息。雖說JWT方式讓服務器有一些計算壓力,但是這些壓力相比磁盤存儲而言可能就不算什麼了。

具體是否採用,需要在不同場景下用數據說話。


在這裏插入圖片描述

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