RabbitMQ的5種消息隊列

RabbitMQ的5種消息隊列

1、七種模式介紹與應用場景

1.1 簡單模式(Hello World)

在這里插入圖片描述

一個生產者對應一個消費者,RabbitMQ 相當于一個消息代理,負責將 A 的消息轉發給 B。

應用場景:將發送的電子郵件放到消息隊列,然后郵件服務在隊列中獲取郵件并發送給收件人。

1.2 工作隊列模式(Work queues)

在這里插入圖片描述

在多個消費者之間分配任務(競爭的消費者模式),一個生產者對應多個消費者,一般適用于執行資源密集型任務,

單個消費者處理不過來,需要多個消費者進行處理。

應用場景:一個訂單的處理需要10s,有多個訂單可以同時放到消息隊列,然后讓多個消費者同時處理,這樣就是

并行了,而不是單個消費者的串行情況。

1.3 訂閱模式(Publish/Subscribe)

在這里插入圖片描述

一次向許多消費者發送消息,一個生產者發送的消息會被多個消費者獲取,也就是將消息將廣播到所有的消費者

中。

應用場景:更新商品庫存后需要通知多個緩存和多個數據庫,這里的結構應該是:

  • 一個 fanout 類型交換機扇出兩個個消息隊列,分別為緩存消息隊列、數據庫消息隊列
  • 一個緩存消息隊列對應著多個緩存消費者
  • 一個數據庫消息隊列對應著多個數據庫消費者

1.4 路由模式(Routing)

在這里插入圖片描述

有選擇地 (Routing key) 接收消息,發送消息到交換機并且要指定路由 key,消費者將隊列綁定到交換機時需要指

定路由 key,僅消費指定路由 key 的消息。

應用場景:如在商品庫存中增加了 1 臺 iphone12,iphone12 促銷活動消費者指定 routing key 為 iphone12,只

有此促銷活動會接收到消息,其它促銷活動不關心也不會消費此 routing key 的消息。

1.5 主題模式(Topics)

在這里插入圖片描述

根據主題 (Topics) 來接收消息,將路由 key 和某模式進行匹配,此時隊列需要綁定在一個模式上,#匹配一個詞

或多個詞,*只匹配一個詞。

應用場景:同上 iphone 促銷活動可以接收主題為 iphone 的消息,如 iphone12、iphone13 等。

1.6 遠程過程調用(RPC)

在這里插入圖片描述

如果我們需要在遠程計算機上運行功能并等待結果就可以使用 RPC,具體流程可以看圖。

應用場景:需要等待接口返回數據,如訂單支付。

1.7 發布者確認(Publisher Confirms)

與發布者進行可靠的發布確認,發布者確認是 RabbitMQ 擴展,可以實現可靠的發布。在通道上啟用發布者確認

后,RabbitMQ 將異步確認發送者發布的消息,這意味著它們已在服務器端處理。

應用場景:對于消息可靠性要求較高,比如錢包扣款。

2、代碼演示

<dependency><groupId>com.rabbitmq</groupId><artifactId>amqp-client</artifactId><version>5.6.0</version>
</dependency>

2.1 簡單模式

