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

一、系统设计面试概述

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

二、经典面试题及解析

题目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倍怎么办
  • 安全性:防攻击、权限控制
  • 监控:如何发现和定位问题

五、总结

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

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

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


个人观点,仅供参考

相关推荐
zhangfeng11335 分钟前
openclaw skills 小龙虾技能 通讯仿真 matlab skill Simulink Agentic Toolkit,通过kimi找到,mcp通讯
开发语言·matlab·openclaw·通讯仿真
Javatutouhouduan6 小时前
2026Java面试的正确打开方式!
java·高并发·java面试·java面试题·后端开发·java编程·java八股文
chao1898447 小时前
基于 SPEA2 的多目标优化算法 MATLAB 实现
开发语言·算法·matlab
JAVA面经实录9177 小时前
Java初级最终完整版学习路线图
java·spring·eclipse·maven
赏金术士7 小时前
Kotlin 习题集 · 高级篇
android·开发语言·kotlin
亚空间仓鼠7 小时前
Docker容器化高可用架构部署方案(六)
docker·容器·架构
RInk7oBjo7 小时前
从零设计生产级 Multi-Agent Harness:架构、评估、记忆、成本与 MCP 工具接入全拆解
架构
Cat_Rocky8 小时前
k8s-持久化存储,粗浅学习
java·学习·kubernetes
楼兰公子8 小时前
buildroot 在编译rust时裁剪平台类型数量的方法
开发语言·后端·rust
张伯毅8 小时前
如何构建一个生产级 AI Agent CLI —— 以 Claude Code 架构探索
人工智能·架构