Java io知识点

如何理解IO,java中常用的IO模型有哪些#

IO(Input/Output)指的是输入/输出,是计算机与外部设备进行数据交换的一种机制。在Java中,IO操作主要涉及到输入流(InputStream)和输出流(OutputStream)两种类型,用于读取和写入不同类型的数据。Java提供了多种IO模型来满足不同的应用需求,常用的IO模型包括以下几种:

  1. 同步阻塞IO(Blocking IO):也称为标准IO,使用同步阻塞方式读写数据,即在进行IO操作时会一直阻塞直到数据读写完成。这种IO模型的优点是编程简单,易于理解和实现,但当IO数据量大时会造成程序的阻塞。
  2. 同步非阻塞IO(Non-blocking IO):也称为NIO,使用同步非阻塞方式读写数据,即在进行IO操作时不会一直阻塞,而是不断轮询是否有数据可以读写。这种IO模型的优点是可以在等待IO的同时进行其他操作,但由于需要轮询,会造成CPU的浪费。
  3. 多路复用IO(Multiplexed IO):也称为NIO(New IO),使用多路复用器对多个IO通道进行管理,避免轮询。多路复用器可以同时监控多个IO通道的读写事件,当有IO事件就绪时,通知程序进行读写操作。这种IO模型的优点是能够支持并发读写,效率较高,但对程序的编写和调试难度较大。
  4. 异步IO(Asynchronous IO):也称为AIO(Asynchronous IO),使用异步非阻塞方式读写数据,即在进行IO操作时不会阻塞,而是将IO操作交给操作系统,等数据就绪后再通知程序进行读写。这种IO模型的优点是可以支持高并发读写,但需要操作系统的支持,在某些场景下可能不适用。

Java中常用的IO模型主要有上述四种,具体选择哪种模型应根据应用需求和场景来决定。例如,当需要支持高并发IO操作时,可以选择多路复用IO模型或异步IO模型,而在需要编写简单的IO程序时可以选择同步阻塞IO模型。

磁盘IO和网络IO的区别#

磁盘IO和网络IO是两种不同的IO类型,它们在应用场景、实现方式和性能特征等方面都有所不同。

  1. 应用场景:磁盘IO主要用于读写本地磁盘上的文件,而网络IO则主要用于进行网络通信,包括从网络接收数据和向网络发送数据。
  2. 实现方式:磁盘IO是通过读写本地磁盘上的文件来实现,而网络IO则是通过读写网络套接字(socket)来实现。网络IO通常需要使用网络协议(如TCP、UDP等)来进行通信,而磁盘IO不需要。
  3. 性能特征:磁盘IO的速度通常较慢,因为它涉及到磁盘寻道、旋转和数据传输等多个步骤,而网络IO的速度通常较快,因为它通常涉及到的是高速网络链路的数据传输。另外,由于网络IO通常是异步进行的,因此可以支持高并发的IO操作,而磁盘IO通常是同步进行的,不太适合进行高并发IO操作。

总的来说,磁盘IO和网络IO都是计算机中常见的IO类型,它们各自有自己的特点和应用场景,在进行IO编程时应根据具体需求选择合适的IO类型和IO模型。

IO字节流和字符流的区别#

IO字节流和字符流是Java IO中的两种基本数据流类型,它们之间的主要区别在于处理的数据类型和方式。

  1. 数据类型:字节流以字节为单位读写数据,而字符流以字符为单位读写数据。字节流主要用于读写二进制数据(如图像、音频、视频等),而字符流主要用于读写文本数据(如文本文件、配置文件等)。
  2. 处理方式:字节流处理数据时是以字节为单位进行读写,而字符流处理数据时是以字符为单位进行读写。字节流读取时一次读取一个字节,写入时也一次写入一个字节;而字符流则会将字节流转换为字符流,并使用缓冲区来优化读写性能。
  3. 编码方式:字节流不关心数据的编码方式,它只是按照字节进行读写,而字符流则需要根据指定的编码方式进行读写。例如,当读取文本文件时,如果使用字节流进行读取,则需要自己编写编码转换的代码,而使用字符流则会自动进行编码转换。

