前端面試題

重點(diǎn)看面試流程和問題!!!

重點(diǎn)看面試流程和問題!!!

重點(diǎn)看面試流程和問題!!!

百度 WEB前端工程師 連續(xù)五面 全程3約個(gè)小時(shí)

一面

先完成筆試題

1、實(shí)現(xiàn)一個(gè)函數(shù),判斷輸入是不是回文字符串。



2、兩種以上方式實(shí)現(xiàn)已知或者未知寬度的垂直水平居中。



3、實(shí)現(xiàn)效果,點(diǎn)擊容器內(nèi)的圖標(biāo),圖標(biāo)邊框變成border 1px solid red,點(diǎn)擊空白處重置。



4、請(qǐng)簡單實(shí)現(xiàn)雙向數(shù)據(jù)綁定mvvm。

5、實(shí)現(xiàn)Storage,使得該對(duì)象為單例,并對(duì)localStorage進(jìn)行封裝設(shè)置值setItem(key,value)和getItem(key)

Q1 你的技術(shù)棧主要是react,那你說說你用react有什么坑點(diǎn)?

1、JSX做表達(dá)式判斷時(shí)候,需要強(qiáng)轉(zhuǎn)為boolean類型,如:

如果不使用 !!b 進(jìn)行強(qiáng)轉(zhuǎn)數(shù)據(jù)類型,會(huì)在頁面里面輸出 0。


2、盡量不要在 componentWillReviceProps 里使用 setState,如果一定要使用,那么需要判斷結(jié)束條件,不然會(huì)出現(xiàn)無限重渲染,導(dǎo)致頁面崩潰。(實(shí)際不是componentWillReviceProps會(huì)無限重渲染,而是componentDidUpdate)


3、給組件添加ref時(shí)候,盡量不要使用匿名函數(shù),因?yàn)楫?dāng)組件更新的時(shí)候,匿名函數(shù)會(huì)被當(dāng)做新的prop處理,讓ref屬性接受到新函數(shù)的時(shí)候,react內(nèi)部會(huì)先清空ref,也就是會(huì)以null為回調(diào)參數(shù)先執(zhí)行一次ref這個(gè)props,然后在以該組件的實(shí)例執(zhí)行一次ref,所以用匿名函數(shù)做ref的時(shí)候,有的時(shí)候去ref賦值后的屬性會(huì)取到null。

4、遍歷子節(jié)點(diǎn)的時(shí)候,不要用 index 作為組件的 key 進(jìn)行傳入。

Q2 我現(xiàn)在有一個(gè)button,要用react在上面綁定點(diǎn)擊事件,要怎么做?


Q3 接上一個(gè)問題,你覺得你這樣設(shè)置點(diǎn)擊事件會(huì)有什么問題嗎?


由于onClick使用的是匿名函數(shù),所有每次重渲染的時(shí)候,會(huì)把該onClick當(dāng)做一個(gè)新的prop來處理,會(huì)將內(nèi)部緩存的onClick事件進(jìn)行重新賦值,所以相對(duì)直接使用函數(shù)來說,可能有一點(diǎn)的性能下降(個(gè)人認(rèn)為)。


修改

當(dāng)然你在內(nèi)部聲明的不是箭頭函數(shù),然后你可能需要在設(shè)置onClick的時(shí)候使用bind綁定上下文,這樣的效果和先前的使用匿名函數(shù)差不多,因?yàn)閎ind會(huì)返回新的函數(shù),也會(huì)被react認(rèn)為是一個(gè)新的prop。


Q4 你說說event loop吧


首先,js是單線程的,主要的任務(wù)是處理用戶的交互,而用戶的交互無非就是響應(yīng)DOM的增刪改,使用事件隊(duì)列的形式,一次事件循環(huán)只處理一個(gè)事件響應(yīng),使得腳本執(zhí)行相對(duì)連續(xù),所以有了事件隊(duì)列,用來儲(chǔ)存待執(zhí)行的事件,那么事件隊(duì)列的事件從哪里被push進(jìn)來的呢。那就是另外一個(gè)線程叫事件觸發(fā)線程做的事情了,他的作用主要是在定時(shí)觸發(fā)器線程、異步HTTP請(qǐng)求線程滿足特定條件下的回調(diào)函數(shù)push到事件隊(duì)列中,等待js引擎空閑的時(shí)候去執(zhí)行,當(dāng)然js引擎執(zhí)行過程中有優(yōu)先級(jí)之分,首先js引擎在一次事件循環(huán)中,會(huì)先執(zhí)行js線程的主任務(wù),然后會(huì)去查找是否有微任務(wù)microtask(promise),如果有那就優(yōu)先執(zhí)行微任務(wù),如果沒有,在去查找宏任務(wù)macrotask(setTimeout、setInterval)進(jìn)行執(zhí)行。


Q5 說說事件流吧


事件流分為兩種,捕獲事件流和冒泡事件流。

捕獲事件流從根節(jié)點(diǎn)開始執(zhí)行,一直往子節(jié)點(diǎn)查找執(zhí)行,直到查找執(zhí)行到目標(biāo)節(jié)點(diǎn)。

冒泡事件流從目標(biāo)節(jié)點(diǎn)開始執(zhí)行,一直往父節(jié)點(diǎn)冒泡查找執(zhí)行,直到查到到根節(jié)點(diǎn)。

DOM事件流分為三個(gè)階段,一個(gè)是捕獲節(jié)點(diǎn),一個(gè)是處于目標(biāo)節(jié)點(diǎn)階段,一個(gè)是冒泡階段。


Q6 我現(xiàn)在有一個(gè)進(jìn)度條,進(jìn)度條中間有一串文字,當(dāng)我的進(jìn)度條覆蓋了文字之后,文字要與進(jìn)度條反色,怎么實(shí)現(xiàn)?


當(dāng)時(shí)我給的是js的方案,在進(jìn)度條寬度變化的時(shí)候,計(jì)算蓋過每一個(gè)文字的50%,如果超過,設(shè)置文字相反顏色。當(dāng)然css也有對(duì)應(yīng)的方案,也就是 mix-blend-mode,我并沒有接觸過。對(duì)應(yīng)html也有對(duì)應(yīng)方案,也就設(shè)置兩個(gè)相同位置但是顏色相反的dom結(jié)構(gòu)在重疊在一起,頂層覆蓋底層,最頂層的進(jìn)度條取overflow為hidden,其寬度就為進(jìn)度。


二面

Q1 你為什么要離開上一家公司?

-

Q2 你覺得理想的前端地位是什么?

-

Q3 那你意識(shí)到問題所在,你又嘗試過解決問題嗎?

-

三面


Q1 說一下你上一家公司的一個(gè)整體開發(fā)流程吧

