【数据结构--查找】

news2024/9/22 17:22:41

目录

  • 一、查找(Searching)的概念
    • 1.1、基本概念
    • 1.2、算法的评价指标
  • 二、顺序查找
    • 2.1、算法思想
    • 2.2、算法实现
      • 2.2.1、常规顺序查找
      • 2.2.2、带哨兵的顺序查找
    • 2.3、效率分析
    • 2.4、优化
      • 2.4.1、针对有序表
      • 2.4.2、被查效率不相等
  • 三、折半查找
    • 3.1、算法思想
    • 3.2、算法实现
    • 3.3、效率分析
      • 3.3.1、判定树的构造
    • 3.4、拓展
  • 四、分块查找
    • 4.1、算法思想
    • 4.2、效率分析
      • 4.2.1、顺序查找查索引表
      • 4.2.2、折半查找查索引表
    • 4.3、拓展
  • 五、散列查找
    • 5.1、散列表
    • 5.2、查找
    • 5.3、常见的散列函数
      • 5.3.1、除留余数法
      • 5.3.2、直接定址法
      • 5.3.3、数学分析法
      • 5.3.4、平方取中法
      • 5.3.5、随机数法
    • 5.4、处理冲突的方法
      • 5.4.1、拉链法
      • 5.4.2、开放定址法
        • 1.线性探测法
          • (1)查找
          • (2)删除
          • (3)查找效率分析
          • (4)缺点
        • 2.平方探测法
          • (1)查找
        • 3.伪随机序列法
        • 4.再散列法
      • 5.4.3、公共溢出区法

一、查找(Searching)的概念

1.1、基本概念

  • 查找:就是根据某个给定的值,在查找表中确定一个其关键字等于给定值的数据元素(或记录)。

  • 查找表(Search Table): 是由同一类型数据元素(或记录)构成的集合,有静态查找表动态查找表

  • 静态查找表(Static Search Table): 只做查找操作的查找表,主要操作为:

  • (1)查询某个“特定的”数据元素是否在查找表中;

  • (2)检索某个“特定的”数据元素和各种属性。

  • 动态查找表(Dynamic Search Table): 在查找过程中同时插入查找表中不存在的数据元素,或者从查找表中删除已经存在的某个数据元素,

  • (1)查找时插入不存在的数据元素;

  • (2)查找时删除已存在的数据元素。

  • 关键字(Key): 数据元素中唯一标识该元素的某个数据项的值,使用基于关键字的查找,查找结果应该是唯一的。例如,在一个由学生元素构成的数据元素集合中,学生元素中“学号”这一数据项的值唯一地标识一位学生。

1.2、算法的评价指标

  • 平均查找长度(Average Search Length): 在查找过程中,一次查找的长度是指需要比较的关键字次数,而平均查找长度,则是所有查找过程中进行关键字的比较次数的平均值,其数学定义为:
    A S L = ∑ i = 1 n P i C i ASL=\sum_{i=1}^{n} P_{i}C_{i} ASL=i=1nPiCi
    式中,n是查找表的长度, P i P_{i} Pi是查找第i个数据元素的概率,一般认为每个数据元素的查找概率相等, P i = 1 / n P_{i}=1/n Pi=1/n C i C_{i} Ci是找到第i个数据元素所需要进行的比较次数。平均查找长度是衡量查找算法效率的最主要的指标。
    既然是进行查找,那必然就有查找成功和查找失败两种结果,对于两种结果进行分析均是用平均查找长度,但是注意计算比较次数的问题,由例子来分辨:
    ①查找成功的平均查找长度:
    在这里插入图片描述
    解释:若给定值就是根结点的关键字,那么查找1次就成功;若是第二层的关键字,就需要再查完第一层(已经比较了1次)之后,在第二层进行第2次比较,共2次;依次类推,若在第三层,则需要1+1+1=3次;上图(左树)一共有四层,则第四层的查找次数就为4次,默认每个数据元素的查找概率相同的情况下,根据每层的数据元素个数,可以列出 A S L = ( 1 ∗ 1 + 2 ∗ 2 + 3 ∗ 4 + 4 ∗ 1 ) / 8 = 2.625 ASL=(1*1+2*2+3*4+4*1)/8=2.625 ASL=(11+22+34+41)/8=2.625
    ②查找失败的平均查找长度:
    在这里插入图片描述
    解释:何为查找失败,也就是所查找的范围内没有目标值,而树的查找过程是从根结点到叶结点,一直查,直到比较完所有的结点,没有找到,就失败。以上图(左树)为例,查找一个目标值一直查到21了都没有符合的,那么所查值既然不等于21,那就是大于或者小于,就给有两种情况,同理,每一个叶结点都满足这种推理,所以可以列出 A S L = ( 3 ∗ 7 + 4 ∗ 2 ) / 9 = 3.22 ASL=(3*7+4*2)/9=3.22 ASL=(37+42)/9=3.22,因为有9种失败的情况,所以除以9。