综上所述,字节流和字符流在处理数据类型和方式、以及编码方式等方面都有所不同。在进行IO编程时,应根据读写的数据类型和具体需求来选择合适的IO流类型。如果需要读写文本数据,可以选择字符流,而如果需要读写二进制数据,则应该使用字节流。

NIO 中的 buffer,channel,selector 分别的作用#

NIO源码分析:https://juejin.cn/post/6844903765741404173

在 NIO 编程模型中,Buffer、Channel 和 Selector 是三个核心组件,分别负责缓存数据、数据通道的操作和多路复用管理。它们的具体作用如下:

  1. Buffer:缓存数据的容器,负责读写数据。在 NIO 中,所有数据的读写操作都是通过 Buffer 进行的。Buffer 封装了一组数据,并提供了一系列读写方法,可以方便地进行数据的存储和处理。
  2. Channel:数据通道的抽象,负责数据的传输。在 NIO 中,所有的 IO 操作都是通过 Channel 进行的。Channel 可以是一个文件、一个网络连接、一个管道等,可以读取和写入数据,并且支持非阻塞 IO 操作。
  3. Selector:多路复用器,负责管理多个 Channel。Selector 可以检测多个 Channel 上是否有数据可读、可写等事件,从而实现了单线程管理多个 Channel 的机制。在 NIO 中,Selector 是非常重要的组件,可以极大地提高 IO 操作的效率和性能。

总之,Buffer、Channel 和 Selector 是 NIO 编程模型中的三个核心组件,分别负责缓存数据、数据通道的操作和多路复用管理,共同协作实现了高效的 IO 操作。Buffer 用于读写数据,Channel 用于传输数据,Selector 用于管理多个 Channel,实现了非阻塞 IO 操作,提高了 IO 操作的效率。

详解NIO多路复用模型#

NIO(Non-blocking I/O)是一种基于多路复用器的高效 IO 编程模型,它通过一个线程可以管理多个通道(Channel)的方式,实现了非阻塞 IO 操作。NIO 的核心是 Selector,它是一个能够检测多个 NIO 通道(Channel)是否有数据可读、写入的 Java NIO 组件,通过注册多个 Channel 到 Selector 中,Selector 可以不断轮询每个 Channel 上是否有事件发生,从而实现了单线程管理多个 Channel 的机制。

多路复用模型的基本思想是:当一个线程的IO请求不能立即得到响应时,该线程可以立即释放CPU,并将该请求的状态保存下来,然后继续处理其他请求。当IO请求准备好之后,操作系统通知该线程,该线程再从之前的状态继续执行,实现了异步IO操作的效果。

NIO 的多路复用模型相较于传统的 IO 模型,具有以下优势:

  1. 单线程管理多个 Channel,可以有效减少线程的开销。
  2. 可以非阻塞地执行 IO 操作,提高了 IO 操作的效率。
  3. 可以通过配置 Selector 和 Channel 的参数,实现自定义的 IO 策略,更加灵活地控制 IO 操作。

在 NIO 的多路复用模型中,通常有以下几个核心组件:

  1. Selector:负责注册多个 Channel,并轮询这些 Channel 上是否有事件发生。
  2. Channel:与 IO 操作相关的抽象对象,可以是一个文件、一个网络连接、一个管道等。
  3. Buffer:缓冲区,用于存储数据。
  4. SelectionKey:Selector 和 Channel 之间的关联对象,每个 Channel 向 Selector 注册时都会生成一个 SelectionKey 对象。
  5. SocketChannel 和 ServerSocketChannel:SocketChannel 用于 TCP 连接的读写,ServerSocketChannel 用于监听 TCP 连接请求。

