前端进阶之旅前端进阶之旅
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
首页程序员面试题库Node.js stream 四种流类型 Readable Writable Duplex Transform
NoNode.js流与二进制

Node.js 的 Readable、Writable、Duplex、Transform 分别解决什么问题?

判断流类型时,从使用者能读什么、能写什么开始,再看写入数据与读出数据有没有转换关系。

前端进阶之旅 · 一题精讲更新于 2026.09.06
Node.js#流与二进制#流处理
先看核心答案
理解线索

先看方向,再看两侧关系

  1. 单向接口Readable 供读取,Writable 接收写入
  2. 双向接口Duplex 同时提供读写,两个方向可以相对独立
  3. 转换接口Transform 将写入的输入加工为可读取的输出

流不等于文件,也不等于一次拿到全部数据。网络、压缩、加密和内存中的分段处理都可以使用相同的流接口。

核心回答

先记住这个答案

Readable 提供数据供消费者读取,Writable 接收写入数据,Duplex 同时具有可读与可写两侧,而 Transform 是一种特殊 Duplex,读出数据由写入数据经过转换产生。网络 socket 的收发可以相对独立,压缩流则体现输入到输出的转换关系。双工并不意味着两侧共享同一缓冲或同时结束;四种类型都要考虑错误、背压与资源生命周期,objectMode 只是改变传输单位,不是额外一种流方向。

  • 可读与可写以流消费者的视角判断
  • Transform 是具有转换关系的双工流
  • 双工两侧的缓冲和完成状态要分别理解

可读和可写描述的是调用方能力

文件读取流向调用方提供文件内容,因此是 Readable;文件写入流接收调用方交来的内容,因此是 Writable。不要从磁盘或远端服务的视角反过来命名,否则分析 HTTP 请求和响应时很容易混淆方向。

Readable 可以通过异步迭代、pipe 或事件等方式消费,Writable 通过 write 和 end 接收数据。消费方式与流类型是不同维度,同一个可读流不因为选择 data 事件就变成另一种类型。

Duplex 与 Transform 的关键差别是数据关系

TCP socket 可以一边接收远端消息,一边发送本地消息,两边内容不必一一对应。Transform 则通过转换逻辑把写入输入变成读出结果,例如压缩数据、解析记录或过滤内容,因此适合放在处理链中间。

转换也不保证一个输入 chunk 对应一个输出 chunk。压缩或分帧可能缓存多个输入后输出一段,也可能把一段输入拆成多个结果;业务协议不能把 chunk 数量当作记录数量或请求数量。

双工两侧与对象模式需要独立预算

Duplex 和 Transform 的可读、可写两侧各有状态与缓冲。写入端完成不代表读出结果已被消费者拿完;如果输出无人消费,转换链也可能因背压停住,不能只观察输入已经写完。

objectMode 允许把非 null 的 JavaScript 值作为对象单位传递,并按对象数量管理相关阈值,但对象大小仍会影响内存。传输大对象并不会因为计数只有几个就变得便宜,生命周期和总量预算仍需设计。

回答前,多想一步

容易答错的地方

认为 Duplex 的输出一定来自输入转换
这正是需要区分普通双工与转换流的原因。网络收发可以独立,而转换流定义了加工关系;选错抽象可能把协议通信硬写成数据转换,导致完成条件和错误处理难以表达。
把 objectMode 当作不会占内存的消息通道
对象模式改变计量单位,不会限制每个对象占用的内存,也不会自动复制或验证业务对象。应控制对象规模与队列长度,避免把整份大型数据塞进一个对象来绕过看起来很小的数量阈值。
试着用自己的话回答

面试官还会怎么问?

Transform 的 finish 和 end 为什么可能不同步?

finish 关注写入侧完成,end 关注可读侧已经被消费完。转换结果可能还在可读缓冲里,因此需要按照任务目标等待相应两侧,不能把写入侧完成直接当成整条数据链已经交付。

读取 HTTP 请求体与写响应属于什么方向?

在 Node 原生服务端,传入请求可作为可读来源消费请求体,响应对象则接收服务端写出的响应数据。实际网络连接本身具有双向能力,但请求和响应封装给调用方的接口职责不同。

为什么学习类型之后还要学习 pipeline?

类型只描述接口与方向,多个流连接之后还需要处理背压、结束、错误传播和清理。pipeline 提供整条链的管理能力,但外部文件或业务事务仍有各自责任,不能只会连接箭头就忽略失败路径。

从一道题,走向一组知识

把知识连起来

流与二进制

pipe 与 pipeline 在错误传播和资源清理上有什么区别?

把不同方向的流连接起来,并管理整条链的失败。

流与二进制

stream.finished、end、finish 和 close 分别说明什么完成状态?

分别判断读写完成、资源关闭和异常中止。

流与二进制

Node.js 流的 highWaterMark 怎么调,越大吞吐就越高吗?

根据字节或对象模式设置实际缓冲预算。

参考资料

  • Node.js 22:Types of streams

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. 可读和可写描述的是调用方能力
  3. Duplex 与 Transform 的关键差别是数据关系
  4. 双工两侧与对象模式需要独立预算
  5. 容易答错的地方
  6. 面试官还会怎么问
  7. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