二、顺序查找

2.1、算法思想

顺序查找(Sequential Search)又叫做线性查找,是基本的查找技术,作为一种最直观的查找方法,其基本思想是从线性表的一端开始,逐个检查关键字是否满足给定的条件。若查找到的某个元素的关键字满足给定条件。则查找成功,返回该元素在线性表中的位置,若已经查找到线性表另一端,但还没查找到符合条件的元素,则返回查找失败的信息。

2.2、算法实现

2.2.1、常规顺序查找

//查找表的数据结构(顺序表)
typedef struct{
    ElemType *elem;//动态数组的基址
    int length;//表的长度
}SSTable;

//顺序查找
int Seq_Search(SSTable ST, ElemType key){
    int i;
    for(i=0;i<ST.length && ST.elem[i] != key; ++i);
    //若i等于表长,说明未在表中找到目标值,即查找失败,返回-1,若不等就跳出了循环,说明找到了目标值,返回i
    return i = ST.length ? -1 : i;
}

在这里插入图片描述

2.2.2、带哨兵的顺序查找

从后往前进行查找,在下标为0处添加哨兵,减少了对越界的判断

typedef struct{
    ElemType *elem;
    int length;
}SSTable;

//带哨兵的顺序查找
int Seq_Search(SSTable ST, int key){
    int i;
    ST.elem[0] = key;
    for(int i = ST.length; ST.elem[i] != key; --i);
    return i;
}

在这里插入图片描述

2.3、效率分析

每个元素查找的概率都为 1 / n 1/n 1/n,第一个元素查找成功需要进行的查找为1次,第二个为2次,…以此类推,第n个就为n次, A S L 成功 = ( 1 + 2 + 3 + 4 + . . . + n ) / n = ( n + 1 ) / 2 ASL_{成功}=(1+2+3+4+...+n)/n=(n+1)/2 ASL成功=(1+2+3+4+...+n)/n=(n+1)/2 A S L 失败 = n + 1 ASL_{失败}=n+1 ASL失败=n+1

2.4、优化

2.4.1、针对有序表

查找成功的ASL计算无变化,若有序的话能够尽可能在前期查找中就判断出是否存在目标值,就不需要一定要判断到最后一个元素。
在这里插入图片描述
在这里插入图片描述

2.4.2、被查效率不相等

在这里插入图片描述

三、折半查找

3.1、算法思想

折半查找(Binary Search)技术,又称为二分查找。它的前提是线性表中的记录必须是关键码有序(通常从小到大有序),线性表必须采用顺序存储。折半查找的基本思想:在有序表中,取中间记录作为比较对象,若给定值与中间记录的关健值相等,则查找成功;若给定值小于中间记录的关健值,则在中间记录的左半区继续查找;若给定值大于中间记录的关键值,则在中间记录的右半区继续查找。不断重复上述过程,直到查找成功,或所有查找区域无记录,查找失败为止。

3.2、算法实现

