springboot整合RabbitMQ,RabbitMQ实现高级特性消息不丢失

news2024/11/17 15:32:16

1.生产者可靠性消息投递

简单操作参考---------打开主页上篇博客

https://blog.csdn.net/weixin_45810161/article/details/135906602?spm=1001.2014.3001.5501

在使用RabbitMQ的时候,怎么保证保证消息不丢失,RabbitMQ提供了两种不同的方式来控制消息的可靠性投递
1.confirm模式,生产者发送到交换机
2.return模式,交换机发送到队列

2.搭建生产者项目

2.1添加依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.rabbitmq</groupId>
    <artifactId>springboot-rabbitmq-demo01</artifactId>
    <version>1.0-SNAPSHOT</version>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.4.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
    </dependencies>
</project>

2.2配置文件

配置文件开启confirm老版本可能不一样,如图所示,配置为true

在这里插入图片描述

server:
  port: 19991
spring:
  application:
    name: rabbitmq-producer
  rabbitmq:
    host: 192.168.3.123
    port: 5672
    virtual-host: /mqname1
    username: admin
    password: admin
    #开启confirm模式
    publisher-confirm-type: correlated

2.3新建启动类

package com.rabbitmq;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @Author: albc
 * @Date: 2024/01/30/10:06
 * @Description: good good study,day day up
 */
@SpringBootApplication
public class RabbitMqApplication {
    public static void main(String[] args) {
        SpringApplication.run(RabbitMqApplication.class, args);
        System.out.println("启动成功");
    }
}

2.4新建配置类

package com.rabbitmq.config;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * Rabbitmq配置类
 * @Author: albc
 * @Date: 2024/01/30/11:09
 * @Description: good good study,day day up
 */
@Configuration
public class RabbitMqConfig {

    //创建队列
    @Bean
    public Queue createqueue(){
        return new Queue("springboot_queue");
    }

    //创建交换机
    @Bean
    public DirectExchange createExchange(){
        return new DirectExchange("springboot_exchange");
    }

    //创建绑定
    @Bean
    public Binding createBinding(){
        return BindingBuilder.bind(createqueue()).to(createExchange()).with("user.insert");
    }
}

2.5新建回调函数

package com.rabbitmq.confirm;

import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;

/**
 * 发送交换机回调函数
 * @Author: albc
 * @Date: 2024/01/30/11:55
 * @Description: good good study,day day up
 */
@Component
public class MyConfirmCallback implements RabbitTemplate.ConfirmCallback {

    /**
     *
     * @param correlationData 发送消息信息
     * @param ack  确认标识:true,MQ服务器exchange表示已经确认收到消息 false 表示没有收到消息
     * @param cause  如果没有收到消息,则指定为MQ服务器exchange消息没有收到的原因,如果已经收到则指定为null
     */
    @Override
    public void confirm(@Nullable CorrelationData correlationData, boolean ack, @Nullable String cause) {
        if(ack){
            System.out.println("发送消息到交换机成功:"+cause);
        }else{
            System.out.println("发送消息到交换机失败,原因是:"+cause);
        }
    }

}

2.6测试

备注:如果发送失败,查看是否创建原来的队列导致的,进入rabbitmq客户端,删除交换机和队列
在这里插入图片描述
在这里插入图片描述

package com.rabbitmq.controller;

import com.rabbitmq.confirm.MyConfirmCallback;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @Author: albc
 * @Date: 2024/01/30/10:14
 * @Description: good good study,day day up
 */
@RestController
@RequestMapping("/test")
public class TestController {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private MyConfirmCallback myConfirmCallback;

    @RequestMapping("/test1")
    public String test1(){
        //设置回调函数
        rabbitTemplate.setConfirmCallback(myConfirmCallback);
        //发送消息
        rabbitTemplate.convertAndSend("springboot_exchange", "user.insert", "测试user.insert消息发送");
        System.out.println("测试");
        return "发送成功";
    }

}

