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

Java中的I/O模型——BIO、NIO、AIO

1. BIO(Blocking I/O)

1. 1 BIO(Blocking I/O)模型概述

        BIO,即“阻塞I/O”(Blocking I/O),是一种同步阻塞的I/O模式。它的主要特点是,当程序发起I/O请求(比如读取数据或写入数据)时,程序会一直等到这个请求完成,才继续往下执行。在BIO模型下,每个连接都需要一个独立的线程去处理。

        举个简单的例子:假设你写了一个服务器,它会接收客户端的连接,并与客户端进行数据交流。在BIO模式下,这个服务器每接收一个连接,就需要新创建一个线程来处理该连接的数据读写。这意味着:

  • 如果有100个客户端同时连接服务器,服务器需要创建100个线程来处理。
  • 如果客户端不发送数据,线程就会空闲等待,但依旧会占用系统资源(例如CPU和内存)。

        这种模型对于连接数量较少连接时间较短的场景比较合适。但是如果连接数量增多,比如成千上万个连接,BIO模式就显得捉襟见肘了,因为线程数量会迅速增加,系统资源会被大量占用,最终导致性能下降。

1.2BIO的工作原理

        在BIO(Blocking I/O)模式中,关键的机制就是“阻塞”。简单来说,阻塞意味着当一个I/O操作(例如读取数据)在进行时,程序会“停下来”直到操作完成才能继续。让我们一步步来看一个BIO服务器的典型工作流程:

  1. 等待客户端连接:服务器启动后,会在某个端口上等待客户端的连接请求。

  2. 接收连接:当客户端发起连接时,服务器会接收该连接,并创建一个新的线程来处理这个连接。这个线程负责处理客户端发送过来的所有数据,直到连接关闭。

  3. 数据读取阻塞:一旦线程开始读取数据,它会进入阻塞状态,直到收到完整的数据或遇到异常。在这期间,线程不能做其他事情。想象成排队买票,一个窗口只能接待一个人,其他人都得等前一个人买完才能上前。

  4. 处理数据:当线程收到数据后,它会处理这些数据(例如解析请求、生成响应)。

  5. 发送数据阻塞:处理完数据后,线程会将响应发送给客户端。在发送过程中,线程也会被阻塞,直到数据全部发送完毕。

  6. 结束连接或继续等待:如果客户端断开连接,线程会关闭。如果客户端保持连接,线程会继续等待下一个数据块的到来。

        整个流程看似简单,但每一个连接都占用一个线程。所以,一旦连接数较多,系统资源就会迅速消耗,产生以下问题:

1.3 BIO的优缺点分析

优点

  1. 逻辑简单:BIO模型结构直观,每个线程专门服务一个客户端连接,代码编写和调试相对简单。

  2. 适合短连接:对于连接时间较短、交互少的场景(例如Web应用中的HTTP请求),BIO模型能胜任。

缺点

  1. 资源占用高:由于每个连接都需要一个线程来处理,线程数量直接与连接数成正比,导致资源消耗随连接数增加而大幅度提高。

  2. 性能瓶颈:线程之间需要竞争CPU时间片,同时可能会导致大量线程进入等待状态(因为阻塞I/O),从而降低CPU的整体利用率。

  3. 扩展性差:BIO模型并不适合需要处理大量并发连接的应用场景,比如实时聊天系统或大规模服务器。因为线程数受限于系统资源,过多的线程会拖慢系统响应速度,甚至导致崩溃。

2. NIO(Non-blocking I/O)

        NIO,全称非阻塞I/O(Non-blocking I/O),是Java在1.4版引入的一种新I/O模型,它通过非阻塞机制和多路复用(Selector)来管理大量的连接,目标是提高高并发下的性能。我们分步来看看NIO的特点和工作流程。

2.1 NIO的关键概念

  1. 非阻塞(Non-blocking):NIO允许线程在等待I/O操作时不用一直被“卡住”。比如,线程可以发起一个读取请求并立即返回,如果数据未准备好,线程可以先去做其他事,不会阻塞等待。

  2. 多路复用(Selector):NIO通过一个Selector来管理多个通道(Channel)和连接。Selector是一个事件管理器,能在同一线程中监控多个连接的状态,只有当某个连接有数据准备好时才处理该连接。这使得一个线程可以处理多个连接,节省了大量的资源。

