關注若川視野
,回復"pdf" 領取資料,回復"加群",可加群長期交流學習
滴滴前端實習面經
滴滴是我投簡歷之后第二家面試的公司, 國慶節前兩三天投的簡歷, 國慶后復工第一天就給我打了電話約一面。
那時候因為還沒什么面試經驗,所以一面有些緊張,很多題雖然是八股題, 但因為都是第一次答,所以有些磕巴和不全面(后來就成老油條了)。
總結一下:
一面問的都是常規基礎題, 主要考察對知識掌握的廣度,初級前端需要的技能棧基本都有所涉及(不超出簡歷所寫的技能范圍)。
二面的時候, 因為面試官對我的簡歷比較感興趣,所以將近一半時間都在問項目, 還有我自己和前端無關的一些動手折騰的經歷。
大概考慮到自己還是存在比較明顯的項目經驗短板,所以加了三面,把我推給了搞開源框架的小程序負責人,這一面比較難, 會扣細節談認識,然后開屏幕共享,手撕中等難度的JavaScript題,編程題和算法題。
注意, 面試題只給出整體思路,以及某些需要特別注意的地方,部分會附上一些個人推薦的文章鏈接,但答題細節不做全部展開。
一面
滴滴的面試非常準時,視頻會議的入口在開始前十幾分鐘前才以短信的形式發過來。兩點鐘的面試,對面一點五十九分打開攝像頭。面試官是一個小姐姐,很漂亮人也很溫柔, 聽鼻音是感冒了,但依然會很耐心地和你說不要緊張,問題沒答好還會幫著給提示,總之面試體驗非常nice啦~讓我這個面試經驗幾乎為零的小菜雞不至于太緊張。
1. css部分
1.1 盒模型
開頭面的好幾家都連續問到了這個問題,所以這道基礎之基礎題可以多看,爭取回答的滴水不漏。
關鍵點: 不要漏掉IE的怪異盒模型
1.2 怎么實現一個水平居中
先說,自己實際中常用的就兩種
flex三板斧
絕對定位
然后補充說一些其它的
有些比較trick,了解就好: absolute + margin負值/cacl/50%/translate、writing-mode + text-align、基于視口、grid三板斧
Tips: 《CSS揭秘》有談到克服解決居中問題的歷史,循序漸進,比滿天飛的羅列居中方法的文章有意思的多,如果覺得死記硬背記不全,可以從歷史演變的角度來理解記憶。
垂直居中-《CSS揭秘》-微信讀書
早期方法,表格布局法/行內塊法/絕度定位 → translate → 視口單位 → Flexbox → Grid
再就是些奇技淫巧: 快狗打車-:before搭配vertical-align:middle
2. JS部分
2.1 JavaScript有哪些數據類型
基本數據類型:
undefined
、null
、boolean
、number
、string
、symbol
引用數據類型:
object
、array
、function
Tips: 千萬不要漏掉null,undefined,Symbol
2.2 JavaScript是單線程還是多線程
本質考察的是消息隊列和事件循環
首先,JavaScript是單線程,這是它的核心特征,現在和未來都不會改變,即使加入Web Worker,但子線程完全受主線程控制,不會改變JavaScript單線程的本質
為了統籌調度唯一主線程上的各種任務,引入消息隊列和時間循環機制
有需要的話可以展開詳述,不過這就是另一個大坑了......
JS部分除了這兩道,應該還問了幾道JavaScript相關題,暫時想不起來了
3. 瀏覽器部分
3.1 項目中有遇到過跨域的問題嗎,你是怎么解決的
我當時回答的有些支離破碎, 這里直接給出一位朋友的公眾號文章吧(歡迎點關注哈~)
前端時光屋-跨域解決方案
3.2 現在使用的瀏覽器是單進程還是多進程
講了一遍Chrome架構的發展史:
單進程瀏覽器時代(存在的幾個問題) → 多進程瀏覽器時代(新加入了哪些進程) → 面向服務架構的時代(工作內容以及有什么意義)
3.3 描述一下瀏覽器渲染過程
這里只給出骨架
HTML解析 → 字節流Bytes轉為Tokens → 生成node節點 → 構造DOM樹 → 同時請求CSS和JavaScript文件 → 響應CSS數據, 構建CSSOM → 響應并執行JavaScript → 繼續構建DOM → 構建布局樹 → 分層 → 分塊→ 合成(包括光柵化)
4. 計網部分
4.1 常見狀態碼有哪些
先從整體講起
狀態碼 | 含義 |
1×× | 指示信息–表示請求已接收,繼續處理 |
2×× | 成功–表示請求已被成功接收、理解、接受 |
3×× | 重定向–要完成請求必須進行更進一步的操作 |
4×× | 客戶端錯誤–請求有語法錯誤或請求無法實現 |
5×× | 服務器端錯誤–服務器未能實現合法的請求 |
平時遇到比較常見的狀態碼有:200,301,302,304,400,401,403,404,422, 500
然后逐個講,說到304的時候,提到了檢查緩存
這個時候,小姐姐開始靈魂追問(屬于自己把自己帶進坑了)
4.2 追問: 是在命中強緩存還是協商緩存的時候才返回304呢?
協商緩存生效,返回304和Not Modified
4.3 追問: 那聊聊瀏覽器緩存
推薦文章
瀏覽器緩存
4.4 三握手的過程
直接放一篇寫的非常好的文章
通俗大白話來理解TCP協議的三次握手和四次分手
4.5 OSI七層模型
我一直背的是五層模型,其實很多地方都用的OSI標準,學校課本也是,但我不記得了......
安利一波阮一峰老師的TCP/IP協議入門(很基礎,但講的非常清晰)
互聯網協議入門(一)阮一峰
互聯網協議入門(二)阮一峰
回答的時候,不知怎么的,扯到了HTTPS(又一次把自己帶偏)
4.5 追問: HTTPS位于哪一層呢
HTTPS所處的安全層插入在TCP和HTTP之間,連接了傳輸層和網絡層
但并不會影響到上層的 HTTP 協議,也不會影響到下層的 TCP/IP
5. Git部分
5.1 用過哪些Git命令
balabala說了一大通~
對于Git還是挺有信心的,因為參與過幾個項目的PR,包括github某大名鼎鼎的女裝項目(大誤
Git闖關游戲也基本通關了,自以為問題不大
現在想想,估計就是給接下來的問題挖了坑吧
5.2 怎么切換到新分支
git checkout咯
創建 + 切換分支就是git checkout -b 'new branch'
5.3 手上的代碼還不足夠commit,需要暫存當前工作并返回上一個commit,應該用哪個Git命令
前面講了很多我用過的命令,小姐姐估計特意挑了一個我沒說的
這個情景沒答上來,因為確實不記得有對應的處理命令了。瞎說了一個git add到緩沖區,然后checkout到另一個分支。
小姐姐提示說這樣不行哦,會污染當前的工作區狀態,然后給出了正確操作:git stash, 還建議我回去可以了解一下
git方面,推薦一篇從實踐里總結出來的好文(非全面歸納),可惜自己當初沒有細看
前端瓶子君-珍藏多年的 Git 問題和操作清單
6. 框架
框架題基本被我水掉了
因為我這段時間用的都是React
Vue還是一年多前對著文檔寫過東西,中間一直沒撿回來,所以和滴滴目前Vue為主的技術棧不太吻合,和小姐姐也不太聊的上來,中間甚至還有一小段尷尬的沉默......
最后還是象征性地問了一個八股題
6.1 React和Vue的區別
可以圍繞的角度: 數據綁定、數據渲染、生命周期、使用場景、開發風格、操作粒度等等.....還可以提一嘴Vue3做出的改變
7. 分析輸出
這兩道題因為是現場給出的,都找不到原題了,this指向題是我根據記憶大概重寫的,異步分析題是在網上找的類似的
7.1 this指向分析
var myObject = {foo: "bar",func: function() {var self = this;console.log(this.foo); console.log(self.foo); (function() {console.log(this.foo); console.log(self.foo); }());}
};
myObject.func();
輸出
bar
bar
undefined
bar
7.2 異步分析
在網上找了一道題,比小姐姐出的面試題要難一丟丟,這道題比起原面試題,多了async/wait,少了一個setTimeout(面試題里有兩個定時器),能正確分析出這道題,對于異步最基礎的認知應該就沒問題了
async function foo() {console.log('foo')
}
async function bar() {console.log('bar start')await foo()console.log('bar end')
}
console.log('script start')
setTimeout(function () {console.log('setTimeout')
}, 0)
bar();
new Promise(function (resolve) {console.log('promise executor')resolve();
}).then(function () {console.log('promise then')
})
console.log('script end')
輸出結果放在這里,分析完了可以核對:
script start
bar start
promise executor
script end
foo
bar end
promise then
setTimeout
8. 算法部分
這道算法是劍指offer原題,小姐姐出題的時候也直說了是劍指offer上的
在一個 n * m 的二維數組中,每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序。請完成一個函數,輸入這樣的一個二維數組和一個整數,判斷數組中是否含有該整數。
這道題用二分查找法或者坐標系法(原書解法)都可以搞定
直接放LeetCode鏈接二維數組中的查找
二面
二面的是個能明顯感覺到技術很強的小哥哥
后來加了微信才知道,小哥哥已經在滴滴工作四五年了
1. 聊項目
這一塊都是對著簡歷里寫的東西問的,不只有項目,還有自己以前做的各種奇奇怪怪的折騰和開發經歷
不展開來說,只把問題記錄一下吧~
1.1 你用lua腳本的寫的一個小應用,介紹一下
1.2 追問: 怎么實現這里面的廣告攔截
1.3 展示一下字體設計
1.4 組件庫項目的設計思路
2. async有用過嗎, 它是怎么實現異步的
介紹了Promise和Generator
Generator底層實現機制--協程
協程執行流程
協程如何與Promise配合
封裝執行生成器代碼(參考co)
回到async/wait的語法糖
3. ES6怎么兼容低版本的瀏覽器
正確思路應該是,從Babel和AST結合去展開講,比如
Babel將 ES6 源碼轉換為 AST,然后再將 ES6 語法的 AST 轉換為 ES5 語法的 AST,最后利用 ES5 的 AST 生成 JavaScript 源代碼
對了,當然也不要忘記去講Polyfill
推薦參考:Babel文檔-@Babel/polyfill(已經拆分為core-js和regenerator-runtime)
但我那時候一下子只想到了Babel
所以選擇了兩個我自己熟悉的角度切入(后來發現其實跑題了......)
我經常會用Babel去幫助深入理解一些ES6的特性
舉了兩個例子:
for循環中的let的隱蔽作用域, 編譯成ES5是什么樣子
ES6怎樣去編譯class
后端開發了解過嗎
答: 大二學了java,但掌握的很淺
然后正在學習node……
有用過TS嗎
答: typescript也正在待學習清單上……
小哥哥繼續問: 盡可能說一下對TS了解
答: (胡言亂語)TS增加了泛型, 更向java靠攏……
實在扯不下去了,小哥哥看我不怎么了解也沒問下去了
連續水了node和typescript的問題,出現兩塊這么大的空白,感覺已經有點崩了
4. 你簡歷上寫了對V8有過了解,那么說說JavaScript和C有什么區別
一開始沒有get到重點,只說了JavaScript是動態的(不需要檢查數據類型),弱類型(支持隱式類型轉換)的語言,而C是靜態(需要檢查數據類型)的,弱類型(支持隱式類型轉換)的語言。
然后小哥哥提醒,可以說說兩者在編譯上的區別嗎
追問: JavaScript和C在編譯上的區別
本質就是考察JavaScript編譯原理,這里直接放一個對比圖吧
5. 追問: 你說C編譯生成了一個exe文件,那這個exe文件里具體存儲的是什么呢
這個不是很了解......(不敢深入說)
6. 說一說你對JIT的認識
細節不再贅述,這里面可以講的太多, 直接上總圖
三面
第三面是加面(滴滴的前端實習本來只有兩面),二面的小哥哥把我推給了滴滴小程序部門的leader,這位大佬主導開發了滴滴一個開源框架mpx,但其實給人感覺特別平易近人
1. react有一些新特性,比如fiber,談談你對react fiber的認識
常規問題,愿意的話,可以講的非常深入
2. 說說你對打包器的了解
講了講以前手動封裝一個JavaScript打包器的經歷
2.1 追問: 怎么引入依賴
這個沒答好
@babel/parser 解析入口文件(已經過時, 需要拆分),獲取 AST
使用
@babel/parser
解析并讀取器解析入口文件使用
@babel/parser
(JavaScript解析器)解析代碼,生成 AST(抽象語法樹)解析 AST,解析入口文件內容,獲取所有依賴模塊
dependencies
推薦閱讀
如何用 Babel 為代碼自動引入依賴
3. 你在簡歷里寫到,用styled-components實踐了CSS in JS,談一談你的認識
先講一下ES6的標簽模板
然后講styled-components相對CSS mosules的優勢
比如可以直接寫JavaScript邏輯代碼, 而且不必再采用內聯樣式
解決了一些CSS modules中很機械的寫法,比如類名不能使用連接符,className寫法固定的問題
4. 性能優化
這個可以說的太多太多了
先從自己的經驗切入,扯了一些實際用到過的,比如從DOMFragment轉移到虛擬DOM啦, 把耗時操作分解到微任務和延時隊列啦,will-change和requestAnimationFrame啦,webpack首屏優化啦,script的defer和async啦,懶加載啦,balabala挺多的
實踐經驗講完了,然后系統歸納優化方案
加載階段
減少關鍵資源(HTML、JavaScript、CSS)個數
減少關鍵資源大小
降低關鍵資源的 RTT 次數
交互階段
減少 JavaScript 腳本執行時間
避免強制同步布局
避免布局抖動
盡可能利用 CSS 合成動畫
避免頻繁的垃圾回收
關閉階段
如何安全退出
再送一張圖
5. 手寫: 組合繼承
冴羽大佬的博客里對這個梳理的很好,但那篇文章更多像是紅寶書的讀書筆記,所以建議直接反復閱讀紅寶書上繼承的部分(寫的非常精彩)
參考范例引用自冴羽的博客
JavaScript深入之繼承的多種方式和優缺點
function Parent (name) {this.name = name;this.colors = ['red', 'blue', 'green'];
}
Parent.prototype.getName = function () {console.log(this.name)
}
function Child (name, age) {Parent.call(this, name);this.age = age;
}
Child.prototype = new Parent();
Child.prototype.constructor = Child;
var child1 = new Child('kevin', '18');
child1.colors.push('black');
console.log(child1.name); // kevin
console.log(child1.age); // 18
console.log(child1.colors); // ["red", "blue", "green", "black"]
var child2 = new Child('daisy', '20');
console.log(child2.name); // daisy
console.log(child2.age); // 20
5.1. 追問: 分析你寫的組合繼承中的原型鏈
這個很簡單,說明白就好了
7. 手寫: async
這個網上的資料很多,我就不把自己寫的貼出來了: )
8. 算法: 三數之和
給你一個包含 n 個整數的數組 nums,判斷 nums 中是否存在三個元素 a,b,c ,使得 a + b + c = 0 ?請你找出所有滿足條件且不重復的三元組。
這道題在LeetCode原題上稍有改動,條件里的 a + b + c = 0 改成了 ?a + b + c = target,不過都是差不多的啦~
思路: 雙指針夾逼 + 二分法加速
照例,放上LeetCode鏈接三數之和
至此,三輪實習生面試所有能回憶起來的內容結束
推薦閱讀
知乎問答:一年內的前端看不懂前端框架源碼怎么辦?
我在阿里招前端,我該怎么幫你?(文末有福利)
如何拿下阿里巴巴 P6 的前端 Offer
如何準備阿里P6/P7前端面試--項目經歷準備篇
大廠面試官常問的亮點,該如何做出?
如何從初級到專家(P4-P7)打破成長瓶頸和有效突破
若川知乎問答:2年前端經驗,做的項目沒什么技術含量,怎么辦?
末尾
你好,我是若川,江湖人稱菜如若川,歷時一年只寫了一個學習源碼整體架構系列~(點擊藍字了解我)
關注
若川視野
,回復"pdf" 領取優質前端書籍pdf,回復"加群",可加群長期交流學習我的博客地址:https://lxchuan12.gitee.io?歡迎收藏
覺得文章不錯,可以點個
在看
呀^_^另外歡迎留言
交流~
小提醒:若川視野公眾號面試、源碼等文章合集在菜單欄中間
【源碼精選】
按鈕,歡迎點擊閱讀,也可以星標我的公眾號,便于查找