-

Q2 react 的虛擬dom是怎么實(shí)現(xiàn)的


首先說說為什么要使用Virturl DOM,因?yàn)椴僮髡鎸?shí)DOM的耗費(fèi)的性能代價(jià)太高,所以react內(nèi)部使用js實(shí)現(xiàn)了一套dom結(jié)構(gòu),在每次操作在和真實(shí)dom之前,使用實(shí)現(xiàn)好的diff算法,對(duì)虛擬dom進(jìn)行比較,遞歸找出有變化的dom節(jié)點(diǎn),然后對(duì)其進(jìn)行更新操作。為了實(shí)現(xiàn)虛擬DOM,我們需要把每一種節(jié)點(diǎn)類型抽象成對(duì)象,每一種節(jié)點(diǎn)類型有自己的屬性,也就是prop,每次進(jìn)行diff的時(shí)候,react會(huì)先比較該節(jié)點(diǎn)類型,假如節(jié)點(diǎn)類型不一樣,那么react會(huì)直接刪除該節(jié)點(diǎn),然后直接創(chuàng)建新的節(jié)點(diǎn)插入到其中,假如節(jié)點(diǎn)類型一樣,那么會(huì)比較prop是否有更新,假如有prop不一樣,那么react會(huì)判定該節(jié)點(diǎn)有更新,那么重渲染該節(jié)點(diǎn),然后在對(duì)其子節(jié)點(diǎn)進(jìn)行比較,一層一層往下,直到?jīng)]有子節(jié)點(diǎn)。


Q3 react 的渲染過程中,兄弟節(jié)點(diǎn)之間是怎么處理的?也就是key值不一樣的時(shí)候。


通常我們輸出節(jié)點(diǎn)的時(shí)候都是map一個(gè)數(shù)組然后返回一個(gè)ReactNode,為了方便react內(nèi)部進(jìn)行優(yōu)化,我們必須給每一個(gè)reactNode添加key,這個(gè)key prop在設(shè)計(jì)值處不是給開發(fā)者用的,而是給react用的,大概的作用就是給每一個(gè)reactNode添加一個(gè)身份標(biāo)識(shí),方便react進(jìn)行識(shí)別,在重渲染過程中,如果key一樣,若組件屬性有所變化,則react只更新組件對(duì)應(yīng)的屬性;沒有變化則不更新,如果key不一樣,則react先銷毀該組件,然后重新創(chuàng)建該組件。


Q4 我現(xiàn)在有一個(gè)數(shù)組[1,2,3,4],請(qǐng)實(shí)現(xiàn)算法,得到這個(gè)數(shù)組的全排列的數(shù)組,如[2,1,3,4],[2,1,4,3]。。。。你這個(gè)算法的時(shí)間復(fù)雜度是多少


這個(gè)我沒寫出來,大概給了個(gè)思路,將每一個(gè)數(shù)組拆除倆個(gè)小數(shù)組進(jìn)行求它的全排列,然后得到的結(jié)果互相之間又進(jìn)行全排列,然后把最后的結(jié)果連接起來。


Q5 我現(xiàn)在有一個(gè)背包,容量為m,然后有n個(gè)貨物,重量分別為w1,w2,w3...wn,每個(gè)貨物的價(jià)值是v1,v2,v3...vn,w和v沒有任何關(guān)系,請(qǐng)求背包能裝下的最大價(jià)值。


這個(gè)我也沒寫出來,也給了個(gè)思路,首先使用Q4的方法得到貨物重量數(shù)組的全組合(包括拆分成小數(shù)組的全組合),然后計(jì)算每一個(gè)組合的價(jià)值,并進(jìn)行排序,然后遍歷數(shù)組,找到價(jià)值較高切剛好能裝進(jìn)背包m的組合。


四面

Q1 請(qǐng)說一下你的上一家公司的研發(fā)發(fā)布流程。

Q2 你說一下webpack的一些plugin,怎么使用webpack對(duì)項(xiàng)目進(jìn)行優(yōu)化。

構(gòu)建優(yōu)化

1、減少編譯體積 ContextReplacementPugin、IgnorePlugin、babel-plugin-import、babel-plugin-transform-runtime。

2、并行編譯 happypack、thread-loader、uglifyjsWebpackPlugin開啟并行

3、緩存 cache-loader、hard-source-webpack-plugin、uglifyjsWebpackPlugin開啟緩存、babel-loader開啟緩存

4、預(yù)編譯 dllWebpackPlugin && DllReferencePlugin、auto-dll-webapck-plugin

性能優(yōu)化

1、減少編譯體積 Tree-shaking、Scope Hositing。

2、hash緩存 webpack-md5-plugin

3、拆包 splitChunksPlugin、import()、require.ensure


Q3 es6 class 的new實(shí)例和es5的new實(shí)例有什么區(qū)別


這個(gè)我覺得是一樣的(當(dāng)時(shí)因?yàn)楹苌倏碽abel編譯之后的結(jié)果),面試官說不一樣。。。后來我看了一下babel的編譯結(jié)果,發(fā)現(xiàn)只是類的方法聲明的過程不一樣而已,最后new的結(jié)果是一樣的。。。具體答案現(xiàn)在我也不知道。


Q4 看你簡歷上寫了canvas,你說一下為什么canvas的圖片為什么會(huì)有跨域問題。


canvas圖片為什么跨域我不知道,至今沒查出來,也差不多,大概跨域原因和瀏覽器跨域的原因是一樣的吧。


Q5 我現(xiàn)在有一個(gè)canvas,上面隨機(jī)布著一些黑塊,請(qǐng)實(shí)現(xiàn)方法,計(jì)算canvas上有多少個(gè)黑塊。


使用getImageData獲取像素?cái)?shù)組,然后遍歷數(shù)組,把在遍歷節(jié)點(diǎn)的過程中,查看節(jié)點(diǎn)上下左右的像素顏色是否相同,如果相同,然后設(shè)置標(biāo)識(shí),最后groupBy一下所有像素。(這是我當(dāng)時(shí)的方案)


Q6 請(qǐng)手寫實(shí)現(xiàn)一個(gè)promise


注:四面是一個(gè)超級(jí)可愛的小姐姐,電腦給我讓我寫完之后,我說我寫得差不多了,然后電腦給她,然后她竟然默默的在看我的代碼,嘗試尋找我的思路,也沒有問我實(shí)現(xiàn)思路是啥,然后我就問她,你不應(yīng)該是讓我給你解釋我的代碼思路嗎。。。你竟然在嘗試尋找我的思路,我自己都不知道我自己是思路是啥。。。然后我兩都笑了,哈哈哈。最后結(jié)束的時(shí)候我說我午飯還沒吃,她還叫了另外一個(gè)小哥哥先帶了下去吃飯,真是一個(gè)善良的小姐姐,非常感謝。


