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

【02基础】- RabbitMQ基础

目录

  • 2- RabbitMQ
    • 2-1 介绍和安装
      • 安装
    • 2-2 RabbitMQ 快速入门
    • 2-3 RabbitMQ 数据隔离
  • 3- Java客户端
    • 3-1 快速入门
      • AMQP
      • 快速入门
      • 📑小结:SpringAMQP如何收发消息?
    • 3-2 WorkQueues 任务模型
      • 案例-使用 WorkQueue 单队列绑定多消费者
      • 📑小结:Work模型的使用
    • 3-3 Fanout 交换机
      • 案例- FanouotExchange 使用
      • 📑小结:交换机的作用是什么?
    • 3-4 Direct 交换机
      • 案例-利用 SpringAMQP 演示 DirectExchange 的使用
      • 📑小结:DirectExchange 的作用是什么?
    • 3-5 Topic 交换机
      • 案例-利用 SpringAMQP 演示 DirectExchange 的适用
      • 📑小结:描述下 Direct 交换机和 Topic 交换机的差异
    • 3-6 声明队列和交换机
      • 声明队列和交换机的方式(Java代码实现)
        • 代码实现
        • 使用注解的方式解决 Direct 交换机问题
      • 📑小结
    • 3-7 消息转换器
      • 案例-利用 SpringAMQP 发送对象类型的消息
      • 问题
  • 4- 使用 MQ 改造支付业务代码
    • 案例

2- RabbitMQ

2-1 介绍和安装

RabbitMQ 的整体架构以及核心概念

  • publisher:消息发送者
  • cunsumer:消息消费者
  • queue:队列
  • exchange:交换机,负责路由消息
  • virtual-host :虚拟主机,起到数据隔离的作用;一个 MQ 中可以创建多个 virtual-host

数据流转的模型①生产者将数据发送给交换机 ——> ②交换机将消息路由给队列 ——> ③消费者监听队列拿到消息

安装

  1. 上传镜像文件 mq.tar 到 Linux 系统中
  2. 执行命令
docker load -i mq.tar
  1. 复制以下代码执行
  • 其中 15672 ,是控制台端口
  • 其中 5672 ,是收发消息的端口
docker run \
-e RABBITMQ_DEFAULT_USER=itheima \
-e RABBITMQ_DEFAULT_PASS=123321 \
-v mq-plugins:/plugins \
--name mq \
--hostname mq \
-p 15672:15672 \
-p 5672:5672 \
--network hmall \
-d \
rabbitmq:3.8-management

2-2 RabbitMQ 快速入门

需求

  • rabbitmq 的控制台完成下列操作:
  • 新建队列 hello.queue1hello.queue2
  • 向默认的 amp.fanout 交换机发送一条消息
  • 查看消息是否到达 hello.queue1hello.queue2

实现

  • 需要创建队列,同时在交换机中需要绑定队列才能实现消息的路由。

总结规律

①如果交换机和队列没有绑定能否收到消息?

  • 交换机:是负责路由和转发消息的。交换机通过绑定队列,之后可以将消息转发到队列中。

②如果绑定了所有队列是不是所有队列都可以收到消息?

  • 是的,如果一个交换机绑定了多个队列,那类似于广播的效果所有队列都能收到消息。

2-3 RabbitMQ 数据隔离

  • 在 RabbitMQ 中有虚拟主机的概念,对于交换机和队列而言都有二者自己的虚拟主机。

需求

  • 在 RabbitMQ 的控制台下完成下列操作
    • 新建一个用户 hmall
    • 为 hmall 用户创建一个 vitual host
    • 测试不同的 vitual host 之间的数据隔离现象

实现

  • ① 首先在 Admin ——> Users 中创建用户
  • ② 在 Admin ——> Users 中创建虚拟主机

总结

  • 各个虚拟主机下都是相互隔离的。

3- Java客户端

3-1 快速入门

