第十一章 SpringCloud Alibaba 实现Rocketmq–消息驱动

MQ简介

什么是MQ

MQ(Message Queue)是一种跨进程的通信机制,用于传递消息。通俗点说,就是一个先进先出的数
据结构。
在这里插入图片描述

MQ的应用场景

异步解耦

最常见的一个场景是用户注册后,需要发送注册邮件和短信通知,以告知用户注册成功。传统的做法如下:
在这里插入图片描述
此架构下注册、邮件、短信三个任务全部完成后,才返回注册结果到客户端,用户才能使用账号登录。
但是对于用户来说,注册功能实际只需要注册系统存储用户的账户信息后,该用户便可以登录,而后续的注册短信和邮件不是即时需要关注的步骤。
所以实际当数据写入注册系统后,注册系统就可以把其他的操作放入对应的消息队列 MQ 中然后马上返回用户结果,由消息队列 MQ 异步地进行这些操作。架构图如下:
在这里插入图片描述
异步解耦是消息队列 MQ 的主要特点,主要目的是减少请求响应时间和解耦。主要的使用场景就是将比较耗时而且不需要即时(同步)返回结果的操作作为消息放入消息队列。同时,由于使用了消息队列MQ,只要保证消息格式不变,消息的发送方和接收方并不需要彼此联系,也不需要受对方的影响,即解耦合。

流量削峰

流量削峰也是消息队列 MQ 的常用场景,一般在秒杀或团队抢购(高并发)活动中使用广泛。
在秒杀或团队抢购活动中,由于用户请求量较大,导致流量暴增,秒杀的应用在处理如此大量的访问流量后,下游的通知系统无法承载海量的调用量,甚至会导致系统崩溃等问题而发生漏通知的情况。为解决这些问题,可在应用和下游通知系统之间加入消息队列 MQ。
在这里插入图片描述
秒杀处理流程如下所述:

  1. 用户发起海量秒杀请求到秒杀业务处理系统。
  2. 秒杀处理系统按照秒杀处理逻辑将满足秒杀条件的请求发送至消息队列 MQ。
  3. 下游的通知系统订阅消息队列 MQ 的秒杀相关消息,再将秒杀成功的消息发送到相应用户。
  4. 用户收到秒杀成功的通知。

常见的MQ产品

目前业界有很多MQ产品,比较出名的有下面这些:

  • ZeroMQ
    号称最快的消息队列系统,尤其针对大吞吐量的需求场景。扩展性好,开发比较灵活,采用C语言
    实现,实际上只是一个socket库的重新封装,如果做为消息队列使用,需要开发大量的代码。
    ZeroMQ仅提供非持久性的队列,也就是说如果down机,数据将会丢失。

  • RabbitMQ
    使用erlang语言开发,性能较好,适合于企业级的开发。但是不利于做二次开发和维护。

  • ActiveMQ
    历史悠久的Apache开源项目。已经在很多产品中得到应用,实现了JMS1.1规范,可以和springjms轻松融合,实现了多种协议,支持持久化到数据库,对队列数较多的情况支持不好。

  • RocketMQ
    阿里巴巴的MQ中间件,由java语言开发,性能非常好,能够撑住双十一的大流量,而且使用起来
    很简单。

  • Kafka
    Kafka是Apache下的一个子项目,是一个高性能跨语言分布式Publish/Subscribe消息队列系统,
    相对于ActiveMQ是一个非常轻量级的消息系统,除了性能非常好之外,还是一个工作良好的分布
    式系统。

RocketMQ入门

RocketMQ是阿里巴巴开源的分布式消息中间件,现在是Apache的一个顶级项目。在阿里内部使用
非常广泛,已经经过了"双11"这种万亿级的消息流转。

RocketMQ环境搭建

接下来我们先在linux平台下安装一个RocketMQ的服务

环境准备

下载RocketMQ:http://rocketmq.apache.org/release_notes/release-notes-4.4.0/

安装RocketMQ

1 上传文件到Linux系统

