rabbitMQ (1)

news2024/10/6 2:30:49

文章目录

  • 1. RabbitMQ 介绍
    • 1.1 几个重要概念
    • 1.2 RabbitMq 的工作原理
  • 2 RabbitMQ 安装
  • 3. RabbitMQ 入门操作
    • 3.1 添加依赖
    • 3.2 生产者代码
    • 3.3 消费者代码
  • 4. Work Queues
  • 5. 管理端页面创建队列

1. RabbitMQ 介绍

引用 :

RabbitMQ 是一个消息中间件:它接受并转发消息。你可以把它当做一个快递站点,当你要发送一个包裹时,

你把你的包裹放到快递站,快递员最终会把你的快递送到收件人那里,按照这种逻辑 RabbitMQ 是 一个快递站,

一个快递员帮你传递快件。RabbitMQ 与快递站的主要区别在于,它不处理快件而是接收,存储和转发消息数据。

1.1 几个重要概念

  1. 消息(Message):消息是 RabbitMQ 中最基本的数据单元,它由消息体和可选的属性组成。消息体是要传递的实际数据,属性可以包含一些元数据,如路由键、优先级等。
  2. 生产者(Producer):生产者是发送消息到 RabbitMQ 的应用程序。它将消息发布到交换器(Exchange),并指定一个路由键(Routing Key)来标识消息的目的地。 --> 可以直接认为是生产消息的人 (厂家)
  3. 交换器(Exchange):交换器是接收来自生产者的消息,并根据路由规则将消息路由到一个或多个队列。它定义了消息从生产者到队列的路由策略。
  4. 队列(Queue):队列是存储消息的地方,它是消费者从中接收消息的对象。队列具有名称,并且可以设置各种属性,如持久性、优先级等。
  5. 绑定(Binding):绑定是将交换器和队列关联起来的过程。它指定了一个交换器和一个队列之间的关系,通常包括交换器名称、队列名称和路由键。
  6. 消费者(Consumer):消费者是从队列中获取消息的应用程序。它订阅一个或多个队列,并从队列中接收、处理消息。
  7. 路由键(Routing Key):路由键是生产者在将消息发送到交换器时指定的一个关键字。交换器根据路由键的值将消息路由到一个或多个队列。
  8. 绑定键(Binding Key):绑定键是用来绑定交换器和队列之间关系的关键字。当交换器接收到消息时,会根据消息的路由键和绑定键来进行匹配,从而确定将消息发送到哪个队列。
  9. 消息确认(Message Acknowledgement):消息确认机制用于确保消息在消费者处理后得到正确处理。消费者在处理完消息后,通过发送确认给 RabbitMQ,告知它该消息已被成功处理。
  10. 可靠性(Reliability):RabbitMQ 提供了一些可靠性机制,如持久化消息、持久化队列和交换器,以保证消息不会丢失,并在发生故障时恢复数据。

1.2 RabbitMq 的工作原理


简单 看完上面的几个概念 , 这里在来简单了解一下 RabbitMq 的工作原理


图一 :

在这里插入图片描述


图二 :

在这里插入图片描述


图三 :

在这里插入图片描述

2 RabbitMQ 安装


环境: Linux 的 CentOS 7

RabbitMQ 安装地址

在这里插入图片描述


RabbitMqErlang 版本对照 : RabbitMQ Erlang Version Requirements — RabbitMQ


找到了自己要下载的 Erlang 版本 下面就来下载 : rabbitmq/erlang - Packages · packagecloud


在这里插入图片描述


安装包有了,下面我们就来安装 , 这里先将 这两个安装包传输到 Linux 服务器 上 .


这里我传输用到的工具是 xftp

图一 :

在这里插入图片描述


图二 :

在这里插入图片描述


安装包传输完成后 就来安装 Erlang


进入到 /usr/local/rabbitmq 目录 解压缩 Erlang

cd /usr/local/rabbitmq

rpm -ivh erlang-23.2.7-2.el7.x86_64.rpm

