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

一、系统设计面试概述

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

二、经典面试题及解析

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

五、总结

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

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

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


个人观点,仅供参考

相关推荐
Ramble_Naylor30 分钟前
async/await:让一个线程同时等很多件事
开发语言·rust
ZealSinger37 分钟前
Spring7 RestTemplate弃用迁移
java·spring·后端开发·restclient
代码方舟39 分钟前
零信任架构实战:基于天远学历信息高级版构建自动化智库入驻审查网关
运维·人工智能·架构·自动化
迅猛龙办公室1 小时前
Python实现绘制同切圆
开发语言·python
朝朝辞暮i1 小时前
C++ 第 13 课:值传递 —— 为什么函数里改了,外面却没变?
java·c++·算法
弹简特1 小时前
【Java项目-企悦抽】16-抽奖模块01-获取活动完整信息接口实现
java·开发语言·状态模式·springboot
mftang1 小时前
EtherCAT协议:从“飞读飞写”机制到分布式时钟同步的实时以太网架构深度解析
分布式·架构·ethercat·分布式时钟·从站控制器
言乐61 小时前
Python语音检索
开发语言·python·django·virtualenv·pygame
BD_Marathon2 小时前
多轮对话聊天机器人
开发语言·机器人·c#
泡茶喝茶写代码2 小时前
A股量化数据工程:从 REST 接口到策略信号(第 1 篇):指数列表与实时行情接入
java·python·股票数据api·股票数据·股票数据api接口·股票api数据接口·股票量化数据接口