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

尚硅谷rabbitmq2024 工作模式路由篇 第11节 答疑

String exchangeName ="test_direct";
/! 创建交换机
人图全
channel.exchangeDeclare(exchangeName,BuiltinExchangeType.DIREcT, b: true, b1: false, b2: false, map: null);
/1 创建队列
String queue1Name ="test_direct_queue1";
String queue2Name ="test direct queve2";
1惠明(创)&列
channel.queveDeclare(queue1Name,b: true, b1: false, b2: false, map: null);channel.queueDeclare(queue2Name,b: true,b1: false,b2: false, map: null);
/!队列绑定交换机//队列1绑定error
channel.queueBind(queue1Name,exchangeName,s2:"error");
//队列2锦定info error warning
channel.queveBind(queue2Name,exchangeName,s2:"info");
channel.gveveBind(aveve2Name,exchangeName,s2:"error"):channel.queueBind(queue2Name,exchangeName,s2:"warning");
String message ="日志信息:张三调用了delete方法,错误了,目志级别warning";
11 发送消息
channel.basicPublish(exchangeName, s1: "warning", basicProperties: null,message.getBytes());System.out.println(message);
// 释放资濛笮咸
----------发布订阅模式的时候绑定队列和交换机没有指定,error warn ifno等等,为什么这里工作队列模式(就是direct交换机)要指定这些,还有direct交换机为什么要绑定队列,不是这个关系应该有路由键决定的吗?

在 RabbitMQ 中,交换机(Exchange)和队列(Queue)的绑定关系和消息路由机制是消息传递的核心。不同类型的交换机(如 `direct`、`fanout`、`topic` 等)有不同的消息路由规则。让我们详细解释一下你的代码以及 `direct` 交换机的工作原理。

### 代码解析

首先,让我们修正并解释你的代码:

```java
import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

public class DirectExchangeExample {
    public static void main(String[] argv) throws Exception {
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("localhost");
        try (Connection connection = factory.newConnection();
             Channel channel = connection.createChannel()) {

            String exchangeName = "test_direct";

            // 创建交换机
            channel.exchangeDeclare(exchangeName, BuiltinExchangeType.DIRECT, true, false, false, null);

            // 创建队列
            String queue1Name = "test_direct_queue1";
            String queue2Name = "test_direct_queue2";

            channel.queueDeclare(queue1Name, true, false, false, null);
            channel.queueDeclare(queue2Name, true, false, false, null);

            // 队列绑定交换机
            // 队列1绑定"error"
            channel.queueBind(queue1Name, exchangeName, "error");

            // 队列2绑定"info", "error", "warning"
            channel.queueBind(queue2Name, exchangeName, "info");
            channel.queueBind(queue2Name, exchangeName, "error");
            channel.queueBind(queue2Name, exchangeName, "warning");

            String message = "日志信息:张三调用了delete方法,错误了,日志级别warning";

            // 发送消息
            channel.basicPublish(exchangeName, "warning", null, message.getBytes("UTF-8"));
            System.out.println(" [x] Sent '" + message + "'");
        }
    }
}
```

### `direct` 交换机的工作原理


`direct` 交换机通过路由键(routing key)将消息精确地路由到绑定了相同路由键的队列中。每个绑定(binding)包含一个队列和一个路由键。消息只有在路由键匹配绑定的路由键时,才会被路由到相应的队列。

### 为什么需要绑定队列

在 `direct` 交换机中,绑定队列和路由键的关系定义了消息的路由规则。你需要明确地将队列绑定到交换机,并指定路由键,这样交换机才能根据路由键将消息路由到正确的队列。

### 示例解释

1. **创建交换机和队列**:
   - 交换机 `test_direct` 是一个 `direct` 类型的交换机。
   - 创建了两个队列 `test_direct_queue1` 和 `test_direct_queue2`。

2. **绑定队列到交换机**:
   - `test_direct_queue1` 绑定了路由键 `error`。
   - `test_direct_queue2` 绑定了路由键 `info`、`error` 和 `warning`。

3. **发送消息**:
   - 发送了一条消息,路由键为 `warning`。
   - 根据绑定关系,消息会被路由到 `test_direct_queue2`,因为它绑定了 `warning` 路由键。

