当前位置: 首页 > news >正文

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、重点剖析

  1. 该方法首先检查interfaceName是否是一个有效的IP地址:
  2. 如果不是IP地址,检查interfaceName是否是一个有效的子网:
  3. 如果是有效的子网,获取该子网中的所有IP地址,并将每个IP地址封装为InetSocketAddress对象,添加到localAddrs列表中。
  4. 如果既不是IP地址也不是子网,假定它是一个域名:
  5. 通过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、重点剖析

  1. 检查 localInterfaceAddrs 数组是否为空,如果为空则返回 null
  2. 使用随机数生成器 r 生成一个随机索引 idx
  3. 获取并返回 localInterfaceAddrs 数组中对应索引 idxSocketAddress 对象。
  4. 在返回之前,记录调试日志以便于跟踪选中的本地接口地址。

3.5、读写超时时间判定

3.5.1、代码概述

        这段代码包含两个方法:getDatanodeWriteTimeoutgetDatanodeReadTimeout,它们用于计算数据节点写入和读取的超时时间。每个方法都接收一个参数 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、重点剖析

  1. 通过dfsclientconf获取写入\读取超时时间t;
  2. 如果t大于0则返回 t 加上一个扩展超时时间,这个扩展超时时间是常量 HdfsConstants.WRITE_TIMEOUT_EXTENSION 乘以 numNodes(数据节点数量)
  3. 如果t<=0,则返回0

3.6、租约管理

3.6.1、代码概述

        这段代码定义了三个方法:getLeaseRenewerbeginFileLeaseendFileLease,用于管理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,未完待续

相关文章:

hdfs源码解析之DFSClient

1、DFSClient类简介 DFSClient 是 Hadoop 分布式文件系统&#xff08;HDFS&#xff09;中的一个核心类&#xff0c;用于客户端与 HDFS 之间的交互。它提供了一组方法&#xff0c;使客户端应用程序可以方便地与 HDFS 进行通信&#xff0c;包括文件的读取、写入、创建、删除、重命…...

智能化立体仓库的种类有哪些?

在仓储运输系统中&#xff0c;自动化立体仓库可充分利用空间储存货物&#xff0c;故而也被称之为高层货架仓库。在实际应用中&#xff0c;自动化仓库系统是不需人工处理的情况下能自动存储和取出物料的系统。那么&#xff0c;智能化立体仓库的种类有哪些&#xff1f;下面就让小…...

Stable Diffusion 3 如何下载安装使用及性能优化

Stable Diffusion 3 Stable Diffusion 3&#xff08;SD3&#xff09;&#xff0c;Stability AI最新推出的Stable Diffusion模型系列&#xff0c;现在可以在Hugging Face Hub上使用&#xff0c;并且可以与Diffusers一起使用。 今天发布的模型是Stable Diffusion 3 Medium&…...

c语言操作符详解

操作符详解 正数的原码反码补码相同 负数的原码最高位数是1&#xff0c;正数为0 整数在内存中存储的是补码 负数的左移与右移&#xff0c;移的是补码&#xff0c;打印的是源码 补码-1取反就是原码。 左移有乘2的效果 左移和右移只针对整数。 vs里的右移操作赋采用的是算数右…...

【耐水好】强耐水UV胶水它的粘接强度和普通UV胶水比如何呢

【耐水好】强耐水UV胶水它的粘接强度和普通UV胶水比如何呢 强耐水UV胶水的粘接强度与普通UV胶水相比&#xff0c;具有显著的优势。以下是详细的比较和归纳&#xff1a; 固化方式&#xff1a; 两者都是通过紫外线&#xff08;UV&#xff09;照射进行固化&#xff0c;但强耐水UV…...

jumpserver堡垒机集群搭建

1、环境 操作系统&#xff1a;龙蜥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…...

Termius for Mac/Win:跨平台多协议远程管理利器

Termius for Mac/Win是一款备受瞩目的跨平台多协议远程管理软件&#xff0c;以其卓越的性能、丰富的功能和便捷的操作体验&#xff0c;赢得了广大用户的青睐。无论是在企业IT管理、系统维护&#xff0c;还是个人远程连接、文件传输等方面&#xff0c;Termius都展现出了出色的实…...

