Files
interview/questions/15-简历面试/场景设计题.md
yasinshaw 9c9610fc60 feat: 添加简历面试题
- 项目深挖题:5个重点项目STAR法则回答,针对每个项目准备深挖问题
- 场景设计题:秒杀系统、优惠券系统、数据一致性、限流降级等设计题
- 个人发展题:职业规划、学习能力、团队协作、抗压能力、价值观
- 离职原因与动机:离职原因、择公司、职业目标、反问技巧
- 薪资谈判:谈判策略、Web3特有问题(代币激励、远程工作)、DO & DON'T

针对简历特点:
- 结合字节跳动、阿里巴巴、ThoughtWorks的项目经验
- 提供STAR法则回答模板
- 强调Web2经验向Web3的转化
- 包含大量代码示例和架构图
- 提供薪资谈判实战策略

适用场景:
- 面试前准备:项目深挖、场景设计
- 面试中:个人发展、离职原因
- 面试后:薪资谈判、offer评估
2026-03-03 00:20:12 +08:00

26 KiB
Raw Blame History

场景设计题

说明

场景设计题是考察系统设计能力和问题解决能力的常见题型。本文档针对你的简历背景,设计相关的场景题。


1. 电商促销系统设计

题目

面试官问 "假设你要设计一个电商秒杀系统,支持百万用户同时抢购,你会如何设计?"


参考回答

【需求分析】

核心需求:
1. 高并发:百万用户同时抢购
2. 防超卖:库存不能卖超
3. 高可用:服务不能挂
4. 公平性:先到先得
5. 用户体验:快速响应

非功能需求:
- QPS: 100万+
- 延迟: <100ms
- 可用性: 99.99%
- 数据一致性: 强一致

【架构设计】

┌─────────────────────────────────────────────┐
│              客户端层                        │
│  移动App、Web、H5                           │
└──────────────┬──────────────────────────────┘
               │
               ↓
┌─────────────────────────────────────────────┐
│              CDN层                          │
│  - 静态资源图片、CSS、JS                │
│  - 动态接口(边缘计算)                      │
└──────────────┬──────────────────────────────┘
               │
               ↓
┌─────────────────────────────────────────────┐
│           API网关层                         │
│  - 限流100万QPS                           │
│  - 熔断:保护后端                            │
│  - 负载均衡                                  │
└──────────────┬──────────────────────────────┘
               │
      ┌────────┴────────┐
      ↓                 ↓
┌──────────┐      ┌──────────┐
│  缓存层   │      │  服务层   │
└──────────┘      └──────────┘
      │                 │
      ↓                 ↓
┌─────────────────────────────────┐
│         数据库层                │
│  MySQL主从 + 分库分表           │
└─────────────────────────────────┘

【详细设计】

1. 缓存层设计(关键)

/**
 * Redis预减库存核心
 */
@Service
public class SeckillService {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 预减库存(原子操作)
     */
    public boolean decrementStock(Long productId, Long userId) {
        String key = "stock:seckill:" + productId;

        // 原子减库存
        Long stock = redisTemplate.opsForValue().decrement(key);

        if (stock < 0) {
            // 库存不足,回滚
            redisTemplate.opsForValue().increment(key);
            return false;
        }

        // 记录用户抢购记录
        String userKey = "user:seckill:" + productId + ":" + userId;
        redisTemplate.opsForValue().set(userKey, "1", 24, TimeUnit.HOURS);

        return true;
    }

    /**
     * 异步下单(消息队列)
     */
    public void asyncOrder(Order order) {
        // 发送到消息队列
        rabbitTemplate.convertAndSend("order.queue", order);
    }
}

/**
 * 消息队列消费者
 */
@Component
public class OrderConsumer {

    @RabbitListener(queues = "order.queue")
    public void createOrder(Order order) {
        // 1. 校验库存(数据库)
        int stock = productMapper.getStock(order.getProductId());
        if (stock <= 0) {
            throw new InsufficientStockException();
        }

        // 2. 扣减库存(数据库)
        productMapper.decrementStock(order.getProductId());

        // 3. 创建订单
        orderMapper.insert(order);

        // 4. 返回成功
        log.info("订单创建成功: {}", order.getId());
    }
}

2. 限流设计

