阿里前端攻城獅們寫了一份前端面試題答案

話說一週前,我發了這樣一條沸點:前端

因而我真的就建羣收集了題目,和團隊的同事一塊兒寫答案,咱們也不圖什麼,就是想作一件有意義的事情,如今我整理了下咱們的回答,有的不必定就是很是具體的回答,但也提供了思路和參考資料,你們看看是否還有什麼補充的,或者面試時遇到的問題,也歡迎補充android

[高德一面]一個 tcp 鏈接能發幾個 http 請求?(LVYOU)

若是是 HTTP 1.0 版本協議,通常狀況下,不支持長鏈接,所以在每次請求發送完畢以後,TCP 鏈接即會斷開,所以一個 TCP 發送一個 HTTP 請求,可是有一種狀況能夠將一條 TCP 鏈接保持在活躍狀態,那就是經過 Connection 和 Keep-Alive 首部,在請求頭帶上 Connection: Keep-Alive,而且能夠經過 Keep-Alive 通用首部中指定的,用逗號分隔的選項調節 keep-alive 的行爲,若是客戶端和服務端都支持,那麼其實也能夠發送多條,不過此方式也有限制,能夠關注《HTTP 權威指南》4.5.5 節對於 Keep-Alive 鏈接的限制和規則。ios

而若是是 HTTP 1.1 版本協議,支持了長鏈接,所以只要 TCP 鏈接不斷開,即可以一直髮送 HTTP 請求,持續不斷,沒有上限; 一樣,若是是 HTTP 2.0 版本協議,支持多用複用,一個 TCP 鏈接是能夠併發多個 HTTP 請求的,一樣也是支持長鏈接,所以只要不斷開 TCP 的鏈接,HTTP 請求數也是能夠沒有上限地持續發送git

[騰訊一面]Virtual Dom 的優點在哪裏?(B_Cornelius)

「Virtual Dom 的優點」其實這道題目面試官更想聽到的答案不是上來就說「直接操做/頻繁操做 DOM 的性能差」,若是 DOM 操做的性能如此不堪,那麼 jQuery 也不至於活到今天。因此面試官更想聽到 VDOM 想解決的問題以及爲何頻繁的 DOM 操做會性能差。es6

首先咱們須要知道:github

DOM 引擎、JS 引擎 相互獨立,但又工做在同一線程(主線程) JS 代碼調用 DOM API 必須 掛起 JS 引擎、轉換傳入參數數據、激活 DOM 引擎,DOM 重繪後再轉換可能有的返回值,最後激活 JS 引擎並繼續執行如有頻繁的 DOM API 調用,且瀏覽器廠商不作「批量處理」優化, 引擎間切換的單位代價將迅速積累若其中有強制重繪的 DOM API 調用,從新計算佈局、從新繪製圖像會引發更大的性能消耗。web

其次是 VDOM 和真實 DOM 的區別和優化:面試

  1. 虛擬 DOM 不會立馬進行排版與重繪操做
  2. 虛擬 DOM 進行頻繁修改,而後一次性比較並修改真實 DOM 中須要改的部分,最後在真實 DOM 中進行排版與重繪,減小過多DOM節點排版與重繪損耗
  3. 虛擬 DOM 有效下降大面積真實 DOM 的重繪與排版,由於最終與真實 DOM 比較差別,能夠只渲染局部

[字節跳動] common.js 和 es6 中模塊引入的區別? (霍小葉)

CommonJS 是一種模塊規範,最初被應用於 Nodejs,成爲 Nodejs 的模塊規範。運行在瀏覽器端的 JavaScript 因爲也缺乏相似的規範,在 ES6 出來以前,前端也實現了一套相同的模塊規範 (例如: AMD),用來對前端模塊進行管理。自 ES6 起,引入了一套新的 ES6 Module 規範,在語言標準的層面上實現了模塊功能,並且實現得至關簡單,有望成爲瀏覽器和服務器通用的模塊解決方案。但目前瀏覽器對 ES6 Module 兼容還不太好,咱們平時在 Webpack 中使用的 export 和 import,會通過 Babel 轉換爲 CommonJS 規範。在使用上的差異主要有:小程序

  1. CommonJS 模塊輸出的是一個值的拷貝,ES6 模塊輸出的是值的引用。
  2. CommonJS 模塊是運行時加載,ES6 模塊是編譯時輸出接口。
  3. CommonJs 是單個值導出,ES6 Module能夠導出多個
  4. CommonJs 是動態語法能夠寫在判斷裏,ES6 Module 靜態語法只能寫在頂層
  5. CommonJs 的 this 是當前模塊,ES6 Module的 this 是 undefined

