尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

从努比亚校招笔试题看开发工程师必备基础与算法思维

从努比亚校招笔试题看开发工程师必备基础与算法思维 1. 一份手机厂商校招笔试到底想筛掉什么人聊到努比亚2017校招开发工程师试卷很多后来者第一反应是这都过去这么久了还有什么参考价值。但我在移动开发这行干了十多年后来也参与过几次校招笔试的命题和阅卷我可以负责任地说这种厂商笔试的命题思路、考点分布、淘汰逻辑放到现在依然管用甚至有不少东西正在被AI时代重新捡起来。先说清楚一个前提。2017年正是国产手机厂商疯狂扩张的年份努比亚这种以无边框屏幕、手机摄影见长的品牌招开发工程师主要面向三类岗位方向Android应用开发、底层驱动/Linux开发、以及部分嵌入式方向。对应到笔试上它的考察点就非常明确计算机基础功底要扎实语言层面C/C和Java都要能拿得起来操作系统和网络不能是死记硬背Android相关的实战经验要有。它不是要招一个什么都会的天才而是要在一批简历看起来差不多的应届生里筛掉那些基础不牢、只会背面试题的人。整张试卷的筛选逻辑本质上就三层。第一层是淘汰层也就是数据结构与算法题。这部分题量最大、分值最重也是刷人最狠的地方。它考察的不是你会不会背某个算法而是你在短时间内能不能分析出问题的本质、写出能跑的代码、把复杂度算清楚。第二层是鉴别层也就是语言基础、操作系统、网络这些计算机核心知识。这部分题的特点是看着简单翻车率却极高。一个sizeof(struct)的题一个进程间通信的题一道TCP握手状态的题往往能把真会和背过区分得明明白白。第三层是差异化层也就是Android/移动端相关的考题。这是手机厂商比互联网大厂更爱考的部分。毕竟招你进来是要写手机软件的Activity生命周期、Handler机制、内存优化这种东西工作第一天就要用。我当时拿到这份试卷的第一感受是没有偏题怪题每一道题都能在《王道考研系列》《程序员面试宝典》或者LeetCode上找到影子但组合起来就是在考察一个工程师最基本的职业素养——能不能把一个明确的问题用清晰的思路和严谨的代码表达出来。下面我按试卷的考察模块把每一类题型的命题逻辑、典型题目和应对思路拆开讲。2. 数据结构与算法笔试的硬通货也是刷人最狠的地方2.1 从链表到二叉树厂商笔试算法的典型分布任何一份开发岗笔试卷算法题都躲不开。努比亚这份试卷里的算法题没有特别离谱的竞赛难度基本集中在几个经典考点上单链表的逆置、合并、判环二叉树的遍历尤其非递归、深度、镜像翻转排序算法的手写与复杂度分析快排、归并、堆排序是常客字符串处理最长公共前缀、子串匹配、字符统计简单动态规划背包、最长递增子序列、爬楼梯为什么考这些因为这是判断科班底子最公平的方式。八股文可以突击背诵但让你在笔试现场二十分钟内手写一个链表反转的非递归实现是装不出来的。链表指针指来指去的细节二叉树递归转非递归的栈操作考察的是你能不能把抽象的逻辑结构落地成具体代码。我当时印象比较深的一道题是给定两个有序链表要求合并成一个有序链表但是要求空间复杂度为O(1)。很多人第一反应是开一个新链表或者用递归——这两个都能过但空间复杂度不对。正确做法是原地调整指针维护一个哑结点作为新链表头部然后用双指针依次比较两个链表的当前节点把较小的节点摘下来接到结果链表尾部。这个题你说难吗不难。但能一次写对的人真心不多。很多人在指针断链的地方翻车把链表弄丢了。2.2 手撕代码之外复杂度分析才是真正的分水岭算法题的第二层考察是复杂度分析。2017年的笔试已经有明确的时间限制和数据规模提示了比如n 10^5这时候O(n^2)的解法基本就是死刑。很多应届生能写出暴力解但不会进一步优化。举一个典型的例子。求一个数组里连续子数组的最大和经典的最大子数组和问题。O(n^2)枚举所有人都会但Kadane算法的O(n)解法思路就是到当前位置为止的最大子数组和要么是当前元素自己要么是当前元素加上之前的最大和。用状态转移方程表达就是dp[i] max(nums[i], dp[i-1] nums[i])这道题几乎是笔试必考题。为什么反复考因为它考察的是一个开发工程师最核心的能力能不能把一个看起来是暴力枚举的问题抽象成一个有状态转移关系的递推模型。这不只是算法题这是工程里做性能优化时天天要用的思维方式。我的建议是准备这类厂商笔试不需要去刷竞赛难度的题但LeetCode上的高频题必须过两遍尤其是链表、二叉树、哈希表、双指针、动态规划这几个专题。手写能力一定要练光看题解永远练不出笔试时的那种手感。3. 语言基本功与内存管理C/C和Java的必考陷阱3.1 C/C考点指针、内存布局、关键字背后的原理努比亚这种做手机底层的厂商对C/C的重视程度明显高于纯互联网公司。它的应用层是Java/Kotlin但驱动、协议栈、系统优化这些全是C/C的阵地。所以试卷里的C/C题考的从来不是语法而是内存和指针。常见题型包括sizeof结构体内存对齐的计算。比如一个结构体有三个成员char、int、short问你sizeof是多少。很多人答12或者10实际上在默认4字节对齐下是12。这个题考的是你知不知道内存对齐的规则每个成员的偏移量必须是其自身大小的整数倍结构体总大小必须是最大成员对齐数的整数倍。指针和数组的区别。sizeof(arr)和sizeof(ptr)数组名作为参数传入函数后发生了什么。这是一个经典陷阱数组作为函数参数时退化为指针sizeof拿到的是指针大小而不是数组大小。static、const、volatile关键字的作用。static修饰局部变量改变生命周期修饰全局变量改变作用域修饰函数改变链接属性。volatile提醒编译器不要优化掉对变量的访问因为它在别处可能被修改——这在写底层驱动时太常见了。野指针和内存泄漏的成因。为什么会野指针因为指针被free之后没有置空或者返回了局部变量的地址。这些题目做多了你会发现它本质上是在问你你能不能理解程序运行时内存里到底发生了什么。注意我在实际阅卷时发现很多考生对指针和引用的区别堆和栈的区别这类题能答得上来但一旦给一段实际代码让分析输出结果就会暴露问题。我的建议是复习C/C时不要只看概念要自己动手在编译器里跑一跑把每个关键字的实际效果验证一遍。这个过程花不了几小时但远比背十遍static的作用有效。3.2 Java考点集合、GC和并发Android开发的地基Java部分的考察集中在三个方向集合框架的理解。HashMap的底层原理几乎是必考。2017年还在考HashMap和Hashtable的区别现在会追问红黑树是怎么优化链表的为什么容量要设计成2的幂次。这些底层问题的答案直接影响你对Android开发中数据结构的选型判断。比如你知道HashMap在并发场景下可能丢数据就该知道什么时候改用ConcurrentHashMap。垃圾回收机制。Java和Android里的GC是必考项尤其是强引用、软引用、弱引用、虚引用的区别。这个题在Android开发里的实际意义非常直接Handler内存泄漏就是因为内部类持有外部Activity的强引用用WeakReference包裹Activity就可以避免图片缓存用LruCache底层其实就是LinkedHashMap的访问顺序特性。并发编程基础。synchronized和ReentrantLock的区别volatile的可见性线程池的核心参数。这些内容在2017年的试卷里已经出现了到了今天的岗位要求里更是高频考点。拿一道典型的Java题举例子类继承父类时构造方法的调用顺序是什么答案先父类构造器再子类构造器但如果子类构造器第一行写了this(...)则会先调用子类自身其他构造器再由那个构造器调用父类构造器。很多人会在这个细节上栽跟头。这类题考的不是智商而是你有没有真正写过足够多的Java代码。4. 操作系统、网络与Android手机厂商笔试的差异化重头4.1 操作系统进程线程、死锁、内存管理一道题看出工程素养操作系统题是笔试里最容易背了考不到、考到了不会的部分。努比亚这份试卷里的OS题我印象里集中在几个点进程和线程的区别。这题人人都能说两句但要说透就不容易了。地址空间、资源拥有、调度单位、切换开销要能从操作系统实现的角度讲清楚为什么线程切换比进程切换轻量。因为线程共享地址空间所以切换时不需要切换页表TLB不用失效这就是轻量的根本原因。死锁的四个必要条件互斥、持有并等待、不可剥夺、循环等待。这个考烂了但结合具体场景的题目就难了。比如给你一段加锁代码问会不会死锁、怎么避免。这种题需要你真正理解锁的申请顺序和释放时机。进程间通信方式管道、消息队列、共享内存、信号量、Socket。Android开发里对应的就是Binder。Binder为什么高效因为只做一次内存拷贝而传统管道需要两次。这种关联性恰恰是手机厂商笔试愿意看到的深度。内存管理虚拟内存、分页分段、页面置换算法LRU。LRU这个点在Android里就是LruCache的底层实现原理也是图片加载框架的必要组件。4.2 网络TCP三次握手、HTTP与Socket移动开发绕不开的坎网络题的分值不如算法重但基本必考。考点也无外乎那几个TCP三次握手和四次挥手。考察点不只是为什么是三次还有各个状态的含义。比如四次挥手中的TIME_WAIT状态为什么要等2MSL因为要确保最后一个ACK能送到对方同时让本连接产生的所有报文段都从网络中消失。这个知识点在服务端开发里特别重要大量短连接会导致TIME_WAIT堆积进而影响新连接建立。TCP和UDP的区别。这个问题在移动端的实际意义视频通话和语音用UDP居多因为这允许丢包但不允许延迟文件传输、支付请求用TCP因为这不允许丢数据。产品和技术选型的逻辑在这个题里就能看个大概。HTTP和HTTPS。2017年正好是HTTPS全面普及的节点所以考HTTPS的握手流程、加密方式、为什么比HTTP安全是很自然的。同时会考HTTP的状态码比如301和302的区别——前者是永久重定向后者是临时重定向401和403的区别——前者是未认证后者是已认证但无权限。Socket编程。这道题在手机开发岗位里出现频率特别高。它考的其实很简单客户端和服务端各需要哪些步骤。但要注意iOS和Android的网络权限配置是不同的Android的明文流量默认被禁止是从API 28开始2017年时还只是建议配置阶段。这种和时间点绑定的知识恰恰说明笔试题目是贴近实际业务的。4.3 Android专项Activity、Handler、ANR、内存泄漏全是实战题最后一个大模块是Android专项。手机厂商笔试和互联网公司笔试最大的不同就是Android题占比高、题目更实战。Activity生命周期。这个题几乎必考但考法各不相同。有的画时序图让你标注状态有的问屏幕旋转时Activity会经历哪些生命周期方法。后者是典型的配置变更场景Activity会被销毁重建经历onPause - onStop - onDestroy - onCreate - onStart - onResume。如果不做配置处理你保存的状态就丢了。Handler机制。Handler、Looper、MessageQueue三者之间的关系这是Android开发的面试之魂。为什么主线程Looper在被创建后要调用Looper.loop()进行无限循环因为Android是事件驱动模型loop()不断从MessageQueue里取消息并分发处理。子线程里能用Handler吗可以但你必须先Looper.prepare()再Looper.loop()。ANR的成因和定位。InputDispatching超时、BroadcastReceiver执行超时、Service执行超时三大ANR场景。为什么主线程不能做耗时操作因为主线程要处理用户输入和UI绘制你卡了5秒系统就认为应用无响应了。这个知识的引申就是文件读写、网络请求、数据库操作全都不能放在主线程。常见内存泄漏场景Handler持有Activity引用、静态变量持有Context、注册了广播但没反注册、单例模式持有Activity。每一类都能跟GC机制里的引用类型对应上。我当时判卷的时候凡是能写出因为内部类默认持有外部类的引用而Handler的消息在MessageQueue里排队如果消息一直没处理完外部Activity就不会被GC回收这种完整逻辑链条的考生基本都给了高分。自绘View和事件分发。onMeasure、onLayout、onDraw的顺序事件分发机制里dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent的调用关系这些是Android开发进阶的分水岭。手机厂商尤其看重这部分因为它们的系统UI和定制ROM经常要修改这些逻辑。5. 从2017到AI时代考点变了底层逻辑没变5.1 AI应用开发工程师、大模型全栈工程师这些新岗位在考什么这些年技术圈的变化确实大。2017年的时候没有人会想到提示词工程能成为一个岗位技能更没有人会想到智能体开发工程师会出现在招聘网站的热搜词里。我最近也看了不少AI应用开发工程师和大模型全栈工程师的岗位要求发现它们的核心技能树已经变成了大模型API的调用与微调、RAG检索增强生成、Agent框架的设计与编排、向量数据库的使用、Prompt的调优。但有意思的是这些新岗位的面试里算法题的权重并没有下降。你仍然要会写代码仍然要理解数据结构仍然要分析复杂度。为什么因为AI应用的落地说到底还是工程问题一个Agent要调用多个工具工具调度的顺序和并发怎么设计RAG要检索大量文档向量检索的性能怎么优化这些问题的答案仍然落在数据结构和算法、操作系统、网络这些基础学科上。5.2 大模型全栈工程师和AI全栈开发工程师的区别看的是哪一层最近总有人问我大模型全栈工程师和AI全栈开发工程师到底有什么不同。以我自己的理解大模型全栈更侧重模型层要懂Transformer原理、懂训练和微调、懂部署推理优化而AI全栈开发更侧重应用层懂业务逻辑、懂前后端、懂如何用大模型API和向量库搭出一个能用的产品。但两者的共同点是都得有一个扎实的工程底子。这恰恰是2017年那份试卷到今天仍然值得看的根本原因。无论技术栈怎么变无论岗位名称怎么换笔试真正筛选的始终是一个人的基本功和思维方式。你能不能在拿到一个模糊需求时拆解出清晰的模块和接口能不能在代码里把内存和并发问题考虑清楚能不能在系统出问题时快速定位根因——这些能力不因为你用了大模型而自动获得。5.3 智能体开发工程师新的加分项旧的基础盘智能体Agent开发是现在比较火的细分方向。所谓智能体就是让大模型具备规划、调用工具、记忆和反思的能力。技术上要处理Prompt模板、工具注册与调用、多轮对话状态管理、记忆存储与检索。这些东西在2017年是完全不存在的考点但你会发现它的实现框架里到处是老朋友多轮对话的状态管理要用到状态机或者流程编排的思路工具调用的并发控制要用到生产者消费者模型记忆的存储和清理要用到LRU这类淘汰策略。所以我的观点是如果你是准备当前这个时间点的校招2017年的试卷可以直接拿来当基础能力自测题。算法题做了多少对语言题分析得够不够深系统题能不能答出底层原理——先把这些过了再去学LangChain、LlamaIndex这些框架效率会高得多。反过来如果基础不牢就追新框架大概率是浮沙建塔面试深问两层就露馅。提醒一下现在的有些AI应用岗位笔试已经开始允许在部分环节使用AI辅助工具了。但你依然要理解每段代码的含义依然要能徒手写出核心算法。工具能帮你提速替代不了你的判断力。6. 过来人的备考方法与判卷心得哪些分值得拿哪些坑不值得踩6.1 按性价比分配复习时间别一头扎进难题里我当年备考校招笔试的时候最吃亏的一件事就是把大量时间花在了难题上结果基础题反而丢分。后来我自己参与阅卷才明白一份笔试的分数分布通常是基础题保底、中档题拉开差距、难题锦上添花。大多数人的分数差距不在最后一道压轴题而在前面的选择题、填空题和简答题上。所以复习时间的分配建议是数据结构与算法每天至少刷2道LeetCode中等题坚持一个月。C/C/Java语言基础把高频考点列成清单逐个验证不要只看不写。操作系统和网络画图理解。进程状态的变迁图画一遍TCP连接的状态图画一遍比你背十遍都管用。Android专项用真机写一个完整的Demo把Activity、Service、BroadcastReceiver、ContentProvider四大组件全走一遍。6.2 阅卷时最容易丢分的地方往往不是不会我在阅卷时总结了几个高频丢分点这里一并写出来帮后来人避坑第一代码不规范。变量名叫a、b、c没有缩进没有注释。就算逻辑对了阅卷人第一眼也是劝退的。笔试考的不只是正确性还有你的代码习惯。一个工程师写的代码是要交出去和别人协作的可读性本身就是硬指标。第二不写复杂度分析。一道算法题代码写对了但没写时间复杂度和空间复杂度会扣分吗我的答案是会。因为阅卷人需要确认你是真的理解这个算法而不是碰巧写对了。写上O(nlogn)和O(1)成本极低收益却很高。第三计算题没有步骤。内存对齐、死锁分析、TCP状态变迁这类计算和分析题一定要把推导过程写清楚。很多考生直接给一个结论性的数字或答案错了连步骤分都没有对了也要让阅卷人去猜你怎么想的。第四简答题只答要点不展开。进程和线程的区别只写一句进程是资源分配的基本单位线程是CPU调度的基本单位这是不够的。要展开进程为什么是资源分配的基本单位因为每个进程有独立的地址空间、文件描述符、信号处理器。线程为什么更轻量因为线程共享进程的地址空间切换时不需要切换页表。把逻辑链条写完整才是阅卷人想看到的深度。6.3 笔试题本身也是最好的面试准备素材最后分享一个很实用的心得。不要觉得笔试考完就结束了。把每一道笔试错题整理成一份文档针对每个错题写清楚错在哪里、正确解法是什么、涉及的核心知识点是什么这张文档就是你后续面试的最佳复习材料。一份好的笔试卷它的题目设计是有逻辑的每一道题都在对应一个实际工作场景。你和它死磕一遍就等于把开发工程师的核心知识体系过了一遍。我在实际工作和带人的过程中反复验证过一件事那些在校招笔试里基础题拿满、代码干净、分析步骤完整的人入职之后写代码的质量普遍更高出线上问题的概率更小。反过来笔试靠背题蒙混过关的人往往在入职三个月内就会露出基本功薄弱的短板。所以别嫌笔试烦它其实是用最低的成本帮你和公司双向验证匹配度。2017年的这份试卷已经成为过去但它的考点框架——算法、语言、操作系统、网络、移动开发——至今仍然是开发工程师的立足之本。哪怕现在的AI工具再强大也只是放大了一个人的基础能力不会凭空补上你缺失的那部分工程素养。顺着这套框架往里走把每一步踩实比追任何热点都更值得。
返回列表