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

微服务框架SpringcloudAlibaba+Nacos集成RabbitMQ

目前公司使用jeepluscloud版本,这个版本没有集成消息队列,这里记录一下,集成的过程;这个框架跟ruoyi的那个微服务版本结构一模一样,所以也可以快速上手。

1.项目结构图:

配置类的东西做成一个公共的模块

在这里插入图片描述

rabbitmq模块:

在这里插入图片描述

2.核心配置

1.pom类

<?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"><parent><artifactId>jeeplus-common</artifactId><groupId>org.jeeplus</groupId><version>${revision}</version></parent><modelVersion>4.0.0</modelVersion><artifactId>jeeplus-common-rabbitmq</artifactId><packaging>jar</packaging><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId></dependency><dependency><groupId>org.jeeplus</groupId><artifactId>jeeplus-common-core</artifactId><version>${project.parent.version}</version></dependency></dependencies>
</project>

2.ConditionalOnRabbit

package com.jeeplus.common.rabbit.conditional;import org.springframework.context.annotation.Conditional;import java.lang.annotation.*;/*** 判断系统是否在启用了Rabbit, 未启用的情况下不将Bean注册到系统中** 使用场景: 在不使用Rabbit中间件但未去除Rabbit依赖的情况下, 通过配置文件中关闭Rabbit选项,* 同时将这个注解到有`@RabbitListener`标志的类上,让这个对象不注册到Spring容器中,* 从而避免`RabbitMQ`进行无限尝试重连服务器,导致项目一直抛出异常,影响开发和使用。** @author xxm* @since 2022/12/12*/
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnRabbitEnable.class)
public @interface ConditionalOnRabbit {}

3.OnRabbitEnable

package com.jeeplus.common.rabbit.conditional;import com.jeeplus.common.rabbit.configuration.RabbitMqProperties;
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;/*** 判断是否在启用了Rabbit, 用来控制在没启用Rabbit情况下. 不将 @RabbitListener 修饰的监听器注册为Bean, 不然会导致无限尝试重连** @author xxm* @since 2022/12/12*/
public class OnRabbitEnable implements Condition {private final String rabbitPropertiesPrefix = "com.jeeplus.common.rabbit";/*** @param context* @param metadata* @return*/@Overridepublic boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {RabbitMqProperties rabbitMqProperties = Binder.get(context.getEnvironment()).bind(rabbitPropertiesPrefix, RabbitMqProperties.class).orElse(new RabbitMqProperties());return rabbitMqProperties.isEnable();}}

4.BootxRabbitListenerConfigurer

package com.jeeplus.common.rabbit.configuration;import lombok.RequiredArgsConstructor;
import org.springframework.amqp.rabbit.annotation.RabbitListenerConfigurer;
import org.springframework.amqp.rabbit.listener.RabbitListenerEndpointRegistrar;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.handler.annotation.support.DefaultMessageHandlerMethodFactory;/*** Rabbit 侦听器配置器** @author xxm* @since 2021/6/25*/
@Configuration
@RequiredArgsConstructor
public class BootxRabbitListenerConfigurer implements RabbitListenerConfigurer {private final DefaultMessageHandlerMethodFactory jsonHandlerMethodFactory;@Overridepublic void configureRabbitListeners(RabbitListenerEndpointRegistrar registrar) {registrar.setMessageHandlerMethodFactory(jsonHandlerMethodFactory);}}

5.BootxRabbitListenerConfigurer

package com.jeeplus.common.rabbit.configuration;import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.amqp.rabbit.annotation.EnableRabbit;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.converter.MappingJackson2MessageConverter;
import org.springframework.messaging.handler.annotation.support.DefaultMessageHandlerMethodFactory;/*** 消息队列配置** @author xxm* @since 2021/6/25*/
@EnableRabbit
@Configuration
public class RabbitMqConfigurer {/*** 注册 RabbitTemplate 对象, 使用默认序列化方式*/@Beanpublic RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory, ObjectMapper objectMapper) {RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);// 使用系统同版jackson 序列化配置rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter(objectMapper));return rabbitTemplate;}/*** 添加默认消息序列化方式, 使用默认序列化方式*/@Beanpublic DefaultMessageHandlerMethodFactory jsonHandlerMethodFactory(ObjectMapper objectMapper) {DefaultMessageHandlerMethodFactory factory = new DefaultMessageHandlerMethodFactory();// 这里的转换器设置实现了 通过 @Payload 注解 自动反序列化message bodyMappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();converter.setObjectMapper(objectMapper);factory.setMessageConverter(converter);return factory;}}

