哈希 -- 位图、布隆过滤器、海量数据处理

目录

  • 一、位图
    • 1.1 经典题目
    • 1.2 位图概念
    • 1.3 位图的应用
    • 1.4 关于位图的三个经典问题
  • 二、布隆过滤器
    • 2.1 布隆过滤器的提出
    • 2.2 布隆过滤器的概念
    • 2.3 布隆过滤器的插入
    • 2.4 布隆过滤器的查找
    • 2.5 布隆过滤器删除
    • 2.6 代码实现
    • 2.7 布隆过滤器的优点
    • 2.8 布隆过滤器的缺陷
    • 2.9 布隆过滤器的应用场景
  • 三、海量数据处理
    • 3.1 布隆过滤器
    • 3.2 位图应用
    • 3.3 哈希切割

一、位图

1.1 经典题目

假设有这么一道题目:
给40亿个不重复的无符号整数,没排过序。给一个无符号整数,如何快速判断一个数是否在这40亿个数中。
1、先把数据用set存起来,再查找一个无符号整数可以吗?
不可以!为什么?因为40亿个整数大概要占16G内存,但是一般配置的计算机都是开不出16G的内存的,除非有些超级计算机,所以这个方法并不适用于所有计算机。
2、排序+二分查找可以吗?
也不适合,因为数据量太大而不能一次性全部加载到内存中,所以需要在磁盘中进行归并排序,要进行大量的IO,效率低;并且二分查找的时候也是要在磁盘中进行的,所以这个方法也不适合解决这个问题!
这也不行,那也不行,那该如何解决这个问题呢?
上面两种方法之所以不适用,是因为数据量太大了,并且又是整形,所占的内存空间太多,所以我们不能开辟那么大的内存出来,那如果我们能够用一个很小的空间标志出这些数据是否存在,那不就可以了吗?在这道题中我们的目标是知道一个数在不在这堆数里面,是在不在的问题,所以我们完全没有必要把这40亿个整数存起来,只需要标志一下这些数是否存在就可以了,标志一个数在不在我们其实只需要一个比特位就可以了,某个数在就把对应的比特位设置成1,不在就把对应的比特位设置成0,这样一来,本来需要4个字节,即32个比特位的空间存放一个整形,现在变成了只需要一个比特位标志,所以40亿个整数占用的空间就从16G变成了500M,500M的内存我们是可以开辟出来的,我们把开辟出来标志数据在不在的这段空间叫做位图,这样我们就能把这40亿个整数都标志到这个位图的对应位置,再查找某一个数在不在的时候就只需要查看位图中对应位置的是否为1,是1就表示这个数在,是0就表示这个数不在。
如此一来,就能把这道题给解决了。

1.2 位图概念

所谓位图,就是用每一位来存放某种状态,适用于海量数据,数据无重复的场景。通常是用来判断某个数据存不存在的。
因为500M内存我们的计算机是能够开辟出来的,所以我们用的是直接定址法,即每一个整数直接映射到位图上的对应的位置。
在这里插入图片描述
位图代码实现:

namespace BitSetC
{//N是非类型模板参数template <size_t N>class bitset{public://构造函数,N表示该位图能映射的数据的最大值,每一个映射的值是一个比特位,所以应该根据//N的值求出我们需要开辟多少个char的空间,因为/的特点是把余数舍去了,所以为了映射数据//时不越界,所以应该多开辟一个char的空间,所以是开辟N/8+1个空间bitset(){_bs.resize(N / 8 + 1);}void set(size_t x){//计算x应该映射到第几个char中size_t i = x / 8;//计算x在第i个char中的第几个位置size_t j = x % 8;//通过位运算把第i个char的第j个位置设置为1//就把这个x设置进位图了_bs[i] |= (1 << j);}bool test(size_t x){//计算x应该映射到第几个char中size_t i = x / 8;//计算x在第i个char中的第几个位置size_t j = x % 8;//利用位运算检查第i个char的第j个位置是否被设置成1了//如果设置了,就证明这个x在位图中,否则,x不在位图中if (((_bs[i] >> j) & 1) == 1){return true;}else{return false;}}void reset(size_t x){//计算x应该映射到第几个char中size_t i = x / 8;//计算x在第i个char中的第几个位置size_t j = x % 8;//通过位运算把第i个char中的第j位设置为0即可_bs[i] &= (~(1 << j));}private://这里的vector的元素可以是char,也可以是其他类型vector<char> _bs;};
}

