前段时间,我的一个朋友在字节的面试中,栽在了一道看似简单的大数据处理题上。
面试官抛出了一个看似简单却暗藏玄机的问题:
假设你是抖音搜索团队的工程师,每天需要分析1TB的用户搜索日志,找出最热门的100个搜索词。具体条件如下:
我朋友当时的内心:?
这是一道在大数据处理领域非常实用的算法题:如何在海量搜索词中找出TOP100热词。这个问题在实际应用中非常常见,无论是搜索引擎优化、社交媒体趋势分析,还是电商平台的商品推荐,都离不开这个技术。
大数据处理的“杀手锏”:分而治之
面对海量数据,我们需要一个既高效又省内存的方案。这里,我们采用“分而治之”的策略:
1. 数据分片
将1TB的大文件智能地切分成多个小文件,每个文件保持在 几百MB 的大小。这是为了确保每个分片在处理时不会超出内存限制。
def split_large_file(file_path, chunk_size=100*1024*1024): # 100MB chunks = [] with open(file_path, 'r') as f: chunk = [] for line in f: chunk.append(line) if len(chunk) * len(line) >= chunk_size: chunks.append(chunk) chunk = [] if chunk: # 处理最后一个不完整的chunk chunks.append(chunk) return chunks
2. 分片处理
对每个小文件进行并行词频统计。通过限制每片的大小,确保我们在任何时间点都不会超出内存限制,就像多个工人同时搬砖,效率倍增!
def count_word_frequency(chunk): word_counts = {} for line in chunk: word = line.strip() word_counts[word] = word_counts.get(word, 0) + 1 return word_counts
3. 结果合并
使用小顶堆快速合并各个分片的结果,找出全局 TOP 100。小顶堆的使用使得我们能够在内存有限的情况下,高效地保留最高频的词。
import heapq def merge_top_k(partition_results, k=100): global_heap = [] for result in partition_results: for word, count in result.items(): if len(global_heap) < k: heapq.heappush(global_heap, (count, word)) elif count > global_heap[0][0]: heapq.heapreplace(global_heap, (count, word)) return sorted(global_heap, reverse=True)
核心技术解密
这个方案有三大杀手锏:
- 哈希分区:将数据均匀分布到不同的文件中,避免单个文件过大。
- 并行计算:充分利用多核CPU,通过多线程/多进程并行处理分片,提高效率。
- 小顶堆:在内存有限的情况下高效筛选出Top K(本例中为TOP 100)。
大数据处理看似复杂,其实是“分治”思想的完美体现。关键在于:
在抖音这样的超大规模系统中,通常还会:
- 使用 Spark/Flink 进行分布式计算,以进一步扩展处理能力。
HDFS 等分布式文件系统,方便存储和处理大规模数据。
希望今天的分享对大家有所帮助!如果你对这个问题还有其他思路或疑问,欢迎留言讨论哦!