快手工程B卷笔试复盘:算法、基础与设计题全解析
2026/8/31 10:57:48 网站建设 项目流程

快手2019年春季校园招聘笔试试题--工程B试卷

每年三四月份,互联网大厂的春季补招和暑期实习招聘就会集中冒出来,快手在这段时间的笔试一向以题量大、覆盖面广、考察细著称。我当年参加的是工程B卷,整场做下来最大的感受是:它不跟你玩虚的,不考脑筋急转弯式的偏题怪题,而是在基础功底上反复试探你的深度,并且非常强调与真实业务场景的结合。如果你是准备投递快手工程类岗位的同学,或者正在备战其他大厂校招笔试,这篇复盘应该能帮你少走不少弯路。

工程B卷这份试卷,适合谁参考?两类人:一类是即将参加快手或同类互联网公司校园招聘笔试的应届生,另一类是工作几年想回头补基础、检验自己技术功底的工程师。它的价值不在于题目本身有多难,而在于它非常典型地反映了大厂校招笔试的出题逻辑——算法题占大头,但计算机基础(网络、操作系统、数据库)绝不是走过场,而业务场景题更是直接把"你会不会写代码"提升到"你会不会用代码解决问题"的层面。

先说整场笔试下来我最直观的三个感受:

第一,时间紧。两个小时的笔试,算法题加上基础选择题,如果你对某个知识点没有形成“肌肉记忆”级的熟练度,很容易在某道题上卡住,然后就乱了节奏。

第二,考点密度高。一份试卷里几乎把计算机核心课程过了一遍,从C++内存管理到TCP连接状态,从数据库索引到分布式一致性,甚至还会穿插一两道和短视频业务相关的场景设计题。

第三,场景化强。纯考记忆的题目不多,很多题都会给一段业务背景——比如"某活动页面短时间涌入大量请求""用户上传视频后需要做转码处理"——然后让你在这个背景下分析问题、选择方案或写代码。这就要求你不是死记硬背知识点,而是真正理解它背后的原理和应用边界。

下面我按考卷的模块拆解方式,把工程B卷的核心内容、解题思路和备考心得完整分享出来。

1. 工程B卷整体结构与出题逻辑拆解

1.1 试卷模块与分值分布

工程B卷的题型结构大致分为三类:不定项选择题、算法编程题、主观设计题。不定项选择题覆盖计算机网络、操作系统、数据库、C++/Java基础、Linux常用命令等;算法编程题一般是两道,一道偏数据结构与常见算法,另一道会结合业务场景;主观设计题通常是最后一道,考察系统设计或问题排查思路。

从分值上看,算法编程题和主观设计题占了大头,选择题虽然单题分值不高,但胜在知识点分散、容错率低,一不小心就会连环错。我参加的那场,选择题大概有20道左右,两道编程题各占20分左右,最后一道主观题大概15分到20分。

这里有个值得注意的点:快手工程B卷的选择题非常多选,选错、漏选都不得分,所以对知识点的掌握必须准确,不能靠模糊记忆去猜。

1.2 为什么叫"工程B卷"

快手笔试一般分为A卷和B卷(有时候还有C卷),对应不同的岗位方向。工程B卷更偏向后端开发、基础架构、服务端研发这类方向,所以试卷里会特别强调高并发、分布式、存储、缓存这些在大流量场景下绕不开的知识点。

这跟快手的业务形态高度相关。快手是短视频平台,日活用户过亿,用户上传视频、刷推荐流、评论点赞,每一个动作背后都是海量的请求和数据处理。作为后端工程师,你写的每一行代码都可能被部署在成千上万台机器上,承受极高的并发压力。所以笔试不会只考单纯的算法,而是会把算法放到具体的业务场景里去考——比如"如何在海量视频中找出播放量Top100"这样的问题。

1.3 官方考察点与真实岗位能力的关联

如果你把整份试卷拆开来看,会发现它考察的能力模型和实际工作中的工程能力非常吻合:

  • 算法能力对应的是你对数据结构和基本算法的掌握程度,这是解决一切技术问题的底层工具;
  • 计算机基础对应的是你在实际开发中能否理解程序运行的底层机制,比如网络请求为什么慢、内存为什么涨、数据库为什么慢查询;
  • 业务场景题对应的是你把技术方案落地到具体业务中的能力,这决定你能否从写代码的人成长为解决问题的人。

