Go最新海量数据处理的方法总结,Golang高级工程师进阶学习—Golang热修复原理

11 篇文章 0 订阅
11 篇文章 0 订阅

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • (1)2.5亿个 int 类型 hash 到1024个小文件中 a0~a1023,如果某个小文件大小还大于内存,进行多级hash
  • (2)将每个小文件读进内存,找出只出现一次的数据,输出到b0~b1023
  • (3)最后数据合并即可

解决方案2 : 2-Bitmap

如果内存够1GB的话,采用 2-Bitmap 进行统计,共需内存 2^32 * 2bit = 1GB内存。2-bitmap 中,每个数分配 2bit(00表示不存在,01表示出现一次,10表示多次,11无意义),然后扫描这 2.5 亿个整数,查看Bitmap中相对应位,如果是00,则将其置为01;如果是01,将其置为10;如果是10,则保持不变。所描完成后,查看bitmap,把对应位是01的整数输出即可。(如果是找出重复的数据,可以用1-bitmap。第一次bit位由0变1,第二次查询到相应bit位为1说明是重复数据,输出即可)

二、Trie树+红黑树+hashmap

Trie树、红黑树 和 hashmap 可以认为是第一部分中分而治之算法的具体实现方法之一。

其中,Trie树适合处理海量字符串数据,尤其是大量的字符串数据中存在前缀时。Trie树在字典的存储,字符串的查找,求取海量字符串的公共前缀,以及字符串统计等方面发挥着重要的作用。

  • 用于存储时,Trie树因为不重复存储公共前缀,节省了大量的存储空间;
  • 用于以字符串的查找时,Trie树依靠其特殊的性质,实现了在任意数据量的字符串集合中都能以O(len)的时间复杂度完成查找(len为要检索的字符串长度);
  • 在字符串统计中,Trie树能够快速记录每个字符串出现的次数

**问题1:**上千万或上亿数据(有重复),统计其中出现次数最多的前N个数据。

解决方案: hashmap/红黑树 + 堆排序

  • (1)如果是上千万或上亿的 int 数据,现在的机器4G内存能存下。所以考虑采用 hashmap/搜索二叉树/红黑树 等来进行统计重复次数
  • (2)然后使用包含 N 个元素的小顶堆找出频率最大的N个数据

**问题2:**一个文本文件,大约有一万行,每行一个词,要求统计出其中最频繁出现的前10个词,并给出时间复杂度

解决思路: trie树 + 堆排序

  • 用 trie树 统计每个词出现的次数,时间复杂度是O(n*len)(len表示单词的平均长度)。
  • 然后使用小顶堆找出出现最频繁的前10个词,时间复杂度是O(n*lg10)。

总的时间复杂度,是O(n*le)与O(n*lg10)中较大的那一个。

问题3:有一千万个字符串记录(这些字符串的重复率比较高,虽然总数是1千万,但是如果去除重复和,不超过3百万个),每个查询串的长度为1-255字节。请你统计最热门的10个查询串(重复度越高,说明越热门),要求使用的内存不能超过1G。

解决方案:

内存不能超过 1G,每条记录是 255byte,1000W 条记录需要要占据2.375G内存,这个条件就不满足要求了,但是去重后只有 300W 条记录,最多占用0.75G内存,因此可以将它们都存进内存中去。使用 trie树(或者使用hashmap),关键字域存该查询串出现的次数。最后用10个元素的最小堆来对出现频率进行排序。总的时间复杂度,是O(n*le)与O(n*lg10)中较大的那一个。

问题4:1000万字符串,其中有些是重复的,需要把重复的全部去掉,保留没有重复的字符串。

解决方案:trie树

三、BitMap 与 Bloom Filter

1、BitMap 就是通过 bit 位为 1 或 0 来标识某个状态存不存在。可用于数据的快速查找,判重,删除,一般来说适合的处理数据范围小于 8bit *2^32。否则内存超过4G,内存资源消耗有点多。

2、Bloom Filter 主要是用于判定目标数据是否存在于一个海量数据集 以及 集合求交集。以存在性判定为例,Bloom Filter 通过对目标数据的映射,能够以 O(k) 的时间复杂度判定目标数据的存在性,其中k为使用的hash函数个数。这样就能大大缩减遍历查找所需的时间。

**问题1:**已知某个文件内包含一些电话号码,每个号码为8位数字,统计不同号码的个数。

解决思路

8位最多99 999 999,需要 100M个bit 位,不到12M的内存空间。我们把 0-99 999 999的每个数字映射到一个Bit位上,这样,就用了小小的12M左右的内存表示了所有的8位数的电话

