<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          雙非本科的大廠面經(jīng)總結(jié),不是很卷!(新鮮出爐)

          共 6532字,需瀏覽 14分鐘

           ·

          2021-12-28 21:07

          大廠技術(shù)??高級前端??Node進階

          點擊上方?程序員成長指北,關(guān)注公眾號

          回復1,加入高級Node交流群

          作者:Uni (感謝小伙伴投稿)

          原文:https://fwf-studio.feishu.cn/docs/doccnqyJfOyD3Q5JPG2K0PfAPnf#

          個人背景介紹

          嗨咯大家好,我是 Uni。本人就讀于某雙非一本大學計算機系,大一的時候在疲于提升績點后,發(fā)現(xiàn)自己根本不知道計算機有哪些領(lǐng)域,能夠干啥。于是在互聯(lián)網(wǎng)上廣泛搜索計算機有哪些領(lǐng)域、需要學什么、能干什么后,確定了自己喜歡的領(lǐng)域:前端。在我看來前端就是美學與邏輯的完美結(jié)合,也是那個時候堅定了自己的座右銘:無論是技藝、構(gòu)圖、還是大膽的想法,達到極致,即為藝術(shù)。于是在大一下,我開始了我的前端自學之路。

          后來大二的時候跟志同道合的朋友們一起組建了一個技術(shù)組織,一起寫項目、學技術(shù),也是一段快樂時光了。

          在今年的3月份(2021年),考慮到家里和學業(yè)的緣故,在實習和字節(jié)跳動訓練營之間選擇了參加字節(jié)跳動的前端訓練營,并取得了不錯的名次。原本是要準備秋招的,但是暑假因為算法比賽和其他緣故又擱置了。

          因為一直很喜歡網(wǎng)易云音樂這個產(chǎn)品,從大三的時候就一直 follow 網(wǎng)易云音樂大前端團隊在掘金上的文章,并一直在關(guān)注著網(wǎng)易云音樂的崗位。然后很幸運地發(fā)現(xiàn)網(wǎng)易云音樂現(xiàn)在正在招實習生于是便投了。網(wǎng)易的效率很高,兩三天后就約面試了,所以最近有且僅面了網(wǎng)易。

          因為最近半年基本因為一些原因一直在打算法比賽和學機器學習相關(guān)的東西,一直沒怎么碰過 Web,所以在面試之初還是有些緊張的。

          技術(shù)一面

          面試官人很nice,一開始怕我緊張就一直讓我介紹自己的項目。一面主要是在深挖項目。

          介紹下在字節(jié)跳動訓練營的這個項目

          回答:這個項目是一個在線 markdown 編輯器,用的是 React 及其相關(guān)生態(tài)做的前端,Koa2 做的服務端,采用的MongoDB數(shù)據(jù)庫。有郵箱驗證、JWT鑒權(quán)、文件上傳并返回鏈接、將 markdown 語法編寫的文本轉(zhuǎn)換成 HTML、采用 websocket 做的在線錯誤日志等功能。

          為什么要做這個基于 websocket 的在線錯誤日志?主要是怎么實現(xiàn)的?

          回答:做這個功能的原因主要是當時為了練技術(shù),并沒有從整個產(chǎn)品的角度去考慮這一塊功能,僅僅是為了實現(xiàn)而實現(xiàn)。在實現(xiàn)上,首先我后端的所有響應類型都是基于 SuccessModelErrorModel 這兩個類產(chǎn)生的,這樣能夠保證我的響應格式的統(tǒng)一(都是 msgdatacode

          然后通過 Node 中 fs 模塊的 appendFile 方法將錯誤信息傳入 errorLog.txt 這個文件,如果沒有這個文件是會自動生成的。

          然后在管理員打開錯誤日志的前端頁面的時候會建立 websocket 連接,并將 errorLog.txt 文件中的記錄當作歷史日志傳給前端并倒序渲染出來。這個時候同時調(diào)用 fs.watch 方法對 errorLog.txt 文件的變化進行監(jiān)聽,如果有錯誤日志寫入文件中,那么文件就變化了,就會通過 websocket 將新增的錯誤日志記錄主動廣播給前端,以此達到管理員在日志界面時可以看到實時的錯誤信息的效果。

          PS:做這個功能的目的是為做而做,并沒有考慮那么多,也沒有過這種場景的經(jīng)驗,所以做的很不規(guī)范。只是為了嘗試、鍛煉一下。

          面試官:我看到你簡歷上有一個在線聊天室的項目,用到了 socket.io 來做實時通訊這一塊,而你訓練營的項目用的是 ws 這個 npm 庫,能說說為什么用 socket.io 嗎以及 socket.io 和 ws 之間的對比。

          回答:用 socket.io 主要原因還是為了嘗試新的東西,其實這兩個我都沒有鉆的很深,只是為了需求去實現(xiàn)。

          我所了解到的是,相比于 ws,socket.io 在客戶端有良好的支持,但是 ws 沒有,在客戶端寫的時候還需要自己去封裝。其次就是 socket.io 是有回退方案的,在不支持 websocket 的時候會回退到 HTTP 長輪訓的方案。(這一塊答的不怎么好,因為確實對這兩個庫使用的不多,理解的不深)

          能說說你項目中圖片上傳那一塊是怎么實現(xiàn)的嗎?

          回答:在項目的一開始,我是采用 base64 的方式實現(xiàn)的圖片上傳,但是這樣的話每次請求都會傳一個超長的字符串,這樣會占據(jù)更多的空間資源。所以后來我換成了文件流的形式上傳。前端通過事件對象和 FormData 的配合,將數(shù)據(jù)傳給后端。

          然后后端我引用了 formidable-upload-koafs-extra 這兩個庫,將傳過來的文件格式進行解析并移動到一個暴露在外的可訪問目錄下,最后再將文件路徑存于數(shù)據(jù)庫中并返回路徑給前端,前端每次獲取圖片只需要請求暴露在外的路徑即可,就相當于是做了一個簡陋的圖床。

          (反思:面試官問完我這個問題后,我雖然說出了自己實現(xiàn)的思路以及為什么用這個方案的原因,但是卻沒有實打?qū)嵉匮芯窟^這兩個方案到底適合什么場景,也沒有仔細思考過到底是不是很項目,只是為了用技術(shù)而用。通過前面幾個問題發(fā)現(xiàn)了自己思維上的大短板,就是很少思考項目本身需要什么技術(shù),用什么技術(shù)合適。)

          如果有海量請求來了,你在項目中是如何處理這些高并發(fā)請求的呢?

          回答:因為我沒有實際遇到過這種場景所以我也沒有具體了解過相關(guān)的解決方案。但是 I/O 密集型是 Node的強項,我后端所有的 I/O 處理都是采用異步的方式。然后前端也會對一些操作做防抖節(jié)流,來防止一些無效或者重復的請求。

          你剛剛說到了防抖節(jié)流,能講講他們之間的區(qū)別嗎?

          回答:防抖在單位時間內(nèi)觸發(fā)的事件會被重置,防止誤觸多次事件。節(jié)流就是單位時間內(nèi)只觸發(fā)一次。(回答完我摸了摸鍵盤準備等著面試官讓我手寫防抖節(jié)流,但是他沒有繼續(xù)往下問了)

          你項目都是 React 是吧?(是的,我 hook 寫的比較多)那你介紹一下你常用的 hook 吧

          說了幾個常用的 hook,然后重點講了一下 useEffectuseLayoutEffect 的區(qū)別,通過他們渲染時機的區(qū)別講了講項目中遇到過的頁面閃爍的問題并怎么解決的。

          那你來手寫實現(xiàn)一下這道題吧

          class?Event?{
          ????//?觸發(fā)事件
          ????trigger(eventName)?{}
          ????//?注冊事件
          ????on(eventName,?callback)?{}
          ????//?銷毀事件
          ????off(eventName)?{}
          }

          //?case
          const?event?=?new?Event()
          event.on("eventA",?(a)?=>?{
          ????console.log(a)
          })
          event.on("eventA",?(a,?b)?=>?{
          ????console.log(a)
          ????console.log(b)
          })
          event.trigger("eventA",?1,?2)???//?print:?1?1?2

          我的實現(xiàn):

          class?Event?{
          ????constructor()?{
          ????????this.map?=?new?Map()
          ????}

          ????//?注冊事件
          ????on(eventName,?callback)?{
          ????????!this.map.has(eventName)?&&?this.map.set(eventName,?[])
          ????????const?arr?=?this.map.get(eventName)
          ????????arr.push(callback)
          ????????this.map.set(eventName,?arr)
          ????}
          ????//?觸發(fā)事件
          ????trigger(eventName,?...args)?{
          ????????const?arr?=?this.map.get(eventName)
          ????????arr.forEach(item?=>?{
          ????????????item(...args)
          ????????})
          ????}
          ????//?銷毀事件
          ????off(eventName)?{
          ????????this.map.delete(eventName)
          ????}
          }

          追問:如果這個 off 方法加一個 callback 參數(shù),我想要每次注銷的事件是這一組同名事件中的具體的某一個呢?

          回答:如果這個 callback 是外部作用域有引用的,然后傳入?yún)?shù)的話,那直接 forEach 判斷一下是否相等然后直接對數(shù)組使用 splice方法刪除即可,因為都是同一個引用嘛。如果是這種場景的話我這里就可能用 WeakMap 會比 Map好些,這樣可以防止內(nèi)存泄漏的情況發(fā)生

          技術(shù)二面

          面試官人也很nice,我運氣真的太好了,遇到的都是彬彬有禮、很是溫和的面試官。首先還是上來跟面試官介紹了一下項目,這里就簡單跳過。

          你對跨域的方案有了解嗎?你的項目里是怎么實現(xiàn)跨域的?

          我了解到的跨域方案有 jsonpCORSpostMessgae 以及 Websocket。在我的項目中用的是 CORS 跨域的方案。

          你剛剛說到CORS 跨域,哪請問 options 是在什么情況下觸發(fā)的呢?

          回答:不會(這個真沒了解到) 下來后立馬百度了解了相關(guān)知識:瀏覽器會對于非簡單請求會觸發(fā)一次預檢的請求,對應的 HTTP Request Method 為 OPTIONS。這個請求對服務器是安全的,也就是說不會對服務器的資源做任何改變,僅僅用于確認 header 響應。具體的歡迎參考這篇文章進行了解: https://zhuanlan.zhihu.com/p/70032617

          讓我手寫 JS 的繼承方式

          先問:你平時都看什么技術(shù)書

          • 答:紅寶書和《你不知道的JS》

          再問:那你能講講這些書里面讓你印象深刻的知識點嗎

          • 我說了說繼承、原型鏈、JS執(zhí)行機制等

          繼續(xù)問:那你說說有什么繼承方式吧(其實我很想讓面試官問我JS整個執(zhí)行機制和詞法作用域具體機制來著,整個當時深鉆了很長時間)

          回答(讓我手寫 JS 的繼承方式,我寫了三種):

          //?1.借助原型鏈
          function?Parent()?{
          ????this.name?=?"Uni"
          }

          function?Child()?{}

          Child.prototype?=?new?Parent()
          Child.prototype.constructor?=?Child

          //?2.借助?call?方法
          function?Parent()?{
          ????this.name?=?"Uni"
          }

          function?Child()?{
          ????Parent.call(this)
          ????this.age?=?21
          }

          const?child?=?new?Child()

          //?3.寄生組合式繼承
          function?clone?(parent,?child)?{
          ????child.prototype?=?Object.create(parent.prototype)
          ????child.prototype.constructor?=?child
          }

          function?Parent()?{
          ????this.name?=?"Uni"
          }??

          function?Child()?{
          ????Parent.call(this)
          ????this.age?=?21
          }

          clone(Parent,?Child)

          面試的時候其實我是邊寫邊跟面試官說每種寫法的優(yōu)缺點和為什么用這種寫法,所以自然而然地按照這個順序?qū)懴聛砹耍怯捎谟行┚o張加上邊寫邊說,所以有些磕磕絆絆,但是總的還是回答完了這個問題。

          如果有一個模態(tài)框,想要點擊模態(tài)框以外的區(qū)域讓模態(tài)框消失,應該怎么做?

          回答:我從事件冒泡和事件捕獲兩種方式進行了回答。冒泡的方式很好地答了出來,但是面試官一直在不斷追問我一些情形,然后我腦子卡殼了捕獲就沒有答的很好。因為是面經(jīng)具體答案就不闡述了,這個問題手動寫寫試一下就知道答案了。

          CSS優(yōu)先級順序能說說嗎?

          回答:當時因為還在糾結(jié)前面捕獲的事情,腦子一團混亂,就迷迷糊糊答得很差。面完后重新看了下這塊的內(nèi)容,具體可以參考這兩篇文章:

          1、https://zhuanlan.zhihu.com/p/41604775
          2、https://zhuanlan.zhihu.com/p/23047507

          有讀過什么框架和庫的源碼嗎(我其實研究過一段時間的 React 和 JQuery,但是因為最近半年一直在打算法和研究機器學習方面的內(nèi)容,前端很多東西都忘了,就求穩(wěn)說了一個 JQuery),請講講JQuery 源碼方面的內(nèi)容。

          • 回答:我講了講 JQuery 的大致機制和外部的自執(zhí)行匿名函數(shù)。

          追問:JQuery 是如何做到鏈式調(diào)用的

          • 回答:返回 this(如下是示例,面試的時候并沒有寫代碼只是口頭講解)
          const?MyJQ?=?function(){}
          MyJQ.prototype?=?{
          ????css:function(){
          ???????console.log("設(shè)置css樣式");
          ????????return?this;
          ????},
          ???show:function(){
          ????????console.log("將元素顯示");
          ???????return?this;
          ????},
          ???hide:function(){
          ????????console.log("將元素隱藏");
          ???}
          };
          const?myjq?=?new?MyJQ();
          myjq.css().css().show().hide();

          寫一道算法題(有效括號,LeetCode 20)

          就用一個輔助棧就好了,感興趣的朋友可以去刷一下

          反思與總結(jié)

          其實說實話,面經(jīng)中寫面試題很難說起到一個參考或者幫助作用,因為面試題是不固定的、面試官是不確定的、面試難度和應聘者實力也是不一定匹配的。這就像考試一樣,有些人拿一百分是因為卷子滿分就一百分。

          但是面試和考試不一樣的地方在于,面試是你與面試官交流的媒介,是要體現(xiàn)個人綜合實力的地方,也是一個學習的渠道。所以我認為面經(jīng)最重要的地方其實在于面試者下來的反思和思考。

          我的反思

          通過這次面試,其實我最大的感觸是對業(yè)務上思考太少,我很少會去從產(chǎn)品功能的角度去思考我的技術(shù)。這會導致我的技術(shù)方案或者做法缺少業(yè)務價值。比如在做在線 markdown 編輯器的時候我的關(guān)注點只在于我怎么做出來這個語法轉(zhuǎn)譯的功能,但卻沒有思考如果從用戶角度想要定制我的一些 markdown 語法轉(zhuǎn)譯后的樣式我該怎么去做,所以我的整個功能可擴展性就非常地低。因為缺少業(yè)務上的思考,所以我開發(fā)的時候會更難想到一些更隱性的場景,比如性能優(yōu)化、功能的可擴展性和完備性。這是我需要再多刻意練習的。

          關(guān)于面試的建議

          首先,我覺得應該抱著學習的心態(tài)多面試,不論是找實習的同學還是找校招的同學。面試就是一個從面試官那取經(jīng)、發(fā)現(xiàn)不足的地方。所以一定一定不要緊張,要放開手腳來。在面試的過程中可以多跟面試官交流,可以根據(jù)某道題聊聊你的思考,也可以在反問環(huán)節(jié)向面試官請教自身的不足,也可以帶著面試官一起剖析反思自己。我面試的時候就是抱著這樣的心態(tài)去跟面試官交流,最后也都跟面試官們聊開了,也得到了許多寶貴的建議。真就是面到就是賺到!最后,不得不說整個流程下來,我的體驗是非常好的,HR推進流程的效率非常高,面試官也都很好溝通愿意引導我給我一些建議。

          Node 社群


          我組建了一個氛圍特別好的 Node.js 社群,里面有很多 Node.js小伙伴,如果你對Node.js學習感興趣的話(后續(xù)有計劃也可以),我們可以一起進行Node.js相關(guān)的交流、學習、共建。下方加 考拉 好友回復「Node」即可。


          ???“分享、點贊在看” 支持一波??

          瀏覽 62
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  久操新在线 | 怡红院一区二区 | 亚洲视频91 | 青青草国产 | 欧美日韩性爱一区二区三区 |