22
33> 题目作者:Monkery&&juejin.im/post/5e397ccaf265da570b3f1b02
44
5- > [ 😁目前为东半球解答最完整的一份参考答案 ] ( https://github.com/DevDragonLi/iOSInterviewsAndDevNotes/tree/master/interview-iOS )
5+ > [ 😁东半球解答最完整的一份参考答案:90% cover ] ( https://github.com/DevDragonLi/iOSInterviewsAndDevNotes/tree/master/interview-iOS )
66
77> 笔者最近收集梳理了一些iOS相关的问题,其中大部分都是大厂面试或者面试其他人用到的,能命中大部分的面试和日常工作,更希望你可以用它来检验自己
88
@@ -1628,13 +1628,37 @@ dispatch_source_cancel(self.disTimer);
16281628<details>
16291629<summary> 参考内容 </summary>
16301630
1631+ - 由苹果生成一对公私钥,公钥内置与iOS设备中,私钥由苹果保管。
1632+ - 开发者上传App给苹果审核后,苹果用私钥对App数据进行签名,发布至App Store。
1633+ - iOS设备下载App后,用公钥进行验证,若正确,则证明App是由苹果认证过的。
1634+
16311635</details>
16321636
16331637### 开发者怎么在debug模式下把app安装到设备呢
16341638
16351639<details>
16361640<summary> 参考内容 </summary>
16371641
1642+ > 由于不需要提交苹果审核,所以苹果没办法对App进行签名,因此苹果采用了双重签名的机制。Mac电脑有一对公私钥,苹果还是原来的一对公私钥。
1643+
1644+ * 开发时需要真机测试时,需要从钥匙串中的证书中心创建证书请求文件(CSR),并传至苹果服务器。
1645+ * Apple使用私钥对 CSR 签名,生成一份包含Mac公钥信息及Apple对它的签名,被称为证书(CER:即开发证书,发布证书)。
1646+ * 编译完一个App后,Mac电脑使用私钥对App进行签名。
1647+ * 在安装App时,根据当前配置把CER证书一起打包进App。
1648+ * iOS设备通过内置的Apple的公钥验证CER是否正确,证书验证确保Mac公钥时经过苹果认证的。
1649+ * 再使用CER文件中Mac的公钥去验证App的签名是否正确,确保安装行为是经过苹果允许的。
1650+
1651+ #### 补充:Ad-Hoc正式打包安装
1652+
1653+ > Xcode打包App生成ipa文件,通过iTunes或者蒲公英等第三方发布平台,安装到手机上。流程步骤基本和真机调试相同,差别在于第4步:
1654+
1655+ * 开发时需要打包测试或发布时,需要从钥匙串中的证书中心创建证书请求文件(CSR),并传至苹果服务器。
1656+ * Apple使用私钥对 CSR 签名,生成一份包含Mac公钥信息及Apple对它的签名,被称为证书(CER:即开发证书,发布证书)。
1657+ * 编译完一个App后,Mac电脑使用私钥对App进行签名。
1658+ * 编译签名完之后,要导出ipa文件,导出时,需要选择一个保存的方法(App Store/Ad Hoc/Enterprise/Development),就是选择将上一步生成的CER一起打包进App。
1659+ * iOS设备通过内置的Apple的公钥验证CER是否正确,证书验证确保Mac公钥是经过苹果认证的。
1660+ * 再使用CER文件中Mac的公钥去验证App的签名是否正确,确保安装行为是经过苹果允许的。
1661+
16381662</details>
16391663
16401664## 架构设计
@@ -1666,6 +1690,11 @@ dispatch_source_cancel(self.disTimer);
16661690
16671691- [MVVM和MVC的区别](19新浪公司iOS面试题2019年6月.md)
16681692
1693+ - MVP模式是MVC模式的一个演化版本(好像所有的模式都是出自于MVC~~),MVP全称Model-View-Presenter。
1694+ - Presenter:作为model和view的中间人,从model层获取数据之后传给view,使得View和model没有耦合。
1695+ - 说了那么多,总得来说MVP的好处就是解除view与model的耦合,使得view或model有更强的复用性。
1696+
1697+
16691698</details>
16701699
16711700### 常见的设计模式
@@ -1703,7 +1732,9 @@ dispatch_source_cancel(self.disTimer);
17031732<details>
17041733<summary> 参考内容 </summary>
17051734
1706- - TODO
1735+ - Code Review
1736+
1737+ - 工作流程
17071738
17081739</details>
17091740
@@ -1712,25 +1743,48 @@ dispatch_source_cancel(self.disTimer);
17121743<details>
17131744<summary> 参考内容 </summary>
17141745
1746+ - LRU
1747+ - 双向链表(Doubly Linked List)
1748+ - 哈希表(Dictionary)
1749+
1750+ - 一个Cache的操作无非三种:插入、替换、查找
1751+ - 插入:当Cache未满时,新的数据项只需插到双链表头部即可
1752+ - 替换:当Cache已满时,将新的数据项插到双链表头部,并删除双链表的尾结点即可
1753+ - 查找:每次数据项被查询到时,都将此数据项移动到链表头部
1754+
1755+ > [参考YYCache](https://github.com/ibireme/YYCache)
1756+
1757+ - YYMemoryCache
1758+ - _YYLinkedMapNode
1759+ - _YYLinkedMap
1760+
17151761</details>
17161762
17171763### 如何设计一个git diff
17181764<details>
17191765<summary> 参考内容 </summary>
17201766
1767+ - TODO
1768+
17211769</details>
17221770
17231771### 设计一个线程池?画出你的架构图
17241772<details>
17251773<summary> 参考内容 </summary>
17261774
1775+ > dispatch_semaphore
1776+
1777+ - 使用信号量机制可以实现线程的同步,也可以控制最大并发数。以下是控制最大并发数的代码
1778+
17271779</details>
17281780
17291781### 你的app架构是什么,有什么优缺点、为什么这么做、怎么改进
17301782
17311783<details>
17321784<summary> 参考内容 </summary>
17331785
1786+ - TODO
1787+
17341788</details>
17351789
17361790## 其他问题
@@ -1739,27 +1793,68 @@ dispatch_source_cancel(self.disTimer);
17391793<details>
17401794<summary> 参考内容 </summary>
17411795
1796+ > NSInvocation与PerformSelector:的作用是一样的,都是可以直接调用某个对象的消息
1797+
1798+
1799+ - 相同点: 有相同的父类NSObject
1800+ - 区别: 在参数个数<= 2的时候performSelector:的使用要简单一些,但是在参数个数 > 2的时候NSInvocation就简单一些
1801+
17421802</details>
17431803
1744- ### OC怎么实现多继承?怎么面向切面[(可以参考Aspects深度解析-iOS面向切面编程)](https://juejin.im/post/5e13c4366fb9a047f42e6406)
1804+ ### OC怎么实现多继承?怎么面向切面
17451805
17461806<details>
17471807<summary> 参考内容 </summary>
17481808
1809+ > Aspects
1810+
1811+ - 通过组合实现“多继承”
1812+
1813+ - 通过协议实现“多继承”
1814+
1815+ - 通过category实现“单继承”(大部分网上文章将此方法误解成“多继承”)
1816+
1817+ - 面向切面:打点等场景
1818+
17491819</details>
17501820
17511821### 哪些bug会导致崩溃,如何防护崩溃
17521822<details>
17531823<summary> 参考内容 </summary>
17541824
1825+ - [本系列第二份面试题:你认为开发中那些导致crash?](./02interview-iOS-2.md)
1826+
1827+ - Crash case
1828+
1829+ * unrecognized selector sent to instance 方法找不到
1830+ * 数组越界,插入空值
1831+ * [NSDictionary initWithObjects:forKeys:]使用此方法初始化字典时,objects和keys的数量不一致时
1832+ * NSMutableDictionary,setObject:forKey:或者removeObjectForKey:时,key为nil
1833+ * setValue:forUndefinedKey:,使用KVC对对象进行存取值时传入错误的key或者对不可变字典进行赋值
1834+ * NSUserDefaults 存储时key为nil
1835+ * 对字符串操作时,传递的下标超出范围,判断是否存在前缀,后缀子串时,子串为空
1836+ * 使用C字符串初始化字符串时,传入null
1837+ * 对可变集合或字符串使用copy修饰并进行修改操作
1838+ * 在空间未添加到父元素上之前,就使用autoLayout进行布局
1839+ * KVO在对象销毁时,没有移除KVO或者多次移除KVO
1840+ * 野指针访问
1841+ * 死锁
1842+
1843+ - 代码层加强数据校验
1844+ - Hook方式(数组,字典等)等
1845+
17551846</details>
17561847
17571848### 怎么监控崩溃
17581849<details>
17591850<summary> 参考内容 </summary>
17601851
1852+ - [本系列第二份面试题:crash的收集和定位bug的方式?](./02interview-iOS-2.md)
1853+
17611854</details>
1855+
17621856### app的启动过程(考察LLVM编译过程、静态链接、动态链接、runtime初始化)
1857+
17631858<details>
17641859<summary> 参考内容 </summary>
17651860
0 commit comments