中小公司系统设计题

70 阅读11分钟

详细题目拆解 + 考察点

1. 实时聊天系统

  • 如何实现消息的实时推送?(WebSocket vs Long Polling vs SSE)
  • 消息存储在哪里?数据库设计怎么做?
  • 如何处理离线消息?
  • 如何显示"对方正在输入..."?
  • 如何保证消息顺序?
  • 如何处理消息发送失败?

考察点:

  • WebSocket的理解和使用(Socket.io)
  • 数据库设计能力(消息表、用户关系表)
  • 状态管理(前端如何管理聊天状态)
  • 错误处理和边界情况

2. 文件上传系统

  • 如何处理大文件上传(>100MB)?
  • 如何实现断点续传?
  • 前端如何显示上传进度?
  • 如何验证文件类型和大小?
  • 文件存储在哪里?(本地 vs S3/云存储)
  • 如何防止恶意文件上传?

考察点:

  • 文件分片上传(chunking)
  • FormData和multipart/form-data
  • 前后端协作(进度回调、错误处理)
  • 安全意识(文件类型验证、大小限制)
  • 云服务集成能力

3. 通知系统

  • 如何实现实时通知?
  • 通知数据如何存储?
  • 如何标记已读/未读?
  • 如何处理通知优先级?
  • 如何实现邮件/短信通知?
  • 如何避免通知过载?

考察点:

  • 实时通信(WebSocket/Server-Sent Events)
  • 数据库设计(通知表结构)
  • 第三方服务集成(SendGrid、Twilio)
  • 消息队列的基本认知(RabbitMQ/Redis队列)

4. 认证与授权系统

  • 用户密码如何存储?
  • JWT vs Session,你会选哪个?为什么?
  • Token如何刷新?
  • 如何实现"记住我"功能?
  • 如何实现角色权限控制(RBAC)?
  • 如何防止CSRF和XSS攻击?

考察点:

  • 安全基础(加密、哈希、bcrypt)
  • JWT工作原理
  • HTTP安全头(HttpOnly, Secure cookies)
  • 前端路由守卫(React Router)
  • 中间件设计(Node.js middleware)

5. 评论系统

  • 如何设计嵌套评论的数据结构?
  • 如何高效查询评论树?
  • 分页怎么做?(一次加载多少条)
  • 如何实现点赞功能?
  • 如何防止刷赞/刷评论?
  • 删除评论时如何处理子评论?

考察点:

  • 树形数据结构设计(邻接列表 vs 路径枚举)
  • 递归查询和性能优化
  • 数据库索引使用
  • 反作弊机制(Rate Limiting)

6. 搜索功能(全文搜索 + 自动补全)

  • 如何实现模糊搜索?
  • 自动补全如何实现?(用户输入时实时显示)
  • 如何处理高频搜索(性能优化)?
  • 搜索结果如何排序?
  • 是否需要引入搜索引擎(Elasticsearch)?

考察点:

  • 数据库全文搜索(LIKE vs Full-Text Search)
  • Debounce/Throttle防抖技术
  • 缓存策略(Redis缓存热门搜索)
  • Elasticsearch基本概念

7. 限流/频率控制(Rate Limiting)

  • 如何限制用户每分钟只能调用10次API?
  • 前端还是后端做限流?
  • 如何存储用户的请求次数?
  • 如何处理分布式环境下的限流?
  • 被限流后如何友好提示用户?

考察点:

  • 限流算法(令牌桶、滑动窗口)
  • Redis的使用(存储计数器)
  • 中间件实现
  • HTTP状态码(429 Too Many Requests)

8. 缓存策略

  • 哪些数据适合缓存?
  • 缓存失效策略有哪些?(LRU, TTL)
  • 如何处理缓存穿透/击穿/雪崩?
  • Redis数据结构如何选择?
  • 缓存和数据库如何保持一致?

考察点:

  • Redis基础操作
  • 缓存设计思维
  • 缓存失效问题的理解
  • 前端缓存(HTTP缓存头)

9. 购物车系统

  • 未登录用户的购物车存在哪里?
  • 登录后如何合并购物车?
  • 如何处理商品库存?
  • 如何处理商品价格变化?
  • 购物车数据如何持久化?

考察点:

  • LocalStorage vs 数据库存储
  • 状态同步
  • 数据库事务(库存扣减)
  • 用户体验设计

10. 用户动态Feed流

  • 如何获取关注用户的动态?
  • 分页加载如何实现?(无限滚动)
  • 如何处理新动态的实时推送?
  • Feed流如何排序?(时间 vs 热度)
  • 如何优化查询性能?

考察点:

  • 数据库关联查询(JOIN)
  • 分页算法(offset vs cursor-based)
  • 缓存预热
  • 推模式 vs 拉模式

