面试知识库

TCP 三次握手 → Socket → Netty 追问链#

追问路径#

涉及知识点#

核心串联逻辑#

  1. TCP握手建立可靠连接后,服务端accept()返回Socket
  2. BIO → NIO:BIO一连接一线程上限约1万(线程栈~1MB×10000=10GB);NIO通过Selector一线程管多连接
  3. epoll优势:O(1)事件通知(vs select O(n)),无fd数量限制(vs select 1024),ET模式减少事件触发次数
  4. Netty封装:解决JDK NIO的epoll空轮询bug,提供主从Reactor线程模型,池化内存管理
  5. 堆外内存:DirectByteBuffer绕过JVM堆,Socket读写少一次从堆到native的memcpy
  6. 代码示例
    // Netty主从Reactor典型配置
    EventLoopGroup bossGroup = new NioEventLoopGroup(1);     // accept线程
    EventLoopGroup workerGroup = new NioEventLoopGroup();     // 默认CPU*2
    ServerBootstrap b = new ServerBootstrap();
    b.group(bossGroup, workerGroup)
     .channel(NioServerSocketChannel.class)
     .childHandler(new ChannelInitializer<>() { /* Pipeline配置 */ });
    java

面试回答串联#

30秒速答#

“TCP三次握手建连后,BIO每连接一线程上限约1万。NIO通过Selector多路复用让单线程管多连接。Linux上epoll用红黑树+就绪链表实现O(1)事件通知。生产用Netty的主从Reactor——BossGroup负责accept,WorkerGroup负责IO读写。“

2分钟展开答#

“TCP三次握手确认双方收发能力后建立连接。传统BIO模型每个连接一个线程阻塞读写,线程栈约1MB,1万连接就需要10GB内存,实际上限约1万连接。NIO通过Selector多路复用让一个线程监听多个Channel的IO事件。Linux上epoll用红黑树管理fd+就绪链表存储就绪事件,事件通知是O(1)而select是O(n),也没有1024的fd数量限制。epoll有LT(水平触发)和ET(边缘触发)两种模式,Netty在Linux上用ET模式性能更高。为什么不直接用Java NIO?因为JDK的Selector有epoll空轮询bug会导致CPU 100%,Netty自动检测并重建Selector解决了这个问题。Netty的线程模型是主从Reactor——BossGroup 1-2个线程负责accept新连接,WorkerGroup默认CPU核数×2个线程处理IO读写,Handler链式处理业务。内存管理上Netty用PooledByteBufAllocator池化+堆外内存(DirectByteBuffer),减少用户态到内核态的一次memcpy。“

相关追问链#