五面

Q1 你說一下你的技術(shù)有什么特點(diǎn)


Q2 說一下你覺得你最得意的一個(gè)項(xiàng)目?你這個(gè)項(xiàng)目有什么缺陷,弊端嗎?


Q3 現(xiàn)在有那么一個(gè)團(tuán)隊(duì),假如讓你來做技術(shù)架構(gòu),你會(huì)怎么做?


考慮到團(tuán)隊(duì)每一個(gè)前端的技術(shù)棧可能不一致,這個(gè)時(shí)候我可能選擇微前端架構(gòu),讓每個(gè)人負(fù)責(zé)的模塊可以單獨(dú)開發(fā),單獨(dú)部署,單獨(dú)回滾,不依賴于其他項(xiàng)目模塊,在盡可能的情況下節(jié)約團(tuán)隊(duì)成員之間的學(xué)習(xí)成本,當(dāng)然這肯定也有缺點(diǎn),那就是每個(gè)模塊都需要一個(gè)前端項(xiàng)目,單獨(dú)部署,單獨(dú)回滾無疑也加大了運(yùn)維成本。


Q4 說一下你上一家公司的主要業(yè)務(wù)流程,你參與到其中了嗎?


杭州有贊

一面 WEB前端工程師 電話面 全程43分鐘


Q1 自我介紹


Q2 說說從輸入U(xiǎn)RL到看到頁面發(fā)生的全過程,越詳細(xì)越好。


1、首先瀏覽器主進(jìn)程接管,開了一個(gè)下載線程。

2、然后進(jìn)行HTTP請(qǐng)求(DNS查詢、IP尋址等等),中間會(huì)有三次捂手,等待響應(yīng),開始下載響應(yīng)報(bào)文。

3、將下載完的內(nèi)容轉(zhuǎn)交給Renderer進(jìn)程管理。

4、Renderer進(jìn)程開始解析css rule tree和dom tree,這兩個(gè)過程是并行的,所以一般我會(huì)把link標(biāo)簽放在頁面頂部。

5、解析繪制過程中,當(dāng)瀏覽器遇到link標(biāo)簽或者script、img等標(biāo)簽,瀏覽器會(huì)去下載這些內(nèi)容,遇到時(shí)候緩存的使用緩存,不適用緩存的重新下載資源。

6、css rule tree和dom tree生成完了之后,開始合成render tree,這個(gè)時(shí)候?yàn)g覽器會(huì)進(jìn)行l(wèi)ayout,開始計(jì)算每一個(gè)節(jié)點(diǎn)的位置,然后進(jìn)行繪制。

繪制結(jié)束后,關(guān)閉TCP連接,過程有四次揮手。



Q3 你剛剛說了三次握手,四次揮手,那你描述一下?


本人對(duì)計(jì)算機(jī)網(wǎng)絡(luò)的這些概念一直不是很熟悉,所以這個(gè)問題回答不會(huì),這里mark下文章,感興趣的同學(xué)查看地址


Q4 剛剛Q2中說的CSS和JS的位置會(huì)影響頁面效率,為什么?


css在加載過程中不會(huì)影響到DOM樹的生成,但是會(huì)影響到Render樹的生成,進(jìn)而影響到layout,所以一般來說,style的link標(biāo)簽需要盡量放在head里面,因?yàn)樵诮馕鯠OM樹的時(shí)候是自上而下的,而css樣式又是通過異步加載的,這樣的話,解析DOM樹下的body節(jié)點(diǎn)和加載css樣式能盡可能的并行,加快Render樹的生成的速度。


js腳本應(yīng)該放在底部,原因在于js線程與GUI渲染線程是互斥的關(guān)系,如果js放在首部,當(dāng)下載執(zhí)行js的時(shí)候,會(huì)影響渲染行程繪制頁面,js的作用主要是處理交互,而交互必須得先讓頁面呈現(xiàn)才能進(jìn)行,所以為了保證用戶體驗(yàn),盡量讓頁面先繪制出來。


Q5 現(xiàn)在有一個(gè)函數(shù)A和函數(shù)B,請(qǐng)你實(shí)現(xiàn)B繼承A



Q6 剛剛你在Q5中說的幾種繼承的方式,分別說說他們的優(yōu)缺點(diǎn)


方式1:簡單易懂,但是無法實(shí)現(xiàn)多繼承,父類新增原型方法/原型屬性,子類都能訪問到

方式2:可以實(shí)現(xiàn)多繼承,但是只能繼承父類的實(shí)例屬性和方法,不能繼承原型屬性/方法

方式3:可以繼承實(shí)例屬性/方法,也可以繼承原型屬性/方法,但是示例了兩個(gè)A的構(gòu)造函數(shù)


Q7 說說CSS中幾種垂直水平居中的方式


參考前面百度一面筆試題Q2


Q8 Q7中說的flex布局,垂直水平居中必須知道寬度嗎?


是的,必須知道高度(腦子進(jìn)水了回答了必須知道,其實(shí)答案是不需要知道高度的)


Q9 描述一下this


this,函數(shù)執(zhí)行的上下文,可以通過apply,call,bind改變this的指向。對(duì)于匿名函數(shù)或者直接調(diào)用的函數(shù)來說,this指向全局上下文(瀏覽器為window,nodejs為global),剩下的函數(shù)調(diào)用,那就是誰調(diào)用它,this就指向誰。當(dāng)然還有es6的箭頭函數(shù),箭頭函數(shù)的指向取決于該箭頭函數(shù)聲明的位置,在哪里聲明,this就指向哪里。


Q10 說一下瀏覽器的緩存機(jī)制


瀏覽器緩存機(jī)制有兩種,一種為強(qiáng)緩存,一種為協(xié)商緩存。

對(duì)于強(qiáng)緩存,瀏覽器在第一次請(qǐng)求的時(shí)候,會(huì)直接下載資源,然后緩存在本地,第二次請(qǐng)求的時(shí)候,直接使用緩存。

對(duì)于協(xié)商緩存,第一次請(qǐng)求緩存且保存緩存標(biāo)識(shí)與時(shí)間,重復(fù)請(qǐng)求向服務(wù)器發(fā)送緩存標(biāo)識(shí)和最后緩存時(shí)間,服務(wù)端進(jìn)行校驗(yàn),如果失效則使用緩存。

強(qiáng)緩存方案

Exprires:服務(wù)端的響應(yīng)頭,第一次請(qǐng)求的時(shí)候,告訴客戶端,該資源什么時(shí)候會(huì)過期。Exprires的缺陷是必須保證服務(wù)端時(shí)間和客戶端時(shí)間嚴(yán)格同步。