1.3 位图的应用

  1. 快速查找某个数据是否在一个集合中
  2. 排序 + 去重
  3. 求两个集合的交集、并集等
  4. 操作系统中磁盘块标记

1.4 关于位图的三个经典问题

1、 给定100亿个整数,设计算法找到只出现一次的整数?
虽然是100亿个整数,但是整数最多也就40多亿个,所以一个位图占用的空间还是500M,因为要找出只出现一次的整数,如果只用一个位图只能标志一个数在不在,并不能很好的统计该数出现的次数,所以我们可以用两个位图来表示一个数字出现的次数,因为两个比特位可以表示出四种情况,00表示出现了0次,01表示出现了1次,10表示出现了2次,11表示出现了3次,如果一个数字出现了2次以上的就标志为11就行了,因为我们要找的是出现一次的数字,2次及以上的都是不符合要求的。

所以解决这个问题的大概思路是创建两个位图bs1和bs2,然后遍历这100亿个整数,判断bs1和bs2对应位置的情况,如果在这个数对应位置中,bs1=0,bs2=0,说明这个数还没有出现过,此时bs2设置为1;如果bs1=0,bs2=1,说明这个数字已经出现过一次,此时把bs1设置为1,bs2设置为0;如果bs1=1,bs2=0,说明这个数字已经出现了2次,这时把bs2设置为1,或者说设不设置都可以,因为这个数一定是不符合要求的。这样就能把所有数字出现的次数存放在了这两个位图中,再遍历一遍这批数,同时通过位图查看哪一些数映射到位图上对应位置的结果是bs1=0,bs2=1的数就是出现一次的数。

2、位图应用变形:1个文件有100亿个int,1G内存,设计算法找到出现次数不超过2次的所有整数。
同理,找出不超过2次的整数也是先按照第1题那样把这100亿个整形设置到两个位图bs1和bs2中,然后再遍历这100亿个数,找到在位图中对应位置的bs1=0,bs2=1或者bs1=1,bs2=0的数,就是出现次数不超过2的数,统计即可。

下面是用我们自己实现的位图解决1、2问题的参考代码:

namespace BitSetC
{//N是非类型模板参数template <size_t N>class bitset{public://构造函数,N表示该位图能映射的数据的最大值,每一个映射的值是一个比特位,所以应该根据//N的值求出我们需要开辟多少个char的空间,因为/的特点是把余数舍去了,所以为了映射数据//时不越界,所以应该多开辟一个char的空间,所以是开辟N/8+1个空间bitset(){_bs.resize(N / 8 + 1);}void set(size_t x){//计算x应该映射到第几个char中size_t i = x / 8;//计算x在第i个char中的第几个位置size_t j = x % 8;//通过位运算把第i个char的第j个位置设置为1//就把这个x设置进位图了_bs[i] |= (1 << j);}bool test(size_t x){//计算x应该映射到第几个char中size_t i = x / 8;//计算x在第i个char中的第几个位置size_t j = x % 8;//利用位运算检查第i个char的第j个位置是否被设置成1了//如果设置了,就证明这个x在位图中,否则,x不在位图中if (((_bs[i] >> j) & 1) == 1){return true;}else{return false;}}void reset(size_t x){//计算x应该映射到第几个char中size_t i = x / 8;//计算x在第i个char中的第几个位置size_t j = x % 8;//通过位运算把第i个char中的第j位设置为0即可_bs[i] &= (~(1 << j));}private://这里的vector的元素可以是char,也可以是其他类型vector<char> _bs;};
}//给定100亿个整数,设计算法找到只出现一次的整数?
//1个文件有100亿个int,1G内存,设计算法找到出现次数不超过2次的所有整数
template <size_t N>
class TwoBitSet
{
public:void set(size_t x){//x出现0次,则原来的位图组合是00,则把_bs1的x位置和_bs2的x位置设置为01if (!_bs1.test(x) && !_bs2.test(x)){_bs2.set(x);}//x出现1次,则原来的位图组合是01,则把_bs1的x位置和_bs2的x位置设置为10else if (!_bs1.test(x) && _bs2.test(x)){_bs1.set(x);_bs2.reset(x);}//x出现2次及以上,则原来的位图组合是10,则把_bs1的x位置和_bs2的x位置设置为11else if (_bs1.test(x) && !_bs2.test(x)){_bs2.set(x);}}//查找只出现一次的数bool is_once(size_t x){if (!_bs1.test(x) && _bs2.test(x)){return true;}return false;}//1个文件有100亿个int,1G内存,设计算法找到出现次数不超过2次的所有整数bool FindLowerTwo(size_t x){//出现1次if (!_bs1.test(x) && _bs2.test(x)){return true;}//出现2次else if (_bs1.test(x) && !_bs2.test(x)){return true;}//出现0次或者2次以上return false;}
private:BitSetC::bitset<N> _bs1;BitSetC::bitset<N> _bs2;
};

3、给两个文件,分别有100亿个整数,我们只有1G内存,如何找到两个文件交集?
这里也肯定是用位图来解决的,因为有100亿个整数,整形的范围是固定的42亿9千万个,所以一个位图还是500M的空间。
所以先创建两个位图bs1和bs2,然后分别把这两个文件的整数设置到bs1和bs2位图中。此时我们如何找到这两个位图中的交集呢?我们知道1&1=1,1&0=0,0&1=1,而位图中的每一个位置要么是0,要么是1,如果两个文件都有同一个数,即交集,那么它们在各自位图中的映射的位置一定是一样的,所以把两个位图进行按位与操作,得到的结果就是它们的交集了,并且通过位图来查找交集还自带了去重的操作,因为交集是一个无重复元素的集合。那这两个位图怎么做按位与操作呢?其实这里不用真的把两个位图做按位与操作的,只需要在遍历这些数的时候判断该数是否同时在bs1和bs2中就可以了。

int main()
{//给两个文件,分别有100亿个整数,我们只有1G内存,如何找到两个文件交集?//假设nums1和nums2就是100亿个整数的文件int nums1[] = { 1,2,3,6,8,2,3,6 ,6 };int nums2[] = { 1,7,9,6 };BitSetC::bitset<10> bs1;BitSetC::bitset<10> bs2;for (const auto& e : nums1){bs1.set(e);}for (const auto& e : nums2){bs2.set(e);}for (size_t i = 0; i < 10; i++){//同一个元素两个位图都设置了说明这个元素是交集if (bs1.test(i) && bs2.test(i)){cout << i << " ";}}cout << endl;return 0;
}

二、布隆过滤器

2.1 布隆过滤器的提出

我们在刷抖音时,它会给我们不停地推荐新的内容,它每次推荐时要去重,去掉那些已经看过的内容。那么问题来了,抖音客户端推荐系统如何实现推送去重的? 用服务器记录了用户看过的所有历史记录,当推荐系统推荐视频时会从每个用户的历史记录里进行筛选,过滤掉那些已经存在的记录。 如何快速查找呢?