注意 : 这里如果使用 没有权限的用户 安装是 安装不下来的 需要 像 root 用户 申请权限 , 

使用 sudo rpm -ivh erlang-23.2.7-2.el7.x86_64.rpm 即可  --> 这里会出现让你输入 管理员密码输入即可 

命令解释 : 

sudo: sudo 是一个用于以超级用户(root)身份执行命令的命令。在执行需要管理员权限的操作时,使用 sudo 可以提升当前用户的权限。

rpm: rpm 是 Linux 中一个常用的包管理器,用于管理安装、升级、查询和删除软件包。它用于执行与 RPM 软件包相关的操作。

-ivh: 这是 rpm 命令的选项参数。具体含义如下:

-i: 安装指定的 RPM 软件包。
-v: 在执行安装过程时显示详细的输出信息。
-h: 在显示进度条时使用哈希字符(#),提供更直观的进度显示。



结果 : 

[root@master rabbitmq]# rpm -ivh erlang-23.2.7-2.el7.x86_64.rpm

警告:erlang-23.2.7-2.el7.x86_64.rpm: 头V4 RSA/SHA1 Signature, 密钥 ID 6026dfca: NOKEY

准备中...                          ################################# [100%]

正在升级/安装...
   1:erlang-23.2.7-2.el7               ################################# [100%]
   
安装完后 可以输入 erl -v  , 如果出现 erlang 的版本好就说明安装成功了

结果 : 

[root@localhost rabbitmq]# erl -v

Erlang/OTP 23 [erts-11.1.8] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe]

Eshell V11.1.8  (abort with ^G)
1>


到此Erlang 就安装完了,下面我们来安装 RabbitMq

输入: rpm -ivh rabbitmq-server-3.8.35-1.el8.noarch.rpm

同理如果没有权限 可以 在前面 加上 sudo , 如果嫌弃每次加上 sudo 麻烦 可以直接使用 sudo su 直接切换到 超级用户(root) 

过程 : 
[root@master rabbitmq]# rpm -ivh rabbitmq-server-3.8.35-1.el8.noarch.rpm

警告:rabbitmq-server-3.8.35-1.el8.noarch.rpm: 头V4 RSA/SHA256 Signature, 密钥 ID 6026dfca: NOKEY
准备中...                          ################################# [100%]
正在升级/安装...
   1:rabbitmq-server-3.8.35-1.el8     ################################# [100%]

安装完 RabbitMQ 后我们就可以启动 RabbitMQ

# 启动服务
systemctl start rabbitmq-server

# 查看服务状态
systemctl status rabbitmq-server


在未启动 rabbitmq时 使用 systemctl status rabbitmq-server命令查看服务状态

[root@localhost rabbitmq]# systemctl status rabbitmq-server
● rabbitmq-server.service - RabbitMQ broker
   Loaded: loaded (/usr/lib/systemd/system/rabbitmq-server.service; disabled; vendor preset: disabled)
   Active: inactive (dead) # 可以看到这里显示 dead 说明是 死的 即没有启动服务

920 17:02:42 localhost.localdomain rabbitmq-server[3006]: /var/log/rabbitmq/rabbit@localhost_upgrade.log
920 17:02:42 localhost.localdomain rabbitmq-server[3006]: Config file(s): (none)
920 17:02:44 localhost.localdomain rabbitmq-server[3006]: Starting broker... completed with 4 plugins.
920 17:02:44 localhost.localdomain systemd[1]: Started RabbitMQ broker.
920 22:34:02 localhost.localdomain systemd[1]: Stopping RabbitMQ broker...
920 22:34:02 localhost.localdomain rabbitmqctl[11894]: Shutting down RabbitMQ node rabbit@localhost running at PID 3006
920 22:34:02 localhost.localdomain rabbitmq-server[3006]: Gracefully halting Erlang VM
920 22:34:02 localhost.localdomain rabbitmqctl[11894]: Waiting for PID 3006 to terminate
920 22:34:07 localhost.localdomain rabbitmqctl[11894]: RabbitMQ node rabbit@localhost running at PID 3006 successfully shut down
920 22:34:08 localhost.localdomain systemd[1]: Stopped RabbitMQ broker.
[root@localhost rabbitmq]# 


