feat: add 50 backend interview questions and answers
Generated comprehensive interview preparation materials covering: - Distributed systems (transactions, locks, ID generation, consistency) - Database (indexing, sharding, replication, transactions) - Caching (Redis, cache problems, distributed lock) - Message queues (RocketMQ, Kafka) - Concurrency (ThreadLocal, ConcurrentHashMap, thread pools) - JVM (GC, memory, tuning) - System design (seckill, short URL, IM, feed, LBS) - Algorithms (B+ tree, LRU, Red-Black tree, Skip list, Timing wheel) - Network (TCP/IP, HTTP/HTTPS) - Security (encryption, SQL injection, XSS) - Performance tuning - Design patterns - Microservices (Spring Boot, Gateway, Service Mesh) - Container orchestration (Kubernetes, Docker) - CI/CD, observability Each file includes: - Detailed questions - Comprehensive answers - Code examples - Real project experience - Alibaba P7 level requirements 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>
This commit is contained in:
439
questions/cap-theorem.md
Normal file
439
questions/cap-theorem.md
Normal file
@@ -0,0 +1,439 @@
|
||||
# CAP 理论和 BASE 理论
|
||||
|
||||
## 问题
|
||||
|
||||
1. 什么是 CAP 理论?CAP 三者为什么不可兼得?
|
||||
2. 什么是 BASE 理论?
|
||||
3. CP、AP、AP 架构分别适用于什么场景?
|
||||
4. Zookeeper、Eureka、Nacos、Consul 分别是 CP 还是 AP?
|
||||
5. 在实际项目中如何权衡一致性、可用性、分区容错性?
|
||||
|
||||
---
|
||||
|
||||
## 标准答案
|
||||
|
||||
### 1. CAP 理论
|
||||
|
||||
#### **定义**
|
||||
|
||||
CAP 是指分布式系统中的三个核心指标:
|
||||
|
||||
| 指标 | 说明 | 示例 |
|
||||
|------|------|------|
|
||||
| **Consistency(一致性)** | 所有节点在同一时间看到相同的数据 | 写入后,所有节点立即读取到新数据 |
|
||||
| **Availability(可用性)** | 系统持续提供服务,每个请求都能得到响应 | 即使部分节点故障,系统仍能响应 |
|
||||
| **Partition Tolerance(分区容错性)** | 系统在网络分区时仍能继续运行 | 节点间网络断开,系统仍能工作 |
|
||||
|
||||
---
|
||||
|
||||
#### **CAP 定理**
|
||||
|
||||
**一个分布式系统最多只能同时满足两项**:
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ CAP 三选二 │
|
||||
│ │
|
||||
│ CA ────┐ │
|
||||
│ │ │
|
||||
│ ╱ │ ╲ │
|
||||
│ ╱ │ ╲ │
|
||||
│ ╱ │ ╲ │
|
||||
│ ●────────●──────● │
|
||||
│ C P A │
|
||||
│ │
|
||||
│ CP AP CA │
|
||||
└─────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**为什么?**(证明)
|
||||
```
|
||||
场景:两个节点 N1、N2,网络分区(P)
|
||||
|
||||
情况 1:保证 C(一致性)
|
||||
├─ N1 写入数据
|
||||
└─ 为了保证一致性,N2 必须拒绝读取(牺牲 A)
|
||||
|
||||
情况 2:保证 A(可用性)
|
||||
├─ N1 写入数据
|
||||
└─ 为了保证可用性,N2 返回旧数据(牺牲 C)
|
||||
|
||||
结论:在有分区(P)的情况下,C 和 A 无法同时满足
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### **CP、AP、CA 架构**
|
||||
|
||||
**1. CP(一致性 + 分区容错)**
|
||||
|
||||
**特点**:
|
||||
- 保证数据一致性
|
||||
- 分区时部分节点不可用
|
||||
|
||||
**适用场景**:
|
||||
- 金融系统(转账、支付)
|
||||
- 库存系统(超卖不可接受)
|
||||
|
||||
**代表系统**:
|
||||
- Zookeeper(CP)
|
||||
- HBase(CP)
|
||||
- Redis Cluster(CP,主从切换时短暂不可用)
|
||||
|
||||
**示例**:
|
||||
```java
|
||||
// Zookeeper 写入流程
|
||||
client.setData("/node", data);
|
||||
// 等待大多数节点确认
|
||||
// 如果网络分区,部分节点无法写入
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**2. AP(可用性 + 分区容错)**
|
||||
|
||||
**特点**:
|
||||
- 保证系统可用
|
||||
- 分区时可能读到脏数据
|
||||
|
||||
**适用场景**:
|
||||
- 社交媒体(点赞、评论)
|
||||
- 内容分发(CDN)
|
||||
- 用户行为统计
|
||||
|
||||
**代表系统**:
|
||||
- Cassandra(AP)
|
||||
- DynamoDB(AP)
|
||||
- Eureka(AP)
|
||||
- DNS(AP)
|
||||
|
||||
**示例**:
|
||||
```java
|
||||
// Cassandra 写入
|
||||
session.execute("INSERT INTO users (id, name) VALUES (1, 'Alice')");
|
||||
// 写入成功立即返回
|
||||
// 数据可能尚未复制到其他节点(最终一致性)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**3. CA(一致性 + 可用性)**
|
||||
|
||||
**注意**:**在分布式系统中,CA 不存在**(因为网络分区不可避免)。
|
||||
|
||||
**CA 存在于**:
|
||||
- 单机系统(RDBMS)
|
||||
- 传统关系型数据库(MySQL、PostgreSQL)
|
||||
|
||||
---
|
||||
|
||||
### 2. BASE 理论
|
||||
|
||||
#### **定义**
|
||||
|
||||
BASE 是对 CAP 中 AP 方案的补充,通过**牺牲强一致性**来获得**高可用性**。
|
||||
|
||||
| 指标 | 说明 | 示例 |
|
||||
|------|------|------|
|
||||
| **Basically Available(基本可用)** | 系统出现故障时,允许损失部分可用性 | 秒杀时拒绝部分请求 |
|
||||
| **Soft state(软状态)** | 允许数据存在中间状态 | 订单状态:待支付 → 已支付 |
|
||||
| **Eventually consistent(最终一致性)** | 数据最终会达到一致状态 | 支付后 1 秒内到账 |
|
||||
|
||||
---
|
||||
|
||||
#### **BASE vs ACID**
|
||||
|
||||
| 特性 | ACID(传统数据库) | BASE(NoSQL) |
|
||||
|------|-------------------|---------------|
|
||||
| **一致性** | 强一致性(立即) | 最终一致性(延迟) |
|
||||
| **可用性** | 可能(锁、事务) | 高(无锁、异步) |
|
||||
| **隔离性** | 严格(锁) | 松散 |
|
||||
| **持久性** | 强 | 弱(可能丢失) |
|
||||
|
||||
---
|
||||
|
||||
#### **最终一致性的实现**
|
||||
|
||||
**1. 读时修复(Read Repair)**:
|
||||
```java
|
||||
// 读取时检查一致性
|
||||
public User getUser(Long userId) {
|
||||
// 从多个节点读取
|
||||
User user1 = node1.get(userId);
|
||||
User user2 = node2.get(userId);
|
||||
|
||||
// 发现不一致,修复
|
||||
if (!user1.equals(user2)) {
|
||||
// 使用版本号或时间戳决定哪个更新
|
||||
User latest = user1.getVersion() > user2.getVersion() ? user1 : user2;
|
||||
|
||||
// 异步修复旧数据
|
||||
asyncRepair(latest);
|
||||
|
||||
return latest;
|
||||
}
|
||||
|
||||
return user1;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**2. 写时修复(Write Repair)**:
|
||||
```java
|
||||
// 写入时同步到所有节点
|
||||
public void saveUser(User user) {
|
||||
// 写入主节点
|
||||
masterNode.save(user);
|
||||
|
||||
// 异步同步到从节点
|
||||
for (Node slave : slaves) {
|
||||
CompletableFuture.runAsync(() -> {
|
||||
slave.save(user);
|
||||
});
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**3. 异步复制**:
|
||||
```
|
||||
主节点收到写入
|
||||
↓
|
||||
立即返回成功
|
||||
↓
|
||||
异步复制到从节点
|
||||
↓
|
||||
最终一致
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. 主流注册中心对比
|
||||
|
||||
#### **Zookeeper(CP)**
|
||||
|
||||
**特点**:
|
||||
- 保证一致性(ZAB 协议)
|
||||
- Leader 挂了会重新选举(期间不可用)
|
||||
|
||||
**适用场景**:
|
||||
- 需要强一致性
|
||||
- 对可用性要求不高(如配置中心)
|
||||
|
||||
**示例**:
|
||||
```java
|
||||
// Zookeeper 注册
|
||||
zk.create("/services/order/192.168.1.10:8080", data, ZooDefs.Ids.OPEN, NodeMode.EPHEMERAL);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### **Eureka(AP)**
|
||||
|
||||
**特点**:
|
||||
- 保证可用性
|
||||
- 客户端缓存注册信息
|
||||
- 网络分区时仍能提供服务
|
||||
|
||||
**适用场景**:
|
||||
- 对可用性要求高
|
||||
- 可容忍短暂的服务发现不准确
|
||||
|
||||
**示例**:
|
||||
```java
|
||||
// Eureka 注册
|
||||
@Bean
|
||||
public EurekaInstanceBeanBean eurekaInstanceBean(InetAddress inetAddress) {
|
||||
EurekaInstanceBeanBean bean = new EurekaInstanceBeanBean();
|
||||
bean.setHostname(inetAddress.getHostAddress());
|
||||
bean.setAppName("order-service");
|
||||
bean.setNonSecurePort(8080);
|
||||
return bean;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### **Nacos(AP + CP)**
|
||||
|
||||
**特点**:
|
||||
- 支持 AP 和 CP 切换
|
||||
- 默认 AP(临时实例)
|
||||
- 可配置 CP(持久化实例)
|
||||
|
||||
**配置**:
|
||||
```yaml
|
||||
# Nacos 配置
|
||||
spring:
|
||||
cloud:
|
||||
nacos:
|
||||
discovery:
|
||||
server-addr: localhost:8848
|
||||
ephemeral: true # true=AP, false=CP
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### **Consul(CP)**
|
||||
|
||||
**特点**:
|
||||
- 保证一致性(Raft 协议)
|
||||
- 支持 KV 存储
|
||||
- 支持健康检查
|
||||
|
||||
**适用场景**:
|
||||
- 服务发现
|
||||
- 配置中心
|
||||
- 分布式锁
|
||||
|
||||
---
|
||||
|
||||
### 4. 实际项目应用
|
||||
|
||||
#### **场景 1:订单系统(CP)**
|
||||
|
||||
**需求**:
|
||||
- 不能超卖
|
||||
- 库存数据必须准确
|
||||
|
||||
**方案**:
|
||||
```
|
||||
1. 使用分布式锁(Redis、Zookeeper)
|
||||
2. 数据库使用强一致性事务
|
||||
3. 库存扣减使用串行化
|
||||
```
|
||||
|
||||
**代码**:
|
||||
```java
|
||||
@Transactional
|
||||
public void createOrder(Order order) {
|
||||
// 1. 获取分布式锁
|
||||
RLock lock = redissonClient.getLock("product:" + order.getProductId());
|
||||
lock.lock();
|
||||
|
||||
try {
|
||||
// 2. 查询库存
|
||||
Product product = productMapper.selectById(order.getProductId());
|
||||
if (product.getStock() < order.getQuantity()) {
|
||||
throw new BusinessException("库存不足");
|
||||
}
|
||||
|
||||
// 3. 扣减库存
|
||||
product.setStock(product.getStock() - order.getQuantity());
|
||||
productMapper.updateById(product);
|
||||
|
||||
// 4. 创建订单
|
||||
orderMapper.insert(order);
|
||||
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### **场景 2:社交点赞(AP)**
|
||||
|
||||
**需求**:
|
||||
- 高并发点赞
|
||||
- 允许点赞数短暂不准确
|
||||
|
||||
**方案**:
|
||||
```
|
||||
1. 先更新缓存(Redis)
|
||||
2. 异步同步到数据库
|
||||
3. 最终一致(1 秒内)
|
||||
```
|
||||
|
||||
**代码**:
|
||||
```java
|
||||
public void like(Long userId, Long postId) {
|
||||
// 1. 更新缓存(立即返回)
|
||||
redisTemplate.opsForSet().add("post:" + postId + ":likes", userId);
|
||||
|
||||
// 2. 异步更新数据库
|
||||
CompletableFuture.runAsync(() -> {
|
||||
likeMapper.insert(new Like(userId, postId));
|
||||
});
|
||||
}
|
||||
|
||||
public Long getLikeCount(Long postId) {
|
||||
// 1. 先查缓存
|
||||
Long count = redisTemplate.opsForSet().size("post:" + postId + ":likes");
|
||||
|
||||
// 2. 如果缓存不存在,查数据库
|
||||
if (count == null || count == 0) {
|
||||
count = likeMapper.countByPostId(postId);
|
||||
redisTemplate.opsForValue().set("post:" + postId + ":count", count, 1, TimeUnit.HOURS);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### **场景 3:库存同步(最终一致性)**
|
||||
|
||||
**需求**:
|
||||
- 多个仓库库存同步
|
||||
- 允许短暂不一致
|
||||
|
||||
**方案**:
|
||||
```
|
||||
1. 使用消息队列(RocketMQ)
|
||||
2. 事务消息保证不丢失
|
||||
3. 消费者重试保证最终一致
|
||||
```
|
||||
|
||||
**代码**:
|
||||
```java
|
||||
// 1. 发送事务消息
|
||||
@Transactional
|
||||
public void updateStock(Long productId, int quantity) {
|
||||
// 更新数据库
|
||||
productMapper.updateStock(productId, quantity);
|
||||
|
||||
// 发送事务消息
|
||||
Message msg = new Message("StockTopic", "StockUpdate",
|
||||
JSON.toJSONString(new StockUpdateEvent(productId, quantity)).getBytes());
|
||||
rocketMQTemplate.sendMessageInTransaction(msg, null);
|
||||
}
|
||||
|
||||
// 2. 消费消息
|
||||
@RocketMQMessageListener(topic = "StockTopic", consumerGroup = "stock-consumer")
|
||||
public class StockConsumer implements RocketMQListener<StockUpdateEvent> {
|
||||
@Override
|
||||
public void onMessage(StockUpdateEvent event) {
|
||||
// 同步到其他仓库
|
||||
warehouseService.syncStock(event.getProductId(), event.getQuantity());
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 5. 阿里 P7 加分项
|
||||
|
||||
**深度理解**:
|
||||
- 理解 CAP 理论的局限性(如网络延迟、时钟问题)
|
||||
- 理解各种一致性协议(Paxos、Raft、ZAB)
|
||||
- 理解分布式事务的权衡
|
||||
|
||||
**实战经验**:
|
||||
- 有设计 CP 或 AP 系统的经验
|
||||
- 有处理数据不一致问题的经验
|
||||
- 有最终一致性调优的经验
|
||||
|
||||
**架构能力**:
|
||||
- 能根据业务特点选择合适的架构
|
||||
- 能设计混合架构(部分 CP、部分 AP)
|
||||
- 能设计数据修复和补偿机制
|
||||
|
||||
**技术选型**:
|
||||
- 了解各种注册中心和存储系统的 CAP 特性
|
||||
- 能根据业务特点选择合适的技术
|
||||
- 有分布式系统设计经验
|
||||
Reference in New Issue
Block a user