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

资讯详情

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

网易2018Android实习生笔试题解析:高频考点与备战指南

网易2018Android实习生笔试题解析:高频考点与备战指南 1. 网易2018实习生招聘笔试题整体拆解一份Android实习生的“体检报告”每年三四月份各大厂的实习生招聘就陆续启动了。2018年那会儿网易的实习生笔试题目在圈子里流传得挺广原因很简单题量适中、覆盖面广而且非常看重基础功底。我当年也刷过这套题后来带团队面试实习生时偶尔还会翻出来参考一下。说句实在话虽然是2018年的题但放到今天来看核心知识点基本没有过时——Android开发的基础栈就那么大变来变去都是那几板斧。先给没参加过这类笔试的朋友交代一下背景。网易的实习生笔试通常采用的是牛客网或赛码网平台Android开发实习生的试卷一般分为三块单选题、多选题和编程题。单选题大概20道左右覆盖Java基础、Android基础、计算机网络和数据结构多选题会有5到10道经常在一些易混淆的API和概念上“挖坑”编程题一般是2道一道偏算法一道偏工程实现。从考察目标来看这套题本质上不是要你写出多惊艳的代码而是要在有限时间里证明三件事第一你的Java功底扎实不扎实第二你对Android的四大组件、消息机制、进程通信这些核心概念有没有真正理解而不是只会调用API第三你遇到问题时的分析思路是否清晰。说白了这就是一份针对实习生的“体检报告”检查你有没有成为一个合格Android工程师的基本潜质。我见过不少同学刷题时只关注“这道题选A还是选B”然后把答案死记硬背下来。这种备考方式在实习生笔试里特别吃亏因为大厂的笔试题变数很大同一个考点换个问法死记答案的人就懵了。所以我写这篇解析的思路是把题目背后真正要考的知识点拎出来讲清楚原理再说说这类知识点在实际开发中会怎么用。这样你以后不管遇到哪个厂的题都能从容应对。2. 高频考点第一梯队Java基础与并发Android岗笔试的地基2.1 面向对象与集合框架别在送分题上丢分Java基础在Android开发实习生的笔试里通常占30%到40%的题量重要性不用多说。网易这套题里面向对象部分考得比较典型我记得有几道题涉及继承中的构造方法调用顺序、接口和抽象类的区别、重载和重写的差异。这些题在概念上并不难但出题人喜欢在细节上做文章。举个典型例子关于构造方法调用顺序那道题父类有静态代码块、非静态代码块、构造方法子类同样有这三者问执行顺序是什么。正确答案是先执行父类静态代码块再执行子类静态代码块然后执行父类非静态代码块和父类构造方法最后执行子类非静态代码块和子类构造方法。这里面的关键点是静态代码块只在类加载时执行一次而且父类先于子类加载。很多同学会记混“非静态代码块和构造方法的先后顺序”我在这里给个记忆技巧非静态代码块和成员变量初始化都在构造方法之前它们按照代码中出现的顺序执行。你可以理解为构造方法是“组装成品”非静态代码块和成员变量初始化是“准备零件”组装前肯定要先准备好零件。集合框架在笔试中的出镜率也相当高尤其是HashMap和ArrayList这两个最常用的。2018年的题目里HashMap还没有变成现在JDK 8那种“数组链表红黑树”的结构但考的点其实差不多HashMap的底层数据结构、扩容机制、put方法的流程、hash碰撞的解决办法。这里我说一个面试官特别喜欢的追问点为什么HashMap的默认负载因子是0.75这个数值是时间和空间成本的一个折中——负载因子太高比如1.0虽然节省了内存空间但hash碰撞的概率增大链表变长查询效率下降负载因子太低比如0.5虽然查询快了但频繁扩容浪费内存。所以0.75这个值本质上是在“空间”和“时间”之间找平衡。ArrayList和LinkedList的区别也是老生常谈但我要提醒一点ArrayList的扩容机制在笔试里经常被细化考察。ArrayList默认容量是10每次扩容为原来的1.5倍也就是oldCapacity (oldCapacity 1)。这个位运算表达式看起来很巧妙实际上就是“原容量加原容量的一半”。为什么不是2倍因为1.5倍的扩容策略在空间利用率和扩容次数之间取得了更好的平衡如果翻倍扩容次数少但浪费空间如果扩得太少频繁System.arraycopy的性能损耗又大了。2.2 并发与线程从底层开始理解笔试才有底气Java并发相关的考点在Android笔试里通常占两道到四道题。网易在这一块考得不深但很讲究概念的准确性。我印象比较深的是一道关于volatile关键字的题问volatile是否能保证原子性以及它和synchronized的区别。正确答案是volatile保证可见性和有序性但不保证原子性。比如i这种操作即使变量被volatile修饰在多线程环境下依然可能出问题因为i在底层是“读取-修改-写入”三步volatile管不了这个复合操作的原子性。关于线程池笔试常考的是ThreadPoolExecutor的几个核心参数——corePoolSize核心线程数、maximumPoolSize最大线程数、keepAliveTime存活时间、workQueue任务队列、RejectedExecutionHandler拒绝策略。网易有一道多选题就是让选出正确的线程池执行流程当提交一个新任务时如果当前运行的线程数小于核心线程数就创建新线程来执行如果大于等于核心线程数就把任务放入队列如果队列满了且线程数小于最大线程数就创建非核心线程执行如果线程数已经达到最大且队列也满了就执行拒绝策略。这个流程在Android开发中极其常用因为很多场景要自己封装线程池来管理异步任务。我在实际项目里踩过一个坑跟线程池的队列选择有关。有次我负责的一个下载模块用的是无界队列LinkedBlockingQueue当时想的是任务多的时候排队等着就行结果遇到高峰期任务积压了几千个内存占用飙升App直接卡顿。后来改成了有界队列ArrayBlockingQueue配合CallerRunsPolicy拒绝策略——线程池满了就让提交任务的线程自己执行虽然偶尔会阻塞UI线程但至少不会内存爆掉。这个经验说明笔试里考线程池参数不是让你背定义而是要理解不同参数组合在真实场景下的表现差异。2.3 内存模型与引用类型JVM考点在Android面试中的变体JVM内存区域划分也是笔试的常客网易喜欢考的是“哪些区域是线程共享的、哪些是线程私有的”。堆和方法区是线程共享的虚拟机栈、本地方法栈、程序计数器是线程私有的。在Android场景里这个知识点会演变成“OOMOutOfMemoryError通常发生在哪个区域”——绝大多数情况下是堆内存不够了但如果你用C通过NDK写代码native层的内存溢出就是另一回事了。强引用、软引用、弱引用、虚引用这四种引用类型笔试里经常以选择题形式出现。Android开发里SoftReference软引用和WeakReference弱引用用得比较多比如图片缓存框架在早期版本会用SoftReference来实现内存敏感的高速缓存但因为软引用在系统内存不足时容易被回收后来大家逐渐改成用LruCache加DiskLruCache配合使用。不过笔试里考引用类型核心还是要记住强引用只要活着就不会被回收软引用在内存不足时会被回收弱引用在下一次GC时就会被回收虚引用随时可能被回收且无法通过它获取对象实例。3. 高频考点第二梯队Android核心机制理解本质比记住答案重要3.1 四大组件Activity和Service是笔试重灾区四大组件是Android笔试的绝对主角Activity和Service更是重灾区中的重灾区。网易这套题里Activity的考察集中在生命周期、启动模式和任务栈三个方向。生命周期不必多说但要注意一个容易忽略的细节在API 28Android 9.0之前onPause之后才能执行onStop期间不允许做过重的操作因为系统会等onPause执行完才让新的Activity可见。这一块笔试很喜欢用场景题来考察比如“Activity A启动Activity B两个Activity的生命周期回调顺序是什么”。完整顺序是A.onPause - B.onCreate - B.onStart - B.onResume - A.onStop。如果B是透明主题或者Dialog样式A只会走到onPause不会走onStop这在开发中是个很实用的经验。启动模式这部分standard、singleTop、singleTask、singleInstance是必背的。网易有一道关于Intent Flag的题目考的是FLAG_ACTIVITY_NEW_TASK和FLAG_ACTIVITY_CLEAR_TOP组合使用的效果。这个组合和singleTask模式的行为基本一致如果任务栈中已经存在目标Activity实例就把这个实例之上的所有Activity出栈然后复用这个实例同时会回调它的onNewIntent而不是onCreate。我在实际开发中用过这个Flag组合来做App的主界面跳转比如从推送通知栏点击跳转到首页时为了避免堆积一堆重复页面就会用这个方案。Service在笔试里的考法比较常规大概率会问startService和bindService的区别以及它们的生命周期。这里有个细节值得注意startService启动的Service如果调用方直接退出Service还是在后台运行需要调用stopService或者Service内部调stopSelf才能停止而bindService启动的Service生命周期和调用方绑定调用方销毁时系统会解绑但如果这个Service之前也用过startService那它还需要通过stopService才能停止。混合使用startService和bindService的场景也是笔试多选题的热门大家把两种方式的独立行为理解透了这种题就不会错。ContentProvider和BroadcastReceiver在笔试里占的比重相对小一些但ContentProvider在2018年的题目里有一道涉及进程间数据共享的题问的是ContentProvider底层用的是什么进程通信机制——答案是Binder。Binder是Android系统最核心的IPC机制之一笔试会问你为什么Android不直接用Linux的管道、消息队列或者共享内存而是自己搞了一个Binder。这个问题我在下文专门讲IPC时展开。3.2 Handler消息机制面试官最爱的连环追问题Handler消息机制是Android开发面试中出镜率最高的考点没有之一。网易的笔试里Handler、Looper、MessageQueue三者的关系属于“标配题”。考察方式一般是让你描述一个完整的消息流转过程Handler发送消息 - 消息进入MessageQueue - Looper通过loop()方法不断从队列中取出消息 - 回调Handler的handleMessage方法处理消息。这里面的关键点在于Looper是整个机制的“发动机”而且每个线程只能有一个Looper实例。主线程的Looper在App启动时就已经通过Looper.prepareMainLooper()创建好了所以我们在主线程里可以直接new Handler使用。但如果在子线程里创建Handler就必须先调用Looper.prepare()创建当前线程的Looper再调用Looper.loop()让它转起来否则会直接抛RuntimeException“Cant create handler inside thread that has not called Looper.prepare()”。还有一个高频考点是Handler的post方法和sendMessage方法有什么区别。本质上它们没有区别post(Runnable)最后还是通过getPostMessage把Runnable包装成了一个Message然后走sendMessageDelayed。所以post和sendMessage殊途同归最终都是往MessageQueue里插入一条消息。死锁问题在Handler机制里也会考在主线程中调用Looper.loop()会不会ANRApplication Not Responding答案是会但这不是死锁而是主线程被阻塞无法处理用户的输入事件。Looper.loop()本身是一个死循环它不断从消息队列里取消息并处理手机系统正是靠这个死循环保证UI线程随时待命。这个点一定要理解透因为面试官会顺着这个问题往下问既然主线程是死循环那为什么不会卡死答案在于没有消息处理时主线程会阻塞在MessageQueue的next()方法中的nativePollOnce里这时候线程是休眠状态不占用CPU一旦有新消息进来系统会通过epoll机制唤醒它。3.3 IPC与Binder理解Android进程通信的设计哲学Android笔试里进程间通信相关的内容一般在选择题中出现一到两道。网易2018年那套题里关于Binder的描述题挺有意思四个选项里有三个是常见的套话比如“Binder性能高是因为只拷贝一次数据”“Binder基于C/S架构”“Binder使用mmap映射内核空间和用户空间”——这些都是对的。有一个错误选项是“Binder是Android基于Linux消息队列实现的”这就是在考你有没有真正搞清楚Binder的底层实现。Binder为什么只拷贝一次数据传统IPC管道、消息队列需要在内核空间和目标进程用户空间之间拷贝两次数据而Binder借助mmap把内核缓冲区和目标进程的用户空间做了地址映射数据只需要从发送进程的用户空间拷贝到内核缓冲区目标进程通过映射直接访问这块区域所以只需要一次拷贝。这个设计在性能上比传统的SharedPreferences那种文件方式要好得多而且足够安全——内核可以为每个进程分配UID在传输过程中自动校验身份。作为Android开发实习生你不需要写出Binder驱动代码但至少要能说出AIDL的基本使用流程定义接口文件实现Stub类在Service的onBind方法中返回这个Binder对象客户端通过bindService拿到IBinder再调用asInterface或asProxy方法。笔试如果考到AIDL支持的参数类型记住基本数据类型、String、CharSequence、List、Map、Parcelable都可以但不能直接传普通的Java对象。3.4 自定义View与事件分发考验空间想象力的硬骨头自定义View这块在2018年的实习生笔试里出现率没有前面那些考点高但一旦出现难度都不低而且网易比较喜欢考事件分发机制和View绘制流程的结合题。事件分发机制的核心是三个方法dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent。笔试会考它们的调用顺序事件先传给最外层的ViewGroup的dispatchTouchEvent然后它的onInterceptTouchEvent决定是自己处理还是继续往下传递。这里有个非常关键也容易混淆的细节子View可以通过requestDisallowInterceptTouchEvent(true)禁止父View拦截事件但父View可以在ACTION_DOWN事件时无视这个请求照常拦截。为什么这样设计因为父View需要确保自己在滑动等场景下能拿到事件的控制权如果子View把事件永久“锁死”在自己手里父View的滑动功能就废了。View的绘制流程也是笔试重点onMeasure测量尺寸 - onLayout确定位置 - onDraw绘制内容。其中MeasureSpec的三种模式——AT_MOST、EXACTLY、UNSPECIFIED——在笔试里经常配合wrap_content和match_parent来考。简单来说match_parent对应EXACTLY规格大小就是父容器剩余空间wrap_content对应AT_MOST视图最大不能超过父容器剩余空间ListView、ScrollView这种可滚动容器里面的item在测量时可能会收到UNSPECIFIED意思是不限定大小。我在实际开发中自定义View时经常处理wrap_content相关的问题很多初学者自定义View时会忘记处理wrap_content的情况导致设置无效——这背后的原因就是在onMeasure里直接把宽高写死了没有根据MeasureSpec的不同模式做分支处理。3.5 序列化与数据存储Parcelable和Serializable的对比考点关于序列化网易笔试考了一道Parcelable和Serializable的区别。这两个都能实现对象的序列化和反序列化但Parcelable是Android专有的性能更高用于进程间通信和Intent传对象时使用Serializable是Java原生的使用方便但利用反射机制序列化和反序列化时性能较差而且会创建大量临时对象容易引发GC。这里有一个容易踩坑的点Intent传递自定义对象时如果对象实现了Serializable接口可以直接putExtra传进去但如果这个对象里面嵌套了其他对象那所有嵌套对象也必须实现Serializable否则会抛NotSerializableException。Parcelable也有类似的约束嵌套对象要实现Parcelable或者用Bundle包装。另外Parcelable的writeToParcel方法中写变量的顺序必须和CREATOR中读出来的顺序保持一致否则运行时会得到错误数据这个Bug排查起来非常隐蔽因为编译期完全不会报错。Android本地存储方面笔试常考的是SharedPreferences和SQLite。SharedPreferences底层是XML文件适合存储轻量级的键值对数据但不适合存大量数据而且跨进程读取时会有并发问题——即使是官方后来推出的SharedPreferences的多进程模式也只是做了文件锁性能堪忧所以实际开发中如果多进程场景需要共享数据我一般会直接用ContentProvider或者数据库。SQLite在笔试里考得不多一般问一下SQLiteOpenHelper的onCreate和onUpgrade回调时机就差不多了但有个细节值得提起数据库升级时如果只增加了一张表只要在onUpgrade里执行CREATE TABLE语句就行但如果改动的是已有表的结构比如加字段就要用ALTER TABLE或者重建表加数据迁移这一环没做好线上用户升级App后很容易出现“no such column”崩溃。4. 性能优化与专项考点笔试里的“隐性加分项”4.1 内存泄漏与OOM必考的三板斧排查思路Android笔试题里性能优化相关的内容一般作为“区分度”题目出现网易也差不多。内存泄漏这块考得最多的是Handler造成的内存泄漏和静态变量持有Activity引用。Handler为什么会导致内存泄漏原因是MessageQueue中等待处理的Message持有Handler的引用Handler如果是非静态内部类就会持有外部Activity的引用。如果消息一直没被处理比如延迟了很长时间或者Activity已经销毁但消息还没有被取出Activity就无法被GC回收。解决方法是使用静态内部类加WeakReference同时在Activity的onDestroy方法中调用mHandler.removeCallbacksAndMessages(null)清掉所有未处理的消息。这个内存泄漏场景在实际开发中非常常见我被坑过不止一次。有个项目在做启动页倒计时时用了Handler.postDelayed发了一个延迟消息结果有个用户在倒计时还没结束就退出了App后面反复横跳几次内存就蹭蹭往上涨。后来排查发现就是这个问题——Activity销毁后Handler里还挂着一个延迟消息没清理。修复方案也很简单onDestroy里移除所有回调和消息即可代码就一行但如果不了解背后的原理根本想不到问题出在这里。OOM的考察点主要集中在“哪些操作容易导致OOM”。常见的答案是加载大图片、内存缓存没有限制、频繁创建对象。图片加载这关对Android开发来说几乎无法避免Bitmap在内存中的占用计算方式是宽度 x 高度 x 每像素字节数。ARGB_8888模式下一个像素占4字节一张1920x1080的图片在内存中就要占用约8MB。笔试如果给你一张图片的尺寸和颜色格式让你算内存占用你要会这个公式。优化思路一般是压缩采样率inSampleSize、使用RGB_565模式一个像素占2字节、配合LruCache做内存缓存。4.2 ANR与进程优先级为什么主线程不能做耗时操作ANRApplication Not Responding相关知识点在笔试中出现的频率也不低网易喜欢考的是ANR的触发条件。Android系统对主线程有时间上的硬性约束BroadcastReceiver的onReceive在10秒内没执行完会ANRService的onCreate等生命周期在20秒内没处理完会ANR输入事件屏幕点击、滑动在5秒内没有被处理完也就是主线程阻塞超过5秒会产生InputDispatching Timeout类型的ANR。备考时不要只记时间要理解底层逻辑主线程的Looper负责处理所有UI事件如果主线程被耗时操作阻塞用户点击屏幕后系统发出的输入事件就一直排在消息队列里得不到处理超过一定时间系统就判定应用无响应。所以“不要在主线程做耗时操作”这个开发铁律本质上就是保证消息队列畅通。笔试还有一道关于进程优先级的题前台进程 可见进程 服务进程 后台进程 空进程。这个优先级决定了一个App进程被系统杀掉的先后顺序优先级越低的进程越容易被LMKLow Memory Killer回收。比如手机内存不足时系统会优先杀掉空进程和后台进程来释放内存。应用开发中常见的优化做法是用前台Service或者WorkManager来提升后台任务的存活率但这块涉及的内容比较敏感——不是技术上的敏感而是国内不同手机厂商的杀后台策略差异很大这里就不展开说了笔试也不会深挖到厂商定制系统层面。4.3 网络与数据解析HttpURLConnection与图片加载的笔试常规题网络相关的题目在Android开发实习生笔试里不算特别多但也不缺席。网易2018年的题里就有一道关于HTTP状态码的选择题问201、301、302、401、404这些状态码的含义。常见的坑是301是永久重定向302是临时重定向401是未授权需要认证403才是禁止访问服务器理解了请求但拒绝执行404是资源不存在。这道题本质上考的不是Android知识而是计算机基础所以想进大厂HTTP协议还是要认真过一遍。Retrofit、OkHttp、Glide这些网络和图片加载库笔试主考的是缓存策略和线程调度机制。比如Glide的三级缓存活动资源内存缓存中正在使用的资源、内存缓存LRU算法管理、磁盘缓存。图片加载流程大致是检查活动资源 - 检查内存缓存 - 检查磁盘缓存 - 网络下载。这个流程和后面要说的LruCache原理是相通的。OkHttp的拦截器机制也是特色考点它会按照添加顺序把多个拦截器组成一个责任链从上到下依次执行。应用拦截器和网络拦截器的区别在于应用拦截器能看到的是请求的原始状态而网络拦截器能看到经过重试、重定向之后的最终请求所以在日志打印、修改header这些场景要选对拦截器类型。笔试不会考得非常细但至少要知道OkHttp的拦截器是可以拆解整个网络请求流程的。5. 算法与编程题如何在笔试中拿下两道送分保命题5.1 常见算法题类型排序、链表、二叉树、动态规划网易实习生笔试的编程题正常情况下是一道简单偏中等、一道中等偏难的组合。简单那道通常可以用基本数据结构和算法解决难的那道会涉及动态规划、贪心或者二分查找。2018年的Android开发实习生的编程题听说是有字符串处理的题目和一道动态规划的题目。针对Android岗位的笔试编程题刷题范围其实很明确。排序算法要掌握快排和归并排序的思路以及它们的平均复杂度和最坏复杂度快排平均O(nlogn)最坏O(n²)归并排序稳定在O(nlogn)但需要额外空间。链表类的题目要会反转链表、判断是否有环、找倒数第K个节点这些题在牛客和LeetCode上都是热题。二叉树要掌握前中后序遍历和层序遍历其中层序遍历比较常考用队列实现。动态规划是很多人的噩梦但实习生笔试里的DP题一般不会太变态最多考个背包问题或者简单的线性DP。以背包问题为例你需要能写出二维dp数组的版本然后能解释清楚状态转移方程的含义——dp[i][j]表示前i个物品在容量为j的背包中能获得的最大价值转移方程是dp[i][j] max(dp[i-1][j], dp[i-1][j-w[i]] v[i])。这里有个面试官爱追问的点为什么要倒序遍历j因为要保证每个物品只被选一次倒序遍历时可以避免在同一个物品上重复选择。5.2 编程题的实战策略先暴力、后优化、再兜底笔试编程题的实战策略很重要。很多同学一上来就死磕最优解结果卡了半小时没写出来其他题也没时间做。我的建议是先快速用暴力解法把题目过了确保有分如果时间还有富余再优化复杂度。毕竟笔试系统只以最后提交的代码能不能ACAccepted为准不看你过程多优雅。如果是LeetCode上做练习建议按标签来刷比如“数组操作”刷半个月、“链表”刷一周、“二叉树”刷一周、“动态规划”刷两周。Java提交代码时有个细节要留意数组和List之间的转换要熟练因为笔试现场经常需要快速构造辅助的数据结构如果API都记不熟写的时候会非常痛苦。编程题还有一个经常被忽略的点输入输出格式。牛客上的笔试编程题第一行通常是一个整数n表示数据个数接下来一行是n个整数你要能用BufferedReader和BufferedWriter做高效的输入输出。用Scanner虽然写起来简单但在数据量大的场景下性能会差不少。而且笔试环境一般不给调试提示交上去超时了也不会告诉你到底超在哪里所以平时练习时就要养成用高效IO的习惯。我在牛客上刷题时一开始用Scanner后来数据量大的一道题就超时了换成BufferedReader之后秒过这个教训还挺深刻的。5.3 一道典型的动态规划笔试题从题目文本到AC代码我之前刷过一道类似网易风格的编程题题目描述大致是这样给定一个长度为n的数组每次操作可以把任意一个元素加1问最少需要多少次操作能让数组中所有元素相等。这道题看似简单实际上有个很直接的数学结论把所有元素变成中位数需要的总变动次数最少。因为中位数到所有数字的距离和是最小的小于平均值。所以解法就是排序取中位数然后遍历累加每个元素与中位数的差值的绝对值。时间复杂度O(nlogn)主要来自排序。代码实现大概长这样import java.util.Arrays; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc new Scanner(System.in); int n sc.nextInt(); int[] arr new int[n]; for (int i 0; i n; i) { arr[i] sc.nextInt(); } Arrays.sort(arr); int median arr[n / 2]; long ans 0; for (int num : arr) { ans Math.abs(num - median); } System.out.println(ans); sc.close(); } }注意这里ans要用long类型因为最坏情况下数组长度很大、数值差异很大时int会溢出。这个细节在笔试中非常容易被忽略需要特别留意。如果再延伸一下这道题可以变成“每次操作可以让一个元素加1或减1问最少操作几次让所有元素相等”。答案还是一样的取中位数。6. 高频考点第三梯队Android Studio与工程化能力笔试之外的隐性考察6.1 从工具考察看网易对实习生的工程预期虽然很多笔试题目都是选择题形式但网易这种级别的公司其实很看重候选人的工程化能力。2018年的Android题目里偶尔会夹杂一两道和Android Studio、Gradle、依赖管理相关的题目问的是apk打包流程、混淆配置这些。先说Gradle这块笔试可能会问Android工程的构建流程Java源码 - javac编译成.class文件 - 结合第三方库和资源文件 - 通过D8/R8编译成dex文件 - 打包成apk - 签名 - 对齐。Android Gradle Plugin更新到8.0以后构建工具链变化比较大但核心流程还是这些。作为实习生你不需要精通Gradle插件开发但至少要能看懂build.gradle里的常用配置。关于R8/混淆笔试不会考太深通常是问混淆配置的作用。常见的混淆配置包括keep规则不混淆某个类的完整类名-keep class com.example.bean.** { *; }、不混淆某个方法-keepclassmembers、去掉日志输出-assumenosideeffects搭配Log等。这部分的实操性很强如果实际没做过理解起来会有点抽象。我的建议是自己找个项目在debug和release两种模式下分别打一次包对比一下apk的字节大小和反编译后的代码内容体感会强很多。6.2 版本适配与兼容性大厂格外看重的隐性能力大厂的实习生笔试不会明着考版本适配但在一些开放性的选择题中偶尔会以“Android 8.0通知渠道”“Android 6.0运行时权限”这样的方式出现。你要知道Android 6.0开始引入了动态权限机制危险权限需要在运行时申请不能只在Manifest里声明Android 8.0开始引入了通知渠道NotificationChannel创建通知时必须指定一个channel否则通知不显示。这些版本变化背后其实暗示了一件事优秀工程师要有兼容性意识。不同版本的Android系统行为和API差异非常大开发时如果只在自己手机上调试上线后很容易翻车。我记得有次用了Android 9.0的API来获取设备唯一标识结果在Android 8.0的测试机上直接崩了后来加了Build.VERSION.SDK_INT判断才解决。这就是典型的兼容性意识不足。6.3 第三方框架的使用会调API不算真会理解原理才加分实习生笔试一般不直接考Retrofit和Glide的源码细节但面试环节有极大可能问到“你用过哪些第三方库它们是怎么实现的”。笔试阶段相关的选择题一般围绕注解、反射等基础概念来出。建议你在准备笔试的时候把常用的第三方框架的底层原理过一遍这里挑几个高频的Retrofit的核心是“动态代理注解解析”OkHttp的核心是“Dispatcher拦截器链”Glide的核心是“三级缓存生命周期感知”EventBus的核心是“注解反射”。能把这些原理说清楚笔试和面试的通过率都会大幅提升。虽然2018年的题目没有直接列明这些框架的源码但我猜很多同学遇到Retrofit相关题时就是把注解处理器、动态代理这些词往选项里怼基础扎实的人一眼就能选出正确答案。7. 常见问题与备考建议刷题之外的避坑经验7.1 笔试中最容易翻车的三个坑第一个坑是Java基础不牢就冲Android题。很多初学者Android用得很爽但一考到HashMap扩容、线程池拒绝策略、类加载顺序就露馅。笔试中Java相关的题往往占比不低如果你Java基础薄弱刷再多的Android题也补不回来。建议先把《Java编程思想》中集合与并发两章精读一遍再做几套往年的真题摸一遍底。第二个坑是会写代码不会选答案。笔试中的选择题尤其是多选题喜欢在一些边界条件上做文章。比如“以下哪些方法会阻塞主线程”很多人只记得Thread.sleep阻塞忘了Looper.loop()本身其实也是阻塞的。这类细节只有通过刷题才能暴露出来所以做真题错题集是非常必要的。第三个坑是时间分配不合理。网易这种笔试题型多、时间紧我的经验是先做会做的不会的题标记一下最后再回头思考。编程题如果一时没有思路最多留20分钟写个暴力解法保证过测试点比死磕最优解要实际得多。毕竟笔试的加分是看分数线的拿到基础分比追求满分稳妥。7.2 真题之外如何系统化准备Android实习笔试我的建议是分三步走。第一步夯实基础Java集合、JVM内存、并发编程、网络协议、数据库基础这些属于通用基础任何方向的实习生都会被考察。第二步Android专项四大组件生命周期、Handler消息机制、Binder、自定义View、事件分发、序列化、存储方式、性能优化、ANR与OOM这些是Android岗的必考范围。第三步刷题和总结每周至少刷10道LeetCode算法题同时整理一份错题集把每道错题背后的知识点写清楚考前集中翻阅。还有一点值得提的是网易笔试之后通常紧跟一轮专业面试。面试官可能会顺着你笔试的答案深挖比如你选了“Binder性能高是因为只拷贝一次数据”面试官就可能会问“一次拷贝具体是怎么实现的”。所以备考笔试不能只看题目本身要带着“再往下深挖一层”的心态去准备。7.3 笔试之后的复盘从错题中找到知识盲区笔试结束不等于学习结束但我发现很多同学考完就丢这是最可惜的。笔试是一个极好的知识自测机会你应该在考后把每一道拿不准的题目都翻一遍书为什么是这样我当时为什么选错正确的结论还有哪些延伸我每次带实习生都会建议他们把笔试当成一次“学习地图”因为考试范围往往就是业内公认的工程师必备知识清单把每道题背后的知识网络展开学习效率和效果都比漫无目的地刷帖子好得多。另外很多笔试平台牛客等在活动结束后会放出题目解析但2018年的题在网上还能找到原题截图和一些考生的回忆版解析只是不够系统。你可以搜一下“网易2018实习生招聘笔试题Android”这个关键词再搭配“牛客网 Android 笔试题”一起看能搜到不少别人整理的题解。我在写这篇博文时也参考了当年几位网友分享的回忆版题目在这里一并感谢他们的分享。我把公共考点整理成了一份参考表帮助大家快速对照自查。考察方向核心知识点高频题型准备优先级Java基础集合、并发、JVM内存、序列化选择/多选高Android基础四大组件、Handler、Binder选择/多选高自定义View测量布局绘制、事件分发选择/多选中性能优化内存泄漏、ANR、OOM选择/多选中网络与数据HTTP状态码、图片加载缓存选择/多选中算法编程排序、链表、二叉树、DP编程题高工具链Gradle、混淆、版本适配选择/问答低这套表是我根据自己的经验整理的优先级排序供大家参考。总体思路很清晰Java基础和Android核心机制是第一优先级算法题是第二优先级工具链和工程化能力是“加分项”。备考时不要本末倒置把大量时间花在研究Gradle插件上而忽略了Handler和四大组件这些真正的核心考点。8. 写在最后一份“过来人”的备战心得我自己备考时走过不少弯路最深刻的体会是Android开发实习生的笔试本质上考的是“你有没有在真实开发中咂摸过这些底层机制的味道”。死记硬背的答案在选择题里也许能对但到了面试环节一问细节就崩。所以准备笔试最好的方式不是刷几套题而是把每一个考点放到真实项目里去理解。比如你写一个网络请求工具顺手想想OkHttp的拦截器链是怎么设计的你做一个头像上传功能顺手想想Bitmap采样压缩和内存占用的关系你的App偶尔卡顿顺手用Profile工具定位一下是不是主线程被耗时操作阻塞了——这些都是把知识从“做题”变成“内化”的过程。回到“网易2018实习生招聘笔试题-Android开发实习生”这个标题虽然年份已经过去这么久但题目背后的考点体系依然是Android岗位笔试的核心框架。我在写这篇博文时也把当年纠结过的一些细节重新梳理了一遍有一种温故而知新的感觉。如果你正在准备Android实习生的笔试不妨按照我整理的这些方向逐个过一遍再搭配真题练手相信你会比当年的我准备得更加扎实。祝顺利。
返回列表