粉粉蕉的笔记本粉粉蕉的笔记本
  • JAVA

    • 代码笔记
    • Java8实战
    • 分布式事务实战(Seata)
    • 模板引擎(FreeMarker)
    • SpringSecurity
    • Maven
  • PYTHON

    • 概述
    • python3
    • python3(菜鸟教程)
    • pandas
    • numpy
    • matplotlib
  • 中间件

    • Kafka
    • RocketMQ
    • Redis
    • MongoDB
    • Elastic Search
  • 数据库

    • Mysql
  • 前端

    • HTML
    • CSS
    • Javascript
    • Vue2学习笔记
    • Vue3学习笔记
  • 设计模式
  • 大数据

    • 概览
    • Hadoop
    • Hive
  • 机器学习

    • 机器学习概览
  • openclaw实战
  • claudecode实战
  • RAG
  • 拟人类Agent
  • linux命令速查
  • windows命令速查
  • Docker笔记
  • kubernetes学习笔记
  • kubernetes实操笔记
  • 运维工具大全
  • git操作宝典
  • 概率论
  • 线性代数
  • 统计学
  • 金融知识学习
  • 聚宽
  • 因子分析
  • 后端

    • JAVA基础
    • JAVA多线程
    • JVM
    • 分布式相关
    • 数据库
  • 前端

    • HTML
    • CSS
    • JAVASCRIPT
    • VUE3
    • 网络
    • 前端工程化
    • nodejs
  • AI

    • RAG
  • 健身

    • 笔记
    • 训练计划
  • 读书笔记

    • 《深度学习》
  • 其他

    • RSS
    • 资源导航
    • 医保
    • 装修攻略
我也想搭建这样的博客!
🚋开往
  • JAVA

    • 代码笔记
    • Java8实战
    • 分布式事务实战(Seata)
    • 模板引擎(FreeMarker)
    • SpringSecurity
    • Maven
  • PYTHON

    • 概述
    • python3
    • python3(菜鸟教程)
    • pandas
    • numpy
    • matplotlib
  • 中间件

    • Kafka
    • RocketMQ
    • Redis
    • MongoDB
    • Elastic Search
  • 数据库

    • Mysql
  • 前端

    • HTML
    • CSS
    • Javascript
    • Vue2学习笔记
    • Vue3学习笔记
  • 设计模式
  • 大数据

    • 概览
    • Hadoop
    • Hive
  • 机器学习

    • 机器学习概览
  • openclaw实战
  • claudecode实战
  • RAG
  • 拟人类Agent
  • linux命令速查
  • windows命令速查
  • Docker笔记
  • kubernetes学习笔记
  • kubernetes实操笔记
  • 运维工具大全
  • git操作宝典
  • 概率论
  • 线性代数
  • 统计学
  • 金融知识学习
  • 聚宽
  • 因子分析
  • 后端

    • JAVA基础
    • JAVA多线程
    • JVM
    • 分布式相关
    • 数据库
  • 前端

    • HTML
    • CSS
    • JAVASCRIPT
    • VUE3
    • 网络
    • 前端工程化
    • nodejs
  • AI

    • RAG
  • 健身

    • 笔记
    • 训练计划
  • 读书笔记

    • 《深度学习》
  • 其他

    • RSS
    • 资源导航
    • 医保
    • 装修攻略
我也想搭建这样的博客!
🚋开往

Node.js 面试题

⭐Node.js 是什么?有哪些特点?

Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时环境,让 JavaScript 可以在服务端运行。

核心特点:

特点说明
单线程主线程只有一个,避免线程切换开销
事件驱动基于事件循环(Event Loop)处理请求
非阻塞 I/OI/O 操作异步执行,不阻塞主线程
高并发适合 I/O 密集型场景(网络请求、文件读写)
跨平台支持 Windows、Linux、macOS
npm 生态拥有世界最大的开源包仓库

不适合的场景: CPU 密集型任务(大量计算),因为单线程会被阻塞。


⭐Node.js 的事件循环(Event Loop)是什么?

Node.js 的事件循环基于 libuv 库实现,分为多个阶段:

   ┌─────────────────────────────┐
┌──┤         timers              │  ← setTimeout / setInterval 回调
│  └──────────────┬──────────────┘
│  ┌──────────────┴──────────────┐
│  │     pending callbacks       │  ← 上一轮延迟的 I/O 回调
│  └──────────────┬──────────────┘
│  ┌──────────────┴──────────────┐
│  │         idle, prepare       │  ← 内部使用
│  └──────────────┬──────────────┘
│  ┌──────────────┴──────────────┐
│  │            poll             │  ← 获取新的 I/O 事件(核心阶段)
│  └──────────────┬──────────────┘
│  ┌──────────────┴──────────────┐
│  │            check            │  ← setImmediate 回调
│  └──────────────┬──────────────┘
│  ┌──────────────┴──────────────┐
└──┤      close callbacks        │  ← socket.on('close') 等
   └─────────────────────────────┘

