Node面试总结

Posted lime2019

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Node面试总结相关的知识,希望对你有一定的参考价值。

本篇博客记录个人在面试过程中所遇到有关Node的问题。

1. Node基础

1.1 node.js是什么?

Node.js 是一个基于 Chrome V8 引擎的 javascript 运行时。

1.2 Node.js与前端JavaScript的异同?

相同点:

  • Node.js与前端JavaScript语言基础都是ECMAScript;

不同点:

  • 前端JavaScript使用JS Web API,Node.js使用 Node API;
  • 前端JavaScript主要是在浏览器上运行,用于网页开发,因此其拓展了DOM、BOM操作;
  • Node.js主要是在服务器上运行,用于服务端程序开发,因此其拓展了os(操作系统)、file(文件系统)、net(网络系统)、database(数据库)等能力;

1.3 Node.js调试

如何调试Node项目:

  • 启动Node服务时,使用--inspect参数;
  • 代码中使用debugger断点;
  • 使用Chrome进行调试(在Chrome浏览器地址栏输入chrome://inspect);

可参考阮一峰老师写的Node 调试工具入门教程

1.4 获取当前文件和当前目录的路径

使用两个全局变量进行获取:

  • 使用__filename获取当前文件路径;
  • 使用__dirname获取当前目录路径;

1.5 CommonJS和ES6 Module的区别

共同点:

  • CommonJS和ES6 Module都可以对引入的对象进行赋值,即对对象内部属性的值进行改变;

不同点:

  • CommonJS模块输出的是一个值的拷贝,ES6 Module输出的是值的引用;
  • CommonJS模块是动态引入,执行时引入,ES6 Module是静态引入,编译时引入;
  • CommonJS模块的require()是同步加载模块,ES6 Module的import命令是异步加载,有一个独立的模块依赖的解析阶段;
  • CommonJS的this是当前模块,ES6 Module的thisundefined

可参考《ECMAScript 6 入门》Module 的加载实现 中 ES6 模块与 CommonJS 模块的差异 一节。

另外webpack中Tree Shaking仅支持ES6 Module。

1.6 path.resolve和path.join的区别

相同点:

  • 两者都是用于拼接文件路径;

不同点:

  • path.resolve返回绝对路径;
  • path.join返回相对路径;

2. Node进阶

2.1 读取大文件

知识点:流(stream),readline;

2.2 事件循环(event loop)在Node和浏览器中区别

Node 11版本中,Event Loop已经与浏览器趋于相同。

浏览器中异步:

  • 宏任务(macro):setTimeout、setInterval、ajax等;
  • 微任务(micro):Promise、async/await等;

浏览器事件循环:

  • Call Stack空闲时,将触发Event Loop机制,执行宏任务;
  • 在触发Event Loop之前,会把现有的微任务都执行完成;
  • 微任务会比宏任务执行时机更早;

Node中异步:

  • 宏任务:setTimeout、setInterval、setImmediate、I/O文件操作、网络操作、Socket连接等;
  • 微任务:Promise、async/await、process.nextTick等;

Node事件循环:
Node事件循环

  • timers:执行setTimeout以及setInterval的回调;
  • I/O callbacks:处理网络、流、TCP的错误回调;
  • idle, prepare:闲置阶段,Node内部使用;
  • poll:执行poll中的I/O队列,检查定时器是否到达时间;
  • check:存放setImmediate回调;
  • close callback:关闭回调,例如:Socket.on("close")

每个阶段执行之前,先执行微任务。

微任务中process.nextTick优先级最高,最早执行(不被推荐使用,因为其会阻塞I/O),建议使用setImmediate替代process.nextTick

相同点:

  • 微任务比宏任务优先级高;

不同点:

  • NodeJS异步API更多,宏任务也更多;
  • NodeJS的Event Loop分为六个阶段,要按照顺序执行;

参考博文:

async/await执行顺序

setImmediate(() => {
    console.log('immediate')
})

async function async1 () {
    console.log('async1 start') // 同步
    await async2() // 同步
    console.log('async1 end') // await 后面的内容,异步(微任务),相当于 callback 函数里的内容
}

async function async2 () {
    console.log('async2')
}

console.log('script start')

setTimeout(function () {
    console.log('setTimeout')
}, 0)

async1() // 同步

new Promise (function (resolve) {
    console.log('promise1') // 同步
    resolve()
}).then (function () {
    console.log('promise2')
})

process.nextTick(() => {
    console.log('nextTick')
})

console.log('script end')
// 同步代码执行完成

// 同步代码执行完成之后,有哪些异步还没有被执行:
// 1. setImmediate 回调,宏任务,优先级比较低
// 2. async1 函数中,await 后面的内容,微任务
// 3. setTimeout 回调,宏任务,优先级比 setImmediate 高
// 4. promise then 回调,微任务
// 5. process.nextTick 回调,微任务,优先级在微任务中最高

代码来源:

2.3 NodeJS线上为什么开启多进程

使用PM2的优点:

  • 高效使用多核CPU;
  • 充分利用服务器内存;
  • 不浪费服务器资源;

3. Node框架

3.1 描述Koa2洋葱模型

描述Koa2洋葱模型

3.2 描述Koa2和express的中间件机制

中间件:

  • 从代码来看,中间件就是一个函数;
  • 从业务来看,中间件则是一个独立的模块;
  • 模块拆分、模块组合,可以完成复杂的功能;

4. 操作系统相关

4.1 进程与线程区别

进程是CPU资源分配的最小单位;线程是CPU调度的最小单位;

一个进程由一个或多个线程组成,线程是一个进程中代码的不同执行路线;

一个进程的内存空间是共享的,每个线程都可以使用这些共享内存;

多进程:在同一个时间里,同一个计算机系统中如果允许两个或两个以上的进程处于运行状态。

多线程:程序中包含多个执行流,即在一个程序中可以同时运行多个不同的线程来执行不同的任务,也就是说允许单个程序创建多个并行执行的线程来完成各自的任务。

以上是关于Node面试总结的主要内容,如果未能解决你的问题,请参考以下文章

Node面试总结

Node.js 面试问题与答案 2017 版

面试常用的代码片段

Node.js JavaScript 片段中的跳过代码

面向面试编程代码片段之GC

extjs常用技巧