/**
 * 限流策略(多级)
 */
@Configuration
public class RateLimiterConfig {

    /**
     * 接口级限流(令牌桶)
     */
    @Bean
    public RateLimiter apiRateLimiter() {
        // 100万QPS
        return RateLimiter.create(1000000.0);
    }

    /**
     * 用户级限流(防刷)
     */
    public boolean checkUserRateLimit(Long userId) {
        String key = "rate_limit:user:" + userId;
        Long count = redisTemplate.opsForValue().increment(key);

        if (count == 1) {
            redisTemplate.expire(key, 1, TimeUnit.MINUTES);
        }

        // 每分钟最多10次
        return count <= 10;
    }
}

/**
 * 限流拦截器
 */
@Component
public class RateLimitInterceptor implements HandlerInterceptor {

    @Autowired
    private RateLimiter apiRateLimiter;

    @Override
    public boolean preHandle(HttpServletRequest request,
                           HttpServletResponse response,
                           Object handler) {
        // 接口级限流
        if (!apiRateLimiter.tryAcquire()) {
            response.setStatus(429);  // Too Many Requests
            return false;
        }

        // 用户级限流
        Long userId = getUserId(request);
        if (!checkUserRateLimit(userId)) {
            response.setStatus(429);
            return false;
        }

        return true;
    }
}

3. 防刷设计

/**
 * 防刷策略
 */
@Service
public class AntiSpamService {

    /**
     * 验证码(图形验证码 + 滑动验证)
     */
    public boolean verifyCaptcha(String token, String answer) {
        // 调用验证码服务
        return captchaService.verify(token, answer);
    }

    /**
     * 风控规则
     */
    public RiskLevel checkRisk(Long userId, SeckillRequest request) {
        RiskScore score = new RiskScore();

        // 1. IP风险检测
        String ip = getIp(request);
        if (ipRiskService.isHighRisk(ip)) {
            score.add(50);
        }

        // 2. 设备指纹检测
        String deviceId = getDeviceId(request);
        if (deviceRiskService.isEmulator(deviceId)) {
            score.add(80);  // 模拟器
        }

        // 3. 行为检测
        if (userBehaviorService.isAbnormal(userId)) {
            score.add(30);
        }

        // 4. 频率检测
        int requestCount = getRequestCount(userId, 1, TimeUnit.MINUTES);
        if (requestCount > 100) {
            score.add(40);
        }

        // 判定风险等级
        if (score.getScore() >= 80) {
            return RiskLevel.HIGH;  // 拒绝
        } else if (score.getScore() >= 50) {
            return RiskLevel.MEDIUM;  // 需要验证
        } else {
            return RiskLevel.LOW;  // 通过
        }
    }
}

4. 降级策略

/**
 * 降级策略
 */
@Component
public class DegradationService {

    /**
     * 降级开关(配置中心)
     */
    @Value("${seckill.degradation.enabled:false}")
    private boolean degradationEnabled;

    /**
     * 降级方案
     */
    public SeckillResult handleSeckill(SeckillRequest request) {
        if (degradationEnabled) {
            // 降级:返回静态页面
            return SeckillResult.degraded();
        }

        // 正常流程
        return seckillService.seckill(request);
    }

    /**
     * 自动降级(基于错误率)
     */
    @Scheduled(fixedRate = 1000)  // 每秒检查
    public void autoDegradation() {
        double errorRate = getErrorRate();

        if (errorRate > 0.5) {  // 错误率超过50%
            // 开启降级
            enableDegradation();

            // 发送告警
            alertService.send("错误率过高,已自动降级");
        }
    }
}

5. 库存回滚(重要)

/**
 * 库存回滚机制
 */
@Service
public class StockRollbackService {

    /**
     * 定时任务:回滚未支付的订单库存
     */
    @Scheduled(cron = "0 */5 * * * ?")  // 每5分钟
    public void rollbackUnpaidStock() {
        // 查询15分钟前未支付的订单
        List<Order> unpaidOrders = orderMapper.getUnpaidOrders(15);

        unpaidOrders.forEach(order -> {
            // 回滚库存Redis
            String key = "stock:seckill:" + order.getProductId();
            redisTemplate.opsForValue().increment(key);

            // 回滚库存(数据库)
            productMapper.incrementStock(order.getProductId());

            // 取消订单
            orderMapper.updateStatus(order.getId(), OrderStatus.CANCELLED);

            log.info("库存已回滚: orderId={}", order.getId());
        });
    }
}

