一年前端面試打怪升級之路(二)

如意同學發表於2018-03-02

傳送門:

一年前端面試打怪升級之路(一)

一年前端面試打怪升級之路(二)

一年前端面試打怪升級之路(三)

對於DXY的面試印象最深刻最難忘,所以就詳細地列一個單獨的篇幅吧

DXY

最想去的一家公司,參加過他們的技術分享會,技術氛圍早有耳聞。不侷限於做商業化的專案,而是會投入精力去做優化流程和提高效率的事情,開發開源工具,或者重構老舊專案等等

在我問到部門工作流程,第一位面試官說了一句話:在確定好技術選型後,怎麼爽怎麼寫。

這不是程式設計師的高潮嗎?!

全程歷時將近3小時,是學到最多的一次面試,也是目前以來被虐的最慘的一次。

筆試

首先筆試半小時,有一些常規的題目,涵蓋的內容有基本資料型別,去重陣列函式,Dom優化方案,行內元素有哪些,label的作用(這個很有意思),css選擇器的查詢方式(從右往左);css選擇器的優先順序;setTimeout非同步流程;函式this的指向。

也有一些個人不太確定答案的題目。其中不熟練的點有正則的宣告,即時函式的執行流程,操作符優先順序,css偽類選擇器的優先順序

將不確定的題目羅列一下

<!--關於正則 -->
正則宣告的正確選項

<!--console輸出結果是什麼,考察操作符優先順序-->
var a = 1,b =2;
console.log(a+++b)

<!--console輸出結果是什麼,考察即時函式的執行流程-->
var result = (function(){
    return 1;
},function(){
    return "2"
})()
console.log(typeof result)

<!--關於css選擇器優先順序排序-->
id class 標籤選擇器 屬性值選擇器  偽類選擇器  萬用字元選擇器 繼承選擇(大概是這幾類的排序)

複製程式碼

做完題目檢查了一遍,然後交給hr,等待通知。

等的時候對於DOM建立的優化那一題突然有了更好的方案

題目是這樣的:

<!--對下列方法進行優化-->
var nodeI,m;
var data = [] //這裡的data是一組真實資料
for(var i = 0,m = data.length ; i<m ; i++){
    nodeI = document.creatElement("li");
    nodeI.noteText = data[i];
    var con = document.getElementById("container");
    con.appendChild(nodeI);   
}
複製程式碼

我在寫的時候思考了一會兒,最後只是把container容器的變數提取為了全域性,這樣就不需要迴圈都去建立一個變數。

但是之後想到應該使用innerHTML屬性直接使用字串新增,這樣的效率是最高的,瀏覽器只需要對元素重排一次,而不是每次迴圈都去重新渲染頁面一次。

想著想著,面試官就進來了

第一位

一位冷冰冰的大哥,全程沒什麼話,很認真地在看我帶過去的簡歷,以及筆試題。

第一句話就對我說,你這個基本資料型別寫錯了吧,這麼基礎的題

我心想完了不會跪在這種題目吧。拿過來仔細看了下,五種型別string,null,number,boolean,undefined沒寫錯啊。面試官說還有object,而Null是屬於object的。

我覺得他說的不對,於是現場查了下,結果顯示我寫的應該是對的,我說了句,這點之後再求證好了就跳過了這個話題。

之後,他就開始指了幾道我寫的答案,問我是怎麼思考的。

遇到不會的,我就說我不確定,他也沒告訴我正確答案是什麼,我說的對不對。一直都是毫無波瀾的表情。

過完了題目,我開始想展示下寫的專案,拿出資料以及存在手機的動圖,他很隨意地看了下,然後說好的我知道了。

之後問有沒有做過h5,和pc端有什麼不同。

我說沒有做過完整的專案,h5在一般在手機端使用,點選事件不太一樣;另外對頁面效能要求比較高

看他反應想來是對我的答案不太滿意。

後來問我有沒有做過從0開始配置,開發產品,打包專案,到釋出上線的完整工作流。

我實話實說沒有,因為公司專案不需要使用腳手架,也沒有使用打包工具。我自己寫的專案有使用過webpack,瞭解一些配置和打包方法,但沒有過釋出專案的經驗。(後知後覺,他應該是想問開發環境和生產環境的配置有什麼不一樣)

他說ok瞭解,然後就問我有沒有什麼問題問他的

這句話一般就是想要結束面試的標識。我詢問了他們對這個崗位的要求,以及他們的技術棧。這些點面試官有比較耐心地去解答,這時候才感覺出來他是個有條不紊,話不多,但是很務實的人。

