后端开发场景面试题
top k问题
10亿个数据中找出最大的10000个?
在10亿个数据中找出最大的10000个数,可以采用以下高效的方法:
方法一:使用最小堆
初始化最小堆:读取前10000个数据,构建一个大小为10000的最小堆。
遍历剩余数据:对于每一个后续的数据,与堆顶元素(当前最小的10000个数中的最小值)进行比较:
如果当前数据大于堆顶元素,则替换堆顶元素,并调整堆结构以保持最小堆的性质。
如果当前数据小于或等于堆顶元素,则跳过。
完成遍历:当所有数据处理完毕后,堆中的10000个数即为最大的10000个数。
优点:
时间复杂度为O(n log k),其中n为数据总数,k为10000。
空间复杂度为O(k),适用于内存有限的情况。
方法二:分块处理
分块:将10亿个数据分成多个块,例如每个块包含100万个数据。
块内处理:对每个块使用快速排序或其他方法,找出该块内的前10000个最大值。
合并结果:将所有块的前10000个最大值合并成一个大的数据集。
最终筛选:对合并后的数据集再次使用最小堆或其他方法,找出最终的10000个最大值。
优点:
适用于内存无法一次性处理所有数据的情况。
可以并行处理各个块,提高效率。
方法三:外部排序
分批处理:将数据分批读取到内存中,每批处理后将结果写入磁盘。
排序与合并:对每批数据进行排序,然后逐步合并排序后的结果,保持只保留最大的10000个数。
最终结果:完成所有批次的处理后,得到最大的10000个数。
优点:
适用于数据量远超内存容量的情况。
可以利用磁盘空间进行扩展处理。
方法四:结合哈希表优化
去重处理:如果数据中有大量重复值,可以先使用哈希表去重,减少需要处理的数据量。
后续处理:对去重后的数据使用上述方法之一,找出最大的10000个数。
优点:
减少处理数据量,提高效率。
特别适用于数据重复率较高的场景。
总结
根据具体情况,可以选择上述方法中的一种或多种结合使用。最小堆方法在内存足够的情况下最为高效,而分块处理和外部排序则适用于内存受限的情况。结合哈希表去重可以在数据重复率较高时进一步优化处理过程。
方法四:比特位图(bitmap)法
链接: bitmap计数,求TopK最快的方法
有几台机器存储着几亿淘宝搜索日志,你只有一台 2g 的电脑,怎么选出搜索热度最高的十个?
步骤 1:分块处理
数据分块:将几亿条日志分成多个小块,每个小块的大小适合内存处理。例如,每个小块包含3200万条日志,这样每个小块占用约2G内存。
遍历每个小块:逐个处理每个小块,避免一次性加载所有数据到内存中。
步骤 2:统计频率
哈希表统计:对于每个小块,使用哈希表统计每个搜索词的出现次数。
生成局部前十:对每个小块的哈希表进行排序,取出出现次数最多的前十名,记录下来。
步骤 3:合并结果
收集局部前十:将所有小块的前十名列表收集起来,形成一个大的列表。
统计总频率:对这个大的列表中的每个搜索词进行频率累加,得到每个搜索词的总出现次数。
全局排序:对累加后的结果进行排序,选出出现次数最多的前十名。
优化方法
使用堆结构:小顶堆排序,在每个小块处理时,使用堆结构只保留前十名,减少内存占用。
分布式处理:如果有多个机器,可以将分块处理任务分配到不同机器上,加快处理速度。
提取某日访问次数最多的IP地址
1.IP地址最多有2^32=4G种取值情况
2.可以考虑采用“分而治之”的思想,按照IP地址的Hash(IP)%1024值,把海量IP日志分别存储到1024个小文件中。这样,每个小文件最多包含4MB个IP地址;
3.对于每一个小文件,可以构建一个IP为key,出现次数为value的Hashmap,同时记录当前出现次数最多的那个IP地址;
4.可以得到1024个小文件中的出现次数最多的IP,再依据常规的排序算法得到总体上出现次数最多的IP;
具体步骤
Hash分片:
使用Hash函数Hash(IP) % 1024将IP地址分成1024个小文件。
每个小文件存储部分IP地址,减少内存压力。
Hash统计:
对每个小文件,构建一个Hashmap,其中键为IP地址,值为出现次数。
遍历小文件中的每个IP地址,更新Hashmap中的计数。
排序:
对每个小文件中的Hashmap,找出出现次数最多的IP地址。
将所有小文件中出现次数最多的IP地址收集起来,进行最终的排序,找出总体上出现次数最多的IP地址。
优点
内存效率:通过分片处理,避免了内存不足的问题。
处理效率:利用Hashmap进行快速统计,减少了处理时间。
搜索引擎会通过日志文件把用户每次检索使用的所有检索串都记录下来,每个查询串的长度为1-255字节。假设目前有一千万个记录(这些查询串的重复度比较高,虽然总数是1千万,但如果除去重复后,不超过3百万个。一个查询串的重复度越高,说明查询它的用户越多,也就是越热门。),请你统计最热门的10个查询串,要求使用的内存不能超过1G。
解决思路
Hash统计:使用Hashmap统计每个查询串的出现次数。
堆排序:利用堆结构快速找到出现次数最多的前10个查询串。
具体步骤
Hash统计:
遍历所有查询记录,使用Hashmap记录每个查询串的出现次数。
键为查询串,值为出现次数。
堆排序:
使用一个容量为10的最小堆,遍历Hashmap中的所有查询串。
对于每个查询串,如果其出现次数大于堆顶元素的出现次数,则替换堆顶元素,并调整堆。
最终,堆中包含出现次数最多的前10个查询串。
优点
内存效率:直接使用Hashmap统计,内存使用在限制范围内。
处理效率:堆排序的时间复杂度为O(N log K),适用于大数据量的处理。
2709

被折叠的 条评论
为什么被折叠?



