這份前端面試小冊子dog cheng帶來啦~

来源:https://www.cnblogs.com/okaychen/archive/2020/01/09/12173418.html
-Advertisement-
Play Games

寫在前面 沒有錯,就是我啦dog cheng,好久不見,從17年在博客園寫下第一篇文章,轉身間已然兩年,從大二到現在的大四預備畢業生,我仍然在這條道路上前進。秋招早已經結束,在拿到用友,滴滴的offer之後,最終在九月選擇了百度APP,但是我沒有停下,懷著學習的態度完成了一份 90頁PDF , 近1 ...


寫在前面

沒有錯,就是我啦dog cheng,好久不見,從17年在博客園寫下第一篇文章,轉身間已然兩年,從大二到現在的大四預備畢業生,我仍然在這條道路上前進。秋招早已經結束,在拿到用友,滴滴的offer之後,最終在九月選擇了百度APP,但是我沒有停下,懷著學習的態度完成了一份90頁PDF近140+commits的面試小冊之後,寫下了這段文字

互聯網發展迅猛之餘也伴隨著互聯網寒冬,行業不景氣這樣的詞,等畢業季去各個求職網站投簡歷,去各個人才市場找機會,才發現四處碰壁,作為應屆求職者更需要打好基礎,明確發展規劃,跟上行業步伐。下麵是本人2019年秋招前端面試經歷,結合個人博客和牛油們面經中的高頻問題以及行業前輩們複習資料的綜合整理,包含基礎篇Vue框架篇HTTP&瀏覽器構建工具篇安全篇演算法篇,歡迎交流斧正,希望大家在畢業季都能一帆風順,從容斬獲OFFER。近100+前端面試題及推薦解答,資源合集,這個冬天不會很冷

因為篇幅有限,下麵留下了前兩篇各五道面試題,這個項目已經在github上開源,歡迎大家取用:Github

HTML/CSS

瀏覽器解析渲染頁面過程

大致過程:

HTML解析構建DOM->CSS解析構建CSSOM樹->根據DOM樹和CSSOM樹構建render樹->根據render樹進行佈局渲染render layer->根據計算的佈局信息進行繪製

不同瀏覽器的內核不同,所以渲染過程其中有部分細節有不一樣,以webkit主流程為例:

一篇很棒的文章:How Browser Work

我有話說:瀏覽器解析渲染頁面過程是一個複雜的過程,其中有不少的細節和規則,如果把上面分享的文章翻譯成譯文,至少有3~5頁PDF左右,所以這裡只能總結大致過程(作為面試回答【很可能讓回答的儘可能詳細】瞭解來說已經足夠,更深入的瞭解可以好好讀下上面那篇文章)

較詳細過程:

HTML解析構建DOM樹:其中HTML Parser就起到了將HTML標記解析成DOM Tree的作用,HTML Parser將文本的HTML文檔,提煉出關鍵信息,嵌套層級的樹形結構,便於計算拓展;這其中也有很多的規則和操作,比如容錯機制,識別特殊標簽<br></br>

CSS解析構建CSSOM樹:CSS Parser將很多個CSS文件中的樣式合併解析出具有樹形結構Style Rules,也叫做CSSOM。

※其中還有一個細節是瀏覽器解析文檔:當遇到<script>標簽的時候會停止解析文檔,立即解析腳本,將腳本中改變DOM和CSS的地方分別解析出來,追加到DOM Tree和CSSOM上

根據DOM樹和CSSOM樹構建Render樹:Render Tree的構建其實就是DOM Tree和CSSOM Attach的過程,在webkit中,解析樣式和創建呈現器的過程稱為"附加",每個DOM節點都有一個"attach"方法,Render Tree其實就相當於一個計算好樣式,與HTML對應的Tree

根據Render樹進行佈局渲染render layer:創建渲染樹後,Layout根據根據渲染樹中渲染對象的信息,計算好每一個渲染對象的位置和尺寸,將其放在瀏覽器視窗的正確位置,某些時候會在文檔佈局完成之後進行DOM修改,重新佈局的過程就稱為迴流