所以这份试卷本质上不是要难倒你,而是想筛选出"基础扎实、思路清晰、有业务Sense"的候选人。

2. 核心考点模块精讲:每个知识点的考察方式与应对策略

2.1 计算机网络:不只是背协议,更要会分析问题

在工程B卷里,计算机网络是选择题的重灾区,也是很多人丢分的重灾区。考察的知识点基本集中在TCP/UDP、HTTP协议、TCP三次握手与四次挥手、流量控制与拥塞控制、DNS解析过程、常见HTTP状态码语义,以及HTTPS的握手过程。

你以为背下来就完了?太天真了。我记得有一道题是这样的:客户端与服务器建立TCP连接后,客户端突然断电,问服务器端会发生什么,以及TCP的保活机制是如何工作的。这道题考的是你对TCP连接状态的理解深度——如果客户端断电,服务器端不会立刻知道连接已断开,它会一直维护着这条连接,直到TCP的Keep-Alive定时器超时或者发送数据时收到RST报文。

另一个容易翻车的地方是HTTP状态码。题目会给你一堆场景,让你选对应的状态码——比如"服务器无法理解请求格式"是400,"请求的资源不存在"是404,而"服务器内部错误"是500。这些看起来很简单,但一旦混淆了401和403的语义,或者不知道408是请求超时,就会丢分。

我建议复习网络时不要只看协议本身,要把"为什么要这样设计"搞清楚。比如TCP为什么要三次握手而不是两次?因为要防止失效的连接请求突然又传到了服务器,导致服务器建立无用连接。理解了这一点,不管题目怎么变着花样考,你都能抓住本质。

2.2 操作系统:进程线程、内存管理是永远的主旋律

操作系统部分的考察重点非常清晰:进程与线程的区别、进程间通信方式、线程同步机制(互斥锁、信号量、条件变量)、死锁产生的四个必要条件、虚拟内存与分页机制、页面置换算法、用户态与内核态的切换。

有一道题我记得很清楚:给出四个关于死锁的描述,让你选出正确的选项,其中涉及"死锁的预防可以通过破坏互斥条件实现"这个选项。这个选项是错的,因为在大多数情况下互斥条件是无法破坏的——两个进程不可能同时使用同一台打印机,所以实际工程中更多是通过破坏"占有且等待""不可抢占""循环等待"这三个条件之一来预防死锁。

还有一个高频考点是虚拟内存。题目会给你一个系统配置:物理内存大小、页表项大小、虚拟地址位数,让你计算页表占用的内存大小。这种题看着复杂,其实套公式就能解,关键是要理解分页机制的原理,而不是死记公式。

我当时复习操作系统的策略是:把每个知识点都和实际开发场景联系起来。比如进程间通信方式,我就想到Redis的持久化是通过fork子进程来实现的,Master进程和子进程之间通过管道通信;多线程编程时为什么需要加锁,我就想到ConcurrentHashMap在JDK 8前后锁粒度的变化。这样记起来既牢固又有趣。

2.3 数据库:索引与事务是必须拿下的基础题

数据库部分的考点集中在MySQL上,包括索引的数据结构(B+树)、聚簇索引与非聚簇索引的区别、最左前缀匹配原则、事务的ACID特性、隔离级别、MVCC机制、以及常见SQL语句的编写。

这里我要特别提醒一句:不要只背概念,一定要动手写SQL。工程B卷里大概率会有一道SQL编写题,比如"有两张表,一张是用户表user(id, name),一张是订单表order(id, user_id, amount, create_time),请统计每个用户的订单总金额,并筛选出总金额超过10000的用户",题目本身不难,考察的是基本的JOIN、GROUP BY和HAVING语法。

让我比较意外的是,有一道选择题考了B+树和哈希索引的区别。题目问"哪种索引支持范围查询",答案是B+树,因为B+树的叶子节点通过双向链表连接,天然支持范围扫描;而哈希索引适合等值查询,一旦遇到范围查询就会退化为全表扫描。这道题虽然不难,但它提醒了我一个事实:面试官很看重你对底层数据结构特性的理解,而不是仅仅知道"MySQL有索引"。

