Elasticsearch:向量搜索的快速介绍
作者:来自 Elastic Valentin Crettaz
本文是三篇系列文章中的第一篇,将深入探讨向量搜索(也称为语义搜索)的复杂性,以及它在 Elasticsearch 中的实现方式。
本文是三篇系列文章中的第一篇,将深入探讨向量搜索(也称为语义搜索)的复杂性以及它在 Elasticsearch 中的实现方式。
第一部分重点介绍嵌入向量的基础知识以及向量搜索的底层工作原理。
借助第一篇文章中学到的所有知识,第二部分将指导你了解如何在 Elasticsearch 中设置向量搜索。
在第三部分中,我们将利用前两部分中学到的知识,在此基础上深入研究如何在 Elasticsearch 中编写强大的混合搜索查询。
在深入探讨本文的真正内容之前,让我们回顾一下向量的一些历史,它是语义搜索中的关键概念。
向量搜索并不新鲜
可以肯定的是,自 2022 年 11 月 ChatGPT 问世以来,我们每天都会听到或读到有关 “向量搜索” 的信息。向量搜索无处不在,而且非常普遍,我们常常会觉得这是一项刚刚问世的尖端新技术,但事实是,这项技术已经存在了 60 多年!该主题的研究始于 1960 年代中期,第一篇研究论文于 1978 年由信息检索专家 Gerard Salton 及其康奈尔大学的同事发表。Salton 在密集和稀疏向量模型方面的工作构成了现代向量搜索技术的根基。
在过去的 20 年里,许多基于他的研究的向量 DBMS 被创建并推向市场。其中包括由 Apache Lucene 项目提供支持的 Elasticsearch,该项目于 2019 年开始研究向量搜索。
向量现在无处不在,如此普遍,因此在使用它们之前,首先要很好地掌握它们的基本理论和内部工作原理。在深入研究之前,让我们快速回顾一下词汇搜索和向量搜索之间的区别,以便我们更好地理解它们的区别以及它们如何相互补充。
向量搜索与词汇搜索
介绍向量搜索的一个简单方法是将其与你可能习惯的更传统的词汇搜索进行比较。向量搜索(通常也称为语义搜索)和词汇搜索的工作方式截然不同。词汇搜索是我们在 Elasticsearch 中多年来一直使用的搜索类型。简而言之,它不会尝试理解索引和查询内容的真正含义,而是会尽力将用户在查询中输入的单词或其变体(例如词干、同义词等)的文字与之前已使用相似性算法(例如 TF-IDF)索引到数据库中的所有文字进行词汇匹配。

我们可以看到,左上角的三个文档被标记并分析。然后,将生成的术语编入倒排索引,该索引只是将分析的术语映射到包含它们的文档 ID。请注意,所有术语都只出现一次,并且没有一个与任何文档共享。搜索 “nice german teacher” 将匹配所有三个文档,分数各不相同,即使它们都没有真正抓住查询的真正含义。
如下图 2 所示,在处理多义词或同形异义词时,情况会变得更加棘手,即拼写相同但含义不同的单词(right、palm、bat、mean 等)。让我们以 “right” 这个词为例,它可以表示三种不同的含义,看看会发生什么。

搜索 “I’m not right” 会返回一个与第一个返回结果含义完全相反的文档。如果你搜索完全相同的术语,但以不同的顺序排列它们以产生不同的含义,例如 “turn right” 和 “right turn”,则会产生完全相同的结果(即第三个文档 “Take a right turn”)。诚然,我们的查询过于简单,没有使用短语匹配等更高级的查询,但这有助于说明词汇搜索不了解索引和搜索内容背后的真正含义。如果这不清楚,请不要担心,我们将在第三篇文章中重新讨论这个例子,看看向量搜索在这种情况下如何提供帮助。
公平地说,当你可以控制如何索引结构化数据(想想映射、文本分析、提取管道等)以及如何编写查询(想想巧妙编写的 DSL 查询、查询术语分析等)时,你就可以使用词汇搜索引擎创造奇迹,这是毫无疑问的!Elasticsearch 在词汇搜索功能方面的记录令人惊叹。它在过去几年中取得的成就以及它在多大程度上普及和改进了词汇搜索领域,这确实令人惊叹。
但是,当你负责为需要提出自由文本问题的用户提供查询非结构化数据(想想图像、视频、音频、原始文本等)的支持时,词汇搜索就显得力不从心了。此外,有时查询甚至不是文本,它可能是图像,我们很快就会看到。词汇搜索在这种情况下不足的主要原因是非结构化数据既不能像结构化数据那样被索引,也不能被查询。处理非结构化数据时,语义(semantics)就会发挥作用。语义是什么意思?很简单,就是含义!
我们以图像搜索引擎(例如 Google 图片搜索或 Lens)为例。你拖放一张图片,Google 语义搜索引擎就会找到并返回与你查询的图片最相似的图片。在下面的图 3 中,我们可以在左侧看到德国牧羊犬的图片,在右侧看到所有已检索到的类似图片,第一个结果是与提供的图片相同的图片(即最相似的图片)。