  1. 用哈希表存储用户记录。缺点:浪费空间
  2. 用位图存储用户记录。缺点:位图一般只能处理整形,如果内容编号是字符串,就无法处理了。
  3. 将哈希与位图结合,就叫做布隆过滤器。

2.2 布隆过滤器的概念

布隆过滤器是由布隆(Burton Howard Bloom)在1970年提出的 一种紧凑型的、比较巧妙的概率型数据结构,特点是高效地插入和查询,可以用来告诉你 “某样东西一定不存在或者可能存在”,它是用多个哈希函数,将一个数据映射到位图结构中的多个位置。此种方式不仅可以提升查询效率,也可以节省大量的内存空间。

2.3 布隆过滤器的插入

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

2.4 布隆过滤器的查找

布隆过滤器的思想是将一个元素用多个哈希函数映射到一个位图中的多个位置上,因此被映射到的位置的比特位一定为1。所以可以按照以下方式进行查找:分别计算每个哈希值对应的比特位置存储的是否为零,只要有一个为零,代表该元素一定不在哈希表中,否则可能在哈希表中。
注意:布隆过滤器如果说某个元素不存在时,该元素一定不存在,如果该元素存在时,该元素可能存在,因为有些哈希函数存在一定的误判。
比如:在布隆过滤器中查找"zhaoyun"时,假设3个哈希函数计算的哈希值为:2、4、6,刚好和其他元素的比特位重叠,即其他元素的刚好把2,4,6比特位都设置了,此时布隆过滤器告诉你该元素存在,但是该元素是不存在的。

2.5 布隆过滤器删除

布隆过滤器不能直接支持删除工作,因为在删除一个元素时,可能会影响其他元素。比如你要删除的元素的映射位置是1,3,5,那么你想删除这个元素就要把1,3,5位置都设置为0,但是可能其他元素通过哈希函数计算出来的映射位置也是1或者3或者5,所以如果把1,3,5的位置改成0的话,其它本来存在的元素也会变成不存在,这显然是不对的。基于这样的原因,有人提出既然直接置成0有可能会影响到其它元素,那么就用一个引用计数记录这个位置被映射了多少次,每一次删除的时候就减减这个引用计数,直到引用计数减为0的时候才把这个位置设置为0,这样删除就可以不影响其它元素了。
这个方法听起来确实可行,但是它真的可行吗?
其实不是的,因为某个元素存在是会有误判的,所以你怎么确定你这个元素是存在布隆过滤器里的呢?你都无法确定你这个元素是否存在,你怎么敢删除呢?就好比“zhaoyun”这个元素,假设它通过哈希函数算出来的映射位置是2,4,6,而2,4,6三个位置刚好又被其他元素都映射了,也就是说这个“zhaoyun”的存在是误判的,它压根就不存在,此时你删除“zhaoyun”,即把2,4,6三个位置的引用计数都减1,这符合逻辑吗?这显然不符合,你压根就不存在布隆过滤器中,你如何删除。所以用引用计数的方法实现布隆过滤器的删除也是不可行的,也是会影响到其他元素的,所以无论如何布隆过滤器都是不支持删除操作的。

2.6 代码实现

//针对字符串的哈希函数
struct BKDRHash
{size_t operator()(const string& str){size_t hash = 0;for (auto ch : str){hash = hash * 131 + ch;}return hash;}
};struct APHash
{size_t operator()(const string& str){size_t hash = 0;for (size_t i = 0; i < str.size(); i++){size_t ch = str[i];if ((i & 1) == 0){hash ^= ((hash << 7) ^ ch ^ (hash >> 3));}else{hash ^= (~((hash << 11) ^ ch ^ (hash >> 5)));}}return hash;}
};struct DJBHash
{size_t operator()(const string& str){size_t hash = 5381;for (auto ch : str){hash += (hash << 5) + ch;}return hash;}
};template <size_t N,class K = string,class Func1= BKDRHash, class Func2 = APHash, class Func3 = DJBHash>
class BloomFilter
{
public://为了减少误判率,所以一个字符串可以通过多个哈希函数//映射到多个位置,只有当全部的映射位置都被设置为1了才算// 是这个字符串存在,只要有任意一个位置没有被映射,就说//明这个字符串是不存在的void set(const K& key){//创建仿函数的匿名对象直接调用哈希函数计算映射位置//因为我们只有N个映射位置,所以需要%N才能映射到合// 法的对应的映射位置上size_t hash1 = Func1()(key) % N;size_t hash2 = Func2()(key) % N;size_t hash3 = Func3()(key) % N;//把通过哈希函数计算出来的这三个映射位置都设置为1,//代表这个字符串是存在的_bs.set(hash1);_bs.set(hash2);_bs.set(hash3);}bool test(const K& key){//分别检查key通过不同哈希函数计算出来的映射位置//是否都被设置成了1,只要其中任意一个位置不被设//置,就说明这个字符串是不存在的size_t hash1 = Func1()(key) % N;if (!_bs.test(hash1)){return false;}size_t hash2 = Func2()(key) % N;if (!_bs.test(hash2)){return false;}size_t hash3 = Func3()(key) % N;if (!_bs.test(hash3)){return false;}//来到这里说明该字符串在这三个映射的位置都被设置成1了//此时可以认为该字符串是存在的,但是也是会存在误判的//想要降低误判率,可以增加每一个字符串映射位置的个数//或者增加N,但是凡是都是有两面性的,增加了哈希函数就//会在映射时增加计算映射位置的时间,增大N就需要开辟更// 多的空间return true;}
private:bitset<N> _bs;
};

2.7 布隆过滤器的优点

