面试:海量数据处理实例

12 篇文章 0 订阅
3 篇文章 0 订阅

在bat等大公司,基本所有业务的数据量级都很庞大,那么如何在保证数据完整性的情况下快速处理成了一个通用的难题,这里列举几个例子,大致反应一些处理思想。
1.一个文件中,每一行有一个整数,有上亿行,目的:统计出现次数超过三次的整数写入到另一个文件中。

分析:
(1)首先数据在文件中,既然要统计,那么有一个原则就是减少IO次数。
(2)其次数据量上亿,内存中肯定不可能全放下。
(3)需要统计次数,那么就需要知道每个整数的出现次数。
问题:既然内存中放不下每一个数据,那么就没办法知道当前拿到的数据出现了几次,也就不知道应不应该把它写入到目标文件中去。
思考:上亿的数据无法存放在内存中,我们先缩小数据量级,100w的数据是可以放在内存中的,那么我们是不是可以把上亿的数据分成100份100w的数据分开处理呢。
解决思路:先轮询一遍整个文件,对数据进行分片,分片规则:0<= num <100w放一个文件,100w<= num <200w放一个文件,依此类推。那么现在就会分为多个小文件了,我们就可以一个一个处理了,总的会进行2次IO,时间复杂度就是2n了。(PS:分治的方法,需要遍历两次,也可以使用位图,值需要遍历一次,但位图有限制,只能缩小32倍,2G内存最多可存放2^34个整数对应的位)

2.海量日志数据,提取出某日访问网站次数最多的IP

分析:
(1)日志数据极其庞大,包括各种格式不一致的数据。
(2)需要统计每个IP的访问次数,内存中肯定放不下当前的统计值,但是也不能放到外部存储中,这样会增加IO,并且效率会慢。
思考:一个ip32位,最多存在2^32次方个ip,可以采用分治的思想,比如IP模1000,再找出每个小文件中次数最多的ip,最后从1000个ip中找到访问次数最多的ip。(PS:分治的方法,类似于第一题)

3.搜索引擎会通过日志文件把用户每次检索使用的检索串都记录下来,每个查询串的长度为1~255个字节,假设目前有一千万个记录(这些查询串的重复度比较高,虽然总数是1千万,但如果除去重复后,不超过3百万个。一个查询串的重复度越高,说明查询它的用户越多,也就是越热门。),请你统计最热门的10个查询串,要求使用的内存不能超过1G

分析:
(1)1G最多能放1024^2*4=4194304个查询串,是足够放不超过300w查询串的数据的。
(2)然后需要在300w数据中找出前10大,即第k大问题,可以通过堆排序进行计算。
解决思路:使用hashmap,遍历1000w记录,得出300w查询串的统计值。然后维护一个10大小的小根堆,遍历300w次,每次与根对比,最后得出前10。(PS:采用trie树,关键字域存该查询串出现的次数,没有出现为0。最后用10个元素的最小推来对出现频率进行排序)

4.有一个1G大小的文件,里面每一行是一个词,词的大小不超过16字节,内存限制大小是1M,返回频数最高的100个词

分析:
(1)最大的问题是内存仅1M,那么能同时读入内存的数据就不能超过1M,只能分片。
(2)需要的是统计每个词出现的频率。
(3)每个词不超过16个字节,那么至少也就有1024^3/16=67108864个词。
问题:分片应该如何分?如何从分片后的数据统计得出所有数据的频数最高的词。
思考:1g至少要分1024份才能保证每一份平均大小为1M,为避免出现部分文件超出1M,我们可以取值再大一点。
解决思路:首先,取每个词%5000,然后把每个词按结果分别存到5000个小文件中,这样每个文件大约200k,如果还有文件大于1M,用这个方法继续拆。然后对每个小文件进行统计,按每个小文件前100个词带统计结果存入统计文件中,最后对这个文件内容进行排序,得出前100。

5.给定a,b两个文件,各存放50亿个url,每个url各占64字节,内存限制是4g,找出a,b文件共同的url。