还有一个容易被忽略的考点是事务隔离级别。可重复读(Repeatable Read)是MySQL默认的隔离级别,它通过MVCC解决了不可重复读的问题,但不能完全解决幻读——MySQL在可重复读级别下通过间隙锁(Gap Lock)部分解决了幻读。这个点如果不深入理解,做题时就容易踩坑。

2.4 C++/Java基础:内存管理与集合类是命题高发区

工程类岗位的笔试通常要求你掌握C++或者Java中的至少一门,但不管选哪门,内存管理和常用集合类都是必考的。

如果你是C++方向,那么智能指针(shared_ptr、unique_ptr、weak_ptr)、内存泄漏的成因与排查、虚函数与多态的实现原理、STL容器的底层数据结构,这些是必须吃透的。有一道选择题我记得是问"vector扩容时,旧元素是如何迁移的",答案是"分配一块新内存,将旧元素拷贝或移动到新内存中,然后释放旧内存"。这个过程中如果元素的拷贝构造函数很耗时,就会导致性能下降,所以实际工程中会预先reserve足够的容量。

如果你是Java方向,那么HashMap的底层实现(JDK 8中数组+链表+红黑树)、ConcurrentHashMap的锁机制、JVM内存模型(堆、栈、方法区)、垃圾回收算法(标记-清除、复制、标记-整理),这些是高频考点。有一道题问"JDK 8中HashMap在什么情况下会将链表转换为红黑树",答案是"链表长度超过阈值(默认8)并且数组长度大于等于64"。这个细节很多人会忽略后半句,导致选错。

我个人的建议是:复习时不要只背结论,要把代码打开看看,亲手在本地跑一跑,观察一下不同操作下内存和性能的变化。比如写一个demo,向HashMap中不断put元素,通过debug观察链表什么时候变成红黑树,这样记忆会深刻很多。

2.5 Linux与常用命令:那些"不用背但必须会"的知识

工程B卷里还会出现几道Linux相关的选择题,考察内容包括文件权限管理(chmod、chown)、进程管理(ps、top、kill)、文本处理(grep、awk、sed)、网络排查(netstat、ping、traceroute)、以及查看系统资源(free、df、du)等。

这类题目的特点是:不给你完整的命令,而是给你一个具体需求,让你选择合适的命令组合。比如"如何查看某个进程监听的端口号",正确做法是使用netstat -tlnp | grep 进程名,或者使用lsof -i:端口号。如果你只记得netstat但不知道怎么过滤,就会选错。

这里有一个实战经验可以分享:准备笔试时不用专门去背命令的每一个参数,但你一定要用Linux环境动手敲一遍。我当时在本地装了一个Ubuntu虚拟机,每天花20分钟练习常用的Linux命令,特别是把awksed的常见用法过了几遍。笔试中看到这类题目时,基本就是送分题。

3. 算法编程题实战复盘:从题目到AC的完整推导

3.1 题目一:滑动窗口内的最大值

这道题是所有刷过LeetCode的同学都很熟悉的经典题——给定一个整数数组和一个滑动窗口大小k,求每个窗口内的最大值。LeetCode 239原题,难度Hard,但只要掌握了单调队列的解法,其实不难。

我当时选择的实现方式是维护一个双端队列(deque),队列中存储的是数组下标,并且保证队列中下标对应的值是单调递减的。每次窗口滑动时,先将队尾所有小于当前元素的下标弹出,再将当前元素下标压入队尾;同时,如果队首下标已经不在当前窗口内,则将其从队首弹出。这样队首始终是当前窗口的最大值。

时间复杂度O(n),空间复杂度O(k)。我在笔试现场大概是花了两分钟理清思路,十分钟写完代码,然后花了三分钟检查边界情况——比如k为1、k等于数组长度、数组为空这些特殊情况。

这道题表面考的是数据结构的应用,实际上考的是你对"单调性"这个核心思想的理解。我当时在注释里写了一段话:单调队列的核心在于维护一个"对后续计算仍有价值"的候选集合,元素之间的比较关系一旦确定就不会被重复比较,从而把时间复杂度优化到O(n)。这个思想在很多算法题里都能用到。

