Java中的IO与NIO⾯试题(15题)
再⽹上看了很多的java⾯试题,有很多都是零零碎碎的,有或者是需要付费加密 的,加个vip什么的,故⽽以下是博主整理的有关java⾯试题的以下内容,我想以⼀种幽默风趣 的风格来给⼤家分享和探讨。另外附加有⼀些公司的⾯试真题(内部分享)下⾯我就开启 ⽿机模式。并且 是重要部分,要记易考噢。
————————————————
1、Java 中 IO 流? .
Java 中 IO 流分为⼏种?
```css
1.按照流的流向分,可以分为输⼊流和输出流;
2.按照操作单元划分,可以划分为字节流和字符流;
3.按照流的⾓⾊划分为节点流和处理流。
Java Io 流共涉及 40 多个类,这些类看上去很杂乱,但实际上很有规则,⽽且彼此之间存在⾮常紧密的联系, Java I0 流的 40 多个类都是从如下 4个抽象类基类中派⽣出来的。
1. InputStream/Reader: 所有的输⼊流的基类,前者是字节输⼊流,后者是字符输⼊流。
2. OutputStre m/Writer: 所有输出流的基类,前者是字节输出流,后者是字符输出流。
2、 Java IO与 NIO的区别
NIO即New IO,这个库是在JDK1.4中才引⼊的。NIO和IO有相同的作⽤和⽬的,但实现⽅式不同,NIO主要⽤到的是块,所以NIO的效率要⽐IO⾼很多。在Jav a API中提供了两套NIO,⼀套是针对标准输⼊输出NIO,另⼀套就是⽹络编程NIO。
3、常⽤io类有那些
File
FileInputSteam,FileOutputStream
BufferInputStream,BufferedOutputSream
PrintWrite
FileReader,FileWriter
BufferReader,BufferedWriter
ObjectInputStream,ObjectOutputSream
4、字节流与字符流的区别
以字节为单位输⼊输出数据,字节流按照8位传输以字符为单位输⼊输出数据,字符流按照16位传输
5、阻塞 IO 模型
最传统的⼀种 IO 模型,即在读写数据过程中会发⽣阻塞现象。当⽤户线程发出 IO 请求之后,内核会去查看数据是否就绪,如果没有就绪就会等待数据就绪,⽽⽤户线程就会处于阻塞状态,⽤户线程交出CPU。当数据就绪之后,内核会将数据拷贝到⽤户线程,并返回结果给⽤户线程,⽤户线程才解除block 状态。典型的阻塞 IO 模型的例⼦为: data = ad();如果数据没有就绪,就会⼀直阻塞在 read ⽅法
6、⾮阻塞 IO 模型
⼜再次收到了⽤户线程的请求,那么它马上就将数据拷贝到了⽤户线程,然后返回。所以事实上,在⾮阻塞 IO 模型中,⽤户线程需要不断地询问内核数据是否就绪,也就说⾮阻塞 IO不会交出 CPU,⽽会⼀当⽤户线程发起⼀个 read 操作后,并不需要等待,⽽是马上就得到了⼀个结果。团整如果结果是⼀个 vip error 时,它就知道数据还没有准备好,于是它可以再次发送 read 操作。⼀旦内核中的数据准备好了,并且直占⽤ CPU。典型的⾮阻塞 IO 模型⼀般如下: .
while(true){  发  ycbbs
data = ad();
if(data!= error){ 研
/
/处理数据
break;
}
}
.
但是对于⾮阻塞IO就有⼀个⾮常严重的问题,在hile 循环中需要不断地去询问内核数据是否就绪,这样会导致 CPU 占⽤率⾮常⾼,因此⼀般情况下很少使⽤ w hile 循环这种⽅式来读取数据。
7、多路复⽤ IO 模型
多路复⽤ IO 模型是⽬前使⽤得⽐较多的模型。 Java NIO 实际上就是多路复⽤ IO。在多路复⽤ IO模型中,会有⼀个线程不断去轮询多个 socket 的状态,只有当 socket 真正有读写事件时,才真正调⽤实际的 IO 读写操作。因为在多路复⽤ IO 模型中,只需要使⽤⼀个线程就可以管理多个socket,系统不需要建⽴新的进程或者线程,也不必维护这些线程和进程,并且只有在真正有socket 读写事件进⾏时,才会使⽤ IO 资源,所以它⼤⼤减少了资源占⽤。在 Java NIO 中,是通过 selector.select()去查询
每个通道是否有到达事件,如果没有事件,则⼀直阻塞在那⾥,因此这种⽅式会导致⽤户线程的阻塞。多路复⽤ IO 模式,通过⼀个线程就可以管理多个 socket,只有当 socket 真正有读写事件发⽣才会占⽤资源来进⾏实际的读写操作。因此,多路复⽤ IO ⽐较适合连接数⽐较多的情况。
另外多路复⽤ IO 为何⽐⾮阻塞 IO 模型的效率⾼是因为在⾮阻塞 IO 中,不断地询问 socket 状态时通过⽤户线程去进⾏的,⽽在多路复⽤ IO 中,轮询每个 soc ket 状态是内核在进⾏的,这个效率要⽐⽤户线程要⾼的多。
ket 状态是内核在进⾏的,这个效率要⽐⽤户线程要⾼的多。
不过要注意的是,多路复⽤ IO 模型是通过轮询的⽅式来检测是否有事件到达,并且对到达的事件逐⼀进⾏响应。因此对于多路复⽤ IO 模型来说,⼀旦事件响应体很⼤,那么就会导致后续的事件迟迟得不到处理,并且会影响新的事件轮询。
8、信号驱动 IO 模型
在信号驱动 IO 模型中,当⽤户线程发起⼀个 IO 请求操作,会给对应的 socket 注册⼀个信号函数,然后⽤户线程会继续执⾏,当内核数据就绪时会发送⼀个信号给⽤户线程,⽤户线程接收到信号之后,便在信号函数中调⽤ IO 读写操作来进⾏实际的 IO 请求操作。
java面试八股文
9、异步 IO 模型
异步 IO 模型才是最理想的 IO 模型,在异步 IO 模型中,当⽤户线程发起 read 操作之后,⽴刻就可以开始去做其它的事。⽽另⼀⽅⾯,从内核的⾓度,当它受到⼀个 asynchronous read 之后,它会⽴刻返回,说明 read 请求已经成功发起了,因此不会对⽤户线程产⽣任何 block。然后,内核会等待数据
注意,异步 IO 是需要操作系统的底层⽀持,在 Java 7 中,提供了 Asynchronous IO。
准备完成,然后将数据拷贝到⽤户线程,当这⼀切都完成之后,内核会给⽤户线程发送⼀个信号,告诉它 read 操作完成了。也就说⽤户线程完全不需要实际的整个 IO 操作是如何进⾏的,只需要先发起⼀
个请求,当接收内核返回的成功信号时表⽰ IO 操作已经完成,可以直接去使⽤数据了。
也就说在异步 IO 模型中, IO 操作的两个阶段都不会阻塞⽤户线程,这两个阶段都是由内核⾃动完成,
然后发送⼀个信号告知⽤户线程操作已完成。⽤户线程中不需要再次调⽤ IO 函数进⾏具体的读写。这点是和信号驱动模型有所不同的,在信号驱动模型中,当⽤户线程接收到信号表⽰数据已经就绪,然后需要⽤户线程调⽤ IO 函数进⾏实际的读写操作;⽽在异步 IO 模型中,收到信号表⽰ IO 操作已经
完成,不需要再在⽤户线程中调⽤ IO 函数进⾏实际的读写操作。
10、JAVA NIO
NIO 主要有三⼤核⼼部分: Channel(通道), Buffer(缓冲区), Selector。传统 IO 基于字节流和字符流进⾏操作,⽽ NIO 基于 Channel 和 Buffer(缓冲区)进⾏操作,数据总是从通道读取到缓冲区中,或者从缓冲区写⼊到通道中。 Selector(选择区)⽤于监听多个通道的事件(⽐如:连接打开,数据到达)。因此,单个线程可以监听多个数据通道。 NIO 和传统 IO 之间第⼀个最⼤的区别是, IO 是⾯向流的, NIO 是⾯向缓冲区的。
11、NIO 的缓冲区
Java IO ⾯向流意味着每次从流中读⼀个或多个字节,直⾄读取所有字节,它们没有被缓存在任何地⽅。此外,它不能前后移动流中的数据。如果需要前后移动从流中读取的数据,需要先将它缓存到⼀个缓冲区。 NIO 的缓冲导向⽅法不同。数据读取到⼀个它稍后处理的缓冲区,需要时可在缓冲区中前后移动。这就增加了处理过程中的灵活性。但是,还需要检查是否该缓冲区中包含所有您需要处理的数据。⽽且,需确保当更多的数据读⼊缓冲区时,不要覆盖缓冲区⾥尚未处理的数据。
12、NIO 的⾮阻塞
IO 的各种流是阻塞的。这意味着,当⼀个线程调⽤ read() 或 write()时,该线程被阻塞,直到有⼀些数据被读取,或数据完全写⼊。该线程在此期间不能再⼲任何事情了。 NIO 的⾮阻塞模式,使⼀个线程从某通道发送请求读取数据,但是它仅能得到⽬前可⽤的数据,如果⽬前没有数据可⽤时,就什么都不会获取。⽽不是保持线程阻塞,所以直⾄数据变的可以读取之前,该线程可以继续做其他的事情。⾮阻塞写也是如此。⼀个线程请求写⼊⼀些数据到某通道,但不需要等待它完全写⼊,这个线程同时可以去做别的事情。线程通常将⾮阻塞 IO 的空闲时间⽤于在其它通道上执⾏ IO 操作,所以⼀个单独的线程现在可以管理多个输⼊和输出通道(channel)。
13、Channel
⾸先说⼀下 Channel,国内⼤多翻译成“通道”。 Channel 和 IO 中的 Stream(流)是差不多⼀个等级的。只不过 Stream 是单向的,譬如: InputStream, Output Stream,⽽ Channel 是双向的,既可以⽤来进⾏读操作,⼜可以⽤来进⾏写操作。NIO 中的 Channel 的主要实现有:
1. FileChannel
2. DatagramChannel
3. SocketChannel
4. ServerSocketChannel 这⾥看名字就可以猜出个所以然来:分别可以对应⽂件理IO、 UDP 和TCP(Server 和 Client)。下⾯演⽰的案例基本上就是围绕这4 个类型的 Channel 进⾏陈述的。
14、Buffer
14、Buffer
Buffer,故名思意,缓冲区,实际上是⼀个容器,是⼀个连续数组。 Channel 提供从⽂件、⽹络读取.
数据的渠道,但是读取或写⼊的数据都必须经由 Buffer。
上⾯的图描述了从⼀个客户端向服务端发送数据,然后服务端接收数据的过程。客户端发送数据时,必须先将数据存⼊ Buffer 中,然后将 Buffer 中的内容写⼊通道。服务端这边接收数据必须通过 Channel 将数据读⼊到 Buffer 中,然后再从 Buffer 中取出数据来处理。
在 NIO 中, Buffer 是⼀个顶层⽗类,它是⼀个抽象类,常⽤的 Buffer 的⼦类有:ByteBuffer、IntBuffer、 CharBuffer、 LongBuffer、 DoubleBuffer、 Float Buffer、ShortBuffer
15、Selector
Selec or 类是 NIO 的核⼼类, Selector 能够检测多个注册的通道上是否有事件发⽣,如果有事件发⽣,便获取事件然后针对每个事件进⾏相应的响应处理。这样⼀来,只是⽤⼀个单线程就可以管理多个通道,也就是管理多个连接。这样使得只有在连接真正有读写事件发⽣时,才会调⽤函数来进⾏读写,就⼤⼤地减少了系统开销,并且不必为每个连接都创建⼀个线程,不⽤去维护多个线程,并且避免了多线程之间的上下⽂切换导致的开销。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。