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

哈希表数据结构学习

哈希表数据结构学习

  • 哈希表
    • 基本概念
    • 哈希方法
    • 单值哈希与多值哈希
    • 哈希冲突
      • 1. 开放寻址法(Open Addressing)
      • 2. 链地址法(Chaining)
      • 3. 再哈希法(Rehashing)
      • 4. 建立公共溢出区(Overflow Area)
      • 5. 扩展线性哈希法(Extendible Hashing)
      • 6. 线性分离法(Cuckoo Hashing)
    • 空间扩容
      • vector扩容
      • 负载因子以及增容
    • GPU上的哈希表

哈希表

这里不区分 hashmap 和 hash table,(个人理解)一般hashmap指哈希表这种数据结构,而hash table指通过这种数据结构建立所得的结果。

哈希表,又称散列表,它通过建立键 key 与值 value 之间的映射,实现高效(O(1) )的元素查询。

为什么哈希又叫散列——其实一个是音译一个是意译。
散列(hash)英文原意是“混杂”、“拼凑”、“重新表述”的意思。

在哈希表中进行增删查改的时间复杂度都是 O(1) 。
查找某个元素是否存在的过程中,数组和链表都需要挨个循环比较,而通过 哈希 计算,可以大大减少比较次数。
在这里插入图片描述

基本概念

若键key或k,其值value或v存放在f(k)对应的桶bucket中。映射关系f为哈希函数或散列函数,所得的表成为哈希表或散列表。

哈希映射由一个桶数组组成,其中每个桶可以包含一个或多个键值对。要在映射中插入新的对,将向键应用哈希函数以生成哈希值。然后使用该哈希值选择其中一个桶。如果存储桶可用,则该对存储在该存储桶中。

例如,要插入键值对 (Alice, 408-555-0148) ,对键,进行散列以获取其散列值( hash(Alice)=4),并选择位置 4 处的存储桶来存储值(408-555-0148)。稍后,要检索与 Alice 关联的值,可以使用相同的哈希函数 hash(Alice), 再次选择位置 4 处的存储桶并检索先前存储的值。

哈希方法

  • 直接寻址法:取关键字或关键字的某个线性函数值为散列地址。即hash(k)=k或hash(k)=ak+b(a,b为常数),(这种散列函数叫做自身函数)。

在LeetCode中常用一维数组

  • 数字分析法:假设关键字是以r为基的数,并且哈希表中可能出现的关键字都是事先知道的,则可取关键字的若干数位组成哈希地址。
  • 平方取中法:取关键字平方后的中间几位为哈希地址。通常在选定哈希函数时不一定能知道关键字的全部情况,取其中的哪几位也不一定合适,而一个数平方后的中间几位数和数的每一位都相关,由此使随机分布的关键字得到的哈希地址也是随机的。取的位数由表长决定。
    折- 叠法:将关键字分割成位数相同的几部分(最后一部分的位数可以不同),然后取这几部分的叠加和(舍去进位)作为哈希地址。
  • 除留余数法:取关键字 key 对某个不大于哈希表长度的质数 p 取余数作为哈希地址,即 hash(key) = key % p。选择质数可以减少哈希冲突。
  • 位运算法:通过对关键字进行位移、异或、与或等位运算来生成哈希值。这种方法速度快且实现简单,尤其适合于二进制数据。
  • 混合哈希法等等

密码学中常见的哈希算法

  • MD5 (Message-Digest Algorithm 5)
    特点:MD5 是一种广泛使用的哈希函数,它将任意长度的输入数据映射为 128 位的散列值(通常表示为 32 位的十六进制数)。
    应用:MD5 常用于数据完整性校验。但是,由于存在碰撞攻击(即不同的输入会生成相同的哈希值),MD5 在加密应用中已被逐步淘汰。

  • SHA-2 (Secure Hash Algorithm 2)
    特点:SHA-2 是 SHA-1 的改进版,具有更强的安全性。SHA-2 包括多个不同的变种,如 SHA-224、SHA-256、SHA-384、SHA-512 等,分别生成 224 位、256 位、384 位和 512 位的散列值。
    应用:SHA-2 广泛应用于数字签名、TLS/SSL 证书和区块链技术中。

单值哈希与多值哈希

