【Java面试题】IO & NIO

2023-11-09

1、什么是IO流?

它是一种数据的流从源头流到目的地。比如文件拷贝,输入流和输出流。输入流从文件中读取数据存储到进程(process)中,输出流从进程中读取数据然后写入到目标文件。

2、Java中有几种类型的流?

  • 按照单位大小:字符流、字节流。
  • 按照流的方向:输出流、输入流。

3、字节流和字符流哪个好?怎么选择?

  • 绝大多数情况下使用字节流会更好,因为字节流是字符流的包装,而大多数时候 IO 操作都是直接操作磁盘文件,所以这些流在传输时都是以字节的方式进行的〔图片等都是按字节存储的)
  • 如果操作是需要通过 IO 在内存中频繁处理字符串的情况,使用字符流会好些,因为字符流具备缓冲区,提高了性能。

4、读取数据量大的文件时,速度会很慢,如何选择流?

字节流时,选择BufferedInputStreamBufferedOutputStream
字符流时,选择BufferedReaderBufferedWriter

5、IO 模型有几种?

  • 阻塞 IO
  • 非阻塞 IO
  • 多路复用 IO
  • 信号驱动 IO
  • 异步 IO

6、阻塞IO(blocking IO)

应用程序调用一个 IO 函数,导致应用程序阻塞,如果数据已经准备好,从内核拷贝到用户空间,否则一直等待下去。一个典型的读操作流程大致如下图,当用户进程调用 recvfrom 这个系统调用时,kernel 就开始了 IO 的第一个阶段:准备数据,就是数据被拷贝到内核缓冲区中的一个过程(很多网络 IO 数据不会那么快到达,如没收一个完整的UDP包),等数据到操作系统内核缓冲区了,就到了第二阶段:将数据从内核缓冲区拷贝到用户内存,然后 kernel 返回结果,用户进程才会解除 block 状态,重新运行起来。

blocking IO 的特点就是在 IO 执行的两个阶段用户进程都会 block 住;

在这里插入图片描述

7、非阻塞 I/O(non-blocking IO)

非阻塞 I/O 模型,我们把一个套接口设置为非阻塞就是告诉内核,当所请求的 I/O 操作无法完成时,不要将进程睡眠,而是返回一个错误。这样我们的 I/O 操作函数将不断地测试数据是否已经准备好,如果没有准备好,继续测试,直到数据准备好为止。在这个不断测试的过程中,会大量的占用CPU的时间。

当用户进程发出read操作时,如果kernel中数据还没准备好,那么并不会 block 用户进程,而是立即返回error,用户进程判断结果是error,就知道数据还没准备好,用户可以再次发read,直到kernel中数据准备好,并且用户再一次发read操作,产生system call,那么kernel马上将数据拷贝到用户内存,然后返回;所以nonblocking I/O 的特点是用户进程需要不断的主动询问 Kernel 数据好了没有。

阻塞 I/O 一个线程只能处理一个 I/O 流事件,要想同时处理多个 I/O 流事件要么多线程要么多进程,这样做效率显然不会高,而非阻塞 I/O 可以一个线程处理多个流事件,只要不停地询所有流事件即可,当然这个方式也不好,当大多数流没数据时,也是会大量浪费CPU资源;为了避免CPU空转,引进代理(select 和 poll ,两种方式相差不大),代理可以观察多个流 I/O 事件,空闲时会把当前线程阻塞掉,当有一个或多个 I/O 事件时,就从阻塞态醒过来,把所有 I/O 流都轮询一遍,于是没有 I/O 事件我们的程序就阻塞在 select 方法处,即便这样依然存在问题,我们从 select 处只是知道有 I/O 事件发生,却不知道是哪几个流,还是只能轮询所有流,epoll这样的代理就可以把哪个流发生怎样的 I/O 事件通知我们:
在这里插入图片描述

8、I/O多路复用模型(I/O multiplexing)

I/O 多路复用就在于单个进程可以同时处理多个网络连接 IO,基本原理就是select、poll、epoll这些个函数会不断轮询所负责的所有socket,当某个socket有数据到达了,就通知用户进程,这三个function会阻塞进程,但和 I/O 阻塞不同,这些函数可以同时阻塞多个 I/O 操作,而且可以同时对多个读操作,写操作 I/O 进行检验,直到有数据到达,才真正调用 I/O 操作函数,调用过程如下图;

所以 I/O 多路复用的特点是通过一种机制一个进程能同时等待多个文件描述符,而这些文件描述符(套接字描述符)其中任意一个进入就绪状态,select函数就可以返回。

