ARTICLE DETAIL

资讯详情

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

OPPO后端笔试复盘:基础考点、算法设计与避坑指南

OPPO后端笔试复盘:基础考点、算法设计与避坑指南 2023年OPPO秋招后端岗笔试我踩过的坑和复盘思路又到一年秋招季后台不少同学在问OPPO的笔试难度和风格。去年我完整参加了2023年OPPO秋招后端岗的笔试流程从收到笔试通知到做完最后一道题中间有几个印象特别深的点也有不少事后复盘才想明白的细节。这篇不写什么“通关秘籍”就老老实实把我自己遇到的题目类型、答题策略、以及踩过的坑整理出来给准备冲后端岗的同学一个参考。先说结论OPPO后端岗笔试的难度在主流大厂里算中上题型覆盖很广既有考察基础功的选择题也有需要完整思路的算法题和系统设计题。它不是单纯刷题就能过的更看重你对后端知识体系的整体理解。适合正在准备秋招的应届生、想跳槽后端岗的年轻工程师以及自学Java后端想检验水平的朋友参考。1. 笔试整体流程与岗位匹配1.1 笔试基本信息与时间安排OPPO的秋招笔试一般在网申截止后一周内分批发放我去年是投递后第6天收到的笔试通知。整个笔试在牛客网进行时长90分钟题量大概在40道左右包含单选、多选、编程题和一道场景设计题。跟其他大厂不太一样的是OPPO的笔试没有单独的客观题部分和编程题部分拆分而是混在一起限时作答这意味着你需要自己控制节奏。时间分配上我复盘过最优策略大概是选择题部分控制在45分钟内编程题留30分钟最后10分钟处理系统设计题。这里有个很关键的认知——系统设计题往往不是看你写得多完整而是看你有没有基本的工程思维但如果你前面选择题浪费太多时间后面设计题就只能交白卷非常可惜。我当时就是吃了这个亏前面几道网络和数据库的多选题纠结太久导致最后一道设计题只写了个大框架很多细节没来得及展开估计扣了不少分。所以时间管理真的是笔试的第一道考题。1.2 岗位方向与考察重点后端岗在OPPO内部其实分了好几个方向有做互联网服务的有做底层中间件的还有做设备端后台的。不同方向的笔试题侧重点会有差异但公共部分大致相同。我当时投的是互联网服务方向考察重点集中在Java基础、并发编程、MySQL、Redis、消息队列和分布式基础这几个模块。还要提醒一点OPPO的笔试系统会记录你的答题轨迹包括每道题的停留时间。虽然没有实锤说会分析这个但考虑到有些公司会看候选人是否在编程题上有异常操作建议还是老老实实做题不要想着切屏查资料。我认识的一个同学就因为切屏次数太多被系统警告了虽然最后成绩还行但流程上很被动。2. 选择题考点复盘基础功底决定上限2.1 Java核心与并发编程选择题里Java相关的占比最高大概有12道左右难度从简单到中等偏上都有。比较有代表性的几类考点第一类是Java内存模型和JMM可见性问题。比如给你一段多线程代码问某个变量加了volatile之后哪些操作是原子的哪些不是。这种题表面上考volatile实际上考的是JMM的happens-before规则。我建议复习的时候一定要把JMM的八大操作和happens-before规则背熟特别是程序次序规则、管程锁定规则、volatile变量规则这老三样。第二类是线程池的参数组合。题目会给一个场景比如CPU密集型任务、IO密集型任务问线程池核心线程数和最大线程数怎么设置。这里有个容易被忽略的点——任务队列的选择。SynchronousQueue适合非缓冲的提交模式LinkedBlockingQueue适合无界队列模式ArrayBlockingQueue适合有界队列。笔试往往不会直接告诉你用哪种队列而是让你根据场景推断这就需要对线程池的整个工作流程很熟。第三类是synchronized和ReentrantLock的区别这个基本是必考的。重点关注可中断性、公平锁、超时获取锁、Condition等待队列这些点。我印象很深的一道题是问synchronized在JDK 6之后做了哪些优化选项里有偏向锁、轻量级锁、自旋锁、锁消除、锁粗化。这道题如果你只看过面试题总结没看过源码或者JVM的官方文档很容易把锁消除和锁粗化搞混。2.2 网络与操作系统基础网络部分的考点集中在TCP和HTTP。OPPO比较喜欢考TCP的拥塞控制流程特别是慢启动、拥塞避免、快重传、快恢复这几个状态的转换条件。有一道题我记得很清楚给了一个TCP连接传输过程中的拥塞窗口变化曲线要求判断哪些阶段对应什么算法。这道题需要你对拥塞窗口的呈指数增长和线性增长阶段有直观理解不能只背概念。操作系统方面进程线程的区别、死锁产生的四个必要条件、虚拟内存和页面置换算法是高频考点。有个比较偏的点是考了用户态和内核态的切换开销问哪些操作会导致状态切换。系统调用、异常、外设中断都会导致切换而普通的函数调用不会。这道题很多同学容易漏选异常和外设中断因为平常复习很少会专门记这个。HTTP部分考了HTTP/1.1和HTTP/2的区别包括多路复用、头部压缩、二进制分帧这些特性。另外还考了GET和POST的本质区别不是GET有长度限制这种表面答案而是从RFC规范角度的语义差异。2.3 MySQL与Redis专项数据库的题目占了大概8道是选择题里的重头戏。MySQL的考察集中在索引机制、事务隔离级别和锁机制三块。索引那部分考察点B树为什么适合做索引、聚簇索引和非聚簇索引的区别、联合索引的最左前缀原则、索引下推优化。有一道题给了个SQL问怎么建索引才能让查询效率最高选项里有单列索引、联合索引、覆盖索引的组合。这题的关键是先看WHERE子句的条件顺序再看SELECT的字段是否能被覆盖索引覆盖两个条件都满足才是最优解。事务隔离级别的题目是给几个并发场景问你分别会出现什么问题。比如脏读在哪种隔离级别下不会出现不可重复读和幻读的区别是什么。这里有个容易混淆的点——MySQL默认的RR隔离级别下通过MVCC解决了快照读的幻读问题但当前读还是会存在幻读隐患。笔试如果问到RR是否能完全避免幻读一定要分快照读和当前读两种情况回答。Redis的考察集中在缓存策略和数据结构。缓存穿透、缓存击穿、缓存雪崩这三个概念是必考的题目会给你一个具体场景问属于哪种问题以及对应的解决方案。数据结构方面比较喜欢考ZSet的底层实现是跳表哈希表以及跳表的插入和查找的时间复杂度。3. 编程题解析从暴力到最优的演进路径3.1 第一道编程题数组类问题编程题一共两道第一道相对简单考的是数组相关的算法。我抽到的题目是给定一个未排序的整数数组找出其中没有出现的最小的正整数。这题最直观的解法是排序后遍历时间复杂度O(nlogn)空间复杂度O(1)。但如果追求最优解可以用原地哈希的思路把每个数放到它应该在的位置上比如数字3应该放在索引2的位置。遍历一遍交换再遍历一遍找缺失值时间复杂度O(n)空间复杂度O(1)。笔试时我只写出了排序解法因为时间比较紧没有往原地哈希的方向想。复盘的时候才发现这个解法其实很经典在LeetCode上是原题41. 缺失的第一个正数如果提前刷过就不会丢这个分了。这里给个建议笔试前把LeetCode热门100题中的数组类问题都过一遍特别是原地哈希、双指针、滑动窗口这几个套路。OPPO的编程题不太会出偏题怪题基本都是经典题型的变种。3.2 第二道编程题动态规划与字符串第二道题明显难度上了一个台阶考察的是字符串编辑距离问题——给定两个单词word1和word2计算将word1转换成word2所使用的最少操作数。这个考点很经典在笔试中出现频率很高。标准解法是二维DPdp[i][j]表示word1的前i个字符转换成word2的前j个字符需要的最少操作数。状态转移方程分两种情况如果word1[i-1]等于word2[j-1]那么dp[i][j] dp[i-1][j-1]如果不相等取插入、删除、替换三种操作的最小值再加1。这题我没写出完整的多维代码只写了递归加备忘录的版本。虽然逻辑上也对但笔试环境里没有IDE提示递归的边界条件写起来容易出错浪费了不少时间。复盘时我在本地用迭代方式重写了一遍发现核心逻辑其实只有十几行关键是要把二维数组的初始化做好特别是第一行和第一列的处理容易出错。3.3 编程题的答题策略与踩坑记录编程题这块有几点教训想分享第一一定要先明确题目要求的输入输出格式。牛客网的笔试和LeetCode不同需要自己处理输入输出。我第一道题就吃了这个亏题目要求处理多组输入我默认只处理了一组导致部分测试用例没通过。第二时间分配上如果第二道题10分钟内没有思路建议先写一个暴力解保底能拿部分分数。笔试通常有部分用例的分数暴力解至少能过简单的测试用例总比空着强。第三注意溢出问题。数组和字符串相关的题经常涉及到大数相加或数值计算笔试环境是Java的话用long替代int能避免一些低级错误。我当时在编辑距离的状态数组里就用了int如果字符串很长dp数组的值可能超出int范围这一点在反复确认后果然踩到了。4. 数据库与系统设计题工程思维的试金石4.1 数据库场景题索引设计与SQL优化最后一道大题是场景题给了一个实际业务背景一个电商系统的订单表数据量在千万级别包含订单ID、用户ID、订单状态、创建时间、支付时间、订单金额等字段。然后给了一批常见的查询场景让你设计合理的索引方案。这类题目的核心考察点有两块一是对联合索引和覆盖索引的理解二是对索引失效场景的敏感度。我当时的方案是对用户ID和创建时间建联合索引因为最常见的查询是查某个用户的订单列表并按照时间排序对订单状态和支付时间建联合索引因为运营侧经常需要统计某段时间内某个状态的订单数量。复盘时想到的几个加分点可以在索引设计里考虑降序索引比如创建时间按DESC建索引避免文件排序对于订单金额这种范围查询要注意索引的选择性如果某个状态的值分布非常不均匀单独建索引可能反而不如全表扫描。这些细节如果能在笔试中写出来会很加分。4.2 分布式场景题缓存与一致性除了数据库设计还有一道分布式的场景题背景是用户积分系统要求支持高并发读写并保证一定程度的最终一致性。这题问的是缓存策略选择、缓存与数据库的一致性方案、以及积分扣减的幂等性设计。这里我踩了一个坑——只考虑了本地缓存但实际上在分布式场景下本地缓存的失效通知是个大问题。标准答案应该先明确应用场景再给出多级缓存方案本地缓存做一级缓存Redis做二级缓存数据库做最终存储。数据更新时采用Cache Aside Pattern先更新数据库再删除缓存。积分扣减的幂等性设计也是核心考点。我当时只想到用分布式锁但缺少了唯一ID的幂等校验这在面试评审中是很大的扣分点。后来复盘时梳理了更完整的方案通过请求唯一ID做幂等表先查幂等表再执行业务逻辑最后更新幂等表三步骤放在同一个事务里。这个思路在多个场景中都经常使用值得反复练习。4.3 设计题的时间分配与答题框架之前提到我在这道设计题上时间不够这里分享一个我自己总结的答题框架方便在有限时间内快速组织答案第一步明确业务场景的数据量、并发量读写比例、延迟要求这是一个优秀设计的前提第二步画核心架构图标注哪些是存储层、缓存层、业务层不需要画得很细但层次要清晰第三步针对核心问题逐点说明比如缓存策略、一致性方案、幂等处理、分库分表策略第四步点出可能的瓶颈和优化方向比如热key问题、大key问题、慢查询治理显示你的思考深度这套框架前两步控制在5分钟第三步10分钟第四步5分钟总共20分钟基本够用。如果再给我一次机会我就会按这个节奏来而不是在一开始就陷入细节。5. 笔试经验总结与进阶建议5.1 一份好用的复习清单按照2023年OPPO秋招的笔试考察范围结合热词里的高频内容我整理了一份自测清单每个知识点都能不打磕绊地讲清楚再上考场Java基础集合源码特别是HashMap的put流程和扩容机制、JVM内存模型与GC算法、反射与代理、泛型擦除并发编程synchronized与ReentrantLock的底层实现、volatile的内存语义、线程池参数设计与饱和策略、CAS与ABA问题、AQS原理Spring生态Spring Bean的生命周期、Spring Boot自动配置原理、Spring事务传播机制与失效场景MySQL索引数据结构与优化、事务隔离级别与MVCC、锁机制记录锁、间隙锁、临键锁、慢查询排查Redis五种数据结构的底层实现、持久化机制RDB与AOF、缓存穿透与雪崩的解决方案、分布式锁的Redisson实现消息队列Kafka的消息存储机制、消费者组与分区分配策略、如何保证消息不丢失不重复网络基础TCP三次握手四次挥手、TCP与UDP区别、HTTP与HTTPS、HTTP/2的新特性算法动态规划、回溯、贪心、图的遍历与最短路、字符串匹配、常见数据结构的手写实现以上这些基本上是后端岗位笔试的核心考点无论投哪家互联网公司60%-70%的概率会遇到。5.2 系统设计题的日常训练方法系统设计题在笔试中占比不高但对后续面试很关键。平时可以利用零散时间做素材积累比如和朋友点外卖时想想外卖平台的订单架构看短视频时思考推荐系统的粗排和精排网上买东西时琢磨库存扣减怎么保证不超卖。这种思考多了笔试遇到任何场景题都不会没话说。我个人的一个习惯是每周挑一个系统做文字版的架构设计比如设计一个短链接系统、一个秒杀系统、一个实时弹幕系统写完参考答案对比。坚持几个月后你会发现自己的系统设计能力有质的飞跃。5.3 关于心态和临场发挥笔试前一天最重要的是保证睡眠而不是拼命刷题。我在做OPPO笔试时因为前一天熬夜刷题导致第二天头昏脑涨选择题的正确率明显不如模考时高。笔试开始后如果遇到卡壳的题超过两分钟没有思路就先标记跳过不要在一道题上耗太久。还有一个小细节牛客网的笔试环境支持本地IDE调试但有些公司的笔试系统会禁用复制粘贴到IDE只能直接在线提交。OPPO当时是可以使用本地IDE的不过提交代码还是要粘贴回网页里。建议提前在牛客网上做一两套模拟题熟悉整个操作流程避免因为不熟悉环境而手忙脚乱。从我自己和身边人的经验来看笔试过程是秋招中最容易遗憾的环节。技术能力再强如果因为时间分配、环境不熟或者心里紧张没发挥好都很可惜。希望这篇复盘能让你少踩几个我踩过的坑。最后再说一个很多经验帖不会提的点笔试结束后不管自我感觉如何建议第一时间把题目里你犹豫过、不会的知识点记录下来再顺手搜一下最优解。这个动作虽然简单但对面试时候的深度追问帮助非常大不少面试官会顺着笔试题的考点继续深挖。我就是靠着笔试后的复盘在下一轮面试中接住了关于Redis持久化和MySQL间隙锁的连续追问。祝大家都能拿到心仪的offer。
返回列表