2019独角兽企业重金招聘Python工程师标准>>>
一个大文件,里面存储了一批非法词,每行一个词。
需求是,我随便给你一句话,能快速的判断出这句话是否包含了非法词,具体哪些非法词?
第一个关注点->算法
//
这个问题,常规的做法
1:逐行读文件,写到HashSet
2:forHashSet,对于每个word进行sentence.indexOf(word)>-1判断
通过循环Set的方式提取出句子中的非法词。
时间复杂度很容易得到:O(n),得留意下这里说的是大文件,这个n很大。能不能快一点呢?
//
使用Trie树
1:把文件中所有的非法词遍历出来,构建一颗Trie树
2:利用Trie树对sentence做分词处理("正向/反向最大匹配", "长词优先" 等策略),分得出来的词,则说明该sentence含有对应的非法词
Trie树查询时间复杂度O(1),这里忽略分词算法时间复杂度
这里真的就完美了吗?注意大文件Trie树利用HashMap做节点,巨耗空间,等于是在用空间换时间,可以考虑改进为DoubleArrayTrie树。有没有更好的方案?
//
使用BloomFilter
把字典压入BloomFilter
跟Trie树做分词差不多,只不过BloomFilter能更高效的利用空间。但是有小概率出现误判,在大数据面前无所谓了
检查时间复杂度依然是O(1),但空间的话可以省很多,即便是怕hash冲突,做多个BloomFilter
第二个关注点->如何加速文件读取速度,如果10GB怎么办?
这个方向我确实没有什么特别好的策略
唯一我知道的,能用文件内存映射技术实现IO加速
原理是,JVM要把文件读取到堆,一般情况下会经过文件->内核内存->JVM工作内存,中间存在一个数据拷贝的过程。
现代操作系统都使用虚拟内存,可以把多个虚拟地址可以映射到相同的物理地址,省去内核和用户空间之间的拷贝。
另外一种思路就是,把这个文件的信息,写入到HDFS上面去。加载的时候从HDFS上面拿,因为数据被打散到多台节点,我想读取的时候速度应该会快些。