【容量预估】

1. QPS预估
   - 用户数100万
   - 峰值QPS100万/秒
   - 考虑10倍冗余1000万QPS

2. 缓存容量
   - Redis实例10个
   - 每个实例10万QPS
   - 总计100万QPS

3. 消息队列
   - Kafka分区100个
   - 消费者200个
   - 吞吐量100万/秒

4. 数据库
   - 主库1个写入
   - 从库10个读取
   - 分库分表100个库1000个表

【压测方案】

/**
 * 压测方案
 */
@Test
public class LoadTest {

    /**
     * 压测脚本
     */
    @Test
    public void testSeckill() {
        // 1. 预热
        warmUp();

        // 2. 施加压力
        int threadCount = 10000;  // 1万个线程
        int requestsPerThread = 100;  // 每个线程100次请求

        ExecutorService executor = Executors.newFixedThreadPool(threadCount);

        CountDownLatch latch = new CountDownLatch(threadCount);

        long startTime = System.currentTimeMillis();

        for (int i = 0; i < threadCount; i++) {
            executor.submit(() -> {
                try {
                    for (int j = 0; j < requestsPerThread; j++) {
                        // 发起请求
                        seckillService.seckill(request);
                    }
                } finally {
                    latch.countDown();
                }
            });
        }

        latch.await();

        long endTime = System.currentTimeMillis();
        long duration = endTime - startTime;

        int totalRequests = threadCount * requestsPerThread;
        double qps = (double) totalRequests / (duration / 1000.0);

        System.out.println("QPS: " + qps);
        System.out.println("平均耗时: " + (duration / totalRequests) + "ms");
    }
}

【监控告警】

监控指标:
1. QPS
2. 响应时间P50、P95、P99
3. 错误率
4. 库存消耗速度
5. 订单创建速度

告警策略:
- QPS < 100万警告
- P99 > 500ms警告
- 错误率 > 1%:严重告警
- 库存耗尽:通知

2. 优惠券系统设计

题目

面试官问 "设计一个优惠券系统,支持满减、折扣、立减等多种类型,支持叠加使用,如何设计?"


参考回答

【需求分析】

功能需求:
1. 优惠券类型
   - 满减券满100减20
   - 折扣券打8折
   - 立减券立减10元
   - 兑换券(兑换商品)

2. 使用规则
   - 叠加使用(可以同时使用多张)
   - 互斥使用(不能同时使用)
   - 优先级(先使用优先级高的)

3. 限制条件
   - 品类限制(仅限某品类)
   - 商品限制(仅限某商品)
   - 用户限制(新用户专享)
   - 时间限制(有效期)

非功能需求:
- 性能:计算优惠 < 10ms
- 准确:不能算错
- 灵活:方便配置新规则

【数据模型设计】

-- 优惠券模板
CREATE TABLE coupon_template (
    id BIGINT PRIMARY KEY,
    name VARCHAR(128),  -- 名称
    type TINYINT,  -- 类型1满减 2折扣 3立减
    discount_value DECIMAL(10,2),  -- 优惠值
    min_amount DECIMAL(10,2),  -- 最低消费金额
    max_discount DECIMAL(10,2),  -- 最大优惠金额
    category_id BIGINT,  -- 适用品类
    product_id BIGINT,  -- 适用商品
    user_limit INT,  -- 每人限领数量
    total_count INT,  -- 总发行量
    issued_count INT DEFAULT 0,  -- 已发行量
    used_count INT DEFAULT 0,  -- 已使用量
    valid_days INT,  -- 有效天数
    status TINYINT,  -- 状态1草稿 2进行中 3已结束
    priority INT DEFAULT 0,  -- 优先级
    stackable TINYINT DEFAULT 0,  -- 是否可叠加
    create_time DATETIME,
    update_time DATETIME
);

-- 用户优惠券
CREATE TABLE user_coupon (
    id BIGINT PRIMARY KEY,
    user_id BIGINT,
    template_id BIGINT,
    status TINYINT,  -- 状态1未使用 2已使用 3已过期
    order_id BIGINT,  -- 关联订单
    receive_time DATETIME,
    use_time DATETIME,
    expire_time DATETIME,
    INDEX idx_user_id_status (user_id, status)
);

