RabbitMQ工作模式(详解 工作模式:简单队列、工作队列、公平分发以及消息应答和消息持久化)

文章目录

  • 十.RabbitMQ
    • 10.1 简单队列实现
    • 10.2 Work 模式(工作队列)
    • 10.3 公平分发
    • 10.4 RabbitMQ 消息应答与消息持久化
      • 消息应答
        • 概念
        • 配置
      • 消息持久化
        • 概念
        • 配置

十.RabbitMQ

10.1 简单队列实现

简单队列通常指的是一个基本的消息队列,它可以用于在生产者(生产消息的一方)和消费者(消费消息的一方)之间传递消息。

在这里插入图片描述

新创建Springboot项目

引入依赖

<dependency>
            <groupId>com.rabbitmq</groupId>
            <artifactId>amqp-client</artifactId>
            <version>5.7.1</version>
 </dependency>

连接工具类

public class ConnectionUtils
{
    public static Connection getConnection()
    {
        try
        {
            Connection connection = null;
            //定义一个连接工厂
            ConnectionFactory factory = new ConnectionFactory();
            //设置服务端地址(域名地址/ip)
            factory.setHost("127.0.0.1");
            //设置服务器端口号
            factory.setPort(5672);
            //设置虚拟主机(相当于数据库中的库)
            factory.setVirtualHost("/");
            //设置用户名
            factory.setUsername("guest");
            //设置密码
            factory.setPassword("guest");
            connection = factory.newConnection();
            return connection;
        }
        catch (Exception e)
        {
            return null;
        }
    }
}

创建生产者