11. 点赞/收藏功能

  • 如何设计点赞的数据库表结构?
  • 如何防止用户重复点赞?
  • 点赞数如何统计?(实时计算 vs 冗余存储)
  • 如何处理高并发点赞?(热门帖子被疯狂点赞)
  • 取消点赞如何处理?
  • 如何快速查询"用户是否已点赞"?
  • 收藏和点赞有什么区别?数据库设计有何不同?
  • 如何展示"点赞列表"(谁点赞了这个帖子)?

考察点:

  • 数据库设计(多对多关系表)
  • 索引设计(复合索引:user_id + post_id)
  • 并发控制(数据库事务、乐观锁)
  • 缓存设计(Redis存储点赞计数,避免频繁查库)
  • 性能优化(异步更新计数、消息队列)
  • 反作弊机制(防止刷赞)

12. 图片CDN上传和展示

  • 图片上传的完整流程是什么?
  • 前端如何压缩图片?
  • 如何生成缩略图?(前端 vs 后端 vs 云服务)
  • 图片存储在哪里?(本地 vs S3/OSS)
  • 如何使用CDN加速图片访问?
  • 如何处理不同尺寸的图片?(响应式图片)
  • 如何优化图片加载性能?(懒加载、WebP格式)
  • 如何防止恶意上传?(文件类型、大小验证)
  • 图片URL如何设计?(如何防盗链?)

考察点:

  • 云服务集成(AWS S3、阿里云OSS、Cloudinary)
  • 图片处理(Sharp库、Canvas API)
  • CDN工作原理(缓存策略、回源)
  • 前端优化(懒加载、IntersectionObserver、srcset)
  • 安全意识(文件类型验证、防盗链、签名URL)
  • 成本意识(存储成本、流量成本)

技术细节可能追问:

  • 如何实现图片懒加载?
  • 如何生成带签名的临时URL?
  • 如何配置CDN缓存策略?
  • 前端如何预览图片后再上传?
  • 如何实现拖拽上传?

React 系统设计题目

1. 无限滚动列表(Infinite Scroll)

面试官可能问的具体问题:

  • 如何检测用户滚动到底部?
  • 如何防止重复加载数据?
  • 如何处理加载失败的情况?
  • 初次加载多少条数据?每次加载多少条?
  • 如何优化长列表性能?(虚拟滚动)
  • 用户快速滚动时如何处理?
  • 如何实现"回到顶部"且保持之前的加载状态?

考察点:

  • Intersection Observer API使用
  • React性能优化(useMemo、useCallback、React.memo)
  • 虚拟滚动(react-window、react-virtualized)
  • 防抖/节流(Debounce/Throttle)
  • 状态管理(已加载数据、加载状态、是否还有更多)
  • 错误边界和重试机制
  • 用户体验(加载指示器、骨架屏)

2. 搜索框自动补全(Autocomplete/Typeahead)

面试官可能问的具体问题:

  • 用户输入时何时触发搜索?
  • 如何防止频繁请求?(Debounce)
  • 如何高亮匹配的文字?
  • 如何实现键盘导航?(上下键选择)
  • 如何缓存搜索结果?
  • 如何处理搜索请求的竞态条件?(旧请求后返回)
  • 如何实现搜索历史?

考察点:

  • 防抖(Debounce)实现
  • 取消过期请求(AbortController)
  • useEffect依赖管理
  • 键盘事件处理(onKeyDown)
  • 缓存策略(React Query、SWR)
  • 高亮算法实现
  • 可访问性(ARIA标签)
  • LocalStorage(搜索历史)

3. 复杂表单系统(Dynamic Form Builder)

面试官可能问的具体问题:

  • 如何设计可配置的表单结构?(JSON Schema)
  • 表单验证如何实现?(实时 vs 提交时)
  • 如何处理表单字段之间的联动?(条件显示/隐藏)
  • 如何处理大型表单的性能问题?
  • 表单状态如何管理?(受控 vs 非受控)
  • 如何支持多步骤表单?
  • 草稿保存如何实现?(自动保存 vs 手动保存)

考察点:

  • React Hook Form / Formik使用
  • JSON Schema验证(Yup、Zod)
  • 受控/非受控组件理解
  • useReducer复杂状态管理
  • 表单性能优化(避免全表单re-render)
  • LocalStorage/SessionStorage(草稿保存)
  • 自定义Hooks封装
  • 错误边界和错误提示

4. 数据表格系统(DataGrid with Filter/Sort)

面试官可能问的具体问题:

  • 如何处理大量数据的表格渲染?(前端分页 vs 后端分页)
  • 如何实现列的排序?(前端排序 vs 后端排序)
  • 如何实现复杂筛选?(多条件筛选)
  • 如何实现列的显示/隐藏?
  • 如何导出为Excel/CSV?
  • 如何实现固定列/固定表头?
  • 如何处理单元格编辑?