在实现 NIO 多路复用模型时,需要进行以下步骤:

  1. 创建 Selector。
  2. 创建 Channel,并将 Channel 注册到 Selector 中。
  3. 通过 Selector.select() 方法轮询所有注册的 Channel,获取可读、可写、连接等事件。
  4. 对于每个事件,执行相应的操作,比如读写数据等。
  5. 如果操作完成后,需要关闭 Channel,可以将 SelectionKey 取消注册,并关闭 Channel。

总之,NIO 的多路复用模型通过 Selector 实现了单线程管理多个 Channel 的机制,提高了 IO 操作的效率,并且能够通过配置 Selector 和 Channel 的参数,实现自定义的 IO 策略,更加灵活地控制 IO 操作。

Java NIO零拷贝#

Java NIO 零拷贝(Zero-copy)指的是在数据传输过程中,不需要将数据从一个缓冲区复制到另一个缓冲区,而是直接在数据源和目标之间传输数据,避免了数据复制的开销,提高了系统性能。

在 Java NIO 中,通过使用 Direct Buffer(直接缓冲区)可以实现零拷贝。Direct Buffer 是一种特殊的缓冲区,它的数据并不在 JVM 的堆中,而是在操作系统的内存中。使用 Direct Buffer 可以将数据直接传输到操作系统的内存中,避免了数据复制的开销。

Java NIO 零拷贝还可以通过 FileChannel 的 transferTo() 和 transferFrom() 方法实现。这两个方法可以将文件数据直接传输到另一个 Channel 或者从另一个 Channel 读取数据,避免了数据在用户空间和内核空间之间的复制。

总之,Java NIO 零拷贝技术可以避免数据复制的开销,提高系统性能。它可以通过使用 Direct Buffer 实现,在数据传输过程中避免了数据复制;也可以通过 FileChannel 的 transferTo() 和 transferFrom() 方法实现,将文件数据直接传输到另一个 Channel 或者从另一个 Channel 读取数据,避免了数据在用户空间和内核空间之间的复制

Java 堆外内存的管理和回收:https://juejin.cn/post/7115787649910046750#

在 Java NIO 中,堆外内存(Direct Memory)是由操作系统分配的内存,它不受 Java 堆内存大小的限制,可以提高程序的性能。但是,由于堆外内存不在 JVM 管理的堆中,因此无法像普通的 Java 对象一样通过垃圾回收来进行自动回收。因此,在使用堆外内存时,需要手动管理它们的生命周期,避免出现内存泄漏等问题。

一般来说,堆外内存的回收可以通过显式地释放内存来实现。在 Java NIO 中,可以通过调用 ByteBuffer 的 clear()、compact() 或者 force() 方法来释放堆外内存。其中,clear() 方法会将缓冲区的指针归零,但是并不会释放内存;compact() 方法会将所有未读的数据移到缓冲区的起始位置,然后释放所有已读的数据占用的内存;而 force() 方法会将数据写回磁盘,同时释放缓冲区占用的内存。在使用完堆外内存后,可以通过这些方法来释放内存,避免内存泄漏和占用过多的系统资源。

另外,在一些场景下,也可以通过 JVM 参数来设置堆外内存的最大限制,当堆外内存超过这个限制时,就会自动触发 Full GC。例如,可以通过设置 -XX:MaxDirectMemorySize 参数来限制堆外内存的最大大小。但是,这种方式并不能完全避免内存泄漏等问题,因此还需要手动管理堆外内存的生命周期。

什么是半包,粘包和拆包#

在网络通信中,由于网络传输的不确定性,会导致数据在传输过程中出现一些问题,其中比较常见的问题是“半包”、“粘包”和“拆包”。

  1. 半包:指发送方在传输数据时,将数据拆分成了多个小包,而接收方只接收到了其中的一部分,即“半包”。发生半包的原因可能是发送方缓存区的大小不足,或者网络传输过程中的延迟等。
  2. 粘包:指发送方在传输数据时,将多个小包合并成了一个大包发送,而接收方只接收到了其中的一部分,即“粘包”。发生粘包的原因可能是发送方缓存区的数据过多,或者网络传输过程中的延迟等。
  3. 拆包:指发送方在传输数据时,将一个完整的数据包拆分成了多个小包,而接收方只接收到了其中的一部分,即“拆包”。发生拆包的原因可能是发送方缓存区的数据大小超过了网络的最大传输单元(MTU),或者发送方在传输过程中对数据进行了分片等。

