ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

百度后端秋招笔试全复盘:C++/PHP/GO方向考点与避坑指南

百度后端秋招笔试全复盘:C++/PHP/GO方向考点与避坑指南 2024年秋招我投了百度C/PHP/GO方向的后端工程师岗位赶上了第一批笔试。说实话第一批笔试往往是最没底的一批网上能搜到的往年真题少群里大家也都是盲人摸象谁都不知道今年题型变了没有、难度是升是降。我考完之后把整个流程、题型、踩坑点都复盘了一遍这篇就按我真实的笔试经历来写给后面几批的同学做个参考。先说结论百度的笔试整体风格是算法为王但绝不只考算法。选择题里会藏大量语言细节和工程常识编程题部分对代码效率和分析能力的要求比较高最后还会有开放式的设计题来拉区分度。C、PHP、GO三个语言方向虽然投的是同一个岗位大类但笔试试卷里的语言侧重其实能明显感觉到差异。这篇文章我会拆开讲每个方向考什么、怎么准备、容易在哪儿翻车最后再把我自己的失误和教训一并交代清楚。1. 收到笔试通知后的准备别只刷算法题1.1 考前48小时我做了什么百度笔试通知一般提前2-3天发时间窗口很紧。我收到通知后先做了一件事把招聘官网的岗位描述重新读了一遍重点看它列出的职责要求和任职资格。这个动作很多人忽略但它能直接提示笔试的考察范围。C/PHP/GO工程师这个岗位描述里通常会出现熟悉Linux环境掌握常见数据结构和算法对高并发、高性能服务有理解这类字眼翻译过来就是算法题必考、Linux基础要懂、工程场景题会出。之后我把时间分成三块算法部分按二分、双指针、DP、树/图、字符串、排序变体这几个高频专题每天过2-3道中档题不刷难题怪题。语言基础C方向我重新翻了Primer里的内存管理、STL容器源码实现思路、C11/14/17特性PHP方向看了错误处理机制、数组底层实现、常见Web安全问题GO方向看了goroutine调度、channel通信、sync包、内存逃逸分析。项目复盘把简历上写的项目从架构设计、核心模块、难点解决、性能优化四个角度重新梳理了一遍因为设计题很可能跟项目经验结合。这套准备思路不算特殊但胜在覆盖面够广。百度的笔试有个特点你永远不知道选择题里会从哪个犄角旮旯冒出一道题。我能做的就是把高频考点都铺一遍而不是赌它考什么。1.2 第一批笔试的通用环境问题百度笔试用的是牛客网系统支持本地IDE调试也可以在线编译。这里有一个非常实际的建议提前半小时进入系统做环境测试。我遇到过不止一次键盘输入法把代码里的中文引号带进去、或者本地能跑但牛客上编译不过的情况。尤其是C如果代码里有一个中文字符出现在注释之外的地方编译直接报错浪费的时间非常可惜。另外牛客的系统默认是按通过率给分还是AC给分每年可能不一样我这场是多个测试用例加权判分——部分用例通过也能拿部分分。所以即使暴力解法只能过30%的用例也要把代码写上去不要空着。后面我细讲怎么骗这部分分。2. 试卷整体结构与时间分配策略2.1 我拿到的题型分布整张卷子大概是这样的结构不同批次可能略有差异题型题量建议用时分值占比估单选题语言基础/网络/OS20道左右25-30分钟25%多选题语言细节/易错点5-10道10分钟10-15%编程题手写代码3-4道60-70分钟45%-50%简答/设计题1-2道15-20分钟15%第一反应是题量好像不大但实际上做题过程中会不断感受到压力。选择题里经常出现以下说法正确的是这种多选选项里两三个都长得差不多对语言细节的熟练度要求非常高。编程题倒不是每道都难但有一道压轴题通常需要比较复杂的推导和实现很容易卡住。我的建议是选择题不要恋战。一道题超过1分半还没把握先标记跳过最后有时间再回来纠结。编程题才是大头前面把时间耗太多后面的代码题会写得很仓促。我给自己定的节奏是选择题多选题总时间不超过40分钟后面留足80分钟给代码题和设计题。2.2 编程题难度曲线这套卷的编程题难度是递增的。第一题基本是签到题比如字符串处理、数组统计、简单模拟10-15分钟内必须AC。第二题开始上强度常见的是二分答案、并查集、拓扑排序、贪心这类经典算法变体。第三题和第四题就明显拉开差距了涉及到树形DP、状态压缩、线段树这类进阶数据结构考场上没有扎实的训练基础很难全过。一个比较反直觉的现象是我复盘时发现第二题比第三题更值得花时间死磕。因为第三、四题通常区分度太高大部分人在那里挣扎半小时也未必能多过一个用例而第二题是那种卡壳了但跳出来换个思路就能AC的题目性价比更高。后面我会用一道类似的真题结构来做实战拆解。3. 语言细节题三个方向各自的重灾区3.1 C方向内存、STL、新特性C方向的选择题基本围绕这几类内存布局栈、堆、静态区、常量区、指针与引用、构造函数/析构函数的调用顺序、STL容器底层实现及迭代器失效、C11/14/17新特性。我考场上印象比较深的有几道字符串数组初始化方式的差异。char str[] hello和const char* str hello一个在栈上一个在只读常量区修改行为完全不同这种题几乎是C笔试标配。constexpr是在哪个C版本引入的。这题不偏但你要是没专门背过这个时间线很容易蒙错。C11引入constexprC14放宽了函数限制C17加了if constexpr一环扣一环。STL里vector扩容机制的细节emplace_back和push_back的区别reserve和resize的区别迭代器什么时候失效。多线程相关的std::atomic、std::mutex、条件变量以及ABA问题。说到ABA问题它本质上是指针比较时出现的经典坑很多人只在面试八股里背过但笔试选择题里它一样会换着法子考。我的感受是C方向的选择题其实不太偏大部分都是科班学过、刷过题就见过的东西。但如果平时写代码过度依赖IDE自动补全这些细节考场上会非常痛苦。备考C方向建议把STL常用容器源码级别的实现思路过一遍不需要背源码但要知道底层是数组还是链表、插入删除的时间复杂度、迭代器在什么操作后失效。3.2 PHP方向弱类型、错误处理、Web安全PHP方向的选择题有明显的Web业务倾向。我梳理一下考得比较多的点弱类型比较的坑0 abc在PHP 7和PHP 8里的结果不一样null false为真in_array第三个参数不传时是松散比较。这类题如果平时没踩过坑考场上很容易做错。错误处理机制PHP 7之后大多数错误改成了Error和Exception两套体系try-catch能捕获Exception但默认不捕获Error除非用全局set_error_handler或\Throwable接口。笔试里考下列哪种方式能捕获所有错误类型答案是catch (\Throwable $e)。跨域与JSONP虽然这是前端概念但后端工程师必须知道服务端怎么设置Access-Control-Allow-Origin、怎么处理OPTIONS预检请求JSONP为什么只能GET。选择题里给一个场景问你跨域失败的原因多半就是服务端响应头没设置对。框架类ThinkPHP这类国内主流框架是高频考点路由解析、ORM的find/select区别、中间件执行顺序。如果你的简历写了PHP这些几乎是必问。PHP数组底层实现PHP数组本质是有序哈希表这在选择题里经常拐弯抹角地考比如unset一个元素之后顺序如何变化foreach遍历时修改数组会不会出问题。我朋侪里有个做PHP的老手他的建议很干脆PHP方向笔试想拿高分就按Web安全语言陷阱框架使用三条线去复习。Web安全里的SQL注入、XSS、CSRF、SSRF基本年年出现语言陷阱主要就是弱类型比较、引用赋值、数组指针移动这些。3.3 GO方向并发模型、内存管理、工程化GO方向的选择题风格跟C很不一样更偏工程正确性和并发安全goroutine 与 channel 的使用场景channel的关闭原则、单向channel、select的随机性、sync.WaitGroup的使用限制。有一道题问的是下列哪个操作会导致死锁选项里有一个是在没有接收者的情况下向无缓冲channel发送数据——这就是经典陷阱。内存逃逸分析一个变量到底分配到栈上还是堆上选择题会给你一段函数问x逃逸没有。这个靠背结论没用得理解指针被外部引用、闭包捕获变量、大对象分配这几个触发条件。垃圾回收机制GO的GC是并发三色标记清除选择题会考STW的时机、GOGC环境变量的作用。不深但得知道。接口与类型断言空接口interface{}和类型断言的用法nil接口值的神奇行为也是易错点。字符串与切片string底层是只读字节数组[]byte和string互转会拷贝切片append导致底层数组变化、多个切片共享底层数组的修改可见性问题。这些是GO笔试里选择题的重灾区。还有一个很容易忽略的点cgo。如果简历里写了涉及CGO调用C库那选择题里可能会问cgo的限制、跨语言调用的性能开销、import C的基本用法。我标题里写的是C/PHP/GO但GO这个方向近年越来越重视底层和性能优化准备时别只盯着Web开发写。3.4 三个方向都绕不开的操作系统和网络不管选哪个语言方向操作系统和计算机网络的选择题也占了一部分。我在卷子里遇到的进程和线程的区别、协程goroutine与线程的调度模型。虚拟内存、缺页中断、LRU淘汰算法。TCP三次握手/四次挥手、TIME_WAIT状态的意义、TCP和UDP的区别。HTTP/1.1、HTTP/2、HTTPS握手过程、状态码语义。这些内容没什么技巧纯粹靠平时的积累。建议每个方向的同学都把那本《计算机网络自顶向下方法》和《操作系统导论》快速翻一遍不用精读抓住高频考点就行。4. 编程题实战拆解从读题到AC的完整思路4.1 第一题签到题如何确保一次AC签到题我没记错的话是一道字符串处理排序的题目大概是给一个字符串数组要求按某个规则排序后输出。这种题算法上几乎没有门槛真正的得分要点在于读清楚排序规则是字典序还是自定义权重是升序还是降序。注意输入输出格式到底要不要去重、要不要处理空字符串。边界情况数组为空、只有一个元素、字符串包含空格或特殊字符。我的经验是签到题用最稳的写法不要炫技。比如C里sort加自定义lambdaPHP里用usortGO里用sort.Slice每种语言都有成熟的排序方式直接调用就好。我见过有人手写快排然后分治边界写错白白丢分。写完之后花30秒自测两个用例一个常规输入一个边界输入。确认没有问题再提交不要急着写下一题。因为签到题的AC率会影响后续做题心态稳扎稳打永远比贪快划算。4.2 第二题经典算法的变体味道第二题我做的时候感觉特别像并查集图论的一个变体。题干大概意思是有若干个节点节点之间有连接关系要求判断某些操作之后图的连通性。核心算法其实就是并查集但它把场景包装成了业务问题读题时需要自己抽离出这是并查集。这种变体题的解题步骤我总结为三步抽象建模把题目里的实体翻译成节点或边把操作翻译成并查集的union或find。判断算法类型连通性、环检测、最小生成树的变体大概率是并查集最短路、可达性大概率是BFS/DFS排序后二分找答案大概率是二分答案。边界处理并查集如果节点编号是离散的需要用map做离散化如果有路径压缩和按秩合并复杂度就很稳。我当时做到了union的路径压缩和按秩合并整个过程大概20分钟AC。复盘时我觉得这一题最关键的收获是当你识别出题目的算法原型后不要犹豫直接用模板写能省一半时间。但前提是你真的做过并查集的经典题理解模板每一行为什么这么写。4.3 第三题一个卡住我15分钟的DP第三题是一道动态规划具体背景不细说了总之是一个二维网格上的最优路径问题。我的第一版思路直接用二维DP数组结果有几个样例超时——一看数据范围网格是10^5 * 10^5级别二维数组根本不可能开得下。这就是一个典型的题设规模暗示信号看到10^5以上的二维题目要立刻想到状态压缩或数学优化。我最后改用了一维滚动数组把空间复杂度降下来又加了一个剪枝条件才把所有用例跑过。这里分享一个笔试DP题的通用套路先写出朴素DP确认状态定义和转移方程是正确的这是得分的基础哪怕超时也能拿部分分。再去看数据范围如果空间太大尝试滚动数组如果时间太大尝试用单调队列、斜率优化、矩阵快速幂等技巧。一旦优化受阻果断放弃因为后面还有一题甚至还有设计题别在一棵树上吊死。实话说第三题我只优化到能过大部分用例没有做到满分AC。但在笔试这种场景下部分AC已经能拉开不少差距了没必要追求每题都完美。4.4 模拟题和偏难怪题怎么拿部分分除了上面几道我印象里还有一道纯模拟题规则很绕像在实现一个简化版的状态机。这种题算法上不难但极其考验代码组织的细心程度。我的做法是先把状态转移画在草稿纸上变成清晰的state - event - next_state映射表。再根据这个表写代码而不是边想边写。写完后逐条对照题意检查条件分支的顺序。对于完全没思路的压轴题我的策略是暴力兜底哪怕复杂度是O(n^2)或O(n!)只要能过最朴素的几个小规模用例就写上。笔试系统大多按测试用例给部分分暴力解能拿到20%-30%的分数远比空着强。另外只要复杂度分析写得清楚评卷人如果是人评是能看懂的会给一点思路分。4.5 我常用的几段代码模板把这些模板背熟笔试时能省很多时间C 快速幂long long fastPow(long long a, long long b, long long mod) { long long res 1; while (b) { if (b 1) res res * a % mod; a a * a % mod; b 1; } return res; }PHP 数组排序按某个字段usort($arr, function($a, $b) { return $a[score] $b[score]; });GO 并查集type UnionFind struct { parent []int rank []int } func NewUnionFind(n int) *UnionFind { uf : UnionFind{ parent: make([]int, n), rank: make([]int, n), } for i : range uf.parent { uf.parent[i] i } return uf } func (uf *UnionFind) Find(x int) int { if uf.parent[x] ! x { uf.parent[x] uf.Find(uf.parent[x]) } return uf.parent[x] } func (uf *UnionFind) Union(x, y int) { rx, ry : uf.Find(x), uf.Find(y) if rx ry { return } if uf.rank[rx] uf.rank[ry] { uf.parent[rx] ry } else if uf.rank[rx] uf.rank[ry] { uf.parent[ry] rx } else { uf.parent[ry] rx uf.rank[rx] } }这些模板不是让你死记硬背而是帮你在考场上省掉从零推导的体力活。笔试是限时战斗所有能提前写好背熟的东西都是你的弹药。5. 简答与设计方案题面试官到底在看什么5.1 简答题的踩分点我遇到的简答题是跟高并发场景相关的设计一个短链服务要求支持海量存储和高并发读取。这类题目面试官通常不是要看一个标准答案而是看你能不能把工程问题拆清楚。我的答题结构是需求分析分清楚核心功能短链生成、重定向、过期策略和扩展功能统计点击量、自定义短链。存储设计短链码怎么生成我用的是雪花ID再转62进制或者直接用哈希取前几位去重。数据存储用MySQL还是Redis热数据放Redis全量放MySQL。性能优化读多写少的场景加缓存、CDN、降级策略。可用性如果Redis挂了怎么办MySQL挂了怎么办可以怎么容灾。这套结构就是需求-存储-性能-可用性无论什么系统设计题都可以套。面试官在笔试里其实很难逐字读你的长篇大论所以结构清晰、关键词到位比字数多重要得多。如果是C方向加分项可以主动写一段线程池/内存池的设计或者说一下TCMalloc、jemalloc这类内存分配器在服务里的作用。如果是GO方向加分项可以提一下goroutine和channel怎么组织生产者消费者模型如何用sync.Pool减少对象分配压力。如果是PHP方向加分项可以说清楚PHP-FPM的进程模型、opcache的作用、Redis做分布式锁的细节。5.2 设计题里的坑与话术设计题最容易犯的错是只给口号不给落地。使用缓存谁都会写你得写出用什么缓存Redis还是本地缓存、缓存什么短链映射还是整个响应、过期时间多少、缓存击穿怎么办。另一个坑是忽略成本设计方案时什么都不考虑直接上全链路强一致多副本异地多活会让面试官觉得你天真。我一般会在设计里主动做取舍这个场景读多写少所以我会牺牲一些写入的实时性使用最终一致性必要时通过消息队列异步化处理。这部分的文字不需要刻意写得像论文而是要有一种我真的做过系统的务实感。哪怕我实际上没有做过大规模系统也要从平时的项目积累和阅读经验里提炼出真实可信的设计思路。6. 实战复盘我踩过的坑和事后总结6.1 考场上最容易犯的低级错误我这次笔试踩的坑其实挺典型的先说我最痛的一个第二道编程题我一开始读题太快把节点下标从0开始看成了从1开始导致样例输出对不上。浪费了几分钟排查实际上就是下标偏移的问题。这种错误在校招笔试里非常常见对策只有一条动手写代码之前先手动模拟一遍题目给的示例。如果示例能对得上再动手不迟。另一个坑是编译器的差异。我在本地用VS Code配的C环境默认C17写了个auto加结构化绑定觉得理所当然结果牛客的在线编译器是C11标准直接编译报错。考试系统一般会标注编译标准一定要看一眼。我后来把所有依赖新标准的写法都改成了兼容写法。PHP方向我总结的教训是写代码时要注意?php标签别写成短标签?很多在线编译器默认不开short_open_tag直接白屏报错。GO方向的坑主要是go mod和依赖路径但笔试系统一般已经配好了不需要自己go get所以这个坑反而小。6.2 时间管理上的失误我前一个小时因为选择题上的一些钻牛角尖多花了差不多8分钟导致最后压轴的模拟题只写了一半。事后复盘那几道死磕的选择题就算全对也就3-4分但我丢失的可能是模拟题里一半的用例分至少也有5-6分算下来亏了。正确节奏应该是每道选择题固定最长时限超时直接标记跳过先把编程题和设计题的基础分拿到手回头再补。如果最后实在没时间蒙一个也比空着强——选择题有25%的正确概率千万别空。6.3 笔试结束后怎么复盘才有意义笔试结束不代表这件事就完了恰恰相反复盘的价值不亚于考前刷题。我一般会做三件事还原每道题趁记忆还热把编程题的题干和我的解法写下来试着找更好的解法。我会把当时超时的题目重新在本地跑一遍理解正确做法。整理错题本把选择题里不确定的、做错的知识点单独记下来按语言方向分门别类。比如PHPempty和isset的区别GOchannel关闭后接收方会收到零值。估算自己的水准对比一下目标岗位历年笔试的分数线虽然官方不公布但通过论坛、牛客的讨论能有个模糊估计判断自己该补短板还是继续冲下一个公司。我认识一位学历背景一般但成功拿到大厂Offer的朋友他的策略就是每次笔试都当一次免费的模拟考试。不管最后有没有进面笔试中暴露的问题都是最真实的面试预报。他把每一场笔试的错题都消化透后面面试时被问到底层原理反而因为笔试复盘过而答得比很多科班生更扎实。6.4 关于第一批笔试的心态建议第一批笔试最大的不确定性是你不知道难度基准在哪也不知道竞争对手的普遍水平容易产生这题我是不是不该错的后悔情绪。我的建议是别纠结直接准备下一场。秋招是rolling制的百度这批挂了后面还有别的部门、别家公司每年都有不少人前面几批全挂最后却在后期批次里拿到理想Offer。笔试只是入场券不是终点线。当然如果你能查到笔试考完后多久出结果可以顺手设个提醒。一般百度秋招是分批通知面试第一批笔试之后大概一两周内会有消息。这段时间别干等继续刷题、继续投别的公司把自己维持在随时能打的状态远比焦虑结果有用。7. 给备考者的最后几点私人建议这些都是我考完之后最想回到考前去告诉自己的话写在这里就当是给后面批次同学的福利了。第一语言方向的选择要跟自己的简历一致。你投的是C/PHP/GO笔试题里很可能会让你用自己熟悉的语言做题但选择题是三个方向都可能出现的。简历写C结果只会写业务逻辑不会看汇编级别的优化选择题一旦深入就会露馅。反过来如果你主攻GO但C的基础也没丢选择题的得分会比想象中稳。第二笔试和面试是连贯的不是两个孤立的战场。笔试里遇到的设计题面试时经常会被追问笔试编程题的解法面试官也可能拿出来让你讲思路。所以笔试结束后一定把题留存别考完就删。面试前把笔试回忆题再过一遍是非常精准的押题。第三想进好的后端团队能写会写写好是三个层次。笔试里大多数人的代码都能跑过用例但只有少数人在代码结构、边界处理、复杂度分析上达到写好的标准。这些能力不靠短期突击还是得从平时每一次代码练习里积累。第四必要的时候用工具武装自己也没毛病。我们这行很多人会讨论本地开发环境怎么配置、怎么让代码跑得更顺畅比如VS Code配置C/C环境、装好PHP Debug插件、配置好GO的环境变量。这些平时觉得枯燥的准备工作在笔试限时场景下都会变成实打实的效率优势。我对环境配置的建议是提前一天把所有需要的编译调试环境在本地跑通别等到笔试那天才手忙脚乱地装依赖。最后再说一句百度这类大厂的秋招笔试很多时候考的不只是你会不会更是你在压力下能不能稳定输出。我见过刷题量很大但考场上一紧张连签到题都写错的人也见过算法水平中等但心态很稳、稳扎稳打拿到理想Offer的人。这场笔试对我最大的价值不是那张成绩单而是让我意识到自己的知识边界在哪里、临场心态有多重要。祝后面批次的各位旗开得胜。有笔试或面试相关的问题可以在评论里聊我看到会尽量回。
返回列表