java面试题-IO流

news2024/9/28 9:22:01

基础IO

1.如何从数据传输方式理解IO流?

IO流根据处理数据的类型可以分为字节流和字符流。

  1. 字节流

字节流以字节(8位)为单位读写数据。字节流主要用于读写二进制文件,如图片、音频、视频等。Java中的InputStream和OutputStream就是字节流。

InputStream和OutputStream的子类有很多,如FileInputStream和FileOutputStream、ByteArrayInputStream和ByteArrayOutputStream等。使用字节流进行读写文件时,一般需要使用缓冲流来提高读写效率。缓冲流会将数据先缓存到内存中,再批量读写,从而避免了频繁的磁盘读写操作。

  1. 字符流

字符流以字符为单位读写数据。字符流主要用于读写文本文件,如txt文件等。Java中的Reader和Writer就是字符流。

Reader和Writer的子类有很多,如FileReader和FileWriter、CharArrayReader和CharArrayWriter等。使用字符流进行读写文件时,一般也需要使用缓冲流来提高读写效率。需要注意的是,使用字符流读写文件时需要注意文件编码的问题,否则可能会出现乱码。

在实际开发中,如果需要读写的数据是二进制数据,应该使用字节流;如果需要读写的数据是文本数据,应该使用字符流。需要根据实际需求选择合适的流进行操作。

  • 字节流

  • 字符流

  • 字节转字符

2.如何从数据操作上理解IO流?

3.Java IO设计上使用了什么设计模式?

在Java IO中,装饰器模式被广泛应用于输入流和输出流的设计中。以输入流为例,下面是一个使用装饰器模式的简单示例:

InputStream input = new FileInputStream("file.txt");
input = new BufferedInputStream(input);
input = new DataInputStream(input);

在这个示例中,我们首先创建了一个FileInputStream对象,它是一个具体组件,表示一个输入流。然后,我们通过装饰器模式创建了一个缓冲输入流对象,它是一个具体装饰器,向原始对象添加了缓冲功能。最后,我们又通过装饰器模式创建了一个数据输入流对象,它也是一个具体装饰器,向缓冲输入流添加了读取数据的功能。这样,我们就可以通过数据输入流对象来读取文件中的数据了。

在输出流中,同样使用了装饰器模式。下面是一个简单的示例:

OutputStream output = new FileOutputStream("file.txt");
output = new BufferedOutputStream(output);
output = new DataOutputStream(output);

在这个示例中,我们首先创建了一个FileOutputStream对象,它是一个具体组件,表示一个输出流。然后,我们通过装饰器模式创建了一个缓冲输出流对象,它是一个具体装饰器,向原始对象添加了缓冲功能。最后,我们又通过装饰器模式创建了一个数据输出流对象,它也是一个具体装饰器,向缓冲输出流添加了写入数据的功能。这样,我们就可以通过数据输出流对象来将数据写入到文件中了。


5种IO模型

1.什么是阻塞?什么是同步?

  • 阻塞IO 和 非阻塞IO

这两个概念是程序级别的。主要描述的是程序请求操作系统IO操作后,如果IO资源没有准备好,那么程序该如何处理的问题: 前者等待;后者继续执行(并且使用线程一直轮询,直到有IO资源准备好了)

  • 同步IO 和 非同步IO

这两个概念是操作系统级别的。主要描述的是操作系统在收到程序请求IO操作后,如果IO资源没有准备好,该如何响应程序的问题: 前者不响应,直到IO资源准备好以后;后者返回一个标记(好让程序和自己知道以后的数据往哪里通知),当IO资源准备好以后,再用事件机制返回给程序。

2.什么是同步阻塞IO?

同步阻塞IO是指程序进行IO操作时,程序会一直等待,直到操作完成,期间无法进行其他操作。例如,在Java中,如果使用InputStream的read()方法进行读操作,当没有可读数据时,该方法将会一直阻塞线程,直到有可读数据或者读操作超时才返回。

同步阻塞IO通常使用单线程或者有限数量的线程来处理IO操作,每个线程会阻塞在IO操作上,等待IO操作完成后才会继续执行。这种模型的优点是简单可靠,适用于并发请求量不大的场景,但是并发能力有限,无法满足高并发的需求。

