简历 preview
简历上 : 设计并实现了 用户的 评论功能, 支持多层级的评论回复
流程设计
需求分析 :
-
需要支持 用户 某篇文章进行评论
-
需要支持 用户 给评论 进行评论
-
需要支持 获取评论,以及获取子评论,创建评论,删除评论
模块分析 :
- 用户 可以给文章进行 评论 也可以给 用户的评论 进行评论 , 可以抽象为 用户给某个资源进行评论 因此将评论 单独抽象成一个服务
评论服务模块
支持的功能
-
获取第一页的评论
-
删除评论
-
创建评论
-
获取单条评论
-
获取子评论
表结构设计
-
设计 <PID, id> 外键, 因为我们不允许子评论出现在一个不存在的父评论上 。 并且我们希望在删除父评论的时候 同步删除子评论。
-
引入 RootID, 因为是通过 邻接表创建的 评论结构 。额外创建一个 RootId 列 能够优化查询顶级评论下全部评论的时间
-
PID 和 RootID 的类型是 Sql.NullInt64 因为顶级节点的父节点是空 。 这里考虑优化成 -1
|
|
获取评论列表功能设计
我们需要获取对应业务的 第一页所有评论,并且返回前3条子评论
-
直接根据 biz 和 bizID 进行查询
-
考虑到并发问题 使用 minID 进行偏移控制 。 如果使用 offset 可能会频繁变化
-
在降级到时候 考虑不去读取子评论 。 遍历所有顶级节点 然后并发的去查询子评论
其他细节
-
创建和删除 的时候 通过外键进行约束
-
查询顶级评论的时候 根据 RootId 进行优化

难点 & 亮点
问题 :
对于多级评论的表结构设计
方案 :
使用邻接表的方案进行设计评论表 。设计 外键 <pid, id> 控制 插入子评论的时候 不应该插入到不存在的父评论 。 以及删除父评论的时候应该同步删除子评论
亮点 :
-
在查找第一页评论的时候 需要返回对应的前3条子评论 。 考虑在服务降级的时候,不走这部分慢查询 。
-
考虑 用户可以评论 别人的评论 和文章 将评论服务单独拆成一个服务 并且使用 biz + biz_id 进行通用化处理
-
使用 minId 进行第一次分页查询,避免 offset 在高并发插入下 会漏
-
表结构设计 冗余 RootID 列,在查询顶级评论的时候能够直接查询全部回复 ,而不需要递归一整颗树
缺点
- 没有较好的缓存方案,例如加载第一页的时候可以考虑 维护一个热榜评论,并且缓存第一页 定时刷新
总分:68 / 100
对标 2 年 Golang、简历点「多层级评论」:能讲清主干,但深度、完整性和面试表达还不够稳,容易被追问卡住。
分项(满分)
| 维度 | 分 | 说明 |
|---|---|---|
| 需求分析 / 边界 | 14/20 | 功能列全了,缺非功能(QPS、延迟、一致性、审核) |
| 表结构 / 建模 | 16/20 | 邻接表 + RootID + FK 方向对,细节经不起深挖 |
| 查询 / 分页 | 12/20 | 知道 minID、降级,论证不严谨,实现路径模糊 |
| 亮点可讲性 | 14/20 | 有点,但缺「为什么 / 怎么权衡 / 踩过什么坑」 |
| 表达与材料质量 | 12/20 | 结构尚可,笔误多、描述空、像草稿 |
优点
- 服务抽象合理:
biz + biz_id把「评文章 / 评评论」统一成资源评论,符合可扩展拆分,面试官一般认可。 - 树存储选型正确:邻接表 + 冗余
RootID是常见方案;外键约束父子存在性、级联删也说得通。 - 有工程意识:第一页带前 3 条子评、降级不查子评、
minID代替offset,说明想过热路径和并发插入。 - 有自省:主动写「缺缓存」比硬吹完整方案更加分。
缺点(面试里会被追的)
-
「多层级」与实现深度不匹配
简历写多层级,正文几乎是「顶级 + 若干子评」。要明确:产品是无限嵌套还是只展示两级;邻接表如何保证插入时PID/RootID一致。 -
分页说法不严谨
高并发下offset的问题主要是重复/跳过、深分页成本,不是简单「漏数据」。minID(游标)要讲清排序键(id还是ctime)、同时间戳、方向(上滑/下滑)。 -
级联硬删很脆
真实产品多为软删、子评保留并标「父评已删」。只说OnDelete:CASCADE会被问:误删恢复、审核下架、计数怎么维护。 -
「前 3 条子评」实现空洞
按时间还是热度?一次 SQL 还是 N+1?并发查子评的限流、错误、超时?降级开关与指标?这些不补,亮点站不住。 -
空值方案半吊子
sql.NullInt64vs-1只提「考虑」,没有索引、查询条件、GORM 写入的结论。 -
缺面试常问块
创建时事务与 RootID 赋值、内容长度/敏感词、计数(回复数)、鉴权(谁可删)、幂等、缓存一致性——几乎空白。 -
材料完成度低
description: xxxx、错别字、口语化、无接口草图/时序,显得准备不充分。
建议(按优先级)
- 准备 3 分钟口述稿:需求 → 为何独立评论服务 → 表(PID/RootID)→ 第一页查询(含前 3 条子评)→ 降级 → 已知不足(缓存)。控制在 2~3 分钟。
- 画清两种删除语义:硬删级联 vs 软删;选一种并说清对列表、计数、子评展示的影响。
- 把分页讲死:排序字段、
WHERE id < ? ORDER BY id DESC LIMIT、为何不用offset、边界 case。 - 补「前 3 条」实现:例如按
root_id批量取 + 应用层截断,或窗口函数;说明为何不用「每条顶级再查一次」做默认路径。 - 补一条缓存方案(哪怕未做):第一页热评 ZSet / 本地+Redis、失效(写删、TTL)、穿透与击穿——对应你自己写的缺点。
- 对齐简历用词:若只做两级展示,简历改成「支持回复与两级展示」;若真支持 N 级,补插入校验与查询深度限制。
- 准备 5 个追问答案:并发插评、父评不存在、删父留子、深分页、评论热点文章打爆 DB。
一句话结论
68 分:方向和关键词对,够「做过评论」的入门讲述;要过认真的 Golang 一面/二面,需要把分页、删除语义、子评批量查询和缓存权衡讲扎实,并把材料从草稿修到能直接口述的版本。