6.RabbitMqConfigurer

package com.jeeplus.common.rabbit.configuration;import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.amqp.rabbit.annotation.EnableRabbit;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.converter.MappingJackson2MessageConverter;
import org.springframework.messaging.handler.annotation.support.DefaultMessageHandlerMethodFactory;/*** 消息队列配置** @author xxm* @since 2021/6/25*/
@EnableRabbit
@Configuration
public class RabbitMqConfigurer {/*** 注册 RabbitTemplate 对象, 使用默认序列化方式*/@Beanpublic RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory, ObjectMapper objectMapper) {RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);// 使用系统同版jackson 序列化配置rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter(objectMapper));return rabbitTemplate;}/*** 添加默认消息序列化方式, 使用默认序列化方式*/@Beanpublic DefaultMessageHandlerMethodFactory jsonHandlerMethodFactory(ObjectMapper objectMapper) {DefaultMessageHandlerMethodFactory factory = new DefaultMessageHandlerMethodFactory();// 这里的转换器设置实现了 通过 @Payload 注解 自动反序列化message bodyMappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();converter.setObjectMapper(objectMapper);factory.setMessageConverter(converter);return factory;}}

7.RabbitMqProperties

package com.jeeplus.common.rabbit.configuration;import com.jeeplus.common.rabbit.conditional.ConditionalOnRabbit;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;/*** MQTT配置** @author xxm* @since 2022/12/12*/
@Getter
@Setter
@ConfigurationProperties("com.jeeplus.common.rabbit")
public class RabbitMqProperties {/*** 是否开启 RabbitMQ功能,* @see ConditionalOnRabbit 配合此注解使用*/private boolean enable = false;}

8.RabbitMqCommonAutoConfiguration

package com.jeeplus.common.rabbit;import org.springframework.boot.autoconfigure.SpringBootApplication;/*** RabbitMQ配置** @author xxm* @since 2022/5/3*/
@SpringBootApplication
public class RabbitMqCommonAutoConfiguration {}

在这里插入图片描述

9.org.springframework.boot.autoconfigure.AutoConfiguration.imports

RabbitMqCommonAutoConfiguration

10.spring.factories

## 配置自定义 starter 的自动化配置
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\com.jeeplus.common.rabbit.RabbitMqCommonAutoConfiguration

3. nacos配置

哪一个服务模块需要消息队列,就在对应的yml文件中配置 rabbit链接
在这里插入图片描述

  #rabbitmqrabbitmq:host: localhostport: 5627username: rootpassword: root123virtual-host: /publisher-confirm-type: correlatedlistener:simple:acknowledge-mode: manual

4.服务中调用rabbitmq

建立两个包,配置类和监听类

在这里插入图片描述

1.mq模板配置

package com.jeeplus.duxin.config;import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;/*** mq模板* @author lgn* @date 2023/10/28 10:15*/
@Configuration
public class MyRabbitConfig {private RabbitTemplate rabbitTemplate;@Primary@Beanpublic RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);this.rabbitTemplate = rabbitTemplate;rabbitTemplate.setMessageConverter(messageConverter());initRabbitTemplate();return rabbitTemplate;}@Beanpublic MessageConverter messageConverter() {return new Jackson2JsonMessageConverter();}/*** 定制RabbitTemplate* 1、服务收到消息就会回调*      1、spring.rabbitmq.publisher-confirms: true*      2、设置确认回调* 2、消息正确抵达队列就会进行回调*      1、spring.rabbitmq.publisher-returns: true*         spring.rabbitmq.template.mandatory: true*      2、设置确认回调ReturnCallback** 3、消费端确认(保证每个消息都被正确消费,此时才可以broker删除这个消息)**/// @PostConstruct  //MyRabbitConfig对象创建完成以后,执行这个方法public void initRabbitTemplate() {/*** 1、只要消息抵达Broker就ack=true* correlationData:当前消息的唯一关联数据(这个是消息的唯一id)* ack:消息是否成功收到* cause:失败的原因*///设置确认回调rabbitTemplate.setConfirmCallback((correlationData,ack,cause) -> {System.out.println("confirm...correlationData["+correlationData+"]==>ack:["+ack+"]==>cause:["+cause+"]");});/*** 只要消息没有投递给指定的队列,就触发这个失败回调* message:投递失败的消息详细信息* replyCode:回复的状态码* replyText:回复的文本内容* exchange:当时这个消息发给哪个交换机* routingKey:当时这个消息用哪个路邮键*/rabbitTemplate.setReturnCallback((message,replyCode,replyText,exchange,routingKey) -> {System.out.println("Fail Message["+message+"]==>replyCode["+replyCode+"]" +"==>replyText["+replyText+"]==>exchange["+exchange+"]==>routingKey["+routingKey+"]");});}
}

