備案個人可以做視頻網(wǎng)站嗎網(wǎng)站關(guān)鍵詞排名優(yōu)化客服
校招前端面試常見問題【4】——網(wǎng)絡(luò)及瀏覽器
1、網(wǎng)絡(luò)相關(guān)
Q:請簡述一下 HTTP 協(xié)議,以及 HTTP1.0/1.1/2.0/3.0 的區(qū)別?
HTTP 協(xié)議:超文本傳輸協(xié)議,使用 TCP/IP 協(xié)議傳輸數(shù)據(jù)。是一個應(yīng)用層的協(xié)議。
HTTP1.0:HTTP 1.0 規(guī)定瀏覽器與服務(wù)器只保持短暫的連接,瀏覽器的每次請求都需要與服務(wù)器建立一個 TCP 連接,服務(wù)器完成請求處理后立即斷開 TCP 連接,服務(wù)器不跟蹤每個客戶也不記錄過去的請求。因此 HTTP 1.0 存在很大的性能缺陷——當(dāng)訪問一個包含有許多資源文件的網(wǎng)頁時,每次請求和響應(yīng)都需要建立一個單獨的連接,每次連接只是傳輸一個文檔和圖像,請求之間完全分離。即使圖像文件都很小,但是客戶端和服務(wù)器端每次建立和關(guān)閉連接卻是一個相對比較費時的過程,會嚴重影響到性能。
HTTP 1.1:支持長連接的 HTTP 協(xié)議,在一個 TCP 連接上可以傳送多個 HTTP 請求和響應(yīng)。一個包含有許多圖像的網(wǎng)頁文件的多個請求和應(yīng)答可以在一個連接中傳輸,但每個單獨的網(wǎng)頁文件的請求和應(yīng)答仍然需要使用各自的連接。
HTTP2.0:支持多路復(fù)用的 HTTP 協(xié)議。 HTTP 2.0 允許同時通過單一的 HTTP 2.0 連接發(fā)起多重的請求-響應(yīng)消息。所有通信都在一個連接上完成,這個連接可以承載任意數(shù)量的雙向數(shù)據(jù)流。由于 TCP 有慢啟動的特點,如果 HTTP 連接很多,就會十分低效。HTTP/2 通過讓所有數(shù)據(jù)流共用同一個連接,可以更有效地使用 TCP 連接。
HTTP3.0:也就是 QUIC (quick udp internet connection)協(xié)議,是由 google 提出的使用 udp 進行多路并發(fā)傳輸?shù)膮f(xié)議。通過使用 UDP 協(xié)議,省去了 TCP 握手和慢啟動的時間,擁有極低的建立連接延時。
Q:請簡述一下 HTTPS 協(xié)議?
HTTPS 在傳輸數(shù)據(jù)之前需要客戶端與服務(wù)器之間進行一次握手,在握手過程中將確立雙方加密傳輸數(shù)據(jù)的密碼信息。TLS/SSL 協(xié)議不僅僅是一套加密傳輸?shù)膮f(xié)議,TLS/SSL 中使用了非對稱加密,對稱加密以及 HASH 算法。
握手過程的簡單描述如下:
1、客戶端將自己支持的加密規(guī)則發(fā)送給服務(wù)器。
2、網(wǎng)站從中選出加密算法和 HASH 算法,將證書發(fā)回給瀏覽器。證書里面包含了網(wǎng)站地址,加密公鑰,以及證書的頒發(fā)機構(gòu)等信息。
3、獲得證書之后客戶端要做以下工作:
a) 驗證證書(頒發(fā)證書的機構(gòu)是否合法,證書中包含的網(wǎng)站地址是否與正在訪問的地址一致等)。
b) 如果通過驗證,瀏覽器會生成一串隨機數(shù)的密碼,并用證書中提供的公鑰加密
c) 計算握手信息的 HASH,然后將握手信息也一并加密,最后將所有信息發(fā)送給網(wǎng)站。
4、網(wǎng)站接收瀏覽器發(fā)來的數(shù)據(jù)之后要做以下的操作:
a) 使用自己的私鑰將信息解密取出密碼,使用密碼解密握手消息,判斷 HASH 是否一致。
b) 計算握手的 HASH,并使用密碼加密握手消息,發(fā)送給瀏覽器。
5、瀏覽器解密并計算握手消息的 HASH,如果與服務(wù)端發(fā)來的 HASH 一致,此時握手過程結(jié)束,之后所有的通信數(shù)據(jù)將由之前瀏覽器生成的隨機密碼進行加密。
Q:請簡述一下 HTTP 協(xié)議中的緩存策略?
HTTP 的緩存策略有兩種:強緩存和協(xié)商緩存。
強緩存是利用 http 頭中的 Expires 和 Cache-Control 兩個字段來控制的,用來表示資源的緩存時間。強緩存中,普通刷新會忽略它,但不會清除它,需要強制刷新。
例如:
cache-control: max-age=691200 (HTTP 1.1)
expires: Fri, 14 Apr 2017 10:47:02 GMT (HTTP 1.0)
協(xié)商緩存主要涉及到兩個 header 字段:E-Tag 和 Last-Modified。每次讀取數(shù)據(jù)時客戶單都會跟服務(wù)器通信,并且會增加緩存標識。在第一次請求服務(wù)器時,服務(wù)器會返回資源,并且返回一個資源的緩存標識,一起存到瀏覽器的緩存數(shù)據(jù)庫。當(dāng)?shù)诙握埱筚Y源時,瀏覽器會首先將緩存標識發(fā)送給服務(wù)器,服務(wù)器拿到標識后判斷標識是否匹配,如果不匹配,表示資源有更新,服務(wù)器會將新數(shù)據(jù)和新的緩存標識一起返回到瀏覽器;如果緩存標識匹配,表示資源沒有更新,并且返回 304,瀏覽器就讀取本地緩存服務(wù)器中的數(shù)據(jù)。
例如:
E-Tag: 123456abcd
Last-Modify: Thu,31 Dec 2037 23:59:59 GMT。
2、瀏覽器相關(guān)
Q:請列舉一下你知道的瀏覽器內(nèi)核的種類?
Trident:IE6、IE7、IE8、IE9、IE10、360 瀏覽器和獵豹瀏覽器。
Gecko:firefox 瀏覽器。
Blink:opera 瀏覽器。
Webkit:sarfari 和 chrome 瀏覽器。
Q:瀏覽器內(nèi)核中的有哪些線程?
內(nèi)核主要分成五部分:
GUI 渲染線程:負責(zé)渲染瀏覽器界面,解析 HTML,CSS,構(gòu)建渲染樹,布局和繪制等。當(dāng)界面需要重繪或回流時,該線程就會執(zhí)行。注意,GUI 渲染線程與 JS 引擎線程是互斥的,
JS 引擎線程:解析和執(zhí)行 javascript。
事件觸發(fā)線程:歸屬于瀏覽器而不是 JS 引擎,用來控制事件循環(huán)。
定時器觸發(fā)線程:setInterval 與 setTimeout 所在線程。瀏覽器定時計數(shù)器并不是由 JavaScript 引擎計數(shù)的,因此通過單獨線程來計時并觸發(fā)定時(計時完畢后,添加到事件隊列中,等待 JS 引擎空閑后執(zhí)行)。
異步 http 請求線程:在 XMLHttpRequest 在連接后是通過瀏覽器新開一個線程請求,將檢測到狀態(tài)變更時,如果設(shè)置有回調(diào)函數(shù),異步線程就產(chǎn)生狀態(tài)變更事件,將這個回調(diào)再放入事件隊列中,再由 JavaScript 引擎執(zhí)行。
Q:請簡述一下瀏覽器的渲染流程?
接收到文檔后,渲染引擎會對 HTML 文檔進行解析生成 DOM 樹、對 CSS 文件進行解析生成布局樹;同時執(zhí)行頁面中的 JavaScript 代碼;最終根據(jù) DOM 樹和布局樹,計算樣式生成渲染樹,渲染樹中,只會包含即將顯示在頁面中的元素及其樣式信息(如 head 元素、display 為 hidden 的元素就不會包含在渲染樹中);根據(jù)渲染樹需要進行布局來計算每個元素在頁面上的位置;
接下來渲染引擎開始進行繪制(paint),這一步分為若干階段:
1、根據(jù)渲染樹繪制每層的各個元素。
2、柵格化繪制出的圖像(將渲染樹中的節(jié)點轉(zhuǎn)換成屏幕上的實際像素)
3、顯示在屏幕上。
每一層的繪制是由瀏覽器來完成的;最后的合成是由 GPU 來完成;而柵格化過程取決于瀏覽器的設(shè)置,chrome 默認開啟 GPU 柵格化,否則由 CPU 進行。
Q:瀏覽器從輸入請求到呈現(xiàn)頁面有哪幾步?
1、URL 解析
2、DNS 查詢
3、TCP 連接
4、處理請求
5、接受響應(yīng)
6、渲染頁面
Q:localstorage、sessionstorage 的區(qū)別,以及使用場景是什么?
localStorage:生命周期是永久的,關(guān)閉頁面或瀏覽器之后 localStorage 中的數(shù)據(jù)也不會消失。localStorage 除非主動刪除數(shù)據(jù),否則數(shù)據(jù)永遠不會消失(只會存儲 string)。
sessionStorage:生命周期是在僅在當(dāng)前會話下有效。sessionStorage 引入了一個“瀏覽器窗口”的概念,sessionStorage 是在同源的窗口中始終存在的數(shù)據(jù)。只要這個瀏覽器窗口沒有關(guān)閉,即使刷新頁面或者進入同源另一個頁面,數(shù)據(jù)依然存在。但是 sessionStorage 在關(guān)閉了瀏覽器窗口后就會被銷毀。同時獨立的打開同一個窗口同一個頁面,sessionStorage 也是不一樣的。
使用方法:
window.localStorage
window.sessionStorage
API:
setItem(key, value) // 保存數(shù)據(jù),以鍵值對的方式儲存信息。
getItem(key) // 獲取數(shù)據(jù),將鍵值傳入,即可獲取到對應(yīng)的 value 值。
removeItem(key) // 刪除單個數(shù)據(jù),根據(jù)鍵值移除對應(yīng)的信息。
clear() // 刪除所有的數(shù)據(jù)
key(index) // 獲取某個索引的 key