一年半前端工做經驗試水杭州:我是如何拿下網易、阿里和滴滴 offer 的

前言

筆者畢業於東北大學,大學畢業社招進入環球網,前端開發工程師一職。技術棧:React+node,Github 地址javascript

成果

來到杭州的目標很是的明確,大廠。其實就是網易、阿里和滴滴。好在基本三家都拿到了offer。最終決定選擇阿里p6。css

面試題

大廠流程比較長,好比阿里就面試了將近三週。因此期間也面試了不少別的公司,創業公司or上市公司。這裏我把我所被問到的面試題總結梳理一下。簡單深刻的都有。筆者我的工做經驗不豐富,如若回答很差的地方歡迎指正。html

HTML && CSS 部分

  • CSS經常使用佈局
    CSS經常使用佈局爲盒模型div+css、其中須要注意IE的怪異盒模型,咱們一般經過box-sizing解決。傳統盒模型佈局方式中咱們能夠細分爲文檔流佈局、浮動佈局、定位佈局。在ie10+中咱們可使用flex佈局,其中咱們須要理解最爲核心的容器和軸的概念。二維佈局中,咱們可使用Grid佈局。對於三欄佈局,除了浮動實現方式,還有雙飛翼佈局和聖盃佈局。其實雙飛翼佈局就是對聖盃佈局的bug修復,一種改造升級。
  • 瞭解BFC麼?
    BFC即爲塊級格式化上下文。在普通流的Box屬於一種formatting box,類型能夠爲block或者爲inline。可是不能同時爲這二者。而且Block boxes在block formatting context裏格式化,inline boxes在inline formatting context中格式化,任何被渲染的元素都屬於一個box,不是block就是inline。其通常表現規則分爲如下幾種狀況:一、在建立了BFC的元素中,其子元素按照文檔流一個接着一個放置。垂直方向上他們的起點是一個包含塊的頂部,二者相鄰元素的垂直距離取決margin特性。二、在BFC中,每個元素的左外邊與包含塊的左邊相接觸。及時存在浮動也是如此。除非這個元素也建立了一個新的BFC。三、BFC就是頁面的一個獨立的行政區域。全部瀏覽器都會將BFC放到浮動元素所在行的剩餘空間內。當HTML知足一下任意一個條件便可產生BFC:float不爲none、overflow不爲hidden、display爲table-cell,table-caption,inline-block中的任何一個。Position值不爲relative或static。一般咱們使用BFC爲了避免和浮動元素重疊。清除內部浮動元素。解決上下元素相鄰時候重疊。
  • 居中方面問題
    分別從水平居中垂直居中兩方面回答。水平、垂直居中分爲單個元素、多個元素、已知寬高和未知寬高回答
  • session、cookie、sessionStorage、localStorage區別
    從client和Server中區分回答session是什麼以及通常session如何使用注意事項以及安全策略,cookie、sessionStorage和localStorage等分別從概念和異同處回答。最後補充項目中的使用狀況
  • px/em/rem的區別
    px顧名思義就是咱們一般說的像素大小。em和rem都是相對大小,不過em是繼承父級元素的字體大小,rem是相對於根元素的大小,這個單位可謂是集相對大小和絕對大小爲一身。經過它能夠作到只修改根元素便可修改全部字體的大小,又能夠避免字體大小逐層複合的連鎖反應。當rem相對於瀏覽器進行縮放,1rem默認爲16px。
  • animation和transition使用過麼
    寫法:animation:name duration timing-function delay iteration-function direction .transition爲過渡動畫,這種效果能夠在事件中觸發,而且圓滑的以動畫效果改變css的屬性值。不一樣於transform,transform爲2D轉換(問題很是開放,儘量多回答你所知道的)
  • css編寫注意事項
    這個考驗我的平時編碼的總結和約束。問題較爲開放,能夠結合我的開發體驗和團隊約束來回答。好比0後面不帶單位、儘可能使用簡寫、使用子選擇器、合理使用id等。前端

    JavaScript部分

  • JavaScript閉包瞭解麼
    閉包即爲函數,可是咱們一般所說的閉包是指有權訪問並操道別的函數做用域中變量的函數。通常表現形式爲函數中返回函數。一般咱們開發中就會有不少的閉包好比定時器、事件監聽、IIFE等。此題是一個借題發揮漲分的題目,咱們能夠談談閉包的高級用法,好比單例模式中的使用、js的節流和防抖甚至能夠談一談js的運行機制,gc機制。
  • 前端跨域都有哪些解決方案
    js的前端跨域不少,一般咱們給出方案而且應該簡述優缺點,好比方式有,jsonp、document.domain+iframe、window.name+ifram、location.hash+iframe、postMessage跨域、CORS跨域、websocket跨域、node代理跨域以及NGINX代理等方式。其中對於咱們經常使用的能夠張開說明,好比CORS跨域中簡單請求和非簡單請求的header字段,access-control-allow-origin、access-control-allow-headers、access-control-allow-method等常規head字段說明。
  • JavaScript中的繼承
    一、Es6中咱們直接可使用extends關鍵字去繼承,經過重寫super完成繼承,可是在es5中,纔是應該去主要細說的。2.原型繼承的核心爲父類的實例做爲子類的原型。優勢:很是純粹的繼承關係、簡單易用、父類新增的原型方法原型屬性子類均可以訪問到。缺點:要爲子類新增屬性和方法,必需要放到new Animal()以後,不能放到構造器中,來自原型對象的引用類型被全部實力共享,建立子類,沒法向構造函數傳參。3.構造函數繼承核心:使用父類構造函數來加強子類的實例優勢:解決了共享引用類型的問題,能夠在構造函數裏面傳參,能夠實現多繼承。缺點:實例不是父類實例,只能繼承父類的屬性和方法,不能繼承父類原型的方法和屬性、沒法實現函數的複用。四、組合繼承的核心:經過調用父類的構造,繼承父類的屬性並保留參數的有點,經過父類的實例做爲子類原型,實現函數複用。優勢:能夠繼承屬性和方法以及原型上的屬性和方法、便是子類實例也是父類實例、不存在屬性共享的問題、函數可複用。缺點:調用了兩次構造函數,生成了兩份實例。五、寄生組合繼承核心:砍掉父類的實例屬性,這樣,在調用兩次父類的構造時候,就不會初始化兩次實例方法和屬性,避免組合繼承的缺點
    es6 extends繼承,ES5中的繼承,實質上是先建立子類上的this,而後再將父類方法添加到this上,es6則是先建立父類的實例方法(必須調用super),而後在用子類構造函數修改this。沒有調用super,是沒有this的。
  • JavaScript中的節流和防抖
    防抖的原理爲觸發事件的n時間後才執行,若是n時間內事件再次被觸發,則以新觸發的時間爲標準,而後n事件後再執行

    節流的原理爲在持續觸發事件時候,每隔一段時間執行一次。咱們可使用time line或者定時器來實現,或者兩者結合實現。
  • JavaScript中的事件你瞭解哪些
    這種題目通常爲開放性的題目,首先咱們能夠從事件的階段來回答,事件冒泡、事件捕獲、以及目標階段。同時咱們能夠說明下事件委託的使用方式以及瀏覽器兼容性的問題。
  • setTimeout設置爲0發生了什麼
    這主要考察js的執行機制,能夠從event loop來回答,包括js的單線程以及task queue microtask queue等。
  • 原生ajax請求瞭解麼
  • js判斷數據類型的幾種方法
    一、最多見的typeof,返回的String格式。可以判斷function,可是判斷Object比較煩。二、判斷已知數據類型能夠用instanceof,注意instanceof後面必定是對象類型,而且大小寫不能錯。3.constructor方式。可是在實現繼承的時候回出現錯誤,須要手動修改。4.通用可是很繁瑣的方法爲prototype:Object.prototype.toString.call(a)
  • this指向問題
    一、常規爲題,從默認綁定、隱含綁定、明確綁定以及new綁定來回答。二、擴展es6中的箭頭函數,以及call、apply和bind的區別。
  • 你如何看待JavaScript這門語言
    開放新問題,能夠從參考《JavaScript語言精粹》,談談本身開發中遇到的各類問題,最重要的不是吐槽而是對雞肋的解決辦法,好比繼承的實現、塊級做用域、變量提高等。
  • es6用過麼?說說promise的實現
    關於es6的知識點這裏再也不贅述。Promise的實現主要是pub-sub模式。狀態和行爲相分離的難點。

    java

    React部分

  • react組件的生命週期相關
    react組件生命週期最好的提現是使用es5 的編碼方式,其中生命線大概分爲兩條路線,分別爲getDefaultProps、getInitialState、componentWillMount、render、componentDidMount、(Running),而後分爲兩路,componentWillReceiveProps、shouldComponentUpdate、componentWillUpdate、render、componentDidUpdate以及componentWillUumount。咱們通常在getInitialState中初始化組件的狀態數據,在componentDidMount或者componentWillMount中進行獲取API請求操做等,在shouldComponentUpdate中進行組件的優化。其中能夠展開如何優化以及官方推薦的PureRenderMixin等實現方式。以及別的方面擴展結合本身的開發經驗。
  • setState是同步的仍是異步的
    一般咱們的寫法都是異步的,可是真正想要咱們回答的是當給setState傳入函數的時候,其實表現的爲同步的。
  • 子組件的componentDidMount和父組件的componentDidMount哪個先執行?
    必然是子組件的componentDidMount限制性,能夠從react組件的生命週期進行分析擴展。
  • react的DIFF算法和virtual dom瞭解多少?node