我感覺應該是看過簡歷以及筆試題之後,心裡已經有了預判覺得水平不夠,所以結束的非常快

他也直說,他們組缺乏的成員,我這個水平可能還達不到。讓我再等等,他去溝通下有沒有其他組的人有興趣的。

隨後就出去了。

第一位失敗,重點問題整理如下。

  1. H5和普通PC端有什麼不同
  2. 從0配置到釋出上線的完整流程
  3. 未來一年對自己的技術方向的規劃
  4. 對前端行業的看法

沒有問我的專案,沒有問解決問題的過程,沒有問筆試題以外的技術問題。

二面

第二位面試官,之前有過一些瞭解,有關注他的掘金,一個高階前端,端著電腦進來,從頭到尾笑眯眯,還是溫州老鄉。感覺很親切。偷偷@相學長一下,不知道他會不會知道哈哈哈

too young too simple。我的懷疑人生之路開始了

首先做了簡單的自我介紹,在自我介紹裡我趕緊趁機講了下我做過的專案,使用的技術點,以及一些比較有趣的小demo,都是上場面試中沒來得及展示的

他有仔細聽,有沒有評價我也忘了。和上一位面試官一樣沒有過多的表示。或許是因為對JQ的專案興趣不大吧。

接著又回到了筆試題上,我就搶先說了應該是錯了不少,而且有道題我後來有想到更好的優化方案。

1. 我闡述了我的方案

<!--對下列方法進行優化-->
var nodeI,m;
var data = [] //這裡的data是一組真實資料
var html = "";
var con = document.getElementById("container");
for(var i = 0,m = data.length ; i<m ; i++){
    html += "<li>"+data[i]+"</li>"
}
con.innerHTML = html;
複製程式碼
問1:為什麼這樣更好呢。

我說只在最後一步把內容加到頁面中,減少了瀏覽器重排重繪的次數

他立刻問2:什麼是重排重繪?

前兩天剛看到了這個概念,講了下自己的理解。重排是需要重新分析頁面元素尺寸;重繪是元素樣式的改變

問3:什麼情況下會導致重排重繪?

我說頁面佈局被修改或者重新渲染的時候。

問4:能不能再具體點

當時沒理get到他想要的答案,我就又重複了一遍。他應該是想問怎樣算是佈局被修改吧

標準答案:

  1. 新增或者刪除可見的DOM元素
  2. 元素位置改變
  3. 元素尺寸改變
  4. 元素內容改變(例如:一個文字被另一個不同尺寸的圖片替代)
  5. 頁面渲染初始化(這個無法避免)
  6. 瀏覽器視窗尺寸改變
問5:v-show元素的顯示和隱藏算是重排嗎?

我說算。我的答案應該是對的,但他應該是希望我能答出“新增或者刪除可見的dom元素屬於重排”這句話,v-show是設定了css的屬性,是算重排的

接著基本上開始一道道過筆試題,以及在原來題目基礎上擴充套件。

2. setTimeout的非同步執行

原題如下

<!--執行結果是什麼-->
var a = 2;
setTimeout(function(){
   a--;
});
a++
console.log(a);
複製程式碼

題目還是比較簡單,最終輸出的是3.

變態的來了

問1:如果外面的a++迴圈一百萬次呢,順序如何?

答,還是一樣,setTimeout在後面

問2:為什麼會這樣?

(標準答案:同步會阻塞程式。)

這裡稍微有點答非所問了,我受到近期看的一篇文章影響一直在強調同步非同步和阻塞非阻塞的區別,非同步是執行完了告訴你,同步是等待你執行完;堵塞是瀏覽器一直在請求是否完成。我也不知道我在說啥,我估計他也不知道我在說啥 - -)

問3:知道promise嗎,寫了一個promise物件,混合setTimeout方法,要求判斷輸出的先後順序

知道一點,曾經看到過類似的題目,但是時間比較久了不太記得,被我蒙對了

問4:為什麼會這樣?

根據我的理解簡單講了下事件迴圈機制

更多可以參照這兩篇文章:

這一次,徹底弄懂 JavaScript 執行機制

深入淺出JavaScript事件迴圈機制

問6:給你一個需求讓你寫吧。有一個實時搜尋的搜尋框,連續輸入的時候不觸發實時搜尋,當使用者停下來1s以上時,再顯示搜尋結果

電腦一擺,讓我敲。

十臉懵逼說的就是我

