Node.js 面试题详细答案 - Q1
Q1: Node.js 是什么?它的核心特性是什么?(非阻塞 I/O、事件驱动、单线程)
Node.js 概述
Node.js 是一个基于 Chrome V8 JavaScript 引擎构建的 JavaScript 运行时环境,让 JavaScript 能够在服务器端运行。
核心特性
1. 非阻塞 I/O (Non-blocking I/O)
原理:当执行 I/O 操作时,不会等待操作完成,而是继续执行后续代码。
// 阻塞式 I/O (传统方式)
const fs = require('fs');
console.log('开始读取文件');
const data = fs.readFileSync('large-file.txt'); // 阻塞,等待文件读取完成
console.log('文件读取完成');
console.log('继续执行其他任务');
// 非阻塞 I/O (Node.js 方式)
console.log('开始读取文件');
fs.readFile('large-file.txt', (err, data) => {
console.log('文件读取完成');
});
console.log('继续执行其他任务'); // 立即执行,不等待文件读取
2. 事件驱动 (Event-driven)
原理:基于事件和回调函数的编程模型,通过事件循环处理异步操作。
const EventEmitter = require('events');
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
// 注册事件监听器
myEmitter.on('data', (data) => {
console.log('接收到数据:', data);
});
// 触发事件
myEmitter.emit('data', 'Hello World');
// 实际应用:HTTP 服务器
const http = require('http');
const server = http.createServer();
server.on('request', (req, res) => {
res.end('Hello World');
});
server.listen(3000);
3. 单线程 (Single-threaded)
原理:主线程是单线程的,但通过事件循环和线程池处理 I/O 操作。
// 主线程是单线程的
console.log('主线程开始');
setTimeout(() => {
console.log('定时器回调');
}, 1000);
console.log('主线程结束');
// 输出顺序:
// 主线程开始
// 主线程结束
// 定时器回调 (1秒后)
高并发处理机制
// 单线程 + 事件循环处理高并发
const http = require('http');
const server = http.createServer((req, res) => {
// 模拟异步操作
setTimeout(() => {
res.end(`请求处理完成: ${req.url}`);
}, 100);
});
server.listen(3000, () => {
console.log('服务器启动,可以处理大量并发请求');
});
// 一个线程可以处理数千个并发连接
优势与适用场景
优势:
- 高并发处理能力
- 开发效率高(JavaScript 全栈)
- 丰富的生态系统
- 轻量级和快速
适用场景:
- Web 服务器和 API
- 实时应用(聊天、游戏)
- 微服务架构
- 工具和脚本
不适用场景:
- CPU 密集型任务
- 图像/视频处理
- 机器学习计算
总结
Node.js 通过非阻塞 I/O、事件驱动和单线程模型,实现了高并发、高性能的服务器端 JavaScript 运行环境,特别适合 I/O 密集型的网络应用开发。