尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

58同城2017秋招研发工程师笔试试卷深度解析

58同城2017秋招研发工程师笔试试卷深度解析 这个标题让我想起了很多当年一起刷牛客网、赶宣讲会的日子。2017年秋招是互联网行业竞争相当激烈的一年58同城作为分类信息领域的头部玩家技术岗笔试的含金量一直被校招生们当作重要的风向标。虽然没有官方完整试卷流出但根据当年参加笔试的同学反馈和各个技术社区的讨论记录试卷的结构和考察逻辑是比较清晰的。这篇博文我按“试卷结构拆解—基础考点复现—算法题深度复盘—数据库与设计题—备考经验”这条线来写尽量把每一类题的出题意图和答题思路讲透希望能给正在准备大厂研发岗笔试的同学一些真正用得上的东西。1. 当年的题型权重与整体做题节奏1.1 笔试试卷的基本盘58同城2017秋招研发工程师笔试试卷整体结构分为三块选择题、编程题、主观设计题。总时长120分钟题量在35道左右。选择题约30道单选占多数夹杂少量多选编程题3道题目难度呈梯度上升第一道属于送分题第二道中等第三道需要一定的算法功底主观设计题1到2道通常结合58同城的业务场景比如信息发布、搜索筛选、消息通知这类实际功能来做设计。这个题型结构在当时的大厂笔试里属于主流配置。和腾讯、阿里、百度那几年的笔试卷相比58的卷子有个显著特点选择题的覆盖面更广、但单题深度不算特别变态。换句话说它更看重你知识面的广度和基础扎实程度而不是在一个点上死磕。这也和58同城当时的业务形态有关——分类信息网站的业务链路长从用户端的信息流展示到商户端的发布管理再到后端的检索、审核、调度系统涉及的中间件和技术栈非常杂所以考察点自然铺得开。1.2 120分钟的答题节奏应该怎么分配我复盘过很多同学的笔试经验发现分数不理想的人问题多半出在节奏上。前30道选择题很多基础扎实的同学能20分钟出头做完但一旦遇到一两道卡壳的题就开始反复纠结结果编程题只剩30分钟。这是最典型的失误。合理的节奏是这样的选择题控制在25到30分钟内。单题最多1分钟拿不准的先标记不恋战。编程题每道预留15到20分钟。第一道题要又快又稳第二道题看思路清晰程度第三道题如果卡了10分钟没进展果断写一个暴力解拿部分分。主观设计题放最后预留20分钟。设计题没有标准答案只要框架完整、关键点到位分数差距不会太大。我在实际做这套卷子的模拟时发现选择题里最容易耗时的是多选。多选题选错一个就全错很多人会反复琢磨。我的做法是能在草稿纸上写出的性质、推导结论的题直接列出来对照选项纯记忆性的题信第一感觉不回头改。1.3 不同岗位方向的卷面差异这里多说一句研发工程师在网申时是有具体方向的。58同城2017年秋招的研发岗主要分Java开发、C开发、前端开发和测试开发试卷不完全一样。后端方向共用一套卷但编程题的语言要求通常是Java/C/PHP三选一前端方向的卷子会加入浏览器缓存机制、页面渲染流程、JS原型链等考点测试开发方向则偏向Linux命令、自动化测试框架、接口测试设计。所以准备笔试前先确认自己投的方向别拿后端的卷子去复习前端的内容复习效率会差很多。2. 选择题里的高频考点每一类都在考什么2.1 数据结构与算法不是死记复杂度是考为什么选择题里占比最大的永远是数据结构与算法大概在8到10道。这一块出题方式有两种一种是直接问性质另一种是给一段代码让推结果。后者更常见也更考验真实理解。我挑几个当年出现频率最高的考点说一下。栈和队列的性质。通常会结合出栈序列来出题给定入栈序列1,2,3,4,5以下哪个出栈序列不可能。这类题很多人靠枚举硬推其实核心就一句话栈的pop顺序里任何一个元素后面的所有元素必须按照它们在栈里从顶到底的顺序出现。理解了这句话所有出栈序列题都能10秒内解决。二叉树的性质。常考的是度为0的节点数等于度为2的节点数加1满二叉树第k层有2^(k-1)个节点完全二叉树用数组存储时父节点下标和子节点下标的关系。这些点很基础但架不住每年都考。我的建议是考前花10分钟把这几条性质推一遍不要背结论而是从为什么出发推导这样不管题目怎么变种都能应对。排序算法复杂度。这是必考点。注意区分平均时间复杂度和最坏时间复杂度快排平均O(nlogn)但最坏O(n²)归并排序无论什么情况都是O(nlogn)堆排序也一样。稳定性上选择排序不稳定、快排不稳定、堆排不稳定冒泡、插入、归并稳定。这个表我建议自己默写一遍比看任何总结都管用。哈希表。冲突处理有两种主流方式开放寻址法和链地址法。选择题常考负载因子对查找效率的影响以及HashMap在Java中的扩容机制。这里提醒一下如果选项里出现哈希表查找时间复杂度一定O(1)这个选项必然是错的因为极端情况下所有元素都冲突会退化成链表。2.2 计算机网络TCP和HTTP是绝对核心计算机网络的选择题大约4到5道集中在TCP/IP协议族和HTTP协议上。TCP三次握手属于必考题。它不只是考发送什么标志位更常考的变种是为什么是三次而不是两次为什么连接释放需要四次这两个为什么如果只背答案不理解换个问法就会懵。三次握手的本质是让双方都确认自己的发送能力和对方的接收能力正常。两次握手的话服务端无法确认客户端的接收能力是否正常也就无法应对服务端发送的SYN应答报文丢失这种异常情况。HTTP状态码也是高频考点。302临时重定向和307临时重定向但保持请求方法的区分、301永久重定向和302的应用场景都是选择题常挖的坑。还有一个容易错的点是304 Not Modified表示缓存有效服务端不返回实体内容它属于重定向类的3xx状态码语义是你用本地缓存就行。TCP拥塞控制同样逃不掉。慢启动、拥塞避免、快重传、快恢复这个四个阶段的阈值变化过程经常作为多选题出现。我在模拟时总结了一个规律题目问你拥塞窗口怎么变化你就盯住ssthresh这个阈值词所有变化都围绕它展开。2.3 操作系统与Linux进程线程和内存管理操作系统这块占比在5道题左右考点分布比较集中。进程与线程的区别几乎是必考的。出题方式常见的有哪个不是进程间通信方式、线程之间共享哪些资源。这里容易错的点是线程拥有自己独立的栈和寄存器上下文但共享进程的堆和全局变量。所以选择题如果问线程间不共享的是什么答案是栈和寄存器不是堆。死锁产生的四个必要条件——互斥、持有并等待、不可剥夺、循环等待。多选里如果问破坏死锁条件的方式破坏互斥条件几乎不可能破坏持有并等待可以用一次性申请所有资源破坏不可剥夺可以引入资源抢占破坏循环等待可以用资源有序分配。它们之间的对应关系要一一记牢。Linux命令。58的卷子里Linux基础题很务实常考的有查看进程用ps动态查看用top查看端口的网络连接用netstat查看内存用free查看磁盘用df。我记得有一道题是某服务端口起不来你应该用什么命令排查答案应该是 netstat -tlnp 加 ps aux 的组合。这类题没有技巧就是平时多敲。2.4 Java基础与并发58技术栈的特殊偏重58同城的后端以Java为主所以试卷里Java相关的选择题占比明显高于同期的很多公司大概在6到8道。HashMap的实现原理必考。2017年之前Java 8已经普及所以考题已经不满足于数组加链表而是进一步深入到红黑树链表长度超过8且数组长度不小于64时转红黑树。这个阈值是要背的选择题会直接把陷阱设在数字上。线程池。核心参数是常考坑点corePoolSize核心线程数、maximumPoolSize最大线程数、keepAliveTime非核心线程空闲存活时间、BlockingQueue任务队列、RejectedExecutionHandler拒绝策略。选择题经常给一个场景让你判断当任务数超过核心线程数时新任务会先去哪——注意不是直接创建新线程而是先进入工作队列队列满了才创建非核心线程。这个执行顺序是重中之重。JVM内存模型。堆、栈、方法区各存什么垃圾回收算法里可达性分析的根节点有哪些类是高频点。常考的一个细节是成员变量存储在堆上局部变量存储在栈上静态变量存储在方法区Java 8之后是元空间。3. 三道编程题怎样拿满前两道再啃第三道3.1 第一题链表反转类编程题第一道通常容易链表反转是出现概率最高的题之一。题目一般不会直接写反转链表而是包装成一个场景比如给定一个单向链表每K个节点为一组反转。你如果不能手写基础反转这种变种题肯定无从下手。基础反转的思路就六行代码但要清楚维护三个指针的语义public ListNode reverseList(ListNode head) { ListNode prev null; ListNode curr head; while (curr ! null) { ListNode next curr.next; // 暂存下一个节点 curr.next prev; // 当前节点指向前驱 prev curr; // 前驱指针后移 curr next; // 当前指针后移 } return prev; }核心逻辑是暂存next反转指针双指针推进。这个写法一定要练到肌肉记忆因为K个一组反转、回文链表判断、重排链表这些进阶题全都建立在它上面。3.2 第二题动态规划入门题第二道编程题往往是动态规划常见的是最长公共子序列或者打家劫舍这类入门DP。我当时遇到的是类似最大子数组和的问题也就是LeetCode 53的原题。最大子数组和的DP思路很经典维护一个dp[i]表示以第i个元素结尾的子数组的最大和。状态转移方程是dp[i] Math.max(nums[i], dp[i-1] nums[i]);翻译成大白话就是要么从当前元素重新开始累加要么把当前元素接到前面的最大和子数组后面。最终答案是所有dp[i]里的最大值。这道题有两个优化点笔试时如果写了面试官会有不错的印象。一是用滚动变量替代dp数组把空间复杂度从O(n)降到O(1)二是可以进一步扩展成返回最大子数组的起始下标的版本用两个指针记录边界。这类小优化体现了你对DP状态压缩的理解比单纯列转移方程拿分多。3.3 第三题复杂题目的部分分策略第三道题的定位是筛选难度会明显跳档常见的是带约束的搜索题或复杂的DP。我印象里讨论比较多的一道题是类似给定一个字符串求最少切几刀能把它切成全部由回文子串组成的DP题目也就是LeetCode 132。这类题的完整解法是一道二维DP笔试时15分钟内从零写出来很困难。但注意实在不会时可以写DFS暴力搜索一定不要空着。我见过很多同学看到难题直接放弃其实暴力解法至少能通过30%到40%的测试用例。笔试系统按通过的测试用例比例给分你写个能跑出正确答案但超时的解法拿的分远比空着多。另外第三题如果涉及图论比如最短路、拓扑排序优先想BFS/DFS的框架而不是Dijkstra因为DFS的代码量少、不容易写错在拿部分分的策略里性价比最高。这个取舍很重要——笔试题量大你的目标不是每道都满分而是总分最大化。3.4 编程题的代码习惯不扣细节真的会扣分校招笔试的编译环境和本地IDE不同它通常要求你自己写完整类名和main方法入口。很多同学练习时用LeetCode的函数式写法习惯了leetcode给好的方法签名真要自己从public class开始写反而容易漏掉import包导致编译失败。我的建议是笔试前至少用牛客网的在线系统练5道题适应它不提示import、不帮你写输入输出的粗暴模式。特别是使用Java的话输入建议用BufferedReader加StringTokenizer不要用Scanner后者在数据量大的case上可能因为性能问题卡Time Limit Exceeded。这个细节很多经历过笔试的人都吃过亏。4. 数据库题事务隔离与索引两道必考题的完整解法4.1 事务隔离级别别只背四个名字58的卷子数据库部分大概4到5道题事务隔离级别是每年必考。四个级别——读未提交、读已提交、可重复读、串行化——分别解决什么问题这个问题既可能出现在选择题也可能出现在简答题。容易混淆的是可重复读和读已提交的区别。简单理解读已提交Read Committed解决脏读但会出现不可重复读。也就是说同一个事务里同样的SELECT语句执行两次结果可能不一样因为另一个事务在你两次查询之间提交了修改。可重复读Repeatable Read进一步解决不可重复读保证事务内多次读取同一行数据结果一致。但它仍可能出现幻读——查询一个范围内的记录时另一个事务插入了新记录导致两次查询的记录条数不同。MySQL的InnoDB引擎默认隔离级别是可重复读但它通过间隙锁MVCC做到了对幻读的规避。这是面试官非常爱追问的一个点。笔试的选择题如果问MySQL默认隔离级别是什么答案是Repeatable Read不是大多数数据库教材里写的Read Committed——很多教材以Oracle为例这里是个大坑。4.2 索引失效场景一条一条对着报错SQL优化相关的题最常见的是给一条SQL问以下哪个条件会导致索引失效。我整理了出现频率最高的五类对索引列使用函数或运算比如WHERE age 1 30索引失效。左模糊查询比如WHERE name LIKE %张因为B树按最左前缀匹配左模糊无法利用索引序。隐式类型转换比如索引列是varchar查询条件是数字数据库会做隐式转换导致失效。用OR连接非索引列条件。联合索引没遵守最左前缀原则。这里重点说下最左前缀原则。联合索引(a, b, c)相当于建了(a)、(a,b)、(a,b,c)三个索引。你查询条件是b和c没有a索引直接失效查询条件是a和c只有a能走索引。这个规则在选择题里百考不厌需要彻底理解B树的排序顺序是先按a排再按b排最后按c排所以跳过了a就无法用索引完成精确定位。4.3 MySQL索引底层为什么选B树一道常考判断题是为什么InnoDB用B树而不是B树。答案的关键在于只有叶子节点存数据非叶子节点只存索引键。这意味着同样的页大小B树的非叶子节点能容纳更多索引项树的高度更低磁盘IO次数更少。同时叶子节点用链表连接范围查询时只需要顺着叶子节点顺序遍历不需要回溯到父节点。我还见过一道变种题问为什么不用哈希索引。答案也不难哈希索引只能做等值查询无法处理范围查询和排序而数据库查询里范围查询非常常见。B树的有序性让查询和排序统一在同一个数据结构里解决这就是它的核心竞争力。5. 主观设计题开放问题怎样答题才能拿高分5.1 58式业务设计题的典型场景58同城的业务是典型的分类信息撮合平台用户发帖、搜索、筛选、联系商家管理帖子、刷新、置顶。2017年的设计题我记得有不少是围绕帖子搜索和消息通知这两个场景展开的。比如设计一个支持高并发访问的帖子搜索系统要求能按分类、区域、价格排序并分页展示。这类题没有唯一标准答案但踩分点非常明确数据存储方案帖子数据量大且读多写少适合用MySQL读从库或者主从集群帖子详情放缓存Redis减轻DB压力搜索功能用Elasticsearch或Solr做倒排索引按地理位置过滤用ES的geo功能。缓存策略列表页做多级缓存一级是本地缓存Caffeine二级是Redis。缓存key的设计要考虑分类、区域、页码、排序方式这些维度。注意缓存穿透和缓存雪崩的应对布隆过滤器挡穿透缓存过期时间加随机值防雪崩。索引与分页ES深分页问题要放明面上讲——翻到一万页以后深分页的性能会急剧下降需要用search_after方式而不是fromsize。可扩展性消息队列削峰比如帖子发布高峰期使用Kafka做异步处理把写入压力从数据库剥离。5.2 框架是骨架细节才是血和肉设计题的答题层次直接决定了你的分数上限。如果你只写用Redis缓存、用ES搜索、用消息队列削峰这三句话那分数一定不高因为任何学过八股文的人都能写出来。拉开差距的是参数和细节。我举一个具体的例子。你提到用Redis缓存帖子列表那就该写清楚缓存key设计为post:list:{category}:{region}:{page}:{size}缓存value用什么格式JSON序列化还是Protobuf过期时间设置多久帖子列表可以设5到10分钟缓存更新方式是更新DB后主动删除缓存Cache Aside Pattern而不是先更新缓存写操作时先删缓存再更新数据库还是先更新数据库再删缓存两者在并发下的差异同样你说用消息队列削峰应该补充Kafka的topic怎么划分按帖子分类或按区域、消费者组的规划、消息丢失和重复消费怎么处理消费者幂等。这些细节综合起来才体现你真正动手做过分布式系统而不是背了一堆名词。5.3 设计题里的业务感比技术本身更难得在58的业务背景下设计题还会考察你对业务场景的理解。同样是帖子列表接口你要知道分类信息网站的核心诉求是新帖优先和真实有效性。所以你的缓存过期策略要考虑新帖发布后列表页多久能看到——如果缓存时间太长用户发了帖一直看不到就会流失。一个加分设计是帖子发布时主动清除对应分类和区域的列表缓存而不是等缓存自然过期。另外一个隐含考点是反作弊和内容审核。58当年非常重视虚假信息和垃圾帖的治理。如果你是候选人能在设计题里主动提出文本审核走异步队列系统侧接入敏感词过滤异常发布行为做频控这一类方案说明你真的考虑过业务里最痛的问题这比堆技术名词更能打动评委。6. 考后的复盘方法比刷题量更重要6.1 从错题反向定位知识盲区笔试结束到面试通常有一到两周的间隔。这段时间不该盲目刷题而应该按错题→知识点→专题突破的路径来复盘。我在准备这类笔试时建立了一个简单的错因分类不会做、会做但做错、会做但超时。三种错因对应的复习策略完全不同。不会做说明这个知识点存在结构性盲区需要回到教材或者课程里把原理捋一遍而不是背题。会做但做错大概率是概念混淆或粗心比如可重复读和读已提交的区别没记牢。这类错误用一句话记录在错题本上考前过一遍就行。会做但超时说明熟练度不够。典型的就是链表反转这类必须形成肌肉记忆的代码建议摘出来反复手写。6.2 时间分配策略的二次校准第一次做笔试模拟卷大多数人的时间分布是不合理的。我当时的第一次模拟选择题用了40分钟导致编程题只剩40分钟第三题基本没写。后来我调整了策略第一轮把选择题做一遍不会的果断跳过并标记等编程题做完后再回头处理。这样能保证编程题永远有充足的时间。另外多选和单选要区别对待。多选的评分规则是漏选得一半分还是零分并不统一如果卷子没写明我的保守策略是只能100%确定的选项才选不确定的宁可不选。当然如果规则写明了漏选得部分分那就尽量多选自己有把握的项。6.3 笔试只是开始心态和技术都不能偏科笔试能筛掉一部分人但真正决定你是否拿offer的是后面的一到两轮技术面和HR面。笔试过程中暴露的问题面试官真的会拿着你的卷子追问我在一次模拟面试中就遇到过面试官直接问你当时这道题为什么用这个解法的情况。所以别把笔试当成一次性考试——笔试是你给面试官的第一份技术简历你写的每一个解法、每一个设计决策都可能成为面试的素材。我的核心建议就一条把每一次笔试都当成一次学习闭环。做题、复盘、补盲区、再验证。这个循环跑得越扎实你面对下一场笔试时的手感就越稳。等到真正坐在考场上你会发现自己不需要靠运气而是靠已经内化的知识结构稳稳地把该拿的分数拿满。
返回列表