讨论哈希表时的一个重要区别是是否允许重复键。

  • 单值哈希表或哈希映射要求键是唯一的(例如 std::unordered_map),单键对单值。
  • 多值哈希表和哈希多映射允许重复键(如 std::unordered_multimap),单键对多值。

哈希冲突

如果表中桶的数量等于可能的键的数量,则可以使用哈希桶和键之间的一对一关系,其中每个键正好映射到表中的一个桶。

然而,这在大多数情况下是不切实际的,因为潜在键值对的数量事先不知道,或者为每个键值对保留存储桶所需的存储将超过可用的存储容量。好比一个电话簿不可能写得下宇宙中每个可能的名字和其号码。

因此,哈希函数通常是不完美的,并可能导致哈希冲突(Hash Collision),其中两个不同的键映射到相同的哈希值( f ( k 1 ) = f ( k 2 ) , k 1 ≠ k 2 f(k_1)=f(k_2),k_1\neq k_2 f(k1)=f(k2),k1=k2)。好的哈希函数寻求最小化冲突的可能性,但在大多数情况下它们是不可避免的。

在这里插入图片描述

在哈希表中,由于不同的关键字可能被映射到相同的哈希地址,导致哈希冲突(Hash Collision)。为了解决哈希冲突,可以采用以下几种常见的方法:

1. 开放寻址法(Open Addressing)

当发生哈希冲突时,开放地址法通过在哈希表中找到另一个空闲位置来存储冲突的关键字。常见的开放地址法有以下几种策略:

  • 线性探测法(Linear Probing) :当发生冲突时,按顺序检查哈希表的下一个位置,直到找到一个空闲位置。
    优点 :实现简单,容易理解。
    缺点 :容易形成“聚集”现象,导致性能下降。
  • 二次探测法(Quadratic Probing) :探测位置不是线性增长,而是按二次函数增长,即探测序列为 hash(key) + 1², hash(key) + 2², ...
    优点 :减少了线性探测法中的聚集问题。
    缺点 :探测序列可能导致访问不到某些位置,尤其是当哈希表大小不是质数时。
  • 双重哈希法(Double Hashing) :使用两个不同的哈希函数 h1(key)h2(key),当发生冲突时,探测序列为 h1(key) + i * h2(key)
    优点 :减少了冲突发生的概率,更均匀地分布关键字。
    缺点 :实现相对复杂,需要设计两个合适的哈希函数。

2. 链地址法(Chaining)

每个哈希表槽位对应一个链表,当多个关键字被映射到同一槽位时,将这些关键字存储在链表中。
优点 :

  • 容易处理不同大小的哈希表。
  • 无需担心哈希表装载因子过大(元素个数超出哈希表大小)。
    缺点 :
  • 链表的使用增加了额外的内存开销。
  • 查找和删除操作的时间复杂度取决于链表的长度,最坏情况下为O(n)。

3. 再哈希法(Rehashing)

当发生冲突时,使用一个新的哈希函数重新计算哈希地址,直到找到一个空闲的位置。
优点 :可以减少冲突的发生,提高哈希表的查找效率。
缺点 :需要设计多个有效的哈希函数,增加了实现复杂性。

4. 建立公共溢出区(Overflow Area)

将冲突的关键字存放在一个公共的溢出区中,而不是在原哈希表中继续查找位置。
优点 :

  • 简化了哈希表的查找逻辑,尤其是当溢出区结构简单时。
    缺点 :
  • 溢出区可能导致查找效率低下,尤其是在溢出区中的元素较多时。
  • 需要额外的内存来存储溢出区。

5. 扩展线性哈希法(Extendible Hashing)

基于二进制哈希值的扩展哈希表,每次冲突会通过增加哈希表的位数来解决冲突。哈希表会随着数据的增加而动态扩展。
优点 :

  • 动态扩展,避免了固定哈希表大小的限制。
  • 分布均匀,减少了冲突的概率。
    缺点 :实现较为复杂,适合需要动态调整哈希表大小的场景。

6. 线性分离法(Cuckoo Hashing)

使用两个哈希函数和两个哈希表,当插入时,如果第一个位置已经被占用,则将占用该位置的元素移动到另一个哈希表中,循环此操作直到没有冲突或达到预设的最大尝试次数。
优点 :

  • 查找时间复杂度为 O(1),因为每个元素最多只能在两个位置上找到。
  • 插入操作复杂度较低。
    缺点 :
  • 可能会出现无限循环,需要重新哈希。
  • 需要更大的哈希表空间来避免频繁的冲突。

