最近iOS面试总结 2018.12 (更新12%)
2018-12-21 本文已影响248人
Hugin
公司11月倒闭了,又到了重新找工作的时候,因为在上家公司一年半的时间里各种摸鱼,水平也是直线下降,导致面试时各种说不清原理,所以做一个面试总结吧,也加强下自己回答问题的总结能力233...
问题1:说说 mvc mvvm ?
首先,自己面试的总结能力不强,碰到这种概念问题也是各种无语233...
我认为的回答流程:
- 首先这个 MVC用来做什么,MVVM跟他有什么关系?
这两者都是架构模式(设计模式),MVVM是 MVC模式的一种演进,它主要解决了 ViewController过于臃肿带来的不易维护和测试的问题.
- 什么是 MVC?
- M指的是模型,用于存放数据和业务逻辑。
- V指的是视图,用于渲界面和用户交互。
- C指的是控制器,主要调节模型和视图两者之间的关系。
- 在 MVC中控制器可以跟模型或视图进行直接或间接通信,但模型跟视图之间不能通信。
- 视图发生交互事件,则把事件传递给控制器,控制器会更新这个视图对应模型数据来响应交互状态。
- 模型的数据刷新了,则通知控制器,让控制器渲染对应的视图刷新界面。
- 为什么有了 MVC还会出现 MVVM?
- MVC的使用不当会使用 ViewConreoller变得相当臃肿,难以维护。
- 一般来说模型通常非常的简单,很多时候就是添加对应的属性,没有其他的代码。只是用来方便数据存取。很多业务逻辑代码都放在了 ViewConreoller中。
- 控制器本来只是协调模型和视图之间的所有交互。但是 ViewConreoller包含了视图和控制器,使用两者之间过于紧密。它要负责管理所拥有的视图的结构层次、生命周期、加载、布局、显示、消失、释放等等。还有加载网络数据、刷新模型视图、遵循许多协议等等。所以使 ViewConreoller过于臃肿,带来的不易维护和测试的问题。
- 什么是 MVVM?
- MVVM指得是把 MVC中C给替换成VM,就是视图模型。
- 模型层作用相同,没有改变,还是原来的M层;view 和 viewController联系在一起,视为同一个组件就是V层。
- 视图模型主要代替了之前控制器做的事,从而减少了 ViewConreoller的代码。让ViewConreoller成为中间人,接收视图事件,调用对应viewModel方法,响应ViewModel的变化。
- view viewController可以直接引用 viewModel, viewModel可以直接引用 model, 可是反过来不行。viewModel可以绑定一个 view上,当 view改变时,通过 viewModel 修改对应的 model, 当 model改变时通过 viewModel修改对应的view。
- 项目中的使用?
- 可以配合 RAC让 veiw viewModel 做一个绑定,当数据跟视图一起改变。但这个 RAC有一定的学习成本,如果项目开发人员不能对这个框架有一定的认知,使用起来也会变得复杂,而且这个属于重量级框架,引入项目中会有一定的开销。
- MVVM是 MVC的升级版,完全兼容当前的 MVC架构,MVVM虽然促进了 UI代码与业务逻辑的分离,一定程度上减轻了 viewController的臃肿度,但是 View和 ViewModel之间的数据绑定使得 MVVM变得复杂和难用了,如果我们不能更好的驾驭两者之间的数据绑定,同样会造成代码过于复杂,代码逻辑不易维护的问题。
- 项目中这两种模式使用其实不冲突,项目中那些模块使用那种模式,可以基于实际考虑。如果控制器代码量不多,传统的 MVC就可以应对,如果控制器所做的事情过多,也可以参考 MVVM来对控制器进行减压。
这个MVVM真不知道怎么用,希望有人可以指点下
用到的参考资料:
- 浅谈MVC和MVVM模式
- iOS 关于MVC和MVVM设计模式的那些事
- Model-View-ViewModel for iOS [译]
- 关于iOS中MVC和MVVM的一些思考
- MVVM 介绍
- iOS开发:MVVM的使用分析
- iOS 架构模式--解密 MVC,MVP,MVVM以及VIPER架构
问题2:你有没有看过开源源码?说说看?(AFNetworking)
这个问题,那个,我复习时源码看了,当时说出来说的好乱,真难受。。。
我认为的回答流程:
- 首先afn是啥? 有啥用?(我面的都是小公司,一般面我的可能不是做ios。。。)
afn是一个网络请求框架。。。2.0基于NSURLConnection 3.0基于NSURLSession
- afn代码结构?
afn 由5个模块组成
- 网络通信模块
- 网络状态监听模块
- 网络通信安全策略模块
- 网络通信信息序列化/反序列化模块
- 对于iOS UIKit库的扩展
- 其中为核心网络通信模块,而其余的四个模块,均是为了配合网络通信模块或对已有UIKit的一个扩展工具包。
- afn实现流程?
- 网络通信模块有两个类,一个是 AFHTTPSessionManager, 一个是 AFURLSeesionManager。其中 AFHTTPSessionManager继承 AFURLSeesionManager,但是它本身是没有做实事,只是封装 HTTP请求,如POST、GET、HEAD、PUT、DELETE等等。并通过调用父类方法发送网络请求。
- AFHTTPSessionManager的初始化,其实是调用父类完成初始化过程。自己只保存了一个 baseURL,还生成了一个请求序列对象。
- AFURLSessionManager的初始化主要有3点
- 初始化一个operationQueue对象, 并设置最大并发数为1,这个我们af自定义代理回调的queue。
- 初始化一个session对象, 并成为他的代理,默认的实现对应的协议。
- 初始化一个字典,主要用于映射请求task与af自定义代理, afn对task代理进行了封装,并转发了一部分到af自定义代理中。
- 我用调用AFHTTPSessionManager的请求方法,绝大多都会走同一个方法,在这个方法中,通过请求序列对象,把请求方法 url 参数序列化成一个request对象。调用父类方法生成task, 并开启task。
- 通过AFURLSessionManager生成task时,就会创建af自定义代理并与task进行绑定。
- afn做了什么?
- 首先它通过请求序列化对象来做各种请求方式 request的拼接。
- 通过block的方式让我们简化的URLSeesionDelegate实现过程。
- 帮我们做了自定义的https认证处理.
- 对于请求到的数据,AF提供各种格式的数据解析,并且支持我们通过block设置自定义的解析。
- 做了网络请求成功和失败的回调处理。
- 怎么使用afn?
- 一般对应网络库会进行二次封装,这样做有利于网络请求的管理,以及方便日后对网络库的随时更换。
- 二次封装之后,请求失败统一错误处理,开发过程中调试接口统一log输出日志,添加通用公共参数,参数的统一加密等等。
看看这个大佬写的afn源码解析,通俗易懂:
- AFNetworking到底做了什么?(一)
- AFNetworking到底做了什么?(二)
- AFNetworking之于https认证
- AFNetworking之UIKit扩展与缓存实现
- AFNetworking到底做了什么?(终)
问题3:说说内存管理?
- iOS中内存管理方式是引用计数机制,引用计数是一种简单方便的管理对象生命周期的一种方式。每个oc对象都有一个retainCount属性,当一个新的指针引用当前对象时,这个retainCount+1,当不引用时retainCount-1,每次runloop,都会检查对象retainCount是否为0,为0说明这个对象没有其他地方需要使用,则可以释放回收内存。
- ios给我们提供了两种使用方式,一种是MRC手动引用计数器,一种是ARC自动引用计数器。手动引用计数是当一个对象创建时,如果通过alloc new等类方法创建的对象,此时对象的引用计数已经是1,所以我们要在这个对象不使用之后,调用 release方法,使对象引用计数减1,如果此时有别的指针引用当前对象,则调用retain方法,使对象引用计数加1,在这个指针不用时,调用 release方法,使对象引用计数减1,这样就能保证,在对象不用时引用计数为0,就可以释放内存。ARC就是基于MRC,他在编译期会自动帮我们添加retain release 方法,让我们不用关心内存管理的一种技术。
- 现在开发都是使用ARC,可以解决开发中 90% 的内存管理问题,但是还有 10% 内存管理,是需要自己处理的。主要有两个地方,一个循环引用问题,一个是底层 CoreFoundation 对象,需要自己手工管理它们的引用计数。
- 循环引用,当一个对象A持有另外一个对象B,而此时对象B也持有对象A,那么会产生循环引用。一般出现在block中相对较多,block作为对象的属性,在block内部又引用当前对象。解决方法两种方法,1.一种是主动断开循环引用,在block执行完成后,主动释放对于 block 的持有,以便打破循环引用。这种方法使block成为一次性,性质像系统 UIView animationsBlock方法; 2.一种是使用弱引用weak __weak等等,弱引用虽然持有对象,但是并不增加引用计数,这样就避免了循环引用的产生,像代理属性用weak修饰,block引用当前对象用__weak修饰等等。
用到的参考资料:
问题4:说说 tcp/ip
- OSI模型中网络被分为七层,由底层向高层依次是:物理层,数据链路层,网络层,传输层,会话层,表示层和应用层。
- 物理层是将 0、1 构成的比特流与电子信号进行转换,使比特流在物理介质中传播。
- 数据链路层定义了通过物理介质相互连接的设备之间,数据传输的规范。在数据链路层中,数据不再以 0、1 存在,它通过分组交换把大数据分割为若干帧,然后根据MAC地址找到对应设备进行传输。
- 网络层,它实现终端节点间的通信。数据链路层的作用在于实现同一种数据链路下的包传递,而网络层则可以实现跨越不同数据链路的包传递。
比如主机A通过Wi-Fi连接到路由器B,路由器B通过以太网连接到路由器C,而路由器C又通过Wi-Fi与主机D保持连接。这时主机A向D发送的数据包就依赖于网络层进行传输。IP协议是网络层的一个重要协议。IP地址是一种在网络层用于识别通信对端信息的地址。它有别于数据链路层中的MAC地址,后者用于标识同一链路下不同的计算机。举个例子,深圳地铁1号,白石洲,高新园,深大三站,我家在白石洲要去深圳大学,通信两端的地址分别是家和学校,他们相当于IP地址。我从家可以骑摩拜到白石洲地铁站,再坐地铁到深大站,走路到深圳大学,在这个过程中三种交通方式,就相当于不同的数据链路,每次中转都有起点和终点就相当于mac地址。- 传输层的主要作用是实现应用程序之间的通信。网络层主要是保证不同数据链路下数据的可达性,至于如何传输数据则是由传输层负责。常见的传输层协议主要有 TCP 协议和 UDP 协议。TCP 协议是面向有连接的协议,也就是说在使用 TCP 协议传输数据之前一定要在发送方和接收方之间建立连接。一般情况下建立连接需要三步,关闭连接需要四步。建立 TCP 连接后,TCP 协议能够正确处理丢包问题,保证接收方能够收到数据,与此同时还能够有效利用网络带宽。然而 TCP 协议中定义了很多复杂的规范,因此效率不如 UDP 协议,不适合实时的视频和音频传输。UDP 协议是面向无连接的协议,它只会把数据传递给接收端,但是不会关注接收端是否真的收到了数据。但是这种特性反而适合直播实时视频和音频传输。因为个别数据包的丢失并不会影响视频和音频的整体效果。
- OSI只是一个理论上的参考模型,会话层,表示层一般来说在开发过程中并没有真正从应用层中独立出来。HTTP协议作用于应用层。
用到的参考资料:
问题4:说说什么是 HTTP? 什么是HTTPS?
-
http是常用的网络协议。在浏览器访问一个网页时就是用http协议,客户端首先与服务端的 80 端口建立一个 TCP 连接,然后在这个连接的基础上进行请求和响应,以及数据的交换。HTTP协议和TCP协议是不冲突的,HTTP作用于应用层,TCP解决的是传输层的逻辑。
-
HTTP 协议中的内容都是明文传输,HTTPS 的目的是将这些内容加密,确保信息传输安全。S 指的是 SSL/TLS 协议,它位于 HTTP 协议与 TCP/IP 协议中间。
- 客户端使用公钥将信息加密,密文发送给服务端
- 服务端用自己的私钥解密,再将返回数据用私钥加密发回客户端
- 客户端用公钥解密
用到的参考资料:
问题4:你在项目中做过什么?解决过什么问题?项目有什么亮点?
这个我真不知道怎么说,我这小破app,都不知道怎么回答。。。
问题5:说一下TCP和UDP?
- 这两者都是作用于传输层的协议。
- tcp是面向有连接的协议,而udp是面向无连接的协议。
- tcp协议在传输数据之前一定要在发送方和接收方之间建立连接,所以就有三次握手和四次挥手机制。
- udp协议只会发送数据到接收方,并不关注接收方是否真正接收到数据。
- 所以这两者适用的场景不一样,要考虑到数据的完整性就使用tcp,因为tcp有数据重传等功能,能够正确处理丢包问题,保证接收方能够收到数据。因为功能过多效率不如udp,像实时的音视频传输,对个别数据包的丢失并不会影响视频和音频的整体效果,那么在这种场景下udp更加适合。
- tcp的3次握手过程
- 客户端创建tcp请求报文,其中报文中包含随机生成seq序列号,并将报文中的syn字段置为1,发送给服务端,表示需要建立连接。
- 服务端接收到tcp请求报文,会创建一个响应报文发送给客户端,其中报文中包含另一个随机生成seq序列号,并产生一个ack字段,ACK = 客户端seq + 1,syn = 1,发送给客户端,表示知道并验证建立连接。
- 客户端收到服务端响应报文,sep序列号+1,ACK = 服务端seq + 1,syn = 1,发送给服务器表示建立连接。
- tcp的4次挥手过程和3次握手过程差不多
- 客户端通知服务端表示要中断连接。
- 服务端收到并回复表示正在在中断连接工作。
- 服务端通知客户端表示中断连接工作完成可以中断。
- 客户端通知服务端中断连接。
- 所以tcp有这些机制,就可以做到数据重等功能,因为发送的数据一般来说,不可能一次发送完成,一般来说要通过网络层那边的分组交换把数据分割成若干帧小数据,每次发送一部分,如果对方接收到会回复,之后发送下一段数据,如果对方没回复可能发生数据包的丢失,则重新发送这部分数据,直到对象回复,当然也有超时时间,如果对方超时则会关闭连接。