Java- IO 及其相关面试题(下)

简介: Java- IO 及其相关面试题(下)

六、 序列化和反序列化

6.1. Serializable接口

    Serializable接口是Java中的一个标记接口,它告诉Java虚拟机(JVM)这个类是可以被序列化的。序列化是将对象转换为字节流的过程,而反序列化则是将字节流转换回对象。   Serializable接口没有任何方法,因此它只是一个标记接口,表示可以被序列化和反序列化。当一个类实现Serializable接口时,JVM会自动处理该类的序列化和反序列化过程。

6.2 ObjectOutputStream和ObjectInputStream

    ObjectOutputStream类将Java对象序列化到文件或网络流中。而ObjectInputStream类则用于从文件或网络流中反序列化Java对象。

下面是一个将对象序列化到文件中的示例代码:

try {
    FileOutputStream fileOut = new FileOutputStream("output.ser");
    ObjectOutputStream out = new ObjectOutputStream(fileOut);
    out.writeObject(new Person("John", 30));
    out.close();
    fileOut.close();
} catch (IOException e) {
    e.printStackTrace();
}

这个示例代码创建了一个ObjectOutputStream对象,将一个Person对象序列化到名为"output.ser"的文件中。

下面是一个从文件中反序列化Java对象的示例代码:

try {
    FileInputStream fileIn = new FileInputStream("output.ser");
    ObjectInputStream in = new ObjectInputStream(fileIn);
    Person person = (Person) in.readObject();
    in.close();
    fileIn.close();
} catch (IOException e) {
    e.printStackTrace();
} catch (ClassNotFoundException e) {
    e.printStackTrace();
}

这个示例代码从名为"output.ser"的文件中读取一个Person对象,并将其反序列化为一个Java对象。

6.3 Externalizable接口

   Externalizable接口是Serializable接口的子接口,它提供了更多的序列化和反序列化方法。Externalizable接口定义了writeExternal和readExternal方法,用于将对象序列化和反序列化到字节流中。


下面是一个使用Externalizable接口序列化和反序列化Java对象的示例代码:

try {
    Person person = new Person("John", 30);
    DataOutputStream out = new DataOutputStream(new FileOutputStream("output.ser"));
    person.writeExternal(out);
    out.close();
    FileInputStream in = new FileInputStream("output.ser");
    Person newPerson = new Person();
    newPerson.readExternal(in);
    in.close();
} catch (IOException e) {
    e.printStackTrace();
}

  这个示例代码使用DataOutputStream将Person对象序列化到名为"output.ser"的文件中,然后使用DataInputStream从文件中反序列化Person对象。

七、异常处理和资源管理

7.1 异常处理

    常见的IO异常包括FileNotFoundException、IOException和EOFException。在处理IO异常时,应该捕获IOException并处理它,因为它是所有IO异常的父类。

下面是一个处理IO异常的示例代码:

try {
    // 执行 IO 操作
} catch (FileNotFoundException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}

7.2 资源管理

    在处理IO流时,应该正确地关闭流和释放资源,以避免资源泄漏。可以使用try-with-resources语句来自动关闭流,例如:

try (FileInputStream fileIn = new FileInputStream("output.ser");
     ObjectInputStream in = new ObjectInputStream(fileIn)) {
    // 读取对象
} catch (IOException e) {
    e.printStackTrace();
}

  这个示例代码使用try-with-resources语句创建了一个FileInputStream和一个ObjectInputStream对象,并在try块结束时自动关闭它们。这样可以确保资源被正确地释放,避免资源泄漏。

八、NIO、BIO、AIO

8.1 什么是NIO、BIO、AIO?

    NIO、BIO、AIO是 Java 中不同类型的 I/O 操作。
   NIO (Non-blocking I/O) 是非阻塞 I/O,它不会阻塞线程,而是在读写操作完成之后通知线程。


   BIO (Blocking I/O) 是阻塞 I/O,它会在读写操作完成之前阻塞线程,等待数据读写完成。


   AIO (Asynchronous I/O) 是异步 I/O,它不会阻塞线程,而是使用回调函数通知线程读写操作已完成。

维度 BIO NIO AIO
IO模型 同步阻塞IO 同步非阻塞IO 异步非阻塞IO
编程模型 基于流(Stream) 基于缓冲区(Buffer) 基于事件(Event)
代码复杂度 简单 较复杂 最复杂
并发性能 较好 最好
可扩展性 较好 最好
资源消耗
对网络连接数 单线程处理多个连接 单线程处理多个连接 多线程处理多个连接
对操作系统支持 全面支持 仅支持较新版本 仅支持Linux和Windows
应用场景 对并发性能要求不高的小型应用 对并发性能要求较高的中小型应用 对并发性能要求最高的大型应用
IO模型 同步阻塞IO 同步非阻塞IO 异步非阻塞IO
编程模型 基于流(Stream) 基于缓冲区(Buffer) 基于事件(Event)
代码复杂度 简单 较复杂 最复杂
并发性能 较好 最好
可扩展性 较好 最好
资源消耗
对网络连接数 单线程处理多个连接 单线程处理多个连接 多线程处理多个连接
对操作系统支持 全面支持 仅支持较新版本 仅支持Linux和Windows
应用场景 对并发性能要求不高的小型应用 对并发性能要求较高的中小型应用 对并发性能要求最高的大型应用
IO模型 同步阻塞IO 同步非阻塞IO 异步非阻塞IO
编程模型 基于流(Stream) 基于缓冲区(Buffer) 基于事件(Event)
代码复杂度 简单 较复杂 最复杂
并发性能 较好 最好
可扩展性 较好 最好
资源消耗
对网络连接数 单线程处理多个连接 单线程处理多个连接 多线程处理多个连接
对操作系统支持 全面支持 仅支持较新版本 仅支持Linux和Windows
应用场景 对并发性能要求不高的小型应用 对并发性能要求较高的中小型应用 对并发性能要求最高的大型应用