Cache-control:max-age,表示該資源多少時(shí)間后過期,解決了客戶端和服務(wù)端時(shí)間必須同步的問題,

協(xié)商緩存方案

If-None-Match/ETag:緩存標(biāo)識(shí),對(duì)比緩存時(shí)使用它來標(biāo)識(shí)一個(gè)緩存,第一次請(qǐng)求的時(shí)候,服務(wù)端會(huì)返回該標(biāo)識(shí)給客戶端,客戶端在第二次請(qǐng)求的時(shí)候會(huì)帶上該標(biāo)識(shí)與服務(wù)端進(jìn)行對(duì)比并返回If-None-Match標(biāo)識(shí)是否表示匹配。

Last-modified/If-Modified-Since:第一次請(qǐng)求的時(shí)候服務(wù)端返回Last-modified表明請(qǐng)求的資源上次的修改時(shí)間,第二次請(qǐng)求的時(shí)候客戶端帶上請(qǐng)求頭If-Modified-Since,表示資源上次的修改時(shí)間,服務(wù)端拿到這兩個(gè)字段進(jìn)行對(duì)比。


Q11 ETag是這個(gè)字符串是怎么生成的?


沒答出來,我當(dāng)時(shí)猜是根據(jù)文件內(nèi)容或者最后修改時(shí)間進(jìn)行的加密算法。其實(shí)官方?jīng)]有明確指定生成ETag值的方法。通常,使用內(nèi)容的散列,最后修改時(shí)間戳的哈希值,或簡單地使用版本號(hào)。


Q12 現(xiàn)在要你完成一個(gè)Dialog組件,說說你設(shè)計(jì)的思路?它應(yīng)該有什么功能?


1、該組件需要提供hook指定渲染位置,默認(rèn)渲染在body下面。

2、然后改組件可以指定外層樣式,如寬度等

3、組件外層還需要一層mask來遮住底層內(nèi)容,點(diǎn)擊mask可以執(zhí)行傳進(jìn)來的onCancel函數(shù)關(guān)閉Dialog。

4、另外組件是可控的,需要外層傳入visible表示是否可見。

5、然后Dialog可能需要自定義頭head和底部footer,默認(rèn)有頭部和底部,底部有一個(gè)確認(rèn)按鈕和取消按鈕,確認(rèn)按鈕會(huì)執(zhí)行外部傳進(jìn)來的onOk事件,然后取消按鈕會(huì)執(zhí)行外部傳進(jìn)來的onCancel事件。

6、當(dāng)組件的visible為true時(shí)候,設(shè)置body的overflow為hidden,隱藏body的滾動(dòng)條,反之顯示滾動(dòng)條。

7、組件高度可能大于頁面高度,組件內(nèi)部需要滾動(dòng)條。

8、只有組件的visible有變化且為ture時(shí)候,才重渲染組件內(nèi)的所有內(nèi)容。


Q13 你覺得你做過的你覺得最值得炫耀的項(xiàng)目?


螞蟻金服-體驗(yàn)技術(shù)部 資深數(shù)據(jù)可視化研發(fā)工程師


一面 電話面 全程1小時(shí)24分鐘


Q1 描述一下你最近做的可視化的項(xiàng)目


Q2 剛剛說的java調(diào)用js離線生成數(shù)據(jù)報(bào)告?java調(diào)用js的promise異步返回結(jié)果怎么實(shí)現(xiàn)的?


使用java的js引擎Nashorn,Nashorn不支持事件隊(duì)列,是要引進(jìn)polyfill,然后java調(diào)用js方法獲得java的promise對(duì)象,然后在調(diào)用該對(duì)象的then方法,回調(diào)函數(shù)為java中的某各類的某個(gè)方法,然后while一個(gè)表示是否已執(zhí)行回調(diào)的變量,如果未執(zhí)行,則讓java主線程sleep,如果已經(jīng)執(zhí)行,則跳出循環(huán),表示是否已執(zhí)行回調(diào)的變量在傳入promise的回調(diào)函數(shù)中設(shè)置更改。詳情代碼見地址


Q3 說說svg和canvas各自的優(yōu)缺點(diǎn)?


共同點(diǎn):都是有效的圖形工具,對(duì)于數(shù)據(jù)較小的情況下,都很又高的性能,它們都使用 JavaScript 和 HTML;它們都遵守萬維網(wǎng)聯(lián)合會(huì) (W3C) 標(biāo)準(zhǔn)。

svg優(yōu)點(diǎn):

矢量圖,不依賴于像素,無限放大后不會(huì)失真。

以dom的形式表示,事件綁定由瀏覽器直接分發(fā)到節(jié)點(diǎn)上。

svg缺點(diǎn):

dom形式,涉及到動(dòng)畫時(shí)候需要更新dom,性能較低。

canvas優(yōu)點(diǎn):

定制型更強(qiáng),可以繪制繪制自己想要的東西。

非dom結(jié)構(gòu)形式,用JavaScript進(jìn)行繪制,涉及到動(dòng)畫性能較高。

canvas缺點(diǎn):

事件分發(fā)由canvas處理,繪制的內(nèi)容的事件需要自己做處理。

依賴于像素,無法高效保真,畫布較大時(shí)候性能較低。


Q4 你剛剛說的canvas渲染較大畫布的時(shí)候性能會(huì)較低?為什么?


因?yàn)閏anvas依賴于像素,在繪制過程中是一個(gè)一個(gè)像素去繪制的,當(dāng)畫布足夠大,像素點(diǎn)也就會(huì)足夠多,那么想能就會(huì)足夠低。


Q6 假設(shè)我現(xiàn)在有5000個(gè)圓,完全繪制出來,點(diǎn)擊某一個(gè)圓,該圓高亮,另外4999個(gè)圓設(shè)為半透明,分別說說用svg和canvas怎么實(shí)現(xiàn)?


首先,從數(shù)據(jù)出發(fā),我們的每個(gè)圓是一個(gè)數(shù)據(jù),這個(gè)數(shù)據(jù)有圓的x、y、radius、isHighlight如果是svg,直接渲染節(jié)點(diǎn)即可,然后往節(jié)點(diǎn)上邊綁定點(diǎn)擊事件,點(diǎn)擊改變所有數(shù)據(jù)的高亮屬性(必須同步執(zhí)行完成),然后讓瀏覽器進(jìn)行繪制。如果是canvas,我們需要自己綁定事件到canvans標(biāo)簽上,然后點(diǎn)擊的時(shí)候判斷點(diǎn)擊的位置是否在圓內(nèi),如果在某個(gè)圓內(nèi),則更新所有數(shù)據(jù)的高亮屬性,之后在進(jìn)行一次性繪制。


