ElasticSearch学习篇17_《检索技术核心20讲》最邻近检索-局部敏感哈希、乘积量化PQ思路

news2025/1/15 21:09:55

目录

场景在搜索引擎和推荐引擎中,对相似文章去重是一个非常重要的环节,另外是拍照识花、摇一摇搜歌等场景都可以使用它快速检索。

基于敏感性哈希的检索更擅长处理字面上的相似而不是语义上的相似。

  • 向量空间模型
  • ANN检索加速思路
    • 局部敏感哈希编码
      • 随机超平面划分哈希编码思路
      • Google的SimHash编码思路以及抽屉原理
    • 聚类
    • 乘积量化

ANN与向量空间模型

对于高纬度数据近邻检索常见方式

将所有文档中的关键词都提取出来,如果总共n个关键词,那么就是一个n纬度的向量。具体到一篇文章,假如文档包含关键词数量是k,其中(0<=k<=n),如果文档包含的第k个关键词的权重为w,那么权重向量k位置的元素就是w,这个权重w一般是根据TF-IDF计算得出,如果文档不包含第k个关键词,那么权重w就是0。

关于TF-IDF词频-逆文档频率参考往期:

ElasticSearch学习篇15_《检索技术核心20讲》进阶篇之TopK检索-CSDN博客

本质就转化为计算两个向量的相似度,可用余弦相似度、欧式距离等计算,另外n纬向量放入到空间中就是一个点,也可理解为空间中的近邻检索ANN,在十几维量级的低维空间中,我们可以使用 k-d 树进行 k 维空间的近邻检索,这种思路就是前面说的精确检索的思路,它的性能还是不错的,但是纬度上来之后,因为基础k-d树特点当纬度大于20的时候可能出现线性灾难,搜索大量的邻域导致性能很慢。

关于KD树、KDB、BKD树参考往期:

ElasticSearch学习篇10_Lucene数据存储之BKD动态磁盘树(论文Bkd-Tree: A Dynamic Scalable kd-Tree)_bkd树-CSDN博客

向量空间模型可用来表示文字、图片等内容,从而进行文本、图像近邻搜索ANN,一些常见的ANN加速算法思想基本分为两类

  • 缩小候选集
  • 压缩向量存储空间

ANN搜索加速技术思想

局部敏感哈希-缩小候选集数量

借助非精确检索的思路,可以将高纬空间中的点进行区域划分,然后给每个区域生成一个较短的编码,查询的时候先根据规则定位区域,达到缩小候选集的目的,再从该区域高效近邻检索。

这个规则就类似哈希,但是普通的哈希函数值不太可控,文章中变化很少的关键词就会导致哈希值很大的变动。

因此必须找出一个特殊的哈希规则,使得相似的数据哈希之后,得到的哈希值也是相近的,被称为局部敏感性哈希(Locality-Sensitive Hashing)

随机超平面划分哈希编码

以二维空间举例,找出一条线,将区域划分为两部分,处在区域1的点编码为1,处在另外区域的点编码为0,这条线需要尽可能合理,因此可以随机找出n条线,一条线切分下,会对点增加一位编码,这样n条线就会给一个点产生n位的编码。

对于多维空间,就需要找超平面,如n个纬度就找n个超平面,然后这些超平面将空间中的点切割,位于超平面两侧的点(通过超平面法向量的余弦相似度计算)分别被编码0、1,这样可以将高维空间的点映射为一纬的编码。

如果两个点的哈希值是一样的,那么两个点大概率距离的非常近,即使哈希值不一样,只要他们在n个比特位中大大部分是相同的(具体的计算算法如海明距离),说明他们大概率相近。举个例子如果两篇文章内容是100%相同的,那么他们的哈希值就是相同的,也就相当于编码相同。

这种一般哈希编码有个缺点就是随着超线、超平面的划分编码,会丢失某些纬度权重信息。

SimHash编码