每种方法都有其适用的场景和局限性,选择合适的哈希冲突解决方法取决于具体应用的需求、哈希表的大小以及允许的冲突处理开销。

空间扩容

由于哈希表能够直接访问查找元素的地址,所以它的时间复杂度为常数的复杂度 O(1)。而每一个key到address的映射关系需要记录下来,假设哈希表有 n 个元素,那么就需要 n 条记录,故空间复杂度为 O(n)。

关于复杂度记法
Ο,读音:big-oh;表示上界,小于等于。
Ω,读音:big omega、欧米伽;表示下界,大于等于。
Θ,读音:theta、西塔;既是上界也是下界,称为确界,等于。
ο,读音:small-oh;表示上界,小于。
ω,读音:small omega;表示下界,大于。
Ο是渐进上界,Ω是渐进下界。Θ需同时满足大Ο和Ω,故称为确界。Ο极其有用,因为它表示了最差性能。

vector扩容

先看以下vector是怎么扩容的。

vector容器不同于数组,能够进行动态扩容,其底层原理:所谓动态扩容,并不是在原空间之后接续新空间,因为无法保证原空间之后尚有可配置的空间。而是以原大小的两倍另外配置一块较大空间,然后将原内容拷贝过来,并释放原空间。

在这里插入图片描述

push_back扩容机制:当push_back一个元素时,

如果发现size() == capacity(),那么会以两倍空间扩容,然后将元素插入到finish迭代器的下一个元素(注意会申请一个新的空间,并将原有元素拷贝到新空间中,然后释放原有空间)
如果发现size() < capacity(),那么会插入到finish迭代器的下一个元素
不会出现size() > capacity()

pop_back、earse、clear缩容机制
pop_back会减少一个size(),但是不会改变capacity() (finish迭代器前移一位)
earse会减少一个size(),但是不会改变capacity() (finish迭代器前移一位)
clear令size()为0,但是不会改变capacity()(将finish迭代器移动到start相同位置)

对于resize(new_size)
如果new_size== curr.size,什么也不做
如果new_size< curr.size, 那么 curr.size = new_size,curr.capacity不变
如果new_size> curr.size, 那么 curr.size = new_size,curr.capacity = new_size,将容器capacity 扩大到能容纳new_size的大小,改变容器的curr.size,并且创建对象。

对于reserve(new_size)
如果new_size== curr.size,什么也不做
如果new_size< curr.size,什么也不做
如果new_size> curr.size,curr.size不变,curr.capacity=new_size,将容器capacity 扩大到能容纳new_size的大小,在空间内不真正创建对象,所以不改变curr.size

真正的释放内存

vector<int>(v).swap(v); 

vector(v)通过拷贝构造函数创建了一个匿名对象,这个匿名对象拥有v的全部数据,但是,没有空闲的空间,也就是说,这个匿名对象的容量和数据量是相等的。

此时,通过 swap(v) 调用该匿名对象的swap()方法,交换v与匿名对象的内容。

匿名对象在执行完代码之后会自动调用析构函数,那么空间被释放,最终结果就是,原容器中的空位被释放。

在这里插入图片描述

负载因子以及增容

若哈希冲突出现的较为密集,往往代表着此时数据过多,而能够映射的地址过少,而要想解决这个问题,就需要通过 负载因子(装填因子) 的判断来进行增容

负载因子的大小 = 表中数据个数 / 表的容量(长度)

闭散列
对于闭散列来说,因为其是一种线性的结构,所以一旦负载因子过高,就很容易出现哈希冲突的堆积,所以当负载因子达到一定程度时就需要进行增容,并且增容后,为了保证映射关系,还需要将数据重新映射到新位置。对应上述开放寻址法。