package simple;import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;import java.io.IOException;
import java.util.concurrent.TimeoutException;public class Sender {private final static String QUEUE_NAME = "simple_queue";public static void main(String[] args) throws IOException, TimeoutException {ConnectionFactory factory = new ConnectionFactory();factory.setHost("localhost");factory.setPort(5672);Connection connection = factory.newConnection();Channel channel = connection.createChannel();// 聲明隊列// queue: 隊列名// durable: 是否持久化// exclusive: 是否排外,即只允許該channel訪問該隊列,一般等于true的話用于一個隊列只能有一個消費者來消費的場景// autoDelete: 是否自動刪除,消費完刪除// arguments: 其他屬性channel.queueDeclare(QUEUE_NAME, false, false, false, null);// 消息內容String message = "simplest mode message";channel.basicPublish("", QUEUE_NAME, null, message.getBytes());System.out.println("[x]Sent '" + message + "'");// 最后關閉通關和連接channel.close();connection.close();}
}
package simple;import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;import java.io.IOException;
import java.util.concurrent.TimeoutException;public class Receiver {private final static String QUEUE_NAME = "simple_queue";public static void main(String[] args) throws IOException, TimeoutException {// 獲取連接ConnectionFactory factory = new ConnectionFactory();factory.setHost("localhost");factory.setPort(5672);Connection connection = factory.newConnection();Channel channel = connection.createChannel();channel.queueDeclare(QUEUE_NAME, false, false, false, null);DeliverCallback deliverCallback = (consumerTag, delivery) -> {String message = new String(delivery.getBody(), "UTF-8");System.out.println(" [x] Received '" + delivery.getEnvelope().getRoutingKey() + "':'" + message + "'");};channel.basicConsume(QUEUE_NAME, true, deliverCallback, consumerTag -> {});}
}
[x]Sent 'simplest mode message'[x] Received 'simple_queue':'simplest mode message'

2.2 工作隊列模式

package work;import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;import java.io.IOException;
import java.util.concurrent.TimeoutException;public class Receiver1 {private final static String QUEUE_NAME = "queue_work";public static void main(String[] args) throws IOException, TimeoutException {ConnectionFactory factory = new ConnectionFactory();factory.setHost("localhost");factory.setPort(5672);Connection connection = factory.newConnection();Channel channel = connection.createChannel();channel.queueDeclare(QUEUE_NAME, false, false, false, null);// 同一時刻服務器只會發送一條消息給消費者channel.basicQos(1);DeliverCallback deliverCallback = (consumerTag, delivery) -> {String message = new String(delivery.getBody(), "UTF-8");System.out.println(" [x-1] Received '" + delivery.getEnvelope().getRoutingKey() + "':'" + message + "'");};channel.basicConsume(QUEUE_NAME, true, deliverCallback, consumerTag -> {});}
}
package work;import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;import java.io.IOException;
import java.util.concurrent.TimeoutException;public class Receiver2 {private final static String QUEUE_NAME = "queue_work";public static void main(String[] args) throws IOException, TimeoutException {ConnectionFactory factory = new ConnectionFactory();factory.setHost("localhost");factory.setPort(5672);Connection connection = factory.newConnection();Channel channel = connection.createChannel();channel.queueDeclare(QUEUE_NAME, false, false, false, null);// 同一時刻服務器只會發送一條消息給消費者channel.basicQos(1);DeliverCallback deliverCallback = (consumerTag, delivery) -> {String message = new String(delivery.getBody(), "UTF-8");System.out.println(" [x-2] Received '" + delivery.getEnvelope().getRoutingKey() + "':'" + message + "'");};channel.basicConsume(QUEUE_NAME, true, deliverCallback, consumerTag -> {});}
}
package work;import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;import java.io.IOException;
import java.util.concurrent.TimeoutException;public class Sender {private final static String QUEUE_NAME = "queue_work";public static void main(String[] args) throws IOException, InterruptedException, TimeoutException {ConnectionFactory factory = new ConnectionFactory();factory.setHost("localhost");factory.setPort(5672);Connection connection = factory.newConnection();Channel channel = connection.createChannel();// 聲明隊列channel.queueDeclare(QUEUE_NAME, false, false, false, null);for (int i = 0; i < 10; i++) {String message = "work mode message" + i;channel.basicPublish("", QUEUE_NAME, null, message.getBytes());System.out.println("[x] Sent '" + message + "'");Thread.sleep(i * 10);}channel.close();connection.close();}
}
[x] Sent 'work mode message0'
[x] Sent 'work mode message1'
[x] Sent 'work mode message2'
[x] Sent 'work mode message3'
[x] Sent 'work mode message4'
[x] Sent 'work mode message5'
[x] Sent 'work mode message6'
[x] Sent 'work mode message7'
[x] Sent 'work mode message8'
[x] Sent 'work mode message9'[x-1] Received 'queue_work':'work mode message0'
[x-1] Received 'queue_work':'work mode message2'
[x-1] Received 'queue_work':'work mode message4'
[x-1] Received 'queue_work':'work mode message6'
[x-1] Received 'queue_work':'work mode message8'[x-2] Received 'queue_work':'work mode message1'
[x-2] Received 'queue_work':'work mode message3'
[x-2] Received 'queue_work':'work mode message5'
[x-2] Received 'queue_work':'work mode message7'
[x-2] Received 'queue_work':'work mode message9'

2.3 發布訂閱模式

package publishsubscribe;import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;public class Receive1 {private static final String EXCHANGE_NAME = "logs";public static void main(String[] argv) throws Exception {ConnectionFactory factory = new ConnectionFactory();factory.setHost("localhost");Connection connection = factory.newConnection();Channel channel = connection.createChannel();channel.exchangeDeclare(EXCHANGE_NAME, "fanout");String queueName = channel.queueDeclare().getQueue();channel.queueBind(queueName, EXCHANGE_NAME, "");System.out.println(" [*] Waiting for messages. To exit press CTRL+C");// 訂閱消息的回調函數DeliverCallback deliverCallback = (consumerTag, delivery) -> {String message = new String(delivery.getBody(), "UTF-8");System.out.println(" [x-1] Received '" + message + "'");};// 消費者,有消息時出發訂閱回調函數channel.basicConsume(queueName, true, deliverCallback, consumerTag -> {});}
}
package publishsubscribe;import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;public class Receive2 {private static final String EXCHANGE_NAME = "logs";public static void main(String[] argv) throws Exception {ConnectionFactory factory = new ConnectionFactory();factory.setHost("localhost");Connection connection = factory.newConnection();Channel channel = connection.createChannel();channel.exchangeDeclare(EXCHANGE_NAME, "fanout");String queueName = channel.queueDeclare().getQueue();channel.queueBind(queueName, EXCHANGE_NAME, "");System.out.println(" [*] Waiting for messages. To exit press CTRL+C");// 訂閱消息的回調函數DeliverCallback deliverCallback = (consumerTag, delivery) -> {String message = new String(delivery.getBody(), "UTF-8");System.out.println(" [x-2] Received2 '" + message + "'");};// 消費者,有消息時出發訂閱回調函數channel.basicConsume(queueName, true, deliverCallback, consumerTag -> {});}
}
package publishsubscribe;import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;public class Sender {private static final String EXCHANGE_NAME = "logs";public static void main(String[] argv) throws Exception {ConnectionFactory factory = new ConnectionFactory();factory.setHost("localhost");Connection connection = factory.newConnection();Channel channel = connection.createChannel();channel.exchangeDeclare(EXCHANGE_NAME, "fanout");String message = "publish subscribe message";channel.basicPublish(EXCHANGE_NAME, "", null, message.getBytes("UTF-8"));System.out.println(" [x] Sent '" + message + "'");channel.close();connection.close();}
}
[x] Sent 'publish subscribe message'[*] Waiting for messages. To exit press CTRL+C
[x-1] Received 'publish subscribe message'[*] Waiting for messages. To exit press CTRL+C
[x-2] Received2 'publish subscribe message'

2.4 路由模式

package router;import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;import java.io.IOException;
import java.util.concurrent.TimeoutException;public class Receiver1 {private final static String QUEUE_NAME = "queue_routing";private final static String EXCHANGE_NAME = "exchange_direct";public static void main(String[] args) throws IOException, TimeoutException {ConnectionFactory factory = new ConnectionFactory();factory.setHost("localhost");factory.setPort(5672);Connection connection = factory.newConnection();Channel channel = connection.createChannel();channel.queueDeclare(QUEUE_NAME, false, false, false, null);// 指定路由的key,接收key和key2channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "key");channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "key2");channel.basicQos(1);DeliverCallback deliverCallback = (consumerTag, delivery) -> {String message = new String(delivery.getBody(), "UTF-8");System.out.println(" [x-1] Received '" + delivery.getEnvelope().getRoutingKey() + "':'" + message + "'");};channel.basicConsume(QUEUE_NAME, true, deliverCallback, consumerTag -> {});}
}
package router;import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;import java.io.IOException;
import java.util.concurrent.TimeoutException;public class Receiver2 {private final static String QUEUE_NAME = "queue_routing2";private final static String EXCHANGE_NAME = "exchange_direct";public static void main(String[] args) throws IOException, TimeoutException {ConnectionFactory factory = new ConnectionFactory();factory.setHost("localhost");factory.setPort(5672);Connection connection = factory.newConnection();Channel channel = connection.createChannel();channel.queueDeclare(QUEUE_NAME, false, false, false, null);// 僅接收key2channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "key2");channel.basicQos(1);DeliverCallback deliverCallback = (consumerTag, delivery) -> {String message = new String(delivery.getBody(), "UTF-8");System.out.println(" [x-2] Received '" +delivery.getEnvelope().getRoutingKey() + "':'" + message + "'");};channel.basicConsume(QUEUE_NAME, true, deliverCallback, consumerTag -> {});}
}
package router;import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;import java.io.IOException;
import java.util.concurrent.TimeoutException;public class Sender {private final static String EXCHANGE_NAME = "exchange_direct";private final static String EXCHANGE_TYPE = "direct";public static void main(String[] args) throws IOException, TimeoutException {ConnectionFactory factory = new ConnectionFactory();factory.setHost("localhost");factory.setPort(5672);Connection connection = factory.newConnection();Channel channel = connection.createChannel();// 交換機聲明channel.exchangeDeclare(EXCHANGE_NAME, EXCHANGE_TYPE);// 只有routingKey相同的才會消費String message = "routing mode message";channel.basicPublish(EXCHANGE_NAME, "key2", null, message.getBytes());System.out.println("[x] Sent '" + message + "'");// channel.basicPublish(EXCHANGE_NAME, "key", null, message.getBytes());// System.out.println("[x] Sent '" + message + "'");channel.close();connection.close();}
}
[x] Sent 'routing mode message'[x-1] Received 'key2':'routing mode message'[x-2] Received 'key2':'routing mode message'

2.5 主題模式

package topic;import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;import java.io.IOException;
import java.util.concurrent.TimeoutException;public class Receiver1 {private final static String QUEUE_NAME = "queue_topic";private final static String EXCHANGE_NAME = "exchange_topic";public static void main(String[] args) throws IOException, InterruptedException, TimeoutException {ConnectionFactory factory = new ConnectionFactory();factory.setHost("localhost");factory.setPort(5672);Connection connection = factory.newConnection();Channel channel = connection.createChannel();channel.queueDeclare(QUEUE_NAME, false, false, false, null);// 可以接收key.1channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "key.*");channel.basicQos(1);DeliverCallback deliverCallback = (consumerTag, delivery) -> {String message = new String(delivery.getBody(), "UTF-8");System.out.println(" [x-1] Received '" + delivery.getEnvelope().getRoutingKey() + "':'" + message + "'");};channel.basicConsume(QUEUE_NAME, true, deliverCallback, consumerTag -> {});}
}
package topic;import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;import java.io.IOException;
import java.util.concurrent.TimeoutException;public class Receiver2 {private final static String QUEUE_NAME = "queue_topic2";private final static String EXCHANGE_NAME = "exchange_topic";private final static String EXCHANGE_TYPE = "topic";public static void main(String[] args) throws IOException, InterruptedException, TimeoutException {ConnectionFactory factory = new ConnectionFactory();factory.setHost("localhost");factory.setPort(5672);Connection connection = factory.newConnection();Channel channel = connection.createChannel();channel.queueDeclare(QUEUE_NAME, false, false, false, null);// *號代表單個單詞,可以接收key.1channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "*.*");// #號代表多個單詞,可以接收key.1.2channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "*.#");channel.basicQos(1);DeliverCallback deliverCallback = (consumerTag, delivery) -> {String message = new String(delivery.getBody(), "UTF-8");System.out.println(" [x-2] Received '" + delivery.getEnvelope().getRoutingKey() + "':'" + message + "'");};channel.basicConsume(QUEUE_NAME, true, deliverCallback, consumerTag -> {});}
}
package topic;import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;import java.io.IOException;
import java.util.concurrent.TimeoutException;public class Sender {private final static String EXCHANGE_NAME = "exchange_topic";private final static String EXCHANGE_TYPE = "topic";public static void main(String[] args) throws IOException, TimeoutException {ConnectionFactory factory = new ConnectionFactory();factory.setHost("localhost");factory.setPort(5672);Connection connection = factory.newConnection();Channel channel = connection.createChannel();channel.exchangeDeclare(EXCHANGE_NAME, EXCHANGE_TYPE);String message = "topics model message with key.1";channel.basicPublish(EXCHANGE_NAME, "key.1", null, message.getBytes());System.out.println("[x] Sent '" + message + "'");String message2 = "topics model message with key.1.2";channel.basicPublish(EXCHANGE_NAME, "key.1.2", null, message2.getBytes());System.out.println("[x] Sent '" + message2 + "'");channel.close();connection.close();}
}
[x] Sent 'topics model message with key.1'
[x] Sent 'topics model message with key.1.2'[x-1] Received 'key.1':'topics model message with key.1'[x-2] Received 'key.1':'topics model message with key.1'
[x-2] Received 'key.1.2':'topics model message with key.1.2'

3、四種交換機介紹

  • 直連交換機( Direct exchange ):具有路由功能的交換機,綁定到此交換機的時候需要指定一個

    routing_key,交換機發送消息的時候需要 routing_key,會將消息發送道對應的隊列。

  • 扇形交換機( Fanout exchange ):廣播消息到所有隊列,沒有任何處理,速度最快。

  • 主題交換機( Topic exchange ):在直連交換機基礎上增加模式匹配,也就是對 routing_key 進行模式匹配,

    * 代表一個單詞,# 代表多個單詞。

  • 首部交換機( Headers exchange ):忽略 routing_key,使用 Headers 信息(一個 Hash 的數據結構)進行匹

    配,優勢在于可以有更多更靈活的匹配規則。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/40070.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/40070.shtml
英文地址,請注明出處:http://en.pswp.cn/news/40070.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【JS學習】Object.assign 用法介紹

Object.assign 是ES6中的一個方法。該方法能夠實現對象的淺復制以及對象合并。Object.assign 并不會修改目標對象本身&#xff0c;而是返回一個新的對象&#xff0c;其中包含了所有源對象的屬性。 例1 2個對象合并 const target { a: 1, b: 2 }; const source { b: 3, c: 4…

【git】初次使用git上傳代碼到github遠程倉庫

目錄 0.前言1.新建代碼庫2.添加SSH公鑰2.1 前置準備2.2 Git 基本信息設置2.3 添加SSH Key 3.本地倉庫上傳到github3.1 建立本地倉庫并初始化3.2 初始化倉庫3.3 建立本地與github上新建項目鏈接3.4 同步github新建項目到本地3.5 添加本地文件到緩存區3.6 為上傳文件添加注釋3.7 …

注冊中心Eureka和Nacos,以及負載均衡Ribbon

1.初識微服務 1.1.什么是微服務 微服務&#xff0c;就是把服務拆分成為若干個服務&#xff0c;降低服務之間的耦合度&#xff0c;提供服務的獨立性和靈活性。做到高內聚&#xff0c;低耦合。 1.2.單體架構和微服務架構的區別&#xff1a; 單體架構&#xff1a;簡單方便&#…

TS基本語法

一、安裝 npm install -g typescript 或者 cnpm install -g typescript 或者 yarnlobal add typescript二、運行 tsc xxxx.ts注意&#xff1a;如果電腦上面沒有安裝過cnpm&#xff0c;請先安裝cnpm npm install -g cnpm --registryhttps://registry.npm.taobao.org注意&…

數字圖像處理-AWB跳變

1、自動白平衡&#xff08;AWB&#xff09;算法是相機中常用的圖像處理技術&#xff0c;它能夠自動調整圖像中的白平衡&#xff0c;使得圖像中的顏色更加真實、自然。然而&#xff0c;在實際應用中&#xff0c;AWB算法也存在著一些問題&#xff0c;例如AWB跳變&#xff08;Whit…

DevExpress WinForms數據編輯器組件,提供豐富的數據輸入樣式!(一)

DevExpress WinForms超過80個高影響力的WinForms編輯器和多用途控件&#xff0c;從屏蔽數據輸入和內置數據驗證到HTML格式化&#xff0c;DevExpress數據編輯庫提供了無與倫比的數據編輯選項&#xff0c;包括用于獨立數據編輯或用于容器控件(如Grid, TreeList和Ribbon)的單元格。…

云原生 envoy xDS 動態配置 java控制平面開發 支持restful grpc實現 EDS 動態endpoint配置

envoy xDS 動態配置 java控制平面開發 支持restful grpc 動態endpoint配置 大綱 基礎概念Envoy 動態配置API配置方式動靜結合的配置方式純動態配置方式實戰 基礎概念 Envoy 的強大功能之一是支持動態配置&#xff0c;當使用動態配置時&#xff0c;我們不需要重新啟動 Envoy…

spring boot 整合mongodb

1、安裝依賴 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId></dependency>2、配置數據庫連接 spring:data:mongodb:host: localhostport: 27017username: xxxxxxp…

2682. 找出轉圈游戲輸家

題目描述&#xff1a; n 個朋友在玩游戲。這些朋友坐成一個圈&#xff0c;按 順時針方向 從 1 到 n 編號。從第 i 個朋友的位置開始順時針移動 1 步會到達第 (i 1) 個朋友的位置&#xff08;1 < i < n&#xff09;&#xff0c;而從第 n 個朋友的位置開始順時針移動 1 步…

“華為杯”研究生數學建模競賽2018年-【華為杯】F題:中轉航班調度:從 MILP 模型到啟發式算法

目錄 摘 要 1 問題描述 2 模型假設 3 符號定義及數據預處理 3.1 符號定義

【廣州華銳視點】帆船航行VR模擬實操系統

帆船航行VR模擬實操系統由廣州華銳視點開發&#xff0c;是一種創新的教學工具&#xff0c;它利用虛擬現實技術&#xff0c;為學生提供了一個沉浸式的學習環境。通過這種系統&#xff0c;學生可以在虛擬的環境中進行帆船航行的實訓&#xff0c;從而更好地理解和掌握帆船航行的技…

Maven(四)常用命令大全

目錄 一、mvn 命令參數二、mvn 插件命令1.介紹2.查看插件的使用文檔3.常用的插件命令 官網地址&#xff1a; https://maven.apache.org/官方插件清單&#xff1a; https://maven.apache.org/plugins/index.html Maven 是一個強大的構建工具&#xff0c;它提供了許多命令來進行項…

使用Python統計字符內容的占比

說明&#xff1a;如果有自己動手做過字符動畫&#xff0c;會知道字符動畫的“靈動性”核心在于使用的字符集。 簡單來說&#xff0c;動畫轉為字符動畫&#xff0c;原理是將動畫轉為灰階圖&#xff0c;灰度范圍是0~255&#xff0c;然后將對應灰度的像素點轉為對應比值的字符。這…

linux github 倉庫管理常用操作

linux 的常用操作 linux 本地 ssh驗證連接github賬號本地倉庫連接遠程私有倉庫push/pull操作 Connecting to Github with ssh git local configuration If you are using git for the first time, configure the user name and email in the device. git config --global u…

R語言ggplot2 | R語言繪制物種組成面積圖(三)

&#x1f4cb;文章目錄 面積圖簡介準備數據集加載數據集數據處理數據可視化 利用R語言繪制物種組成圖。本文以堆疊面積圖的方式與大家分享。 面積圖簡介 面積圖又叫區域圖。它是在折線圖的基礎之上形成的, 它將折線圖中折線與自變量坐標軸之間的區域使用顏色或者紋理填充&…

設計模式之單例設計模式

單例設計模式 2.1 孤獨的太陽盤古開天&#xff0c;造日月星辰。2.2 餓漢造日2.3 懶漢的隊伍2.4 大道至簡 讀《秒懂設計模式總結》 單例模式(Singleton)是一種非常簡單且容易理解的設計模式。顧名思義&#xff0c;單例即單一的實例&#xff0c;確切地講就是指在某個系統中只存在…

【算法題】螺旋矩陣III (求解n階蛇形矩陣)

一、問題的提出 n階蛇形矩陣的特點是按照圖1所示的方式排列元素。n階蛇形矩陣是指矩陣的大小為nn&#xff0c;其中n為正整數。 題目背景 一個 n 行 n 列的螺旋矩陣可由如圖1所示的方法生成&#xff0c;觀察圖片&#xff0c;找出填數規律。填數規則為從 1 開始填到 nn。 圖1 …

【配置環境】Linux下安裝MySQL

目錄 一&#xff0c;環境 二&#xff0c;安裝步驟 1.使用包管理器安裝MySQL 2.配置MySQL的安全選項 3.設置root用戶使用密碼進行身份驗證&#xff08;可選&#xff09; 三&#xff0c;拓展知識 1.如何修改MySQL的密碼策略&#xff1f; 2.實現連接MySQL數據庫的測試代碼…

TiDB基礎介紹、應用場景及架構

1. 什么是newsql NewSQL 是對各種新的可擴展/高性能數據庫的簡稱&#xff0c;這類數據庫不僅具有NoSQL對海量數據的存儲管理能力&#xff0c;還保持了傳統數據庫支持ACID和SQL等特性。 NewSQL是指這樣一類新式的關系型數據庫管理系統&#xff0c;針對OLTP&#xff08;讀-寫&…

經驗分享:企業數據倉庫建設方案總結!

導讀 在企業的數字化轉型浪潮中&#xff0c;數據被譽為“新時代的石油”&#xff0c;而數據倉庫作為數據管理與分析的核心基礎設施&#xff0c;在企業的信息化建設中扮演著重要的角色。本文將深入探討企業數據倉庫建設過程中所遇到的問題以及解決經驗&#xff0c;為正在籌備或…