为了解决半包、粘包和拆包等问题,通常可以使用一些协议或技术进行处理,比如在数据包中添加特定的标识符或长度信息,或者使用特定的协议,如 HTTP、TCP、UDP 等。同时,还可以使用一些框架和库,如 Netty、Apache MINA 等,来简化网络通信中的数据处理和管理。

Socket中常用的拆包方式有哪些#

在 Socket 通信中,由于网络传输的不确定性,会出现粘包、拆包等问题。为了解决这些问题,常用的拆包方式有以下几种:

  1. 固定长度拆包:指在发送数据时,将每个数据包的长度设置为固定值,接收方每次读取指定长度的数据,这样就可以避免粘包和拆包问题。但是,如果数据包的长度不确定或者数据包较小,这种方式会造成资源的浪费。
  2. 分隔符拆包:指在发送数据时,将每个数据包的末尾添加一个特定的分隔符,例如“\n”或“\r\n”,接收方每次读取到分隔符时就将数据包拆分出来。这种方式可以处理数据包长度不确定的情况,但是如果数据包中本身就包含分隔符,就需要进行转义处理。
  3. 固定长度头部拆包:指在发送数据时,在数据包的头部添加一个固定长度的信息,用于表示数据包的长度,接收方先读取头部信息,再根据头部信息的长度读取数据包。这种方式可以避免粘包和拆包问题,但是需要在数据包头部添加额外的信息,会增加数据包的大小。
  4. 变长长度头部拆包:指在发送数据时,在数据包的头部添加一个变长长度的信息,用于表示数据包的长度,接收方先读取头部信息,再根据头部信息的长度读取数据包。这种方式可以处理数据包长度不确定的情况,但是需要在数据包头部添加额外的信息,会增加数据包的大小。

Netty 内置的拆包类有哪些#

Netty 是一款基于 NIO 的异步网络编程框架,内置了多种拆包类来帮助开发者解决粘包、拆包等问题,其中比较常用的拆包类有:

  1. DelimiterBasedFrameDecoder:分隔符拆包类,通过指定分隔符将接收到的数据拆分成一个个完整的数据包。
  2. FixedLengthFrameDecoder:固定长度拆包类,通过指定数据包的固定长度来将接收到的数据拆分成一个个完整的数据包。
  3. LengthFieldBasedFrameDecoder:基于长度域的拆包类,通过解析数据包中的长度域来将接收到的数据拆分成一个个完整的数据包。
  4. LineBasedFrameDecoder:基于换行符的拆包类,通过识别换行符将接收到的数据拆分成一个个完整的数据包。

这些拆包类都是在 Netty 内置的编解码器库(codec)中实现的,可以根据具体的业务需求选择合适的拆包类来解决粘包、拆包问题。同时,也可以通过继承这些拆包类来实现自定义的拆包逻辑。

什么是IO大小端#

IO大小端指的是在存储器中数据的字节顺序。字节顺序是指一个多字节数据类型的字节存储顺序。它影响了数据在内存中的表示方式和在不同系统间传输的方式。在计算机中,一个字节通常是8位二进制数,而一个多字节的数据类型(如整数或浮点数)需要在内存中存储多个字节。如果一个系统使用小端模式(little-endian),则最低有效字节(即数值中的最后一个字节)存储在最小的地址上,而最高有效字节(即数值中的第一个字节)存储在最大的地址上。相反,如果一个系统使用大端模式(big-endian),则最高有效字节存储在最小的地址上,而最低有效字节存储在最大的地址上。