AMQP

什么是 AMQP?

  • Advanced Message Queuing Protocol,是一种高级的消息队列协议,是用于在应用程序之间传递业务消息的开放标准。该协议与语言和平台无关,更符合微服务中独立性的要求。

Spring AMQP

  • Spring AMQP是基于 AMQP 协议定义的一套 API 规范,提供了模板来发送和接收消息。包含两部分,其中Spring AMQP 是基础抽象,spring-rabbit 是底层的默认实现

快速入门

需求

  • 利用控制台创建队列 simple.queue
  • 在 publisher 服务中,利用 SpringAMQP 直接向 simple.queue 发送消息
  • 在 consumer 服务中,利用 SpringAMQP 编写消费者监听 simple.queue 队列

实现

  • ① 引入 spring-amqp依赖,在父工程中引入 spring-amqp 依赖,这样 publisherconsumer 服务都可以使用
<!-- AMQP依赖,包含RabbitMQ -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
  • ② 在每个微服务中引入 MQ 服务端信息,这样微服务才能连接到 RabbitMQ

  • ③ 发送消息: SpringAMQP 提供了 RabbitTemplate 工具类,方便我们发送消息,发送消息的代码如下
@Autowired
private RabbitTemplate rabbitTemplate;@Test
public void testSimpleQueue() {// 队列名称String queueName = "simple.queue";// 消息String message = "hello, spring amqp!";// 发送消息rabbitTemplate.convertAndSend(queueName, message);
}
  • ④ 接收消息
  • SpringAMQP 提供声明式的消息监听,我们只需要通过 注解 在方法上声明要监听的队列名称,将来 SpringAMQP 就会把消息传递给当前方法。
@Slf4j
@Component
public class SpringRabbitListener {@RabbitListener(queues = "simple.queue")public void listenSimpleQueueMessage(String msg) throws InterruptedException {log.info("spring 消息接收到消息: [" + msg + "]");if (true) {throw new MessageConversionException("故意的");}log.info("消息处理完毕");}
}

📑小结:SpringAMQP如何收发消息?

在这里插入图片描述


3-2 WorkQueues 任务模型

  • Work queues,任务模型。简单来说就是 让多个消费者绑定到一个队列,共同消费队列中的消息。

案例-使用 WorkQueue 单队列绑定多消费者

模拟 WorkQueue 实现一个队列绑定多个消费者,基本思路如下

  • ① 在 RabbitMQ 的控制台创建一个队列,名为 work.queue
  • ② 在 publisher 服务中定义测试方法,在 1 秒内产生 50 条消息,发送到 work.queue
  • ③ 在 consumer 服务中顶级两个消息监听者,都监听 work.queue 队列
  • ④ 消费者每 1 秒处理 50 条消息,消费者每 2 秒处理 5 条消息

实现

  • ① 实现消费者
@Slf4j
@Component
public class MqListener {@RabbitListener(queues = "simple.queue")public void listenSimpleQueue(String msg) {System.out.println("消费者收到了simple.queue的消息: [" + msg + "]");}@RabbitListener(queues = "work.queue")public void listenWorkQueue1(String msg) {System.out.println("消费者1 收到了 work.queue的消息: [" + msg + "]");}@RabbitListener(queues = "work.queue")public void listenWorkQueue2(String msg) {System.err.println("消费者2 收到了 work.queue的消息: [" + msg + "]");}
}
  • ② 实现生产者
@SpringBootTest
public class SpringAmqpTest {@Autowiredprivate RabbitTemplate rabbitTemplate;@Testvoid testSendMessage2Queue() {String queueName = "simple.queue";String msg = "hello, amqp!";rabbitTemplate.convertAndSend(queueName, msg);}@Testvoid testWorkQueue() throws InterruptedException {String queueName = "work.queue";for (int i = 1; i <= 50; i++) {String msg = "hello, worker, message_" + i;rabbitTemplate.convertAndSend(queueName, msg);Thread.sleep(20);}}
}

