ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

从网易2017春招笔试编程题看校招算法面试的五大关键能力

从网易2017春招笔试编程题看校招算法面试的五大关键能力 拿到这份网易2017春招笔试编程题我看到的不是题目而是这五件事又是一年春招季群里不少学弟学妹在问网易的笔试编程题该怎么准备。翻出当年整理的那套2017春招笔试真题说实话距离现在过去这么多年具体题目早就不是当年的样子了但这套题背后考察的逻辑、出题人想筛选的能力以及刷题时绕不开的那些坎直到今天依然有很强的参考价值。网易的笔试编程题历来不走极端偏难怪路线它更看重的是基础功扎不扎实、边界条件想得全不全、在限时压力下能不能写出可运行的代码。如果你正准备投递互联网公司的技术岗无论目标是不是网易这套题都值得认真过一遍。本文不打算做逐题搬运式的题解那在牛客网上都能找到我更想聊的是这套题到底在考什么、每类题型的破解思路是什么、笔试现场的时间怎么分配以及从这些真题里能反推出网易这样的公司到底想招什么样的人。1. 拿到卷子先别急着写2017春招笔试题的整体观感1.1 题量、时间与难度梯度决定了你该用什么策略网易2017春招的笔试编程题整套下来给我的第一感觉是不是让你一道题憋到天荒地老而是考察你在有限时间内如何做取舍。当时是牛客网在线笔试编程大题大概4到5道加上前面的客观选择题整体时间大约两到三个小时。这个配置意味着每道编程题留给你的时间并不宽裕如果你在前面某道题上死磕超过四十分钟后面的题目大概率会来不及。从难度分布来看这套题有明显的梯度设计。第一道或者第二道通常是字符串处理或者简单模拟属于热身题只要思路清晰、代码不出低级错误基本能拿下。中间的题目会混入一些需要动脑的贪心或者动态规划这类题区分度最高——会做的人十五分钟搞定不会的人盯着题目半小时也无从下手。压轴的题往往带有一些数学性质或者思维陷阱表面看是常规题实际上需要绕一个弯才能想到最优解。1.2 这套题最鲜明的两个特点边界条件多、暴力解法会超时翻看当年的题目和大家的复盘讨论有两个高频关键词几乎贯穿所有编程题边界条件和复杂度。网易的题目很喜欢在输入范围上做文章比如数组长度到10的5次方、数值范围很大、字符串可能有空串等等。这些设置看似无关紧要实际上是在提醒你别想用暴力解法糊弄过去同时也别忽略了空输入和极端值。我当年就栽过一个跟头。有一道题逻辑很简单就是按规则处理字符串我写完自测用例都通过了但提交后总是报错。后来排查才发现我忽略了字符串可能为空的情况这一下就导致数组越界。这种错误在校招笔试里特别典型因为本地自测的用例往往是自己构造的正常情况而评测系统里藏着各种刁钻的边界用例。1.3 语言选择和本地环境其实比想象中更重要另一个容易忽略的点是编程语言和本地环境的准备。网易的在线笔试系统支持主流语言C、Java、Python都可以但如果你习惯用Python要特别注意运行效率的问题。有些题目如果你用Python的常规写法在大数据量下可能超时这时候就得考虑用一些技巧来优化或者干脆换用C/Java来实现。我当时用的主力语言是C这套题做下来整体感觉比较顺手。如果你对C不熟用Java或Python也完全没问题关键是要熟悉这门语言在竞赛环境下的常用写法比如Java的快速输入输出、Python的sys.stdin读取等等。别小看这些细节笔试现场每一秒都很宝贵如果因为输入输出写法不熟练多花了五分钟那后面题目的时间就更紧张了。2. 字符串处理与模拟类题目最容易翻车也最容易拿分2.1 为什么这类题是兵家必争之地在网易2017春招这套题里字符串处理和模拟类的题目占据了相当大的比重。这类题往往放在比较靠前的位置难度不大但非常考验细心程度。说白了这类题拼的就是你能不能把题目描述的逻辑100%转换成代码中间不出任何偏差。拿当年的一道题来举例大意是需要对给定的字符串做某种规则变换比如根据字符出现的次数重新排序、或者按照特定的编码规则生成新字符串。题目本身的思路很直白遍历字符串、统计信息、按规则处理。但真正写代码的时候你会发现有很多细节需要小心处理字符串下标从0开始还是从1开始、大小写是否需要区分、变换之后是否要处理连续相同字符的情况、输出格式有没有特殊要求等等。2.2 一个典型的样例推演从题目描述到代码实现我拿一道比较有代表性的题目来推演一下这类题的标准解法思路。假设题目是这样给定一个字符串要求将其中每个字符替换成它在字母表中往后数第N个位置的字符如果超过z则从a重新开始。这看起来非常简单对吧但如果你直接写ch N当N很大的时候就可能溢出而且如果N是26的倍数那所有字符其实都不变。正确的做法是先将字符偏移量映射到0到25的范围内也就是(ch - a N) % 26 a。这还只是最基础的版本。如果题目再增加一点难度比如大小写混合处理、非字母字符保持不变那你要考虑的边界情况就更多了。这种题本质上就是把数学问题转化成代码逻辑你要是忽略了对N取模这一步大数据量下必然出错。2.3 我用血泪换来的三个字符串题避坑点第一注意输入读取方式。网易的笔试系统输入通常有多行有时候同一行包含多个参数有时候参数分散在多行。如果你用C的cin s读取字符串而题目里字符串可能包含空格那就要改用getline。这个地方翻车的人非常多。第二输出格式严格匹配。题目要求每个结果占一行那你就老老实实换行不要多打空格也不要漏掉换行。第三自测的时候多造边界数据。空字符串、单字符字符串、全相同字符的字符串、超长字符串这几种情况一定要在本地测一遍因为评测系统里大概率真的有这些用例。3. 动规与贪心这类会做但过不了的题到底差在哪3.1 看似是贪心实则需要动态规划的经典陷阱网易2017春招的题目里有不少题表面上是贪心可以解的但实际上需要动态规划才能拿到满分。这种贪心动规二象性的题是最容易让考生纠结的。有一个很典型的场景题目给出一组物品或者任务要求你选择其中若干个使得某种收益最大化。如果你凭直觉按照某种规则优先选择可能在小数据量下是对的但一旦数据量变大、情况变复杂贪心策略就会在某个角落翻车。为什么这类题容易让人产生贪心可行的错觉因为贪心策略的代码写起来特别简单而且对于题目中给出的示例用例贪心往往是能通过的。那面试官想考察的是什么是你有没有能力判断当前问题是贪心还是动规以及你愿不愿意多花时间去验证贪心的正确性。如果题目数据范围比较小用贪心加上枚举可能也能过部分测试用例但想拿全分还是得老老实实写状态转移方程。3.2 一道题看懂状态设计从暴力递归到动态规划的演变拿一道经典问题来拆解假设有N个任务每个任务有开始时间、结束时间和收益任务之间时间可能重叠要求选择一组互不冲突的任务使总收益最大。最暴力的做法当然是枚举所有子集但N稍微大一点就会爆炸。再进一步可以按照结束时间排序然后对每个任务考虑选或不选用递归来暴力搜索。但这个搜索树是指数级的依然不行。这时候就要想到动态规划。设dp[i]表示前i个任务能获得的最大收益那么对于第i个任务要么不选dp[i] dp[i-1]要么选它那就要找到在它开始时间之前结束的最后一个任务j此时dp[i] dp[j] value[i]。这个状态转移方程本质上就是把选和不选两种决策量化成递推关系。难点在于怎么快速找到这个j这里又可以引入二分查找来优化。这种环环相扣的思路就是一道典型的校招中等难度题。3.3 关于复杂度优化你必须养成的肌肉记忆这套题里几乎每道题都在暗示你如果你写出的解法时间复杂度是O(n^2)而n已经到10^5那这个解法肯定不是最优解。校招笔试的机器评测环境通常有严格的时间限制大多数题目要求在1到2秒内跑完所有测试数据O(n^2)在10^5量级下是必挂无疑的。我见过很多同学其实想到了正确的算法思路但就是因为复杂度优化没做到位而丢分。比如用两层循环去找某个前缀信息其实可以提前用一个哈希表或者前缀和数组提前算好比如每次都要重新排序其实可以提前排好一次。这些优化说起来很容易但考场上紧张起来就容易忽略。平时刷题的时候一定要养成先估算复杂度的习惯看到题目数据范围立刻在脑子里过一遍我的这个算法在最大数据量下能不能扛得住。这个习惯比多做几道题重要得多。4. 限时笔试的节奏控制从时间分配到边界自测4.1 拿到题目后前五分钟应该做什么很多人一进笔试系统看到题目就开始敲代码这是大忌。我个人的习惯是前五分钟先把所有编程题都扫一遍对每道题的难度有个预判。这种预判不是玄学而是基于题目描述的长度、数据范围的大小、以及对题型类别的初步感知。第一道题如果是字符串处理大概率是送分题中间出现那种题目描述特别长、还带各种限制条件的往往是有区分度的题最后一道题如果数据范围特别大很可能需要一些数学推导。把题都扫过一遍之后我会定一个粗略的时间计划送分题每题控制在20分钟以内中等题每题控制在30分钟左右难题留到最后攻坚但最多花40分钟超过时间就果断放弃。这个计划听起来很机械但在笔试现场有一个明确的时间分配表能够极大地减少焦虑感。我见过太多人栽在时间管理上前面简单题写得太快导致粗心出错调试浪费了大量时间后面难题明明会做却因为时间不够而遗憾收场。4.2 自测用例怎么造才有效不是随便写两个就算测过很多同学写完代码之后拿题目给的示例跑一遍发现输出对了就迫不及待地提交。这是非常危险的行为。题目给的示例通常只是正常情况下的一个代表远远覆盖不了所有边界条件。我自己有一个固定的自测清单每次写完题都会快速过一遍最小输入比如N1或者字符串长度为1甚至空输入。最大输入构造一个接近数据范围上限的用例看会不会超时或者溢出。重复元素比如数组里所有值都相同这种情况往往能暴露排序或去重逻辑的问题。极端顺序比如数组本身已经升序或者降序一些排序算法或者贪心策略可能在极端顺序下表现异常。负数或零如果题目里数值范围包含负数要特别检查。这套自测流程大概也就花三到五分钟但它能帮你拦下很大一部分提交报错。尤其是那些数组越界、整数溢出、死循环之类的低级错误靠肉眼很难发现但构造对应的测试用例一跑就能暴露。4.3 debug的正确姿势不要盯着代码看要打日志笔试过程中遇到bug是再正常不过的事情。我发现很多同学卡在bug上不是因为他们代码能力不行而是debug的方式太低效。他们就盯着代码一行一行看试图用肉眼找出问题。这种方法在代码短的时候可能有效但一旦代码超过几十行效率就极低了。我的做法是遇到输出不对的情况如果在五分钟内找不出原因就直接在关键位置打印中间结果。比如循环变量、状态转移方程里的dp值、排序后的数组等等然后把打印结果和手算的期望值对比这样往往能很快定位到是哪个环节出了问题。笔试系统的编译器支持调试输出只要提交之前记得把这些日志删掉就行。省下时间多调试几轮比你坐在那里干瞪眼有效得多。5. 真题背后的信号网易想招什么样的工程师5.1 从题目风格看公司的技术文化刷完网易2017春招这套编程题我最大的感受是网易的题目很务实。它不会出那种特别偏门、需要背特定算法模板才能解出来的题反而很注重对基础数据结构和基础算法思想的理解。字符串处理、排序、二分查找、简单的动态规划和贪心这些在岗位日常开发中真正能用到的能力才是出题人想考察的重点。这和网易本身的业务调性也有关系。网易的技术栈比较多元游戏、音乐、电商、教育等业务线都有不同业务线的开发需求差异很大。但在校招笔试这个环节它没法针对每个岗位都出差异化极大的题目所以只能选择考察通用能力。这也反过来提醒我们与其去赌那些冷门算法会不会考不如把高频数据结构和算法练扎实这样无论遇到什么题都有应对的底气。5.2 这几类基本功练好了比背题更重要如果你后续要参加网易或者其他大厂的笔试我的建议是集中火力练这几块第一字符串处理。这是笔试编程题里的常青树各种规则变换、匹配、统计层出不穷。第二排序和二分。它们是很多复杂算法的基石熟练掌握sort的自定义比较函数、二分边界处理能帮你快速解决一大片问题。第三动态规划和贪心。这是区分度最高的部分但你不需要掌握那些竞赛级别的变态动规能把背包、最长上升子序列、区间DP这类常见模型吃透应付校招绰绰有余。第四简单图论和搜索。DFS、BFS、拓扑排序这些基础操作要熟练到不需要思考就能默写出来的程度。用我自己的话说校招笔试就是一场基础功大阅兵。你的代码风格干不干净、边界意识强不强、复杂度估算准不准全都会在评测数据里原形毕露。从17年到现在这套筛选逻辑基本没变过。5.3 举个例子一道需要绕弯的题考察的是思维惯性最后说一道当年让我印象很深的题。那道题猛一看是一个普通的模拟题按部就班地处理流程就能得到结果但如果你真的傻乎乎地去模拟每一步在数据量大的时候就会超时。正确的解法是发现这个模拟过程存在周期性或者可以通过数学公式直接算出答案。这种题考察的不是你会不会写代码而是你能不能跳出惯性思维。很多人在笔试的时候看到题目描述长、操作步骤多就下意识地开始模拟完全没想过是否可以利用周期或者公式化简。这道题给我的启发是当你觉得自己的解法代码很长、逻辑很绕的时候停下来想一想是不是有更简单的数学规律藏在背后。这种停下想想的能力恰恰是校招笔试最想考察的思维品质之一。整套网易2017春招笔试编程题刷下来我最大的收获不是记住了某几道题的解法而是养成了一套应对限时编程的完整方法论先扫题定策略再动手写代码写完认真造边界用例遇到bug用日志快速定位每道题都估算复杂度。这套方法论陪我走过了之后很多场笔试希望也能帮到你。
返回列表