※其中計算(樣式計算)一個複雜的過程,因為DOM中的一個元素可以對應樣式表中的多個元素,Firefox採用了規則樹和樣式上下文樹來簡化樣式計算,規則樹包含了所有已知規則的匹配路徑,樣式上下文包含端值,webkit也有樣式對象,但它們不保存在類似上下文樹這樣的結構中,只是由DOM節點指向此類對象的相關樣式

根據計算的佈局信息進行繪製:繪製階段則會遍歷呈現樹,並調用呈現器的paint方法,將呈現器的內容顯示在屏幕上,繪製的順序其實就是元素進入堆棧樣式上下文的順序,例如,塊呈現器的堆棧順序如下:1.背景顏色,2.背景圖片,3.邊框,4.子代,5.輪廓

移動端點透現象有遇到過嘛

首先需要瞭解的是,移動端在touch上一共有4個事件,

執行順序為touchstart -> touchmove -> touchend -> touchcancel

當用戶點擊屏幕時,會觸發touch和click事件,touch事件會優先處理,touch事件經過捕獲,目標,冒泡一系列流程處理完成之後,才會觸發click,所有我們經常會談到移動端點擊事件300ms延遲的問題

移動端點擊事件300ms問題,常見的解決方案:

  • 阻止用戶雙擊縮放,並限制視口大小
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no"/>
  • 設置csstouch-action用於指定某個給定的區域是否允許用戶操作,以及如何相應用戶操作
* {
  touch-action: none;
}
  • fastclick.js來解決,其原理是在檢測到touchend事件的時候,會通過自定義事件立即觸發模擬一個click事件,併在300ms之後把真正的click事件阻止掉

點透現象:

發生條件:①按鈕A和按鈕B不是後代繼承關係,②A發生touch,A touch後立即消失,B綁定click,③A z-index大於B,即 A 顯示在 B 浮層之上

發生原因:當點擊屏幕時,系統生成touch和click兩個事件,touch先執行,touch執行完之後A消失,然後要執行click的時候,就會發現用戶點擊的是B,所以就執行了B的click

解決方法:①阻止預設事件,在touch的某個時間段執行event.preventDefault,去取消系統生成的click事件,一半在 touchend 中執行。②要消失的元素延遲300ms後在消失

margin塌陷和合併問題

首先,margin塌陷是相對於父子級關係的兩個元素,而margin合併是相對兩個兄弟級關係的兩個元素

兩個兄弟級關係的元素,垂直方向上的margin,其外邊距會發生重疊現象,兩者兩個的外邊距取的是兩個所設置margin的最大值,就是所說的margin合併問題

兩個父子級關係的元素,垂直方向上的margin會粘合在一起,外層和模型的margin-top取兩個元素中margin-top的最大值,發生margin塌陷的內層元素相對於整個文檔移動

解決方案:兩者都可以通過觸發BFC來解決

CSS定位的方式有哪些分別相對於誰

static(預設值)
absolute(絕對定位,相對於最近已定位的父元素,如果沒有則相對於<html>)
fixed(固定定位,相對於視窗)
relative(相對定位,相對於自身)
sticky(2017年瀏覽器開始支持,粘性定位)

absolute會使元素位置與文檔流無關,不占據空間,absolute 定位的元素和其他元素重疊

relative相對定位時,無論元素是否移動,仍然占據原來的空間

sticky是2017年瀏覽器才開始支持,會產生動態效果,類似relative和fixed的結合,一個實例是"動態固定",生效前提是必須搭配top,left,bottom,right一起使用,不能省略,否則等同於relative定位,不產生"動態固定"的效果

移動端佈局的解決方案,平時怎麼做的處理

  • 使用Flexbox
  • 百分比佈局結合媒體查詢
  • 使用rem

rem轉換像素大小(根元素的大小乘以rem值),取決與頁面根元素的字體大小,即HTML元素的字體大小

em轉換像素大小(em值乘以使用em單位的元素的字體大小),比如一個div的字體大小為16px,那麼10em就是180px(或者接近它)