结果

  • 发现在消费的过程中,两个消费者并没有都消费 50 条消息。
  • 二者消费的过程是采用轮询的方式进行消费。

通过改变消费速度

  • 即便改变了消费的速度,消费的过程中消费者1 和消费者2,也是按照轮询的方式消费任务。
    @RabbitListener(queues = "work.queue")public void listenWorkQueue1(String msg) {System.out.println("消费者1 收到了 work.queue的消息: [" + msg + "]");}@RabbitListener(queues = "work.queue")public void listenWorkQueue2(String msg) {System.err.println("消费者2 收到了 work.queue的消息: [" + msg + "]");Thread.sleep(20);}

📑小结:Work模型的使用

在这里插入图片描述


3-3 Fanout 交换机

Fanout Exchange 交换机会将收到的消息广播到每一个跟其绑定的 queue,所以也叫 广播模式

案例- FanouotExchange 使用

实现思路如下

  • ① 在 RabbitMQ 控制台中,声明队列 fanout.queue1fanout.queue2
  • ② 在 RabbitMQ 控制台中,声明交换机 hmall.fanout 将两个队列与其绑定
  • ③ 在 consumer 服务中,编写两个消费者方法,分别监听 fanout.queue1**fanout.queue2
  • ④ 在 publisher 中编写测试方法,向 hmall.fanout 发送消息。

Fanout 交换机

  • 消费者
@RabbitListener(queues = "fanout.queue1")
public void listenWorkQueue1(String msg) {System.out.println("消费者1 收到了 fanout.queue1的消息: [" + msg + "]");
}@RabbitListener(queues = "fanout.queue2")
public void listenWorkQueue2(String msg) {System.err.println("消费者2 收到了 fanout.queue2的消息: [" + msg + "]");
}
  • 生产者
@Test
void testSendFanout()  {String exchangeName = "hmall.fanout";String msg = "hello,everyone";rebbitTemplate.converAndSend(exchangeName,numm,msg);
}
  • 运行结果

📑小结:交换机的作用是什么?

在这里插入图片描述


3-4 Direct 交换机

Direct Exchange 会将接收到的消息根据路由规则路由到指定的 Queue,因此可以称为定向路由。

  • 每一个 Queue 都与 Exchange 设置一个 Bindingkey
  • 发布者发送消息时,制定消息的 RoutingKey
  • Exchange 将消息路由到 BindingKey 与消息 RoutingKey 一致的队列

案例-利用 SpringAMQP 演示 DirectExchange 的使用

需求如下

  • ① 在 RabbitMQ 控制台中,声明队列 direct.queue1 和 direct.queue2
  • ② 在 RabbitMQ 控制台中,声明交换机 hmall.direct,将两个队列与其绑定
  • ③ 在 consumer 服务中,编写两个消费方法,分别监听 direct.queue1 和 direct.queue2
  • ④ 在 publisher 中编写测试方法,利用不同的 RoutingKey 向 hmall.direct 发送消息

📑小结:DirectExchange 的作用是什么?

:::info

  • DirectExchange 交换机可以通过 bindingKey 来设置,将消息通过 bindingKey 发送到指定的队列中。通过设置合适的绑定键,您可以确保特定的消息被发送到特定的微服务进行处理。这样可以实现消息的精确路由,确保消息只被需要的消费者接收和处理。

:::


3-5 Topic 交换机

TopicExchange 与 DirectExchange 类似,区别在于 routingKey 可以是多个单词的列表,并且以 . 分割。

  • Queue 与 Exchange 指定 BindingKey 时可以使用通配符
    • #代表 0 个 或多个单词。
    • * :代指一个单词

  • 类似上述实现,如果一个 bindingKey 定义为了 china.# 那么,对于其而言只会接收与 china.#开头的消息。

