From 16de9e2dd8b0fab116865bb9c6dec10e83b8b953 Mon Sep 17 00:00:00 2001 From: lwc-1 <1324004784@qq.com> Date: Thu, 6 Aug 2026 18:49:37 +0800 Subject: [PATCH 1/3] docs: add CC Sangfor first interview notes --- content/docs/interview/zhongchang/CC-?????.md | 191 ++++++++++++++++++ 1 file changed, 191 insertions(+) create mode 100644 content/docs/interview/zhongchang/CC-?????.md diff --git a/content/docs/interview/zhongchang/CC-?????.md b/content/docs/interview/zhongchang/CC-?????.md new file mode 100644 index 0000000..487be18 --- /dev/null +++ b/content/docs/interview/zhongchang/CC-?????.md @@ -0,0 +1,191 @@ +--- +title: "CC-深信服一面" +--- + +# 深信服一面 + +> 方向:Go 后端 / 短视频后端项目 / 计算机基础 / 场景题。 +> +> 本文记录面试真题,并整理了复盘要点。参考答案应结合自己的技术栈和真实经历调整,避免照搬或虚构项目、实习经历。 + +## 一、项目经历:短视频后端系统 + +### 1. 介绍一下这个项目:为什么要做?中间遇到了哪些困难?如何解决? + +答:这是一个短视频后端服务,主要实现用户、视频上传与发布、视频流、点赞、评论和关注等能力。做这个项目是为了把 Go Web 开发、数据库设计、对象存储、并发控制和容器化部署串成一次完整的工程实践;短视频场景不仅有常规 CRUD,还涉及大文件上传、异步处理和高并发写入。 + +项目中的主要难点和处理方式: + +- **大文件上传**:不把视频二进制直接存入 MySQL。客户端上传至对象存储,数据库只记录对象 key、封面地址、时长、大小和格式等元数据,降低数据库容量与 I/O 压力。 +- **发布链路一致性**:将上传和发布拆开。发布接口只校验文件、创建视频元数据与发布任务;转码、封面生成、审核和通知等耗时操作异步执行。视频状态按 `draft -> processing -> published/failed` 流转。 +- **重复发布与并发写入**:为每次发布加入 `request_id`,并在数据库建立 `author_id + request_id` 唯一约束;重复请求直接返回已有结果。事务只包住必要的元数据和状态更新,避免长事务。 +- **查询性能**:对视频流、评论和关系表的高频查询字段建立联合索引,例如 `videos(author_id, published_at)`、`comments(video_id, created_at)`。 + +### 2. 底层框架是纯手写的,还是 AI 辅助搭建的? + +答:架构设计和核心实现由自己完成,包括模块划分、接口设计、数据库表结构、认证流程、发布状态流转与并发控制。开发时会使用 AI 辅助完成部分脚手架、查询库的用法、补充测试思路或检查边界条件,但不会直接不加理解地复制。AI 生成的代码会结合项目结构改写、运行测试并自己定位问题。 + +面试时应如实回答使用范围。重点是能解释核心设计:为什么文件放对象存储、为什么发布要幂等、为什么耗时任务要异步化,以及异常时如何恢复。 + +### 3. 视频发布功能中的并发问题,能详细讲讲吗? + +答:视频发布不能把“上传文件”和“写发布记录”混在一个长请求、长事务中。通常先让客户端通过预签名 URL 或上传凭据直传对象存储;上传成功后,客户端再调用发布接口。 + +发布接口的并发风险主要是用户重复点击、网络超时重试和客户端重复投递,导致同一视频生成多条记录。处理过程如下: + +1. 客户端为一次发布生成 `request_id`,服务端也可生成发布任务 ID。 +2. 服务端校验登录状态、文件对象和参数,创建 `videos`、`publish_tasks` 等必要记录。 +3. 对 `author_id + request_id` 建唯一索引;发生重复请求时查询并返回第一次创建的任务或视频,而不是重复插入。 +4. 数据库事务只保护元数据、状态和必要关系,不执行转码、截图、审核等耗时工作。 +5. 后续任务通过消息队列异步处理;消费者完成后用条件更新推进状态,失败则记录错误并允许重试。 + +这样不需要使用全局锁。全局锁会让不同用户互相阻塞,而唯一约束与幂等键只会约束同一发布请求,吞吐量更高。 + +### 4. 多用户高并发发布视频,后端只有一个数据库,如何缓解入库压力? + +答:核心是使用消息队列削峰填谷,而不是把所有发布请求同步写入单个数据库。 + +```text +客户端直传对象存储 + ↓ +发布服务校验并投递消息 + ↓ +消息队列暂存峰值流量 + ↓ +消费者按受控并发度写入 MySQL + ↓ +更新发布状态,客户端轮询或订阅结果 +``` + +- 接口成功投递消息后可返回“处理中”,避免请求一直等待数据库写入完成。 +- 消费者数量和批量大小按数据库承受能力设置,防止连接池耗尽、磁盘 I/O 饱和或锁竞争恶化。 +- 消息应持久化;消费者成功写库后再确认,失败时重试,多次失败转入死信队列。 +- 消息可能重复投递或重复消费,因此数据库仍需使用 `request_id` 唯一约束保证幂等。 +- 如果业务要求“写库成功”和“发消息成功”严格一致,可使用事务 Outbox:同一事务内写业务数据和 `outbox_event`,后台任务再可靠投递 MQ。 + +### 5. 数据库表如何设计?包含哪些表? + +核心表可以按领域划分: + +| 表 | 关键字段 | 作用 | +| --- | --- | --- | +| `users` | `id`、`username`、`password_hash`、`avatar_url` | 用户账户和资料 | +| `videos` | `id`、`author_id`、`title`、`description`、`status`、`cover_url`、`published_at` | 视频核心元数据和发布状态 | +| `video_assets` | `id`、`video_id`、`object_key`、`file_size`、`duration`、`format` | 视频文件、封面和转码产物信息 | +| `publish_tasks` | `id`、`author_id`、`request_id`、`video_id`、`status`、`error_message` | 发布幂等、异步处理和失败追踪 | +| `user_video_likes` | `user_id`、`video_id`、`created_at` | 用户点赞关系 | +| `comments` | `id`、`video_id`、`user_id`、`parent_id`、`content` | 视频评论和回复 | +| `user_follows` | `follower_id`、`followee_id`、`created_at` | 用户关注关系 | +| `favorites` | `id`、`user_id`、`name` | 用户收藏夹 | +| `favorite_videos` | `favorite_id`、`video_id` | 收藏夹和视频的关联 | +| `categories`、`video_categories` | 分类 ID、视频 ID | 视频分类及多对多关联 | + +## 二、数据库表之间如何关联? + +答:每个实体表通常使用自增 `BIGINT` 或雪花 ID 作为主键,例如 `users.id`、`videos.id`。关联关系按业务建模: + +- **一对多**:一个用户可以发布多个视频,`videos.author_id` 关联 `users.id`;一个视频有多条评论,`comments.video_id` 关联 `videos.id`。 +- **一对一或一对多资源**:`video_assets.video_id` 关联 `videos.id`。若一条视频只有一个主文件可做一对一;若包含原视频、封面和多种清晰度转码文件,则是一对多。 +- **多对多**:用户和视频的点赞关系通过 `user_video_likes` 中间表实现;视频和分类通过 `video_categories` 实现。中间表通常用 `(user_id, video_id)` 或 `(video_id, category_id)` 作为联合主键或联合唯一索引。 +- **自关联**:`user_follows` 的 `follower_id` 和 `followee_id` 都关联 `users.id`,表示关注者与被关注者。 +- **评论回复**:`comments.parent_id` 指向同表的 `comments.id`,根评论的 `parent_id` 为 `NULL` 或 `0`。 + +在 MySQL 中,外键能保证引用完整性,例如避免为不存在的用户创建视频。实际高并发互联网业务有时不在数据库层显式建立外键,而是只建立普通索引并在应用层校验,以减少级联操作和跨表写入的限制;无论是否建立物理外键,逻辑上的主外键关系、唯一约束和索引都必须清晰。 + +## 三、Docker 主要用来做什么? + +答:Docker 用于将服务及其运行环境一起打包,解决“本地能运行、服务器不能运行”的环境差异问题。 + +- 使用 `Dockerfile` 构建 Go 二进制和运行镜像,固定 Go 版本、依赖和启动命令。 +- 使用 Docker Compose 一键拉起 API、MySQL、Redis、对象存储或消息队列,便于本地开发、联调和测试。 +- 通过环境变量或挂载配置文件注入数据库地址、密钥、日志级别等配置,不把敏感信息写死在镜像内。 +- 容器化后可以统一发布、回滚和扩容;生产上可配合 Kubernetes 做健康检查和滚动更新。 + +## 四、计算机专业基础知识 + +### 1. Go 和 C 的相似与差别 + +相似点:二者都偏系统编程,支持指针、结构体、函数和编译为本地机器码,性能与资源控制能力较强。 + +差异: + +- C 更接近硬件和操作系统,需要手动管理内存,指针操作自由但更容易出现越界、悬垂指针和内存泄漏。 +- Go 具有垃圾回收、切片、map、接口和反射等运行时能力,开发效率和安全性更高,但运行时和 GC 会带来一定开销。 +- C 的并发通常依赖 pthread、锁和条件变量;Go 原生提供 Goroutine、Channel 和 `select`,并通过 GMP 调度模型实现轻量并发。 +- C 头文件、预处理器和链接过程更直接;Go 使用 package、模块系统和统一的格式化、测试工具链。 + +### 2. Go 是否区分全局变量与局部变量?如何创建 Goroutine? + +答:有区分。包级变量定义在函数外,生命周期通常覆盖整个程序运行期,可被同包代码访问,首字母大写时可被其他包导出;局部变量定义在函数、代码块或参数列表内,只在对应作用域内有效。局部变量是否分配到栈上由编译器逃逸分析决定,不能简单认为“局部变量一定在栈上”。 + +创建 Goroutine 使用 `go` 关键字: + +```go +go func() { + // 并发执行的任务 +}() +``` + +Goroutine 间可通过 Channel 通信,也可用 `sync.WaitGroup` 等待任务结束;共享数据时仍要注意互斥锁、原子操作和竞态条件。 + +### 3. 了解 Python、Linux 命令、Bash 或 Python 脚本吗? + +答:了解 Python,常用于数据处理、自动化和调用 HTTP 接口;也写过 Bash/Python 脚本做日志处理、批量文件操作、接口巡检或开发环境初始化。常用 Linux 命令包括: + +- 文件与文本:`ls`、`cd`、`cp`、`mv`、`find`、`grep`、`sed`、`awk`、`tail -f`; +- 进程与资源:`ps`、`top`、`htop`、`kill`、`free`、`df -h`、`du -sh`; +- 网络与排查:`curl`、`wget`、`ss -lntp`、`ping`、`traceroute`、`nslookup`; +- 权限与服务:`chmod`、`chown`、`systemctl`、`journalctl`。 + +面试时最好补充一个真实脚本例子,例如“用 Python 定时读取日志并统计错误码,超过阈值通过企业通知机器人告警”。 + +### 4. 多线程、多进程、协程的区别 + +答:进程是资源分配的基本单位,拥有独立地址空间;进程间隔离强,但创建和通信成本较高。线程是 CPU 调度的基本单位,同一进程的线程共享地址空间,创建切换较轻,但共享内存需要锁保护。协程是用户态的轻量执行单元,由语言运行时调度,创建成本低,适合大量 I/O 并发;遇到阻塞 I/O 时,运行时可以切换到其他协程。 + +在 Go 中,Goroutine 不是直接等于 OS 线程,而是由 GMP 调度器把大量 G 调度到少量 M(系统线程)上运行;P 提供运行 G 所需的上下文和本地队列。 + +### 5. HTTP、TCP、IP 与网络问题排查 + +答:IP 负责网络层寻址和路由,本身是无连接、尽力而为的协议;TCP 在 IP 之上提供面向连接、可靠、有序的字节流,通过三次握手建立连接、序号确认与重传保证可靠性、滑动窗口和拥塞控制调节发送速度;HTTP 是应用层协议,定义请求方法、头、状态码和消息语义,通常运行在 TCP 之上,HTTPS 则在 HTTP 与 TCP 之间加入 TLS。 + +排查接口问题时先分层: + +1. 用 `curl -v` 查看 DNS、连接、TLS、请求头和响应头; +2. 关注状态码:`2xx` 成功、`301/302` 重定向、`400` 参数错误、`401` 未认证、`403` 无权限、`404` 路径不存在、`429` 限流、`5xx` 服务端异常; +3. 查看应用日志、反向代理日志和数据库/依赖服务耗时; +4. 用 `ss` 检查端口监听和连接状态,必要时用抓包工具确认 TCP 握手、重传或超时。 + +### 6. 如果实际组装一台电脑,会怎么做? + +答:先明确用途和预算,例如办公、游戏、开发或视频剪辑,再围绕兼容性和性能瓶颈选型。 + +| 组成原理中的部件 | 实际硬件映射 | 选型关注点 | +| --- | --- | --- | +| 运算器、控制器 | CPU | 插槽、核心数、性能与功耗 | +| 主存储器 | 内存(RAM) | 主板代际、容量、频率与双通道 | +| 外存储器 | SSD / HDD | NVMe 或 SATA、容量与读写需求 | +| 输入/输出设备 | 键盘、鼠标、显示器、网卡、显卡等 | 接口与实际使用场景 | +| 总线与连接 | 主板、PCIe、SATA、USB 等 | CPU 插槽、内存插槽、扩展能力 | + +独显、CPU、内存和主板要兼容;电源要预留足够功率并选择可靠品牌;机箱尺寸要容纳主板、显卡和散热器;最后装机、接线、进入 BIOS 检查硬件识别和温度,安装系统并做压力测试。 + +## 五、职场软技能与场景问题 + +### 1. 你的抗压能力怎么样? + +答:我认为抗压不是单纯熬时间,而是在压力下保持信息透明、优先级清晰和稳定交付。遇到紧急任务时,我会先确认截止时间、影响范围和验收标准,拆分出最小可交付版本,优先解决阻塞项;对风险及时同步,不等到最后一刻才暴露问题。高强度阶段结束后也会复盘流程和技术债,减少同类压力反复出现。 + +### 2. 任务只给有限上下文和大方向,会如何推进?有类似实习经历吗? + +答:我会先把模糊需求转成可验证的问题:目标用户是谁、要解决什么问题、输入输出是什么、优先级和验收标准是什么。然后阅读现有代码、文档、接口和监控数据,画出涉及的模块与依赖;在不确定点上主动向负责人确认,不会在关键假设上长期闭门开发。 + +接着将任务拆成调研、方案、最小实现、测试和发布观察几个阶段,先交付可运行的最小版本,再逐步完善。若有真实实习或项目案例,应按“背景—任务—行动—结果”说明;没有实习时不要虚构,可以用课程项目、开源贡献或团队项目举例。 + +### 3. 同时有多个任务,如何处理和排期? + +答:先按紧急程度、业务影响、依赖关系和工作量排序。存在外部依赖或会阻塞他人的事项优先推进;重要但不紧急的任务拆到迭代计划中。每天明确一到两个最重要目标,预留处理线上问题和沟通的缓冲时间。若资源和时间确实冲突,会尽早说明各方案的交付风险,请负责人确认优先级,而不是默认所有任务都能按原计划完成。 + +### 4. 技术热情怎么样?是否确定未来做研发岗位? + +答:我希望长期从事研发,尤其倾向后端与基础服务方向。吸引我的不仅是写出一个功能,更是通过设计、性能优化、稳定性建设和自动化让系统长期可靠运行。我会持续学习 Go、数据库、分布式系统和云原生相关知识,也愿意在实际业务里根据团队需要拓展其他技术栈。 From 6b07713641030e466dc71f2991dadb086858b611 Mon Sep 17 00:00:00 2001 From: lwc-1 <1324004784@qq.com> Date: Thu, 6 Aug 2026 19:33:37 +0800 Subject: [PATCH 2/3] docs: use ASCII filename for CC Sangfor interview --- .../zhongchang/{CC-?????.md => CC-Sangfor-First-Interview.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename content/docs/interview/zhongchang/{CC-?????.md => CC-Sangfor-First-Interview.md} (100%) diff --git a/content/docs/interview/zhongchang/CC-?????.md b/content/docs/interview/zhongchang/CC-Sangfor-First-Interview.md similarity index 100% rename from content/docs/interview/zhongchang/CC-?????.md rename to content/docs/interview/zhongchang/CC-Sangfor-First-Interview.md From 413bd1a60d1ce0e98f3383935bb4ac73088e6de5 Mon Sep 17 00:00:00 2001 From: lwc-1 <1324004784@qq.com> Date: Thu, 6 Aug 2026 19:35:56 +0800 Subject: [PATCH 3/3] docs: add interview metadata and directory entry --- .../zhongchang/CC-Sangfor-First-Interview.md | 1 + content/docs/interview/zhongchang/_index.md | 20 +++++++++++-------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/content/docs/interview/zhongchang/CC-Sangfor-First-Interview.md b/content/docs/interview/zhongchang/CC-Sangfor-First-Interview.md index 487be18..354c2de 100644 --- a/content/docs/interview/zhongchang/CC-Sangfor-First-Interview.md +++ b/content/docs/interview/zhongchang/CC-Sangfor-First-Interview.md @@ -1,5 +1,6 @@ --- title: "CC-深信服一面" +weight: 100 --- # 深信服一面 diff --git a/content/docs/interview/zhongchang/_index.md b/content/docs/interview/zhongchang/_index.md index 9f2ff50..2c34ec8 100644 --- a/content/docs/interview/zhongchang/_index.md +++ b/content/docs/interview/zhongchang/_index.md @@ -1,11 +1,15 @@ ---- -title: "中厂面试" -weight: 2 -bookCollapseSection: true ---- - -# 中厂面试 - +--- +title: "中厂面试" +weight: 2 +bookCollapseSection: true +--- + +# 中厂面试 + 这里收录中厂相关面试真题。 适合对比不同中厂岗位的题型分布、项目追问方式和手撕题方向。 + +## 本目录新增 + +- [CC-深信服一面](CC-Sangfor-First-Interview/)