原文地址:http://www.ahonn.me/2017/03/1...javascript
2月末的時候,經過 simplyY 內推了阿里巴巴暑期實習的前端開發崗,在此表示感謝。
接着3月1號收到了內推的通知郵件,完善信息後很快就接到了一面的電話(3月3號)。css
面試了大概20分鐘左右,總體內容仍是比較偏基礎。一開始是正常流程的自我介紹,說是三分鐘自我介紹,可是我語速比較快的不到兩分鐘的介紹完了。(恰好是臨近中午,本來打算吃飯的,要是去吃飯的話就得在路上面了...)前端
這個寫過一篇博文專門總結過,不過面試的時候仍是太過緊張沒有答全。主要是 Flexbox 佈局的垂直居中比較容易忘記。java
具體就再也不囉嗦了,詳情能夠查看:CSS 實現垂直居中react
call
與 apply
的區別,這是一個老生常談的面試題了。call()
與 apply()
都是用於在指定 this 值與參數的狀況下調用函數,主要的區別在於除了傳入 this 值以外,apply()
接收類數組或者類數組對象來做爲調用的函數的參數,而 call()
則是須要分別傳入函數的每個參數(除第一個參數以外的其餘參數)。git
call()方法與apply()方法的做用相同,它們的區別僅在於接收參數的方式不一樣。對於call()方法而言,第一個參數是this值沒有變化,變化的是其他參數都直接傳遞給函數。換句話說,在使用call()方法時,傳遞給函數的參數必須逐個列舉出來。—— 『JavaScript 高級程序設計』github
區別的話基本上只要看過書或者刷過面試題都會知道,但 call()
與 apply()
之間的性能差異就不是那麼常見了。
比較幸運的是,以前在閱讀 underscore 源碼的時候有注意到這個細節,爲此也寫過另外的文章:從 optimizeCb 提及。面試
實踐證實,在知道調用函數的參數數量時,使用 call()
的性能會優於 apply()
。主要在實現的過程當中 apply()
須要完成額外的操做(判斷第二個參數類數組的長度,etc.)。具體爲何有這種差異,能夠在 ECMAScript Language Specification 中查看 Function.prototype.apply 與 Function.prototype.call 的具體實現差別。ajax
參考連接算法
javascript - What is the difference between call and apply? - Stack Overflow
javascript - Why is call so much faster than apply? - Stack Overflow
又是一個老生常談的問題。個人理解比較膚淺,就是 A 函數返回 B 函數,B 函數可以訪問 A 函數中的局部變量,使得在 A 外部的做用域中可以使用 B 函數間接操做 A 函數中的局部變量,這樣就造成了一個閉包。A 函數中的局部變量與返回的 B 函數一同存在,不會被垃圾回收機制清理(引用還存在)。
在計算機科學中,閉包(英語:Closure),又稱詞法閉包(Lexical Closure)或函數閉包(function closures),是引用了自由變量的函數。這個被引用的自由變量將和這個函數一同存在,即便已經離開了創造它的環境也不例外。—— 維基百科
建議閱讀 『你不知道的 JavaScript(上卷)』 中有關做用域與閉包的部分。
在計算機科學裏,尾調用是指一個函數裏的最後一個動做是一個函數調用的情形:即這個調用的返回值直接被當前函數返回的情形。這種情形下稱該調用位置爲尾位置。若這個函數在尾位置調用自己(或是一個尾調用自己的其餘函數等等),則稱這種狀況爲尾遞歸,是遞歸的一種特殊情形。—— 維基百科
通常遞歸實現階乘:
function fact(n) { if (n == 0 || n == 1) { return 1; } else { return n * fact(n - 1); } }
通常遞歸須要中棧上維護函數的調用信息直到函數返回後才釋放,容易發生『棧溢出』錯誤。但對於尾遞歸來講,只須要維護一個調用記錄。
尾遞歸實現階乘:
function fact(n) { return fact-iter(n, 1); } function fact-iter(n, a) { if (n == 0) { return 1; } else if (n == 1) { return a; } else { return fact-iter(n - 1, n * a); } }
關於遞歸與尾遞歸,在 『計算機程序的構造和解釋』中也有相似的討論。
這部分答得不是很好,只提到了組件化,單向數據流,Virtual DOM 之類的。
有關 React 的設計思想能夠參考這一篇文章:React 設計思想。
第一反應就是 XSS
與 CSRF
,XSS
能夠經過對輸入數據進行轉義來防範,而 CSRF
則經過使用 SSL 連接訪問資源或者請求中添加驗證碼來進行防範。
除此以外我漏掉了網絡劫持,控制檯注入代碼等攻擊方式,這裏有篇文章作了詳細介紹:聊一聊WEB前端安全那些事兒。
第一次遠程視頻面試,好緊張。
一開始問了 CSS 中 position 屬性的 absolute 的做用以及應用場景,這個基本上沒有什麼問題。接着叫我拿紙寫冒泡排序(手寫 T-T),飛快的寫完。
而後跟一面同樣也問了前端安全相關的問題,一會兒都不緊張了.. 沒有想象中的難。
一樣是讓我寫代碼,一樣是手寫(T-T)。這個問題對我來講不算難,不過只是寫了簡單的實現,沒有考慮其餘狀況。
Function.prototype.bind = Function.prototype.bind || function (context) { var self = this; return function () { return self.apply(context, arguments); } }
基本原理就是使用 apply()
與閉包,返回包含 apply()
的閉包使得 apply()
綁定指定做用域,但並未執行。
以前拖拖拉拉的閱讀完了 Underscore 的源碼,並提交了一個小 Pull Request。
在閱讀的過程當中學到了許多的東西,例如上面提到的 call 與 apply 的性能差異,除此以外還有如何去判斷變量的類型,以及如何判斷兩個變量是否相等,等等。另外也瞭解到許多閉包的使用場景。
除了 Underscore 以外還閱讀過一點 Bootstrap 和 jQuery,這個博客主題的樣式部分的組織方式就是參考了 Bootstrap 的組織方式,另外也稍微閱讀過 jQuery中 $.ajax
以及事件相關的源碼。
在閱讀代碼的過程當中的收穫就是學習了一些組織代碼的方式,還有如何寫纔能有利於拓展,更加健壯。其中也學到了一些提升性能的技巧,函數緩存,事件隊列之類的。
其實一開始寫主題只是想給本身用,以後發現蠻多人也喜歡我這個主題的,並時不時有人中 Github 上提 Issue,這對我是莫大的鼓勵。雖然我水平並非很高,可是寫出來的東西有人用感受真的是特別開心,也特別有動力去改進。
從開始去寫主題到如今差很少也一年了,這一年中我從前端小白變成前端大白。在維護的過程當中學習到不少東西,雖然目前寫得也不是很好,可是我仍是會慢慢改進繼續維護下去的。
維護的過程當中的收穫就是,當站在本身的角度看問題與在別人的角度看徹底是不同的,或許有個功能我並不須要,可是有人提了,我就得站在『用戶』的角度去思考,去實現。『用戶』只關心能不能用,好很差用,而並不關心代碼寫得怎麼樣。
可能我作的工做相對簡單,就算不會,基本上靠搜索引擎都可以解決。我以爲能用 Google 解決的問題不算難題。以我如今的水平,還達不到遇到的難題 Google 搜索不到的?
三面基本上沒有問太過具體的前端相關的問題,大部分是在聊聊見解,聊聊項目。
開始讓我用紙畫出博客的設計,其實主要仍是主題,沒什麼難度,畢竟代碼都是我本身寫的。
而後讓我介紹一下我熟悉的一個框架,說的 React,說起到了 Vitrual DOM 和 diff 算法,說了一下 diff 算法的大概策略。還有說到組件化,單向數據流等等。幸運的是,我在二面以前刷了 『深刻 React 技術棧』這本書,結合以前的實踐可以說個大概。
中間有聊到興趣愛好,我想了想好像只有寫代碼。聽歌應該也算?寫代碼的時候一定要聽歌。我記得去年國慶有一天從起牀寫到晚上睡覺,差很少寫了 11 個小時,那時候正在折騰 React 與 Meteor。我本身都以爲難以想象。
多是運氣問題,我以爲個人這幾面難度都不高?。得益於看的書,好多知識點都是書上有的。基本上基礎的前端面試題均可以在紅寶書上找到,真不愧爲前端面試寶典。另外 Github 上的這個博客主題也幫了很大的忙,300+ star 果真仍是有點用處的(雖說 star 不能表明什麼,並且的確寫得也很水,但做用不能否認)。
最後,基礎很重要,基礎紮實是基本。可是若是想要有突出的表現仍是須要更有深度的研究。須要常常思考總結,不只僅是浮於表面,更要深刻原理。