大数据问题

top k问题

即在很多数据的情况下选出前k大的数据,数据量可上亿

要分情况讨论,

如果是堆排序,时间复杂度是O(lgn)级别,,比较次数和交换次数相同,平均为logn/2,

可以采用插入排序的办法,只维护一个k的数组,按降序排列,只用在中间插入并删掉超过k的部分,这个时间复杂度为O(n),平均比较次数为O(n/2),移动次数是O(n/2),如果可以做成链表结构,则还能省去移动的开销,而只用在比较完成后修改指针

大数据排序

如果是上亿的数据,常规的办法:加载到内存并用经典算法是行不通的,内存没办法装下那么多数据,一种解决办法是用数据库来建立索引从而排序,要保证数据库要能容纳这么多数据

另一种解决是分治,,可以用哈希来把大文件映射到相同大小,小到能用内存装下,从而分批操作,最后用外排来两两合并成同一个文件,这即是归并排序的思想,归并的时候

分治的一个好处是如果有多机可以分块后并行操作

 

如果是不重复的数据,可以采用桶排序的思想,每一位代表一个数字,用上亿个bit位,也不过几百MB,可以读进内存;操作方法是先初始化这个bit数组位0,接着遍历一遍数据,对每个数字对应的bit位置1,最后按这些bit位写进另一个文件中,可以做到O(n)的排序

找重复

如果是知道界限的,不同的数字都能用一个bit表示,哪怕上亿的数据也只需几百MB的bit图,一个重复出现的数字设置bit图的时候会发现已经被设过了

找重复url

两个大文件,各含有很多url,找两个里面重复的url

因为是URL找相同,不能用bitmap来代表每个URL,要用常规办法,就得把URL装入内存,需要两边分别hash后取模,左右若相同的URL会落到相同序号的文件,然后用hashmap来把判断左右相同序号的文件里相同的URL

找不重复的数字

(用分治的思想,把文件切分到内存可容纳的大小后用)

用位图的方法,不过因为不重复,每个数字要用两个bit,也就翻倍而已

数据去重

问题:

  • 每个ID判断是否是第一次添加,或者说数据去重,是否是第一次添加也可以看成是有无标记,
  • 如何对短时间内的大量请求访问进行限流
  • 场景题:QQ的服务器会保存登录用户的QQ号,只要有登录,文件里面就会有记录,现在需要统计哪些QQ号登录过,怎么做?(先说了分治用小文件,他说除了这个了,我说bit数组,他就问需要多大内存?)

解决方案

可以采用数据库,每次加入看是否是第一次加入,但是如果数据很长,是URL或者很长的int会开销比较大,而且存在磁盘中访问比较慢

如果知道了数据的区间是连续的较密集的int,可以采用bitmap,能判断是否第一次且能去重

判断是否是黑名单,也是类似用法,如果是字符串类型如url,则无法用bitmap

另一种方法是用哈希,标记哈希完的值以节省空间,为了减少碰撞的危害,采用多种hash分别存储,如果一个字符串在多个hash完的记录里都存在,即被标记过(也可能碰撞),这就是布隆过滤器

 

 

总结

首先以下都能用数据库来解决

标记数据

如果是知道范围且不重复的数字,可以用bit位图表示,n个数据就是n个bit的大小

bitmap如果排列很稀疏,可以用谷歌的Enhanced Word-Aligned Hybrid算法,不在讨论范围内

如果是字符串类型比如URL,可以用多个哈希来标记如布隆过滤器

排序

对于大数据可以采用分治的思想,采用hash+取模就是一种划分的方法

如果要排序,可以采用分治+外排,即归并排序

  • 当然如果能了解下比如hdfs文件系统,一致性哈希,mapreduce,spark/flink流式计算最佳哈

如何并行

并行一个是拆分任务,一个是合并结果

拆分任务要保证任务间不重叠,最好是保证均匀划分,如果是处理数据,可以用哈希+取模的方式来分配

问题

  • 如何对短时间内的大量请求访问进行限流
  • 有200亿qq,但实际只有25亿用户,找到重复的qq,25亿qq占用内存多大
  • 1-100万,计算找出所有的质数(计算密集型任务),用单线程与多线程怎么处理
  • 1个G的文件写程序,从A机器发送到B机器,怎么发?
  • 100G的文本,每行80k还是80字符,提示用多个机器,多进程,多线程,求出重复最多的行。一个机器内存8G,计算每个机器大概分多少?能读取100G的文本吗?找重复率前十的文本
  • 三个有序的序列,查找公共的部分,第一次我说用哈希表,他说序列太大,空间复杂度要低点,我说了二分查找,他问三个序列查找的顺序和时间复杂度。(时间复杂度为N*logN *logN)
  • 100WURL,如何存储
  • 10台服务器,100w用户,如何进行负载均衡,如何有个服务器挂掉了咋 办
  • 地铁问题: 统计地铁   某一秒的 人数 数据: 时间都到秒级别 进站时间   出站时间   卡ID;;方法: 1、用一个数据a[60*60*24]来表示每一秒的变化人数,比如第10秒,进入100人,a[10]+=100,出站20人,a[10]-=20那么最终a[10] = 80。 2、再用另外一个同大小数组b[0] = a[0]     b[i] = b[i-1] + a[i]  就是第I秒前的总人数 重点: 考虑每秒变化的人数!

参考

  1. https://zhuanlan.zhihu.com/p/24383239
  2. https://baijiahao.baidu.com/s?id=1631026060250958623&wfr=spider&for=pc

https://blog.csdn.net/godwei_ding/article/details/80328923

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值