Unity OpenCVForUnity 安装和第二个案例详解 <二>

目录 一、前言 二、场景介绍 1.WebCamTextureToMatExample脚本 2.FpsMonitor脚本 三、 结构体Scaler 四、找到相机并使用 1.相机的启用 2.格式转换 a.把webCamTexture转换成Mat b.把Mat转换成Texture2D 五、脚本组合 六、作者的碎碎念 一、前言 第二个案例&#xf…...

Lua实现自定义函数面向对象编程

本文目录 1、引言2、原理3、实例4、层析验证 文章对应视频教程&#xff1a; 暂无&#xff0c;可以关注我的B站账号等待更新。 点击图片或链接访问我的B站主页~~~ 1、引言 在现代软件开发中&#xff0c;面向对象编程&#xff08;OOP&#xff09;已经成为一种广泛使用的编程范式…...

docker安装消息队列mq中的rabbit服务

在现代化的分布式系统中&#xff0c;消息队列&#xff08;Message Queue, MQ&#xff09;已经成为了一种不可或缺的组件。RabbitMQ作为一款高性能、开源的消息队列软件&#xff0c;因其高可用性、可扩展性和易用性而广受欢迎。本文将详细介绍如何在Docker环境中安装RabbitMQ服务…...

OpenAI新模型发布,免费开放GPT-4o!但只开放一点点...

GPT-4o 中的“o”代表“omni”——指的是 GPT-4o 的多模态。 该模型将向免费客户开放&#xff0c;这意味着任何人都可以通过 ChatGPT 访问 OpenAI 最先进的技术。 GPT-4o 是 OpenAI 昨天晚上发布的新旗舰模型&#xff0c;可以实时推理音频、视觉和文本。 据官方介绍&#xff0…...

idea的右边栏maven不见了(丢了)解决方案以及idea无法识别maven项目

前言 众所周知&#xff0c;idea是java开发中不可缺少的利器&#xff0c;但是由于功能过多&#xff0c;导致奇怪的问题也很多 问题汇总 idea的右边栏maven丢了 idea无法识别maven项目 对应的解决办法 idea的右边栏maven丢了 原因可能是被自己手动移除了 或者 项目没被正确…...

等待 chrome.storage.local.get() 完成

chrome.storage.local.get() 获取存储处理并计数&#xff0c;内部计数正常&#xff0c;外部使用始终为0&#xff0c;百思不得其解。 如何在继续执行之前等待异步chrome.storage.local.get()完成-腾讯云开发者社区-腾讯云 (tencent.com) 原来我忽略了异步问题&#xff0c;最简…...

004 AOP使用

文章目录 基于AspectJ的AOP的使用添加依赖编写目标类和目标方法使用XML实现实现步骤切入点表达式通知类型 使用注解实现实现步骤环绕通知注解配置定义通用切入点 纯注解方式 基于AspectJ的AOP的使用 其实就是指的SpringAspectJ整合&#xff0c;不过Spring已经将AspectJ收录到自…...

Zookeeper 集群广播事务性能如何保证?