启动 rabbitmq ,后再 查看 服务状态

[root@localhost rabbitmq] systemctl start rabbitmq-server # 启动 rabbitmq 服务 
[root@localhost rabbitmq] 
[root@localhost rabbitmq] 
[root@localhost rabbitmq] systemctl status rabbitmq-server
● rabbitmq-server.service - RabbitMQ broker
   Loaded: loaded (/usr/lib/systemd/system/rabbitmq-server.service; disabled; vendor preset: disabled)
   Active: active (running) since 三 2023-09-20 22:36:29 CST; 7s ago # 可以看到这里的状态显示 running 说明正在运行
 Main PID: 11976 (beam.smp)
   Status: "Initialized"
    Tasks: 28
   CGroup: /system.slice/rabbitmq-server.service
           ├─11976 /usr/lib64/erlang/erts-11.1.8/bin/beam.smp -W w -MBas ageffcbf -MHas ageffcbf -MBlmbcs 512 -MHlmbcs 512 -MMmcs 30 -P 1048576 -t 5...
           ├─11994 erl_child_setup 32768
           ├─12021 /usr/lib64/erlang/erts-11.1.8/bin/epmd -daemon
           ├─12046 inet_gethost 4
           └─12047 inet_gethost 4

920 22:36:27 localhost.localdomain rabbitmq-server[11976]: TLS Library: OpenSSL - OpenSSL 1.0.2k-fips  26 Jan 2017
920 22:36:27 localhost.localdomain rabbitmq-server[11976]: Doc guides:  https://rabbitmq.com/documentation.html
920 22:36:27 localhost.localdomain rabbitmq-server[11976]: Support:     https://rabbitmq.com/contact.html
920 22:36:27 localhost.localdomain rabbitmq-server[11976]: Tutorials:   https://rabbitmq.com/getstarted.html
920 22:36:27 localhost.localdomain rabbitmq-server[11976]: Monitoring:  https://rabbitmq.com/monitoring.html
920 22:36:27 localhost.localdomain rabbitmq-server[11976]: Logs: /var/log/rabbitmq/rabbit@localhost.log
920 22:36:27 localhost.localdomain rabbitmq-server[11976]: /var/log/rabbitmq/rabbit@localhost_upgrade.log
920 22:36:27 localhost.localdomain rabbitmq-server[11976]: Config file(s): (none)
920 22:36:29 localhost.localdomain rabbitmq-server[11976]: Starting broker... completed with 4 plugins.
920 22:36:29 localhost.localdomain systemd[1]: Started RabbitMQ broker.
[root@localhost rabbitmq] 


关于 RabbitMq 的其他命令

# 开机自启动

systemctl enable rabbitmq-server
# 停止服务
systemctl stop rabbitmq-server

# 重启服务
systemctl restart rabbitmq-server


这里关于 RabbitMq的几个命令看完,下面我们来安装一下 RabbitMq 为我们提供的一个管理端页面 .

在这里插入图片描述

安装客户端软件
rabbitmq-plugins enable rabbitmq_management

重启RabbitMq 服务
systemctl restart rabbitmq-server


注意 : 这里开放 15672 端口号 ,因为RabbitMq 默认的访客端口号为 15672


如果开放呢可以采取关闭防火墙的方式 ,如果关闭防火墙

$ sudo systemctl stop firewalld    # 停止 firewalld 服务
$ sudo systemctl disable firewalld # 禁止开机启动 firewalld

这里可以通过 $ sudo firewall-cmd --state 命令查看 防火墙是否真的关闭 , 如果输出结果为 : no running 则说明 防火墙已成功停止


安装完管理界面,我们还需要配置一个管理员用户 ,要不然无法登录管理页面 , 无法进行管理操作,无法查看系统状态 ,另外 rabbitmq 有一个默认的账号密码 guest , 用这个登录 会出现权限问题 (仅限于本机进行访问也就是rabbitmq服务器所在的机器) .