来源:Google 图片搜索, https://www.google.com/imghp
尽管这对于我们人类来说听起来简单而合乎逻辑,但对于计算机来说,情况就完全不同了。这就是向量搜索能够实现和帮助实现的。正如世界最近所见证的那样,向量搜索释放的力量是巨大的。现在让我们揭开它的面纱,看看下面隐藏着什么。
嵌入向量
正如我们之前所见,使用词汇搜索引擎,文本等结构化数据可以轻松标记为可在搜索时匹配的术语,而不管这些术语的真实含义如何。然而,非结构化数据可以采用不同的形式,例如大型二进制对象(图像、视频、音频等),并且根本不适合相同的标记(tokenizing)过程。此外,语义搜索的整个目的是以这样的方式索引数据,以便可以根据其所代表的含义进行搜索。我们如何实现这一点?答案就在两个词中:机器学习!或者更准确地说是深度学习!
深度学习(Deep Learning)是机器学习的一个特定领域,它依赖于基于人工神经网络的模型,该模型由多层处理组成,可以逐步提取数据的真正含义。这些神经网络模型的工作方式深受人脑的启发。下面的图 4 显示了神经网络的外观,包括输入层和输出层以及多个隐藏层:

来源:IBM,https://www.ibm.com/topics/neural-networks
神经网络的真正壮举是它们能够将单个非结构化数据转换为一系列浮点值,这些浮点值被称为嵌入向量或简称为嵌入。作为人类,只要我们在二维或三维空间中可视化它们,我们就能很好地理解什么是向量。向量的每个分量表示二维 x-y 平面或三维 x-y-z 空间中的坐标。
但是,神经网络模型工作的嵌入向量可以有几百甚至几千个维度,并且仅表示多维空间中的一个点。每个向量维度代表非结构化数据的一个特征(feature)或特性。让我们用一个深度学习模型来说明这一点,该模型将图像转换为 2048 维的嵌入向量。该模型会将我们在图 3 中使用的德国牧羊犬图片转换为下表所示的嵌入向量。请注意,我们仅显示第一个和最后一个元素,但表中还会有 2,042 个列/维度。
is_red | is_dog | blue_sky | … | no_gras | german_shepherd | is_tree | |
---|---|---|---|---|---|---|---|
German shepherd embeddings | 0.0121 | 0.9572 | 0.8735 | … | 0.1198 | 0.9712 | 0.0512 |
每一列都是模型的一个维度,代表底层神经网络试图建模的特征或特性。提供给模型的每个输入都将根据该输入与 2048 个维度的相似程度进行表征。因此,嵌入向量中每个元素的值表示该输入与特定维度的相似度。在这个例子中,我们可以看到模型检测到狗和德国牧羊犬之间有很高的相似性,并且还检测到了一些蓝天。
与词汇搜索(其中术语可以匹配也可以不匹配)相比,使用向量搜索,我们可以更好地了解一段非结构化数据与模型支持的每个维度的相似程度。因此,嵌入向量可以作为非结构化数据的极好的语义表示。
秘诀
现在我们知道了深度学习神经网络如何将非结构化数据切分为嵌入向量,从而捕捉大量维度上数据的相似性,我们需要了解这些向量的匹配是如何进行的。答案其实很简单。彼此接近的嵌入向量表示语义上相似的数据片段。因此,当我们查询向量数据库时,搜索输入(图像、文本等)首先使用与索引所有非结构化数据相同的模型转换为嵌入向量,最终目标是找到与该查询向量最近的相邻向量。因此,我们需要做的就是弄清楚如何测量查询向量与数据库中索引的所有现有向量之间的 “距离” 或 “相似性”,仅此而已。
距离和相似性
幸运的是,借助向量算法,测量两个向量之间的距离是一个很容易解决的问题。那么,让我们来看看现代向量搜索数据库(例如 Elasticsearch)支持的最流行的距离和相似度函数。警告,前方有数学知识!
L1 距离
两个向量 x 和 y 的 L1 距离(也称为曼哈顿距离)是通过将它们所有元素的成对绝对差相加来测量的。显然,距离 d 越小,两个向量越接近。公式非常简单,如下所示:
从视觉上看,L1 距离可以用下面的图 5 来表示:

设两个向量 x 和 y,例如 x = (1, 2) 和 y = (4, 3),则两个向量的 L1 距离为 | 1 - 4 | + | 2 - 3 | = 4。
L2 距离
L2 距离,也称为欧几里得距离,两个向量 x 和 y 的测量方法是先将它们所有元素的两两差值的平方相加,然后对结果取平方根。它基本上是两点之间的最短路径(也称为斜边)。与 L1 类似,距离 d 越小,两个向量越接近:
L2 距离如下图6所示:

让我们重复使用与 L1 距离相同的两个样本向量 x 和 y,现在我们可以计算 L2 距离为 。取 10 的平方根将得出 3.16。
Linf 距离
两个向量 x 和 y 的 Linf(代表 L 无穷大)距离,也称为切比雪夫距离或棋盘距离,简单定义为任意两个元素之间的最长距离或沿其中一个轴/维度测量的最长距离。公式非常简单,如下所示:
Linf 距离的表示如下图 7 所示:

同样,取相同的两个样本向量 x 和 y,我们可以计算 L 无穷距离为 max ( | 1 - 4 | , | 2 - 3 | ) = max (3, 1) = 3。
余弦相似度
与 L1、L2 和 Linf 不同,余弦相似度不测量两个向量 x 和 y 之间的距离,而是测量它们的相对角度,即它们是否都指向大致相同的方向。相似度 s 越高,两个向量越 “接近”。公式同样非常简单,如下所示:
两个向量之间余弦相似度的表示方法如下图 8 所示:

此外,由于余弦值始终在 [-1, 1] 区间内,-1 表示相反的相似性(即两个向量之间呈 180° 角),0 表示不相关的相似性(即呈 90° 角),1 表示相同(即呈 0° 角),如下图 9 所示:

再次,让我们重复使用相同的样本向量 x 和 y,并使用上述公式计算余弦相似度。首先,我们可以计算两个向量的点积,即 (1x4)+(2x3) = 10。然后,我们将两个向量的长度(也称为幅度)相乘:。最后,我们将点积除以乘积的长度 10 / 11.18034 = 0.894427(即 26° 角),该值非常接近 1,因此两个向量可以被认为非常相似。
点积相似度
余弦相似度的一个缺点是它只考虑两个向量之间的角度,而不考虑它们的大小(即长度),这意味着如果两个向量大致指向同一方向,但其中一个比另一个长得多,则两者仍将被视为相似。点积相似度(也称为标量或内积)通过同时考虑向量的角度和大小来改善这一点,从而提供更准确的相似度度量。
两个等效公式用于计算点积相似度。第一个与我们之前在余弦相似度的分子中看到的相同:
第二个公式只是将两个向量的长度乘以它们之间角度的余弦:
点积相似度如下图 10 所示:

最后一次,我们取样本 x 和 y 向量,并使用第一个公式计算它们的点积相似度,就像我们之前对余弦相似度所做的那样,即 (1x4)+(2x3) = 10。
使用第二个公式,我们将两个向量的长度相乘: 并将其乘以两个向量之间 26° 角的余弦,得到 11.18034 x cos(26°) = 10。
值得注意的是,如果先对所有向量进行归一化(即,它们的长度为 1),那么点积相似度将与余弦相似度完全相同(因为 |x| |y| = 1),即两个向量之间角度的余弦。正如我们稍后会看到的,归一化向量是一种很好的做法,它可以让向量的大小变得无关紧要,从而使相似度只关注角度。它还可以加快索引和查询时的距离计算,这在处理数十亿个向量时可能是一个大问题。
快速回顾
哇,到目前为止我们已经了解了很多信息,所以让我们暂停一下,快速回顾一下我们所处的位置。我们已经了解到……
- …语义搜索基于深度学习神经网络模型,该模型擅长将非结构化数据转换为多维嵌入向量。
- …模型的每个维度都代表非结构化数据的特征或特性。
- …嵌入向量是一系列相似度值(每个维度一个),表示给定的非结构化数据与每个维度的相似程度。
- …两个向量越 “近”(即最近邻居),它们所代表的语义相似概念就越多。
- …距离函数(L1、L2、Linf)使我们能够测量两个向量的接近程度。
- …相似度函数(余弦和点积)使我们能够测量两个向量朝同一方向的距离。
现在,我们需要深入研究的最后一部分是向量搜索引擎本身。当查询进入时,查询首先被向量化,然后向量搜索引擎找到与该查询向量最近的相邻向量。测量查询向量与数据库中所有向量之间的距离或相似度的蛮力(brute-force)方法可以适用于小型数据集,但随着向量数量的增加,它很快就会失效。换句话说,我们如何索引数百万、数十亿甚至数万亿个向量,并在合理的时间内找到查询向量的最近邻居?这就是我们需要变得聪明并找出索引向量的最佳方法的地方,这样我们就可以尽快锁定最近的邻居,而不会过多地降低精度。
更多有关距离和相似性的知识,请详细阅读 “Elasticsearch:向量相似度技术和评分”
向量搜索算法和技术
多年来,许多不同的研究团队投入了大量精力来开发非常巧妙的向量搜索算法。在这里,我们将简要介绍主要的算法。根据用例,有些算法比其他算法更适合。
线性搜索
我们之前简要介绍了线性搜索或平面索引,当时我们提到了将查询向量与数据库中存在的所有向量进行比较的蛮力(brute-force)方法。虽然它可能在小型数据集上效果很好,但随着向量数量和维度的增加(O(n)复杂度),性能会迅速下降。
幸运的是,有一种更有效的方法,称为近似最近邻 (approximate nearest neighbor - ANN),其中嵌入向量之间的距离是预先计算的,并且相似的向量以保持它们靠近的方式存储和组织,例如使用集群、树、哈希或图形。这种方法被称为 “近似”,因为它们通常不能保证 100% 的准确性。最终目标是尽可能快速地缩小搜索范围,以便只关注最有可能包含相似向量的区域,或者降低向量的维数。
K 维树 - K - Dimensional trees
K 维树或 KD 树是二叉搜索树的泛化,它将点存储在 k 维空间中,并通过将搜索空间连续二等分为较小的左树和右树来工作,其中向量被索引。在搜索时,算法只需访问查询向量周围的几个树枝(图 11 中的红点)即可找到最近的邻居(图 11 中的绿点)。如果请求的邻居超过 k 个,则黄色区域会扩展,直到算法找到更多邻居。

Source: Kd-tree and Nearest neighbor (NN) search (2D case) | Alexey Abramov | Salzi | Blog
KD 树算法的最大优点是它允许我们快速地只关注一些局部的树分支,从而排除大部分向量的考虑。然而,这种算法的效率会随着维数的增加而降低,因为与低维空间相比,需要访问的分支要多得多。
倒排索引
倒排索引 (inverted file index - IVF) 方法也是一种空间分区(space-partitioning)算法,它将彼此接近的向量分配到它们的共享质心。在 2D 空间中,最好使用 Voronoi 图来可视化,如图 12 所示:

Source: AUTOINDEX Explained | Cloud | Zilliz Cloud Developer Hub
我们可以看到,上面的二维空间被划分为 20 个簇,每个簇的质心都用黑点表示。空间中的所有嵌入向量都被分配给质心最接近的簇。在搜索时,算法首先通过找到最接近查询向量的质心来确定要关注的簇,然后它可以简单地将焦点集中在该区域,如果需要,还可以将焦点集中在周围的区域,以找到最近的邻居。
在高维空间中使用时,此算法会遇到与 KD 树相同的问题。这称为维数灾难,当空间体积增加太多以至于所有数据看起来都很稀疏,并且获得更准确结果所需的数据量呈指数增长时,就会发生这种情况。当数据稀疏时,这些空间分区算法将数据组织成簇变得更加困难。幸运的是,还有其他算法和技术可以缓解这个问题,如下所述。
量化 - Quantization
量化是一种基于压缩的方法,它允许我们通过降低嵌入向量的精度来减少数据库的总大小。这可以通过使用标量量化 (scalar quantization - SQ) 来实现,即将浮点向量值转换为整数值。这不仅可以将数据库的大小减少 8 倍,还可以减少内存消耗并加快搜索时向量之间的距离计算。
另一种技术称为乘积量化 (product quantization - PQ),它首先将空间划分为低维子空间,然后使用聚类算法(类似于 k 均值 - k-means)将彼此接近的向量分组到每个子空间中。
请注意,量化不同于降维,降维是减少维数(dimensionality reduction),即向量只是变短了。
分层可导航小世界 (Hierarchical Navigable Small Worlds - HNSW)
如果仅从名称来看它看起来很复杂,别担心,其实它并不复杂!简而言之,分层可导航小世界是一种基于多层图形的算法,非常流行且高效。它被许多不同的向量数据库使用,包括 Apache Lucene。下图 13 中可以看到 HNSW 的概念表示。

Source: Similarity Search, Part 4: Hierarchical Navigable Small World (HNSW) | Towards Data Science
在顶层,我们可以看到一个由极少数向量组成的图,这些向量之间的链接最长,即相似度最低的连接向量图。我们越深入底层,找到的向量就越多,图就越密集,向量之间的距离也越来越近。在最低层,我们可以找到所有向量,其中最相似的向量彼此距离最近。
在搜索时,算法从顶层的任意入口点开始,找到最接近查询向量的向量(以灰色点表示)。然后,它移动到下一层并重复相同的过程,从上一层留下的相同向量开始,依此类推,一层接一层,直到到达最低层并找到查询向量的最近邻居。
局部敏感哈希 (Locality-sensitive hashing - LSH)
与迄今为止介绍的所有其他方法一样,局部敏感哈希力求大幅减少搜索空间,以提高检索速度。通过这种技术,嵌入向量被转换为哈希值,所有这些都通过保留相似性信息来实现,这样搜索空间最终就变成了一个可以查找的简单哈希表,而不是需要遍历的图或树。基于哈希的方法的主要优点是,包含任意(大)维数的向量可以映射到固定大小的哈希,这极大地加快了检索时间,而不会牺牲太多的精度。
通常,对数据进行哈希处理的方法有很多种,特别是对嵌入向量进行哈希处理的方法,但本文不会深入讨论每种方法的细节。传统的哈希方法通常会为看起来非常相似的数据产生非常不同的哈希。由于嵌入向量由浮点值组成,我们取两个在向量算法中被认为非常接近的浮点值样本(例如 0.73 和 0.74),并将它们通过几个常见的哈希函数运行。从下面的结果可以看出,常见的哈希函数显然无法保留输入之间的相似性。
Hashing function | 0.73 | 0.74 |
---|---|---|
MD5 | 1342129d04cd2924dd06cead4cf0a3ca | 0aec1b15371bd979cfa66b0a50ebecc5 |
SHA1 | 49d2c3e0e44bff838e1db571a121be5ea874e8d9 | a534e76482ade9d9fe4bff3035a7f31f2f363d77 |
SHA256 | 99d03fc3771fe6848d675339fc49eeb1cb8d99a12e6358173336b99a2ec530ea | 5ecbc825ba5c16856edfdaf0abc5c6c41d0d8a9c508e34188239521dc7645663 |
虽然传统的哈希方法试图最小化相似数据片段之间的哈希冲突,但局部敏感哈希的主要目标恰恰相反,即最大化哈希冲突,以便相似的数据以高概率落入同一个存储桶中。通过这样做,在多维空间中彼此接近的嵌入向量将被哈希为落入同一个存储桶中的固定大小值。由于 LSH 允许这些哈希向量保持其接近度,因此该技术对于数据聚类和最近邻搜索非常有用。
所有繁重的工作都发生在需要计算哈希值的索引时,而在搜索时,我们只需要对查询向量进行哈希处理,以查找包含最近嵌入向量的存储桶。一旦找到候选存储桶,通常会进行第二轮以确定与查询向量最近的相邻向量。
让我们总结一下
为了介绍向量搜索,我们必须在本文中介绍相当多的内容。在比较了词汇搜索和向量搜索之间的差异之后,我们了解了深度学习神经网络模型如何设法捕获非结构化数据的语义并将其含义转码为高维嵌入向量,即表示数据沿模型每个维度的相似性的浮点数序列。还值得注意的是,向量搜索和词汇搜索不是竞争关系,而是互补的信息检索技术(我们将在本系列的第三部分深入研究混合搜索时看到)。
之后,我们介绍了向量搜索的一个基本构建块,即距离(和相似度)函数,它使我们能够测量两个向量的接近度并评估它们所代表的概念的相似性。
最后,我们回顾了最流行的向量搜索算法和技术的不同类型,这些算法和技术可以基于树、图、集群或哈希,其目标是快速缩小多维空间的特定区域,以便找到最近的邻居,而不必像线性蛮力搜索那样访问整个空间。
请继续关注本系列的其他部分:
- 第 2 部分:如何在 Elasticsearch 中设置向量搜索
- 第 3 部分:使用 Elasticsearch 进行混合搜索
使用此自定进度的 Search AI 动手学习亲自尝试向量搜索。您现在可以开始免费云试用或在本地机器上试用 Elastic。
原文:A quick introduction to vector search - Elasticsearch Labs
相关文章:

Elasticsearch:向量搜索的快速介绍
作者:来自 Elastic Valentin Crettaz 本文是三篇系列文章中的第一篇,将深入探讨向量搜索(也称为语义搜索)的复杂性,以及它在 Elasticsearch 中的实现方式。 本文是三篇系列文章中的第一篇,将深入探讨向量搜…...

Docker在安装时遇到的问题(第一部分)
一、在用docker-config-manager安装yum源时出现错误 [rootlocalhost ~]# yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo 已加载插件:fastestmirror, langpacks adding repo from: https://download.docker.com/linux/ce…...

使用 OpenGL ES 在 iOS 上渲染一个四边形:从基础到实现
使用 OpenGL ES 在 iOS 上渲染一个四边形:从基础到实现 在 iOS 开发中,OpenGL ES 是一个强大的工具,用于实现高性能的 2D 和 3D 图形渲染。本文将详细分析一段完整的代码,展示如何使用 OpenGL ES 在 iOS 上渲染一个简单的四边形。我们将从代码的结构、关键模块、着色器的实…...
Spring Boot 2 快速教程:WebFlux处理流程(五)
WebFlux请求处理流程 下面是spring mvc的请求处理流程 具体步骤: 第一步:发起请求到前端控制器(DispatcherServlet) 第二步:前端控制器请求HandlerMapping查找 Handler (可以根据xml配置、注解进行查找) 匹配条件包括…...

Vue 鼠标事件合集,关于鼠标右键的处理方法(改写鼠标右键方法、自定义鼠标右键)
鼠标事件使用 mousedown"canvasDown($event)"按下事件合集 click 点击某个对象时触发 mousedown 鼠标按钮被按下时触发 mouseup 鼠标按钮被松开时触发 mouseleave 当鼠标指针移出元素时触发 dblclick 双击时触发 mousemove 鼠标移动时触发,…...

两种交换排序算法--冒泡,快速
目录 1.冒泡排序原理 2.快速排序原理 3.冒泡代码实现 4.快速排序代码实现 1.冒泡排序原理 冒泡排序(Bubble Sort)是一种简单的排序算法,基本思想是通过反复交换相邻的元素,直到整个序列有序。它的名字来源于较大的元素像气泡…...

语音交友app系统源码功能及技术研发流程剖析
语音交友App的核心功能包括语音聊天、语音房间、社交互动等,开发流程涵盖需求分析、技术选型、前后端开发、实时通信集成、测试优化、部署上线及运营维护。 一、语音交友App的大概功能 1. 语音聊天 一对一聊天:用户可与好友进行私密语音通话。 群组语音…...

