【ZooKeeper】ZooKeeper快速入门

news2024/9/29 1:16:50

1.ZooKeeper的概念


  • ZookeeperApache Hadoop 项目下的一个子项目,是一个树形目录服务。
  • Zookeeper 翻译过来就是动物园管理员,它是用来管 Hadoop(大象)、Hive(蜜蜂)、Pig(小猪)的管理员。
  • Zookeeper 是一个分布式的、开源的分布式应用程序的协调服务。
  • Zookeeper 提供的主要功能包括:配置管理、分布式锁、集群管理

Zookeeper提供的功能


2.ZooKeeper的安装配置


3.ZooKeeper命令操作


3.1 ZooKeeper数据模型


  • ZooKeeper 是一个树形目录服务,其数据模型和 Unix 的文件系统目录树很类似,拥有一个层次化结构。
  • 每一个节点都被称为: ZNode
  • 每个节点由三部分组成:节点的数据、节点的子节点、节点的状态信息
  • 节点可以分为四大类(节点的类型在创建时即被确定且不能修改):
    • PERSISTENT 持久化节点
    • EPHEMERAL 临时节点 :-e
    • PERSISTENT_SEQUENTIAL 持久化顺序节点 :-s
    • EPHEMERAL_SEQUENTIAL 临时顺序节点 :-es
  • 注意
    • 临时结点:客户端和服务端断开连接后,创建的节点自己删除。临时结点不允许拥有子结点
    • 持久化结点:客户端和服务端断开连接后,创建的节点不删除。只有在客户端显式执行删除操作时才被删除。

Zookeeper树型目录


3.2 ZooKeeper服务端常用命令

启动ZooKeeper服务
./zkServer.sh start
停止ZooKeeper服务
./zkServer.sh stop
查看ZooKeeper服务状态
./zkServer.sh status

3.3 ZooKeeper客户端常用命令


在这里插入图片描述


3.3.1 基本的CRUD

连接ZooKeeper服务端

./zkCli.sh -server ip:port

断开连接

quit

显示指定目录下的节点

ls 目录

创建节点

create /节点path value

获取节点值

get /节点path # 使用get查看节点的状态信息和数据。
stat /节点path # 使用stat只返回节点的状态信息,没有数据。

设置节点值

set /节点path value

删除单个节点

delete /节点path

删除带有子节点的节点

deleteall /节点path

3.3.2 监听器

使用此命令注册的监听器能够在节点的数据发生改变的时候,向客户端发出通知。

get /节点path watch

使用此命令注册的监听器能够在节点的数据或者状态信息发生改变的时候,向客户端发出通知。

stat /节点path watch

能够监听该节点下所有子节点的增加和删除操作

ls/ls2 /节点path watch

3.3.3 创建临时顺序节点

创建临时节点

create -e /节点path value

创建顺序节点

create -s /节点path value

查询节点详细信息

ls -s /节点path

节点详细信息介绍

  • czxid:节点被创建的事务 ID
  • ctime:创建时间
  • mzxid:最后一次被更新的事务 ID
  • mtime:修改时间
  • pzxid:子节点列表最后一次被更新的事务 ID
  • cversion:子节点的版本号
  • dataversion:数据版本号
  • aclversion:权限版本号
  • ephemeralOwner:用于临时节点,代表临时节点的事务 ID,如果为持久节点则为 0
  • dataLength:节点存储的数据的长度
  • numChildren:当前节点的子节点个数

4.ZooKeeper的ACL权限控制


1.概述

  • ZooKeeper 类似文件系统,client 可以创建节点、更新节点、删除节点。
  • ZooKeeperaccess control list 访问控制列表可以控制节点的权限。
  • ACL权限控制,使用 schemeidpermission 来标识,主要涵盖三个方面:
    • 权限模式(scheme):授权的策略
    • 授权的对象(id):授权的对象
    • 权限(permission):授予的权限

2.特性

  • ZooKeeper 的权限控制是基于每个 ZNode 节点,需要对每个节点设置权限。
  • 子节点不会继承父节点的权限,客户端无权访问某节点,但可能可以访问他的子节点。

3.scheme:权限模式

