Files
interview/questions/07-系统设计/LBS附近的人设计.md
yasinshaw 0e46a367c4 refactor: rename files to Chinese and organize by category
Organized 50 interview questions into 12 categories:
- 01-分布式系统 (9 files): 分布式事务, 分布式锁, 一致性哈希, CAP理论, etc.
- 02-数据库 (2 files): MySQL索引优化, MyBatis核心原理
- 03-缓存 (5 files): Redis数据结构, 缓存问题, LRU算法, etc.
- 04-消息队列 (1 file): RocketMQ/Kafka
- 05-并发编程 (4 files): 线程池, 设计模式, 限流策略, etc.
- 06-JVM (1 file): JVM和垃圾回收
- 07-系统设计 (8 files): 秒杀系统, 短链接, IM, Feed流, etc.
- 08-算法与数据结构 (4 files): B+树, 红黑树, 跳表, 时间轮
- 09-网络与安全 (3 files): TCP/IP, 加密安全, 性能优化
- 10-中间件 (4 files): Spring Boot, Nacos, Dubbo, Nginx
- 11-运维 (4 files): Kubernetes, CI/CD, Docker, 可观测性
- 12-面试技巧 (1 file): 面试技巧和职业规划

All files renamed to Chinese for better accessibility and
organized into categorized folders for easier navigation.

