ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

华为2016校招机试真题解析:题型考点与备考策略

华为2016校招机试真题解析:题型考点与备考策略 华为2016校园招聘上机笔试题这个题目放到今天看已经算是一代人的集体记忆了。那几年互联网还没像现在这么卷华为校招的流程相对固定网申、笔试、上机、性格测试、面试。其中上机笔试是刷人最多的一关也是很多非科班同学第一次正经在OJ上做算法题。我当年备考的时候翻遍了网上能找到的2016年机试题目和师兄师姐的面经后来也帮好几个学弟学妹梳理过类似题目。今天干脆把这类题目的考法、考点、经典题型和答题技巧一次性整理出来给准备华为机试或者类似大厂笔试的朋友做一个参考。这篇文章不会列一个标准答案合集因为华为的机试题库年年换2016年的原题就算留着也未必会再考。但万变不离其宗它考察的核心能力、题型分布、评分规则、答题陷阱这些年基本没怎么变过。看懂这篇你就知道这类上机考试到底在考什么以及怎么练才高效。1. 华为2016校招机试考情分析1.1 考试形式与使用环境先说考试形式。华为2016年校园招聘上机笔试采用的是在线OJ系统考生在指定考场统一登录在规定时间内完成三道编程题。考试时间我记得比较清楚90分钟左右不同批次可能有细微差异。语言支持C、C和Java个别批次可能支持其他语言但主流就是这三个。虚拟机环境比较老旧编译器版本不高所以代码里别用什么太新的语法特性免得本地能跑、提交就编译报错。这里我建议备考的时候一律用Java或者C不要想着用Python。虽然现在华为OD机试部分批次支持Python但2016年那个阶段Python在OJ系统里支持不稳定而且考场上你没法确认编译器版本和第三方库情况。老老实实写Java或者C稳一点。评分规则是重点。华为机试不是按通过率给分的而是按测试用例给分。也就是说系统里有若干组测试数据你的程序跑通几组就给几分一个用例不过就扣对应的分数。三道题的分值一般是100分、200分、300分总分600分也有说法是100分、200分、300分制或者是60分及格线不同批次略有出入。但规律是明确的第一题最基础第二题中等第三题拉开差距。提示华为机试一般有及格线没过线直接淘汰没有面试机会。所以机试不是冲刺题而是保底题。先把前两道稳拿再去啃第三道这是最稳妥的策略。1.2 三道题的结构与常识2016年华为机试的三道题基本遵循“简单字符串处理 → 中等逻辑模拟 → 复杂算法设计”的递进结构难度阶梯明显。第一题通常考察基本功常见类型包括字符串反转、数字进制转换、字符统计、简单数组去重稍微绕一点的也就是字符串子串匹配。这类题本质上是语言基础不涉及复杂算法只要平时写过几十道LeetCode简单题基本都能在15分钟内搞定。第二题开始有点意思了通常是数组操作、排序规则自定义、矩阵处理、特定格式解析或者一个中等难度的模拟题。它考察的核心是“读题是否仔细、逻辑是否严密、数据结构是否选得对”。很多人挂在这题上不是因为不会写而是题目里藏了边界条件比如空输入、数组越界、排序规则里某个特殊字段没注意就全盘崩掉。第三题是真正的分水岭。2016年前后常考的方向有背包问题变种、状态压缩DP、贪心策略题、图的最短路径偶尔有并查集。它不一定是算法竞赛那种级别的难但对于校招生来说能现场写出来完整、正确、没有超时的代码已经能淘汰掉一大半人了。很多人第三题只看一眼就放弃了其实这里有个技巧就算不能AC也可以根据部分测试用例的特点写一个暴力解法拿部分分。2. 核心考点与命题规律拆解2.1 字符串处理为什么是必考题纵横华为机试题库字符串永远占一席之地2016年也不例外。为什么大厂笔试这么偏爱字符串因为字符串处理最能综合考察语言基本功、边界思维和代码简洁度。一个简单的字符串反转看起来简单但你得考虑空格怎么处理、空串怎么办、多组输入输出格式是否匹配。一个字符串压缩连续字符的题就足够筛掉一批只会背API的选手。我整理了几道2016年流传比较广的字符串类题目帮你找找感觉。第一道是“求字符串最后一个单词的长度”。题目描述很简单输入一行字符串单词间以空格分隔输出最后一个单词的长度。考察点其实就一个字符串按空格切分或者反向遍历。有人直接用split代码三行。但如果末尾有多个空格split之后数组末尾会出现空字符串你要注意去掉。这种细节就是典型的测试用例陷阱。第二道是“字符串加密或解密”。2016年的题库里出现过类似凯撒密码的题输入明文和偏移量输出密文或者反过来。这类题需要你处理字母循环并且统一大小写逻辑。核心公式就是(ch - base offset) % 26 base其中base是A或者a的ASCII值。注意点是负数取模很多语言里负数取模结果还是负数写的时候要先加26再取模。第三道是“字符串字符个数的统计与排序”。输入一个字符串按字符出现次数从高到低排序输出次数相同按ASCII码升序。这题看着简单但排序规则一复杂就容易出错。推荐的做法是用HashMap统计再把entry塞进List里写Comparator。考场上如果你对Comparator不熟可以改成桶排序的思路或者用数组下标做统计更稳妥。2.2 排序与自定义规则的考察频率排序在2016年华为机试里出现的频率极高。但很少考察直接调Arrays.sort()那种基础排序而是大量考察“自定义比较规则”。比如按学生的总分排序、按字典序排序后输出或者按条件优先级的顺序多级排序。有一道流传很广的题“成绩排序”输入学号、姓名、成绩按照成绩从高到低输出如果成绩相同按学号从小到大排。如果只在笔试阶段做这题就是水题。但机试环境里你得自己写好输入解析、对象定义、比较器还得处理多组用例这些操作用5分钟写完不出错真不是人人能做到的。这里我给一个通用的Java排序做法。定义一个内部类实现Comparable接口然后重写compareTo方法里面把多级排序规则写清楚。或者用Comparator.comparing链式比较。Java 8里的Comparator.comparing(Student::getScore).reversed().thenComparing(Student::getId)这种写法在机试环境里不一定兼容保险起见还是手写比较器。注意机试环境里的Java版本多半是Java 7甚至更早lambda表达式和函数式接口可能用不了。备考时尽量写传统写法不要依赖高版本特性。2.3 模拟题是第二题的主流形态第二题最常见的题型其实是“模拟”。说白了就是题目设定一个场景或规则让你照着流程一步步算下来。这类题目不考高深算法但很考验细致的逻辑拆解能力。比如2016年出现过的一个版本“验证密码是否合格”规则包含长度、字符种类、不能有重复子串等好几条。你需要把每一条规则单独写成一个判断函数然后逐个检查哪条不满足就返回失败原因。这种题最大的坑在于规则之间可能存在优先级关系。比如密码长度不合格时是直接输出“NG”还是先检查其他规则题目描述可能就一句话带过但测试用例是按特定顺序设计的。你没按预期顺序输出就是0分。我在做这类题时习惯先把题目里的规则全部抄到草稿纸上逐条编号然后再动手写代码。写着写着发现有些规则可以用同一个循环解决就合并不能合并的就拆独立函数。写完后再把每条规则的典型边界数据测一遍比如空串、超长串、恰好满足条件的数据。这样能避免大量低级失误。模拟题还有一个变种是“矩阵操作”比如矩阵旋转、Z字形打印、螺旋输出。华为2016年的题库里出现过螺旋矩阵打印输入n生成n×n的螺旋矩阵并输出。这题核心是控制上下左右边界循环打印。有个通用写法定义四个边界变量top、bottom、left、right每次打印完一行或一列就收缩边界直到相遇。这种写法背下来遇到类似题目直接套就行。2.4 第三题的算法难度与训练方向第三题的技术含量是实打实的2016年前后方向集中在贪心、动态规划、搜索和图论。我挑几个典型方向说一下。贪心题里常考“活动安排”“最少硬币数”“区间覆盖”之类的变体。比如有“多任务调度”题每个任务有开始时间和结束时间问最多能完成多少个任务。思路是按结束时间排序然后依次选择不冲突的任务。这类题的关键是先证明或者至少猜出贪心策略是对的然后再写。很多人在考场上写了一个“看着挺对”的贪心策略但贪心策略本身选错了测试用例就会精准地打脸。动态规划题里常考“背包问题变种”“最长递增子序列变体”。2016年出现过一道“砝码称重”类型的DP题给定若干种重量的砝码每个砝码数量有限问能称出多少种不同的重量。解法是用布尔数组来标记可达重量每个砝码逐个更新数组。状态转移是dp[w] dp[w] || dp[w - weight[i]]。这题如果不会DP背包问题解法写不出来暴力DFS会超时基本就拿不到分。搜索题就更直接了BFS迷宫最短路径、DFS连通块计数。有个经典题“迷宫问题”给定二维矩阵0表示可走1表示墙求从起点到终点的最短步数。BFS模板背熟基本就是套模板的事。但机试有个细节输入矩阵时每行是一个没有空格的字符串你必须先读到String再转成char数组而不是用nextInt去读。这个输入差异备考时没练过考场上很容易卡死。图论题里最常考的还是最短路径和最小生成树。不过2016年第三题考到图论的频率不算最高通常作为压轴题的备选。如果时间不够我的建议是优先刷DP和BFS这两个上手快、模板固定、性价比高。3. 三道典型真题的解题思路拆解3.1 第一题简单字符串处理实例我拿一道流传较广的2016年真题“字符串反转打印”来拆解。题目要求输入一个字符串将其反转后输出但要求单词内部的字母顺序不变只反转单词之间的顺序。比如输入I am a student输出student a am I。这种题其实有两种做法。第一种是整体反转再逐词反转是经典的算法思路。第二种更直观先按空格拆分成单词数组然后从后往前拼接。我推荐第二种代码短不容易错但需要处理多个连续空格的情况。机试版本的题目里通常说明单词间以单个空格分隔所以直接用split( )是安全的。如果没说明就改用正则split(\\s)。这里有一个非常容易踩的坑输出格式。题目可能要求每个单词之间以单个空格分隔并且末尾不能有空格。如果你用循环拼接最后要多加一个判断别让它多打一个空格。别小看这个细节一个用例的格式分可能就没了。下面是参考实现Javaimport java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc new Scanner(System.in); while (sc.hasNextLine()) { String line sc.nextLine().trim(); if (line.isEmpty()) { System.out.println(); continue; } String[] words line.split( ); StringBuilder sb new StringBuilder(); for (int i words.length - 1; i 0; i--) { sb.append(words[i]); if (i ! 0) { sb.append( ); } } System.out.println(sb.toString()); } sc.close(); } }这段代码里有个细节split( )对多个连续空格处理不太好如果题目没有明确说单词间只有一个空格建议改成split(\\s)对制表符也能兼容。还有trim()去掉首尾空格是为了避免末尾空格导致数组末尾多一个空字符串。这些习惯养成之后机试里很多字符串题都能顺带避坑。3.2 第二题自定义排序实例2016年第二题常考的“成绩排序”我详细说一下。题目描述通常是输入若干行每行包含姓名和三科成绩按总分从高到低排序总分相同的按语文成绩降序再相同按姓名字典序升序最后输出姓名和总分。这题数据结构和排序规则是核心。我的做法是定义一个Student类字段包括name、chinese、math、english然后计算一个total字段。排序的时候直接用Comparator把比较规则一步步串起来。写成代码大概是class Student { String name; int chinese; int math; int english; int total; } Collections.sort(list, new ComparatorStudent() { Override public int compare(Student s1, Student s2) { if (s1.total ! s2.total) { return s2.total - s1.total; // 总分降序 } if (s1.chinese ! s2.chinese) { return s2.chinese - s1.chinese; // 语文降序 } return s1.name.compareTo(s2.name); // 姓名升序 } });这里有一个容易忽略的点输入行的数量不确定需要持续读到EOF。Java中就是while (sc.hasNext())。如果你只读一次那就只能过一组用例其余全挂。这种多组输入的处理是所有OJ类考试的基本功2016年华为机试也一样几乎所有题目都是多组输入。另外排序稳定性也要留意。如果题目要求“总分相同按输入顺序输出”而你的排序算法不稳定结果就会出错。Java的Collections.sort是稳定的归并排序但如果你自己写了快排就得小心。稳妥起见我建议遇到“按输入顺序”这种要求时给每条记录加一个序号字段作为最后一级比较条件彻底避免稳定性问题。3.3 第三题动态规划实例第三题我拿“砝码称重”来拆解因为它很典型而且网上流传的2016年版本跟这题很接近。题目大意输入砝码种类n每种砝码的重量数组w[]和数量数组c[]问用这些砝码能称出多少种不同的重量。解题思路是用一个boolean数组dp[]dp[i]表示重量i是否可以被称出来。初始化dp[0] true。然后遍历每种砝码再遍历该砝码的数量逐个更新数组。核心代码int maxWeight 0; for (int i 0; i n; i) { maxWeight w[i] * c[i]; } boolean[] dp new boolean[maxWeight 1]; dp[0] true; for (int i 0; i n; i) { for (int j 1; j c[i]; j) { for (int k maxWeight; k w[i]; k--) { if (dp[k - w[i]]) { dp[k] true; } } } } int count 0; for (boolean b : dp) { if (b) count; } System.out.println(count);这里有个关键点内层循环一定要从大到小遍历重量。如果你从小到大遍历同一个砝码会被重复使用导致“使用次数超过c[i]”这种非法情况。这跟01背包问题的优化思路一模一样。机试中这种细节如果没想明白代码跑出来结果永远偏大而且你根本找不到bug。再补充一句如果maxWeight很大比如上万甚至更大boolean数组会占比较多内存。但机试一般不会给那么大的数据真遇到的话可以用HashSet来存可达重量用集合的add操作代替数组标记。不过HashSet在数据量大时性能不如数组考场时间有限能用数组就用数组。4. 机试实战中的高频踩坑点4.1 输入输出格式问题机试跟平时自己在IDE里跑程序最大的不同就是输入输出格式卡得很死。2016年华为机试的输入是标准输入流输出必须精确匹配包括空格、换行、空行。我见过太多人思路完全正确却在输出格式上丢分。比如要求输出“结果之间用空格分隔”结果你用了逗号要求每组输出占一行结果你多打了一个换行要求数字之前补零你直接输出原数字。这些错误在测试用例里都会导致该组用例判错没有任何商量的余地。所以在写完代码后一定要做一次输出格式自查。问自己几个问题末尾有没有多余的空格换行符是不是只在该出现的位置空数据输入时程序会不会异常退出多组输入时输出是不是容易粘连在一起另外每次提交前建议在本地把样例输入手动测一遍包括最基础的样例、边界样例、稍大规模的样例。如果你的程序能全部通过再提交。这一点看上去很基础但考场上很多人紧张起来连样例都不测就直接交结果因为一个小失误丢了大分。4.2 多组输入与EOF处理华为机试的题目描述经常写“输入包含多组测试用例”但不会明确告诉你多少组。如果你只处理一组就结束程序后面的用例全部判错这是最可惜的丢分方式。Java里处理多组输入标准写法是while (sc.hasNext()) { // 处理每组逻辑 int n sc.nextInt(); int[] arr new int[n]; for (int i 0; i n; i) { arr[i] sc.nextInt(); } // 计算结果并输出 }C里类似就是while (cin n)。C语言则是while (scanf(%d, n) ! EOF)。这三种写法是机试的基本功。平时练习时一定要形成肌肉记忆看到“多组输入”就直接套用。还有一种情况是题目要求一次读完然后输出所有结果。这时候可以用一个List暂存所有输出最后统一输出避免在循环里反复打印导致效率问题。Java里System.out.println本身性能尚可但如果循环里打印上千次也可能超时。更稳妥的写法是用StringBuilder拼接所有结果最后一次性输出。4.3 数据结构选择不当引发的超时有些同学明明算法思路正确却因为数据结构选错了导致超时。最典型的例子是查找某个元素是否存在时用List的contains方法时间复杂度O(n)。如果在一个循环里反复调用整体复杂度直接升到O(n²)数据一大就超时。正确做法是能用HashSet或HashMap就用查找复杂度降到O(1)。比如字符串字符去重、统计频次、判断是否存在等场景都应该用哈希结构。2016年机试的数据规模一般不大但第三题如果涉及搜索和优化数据结构选错一样会卡死。另一点是数组和集合的选择。机试里能用数组就用数组因为数组的访问速度最快。但动态添加数据时ArrayList更方便。我的习惯是已知大小用数组未知大小用ArrayList判断存在用HashSet键值对应用HashMap。把这些用熟考场才能快速作出选择。4.4 边界条件与空输入边界条件是我认为机试丢分最冤的地方。几乎每道题都有几个边界测试用例专门用来考察你有没有认真处理特殊情况。我整理一个边界条件自查清单字符串输入是否可能为空串或者只包含空格数组长度是否为0或1数字是否可能出现负数或者0是否可能包含重复元素最大值是否超出int范围要不要用long矩阵输入是否可能只有一行或一列树或图的节点数是否为0每次写完代码按照这个清单逐个检查能帮你在交卷前找出很多隐藏问题。2016年华为机试的第一题就有人因为没处理空字符串输入导致数组访问越界白丢一个用例。我曾经在模拟测试时遇到过一道题输入一个字符串要求把所有空格去掉并输出。我直接用小技巧遍历字符凡是空格就跳过。简单吧但系统测试用例里有一个全空格输入我的程序输出的空串看起来没问题。但如果题目要求输出一行空行而不是什么都没有那就不一样了。这种“空输出也是输出”的细节一定要看题目要求。5. 时间分配与做题策略5.1 先保前两题再拼第三题机试的时间很宝贵。我的策略是拿到题目先全部看一遍花两分钟判断每道题的难度。然后直接从第一题开始做做完马上做第二题确保前两题尽可能拿满分。最后再集中精力啃第三题。如果第三题做不出来就把能拿的暴力分拿上然后回头检查前两题。这里多强调一句前两题的分数一定不能丢。2016年华为机试中第三题满分300分但能AC的人比例并不高。如果你前两题全对第三题哪怕只拿一半分总分也能到400分以上这个分数在多数批次都算有竞争力的。相反如果你前两题没稳第三题再牛也很难弥补。5.2 时间段的分配建议按照90分钟来算我建议的时间分配是前5分钟通读三道题标记出关键词、输入格式、边界要求第一题10分钟调试完成最多不超过15分钟第二题25分钟调试完成最多不超过35分钟第三题预留30到35分钟思考加编码最后10分钟统一复查输入输出格式和边界用例这个计划看着很简单但很多人在第一题上就卡了20分钟。为什么因为第一题读题不够仔细写着写着发现理解错了推倒重来。所以第一题就算简单也要先花一分钟把题目读懂再动手。5.3 读题的两个小技巧读题是机试里最不被重视却最重要的环节。我总结了两条实用技巧第一条题目中的每个条件都要圈出来。比如“最多”“至少”“不存在”“升序”“降序”“不区分大小写”“最后一个”这些词往往是出题人埋的坑。漏掉一个可能就会在某个用例上翻车。第二条把题目给的示例输入输出手动推一遍。不要只看一眼就觉得懂了真的要拿笔在草稿纸上走一遍流程。这样你会发现很多题目描述里没写清楚但示例里能看出来的要求。比如某个字段是否需要补零输出示例里就能看出来。6. 应考环境准备与心态管理6.1 熟悉本地IDE和OJ系统的差异平时练习用的IDE跟机试的在线OJ系统是有差异的。最大差异在于IDE允许你自己写main方法、自己定义类、随意打印调试信息而OJ系统完全相反它只看提交代码的输出结果不允许有任何多余输出类名也必须是Main。2016年华为机试要求Java类的定义是public class Main方法签名是public static void main(String[] args)。这个细节不提前练考场上临时改类名很容易出低级错误。C/C则要注意函数返回值和打印格式。平时练习时我建议直接用在线OJ系统练比如牛客网、华为OD机试刷题平台或者LeetCode笔试模式。养成提交代码的习惯才能提前适应那种“写代码会被系统自动评测”的紧张感。6.2 考场上遇到不会的题怎么办机试不可避免地会遇到做不出的题。这时候最怕的是一头扎进去死磕结果时间全耗没了连前两道都没保底。正确做法是先跳过做后面的若时间富余回头用暴力方法尽量拿部分分。部分分的思路是什么就是根据题目数据范围的限制写一个复杂度高但正确性有保证的解法。比如第三题动态规划不会做就写DFS暴力搜虽然可能会超时但中小规模的测试用例能过也能拿不少分。只要你暴力方法写对了OJ系统按用例计分你就能拿到对应比例的分值。还要准备好应对“编译错误”的突发状况。考场上编译失败了系统会直接显示编译错误而不是运行结果。这时候别慌先看第一行错误提示多半是类名不对、少了分号、括号不匹配或者引入了不存在的包。提交前最好先在自己的本地环境编译运行一遍确认没有语法错误再交。6.3 考前一个月的刷题规划如果你现在还有一个月准备时间我的建议是按下面这个顺序刷题第一周主攻字符串处理和数组操作。把简单难度的题目刷50道左右重点练输入输出、边界条件、多组输入处理。目标是形成代码手感做到简单的题10分钟内AC。第二周主攻排序、模拟和基础数据结构。把自定义排序、矩阵操作、字符串解析这类题刷30道左右。重点练读题能力和代码组织能力。第三周主攻搜索和动态规划基础。BFS、DFS模板刷熟背包问题、最长递增子序列、编辑距离等经典DP题至少刷20道。目标是把模板背下来遇到题能快速套用。第四周全真模拟。每天固定时间做一套机试模拟题严格按照90分钟计时。做完后复盘看丢分是因为思路不会、代码写错还是细节没注意。复盘比做题更重要因为很多错误是反复出现的。7. 备考资料与工具推荐7.1 上机刷题平台备考华为机试刷题平台的选择很关键。我先说结论优先使用牛客网的华为机试专项题库和在线OJ因为有历年真题汇总题目风格最贴近。其次是LeetCode用来练算法基础和思维。至于其他小众OJ没必要花太多精力在上面。牛客网的“华为机试”模块有大量公开题目而且有题解和讨论可以看看别人的代码思路。同一个题不同人的解法差异很大尤其是输入处理和边界条件处理多浏览几个答案能学到很多细节。LeetCode的话我建议按标签刷重点刷字符串、数组、哈希表、排序、二分查找、DFS、BFS、动态规划这八个标签下的经典题。特别是动态规划LeetCode的题目质量很高多刷几道就能建立起DP的直觉。7.2 参考书与系统性教材如果基础比较薄弱还是建议先看一本系统性的算法入门教材。市面上常见的选择有《算法第4版》和《算法笔记》。我的感受是《算法笔记》更贴近国内机试风格里面的代码风格和OJ提交方式非常类似适合用来入门。而《算法第4版》的讲解更经典适合理解算法背后的原理但代码风格偏工程化和机试的简洁风格不太一样。不要贪多认真吃透一本就够了。我当年用的是《算法笔记》搭配牛客网刷题效果很理想。如果你时间紧张可以直接跳过教材从刷题中边做边补知识漏洞但效率会低一些。7.3 一套完整的练手模拟流程最后给大家分享一个我备考后期常用的模拟方法。找一个安静的环境把手机调成勿扰模式打开牛客网的真题套卷给自己设好90分钟倒计时然后像正式考试一样开始做题。做完之后先不急着看题解而是把每道题的错误原因记录下来分三类思路错误、代码实现错误、细节遗漏。思路错误意味着这类题还没吃透需要再找类似题练代码实现错误可能是变量名混淆、逻辑条件写反这类错误说明写代码不够细心细节遗漏则可能是边界情况、空输入、多组输入这些地方没处理好。我统计过多数人的丢分大头不是思路不会而是细节遗漏。所以模拟练习的核心目的就是不断暴露这些细节问题然后在下次模拟中刻意避免。你能在备考阶段犯过的错越多考场上就会越稳。华为2016校园招聘上机笔试题这个题目放在当年的语境下代表的是很多应届生跨入大厂的第一道门槛。但它的价值并不仅仅在于那道题本身而在于它逼着每一个想进大厂的年轻人把数据结构、算法基础、代码规范、边界意识这些基本功扎扎实实练了一遍。十几年过去了题型和平台可能变了但大厂机试看重的能力内核没有变。希望这篇拆解能帮你少走一些弯路在机试考场上稳住心态发挥出自己真实的水平。
返回列表