<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          【秋招求職之路】「阿里智能事業(yè)群-達(dá)摩院」秋招面試復(fù)盤總結(jié)【文末福利】

          共 10298字,需瀏覽 21分鐘

           ·

          2021-06-15 03:09

          往期精彩文章推薦


          阿里智能事業(yè)群-達(dá)摩院-機(jī)器智能技術(shù)部

          一面

          自我介紹

          聊實(shí)習(xí)經(jīng)歷

          主要工作內(nèi)容,比如申請前端小組組長,與項目負(fù)責(zé)人溝通,完成模塊發(fā)布工具前端框架。每日完成工作進(jìn)度匯報,前端工作主要是表格頁面渲染,比如樹形表格,分組表格結(jié)合等,實(shí)現(xiàn)基本的增刪改查功能...

          項目中有用到SSR,說說對SSR的理解,目前為什么要用SSR?

          頁面的渲染流程

          • 瀏覽器通過請求得到一個HTML文本
          • 渲染進(jìn)程解析HTML文本,構(gòu)建DOM樹
          • 解析HTML的同時,如果遇到內(nèi)聯(lián)樣式或者樣式腳本,則下載并構(gòu)建樣式規(guī)則(stytle rules),若遇到JavaScript腳本,則會下載執(zhí)行腳本。
          • DOM樹和樣式規(guī)則構(gòu)建完成之后,渲染進(jìn)程將兩者合并成渲染樹(render tree)
          • 渲染進(jìn)程開始對渲染樹進(jìn)行布局,生成布局樹(layout tree)
          • 渲染進(jìn)程對布局樹進(jìn)行繪制,生成繪制記錄
          • 渲染進(jìn)程的對布局樹進(jìn)行分層,分別柵格化每一層,并得到合成幀
          • 渲染進(jìn)程將合成幀信息發(fā)送給GPU進(jìn)程顯示到頁面中

          可以看到,頁面的渲染其實(shí)就是「瀏覽器將HTML文本轉(zhuǎn)化為頁面幀」的過程。而如今我們大部分WEB應(yīng)用都是使用 JavaScript 框架(Vue、React、Angular)進(jìn)行頁面渲染的,也就是說,在執(zhí)行 JavaScript 腳本的時候,「HTML頁面已經(jīng)開始解析并且構(gòu)建DOM樹」了,JavaScript 腳本只是動態(tài)的改變 DOM 樹的結(jié)構(gòu),使得頁面成為希望成為的樣子,這種渲染方式叫動態(tài)渲染,也可以叫客戶端渲染(client side rende)

          那么什么是服務(wù)端渲染(server side render)?顧名思義,服務(wù)端渲染就是在瀏覽器請求頁面URL的時候,服務(wù)端「將我們需要的HTML文本組裝好」,并返回給瀏覽器,這個HTML文本被瀏覽器解析之后,「不需要經(jīng)過 JavaScript 腳本」的執(zhí)行,即可直接構(gòu)建出希望的 DOM 樹并展示到頁面中。這個服務(wù)端組裝HTML的過程,叫做服務(wù)端渲染

          服務(wù)端渲染的由來

          「Web1.0」

          在沒有AJAX的時候,也就是web1.0時代,幾乎所有應(yīng)用都是服務(wù)端渲染(此時服務(wù)器渲染非現(xiàn)在的服務(wù)器渲染),那個時候的頁面渲染大概是這樣的,瀏覽器請求頁面URL,然后服務(wù)器接收到請求之后,到數(shù)據(jù)庫查詢數(shù)據(jù),將「數(shù)據(jù)丟到后端的組件模板(php、asp、jsp等)中,并渲染成HTML片段」,接著服務(wù)器在組裝這些HTML片段,組成一個完整的HTML,最后返回給瀏覽器,這個時候,瀏覽器已經(jīng)拿到了一個完整的被服務(wù)器動態(tài)組裝出來的HTML文本,然后將HTML渲染到頁面中,過程沒有任何JavaScript代碼的參與。

          「客戶端渲染」

          在WEB1.0時代,服務(wù)端渲染看起來是一個當(dāng)時的最好的渲染方式,但是隨著業(yè)務(wù)的日益復(fù)雜和后續(xù)AJAX的出現(xiàn),也漸漸開始暴露出了WEB1.0服務(wù)器渲染的缺點(diǎn)。

          • 每次更新頁面的一小的模塊,都需要重新請求一次頁面,重新查一次數(shù)據(jù)庫,重新組裝一次HTML
          • 前端JavaScript代碼和后端(jsp、php、jsp)代碼混雜在一起,使得日益復(fù)雜的WEB應(yīng)用難以維護(hù)

          而且那個時候,根本就沒有前端工程師這一職位,前端js的活一般都由后端同學(xué) jQuery 一把梭。但是隨著前端頁面漸漸地復(fù)雜了之后,后端開始發(fā)現(xiàn)js好麻煩,雖然很簡單,但是坑太多了,于是讓公司招聘了一些專門寫js的人,也就是前端,這個時候,前后端的鄙視鏈就出現(xiàn)了,后端鄙視前端,因?yàn)楹蠖擞X得js太簡單,無非就是寫寫頁面的特效(JS),切切圖(CSS),根本算不上是真正的程序員。

          隨之 nodejs 的出現(xiàn),前端看到了翻身的契機(jī),為了擺脫后端的指指點(diǎn)點(diǎn),前端開啟了一場前后端分離的運(yùn)動,希望可以脫離后端獨(dú)立發(fā)展。前后端分離,表面上看上去是代碼分離,實(shí)際上是為了前后端人員分離,也就是前后端分家,前端不再歸屬于后端團(tuán)隊。

          前后端分離之后,網(wǎng)頁開始被當(dāng)成了獨(dú)立的應(yīng)用程序(SPA,Single Page Application),前端團(tuán)隊接管了所有頁面渲染的事,后端團(tuán)隊只負(fù)責(zé)提供所有數(shù)據(jù)查詢與處理的API,大體流程是這樣的:首先瀏覽器請求URL,前端服務(wù)器直接返回一個空的靜態(tài)HTML文件(不需要任何查數(shù)據(jù)庫和模板組裝),這個HTML文件中加載了很多渲染頁面需要的 JavaScript 腳本和 CSS 樣式表,瀏覽器拿到 HTML 文件后開始加載腳本和樣式表,并且執(zhí)行腳本,這個時候腳本請求后端服務(wù)提供的API,獲取數(shù)據(jù),獲取完成后將數(shù)據(jù)通過JavaScript腳本動態(tài)的將數(shù)據(jù)渲染到頁面中,完成頁面顯示。

          這一個前后端分離的渲染模式,也就是客戶端渲染(CSR)

          「服務(wù)端渲染」

          隨著單頁應(yīng)用(SPA)的發(fā)展,程序員們漸漸發(fā)現(xiàn)SEO(Search Engine Optimazition,即搜索引擎優(yōu)化)出了問題,而且隨著應(yīng)用的復(fù)雜化,JavaScript 腳本也不斷的臃腫起來,使得「首屏渲染」相比于 Web1.0時候的服務(wù)端渲染,也慢了不少。

          自己選的路,跪著也要走下去。于是前端團(tuán)隊選擇了使用 nodejs 在服務(wù)器進(jìn)行頁面的渲染,進(jìn)而再次出現(xiàn)了服務(wù)端渲染。大體流程與客戶端渲染有些相似,首先是瀏覽器請求URL,前端服務(wù)器接收到URL請求之后,根據(jù)不同的URL,前端服務(wù)器向后端服務(wù)器請求數(shù)據(jù),請求完成后,前端服務(wù)器會組裝一個攜帶了具體數(shù)據(jù)的HTML文本,并且返回給瀏覽器,瀏覽器得到HTML之后開始渲染頁面,同時,「瀏覽器加載并執(zhí)行 JavaScript 腳本,給頁面上的元素綁定事件,讓頁面變得可交互」,當(dāng)用戶與瀏覽器頁面進(jìn)行交互,如跳轉(zhuǎn)到下一個頁面時,瀏覽器會執(zhí)行 JavaScript 腳本,向后端服務(wù)器請求數(shù)據(jù),獲取完數(shù)據(jù)之后再次執(zhí)行 JavaScript 代碼動態(tài)渲染頁面。

          參考:【萬字長文警告】從頭到尾徹底理解服務(wù)端渲染SSR原理

          參考:為什么現(xiàn)在又流行服務(wù)端渲染html?

          Vue.js 服務(wù)器端渲染指南

          服務(wù)端渲染的利弊

          「利于SEO」

          有利于SEO,其實(shí)就是有利于爬蟲來爬你的頁面,然后在別人使用搜索引擎搜索相關(guān)的內(nèi)容時,你的網(wǎng)頁排行能靠得更前,這樣你的流量就有越高。那為什么服務(wù)端渲染更利于爬蟲爬你的頁面呢?其實(shí),爬蟲也分低級爬蟲和高級爬蟲。

          • 低級爬蟲:只請求URL,URL返回的HTML是什么內(nèi)容就爬什么內(nèi)容。
          • 高級爬蟲:請求URL,加載并執(zhí)行JavaScript腳本渲染頁面,「爬JavaScript渲染后的內(nèi)容」

          也就是說,低級爬蟲對客戶端渲染的頁面來說,簡直無能為力,因?yàn)榉祷氐腍TML是一個空殼,它需要執(zhí)行 JavaScript 腳本之后才會渲染真正的頁面。而目前像百度、谷歌、微軟等公司,有一部分年代老舊的爬蟲還屬于低級爬蟲,使用服務(wù)端渲染,對這些低級爬蟲更加友好一些。

          「白屏?xí)r間更短」

          相對于客戶端渲染,服務(wù)端渲染在瀏覽器請求URL之后已經(jīng)得到了一個帶有數(shù)據(jù)的HTML文本,瀏覽器只需要解析HTML,直接構(gòu)建DOM樹就可以。而客戶端渲染,需要先得到一個空的HTML頁面,這個時候頁面已經(jīng)進(jìn)入白屏,之后還需要經(jīng)過加載并執(zhí)行 JavaScript、請求后端服務(wù)器獲取數(shù)據(jù)、JavaScript 渲染頁面幾個過程才可以看到最后的頁面。特別是在復(fù)雜應(yīng)用中,由于需要加載 JavaScript 腳本,「越是復(fù)雜的應(yīng)用,需要加載的 JavaScript 腳本就越多、越大,這會導(dǎo)致應(yīng)用的首屏加載時間非常長,進(jìn)而降低了體驗(yàn)感。」

          服務(wù)端渲染缺點(diǎn)

          并不是所有的WEB應(yīng)用都必須使用SSR,這需要開發(fā)者自己來權(quán)衡,因?yàn)榉?wù)端渲染會帶來以下問題:

          • 「代碼復(fù)雜度增加」。為了實(shí)現(xiàn)服務(wù)端渲染,應(yīng)用代碼中需要兼容服務(wù)端和客戶端兩種運(yùn)行情況,而一部分依賴的外部擴(kuò)展庫卻只能在客戶端運(yùn)行,需要對其進(jìn)行特殊處理,才能在服務(wù)器渲染應(yīng)用程序中運(yùn)行。
          • 「需要更多的服務(wù)器負(fù)載均衡」。由于服務(wù)器增加了渲染HTML的需求,使得原本只需要輸出靜態(tài)資源文件的nodejs服務(wù),新增了數(shù)據(jù)獲取的IO和渲染HTML的CPU占用,如果流量突然暴增,有可能導(dǎo)致服務(wù)器down機(jī),因此需要使用響應(yīng)的緩存策略和準(zhǔn)備相應(yīng)的服務(wù)器負(fù)載。
          • 「及構(gòu)建設(shè)置和部署的更多要求」。與可以部署在任何靜態(tài)文件服務(wù)器上的完全靜態(tài)單頁面應(yīng)用程序 (SPA) 不同,服務(wù)器渲染應(yīng)用程序,需要處于 Node.js server 運(yùn)行環(huán)境。

          所以在使用服務(wù)端渲染SSR之前,需要開發(fā)者考慮投入產(chǎn)出比,比如大部分應(yīng)用系統(tǒng)都不需要SEO,而且首屏?xí)r間并沒有非常的慢,如果使用SSR反而小題大做了。

          同構(gòu)

          在服務(wù)端渲染中,有兩種頁面渲染的方式:

          • 前端服務(wù)器通過請求后端服務(wù)器獲取數(shù)據(jù)并組裝HTML返回給瀏覽器,瀏覽器直接解析HTML后渲染頁面
          • 瀏覽器在交互過程中,請求新的數(shù)據(jù)并動態(tài)更新渲染頁面

          這兩種渲染方式有一個不同點(diǎn)就是,一個是在服務(wù)端中組裝html的,一個是在客戶端中組裝html的,運(yùn)行環(huán)境是不一樣的。所謂「同構(gòu)」,就是讓一份代碼,「既可以在服務(wù)端中執(zhí)行,也可以在客戶端中執(zhí)行,并且執(zhí)行的效果都是一樣的」,都是完成這個html的組裝,正確的顯示頁面。也就是說,一份代碼,既可以客戶端渲染,也可以服務(wù)端渲染。

          「同構(gòu)的條件」

          為了實(shí)現(xiàn)同構(gòu),我們需要滿足什么條件呢?

          首先,我們思考一個應(yīng)用中一個頁面的組成,假如我們使用的是Vue.js,當(dāng)我們打開一個頁面時,首先是打開這個頁面的URL,這個URL,可以通過應(yīng)用的路由匹配,找到具體的頁面,不同的頁面有不同的視圖,那么,視圖是什么?從應(yīng)用的角度來看,「視圖 = 模板 + 數(shù)據(jù)」,那么在 Vue.js 中, 模板可以理解成組件,數(shù)據(jù)可以理解為數(shù)據(jù)模型,即響應(yīng)式數(shù)據(jù)。所以,對于同構(gòu)應(yīng)用來說,我們「必須實(shí)現(xiàn)客戶端與服務(wù)端的路由、模型組件、數(shù)據(jù)模型的共享」

          總結(jié)

          「瀏覽器渲染」

          單頁應(yīng)用用的基本都是瀏覽器渲染。優(yōu)點(diǎn)很明確,后端只提供數(shù)據(jù),前端做視圖和交互邏輯,「分工明確」。服務(wù)器只提供接口,路由以及渲染都丟給前端,服務(wù)器計算壓力變輕了。但是弱點(diǎn)就是「用戶等待時間變長」了,尤其在請求數(shù)多而且有一定先后順序的時候。

          客戶端渲染路線:1. 請求一個html -> 2. 服務(wù)端返回一個html -> 3. 瀏覽器下載html里面的js/css文件 -> 4. 等待js文件下載完成 -> 5. 等待js加載并初始化完成 -> 6. js代碼終于可以運(yùn)行,由js代碼向后端請求數(shù)據(jù)( ajax/fetch ) -> 7. 等待后端數(shù)據(jù)返回 -> 8. 客戶端從無到完整地,把數(shù)據(jù)渲染為響應(yīng)頁面

          「服務(wù)器渲染」

          服務(wù)器接到用戶請求之后,計算出用戶需要的數(shù)據(jù),然后將數(shù)據(jù)更新成視圖(也就是一串dom字符)發(fā)給客戶端,客戶端直接將這串字符塞進(jìn)頁面即可。這樣做的好處是「響應(yīng)很快,用戶體驗(yàn)會比較好」,另外對于搜索引擎來說也是友好的,「有SEO優(yōu)化」。nodejs層的服務(wù)器渲染,還有一個明顯的好處就是「前端性能優(yōu)化更順手了,可操作的空間大」了。但是缺點(diǎn)也很明顯,如果不是增加一個node層的話,前后端責(zé)任分工不明,不能很好的并行開發(fā)。另外也增加了服務(wù)器計算壓力(雖然可以做渲染緩存,但畢竟是多做了計算)。

          服務(wù)端渲染路線:2. 請求一個html -> 2. 服務(wù)端請求數(shù)據(jù)( 內(nèi)網(wǎng)請求快 ) -> 3. 服務(wù)器初始渲染(服務(wù)端性能好,較快) -> 4. 服務(wù)端返回已經(jīng)有正確內(nèi)容的頁面 -> 5. 客戶端請求js/css文件 -> 6. 等待js文件下載完成 -> 7. 等待js加載并初始化完成 -> 8. 客戶端把剩下一部分渲染完成( 內(nèi)容小,渲染快 )

          對CDN的理解

          github 里面有做cdn倉庫,于是扯到了cdn,之后掛鉤上http緩存,瀏覽器緩存相關(guān),回源那一塊。

          說一個最近刷的印象比較深刻的 leetcode 題目,講講思路

          leetcode 200 島嶼問題 講了怎么dfs 沉島

          大學(xué)里面學(xué)的一些課程哪門最熟悉?

          算法、數(shù)據(jù)結(jié)構(gòu)、計算機(jī)網(wǎng)絡(luò)、操作系統(tǒng)

          選了計算機(jī)網(wǎng)絡(luò),畢竟是班主任教的(orz)

          說說五層、七層 計算機(jī)網(wǎng)絡(luò)模型

          參考:詳解 四層、五層、七層 計算機(jī)網(wǎng)絡(luò)模型

          舉例傳輸層和應(yīng)用層

          傳輸層:TCP / UDP 應(yīng)用層:HTTP / HTTPS 、FTP、SMTP等

          HTTP1.0 和 HTTP2.0區(qū)別有了解嗎?

          簡要概括一下 HTTP 的特點(diǎn)?HTTP 有哪些缺點(diǎn)?

          「HTTP 特點(diǎn)」

          • 靈活可擴(kuò)展 主要體現(xiàn)在兩個方面。一個是語義上的自由,只規(guī)定了基本格式,比如空格分隔單詞,換行分隔字段,其他的各個部分都沒有嚴(yán)格的語法限制。另一個是傳輸形式的多樣性,不僅僅可以傳輸文本,還能傳輸圖片、視頻等任意數(shù)據(jù),非常方便。

          • 可靠傳輸 HTTP 基于 TCP/IP,因此把這一特性繼承了下來。

          • 請求-應(yīng)答 也就是一發(fā)一收、有來有回, 當(dāng)然這個請求方和應(yīng)答方不單單指客戶端和服務(wù)器之間,如果某臺服務(wù)器作為代理來連接后端的服務(wù)端,那么這臺服務(wù)器也會扮演請求方的角色。

          • 無狀態(tài) 這里的狀態(tài)是指「通信過程的上下文信息」,而每次 http 請求都是獨(dú)立、無關(guān)的,默認(rèn)不需要保留狀態(tài)信息。

          「HTTP 缺點(diǎn)」

          • 無狀態(tài)

          所謂的優(yōu)點(diǎn)和缺點(diǎn)還是要分場景來看的,對于 HTTP 而言,最具爭議的地方在于它的「無狀態(tài)」

          「需要長連接」的場景中,需要保存大量的上下文信息,以免傳輸大量重復(fù)的信息,那么這時候無狀態(tài)就是 http 的缺點(diǎn)了。

          但與此同時,另外一些應(yīng)用僅僅只是為了獲取一些數(shù)據(jù),不需要保存連接上下文信息,無狀態(tài)反而減少了網(wǎng)絡(luò)開銷,成為了 http 的優(yōu)點(diǎn)。

          • 明文傳輸

          即協(xié)議里的報文(主要指的是「頭部」)不使用二進(jìn)制數(shù)據(jù),而是「文本形式」。這當(dāng)然對于調(diào)試提供了便利,但同時也讓 HTTP 的報文信息暴露給了外界,給攻擊者也提供了便利。WIFI陷阱就是利用 HTTP 明文傳輸?shù)娜秉c(diǎn),誘導(dǎo)你連上熱點(diǎn),然后瘋狂抓你所有的流量,從而拿到你的敏感信息。

          • 隊頭阻塞問題

          當(dāng) http 開啟長連接時,共用一個 TCP 連接,同一時刻只能處理一個請求,那么當(dāng)前請求耗時過長的情況下,其它的請求只能處于阻塞狀態(tài),也就是著名的「隊頭阻塞」問題。

          參考:三元大佬(建議精讀)HTTP靈魂之問,鞏固你的 HTTP 知識體系

          HTTP1.1 如何解決 HTTP 的隊頭阻塞問題?

          「什么是 HTTP 隊頭阻塞?」

          HTTP 傳輸是基于請求-應(yīng)答的模式進(jìn)行的,報文必須是一發(fā)一收,但值得注意的是,里面的任務(wù)被放在一個任務(wù)隊列中串行執(zhí)行,一旦隊首的請求處理太慢,就會阻塞后面請求的處理。這就是著名的HTTP隊頭阻塞問題。

          • 并發(fā)連接

          對于一個域名允許分配多個長連接,那么相當(dāng)于增加了任務(wù)隊列,不至于一個隊伍的任務(wù)阻塞其它所有任務(wù)。在RFC2616規(guī)定過客戶端最多并發(fā) 2 個連接,不過事實(shí)上在現(xiàn)在的瀏覽器標(biāo)準(zhǔn)中,這個上限要多很多,「Chrome 中是 6 個」

          但其實(shí),即使是提高了并發(fā)連接,還是不能滿足人們對性能的需求。

          • 域名分片

          一個域名不是可以并發(fā) 6 個長連接嗎?那我就多分幾個域名。

          比如 content1.sanyuan.com 、content2.sanyuan.com。

          這樣一個sanyuan.com域名下可以分出非常多的二級域名,而它們都指向同樣的一臺服務(wù)器,能夠并發(fā)的長連接數(shù)更多了,事實(shí)上也更好地解決了隊頭阻塞的問題。

          HTTP/2 有哪些改進(jìn)?

          由于 HTTPS 在安全方面已經(jīng)做的非常好了,HTTP 改進(jìn)的關(guān)注點(diǎn)放在了性能方面。對于 HTTP/2 而言,它對于性能的提升主要在于兩點(diǎn):

          • 頭部壓縮
          • 多路復(fù)用

          當(dāng)然還有一些顛覆性的功能實(shí)現(xiàn):

          • 設(shè)置請求優(yōu)先級
          • 服務(wù)器推送

          這些重大的提升本質(zhì)上也是為了解決 HTTP 本身的問題而產(chǎn)生的。接下來我們來看看 HTTP/2 解決了哪些問題,以及解決方式具體是如何的。

          「頭部壓縮」

          在 HTTP/1.1 及之前的時代,「請求體」一般會有響應(yīng)的壓縮編碼過程,通過Content-Encoding頭部字段來指定,但你有沒有想過頭部字段本身的壓縮呢?當(dāng)請求字段非常復(fù)雜的時候,尤其對于 GET 請求,請求報文幾乎全是請求頭,這個時候還是存在非常大的優(yōu)化空間的。HTTP/2 針對頭部字段,也采用了對應(yīng)的壓縮算法——HPACK,對請求頭進(jìn)行壓縮。

          HPACK 算法是專門為 HTTP/2 服務(wù)的,它主要的亮點(diǎn)有兩個:

          • 首先是在服務(wù)器和客戶端之間建立哈希表,將用到的字段存放在這張表中,那么在傳輸?shù)臅r候?qū)τ谥俺霈F(xiàn)過的值,只需要把「索引」(比如0,1,2,...)傳給對方即可,對方拿到索引查表就行了。這種「傳索引」的方式,可以說讓請求頭字段得到極大程度的精簡和復(fù)用。

          HTTP/2 當(dāng)中廢除了起始行的概念,將起始行中的請求方法、URI、狀態(tài)碼轉(zhuǎn)換成了頭字段,不過這些字段都有一個":"前綴,用來和其它請求頭區(qū)分開。

          • 其次是對于整數(shù)和字符串進(jìn)行「哈夫曼編碼」,哈夫曼編碼的原理就是先將所有出現(xiàn)的字符建立一張索引表,然后讓出現(xiàn)次數(shù)多的字符對應(yīng)的索引盡可能短,傳輸?shù)臅r候也是傳輸這樣的「索引序列」,可以達(dá)到非常高的壓縮率。

          「多路復(fù)用」

          我們之前討論了 HTTP 隊頭阻塞的問題,其根本原因在于HTTP 基于請求-響應(yīng)的模型,在同一個 TCP 長連接中,前面的請求沒有得到響應(yīng),后面的請求就會被阻塞。

          后面我們又討論到用「并發(fā)連接」「域名分片」的方式來解決這個問題,但這并沒有真正從 HTTP 本身的層面解決問題,只是增加了 TCP 連接,分?jǐn)傦L(fēng)險而已。而且這么做也有弊端,多條 TCP 連接會競爭「有限的帶寬」,讓真正優(yōu)先級高的請求不能優(yōu)先處理。

          而 HTTP/2 便從 HTTP 協(xié)議本身解決了隊頭阻塞問題。注意,這里并不是指的TCP隊頭阻塞,而是HTTP隊頭阻塞,兩者并不是一回事。TCP 的隊頭阻塞是在數(shù)據(jù)包層面,單位是數(shù)據(jù)包,前一個報文沒有收到便不會將后面收到的報文上傳給 HTTP,而HTTP 的隊頭阻塞是在 HTTP 請求-響應(yīng)層面,前一個請求沒處理完,后面的請求就要阻塞住。兩者所在的層次不一樣。

          那么 HTTP/2 如何來解決所謂的隊頭阻塞呢?

          「二進(jìn)制分幀」

          首先,HTTP/2 認(rèn)為「明文傳輸對機(jī)器而言太麻煩」了,不方便計算機(jī)的解析,因?yàn)閷τ谖谋径詴卸嗔x性的字符,比如回車換行到底是內(nèi)容還是分隔符,在內(nèi)部需要用到狀態(tài)機(jī)去識別,效率比較低。于是 HTTP/2 干脆把報文全部換成二進(jìn)制格式,全部傳輸01串,方便了機(jī)器的解析。

          原來Headers + Body的報文格式如今被拆分成了一個個二進(jìn)制的幀,用「Headers幀」存放頭部字段,「Data幀」存放請求體數(shù)據(jù)。分幀之后,服務(wù)器看到的不再是一個個完整的 HTTP 請求報文,而是一堆「亂序的二進(jìn)制幀」。這些二進(jìn)制幀不存在先后關(guān)系,因此也就不會排隊等待,也就沒有了 HTTP 的隊頭阻塞問題

          通信雙方都可以給對方發(fā)送二進(jìn)制幀,這種二進(jìn)制幀的「雙向傳輸?shù)男蛄小?/strong>,也叫做流(Stream)。HTTP/2 用來在「一個 TCP 連接上來進(jìn)行多個數(shù)據(jù)幀的通信」,這就是多路復(fù)用的概念。

          可能你會有一個疑問,既然是亂序首發(fā),那最后如何來處理這些亂序的數(shù)據(jù)幀呢?

          首先要聲明的是,所謂的亂序,指的是不同 ID 的 Stream 是亂序的,但同一個 Stream ID 的幀一定是按順序傳輸?shù)摹6M(jìn)制幀到達(dá)后對方會將 Stream ID 相同的二進(jìn)制幀組裝成完整的請求報文響應(yīng)報文。當(dāng)然,在二進(jìn)制幀當(dāng)中還有其他的一些字段,實(shí)現(xiàn)了優(yōu)先級和流量控制等功能,我們放到下一節(jié)再來介紹。

          「服務(wù)器推送」

          另外值得一說的是 HTTP/2 的服務(wù)器推送(Server Push)。在 HTTP/2 當(dāng)中,服務(wù)器已經(jīng)不再是完全被動地接收請求,響應(yīng)請求,它「也能新建 stream 來給客戶端發(fā)送消息」,當(dāng) TCP 連接建立之后,比如瀏覽器請求一個 HTML 文件,服務(wù)器就可以在返回 HTML 的基礎(chǔ)上,將 HTML 中引用到的其他資源文件一起返回給客戶端,減少客戶端的等待

          「總結(jié)」

          當(dāng)然,HTTP/2 新增那么多的特性,是不是 HTTP 的語法要重新學(xué)呢?不需要,HTTP/2 完全兼容之前 HTTP 的語法和語義,如「請求頭、URI、狀態(tài)碼、頭部字段」都沒有改變,完全不用擔(dān)心。同時,在安全方面,HTTP 也支持 TLS,并且現(xiàn)在主流的瀏覽器都公開只支持加密的 HTTP/2, 因此你現(xiàn)在能看到的 HTTP/2 也基本上都是跑在TLS 上面的了。最后放一張分層圖給大家參考:

          HTTP/2 中的二進(jìn)制幀是如何設(shè)計的?

          「幀結(jié)構(gòu)」

          HTTP/2 中傳輸?shù)膸Y(jié)構(gòu)如下圖所示:每個幀分為「幀頭」「幀體」。先是三個字節(jié)的幀長度,這個長度表示的是幀體的長度。

          然后是幀類型,大概可以分為「數(shù)據(jù)幀」「控制幀」兩種。數(shù)據(jù)幀用來存放 HTTP 報文,控制幀用來管理的傳輸。

          接下來的一個字節(jié)是「幀標(biāo)志」,里面一共有 8 個標(biāo)志位,常用的有 「END_HEADERS」表示頭數(shù)據(jù)結(jié)束,「END_STREAM」表示單方向數(shù)據(jù)發(fā)送結(jié)束。

          后 4 個字節(jié)是Stream ID, 也就是流標(biāo)識符,有了它,接收方就能從亂序的二進(jìn)制幀中選擇出 ID 相同的幀,按順序組裝成請求/響應(yīng)報文。

          「流的狀態(tài)變化」

          從前面可以知道,在 HTTP/2 中,所謂的,其實(shí)就是二進(jìn)制幀的「雙向傳輸?shù)男蛄小?/strong>。那么在 HTTP/2 請求和響應(yīng)的過程中,流的狀態(tài)是如何變化的呢?HTTP/2 其實(shí)也是借鑒了 TCP 狀態(tài)變化的思想,根據(jù)幀的標(biāo)志位來實(shí)現(xiàn)具體的狀態(tài)改變。這里我們以一個普通的請求-響應(yīng)過程為例來說明:

          最開始兩者都是空閑狀態(tài),當(dāng)客戶端發(fā)送Headers幀后,開始分配Stream ID, 此時「客戶端的流打開」, 「服務(wù)端接收之后服務(wù)端的流也打開」,兩端的流都打開之后,就可以互相傳遞數(shù)據(jù)幀和控制幀了。

          當(dāng)客戶端要關(guān)閉時,向服務(wù)端發(fā)送END_STREAM幀,進(jìn)入「半關(guān)閉狀態(tài)」, 這個時候客戶端只能接收數(shù)據(jù),而不能發(fā)送數(shù)據(jù)

          服務(wù)端收到這個END_STREAM幀后也進(jìn)入半關(guān)閉狀態(tài),不過此時服務(wù)端的情況是「只能發(fā)送數(shù)據(jù),而不能接收數(shù)據(jù)」。隨后服務(wù)端也向客戶端發(fā)送END_STREAM幀,表示「數(shù)據(jù)發(fā)送完畢,雙方進(jìn)入關(guān)閉狀態(tài)」

          如果下次要開啟新的流,流 ID 需要自增,直到上限為止,到達(dá)上限后開一個新的 TCP 連接重頭開始計數(shù)。由于流 ID 字段長度為 4 個字節(jié),最高位又被保留,因此范圍是 0 ~ 2的 31 次方,大約 21 億個。

          「流的特性」

          剛剛談到了流的狀態(tài)變化過程,這里順便就來總結(jié)一下流傳輸?shù)奶匦?

          • 并發(fā)性。一個 HTTP/2 連接上可以同時發(fā)多個幀,這一點(diǎn)和 HTTP/1 不同。這也是實(shí)現(xiàn)「多路復(fù)用」的基礎(chǔ)。
          • 自增性。流 ID 是不可重用的,而是會按順序遞增,達(dá)到上限之后又新開 TCP 連接從頭開始。
          • 雙向性。客戶端和服務(wù)端都可以創(chuàng)建流,互不干擾,雙方都可以作為發(fā)送方或者接收方
          • 可設(shè)置優(yōu)先級。可以設(shè)置數(shù)據(jù)幀的優(yōu)先級,讓服務(wù)端先處理重要資源,優(yōu)化用戶體驗(yàn)。

          自己搭的博客目的是什么?主要寫的內(nèi)容是?

          愛折騰,搭建了一個美化版的博客,主要整合前端相關(guān)知識點(diǎn)

          詢問了大學(xué)里面圖像處理課程

          博客專欄里面有圖像處理相關(guān)博文,問到了這個點(diǎn)

          如何學(xué)習(xí)前端(或者說是如何學(xué)習(xí)計算機(jī)領(lǐng)域知識)

          先學(xué)好本科基礎(chǔ)知識,鍛煉思維,然后經(jīng)常逛一些博客網(wǎng)站,例如掘金,學(xué)習(xí)優(yōu)秀的人是怎樣學(xué)習(xí)的,看一些書籍,比如js紅寶書。另外,常逛一些b站學(xué)習(xí)一些老師教授的課程。

          對未來的職業(yè)規(guī)劃

          熱愛前端,干到退休(苦笑)往架構(gòu)方向發(fā)展,然后面試官提到了是否未來會參與算法、人工智能相關(guān)領(lǐng)域。我非常贊同,也提了nodejs目前比較火熱,后續(xù)也會繼續(xù)學(xué)習(xí) koa、egg框架,總之,懂的越多,不懂得更多,一直學(xué)習(xí)~

          有什么問題可以詢問

          了解部門主要業(yè)務(wù)工作,了解部門規(guī)模

          結(jié)果

          感受:問題能想起來的暫時這么多,一面體驗(yàn)還是不錯的,又增加了一些知識,還能和面試官交流一下大學(xué)學(xué)習(xí)課程,挺好的。但最后還是因?yàn)橹R掌握程度與崗位匹配度,主要是崗位匹配度吧,達(dá)摩院大家懂得都懂...

          小獅子有話說

          我是小獅子團(tuán)隊的【一百個Chocolate】,全網(wǎng)同名,周更的前端博主,分享一些前端技術(shù)干貨與程序員生活日常,歡迎各位小伙伴的持續(xù)關(guān)注,一起變優(yōu)秀~

          本次給大家?guī)硪徊ㄐ「@P(guān)注公眾號【小獅子前端】后臺回復(fù) 0612 即可參與,現(xiàn)在參與人數(shù)也不多,中獎幾率特別大!確定不來參與嘛?



          學(xué)如逆水行舟,不進(jìn)則退

          點(diǎn)擊【在看】紅包福利就多一次~

          瀏覽 53
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                    <th id="afajh"><progress id="afajh"></progress></th>
                    啊V在线视频 | a天堂视频 | 成人抽插视频 | 成人国产经典视频 | 国产美女被干网站 |