宏任务 vs 微任务:

类型示例执行时机
微任务(microtask)Promise.then、process.nextTick每个阶段切换之前清空
宏任务(macrotask)setTimeout、setInterval、setImmediate按阶段顺序执行

process.nextTick 优先级高于 Promise.then,在微任务队列中最先执行。

setTimeout(() => console.log('timeout'), 0)
setImmediate(() => console.log('immediate'))
Promise.resolve().then(() => console.log('promise'))
process.nextTick(() => console.log('nextTick'))

// 输出顺序:nextTick → promise → timeout/immediate(顺序不固定)

⭐Node.js 中 CommonJS 模块系统

Node.js 默认使用 CommonJS 模块规范:

// 导出(方式1:exports)
exports.add = (a, b) => a + b
exports.PI = 3.14159

// 导出(方式2:module.exports,可导出任意值)
module.exports = {
  add: (a, b) => a + b,
  PI: 3.14159
}

// 导出类
module.exports = class Calculator {
  add(a, b) { return a + b }
}
// 导入
const math = require('./math')
const { add, PI } = require('./math')
const Calculator = require('./calculator')

// 内置模块
const fs = require('fs')
const path = require('path')
const http = require('http')

CommonJS vs ES Module:

特性CommonJSES Module
语法require / module.exportsimport / export
加载时机运行时动态加载编译时静态分析
同步/异步同步异步
Tree Shaking不支持支持
文件扩展名.js.mjs 或 "type":"module"
this 指向module.exportsundefined

⭐常用的 Node.js 核心模块

fs(文件系统)

const fs = require('fs')
const fsPromises = require('fs/promises')

// 同步读取
const content = fs.readFileSync('./file.txt', 'utf8')

// 异步读取(回调)
fs.readFile('./file.txt', 'utf8', (err, data) => {
  if (err) throw err
  console.log(data)
})

// Promise 风格(推荐)
async function readFile() {
  const data = await fsPromises.readFile('./file.txt', 'utf8')
  console.log(data)
}

// 写入文件
await fsPromises.writeFile('./output.txt', 'Hello World')

// 读取目录
const files = await fsPromises.readdir('./src')

path(路径处理)

const path = require('path')

path.join('/foo', 'bar', 'baz')        // '/foo/bar/baz'
path.resolve('src', 'utils', 'index')  // 绝对路径
path.basename('/foo/bar/baz.txt')      // 'baz.txt'
path.extname('index.html')             // '.html'
path.dirname('/foo/bar/baz.txt')       // '/foo/bar'

// 常用:获取当前文件所在目录
const dir = path.dirname(__filename)
const fullPath = path.join(__dirname, 'config.json')

http(HTTP 服务)

const http = require('http')

const server = http.createServer((req, res) => {
  const { method, url } = req

  res.writeHead(200, { 'Content-Type': 'application/json' })
  res.end(JSON.stringify({ message: 'Hello World' }))
})

server.listen(3000, () => {
  console.log('Server running at http://localhost:3000')
})

stream(流)

const fs = require('fs')

// 读取流
const readStream = fs.createReadStream('./large-file.txt', { encoding: 'utf8' })
readStream.on('data', chunk => console.log(chunk))
readStream.on('end', () => console.log('读取完成'))

// 管道(pipe):读取文件 → 压缩 → 写入
const zlib = require('zlib')
fs.createReadStream('./input.txt')
  .pipe(zlib.createGzip())
  .pipe(fs.createWriteStream('./output.gz'))

⭐什么是 Express?如何搭建基本服务?

Express 是最流行的 Node.js Web 框架,提供路由、中间件等核心功能。

const express = require('express')
const app = express()

// 内置中间件
app.use(express.json())                          // 解析 JSON 请求体
app.use(express.urlencoded({ extended: true }))  // 解析表单数据
app.use(express.static('public'))                // 静态文件服务

// 路由
app.get('/users', async (req, res) => {
  const { page = 1, limit = 10 } = req.query    // 查询参数
  res.json({ users: [], page, limit })
})

app.get('/users/:id', (req, res) => {
  const { id } = req.params                      // 路径参数
  res.json({ id })
})

app.post('/users', (req, res) => {
  const { name, email } = req.body               // 请求体
  res.status(201).json({ id: 1, name, email })
})

// 错误处理中间件(4个参数)
app.use((err, req, res, next) => {
  console.error(err.stack)
  res.status(500).json({ error: err.message })
})

app.listen(3000, () => console.log('Server started on port 3000'))

Express 中间件机制:

// 中间件是带有 (req, res, next) 参数的函数
const logger = (req, res, next) => {
  console.log(`${req.method} ${req.url}`)
  next()  // 调用 next() 传递给下一个中间件
}

app.use(logger)

// 路由级中间件(仅对特定路由生效)
const authMiddleware = (req, res, next) => {
  const token = req.headers.authorization
  if (!token) return res.status(401).json({ error: 'Unauthorized' })
  next()
}

app.get('/profile', authMiddleware, (req, res) => {
  res.json({ user: 'me' })
})

⭐Node.js 如何处理异步操作?

Node.js 经历了三个阶段的异步处理方式:

1. 回调函数(Callback)- 早期方式

fs.readFile('./a.txt', 'utf8', (err, data1) => {
  if (err) return console.error(err)
  fs.readFile('./b.txt', 'utf8', (err, data2) => {
    // 回调地狱(Callback Hell)
    if (err) return console.error(err)
    console.log(data1 + data2)
  })
})

2. Promise - 改善可读性

const fsPromises = require('fs/promises')

fsPromises.readFile('./a.txt', 'utf8')
  .then(data1 => fsPromises.readFile('./b.txt', 'utf8').then(data2 => [data1, data2]))
  .then(([data1, data2]) => console.log(data1 + data2))
  .catch(err => console.error(err))

3. async/await - 推荐方式

async function readFiles() {
  try {
    const [data1, data2] = await Promise.all([
      fsPromises.readFile('./a.txt', 'utf8'),
      fsPromises.readFile('./b.txt', 'utf8')   // 并行读取
    ])
    console.log(data1 + data2)
  } catch (err) {
    console.error(err)
  }
}

⭐什么是 npm?常用命令有哪些?

npm(Node Package Manager):Node.js 的包管理器,用于安装、管理第三方依赖。

# 初始化项目
npm init -y

# 安装依赖
npm install express          # 安装到 dependencies
npm install -D eslint        # 安装到 devDependencies
npm install -g nodemon       # 全局安装

# 删除依赖
npm uninstall express

# 更新依赖
npm update
npm update express

# 查看已安装
npm list
npm list --depth=0           # 只看顶层

# 运行脚本
npm run dev
npm run build
npm start                    # 快捷方式

# 查看包信息
npm info express
npm outdated                 # 查看过期依赖

# 清除缓存
npm cache clean --force

package.json 重要字段:

{
  "name": "my-app",
  "version": "1.0.0",
  "scripts": {
    "start": "node index.js",
    "dev": "nodemon index.js",
    "build": "webpack --mode production"
  },
  "dependencies": {
    "express": "^4.18.0"     // ^ 允许次版本更新
  },
  "devDependencies": {
    "nodemon": "~3.0.0"      // ~ 只允许补丁版本更新
  },
  "engines": {
    "node": ">=18.0.0"
  }
}

⭐Node.js 中如何解决跨域问题?

// 方法1:手动设置 CORS 头
app.use((req, res, next) => {
  res.setHeader('Access-Control-Allow-Origin', '*')          // 或指定域名
  res.setHeader('Access-Control-Allow-Methods', 'GET,POST,PUT,DELETE,OPTIONS')
  res.setHeader('Access-Control-Allow-Headers', 'Content-Type,Authorization')
  if (req.method === 'OPTIONS') return res.sendStatus(204)   // 预检请求
  next()
})

// 方法2:使用 cors 中间件(推荐)
const cors = require('cors')

app.use(cors())  // 允许所有来源

// 精细配置
app.use(cors({
  origin: ['http://localhost:3000', 'https://myapp.com'],
  methods: ['GET', 'POST', 'PUT', 'DELETE'],
  allowedHeaders: ['Content-Type', 'Authorization'],
  credentials: true  // 允许携带 Cookie
}))

⭐Node.js 性能优化

  1. 使用 cluster 模块充分利用多核 CPU
const cluster = require('cluster')
const os = require('os')

if (cluster.isPrimary) {
  const numCPUs = os.cpus().length
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork()  // 创建子进程
  }
} else {
  // 每个子进程运行独立的 HTTP 服务
  const app = require('./app')
  app.listen(3000)
}
  1. 流式处理大文件(避免将整个文件加载到内存)
// 不推荐:内存占用大
const data = fs.readFileSync('./large-file.csv')

// 推荐:流式读取
fs.createReadStream('./large-file.csv').pipe(processStream).pipe(res)
  1. 缓存热点数据(Redis + 内存缓存)

  2. 避免同步 API(生产环境禁用 *Sync 方法)

  3. 使用 PM2 进程管理器(负载均衡、自动重启、日志管理)

pm2 start app.js -i max    # 开启 cluster 模式,使用所有 CPU
pm2 logs                   # 查看日志
pm2 monit                  # 监控面板
Last Updated: 6/26/26, 3:05 AM
Contributors: azil, dongyz8