MQ,RabbitMQ,MQ的好处,RabbitMQ的原理和核心组件,工作模式

news2025/3/25 23:51:28

1.MQ

 MQ全称 Message Queue(消息队列),是在消息的传输过程中  保存消息的容器。它是应用程序和应用程序之间的通信方法

1.1 为什么使用MQ

在项目中,可将一些无需即时返回且耗时的操作提取出来,进行异步处理,而这种异步处理的方式大大的节省了服务器的请求响应时间,从而提高系统吞吐量

1.2MQ的好处

1.应用解耦   系统间通过消息通信,不用关心其他系统的处理。

2.异步提速  相比于传统的串行、并行方式,提高了系统吞吐量。

3.削峰填谷   可以通过消息队列长度控制请求量;可以缓解短时间内的高并发请求。

简单来说: 就是在访问量剧增的情况下,但是应用仍然不能停,比如“双十一”下单的人多,但是淘宝这个应用仍然要运行,所以就可以使用消息中间件采用队列的形式减少突然访问的压力

使用MQ后,可以提高系统稳定性

1.3劣势

  1. 系统可用性降低 系统引入的外部依赖越多,系统稳定性越差。一旦 MQ 宕机,就会对业务造成影响。如何保证MQ的高可用?

  2. 系统复杂度提高 MQ 的加入大大增加了系统的复杂度,以前系统间是同步的远程调用,现在是通过 MQ 进行异步调用。如何保证消息没有被重复消费?怎么处理消息丢失情况?那么保证消息传递的顺序性?

  3. 一致性问题 A 系统处理完业务,通过 MQ 给B、C、D三个系统发消息数据,如果 B 系统、C 系统处理成功,D 系统处理失败。如何保证消息数据处理的一致性?

1.4常见的MQ组件

RabbitMQ、RocketMQ、ActiveMQ、Kafka、ZeroMQ、MetaMq等

2.RabbitMQ

RabbitMQ是一个由erlang开发的AMQP(Advanced Message Queue 高级消息队列协议 )的开源实现,由于erlang 语言的高并发特性,性能较好,本质是个队列,FIFO 先入先出,里面存放的内容是message

RabbitMQ是一个消息中间件:它接受并转发消息。你可以把它当做一个快递站点,当你要发送一个包裹时,你把你的包裹放到快递站,快递员最终会把你的快递送到收件人那里,按照这种逻辑RabbitMQ是一个快递站,一个快递员帮你传递快件。RabbitMQ与快递站的主要区别在于,它不处理快件而是接收,存储和转发消息数据。

2.1RabbitMQ的原理

核心组件

  1. 生产者(Producer):负责发送消息到交换器的客户端应用程序。

  2. 消费者(Consumer):从队列中获取并处理消息的客户端应用程序。

  3. 交换器(Exchange):接收生产者发送的消息,并根据路由规则将消息转发到相应的队列。

  4. 队列(Queue):存储消息,直到消费者取走消息。

  5. 绑定(Binding):定义交换器和队列之间的关联关系。

工作流程

  1. 消息发送:生产者通过信道(Channel)将消息发送到交换器。

  2. 消息路由:交换器根据路由键(Routing Key)和绑定键(Binding Key)将消息路由到相应的队列。

  3. 消息存储:队列存储消息,等待消费者取走。

  4. 消息消费:消费者通过信道从队列中获取消息并处理。

交换器类型

  1. Direct:根据完全匹配的路由键将消息发送到相应的队列。

  2. Fanout:将消息广播到所有绑定的队列,不考虑路由键。

  3. Topic:根据模式匹配的路由键将消息发送到相应的队列。

2.2简单模式simple

生产者向队列投递消息,消费者从其中取出消息

1.依赖

<!--        java连接rabbitmq的依赖-->
        <dependency>
            <groupId>com.rabbitmq</groupId>
            <artifactId>amqp-client</artifactId>
            <version>5.16.0</version>
        </dependency>

2.生产消息

package com.ghx.hello;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * @author :guo
 * @date :Created in 2025/3/20 11:35
 * @description:
 * @version:
 */