不過其實這個需求不應該寫不出來,之前做過的導航優化用的也是這個方法,在規定時間內未執行事件,就使用clearTimeout清空計時器。不過當時死腦筋陷入了時間戳,沒往這方面想。

正確寫法

var time = null;
input.addEventListener("input",()=>{
    cleartimeout(time);
    time = setTimeout(()=>{
        seach();
    })
})
複製程式碼

學長說如果這只是開始,如果能答出來還可以接著問抽象,不過我第一步就沒答出來

淚奔~~~~

3. 對this的理解

原題是讓選擇正確的呼叫方法,也比較簡單,正確選項長這樣

var opt = {
    name:"Amy",
    say:function(){return this.name}
}
複製程式碼

擴充套件開始

問1:怎麼理解函式中的this

指向呼叫函式的物件

問2:箭頭函式的this呢

額。不改變this指向,函式外部指向哪裡就是哪裡

問3:setTimeout函式裡面的呢

指向全域性

問4:我把上面的增加一個name2:this.name輸出什麼?

undefined..(更確切地說,根據執行環境不同,輸出結果也不同。這裡的this指向全域性,瀏覽器中的window.name其實是存在的,一般來說是空字串)

我把say方法改成這樣會如何
say:function(){
    setTimeout(function(){return this.name})
}
複製程式碼
問5:改成這樣呢
say:function(){
    setTimeout(()=>{return this.name})
}
複製程式碼

只能說一定要自信,雖然對於this是理解的,但是問到後面我已經沒底氣了,都不太敢說。

最後兩個問題我都忘了自己當時怎麼說的了,正確答案都是undefined,因為在執行say()的時候函式上下文為全域性了

4.跨域

原題是讓寫幾個跨域方案

我寫了cors,jsonp,window.name

問1:jsonp是怎麼實現的

我說通過script標籤引入

問2:為什麼可以這麼用,資料怎麼返回的?

我說script標籤是可以跨域訪問CDN的

標準答案:JSONP 由兩部分組成:回撥函式和資料。回撥函式是當響應到來時應該在頁面中呼叫的函式。回撥函式的名字一般是在請求中指定的。而資料就是傳入回撥函式中的 JSON 資料。

問3:window.name的侷限

只能在同一視窗,大小2m

問3:知道localstorge和sessionstorge的區別嗎

local是關閉視窗還會存在,資料永久儲存,除非去清除瀏覽器快取,session關閉視窗就清空了了

問4:localstorge和域名有關嗎,sessionstorge呢

相同瀏覽器的條件下,local在同一域名和埠下是可以共享的,而不同頁面無法共享session的資料 (注:如果同源,且屬於一個視窗下的iframe,session也是共享的)

4. 關於vue

首先問了幾個關於vue的基本問題

擴充開始

問1:你覺得vue和JQ相比,有什麼優勢

我說了維護更方便,以及資料渲染頁面的方式使邏輯和頁面分離,更加高效

他好像不太滿意,又追問了一遍。

我說有兩個最大的優勢,一個是雙向繫結,一個是元件。他點了點頭,然後繼續問:

問2:vue的雙向繫結的原理是什麼

我說在改變輸入框的屬性時實際上是在呼叫defineProperty的get和set方法(更專業的說法叫wacher),在方法裡面去修改繫結的元素的值。

問3 :虛擬dom有了解嗎

知道..不怎麼了解

問4:寫的時候為什麼data不直接返回物件資料,而是要用函式的形式return出結果?

恩....不瞭解

問56789:啊我已經說了不瞭解了所以之後的問題已經不知道他在問什麼了...

不過他就開始跟我講虛擬dom的工作原理,然後還時不時問幾個問題,你覺得他是怎麼做到的?如果是你會怎麼實現?

中途扔了一個問題給我,虛擬DOM的是這麼檢測到程式碼已經執行完了,然後插入真實的Dom中的。允許我查資料,他去洗手間。

短時間內我也並沒有查出什麼東西,然後他回來了跟我解釋。

大概意思是,vue裡面有一個類似於setTimeout的非同步機制,在所有同步程式執行完後,執行這個非同步操作,作為這段程式結束的標識。

類似於剛剛問的a++一萬次,setTimeout依然在最後執行。

恩...不明覺厲

6. 關於js原生

問1:怎麼去實現查詢元素的find方法?

沒見過這種型別的題目,所以想了一會兒,然後弱雞地說遍歷啊...

問2:他說遍歷子節點只能遍歷一層啊,那子節點的子節點呢?

繼續弱雞地說,遞迴呀...

問3:還有什麼更有效率的方法可以代替遍歷?

