百强企业2013新校招笔试题(二)
作者:网络转载 发布时间:[ 2013/10/28 10:07:54 ] 推荐标签:面试
10月11日,腾讯web前端面试
一个数组 var arr = ['abc','ddadbc','adbdcd','abcqew'.......] 长度一万, 用有效率的方法计算出包含被元素出现多的。
单机5G内存,磁盘200T的数据,分别为字符串,然后给定一个字符串,判断这200T数据里面有没有这个字符串,怎么做?
如果查询次数会非常的多, 怎么预处理?
点评:如果数据是200g且允许少许误差的话,可以考虑用布隆过滤器Bloom Filter:http://blog.csdn.net/v_july_v/article/details/6685894。但本题是200T,得另寻良策。
OK,以下是@cy 提供的题解(暴露出的一个问题是题意不是特别明确,因为题解中有不少自己的假设,所以日后各位面试时一定要跟面试官彻底弄清题意再作答,包括各种使用条件):
“①. 内存和数据比是 5GB / 200TB, 约为 1 比 4w, 所以trie啥的不用想了, 的是hash.
②. 简单的假设每个字符串是相对短的(只要不会超过5GB)
1. 几MB, 甚至百MB的字符串也能处理, 但是确实对终的效果有很大影响, 如果只是部分case特别大,可以特殊处理下.
③. 一个字符串块 在内存中需要一个 条目 来标识
1. value 需要 8 字节, key约为4字节
1. 200TB总共有 200 * 2^40 位, 地址空间至少为48个bit, 存储长度用16bit则一个条目的value 需要8个字节
1. 这里的长度是用来存一个 字符串块 的长度, 单位可以优化为KB, 甚至MB, 16bit肯定是够的
1. key用4个字节有些紧张, 可以考虑占用部分长度的位
1. 长度也可以不在条目中出现, 而是在块头出现, 但这样取块的时候有可能浪费, 也有可能要取多次.
2. 所谓一个 字符串块 是hash值相同的字符串挨个存在一起, 从而得到的字符串块.
④. 这样的话, 5GB 可以存放多 5GB / 8 约为 4亿个条目.
⑤. 把原来的200TB字符串挨个的hash, 并按hash排序后, 存起来, 建立索引.
1. hash值可以用md5之类的散列到足够开, 然后 mod 4亿值来求
⑥. 根据重排后的文件, 建立索引, key为hash值, value为前面说到的, 该hash对应字符串块在文件中的偏移, 和 块的长度.
⑦查询时, 根据hash值, 找到该字符串可能在的字符串, 然后将整个字符串读出来, 用kmp比较即可.
200TB的数据, 被划到 4亿 个字符块当中, 平均一块应该在 800KB 附近, 考虑到hash不均衡, 一般也是几MB的样子,
比较起来应该还OK.
⑧其他的小优化点:
1. 不是一个文件, 而是若干个文件, 但是不影响偏移的编号
1. 为什么做hash再分块? 避免通用前缀过多,导致分块极不均匀
1. 大长的字符串容易导致 字符串块 暴大, 可以考虑分为若干小串, 同时记录原来的位置, 知道是否是一个整串
1. 压缩...留一些空间做常用查询串的缓存...
⑨再说怎么优化这个预处理的排序过程. 每次读5GB的数据进来, 算好hash分好桶, 这种OK吧, 然后按桶回写到下去, 这里也是批量写的. 处理完继续处理下一个5GB, 全部处理完后, 再做归并, 搞几轮后, OK了嘛. 当然, 为了把内存中排序时浪费的IO补回来, 可以 并行做, 一个在算的时候,另一个在读....”。
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11