minimax 校招后端开发 一面面经

minimax 校招后端开发 一面面经
最新回答
岁月并非如歌

2023-12-14 06:37:59

Minimax校招后端开发一面面经核心内容总结如下

1. 实习相关问题
  • 雪花算法及时钟回拨问题

    雪花算法(Snowflake)是分布式ID生成算法,结合时间戳、机器ID和序列号生成唯一洞兆如ID。

    时钟回拨问题:当系统时间被回退(如NTP校时),可能导致ID重复。

    解决方案

    缓存已生成ID的时间戳,检测到回拨时抛出异常或等待时间追上。

    使用双Buffer切换或记录最大时间戳,回拨时拒绝服务或切换备用方案。

2. 网络协议对比与可靠性
  • TCP与UDP的区别

    TCP:面向连接、可靠传输(ACK确认、重传机制)、流量控制(滑动窗口)纳启、拥塞控制。

    UDP:无连接、不可靠、高效(无握手和状态维护),适用于实时性猜塌要求高的场景(如视频流)。

  • TCP如何保证可靠性

    三次握手建立连接,四次挥手释放连接。

    序列号与ACK确认:确保数据按序到达且不丢失。

    超时重传(RTO)与快速重传:丢失时触发重传。

    滑动窗口:控制发送速率,避免拥塞。

3. QUIC协议介绍
  • QUIC(Quick UDP Internet Connections)是基于UDP的传输协议,旨在解决TCP的缺陷(如队头阻塞)。

    特点

    连接建立快(类似TCP的三次握手,但集成TLS握手)。

    多路复用(避免HTTP/2的队头阻塞)。

    前向纠错(FEC)减少重传。

    连接迁移(IP变化时保持连接)。

4. 浏览器输入URL到页面展示的全过程
  1. DNS解析:将域名转换为IP地址(可能涉及缓存、递归查询)。
  2. TCP连接:与服务器建立TCP连接(三次握手)。
  3. TLS握手(HTTPS):协商加密算法、交换密钥。
  4. 发送HTTP请求:浏览器发送请求头及数据。
  5. 服务器处理:后端解析请求、查询数据库、生成响应。
  6. 返回HTTP响应:包含HTML、CSS、JS等资源。
  7. 渲染页面:浏览器解析HTML构建DOM树,解析CSS构建CSSOM树,合并为渲染树后布局绘制。
  8. 执行JS:可能触发重排/重绘,加载子资源。
5. Redis数据结构与底层实现
  • ZSet底层结构

    跳表(Skip List):通过多层链表实现快速查找(平均O(logN)复杂度),支持范围查询。

    为什么不用平衡树:跳表实现简单,且Redis需要频繁插入/删除,跳表性能更稳定。

  • 哨兵机制

    功能:监控Redis主从节点,故障时自动选举新主节点并通知客户端。

    核心流程

    哨兵集群通过Gossip协议通信。

    主观下线(单个哨兵判断)→ 客观下线(多数哨兵确认)。

    选举Leader哨兵执行故障转移。

  • 单线程到多线程的演进

    单线程模型:早期版本所有操作在单个线程执行,避免锁竞争,但CPU利用率低。

    多线程引入:高版本(如Redis 6.0)对I/O操作(如网络读写)使用多线程,计算仍单线程,提升吞吐量。

6. MySQL索引结构选择
  • B+树

    优点

    磁盘友好(块存储,减少I/O)。

    范围查询高效(叶子节点链表连接)。

    查询稳定(树高可控,O(logN)复杂度)。

  • ZSet为何用跳表

    ZSet需要频繁插入/删除且支持范围查询,跳表实现简单且性能稳定,而B+树更适合磁盘存储的静态数据。

7. 场景题:微信朋友圈评论与点赞设计
  • 存储模型

    动态表(Feed):存储用户发布的动态(ID、内容、时间、作者)。

    评论表(Comment):动态ID、评论内容、用户ID、时间、父评论ID(支持嵌套)。

    点赞表(Like):动态ID、用户ID、时间(可去重)。

  • 展现功能

    查询动态时,关联评论和点赞表,按时间排序返回。

    分页加载评论,避免一次性返回大量数据。

    使用缓存(如Redis)存储热点动态的评论/点赞数。

8. LeetCode 106题(从中序与后序遍历序列构造二叉树)
  • 解题思路

    后序遍历的最后一个元素是根节点。

    在中序遍历中找到根节点,划分左右子树。

    递归构建左右子树。

  • 代码框架(Python)def buildTree(inorder, postorder): if not inorder or not postorder: return None root_val = postorder.pop() root = TreeNode(root_val) root_idx = inorder.index(root_val) root.right = buildTree(inorder[root_idx+1:], postorder) root.left = buildTree(inorder[:root_idx], postorder) return root
总结

一面覆盖分布式ID、网络协议、数据库、Redis、算法等多个后端核心知识点,侧重基础理解与工程实践结合。建议复习时结合源码(如Redis跳表、TCP状态机)和实际场景(如高并发设计)深入理解。