项目结构如下
在这里插入图片描述

发送消息
在这里插入图片描述
发送成功返回null
在这里插入图片描述
消费者收到消息

在这里插入图片描述
当发送一个不存在的交换机时
在这里插入图片描述
返回失败
在这里插入图片描述
消费者未收到消息
在这里插入图片描述

3.搭建消费者服务

3.1添加依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.rabbitmq</groupId>
    <artifactId>springboot-rabbitmq-demo02</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.4.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
    </dependencies>
</project>

3.2 创建启动类

package com.rabbitmq;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * 消费者消费消息
 * @Author: albc
 * @Date: 2024/01/30/13:41
 * @Description: good good study,day day up
 */
@SpringBootApplication
public class ConsumberApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConsumberApplication.class, args);
        System.out.println("启动成功");
    }
}

3.3 创建监听类

package com.rabbitmq.common;

import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

/**
 * 消费者
 * @Author: albc
 * @Date: 2024/01/30/13:45
 * @Description: good good study,day day up
 */
@Component
public class RabbitMqConsumber {

    /**
     * 消费者监听某个队列的消息
     * @param message 接收到的消息
     */
    @RabbitListener(queues = "springboot_queue")
    public void myListener1(String message){
        System.out.println("消费者接收到的消息为:" + message);
    }
}

3.4配置文件

server:
  port: 19992
spring:
  application:
    name: rabbitmq-consumer
  rabbitmq:
    host: 192.168.3.123
    port: 5672
    virtual-host: /mqname1
    username: admin
    password: admin

4.开启return模式

上面已经开启了confirm模式,可以保证消息发送交换机,但是如果交换机发送成功,消息发送队列的时候发送错误,消息还是会丢,现在需要开启return模式

4.1配置文件开启return模式

    #开启return模式
    publisher-returns: true

在这里插入图片描述

4.2 设置回调函数

发送消息正常不会回调

package com.rabbitmq.returns;

import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Component;

/**
 * 开启return模式回调函数
 * @Author: albc
 * @Date: 2024/01/30/14:31
 * @Description: good good study,day day up
 */
@Component
public class MyReturnsCallback implements RabbitTemplate.ReturnCallback {


    /**
     *
     * @param message 退回的消息信息
     * @param replyCode 退回的状态码,对应消息信息
     * @param replyText 退回的信息
     * @param exchange 交换机
     * @param routingKey 路由key
     */
    @Override
    public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
        System.out.println("开启Return模式退回的消息是:"+new String(message.getBody()));
        System.out.println("开启Return模式退回的replyCode是:"+replyCode);
        System.out.println("开启Return模式退回的replyText是:"+replyText);
        System.out.println("开启Return模式退回的exchange是:"+exchange);
        System.out.println("开启Return模式退回的routingKey是:"+routingKey);
    }



}

4.3测试消息发送

package com.rabbitmq.controller;

import com.rabbitmq.confirm.MyConfirmCallback;
import com.rabbitmq.returns.MyReturnsCallback;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @Author: albc
 * @Date: 2024/01/30/10:14
 * @Description: good good study,day day up
 */
@RestController
@RequestMapping("/test")
public class TestController {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private MyConfirmCallback myConfirmCallback;

    @Autowired
    private MyReturnsCallback myReturnCallback;

    @RequestMapping("/test1")
    public String test1(){
        //设置回调函数
        rabbitTemplate.setConfirmCallback(myConfirmCallback);
        //发送消息
        rabbitTemplate.convertAndSend("springboot_exchange", "user.insert", "测试user.insert消息发送");
        System.out.println("测试");
        return "发送成功";
    }

    @RequestMapping("/test2")
    public String test2(){
        //设置回调函数
        //rabbitTemplate.setConfirmCallback(myConfirmCallback);
        rabbitTemplate.setReturnCallback(myReturnCallback);
        //发送消息
        rabbitTemplate.convertAndSend("springboot_exchange", "user.insert", "测试user.insert-Returns消息发送");
        System.out.println("测试");
        return "发送成功";
    }


}