3.2 题目二:求数组中的Top K个高频元素

这道题是典型的"海量数据 + 频率统计 + Top K"组合拳。题目给一个整数数组和一个整数k,要求返回数组中出现频率最高的k个元素。

第一反应是用哈希表统计每个元素出现的频率,然后用堆来维护当前频率最高的k个元素。这里有个容量选择的细节:维护的是一个大小为k的最小堆,每次新元素进来时,如果堆的大小小于k,直接入堆;否则比较新元素的频率和堆顶元素的频率,如果更大,就先弹出堆顶,再压入新元素。

这里还有一个更优的解法:如果数组元素的范围很大,用哈希表统计频率的空间复杂度是O(n),这个基本免不掉;但求TopK的部分可以用快速选择(Quick Select)算法做到平均O(n)的时间复杂度,替代O(n log k)的堆解法。笔试时我选择用堆,因为代码更稳妥,不容易出错——笔试求稳,面试再求炫技。

我做完这道题后的一个体会是:TopK问题是大厂笔试的高频考题,它的变体非常多,比如"从海量日志中找出访问次数最多的IP","从100亿个整数中找出最大的100个数"等。解题思路是通用的:先用哈希表或计数法做频率统计,再用堆或快速选择取TopK。把这个套路练熟,遇到这类题基本就有了底。

3.3 算法复习的推荐路线

如果你现在才开始准备,我建议你不要盲目刷题,而是按照下面的优先级顺序来复习:

  • 时间充足(两个月以上):LeetCode高频题100-200道,按专题分类刷,优先搞定数组、链表、二叉树、哈希表、双指针、滑动窗口、动态规划、DFS/BFS、单调栈、并查集。每道题做完后一定要看题解,对比自己的解法和最优解法的差距,思考为什么别人的解法更优。
  • 时间紧张(一个月到两个月):针对大厂笔试的高频题型专项突破,尤其是数组/字符串处理、链表操作、二叉树遍历、TopK问题、LRU缓存、以及各种排序算法的变体。
  • 时间非常紧张(两周以内):只刷高频题和经典题,每天保持2-3道编程题的节奏,重点保证熟练度而不是广度。

4. 主观设计题:如何组织思路拿高分

4.1 设计一个短网址系统

工程B卷的主观题我记得很清楚,是让设计一个短网址系统,要求说明完整的系统设计思路,包括API设计、存储选型、重定向流程、以及如何应对高并发。

这种题目没有标准答案,但它有明确的评分维度:思路是否清晰、方案是否可行、是否考虑到了实际工程中的关键问题(如并发、扩展性、缓存、数据持久化等)。

短网址系统的核心流程是:用户提交长URL,系统生成一个短URL并存储在数据库中;用户访问短URL时,系统根据短URL的标识查询到原始长URL,然后返回302重定向。

为什么用302而不是301?这是一个经典的考点。301是永久重定向,浏览器会缓存重定向结果,后续访问短URL时直接跳到长URL,不再请求短网址服务。这虽然可以减轻服务器压力,但你无法统计短URL的点击次数;302是临时重定向,每次访问都会经过短网址服务,虽然服务器压力大一些,但可以做点击统计和分析。对于业务方来说,点击数据分析是核心需求,所以一般选中方案302。这个细节不一定会直接考,但在设计题里主动提到,能体现你的思考深度。

存储选型上,我当时的方案是使用MySQL存储映射关系,同时用Redis做热点短URL的缓存。短URL的标识可以通过自增ID进行base62编码生成,避免使用复杂的哈希算法——因为哈希会有碰撞问题,而自增ID天然无碰撞。

高并发方面,需要考虑的是:如果某个短URL被大量访问(比如热点活动链接),如何防止数据库被打爆?做法是加Redis缓存,并且设置合理的过期时间;另外可以在应用层做限流,比如使用令牌桶算法控制单个短URL的QPS上限。

4.2 设计题的高分答题框架

