这是一篇关于技术知识点的整理汇总,在技术道路上,有许多知识点属于不常用但有用的知识,如果不加以记录,时间久了记忆就会模糊,不利于知识积累。我就是深受其害o(╥﹏╥)o
编程思想与框架
面向过程/面向对象/响应式编程
Q: 面向过程思想
A: 一切以过程为核心去解决问题的语言。将解决问题的方法视为函数,按解决问题的步骤去调用函数,就组成了过程。面向过程适合解决细化的问题。
Q: 面向对象思想
A: 一切以对象为核心去解决问题的语言。对象作为实体,通过对对象进行数据抽象和行为抽象得到了类;通过封装隐藏了内部实现;通过多态实现了动态分配;通过继承实现了特殊化和基本化(这两个我没找到好的形容词)。面向对象适合解决复杂的、静态的问题。
Q: 响应式编程
A: 响应式编程是以关系为核心去解决问题的语言。在现实世界,当关系产生了变化,你可以通过电话、短信任意的联系方式去获取状态变化,以及做出自己的反应。在计算机世界,它的传递方式是数据流。接受数据流的可以是对象,可以是函数。响应式编程适合解决动态的问题。
Q: 编程思想的理解
A: 一切编程思想都是对解决现实问题的某种思考方式,依据这种思考方式去解决问题就是编程思想。
MVC、MVVM、MVP
Q: MVC框架构成
A: Model(数据)/View(视图)/C(控制器)。V和M可以直接通信,所以M中存在数据处理的逻辑,V中存在数据展示的逻辑,C用来接收事件,向M传送数据等其它逻辑。
Q: MVP框架构成
A: Model(数据)/View(视图)/P(展示器)。V和M不可以直接通信。M只具有简单的数据模型,V只具有简单的控件组成,它们没有逻辑在内。P则会把所有的逻辑在其内去处理,这是它和MVC的不同。
Q: MVVM框架构成
A: Model(数据)/View(视图)/VM(控制器)。V和M不可以直接通信。M只具有简单的数据模型,V只具有简单的控件组成,它们没有逻辑在内。VM会包含所有逻辑,但它的实现是进行data-binding来动态的修改数据,这是它与MVP的不同。
Q: 三者的关系
A: MVC衍生出MVP,MVP衍生出MVVM。三个框架没有高低之分,只有适合与不适合,毕竟它们三者都是为了解耦。是数据、界面、逻辑由谁来负责在发生变化。如果具体到iOS上面,由于官方的原因,C本身就是一个很重的东西,即使M和V会帮助C分担一部分的逻辑。所以在iOS上面,我认为也可以理解为通过不同的手段为C减负,保证代码组织的合理性。
编译原理相关
Q: dSYM文件是什么,作用。
A: 每次编译后都会产生的一个文件,本质是一个符号表,包含内存地址、函数名、文件名、行号。作用是可以查找到指定内存地址对应的函数位置。
Q: 如何防止反编译
A: 本地数据加密、URL加密、网络请求加密、代码混淆、代码逻辑混淆
App相关
Q: App启动过程
|
|
Q: App启动优化
|
|
Q: App内存分布
A: 内存地址由高到低,栈区,堆区,静态区,常量区,代码区
Q: App框架层级
|
|
Q: App性能优化
|
|
Q: tableView性能优化
|
|
Q: 读取一个xib文件的步骤
|
|
多线程相关
Q: 多线程是什么,作用,缺点
A: 多线程是指多个线程并发执行的技术。作用是用来提升同一时间段内系统的处理效率,也就是作业量。缺点是消耗资源,使用不当容易造成数据竞争,死锁,优先级反转等问题。
Q: 线程是什么,特点
A: CPU执行的最小单元,由线程ID、指令指针、寄存器、堆栈组成,也常被称之为轻型进程。特点是无单独的内存空间,与同一进程下的其他线程共享进程的内存空间;线程crash会导致进程crash。
Q: 单线程、并发、并行
A: 一个CPU在一条线程上执行单一无分叉路径为单线程。一个CPU在多条线程切换执行称为并发,也叫伪.多线程。多个CPU同时执行多条线程称为并行,也叫真.多线程。
Q: 数据竞争/死锁/优先级反转
A: 数据竞争,即资源非互斥状态。如果一个属性被多个进程读没有问题,如果同时有进程写入,那么有些进程就会获得旧数据。因此可以通过加锁或者栅栏来解决。
死锁需要四个条件:资源互斥、请求和保持、循环等待、不可剥夺。破坏任何一个就能解决死锁问题。A和B两个线程访问R1和R2资源,如果各持有一个的话,那么A会等B释放,B会等A释放,就形成了死锁。
优先级反转:A,B,C三个线程,优先级A>B>C。C先运行占用资源R,A然后运行来使用资源R,但R已被使用,A只能等待,这时任务B来执行,由于优先级高于C,所以B先执行,然后C执行,最后才是A执行,这样就产生了优先级反转。解决办法是优先级天花板和优先级继承。优先级天花板是指,任意使用资源R的线程,它的优先级都会被提到这个资源的最高优先级。这样就不会出现优先级反转的问题了。优先级继承是指,当C在使用资源R时,A也要使用资源R,通过判断,如果C的优先级低于A,那么将C的优先级临时提升到A。
Q: pthread、NSThread、NSOperation、GCD
A: 都是多线程问题解决方案,pthread和GCD都是一套C语言API,NSThread和NSOperation是一套OC语言的API。pthread和NSThread对线程直接操作,并且需要程序员去管理生命周期,很少使用。NSOperation和GCD不是直接面向线程操作,而是把要执行的方法提交到指定的block或者对象中,程序员无需管理线程的生命周期,也无需考虑当时CPU的使用情况以及消耗,系统会自动进行分配。NSOperation比GCD更易于管理,很简单就可以实现对执行任务的暂停取消依赖等操作。而GCD功能更颗粒化,适合需求简单的多线程操作。
Q: GCD的同步/异步,并发/串行
|
|
Q: NSOperation/NSOperationQueue
|
|
Q: 锁
|
|
Q: 信号量
|
|
Q: 如何避免多线程的常见问题
A: 选择合适的多线程技术;尽量简化线程之间的关系;尽量指定相同优先级;队列中写操作栅栏,读操作并行。
版本控制
Q: SVN,Git
A: SVN是一个集中式控制系统,管理集中在远程服务器。Git是一个分布式控制系统,每台使用git的电脑都拥有版本库,远程也有一个远程库,用来做数据交换。
Q: SVN的缺点
A: 第一,连接不到远程服务器基本无法工作;第二,每个分支每次提交都是整体的拷贝,占用存储空间。
Q: Git的差异记录方式
A: 整体文件做一个快照,文件有变化,产生一个新的快照;文件无变化,延用上一个快照。会使用文件内容或者目录结构生成一个40位的十六进制的哈希值。
组件化
Q: 如何组件化
A: 首先要明白组件化的实质就是把一个整体的耦合度高的项目给拆分成各种小的模块,拆成了模块之后,为了不让各模块耦合,需要一个中间层去进行模块间的通讯。对于一些基础功能模块和可以通用的模块,如网络请求,帮助类,公共UI库可以以cocoapods的方法去进行管理,便于多项目通用和版本管理。
runloop
Q: runloop的运行顺序
|
|
Q: runloop概念
|
|
Q: runloop处理的事件
|
|
block
Q: 什么是block
A: 从表面看,block就是一段封装的代码,可以传递数据。从本质上看,它是闭包在iOS的具现化表现。按维基百科给出的解释,闭包就是一个封闭的作用域可以保存捕捉到的外部变量。从代码看,使用clang rewrite之后的block就是一个结构体,包含一个isa指针,捕捉的变量,实现的C函数,描述结构体。
Q: 为什么添加__block后,变量可以被修改
A: 因为添加之后,捕捉的变量就从一个普通的值引用变为了指针引用,用__block修饰的变量会生成一个结构体,结构体内部存储isa指针、变量、forwarding指针、释放函数、copy函数。
屏幕渲染
Q: 屏幕渲染大致流程
|
|
runtime
Q: 什么是runtime
runtime是一套底层的C语言API,是iOS的核心之一,平时写的代码,底层都是基于它实现的。
Q: runtime的作用
将一部分编译和链接时候做的工作,转移到运行时去做
内存管理
Q: 主线程中的所有对象会加入到自动释放池吗?
A: 不会,只有调用了autorelease方法的会。一般就是new/alloc/copy/retain之外的对象会自动调用autorelease。
Q: 主线程中的对象什么时候释放?
A: 如果未被加入自动释放池,在引用计数归0后,内存区域会被标记为可分配,但其中的内容并未清理。如果加入了自动释放池,在自动释放池释放时会执行一次release方法,这个时候如果引用计数为0,内存区域会被标记为可分配。
Q: main函数入口的自动释放池中的对象什么时候释放?
A: 系统在每次runloop开始的时候创建了一个自动释放池,在结束的时候释放这个自动释放池,对象也就是在这里释放的。
Q: 子线程中没有runloop,它的自动释放池什么时候释放?
A: 没有runloop,线程不会一直存在,自动释放池也会在线程结束的时候释放。
Q: 内存区域的释放时机?
A: 所谓的释放只是将其标为可分配,其内的值仍然存在。值的覆盖实际上发生在这块内存区域被重新使用时。
Q: Autorelease原理
|
|
Q: Autorelease对返回值的优化
依赖于TLS机制,这是一块某个线程专有的存储内存,以key-value进行读写。调用objc_autoreleaseReturnValue时将其存储进去,调用objc_retainAutoreleasedReturnValue时,去TLS中读取,如果读取到就不需要retain了。如果一方ARC,一方非ARC,那就需要依赖地址偏移量了。
Q: 关联对象功能、基本内部参数(参考objc-refrences.mm文件)
|
|
Q: objc_setAssociatedObject
|
|
Q: objc_getAssociatedObject
|
|
Q: objc_removeAssociatedObjects
|
|
JavaScriptCore框架相关
JSCore框架特性
- 自动化的,类型自动转换
- 安全的,JS是一门动态类型语言,OC是静态类型语言,它保证了转化过程中不会产生crash,并且JSCore提供的方法是线程安全的
- 高保真的,说白了就是两边互不侵犯,写OC就写OC,写JS就写JS
JSCore框架中的几个类
- JSContext 提供JS执行环境的类
- JSValue 是对JS对象的封装,包括函数,可以进行OC对象和JS对象的转化
- JSManagedValue 因为JSValue是对js值得强引用,所以很容易造成内存问题,这样就有了JSManagedValue
- JSExport 一个协议,使用这个协议,可以将OC中的对象暴露给JS使用。也可以通过直接给jsContext注入block进行单个方法的注入
- JSVirtualMachine 它为JS运行提供了底层资源,有独立的堆栈以及垃圾回收机制。一个进程可以包含多个JSVirtualMachine,一个JSVirtualMachine可以包含多个JSContext。一个JSVirtualMachine下不同JSContext中的JSValue可以互相传递,但是不同的JSVirtualMachine不行。
iOS 算法题
一副牌除掉大小王52张,随机抽取一张扔掉,如何得知扔掉那张牌数值以及花色是多少?
YYBox一个数组存储52张卡牌,一个方法随机删除一张;YYCard就一个数值1-13,一个类型黑红梅芳四种。
|
|
问题:一个农场有一只奶牛,第二年和第四年会生育小牛,第五年死亡。生育的小牛同样如此,不考虑公牛,N年后农场多少只牛?
YYFarm只要一个牛的数组;YYCow一个牛的年龄,一个牛年龄加1的函数,这个函数会返回三种结果类型,生小牛,死,无.
|
|
冷门小知识
Q: ==,isEqual,各类衍生的isEqualXXX的区别
==直接判断,判断基本类型时,判断值是否相等。判断对象时,判断所指向内存地址是否相同。
isEqualXXX,由isEqual衍生而来,当你知道两者类型相同时,使用这个比isEqual快。应该是省去了二者类型的比较和指向地址的比较,直接进行内容比较。
isEqual,NSObject提供的方法,正常来讲是跟==相同。但是iOS中的一些类对它进行了重写,我知道的有UIColor,NSArray,NSDictionary,NSSet,NSData.重写之后它们只进行类型判断和存储的数据判断,而不判断指向地址。不信的话,你可以初始化两个NSObject进行判断,再初始化两个NSArray进行判断,看下返回结果。
最后提一嘴,值相同的,hash值也相同,反之不一定。
Q: App中使用了单独hash表的有
|
|