描述方案
world只有一个用户:anyone,代表登录 Zookeeper 的所有人(默认)
ip对客户端使用 IP 地址认证
auth使用已添加认证的用户认证
digest使用 用户名 : 密码 方式认证

4.id:授权对象

  • 授权对象 id 是指:权限赋予的实体
  • 例如:IP地址或用户

5.permission:授予的权限

权限ACL 简写描述
createc可以创建子节点
deleted可以删除子节点(即下一级节点)
readr可以读取节点数据及显示子节点列表
writew可以设置节点数据
admina可以设置节点访问控制列表权限
  • 增、删、查、改、管理权限可以简写为 cdrwa
  • 注意:这5中权限中,delete 是指对子节点的删除权限,其他四种权限指对自身节点的操作权限。

6.授权的相关命令

命令使用方式描述
getAclgetAcl读取ACL权限
setAclsetAcl设置ACL权限
addauthaddauth添加认证用户

7.相关命令
world 授权模式

setAcl <path> world:anyone:<acl>

ip 授权模式

setAcl  <path> ip:<ip>:<acl>

auth 授权模式

addauth digest <user>:<password> # 添加认证用户
setAcl <path> auth:<user>:<acl> # 授权

digest 授权模式

setAcl <path> digest:<user>:<password>:<acl>

5.ZooKeeper JavaAPI操作


5.1 Curator介绍


  • CuratorApache ZooKeeperJava 客户端库。
  • 常见的 ZooKeeper Java API
    • 原生 Java API
    • ZkClient
    • Curator
  • Curator 项目的目标是简化 ZooKeeper 客户端的使用。
  • Curator 最初是 Netfix 研发的,后来捐献了 Apache 基金会,目前是 Apache 的顶级项目。

5.2 使用IDEA创建Maven工程


  • pom.xml
<!-- curator -->
<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-framework</artifactId>
    <version>4.0.0</version>
</dependency>
<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-recipes</artifactId>
    <version>4.0.0</version>
</dependency>

5.3 Curator API的CRUD操作


5.3.1 建立连接

方式一(CuratorTest.java文件)

public class CuratorTest {
    private CuratorFramework client;
    @Test
    public void testConnect() {
        /*
            * @param connectString       连接字符串。zk server 地址和端口 "192.168.2.212:2181,192.168.2.212:2181"
            * @param sessionTimeoutMs    会话超时时间 单位ms
            * @param connectionTimeoutMs 连接超时时间 单位ms
            * @param retryPolicy         重试策略
            */
        // 重试策略
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(3000, 10);

        // 创建连接,构造客户端对象_第一种方式
        client = CuratorFrameworkFactory.newClient("192.168.2.212:2181", 60 * 1000,15 * 1000, retryPolicy);

        // 开启连接
        client.start();
    }
}

方式二(CuratorTest.java文件)

public class CuratorTest {
    private CuratorFramework client;
    @Test
    public void testConnect() {
        // 重试策略
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(3000, 10);

        // 创建连接构造客户端对象_第二种方式:链式编程的方式
        client = CuratorFrameworkFactory.builder()
                .connectString("192.168.2.212:2181")
                .sessionTimeoutMs(60 * 1000)
                .connectionTimeoutMs(15 * 1000)
                .retryPolicy(retryPolicy)
                .build();

        // 开启连接
        client.start();
    }
}

5.3.2 创建节点

CuratorTest.java文件

public class CuratorTest {
    private CuratorFramework client;

    @Before
    public void testConnect() {
        // 重试策略
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(3000, 10);
        
        // 创建连接构造客户端对象_第二种方式:链式编程的方式
        client = CuratorFrameworkFactory.builder()
                .connectString("192.168.2.212:2181")
                .sessionTimeoutMs(60 * 1000)
                .connectionTimeoutMs(15 * 1000)
                .retryPolicy(retryPolicy)
                .build();

        // 开启连接
        client.start();
    }
   
    /* 1.基本创建 */
    @Test
    public void testCreate_1() throws Exception {
        // 如果创建节点,没有指定数据,则默认将当前客户端的ip作为数据存储
        String path = client.create().forPath("/app1");
    }

    /* 2.创建节点,带有数据 */
    @Test
    public void testCreate_2() throws Exception {
        String path = client.create().forPath("/app2", "hehe".getBytes());
    }

