共 15 道 Node.js 方向的面试题,每题附完整答案与代码示例。点击右侧方框可标记掌握度。
Node.js 基于 libuv 实现事件循环,把回调按阶段(phase)依次执行,每个阶段有自己的 FIFO 队列: 微任务 在两个节点之间、每个阶段切换前清空(全清空,不是只取一个): - pro…
CommonJS(CJS) :同步 require,模块是对象,运行时加载,可动态条件引入。 ESM :静态 import/export,编译期分析,支持 Tree Shaking,顶层 this 为…
Stream 是 边读边处理 的数据抽象,不用把整份数据一次性载入内存。四种类型: - Readable(可读,如文件读取) - Writable(可写,如下载落盘) - Duplex(双向,如 so…
Buffer 是 Node 对 二进制数据 的直接内存视图(类似 Uint8Array),用于处理网络包、文件、图片等非文本字节。 区别 : - String 是字符序列(UTF-16),关心「语义字…
演进:回调 → Promise → async/await。 现在推荐 fs/promises + async/await ,可读性好、便于 try/catch 统一错误处理。回调式 API(fs.r…
Node 主线程单线程,但可通过 多进程/多线程 利用多核: - cluster :fork 出多个子进程(每个进程一个 Event Loop),共享同一端口,主进程做负载均衡。适合 CPU 密集的 …
process 是全局对象,提供环境信息与控制: - process.env:环境变量(NODE ENV 等),生产环境务必读取 - process.argv:命令行参数(argv[2] 起是自定义参…
常见原因 : 1. 全局变量 / 闭包长期引用大对象 2. 忘记清理的监听器(EventEmitter 反复 on 不 off) 3. 缓存(Map/数组)只增不删,无上限 4. 定时器(setInt…
三者都用于启动子进程,差异在 流式 vs 缓冲、是否走 shell : - exec(cmd, cb):通过 shell 执行整条命令,输出 缓冲 到内存(默认 1MB 上限),适合短输出命令;回调拿…
必须兜底的两类 : - uncaughtException:同步代码未捕获异常 - unhandledRejection:Promise 拒绝未被 catch 最佳实践 :监听只是最后防线, 真正的修…
require 加载模块后会把 module.exports 缓存到 require.cache 中, 同进程内第二次 require 直接返回缓存 (不会重复执行文件),因此模块顶层代码只跑一次。 …
常用手段: 1. perf hooks :在代码内埋点测耗时 2. CPU Profiling :node --prof app.js 生成 -v8.log,用 --prof-process 或 ch…
EventEmitter 本质是 发布-订阅 :内部维护 事件名 → 回调数组 的 Map,on 注册、emit 触发、off 移除。 注意点 : - 内存泄漏高发区 :on 后若不再 off,且 e…
- setTimeout(fn, 0) 实际延迟约 1ms(小于 1 会被提升到 1),且受 Event Loop 阶段调度影响,不准 - setInterval 的回调 不会累加排队 :若单次执行超…
http 原生模块只提供底层请求/响应对象,路由、body 解析、中间件全要自己写: 对比框架 : - Express :基于回调的中间件队列(app.use),生态最大,但洋葱模型不彻底 - Koa…