public class Test01 {
    public static void main(String[] args) throws IOException, TimeoutException {
        //创建连接工厂
        ConnectionFactory factory=new ConnectionFactory();
        //rabbitmq服务器地址 默认本地localhost
        factory.setHost("xxxx");
        //端口号 默认5672
        factory.setPort(5672);
        //用户名 密码  默认guest
        factory.setUsername("guest");
        factory.setPassword("guest");
        factory.setVirtualHost("/");

        //创建连接对象
        Connection connection=factory.newConnection();
        //获取channel对象
        Channel channel = connection.createChannel();
        //创建队列 存在则不创建,不存在则创建
        //String queue, 队列名
        // boolean durable, 是否持久化
        // boolean exclusive, 是否独占队列 false
        // boolean autoDelete,是否自动删除 false
        // Map<String, Object> arguments 队列的参数配置--消息的格式 消息存放的时间等
        channel.queueDeclare("hello",true,false,false,null);
        String msg="hello rabbitmq2";
        //String exchange,交换机的名称 "":默认交换机
        // String routingKey, 路由key "hello":队列名
        // BasicProperties props, 消息的属性--设置过期时间 设置id等 null
        // byte[] body  消息的内容
        channel.basicPublish("","hello",null,msg.getBytes());
        System.out.println("消息发送成功");
        channel.close();
        connection.close();


    }
}

3.消费消息

package com.ghx.hello;

import com.rabbitmq.client.*;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * @author :guo
 * @date :Created in 2025/3/20 14:22
 * @description:
 * @version:
 */
public class Test01 {
    public static void main(String[] args) throws IOException, TimeoutException {
        //创建连接工厂
        ConnectionFactory factory=new ConnectionFactory();
        //rabbitmq服务器地址 默认本地localhost
        factory.setHost("xxxx");
        //端口号 默认5672
        factory.setPort(5672);
        //用户名 密码  默认guest
        factory.setUsername("guest");
        factory.setPassword("guest");
        //虚拟机名称 默认/
        factory.setVirtualHost("/");
        //创建连接对象
        Connection connection = factory.newConnection();
        //获取channel对象
        Channel channel = connection.createChannel();
        DefaultConsumer consumer=new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println("消费者1收到消息"+new String(body));
            }
        };
        //接受消息
        channel.basicConsume("hello",true,consumer);
        //不要关闭连接和channel  监听消息

    }
}

2.3工作者模式work queues

多个消费者消费同一个队列中的消息,多个消费者之间属于竞争关系,一个消息只能被一个消费者消费,适合对于任务过重或任务较多的情况,使用工作队列可以提高任务的处理速度

1.生产者

package com.ghx.work;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.MessageProperties;

/**
 * @author :guo
 * @date :Created in 2025/3/20 14:51
 * @description:
 * @version:
 */
public class Test03 {
    private static final String QUEUE_NAME="queue01";
    public static void main(String[] args) {
        ConnectionFactory factory=new ConnectionFactory();
        factory.setHost("xxxx");
        factory.setPort(5672);
        factory.setUsername("guest");
        factory.setPassword("guest");
        factory.setVirtualHost("/");
        try {
            Connection connection = factory.newConnection();
            Channel channel = connection.createChannel();
            channel.queueDeclare(QUEUE_NAME,true,false,false,null);
            for (int i = 0; i < 10; i++){
                String msg="你好  世界"+i;
                channel.basicPublish("",QUEUE_NAME, MessageProperties.PERSISTENT_TEXT_PLAIN,msg.getBytes("utf-8"));
            }
            channel.close();
            connection.close();
        }catch (Exception e){

        }

    }
}

2.  2个消费者

package com.ghx.work;

import com.rabbitmq.client.*;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * @author :guo
 * @date :Created in 2025/3/20 15:00
 * @description:
 * @version:
 */
