
2015年互联网校招战场跟现在最大的区别是那时候BAT还是三座绕不开的大山。百度重金押注人工智能和移动端阿里在All in云计算腾讯靠微信拿到了移动互联网最值钱的船票。三个业务方向完全不同的大厂笔试却都爱用一套“选择题编程题开放题”的组合拳内推笔试更是把难度直接拉到正职面试的量级。今天要聊的这份“BAT 2015实习内推笔试卷第二场”就是当年流传出来、后来被无数人拿来当模拟题反复刷的一份卷子。这份卷子是干什么用的说白了BAT实习内推笔试是校招流程的第一道关卡。简历通过内推筛选之后候选人要先做一轮在线笔试过了才能进入电话面试或现场面试。这份第二场试卷就是其中一套高分还原的原题版本。它的价值不在“能不能押中题”而在于它完整地展示了BAT筛选实习生的核心逻辑数据结构与算法是硬通货计算机基础是底线灵活的工程思维是加分项。适合谁参考准备参加大厂校招或实习面试的同学计算机专业想检验自己基础扎实程度的在校生以及想搞清互联网公司技术面试套路的职场新人都可以拿这份卷子做一次系统性自测。下面我从复盘角度把这份卷子掰开揉碎讲一遍顺便聊一聊那些年在笔试里踩过的坑。1. 这份笔试卷的背景与真实分量1.1 内推不是免试90%的人误解了“内推”两个字2015年BAT的实习内推流程跟现在很多公司的“简历直通”完全不同。那时候内推渠道通常由内部员工推荐简历推荐成功后的第一关就是线上笔试。很多同学以为内推就是走个过场、简历过了就能面试结果一上来就挂在了笔试环节连面试官长什么样都没见到。为什么会这样因为内推的本质是“让HR在第一轮更认真地看你的简历”而不是“跳过筛选直接录用”。2015年移动互联网正处于爆发期BAT的实习生岗位含金量极高竞争激烈程度完全不亚于当年的正职校招。笔试的淘汰率相当高一份卷子刷掉七八成的人属于常态。所以把内推笔试卷当成“备胎级的练习题”是最危险的心态它实际上是整条招聘链路里淘汰率最高的一关。从招聘逻辑来看BAT设这套笔试的意图很清晰简历只能体现“你学过什么”很难体现“你会不会用”笔试是第一个能客观量化候选人的环节。因此在卷面设计上BAT有意识地把“基础能力”和“潜力”分开考察——用选择题筛掉基础不牢的用编程题筛掉动手能力不行的用开放题筛掉没有工程思维的。1.2 第二场试卷的定位题量、结构与考察方向这份卷子的结构大致分三块。第一部分是计算机基础选择题覆盖C/C语言、操作系统、计算机网络、数据结构第二部分是编程题一般是2到3道难度从低到高排列第三部分是简答或设计题考察系统设计思路和业务理解。从题量配置来看选择题在20道左右编程题2到3道设计题1到2道总时长150分钟。这个配置说明BAT想要的不是“在某一个点上特别强但其他地方一塌糊涂”的人而是“基础扎实、编码过关、思维有框架”的综合型选手。时间分配本身就是一个隐藏考点。150分钟看着不短但选择题如果每题花5分钟就是100分钟编程题基本只剩50分钟根本不够用。我见过很多同学在第一部分选择题上死磕太久导致编程题草草交卷这是笔试的大忌。正确的做法应该是在拿到卷子后先花2分钟通读全卷判断各部分难度然后再决定时间投入。这一点会在后面的实战章节详细展开。2. 笔试题型全景拆解从选择题到编程题都在考什么2.1 计算机基础选择题覆盖面与高频考点当年这份卷子的选择题覆盖范围相当广但绝不是漫无目的地堆知识点。现在回过头去看高频考点其实非常集中有很强的规律性。C/C语言部分考的是指针与引用、内存管理、sizeof与结构体对齐、虚函数与多态、static与const的作用。这些题表面在考语法实际考的是你对底层机制的理解程度。比如sizeof这道经典题看着是考“结构体占多少字节”其实考的是“你是否理解编译器如何布局内存”。数据结构部分二叉树遍历、链表操作、哈希冲突处理、堆排序与快速排序的复杂度分析是绝对高频。操作系统部分进程与线程的区别、死锁的四个必要条件、虚拟内存与页面置换算法是老面孔。计算机网络部分TCP三次握手与四次挥手、OSI七层模型、HTTP状态码几乎是必考。不要被这些名词吓到它们都是计算机专业本科课程里的核心内容。真正的问题在于大学里很多人是为了应付考试背下来的没有深究背后的原理。BAT的笔试题恰恰喜欢在这些“基础中的基础”上做文章考察你的理解深度。2.2 编程题从签到题到压轴题的难度梯度编程题是整份卷子的重头戏也是分水岭。以我当时刷题的经验来看BAT的编程题一般分三档。第一档是“签到题”比如数组去重、字符串反转、链表逆序。这类题卡人不多但要求你写出无bug的代码。很多人在这一档就翻车了不是因为不会思路而是因为边界条件没处理好比如链表为空、数组只有一个元素、字符串里有空格等。在线判题系统不会给你留情面一个边界没过就整体判错。第二档是“中等难度题”常见的有判断链表是否有环、二叉树层次遍历、求最长回文子串、Top K问题。这类题需要一定的算法积累考察的是数据结构和常见算法的熟练度。平时刷过题和没刷过题的人在这档题上差距非常明显。第三档是“压轴题”往往是动态规划、贪心算法、图论等比较吃脑子的题。2015年前后比较流行的是从海量数据中找出现频率最高的前K个数、编辑距离、字符串匹配变体等。这类题考察的是你在有限时间压力下的算法思维和代码实现能力能完整做出来的人基本就能锁定下一轮面试的名额。2.3 开放题与设计题BAT关心的工程思维开放题或者设计题是很多人的盲区因为它没有标准答案。当年的卷子里出现过几类典型的题设计一个短链接系统、设计一个微博信息流、1000万用户同时在线的聊天室后端架构怎么搭。每一道都是开放式没有“唯一正确解”。这类题考察的其实是你的工程思维框架。我看到太多答得稀烂的卷子通篇只谈某一个技术点比如“用Redis缓存”“用消息队列”却完全说不清你的整体方案是什么。要答好这类题核心在于“有结构”先界定需求和规模再谈整体架构最后说核心难点的解法。比如短链接系统不要一上来就写代码。先问短链码的生成算法有哪几种是自增主键还是哈希取模冲突了怎么办数据库怎么设计需不需要考虑高并发下的ID原子性再谈重定向的方式是301还是302缓存怎么加这样一层层展开哪怕你没做过真实系统也能让面试官看到你“有系统化思考的骨架”。3. 典型真题复盘与解题思路精讲3.1 一道C/C高频题的完整解法结构体对齐与sizeof以结构体对齐为例这份卷子里的选择题十有八九会出现。原题类似这样有一个结构体struct Test { char a; int b; short c; };问sizeof(struct Test)是多少。很多人会不假思索地算1427。但正确答案在32位平台下是12在64位平台下通常也是12。为什么因为编译器会按照“最大对齐数”来对齐结构体成员。char占1字节后int必须从4字节对齐的地址开始所以char后面会补3个padding字节int占4字节后short占2字节此时偏移是8short放在偏移8和9的位置。整个结构体结束后还要对齐到最大对齐数4的倍数10补到12因此结果是12。这类题目的深层价值在于它考的不仅是语法而是你对“内存布局”的理解。为什么CPU要对齐因为现代CPU访问对齐数据的效率远高于非对齐数据很多时候非对齐访问甚至会触发异常。编译器用空间换时间在结构体里插入padding牺牲一点内存换取更快的读取速度。理解了这一层不仅能把题目做对还能给面试官解释“为什么”这就比只会背结论的人高出一截。3.2 算法题链表、二叉树、动态规划的代表题思路链表判断环是当年笔试的高频题解法是快慢指针快指针一次走两步慢指针一次走一步。如果链表有环快慢指针必然相遇如果没有环快指针会先到达末尾此时返回false。复杂度为O(n)时间、O(1)空间比用哈希表记录访问过的节点要省内存这正是面试官期望的“最优解”。代码实现很简洁struct ListNode { int val; ListNode *next; ListNode(int x) : val(x), next(NULL) {} }; bool hasCycle(ListNode *head) { ListNode *slow head, *fast head; while (fast ! NULL fast-next ! NULL) { slow slow-next; fast fast-next-next; if (slow fast) return true; } return false; }注意循环条件必须同时判断fast和fast-next不为空否则访问空指针会崩溃。这就是典型的“边界条件”考点很多人都挂在fast-next为空的场景。二叉树层次遍历则考察队列的使用根节点先入队然后每弹出一个节点就把它的左右孩子入队直到队列为空。每层之间要用一个变量记录当前层的节点数每处理一个节点递减处理完一层之后再进入下一轮循环。代码骨架如下vectorvectorint levelOrder(TreeNode* root) { vectorvectorint result; if (root NULL) return result; queueTreeNode* q; q.push(root); while (!q.empty()) { int levelSize q.size(); vectorint level; for (int i 0; i levelSize; i) { TreeNode* node q.front(); q.pop(); level.push_back(node-val); if (node-left) q.push(node-left); if (node-right) q.push(node-right); } result.push_back(level); } return result; }动态规划的题比如最长上升子序列、编辑距离、01背包在当年卷子里出现频率也高。这类题有个通用思考框架先定义状态再找转移方程最后处理初始化和边界。比如编辑距离状态dp[i][j]表示word1前i个字符转换成word2前j个字符需要的最少操作数转移方程分三种情况插入、删除、替换取最小值初始化时处理空串情况。只要这三步走通了代码实现其实非常简单。3.3 网络与系统题从协议栈到并发模型计算机网络题在笔试里通常不以代码形式出现而是一道简答题比如“简述TCP三次握手为什么需要三次”。别小看这道经典题能答到点子上的不多。核心原因是三次握手是为了让通信双方都确认自己的发送能力和接收能力是正常的。第一次握手客户端发SYN服务器收到后确认客户端的发送能力正常第二次握手服务器发SYNACK客户端收到后确认服务器的发送和接收能力都正常第三次握手客户端发ACK服务器收到后才能确认客户端的接收能力正常。所以三次是“建立双向可靠连接”的最小次数。如果只有两次握手服务器无法确认客户端是否已经收到了自己的SYN也就无法确认“客户端的接收能力”是否正常。系统并发题则常考“单台服务器上你能用什么方式处理高并发请求”。2015年前后最主流的答案是多线程加连接池加缓存。你需要清晰描述线程池大小怎么定CPU密集型和IO密集型的公式不同、锁应该加在哪里、缓存不一致怎么办。这类问题没有唯一答案但你能把每个方案“为什么这么做”“有什么代价”讲清楚就能让面试官感受到你的工程经验。4. 如何高效备战这类笔试我的实操方法4.1 时间分配与刷题顺序在开始刷题之前先明确一条主线基础不牢刷再多题也是空中楼阁。我当时给自己规划的备战过程分三个阶段。第一阶段是补基础用两周时间快速过一遍数据结构、操作系统、计算机网络三门课的核心概念。重点是做笔记把关键结论和典型样例写下来而不是只看书。计算机基础的知识本质上是网状的靠笔记把知识点串起来效率远高于从头到尾啃教材。第二阶段是刷算法题每天3到5道按专题刷。顺序建议是数组、链表、字符串、栈与队列、哈希表、树、图、贪心、动态规划。这个顺序是循序渐进的前面几个专题能快速建立信心后面的题目则是真正的思维挑战。第三阶段是模拟笔试每周找一整块时间做一套真题严格限时。这一步非常关键因为线上笔试和平时刷题的感觉完全不同——没有编译器提示没有随时翻笔记的机会只有时间压力和判分系统。只有通过模拟才能练出“在规定时间内把会做的题做完”的临场能力。刷题顺序上还有个个人体会不要一上来就刷动态规划容易劝退。动态规划题在笔试中的占比并不算高但经常出现在压轴位置是决定能不能进下一轮的关键。所以把它放在刷题计划的后半程集中火力突破。4.2 笔试环境与做题节奏2015年的笔试已经很大部分是线上笔试了但很多人仍然习惯在本地IDE里写代码这是个致命误区。线上笔试环境通常没有代码提示很多在线编辑器连自动缩进都做不到你平时在VS或Xcode里写得飞快的代码一到线上环境可能连基本的格式都要手动敲。所以备战期一定要在在线判题环境中练习熟悉那种“手敲代码、提交判断、没有IDE辅助”的做题方式。LeetCode、牛客网这些平台都可以重点是适应在线编辑器的操作手感。做题节奏上我个人的经验是拿到试卷先花2分钟通读全卷把编程题和设计题的难度在心里排个序。然后先做选择题控制在40分钟内碰到不会的先标记不要死磕。再花60分钟写编程题先把签到题完整写对再去攻中等题和压轴题。最后留20到30分钟处理开放题以及回头检查选择题里标记过的题目。有人喜欢“先难后易”先把压轴题干掉再做简单的。我建议不要这么做笔试第一目标是“保分”先把必得的分拿到手再考虑是否能拿满。压轴题通常只是一道做完前面的题之后心态会稳很多再攻难题的成功率更高。4.3 容易被忽视的加分细节笔试中真正拉开差距的往往不是难题而是细节。第一个细节是代码风格。变量命名要有意义不要全部写a、b、c、d缩进统一主函数和处理逻辑分开关键逻辑加一句注释。面试官在看你的代码时能直接看到这些细节。一份整洁的代码和一个乱七八糟的代码观感差距极大。第二个细节是边界条件。数组越界、空指针、输入为空、只有一个元素等情况务必在提交前自己先脑内跑一遍。很多笔试挂掉的人不是不会做而是边界没处理好测试用例一跑全挂。比如反转链表空链表和只有一个节点的链表都需要单独处理二分查找区间是开还是闭会极大影响循环条件。第三个细节是不要在编程题上追求“炫技”先求“正确”。能用最朴素的暴力解法拿部分分也不要写一个看似很妙但你自己都讲不清的解法。笔试判分以用例通过为核心不是以美感为核心。在时间紧张的情况下正确的暴力解远胜于有bug的“最优解”。我见过一个同学笔试时花了大半时间写一个很复杂的线段树解法结果边界写错全盘崩掉。而另一个同学用简单的排序加遍历拿到了满分。一定要记住笔试是“得分游戏”不是“炫技秀场”。5. 关于“BAT”与“bat”的澄清一题两解别弄混了5.1 BAT是三家公司的合称bat是Windows批处理脚本这里需要专门说明一个问题因为搜索热词里混了两个方向。“BAT”在互联网圈里是百度、阿里巴巴、腾讯三家公司的合称B取自百度BaiduA取自阿里巴巴AlibabaT取自腾讯Tencent。2015年的时候这三家公司几乎垄断了互联网行业最优质的实习生岗位和技术资源所以“BAT笔试”特指这三家的校招和实习笔面试。而小写的“bat”是Windows系统里的一种批处理文件扩展名全称batch file。简单说就是把一堆Windows命令行命令写进一个文本文件保存为.bat后缀双击就能按顺序执行。很多人想搜“BAT笔试”却搜成了“bat批处理”其实是一字之差的乌龙。如果你本来是想找Windows批处理脚本的用法下面这些内容才是为你准备的。5.2 bat批处理文件究竟能做什么几个实用场景bat批处理文件在本质上就是“把多条cmd命令打包成脚本”让计算机自动执行重复性操作。它最常见的用途包括批量重命名文件、批量复制备份、定时清理垃圾文件、一键启动或停止服务、模拟按键、开机自动启动项目等。举个例子搜索热词里有“bat批量重命名文件ren”Windows里ren命令的语法是ren 旧名 新名单独用的话一次只能改一个文件。但结合for循环就能实现批量操作。比如把当前目录下所有.txt改成.bak命令行里写for %i in (*.txt) do ren %i *.bak如果写成bat文件变量要用两个百分号echo off for %%i in (*.txt) do ren %%i *.bak echo 完成 pause这个双百分号的坑让很多第一次写bat的人在本地命令行里测试没问题一存成bat就报错原因就在这里。再比如热词里“谷歌浏览器多开txt转bat”本质就是先新建一个txt输入启动谷歌浏览器的多行命令再把txt后缀改成.bat双击执行。谷歌浏览器默认是多进程架构但多开多个独立的浏览器实例需要借助--user-data-dir参数指定不同的用户数据目录。bat内容可以写成echo off start chrome.exe --user-data-dirC:\chrome_profile1 start chrome.exe --user-data-dirC:\chrome_profile2 start chrome.exe --user-data-dirC:\chrome_profile3保存为bat并双击就能同时打开多个互相独立的Chrome窗口每个窗口的登录状态、扩展、缓存互不干扰。这个技巧在处理多账号场景时非常实用。5.3 顺手能用到的批处理模板示例如果只是想体验一下bat的威力这里提供一个安全、无破坏性的简单示例一键清理Windows临时文件。新建一个txt粘贴以下内容保存后把后缀改为.bat右键以管理员身份运行echo off echo 正在清理临时文件... del /q /f %temp%\*.* 2nul del /q /f C:\Windows\Temp\*.* 2nul echo 清理完成。 pause注意这个脚本只清理当前用户的临时文件夹和系统的临时文件夹不会触碰你的个人文件但任何清理类操作都建议先备份重要数据以防误删。另外一个常见问题是bat文件里的中文乱码通常是因为编码不对。bat文件默认采用ANSI编码如果你用UTF-8编码保存中文提示就会变成乱码。解决方法是要么用ANSI编码保存要么代码里全部用英文提示如图中的echo done这类。开头热词里还有一个“smapi bat 打不开”的问题这类情况常见原因有三个一是文件扩展名保存成了.bat.txtWindows默认隐藏扩展名很可能你没意识到二是文件路径或文件名中包含中文或空格而bat里调用的命令没有加引号导致解析失败三是被系统安全策略拦截Windows SmartScreen可能会阻止未签名的bat文件运行。我的建议是先确认文件扩展名是.bat而不是.bat.txt再右键选择“以管理员身份运行”最后再考虑用记事本或其他编辑器重新转换编码或检查内容。这些虽然是小问题但能解决很多新手在bat之路上的第一个阻碍。关于“请帮我生成一段bat批处理代码用于优化Windows系统的游戏性能”这类需求我补充一个温和但不破坏系统稳定性的示例。真正“优化游戏性能”涉及数十项系统参数调整风险较高不建议直接把网上抄来的注册表脚本一键运行。保守的方案是先做系统临时文件清理再切换电源模式为高性能再清理网络DNS缓存这三步都是安全操作对游戏体验会有一定改善echo off echo 正在清理系统临时文件... del /q /f %temp%\*.* 2nul echo 正在切换电源模式为高性能... powercfg /setactive 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c echo 正在刷新DNS缓存... ipconfig /flushdns echo 优化完成建议重启电脑后生效。 pause如果电源模式GUID执行失败可以先运行powercfg /list查看你电脑上可用的电源计划GUID再替换成你机器上的高性能计划GUID。这些操作不会删除系统文件也不会修改注册表相比网上一键“游戏加速”脚本安全得多。如果你是为了准备大厂笔试来的请记住刷这份卷子的目标不是背答案而是通过它检验自己的知识框架是否完整、代码能力是否扎实、工程思维是否有雏形。这份2015年的卷子在今天看来技术栈已经有些年头了但它的考察逻辑到今天仍然成立——基础、算法、思维永远是技术面试绕不开的三大支柱。而如果你是因为想学批处理误入这篇文的那也恭喜你把一个低调但高效的小工具纳入了技能包。很多重复性工作无论是在Windows上批量处理文件还是写个小脚本自动清理系统都可以用bat一键完成。这两种“BAT”我都在各自的战场上踩过坑、填过坑。希望这篇复盘能帮你少走一点弯路。