谷歌提出的局部敏感哈希策略,简化哈希函数,保留多维数据(点)项的权重信息。

它使用一个普通的哈希函数代替了n次随机超平面划分,这个哈希函数作用对象不是整体所有的高纬度数据项,而是一个个处理高纬度数据项,通过数据项哈希值编码与数据项权重计算的时候就能保留权重。

构造SimHash的具体过程,以一篇文档进行局部敏感哈希编码来说明

  • 文档分词,关键词项带权重:分词并计算每个关键词的权重w。
  • 生成Hash值:使用一般的Hash函数,针对每个关键词生成如64位的0、1哈希值编码。
  • 每个关键词哈希值变化:将哈希值的0改为-1,如10110 -> 1 -1 1 1 -1
  • 每个关键词哈希值按位乘上词权重:如词权重3,变为 3 -3 3 3 -3。
  • 按位相加所有关键词的哈希值:计算文档所有关键词哈希值按位加的结果。
  • 文档哈希值编码转换:将编码转为0、1。

这样,文档的最终哈希编码是收到权重比较大的词影响比较多的,另外就是哈希函数比较简单,代替了复杂的随机选取超平面方式。

抽屉原理

对于文章查重领域,如果两个文章的SimHash编码的距离(使用汉明距离计算)小于k,那么就认为它们是相似的。举个例子当k=3的时候,需要找出k小于3的文章,然后遍历逐一计算对比,效率比较低,有没有加速方案?

一个直观的想法,使用SimHash编码某一位bit作为key,使用文章内容作为value构建倒排索引,以64位的SimHash编码为例,key的数量为128个,构造的倒排索引key如

  • 1xxxxx、0xxxxx
  • x1xxxx、x0xxxx

查找的时候,逐位查找64次,将第n为比特位对应key对应的文章全部取出来,然后计算对比。

这种方式效率不是很高,因为即使两篇文章64位bit任意两个位置的bit相同的话就会被召回,即使不太相似。

Google提出优化的抽屉原理:将文章的SimHash编码分4段,如果想找出和此文章bit位差异不超过3个的文章,那么4个段其中一定至少有一个段的bit是完全一致的。因此查询就被转化为了4段中有一段完全相同的文章会被召回。

按照这个思路,

  • 分段构建倒排索引:将每个文档的SimHash编码划分为四段,每段的16位bit作为一个倒排索引,
  • 分段查询:查询的时候,当前文档的SimHash编码也会被划分为四段,如果找出汉明距离k<3的文档,只需召回四段中任一段完全相同的文档即可,然后从四段倒排索引找回的结果合并。

通过使用 SimHash 函数和分段检索(抽屉原理),使得 Google 能在百亿级别的网页中快速完成过滤相似网页的功能,从而保证搜索结果的数量。

思考1:对于 SimHash,如果将海明距离在 4 之内的文章都定义为相似的,那我们应该将哈希值分为几段进行索引和查询呢?分为5段,因为4为不同的bit位最多能影响四段,虽然除不尽,每段可以是12或者13,查询的时候也按照这种规则划分5段即可。

对比编辑距离、杰卡德算法计算文本相似性

对比杰卡德、莱文斯坦、SimHash三种计算文章相似度的效果,总结特点以及适用场景。

SimHash的一种实现参考:SimHash结合汉明距离判断文本相似性

下面选取一套初中语文的试卷,试卷包含大概20道试题,大概1w字符

手动创造不同的CASE,以下是包含完整CASE描述的表格:

CASE描述原文内容长度内容长度simHash相似度simHash耗时levenshtein相似度levenshtein耗时jaccard相似度jaccard耗时
CASE1将21题和22题互相换位置85568556100.0274ms0.84298ms1.07ms
CASE2删除试卷中间的11题8556840196.88102ms0.98274ms1.01ms
CASE3删除10题之后的所有内容8556192165.6330ms0.2241ms1.02ms
CASE4完全打乱试题顺序85568560100.045ms0.45183ms1.01ms
CASE5删除11题之前的所有内容8556663592.1940ms0.77143ms1.01ms
CASE6前11道题内容不相同,后面内容相同8556918489.0640ms0.74194ms0.90359712230215831ms
CASE7在11题后面中间加入一道试题8556874198.4437ms0.97186ms1.01ms

绘制成图表

在选取初中语文试卷内容1w字符文本相似度计算场景下,综合CASE分析文本相似度计算效率以及严格程度

  • 效率:杰卡德 > SimHash > 莱文斯坦编辑距离
  • 严格程度:莱文斯坦编辑距离 > SimHash > 杰卡德

针对CASE2、CASE3分析,即使试卷内容1和试卷内容2相差了一道或者十多道试题,但是杰卡德计算的文本相似度仍为100,SimHash计算的文本相似度较为准确,但是效率又要比莱文斯坦效率要高,使用SimHash可以避免查重中将不是完全一致的试卷内容(差别几道试题)误查,同时又兼顾相似度计算效率。

SimHash、杰卡德(Jaccard)和莱文斯坦(Levenshtein)是三种常用的文本相似度计算算法,它们各有特点和适用场景:

  1. SimHash:局部敏感性哈希
    • 特点:SimHash是一种局部敏感哈希算法,主要用于快速计算大规模文本数据的相似性。它通过将文本转换为一个固定长度的二进制哈希值来表示文本特征。SimHash的优点是计算速度快,适合处理大规模数据。
    • 适用场景:SimHash常用于海量数据的去重、近似重复检测和相似文档查找等场景。由于其计算效率高,特别适合需要快速处理和比较大量文本的应用。
  2. 杰卡德(Jaccard)相似系数
    • 特点:杰卡德相似系数用于衡量两个集合的相似度,定义为两个集合交集的大小除以并集的大小。对于文本相似性,通常将文本分割成词或字符的集合,然后计算这些集合的杰卡德相似度。
    • 适用场景:杰卡德相似度适合用于比较短文本或关键词集合的相似性,如文档分类、标签推荐等。由于其计算简单,适合用于需要快速评估文本相似性的场合。
  3. 莱文斯坦(Levenshtein)距离
    • 特点:莱文斯坦距离,又称编辑距离,表示将一个字符串转换为另一个字符串所需的最小编辑操作次数(插入、删除、替换)。它能够精确地衡量两个字符串之间的差异。
    • 适用场景:莱文斯坦距离适合用于需要精确比较字符串差异的场合,如拼写检查、DNA序列比对、文本纠错等。由于其计算复杂度较高,通常用于较短文本的比较。

总结来说,SimHash适合大规模文本的快速相似性检测,杰卡德相似度适合集合间的相似性比较,而莱文斯坦距离适合精确的字符串差异分析。选择合适的算法需要根据具体的应用场景和数据特征来决定。

汉明距离

主要是计算等长的两个二进制字符串之间差别的位数

def hamming_distance(str1, str2):
    if len(str1) != len(str2):
        raise ValueError("Strings must be of the same length")
    
    distance = 0
    for ch1, ch2 in zip(str1, str2):
        if ch1 != ch2:
            distance += 1
    
    return distance

# 示例
str1 = "1101"
str2 = "1001"
print(hamming_distance(str1, str2))  # 输出: 1

聚类-缩小候选集数量

图片如何相似性检索,检索图片和检索文章一样,首先要先用向量空间模型将图片表示出来,这样图像就变成了高纬度空间的一个点,搜素图片转化为了高纬度空间的ANN。

如何从图片抽取向量空间模型,如果把图像的每个像素看作一个纬度,像素上的RGB值作为纬度值,是一种思路,但是一张图片的纬度大概是百万级别,检索起来很复杂,因此另外一种方式就是使用CNN等进行图像特征提取,转为一个512或者1024纬度的向量空间模型。

