字節(jié)跳動(dòng)前端日常實(shí)習(xí)一二三面面經(jīng)(offer還愿)
作者:Jieunsi
https://www.nowcoder.com/discuss/670720?from=kaifazhe0630
時(shí)間線
5.19投遞簡(jiǎn)歷
5.20hr約一面
5.24一面
5.25中午一面通過(guò),hr約二面時(shí)間。本來(lái)約的是6月1號(hào),但面試官臨時(shí)請(qǐng)假,改到了3號(hào)
6.3二面
6.4下午二面通過(guò),hr約三面時(shí)間
6.8三面
6.9中午三面通過(guò),hr約10號(hào)三面
有些問(wèn)題可能不是面試官的本意,還有一些問(wèn)題沒(méi)聽(tīng)懂,從場(chǎng)景題提取問(wèn)題出來(lái)還是挺難的 其實(shí)15號(hào)中午的時(shí)候就offer了,現(xiàn)在來(lái)添加面經(jīng)答案,答案只是我的見(jiàn)解哈,有些部分也沒(méi)給出來(lái),如果有錯(cuò)誤歡迎指出
一面(???0mins)
怎么判斷兩個(gè)網(wǎng)站是否同域
?瀏覽器從一個(gè)域向另一個(gè)域的服務(wù)器發(fā)送請(qǐng)求來(lái)訪問(wèn)其資源。瀏覽器的同源策略:協(xié)議、域名、端口號(hào)一致。
?
保持登錄狀態(tài)能夠使用什么實(shí)現(xiàn)
?cookie,token
?
externals是怎么實(shí)現(xiàn)的 你這些外部的資源是存在公共的CDN上,還是有現(xiàn)成可以直接用的托管CDN
?回答了公共的CDN
?
是哪種類型的CDN呢,具體是哪些域名 為什么CDN能夠加速用戶訪問(wèn)一個(gè)網(wǎng)站,它的原理是什么
?最簡(jiǎn)單的CDN網(wǎng)絡(luò)由一個(gè)DNS服務(wù)器和幾臺(tái)緩存服務(wù)器組成:
i. 當(dāng)用戶點(diǎn)擊網(wǎng)站頁(yè)面上的內(nèi)容URL,經(jīng)過(guò)本地DNS系統(tǒng)解析,DNS系統(tǒng)會(huì)最終將域名的解析權(quán)交給CNAME指向的CDN專用DNS服務(wù)器。
ii. CDN的DNS服務(wù)器將CDN的全局負(fù)載均衡設(shè)備IP地址返回給用戶
iii. 用戶向CDN的全局負(fù)載均衡設(shè)備發(fā)起內(nèi)容URL訪問(wèn)請(qǐng)求
iv. CDN全局負(fù)載均衡設(shè)備根據(jù)用戶IP地址,以及用戶請(qǐng)求的內(nèi)容URL,選擇一臺(tái)用戶所屬區(qū)域的區(qū)域負(fù)載均衡設(shè)備,告訴用戶向這臺(tái)設(shè)備發(fā)起請(qǐng)求
v. 區(qū)域負(fù)載均衡設(shè)備會(huì)為用戶選擇一臺(tái)合適的緩存服務(wù)器提供服務(wù),選擇的依據(jù)包括:根據(jù)用戶IP地址,判斷哪一臺(tái)服務(wù)器距用戶最近;根據(jù)用戶所請(qǐng)求的URL中攜帶的內(nèi)容名稱,判斷哪一臺(tái)服務(wù)器上有用戶所需內(nèi)容;查詢各個(gè)服務(wù)器當(dāng)前的負(fù)載情況,判斷哪一臺(tái)服務(wù)器尚有服務(wù)能力?;谝陨线@些條件的綜合分析之后,區(qū)域負(fù)載均衡設(shè)備會(huì)向全局負(fù)載均衡設(shè)備返回一臺(tái)緩存服務(wù)器的IP地址
vi. 全局負(fù)載均衡設(shè)備把服務(wù)器的IP地址返回給用戶
vii. 用戶向緩存服務(wù)器發(fā)起請(qǐng)求,緩存服務(wù)器響應(yīng)用戶請(qǐng)求,將用戶所需內(nèi)容傳送到用戶終端。如果這臺(tái)緩存服務(wù)器上并沒(méi)有用戶想要的內(nèi)容,而區(qū)域均衡設(shè)備依然將它分配給了用戶,那么這臺(tái)服務(wù)器就要向它的上一級(jí)緩存服務(wù)器請(qǐng)求內(nèi)容,直至追溯到網(wǎng)站的源服務(wù)器將內(nèi)容拉到本地
?
怎么確定哪個(gè)CDN節(jié)點(diǎn)離用戶最近呢
?上個(gè)問(wèn)題答案的第4.5點(diǎn)
?
假設(shè)同樣的資源,我用域名去訪問(wèn),訪問(wèn)到哪個(gè)服務(wù)器取決于什么?
?DNS
?
DNS解析過(guò)程
?簡(jiǎn)單的來(lái)說(shuō),瀏覽器先檢查自身有沒(méi)有緩存,如果沒(méi)有就檢查操作系統(tǒng)有沒(méi)有緩存,如果還是沒(méi)有就會(huì)向本地域名服務(wù)器發(fā)起一個(gè)請(qǐng)求來(lái)解析這個(gè)域名;如果本地域名服務(wù)器還是沒(méi)有,則會(huì)從根域名服務(wù)器開(kāi)始遞歸查找域名,直到找到為止。
?
DNS解析過(guò)程中,某個(gè)DNS服務(wù)器的記錄被篡改過(guò),指向一個(gè)惡意網(wǎng)站,這種情況會(huì)對(duì)用戶的訪問(wèn)造成安全風(fēng)險(xiǎn),這么防范。怎么防范DNS污染(應(yīng)該是這個(gè)問(wèn)題)
?感覺(jué)這個(gè)問(wèn)題不是很重要
?
DNS使用什么網(wǎng)絡(luò)協(xié)議
?DNS區(qū)域傳輸?shù)臅r(shí)候使用TCP協(xié)議:
1.輔域名服務(wù)器會(huì)定時(shí)(一般3小時(shí))向主域名服務(wù)器進(jìn)行查詢以便了解數(shù)據(jù)是否有變動(dòng)。如有變動(dòng),會(huì)執(zhí)行一次區(qū)域傳送,進(jìn)行數(shù)據(jù)同步。區(qū)域傳送使用TCP而不是UDP,因?yàn)閿?shù)據(jù)同步傳送的數(shù)據(jù)量比一個(gè)請(qǐng)求應(yīng)答的數(shù)據(jù)量要多得多。
2.TCP是一種可靠連接,保證了數(shù)據(jù)的準(zhǔn)確性。
域名解析時(shí)使用UDP協(xié)議:
客戶端向DNS服務(wù)器查詢域名,一般返回的內(nèi)容都不超過(guò)512字節(jié),用UDP傳輸即可。不用經(jīng)過(guò)三次握手,這樣DNS服務(wù)器負(fù)載更低,響應(yīng)更快。理論上說(shuō),客戶端也可以指定向DNS服務(wù)器查詢時(shí)用TCP,但事實(shí)上,很多DNS服務(wù)器進(jìn)行配置的時(shí)候,僅支持UDP查詢
?
除了打包體積減小,還有哪些手段可以提升用戶的訪問(wèn)速度
?緩存,懶加載,代碼優(yōu)化,SSR...
?
HTTP緩存怎么設(shè)置
?通過(guò)設(shè)置Cache-Control/Pragma、Expires(過(guò)期時(shí)間)、Last-Modified/Etag。
?
確定協(xié)商緩存有效性的協(xié)商過(guò)程是怎么樣的
?在第一次請(qǐng)求服務(wù)器時(shí),服務(wù)器會(huì)返回資源,并且返回一個(gè)資源的緩存標(biāo)識(shí),一起存到瀏覽器的緩存數(shù)據(jù)庫(kù)。當(dāng)?shù)诙握?qǐng)求資源時(shí),瀏覽器會(huì)首先將緩存標(biāo)識(shí)發(fā)送給服務(wù)器,服務(wù)器拿到標(biāo)識(shí)后判斷標(biāo)識(shí)是否匹配,如果不匹配,表示資源有更新,服務(wù)器會(huì)將新數(shù)據(jù)和新的緩存標(biāo)識(shí)一起返回到瀏覽器;如果緩存標(biāo)識(shí)匹配,表示資源沒(méi)有更新,并且返回 304 狀態(tài)碼,瀏覽器就讀取本地緩存服務(wù)器中的數(shù)據(jù)。
?
有些資源打開(kāi)頁(yè)面的時(shí)候不需要,需要的時(shí)候在加載
?懶加載
?
不同類型的東西處理方式不一樣,例如圖片,js代碼,他們分別怎么懶加載
?js通過(guò)設(shè)置defer和async
?
建議圖片懶加載多去看看實(shí)現(xiàn)方法 有沒(méi)有更簡(jiǎn)單的方式去判斷圖片離瀏覽器頂部距離的方法
?面試官建議:intersectionObserver?這個(gè)API,可以監(jiān)控一個(gè)元素即將進(jìn)入到窗口的范圍
?
說(shuō)一下Vue的工作原理(響應(yīng)式原理)
?Vue響應(yīng)式底層實(shí)現(xiàn)方法是 Object.defineProperty() 方法,該方法中存在一個(gè)getter和setter的可選項(xiàng),可以對(duì)屬性值的獲取和設(shè)置造成影響
1. 當(dāng)你把一個(gè)普通的 JavaScript 對(duì)象傳入 Vue 實(shí)例作為 data 選項(xiàng),Vue將遍歷此對(duì)象所property,并使用 Object.defineProperty 把這property 全部轉(zhuǎn)為 getter/setter。
2. 這些 getter/setter 對(duì)用戶來(lái)說(shuō)是不可見(jiàn)的,但是在內(nèi)部它們讓 Vue 能夠追蹤依賴,在 property 被訪問(wèn)和修改時(shí)通知變更。
3. 每個(gè)組件實(shí)例都對(duì)應(yīng)一個(gè) watcher 實(shí)例,它會(huì)在組件渲染的過(guò)程中把“接觸”過(guò)的數(shù)據(jù) property 記錄為依賴。之后當(dāng)依賴項(xiàng)的 setter 觸發(fā)時(shí),會(huì)通知 watcher,從而使它關(guān)聯(lián)的組件重新渲染。
?
我改變了一個(gè)Data中數(shù)據(jù)后,他怎么更新到實(shí)際頁(yè)面的DOM,這個(gè)過(guò)程是怎樣的 模板里面,對(duì)于一個(gè)字段的引用是怎么收集的 對(duì)于這個(gè)字段的依賴是在什么時(shí)候建立的呢,是怎么建立的呢 假設(shè)有A,B兩個(gè)請(qǐng)求,希望在A請(qǐng)求完后拿到一個(gè)結(jié)果,之后將A的結(jié)果作為參數(shù)給B,B發(fā)起請(qǐng)求,這樣的過(guò)程要怎么實(shí)現(xiàn)
?異步操作
?
如果A,B沒(méi)有依賴關(guān)系,希望兩個(gè)都拿到結(jié)果之后,在執(zhí)行一些操作,要怎么實(shí)現(xiàn)
?Promise.all
?
你提到Promise.all,那假設(shè)瀏覽器沒(méi)有這個(gè)東西,你給我整一個(gè)
function myPromiseAll(promises) {
let results = [];
let promiseCount = 0;
let promisesLength = promises.length;
return new Promise(function(resolve, reject) {
for(let i = 0; i < promises.length; i++){
Promise.resolve(promises[i]).then(function(res) {
promiseCount++;
results[i] = res;
// 當(dāng)所有函數(shù)都正確執(zhí)行了,resolve輸出所有返回結(jié)果。
if (promiseCount === promisesLength) {
return resolve(results);
}
}, function(err) {
return reject(err);
});
}
});
};
反問(wèn)
?部門:交叉面試
建議:多實(shí)踐
?
二面(牛客38mins)
簡(jiǎn)單問(wèn)了下項(xiàng)目的東西 項(xiàng)目里有訂單管理的功能,一般來(lái)說(shuō)訂單要考慮什么狀態(tài)呢 如何實(shí)時(shí)拿到這些狀態(tài)呢 最近在學(xué)什么呢 vue框架有什么特點(diǎn)
?數(shù)據(jù)驅(qū)動(dòng)、組件化
?
手撕代碼(寫完說(shuō)思路)
function bubbleSort(array){
let length = array.length;
for(let i = 0; i < length - 1; i++){
for(let j = 0; j < length - i -1; j++){
if(array[j] < array[j+1]){
[array[j],array[j+1]] = [array[j+1],array[j]];
}
}
}
}
let test = [6,8,4,5,1];
bubbleSort(test);
console.log(test);
function quickSort(array){
if(array.length < 2) return array;
let leftArray = [];
let rightArray = [];
let base = array[0];
array.forEach((element) => {
if(element > base){
leftArray.push(element);
} else if(element < base){
rightArray.push(element);
}
});
return quickSort(leftArray).concat(base,quickSort(rightArray));
};
let test2 = [5,3,2,1,4];
let res = quickSort(test2);
console.log(res);
?實(shí)現(xiàn)一個(gè)函數(shù),把一個(gè)字符串?dāng)?shù)組(['zm', 'za', 'b', 'lm', 'ln', 'k'])格式化成一個(gè)對(duì)象 { 'b': ['b'], 'k': ['k'], 'l': ['lm', 'ln'], 'z': ['za', 'zm'] }
?
這道題沒(méi)寫完整,說(shuō)了下思路用偽代碼寫了下。
近一兩年的規(guī)劃 為什么選擇字節(jié)
三面6.8(???8mins)
聊了下之前的筆試 參與之前的面試下來(lái),有什么感受,有沒(méi)有總結(jié)出自己的長(zhǎng)處與短板
?提到了要深入學(xué)原理源碼啥的
?
你打算怎么看源碼 聊一下項(xiàng)目 為什么做這個(gè)項(xiàng)目 項(xiàng)目有沒(méi)有你自己想的一些功能 怎樣從零搭建項(xiàng)目
?感覺(jué)就是看你是不是真的自己做了一遍
使用vue-cli初始化的步驟
?
vue-cli主要幫你完成了哪些事情
?1.ES6代碼轉(zhuǎn)換成ES5代碼 2. scss/sass/less/stylus轉(zhuǎn)css 3. .vue文件轉(zhuǎn)換成js文件 4. 使用 jpg、png,font等資源文件 4. 自動(dòng)添加css各瀏覽器產(chǎn)商的前綴 5. 代碼熱更新 6. 資源預(yù)加載 7. 每次構(gòu)建代碼清除之前生成的代碼 8. 定義環(huán)境變量 9. 區(qū)分開(kāi)發(fā)環(huán)境打包跟生產(chǎn)環(huán)境打包 ......
?
其中生成的那些文件,分別是干什么的 packjson文件里有一些key,value。其中一個(gè)key叫dependencies和devDependencies,能說(shuō)說(shuō)作用嗎
?package.json:
主要用來(lái)定義項(xiàng)目中需要依賴的包
package-lock.json:
在 npm install時(shí)候生成一份文件,用以記錄當(dāng)前狀態(tài)下實(shí)際安裝的各個(gè)npm package的具體來(lái)源和版本號(hào)。
'^' :放在版本號(hào)之前,表示向后兼容依賴,說(shuō)白了就是在大版本號(hào)不變的情況下,下載最新版的包
項(xiàng)目中引入的包版本號(hào)之前經(jīng)常會(huì)加^號(hào),每次在執(zhí)行npm install之后,下載的包都會(huì)發(fā)生變化,為了系統(tǒng)的穩(wěn)定性考慮,每次執(zhí)行完npm install之后會(huì)對(duì)應(yīng)生成package-lock文件,該文件記錄了上一次安裝的具體的版本號(hào),相當(dāng)于是提供了一個(gè)參考,在出現(xiàn)版本兼容性問(wèn)題的時(shí)候,就可以參考這個(gè)文件來(lái)修改版本號(hào)即可。
i.“dependencies” 運(yùn)行依賴,需引入頁(yè)面使用
ii.“devDependencies” 開(kāi)發(fā)依賴(生產(chǎn)環(huán)境使用),只是開(kāi)發(fā)階段需要
?
babel.config.js的作用
?Babel是一個(gè)JS編譯器,主要作用是將ECMAScript 2015+ 版本的代碼,轉(zhuǎn)換為向后兼容的JS語(yǔ)法,以便能夠運(yùn)行當(dāng)前和舊版本的瀏覽器或其它環(huán)境中。
?
Vue項(xiàng)目中普遍使用ES6語(yǔ)法,若要求兼容低版本瀏覽器,就需要引入Babel,將ES6轉(zhuǎn)換為ES5。
babel怎么把es6轉(zhuǎn)成es5 es6哪些特性你覺(jué)得比較常用或者好用 let const var區(qū)別
?變量提升方面:var聲明的變量存在變量提升,即變量可以在聲明之前調(diào)用,值為undefined。let和const不存在變量提升問(wèn)題(注意這個(gè)‘問(wèn)題’后綴,其實(shí)是有提升的,只不過(guò)是let和const具有一個(gè)暫時(shí)性死區(qū)的概念,即沒(méi)有到其賦值時(shí),之前就不能用),即它們所聲明的變量一定要在聲明后使用,否則報(bào)錯(cuò)。
塊級(jí)作用域方面:var不存在塊級(jí)作用域,let和const存在塊級(jí)作用域
聲明方面:var允許重復(fù)聲明變量,let和const在同一作用域不允許重復(fù)聲明變量。其中const聲明一個(gè)只讀的常量(因?yàn)槿绱?,其聲明時(shí)就一定要賦值,不然報(bào)錯(cuò))。一旦聲明,常量的值就不能改變。
?
回到項(xiàng)目,登錄功能怎么實(shí)現(xiàn)的 token怎么保持登錄狀態(tài)
?當(dāng)用戶請(qǐng)求頁(yè)面,輸入用戶信息,服務(wù)端經(jīng)過(guò)驗(yàn)證后,會(huì)生成一個(gè)token安全令牌(隨機(jī)字符串),并返回給客戶端,當(dāng)客戶端發(fā)送下一次請(qǐng)求的時(shí)候,直接攜帶這個(gè)token,服務(wù)端識(shí)別后,就可以直接訪問(wèn)頁(yè)面,不需要再次登錄了
?
sessionStorage有什么優(yōu)勢(shì),token應(yīng)該放在哪
sessionStorage的特點(diǎn)
?+各個(gè)標(biāo)簽頁(yè)的sessionStorage 是獨(dú)立的 。+在a標(biāo)簽頁(yè)寫入修改刪除sessionStorage ,不會(huì)影響到已經(jīng)打開(kāi)的標(biāo)簽頁(yè)中的sessionStorage 。+通過(guò)a標(biāo)簽,window.open,window.location,windows.history ,右鍵復(fù)制 等方式在新標(biāo)簽頁(yè),本頁(yè),iframe ,新窗口中打開(kāi)新頁(yè)面,當(dāng)前標(biāo)簽頁(yè)的 sessionStorage 會(huì)傳遞到新頁(yè)面。+通過(guò)按住 ctrl鍵打開(kāi)新標(biāo)簽頁(yè),或者右鍵菜單打開(kāi)新標(biāo)簽頁(yè),新窗口 ,當(dāng)前標(biāo)簽頁(yè)的 sessionStorage 是不會(huì)傳遞到新頁(yè)面的 。+關(guān)閉某個(gè)標(biāo)簽頁(yè),該標(biāo)簽頁(yè)的sessionStorage 會(huì)被銷毀。不影響其他標(biāo)簽頁(yè)或者窗口 。+在某個(gè)標(biāo)簽頁(yè)即使跳出了當(dāng)前站點(diǎn),返回來(lái)的時(shí)候,sessionStorage 也還在的 。
?
鑒于它有以上特點(diǎn) :1,可以用來(lái)做多賬戶登錄 , sessionid 不用cookie存儲(chǔ),用 sessionStorage 來(lái)存儲(chǔ)。spa應(yīng)用比較適合 。
token存放位置參考
?Cookie 的作用是與服務(wù)器進(jìn)行交互,作為 HTTP 規(guī)范的一部分而存在 ,而 Web Storage 僅僅是為了在本地“存儲(chǔ)”數(shù)據(jù)而生。而token的安全和性能都是中肯的,唯一的問(wèn)題就是cookie的存儲(chǔ)性能和提取安全性太低,而localstorage更安全而且能夠跨會(huì)話實(shí)現(xiàn)身份鑒別,很明顯token應(yīng)該存在localstorage里。
?
localStorage里可以存圖片嗎,怎么存
?我們的想法是做到將已經(jīng)當(dāng)前頁(yè)面中已緩存的圖片保存到本地存儲(chǔ)中。不過(guò)就像我們之前已經(jīng)確定的,本地存儲(chǔ)只支持字符串的存取,那么我們要做的就是將圖片轉(zhuǎn)換成 Data URI 。其中一種實(shí)現(xiàn)方式就是用canvas元素來(lái)加載圖片。然后你可以以Data URI的形式從canvas中讀取出當(dāng)前展示的內(nèi)容。
?
token能放在cookie里嗎
?可以
?
xss能不能取到sessionStorage里的數(shù)據(jù)
?可以
?
hash路由和history路由
除了這個(gè)項(xiàng)目還有別的項(xiàng)目嗎
翻頁(yè)功能怎么實(shí)現(xiàn)
數(shù)據(jù)是前端來(lái)分頁(yè)還是后端來(lái)分頁(yè)
能實(shí)現(xiàn)前端分頁(yè)嗎
怎么實(shí)現(xiàn)
數(shù)據(jù)存哪
vuex有用過(guò)嗎
vuex的目的是什么
已經(jīng)有sessionStorage這類的放數(shù)據(jù)的地方,為什么還要有vuex,有什么特別的價(jià)值嗎
聊了下筆試
問(wèn)了下是不是還沒(méi)有開(kāi)始復(fù)習(xí)算法和數(shù)據(jù)結(jié)構(gòu)
說(shuō)一個(gè)最近在復(fù)習(xí)的算法再說(shuō)說(shuō)對(duì)應(yīng)的例題
?說(shuō)了道最大無(wú)重復(fù)子串,雙指針
?
復(fù)雜度
動(dòng)態(tài)規(guī)劃一般解決什么樣類型的問(wèn)題
動(dòng)態(tài)規(guī)劃相比于回溯,有什么優(yōu)勢(shì)
異步組件的懶加載是你自己想的還是教程有的
怎么實(shí)現(xiàn)懶加載
優(yōu)化效果有看過(guò)嗎
看到面評(píng),問(wèn)實(shí)習(xí)是想積累經(jīng)驗(yàn)還是想轉(zhuǎn)正
反問(wèn)
?部門:技術(shù)中臺(tái)
看重實(shí)習(xí)生哪些方面
?
碎碎念
字節(jié)的面試官是能夠看到你之前投遞的簡(jiǎn)歷,參加過(guò)的筆試和面試結(jié)果,所以如果要投的話一定要認(rèn)真對(duì)待面試和筆試吧。另外我看到牛客網(wǎng)也有前端的課程,筆試面試會(huì)涉及到的知識(shí)點(diǎn)里邊基本都會(huì)涵蓋,如果大家不知道從哪里開(kāi)始學(xué)起的話可以報(bào)名這種課程。
愛(ài)心三連擊
1.看到這里了就點(diǎn)個(gè)在看支持下吧,你的在看是我創(chuàng)作的動(dòng)力。
2.關(guān)注公眾號(hào)腦洞前端,獲取更多前端硬核文章!加個(gè)星標(biāo),不錯(cuò)過(guò)每一條成長(zhǎng)的機(jī)會(huì)。
3.如果你覺(jué)得本文的內(nèi)容對(duì)你有幫助,就幫我轉(zhuǎn)發(fā)一下吧。
