已经收到 Offer ,是一家中型的承接金融业务开发的科技公司,下周去上班。找新工作前前后后一共花了大概 3 周左右的时间,期间面试过神州租车、中图云创、阳光保险、头条、中信银行和发 Offer 的这家公司,一共 6 家。前 3 家面试前没有任何准备,抽工作空闲时间过去直接面技术。心中认为凭借自己 6 个 App 的开发上架经验,问题都能 hold。实际技术面都会问非常基础的问题,比如关键字 assign 和 weak 的区别、KVO 的实现、static 和 const 的区别等。实际开发中大都集中在「用」上,突然让详细讲原理,还是需要私下准备的。后面 3 家面试前都有认真的准备,面试时大体上做到了游刃有余,下面对 iOS 的面试题目做一个梳理,希望准备面试的朋友心中能有大致的准备方向。
iOS 开发面试一般遵循由浅入深的顺序,这个流程可以分为 3 个层级:初级试题、中级试题和高级试题。初级试题关注业务界面的实现;中级试题关注页面的优化;高级试题关注线程安全和底层原理。与不同层级对应的题目如下:
初级题目
1 iOS 中事件分发流程:一个触摸事件如何找到响应者;
2 一个事件被响应后,如何沿着响应者链传递;
3 对一个 NSObject 子类实例/子类发送消息,消息处理的流程;
4 assign/weak 、 copy/strong、 const/static 关键字的区别和使用场景;
初级题目参考答案:
1 和 2 参考 https://www.jianshu.com/p/c294d1bd963d
3 参考 https://www.jianshu.com/p/8f98595b524e
中级题目
1 KVO 的实现原理;
2 NSMutableDictionary 中 setValue:ForKey: 和 setObject:ForKey: 的区别;
3 block 的分类;强引用的原因;
4 通知、代理、block 有什么区别;
5 NSURLSession 和 NSURLConnection 的区别;
初级题目参考答案:
1 KVO 的底层实现:原理是利用 NSObject 的非正式协议;
1 在运行时重写了 class ,命名为为 NSKVO+class 名;
2 在子类中重写 set 方法,在调用set方法复制属性时,会依次调用属性值将要改变、set 和已经改变 3 个方法;其中在 didChangeValueForKey 方法中,会调用 objectForKeyObserver 方法;
2 - (void)setValue:(nullable id)value forKey:(NSString *)key; 在字典赋值时中会自动调用,当 value 为 nil 时,自动调用 removeObjectForKey; - (void)setObject:(ObjectType)anObject forKey:(KeyType <NSCopying>)aKey; setObject: ForKey: 中 object 不能为nil,否则会崩溃;
3 block 3 种类型:
1 NSGlobalBlock 全局 block 放在数据区,不访问外部属性,定义在全局位置的都是这种类型;
2 NSStackBlock 栈 block 放在栈区, 访问 auto 属性时,NSGlobalBlock 变为 NSStackBlock;
3 NSMallocBlock 堆 block 放在堆区, 当对栈区的block 进行copy时;
block 修饰符 建议 copy 和 strong (ARC)
4 Block 和 Delegate 区别:
1 消耗 block 会将用到的变量由栈内存拷贝到堆内存,消耗大;delegate 仅仅是栈内存中开辟的指针空间转移,消耗少;
2 使用要点
2.1 block 易引起循环引用,且难以查找;
2.2 使用频率 block 用于调用次数少,传参数多的地方;delegate 用于多个方法,调用次数多的地方;
5 NSURLSession 比 NSURLConnection 优点:
1 区分请求:普通、上传、下载;
2 对不同请求进行优化,如普通中的 resume, cancle 和 suspend; 上传和下载的断点续传;
3 对请求配置进行了分类:带缓冲、不带缓存(无痕浏览)、后台请求;
高级题目
1 GCD 中栅栏函数 barrier、group、semphore、wait 的使用;
2 NSMutableDictionary 实现的原理;
3 HTTP 协议的理解,HTTPS 的实现原理 ;TCP/IP 三次握手和四次挥手;TCP 和 UDP 的区别;
4 图片的编解码;
5 多线程安全;NSSpinLock 、NSLock 、NSConditionLock 、pthread_mutex_lock 等各种锁的区别;
高级题目参考答案:
1 GCD 的相关函数,建议自己动手试一试;
2 NSMutableDictionary: 底层是一个 hash表,系统给出的查询时间复杂度接近 O(1), 推测采用的 hash 算法是拉链法(key和value 统一存储)和开放定址法;
3 HTTP 相关,参考阮一峰老师的 blog ,语言简洁,思路清晰;
4 自行查找;
5 参考 https://www.jianshu.com/p/cac79781965e
以上基本上涵盖了技术面由浅入深的全部内容,当然如果是应聘目标是 iOS 的高级开发,不可避免的还会有算法相关问题,比如链表成环判断、链表反转、字符串反转、快排算法等,这些都属于计算机专业数据结构的基本功,要求咱们开发者在闲余时间,看下《剑指 offer》、《LeetCode》等上面的题目。
面试过程是一个对 iOS 开发知识全面梳理的一个过程,经过这次面试,我觉得即便是自己没有跳槽的打算,间隔一段时期,也可以看一看面试相关的题目,自己尝试回答一下。因为面试的问题是随着移动端的发展,难度逐步提升的,比如现在面试时的算法知识和网络相关知识,在 3 年前都属于面试时不太关注的内容。通过对面试题的梳理,能够大概检测一下自己的 iOS 开发水平是进步了,还是原地踏步、落后于时代,从而提醒自己不断进步。
喜欢和关注都是对我的鼓励和支持~
参考:
1 简单易懂iOS面试篇