Q7 剛剛說的canvas的點(diǎn)擊事件,怎么樣實(shí)現(xiàn)?假如不是圓,這些圖形是正方形、長方形、規(guī)則圖形、不規(guī)則圖形呢。


針對(duì)于每一個(gè)形狀,將其抽象成shape類,每一個(gè)類有自己的方法isPointInSide來判斷節(jié)點(diǎn)是否在圖形內(nèi),對(duì)于不規(guī)則圖形,當(dāng)做矩形處理,點(diǎn)擊的時(shí)候執(zhí)行該方法判斷點(diǎn)擊位置是否在圖形內(nèi)。


Q8 那假如我的圖形可能有變形、放大、偏移、旋轉(zhuǎn)的需求呢?你的這個(gè)isPointInSide怎么處理?


這個(gè)我答不出來,據(jù)面試官提示,好像有相應(yīng)的API處理變形、旋轉(zhuǎn)、放大等等之后的位置映射關(guān)系。


Q9 那個(gè)這個(gè)canvas的點(diǎn)擊事件,點(diǎn)擊的時(shí)候怎么樣快速的從這5000個(gè)圓中找到你點(diǎn)擊的那個(gè)圓(不完全遍歷5000個(gè)節(jié)點(diǎn))?


可以通過預(yù)查找的形式,當(dāng)鼠標(biāo)劃過的時(shí)候預(yù)先查找到鼠標(biāo)附近的一些節(jié)點(diǎn),當(dāng)點(diǎn)擊的時(shí)候在從這些預(yù)先篩選好的節(jié)點(diǎn)里查找點(diǎn)擊下來的節(jié)點(diǎn),當(dāng)然這個(gè)方法的前提是不能影響js主線程的執(zhí)行,必須是異步的形式。


Q10 那你用過@antv/g6,里面有一個(gè)tree,說說你大學(xué)時(shí)候接觸到的tree的數(shù)據(jù)結(jié)構(gòu)是怎么實(shí)現(xiàn)的?


畢業(yè)一年多,tree的結(jié)構(gòu)大概忘記了,我當(dāng)時(shí)是這么回答的:

大學(xué)使用的是C++學(xué)的數(shù)據(jù)結(jié)構(gòu),是用指針的形式,首先有一個(gè)根節(jié)點(diǎn),根節(jié)點(diǎn)里有一個(gè)指針數(shù)組指向它的所有子節(jié)點(diǎn),然后每一個(gè)子節(jié)點(diǎn)也是,擁有著子節(jié)點(diǎn)的指針數(shù)組,一層一層往下,直到為葉子節(jié)點(diǎn),指針數(shù)組指向?yàn)榭铡?/p>


Q11 還記得二叉樹嗎?描述二叉樹的幾種遍歷方式?


先序遍歷:若二叉樹非空,訪問根結(jié)點(diǎn),遍歷左子樹,遍歷右子樹。

中序遍歷:若二叉樹非空,遍歷左子樹;訪問根結(jié)點(diǎn);遍歷右子樹。

后序遍歷:若二叉樹非空,遍歷左子樹;遍歷右子樹;訪問根結(jié)點(diǎn)。

所有遍歷是以遞歸的形似,直到?jīng)]有子節(jié)點(diǎn)。


Q12 說說你記得的所有的排序,他們的原理是什么?


冒泡排序:雙層遍歷,對(duì)比前后兩個(gè)節(jié)點(diǎn),如果滿足條件,位置互換,直到遍歷結(jié)束。

快速排序:去數(shù)組中間的那一個(gè)數(shù),然后遍歷所有數(shù),小于該數(shù)的push到一個(gè)數(shù)組,大于該數(shù)的push到另外一個(gè)數(shù)組,然后遞歸去排序這兩個(gè)數(shù)組,最后將所有結(jié)果連接起來。

選擇排序:聲明一個(gè)數(shù)組,每次去輸入數(shù)組里面找數(shù)組中的最大值或者最小值,取出來后push到聲明的數(shù)組中,直到輸入數(shù)組為空。


Q13 說一下你覺得你做過的最復(fù)雜的項(xiàng)目?中間遇到的困難,以及你是怎么解決的?



面試官:我這邊問題差不多問完了,你還有什么問題?

我:很驚訝今天全都是問可視化相關(guān)的,沒怎么問js,css,html。

面試官:那我們繼續(xù)吧

我:。。。



Q14 那給我介紹一下react吧(面試官是做可視化開發(fā)的,根本不懂react)


以前我們沒有jquery的時(shí)候,我們大概的流程是從后端通過ajax獲取到數(shù)據(jù)然后使用jquery生成dom結(jié)果然后更新到頁面當(dāng)中,但是隨著業(yè)務(wù)發(fā)展,我們的項(xiàng)目可能會(huì)越來越復(fù)雜,我們每次請(qǐng)求到數(shù)據(jù),或則數(shù)據(jù)有更改的時(shí)候,我們又需要重新組裝一次dom結(jié)構(gòu),然后更新頁面,這樣我們手動(dòng)同步dom和數(shù)據(jù)的成本就越來越高,而且頻繁的操作dom,也使我我們頁面的性能慢慢的降低。

這個(gè)時(shí)候mvvm出現(xiàn)了,mvvm的雙向數(shù)據(jù)綁定可以讓我們?cè)跀?shù)據(jù)修改的同時(shí)同步dom的更新,dom的更新也可以直接同步我們數(shù)據(jù)的更改,這個(gè)特定可以大大降低我們手動(dòng)去維護(hù)dom更新的成本,mvvm為react的特性之一,雖然react屬于單項(xiàng)數(shù)據(jù)流,需要我們手動(dòng)實(shí)現(xiàn)雙向數(shù)據(jù)綁定。

有了mvvm還不夠,因?yàn)槿绻看斡袛?shù)據(jù)做了更改,然后我們都全量更新dom結(jié)構(gòu)的話,也沒辦法解決我們頻繁操作dom結(jié)構(gòu)(降低了頁面性能)的問題,為了解決這個(gè)問題,react內(nèi)部實(shí)現(xiàn)了一套虛擬dom結(jié)構(gòu),也就是用js實(shí)現(xiàn)的一套dom結(jié)構(gòu),他的作用是講真實(shí)dom在js中做一套緩存,每次有數(shù)據(jù)更改的時(shí)候,react內(nèi)部先使用算法,也就是鼎鼎有名的diff算法對(duì)dom結(jié)構(gòu)進(jìn)行對(duì)比,找到那些我們需要新增、更新、刪除的dom節(jié)點(diǎn),然后一次性對(duì)真實(shí)DOM進(jìn)行更新,這樣就大大降低了操作dom的次數(shù)。