//查找表的数据结构(顺序表)
typedef struct{
    ElemType *elem;//动态数组的基址
    int length;//表的长度
}SSTable;
int Binary_Search(SSTable ST, int key ){
    int left = 0;
    int right = ST.length - 1;
    int mid = 0;
    while(left <= right){
        mid = left + (right - left)/2;
        if(key == ST.elem[mid])
            return mid;
        else if(key < ST.elem[mid])
            right = mid - 1;
        else 
            left = mid + 1;
    }
    return -1;//查找失败,返回-1
}

3.3、效率分析

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.3.1、判定树的构造

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.4、拓展

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

四、分块查找

4.1、算法思想

分块查找(Blocking Search)又称索引顺序查找,它吸取了顺序查找和折半查找的优点,既有动态结构,又适于快速查找。

分块查找相比于前两种查找方法,需要额外建立一个“索引表”。将查找表分为若干子表(或称块),对每个子表建立一个索引项,其中包含两项内容:①关键字项:值为该子表内最大的关键字,②指针项:指示子表的第一个记录在表中的位置。每个索引项构成一个索引表,索引表按关键字有序排列。
注意:块内的的元素可以无序,但块与块之间是有序的,即第一块中最大关键字小于第二块中最大关键字,以此类推。

分块查找过程分为两步:

  1. 先确定记录所在的块;
  2. 在块中进行顺序查找来查所需记录。

找所在块时,因为块间是有序的,所以可采用顺序查找也可采用折半查找。

4.2、效率分析

分块查找的平均查找长度为:
A S L 成功 = L b + L w ASL_{成功}=L_{b}+L_{w} ASL成功=Lb+Lw
其中, L b L_{b} Lb为查找索引表所在块的平均查找长度, L w L_{w} Lw为在块内查找元素的平均查找长度。

我们将长度为n的表均匀分为b块,每块含有s个记录,即 b = [ n / s ] b=[n/s] b=[n/s];假定表中每个记录的查找概率相等,即每块的查找概率为 1 / b 1/b 1/b,块中每个记录的查找概率为 1 / s 1/s 1/s

4.2.1、顺序查找查索引表

A S L b s = L b + L w = 1 b ∑ i = 1 b i + 1 s ∑ j = 1 s j = b + 1 2 + s + 1 2 ASL_{bs}=L_{b}+L_{w}=\frac{1}{b}\sum_{i=1}^{b}i+\frac{1}{s}\sum_{j=1}^{s}j=\frac{b+1}{2}+\frac{s+1}{2} ASLbs=Lb+Lw=b1i=1bi+s1j=1sj=2b+1+2s+1
从式中可以看出,顺序查找所确定块,与s,n均有关系,因此得,当s取得 n \sqrt{n} n 时, A S L b s ASL_{bs} ASLbs的值最小,为 n + 1 \sqrt{n}+1 n +1

4.2.2、折半查找查索引表

A S L b s ≈ l o g 2 ( n s + 1 ) + s + 1 2 ASL_{bs}\approx log_{2}(\frac{n}{s}+1)+\frac{s+1}{2} ASLbslog2(sn+1)+2s+1

时间复杂度:
分块查找的时间复杂度取决于块的数量以及块内元素的数量,在最坏的情况下(即目标位于最后一个块的最后一位),不仅需要查找完所有的块,也需要在最后一个块中遍历完所有的元素,因此,时间复杂度为 O ( m + n ) O(m+n) O(m+n),其中m是块的数量,n是所有块中元素的数量。
空间复杂度:
分块查找的空间复杂度取决于用于存储块的辅助空间。由于每个块中的元素是无序的,所以无法通过块中的元素直接定位目标元素,需要额外的空间来存储块的索引。因此空间复杂度为 O ( m ) O(m) O(m),其中m是块的数量。

4.3、拓展

在这里插入图片描述

五、散列查找

5.1、散列表

散列表是根据关键字而直接进行访问的数据结构,也就是说,散列表建立了关键字和存储地址之间的一种直接映射关系,我们只需要通过某个函数f,使得:
存储位置 = f (关键字) 存储位置=f(关键字) 存储位置=f(关键字)那样我们就可以通过查找关键字,不需要比较就可获得需要的记录的存储位置。
f为散列函数,又称为哈希(hash)函数。按照这个思想,采用散列技术将记录存储在一块连续的存储空间内,这块连续的存储空间称为散列表或哈希表(hash table),那么关键字对应的记录存储位置被称为是散列地址。