2.2 NIO的核心组件

在NIO中,有几个核心组件我们需要理解:

  • Channel(通道):类似于BIO中的“流”,但Channel是双向的,即既能读又能写。常用的Channel包括SocketChannel(用于网络数据传输)、FileChannel(用于文件操作)等。

  • Buffer(缓冲区):在NIO中,数据读写都是通过缓冲区进行的。缓冲区是一个可以存放数据的内存区域,数据读写都会先进入缓冲区,再从缓冲区进行处理。

  • Selector(选择器)Selector负责监听多个Channel的状态,可以在一个线程内监控多个连接,只有当Channel有数据可读、可写或有新的连接时,Selector才会触发处理。

2.3 NIO的工作流程

让我们一步步看NIO是如何工作的:

  1. 创建通道(Channel)并注册到选择器(Selector)

    • 服务器创建一个ServerSocketChannel并绑定端口,等待客户端连接。
    • ServerSocketChannel设置为非阻塞模式,并注册到Selector,表示服务器现在开始通过Selector管理该通道。
  2. 选择器轮询事件

    • 服务器主线程调用Selector.select()方法。这是一个阻塞方法,但它会在有事件发生时返回,例如某个Channel有新数据可读、可写,或有新连接到达。
    • 一旦有事件触发,Selector会返回这些事件的集合,服务器线程可以根据这些事件选择性地处理相应的通道。
  3. 处理事件(如读取或写入)

    • 假设一个通道上有数据可读,服务器线程会读取数据并将它放入缓冲区,进行相应的业务逻辑处理。
    • 读取完成后,线程可以继续检查其他通道的状态,不必在一个连接上等待。
  4. 结束或继续等待

    • 如果客户端关闭连接,服务器会注销该通道;否则,线程继续通过Selector等待新事件。

2.4 NIO的优缺点分析

优点

  • 高效的资源利用:一个线程可管理多个连接,不需要为每个连接创建一个线程,大大降低了线程的数量和资源消耗。

  • 适合高并发:NIO更适合需要处理大量连接的场景,比如聊天室、实时系统等。

缺点

  • 实现复杂:NIO的代码实现比BIO复杂,理解通道、缓冲区、选择器的机制需要更多经验。

  • 适用性有限:NIO适用于长连接场景(如聊天室),但对于短连接或低并发场景,BIO可能更简单易用。

2.5 NIO的应用实例——Netty

        Netty 是一个基于 NIO 的高性能网络应用框架,专门为了解决 Java 网络编程中的复杂性和性能问题。Netty 封装了底层的 NIO 操作,使得编写高并发、可扩展的网络应用更加轻松。它通常用于开发高性能的网络服务器和客户端,尤其在分布式系统、微服务等需要处理大量连接的场景中非常流行。

1. Netty 的核心概念

        Netty 主要使用 NIO 的非阻塞特性,并在其基础上进一步封装和优化,核心组件包括EventLoopChannelPipelineHandler 等。我们来详细看看这些核心部分:

  1. Channel

    • Netty 中的 Channel 是数据读写的基本接口,表示网络连接的抽象。不同的 Channel 实现支持不同协议(如 TCP、UDP),每个 Channel 可以绑定不同的事件。
  2. EventLoop

    • Netty 使用 EventLoop 来管理和调度 Channel 上的事件。EventLoop 是一个事件循环,用于处理 I/O 操作和事件分发。通常,一个 EventLoop 可以管理多个 Channel,从而实现高效的多路复用。
  3. Pipeline 和 Handler

    • Pipeline 是 Netty 中的一个职责链,所有的事件和数据都会沿着这条链进行传输和处理。
    • Handler 则是 Pipeline 中的处理单元,每个 Handler 负责处理某一种类型的事件,比如读取数据、解码、业务处理等。
    • Pipeline 中的 Handler 可以分为“入站(Inbound)”和“出站(Outbound)”,分别用于处理输入数据和输出数据,整个数据流的处理通过 Pipeline 完成。

2. Netty 的工作流程