闭散列是一种预先分配存储空间的方法。在闭散列中,存储空间被划分为若干个固定大小的桶,每个桶中可以存储多个元素。当插入新元素时,根据其哈希值确定其所属的桶,并将元素添加到该桶中。如果发生哈希冲突,则将元素添加到下一个可用的桶中。这种方法简单易行,但可能会导致某些桶被过度使用,而其他桶仍空闲。
开散列是一种动态调整存储空间的方法。在开散列中,当某个桶已满时,会根据一定规则分配一个新的桶。这种方法可以更好地利用存储空间,但需要额外的空间来管理桶的分配。
在实际应用中,可以根据具体情况选择不同的哈希策略。例如,对于需要快速插入和查找的数据结构,闭散列可能是一个更好的选择。而对于需要高效利用存储空间的数据结构,开散列可能更为合适。

经过算法科学家的计算, 负载因子应当严格的控制在 0.7-0.8 以下,所以一旦负载因子到达这个范围,就需要进行增容。

因为除留余数法等方法通常是按照表的容量来计算,且当对一个质数取模时,冲突的几率会大大的降低,并且因为增容的区间一般是 1.5-2 倍,所以算法科学家列出了一个增容质数表,按照这样的规律增容,冲突的几率会大大的降低。
这也是 STL 中 unordered_map/unordered_set 使用的增容方法

开散列
因为哈希桶是开散列的链式结构,发生了哈希冲突是直接在对应位置位置进行头插,而桶的个数是固定的,而插入的数据会不断增多,随着数据的增多,就可能会导致某一个桶过重,使得效率过低。对应上述拉链法。

在这里插入图片描述
开散列中每个桶放的都是哈希冲突的元素。哈希桶下面挂着的是一个一个的节点(一条链表),如果该位置哈希冲突的元素过多时,通常会将这条链表转为一颗红黑树。


GPU上的哈希表

精心设计的哈希函数通过最大化哈希任意两个键将导致不同哈希值的可能性来最小化冲突次数。这意味着对于任何给定的两个键,它们对应的桶可能位于不同的内存位置。

因此,大多数哈希表操作的内存访问模式实际上是随机的。为了理解哈希表的性能,了解随机内存访问的性能非常重要。

下表比较了理论峰值带宽与在现代 GPUs 和 GPUs 上通过 GUPs benchmark 测量的随机 64 位读取的实现带宽(带宽计算为访问大小乘以访问次数除以时间)。

在这里插入图片描述
随机内存访问大约比理论峰值带宽慢 10 倍。这是因为内存子系统针对顺序访问进行了优化。更重要的是, NVIDIA GPU s 的随机访问吞吐量比现代 CPU s 的高一个数量级。这些结果表明,性能最好的 CPU 哈希表可能比性能最好的 GPU 哈希表慢一个数量级

显存允许的情况下那肯定优先考虑使用GPU哈希表了。

以下是一个CUDA的哈希表三方库:
在这里插入图片描述

在这里插入图片描述


参考

  • maximizing-performance-with-massively-parallel-hash-maps-on-gpus
  • hello-algo/hash_map
  • C++进阶(哈希)

先到这儿。

相关文章:

哈希表数据结构学习

哈希表数据结构学习 哈希表基本概念哈希方法单值哈希与多值哈希哈希冲突1. 开放寻址法&#xff08;Open Addressing&#xff09;2. 链地址法&#xff08;Chaining&#xff09;3. 再哈希法&#xff08;Rehashing&#xff09;4. 建立公共溢出区&#xff08;Overflow Area&#xf…...

数据结构——“二叉搜索树”

二叉搜索树是一个很重要的数据结构&#xff0c;它的特殊结构可以在很短的时间复杂度找到我们想要的数据。最坏情况下的时间复杂度是O(n)&#xff0c;最好是O(logn)。接下来看一看它的接口函数的实现。 为了使用方便&#xff0c;这里采用模版的方式&#xff1a; 一、节点 temp…...

Java零基础-Java对象详解

哈喽&#xff0c;各位小伙伴们&#xff0c;你们好呀&#xff0c;我是喵手。运营社区&#xff1a;C站/掘金/腾讯云/阿里云/华为云/51CTO&#xff1b;欢迎大家常来逛逛 今天我要给大家分享一些自己日常学习到的一些知识点&#xff0c;并以文字的形式跟大家一起交流&#xff0c;互…...

从Prompt到创造:解锁AI的无限潜能

文章目录 &#x1f34a;AI内容创作核心&#xff1a;提示词Prompt1 什么是提示词工程?1.1 提示词的原理是什么&#xff1f;1.2 提示词工程师&#xff1a;百万年薪的职业&#xff1f;1.3 谁都能成为提示词工程师吗&#xff1f; 2 提示词书写的基本技巧3 常见的提示词框架3.1 CO-…...