[未知] cookie token 和 session 的區別(Roxannej)

這道題絕對不是你回答的點越多就越好。這道題考察的是你對瀏覽器緩存知識的理解程度,因此你應該回答的是 Cookie、 Session、Token 的產生背景、原理、有什麼問題,在回答這個的基礎上把差異講出來。把這些東西答出本質,再加點裝逼的東西,再故意拓展講到你準備的其餘內容纔是答好這道題的關鍵,而要理解好這些東西,其實一兩天就夠了。關於 Cookie,最近還發生了 Chrome80 屏蔽第三方 Cookie 的事件,若是真的問到這個問題,講到這件事情妥妥的加分項,前提是你對這件事情也有比較深刻的瞭解。關於 Cookie 和這件事情 我寫了篇文章 github.com/mqyqingfeng… 能夠看一下。api

[頭條]如何選擇圖片格式,例如 png, webp(B_Cornelius)

圖片格式

壓縮方式

透明度

動畫

瀏覽器兼容

適應場景

JPEG

有損壓縮

不支持

不支持

全部

複雜顏色及形狀、尤爲是照片

GIF

無損壓縮

支持

支持

全部

簡單顏色,動畫

PNG

無損壓縮

支持

不支持

全部

須要透明時

APNG

無損壓縮

支持

支持

FirefoxSafariiOS Safari

須要半透明效果的動畫

WebP

有損壓縮

支持

支持

ChromeOperaAndroid ChromeAndroid Browser

複雜顏色及形狀瀏覽器平臺可預知

SVG

無損壓縮

支持

支持

全部(IE8以上)

簡單圖形,須要良好的放縮體驗須要動態控制圖片特效

[未知]首屏和白屏時間如何計算?(jhinnn)

首屏時間的計算,能夠由 Native WebView 提供的相似 onload 的方法實現,在 ios 下對應的是 webViewDidFinishLoad,在 android 下對應的是onPageFinished事件。

白屏的定義有多種。能夠認爲「沒有任何內容」是白屏,能夠認爲「網絡或服務異常」是白屏,能夠認爲「數據加載中」是白屏,能夠認爲「圖片加載不出來」是白屏。場景不一樣,白屏的計算方式就不相同。

方法1:當頁面的元素數小於x時,則認爲頁面白屏。好比「沒有任何內容」,能夠獲取頁面的DOM節點數,判斷DOM節點數少於某個閾值X,則認爲白屏。 方法2:當頁面出現業務定義的錯誤碼時,則認爲是白屏。好比「網絡或服務異常」。 方法3:當頁面出現業務定義的特徵值時,則認爲是白屏。好比「數據加載中」。

[未知]小程序和 H5 有什麼區別?(張慈仁)

  1. 渲染方式與 H5 不一樣,小程序通常是經過 Native 原生渲染的,可是小程序同時也支持 web 渲染,若是使用 web 渲染的方式,咱們須要初始化一個WebView 組件,而後在 WebView 中加載 H5 頁面;

因此當咱們開發一個小程序時,一般會使用 hybrid 的方式,即會根據具體狀況選擇部分功能用小程序原生的代碼來開發,部分功能經過 WebView 加載 H5 頁面來實現。Native 與 Web 渲染混合使用,以實現項目的最優解;