Netty 的工作流程比直接使用 NIO 更加简洁,以下是 Netty 服务器的一般流程:

  1. 启动引导程序:创建一个 ServerBootstrap 实例,用于配置和启动服务器。ServerBootstrap 允许我们设置 EventLoop 线程池、Channel 类型以及其他参数。

  2. 初始化 Channel 和 Pipeline

    • ServerBootstrap 中配置 Channel 的类型(比如 NioServerSocketChannel 表示使用 NIO)。
    • Channel 配置 Pipeline,并将业务逻辑的 Handler 加入到 Pipeline 中,Netty 会根据事件触发不同的 Handler
  3. 处理连接和数据

    • 当有客户端连接到服务器时,Netty 会自动创建一个 Channel 来处理该连接,并触发相应的事件。
    • 数据从客户端到达后会按顺序通过 Pipeline 中的每个 Handler,经过编码、解码、业务处理等过程,最后将响应返回客户端。

3. Netty 的优势

        Netty 在底层优化了 Java NIO 的性能,同时提供了开发者友好的接口,简化了许多 NIO 编程的复杂性。

  • 高并发性:Netty 的 EventLoop 模型和 NIO 非阻塞特性,使得它可以高效处理大量并发连接。

  • 易于扩展:Netty 的 PipelineHandler 机制让网络应用的开发和扩展变得灵活。可以随时在 Pipeline 中添加、移除、替换处理逻辑。

  • 丰富的功能支持:Netty 不仅支持 TCP、UDP 等常见协议,还提供了 HTTP、WebSocket 等协议的封装,方便构建多种类型的网络应用。

4. Netty 的核心组件深入分析

  1. EventLoopGroup 和多线程模型

    • Netty 的 EventLoopGroup 是一种线程管理机制,它的作用是管理 EventLoop,并负责调度所有的 I/O 事件和任务。通常,一个 EventLoopGroup 会分配多个线程,每个线程负责管理一个或多个 Channel,从而实现高效的并发处理。
    • 通常在服务端会使用两个 EventLoopGroup,一个用于接收新连接(Boss Group),另一个用于处理数据读写(Worker Group)。这使得 Netty 能够分离连接建立与数据处理的任务,避免资源争用。
  2. Channel 和 ChannelFuture

    • Channel 作为 I/O 操作的核心接口,支持异步操作。每个操作都会返回一个 ChannelFuture 对象,用于监听操作的完成状态,比如连接是否成功、数据是否发送完毕等。
    • ChannelFuture 提供回调机制,允许我们在操作完成后触发相应的处理逻辑。这种异步操作方式让 Netty 能够更高效地进行并发处理。
  3. ChannelHandler 和 Pipeline

    • ChannelHandler 是 Netty 的处理单元,用于对 I/O 事件进行处理。通过 Pipeline,可以将多个 Handler 组成一个处理链条。Pipeline 会根据事件类型(比如读取、写入)将事件依次传递给链条中的 Handler
    • Pipeline 中的 Handler 分为入站和出站两种,入站 Handler 负责处理从客户端来的请求数据,而出站 Handler 则处理响应数据。这样可以实现数据的灵活处理和清晰的逻辑分离。
  4. ByteBuf 缓冲区

    • Netty 提供了 ByteBuf 作为数据缓冲区替代 NIOByteBufferByteBuf 的功能更丰富,比如动态扩展、读写指针分离等,极大地简化了数据处理过程。

5. Netty 常见的使用场景

Netty 的高性能和灵活性使它在许多应用场景中表现出色,以下是一些常见的场景:

  1. 实时聊天系统

    • 由于聊天系统需要支持大量长连接,且需要实时响应消息,Netty 的高并发处理能力非常适合这种场景。通过 Pipeline 可以实现数据的快速传递和处理,保证消息的快速响应。
  2. 微服务间通信

    • 在微服务架构中,服务之间的通信通常是通过网络完成的。Netty 支持多种协议,并能够封装成适合服务间通信的自定义协议(例如基于 TCP 的协议)。Netty 的高效 I/O 模型可以减少通信延迟,适合服务间的大量数据传输。
  3. 游戏服务器

    • 在线游戏需要支持大量玩家的连接,同时对实时性要求高。Netty 可以用于游戏服务器的底层网络架构,利用 NIO 模型减少连接管理的资源消耗,并提供快速响应。
  4. 分布式系统中作为 RPC 框架

    • Netty 是许多 RPC 框架的底层通信支持。比如 DubbogRPC 等分布式系统中常用的框架都使用 Netty 来处理底层网络通信。通过 Netty,能够实现低延迟的远程调用。