[root@heima rocketmq]# ls /usr/local/src/
rocketmq-all-4.4.0-bin-release.zip

2 解压到安装目录

[root@heima src]# unzip rocketmq-all-4.4.0-bin-release.zip
[root@heima src]# mv rocketmq-all-4.4.0-bin-release ../rocketmq

启动RocketMQ

1切换到安装目录

[root@heima rocketmq]# ls
benchmark bin conf lib LICENSE NOTICE README.md

2 启动NameServer

[root@heima rocketmq]# nohup ./bin/mqnamesrv &
[1] 1467
# 只要进程不报错,就应该是启动成功了,可以查看一下日志
[root@heima rocketmq]# tail -f /root/logs/rocketmqlogs/namesrv.log

3 启动Broker

# 编辑bin/runbroker.sh 和 bin/runserver.sh文件,修改里面的
# JAVA_OPT="${JAVA_OPT} -server -Xms8g -Xmx8g -Xmn4g"
# 为JAVA_OPT="${JAVA_OPT} -server -Xms256m -Xmx256m -Xmn128m"
[root@heima rocketmq]# nohup bin/mqbroker -n localhost:9876 &
[root@heima rocketmq]# tail -f /root/logs/rocketmqlogs/broker.log

测试RocketMQ

1 测试消息发送

[root@heima rocketmq]# export NAMESRV_ADDR=localhost:9876
[root@heima rocketmq]# bin/tools.sh
org.apache.rocketmq.example.quickstart.Producer

2 测试消息接收

[root@heima rocketmq]# export NAMESRV_ADDR=localhost:9876
[root@heima rocketmq]# bin/tools.sh
org.apache.rocketmq.example.quickstart.Consumer

关闭RocketMQ

[root@heima rocketmq]# bin/mqshutdown broker
[root@heima rocketmq]# bin/mqshutdown namesrv

RocketMQ的架构及概念

在这里插入图片描述
如上图所示,整体可以分成4个角色,分别是:NameServer,Broker,Producer,Consumer。

  • Broker(邮递员):Broker是RocketMQ的核心,负责消息的接收,存储,投递等功能
  • NameServer(邮局):消息队列的协调者,Broker向它注册路由信息,同时Producer和Consumer向其获取路由信息
  • Producer(寄件人):消息的生产者,需要从NameServer获取Broker信息,然后与Broker建立连接,向Broker发送消息
  • Consumer(收件人):消息的消费者,需要从NameServer获取Broker信息,然后与Broker建立连接,从Broker获取消息
  • Topic(地区):用来区分不同类型的消息,发送和接收消息前都需要先创建Topic,针对Topic来发送和接收消息
  • Message Queue(邮件):为了提高性能和吞吐量,引入了Message Queue,一个Topic可以设置一个或多个MessageQueue,这样消息就可以并行往各个Message Queue发送消息,消费者也可以并行的从多个Message Queue读取消息
  • Message:Message 是消息的载体。
  • Producer Group:生产者组,简单来说就是多个发送同一类消息的生产者称之为一个生产者组。
  • Consumer Group:消费者组,消费同一类消息的多个 consumer 实例组成一个消费者组。

RocketMQ控制台安装

1 下载

# 在git上下载下面的工程 rocketmq-console-1.0.0
https://github.com/apache/rocketmq-externals/releases

2 修改配置文件

# 修改配置文件 rocketmq-console\src\main\resources\application.properties
server.port=7777 #项目启动后的端口号
rocketmq.config.namesrvAddr=192.168.109.131:9876 #nameserv的地址,注意防火墙要开启9876端口

3 打成jar包,并启动

# 进入控制台项目,将工程打成jar包
mvn clean package -Dmaven.test.skip=true
# 启动控制台
java -jar target/rocketmq-console-ng-1.0.0.jar

4 访问控制台
在这里插入图片描述

消息发送和接收演示

接下来我们使用Java代码来演示消息的发送和接收

