Node面试题汇总

1、面试官:说说你对Node.js 的理解?

Node.js 是一个开源与跨平台的 JavaScript 运行时环境
在浏览器外运行 V8 JavaScript 引擎(Google Chrome 的内核),利用事件驱动、非阻塞和异步输入输出模型等技术提高性能
可以理解为 Node.js 就是一个服务器端的、非阻塞式I/O的、事件驱动的JavaScript运行环境
非阻塞异步
Nodejs采用了非阻塞型I/O机制,在做I/O操作的时候不会造成任何的阻塞,当完成之后,以时间的形式通知执行操作
例如在执行了访问数据库的代码之后,将立即转而执行其后面的代码,把数据库返回结果的处理代码放在回调函数中,从而提高了程序的执行效率
事件驱动
事件驱动就是当进来一个新的请求的时,请求将会被压入一个事件队列中,然后通过一个循环来检测队列中的事件状态变化,如果检测到有状态变化的事件,那么就执行该事件对应的处理代码,一般都是回调函数
比如读取一个文件,文件读取完毕后,就会触发对应的状态,然后通过对应的回调函数来进行处理
优点:
1、处理高并发场景性能更佳
2、适合I/O密集型应用,值的是应用在运行极限时,CPU占用率仍然比较低,大部分时间是在做 I/O硬盘内存读写操作
因为Nodejs是单线程,带来的缺点有:
1、不适合CPU密集型应用
2、只支持单核CPU,不能充分利用CPU
3、可靠性低,一旦代码某个环节崩溃,整个系统都崩溃

2、面试官:说说 Node. js 有哪些全局对象?

在浏览器 JavaScript 中,通常window 是全局对象, 而 Nodejs中的全局对象是 global
模块级别的全局对象
这些全局对象是模块中的变量,只是每个模块都有,看起来就像全局变量,像在命令交互中是不可以使用,包括:
__dirname __filename exports module require

  • _dirname:获取当前文件所在的路径,不包括后面的文件名
  • _filename:获取当前文件所在的路径和文件名称,包括后面的文件名称
  • exports:module.exports 用于指定一个模块所导出的内容,即可以通过 require() 访问的内容
  • module:对当前模块的引用,通过module.exports 用于指定一个模块所导出的内容,即可以通过 require() 访问的内容
  • require 用于引入模块、 JSON、或本地文件。 可以从 node_modules 引入模块。

可以使用相对路径引入本地模块或JSON文件,路径会根据__dirname定义的目录名或当前工作目录进行处理

3、面试官:说说对 Node 中的 process 的理解?

process 对象是一个全局变量,提供了有关当前 Node.js进程的信息并对其进行控制,作为一个全局变量

4、面试官:说说对 Node 中的 fs模块的理解?

fs(filesystem),该模块提供本地文件的读写能力,基本上是POSIX文件操作命令的简单包装
可以说,所有与文件的操作都是通过fs核心模块实现
导入模块如下:

const fs = require('fs');

这个模块对所有文件系统操作提供异步(不具有sync 后缀)和同步(具有 sync 后缀)两种操作方式,而供开发者选择

5、面试官:说说对 Node 中的 Buffer 的理解?

在Node应用中,需要处理网络协议、操作数据库、处理图片、接收上传文件等,在网络流和文件的操作中,要处理大量二进制数据,而Buffer(缓冲区)就是在内存中开辟一片区域(初次初始化为8KB),用来存放二进制数据
简单来讲,Nodejs不能控制数据传输的速度和到达时间,只能决定何时发送数据,如果还没到发送时间,则将数据放在Buffer中,即在RAM中,直至将它们发送完毕
Buffer是用来存储二进制数据,其的形式可以理解成一个数组,数组中的每一项,都可以保存8位二进制:00000000,也就是一个字节

6、面试官:说说对 Node 中的 Stream 的理解?应用场景?

流(Stream),是一个数据传输手段,是端到端信息交换的一种方式,而且是有顺序的,是逐块读取数据、处理内容,用于顺序读取输入或写入输出
Node.js中很多对象都实现了流,总之它是会冒数据(以 Buffer 为单位)
它的独特之处在于,它不像传统的程序那样一次将一个文件读入内存,而是逐块读取数据、处理其内容,而不是将其全部保存在内存中
流可以分成三部分:source、dest、pipe
在source和dest之间有一个连接的管道pipe,它的基本语法是source.pipe(dest),source和dest就是通过pipe连接,让数据从source流向了dest
在NodeJS,几乎所有的地方都使用到了流的概念,分成四个种类:

  • 可写流:可写入数据的流。例如 fs.createWriteStream() 可以使用流将数据写入文件
  • 可读流: 可读取数据的流。例如fs.createReadStream() 可以从文件读取内容
  • 双工流: 既可读又可写的流。例如 net.Socket
  • 转换流: 可以在数据写入和读取时修改或转换数据的流。例如,在文件压缩操作中,可以向文件写入压缩数据,并从文件中读取解压数据

