Java NIO详解与Netty面试关键点

需积分: 10 0 下载量 58 浏览量 更新于2024-09-05 收藏 471KB PDF 举报
"这份PDF是关于Netty面试的专题,涵盖了Java面试中关于NIO的知识点,适合于Java学习者和开发者,旨在帮助提升面试准备和技能水平。" Netty是一个高性能、异步事件驱动的网络应用程序框架,常用于创建高并发、低延迟的服务器,尤其在处理网络协议和I/O操作时表现出色。Java BIO(Blocking I/O)和NIO(Non-blocking I/O)是两种不同的I/O模型,它们有着显著的区别。 1. **BIO与NIO对比** - **面向流与面向缓冲区**:BIO是面向流的,即数据按顺序逐个字节读写,而NIO是面向缓冲区的,数据一次性读写多个字节。 - **阻塞与非阻塞**:BIO的读写操作是阻塞的,一旦执行就会一直等待,直到数据读取完毕或写入完成。NIO则是非阻塞的,当数据未准备好时,读写操作不会立即返回,而是允许其他操作继续进行。 - **单向与双向**:BIO的Stream是单向的,数据只能单向流动。而NIO的Channel是双向的,可以同时进行读写操作。 2. **NIO特点** - **事件驱动模型**:NIO采用事件驱动的方式,通过Selector监听通道状态,当通道准备好读写时,Selector会通知用户程序进行相应的操作。 - **单线程处理多任务**:利用Reactor线程模型,一个线程可以处理多个通道的事件,提高资源利用率。 - **非阻塞I/O**:读写操作不会阻塞,提高系统响应速度。 - **基于Block的传输**:基于块的传输效率高于基于流,因为减少了数据复制次数。 - **Zero-copy(零拷贝)**:NIO支持零拷贝技术,减少了CPU在用户态和内核态之间复制数据的开销。 - **IO多路复用**:Selector可以同时监控多个通道,实现多路复用,增加系统扩展性。 3. **NIO组件** - **Buffer**:数据交换的核心,提供了一种有限容量的线性数据结构,通过flip、clear、rewind等方法切换读写模式并管理数据。 - **DirectByteBuffer**:直接在物理内存中分配,减少了Java堆与操作系统之间的数据拷贝,适用于大容量数据。 - **HeapBuffer**:在Java堆中分配,适用于小数据量的场景。 - **Channel**:双向数据通道,连接I/O源和目标,但不直接处理数据,而是通过Buffer进行数据交互。 - **Selector**:多路复用器,负责监听和选择准备好的通道,允许一个线程处理多个通道的事件。 - **SelectionKey**:Selector与SelectableChannel之间的注册关系,记录了注册的事件类型(如读、写、连接、接受)。 4. **Reactor模式** - Reactor模式是NIO的核心设计模式,其工作流程包括:注册事件处理器、事件分发器等待事件、事件触发后调用处理器、处理器完成操作后返回控制权。 了解并熟练掌握这些NIO概念和技术,对于理解Netty框架的运行机制以及在面试中展示Java网络编程能力至关重要。在实际开发中,根据具体应用场景选择合适的I/O模型和数据管理方式,能有效优化系统性能。

com.fmall58.wechatsub.business.bizs.UException at com.fmall58.wechatsub.business.service.PubService.isBindWeChatSub(PubService.java:76) at com.fmall58.wechatsub.business.bizs.PubHelper.isBindWeChatSub(PubHelper.java:125) at com.fmall58.wechatsub.business.bizs.PubHelper.execute(PubHelper.java:38) at com.fmall58.wechatsub.server.handlers.ServerHandler.channelRead(ServerHandler.java:103) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:102) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:323) at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:297) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1434) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:965) at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163) at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:656) at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:591) at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:508) at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:470) at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:909) at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)

2023-06-11 上传