-- 优惠券使用记录
CREATE TABLE coupon_usage_log (
    id BIGINT PRIMARY KEY,
    user_id BIGINT,
    coupon_id BIGINT,
    order_id BIGINT,
    discount_amount DECIMAL(10,2),
    create_time DATETIME
);

【核心代码设计】

/**
 * 优惠计算引擎
 */
@Service
public class DiscountCalculator {

    /**
     * 计算最优优惠
     */
    public DiscountResult calculateBestDiscount(
        Long userId,
        List<CartItem> items,
        List<Long> availableCouponIds
    ) {
        // 1. 获取可用优惠券
        List<UserCoupon> availableCoupons = getAvailableCoupons(userId, availableCouponIds);

        if (availableCoupons.isEmpty()) {
            return DiscountResult.empty();
        }

        // 2. 计算订单金额
        BigDecimal originalAmount = calculateOriginalAmount(items);

        // 3. 尝试所有优惠券组合
        DiscountResult bestResult = null;
        BigDecimal maxDiscount = BigDecimal.ZERO;

        // 3.1 单张优惠券
        for (UserCoupon coupon : availableCoupons) {
            DiscountResult result = calculateDiscount(coupon, items);
            if (result.getDiscountAmount().compareTo(maxDiscount) > 0) {
                bestResult = result;
                maxDiscount = result.getDiscountAmount();
            }
        }

        // 3.2 多张优惠券组合(如果可叠加)
        List<UserCoupon> stackableCoupons = availableCoupons.stream()
            .filter(c -> c.getTemplate().isStackable())
            .collect(Collectors.toList());

        if (stackableCoupons.size() > 1) {
            // 递归计算所有组合
            List<DiscountResult> combinations = calculateCombinations(stackableCoupons, items);
            for (DiscountResult result : combinations) {
                if (result.getDiscountAmount().compareTo(maxDiscount) > 0) {
                    bestResult = result;
                    maxDiscount = result.getDiscountAmount();
                }
            }
        }

        return bestResult;
    }

    /**
     * 计算单张优惠券的优惠
     */
    private DiscountResult calculateDiscount(UserCoupon coupon, List<CartItem> items) {
        CouponTemplate template = coupon.getTemplate();
        BigDecimal originalAmount = calculateOriginalAmount(items);

        BigDecimal discountAmount = BigDecimal.ZERO;

        switch (template.getType()) {
            case 1:  // 满减券
                if (originalAmount.compareTo(template.getMinAmount()) >= 0) {
                    discountAmount = template.getDiscountValue();
                    // 不超过最大优惠
                    if (discountAmount.compareTo(template.getMaxDiscount()) > 0) {
                        discountAmount = template.getMaxDiscount();
                    }
                }
                break;

            case 2:  // 折扣券
                discountAmount = originalAmount.multiply(
                    BigDecimal.ONE.subtract(template.getDiscountValue().divide(BigDecimal.valueOf(100)))
                );
                break;

            case 3:  // 立减券
                discountAmount = template.getDiscountValue();
                break;
        }

        return DiscountResult.builder()
            .couponId(coupon.getId())
            .discountAmount(discountAmount)
            .finalAmount(originalAmount.subtract(discountAmount))
            .build();
    }

    /**
     * 获取可用优惠券
     */
    private List<UserCoupon> getAvailableCoupons(Long userId, List<Long> couponIds) {
        // 查询未使用且未过期的优惠券
        return userCouponMapper.selectByUserIdAndStatusAndIds(
            userId,
            UserCouponStatus.UNUSED.getValue(),
            couponIds
        );
    }

    /**
     * 计算原始金额
     */
    private BigDecimal calculateOriginalAmount(List<CartItem> items) {
        return items.stream()
            .map(item -> item.getPrice().multiply(BigDecimal.valueOf(item.getQuantity())))
            .reduce(BigDecimal.ZERO, BigDecimal::add);
    }
}

/**
 * 优惠券使用服务
 */
@Service
public class CouponUsageService {