### 为什么需要指定路由键

在 `direct` 交换机中,路由键是用来精确匹配的。每个绑定需要明确的路由键,这样交换机才能将消息路由到相应的队列。不同的路由键可以用于区分不同类型的消息。例如,日志系统中可以用不同的路由键来区分不同级别的日志消息(如 `info`、`warning`、`error`)。

```java
// 绑定队列到交换机
// 队列1绑定"error"
channel.queueBind(queue


==========
为什么kafka的代码的java代码好像没这么多步骤?direct交换机的绑定工作要放到生产端吗?为什么?不同的类型的交换机分别应该把绑定的代码放到那一端?


在消息队列系统中,RabbitMQ 和 Kafka 的设计哲学和使用场景有所不同,这导致了它们在配置和使用上的差异。让我们详细讨论一下这些差异以及为什么在 RabbitMQ 中需要进行绑定,并讨论不同类型的交换机绑定代码应该放在哪一端。

### RabbitMQ vs. Kafka

#### RabbitMQ
RabbitMQ 是一个基于 AMQP 协议的消息代理,它的设计更关注消息的路由和灵活的消息传递模式。RabbitMQ 提供了多种类型的交换机(如 `direct`、`fanout`、`topic` 等),每种交换机都有不同的消息路由规则。使用 RabbitMQ 时,需要显式地声明交换机、队列,并将它们绑定在一起。

#### Kafka
Kafka 是一个分布式流处理平台,设计上更侧重于高吞吐量和持久化消息。Kafka 中没有交换机的概念,消息是按主题(topic)进行发布和订阅的。生产者将消息发送到主题,消费者从主题中读取消息。Kafka 的配置相对简单,因为它的设计更倾向于日志式存储和流处理。

### 交换机绑定在 RabbitMQ 中的重要性

在 RabbitMQ 中,交换机和队列的绑定定义了消息的路由规则。不同类型的交换机有不同的绑定和路由逻辑:

- **Direct Exchange**: 消息通过完全匹配的路由键发送到绑定的队列。
- **Fanout Exchange**: 消息广播到所有绑定的队列,忽略路由键。
- **Topic Exchange**: 消息通过模式匹配的路由键发送到绑定的队列。
- **Headers Exchange**: 通过匹配消息头属性来路由消息。

### 绑定代码应该放在哪一端

绑定代码可以放在生产端或消费端,具体取决于你的应用场景和架构设计。以下是一些建议:

#### Direct Exchange
对于 `direct` 交换机,绑定代码通常放在消费端,因为消费端知道需要接收哪些类型的消息。例如,日志系统中的不同服务可能会订阅不同级别的日志消息(如 `info`、`error`、`warning`)。

```java
// 消费端绑定代码示例
channel.queueBind(queue1Name, exchangeName, "error");
channel.queueBind(queue2Name, exchangeName, "info");
channel.queueBind(queue2Name, exchangeName, "warning");
```

#### Fanout Exchange
对于 `fanout` 交换机,绑定代码也通常放在消费端,因为所有绑定的队列都会接收到消息,不需要路由键。

```java
// 消费端绑定代码示例
channel.queueBind(queue1Name, exchangeName, "");
channel.queueBind(queue2Name, exchangeName, "");
```

#### Topic Exchange
对于 `topic` 交换机,绑定代码通常放在消费端,因为消费端知道需要接收哪种模式的消息。例如,某个服务可能会订阅 `*.error` 或 `app.*` 这样的模式。

```java
// 消费端绑定代码示例
channel.queueBind(queue1Name, exchangeName, "*.error");
channel.queueBind(queue2Name, exchangeName, "app.*");
```

#### Headers Exchange
对于 `headers` 交换机,绑定代码通常放在消费端,因为消费端知道需要匹配哪些消息头。

```java
// 消费端绑定代码示例
Map<String, Object> headers = new HashMap<>();
headers.put("format", "pdf");
headers.put("type", "report");
channel.queueBind(queue1Name, exchangeName, "", headers);
```

### 为什么 Kafka 的代码步骤较少?

Kafka 的设计简洁且高效,因为它没有交换机和队列的概念,消息是直接发布到主题的。生产者和消费者只需要知道主题名称即可,不需要显式地进行绑定。Kafka 的这种设计减少了配置步骤,但也意味着它在消息路由和灵活性上不如 RabbitMQ 强大。

### 总结

- 在 RabbitMQ 中,绑定交换机和队列是必要的,因为这定义了消息的路由规则。
- 绑定代码通常放在消费端,因为消费端更清楚需要接收哪些类型的消息。
- 不同类型的交换机有不同的绑定逻辑,具体绑定代码应根据交换机类型和应用需求来放置。
- Kafka 的设计更简洁,减少了配置步骤,但也减少了路由灵活性。

希望这些解释能帮助你更好地理解 RabbitMQ 和 Kafka 的差异以及如何配置它们的绑定关系。

===========
direct的放到消费端,那如果有多个消费者呢?一个消费info,一个消费warn,那不是这些绑定交换机 队列和路由键的代码     分散到各处,如果写掉了一个、消息还会丢失吗?最佳实践是什么


你提到的场景确实是一个需要仔细考虑的问题。在 RabbitMQ 中,如果有多个消费者,每个消费者关注不同的路由键,那么绑定代码分散在各个消费者中是常见的做法。然而,这也带来了一些潜在的问题,比如代码重复、配置不一致等。

### 消息丢失问题

如果某个消费者的绑定代码遗漏了某个路由键,那么发送到该路由键的消息确实可能会找不到相应的队列,从而导致消息丢失。为了避免这种情况,以下是一些最佳实践:

### 最佳实践

1. **集中管理绑定配置**:
   - 将所有的绑定配置集中管理,例如在一个配置文件或集中管理的服务中。这样可以确保所有的绑定关系都在一个地方定义和维护,减少遗漏的风险。
   - 可以使用配置管理工具(如 Spring Boot 配置文件)来集中管理这些绑定关系。

2. **启动时自动绑定**:
   - 在应用启动时,自动执行绑定操作。这样可以确保每次启动时都会重新绑定,防止手动配置遗漏。
   - 例如,在 Spring Boot 应用中,可以使用 `@Bean` 注解来定义绑定关系。

3. **配置自动化脚本**:
   - 使用自动化脚本或工具来管理和执行绑定操作。例如,可以编写一个脚本来自动声明交换机、队列,并执行绑定操作。
   - 这种方法适用于需要频繁变更绑定关系的场景。

4. **监控和告警**:
   - 实时监控 RabbitMQ 的队列和交换机状态,确保所有绑定关系都正常工作。
   - 配置告警机制,如果发现某个队列没有绑定到交换机,或者消息积压严重,及时发送告警。

### 示例代码

以下是一个简单的示例,展示如何在 Spring Boot 中集中管理和自动绑定:

#### application.yml

```yaml
rabbitmq:
  exchanges:
    direct: test_direct
  queues:
    - name: test_direct_queue1
      bindings:
        - routingKey: error
    - name: test_direct_queue2
      bindings:
        - routingKey: info
        - routingKey: error
        - routingKey: warning