散列函数可能会把两个或者两个以上的不同关键字映射到同一地址,称这样的情况为冲突,这些发生碰撞的不同关键字称为同义词。一方面,设计得好的散列函数应该尽量减少这方面的冲突;另一方面,由于这种冲突时不可避免的,所以还要设计处理冲突的方法。

理想情况下,散列查找的时间复杂度为 O ( 1 ) O(1) O(1),即与表中元素的个数无关。

5.2、查找

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5.3、常见的散列函数

在构造散列函数时,必须注意以下几点:

  • 散列函数的定义域必须包含全部需要存储的关键字,而值域的范围依赖于散列表的大小或地址范围;
  • 散列函数计算出来的地址应能等概率、均匀地分布在整个地址空间中,从而减少冲突的发生;
  • 散列函数应尽量简单,能够在较短时间内计算出任意关键字的散列地址。

5.3.1、除留余数法

假定散列表表长为m,取一个不大于m但最接近或等于m的质数p,利用以下公式将关键字转换为散列地址,散列函数为: H ( k e y ) = k e y % p   ( p < = m ) H(key)=key\%p \ (p<=m) H(key)=key%p (p<=m)可以对关键字直接取模(即取余),也可在折叠、平方后再取模。
关键是选好p,使得每个关键字通过该函数转换后等概率地映射到散列空间上任一地址,从而尽量减少冲突的可能性。

5.3.2、直接定址法

直接取关键字的某个线性函数值为散列地址,散列函数为: H ( k e y ) = k e y 或 H ( k e y ) = a ∗ k e y + b H(key)=key或H(key)=a*key+b H(key)=keyH(key)=akey+b式中,a和b是常数,这种方法计算最简单,且不会产生冲突。适合关键字的分布基本连续的情况,若关键字分布不连续,空位较多,则会造成存储空间的浪费。

5.3.3、数学分析法

例如当身份证证号为关键字时,这串数字是有规则的,无需将整个身份证号全部当做散列地址,这时我们给关键字进行抽取,抽取方法是使用关键字的一部分来计算散列地址的方法。适合处理关键字位数比较大的情况,如果事先知道关键字的分布且关键字的若干位分布较均匀,就可以考虑用这个方法。

5.3.4、平方取中法

假设关键字是1234,那么它的平方就是1522756,取中即抽取中间的3位,也就是227,用作散列地址;再比如关键字4321,其平方为18671041,抽取中间的3位,可以是671也可以是710用作散列地址。适合于不知道关键字的分布,而位数又不是很大的情况。

5.3.5、随机数法

选择一个随机数,取关键字的随机数作为它的散列地址,也就是: H ( k e y ) = r a n d o m ( k e y ) H(key)=random(key) H(key)=random(key)这里的random是随机函数。当关键字的长度不等时,可采用这个方法。

5.4、处理冲突的方法

5.4.1、拉链法

将所有关键字为同义词的记录存储在一个单链表中,我们称这种表为同义词子表,在散列表中只存储所有同义词子表的头指针。
例如,关键字序列为 { 12 , 67 , 56 , 16 , 25 , 37 , 22 , 29 , 15 , 47 , 48 , 34 } \{12,67,56,16,25,37,22,29,15,47,48,34\} {12,67,56,16,25,37,22,29,15,47,48,34},用除留取余法构造散列函数 H ( k e y ) = k e y % 12 H(key)=key\%12 H(key)=key%12,用拉链法处理冲突,建立的表如下图所示:
在这里插入图片描述

5.4.2、开放定址法