2.服务交换机 队列设置

初始化交换机,队列,建立绑定。

package com.jeeplus.duxin.config;import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.Exchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.util.HashMap;/*** 服务交换机 队列设置* @author lgn* @date 2023/10/28 10:16*/
@Configuration
public class MyRabbitMQConfig {/* 容器中的Queue、Exchange、Binding 会自动创建(在RabbitMQ)不存在的情况下 *//*    *//*** 初始化队列* 死信队列** @return*//*@Beanpublic Queue orderDelayQueue() {*//*Queue(String name,  队列名字boolean durable,  是否持久化boolean exclusive,  是否排他boolean autoDelete, 是否自动删除Map<String, Object> arguments) 属性*//*HashMap<String, Object> arguments = new HashMap<>();arguments.put("x-dead-letter-exchange", "order-event-exchange");arguments.put("x-dead-letter-routing-key", "order.release.order");arguments.put("x-message-ttl", 60000); // 消息过期时间 1分钟Queue queue = new Queue("order.delay.queue", true, false, false, arguments);return queue;}*//*    *//*** 初始化队列* 普通队列** @return*//*@Beanpublic Queue orderReleaseQueue() {Queue queue = new Queue("order.release.order.queue", true, false, false);return queue;}*//*    *//**** TopicExchange* 创建topic类型的交换机* @return*//*@Beanpublic Exchange orderEventExchange() {*//**   String name,*   boolean durable,*   boolean autoDelete,*   Map<String, Object> arguments* *//*return new TopicExchange("order-event-exchange", true, false);}*//*    *//*** 路由和交换机进行绑定 设置路由key* @author lgn* @date 2023/10/28 10:33* @return Binding*//*@Beanpublic Binding orderCreateBinding() {*//** String destination, 目的地(队列名或者交换机名字)* DestinationType destinationType, 目的地类型(Queue、Exhcange)* String exchange,* String routingKey,* Map<String, Object> arguments* *//*return new Binding("order.delay.queue",Binding.DestinationType.QUEUE,"order-event-exchange","order.create.order",null);}*//*    @Beanpublic Binding orderReleaseBinding() {return new Binding("order.release.order.queue",Binding.DestinationType.QUEUE,"order-event-exchange","order.release.order",null);}*//*** 订单释放直接和库存释放进行绑定* @return*//*@Beanpublic Binding orderReleaseOtherBinding() {return new Binding("stock.release.stock.queue",Binding.DestinationType.QUEUE,"order-event-exchange","order.release.other.#",null);}*//*    *//*** 初始化队列* 商品秒杀队列* @return*//*@Beanpublic Queue orderSecKillOrrderQueue() {Queue queue = new Queue("order.seckill.order.queue", true, false, false);return queue;}@Beanpublic Binding orderSecKillOrrderQueueBinding() {//String destination, DestinationType destinationType, String exchange, String routingKey,// 			Map<String, Object> argumentsBinding binding = new Binding("order.seckill.order.queue",Binding.DestinationType.QUEUE,"order-event-exchange","order.seckill.order",null);return binding;}*//*** BOM模块的交换机* TopicExchange* 创建topic类型的交换机* @return*/@Beanpublic Exchange orderEventExchange() {/**   String name,*   boolean durable,*   boolean autoDelete,*   Map<String, Object> arguments* */return new TopicExchange("bom-event-exchange", true, false);}/*** 初始化BOM队列* @return*/@Beanpublic Queue bomMaintenanceQueue() {Queue queue = new Queue("bom.maintenance.queue", true, false, false);return queue;}/*** bom* 路由和交换机进行绑定 设置路由key* @author lgn* @date 2023/10/28 10:33* @return Binding*/@Beanpublic Binding bomCreateBinding() {/** String destination, 目的地(队列名或者交换机名字)* DestinationType destinationType, 目的地类型(Queue、Exhcange)* String exchange,* String routingKey,* Map<String, Object> arguments* */return new Binding("bom.maintenance.queue",Binding.DestinationType.QUEUE,"bom-event-exchange","bom.maintenance.create",null);}/*** 初始化产品存货档案队列* @return*/@Beanpublic Queue stockDocQueue() {Queue queue = new Queue("stock.doc.queue", true, false, false);return queue;}/*** 存货档案StockDoc* 路由和交换机进行绑定 设置路由key* @author lgn* @date 2023/10/28 10:33* @return Binding*/@Beanpublic Binding docCreateBinding() {/** String destination, 目的地(队列名或者交换机名字)* DestinationType destinationType, 目的地类型(Queue、Exhcange)* String exchange,* String routingKey,* Map<String, Object> arguments* */return new Binding("stock.doc.queue",Binding.DestinationType.QUEUE,"bom-event-exchange","stock.doc.create",null);}/*** 调用C++模块的交换机* TopicExchange* 创建topic类型的交换机* @return*/@Beanpublic Exchange cEventExchange() {/**   String name,*   boolean durable,*   boolean autoDelete,*   Map<String, Object> arguments* */return new TopicExchange("c-event-exchange", true, false);}/*** 初始化c++生成记录文件队列* @return*/@Beanpublic Queue cCreatFileQueue() {Queue queue = new Queue("c.creatfile.queue", true, false, false);return queue;}/*** 初始化c++签名队列* @return*/@Beanpublic Queue cDealQueue() {Queue queue = new Queue("c.deal.queue", true, false, false);return queue;}/** * 创建绑定关系* @author lgn* @date 2023/10/30 9:34* @return Binding*/@Beanpublic Binding cCreatFileCreateBinding() {/** String destination, 目的地(队列名或者交换机名字)* DestinationType destinationType, 目的地类型(Queue、Exhcange)* String exchange,* String routingKey,* Map<String, Object> arguments* */return new Binding("c.creatfile.queue",Binding.DestinationType.QUEUE,"c-event-exchange","c.creatFile.create",null);}/*** 创建绑定关系* @author lgn* @date 2023/10/30 9:34* @return Binding*/@Beanpublic Binding cDealBinding() {/** String destination, 目的地(队列名或者交换机名字)* DestinationType destinationType, 目的地类型(Queue、Exhcange)* String exchange,* String routingKey,* Map<String, Object> arguments* */return new Binding("c.deal.queue",Binding.DestinationType.QUEUE,"c-event-exchange","c.deal.create",null);}}

