您當前的位置:首頁 > 體育

位元組跳動前端面試經驗

作者:由 會講故事的蔣同學 發表于 體育時間:2021-05-10

一面面試經驗

1、資料庫正規化

2、TCP & UDP

3、UDP的例子(郵件、直播)

4、Hybrid Uni-App如何引用本地頁面hybrid

5、Webview 巢狀 Webview的原理

6、Webview 通訊 postMessage和postMessage chrome

7、JSBridge的原理

8、前端路由實現 hash模式、histroy模式

9、SEO最佳化有哪些操作;在商品很多的情況下,如何在商品詳情中寫入商品資訊(SSR、服務端渲染在標籤中寫入)

10、效能最佳化中,CSS壓縮的原理、圖片壓縮的原理

11、Webpack中,loader和plugin的原理,傳入物件是什麼

12、Webpack中,TS檔案如何轉成JS檔案

13、瀏覽器的eventLoop和node的eventLoop的區別?Node有哪些微執行緒

14、怎麼實現跨域?JSONP的原理

15、專案部署中,如何解決跨域?

16、多語言翻譯如何實現?

17、演算法題:二叉樹所有根到葉子路徑組成的數字之和

const root = {

value: 1,

left: {

value: 2,

left: {

value: 4,

},

right: {

value: 5,

}

},

right: {

value: 3

}

}

function pathSum(root) {

const paths = [];

/*

* dfs的方式進行遍歷樹

* curr表示當前節點

* path表示已經累計的路徑內容

*/

const dfs = (curr, path) => {

path += curr。value + ‘’; // 路徑累計,需要轉成字串

if(curr !== undefined && curr。left === undefined && curr。right === undefined) {

paths。push(path);

return;

}

if (curr。left !== undefined) {

dfs(curr。left, path);

}

if (curr。right !== undefined) {

dfs(curr。right, path);

}

}

dfs(root, ‘’);

let sum = 0;

for(let i = 0; i < paths。length; i++) {

sum += Number(paths[i]);

}

return sum

}

pathSum(root);

二面面試經驗

程式設計題1:

// 順序執行下面程式碼,請寫出列印結果:

function Foo(){

this。getName = function(){

console。log(‘1’)

};

return this;

}

Foo。getName = function() {

console。log(‘2’);

};

Foo。prototype。getName=function(){

console。log(‘3’);

};

var getName=function(){

console。log(‘4’)

};

function getName(){

console。log(‘5’);

};

// 列印

Foo。getName();// -> 2

getName(); // 函式變數提升 輸出 4

Foo()。getName();// -> 1

getName();// -> 1

new (Foo。getName)();// -> 2

(new Foo())。getName();// -> 1

程式設計題2:

實現 mergePromise 函式,把傳進去的陣列順序先後執行,並且把返回的資料先後放到陣列 data 中

const timeout = ms =>

new Promise((resolve, reject) => {

setTimeout(() => {

resolve()

}, ms)

})

const ajax1 = () =>

timeout(2000)。then(() => {

console。log(‘1’)

return 1

})

const ajax2 = () =>

timeout(1000)。then(() => {

console。log(‘2’)

return 2

})

const ajax3 = () =>

timeout(2000)。then(() => {

console。log(‘3’)

return 3

})

const mergePromise = ajaxArray => {

// 在這裡實現你的程式碼

let data = [];

// 這裡需要最佳化成,題目給出3個,需要做成list的形式

return new Promise((resolve, reject) => {

ajaxArray[0]()。then((res) => {

data。push(res)

return ajaxArray[1]()

})。then((res) => {

data。push(res)

return ajaxArray[2]()

})。then((res) => {

data。push(res);

resolve(data);

})。catch(err => {

reject(err)

})

})

}

mergePromise([ajax1, ajax2, ajax3])。then(data => {

console。log(‘done’)

console。log(data) // data 為 [1, 2, 3]

})

// 分別輸出

// 1

// 2

// 3

// done

// [1, 2, 3]

程式設計題3:

寫一個定時器函式 myTimer(fn, a, b),每次間隔 a,a+b,a+2b,。。。,a+nb 的時間執行fn,

該定時器返回一個函式為 myClear,可以停止上面的定時器 myTimer(請使用setTimeout來實現該題目,

myTimer函式只調用一次)

let fn = function() {

console。log(‘fn’)

}

let a = 1000, b = 1000;

function myTimer(fn, a, b) {

let timer;

let count = 0;

let delay = a + count * b;

console。log(fn, a, b);

// 這裡使用遞迴進行實現

const repeatSetTimeout = () => {

timer = setTimeout(() => {

fn();

count++;

delay = a + count * b;

repeatSetTimeout();

}, delay);

};

// 首次觸發

repeatSetTimeout();

const myClear = () => {

clearTimeout(timer)

};

return myClear;

}

console。log(fn, a, b);

myTimer(fn, a, b);

問答題:

1、瀏覽器協商快取和強快取的區別?last-modifide 和 ETag的優先順序哪個高?-> Etag高

2、命中協商快取,瀏覽器返回的狀態碼是多少?304

3、HTTP協議頭Cache-Control取值no-cache和no-storage的區別?

no-storage:徹底禁用緩衝,所有內容都不會被快取到快取或臨時檔案中。

no-cache:在瀏覽器使用快取前,會往返對比ETag,如果ETag沒變,返回304,則使用快取。

4、es5的繼承和es6的繼承的區別?哪一個是先生成子類,再生成父類,哪一個想先生成父類,再生成子類

5、http1。0和http2。0的區別,http2。0有哪些提升的地方?

6、Vue使用過程中,為啥需要繫結key?-> 提高diff的效率

三面

1、聊實際專案

2、最有收穫、最有意義的事情是什麼?

3、程式設計題:刪除一個已排序(升序)的單向連結串列中的重複元素,一旦元素重複,刪除全部該重複元素,例如1->2->2->3,

刪除結果為1-3,返回修正後的表頭,參考leetcode原題82。刪除排序連結串列中的重複元素 II https://leetcode-cn。com/problems/remove-duplicates-from-sorted-list-ii/

如果你是普通使用者,在海外網站上發帖,但是網站只告訴你該發帖含有違禁詞,沒有提示具體的違禁詞,你要怎麼找出違禁詞?——二分法查詢,先分成兩部分,然後各自發帖,如果發帖結果為含有違禁詞,繼續二分查詢,直到查詢到該詞

標簽: console  log  const  curr  return