feat: add comprehensive system design interview questions
- design-seckill.md: 秒杀系统设计 - design-shorturl.md: 短链接系统设计 - design-lbs.md: LBS附近的人系统设计 - design-im.md: 即时通讯系统设计 - design-feed.md: 社交信息流系统设计 Each document includes: - Requirements analysis and data volume assessment - Technical challenges - System architecture design - Database design - Caching strategies - Scalability considerations - Practical project experience - Alibaba P7 level additional points Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
359
questions/design-shorturl.md
Normal file
359
questions/design-shorturl.md
Normal file
@@ -0,0 +1,359 @@
|
||||
# 短链接系统设计
|
||||
|
||||
## 需求分析和数据量评估
|
||||
|
||||
### 需求分析
|
||||
- **核心功能**:长链接转短链接、短链接跳转、统计分析
|
||||
- **业务场景**:短信营销、社交媒体分享、广告推广
|
||||
- **QPS评估**:日点击量10亿次,峰值QPS 3万+
|
||||
- **数据规模**:短链接10亿+,日生成1000万+
|
||||
|
||||
### 数据量评估
|
||||
- **短链接表**:10亿条,日均写入1000万次
|
||||
- **原始链接表**:10亿条,日均读取10亿次
|
||||
- **访问统计表**:100亿+条,日增1亿+
|
||||
- **用户表**:1000万+,日均查询100万次
|
||||
|
||||
## 核心技术难点
|
||||
|
||||
### 1. 高并发写入
|
||||
- 短链接生成需要高性能
|
||||
- 避免数据库写入瓶颈
|
||||
- 分布式ID生成
|
||||
|
||||
### 2. 高性能读取
|
||||
- 毫秒级响应时间
|
||||
- 缓存命中率优化
|
||||
- 全球CDN加速
|
||||
|
||||
### 3. 长链接查重
|
||||
- 重复链接检测
|
||||
- 去重策略设计
|
||||
- 一致性保证
|
||||
|
||||
### 4. 统计准确性
|
||||
- 实时统计延迟
|
||||
- 统计数据准确性
|
||||
- 分布式计数器
|
||||
|
||||
## 系统架构设计
|
||||
|
||||
### 总体架构
|
||||
```
|
||||
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
||||
│ CDN/Edge │ │ Load Balance │ │ API Gateway │
|
||||
│ Cache │◄──►│ (Anycast) │◄──►│ (Gateway) │
|
||||
└─────────────────┘ └─────────────────┘ └─────────────────┘
|
||||
│
|
||||
┌───────────────────────────────────┼───────────────────────────────────┐
|
||||
│ │ │
|
||||
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
||||
│ 短链接服务 │ │ 统计服务 │ │ 监控服务 │
|
||||
│ (微服务) │ │ (微服务) │ │ (微服务) │
|
||||
└─────────────────┘ └─────────────────┘ └─────────────────┘
|
||||
│ │ │
|
||||
└───────────────────────────────────┼───────────────────────────────────┘
|
||||
│
|
||||
┌───────────────────────────────────┼───────────────────────────────────┐
|
||||
│ │ │
|
||||
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
||||
│ Redis集群 │ │ 消息队列 │ │ 数据库集群 │
|
||||
│ (缓存+计数器)│ │ (Kafka) │ │ (MySQL分库分表)│
|
||||
└─────────────────┘ └─────────────────┘ └─────────────────┘
|
||||
│
|
||||
┌───────────────────────────────────┼───────────────────────────────────┐
|
||||
│ │ │
|
||||
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
||||
│ 时序数据库 │ │ 数据仓库 │ │ 搜索引擎 │
|
||||
│ (InfluxDB) │ │ (ClickHouse) │ │ (Elasticsearch)│
|
||||
└─────────────────┘ └─────────────────┘ └─────────────────┘
|
||||
```
|
||||
|
||||
### 关键组件
|
||||
|
||||
#### 1. 流量层
|
||||
- **CDN/Edge**:全球加速,缓存热点短链接
|
||||
- **负载均衡**:Anycast IP,就近接入
|
||||
- **API网关**:限流、路由、认证
|
||||
|
||||
#### 2. 服务层
|
||||
- **短链接服务**:核心业务逻辑
|
||||
- **统计服务**:访问统计和报表
|
||||
- **管理服务**:后台管理系统
|
||||
- **监控服务**:实时监控告警
|
||||
|
||||
#### 3. 存储层
|
||||
- **Redis集群**:缓存和计数器
|
||||
- **MySQL集群**:主从复制,分库分表
|
||||
- **时序数据库**:时序数据存储
|
||||
- **搜索引擎**:链接检索和分析
|
||||
|
||||
#### 4. 分析层
|
||||
- **数据仓库**:离线数据分析
|
||||
- **OLAP引擎**:实时查询分析
|
||||
- **报表系统**:业务报表展示
|
||||
|
||||
## 数据库设计
|
||||
|
||||
### 短链接表
|
||||
```sql
|
||||
CREATE TABLE `short_url` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`short_code` varchar(10) NOT NULL COMMENT '短链接编码',
|
||||
`long_url` text NOT NULL COMMENT '原始长链接',
|
||||
`domain` varchar(255) NOT NULL COMMENT '自定义域名',
|
||||
`title` varchar(255) DEFAULT NULL COMMENT '页面标题',
|
||||
`description` text COMMENT '页面描述',
|
||||
`keywords` varchar(500) DEFAULT NULL COMMENT '关键词',
|
||||
`user_id` bigint DEFAULT NULL COMMENT '用户ID',
|
||||
`is_custom` tinyint NOT NULL DEFAULT 0 COMMENT '是否自定义',
|
||||
`status` tinyint NOT NULL DEFAULT 1 COMMENT '状态',
|
||||
`expire_at` datetime DEFAULT NULL COMMENT '过期时间',
|
||||
`click_count` int NOT NULL DEFAULT 0 COMMENT '点击次数',
|
||||
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_short_code` (`short_code`),
|
||||
KEY `idx_long_url` (`long_url`(255)),
|
||||
KEY `idx_user_id` (`user_id`),
|
||||
KEY `idx_expire_at` (`expire_at`),
|
||||
KEY `idx_domain` (`domain`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
```
|
||||
|
||||
### 访问记录表
|
||||
```sql
|
||||
CREATE TABLE `url_access_log` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`short_code` varchar(10) NOT NULL COMMENT '短链接编码',
|
||||
`ip` varchar(45) NOT NULL COMMENT '访问IP',
|
||||
`user_agent` text COMMENT '用户代理',
|
||||
`referer` text COMMENT '来源页面',
|
||||
`country` varchar(50) DEFAULT NULL COMMENT '国家',
|
||||
`region` varchar(50) DEFAULT NULL COMMENT '地区',
|
||||
`city` varchar(50) DEFAULT NULL COMMENT '城市',
|
||||
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_short_code` (`short_code`),
|
||||
KEY `idx_created_at` (`created_at`),
|
||||
KEY `idx_ip` (`ip`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
```
|
||||
|
||||
### 统计表
|
||||
```sql
|
||||
CREATE TABLE `url_stats` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`short_code` varchar(10) NOT NULL COMMENT '短链接编码',
|
||||
`date` date NOT NULL COMMENT '统计日期',
|
||||
`total_clicks` int NOT NULL DEFAULT 0 COMMENT '总点击次数',
|
||||
`unique_clicks` int NOT NULL DEFAULT 0 COMMENT '独立点击次数',
|
||||
`by_country` json DEFAULT NULL COMMENT '国家分布',
|
||||
`by_region` json DEFAULT NULL COMMENT '地区分布',
|
||||
`by_device` json DEFAULT NULL COMMENT '设备分布',
|
||||
`by_browser` json DEFAULT NULL COMMENT '浏览器分布',
|
||||
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_date_code` (`date`, `short_code`),
|
||||
KEY `idx_short_code` (`short_code`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
```
|
||||
|
||||
### 用户表
|
||||
```sql
|
||||
CREATE TABLE `short_url_user` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`user_id` bigint NOT NULL COMMENT '用户ID',
|
||||
`username` varchar(50) NOT NULL COMMENT '用户名',
|
||||
`email` varchar(100) NOT NULL COMMENT '邮箱',
|
||||
`domain` varchar(255) DEFAULT NULL COMMENT '自定义域名',
|
||||
`api_key` varchar(64) DEFAULT NULL COMMENT 'API密钥',
|
||||
`quota` int NOT NULL DEFAULT 1000 COMMENT '配额',
|
||||
`used` int NOT NULL DEFAULT 0 COMMENT '已使用',
|
||||
`status` tinyint NOT NULL DEFAULT 1 COMMENT '状态',
|
||||
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_user_id` (`user_id`),
|
||||
UNIQUE KEY `uk_api_key` (`api_key`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
```
|
||||
|
||||
## 缓存策略
|
||||
|
||||
### Redis缓存设计
|
||||
```typescript
|
||||
// 短链接缓存
|
||||
const SHORT_URL_CACHE_PREFIX = 'short_url:';
|
||||
const SHORT_URL_CACHE_TTL = 86400; // 24小时
|
||||
|
||||
// 访问计数器
|
||||
const CLICK_COUNT_PREFIX = 'click:';
|
||||
const CLICK_COUNT_TTL = 60; // 1分钟
|
||||
|
||||
// 布隆过滤器
|
||||
const BLOOM_FILTER_PREFIX = 'bloom:';
|
||||
const BLOOM_FILTER_SIZE = 1000000000; // 10亿
|
||||
|
||||
// 限流计数器
|
||||
const RATE_LIMIT_PREFIX = 'rate_limit:';
|
||||
const RATE_LIMIT_TTL = 60; // 1分钟
|
||||
```
|
||||
|
||||
### 缓存策略
|
||||
1. **多级缓存**:
|
||||
- 本地缓存:Caffeine
|
||||
- 分布式缓存:Redis Cluster
|
||||
- CDN缓存:边缘节点
|
||||
|
||||
2. **缓存更新策略**:
|
||||
- Write Through:写入同时更新缓存
|
||||
- Write Back:异步更新缓存
|
||||
- Refresh Ahead:预加载热点数据
|
||||
|
||||
3. **缓存预热**:
|
||||
- 热门短链接预加载
|
||||
- 统计数据预计算
|
||||
- 静态资源预缓存
|
||||
|
||||
### 布隆过滤器实现
|
||||
```java
|
||||
public class BloomFilter {
|
||||
private final BitSet bitSet;
|
||||
private final int size;
|
||||
private final int[] hashSeeds;
|
||||
|
||||
public BloomFilter(int size, int hashCount) {
|
||||
this.size = size;
|
||||
this.bitSet = new BitSet(size);
|
||||
this.hashSeeds = new int[hashCount];
|
||||
Random random = new Random();
|
||||
for (int i = 0; i < hashCount; i++) {
|
||||
hashSeeds[i] = random.nextInt();
|
||||
}
|
||||
}
|
||||
|
||||
public void add(String key) {
|
||||
for (int seed : hashSeeds) {
|
||||
int hash = Math.abs((key.hashCode() ^ seed) % size);
|
||||
bitSet.set(hash, true);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean mightContain(String key) {
|
||||
for (int seed : hashSeeds) {
|
||||
int hash = Math.abs((key.hashCode() ^ seed) % size);
|
||||
if (!bitSet.get(hash)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 扩展性考虑
|
||||
|
||||
### 1. 水平扩展
|
||||
- **无状态服务**:短链接服务无状态化
|
||||
- **数据分片**:按短链接编码分片
|
||||
- **读写分离**:主库写入,从库读取
|
||||
|
||||
### 2. 垂直扩展
|
||||
- **服务拆分**:API服务、统计服务、管理服务
|
||||
- **数据分层**:热数据、温数据、冷数据
|
||||
- **多级缓存**:本地、Redis、CDN
|
||||
|
||||
### 3. 全球化部署
|
||||
- **CDN加速**:全球节点部署
|
||||
- **地域化存储**:按地域分片
|
||||
- **灾备切换**:多机房容灾
|
||||
|
||||
### 4. 监控告警
|
||||
- **实时监控**:QPS、响应时间、错误率
|
||||
- **业务监控**:点击量、转化率
|
||||
- **异常告警**:服务异常、数据异常
|
||||
|
||||
## 实际项目经验
|
||||
|
||||
### 1. 技术栈选择
|
||||
- **前端**:React + TypeScript
|
||||
- **后端**:Spring Boot + Node.js
|
||||
- **数据库**:MySQL + Redis
|
||||
- **缓存**:Redis Cluster
|
||||
- **消息队列**:Kafka
|
||||
- **监控**:Prometheus + Grafana
|
||||
|
||||
### 2. 性能优化
|
||||
- **短链接生成**:Snowflake算法
|
||||
- **缓存优化**:多级缓存策略
|
||||
- **数据库优化**:分库分表、索引优化
|
||||
- **网络优化**:HTTP/2、Keep-Alive
|
||||
|
||||
### 3. 运维部署
|
||||
- **容器化**:Docker + Kubernetes
|
||||
- **CI/CD**:Jenkins + GitLab
|
||||
- **监控告警**:ELK Stack + AlertManager
|
||||
- **压测**:JMeter + Locust
|
||||
|
||||
### 4. 安全设计
|
||||
- **HTTPS**:全链路加密
|
||||
- **API限流**:防刷、防攻击
|
||||
- **数据脱敏**:敏感信息加密
|
||||
- **访问控制**:API密钥认证
|
||||
|
||||
## 阿里P7加分项
|
||||
|
||||
### 1. 架构设计能力
|
||||
- **高可用架构**:99.99%可用性
|
||||
- **高性能架构**:支持亿级QPS
|
||||
- **全球化架构**:全球CDN加速
|
||||
|
||||
### 2. 技术深度
|
||||
- **分布式算法**:一致性哈希、布隆过滤器
|
||||
- **缓存优化**:多级缓存策略
|
||||
- **数据库优化**:分库分表、读写分离
|
||||
|
||||
### 3. 业务理解
|
||||
- **营销业务**:理解短链接在营销中的应用
|
||||
- **用户行为**:分析点击行为模式
|
||||
- **数据统计**:实时统计和离线分析
|
||||
|
||||
### 4. 团队管理
|
||||
- **技术团队**:带领15人+团队
|
||||
- **项目管控**:管理亿级用户项目
|
||||
- **技术方案**:主导技术架构设计
|
||||
|
||||
### 5. 前沿技术
|
||||
- **Serverless**:短链接函数化
|
||||
- **边缘计算**:边缘节点处理
|
||||
- **AI应用**:智能推荐、异常检测
|
||||
|
||||
## 面试常见问题
|
||||
|
||||
### 1. 短链接如何生成?
|
||||
- **随机字符**:生成随机字符串
|
||||
- **自增序列**:数据库自增ID
|
||||
- **哈希算法**:MD5/SHA1取前几位
|
||||
- **Base62编码**:数字转62进制
|
||||
|
||||
### 2. 如何避免短链接冲突?
|
||||
- **布隆过滤器**:快速检测重复
|
||||
- **数据库唯一索引**:保证唯一性
|
||||
- **重试机制**:冲突时重新生成
|
||||
|
||||
### 3. 如何实现高并发生成?
|
||||
- **预生成**:批量生成短链接
|
||||
- **分布式ID**:Snowflake算法
|
||||
- **内存缓存**:减少数据库访问
|
||||
|
||||
### 4. 如何统计点击数据?
|
||||
- **实时统计**:Redis计数器
|
||||
- **异步处理**:消息队列存储
|
||||
- **离线分析**:数据仓库计算
|
||||
|
||||
### 5. 如何保证短链接安全?
|
||||
- **链接过滤**:过滤恶意链接
|
||||
- **访问控制**:黑白名单
|
||||
- **HTTPS加密**:防止劫持
|
||||
- **IP限制**:防刷机制
|
||||
Reference in New Issue
Block a user