所谓的开放定址就是一旦发生了冲突,就去寻找下一个空的散列地址,只要散列表够大,空的散列地址总能找到,并将记录存入。公式为: H i ( k e y ) = ( f ( k e y ) + d i ) % m   ( d i = 1 , 2 , 3 , . . . , m − 1 ) H_{i}(key)=(f(key)+d_{i})\%m\ (d_{i}=1,2,3,...,m-1) Hi(key)=(f(key)+di)%m (di=1,2,3,...,m1)式中,H(key)为散列函数;i=0,1,2,…,k(k<=m-1);m表示散列列表的表长; d i d_{i} di为增量序列。
取定某一增量序列后,对应的处理方法就是确定的。

  • 注意:在开放定址的情形下,不能随便物理删除表中的已有元素,因为若删除元素,则会截断其他具有相同散列地址的元素的查找地址。因此,要删除一个元素时,可给它做一个删除标记,进行逻辑删除。但这样做的副作用是:执行多次删除后,表面上看起来散列表很满,实际上有许多位置未利用,因此需要定期维护散列表,要把删除标记的元素物理删除。

通常有以下4种方法:

1.线性探测法

d i = 0 , 1 , 2 , . . . , m − 1 d_{i}=0,1,2,...,m-1 di=0,1,2,...,m1时,称为线性探测法。这种方法的特点就是:当发生冲突时,顺序查看表中下一个单元(探测到表尾地址m-1时,下一个探测地址是表首地址0),直到找到一个空闲单元(表未满时,一定能找到空闲单元)或查遍全表。

(1)查找

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

(2)删除

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

(3)查找效率分析

在这里插入图片描述
在这里插入图片描述

(4)缺点

线性探测法可能使第i个散列地址的同义词存入第i+1个散列地址,这样本应存入第i+1个散列地址的元素就争夺第i+2个散列地址的元素的地址,从而造成大量元素在相邻的散列地址上堆积,大大降低了查找效率。

2.平方探测法

d i = 0 2 , 1 2 , 2 2 , . . . , k 2 , − k 2 d_{i}=0^{2},1^{2},2^{2},...,k^{2},-k^{2} di=02,12,22,...,k2,k2时,称为平方探测法。其中k<m/2,散列表长度m必须是一个可以被表示为4k+3的素数,又称二次探测法。
平方探测法是一种较好的处理冲突的方法,可以避免出现“堆积”问题,它的缺点是不能探测到散列表上的所有单元,但至少能探测到一半单元。

(1)查找

在这里插入图片描述
在这里插入图片描述

3.伪随机序列法

d i = 伪随机数序列 d_{i}=伪随机数序列 di=伪随机数序列时,称为伪随机序列法。

4.再散列法

d i = H a s h 2 ( k e y ) d_{i}=Hash_{2}(key) di=Hash2(key)时,称为再散列法,又称为双散列法。需要使用两个散列函数,当通过第一个散列函数H(key)得到的地址发生冲突时,则利用第二个散列函数 H a s h 2 ( k e y ) Hash_{2}(key) Hash2(key)计算该关键字的地址增量,它具体的散列函数形式如下: H i = ( H ( k e y ) + i ∗ H a s h 2 ( k e y ) ) % m H_{i}=(H(key)+i*Hash_{2}(key))\%m Hi=(H(key)+iHash2(key))%m初始探测地址 H 0 = H ( k e y ) H_{0}=H(key) H0=H(key),i是冲突次数,初始为0。在再散列法中,最多经过m-1次探测就会遍历表中所有位置,回到 H 0 H_{0} H0位置。

5.4.3、公共溢出区法

这个方法其实就更加好理解,就是把凡是冲突的家伙额外找个公共场所待着。我们为所有冲突的关键字建立了一个公共的溢出区来存放。
就前面的例子而言,我们共有三个关键字37,48,34与之前的关键字位置有冲突,那么就将它们存储到溢出表中,如下图所示。
在这里插入图片描述
如果相对于基本表而言,有冲突的数据很少的情况下,公共溢出区的结构对查找性能来说还是非常高的。

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

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

相关文章

<数据集>学生课堂行为识别数据集<目标检测>

