SpringBoot+ActiveMQ-发布订阅模式(生产端)
SpringBoot+ActiveMQ-发布订阅模式(生产端)
Topic 主题
* 消息消费者(订阅方式)消费该消息
* 消费生产者将发布到topic中,同时有多个消息消费者(订阅)消费该消息
* 这种方式和点对点方式不同,发布到topic的消息会被所有订阅者消费
* 当生产者发布消息,不管是否有消费者,都不会保存消息,如果对订阅消息提前做了持久化操作,还是可以收到的
ActiveMQ版本:apache-activemq-5.16.5
案例源码:SpringBoot+ActiveMQ-发布订阅Demo
SpringBoot集成ActiveMQ topic生产端的pom.xml
<?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"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.0.5.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>boot.example.topic.provider</groupId><artifactId>boot-example-topic-demo-provider-2.0.5</artifactId><version>0.0.1-SNAPSHOT</version><name>boot-example-topic-demo-provider-2.0.5</name><description>Demo project for Spring Boot</description><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.8</java.version></properties><dependencies><dependency><groupId>boot.example.demo.entity</groupId><artifactId>boot-example-demo-entity-2.0.5</artifactId><version>0.0.1-SNAPSHOT</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- activeMQ依赖组件 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-activemq</artifactId><exclusions><exclusion><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId></exclusion></exclusions></dependency><!-- spring.activemq.pool.enabled=true --><dependency><groupId>org.apache.activemq</groupId><artifactId>activemq-pool</artifactId><version>5.16.5</version></dependency><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>2.9.2</version></dependency><dependency><groupId>com.github.xiaoymin</groupId><artifactId>swagger-bootstrap-ui</artifactId><version>1.9.2</version></dependency></dependencies><build><plugins><!-- 打包成一个可执行jar --><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><executions><execution><goals><goal>repackage</goal></goals></execution></executions></plugin></plugins></build></project>
application.properties
server.port=8043spring.activemq.broker-url=tcp://127.0.0.1:61616
spring.activemq.user=admin
spring.activemq.password=admin
spring.activemq.in-memory=false
spring.activemq.packages.trust-all=true
spring.activemq.pool.enabled=true
spring.activemq.pool.max-connections=6
spring.activemq.pool.idle-timeout=30000
spring.activemq.pool.expire-timeout=0
spring.jms.pub-sub-domain=false
启动类AppTopicProvider
package boot.example.topic.provider;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.jms.annotation.EnableJms;/***蚂蚁舞*/
@SpringBootApplication
@EnableJms
public class AppTopicProvider
{public static void main( String[] args ){SpringApplication.run(AppTopicProvider.class, args);System.out.println( "Hello World!" );}
}
ActiveMqConfig
package boot.example.topic.provider.config;import org.apache.activemq.command.ActiveMQTopic;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.annotation.EnableJms;
import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
import org.springframework.jms.config.JmsListenerContainerFactory;import javax.jms.ConnectionFactory;
import javax.jms.Topic;/*** 蚂蚁舞*/@Configuration
public class ActiveMqConfig {public static final String defaultTopic = "myw_topic";@Beanpublic Topic topic() {return new ActiveMQTopic(defaultTopic);}// // topic模式的ListenerContainer
// @Bean
// public JmsListenerContainerFactory<?> jmsListenerContainerTopic(ConnectionFactory activeMQConnectionFactory) {
// DefaultJmsListenerContainerFactory bean = new DefaultJmsListenerContainerFactory();
// bean.setPubSubDomain(true);
// bean.setConnectionFactory(activeMQConnectionFactory);
// return bean;
// }}
ProviderDefaultTopicService
package boot.example.topic.provider.service;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsMessagingTemplate;
import org.springframework.stereotype.Service;import javax.jms.Topic;@Service
public class ProviderDefaultTopicService {@Autowiredprivate Topic topic;@Autowiredprivate JmsMessagingTemplate jmsMessagingTemplate;/*** 使用默认bean配置的名称发送数据*/public void sendStringDefaultTopic(String message) {this.jmsMessagingTemplate.convertAndSend(topic, message);}}
ProviderTopicService
package boot.example.topic.provider.service;import boot.example.queue.entity.BootProvider;
import org.apache.activemq.command.ActiveMQTopic;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsMessagingTemplate;
import org.springframework.stereotype.Service;import java.util.List;/*** 蚂蚁舞*/
@Service
public class ProviderTopicService {@Autowiredprivate JmsMessagingTemplate jmsMessagingTemplate;/*** 发送字符串消息主题** @param topicName 主题名称* @param message 字符串*/public void sendStringTopic(String topicName, String message) {this.jmsMessagingTemplate.convertAndSend(new ActiveMQTopic(topicName), message);}/*** 发送字符串集合消息主题** @param topicName 主题名称* @param list 字符串集合*/public void sendStringListTopic(String topicName, List<String> list) {this.jmsMessagingTemplate.convertAndSend(new ActiveMQTopic(topicName), list);}/*** 发送对象消息主题** @param topicName 主题名称* @param obj 对象*/public void sendObjTopic(String topicName, BootProvider obj) {this.jmsMessagingTemplate.convertAndSend(new ActiveMQTopic(topicName), obj);}/*** 发送对象集合消息主题** @param topicName 主题名称* @param objList 对象集合*/public void sendObjListTopic(String topicName, List<BootProvider> objList) {this.jmsMessagingTemplate.convertAndSend(new ActiveMQTopic(topicName), objList);}}
BootDefaultTopicProviderController
package boot.example.topic.provider.controller;import boot.example.topic.provider.service.ProviderDefaultTopicService;
import org.springframework.web.bind.annotation.*;import javax.annotation.Resource;/*** 蚂蚁舞*/
@RestController
@RequestMapping(value="/provider")
public class BootDefaultTopicProviderController {@Resourceprivate ProviderDefaultTopicService providerDefaultTopicService;@PostMapping(value = "/sendStringDefaultTopic")@ResponseBodypublic String sendStringDefaultTopic(@RequestParam(name="message",required = true) String message) throws Exception {providerDefaultTopicService.sendStringDefaultTopic(message);return "success";}}
BootTopicProviderController
package boot.example.topic.provider.controller;import boot.example.queue.entity.BootProvider;
import boot.example.topic.provider.service.ProviderTopicService;
import org.springframework.web.bind.annotation.*;import javax.annotation.Resource;
import java.util.List;/*** 蚂蚁舞*/
@RestController
@RequestMapping(value="/provider")
public class BootTopicProviderController {// 指定Topicpublic static final String stringTopic = "stringTopic";// 指定list<String>public static final String stringListTopic = "stringListTopic";// 指定Objectpublic static final String objTopic = "objTopic";// 指定List<Object>public static final String objListTopic = "objListTopic";@Resourceprivate ProviderTopicService providerTopicService;@PostMapping(value = "/sendStringTopic")@ResponseBodypublic String sendStringTopic(@RequestParam(name="message",required = true) String message) throws Exception {providerTopicService.sendStringTopic(stringTopic, message);return "success";}@PostMapping(value = "/sendStringListTopic")@ResponseBodypublic String sendStringListTopic(@RequestBody List<String> list) throws Exception {if(list.isEmpty()){return "fail";}providerTopicService.sendStringListTopic(stringListTopic, list);return "success";}@PostMapping(value = "/sendObjTopic")@ResponseBodypublic String sendObjTopic(@RequestBody BootProvider bootProvider) throws Exception {if(bootProvider == null){return "fail";}providerTopicService.sendObjTopic(objTopic, bootProvider);return "success";}@PostMapping(value = "/sendObjListTopic")@ResponseBodypublic String sendObjListTopic(@RequestBody List<BootProvider> list) throws Exception {if(list.isEmpty()){return "fail";}providerTopicService.sendObjListTopic(objListTopic, list);return "success";}}
SwaggerConfig UI界面测试用
package boot.example.topic.provider.config;import com.google.common.base.Predicates;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;/*** 蚂蚁舞*/
@Configuration
@EnableSwagger2
public class SwaggerConfig {@Beanpublic Docket createRestApi(){return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select().apis(RequestHandlerSelectors.any()).paths(PathSelectors.any()).paths(Predicates.not(PathSelectors.regex("/error.*"))).paths(PathSelectors.regex("/.*")).build().apiInfo(apiInfo());}private ApiInfo apiInfo(){return new ApiInfoBuilder().title("demo").description("demo接口").version("0.01").build();}/*** http://localhost:XXXX/doc.html 地址和端口根据实际项目查看*/}
BootProvider用来测试的类
package boot.example.queue.entity;import java.io.Serializable;
import java.util.Date;/*** 用在activeMq消息,必须保证package一致,不然序列化后反序列化要出错* 蚂蚁舞*/
public class BootProvider implements Serializable {private int id;private String name;private Date date = new Date();public BootProvider() {}public BootProvider(int id, String name) {this.id = id;this.name = name;}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Date getDate() {return date;}public void setDate(Date date) {this.date = date;}@Overridepublic String toString() {return "BootProvider{" +"id=" + id +", name='" + name + '\'' +", date=" + date +'}';}
}
代码结构
├─boot-example-demo-entity-2.0.5
│ │ pom.xml
│ │
│ ├─src
│ │ └─main
│ │ └─java
│ │ └─boot
│ │ └─example
│ │ └─queue
│ │ └─entity
│ │ BootProvider.java
│ │
├─boot-example-topic-demo-provider-2.0.5
│ │ pom.xml
│ ├─src
│ │ ├─main
│ │ │ ├─java
│ │ │ │ └─boot
│ │ │ │ └─example
│ │ │ │ └─topic
│ │ │ │ └─provider
│ │ │ │ │ AppTopicProvider.java
│ │ │ │ │
│ │ │ │ ├─config
│ │ │ │ │ ActiveMqConfig.java
│ │ │ │ │ SwaggerConfig.java
│ │ │ │ │
│ │ │ │ ├─controller
│ │ │ │ │ BootDefaultTopicProviderController.java
│ │ │ │ │ BootTopicProviderController.java
│ │ │ │ │
│ │ │ │ └─service
│ │ │ │ ProviderDefaultTopicService.java
│ │ │ │ ProviderTopicService.java
│ │ │ │
│ │ │ └─resources
│ │ │ application.properties
│ │ │
│ │ └─test
│ │ └─java
│ │ └─boot
│ │ └─example
│ │ └─topic
│ │ └─provider
│ │ AppTopicProviderTest.java
ActiveMQ在SpringBoot里的Topic代码demo集成完成,(ActiveMQ已启动后)启动程序访问
http://localhost:8043/doc.html


SpringBoot集成activeMQ对于队列(queue)来说是持久化的事物模式,因此拿来即用,但是发布订阅(topic主题)模式不是持久化的,发送端把消息发出后,如果没有消费者,消息不会被消费,即使消费者端启动了,也不会消费之前的消息(除非对发布订阅也做持久化)
典型的案例topic demo测试(支持持久化订阅)
ActiveMQTopicProvider(Topic生产端)
package boot.example.topic.provider;import org.apache.activemq.ActiveMQConnectionFactory;import javax.jms.*;/*** 蚂蚁舞*/
public class ActiveMQTopicProvider {public static void main(String[] args) throws Exception{ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("admin", "admin", "tcp://127.0.0.1:61616");Connection connection = connectionFactory.createConnection();connection.start();//创建会话//第一个参数:是否开启事务 transacted true开启 false不开启//第二个参数:消息是否自动确认 acknowledgeMode//当transacted为true时,acknowledgeMode会默认Session.SESSION_TRANSACTEDSession session = connection.createSession(true, Session.DUPS_OK_ACKNOWLEDGE);//创建TopicTopic topic = session.createTopic("myw_topic_test");MessageProducer producer = session.createProducer(topic);producer.setDeliveryMode(DeliveryMode.PERSISTENT);//持久化设置 默认就是这个Message message = session.createTextMessage("myyhtw蚂蚁也会跳舞");producer.send(message);session.commit(); // 开启事务必须提交这个producer.close();session.close();connection.close();}
}
ActiveMQTopicConsumer(Topic消费端)
package boot.example.topic.provider;import org.apache.activemq.ActiveMQConnectionFactory;import javax.jms.*;/*** 蚂蚁舞*/
public class ActiveMQTopicConsumer {public static void main(String[] args) throws Exception {String clientId = "myw_topic_test_wijwe";//创建连接工厂ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("admin", "admin", "tcp://127.0.0.1:61616");// 持久订阅的Client端标识(多个端持久订阅需要保证唯一性,否则可能会出现问题)connectionFactory.setClientID(clientId);//创建连接Connection connection = connectionFactory.createConnection();//开启连接connection.start();// 创建会话// transacted 如果设置true,操作消息队列后,必须使用 session.commit() 如果设置false,操作消息队列后,不使用session.commit();// acknowledgeMode// 1-Session.AUTO_ACKNOWLEDGE 自动应答// 2-Session.CLIENT_ACKNOWLEDGE 手动应答// 3-Session.DUPS_OK_ACKNOWLEDGE 延迟应答// 0-Session.SESSION_TRANSACTED 事务// 当transacted为true时,acknowledgeMode会默认Session.SESSION_TRANSACTEDSession session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);//创建topicTopic topic = session.createTopic("myw_topic_test");//持久订阅//创建消费者
// // 普通订阅 topic不是持久化的
// MessageConsumer consumer = session.createConsumer(topic);// 持久订阅MessageConsumer consumer = session.createDurableSubscriber(topic,clientId);while(true){//失效时间,如果10秒内没有收到新的消息,说明没有消息存在,此时可以退出当前循环TextMessage message = (TextMessage) consumer.receive(60000);if(message!=null){System.out.println(message.getText());//message.acknowledge();} else {break;}}//关闭连接session.commit();session.close();connection.close();}
}
ActiveMQTopicConsumerListener(Topic消费端监听)
package boot.example.topic.provider;import org.apache.activemq.ActiveMQConnectionFactory;import javax.jms.*;/*** 蚂蚁舞*/
public class ActiveMQTopicConsumerListener {public static void main(String[] args) throws Exception {String clientId = "myw_topic_test_www2";//创建连接工厂ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("admin", "admin", "tcp://127.0.0.1:61616");//创建连接Connection connection = connectionFactory.createConnection();// 持久订阅的Client端标识(多个端持久订阅需要保证唯一性,否则可能会出现问题)connection.setClientID(clientId);//开启连接connection.start();// 创建会话// transacted 如果设置true,操作消息队列后,必须使用 session.commit() 如果设置false,操作消息队列后,不使用session.commit();// acknowledgeMode// 1-Session.AUTO_ACKNOWLEDGE 自动应答// 2-Session.CLIENT_ACKNOWLEDGE 手动应答// 3-Session.DUPS_OK_ACKNOWLEDGE 延迟应答// 0-Session.SESSION_TRANSACTED 事务// 当transacted为true时,acknowledgeMode会默认Session.SESSION_TRANSACTEDSession session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);//创建topicTopic topic = session.createTopic("myw_topic_test");//创建消费者
// // 普通订阅 topic不是持久化的
// MessageConsumer consumer = session.createConsumer(topic);// 持久订阅MessageConsumer consumer = session.createDurableSubscriber(topic,clientId);//注册消息监听器consumer.setMessageListener(new MessageListener() {@Overridepublic void onMessage(Message message) {try {TextMessage msg = (TextMessage)message;System.out.println(msg.getText());message.acknowledge();} catch (JMSException e) {throw new RuntimeException(e);}}});while (true){}
// consumer.close();
// session.close();
// connection.close();}}
topic持久化需要发布端设置持久化
producer.setDeliveryMode(DeliveryMode.PERSISTENT);//持久化设置 默认就是这个
topic消费订阅端在代码里有这几个设置
String clientId = "myw_topic_test_www2";// 持久订阅的Client端标识(多个端持久订阅需要保证唯一性,否则可能会出现问题)
connection.setClientID(clientId);// 持久订阅
MessageConsumer consumer = session.createDurableSubscriber(topic,clientId);
相关文章:

SpringBoot+ActiveMQ-发布订阅模式(生产端)
SpringBootActiveMQ-发布订阅模式(生产端)Topic 主题* 消息消费者(订阅方式)消费该消息* 消费生产者将发布到topic中,同时有多个消息消费者(订阅)消费该消息* 这种方式和点对点方式不同…...

Android实例仿真之三
目录 四 Android架构探究 五 大骨架仿真 六 Android实例分析思路拓展 四 Android架构探究 首先,Android系统所带来的好处,就在于它本身代码的开放性,这提供了一个学习、借鉴的平台。这对分析仿真而言,本身就是一大利好…...

关于MySQL的limit优化
1、前提 提示:只适用于InnoDB引擎 2、InnoDB存储特点 它把索引和数据放在了一个文件中,就是聚集索引。这与MyISAM引擎是不一样的。 3、SQL示例 -- 给cve字段建立索引 select * from cnnvd where cveCVE-2022-24808 limit 300000,10;由于M…...
Java-Stream流基本使用
collection.stream将会破坏原有的数据结构,可以通过collect方法收集,可以用Collectors提供的构造器,add等方法构造形成新的数据结构。 HashSet<List<Integer>> rs new HashSet<>(); rs.stream().toList();Collection集合转…...

Liunx(狂神课堂笔记)
一.常用命令 1. cd 切换目录 cd ./* 当前目录cd /* 绝对路径cd .. 返回上一级目录cd ~ 回到当前目录pwd …...
【史上最全面esp32教程】点灯大师篇
文章目录前言ESP32简介认识arduino的两个函数点灯步骤函数介绍LED灯闪烁流水灯总结前言 esp32有很多的功能,例如wifi,蓝牙等,这节我们学习最简单的点灯。 提示:以下是本篇文章正文内容,下面案例可供参考 ESP32简介 …...

【Java 面试合集】内存中为什么要区分栈和堆
内存中为什么要区分栈和堆 1. 概述 嗨,大家好Java 面试合集又来了,今天我们分享的主题很大众化以及普通。无论是Java 语言本身还是别的语言都会有所涉及,但是今天我们从Java角度来讲下 2. 分析 今天我们会从多个方向来分享这个话题 2.1 栈是…...

【NLP实战】Python字符串处理
一、Python字符串基本操作 1. 去掉前后的特殊字符(strip) Python的strip操作可以去除字符串前后的空格(不改变原串)下例将前后的空格均删掉👇 str 人工智能 str.strip() # OUT:人工智能rstrip删除右边的空格&a…...

17.CSS伪类
举一个简单的例子来说明什么是伪类? 从之前的代码中,如下图,我们像给这两个列表中的某一列单独设置样式,我们该如何做呢? 我们肯定会选择在li标签上添加class去实现,如下 开始标记结束标记实际元素 <…...

数据链路层
一.以太网数据链路层考虑的是相邻两个节点(通过网线/光纤、无线直接相连的两个设备)之间的传输,这里的典型协议中最知名的就是“以太网”这个协议了数据链路层,也规定了物理层的内容以太网帧格式:IP地址用来描述整个传…...

投票需要什么流程微信投票互助平台的免费投票平台搭建
“最美家政人”网络评选投票_免费小程序投票推广_小程序投票平台好处手机互联网给所有人都带来不同程度的便利,而微信已经成为国民的系统级别的应用。现在很多人都会在微信群或朋友圈里转发投票,对于运营及推广来说找一个合适的投票小程序能够提高工作效…...

数据结构——算法的时间复杂度
🌇个人主页:_麦麦_ 📚今日名言:生命中曾经有过的所有灿烂,都终究需要用寂寞来偿还。——《百年孤独》 目录 一、前言 二、正文 1.算法效率 1.1如何衡量一个算法的好坏 1.2算法的复杂度 2. 时间复杂度 2.1时间复杂度的…...
Go基础-类型
文章目录1 bool2 有符号整数3 无符号整数4 浮点数5 复数6 string7 关于类型转型1 bool bool类型有两个值,一个是true,一个是false。 测试 package mainimport "fmt"func main() {a : trueb : falsec : a && bd : a || bfmt.Println(a…...

良许翻天覆地的2022年
大家好,我是良许,新年快乐呀~ 在我女室友坚持不懈的努力之下,2022年的最后一天我终于被她传染了,阳了~ 此时的我,正顶着37多度的低烧写下这篇年终总结。 2022年,对于大多数人而言,封控是主旋…...

node+vue微信小程序的社区后勤报修系统
社区后勤报修系统小程序进行总体设计和详细设计。总体设计主要包括小程序功能设计、小程序总体结构设计、小程序数据结构设计和小程序安全设计等:详细设计主要包括社区后勤报修系统小程序数据库访问的实现,主要功能模块的具体实现,模块实现关键代码等。最后对社区后…...

WSL(Windows Subsystem for Linux)
一、WSL优势 •传统方式:获取Linux操作系统环境,必须安装完整的虚拟机,如VMware•WSL:以非常轻量化的方式,得到Linux系统环境总结:WSL更方便,简单、好用、轻量化、省内存 二、什么是WSL ①不…...
华为OD机试题 - 单词反转(JavaScript)
最近更新的博客 华为OD机试题 - 任务总执行时长(JavaScript) 华为OD机试题 - 开放日活动(JavaScript) 华为OD机试 - 最近的点 | 备考思路,刷题要点,答疑 【新解法】 华为OD机试题 - 最小步骤数(JavaScript) 华为OD机试题 - 任务混部(JavaScript) 华为OD机试题 - N 进…...
人工智能原理复习 | 产生式系统的搜索策略
文章目录 一、回溯策略二、图搜索策略三、A 算法与 A* 算法CSDN 叶庭云:https://yetingyun.blog.csdn.net/ 主要内容:回溯策略、图搜索策略(无信息的图搜索、启发式的图搜索)、A 算法与 A* 算法 一、回溯策略 回溯算法(BackTracking Algorithm) 实际上是一个类似枚举的搜…...

初始C语言 - 数组(一维数组、二维数组、数组越界、数组传参)
目录 一、一维数组的创建和初始化 1、数组的创建 2、 数组的初始化 3.一维数组的使用 数组通过下标来访问 总结: 1. 数组是使用下标来访问的,下标是从0开始。 2. 数组的大小可以通过计算得到。 4、一维数组在内存中的存储 二、 二维数组的创建和初始化 1.二…...
人工智能原理复习 | 可分解产生式系统的搜索策略
文章目录 一、前言二、基础知识三、AO* 算法四、博弈树搜索五、总结CSDN 叶庭云:https://yetingyun.blog.csdn.net/ 主要内容: 与 / {/} /或图搜索、AO* 算法、极大极小过程、...
Python爬虫实战:研究MechanicalSoup库相关技术
一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...
Android Wi-Fi 连接失败日志分析
1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分: 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析: CTR…...
Java 语言特性(面试系列2)
一、SQL 基础 1. 复杂查询 (1)连接查询(JOIN) 内连接(INNER JOIN):返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

阿里云ACP云计算备考笔记 (5)——弹性伸缩
目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?
在建筑行业,项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升,传统的管理模式已经难以满足现代工程的需求。过去,许多企业依赖手工记录、口头沟通和分散的信息管理,导致效率低下、成本失控、风险频发。例如&#…...
c++ 面试题(1)-----深度优先搜索(DFS)实现
操作系统:ubuntu22.04 IDE:Visual Studio Code 编程语言:C11 题目描述 地上有一个 m 行 n 列的方格,从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子,但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...
C++中string流知识详解和示例
一、概览与类体系 C 提供三种基于内存字符串的流,定义在 <sstream> 中: std::istringstream:输入流,从已有字符串中读取并解析。std::ostringstream:输出流,向内部缓冲区写入内容,最终取…...
Java入门学习详细版(一)
大家好,Java 学习是一个系统学习的过程,核心原则就是“理论 实践 坚持”,并且需循序渐进,不可过于着急,本篇文章推出的这份详细入门学习资料将带大家从零基础开始,逐步掌握 Java 的核心概念和编程技能。 …...
MySQL 8.0 事务全面讲解
以下是一个结合两次回答的 MySQL 8.0 事务全面讲解,涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容,并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念(ACID) 事务是…...