Generated with [Claude Code](https://claude.com/claude-code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-03-01 00:10:53 +08:00

379 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# LBS 附近的人系统设计
## 需求分析和数据量评估
### 需求分析
- **核心功能**:位置搜索、附近的人、距离计算、实时更新
- **业务场景**:社交软件、外卖服务、打车应用
- **QPS评估**日查询10亿次峰值QPS 5万+
- **数据规模**用户1亿+日均位置更新1000万+
### 数据量评估
- **用户位置表**1亿条实时更新频率高
- **位置历史表**100亿+条,存储轨迹信息
- **地理索引表**:全球空间索引,数据量大
- **社交关系表**10亿+条,好友关系数据
## 核心技术难点
### 1. 海量数据处理
- 亿级用户位置数据存储
- 实时数据写入性能要求
- 空间索引构建和维护
### 2. 实时性要求
- 位置信息实时更新
- 查询响应毫秒级
- 数据一致性问题
### 3. 距离计算优化
- 快速计算两点间距离
- 批量距离计算优化
- 空间索引查询优化
### 4. 隐私保护
- 用户位置隐私
- 数据脱敏处理
- 访问权限控制
## 系统架构设计
### 总体架构
```
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ 移动端APP │ │ Web管理后台 │ │ 第三方API │
│ (iOS/Android)│ │ (PC) │ │ (SDK) │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │ │
└───────────────────────┼───────────────────────┘
┌─────────────────────┼───────────────────────┐
│ │ │
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ API网关 │ │ 负载均衡 │ │ CDN加速 │
│ (Gateway) │ │ (Nginx) │ │ (Edge) │
└─────────────────┘ └─────────────────┘ └─────────────────┘
┌─────────────────────┼───────────────────────┐
│ │ │
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ 位置服务 │ │ 搜索服务 │ │ 计算服务 │
│ (微服务) │ │ (微服务) │ │ (微服务) │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │ │
└─────────────────────┼───────────────────────┘
┌─────────────────────┼───────────────────────┐
│ │ │
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Redis集群 │ │ 数据库集群 │ │ 消息队列 │
│ (缓存+pub/sub)│ │ (PostGIS) │ │ (Kafka/RabbitMQ)│
└─────────────────┘ └─────────────────┘ └─────────────────┘
┌─────────────────────┼───────────────────────┐
│ │ │
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ 地理计算 │ │ 数据仓库 │ │ 地图渲染 │
│ (Geospatial) │ │ (ClickHouse) │ │ (Mapbox) │
└─────────────────┘ └─────────────────┘ └─────────────────┘
```
### 关键组件
#### 1. 流量层
- **API网关**:请求路由、限流、认证
- **负载均衡**Nginx L7负载均衡
- **CDN加速**:静态资源缓存
#### 2. 服务层
- **位置服务**:位置更新、订阅管理
- **搜索服务**:附近的人查询
- **计算服务**:距离计算、路线规划
- **社交服务**:好友关系管理
#### 3. 存储层
- **Redis集群**:位置缓存、订阅频道
- **PostgreSQL**:空间数据存储
- **ClickHouse**:地理位置分析
- **MongoDB**:轨迹数据存储
#### 4. 分析层
- **数据仓库**:离线数据分析
- **实时计算**Flink/Kafka Streams
- **地图服务**:地图渲染和展示
## 数据库设计
### 用户位置表
```sql
CREATE TABLE `user_location` (
`id` bigint NOT NULL AUTO_INCREMENT,
`user_id` bigint NOT NULL COMMENT '用户ID',
`latitude` decimal(10,8) NOT NULL COMMENT '纬度',
`longitude` decimal(11,8) NOT NULL COMMENT '经度',
`accuracy` decimal(10,2) DEFAULT NULL COMMENT '定位精度(米)',
`device_type` varchar(20) DEFAULT NULL COMMENT '设备类型',
`app_version` varchar(50) DEFAULT NULL COMMENT '应用版本',
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`expire_at` timestamp NOT NULL COMMENT '过期时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_user_id` (`user_id`),
KEY `idx_location` (`latitude`, `longitude`),
KEY `idx_expire_at` (`expire_at`),
SPATIAL KEY `idx_spatial` (`latitude`, `longitude`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
```
### 位置历史表
```sql
CREATE TABLE `location_history` (
`id` bigint NOT NULL AUTO_INCREMENT,
`user_id` bigint NOT NULL COMMENT '用户ID',
`latitude` decimal(10,8) NOT NULL COMMENT '纬度',
`longitude` decimal(11,8) NOT NULL COMMENT '经度',
`accuracy` decimal(10,2) DEFAULT NULL COMMENT '定位精度(米)',
`timestamp` datetime NOT NULL COMMENT '时间戳',
`device_type` varchar(20) DEFAULT NULL COMMENT '设备类型',
PRIMARY KEY (`id`),
KEY `idx_user_timestamp` (`user_id`, `timestamp`),
KEY `idx_location` (`latitude`, `longitude`),
SPATIAL KEY `idx_spatial` (`latitude`, `longitude`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
```
### 地理索引表
```sql
CREATE TABLE `geo_index` (
`id` bigint NOT NULL AUTO_INCREMENT,
`grid_id` varchar(20) NOT NULL COMMENT '网格ID',
`min_lat` decimal(10,8) NOT NULL COMMENT '最小纬度',
`max_lat` decimal(10,8) NOT NULL COMMENT '最大纬度',
`min_lng` decimal(11,8) NOT NULL COMMENT '最小经度',
`max_lng` decimal(11,8) NOT NULL COMMENT '最大经度',
`user_count` int NOT NULL DEFAULT 0 COMMENT '用户数量',
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_grid_id` (`grid_id`),
KEY `idx_bounds` (`min_lat`, `max_lat`, `min_lng`, `max_lng`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
```
### 好友关系表
```sql
CREATE TABLE `user_friends` (
`id` bigint NOT NULL AUTO_INCREMENT,
`user_id` bigint NOT NULL COMMENT '用户ID',
`friend_id` bigint NOT NULL COMMENT '好友ID',
`distance` decimal(10,2) DEFAULT NULL COMMENT '距离(公里)',
`status` tinyint NOT NULL DEFAULT 1 COMMENT '状态',
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_user_friend` (`user_id`, `friend_id`),
KEY `idx_user_id` (`user_id`),
KEY `idx_friend_id` (`friend_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
```
## 缓存策略
### Redis缓存设计
```typescript
// 用户位置缓存
const USER_LOCATION_PREFIX = 'location:';
const USER_LOCATION_TTL = 60; // 1分钟
// 地理网格缓存
const GRID_PREFIX = 'grid:';
const GRID_TTL = 300; // 5分钟
// 用户订阅缓存
const SUBSCRIPTION_PREFIX = 'subscription:';
const SUBSCRIPTION_TTL = 3600; // 1小时
// 距离计算缓存
const DISTANCE_PREFIX = 'distance:';
const DISTANCE_TTL = 60; // 1分钟
```
### 缓存策略
1. **多级缓存**
- 本地缓存Caffeine
- 分布式缓存Redis Cluster
- CDN缓存静态资源
2. **缓存更新策略**
- Write Behind异步更新
- Refresh Ahead预加载热点数据
- Cache Invalidation定时失效
3. **空间索引缓存**
- 网格索引预加载
- 热点区域缓存
- 分层缓存策略
### GeoHash实现
```python
import math
def geohash_encode(latitude, longitude, precision=12):
# 地球半径(米)
earth_radius = 6371000
# GeoHash字符集
chars = "0123456789bcdefghjkmnpqrstuvwxyz"
# 计算精度对应的网格大小
grid_size = 5e6 / (2 ** (precision / 2))
# 计算经纬度范围
lat_min = -90
lat_max = 90
lng_min = -180
lng_max = 180
geo_hash = []
for i in range(precision):
# 纬度二进制
mid_lat = (lat_min + lat_max) / 2
if latitude >= mid_lat:
lat_min = mid_lat
lat_bit = 1
else:
lat_max = mid_lat
lat_bit = 0
# 经度二进制
mid_lng = (lng_min + lng_max) / 2
if longitude >= mid_lng:
lng_min = mid_lng
lng_bit = 1
else:
lng_max = mid_lng
lng_bit = 0
# 组合成字符索引
index = lat_bit * 2 + lng_bit
geo_hash.append(chars[index])
return ''.join(geo_hash)
def calculate_distance(lat1, lng1, lat2, lng2):
# Haversine公式计算距离
R = 6371000 # 地球半径(米)
dLat = math.radians(lat2 - lat1)
dLng = math.radians(lng2 - lng1)
a = (math.sin(dLat/2) * math.sin(dLat/2) +
math.cos(math.radians(lat1)) * math.cos(math.radians(lat2)) *
math.sin(dLng/2) * math.sin(dLng/2))
c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a))
distance = R * c
return distance
```
## 扩展性考虑
### 1. 水平扩展
- **无状态服务**:位置服务和搜索服务无状态化
- **数据分片**按用户ID分片
- **读写分离**:主库写入,从库读取
### 2. 垂直扩展
- **服务拆分**:位置更新服务、查询服务、计算服务
- **数据分层**:热数据、温数据、冷数据
- **多级缓存**本地、Redis、CDN
### 3. 全球化部署
- **地域化服务**:按地域部署服务
- **数据同步**:跨地域数据同步
- **灾备切换**:多机房容灾
### 4. 性能优化
- **空间索引**R-Tree、Quadtree
- **批量处理**:批量查询优化
- **异步处理**:消息队列异步化
## 实际项目经验
### 1. 技术栈选择
- **前端**React Native + Flutter
- **后端**Spring Boot + Node.js
- **数据库**PostgreSQL + Redis
- **缓存**Redis Cluster
- **消息队列**Kafka
- **监控**Prometheus + Grafana
### 2. 性能优化
- **空间索引优化**GeoHash、R-Tree
- **缓存优化**:多级缓存策略
- **数据库优化**:分库分表、索引优化
- **网络优化**HTTP/2、Keep-Alive
### 3. 运维部署
- **容器化**Docker + Kubernetes
- **CI/CD**Jenkins + GitLab
- **监控告警**ELK Stack + AlertManager
- **压测**JMeter + Locust
### 4. 安全设计
- **位置隐私**:数据脱敏、权限控制
- **数据加密**:传输加密、存储加密
- **访问控制**API鉴权、黑白名单
## 阿里P7加分项
### 1. 架构设计能力
- **高可用架构**99.99%可用性
- **高性能架构**:支持亿级查询
- **全球化架构**:全球多机房部署
### 2. 技术深度
- **空间算法**GeoHash、R-Tree算法
- **分布式系统**:分布式缓存、分布式计算
- **数据库优化**PostGIS优化、空间索引
### 3. 业务理解
- **社交业务**:理解社交应用场景
- **位置服务**掌握LBS业务模式
- **用户行为**:分析用户移动模式
### 4. 团队管理
- **技术团队**带领20人+团队
- **项目管控**:管理千万级用户项目
- **技术方案**:主导技术架构设计
### 5. 前沿技术
- **边缘计算**:边缘节点处理
- **AI应用**:轨迹预测、位置推荐
- **Serverless**:函数化服务
## 面试常见问题
### 1. 如何高效查询附近的人?
- **空间索引**GeoHash、R-Tree
- **网格划分**:地理网格索引
- **缓存策略**:多级缓存优化
### 2. 如何保证位置数据实时性?
- **推送机制**WebSocket实时推送
- **订阅模式**:用户订阅位置变化
- **数据过期**:定时清理过期数据
### 3. 如何处理海量位置数据?
- **分库分表**按用户ID分片
- **数据归档**:冷热数据分离
- **压缩存储**:轨迹数据压缩
### 4. 如何保护用户隐私?
- **数据脱敏**:位置信息模糊化
- **权限控制**:基于关系的访问控制
- **加密存储**:敏感信息加密
### 5. 如何优化距离计算?
- **近似计算**GeoHash过滤
- **批量计算**:向量运算优化
- **缓存机制**:距离结果缓存