6. Netty 示例:构建一个简单的 Echo 服务器

        为了加深理解,我们来看一个 Netty 示例:一个简单的 Echo 服务器。Echo 服务器会将客户端发送的数据原封不动地返回给客户端。

public class EchoServer {public static void main(String[] args) throws Exception {EventLoopGroup bossGroup = new NioEventLoopGroup(1); // 用于接收连接EventLoopGroup workerGroup = new NioEventLoopGroup(); // 用于处理数据try {ServerBootstrap b = new ServerBootstrap(); // 创建引导程序b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class) // 使用NIO.childHandler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel ch) throws Exception {ch.pipeline().addLast(new EchoServerHandler()); // 加入Echo处理器}});ChannelFuture f = b.bind(8080).sync(); // 绑定端口并启动f.channel().closeFuture().sync(); // 等待关闭} finally {bossGroup.shutdownGracefully();workerGroup.shutdownGracefully();}}
}class EchoServerHandler extends ChannelInboundHandlerAdapter {@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) {ctx.write(msg); // 写回收到的数据ctx.flush(); // 立即发送}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {cause.printStackTrace();ctx.close(); // 发生异常时关闭通道}
}

这个代码展示了 Netty 的基本工作流程:

  • ServerBootstrap 设置服务器的基本配置。
  • EventLoopGroup 负责处理连接和数据。
  • ChannelInitializer 配置了 Pipeline,将处理器加入到处理链中。
  • EchoServerHandlerchannelRead 中接收数据并返回给客户端。

3. AIO(Asynchronous I/O)

        AIO 模型是在 Java 7 中引入的,也被称为 NIO.2,它与 BIO 和 NIO 的关键不同点在于完全异步的处理方式。AIO 允许我们在 I/O 操作完成后自动调用回调函数,不需要通过轮询或等待的方式来检查 I/O 是否已完成,这种特性在处理长时间的、数据密集型的任务时特别有优势。

3.1 AIO 的关键特性

  1. 异步非阻塞

    • 在 AIO 模型中,操作是非阻塞且异步的。无论是连接、读取还是写入操作,都会直接返回,通过回调机制在操作完成后通知应用进行相应的处理。线程无需等待数据读写完成,能够更高效地处理其他任务。
  2. 基于回调的编程方式

    • AIO 通过回调机制实现异步处理。每当 I/O 操作完成后,系统会自动调用指定的回调方法,这样线程无需手动轮询操作状态。回调机制使得程序结构更加简洁,减少了阻塞等待和轮询操作。

3.2 AIO 的核心组件

        在 AIO 中,核心组件围绕 AsynchronousChannel 系列接口设计,这些接口提供了异步 I/O 的主要操作。

  1. AsynchronousServerSocketChannel

    • 用于异步地处理服务器端的连接请求。它类似于 NIO 中的 ServerSocketChannel,但它提供了异步的 accept 操作,支持在新连接到达时自动触发回调。
  2. AsynchronousSocketChannel

    • 用于客户端或服务器端进行异步数据传输的通道。AsynchronousSocketChannel 提供了异步的读写操作,操作完成后会触发回调。
  3. CompletionHandler

    • 这是 AIO 处理中最重要的接口之一。CompletionHandler 负责定义回调逻辑,在 I/O 操作完成或失败后会自动调用。CompletionHandler 接口包含两个方法:
      • completed:在 I/O 操作成功时调用,处理成功逻辑。
      • failed:在 I/O 操作失败时调用,处理异常逻辑。

3.3 AIO 的工作流程

        AIO 的工作流程基于回调,我们可以用步骤来概述其操作:

  1. 建立连接

    • 使用 AsynchronousServerSocketChannel 监听客户端连接,通过 accept 方法注册一个回调 CompletionHandler。当有新的连接请求时,回调函数会被触发,服务器会获取该连接的 AsynchronousSocketChannel 进行后续的处理。
  2. 异步读取

    • 在服务器获取到客户端连接的 AsynchronousSocketChannel 后,可以调用 read 方法进行数据读取。此方法也是异步的,接收一个 CompletionHandler 作为参数,数据读取完成后将自动触发回调处理。
  3. 异步写入

