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