面試官系列- 你真的瞭解 http 嗎

[toc]css

個人 CSDN 博客:blog.csdn.net/gdutxiaoxu
個人掘金:juejin.im/user/58aa85…
github: github.com/gdutxiaoxu/
微信公衆號:徐公碼字(stormjun94)
知乎:www.zhihu.com/people/xuju…
html

往期文章

Android 面試必備 - http 與 https 協議git

Android 面試必備 - 計算機網絡基本知識(TCP,UDP,Http,https)程序員

Android 面試必備 - 線程github

Android 面試必備 - JVM 及 類加載機制面試

Android 面試必備 - 系統、App、Activity 啓動過程算法

Android_interview github 地址chrome

有興趣的話能夠關注個人公衆號 徐公碼字(stormjun94),第一時間會在上面更新數據庫

image

前言

轉眼間,2020 年已過去一大半了,2020 年很難,各企業裁人的消息蠻多的,降職,不發年終獎等等。2020 年確實是艱難的一年。然而生活老是要繼續,時間不給你喪的機會!若是咱們能堅持下來,不斷提升本身,說不定會有新的機會。api

面試中,網絡(http, https, tcp, udp), jvm, 類加載機制等這些基礎的知識點是高頻出現的,每一個程序員都能說上好多。但不必定說到重點,以及理解背後的原理。

我在面試的過程當中也常常被問到,因而總結記錄了下來。千萬不要小瞧這些基礎,有時候,你算法,項目經驗都過了,可是基礎答得不太好。結果可能會經過,但這確定會影響你的評級,這是特別吃虧的。因此,不如花點時間背一下,理解一下背後的原理。

舉一個簡單的例子, https 鏈接過程是怎樣的,使用了了哪一種加密方https 的鏈接過程式,能夠抓包嗎,怎樣防止抓包,你是否可以對答以下。

廢話很少說,開始進入正文。

面試常見

一道經典的面試題

還記得這道經典的面試題目嗎?從 URL 在瀏覽器被被輸入到頁面展示的過程當中發生了什麼?

整體來講分爲如下幾個過程:

  • DNS 解析:將域名解析成 IP 地址
  • TCP 鏈接:TCP 三次握手
  • 發送 HTTP 請求
  • 服務器處理請求並返回 HTTP 報文
  • 瀏覽器解析渲染頁面
  • 斷開鏈接:TCP 四次揮手

完整的能夠看如下下面的圖片

image

http 必備基礎知識

HTTP 是一種 超文本傳輸協議(Hypertext Transfer Protocol),HTTP 是一個在計算機世界裏專門在兩點之間傳輸文字、圖片、音頻、視頻等超文本數據的約定和規範

image

HTTP 主要內容分爲三部分,超文本(Hypertext)、傳輸(Transfer)、協議(Protocol)。

  • 超文本就是不僅僅只是本文,它還能夠傳輸圖片、音頻、視頻,甚至點擊文字或圖片可以進行超連接的跳轉。
  • 上面這些概念能夠統稱爲數據,傳輸就是數據須要通過一系列的物理介質從一個端系統傳送到另一個端系統的過程。一般咱們把傳輸數據包的一方稱爲請求方,把接到二進制數據包的一方稱爲應答方。
  • 而協議指的就是是網絡中(包括互聯網)傳遞、管理信息的一些規範。如同人與人之間相互交流是須要遵循必定的規矩同樣,計算機之間的相互通訊須要共同遵照必定的規則,這些規則就稱爲協議,只不過是網絡協議。

什麼是無狀態協議,HTTP 是無狀態協議嗎,怎麼解決

無狀態協議(Stateless Protocol) 就是指瀏覽器對於事務的處理沒有記憶能力。舉個例子來講就是好比客戶請求得到網頁以後關閉瀏覽器,而後再次啓動瀏覽器,登陸該網站,可是服務器並不知道客戶關閉了一次瀏覽器。

HTTP 就是一種無狀態的協議,他對用戶的操做沒有記憶能力。可能大多數用戶不相信,他可能以爲每次輸入用戶名和密碼登錄一個網站後,下次登錄就再也不從新輸入用戶名和密碼了。這其實不是 HTTP 作的事情,起做用的是一個叫作 小甜餅(Cookie) 的機制。它可以讓瀏覽器具備記憶能力。 若是你的瀏覽器容許 cookie 的話,查看方式 chrome://settings/content/cookies

幾種方法

HTTP1.0定義了三種請求方法: GET, POST 和 HEAD方法

HTTP1.1新增了五種請求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT

  • GET: 一般用於請求服務器發送某些資源
  • HEAD: 請求資源的頭部信息, 而且這些頭部與 HTTP GET 方法請求時返回的一致. 該請求方法的一個使用場景是在下載一個大文件前先獲取其大小再決定是否要下載, 以此能夠節約帶寬資源
  • OPTIONS: 用於獲取目的資源所支持的通訊選項
  • POST: 發送數據給服務器,是非冪等
  • PUT: 跟POST方法很像,也是想服務器提交數據。可是,它們之間有不一樣。PUT指定了資源在服務器上的位置,而POST不須要置頂資源在服務器的位置,是冪等
  • DELETE: 用於刪除指定的資源
  • PATCH: 用於對資源進行部分修改
  • CONNECT: HTTP/1.1協議中預留給可以將鏈接改成管道方式的代理服務器
  • TRACE: 回顯服務器收到的請求,主要用於測試或診斷

