前言
筆者其實是三月份就面的 Bigo
,當時工作經驗算一年半多。之所以現在才發,其實是之前雖然總結了,但多半是自己總結歸納復盤用,有點粗糙,現在重新整理,希望對大家有所幫助
一面
說說 Javascript
的數據類型
最新的 ECMAScript
標準 定義了 8 種數據類型
原始數據類型:Boolean、Null、Undefined、Number、BigInt、String、Symbol
引用類型:對象(Object
)。其中對象類型包括:數組(Array
)、函數(Function
)、還有兩個特殊的對象:正則(RegExp
)和日期(Date
)
加分項:BigInt
和 Symbol
類型
BigInt
是一種數字類型的數據,它可以表示任意精度格式的整數。由于 Number
類型的局限性。Number 類型的局限性(JavaScript 中的 Number
是雙精度浮點型,這意味著精度有限,如下所示)
const max = Number.MAX_SAFE_INTEGER; // 9007199254740991
max + 1 // 9007199254740992
max + 2 // 9007199254740992
注意 max + 1 === max + 2
,這是不對的
BigInt
就是解決此類問題
Symbol
類型的使用場景
Symbol
: 表示獨一無二的值,通過 Symbol
函數生成,接收一個字符串作為參數,表示對 Symbol
實例的描述,主要是為了在控制臺顯示
應用場景:Symbol
的目的就是為了實現一個唯一不重復不可變的值,任何一個 Symbol
都是唯一的,不會和其他任何 Symbol
相等
- 對象中保證不同的屬性名
- 注意:使用
Symbol
值定義屬性的時候,必須放在方括號中 - 讀取的時候也是不能使用點運算符
- 注意:使用
- 定義一組常量,保證這組常量都是不相等的
- 使用 Symbol 定義類的私有屬性/方法
const bar = Symbol('bar');
const snaf = Symbol('snaf');
export default class myClass{
// 公有方法
foo(baz) {
this[bar](baz);
}
// 私有方法
[bar](baz) {
return this[snaf] = baz; //私有屬性
}
// ...
};
-
Vue
中的 project 和 inject
其他應該留意的知識點:
-
注意屬性名的遍歷
- 遍歷對象的時候,該屬性不會出現在 for...in...、for...of循環中,也不會被Object.keys()、Object.getOwnPropertyNames()、JSON.stringify()返回
- 可以通過 Object. getOwnPropertySymbols()
-
Symbol.hasInstance
- 指向一個內部方法。當其他對象使用 instanceof 運算符,判斷是否為該對象的實例的時候,會調用這個方法
- 比如,foo instanceof Foo在語言內部,實際調用的是Foo[Symbol.hasInstance](foo),有點類似劫持了 instanceof 方法
class MyClass {
[Symbol.hasInstance](foo) {
return foo instanceof Array;
}
}
[1, 2, 3] instanceof new MyClass() // true
null
和 undefined
的區別
null
類型代表著空值,代表著一個空指針對象,typeof
null
會是得到 'object'
所以可以認為它是一個特殊的對象值。undefined
當你聲明一個變量未初始化的時候,得到的就是 undefined
-
typeof
的值不一樣
console.log(typeof undefined); //undefined
console.log(typeof null); //object
- 轉為數值時,值不一樣
console.log(Number(undefined)); //NaN
console.log(undefined + 10);//NaN
console.log(Number(null)); //0
console.log(null + 10); //10
- === 運算符可區分
null
和undefined
-
null
使用的場景- 作為對象原型鏈的終點
Object.getPrototypeOf(Object.prototype) // null
- 作為對象原型鏈的終點
-
undefined
的典型用法 【變量,函數參數,函數返回,對象屬性】
常見的頁面性能優化
HTTP 上有哪些優化手段
重排和重繪的概念,以及如何避免重排和重繪
TCP 三次握手和 TCP 四次握手的區別
關于TCP的握手機制,一定不要死記硬背,要理解為什么這么設計,也就很容易記住了
三次握手:
在客戶端和服務器之間建立正常的TCP網絡連接時,客戶端首先會發出一個
SYN
消息,服務器使用SYN+ACK
應答表示已經接收到這個消息,最后客戶端再以ACK
消息響應。這樣在客戶端和服務器之間才能建立起可靠的TCP
連接,數據才可以在客戶端和服務器之間傳遞建立連接時,客戶端發送
SYN
包到服務器,等待服務器響應。(SYN
同步序列編號,是建立連接時使用的握手信號)服務器收到
SYN
包,使用ACK
包進行確認應答,同時自己也會發送一個SYN
包,即發送SYN+ACK
包。
客戶端收到服務器的SYN
包,向服務器發送確認包ACK
。此包發送完畢,代表TCP
連接完成,完成了三次握手
四次揮手:四次揮手是釋放 TCP
連接的握手過程
- 客戶端向服務端發送釋放連接報文
FIN
,等待服務端確認,并停止發送數據 - 服務器收到連接釋放請求后,發送
ACK
包表示確認。(此狀態下,表示客戶端到服務器的連接已經釋放,不再接受客戶端發的數據了,但是服務器要是還發送數據,客戶端依然接收) - 服務器將最后的數據發送完畢后,就向客戶端發送連接釋放報文
FIN
,等待客戶端確認。 - 客戶端收到服務器連接釋放報文后,發出
ACK
包表示確認。此時客戶端會進入TIME_WAIT
狀態,該狀態將持續2MSL
(最大報文段生存時間,指報文段在網絡中生存的時間,超時將被拋棄)時間,若該時間段內沒有服務器重發請求的話,就進入關閉狀態,當服務端接收到ACK
應答后,立即進入關閉狀態
[圖片上傳失敗...(image-557c6c-1601881810112)]
webpack 性能優化怎么做的?
小程序的數據更新是怎樣的?
小程序有哪些線程?
[圖片上傳失敗...(image-7bc44e-1601881810112)]
- 小程序的渲染層和邏輯層分別由 2 個線程管理:渲染層的界面使用了
WebView
進行渲染,邏輯層采用 JsCore 線程運行 JS 腳本 - 邏輯層:創建一個單獨的線程去執行 JavaScript,在這個環境下執行的都是有關小程序業務邏輯的代碼,由于 js 不跑在
WebView
里,就不能直接操縱 DOM 和 BOM,這就是小程序沒有 window 全局變量的原因 - 渲染層:界面渲染相關的任務全都在
WebView
線程里執行,通過邏輯層代碼去控制渲染哪些界面。一個小程序存在多個界面,所以渲染層存在多個WebView
線程 - 雙線程通信【Virtual DOM 相信大家都已有了解,大概是這么個過程:用JS對象模擬DOM樹 -> 比較兩棵虛擬DOM樹的差異 -> 把差異應用到真正的DOM樹上。】
1、在渲染層把 WXML 轉化成對應的 JS 對象
2、在邏輯層發生數據變更的時候,通過宿主環境提供的 setData 方法把數據從邏輯層傳遞到 Native,再轉發到渲染層
3、經過對比前后差異,把差異應用在原來的 DOM 樹上,更新界面
[圖片上傳失敗...(image-7c1072-1601881810112)]
小程序多次設置很多數據的時候會對性能產生很大的影響么?怎么優化
有,可以統一一次設置,多次盡量最后一次設置
Vue 2.x
的實現原理?
回答了雙向數據綁定的相關原理
Vue 的 diff 算法
Vue 的 compile 過程
- 主要是三個過程
parse
,optimize
,generate
- compile 的作用是解析模板,生成渲染模板的 render。而 render 的作用,也是為了生成跟模板節點一一對應的 Vnode
- parse: 接收 template 原始模板,按照模板的節點 和數據 生成對應的 ast【通過大量的正則匹配去實現對字符串的解析】
- Optimize:遍歷遞歸每一個ast節點,標記靜態的節點(沒有綁定任何動態數據),這樣就知道那部分不會變化,于是在頁面需要更新時,減少去比對這部分DOM。從而達到性能優化的目的。【為什么要有優化過程,因為我們知道 Vue 是數據驅動,是響應式的,但是我們的模板并不是所有數據都是響應式的,也有很多數據是首次渲染后就永遠不會變化的,那么這部分數據生成的 DOM 也不會變化,我們可以在 patch 的過程跳過對他們的比對。】
- Generate:把前兩步生成完善的 ast 組裝成 render 字符串(這個 render 變成函數后是可執行的函數,不過現在是字符串的形態,后面會轉成函數)
Vuex簡單的原理實現【同時考察了發布訂閱的模式】
移動端有哪些兼容的場景【重點回顧】
- 1px 問題解決:http://www.lxweimin.com/p/3a262758abcf
- 防止手機中頁面放大和縮小
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
- 上下拉動滾動條時卡頓、慢。Android3+和iOSi5+支持CSS3的新屬性為overflow-scrolling
body {
-webkit-overflow-scrolling:touch;
overflow-scrolling:touch;
}
- ios和android下觸摸元素時出現半透明灰色遮罩
-webkit-tap-highlight-color:rgba(255,255,255,0);
- click 的
300ms
延遲問題
問題:在移動端中,click事件是生效的,但是,點擊之后會有300ms的延遲響應
原因:safari是最早做出這個機制的,因為在移動端里,瀏覽器需要等待一段時間來判斷此次用戶操作是單擊還是雙擊,所以就有click 300ms 的延遲機制
方案一:禁用縮放
當 HTML
文檔頭部包含如下 meta
標簽時:表明這個頁面是不可縮放的,那雙擊縮放的功能就沒有意義了,此時瀏覽器可以禁用默認的雙擊縮放行為并且去掉 300ms
的點擊延遲
<meta name="viewport" content="user-scalable=no">
<meta name="viewport" content="initial-scale=1,maximum-scale=1">
方案二:更改默認的視口寬度
<meta name="viewport" content="width=device-width">
如果設置了上述meta標簽,那瀏覽器就可以認為該網站已經對移動端做過了適配和優化,就無需雙擊縮放操作了
??這個方案相比方案一的好處在于,它沒有完全禁用縮放,而只是禁用了瀏覽器默認的雙擊縮放行為,但用戶仍然可以通過雙指縮放操作來縮放頁面。
方案三:引入 fastclick
庫來解決
FastClick
的實現原理是在檢測到 touchend
事件的時候,會通過 DOM
自定義事件立即出發模擬一個click事件,并把瀏覽器在300ms之后的click事件阻止掉。
參考:http://www.lxweimin.com/p/b5c103a9bed0
水平居中和垂直居中
node有使用過么
二面
HTTP 中的 content-encoding
Content-Encoding
是一個實體消息首部,用于對特定媒體類型的數據進行壓縮。當這個首部出現的時候,它的值表示消息主體進行了何種方式的內容編碼轉換。這個消息首部用來告知客戶端應該怎樣解碼才能獲取在 Content-Type
中標示的媒體類型內容。
Content-Encoding: gzip
Content-Encoding: compress
Content-Encoding: deflate
Content-Encoding: identity
Content-Encoding: br
參考:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Content-Encoding
HTTP
中的長連接
HTTP
協議采用“請求-應答”模式,當使用普通模式,即非 KeepAlive
模式時,每個請求/應答客戶和服務器都要新建一個連接,完成 之后立即斷開連接(HTTP
協議為無連接的協議);當使用 Keep-Alive
模式(又稱持久連接、連接重用)時,Keep-Alive
功能使客戶端到服 務器端的連接持續有效,當出現對服務器的后繼請求時,Keep-Alive
功能避免了建立或者重新建立連接
http 1.0
中默認是關閉的,需要在 http
頭加入 "Connection: Keep-Alive"
,才能啟用 Keep-Aliv
e;http 1.1
中默認啟用 Keep-Alive
,如果加入 "Connection: close ",才關閉。目前大部分瀏覽器都是用 http1.1 協議,也就是說默認都會發起 Keep-Alive 的連接請求了,所以是否能完成一個完整的 Keep- Alive
連接就看服務器設置情況
參考:https://blog.csdn.net/gt11799/article/details/41147933
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Keep-Alive
說下 JS 中的事件循環
強緩存和協商緩存
啟發緩存有了解過么
- 沒有任何關于緩存的字段 —— 不設置任何緩存策略
- 常會取響應頭中的
Date
減去Last-Modified
值的 10% 作為緩存時間
參考:
V8 中的垃圾回收機制
參考:【Web技術】737- 深入理解 Chrome V8垃圾回收機制
node 的全局變量有哪些
JavaScript
中有一個特殊的對象,稱為全局對象(Global Object
),它及其所有屬性都可以在程序的任何地方訪問,即全局變量
在瀏覽器 JavaScript 中,通常 window 是全局對象, 而 Node.js 中的全局對象是 global
,所有全局變量(除了 global 本身以外)都是 global
對象的屬性。
在 Node.js 我們可以直接訪問到 global 的屬性,而不需要在應用中包含它。
global,process,__filename,__dirname
參考:Node.js 全局對象
node 了解程度
ES6 有了解哪些?
set 和 map 有了解么?
map 的實現原理是什么?
Map
利用鏈表,hash
的思想來實現。
首先,Map可以實現刪除,而且刪除的數據可以是中間的值。而鏈表的優勢就是在中間的任意位置添加,刪除元素都非常快,不需要移動其他元素,直接改變指針的指向就可以。而在存儲數據很多的情況下,會導致鏈條過長,導致查找效率慢,所以我們可以創建一個桶(存儲對象的容器),根據 hash
(把散列的值通過算法變成固定的某值)來平局分配數據,防止鏈條過長。
參考:
為什么要想著離職呢?
算法題
輸入[1,3,1,3,2],輸出數組中唯一一個只存在一項的值,比如如上就是 2
三面
談談你的項目【其中針對項目進行了提問】
說說 webpack 打包優化
從一個數組中拿到前三個最小的值
一道編程題
[1,2,3,1,2,4,1,3,2,1] [1,2] [3,4,5] =>[3,4,5,3,3,4,5,4,1,3,2,1]
說明:第一個輸入是原始數組,第二個輸入是一個條件:要在原始數組中的連續數組,第三個輸入是要替換掉原數組符合參數二條件的數據
能夠使用的api:
1. 數組的長度獲取。
2. 數組某個下標對應的數字。
3. 往數組里push元素。
總結
歸納總結了 Bigo 一二三面的知識,有一些問題總結回答建議,有一些沒有,希望對大家有幫助