这里想要打开rabbitmq 的管理页面在搜索框中输入 : http://rabbitmq所在的ip地址:15672 即可


创建管理员用户 :

# 创建账号和密码
rabbitmqctl add_user 用户名 密码

# 设置用户角色
rabbitmqctl set_user_tags 用户名 角色

四种角色 :

administrator:可以登录控制台、查看所有信息、并对rabbitmq进行管理

monToring:监控者;登录控制台,查看所有信息

policymaker:策略制定者;登录控制台指定策略

managment:普通管理员;登录控制


# 为用户添加资源权限,添加配置、写、读权限
# set_permissions [-p <vhostpath>] <user> <conf> <write> <read>

rabbitmqctl set_permissions -p "/" y(将 y 替换成我们自己创建的用户) ".*" ".*" ".*"
// Make sure to add code blocks to your code group


图:

在这里插入图片描述


到此关于rabbitmq 环境 安装就安装完成了,下面我们来学习一下 rabbitmq 的相关操作.

3. RabbitMQ 入门操作


这里我们通过 写一个 Hello World 的程序,来入门 RabbitMQ .


大致操作: 使用 java 创建 生产者和消费者 ,通过生产者生产者生产消息 发送到 Rabbitmq 服务器 , 然后让 消费者 去 rabbitmq 服务器拿取消息 进行消费.

在这里插入图片描述


特别注意 : 这里 java 连接 rabbitmq 时需要 Linux 开放 5672 端口 , 否者会超时 , 之前 web界面的 端口号是 15672.


简单看完流程 : 下面就来进行编码

3.1 添加依赖


这里先创建一个 Maven 程序 ,在 pom.xml 添加下面的依赖


    <dependencies>
        <!--rabbitmq 依赖客户端-->
        <dependency>
            <groupId>com.rabbitmq</groupId>
            <artifactId>amqp-client</artifactId>
            <version>5.8.0</version>
        </dependency>
        <!--操作文件流的一个依赖-->
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.6</version>
        </dependency>
    </dependencies>

3.2 生产者代码


创建一个类代表生产者,生产消息并发送到 rabbitmq 服务器的队列中

package org.example.one;


// 生产者


import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import javafx.util.Callback;

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

public class Producer {

    // 队列名称
    public static final String QUEUE_NAME = "mu";

    // 生产消息并发送到 rabbitmq 上
    public static void main(String[] args) throws IOException, TimeoutException {
        // 1. 创建一个连接工厂
        ConnectionFactory factory = new ConnectionFactory();

        // 2. 指定  rabbitmq 服务 所在的 ip 和 管理员用户名 和密码

        // ip
        factory.setHost("192.168.80.129");

        // 用户名
        factory.setUsername("mu");

        // 密码
        factory.setPassword("1234");

        // 3. 创建连接 -- newConnection 方法需要抛出异常
        Connection connection = factory.newConnection();

        // 4. 获取信道 : 使用信道可以减少网络开销、提高吞吐量,并提供灵活的流量控制,从而改善 RabbitMQ 的性能和可扩展性。虽然每个信道都会增加一些内存和CPU的开销,
        // 但与为每条消息建立新连接相比,整体系统的开销会更小。因此,在大多数情况下,使用信道是更合适和有效的做法。
        Channel channel = connection.createChannel();


        /**
         * 生产出一个队列 , 使用 queueDeclare 方法
         * 主要参数:
         * 1. queue:要创建或声明的队列名称。如果没有指定任何名称,则系统将随机生成一个唯一的名称并返回。
         *    如果已有同名队列存在,则使用该队列的其他参数(如持久化、排他性等)。
         * 2. durable:如果为 True,则表示该队列是持久化的。这意味着在 RabbitMQ Broker 重启后,该队列和其中的消息仍将存在。
         * 3. exclusive:如果为 True,则表示该队列是排他的。这意味着该队列只能由申明它的连接访问,其他连接不能访问。当连接关闭后,该队列也将被删除。
         * 4. auto_delete:如果为 True,则表示该队列是自动删除的。这意味着当该队列没有任何消费者时,自动删除该队列。
         * 5. arguments:可选参数列表,用于设置队列的特殊参数。
         */


        //5. 这里设置了 队列名称 , 不持久化 , 消息不共享,只让一个消费者消费 , 无其他参数
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);