I/O 多路复用的优势在于适合并发数比较高的 I/O 操作清况,可以同时处理多个连接,和bloking I/O 一样,socket 是被阻塞的,只不过在多路复用中 socket 是被 select 阻塞,而在阻塞 I/O 中是被socket I/O 给阻塞。

在这里插入图片描述

9、信号驱动I/O模型

可以用信号,让内核在描述符就绪时发送 SIGIO 信号通知我们,通过 sigaction 系统调用安装一个信号处理函数。该系统调用将立即返回,我们的进程继续工作,也就是说它没有被阻塞。当数据报准备好读取时,内核就为该进程产生一个 SIGIO 信号。我们随后既可以在信号处理函数中调用recvfrom读取数据报,并通知主循环数据已经准备好待处理。特点:等待数据报到达期间进程不被阻塞。主循环可以继续执行,只要等待来自信号处理函数的通知:既可以是数据已准备好被处理,也可以是数据报已准备好被读取。

在这里插入图片描述

10、异步I/O(asynchronous IO)

异步 I/O 告知内核启动某个操作,并让内核在整个操作(包括将内核数据复制到我们自己的缓冲区)完成后通知我们,调用aio_read(Posix异步 I/O 函数以 aio 或 lio 开头)函数,给内核传递描述字、缓冲区指针、缓冲区大小(与read相同的3个参数)、文件偏移以及通知的方式,然后系统立即返回。我们的进程不阻塞于等待 I/O 操作的完成。当内核将数据拷贝到缓冲区后,再通知应用程序。

用户进程发起 read 操作之后,立刻就可以开始去做其它的事。而另一方面,从 kernel 的角度,当它受到一个 asynchronous read 之后,首先它会立刻返回,所以不会对用户进程产生任何 block 。然后,kernel 会等待数据准备完成,然后将数据拷贝到用户内存,当这一切都完成之后,kernel会给用户进程发送一个 signal,告诉它read操作完成了。
在这里插入图片描述

11、NIO 与 IO 的区别?

NIO 即 New IO,这个库是在JDK1.4中才引入的。NIO 和 IO 有相同的作用和目的,但实现方式不同,NIO 主要用到的是块,所以 NIO 的效率要比 IO 高很多。在Java API中提供了两套 NIO ,一套是针对标准输入输出 NIO,另一套就是网络编程 NIO。

IO NIO
面向流 面向缓冲
阻塞IO 非阻塞IO
选择器

12、NIO和IO适用场景

NIO 是为弥补传统 IO 的不足而诞生的,但是尺有所短寸有所长,NIO 也有缺点,因为NIO是面向缓冲区的操作,每一次的数据处理都是对缓冲区进行的,那么就会有一个问题,在数据处理之前必须要判断缓冲区的数据是否完整或者已经读取完毕,如果没有,假设数据只读取了一部分,那么对不完整的数据处理没有任何意义。所以每次数据处理之前都要检测缓冲区数据。

那么 NIO 和 IO 各适用的场景是什么呢?

如果需要管理同时打开的成千上万个连接,这些连接每次只是发送少量的数据,例如聊天服务器,这时候用 NIO 处理数据可能是个很好的选择。

而如果只有少量的连接,而这些连接每次要发送大量的数据,这时候传统的 IO 更合适。使用哪种处理数据,需要在数据的响应等待时间和检查缓冲区数据的时间上作比较来权衡选择。

13、NIO核心组件

channel、buffer、selector

14、什么是channel

一个Channel(通道)代表和某一实体的连接,这个实体可以是文件、网络套接字等。也就是说,通道是 Java NIO 提供的一座桥梁,用于我们的程序和操作系统底层 I/O 服务进行交互。

通道是一种很基本很抽象的描述,和不同的 I/O 服务交互,执行不同的 I/O 操作,实现不一样,因此具体的有FileChannel、SocketChannel等。

通道使用起来跟Stream比较像,可以读取数据到 Buffer 中,也可以把 Buffer 中的数据写入通道。

在这里插入图片描述
当然,也有区别,主要体现如下两点:

  • 一个通道,既可以读又可以写,而一个Stream是单向的(所以分为InputStream和OutputStream)
  • 通道有非阻塞 I/O 模式。

15、Java NIO 中最常用的通道实现?

  • FileChannel:读写文件
  • DatagramChannel:UDP协议网络通信
  • SocketChannel:TCP协议网络通信
  • ServerSocketChannel:监听TCP连接

16、Buffer是什么?

NIO 中所使用的缓冲区不是一个简单的byte数组,而是封装过的Buffer类,通过它提供的API,我们可以灵活的操纵数据。