React的render函數返回的是一個DOM描述,結果僅僅是輕量級的js對象,reactjs在調用setState的時候會更新DOM,並且是先更新virtual dom,而後和實際dom比較,最後更新dom。React厲害的地方不是說他比真實的dom速度快,而是你不敢數據怎麼變化,我都以最小的代價來更新視圖。方法就是我在內存當中使用新的數據來構建一個virtual dom,而後和舊DOM進行比較,找出差別,而後更新到DOM節點上。當咱們修改dom上的一個節點對應的state,react會當即將他標記爲「髒狀態」,在事件循環的最後才從新渲染全部的髒節點。在實際的代碼中,會對新舊兩棵樹進行一次深度優先遍歷,這樣每個節點都會有一個惟一的標記,沒遍歷到一個節點,就把該節點和新的樹進行比較,若是有差別就記錄到一個對象中,最後把差別應用到真正的DOM樹上。算法實現步驟爲:用js對象模擬DOM樹,比較兩顆虛擬DOM的差別,把差別應用到真正的DOM樹上,DOM DIFF採用的是增量更新的方式,相似於打補丁。React須要爲節點添加key來保證算法的效率。Key屬性能夠幫助react定位到正確的節點進行比較。從而大幅度減小DOM操做,提升性能。react

  • MVC和MVVM瞭解麼?能夠大體說一下雙向綁定的實現方式麼?

