一次令人窒息的百度面試 (前端開發(fā)工程師)

最近接到了百度的面試,個人覺得基礎知識準備的比較充分,就去網上找了一些百度的面經,冥冥之中我在眾多的面試題中打開了下邊兩個面試題:
2021百度前端社招面經
百度前端面試題分享,帶答案
看完之后我直呼“哇哦~”,全部在我的射程范圍之內。我該不會如此幸運到問的全會吧。
是的,答案就是不會,我就是沒有幸運到問的全會。
話不多說,接下來就回顧下面試的問題。
看簡歷
上來首先是萬年不變的自我介紹,介紹完之后面試官就開始逐行看我的簡歷,并針對簡歷上的項目經歷進行詢問。詢問的十分詳細。
如何實現新手指引
問這個問題的原因是我簡歷上寫到了使用driver.js庫實現了新手指引。
使用js實現如下:
注意元素中包含如下結構:
實現思路是:
點擊“開始指引”:找到id為mask的元素,為該元素添加蒙層樣式(setMask)
添加提示信息:找到id為tip的元素,將提示信息添加為該元素的子元素(setTip)
高亮當前步驟元素:找到當前目標元素,克隆目標元素,然后將克隆后的目標元素添加為curStepMask的子元素(setTip)
定位tip和curStepMask的元素:curStepMask元素在當前目標元素的正上方,tip元素根據情況而定
每次添加當前提示信息時要移除上一次添加的提示信息和覆蓋元素(removeTip,removeStepMask)
getBoundingClientRec
返回值是一個?
DOMRect
?對象,是包含整個元素的最小矩形(包括?padding
?和?border-width
)。該對象使用?left
、top
、right
、bottom
、x
、y
、width
?和?height
?這幾個以像素為單位的只讀屬性描述整個矩形的位置和大小。除了?width
?和?height
?以外的屬性是相對于視圖窗口的左上角來計算的。 --MDN

圖片上有一個人臉,除了臉部以外加上蒙層
方案一:
添加遮罩層,在圖片上方添加一張只有人臉的圖片:
最終實現效果:(沒有用一模一樣的圖片,只是模擬了類似的效果)

上述是在整個頁面添加蒙層,若想只在圖片部分添加蒙層:
效果:

echarts動畫實現原理
對Echarts目前處于使用的水平,原理后續(xù)學習的話再補上吧~~~
了解canvas嗎
HTML5 <canvas>
元素用于圖形的繪制,通過腳本 (通常是JavaScript)來完成。
<canvas>
標簽只是圖形容器,必須使用腳本來繪制圖形。
可以通過多種方法使用 canvas 繪制路徑,盒、圓、字符以及添加圖像。
canvas教程傳送門
如何實現組件滑動切換效果
不使用react-transition-group
對語義化的理解
語義化就是正確的標簽做正確的事。語義化的好處在于:
對于開發(fā)團隊而言,代碼更加容易維護
在css沒有加載出來的情況下也能很好的展示結構
有利于SEO優(yōu)化
更好地支持各種終端,例如無障礙閱讀和有聲小說等
HTML5有哪些語義化標簽
常用的語義化標簽有:
header:定義頁眉信息
nav:導航欄
section:頁面的組成部分
footer:腳注信息
aside:側邊欄信息,比如菜單或者廣告等
less 多處用到px轉換為vw 如何實現
sass中可以定義函數,接收參數并且返回計算值:
less中函數是內置的不能夠自定義,所以可以使用混入:
less傳送門
vue-router中router和route的區(qū)別
router是路由實例對象,包含一些路由跳轉方法,比如push。
route是路由信息對象,包含和路由相關的一些信息,比如params,location等。
vue單頁面應用無刷新更新組件怎么實現的
我理解面試官詢問的點在于vue-router兩種模式下如何實現的url到組件的映射。
hash模式
hash模式是vue-router的默認模式。hash指的是url描點,當描點發(fā)生變化的時候,瀏覽器只會修改訪問歷史記錄,不會訪問服務器重新獲取頁面。因此可以監(jiān)聽描點值的變化,根據描點值渲染指定dom。
改變描點
可以通過location.hash = "/hashpath"
的方式修改瀏覽器的hash值。
監(jiān)聽描點變化
可以通過監(jiān)聽hashchange事件監(jiān)聽hash值的變化。
history模式
通過mode選項開啟history模式,history 模式和 hash 模式的區(qū)別在于:
history模式中不帶有“#”,更加美觀
history模式當用戶刷新或直接輸入地址時會向服務器發(fā)送一個請求,所以history模式需要服務端同學進行支持,將路由都重定向到根路由
改變url
H5的history對象提供了pushState和replaceState兩個方法,當調用這兩個方法的時候,url會發(fā)生變化,瀏覽器訪問歷史也會發(fā)生變化,但是瀏覽器不會向后臺發(fā)送請求。
監(jiān)聽url變化
可以通過監(jiān)聽popstate事件監(jiān)聽history變化,也就是點擊瀏覽器的前進或者后退功能時觸發(fā)。
從某種程度來說,調用?
pushState()
?和?window.location = "#foo"
基本上一樣,他們都會在當前的 document 中創(chuàng)建和激活一個新的歷史記錄。但是?pushState()
?有以下優(yōu)勢:
新的 URL 可以是任何和當前 URL 同源的 URL。但是設置?
window.location
?只會在你只設置錨的時候才會使當前的 URL。非強制修改 URL。相反,設置?
window.location = "#foo";
?僅僅會在錨的值不是 #foo 情況下創(chuàng)建一條新的歷史記錄。可以在新的歷史記錄中關聯任何數據。
window.location = "#foo"
形式的操作,你只可以將所需數據寫入錨的字符串中。注意:?
pushState()
?不會造成?hashchange
?事件調用,即使新的 URL 和之前的 URL 只是錨的數據不同。 ----MDN
vue在頁面中如何監(jiān)聽回到上一步的操作
掛載完成后,判斷瀏覽器是否支持popstate
頁面銷毀時,取消監(jiān)聽。否則其他vue路由頁面也會被監(jiān)聽
頁面跳轉函數
代碼題:回文字符串
場景提:一個公告欄,每一天都可以展示,當用戶點擊關閉后今天不顯示,明天(過了今天零點)還會顯示
我給出的方案就是在localStorage中存儲用戶關閉公告欄的時間戳,等再次進入頁面的時候判斷是不是存在localStorage:
若不存在則證明從來沒有關閉過公告欄,那就顯示;
若存在,就判斷時間戳和當前時間是否是同一天,不是同一天就顯示
代碼題:命名方式中劃線改小駝峰
方案一:
方案二:
代碼題:命名方式小駝峰改中劃線
git commit之后修改上一次commit的信息
剛commit還沒有push
git commit --amend
會進入vim編輯器,點擊i,修改commit信息后,點擊esc,輸入ZZ退出。
git log 可以看見最近commit信息
剛push,修改最近一次commit
git commit --amend
會進入vim編輯器,點擊i,修改commit信息后,點擊esc,輸入ZZ退出。
git log 可以看見最近commit信息,pull后再push到遠程(但是每次pull后再push會導致覆蓋原來的更改,后來直接強制推送成功了:git push origin HEAD:master --force)
修改歷史push的commit信息
git rebase -i HEAD~3
表示要修改當前版本的倒數第三次狀態(tài).
這個命令出來之后,會出來三行東東:
復制代碼
如果你要修改哪個,就把那行的pick改成edit,然后保存退出(點擊esc,輸入ZZ退出)
這時通過git log你可以發(fā)現,git的最后一次提交已經變成你選的那個了,這時再使用:
git commit --amend 來對commit進行修改。
修改完成后使用git rebase --continue
然后將變化push到遠程:git push origin HEAD:master --force
webpack優(yōu)化構建速度
前端性能優(yōu)化
頁面渲染優(yōu)化
Webkit 渲染引擎流程:
處理 HTML 并構建 DOM 樹
處理 CSS 構建 CSS 規(guī)則樹(CSSOM)
DOM Tree 和 CSSOM Tree 合成一棵渲染樹 Render Tree。
根據渲染樹來布局,計算每個節(jié)點的位置
調用 GPU 繪制,合成圖層,顯示在屏幕上
避免css阻塞:css影響renderTree的構建,會阻塞頁面的渲染,因此應該盡早(將 CSS 放在 head 標簽里)和盡快(啟用 CDN 實現靜態(tài)資源加載速度的優(yōu)化)的將css資源加載
避免js阻塞:js可以修改CSSOM和DOM,因此js會阻塞頁面的解析和渲染,并且會等待css資源的加載。也就是說js會搶走渲染引擎的控制權。所以我們需要給js資源添加defer或者async,延遲js腳本的執(zhí)行。
使用字體圖標 iconfont 代替圖片圖標:
圖片會增加網絡請求次數,從而拖慢頁面加載時間
iconfont可以很好的縮放并且不會添加額外的請求
?? 4.降低css選擇器的復雜度:瀏覽器讀取選擇器,遵循的原則是從選擇器的右邊到左邊讀取。
減少嵌套:最多不要超過三層,并且后代選擇器的開銷較高,慎重使用
避免使用通配符,對用到的元素進行匹配即可
利用繼承,避免重復匹配和定義
正確使用類選擇器和id選擇器
? 5.減少重繪和回流:
CSS
避免使用table布局。
盡可能在DOM樹的最末端改變class。
避免設置多層內聯樣式。
將動畫效果應用到position屬性為absolute或fixed的元素上。
避免使用CSS表達式(例如:calc())。
JavaScript
避免頻繁操作樣式,最好一次性重寫style屬性,或者將樣式列表定義為class并一次性更改class屬性。
避免頻繁操作DOM,創(chuàng)建一個documentFragment,在它上面應用所有DOM操作,最后再把它添加到文檔中。
為元素設置display: none,操作結束后再把它顯示出來。因為在display屬性為none的元素上進行的DOM操作不會引發(fā)回流和重繪。用一次回流替代多次回流
避免頻繁讀取會引發(fā)回流/重繪的屬性,如果確實需要多次使用,就用一個變量緩存起來。
對具有復雜動畫的元素生成一個新圖層
JS中的性能優(yōu)化
使用事件委托
防抖和節(jié)流
盡量不要使用JS動畫,css3動畫和canvas動畫都比JS動畫性能好
圖片的優(yōu)化
雪碧圖:借助減少http請求次數來進行優(yōu)化
圖片懶加載:在圖片即將進入可視區(qū)域的時候進行加載(后邊有判斷即將進入可視區(qū)域的方法)
使用CSS3代替圖片:有很多圖片使用 CSS 效果(漸變、陰影等)就能畫出來,這種情況選擇 CSS3 效果更好
webpack優(yōu)化
代碼壓縮:html,css,js文件壓縮
Tree shaking 去除死代碼
babel-plugin-transform-runtime
減少ES6轉化ES5的冗余提升打包速度
vue
路由懶加載
合理使用computed和watch
v-for添加key
v-for的同時避免使用v-if
destory時銷毀事件:比如addEventListener添加的事件、setTimeout、setInterval、bus.$on綁定的監(jiān)聽事件等
第三方插件按需引入
react
map循環(huán)展示添加key
路由懶加載
使用scu,memo或者pureComponent避免不必要的渲染
前端的緩存機制
分為強緩存和協商緩存。
強緩存不需要客戶端向服務端發(fā)送請求,有兩種響應頭實現方案:
Expires:值是一個絕時間,在這個時間前緩存有效,但是如果本地時間被修改,會導致緩存失效
Cache-control:值是一個相對時間,單位為秒,資源在這個時間內有效
強緩存過期之后會使用協商緩存,協商緩存需要客戶端向服務端發(fā)送請求,資源未過期則服務端返回304否則返回新的資源。 協商緩存也有兩種實現方案:
Last-Modified 和 If-Modified-Since:
Last-Modified
表示本地文件最后修改日期,If-Modified-Since
會將Last-Modified
的值發(fā)送給服務器,詢問服務器在該日期后資源是否有更新,有更新的話就會將新的資源發(fā)送回來。但是如果本地文件被打開,會導致Last-Modified
被修改。ETag 和 If-None-Match:
ETag
類似于文件指紋,If-None-Match
會將當前ETag
發(fā)送給服務器,詢問該資源ETag
是否變動,有變動的話就將新的資源發(fā)送回來。并且ETag
優(yōu)先級比Last-Modified
高。
如何判斷圖片即將進入可視區(qū)域
方案1:clientHeight+scroolTop>offsetTop
方案2:下滑過程中bound.top會越來越小

最后
??? 小伙伴們學習編程,有時候不知道怎么學,從哪里開始學。掌握了基本的一些語法或者做了兩個案例后,不知道下一步怎么走,不知道如何去學習更加高深的知識。
那么對于這些小伙伴們,我準備了大量的視頻教程,PDF電子書籍,以及源代碼!
只要+up主威信wangkeit1備注“B站”就可以白嫖領取啦!?
