15个常见的NodeJS面试问题合集(面试可能遇到的)

对于成功的编程面试,准备工作与你的知识一样重要。它会让你有信心参加面试,而不必担心不确定性。如果你一生中第一次面临编程面试,则尤其如此。
NodeJS常见面试问题有哪些?为了帮助 Node.js 开发人员为面试做好必要的准备,我汇总了 15 个常见的 Node.js 和 Web 开发相关面试问题的列表。这些问题和他们的回答也会促使你在大面试之前复习任何你觉得需要改进的地方。
在这个NodeJS面试问题合集中,我们只关注与 Node.js 相关的问题;但是,请记住,与 JavaScript 相关的问题在 Node.js 面试中非常常见,因此你也可以准备其中的一些问题。不久前,我们写了一篇关于常见 Javascript 面试问题的帖子, 以涵盖你的所有基础。
现在,让我们深入了解你在下一次面试中可能会遇到的与 Node 相关的问题。
Node.js 与 Javascript 有何不同?

JavascriptNode.js
Javascript 是一种编程语言,可以在任何具有合适浏览器引擎的 Web 浏览器中运行。Node.js 是为 Javascript 设计的解释器和运行时环境。Node.js 带有一些内置模块,可以增强 Javascript 编程的功能。
在 Node.js 之外,Javascript 用于 Web 应用程序的客户端,特别是用于开发动态功能。Node.js 可以在任何操作系统上使用来开发与系统硬件交互的应用程序,特别是对于 Web 后端。
Javascript 可以在不同的浏览器引擎上运行,例如 V8 (Google Chrome)、Spider Monkey (Firefox) 和 Javascript Core (Safari)。Node.js 只运行在 Chrome 使用的 V8 引擎上。
什么时候应该和不应该使用 Node.js?NodeJS面试问题解析:Node.js 是异步的、事件驱动的、非阻塞的和单线程的。它使 Node 成为开发以下类型应用程序的完美候选者:
  • 实时应用程序,如聊天和实时更新提供应用程序。
  • 将视频或其他多媒体内容流式传输给大量观众的流式应用程序。
  • 其他 I/O 密集型应用程序,如协作平台。
  • 遵循微服务架构的 Web 后端。
【15个常见的NodeJS面试问题合集(面试可能遇到的)】但是,Node.js 的独特品质使其不是某些其他类型应用程序的理想选择。执行 CPU 密集型任务(如复杂的数学计算)的应用程序不适合使用 Node.js,因为它是单线程执行的。
如果你想了解更多关于这一点,看看我们的文章Node.js的架构以及何时在项目中使用Node.js的  。
EventEmitter 是做什么的?NodeJS常见面试问题有哪些?Node.js 中能够发出事件的每个对象都是EventEmitter该类的成员。http模块就是一个这样的例子。
所有EventEmitter类都可以使用该eventEmitter.on()函数将事件侦听器附加到事件。然后,一旦捕获到这样的事件,它的侦听器就会被一个一个同步调用。
const events = require("events"); const eventEmitter = new events.EventEmitter(); const eventListener = function(){ console.log("event triggered"); }eventEmitter.on("emitted", eventListener); eventEmitter.emit("emitted");

Node 的事件循环是什么?NodeJS面试问题合集:由于 Node.js 是单线程的,它必须是非阻塞的,以防止线程在需要很长时间才能完成的任务上花费太长时间。事件循环负责实现这种非阻塞行为。
它的工作是使用应用程序线程调度挂起的任务。
我们知道,Node 使用回调来处理异步函数在其任务完成时返回的响应。与创建任务的事件类似,任务的完成也会发出一个事件。Node.js 将这些需要处理的事件添加到事件队列中。
事件循环遍历事件队列中的事件并安排何时执行其关联的回调函数。
什么是节点流?流是从源读取或写入数据并将其传输到连续流目的地的管道。有四种类型的流:
  • 可读
  • 可写
  • 双工(可读可写)
  • Transform(一种双工流。它的输出是使用输入计算的)
每个流也是一个EventEmitter.  这意味着流对象可以在流上没有数据、流上有数据或从程序中刷新流中的数据时发出事件。
const fs = require("fs"); const readableStream = fs.createReadStream("test.txt"); let content = ""; readableStream.on("data", (chunk) => { content += chunk; }); readableStream.on("end", () => { console.log(content); });

readFile 和 createReadStream 函数之间有什么区别?NodeJS常见面试问题有哪些?readFile 函数异步读取文件的全部内容并将其存储在内存中,然后再将其传递给用户。
createReadStream  使用可读流,该流将逐块读取文件,而不将其全部存储到内存中。
createReadStreamreadFile使用更少的内存并使其更快相比,优化了文件读取操作。如果文件相当大,用户不必等待很长时间,直到它的全部内容都可用,因为在读取时会向用户发送小块。
const fs = require("fs"); fs.readFile("test.txt", (err, content) => { console.log( content); });

你如何处理 Node.js 中未捕获的异常?我们可以在其进程级别捕获应用程序中抛出的未捕获异常。我们将侦听器附加到process全局对象以捕获此类事件。
process.on("uncaughtException", (err) => { console.log("exception caught: ", err); });