例如,一个16位整数值0x1234,在小端模式下存储为0x34 0x12,在大端模式下存储为0x12 0x34。因此,在传输数据时,必须使用相同的字节序列才能正确解释数据,否则可能会导致解释错误。

详解TCP,UDP和HTTP协议,TCP三次握手和四次挥手#

TCP、UDP 和 HTTP 是常见的网络协议,它们各自具有不同的特点和用途。

  1. TCP 协议:TCP(Transmission Control Protocol)传输控制协议是一种可靠的、面向连接的协议。TCP 协议提供了三次握手、数据重传、流量控制、拥塞控制等功能,可以保证数据的可靠传输。TCP 协议适用于可靠性要求较高、数据量较大、传输速度不是关键因素的应用场景,如文件传输、邮件传输、网页浏览等。

TCP 三次握手和四次挥手是 TCP 协议的重要机制,分别用于建立和关闭连接。TCP 三次握手的过程如下:

  • 第一次握手:客户端向服务器发送 SYN 报文,请求建立连接;
  • 第二次握手:服务器接收到客户端的 SYN 报文后,向客户端发送 SYN+ACK 报文,表示同意建立连接;
  • 第三次握手:客户端接收到服务器的 SYN+ACK 报文后,向服务器发送 ACK 报文,表示连接建立成功。

TCP 四次挥手的过程如下:

  • 第一次挥手:客户端向服务器发送 FIN 报文,请求关闭连接;
  • 第二次挥手:服务器接收到客户端的 FIN 报文后,向客户端发送 ACK 报文,表示确认收到关闭请求;
  • 第三次挥手:服务器发送 FIN 报文,请求关闭连接;
  • 第四次挥手:客户端接收到服务器的 FIN 报文后,向服务器发送 ACK 报文,表示确认收到关闭请求。
  1. UDP 协议:UDP(User Datagram Protocol)用户数据报协议是一种不可靠的、无连接的协议。UDP 协议没有可靠性和流量控制的机制,不保证数据的可靠传输。UDP 协议适用于数据量小、传输速度较快、可靠性要求较低的应用场景,如实时视频、实时音频等。
  2. HTTP 协议:HTTP(Hypertext Transfer Protocol)超文本传输协议是一种应用层协议,用于在 Web 浏览器和 Web 服务器之间传输数据。HTTP 协议基于 TCP 协议实现,采用请求-响应模式,支持 GET、POST、PUT、DELETE 等多种请求方法。

以上是 TCP、UDP 和 HTTP 协议的简要介绍,对于 TCP 协议中的三次握手和四次挥手,它们的目的是为了建立连接和关闭连接时保证双方的同步。在建立连接时,三次握手可以避免因网络延迟导致的连接失败和资源浪费;在关闭连接时,四次挥手可以确

网络中的七层结构,了解SSL2安全协议#

网络中的七层结构指的是 OSI(Open System Interconnection,开放式系统互联)参考模型,它将计算机网络分为七层,每一层都有各自的功能和协议。

七层结构如下:

  1. 物理层(Physical Layer):负责物理接口,定义物理介质和传输方式,如电缆、光纤、无线电波等。
  2. 数据链路层(Data Link Layer):负责点对点的数据传输,实现数据的分帧和流量控制,如以太网、PPP 等。
  3. 网络层(Network Layer):负责数据在网络中的传输,实现路由和寻址功能,如 IP 协议、ICMP 协议等。
  4. 传输层(Transport Layer):负责端到端的数据传输,实现可靠性和流量控制,如 TCP 协议、UDP 协议等。
  5. 会话层(Session Layer):负责建立、维护和释放会话连接,如 NFS 协议等。
  6. 表示层(Presentation Layer):负责数据格式的转换、加密和解密等,如 JPEG 格式、MPEG 格式等。
  7. 应用层(Application Layer):负责应用程序的通信和协议,如 HTTP 协议、FTP 协议等。

