摘要:還是老規矩,從易到難吧傳統的定時器,異步編程等。分配對象時,先是在空間中進行分配。內存泄漏內存泄漏是指程序中己動態分配的堆內存由于某種原因程序未釋放或無法釋放,造成系統內存的浪費,導致程序運行速度減慢甚至系統崩潰等嚴重后果。
網上參差不棄的面試題,本文由淺入深,讓你在做面試官的時候,能夠辨別出面試者是不是真的有點東西,也能讓你去面試中級前端工程師更有底氣。但是切記把背誦面試題當成了你的唯一求職方向
另外歡迎大家加入我們的前端交流二群~,里面很多小姐姐哦,下篇將是非常硬核的源碼,原理,自己編寫框架和庫等,如果感覺寫得不錯,可以關注給個star~
越是開放性的題目,更能體現回答者的水平,一場好的面試,不僅能發現面試者的不足,也能找到他的閃光點,還能提升面試官自身的技術
1.Css和Html合并在第一個題目,請簡述你讓一個元素在窗口中消失以及垂直水平居中的方法,還有Flex布局的理解標準答案:百度上當然很多,這里不做闡述,好的回答思路是:
元素消失的方案先列出來, display:none和visibility: hidden;的區別,拓展到vue框架的v-if和v-show的區別,可以搭配回流和重繪來講解
回流必將引起重繪,重繪不一定會引起回流 回流(Reflow):當Render Tree中部分或全部元素的尺寸、結構、或某些屬性發生改變時,瀏覽器重新渲染部分或全部文檔的過程稱為回流
下面內容會導致回流:
頁面首次渲染
瀏覽器窗口大小發生改變
元素尺寸或位置發生改變
元素內容變化(文字數量或圖片大小等等)
元素字體大小變化
添加或者刪除可見的DOM元素
激活CSS偽類(例如::hover)
查詢某些屬性或調用某些方法
一些常用且會導致回流的屬性和方法:
clientWidth、clientHeight、clientTop、clientLeft
offsetWidth、offsetHeight、offsetTop、offsetLeft
scrollWidth、scrollHeight、scrollTop、scrollLeft
scrollIntoView()、scrollIntoViewIfNeeded()
getComputedStyle()
getBoundingClientRect()
scrollTo()
重繪當頁面中元素樣式的改變并不影響它在文檔流中的位置時(例如:color、background-color、visibility等),瀏覽器會將新樣式賦予給元素并重新繪制它,這個過程稱為重繪。性能影響對比:
原文出處,感謝作者
列出元素垂直居中的方案,以及各種方案的缺陷
16種居中方案,感謝作者
講出flex常用的場景,以及flex 1做了什么
阮一峰老師的Flex布局
上面的問題如果答得非常好,在重繪和回流這塊要下大功夫。這點是前端性能優化的基礎,而性能優化是前端最重要的核心基礎技能點,也是面試官最看中的基礎之一2.你對This了解嗎,有自己實現過call,apply,bind嗎?
50行javaScript代碼實現call,apply,bind
這是一個很基礎的技能點,考察你對閉包,函數調用的理解程度,我感覺我寫得比較簡單容易懂
3.如何減少重繪和回流的次數: 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嵌套地獄requestAnimationFrame和requestIdleCallback:
傳統的javascript 動畫是通過定時器 setTimeout 或者 setInterval 實現的。但是定時器動畫一直存在兩個問題
第一個就是動畫的循時間環間隔不好確定,設置長了動畫顯得不夠平滑流暢,設置短了瀏覽器的重繪頻率會達到瓶頸,推薦的最佳循環間隔是17ms(大多數電腦的顯示器刷新頻率是60Hz,1000ms/60);
第二個問題是定時器第二個時間參數只是指定了多久后將動畫任務添加到瀏覽器的UI線程隊列中,如果UI線程處于忙碌狀態,那么動畫不會立刻執行。為了解決這些問題,H5 中加入了 requestAnimationFrame以及requestIdleCallback
requestAnimationFrame 會把每一幀中的所有 DOM 操作集中起來,在一次重繪或回流中就完成,并且重繪或回流的時間間隔緊緊跟隨瀏覽器的刷新頻率
在隱藏或不可見的元素中,requestAnimationFrame 將不會進行重繪或回流,這當然就意味著更少的 CPU、GPU 和內存使用量
requestAnimationFrame 是由瀏覽器專門為動畫提供的 API,在運行時瀏覽器會自動優化方法的調用,并且如果頁面不是激活狀態下的話,動畫會自動暫停,有效節省了 CPU 開銷
性能對比:requestAnimationFrame的回調會在每一幀確定執行,屬于高優先級任務,而requestIdleCallback的回調則不一定,屬于低優先級任務。
我們所看到的網頁,都是瀏覽器一幀一幀繪制出來的,通常認為FPS為60的時候是比較流暢的,而FPS為個位數的時候就屬于用戶可以感知到的卡頓了,那么在一幀里面瀏覽器都要做哪些事情呢,如下所示:
圖中一幀包含了用戶的交互、js的執行、以及requestAnimationFrame的調用,布局計算以及頁面的重繪等工作。
假如某一幀里面要執行的任務不多,在不到16ms(1000/60)的時間內就完成了上述任務的話,那么這一幀就會有一定的空閑時間,這段時間就恰好可以用來執行requestIdleCallback的回調,如下圖所示:
5.簡述瀏覽器的Eventloop和Node.js的Eventloop 瀏覽器的EventLoop不想解釋太多,看圖Node.js的EventLoop 特別提示:網上大部分Node.js的EventLoop的面試題,都會有BUG,代碼量和計算量太少,很可能還沒有執行到微任務的代碼,定時器就到時間被執行了 6.閉包與V8垃圾回收機制:
JS 的垃圾回收機制的基本原理是:
找出那些不再繼續使用的變量,然后釋放其占用的內存,垃圾收集器會按照固定的時間間隔周期性地執行這一操作。
V8 的垃圾回收策略主要基于分代式垃圾回收機制,在 V8 中,將內存分為新生代和老生代,新生代的對象為存活時間較短的對象,老生代的對象為存活事件較長或常駐內存的對象。
V8 堆的整體大小等于新生代所用內存空間加上老生代的內存空間,而只能在啟動時指定,意味著運行時無法自動擴充,如果超過了極限值,就會引起進程出錯。
Scavenge 算法在分代的基礎上,新生代的對象主要通過 Scavenge 算法進行垃圾回收,在 Scavenge 具體實現中,主要采用了一種復制的方式的方法—— Cheney 算法。
Cheney 算法將堆內存一分為二,一個處于使用狀態的空間叫 From 空間,一個處于閑置狀態的空間稱為 To 空間。分配對象時,先是在 From 空間中進行分配。
當開始進行垃圾回收時,會檢查 From 空間中的存活對象,將其復制到 To 空間中,而非存活對象占用的空間將會被釋放。完成復制后,From 空間和 To 空間的角色發生對換。
當一個對象經過多次復制后依然存活,他將會被認為是生命周期較長的對象,隨后會被移動到老生代中,采用新的算法進行管理。
還有一種情況是,如果復制一個對象到 To 空間時,To 空間占用超過了 25%,則這個對象會被直接晉升到老生代空間中。
標記-清除和標記-整理算法對于老生代中的對象,主要采用標記-清除和標記-整理算法。標記-清除 和前文提到的標記一樣,與 Scavenge 算法相比,標記清除不會將內存空間劃為兩半,標記清除在標記階段會標記活著的對象,而在內存回收階段,它會清除沒有被標記的對象。
而標記整理是為了解決標記清除后留下的內存碎片問題。
增量標記(Incremental Marking)算法前面的三種算法,都需要將正在執行的 JavaScript 應用邏輯暫停下來,待垃圾回收完畢后再恢復。這種行為叫作“全停頓”(stop-the-world)。
在 V8 新生代的分代回收中,只收集新生代,而新生代通常配置較小,且存活對象較少,所以全停頓的影響不大,而老生代就相反了。
為了降低全部老生代全堆垃圾回收帶來的停頓時間,V8將標記過程分為一個個的子標記過程,同時讓垃圾回收標記和JS應用邏輯交替進行,直到標記階段完成。
經過增量標記改進后,垃圾回收的最大停頓時間可以減少到原來的 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文檔
3.localstorage,sessionstorage,cookie,session等。
瀏覽器的會話存儲和持久性存儲
4.瀏覽器緩存的實現機制的實現
跨域解決的辦法
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,反向代理服務器等。
上篇已經結束,歡迎你關注,等待下篇非常硬核的文章出爐~
期待你加入我們哦~
現在一群滿了,所以新開了一個二群
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/116244.html
摘要:還是老規矩,從易到難吧傳統的定時器,異步編程等。分配對象時,先是在空間中進行分配。內存泄漏內存泄漏是指程序中己動態分配的堆內存由于某種原因程序未釋放或無法釋放,造成系統內存的浪費,導致程序運行速度減慢甚至系統崩潰等嚴重后果。 showImg(https://segmentfault.com/img/bVbwkad?w=1286&h=876); 網上參差不棄的面試題,本文由淺入深,讓你在...
摘要:安裝后已經完成了安裝,并且等待其他的線程被關閉。激活后在這個狀態會處理事件回調提供了更新緩存策略的機會。并可以處理功能性的事件請求后臺同步推送。廢棄狀態這個狀態表示一個的生命周期結束。 showImg(https://segmentfault.com/img/bVbwWJu?w=2056&h=1536); 不知不覺,已經來到了最后的下篇 其實我寫的東西你如果認真去看,跟著去寫,應該能有...
摘要:前端個靈魂拷問,徹底搞明白你就是中級前端工程師上篇感覺大家比較喜歡看這種類型的文章,以后會多一些。所有依賴這個模塊的語句,都定義在一個回調函數中,等到加載完成之后,這個回調函數才會運行。此規范其實是在推廣過程中產生的。 showImg(https://segmentfault.com/img/bVbwAMU?w=700&h=394); 前端20個靈魂拷問,徹底搞明白你就是中級前端工程師...
摘要:前端個靈魂拷問,徹底搞明白你就是中級前端工程師上篇感覺大家比較喜歡看這種類型的文章,以后會多一些。所有依賴這個模塊的語句,都定義在一個回調函數中,等到加載完成之后,這個回調函數才會運行。此規范其實是在推廣過程中產生的。 showImg(https://segmentfault.com/img/bVbwAMU?w=700&h=394); 前端20個靈魂拷問,徹底搞明白你就是中級前端工程師...
摘要:黑客技術點擊右側關注,了解黑客的世界開發進階點擊右側關注,掌握進階之路開發點擊右側關注,探討技術話題作者丨呼延十排版丨團長前言本文主要受眾為開發人員所以不涉及到的服務部署等操作且內容較多大家準備好耐心和瓜子礦泉水前一陣系統的學習了一下也有 ...
閱讀 1436·2021-09-22 16:04
閱讀 2800·2019-08-30 15:44
閱讀 887·2019-08-30 15:43
閱讀 765·2019-08-29 15:24
閱讀 1844·2019-08-29 14:07
閱讀 1134·2019-08-29 12:30
閱讀 1729·2019-08-29 11:15
閱讀 2740·2019-08-28 18:08