面试官您好,我叫廖俊文,是吉林大学网络空间安全专业的一名大三在读学生 。
主要使用go语言进行开发, 熟悉go的gmp模型, gc回收机制, 熟悉slice, map等数据结构的底层原理
在校期间,我系统地学习了计算机网络、操作系统、数据库等核心课程。同时我作为吉林大学CTF校队的核心主力,和队友们一起拿下了第十六届全国大学生信息安全竞赛的全国一等奖等多个奖项。
我第一个项目是**“项目管理与协作平台”。这是一个导师接手的横向项目, 采用微服务架构的Go项目。在这个项目中,我主要负责后端核心模块的设计与开发。我们使用 gRPC 进行服务间的高性能通信,通过 Etcd 和 实现服务治理。引入了领域驱动设计的思想,并基于 RBAC 模型设计了的权限控制**。同时使用jwt作为身份验证,我运用了 Redis ,通过缓存和异步化的手段,来提升系统的响应速度和吞吐能力。并使用kafka来实现和redis的缓存最终一致性
第二个项目是一个学习项目,内容是 TinyKV 这个分布式键值数据库项目。实现了 Raft 共识算法,包括 Leader 选举、日志复制和快照。为了支持分布式事务,实现了 MVCC 多版本并发控制和两阶段提交(2PC)。整个过程让我对分布式系统的一致性、可用性以及各种故障处理有了非常深刻的理解。
总而言之,我认为自己是一个对技术充满热情、学习能力非常强的人。也渴望继续变强,充实自我
- 项目不熟悉
- 简历太阔了
- 算法能力太弱
- 系统设计
主要是预见到项目未来的功能会不断扩展,团队规模也可能会变大。我们希望从一开始就建立一个高内聚、低耦合的、可持续演进的架构
最大的好处之一就是解耦了发布流程。在单体应用中,任何一个小功能的改动,都需要整个应用重新编译、测试和发布,流程很慢。
最大的挑战就是数据一致性
“我们引入了 OpenTelemetry 和 Jaeger 作为全链路追踪方案。
-
API 网关层:在
project-api
服务的 Gin 框架中,我们使用otelgin
中间件。它会自动为每个 HTTP 请求创建顶层的 Trace 和 Span,并能解析上游(如 Nginx)传来的 Trace ID。 -
服务间调用:在 gRPC 的客户端和服务端,我们都配置了
otelgrpc
拦截器。这个拦截器会自动在服务间调用的 gRPC Metadata 中注入和提取 Trace 上下文,从而将一次请求在所有微服务间的调用路径完整地串联起来。 -
效果:所有服务产生的 Span 数据最终都会上报给 Jaeger Collector。当线上出现某个接口慢或报错时,我们可以在 Jaeger 的 UI 上清晰地看到完整的调用链,快速定位到是哪个服务的哪个环节出了问题。”
-
熔断降级(Circuit Breaking & Degradation):
- “服务间的 gRPC 调用是不可靠的。为了防止对某个下游服务(比如‘邮件服务’)的调用失败导致上游服务(比如‘任务服务’)的资源被耗尽而雪崩,我们引入了熔断器机制。
- 实现:我们可以在 gRPC 客户端的调用处,包裹一层熔断器逻辑(比如使用
sony/gobreaker
库)。 - 逻辑:熔断器会统计对下游服务的调用失败率。当失败率超过阈值时,熔断器会“跳闸”(进入 Open 状态),在接下来的一小段时间内,所有对该服务的调用都会直接在本地失败,立即返回一个降级响应,而不会再发起网络请求,从而保护了上游服务。一段时间后,熔断器会进入“半开”状态,尝试放过一个请求,如果成功,则关闭熔断器;如果失败,则继续保持打开状态。
- 降级:当熔断发生时,我们会执行降级逻辑。比如,发送邮件通知的操作被熔断了,我们会将这个通知任务存入一个备用的 Redis 队列,等邮件服务恢复后再进行补偿发送。对用户来说,核心功能不受影响,只是通知会延迟。”
接口限流(Rate Limiting):
-
“为了防止恶意请求或突发流量,我们在 API 网关层(
project-api
)实现了一个基于令牌桶算法的限流中间件。 -
实现:我们使用
golang.org/x/time/rate
这个库。可以对不同的接口设置不同的速率限制。 -
逻辑:每个请求到来时,都尝试从令牌桶里获取一个令牌。如果能拿到,就处理请求;如果拿不到(令牌被消耗完了),就直接返回 HTTP 状态码
429 Too Many Requests
。并且 -
消息中继:一个独立的中继服务负责将这条事件记录可靠地发布到 Kafka 的
task_events
Topic 中。 -
下游消费者:
- 通知服务:会订阅
task_events
Topic。当它收到newStatus: "done"
的事件时,它会查询任务详情,然后向任务的关注者发送站内信或邮件通知。 - 项目进度服务:也会订阅
task_events
Topic。它会根据一个项目下所有任务的状态变化,重新计算该项目的总体进度,并更新ms_project
表的schedule
字段。 - 操作日志服务:同样订阅这个 Topic,将这次“完成任务”的行为,记录到
ms_project_log
表中,形成完整的任务动态。
- 通知服务:会订阅
-
- “在我的缓存逻辑中,当一个缓存失效时,可能会有大量并发请求同时去查询数据库,这会造成缓存击穿。为了解决这个问题,我使用了
singleflight
库。它的底层原理就是用一个互斥锁来保护一个map
,这个map
记录了正在进行中的数据库查询。当第一个请求到来时,它会获取执行权;后续对同一个 key 的请求,则会阻塞等待,直到第一个请求完成后,所有等待者共享它的结果。这确保了在任何时刻,只有一个请求会真正地去“击穿”缓存,访问数据库。”
- “在我的缓存逻辑中,当一个缓存失效时,可能会有大量并发请求同时去查询数据库,这会造成缓存击穿。为了解决这个问题,我使用了
“比如,在用户注册或创建组织时,为了防止用户因为网络抖动等原因在短时间内重复提交同一个请求,从而创建出两条重复的数据。我在处理这类请求的 Handler
层,使用了一个基于用户ID或请求特征的内存锁。在处理请求前,先尝试获取锁;处理完毕后,再释放锁。如果获取锁失败,说明有另一个相同的请求正在处理中,就可以直接拒绝这次重复请求。这是一个简单的、单机版的请求去重锁实现。”