前端20個真正靈魂拷問,吃透這些你就是中級前端工程師 【上篇】

clipboard.png

網上參差不棄的面試題,本文由淺入深,讓你在作面試官的時候,可以辨別出面試者是否是真的有點東西,也能讓你去面試中級前端工程師更有底氣。可是切記把背誦面試題當成了你的惟一求職方向

另外歡迎你們加入咱們的前端交流二羣~,裏面不少小姐姐哦,下篇將是很是硬核的源碼,原理,本身編寫框架和庫等,若是感受寫得不錯,能夠關注給個starjavascript

clipboard.png

越是開放性的題目,更能體現回答者的水平,一場好的面試,不只能發現面試者的不足,也能找到他的閃光點,還能提高面試官自身的技術html

1.CssHtml合併在第一個題目,請簡述你讓一個元素在窗口中消失以及垂直水平居中的方法,還有Flex佈局的理解

標準答案:百度上固然不少,這裏不作闡述,好的回答思路是:前端

  • 元素消失的方案先列出來, display:nonevisibility: hidden;的區別,拓展到vue框架的v-ifv-show的區別,能夠搭配迴流和重繪來說解

迴流必將引發重繪,重繪不必定會引發迴流

迴流(Reflow):

Render Tree中部分或所有元素的尺寸、結構、或某些屬性發生改變時,瀏覽器從新渲染部分或所有文檔的過程稱爲迴流
  • 下面內容會致使迴流:vue

    • 頁面首次渲染
    • 瀏覽器窗口大小發生改變
    • 元素尺寸或位置發生改變
    • 元素內容變化(文字數量或圖片大小等等)
    • 元素字體大小變化
    • 添加或者刪除可見的DOM元素
    • 激活CSS僞類(例如::hover)
    • 查詢某些屬性或調用某些方法
  • 一些經常使用且會致使迴流的屬性和方法:java

    • clientWidth、clientHeight、clientTop、clientLeft
    • offsetWidth、offsetHeight、offsetTop、offsetLeft
    • scrollWidth、scrollHeight、scrollTop、scrollLeft
    • scrollIntoView()、scrollIntoViewIfNeeded()
    • getComputedStyle()
    • getBoundingClientRect()
    • scrollTo()

重繪

當頁面中元素樣式的改變並不影響它在文檔流中的位置時(例如:color、background-color、visibility等),瀏覽器會將新樣式賦予給元素並從新繪製它,這個過程稱爲重繪。

性能影響對比:

clipboard.png

原文出處,感謝做者web

  • 列出元素垂直居中的方案,以及各類方案的缺陷

16種居中方案,感謝做者面試

  • 講出flex經常使用的場景,以及flex 1作了什麼

阮一峯老師的Flex佈局算法

上面的問題若是答得很是好,在重繪和迴流這塊要下大功夫。這點是前端性能優化的基礎,而性能優化是前端最重要的核心基礎技能點,也是面試官最看中的基礎之一

2.你對This瞭解嗎,有本身實現過call,apply,bind嗎?

50行javaScript代碼實現call,apply,bind編程

這是一個很基礎的技能點,考察你對閉包,函數調用的理解程度,我感受我寫得比較簡單容易懂segmentfault

3.如何減小重繪和迴流的次數:

clipboard.png

4.你對前端的異步編程有哪些瞭解呢

這個題目若是回答很是完美,那麼能夠判斷這我的已經脫離了初級前端工程師,前端的核心就是異步編程,這個題目也是體現前端工程師基礎是否紮實的最重要依據。

仍是老規矩,從易到難吧

傳統的定時器,異步編程:

setTimeout(),setInterval()等。

缺點:當同步的代碼比較多的時候,不肯定異步定時器的任務時候能在指定的時間執行。

例如:

在第100行執行代碼 setTimeout(()=>{console.log(1)},1000)//1s後執行裏面函數

可是後面可能有10000行代碼+不少計算的任務,例如循環遍歷,那麼1s後就沒法輸出console.log(1)

可能要到2s甚至更久

setInterval跟上面同理 當同步代碼比較多時,不確保每次能在同樣的間隔執行代碼,

若是是動畫,那麼可能會掉幀

ES6的異步編程:

promise generator async
new promise((resolve,reject)=>{ resolve() }).then()....
 缺點: 仍然沒有擺脫回掉函數,雖然改善了回掉地獄
 
 generator函數 調用next()執行到下一個yeild的代碼內容,若是傳入參數則做爲上一個

`yield`的
返回值
 缺點:不夠自動化

 async await 
 只有async函數內部能夠用await,將異步代碼變成同步書寫,可是因爲async函數自己返回一個
promise,也很容易產生async嵌套地獄

requestAnimationFramerequestIdleCallback