<dependency>
	<groupId>org.apache.rocketmq</groupId>
	<artifactId>rocketmq-spring-boot-starter</artifactId>
	<version>2.0.2</version>
</dependency>

发送消息

消息发送步骤:

  1. 创建消息生产者, 指定生产者所属的组名
  2. 指定Nameserver地址
  3. 启动生产者
  4. 创建消息对象,指定主题、标签和消息体
  5. 发送消息
  6. 关闭生产者
//发送消息
public class RocketMQSendTest {

    public static void main(String[] args) throws Exception {
        //1. 创建消息生产者, 指定生产者所属的组名
        DefaultMQProducer producer = new DefaultMQProducer("myproducer-group");
        //2. 指定Nameserver地址
        producer.setNamesrvAddr("192.168.109.131:9876");
        //3. 启动生产者
        producer.start();
        //4. 创建消息对象,指定主题、标签和消息体
        Message msg = new Message("myTopic", "myTag", ("RocketMQ Message").getBytes());
        //5. 发送消息
        SendResult sendResult = producer.send(msg, 10000);
        System.out.println(sendResult);
        //6. 关闭生产者
        producer.shutdown();
    }
}

接收消息

消息接收步骤:

  1. 创建消息消费者, 指定消费者所属的组名
  2. 指定Nameserver地址
  3. 指定消费者订阅的主题和标签
  4. 设置回调函数,编写处理消息的方法
  5. 启动消息消费者
//接收消息
public class RocketMQReceiveTest {
    public static void main(String[] args) throws MQClientException {
        //1. 创建消息消费者, 指定消费者所属的组名
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("myconsumergroup");
        //2. 指定Nameserver地址
        consumer.setNamesrvAddr("192.168.109.131:9876");
        //3. 指定消费者订阅的主题和标签
        consumer.subscribe("myTopic", "*");
        //4. 设置回调函数,编写处理消息的方法
        consumer.registerMessageListener(new MessageListenerConcurrently() {
            @Override
            public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt>
                                                                    msgs,
                                                            ConsumeConcurrentlyContext
                                                                    context) {
                System.out.println("Receive New Messages: " + msgs);
                //返回消费状态
                return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
            }
        });
            //5. 启动消息消费者
        consumer.start();
        System.out.println("Consumer Started.");
    }
}

案例

接下来我们模拟一种场景: 下单成功之后,向下单用户发送短信。设计图如下:
在这里插入图片描述

订单微服务发送消息

1 在 shop-order 中添加rocketmq的依赖

<dependency>
            <groupId>org.apache.rocketmq</groupId>
            <artifactId>rocketmq-spring-boot-starter</artifactId>
            <version>2.0.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.rocketmq</groupId>
            <artifactId>rocketmq-client</artifactId>
            <version>4.4.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.rocketmq</groupId>
            <artifactId>rocketmq-spring-boot</artifactId>
            <version>2.2.0</version>
        </dependency>

2 添加配置

rocketmq:
  name-server: 127.0.0.1:9876 #rocketMQ服务的地址
  producer:
    group: shop-order # 生产者组

3 编写测试代码

@RestController
@Slf4j
public class OrderController4 {
    @Autowired
    private OrderService orderService;
    @Autowired
    private ProductService productService;
    @Autowired
    private RocketMQTemplate rocketMQTemplate;
    //准备买1件商品
    @GetMapping("/order/prod/{pid}")
    public Order order(@PathVariable("pid") Integer pid) {
        log.info(">>客户下单,这时候要调用商品微服务查询商品信息");
        //通过fegin调用商品微服务
        Product product = productService.findByPid(pid);
        if (product == null){

            Order order = new Order();
            order.setPname("下单失败");
            return order;
        }
        log.info(">>商品信息,查询结果:" + JSON.toJSONString(product));
        Order order = new Order();
        order.setUid(1);
        order.setUsername("测试用户");
        order.setPid(product.getPid());
        order.setPname(product.getPname());
        order.setPprice(product.getPprice());
        order.setNumber(1);
        orderService.save(order);
        //下单成功之后,将消息放到mq中
        rocketMQTemplate.convertAndSend("order-topic", order);
        return order;
    }
}