那么diff算法是怎么運(yùn)作的呢,首先,diff針對(duì)類型不同的節(jié)點(diǎn),會(huì)直接判定原來節(jié)點(diǎn)需要卸載并且用新的節(jié)點(diǎn)來裝載卸載的節(jié)點(diǎn)的位置;針對(duì)于節(jié)點(diǎn)類型相同的節(jié)點(diǎn),會(huì)對(duì)比這個(gè)節(jié)點(diǎn)的所有屬性,如果節(jié)點(diǎn)的所有屬性相同,那么判定這個(gè)節(jié)點(diǎn)不需要更新,如果節(jié)點(diǎn)屬性不相同,那么會(huì)判定這個(gè)節(jié)點(diǎn)需要更新,react會(huì)更新并重渲染這個(gè)節(jié)點(diǎn)。

react設(shè)計(jì)之初是主要負(fù)責(zé)UI層的渲染,雖然每個(gè)組件有自己的state,state表示組件的狀態(tài),當(dāng)狀態(tài)需要變化的時(shí)候,需要使用setState更新我們的組件,但是,我們想通過一個(gè)組件重渲染它的兄弟組件,我們就需要將組件的狀態(tài)提升到父組件當(dāng)中,讓父組件的狀態(tài)來控制這兩個(gè)組件的重渲染,當(dāng)我們組件的層次越來越深的時(shí)候,狀態(tài)需要一直往下傳,無疑加大了我們代碼的復(fù)雜度,我們需要一個(gè)狀態(tài)管理中心,來幫我們管理我們狀態(tài)state。

這個(gè)時(shí)候,redux出現(xiàn)了,我們可以將所有的state交給redux去管理,當(dāng)我們的某一個(gè)state有變化的時(shí)候,依賴到這個(gè)state的組件就會(huì)進(jìn)行一次重渲染,這樣就解決了我們的我們需要一直把state往下傳的問題。redux有action、reducer的概念,action為唯一修改state的來源,reducer為唯一確定state如何變化的入口,這使得redux的數(shù)據(jù)流非常規(guī)范,同時(shí)也暴露出了redux代碼的復(fù)雜,本來那么簡單的功能,卻需要完成那么多的代碼。

后來,社區(qū)就出現(xiàn)了另外一套解決方案,也就是mobx,它推崇代碼簡約易懂,只需要定義一個(gè)可觀測(cè)的對(duì)象,然后哪個(gè)組價(jià)使用到這個(gè)可觀測(cè)的對(duì)象,并且這個(gè)對(duì)象的數(shù)據(jù)有更改,那么這個(gè)組件就會(huì)重渲染,而且mobx內(nèi)部也做好了是否重渲染組件的生命周期shouldUpdateComponent,不建議開發(fā)者進(jìn)行更改,這使得我們使用mobx開發(fā)項(xiàng)目的時(shí)候可以簡單快速的完成很多功能,連redux的作者也推薦使用mobx進(jìn)行項(xiàng)目開發(fā)。但是,隨著項(xiàng)目的不斷變大,mobx也不斷暴露出了它的缺點(diǎn),就是數(shù)據(jù)流太隨意,出了bug之后不好追溯數(shù)據(jù)的流向,這個(gè)缺點(diǎn)正好體現(xiàn)出了redux的優(yōu)點(diǎn)所在,所以針對(duì)于小項(xiàng)目來說,社區(qū)推薦使用mobx,對(duì)大項(xiàng)目推薦使用redux。


Q15 假如我一個(gè)組件有一個(gè)狀態(tài)count為1,然后我在componentDidMount()里面執(zhí)行執(zhí)行了兩次this.setState({count: ++this.state.count}),然后又執(zhí)行了兩次setTimeout(() => { this.setState({count: ++this.state.count}) }, 0),最后count為多少?為什么?


count為4,因?yàn)榈诙螆?zhí)行setState的時(shí)候,取不到第一次this.state.count++的結(jié)果,react在一輪生命周期結(jié)束后才會(huì)更新內(nèi)部的state,如果在一輪生命周期內(nèi)多次使用了setState,react內(nèi)部會(huì)有一個(gè)字段isBatchUpdate標(biāo)識(shí)本次更新為批量更新,然后在最后render的時(shí)候?qū)⑺衧etState的結(jié)果提交到state中,一次性進(jìn)行更新,并且把isBatchUpdate這個(gè)字段設(shè)置為false。

針對(duì)于兩次setTimeout,js引擎會(huì)把這兩個(gè)setState丟到事件隊(duì)列中,等待js空閑了去執(zhí)行,而我們的渲染函數(shù)render是同步執(zhí)行的(react16版本默認(rèn)沒有開啟異步渲染),所以等我們r(jià)ender執(zhí)行完全,也就是我們的state被同步完后,在取事件隊(duì)列里面的setState進(jìn)行執(zhí)行,setTimeout的第二個(gè)setState也是一樣的,所以最后結(jié)果是4。

備注:這個(gè)count的答案似乎有疑問,寫了個(gè)demo,答案并不是4,Demo地址 jsfiddle.net/yacan8/5gsp…


Q16 說一下你覺得你做過的最值得你說的吧

-

最后

這幾輪面試的面試官都非常和藹好交流,百度的五輪面試不知道過了沒有,只記得五面的面試官說,你稍等一下,我去問一下其他人對(duì)你還有什么其他要求,然后過了一會(huì)兒HR就喊我先回去了,叫我等HR面的消息,如果沒通過,也不會(huì)在聯(lián)系我了,已經(jīng)過了四天了,但愿后面有消息吧。然后有贊、螞蟻金服的兩個(gè)一面都過了,因?yàn)槊看蚊嫱暝嚸嬖嚬賳栁疫€有什么問題嗎?我都會(huì)詢問一下本次面試面試官對(duì)我的評(píng)論是啥。


有贊一面結(jié)束后過了兩天就收到了二面的邀請(qǐng),我回復(fù)面試邀請(qǐng)的短信,說最近可能請(qǐng)假太多,能不能約到晚上面試,對(duì)方很很爽快的答應(yīng)了,就約在了晚上七點(diǎn)半,我回復(fù)可以的,然后第二天,收到了確切的面試的時(shí)間和地點(diǎn),時(shí)間定在了晚上7點(diǎn)15分。