傳統的 javascript 動畫是經過定時器 setTimeout 或者 setInterval 實現的。可是定時器動畫一直存在兩個問題

第一個就是動畫的循時間環間隔很差肯定,設置長了動畫顯得不夠平滑流暢,設置短了瀏覽器的重繪頻率會達到瓶頸,推薦的最佳循環間隔是17ms(大多數電腦的顯示器刷新頻率是60Hz,1000ms/60);

第二個問題是定時器第二個時間參數只是指定了多久後將動畫任務添加到瀏覽器的UI線程隊列中,若是UI線程處於忙碌狀態,那麼動畫不會馬上執行。爲了解決這些問題,H5 中加入了 requestAnimationFrame以及requestIdleCallback

requestAnimationFrame 會把每一幀中的全部 DOM 操做集中起來,在一次重繪或迴流中就完成,而且重繪或迴流的時間間隔牢牢跟隨瀏覽器的刷新頻率

在隱藏或不可見的元素中,requestAnimationFrame 將不會進行重繪或迴流,這固然就意味着更少的 CPU、GPU 和內存使用量

requestAnimationFrame 是由瀏覽器專門爲動畫提供的 API,在運行時瀏覽器會自動優化方法的調用,而且若是頁面不是激活狀態下的話,動畫會自動暫停,有效節省了 CPU 開銷

性能對比:

clipboard.png

requestAnimationFrame的回調會在每一幀肯定執行,屬於高優先級任務,而requestIdleCallback的回調則不必定,屬於低優先級任務。

咱們所看到的網頁,都是瀏覽器一幀一幀繪製出來的,一般認爲FPS爲60的時候是比較流暢的,而FPS爲個位數的時候就屬於用戶能夠感知到的卡頓了,那麼在一幀裏面瀏覽器都要作哪些事情呢,以下所示:

clipboard.png

圖中一幀包含了用戶的交互、js的執行、以及requestAnimationFrame的調用,佈局計算以及頁面的重繪等工做。

假如某一幀裏面要執行的任務很少,在不到16ms(1000/60)的時間內就完成了上述任務的話,那麼這一幀就會有必定的空閒時間,這段時間就剛好能夠用來執行requestIdleCallback的回調,以下圖所示:

clipboard.png

5.簡述瀏覽器的EventloopNode.jsEventloop

瀏覽器的EventLoop

clipboard.png

不想解釋太多,看圖

Node.jsEventLoop

clipboard.png

特別提示:網上大部分Node.jsEventLoop的面試題,都會有BUG,代碼量和計算量太少,極可能尚未執行到微任務的代碼,定時器就到時間被執行了

6.閉包與V8垃圾回收機制:

JS 的垃圾回收機制的基本原理是:

找出那些再也不繼續使用的變量,而後釋放其佔用的內存,垃圾收集器會按照固定的時間間隔週期性地執行這一操做。

V8 的垃圾回收策略主要基於分代式垃圾回收機制,在 V8 中,將內存分爲新生代和老生代,新生代的對象爲存活時間較短的對象,老生代的對象爲存活事件較長或常駐內存的對象。

clipboard.png

V8 堆的總體大小等於新生代所用內存空間加上老生代的內存空間,而只能在啓動時指定,意味着運行時沒法自動擴充,若是超過了極限值,就會引發進程出錯。

Scavenge 算法

在分代的基礎上,新生代的對象主要經過 Scavenge 算法進行垃圾回收,在 Scavenge 具體實現中,主要採用了一種複製的方式的方法—— Cheney 算法。

Cheney 算法將堆內存一分爲二,一個處於使用狀態的空間叫 From 空間,一個處於閒置狀態的空間稱爲 To 空間。分配對象時,先是在 From 空間中進行分配。

當開始進行垃圾回收時,會檢查 From 空間中的存活對象,將其複製到 To 空間中,而非存活對象佔用的空間將會被釋放。完成複製後,From 空間和 To 空間的角色發生對換。

clipboard.png
當一個對象通過屢次複製後依然存活,他將會被認爲是生命週期較長的對象,隨後會被移動到老生代中,採用新的算法進行管理。

還有一種狀況是,若是複製一個對象到 To 空間時,To 空間佔用超過了 25%,則這個對象會被直接晉升到老生代空間中。

標記-清除和標記-整理算法

對於老生代中的對象,主要採用標記-清除和標記-整理算法。標記-清除 和前文提到的標記同樣,與 Scavenge 算法相比,標記清除不會將內存空間劃爲兩半,標記清除在標記階段會標記活着的對象,而在內存回收階段,它會清除沒有被標記的對象。

而標記整理是爲了解決標記清除後留下的內存碎片問題。

增量標記(Incremental Marking)算法

前面的三種算法,都須要將正在執行的 JavaScript 應用邏輯暫停下來,待垃圾回收完畢後再恢復。這種行爲叫做「全停頓」(stop-the-world)。