用户微服务订阅消息

1 修改 shop-user 模块配置

<dependency>
            <groupId>org.apache.rocketmq</groupId>
            <artifactId>rocketmq-spring-boot-starter</artifactId>
            <version>2.0.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.rocketmq</groupId>
            <artifactId>rocketmq-client</artifactId>
            <version>4.4.0</version>
        </dependency>

2 修改主类

@SpringBootApplication
@EnableDiscoveryClient
public class ShopUserApplication {
    public static void main(String[] args) {
        SpringApplication.run(ShopUserApplication.class,args);


        System.out.println("Hello world!");
    }
}

3 修改配置文件

server:
  port: 8071
spring:
  application:
    name: service-user
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/shop?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
    username: root
    password: root123
  jpa:
    properties:
     hibernate:
      hbm2ddl:
       auto: update
     dialect: org.hibernate.dialect.MySQL5InnoDBDialect
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
rocketmq:
  name-server: 192.168.109.131:9876

4 编写消息接收服务

//发送短信的服务
@Slf4j
@Service
@RocketMQMessageListener(consumerGroup = "shop-user", topic = "order-topic")
public class SmsService implements RocketMQListener<Order> {
    @Override
    public void onMessage(Order order) {
        log.info("收到一个订单信息{},接下来发送短信", JSON.toJSONString(order));
    }
}

5 启动服务,执行下单操作,观看后台输出

发送不同类型的消息

普通消息

RocketMQ提供三种方式来发送普通消息:可靠同步发送、可靠异步发送和单向发送
可靠同步发送

同步发送是指消息发送方发出数据后,会在收到接收方发回响应之后才发下一个数据包的通讯方
式。
此种方式应用场景非常广泛,例如重要通知邮件、报名短信通知、营销短信系统等。

可靠异步发送

异步发送是指发送方发出数据后,不等接收方发回响应,接着发送下个数据包的通讯方式。发送
方通过回调接口接收服务器响应,并对响应结果进行处理。
异步发送一般用于链路耗时较长,对 RT 响应时间较为敏感的业务场景,例如用户视频上传后通知
启动转码服务,转码完成后通知推送转码结果等。

单向发送

单向发送是指发送方只负责发送消息,不等待服务器回应且没有回调函数触发,即只发送请求不
等待应答。
适用于某些耗时非常短,但对可靠性要求并不高的场景,例如日志收集

<!--依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
//测试
@RunWith(SpringRunner.class)
@SpringBootTest(classes = OrderApplication.class)
public class MessageTypeTest {
    @Autowired
    private RocketMQTemplate rocketMQTemplate;
    //同步消息
    @Test
    public void testSyncSend() {
        //参数一: topic, 如果想添加tag 可以使用"topic:tag"的写法
        //参数二: 消息内容
        SendResult sendResult =
                rocketMQTemplate.syncSend("test-topic-1", "这是一条同步消息");
        System.out.println(sendResult);
    }
    //异步消息
    //异步消息
    @Test
    public void testAsyncSend() throws InterruptedException {

         {
                 //参数一: topic, 如果想添加tag 可以使用"topic:tag"的写法
              //参数二: 消息内容
                //参数三: 回调函数, 处理返回结果
            rocketMQTemplate.asyncSend("test-topic-1", "这是一条异步消息", new
                    SendCallback() {
                        @Override
                        public void onSuccess(SendResult sendResult) {
                            System.out.println(sendResult);
                        }

                        @Override
                        public void onException(Throwable throwable) {
                            System.out.println(throwable);
                        }
                    });
        }
        //让线程不要终止
        Thread.sleep(30000000);
    }

        //单向消息
        @Test
        public void testOneWay() {
            rocketMQTemplate.sendOneWay("test-topic-1", "这是一条单向消息");
        }
    }

三种发送方式的对比