3.监听队列 接收消息

消费方消费消息

package com.jeeplus.duxin.listener;import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;import java.io.IOException;/*** 监听路由信息* @author lgn* @date 2023/10/28 10:33*/
@Slf4j
@Component
//@RabbitListener标注在方法上,直接监听指定的队列,此时接收的参数需要与发送时类型一致
//@RabbitListener 注解是指定某方法作为消息消费的方法,例如监听某 Queue 里面的消息。
@RabbitListener(queues = "bom.maintenance.queue")
public class MQTestListener {//@RabbitListener 可以标注在类上面,需配合 @RabbitHandler 注解一起使用//@RabbitListener 标注在类上面表示当有收到消息的时候,就交给 @RabbitHandler 的方法处理,根据接受的参数类型进入具体的方法中。@RabbitHandlerpublic void listener(String info,Channel channel, Message message) throws IOException {System.out.println("=============接收消息开始执行:"+info);try {channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);} catch (Exception e) {channel.basicReject(message.getMessageProperties().getDeliveryTag(),true);}}
}

5.使用

使用起来也非常方便:
在业务service中直接调用,生产者消息发送。

	/*** mqTest* @author lgn* @date 2023/10/28 10:03* @return Object*/public String mqTest() {//TODO 订单创建成功,发送消息给MQrabbitTemplate.convertAndSend("bom-event-exchange","bom.maintenance.create","1234");return null;}

希望对你有用!

相关文章:

微服务框架SpringcloudAlibaba+Nacos集成RabbitMQ

目前公司使用jeepluscloud版本&#xff0c;这个版本没有集成消息队列&#xff0c;这里记录一下&#xff0c;集成的过程&#xff1b;这个框架跟ruoyi的那个微服务版本结构一模一样&#xff0c;所以也可以快速上手。 1.项目结构图&#xff1a; 配置类的东西做成一个公共的模块 …...

低代码开发,一场深度的IT效率革命

目录 一、前言 二、低代码迅速流行的理由 三、稳定性和生产率的最佳实践 四、程序员用低代码开发应用有哪些益处&#xff1f; 1、提升开发价值 2、利于团队升级 五、总结 一、前言 尽管IT技术支撑了全球的信息化浪潮&#xff0c;然而困扰行业已久的软件开发效率并未像摩尔定律那…...

虚拟串口软件使用介绍

对于上位机开发来说(特别是串口通信应用),上机位软件的调试尤为重要,但是上机位软件的调试并不关心硬件,只需要关注验证发送的数据帧的接收情况,为了便于调试,可以将上机位软件与串口软件互通,实现数据的交互,但由于互通需要串口,可以借助串口虚拟软件(VSPD),虚拟出…...

如何编写一份完整的软件测试报告?(进阶版)百分之90不知道

背景 作为测试从业者&#xff0c;编写测试用例&#xff0c;测试计划&#xff0c;测试报告都是必经之路&#xff0c;最近完成了年终述职以及版本准出&#xff0c;感觉测试报告或者各类报告真是职场人不可或缺的一项技能&#xff0c;趁着热乎劲&#x1f525;&#xff0c;写下一些…...

python企业微信小程序发送信息

python企业微信小程序发送信息 在使用下面代码之前先配置webhook 教程如下&#xff1a; https://www.bilibili.com/video/BV1oH4y1S7pN/?vd_sourcebee29ac3f59b719e046019f637738769 然后使用如下代码就可以发消息了&#xff1a; 代码如下&#xff1a; #codinggbk import r…...

Java入门篇 之 逻辑控制(练习题篇)

博主碎碎念: 练习题是需要大家自己打的请在自己尝试后再看答案哦&#xff1b; 个人认为&#xff0c;只要自己努力在将来的某一天一定会看到回报&#xff0c;在看这篇博客的你&#xff0c;不就是在努力吗&#xff0c;所以啊&#xff0c;不要放弃&#xff0c;路上必定坎坷&#x…...

Android Google登录并获取token(亲测有效)

背景&#xff1a; Android 需要用到Google的登录授权&#xff0c;用去token给到服务器&#xff0c;服务器再通过token去获取用户信息&#xff0c;实现第三方登录。 我们通过登录之后的email来获取token&#xff0c;不需要server_clientId&#xff1b;如果用server_clientId还…...

npm ERR! code ELIFECYCLE

问题&#xff1a; 一个老项目&#xff0c;现在想运行下&#xff0c;打不开了 npm install 也出错 尝试1 、使用cnpm npm install -g cnpm --registryhttps://registry.npm.taobao.org cnpm install 还是不行 尝试2、 package.json 文件&#xff0c;去掉 那个插件 chorm…...

Mgeo:multi-modalgeographic language model pre-training

文章目录 question5.1 Geographic Encoder5.1.1 Encoding5.1.2 5.2 multi-modal pre-training 7 conclusionGeo-Encoder: A Chunk-Argument Bi-Encoder Framework for Chinese Geographic Re-Rankingabs ERNIE-GeoL: A Geography-and-Language Pre-trained Model and its Appli…...

[激光原理与应用-75]:西门子PLC系列选型

目录 一、西门子PLC PLC系列 二、西门子PLC S7 1200系列 2.1 概述 2.2 12xx系列比较 三、西门子 PLC 1212C系列 四、主要类别比较 4.1 AC/DC/RLY的含义 4.2 AC/DC/RLY与DC/DC/DC 4.3 直流输入与交流输入比较 4.4 继电器输出与DC输出的区别 一、西门子PLC PLC系列 …...

Linux上编译sqlite3库出现undefined reference to `sqlite3_column_table_name‘

作者&#xff1a;朱金灿 来源&#xff1a;clever101的专栏 为什么大多数人学不会人工智能编程&#xff1f;>>> 在Ubuntu 18上编译sqlite3库后在运行程序时出现undefined reference to sqlite3_column_table_name’的错误。网上的说法是说缺少SQLITE_ENABLE_COLUMN_M…...

第十五章 EM期望极大算法及其推广

文章目录 导读符号说明混合模型伯努利混合模型(三硬币模型)问题描述三硬币模型的EM算法1.初值2.E步3.M步初值影响p,q 含义 EM算法另外视角Q 函数BMM的EM算法目标函数LEM算法导出 高斯混合模型GMM的EM算法1. 明确隐变量, 初值2. E步,确定Q函数3. M步4. 停止条件 如何应用GMM在聚…...

自动化测试如何准备测试数据

其实大部分类型的测试都需要去准备测试数据。 手工测试&#xff1a;一些基础数据&#xff0c;比如配置数据等等是需要去准备的&#xff1b;自动化测试&#xff1a;基础需要准备&#xff0c;现有数据&#xff0c;动态运行时产生的数据是需要准备的&#xff1b;性能测试&#xf…...

javaEE -13(6000字CSS入门级教程 - 2)

一&#xff1a;Chrome 调试工具 – 查看 CSS 属性 首先打开浏览器&#xff0c;接着有两种方式可以打开 Chrome 调试工具 直接按 F12 键鼠标右键页面 > 检查元素 点开检查即可 标签页含义&#xff1a; elements 查看标签结构console 查看控制台source 查看源码断点调试ne…...

vscode 使用python无法导入库

刚刚在使用vscode,编辑python时&#xff0c;在使用语句 import matplotlib.pyplot as plt 时出现报错&#xff0c;但是在命令行下和conda环境中没有报错 在尝试 pip uninstall matplotlib pip install matplotlib后无法解决 之后再发现是工作的目录出错导致的&#xff0c;…...

三维向量旋转

三维向量旋转 问题描述问题分析 v ⃗ ∣ ∣ \vec{v}_{||} v ∣∣​的旋转 v ⃗ ⊥ \vec{v}_{\bot} v ⊥​的旋转 v ⃗ \vec{v} v 的旋转结论致谢 问题描述 如图1所示&#xff0c;设一个向量 v ⃗ \vec{v} v 绕另一个向量 u ⃗ [ x , y , z ] T \vec{u}[x,y,z]^{T} u [x,y,z]T…...

顺序表——leetcode

原地删除数据 我们的思路这里给的是双指针&#xff0c;给两个指针&#xff0c;从前往后移动&#xff0c;如果不是val就覆盖&#xff0c;如果是我就跳过&#xff0c;大家一定要看到我们的条件是原地修改&#xff0c;所以我们不能另开一个数组来实现我们这道题目。 这里我们给两…...

Kaprekar 7641 - 1467= 6174

package homework;import java.util.Arrays;import util.StringUtil;/*** 数学黑洞数6174&#xff0c;即卡普雷卡尔&#xff08;Kaprekar&#xff09;常数&#xff0c; 它的算法如下&#xff1a; 取任意一个4位数&#xff08;4个数字均为同一个数的除外&#xff09;&#xff0…...

李宏毅机器学习笔记.Flow-based Generative Model(补)

文章目录 引子生成问题回顾&#xff1a;GeneratorMath BackgroundJacobian MatrixDeterminant 行列式Change of Variable Theorem简单实例一维实例二维实例 网络G的限制基于Flow的网络构架G的训练Coupling LayerCoupling Layer反函数计算Coupling Layer Jacobian矩阵计算Coupli…...

Java使用Spark入门级非常详细的总结

目录 Java使用Spark入门 环境准备 安装JDK 安装Spark 编写Spark应用程序 创建SparkContext 读取文本文件 计算单词出现次数 运行Spark应用程序 总结 Java使用Spark入门 本文将介绍如何使用Java编写Spark应用程序。Spark是一个快速的、通用的集群计算系统&#xff0c;它可以处理…...

kubernetes集群编排——k8s存储

configmap 字面值创建 kubectl create configmap my-config --from-literalkey1config1 --from-literalkey2config2kubectl get cmkubectl describe cm my-config 通过文件创建 kubectl create configmap my-config-2 --from-file/etc/resolv.confkubectl describe cm my-confi…...

【软件STM32cubeIDE下H73xx配置串口uart1+中断接收/DMA收发+HAL库+简单数据解析-基础样例】

#【软件STM32cubeIDE下H73xx配置串口uart1中断接收/DMA收发HAL库简单数据解析-基础样例】 1、前言2、实验器件3-1、普通收发中断接收实验第一步&#xff1a;代码调试-基本配置&#xff08;1&#xff09;基本配置&#xff08;3&#xff09;时钟配置&#xff08;4&#xff09;保存…...

jdk8和jdk9中接口的新特性

jdk8之前&#xff1a;声明抽象方法&#xff0c;修饰为public abstract。 jdk8&#xff1a;添加声明静态方法&#xff0c;默认方法。 jdk9&#xff1a;添加声明私有方法 jdk8: ①接口中声明的静态方法只能被接口来调用&#xff0c;不能使用其实现类进行调用 静态方法的声明&…...

1-爬虫-requests模块快速使用,携带请求参数,url 编码和解码,携带请求头,发送post请求,携带cookie,响应对象, 高级用法

1 爬虫介绍 2 requests模块快速使用 3 携带请求参数 4 url 编码和解码 4 携带请求头 5 发送post请求 6 携带cookie 7 响应对象 8 高级用法 1 爬虫介绍 # 爬虫是什么&#xff1f;-网页蜘蛛&#xff0c;网络机器人&#xff0c;spider-在互联网中 通过 程序 自动的抓取数据 的过程…...

java商城免费搭建 VR全景商城 saas商城 b2b2c商城 o2o商城 积分商城 秒杀商城 拼团商城 分销商城 短视频商城

1. 涉及平台 平台管理、商家端&#xff08;PC端、手机端&#xff09;、买家平台&#xff08;H5/公众号、小程序、APP端&#xff08;IOS/Android&#xff09;、微服务平台&#xff08;业务服务&#xff09; 2. 核心架构 Spring Cloud、Spring Boot、Mybatis、Redis 3. 前端框架…...

【TS篇一】TypeScript介绍、使用场景、环境搭建、类和接口

文章目录 一、TypeScript 介绍1. TypeScript 是什么1.2 静态类型和动态类型1.3 Why TypeScript1.4 TypeScript 使用场景1.5 TypeScript 不仅仅用于开发 Angular 应用1.6 前置知识 二、如何学习 TypeScript2.1 相关链接 三、起步3.1 搭建 TypeScript 开发环境3.2 编辑器的选择3.…...

Tuna: Instruction Tuning using Feedback from Large Language Models

本文是LLM系列文章&#xff0c;针对《Tuna: Instruction Tuning using Feedback from Large Language Models》的翻译。 Tuna:使用来自大型语言模型的反馈的指令调优 摘要1 引言2 方法3 实验4 相关工作5 结论局限性 摘要 使用更强大的LLM&#xff08;如Instruction GPT和GPT-…...

uni-app 应对微信小程序最新隐私协议接口要求的处理方法

这里给大家分享我在网上总结出来的一些知识&#xff0c;希望对大家有所帮助 一&#xff0c;问题起因 最新在开发小程序的时候&#xff0c;调用微信小程序来获取用户信息的时候经常报错一个问题 fail api scope is not declared in the privacy agreement&#xff0c;api更具公告…...

PostgreSQL 进阶 - 使用foreign key,使用 subqueries 插入,inner joins,outer joins

1. 使用foreign key 创建 table CREATE TABLE orders( order_id SERIAL PRIMARY KEY, purchase_total NUMERIC, timestamp TIMESTAMPTZ, customer_id INT REFERENCES customers(customer_id) ON DELETE CASCADE);“order_id”&#xff1a;作为主键的自增序列&#xff0c;使用 …...

【Python 千题 —— 基础篇】地板除计算

题目描述 题目描述 编写一个程序&#xff0c;接受用户输入的两个数字&#xff0c;然后计算这两个数字的地板除&#xff08;整除&#xff09;结果&#xff0c;并输出结果。 输入描述 输入两个数字&#xff0c;用回车隔开两个数字。 输出描述 程序将计算这两个数字的地板除…...