当前位置: 首页 > news >正文

【Java核心技术/IO】35道Java IO面试题与答案

1. 什么是Java IO?

Java IO是Java提供的用于输入输出操作的API,主要处理文件、网络连接等数据的读取和写入,核心是“流”(Stream)的概念。

2. Java IO主要分为哪几类?

按数据流向分为输入流(InputStream/Reader) 和输出流(OutputStream/Writer);按处理数据类型分为字节流(处理二进制数据)和字符流(处理文本数据,需指定编码)。

3. 字节流和字符流的区别是什么?

  • 处理数据:字节流以 byte (8位)为单位,处理所有二进制数据;字符流以 char (16位)为单位,仅处理文本数据。
  • 编码依赖:字符流需依赖编码(如UTF-8),字节流不依赖。
  • 核心类:字节流核心是 InputStream/OutputStream ,字符流是 Reader/Writer 。

4. 什么是缓冲流(Buffered Stream)?它的作用是什么?

缓冲流是包装普通流的“增强流”(如 BufferedReader 、 BufferedOutputStream ),内部维护一个缓冲区(内存数组)。
作用:减少IO与磁盘/网络的直接交互次数,提升读写效率(内存操作比硬件操作快得多)。

5. 缓冲流的 flush() 方法有什么用?

强制将缓冲区中未写满的数据立即写入目标设备(如磁盘),避免数据滞留。关闭流( close() )时会自动调用 flush() ,但需注意:若未关闭/flush,缓冲区未满的数据可能丢失。

6. 什么是节点流(Node Stream)和处理流(Processing Stream)?

  • 节点流:直接连接数据源/目标的流(如 FileInputStream 直接读文件),是IO操作的“基础流”,必须存在。
  • 处理流:包装节点流或其他处理流的流(如缓冲流、转换流),用于增强功能(如缓冲、编码转换),不能独立存在。

7. 转换流(InputStreamReader/OutputStreamWriter)的作用是什么?

实现字节流与字符流的转换:

  • InputStreamReader :将字节流(如 FileInputStream )转为字符流,需指定编码(解决文本读取乱码问题)。
  • OutputStreamWriter :将字符流转为字节流,写入时指定编码。

8. 什么是对象流(ObjectInputStream/ObjectOutputStream)?

用于对象的序列化(写对象到流)和反序列化(从流读对象) 的处理流,核心方法是 writeObject() 和 readObject() 。
注意:被序列化的类必须实现 Serializable 接口(空接口,仅作标记)

9. Serializable 接口的作用是什么?为什么是标记接口?

Serializable 是Java的序列化标记接口,作用是告诉JVM:“该类的对象允许被序列化”。
它是标记接口(无任何抽象方法),因为仅需“标记”类的序列化权限,无需强制实现特定逻辑。

10. 序列化时,如何让某个字段不被序列化?

在该字段前加 transient 关键字,JVM会忽略该字段,序列化时不写入流,反序列化时该字段会被赋默认值(如 null 、0)。

11. 什么是序列化ID(serialVersionUID)?有什么用?

serialVersionUID 是序列化类中显式声明的一个 long 类型常量(如 private static final long serialVersionUID = 1L ),用于验证序列化与反序列化的对象是否属于同一个类。
若类未显式声明,JVM会根据类结构(字段、方法)自动生成;若类结构修改(如增删字段),自动生成的ID会变,导致反序列化失败。

12. Java IO中的“流”是阻塞的还是非阻塞的?

默认的Java IO(BIO)是阻塞式的:当调用 read() / write() 时,若数据未准备好/未写完,线程会一直等待(阻塞),直到操作完成。

13. 什么是NIO?它和传统IO(BIO)的区别是什么?

NIO(New IO)是Java 1.4引入的非阻塞IO模型,核心是通道(Channel)、缓冲区(Buffer)、选择器(Selector)。
区别:

  • 阻塞性:BIO是阻塞的,NIO可非阻塞(线程无需等待IO完成)。
  • 数据操作:BIO以流为单位,NIO以缓冲区(批量数据)为单位。
  • 线程效率:BIO一个连接需一个线程,NIO一个线程可处理多个连接(通过Selector)。

14. NIO中的Buffer和Channel是什么关系?

  • Buffer:是数据的“容器”,用于存储读写的数据(NIO中数据必须通过Buffer传输)。
  • Channel:是数据的“传输通道”(如文件通道、网络通道),用于连接数据源/目标。
    关系:数据从Channel读入Buffer,或从Buffer写入Channel(双向,而流是单向的)。

15. NIO的Selector有什么用?

Selector(选择器)是NIO实现“单线程处理多连接”的核心组件。
它可注册多个Channel,监听Channel的IO事件(如“数据可读”“连接就绪”),线程只需通过Selector轮询“就绪事件”,再处理对应Channel,无需阻塞等待。

16. Java 7引入的NIO.2有什么新特性?