如何加速ANN检索效率,有了向量空间模型,就可以使用ANN加速技术比如SimHash来加速检索,比如将高纬空间的点划分到有限区域,从而达到缩小候选集的目的。但是SimHash哈希函数比较简单,更适合计算字面上的相似性而不是语义上的相似性,同时SimHash是一种粒度很粗的非精确检索方案,他能将上百万的纬度压缩为64位bit,损失不少精度。因此一般使用聚类方案加速ANN检索,常见的一种是K-Means(K-平均算法)方案

K-Means聚类算法构建聚类计算步骤

  • 初始聚类中心:随机从数据中选取k个数据作为初始聚类中心
  • 计算距离:计算其他数据与ki 的距离,加入到最邻近的ki 聚类中
  • 根据距离均值重新选取聚类中心:根据聚类中的点到聚类中心距离的均值,重新选一个聚类中心

重复2-3步,即重新计算其他还数据到聚类中心的距离,然后将节点划分到最近的聚类中,然后在更新聚类中心。

K-Means 聚类算法的优化目标是,类内的点到类中心的距离均值总和最短。构建好之后,以聚类中心数据ID作为key,单个聚类的数据创建倒排索引。

K-Means查询的时候,直接找出待查询数据距离最近的聚类中心ki 然后从倒排索引取出topK候选集,

  • 如果不足topK数量,那么可以再查询邻近聚类的候选集。
  • 如果数量很多同时topK又取得非常大,那么一个一个计算和待查询数据距离代价也很大,可以采用层级子聚类来继续缩小候选集。

乘积量化-压缩向量模型存储空间

对于向量的相似检索,除了检索算法本身,优化向量存储空间也是一个优化方向,因为向量的相似度计算需要加载进内存。

以一个1024纬度的向量距离,每个向量纬度是一个浮点数占4 Bytes = 32 bits,那么一个向量占用1KB空间,如果是上亿级的数据,存储向量需要占几百个G。(100 000 000 KB = 100 GB)

为了更好的将向量加载进去内存,需要对向量存储空间优化,一种思路是使用上面的聚类思想,减少加载进内存的数量,只把查询向量和聚类向量加载进内存,而不是聚类下所有向量,这样可能会损失结果粒度。另外一种思路就是使用向量量化-乘积量化来压缩。

乘积量化的概念

  • 乘积:高纬空间向量可以看作是多个低纬空间向量相乘的结果,可以理解为笛卡尔集,如数轴的x、y轴分别表示一纬空间,数轴区域中的点(xi.yi)就是二维空间的点,假如xi的值为1、2、3,yi的值为5、6、7,那么组合笛卡尔集的二纬空间的点个数为9个。
  • 量化:将区域划分为子区域,然后在编码,这样就能将区域转为1纬编码,上面聚类就是一种量化方式。

乘积量化就是将高纬空间划分为多个子空间,然后对子空间编码,针对子空间在进行聚类技术分为多个子区域,然后给每个子区域编码即聚类ID。好处:省空间,二纬空间存储的点数量为9,但是只存储一纬空间x、y的话,只需要存储的数量为6个一纬点。

举例假设一组1024纬度的向量进行乘积量化

  • 首先将1024纬度向量拆分为4个256纬度子向量
  • 在每一个256纬度子向量进行聚类,找出1-256和聚类ID,因此只使用8 bits就能表示1-256的聚类ID。

所以经过上述过程,1024纬度的向量使用 4 * 8 bits = 32 bit就能表示。

乘积量化PQ过程思想

乘积量化向量相似查询的时候,涉及到三个向量

  • 样本向量:1024纬度,乘积量化过程会被压缩为4段,每段进行聚类,每段会得到一个聚类中心ID,范围为1-256,最后所有样本处理完后,大概会得到 256 * 4 个聚类中心向量。
  • 聚类中心向量:每段都有256个聚类中心ID,256 * 4 个聚类中心向量。
  • 查询向量:1024纬度,查询过程会被压缩4段。

