System Design 搜索功能面试方法论
System Design Search Methodology
🎯 核心问题:什么时候需要深入实现搜索 vs 什么时候可以用 Elasticsearch 快速带过?
Core Question: When to implement search from scratch vs when to use Elasticsearch?
📊 决策树:判断是否需要深入实现搜索
Decision Tree: When to implement search from scratch
面试题目分析
│
├─ 题目是否专门设计"搜索系统"?
│ │
│ ├─ YES → 深入实现搜索(不能直接用 Elasticsearch)
│ │ └─ 需要实现:Inverted Index, Tokenization, Ranking 等
│ │
│ └─ NO → 继续判断...
│
├─ 面试官是否明确禁止使用 Elasticsearch/搜索引擎?
│ │
│ ├─ YES → 深入实现搜索
│ │ └─ 需要自己实现核心搜索功能
│ │
│ └─ NO → 继续判断...
│
├─ 搜索是否是系统的核心功能(>50% 的讨论时间)?
│ │
│ ├─ YES → 深入实现搜索
│ │ └─ 即使可以用 Elasticsearch,也要深入讨论其原理
│ │
│ └─ NO → 可以用 Elasticsearch 快速带过
│ └─ 搜索只是系统的一个功能模块
│
└─ 题目类型判断
│
├─ "Design Facebook Search" → 深入实现
├─ "Design Google Search" → 深入实现
├─ "Design Post Search" → 深入实现
│
├─ "Design Ticketmaster" → Elasticsearch 快速带过
├─ "Design Uber" → Elasticsearch 快速带过(如果有搜索)
├─ "Design Instagram" → Elasticsearch 快速带过(如果有搜索)
└─ "Design E-commerce" → Elasticsearch 快速带过(如果有搜索)
🔍 场景一:需要深入实现搜索(不能直接用 Elasticsearch)
Scenario 1: Implement search from scratch (cannot use Elasticsearch directly)
典型题目特征
Typical Problem Characteristics
- 题目名称明确包含”Search”
- Design Facebook Post Search
- Design Google Search
- Design Twitter Search
- 面试官明确禁止使用搜索引擎
- “You cannot use Elasticsearch”
- “Build the search functionality from scratch”
- “We want to test your understanding of indexing fundamentals”
- 搜索是系统的核心功能
- 搜索相关的讨论会占据大部分面试时间
- 需要深入讨论搜索的底层原理
必须实现的核心组件
Core Components to Implement
1. Inverted Index(倒排索引)
核心思想:从 keyword → documents,而不是 document → keywords
Core Idea: Map keyword → documents, not document → keywords
数据结构:
Data Structure:
{
"keyword1": [docId1, docId2, docId3, ...],
"keyword2": [docId4, docId5, ...],
...
}
存储选择:
Storage Options:
- Redis: 内存存储,速度快,但需要考虑持久化
In-memory storage, fast, but need to consider persistence
- MemoryDB: Redis + 持久化
Redis + persistence
- 分布式存储:按 keyword hash 分片
Distributed storage: shard by keyword hash
2. Tokenization(分词)
功能:将文本分解为可搜索的关键词
Function: Break text into searchable keywords
处理步骤:
Processing Steps:
1. 文本预处理:转小写、去除标点
Text preprocessing: lowercase, remove punctuation
2. 分词:按空格分割
Tokenization: split by spaces
3. 去停用词(可选):the, a, an, etc.
Remove stop words (optional): the, a, an, etc.
4. 词干提取(可选):running → run
Stemming (optional): running → run
示例:
Example:
"Taylor Swift Concert"
→ ["taylor", "swift", "concert"]
3. 多关键词查询处理
单关键词:直接查 inverted index
多关键词(AND):
- 取交集:intersect(postIds for "Taylor", postIds for "Swift")
- 优化:从最小的 list 开始 intersect
多关键词(OR):
- 取并集:union(all postIds)
短语查询:
- Bigrams/Shingles: "Taylor Swift" → ["taylor swift"]
- 先查 bigram index,再 filter 验证
4. 排序(Sorting)
按时间排序:
- 使用 Redis List,append 时按时间顺序
- 查询时取最后 N 个元素
按点赞数排序:
- 使用 Redis Sorted Set
- Score = like count
- 查询时用 ZREVRANGE 取 top N
混合排序:
- 维护多个 index(时间 index + 点赞数 index)
- 根据用户选择查询对应的 index
5. 写入路径(Ingestion)
Post Creation Flow:
1. User creates post → Post Service
2. Post Service → Ingestion Service
3. Ingestion Service:
- Tokenize post content
- For each keyword:
- Add postId to Creation Index (Redis List)
- Add postId to Likes Index (Redis Sorted Set, score=0)
4. Store post metadata in DB
Like Event Flow:
1. User likes post → Like Service
2. Like Service → Ingestion Service
3. Ingestion Service:
- For each keyword in the post:
- Update score in Likes Index (ZINCRBY)
6. 查询路径(Query)
Search Flow:
1. User searches "Taylor Swift" sorted by likes
2. Tokenize query → ["taylor", "swift"]
3. Query Likes Index:
- Get postIds for "taylor" (sorted by likes)
- Get postIds for "swift" (sorted by likes)
- Intersect the two lists
4. Return top N results
优化策略
1. 处理热门关键词
问题:某些关键词(如 "the", "a")可能有百万级 postIds
解决方案:
- 限制每个 keyword 的 postId list 大小(如 top 10k)
- 使用 Bloom Filter 快速判断是否存在
- 对于超热门关键词,使用概率数据结构
2. 存储优化
冷热数据分离:
- Hot keywords → Redis (内存)
- Cold keywords → S3/Blob Storage (磁盘)
- 定期 batch job 迁移冷数据
分片策略:
- 按 keyword hash 分片到多个 Redis 实例
- 减少单个实例的压力
3. 写入优化
批量处理:
- 使用 Kafka 缓冲写入
- Batch updates 到 Redis
- 异步处理,不阻塞主流程
Like 事件优化:
- 使用 Two-Stage Architecture
- 只在里程碑更新(1, 2, 4, 8, 16... likes)
- 查询时再获取精确的 like count
4. 缓存策略
查询结果缓存:
- Cache key: "search:{keyword}:{sort}:{page}"
- TTL: 根据数据更新频率设置
- 使用 CDN 缓存热门查询
Index 缓存:
- 热门 keyword 的 postId list 保持在内存
- LRU eviction policy
面试要点总结
✅ 必须掌握:
- Inverted Index 的原理和实现
- Tokenization 的处理流程
- 多关键词查询的交集/并集算法
- 排序的实现(List vs Sorted Set)
- 写入和查询的完整流程
✅ 加分项:
- 处理热门关键词的策略
- 冷热数据分离
- 分布式系统的考虑(分片、复制)
- 缓存策略的优化
⚡ 场景二:可以用 Elasticsearch 快速带过
Scenario 2: Use Elasticsearch (quick pass)
典型题目特征
Typical Problem Characteristics
- 搜索只是系统的一个功能模块
- Design Ticketmaster(搜索事件只是功能之一)
- Design Uber(搜索司机/乘客不是核心)
- Design E-commerce(商品搜索是功能之一)
- 面试官没有禁止使用搜索引擎
- 可以直接使用成熟的解决方案
- 搜索不是面试重点
- 大部分时间讨论其他核心功能(如 booking、payment、scaling)
快速解决方案模板
Quick Solution Template
1. 识别搜索需求
Identify Search Requirements
在 Requirements 阶段:
During Requirements phase:
- "Users should be able to search for events by keyword"
- 明确搜索的范围和排序需求
Clarify search scope and sorting requirements
2. 提出 Elasticsearch 方案
Propose Elasticsearch Solution
"对于搜索功能,我会使用 Elasticsearch 作为专门的搜索数据库。
"For search functionality, I'll use Elasticsearch as a dedicated search database.
原因:
Reasons:
1. Elasticsearch 专为全文搜索优化,使用 Inverted Index
Elasticsearch is optimized for full-text search, uses Inverted Index
2. 支持复杂的查询(fuzzy search, phrase search)
Supports complex queries (fuzzy search, phrase search)
3. 可以处理高并发查询
Can handle high concurrent queries
4. 支持多种排序方式
Supports multiple sorting methods
架构:
Architecture:
- PostgreSQL (主数据库) → CDC → Elasticsearch (搜索索引)
PostgreSQL (main DB) → CDC → Elasticsearch (search index)
- Search Service 查询 Elasticsearch
Search Service queries Elasticsearch
- 结果返回给用户
Results returned to users"
3. 简要说明同步机制
"数据同步:
- 使用 CDC (Change Data Capture) 实时同步
- 或者使用 Kafka 作为中间层
- 确保 Elasticsearch 索引与主数据库一致"
4. 简要说明优化
"优化策略:
1. 缓存热门查询结果(Redis)
2. CDN 缓存(如果搜索结果不个性化)
3. Elasticsearch 集群水平扩展"
面试要点总结
✅ 快速带过的关键:
- 明确说明使用 Elasticsearch 的原因
- 简要说明数据同步机制(CDC)
- 提及基本的优化策略(缓存、CDN)
- 不要深入讨论 Elasticsearch 的内部实现
✅ 如果面试官追问:
- 可以简单说明 Elasticsearch 使用 Inverted Index
- 可以讨论如何保持数据一致性
- 可以讨论如何优化查询性能
- 但不需要自己实现 Inverted Index
📋 面试准备 Checklist
Interview Preparation Checklist
场景一准备(深入实现搜索)
Scenario 1 Preparation (Implement from scratch)
- 理解 Inverted Index 的原理和数据结构
- 掌握 Tokenization 的处理流程
- 熟悉多关键词查询的交集/并集算法
- 理解 Redis List 和 Sorted Set 的使用场景
- 准备处理热门关键词的策略
- 准备冷热数据分离的方案
- 准备分布式系统的考虑(分片、复制)
- 准备写入和查询的完整流程图
场景二准备(Elasticsearch 快速带过)
Scenario 2 Preparation (Elasticsearch quick pass)
- 理解 Elasticsearch 的基本原理(Inverted Index)
- 准备 CDC 同步机制的说明
- 准备缓存策略(Redis + CDN)
- 准备 Elasticsearch 集群扩展的说明
- 不需要深入实现细节
🎯 实战策略
Practical Strategies
策略一:开场就明确方向
Strategy 1: Clarify direction at the start
面试开始时的对话:
Candidate: "Before I start, I want to clarify - are we allowed to use
search engines like Elasticsearch, or should I design the
search functionality from scratch?"
Interviewer: "You can use Elasticsearch"
→ 快速带过,重点放在其他功能
Interviewer: "No, you need to build it from scratch"
→ 深入实现,重点讨论搜索原理
策略二:根据题目名称判断
Strategy 2: Judge by problem name
题目名称包含 "Search":
→ 默认需要深入实现
→ 如果面试官说可以用 Elasticsearch,再调整
题目名称是其他系统(Ticketmaster, Uber, etc.):
→ 默认可以用 Elasticsearch 快速带过
→ 如果面试官禁止,再深入实现
策略三:时间分配
Strategy 3: Time allocation
深入实现搜索(45-60分钟面试):
- Requirements: 5分钟
- Core Entities & API: 5分钟
- High-Level Design (Inverted Index): 15分钟
- Deep Dives (优化、扩展): 20-30分钟
- 总结: 5分钟
Elasticsearch 快速带过(45-60分钟面试):
- 搜索需求识别: 2分钟
- Elasticsearch 方案: 3分钟
- 数据同步说明: 2分钟
- 优化策略: 2分钟
- **总共 10 分钟内完成搜索部分**
- 剩余时间讨论其他核心功能
📚 参考题目分类
Problem Categories
需要深入实现的搜索题目
Problems requiring deep implementation
- Design Facebook Post Search
- 核心:实现 Inverted Index
- 重点:Tokenization, Multi-keyword queries, Sorting
- Design Google Search
- 核心:大规模搜索系统
- 重点:Crawling, Indexing, Ranking, Distributed systems
- Design Twitter Search
- 核心:实时搜索
- 重点:Real-time indexing, Trending topics, Hashtag search
可以用 Elasticsearch 快速带过的题目
Problems where Elasticsearch can be used (quick pass)
- Design Ticketmaster
- 搜索:事件搜索(Elasticsearch + CDC)
- 核心:Booking system, Distributed locks, Scalability
- Design Uber
- 搜索:司机/乘客匹配(可能不需要传统搜索)
- 核心:Real-time matching, Geospatial queries, Scaling
- Design E-commerce Platform
- 搜索:商品搜索(Elasticsearch + CDC)
- 核心:Inventory management, Payment, Recommendations
- Design Instagram
- 搜索:用户/帖子搜索(Elasticsearch)
- 核心:Feed generation, Image storage, Social graph
💡 关键区别总结
Key Differences Summary
| 维度 / Dimension | 深入实现搜索 / Deep Implementation | Elasticsearch 快速带过 / Quick Pass |
|---|---|---|
| 题目类型 / Problem Type | 专门设计搜索系统 / Dedicated search system | 搜索是功能之一 / Search is one feature |
| 面试重点 / Interview Focus | 搜索原理和实现 / Search principles & implementation | 其他核心功能 / Other core features |
| 技术深度 / Technical Depth | 需要实现 Inverted Index / Need to implement Inverted Index | 只需说明使用原因 / Just explain usage |
| 时间分配 / Time Allocation | 搜索占 60-80% / Search 60-80% | 搜索占 10-20% / Search 10-20% |
| 准备重点 / Preparation Focus | 搜索算法和数据结构 / Search algorithms & data structures | 系统整体架构 / Overall system architecture |
| 面试官期望 / Interviewer Expectation | 展示底层知识 / Show low-level knowledge | 展示系统设计能力 / Show system design skills |
🚀 快速决策指南
Quick Decision Guide
面试开始 → 看题目名称
Interview starts → Check problem name
│
├─ 包含 "Search" → 准备深入实现
│ Contains "Search" → Prepare deep implementation
│ └─ 问面试官:"Can I use Elasticsearch?"
│ Ask interviewer: "Can I use Elasticsearch?"
│ ├─ No → 深入实现 Inverted Index
│ │ Deep implementation of Inverted Index
│ └─ Yes → 可以讨论原理,但用 Elasticsearch
│ Can discuss principles, but use Elasticsearch
│
└─ 不包含 "Search" → 准备快速带过
Doesn't contain "Search" → Prepare quick pass
└─ 提到搜索时直接说:"I'll use Elasticsearch with CDC"
When mentioning search: "I'll use Elasticsearch with CDC"
└─ 如果面试官追问 → 简单说明原理
If interviewer asks → Briefly explain principles
└─ 如果面试官禁止 → 切换到深入实现模式
If interviewer forbids → Switch to deep implementation mode
📝 面试话术模板
Interview Script Templates
场景一:深入实现搜索
Scenario 1: Deep Implementation
"对于搜索功能,我需要实现一个 Inverted Index。
"For search functionality, I need to implement an Inverted Index.
核心思路是:
Core approach:
1. 建立 keyword → [postIds] 的映射
Build keyword → [postIds] mapping
2. 使用 Redis 存储,List 用于时间排序,Sorted Set 用于点赞数排序
Use Redis: List for time sorting, Sorted Set for like count sorting
3. 写入时 tokenize 内容,更新所有相关 keyword 的 index
On write: tokenize content, update all related keyword indices
4. 查询时取交集/并集,然后排序返回
On query: intersect/union, then sort and return
让我详细设计一下写入和查询的流程..."
Let me design the write and query flows in detail..."
场景二:Elasticsearch 快速带过
Scenario 2: Elasticsearch Quick Pass
"对于搜索功能,我会使用 Elasticsearch 作为专门的搜索数据库。
"For search functionality, I'll use Elasticsearch as a dedicated search database.
架构上:
Architecture:
- 主数据库(PostgreSQL)通过 CDC 同步到 Elasticsearch
Main DB (PostgreSQL) syncs to Elasticsearch via CDC
- Search Service 查询 Elasticsearch 返回结果
Search Service queries Elasticsearch and returns results
- 使用 Redis 缓存热门查询,CDN 缓存静态结果
Use Redis to cache popular queries, CDN to cache static results
这样可以满足低延迟搜索的需求。现在让我继续设计系统的其他核心功能..."
This meets low-latency search requirements. Now let me continue designing other core features..."
✅ 最终检查清单
Final Checklist
面试前确认: Before interview, confirm:
- 我理解什么时候需要深入实现搜索 I understand when to implement search from scratch
- 我理解什么时候可以用 Elasticsearch 快速带过 I understand when to use Elasticsearch (quick pass)
- 我准备好了 Inverted Index 的实现方案 I’m ready with Inverted Index implementation
- 我准备好了 Elasticsearch 的快速方案 I’m ready with Elasticsearch quick solution
- 我知道如何根据题目判断使用哪种策略 I know how to judge which strategy to use based on the problem
- 我准备好了两种场景的话术模板 I’m ready with scripts for both scenarios
记住:灵活应对,根据题目和面试官的反馈调整策略! Remember: Be flexible, adjust strategy based on problem and interviewer feedback!