【架构实战】系统设计面试题精选

一、系统设计面试概述

系统设计面试是高级工程师和架构师岗位的必考环节。面试官希望通过一道开放性问题,考察候选人的全局思维、技术深度和工程经验。

二、经典面试题及解析

题目1:设计一个短网址服务

需求分析:

  • 长URL → 短URL的映射
  • 支持高并发访问
  • 短URL尽可能短

核心设计:

java 复制代码
// 基于自增ID + Base62编码
public class ShortUrlService {
    
    private static final String BASE62 = 
        "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
    
    public String encode(long id) {
        StringBuilder sb = new StringBuilder();
        while (id > 0) {
            sb.append(BASE62.charAt((int)(id % 62)));
            id /= 62;
        }
        return sb.reverse().toString();
    }
    
    // 存储:Redis + MySQL双写
    public String shorten(String longUrl) {
        long id = idGenerator.nextId();
        String shortKey = encode(id);
        
        // 写入Redis缓存
        redisTemplate.opsForValue().set(
            "short:" + shortKey, longUrl, 7, TimeUnit.DAYS);
        
        // 写入MySQL持久化
        urlMapper.insert(new UrlMapping(id, shortKey, longUrl));
        
        return "https://t.cn/" + shortKey;
    }
}

题目2:设计一个秒杀系统

核心挑战:

  • 瞬时高并发(10万QPS+)
  • 防止超卖
  • 保证公平性

架构设计:

复制代码
用户请求 → Nginx限流 → API网关
                          ↓
                    Redis预扣库存
                          ↓
                    消息队列异步下单
                          ↓
                    数据库扣减库存
java 复制代码
// Redis预扣库存(Lua脚本保证原子性)
public boolean deductStock(String productId, int count) {
    String script = 
        "if (redis.call('exists', KEYS[1]) == 1) then " +
        "   local stock = tonumber(redis.call('get', KEYS[1])); " +
        "   if (stock >= tonumber(ARGV[1])) then " +
        "       redis.call('decrby', KEYS[1], ARGV[1]); " +
        "       return 1; " +
        "   end; " +
        "end; " +
        "return 0;";
    
    Long result = redisTemplate.execute(
        new DefaultRedisScript<>(script, Long.class),
        Collections.singletonList("stock:" + productId), 
        String.valueOf(count));
    
    return result != null && result == 1;
}

题目3:设计一个消息系统(类似微信)

核心模块:

  • 用户管理
  • 消息收发
  • 离线消息
  • 消息已读/未读

技术选型:

模块 方案
长连接 WebSocket / Netty
消息存储 MySQL + MongoDB
离线消息 Redis队列
群聊 消息扇出
消息同步 推拉结合模式
java 复制代码
// 推拉结合模式
// 推:新消息实时推送
// 拉:客户端上线后拉取离线消息
public List pullOfflineMessages(String userId) {
    String key = "offline:" + userId;
    List messages = redisTemplate.opsForList()
        .range(key, 0, -1);
    redisTemplate.delete(key);
    // 反序列化返回
    return messages.stream()
        .map(this::deserialize)
        .collect(Collectors.toList());
}

题目4:设计一个Feed流系统

三种方案对比:

方案 优点 缺点
推模式(写扩散) 读快 写慢,粉丝多成本高
拉模式(读扩散) 写快 读慢,大V成本高
推拉结合 平衡 实现复杂
java 复制代码
// 推拉结合:普通用户推,大V拉
public List getFeedTimeline(String userId) {
    User user = userMapper.selectById(userId);
    
    if (user.isBigV()) {
        // 大V:拉取关注的人的最新动态
        return feedMapper.pullFromFollowings(userId);
    } else {
        // 普通用户:从收件箱读取
        return redisTemplate.opsForList()
            .range("inbox:" + userId, 0, 50);
    }
}

三、答题框架

系统设计面试的标准答题流程:

  1. 理解需求 - 主动提问,明确功能范围
  2. 高层设计 - 画出整体架构图
  3. 深入设计 - 选择核心组件详细展开
  4. 扩展讨论 - 可扩展性、容错、监控
  5. 总结回顾 - Trade-off取舍说明

四、常见考察点

  • 数据一致性:如何保证分布式场景下的数据一致性
  • 高可用:单点故障如何处理
  • 可扩展:数据量增长10倍怎么办
  • 安全性:防攻击、权限控制
  • 监控:如何发现和定位问题

五、总结

系统设计面试不是要求完美方案,而是考察:

  • ✅ 结构化思维
  • ✅ 技术选型的权衡能力
  • ✅ 实际工程经验
  • ✅ 沟通表达能力

思考题:你遇到过最有趣的系统设计面试题是什么?你是怎么回答的?


个人观点,仅供参考

相关推荐
禅思院16 小时前
流式 Markdown 渲染完全指南【引子】
前端·架构·前端框架
魏码不凡16 小时前
CURL报错:未找到SSL证书文件问题
开发语言·php·ssl
翼龙云_cloud16 小时前
阿里云国际站代理商:ECS弹性伸缩 自动应对流量高峰
运维·网络·数据库·阿里云·架构
geovindu16 小时前
go:loghelper
开发语言·后端·golang
IMPYLH16 小时前
HTML 的 <em> 元素
java·前端·html
啊真真真17 小时前
ArgoCD:我的GitOps探索之旅与未来展望
java·算法·argocd
zandy101117 小时前
2026年,AI Agent搜索Skill推荐已经离不开底层架构
大数据·人工智能·架构
深入云栈17 小时前
从零手写连接池:Redisson ConnectionsHolder设计与简化实现
java·架构
学编程就要猛17 小时前
解析博客系统后端实现
java·mysql·jwt·摘要算法·加盐
笨蛋不要掉眼泪17 小时前
RabbitMQ消息队列:交换机机制
java·分布式·rabbitmq