  1. 增加和查询元素的时间复杂度为:O(K), (K为哈希函数的个数,一般比较小),与数据量大小无关。
  2. 哈希函数相互之间没有关系,方便硬件并行运算。
  3. 布隆过滤器不需要存储元素本身,在某些对保密要求比较严格的场合有很大优势。
  4. 在能够承受一定的误判时,布隆过滤器比其他数据结构有这很大的空间优势。
  5. 数据量很大时,布隆过滤器可以表示全集,其他数据结构不能
  6. 使用同一组散列函数的布隆过滤器可以进行交、并、差运算。

2.8 布隆过滤器的缺陷

  1. 有误判率,即存在假阳性(False Position),即不能准确判断元素是否在集合中(补救方法:再建立一个白名单,存储可能会误判的数据)
  2. 不能获取元素本身,只能判断元素存不存在。
  3. 不能从布隆过滤器中删除元素。
  4. 如果采用计数方式删除,还是会影响到其他元素,因为可能要删除的元素本身就不存在。

2.9 布隆过滤器的应用场景

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

三、海量数据处理

3.1 布隆过滤器

  1. 给两个文件,分别有100亿个query,我们只有1G内存,如何找到两个文件交集?分别给出精确算法和近似算法。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

3.2 位图应用

  1. 给定100亿个整数,设计算法找到只出现一次的整数?
  2. 给两个文件,分别有100亿个整数,我们只有1G内存,如何找到两个文件交集?
  3. 位图应用变形:1个文件有100亿个int,1G内存,设计算法找到出现次数不超过2次的所有整数
    这3个问题在上面位图的地方已经解答过了。

3.3 哈希切割

给一个超过100G大小的log file, log中存着IP地址, 设计算法找到出现次数最多的IP地址?
在这里插入图片描述
在这里插入图片描述
与上题条件相同,如何找到top K的IP?如何直接用Linux系统命令实现?
按每一条log file出现的次数建立一个k个元素的小堆,最后这个堆的k个数就是topk的IP,用linux系统指令实现是:

cat log.txt | cut -f1 -d' ' | sort | uniq -c | sort -nr | head -n 1上述命令按以下步骤执行:使用cat命令读取日志文件。
使用cut命令提取每行中的第一个字段(即IP地址)。
使用sort命令对IP地址进行排序。
使用uniq -c命令统计每个唯一的IP地址出现的次数。
使用sort -nr命令按照计数的逆序(从高到低)对IP地址进行排序。
使用head -n 1命令选择排序后的第一行(即出现次数最多的IP地址)。
要找到top K的IP地址,您可以将最后一步的命令更改为head -n K,其中K是您想找到的IP地址的数量。

以上就是今天想要跟大家分享的内容啦,你学会了吗?如果感觉到有所帮助,那就点亮一下小心心,点点关注呗,后期还会持续更新C++相关的知识哦,我们下期见!!!!

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

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

相关文章

TongWeb8下应用忙碌线程监控

问题 &#xff1a; 在系统运行过程中发现TongWeb进程占用CPU过高&#xff0c;需要分析是应用哪里引起的问题。 分析过程(仅限Linux环境)&#xff1a; 1. 通过top命令查看TongWeb的java进程占用的CPU情况。 查看误区&#xff1a;不要以为java进程CPU占到398%就是高&#xff0…

MySQL学习笔记12

MySQL 查询语句&#xff1a; 1、查询五子句&#xff1a;&#xff08;重点&#xff09; mysql> select */字段列表 from 数据表名称 where 子句 group by 子句 having 子句 order by 子句 limit 子句; 1&#xff09;where 子句&#xff1b;条件筛选。 2&#xff09;group…

golang 通过案列感受下内存分析

package main // 声音文件所在的包&#xff0c;每个go文件必须有归属的包 import ("fmt" )// 引入程序中需要用的包&#xff0c;为了使用包下的函数&#xff0c;比如&#xff1a;Printinfunc exchangeNum(num1 int, num2 int){var t intt num1num1 num2num2 t }…

Elasticsearch:什么是向量和向量存储数据库,我们为什么关心?

Elasticsearch 从 7.3 版本开始支持向量搜索。从 8.0 开始支持带有 HNSW 的 ANN 向量搜索。目前 Elasticsearch 已经是全球下载量最多的向量数据库。它允许使用密集向量和向量比较来搜索文档。 矢量搜索在人工智能和机器学习领域有许多重要的应用。 有效存储和检索向量的数据库…

Cortex-M3/M4之SVC和PendSV异常

一、SVC异常 SVC(系统服务调用&#xff0c;亦简称系统调用)用于产生系统函数的调用请求。例如&#xff0c;操作系统不让用户程序直接访问硬件&#xff0c;而是通过提供一些系统服务函数&#xff0c;用户程序使用 SVC 发出对系统服务函数的呼叫请求&#xff0c;以这种方法调用它…

2023华为杯数学建模D题第三问-碳排放路径优化(能源消费结构调整的多目标优化模型构建详细过程+模型假设(可复制))

1.碳排放约束下&#xff08;人为干预按时碳达峰与碳中和的基准情景&#xff09;能源消费结构多目标优化模型构建 1.1基本假设 本文的模型设计主要基于以下几个基本假设&#xff1a; &#xff08;1&#xff09;能源消费结构调整的根本驱动要素&#xff0c;是对投资耗费的最小化…

威胁的数量、复杂程度和扩散程度不断上升

Integrity360 宣布了针对所面临的网络安全威胁、数量以及事件响应挑战的独立研究结果。 数据盗窃、网络钓鱼、勒索软件和 APT 是最令人担忧的问题 这项调查于 2023 年 8 月 9 日至 14 日期间对 205 名 IT 安全决策者进行了调查&#xff0c;强调了他们的主要网络安全威胁和担忧…

Java流式编程的使用

流式编程的使用步骤 使用流式编程的步骤就是: 设置数据源, 设置数据处理的方式,设置收集结果的方式。 使用filter方法实现过滤条件 例子为下&#xff08;查询年龄大于18的用户&#xff09;: Testpublic void streamTest1() {List<Student> students Arrays.asList(ne…

《JVM》第二篇 JVM内存模型深度剖析与优化

目录 一. JDK体系结构与跨平台特性介绍二. JVM内存模型深度剖析三. 从Jvisualvm来研究下对象内存流转模型四. GC Root与STW机制五. JVM参数设置通用模型 一. JDK体系结构与跨平台特性介绍 二. JVM内存模型深度剖析 按照线程是否共享来划分 TLAB(Thread Local Allocation Buffe…

改写软件-怎么选择改写软件

什么是改写软件&#xff1f;改写软件是基于自然语言处理技术的工具&#xff0c;它们可以分析一段文字&#xff0c;并将其重新表达&#xff0c;以保持原始意义&#xff0c;但使用不同的词汇和结构。这种技术可用于减少内容的重复&#xff0c;增加多样性&#xff0c;或者简化复杂…

Python量化交易学习笔记(0)

本文将简单回顾我的量化交易学习的历程&#xff0c;并给出新手学习量化交易的建议学习路线&#xff0c;适合于尚无稳定盈利策略的量化新手阅读&#xff0c;量化大神们请略过。 本文将在博客中置顶&#xff0c;并不定期根据我的学习、交易进行更新。 回顾学习历程 2020年初接…

SpringMVC初级

文章目录 一、SpringMVC 概述二、springMVC步骤1、新建maven的web项目2、导入maven依赖3、创建controller4、创建spring-mvc.xml配置文件&#xff08;本质就是spring的配置件&#xff09;5、web.xml中配置前端控制器6、新建a.jsp文件7、配置tomcat8、启动测试 三、工作流程分析…

pytorch环境搭建到pycharm项目映射配置(成功后回顾性记录/自用)

利用Anaconda创建pytorch虚拟环境 前提&#xff1a;成功安装Anaconda&#xff0c;确保可以打开NVIDIA控制面板 开始-》搜索“Anaconda Prompt” 打开后输入&#xff1a;conda create -n 你的虚拟环境名 python3.9。输入y&#xff0c;继续安装&#xff0c;完成。 输入&#…

合肥综合性国家科学中心人工智能研究院-机器学习作业(一)

1.试析min-max规范化和z-score规范化的优缺点 可参考博客&#xff1a;https://wenku.csdn.net/answer/fdbf30eb204644e5b69fc533a3757268 2.试分析损失函数与性能度量的关系 损失函数和性能度量之间的关系可以根据优化目标来理解。损失函数的优化目标是最小化预测值与实际值之…

力扣刷题-链表-两两交换链表中的节点

24.两两交换链表中的节点 给定一个链表&#xff0c;两两交换其中相邻的节点&#xff0c;并返回交换后的链表。你不能只是单纯的改变节点内部的值&#xff0c;而是需要实际的进行节点交换。 解题思路 采用正常模拟的方法。 建议使用虚拟头结点&#xff0c;这样会方便很多&am…

面向面试知识-Redis

面向面试知识-Redis 什么是Redis 运行于内存的基于key-value的非关系型数据库。 一款开源的内存数据结构存储&#xff0c;用作数据库、缓存、消息代理等。&#xff08;可以基于Redis实现分布式锁、以及消息队列&#xff09; 发布订阅&#xff1f;&#xff1f; 对数据类型的操…

消息队列中,如何保证消息的顺序性?

本文选自&#xff1a;advanced-java 作者&#xff1a;yanglbme 问&#xff1a;如何保证消息的顺序性&#xff1f; 面试官心理分析 其实这个也是用 MQ 的时候必问的话题&#xff0c;第一看看你了不了解顺序这个事儿&#xff1f;第二看看你有没有办法保证消息是有顺序的&#xf…

Spring Boot的新篇章:探索2.0版的创新功能

文章目录 引言1. Spring Boot 2.0的响应式编程2. 自动配置的改进3. Spring Boot 2.0的嵌入式Web服务器4. Spring Boot 2.0的Actuator端点5. Spring Boot 2.0的Spring Data改进6. Spring Boot 2.0的安全性增强7. Spring Boot 2.0的监控和追踪8. Spring Boot 2.0的测试改进结论 &…

6、SpringBoot_项目的打包与运行

七、SpringBoot项目的打包与运行 1.目前项目怎么运行的 通过浏览器访问idea 将jar部署到服务器 2.maven 打包项目 命令 mvn package使用命令后会得到如下的jar 3.程序运行 命令 java -jar 项目.jar启动如下 4.springboot打包需要插件 插件 <plugin><group…

从零学习开发一个RISC-V操作系统(二)丨GCC编译器和ELF格式

本篇文章的内容 一、GCC&#xff08;GUN Compiler Collection&#xff09;1.1 GCC的命令格式1.2 GCC的主要执行步骤1.3 GCC涉及的文件类型 二、ELF简介2.1 ELF文件格式图2.2 ELF文件处理的相关工具2.3 练习 本系列是博主参考B站课程学习开发一个RISC-V的操作系统的学习笔记&…