iOS面试题之一
from 逻辑教育
第一部分:iOS面试题(上)
1: 谈谈你对KVC的理解
2: iOS项目中引用多个第三方库引发冲突的解决方法
3: GCD实现多读单写
4: 讲一下atomic的实现机制;为什么不能保证绝对的线程安全?
5: Autoreleasepool所使用的数据结构是什么?
6: AutoreleasePoolPage结构体了解么?
7: iOS中内省的几个方法?
8: class方法和objc_getClass方法有什么区别?
9: 分类和扩展有什么区别?可以分别用来做什么?
10: 分类有哪些局限性?分类的结构体里面有哪些成员?
11: 能不能简述一下Dealloc的实现机制第二部分:iOS面试题(中)
12: HTTPS和HTTP的区别
13: TCP为什么要三次握手,四次挥手?
14: 对称加密和非对称加密的区别?分别有哪些算法的实现?
15: HTTPS的握手流程?为什么密钥的传递需要使用非对称加密?双向认证了解么?
16: 如何用Charles抓HTTPS的包?其中原理和流程是什么?
17: 什么是中间人攻击?如何避免?
18: 了解编译的过程么?分为哪几个步骤?
19: 静态链接了解么?静态库和动态库的区别?
20: App网络层有哪些优化策略?
21: 排序题︰冒泡排序,选择排序,插入排序,快速排序(二路,三路)能写出那些?
22: iOS开发中的加密方式
23: App安全,数字签名,App签名,重签名第三部分:iOS面试题(下)
24: OC数据类型
25: property和属性修饰符
26: 成员变量ivar和属性property的区别,以及不同关键字的作用
27: 类簇的优缺点
28: 谈谈设计模式
29: 谈谈架构设计
30: ReactiveCocoa的使用及优缺点
31: 类的继承,类能否多继承,协议能不能做继承?
32: 分类(category)和类扩展(extension)的区别
33: 如何实现week
34: 字典注意事项:setvalue和setobject的区别
35: 多线程和锁
36: WebSocket与TCP Socket的区别
37: 事件传递和响应机制
以下答案为本人自己查找资料整理回答
答案:
第一部分:
1: 谈谈你对KVC的理解
答:key-value- coding 键值编码,通过属性字符串名称访问或修改属性机制,api为:valueForKey: 、 setValue:、 valueForKeyPath: 、setValue:
setValue原理为:
image.pngvalueForKey原理为:
image.png2: iOS项目中引用多个第三方库引发冲突的解决方法
答:表现为编译报dumplicate symbols错误。
解决方式
一、使用命令将 .a 库中相同的包
二、在编译链接项中添加-dead_strip项
一、使用命令将 .a 库中相同的包
1、创建临时文件夹,用于存放armv7平台解压后的.o文件:mkdir armv7
2、取出armv7平台的包:lipo libx.a -thin armv7 -output armv7/libx-armv7.a
3、查看库中所包含的文件列表:ar -t armv7/libx-armv7.a
4、解压出object file(即.o后缀文件):cd armv7 && ar xv libx-armv7.a
5、找到冲突的包(AFHTTPSessionManager),删除掉rm AFHTTPSessionManager.o
6、重新打包object file:cd .. && ar rcs libx-armv7.a armv7/*.o,可以再次使用[2]中命令确认是否已成功将文件去除
7、将其他几个平台(armv7s, i386, arm64, x86_64)包逐一做上述[1-6]操作
8、重新合并为fat file的.a文件:
lipo -create libx-armv7.a libx-armv7s.a libx-i386.a -output libSDK-new.a
9、拷贝到项目中覆盖源文件:
cp libSDK-new.a /Users/tony/Desktop/XXXProject/Lib/libSDK.a
解决二
二、在编译链接项中添加-dead_strip项
在Build Settings->Other link flags中添加-dead_strip,如果Other link flags中有-all_load与-force_load则删掉,只填-dead_strip
3: GCD实现多读单写
- (void)viewDidLoad {
[super viewDidLoad];
_syncQueue = dispatch_queue_create("ioQueue", DISPATCH_QUEUE_CONCURRENT);
for (int i = 0; i < 100; i ++) {
[self setSomeString:[NSString stringWithFormat:@"%d",i]];
NSLog(@"someString:%@",[self someString]);
}
}
-(NSString *)someString {
__block NSString *localSomeString;
dispatch_sync(_syncQueue, ^{
sleep(1);
localSomeString = self.string;
});
return localSomeString;
}
- (void)setSomeString:(NSString *)someString {
dispatch_barrier_async(_syncQueue, ^{
sleep(1);
self.string = someString;
});
}
4: 讲一下atomic的实现机制;为什么不能保证绝对的线程安
全?
答:
- atomic用于保证属性setter、getter的原子性操作,相当于在getter和setter内部加了线程同步的锁
- 这个锁只能保证单独的读或者单独的写诗线程安全,如果同时读和写,就不是线程安全。
- 解决的方法就是读和写用同一把锁。
5: Autoreleasepool所使用的数据结构是什么?
答:双向链表
6: AutoreleasePoolPage结构体了解么?
image.png7: iOS中内省的几个方法?
答:四个方法,判断类,判断方法
-(BOOL) isKindOfClass: 判断是否是这个类或者这个类的子类的实例
-(BOOL) isMemberOfClass: 判断是否是这个类的实例
-(BOOL) respondsToSelector: 判读实例是否有这样方法
+(BOOL) instancesRespondToSelector: 判断类是否有这个方法
8: class方法和objc_getClass方法有什么区别?
答:
1.object_getClass(obj)
返回的是obj的isa指针;
-
[obj class]
obj为实例对象
调用的是实例方法:- (Class)class,返回的obj对象中的isa指针;
obj为类对象(包括元类和根类以及根元类)
调用的是类方法:+ (Class)class,返回的结果为调用者本身。
再回顾一下经典图:
image.png
9: 分类和扩展有什么区别?可以分别用来做什么?
- Class Extension在编译的时候,它的数据就已经包含在类信息中
- Category是在运行时,才会将数据合并到类信息中
- 扩展作用:为一个类添加额外的原来没有变量,方法和属性
一般的类扩展写到.m文件中
一般的私有属性写到.m文件中的类扩展中
10: 分类有哪些局限性?分类的结构体里面有哪些成员?
答:不能直接添加属性,需要通过Runtime动态添加get、set方法达到添加属性目的,注意,只能通过get、set方法获取,不能通过成员变量获取,除非用runtime添加成员变量。
struct category_t {
const char *name;
classref_t cls;
WrappedPtr<method_list_t, PtrauthStrip> instanceMethods;
WrappedPtr<method_list_t, PtrauthStrip> classMethods;
struct protocol_list_t *protocols;
struct property_list_t *instanceProperties;
// Fields below this point are not always present on disk.
struct property_list_t *_classProperties;
method_list_t *methodsForMeta(bool isMeta) {
if (isMeta) return classMethods;
else return instanceMethods;
}
property_list_t *propertiesForMeta(bool isMeta, struct header_info *hi);
protocol_list_t *protocolsForMeta(bool isMeta) {
if (isMeta) return nullptr;
else return protocols;
}
};
11: 能不能简述一下Dealloc的实现机制
答:
- 当一个对象要释放时,会自动调用dealloc,接下的调用轨迹是
- dealloc
- _objc_rootDealloc
- rootDealloc
- object_dispose
- objc_destructInstance、free
第二部分:
12: HTTPS和HTTP的区别
答:
- HTTP:超文本传输协议,明文传输
- HTTPS:在HTTP基础上增加SSL/TLS加密层,密文传输
- HTTP端口号为8080,HTTPS端口号为443
- HTTPS需要证书认证,一般需要申请证书的费用
- HTTP 页面响应速度比 HTTPS 快,主要是因为 HTTP 使用 TCP 三次握手建立连接,客户端和服务器需要交换 3 个包,而 HTTPS除了 TCP 的三个包,还要加上 ssl 握手需要的 9 个包,所以一共是 12 个包。
13: TCP为什么要三次握手,四次挥手?
答:为了确保TCP正确地建立连接和断开连接
详情请看: 这一次,彻底搞懂TCP3次握手、4次挥手好吗?
14: 对称加密和非对称加密的区别?分别有哪些算法的实现?
答:
- 对称加密:使用同一个秘钥,非对称加密使用2把密钥加密和解密,即公钥、私钥
- 常见的加密方式:
- 不可逆
- 单向散列函数:MD5、SHA
- 可逆
- 对称加密:DES、3DES、AES
- 非对称加密:RSA
- 其他
- 混合密码系统
- 数字签名
- 证书
- 不可逆
15: HTTPS的握手流程?为什么密钥的传递需要使用非对称加密?双向认证了解么?
答:
- 为什么密钥的传递需要使用非对称加密?因为防止密钥被窃取、篡改。
16: 如何用Charles抓HTTPS的包?其中原理和流程是什么?
答:客户端安装证书。原理就是利用代理网络对客户端的网络请求进行代理转发。
17: 什么是中间人攻击?如何避免?
答:
- 指攻击者与通讯的两端分别创建独立的联系,并交换其所收到的数据,使通讯的两端认为他们正在通过一个私密的连接与对方直接对话,但事实上整个会话都被攻击者完全控制。
- 使用HTTPS
18: 了解编译的过程么?分为哪几个步骤?
- 预处理:处理以#开头的命令,删除注释,解开宏定义等
- 编译:词法分析、语法分析、语义分析、中间代码生成与优化,最终生成汇编代码
- 汇编:将汇编代码翻译成机器码,生成.o目标文件
- 链接:将多个.o目标文件和其他函数库链接成可执行文件
19: 静态链接了解么?静态库和动态库的区别?
答:
- 静态链接:将各个模块之间互相引用的部分都处理好,使得各个模块之间能够正确的衔接
- 区别:静态库在程序链接成可执行文件时就已经链接完成,动态库是在程序启动、运行时才进行链接
20: App网络层有哪些优化策略?
1、优化DNS解析和缓存
2、网络质量检测(根据网络质量来改变策略)
3、提供网络服务优先级和依赖机制
4、提供网络服务重发机制
5、减少数据传输量
6、优化海外网络性能
7、购买配置CDN网络加速服务
21: 排序题︰冒泡排序,选择排序,插入排序,快速排序(二路,三路)能写出那些?
22: iOS开发中的加密方式
- base64加密
- Token值加密:服务端生成token,客户端保存后每次请求发送token到服务端,用来判断登陆状态。
- MD5加密--(信息-摘要算法) 哈希算法之一、
- 时间戳密码以及指纹识、人脸识别
- keychain保存
23: App安全,数字签名,App签名,重签名
- iOS应用程序在上传App Store后,苹果会对ipa包进行数字签名,用来保证app包的安全性
第三部分
24: OC数据类型
略
25: property和属性修饰符
略
26: 成员变量ivar和属性property的区别,以及不同关键字的作用
- ivar是ARC之前的产物,对象内存需要自己管理
- ARC之后新增property特性,编译器自动生成ivar成员变量、get方法、set方法。
- 分类中的property不会生成ivar成员变量、get方法、set方法,需要自己通过runtime生成。
27: 类簇的优缺点
优点:
- 可以将抽象基类背后的复杂细节隐藏起来。
- 程序员不会需要记住各种创建对象的具体类实现,简 化了开发成本,提高了开发效率。
- 便于进行封装和组件化。
- 减少了 if-else 这样缺乏扩展性的代码。
- 增加新功能支持不影响其他代码。
缺点=
- 已有的类簇非常不好扩展。
28: 谈谈设计模式
29: 谈谈架构设计
- 组件化
- MVVM
30: ReactiveCocoa的使用及优缺点
31: 类的继承,类能否多继承,协议能不能做继承?
不能
32: 分类(category)和类扩展(extension)的区别
略
33: weak实现原理
- weak的原理在于底层维护了一张weak_table_t结构的hash表,key是所指对象的地址,value是weak指针的地址数组。
- weak 关键字的作用是弱引用,所引用对象的计数器不会加1,并在引用对象被释放的时候自动被设置为 nil。
- 对象释放时,调用clearDeallocating函数根据对象地址获取所有weak指针地址的数组,然后遍历这个数组把其中的数据设为nil,最后把这个entry从weak表中删除,最后清理对象的记录。
-
SideTable、weak_table_t、weak_entry_t这样三个结构,它们之间的关系如下图所示。
image.png
34: 字典注意事项:setvalue和setobject的区别
setvalue需要注意对象为nil情况,为nil会导致崩溃,setobject不会
35: 多线程和锁
- 多线程:利用cpu多核特性,同时执行多个任务,单核cpu通过任务调度模拟多线程。
- 锁,为了防止多线程对读和写操作数据不一致问题,和多线程安全问题,有必要进行加锁操作
36: WebSocket与TCP Socket的区别
- WebSocket protocol 是HTML5一种新的协议。它实现了浏览器与服务器全双工通信(full-duplex)。一开始的握手需要借助HTTP请求完成。
- TCP Socket不是协议,是一套API,是对TCP、UDP复杂传输方法的一套封装。位于应用层和传输层之间。
37: 事件传递和响应机制
- 事件的产生
- 发生触摸事件后,系统会将该事件加入到一个由UIApplication管理的事件队列中,为什么是队列而不是栈?因为队列的特点是FIFO,即先进先出,先产生的事件先处理才符合常理,所以把事件添加到队列。
- UIApplication会从事件队列中取出最前面的事件,并将事件分发下去以便处理,通常,先发送事件给应用程序的主窗口(keyWindow)。
- 主窗口会在视图层次结构中找到一个最合适的视图来处理触摸事件,这也是整个事件处理过程的第一步。
- 找到合适的视图控件后,就会调用视图控件的touches方法来作具体的事件处理。
- 事件的传递
- 触摸事件的传递是从父控件传递到子控件
- 也就是UIApplication->window->寻找处理事件最合适的view
- 注 意: 如果父控件不能接受触摸事件,那么子控件就不可能接收到触摸事件