零基础Vue入门7——状态管理Pinia
本节重点: pinia是什么pinia怎么用 pinia是什么 vue中组件间的数据传递: app.config.globalProperties:能够被应用内所有组件实例访问到的全局属性的对象props:父传子用provide:父传后代用 想象下有咩有哪些数据存储…...

Bash (Bourne-Again Shell)、Zsh (Z Shell)
文章目录 1. 历史背景2. 主要区别3. 功能对比自动补全插件和主题路径扩展提示符定制 4. 性能5. 使用场景6. 如何切换 Shell7. 总结 以下是 Bash 和 Zsh 之间的主要区别,列成表格方便对比: 特性BashZsh默认Shell大多数Linux发行版默认ShellmacOS默认She…...

Android studio 创建aar包给Unity使用
1、aar 是什么? 和 Jar有什么区别 aar 和 jar包 都是压缩包,可以使用压缩软件打开 jar包 用于封装 Java 类及其相关资源 aar 文件是专门为 Android 平台设计的 ,可以包含Android的专有内容,比如AndroidManifest.xml 文件 &#…...

DeepSeek R1 简单指南:架构、训练、本地部署和硬件要求
DeepSeek 的 LLM 推理新方法 DeepSeek 推出了一种创新方法,通过强化学习 (RL) 来提高大型语言模型 (LLM) 的推理能力,其最新论文 DeepSeek-R1 对此进行了详细介绍。这项研究代表了我们如何通过纯强化学习来增强 LLM 解决复杂问题的能力,而无…...

图论常见算法
图论常见算法 算法prim算法Dijkstra算法 用途最小生成树(MST):最短路径:拓扑排序:关键路径: 算法用途适用条件时间复杂度Kruskal最小生成树无向图(稀疏图)O(E log E)Prim最小生成树无…...

MySQL三大日志详解
在MySQL数据库的运行过程中,三大关键日志——binlog、redo log和undo log,起着至关重要的作用。理解这三大日志,对于深入掌握MySQL的工作原理、数据恢复以及主从复制等操作有着极大的帮助。本文将详细剖析这三大日志的作用和工作机制。 Binl…...

【SQL 中的分组查询与联合查询详解】
文章目录 SQL 中的分组查询与联合查询详解 1. GROUP BY分组查询 1.1 语句格式1.2 示例说明 1.2.1 分别查询哥哥组和弟弟组的英语成绩总和1.2.2 查询哥哥组的所有成绩总和 2. 联合查询 2.1 内连接 2.1.1 语法格式2.1.2 执行过程 2.2 外连接 2.2.1 左外连接2.2.2 右外连接 2.3 …...

【实战篇】用 Cursor 独立开发并上线电商类 Android APP 全攻略
一、为啥要用 Cursor 开发电商类 Android APP 家人们,如今电商类 APP 随处可见,不管是买衣服、食品,还是电子产品,都能通过这些 APP 轻松搞定。要是能自己开发一款电商类 Android APP,那可太酷啦!但开发 APP 可不是一件容易的事,涉及到很多技术,像写代码、设计界面、处…...

quartus24.1版本子模块因时钟问题无法综合通过,FPGA过OOC问题复盘
因为只负责一个子模块,所以需要单独对该子模块进行综合和过OOC,这时候已经有一些加虚拟pin文件,敲命令让子模块能过OOC的方法。但这个方法的前提是先过综合,然后再敲命令让虚拟管脚命令成功,最终可以过OOC。 今天负责…...