sqlgun靶场攻略

打开界面 1.输入框测试回显点 -1union select 1,2,3#出现回显点 2.查看数据库名 -1union select 1,2,database()# 3.查看表名 -1union select 1,2,group_concat(table_name) from information_schema.tables where table_schemasqlgunnews# 4.查看admin表中列名 -1union se…...

《网络协议 - HTTP传输协议及状态码解析》

文章目录 一、HTTP协议结构图二、HTTP状态码解读1xx: 信息响应类2xx: 成功响应类3xx: 重定向类4xx: 客户端错误类5xx: 服务器错误类 一、HTTP协议结构图 二、HTTP状态码解读 HTTP状态码&#xff08;英语&#xff1a;HTTP Status Code&#xff09;是用以表示网页服务器超文本传…...

9.11 QT ( Day 4)

一、作业 1.Widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTimerEvent> //定时器类 #include <QTime> #include <QtTextToSpeech> //文本转语音类QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEcl…...

利用AI驱动智能BI数据可视化-深度评测Amazon Quicksight(四)

简介 随着生成式人工智能的兴起&#xff0c;传统的 BI 报表功能已经无法满足用户对于自动化和智能化的需求&#xff0c;今天我们将介绍亚马逊云科技平台上的AI驱动数据可视化神器 – Quicksight&#xff0c;利用生成式AI的能力来加速业务决策&#xff0c;从而提高业务生产力。…...

2024.9最新:CUDA安装,pytorch库安装

目录 一、CUDA安装 1.查看自己电脑适配的CUDA的最高版本 2.安装CUDA 3.检查环境变量是否配置&#xff0c;安装是否成功 二、pytorch库安装 1.pytorch库下载 2.选择合适的版本 3.查看版本 一、CUDA安装 1.查看自己电脑适配的CUDA的最高版本 在命令提示符里输入nvidia-…...

Vue3.0组合式API:setup()函数

1、什么是组合式API Vue 3.0 中新增了组合式 API 的功能&#xff0c;它是一组附加的、基于函数的 API&#xff0c;可以更加灵活地组织组件代码。通过组合式 API 可以使用函数而不是声明选项的方式来编写 Vue 组件。因此&#xff0c;使用组合式 API 可以将组件代码编写为多个函…...

利用AI驱动智能BI数据可视化-深度评测Amazon Quicksight(三)

简介 随着生成式人工智能的兴起&#xff0c;传统的 BI 报表功能已经无法满足用户对于自动化和智能化的需求&#xff0c;今天我们将介绍亚马逊云科技平台上的AI驱动数据可视化神器 – Quicksight&#xff0c;利用生成式AI的能力来加速业务决策&#xff0c;从而提高业务生产力。…...

2022高教社杯全国大学生数学建模竞赛C题 问题一(1) Python代码演示

目录 问题 11.1 对这些玻璃文物的表面风化与其玻璃类型、纹饰和颜色的关系进行分析数据探索 -- 单个分类变量的绘图树形图条形图扇形图雷达图Cramer’s V 相关分析统计检验列联表分析卡方检验Fisher检验绘图堆积条形图分组条形图分类模型Logistic回归随机森林import matplotlib…...

Qt QSerialPort数据发送和接收DataComm

文章目录 Qt QSerialPort数据发送和接收DataComm2.添加 Qt Serial Port 模块3.实例源码 Qt QSerialPort数据发送和接收DataComm Qt 框架的Qt Serial Port 模块提供了访问串口的基本功能&#xff0c;包括串口通信参数配置和数据读写&#xff0c;使用 Qt Serial Port 模块就可以…...

macOS上谷歌浏览器的十大隐藏功能

谷歌浏览器&#xff08;Google Chrome&#xff09;在macOS上拥有一系列强大而隐蔽的特性&#xff0c;这些功能能显著提高您的浏览体验。从多设备同步到提升安全性和效率&#xff0c;这些被低估的功能等待着被发掘。我们将逐步探索这些功能&#xff0c;帮助您最大化利用谷歌浏览…...

【C++篇】C++类与对象深度解析(二):类的默认成员函数详解