Zookeeper 集群广播事务性能如何保证? zookeeper是如何保证广播事务时,从开始到多数节点确认事务这个高效的? 在 Zookeeper 中,确保广播事务从开始到多数节点确认的高效性至关重要。Zookeeper 通过以下几个关键机制 和优化策略来实现这一目标: ZAB 协议(Zookeeper Atom…...

【vue解决el-input组件自动填充用户名密码】

解决el-input组件自动填充用户名密码 发现用autocomplete"off"并不能解决el-input组件自动填充密码的问题。 解决方法 auto-complete"new-password" 在el-input组件添加auto-complete"new-password" 即可...

案例练习:演讲比赛

演讲比赛: 比赛规则&#xff1a; 某市举行一场演讲比赛&#xff08; speech_contest &#xff09;&#xff0c;共有 24 个人参加。比赛共三轮&#xff0c;前两轮为淘汰赛&#xff0c;第三轮为决赛。 比赛方式&#xff1a;分组比赛&#xff0c;每组 6 个人&#xff1b;选手每次…...

推荐一个很好用的Latex写代码的软件

软件名称&#xff1a;Axmath 据说是国产软件&#xff0c;好用是真好用&#xff08;去哪找&#xff1f;比如某地球号的公主号或其他地方&#xff09;我是推荐付费购买使用 1.通过图形操作&#xff0c;选择要转成Latex代码的符号&#xff0c;按下转换&#xff0c;直接就出现了我…...

windows 程序右键管理员点击无响应

Windows 程序在右键单击以管理员身份运行时没有响应&#xff0c;可能是由于多种原因引起的。下面是一些常见的问题和解决方案&#xff1a; 1. 用户账户控制 (UAC) 设置问题&#xff1a; - 试着降低或提高 UAC 设置&#xff0c;然后再试一次。可以在控制面板的“用户账户”部…...

开发基于Java语言的SaaS(Software-as-a-Service,软件即服务)模式的HIS系统详解 HIS系统源码 支持二开

开发基于Java语言的SaaS&#xff08;Software-as-a-Service&#xff0c;软件即服务&#xff09;模式的HIS系统详解 HIS系统源码 支持二开 开发基于Java语言的SaaS&#xff08;Software-as-a-Service&#xff0c;软件即服务&#xff09;模式的HIS&#xff08;Hospital Informat…...

Xshell远程连接Kali(默认 | 私钥)Note版

前言:xshell远程连接&#xff0c;私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...

黑马Mybatis

Mybatis 表现层&#xff1a;页面展示 业务层&#xff1a;逻辑处理 持久层&#xff1a;持久数据化保存 在这里插入图片描述 Mybatis快速入门 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/6501c2109c4442118ceb6014725e48e4.png //logback.xml <?xml ver…...

实现弹窗随键盘上移居中

实现弹窗随键盘上移的核心思路 在Android中&#xff0c;可以通过监听键盘的显示和隐藏事件&#xff0c;动态调整弹窗的位置。关键点在于获取键盘高度&#xff0c;并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...

2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)

安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...

【JavaSE】多线程基础学习笔记

多线程基础 -线程相关概念 程序&#xff08;Program&#xff09; 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序&#xff0c;比如我们使用QQ&#xff0c;就启动了一个进程&#xff0c;操作系统就会为该进程分配内存…...

[大语言模型]在个人电脑上部署ollama 并进行管理,最后配置AI程序开发助手.

ollama官网: 下载 https://ollama.com/ 安装 查看可以使用的模型 https://ollama.com/search 例如 https://ollama.com/library/deepseek-r1/tags # deepseek-r1:7bollama pull deepseek-r1:7b改token数量为409622 16384 ollama命令说明 ollama serve #&#xff1a…...

嵌入式常见 CPU 架构

架构类型架构厂商芯片厂商典型芯片特点与应用场景PICRISC (8/16 位)MicrochipMicrochipPIC16F877A、PIC18F4550简化指令集&#xff0c;单周期执行&#xff1b;低功耗、CIP 独立外设&#xff1b;用于家电、小电机控制、安防面板等嵌入式场景8051CISC (8 位)Intel&#xff08;原始…...

pgsql:还原数据库后出现重复序列导致“more than one owned sequence found“报错问题的解决

问题&#xff1a; pgsql数据库通过备份数据库文件进行还原时&#xff0c;如果表中有自增序列&#xff0c;还原后可能会出现重复的序列&#xff0c;此时若向表中插入新行时会出现“more than one owned sequence found”的报错提示。 点击菜单“其它”-》“序列”&#xff0c;…...

Linux 内存管理调试分析:ftrace、perf、crash 的系统化使用

Linux 内存管理调试分析&#xff1a;ftrace、perf、crash 的系统化使用 Linux 内核内存管理是构成整个内核性能和系统稳定性的基础&#xff0c;但这一子系统结构复杂&#xff0c;常常有设置失败、性能展示不良、OOM 杀进程等问题。要分析这些问题&#xff0c;需要一套工具化、…...

深入理解 C++ 左值右值、std::move 与函数重载中的参数传递

在 C 编程中&#xff0c;左值和右值的概念以及std::move的使用&#xff0c;常常让开发者感到困惑。特别是在函数重载场景下&#xff0c;如何合理利用这些特性来优化代码性能、确保语义正确&#xff0c;更是一个值得深入探讨的话题。 在开始之前&#xff0c;先提出几个问题&…...