与Java基本类型相对应,NIO 提供了多种Buffer类型,如ByteBuffer、CharBuffer、IntBuffer等,区别就是读写缓冲区时的单位长度不一样(以对应类型的变量为单位进行读写)。

17、核心Buffer实现有哪些?

核心的 buffer 实现有这些:ByteBuffer、CharBuffer、DoubleBuffer、FloatBuffer、IntBuffer、LongBuffer、ShortBuffer,涵盖了所有的基本数据类型〔4类8种,除了Boolean)。也有其他的buffer,如MappedByteBuffer。

18、buffer读写数据基本操作

  1. 将数据写入 buffer
  2. 调用buffer.flip()
  3. 将数据从 buffer 中读取出来
  4. 调用 buffer.clear() 或者 buffer.compact()

在写buffer的时候,buffer会跟踪写入了多少数据,需要读buffer的时候,需要调用 flip() 来将buffer从写模式切换成读模式,读模式中只能读取写入的数据,而非整个 buffer。

当数据都读完了,你需要清空buffer以供下次使用,可以有2种方法来操作:调用 clear() 或者调用 compact()

区别:clear方法清空整个buffer,compact方法只清除你已经读取的数据,未读取的数据会被移到buffer的开头,此时写入数据会从当前数据的末尾开始。

// 创建一个容量为48的ByteBuffer
ByteBuffer buf = ByteBuffer.allocate(48);
// 从channel中读(取数据然后写)入buffer
int bytesRead = inChannel.read(buf);
// 下面是读取buffer
while (bytesRead != -1) {
	buf.flip(); // 转换buffer为读模式
	System.out.print((char) buf.get()); // 一次读取一个byte
	buf.clear(); //清空buffer准备下一次写入
}

19、Selector是什么?

Selector(选择器)是一个特殊的组件,用于采集各个通道的状态(或者说事件)。我们先将通道注册到选择器,并设置好关心的事件,然后就可以通过调用select()方法,静静地等待事件发生。

20、通道可以监听哪几个事件?

通道有如下4个事件可供我们监听:

  • Accept:有可以接受的连接
  • Connect:连接成功
  • Read:有数据可读
  • Write:可以写入数据了

21、为什么要用Selector?

如果用阻塞 I/O,需要多线程(浪费内存),如果用非阻塞 I/O 需要不断重试(耗费CPU)。Selector的出现解决了这尴尬的问题,非阻塞模式下,通过Selector,我们的线程只为已就绪的通道工作,不用盲目的重试了。比如,当所有通道都没有数据到达时,也就没有Read事件发生,我们的线程会在select()方法处被挂起,从而让出了CPU资源。

22、Selector处理多Channel图文说明

在这里插入图片描述
要使用一个Selector,你要先注册这个Selector的Channels。然后你调用Selector的select()方法。这个方法会阻塞,直到它注册的 Channels 当中有一个谁备好了的事件发生了。当 select() 方法返回的时候,线程可以处理这些事件,如新的连接的到来,数据收到了等。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Java面试题】IO & NIO 的相关文章