        //6. 创建消息
        String message = "Hello World";

        /**
         * 7. 发送消息 需要使用到 basicPublish方法
         * 1.发送到哪个交换机
         * 2.路由的key值是哪个本次是队列的名称
         * 3.其他参数信息
         * 4.发送消息的消息体
         */

        channel.basicPublish("",QUEUE_NAME,null,message.getBytes());

        // 到此 消息发送完成
        System.out.println("生产者生产完消息并发送");
    }

}


执行生产者代码后我们可以在 rabbitmq 管理页面看到 消息存放的 队列

在这里插入图片描述

3.3 消费者代码


创建一个类来表示消费者 ,从 rabbitmq 的队列中读取消息 ,进行消费

这里先来列举出即将要使用到的方法 :

通过 basicConsume 方法接受消息 , 这里 basicConsume 方法 第三个和第四个参数都是接口,所以需要实现该接口的方法

    channel.basicConsume(队列名字/String, 是否自动签收/boolean, 消费时的回调/接口类, 无法消费的回调/接口类);    

简单介绍一下参数: 
         1.消费哪个队列
         2.消费成功之后是否要自动应答true:代表自动应答false:代表手动应答
         3.消费者未成功消费的回调
         4.消费者取消消费的回调


了解完要用到的 api 后 ,我们来写 消费者代码

package org.example.one;

// 消费者

import com.rabbitmq.client.*;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeoutException;

public class Consumer {

    public static final String QUEUE_NAME = "mu";

    public static void main(String[] args) throws IOException, TimeoutException {
        // 1. 创建一个连接工厂
        ConnectionFactory factory = new ConnectionFactory();

        // 2. 指定  rabbitmq 服务 所在的 ip 和 管理员用户名 和密码

        // ip
        factory.setHost("192.168.80.129");

        // 用户名
        factory.setUsername("mu");

        // 密码
        factory.setPassword("1234");

        // 3. 创建连接 -- newConnection 方法需要抛出异常
        Connection connection = factory.newConnection();

        Channel channel = connection.createChannel();

        // 4. 声明接收消息的回调

        DeliverCallback deliverCallback = (consumerTag, message) -> {
            System.out.println("接收到消息, 消息为: " + new String(message.getBody(), StandardCharsets.UTF_8));
        };

        //50 声明 取消消费消息的回调
        CancelCallback cancelCallback = consumerTag ->{
            System.out.println("消息消费被中断");
        };

        /**
         * 消费者消费消息
         * 1.消费哪个队列
         * 2.消费成功之后是否要自动应答true:代表自动应答false:代表手动应答
         * 3.消费者未成功消费的回调
         * 4.消费者取消消费的回调
         */
        channel.basicConsume(QUEUE_NAME,true,deliverCallback,cancelCallback);

    }
}


到此消费者的代码就写完了,运行一下看看效果

在这里插入图片描述


入门案例看完我们就来学一下 Work Queues (任务队列)

4. Work Queues


引用:

Work Queues 是工作队列(又称任务队列)的主要思想是避免立即执行资源密集型任务,而不得不等待它完成。相反我们安排任务在之后执行。我们把任务封装为消息并将其发送到队列。在后台运行的工作进程将弹出任务并最终执行作业。当有多个工作线程时,这些工作线程将一起处理这些任务。


这里抛出一个 Work Queues 是为了说明 rabbitmq 是通过轮询消费的方式 来处理消息的 , 当生产者生产了很多消息,并发送到工作队列中的消息队列中 ,多个消费者 会按顺序的方式依次去队列中取消息进行消费 .


图:

在这里插入图片描述


代码案例 :


上面我们写 消费者和生产者的代码 会发现有一些代码是重复的,我们可以把这些重复的代码抽出来封装成一个类



