Node.js 常见面试题速查

2023-05-17 16:42:27 浏览数 (2)

# node 如何获取命令行传来的参数

process 是一个全局变量,它提供当前 Node.js 进程的有关信息,而 process.argv 属性则返回一个数组,数组中的信息包括启动 Node.js 进程时的命令行参数

代码语言:javascript复制
// {
//   "scripts": {
//     "serve": "node test.js arg1 arg2",
//   }
// }
// test.js
const arguments = process.argv.splice(2); // ['arg1', 'arg2']

其他参数

  • process.argv[0] 启动 Node.js 进程的可执行文件所在的绝对路径
  • process.argv[1] 当前执行的文件的 JS 文件路径
  • process.argv.splice(2) 命令行参数

关于获取命令行传来的参数还可以结合 commander 的 commander.parse(process.argv);

# node 有哪些相关的文件路径

  • __dirname 被执行的 js 所在文件夹的绝对路径
  • __filename 返回被执行的 js 的绝对路径
  • process.cwd() node 命令时所在的文件夹的绝对路径
  • ./ 当前目录
  • ../ 相对路径,上级目录

# node 相关的 path API

  • path.dirname(): 返回 path 的目录名
  • path.join():所有给定的 path 片段连接到一起,然后规范化生成的路径
  • path.resolve():方法会将路径或路径片段的序列解析为绝对路径,解析为相对于当前目录的绝对路径,相当于 cwd 命令

join 是直接拼接 path 片段, resolve 是解析路径并返回

# node 文件如何读取

代码语言:javascript复制
const fs = require('fs');

// 同步
try {
  fs.unlinkSync('文件');
  console.log('已成功删除文件');
} catch (err) {
  // 处理错误
}

// 异步回调
fs.unlink('文件', (err) => {
  if (err) throw err;
  console.log('已成功地删除文件');
});

// promisify
const fs = require('fs/promises');

(async function(path) {
  try {
    await fs.unlink(path);
    console.log(`已成功地删除文件 ${path}`);
  } catch (error) {
    console.error('出错:', error.message);
  }
})('文件');

# node 的 URL 模块是用来干嘛的?

对 url 的字符串解析、url 拼接等

  • url.parse 可以将一个 url 的字符串解析并返回一个 url 的对象
  • url.format 将传入的 url 对象编程一个 url 字符串并返回

# node 的 http 模块创建服务与 Express 或 Koa 框架有何不同?

express = http 模块 中间件 路由

http 实现

代码语言:javascript复制
const http = require('http');
const server = http.createServer((req, res) => {
  res.writeHead(200, {
    'content-type': 'text/plain'
  });
  res.write('hello node');
  res.end();
});
server.listen(3000);

express 实现

代码语言:javascript复制
const express = require('express');
const app = express();

app.use(middleware1);
app.use(middleware2);

app.get('/', (req, res) => {
  res.send('hello express');
});

app.listen(3000, () => {
  console.log('listen at 3000');
})

function middleware1(req, res, next) {
  // before next()
  next();
  // after next()
}

function middleware2(req, res, next) {
  // before next()
  next();
  // after next()
}

# Express 和 Koa 框架中间件有什么不同

express 中间件:通过 next 的机制,即上一个中间件会通过 next 触发下一个中间件(层层递归)

koa2 中间件:通过 async/await 实现,中间件执行顺序是 “洋葱圈模型”(精简彪悍)

  • koa compose,利用闭包和递归
代码语言:javascript复制
const Koa = require('koa');
const app = new Koa();

app.use(middleware1);
app.use(middleware2);

app.listen(3000);

async function middleware1(ctx, next) {
  // before next()
  await next();
  // after next()
}

async function middleware2(ctx, next) {
  // before next()
  await next();
  // after next()
}

# 什么是模板引擎

模板引擎是一个通过结合页面模板、要展示的数据生成HTML页面的工具,本质上是后端渲染(SSR)的需求,加上Node渲染页面本身是纯静态的,当我们需要页面多样化、更灵活,我们就需要使用模板引擎来强化页面,更好的凸显服务端渲染的优势

常见模板引擎

  • art-templat 号称效率最高的,模版引擎
  • ejs 是一个 JavaScript 模板库,用来从 JSON 数据中生成 HTML 字符串
  • pug 是一款健壮、灵活、功能丰富的模板引擎,专门为 Node.js 平台开发

# node 如何利用多核 CPU 以及创建集群

nodejs 是基于 V8 引擎构建的,一个 nodejs 进程只能使用一个 CPU(一个 CPU 运行一个 node 实例),如果有多核 CPU,可以启动多个进程来利用多核 CPU

代码语言:javascript复制
const cluster = require('cluster');
const os = require('os');
const express = require('express');
const path = require('path');
const ejs = require('ejs');

const app = express();

const numCPUs = os.cpus().length;

if (cluster.isMaster) {
  console.log(`Master ${process.pid} is running`);
  for (let i = 0; i < numCPUs;   i) {
    cluster.fork();
  }
  cluster.on('exit', (worker, code, signal) => {
    console.log(`worker ${worker.process.pid} died`);
  });
} else {
  app.set('views', path.join(__dirname, 'views'));
  app.set('view engine', 'ejs');

  app.get('/', (req, res, next) => {
    res.render('index.ejs', { title: 'ejs' });
  });
  app.listen(3000, () => {
    console.log(`Worker ${process.pid} started`);
  })
}

cluster.fork() 的本质上还是使用 child_process.fork(),虽然 1 个 Master 和 多个 Worker 进程会对端口监听自动进行负载均衡。

0 人点赞