```

#### RabbitMQConfig.java

```java
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.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RabbitMQConfig {

    @Bean
    public DirectExchange directExchange() {
        return new DirectExchange("test_direct", true, false);
    }

    @Bean
    public Queue queue1() {
        return new Queue("test_direct_queue1", true);
    }

    @Bean
    public Queue queue2() {
        return new Queue("test_direct_queue2", true);
    }

    @Bean
    public Binding binding1(Queue queue1, DirectExchange directExchange) {
        return BindingBuilder.bind(queue1).to(directExchange).with("error");
    }

    @Bean
    public Binding binding2(Queue queue2, DirectExchange directExchange) {
        return BindingBuilder.bind(queue2).to(directExchange).with("info");
    }

    @Bean
    public Binding binding3(Queue queue2, DirectExchange directExchange) {
        return BindingBuilder.bind(queue2).to(directExchange).with("error");
    }

    @Bean
    public Binding binding4(Queue queue2, DirectExchange directExchange) {
        return BindingBuilder.bind(queue2).to(directExchange).with("warning");
    }
}
```

#### 消费者代码

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

@Component
public class RabbitMQConsumer {

    @RabbitListener(queues = "test_direct_queue1")
    public void handleErrorMessages(String message) {
        System.out.println("Received error message: " + message);
    }

    @RabbitListener(queues = "test_direct_queue2")
    public void handleInfoMessages(String message) {
        System.out.println("Received info/warning message: " + message);
    }
}
```

