赞
踩
此博客主要讲解海量数据处理计算及算法实现,了解海量数据处理方法可移步海量数据处理方法总结,了解数据处理问题可移步海量数据处理问题总结
在解决问题之前,要先计算一下海量数据需要占多大的容量。常见的单位换算如下:
可以将海量数据拆分到多台机器上和拆分到多个文件上:
有以下策略进行拆分:
拆分之后的结果还只是局部结果,需要将局部结果汇总为整体的结果。
注:大部分海量数据都可以使用 hash 取模来处理,因为同一个值 hash 取模后一定会分配到同一个位置。如果内存实在小,N 的值可以取大一些。再者,Hadoop 和 spark 也是处理海量数据的方案,不过非大数据方向应该不做要求。
考虑到数据是海量的,那么就使用拆分的方式将数据拆分到多台机器上,分别在每台机器上使用 HashSet 存储。我们需要使得相同的数据拆分到相同的机器上,可以使用哈希取模的拆分方式进行实现。
如果海量数据是整数,并且范围不大时,就可以使用 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; } }
public class BloomFilter { //你的布隆过滤器容量 private static final int DEFAULT_SIZE = 2 << 28; //bit数组,用来存放key private static BitSet bitSet = new BitSet(DEFAULT_SIZE); //后面hash函数会用到,用来生成不同的hash值,可随意设置,别问我为什么这么多8,图个吉利 private static final int[] ints = {1, 6, 16, 38, 58, 68}; //add方法,计算出key的hash值,并将对应下标置为true public void add(Object key) { Arrays.stream(ints).forEach(i -> bitSet.set(hash(key, i))); } //判断key是否存在,true不一定说明key存在,但是false一定说明不存在 public boolean isContain(Object key) { boolean result = true; for (int i : ints) { //短路与,只要有一个bit位为false,则返回false result = result && bitSet.get(hash(key, i)); } return result; } //hash函数,借鉴了hashmap的扰动算法,强烈建议大家把这个hash算法看懂,这个设计真的牛皮加闪电 private int hash(Object key, int i) { int h; return key == null ? 0 : (i * (DEFAULT_SIZE - 1) & ((h = key.hashCode()) ^ (h >>> 16))); } }
字典树,又称单词查找树或键树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:最大限度地减少无谓的字符串比较,查询效率比哈希表高。
Trie 的核心思想是空间换时间。利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的。
三个基本性质:
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'; } }
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。