public class Test03 {
    private static final String QUEUE_NAME="queue01";
    public static void main(String[] args) throws IOException, TimeoutException {
        ConnectionFactory factory=new ConnectionFactory();
        factory.setHost("xxxX");
        factory.setPort(5672);
        factory.setUsername("guest");
        factory.setPassword("guest");
        factory.setVirtualHost("/");
        Connection connection = factory.newConnection();
        Channel channel = connection.createChannel();
        channel.queueDeclare(QUEUE_NAME,true,false,false,null);
        channel.basicQos(1);
        Consumer consumer = new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println("消费者1收到消息"+new String(body));
            }
        };
        //接收消息
        channel.basicConsume(QUEUE_NAME,true,consumer);
    }


}
package com.ghx.work;

import com.rabbitmq.client.*;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * @author :guo
 * @date :Created in 2025/3/20 15:00
 * @description:
 * @version:
 */
public class Consumer02 {
    private static final String QUEUE_NAME="queue01";
    public static void main(String[] args) throws IOException, TimeoutException {
        ConnectionFactory factory=new ConnectionFactory();
        factory.setHost("xxxx");
        factory.setPort(5672);
        factory.setUsername("guest");
        factory.setPassword("guest");
        factory.setVirtualHost("/");
        Connection connection = factory.newConnection();
        Channel channel = connection.createChannel();
        channel.queueDeclare(QUEUE_NAME,true,false,false,null);
        channel.basicQos(1);
        Consumer consumer = new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println("消费者2收到消息"+new String(body));
            }
        };
        //接收消息
        channel.basicConsume(QUEUE_NAME,true,consumer);
    }


}

2.3发布订阅模式 publish/subscribe

x  : 交换机

        一方面,接收生产者发送的消息。另一方面,知道如何处理消息,例如递交给某个特别队列、递交给所有队列、或是将消息丢弃。到底如何操作,取决于Exchange的类型。Exchange有常见以下3种类型:

  1. Fanout:广播,将消息交给所有绑定到交换机的队列

  2. Direct:定向,把消息交给符合指定routing key 的队列

  3. Topic:通配符,把消息交给符合routing pattern(路由模式) 的队列

每个消费者都有自己独立的队列

2.3.1生产者

package com.ghx.work;

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

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * @author :guo
 * @date :Created in 2025/3/20 11:35
 * @description:
 * @version:
 */
public class Test01 {
    public static void main(String[] args) throws IOException, TimeoutException {
        //创建连接工厂
        ConnectionFactory factory=new ConnectionFactory();
        //rabbitmq服务器地址 默认本地localhost
        factory.setHost("xxxx");
        //端口号 默认5672
        factory.setPort(5672);
        //用户名 密码  默认guest
        factory.setUsername("guest");
        factory.setPassword("guest");
        factory.setVirtualHost("/");

        //创建连接对象
        Connection connection=factory.newConnection();
        //获取channel对象
        Channel channel = connection.createChannel();

        //创建交换机
//        String exchange,交换机的名称
//        BuiltinExchangeType type, 交换机的类型
//        boolean durable: 是否持久化
        channel.exchangeDeclare("fanout_exchange", BuiltinExchangeType.FANOUT,true);
        //创建队列
        channel.queueDeclare("fanout_queue1",true,false,false,null);
        channel.queueDeclare("fanout_queue2",true,false,false,null);

        //绑定队列和交换机
//        String queue,队列名
//        String exchange,交换机名
//        String routingKey: 路由key 因为广播模式没有路由key  ""
        channel.queueBind("fanout_queue1","fanout_exchange","");
        channel.queueBind("fanout_queue2","fanout_exchange","");
        //发送消息
        String msg="hello fanout交换机";
        channel.basicPublish("fanout_exchange","",null,msg.getBytes());
        channel.close();
        connection.close();


    }
}

2.4路由模式routing

  • 队列与交换机的绑定,不能是任意绑定了,而是要指定一个 RoutingKey(路由key)

  • 消息的发送方在向 Exchange 发送消息时,也必须指定消息的 RoutingKey

  • Exchange 不再把消息交给每一个绑定的队列,而是根据消息的 Routing Key 进行判断,只有队列的Routingkey 与消息的 Routing key 完全一致,才会接收到消息

package com.ghx.router;

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

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * @author :guo
 * @date :Created in 2025/3/20 11:35
 * @description:
 * @version:
 */
