《Java 核心技术面试》课程笔记(十一)
Java 提供了哪些 IO 方式?
典型回答
Java IO 基于不同的 IO 抽象模型和交互方式,可以分为:
BIO,传统的 java.io 包,它基于流模型实现。
提供了我们最熟知的⼀些 IO 功能,比如 File 抽象、输入输出流等。 交互方式是同步 、阻塞 的方式,也就是说,在读取输入流或者写入输出流时,在读、写动作完成之前,线程会⼀直阻塞在那里,它们之间的调用是可靠的线性顺序。 java.net 提供的部分网络 API,比如 Socket、ServerSocket、HttpURLConnection 也归类到同步阻塞 IO 类库,因为网络通信同样是 IO 行为。 NIO,java.nio 包,提供了 Channel、Selector、Buffer 等新的抽象。
可以构建多路复用 的、同步非阻塞 IO 程序 。 同时提供了更接近操作系统底层的高性能数据操作方式。 AIO(Asynchronous IO),也就是 NIO 2,引入了异步非阻塞 IO 方式。
异步 IO 操作基于事件和回调机制。 应用操作直接返回,而不会阻塞在那里,当后台处理完成,操作系统会通知相应线程进行后续工作。
考点分析
在实际面试中,从传统 IO 到 NIO、NIO 2,其中有很多地方可以扩展开来,考察点涉及方方面面:
基础 API 功能与设计,InputStream/OutputStream 和 Reader/Writer 的关系和区别。 NIO、NIO 2 的基本组成。 给定场景,分别用不同模型实现,分析 BIO、NIO 等模式的设计和实现原理。 NIO 提供的高性能数据操作方式是基于什么原理,如何使用? 从开发者的角度来看,你觉得 NIO 自身实现存在哪些问题?有什么改进的想法吗?
知识扩展
区分同步或异步(synchronous/asynchronous)。
简单来说,同步是⼀种可靠的有序运行机制,当我们进行同步操作时,后续的任务是等待当前调用返回,才会进行下⼀步; 异步则相反,其他任务不需要等待当前调用返回,通常依靠事件、回调等机制来实现任务间次序关系。 区分阻塞与非阻塞(blocking/non-blocking)。
在进行阻塞操作时,当前线程会处于阻塞状态,无法从事其他任务,只有当条件就绪才能继续,比如 ServerSocket 新连接建立完毕,或数据读取、写入操作完成; 非阻塞则是不管 IO 操作是否结束,直接返回,相应操作在后台继续处理。 不能⼀概而论认为同步或阻塞就是低效,具体还要看应用和系统特征。
IO 不仅仅是对文件的操作,网络编程中,比如 Socket 通信,都是典型的 IO 操作目标。 输入流、输出流(InputStream/OutputStream)是用于读取或写入字节的,例如操作图片文件。 Reader/Writer 则是用于操作字符,增加了字符编解码等功能,适用于类似从文件中读取或者写入文本信息,本质上计算机操作的都是字节。 BufferedOutputStream 等带缓冲区的实现,可以避免频繁的磁盘读写,进而提高 IO 处理效率。这种设计利用了缓冲区,将批量数据进行⼀次操作,但在使用中千万别忘了 flush。 Java NIO 多路复用机制
Buffer,高效的数据容器,除了布尔类型,所有原始数据类型都有相应的 Buffer 实现。 Channel,类似在 Linux 之类操作系统上看到的文件描述符,是 NIO 中被用来支持批量式 IO 操作的⼀种抽象。 Selector,是 NIO 实现多路复用的基础,它同样是基于底层操作系统机制,可以检测到注册在 Selector 上的多个 Channel 中,是否有 Channel 处于就绪状态,进而实现了单线程对多 Channel 的高效管理。 NIO 利用了单线程轮询事件的机制,通过高效地定位就绪的 Channel,来决定做什么,仅仅 select 阶段是阻塞的,可以有效避免大量客户端连接时,频繁线程切换带来的问题,应用的扩展能力有了非常大的提高。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/551614.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!