在这里插入图片描述

发送成功
在这里插入图片描述
消费者收到消息

在这里插入图片描述

测试发送不存在的队列

在这里插入图片描述

回调报错

在这里插入图片描述
同时开启confirm模式,return模式

在这里插入图片描述
发送交换机成功,发送到队列失败
在这里插入图片描述

正常消息发送,修改成正确的交换机和队列
在这里插入图片描述

发送成功
在这里插入图片描述

消费者收到消息

在这里插入图片描述

5.手动确认消息ACK

前面实现了发送的消息不丢失,但是消费者可能会丢消息,例如消息者没有接受消息,或者消费者收到消息后出现异常,这种情况下消息会丢失,RabbitMQ提供了一种进行手动确认的消息,ACK机制
ACK有三种模式
自动确认
当消息被消费者收到以后,会自动确认收到消息,消息会从队列中移除,实际业务中,消息可能收到了,但是业务执行过程中出现了异常,这种情况消息就会丢失

手动确认
当收到消息以后,需要手动确认消息收到,调用channel.basicAck手动签收,如果出现异常,调用channel.basicNack按照功能业务处理,例如:重新发送,拒绝签收进入死信队列等

根据异常情况来确认(基本不用)
RabbitMQ判断异常肯定不如我们判断的异常靠谱,基本不用

5.1开启ack模式

修改配置文件

消费者配置文件
不是生产者开启
在这里插入图片描述

    #开启手动确认
    listener:
      simple:
        acknowledge-mode: manual

生产者发送消息测试

http://127.0.0.1:19991/test/test2

测试接受消息

在这里插入图片描述

消费以后发现消息还在,重启以后又再次收到了消息
在这里插入图片描述

在这里插入图片描述

5.2手动确认消息

修改监听类RabbitMqConsumber

第一种:签收
channel.basicAck()
第二种:拒绝签收 批量处理
channel.basicNack()
第三种:拒绝签收 不批量处理
channel.basicReject()

自动确认代码修改前

package com.rabbitmq.common;

import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

/**
 * 消费者
 * @Author: albc
 * @Date: 2024/01/30/13:45
 * @Description: good good study,day day up
 */
@Component
public class RabbitMqConsumber {

    /**
     * 消费者监听某个队列的消息
     * @param message 接收到的消息
     */
    @RabbitListener(queues = "springboot_queue")
    public void myListener1(String message){
        System.out.println("消费者接收到的消息为:" + message);
    }
}

修改后,手动确认消息

package com.rabbitmq.common;

import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.io.IOException;

/**
 * 消费者
 * @Author: albc
 * @Date: 2024/01/30/13:45
 * @Description: good good study,day day up
 */
@Component
public class RabbitMqConsumber {