考察点:

  • 虚拟滚动(大数据量)
  • React Table / TanStack Table使用
  • 状态管理(筛选条件、排序状态)
  • 前后端分页逻辑
  • CSV/Excel导出(客户端 vs 服务端)
  • Memoization优化(避免不必要的重渲染)
  • 性能优化(useCallback、useMemo)

5. 权限路由系统(Role-Based Routing)

面试官可能问的具体问题:

  • 如何根据用户角色显示/隐藏路由?
  • 未授权用户访问受限路由如何处理?
  • 如何实现路由级别的权限校验?
  • 如何实现按钮/组件级别的权限控制?
  • 权限数据从哪里获取?如何缓存?
  • 用户登录后如何动态加载路由?
  • 如何处理权限变更?(实时更新)

考察点:

  • React Router守卫(Protected Route)
  • Higher-Order Component(HOC)
  • Custom Hooks(usePermission)
  • Context API(权限上下文)
  • JWT解析和验证
  • 动态路由生成
  • 路由懒加载(React.lazy)
  • 重定向逻辑(403页面)

6. 拖拽看板系统(Drag & Drop Kanban)

面试官可能问的具体问题:

  • 如何实现拖拽功能?(原生HTML5 vs 库)
  • 拖拽时的状态管理如何设计?
  • 如何处理不同列之间的拖拽?
  • 拖拽后如何持久化到后端?(实时 vs 批量)
  • 如何实现拖拽预览效果?
  • 移动端如何支持拖拽?
  • 如何实现拖拽排序?(计算新的位置)

考察点:

  • HTML5 Drag & Drop API / react-beautiful-dnd
  • 复杂状态管理(Redux/Zustand)
  • 不可变数据更新(数组重排序)
  • 乐观更新(Optimistic UI)
  • WebSocket实时同步(多人协作)
  • 性能优化(大量DOM节点)
  • 触摸事件处理(移动端适配)

答题框架(通用)

答题框架是骨架,通用模式是肌肉,具体问题是细节

1. 需求澄清(2-3分钟)
   - 理解功能范围:"这个聊天系统需要支持群聊吗?"
   - 确认用户规模:"预计有多少用户?并发量多大?"
   - 询问技术约束:"需要支持离线消息吗?"

2. 高层设计(5分钟)
   - 画出架构图:前端 → API → 后端 → 数据库
   - 说明技术选型:
     * 前端:React + Redux/Context
     * 后端:Node.js + Express
     * 数据库:PostgreSQL/MongoDB
     * 其他:Redis缓存、WebSocket
   - 数据流向:用户操作 → 前端 → API → 数据库 → 返回

3. 核心模块设计(8-10分钟)
   A. 数据库设计
      - 画出表结构(ER图)
      - 说明字段和索引
   
   B. API设计
      - 列出核心接口
      - 说明请求/响应格式
   
   C. 前端状态管理
      - 如何管理全局状态
      - 如何处理异步操作
   
   D. 关键技术点
      - WebSocket连接管理
      - 文件分片上传
      - 缓存策略等

4. 深入讨论(5分钟)
   - 性能优化:索引、缓存、CDN
   - 安全考虑:XSS、CSRF、SQL注入
   - 错误处理:重试机制、降级方案
   - 扩展性:如何支持更多用户

5. Trade-offs(2分钟)
   - 说明你的设计选择
   - 解释为什么选A而不是B
   例如:"我选择WebSocket而不是轮询,因为..."

回答示例结构

以"实时聊天系统"为例:

面试官:设计一个一对一实时聊天系统

你的回答:
1. 澄清需求
   "我先确认几个问题:
   - 只需要一对一聊天,不需要群聊对吗?
   - 需要支持离线消息吗?
   - 预计有多少用户?并发多少?
   - 需要消息历史记录吗?"

2. 高层设计
   "整体架构是这样的:
   - 前端:React + Socket.io-client
   - 后端:Node.js + Express + Socket.io
   - 数据库:PostgreSQL存储消息,Redis存储在线状态
   - WebSocket用于实时通信"

3. 核心设计
   A. 数据库设计
      - users表:用户信息
      - messages表:消息内容、发送者、接收者、时间戳
      - conversations表:会话列表
   
   B. API设计
      - POST /api/messages - 发送消息(兜底HTTP接口)
      - GET /api/messages/:conversationId - 获取历史消息
      - WebSocket事件:
        * emit 'send_message'
        * on 'receive_message'
        * on 'user_online'
   
   C. 实时通信
      - 用户登录后建立WebSocket连接
      - 服务端维护用户ID到Socket ID的映射
      - 发送消息时查找接收者的Socket ID并推送

4. 优化和安全
   - Redis缓存最近消息
   - 消息内容XSS过滤
   - WebSocket连接认证(JWT)
   - 重连机制(前端断线重连)

5. Trade-offs
   "我选择WebSocket而不是长轮询,因为WebSocket是全双工,
   延迟更低,更适合实时聊天场景"