核心是 java.nio.file 包,新增特性:

  • Path接口:替代传统 java.io.File ,更方便处理文件路径。
  • Files工具类:提供静态方法,简化文件操作(如 Files.readAllLines() 读文件、 Files.copy() 复制文件)。
  • 异步IO(Asynchronous IO):支持异步的文件和网络IO,操作完成后通过回调/Future通知。

17. File 类的作用是什么?它能操作文件内容吗?

File 类是文件/目录路径的抽象表示,用于操作文件的“元数据”(如判断文件是否存在、创建/删除文件、获取文件大小),但不能直接操作文件内容(读写内容需通过流或NIO的Channel)。

18. 如何用Java IO复制一个文件?

核心逻辑:用输入流读源文件,用输出流写目标文件,通过缓冲区提升效率。示例代码思路:
java
try (InputStream in = new BufferedInputStream(new FileInputStream(“源文件路径”));
OutputStream out = new BufferedOutputStream(new FileOutputStream(“目标文件路径”))) {
byte[] buf = new byte[1024]; // 1KB缓冲区
int len;
while ((len = in.read(buf)) != -1) { // 读入缓冲区
out.write(buf, 0, len); // 从缓冲区写出
}
} catch (IOException e) {
e.printStackTrace();
}

19. Reader 类的 read() 方法返回值是什么意思?

Reader 的 read() 有两种常用重载:

  • int read() :读取一个字符,返回该字符的Unicode值(0-65535);若已到流末尾,返回 -1 。
  • int read(char[] cbuf) :读取字符到数组 cbuf ,返回实际读取的字符数;若到末尾,返回 -1 。

20. 为什么推荐用“try-with-resources”语法处理IO流?

传统 try-catch-finally 需手动关闭流( close() ),若忘记关闭或 finally 中代码出错,会导致流泄漏。
try-with-resources (Java 7+)会自动关闭实现 AutoCloseable 接口的资源(所有IO流都实现了该接口),代码更简洁,且能确保资源关闭。

21. AutoCloseable 和 Closeable 接口的关系是什么?

  • Closeable 是Java 5引入的接口,仅含 void close() throws IOException 方法,用于IO资源关闭。
  • AutoCloseable 是Java 7引入的父接口,含 void close() throws Exception 方法,范围更广(支持所有需自动关闭的资源)。
    关系: Closeable 继承自 AutoCloseable ,IO流实现 Closeable ,因此可被 try-with-resources 自动关闭。

22. 什么是字符编码?IO操作中如何避免乱码?

字符编码是“字符与二进制数据的映射规则”(如UTF-8、GBK)。乱码源于“写入编码与读取编码不一致”。
避免乱码:

  • 字符流/转换流操作时,显式指定编码(如 new InputStreamReader(in, “UTF-8”) ),不依赖系统默认编码。
  • 统一项目编码(如全用UTF-8)。

23. PrintStream 和 PrintWriter 的区别是什么?

两者都是“打印流”,支持格式化输出(如 print() 、 println() ),区别:

  • 流类型: PrintStream 是字节流, PrintWriter 是字符流。
  • 编码支持: PrintWriter 构造时可显式指定编码, PrintStream 需通过 OutputStreamWriter 间接指定。
  • 异常处理:两者都不抛 IOException ,需通过 checkError() 方法检查是否有错误。

24. 什么是数据流(DataInputStream/DataOutputStream)?

数据流是处理“基本数据类型(如int、double) ”的字节流,可直接读写基本数据类型,无需手动转换为字节数组。
示例: dataOut.writeInt(100) 写入int, dataIn.readInt() 读取int。

25. 随机访问文件(RandomAccessFile)有什么特点?

RandomAccessFile 是特殊的IO类,支持“随机读写”(可跳转到文件任意位置操作),无需从头顺序读写。
核心方法:

  • seek(long pos) :跳转到文件指定位置(字节偏移量)。
  • readXXX() / writeXXX() :读写基本数据类型。
    用途:适用于大文件分段读写(如断点续传)。

26. IO流关闭的顺序是什么?为什么?

若多个流嵌套(如缓冲流包装文件流),关闭顺序是“先关外层流,再关内层流”;但实际用 try-with-resources 时,会自动按“声明逆序”关闭,无需手动控制。
原因:外层流依赖内层流,关闭外层流时会自动关闭内层流(避免内层流泄漏);若先关内层流,外层流关闭时可能报错。

27. 什么是“流泄漏”?如何避免?

流泄漏是“IO流未关闭,导致系统资源(如文件句柄、网络连接)被占用,无法释放”,长期会导致资源耗尽。
避免方式:

  • 用 try-with-resources 自动关闭流。
  • 传统方式中,在 finally 块中确保 close() (需判空,避免空指针)。

28. NIO中的“零拷贝”是什么意思?有什么优势?

零拷贝(Zero-Copy)是NIO优化IO性能的技术,指“数据从内核空间直接传输到目标设备(如网络),无需在内核空间与用户空间之间拷贝”(传统IO需2-4次拷贝)。
优势:减少CPU拷贝开销,提升大文件传输效率(如文件下载、视频流),常见于 FileChannel.transferTo() 方法。