案例-利用 SpringAMQP 演示 DirectExchange 的适用

需求如下

  • ① 在 RabbitMQ 控制台中,声明队列 topic.queue1 和 topic.queue2
  • ② 在 RabbitMQ 控制台中,声明交换机 hmall.topic 将两个队列与其绑定
  • ③ 在 consumer 服务中,编写两个消费者方法,分别监听 topic.queue1 和 topic.queue2
  • ④ 在 publisher 中编写测试方法,利用不同的 RoutingKey 向 hmall.topic 发送消息

  • 消费者
@RabbitListener(queues = "topic.queue1")
public void listenTopicQueue1(String msg) throws InterruptedException {System.out.println("消费者1 收到了 topic.queue1的消息: [" + msg + "] ");
}@RabbitListener(queues = "topic.queue2")
public void listenTopicQueue2(String msg) throws InterruptedException {System.out.println("消费者2 收到了 topic.queue2的消息: [" + msg + "] ");
}
  • 发送者
    • 以下情况消息会被路由到 **#.news** 的队列中。
@Test
void testSendTopic() {String exchangeName = "hmall.topic";String msg = "蓝色通知,警报解除,哥斯拉是放的气球";rabbitTemplate.convertAndSend(exchangeName, "japan.news", msg);
}
  • 发送者2
    • 以下情况两个队列都会收到消息。
@Test
void testSendTopic() {String exchangeName = "hmall.topic";String msg = "蓝色通知,警报解除,哥斯拉是放的气球";rabbitTemplate.convertAndSend(exchangeName, "china.news", msg);
}
  • 发送者3
    • 以下情况只有队列1 会受到消息。
@Test
void testSendTopic() {String exchangeName = "hmall.topic";String msg = "蓝色通知,警报解除,哥斯拉是放的气球";rabbitTemplate.convertAndSend(exchangeName, "china.weather", msg);
}

📑小结:描述下 Direct 交换机和 Topic 交换机的差异

在这里插入图片描述

3-6 声明队列和交换机

  • 使用 Java 代码声明队列交换机才是最靠谱的方式

声明队列和交换机的方式(Java代码实现)

SpringAMQP 提供了几个类,用来声明队列、交换机及其绑定关系

  • Queue:用于声明队列,可用工厂类 QueueBuilder 创建
  • Exchange:用于声明交换机,可以用工厂类 ExchangeBuilder 构建
  • Binding:用于声明队列和交换机的绑定关系,可以用工厂类 BindingBuilder 构建

代码实现
  • 例如,声明一个 Fanout 类型的交换机,并且创建队列与其绑定
public class FanoutConfiguration {@Beanpublic FanoutExchange fanoutExchange(){// ExchangeBuilder.fanoutExchange("").build();return new FanoutExchange("hmall.fanout2");}@Beanpublic Queue fanoutQueue3(){// QueueBuilder.durable("ff").build();return new Queue("fanout.queue3");}@Beanpublic Binding fanoutBinding3(Queue fanoutQueue3, FanoutExchange fanoutExchange){return BindingBuilder.bind(fanoutQueue3).to(fanoutExchange);}@Beanpublic Queue fanoutQueue4(){// QueueBuilder.durable("ff").build();return new Queue("fanout.queue4");}@Beanpublic Binding fanoutBinding4(){return BindingBuilder.bind(fanoutQueue4()).to(fanoutExchange());}
}
使用注解的方式解决 Direct 交换机问题
  • 由于 Direct 交换机可以配置对应的 key,但对于声明式方式来说,需要对每个 key 都写一个 binding 方法,这样效率很低,所以引入注解的方式实现
  • SpringAMQP 还提供了基于 @RabbitListener 注解来声明队列和交换机的方式,在 Listener 的部分通过注解实现
@RabbitListener(bindings = @QueueBinding(value = @Queue(name = "direct.queue1",durable = "true"),exchange = @Exchange(name = "hmall,direct",type = ExchangeTypes,DIRECT),key = {"red","blue"}
))
public void listenDirectQueue1(String msg)  throws InterruptedException{System.out.println("消费者 1 收到了 direct.queueq 的消息:【"+msg+"】");
}

📑小结

在这里插入图片描述


3-7 消息转换器

案例-利用 SpringAMQP 发送对象类型的消息