7、面试官:说说Node中的EventEmitter? 如何实现一个EventEmitter?

Node采用了事件驱动机制,而EventEmitter就是Node实现事件驱动的基础
在EventEmitter的基础上,Node几乎所有的模块都继承了这个类,这些模块拥有了自己的事件,可以绑定/触发监听器,实现了异步操作
这些产生事件的对象都是 events.EventEmitter 的实例,这些对象有一个 eventEmitter.on() 函数,用于将一个或多个函数绑定到命名事件上

8、面试官:说说对Nodejs中的事件循环机制理解?

js可以在浏览器中执行又可以在node中执行,但是它们的事件循环机制并不是一样的。并且有很大的区别。在Node中的事件循环分为六个阶段。
按顺序进行:
1、Timers:用于存储定时器的回调函数(setlnterval,setTimeout)。
2、Pending callbacks:执行与操作系统相关的回调函数,比如启动服务器端应用时监听端口操作的回调函数就在这里调用。
3、idle,prepare:系统内部使用。(这个我们程序员不用管)
4、Poll:存储1/O操作的回调函数队列,比如文件读写操作的回调函数。
5、Check:存储setlmmediate的回调函数。
setlmmediate方法用来把一些需要长时间运行的操作放在一个回调函数里,在浏览器完成后面的其他语句后,就立刻执行这个回调函数。
6、Closingcallbacks:执行与关闭事件相关的回调,例如关闭数据库连接的回调函数等。
总结:
1、当主线程同步代码执行完毕后才会进入事件循环
2、事件循环总共分六个阶段
3、事件循环中会先执行微任务再执行宏任务。
4、微任务会穿插在这六个阶段之间执行,每进入到下个阶段前会清空当前的微任务队列。
5、微任务中process.nextTick的优先级最高,会优先执行。
宏任务
Setlnterval、setimeout、setlmmediate、I/O
微任务
Promise.then、Promise.catch、Promise.finally、process.nextTick

9、面试官:说说 Node 文件查找的优先级以及 Require 方法的文件查找策略?

通过require函数导入其他模块(自定义模块、系统模块、第三方库模块)中的内容,require参数较为简单,但是内部的加载却是十分复杂的,其加载优先级也各自不同
1、缓存的模块优先级最高
2、如果是内置模块,则直接返回,优先级仅次缓存的模块
3、如果是绝对路径 / 开头,则从根目录找
4、如果是相对路径 ./开头,则从当前require文件相对位置找
5、如果文件没有携带后缀,先从js、json、node按顺序查找
6、如果是目录,则根据 package.json的main属性值决定目录下入口文件,默认情况为 index.js
7、如果文件为第三方模块,则会引入 node_modules 文件,如果不在当前仓库文件中,则自动从上级递归查找,直到根目录

10、面试官:如何实现jwt鉴权机制?说说你的思路

JWT(JSON Web Token),本质就是一个字符串书写规范,作用是用来在用户和服务器之间传递安全可靠的信息,使用token鉴权机制用于身份验证是最常见的方案
Token,分成了三部分,头部(Header)、载荷(Payload)、签名(Signature),并以.进行拼接。

  • 载荷即消息体,这里会存放实际的内容,也就是Token的数据声明,例如用户的id和name,默认情况下也会携带令牌的签发时间iat,通过还可以设置过期时间
  • 主要说一下签名,签名是对头部和载荷内容进行签名,一般情况,设置一个密钥,对前两个的结果进行HMACSHA25算法,这样一旦前面两部分数据被篡改,只要服务器加密用的密钥没有泄露,得到的签名肯定和之前的签名不一致

Token的使用分成了两部分:
1、生成token:登录成功的时候,颁发token
2、验证token:访问某些资源或者接口时,验证token
可以借助第三方库jsonwebtoken,通过jsonwebtoken 的 sign 方法生成一个 token
之后前端可以通过路由进行校验等等

11、面试官:如何实现文件上传?说说你的思路

对于文件上传,我们需要设置请求头为content-type:multipart/form-data
Multipart为互联网上的混合资源,就是资源由多种元素组成,form-data表示可以使用HTML Forms 和 POST 方法上传文件
文件上传步骤:
1、 action里确定提交的接口,enctype=“multipart/form-data” 就是指定上传文件格式,input 的 name 属性一定要等于file
2、 之后在服务器中,采用koa2中间件的形式解析上传的文件数据
首先获取上传的文件,获取文件数据后,可以通过fs模块将文件保存到指定目录,

12、面试官:如果让你来设计一个分页功能, 你会怎么设计? 前后端如何交互?