同步阻塞IO的一个特点是每个IO操作需要独立的线程或者进程来处理,因此在并发访问时,可能会出现线程竞争、线程切换等问题,导致性能下降。此外,由于每个线程都会阻塞在IO操作上,当IO操作非常耗时时,会导致线程资源浪费,影响程序的响应性能。

3.什么是同步非阻塞IO?

同步非阻塞IO是指程序进行IO操作时,程序不会一直阻塞等待操作完成,而是先向操作系统发起一个IO请求,并继续执行其他任务。当IO操作完成时,操作系统会通知程序,并将数据复制到程序缓冲区中,程序再次请求读取或写入缓冲区中的数据。

在同步非阻塞IO模型中,程序不会等待IO操作完成,而是通过轮询或者事件通知的方式查询IO状态,直到IO操作完成或者超时才返回。这种模型适用于并发请求数较多的场景,可以通过少量线程处理大量并发请求,从而提高并发处理能力。

同步非阻塞IO的一个特点是需要程序不断轮询IO状态或者注册IO事件,并且需要不断地检查IO状态。这种模型需要更多的CPU资源来处理IO操作,但相对于同步阻塞IO模型,可以更好地支持并发请求。

4.什么是多路复用IO?

多路复用IO(Multiplexing IO)是一种IO模型,它通过使用一种机制,使得单个进程可以同时处理多个I/O请求。

在多路复用IO模型中,一个进程可以同时监听多个文件描述符,当有一个或多个文件描述符有I/O事件发生时,通过操作系统提供的系统调用进行通知,进程可以针对每个文件描述符进行处理,从而实现高并发的I/O处理。常见的多路复用IO机制包括select、poll和epoll。

多路复用IO的主要优点是能够在单个线程内处理多个I/O请求,相比于多线程或者多进程的方式,减少了线程或进程上下文切换的开销,避免了线程或进程资源的浪费。同时,由于多路复用IO可以同时处理多个I/O请求,能够有效地提高程序的并发处理能力,适用于高并发的网络应用场景。

总之,多路复用IO是一种高并发的IO模型,通过使用一种机制,使得单个进程可以同时处理多个I/O请求,能够有效地提高程序的并发处理能力,减少线程或进程资源的浪费。

5.有哪些多路复用IO?

常见的多路复用IO机制包括select、poll和epoll。

  1. select:select是最早的多路复用IO机制之一,可以同时监听多个文件描述符,当有一个或多个文件描述符有I/O事件发生时,通过操作系统提供的系统调用进行通知,进程可以针对每个文件描述符进行处理。

  1. poll:poll是select的改进版,同样可以监听多个文件描述符,但它采用链表来存储文件描述符,避免了select中文件描述符数量的限制。

  1. epoll:epoll是Linux系统上的多路复用IO机制,相对于select和poll,epoll具有更高的效率和更低的延迟。它使用事件驱动的方式来处理文件描述符,可以同时处理大量的文件描述符,避免了select和poll中需要遍历所有文件描述符的缺点。同时,epoll还支持边缘触发和水平触发两种模式,能够更加灵活地处理I/O事件。

6.什么是信号驱动IO?

信号驱动IO是一种I/O模型,也称为异步I/O模型。在信号驱动IO模型中,当进行I/O操作时,进程会向操作系统注册一个信号处理函数,然后继续执行其他任务。当I/O操作完成后,操作系统会向进程发送一个信号,告知该I/O操作已经完成,进程可以通过信号处理函数来获取I/O操作的结果。

相对于阻塞和非阻塞IO模型,信号驱动IO模型更加高效,因为它可以同时处理多个I/O操作,而不需要阻塞进程或使用轮询等方式等待I/O操作的完成。同时,信号驱动IO模型相对于多路复用IO模型更加灵活,因为它不需要将多个文件描述符放在一个轮询列表中等待事件的发生,而是可以对每个文件描述符单独注册信号处理函数。

需要注意的是,信号驱动IO模型在某些情况下也可能存在一些缺陷。例如,当同时注册大量的信号处理函数时,会导致信号处理函数的调用时间变长,从而影响整个系统的性能。因此,在实际应用中,需要根据具体的情况选择最合适的IO模型。