public class Test01 {
    public static void main(String[] args) throws IOException, TimeoutException {
        //创建连接工厂
        ConnectionFactory factory=new ConnectionFactory();
        //rabbitmq服务器地址 默认本地localhost
        factory.setHost("xxxx");
        //端口号 默认5672
        factory.setPort(5672);
        //用户名 密码  默认guest
        factory.setUsername("guest");
        factory.setPassword("guest");
        factory.setVirtualHost("/");

        //创建连接对象
        Connection connection=factory.newConnection();
        //获取channel对象
        Channel channel = connection.createChannel();

        //创建交换机
//        String exchange,交换机的名称
//        BuiltinExchangeType type, 交换机的类型
//        boolean durable: 是否持久化
        channel.exchangeDeclare("direct_exchange", BuiltinExchangeType.DIRECT,true);
        //创建队列
        channel.queueDeclare("direct_queue1",true,false,false,null);
        channel.queueDeclare("direct_queue2",true,false,false,null);

        //绑定队列和交换机
//        String queue,队列名
//        String exchange,交换机名
//        String routingKey: 路由key 因为广播模式没有路由key  ""
        channel.queueBind("direct_queue1","direct_exchange","error");
        channel.queueBind("direct_queue2","direct_exchange","error");
        channel.queueBind("direct_queue2","direct_exchange","info");
        channel.queueBind("direct_queue2","direct_exchange","warning");
        //发送消息
        String msg="hello direct交换机";
        channel.basicPublish("direct_exchange","info",null,msg.getBytes());
        channel.close();
        connection.close();


    }
}

2.5主题模式topics

  • Topic 类型与 Direct 相比,都是可以根据 RoutingKey 把消息路由到不同的队列。只不过 Topic 类型Exchange 可以让队列在绑定 Routing key 的时候使用==通配符==!

  • Routingkey 一般都是有一个或多个单词组成,多个单词之间以”.”分割,例如: item.insert

  • 通配符规则:# 匹配一个或多个词,* 匹配不多不少恰好1个词,例如:item.# 能够匹配 item.insert.abc 或者 item.insert,item.* 只能匹配 item.insert

下面的只会发送给2

package com.ghx.topic;

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

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * @author :guo
 * @date :Created in 2025/3/20 11:35
 * @description:
 * @version:
 */
public class Test01 {
    public static void main(String[] args) throws IOException, TimeoutException {
        //创建连接工厂
        ConnectionFactory factory=new ConnectionFactory();
        //rabbitmq服务器地址 默认本地localhost
        factory.setHost("121.196.229.251");
        //端口号 默认5672
        factory.setPort(5672);
        //用户名 密码  默认guest
        factory.setUsername("guest");
        factory.setPassword("guest");
        factory.setVirtualHost("/");

        //创建连接对象
        Connection connection=factory.newConnection();
        //获取channel对象
        Channel channel = connection.createChannel();

        //创建交换机
//        String exchange,交换机的名称
//        BuiltinExchangeType type, 交换机的类型
//        boolean durable: 是否持久化
        channel.exchangeDeclare("topic_exchange", BuiltinExchangeType.TOPIC,true);
        //创建队列
        channel.queueDeclare("topic_queue1",true,false,false,null);
        channel.queueDeclare("topic_queue2",true,false,false,null);

        //绑定队列和交换机
//        String queue,队列名
//        String exchange,交换机名
//        String routingKey: 路由key 因为广播模式没有路由key  ""
        channel.queueBind("topic_queue1","topic_exchange","*.orange.*");
        channel.queueBind("topic_queue2","topic_exchange","*.*.rabbit");
        channel.queueBind("topic_queue2","topic_exchange","lazy.#");
        //发送消息
        String msg="hello topic交换机";
        channel.basicPublish("topic_exchange","lazy.orange",null,msg.getBytes());
        channel.close();
        connection.close();


    }
}

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

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

相关文章

ETL:数据清洗、规范化和聚合的重要性

