详解RabbitMQ工作模式之发布订阅模式
目录
发布订阅模式
概念
概念介绍
特点和优势
应用场景
注意事项
代码案例
引入依赖
常量类
编写生产者代码
编写消费者1代码
运行代码
发布订阅模式
概念
RabbitMQ的发布订阅模式(Publish/Subscribe)是一种消息传递模式,它允许消息生产者(Publisher)将消息发送到交换机(Exchange),然后交换机根据路由规则将消息广播到一个或多个队列,最后由消费者(Subscriber)从队列中接收并处理消息。
图中X表⽰交换机, 在订阅模型中,多了⼀个Exchange⻆⾊, 过程略有变化。
概念介绍
Exchange: 交换机 (X).
作⽤: ⽣产者将消息发送到Exchange, 由交换机将消息按⼀定规则路由到⼀个或多个队列中(上图中⽣产者将消息投递到队列中, 实际上这个在RabbitMQ中不会发⽣. )
RabbitMQ交换机有四种类型: fanout,direct, topic, headers, 不同类型有着不同的路由策略. AMQP协议⾥还有另外两种类型, System和⾃定义, 此处不再描述.
1. Fanout:⼴播,将消息交给所有绑定到交换机的队列(Publish/Subscribe模式)
2. Direct:定向,把消息交给符合指定routing key的队列(Routing模式)
3. Topic:通配符,把消息交给符合routing pattern(路由模式)的队列(Topics模式)
4. headers类型的交换器不依赖于路由键的匹配规则来路由消息, ⽽是根据发送的消息内容中的headers属性进⾏匹配. headers类型的交换器性能会很差,⽽且也不实⽤,基本上不会看到它的存在.
Exchange(交换机)只负责转发消息, 不具备存储消息的能⼒, 因此如果没有任何队列与Exchange绑定,或者没有符合路由规则的队列,那么消息就会丢失
RoutingKey: 路由键.⽣产者将消息发给交换器时, 指定的⼀个字符串, ⽤来告诉交换机应该如何处理这个消息.
Binding Key:绑定. RabbitMQ中通过Binding(绑定)将交换器与队列关联起来, 在绑定的时候⼀般会指定⼀个Binding Key, 这样RabbitMQ就知道如何正确地将消息路由到队列了.
⽐如下图: 如果在发送消息时, 设置了RoutingKey 为orange, 消息就会路由到Q1
当消息的Routing key与队列绑定的Bindingkey相匹配时,消息才会被路由到这个队列.
BindingKey其实也属于路由键中的⼀种, 官⽅解释为:the routingkey to use for the binding.
可以翻译为:在绑定的时候使⽤的路由键. ⼤多数时候,包括官⽅⽂档和RabbitMQJava API 中都把
BindingKey和RoutingKey看作RoutingKey, 为了避免混淆,可以这么理解:
1. 在使⽤绑定的时候,需要的路由键是BindingKey.
2. 在发送消息的时候,需要的路由键是RoutingKey
特点和优势
1.解耦合:生产者和消费者之间通过交换机进行解耦。生产者无需知道消息将被传递到哪些队列,消费者也无需知道消息来自哪个生产者。这种解耦合使得系统更加灵活和可扩展。
2.多播:支持多个消费者同时处理同一条消息,实现消息的多播效果。这有助于提高系统的并行处理能力和容错性。
3.灵活性:可以根据需要使用不同类型的交换机和绑定规则,以满足不同的消息传递需求。RabbitMQ提供了多种交换机类型,如直接交换机、扇形交换机、主题交换机等。
应用场景
发布订阅模式适用于需要将消息广播给多个消费者的场景,例如:
1.实时通知:如系统状态更新、订单状态变更等实时事件的通知。通过发布订阅模式,可以将这些事件广播给所有感兴趣的消费者。
2.日志记录:将应用程序的日志信息广播到多个日志处理服务进行处理和存储。这有助于实现日志的集中管理和分析。
3.事件处理:在事件驱动架构中,将事件作为消息发布到交换机,由多个消费者订阅并处理这些事件。这有助于实现事件的异步处理和分布式处理。
注意事项
1.消息持久化:为了确保消息在RabbitMQ服务器重启后不会丢失,可以将消息和队列标记为持久性。这样,即使服务器发生故障,消息仍然可以被消费者接收和处理。
2.消息确认:RabbitMQ支持消息确认机制,确保消息在成功处理后才会从队列中删除。这有助于防止消息丢失和重复处理。
3.负载均衡:在发布订阅模式中,多个消费者可以监听同一个队列或不同的队列。为了实现负载均衡,可以配置多个消费者来处理同一个队列中的消息。
代码案例
引入依赖
<!-- https://mvnrepository.com/artifact/com.rabbitmq/amqp-client --> <dependency><groupId>com.rabbitmq</groupId><artifactId>amqp-client</artifactId><version>5.21.0</version> </dependency>
常量类
public class Constants {public static final String HOST = "47.98.109.138";public static final int PORT = 5672;public static final String USER_NAME = "study";public static final String PASSWORD = "study";public static final String VIRTUAL_HOST = "aaa";//发布订阅模式public static final String FANOUT_EXCHANGE = "fanout.exchange";public static final String FANOUT_QUEUE1 = "fanout.queue1";public static final String FANOUT_QUEUE2 = "fanout.queue2";
}
编写生产者代码
import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import rabbitmq.constant.Constants;import java.io.IOException;
import java.util.concurrent.TimeoutException;public class Producer {public static void main(String[] args) throws IOException, TimeoutException {//1. 建立连接ConnectionFactory connectionFactory = new ConnectionFactory();connectionFactory.setHost(Constants.HOST);connectionFactory.setPort(Constants.PORT); //需要提前开放端口号connectionFactory.setUsername(Constants.USER_NAME);//账号connectionFactory.setPassword(Constants.PASSWORD); //密码connectionFactory.setVirtualHost(Constants.VIRTUAL_HOST); //虚拟主机Connection connection = connectionFactory.newConnection();//2. 开启信道Channel channel = connection.createChannel();//3. 声明交换机channel.exchangeDeclare(Constants.FANOUT_EXCHANGE, BuiltinExchangeType.FANOUT, true);//4. 声明队列channel.queueDeclare(Constants.FANOUT_QUEUE1,true,false,false,null);channel.queueDeclare(Constants.FANOUT_QUEUE2,true,false,false,null);//5. 交换机和队列绑定channel.queueBind(Constants.FANOUT_QUEUE1,Constants.FANOUT_EXCHANGE,"");channel.queueBind(Constants.FANOUT_QUEUE2,Constants.FANOUT_EXCHANGE,"");//6. 发布消息String msg = "hello fanout....";channel.basicPublish(Constants.FANOUT_EXCHANGE,"", null, msg.getBytes());System.out.println("消息发送成功");//7. 释放资源channel.close();connection.close();}
}
编写消费者1代码
import com.rabbitmq.client.*;
import rabbitmq.constant.Constants;import java.io.IOException;
import java.util.concurrent.TimeoutException;public class Consumer1 {public static void main(String[] args) throws IOException, TimeoutException {//1. 建立连接ConnectionFactory connectionFactory = new ConnectionFactory();connectionFactory.setHost(Constants.HOST);connectionFactory.setPort(Constants.PORT); //需要提前开放端口号connectionFactory.setUsername(Constants.USER_NAME);//账号connectionFactory.setPassword(Constants.PASSWORD); //密码connectionFactory.setVirtualHost(Constants.VIRTUAL_HOST); //虚拟主机Connection connection = connectionFactory.newConnection();//2. 开启信道Channel channel = connection.createChannel();//3. 声明队列channel.queueDeclare(Constants.FANOUT_QUEUE1,true,false,false,null);//4. 消费消息DefaultConsumer consumer = new DefaultConsumer(channel){//从队列中收到消息, 就会执行的方法@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {System.out.println("接收到消息:"+ new String(body));}};channel.basicConsume(Constants.FANOUT_QUEUE1, true, consumer);}
}
编写消费者2代码
import com.rabbitmq.client.*;
import rabbitmq.constant.Constants;import java.io.IOException;
import java.util.concurrent.TimeoutException;public class Consumer2 {public static void main(String[] args) throws IOException, TimeoutException {//1. 建立连接ConnectionFactory connectionFactory = new ConnectionFactory();connectionFactory.setHost(Constants.HOST);connectionFactory.setPort(Constants.PORT); //需要提前开放端口号connectionFactory.setUsername(Constants.USER_NAME);//账号connectionFactory.setPassword(Constants.PASSWORD); //密码connectionFactory.setVirtualHost(Constants.VIRTUAL_HOST); //虚拟主机Connection connection = connectionFactory.newConnection();//2. 开启信道Channel channel = connection.createChannel();//3. 声明队列channel.queueDeclare(Constants.FANOUT_QUEUE2,true,false,false,null);//4. 消费消息DefaultConsumer consumer = new DefaultConsumer(channel){//从队列中收到消息, 就会执行的方法@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {System.out.println("接收到消息:"+ new String(body));}};channel.basicConsume(Constants.FANOUT_QUEUE2, true, consumer);}
}
运行代码
运行生产者代码之后,可以在管理界面看到两个队列中都有1条消息。
由此我们可以看到,交换机收到的生产者生产的一条消息被广播到了两个队列,消费者都能够分别从这两个队列中得到一条消息并消费。
相关文章:
详解RabbitMQ工作模式之发布订阅模式
目录 发布订阅模式 概念 概念介绍 特点和优势 应用场景 注意事项 代码案例 引入依赖 常量类 编写生产者代码 编写消费者1代码 运行代码 发布订阅模式 概念 RabbitMQ的发布订阅模式(Publish/Subscribe)是一种消息传递模式,它允许消…...
JobHistory Server的配置和启动
在 Hadoop 集群里,JobHistory Server(JHS)负责为所有已完成的 MapReduce 作业提供元数据与 Web 可视化;只有它启动并配置正确,开发者才能通过 http://<host>:19888 查看作业的执行详情、计数器和任务日志…...
刷leetcodehot100返航版--哈希表5/5
回顾一下之前做的哈希,貌似只有用到 unordered_set:存储无序元素unordered_map:存储无序键值对 代码随想录 常用代码模板2——数据结构 - AcWing C知识回顾-CSDN博客 1.两数之和5/5【30min】 1. 两数之和 - 力扣(LeetCode&…...
【STM32 学习笔记】GPIO输入与输出
GPIO详解 一、GPIO基本概念 GPIO(通用输入输出)是微控制器与外部设备交互的核心接口,具有以下特性: 可编程控制输入/输出模式支持数字信号的读取与输出集成多种保护机制复用功能支持片上外设连接 二、GPIO位结构解析 2.1 保护二…...
网狐飞云娱乐三端源码深度实测:组件结构拆解与部署Bug复盘指南(附代码分析)
本文基于“网狐系列三网通飞云娱乐电玩”源码包,从项目结构、界面逻辑、三端兼容性、机器人机制、本地部署实践等多维角度进行全面剖析,并附录多个真实报错修复案例与源码片段。本组件适用于本地学习、框架研究与技术测试,不具备线上部署条件…...
HTML5好看的水果蔬菜在线商城网站源码系列模板9
文章目录 1.设计来源1.1 主界面1.2 商品界面1.3 购物车界面1.4 心愿列表界面1.5 商品信息界面1.6 博客界面1.7 关于我们界面1.8 联系我们界面1.9 常见问题界面1.10 登录界面 2.效果和源码2.1 动态效果2.2 源代码 源码下载万套模板,程序开发,在线开发&…...
【ArcGIS Pro微课1000例】0066:多边形要素添加折点,将曲线线段(贝塞尔、圆弧和椭圆弧)替换为线段?
文章目录 增密工具介绍举例1. 圆2. 椭圆3. 折线增密工具介绍 ArcGIS Pro中提供了【增密】工具,作用是: 沿线或多边形要素添加折点。还可将曲线线段(贝塞尔、圆弧和椭圆弧)替换为线段。 原理图如下所示: 用法: 通过距离参数对直线段进行增密。利用距离、最大偏转角或最大…...
虚拟dom是什么,他有什么好处
本编,博主将从虚拟dom是什么引出,为什么需要虚拟dom, 虚拟dom的益处 , 为什么需要Diff算法,for循环中key的作用是什么。 1.虚拟dom是什么 虚拟dom就是以js对象的形式表示真实dom结构 例如 const newVNode {type: di…...
算力经济模型推演:从中心化到去中心化算力市场的转变(区块链+智能合约的算力交易原型设计)
一、算力经济的历史脉络与范式转移 1.1 中心化算力市场的演进困境 传统算力市场以超算中心、云计算平台为核心载体,其运营模式呈现强中心化特征。中国移动构建的"四算融合"网络虽实现百万级服务器的智能调度,但动态资源分配仍受制于集中式控…...
数据结构之二叉树(4)
(注:本文所示代码均为C) 一.二叉树选择题 根据二叉树的性质,完成以下选择题: (1)第一组 某二叉树共有 399 个结点,其中有 199 个度为 2 的结点,则该二叉树中的叶子结点数为&am…...
互联网与无线广播:数字时代与模拟时代的通讯双轨制-优雅草卓伊凡
互联网与无线广播:数字时代与模拟时代的通讯双轨制-优雅草卓伊凡 一、无线广播:穿越百年的电磁波通讯 1.1 无线广播的技术本质 当卓伊凡深入研究无线广播技术后,发现这套诞生于19世纪末的通讯系统蕴含着惊人的智慧。无线广播本质上是一种单…...
Java 集合线程安全
在高并发环境下,Java集合ArrayList和HashMap读写可能会出现安全问题。其中有几个解决办法: 使用Collections类方法Collections.synchronizedList和Collections.synchronizedMap在Java并发包中提供了CopyOnWriteArrayList和ConcurrentHashMap类 一、Arr…...
解决 Builroot 系统编译 perl 编译报错问题
本文提供一种修复 Builroot 系统编译 perl 编译报错途径 2025-05-04T22:45:08 rm -f pod/perl5261delta.pod 2025-05-04T22:45:08 /usr/bin/ln -s perldelta.pod pod/perl5261delta.pod 2025-05-04T22:45:08 /usr/bin/gcc -c -DPERL_CORE -fwrapv -fpcc-struct-return -pipe -f…...
理解计算机系统_并发编程(1)_并发基础和基于进程的并发
前言 以<深入理解计算机系统>(以下称“本书”)内容为基础,对程序的整个过程进行梳理。本书内容对整个计算机系统做了系统性导引,每部分内容都是单独的一门课.学习深度根据自己需要来定 引入 并发是一种非常重要的机制,用于处理多个指令流.特别是在网…...
详细案例,集成算法
以下是一个使用 随机森林(RF) 和 XGBoost 解决结构化数据分类问题的完整案例(以泰坦尼克号生存预测为例),包含数据处理、建模和结果分析: 案例:泰坦尼克号乘客生存预测 目标:根据乘客…...
57认知干货:AI机器人产业
机器人本质上由可移动的方式和可交互万物的机构组成,即适应不同环境下不同场景的情况,机器人能够做到根据需求调整交互机构和移动方式。因此,随着人工智能技术的发展,AI机器人的产业也将在未来逐步从单一任务的执行者,发展为能够完成复杂多样任务的智能体。 在未来的社会…...
谷歌 NotebookLM 支持生成中文播客
谷歌 NotebookLM 支持生成中文播客。 2025 年 4 月 29 日,NotebookLM 宣布其 “音频概览”(Audio Overviews)功能新增 76 种语言支持,其中包括中文。用户只需将文档、笔记、研究材料等上传至 NotebookLM,然后在设置中选…...
【MySQL数据库】用户管理
目录 1,用户信息 2,创建/删除/修改用户 3,数据库的权限 MySQL数据库安装完之后,我们最开始时使用的都是 root 用户,其它用户通常无法进行操作。因此,MySQL数据库需要对用户进行管理。 1,用户…...
杜教筛原理,实现与时间复杂度分析
引例 洛谷 P4213 【模板】杜教筛 题目描述 给定一个正整数,求 a n s 1 ∑ i 1 n φ ( i ) ans_1\sum_{i1}^n\varphi(i) ans1i1∑nφ(i) a n s 2 ∑ i 1 n μ ( i ) ans_2\sum_{i1}^n \mu(i) ans2i1∑nμ(i) 输入格式 本题单测试点内有多组数据。 输入的…...
【时时三省】(C语言基础)怎样定义和引用一维数组
山不在高,有仙则名。水不在深,有龙则灵。 ----CSDN 时时三省 一维数组是数组中最简单的,它的元素只需要用数组名加一个下标,就能唯一地确定。如上面介绍的学生成绩数组s就是一维数组。有的数组,其元素要指定两个下标才…...
二叉搜索树的最近祖先(递归遍历)
235. 二叉搜索树的最近公共祖先 - 力扣(LeetCode) class Solution { private:TreeNode*traversal(TreeNode*cur,TreeNode*p,TreeNode*q){if(curNULL){return NULL;}if(cur->val>p->val&&cur->val>q->val){TreeNode*lefttrave…...
蘑菇管理——AI与思维模型【94】
一、定义 蘑菇管理思维模型是一种形象地描述组织对待新员工或初入职场者的管理方式及相关现象的思维模型。它将新员工或初入职场者比作蘑菇,这些人在初期往往被置于阴暗的角落(不受重视的部门,或打杂跑腿的工作),浇上…...
Uni-app 组件使用
在前端开发领域,能够高效地创建跨平台应用是开发者们一直追求的目标。Uni-app 凭借其 “一次开发,多端部署” 的特性,成为了众多开发者的首选框架。而组件作为 Uni-app 开发的基础单元,合理运用组件能够极大地提升开发效率和代码的…...
湖北理元理律师事务所:债务优化的合规化探索
在债务处置领域,合法性与有效性往往难以兼得。湖北理元理律师事务所通过标准化服务流程设计,尝试在二者间建立平衡点,其经验为行业提供了可参考的实践样本。 四阶服务模型 1.合规审查 核查债务来源合法性,重点筛查: …...
PISI:眼图1:眼图相关基本概念
0 英文缩写 TIE(Time Interval Error)时间间隔误差,UI(Unit Interval)单位间隔PDF(Probability Density Function)概率密度函数BER(Bit Error Rate)误码率TJ(…...
初试C++报错并解决记录
初试C报错并解决记录 报错开始解决问题记录1、考虑应该是没有指定dll位置 无法打开.lib文件1. 应该是没有包含Lib文件 问题解决➡ C 文件需要添加路径的位置记录: 显示调用dll文件位置注意问题解决➡调用位置: 调用人家的.h文件的方法(项目使…...
Android运行时ART加载类和方法的过程分析
目录 一,概述 二,ART运行时的入口 一,概述 既然ART运行时执行的都是翻译DEX字节码后得到的本地机器指令了,为什么还需要在OAT文件中包含DEX文件,并且将它加载到内存去呢?这是因为ART运行时提供了Java虚拟机接口,而要实现Java虚…...
【力扣刷题记录】hot100错题本(一)
1. 简单题 我的答案:时间复杂度过高:O(N^3) class Solution:def twoSum(self, nums: List[int], target: int) -> List[int]:for num in nums:if (target - num) in nums:#多余for i in range(len(nums)):if nums[i] num :for j in range(i1,len(nu…...
Android运行时ART加载OAT文件的过程
目录 一,概述 1.1 OAT是如何产生的 一,概述 OAT文件是一种Android私有ELF文件格式,它不仅包含有从DEX文件翻译而来的本地机器指令,还包含有原来的DEX文件内容。这使得我们无需重新编译原有的APK就可以让它正常地在ART里面运行,也就是我们不…...
Python读取comsol仿真导出数据并绘图
文章目录 comsol数据导出python读取文件python绘制云图python进一步分析数据 完整代码 当我们使用comsol,ansys等仿真工具进行仿真后,难免需要对仿真结果进行导出并进一步处理分析。 今天小姜以comsol的一个简单磁场仿真为例,详细介绍如何对c…...
cloudfare+gmail 配置 smtp 邮箱
这里介绍有一个域名后,不需要服务器,就可以实现 cloudfare gmail 的 邮箱收发。 为什么还需要 gmail 的 smtp 功能,因为 cloudfare 默认只是对 email 进行转发,就是只能收邮件而不能发送邮件,故使用 gmail 的功能来进…...
【翻译、转载】使用 LLM 构建 MCP
资料来源: https://modelcontextprotocol.io/tutorials/building-mcp-with-llms 本文仅仅是翻译。 使用 LLM 构建 MCP 利用 Claude 等大型语言模型(LLM)加速您的 MCP 开发! 本指南将帮助您使用 LLM 来构建自定义的模型上下文协…...
Python速成系列二
文章目录 Python 条件语句与循环结构详解一、条件语句(if-elif-else)1. 基本 if 结构2. if-else 结构3. if-elif-else 结构4. 嵌套条件语句5. 三元表达式(条件表达式) 二、循环结构1. while 循环2. for 循环3. 循环控制语句break …...
基于STM32的心电图监测系统设计
摘要 本论文旨在设计一种基于 STM32 微控制器的心电图监测系统,通过对人体心电信号的采集、处理和分析,实现对心电图的实时监测与显示。系统采用高精度的心电信号采集模块,结合 STM32 强大的数据处理能力,能够有效去除噪声干扰&a…...
线程池的线程数配置策略
目录 1. CPU密集型任务 2. IO密集型任务 3. 混合型任务 1. CPU密集型任务 特点:任务主要消耗CPU资源(如计算、加密、压缩)。 推荐线程数: 线程数 ≈ 物理核心数 1 / CPU - 1(不知道哪个√) 例如&#…...
分享一个Android中文汉字手写输入法并带有形近字联想功能
最近我写了一个Android版本的中文汉字手写输入法功能,并实现了汉字形近字联想功能,此手写输入法功能完全满足公司的需求。 之前小编用Android SurfaceView,运用canvas的Path画坐标轨迹,并结合使用一个叫汉王输入法的so库来识别手…...
C语言:文件操作
文件的概念 文件是计算机用于存储数据的工具,我们计算机磁盘上的数据是混乱的,但是我们计算机系统通过文件的方式记录数据在磁盘上的位置来将数据整齐划分。 文件的类型 文件有两种类型,数据文件与程序文件 程序文件是用来执行的文件&#…...
2024年第十五届蓝桥杯省赛B组Python【 简洁易懂题解】
2024年第十五届蓝桥杯省赛B组Python题解 一、整体情况说明 2024年第十五届蓝桥杯省赛B组Python组考试共包含8道题目,分为结果填空题和程序设计题两类。 考试时间:4小时编程环境:Python 3.x,禁止使用第三方库,仅可使…...
线程与进程深度解析:从fork行为到生产者-消费者模型
线程与进程深度解析:从fork行为到生产者-消费者模型 一、多线程环境下的fork行为与线程安全 1. 多线程程序中fork的特殊性 核心问题:fork后子进程的线程模型 当多线程程序中的某个线程调用fork时: 子进程仅包含调用fork的线程࿱…...
2025年第十六届蓝桥杯省赛B组Java题解【完整、易懂版】
2025年第十六届蓝桥杯省赛B组Java题解 题型概览与整体分析 题目编号题目名称题型难度核心知识点通过率(预估)A逃离高塔结果填空★☆☆数学规律、模运算95%B消失的蓝宝结果填空★★★同余定理、中国剩余定理45%C电池分组编程题★★☆异或运算性质70%D魔法…...
【NTN 卫星通信】NTN关键问题的一些解决方法(一)
1 概述 3GPP在协议23.737中对一些卫星通信需要面对的关键问题进行了探讨,并且讨论了初步的解决方法,继续来看看这些内容把。 问题包括: 1、大型卫星覆盖区域的移动性管理 2、移动卫星覆盖区域的移动性管理 3、卫星延迟 4、卫星接入的QoS …...
C++基础算法9:Dijkstra
1、概念 Dijkstra算法 是一种用于计算图中单源最短路径的算法,主要用于加权图(图中边的权重可以不同)中找出从起点到各个其他节点的最短路径。 Dijkstra算法的核心概念: 图的表示: 有向图:图的边是有方…...
5块钱的无忧套餐卡可以变成流量卡吗
电信的 5 块钱无忧套餐卡理论上可以变成流量卡,但会受到一些条件限制,以下是具体介绍: 中国电信无忧卡简介 中国电信无忧卡是电信推出的低月租套餐,月租仅 5 元,包含 200M 国内流量、来电显示和 189 邮箱,全…...
word页眉去掉线
直接双击页眉处于下面状态: 然后: 按CtrlshiftN即可!去除...
Spark,Idea中编写Spark程序 2
Idea中编写Spark程序 一、修改pom.xml文件 <build><sourceDirectory>src/main/scala</sourceDirectory><testSourceDirectory>src/test/scala</testSourceDirectory> <!-- 添加必要的插件以打包scala程序--><plugins><plu…...
GTID(全局事务标识符)的深入解析
GTID(全局事务标识符)的深入解析 GTID(Global Transaction Identifier)是 MySQL 5.6 版本引入的一项核心功能,旨在解决传统主从复制中的痛点。它通过为每个事务赋予一个全局唯一的标识符,彻底改变了复制的管理方式。 一、传统复制的痛点 在 GTID 出现之前,MySQL 主从…...
Circular Plot系列(一): 环形热图绘制
针对近期多个粉丝咨询环形图的绘制,我意识到,我们似乎没有真正介绍过circle图,但这一类图确是非常常用的图,所以这里详细学习一下circle的绘制,使用的是circlize包,功能很完善:安装包, #https:/…...
字符串匹配 之 KMP算法
文章目录 习题28.找出字符串中第一个匹配项的下标1392.最长快乐前缀 本博客充分参考灵神和知乎的另一位博主 灵神KMP算法模版 知乎博主通俗易懂讲解 对于给定一个主串S和一个模式串P,如果让你求解出模式串P在主串S中匹配的情况下的所有的开始下标简单的做法又称为Brute-Force算…...
「一针见血能力」的终极训练手册
缘起 和顶尖的高手接触以后,发现他们在表达沟通上面的能力真的太强了,仿佛有种一阵见血看问题的能力,这种拨开浓雾看本质的能力是嘈杂世界防止上当受骗的不二法门. 网上找了一些训练方法,可以试试训练锐化思维,提高表…...
Linux 入门:操作系统进程详解
目录 一.冯诺依曼体系结构 一). 软件运行前为什么要先加载?程序运行之前在哪里? 二).理解数据流动 二.操作系统OS(Operator System) 一).概念 二).设计OS的目的 三).如何理解操作系统…...