7.什么是异步IO?

异步I/O是一种I/O模型,也称为事件驱动I/O。在异步I/O模型中,当进行I/O操作时,进程不会被阻塞,而是会向操作系统注册一个I/O操作,并继续执行其他任务。当I/O操作完成后,操作系统会通知进程,进程可以获取I/O操作的结果。

相对于阻塞、非阻塞和信号驱动IO模型,异步I/O模型更加高效,因为它可以充分利用CPU资源,同时处理多个I/O操作,而不需要等待任何一个操作的完成。异步I/O模型通常采用回调函数的方式来处理I/O操作的结果,当I/O操作完成后,操作系统会回调相应的函数,进程可以在回调函数中获取I/O操作的结果。

异步I/O模型通常用于需要处理大量I/O操作的系统中,如高并发的网络服务器、图形图像处理等领域。需要注意的是,异步I/O模型的实现比较复杂,需要使用操作系统提供的特定API或框架,如Linux系统中的epoll、Windows系统中的I/O Completion Ports等。

8.什么是Reactor模型?

Reactor模型是一种基于事件驱动的I/O模型,用于处理高并发的网络应用程序。它由Doug Lea等人在1996年提出,是一种被广泛应用的I/O编程模型。

Reactor模型的基本思想是将I/O事件的处理过程分离出来,使其在单独的线程中运行。这个线程被称为Reactor线程,它负责监听所有的I/O事件,并根据事件的类型分发给相应的事件处理器。事件处理器通常在单独的线程中执行,它负责处理I/O事件,并根据业务逻辑进行相应的处理。

Reactor模型中包含两个核心组件,即Reactor和Handler。Reactor是I/O事件处理器的核心,负责监听和分发所有的I/O事件。Handler是具体的事件处理器,它会在事件发生时被Reactor调用,并处理相应的I/O事件。

Reactor模型的优点在于能够有效地利用多核CPU资源,同时处理大量的并发请求,提高系统的吞吐量和响应速度。在实际应用中,Reactor模型被广泛应用于高并发的网络应用程序中,如Web服务器、消息队列等。常见的Reactor模型包括单线程Reactor模型、多线程Reactor模型和主从Reactor模型。

9.什么是Java NIO?

Java NIO的核心组件包括以下几个部分:

  • 缓冲区(Buffer):用于存储数据的内存区域,可以通过NIO提供的ByteBuffer、CharBuffer、ShortBuffer等类来实现。

  • 通道(Channel):用于对数据进行读写操作的对象,可以通过NIO提供的FileChannel、SocketChannel、ServerSocketChannel、DatagramChannel等类来实现。

  • 选择器(Selector):用于监控多个通道的I/O事件,可以通过NIO提供的Selector类来实现。

Java NIO相比于传统的Java I/O,具有以下几个优点:

  • 非阻塞I/O操作:Java NIO提供了基于缓冲区、通道和选择器的非阻塞I/O操作方式,使得单线程可以同时处理多个I/O操作,提高了系统的并发处理能力。

  • 支持多种网络协议:Java NIO提供了对TCP、UDP、SSL等多种网络协议的支持,可以满足不同场景下的需求。

  • 零拷贝I/O:Java NIO支持零拷贝I/O操作,可以直接将数据从文件或网络中读取到内存中,提高了数据的传输效率。

在实际应用中,Java NIO被广泛应用于高并发的网络应用程序中,如网络服务器、消息队列等。

零拷贝

1.传统的IO存在什么问题?为什么引入零拷贝的?

传统的IO(也称为IO流或者普通IO)存在以下几个问题:

  1. 低效:传统的IO操作基于字节流或字符流进行,需要进行频繁的数据转换和复制,造成了大量的CPU和内存资源浪费,导致I/O操作效率低下。

  1. 阻塞:传统的IO操作是阻塞的,即读写操作必须等待I/O操作完成后才能继续执行,这导致单线程无法处理多个I/O操作,从而限制了系统的并发性能。

  1. 不支持零拷贝:传统的IO操作需要进行数据的复制和移动,即从文件或网络读取数据到内存中后,还需要将数据复制到另一个缓冲区中,再进行下一步操作。这种复制和移动操作浪费了大量的CPU和内存资源,影响了I/O操作的效率。