    /* 3.设置节点的类型 */
    @Test
    public void testCreate_3() throws Exception {
        // 默认类型:持久化。
        String path = client.create().withMode(CreateMode.EPHEMERAL).forPath("/app3");
    }

    /* 4.创建多级节点 /app1/p1 */
    @Test
    public void testCreate_4() throws Exception {
        // creatingParentsIfNeeded():如果父节点不存在,则创建父节点
        String path = client.create().creatingParentsIfNeeded().forPath("/app4/p1");
    }

    @After
    public void close() {
        if (client != null) {
            client.close();
        }
    }
}

5.3.3 查询节点

CuratorTest.java文件

@Test
public void testGet_1() throws Exception {
    //1.查询数据:get
    byte[] data = client.getData().forPath("/app1");
}

@Test
public void testGet_2() throws Exception {
    // 2.查询子节点: ls
    List<String> path = client.getChildren().forPath("/");
}

@Test
public void testGet_3() throws Exception {
    Stat status = new Stat();
    //3.查询节点状态信息:ls -s
    client.getData().storingStatIn(status).forPath("/app1");
}

5.3.4 修改节点

CuratorTest.java文件

/**
    * 修改数据
    * 1. 基本修改数据:setData().forPath()
    * 2. 根据版本修改: setData().withVersion().forPath()
    * * version 是通过查询出来的。目的就是为了让其他客户端或者线程不干扰我。
    */
@Test
public void testSet() throws Exception {
    client.setData().forPath("/app1", "itcast".getBytes());
}

@Test
public void testSetForVersion() throws Exception {
    Stat status = new Stat();

    // 查询节点状态信息:ls -s
    client.getData().storingStatIn(status).forPath("/app1");

    // 查询出来的版本信息
    int version = status.getVersion();
    
    client.setData().withVersion(version).forPath("/app1", "heheda".getBytes());
}

5.3.5 删除节点

CuratorTest.java文件

/**
    * 删除节点
    * 1. 删除单个节点:delete().forPath("/app1");
    * 2. 删除带有子节点的节点:delete().deletingChildrenIfNeeded().forPath("/app1");
    * 3. 必须成功的删除:为了防止网络抖动。本质就是重试。  client.delete().guaranteed().forPath("/app2");
    * 4. 回调:inBackground
    *
    * @throws Exception
    */

@Test
public void testDelete_1() throws Exception {
    // 1.删除单个节点
    client.delete().forPath("/app1");
}

@Test
public void testDelete_2() throws Exception {
    // 2.删除带有子节点的节点
    client.delete().deletingChildrenIfNeeded().forPath("/app4");
}

@Test
public void testDelete_3() throws Exception {
    // 3.必须成功的删除
    client.delete().guaranteed().forPath("/app2");
}

@Test
public void testDelete4() throws Exception {
    // 4.回调
    client.delete().guaranteed().inBackground(new BackgroundCallback() {
        @Override
        public void processResult(CuratorFramework client, CuratorEvent event) throws Exception {
            System.out.println(event);
        }
    }).forPath("/app1");
}

5.4 Watch事件监听


5.4.1 Watch监听的概念

Watch 事件监听

  • ZooKeeper 允许用户在指定节点上注册一些 Watcher,并且在一些特定事件触发的时候,ZooKeeper 服务端会将事件通知到感兴趣的客户端上去,该机制是 ZooKeeper 实现分布式协调服务的重要特性。
  • ZooKeeper 中引入了 Watcher 机制来实现了发布/订阅功能,能够让多个订阅者同时监听某一个对象,当一个对象自身状态变化时,会通知所有订阅者。
  • Curator 引入了 Cache 来实现对 ZooKeeper 服务端事件的监听。
  • ZooKeeper 提供了三种 Watcher
    • NodeCache:只是监听某一个特定的节点
    • PathChildrenCache:监控—个 ZNode 的子节点.
    • TreeCache:可以监控整个树上的所有节点,类似于 PathChildrenCacheNodeCache 的组合

5.4.2 NodeCache

CuratorWatcherTest.java

public class CuratorWatcherTest {
    private CuratorFramework client;

