2021 年字節(jié)跳動前端架構(gòu)組實習(xí)生面經(jīng)分享(已拿offer)
22 屆,211 CS 本科。有兩段前端實習(xí)經(jīng)歷,第一次實習(xí)在騰訊,大二暑假去的,然后大三上學(xué)期給一家美國硅谷的創(chuàng)業(yè)公司遠(yuǎn)程打工,現(xiàn)已離職。
一面 總時長 62min
自我介紹
為什么前把項目的狀態(tài)管理方案遷移到 React Hooks
我講了 Render props 嵌套的問題,Context 導(dǎo)致組件不必要重渲染的問題,為什么沒用 redux ,redux 的負(fù)擔(dān)。最后講了 React Hooks 的好處
React 有那些組件間通信的方式?
我講了這些:父傳子 props, 父傳子 callback 后子組件通過 callback 更改父組件狀態(tài) Context redux,順便提了 react-redux 的 connect 原理 組件間共享同一個 hook 3. Context 導(dǎo)致的子組件不必要重渲染問題怎么解決?
原因是 Context 子組件內(nèi)容每次都是 React.createElement 創(chuàng)建的對象,引用是會變的,即使內(nèi)容完全沒改變。
解決方案:將子組件通過 children props 傳進(jìn)來,保證引用不變,變更的只是 props.children 這個對象的屬性。
了解 React Fiber 嗎?
我講了 Stack Reconcile 時代的問題(遞歸不可中斷更新,性能問題,沒有任務(wù)優(yōu)先級)。Fiber 基于鏈表做可中斷的更新,并且講了 React 放棄 requestIdleCallback 而選擇自己編寫 scheduler 的原因。
進(jìn)程和線程的區(qū)別?
講了各自的定義和區(qū)別之后,我還詳細(xì)說了 Chrome 為什么采用多進(jìn)程架構(gòu)(安全沙箱隔離,頁面關(guān)閉后釋放地址空間,減少內(nèi)存碎片,崩潰問題)。
進(jìn)程間通信有哪些方法?
匿名管道,有名管道,信號量,消息隊列,socket
JS 異步解決方案?
我講了 callback 以及它的問題(callback hell 以及錯誤處理麻煩),Promise 的好處(鏈?zhǔn)秸{(diào)用,錯誤統(tǒng)一.catch() 處理),然后提到 async / await ,講了協(xié)程機制,async / await 底層的 generator 實現(xiàn),隱式的 Promise。
事件循環(huán)?
常規(guī)題,講宏任務(wù)微任務(wù) UI 渲染,不多贅述。
跨域有哪些方案?
我提了 jsonp , cors,并且詳細(xì)說了簡單請求和復(fù)雜請求,預(yù)檢請求,還有 iframe domain.name ,nginx 反向代理
手寫 jsonp
這里沒寫好,我 jsonp 實際上沒有真正使用過。自己實踐都是用 cors 做的。。。
水平垂直居中怎么實現(xiàn)?
講了 flex,absolute + translate,inline-box + vertical-align: center + text-align: center, 順便扯到了 table 布局的性能問題。
JS 的數(shù)據(jù)類型
document.querySelectorAll('div') 返回的是一個什么類型?如何遍歷它?
它是一個對象,是一個類數(shù)組。通過 迭代器遍歷,數(shù)字索引遍歷,for of 語法糖,順便提了 for of 語法糖的實現(xiàn)。
14. 事件委托?常規(guī)題
event.currentTarget 與 event.target 分別是什么?
這個的輸出?
var a = 10;
(function (){
console.log(a);
a = 5;
console.log(window.a);
var a = 20;
console.log(a);
})()
答:undefined, 10, 20
算法題,特征數(shù)據(jù)轉(zhuǎn)成一個樹。
太緊張了??,只寫出來最簡單的情況。不過說了下思路。
反問環(huán)節(jié)
二面 總時長 54 min
自我介紹 什么時候開始接觸前端的? 先聊點基礎(chǔ)吧,說一下 OSI 網(wǎng)絡(luò)模型,并且每層的協(xié)議? OSI 應(yīng)該是七層的那個,我當(dāng)時說的是 TCP/IP 四層模型,說了這些 應(yīng)用層:http, dns, ftp, smtp, pop3; 傳輸層:TCP UDP ; 網(wǎng)絡(luò)層:IP, RIP, OSPF 數(shù)據(jù)鏈路層:ARP 不過面完查了下,RIP 和 OSPF 應(yīng)該是應(yīng)用層協(xié)議。 聊聊 TCP 和 UDP 的區(qū)別? TCP 面向連接,UDP 盡最大努力交付,無連接 TCP 首部 20 字節(jié),UDP 首部 4 字節(jié) TCP 是可靠傳輸,詳細(xì)講了 TCP 保證可靠傳輸?shù)臋C制 還詳細(xì)說了 TCP 慢啟動,滑動窗口,重傳機制 我們正在使用的面試視頻是采用什么協(xié)議實現(xiàn)的? 答:UDP,因為要降低延遲,UDP 快首部開銷小,并且視頻通話容忍少量數(shù)據(jù)的丟失。 https 的 s 是什么? s 是 ssl,然后詳細(xì)講了 ssl 握手的過程。并且詳細(xì)說了瀏覽器認(rèn)證數(shù)字證書合法性的過程(證書鏈向上查找合法 RootCA 記錄),還提到了 CRL (證書吊銷列表)的更新不及時可能導(dǎo)致的問題 ,由此扯到了 OSCP 在線證書檢查協(xié)議詢問 RootCA。 302 和 304 的區(qū)別? 302 暫時重定向,并且講了 302 網(wǎng)站劫持,影響搜索引擎排名的問題。304 Not Modified,協(xié)商緩存內(nèi)容沒有改變。同時聊了下緩存機制,強緩存未過期直接返回 200 并且不會向服務(wù)端發(fā)出請求。 手寫代碼,基于鏈表實現(xiàn) push 與 shift。 聊項目?為什么技術(shù)選型選擇了 Umi + Dva? 講了項目具體的歷史包袱,然后講了 Umi 的設(shè)計思想及它解決的問題,并且剛好符合那個項目的具體場景,內(nèi)容很長不贅述(。至于 Dva 部分,我首先講了 React 原生的狀態(tài)管理機制的問題,Context 導(dǎo)致子組件不必要重渲染的開銷,然后切入到 redux 將 redux 的思想(因為 Dva 是基于 redux 的一種優(yōu)化解決方案)。最后引申到 Dva 的設(shè)計思想,解決了 Redux 的哪些痛點。中間我還扯了 redux-saga 的實現(xiàn)以及 dva 是如何集成 saga 的,還扯了協(xié)程的問題。這里內(nèi)容也很長很細(xì)不贅述。建議大家針對這種關(guān)鍵性的問題好好準(zhǔn)備并且了解整個鏈路的思想與原理,便于在面試的過程中表現(xiàn)自己的競爭力。想了解 react 相關(guān)的設(shè)計思想的同學(xué)可以去知乎搜「張立理」老師的文章,他的文章給了我很多啟發(fā)與收獲。 你在這個項目中推廣了基于 GitFlow 的 CI / CD 上線流程,能詳細(xì)說說整個過程嗎? 從 develop 分支 checkout 到 feature 分支進(jìn)行開發(fā),所有 commit 到遠(yuǎn)程庫的代碼都會跑質(zhì)量流水線(lint 與 test cases),然后 feature 開發(fā)完之后 merge develop 前有 MR 檢查,MR 檢查除了跑質(zhì)量流水線外還要生成一個線上的測試地址,以便檢查。MR develop 后,等到要發(fā)板時,merge master ,同樣 merge master 之后 跑質(zhì)量流水線和發(fā)布測試地址,最后打 tag 發(fā)版,跑部署流水線構(gòu)建發(fā)布到 OSS。不清楚的同學(xué)可以去看看 Git Flow ,還有流水線的設(shè)計相關(guān)的書籍。推薦《 持續(xù)交付2.0 業(yè)務(wù)引領(lǐng)的DevOps精要》,喬梁老師講得很好。 線上的代碼放哪?答:OSS + CDN 如何保證發(fā)布后 CDN 代碼是最新的? 首先講了下 CDN 的原理,然后給每個文件打包輸出時加上 [contentHash], 文件內(nèi)容變化時文件名必定變化。順便扯了下 [hash] 和 [contentHash] 的區(qū)別。然后 index.html 不要設(shè)置緩存,因為打包后 index.html 內(nèi)引用的 scirpt url 發(fā)生了變化(因為 contentHash),因此可以知道最新的 js 文件。并且 CDN 配置了監(jiān)聽 OSS 的更新事件,觸發(fā)回源更新。 有沒有為這個項目做什么優(yōu)化? 首先從網(wǎng)絡(luò)講起,講了 http 1.1 升級到 http 2 的優(yōu)化。(使用同一個 TCP 連接,HOLB 問題優(yōu)化,Server Push,HPACK) 還提到了動畫頁面對動畫的性能優(yōu)化,rAf 還有單獨建立圖層保證 reflow 不影響其它元素,以及 GPU 加速。 有對 SPA 做什么特別的優(yōu)化嗎? 講了基于路由的 code splitting / lazy loading,還有基于某些需要打開 modal 才會使用但又很少使用的模塊做了 dynamic import 然后提到了構(gòu)建時的 Tree shaking,首先講了 Tree Shaking 的原理:harmony import / export 標(biāo)記,然后交給 terser 進(jìn)行提出,還提了下 sideEffect。然后講 webpack tree shaking 的配置。還有將了下如何編寫易于 Tree shaking 的代碼(要將每個工具函數(shù)單獨 export ,不要集成為一個 class ,tree shaking 的最小單元是一個對象,它不能識別一個對象中哪些函數(shù)是否需要 你項目使用 TS 寫的,那你知道 TS 如何編譯到 ES 5 代碼的嗎? 思考了十秒鐘,一開始是懵的。突然想通,這不就是問 babel 原理么。然后就將 TS 的詞法分析,聊了下 DFA 。然后就是基于文法做語法分析,構(gòu)建語法樹。后面把 AST 交給 Babel。Babel 遍歷 AST,在遍歷的過程中根據(jù)每一個 AST Node 的類型,交給 Babel 對應(yīng)的 Plugin,在這個切入點引申到 Babel 的插件機制。講了下插件的 visitor 的作用。最后轉(zhuǎn)換程 ES 5 的 AST,同時在這個過程中能得到 SourceMap。然后將 ES 5 的AST 還原成代碼,即得 ES 5 代碼。 如果 TS 代碼編譯的過程中,遇到了一些高級的特性,ES 5 并不支持怎么辦? 答:引入對應(yīng)特性的 polyfill 反問環(huán)節(jié) 問了下組里的業(yè)務(wù),還有面試官的前端經(jīng)歷。
三面
自我介紹 為什么從上一段實習(xí)離職? 大二去實習(xí)怎么平衡學(xué)業(yè)和工作的關(guān)系? 項目中提到的數(shù)據(jù)圖表渲染優(yōu)化是怎么做的? 根據(jù)數(shù)據(jù)特征實現(xiàn) sampling 算法取樣,只需要取關(guān)鍵點,重復(fù)的無變化的數(shù)據(jù)剔除,減少渲染數(shù)據(jù)量。 簡歷中有提到你在學(xué)校團(tuán)隊中推廣落地了 Code Review ,你具體是怎么做的?
先找團(tuán)隊中技術(shù)好有影響里的幾位同學(xué),單獨做一個小項目,先在這個小項目內(nèi)應(yīng)用 Code Review。先讓這些同學(xué)熟悉 Code Review 的流程,以及 Code Review 能給他們帶來什么,讓他們認(rèn)識到 Code Review 的價值,能夠帶來好處之后,再在大項目中,聯(lián)合這些同學(xué)一起推廣 Code Review如何評價 Code Review 質(zhì)量 ? 抽檢 CR ,看評論內(nèi)容是否有意義???Request For Changes 之后的代碼修改是否有經(jīng)過設(shè)計思考。CR 是一個相互學(xué)習(xí)的過程,如果看到雙方對某個設(shè)計問題有所爭論,那也便是好事。 你認(rèn)為什么樣的代碼是好代碼講了一些 OOP 封裝復(fù)用的思想,SOLID 設(shè)計原則。也提了實際業(yè)務(wù)場景與代碼提前設(shè)計的矛盾。 聊簡歷中的命令行工具設(shè)計?// 經(jīng)歷強相關(guān),不便分享~ 怎么評價這個工具推廣的效果? 使用命令行工具將需求單狀態(tài)實現(xiàn)自動化更新的話?會不會帶來一些不好的影響? 手寫代碼,寫 timeFormat 函數(shù)。包含占位符解析 如:timeFormat(new Date().getTime(), ‘YYYY-MM-DD hh:mm’); // 2021-02-26 14:02
思路:一遍掃描。用詞法分析的思想,YYYY MM DD 這些就是關(guān)鍵詞。識別到關(guān)鍵詞替換成對應(yīng)的值。
寫上面這題過程中,遇到了 string 類型的不可變性問題。順便談下可變與不可變
手寫代碼。實現(xiàn)一個隨輸隨搜的搜索框 首先講需要注意哪些點:1. 觸發(fā)搜索防抖 2.響應(yīng)內(nèi)容保證按需返回 3. 服務(wù)端限定處理的關(guān)鍵詞長度 ,只去前面 n 個。因為太長的關(guān)鍵字會使得 Elastic Search 效率低下除了這些方面呢?用戶體驗方面上你會怎么設(shè)計?常搜索的關(guān)鍵詞做緩存,以后輸入如果匹配上了歷史搜索,歷史搜索關(guān)鍵詞的排序會更靠前。
搜索框的 outline 交互。還有搜索框的 a11y 優(yōu)化,以方便特殊人士使用
默認(rèn) focus,減少用戶一次點擊
對違法詞匯搜索的結(jié)果信息過濾
根據(jù)用戶特征與地理位置返回特定的結(jié)果(因為我經(jīng)常使用 Google,Google 就是這么做的
14. 還有嗎?從前端輸入到服務(wù)端性能整個鏈路角度來看,有什么可以優(yōu)化的點嗎?如何降低用戶操作的折損?
這個問題問出來的時候,腦子里就認(rèn)為這是一個商業(yè)化實驗數(shù)據(jù)相關(guān)的問題。
跨域怎么收集用戶數(shù)據(jù)? 跨域不能共享 Cookie 但是可以知道用戶的唯一標(biāo)識符,通過用戶唯一標(biāo)識與同時接入的第三方平臺實現(xiàn)數(shù)據(jù)共享。 怎么最終用戶?有哪些常用的標(biāo)識?IMEI,MEID,ICCID,手機號 手寫代碼:節(jié)流,防抖 前面問了太多意料之外的東西,導(dǎo)致我很緊張。防抖節(jié)流怎么寫都想不起來了?? 入職時間,實習(xí)多久? 反問環(huán)節(jié)
面試過程體驗很好,面試官善于引導(dǎo),并且問題都很有深度?,F(xiàn)在 offer 已到。