### 总结

- **集中管理**:将绑定关系集中管理,避免分散在各个消费者中。
- **自动绑定**:在应用启动时自动执行绑定操作,确保配置一致。
- **自动化脚本**:使用自动化脚本管理和执行绑定操作,适用于频繁变更的场景。
- **监控和告警**:实时监控 RabbitMQ 状态,配置告警机制,防止遗漏。

通过这些最佳实践,可以有效降低消息丢失的风险,并确保系统的健壮性和可维护性。

=====topic类型交换机里面#和*怎么用的?通配符怎么使用?

在 RabbitMQ 中,`topic` 类型的交换机允许使用通配符来实现更复杂和灵活的消息路由。通配符主要有两个:`*` 和 `#`。

### 通配符的使用

- `*` (星号) 匹配一个单词。
- `#` (井号) 匹配零个或多个单词。

#### 示例解释

假设我们有一个 `topic` 交换机,路由键(routing key)使用点号(.)分隔单词。以下是一些示例:

1. **使用 `*` 通配符**:
   - 路由键:`log.*.error`
   - 绑定队列:`queue1`
   - 这个绑定会匹配以下路由键:
     - `log.user.error`
     - `log.system.error`
   - 不匹配以下路由键:
     - `log.error`
     - `log.user.system.error`

2. **使用 `#` 通配符**:
   - 路由键:`log.#`
   - 绑定队列:`queue2`
   - 这个绑定会匹配以下路由键:
     - `log.user.error`
     - `log.system.info`
     - `log.user.system.error`
     - `log.error`
   - 匹配所有以 `log.` 开头的路由键。

3. **组合使用**:
   - 路由键:`*.orange.*`
   - 绑定队列:`queue3`
   - 这个绑定会匹配以下路由键:
     - `quick.orange.rabbit`
     - `lazy.orange.fox`
   - 不匹配以下路由键:
     - `quick.orange`
     - `quick.brown.fox`
     - `lazy.orange.male.rabbit`

### 示例代码

以下是一个完整的示例,展示如何使用 `topic` 交换机和通配符进行消息路由。

#### RabbitMQConfig.java

```java
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RabbitMQConfig {

    @Bean
    public TopicExchange topicExchange() {
        return new TopicExchange("topic_logs", true, false);
    }

    @Bean
    public Queue queue1() {
        return new Queue("queue1", true);
    }

    @Bean
    public Queue queue2() {
        return new Queue("queue2", true);
    }

    @Bean
    public Queue queue3() {
        return new Queue("queue3", true);
    }

    @Bean
    public Binding binding1(Queue queue1, TopicExchange topicExchange) {
        return BindingBuilder.bind(queue1).to(topicExchange).with("log.*.error");
    }

    @Bean
    public Binding binding2(Queue queue2, TopicExchange topicExchange) {
        return BindingBuilder.bind(queue2).to(topicExchange).with("log.#");
    }

    @Bean
    public Binding binding3(Queue queue3, TopicExchange topicExchange) {
        return BindingBuilder.bind(queue3).to(topicExchange).with("*.orange.*");
    }
}
```

#### 消费者代码

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

@Component
public class RabbitMQConsumer {

    @RabbitListener(queues = "queue1")
    public void handleQueue1Messages(String message) {
        System.out.println("Queue1 received: " + message);
    }

    @RabbitListener(queues = "queue2")
    public void handleQueue2Messages(String message) {
        System.out.println("Queue2 received: " + message);
    }

    @RabbitListener(queues = "queue3")
    public void handleQueue3Messages(String message) {
        System.out.println("Queue3 received: " + message);
    }
}
```

#### 生产者代码

```java
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/send")
public class RabbitMQProducer {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @GetMapping("/log/error")
    public String sendErrorLog() {
        String message = "This is an error log";
        rabbitTemplate.convertAndSend("topic_logs", "log.user.error", message);
        return "Sent: " + message;
    }