为了解决这些问题,引入了零拷贝技术。零拷贝(Zero-copy)是指在数据传输过程中,数据从磁盘、网络等外部设备直接传输到内存或者其他设备中,避免了数据的重复复制和移动,从而提高了I/O操作的效率和吞吐量。零拷贝技术可以避免数据复制和移动的过程,从而减少了CPU和内存的使用,提高了系统的性能。

Java NIO提供了零拷贝I/O操作的支持,通过使用DirectByteBuffer等直接缓冲区实现了数据在内存和外部设备之间的直接传输,避免了数据复制和移动的过程,从而提高了I/O操作的效率。

2.mmap + write怎么实现的零拷贝

mmap + write 是一种实现零拷贝的方式,其主要思路是将文件数据映射到内存中,通过内存映射的方式来访问文件数据,从而避免了数据从内核空间向用户空间的拷贝,以及从用户空间向内核空间的拷贝。具体实现步骤如下:

  1. 调用 mmap 函数将文件映射到内存中,得到一个指向内存的指针 buf。

  1. 调用 write 函数将内存中的数据写入网络套接字 sockfd 中。

在这个过程中,mmap 函数将文件的数据映射到了内存中,而 write 函数则直接将内存中的数据写入网络套接字中,避免了数据的拷贝过程。

需要注意的是,这里的写入操作是异步的,即 write 函数将数据写入套接字的缓冲区中后就返回了,不会等待数据发送完成。如果需要等待数据发送完成再进行下一步操作,需要使用相应的系统调用来实现。

相比传统的数据拷贝方式,mmap + write 可以避免多次数据拷贝,减少了 CPU 和内存的开销,提高了数据传输的效率。但也有一些限制和注意事项:

  1. mmap 函数会将整个文件映射到内存中,因此对于大文件来说,可能会占用大量的内存,需要谨慎使用。

  1. 在进行写操作之前,需要确保文件的内容已经被完全读入内存中,否则写入的数据可能不完整。

  1. 对于频繁的写操作,由于每次写入都需要调用 mmap 函数重新映射内存,可能会带来额外的开销,因此需要根据具体情况进行优化。

3.sendfile怎么实现的零拷贝?

sendfile() 函数是一种系统调用,它在 Linux 和 Unix 系统上实现了零拷贝技术,可以在内核空间和用户空间之间直接传输数据,从而减少了数据拷贝的次数,提高了传输效率。

sendfile() 函数的基本用法如下

#include <sys/sendfile.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count);

其中,out_fd 是输出文件描述符,in_fd 是输入文件描述符,offset 是输入文件的偏移量,count 是要传输的字节数。在调用 sendfile() 函数时,输入文件描述符 in_fd 必须是一个打开的文件,而输出文件描述符 out_fd 必须是一个套接字。

sendfile() 函数的工作原理是这样的:在内核中,sendfile() 函数将输入文件描述符 in_fd 和输出套接字 out_fd 绑定在一起,然后在内核中将文件内容从输入文件描述符中复制到输出套接字中,这个过程是在内核中完成的,而不涉及用户空间。具体来说,sendfile() 函数首先在内核中将输入文件描述符和输出套接字建立一个连接,然后从输入文件描述符中读取数据到内核缓冲区中,再将数据从内核缓冲区中写入到输出套接字中,最后将输出套接字中写入的字节数返回给用户程序。

在使用 sendfile() 函数时,需要注意以下几点:

  1. sendfile() 函数只能用于在两个文件描述符之间进行数据传输,而不能用于网络套接字和文件之间的传输。

  1. sendfile() 函数只能用于 Linux 和 Unix 系统,而不能用于 Windows 系统。

  1. sendfile() 函数只能传输一个文件的数据,如果需要传输多个文件,则需要在用户程序中多次调用 sendfile() 函数。

  1. sendfile() 函数只能用于传输文件的全部内容,而不能用于传输文件的部分内容。

sendfile() 函数实现了零拷贝技术,可以在内核空间和用户空间之间直接传输数据,减少了数据拷贝的次数,提高了传输效率,是实现高性能网络编程的重要手段之一。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/366687.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

