分布式微服务--ZooKeeper的客户端常用命令 Java API 操作

一、ZooKeeper 客户端常用命令

1. 启动与退出

bin/zkCli.sh -server 127.0.0.1:2181  # 连接客户端
quit                                  # 退出客户端

2. 节点操作

# 查看子节点
ls /
ls -s /
ls /app# 查看节点详细信息
ls2 /app
stat /app
# 创建节点
create /node1 "hello"          # 持久节点
create -e /node2 "temp"        # 临时节点
create -s /node3 "seq"         # 顺序节点
create -e -s /node4 "tempSeq"  # 临时顺序节点创建node1下的子节点,不能node1和node1一起创建,必须创建了node1才能执行下面的否则报错
create /node1/node11 "hello1"  #子节点
# 获取/修改数据
get /node1
set /node1 "world"
# 删除节点
delete /node1   # 删除无子节点的
deleteall /节点path #删除带有子节点的节点
rmr /node1      # 递归删除

3. Watch 监听

get /node1 true   # 监听数据变化
ls / true         # 监听子节点变化

⚠️ 监听是一次性的,触发后失效。


4. ACL 权限控制

getAcl /node1
setAcl /node1 world:anyone:rw

权限:r=读,w=写,c=创建,d=删除,a=管理。
模式:world(所有人)、authdigest(用户名密码)、ip


5. 辅助命令

help        # 查看帮助
history     # 查看历史命令
redo <id>   # 重做历史命令

二、ZooKeeper Java API 操作

1. 原生 API(org.apache.zookeeper.ZooKeeper)

需要的依赖

<!-- 原生 ZooKeeper 依赖 -->
<dependency><groupId>org.apache.zookeeper</groupId><artifactId>zookeeper</artifactId><version>3.8.3</version>
</dependency>

代码实现