发送方式发送 TPS发送结果反馈可靠性
同步发送不丢失
异步发送不丢失
单向发送最快可能丢失

顺序消息

顺序消息是消息队列提供的一种严格按照顺序来发布和消费的消息类型。
在这里插入图片描述

//同步顺序消息[异步顺序 单向顺序写法类似]
public void testSyncSendOrderly() {
//第三个参数用于队列的选择
		rocketMQTemplate.syncSendOrderly("test-topic-1", "这是一条异步顺序消息",
	"xxxx");
}

事务消息

RocketMQ提供了事务消息,通过事务消息就能达到分布式事务的最终一致。
事务消息交互流程:
在这里插入图片描述
两个概念:

  • 半事务消息:暂不能投递的消息,发送方已经成功地将消息发送到了RocketMQ服务端,但是服务
    端未收到生产者对该消息的二次确认,此时该消息被标记成“暂不能投递”状态,处于该种状态下的
    消息即半事务消息。
  • 消息回查:由于网络闪断、生产者应用重启等原因,导致某条事务消息的二次确认丢失,
    RocketMQ服务端通过扫描发现某条消息长期处于“半事务消息”时,需要主动向消息生产者询问该
    消息的最终状态(Commit 或是 Rollback),该询问过程即消息回查。
    事务消息发送步骤:
  1. 发送方将半事务消息发送至RocketMQ服务端。
  2. RocketMQ服务端将消息持久化之后,向发送方返回Ack确认消息已经发送成功,此时消息为半事
    务消息。
  3. 发送方开始执行本地事务逻辑。
  4. 发送方根据本地事务执行结果向服务端提交二次确认(Commit 或是 Rollback),服务端收到
    Commit 状态则将半事务消息标记为可投递,订阅方最终将收到该消息;服务端收到 Rollback 状
    态则删除半事务消息,订阅方将不会接受该消息。

事务消息回查步骤:

  1. 在断网或者是应用重启的特殊情况下,上述步骤4提交的二次确认最终未到达服务端,经过固定时间后服务端将对该消息发起消息回查。
  2. 发送方收到消息回查后,需要检查对应消息的本地事务执行的最终结果。
  3. 发送方根据检查得到的本地事务的最终状态再次提交二次确认,服务端仍按照步骤4对半事务消息进行操作。
@Service
public class OrderServiceImpl4 {

    @Autowired
    private OrderDao orderDao;

    @Autowired
    private TxLogDao txLogDao;
    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    public void createOrderBefore(Order order) {
        String txId = UUID.randomUUID().toString();
//发送半事务消息
        Message<?> Message = null;
        rocketMQTemplate.sendMessageInTransaction(
                "tx_producer_group",
                MessageBuilder.withPayload(order).setHeader("txId",
                        txId).build(),
                order
        );
    }
    //本地事物
    @Transactional
    public void createOrder(String txId, Order order) {
//本地事物代码
        orderDao.save(order);
//记录日志到数据库,回查使用
        TxLog txLog = new TxLog();
        txLog.setTxLogId(txId);
        txLog.setContent("事物测试");
        txLog.setDate(new Date());
        txLogDao.save(txLog);
    }
}

消息消费要注意的细节

@RocketMQMessageListener(
	consumerGroup = "shop",//消费者分组
	topic = "order-topic",//要消费的主题
	consumeMode = ConsumeMode.CONCURRENTLY, //消费模式:无序和有序
	messageModel = MessageModel.CLUSTERING, //消息模式:广播和集群,默认是集群
)
public class SmsService implements RocketMQListener<Order> {}

RocketMQ支持两种消息模式:

  • 广播消费: 每个消费者实例都会收到消息,也就是一条消息可以被每个消费者实例处理;

  • 集群消费: 一条消息只能被一个消费者实例消费

  • 第十二章 SpringCloud Alibaba 实现SMS–短信服务

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Qt中槽函数在那个线程执行的探索和思考