不知道哎。。

他引導了我半天,才說有方法叫querySelector()知道嗎,我說知道的,見過但是沒去了解過。

他開始跟我說這個效率是最高的,我問為啥,他說因為底層就不是用js寫的,我不明覺厲,表示驚歎。然而心中默默吐槽,你特麼不是要我寫個方法嗎!不能這麼開外掛的!

ps:後來特意去查了下,發現他說的不對啊,這個方法的效能還是比不上js原生getElementById的,不過和jq相比,還是快非常多,特意測試了下

//測試程式碼
console.time('$(".item")');
for (var i = 0; i < 10000; i++) {
  $(".item");
}
console.timeEnd('$(".item")');
//$(".item"): 56.569091796875ms

console.time('querySelectorAll');
for (var i = 0; i < 10000; i++) {
  document.querySelectorAll(".item");
}
console.timeEnd('querySelectorAll');
//querySelectorAll: 1781ms

console.time('getElementsByClassName');
for (var i = 0; i < 10000; i++) {
  document.getElementsByClassName("item");
}
console.timeEnd('getElementsByClassName');
//getElementsByClassName: 54ms

複製程式碼

7.關於css:

1. 行內元素怎麼設定垂直居中,塊級元素呢,舉三種方法

我說了四種方法:

  1. 常用的絕對定位
  2. flex佈局,然而flex佈局的屬性名記不清了
  3. 還有display設定為table
  4. 使用transform或者margin往回移動50%

2. 清除浮動都有哪些方法

說了both-clear和overflow:hidden兩種方法

3. nth-of-child和nth-of-type的區別

nth-of-child:查詢位置優先 nth-of-type:查詢元素優先

4. 怎麼實現在兩個元素中間有空位時,移到另一個元素依然讓其顯示

我說可以用css3動畫實現。

他問還有沒有其他的方法

沒答上來,就算是他的解釋也沒法讓我理解,怎麼做到對一個元素hover之後去設定另一個元素的display屬性??不用js能實現?

5. 怎麼實現三角形,為什麼會有這種現象?

將元素寬高設為0,然後邊框只保留一邊,另外三邊設為透明。畫了個圖說明原因。

6. 怎麼對三角形設定陰影

我說用filter中的drop-shadow屬性,他問為什麼,還有什麼做法,我想了一下說可以直接再寫個三角形放在下面,還可以寫個矩形然後旋轉下

關於css我覺得答得還可以,包括後來的反饋也是說擅長css。不過也可能因為到最後了面試官懶得再展開了。

8.最後問了平時是怎麼學習的

我說看視訊,看書

問:看什麼書

我說最近看了dom程式設計藝術和js物件導向

他馬上問:繼承有哪幾種方式

我講了我理解的兩種,我看的那本書中寫了十幾種繼承方式

問:知道class嗎

我說知道一些

問:和建構函式有區別嗎

有區別,他的屬性的是不可列舉的

這部分應該是答得不怎麼樣了,沒有使用過,只不過以前粗略地瀏覽過一遍文件,估計因為已經面試了很長時間所以也沒多做展開。

面試就告一段落。

總結

以上為問題記錄,有些問題很簡單,篇幅問題就沒一一寫出來了;還有些問題實在是超出了理解範圍,都不知道他在問什麼。只能憑藉短期記憶複述他的原話,忘了也很無力啊

高階前端的角度就是,你不僅僅要會用,還要知道為什麼要這麼用。

最後他問了我還有什麼想問他的。我當時傻逼地問了我表現怎麼樣,他說一般,不算好也不算差

其實我更想問他你是怎麼學習的,以及對我的發展有什麼建議。

當時被問的有些絕望,只想知道自己有沒有戲

技術總監

因為已經到了他們的下班時間了,總監就問了2個問題

1. 為什麼你們公司還在用JQ(目前部門就我一個人全職寫前端實在是沒有人手去重構專案啊!)
2. 你覺得自己在技術方面的優勢是什麼

我只能極力表達自己的學習能力,畢竟工作時間不長,而且面試表現也不算太好,同時跟他們的技術棧不符。

但面試時百分之90的問題都是我在工作之餘的學習成果,如果侷限於公司的業務,很多新的概念我是接觸不到的。

最後還是個等通知的結果。只能說這是一個全憑實力說話的地方,不看你工作年限的多少,不看你的性格,也沒人想要去了解你的潛力,很現實的投入產出比問題,只看你現在能不能為他們產生價值。

不過沒關係,收穫很多,繼續努力吧嘿~

相關文章