到了面試當(dāng)天,我提前了五分鐘下班,照著百度地圖的提示路線(約1小時(shí)9分鐘),到了公交站等車。。。然后等呀等,等了十五分鐘公交還沒來,怕自己遲到,就打了個(gè)滴滴過去,到了面試地點(diǎn)之后上到了公司的前臺(tái),前臺(tái)沒有人,可能是因?yàn)榈斤堻c(diǎn)了,前臺(tái)去吃飯了吧。然后看到前臺(tái)那層樓好多人在打乒乓球,大家也玩得挺開心,看起來環(huán)境也很不錯(cuò),當(dāng)時(shí)想,誒呀,原來有贊的環(huán)境這么好。等了一會(huì)兒之后,看了一下短信,發(fā)現(xiàn)面試邀請(qǐng)里留有面試官的聯(lián)系電話,果斷打了過去,過了一會(huì)兒面試官到前臺(tái)接我,然后找了一個(gè)會(huì)議室,開始了當(dāng)天的面試。



面試官:先自我介紹吧


我:巴拉巴拉...


面試官:先說一下你上一家公司的研發(fā)部署流程


我:巴拉巴拉...(其實(shí)這個(gè)是我絕活,每次都可以吹很久)


面試官:既然你們是文件覆蓋式發(fā)布,那你們的緩存是怎么刷新的


我:從公司的業(yè)務(wù)出發(fā),巴拉巴拉...(還沒說完)


面試官:那我現(xiàn)在就不談業(yè)務(wù),你說一下瀏覽器的緩存方案吧


我:哦,脫離業(yè)務(wù)呀,首先,瀏覽器有兩種緩存方案,一種是強(qiáng)緩存一種是協(xié)商緩存。


面試官:嗯,那怎么使用強(qiáng)緩存?


我:瀏覽器在第一次請(qǐng)求資源的時(shí)候,服務(wù)端響應(yīng)頭里可以設(shè)置expires字段,該字段表示該資源的緩存過期時(shí)間,第二次請(qǐng)求的時(shí)候,如果時(shí)間還在該緩存時(shí)間之內(nèi),則會(huì)直接使用緩存,否則重新加載資源,這個(gè)expires字段有個(gè)缺陷,就是它必須服務(wù)端和客戶端的時(shí)間嚴(yán)格同步才能生效,所以現(xiàn)在很多人不會(huì)使用改方案。另外一種方案是第一次請(qǐng)求資源的時(shí)候,服務(wù)端設(shè)置響應(yīng)頭cache-control: max-age,這樣設(shè)置的意思是告訴瀏覽器,這個(gè)資源什么時(shí)候過期,等第二次請(qǐng)求資源的時(shí)候,判斷是否超出了過期時(shí)間,如果沒超出,直接使用緩存。


面試官:cache-control這個(gè)頭是服務(wù)端設(shè)置的還是客戶端設(shè)置的?


我:cache-control服務(wù)端設(shè)置的


面試官:cache-control的其他值,你也說一下吧


我:首先是public,客戶端和服務(wù)端都可以緩存;然后是private,只能客戶端緩存;no-store,不使用緩存;no-cache,使用協(xié)商緩存。

面試官:那你往下說,說一下協(xié)商緩存


我:協(xié)商緩存有兩種,一種是Last-Modified,就是第一次請(qǐng)求資源的時(shí)候,服務(wù)端會(huì)在響應(yīng)頭里面設(shè)置該字段,表示該資源的最后修改時(shí)間,瀏覽器第二次請(qǐng)求該資源的時(shí)候,會(huì)在請(qǐng)求頭里面加上一個(gè)字段If-Modified-Since,值為第一次請(qǐng)求的時(shí)候服務(wù)端返回的Last-Modified的值,服務(wù)端會(huì)判斷資源當(dāng)時(shí)的最后更改時(shí)間與請(qǐng)求頭里面的If-Modified-Since字段是否相同,如果相同,則告訴客戶端使用緩存,否則重新下載資源。然后另外一種協(xié)商緩存時(shí)使用ETag,原理與Last-Modified類似,就是第一次請(qǐng)求的時(shí)候,服務(wù)端會(huì)根據(jù)資源的內(nèi)容或者最后修改時(shí)間生成一個(gè)標(biāo)識(shí),然后在響應(yīng)頭里面設(shè)置為ETag返回給客戶端,客戶端第二次請(qǐng)求的時(shí)候會(huì)在請(qǐng)求頭里面帶上這個(gè)ETag,也就是在請(qǐng)求頭里面加上If-None-Match字段,服務(wù)端接收到了ETag之后判斷是否與原來第一次的標(biāo)識(shí)相同,如果相同,則告訴客戶端使用緩存。


說一下Last-modified/If-Modified-Since和If-None-Match/ETag兩種方案的優(yōu)缺點(diǎn)


我:嗯呢,這個(gè)我想一想(我并不知道,假裝思考一下)......我覺得其實(shí)ETag其實(shí)也是有的時(shí)候是根據(jù)資源的最后修改時(shí)間生成的,原理和Last-modified好像有點(diǎn)類似,而ETag需要耗費(fèi)服務(wù)端的資源去生成,所以性能較低。。。(雖然不會(huì),也盡量說說,萬一面試官也不知道呢。哈哈哈哈)


面試官:那說一下性能優(yōu)化的方案吧


我:首先,減少HTTP請(qǐng)求次數(shù),比如說合并CSS和JS文件,但是也不要完全的合并在同一個(gè)文件里面,一個(gè)域名分散三四個(gè)資源,這樣方便瀏覽器去并行下載,當(dāng)然瀏覽器對(duì)每個(gè)域名的并行下載個(gè)數(shù)有限制,一個(gè)域名分配三四個(gè)資源雖然增加了HTTP請(qǐng)求數(shù)量,但是對(duì)比并行下載來說,性價(jià)比更高。


面試官:為什么瀏覽器要限制同一域名并行下載資源的個(gè)數(shù)。


我:嗯呢,這個(gè)我也想一下(其實(shí)我也不知道)......這個(gè)我沒有深究過,難道是因?yàn)闉g覽器啟動(dòng)了太多下載線程的原因?


面試官:下載資源和線程有什么關(guān)系?


我:除了了每個(gè)標(biāo)簽頁是一個(gè)進(jìn)程以外,瀏覽器有一個(gè)進(jìn)程是專門用來管理下載,我覺得大概是每下載一個(gè)資源啟動(dòng)一個(gè)線程吧(反正我也不知道,也猜猜結(jié)果是不是這樣)

面試官:(沉默了一會(huì)兒),進(jìn)程和線程區(qū)別是什么


我:進(jìn)程是分配內(nèi)存的最小單位,線程是CPU調(diào)度的最小單位,進(jìn)程可以包含多個(gè)線程。


面試官:nodejs用得多嗎?說一下nodejs進(jìn)程之間是怎么通信的


我:nodejs用的比較少,nodejs可以啟動(dòng)子線程,然后用主線程來監(jiān)聽訂閱子線程的消息,子線程之間的通信,由主線程來控制。(大概錯(cuò)了吧,應(yīng)該是進(jìn)程)