写论文不用构建语料库!只需要福昕PDF阅读器高级搜索

写论文不用构建语料库&#xff01;只需要福昕PDF阅读器高级搜索 文章目录写论文不用构建语料库&#xff01;只需要福昕PDF阅读器高级搜索前言&#xff1a;“福昕语料库”使用前的准备&#xff1a;调用“语料库”&#xff1a;前言&#xff1a; 最近论文阅读可以借助NewBing的总…

【算法与数据结构(C语言)】栈和队列

文章目录 目录 前言 一、栈 1.栈的概念及结构 2.栈的实现 入栈 出栈 获取栈顶元素 获取栈中有效元素个数 检测栈是否为空&#xff0c;如果为空返回非零结果&#xff0c;如果不为空返回0 销毁栈 二、队列 1.队列的概念及结构 2.队列的实现 初始化队列 队尾入队列 队头出队列 获…

报表开发难上手?这里有一份 Fastreport 最新中文用户指南,请查收

Fast Reports,Inc.成立于1998年&#xff0c;多年来一直致力于开发快速报表软件&#xff0c;包括应用程序、库和插件。FastReport的报表生成器&#xff08;VCL平台和.NET平台&#xff09;、跨平台的多语言脚本引擎FastScript、桌面OLAP FastCube&#xff0c;如今都受到世界各地开…

Typecho COS插件实现网站静态资源存储到COS,降低本地存储负载

Typecho 简介Typecho 是一个简单、强大的轻量级开源博客平台&#xff0c;用于建立个人独立博客。它具有高效的性能&#xff0c;支持多种文件格式&#xff0c;并具有对设备的响应式适配功能。Typecho 相对于其他 CMS 还有一些特殊优势&#xff1a;包括可扩展性、不同数据库之间的…

IDA 实战--(2)熟悉工具

布局介绍 软件启动后会 有几个选项&#xff0c;一般直接选择Go 即可 之后的工作台布局如下 开始分析 分析的第一个&#xff0c;将PE 文件拖入工作区 刚开始接触&#xff0c;我们先保持默认选项&#xff0c;其它选项后面会详细讲解&#xff0c;点击OK 后&#xff0c;等待分析…

软件项目管理知识回顾---软件项目质量和资源管理

软件项目质量和资源管理 5.0质量管理 5.1质量管理模型 1.模型 boehm模型&#xff1a;可移植性&#xff0c;可使用性&#xff0c;可维护性McCall模型ISO体系认证5.2质量成本 1.含义&#xff1a;由于产品第一次不正常运行而产生的附加费用 预防成本和缺陷成本5.3质量管理 1.过程 …

Python opencv进行矩形识别

Python opencv进行矩形识别 图像识别中,圆形和矩形识别是最常用的两种,上一篇讲解了圆形识别,本例讲解矩形识别,最后的结果是可以识别出圆心,4个顶点,如下图: 左边是原始图像,右边是识别结果,在我i5 10400的CPU上,执行时间不到8ms。 识别出结果后,计算任意3个顶点…

【自监督论文阅读笔记】Unsupervised Learning of Dense Visual Representations

Abstract 对比自监督学习已成为无监督视觉表示学习的一种有前途的方法。通常&#xff0c;这些方法学习全局&#xff08;图像级&#xff09;表示&#xff0c;这些表示对于同一图像的不同视图&#xff08;即数据增强的组合&#xff09;是不变的。然而&#xff0c;许多视觉理解任务…

PDF文件怎么转图片格式?转换有技巧

PDF文件有时为了更美观或者更直观的展现出效果&#xff0c;我们会把它转成图片格式&#xff0c;这样不论是归档总结还是存储起来都会更为高效。有没有合适的转换方法呢&#xff1f;这就来给你们罗列几种我个人用过体验还算不错的方式&#xff0c;大家可以拿来参考一下哈。1.用电…

vm 网络配置

点击NAT设置&#xff0c;配置本台虚拟机ip&#xff08;注意网关要在同一个网段&#xff09;&#xff0c;配置对应端口 然后添加映射端口&#xff1a; 然后选择网络适配器 选择vm8网卡 配置网卡静态ip #查看网卡 ip addr #修改网卡配置 cd /etc/sysconfig/network-scripts…