    @GetMapping("/log/info")
    public String sendInfoLog() {
        String message = "This is an info log";
        rabbitTemplate.convertAndSend("topic_logs", "log.system.info", message);
        return "Sent: " + message;
    }

    @GetMapping("/log/orange")
    public String sendOrangeLog() {
        String message = "This is an orange log";
        rabbitTemplate.convertAndSend("topic_logs", "quick.orange.rabbit", message);
        return "Sent: " + message;
    }
}
```

### 总结

- **`*` 通配符**:匹配一个单词。
- **`#` 通配符**:匹配零个或多个单词。
- 通过使用通配符,可以实现灵活的消息路由,满足不同的业务需求。
- 绑定配置可以集中管理,确保配置一致,减少维护成本。

希望这些示例和解释能帮助你更好地理解和使用 `topic` 交换机及其通配符。

相关文章:

尚硅谷rabbitmq2024 工作模式路由篇 第11节 答疑

String exchangeName "test_direct"; /! 创建交换机 人图全 channel.exchangeDeclare(exchangeName,BuiltinExchangeType.DIREcT, b: true, b1: false, b2: false, map: null); /1 创建队列 String queue1Name "test_direct_queue1"; String queue2Name &q…...

HTTP vs WebSocket

本文将对比介绍HTTP 和 WebSocket &#xff01; 相关文章&#xff1a; 1.HTTP 详解 2.WebSocket 详解 一、HTTP&#xff1a;请求/响应的主流协议 HTTP&#xff08;超文本传输协议&#xff09;是用于发送和接收网页数据的标准协议。它最早于1991年由Tim Berners-Lee提出来&…...

R语言医学数据分析实践-数据读写

【图书推荐】《R语言医学数据分析实践》-CSDN博客 《R语言医学数据分析实践 李丹 宋立桓 蔡伟祺 清华大学出版社9787302673484》【摘要 书评 试读】- 京东图书 (jd.com) R语言编程_夏天又到了的博客-CSDN博客 R编程环境的搭建-CSDN博客 在分析公共卫生数据时&#xff0c;数…...

JavaWeb环境下Spring Boot在线考试系统的优化策略

摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了基于JavaWeb技术的在线考试系统设计与实现的开发全过程。通过分析基于Java Web技术的在线考试系统设计与实现管理的不足&#xff0c;创建了一个计算机管理基于Ja…...

ETL技术在金蝶云星空与旺店通WMS集成中的应用

金蝶云星空数据集成到旺店通WMS的技术案例分享 在数字化转型的背景下&#xff0c;现代企业对系统间的数据集成需求日益增加。本篇文章将以“组装入库>其他入库单-1”方案为例&#xff0c;详细解析如何通过轻易云数据集成平台&#xff0c;实现金蝶云星空与旺店通WMS之间的数…...

【力扣热题100】3194. 最小元素和最大元素的最小平均值【Java】

题目&#xff1a;3194.最小元素和最大元素的最小平均值 你有一个初始为空的浮点数数组 averages。另给你一个包含 n 个整数的数组 nums&#xff0c;其中 n 为偶数。 你需要重复以下步骤 n / 2 次&#xff1a; 从 nums 中移除 最小 的元素 minElement 和 最大 的元素 maxElement…...

机器学习拟合过程

import numpy as np import matplotlib.pyplot as plt# 步骤1: 生成模拟数据 np.random.seed(0) X 2 * np.random.rand(100, 1) y 4 3 * X 2 * X**2 np.random.randn(100, 1)# 步骤2: 定义线性模型 (我们从随机权重开始) w np.random.randn(2, 1) b np.random.randn(1)#…...

如何快速部署一套智能化openGauss测试环境

一、openGauss介绍 openGauss是一款开源关系型数据库管理系统&#xff0c;采用木兰宽松许可证v2发行&#xff0c;允许用户自由地复制、使用、修改和分发软件。openGauss内核深度融合了华为在数据库领域多年的研发经验&#xff0c;结合企业级场景需求&#xff0c;持续构建竞争力…...

【设计模式】深入理解Python中的原型设计模式

深入理解Python中的原型设计模式 在软件开发中&#xff0c;有时需要创建对象的过程非常复杂或者代价较高&#xff0c;而在同一类对象的实例之间有很多重复的属性。为了避免重复构造对象&#xff0c;提升性能和效率&#xff0c;原型设计模式&#xff08;Prototype Pattern&…...