    @Before
    public void testConnect() {
        // 重试策略
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(3000, 10);

        client = CuratorFrameworkFactory.builder()
                .connectString("192.168.2.212:2181")
                .sessionTimeoutMs(60 * 1000)
                .connectionTimeoutMs(15 * 1000)
                .retryPolicy(retryPolicy)
                .build();

        // 开启连接
        client.start();
    }

    @After
    public void close() {
        if (client != null) {
            // 关闭连接
            client.close();
        }
    }

    /**
        * NodeCache给指定一个节点注册监听器
        */
    @Test
    public void testNodeCache() throws Exception {
        // 1.创建 NodeCache 对象
        final NodeCache nodeCache = new NodeCache(client, "/app1");
        // 2.注册监听
        nodeCache.getListenable().addListener(new NodeCacheListener() {
            @Override
            public void nodeChanged() throws Exception {
                System.out.println("节点变化了~");
                // 获取修改节点后的数据
                byte[] data = nodeCache.getCurrentData().getData();
                System.out.println("新数据:" + new String(data));
            }
        });

        // 3.开启监听
        nodeCache.start(true);
        
        while (true) {

        }
    }
}

5.4.3 PathChildrenCache

CuratorWatcherTest.java

/**
    * PathChildrenCache监听某个节点的所有子节点
    */

@Test
public void testPathChildrenCache() throws Exception {
    // 1.创建监听对象
    PathChildrenCache pathChildrenCache = new PathChildrenCache(client, "/app2", true);

    // 2. 绑定监听器
    pathChildrenCache.getListenable().addListener(new PathChildrenCacheListener() {
        @Override
        public void childEvent(CuratorFramework client, PathChildrenCacheEvent event) throws Exception {
            System.out.println("子节点变化了~");
            System.out.println(event);
            // 监听子节点的数据变更,并且拿到变更后的数据。
            // 1.获取类型
            PathChildrenCacheEvent.Type type = event.getType();
            // 2.判断类型是否是update
            if (type.equals(PathChildrenCacheEvent.Type.CHILD_UPDATED)) {
                System.out.println("数据变了!!!");
                byte[] data = event.getData().getData();
                System.out.println(new String(data));
            }
        }
    });
    // 3. 开启监听
    pathChildrenCache.start();

    while (true) {

    }
}

5.4.4 TreeCache

CuratorWatcherTest.java

/**
    * TreeCache监听某个节点自己和所有子节点
    */

@Test
public void testTreeCache() throws Exception {
    // 1. 创建监听器
    TreeCache treeCache = new TreeCache(client, "/app2");

    // 2. 注册监听
    treeCache.getListenable().addListener(new TreeCacheListener() {
        @Override
        public void childEvent(CuratorFramework client, TreeCacheEvent event) throws Exception {
            System.out.println("节点变化了");
            System.out.println(event);
        }
    });

    // 3. 开启监听
    treeCache.start();

    while (true) {

    }
}

5.5 分布式锁


分布式锁

  • 在我们进行单机应用开发,涉及并发同步的时候,我们往往采用 synchronized 或者 Lock 的方式来解决多线程间的代码同步问题,这时多线程的运行都是在 同一个JVM 之下,没有任何问题。
  • 但是当我们的应用是分布式集群工作的情况下,属于 多JVM下的工作环境,跨JVM之间已经无法通过多线程的锁解决同步问题。
  • 那么就需要一种更加高级的锁机制,来处理种跨机器的进程之间的数据同步问题——这就是分布式锁。

分布式锁介绍


ZooKeeper分布式锁原理

  • 核心思想:当客户端要获取锁,则创建节点,使用完锁,则删除该节点。
  • 客户端获取锁时,在 lock 节点下创建临时顺序节点
  • 然后获取 lock 下面的所有子节点,客户端获取到所有的子节点之后,如果发现自己创建的子节点序号最小,那么就认为该客户端获取到了锁。使用完锁后,将该节点删除。
  • 如果发现自己创建的节点并非 lock 所有子节点中最小的,说明自己还没有获取到锁。此时客户端需要找到比自己小的那个节点,同时对其注册事件监听器,监听删除事件。
  • 如果发现比自己小的那个节点被删除,则客户端的 Watcher 会收到相应删除事件通知,此时再次判断自己创建的节点:
    • 是否是 lock 子节点中序号最小的,如果是则获取到了锁;
    • 如果不是,则重复以上步骤,继续获取到比自己小的一个节点,并注册监听。