设计题一般都有固定的答题框架,按照下面这四步走基本不会跑偏:

  • 第一步,明确需求。先搞清楚系统要解决什么问题,核心功能有哪些,非功能性需求是什么(并发量、数据量、可用性要求)。
  • 第二步,做技术选型。根据需求选择合适的技术组件,比如存储选SQL还是NoSQL、缓存选Redis还是Memcached、消息队列选Kafka还是RocketMQ,并说明选择理由。
  • 第三步,画出核心流程。说明数据是如何流转的,从请求进入系统到返回响应的完整路径是什么,每个环节的职责是什么。
  • 第四步,考虑扩展性与容错。如果并发再翻十倍怎么办?某个组件挂了怎么办?有没有监控和告警?日志怎么记录?

设计题最怕的就是没有结构、想到哪说到哪。我当时在脑内先搭了一个草稿框架,然后按框架逐步展开,最后还特意提到了缓存穿透、缓存雪崩的应对措施,这应该是整道题的加分项。

4.3 多拿分的小技巧:主动补充分布式相关方案

在做设计题时,有一个小技巧非常实用:在方案中主动提到分布式环境下的一致性、幂等性、负载均衡等问题的解决方案。比如短网址系统里,你可以说"当多个实例同时处理请求时,需要保证短URL标识生成的唯一性,因此可以采用预分配ID段或使用分布式发号器(比如Snowflake算法)来生成ID"。

这种回答方式有几个好处:第一,展示了你对分布式系统的理解;第二,证明了你不只是一个会写CRUD的码农,而是一个有全局视野的工程师;第三,给面试官留下了充足的追问空间——后续面试中很大概率会顺着这道题继续深入,你已经提前铺好了路。

我在笔试中就把短URL的生成方案从"数据库自增ID"升级到了"预分配ID段+内存发号"的方案,解释了一下为什么自增ID在分布式场景下会成为瓶颈,以及Snowflake算法的基本原理。写完这一段,我自己都觉得整个方案的完整度上了一个台阶。

5. 备考策略与时间分配建议

5.1 考前一个月应该怎么规划

如果你现在距离笔试还有一个月,我建议把时间分成三个阶段:基础复习期、刷题强化期、模拟实战期。

基础复习期(前两周):每天上午复习计算机网络、操作系统、数据库中的一门,下午刷算法题。复习方式以教材加博客为主,重点是把核心概念吃透。我当时主要参考了《计算机网络:自顶向下方法》《深入理解计算机系统》《高性能MySQL》这些经典书目的核心章节,配合网上整理的高频面试题来巩固。

刷题强化期(中间一周):算法题保持每天3-5道的节奏,优先刷高频题。晚上集中整理错题本,把每道题的解题思路、关键代码、易错点记录下来,周末统一回顾。

模拟实战期(最后一周):每天刷一套模拟卷或往年真题,严格按照120分钟的时限来练习,让自己适应考试的节奏和压力。同时把之前整理的基础知识点快速过一遍,查漏补缺。

5.2 各科目复习优先级排序

我个人的经验是,按下面的优先级来投入时间:

第一优先级:算法与数据结构。这是笔试的得分大头,也是最容易通过刷题快速提升的部分。建议每天至少保证2小时的刷题时间。

第二优先级:计算机网络与操作系统。这两门课的知识点相对固定,多刷几遍高频考点就能较好地掌握,性价比很高。

第三优先级:数据库与Linux。数据库的重点非常集中,索引和事务搞懂基本就能应付大部分题目;Linux命令则是熟练度问题,多练就好。

第四优先级:编程语言基础。不要为了笔试去钻研语言的高级特性,把内存管理、并发、常用集合类这些基础打牢就够了。

5.3 笔试当天的应试技巧

再分享几个笔试现场非常实用的技巧:

  • 先把所有题目快速浏览一遍,标记出自己擅长的题目,先做会做的,再啃硬骨头。不要在选择题上死磕太久,遇到拿不准的可以先标记,做完编程题再回头细想。
  • 编程题千万别留白。即使写不出来,也要把思路写上去,用伪代码描述你的算法,有时候也会给一部分分。
  • 注意代码的边界情况处理。大厂笔试的判题系统对边界情况的测试非常严格,数组越界、空指针、整数溢出都是常见扣分点。
  • 写在代码里的注释要清晰。虽然阅卷主要看判题结果,但有些题目需要人工review,清晰的注释和良好的代码风格会给你加分。

