第一章 Java的IO演进之路

博客介绍了Unix中5种IO模型,包括阻塞式、非阻塞式、IO复用、信号驱动和异步IO,阐述了它们在进程应对数据未准备好时的不同处理方式。还提到了IO多路复用,早期用select,后因缺陷采用epoll,介绍了epoll的优点。

Unix中5种IO模型

  就网络通信而言,一次数据读入可以分为两个阶段,首先等待数据从网络中到达,到达后需要复制到内核的缓冲区中,第二个阶段是从内核的缓冲区复制到进程的缓冲区,复制到进程的缓冲区才算读取完毕。推广到所有IO,一次完整的IO读入分为两个阶段

  • 等待数据准备完毕
  • 把准备好的数据读到进程的内存空间

  各种IO模型的区别在于当一个进程读取的数据没有准备好的时候该进程如何应对

阻塞式IO

  等待数据准备阶段,进程会一直阻塞,直到数据准备好或者抛出异常。调用recvfrom默认是阻塞式调用,当fd对应的数据没有准备好recvfrom会一直阻塞。

非阻塞式IO

  recvfrom的非阻塞式调用,recvfrom对应的fd如果没有准备好数据,会返回EWOULDBLOCK,代表数据没有准备好,请求数据的进程不会阻塞而是立即返回。代表数据没有准备好。

IO复用模型 

  如果一个进程同时对多个fd感兴趣,可以把多个fd注册到select方法上,当注册的fd有数据准备好select会通知调用线程。广义而言这是一个阻塞模型,不同于阻塞IO,IO复用模型阻塞在select上,阻塞式IO阻塞在recvfrom上。 

  select的缺点在于如果轮询的文件描述符不够多,调用select的代价大于直接调用recvfrom的代价。且select能够同时监听的文件描述符的数量受限于内核的参数。

信号驱动IO模型

  当数据没有准备好的时候,调用进程直接返回。等数据准备好的时候通过一个信号通知调用进程。这种模型应该也是一种非阻塞的模型,毕竟在没有读到数据的时候进程没有阻塞。区别于上述非阻塞模型,这种模型只需要询问一次数据是否准备好,然后只需要等待信号通知而后再次调用recvfrom,而上述非阻塞模型需要在没有获得数据的时候一直循环读数据。

异步IO

  比信号驱动模型更高级,信号驱动模型中,进程在收到通知的是可以开始一个IO操作,异步IO模型中收到的通知是数据以及读取完毕。

  • 只有最后一种IO模型是异步的,前四种模型在真正的IO操作中会阻塞进程,异步IO收到信号后数据以及读到进程缓冲区了
  • 同步IO指在IO请求过程中进程阻塞,这个IO请求指的是在数据以及准备好了后真正执行recvfrom

 IO多路复用

  早期的IO多路复用技术采用select系统调用,由于select的一些固有缺陷如能够监听的最大文件数受限,后来采用epoll。其优点在于

  • 注册的fd不受限制,select默认最大能够注册的文件描述符为1024个
  • 效率不会因注册fd增多而降低。select会线性的扫描所有注册的fd,当注册的fd过一次线性扫描的时间会增加。epoll是一种“伪异步”,epoll依据fd上回调函数来实现。  

  

转载于:https://www.cnblogs.com/AshOfTime/p/10819785.html