    @Autowired
    private DiscountCalculator discountCalculator;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 使用优惠券(分布式锁保证幂等)
     */
    @Transactional
    public void useCoupon(Long userId, Long couponId, Long orderId) {
        String lockKey = "coupon:lock:" + couponId;

        // 分布式锁
        Boolean locked = redisTemplate.opsForValue().setIfAbsent(
            lockKey,
            "1",
            10,
            TimeUnit.SECONDS
        );

        if (!locked) {
            throw new BusinessException("系统繁忙,请稍后重试");
        }

        try {
            // 1. 查询优惠券
            UserCoupon coupon = userCouponMapper.selectById(couponId);

            // 2. 校验状态
            if (coupon.getStatus() != UserCouponStatus.UNUSED.getValue()) {
                throw new BusinessException("优惠券已使用或已过期");
            }

            // 3. 校验有效期
            if (coupon.getExpireTime().before(new Date())) {
                throw new BusinessException("优惠券已过期");
            }

            // 4. 更新状态
            userCouponMapper.updateStatus(couponId, UserCouponStatus.USED.getValue());

            // 5. 记录使用日志
            couponUsageLogMapper.insert(CouponUsageLog.builder()
                .userId(userId)
                .couponId(couponId)
                .orderId(orderId)
                .discountAmount(coupon.getTemplate().getDiscountValue())
                .build());

        } finally {
            // 释放锁
            redisTemplate.delete(lockKey);
        }
    }
}

3. 数据一致性设计

题目

面试官问 "在大促活动中如何保证Redis缓存和数据库的数据一致性"


参考回答

【问题分析】

不一致的场景:
1. 先更新数据库,后删除缓存
   - A更新数据库
   - B读取缓存旧数据
   - A删除缓存
   - B写入缓存旧数据
   → 不一致

2. 先删除缓存,后更新数据库
   - A删除缓存
   - B读取数据库旧数据
   - B写入缓存旧数据
   - A更新数据库
   → 不一致

3. 缓存过期
   - 缓存过期
   - A读取数据库旧数据
   - B更新数据库
   - A写入缓存旧数据
   → 不一致

【解决方案】

方案1延迟双删推荐

/**
 * 延迟双删
 */
@Service
public class DataUpdateService {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private ProductMapper productMapper;

    /**
     * 更新商品(延迟双删)
     */
    @Transactional
    public void updateProduct(Product product) {
        // 1. 删除缓存
        String cacheKey = "product:" + product.getId();
        redisTemplate.delete(cacheKey);

        // 2. 更新数据库
        productMapper.updateById(product);

        // 3. 延迟删除缓存(异步)
        asyncDeleteCache(cacheKey);
    }