Django CORS配置方案

参考 https://pypi.org/project/django-cors-headers/ 在setting.py中设置 INSTALLED_APPS [......corsheaders, #添加此行 ]MIDDLEWARE[......corsheaders.middleware.CorsMiddleware, #添加此行django.middleware.common.CommonMiddleware,#django.middleware.csrf.CsrfVi…...

2024年开放式耳机哪个牌子好?推荐最好的顶级开放式耳机品牌

在当下&#xff0c;开放式耳机逐渐成为众多消费者的新宠。与传统入耳式耳机相比&#xff0c;开放式耳机展现出诸多独特之处。它可以呈现出更清晰的音质效果&#xff0c;让用户有更美妙的听觉体验。在佩戴感上&#xff0c;开放式耳机更为舒适&#xff0c;不会给耳朵带来压迫感。…...

零基础读懂Stable Diffusion!

前言 一文搞懂Stable Diffusion是什么&#xff0c;怎么训练和使用&#xff0c;语义信息影响生成图片的过程。>>[][加入极市CV技术交流群&#xff0c;走在计算机视觉的最前沿] 前几个月AIGC可谓是大热了一把&#xff0c;各种高质量的生成图片层出不穷&#xff0c;而其中…...

Hash Join 和 Index Join工作原理和性能差异

在数据库查询中&#xff0c;Hash Join 和 Index Join 是两种常见的表连接策略。了解它们的工作原理和性能差异有助于设计高效的数据库查询。我们可以使用 Java 模拟这两种不同的连接方式&#xff0c;并进行性能对比。 1. Hash Join 和 Index Join 的概念&#xff1a; Hash Joi…...

Apifox简介及使用

Apifox 是一款集 API文档管理、接口调试、接口自动化测试 和 Mock 功能于一体的全功能工具&#xff0c;旨在为开发者和测试人员提供一个高效的一站式解决方案。它融合了 Postman、Swagger、JMeter 等工具的优势&#xff0c;能够极大地提升团队协作和 API 开发的效率。 在实际开…...

十、IPD 实施细节(产品设计与开发管理)

产品设计与开发管理 产品设计与开发管理是IPD(集成产品开发)实施过程中的核心环节。它确保从概念设计到最终产品的实现能够按照预定的质量、成本、进度目标顺利完成,并与市场需求、技术发展及企业战略保持一致。IPD强调产品设计与开发管理过程中跨职能团队的协作、流程的系…...

MySQL-13.DQL-聚合函数

