一、企业概况
1.1公司简介
深信服科技股份有限公司成立于 2000 年,总部位于深圳,2018 年在深交所创业板上市,是国内较早专注企业级网络安全、云计算与 IT 基础设施的厂商之一。公司产品线覆盖下一代防火墙、上网行为管理、VPN、终端安全、超融合、桌面云与分布式存储,客户以政府、金融、教育、医疗和大型企业为主。在 IDC 等机构的国内市场跟踪报告里,深信服的 VPN、防火墙、桌面云等品类长期位居前列,研发人员占比较高,技术岗校招也因此更看重计算机基础而不是项目数量。
| 成立时间 | 2000 年 |
| 总部 | 深圳 |
| 上市情况 | 2018 年深交所创业板上市(300454) |
| 主营业务 | 网络安全、云计算、IT 基础设施与物联网产品 |
| 规模与行业地位 | 国内网络安全与云计算头部厂商,VPN、防火墙、桌面云等品类市占率长期居前 |
1.2岗位定位
技术岗是深信服校招研发序列的统称,入职后按方向分流到网络安全、云计算、基础架构或存储团队,日常以 Linux 环境下的 C/C++ 开发为主,涉及协议解析、数据面转发、虚拟化与分布式存储等模块。新人一般由导师带教,从单个功能模块做起,逐步独立负责子系统。这个岗位不要求候选人有很深的业务积累,但要求基础扎实、代码写得出来、遇到问题能自己定位。
| 所属体系 | 研发体系(网络安全 / 云计算 / 基础架构) |
| 核心职责 | 模块设计、编码实现、单元测试与线上问题定位 |
| 技术栈 | C/C++、Linux、数据结构与算法、TCP/IP、数据库 |
| 发展路径 | 初级研发工程师 → 高级研发工程师 → 技术专家 / 技术管理 |
- 一面不区分具体业务部门,题目全部是通用技术能力,说明分流发生在入职或后续轮次
- 对 C/C++ 的要求高于脚本语言,指针、内存布局、字节序这类底层知识会被直接问到
1.3招聘概况
2025 届校招技术岗面向计算机、软件工程、网络空间安全、电子信息等专业,流程一般为网申、在线笔试、技术面与 HR 面。笔试和一面都围绕计算机基础展开,算法题以经典题型为主,不追求竞赛难度。
| 招聘对象 | 2025 届应届毕业生 |
| 面向专业 | 计算机、软件工程、网络空间安全、电子信息等 |
| 岗位方向 | 研发技术岗(C/C++ 为主) |
| 流程 | 网申 → 在线笔试 → 技术面 → HR 面 |
企业概况整理自公司官网、公开年报与招聘公告,具体数据以官方最新发布为准。
二、面试总体概述
2.1案例背景
这是一份 2025 届深信服校招技术岗的一面记录,全程围绕 C++、操作系统、计算机网络、SQL 与手撕算法五块展开,没有业务场景题,也没有冷门偏题。题目的难度集中在「基础是否扎实」:面向对象三大特性、C++11 特性、哈希冲突、指针数组与数组指针、堆栈区别、大小端、TCP 可靠性、Cookie 与 Session,最后现场写快速排序和链表判环。面试官会给思考时间,也会顺着回答继续追问一层原理,答得越具体、越能举例,越容易往下一轮走。
2.2基本信息
| 公司 | 深信服科技股份有限公司 |
| 岗位 | 技术岗 |
| 招聘类型 | 校招 · 2025届 |
| 用工形式 / 部门 | 直招 |
| 面试轮次 | 1 轮 |
| 平均时长 | 45 分钟 |
| 题目数量 | 共 11 题,均附参考答案 |
| 整体难度 | ★★★☆☆ 中等 |
| 候选人背景 | 经历 2025 届应届毕业生 |
2.3高频考点
| 考点 | 分类 | 出现轮次 | 次数 |
|---|---|---|---|
| C++ 面向对象与语言特性 | 编程语言 · C++ | 技术一面 | 2 |
| 指针、数组与内存布局 | 编程语言 · C++ | 技术一面 | 2 |
| 堆栈、字节序等操作系统基础 | 计算机基础 · 操作系统 | 技术一面 | 2 |
| TCP 可靠传输与会话管理 | 计算机基础 · 网络 | 技术一面 | 2 |
| SQL 分组统计 | 数据库 | 技术一面 | 1 |
| 手撕经典算法 | 算法与编码 | 技术一面 | 2 |
2.4备考建议
| 优先级 | 易失分点 | 准备动作 |
|---|---|---|
| P0 | 八股只背结论,追问到原理就断片 | 把 C++、操作系统、网络三科按「是什么 → 底层怎么做 → 什么场景用」重写笔记,每章准备三个追问 |
| P0 | 手撕代码写得出但边界不全 | 限时练快排、归并、链表判环、反转链表、二叉树遍历,写完先口述边界再运行 |
| P0 | 指针与数组的声明容易看错 | 整理指针数组、数组指针、函数指针、指向函数指针的数组四组声明,每组画一次结合顺序 |
| P1 | 大小端只会背定义,写不出判断代码 | 手写强制类型转换和 union 两种判断方式,并补一句网络字节序转换的实际用途 |
| P1 | SQL 只会写单表查询 | 把 GROUP BY、HAVING、聚合函数、多表连接各写五个例子,重点练「按维度分组再统计」的题型 |
三、面试流程
3.1流程总览
| # | 环节 | 形式 | 时长 | 筛选重点 |
|---|---|---|---|---|
| 1 | 网申投递 | 官网 / 校招公众号 | 约 15 分钟 | 简历与岗位方向的匹配度 |
| 2 | 在线笔试 | 在线机考 | 约 90 分钟 | 编程能力与计算机基础 |
| 3 | 技术一面 | 视频 / 现场 | 45~60 分钟 | 计算机基础与现场编码 |
| 4 | HR 面 / 综合面 | 视频 | 20~30 分钟 | 求职动机、稳定性与地点 |
3.2各环节说明
深信服校招技术岗通过官网或校招公众号投递,简历按学校、专业、项目经历与技术栈综合筛选。研发岗投递量大,筛选时更看「有没有真正写过 C/C++、有没有 Linux 环境下的开发经验」,而不是罗列一堆语言名词。
- 简历里出现的每个技术点都要能被追问到底层,写不熟的不要写
- 项目写清自己负责的模块、遇到的难点和最后的结果,避免只写「参与了 xx 系统」
- 投递前确认岗位方向与 base 地,网络安全、云计算、存储的侧重点并不相同
技术岗笔试通常是选择题加编程题,选择题覆盖 C/C++ 语法、操作系统、计算机网络、数据库,编程题以数组、字符串、链表、排序等经典题型为主。编程题按通过用例计分,边界条件和复杂度都会影响最终得分。
- 先拿稳有把握的题,不要在一道题上耗掉一半时间
- 写完自测空输入、单元素、重复值、越界四类边界
- 提前熟悉 ACM 模式的输入输出,避免把时间花在格式上
本贴记录的就是这一轮。面试官按「C++ → 操作系统 → 网络 → SQL → 手撕算法」的顺序提问,每个概念后面都会追一层原理,最后留十分钟左右让候选人现场写代码。整体氛围偏交流,不会刻意打断,但也不会放过含糊的回答。
- 每个知识点准备「定义 + 原理 + 一个例子」三层,别停在名词解释
- 不会的题先讲思路和边界,再承认掌握程度,不要硬编
- 手撕代码前先口述思路和边界条件,再动手写,写完主动说复杂度
技术面通过后一般还有 HR 或部门负责人面,主要确认求职动机、地点接受度、薪资预期与其他 offer 进度,也会核对简历时间线。回答要前后一致,不要和前面几轮的说法冲突。
- 提前想清楚为什么选网络安全 / 云计算这条赛道
- 地点与到岗时间给明确答复,避免后续流程反复
- 对被追问「还投了哪些公司」如实说,但重点落在选择逻辑上
四、第 1 轮:技术一面
4.1面试形式与时长
| 轮次名称 | 技术一面 |
| 面试类型 | 技术面 |
| 时长 | 45~60 分钟 |
| 本轮题量 | 11 题 |
4.2重点考查维度
- 计算机基础 —— 本组 4 道题
- 编程语言 —— 本组 3 道题
- 算法与编码 —— 本组 2 道题
- 数据结构 —— 本组 1 道题
- 数据库 —— 本组 1 道题
题目按 C++ → 操作系统 → 网络 → SQL → 手撕算法排列,面试官会在每个概念后追问一层原理,回答时主动给例子会明显加分。
考察语言基本功与概念之间的关联;考察语言版本的实战使用而非名词记忆;考察数据结构底层实现与工程取舍
4.3面试真题与参考答案
回答框架:先点名封装、继承、多态,再按「是什么 → 解决什么问题 → 一个例子」逐条展开,最后收一句三者的关系。
- 封装:把数据和对数据的操作包在类里,用 public / protected / private 控制可见性。它解决的是「状态被随意修改」的问题,外部只能通过接口改状态,类内部可以维护不变式。比如账户类把余额设为 private,只暴露 deposit / withdraw 并在内部校验金额。
- 继承:子类复用父类的属性和方法,可以扩展新成员或重写虚函数。它解决代码复用和层次抽象,但继承是强耦合,工程上一般讲「组合优先于继承」。
- 多态:同一个接口在不同对象上有不同实现。编译期多态靠函数重载和模板;运行期多态靠虚函数表,基类指针指向派生类对象时,调用虚函数会按对象的实际类型分派。
收尾可以补一句「封装是基础,继承是手段,多态是目的」,并主动提一句:基类析构函数要写成 virtual,否则用基类指针 delete 派生类对象时析构不完整。
回答框架:不要报菜名,挑五六个真正用过的特性,每个说清「解决什么问题 + 一行示例」。
- nullptr:NULL 本质是整数 0,重载时会被当成 int,nullptr 有独立的 std::nullptr_t 类型,消除了指针与整数的二义性。
- auto / decltype:编译期类型推导,写迭代器和长模板类型时省事,但不要用在对外接口上,可读性会下降。
- 范围 for:
for (auto& x : v)直接遍历容器,配合引用避免拷贝。 - Lambda:匿名函数,常用于排序规则和回调,捕获列表要分清值捕获和引用捕获的生命周期。
- 右值引用与移动语义:
std::move把资源所有权转走,配合移动构造避免深拷贝,std::forward用于完美转发。 - 智能指针:unique_ptr / shared_ptr 把 RAII 落到实处,替代手写 new / delete。
最后补一句:C++11 之后还有 14/17/20,结构化绑定、optional、string_view 在日常代码里也很常见,说明自己跟得上标准演进,而不是停在课本。
回答框架:先说冲突的本质,再按开放定址、链地址、再散列三类讲,最后点出工业界怎么选。
冲突的本质是不同 key 经哈希函数映射到了同一个桶。常见做法有四类:
- 线性探测:冲突后依次看下一个槽位,到表尾折返。实现简单、缓存友好,但容易形成连续聚集,删除还要用墓碑标记。
- 二次探测:步长取 1²、2²、3²……,缓解一次聚集,仍可能出现二次聚集,装填因子一般控制在 0.5 左右。
- 拉链法:每个桶挂一条链表,冲突元素挂到链上。实现直观、删除方便,是 std::unordered_map 的典型做法;链太长时会转成红黑树,把最坏查找从 O(n) 降到 O(log n)。
- 再散列:换一个哈希函数重新计算,直到找到空位,计算开销更大,一般作为兜底。
收尾可以说:工程上还会配合扩容,负载因子超过阈值就 rehash,再配一个分布均匀的哈希函数,单靠某一种冲突处理解决不了性能问题。
回答框架:先给结论,再讲运算符优先级,最后各给一个使用场景。
关键在优先级:[] 高于 *,有括号先看括号。
int *p[10]是指针数组:p 先和 [10] 结合,是一个长度为 10 的数组,每个元素是 int*。适合存一组同类型的指针,比如十个字符串的首地址。int (*p)[10]是数组指针:括号让 p 先和 * 结合,p 是一个指针,指向「含 10 个 int 的数组」。它常用于二维数组传参,作为形参时 p++ 会一次跳过一整行。
追问预警:可能会继续问 int *(*p)[10],那是「指向指针数组的指针」,按同样的优先级一层层剥即可。答题时最好在纸上画一下结合顺序,比背结论更可信,也能顺带说明自己理解的是声明语法而不是死记。
回答框架:按管理方式、分配效率、空间大小、碎片、生长方向五个维度对比,最后落到「什么时候该用堆」。
- 管理方式:栈由编译器自动管理,函数返回就释放;堆由程序员通过 new / delete 或 malloc / free 手动管理,忘记释放就是内存泄漏。
- 分配机制:栈是连续内存,移动栈顶指针即可,剩余空间不够就栈溢出;堆基于空闲链表找合适的内存块,分配前要查找、可能触发系统调用。
- 空间大小:栈一般很小,Windows 默认 1~2 MB,Linux 常见 8 MB;堆受虚拟地址空间限制,可以申请到很大。
- 碎片:栈先进后出、进出一一对应,不产生碎片;堆频繁申请释放会产生外部碎片。
- 生长方向与效率:栈通常向低地址生长,有专用寄存器和指令支持,效率高;堆向高地址生长,机制复杂,效率低。
收尾补一句:对象能在栈上就别放堆上,RAII 和智能指针的价值就是把「手动释放」变成「作用域结束自动释放」。
回答框架:定义 → 举例 → 两种判断代码 → 一句工程背景。
定义:多字节数据在内存里的字节顺序。大端把高字节放在低地址,0x12345678 存成 12 34 56 78;小端把低字节放在低地址,存成 78 56 34 12。x86 和多数 ARM 默认小端,网络字节序规定为大端,所以 socket 编程要做 htonl / ntohl 转换。
判断方法一:取 int 的地址转成 char*,看第一个字节。
int a = 0x12345678;
char c = *(char*)&a;
// c == 0x12 为大端,c == 0x78 为小端方法二:用 union 让 int 和 char 共享同一块内存。
union { int a; char c; } u;
u.a = 0x12345678;
// u.c == 0x12 为大端,0x78 为小端注意:如果题目给的示例是 0x1234 这种两字节数,要先说明自己按 4 字节 int 讨论,避免和示例对不上。收尾补一句:判断字节序的意义在跨平台通信、协议解析和二进制文件读写,不是纯八股。
回答框架:从确认重传、校验、排序、流量控制、拥塞控制五个机制展开,每个说清「解决什么问题」,最后和 UDP 对比收尾。
- 确认与重传:接收方收到报文回 ACK,发送方启动超时计时器,超时未收到确认就重传;还有快速重传,收到三个重复 ACK 立即重发,不必等超时。
- 数据校验:报文头带校验和,接收方校验失败直接丢弃,让发送方重传。
- 分片与排序:按 MSS 分段,接收方缓存乱序到达的段,按序号重组后交给应用层;重复的段会被去重。
- 流量控制:基于滑动窗口,接收方通过窗口字段告知还能收多少,避免发送太快把接收缓冲区打满。
- 拥塞控制:慢启动、拥塞避免、快重传、快恢复,根据网络状况调整拥塞窗口,防止把链路压垮。
收尾对比一句:UDP 不建连接、不确认、不重传,所以快但不可靠,音视频和游戏这类能容忍丢包的场景更常用。如果追问「TCP 一定可靠吗」,要补一句:它保证的是有序、无差错、不重复的字节流,不保证应用层一定处理成功。
回答框架:先给存储位置,再补安全性、容量、生命周期三点差异,最后说实际系统里怎么配合。
- Cookie 存在客户端浏览器,是服务器通过 Set-Cookie 下发的小段文本,单个域名下一般限制在 4 KB 左右,可以设置过期时间、Domain、Path、HttpOnly 和 Secure。它明文可见,容易被篡改,所以不能放敏感信息。
- Session 存在服务端,可以是内存、数据库或 Redis,浏览器只保存一个 SessionID,通常也放在 Cookie 里传回来。数据在服务端,容量不受 4 KB 限制,安全性更高。
- 实际用法:登录成功后服务端生成 SessionID,写入 Redis 并设置过期时间,客户端后续请求带上它;分布式部署时要保证 Session 共享,否则换一台机器就掉登录。
收尾补一句:现在更常见的是 Token / JWT,把状态放到客户端签名里,服务端不存 Session,扩展性更好,但注销和续期要另外设计。
回答框架:先复述需求「按性别分组,统计人数和平均分」,再写语句,最后解释每个关键字的作用与边界。
SELECT sex,
COUNT(*) AS total_students,
AVG(score) AS average_score
FROM grades
WHERE sex IN ('male', 'female')
GROUP BY sex;要点:
- GROUP BY 按 sex 分组,SELECT 里只能出现分组列和聚合函数,否则语义不明确。
- COUNT(*) 统计行数,如果成绩可能为 NULL,用 COUNT(score) 只统计有成绩的记录。
- AVG 会自动忽略 NULL,需要把空成绩当 0 参与平均时要写
AVG(COALESCE(score,0))。 - WHERE 在分组前过滤,如果只想看平均分高于 80 的组,要用 HAVING AVG(score) > 80。
追问预警:面试官可能加一个「按班级和性别两级分组」,那就是 GROUP BY class_id, sex;也可能问去重人数,用 COUNT(DISTINCT student_id)。写之前先确认字段名和是否有 NULL,比直接背模板更稳。
回答框架:先说分治思路和复杂度,再写分区函数,最后讲边界与优化。
思路:选一个基准值,把小于它的放左边、大于它的放右边,基准归位后递归处理左右两段。平均时间复杂度 O(n log n),最坏 O(n²),空间是递归栈的 O(log n)。
int partition(vector<int>& a, int low, int high) {
int pivot = a[high];
int i = low - 1;
for (int j = low; j < high; ++j)
if (a[j] <= pivot) swap(a[++i], a[j]);
swap(a[i + 1], a[high]);
return i + 1;
}
void quickSort(vector<int>& a, int low, int high) {
if (low >= high) return;
int p = partition(a, low, high);
quickSort(a, low, p - 1);
quickSort(a, p + 1, high);
}要主动说明的点:
- 边界:
low >= high直接返回,空数组和单元素不会越界。 - 最坏情况:数组已经有序且固定取最后一个元素做基准,会退化成 O(n²),可以随机选基准或三数取中。
- 稳定性:快排不稳定,需要稳定排序时用归并。
- 工程优化:小区间(比如长度小于 16)改用插入排序,递归深度过大时切堆排序。
回答框架:先说快慢指针的直觉,再写代码,最后补边界和追问。
思路:慢指针每次走一步,快指针每次走两步。如果链表有环,两个指针一定会在环内相遇;如果无环,快指针先到达 NULL。时间 O(n),空间 O(1)。
bool hasCycle(ListNode* head) {
if (!head || !head->next) return false;
ListNode* slow = head;
ListNode* fast = head->next;
while (slow != fast) {
if (!fast || !fast->next) return false;
slow = slow->next;
fast = fast->next->next;
}
return true;
}边界与追问:
- 空链表、单节点直接返回 false,否则 fast->next 会解引用空指针。
- 追问「怎么找环的入口」:相遇后把一个指针放回头节点,两个指针都每次走一步,再次相遇的位置就是入口。
- 追问「环的长度」:相遇后继续走,记录回到原点的步数。
- 追问「为什么一定相遇」:快指针每轮比慢指针多走一步,在环内相当于逐格逼近,不会跨过去。
说复杂度时要顺带说空间 O(1),这是相比哈希表标记法的优势。
五、注意事项
下面这些点来自本场面试的实际提问方式,都是「基础题答不深」的典型失分处,准备时逐条对照。
「三大特性」「C++11 新特性」这类题最容易背成清单。面试官要听的是每个特性解决什么问题、在代码里长什么样,答完一个概念最好跟一句例子或使用场景。
int *p[10] 和 int (*p)[10] 只差一对括号,含义完全相反。答题时先讲「[] 高于 *、有括号先算括号」,再给结论,比直接抛答案更让人信服。
这道题的重点是「如何区分」。强制类型转换和 union 两种写法至少会一种,并且要能说清为什么取第一个字节就能判断。
只答「确认重传」会被认为理解不完整。五个机制里,流量控制解决接收端处理不过来,拥塞控制解决网络扛不住,两者作用对象不同,要分开说。
位置只是第一层,接着要能说容量限制、安全性差异、分布式下 Session 怎么共享,以及现在为什么更多用 Token。
SELECT 里出现非分组列、WHERE 里写聚合条件,都是常见错误。写之前先确认分组维度,再想清楚过滤发生在分组前还是分组后。
快排的空数组与单元素、链表判环的空指针,都是面试官重点看的地方。写完先自己口述一遍边界,再报复杂度,能明显拉开差距。
一面题目多、节奏快,答题最好固定成「结论 → 分点 → 例子 → 一句总结」四段,既控制时间,也让面试官容易记录。
总结收尾
深信服技术岗一面没有想象中难,难的是把每个基础点讲透。C++、操作系统、网络三科是主干,SQL 和算法是常规配置,复习时按「原理 + 例子 + 边界」三层准备,比刷偏题有效得多。手撕代码要练到能边写边讲,写完主动报复杂度。面试时遇到不会的题,先讲思路再承认边界,比沉默或硬编更能保住分数。把这份题单当作自测清单,能顺着每道题往下讲两层,这一轮基本就稳了。
在此推荐你使用求职精灵(https://finsight.work/)进行系统备考。平台拥有深信服等数百家知名企业的真实面经资源,独家支持中英双语 AI 模拟面试,可针对技术岗进行定制化练习和智能评分优化;简历智能修改功能帮你打磨出一份亮眼的简历;超过 15 万道行测、专业题、英语题随时随地在线刷题。无论你是第一次校招还是已经面过几轮,求职精灵都能为你的求职之路提供有力支持。