  • ① 声明一个队列,名为 object.queue
  • ② 编写单元测试,向队列中直接发送一条消息,消息类型为 Map
  • ③ 在控制台查看消息,总结你能发现的问题
// 准备消息
Map<String,Object> msg = new HashMap<>();
msg.put("name","Jack");
msg.put("age",21);
@Test
void testSendObject() {Map<String, Object> msg = new HashMap<>(2);msg.put("name", "jack");msg.put("age", 21);rabbitTemplate.convertAndSend("object.queue", msg);
}

问题

  • Spring 对消息对象的处理是由 org.springframework,amqp.support.converter.MessageConveerter 来处理的。而默认实现是 SimpleMessageConverter,基于 JDK 的 ObjectOutputStream 完成序列化。

存在以下问题

  • JDK 的序列化有安全风险
  • JDK 序列化的消息太大
  • JDK 序列化的消息可读性差

建议采用 JSON 薛丽华代替默认的的 JDK 序列化,要做两件事情:

  • 在 publisher 和 consumer 中都要引入 Jackson 依赖:
<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId>
</dependency>
  • 在 publisher 和 consumer 中都要配置 MessageConverter
@Bean
public MessageConverter messageConverter() {return new Jackson2JsonMessageConverter();
}

4- 使用 MQ 改造支付业务代码

案例

  • 需求:改造余额支付功能,不再同步调用交易服务的 OpenFeign 接口,而是采用异步的 MQ 通知交易服务更改订单状态