http get 和 post 區別

Post通常用於更新或者添加資源信息 Get通常用於查詢操做,並且應該是安全和冪等的
Post更加安全 Get會把請求的信息放到URL的後面
Post傳輸量通常無大小限制 Get不能大於2KB
Post執行效率低 Get執行效率略高

http put 和 post 區別

舉一個簡單的例子

POST:用於提交請求,能夠更新或者建立資源,是非冪等的

舉個例子,在咱們的支付系統中,一個api的功能是建立收款金額二維碼,它和金額相關,每一個用戶能夠有多個二維碼,若是連續調用則會建立新的二維碼,這個時候就用POST

PUT: 用於向指定的URI傳送更新資源,是冪等的

仍是那個例子,用戶的帳戶二維碼只和用戶關聯,並且是一一對應的關係,此時這個api就能夠用PUT,由於每次調用它,都將刷新用戶帳戶二維碼

若是從 RESTful API 的角度來理解,PUT 方法是這麼工做的:

把一個對象 V 綁定到地址 K 上;從此請求地址 K 時,就會返回對象 V。

若是地址 K 以前曾綁定過另外一個對象,好比 V0,那麼 V0 會被 V 替換。

舉一個簡單的例子,假設個人博客後臺支持 RESTful API,我能夠經過下面的請求發佈這篇文章:

PUT https://gdutxiao.github.io/2018/04/16/http-put-vs-post HTTP/1.1

{
    /* 文章內容正文 */
}
複製代碼

能夠看出,使用 PUT 方法時,客戶端須要在 HTTP 請求中明確指定地址 K。

正如 Java 的例子同樣,PUT 方法應當支持冪等性。若是是同一個對象 V,PUT 屢次與 PUT 一次返回的結果應該是相同的。客戶端能夠利用 PUT 的冪等性安全地重試請求,保證客戶端的請求至少被服務端處理一次。

若是把上面發佈文章的例子用 HTTP POST 方法重寫,它可能會是下面這樣:

POST https://gdutxiao.github.io/post-article HTTP/1.1

{
    /* 文章內容正文 */
}
複製代碼

也就是說,地址 K 不是由客戶端指定的,而是由服務端生成的。好比,服務端可能會根據日期和文章標題,爲本文分配一個地址。

另外,與 PUT 方法不一樣,POST 方法是不支持冪等性的。同一個請求被處理兩次,應當生成兩份對象。換句話說,客戶端應該只發送一次 POST 請求,而客戶端的請求至多會被服務端處理一次。

如今問題來了,若是真的遇到了網絡故障,客戶端應該如何重試 POST 請求呢?解決方法其實很簡單,咱們能夠在 POST 請求中隱藏一個惟一的 token,服務端在處理請求後把 token 存入數據庫,若是這個 token 以前遇到過,服務端就知道這是重複的 POST 請求,能夠再也不處理了。

http 版本

1.0 與 1.1

  • http1.0一次只能處理一個請求,不能同時收發數據
  • http1.1能夠處理多個請求,能同時收發數據
  • http1.1增長可更多字段,如cache-control,keep-alive.

2.0

  • http 2.0採用二進制的格式傳送數據,再也不使用文本格式傳送數據
  • http2.0對消息頭採用hpack壓縮算法,http1.x的版本消息頭帶有大量的冗餘消息
  • http2.0 採用多路複用,即用一個tcp鏈接處理全部的請求,真正意義上作到了併發請求,流還支持優先級和流量控制(HTTP/1.x 雖然經過 pipeline也能併發請求,可是多個請求之間的響應會被阻塞的,因此 pipeline 至今也沒有被普及應用,而 HTTP/2 作到了真正的併發請求。同時,流還支持優先級和流量控制。)
  • http2.0支持server push,服務端能夠主動把css,jsp文件主動推送到客戶端,不須要客戶端解析HTML,再發送請求,當客戶端須要的時候,它已經在客戶端了。

缺點

雖然 HTTP/2 解決了不少以前舊版本的問題,可是它仍是存在一個巨大的問題, 主要是底層支撐的 TCP 協議形成的 。HTTP/2的缺點主要有如下幾點:

  • TCP 以及 TCP+TLS創建鏈接的延時

HTTP/2使用TCP協議來傳輸的,而若是使用HTTPS的話,還須要使用TLS協議進行安全傳輸,而使用TLS也須要一個握手過程, 這樣就須要有兩個握手延遲過程

①在創建TCP鏈接的時候,須要和服務器進行三次握手來確認鏈接成功,也就是說須要在消耗完1.5個RTT以後才能進行數據傳輸。