這裏值得注意的是,小程序下,native 方式一般狀況下性能要優於 web 方式。

  1. 小程序特有的雙線程設計。 H5 下咱們全部資源一般都會打到一個 bundle.js 文件裏(不考慮分包加載),而小程序編譯後的結果會有兩個bundle,index.js封裝的是小程序項目的 view 層,以及 index.worker.js 封裝的是項目的業務邏輯,在運行時,會有兩條線程來分別處理這兩個bundle,一個是主渲染線程,它負責加載並渲染 index.js 裏的內容,另一個是 Service Worker線 程,它負責執行 index.worker.js 裏封裝的業務邏輯,這裏面會有不少對底層api調用。

[未知]如何判斷 0.1 + 0.2 與 0.3 相等?(紅白)

做爲一道面試題,我以爲重要的是要講出一點其餘人通常不會答出來的深度。像這道題,能夠從原理和解決方案兩個地方做爲答題點,最好在編一個案例。大體講本身遇到過這個問題,因而很好奇深刻研究了一下,發現是浮點數精度致使……原理怎樣怎樣……而後又看了業界的庫的源碼,而後怎樣怎樣解決。

關於原理,我專門寫了一篇文章 github.com/mqyqingfeng… 來解釋,實際回答的時候,我以爲答出來

  1. 非是 ECMAScript 獨有
  2. IEEE754 標準中 64 位的儲存格式,好比 11 位存偏移值
  3. 其中涉及的三次精度丟失

就已經 OK 了。

再講解決方案,這個能夠直接搜索到,各類方案都瞭解一下,比較一下優劣,還能夠參考業界的一些庫的實現,好比 math.js,不過相關的我並無看過……

若是還有精力的話,能夠從加法再拓展講講超出安全值的數字的計算問題。

因此我以爲一能回答出底層實現,二能回答出多種解決方案的優劣,三能拓展講講 bignum 的處理,就是一個很是不錯的回答了。

[騰訊二面]瞭解v8引擎嗎,一段js代碼如何執行的(B_Cornelius)

在執行一段代碼時,JS 引擎會首先建立一個執行棧

而後JS引擎會建立一個全局執行上下文,並push到執行棧中, 這個過程JS引擎會爲這段代碼中全部變量分配內存並賦一個初始值(undefined),在建立完成後,JS引擎會進入執行階段,這個過程JS引擎會逐行的執行代碼,即爲以前分配好內存的變量逐個賦值(真實值)。

若是這段代碼中存在function的聲明和調用,那麼JS引擎會建立一個函數執行上下文,並push到執行棧中,其建立和執行過程跟全局執行上下文同樣。但有特殊狀況,即當函數中存在對其它函數的調用時,JS引擎會在父函數執行的過程當中,將子函數的全局執行上下文push到執行棧,這也是爲何子函數可以訪問到父函數內所聲明的變量。

還有一種特殊狀況是,在子函數執行的過程當中,父函數已經return了,這種狀況下,JS引擎會將父函數的上下文從執行棧中移除,與此同時,JS引擎會爲還在執行的子函數上下文建立一個閉包,這個閉包裏保存了父函數內聲明的變量及其賦值,子函數仍然可以在其上下文中訪問並使用這邊變量/常量。當子函數執行完畢,JS引擎纔會將子函數的上下文及閉包一併從執行棧中移除。

最後,JS引擎是單線程的,那麼它是如何處理高併發的呢?即當代碼中存在異步調用時JS是如何執行的。好比setTimeout或fetch請求都是non-blocking的,當異步調用代碼觸發時,JS引擎會將須要異步執行的代碼移出調用棧,直到等待到返回結果,JS引擎會當即將與之對應的回調函數push進任務隊列中等待被調用,當調用(執行)棧中已經沒有須要被執行的代碼時,JS引擎會馬上將任務隊列中的回調函數逐個push進調用棧並執行。這個過程咱們也稱之爲事件循環。

附言:須要更深刻的瞭解JS引擎,必須理解幾個概念,執行上下文,閉包,做用域,做用域鏈,以及事件循環。建議去網上多看看相關文章,這裏推薦一篇很是精彩的博客,對於JS引擎的執行作了圖形化的說明,更加便於理解。

相關文章
相關標籤/搜索