文章目录 【C篇】C类与对象深度解析&#xff08;二&#xff09;前言1. 类的默认成员函数2. 构造函数2.1 函数名与类名相同2.2 无返回值2.3 对象实例化时系统会自动调用2.4 构造函数可以重载2.5 默认构造函数的生成规则2.6 无参构造函数与全缺省构造函数的关系2.7 内置类型与自定…...

Linux2-mkdir,touch,cat,more

1.相对路径和绝对路径 cd用于切换目录&#xff0c;对于路径可以用相对路径和绝对路径 例如&#xff1a;cd /home/user/public和cd public效果一样&#xff0c;都是将目录切换到HOME文件夹下的public文件夹 2.特殊路径符 .表示当前目录 ..表示上级目录 ~表示HOME目录 3.m…...

AI 时代程序员的应变之道

一、AI 浪潮来袭&#xff0c;编程界风云变幻 随着 AIGC 大语言模型如 ChatGPT、Midjourney、Claude 等的涌现&#xff0c;AI 辅助编程工具日益普及&#xff0c;程序员的工作方式正经历着深刻的变革。 分析公司 OReilly 日前发布的《2023 Generative AI in the Enterprise》报告…...

SQL编程题复习(24/9/16)

练习题 x40 10-74 获取商品表中商品名称含有“pad”的商品10-75 获取指定商品的商品分类名称&#xff08;多表查询&#xff09;10-76 为sh_goods表添加一行记录10-77 检索出sh_goods表中每项keyword对应的商品数量&#xff0c;查询结果显示字段依据输出样例设置10-78 查询sh_go…...

运维工程师面试整理-操作系统

在运维工程师的面试中,操作系统相关的知识通常是重中之重,尤其是Linux/Unix系统。以下是针对操作系统部分的一些详细内容,帮助你更好地准备面试。 1. Linux/Unix 基础 ● 常用命令 ○ 文件和目录管理:ls, cd, cp, mv, rm, mkdir, rmdir, find, grep, awk, sed...

Linux搭建邮箱服务器(简易版)

本章是上一文档的简易版本搭建方式更为快速简洁&#xff08;只需要两条命令即可搭建&#xff09;&#xff0c;如果想了解更详细一些可以看我上一文档 Linux接发邮件mailx_linux mailx o365-CSDN博客文章浏览阅读857次&#xff0c;点赞25次&#xff0c;收藏19次。本文详细描述了…...

阿里云ACP云计算备考笔记 (5)——弹性伸缩

目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

【JVM】- 内存结构

引言 JVM&#xff1a;Java Virtual Machine 定义&#xff1a;Java虚拟机&#xff0c;Java二进制字节码的运行环境好处&#xff1a; 一次编写&#xff0c;到处运行自动内存管理&#xff0c;垃圾回收的功能数组下标越界检查&#xff08;会抛异常&#xff0c;不会覆盖到其他代码…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序

一、开发准备 ​​环境搭建​​&#xff1a; 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 ​​项目创建​​&#xff1a; File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...

k8s业务程序联调工具-KtConnect

概述 原理 工具作用是建立了一个从本地到集群的单向VPN&#xff0c;根据VPN原理&#xff0c;打通两个内网必然需要借助一个公共中继节点&#xff0c;ktconnect工具巧妙的利用k8s原生的portforward能力&#xff0c;简化了建立连接的过程&#xff0c;apiserver间接起到了中继节…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)

UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中&#xff0c;UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化&#xf…...

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...

【JVM】Java虚拟机(二)——垃圾回收

目录 一、如何判断对象可以回收 &#xff08;一&#xff09;引用计数法 &#xff08;二&#xff09;可达性分析算法 二、垃圾回收算法 &#xff08;一&#xff09;标记清除 &#xff08;二&#xff09;标记整理 &#xff08;三&#xff09;复制 &#xff08;四&#xff…...

逻辑回归暴力训练预测金融欺诈

简述 「使用逻辑回归暴力预测金融欺诈&#xff0c;并不断增加特征维度持续测试」的做法&#xff0c;体现了一种逐步建模与迭代验证的实验思路&#xff0c;在金融欺诈检测中非常有价值&#xff0c;本文作为一篇回顾性记录了早年间公司给某行做反欺诈预测用到的技术和思路。百度…...

根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要

根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分&#xff1a; 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...