Node 能否充分利用多处理器系统?节点应用程序始终是单线程的。因此,即使在多处理器系统上运行时,应用程序自然也仅使用单个处理器。
但是 Node 的核心模块之一,Cluster,为 Node 应用程序提供了利用多核的支持。它允许我们创建多个工作进程,这些进程可以在多个内核上并行运行并共享一个端口来侦听事件。
在这里,每个进程都使用 IPC 与主线程通信,并根据需要将服务器句柄传递给其他进程。主进程可以监听端口本身并以循环顺序将每个新连接传递给子进程,或者将端口分配给子进程以便子进程监听请求。
Node.js 中使用的反应器设计模式是什么?NodeJS面试问题解析:反应器模式用于在 Node.js 中维护非阻塞 I/O 操作。它将回调函数(处理程序)附加到每个 I/O 操作。然后在创建请求时将处理程序提交给解复用器。
多路分解器收集应用程序中发出的每个 I/O 请求,并将它们作为事件排入队列。这个队列就是我们所说的事件队列。将事件排队后,解复用器返回应用程序线程的控制权。
同时,事件循环遍历事件队列中的每个事件并调用附加的回调来处理事件响应。
这是 Node.js 使用的反应器模式。
单线程 Web 后端与多线程 Web 后端相比有什么好处?尽管 Node 是单线程的,但大多数用于后端开发的编程语言都提供了多线程来处理应用程序操作。只有单线程有什么好处有利于后端开发?
  • 开发人员更容易实现应用程序。我们的应用程序没有在生产中突然遇到意外竞争条件的风险。
  • 单线程应用程序易于扩展。
  • 它们可以在没有太多延迟的情况下为一次收到的大量用户请求提供服务。相比之下,当流量很高时,多线程后端必须等待线程池中的线程有空来为用户请求提供服务。由于 Node 的非阻塞特性,用户请求不会在单线程上停留太久的风险(这仅在操作不是 CPU 密集型的情况下才成立)。
Node 中的 REPL 是什么?NodeJS常见面试问题有哪些?REPL 代表 Read-Eval-Print-Loop。它是一个虚拟环境,你可以在其中轻松运行编程语言。Node 带有一个内置的 REPL 来运行 Javascript 代码。它类似于我们在浏览器中用来运行 Javascript 代码的控制台。
要启动 Node REPL,你只需在命令行上运行命令 node。然后,一旦你在一行中编写了一行 Javascript 代码,你就可以在下一行中看到它的输出。
process.nextTick 和 setImmediate 函数有什么区别?NodeJS面试问题合集:传递给 setImmediate 函数的回调在事件队列上的事件循环的下一次迭代中执行。
另一方面,传递给 的回调process.nextTick在事件循环的下一次迭代之前执行,并且在程序中当前运行的操作完成之后执行。在应用程序启动时,它的回调在事件循环开始遍历事件队列之前被调用。
因此, 的回调process.nextTick总是在的回调之前调用setImmediate
如果我们考虑以下代码片段:
setImmediate(() => { console.log("first"); })process.nextTick(() => { console.log("second"); })console.log("third");

它的输出按以下顺序打印。
third second first

什么是存根?测试应用程序时使用存根。它们模拟给定组件或模块的行为,因此你可以只关注要测试的代码部分。通过使用存根代替与测试无关的组件,你不必担心外部组件会影响测试结果。
例如,如果你正在测试的组件在你希望测试的部分之前有一个文件读取操作,你可以使用存根来模拟该行为并返回模拟内容,而无需实际读取文件。
在 Node 中,我们为此使用了像 Sinon 这样的库。
为什么在 Express 中将“应用程序”和“服务器”分开是一个好习惯?NodeJS面试问题解析:通过在 Express 中分离应用程序和服务器,我们可以将 API 实现与网络相关配置分离。这允许我们在不执行网络调用的情况下执行 API 测试。这也保证了更快的测试执行和更好的代码覆盖率指标。
要实现这种分离,你应该在单独的文件中声明 API 和服务器。这里我们使用两个文件:app.jsserver.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/JobBoard/JobListModule"); app.set('port', process.env.PORT); const http = http.createServer(app);

什么是yarn和 npm?为什么要在 npm 上使用 yarn?NodeJS常见面试问题有哪些?npm是随 Node.js 分发的默认包管理器。它有一个庞大的公共和私有包库,存储在名为 emp 注册表的数据库中,用户可以通过 npm 的命令行客户端访问该数据库。借助 npm,用户可以轻松管理项目中使用的依赖项。
yarn也是一个包管理器,作为对 npm 的一些缺点的回答而发布。然而,yarn 依赖于 npm 注册表来为用户提供对包的访问。由于 yarn 的底层结构基于 npm 本身,如果你从 npm 迁移到 yarn,你的项目结构和工作流程不必经历重大更改。
就像我之前提到的,在某些情况下,yarn 提供了比 npm 更好的功能。与 npm 不同的是,它会缓存你下载的每个包,因此你无需在需要时重新下载。
它还通过使用校验和验证包的完整性来提供更好的安全性。它保证在某个系统上工作的包在任何其他系统中的工作方式完全相同。这些是你希望选择 yarn 而不是 npm 进行包管理的一些原因。
NodeJS面试问题合集结论在这篇文章中,我们讨论了 15 个最常见的 Node.js 面试问题,以帮助你更好地准备下一次面试。知道你可能会被问到什么类型的问题并知道他们的答案会让你有信心毫无疑问和紧张地回答面试问题。
每当你面对大型面试时,我们祝你好运,成功!

    推荐阅读