在当今这个数据呈爆炸式增长的时代&#xff0c;数据已成为企业最为宝贵的资产之一。然而&#xff0c;数据的海量增长也伴随着诸多问题&#xff0c;如数据来源多样、结构复杂以及质量问题等&#xff0c;这些问题严重阻碍了数据的有效处理与深度分析。在此背景下&#xff0c;ETL&…

电机控制常见面试问题(十八)

文章目录 一.电机控制高级拓扑结构1.LLC 二.谈谈电压器饱和后果三.电压器绕组连接方式的影响四.有源逆变的条件 一.电机控制高级拓扑结构 1.LLC LLC是什么&#xff1f;—— 一个会"变魔术"的电源盒子 想象你有一个魔法盒子&#xff0c;能把电池的电压变大或变小&…

stable diffusion本地安装

1. 基本环境准备 安装conda 环境 pytorch基础学习-CSDN博客 创建虚拟环境&#xff1a; conda create -n sd python3.10 一定要指定用3.10&#xff0c;过高的版本会提示错误&#xff1a; 激活启用环境&#xff1a; conda activate sd 设置pip国内镜像源&#xff1a; pip conf…

【内网穿透】Linux部署FRP0.61.2实现rk3566 Wechat iPad协议内网穿透教程

写在前面 FRP&#xff08;Fast Reverse Proxy&#xff09;是一个由Go语言编写的开源项目&#xff0c;用于内网穿透&#xff0c;即通过公网服务器将内网服务暴露给外部访问。这对于需要在内网环境中部署但又希望外部用户能够访问这些服务的场景非常有用 Github&#xff1a;htt…

VM虚拟机安装Ubuntu系统

前言 我现在装的Ubuntu总是死机&#xff0c;经常黑屏&#xff0c;所以我决定换个版本&#xff0c;顺便写一下笔记&#xff0c;给大家分享如何安装虚拟机 下载 这里我选择的是Ubuntu 22.04.5 LTS&#xff0c;下载链接&#xff1a;Ubuntu 22.04.5 LTS 如果访问不了网站的话&…

从JVM底层揭开Java方法重载与重写的面纱:原理、区别与高频面试题突破

&#x1f31f;引言&#xff1a;一场由方法调用引发的"血案" 2018年&#xff0c;某电商平台在"双十一"大促期间遭遇严重系统故障。 技术团队排查发现&#xff0c;问题根源竟是一个继承体系中的方法重写未被正确处理&#xff0c;导致订单金额计算出现指数级…

芋道 Spring Cloud Alibaba 消息队列 RocketMQ 入门

1. 概述 RocketMQ 是一款开源的分布式消息系统&#xff0c;基于高可用分布式集群技术&#xff0c;提供低延时的、高可靠的消息发布与订阅服务。同时&#xff0c;广泛应用于多个领域&#xff0c;包括异步通信解耦、企业解决方案、金融支付、电信、电子商务、快递物流、广告营销…

html css js网页制作成品——HTML+CSS+js迪奥口红网站网页设计(4页)附源码

目录 一、&#x1f468;‍&#x1f393;网站题目 二、✍️网站描述 三、&#x1f4da;网站介绍 四、&#x1f310;网站效果 五、&#x1fa93; 代码实现 &#x1f9f1;HTML 六、&#x1f947; 如何让学习不再盲目 七、&#x1f381;更多干货 一、&#x1f468;‍&#x1f…

PPT 转高精度图片 API 接口

PPT 转高精度图片 API 接口 文件处理 / 图片处理&#xff0c;将 PPT 文件转换为图片序列。 1. 产品功能 支持将 PPT 文件转换为高质量图片序列&#xff1b;支持 .ppt 和 .pptx 格式&#xff1b;保持原始 PPT 的布局和样式&#xff1b;转换后的图片支持永久访问&#xff1b;全…

python学习笔记--实现简单的爬虫(二)

任务&#xff1a;爬取B站上最爱欢迎的编程课程 网址&#xff1a;编程-哔哩哔哩_bilibili 打开网页的代码模块&#xff0c;如下图&#xff1a; 标题均位于class_"bili-video-card__info--tit"的h3标签中&#xff0c;下面通过代码来实现&#xff0c;需要说明的是URL中…