分布式锁原理


5.6 案例:模拟12306售票


12306售票


Ticket12306.java

// 以多线程的方式模拟卖票。
public class Ticket12306 implements Runnable{
    private int tickets = 10; // 数据库的票数

    private InterProcessMutex lock ; // 分布式可重入排它锁

    public Ticket12306() {
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(3000, 10);

        CuratorFramework client = CuratorFrameworkFactory.builder()
                .connectString("192.168.2.212:2181")
                .sessionTimeoutMs(60 * 1000)
                .connectionTimeoutMs(15 * 1000)
                .retryPolicy(retryPolicy)
                .build();

        client.start();

        // 创建锁对象
        lock = new InterProcessMutex(client,"/lock");
    }

    @Override
    public void run() {
        while(true){
            // 获取锁
            try {
                lock.acquire(3, TimeUnit.SECONDS);
                if(tickets > 0){
                    System.out.println(Thread.currentThread() + ":" + tickets);
                    Thread.sleep(100);
                    tickets--;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                // 释放锁
                try {
                    lock.release();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

LockTest.java

public class LockTest {
    public static void main(String[] args) {
        Ticket12306 ticket12306 = new Ticket12306();

        // 创建客户端
        Thread t1 = new Thread(ticket12306,"携程");
        Thread t2 = new Thread(ticket12306,"飞猪");

        t1.start();
        t2.start();
    }
}

6.ZooKeeper集群搭建


6.1 Leader选举


  • Serverid:服务器 ID
    • 比如有三台服务器,编号分别是1,2,3。
    • 编号越大在选择算法中的权重越大。
  • Zxid:数据 ID
    • 服务器中存放的最大数据 ID。值越大说明数据越新,在选举算法中数据越新权重越大。
  • 注意:Leader选举的过程中,如果某台 ZooKeeper获得了超过半数的选票,则此ZooKeeper就可以成为 Leader 了。

6.2 配置集群


  • 在每个 zookeeperdata 目录下创建一个 myid 文件,内容分别是1、2、3 。这个文件就是记录每个服务器的 ID

    echo 1 >/usr/local/zookeeper-cluster/zookeeper-1/data/myid

    echo 2 >/usr/local/zookeeper-cluster/zookeeper-2/data/myid

    echo 3 >/usr/local/zookeeper-cluster/zookeeper-3/data/myid

  • 在每一个 zookeeperzoo.cfg 配置客户端访问端口(clientPort)和集群服务器 IP 列表

    vim /usr/local/zookeeper-cluster/zookeeper-1/conf/zoo.cfg

    vim /usr/local/zookeeper-cluster/zookeeper-2/conf/zoo.cfg

    vim /usr/local/zookeeper-cluster/zookeeper-3/conf/zoo.cfg

    集群服务器IP列表如下

    server.1=192.168.2.212:2881:3881
    server.2=192.168.2.212:2882:3882
    server.3=192.168.2.212:2883:3883
    

    解释:server.服务器ID = 服务器IP地址 : 服务器之间通信端口 : 服务器之间投票选举端口


6.3 模拟集群异常

  • 3个节点的集群,1个从服务器挂掉,集群正常。
  • 3个节点的集群,2个从服务器都挂掉,主服务器也无法运行。因为可运行的机器没有超过集群总数量的半数。
  • 3个节点的集群,当集群中的主服务器挂了,集群中的其他服务器会自动进行选举,然后产生新的 leader。

6.4 ZooKeeper集群角色


  • ZooKeeper集群中有三个角色
    • Leader 领导者:
      • 处理客户端的事务请求(事务请求:增删改请求)
      • 同步数据
    • Follower 跟随者:
      • 处理客户端的非事务请求(非事务请求:查询请求),转发事务请求给 Leader 服务器
      • 参与 Leader 选举投票
    • Observer 观察者:
      • 处理客户端的非事务请求(非事务请求:查询请求),转发事务请求给 Leader 服务器

在这里插入图片描述


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

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

相关文章

CSAPP B站陪跑视频学习笔记

视频地址 How program run- overview 栈(stack) 栈的作用&#xff1a; 局部变量和参数&#xff1a;当函数被调用时&#xff0c;函数的局部变量和参数会被分配到栈上。这是因为这些变量的生命周期通常只限于函数执行期间。 函数调用链&#xff1a;栈用于管理函数调用链&#x…

Thinkphp5x远程执行命令及getshell

一.环境配置 靶场&#xff1a;vulhub/thinkphp/5-rce docker-compose up -d #启动环境 访问靶场&#xff1a; 漏洞利用&#xff1a; 漏洞根本源于 thinkphp/library/think/Request.php 中method⽅法可以进⾏变量覆盖&#xff0c;通 过覆盖类的核⼼属性filter导致rce&#xf…

手把手教你OpenCV实现Canny边缘检测 C++

1,原理 canny边缘检测算子是传统边缘检测算子中最优秀的&#xff0c;canny检测基于下面三个目标&#xff1a; &#xff08;1&#xff09;低错误率。即所有边缘都应该找到&#xff0c;并且没有虚假边缘。 &#xff08;2&#xff09;准确的定位边缘。即检测到的边缘应该接近真…

几款设计师必备的AI抠图软件工具分享给你!

前言 在图像处理领域&#xff0c;抠图是一项基本而关键的技能。传统上&#xff0c;PS是作为抠图的首选工具&#xff0c;但其操作复杂性往往令初学者望而却步。幸运的是&#xff0c;随着AIGC技术的发展&#xff0c;现在有多款AI软件和在线网站能够以更简单、快捷的方式完成抠图…

怎么把图片压缩更小?快捷缩小图片的3个在线工具

现在每天都会需要接触很多的图片&#xff0c;当图片在本地存储到一定数量时会占用大量的内存&#xff0c;并且不利于在网上传输使用&#xff0c;那么有什么方法能够快速压缩图片太大呢&#xff1f;在线改图片大小是一种比较简单的缩小图片的处理方法&#xff0c;在网上也有很多…

【多线程-从零开始-柒】代码案例1—单例模式

单例模式&#xff1a;是一种设计模式 设计模式&#xff0c;类似于“棋谱”&#xff0c;就是固定套路&#xff0c;针对一些特定的场景&#xff0c;给出一些比较好的解决方法只要按照设计模式来写代码&#xff0c;就可以保证代码不会太差&#xff0c;保证代码的下限 设计模式 设…

【性能优化】DNS解析优化

前言 DNS解析过程消耗时间DNS有本地缓存 比如首次访问某站点&#xff0c;会耗费很多时间进行DNS解析&#xff0c;但解析结束后会将ip地址存入本地设备&#xff0c;后续再访问此域名时就会直接从缓存中取。 首次访问页面时&#xff0c;本页面的DNS解析是无法优化的&#xff0…

antv l7简化版demo(含mapbox样例)

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><link rel"stylesheet" href"https://gw.alipayobjects.com/os/rmsportal/PqLCOJpqoOUfuPRacUzE.css" /><title>滑过默认高亮</…

Linux磁盘管理与文件结构(二):实用工具和命令、fdisk分区示例

文章目录 4、查看或管理磁盘分区-fdisk格式选项示例 4、示例&#xff1a;使用 fdisk 命令创建分区需求操作步骤 5、创建文件系统-mkfs格式常用选项示例创建其他类型的文件系统 6、创建文件系统-mkswap格式常用选项示例拓展&#xff1a;关闭和启用交换分区拓展&#xff1a;swap分…

路径规划 | 五种经典算法优化机器人路径规划(Matlab)

目录 效果一览基本介绍程序设计参考文献 效果一览 基本介绍 五种经典算法优化机器人路径规划&#xff0c;算法可任意更换&#xff01;地图可修改&#xff01;Matlab语言 1.分为简单路径规划和复杂路径规划两种情景&#xff0c;采用粒子群算法(PSO)&#xff0c;遗传算法(GA)&am…

[Qt][信号与槽][上]详细讲解

目录 0.Q_OBJECT宏1.信号和槽概述1.信号2.槽3.说明 2.信号和槽的使用1.连接信号和槽2.查看内置信号和槽 0.Q_OBJECT宏 Qt如果要让某个类能够使用信号槽&#xff0c;则必须要在类最开始的地方&#xff0c;写下Q_OBJECT宏 1.信号和槽概述 1.信号 在Qt中&#xff0c;⽤⼾和控件…

如何在银河麒麟操作系统上搭建 Electron (含 Electron 打包指南)

本次教程所用版本 QT版本&#xff1a;5.12 Eletron版本&#xff1a;31.3.1 Electron-packager版本&#xff1a;17.1.2 VScode版本&#xff1a;1.92.0 Node版本&#xff1a;18.19.0 npm版本&#xff1a;10.2.3 前言&#xff1a; 随着跨平台应用开发的需求日益增长&#…

Python基础核心知识点(建议收藏再用)

目录 一、python入门day1-day24 day01-03 编程语言day04 变量day05 垃圾回收机制&#xff08;GC机制&#xff09; 1 引用计数2 标记清除3 分代回收 day05 程序交互与基本运算符day06 可变不可变类型day07 流程控制 1 赋值 2 浅拷贝 copy3 深拷贝 deepcopy day08-10 基本数据类…

ES数据类型学习之keyword和text以及查询条件match和term

es&#xff08;4&#xff09;—查询条件match和term_es match term-CSDN博客 参考文章如上。开始学习 1.text和keyword的学习 直接上官网Text type family | Elasticsearch Guide [7.17] | Elastic Text type family The text family includes the following field types: …

默克索引轻松搞定,快速查找!

在化学、药学和生物科学领域&#xff0c;有一部被广泛认可的权威工具书——《默克索引》&#xff08;Merck Index&#xff09;。自1889年首次出版以来有130多年的历史&#xff0c;《默克索引》一直被视为化学品、药物和生物制品的关键物理、药理和历史信息的最权威、最可靠的来…

Ubuntu22.04安装NVIDIA Driver和CUDA

Ubuntu22.04安装NVIDIA Driver和CUDA 1.安装NVIDIA Driver(1).卸载Ubuntu自带的驱动程序&#xff1a;(2).禁用nouveau:(3).安装相应的NVIDIA Driver: 2.安装CUDA(1).下载并安装CUDA:(2).配置环境变量&#xff1a; 本文记录了在 "Ubuntu22.04"上安装 "NVIDIA D…

百度关掉Ai智能回答(保姆级技术文,解决过程完整记录)

随着AI时代到来&#xff0c;百度也是不肯落于人后&#xff0c;在其搜索页面推出了AI自动回答。点到这里的你想必正因此懊恼&#xff0c;你说它怎么切入不好&#xff0c;非得搞个东西在那一直跳&#xff0c;顶着下面的内容哐哐直跳&#xff0c;你想好好浏览内容还得等它跳消停了…

C++(week15): C++提高:(四)并发服务器架构模型

文章目录 一、五种网络IO模型1.数据传输过程2.两组重要概念3.五种网络IO模型(1)阻塞式IO(2)非阻塞式IO(3)IO多路复用(4)信号驱动IO(5)异步IO 4.五种网络IO模型的对比5.举例说明 二、并发服务器模型1.循环式迭代式模式2.并发式服务器3.prefork服务器4.反应式服务器 (Reactor)5.反…

协同过滤推荐算法(包括传统协同过滤、矩阵分解、NeuralCF)

一、什么是协同过滤推荐算法 传统的协同过滤&#xff08;Collaborative Filtering, CF&#xff09;是一种推荐系统技术&#xff0c;它基于用户的历史行为数据来预测用户对未评分项目的潜在兴趣。 “协同大家的反馈、评价和意见一起对海量的信息进行过滤&#xff0c;从中筛选出…

IPD如何通过数字化项目管理平台落地实施?

随着市场竞争的日益激烈&#xff0c;企业对于产品研发的效率和质量逐渐提高&#xff0c;越来越多的企业关注到IPD(Integrated Product Development)&#xff0c;希望参考IPD体系的方法理念和实践经验&#xff0c;从而帮助企业快速响应市场变化、缩短产品开发周期、提升产品开发…