随机推荐

  • 测试用例设计白皮书--测试用例设计综合策略

    测试用例设计白皮书 测试用例设计综合策略 Author Vince 来源 http blog csdn net vincetest 1 Myers提出了使用各种测试方法的综合策略 1 在任何情况下都必须使用边界值分析方法 经验表明用这种方法
  • 微信小程序-SOA架构(17年1月)

    微信小程序 顾名思义 它有两个方面的含义 重点在小 也就是不用安装就能使用的意思 另一个重点 它是应用程序 它和公众号绑定在一起使用 从用户角度去看 它是各种APP的替代品 有了它以后 不再需要安装APP 作为IT人员 更多的是从工程思维的
  • Snort搭建以及规则编写

    目录 Snort IDS Snort搭建 安装web服务 方便设置sonrt后期访问 Mysql安装 PHP安装 安装 Snort Snort配置 创建snort专用的用户和组 配置目录 配置规则 修改配置文件 规则编写 Snort IDS
  • QGIS二次开发02:交互动作实现

    地图交互动作就是通过鼠标操作与地图间的互动 动作包括按下 press 按键弹起 release 鼠标移动 move 双击等等 QGIS实现地图的交互主要是通过继承QgsMapTool这个类实现 目前集成了QgsMapToolZoom 拉框缩
  • 数据结构---堆的构建和堆排序(向下、向上调整算法)

    一 建堆 1 堆的概念及性质 如果有一个关键码的集合 K k0 k1 k2 kn 1 把它的所有元素按完全二叉树的顺序存储方式存储在一个一维数组中 并满足 Ki lt K2 i 1 且 Ki lt K2 i 2 Ki gt K2 i 1 且
  • 七大排序知识点

    目录 1 稳定性 2 冒泡排序 3 插入排序 3 1 折半插入排序 4 希尔排序 5 选择排序 6 堆排序 7 快速排序 挖坑法 8 归并排序 9 海量数据的排序问题 1 稳定性 两个相等的数据 如果经过排序后 排序算法能保证其相对位置不发
  • JSON与MODEL互转

    HYBJSONModel h Json2ModelDemo Created by huangyibiao on 14 9 15 Copyright c 2014年 Home All rights reserved import
  • R语言-线性回归实例(包括所有源码)

    题目描述 目录 一 身高体重 1 身高和体重的散点图 先肉眼观察来判断使用什么模型 2 画出拟合后的线性函数与散点图背景对比 3 对该模型的分析 4 置信区间分析和假设检验 5 多图像分析 二 不良贷款 三 污染 1 以二氧化硫排放量 吨
  • (四)现代计算机系统的层次结构

    程序执行结果 不仅取决于算法 程序的编写 而且取决于语言处理系统 操作系统 ISA 微体系结构 不同计算机课程处于不同层次 必须将各层析关联起来解决问题 功能转换 上层是下层的抽象 下层时上层的实现 地位为上层提供支撑环境 计算机系统的不同
  • install chrome

    1 2 wget https dl google com linux direct google chrome stable current i386 deb 没试用过 3 4 wget https dl google com linux
  • ADS学习:Smith Chart Utility使用说明

    打开方式 原理图界面 Tools Smith Chart Utility 功能分区 1 菜单栏 2 工具栏 3 作图区 4 频率响应区
  • 【报告分享】完美日记品牌分析报告.pdf(附68页pdf全文下载链接)

    今天给大家分享的是上海语析信息咨询有限公司于2020年4月份发布的 完美日记品牌分析报告 pdf 该报告由上海交通大学海外教育学院中国商业发展研究所作为学术指导 报告共包含如下五大部分 1 完美日记品牌故事 2 完美日记营销分析 3 完美日
  • 苹果手机屏幕如何投射到win10?

    说起家庭娱乐 大多数人想到的一定是电脑 手机 亦或者是电视 其中每天陪伴的必定有手机 我们很少再使用电视去看影视作品 取而代之的是各大视频网站 比如腾讯 爱奇艺 优酷等 而不需再等候 黄金七点半 很多人一定会把会员在手机端登录 因此想在电脑
  • 川大计算机信息安全基础试题,信息安全概论考试试题..doc

    四川大学2014年春季软件工程研究生班考试试题 课程名称 信息安全概论 任课教师 琚生根 学生人数 印题份数 学号 姓名 考 试 须 知 四川大学学生参加由学校组织或由学校承办的各级各类考试 必须严格执行 四川大学考试工作管理办法 和 四川
  • 泛微E-Mobile 6.0远程命令执行漏洞

    前言 本次测试仅供学习使用 如若非法他用 与本文作者无关 需自行负责 漏洞描述 Weaver E Mobile是中国泛微科技 Weaver 公司的一个协同办公系统 E Mobile6最新版是上海泛微网络科技推出的一款手机办公应用 将企业微信
  • 纯 CSS 实现高度与宽度成比例的效果

    HTML p class image container img src xxx png p CSS p image container width 100 height 0 padding bottom 60 overflow hidde
  • docker 训练深度学习_Docker:把深度学习装进“口袋”

    熟悉深度学习开发框架的朋友都知道 caffe 的安装麻烦 耗时长 而且很容易因为电脑环境没有配置好导致错误 每次有新同事来 我们都要在他电脑上安装一遍 caffe 经常会因为电脑环境而不断报错 目前TensorFlow受到很多深度学习开发者
  • 阿里云oss视频上传及预览图汇总

    阿里云OSS视频上传的几种方式 1 Web端直传实践简介 https help aliyun com document detail 31923 html spm a2c4g 11186623 6 631 apBNnA 2 JavaScri
  • cacheable 过期设置

    1 增加pom依赖
  • 【Java面试题】IO & NIO

    1 什么是IO流 它是一种数据的流从源头流到目的地 比如文件拷贝 输入流和输出流 输入流从文件中读取数据存储到进程 process 中 输出流从进程中读取数据然后写入到目标文件 2 Java中有几种类型的流 按照单位大小 字符流 字节流 按