ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

顺丰科技安卓笔试客观题全解析:从Java基础到Handler与Binder核心考点

顺丰科技安卓笔试客观题全解析:从Java基础到Handler与Binder核心考点 1. 顺丰科技安卓笔试的底层逻辑这不是一份普通的题库1.1 为什么专业笔试还留在“客观题”这一关先把这个标题拆开看。顺丰科技2019秋招的安卓开发工程师岗位笔试第一关是客观题合集这意味着他们并不仅仅想看你有没有做过几个Demo而是要在一个小时内快速筛掉一批基础不扎实的候选人。物流行业的移动端技术核心场景是快递员App、仓储移动终端、地图轨迹追踪、扫码枪硬件适配这几块业务对“安卓基本功”的依赖程度非常高。我当年秋招时也刷过不少这类型企业的安卓笔试题。一个明显感受是客观题覆盖面很广但深度并不刁钻题目不会让你手写一个插件化框架也不会考你Flutter的渲染原理而是把Android开发中最容易被忽略、最容易混淆的细节拿出来反复考。比如四大组件的启动流程、Handler消息机制、进程间通信、View事件分发、屏幕适配、Java集合与并发。这些知识点单独拿出来都不难但组合起来放在一道道选择题里就非常考验你平时是真懂还是死记硬背。另一个值得注意的点是这份笔试的“客观题合集”属性决定了它同时考察了候选人对概念边界的敏感度。换句话说很多题目的选项之间只差一个限定词比如“一定会”“快速”“内存中”你有没有认真抠过这些措辞直接决定正确率。1.2 顺丰科技移动端业务的岗位画像在聊题目本身之前先花点篇幅说一说顺丰科技的安卓岗到底在做什么。只有理解了岗位背景你才能明白为什么笔试里会出现某些特定题目。顺丰科技是物流行业里技术投入比较激进的公司移动端覆盖的场景包括快递员揽派件App高频、弱网、强地理位置依赖、中转场/仓储的手持终端工业级扫码、RFID、离线缓存、司机端App路径导航、电子回单、以及面向C端的服务入口。这些场景共同指向几个关键技术点弱网环境下的数据同步与重试机制快递员在地下室、电梯间、偏远区域操作App是常态所以网络请求的超时处理、幂等重试、缓存策略会高频出现。地图与定位服务的深度集成轨迹回传、电子围栏、派件路径规划这要求在笔试里考察对定位组件生命周期和经纬度纠偏的理解。工业级硬件的适配手持终端屏幕尺寸差异大、系统版本定制化严重屏幕适配和系统兼容性题目也就顺理成章。所以你会发现这份客观题合集并不是纯粹刷LeetCode式的数据结构题而是把安卓开发者日常工作中最核心的那几个轮子拆开看看候选人对它们的理解到了哪个层次。1.3 关于“2019”这个时间点的特殊性为什么强调2019年因为那一年的安卓技术栈处于一个很微妙的转型期。Kotlin已经成为官方推荐语言但大量存量代码还是JavaAndroidX正在全面替换support库组件化和插件化的讨论热度很高Flutter刚发布了1.0正式版但尚未大面积铺开Gradle版本变革让构建脚本玩法变多。这个背景下笔试客观题呈现出一种“新旧交织”的特点既考老的Java基础因为业务代码里大量存在也开始试探性地考察候选人对新技术的态度。所以准备这套题的时候不要只盯着纯Android框架复习Java虚拟机层面的内存机制、并发工具类、集合的底层实现同样是重头戏而且这些内容放在今天也仍然适用。2. Java基础与内存机制的“送分题”真的送分吗2.1 HashMap的resize与红黑树既要选对还要说得清Java集合类题目在安卓笔试中出现频率极高尤其是HashMap、ArrayList、HashSet三者之间的区别与内部实现。出题人非常喜欢在“容量与扩容”上面做文章。题目示例关于HashMap的描述正确的是 A. HashMap允许key为null但最多只允许一个key为null B. HashMap是线程安全的集合类 C. HashMap的默认容量是16加载因子是0.75当元素数量超过阈值时容量会以2倍方式扩容 D. HashMap在Java 8中引入红黑树当链表长度超过6时转换为红黑树这题考察几个关键点。A选项有一个隐蔽的坑HashMap确实允许null键但“最多只允许一个key为null”的前提是键的唯一性但如果你把null存进去之后再put一个null它的value是会被覆盖的所以这个“最多允许一个”说法本质上不严谨。B选项在单线程环境下是安全的但多线程操作时可能造成死循环和数据丢失因此绝不能选。C选项默认容量16、加载因子0.75正确扩容阈值是容量乘加载因子等于12新容量是旧容量左移一位也就是2倍这个说法是对的。D选项Java 8确实在链表长度达到8且数组容量不小于64时转为红黑树如果数组容量不到64会先做resize所以D选项的“超过6”是有问题的准确说法是“达到8”而且这个8指的是链表节点数量。我在准备这类题目时有个经验把每个选项当成“判断题”来对待。先判断对错再思考这句话在什么边界条件下不成立。HashMap这种题本质上考的是集合框架源码的细节如果你只是背了结论很容易被D这种“看起来对但数值错了”的选项迷惑。2.2 线程池参数组合最容易被绕进去的选择题安卓开发绕不开多线程笔试里线程池的题目几乎必考。但出题人通常不会直接问“请简述线程池的工作原理”而是给出一组参数让你判断线程池的行为。题目示例某线程池核心线程数corePoolSize2最大线程数maximumPoolSize5阻塞队列长度为3当前同时有8个任务提交。在不考虑拒绝策略的情况下这8个任务中最终会有多少个任务被立即执行这道题考的是ThreadPoolExecutor的执行流程。任务是定时器逐个提交还是同时提交会影响结果。如果是同一瞬间提交8个任务那么前2个任务会占据核心线程剩余6个任务会进入阻塞队列但队列长度只有3所以前5个任务2个核心线程3个队列位置会被接收第6个任务到达时队列已满且工作线程数2小于最大线程数5因此会新建非核心线程执行第7、8个任务到来时发现队列已满工作线程数已经达到5此时会触发饱和策略。所以“立即执行”的任务数量是2个核心任务加1个非核心任务共3个。但这个题经常被改写成“任务逐个提交”的形式。逐个提交时前2个任务启动核心线程第3到第5个任务进入队列第6个任务触发非核心线程第7、8个任务继续进入队列还是触发拒绝策略取决于提交顺序和线程执行速度。所以看到这种题第一步永远是要判断提交模式。我给准备笔试的朋友一个建议一定要背下来ThreadPoolExecutor的完整执行流程——先核心线程再阻塞队列再最大线程数最后拒绝策略。这四个步骤的顺序不能乱几乎所有线程池选择题都围绕这个顺序做变形。2.3 引用类型与可达性分析GC题目的标准解法Java垃圾回收相关题目也是笔试常客。特别是四种引用类型——强引用、软引用、弱引用、虚引用——它们的回收时机和应用场景经常混合在一起考察。题目示例关于软引用和弱引用下列说法错误的是 A. 软引用指向的对象在内存充足时不会被回收 B. 弱引用指向的对象在下一次GC时就会被回收 C. 软引用适合实现图片缓存 D. 弱引用适合实现Handler中的Message存储这道题里A和B对应的是基本定义。软引用在内存不足时会被回收内存充足时不会被回收所以A正确。弱引用的生命周期只到下一次GC之前所以B正确。C选项软引用确实适合做缓存但工程上图片缓存一般使用LRU算法加软引用的组合单独说“适合实现图片缓存”也没有问题。D选项就有问题了Handler中的Message会通过obtainMessage复用来避免重复创建Message本身并不依赖弱引用而在Handler中使用弱引用通常是用来持有Activity实例以避免内存泄漏而不是“存储Message”。这道题真正的陷阱是D选项。很多候选人知道Handler内存泄漏是因为内部类持有外部Activity引用解决办法就是改成弱引用但他们不会去细分“弱引用是持有Activity而不是持有Message”。这就是典型的“只记得结论、没记住对象”的失分点。所以复习引用类型时一定要把“谁持有谁”这个关系理清楚而不是只记“弱引用适合Handler”。3. Android核心机制客观题Handler、Binder、启动模式3.1 Handler消息循环从“主线程可以Looper吗”说起Handler是安卓面试里出现频率最高的机制笔试也不例外。但客观题对Handler的考察通常不会停留在“Handler用于子线程更新UI”这个层面而是会深入消息队列的细节。题目示例关于Handler机制下列说法错误的是 A. 主线程默认存在Looper可以直接创建Handler B. 子线程中创建Handler前必须先调用Looper.prepare()否则会抛出RuntimeException C. MessageQueue的消息按优先级排列异步消息优先级高于同步消息 D. Handler的dispatchMessage方法会优先处理Callback回调其次是handleMessageA和B属于基础知识主线程在ActivityThread的main方法中已经调用了Looper.prepareMainLooper所以主线程可以直接new Handler。子线程则必须手动调用Looper.prepare()否则拿不到当前线程的LooperHandler构造函数会通过ThreadLocal查找失败抛出异常。C选项有个关键点MessageQueue里同步和异步消息的先后取决于消息的when时间戳正常情况下按时间排序异步消息并没有天然的优先权除非启用了Barrier同步屏障。所以C说“异步消息优先级高于同步消息”是不严谨的。D选项是对的dispatchMessage的优先级是Message.callback Handler.mCallback handleMessage。这道题的难点在于C。如果你只背同步屏障的概念知道异步消息被优先处理就会误以为“异步消息永远优先”。实际上异步消息只有在同步屏障存在时才会被优先取出而日常开发中普通消息的排序依据是执行时间。出题人就是利用这种“概念混用”来制造干扰项。这里给一个复习建议Handler机制不要只看博客结论一定要自己手写一遍Looper、MessageQueue、Handler三者之间的调用关系尤其是MessageQueue.next()方法中关于同步屏障和空闲消息的处理逻辑。笔试虽然是客观题但对原理理解的深度直接体现在你能否识别出C这种模糊表述上。3.2 Binder与进程通信把“一次拷贝”说到点子上Binder是安卓进程间通信的核心机制也是笔试客观题里“看起来很高级、实际上高频出现的考点”。物流App里大量涉及进程间通信比如定位服务与主进程的交互、后台任务与UI进程的数据传递所以这块知识是实打实的业务需求。题目示例关于Binder机制下列说法正确的是 A. Binder通信时数据拷贝次数为两次 B. Binder使用内存映射完成数据传递进程间数据只拷贝一次 C. 所有跨进程通信必须使用Binder D. Binder通信时客户端与服务端的交互是同步的无法做到异步B选项是核心。Binder通过mmap把内核空间的一块缓冲区映射到用户空间数据从发送进程拷贝到内核缓冲区接收进程可以直接访问所以只需要一次拷贝。A说两次是为传统管道设计的说法不是Binder的特征。C选项过于绝对跨进程通信还有其他方式比如Socket、共享内存并不是所有场景都必须用Binder。D选项也不对Binder本身支持异步调用比如oneway关键字就是用来标记异步Binder调用的。很多人在复习Binder时会被“代理”“Stub”“transact”这些词劝退但客观题考察的重点其实是“架构特点性能特征”。只要抓住三个关键词一次拷贝、内存映射、进程隔离大部分Binder选择题都能应付。假如遇到更深一点的题问“为什么要用Binder而不是Socket”可以从性能、安全、稳定性三个角度回答Binder一次拷贝优于Socket的两次拷贝Binder在内核态完成身份校验比Socket的UUID验证更安全Binder对调用超时有更细粒度的控制。3.3 Activity启动模式singleTask、singleTop、singleInstance边界题启动模式也是客观题重灾区。四个启动模式的区别本身不复杂但出题人最喜欢把“面试者的直觉”作为干扰项设计一种看似正确、细想有漏洞的表述。题目示例关于Activity启动模式下列说法错误的是 A. 设置了singleTop的Activity如果已经位于栈顶再次启动时不会创建新实例而是回调onNewIntent B. 设置了singleTask的Activity如果栈中已存在实例再次启动时会清空该实例之上的所有Activity C. 设置了singleInstance的Activity会独占一个新的任务栈且栈中只能存在这一个Activity D. 设置了standard的Activity每次启动都会创建新的实例并且回退时按后进先出原则出栈A选项singleTop在栈顶时确实不创建新实例回调onNewIntent但如果Activity不在栈顶呢那就和standard一样创建新实例。选项A没有说明“必须位于栈顶”这个前提所以它是错误的。B选项singleTask的清栈行为是存在的系统会把该Activity之上的Activity全部销毁使其回到栈顶。C选项singleInstance确实独占一个Task且这个Task只会放这一个Activity。D选项standard每次启动创建新实例按栈的先进后出出栈没问题。这道题的陷阱在于A选项的表述。很多人一看到“singleTop”就直接选了正确忽略了“位于栈顶”这个重要前提。我在复习启动模式时会把每个模式拆成两个维度来理解一是在什么条件下创建新实例二是创建新实例时对现有任务栈做什么操作。只要把这两个维度对照起来A这种干扰项一眼就能识别。另外这些启动模式在物流手持终端的App里有大量实际应用。扫码页面、派件确认页面通常需要设置为singleTop避免连续扫码时创建大量重复Activity而主界面一般使用singleTask保证从任意二级页面回到首页时不会堆积几十层页面。这种业务知识在笔试中出现时会给面试官留下好印象。4. View机制与屏幕适配高频选择题4.1 View绘制流程onMeasure/onLayout/onDraw的调用顺序题View的绘制体系是安卓开发的重中之重笔试客观题几乎不会缺席。出题方向非常明确绘制流程的调用顺序、MeasureSpec的生成规则、LayoutParams与MeasureSpec的关系。题目示例在自定义View的测量阶段关于MeasureSpec的说法正确的是 A. MeasureSpec由父View的MeasureSpec和子View的LayoutParams共同决定 B. 当子View的LayoutParams为wrap_content时MeasureSpec的mode一定是AT_MOST C. 当子View的LayoutParams为match_parent时MeasureSpec的mode一定是EXACTLY D. 当父View的MeasureSpec为EXACTLY时子View的MeasureSpec一定是EXACTLY这题的标准解法要分情况讨论。子View的MeasureSpec由父View的MeasureSpec和子View自己的LayoutParams通过getChildMeasureSpec计算得出所以A正确。B选项子View是wrap_content时如果父View是EXACTLY或AT_MOST模式子View得到的specMode是AT_MOST但如果父View是UNSPECIFIEDwrap_content得到的也是UNSPECIFIED所以B不绝对成立。C选项match_parent在父View是EXACTLY时得到EXACTLY但父View如果是AT_MOSTmatch_parent得到的是AT_MOST。D选项和C类似父View为EXACTLY时子View为wrap_content的话mode是AT_MOST所以D也错。这道题的核心在于“MeasureSpec的不确定性来源”。我建议把这个考点整理成一张判断表先看父View的specMode再看子View的LayoutParams然后确定最终的specMode。很多人在复习时只背了“wrap_content AT_MOST、match_parent EXACTLY”但这只适用于父View是EXACTLY的情况一旦父View是AT_MOST或UNSPECIFIED结论立刻翻车。4.2 事件分发dispatchTouchEvent与onInterceptTouchEvent的选择题陷阱事件分发机制复杂、规律性又强是笔试里区分度最高的一类题目。出题人很少直接问三个方法的调用顺序因为顺序太简单了他们会把问题包装成“如果一个事件被子View消费了后续事件还会不会传给父View”这样的递进式问题。题目示例一个ViewGroup中包含一个子View手指在子View上按下并滑动。如果子View的onTouchEvent返回false那么接下来滑动事件的流向是 A. 事件会先传递给子View再由子View逐级向上返回给父View B. 事件会直接传递给父View的onTouchEvent不再传给子View C. 事件会先经过父View的onInterceptTouchEvent再由父View的dispatchTouchEvent决定是否传回子View D. 事件会直接消失后续事件不再派发事件分发的核心逻辑是DOWN事件决定了后续事件序列的接收者。如果子View的onTouchEvent对DOWN返回false说明这个子View不消费此次事件序列那么整个事件序列包括MOVE、UP都不会再传给子View。后续的MOVE事件会直接交给父View的事件处理链但前提是父View的dispatchTouchEvent在派发时已经知道子View不消费。此时父View的onInterceptTouchEvent还会不会被调用实际上在ViewGroup分发逻辑里一旦判断子View不消费DOWN事件会把FLAG_DISALLOW_INTERCEPT的状态重置但后续事件传递时由于target已经变为null事件不会进入子View而是走父View自身的处理逻辑。所以最准确的描述是事件会交给父View的onTouchEvent处理但在到达onTouchEvent之前仍会经过父View的dispatchTouchEvent是否调用onInterceptTouchEvent取决于父View的实现。选项C说的“先经过onInterceptTouchEvent”并不完全准确因为拦截器是父View主动控制的子View不消费DOWN事件后父View会直接处理而不一定走拦截逻辑。其实在客观题里这类复杂分支很少直接考更多会考“DOWN返回false后整个事件序列不会再传给子View”这个结论。但为了保险起见建议还是把ViewGroup.dispatchTouchEvent的源码流程走一遍尤其是ACTION_CASE的临时状态、removePointers和target为null的分支处理搞懂之后无论题目怎么变都能应对。4.3 dp/sp/px换算与多屏幕适配计算题的正确姿势物流类App有一个特点需要适配的设备形态特别多从普通手机到扫码枪、车载中控屏密度各不相同。所以屏幕适配和单位换算的题目概率很高。题目示例若设备的屏幕密度为320dpi屏幕宽度为1080px将该设备宽度换算为dp后的数值是 A. 360dp B. 540dp C. 720dp D. 1080dpdp和px的换算公式是dp px / (density / 160)也就是dp px * 160 / dpi。代入数据1080 * 160 / 320 540dp。所以选B。这道题本身计算量很小但有一个容易忽略的点density dpi / 160320dpi对应的density是2.01080px除以2.0等于540dp。我在复习屏幕适配时还会额外注意sp和dp的区别。sp在用户调整系统字体大小后会变化dp不会。如果某个题目问“使用什么单位可以保证字体不受系统设置影响”应该选dp而不是sp。另外Android推荐使用dp用于布局间距、sp用于字体大小但在物流扫码类设备上很多定制ROM的字体缩放行为并不标准工程上有时也会直接用dp写字体以避免布局错乱。笔试中如果遇到这种场景化的问法要结合题干背景来判断。5. 高频易错客观题复盘那些“看似正确”的干扰项5.1 题干陷阱把“错误的是”看成“正确的是”考试时间紧张的时候最容易犯的低级错误是看错题目要求。举个例子如果四个选项中只有一个是错误描述那么这道题的正确答案就是一个“看起来正常、实际上有毛病”的选项而另外三个正确选项反而更像正确答案。很多考生凭着直觉选了一个“正确”的选项最后发现题目问的是“错误的是”。应对方法有两种。第一种是在答题时把“正确的是”或“错误的是”这几个字圈起来给自己一个视觉提醒。第二种是在检查时把每个选项重新判定一次不要凭第一印象。我见过不少候选人第一遍选对了检查时又把“正确”选项改成“错误”选项最终丢分。所以检查阶段的策略是把你选出的选项代入题干连读一遍确认它是否真的满足题目要求。5.2 边界条件空集合、空指针、最小值为0第二类高频失分点在“边界条件”的描述上。客观题喜欢在选项里加入“一定”“必然”“任何情况下”这类绝对化表述而这些表述往往是错的。举一个例子关于Activity的onSaveInstanceState哪个选项是正确的A选项通常会说“onSaveInstanceState一定会被调用”这个说法就有问题。实际上如果用户主动按返回键退出Activity系统会认为这是用户有意关闭界面不会调用onSaveInstanceState。但如果是系统因为内存不足回收Activity或者屏幕旋转导致Activity重建则会保存状态。所以A错在“一定”两个字上。再比如关于Service的onStartCommand返回值START_STICKY、START_NOT_STICKY、START_REDELIVER_INTENT这三个值本身不难但出题人会在“系统杀死Service后是否会自动重启”上做文章。如果进程被彻底杀死Service是否重启取决于进程的adj优先级和系统内存状态而不是只看返回值。这种题就是典型的“结论正确但应用场景不严谨”。5.3 “安卓特有”与“Java通用”的混淆点安卓开发笔试还有一个常见干扰设计把Java通用概念说成Android特有或者反过来。比如“Handler机制是Android的消息处理机制Java中没有对应实现”这个说法需要仔细分辨。Java本身有BlockingQueue、Executor、Future等并发工具但Handler机制依赖Looper和MessageQueue这套基础设施在Java标准库中确实没有。但如果你说“Java中没有消息队列”那就错了因为java.util.concurrent包下大量使用队列。类似的混淆还有“ANR是Android崩溃的一种”其实ANR是“Application Not Responding”是应用在规定时间内没有响应输入或广播导致系统弹窗和崩溃机制完全不同。还有“内存泄漏只能发生在Activity中”这也大错特错任何对象只要生命周期没被正确管理都会泄漏。复习时要专门整理一个“安卓概念对照表”把Java、Android、JVM三个层面的概念分门别类能有效避免这类混淆。6. 复习节奏与实操方法把客观题从“背答案”变成“建体系”6.1 三轮复习法刷题、提炼、串讲笔试客观题覆盖面广靠考前一周突击背题效果很差。我自己的复习节奏是三轮第一轮是“地毯式扫盲”把Java基础、Android四大组件、Handler、View、进程通信、存储、网络这七块内容全部过一遍每块配30到50道客观题练习。这一轮的主要目标是找出知识盲区不用太在意正确率。我自己第一轮复习时View的MeasureSpec相关题目正确率不到一半但正是这些错题让我知道自己需要重点补课。第二轮是“错题提炼”。把第一轮的错题整理成错题本每道错题旁边写三行错误原因、正确思路、对应知识点。这一步很关键因为很多题你第一遍做错、看了解析后觉得自己懂了但一周之后再拿出来做还是错。这说明你并没有建立新的思考路径只是记住了答案。错题本上的“错误原因”必须是针对你自身解题过程的分析比如“没考虑父View是AT_MOST的情况”“把软引用和弱引用搞混了”“没有注意前提条件是子View consume DOWN”这样才有效果。第三轮是“体系串讲”。用A4纸把这七块知识以思维导图的方式画出来然后自己给自己讲一遍。讲的过程中你会发现很多知识点可以串联起来比如Binder的性能很好所以ContentProvider和Service的跨进程通信都基于Binder而Handler的底层是MessageQueueMessageQueue在系统服务层面又和Binder有交互。这些串联并不是为了考试而是为了应对技术终面时面试官的综合性提问。我给不少准备校招的朋友推荐过这套三轮法。他们普遍反馈第三轮看似浪费时间其实收获最大。因为客观题本身考察的是“零散知识点”但面试官最终考察的是“知识网络”。你只有把点连成网才能应对“如果一个Handler在子线程使用应该怎么处理Looper”这类开放性问题。6.2 用错题本建立“易错点-原理-答案”的对应关系错题本不是简单抄题也不是把正确答案写在旁边就结束。我建议每道错题建立三条对应关系易错点这句描述里最容易让人误解的词是什么比如“singleTop Activity位于栈顶”“Binder机制只拷贝一次”这些限定词才是出题人设置的关卡。原理为什么这个结论成立如果不能用两句话解释清楚说明你还没真正理解。比如“一次拷贝是因为mmap映射了内核缓冲区到用户空间”这就是一个合格的原理说明。答案最终选什么为什么其他选项错。当你把每道错题都按这个结构整理后你会发现很多题背后的“易错点”是重复的。比如“一定”“只”“必须”这类绝对化表述在十道题里出现了七次。这时候你就能提炼出自己的答题原则看到绝对化表述先怀疑再验证。这个原则不是靠背题得到的而是从错题本里归纳出来的。6.3 结合项目经验回答主观延伸客观题之外的隐性考察笔试只有客观题但面试不是。顺丰科技的面试官看完你的笔试成绩后通常会针对做错的题目追问“这道题你为什么选C你项目中遇到过类似场景吗”所以笔试并不是考完就结束它其实是面试的第一道题。建议你在复习时不只关注每个知识点怎么选还要准备一个“项目锚点”——从你的项目经历中找一个与这个知识点相关的案例。比如你做过一个物流扫码App里面有弱网重复提交的问题你最终用线程池加幂等键解决。那么当面试官问到Handler、线程池、网络请求关系时你就可以很自然地引出这个项目。当然这种能力不是笔试前临时抱佛脚能练出来的它需要你平时做项目时就有意识地记录“技术决策点”。如果你现在还在准备阶段可以专门写一份简单的技术复盘文档每完成一个功能记录下用了什么技术方案、为什么选它、遇到什么问题、怎么解决的。面试前拿着这份文档复习效果远好于背八股文。我个人在实际操作中的一个体会是纯粹为了笔试而复习效率很低以“能不能给别人讲明白”为标准复习效率最高。如果你在复习MeasureSpec时能合上资料把EXACTLY、AT_MOST、UNSPECIFIED三种模式在不同父View下的子View测量结果画成一张表那么笔试遇到任何变体题目都不慌。这套客观题合集的价值不在于让你记住某道题的正确答案而在于帮你发现自己的知识结构哪里还有缺口。用两三天时间把高频考点对应的题目做一遍再把错题对应的知识点补上比你闷头刷一百道新题有用得多。
返回列表