Modal層表明數據模型,能夠再modal層定義修改和操做數據的邏輯,view表明UI層,負責將數據轉換成UI展示出來,viewModal是同步view和modal的對象。用戶操做view層,view數據變化會同步到modal上,modal數據變化會當即反應到view中,viewModal經過實現雙向綁定來將view和modal鏈接到一塊兒。而雙向綁定,咱們能夠從髒檢查到標記更新來回答。webpack

  • 前端路由的實現方式
    從react當中咱們能夠說說react router的使用和原理,以及h5中的historyAPI,pushState和replaceState來回答。
  • a組件是b組件的父組件,b組件是c組件的父組件,如何讓渲染後的b和c在同級
    經過react16中不返回容器組件能夠實現,也能夠經過「曲線救國」的方式來實現。
  • react SSR瞭解麼
    react ssr有不少種實現方式,可是原理不變,目的就是爲了減小首屏白屏時間以及有好的SEO。對於實現方式咱們能夠從next.js以及webpack-isomorphic-tools來講實現。git

    瀏覽器相關

  • http三次握手後拿到HTML是如何進行加載的?es6

考覈的主要是瀏覽器加載頁面的機制。大概能夠從瀏覽器拿到HTML,自上而下開始解析,大體分爲解析DOM,解析CSSOM,構建渲染樹,佈局階段以及繪製階段來講明。其實儘量的詳細說明,好比構建DOM的時候分別經過Bytes、characters、tokens、Nodes最終到DOM等。回答也能夠擴展repaint和reflow等瀏覽器優化。

  • 簡述瀏覽器優化

  • 200 From cache和200 OK有什麼區別?

顧名思義是form cache是強緩存,不會和服務器通訊,而200OK即爲服務器處理結果正確。以此能夠從瀏覽器緩存、輸入url回車、刷新頁面以及強制刷新等方面展開緩存方面的講解。

  • http2.0新特性瞭解嗎

一、2採用二進制而非文本格式,二進制協議解析起來更高效。
二、採用多路複用,即爲同一個tcp鏈接上能夠創建多個http鏈接,那樣的話,咱們雪碧圖就沒有必要了。
三、使用報文頭壓縮,下降了開銷。
4.可讓服務器主動向瀏覽器推送消息,支持服務端推送,也就是服務端能夠對客戶端有多個響應。

  • post和get有什麼區別?

