
1) 【一句话结论】采用倒排索引为核心索引结构,结合Trie树加速前缀匹配,通过哈希表存储文档元数据,并利用多维度排序算法(如TF-IDF+时间+热度),同时设计分布式分片和缓存优化,支持模糊查询及大规模数据场景。
2) 【原理/概念讲解】倒排索引是搜索引擎核心,将每个关键词映射到包含该关键词的文档ID列表,类似图书馆“书名-书架位置”索引,支持多关键词查询(如“搜索文档”同时匹配“搜索”和“文档”)。Trie树(前缀树)用于前缀匹配,节点代表字符,路径为前缀,叶子节点标记文档,如手机输入法输入“offic”时快速定位“office.doc”“official.pdf”。哈希表用于文档元数据(ID、时间、热度),通过哈希函数实现O(1)时间复杂度查找,如手机通讯录查联系人。排序算法中,TF-IDF计算关键词相关性(高频低频词权重),时间排序(新文档优先,如最近24小时内的文档权重更高),热度排序(热门文档,如被分享或下载次数多的文档优先)。
3) 【对比与适用场景】
| 数据结构/算法 | 定义 | 特性 | 使用场景 | 注意点 |
|---|---|---|---|---|
| 倒排索引 | 关键词→文档ID列表的映射 | 支持多关键词查询,查询时合并文档集 | 主流搜索引擎核心(如搜索“搜索文档”) | 需维护更新,存储开销大(每个关键词对应文档列表) |
| Trie树 | 前缀树结构,节点代表字符 | 支持前缀匹配,快速查找 | 模糊查询(前缀)、自动补全(如输入“offic”时推荐文档) | 空间开销大(节点数量随前缀数量增长),适合前缀场景 |
| 哈希表 | 基于哈希函数的键值对存储 | O(1)查找、插入、删除 | 文档元数据(ID、时间、热度)快速查询 | 哈希冲突需处理(如链地址法、开放地址法) |
4) 【示例】
伪代码展示索引构建和查询处理(以用户输入“offic*”为例):
inverted_index = {} # 字典:关键词→文档ID列表
trie = Trie() # 前缀树
hash_map = {} # 文档ID→元数据(时间、热度)
for doc_id, content, metadata in documents:
for word in content.split():
inverted_index.setdefault(word, []).append(doc_id)
for word in content.split():
trie.insert(word)
hash_map[doc_id] = {
"time": metadata["time"],
"popularity": metadata["popularity"]
}
# 查询处理(模糊查询“offic*”)
query = "offic*"
if "*" in query:
prefix, suffix = query.split("*")
prefix_docs = trie.search_prefix(prefix) # 前缀匹配(如“offic”)
suffix_docs = inverted_index.get(suffix, []) # 后缀匹配(如“*”)
result = set(prefix_docs) | set(suffix_docs) # 去重合并
else:
result = set(inverted_index.get(query, [])) # 精确匹配
# 排序(多维度)
sorted_result = sort_by(
result,
hash_map,
relevance_func=lambda docs: tfidf(docs), # 相关性
time_func=lambda docs: -min(docs, key=lambda d: hash_map[d]["time"]), # 时间(新优先)
popularity_func=lambda docs: max(docs, key=lambda d: hash_map[d]["popularity"]) # 热度(热门优先)
)
5) 【面试口播版答案】
面试官您好,针对Office搜索文档的需求,我的设计核心是构建一个高效的多维度搜索系统。首先,采用倒排索引作为核心索引结构,它通过将每个关键词映射到包含该关键词的文档列表,支持多关键词查询(如“搜索文档”同时匹配“搜索”和“文档”),这是搜索引擎的基础。然后,结合Trie树加速前缀匹配(如用户输入“offic”时,快速找到所有以“offic”开头的文档,比如“office.doc”“official.pdf”),提升模糊查询的响应速度。同时,用哈希表存储文档元数据(如创建时间、热度),实现O(1)时间复杂度的元数据查询。对于排序,通过TF-IDF计算关键词相关性(高频低频词权重),结合文档时间(新文档优先,比如最近24小时内的文档权重更高)和热度(热门文档,如被分享或下载次数多的文档优先)进行多维度排序。在优化方面,对热门查询结果(如“report”)进行缓存(如Redis LRU缓存,淘汰最少使用的缓存项),对搜索结果进行内存分页(比如每页10条结果,避免内存溢出),并采用分布式分片(如将倒排索引按文档ID范围分片,部署在多个节点上,利用Elasticsearch的分布式查询),确保大规模数据下的性能。这样既能满足模糊查询(如“search*”)、多排序需求,又能保证系统性能。
6) 【追问清单】
7) 【常见坑/雷区】