Node 八股文记录

1,653 阅读4分钟

jwt鉴权机制

JWT(JSON Web Token) Token,分成了三部分,头部(Header)、载荷(Payload)、签名(Signature)并以.进行拼接。其中头部和载荷都是以JSON格式存放数据,只是进行了编码

  • 头部(主要声明使用的算法,如hs256)
  • 载荷(存储的数据)
  • 签名(secretKey)

Node性能如何进行监控以及优化?

衡量Node性能的指标

  • I/O
  • CPU
  • 内存
  • 网络

CPU

如果cpu过高说明同步任务较多导致异步任务回调受阻

内存

// /app/lib/memory.js
const os = require('os');
// 获取当前Node内存堆栈情况
const { rss, heapUsed, heapTotal } = process.memoryUsage();
// 获取系统空闲内存
const sysFree = os.freemem();
// 获取系统总内存
const sysTotal = os.totalmem();

module.exports = {
  memory: () => {
    return {
      sys: 1 - sysFree / sysTotal,  // 系统内存占用率
      heap: heapUsed / headTotal,   // Node堆内存占用率
      node: rss / sysTotal,         // Node占用系统内存的比例
    }
  }
}

I/O

硬盘的 IO 开销是非常昂贵的, 内存 IO 比磁盘 IO 快非常多,所以使用内存缓存数据是有效的优化方法。常用的工具如 redismemcached 

如何监控

关于性能方面的监控,一般情况都需要借助工具来实现

这里采用Easy-Monitor 2.0,其是轻量级的 Node.js 项目内核性能监控 + 分析工具,在默认模式下,只需要在项目入口文件 require 一次,无需改动任何业务代码即可开启内核级别的性能监控分析

const easyMonitor = require('easy-monitor');
easyMonitor('你的项目名称');

// 启动项目后启动两个服务用于监控性能面板
[Easy-Monitor: dashboard <11707>] http_server start at 12333...
[Easy-Monitor: dashboard <11707>] tcp_server start at 26666...
[Easy-Monitor: embrace <11704>] connect to 127.0.0.1:26666 success...

性能优化

  • 合并查询
  • 正确使用流 stream

Node 中间件

一、是什么

系统软件所提供的基础服务(系统) ----> (应用)衔接网络上应用系统的各个部分或不同的应用

中间件的本质为一个回调函数,参数包含ctx执行上下文(请求对象、响应对象)执行下一个中间件 next()的函数

// async 函数
app.use(async (ctx, next) => {
    const start = Date.now();
    await next();
    const ms = Date.now() - start;
    console.log(`${ctx.method} ${ctx.url} - ${ms}ms`);
});

// 普通函数
app.use((ctx, next) => {
    const start = Date.now();
    return next().then(() => {
        const ms = Date.now() - start;
        console.log(`${ctx.method} ${ctx.url} - ${ms}ms`);
    });
});

特点

  • app.use() 传入一个函数,这个函数包含两个参数 ctr, next 并且需要返回一个Promise

说说Node中的EventEmitter? 如何实现一个EventEmitter?

Node 采用了事件驱动机制,而EventEmitter 就是Node实现事件驱动的基础

EventEmitter的基础上,Node 几乎所有的模块都继承了这个类,这些模块拥有了自己的事件,可以绑定/触发监听器,实现了异步操作

实现一个自定义 event

const EventEmitter = require('events')

class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter()

function callback() {
    console.log('触发了event事件!')
}
myEmitter.on('event', callback)
myEmitter.emit('event')
myEmitter.removeListener('event', callback);

说说对 Node 中的 Buffer 的理解?应用场景?

Node应用中,需要处理网络协议、操作数据库、处理图片、接收上传文件等,在网络流和文件的操作中,要处理大量二进制数据,而Buffer就是在内存中开辟一片区域(初次初始化为8KB),用来存放二进制数据

Buffer 类在全局作用域中,无须require导入

应用场景

Buffer的应用场景常常与流的概念联系在一起,例如有如下:

  • I/O操作
  • 加密解密
  • zlib.js

说说对 Node 中的 process 的理解?有哪些常用方法?

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

常用属性方法

  • process.env:环境变量,例如通过 `process.env.NODE_ENV 获取不同环境项目配置信息
  • process.nextTick:这个在谈及 EventLoop 时经常为会提到
  • process.pid:获取当前进程id
  • process.ppid:当前进程对应的父进程
  • process.cwd():获取当前进程工作目录,
  • process.platform:获取当前进程运行的操作系统平台
  • process.uptime():当前进程已运行时间,例如:pm2 守护进程的 uptime 值

Node. js 有哪些全局对象?

  • Class:Buffer
  • process
  • console
  • clearInterval、setInterval
  • clearTimeout、setTimeout
  • global
  • __dirname
  • __filename
  • exports
  • module
  • require

说说你对Node.js 的理解?优缺点?应用场景?

一、是什么

  • 开源与跨平台的 JavaScript 运行时环境
  • 在浏览器外运行 V8 JavaScript 引擎(Google Chrome 的内核),利用事件驱动、非阻塞和异步输入输出模型等技术提高性能

优缺点

  • 处理高并发场景性能更佳
  • 适合I/O密集型应用,值的是应用在运行极限时,CPU占用率仍然比较低,大部分时间是在做 I/O硬盘内存读写操作

因为Nodejs是单线程,带来的缺点有:

  • 不适合CPU密集型应用
  • 只支持单核CPU,不能充分利用CPU
  • 可靠性低,一旦代码某个环节崩溃,整个系统都崩溃

common.js和es6中模块引入的区别?

在使用上的差别主要有:

  • CommonJS模块输出的是一个值的拷贝,ES6模块输出的是值的引用CommonJS模块是运行时加载,ES6模块是编译时输出接口。
  • CommonJs是单个值导出,ES6 Module可以导出多个
  • CommonJs是动态语法可以写在判断里,ES6 Module静态语法只能写在顶层CommonJs的this是当前模块,ES6 Module的this是undefined