构造的时候,样本向量会被压缩为4段,会得到256 * 4的聚类中心向量,而样本向量也从1024纬度被压缩为32纬,1024 => 4 * 256 => 4 * 2 ^ 8,压缩含义就是以每段聚类中心ID的8为bit编码代替当前子向量段。

当计算查询向量和样本向量的距离时,

  • 向量切分子空间:我们将查询向量和样本向量都分为 4 段子空间。
  • 子空间计算聚类ID:计算查询向量切分的4段子空间的聚类ID,生成压缩向量。然后预生成一个距离表,该距离表纬度是256 * 4,记录了查询子向量和 子空间各个中心向量的距离。
  • 遍历全部样本数量计算查询向量距离:根据预处理阶段的距离表可以查询出查询向量每段到各个聚类ID的距离,数据库中全部的样本向量属于哪个聚类ID也可以计算出,然后就是求出每段距离:d1、d2、d3、d4,最终通过相关运算如欧式距离等计算两个向量的距离,进而返回topK。

PQ主要是为了压缩空间,计算距离算法不太关注。

其他参考:理解 product quantization 算法

这样,求查询子向量和样本子向量的距离,就转换为求查询子向量和对应的聚类中心向量的距离。那我们只需要将样本子向量所属的聚类中心的聚类 ID 作为 key 去查距离表,就能在 O(1) 的时间代价内知道这个距离了。

这里讲述的只是大致思想,具体的如何计算找出紧邻的topK向量还有 基于倒排的乘积量化IVFPQ缩小遍历全部样本空间向量,以及SDC、ADC向量相似检索算法还有很多小细节。

基于倒排索引的IVFPQ思想

上面说的计算查询向量和所有样本向量之间的距离是遍历全部的样本空间,还有一种维护样本向量倒排索引的方式加速检索。

构建倒排索引的具体的思路

  • 样本向量切分子空间:1024纬切分为4段,每段256纬度
  • 计算子空间聚类ID:可以采用KMeans聚类算法,最终每个子空间(段)聚类256个,每个子空间使用聚类ID代表当前样本子空间特征,最终每个子空间得到8位的聚类ID
  • 建立倒排索引:得到的32位新向量,为每个子空间创建一个倒排索引,每个倒排索引的key可以设置为当前段的聚类ID,value设置为在当前段被聚类到该ID的所有样本数量。

查询的时候,查询向量进行切分子空间,PQ,然后逐段查倒排,这样将四个段的样本数量就是最有可能相近的样本数量,在进行距离计算找出TopK。

另外还有一种根据聚类ID向量残差创建倒排索引的做法,这样做精度会高一些。

思考

如果二维空间中有 16 个点,它们是由 x 轴的 1、2、3、4 四个点,以及 y 轴的 1、2、3、4 四个点两两相乘组合成的。那么,对于二维空间中的这 16 个样本点,如果使用乘积量化的思路,你会怎么进行压缩存储?当我们新增了一个点 (17,17) 时,它的查询过程又是怎么样的?

主要的思想就是使用两纬位置代替真实的二维点值,对于16个样本点,首先是定义x、y轴两个集合,然后将点的x、y轴的值压缩为对应x、y轴集合的索引值,索引值数值相对于点的值是比较小的,通过PQ可以节省存储空间。当新增了一个点(17,17),只需要向x、y轴集合添加17,查询的时候,先判断x、y轴集合是否有值17,若都有的话索引为(xi=5,yi=5),索引对应的点就是要找的(17,17)

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

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

相关文章

针对git、giteeVSCode连接的使用 || Live Share插件使用