SSL(Secure Sockets Layer)是一种用于保护网络通信安全的协议,它建立在 TCP/IP 协议之上,提供了身份验证、加密和数据完整性保护等功能。SSL 有三个版本,分别是 SSLv2、SSLv3 和 TLS(Transport Layer Security)。

SSLv2 是 SSL 协议的第一个版本,于 1995 年发布。SSLv2 存在严重的安全漏洞,容易受到中间人攻击,因此已经被广泛淘汰。SSLv3 于 1996 年发布,是 SSLv2 的改进版本,但也存在一些安全漏洞,被 TLS 代替。TLS 在 1999 年发布,是 SSL 的后续版本,提供更加安全的加密和认证机制,被广泛应用于互联网的安全通信中。

什么是Socket,socket底层如何实现网络通信#

Socket是一种应用层和传输层之间的中间软件抽象层,它提供了一组接口,使得应用程序可以通过网络进行通信。在网络通信中,Socket扮演的角色类似于电话中的话筒和听筒,它是应用程序与网络之间的接口。

Socket底层的实现是通过传输层协议来实现网络通信。在 TCP/IP 协议中,Socket 通常使用 IP 地址和端口号来标识网络上的进程。当应用程序需要建立网络连接时,它会创建一个 Socket 对象,然后将目标主机的 IP 地址和端口号传递给 Socket 对象,Socket 对象就可以开始与目标主机进行通信。

在 TCP 协议中,Socket 通信采用三次握手建立连接,即客户端发送 SYN 报文,服务器回复 SYN-ACK 报文,客户端再回复 ACK 报文,连接建立后,客户端和服务器就可以进行数据的传输。

在 Socket 底层实现中,网络通信使用了操作系统提供的网络协议栈。当应用程序进行网络通信时,Socket 对象会将数据发送给操作系统的网络协议栈,然后网络协议栈会将数据经过一系列的处理后,发送给目标主机。当目标主机接收到数据时,网络协议栈会将数据发送给对应的进程,然后该进程就可以对数据进行处理了。

总的来说,Socket 底层实现是基于操作系统提供的网络协议栈来实现的,它提供了一种方便的接口,使得应用程序可以方便地进行网络通信

如何实现分布式的长链接通信#

分布式的长链接通信一般需要使用一些分布式通信框架,比如 Dubbo、gRPC 等。

其中,Dubbo 是一种基于长连接的分布式服务框架,它使用 Netty 作为底层通信框架,通过在服务提供者和消费者之间建立长连接,实现了高效的通信。

gRPC 也是一种基于长连接的分布式通信框架,它使用 HTTP/2 作为底层通信协议,通过建立长连接,实现了高效的通信。gRPC 还提供了多语言支持,可以方便地进行跨语言通信。

除了使用分布式通信框架外,还可以通过自己实现分布式长链接通信。一般情况下,分布式长链接通信需要解决以下几个问题:

  1. 服务发现和负载均衡:分布式系统中,服务可能存在多个实例,需要使用服务发现和负载均衡技术来选择合适的实例进行通信。
  2. 连接管理:在分布式系统中,长连接的数量可能很大,需要使用连接池等技术来管理长连接的生命周期。
  3. 可靠性保证:在网络通信中,可能存在消息丢失、重复等问题,需要使用可靠性保证技术,比如消息确认、重传等。
  4. 安全性保证:在分布式系统中,需要考虑通信的安全性问题,比如数据加密、身份认证等。

IM即时通讯#

http://www.52im.net/thread-1243-1-1.html

https://www.cnblogs.com/imteck4713/p/14778097.html

参考博客:
网络编程:https://mp.weixin.qq.com/s?__biz=MzkwODE5ODM0Ng==&mid=2247489885&idx=1&sn=1a4cb15c40c07e18f180df6fda8f472f&chksm=c0ccf1f8f7bb78eef66f067d63e2abdf1092847eba6372b6e4c15185a6d6ce7d407278c83e6f&scene=178&cur_album_id=2041709347461709827#rd

posted @   糯米๓  阅读(14)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示