    /**
     * 异步延迟删除缓存
     */
    @Async
    public void asyncDeleteCache(String cacheKey) {
        try {
            // 延迟1秒保证数据库主从同步完成
            Thread.sleep(1000);

            // 再次删除缓存
            redisTemplate.delete(cacheKey);

            log.info("延迟删除缓存成功: {}", cacheKey);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

方案2订阅Binlog最终一致

/**
 * Binlog监听器
 */
@Component
public class BinlogListener {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 监听数据库更新
     */
    @CanalEventListener(
        destination = "product",
        filter = ".*\\..*"
    )
    public void onUpdate(CanalEntry.Entry entry) {
        // 解析Binlog
        CanalEntry.RowChange rowChange = CanalEntry.RowChange.parseFrom(entry.getStoreValue());

        for (CanalEntry.RowData rowData : rowChange.getRowDatasList()) {
            // 获取主键ID
            Long id = rowData.getAfterColumnsList().stream()
                .filter(c -> c.getIsKey())
                .findFirst()
                .map(c -> Long.valueOf(c.getValue()))
                .orElse(null);

            if (id != null) {
                // 删除缓存
                String cacheKey = "product:" + id;
                redisTemplate.delete(cacheKey);

                log.info("Binlog监听删除缓存: {}", cacheKey);
            }
        }
    }
}

方案3分布式锁强一致

/**
 * 分布式锁保证一致性
 */
@Service
public class ConsistentService {

    @Autowired
    private RedissonClient redissonClient;

    /**
     * 更新数据(强一致)
     */
    public void updateData(String key, Object value) {
        String lockKey = "lock:data:" + key;
        RLock lock = redissonClient.getLock(lockKey);

        try {
            // 加锁
            lock.lock(10, TimeUnit.SECONDS);

            // 1. 删除缓存
            redisTemplate.delete(key);

            // 2. 更新数据库
            databaseMapper.update(key, value);

            // 3. 查询最新值
            Object newValue = databaseMapper.select(key);

            // 4. 写入缓存
            redisTemplate.opsForValue().set(key, newValue, 1, TimeUnit.HOURS);

        } finally {
            // 释放锁
            lock.unlock();
        }
    }
}

4. 限流降级设计

题目

面试官问 "在大促活动中,如何设计限流和降级策略?"


参考回答

【限流策略】

/**
 * 多级限流
 */
@Component
public class MultiLevelRateLimiter {

    /**
     * Level 1: 接口级限流(保护服务)
     */
    @Bean
    public RateLimiter interfaceRateLimiter() {
        // 令牌桶100万QPS
        return RateLimiter.create(1000000.0);
    }

    /**
     * Level 2: 用户级限流(防刷)
     */
    public boolean checkUserLimit(Long userId) {
        String key = "limit:user:" + userId;
        Long count = redisTemplate.opsForValue().increment(key);

        if (count == 1) {
            redisTemplate.expire(key, 1, TimeUnit.MINUTES);
        }

        // 每分钟10次
        return count <= 10;
    }

    /**
     * Level 3: IP级限流防DDoS
     */
    public boolean checkIPLimit(String ip) {
        String key = "limit:ip:" + ip;
        Long count = redisTemplate.opsForValue().increment(key);

        if (count == 1) {
            redisTemplate.expire(key, 1, TimeUnit.MINUTES);
        }

        // 每分钟100次
        return count <= 100;
    }
}

【降级策略】

/**
 * 降级策略
 */
@Service
public class DegradationService {

    /**
     * 自动降级(基于错误率)
     */
    @Scheduled(fixedRate = 5000)  // 每5秒检查
    public void autoDegradation() {
        // 1. 统计错误率
        double errorRate = getErrorRate();

        // 2. 判断是否需要降级
        if (errorRate > 0.5) {  // 错误率超过50%
            enableDegradation();
            sendAlert("错误率过高,已自动降级");
        }

        // 3. 统计RT
        double rt = getAverageResponseTime();
        if (rt > 1000) {  // RT超过1秒
            enableDegradation();
            sendAlert("响应时间过长,已自动降级");
        }
    }

    /**
     * 降级执行
     */
    public Result executeWithDegradation(String serviceName) {
        if (isDegradationEnabled()) {
            // 返回默认值或静态数据
            return Result.degraded();
        }

        // 正常调用
        return serviceClient.call(serviceName);
    }

    /**
     * 手动降级(配置中心)
     */
    @EventListener(condition = "#event.type == 'MANUAL_DEGRADATION'")
    public void onManualDegradation(ConfigChangeEvent event) {
        boolean enabled = Boolean.parseBoolean(event.getValue());
        setDegradationEnabled(enabled);
    }
}

💡 设计题答题技巧

1. 答题框架

【需求分析】
- 功能需求XX
- 非功能需求XX
- 约束条件XX

【架构设计】
- 整体架构图
- 技术选型
- 数据模型

【详细设计】
- 核心代码
- 关键流程
- 边界处理

【容量预估】
- QPS预估
- 存储预估
- 带宽预估

【压测方案】
- 压测工具
- 压测场景
- 优化方案

【监控告警】
- 监控指标
- 告警策略

2. 常见追问

追问1如果QPS扩大10倍怎么办

答:
1. 垂直扩展:升级服务器配置
2. 水平扩展:增加服务器数量
3. 缓存优化:增加缓存命中率
4. 读写分离:减轻主库压力
5. 分库分表:分散压力
6. CDN加速减轻源站压力
7. 异步化:消息队列削峰

追问2如何保证数据一致性

答:
1. 强一致:分布式锁
2. 最终一致延迟双删、订阅Binlog
3. 补偿机制:定时任务对账

追问3如何应对突发流量

答:
1. 弹性扩容Serverless、K8s HPA
2. 限流:保护系统
3. 降级:保证核心功能
4. 预热:提前加载缓存