    /**
     * 消费者监听某个队列的消息
     * @param message 接收到的消息
     */
    @RabbitListener(queues = "springboot_queue")
    public void myListener1(Message message, Channel channel, String msg){
        System.out.println("消费者收到了消息:"+msg);
        //消息的属性
        MessageProperties messageProperties = message.getMessageProperties();
        try {
            /**
             * 手动确认消息
             * 1.签收消息的编号
             * 2.是否批量签收,如果批量签收,如果收到的消息为1000,则会把小于1000的消息全部签收
             * 一般不用
             */
            channel.basicAck(messageProperties.getDeliveryTag(),false);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

当前消息还在

在这里插入图片描述

重启后消费,已经确认消息不在了
在这里插入图片描述

5.3异常处理

package com.rabbitmq.common;

import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.io.IOException;

/**
 * 消费者
 * @Author: albc
 * @Date: 2024/01/30/13:45
 * @Description: good good study,day day up
 */
@Component
public class RabbitMqConsumber {

    /**
     * 消费者监听某个队列的消息
     * @param message 接收到的消息
     */
    @RabbitListener(queues = "springboot_queue")
    public void myListener1(Message message, Channel channel, String msg){
        System.out.println("消费者收到了消息:"+msg);
        //消息的属性
        MessageProperties messageProperties = message.getMessageProperties();
        try {
            int i = 1/0;
            /**
             * 手动确认消息
             * 1.签收消息的编号
             * 2.是否批量签收,如果批量签收,如果收到的消息为1000,则会把小于1000的消息全部签收
             * 一般不用
             */
            channel.basicAck(messageProperties.getDeliveryTag(),false);
        } catch (Exception e) {
            System.out.println("进入异常方法.............");
            //保存数据库等
            try {
                /**
                 * 1.消息的编号
                 * 2.是否将消息放回到队列,false:不放回,true:放回队列
                 */
                channel.basicReject(messageProperties.getDeliveryTag(),false);
            } catch (IOException e1) {
                e1.printStackTrace();
            }


        }
    }
}

在这里插入图片描述
此时没有数据

在这里插入图片描述
发送测试
在这里插入图片描述

进入异常方法
在这里插入图片描述

因为没有放回队列,队列无数据
在这里插入图片描述

修改放回队列

在这里插入图片描述

会出现一直报错一直放回队列

在这里插入图片描述

放回队列代码

package com.rabbitmq.common;

import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.io.IOException;

/**
 * 消费者
 * @Author: albc
 * @Date: 2024/01/30/13:45
 * @Description: good good study,day day up
 */
@Component
public class RabbitMqConsumber {

    /**
     * 消费者监听某个队列的消息
     * @param message 接收到的消息
     */
    @RabbitListener(queues = "springboot_queue")
    public void myListener1(Message message, Channel channel, String msg){
        System.out.println("消费者收到了消息:"+msg);
        //消息的属性
        MessageProperties messageProperties = message.getMessageProperties();
        try {
            int i = 1/0;
            /**
             * 手动确认消息
             * 1.签收消息的编号
             * 2.是否批量签收,如果批量签收,如果收到的消息为1000,则会把小于1000的消息全部签收
             * 一般不用
             */
            channel.basicAck(messageProperties.getDeliveryTag(),false);
        } catch (Exception e) {
            System.out.println("进入异常方法.............");
            //保存数据库等
            try {
                /**
                 * 1.消息的编号
                 * 2.是否将消息放回到队列,false:不放回,true:放回队列
                 */
                channel.basicReject(messageProperties.getDeliveryTag(),true);
            } catch (IOException e1) {
                e1.printStackTrace();
            }


        }
    }
}

批量处理

package com.rabbitmq.common;

import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.io.IOException;

/**
 * 消费者
 * @Author: albc
 * @Date: 2024/01/30/13:45
 * @Description: good good study,day day up
 */
@Component
public class RabbitMqConsumber {

    /**
     * 消费者监听某个队列的消息
     * @param message 接收到的消息
     */
    @RabbitListener(queues = "springboot_queue")
    public void myListener1(Message message, Channel channel, String msg){
        System.out.println("消费者收到了消息:"+msg);
        //消息的属性
        MessageProperties messageProperties = message.getMessageProperties();
        try {
            int i = 1/0;
            /**
             * 手动确认消息
             * 1.签收消息的编号
             * 2.是否批量签收,如果批量签收,如果收到的消息为1000,则会把小于1000的消息全部签收
             * 一般不用
             */
            channel.basicAck(messageProperties.getDeliveryTag(),false);
        } catch (Exception e) {
            System.out.println("进入异常方法.............");
            //保存数据库等
            try {
                /**
                 * 1.消息的编号
                 * 2.是否将消息放回到队列,false:不放回,true:放回队列
                 */
                //channel.basicReject(messageProperties.getDeliveryTag(),true);
                /**
                 * 批量处理
                 * 1.消息的编号
                 * 2.是否批量处理
                 * 3.是否放回到队列
                 */
                channel.basicNack(messageProperties.getDeliveryTag(),false,false);
            } catch (IOException e1) {
                e1.printStackTrace();
            }


        }
    }
}

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

js中的数据类型(存储上的差别)

文章目录 前言一、基本类型NumberUndefinedStringNullBooleanSymbol 二、引用类型ObjectArrayFunction其他引用类型 三、存储区别基本类型引用类型 小结 前言 在JavaScript中&#xff0c;我们可以分成两种类型&#xff1a; 基本类型复杂类型 两种类型的区别是&#xff1a;存…

老版本labelme如何不保存imagedata

我的版本是3.16&#xff0c;默认英文且不带取消保存imagedata的选项。 最简单粗暴的方法就是在json文件保存时把传递过来的imagedata数据设定为None&#xff0c;方法如下&#xff1a; 找到labelme的源文件&#xff0c;例如&#xff1a;D:\conda\envs\deeplab\Lib\site-packages…

jsp自助点餐管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 JSP 自助点餐管理系统是一套完善的java web信息管理系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysql5.0…

PCB笔记(二十三):allegro 标注长宽(一般用于测量板宽)时如何显示双单位

步骤&#xff1a;首先选择标注工具&#xff0c;然后右键→Parameters&#xff0c;在弹出来的窗口中√上如下图二所示选项 最终要达到显示单位的效果的话&#xff0c;需要在Text项键入%v%u。 今天就记录到这里啦O

Jmeter直连mysql数据库教程

mysql数据库能够通过Navicat等远程连接工具连接 下载驱动并加入jmeter 1.mysql驱动下载地址&#xff1a;MySQL :: Download MySQL Connector/J (Archived Versions) 找到对应的驱动下载&#xff1a;如下图&#xff1a; 把驱动jar包加入jmeter 配置jmeter连接mysql数据库…

正则表达式与文本处理工具

目录 引言 一、正则表达式基础 &#xff08;一&#xff09;字符匹配 1.基本字符 2.特殊字符 3.量词 4.边界匹配 &#xff08;二&#xff09;进阶用法 1.组与引用 2.选择 二、命令之-----grep &#xff08;一&#xff09;基础用法 &#xff08;二&#xff09;高级用…

数据结构——实验01-线性表的链式存储和操作

一、实验内容 二、算法思想与算法实现 1、解题思想 &#xff08;1&#xff09;逆序创建链表La就是使用头插法创建一个链表&#xff0c;所谓头插法就是在创建链表时始终将新元素插入到头结点之后&#xff0c;而正序创建链表Lb就是使用尾插法创建一个链表&#xff0c;所谓尾插法…

Spring Bean 生命周期常见错误

虽然说 Spring 容器上手简单&#xff0c;可以仅仅通过学习一些有限的注解&#xff0c;即可达到快速使用的目的。但在工程实践中&#xff0c;我们依然会从中发现一些常见的错误。尤其当你对 Spring 的生命周期还没有深入了解时&#xff0c;类初始化及销毁过程中潜在的约定就不会…

AJAX-URL查询参数

定义&#xff1a;浏览器提供给服务器的额外信息&#xff0c;让服务器返回浏览器想要的数据 http://xxxx.com/xxx/xxx?参数名1值1&参数名2值2 axios语法 使用axios提供的params选项 注意&#xff1a;axios在运行时把参数名和值&#xff0c;会拼接到url?参数名值 axios(…

第5课 使用FFmpeg将rtmp流再转推到rtmp服务器

本课对应源文件下载链接&#xff1a; https://download.csdn.net/download/XiBuQiuChong/88801992 通过前面的学习&#xff0c;我们已经可以正常播放网络rtmp流及本地mp4文件。这节课&#xff0c;我们将在前面的基础上实现一个常用的转推功能&#xff1a;读取rtmp流或mp4文件并…

matlab|【EI复现】日前日内多阶段多时间尺度源荷储协调调度

目录 一、模型 二、程序运行 三、下载链接 多阶段多时间尺度的协调调度的优势是考虑新能源出力的波动性与随机性&#xff0c;减少需求响应负荷的不确定性对电网制定的日前调度计划准确性造成的影响&#xff0c;也就是能够更加精准的进行调度和分析&#xff0c;优化结果的可用…

(java版)排序算法----【冒泡,选择,插入,希尔,快速排序,归并排序,基数排序】超详细~~

目录 冒泡排序(BubbleSort)&#xff1a; 代码详解&#xff1a; 冒泡排序的优化&#xff1a; 选择排序(SelectSort)&#xff1a; 代码详解&#xff1a; 插入排序&#xff08;InsertSort&#xff09;&#xff1a; 代码详解&#xff1a; 希尔排序(ShellSort)&#xff1a; 法一…

【数据结构与算法】之排序系列-20240202

这里写目录标题 一、389. 找不同二、414. 第三大的数三、455. 分发饼干四、506. 相对名次五、561. 数组拆分六、594. 最长和谐子序列 一、389. 找不同 简单 给定两个字符串 s 和 t &#xff0c;它们只包含小写字母。 字符串 t 由字符串 s 随机重排&#xff0c;然后在随机位置添…

双非本科准备秋招(14.3)—— java线程

创建和运行线程 1、使用Thread Slf4j(topic "c.Test1")public class Test1 {public static void main(String[] args) {Thread t new Thread("t1") {Overridepublic void run() {log.debug("running");}};t.start();​log.debug("runnin…

VUE项目导出excel

导出excel主要可分为以下两种&#xff1a; 1. 后端主导实现 流程&#xff1a;前端调用到导出excel接口 -> 后端返回excel文件流 -> 浏览器会识别并自动下载 场景&#xff1a;大部分场景都有后端来做 2. 前端主导实现 流程&#xff1a;前端获取要导出的数据 -> 把常规数…

Apache Paimon 文件布局设计

Apache Paimon 介绍 Apache Paimon 基础概念 一张表的所有文件都存储在一个基本目录下&#xff0c;Paimon 文件以分层方式组织。从快照文件开始&#xff0c;可以递归地访问表中的所有记录。 image.png Snapshot Files 所有的 snapshot 文件都存储在 snapshot 目录下&#xff0c…

【C语言刷题系列】喝汽水问题

文章目录 一、文章简介 1.先买再换 1.1 代码逻辑&#xff1a; 1.2 完整代码 1.3 运行结果 1.4 根据方法一总结优化 2.边买边换 2.1 代码逻辑&#xff1a; 2.2 完整代码 2.3 运行结果 一、文章简介 本文所述专栏——C语言经典编程问题 C语言刷题_倔强的石头106的博客…

【AI绘画UI+Windows部署】Fooocus:Controlnet原作者结合了sd的开源和Midjourney重新设计的UI

代码&#xff1a;https://github.com/lllyasviel/Fooocus windows一键启动包下载&#xff1a;https://github.com/lllyasviel/Fooocus/releases/download/release/Fooocus_win64_2-1-831.7z B站视频教程&#xff1a;AI绘画入门神器&#xff1a;Fooocus | 简化SD流程&#xff0c…

创建型模式-单例模式:定义、实现及应用

目录 一、模式定义二、针对问题1.解决的问题2.解决方案3.举个例子4.设计模式适合场景5.实现方式6.优缺点7.与其他模式的关系 三、代码实现 一、模式定义 单例模式&#xff08;Singleton Pattern&#xff09;是一种创建型模式&#xff0c;用于限制某个类只能创建一个对象。它提…

【代码随想录】LC 455. 分发饼干

文章目录 前言一、题目1、原题链接2、题目描述 二、解题报告1、思路分析2、时间复杂度3、代码详解 前言 本专栏文章为《代码随想录》书籍的刷题题解以及读书笔记&#xff0c;如有侵权&#xff0c;立即删除。 一、题目 1、原题链接 455. 分发饼干 2、题目描述 二、解题报告 1、…