<think>嗯,用户之前问过关于Java IO面试题的分类方法,现在他们想要一个学习IO的学习框架。我需要先回顾之前的对话,确保这次回答连贯。用户可能已经对IO的基础有了一定了解,现在需要一个系统的学习路径,帮助他们从基础到高级逐步掌握。 首先,用户提到“学习框架”,应该是指一个结构化的学习路线或者步骤。要考虑到不同层次的知识点,从基础概念到高级应用,可能还要包括实践和常见问题。同时,用户之前的问题涉及到分类,所以这次回答可能需要更详细的分阶段指导。 接下来,我需要确定用户的需求。他们可能正在准备面试,或者在实际开发中需要用到IO相关的知识。无论是哪种情况,一个清晰的学习框架可以帮助他们系统地掌握IO,而不仅仅是零散的知识点。需要涵盖Java IO的核心概念、NIO、设计模式、性能优化以及实际应用场景。 然后,思考如何组织内容。可能分为几个阶段,比如基础、进阶、高级,每个阶段包含理论、实践和重点。还要加入常见问题解析,帮助用户应对面试中的难点。此外,结合设计模式和版本演进的内容,可以加深理解,这也是用户之前提到的分类方法。 还要注意用户可能遇到的困难,比如理解阻塞与非阻塞的区别,或者如何高效处理大文件。因此,在学习框架中需要强调这些重点,并提供解决方法。同时,推荐一些工具和资源,比如使用JUnit进行测试,或者使用VisualVM分析性能,这些都能帮助用户更好地实践。 最后,确保整个框架逻辑清晰,易于记忆。可能需要用一些口诀或对比记忆的方法,比如用户之前提到的“字节字符分两头,节点包装叠高楼”。这样用户可以通过关联实际场景和对比不同技术点来加深记忆。 总结下来,学习框架需要分阶段、结合理论与实践、涵盖重点和常见问题,并且提供记忆技巧和工具推荐。这样用户才能系统地掌握Java IO,应对面试和实际开发中的挑战。</think>好的!以下是一个针对 **Java IO/NIO** 的 **结构化学习框架**,帮助你由浅入深系统掌握核心知识点,同时结合实践和常见面试问题,提升理解和应用能力。 --- ### **一、基础阶段:理解核心概念与基础API** **目标**:掌握IO的基础分类、API使用和基础问题处理 **核心内容**: 1. **IO流分类** - **按数据方向**:输入流(`InputStream/Reader`) vs 输出流(`OutputStream/Writer`) - **按数据类型**:字节流(`InputStream/OutputStream`) vs 字符流(`Reader/Writer`) - **按功能角色**:节点流(直接操作资源,如`FileInputStream`) vs 包装流(增强功能,如`BufferedInputStream`) 2. **常用API与场景** - 文件读写:`FileInputStream`/`FileReader` + `BufferedXXX` - 控制台输入:`System.in` → `Scanner`或`BufferedReader` - 对象序列化:`ObjectInputStream`/`ObjectOutputStream` 3. **必会基础问题** - 为什么字符流需要指定编码(如`UTF-8`)? - 为什么必须调用`close()`或使用`try-with-resources`? - `flush()`方法的作用是什么?何时需要调用? **实践任务**: - 用字节流和字符流分别实现文件复制,对比性能差异。 - 使用`BufferedReader`逐行读取大文件并统计行数。 --- ### **二、进阶阶段:掌握NIO与性能优化** **目标**:理解NIO的核心设计、非阻塞模型和高性能原理 **核心内容**: 1. **NIO三大核心** - **Buffer(缓冲区)**:`ByteBuffer`的`allocate()`、`put()`、`flip()`、`clear()` - **Channel(通道)**:`FileChannel`、`SocketChannel`,零拷贝(`transferTo/From`) - **Selector(选择器)**:多路复用机制(单线程管理多个Channel) 2. **同步/异步与阻塞/非阻塞** - **BIO**:阻塞式(每个连接一个线程,适合低并发) - **NIO**:非阻塞+多路复用(单线程处理多连接,适合高并发) - **AIO**:异步回调(Java 7+,如`AsynchronousFileChannel`) 3. **性能优化技巧** - 缓冲区大小设置(经验值:8KB~64KB) - 内存映射文件(`MappedByteBuffer`,适合超大文件随机访问) - 零拷贝技术(减少数据在用户态和内核态的拷贝次数) **实践任务**: - 用`FileChannel`实现文件复制,对比传统IO的性能。 - 用`Selector`模拟一个简单的NIO服务器,处理多客户端请求。 --- ### **三、高级阶段:设计模式与源码分析** **目标**:理解Java IO的设计思想,关联源码和设计模式 **核心内容**: 1. **设计模式应用** - **装饰者模式**:`BufferedInputStream`包装`FileInputStream` - **适配器模式**:`InputStreamReader`(字节流→字符流适配) - **工厂模式**:`Files.newInputStream()`隐藏具体实现类 2. **源码分析重点** - `BufferedInputStream`的缓冲区实现(`byte[] buf`) - `FileInputStream`的`read()`方法如何调用Native方法 - NIO中`Selector`底层实现(Linux的`epoll`,Windows的`IOCP`) **实践任务**: - 自定义一个装饰者类,为流添加加密/解密功能。 - 通过断点调试追踪`FileInputStream.read()`的调用链。 --- ### **四、实战与面试重点** **目标**:结合高频面试题和实际开发场景,巩固知识 **核心内容**: 1. **高频面试题** - BIO vs NIO vs AIO的区别? - 什么是零拷贝?如何实现? - 内存溢出问题:未关闭流导致`Too many open files`如何排查? 2. **实际场景解决方案** - 大文件分片读取(避免OOM) - 网络通信中的粘包/拆包问题(NIO+自定义协议) - 高并发文件上传(NIO+线程池) 3. **工具与调试技巧** - 使用`lsof`命令(Linux)排查未关闭的文件描述符。 - 通过`jstack`分析线程阻塞问题。 --- ### **五、学习路线图** ```markdown 1. 基础API → 2. 流分类与设计模式 → 3. NIO核心 → 4. 性能优化 → 5. 源码与实战 → 6. 面试题梳理 ``` --- ### **六、辅助工具与资源** 1. **调试工具** - IDEA断点调试(查看缓冲区状态) - Wireshark(分析网络IO数据流) 2. **学习资源** - 书籍:《Java核心技术卷II》(第2章)、《Netty权威指南》 - 视频:B站NIO原理剖析、Netty源码解读 3. **代码实践** - GitHub搜索关键词:Java IO/NIO Demo、File Upload Optimization --- ### **记忆技巧** - **口诀记忆**: “字节字符分两头,节点包装叠高楼;NIO三件套(Buffer/Channel/Selector),高并发不用愁。” - **对比记忆**: - `InputStream`读字节,`Reader`读字符; - BIO阻塞等数据,NIO轮询查状态。 --- 通过这个框架,你可以 **层层递进**,从基础API到源码设计,最终串联起整个Java IO/NIO知识体系,同时通过实践和面试题巩固理解!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值