一.DQL-分组查询 二.聚合函数 -- DQL:分组查询 -- 聚合函数 -- 1.统计该企业员工数量 count select count(id) from tb_emp; select count(job) from tb_emp;select count(A) from tb_emp; select count(*) from tb_emp;-- 2.统计该企业最早入职的员工 min select min(entr…...

为什么跟别人学习如何证明定理要远比使用定理更有意义

目录 背景 为什么跟别人学习 什么是高人&#xff0c;如何判断 高人定义 如何判断一个人的能力&#xff1f; 如何考量一个人的成就&#xff1f; 只知道使用定理的局限性 1. 缺乏灵活性和适应性 2. 无法创新或拓展新方法 3. 容易误用或误解定理 4. 难以推理和分析复杂问…...

Qt在Win,Mac和Linux的开机自启设置

Windows Windows 使用注册表来管理开机自启的应用程序。 void runWithSystem(const QString& name, const QString& path, bool autoRun) {QSetting reg("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", QSetting::NativeForma…...

spring boot热部署

使用热部署解决了每次都需要重新启动的问题&#xff0c;但不过热部署的在对于改动比较小时速度可能快一些&#xff0c;改动大的话尽量停止 1.使用热部署之前需要在pom.xml文件中导入依赖 <dependency><groupId>org.springframework.boot</groupId><artifa…...

网关与蓝牙网关有什么不同之处?

尽管蓝牙网关也属于网关的一种&#xff0c;但在实际应用和功能特性上&#xff0c;它们之间存在着显著的差异。接下来&#xff0c;我们将深入探讨蓝牙网关的独特之处&#xff0c;并与传统网关进行对比分析。 一、网关与蓝牙网关的共同之处 一对多配对能力&#xff1a;无论是网关…...

Qt Http Server模块功能及架构

Qt Http Server 是 Qt 6.0 中引入的一个新模块&#xff0c;它提供了一个轻量级的 HTTP 服务器实现&#xff0c;主要用于构建基于 HTTP 的应用程序和服务。 功能介绍&#xff1a; 主要功能 HTTP服务器功能&#xff1a; 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...

【Linux系统】Linux环境变量:系统配置的隐形指挥官

。# Linux系列 文章目录 前言一、环境变量的概念二、常见的环境变量三、环境变量特点及其相关指令3.1 环境变量的全局性3.2、环境变量的生命周期 四、环境变量的组织方式五、C语言对环境变量的操作5.1 设置环境变量&#xff1a;setenv5.2 删除环境变量:unsetenv5.3 遍历所有环境…...

GraphQL 实战篇:Apollo Client 配置与缓存

GraphQL 实战篇&#xff1a;Apollo Client 配置与缓存 上一篇&#xff1a;GraphQL 入门篇&#xff1a;基础查询语法 依旧和上一篇的笔记一样&#xff0c;主实操&#xff0c;没啥过多的细节讲解&#xff0c;代码具体在&#xff1a; https://github.com/GoldenaArcher/graphql…...

DiscuzX3.5发帖json api

参考文章&#xff1a;PHP实现独立Discuz站外发帖(直连操作数据库)_discuz 发帖api-CSDN博客 简单改造了一下&#xff0c;适配我自己的需求 有一个站点存在多个采集站&#xff0c;我想通过主站拿标题&#xff0c;采集站拿内容 使用到的sql如下 CREATE TABLE pre_forum_post_…...

机器学习的数学基础:线性模型

线性模型 线性模型的基本形式为&#xff1a; f ( x ) ω T x b f\left(\boldsymbol{x}\right)\boldsymbol{\omega}^\text{T}\boldsymbol{x}b f(x)ωTxb 回归问题 利用最小二乘法&#xff0c;得到 ω \boldsymbol{\omega} ω和 b b b的参数估计$ \boldsymbol{\hat{\omega}}…...

数据库——redis

一、Redis 介绍 1. 概述 Redis&#xff08;Remote Dictionary Server&#xff09;是一个开源的、高性能的内存键值数据库系统&#xff0c;具有以下核心特点&#xff1a; 内存存储架构&#xff1a;数据主要存储在内存中&#xff0c;提供微秒级的读写响应 多数据结构支持&…...

PydanticAI快速入门示例

参考链接&#xff1a;https://ai.pydantic.dev/#why-use-pydanticai 示例代码 from pydantic_ai import Agent from pydantic_ai.models.openai import OpenAIModel from pydantic_ai.providers.openai import OpenAIProvider# 配置使用阿里云通义千问模型 model OpenAIMode…...

13.10 LangGraph多轮对话系统实战:Ollama私有部署+情感识别优化全解析

LangGraph多轮对话系统实战:Ollama私有部署+情感识别优化全解析 LanguageMentor 对话式训练系统架构与实现 关键词:多轮对话系统设计、场景化提示工程、情感识别优化、LangGraph 状态管理、Ollama 私有化部署 1. 对话训练系统技术架构 采用四层架构实现高扩展性的对话训练…...

用 FFmpeg 实现 RTMP 推流直播

RTMP&#xff08;Real-Time Messaging Protocol&#xff09; 是直播行业中常用的传输协议。 一般来说&#xff0c;直播服务商会给你&#xff1a; ✅ 一个 RTMP 推流地址&#xff08;你推视频上去&#xff09; ✅ 一个 HLS 或 FLV 拉流地址&#xff08;观众观看用&#xff09;…...

Linux【5】-----编译和烧写Linux系统镜像(RK3568)

参考&#xff1a;讯为 1、文件系统 不同的文件系统组成了&#xff1a;debian、ubuntu、buildroot、qt等系统 每个文件系统的uboot和kernel是一样的 2、源码目录介绍 目录 3、正式编译 编译脚本build.sh 帮助内容如下&#xff1a; Available options: uboot …...