重复的代码: 

   // 1. 创建一个连接工厂
        ConnectionFactory factory = new ConnectionFactory();

        // 2. 指定  rabbitmq 服务 所在的 ip 和 管理员用户名 和密码

        // ip
        factory.setHost("192.168.80.129");

        // 用户名
        factory.setUsername("mu");

        // 密码
        factory.setPassword("1234");

        // 3. 创建连接 -- newConnection 方法需要抛出异常
        Connection connection = factory.newConnection();

        Channel channel = connection.createChannel();

封装到一个类中, 下次写道一样的代码直接调用方法即可 
    
    
public class RabbitMQUtils {
    public static Channel getChannel() throws IOException, TimeoutException {
        // 1. 创建一个连接工厂
        ConnectionFactory factory = new ConnectionFactory();

        // 2. 指定  rabbitmq 服务 所在的 ip 和 管理员用户名 和密码

        // ip
        factory.setHost("192.168.80.129");

        // 用户名
        factory.setUsername("mu");

        // 密码
        factory.setPassword("1234");

        // 3. 创建连接 -- newConnection 方法需要抛出异常
        Connection connection = factory.newConnection();

        Channel channel = connection.createChannel();

        return channel;
    }
}


封装完 RabbitMQUtils ,下面就来完成 轮询的代码案例 , 这里先来创建两个消费者

在这里插入图片描述


这里的代码与之前的 消费者差不多,差别就在几个 打印语句

package org.example.two;

import com.rabbitmq.client.CancelCallback;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.DeliverCallback;
import org.example.utils.RabbitMQUtils;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeoutException;

public class Work1 {

    // 队列名
    public static final String QUEUE_NAME = "mu";

    public static void main(String[] args) throws IOException, TimeoutException {
        Channel channel = RabbitMQUtils.getChannel();

        /**
         * DeliverCallback 的两个参数
         * 1. deliveryTag 参数:deliveryTag 是一个唯一标识符,用于标识和跟踪消息的传递状态。
         * 每个消息都会被分配一个唯一的 deliveryTag。在消息确认时,可以使用 deliveryTag 来指定确认的是哪条消息。
         *
         * 2. message 参数:message 是一个 AMQP 消息对象,包含从队列中获取的消息内容以及相应的属性信息。
         * 通过 message 参数,可以访问消息的内容、标签、路由 key 等相关属性。可以根据需要对消息进行解析和处理。
         */

        // 接受消息的回调
        DeliverCallback deliverCallback = (consumerTag, message) -> {
            System.out.println("消费者1 接收到消息: " + new String(message.getBody(), StandardCharsets.UTF_8));
        };

        // 取消消费消息
        CancelCallback cancelCallback = consumerTag -> {
            System.out.println(consumerTag + "消费者1 取消消费消息");
        };

        // 消息的接受
        channel.basicConsume(QUEUE_NAME, true, deliverCallback, cancelCallback);
    }
}


这里消费2 和消费者1 类似 ,区别在于 接受消息和取消接受消息的 打印语句 复制一份消费者1 即可


消费者就绪,下面来写一个生产者来大量生产消息

package org.example.two;

import com.rabbitmq.client.Channel;
import org.example.utils.RabbitMQUtils;

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

public class Producer {

    //队列的名称
    public static final String QUEUE_NAME = "mu";

    public static void main(String[] args) throws IOException, TimeoutException {
        // 获取信道
        Channel channel = RabbitMQUtils.getChannel();

        // 队列的声明
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);

        // 发送消息
        for (int i = 1; i < 11; i++) {
            String message = "——— " + i + " ———";

            // 发送消息
            channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
        }

    }
}


生产者消费者都就绪了,下面启动来看看效果:

在这里插入图片描述


轮询案例看完,下面来学习一下如何通过 rabbitmq 管理端网页 创建队列

5. 管理端页面创建队列

在这里插入图片描述

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

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

相关文章

Axure设计之引入ECharts图表