    • 数据处理完毕后,可以调用 write 方法将结果返回给客户端,同样也是异步的。写入完成后会触发相应的回调,保证了数据的准确发送。

3.4 AIO 的优缺点

优点

  • 完全异步:AIO 的回调机制减少了阻塞等待,提高了程序的响应速度。
  • 资源节约:不需要多线程来管理 I/O,可以在较少线程下完成高并发的 I/O 操作,特别适合高并发的长连接场景。

缺点

  • 复杂性增加:AIO 的回调编程方式需要设计异步流程,逻辑上会比传统的同步代码复杂。
  • 适用场景有限:AIO 适用于高并发、长时间保持连接的应用场景(如文件传输服务器),但在短连接或低并发情况下不具备明显优势。

3.5 AIO 示例:构建一个简单的 Echo 服务器

        以下是一个使用 AIO 的简单 Echo 服务器示例。该服务器会异步接收客户端的数据并返回。

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;public class AioEchoServer {public static void main(String[] args) throws IOException {AsynchronousServerSocketChannel serverChannel =AsynchronousServerSocketChannel.open().bind(new InetSocketAddress(8080));System.out.println("AIO Echo Server is listening on port 8080...");// 接收客户端连接serverChannel.accept(null, new CompletionHandler<AsynchronousSocketChannel, Void>() {@Overridepublic void completed(AsynchronousSocketChannel clientChannel, Void attachment) {// 继续接收其他连接serverChannel.accept(null, this);// 读取客户端数据ByteBuffer buffer = ByteBuffer.allocate(1024);clientChannel.read(buffer, buffer, new CompletionHandler<Integer, ByteBuffer>() {@Overridepublic void completed(Integer result, ByteBuffer attachment) {attachment.flip();clientChannel.write(attachment, attachment, new CompletionHandler<Integer, ByteBuffer>() {@Overridepublic void completed(Integer result, ByteBuffer attachment) {attachment.clear();clientChannel.read(attachment, attachment, this);}@Overridepublic void failed(Throwable exc, ByteBuffer attachment) {exc.printStackTrace();try {clientChannel.close();} catch (IOException e) {e.printStackTrace();}}});}@Overridepublic void failed(Throwable exc, ByteBuffer attachment) {exc.printStackTrace();try {clientChannel.close();} catch (IOException e) {e.printStackTrace();}}});}@Overridepublic void failed(Throwable exc, Void attachment) {exc.printStackTrace();}});// 阻止主线程退出try {Thread.currentThread().join();} catch (InterruptedException e) {e.printStackTrace();}}
}

总结

  • BIO:每个连接一个线程,适用于低并发、小规模应用。
  • NIO:多路复用、非阻塞,适合高并发场景。
  • AIO:完全异步,回调机制适合高并发、长连接场景。

相关文章:

Java中的I/O模型——BIO、NIO、AIO

1. BIO&#xff08;Blocking I/O&#xff09; 1. 1 BIO&#xff08;Blocking I/O&#xff09;模型概述 BIO&#xff0c;即“阻塞I/O”&#xff08;Blocking I/O&#xff09;&#xff0c;是一种同步阻塞的I/O模式。它的主要特点是&#xff0c;当程序发起I/O请求&#xff08;比如…...

【软考知识】敏捷开发与统一建模过程(RUP)

敏捷开发模式 概述敏捷开发的主要特点包括&#xff1a;敏捷开发的常见实践包括&#xff1a;敏捷开发的优势&#xff1a;敏捷开发的挑战&#xff1a;敏捷开发的方法论&#xff1a; ScrumScrum 的核心概念Scrum 的执行过程Scrum 的适用场景 极限编程&#xff08;XP&#xff09;核…...

Redis常见面试题(二)

Redis性能优化 Redis性能测试 阿里Redis性能优化 使用批量操作减少网络传输 Redis命令执行步骤&#xff1a;1、发送命令&#xff1b;2、命令排队&#xff1b;3、命令执行&#xff1b;4、返回结果。其中 1 与 4 消耗时间 --> Round Trip Time&#xff08;RTT&#xff0c;…...

业务模块部署

一、部署前端 1.1 window部署 下载业务模块前端包。 &#xff08;此包为耐威迪公司发布&#xff0c;请联系耐威迪客服或售后获得&#xff09; 包名为&#xff1a;业务-xxxx-business &#xff08;注&#xff1a;xxxx为发布版本号&#xff09; 此文件部署位置为&#xff1a;……...

【LeetCode】【算法】48. 旋转图像

LeetCode 48. 旋转图像 题目描述 给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在 原地 旋转图像&#xff0c;这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 思路 思路&#xff1a;再次拜见K神&#xf…...

【STM32F1】——9轴姿态模块JY901与串口通信(上)

【STM32F1】——9轴姿态模块JY901与串口通信(上) 一、简介 本篇主要对调试JY901模块的过程进行总结,实现了以下功能。 串口普通收发:使用STM32F103C8T6的USART2实现9轴姿态模块JY901串口数据的读取,并利用USART1发送到串口助手。 串口DMA收发:使用STM32F103C8T6的USART…...

Docker网络概述

1. Docker 网络概述 1.1 网络组件 Docker网络的核心组件包括网络驱动程序、网络、容器以及IP地址管理&#xff08;IPAM&#xff09;。这些组件共同工作&#xff0c;为容器提供网络连接和通信能力。 网络驱动程序&#xff1a;Docker支持多种网络驱动程序&#xff0c;每种驱动程…...

Vite与Vue Cli的区别与详解

它们的功能非常相似&#xff0c;都是提供基本项目脚手架和开发服务器的构建工具。 主要区别 Vite在开发环境下基于浏览器原生ES6 Modules提供功能支持&#xff0c;在生产环境下基于Rollup打包&#xff1b; Vue Cli不区分环境&#xff0c;都是基于Webpack。 在生产环境下&…...

深究JS底层原理

一、JS中八种数据类型判断方法 在JavaScript中&#xff0c;数据类型分为两大类&#xff1a;基本&#xff08;原始&#xff09;数据类型和引用&#xff08;对象&#xff09;数据类型。 基本数据类型&#xff08;Primitive Data Types&#xff09; 基本数据类型是表示简单的数…...

数据分析-41-时间序列预测之机器学习方法XGBoost

文章目录 1 时间序列1.1 时间序列特点1.1.1 原始信号1.1.2 趋势1.1.3 季节性和周期性1.1.4 噪声1.2 时间序列预测方法1.2.1 统计方法1.2.2 机器学习方法1.2.3 深度学习方法2 XGBoost2.1 模拟数据2.2 生成滞后特征2.3 切分训练集和测试集2.4 封装专用格式2.5 模型训练和预测3 参…...

json转java对象 1.文件读取为String 2.String转为JSONObject 3.JSONObject转为Class

一.参考王广帅的 服务器起服时的加载 private void readConfigFile(String configDir, Class<?> clazz) throws Exception {String fileName getConfigFileName(clazz);File configFile new File(configDir, fileName);// 读取所有的行&#xff0c;因此&#xff0c;应…...

基于卷积神经网络的农作物病虫害识别系统(pytorch框架,python源码)

更多图像分类、图像识别、目标检测等项目可从主页查看 功能演示&#xff1a; 基于卷积神经网络的农作物病虫害检测&#xff08;pytorch框架&#xff09;_哔哩哔哩_bilibili &#xff08;一&#xff09;简介 基于卷积神经网络的农作物病虫害识别系统是在pytorch框架下实现的…...

ETLCloud异常问题分析ai功能

在数据处理和集成的过程中&#xff0c;异常问题的发生往往会对业务运营造成显著影响。为了提高ETL&#xff08;提取、转换、加载&#xff09;流程的稳定性与效率&#xff0c;ETLCloud推出了智能异常问题分析AI功能。这一创新工具旨在实时监测数据流动中的潜在异常&#xff0c;自…...

【1】 Kafka快速入门-从原理到实践

文章目录 🔍 一、引言📜 二、Kafka 的历史🏗️ 三、Kafka 的核心结构🖥️ (一)Broker📋 (二)Topic📄 (三)Partition📤 (四)Producer📥 (五)Consumer🐒 (六)Zookeeper💡 四、Kafka 的重点概念📨 (一)消息📏 (二)偏移量(Offset)🔄 (…...

go语言中的map类型详解

在Go语言中&#xff0c;map是一种内建的数据结构&#xff0c;提供了键值对&#xff08;key-value&#xff09;的存储方式。map通常用于实现快速的查找和关联数组&#xff0c;适合在需要根据键来高效查找值的场景下使用。 基本概念 map是一个无序的集合&#xff0c;它存储了键…...

GBase 8a MPP Cluster V9安装部署

GBase 8a MPP Cluster V9安装部署 安装环境准备 节点角色操作系统地址配置GBASE版本gbase01.gbase.cnGCWARE,COOR,DATACentOS 7.9192.168.20.1422C4GGBase 8a MPP Cluster V9 9.5.3.28.12gbase02.gbase.cnGCWARE,COOR,DATACentOS 7.9192.168.20.1432C4GGBase 8a MPP Cluster …...

静态库、动态库、framework、xcframework、use_frameworks!的作用、关联核心SDK工程和测试(主)工程、设备CPU架构

1.1库的概念 库&#xff1a;程序代码的集合&#xff0c;编译好的二进制文件加上头文件供使用&#xff0c;共享程序代码的一种方式。 1.2库的分类 根据开源情况分为&#xff1a;开源库&#xff08;能看到具体实现&#xff09;、闭源库&#xff08;只公开调用的的接口&#xf…...

C++ | Leetcode C++题解之第552题学生出勤记录II

题目&#xff1a; 题解&#xff1a; class Solution { public:static constexpr int MOD 1000000007;vector<vector<long>> pow(vector<vector<long>> mat, int n) {vector<vector<long>> ret {{1, 0, 0, 0, 0, 0}};while (n > 0) {…...

网站架构知识之Ansible(day020)

1.Ansible架构 Inventory 主机清单:被管理主机的ip列表,分类 ad-hoc模式: 命令行批量管理(使用ans模块),临时任务 playbook 剧本模式: 类似于把操作写出脚本,可以重复运行这个脚本 2.修改配置 配置文件&#xff1a;/etc/ansible/ansible.cfg 修改配置文件关闭主机Host_key…...

K8s使用nfs

改动点 ip和路径改为自己的 --- apiVersion: v1 kind: ServiceAccount metadata:name: nfs-client-provisioner# replace with namespace where provisioner is deployednamespace: nfs-client --- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata:nam…...

Python爬虫实战:研究MechanicalSoup库相关技术

一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...

vscode里如何用git

打开vs终端执行如下&#xff1a; 1 初始化 Git 仓库&#xff08;如果尚未初始化&#xff09; git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...

Java 语言特性(面试系列1)

一、面向对象编程 1. 封装&#xff08;Encapsulation&#xff09; 定义&#xff1a;将数据&#xff08;属性&#xff09;和操作数据的方法绑定在一起&#xff0c;通过访问控制符&#xff08;private、protected、public&#xff09;隐藏内部实现细节。示例&#xff1a; public …...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)

2025年能源电力系统与流体力学国际会议&#xff08;EPSFD 2025&#xff09;将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会&#xff0c;EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...

C++ 基础特性深度解析

目录 引言 一、命名空间&#xff08;namespace&#xff09; C 中的命名空间​ 与 C 语言的对比​ 二、缺省参数​ C 中的缺省参数​ 与 C 语言的对比​ 三、引用&#xff08;reference&#xff09;​ C 中的引用​ 与 C 语言的对比​ 四、inline&#xff08;内联函数…...

【HTTP三个基础问题】

面试官您好&#xff01;HTTP是超文本传输协议&#xff0c;是互联网上客户端和服务器之间传输超文本数据&#xff08;比如文字、图片、音频、视频等&#xff09;的核心协议&#xff0c;当前互联网应用最广泛的版本是HTTP1.1&#xff0c;它基于经典的C/S模型&#xff0c;也就是客…...

第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词

Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵&#xff0c;其中每行&#xff0c;每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid&#xff0c;其中有多少个 3 3 的 “幻方” 子矩阵&am…...

Linux --进程控制

本文从以下五个方面来初步认识进程控制&#xff1a; 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程&#xff0c;创建出来的进程就是子进程&#xff0c;原来的进程为父进程。…...

安卓基础(aar)

重新设置java21的环境&#xff0c;临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的&#xff1a; MyApp/ ├── app/ …...