360春招笔试iOS客观题复盘:内存管理、Runtime与多线程核心考点解析
2026/8/31 2:15:23 网站建设 项目流程

先说一个基本判断: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语言特性的客观题,看起来考的是语法,实际上考的是原理。举一个高频例子:属性修饰符的区分。题目会让你判断,nonatomiccopyweakassignstrong这几个修饰符在不同场景下的行为。

这道题看起来简单,但坑极深。很多人只记得“copy是拷贝,weak是弱引用”,但题目可以这么出:一个@property (nonatomic, copy) NSMutableArray *arr;,外部传入一个NSMutableArray对象赋值给arr,会发生什么?答案是:因为用了copy,系统会执行copyWithZone:,生成一个不可变的NSArray。之后你对arr调用addObject:,会直接崩溃。这就是一个标准的“看着会,一用就废”的坑。

再看一个高频考法:__block__weak的使用。在Block内部修改变量,需要在变量前加__block修饰。但题目如果换个问法:在ARC环境下,Block中引用self,会不会造成循环引用?答案是:如果self持有Block,Block又直接引用了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根本不会被触发。正确的解法是在viewWillDisappearviewDidDisappearinvalidate,或者使用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种运行模式(defaultmodalconnectioncommoneventTracking)、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又被派发到主队列,需要等待主线程空闲才能执行。主线程在等block,block在等主线程,双双死锁。类似的变体还有dispatch_async到串行队列去dispatch_sync同一个串行队列,也会死锁。

另一个高频点是dispatch_group信号量。比如:如何用dispatch_group监听多个网络请求全部完成?如何控制并发最大数量?这些在实际开发中使用频率很高,笔试也爱考。dispatch_semaphore的信号量机制,尤其要理解dispatch_semaphore_waitdispatch_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,一个不可变数组。如果后续有人试图对newArraddObject:,就会直接崩。这种题目在笔试中出现频率极高。

另一道我印象很深的题:

int a = 1; void (^block)(void) = ^{ NSLog(@"%d", a); }; a = 2; block();

输出是1还是2?答案是1。因为在Block创建时,未使用__block修饰的局部变量会被值拷贝进Block内部。所以即使之后a变成了2,Block内部保存的仍然是创建时刻的1。如果变量用__block修饰,输出才会是2。这道题考察的是Block对局部变量的截获策略,属于最经典的基础考点。但要注意,如果是static变量或者全局变量,Block并不会截获值,因为两者的存储位置决定了外部可以直接访问。

3.2 内存与Runtime综合题的易错点建模

有一类题是综合了内存管理和Runtime的复合题,难度更高,也是区分度最大的。比如给你一个类的实现,让你判断weakSelfstrongSelf配合使用的原因:

__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只能保证settergetter方法本身的完整性(读写的原子性),不能保证整个业务逻辑的线程安全。举个例子:你在后台线程多次读取某属性,同时另一个线程修改它,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环境下,代码里隐藏的retainreleaseautorelease调用,肉眼看不出来,必须通过逻辑推导才能得出正确结果。

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赋值时,strongcopy有什么区别?当时我的思路是:strong是强引用,copy是拷贝,既然NSString本身是不可变的,两者赋值后效果应该一样。但正确答案是:如果外部赋值给name的是一个NSMutableStringstrong修饰下,name会和外部变量指向同一个可变字符串对象;之后如果外部修改了那个可变字符串,name也会变,这不符合NSString不可变的语义。而copy修饰下,赋值时会执行一次拷贝,name得到的是不可变的副本,外部修改不影响它。所以实际开发中,NSString属性推荐使用copy修饰。

这个教训我记进错题本后,又专门花了两个小时把strongcopyweakassignunsafe_unretained这几个修饰符在不同类型下的行为差异全部推导了一遍,包括对NSStringNSArrayNSMutableArrayBlockDelegate等类型下的应用。从那以后,无论笔试题目怎么出属性修饰符的组合逻辑,我都能快速判断对错。

错题本不要只是抄题和答案,一定要写“为什么错”。这个“为什么”才是真正能帮你避免同类问题的关键。

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 intint做运算时,j会被隐式转换为无符号整数,变成一个巨大的正数,所以i + j的结果也是无符号类型,结果大于0,result为真。如果你不看类型,按常规数学逻辑算,得出-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队列类型和死锁这几个高频考点吃透,你就能拿到基础分。

第二,做真题,不要做模拟题。模拟题和真题的出题思路差距很大,真题能让你把握真实难度和出题风格。牛客网上有大量真实考生回忆的笔试题,你可以拿来做训练。做的时候严格计时,模拟真实考试的节奏。

第三,坚持建错题本,并且每隔三天回看一次。人的遗忘速度比你想象得快,如果不反复回看,错题本建了等于没建。

最后,我不太喜欢说什么“祝顺利”之类的套话,我只想说:客观题笔试真的没那么可怕,它考的是基础知识,而基础是最公平的——因为它是所有人都能通过刻意练习来补强的部分。你把最硬核的地基打牢了,后面无论是面试还是实际开发,路都会好走很多。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询