public class Provider01 {
    public static void main(String[] args) {

        try {
            System.out.println("--------生产者-------");

            // 获取连接
            Connection conn = ConnectionUtils.getConnection();
            //创建通道
            Channel channel = conn.createChannel();

            // 创建队列
            // 队列名称,是否持久化,是否排他,是否自动删除,其他参数
            channel.queueDeclare("test4072", false, false, false, null);

            // 定义发送信息
            String msg = "hello rabbitmq-kwh";

            // 发送数据
            channel.basicPublish("", "test4072", null, msg.getBytes());

            System.out.println("发送成功....");

            // 关闭资源
            channel.close();
            conn.close();


        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

创建消费者

public class Consumer01 {
    public static void main(String[] args) {

        try {

            System.out.println("======消费者======");

            // 获取连接
            Connection conn = ConnectionUtils.getConnection();
            //创建通道
            Channel channel = conn.createChannel();

            // 创建队列(有就直接连接。没有则创建)
            // 队列名称,是否持久化,是否排他,是否自动删除,其他参数
            channel.queueDeclare("test4072", false, false, false, null);

            // 消费者消费消息
            DefaultConsumer consumer = new DefaultConsumer(channel){
                @Override //一旦有消息进入 将触发
                public void handleDelivery(
                  String consumerTag,
                  Envelope envelope,                        
                  AMQP.BasicProperties properties,
                  byte[] body
                ) throws IOException {
                    String str = new String(body,"utf-8");
                    System.out.println("msg==接收=="+str);
                }
            };

            // 监听队列
            channel.basicConsume("test4072",true,consumer);

        }catch (Exception e) {
           e.printStackTrace();
        }

    }
}

10.2 Work 模式(工作队列)

工作队列的概念

  • 工作队列模式:生产者将任务发送到队列中,多个消费者从队列中取出任务并并行处理。这意味着,多个消费者可以共同工作来处理同一个队列中的任务。
  • 负载均衡:每个消费者只处理一个任务(消息),通过增加消费者数量,任务的处理可以并行化,提高整体处理能力。

工作队列的特点:

  1. 任务分配:RabbitMQ 将队列中的任务(消息)分配给可用的消费者,通常是按照“轮询”或“平衡”方式分配,即消费者可以公平地处理任务。
  2. 任务处理并行化:多个消费者可以并行地从同一个队列中消费消息,从而实现任务的并行处理,减轻单一消费者的负担。
  3. 消息丢失的风险低:通过合理配置队列和消息持久化机制,即使 RabbitMQ 重启,也能确保任务消息不丢失。

在这里插入图片描述

生产者

(只是在简单队列中的生产者中循环发送了信息。)

/**
 * Work 模式(工作队列)
 */
public class Provider01 {
    public static void main(String[] args) {

        try {

            System.out.println("--------生产者-------");

            // 获取连接
            Connection conn = ConnectionUtils.getConnection();
            //创建通道
            Channel channel = conn.createChannel();

            // 创建队列
            // 队列名称,是否持久化,是否排他,是否自动删除,其他参数
            channel.queueDeclare("test4072", false, false, false, null);

            for (int i = 0; i < 50; i++) {
                // 定义发送信息
                String msg = "hello rabbitmq-kwh"+i;
                // 发送数据
                channel.basicPublish("", "test4072", null, msg.getBytes());

                Thread.sleep(1000);

            }

            System.out.println("发送成功....");

            // 关闭资源
            channel.close();
            conn.close();


        } catch (Exception e) {
            e.printStackTrace();
        }


    }
}

消费者01

public class Consumer01 {
    public static void main(String[] args) {

        try {

            System.out.println("======消费者01======");

            // 获取连接
            Connection conn = ConnectionUtils.getConnection();
            //创建通道
            Channel channel = conn.createChannel();

            // 创建队列(有就直接连接。没有则创建)
            // 队列名称,是否持久化,是否排他,是否自动删除,其他参数
            channel.queueDeclare("test4072", false, false, false, null);

            // 消费者消费消息
            DefaultConsumer consumer = new DefaultConsumer(channel){
                @Override //一旦有消息进入 将触发
                public void handleDelivery(
                  String consumerTag,                     
                  Envelope envelope,                        
                  AMQP.BasicProperties properties,           
                  byte[] body
                ) throws IOException {
                    String str = new String(body,"utf-8");
                    System.out.println("msg==接收=="+str);
                }
            };

            // 监听队列
            channel.basicConsume("test4072",true,consumer);


        }catch (Exception e) {
           e.printStackTrace();
        }

    }
}

消费者02

public class Consumer02 {
    public static void main(String[] args) {

        try {

            System.out.println("======消费者02======");

            // 获取连接
            Connection conn = ConnectionUtils.getConnection();
            //创建通道
            Channel channel = conn.createChannel();

            // 创建队列(有就直接连接。没有则创建)
            // 队列名称,是否持久化,是否排他,是否自动删除,其他参数
            channel.queueDeclare("test4072", false, false, false, null);

            // 消费者消费消息
            DefaultConsumer consumer = new DefaultConsumer(channel){
                @Override //一旦有消息进入 将触发
                public void handleDelivery(
                  String consumerTag,                    
                  Envelope envelope,                       
                  AMQP.BasicProperties properties,
                  byte[] body
                ) throws IOException {
                    String str = new String(body,"utf-8");
                    System.out.println("msg==接收=="+str);
                }
            };

            // 监听队列
            channel.basicConsume("test4072",true,consumer);


        }catch (Exception e) {
           e.printStackTrace();
        }

    }
}

在这里插入图片描述

. 消费者 1 与消费者 2 处理的数据条数一样。

. 消费者 1 偶数 ;消费者 2 奇数

这种方式叫轮询分发(Round-robin)。

10.3 公平分发

指消息被均匀地分配给多个消费者,以便各个消费者的负载大致相等。通过这种方式,RabbitMQ 旨在避免某些消费者过载而其他消费者空闲的情况。

在这里插入图片描述

在10.2 中,现在有 2 个消费者,所有的奇数的消息都是繁忙的,而偶数则是轻松的。按照轮询的方式,奇数的任务交给了第一个消费者,所以一直在忙个不停。偶数的任务交给另一个消费者,则立即完成任务,然后闲得不行。而 RabbitMQ 则是不了解这些的。这是因为当消息进入队列,RabbitMQ 就会分派消息。它不看消费者为应答的数目,只是盲目的将消息发给轮询指定的消费者。

改造生产者

/*
同一时刻服务器只会发一条消息给消费者
1 限制发送给消费者不得超过一条消息
*/
channel.basicQos(1);
/**
 * 公平分发
 */
public class Provider01 {
    public static void main(String[] args) {

        try {

            System.out.println("--------生产者-------");

            // 获取连接
            Connection conn = ConnectionUtils.getConnection();
            //创建通道
            Channel channel = conn.createChannel();

            //同一时刻服务器只会发一条消息给消费者
            channel.basicQos(1);

            // 创建队列
            // 队列名称,是否持久化,是否排他,是否自动删除,其他参数
            channel.queueDeclare("test4072", false, false, false, null);

            for (int i = 0; i < 50; i++) {
                // 定义发送信息
                String msg = "hello rabbitmq-kwh"+i;
                // 发送数据
                channel.basicPublish("", "test4072", null, msg.getBytes());

                Thread.sleep(1000);

            }

            System.out.println("发送成功....");

            // 关闭资源
            channel.close();
            conn.close();


        } catch (Exception e) {
            e.printStackTrace();
        }


    }

}

消费者01

(在10.2 中消费者的基础上,只添加 channel.basicQos(1);,限制每次只消费一个消息)

public class Consumer01 {
    public static void main(String[] args) {

        try {

            System.out.println("======消费者01======");

            // 获取连接
            Connection conn = ConnectionUtils.getConnection();
            //创建通道
            Channel channel = conn.createChannel();

            //限制每次只消费一个消息
            channel.basicQos(1);

            // 创建队列(有就直接连接。没有则创建)
            // 队列名称,是否持久化,是否排他,是否自动删除,其他参数
            channel.queueDeclare("test4072", false, false, false, null);

            // 消费者消费消息
            DefaultConsumer consumer = new DefaultConsumer(channel){
                @Override //一旦有消息进入 将触发
                public void handleDelivery(
                  String consumerTag,                      
                  Envelope envelope,                     
                  AMQP.BasicProperties properties,
                  byte[] body
                ) throws IOException {
                    String str = new String(body,"utf-8");
                    System.out.println(envelope.getDeliveryTag()+"msg==接收=="+str);

                    // 休眠一秒钟
                    try {
                        Thread.sleep(1000);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }finally {
                        // 手动确认消息
                        // 第一个参数:消息的序号,
                        // 第二个参数:是否批量,false 单条消息应答 当为 true 时批量应答
                        channel.basicAck(envelope.getDeliveryTag(),false);
                    }

                }
            };

            // 监听队列
            // 自动应答设为 false
            channel.basicConsume("test4072",false,consumer);


        }catch (Exception e) {
           e.printStackTrace();
        }


    }
}

消费者02

(同消费者01)

在这里插入图片描述

消费者 1 休眠 1 秒,消费者 2 休眠 2 秒。

分别设置接收消息数,手动反馈,关闭自动应答

10.4 RabbitMQ 消息应答与消息持久化

消息应答

概念

**消息应答(ack)**是 RabbitMQ 中一个重要的机制,用于保证消息在被消费者处理后得以正确确认,确保消息不会丢失。如果消费者成功处理了消息,应该发送一个确认应答;如果消费者遇到问题或失败,则可以选择拒绝该消息,甚至重新放回队列供其他消费者处理。

应答类型:

  • **自动应答(auto-ack):**自动应答是默认设置,消费者从队列中获取消息后,RabbitMQ 会立即认为该消息已经被成功处理,即使消费者并未真正处理完成。在这种模式下,消息会在被消费后立即从队列中删除,而无需消费者确认。这种模式的缺点是,如果消费者在处理消息时崩溃,消息会丢失。
  • **手动应答(manual ack):**消费者处理完消息后,需要显式地发送确认应答,通知 RabbitMQ 该消息已经处理完成。这样,如果消费者没有发送确认应答,RabbitMQ 会重新将消息发送给其他消费者。
配置
// 监听队列
// 参数2:自动应答设为 false; true:开启自动应答
channel.basicConsume("test4072",false,consumer);

参数2为true时:自动确认

只要消息从队列中获取,无论消费者获取到消息后是否成功消费,都认为是消息已经成功消费。一旦rabbitmq 将消息分发给消费者,就会从内存中删除。(会丢失数据消息)

参数2为false时:手动确认

消费者从队列中获取消息后,服务器会将该消息标记为不可用状态,等待消费者的反馈,如果消费者一直没有反馈,那么该消息将一直处于不可用状态。如果有一个消费者挂掉,就会交付给其他消费者。手动告诉 rabbitmq 消息处理完成后,rabbitmq 删除内存中的消息。

反馈:

//手动回馈
channel.basicAck(envelope.getDeliveryTag(),false);

使用 Nack 让消息回到队列中

// 处理条数; 是否批量处理 ;是否放回队列 false 丢弃
channel.basicNack(envelope.getDeliveryTag(),false,true);

生产者

/**
 * 消息应答
 */
public class Provider01 {
    public static void main(String[] args) {

        try {
            System.out.println("--------生产者-------");
            // 获取连接
            Connection conn = ConnectionUtils.getConnection();
            //创建通道
            Channel channel = conn.createChannel();

            //同一时刻服务器只会发一条消息给消费者
            channel.basicQos(1);

            // 创建队列
            // 队列名称,是否持久化,是否排他,是否自动删除,其他参数
            channel.queueDeclare("test4072", false, false, false, null);

            for (int i = 0; i < 50; i++) {
                // 定义发送信息
                String msg = "hello rabbitmq-kwh"+i;
                // 发送数据
                channel.basicPublish("", "test4072", null, msg.getBytes());

                Thread.sleep(1000);

            }

            System.out.println("发送成功....");

            // 关闭资源
            channel.close();
            conn.close();


        } catch (Exception e) {
            e.printStackTrace();
        }

    }

}

消费者01

public class Consumer01 {
    public static void main(String[] args) {

        try {

            System.out.println("======消费者01======");

            // 获取连接
            Connection conn = ConnectionUtils.getConnection();
            //创建通道
            Channel channel = conn.createChannel();

            //限制每次只消费一个消息,防止通道中消息阻塞
            channel.basicQos(1);

            // 创建队列(有就直接连接。没有则创建)
            // 队列名称,是否持久化,是否排他,是否自动删除,其他参数
            channel.queueDeclare("test4072", false, false, false, null);

            // 消费者消费消息
            DefaultConsumer consumer = new DefaultConsumer(channel){
                @Override //一旦有消息进入 将触发
                public void handleDelivery(
                  String consumerTag,                       
                  Envelope envelope,                      
                  AMQP.BasicProperties properties,
                   byte[] body
                ) throws IOException {

                    String str = "";
                   try {
                        str = new String(body,"utf-8");
                       if(envelope.getDeliveryTag()==3){
                            int i=1/0;
                       }

                       System.out.println(envelope.getDeliveryTag()+"消费者01msg==接收=="+str);

                       //手动应答 处理完了
                       // 手动确认消息,即手动反馈
                       // 第一个参数:消息的序号,
                       // 第二个参数:是否批量,false 单条消息应答 ;当为 true 时批量应答
                       channel.basicAck(envelope.getDeliveryTag(),false);

                   }catch(Exception e){
                       // e.printStackTrace();
                       System.out.println("消费者01处理第"+envelope.getDeliveryTag()+"条,时报错,消息内容为"+str);

                       //手动应答 报错了
                       // 第一个参数:消息的序号,
                       // 第二个参数:是否批量,false 单条消息应答 当为 true 时批量应答
                       // 第三个参数:是否放回队列 ;false丢弃 ,true 放回队列
                        channel.basicNack(envelope.getDeliveryTag(),false,true);
                   }

                    // 休眠一秒钟
                    try {
                        Thread.sleep(1000);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                }
            };

            // 监听队列
            // 参数2:自动应答设为 false; true:开启自动应答
            channel.basicConsume("test4072",false,consumer);


        }catch (Exception e) {
           e.printStackTrace();
        }

    }
}

消费者02(同消费者01)

在这里插入图片描述

消息持久化

概念

RabbitMQ 的持久化机制是确保消息和队列在系统崩溃、重启或其他故障情况下不会丢失的关键功能。确保消息不会丢失需要做两件事:将队列和消息都标记为持久化。

配置

持久化队列

// 创建队列,
// 队列名称,是否持久化(队列),是否排他,是否自动删除,其他参数
 channel.queueDeclare("test4072", true, false, false, null);

消息持久化

// 发送数据
// MessageProperties.PERSISTENT_TEXT_PLAIN:持久化消息
//设置生成者发送消息为持久化信息(要求保存到硬盘上)保存在内存中
//MessageProperties.PERSISTENT_TEXT_PLAIN,指令完成持久化
channel.basicPublish("", "test4072", MessageProperties.PERSISTENT_TEXT_PLAIN, msg.getBytes());

如果改动队列参数配置,需要删除原有的队列,重新建,因为在 rabbitmq 是不允许重新定义一个已存在的队列。

在这里插入图片描述

生产者

/**
 * 消息持久化
 */
public class Provider01 {
    public static void main(String[] args) {

        try {

            System.out.println("--------生产者-------");

            // 获取连接
            Connection conn = ConnectionUtils.getConnection();
            //创建通道
            Channel channel = conn.createChannel();

            //同一时刻服务器只会发一条消息给消费者
            channel.basicQos(1);

            // 创建队列
            // 队列名称,是否持久化(队列),是否排他,是否自动删除,其他参数
            channel.queueDeclare("test4072", true, false, false, null);

            for (int i = 0; i < 50; i++) {
                // 定义发送信息
                String msg = "hello rabbitmq-kwh"+i;

                // 发送数据
                // MessageProperties.PERSISTENT_TEXT_PLAIN:持久化消息
                channel.basicPublish("", "test4072", MessageProperties.PERSISTENT_TEXT_PLAIN, msg.getBytes());

                Thread.sleep(1000);

            }

            System.out.println("发送成功....");

            // 关闭资源
            channel.close();
            conn.close();


        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

No Python at ‘C:\Users\MI\AppData\Local\Programs\Python\Python39\python.exe‘

目录 一、检查环境配置 1.1 安装键盘“winR”键并输入cmd 1.2 输入“python” 二、解决问题 2.1 检查本地的python配置路径 2.2 打开PyCharm的Settings 2.3 找到Python Interpreter 2.4 删除当前python版本 2.5 新添版本 PyCharm运行时出现的错误&#xff1a; No Py…

EMQX5.X版本性能配置调优参数

EMQX 主配置文件为 emqx.conf&#xff0c;根据安装方式其所在位置有所不同&#xff1a; 安装方式配置文件所在位置DEB 或 RPM 包安装/etc/emqx/emqx.confDocker 容器/opt/emqx/etc/emqx.conf解压缩包安装./etc/emqx.conf EMQ X 消息服务器默认占用的 TCP 端口包括: 端口 说明…

项目报 OutOfMemoryError 、GC overhead limit exceeded 问题排查以及解决思路实战

项目报 OutOfMemoryError、GC overhead limit exceeded 问题排查以及解决思路实战 前言&#xff1a; 问题现象描述&#xff1a; 1&#xff0c;生产环境有个定时任务&#xff0c;没有初始化告警数据【告警数据量为1000多个】 2&#xff0c;其他定时任务执行正常 3&#xff0c;查…

xinput1_3.dll放在哪里?当xinput1_3.dll丢失时的应对策略:详细解决方法汇总

在计算机系统的运行过程中&#xff0c;我们偶尔会遇到一些令人困扰的问题&#xff0c;其中xinput1_3.dll文件丢失就是较为常见的一种情况。这个看似不起眼的动态链接库文件&#xff0c;实则在许多软件和游戏的正常运行中发挥着至关重要的作用。一旦它丢失&#xff0c;可能会导致…

【Compose multiplatform教程12】【组件】Box组件

查看全部组件文章浏览阅读493次&#xff0c;点赞17次&#xff0c;收藏11次。alignment。https://blog.csdn.net/b275518834/article/details/144751353 Box 功能说明&#xff1a;简单的布局组件&#xff0c;可容纳其他组件&#xff0c;并依据alignment属性精确指定内部组件的对…

MySql:复合查询

✨✨作者主页&#xff1a;嶔某✨✨ ✨✨所属专栏&#xff1a;MySql✨ 准备工作&#xff0c;创建一个雇员信息表&#xff08;来自oracle 9i的经典测试表&#xff09; EMP员工表DEPT部门表SALGRADE工资等级表 多表查询 显示雇员名&#xff0c;雇员工资以及所在部门的名字 因为…

从零创建一个 Django 项目

1. 准备环境 在开始之前&#xff0c;确保你的开发环境满足以下要求&#xff1a; 安装了 Python (推荐 3.8 或更高版本)。安装 pip 包管理工具。如果要使用 MySQL 或 PostgreSQL&#xff0c;确保对应的数据库已安装。 创建虚拟环境 在项目目录中创建并激活虚拟环境&#xff…

基于PREEvision的UML设计

众所周知&#xff0c;PREEvision是一款强大的电子电气架构协同开发及管理软件&#xff0c;可以很好地帮助架构工程师完成架构开发工作&#xff0c;其功能包括需求管理、定义功能逻辑、系统软件开发、网络设计、线束设计及整体工程的产品线管理和变形管理等。随着工程师们越来越…

Azure Function 解决跨域问题

这边前端call本地部署的azure function出现了跨域问题&#xff0c;搜索一下解决方案 直接修改local.setting.json&#xff0c;在其中添加CORS配置为通配符”*”&#xff0c;就行了 local.settings.json {"IsEncrypted": false,"Values": {"PYTHON_E…

Ubuntu离线安装Docker容器

前言 使用安装的工具snap安装在沙箱中&#xff0c;并且该沙箱之外的权限有限。docker无法从其隔离的沙箱环境访问外部文件系统。 目录 前言准备环境卸载已安装的Docker环境快照安装的Dockerapt删除Docker 安装docker-compose下载执行文件将文件移到 /usr/local/bin赋予执行权限…

CMake 构建项目并整理头文件和库文件

本文将介绍如何使用 CMake 构建项目、编译生成库文件&#xff0c;并将头文件和库文件整理到统一的目录中以便在其他项目中使用。 1. 项目结构 假设我们正在构建一个名为 rttr 的开源库&#xff0c;初始的项目结构如下&#xff1a; D:\WorkCode\Demo\rttr-master\|- src\ …

JAVA HTTP压缩数据

/*** 压缩数据包** param code* param data* param resp* throws IOException*/protected void writeZipResult(int code, Object data, HttpServletResponse resp) throws IOException {resp.setHeader("Content-Encoding", "gzip");// write到客户端resp…

公路边坡安全监测中智能化+定制化+全面守护的应用方案

面对公路边坡的安全挑战&#xff0c;我们如何精准施策&#xff0c;有效应对风险&#xff1f;特别是在强降雨等极端天气下&#xff0c;如何防范滑坡、崩塌、路面塌陷等灾害&#xff0c;确保行车安全&#xff1f;国信华源公路边坡安全监测解决方案&#xff0c;以智能化、定制化为…

uniapp 微信小程序 数据空白展示组件

效果图 html <template><view class"nodata"><view class""><image class"nodataimg":src"$publicfun.locaAndHttp()?localUrl:$publicfun.httpUrlImg(httUrl)"mode"aspectFit"></image>&l…

41.欠采样技术下变频不能用与跨两个nyquist的情况下

当接收到的信号位于同一nyquist区间时&#xff0c;信号被成功的折叠到了第一Nyquist区间中。 当接收信号位于两个或多个采样区间时&#xff0c;最后多个区间的信号都会被折叠到第一Nyquist区间中造成信号的重叠。

AI新书推荐:深度学习和大模型原理与实践(清华社)

本书简介 在这个信息爆炸、技术革新日新月异的时代&#xff0c;深度学习作为人工智能领域的重要分支&#xff0c;正引领着新一轮的技术革命。《深度学习和大模型原理与实践》一书&#xff0c;旨在为读者提供深度学习及其大模型技术的全面知识和实践应用的指南。 本书特色在于…

Vue项目中env文件的作用和配置

在实际项目的开发中&#xff0c;我们一般会经历项目的开发阶段、测试阶段和最终上线阶段&#xff0c;每一个阶段对于项目代码的要求可能都不尽相同&#xff0c;那么我们如何能够游刃有余的在不同阶段下使我们的项目呈现不同的效果&#xff0c;使用不同的功能呢&#xff1f;这里…

Ubuntu 22.04.5 修改IP

Ubuntu22.04.5使用的是netplan管理网络&#xff0c;因此需要在文件夹/etc/netplan下的01-network-manager-all.yaml中修改&#xff0c;需要权限&#xff0c;使用sudo vim或者其他编辑器&#xff0c;修改后的内容如下&#xff1a; # Let NetworkManager manage all devices on …

NeeView(图像查看器) v42.4

NeeView是一款功能强大的图像查看器&#xff0c;它为用户提供了一种独特的方式&#xff0c;可以像翻阅书籍一样轻松地浏览文件夹中的图像。这款软件支持多种标准的兼容图像格式&#xff0c;包括bmp、jpg、gif、tiff、png、ico、svg以及WIC兼容图像&#xff0c;这意味着用户可以…

动态规划子序列问题系列一>等差序列划分II

题目&#xff1a; 解析&#xff1a; 1.状态表示&#xff1a; 2.状态转移方程&#xff1a; 这里注意有个优化 3.初始化&#xff1a; 4.填表顺序&#xff1a; 5.返回值&#xff1a; 返回dp表总和 代码&#xff1a; public int numberOfArithmeticSlices(int[] nums) {in…