rem平時怎麼做的轉換:為了方便計算,時常將html的字體大小設置為62.5%,那麼12px就會是1.2rem

JavaScript

列表無限滾動曾經有遇到過嘛

簡單列表滾動載入是監聽滾動條在滿足條件的時候觸發回調,然後通過把新的元素加入到頁面頁尾的方法完成,但是如果用戶載入過多列表數據(比如我這一個列表頁有一萬條數據需要展示),那麼用戶不斷載入,頁面不斷增加新的元素,很容易就導致頁面元素過多而造成卡頓,所以就提出的列表的無限滾動載入,主要是在刪除原有元素並且維持高度的基礎上,生成並載入新的數據

如果滾動過快怎麼辦,高頻率觸發事件解決方案-防抖和節流

節流:在一段時間內不管觸發了多少次都只認為觸發了一次,等計時結束進行響應(假設設置的時間為2000ms,再觸發了事件的2000ms之內,你在多少觸發該事件,都不會有任何作用,它只為第一個事件等待2000ms。時間一到,它就會執行了。 )

//時間戳方式
function throttle(fn,delay){
    let pre = Date.now();
    return function(){
        let context = this;
        let args = arguments;
        let now = Date.now();
        if(now - pre > delay){
            fn.apply(context,args);
            pre = Date.now();
        }
    }
}
//定時器方式
function throttle(fn,delay){
    let timer = null;
    return function(){
        let context = this;
        let args = arguments;
        if(!timer){
            timer = setTimeout(function(){
                fn.apply(context,args);
                timer = null;
            },delay)
        }
    }
}

防抖:在某段時間內,不管你觸發了多少次事件,都只認最後一次(假設設置時間為2000ms,如果觸發事件的2000ms之內,你再次觸發該事件,就會給新的事件添加新的計時器,之前的事件統統作廢。只執行最後一次觸發的事件。)

//定時器方式
function debounce(fn,delay){
    let timer = null;
    return function(){
        let context = this;
        let args = arguments;
        clearTimeout(timer);
        timer = setTimeout(function(){
            fn.apply(context,args);
        },delay)
    }
}

解釋一下變數提升

JavaScript引擎會先進行預解析,獲取所有變數的聲明複製undefined,然後逐行執行,這導致所有被聲明的變數,都會被提升到代碼的頭部(被提升的只有變數,值不會被提升),也就是變數提升(hoisting)

console.log(a) // undefined

var a = 1
function b(){
    console.log(a)
}
b() // 1

預解析階段會先獲的變數a賦值undefined,並將var a = undefined放在最頂端,此時a = 1還在原來的位置,實際就是:

var a = undefined
console.log(a) // undefined

a = 1
function b(){
    console.log(a)
}

b() // 1

然後會是執行階段,逐行執行造成了列印出a是undefined

js為什麼0.1+0.2不等於0.3

主要是因為JavaScript同樣採用IEEE754標準,在64位中存儲一個數字的有效數字形式

第0位表示符號位,0表示整數1表示負數,第1~11位存儲指數部分,第12~63位存小數部分;

由於二進位的有效數字總是表示為1.xxx...這樣的形式,尾數部分在規約形式下的第一位預設為1,故存儲時第一位省略不寫,尾數部分存儲有效數字小數點後的xxx...,最長52位,因此,JavaScript提供的有效數字最長為53個二進位位(尾數部分52位+被省略的1位)

由於需要對求和結果規格化(用有效數字表示),右規導致低位丟失,此時需對丟失的低位進行舍入操作,遵循IEEE754舍入規則,會有精度損失

對eventloop事件迴圈機制的瞭解

首先,JavaScript一大特點就是單線程,這樣的設計讓它在同一時間只做一件事;作為瀏覽器腳本語言,JavaScript的主要用途是與用戶互動,以及操作DOM,避免了複雜性,比如假設JavaScript有兩個線程,那麼在同一時間進行添加刪除節點操作,為瀏覽器分辨以哪個線程為準帶來困難,所以單線程是它作為瀏覽器腳本語言的優勢,也是它的核心特征。