分析:
(1)50亿个url需要500000000064 / (102410241024) ≈ 298G内存,也就是说每次只能处理单个文件1/75的数据,即数据至少分片75份。
(2)需要找出a,b共同的url,所以难点在于如何检索,如果以其中一个文件为基准去遍历至少也要(50亿
75)次遍历。
思考:使用url%1000,把a文件中所有url分到(a0,a1,…a999)中,同样b文件也分到(b0,b1,…,b999)中,这样每个文件大概300M,这样处理后,所有可能相同的url都在对应的小文件中(a0-b0,a1-b1…a999-b999),因为不对应的小文件不可能出现相同的url。然后对每个小文件进行对比就ok了。

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

分析:
(1)给定的数是40亿,一个特殊的值,是否有什么特殊含义。40亿个整数需要消耗40*108*4/10243 ≈ 14.9g内存。
(2)需要判断一个数是否存在,那么最好能直接在内存中检索。
问题:内存中不足以放下所有的数。
思考:由于只需要判断是与否,所以可以优先考虑“位图算法”,即一个整数用一个位来表示,存在为“1”,不存在为“0”。
解决思路:一个int值为4个字节,一个字节8bit,那么一个int值为32位,就可以表示031这32个整数是否存在,下一个int值表示3263这32个整数是否存在,依此类推。比如1565/32=48余29,应该在第47个整数的第28位上,0表示不存在,1表示存在。这样相当于节省内存32倍,需要的内存就为14.9g/32=476M,那么我们可以申请512M的内存。
另一种解决思路:分桶。可以参考第一题的按照数值大小分,也可以用另一个方案如下:
一个int值32位,首先,按首位为“0”和为“1”分,然后分别存放在两个文件中;然后再按次位为“0”或为“1”分,又可以分为2个文件了,这样就可以分为4个文件了,依次类推。其实就是一个二叉树的结构,这个二叉树最多可以有33层,也就是232,但是我们没有必要分那么细,因为232=42亿了,已经超过了我们要处理的数据,我们可以折衷分为2^5=32个文件即可,刚好512M内存足够存放一个文件的内容。这样我们需要检索一个数据的时候,可以先判断一下它的前5位,然后通过二叉树查找到对应文件,把该文件映射到内存中,然后在内存中检索。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Python是一种强大的编程语言,拥有丰富的数据处理库和工具,可用于处理海量数据。下面以一个简单的案例来说明Python如何处理海量数据。 假设我们有一个包含千万条学生信息的数据库文件,其中包含每个学生的姓名、年龄、性别、成绩等信息。我们需要对这些数据进行一些操作和计算。 首先,我们可以使用Python的pandas库来读取和处理数据库文件。通过调用pandas的read_csv函数,我们可以快速将数据库文件加载到内存中,并将其转换为一个数据结构,比如DataFrame,方便我们进行后续操作。 接下来,我们可以使用pandas的各种功能来对数据进行预处理和清洗。比如,我们可以使用DataFrame的filter、sort、groupby等函数来筛选、排序和分组数据,以满足我们的需求。例如,我们可以按照成绩对学生进行排名,筛选出前10%的学生,或者按照性别分组计算平均成绩。 除了pandas,Python还提供了其他强大的数据处理库,比如NumPy和SciPy,可以进行高性能的数值计算和科学计算。我们可以利用这些工具来进行数据分析、统计建模、机器学习等复杂的操作。例如,我们可以使用NumPy的数组和矩阵操作来进行矩阵计算,或者使用SciPy的统计函数来进行概率分布拟合和假设检验。 最后,Python还支持并行计算和分布式计算,可以利用多核处理器和集群来加速海量数据处理。通过使用Python的并行计算库,比如multiprocessing和concurrent.futures,我们可以将数据分成多个部分并行处理,提高计算效率。另外,Python还可以与一些分布式计算框架,比如Spark和Dask等,进行集成,以便处理更大规模的数据。 综上所述,Python为处理海量数据提供了丰富的工具和库,无论是进行简单的数据清洗和处理,还是进行复杂的数据分析和计算,Python都可以帮助我们高效地完成任务。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值