面試官:好吧,性能優(yōu)化繼續(xù)往下說

我:減少HTTP請(qǐng)求數(shù)量還可以把圖標(biāo)合并在同一張圖片里面,使用的時(shí)候用background-position去控制。然后首屏的時(shí)候圖片使用懶加載的形式,盡量在需要顯示的時(shí)候在加載它,當(dāng)然占位符和圖片盡量指定寬度和高度,避免圖片加載完之后替換圖片瀏覽器會(huì)進(jìn)行回流。


面試官:圖片懶加載怎么實(shí)現(xiàn)


我:監(jiān)聽瀏覽器的滾動(dòng)事件,結(jié)合clientHeight、offsetHeight、scrollTop、scrollHeight等等變量計(jì)算當(dāng)前圖片是否在可視區(qū)域,如果在,則替換src加載圖片,當(dāng)然這個(gè)滾動(dòng)事件要主要節(jié)流。


面試官:怎么判斷圖片是否加載完成


我:使用onload事件。

面試官:好吧,你繼續(xù)往下說。

我:性能優(yōu)化的話,還可以合理的利用緩存,盡量把CSS和JS文件使用外鏈的形式,雖然使用內(nèi)聯(lián)的CSS和JS在空緩存的時(shí)候更快,因?yàn)閮?nèi)聯(lián)的樣式和腳本不需要發(fā)送HTTP請(qǐng)求,但是為了盡量發(fā)揮瀏覽器的緩存功能,盡量使用外鏈形式。

我:然后盡量把CSS放在頭部,JS放在底部。


面試官:假如現(xiàn)在頁面里放在head的css文件下載速度很慢,頁面會(huì)出現(xiàn)什么情況?


我:大概頁面會(huì)等待這個(gè)CSS的下載,這個(gè)時(shí)候頁面是白屏狀態(tài),然后這個(gè)CSS資源會(huì)有一個(gè)超時(shí)時(shí)間,假如超過了這個(gè)超時(shí)時(shí)間,這個(gè)資源相當(dāng)于會(huì)下載失敗,瀏覽器會(huì)直接跳過這個(gè)CSS資源,根據(jù)已有的CSS資源生成CSS規(guī)則樹,進(jìn)而生成Render樹,然后渲染頁面。


面試官:假如我現(xiàn)在在頁面動(dòng)態(tài)添加了一個(gè)CSS文件,頁面一定會(huì)回流嗎?


我:只要加入的CSS影響到了頁面的結(jié)構(gòu),那么瀏覽器就會(huì)回流。


面試官:例如頁面這個(gè)CSS文件中有translate3d呢?


我:其實(shí)我感覺它不會(huì)回流,因?yàn)閠ranslate3d只是變換了自己的位置,不會(huì)影響其他元素的位置,但是實(shí)際上是會(huì)造成回流的。


面試官:那假如我在頁面里面加了一個(gè)<div style="position:absolute;width:0;hegiht:0"></div>呢,會(huì)回流嗎


我:不會(huì),因?yàn)闆]有影響頁面結(jié)構(gòu)的變化。

面試官:好吧,那你繼續(xù)往下說

我:性能優(yōu)化,盡量使用CDN。


面試官:CDN的原理是啥?


我:首先,瀏覽器會(huì)先請(qǐng)求CDN域名,CDN域名服務(wù)器會(huì)給瀏覽器返回指定域名的CNAME,瀏覽器在對(duì)這些CNAME進(jìn)行解析,得到CDN緩存服務(wù)器的IP地址,瀏覽器在去請(qǐng)求緩存服務(wù)器,CDN緩存服務(wù)器根據(jù)內(nèi)部專用的DNS解析得到實(shí)際IP,然后緩存服務(wù)器會(huì)向?qū)嶋HIP地址請(qǐng)求資源,緩存服務(wù)器得到資源后進(jìn)行本地保存和返回給瀏覽器客戶端。


面試官:你來實(shí)現(xiàn)以下剛剛說的節(jié)流函數(shù)吧

當(dāng)時(shí)有點(diǎn)不記得什么是防抖,什么節(jié)流,把函數(shù)寫成了防抖。(這個(gè)時(shí)候有一個(gè)人走進(jìn)了會(huì)議室,好像是一面小哥)


面試官:我這邊沒有什么問題了,你還有什么要補(bǔ)充的嗎?

我:那我把性能優(yōu)化這個(gè)問題說完?

面試官:可以。

然后我開始描述使用webpack使用進(jìn)行減少js文件的體積,可以使用babel-plugin-import、babel-plugin-component、webpack.ContextReplacementPlugin、webpack.IgnorePlugin...

面試官:這個(gè)我知道。你還有什么問題嗎?(大概是想結(jié)束面試了吧,不想讓我往下說了)

我:巴拉巴拉。。。問了很多關(guān)于有贊公司的問題,比如公司有多少層樓啊、公司主要技術(shù)棧啊、公司主要做2B還是2C的啊,公司有多少前端的啊(本人可能還是太啰嗦)

最后問了一個(gè)問題,問了一下面試官本次便是的評(píng)價(jià)是啥,面試官只回了一句,還好吧。然后面試到此結(jié)束了,全稱大概一個(gè)多小時(shí)。


面試結(jié)束后,面試官送我到電梯口。。。可以說樓層是真的高,上樓和下樓都需要等很久的電梯。。。到了外面之后,下著大雨,落湯雞似的又打了個(gè)滴滴回家,結(jié)束了當(dāng)天的面試之旅。

最后

直到昨天,收到了有贊的面試結(jié)果回復(fù)郵件,告知沒有合適的職位(有贊還是挺不錯(cuò)的,沒通過面試還通知一下),心里雖然有點(diǎn)不甘,但是想想確實(shí)可能是自己不夠優(yōu)秀,或者是自己面得不是很好,或者是自己的能力跟公司的職位不太匹配。

更多精彩文章

徹底明白JS線程

徹底明白js中的this

徹底明白閉包

超實(shí)用代碼片段

前端-掃碼登錄實(shí)現(xiàn)原理

關(guān)注公眾號(hào)【grain先森】,回復(fù)關(guān)鍵詞 【18福利】,獲取為你準(zhǔn)備的年終福利,更多關(guān)鍵詞玩法期待你的探索~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,527評(píng)論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,687評(píng)論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,640評(píng)論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,957評(píng)論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,682評(píng)論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 56,011評(píng)論 1 329
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,009評(píng)論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,183評(píng)論 0 290
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,714評(píng)論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,435評(píng)論 3 359
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,665評(píng)論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,148評(píng)論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,838評(píng)論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,251評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,588評(píng)論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,379評(píng)論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,627評(píng)論 2 380

推薦閱讀更多精彩內(nèi)容