DevData Talks | 对谈谷歌云 DORA 布道师,像谷歌一样度量 DevOps 表现

本期 DevData Talks 我们请到来自 Google Cloud 谷歌云的 DORA 研究团队的嘉宾 Nathen Harvey与 Apache DevLake、CNCF DevStream 的海外社区负责人 Maxim 进行对谈。如果您关注 DevOps 的话&#xff0c;也许对这个团队有所耳闻。 DORA 的全称是 DevOps Research and Assessme…

mysql lesson1

常用命令 1:exit 退出mysql 2&#xff1a;uroot pENTER键&#xff0c;再输入密码&#xff0c;不被别人看见 3&#xff1a;完美卸载&#xff1a;双击安装包&#xff0c;手动删除program file中的mysql,手动删除Programedate里的mysql 4:use mysql 使用数据库 5&#xff1a;…

InstallAware Multi-Platform updated

InstallAware Multi-Platform updated 原生ARM&#xff1a;为您的内置设置、IDE和整个工具链添加了Apple macOS和Linux ARM构建。 本地化&#xff1a;引擎内多语言感知&#xff0c;可再分发工具&#xff0c;具有资产隔离功能&#xff0c;使您的IP保持安全。 模板&#xff1a;将…

通信算法复习题纲

通信算法复习题1、当信源发送信号满足以下哪一项条件时&#xff0c;接收端采用最小距离准则进行判决等价于采用最大后验概率准则进行判决&#xff1f;2、OFDM系统的正交性体现在哪个方面&#xff1f;3、模拟信号数字化过程中&#xff0c;哪一步会引入量化噪声&#xff1f;4、OF…

考研复试机试 | c++ | 王道复试班

目录n的阶乘 &#xff08;清华上机&#xff09;题目描述代码汉诺塔问题题目&#xff1a;代码&#xff1a;Fibonacci数列 &#xff08;上交复试&#xff09;题目代码&#xff1a;二叉树&#xff1a;题目&#xff1a;代码&#xff1a;n的阶乘 &#xff08;清华上机&#xff09; …

汽车电子社区交流宣传

http://t.csdn.cn/VSLO0http://t.csdn.cn/VSLO0 当今的汽车行业已经进入了数字化时代&#xff0c;汽车电子软件的开发变得越来越重要。在这个领域&#xff0c;开发者们需要应对各种挑战&#xff0c;包括复杂的硬件和软件交互、高效的嵌入式编程和安全性要求。为了帮助汽车电子…

Android Bluetooth(一)——蓝牙的开启和搜索

Android Bluetooth&#xff08;一&#xff09;——蓝牙的开启和搜索Android Bluetooth&#xff08;一&#xff09;——蓝牙的开启和搜索概览设置蓝牙蓝牙权限设置蓝牙查找设备查询已配对设备发现设备启用可检测性Android Bluetooth&#xff08;一&#xff09;——蓝牙的开启和搜…

Git系列——Git理论

概述Git 是一个开源的分布式版本控制系统&#xff0c; 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。Git没有中央版本库的概念&#xff0c;每个客户端都可成为版本库&#xff0c;内部采用全量方式对文件的每次提交建立快照并存储&#x…

探索开源:获取完整的 GitHub 社区数据集

本篇文章聊聊 GitHub 开放数据集的获取和整理&#xff0c;分享一些数据整理的细节技巧&#xff0c;以及一些相对粗浅的数据背后的事情。 写在前面 分析 GitHub 上的项目和开发者获取是深入、真实的了解开源世界演进的方法之一。 在 GHArchive 项目中&#xff0c;我们能够看到…

什么是知识库,内部知识库和外部知识库各有什么优势?

知识库的定义在互联网的整个历史中多次发生变化。起初&#xff0c;它是一个术语&#xff0c;用于描述比通用关系“数据库”更先进的任何复杂数据存储系统。现在&#xff0c;随着SaaS的出现&#xff0c;知识库一词的含义更加不同。根据定义&#xff0c;知识库是一个自助服务存储…