import org.apache.zookeeper.*;public class ZkDemo {public static void main(String[] args) throws Exception {// 1. 连接 ZooKeeperZooKeeper zk = new ZooKeeper("127.0.0.1:2181", 30000, event -> {System.out.println("收到事件:" + event);});// 2. 创建节点zk.create("/node1", "hello".getBytes(),ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT);// 3. 获取节点数据byte[] data = zk.getData("/node1", false, null);System.out.println("节点数据:" + new String(data));// 4. 修改节点数据zk.setData("/node1", "world".getBytes(), -1);// 5. 获取子节点System.out.println("子节点:" + zk.getChildren("/", false));// 6. 删除节点zk.delete("/node1", -1);// 7. 关闭连接zk.close();}
}

2. Curator 客户端(推荐,简化 API

需要的依赖

 <!--curator-->
<!-- Curator(如果你要用 Curator 封装的API) -->
<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>

⚠️ curator-frameworkcurator-recipes 内部会依赖 zookeeper,所以一般不用单独引入 zookeeper 依赖,除非你要控制 zk 版本。

2.1 使用Curator实现增删改查的api

Curator 方法ZooKeeper CLI 类似命令
create().forPath("/node")create /node
getData().forPath("/node")get /node
getChildren().forPath("/")ls /
getData().storingStatIn(stat)ls -s /node
setData().forPath("/node", data)set /node data
delete().forPath("/node")delete /node
delete().deletingChildrenIfNeeded()rmr /node

代码实现:

public class CuratorTest {private CuratorFramework client; // Curator 客户端对象/*** 建立连接*/@Beforepublic void testConnect() {/*** @param connectString       连接字符串。zk server 地址和端口 "127.0.0.1:2181,127.0.0.1:2181"* @param sessionTimeoutMs    会话超时时间 单位ms* @param connectionTimeoutMs 连接超时时间 单位ms* @param retryPolicy         重试策略*//* //重试策略RetryPolicy retryPolicy = new ExponentialBackoffRetry(3000,10);//1.第一种方式CuratorFramework client = CuratorFrameworkFactory.newClient("192.168.149.135:2181",60 * 1000, 15 * 1000, retryPolicy);*///重试策略:初始等待3秒,重试10次RetryPolicy retryPolicy = new ExponentialBackoffRetry(3000, 10);//2.第二种方式:通过builder方式构建客户端//CuratorFrameworkFactory.builder();client = CuratorFrameworkFactory.builder().connectString("127.0.0.1:2181") // 设置ZK地址.sessionTimeoutMs(60 * 1000)           // 会话超时时间.connectionTimeoutMs(15 * 1000)        // 连接超时时间.retryPolicy(retryPolicy)              // 设置重试策略// namespace("czq")// 设置命名空间,将 "czq" 作为客户端操作的根路径// 这样之后创建节点时无需每次都写 /czq 前缀// 例如:client.create().forPath("/node11", "hello1".getBytes())// 实际会在 ZooKeeper 中创建 /czq/node11 节点.namespace("czq")   .build();//开启连接client.start();}//==============================create=============================================================================/*** 创建节点:create 持久 临时 顺序 数据* 1. 基本创建 :create().forPath("")* 2. 创建节点 带有数据:create().forPath("",data)* 3. 设置节点的类型:create().withMode().forPath("",data)* 4. 创建多级节点  /app1/p1 :create().creatingParentsIfNeeded().forPath("",data)*/@Testpublic void testCreate() throws Exception {//2. 创建节点 带有数据//如果创建节点,没有指定数据,则默认将当前客户端的ip作为数据存储String path = client.create().forPath("/app2", "hehe".getBytes());System.out.println(path);}@Testpublic void testCreate2() throws Exception {//1. 基本创建//如果创建节点,没有指定数据,则默认将当前客户端的ip作为数据存储String path = client.create().forPath("/app1");System.out.println(path);}@Testpublic void testCreate3() throws Exception {//3. 设置节点的类型//默认类型:持久化String path = client.create().withMode(CreateMode.EPHEMERAL).forPath("/app3");System.out.println(path);}@Testpublic void testCreate4() throws Exception {//4. 创建多级节点  /app1/p1//creatingParentsIfNeeded():如果父节点不存在,则创建父节点String path = client.create().creatingParentsIfNeeded().forPath("/app4/p1");System.out.println(path);}//===========================get================================================================================/*** 查询节点:* 1. 查询数据:get: getData().forPath()* 2. 查询子节点: ls /: getChildren().forPath()* 3. 查询节点状态信息:ls -s /:getData().storingStatIn(状态对象).forPath()*/@Testpublic void testGet1() throws Exception {//1. 查询数据:getbyte[] data = client.getData().forPath("/app1");System.out.println(new String(data));}@Testpublic void testGet2() throws Exception {// 2. 查询子节点: ls /List<String> path = client.getChildren().forPath("/");System.out.println(path);}@Testpublic void testGet3() throws Exception {Stat status = new Stat(); // 状态对象,用来存储节点元信息System.out.println(status);//3. 查询节点状态信息:ls -s ///.storingStatIn(status)代表存储状态信息到status对象中client.getData().storingStatIn(status).forPath("/app1");System.out.println(status);}//===========================set================================================================================/*** 修改数据* 1. 基本修改数据:setData().forPath()* 2. 根据版本修改: setData().withVersion().forPath()* * version 是通过查询出来的。目的就是为了让其他客户端或者线程不干扰我。** @throws Exception*/@Testpublic void testSet() throws Exception {// 基本修改节点数据client.setData().forPath("/app1", "itcast".getBytes());}@Testpublic void testSetForVersion() throws Exception {Stat status = new Stat();//3. 查询节点状态信息:ls -s//.storingStatIn(status)代表存储状态信息到status对象中client.getData().storingStatIn(status).forPath("/app1");int version = status.getVersion();//查询出来的节点版本System.out.println(version);// 根据版本修改节点数据,保证并发安全client.setData().withVersion(version).forPath("/app1", "hehe".getBytes());}//===========================delete================================================================================/*** 删除节点: delete deleteall* 1. 删除单个节点:delete().forPath("/app1");* 2. 删除带有子节点的节点:delete().deletingChildrenIfNeeded().forPath("/app1");* 3. 必须成功的删除:为了防止网络抖动。本质就是重试。  client.delete().guaranteed().forPath("/app2");* 4. 回调:inBackground* @throws Exception*/@Testpublic void testDelete() throws Exception {// 1. 删除单个节点client.delete().forPath("/app1");}@Testpublic void testDelete2() throws Exception {//2. 删除带有子节点的节点client.delete().deletingChildrenIfNeeded().forPath("/app4");}@Testpublic void testDelete3() throws Exception {//3. 必须成功的删除(自动重试保证删除成功)client.delete().guaranteed().forPath("/app2");}@Testpublic void testDelete4() throws Exception {//4. 回调异步删除client.delete().guaranteed().inBackground(new BackgroundCallback(){@Overridepublic void processResult(CuratorFramework client, CuratorEvent event) throws Exception {System.out.println("我被删除了~");System.out.println(event);}}).forPath("/app1");}@Afterpublic void close() {// 关闭客户端连接if (client != null) {client.close();}}}
2.2 使用Curator实现Watch事件监听的api
(1)Curator 2.x/4.x 常见的写法
  • 使用者三个类(NodeCachePathChildrenCacheTreeCache

    • NodeCache(监听一个节点自己)

    • PathChildrenCache(监听某个节点的直接子节点)

    • TreeCache(监听某个节点和所有子节点)

        Curator 5.x 开始,这三个类(NodeCachePathChildrenCacheTreeCache)已经被 统一弃用,官方推荐用 CuratorCache 来代替。

监听器监听范围典型应用场景
NodeCache单个节点的数据变化监听配置节点变化
PathChildrenCache子节点的增删改,不监听本节点监听服务节点上下线
TreeCache节点及其所有子节点全量配置或服务树监控

代码实现    

public class CuratorWatcherTest {private CuratorFramework client; // Curator 客户端对象/*** 建立连接*/@Beforepublic void testConnect() {/*** @param connectString       连接字符串。zk server 地址和端口 "127.0.0.1:2181,127.0.0.1:2181"* @param sessionTimeoutMs    会话超时时间 单位ms* @param connectionTimeoutMs 连接超时时间 单位ms* @param retryPolicy         重试策略*//* //重试策略RetryPolicy retryPolicy = new ExponentialBackoffRetry(3000,10);//1.第一种方式CuratorFramework client = CuratorFrameworkFactory.newClient("192.168.149.135:2181",60 * 1000, 15 * 1000, retryPolicy);*///重试策略:初始等待3秒,重试10次RetryPolicy retryPolicy = new ExponentialBackoffRetry(3000, 10);//2.第二种方式:通过builder方式构建客户端//CuratorFrameworkFactory.builder();client = CuratorFrameworkFactory.builder().connectString("127.0.0.1:2181") // 设置ZK地址.sessionTimeoutMs(60 * 1000)           // 会话超时时间.connectionTimeoutMs(15 * 1000)        // 连接超时时间.retryPolicy(retryPolicy)              // 设置重试策略// namespace("czq")// 设置命名空间,将 "czq" 作为客户端操作的根路径// 这样之后创建节点时无需每次都写 /czq 前缀// 例如:client.create().forPath("/node11", "hello1".getBytes())// 实际会在 ZooKeeper 中创建 /czq/node11 节点.namespace("czq")   .build();//开启连接client.start();}@Afterpublic void close() {if (client != null) {client.close(); // 关闭客户端连接}}/*** 演示 NodeCache:给指定一个节点注册监听器* NodeCache 只能监听某个具体节点的数据变化(新增/修改/删除)*/@Testpublic void testNodeCache() throws Exception {// 1. 创建 NodeCache 对象,监听 /app1 节点final NodeCache nodeCache = new NodeCache(client,"/app1");// 2. 注册监听器nodeCache.getListenable().addListener(new NodeCacheListener() {@Overridepublic void nodeChanged() throws Exception {System.out.println("节点变化了~");// 获取修改后的节点数据(如果节点被删除,这里可能会是 null)byte[] data = nodeCache.getCurrentData().getData();System.out.println(new String(data));}});// 3. 开启监听// 参数 true 表示在启动监听时,立即加载一次缓存数据nodeCache.start(true);// 阻塞住主线程,保证监听器一直生效while (true){}}/*** 演示 PathChildrenCache:监听某个节点的所有子节点* 只能监听子节点的变化(新增/修改/删除),不能监听当前节点本身*/@Testpublic void testPathChildrenCache() throws Exception {// 1. 创建 PathChildrenCache 监听对象// 参数 true 表示对子节点数据进行缓存PathChildrenCache pathChildrenCache = new PathChildrenCache(client,"/app2",true);// 2. 绑定监听器pathChildrenCache.getListenable().addListener(new PathChildrenCacheListener() {@Overridepublic void childEvent(CuratorFramework client, PathChildrenCacheEvent event) throws Exception {System.out.println("子节点变化了~");System.out.println(event);// 监听子节点数据变更PathChildrenCacheEvent.Type type = event.getType();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){}}/*** 演示 TreeCache:监听某个节点自己和它的所有子节点* 相当于 NodeCache + PathChildrenCache 的结合体*/@Testpublic void testTreeCache() throws Exception {// 1. 创建 TreeCache 监听对象TreeCache treeCache = new TreeCache(client,"/app2");// 2. 注册监听器treeCache.getListenable().addListener(new TreeCacheListener() {@Overridepublic void childEvent(CuratorFramework client, TreeCacheEvent event) throws Exception {System.out.println("节点变化了");System.out.println(event);}});// 3. 开启监听treeCache.start();// 阻塞主线程,保证监听器一直生效while (true){}}
}

(2)Curator 5.x以上常见的写法

 Curator 5.x 开始,这三个类(NodeCachePathChildrenCacheTreeCache)已经被 统一弃用,官方推荐用 CuratorCache 来代替。(新版本)

方法名对应旧API监听范围应用场景
testCuratorCacheNodeNodeCache单节点数据变化单个配置项
testCuratorCacheChildrenPathChildrenCache子节点(不含父节点)服务注册/发现
testCuratorCacheTreeTreeCache节点 + 全部子节点配置中心、全量监控

代码实现 

public class CuratorWatcherTest {// Curator 客户端对象,用于操作 ZooKeeperprivate CuratorFramework client;/*** 建立连接*/@Beforepublic void testConnect() {/*** @param connectString       连接字符串。zk server 地址和端口 "127.0.0.1:2181,127.0.0.1:2181"* @param sessionTimeoutMs    会话超时时间 单位ms* @param connectionTimeoutMs 连接超时时间 单位ms* @param retryPolicy         重试策略*//* //重试策略RetryPolicy retryPolicy = new ExponentialBackoffRetry(3000,10);//1.第一种方式CuratorFramework client = CuratorFrameworkFactory.newClient("192.168.149.135:2181",60 * 1000, 15 * 1000, retryPolicy);*///重试策略:初始等待3秒,重试10次RetryPolicy retryPolicy = new ExponentialBackoffRetry(3000, 10);//2.第二种方式:通过builder方式构建客户端//CuratorFrameworkFactory.builder();client = CuratorFrameworkFactory.builder().connectString("127.0.0.1:2181") // 设置ZK地址.sessionTimeoutMs(60 * 1000)           // 会话超时时间.connectionTimeoutMs(15 * 1000)        // 连接超时时间.retryPolicy(retryPolicy)              // 设置重试策略// namespace("czq")// 设置命名空间,将 "czq" 作为客户端操作的根路径// 这样之后创建节点时无需每次都写 /czq 前缀// 例如:client.create().forPath("/node11", "hello1".getBytes())// 实际会在 ZooKeeper 中创建 /czq/node11 节点.namespace("czq")   .build();//开启连接client.start();}@Afterpublic void close() {// 测试完成后关闭客户端,释放资源if (client != null) {client.close();}}// ==============================替代 NodeCache=============================================================================/*** 1. 监听单个节点(替代 NodeCache)* 使用 CuratorCache + CuratorCacheListener 来代替旧的 NodeCache*/@Testpublic void testCuratorCacheNode() throws Exception {// 创建 CuratorCache,监听 /app1 节点CuratorCache cache = CuratorCache.build(client, "/app1");// 定义监听器,使用 forNodeCache 模式,只监听该节点数据变化CuratorCacheListener listener = CuratorCacheListener.builder().forNodeCache(new Runnable() {@Overridepublic void run() {System.out.println("节点变化了~");try {// 获取节点最新数据并打印byte[] data = client.getData().forPath("/app1");System.out.println("最新数据:" + new String(data));} catch (Exception e) {e.printStackTrace();}}}).build();// 将监听器绑定到缓存cache.listenable().addListener(listener);// 开启缓存(监听)cache.start();// 阻塞主线程,保证监听器一直运行Thread.sleep(Long.MAX_VALUE);}// ==============================替代 PathChildrenCache=============================================================================/*** 2. 监听子节点变化(替代 PathChildrenCache)* 使用 CuratorCache + PathChildrenCacheListener 监听某节点的所有子节点*/@Testpublic void testCuratorCacheChildren() throws Exception {// 创建 CuratorCache,监听 /app2 节点的子节点CuratorCache cache = CuratorCache.build(client, "/app2");// 定义监听器,forPathChildrenCache 表示只监听子节点的变化CuratorCacheListener listener = CuratorCacheListener.builder().forPathChildrenCache("/app2", client, new PathChildrenCacheListener() {@Overridepublic void childEvent(CuratorFramework client, PathChildrenCacheEvent event) throws Exception {System.out.println("子节点变化了~");System.out.println("类型:" + event.getType());if (event.getData() != null) {// 打印节点路径和数据System.out.println("节点:" + event.getData().getPath());System.out.println("数据:" + new String(event.getData().getData()));}}}).build();// 将监听器绑定到缓存cache.listenable().addListener(listener);// 开启缓存cache.start();// 阻塞主线程,保证监听器一直运行Thread.sleep(Long.MAX_VALUE);}// ==============================替代 TreeCache=============================================================================/*** 3. 监听节点及其所有子节点(替代 TreeCache)* 使用 CuratorCache + TreeCacheListener 监听整个节点树*/@Testpublic void testCuratorCacheTree() throws Exception {// 创建 CuratorCache,监听 /app2 节点及其子节点CuratorCache cache = CuratorCache.build(client, "/app2");// 定义监听器,forTreeCache 表示节点本身和子节点都监听CuratorCacheListener listener = CuratorCacheListener.builder().forTreeCache(client, new TreeCacheListener() {@Overridepublic void childEvent(CuratorFramework client, TreeCacheEvent event) throws Exception {System.out.println("树节点变化了~");System.out.println("类型:" + event.getType());if (event.getData() != null) {// 打印节点路径和数据System.out.println("节点:" + event.getData().getPath());System.out.println("数据:" + new String(event.getData().getData()));}}}).build();// 将监听器绑定到缓存cache.listenable().addListener(listener);// 开启缓存cache.start();// 阻塞主线程,保证监听器一直运行Thread.sleep(Long.MAX_VALUE);}}

2.3 实现分布式锁

 这里不做过多讲解详细去看我的另一篇博客:分布式微服务--ZooKeeper作为分布式锁-CSDN博客

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

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

相关文章

PID控制技术深度剖析:从基础原理到高级应用(六)

PID 控制技术深度剖析&#xff1a;从基础原理到高级应用 最近在项目中有要开始进行PID的控制了&#xff0c;隔了很久没有做PID控制的东西了&#xff0c;所以想正好借这个机会&#xff0c;温习一下和PID有关的内容。 系列文章目录 PID控制技术深度剖析&#xff1a;从基础原理到…

PCL关键点提取

1. 核心概念:什么是关键点?为什么需要关键点? 关键词:信息冗余、计算效率、突出特征 “想象一下,我们有一片密集的点云,包含几十万个点。如果我们直接在每个点上都计算像FPFH这样的局部特征,计算量会非常大,极其耗时,而且很多点所处的区域(比如平坦的墙面)特征非常…

vcruntime140_1.dll缺失怎么办?暗黑破坏神游戏vcruntime140_1.dll缺失的4个解决方法

你是否遇到过这样的情况&#xff1a; 玩《暗黑破坏神》《英雄联盟》《GTA5》的时候&#xff0c;游戏忽然闪退&#xff0c;弹窗提示&#xff1a; “无法启动&#xff0c;因为计算机中丢失 vcruntime140_1.dll” 这不是某一个游戏的问题&#xff0c;而是 Windows 系统运行库缺失…

迁移学习-ResNet

好的&#xff0c;我将为你撰写一篇关于ResNet迁移学习的技术博客。以下是博客的主要内容&#xff1a;ResNet迁移学习&#xff1a;原理、实践与效果深度解析1. 深度学习中迁移学习的重要性与ResNet的独特价值迁移学习&#xff08;Transfer Learning&#xff09;是机器学习中一种…

极大似然估计与概率图模型:统计建模的黄金组合

在数据驱动的时代&#xff0c;如何从海量信息中提取有价值的规律&#xff1f;统计建模提供了两大核心工具&#xff1a;极大似然估计&#xff08;MLE&#xff09;帮助我们根据数据推断模型参数&#xff0c;而概率图模型&#xff08;PGM&#xff09;则通过图形化语言描述变量间的…

解析豆科系统发育冲突原因

生命之树是进化生物学的核心&#xff0c;但由于 不完全谱系排序&#xff08;ILS&#xff09;、杂交 和 多倍化 等复杂过程&#xff0c;解析深层且难解的系统发育关系仍然是一个挑战。**豆科&#xff08;Leguminosae&#xff09;**这一物种丰富且生态多样化家族的理解&#xff0…

从Java全栈到前端框架:一次真实的面试对话与技术解析

从Java全栈到前端框架&#xff1a;一次真实的面试对话与技术解析 在一次真实的面试中&#xff0c;一位拥有多年经验的Java全栈开发工程师&#xff0c;被问及了多个涉及前后端技术栈的问题。他的回答既专业又自然&#xff0c;展现了扎实的技术功底和丰富的实战经验。 面试官&…

阿瓦隆 A1566HA 2U 480T矿机参数解析:性能与能效深入分析

在矿机行业&#xff0c;AvaLON是一个备受关注的品牌&#xff0c;尤其在比特币&#xff08;BTC&#xff09;和比特币现金&#xff08;BCH&#xff09;挖矿领域&#xff0c;凭借其强劲的算力和高效能效&#xff0c;在市场中占据了一席之地。本文将针对阿瓦隆 A1566HA 2U 480T矿机…

小迪安全v2023学习笔记(七十八讲)—— 数据库安全RedisCouchDBH2database未授权CVE

文章目录前记服务攻防——第七十八天数据库安全&Redis&CouchDB&H2database&未授权访问&CVE漏洞前置知识复现环境服务判断对象类别利用方法数据库应用 - Redis-未授权访问&CVE漏洞前置知识案例演示沙箱绕过RCE - CVE-2022-0543未授权访问 - CNVD-2019-2…

HTML + CSS 创建图片倒影的 5 种方法

HTML CSS 创建图片倒影的 5 种方法 目标&#xff1a;掌握多种生成“图片倒影 / Reflection”效果的实现思路&#xff0c;理解兼容性、性能差异与最佳实践&#xff0c;方便在真实业务&#xff08;商品展示、相册、登陆页面视觉强化&#xff09;中安全使用。 总览对比 方法核心…

一个文件被打开io流和不打卡 inode

1. 磁盘 最小基本单位 扇区 机器磁盘的io效率 &#xff08;读和取&#xff09;2. 文件系统 对磁盘分区 &#xff0c;最小的文件单位块组&#xff0c;快组内部已经划分好区域&#xff0c;巴拉巴拉&#xff0c;总之&#xff0c;每次使用数据&#xff0c;以操作系统的处理都是块级…

ThermoSeek:热稳定蛋白数据库

这篇论文提出了ThermoSeek&#xff0c;一个综合性的网络资源&#xff0c;用于分析来自嗜热和嗜冷物种的蛋白质序列和结构。具体来说&#xff0c;数据收集&#xff1a;从美国国家生物技术信息中心&#xff08;NCBI&#xff09;的基因组数据库中收集了物种的分类ID&#xff0c;并…

leetcode算法刷题的第二十七天

1.leetcode 56.合并区间 题目链接 class Solution { public:static bool cmp(const vector<int>& a,const vector<int>& b){return a[0]<b[0];}vector<vector<int>> merge(vector<vector<int>>& intervals) {vector<v…

解决 Apache/WAF SSL 证书链不完整导致的 PKIX path building failed 问题

文章目录解决 Apache/WAF SSL 证书链不完整导致的 PKIX path building failed 问题为什么会出现证书链错误&#xff1f;常见场景直连服务器正常&#xff0c;但经过 WAF 出错Windows/Linux 下证书文件说明引入 WAF 或其他中间层&#xff1a;解决方法方法一&#xff1a;单独配置 …

十一、标准化和软件知识产权基础知识

1 标准化基础知识 1.1 基本概念 1.1.1 标准的分类 1.1.1.1 按使用范围分类 国际标准&#xff1a;由国际组织如 ISO、IEC 制定的标准。国家标准&#xff1a;由国家标准化机构制定的标准&#xff0c;如中国的 GB&#xff0c;美国 ANSI。行业标准&#xff1a;由行业主管部门制定的…

计算机毕设选题:基于Python数据挖掘的高考志愿推荐系统

精彩专栏推荐订阅&#xff1a;在 下方专栏&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f496;&#x1f525;作者主页&#xff1a;计算机毕设木哥&#x1f525; &#x1f496; 文章目录 一、项目介绍二…

什么是PCB工艺边?猎板给您分享设计要点

什么是PCB工艺边&#xff1f;猎板给您分享设计要点在PCB设计和制造领域&#xff0c;工艺边是一个看似简单却至关重要的概念&#xff0c;它直接关系到生产流程的顺畅性与最终产品的质量。本文将为您详细解析PCB工艺边的定义、作用、设计要点&#xff0c;并分享猎板PCB在高精度制…

Rustdesk搭建与客户端修改与编译

Rustdesk是一个开源的远程桌面工具&#xff0c;客户端可以自己定制修改编译 这里主要记录一下搭建的过程 服务端搭建 主要是参考了这篇文章&#xff0c;感觉作者分享~ 在 Linux VPS 上创建 RustDesk 服务器 - 知乎 https://zhuanlan.zhihu.com/p/1922729751656765374 这里主要…

数字人系统源码搭建与定制化开发:从技术架构到落地实践

随着元宇宙、直播电商、智能客服等领域的爆发&#xff0c;数字人从概念走向商业化落地&#xff0c;其定制化需求也从 “单一形象展示” 升级为 “多场景交互能力”。本文将从技术底层出发&#xff0c;拆解数字人系统的源码搭建逻辑&#xff0c;结合定制化开发中的核心痛点&…

2025国赛C题创新论文+代码可视化 NIPT 的时点选择与胎儿的异常判定

2025国赛C题创新论文代码可视化 NIPT 的时点选择与胎儿的异常判定基于多通道LED光谱优化的人体节律调节与睡眠质量评估模型摘要无创产前检测&#xff08;NIPT&#xff09;通过分析孕妇血浆中胎儿游离DNA来筛查染色体异常&#xff0c;其准确性很大程度上依赖于胎儿Y染色体浓度的…