最近換工作,面試了好多公司,遇到了挺多的面試題的,將自己最近的面試題統一一下,做個記錄,最近一個月內有空就更新。方便自己學習,以及基礎知識的補充。順便吐槽一下,前端知識跟宇宙一樣寬廣啊~
1. gpu加速的原理
16ms 優化:大多數設備的刷新頻率是 60 次/秒,(1000/60 = 16.6ms)也就說是瀏覽器對每一幀畫面的渲染工作要在 16ms 內完成,超出這個時間,頁面的渲染就會出現卡頓現象,影響用戶體驗
- JavaScript:JavaScript 實現動畫效果,DOM 元素操作等。
- Style(計算樣式):確定每個 DOM 元素應該應用什麼 CSS 規則。
- Layout(佈局):計算每個 DOM 元素在最終屏幕上顯示的大小和位置。由於 web 頁面的元素佈局是相對的,所以其中任意一個元素的位置發生變化,都會聯動的引起其他元素髮生變化,這個過程叫 reflow。
- Paint(繪製):在多個層上繪製 DOM 元素的的文字、顏色、圖像、邊框和陰影等。
- Composite(渲染層合併):按照合理的順序合併圖層然後顯示到屏幕上。
通過改變元素的 transform 實現移動,伸縮變換而非改變物體的 left,top,width,height 避免 layout,paint
如何開啓GPU加速?3D 或透視變換(perspective,transform) CSS 屬性;對自己的 opacity 做 CSS 動畫或使用一個動畫 webkit 變換的元素;CSS過濾器(比如-webkit-filter: grayscale(100%))
資料來源:http://web.jobbole.com/91031/ 侵刪
2.vue的雙向綁定原理是什麼
VUE實現雙向數據綁定的原理就是利用了 Object.defineProperty() 這個方法,重新定義了對象獲取屬性值(get)和設置屬性值(set)的操作來實現的。observer、watcher、compiler
2. BFC的理解
BFC 全稱爲 塊格式化上下文。BFC是在css2.1提出的,它決定了元素如何對其內容進行定位,以及與其他元素的關係和如何相互影響。
BFC 特性(功能):1. 使 BFC 內部浮動元素不會到處亂跑;2. 和浮動元素產生邊界。
BFC就是一個獨立的容器,容器內和容器外的元素不會互相影響。
一個BFC是一個
HTML
盒子並且至少滿足下列條件中的任何一個:
float
的值不爲none
position
的值不爲static
或者relative
display
的值爲table-cell
,table-caption
,inline-block
,flex
, 或者inline-flex
中的其中一個overflow
的值不爲visible
3. 閉包
閉包,就是指能夠訪問另一個函數作用域的變量的函數。
使用場景:閉包一般的用途在,輪播、幻燈片,setInterval
比如:
// 計數器 var f1 = function () { var count = 0; return function () { return ++count; } }; var fun = f1() fun(); // 1 fun(); // 2
導致內存泄露的場景:循環引用,內部函數引用(閉包) 參考資料
垃圾收集機制的原理其實很簡單:找出那些不再繼續使用的變量,然後釋放其佔用的內存
4. http協議的理解,http請求頭和響應頭都有哪些字段?
http協議是無狀態、無連接的,目前http協議裏面版本一般的是1.1的
無連接的含義是限制每次連接只處理一個請求。服務器處理完客戶的請求,並收到客戶的應答後,即斷開連接
無狀態是指協議對於事務處理沒有記憶能力。缺少狀態意味着如果後續處理需要前面的信息,則它必須重傳,這樣可能導致每次連接傳送的數據量增大
http報文裏面主要由四層組成,響應頭,請求頭和請求體(裝載請求數據)
請求頭: refferer,accept,cache-control,content-type,cookie,user-agent,pragma,origin等
響應頭: allow,content-type,date,status,Access-Control-Allow-Origin,cache-control
常用狀態碼:
200 請求完成; 202 服務器已接受請求,但尚未處理
301 永久移動; 302 臨時重定向; 304 未修改(取緩存);200 OK (from memory/disk cache)
400 客戶端請求錯誤; 401 需要認證; 403 拒絕執行; 404 找不到資源
500 服務器內部錯誤; 502 錯誤的網關; 503 服務器不可用(超載或者維護); 504 網關超時
POST、PUT、DELETE等請求永遠不會被緩存,GET請求可以被緩存
再說一下http的三次握手和四次揮手,我自己是用打電話這個例子來幫助理解的
三次揮手
1. 首先A打電話給B(也就是客戶端想服務器發起請求,想和服務器建立連接)
2. B收到A的電話鈴聲,接電話,並“喂,是誰啊”(服務器接受了連接,並且想客戶端發送詢問)
3. A聽到了電話那頭傳過來的語音,就認爲電話接通了,“我是某某啊”(客戶端收到服務器的確認後,向服務器發送確認,表明連接已經建立了)
A然後就跟B說:“萬福金安,三天之內必好運...........”(接下來就是客戶端開始發送數據了...)
四次揮手
4. A說完了話(客戶端這個時候結束了發送數據,服務端收到客戶端結束髮送數據的信號)
5. 輪到B回覆了A的那一堆話(服務端向客戶端發送應該信號,表明服務端即將發送數據)
B開始說話了“三天之內.......” (此時服務端在向客戶端發送數據...)
6. B終於說完了,跟A說:“我好了” (此時服務端向客戶端發送結束數據傳輸的信號,表明數據發送已經完成)
7. A聽到B終於把話說完了,A說“好,我掛了” ,此時A說完這句話,等了一下,然後才掛斷電話(此時,客戶端收到服務器發送的數據發送完成信號,就向服務器發送應答信號,表明收到了所有數據,等待2msl後,A關閉連接)
此時B收到了之後,馬上就掛斷電話
5. 什麼是TCP/IP協議?
TCP/IP協議是一個協議集合。
TCP/IP 參考模型有四層,分別是應用層,網絡層,數據鏈路層,傳輸層。
OSI模型:應用層,表示層,會話層,傳輸層,數據鏈路層,物理層
7. new 一個實例的過程
1. 創建一個新的對象 var obj = {};
2. 設置新對象的constructor指向構造函數,將新對象的__proto__的對象指向構造函數的prototype對象 obj.__proto__ = class.prototype
3. 使用新對象調用函數,將函數的this指向新的實例對象 class.call(obj)
4. 將初始化完畢的新對象地址,返回到等式左邊的變量
8. 這段代碼輸出什麼?爲什麼?(異步、作用域、閉包)
輸出3 3 3。setTimeout是異步的,它會被放到事件隊列中,等待主線程上面的代碼執行完後,才執行事件隊列中的。所以for循環結束後,i是等於3的,事件隊列中的setTimeout開始執行的時候取到的值就是3了,所以輸出三次3。
若是要順序執行0 1 2的話,可這麼做:
或者
let的作用就是在每次循環的時候形成封閉的作用域,也就是每次的setTimeout都都綁定有一個特定的值的i
(function() {})()立即執行函數在每次循環的時候,函數都會被立刻執行,每次i的值都會被放在立刻執行的函數作用域裏
9.你在項目中遇到了哪些問題,並且如何解決的(開放問題)
10. 什麼是RESTful API ?
URL定位資源,用HTTP動詞(GET, POST, PUT, DELETE)描述操作
11. JS設計模式
工廠模式、單體模式、構造函數模式、模塊模式等等
參考鏈接: JS幾種設計模式
12. mixins和extend(組件複用)
mixins一般是用來混入一些常用的公共方法的,可全局混入或者在組件中混入
13. vue自定義指令
以下代碼自定義了一個指令v-loadimg,作用就是當圖片還沒有加載進來的時候,給img標籤加隨機背景顏色,當圖片加載進來的時候,去除背景色。這裏只是一個簡單的自定義指令的編寫
14.ES6數組方法
forEach(): 遍歷數組,沒有返回值
var a = [1,2,3,5] a.forEach((item, index, arr) => { // 元素, 下標, 原數組 console.log(item) }) // 輸出: 1, 2, 3, 5
map(): 遍歷數組每一個元素,並返回新數組
var a = [1,2,3,4,5] var b = a.map(function (item, index, arr) { // 元素, 下標, 原數組 return item * item }) // 輸出[1, 4, 9, 16, 25]
filter(): 過濾掉不符合條件的元素,返回新數組
var a = [1,2,3,4,5] var b = a.filter(function (item, index, arr) { // 元素, 下標, 原數組 return item > 3 }) // 輸出[4, 5]
reduce(): 對數組中的所有元素調用指定的回調函數。該回調函數的返回值爲累積結果,並且此返回值在下一次調用該回調函數時作爲參數提供。
var a = [1,2,3,4,5] var initialVal = 10 // 設定的初始值 可選 var b = a.reduce(function (total, currentValue, currentIndex, arr) { // 初始值、當前元素=》必選 |||| 當前索引、原數組 =》 可選 return total + currentValue }, initialVal) console.log(b) // 輸出 25
some(): 遍歷數組的每一項,若是遇到符合條件的,返回true,並停止循環;若全部不符合則返回false
var a = [1,2,3,4,5] var b = a.some(function (item, index, arr) { // 當前元素, 下標, 原數組 return item > 3 }) console.log(b) // 輸出 true
every(): 遍歷數組每一項,若是遇到不符合條件的,則返回false,並停止循環;若全部都符合則返回true
var a = [1,2,3,4,5] var b = a.every(function (item, index, arr) { // 當前元素, 下標, 原數組 console.log(item) return item < 3 }) console.log(b) // 輸出 false
15. 表現與數據分離?
通俗理解,就是DOM的操作邏輯和數據處理邏輯分離
16. webpack熱更新原理?
EventSource 是 HTML5 中 Server-sent Events 規範的一種技術實現。EventSource 接口用於接收服務器發送的事件。它通過HTTP連接到一個服務器,以text/event-stream 格式接收事件, 不關閉連接。通過 EventSource 服務端可以主動給客戶端發現消息,使用的是 HTTP協議,單項通信,只能服務器向瀏覽器發送; 與 WebSocket 相比輕量,使用簡單,支持斷線重連
17. this指向問題
函數調用(指向window) 對象方法(對象) 構造函數(實例化出來的對象) 計時器調用(window) 匿名函數(window)
原型中的this指向調用他的對象不指向本身
18. AMD(Asynchronous Module Definition異步模塊加載機制)規範,CMD(Common Module Definition)規範
- CMD 推崇依賴就近;AMD 推崇依賴前置
- CMD 是延遲執行;AMD 是提前執行
- CMD性能好,因爲只有用戶需要的時候才執行;AMD用戶體驗好,因爲沒有延遲,依賴模塊提前執行了
AMD異步,CMD同步
19. 一個頁面從輸入 URL 到頁面加載完的過程中都發生了什麼事情
1.瀏覽器接收URL
2.將URL與緩存進行比對如果請求的頁面在緩存中且未過期,則直接進行第8步
3.如果網絡地址不是一個 IP 地址,通過DNS解析域名返回一個IP地址
4.瀏覽器與服務器通過三次握手(SYN,SYN/ACK,ACK)建立TCP 連接
5.瀏覽器向服務器發送HTTP請求
6.服務器收到請求,從它的文檔空間中查找資源並返回HTTP響應
7.瀏覽器接受 HTTP 響應,檢查 HTTP header 裏的狀態碼,並做出不同的處理方式
8.如果是可以緩存的,這個響應則會被存儲起來
9.解碼 10.渲染
20. css都有哪些標籤選擇器?
標籤選擇器(div p),類選擇器(class="header"),ID選擇器(id="header"),全局選擇器(*),僞類選擇器(:after, :before),繼承選擇器(div p),後代選擇器(A>B),任意選擇器(A,B)
21. 重繪和重排
重排:若渲染樹的一部分更新,且尺寸變化,就會發生重排,可以理解爲渲染樹需要重新計算;(比如width, height, display:none / block, left, top...)
重繪:一個元素外觀的改變所觸發的瀏覽器行爲,例如改變visibility、outline、font-size、color、background等屬性
重排必定會引發重繪,但重繪不一定會引發重排
transform會導致重排麼?https://blog.csdn.net/weixin_33922670/article/details/89108346
22. 堆棧?
23. 前端性能優化
DNS Prefetch
<link rel="dns-prefetch" href="//cdn.xxx.com">
精靈圖,減少http連接數,減少dom的操作,使用gpu加速
24.CSRF和XSS
CSRF:是一種僞造跨站請求的攻擊方式. 例如利用你在 A 站 (攻擊目標) 的 cookie / 權限等, 在 B 站 (惡意/釣魚網站) 拼裝 A 站的請求.
CSRF預防方法:在 HTTP 頭中自定義屬性並驗證;cookie中加入hash隨機數;通過檢查來過濾簡單的 CSRF 攻擊, 主要檢查一下兩個 header:Origin Header, Referer Header (origin只用於Post請求,而Referer則用於所有類型的請求;)
XSS:跨站腳本 (Cross-Site Scripting, XSS) 是一種代碼注入方式
感謝網上的一些大佬文章的解決方案