目录java
海量数据计算总结node
海量数据去重总结python
在解决问题以前,要先计算一下海量数据须要占多大的容量。常见的单位换算以下:程序员
1 byte = 8 bit面试
1 KB = 210 byte = 1024 byte ≈ 103 byte数组
1 MB = 220 byte ≈ 10 6 byteide
1 GB = 230 byte ≈ 10 9 byte函数
1 亿 = 108oop
1 个整数占 4 byte,1 亿个整数占 4*108 byte ≈ 400 MB。学习
能够将海量数据拆分到多台机器上和拆分到多个文件上:
若是数据量很大,没法放在一台机器上,就将数据拆分到多台机器上。这种方式可让多台机器一块儿合做,从而使得问题的求解更加快速。可是也会致使系统更加复杂,并且须要考虑系统故障等问题;
若是在程序运行时没法直接加载一个大文件到内存中,就将大文件拆分红小文件,分别对每一个小文件进行求解。
有如下策略进行拆分:
拆分以后的结果还只是局部结果,须要将局部结果汇总为总体的结果。
注:大部分海量数据均可以使用hash取模来处理,由于同一个值hash取模后必定会分配到同一个位置。若是内存实在小,N的值能够取大一些。再者,Hadoop和spark也是处理海量数据的方案,不过非大数据方向应该不作要求。
下面是海量数据去重问题:
对于海量数据,要求判断一个数据是否已经存在。这个数据颇有多是字符串,例如 URL。
最直观的方法是使用 HashSet 存储,那么就能以 O(1) 的时间复杂度判断一个数据是否已经存在。
考虑到数据是海量的,那么就须要使用拆分的方式将数据拆分到多台机器上,分别在每台机器上使用 HashSet 存储。咱们须要使得相同的数据拆分到相同的机器上,可使用哈希取模的拆分方式进行实现。
若是海量数据是整数,而且范围不大时,就可使用 BitSet 存储。经过构建必定大小的比特数组,而且让每一个整数都映射到这个比特数组上,就能够很容易地知道某个整数是否已经存在。由于比特数组比整型数组小的多,因此一般状况下单机就能处理海量数据。
如下是一个 BitSet 的实现,固然在实际开发中能够直接使用语言内置的实现。
class BitSet {
int[] bitset;
public BitSet(int size) {
bitset = new int[(size >> 5) + 1]; // divide by 32
}
boolean get(int pos) {
int wordNumber = (pos >> 5); // divide by 32
int bitNumber = (pos & 0x1F); // mod 32
return (bitset[wordNumber] & (1 << bitNumber)) != 0;
}
void set(int pos) {
int wordNumber = (pos >> 5); // divide by 32
int bitNumber = (pos & 0x1F); // mod 32
bitset[wordNumber] |= 1 << bitNumber;
}
}
复制代码
使用 BitSet 还能够很容易地解决一个整数出现次数的问题,例如使用两个比特数组就能够存储 0~3 的信息。其实判重问题也能够简单当作一个数据出现的次数是否为 1,所以一个比特数组就够了。
布隆过滤器可以以极小的空间开销解决海量数据判重问题,可是会有必定的误判几率。它主要用在网页黑名单系统、垃圾邮件过滤系统、爬虫的网址判重系统。
布隆过滤器也是使用 BitSet 存储数据,可是它进行了必定的改进,从而解除了 BitSet 要求数据的范围不大的限制。在存储时,它要求数据先通过 k 个哈希函获得 k 个位置,并将 BitSet 中对应位置设置为 1。在查找时,也须要先通过 k 个哈希函数获得 k 个位置,若是全部位置上都为 1,那么表示这个数据存在。
因为哈希函数的特色,两个不一样的数经过哈希函数获得的值可能相同。若是两个数经过 k 个哈希函数获得的值都相同,那么使用布隆过滤器会将这两个数判为相同。
能够知道,令 k 和 m 都大一些会使得误判率下降,可是这会带来更高的时间和空间开销。
布隆过滤器会误判,也就是将一个不存在的数判断为已经存在,这会形成必定的问题。例如在垃圾邮件过滤系统中,会将一个邮件误判为垃圾邮件,那么就收不到这个邮件。可使用白名单的方式进行补救。
Trie 树又叫又叫字典树、前缀树、单词查找树,它是一颗多叉查找树。与二叉查找树不一样,键不是直接保存在节点中,而是由节点在树中的位置决定。
若是海量数据是字符串数据,那么就能够用很小的空间开销构建一颗 Trie 树,空间开销和树高有关。
Leetcode : Implement Trie (Prefix Tree)
class Trie {
private class Node {
Node[] childs = new Node[26];
boolean isLeaf;
}
private Node root = new Node();
public Trie() {
}
public void insert(String word) {
insert(word, root);
}
private void insert(String word, Node node) {
if (node == null) return;
if (word.length() == 0) {
node.isLeaf = true;
return;
}
int index = indexForChar(word.charAt(0));
if (node.childs[index] == null) {
node.childs[index] = new Node();
}
insert(word.substring(1), node.childs[index]);
}
public boolean search(String word) {
return search(word, root);
}
private boolean search(String word, Node node) {
if (node == null) return false;
if (word.length() == 0) return node.isLeaf;
int index = indexForChar(word.charAt(0));
return search(word.substring(1), node.childs[index]);
}
public boolean startsWith(String prefix) {
return startWith(prefix, root);
}
private boolean startWith(String prefix, Node node) {
if (node == null) return false;
if (prefix.length() == 0) return true;
int index = indexForChar(prefix.charAt(0));
return startWith(prefix.substring(1), node.childs[index]);
}
private int indexForChar(char c) {
return c - 'a';
}
}
复制代码
Bloom Filters: Is element x in set S?
程序员面试金典
程序员代码面试指南
推荐阅读
欢迎关注我的公众号【菜鸟名企梦】,公众号专一:互联网求职面经、java、python、爬虫、大数据等技术分享**: 公众号**菜鸟名企梦
后台发送“csdn”便可免费领取【csdn】和【百度文库】下载服务; 公众号菜鸟名企梦
后台发送“资料”:便可领取5T精品学习资料**、java面试考点和java面经总结,以及几十个java、大数据项目,资料很全,你想找的几乎都有