8.2 Buffer和Channel

    Buffer是一个对象,可以存储特定类型的数据。与之相对的是Channel,它是数据的源或目标,可以与Buffer进行交互。在NIO中,数据通过Buffer在Channel之间传输。

在Java NIO中,常用的Buffer类有以下几种:ByteBuffer: 存储字节数据

CharBuffer: 存储字符数据

ShortBuffer: 存储短整数数据

IntBuffer: 存储整数数据

LongBuffer: 存储长整数数据

FloatBuffer: 存储浮点数数据

DoubleBuffer: 存储双精度浮点数数据


Channel是与数据源或目标进行通信的对象。常用的Channel类型有:
FileChannel: 用于文件的读写操作


SocketChannel: 用于通过TCP进行网络通信

DatagramChannel:用于通过UDP进行网络通信

ServerSocketChannel: 用于监听TCP连接请求


下面是一个使用Buffer和Channel进行文件读写的示例代码:

import java.io.*;
import java.nio.*;
import java.nio.channels.*;
public class FileReadWriteExample {
    public static void main(String[] args) {
        try {
            // 打开文件输入流和输出流
            FileInputStream fis = new FileInputStream("input.txt");
            FileOutputStream fos = new FileOutputStream("output.txt");
            // 获取文件输入流和输出流对应的通道
            FileChannel inputChannel = fis.getChannel();
            FileChannel outputChannel = fos.getChannel();
            // 创建缓冲区
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            // 从输入通道读取数据到缓冲区
            int bytesRead = inputChannel.read(buffer);
            while (bytesRead != -1) {
                // 切换为读模式
                buffer.flip();
                // 从缓冲区写入数据到输出通道
                outputChannel.write(buffer);
                // 清空缓冲区,准备下一次读取
                buffer.clear();
                // 继续从输入通道读取数据
                bytesRead = inputChannel.read(buffer);
            }
            // 关闭通道和流
            inputChannel.close();
            outputChannel.close();
            fis.close();
            fos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

以下是关于Java IO的常用类的表格:

九、相关面试题

什么是缓冲流?为什么要使用它?

    缓冲流(Buffered Stream)是一种性能优化的流,它使用缓冲区来减少对底层资源(如磁盘或网络)的访问次数,从而提高读写效率。
什么是序列化?如何实现Java对象的序列化?

    序列化是将对象转换为字节流的过程,以便可以将其存储在文件中或通过网络传输。要实现Java对象的序列化,需要实现Serializable接口,并定义一个特殊的serialVersionUID字段。如何使用Java IO进行网络编程?

    可以使用Socket类和ServerSocket类来实现基于TCP/IP的网络编程。Socket类用于创建客户端套接字,ServerSocket类用于创建服务器套接字。通过这些类,可以在网络上发送和接收数据。

相关文章
|
17小时前
|
设计模式 算法 Java
Java的前景如何,好不好自学?,万字Java技术类校招面试题汇总
Java的前景如何,好不好自学?,万字Java技术类校招面试题汇总
|
17小时前
|
存储 网络协议 前端开发
es集群安装,邮储银行java面试
es集群安装,邮储银行java面试
|
17小时前
|
消息中间件 JSON Java
十五,java高级程序员面试宝典
十五,java高级程序员面试宝典
|
17小时前
|
NoSQL 算法 Java
【redis源码学习】持久化机制,java程序员面试算法宝典pdf
【redis源码学习】持久化机制,java程序员面试算法宝典pdf
|
17小时前
|
消息中间件 Java Kafka
Java大文件排序(有手就能学会),kafka面试题2024
Java大文件排序(有手就能学会),kafka面试题2024
|
19小时前
SpringJDK动态代理实现,2024Java面试真题精选干货整理
SpringJDK动态代理实现,2024Java面试真题精选干货整理
|
19小时前
|
安全 前端开发 Java
Java岗大厂面试百日冲刺 - 日积月累,每日三题【Day15
Java岗大厂面试百日冲刺 - 日积月累,每日三题【Day15
|
21小时前
|
Java
阅读《代码整洁之道》总结(1),java多线程面试
阅读《代码整洁之道》总结(1),java多线程面试
|
21小时前
|
NoSQL Java 关系型数据库
爱了!阿里高工纯手打金三银四Java架构面试大全,涵盖近年来1000余道大厂面试真题
爱了!阿里高工纯手打金三银四Java架构面试大全,涵盖近年来1000余道大厂面试真题
|
21小时前
|
Java 程序员
Java this关键字详解(3种用法),Java程序员面试必备的知识点
Java this关键字详解(3种用法),Java程序员面试必备的知识点