信号和槽是Qt的核心机制之一&#xff0c;通过该机制大大简化了开发者的开发难度。信号和槽属于观察者模式&#xff08;本质上是回调函数的应用&#xff09;。是函数就需要考虑其是在那个线程中执行&#xff0c;本文讨论的就是槽函数在那个线程中执行的问题。 目录 1. connect…

[BUG]TDA4 main域 CAN 无法进中断

目录 关键词平台说明一、背景二、根本原因2.1 Com模块 三、措施 关键词 嵌入式、C语言、autosar、TDA4 平台说明 项目ValueOSautosar OSautosar厂商vector芯片厂商TI编程语言C&#xff0c;C编译器HighTec (GCC) 一、背景 在将mcu域的部分can 移植到main域的时候发现无法进…

文章解读与仿真程序复现思路——电网技术EI\CSCD\北大核心《考虑灵活性资源传输精细化建模的配电网优化运行》

这个标题表达的是关于配电网优化运行的一个概念&#xff0c;其中考虑了灵活性资源传输的精细化建模。让我们逐个解读关键词&#xff1a; 考虑灵活性资源传输&#xff1a;这指的是在配电网优化运行中考虑到不同类型的灵活性资源的传输。灵活性资源包括可再生能源、储能系统、柔性…

HarmonyOS首次尝试-HelloWorld

我的旧手机是个HUAWEI PCT-AL10 HarmonyOS 3.0.0(Android 10) 插上后&#xff0c;studio能显示连接上了手机设备&#xff0c;创建的demo使用的是API9&#xff0c;也就是当前的最新版本。 点击运行报错&#xff1a; 点击去往帮助页&#xff0c;做的也挺好&#xff0c;有直达的…

抠图软件哪个好用?什么软件可以抠图换背景?

抠图软件哪个好用&#xff1f;在图片处理中&#xff0c;抠图换背景是一项常见的操作。很多新手可能会对此感到困惑&#xff0c;不知道应该使用什么软件来进行抠图换景。实际上&#xff0c;现在市面上有很多图片处理软件都具备抠图换背景的功能&#xff0c;每款软件都有其优缺点…

开辟“护眼绿洲”,荣耀何以为师?

文 | 智能相对论 作者 | 佘凯文 俗话说&#xff0c;眼睛是心灵的窗户&#xff0c;可如今&#xff0c;人们对于这扇“窗户”的保护&#xff0c;似乎越来越不重视。 据人民日报今年发布的调查显示&#xff0c;中国眼病患病人数2.1亿&#xff0c;近视患者人数多达6亿&#xff0…

Python学习之爬虫基础

目录 文章声明⭐⭐⭐让我们开始今天的学习吧&#xff01;requests库的基本使用BeautifulSoup解析HTML我们还需要学习什么呢&#xff1f; 文章声明⭐⭐⭐ 该文章为我&#xff08;有编程语言基础&#xff0c;非编程小白&#xff09;的 Python爬虫自学笔记知识来源为 B站UP主&…

【JVM从入门到实战】(五)类加载器

一、什么是类加载器 类加载器&#xff08;ClassLoader&#xff09;是Java虚拟机提供给应用程序去实现获取类和接口字节码数据的技术。 类加载器只参与加载过程中的字节码获取并加载到内存这一部分。 二、jdk8及之前的版本 类加载器分为三类&#xff1a; 启动类加载器-加载Ja…

2043杨辉三角(C语言)

目录 一&#xff1a;题目 二&#xff1a;思路分析 三&#xff1a;代码 一&#xff1a;题目 二&#xff1a;思路分析 1.通过杨辉三角&#xff0c;不难发现中间的数等于肩头两个数之和 2.但是当我们的输出结果&#xff0c;与杨辉三角的形式有所不同&#xff0c;但是我们可以找…

【Linux】高性能 Web 服务器 Nginx 安装教程(Ubuntu 22.04)

前言 Nginx 是一个高性能的开源 Web 服务器软件&#xff0c;也可以用作反向代理服务器、负载均衡器、HTTP 缓存以及作为邮件代理服务器等。Nginx 以其高性能、稳定性和丰富的功能而闻名&#xff0c;被广泛用于构建高流量网站和应用程序。 步骤 更新软件源 首先需要更新系统的软…