1.下载git 链接 打开终端&#xff0c;桌面鼠标右键 2.配置密钥 登录gitee。 设置密钥 查看官方文档 跟着教程 复制最后的输出进行密钥添加 验证是否添加成功 3.创建&连接远程仓库 创建仓库 git终端进行配置 远程仓库克隆到本地 桌面终端clone,克隆他人|自己的仓库到本地…

【Pikachu】XML外部实体注入实战

若天下不定&#xff0c;吾往&#xff1b;若世道不平&#xff0c;不回&#xff01; 1.XXE漏洞实战 首先写入一个合法的xml文档 <?xml version "1.0"?> <!DOCTYPE gfzq [<!ENTITY gfzq "gfzq"> ]> <name>&gfzq;</name&…

【vmware+ubuntu16.04】ROS学习_博物馆仿真克隆ROS-Academy-for-Beginners软件包处理依赖报错问题

首先安装git 进入终端&#xff0c;输入sudo apt-get install git 安装后&#xff0c;创建一个工作空间名为tutorial_ws&#xff0c; 输入 mkdir tutorial_ws#创建工作空间 cd tutorial_ws#进入 mkdir src cd src git clone https://github.com/DroidAITech/ROS-Academy-for-Be…

【澜舟科技-注册/登录安全分析报告】

前言 由于网站注册入口容易被机器执行自动化程序攻击&#xff0c;存在如下风险&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露&#xff0c;不符合国家等级保护的要求。短信盗刷带来的拒绝服务风险 &#xff0c;造成用户无法登陆、注册&#xff0c;大量收到垃圾短信的…

thinkphp6 --数据库操作 增删改查

一、数据库连接配置 如果是本地测试&#xff0c;它会优先读取 .env 配置&#xff0c;然后再读取 database.php 的配置&#xff1b; 如果禁用了 .env 配置&#xff0c;则会读取数据库连接的默认配置&#xff1a; # .env文件&#xff0c;部署服务器&#xff0c;请禁用我 我们可以…

Excel数据动态获取与映射

处理代码 动态映射 动态读取 excel 中的数据&#xff0c;并通过 json 配置 指定对应列的值映射到模板中的什么字段上 private void GetFreightFeeByExcel(string filePath) {// 文件名需要以快递公司命名 便于映射查询string fileName Path.GetFileNameWithoutExtension(fi…

Python学习29天

二分查找 # 定义函数冒泡排序法从大到小排列 def bbble_sort(list):# i控制排序次数for i in range(len(list) - 1):# j控制每次排序比较次数for j in range(len(list) - 1 - i):if list[j] < list[j 1]:list[j], list[j 1] list[j 1], list[j] # 定义二分查找函数 def…

nodemon入门介绍

以前&#xff0c;我们开发一个node后端服务时&#xff0c;每次更改文件&#xff0c;均需重启一下&#xff0c;服务才能生效。这使我们的开发效率降低了很多。nodemon的出现&#xff0c;可以随时监听文件的变更&#xff0c;自动重启服务&#xff0c;我们开发时只需关注代码即可&…

STM32设计防丢防摔智能行李箱-分享

目录 目录 前言 一、本设计主要实现哪些很“开门”功能&#xff1f; 二、电路设计原理图 1.电路图采用Altium Designer进行设计&#xff1a; 2.实物展示图片 三、程序源代码设计 四、获取资料内容 前言 随着科技的不断发展&#xff0c;嵌入式系统、物联网技术、智能设备…

Pytest 学习 @allure.severity 标记用例级别的使用

一、前言 使用allure.serverity注解&#xff0c;可以在allure报告中清晰的看到不同级别用例情况 使用等级介绍 allure提供的枚举类 二、等级介绍 二、等级介绍 blocker&#xff1a;阻塞缺陷&#xff08;功能未实现&#xff0c;无法下一步&#xff09; critical&#xff1a;…

[javascript]js的五子棋让红蓝双方自己跟自己下棋

