<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>

          15 個(gè)常見(jiàn)的 Node.js 面試問(wèn)題及答案

          共 4952字,需瀏覽 10分鐘

           ·

          2021-02-22 09:02

          作者 | Juan Cruz Martinez
          譯者 | 吳留坡
          策劃 | 田曉旭

          臨陣磨槍,不快也光。對(duì)于成功的編程面試來(lái)說(shuō),準(zhǔn)備和知識(shí)面一樣重要。準(zhǔn)備使你有信心參加面試,而不用擔(dān)心莫名的緊張情緒。如果第一次參加編程面試,這一點(diǎn)尤其重要。

          為幫助 Node.js 開(kāi)發(fā)人員更好的面試,我列出了 15 個(gè)常見(jiàn)的 Node.js 和網(wǎng)絡(luò)開(kāi)發(fā)相關(guān)的面試問(wèn)題。

          在本文中,我們將重點(diǎn)討論 Node.js 相關(guān)問(wèn)題。但是,請(qǐng)記住 JavaScript 問(wèn)題在 Node.js 面試中也經(jīng)常問(wèn)到,所以準(zhǔn)備一些對(duì)你來(lái)說(shuō)沒(méi)什么壞處。不久前我們寫了一篇關(guān)于常見(jiàn) JavaScript 面試問(wèn)題的帖子,涵蓋了所有這些基礎(chǔ)。

          https://livecodestream.dev/post/20-common-javascript-interview-questions/

          現(xiàn)在,讓我們深入了解面試中可能會(huì)問(wèn)到的 Node.js 問(wèn)題。

          1. Node.js 與 JavaScript 有什么不同?

          2. 什么時(shí)候用 Node.js?

          Node.js 是異步的、事件驅(qū)動(dòng)的、非阻塞的和單線程的,使得它成為開(kāi)發(fā)下面應(yīng)用程序的完美候選:

          • 實(shí)時(shí)應(yīng)用程序,如聊天和提供實(shí)時(shí)更新的應(yīng)用程序

          • 將視頻或其他多媒體內(nèi)容流式傳輸給大量觀眾的流式應(yīng)用程序

          • 其他 I/O 密集型應(yīng)用程序,如協(xié)作平臺(tái)

          • 遵循微服務(wù)架構(gòu)的網(wǎng)絡(luò)后端

          然而,Node.js 的特性使得它對(duì)于其他類型的應(yīng)用程序來(lái)說(shuō)不是一個(gè)理想的選擇。執(zhí)行 CPU 密集型任務(wù)的應(yīng)用程序(如復(fù)雜的數(shù)學(xué)計(jì)算)在使用 CPU 時(shí)表現(xiàn)不佳,因?yàn)?Node.js 是單線程的。

          如果你想了解更多這方面的信息,請(qǐng)查看我們的文章 Node.js 架構(gòu)以及何時(shí)在項(xiàng)目中使用。

          3. EventEmitter 做了什么?

          Node.js 中任何對(duì)象發(fā)出的事件都是 EventEmitter 類的實(shí)例,就像 http 模塊。

          所有 EventEmitter 類都可以使用 eventEmitter.on() 函數(shù)將事件偵聽(tīng)器附加到事件。然后一旦捕捉到這樣的事件,就會(huì)同步地逐個(gè)調(diào)用它的偵聽(tīng)器。
          const?events = require("events");
          const?eventEmitter = new?events.EventEmitter();
          const?eventListener = function(){
          ??console.log("event triggered");
          }
          eventEmitter.on("emitted", eventListener);
          eventEmitter.emit("emitted");
          4. 事件循環(huán)是什么?

          單線程的 Node.js 必須是非阻塞的,以防止線程阻塞在需要很長(zhǎng)時(shí)間才能完成的任務(wù)上,事件循環(huán)負(fù)責(zé)實(shí)現(xiàn)這種非阻塞行為,它使用應(yīng)用程序線程調(diào)度掛起的任務(wù)。

          Node.js 在任務(wù)完成時(shí)通過(guò)回調(diào)來(lái)處理異步函數(shù)返回的響應(yīng)。與創(chuàng)建任務(wù)的事件類似,任務(wù)完成后也會(huì)發(fā)出一個(gè)事件。Node.js 將需要處理的事件添加到事件隊(duì)列。

          事件循環(huán)對(duì)事件隊(duì)列中的事件進(jìn)行迭代,并安排何時(shí)執(zhí)行其關(guān)聯(lián)的回調(diào)函數(shù)。

          5. 流是什么?

          Stream 流是從源讀取或?qū)懭霐?shù)據(jù)并將其傳輸?shù)竭B續(xù)流目標(biāo)的管道。有四種類型:

          • 可讀

          • 可寫的

          • 可讀寫

          • 先寫入,再讀出來(lái)

          每個(gè)流也是一個(gè) EventEmitter。這意味著流對(duì)象可以在流上沒(méi)有數(shù)據(jù)、流上有可用數(shù)據(jù)或流中的數(shù)據(jù)在程序刷新時(shí)發(fā)出事件。
          const fs = require("fs");
          const readableStream = fs.createReadStream("test.txt");
          let content = "";
          readableStream.on("data", (chunk)?=>?{
          ??content += chunk;
          });
          readableStream.on("end", ()?=>?{
          ??console.log(content);
          });
          6. readFile 和 createReadStream 函數(shù)有什么區(qū)別?

          readFile 函數(shù)異步讀取文件的全部?jī)?nèi)容,并存儲(chǔ)在內(nèi)存中,然后再傳遞給用戶。

          createReadStream 使用一個(gè)可讀的流,逐塊讀取文件,而不是全部存儲(chǔ)在內(nèi)存中。

          與 readFile 相比,createReadStream 使用更少的內(nèi)存和更快的速度來(lái)優(yōu)化文件讀取操作。如果文件相當(dāng)大,用戶不必等待很長(zhǎng)時(shí)間直到讀取整個(gè)內(nèi)容,因?yàn)樽x取時(shí)會(huì)先向用戶發(fā)送小塊內(nèi)容。
          const fs = require("fs");
          fs.readFile("test.txt", (err, content)?=>?{
          ??console.log(content);
          });
          7. 如何處理 Node.js 中未捕獲的異常?
          我們可以在進(jìn)程級(jí)別捕獲應(yīng)用程序中未捕獲的異常。為此將偵聽(tīng)器附加到 process 全局對(duì)象:
          process.on("uncaughtException", (err)?=>?{
          ??console.log("exception caught: ", err);
          });
          8. Node.js 能否充分利用多核處理器?

          (默認(rèn)的)Node.js 應(yīng)用程序總是單線程的,即使在多核處理器上運(yùn)行,應(yīng)用程序也能只使用一個(gè)處理器。

          但是 Node.js 的核心模塊之一 Cluster 支持 Node.js 應(yīng)用程序開(kāi)啟多核,允許我們創(chuàng)建多個(gè)工作進(jìn)程,這些進(jìn)程可以在多個(gè)內(nèi)核上并行運(yùn)行,并共享一個(gè)端口來(lái)偵聽(tīng)事件。

          每個(gè)進(jìn)程使用 IPC 與主線程通信,并根據(jù)需要將服務(wù)器句柄傳遞給其他進(jìn)程。主進(jìn)程可以偵聽(tīng)端口本身并以循環(huán)方式將每個(gè)新連接傳遞給子進(jìn)程,也可以將端口分配給子進(jìn)程以便子進(jìn)程偵聽(tīng)請(qǐng)求。

          9. 反應(yīng)堆設(shè)計(jì)模式是什么?

          反應(yīng)堆設(shè)計(jì)模式是,Node.js 將回調(diào)函數(shù)(處理程序)附加到每個(gè) I/O 操作,然后創(chuàng)建請(qǐng)求時(shí)將處理程序提交給解復(fù)用器。

          解復(fù)用器收集應(yīng)用程序中發(fā)出的每個(gè) I/O 請(qǐng)求,并將它們作為隊(duì)列中的事件進(jìn)行排隊(duì)。這個(gè)隊(duì)列就是我們所說(shuō)的事件隊(duì)列。將事件排隊(duì)后,解復(fù)用器返回應(yīng)用程序線程的控制。

          同時(shí),事件循環(huán)遍歷事件隊(duì)列中的每個(gè)事件,并調(diào)用附加的回調(diào)來(lái)處理事件響應(yīng)。

          這就是 Node.js 中所使用的反應(yīng)堆模式。

          10. 單線程與多線程網(wǎng)絡(luò)后端相比有哪些好處?

          盡管 Node.js 是單線程的,但是大多數(shù)用于后端開(kāi)發(fā)的編程語(yǔ)言都提供多線程來(lái)處理應(yīng)用程序操作。

          為什么單線程有利于后端開(kāi)發(fā)?

          • 開(kāi)發(fā)人員更容易實(shí)現(xiàn)應(yīng)用程序。我們的應(yīng)用程序在生產(chǎn)過(guò)程中不會(huì)突然遇到意外的競(jìng)爭(zhēng)條件。

          • 單線程應(yīng)用程序易于擴(kuò)展。

          • 它們可以毫不延遲地在一個(gè)時(shí)刻收到的大量用戶請(qǐng)求提供服務(wù)。相比之下,當(dāng)流量較大時(shí),多線程后端必須等待線程池中的線程釋放,才能為用戶請(qǐng)求提供服務(wù)。利用 Node.js 的非阻塞特性,用戶請(qǐng)求不會(huì)在單個(gè)線程上掛起太長(zhǎng)時(shí)間(只有在操作不是 CPU 密集型時(shí))。

          11. REPL 是什么?

          REPL 代表 Read Eval Print Loop,是一個(gè)虛擬環(huán)境,可以在其中輕松地運(yùn)行編程語(yǔ)言。Node.js 帶有一個(gè)內(nèi)置的 REPL 來(lái)運(yùn)行 JavaScript 代碼,類似于我們?cè)跒g覽器中用來(lái)運(yùn)行 JavaScript 代碼的控制臺(tái)。

          要啟動(dòng) Node.js REPL,只需在命令行上運(yùn)行 node,然后寫一行 JavaScript 代碼,就可以在下一行看到它的輸出。

          12. process.nextTick 和 setImmediate 有什么區(qū)別?

          傳遞給 setImmediate 函數(shù)的回調(diào)將在事件隊(duì)列上的下一次迭代中執(zhí)行。

          另一方面,回調(diào)傳遞給 process.nextTick 在下一次迭代之前以及程序中當(dāng)前運(yùn)行的操作完成之后執(zhí)行。在應(yīng)用程序啟動(dòng)時(shí),開(kāi)始遍歷事件隊(duì)列之前調(diào)用它的回調(diào)。

          因此,回調(diào) process.nextTick 總是在 setImmediate 之前調(diào)用。

          下面代碼段:
          setImmediate(()?=>?{
          ??console.log("first");
          })
          process.nextTick(()?=>?{
          ??console.log("second");
          })
          console.log("third");
          將按順序輸出:
          third
          second
          first
          13. stub 是什么?

          測(cè)試應(yīng)用程序時(shí)使用 stub,模擬給定組件或模塊的行為,你可以將精力集中在要測(cè)試的代碼部分。通過(guò)使用 stub 代替與測(cè)試無(wú)關(guān)的組件,不必?fù)?dān)心外部組件會(huì)影響結(jié)果。

          例如,如果正在測(cè)試的組件在預(yù)期測(cè)試的部分之前有一個(gè)文件讀取操作,則可以使用 stub 來(lái)模擬該行為并返回模擬內(nèi)容,而不用實(shí)際讀取文件。

          在 Node.js 中,我們使用像 Sinon 這樣的庫(kù)來(lái)實(shí)現(xiàn)(譯者注,Sinon 在測(cè)試中替換某部分代碼,減少測(cè)試項(xiàng)編寫的復(fù)雜度 https://sinonjs.org)。

          14. 為什么在 express 中分離“應(yīng)用程序”和“服務(wù)器”是一種好的做法?

          通過(guò)在 Express 中分離應(yīng)用程序和服務(wù)器,可以將 API 實(shí)現(xiàn)與網(wǎng)絡(luò)相關(guān)配置分開(kāi)。在不執(zhí)行網(wǎng)絡(luò)調(diào)用的情況下執(zhí)行 API 測(cè)試,保證了更快的測(cè)試執(zhí)行和更好的代碼覆蓋度量。

          要實(shí)現(xiàn)這種分離,應(yīng)該在單獨(dú)的文件中聲明 API 和 server,對(duì)應(yīng) app.js 和 server.js:
          // app.js
          const?express = require("express");
          const?app = express();
          app.use("/", index);
          app.use("/contact", contact);
          app.use("/user", user);
          module.exports = app;
          // server.js
          const?http = require("http");
          const?app = require("/app");
          app.set('port', process.env.PORT);
          const?http = http.createServer(app);
          15. 什么是 yarn 和 npm?為什么要用 yarn 代替 npm 呢?

          npm 是與 Node.js 自帶的默認(rèn)包管理器,它有一個(gè)大型的公共庫(kù)和私有庫(kù),存儲(chǔ)在 npm registry 的數(shù)據(jù)庫(kù)中(譯者注,官方默認(rèn)中心庫(kù) http://registry.npmjs.org/,國(guó)內(nèi)淘寶鏡像 http://registry.npm.taobao.org/),用戶可以通過(guò) npm 命令行訪問(wèn)該數(shù)據(jù)庫(kù)。在 npm 的幫助下,用戶可以輕松管理項(xiàng)目中的依賴項(xiàng)。

          yarn 也是一個(gè)包管理器,為了解決 npm 的一些缺點(diǎn)。yarn 依賴 npm 注冊(cè)中心為用戶提供對(duì)包訪問(wèn)。yarn 底層結(jié)構(gòu)基于 npm,如果從 npm 遷移到 yarn,項(xiàng)目結(jié)構(gòu)和工作流不需要大改。

          就像之前提到的,在某些情況下,yarn 提供了比 npm 更好的功能。與 npm 不同的是,它會(huì)緩存下載的每個(gè)包,不必重新下載。

          通過(guò)校驗(yàn)和驗(yàn)證包的完整性來(lái)提供更好的安全性,保證在某個(gè)系統(tǒng)上運(yùn)行的包在任何其他系統(tǒng)中的工作方式完全相同,這就是為什么選擇 yarn 而不是 npm 來(lái)進(jìn)行包管理。

          ? ? 結(jié)論? ??

          在本文中,討論了 15 個(gè)最常見(jiàn)的 Node.js 面試問(wèn)題,幫助你為下一次面試做準(zhǔn)備。知道你可能被問(wèn)到的問(wèn)題和答案,面試就不再緊張了。

          祝你好運(yùn),面試成功!

          ??愛(ài)心三連擊

          1.看到這里了就點(diǎn)個(gè)在看支持下吧,你的點(diǎn)贊,在看是我創(chuàng)作的動(dòng)力。

          2.關(guān)注公眾號(hào)程序員成長(zhǎng)指北,回復(fù)「1」加入高級(jí)前端交流群!「在這里有好多 前端?開(kāi)發(fā)者,會(huì)討論?前端 Node 知識(shí),互相學(xué)習(xí)」!

          3.也可添加微信【ikoala520】,一起成長(zhǎng)。

          “在看轉(zhuǎn)發(fā)”是最大的支持

          瀏覽 71
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <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>
                  青青草在线视频免费在线观看 | 港台靓女性啪啪天美传媒精品性88xo | 欧美激情精品久久久久久变态 | 三级片在线视频观看 | 日韩欧美在线国产在线 |