AttributeError: module ‘edge_tts‘ has no attribute ‘Communicate‘解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

pycdc配置和使用

配置 使用的kali2023版本 安装cmake pip install cmake 下载pycdc git clone https://github.com/zrax/pycdc 切换到pycdc目录 cd pycdc 进行cmake cmake CMakeLists.txt make 使用 显示帮助信息 ./pycdc -h 显示帮助信息 反编译 ./pycdc /home/kali/Desktop/main…

瑞萨单片机学习:RA4M3单片机 BOOTloader升级 跳转到主程序 主程序无法执行问题

背景&#xff1a; 使用瑞萨的RA4M3单片机编写BOOT引导程序进行测试&#xff0c;在BOOT程序跳转到主程序时&#xff0c;主程序无法执行。本文介绍了问题的定位和解决方法。 运行开发环境介绍 硬件环境 RA4M3 官方开发板 J-LINK V11 开发板自带 软件开发环境 e2 studio VSCODE…

【MySQL基础】MySQL基本操作详解

系列文章目录 第1篇&#xff1a;【MySQL基础】MySQL介绍及安装 第2篇&#xff1a;【MySQL基础】MySQL基本操作详解 文章目录 ✍1&#xff0c;数据库操作     &#x1f50d;1.1,查看数据库     &#x1f50d;1.2,创建数据库     &#x1f50d;1.3,选择数据库    …

探索太空深渊:计算机技术在航天领域的无限可能

探索太空深渊&#xff1a;计算机技术在航天领域的无限可能 一、引言 在21世纪的科技浪潮中&#xff0c;太空探索和计算机技术无疑是两个最为璀璨夺目的领域。它们各自的发展都足以改变人类社会的未来&#xff0c;而当这两者交汇时&#xff0c;所激发出的创新和变革更是超乎我…

算法通关第十九关-青铜挑战理解动态规划

大家好我是苏麟 , 今天聊聊动态规划 . 动态规划是最热门、最重要的算法思想之一&#xff0c;在面试中大量出现&#xff0c;而且题目整体都偏难一些对于大部人来说&#xff0c;最大的问题是不知道动态规划到底是怎么回事。很多人看教程等&#xff0c;都被里面的状态子问题、状态…

Windows 10如何关闭系统自动更新(实用教程)

本章教程&#xff0c;用最简洁的方式介绍在windows10中如何关闭系统自动更新。 目录 一、关闭自动更新服务 二、关闭自动更新组策略 一、关闭自动更新服务 1、 winr 2、services.msc 3、找到并双击 Windows Update 修改启动类型为禁用 二、关闭自动更新组策略 1、winr 2、gp…

社交网络分析2(下):社交网络情感分析的方法、挑战与前沿技术

社交网络分析2&#xff08;下&#xff09;&#xff1a;社交网络情感分析的方法、挑战与前沿技术 写在最前面7. 词嵌入&#xff08;word embedding&#xff09;的主要目的是什么&#xff1f;结合某方法简要地说明如何实现词嵌入。主要目的实现方法示例&#xff1a;GloVe案例分析…

python深拷贝和浅拷贝

文章目录 浅拷贝深拷贝 刷完这60个标准库模块&#xff0c;成为Python骨灰级玩家 深拷贝和浅拷贝都是用于复制对象的概念。浅拷贝在复制对象时&#xff0c;仅复制其引用&#xff0c;而非复制对象本身。这意味着原对象和新对象都指向相同的内存地址&#xff0c;修改一个对象会影…

linux 文本信息查询grep;控制命令执行和管道操作符号

1、grep grep "keyword" /path/to/logfile获取查询结果最后一行 grep "runs/detect/train" test4.log | tail -n 12、linux控制命令执行和管道操作符号 &、|、; 和 &&、》、>、< ##例子&#xff1b;wandb disabled && yolo …