前端实现分页功能,需要后端返回必要的数据,如总的页数,总的数据量,当前页,当前的数据,后端采用mysql作为数据的持久性存储
前端向后端发送目标的页码page以及每页显示数据的数量pageSize,
默认情况每次取n条数据,则每一条数据的起始位置start为:

const start = (page - 1) * pageSize

数据库中进行截取从start到start+pageSize之间(左闭右开)的数据,返回给前端

13、面试官:Node性能如何进行监控以及优化?

Node作为一门服务端语言,性能方面尤为重要,其衡量指标一般有如下:
1、 CPU 2、内存 3、I/O 4、网络
CPU主要分成了两部分:
1、CPU负载:在某个时间段内,占用以及等待CPU的进程总数
2、CPU使用率:CPU时间占用状况,等于 1 - 空闲CPU时间(idle time) / CPU总时间
这两个指标都是用来评估系统当前CPU的繁忙程度的量化指标
Node应用一般不会消耗很多的CPU,如果CPU占用率高,则表明应用存在很多同步操作,导致异步任务回调被阻塞
内存指标
内存是一个非常容易量化的指标。 内存占用率是评判一个系统的内存瓶颈的常见指标
在Node中,一个进程的最大内存容量为1.5GB。因此我们需要减少内存泄露
磁盘 I/O
硬盘的IO 开销是非常昂贵的,硬盘 IO 花费的 CPU 时钟周期是内存的 164000 倍,内存 IO比磁盘IO 快非常多,所以使用内存缓存数据是有效的优化方法。常用的工具如 redis、memcached等
性能方面的监控,一般情况都需要借助工具来实现
如Easy-Monitor 2.0,其是轻量级的 Node.js 项目内核性能监控 + 分析工具,在默认模式下,只需要在项目入口文件 require 一次,无需改动任何业务代码即可开启内核级别的性能监控分析,查看进程界面
优化方式:
1、使用最新版本Node.js
每个版本的性能提升主要来自于两个方面:
V8 的版本更新
Node.js 内部代码的更新优化
2、正确使用流 Stream
在Node中,很多对象都实现了流,对于一个大文件可以通过流的形式发送,不需要将其完全读入内存
3、代码层面优化
合并查询,将多次查询合并一次,减少数据库的查询次数
4、通过减少内存占用,可以提高服务器的性能
在 V8 中,主要将内存分为新生代和老生代两代:

  • 新生代:对象的存活时间较短。新生对象或只经过一次垃圾回收的对象
  • 老生代:对象存活时间较长。经历过一次或多次垃圾回收的对象

若新生代内存空间不够,直接分配到老生代
而节省内存最好的方式是使用池,其将频用、可复用对象存储起来,减少创建和销毁操作
使用对象池的机制,对这种频繁需要创建和销毁的对象保存在一个对象池中。每次用到该对象时,就取对象池空闲的对象,并对它进行初始化操作,从而提高框架的性能

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一些可能会在2023年前端面试中出现的题目: 1. 什么是闭包?如何使用闭包解决作用域问题? 2. 解释一下 JavaScript 中的继承,有哪些实现继承的方法? 3. 解释一下 JavaScript 中的事件循环机制(Event Loop),以及它与异步编程的关系。 4. 如何优化网页的性能?包括什么方面? 5. 解释一下 Vue.js 中的双向数据绑定原理,它是如何实现的? 6. 解释一下 React 中的虚拟 DOM 是什么,以及它的优点和缺点是什么? 7. 解释一下 CSS 中盒模型的概念,包括 content、padding、border 和 margin。 8. 解释一下 CSS 中 Flexbox 布局的概念,以及如何使用它进行布局。 9. 解释一下 CSS 中 Grid 布局的概念,以及如何使用它进行布局。 10. 解释一下 Webpack 的概念和作用,以及如何使用它进行模块打包。 11. 解释一下 HTTPS 的概念和原理,以及它与 HTTP 的区别。 12. 解释一下 Web 应用程序的安全问题,包括 XSS 和 CSRF 攻击。 13. 解释一下前端工程化的概念和作用,以及常用的前端工程化工具。 14. 解释一下 Node.js 的概念和作用,以及如何使用它进行后端开发。 15. 解释一下 TypeScript 的概念和作用,以及如何使用它进行编程。 16. 解释一下 WebAssembly 的概念和作用,以及它与 JavaScript 的区别。 17. 解释一下 PWA 的概念和作用,以及如何开发一个 PWA 应用程序。 18. 解释一下 GraphQL 的概念和作用,以及如何使用它进行后端开发。 19. 解释一下微前端的概念和作用,以及如何使用它进行前端架构设计。 20. 解释一下 Serverless 的概念和作用,以及如何使用它进行后端开发。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值