零基础Vue入门6——Vue router
本节重点: 路由定义路由跳转 前面几节学习的都是单页面的功能(都在专栏里面https://blog.csdn.net/zhanggongzichu/category_12883540.html),涉及到项目研发都是有很多页面的,这里就需要用到路由(vue route…...

使用 Let‘s Encrypt 和 OpenResty 实现域名转发与 SSL 配置
在搭建网站或服务时,确保域名的安全性和正确的流量转发是非常重要的。本文将介绍如何使用 Let’s Encrypt 获取免费的 SSL 证书,并将其配置到 OpenResty 中,同时实现特定的域名转发规则。这不仅可以提升网站的安全性,还能优化流量…...

Lambda 表达式
一、Lambda 表达式简介 Lambda 表达式是一种简洁的函数式编程方式,用于实现只有一个方法的接口(例如函数式接口)。 基本语法 (parameters) -> expression (parameters) -> { statements; } 参数:可以有零个或多个参数。…...

TCN时间卷积神经网络多变量多步光伏功率预测(Matlab)
代码下载:TCN时间卷积神经网络多变量多步光伏功率预测(Matlab) TCN时间卷积神经网络多变量多步光伏功率预测 一、引言 1.1、研究背景和意义 随着全球能源危机的加剧和环保意识的提升,可再生能源,尤其是太阳能&…...

【Elasticsearch】 Composite Aggregation 详解
1.什么是 Composite Aggregation? Composite Aggregation 是 Elasticsearch 中的一种特殊聚合方式,适用于需要分页展示的聚合结果。它与传统的聚合方式不同,采用了基于游标的分页模型。这种聚合方式可以高效地处理多级聚合中的所有桶&#x…...

如何通过 Logstash 将数据采集到 Elasticsearch
作者:来自 Elastic Andre Luiz 将 Logstash 与 Elasticsearch 集成以实现高效的数据提取、索引和搜索的分步指南。 什么是 Logstash? Logstash 是一种广泛使用的 Elastic Stack 工具,用于实时处理大量日志数据。它充当高效的数据管道&#x…...

mysql的cpu使用率100%问题排查
背景 线上mysql服务器经常性出现cpu使用率100%的告警, 因此整理一下排查该问题的常规流程。 1. 确认CPU占用来源 检查系统进程 使用 top 或 htop 命令,确认是否是 mysqld 进程导致CPU满载:top -c -p $(pgrep mysqld)2. 实时分析MySQL活动 …...

centos虚拟机迁移没有ip的问题
故事背景,我们的centos虚拟机本来是好好的,但是拷贝到其他电脑上就不能分配ip,我个人觉得这个vmware他们软件应该搞定这个啊,因为这个问题是每次都会出现的。 网络选桥接 网络启动失败 service network restart Restarting netw…...

接入 deepseek 实现AI智能问诊
1. 准备工作 注册 DeepSeek 账号 前往 DeepSeek 官网 注册账号并获取 API Key。 创建 UniApp 项目 使用 HBuilderX 创建一个新的 UniApp 项目(选择 Vue3 或 Vue2 模板)。 安装依赖 如果需要在 UniApp 中使用 HTTP 请求,推荐使用 uni.requ…...

用AVFrame + AVPacket 完成accede编码和直接用ffmpeg命令行实现acc编码的对比
在使用 FFmpeg 进行 AAC 音频编码时,可以选择两种方式:通过编程接口(如 AVFrame 和 AVPacket)实现 AAC 编码,或者直接使用 FFmpeg 命令行工具。这两种方式各有特点,适用于不同的场景。以下是对两种方法的详细分析,包括它们的区别、优缺点以及适用场景。 一、通过 AVFram…...

计算机网络笔记再战——理解几个经典的协议6——TCP与UDP
目录 先说端口号 TCP 使用序号保证顺序性和应答来保证有效性 超时重传机制 TCP窗口机制 UDP 路由协议 协议分类:IGP和EGP 几个经典的路由算法 RIP OSPF 链路状态数据库(LSDB) LSA(Link State Advertisement࿰…...

【AI】在Ubuntu中使用docker对DeepSeek的部署与使用
这篇文章前言是我基于部署好的deepseek-r1:8b模型跑出来的 关于部署DeepSeek的前言与介绍 在当今快速发展的技术环境中,有效地利用机器学习工具来解决问题变得越来越重要。今天,我将引入一个名为DeepSeek 的工具,它作为一种强大的搜索引擎&a…...

openssl使用
openssl使用 提取密钥对 数字证书pfx包含公钥和私钥,而cer证书只包含公钥。提取需输入证书保护密码 openssl pkcs12 -in xxx.pfx -nocerts -nodes -out pare.key提取私钥 openssl rsa -in pare.key -out pri.key提取公钥 openssl rsa -in pare.key -pubout -ou…...

《语义捕捉全解析:从“我爱自然语言处理”到嵌入向量的全过程》
首先讲在前面,介绍一些背景 RAG(Retrieval-Augmented Generation,检索增强生成) 是一种结合了信息检索与语言生成模型的技术,通过从外部知识库中检索相关信息,并将其作为提示输入给大型语言模型ÿ…...