hdfs源码解析之DFSClient
1、DFSClient类简介
DFSClient
是 Hadoop 分布式文件系统(HDFS)中的一个核心类,用于客户端与 HDFS 之间的交互。它提供了一组方法,使客户端应用程序可以方便地与 HDFS 进行通信,包括文件的读取、写入、创建、删除、重命名等操作。DFSClient
封装了与 NameNode 和 DataNode 的通信细节,使得客户端开发者可以通过高级 API 进行文件系统操作,而不必关心底层的实现细节。
2、DFSClient主要功能
2.1、文件读取和写入
- 提供方法用于读取和写入 HDFS 上的文件。
- 例如,
open
方法用于打开文件以读取,create
方法用于创建新文件以写入。
2.2、文件操作
- 支持文件的创建、删除、重命名、追加等操作。
- 例如,
delete
方法用于删除文件或目录,rename
方法用于重命名文件或目录。
2.3、目录操作
- 支持创建、删除和列出目录。
- 例如,
mkdirs
方法用于创建目录,listPaths
方法用于列出目录内容。
2.4、获取文件和目录信息
- 提供方法获取文件和目录的元数据信息。
- 例如,
getFileInfo
方法用于获取文件或目录的详细信息,getLocatedBlocks
方法用于获取文件的块位置。
2.5、与NN、DN通信
- 管理与 NameNode 的通信,用于获取文件的元数据和块位置信息。
- 管理与 DataNode 的通信,用于读取和写入实际的数据块。
3、DFSClient核心源码
DFSClient源码主要包括:创建客户端连接(配置获取、令牌处理、连接地址解析)
3.1、构造方法
3.1.1、代码概述
该构造函数已废弃,接受一个Configuration对象,并调用另一个构造函数获取NameNode地址
@Deprecatedpublic DFSClient(Configuration conf) throws IOException {this(DFSUtilClient.getNNAddress(conf), conf);}
该构造函数接受一个InetSocketAddress对象和一个Configuration对象,并将InetSocketAddress 转换为URI然后调用另一个基于URI的构造函数
public DFSClient(InetSocketAddress address, Configuration conf)throws IOException {this(DFSUtilClient.getNNUri(address), conf);}
该构造函数接受一个URI对象和一个Configuration对象,并将FileSystem.Statistics参数设置为 null,然后调用另一个更完整的构造函数
public DFSClient(URI nameNodeUri, Configuration conf) throws IOException {this(nameNodeUri, conf, null);}
该构造函数接受一个URI对象、一个Configuration对象和一个FileSystem.Statistics对象,然后调用最完整的构造函数
public DFSClient(URI nameNodeUri, Configuration conf,FileSystem.Statistics stats) throws IOException {this(nameNodeUri, null, conf, stats);}
最底层构造函数,该方法不建议直接调用。
@VisibleForTestingpublic DFSClient(URI nameNodeUri, ClientProtocol rpcNamenode,Configuration conf, FileSystem.Statistics stats) throws IOException {// Copy only the required DFSClient configurationthis.tracer = FsTracer.get(conf);this.dfsClientConf = new DfsClientConf(conf);this.conf = conf;this.stats = stats;this.socketFactory = NetUtils.getSocketFactory(conf, ClientProtocol.class);this.dtpReplaceDatanodeOnFailure = ReplaceDatanodeOnFailure.get(conf);this.dtpReplaceDatanodeOnFailureReplication = (short) conf.getInt(HdfsClientConfigKeys.BlockWrite.ReplaceDatanodeOnFailure.MIN_REPLICATION,HdfsClientConfigKeys.BlockWrite.ReplaceDatanodeOnFailure.MIN_REPLICATION_DEFAULT);LOG.debug("Sets {} to {}",HdfsClientConfigKeys.BlockWrite.ReplaceDatanodeOnFailure.MIN_REPLICATION, dtpReplaceDatanodeOnFailureReplication);this.ugi = UserGroupInformation.getCurrentUser();this.namenodeUri = nameNodeUri;this.clientName = "DFSClient_" + dfsClientConf.getTaskId() + "_" +ThreadLocalRandom.current().nextInt() + "_" +Thread.currentThread().getId();int numResponseToDrop = conf.getInt(DFS_CLIENT_TEST_DROP_NAMENODE_RESPONSE_NUM_KEY,DFS_CLIENT_TEST_DROP_NAMENODE_RESPONSE_NUM_DEFAULT);ProxyAndInfo<ClientProtocol> proxyInfo = null;AtomicBoolean nnFallbackToSimpleAuth = new AtomicBoolean(false);if (numResponseToDrop > 0) {// This case is used for testing.LOG.warn("{} is set to {} , this hacked client will proactively drop responses",DFS_CLIENT_TEST_DROP_NAMENODE_RESPONSE_NUM_KEY, numResponseToDrop);proxyInfo = NameNodeProxiesClient.createProxyWithLossyRetryHandler(conf,nameNodeUri, ClientProtocol.class, numResponseToDrop,nnFallbackToSimpleAuth);}if (proxyInfo != null) {this.dtService = proxyInfo.getDelegationTokenService();this.namenode = proxyInfo.getProxy();} else if (rpcNamenode != null) {// This case is used for testing.Preconditions.checkArgument(nameNodeUri == null);this.namenode = rpcNamenode;dtService = null;} else {Preconditions.checkArgument(nameNodeUri != null,"null URI");proxyInfo = NameNodeProxiesClient.createProxyWithClientProtocol(conf,nameNodeUri, nnFallbackToSimpleAuth);this.dtService = proxyInfo.getDelegationTokenService();this.namenode = proxyInfo.getProxy();}String localInterfaces[] =conf.getTrimmedStrings(DFS_CLIENT_LOCAL_INTERFACES);localInterfaceAddrs = getLocalInterfaceAddrs(localInterfaces);if (LOG.isDebugEnabled() && 0 != localInterfaces.length) {LOG.debug("Using local interfaces [{}] with addresses [{}]",Joiner.on(',').join(localInterfaces),Joiner.on(',').join(localInterfaceAddrs));}Boolean readDropBehind =(conf.get(DFS_CLIENT_CACHE_DROP_BEHIND_READS) == null) ?null : conf.getBoolean(DFS_CLIENT_CACHE_DROP_BEHIND_READS, false);Long readahead = (conf.get(DFS_CLIENT_CACHE_READAHEAD) == null) ?null : conf.getLongBytes(DFS_CLIENT_CACHE_READAHEAD, 0);this.serverDefaultsValidityPeriod = conf.getTimeDuration(DFS_CLIENT_SERVER_DEFAULTS_VALIDITY_PERIOD_MS_KEY,DFS_CLIENT_SERVER_DEFAULTS_VALIDITY_PERIOD_MS_DEFAULT,TimeUnit.MILLISECONDS);Boolean writeDropBehind =(conf.get(DFS_CLIENT_CACHE_DROP_BEHIND_WRITES) == null) ?null : conf.getBoolean(DFS_CLIENT_CACHE_DROP_BEHIND_WRITES, false);this.defaultReadCachingStrategy =new CachingStrategy(readDropBehind, readahead);this.defaultWriteCachingStrategy =new CachingStrategy(writeDropBehind, readahead);this.clientContext = ClientContext.get(conf.get(DFS_CLIENT_CONTEXT, DFS_CLIENT_CONTEXT_DEFAULT),dfsClientConf, conf);if (dfsClientConf.getHedgedReadThreadpoolSize() > 0) {this.initThreadsNumForHedgedReads(dfsClientConf.getHedgedReadThreadpoolSize());}this.initThreadsNumForStripedReads(dfsClientConf.getStripedReadThreadpoolSize());this.saslClient = new SaslDataTransferClient(conf, DataTransferSaslUtil.getSaslPropertiesResolver(conf),TrustedChannelResolver.getInstance(conf), nnFallbackToSimpleAuth);}
3.1.2、重点剖析
DFSClient的核心构建方式是传入namenode节点对应的URI以及配置信息,也是我们构建DFSClient通常使用的方法
public DFSClient(URI nameNodeUri, Configuration conf) throws IOException {this(nameNodeUri, conf, null); }
3.2、委托令牌处理
这段源码是一个用于续约和取消 HDFS 委托令牌(Delegation Token)的 Renewer 类,它继承自 TokenRenewer 类。主要功能是通过与 NameNode 通信,维护和管理委托令牌的生命周期。
3.2.1、代码概述
3.2.2、重点剖析
- static静态代码块为初始化hdfs配置文件;
- handleKind方法用于判断是否处理指定类型的委托令牌,在当前源码中会默认判定是否为HDFS的委托令牌类型;
renew
方法用于续约委托令牌。它通过getNNProxy
方法获取到与委托令牌对应的 NameNode 代理,然后调用renewDelegationToken
方法进行委托令牌的续约操作;cancel
方法用于取消委托令牌。它也通过getNNProxy
方法获取 NameNode 代理,然后调用cancelDelegationToken
方法执行委托令牌的取消操作;getNNProxy
方法根据委托令牌获取对应的 NameNode 代理。它首先根据委托令牌的信息构建 URI,然后通过NameNodeProxiesClient
类的静态方法创建 NameNode 的代理对象,并返回该代理对象。
3.3、getLocalInterfaceAddrs
3.3.1、代码概述
这个方法的作用是接受一个接口名称的数组,并根据每个接口名称解析成对应的本地地址(可以是 IP 地址、子网或域名)。它首先尝试将接口名称视为一个 IP 地址,如果不是,则检查它是否是一个有效的子网,如果仍然不是,则假定它是一个域名,并通过 DNS 解析。最终,所有解析出的地址都被封装为 InetSocketAddress
对象,并返回一个包含这些地址的数组。
private static SocketAddress[] getLocalInterfaceAddrs(String interfaceNames[]) throws UnknownHostException {List<SocketAddress> localAddrs = new ArrayList<>();for (String interfaceName : interfaceNames) {if (InetAddresses.isInetAddress(interfaceName)) {localAddrs.add(new InetSocketAddress(interfaceName, 0));} else if (NetUtils.isValidSubnet(interfaceName)) {for (InetAddress addr : NetUtils.getIPs(interfaceName, false)) {localAddrs.add(new InetSocketAddress(addr, 0));}} else {for (String ip : DNS.getIPs(interfaceName, false)) {localAddrs.add(new InetSocketAddress(ip, 0));}}}return localAddrs.toArray(new SocketAddress[localAddrs.size()]);}
3.3.2、重点剖析
- 该方法首先检查interfaceName是否是一个有效的IP地址:
- 如果不是IP地址,检查interfaceName是否是一个有效的子网:
- 如果是有效的子网,获取该子网中的所有IP地址,并将每个IP地址封装为InetSocketAddress对象,添加到localAddrs列表中。
- 如果既不是IP地址也不是子网,假定它是一个域名:
- 通过DNS解析获取该域名的所有IP地址,并将每个IP地址封装为InetSocketAddress对象,添加到localAddrs列表中。
3.4、getRandomLocalInterfaceAddr
3.4.1、代码概述
这个方法的作用是从一组预先配置的本地接口地址 (localInterfaceAddrs
数组) 中随机选择一个地址并返回。
SocketAddress getRandomLocalInterfaceAddr() {if (localInterfaceAddrs.length == 0) {return null;}final int idx = r.nextInt(localInterfaceAddrs.length);final SocketAddress addr = localInterfaceAddrs[idx];LOG.debug("Using local interface {}", addr);return addr;}
3.4.2、重点剖析
- 检查
localInterfaceAddrs
数组是否为空,如果为空则返回null
。 - 使用随机数生成器
r
生成一个随机索引idx
。 - 获取并返回
localInterfaceAddrs
数组中对应索引idx
的SocketAddress
对象。 - 在返回之前,记录调试日志以便于跟踪选中的本地接口地址。
3.5、读写超时时间判定
3.5.1、代码概述
这段代码包含两个方法:getDatanodeWriteTimeout
和 getDatanodeReadTimeout
,它们用于计算数据节点写入和读取的超时时间。每个方法都接收一个参数 numNodes
,表示数据节点的数量。
int getDatanodeWriteTimeout(int numNodes) {final int t = dfsClientConf.getDatanodeSocketWriteTimeout();return t > 0? t + HdfsConstants.WRITE_TIMEOUT_EXTENSION*numNodes: 0;
}int getDatanodeReadTimeout(int numNodes) {final int t = dfsClientConf.getSocketTimeout();return t > 0? HdfsConstants.READ_TIMEOUT_EXTENSION*numNodes + t: 0;
}
3.5.2、重点剖析
- 通过dfsclientconf获取写入\读取超时时间
t;
如果t大于0则
返回t
加上一个扩展超时时间,这个扩展超时时间是常量HdfsConstants.WRITE_TIMEOUT_EXTENSION
乘以numNodes
(数据节点数量)- 如果t<=0,则返回0
3.6、租约管理
3.6.1、代码概述
这段代码定义了三个方法:getLeaseRenewer
、beginFileLease
和 endFileLease
,用于管理HDFS中的文件租约。文件租约机制确保文件在写入过程中不会被其他客户端修改或删除。
public LeaseRenewer getLeaseRenewer() {return LeaseRenewer.getInstance(namenodeUri != null ? namenodeUri.getAuthority() : "null", ugi, this);}/** Get a lease and start automatic renewal */private void beginFileLease(final String key, final DFSOutputStream out) {synchronized (filesBeingWritten) {putFileBeingWritten(key, out);LeaseRenewer renewer = getLeaseRenewer();boolean result = renewer.put(this);if (!result) {// Existing LeaseRenewer cannot add another Daemon, so remove existing// and add new one.LeaseRenewer.remove(renewer);renewer = getLeaseRenewer();renewer.put(this);}}}/** Stop renewal of lease for the file. */void endFileLease(final String renewLeaseKey) {synchronized (filesBeingWritten) {removeFileBeingWritten(renewLeaseKey);// remove client from renewer if no files are openif (filesBeingWritten.isEmpty()) {getLeaseRenewer().closeClient(this);}}}
3.6.2、重点剖析
- 获取租约续约器:
getLeaseRenewer
方法返回一个LeaseRenewer
实例,用于管理租约的续约。- 获取租约续约器
- 调用 LeaseRenewer.getInstance 方法获取 LeaseRenewer 实例。
- 如果 namenodeUri 不为空,则使用其权限部分(authority),否则使用 "null"。ugi(用户组信息)和当前 DFSClient 实例(this)作为参数传递给 LeaseRenewer.getInstance
- 开始文件租约:
beginFileLease
方法将文件添加到写入记录中,并确保当前客户端的租约续约器能够处理该文件的续约。- 使用 key 和 out(DFSOutputStream 实例)调用 putFileBeingWritten 方法,记录正在写入的文件;
- 获取 LeaseRenewer 实例;
- 调用 renewer.put(this) 方法将当前客户端添加到租约续约器中;
- 如果返回结果为 false(表示现有的 LeaseRenewer 不能添加新的守护线程),则移除现有的 LeaseRenewer,获取新的 LeaseRenewer 实例,并将当前客户端添加到新的 LeaseRenewer 中;
- 结束文件租约:
endFileLease
方法移除文件写入记录,并在没有文件写入时关闭客户端的租约续约- 使用 renewLeaseKey 调用 removeFileBeingWritten 方法,从记录中移除正在写入的文件
- 如果没有文件在写入(filesBeingWritten 为空),则获取 LeaseRenewer 实例,调用 renewer.closeClient(this) 方法,关闭当前客户端的租约续约。
todo,未完待续
相关文章:
![](https://img-blog.csdnimg.cn/direct/cbe3d877543843c2883aad82f070ca5e.png)
hdfs源码解析之DFSClient
1、DFSClient类简介 DFSClient 是 Hadoop 分布式文件系统(HDFS)中的一个核心类,用于客户端与 HDFS 之间的交互。它提供了一组方法,使客户端应用程序可以方便地与 HDFS 进行通信,包括文件的读取、写入、创建、删除、重命…...
![](https://www.ngui.cc/images/no-images.jpg)
智能化立体仓库的种类有哪些?
在仓储运输系统中,自动化立体仓库可充分利用空间储存货物,故而也被称之为高层货架仓库。在实际应用中,自动化仓库系统是不需人工处理的情况下能自动存储和取出物料的系统。那么,智能化立体仓库的种类有哪些?下面就让小…...
![](https://www.ngui.cc/images/no-images.jpg)
Stable Diffusion 3 如何下载安装使用及性能优化
Stable Diffusion 3 Stable Diffusion 3(SD3),Stability AI最新推出的Stable Diffusion模型系列,现在可以在Hugging Face Hub上使用,并且可以与Diffusers一起使用。 今天发布的模型是Stable Diffusion 3 Medium&…...
![](https://img-blog.csdnimg.cn/direct/35cc3d7147e2418a89eef06305cee350.png)
c语言操作符详解
操作符详解 正数的原码反码补码相同 负数的原码最高位数是1,正数为0 整数在内存中存储的是补码 负数的左移与右移,移的是补码,打印的是源码 补码-1取反就是原码。 左移有乘2的效果 左移和右移只针对整数。 vs里的右移操作赋采用的是算数右…...
![](https://img-blog.csdnimg.cn/direct/f51cf32a01d9420483e5df103f2532a8.jpeg)
【耐水好】强耐水UV胶水它的粘接强度和普通UV胶水比如何呢
【耐水好】强耐水UV胶水它的粘接强度和普通UV胶水比如何呢 强耐水UV胶水的粘接强度与普通UV胶水相比,具有显著的优势。以下是详细的比较和归纳: 固化方式: 两者都是通过紫外线(UV)照射进行固化,但强耐水UV…...
![](https://img-blog.csdnimg.cn/direct/bce817d630b747e68612e9849e7e3309.png)
jumpserver堡垒机集群搭建
1、环境 操作系统:龙蜥os 7.9 firewall-cmd --permanent --zonepublic --remove-servicessh firewall-cmd --permanent --zonepublic --add-rich-rulerule familyipv4 source address10.90.101.1 port port22 protocoltcp accept firewall-cmd --reload2、安装NFS…...
![](https://img-blog.csdnimg.cn/img_convert/f0901b4da14d459819c779b2c256d038.webp?x-oss-process=image/format,png)
Termius for Mac/Win:跨平台多协议远程管理利器
Termius for Mac/Win是一款备受瞩目的跨平台多协议远程管理软件,以其卓越的性能、丰富的功能和便捷的操作体验,赢得了广大用户的青睐。无论是在企业IT管理、系统维护,还是个人远程连接、文件传输等方面,Termius都展现出了出色的实…...
![](https://img-blog.csdnimg.cn/direct/184b21a7049d4226bd634357aeee3269.png)
Unity OpenCVForUnity 安装和第二个案例详解 <二>
目录 一、前言 二、场景介绍 1.WebCamTextureToMatExample脚本 2.FpsMonitor脚本 三、 结构体Scaler 四、找到相机并使用 1.相机的启用 2.格式转换 a.把webCamTexture转换成Mat b.把Mat转换成Texture2D 五、脚本组合 六、作者的碎碎念 一、前言 第二个案例…...
![](https://img-blog.csdnimg.cn/direct/eed0cbdab258439d98f3bdef509296b0.jpeg)
Lua实现自定义函数面向对象编程
本文目录 1、引言2、原理3、实例4、层析验证 文章对应视频教程: 暂无,可以关注我的B站账号等待更新。 点击图片或链接访问我的B站主页~~~ 1、引言 在现代软件开发中,面向对象编程(OOP)已经成为一种广泛使用的编程范式…...
![](https://img-blog.csdnimg.cn/direct/3d83cfc2002f410390e64c7f4b55f917.png)
docker安装消息队列mq中的rabbit服务
在现代化的分布式系统中,消息队列(Message Queue, MQ)已经成为了一种不可或缺的组件。RabbitMQ作为一款高性能、开源的消息队列软件,因其高可用性、可扩展性和易用性而广受欢迎。本文将详细介绍如何在Docker环境中安装RabbitMQ服务…...
![](https://img-blog.csdnimg.cn/img_convert/938ec8293e40185313f26361ba1b1e3c.jpeg)
OpenAI新模型发布,免费开放GPT-4o!但只开放一点点...
GPT-4o 中的“o”代表“omni”——指的是 GPT-4o 的多模态。 该模型将向免费客户开放,这意味着任何人都可以通过 ChatGPT 访问 OpenAI 最先进的技术。 GPT-4o 是 OpenAI 昨天晚上发布的新旗舰模型,可以实时推理音频、视觉和文本。 据官方介绍࿰…...
![](https://img-blog.csdnimg.cn/direct/d0dd4d79c6ec4cca9e22f1374638ffb2.png)
idea的右边栏maven不见了(丢了)解决方案以及idea无法识别maven项目
前言 众所周知,idea是java开发中不可缺少的利器,但是由于功能过多,导致奇怪的问题也很多 问题汇总 idea的右边栏maven丢了 idea无法识别maven项目 对应的解决办法 idea的右边栏maven丢了 原因可能是被自己手动移除了 或者 项目没被正确…...
![](https://img-blog.csdnimg.cn/direct/98ffcc3e3796443483210360b30196d0.jpeg)
等待 chrome.storage.local.get() 完成
chrome.storage.local.get() 获取存储处理并计数,内部计数正常,外部使用始终为0,百思不得其解。 如何在继续执行之前等待异步chrome.storage.local.get()完成-腾讯云开发者社区-腾讯云 (tencent.com) 原来我忽略了异步问题,最简…...
![](https://www.ngui.cc/images/no-images.jpg)
004 AOP使用
文章目录 基于AspectJ的AOP的使用添加依赖编写目标类和目标方法使用XML实现实现步骤切入点表达式通知类型 使用注解实现实现步骤环绕通知注解配置定义通用切入点 纯注解方式 基于AspectJ的AOP的使用 其实就是指的SpringAspectJ整合,不过Spring已经将AspectJ收录到自…...
![](https://www.ngui.cc/images/no-images.jpg)
Zookeeper 集群广播事务性能如何保证?
Zookeeper 集群广播事务性能如何保证? zookeeper是如何保证广播事务时,从开始到多数节点确认事务这个高效的? 在 Zookeeper 中,确保广播事务从开始到多数节点确认的高效性至关重要。Zookeeper 通过以下几个关键机制 和优化策略来实现这一目标: ZAB 协议(Zookeeper Atom…...
![](https://www.ngui.cc/images/no-images.jpg)
【vue解决el-input组件自动填充用户名密码】
解决el-input组件自动填充用户名密码 发现用autocomplete"off"并不能解决el-input组件自动填充密码的问题。 解决方法 auto-complete"new-password" 在el-input组件添加auto-complete"new-password" 即可...
![](https://www.ngui.cc/images/no-images.jpg)
案例练习:演讲比赛
演讲比赛: 比赛规则: 某市举行一场演讲比赛( speech_contest ),共有 24 个人参加。比赛共三轮,前两轮为淘汰赛,第三轮为决赛。 比赛方式:分组比赛,每组 6 个人;选手每次…...
![](https://img-blog.csdnimg.cn/direct/b49436cf9ee04f26aeaf69dfcd71a177.png)
推荐一个很好用的Latex写代码的软件
软件名称:Axmath 据说是国产软件,好用是真好用(去哪找?比如某地球号的公主号或其他地方)我是推荐付费购买使用 1.通过图形操作,选择要转成Latex代码的符号,按下转换,直接就出现了我…...
![](https://www.ngui.cc/images/no-images.jpg)
windows 程序右键管理员点击无响应
Windows 程序在右键单击以管理员身份运行时没有响应,可能是由于多种原因引起的。下面是一些常见的问题和解决方案: 1. 用户账户控制 (UAC) 设置问题: - 试着降低或提高 UAC 设置,然后再试一次。可以在控制面板的“用户账户”部…...
![](https://img-blog.csdnimg.cn/direct/3876efc166324db5832b87a44b9eac9e.png)
开发基于Java语言的SaaS(Software-as-a-Service,软件即服务)模式的HIS系统详解 HIS系统源码 支持二开
开发基于Java语言的SaaS(Software-as-a-Service,软件即服务)模式的HIS系统详解 HIS系统源码 支持二开 开发基于Java语言的SaaS(Software-as-a-Service,软件即服务)模式的HIS(Hospital Informat…...
![](https://img-blog.csdnimg.cn/direct/c291410338e2401f9267eeb17d4a5bb5.png)
关于微信小程序(必看)
前言 为规范开发者的用户个人信息处理行为,保障用户的合法权益,自2023年9月15日起,对于涉及处理用户个人信息的小程序开发者,微信要求,仅当开发者主动向平台同步用户已阅读并同意了小程序的隐私保护指引等信息处理规则…...
![](https://www.ngui.cc/images/no-images.jpg)
Activity中Context
Activity中Context在activity.attach()设置,所以Application中Context为ContextImpl appContext createBaseContextForActivity(r);,即在ContextImpl.createActivityContext()设置DispalyId private ContextImpl createBaseContextForActivity(Activit…...
![](https://img-blog.csdnimg.cn/direct/b3612e408a8d4a39b3fec508a0ec491c.png)
位图法-有效的数独
有效的数独,主要是判断每行每列每宫有无重复元素。 每行每列用二重循环,每宫比较复杂,需要考虑每一宫的坐标与二重循环ij对应关系 行i,每一宫3行,3列 x3*(i/3)j/3 y3*(i%3)j%3...
![](https://www.ngui.cc/images/no-images.jpg)
Zookeeper ZNode 数据结构原理
ZNode 学习指南 1. ZNode 基本概念 什么是 ZNode:ZNode 是 Zookeeper 中的数据节点。它类似于文件系统中的文件和目录,ZNode 既可以保存数据又可以作为其他 ZNode 的父节点。ZNode 的路径:每个 ZNode 在 Zookeeper 命名空间中都有一个唯一的路径,如 /app1/config。2. ZNod…...
![](https://www.ngui.cc/images/no-images.jpg)
Golang - 90天从新手到大师
开篇 最近有很多小伙伴都在寻找go语言完整学习资料,我整理了一些Golang方面的知识,方便大家学习。内容从最基础的入门到项目设计,希望帮助更多想了解和学习Go语言的伙伴。 因为是持续创作,所以也会持续更新。有些章节目录还没有…...
![](https://www.ngui.cc/images/no-images.jpg)
MyBatis常用转义字符 大于、小于、大于等于、小于等
在Mybatis编写特殊常用字符你会发现会报错,比如常用的<,>,<,> 等,原因是与xml文件的元素<>冲突,所以需要转义。整理转义字符如下: 符号原始字符转义字符大于>>大于等于>>小于<<小于等于<<和&…...
![](https://img-blog.csdnimg.cn/direct/3b49cbb42a5142988e038a6a65a41743.png)
Python --- 如何修改Jupyter Notebook在本地保存文件的默认路径?
如何修改Jupyter Notebook在本地保存文件的默认路径? 一直以来都比较喜欢jupter notebook,自从用了以后就爱上了。平时用的时候,因为大多都是临时调用,每次在界面里直接new一个新的file就开干。 曾经也想过我创建的这些python文件…...
![](https://www.ngui.cc/images/no-images.jpg)
大模型 舆情分析 数据构造 prompt提示词 经验分享 数据准备
最近在做舆情分析,需要执行比较复杂的任务流程(例如同时执行人名识别、相关机构识别、90分类),传统Bert无法胜任,因此尝试使用大模型进行处理。 下面的一些提示词是我用来准备数据的,这些数据可以按照不同…...
![](https://img-blog.csdnimg.cn/img_convert/ee00f8009797ac3b3b06670360bbf3b1.jpeg)
这些已经死去的软件,依旧无可替代
互联网这条长河里,软件们就像流星一样,一闪而过。有的软件火过一段时间,然后就慢慢消失了。 说不定有些软件你以前天天用,但不知道从什么时候开始就不再用了。时间一天天过去,我们的热情、记忆都在消退,还…...
![](https://img-blog.csdnimg.cn/direct/9b51ede3e83e4826994fa6f715298d08.png)
SYD88xx使代码在RAM内存中执行/运行
SYD88xx使代码在RAM中执行 SYD8811/8810默认都是cache模式的,但是在代码首次运行的时候,需要将代码从flash搬到cache中执行,这样第一次的代码执行可能会比较慢,这里提供一个将需要提速的代码放到RAM中执行的方法。 对于SYD8811…...
![](/images/no-images.jpg)
关于做血糖仪的网站/网站推广包括
目录 一、产品形态 1、集群使用限制 1)限制概述 2)ACK集群配额限制 3)依赖底层云产品配额限制 2、ACK的优势 一、产品形态 更多介绍请点击:什么是容器服务Kubernetes版_容器服务Kubernetes版-阿里云帮助中心 比较项专有版…...
![](https://img-blog.csdnimg.cn/img_convert/fc6d676855784d135adafb67bc0ba434.png)
wordpress paypal插件/站长工具seo综合查询怎么关闭
我的开发环境是Win8VS2013,数据库环境是MySQL(WampServer)1、下载MySQL Connector/Net 6.8.3地址:http://dev.mysql.com/downloads/connector/net/还需要下载一个MySQL for VisualStudio版本,用于在VS中可以在数据源中引用MySQL地址…...
![](/images/no-images.jpg)
简单扁平化风格后台网站模板/网站友情链接
ExtentReports是一种想对美观的报告,并且查看的内容比较丰富 1,安装mongoDB,启动mongo服务 2,代码添加ExtentManager,ExtentTestNGITestListener这两个类, 3,运行的testng.xml中添加监听 4,mave…...
![](/images/no-images.jpg)
dede网站地图不显示文章列表/百度seo 优化
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼{printf("请输入正确日期!/n");goto aaa;}}int LeapYear(int intoYear,int intoMonth,int intoDay)//闰年计算{int today;switch(intoMonth){case 1:today0;break;case 2:today31;break;case 3:today60;break…...
![](/images/no-images.jpg)
刚做的网站适合做外链吗/苏州seo
是40, 在建立数据表的时候要注意一下, 用char类型就可以了转载于:https://www.cnblogs.com/souroot/archive/2012/10/20/2732456.html...
![](/images/no-images.jpg)
企业的网站建设文章/关键词挖掘工具免费
高考考生即将迎来填报志愿环节,也是教育骗局最猖獗之时。个人信息泄露,早就不是新鲜事。但值得关注的是,随着移动互联技术的快速发展,信息泄露已呈全方位态势。 日前,广东省教育厅发布《广东省普通高等学校一览表》&am…...