Node.js
Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时,广泛用于构建高性能的网络应用。以下是一些常见的 Node.js 面试题及其解答,帮助你准备面试:
1. 什么是 Node.js?
Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时,允许开发者使用 JavaScript 编写服务器端代码。它采用事件驱动、非阻塞 I/O 模型,适合构建高性能、可扩展的网络应用。
2. Node.js 的特点是什么?
非阻塞 I/O:Node.js 使用非阻塞 I/O 模型,能够处理大量并发请求。
事件驱动:基于事件循环机制,适合处理实时应用。
单线程:Node.js 是单线程的,但通过事件循环和异步操作可以高效处理并发。
跨平台:Node.js 可以在多种操作系统上运行,如 Windows、Linux、macOS 等。
3. Node.js 的事件循环是什么?
事件循环是 Node.js 处理异步操作的核心机制。它允许 Node.js 执行非阻塞 I/O 操作,尽管 JavaScript 是单线程的。事件循环不断地检查事件队列,执行回调函数,处理异步任务。
4. 什么是回调函数?
回调函数是作为参数传递给另一个函数的函数,通常用于处理异步操作的结果。例如,在读取文件时,可以传递一个回调函数来处理文件读取完成后的操作。
const fs = require('fs');
fs.readFile('file.txt', 'utf8', (err, data) => {
if (err) throw err;
console.log(data);
});
5. 什么是 Promise?
Promise 是用于处理异步操作的对象,表示一个可能现在、将来或永远都不会完成的操作。它有三种状态:pending(进行中)、fulfilled(已成功)和 rejected(已失败)。
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Success!');
}, 1000);
});
promise.then((result) => {
console.log(result); // 输出: Success!
});
6. 什么是 async/await?
async/await 是 ES2017 引入的语法糖,用于简化异步代码的编写。async 函数返回一个 Promise,await 用于等待 Promise 的解决。
async function fetchData() {
const response = await fetch('https://api.example.com/data');
const data = await response.json();
console.log(data);
}
7. Node.js 中的模块系统是什么?
Node.js 使用 CommonJS 模块系统,允许开发者将代码分割成多个模块。每个模块可以通过 require 导入,通过 module.exports 导出。
// math.js
module.exports = {
add: (a, b) => a + b,
subtract: (a, b) => a - b
};
// app.js
const math = require('./math');
console.log(math.add(2, 3)); // 输出: 5
8. 什么是事件发射器(Event Emitter)?
事件发射器是 Node.js 中用于处理事件的核心类。它允许对象触发和监听事件。EventEmitter 类是 events 模块的一部分。
const EventEmitter = require('events');
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
myEmitter.on('event', () => {
console.log('An event occurred!');
});
myEmitter.emit('event'); // 输出: An event occurred!
9. Node.js 中的流(Stream)是什么?
流是用于处理读写数据的抽象接口,特别适合处理大文件或实时数据。Node.js 中有四种类型的流:可读流、可写流、双工流和转换流。
const fs = require('fs');
const readStream = fs.createReadStream('file.txt');
const writeStream = fs.createWriteStream('output.txt');
readStream.pipe(writeStream);
10. 如何处理 Node.js 中的错误?
在 Node.js 中,错误通常通过回调函数的第一个参数传递,或者通过 Promise 的 catch 方法捕获。还可以使用 try/catch 块来处理 async/await 中的错误。
// 回调函数中的错误处理
fs.readFile('file.txt', 'utf8', (err, data) => {
if (err) {
console.error('Error reading file:', err);
return;
}
console.log(data);
});
// Promise 中的错误处理
promise
.then((result) => console.log(result))
.catch((err) => console.error('Error:', err));
// async/await 中的错误处理
async function fetchData() {
try {
const response = await fetch('https://api.example.com/data');
const data = await response.json();
console.log(data);
} catch (err) {
console.error('Error:', err);
}
}
11. 什么是中间件(Middleware)?
中间件是 Express.js 中的一个概念,指的是在请求和响应之间执行的函数。中间件可以执行各种任务,如日志记录、身份验证、数据解析等。
const express = require('express');
const app = express();
app.use((req, res, next) => {
console.log('Request URL:', req.url);
next();
});
app.get('/', (req, res) => {
res.send('Hello World!');
});
app.listen(3000);
12. 如何调试 Node.js 应用?
可以使用 node inspect 命令启动调试器,或者使用 Chrome DevTools 进行调试。还可以使用 console.log 或 debugger 语句进行简单的调试。
node inspect app.js
13. Node.js 中的集群(Cluster)是什么?
Node.js 的集群模块允许创建多个子进程(worker)来处理请求,充分利用多核 CPU 的性能。每个子进程都有自己的事件循环和内存空间。
const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
} else {
http.createServer((req, res) => {
res.writeHead(200);
res.end('Hello World\n');
}).listen(8000);
}
14. Node.js 中的 Buffer 是什么?
Buffer 是用于处理二进制数据的类。它表示固定长度的字节序列,通常用于处理文件、网络流等。
const buf = Buffer.from('Hello World', 'utf8');
console.log(buf.toString('hex')); // 输出: 48656c6c6f20576f726c64
15. Node.js 中的全局对象有哪些?
Node.js 中的全局对象包括 global、process、console、Buffer、setTimeout、setInterval 等。
16. Node.js 中的 process 对象是什么?
process 对象提供了与当前 Node.js 进程相关的信息和控制。它可以用于获取环境变量、命令行参数、退出进程等。
console.log(process.env.NODE_ENV); // 输出当前环境
process.exit(0); // 退出进程
17. Node.js 中的 require 是如何工作的?
require 是 Node.js 中用于加载模块的函数。它首先查找核心模块,然后查找 node_modules 目录中的模块,最后查找本地文件模块。
const fs = require('fs'); // 核心模块
const express = require('express'); // node_modules 中的模块
const myModule = require('./myModule'); // 本地文件模块
18. Node.js 中的 __dirname 和 __filename 是什么?
__dirname 表示当前模块文件所在的目录路径,__filename 表示当前模块文件的完整路径。
javascript
复制
console.log(__dirname); // 输出当前目录路径
console.log(__filename); // 输出当前文件路径
19. Node.js 中的 setImmediate 和 setTimeout 有什么区别?
setImmediate 和 setTimeout 都用于调度回调函数的执行,但 setImmediate 会在当前事件循环的末尾执行,而 setTimeout 会在指定的延迟后执行。
setImmediate(() => {
console.log('setImmediate');
});
setTimeout(() => {
console.log('setTimeout');
}, 0);
20. Node.js 中的 child_process 模块是什么?
child_process 模块允许创建子进程,执行系统命令或其他 Node.js 脚本。常用的方法有 spawn、exec、execFile 和 fork。
const { exec } = require('child_process');
exec('ls -l', (err, stdout, stderr) => {
if (err) {
console.error('Error:', err);
return;
}
console.log(stdout);
});
21. Node.js 中的 util 模块是什么?
util 模块提供了一些实用函数,如 util.promisify 用于将回调风格的函数转换为返回 Promise 的函数。
const util = require('util');
const fs = require('fs');
const readFile = util.promisify(fs.readFile);
readFile('file.txt', 'utf8')
.then(data => console.log(data))
.catch(err => console.error(err));
22. Node.js 中的 path 模块是什么?
path 模块提供了一些用于处理文件路径的工具函数,如 path.join、path.resolve、path.basename 等。
const path = require('path');
const filePath = path.join(__dirname, 'file.txt');
console.log(filePath); // 输出当前目录下的 file.txt 路径
23. Node.js 中的 os 模块是什么?
os 模块提供了一些与操作系统相关的工具函数,如获取 CPU 信息、内存信息、网络接口等。
const os = require('os');
console.log(os.platform()); // 输出操作系统平台
console.log(os.cpus()); // 输出 CPU 信息
24. Node.js 中的 crypto 模块是什么?
crypto 模块提供了加密功能,如哈希、HMAC、加密、解密等。
const crypto = require('crypto');
const hash = crypto.createHash('sha256');
hash.update('Hello World');
console.log(hash.digest('hex')); // 输出哈希值
25. Node.js 中的 net 模块是什么?
net 模块提供了创建 TCP 服务器和客户端的功能,用于处理网络通信。
const net = require('net');
const server = net.createServer((socket) => {
socket.write('Hello World\n');
socket.end();
});
server.listen(8000, () => {
console.log('Server listening on port 8000');
});
26. Node.js 中的 dns 模块是什么?
dns 模块提供了域名解析功能,如将域名解析为 IP 地址。
const dns = require('dns');
dns.lookup('example.com', (err, address) => {
if (err) throw err;
console.log(address); // 输出 IP 地址
});
27. Node.js 中的 http 模块是什么?
http 模块提供了创建 HTTP 服务器和客户端的功能,用于处理 HTTP 请求和响应。
const http = require('http');
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Hello World\n');
});
server.listen(3000, () => {
console.log('Server listening on port 3000');
});
28. Node.js 中的 https 模块是什么?
https 模块提供了创建 HTTPS 服务器和客户端的功能,用于处理加密的 HTTP 请求和响应。
const https = require('https');
const fs = require('fs');
const options = {
key: fs.readFileSync('key.pem'),
cert: fs.readFileSync('cert.pem')
};
https.createServer(options, (req, res) => {
res.writeHead(200);
res.end('Hello World\n');
}).listen(443);
29. Node.js 中的 fs 模块是什么?
fs 模块提供了文件系统操作的功能,如读取文件、写入文件、删除文件等。
const fs = require('fs');
fs.readFile('file.txt', 'utf8', (err, data) => {
if (err) throw err;
console.log(data);
});
30. Node.js 中的 zlib 模块是什么?
zlib 模块提供了压缩和解压缩功能,如 Gzip、Deflate 等。
const zlib = require('zlib');
const fs = require('fs');
const gzip = zlib.createGzip();
const input = fs.createReadStream('file.txt');
const output = fs.createWriteStream('file.txt.gz');
input.pipe(gzip).pipe(output);
31. Node.js 中的 readline 模块是什么?
readline 模块提供了逐行读取输入流的功能,通常用于处理命令行输入。
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.question('What is your name? ', (name) => {
console.log(`Hello, ${name}!`);
rl.close();
});
32. Node.js 中的 vm 模块是什么?
vm 模块提供了在 V8 虚拟机中运行 JavaScript 代码的功能,通常用于沙箱环境。
const vm = require('vm');
const script = new vm.Script('x += 1;');
const context = { x: 1 };
script.runInNewContext(context);
console.log(context.x); // 输出: 2
33. Node.js 中的 assert 模块是什么?
assert 模块提供了断言功能,用于测试代码的正确性。
const assert = require('assert');
assert.strictEqual(1, 1); // 通过
assert.strictEqual(1, 2); // 抛出 AssertionError
34. Node.js 中的 events 模块是什么?
events 模块提供了事件驱动的功能,允许对象触发和监听事件。
const EventEmitter = require('events');
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
myEmitter.on('event', () => {
console.log('An event occurred!');
});
myEmitter.emit('event'); // 输出: An event occurred!
35. Node.js 中的 stream 模块是什么?
stream 模块提供了流处理的功能,如可读流、可写流、双工流和转换流。
const fs = require('fs');
const readStream = fs.createReadStream('file.txt');
const writeStream = fs.createWriteStream('output.txt');
readStream.pipe(writeStream);
36. Node.js 中的 timers 模块是什么?
timers 模块提供了定时器功能,如 setTimeout、setInterval 和 setImmediate。
setTimeout(() => {
console.log('Timeout');
}, 1000);
setInterval(() => {
console.log('Interval');
}, 1000);
setImmediate(() => {
console.log('Immediate');
});
37. Node.js 中的 querystring 模块是什么?
querystring 模块提供了处理 URL 查询字符串的功能,如解析和序列化。
const querystring = require('querystring');
const query = querystring.parse('name=John&age=30');
console.log(query); // 输出: { name: 'John', age: '30' }
38. Node.js 中的 url 模块是什么?
url 模块提供了处理 URL 的功能,如解析和格式化。
const url = require('url');
const parsedUrl = url.parse('https://example.com/path?name=John');
console.log(parsedUrl.host); // 输出: example.com
39. Node.js 中的 util 模块是什么?
util 模块提供了一些实用函数,如 util.promisify 用于将回调风格的函数转换为返回 Promise 的函数。
const util = require('util');
const fs = require('fs');
const readFile = util.promisify(fs.readFile);
readFile('file.txt', 'utf8')
.then(data => console.log(data))
.catch(err => console.error(err));
40. Node.js 中的 worker_threads 模块是什么?
worker_threads 模块提供了多线程支持,允许在 Node.js 中创建和管理工作线程。
const { Worker, isMainThread, parentPort } = require('worker_threads');
if (isMainThread) {
const worker = new Worker(__filename);
worker.on('message', (message) => {
console.log(message); // 输出: Hello from worker
});
} else {
parentPort.postMessage('Hello from worker');
}
41. Node.js 中的 cluster 模块是什么?
cluster 模块允许创建多个子进程来处理请求,充分利用多核 CPU 的性能。
const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
} else {
http.createServer((req, res) => {
res.writeHead(200);
res.end('Hello World\n');
}).listen(8000);
}
42. Node.js 中的 buffer 模块是什么?
buffer 模块提供了处理二进制数据的功能,表示固定长度的字节序列。
const buf
性能优化
1. 明确优化目标与量化指标
首先说明优化的核心目标,并强调数据驱动:
-
目标:提升用户体验(如加载速度、交互流畅度)、降低资源消耗(如代码体积、请求数)、提高可维护性(如代码规范、架构设计)。
-
量化指标:
-
首屏加载时间(FCP, LCP)降低至 1s 以内
-
页面完全加载时间(Load)减少 30%
-
代码体积(Bundle Size)压缩 40%
-
关键接口响应时间缩短 50%
-
Lighthouse 评分提升至 90+
-
示例回答:
“在最近一个电商项目中,我们通过性能监控发现首屏加载时间超过 3 秒,Lighthouse 性能评分仅 45 分。目标是将首屏时间压缩到 1 秒内,并提升评分至 90+。最终通过静态资源优化、接口缓存和代码分割等手段,首屏时间降至 0.8 秒,Lighthouse 评分达到 92。”
2. 分层优化策略(技术细节)
从多维度展开优化方案,体现技术深度:
① 静态资源优化
-
压缩与 CDN:
-
使用 Webpack + TerserPlugin 压缩 JS/CSS,启用 Brotli/Gzip 压缩;
-
图片使用 WebP/AVIF 格式,配合 image-webpack-loader 自动压缩;
-
静态资源上传 CDN,通过 HTTP/2 多路复用提升加载效率。
-
-
按需加载:
-
路由级懒加载(React.lazy + Suspense / Vue 异步组件);
-
非关键资源(如埋点、非首屏图片)延迟加载(IntersectionObserver);
-
第三方库按需引入(如 lodash-es、antd 的 tree-shaking)。
-
② 代码与构建优化
-
Bundle 分析:
-
使用 webpack-bundle-analyzer 分析依赖体积,拆分重复代码(SplitChunksPlugin);
-
动态导入(Dynamic Import)分割业务代码与第三方库;
-
升级至 Webpack 5,利用持久化缓存(cache.filesystem)减少构建时间。
-
-
现代语法与工具链:
-
使用 ES Module 替代 CommonJS,利用 Vite/Snowpack 提升开发构建速度;
-
通过 Babel 按需编译,避免全量 Polyfill(@babel/preset-env + useBuiltIns: ‘usage’)。
-
③ 运行时性能优化
-
渲染优化:
-
避免强制同步布局(如减少 offsetWidth 读取,使用 FastDom 库);
-
高频操作防抖/节流(如滚动事件、ResizeObserver);
-
复杂列表使用虚拟滚动(react-window / vue-virtual-scroller)。
-
-
内存管理:
-
及时销毁全局事件监听、定时器;
-
使用 Chrome DevTools Memory 面板分析内存泄漏;
-
大数据列表采用分页或增量渲染。
-
④ 网络层优化
-
接口聚合与缓存:
-
GraphQL/BFF 层聚合分散接口,减少 HTTP 请求;
-
浏览器缓存(Cache-Control, ETag)与 Service Worker 离线缓存(Workbox);
-
预加载关键资源()。
-
-
协议升级:
-
升级至 HTTP/2 + TLS 1.3,启用 QUIC(如 Cloudflare 支持);
-
使用 Server Push 推送关键资源。
-
⑤ 用户体验增强
-
加载态优化:
-
骨架屏(Skeleton Screen)占位,避免布局抖动;
-
关键数据优先渲染(如先展示文字,图片懒加载 + 渐进式加载)。
-
-
交互反馈:
-
长任务使用 Web Worker 分解(如大数据计算);
-
点击/滚动添加微交互动画(CSS Transition,避免 JS 动画)。
-
- 工具链与监控
-
性能监控:
-
接入 Sentry 监控异常,Google Analytics 统计性能数据;
-
使用 Performance API 自定义指标(如 FCP、FID);
-
定时跑 Lighthouse CI,集成到 Jenkins/GitHub Actions。
-
-
自动化优化:
-
通过 Critical CSS 工具提取首屏关键样式内联;
-
使用 Preact 替代 React 轻量化(针对低端设备场景)。
-
4. 实际案例与难点突破
结合具体项目,突出技术决策和问题解决能力:
案例:
“在某个中后台项目中,首屏加载慢的原因是全量引入了 Moment.js 和 Antd。优化措施包括:
-
用 day.js 替代 Moment.js,减少 200KB;
-
配置 Antd 按需加载 + babel-plugin-import;
-
将非首屏组件拆分为独立 Chunk;
-
启用 Brotli 压缩后,主 Bundle 从 1.8MB 降至 600KB。首屏时间从 2.5s 优化至 0.9s。”
难点与解决:
“曾遇到 Webpack 编译慢的问题,通过分析发现是 Sass 嵌套过深导致。解决方案:
-
使用 dart-sass 替代 node-sass;
-
拆分全局 Sass 变量与混合器,避免重复编译;
-
开启 thread-loader 并行处理,构建时间减少 60%。”
5. 总结与未来规划
-
成果总结:用数据量化结果(如“PV 跳出率降低 20%”);
-
持续优化:关注 Web Vitals 指标、探索 WASM/Edge Computing 等新技术;
-
团队协作:推动 Code Review 中添加性能检查项,制定性能基线。
回答示例:
“在前端优化中,我会先通过 Lighthouse 和 Web Vitals 定位瓶颈,分优先级制定方案。例如,针对首屏加载,我会优先优化关键资源(如内联 CSS、预加载字体),用代码分割减少主包体积;针对运行时性能,通过虚拟列表和防抖优化长列表滚动。在最近的项目中,通过 Service Worker 缓存接口数据,接口平均响应时间从 800ms 降至 200ms。未来计划引入 RUM(Real User Monitoring)更精准监控性能瓶颈。”