6. 常见的丢分陷阱与避坑经验

6.1 选择题里的"绝对化"陷阱

很多选择题喜欢用"一定""必须""所有""任何"这样的绝对化词汇,这种选项往往是错误的。比如"所有情况下,二叉树的前序遍历结果都是唯一的"——这个说法就是错的,因为如果二叉树中有相同的元素值,不同的二叉树结构可能产生相同的遍历序列。

做题时养成一个习惯:遇到绝对化表述,先在脑子里找反例。找不到反例再选它,能找到反例就果断排除。

6.2 编程题中"只追求AC"的坑

有些同学笔试时写代码只求通过题目给的测试用例,忽视了代码的鲁棒性和复杂度。但大厂的测试用例往往非常全面,包括边界条件、压力测试、极端输入等。

我举一个例子:题目要求求两个大整数之和,如果你直接用int类型读入,遇到超长整数就会溢出。正确的做法是用字符串处理,逐位相加,注意进位。这种细节在平时的刷题中就要养成习惯,特别是要留意题目给出的数据范围。

6.3 时间分配失衡的问题

有不少同学在选择题上花了太多时间,导致最后编程题只剩十几分钟,写不完代码。我的建议是:给选择题设定一个总时间上限,比如50分钟,到点必须停止,无论有没有做完都要切换到编程题。

编程题如果两道都很难,也不要慌。先做相对简单的那道,保证拿到一道完整的分,再去尝试第二道。最忌讳的是跟一道难题死磕到底,结果两道都没写出来。

6.4 不要忽视手写代码的规范性

笔试平台(一般是牛客网或赛码网)的在线编辑器没有IDE那么智能,代码提示和报错提示都比较弱。我建议平时练习时就习惯在简单编辑器里写代码,培养不看提示也能正确写出代码的能力。

写字的时候要注意变量命名规范、缩进清晰、逻辑片段用空行隔开,这样即使代码有bug,review时也更容易定位问题。

6.5 关于模拟笔试的几点经验补充分享

我在考前一周做了3次完整模拟,每次都是严格按照2小时来计时。第一次模拟时我发现自己选择题做了50分钟,完全给编程题留出了足够时间;但第二次模拟时我故意加快选择题速度,结果在几道多选题上连续失分。最后总结出来的经验是:选择题不能一味求快,宁可遇到不确定的先标记跳过,也比瞎猜后心态崩掉好。

另外,如果你想在考试时避免坏习惯,可以尝试在模拟时用同样的设备、同样的输入法,因为有些考生在笔试现场会因为输入法切换问题浪费大量时间。

7. 写在最后:一点个人体会与实用建议

笔试结束后我复盘整份试卷,最大的感悟是:快手工程B卷其实非常“务实”。它选的每一类题,几乎都是从后端工程师日常工作中提炼出来的——你写的接口怎么应对高并发,数据库索引怎么建才高效,缓存用了什么数据结构,服务之间的通信靠什么协议,Linux机器上怎么用命令排查线上问题。几乎没有一道题是“为了难而难”,它考的就是一个真实后端工程师的基本功。

所以我特别建议还在准备阶段的同学,不要只盯着算法题转,多花点时间把自己的计算机基础打扎实,多思考一下你写下的每一行代码在操作系统层面是怎么被执行的,一次网络请求从发出到返回中间经历了什么,一条SQL语句是如何在MySQL中完成优化和执行的。这些思考过程,才是你应对各种变化的笔试题目最可靠的后盾。

根据我个人实际参加快手春季校招笔试的经验来看,笔试过了只是第一步,它更像是叩开面试大门的敲门砖。但你为这份试卷付出的每一分努力,梳理清楚的每一个知识点,刷过的每一道题,都会在面试的深度追问和今后的实际工作中以你想不到的方式回馈你。最后再分享一个小技巧:做完笔试后一定要趁记忆清晰及时复盘,把做错的题和不确定的选项对照答案整理到自己的错题本上——这份笔记在你冲刺下一场笔试或面试前的复习中价值巨大。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询