什么是全双工和半双工?
一则或许对你有用的小广告
欢迎加入小哈的星球,你将获得:专属的实战项目(4个项目都能学) / 1v1 提问 / 简历修改 / Java 学习路线 / 社群讨论 / 学习打卡 / 每月赠书
《Spring AI 项目实战(问答机器人、RAG 智能客服、联网搜索)》已完结,基于
Spring AI + Spring Boot 3.x + JDK 21...,查看介绍《从零手撸:仿小红书(微服务架构)》 已完结,基于
Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...,查看介绍;演示链接:http://116.62.199.48:7070/《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接:http://116.62.199.48/
新开坑项目:《从零手撸:秒杀系统高并发优化实战》 正在更新中...,查看介绍
截止目前,星球内专栏累计输出 150w+ 字,讲解图 5110+ 张,还在持续爆肝中.. 后续还会上新更多项目,已有 4700+ 小伙伴加入学习,欢迎点击围观
面试考察点
-
基础掌握度:光会背定义不够,得能把单工、半双工、全双工三种通信方式讲清楚,再各自配上贴切的例子。
-
概念边界意识:这题名义上归操作系统,实为通信模式问题。如果你能主动点破这一点,再关联到进程间通信里的管道、TCP 连接,面试官立马知道你不是死记硬背的。
-
技术延伸能力:概念本身不难,面试官真正的杀招在后头——“TCP 是全双工还是半双工?”“为什么挥手要四次?”答得出延伸题,这题才算赚到。
核心答案
一句话:半双工是 “你先说,说完我再说”;全双工是 “咱俩同时说,互不耽误”。再把单工拉进来,三个概念一张表看全:
| 通信方式 | 传输方向 | 能否同时收发 | 生活例子 | 技术例子 |
|---|---|---|---|---|
| 单工(Simplex) | 只能单向 | — | 广播、电视 | 键盘 → 主机、SSE 推送 |
| 半双工(Half-Duplex) | 双向但分时 | ❌ 不能 | 对讲机 | 早期共享式以太网(CSMA/CD)、I2C 总线 |
| 全双工(Full-Duplex) | 双向且同时 | ✅ 能 | 打电话 | 交换机以太网、TCP、WebSocket |
深度解析
一、三种模式到底差在哪
- 单工:只修了单行道,数据从头到尾一个方向流。广播电台播什么你听什么,你想插话?没门。
- 半双工:一条独木桥,两头都能过,但同一时刻只允许一头走。对讲机就是这个理,一方按住讲话键时另一方只能听,所以老电影里总有人喊 "Over",提醒对方 “我说完了,该你了”。
- 全双工:双向车道,同时通行。打电话时你俩可以同时开口——虽然同时说话容易吵架,但信道本身完全支持。
二、半双工不是设计失误,是省钱的艺术
为什么早期的网络要搞半双工?穷。一根同轴电缆总线上挂着几十台机器,所有人共享同一条信道,谁都能发,那撞车了怎么办?这就轮到 CSMA/CD(载波监听多路访问/冲突检测)出场:发之前先听一听,没人才开口;发的时候还竖着耳朵,发现信号叠在一起了就立刻闭嘴,各自退避一个随机时间再重试。
后来以太网怎么进化到全双工的?两条路一起走:
- 物理层升级:100BASE-TX 的双绞线直接用 2 对线,一对专门发、一对专门收,物理上就是全双工;1000BASE-T 更狠,4 对线全部同时双向收发,靠回波抵消技术把自家发出去的信号从收到的混合信号里抠掉。
- 交换机登场:每台机器独享一个端口,冲突域直接消失,CSMA/CD 也就失业了——现代交换机网络里这机制基本退场。
三、回到操作系统:管道就是现成的例子
这道题既然挂在操作系统名下,那就得拿出点操作系统里的例子:
- 匿名管道(
pipe()):连半双工都算不上,是纯单工。数据只能从写端流向读端(典型场景:父进程写、子进程读)。想要双向通信?老老实实建两根管道。 - TCP Socket:全双工。同一条连接上读写互不干扰,收发缓冲区各自独立。来看段 Java 代码直观感受下:
// TCP 是全双工的:同一个 Socket 上,读和写互不阻塞
try (Socket socket = new Socket("127.0.0.1", 8080)) {
// 线程 1:专门负责写(发送数据)
new Thread(() -> {
try {
socket.getOutputStream().write("hello".getBytes());
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}).start();
// 主线程:同时在读(接收数据)
// 两个方向各干各的,互不耽误——这就是全双工在应用层的直观体现
socket.getInputStream().read();
}
如果是半双工,你就得停下来商量 “现在谁说话”,就像对讲机一样,读写不能并行。
四、TCP 的全双工藏在哪
这是这道题最有价值的延伸,面试官特别爱往这儿引:
- 收发缓冲区独立:TCP 连接两端各有独立的发送缓冲区和接收缓冲区,两个方向的数据流互不干扰。
- 四次挥手的由来:正因为是全双工,断开连接时两个方向要分别关。我收到你的 FIN,只代表你不发了,我这边可能还有数据没吐完,所以 ACK 必须先回,我的 FIN 得等数据发完再补——两件事经常合并不了,这就是四次。顺带一提,
shutdown()方法支持只关闭一个方向,这叫半关闭,也是全双工特有的玩法。 - 应用层的对照:HTTP/1.1 一问一答、答完才能再问,用起来像半双工(底层 TCP 仍是全双工);WebSocket 握手完成后双方随时互推,是应用层真正的全双工;SSE 只能服务端往客户端单向推,算单工风格。
常见误区
- “HTTP 是半双工协议”——要分层次说。HTTP 跑在 TCP 上,传输层是全双工;只是 HTTP/1.1 的请求-响应语义是串行的,用起来像半双工。
- “半双工就是速度砍一半”——不是。半双工说的是同一时刻只允许一个方向传输,跟信道的带宽容量没关系。
- 把管道说成半双工——管道是单工(单向),半双工好歹还能换向,管道连换向都不行。
面试高频追问
-
TCP 为什么是全双工?体现在哪?
- 收发缓冲区独立、连接状态双向各自维护、断连时每个方向单独关闭。
-
四次挥手为什么不能压缩成三次?
- 被动方收到 FIN 时可能还有数据没发完,ACK 必须立刻回,FIN 得等数据发完才能发,两步经常合不到一起去。
-
WebSocket 和 HTTP 轮询的区别?
- 轮询是客户端反复问 “有了吗”,服务器被动回答;WebSocket 握手一次升级成功后,双方都能主动推,实时性和开销都完胜。
常见面试变体
- 变体一:单工、半双工、全双工分别是什么?请举例说明。
- 变体二:TCP 是全双工还是半双工?依据是什么?
- 变体三:匿名管道是单工、半双工还是全双工?
记忆口诀
广播只能听(单工),对讲机轮流讲(半双工),打电话随便插话(全双工)。
总结
半双工双向但分时,全双工双向且同时。答这题时把 TCP 的全双工、四次挥手、管道的单工一起带出来,顺手把延伸分也拿了。