数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;13899张 标注数量(xml文件个数)&#xff1a;13899 标注数量(txt文件个数)&#xff1a;13899 标注类别数&#xff1a;8 标注类别名称&#xff1a;[js, tt, dk, zt, dx, zl, jz, xt] # 举手 js # 抬头听课 …

新版GPT-4omini上线!快!真TM快!

大半夜&#xff0c;OpenAI突然推出了GPT-4o mini版本。 当我看到这条消息时&#xff0c;正准备去睡觉。mini版本质上是GPT-4o模型的精简版本&#xff0c;没有什么革命性的创新&#xff0c;因此我并没有太在意。 结果今天早上一觉醒来发现伴随GPT-4o mini上线&#xff0c;官网和…

Vue3+ element plus 前后分离admin项目安装教程

前后分离admin项目安装 前后分离admin项目安装基于 vue3.x CompositionAPI typescript vite element plus vue-router-next pinia&#xff0c;适配手机、平板、pc 的后台开源免费模板&#xff0c;希望减少工作量&#xff0c;帮助大家实现快速开发。 下载源码 前往gite…

Flink SQL 实时读取 kafka 数据写入 Clickhouse —— 日志处理(三)

文章目录 前言Clickhouse 表设计adlp_log_local 本地表adlp_log 分布式表 Flink SQL 说明创建 Source Table (Kafka) 连接器表创建 Sink Table (Clickhouse) 连接器解析 Message 写入 Sink 日志查询演示总结 前言 在之前的文章中&#xff0c;我们总结了如何在 Django 项目中进…

甄选范文“论系统安全架构设计及其应用”,软考高级论文,系统架构设计师论文

论文真题 随着社会信息化进程的加快,计算机及网络已经被各行各业广泛应用,信息安全问题也变得愈来愈重要。它具有机密性、完整性、可用性、可控性和不可抵赖性等特征。信息系统的安全保障是以风险和策略为基础,在信息系统的整个生命周期中提供包括技术、管理、人员和工程过…

Noah-MP陆面生态水文模拟与多源遥感数据同化技术

了解陆表过程的主要研究内容以及陆面模型在生态水文研究中的地位和作用&#xff1b;熟悉模型的发展历程&#xff0c;常见模型及各自特点&#xff1b;理解Noah-MP模型的原理&#xff0c;掌握Noah-MP模型在单站和区域的模拟、模拟结果的输出和后续分析及可视化等方法&#xff1b;…

【Spring Boot】网页五子棋项目实现,手把手带你全盘解析(长达两万3千字的干货,坐好了,要发车了......)

目录 网页五子棋项目一、项目核心流程二、 登录模块2.1 前端输入用户信息2.2 后端进行数据库查询用户信息 三、 游戏大厅模块3.1 前端通过Ajax请求用户数据&#xff0c;后端从Session中拿取并从数据库中查询后返回3.2 前后端建立WebSocket连接&#xff0c;并进行判断&#xff0…

xxl-job登录没反应问题解决方法

最近在写一个关于xxl-job的项目&#xff0c;然后遇到了如下的问题&#xff0c;可以正常访问到xxl-job的登录界面但是点击登录按钮发现没有反应&#xff0c;并且没有发送任何请求。 排查步骤&#xff08;使用docker&#xff09; 1.重启mysql 2.重启docker 3.重写安装mysql 4.查看…

Mysql-索引结构

一.什么是索引&#xff1f; 索引(index)是帮助MySQL高效获取数据的数据结构(有序)。在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法,这种数据结构就是索引 二.无索引的情况 找到…

【Linux】Linux的基本使用

一.Linux的背景知识. 1.1什么是Linux Linux是一种开源的类Unix操作系统内核. 和Windows是" 并列 "的关系. 1.2Linux的发行版本. Linux 严格意义来说只是一个 “操作系统内核”.一个完整的操作系统 操作系统内核 配套的应用程序. 由于 Linux 是一个完全开源免费…

基于JSP的高校二手交易平台

开头语&#xff1a;你好&#xff0c;我是专注于计算机技术的学姐码农小野&#xff0c;如果有任何技术需求&#xff0c;欢迎随时联系我。 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;JSP技术 JAVA MySQL 工具&#xff1a;常见Web浏览器&#xff0…