②進行TLS鏈接,TLS有兩個版本——TLS1.2和TLS1.3,每一個版本創建鏈接所花的時間不一樣,大體是須要1~2個RTT。

總之,在傳輸數據以前,咱們須要花掉 3~4 個 RTT。

  • TCP的隊頭阻塞並無完全解決

上文咱們提到在HTTP/2中,多個請求是跑在一個TCP管道中的。但當出現了丟包時,HTTP/2 的表現反倒不如 HTTP/1 了。由於TCP爲了保證可靠傳輸,有個特別的「丟包重傳」機制,丟失的包必需要等待從新傳輸確認,HTTP/2出現丟包時,整個 TCP 都要開始等待重傳,那麼就會阻塞該TCP鏈接中的全部請求(以下圖)。而對於 HTTP/1.1 來講,能夠開啓多個 TCP 鏈接,出現這種狀況反到只會影響其中一個鏈接,剩餘的 TCP 鏈接還能夠正常傳輸數據。

image

Http 3.0

Google 在推SPDY的時候就已經意識到了這些問題,因而就另起爐竈搞了一個基於 UDP 協議的「QUIC」協議,讓HTTP跑在QUIC上而不是TCP上。 而這個「HTTP over QUIC」就是HTTP協議的下一個大版本,HTTP/3。它在HTTP/2的基礎上又實現了質的飛躍,真正「完美」地解決了「隊頭阻塞」問題。

image

QUIC 雖然基於 UDP,可是在本來的基礎上新增了不少功能,接下來咱們重點介紹幾個QUIC新功能。不過HTTP/3目前還處於草案階段,正式發佈前可能會有變更,因此本文儘可能不涉及那些不穩定的細節。

QUIC新功能

上面咱們提到QUIC基於UDP,而UDP是「無鏈接」的,根本就不須要「握手」和「揮手」,因此就比TCP來得快。此外QUIC也實現了可靠傳輸,保證數據必定可以抵達目的地。它還引入了相似HTTP/2的「流」和「多路複用」,單個「流"是有序的,可能會由於丟包而阻塞,但其餘「流」不會受到影響。具體來講QUIC協議有如下特色:

  • 實現了相似TCP的流量控制、傳輸可靠性的功能。

雖然UDP不提供可靠性的傳輸,但QUIC在UDP的基礎之上增長了一層來保證數據可靠性傳輸。它提供了數據包重傳、擁塞控制以及其餘一些TCP中存在的特性。

  • 實現了快速握手功能。

因爲QUIC是基於UDP的,因此QUIC能夠實現使用0-RTT或者1-RTT來創建鏈接,這意味着QUIC能夠用最快的速度來發送和接收數據,這樣能夠大大提高首次打開頁面的速度。 0RTT 建連能夠說是 QUIC 相比 HTTP2 最大的性能優點

  • 集成了TLS加密功能。

目前QUIC使用的是TLS1.3,相較於早期版本TLS1.3有更多的優勢,其中最重要的一點是減小了握手所花費的RTT個數。

  • 多路複用,完全解決TCP中隊頭阻塞的問題

和TCP不一樣,QUIC實現了在同一物理鏈接上能夠有多個獨立的邏輯數據流(以下圖)。實現了數據流的單獨傳輸,就解決了TCP中隊頭阻塞的問題。

image

關於 http 3.0 的,若是想了解更多,能夠查看這一篇文章。解密HTTP/2與HTTP/3 的新特性

總結

  • HTTP/1.1有兩個主要的缺點:安全不足和性能不高。
  • HTTP/2徹底兼容HTTP/1,是「更安全的HTTP、更快的HTTPS",頭部壓縮、多路複用等技術能夠充分利用帶寬,下降延遲,從而大幅度提升上網體驗;
  • QUIC 基於 UDP 實現,是 HTTP/3 中的底層支撐協議,該協議基於 UDP,又取了 TCP 中的精華,實現了即快又可靠的協議

http 狀態碼

Http 狀態碼 含義
200 請求成功
206 支持斷點下載(range = byte = 0 -1024)
301 永遠移動
302 臨時移動
303 See Other 查看其它地址。與301相似。使用GET和POST請求查看
304 無更新
400 Bad request,服務器沒法識別
403 禁止訪問
404 not found
405 Method Not Allowed 客戶端請求中的方法被禁止
500 Internal Server Error 服務器內部錯誤,沒法完成請求

關於更詳細的能夠查看

http 狀態碼

題外話

下一篇預告,將會推出 面試官系列 - https 真的安全嗎,能夠抓包嗎,如何防止抓包。

有興趣的話能夠關注個人公衆號 徐公碼字(stormjun94)

image

目前從事於 Android 開發,除了分享 Android開發相關知識,還有職場心得,面試經驗,學習心得,人生感悟等等。但願經過該公衆號,讓你看到程序猿不同的一面,咱們不僅會敲代碼,咱們還會。。。。。。,期待你的參與

相關文章
相關標籤/搜索