问题2:2.5亿个整数中找出不重复的整数的个数,内存空间不足以容纳这2.5亿个整数。

解决方案:使用 2-bitmap,详情见上文

**问题3:**给40亿个不重复的 unsigned int 的整数,没排过序的,然后再给一个数,如何快速判断这个数是否在那40亿个数当中

解决方案:使用 Bitmap,申请 512M 的内存,一个bit位代表一个 unsigned int 值。读入40亿个数,设置相应的bit位,读入要查询的数,查看相应bit位是否为1,为1表示存在,为0表示不存在。

问题4:现有两个各有20亿行的文件,每一行都只有一个数字,求这两个文件的交集。

解决方案:采用 bitmap 进行问题解决,因为 int 的最大数是 2^32 = 4G,用一个二进制的下标来表示一个 int 值,大概需要4G个bit位,即约4G/8 = 512M的内存,就可以解决问题了。

  • ① 首先遍历文件,将每个文件按照数字的正数,负数标记到2个 bitmap 上,为:正数 bitmapA_positive,负数 bitmapA_negative
  • ② 遍历另为一个文件,生成正数:bitmapB_positive,bitmapB_negative
  • ③ 取 bitmapA_positive and bitmapB_positive 得到2个文件的正数的交集,同理得到负数的交集。
  • ④ 合并,问题解决

这里一次只能解决全正数,或全负数,所以要分两次

**问题5:**与上面的问题4类似,只不过现在不是A和B两个大文件,而是A, B, C, D….多个大文件,求集合的交集

解决方案:

  • (1)依次遍历每个大文件中的每条数据,遍历每条数据时,都将它插入 Bloom Filter;
  • (2)如果已经存在,则在另外的集合(记为S)中记录下来;
  • (3)如果不存在,则插入Bloom Filter;
  • (4)最后,得到的S即为所有这些大文件中元素的交集
四、多层划分:

多层划分本质上还是分而治之的思想,重在“分”的技巧上!因为元素范围很大,需要通过多次划分,逐步确定范围,然后最后在一个可以接受的范围内进行。适用用于:第k大,中位数,不重复或重复的数字

问题1:求取海量整数的中位数

解决方案:

依次遍历整数,按照其大小将他们分拣到n个桶中。如果有的桶数据量很小,有的则数据量很大,大到内存放不下了;对于那些太大的桶,再分割成更小的桶;

之后根据桶数量的统计结果就可以判断中位数落到哪个桶中,如果该桶中还有子桶,就判断在其哪个子桶中,直到最后找出目标。

**问题2:**一共有N个机器,每个机器上有N个数,每个机器最多存 N 个数,如何找到 N^2 个数中的中数?

解决方案1: hash分解 + 排序

  • 按照升序顺序把这些数字,hash划分为N个范围段。假设数据范围是2^32 的unsigned int 类型。理论上第一台机器应该存的范围为0(2^32)/N,第i台机器存的范围是(2^32)*(i-1)/N(2^32)*i/N。hash过程可以扫描每个机器上的N个数,把属于第一个区段的数放到第一个机器上,属于第二个区段的数放到第二个机器上,…,属于第N个区段的数放到第N个机器上。注意这个过程每个机器上存储的数应该是O(N)的。
  • 然后我们依次统计每个机器上数的个数,依次累加,直到找到第k个机器,在该机器上累加的数大于或等于(N2)/2,而在第k-1个机器上的累加数小于(N2)/2,并把这个数记为x。那么我们要找的中位数在第k个机器中,排在第(N2)/2-x位。然后我们对第k个机器的数排序,并找出第(N2)/2-x个数,即为所求的中位数的复杂度是O(N^2)的。

解决方案2: 分而治之 + 归并

先对每台机器上的数进行排序。排好序后,我们采用归并排序的思想,将这N个机器上的数归并起来得到最终的排序。找到第(N2)/2个便是所求。复杂度是O(N2 * lgN^2)的


参考文章:

教你如何迅速秒杀掉:99%的海量数据处理面试题_结构之法 算法之道-CSDN博客


相关阅读:

Spring常见面试题总结

SpringMVC常见面试题总结

Mybatis常见面试题总结

MySQL常见面试题总结

Redis常见面试题总结

RabbitMQ消息队列常见面试题总结

ElasticSearch搜索引擎常见面试题总结

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

链图片转存中…(img-w6EXwWUd-1715897973711)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 15
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值