【开发踩坑】 MySQL不支持特殊字符(表情)插入问题

背景 线上功能报错&#xff1a; Cause:java.sql.SQLException:Incorrect string value:xFO\x9F\x9FxBO for column commentat row 1 uncategorized SQLException; SQL state [HY000]:error code [1366]排查 初步觉得是编码问题&#xff08;utf8 — utf8mb4&#xff09; 参考上…

Linux环境下dockes使用MongoDB,上传zip文件如何解压并备份恢复到MongoDB数据库中

1、准备 Docker 和 MongoDB 容器 建议主机端口改一下 docker run --name mongodb -d -p 27018:27017 mongo 2. 创建一个工作目录并将 zip 文件上传到dockers容器中 docker cp data.zip mongodb:/data.zip 3. 在 MongoDB 容器中解压 zip 文件&#xff08;也可以解压完再复制…

大语言模型LLM-三种模型架构

架构&#xff1a;由Transformer论文衍生出来的大语言模型&#xff0c;主要有三种模型架构预训练目标&#xff1a;FLM&#xff0c;PLM&#xff0c;MLM调整&#xff1a;微调&#xff1a; Transformer transfomer可以并行地计算&#xff1f; transformer中encoder模块是完全并行…

深入理解Linux网络(四):TCP接收阻塞

TCP socket 接收函数 recv 发出 recvfrom 系统调用。 进⼊系统调⽤后&#xff0c;⽤户进程就进⼊到了内核态&#xff0c;通过执⾏⼀系列的内核协议层函数&#xff0c;然后到 socket 对象的接收队列中查看是否有数据&#xff0c;没有的话就把⾃⼰添加到 socket 对应的等待队列⾥…

MYSQL——库表操作

MYSQL——库表操作 1.1 SQL语句基础1.1.1. SQL简介1.1.2. SQL语句分类1.1.3. SQL语句的书写规范 1.2 数据库的操作1.2.1 数据库的登录及退出1.2.2 查看数据库1.2.3 创建数据库1.2.4 切换数据库1.2.5 查看当前用户1.2.6 删除数据库 1.3 MySQL字符集1.3.1. 字符集1.3.2. 字符序1.…

myBatis的基本操作(持续更新中。。。)

目录 1. 简介2. 简单使用3. 代理开发4. 小技巧5. 动态查询6. 注解&#xff08;待更新&#xff09;底部 1. 简介 mybatis是一款优秀的持久层框架&#xff0c;用来简化JDBC开发 持久层&#xff1a;负责将数据保存到数据库的那一层代码 2. 简单使用 依赖 <dependencies>…

LabVIEW断路器操动机构运动速度检测

开发了一种基于LabVIEW设计平台开发的断路器操动机构运动速度检测系统。通过集成高速相机和图像处理技术&#xff0c;该系统能够实时监控和分析操动机构的动态性能&#xff0c;为电力系统提供关键的技术支持。 项目背景 随着工业化的发展&#xff0c;对电力系统的稳定性和可靠…

python的tkinter、socket库开发tcp的客户端和服务端

一、tcp通讯流程和开发步骤 1、tcp客户端和服务端通讯流程图 套接字是通讯的利器&#xff0c;连接时要经过三次握手建立连接&#xff0c;断开连接要经过四次挥手断开连接。 2、客户端开发流程 1&#xff09;创建客户端套接字 2&#xff09;和服务端器端套接字建立连接 3&#x…

钡铼分布式I/O系统边缘计算Modbus,MQTT,OPC UA耦合器BL206

BL206系列耦合器是一个数据采集和控制系统&#xff0c;基于强大的32 位微处理器设计&#xff0c;采用Linux操作系统&#xff0c;支持Modbus&#xff0c;MQTT&#xff0c;OPC UA协议&#xff0c;可以快速接入现场PLC、DCS、PAS、MES、Ignition和SCADA以及ERP系统&#xff0c;同时…