29. 什么是BIO、NIO、AIO?它们的适用场景是什么?

  • BIO:阻塞IO,简单易实现,适用于“连接数少、IO操作快”的场景(如本地文件操作、简单Socket服务)。
  • NIO:非阻塞IO,适用于“连接数多、IO操作慢”的场景(如高并发网络服务,如Tomcat底层)。
  • AIO:异步IO(NIO.2),适用于“需异步通知、不希望阻塞线程”的场景(如高性能服务器,如Netty的AIO模式)。

30. Netty框架和Java NIO的关系是什么?

Netty是基于Java NIO的“高性能网络编程框架”,它封装了NIO的复杂细节(如Selector轮询、缓冲区管理、线程模型),提供更简洁的API和更稳定的性能,解决了NIO的“空轮询”“线程安全”等问题,是企业级网络服务(如RPC、网关)的首选。

31. ByteArrayInputStream 和 ByteArrayOutputStream 的作用是什么?

两者是“内存流”,数据读写基于字节数组(内存),不依赖磁盘/网络,速度快。

  • ByteArrayInputStream :从字节数组读数据(模拟输入流)。
  • ByteArrayOutputStream :向字节数组写数据(模拟输出流),可通过 toByteArray() 获取最终字节数组。
    用途:适用于内存中数据转换(如字符串与字节数组互转)、测试IO逻辑。

32. 什么是字符集(Charset)?如何获取系统默认字符集?

字符集(Charset)是字符编码的集合(如UTF-8、GBK), java.nio.charset.Charset 类是其抽象表示。
获取系统默认字符集:

  • Charset.defaultCharset() :返回JVM默认字符集(依赖操作系统和JVM配置)。
  • System.getProperty(“file.encoding”) :通过系统属性获取,与 defaultCharset() 结果一致。

33. IO操作中, read() 方法返回-1表示什么?

read() 返回-1表示“已到达流的末尾”(没有更多数据可读取),是IO读取循环的终止条件(如 while ((len = in.read(buf)) != -1) )。

34. 为什么 FileInputStream 的 read() 方法返回int类型,而不是byte类型?

byte 类型范围是 -128~127 ,若直接返回byte,当读取的字节是 0xFF (对应十进制255)时,会被解析为 -1 ,与“流末尾”的 -1 冲突。
返回int时,会将byte的8位数据“高位补0”转为32位int(如 0xFF 转为 255 ),仅当真正到流末尾时返回 -1 ,避免歧义。

35. 总结Java IO的核心组件和设计模式?

  • 核心组件:流(字节流/字符流)、缓冲区、通道、选择器、Path、Files工具类。
  • 设计模式:
  1. 装饰器模式:处理流包装节点流(如缓冲流装饰文件流),增强功能。
  2. 适配器模式:转换流(如 InputStreamReader )将字节流适配为字符流。
  3. 工厂模式: Files.newBufferedReader() 等方法创建流实例。
http://www.dtcms.com/a/453441.html

相关文章:

  • ICT 数字测试原理 10 - -VCL 向量如何执行之数字单元
  • 网站目录爬行wordpress怎么做信息分类
  • 专题三:二分查找~
  • 360小工具合集,用39个小工具
  • GreenTuber 0.1.7.6| 纯净无广的油管第三方,支持4K下载
  • UVa 235 Typesetting
  • 东莞营销网站建设哪个平台好十大app排行榜
  • asp网站开发工具现在的企业一般用的什么邮箱
  • 企业区块链重新崛起
  • 【SSH】同一局域网下windows使用Xshell SSH连接另一台 ubuntu 22.04 电脑
  • [随手记] docker 镜像拉取记录
  • Ruoyi 赋能,百度天气不止当下:打造面向未来的预报实战
  • 网站搭建流程负责人长春制作网站哪家好
  • 日语学习-日语知识点小记-进阶-JLPT-N1阶段应用练习(7):语法 +考え方20+2022年7月N1
  • 天天爱天天做网站广告联盟没有网站怎么做
  • 1688 关键词搜索接口深度开发:从精准匹配到供应链筛选的技术实现
  • 网站多域名怎么做绿色网站模板大全
  • 深入理解 Vue 3 组件间数据传递的多种方式
  • 华威桥网站建设wordpress去除更新
  • .net 网站生成安装文件目录asp运行wordpress
  • 免费手机网站模板网站开发设计框图
  • 自助建站官网wordpress免费主机空间
  • systemd-resolved.service实验实战2
  • 基于 GEE 的 GWCCI 指数大豆识别与制图研究
  • Python argparse库介绍(内置的命令行参数解析库)(未检查)
  • JMeter之 json提取器与json path语法
  • 深度学习之神经网络2(Neural Network)
  • 做UI设计的网站网站界面设计尺寸
  • Python全栈(基础篇)——Day06:后端内容(定义函数+调用函数+实战演示+每日一题)
  • C++算法·贪心例题讲解