ARTICLE DETAIL

资讯详情

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

触宝科技2017校招研发笔试复盘:题型拆解与解题思路全解析

触宝科技2017校招研发笔试复盘:题型拆解与解题思路全解析 拿到“触宝科技2017秋季校招笔试研发题第三批”这个标题我第一反应是挺感慨的。触宝这家公司做输入法和通讯工具起家海外市场做得非常猛当年的校招笔试在应届生圈子里是有一定口碑的——题量适中不搞偏题怪题但每一道都在认真考察基本功。我在整理旧资料时翻到这批题顺手做了一次完整复盘发现里面的考察思路放到今天依然很有参考价值。这篇博文就针对这批笔试的题型结构、解题逻辑、实操细节和备战方法做一次系统性拆解适合正在准备校招的应届生、打算转行做研发的朋友以及想了解互联网公司技术笔试套路的同学参考。1. 先搞清楚触宝这场研发笔试到底在考什么1.1 触宝是谁为什么它的笔试值得反复研究触宝科技成立于2008年核心产品是触宝输入法和触宝电话属于典型的移动互联网工具类产品公司而且很早就把重心放到了海外。这家公司有个特点技术团队规模不算特别大但对研发人员的综合能力要求很高因为工具类产品用户量大、场景复杂代码稍微写得糙一点线上就是事故。这就导致它的校招笔试风格非常务实——不会像某些大厂那样堆一堆超纲算法题来卡人而是把基础数据结构、常见算法、语言特性、工程意识混在一张卷子里考察的是“这个人能不能直接上手写生产代码”。2017年秋季校招这批第三批笔试正好处在移动互联网竞争最激烈的时期题目设计也代表了那个阶段国内一线互联网公司对初级研发工程师的核心预期。现在回看这些考察点非但没有过时反而因为行业回归理性变得越来越重要基本功扎实、逻辑清晰、代码习惯好的人永远比只会背题的人走得更远。1.2 研发岗位笔试的三大考察维度把整张卷子拆开看触宝这批研发题基本围绕三个维度展开。第一个维度是算法与数据结构。这是所有技术笔试的重头戏占比通常在60%以上。考察的重点不是那些偏难怪题而是链表、树、字符串处理、排序、二分查找、动态规划、栈和队列这些最基础、最核心的内容。题目形式主要是选择题和编程题选择题考察对概念和复杂度的理解编程题则要求在白板环境下写出可运行的完整代码。第二个维度是语言基础与代码阅读能力。触宝的研发岗以Java和C为主所以笔试里会有不少语言特性题比如Java的HashMap底层原理、C的指针和内存管理、字符串和数组的区别、值传递和引用传递等等。这些题看似简单但非常能拉开差距——很多同学算法题做得飞起一遇到语言细节就翻车。第三个维度是工程思维与设计能力。笔试最后通常有一两道开放题可能是系统设计也可能是场景题。比如“如何设计一个短链接服务”“如何在一个海量日志系统中找出访问频率最高的IP”。这类题没有标准答案考察的是你能否把一个模糊的问题拆解成明确的技术方案是否能考虑到并发、存储、容灾等实际问题。注意这三个维度不是孤立的。一道算法题如果要求你用Java实现那么语言特性和算法逻辑就绑定在了一起写出来的代码既要正确又要符合语言惯用法。这是校招笔试和ACM竞赛最大的区别——竞赛题只求答案对校招笔试还看代码质量。2. 题型复盘每一类题背后的解题逻辑2.1 算法题高频考点的通用破题方法我在复盘这批笔试时把算法题按出现频率和权重分了三类每一类都有相对固定的破题思路。第一类是链表和数组操作。这类题以“反转链表”“合并有序链表”“找链表中倒数第K个节点”“数组去重、循环移位”等变体为主。破题方法很统一先画图走一遍流程把指针怎么动、下标怎么变彻底搞清楚再动手写代码。链表题尤其要注意空指针和头节点问题很多同学笔试挂掉不是因为思路错而是没有处理边界情况。第二类是字符串处理。常见考点是字符串反转、统计字符频率、最长公共前缀、括号匹配等。这类题的核心是掌握好索引操作和常用库函数同时注意时间复杂度和空间复杂度之间的平衡。我记得当年有个典型变体题是“把一个字符串中的每个空格替换成%20”要求在原地完成并保证空间足够。这类题考察的就是对数组扩容和指针移动的理解非常经典。第三类是动态规划和贪心。这是公认的难点但触宝这批笔试的DP题并不算难基本都是背包问题、最长上升子序列、最小路径和这类入门级变体。做DP题我有个习惯先想暴力解法画出递归树然后看有没有重叠子问题有就用缓存优化能顺推就改成自底向上的迭代写法。这个思路比直接背状态转移方程靠谱得多因为笔试现场你不可能记得住所有题的方程。下面是一个典型的最小路径和题目示例展示从暴力到DP的优化过程// 题目给定一个m*n网格每次只能向下或向右走求从左上角到右下角的最小路径和 // 解法一纯递归会超时但思路最直观 public int minPathSum(int[][] grid) { return dfs(grid, 0, 0); } private int dfs(int[][] grid, int i, int j) { if (i grid.length - 1 j grid[0].length - 1) { return grid[i][j]; } if (i grid.length - 1) { return grid[i][j] dfs(grid, i, j 1); } if (j grid[0].length - 1) { return grid[i][j] dfs(grid, i 1, j); } return grid[i][j] Math.min(dfs(grid, i 1, j), dfs(grid, i, j 1)); } // 解法二动态规划自底向上递推 public int minPathSumDP(int[][] grid) { int m grid.length, n grid[0].length; int[][] dp new int[m][n]; dp[0][0] grid[0][0]; for (int i 1; i m; i) { dp[i][0] dp[i - 1][0] grid[i][0]; } for (int j 1; j n; j) { dp[0][j] dp[0][j - 1] grid[0][j]; } for (int i 1; i m; i) { for (int j 1; j n; j) { dp[i][j] Math.min(dp[i - 1][j], dp[i][j - 1]) grid[i][j]; } } return dp[m - 1][n - 1]; }方案一和方案二的实际差别就是指数级复杂度与O(m*n)复杂度的差别。笔试时如果时间紧张我建议直接写DP版本但如果你担心推导错可以先在草稿纸上把状态转移表画出来验证一遍再落代码。2.2 语言基础题输出题和易错点才是失分重灾区这部分是整张卷子里最“阴险”的。因为它表面上看是送分题实际上每个选项都在挖坑。我总结了一下语言基础题的高频失分点集中在以下几类。第一类是Integer缓存问题。考察Integer在-128到127之间会用缓存对象的特性。第二类是String不可变性比如String s abc之后执行s.concat(d)s本身会不会变。第三类是Java的默认值规则数组元素、成员变量的默认值分别是什么。第四类是C的析构函数和拷贝构造函数尤其是涉及到深拷贝和浅拷贝的题。这些知识点教科书上都有但如果不专门整理笔试现场很容易凭感觉选错。我建议你在准备阶段用一个活页本专门记录“易错点清单”每遇到一个坑就记一条考前翻一遍比刷十道题还有用。比如“Integer 比较时超过127一定不等在-128到127之间要看缓存”这种一条条列出来考试时遇到直接秒杀。2.3 开放题没有标准答案但要答出工程思维触宝这批笔试的最后一道题一般会是一个偏设计的场景题。这种题特别能反应一个人是“会写代码”还是“会做工程”。以“如何设计一个短链接服务”为例完整的答题框架应该包括需求分析生成短链接、跳转、过期时间、统计点击量、存储设计短码和原URL的映射关系用什么存储需要考虑什么时候用关系型数据库、什么时候用KV存储、算法设计短码怎么生成要不要考虑碰撞和并发、容灾和扩展单机瓶颈、缓存层、分布式ID。很多同学答这类题只写“用MD5生成短码存到数据库”这个答案只能拿到基础分。更好的回答方式是先确认需求边界“用户量多大、QPS多高、短链接有效期多久”然后基于需求做技术选型最后给出一个分层架构图思路。这种答题方式会让面试官觉得你有工程意识而不是只会背八股。3. 实操细节笔试中决定成败的10个编程细节3.1 从命名和函数拆分看代码习惯笔试编程题虽然对代码风格不会单独打分但代码质量直接影响面试官对你的印象分。在线笔试系统一般会保留你的提交记录面试官在面试前会翻看你的代码。如果你的变量名是a、b、c函数堆了200行哪怕算法思路是对的面试官也会觉得你写代码不专业。我在写代码时一直坚持这几条变量名必须有含义比如用leftIndex而不是l用userName而不是un函数尽可能保持单一职责一个函数超过30行就考虑拆分常量不要硬编码用final或者static final定义关键逻辑写注释解释“为什么这么做”而不是“做了什么”。举个例子同样是反转链表一眼能看懂的写法是这样的public ListNode reverseList(ListNode head) { ListNode prev null; ListNode current head; while (current ! null) { ListNode next current.next; // 先暂存下一个节点 current.next prev; // 反转当前节点指针 prev current; // 移动prev current next; // 移动current } return prev; }而如果写成ListNode a null; ListNode b head; while (b ! null) { ListNode c b.next; b.next a; a b; b c; } return a;虽然逻辑一模一样但可读性差了不是一星半点。笔试现场时间紧很多同学没精力注意这些但请相信我这30秒的整理时间花得非常值。3.2 边界条件与防御式编程笔试挂掉最常见的原因我见过太多同学算法思路完全正确但提交后只通过了一部分测试用例原因几乎都出在边界条件上。常见的有链表题没处理头节点为null的情况数组题没处理长度为0的情况循环里用到了i1但没处理i是最后一个元素的情况整数除法没考虑除数为0的情况字符串题没处理空串的情况。面对这些我的习惯是写代码之前先花30秒列出边界条件然后把它们转化成if语句写代码时直接把这些if补进去。比如写二分查找先确认数组是否为空、左右指针的初始值、while结束条件用的是left right还是left right以及中间值mid的计算会不会溢出。这些细节想清楚了代码的正确率会大幅提升。提示在线笔试题的测试用例一般会覆盖边界情况。宁可代码多几个if分支也不要过度追求“看起来简洁”。在笔试场景里正确率比优雅更重要。3.3 复杂度分析答完题之后一定要做的事很多同学提交完代码就跳到下一题从来不算复杂度。这在实际面试中很吃亏因为面试官问“你的时间复杂度是多少”时如果答不上来或者答错了前面写对的代码也会打折。我给自己定的规矩是每写完一道编程题必须用10秒钟算一下时间和空间复杂度。这个习惯在做P0试题的时候就能锻炼出来。比如遍历两遍数组的算法是O(n)时间、O(1)额外空间双重循环是O(n^2)使用HashMap的话空间复杂度一般是O(n)。这些基础结论要形成条件反射张口就来。如果复杂度不够优比如写出了O(n^2)但你知道有O(nlogn)的解法就在注释里写一下优化思路。这能向面试官传递一个信号你知道自己的代码有局限也知道怎么改。4. 时间分配与作答顺序怎么做才能在有限时间内拿高分4.1 一场笔试的时间分配参考方案校招笔试的时间一般在90到120分钟之间题目数量大概在5到8道。很多同学的错误做法是在一道难题上死磕30分钟最后发现后面的简单题都没时间写非常可惜。我建议的分配方式是先花2分钟快速浏览全部题目按“基础题、中等题、难题/开放题”给每道题打分定级然后按“先易后难”的顺序作答。为什么要先易后难因为校招笔试的得分是按通过用例比例来的基础题做完了保底分数就有了心态也稳了。如果一上来就卡在DP题上很容易满盘皆输。一个比较合理的时间方案是选择题和填空题控制在20分钟以内每道编程题控制在15到20分钟开放题控制在15分钟左右最后留5到10分钟检查。具体可以根据题目难度微调但整体原则不变先拿稳的分再啃硬骨头。4.2 拿到编程题后的标准处理流程做编程题我不建议拿到就马上敲键盘。我一般会走一个固定的四步流程读题、举例、设计、编码。第一步读题划出关键条件。尤其是数据范围这直接决定了算法的选择。如果数组长度是10^5那O(n^2)基本就爆了必须想O(nlogn)或者O(n)的方案如果长度只有100那写个暴力解问题不大。第二步画例子把题目给的示例或者自己写的一个小数据在纸上或者脑子里完完整整走一遍。这个步骤能帮你发现潜在的问题也方便确定函数签名和数据结构。第三步设计算法选好数据结构和核心逻辑在注释里写出算法的大致框架比如“先用HashMap统计频率再用堆做TopK”。第四步才是编码。编码时按照框架一步步写写完在例子上走一遍确认输出正确再考虑边界条件和复杂度。这个流程看上去啰嗦但是非常稳。我当年做笔试时坚持用这个方法最大的感受就是“返工率低”。很多同学习惯性边写边想写到一半发现思路错了全部推倒重来耗时是正常情况的两倍以上。5. 从笔试到面试如何把一场笔试变成拿offer的跳板5.1 笔试后的复盘清单笔试交卷的那一刻准备工作并没有结束。如果你通过了笔试接下来会有技术面如果你没通过更得复盘。我推荐的复盘方法很简单就是回答以下四个问题。第一有没有哪道题是“思路对但没写完”的如果有说明你的编码速度或时间分配有问题后面需要专门练套题。第二有没有哪道题是“看答案就懂考场完全没想到”的如果有说明你的题型积累不够做完题之后没有把解法提炼成通用思路需要多做专题。第三有没有因为语言细节或边界条件丢分如果有强化易错点和边界测试。第四开放题答得怎么样如果思路很乱就要专门练一练结构化表达。我对所有找我咨询校招的同学都说笔试复盘是技术能力提升最快的方式因为考试题目经过设计覆盖了高频考点你每复盘一套题相当于把核心知识体系重新过了一遍。5.2 技术面可以主动抛出的加分点如果你笔试通过了恭喜你你拿到了面试的入场券。但面试官手里有你的笔试记录面试时很可能会问你“能不能讲一下你笔试最后一题的设计思路”。这时候就是一个很好的加分机会。我建议面试前把你笔试时写的代码重新整理一遍尤其是开放题把设计思路、技术选型理由、潜在优化方向都准备清楚。面试时主动提一句“当时笔试的开放性设计题我后来复盘时觉得还可以用Redis的布隆过滤器来优化短链接存储的命中率”这一句话就能让面试官觉得你是一个有技术热情、懂得迭代的人留下的印象比答对十道八股文都深刻。准备面试时还有一个技巧把你笔试中做错或者没做出来的题重新写一遍代码然后总结出这类题的通用解法放在项目经历或自我介绍里作为技术亮点的佐证比如“我在校招笔试中遇到了二叉树层序遍历问题当时通过这个问题引申出了对BFS和DFS两种遍历方式的对比总结”。面试官听到这种复盘式表达通常都会很认可。根据我个人这几年带新人和做技术评审的经验校招笔试拼的从来不是智商而是你愿不愿意在细节上较真。同一个班级出来的同学算法水平不会差太多最后的差距往往体现在变量命名、边界条件、时间分配这些最不起眼的地方。对于触宝这批笔试来说尤其如此——它的题目并不难难的是你能不能稳定地拿满分。只要你踏踏实实把基础知识点梳理清楚把每种题型的解题流程固定下来再把本文提到的这些细节落实到位通过笔试只是时间问题。最后再分享一个小技巧平时刷题时每做完一道题立刻在本子上写一行“这题考察了什么核心考点”坚持一个月你再看笔试题目会发现自己一眼就能看穿出题人的意图。
返回列表