ECharts是一款基于JavaScript的可视化图表库&#xff0c;它提供了丰富的图表类型和交互功能&#xff0c;可以轻松地创建各种类型的图表&#xff0c;如折线图、柱状图、饼图、散点图等。 想要通过Axure实现ECharts示例中的某些图表效果&#xff0c;单纯靠Axure自带的功能是很难实…

C# 实现数独游戏

1.数独单元 public struct SudokuCell{public SudokuCell() : this(0, 0, 0){}public SudokuCell(int x, int y, int number){X x; Y y; Number number;}public int X { get; set; }public int Y { get; set; }public int Number { get; set; }} 2.数独创建 public class …

JVM 参数详解

GC有两种类型&#xff1a;Scavenge GC 和Full GC 1、Scavenge GC 一般情况下&#xff0c;当新对象生成&#xff0c;并且在Eden申请空间失败时&#xff0c;就会触发Scavenge GC&#xff0c;堆的Eden区域进行GC&#xff0c;清除非存活对象&#xff0c;并且把尚且存活的对象移动到…

mysql 命令

1.以root身份登录MySQL服务器 mysql -u root -p 2.输入root用户密码 显示命令 1. 显示数据库列表 show databases; 刚开始时才两个数据库&#xff1a;mysql和test。mysql库很重要它里面有MYSQL的系统信息&#xff0c;我们改密码和新增用户&#xff0c;实际上就是用这个库进…

AUTOSAR词典:CAN驱动Mailbox配置技术要点全解析

AUTOSAR词典&#xff1a;CAN驱动Mailbox配置技术要点全解析 前言 首先&#xff0c;请问大家几个小小问题&#xff0c;你清楚&#xff1a; AUTOSAR框架下的CAN驱动关键词定义吗&#xff1f;是不是有些总是傻傻分不清楚呢&#xff1f;CAN驱动Mailbox配置过程中有哪些关键配置参…

操作系统--------调度算法篇

目录 一.先来先服务调度算法&#xff08;FCFS&#xff09; 二.短作业优先调度算法&#xff08;SJF&#xff09; 2.1.SJF调度算法缺点 三.优先级调度算法 3.1优先级调度算法的类型 1.非抢占优先级调度算法 2.抢占优先级调度算法 3.2优先级的类型 3.1静态优先级 3.2动态…

2101. 引爆最多的炸弹;752. 打开转盘锁;1234. 替换子串得到平衡字符串

2101. 引爆最多的炸弹 核心思想&#xff1a;枚举BFS。枚举每个炸弹最多引爆多少个炸弹&#xff0c;对每个炸弹进行dfs&#xff0c;一个炸弹能否引爆另一个炸弹是两个炸弹的圆心距离在第一个炸弹的半径之内。 752. 打开转盘锁 核心思想:典型BFS&#xff0c;就像水源扩散一样&a…

MySQL数据库 -- 入门篇

1. MySQL概述 1.1 数据库相关概念 三个概念&#xff1a;数据库、数据库管理系统、SQL。 目前主流的关系型数据库管理系统的市场占有率排名如下&#xff1a; Oracle&#xff1a;大型的收费数据库&#xff0c;Oracle公司产品&#xff0c;价格昂贵。MySQL&#xff1a;开源免费…

力扣刷题-数组-螺旋矩阵

模拟过程&#xff0c;但却十分考察对代码的掌控能力。 重点&#xff1a;循环不变量原则&#xff01; 第一条原则&#xff1a; 模拟顺时针画矩阵的过程&#xff1a; 填充上行从左到右填充右列从上到下填充下行从右到左填充左列从下到上 由外向内一圈一圈这么画下去。 第二条原…

【探索Linux世界|中秋特辑】--- 倒计时和进度条的实现与演示

个人主页&#xff1a;兜里有颗棉花糖 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 兜里有颗棉花糖 原创 收录于专栏【Linux专栏】&#x1f388; 本专栏旨在分享学习Linux的一点学习心得&#xff0c;欢迎大家在评论区讨论&#x1f48c; 演示环境&#xff1…