1 、GET把參數包含在URL中,POST經過request body傳遞參數。
二、GET在瀏覽器回退時是無害的,而POST會再次提交請求。 GET產生的URL地址能夠被Bookmark,而POST不能夠。 GET請求會被瀏覽器主動cache,而POST不會,除非手動設置。 GET請求只能進行url編碼,而POST支持多種編碼方式。 GET請求參數會被完整保留在瀏覽器歷史記錄裏,而POST中的參數不會被保留。 GET請求在URL中傳送的參數是有長度限制的,而POST麼有。 對參數的數據類型,GET只接受ASCII字符,而POST沒有限制。 GET比POST更不安全,由於參數直接暴露在URL上,因此不能用來傳遞敏感信息。 GET參數經過URL傳遞,POST放在Request body中。
三、GET和POST是什麼?HTTP協議中的兩種發送請求的方法。
四、HTTP是什麼?HTTP是基於TCP/IP的關於數據如何在萬維網中如何通訊的協議。五、HTTP的底層是TCP/IP。因此GET和POST的底層也是TCP/IP,也就是說,GET/POST都是TCP連接。GET和POST能作的事情是同樣同樣的。你要給GET加上request body,給POST帶上url參數,技術上是徹底行的通的。
六、在我大萬維網世界中,還有另外一個重要的角色:運輸公司。不一樣的瀏覽器(發起http請求)和服務器(接受http請求)就是不一樣的運輸公司。 雖然理論上,你能夠在車頂上無限的堆貨物(url中無限加參數)。可是運輸公司可不傻,裝貨和卸貨也是有很大成本的,他們會限制單次運輸量來控制風險,數據量太大對瀏覽器和服務器都是很大負擔。業界不成文的規定是,(大多數)瀏覽器一般都會限制url長度在2K個字節,而(大多數)服務器最多處理64K大小的url。超過的部分,恕不處理。若是你用GET服務,在request body偷偷藏了數據,不一樣服務器的處理方式也是不一樣的,有些服務器會幫你卸貨,讀出數據,有些服務器直接忽略,因此,雖然GET能夠帶request body,也不能保證必定能被接收到哦。
七、GET產生一個TCP數據包;POST產生兩個TCP數據包。
八、對於GET方式的請求,瀏覽器會把http header和data一併發送出去,服務器響應200(返回數據);而對於POST,瀏覽器先發送header,服務器響應100 continue,瀏覽器再發送data,服務器響應200 ok(返回數據)。也就是說,GET只須要汽車跑一趟就把貨送到了,而POST得跑兩趟,第一趟,先去和服務器打個招呼「嗨,我等下要送一批貨來,大家打開門迎接我」,而後再回頭把貨送過去。由於POST須要兩步,時間上消耗的要多一點,看起來GET比POST更有效。所以Yahoo團隊有推薦用GET替換POST來優化網站性能。但這是一個坑!跳入需謹慎。爲何?1. GET與POST都有本身的語義,不能隨便混用。2. 據研究,在網絡環境好的狀況下,發一次包的時間和發兩次包的時間差異基本能夠無視。而在網絡環境差的狀況下,兩次包的TCP在驗證數據包完整性上,有很是大的優勢。3. 並非全部瀏覽器都會在POST中發送兩次包,Firefox就只發送一次。

構建工具

  • 瞭解過webpack編譯過程嗎?

