阿里巴巴暑假實習面試總結

原文地址:http://www.ahonn.me/2017/03/1...javascript

2月末的時候,經過 simplyY 內推了阿里巴巴暑期實習的前端開發崗,在此表示感謝。
接着3月1號收到了內推的通知郵件,完善信息後很快就接到了一面的電話(3月3號)。css

一面

面試了大概20分鐘左右,總體內容仍是比較偏基礎。一開始是正常流程的自我介紹,說是三分鐘自我介紹,可是我語速比較快的不到兩分鐘的介紹完了。(恰好是臨近中午,本來打算吃飯的,要是去吃飯的話就得在路上面了...)前端

CSS 垂直居中

這個寫過一篇博文專門總結過,不過面試的時候仍是太過緊張沒有答全。主要是 Flexbox 佈局的垂直居中比較容易忘記。java

具體就再也不囉嗦了,詳情能夠查看:CSS 實現垂直居中react

call 與 apply 的區別,以及性能差異

callapply 的區別,這是一個老生常談的面試題了。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.applyFunction.prototype.call 的具體實現差別。ajax

參考連接算法

什麼是閉包

又是一個老生常談的問題。個人理解比較膚淺,就是 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);
  }
}

關於遞歸與尾遞歸,在 『計算機程序的構造和解釋』中也有相似的討論。

React 的設計理念

這部分答得不是很好,只提到了組件化,單向數據流,Virtual DOM 之類的。

有關 React 的設計思想能夠參考這一篇文章:React 設計思想

前端安全(攻擊方式與如何防範)

第一反應就是 XSSCSRFXSS 能夠經過對輸入數據進行轉義來防範,而 CSRF 則經過使用 SSL 連接訪問資源或者請求中添加驗證碼來進行防範。

除此以外我漏掉了網絡劫持,控制檯注入代碼等攻擊方式,這裏有篇文章作了詳細介紹:聊一聊WEB前端安全那些事兒

二面

第一次遠程視頻面試,好緊張。

一開始問了 CSS 中 position 屬性的 absolute 的做用以及應用場景,這個基本上沒有什麼問題。接着叫我拿紙寫冒泡排序(手寫 T-T),飛快的寫完。
而後跟一面同樣也問了前端安全相關的問題,一會兒都不緊張了.. 沒有想象中的難。

實現 bind 函數

一樣是讓我寫代碼,一樣是手寫(T-T)。這個問題對我來講不算難,不過只是寫了簡單的實現,沒有考慮其餘狀況。

Function.prototype.bind = Function.prototype.bind || function (context) {
  var self = this;
  return function () {
    return self.apply(context, arguments);
  }
}

基本原理就是使用 apply() 與閉包,返回包含 apply() 的閉包使得 apply() 綁定指定做用域,但並未執行。

閱讀 Underscore 源碼的經歷

以前拖拖拉拉的閱讀完了 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 不能表明什麼,並且的確寫得也很水,但做用不能否認)。

最後,基礎很重要,基礎紮實是基本。可是若是想要有突出的表現仍是須要更有深度的研究。須要常常思考總結,不只僅是浮於表面,更要深刻原理。

相關文章
相關標籤/搜索