【颠覆性缓存架构】Caffeine双引擎缓存实战:CPU和内存双优化,命中率提升到92%,内存减少75%

千万级QPS验证&#xff01;Caffeine智能双缓存实现 92%命中率&#xff0c;内存减少75% 摘要&#xff1a; 本文揭秘千万级流量场景下的缓存革命性方案&#xff01;基于Caffeine打造智能双模式缓存系统&#xff0c;通过冷热数据分离存储与精准资源分配策略&#xff0c;实现CPU利…

智能汽车图像及视频处理方案,支持视频智能包装能力

美摄科技的智能汽车图像及视频处理方案&#xff0c;通过深度学习算法与先进的色彩管理技术&#xff0c;能够自动调整图像中的亮度、对比度、饱和度等关键参数&#xff0c;确保在各种光线条件下&#xff0c;图像都能呈现出最接近人眼的自然色彩与细节层次。这不仅提升了驾驶者的…

jenkins+1panel面板java运行环境自动化部署java项目

本文章不包含1panel面板安装、jenkins部署、jenkins连接git服务器等操作教程&#xff0c;如有需要可以抽空后期补上 jenkins安装插件Publish Over SSH 在系统配置添加服务器 查看项目的工作空间 项目Configure->构Post Steps选择Send files or execute commands over SSH…

C语言 【实现电脑关机小游戏】非常好玩

引言 在时间限制内做出正确的回答&#xff0c;时间一到&#xff0c;电脑自动关机&#xff0c;听起来是不是很有意思&#xff0c;下面来看看怎么实现吧。 注意&#xff1a;该游戏只在windows系统下可以玩&#xff0c; 一、游戏原理&#xff1a; 在Windows系统下&#xff0c;通…

[网络安全] 滥用Azure内置Contributor角色横向移动至Azure VM

本文来源于团队的超辉老师&#xff0c;其系统分析了Azure RBAC角色模型及其在权限滥用场景下的攻击路径。通过利用AADInternals工具提升用户至Contributor角色&#xff0c;攻击者可在Azure VM中远程执行命令&#xff0c;创建后门账户&#xff0c;实现横向移动。文中详述了攻击步…

vue3,element-plus 表格单选、多选、反选、全选

准备 定义数据 // 表格 const table ref(); // 表格数据 import type { User } from "/interface"; const tableData ref<User[]>([]); // 表格选集 const tableSelection ref<User[]>([]); // 表格选择行 const tableSelectedRow ref<User>…

【Linux】从开发到系统管理深入理解环境变量

文章目录 前言一、环境变量概念1.1 为什么需要环境变量&#xff1f;1.2 环境变量的本质特征 二、环境变量PATH2.1 PATH的运作机制2.2 常见环境变量及其作用2.3 环境变量操作指南 三、再谈环境变量3.1main函数命令行参数解析3.2 环境变量的继承机制3.3 本地变量与内部构建命令 总…

【CGE】社会核算矩阵构建(一):SAM基本结构

【CGE】社会核算矩阵构建&#xff08;一&#xff09;&#xff1a;SAM基本结构 社会核算矩阵构建&#xff08;一&#xff09;&#xff1a;SAM基本结构一、SAM的概念和基本特点二、SAM的基本结构1.开放经济体的SAM表结构2.SAM表各账户的主要核算内容&#xff08;1&#xff09;社会…

Ubuntu 系统部署 Ollama + DeepSeek + Docker + Ragflow

&#x1f339;作者主页&#xff1a;青花锁 &#x1f339;简介&#xff1a;Java领域优质创作者&#x1f3c6;、Java微服务架构公号作者&#x1f604; &#x1f339;简历模板、学习资料、面试题库、技术互助 &#x1f339;文末获取联系方式 &#x1f4dd; Mysql数据库规范 一、Ol…

第三讲 | C/C++内存管理完全手册

C/C内存管理 一、 C/C内存分布二、 C语言中动态内存管理方式&#xff1a;malloc/calloc/realloc/free三、 C内存管理方式1. new/delete操作内置类型2. new和delete操作自定义类型 四、operator new和operator delete函数&#xff08;重点&#xff09;五、new和delete的实现原理…