运行效果&#xff08;这是未分出胜负&#xff09;&#xff1a; 这是分出胜负&#xff1a; 源代码&#xff0c;把下边的代码放到1.html&#xff0c;然后用浏览器打开&#xff0c;就可以&#xff0c;然后刷新网页&#xff1a; <!DOCTYPE html> <html><body>&l…

Go语言中AES加密算法的实现与应用

一、前言 在当今的软件开发领域&#xff0c;数据安全至关重要。加密技术作为保护数据机密性的关键手段&#xff0c;被广泛应用于各个方面。AES&#xff08;高级加密标准&#xff09;作为一种对称加密算法&#xff0c;以其高效性和安全性在众多加密场景中占据重要地位。本文将详…

单片机GPIO中断+定时器 实现模拟串口接收

单片机GPIO中断定时器 实现模拟串口接收 解决思路代码示例 解决思路 串口波特率9600bps,每个bit约为1000000us/9600104.16us&#xff1b; 定时器第一次定时时间设为52us即半个bit的时间&#xff0c;其目的是偏移半个bit时间&#xff0c;之后的每104us采样并读取1bit数据。使得…

近几年新笔记本重装系统方法及一些注意事项

新笔记本怎么重装系统&#xff1f; 近几年的新笔记本默认开启了raid on模式或vmd选项&#xff0c;安装过程中会遇到问题&#xff0c;新笔记本电脑重装自带的系统建议采用u盘方式安装&#xff0c;默认新笔记本有bitlocker加密机制&#xff0c;如果采用一键重装系统或硬盘方式安装…

【支持向量机(SVM)】:算法原理及核函数

文章目录 1 SVM算法原理1.1 目标函数确定1.2 约束条件优化问题转换1.3 对偶问题转换1.4 确定超平面1.5 计算举例1.6 SVM原理小节 2 SVM核函数2.1 核函数的作用2.2 核函数分类2.3 高斯核函数2.3 高斯核函数API2.4 超参数 γ \gamma γ 1 SVM算法原理 1.1 目标函数确定 SVM思想…

自动驾驶系列—告别眩光烦恼:智能大灯如何守护夜间行车安全

&#x1f31f;&#x1f31f; 欢迎来到我的技术小筑&#xff0c;一个专为技术探索者打造的交流空间。在这里&#xff0c;我们不仅分享代码的智慧&#xff0c;还探讨技术的深度与广度。无论您是资深开发者还是技术新手&#xff0c;这里都有一片属于您的天空。让我们在知识的海洋中…

无插件H5播放器EasyPlayer.js RTSP播放器chrome/edge等浏览器如何使用独立显卡

随着互联网的快速发展和视频内容的日益丰富&#xff0c;HTML5视频播放器已成为网页视频播放的主流技术。EasyPlayer.js播放器视频播放技术不仅支持多种浏览器和设备&#xff0c;还提供了丰富的功能和更好的用户体验。 那么chrome/edge等浏览器如何使用独立显卡&#xff1f; 在…

@Autowired 和 @Resource思考(注入redisTemplate时发现一些奇怪的现象)

1. 前置知识 Configuration public class RedisConfig {Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {RedisTemplate<String, Object> template new RedisTemplate<>();template.setConnectionFactory(facto…

STM32低功耗设计NFC与无线距离感应智能钥匙扣-分享

目录 目录 前言 一、本设计主要实现哪些很“开门”功能&#xff1f; 二、电路设计原理图 1.电路图采用Altium Designer进行设计&#xff1a; 2.实物展示图片 三、程序源代码设计 四、获取资料内容 前言 智能钥匙扣作为一种小巧而实用的智能设备&#xff0c;凭借其便携性…

微服务day09

DSL查询 快速入门 GET /items/_search {"query": {"match_all": {}} } 叶子查询 GET /items/_search {"query": {"match_all": {}} }GET /items/_search {"query": {"multi_match": {"query": "脱…