在 V8 新生代的分代回收中,只收集新生代,而新生代一般配置較小,且存活對象較少,因此全停頓的影響不大,而老生代就相反了。

爲了下降所有老生代全堆垃圾回收帶來的停頓時間,V8將標記過程分爲一個個的子標記過程,同時讓垃圾回收標記和JS應用邏輯交替進行,直到標記階段完成。

clipboard.png

通過增量標記改進後,垃圾回收的最大停頓時間能夠減小到原來的 1/6 左右。

內存泄漏

內存泄漏(Memory Leak)是指程序中己動態分配的堆內存因爲某種緣由程序未釋放或沒法釋放,形成系統內存的浪費,致使程序運行速度減慢甚至系統崩潰等嚴重後果。

內存泄漏的常見場景:

  • 緩存:存在內存中數據一隻沒有被清掉
  • 做用域未釋放(閉包)
  • 無效的 DOM 引用
  • 不必的全局變量
  • 定時器未清除(React中的合成事件,還有原生事件的綁定區別)
  • 事件監聽爲清空
  • 內存泄漏優化

7.你熟悉哪些通訊協議,它們的優缺點?

通訊協議全解

個人這篇文章很是詳細介紹了 http1.0 http1.1 http2.0 https websocket等協議

8.從輸入url地址欄,發生了什麼?由此來介紹如何性能優化:

性能優化不徹底手冊

如何優化你的超大型React應用

個人這兩篇文章基本上涵蓋了前端基礎的性能優化,後期我會再出專欄。

9.瀏覽器的緩存實現,請您介紹:

1.preload,prefetch,dns-prefetch

什麼是preload

使用 preload 指令的好處包括:

容許瀏覽器來設定資源加載的優先級所以能夠容許前端開發者來優化指定資源的加載。

賦予瀏覽器決定資源類型的能力,所以它能分辨這個資源在之後是否能夠重複利用。

瀏覽器能夠經過指定 as 屬性來決定這個請求是否符合 content security policy。

瀏覽器能夠基於資源的類型(好比 image/webp)來發送適當的 accept 頭。

Prefetch

Prefetch 是一個低優先級的資源提示,容許瀏覽器在後臺(空閒時)獲取未來可能用獲得的資源,而且將他們存儲在瀏覽器的緩存中。一旦一個頁面加載完畢就會開始下載其餘的資源,而後當用戶點擊了一個帶有 prefetched 的鏈接,它將能夠馬上從緩存中加載內容。

DNS Prefetching

DNS prefetching 容許瀏覽器在用戶瀏覽頁面時在後臺運行 DNS 的解析。如此一來,DNS 的解析在用戶點擊一個連接時已經完成,因此能夠減小延遲。能夠在一個 link 標籤的屬性中添加 rel="dns-prefetch' 來對指定的 URL 進行 DNS prefetching,咱們建議對 Google fonts,Google Analytics CDN 進行處理。

2.servece-worker,PWA漸進式web應用

PWA文檔

clipboard.png

3.localstorage,sessionstorage,cookie,session等。
瀏覽器的會話存儲和持久性存儲
4.瀏覽器緩存的實現機制的實現

clipboard.png

10.同源策略是什麼,跨域解決辦法,cookie能夠跨域嗎?

跨域解決的辦法

Q:爲何會出現跨域問題?

A:出於瀏覽器的同源策略限制,瀏覽器會拒絕跨域請求。

  • 注:嚴格的說,瀏覽器並非拒絕全部的跨域請求,實際上拒絕的是跨域的讀操做。瀏覽器的同源限制策略是這樣執行的:

一般瀏覽器容許進行跨域寫操做(Cross-origin writes),如連接,重定向;

一般瀏覽器容許跨域資源嵌入(Cross-origin embedding),如 img、script 標籤;

一般瀏覽器不容許跨域讀操做(Cross-origin reads)。

Q:什麼狀況纔算做跨域?

A:非同源請求,均爲跨域。名詞解釋:同源 —— 若是兩個頁面擁有相同的協議(protocol),端口(port)和主機(host),那麼這兩個頁面就屬於同一個源(origin)。

Q:爲何有跨域需求?

A:場景 —— 工程服務化後,不一樣職責的服務分散在不一樣的工程中,每每這些工程的域名是不一樣的,但一個需求可能須要對應到多個服務,這時便須要調用不一樣服務的接口,所以會出現跨域。

方法:JSONP,CORS,postmessage,webscoket,反向代理服務器等。

上篇已經結束,歡迎你關注,等待下篇很是硬核的文章出爐~

期待你加入咱們哦~

如今一羣滿了,因此新開了一個二羣

clipboard.png

相關文章
相關標籤/搜索