註:雖然為了利用多核CPU的計算能力,HTML5提出了web worker標準,允許JavaScript創建多個線程,但是子線程完全受主線程式控制制,且不得操作DOM,所以也並沒有改變JavaScript單線程的本質

那麼,單線程就意味著,所有任務需要排隊,前一個任務結束才會執行後一個任務,所以為了提高CPU的利用效率,就把所有任務分成了同步任務(synchronous)和非同步任務(asynchronous),同步任務在主線程順序執行,非同步任務則不進入主線程而是進入到任務隊列(task queue)中。在主線程上會形成一個執行棧,等執行棧中所有任務執行完畢之後,會去任務隊列中查看有哪些事件,此時非同步任務結束等待狀態,進入執行棧中,開始執行。

主線程從任務隊列中讀取事件,這個過程是迴圈不斷的,所以整個的這種運行機制又稱為Event Loop(事件迴圈)

寫在後面

篇幅有限,上面留下了小冊中前兩篇的各五道高頻問題,更多問題以及資源合集,在Github可以直接看到,而且除了Github還提供了其他兩種方案,gitbook和pdf(近90頁),都可以選擇

那麼,最後為了突出主題呢,還是要寫一些對於這份小冊的願景吧:如果你是應屆生(當然,大牛除外),正面臨找前端開發的工作,或者即將成為畢業生的預備生,我相信這份前端面試小冊多多少少會幫到你,在這"不景氣"的"寒冬"之季,我們仍要提高自身綜合素質,堅持技術生活,通過不斷給自己設立小目標並實現來督促自身學習提高,最後就以習大大給我們寄語結束吧—2020願我們只爭朝夕不負韶華


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 個人博客 "http://www.milovetingting.cn" 四大組件的工作過程 四大組件:Activity、Service、BroadcastReceiver、ContentProvider 四大組件的運行狀態 Android的四大組件中除了BroadcastReceiver,其它三種組 ...
  • 先 "pod setup" 再 "pod install". ...
  • 場景 app中常見的對話框。 簡單的帶確定取消按鈕的對話框 帶列表的對話框 帶單項選擇的對話框 帶多項選擇的對話框 註: 博客: https://blog.csdn.net/badao_liumang_qizhi 關註公眾號 霸道的程式猿 獲取編程相關電子書、教程推送與免費下載。 實現 將佈局改為L ...
  • 以前一直用的安卓原生Toast,個人感覺Toast這東西,沒必要花功夫,知道看到了Toasty這東西,立刻被圈粉了,真的非常好看。 項目地址 我們都知道,安卓原生Toast的用法是 1 Toast.makeText(MainActivity.this,"Toast顯示內容",Toast.LENGTH ...
  • 場景 效果 註: 博客: https://blog.csdn.net/badao_liumang_qizhi 關註公眾號 霸道的程式猿 獲取編程相關電子書、教程推送與免費下載。 實現 將佈局改為LinearLayout,並通過android:orientation="vertical">設置為垂直布 ...
  • 1.SharedPreferences介紹 SharedPreferences,它是一個輕量級的配置文件類,用於保存軟體配置參數. 採用xml文件形式存儲在/data/data/包名/shared_prefs/下 優點在於: 輕量級,以鍵值對的方式進行存儲,使用方便,易於理解 程式卸載後會也會一併被 ...
  • 前言 無論在任何的語言或框架中,我們都提倡代碼的復用性。對於Vue來說也是如此,相同的代碼邏輯會被封裝成組件,除了復用之外,更重要的是統一管理提高開發效率。我真就接手過一個項目,多個頁面都會用到的列表,沒有去封裝列表組件,只要有一點改動,每個頁面都得加上。很肯定的說,沒有用組件化開發的Vue項目是沒 ...
  • 花了幾天時間學習了下 React Native,瞭解了基本的移動端App開發流程,不得不說,坑是真的多。。簡易中小型項目的跨端項目……追求簡單的話還是用uni-app吧。 筆記和demo都放在git上了,瞭解了這些知識,感覺開發中小型App項目應該沒問題了,有需要自取哈 git地址:https:// ...
一周排行
    -Advertisement-
    Play Games
  • GoF之工廠模式 @目錄GoF之工廠模式每博一文案1. 簡單說明“23種設計模式”1.2 介紹工廠模式的三種形態1.3 簡單工廠模式(靜態工廠模式)1.3.1 簡單工廠模式的優缺點:1.4 工廠方法模式1.4.1 工廠方法模式的優缺點:1.5 抽象工廠模式1.6 抽象工廠模式的優缺點:2. 總結:3 ...
  • 新改進提供的Taurus Rpc 功能,可以簡化微服務間的調用,同時可以不用再手動輸出模塊名稱,或調用路徑,包括負載均衡,這一切,由框架實現並提供了。新的Taurus Rpc 功能,將使得服務間的調用,更加輕鬆、簡約、高效。 ...
  • 本章將和大家分享ES的數據同步方案和ES集群相關知識。廢話不多說,下麵我們直接進入主題。 一、ES數據同步 1、數據同步問題 Elasticsearch中的酒店數據來自於mysql資料庫,因此mysql數據發生改變時,Elasticsearch也必須跟著改變,這個就是Elasticsearch與my ...
  • 引言 在我們之前的文章中介紹過使用Bogus生成模擬測試數據,今天來講解一下功能更加強大自動生成測試數據的工具的庫"AutoFixture"。 什麼是AutoFixture? AutoFixture 是一個針對 .NET 的開源庫,旨在最大程度地減少單元測試中的“安排(Arrange)”階段,以提高 ...
  • 經過前面幾個部分學習,相信學過的同學已經能夠掌握 .NET Emit 這種中間語言,並能使得它來編寫一些應用,以提高程式的性能。隨著 IL 指令篇的結束,本系列也已經接近尾聲,在這接近結束的最後,會提供幾個可供直接使用的示例,以供大伙分析或使用在項目中。 ...
  • 當從不同來源導入Excel數據時,可能存在重覆的記錄。為了確保數據的準確性,通常需要刪除這些重覆的行。手動查找並刪除可能會非常耗費時間,而通過編程腳本則可以實現在短時間內處理大量數據。本文將提供一個使用C# 快速查找並刪除Excel重覆項的免費解決方案。 以下是實現步驟: 1. 首先安裝免費.NET ...
  • C++ 異常處理 C++ 異常處理機制允許程式在運行時處理錯誤或意外情況。它提供了捕獲和處理錯誤的一種結構化方式,使程式更加健壯和可靠。 異常處理的基本概念: 異常: 程式在運行時發生的錯誤或意外情況。 拋出異常: 使用 throw 關鍵字將異常傳遞給調用堆棧。 捕獲異常: 使用 try-catch ...
  • 優秀且經驗豐富的Java開發人員的特征之一是對API的廣泛瞭解,包括JDK和第三方庫。 我花了很多時間來學習API,尤其是在閱讀了Effective Java 3rd Edition之後 ,Joshua Bloch建議在Java 3rd Edition中使用現有的API進行開發,而不是為常見的東西編 ...
  • 框架 · 使用laravel框架,原因:tp的框架路由和orm沒有laravel好用 · 使用強制路由,方便介面多時,分多版本,分文件夾等操作 介面 · 介面開發註意欄位類型,欄位是int,查詢成功失敗都要返回int(對接java等強類型語言方便) · 查詢介面用GET、其他用POST 代碼 · 所 ...
  • 正文 下午找企業的人去鎮上做貸後。 車上聽同事跟那個司機對罵,火星子都快出來了。司機跟那同事更熟一些,連我在內一共就三個人,同事那一手指桑罵槐給我都聽愣了。司機也是老社會人了,馬上聽出來了,為那個無辜的企業經辦人辯護,實際上是為自己辯護。 “這個事情你不能怪企業。”“但他們總不能讓銀行的人全權負責, ...