一面(2022年2月21日):
中間挺多意外的:
- 自我介紹
- 介紹一下項(xiàng)目。
根據(jù)項(xiàng)目問(wèn)了以下一些問(wèn)題:
- 使用canvas過(guò)程中有沒(méi)有進(jìn)行一些優(yōu)化。用了緩存canvas來(lái)減少一部分操作步驟,然后問(wèn)了下如果緩存canvas過(guò)多怎么處理?這個(gè)沒(méi)答上來(lái),感覺(jué)有必要看一下Fabric的源代碼(面試官想讓我答LRU,但是每次重繪都要畫(huà)一次畫(huà)板,個(gè)人覺(jué)得做不到)。
- 然后問(wèn)我還有沒(méi)有其他項(xiàng)目要介紹的。我說(shuō)了一下electron的IM,其中提到消息超過(guò)一定數(shù)量進(jìn)行換頁(yè)處理,保持頁(yè)數(shù)在3頁(yè)(問(wèn)我為什么3頁(yè),我說(shuō)因?yàn)?頁(yè)的話,滾動(dòng)一下又要加載,體驗(yàn)不是很好)。因?yàn)橄⑻嗪苋菀卓ā?/li>
- 同時(shí)提了一下builder項(xiàng)目里面的靜態(tài)資源為什么用node處理的原因(因?yàn)閚ode不適合處理大片的內(nèi)存)。
之后就是:
- 你說(shuō)一下js的原型,原型鏈,實(shí)例和構(gòu)造函數(shù)之間的關(guān)系吧。
- 了解JS的繼承嗎?是怎么繼承的?
- 作用域和作用域鏈,執(zhí)行上下文和閉包。其中閉包和作用域以及執(zhí)行上下文有什么關(guān)系?
- 了解common js 和es6的module嗎?分別是什么??jī)烧哂惺裁磪^(qū)別?
- 你理解的模塊化是什么?(分隔代碼,方便管理。另外減少全局變量和函數(shù)命名沖突)。
- 用過(guò)webpack對(duì)吧,你理解中的webpack是什么來(lái)的?(講了下webpack是打包器還有AST)
- 講一下事件循環(huán)吧?宏任務(wù)有哪些?微任務(wù)有哪些?宏任務(wù)和宏任務(wù)之間就沒(méi)有其他東西了嗎(答了還有requestAnimationFrame和requestIdleCallback)?這邊對(duì)于requestAnimationFrame每次都一定會(huì)執(zhí)行不太確定,我答的是dom刷新才執(zhí)行。
- 數(shù)組和鏈表的區(qū)別
- vue你比較熟是吧?想問(wèn)下React和vue你覺(jué)得有什么區(qū)別?
- vue你用了這么久,那你覺(jué)得它有什么優(yōu)點(diǎn)和缺點(diǎn)?
- vue是怎么實(shí)現(xiàn)更改數(shù)據(jù)之后就觸發(fā)UI更新的?
- 虛擬dom有什么效果?
- 你談到虛擬Dom可以去掉無(wú)效的狀態(tài),直接到達(dá)最終狀態(tài)。那么如果我確實(shí)需要中間的狀態(tài)呢?(this.$nextTick)
- vue的diff是怎么樣的?復(fù)雜度多少?
- vue中的key有什么作用?如果不用key或者key使用數(shù)組的index,會(huì)有什么效果?
- http常用的頭部有哪些?
- 瀏覽器緩存機(jī)制是怎么樣的?(協(xié)商緩存和強(qiáng)緩存)。
- 做了兩道題:寫(xiě)debounce和合并兩個(gè)有序鏈表。
總結(jié)就是:
八股文復(fù)習(xí)不夠充分。另外項(xiàng)目的一些點(diǎn)沒(méi)有突出介紹,例如使用了單例模式,以及出于跨組件通信比較多而設(shè)計(jì)了時(shí)間總線之類(lèi)的都沒(méi)有說(shuō)。
- 原型鏈這種東西還是不能很流暢的說(shuō)出來(lái)。
- 事件循環(huán)或許需要復(fù)習(xí)一下背景還有更細(xì)節(jié)的一些內(nèi)容。
- http有復(fù)習(xí)但是感覺(jué)復(fù)習(xí)的不夠。例如協(xié)商緩存之類(lèi)的。
- vue的diff算法和key的作用得重新看一下。
- js為什么出現(xiàn)模塊化和兩種不同的模塊導(dǎo)出方案的差異。
二面(2月24日):
狀態(tài)不好,簡(jiǎn)單題想不出來(lái)掛了。
- 自我介紹 balabala
- 做一道題(沒(méi)做出來(lái)),題目如下:
// 編程題: 由'K'(人)和'O'(空地)組成的2D數(shù)據(jù),請(qǐng)計(jì)算人群的數(shù)量。
// 在空地里,人群是通過(guò)垂直方向或者水平方向上相鄰的人連接而成。
//
// 示例1
// 輸入:
// OKKKO
// OKKKO
// OKKKO
// OKKOO
// 輸出:1
//
// 示例2:
// KKOOO
// KOOOO
// OKOKO
// KOOOO
// 輸出:4
const data = [
'OKKKO'.split(''),
'OKKKO'.split(''),
'OKKKO'.split(''),
'OKKOO'.split('')
];
const data1 = [
'KKOOO'.split(''),
'KOOOO'.split(''),
'OKOKO'.split(''),
'KOOOO'.split('')
];
const data2 = [
['O', 'O'],
['K', 'K'],
['O', 'O'],
['K', 'O']
];
function walkGraphic (tdArr, map, x, y) {
if (map[`${x},${y}`]) {
return;
}
if (tdArr[x][y] !== 'K') {
return;
}
map[`${x},${y}`] = true;
if (tdArr[x - 1] && tdArr[x - 1][y]) {
walkGraphic(tdArr, map, x - 1, y);
}
if (tdArr[x + 1] && tdArr[x + 1][y]) {
walkGraphic(tdArr, map, x + 1, y)
}
if (tdArr[x][y + 1]) {
walkGraphic(tdArr, map, x, y + 1);
}
if (tdArr[x][y - 1]) {
walkGraphic(tdArr, map, x, y - 1);
}
}
function getGroupNums (tdArr) {
let groupNums = 0;
const map = {};
tdArr.forEach((arr, x) => {
arr.forEach((item, y) => {
if (item === 'K' && !map[`${x},${y}`]) {
groupNums += 1;
walkGraphic(tdArr, map, x, y);
}
});
});
return groupNums;
}
console.log(getGroupNums(data2));
問(wèn)一下簡(jiǎn)單的問(wèn)題
- 說(shuō)一下vue3和vue2的區(qū)別
- worker是什么?service worker是什么?
- worker和網(wǎng)頁(yè)其他內(nèi)容共享內(nèi)存嗎?(因?yàn)槭蔷€程,應(yīng)該是共享內(nèi)存的)
- grpc是什么協(xié)議?grpc協(xié)議運(yùn)行在網(wǎng)絡(luò)模型第幾層?(基于http2,所以應(yīng)該是應(yīng)用層)
- 用過(guò)nodejs嗎?(寫(xiě)腳本和寫(xiě)過(guò)后端)
- 你用node寫(xiě)過(guò)后端,那么請(qǐng)問(wèn)下你是怎么監(jiān)控后端的運(yùn)行情況的?異常監(jiān)控,api調(diào)用,cpu和內(nèi)存占用率這些。(不會(huì))
- 項(xiàng)目中為什么有webpack還要用vite?
反問(wèn):
- 前端做什么的?
- 前端團(tuán)隊(duì)有多少人?