PageHelp插件在复杂sql下引起的Having无法识别错误及其解决方案

1: 问题出现的场景 系统中有一个复杂SQL内嵌套了多个子查询.在改动时需要将SQL的最后一行加上having来做额外的过滤处理. 添加完having语句后发现SQL能够正常执行就直接将代码提交到了测试环境.结果在测试环境报错Unknown column ‘xxx‘ in ‘having clause. 2: 分析问题 1…

公众号留言功能怎么打开?有什么条件?

为什么公众号没有留言功能&#xff1f;2018年2月12日&#xff0c;TX新规出台&#xff1a;根据相关规定和平台规则要求&#xff0c;我们暂时调整留言功能开放规则&#xff0c;后续新注册帐号无留言功能。这就意味着2018年2月12日号之后注册的公众号不论个人主体还是组织主体&…

十四、MySql的用户管理

文章目录 一、用户管理二、用户&#xff08;一&#xff09;用户信息&#xff08;二&#xff09;创建用户1.语法&#xff1a;2.案例&#xff1a; &#xff08;三&#xff09; 删除用户1.语法&#xff1a;2.示例&#xff1a; &#xff08;四&#xff09;修改用户密码1.语法&#…

ps丢失d3dcompiler_47.dll怎么办,这四个方法都能解决

在当今的信息化社会&#xff0c;电脑已经成为我们生活和工作中不可或缺的一部分。然而&#xff0c;随着软件技术的不断发展&#xff0c;电脑在使用过程中也难免会遇到各种问题。其中&#xff0c;缺失d3dcompiler_47.dll文件是一个常见的问题。本文将为大家介绍如何修复电脑出现…

Python JS逆向之Ku狗,实现搜索下载功能(附源码)

今天用Python来实现一下酷狗JS逆向&#xff0c;实现搜索下载功能 1、环境使用 Python 3.8Pycharm 2、模块使用 import hashlib --> pip install hashlib import prettytable as pt --> pip install prettytable import requests --> pip install requests import…

深度学习从入门到入土

1. 数据操作 N维数组样例 N维数组是机器学习和神经网络的主要数据结构 0-d 一个类别&#xff1a; 1.0 1-d 一个特征向量(一维矩阵)&#xff1a;[1.0, 2.7, 3.4] 2-d 一个样本-特征矩阵-(二维矩阵) 3-d RGB图片 &#xff08;宽x高x通道&#xff09;- 三维数组 4-d 一个RGB…

selenium自动化测试入门,一篇足矣

Selenium是一个基于浏览器的自动化测试工具&#xff0c;它提供了一种跨平台、跨浏览器的端到端的web自动化解决方案。 Selenium是用于自动化控制浏览器做各种操作&#xff0c;打开网页&#xff0c;点击按钮&#xff0c;输入表单等等&#xff0c;可以模拟各种人工操作浏览器的功…

共享WiFi贴项目怎么实施与运营,微火为你提供高效解答!

共享WiFi贴是一项有前景的商业项目&#xff0c;不仅可以满足用户对网络的需求&#xff0c;还可以为创业者带来盈利的机会。那么&#xff0c;我们来看看如何有效地开展共享WiFi贴项目。 最重要的是选择合适的位置。共享WiFi贴项目的成功与否很大程度上取决于位置选择。优先选择人…

web前端之float布局与flex布局

float布局 <style>.nav {overflow: hidden;background-color: #6adfd0; /* 导航栏背景颜色 */}.nav a {float: left;display: block;text-align: center;padding: 14px 16px;text-decoration: none;color: #000000; /* 导航栏文字颜色 */}.nav a:hover {background-col…

示例-安装office2016图文教程简体中文下载安装包

目录 简介 步骤 总结 简介 Office 2016作为一款办公软件套件&#xff0c;下载和安装 都具有许多令人印象深刻的特点。让我来为你介绍一下&#xff1a;Office 2016注重实现跨平台的一致性。无论你是在Windows、Mac、iOS还是Android上使用Office&#xff0c;你都可以享受到相似…