字节 今日头条-C++ 一面

1. 请介绍一下你做的“分布式通知中台”项目,整体架构和主流程是怎样的?

  1. API 网关接收请求并鉴权;
  2. 通知编排服务做模板渲染、路由决策;
  3. 通过 MQ 异步投递到各通道子服务;
  4. 子服务调用第三方渠道并回写投递状态;
  5. 查询服务聚合状态给前端。

这样做的好处是:高并发下削峰、渠道隔离、失败可重试、可观测性清晰。

2. RESTful HTTP 怎么请求?请求方法和路径如何设计?

核心是“资源化建模 + 语义化方法”:

  • POST /api/v1/notifications 创建通知任务
  • GET /api/v1/notifications/{id} 查询详情
  • GET /api/v1/notifications?userId=xx 列表查询
  • DELETE /api/v1/notifications/{id} 取消未发送任务

代码:

POST /api/v1/notifications
Content-Type: application/json

{
  "bizId": "order_123",
  "channel": "email",
  "templateId": "pay_success",
  "receiver": "**********",
  "params": {"name":"Tom","amount":"99.00"}
}

3. GTest 怎么做测试?如何做数据库相关测试?

分三层:

  1. 单元测试:mock 外部依赖(MQ、第三方通道);
  2. 集成测试:连测试库(Docker MySQL),跑迁移脚本后测试;
  3. 回归测试:覆盖重试、幂等、超时场景。

数据库测试重点:每个用例前后清理数据,保证可重复执行。

代码:

#include <gtest/gtest.h>

TEST(TemplateRenderTest, Basic) {
    std::string tpl = "Hi, {{name}}";
    std::string out = Render(tpl, {{"name", "Alice"}});
    ASSERT_EQ(out, "Hi, Alice");
}

4. MQ 中存储的是什么?如果消息太多放不下怎么办?

MQ 中一般存的是业务事件(如“通知待发送”“投递状态变更”),而不是大文件本体。 队列压力过大时可用:

  • 分区扩容 + 多消费者组;
  • 延迟队列与重试队列分离;
  • 过载时降级(低优先级消息限流/丢弃);
  • 大消息改“对象存储 URL + 元数据”;
  • 设置消息 TTL + 死信队列。

5. 通知系统里核心数据库表有哪些?关系如何设计?

典型表设计:

  • notification_task:任务主表(biz_id, template_id, status)
  • notification_recipient:接收人明细(task_id, receiver, channel)
  • notification_delivery_log:投递日志(recipient_id, attempt, provider_resp)
  • notification_template:模板配置(变量、版本、启停状态)

关系:task 1:N recipient 1:N delivery_log,模板与任务是 1:N。

6. “提交通知成功但数据库没写进去”怎么办?

这是典型一致性问题。做法:

  1. API 返回成功前,必须先落库(本地事务);
  2. 发 MQ 用 Outb

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

C++ 常考面试题总结 文章被收录于专栏

本专栏系统梳理C++方向, 大中厂高频高频面试考点 , 内容皆来自真实面试经历,从基础语法、内存管理、STL与设计模式,到操作系统与项目实战,结合真实面试题深度解析,帮助开发者高效查漏补缺,提升技术理解与面试通过率,打造扎实的C++工程能力.

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务