Webpack 的運行流程是一個串行的過程,從啓動到結束會依次執行如下流程,一、初始化參數:從配置文件和 Shell 語句中讀取與合併參數,得出最終的參數;二、開始編譯:用上一步獲得的參數初始化 Compiler 對象,加載全部配置的插件,執行對象的 run 方法開始執行編譯;三、肯定入口:根據配置中的 entry 找出全部的入口文件;四、編譯模塊:從入口文件出發,調用全部配置的 Loader 對模塊進行翻譯,再找出該模塊依賴的模塊,再遞歸本步驟直到全部入口依賴的文件都通過了本步驟的處理;五、完成模塊編譯:在通過第4步使用 Loader 翻譯完全部模塊後,獲得了每一個模塊被翻譯後的最終內容以及它們之間的依賴關係;六、輸出資源:根據入口和模塊之間的依賴關係,組裝成一個個包含多個模塊的 Chunk,再把每一個 Chunk 轉換成一個單獨的文件加入到輸出列表,這步是能夠修改輸出內容的最後機會;七、輸出完成:在肯定好輸出內容後,根據配置肯定輸出的路徑和文件名,把文件內容寫入到文件系統。在以上過程當中,Webpack 會在特定的時間點廣播出特定的事件,插件在監聽到感興趣的事件後會執行特定的邏輯,而且插件能夠調用 Webpack 提供的 API 改變 Webpack 的運行結果。

  • 編寫過webpack插件嗎

    一、Webpack 經過 Plugin 機制讓其更加靈活,以適應各類應用場景。 在 Webpack 運行的生命週期中會廣播出許多事件,Plugin 能夠監聽這些事件,在合適的時機經過 Webpack 提供的 API 改變輸出結果。二、Webpack 啓動後,在讀取配置的過程當中會先執行 new BasicPlugin(options) 初始化一個 BasicPlugin 得到其實例。 在初始化 compiler 對象後,再調用 basicPlugin.apply(compiler) 給插件實例傳入 compiler 對象。 插件實例在獲取到 compiler 對象後,就能夠經過 compiler.plugin(事件名稱, 回調函數) 監聽到 Webpack 廣播出來的事件。 而且能夠經過 compiler 對象去操做 Webpack。三、在開發 Plugin 時最經常使用的兩個對象就是 Compiler 和 Compilation,它們是 Plugin 和 Webpack 之間的橋樑。 Compiler 和 Compilation 的含義以下:Compiler 對象包含了 Webpack 環境全部的的配置信息,包含 options,loaders,plugins 這些信息,這個對象在 Webpack 啓動時候被實例化,它是全局惟一的,能夠簡單地把它理解爲 Webpack 實例;Compilation 對象包含了當前的模塊資源、編譯生成資源、變化的文件等。當 Webpack 以開發模式運行時,每當檢測到一個文件變化,一次新的 Compilation 將被建立。Compilation 對象也提供了不少事件回調供插件作擴展。經過 Compilation 也能讀取到 Compiler 對象。四、Compiler 和 Compilation 的區別在於:Compiler 表明了整個 Webpack 從啓動到關閉的生命週期,而 Compilation 只是表明了一次新的編譯。五、開發插件時須要注意:只要能拿到 Compiler 或 Compilation 對象,就能廣播出新的事件,因此在新開發的插件中也能廣播出事件,給其它插件監聽使用、傳給每一個插件的 Compiler 和 Compilation 對象都是同一個引用。也就是說在一個插件中修改了 Compiler 或 Compilation 對象上的屬性,會影響到後面的插件、有些事件是異步的,這些異步的事件會附帶兩個參數,第二個參數爲回調函數,在插件處理完任務時須要調用回調函數通知 Webpack,纔會進入下一處理流程。

  • 開發過webpack loader麼

一、一個 Loader 的職責是單一的,只須要完成一種轉換。 若是一個源文件須要經歷多步轉換才能正常使用,就經過多個 Loader 去轉換。 在調用多個 Loader 去轉換一個文件時,每一個 Loader 會鏈式的順序執行, 第一個 Loader 將會拿到需處理的原內容,上一個 Loader 處理後的結果會傳給下一個接着處理,最後的 Loader 將處理後的最終結果返回給 Webpack。二、因此,在你開發一個 Loader 時,請保持其職責的單一性,你只需關心輸入和輸出。

感悟

以上問題包括但不全面對於此次杭州的求職。總的來講,你的簡歷就是你給面試官的考綱,因此簡歷必定要真實,及時面試過程當中遇到不會的題目,也要沉着冷靜思考,不會也要主動認可,而後最好可以提出本身的思考和猜想。千萬別不懂裝懂!千萬別不懂裝懂!千萬別不懂裝懂!

前端,我的仍是以爲基礎很重要,從基礎到框架,從框架就到原理,從原理到源碼,一步一腳印。必定要自信,直面面試官,表現出本身最好的狀態。同事別太咄咄逼人,必定要尊敬面試官,禮貌。

最後,仍是但願每個求職者,都可以進入本身如願以償的公司拿到心儀的offer~
ps:如若文章有不當之處,歡迎你們指正。謝謝~

學習交流

關注公衆號: 【全棧前端精選】 每日獲取好文推薦。

公衆號內回覆 【1】,加入全棧前端學習羣,一塊兒交流。

相關文章
相關標籤/搜索