
先说一个基本判断360这种体量的公司春招笔试的iOS客观题本质上不是考“你会不会写代码”而是考“你这三年大学或者一年培训到底有没有把iOS的地基打扎实”。客观题不像编程题那样能靠临场手感蒙混过关错了就是错了而且很多题是单选题、多选题、判断题混合出错选、漏选、多选都不得分。我见过不少候选人简历上写着“精通iOS开发”结果在内存管理、Runloop、多线程这几个基础模块上栽跟头笔试直接挂掉连面试官的面都见不到。这篇内容我按“360 2018春招笔试 iOS开发工程师客观题”这种大厂校招笔试的常见考法来做一次系统复盘。不针对某一道具体题目给答案因为客观题是题库随机抽不同人拿到的题不完全一样而是把这类笔试背后真正想考察的知识点和能力模型拆开揉碎。你会发现只要把下面这几个模块吃透不管题库怎么抽你都能稳定输出。1. 春招笔试客观题的考核逻辑它到底在筛什么人1.1 客观题的高淘汰率从哪来先说一个很多人没意识到的事实大厂校招笔试的客观题部分淘汰率通常在60%到70%左右。也就是说十个人进笔试最后只有三四个能进面试。这个淘汰比例比很多人想象中残酷得多。原因也很直接——客观题是机器阅卷标准统一、成本低、效率高适合在简历筛选之后做第一轮大规模过滤。360的春招笔试iOS开发工程师岗位的客观题覆盖范围非常广。从C语言基础、Objective-C语法到内存管理、Runtime、Runloop、多线程、网络、UI布局甚至数据库、算法数据结构都会考。题目数量通常在40到60道之间考试时间90到120分钟。也就是说平均每道题只有一分半到两分钟的时间。这个时间压力本身就是筛选的一部分——你不仅要会还要够熟练。我当年笔试的时候犯过一个很蠢的错误在几道有争议的多选题上耗费了大量时间导致后面简单的判断题没时间做白白丢分。后来我想明白了客观题的节奏策略应该是简单题秒杀中等题快速判断难题果断标记跳过的策略。一道题卡住超过两分钟就跳过不要恋战。1.2 高分值学科分布特点从历年大厂iOS笔试的题目分布来看可以总结出比较稳定的分值权重。我把常见的考点整理成一张表方便你直接对照复习知识模块题目占比典型考察形式难度等级Objective-C语言特性20% - 25%代码阅读题、属性修饰符、Block中等内存管理15% - 20%ARC/MRC判断、循环引用场景较高Runtime与消息机制10% - 15%isa指针、方法交换、动态添加较高Runloop5% - 10%运行模式、事件循环、Timer中等多线程与GCD10% - 15%队列类型、死锁、线程安全较高网络与数据存储5% - 10%HTTPS握手、JSON解析、SQLite中等UI与Auto Layout5% - 10%frame/bounds、约束优先级中等算法与数据结构10% - 15%链表翻转、二叉树遍历、复杂度中高注意这个占比不是固定的每年都会有波动。但有一个规律是稳定的内存管理和Runtime这两块是区分度最高的考点。为什么因为这两块内容在大学的iOS课程里通常讲得不深很多人是自学的理解停留在表面一旦题目绕个弯就露馅。所以如果你时间有限优先把这两块啃透性价比最高。2. 核心考点模块拆解一道题背后是一整个知识网2.1 Objective-C语言特性区分“会用”和“懂原理”OC语言特性的客观题看起来考的是语法实际上考的是原理。举一个高频例子属性修饰符的区分。题目会让你判断nonatomic、copy、weak、assign、strong这几个修饰符在不同场景下的行为。这道题看起来简单但坑极深。很多人只记得“copy是拷贝weak是弱引用”但题目可以这么出一个property (nonatomic, copy) NSMutableArray *arr;外部传入一个NSMutableArray对象赋值给arr会发生什么答案是因为用了copy系统会执行copyWithZone:生成一个不可变的NSArray。之后你对arr调用addObject:会直接崩溃。这就是一个标准的“看着会一用就废”的坑。再看一个高频考法__block和__weak的使用。在Block内部修改变量需要在变量前加__block修饰。但题目如果换个问法在ARC环境下Block中引用self会不会造成循环引用答案是如果self持有BlockBlock又直接引用了self就会造成循环引用但如果Block只是间接引用了self的一个属性比如_name同样会强引用self一样会循环引用。这个点很多没深入研究过的人会判断错误。2.2 内存管理ARC不是万能保险内存管理这块我强烈建议你复习的时候不要只看ARC要把MRC时代的引用计数机制彻底搞懂。因为很多客观题默认你懂引用计数的底层逻辑。比如这样一道题NSString *str [[NSString alloc] initWithFormat:test];请问str的引用计数是多少很多人脱口而出是1。但如果题目换成NSString *str test;请问str的引用计数是多少答案是常量字符串的引用计数是一个很大的值或者说是“无意义”的因为字符串常量存储在常量区不参与引用计数管理。这类题就是故意考察你对底层存储区域的区分能力。同理__NSCFConstantString常量字符串、__NSCFString堆上的字符串、NSTaggedPointerString小字符串优化这三者的区别也是笔试常客。循环引用更是必考。常见场景包括Block循环引用、NSTimer循环引用、Delegate强引用、父子对象的强引用环。举个例子NSTimer的循环引用self.timer [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:selector(tick) userInfo:nil repeats:YES];这里self强持有timertimer又强持有target也就是self两者互相引用在dealloc里即使写了[_timer invalidate]也永远不会执行因为dealloc根本不会被触发。正确的解法是在viewWillDisappear或viewDidDisappear里invalidate或者使用iOS 10之后的block版本API。这类场景在笔试里几乎年年见。2.3 Runtime机制消息发送的完整链路Runtime是拉开差距最关键的知识模块没有之一。客观题里关于Runtime的考察通常会围绕这几个点展开。第一消息发送机制。在Objective-C中方法调用[obj doSomething]编译后实际上会被转换成objc_msgSend(obj, selector(doSomething))。消息发送的过程是先通过obj-isa找到所属类再在类的method_list中查找对应的方法实现如果没找到会沿着superclass指针逐级向上查找最终如果根类也没找到会进入消息转发流程。笔试题目可能会给你一个类继承关系图让你判断某个方法调用时查找顺序是什么样的。这种题不难但需要你把继承链画清楚千万别漏了根类NSObject这一层。第二isa指针和superclass指针的区别。isa指针是对象指向其所属类的“类对象”类对象的isa指向元类元类的isa指向根元类根元类的isa指向自身。这个“isa指向链”和“superclass继承链”是两条不同的线很多人混淆。笔试中常见的判断就是一个实例对象的isa指向什么指向类对象。类对象的isa指向什么指向元类。搞清楚这条链运行时那些高级操作你才有理解的基础。第三method swizzling方法交换。这是Runtime的高频考点也是实际开发中很常用的技术比如埋点统计、防止崩溃。题目通常会给你一段交换方法的代码让你判断执行结果或者找出潜在问题。这里的重点是要理解方法交换的本质是交换两个Method结构体中的method_imp指针。但要注意交换之后如果原方法所在类中还有其他方法调用了原方法也会走新的IMP这是容易忽略的坑。注意笔试里关于Runtime的题从来不会直接问你“什么是Runtime”而是通过具体的代码场景考察你是否理解运行时机制对代码行为的影响。所以复习时不要死记概念要对着代码逐行分析。2.4 Runloop与多线程高频但容易混淆Runloop的考点集中在NSRunLoop的5种运行模式default、modal、connection、common、eventTracking、Timer在滑动列表时不执行的问题、performSelector在当前线程不执行的问题。经典的客观题是这样的在列表滚动的过程中NSTimer不再触发原因是什么答案是NSTimer默认被添加到了kCFRunLoopDefaultMode模式下而滚动事件时Runloop会切换到UITrackingRunLoopMode模式当前模式下没有Timer事件源所以Timer不执行。解法是把Timer添加到NSRunLoopCommonModes下或者使用dispatch_source系列的Timer。多线程的考点则集中在GCD。队列的类型是首选考点串行队列、并发队列、主队列、全局队列这四者的组合关系。常见的坑题是dispatch_sync(dispatch_get_main_queue(), ^{ // do something });这道题的结果是什么答案死锁。因为主线程正在执行dispatch_sync而dispatch_sync是同步等待block执行完毕后再继续但block又被派发到主队列需要等待主线程空闲才能执行。主线程在等blockblock在等主线程双双死锁。类似的变体还有dispatch_async到串行队列去dispatch_sync同一个串行队列也会死锁。另一个高频点是dispatch_group和信号量。比如如何用dispatch_group监听多个网络请求全部完成如何控制并发最大数量这些在实际开发中使用频率很高笔试也爱考。dispatch_semaphore的信号量机制尤其要理解dispatch_semaphore_wait和dispatch_semaphore_signal的成对关系信号量初始值设为多少、在哪里等待、在哪里发送这些细节决定了并发控制的正确性。3. 实战视角360真实笔试中的题型分布与遇到的高频案例3.1 语言基础类题目的现场解析因为客观题是题库随机抽题同一个岗位不同人遇到的题目差别很大但题型分布基本一致。我在做这组题目的时候印象最深的是几道关于“代码执行结果”的题。这类题不给任何提示直接给一段Objective-C代码问你控制台输出是什么。这种题最考验对语言特性的掌握程度。一道典型的题目NSMutableArray *arr [NSMutableArray array]; NSArray *newArr [arr copy]; [arr addObject:1]; NSLog(%, newArr);输出结果是什么答案是空数组。因为[arr copy]得到的newArr是不可变的NSArray它是一个新的对象之后的[arr addObject:1]操作的是arr本身不会影响到newArr。但这里有个隐含考点[arr copy]之后newArr的类型是__NSArrayI一个不可变数组。如果后续有人试图对newArr做addObject:就会直接崩。这种题目在笔试中出现频率极高。另一道我印象很深的题int a 1; void (^block)(void) ^{ NSLog(%d, a); }; a 2; block();输出是1还是2答案是1。因为在Block创建时未使用__block修饰的局部变量会被值拷贝进Block内部。所以即使之后a变成了2Block内部保存的仍然是创建时刻的1。如果变量用__block修饰输出才会是2。这道题考察的是Block对局部变量的截获策略属于最经典的基础考点。但要注意如果是static变量或者全局变量Block并不会截获值因为两者的存储位置决定了外部可以直接访问。3.2 内存与Runtime综合题的易错点建模有一类题是综合了内存管理和Runtime的复合题难度更高也是区分度最大的。比如给你一个类的实现让你判断weakSelf和strongSelf配合使用的原因__weak __typeof(self) weakSelf self; dispatch_async(dispatch_get_global_queue(0, 0), ^{ __strong __typeof(weakSelf) strongSelf weakSelf; if (!strongSelf) return; // do something });题目可能问你在Block内部重新__strong修饰strongSelf会不会导致self无法释放答案是不会导致无法释放。因为strongSelf是Block内部的局部变量作用域仅限于当前Block的一次执行过程Block执行完毕strongSelf就释放了不会持续持有self。这个模式的目的是避免在执行期间self被提前释放导致的野指针问题。笔试出这种题考察的是对“延迟释放”这个核心思想的理解。再比如关于objc_msgSend的一道判断[person performSelector:selector(eat)];请问这是否等价于objc_msgSend(person, selector(eat))严格来说不完全等价。performSelector:走的是消息发送流程但它有额外的respondsToSelector:检查和警告处理而且编译器对performSelector:的处理在不同场景下也可能有差异。笔试如果出判断题你就要把这个区别说清楚——两者最终都会走到objc_msgSend但performSelector:多了一层封装并且会有“可能会导致泄漏”的已知问题。3.3 多线程与UI更新题一网打尽高频组合多线程与UI更新的组合题也是360这类一线大厂爱出的方向因为实际开发中UI更新必须在主线程这条规则是iOS开发的铁律违反它的后果极其严重。典型题目dispatch_async(dispatch_get_global_queue(0, 0), ^{ // 耗时操作 dispatch_async(dispatch_get_main_queue(), ^{ // 更新UI }); });这道题本身不难问的是“更新UI应该放在哪个队列”答案当然是主队列。但笔试里这道题的变体很恶心把内层的dispatch_async换成dispatch_sync让你判断是否会造成死锁。分析一下内层dispatch_sync往主队列提交Block当前线程是全局并发队列的某个子线程子线程在等待Block执行主线程如果此时空闲则可以执行Block所以不会死锁。但如果当前线程本身就是主线程dispatch_sync到主队列就会死锁。另外一个高频点是atomic与线程安全的关系。很多初学者以为atomic修饰的属性就是线程安全的这是大错特错。atomic只能保证setter和getter方法本身的完整性读写的原子性不能保证整个业务逻辑的线程安全。举个例子你在后台线程多次读取某属性同时另一个线程修改它atomic只能保证你每次读到的值不是一个半初始化状态但无法保证读到的值是最新的、或者是某个业务处理之后的一致状态。笔试里只要出现“atomic保证线程安全”这个判断直接打错就对了。4. 笔试现场的时间分配策略与做题节奏4.1 三分法做题时间轴90分钟做50道客观题平均每题只有1.8分钟。但我的建议是不要匀速分配时间而是把时间分成三段来使用效率会更高。第一段0到15分钟快速扫描全部题目把明显会做的题直接做掉。这个阶段目标是抢分先把确定能拿到的分数牢牢锁死。注意不要在一道简单的题上反复犹豫如果一道题你一看就知道答案果断确认不要回头。第二段15到60分钟集中攻克中等难度的题。这一部分是主战场题目涉及代码阅读、原理判断、场景分析等。每道题控制在1.5分钟以内如果到时间还拿不准标记一个“最可能的选项”继续往下走不要死磕。第三段60到90分钟回头处理跳过的难题和检查。到了这个阶段你只剩30分钟最多只能再深入研究10道题。优先检查那些你标记了“模糊”选项的题因为它们可能因为笔误或者审题不清导致丢分比完全不会的题更可惜。4.2 多选题的排除法与“最保守原则”360笔试的客观题里多选题是丢分重灾区。因为多选题的给分规则通常是“全部选对得满分少选得部分分多选、错选不得分”。换句话说多选一个错误选项整道题直接零分少选一个正确选项可能还能得一半分。基于这个规则我总结出了一套“最保守原则”拿不准的选项宁可少选不要多选。比如一道题问你“以下哪些操作会造成循环引用”你确定Block循环引用和NSTimer循环引用是对的但对ViewController之间的强引用环拿不准那就只选前两个。虽然在“少选得部分分”的规则下你只能拿一半分但至少不会全丢。这里需要注意的是不同笔试系统对“少选是否给分”的规则并不统一360的规则是“多选、错选、漏选均不得分”所以你在做题前一定先看清楚说明如果系统说明明确说“漏选不得分”那保守策略就要换一换变成“尽力选全”。提示绝大多数互联网公司校招笔试多选题都是“错选、漏选、多选均不得分”。这种情况下如果你对某道题的把握不是100%保命策略就是选你有绝对把握的选项放弃模糊选项。必须明确这种题型设计就是为了防止蒙题拉开差距。4.3 判断题与代码阅读题的快准狠技巧判断题是客观题里最简单的题型但也是最容易因为轻敌而丢分的。通常判断题为1分或0.5分一道分值不高但胜在数量多能抢就抢。判断题有一个常见套路题目中只要出现“一定”“必定”“绝对”“任何”“所有”这类绝对化词汇大概率是错的。因为iOS开发中几乎没有“绝对”的场景。比如“所有Block都会造成循环引用”这就是错的因为Block只有在被对象持有时才可能造成循环引用临时创建的Block不会。反过来如果题目出现“通常”“一般”“大多数情况下”这类相对化表述正确的可能性就更大。代码阅读题则讲究“逐行拆解”。我在做这类题的时候习惯拿着下标逐行推演这行代码执行后的内存状态是什么引用计数是多少变量指向的对象变化了吗确保逻辑推导链条完整。千万别凭直觉去猜输出结果。尤其是在ARC环境下代码里隐藏的retain、release、autorelease调用肉眼看不出来必须通过逻辑推导才能得出正确结果。4.4 心态管理与考场应急方案笔试过程中心态崩是最常见也最可惜的情况。遇到连续几道不会做的题很多人会开始慌然后做后面的题时浮躁、审题不清原本会做的也做错了。我个人的经验是允许自己“不会”。一场笔试50道题你允许自己有10道题不会或者拿不准这很正常没人能全对。你只需要把剩下40道会做的题全部做对就已经能超过绝大多数人了。如果真的遇到时间不够的极端情况比如还剩5分钟却有10道题没做我的建议是全部蒙一个选项。比如所有不确定的题都选C判断题全选对/错中的某一项。这样做的好处是至少能保证10%到20%的正确率比随机乱选强。而且如果你平时统计过自己“遇到不确定时的第一直觉”的正确率通常比随机蒙高得多。实际上我在做笔试时有个小习惯第一轮快速扫题时遇到不确定的题会先在草稿纸上记下“第一直觉的答案”然后继续。到了第二轮回头看如果没有新的判断依据就按第一直觉走。因为第一直觉往往源于长期练习形成的隐性记忆改来改去反而容易改错。5. 从客观题反推准备笔试的正确复习路径5.1 按真题反推知识点的“倒推复习法”我这里想分享一个非常实用的复习方法倒推复习法。很多人准备笔试是“从前往后学”把Objective-C、Foundation、UIKit、网络、数据库从头到尾过一遍。这个方法的效率其实很低因为你看完一遍下来前面的早忘了而且你不知道重点在哪。倒推复习法正好相反你先找近两年的笔试真题牛客网、力扣社区、各种求职论坛上都有大量真实回忆帖把真题里的每一个考点整理成一个知识点清单然后针对清单逐个复习。比如真题里出现了10道内存管理的题其中有6道和循环引用有关那你复习内存管理这个模块时就要重点练循环引用而不是平均用力。这个方法的核心逻辑是大厂笔试的考点是高度重复的去年考的循环引用今年大概率还会考只是换了马甲。与其全量学习不如精准打击高频考点。我复习的时候把历年真题的考点做了一张统计表发现多个知识点的出现频率远超其他内容。这类知识点无论你时间多紧张都必须掌握。5.2 好记性不如烂笔头建立自己的错题本准备笔试的过程中建错题本看起来是老生常谈但真正坚持下来的人少之又少。我在准备这组360笔试的时候把做错的、蒙对的、拿不准的题目全部摘录进一个Markdown文档每题记录三个字段错误原因、正确思路、涉及知识点。举个例子我错过一道这样的题property (nonatomic, strong) NSString *name;问题是给name赋值时strong和copy有什么区别当时我的思路是strong是强引用copy是拷贝既然NSString本身是不可变的两者赋值后效果应该一样。但正确答案是如果外部赋值给name的是一个NSMutableStringstrong修饰下name会和外部变量指向同一个可变字符串对象之后如果外部修改了那个可变字符串name也会变这不符合NSString不可变的语义。而copy修饰下赋值时会执行一次拷贝name得到的是不可变的副本外部修改不影响它。所以实际开发中NSString属性推荐使用copy修饰。这个教训我记进错题本后又专门花了两个小时把strong、copy、weak、assign、unsafe_unretained这几个修饰符在不同类型下的行为差异全部推导了一遍包括对NSString、NSArray、NSMutableArray、Block、Delegate等类型下的应用。从那以后无论笔试题目怎么出属性修饰符的组合逻辑我都能快速判断对错。错题本不要只是抄题和答案一定要写“为什么错”。这个“为什么”才是真正能帮你避免同类问题的关键。5.3 面试中的延伸提问准备最后提醒一件事客观题笔试只是第一关笔试中暴露出来的知识薄弱点面试时大概率还会被追问。面试官手里通常有你的笔试答卷他们会围绕你做错的题目往深处问。所以笔试结束之后千万别对完答案就把题目扔到一边应该马上复盘做错的题把每个错题相关的所有知识点都查漏补缺一遍。比如笔试里有一道关于Runloop模式下Timer失效的题目你答错了面试时面试官可能会接着问除了把Timer添加到NSRunLoopCommonModes还有什么方式能保证滑动过程中Timer不失效如果你只记住了“添加NSRunLoopCommonModes”这一个答案就容易被问住。实际上还有两种方案一种是使用dispatch_source_t创建Timer它不依赖于Runloop不会受影响另一种是把Timer放到子线程的Runloop中但这样需要自己管理子线程的Runloop运行复杂度更高。如果你能把这个问题的三种解法都答出来面试官会明显觉得你“知其然更知其所以然”。6. 做题过程中的坑与经验汇总6.1 那些年我们一起踩过的审题坑我在做这组笔试时发现很多丢分不是“不会”而是“看错题”。客观题的文字表述往往非常严谨一个词的不同就能改变整个题目的答案。我在前面已经提到的审题要点这里再展开说说。第一注意“正确”还是“不正确”。这是最频繁出现的坑。题目问“以下说法正确的是”选项A是错的你选了题目问“以下说法不正确的是”你还在按“找正确选项”的思路去做必错。我的习惯是把题目中的“不正确”“错误的是”“除了”这类否定词圈出来或者直接写个大大的“不”字在草稿纸上提醒自己。第二注意“有符号”“无符号”和“溢出”问题。C语言基础题常考这类。比如unsigned int i 1; int j -2; BOOL result i j 0;问result的值。这道题的坑在于unsigned int和int做运算时j会被隐式转换为无符号整数变成一个巨大的正数所以i j的结果也是无符号类型结果大于0result为真。如果你不看类型按常规数学逻辑算得出-1 0为假就掉坑了。第三注意“赋值”与“比较”的区分。if (a 1)和if (a 1)是完全不同的前者是给a赋值1判断条件永远为真后者才是比较。笔试中这类题属于送分题但每年都有人因为粗心丢分真的不应该。6.2 ARC与MRC混编的判断题陷阱有一类题专门考察ARC与MRC混编场景下的行为判断。这类题在实际开发中不常见但在笔试中很爱出因为能有效筛选出对引用计数机制理解不深的人。典型场景- (void)test { __weak NSString *weakStr; autoreleasepool { NSString *str [[NSString alloc] initWithFormat:123]; weakStr str; } NSLog(%, weakStr); }请问输出是什么答案是(null)。因为autoreleasepool结束后局部变量str的强引用被释放weakStr弱引用指向的对象引用计数归零被释放weakStr自动被置为nil所以打印输出为(null)。但如果把str的初始化方式改成NSString *str [NSString stringWithFormat:123];输出就不同了因为stringWithFormat:返回的对象是自动释放的autoreleasepool结束时自动释放一次但不会立即释放要看是否有其他autorelease嵌套。所以按照常规理解在autoreleasepool结束后的NSLog访问weakStr指向的对象已经被自动释放池释放了weakStr也会是nil。但如果字符串内容比较短可能走的是NSTaggedPointerString的优化路径这个细节在ARC下表现就很悬。这类题目的价值在于它逼你去思考ARC背后的自动释放池、弱引用置nil机制、字符串存储优化这些底层细节。你把这些细节都吃透了笔试遇到任何内存管理的变体题都不会再犯错。6.3 Runloop模式和时间敏感题的速记口诀Runloop这部分特别容易记混因为模式的名字有些长而且中英文的对应关系容易搞错。我自己编了一个速记口诀分享给你。default模式下Timer正常工作tracking模式下Timer暂停工作common不是一个真正的模式而是一个“标记”把Timer加入commonModes标记就能让Timer在default和tracking两种模式下都工作。用口诀记就是“追剧不刷新刷剧不追剧点个common都行”。default模式是追剧模式timer正常走tracking模式是刷列表模式timer暂停加common标记两个模式都能跑。时间敏感题还有一个经典考法NSTimer的真实触发时间。题目可能会问“在不精确时间下NSTimer会怎样”答案是NSTimer不是实时机制它依赖于Runloop的循环如果当前Runloop在处理一个长时间任务Timer触发时间会延后。这种“不精确”特性就是为什么在追求精确定时的场景如动画帧率控制、高频采集中开发者会使用dispatch_source_t的原因。7. 重新审视这套笔试一些个人体会整套“360公司-2018春招笔试-iOS开发工程师客观题”做下来我的最大感受是这套题目出得很有水平它不像很多公司的笔试题那样拼堆砌冷门语法而是紧扣iOS开发日常中真正用得上的核心原理。每道题都有实用场景作支撑做错一道题你能明确知道自己哪块知识有漏洞——这是很宝贵的反馈。如果你现在正在准备iOS岗位的校招笔试我给几个最重要的实操建议第一优先复习内存管理、Runtime、多线程。这三块投入产出比最高覆盖了你笔试中近一半的分数。把循环引用场景、消息发送链路、GCD队列类型和死锁这几个高频考点吃透你就能拿到基础分。第二做真题不要做模拟题。模拟题和真题的出题思路差距很大真题能让你把握真实难度和出题风格。牛客网上有大量真实考生回忆的笔试题你可以拿来做训练。做的时候严格计时模拟真实考试的节奏。第三坚持建错题本并且每隔三天回看一次。人的遗忘速度比你想象得快如果不反复回看错题本建了等于没建。最后我不太喜欢说什么“祝顺利”之类的套话我只想说客观题笔试真的没那么可怕它考的是基础知识而基础是最公平的——因为它是所有人都能通过刻意练习来补强的部分。你把最硬核的地基打牢了后面无论是面试还是实际开发路都会好走很多。