    1. 业务中引入 AMQP 依赖
<!-- amqp -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
  • 2.配置 MQ 的地址
spring:rabbitmq:host: 192.168.150.101port: 5672virtual-host: /hmallusername: hmallpassword: 123
    1. 配置 MQ 的 Configure
@Configuration
public class MqConfig {@Beanpublic MessageConverter jackson2JsonMessageConverter() {return new Jackson2JsonMessageConverter();}
}
    1. 编写监听器
@Component
@RequiredArgsConstructor
public class PayStatusListener {private final IOrderService orderService;@RabbitListener(bindings = @QueueBinding(value = @Queue(name = "mark.order.pay.queue", durable = "true"),exchange = @Exchange(name = "pay.topic", type = ExchangeTypes.TOPIC),key = "pay.success"))public void listenOrderPay(Long orderId) {// 标记订单状态为已支付orderService.markOrderPaySuccess(orderId);}
}
    1. 业务异步调用
rabbitTemplate.convertAndSend("pay.topic", "pay.success", po.getBizOrderNo());

相关文章:

【02基础】- RabbitMQ基础

目录 2- RabbitMQ2-1 介绍和安装安装 2-2 RabbitMQ 快速入门2-3 RabbitMQ 数据隔离 3- Java客户端3-1 快速入门AMQP快速入门&#x1f4d1;小结&#xff1a;SpringAMQP如何收发消息&#xff1f; 3-2 WorkQueues 任务模型案例-使用 WorkQueue 单队列绑定多消费者&#x1f4d1;小结…...

vue3中跨层传递provide、inject

前置说明 在 Vue 3 中&#xff0c;provide 和 inject 是一对用于跨组件树传递数据的 API。它们允许你在祖先组件中使用 provide 提供数据或服务&#xff0c;然后在后代组件中使用 inject 来获取这些数据或服务。这种方式特别适用于跨多个层级的组件传递数据&#xff0c;而不需要…...

Nacos-1.4.6升级2.3.2

一、nacos-2.3.2部署(非升级测试步骤) 1、使用nginx进行代理 # nginx-1.25.5 docker run -d --name nginx-nacos --network nacos --privilegedtrue -v /data/nacos/nginx.conf:/etc/nginx/conf.d/default.conf -p 8848:8848 nginx:latest2、创建nacos服务 # nacos-2.3.2 do…...

东识集中文印管理系统|DW-S408系统的主要功能

集中文印管理系统以涉密文件集中管理为目标&#xff0c;实现办公文件汇总、打印信息生成、文件打印、文件追溯等功能&#xff0c;将用户与打印设备分离&#xff0c;有效防止纸媒泄密。 集中文印管理系统是由客户端和服务端两部分构成&#xff0c;客户端能够将打印文件上传至服…...

text-foreground讲解

1、fore单词讲解 fore 是 “forward” 或 “front” 的简写&#xff0c;意思是"前面的"、“前景的”。 一些常见的相关英文词&#xff1a; foreground fore ground&#xff0c;意思是"前景" background back ground&#xff0c;意思是"背景&qu…...

数字IC后端实现之Innovus Place跑完density爆涨案例分析

下图所示为咱们社区a7core后端训练营学员的floorplan。 数字IC后端实现 | Innovus各个阶段常用命令汇总 该学员跑placement前density是59.467%&#xff0c;但跑完place后density飙升到87.68%。 仔细查看place过程中的log就可以发现Density一路飙升&#xff01; 数字IC后端物…...

【牛客刷题实战】二叉树遍历

大家好&#xff0c;我是小卡皮巴拉 文章目录 目录 牛客题目&#xff1a; 二叉树遍历 题目描述 输入描述&#xff1a; 输出描述&#xff1a; 示例1 解题思路 问题理解 算法选择 具体思路 解题要点 完整代码&#xff08;C语言&#xff09; 兄弟们共勉 &#xff01;&…...

消息队列mq有哪些缺点?

大家好&#xff0c;我是锋哥。今天分享关于【消息队列mq有哪些缺点&#xff1f;】面试题&#xff1f;希望对大家有帮助&#xff1b; 消息队列mq有哪些缺点&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 消息队列&#xff08;MQ&#xff09;的缺点 消…...

【CENet】多模态情感分析的跨模态增强网络

在MSA领域&#xff0c;文本的准确度远远高于音频和视觉&#xff0c;如果文本能达到90%&#xff0c;那么音频和视觉的准确度只有60%~80%&#xff0c;但是过往研究很少针对情感分析的背景下去提高音频和视频的准确度。 abstract&#xff1a; 多模态情感分析&#xff08;MSA&…...

动态代理:面向接口编程,屏蔽RPC处理过程

RPC远程调用 使用 RPC 时&#xff0c;一般的做法是先找服务提供方要接口&#xff0c;通过 Maven把接口依赖到项目中。在编写业务逻辑的时候&#xff0c;如果要调用提供方的接口&#xff0c;只需要通过依赖注入的方式把接口注入到项目中&#xff0c;然后在代码里面直接调用接口…...

HTTP 405 Method Not Allowed:解析与解决

HTTP 405 Method Not Allowed&#xff1a;解析与解决 引言 在Web开发中&#xff0c;HTTP状态码是服务器与客户端之间通信的重要组成部分。当我们使用Python进行网络请求时&#xff0c;经常会遇到各种HTTP状态码。其中&#xff0c;HTTP 405 “Method Not Allowed” 错误是一个…...

推荐一款CAD/CAM设计辅助工具:Mastercam

Mastercam是一款非常好用的软件&#xff0c;我们的这款软件是由美国CNC软件公司开发&#xff0c;集平面制图、三维设计、曲面设计、数 控编程、刀具处理等多项强大功能于一体。软件的使用过程具有非常直观的特点&#xff0c;用户可以很方便地对自己的作品进行设计。 Mastercam不…...

位运算刷题记录

1. 使两个整数相等的位更改次数 3226. 使两个整数相等的位更改次数 给你两个正整数 n 和 k。 你可以选择 n 的 二进制表示 中任意一个值为 1 的位&#xff0c;并将其改为 0。 返回使得 n 等于 k 所需要的更改次数。如果无法实现&#xff0c;返回 -1。 class Solution {pub…...

爬虫技术——小白入狱案例

知孤云出岫 目录 1. 案例概述2. 案例需求分析3. 实现步骤Step 1: 环境准备Step 2: 分析百度图片URL请求规律Step 3: 编写爬虫代码代码解析 4. 运行代码5. 注意事项6. 案例总结 要实现大批量爬取百度图片&#xff0c;可以使用Python编写一个网络爬虫&#xff0c;通过发送HTTP请求…...

vue 果蔬识别系统百度AI识别vue+springboot java开发、elementui+ echarts+ vant开发

编号&#xff1a;R03-果蔬识别系统 简介&#xff1a;vuespringboot百度AI实现的果蔬识别系统 版本&#xff1a;2025版 视频介绍&#xff1a; vuespringboot百度AI实现的果蔬识别系统前后端java开发&#xff0c;百度识别&#xff0c;带H5移动端&#xff0c;mysql数据库可视化 1 …...

全新更新!Fastreport.NET 2025.1版本发布,提升报告开发体验

在.NET 2025.1版本中&#xff0c;我们带来了巨大的期待功能&#xff0c;进一步简化了报告模板的开发过程。新功能包括通过添加链接报告页面、异步报告准备、HTML段落旋转、代码文本编辑器中的文本搜索、WebReport图像导出等&#xff0c;大幅提升用户体验。 FastReport .NET 是…...

信息学科平台系统设计与实现:Spring Boot技术手册

5系统详细实现 5.1 用户信息管理 基于保密信息学科平台系统的系统管理员可以对用户信息查询。具体界面的展示如图5.1所示。 图5.1 用户信息管理界面 5.2 教师信息管理 管理员可以对教师信息进行查下和删除。具体界面如图5.2所示。 图5.2 教师信息界面 5.3 学科动态管理 管理…...

conda下jupyterlab安装问题以及交互绘图问题记录

安装 1. 直接conda install jupyterlab就好&#xff0c;只要在base环境下安装就行&#xff0c;可以在任意环境下执行jupyter lab启动。 2. 打开jupyter lab后显示Could not determine jupyterlab build status without nodejs&#xff0c;可以执行conda install nodejs安装no…...

尚硅谷react教程_扩展_setState更新状态的2种写法

1.setState setState更新状态的2种写法&#xff08;1&#xff09;.setState(stateChange,[callback])----对象式的setState1.stateChange为状态改变对象&#xff08;该对象可以体现出状态的更改&#xff09;2.callback是可选的回调函数&#xff0c;它在状态更新完毕、界面也更新…...

C语言编写的自动取款机模拟程序

#include〈stdio。h> #include<string。h> #include <stdio.h> #include〈stdlib.h〉 #include〈direct.h〉 #include<io.h> #include 〈errno。h> /********************************************************…...

DeerFlow惊艳案例:AI深度研究助理生成的报告和播客效果实测

DeerFlow惊艳案例&#xff1a;AI深度研究助理生成的报告和播客效果实测 1. 引言&#xff1a;当AI成为你的研究伙伴 想象一下&#xff0c;你正在为一个复杂的市场分析项目焦头烂额&#xff0c;需要快速整理一份包含最新数据、行业趋势和竞争格局的深度报告。传统方式下&#x…...

GitHub功能全景:从代码创作到企业级方案的技术生态

【导语&#xff1a;GitHub作为全球知名的代码托管平台&#xff0c;提供了丰富多样的功能&#xff0c;涵盖AI代码创作、开发者工作流、应用程序安全等多个领域&#xff0c;还针对不同规模公司、用例和行业提供解决方案&#xff0c;对软件开发行业产生着深远影响。】【GitHub的多…...

实战复盘:从帕鲁杯应急响应赛题看企业级安全事件调查全流程

企业级安全事件调查实战指南&#xff1a;从CTF赛题到真实攻防溯源 在网络安全领域&#xff0c;应急响应能力直接决定了企业遭受攻击后的损失程度。去年某大型电商平台因未能及时识别攻击链&#xff0c;导致用户数据持续泄露长达三周&#xff0c;最终造成数亿元的直接损失。这类…...

FPGA实战:手把手教你用Verilog给NAND Flash数据上把“安全锁”(附完整ECC代码)

FPGA实战&#xff1a;用Verilog为NAND Flash打造硬件级ECC防护系统 1. 为什么你的NAND Flash需要硬件ECC&#xff1f; NAND Flash存储芯片在工业控制、物联网终端和边缘计算设备中扮演着关键角色&#xff0c;但它的物理特性导致数据可靠性存在先天缺陷。想象一下&#xff0c;当…...

别再只数步数了!深入聊聊ADXL345计步算法里的‘动态阈值’与‘最活跃轴’

别再只数步数了&#xff01;深入聊聊ADXL345计步算法里的‘动态阈值’与‘最活跃轴’ 当你盯着智能手环上的步数统计时&#xff0c;有没有想过这串数字背后藏着怎样的算法智慧&#xff1f;ADXL345作为一款经典的三轴加速度传感器&#xff0c;其计步算法远非简单的阈值比较那么简…...

PN5180 ISO15693协议栈实现与嵌入式NFC开发指南

1. PN5180库深度解析&#xff1a;面向嵌入式工程师的NFC ISO15693协议栈实现指南NXP PN5180是业界领先的多协议NFC控制器&#xff0c;支持ISO/IEC 14443 A/B、ISO/IEC 15693、Felica及NFC Forum Type 1–5标签。其核心优势在于高集成度射频前端、可编程调制解调器及灵活的主机接…...

智能转换驱动科研效率:DeTikZify重构学术图表自动化新范式

智能转换驱动科研效率&#xff1a;DeTikZify重构学术图表自动化新范式 【免费下载链接】DeTikZify Synthesizing Graphics Programs for Scientific Figures and Sketches with TikZ 项目地址: https://gitcode.com/gh_mirrors/de/DeTikZify 在科研成果可视化的关键环节…...

【Git】深入解析 ‘.git/index.lock‘ 文件冲突:从报错到彻底解决

1. 当Git突然罢工&#xff1a;index.lock报错现场还原 那天下午我正忙着切换分支部署新功能&#xff0c;突然终端弹出红字警告&#xff1a;fatal: Unable to create .git/index.lock: File exists。这就像你急着上厕所却发现门被反锁&#xff0c;更糟的是你不知道里面到底有没有…...

AI赋能.NET开发:让快马平台智能生成Redis缓存与消息队列集成代码

最近在做一个电商系统的订单模块&#xff0c;发现缓存和消息队列这两个组件几乎是标配。但每次从零开始集成Redis和RabbitMQ都要查半天文档&#xff0c;配置各种连接字符串&#xff0c;写一堆样板代码。直到尝试用InsCode(快马)平台的AI辅助功能&#xff0c;才发现原来这些重复…...

Openclaw案例之构建《全自动化、高适配、可定制”的AI绘画生产体系》

⚡⚡⚡ 欢迎预览&#xff0c;批评指正⚡⚡⚡ 文章目录一、需求&目标二、搭建基础环境2.1 环境准备2.2 OpenClaw与绘画模型部署启动2.3 核心配置&#xff08;模型插件联动&#xff09;三、核心操作3.1 多智能体角色配置&#xff08;核心步骤&#xff09;3.2 一键启动自动化…...