注:自己写的答案,水平有限,如有不足,欢迎指正!
1.选择一个你最熟悉的项目讲一下项目的技术架构,并说明你参与的模块和具体工作。
2.用户触发了一个事件,引起了一个服务请求,然后获取服务端返回,并且更新前端界面的过程。请说的详细一点,比如数据经过了哪些类的处理,每一次传递时的格式是怎么样的?
AN:点击事件触发请求,例如点击某个cell,界面跳转。客户端发起请求,需要在请求头配置一些固有参数,post请求的话,需要在body里面传入,userID,具体某个cell的id等约定好的一些参数。数据初始为字典或数组的形式,请求框架会将参数序列化为json格式,传递过程中会转话为二进制形式,服务端响应请求,返回数据,传递过程中同样以二进制形式传递,到客户端转化为json格式,经过反序列化转化为模型里需要的数据结构如字典数组字符串等。
3.如何处理多个网络请求并发的情况
AN:多线程异步触发,将多次线程operation放入GCD线程组去管理,dispatch_group
,当请求完成后,会触发线程组响应函数dispatch_notify会以block代码块的形式去处理回调,在代码块中做相应处理即可。
4.在网络请求中如何提高性能
AN:尽可能的将请求下来的数据缓存下来,降低请求的次数/采用异步多线程的方式去处理一些耗时操作/之前用的JSONRPC请求框架能做到,在一定时间内的多次请求打包,发起一次请求,分各响应/大文件的上传,上传前对文件压缩处理,并采用断点续传的方式/实时监测网络坏境的变化,如在3G网速稍慢的情况下,加载清晰度像素稍微低的图片,WiFi网速快的环境下加载高清图片等。
5.如何保证网络请求的安全性
AN:对部分关键接口采用加密处理,如MD5,RSA等/将域名IP映射文件打进包内,或上线后通过服务器下发的方式,防止DNS拦截攻击/采用HTTPS协议
6.MD5和base 64的区别及各自的应用场景
AN: MD5是一种非逆向加密的算法,把一个任意长度的字符串变成一定长度的十六进制数字串安全性更高,一般用于数字证书、安全访问的认证、用户密码等核心数据的加密;base 64是一种编码格式,是可逆的,安全性较低,一般用于处理文本数据,将二进制数据转换为文本数据,再就是编码后的数据肉眼不可读。
7.#define和const定义的变量有什么区别
AN:宏定义是在编译时在预处理阶段展开,const常量是一个运行时概念/宏定义是直接替换,不会分配内存存储于程序的代码段中,const常量需要内存分配,存储于程序的数据段/宏定义是字符替换,没有数据类型的区别无安全检查,const常量是常量的声明,有类型区别,需要在编译阶段进行类型检查
8.内存中的栈和堆的区别是什么?那些数据在栈上,那些在堆上?
AN:堆空间的内存是动态分配的,一般存放对象,并且需要程序员手动释放内存,堆是向高地址扩展的数据结构,是不连续的内存区域/栈空间的内存是由系统分配,一般存放局部变量等,不需要手动管理内存,栈是向低地址扩展的数据结构,在内存中的分布是连续的区域。
9.说说你对runtime消息机制的理解及你在实际开发中对runtime的应用
AN:对象实例调用方法时,该方法需要在接收者所属的类中搜寻其方法列表,若找不到沿着继承体系向上寻找,直到根类,若找不到方法的实现,执行消息的转发,会先征询接收者所属的类,看其能否动态的添加方法实现,若不能,请备援的接收者能否处理,若没有运行期系统会把消息相关的细节都封装到NSInvocation对象中,在看接收者能否处理,如扔不能处理,则抛出异常/实际开发中的应用:category中采用关联对象的方法动态的添加属性的setter、getter方法的实现;方法调配swizzing自定义方法替换原方法实现,如从字典或数组中取值添加过滤方法,防止由于空值导致的崩溃;KVO,其实现是利用了runtime能都动态添加类
10.简单描述下TCP的三次握手,TCP和UDP的区别是什么?
AN:客户端发送SYN报文,并置发送序号为X;服务端响应发送SYN+ACK报文,并置发送序号为Y,在确认序号为X+1;客户端发送ACK报文,并置发送序号为Z,再确认发送序号为Y+1/TCP是面向连接的,传输可靠,一般用于传输大量数据,传输速度慢;UDP面向非连接,传输不可靠,一般用于传输少量数据,传输速度快。经典例子,TCP类似于打电话,UDP类似于写信。
11.Notification的使用场景是什么?同步还是异步?
AN:一般适用于同时向多个对象监听响应的场景下,也用于传值.
默认是同步的,当发送通知时,通知中心会一直等待所有的observer都收到并响应后才会返回poster,但是可以通过通知队列去处理一下异步操作。
12.KVO一般都应用在那些场景,其实现原理是什么?
AN:KVO一般用于实现model与view之间的通讯,对属性频繁变化的监听/当用KVO观察某对象a时,KVO机制动态创建一个对象a当前类的子类,并为这个新的子类重写了被观察属性keyPath的setter方法,setter方法随后负责通知负责通知观察对象属性的改变状态。
13.说说你对事件响应链的理解
AN:发生触摸事件后,系统会将事件打包成一个UITouch或UIEvent对象,找到当前运行的程序,会将事件加入到UIApplication管理的一个队列中;UIApplication将处于任务队列最前端的事件依次向下分发,UIApplication至UIWindow至UIViewController至UIView至SuperView至SubViews直至最上层的事件处理者(通过判断对象是否继承自UIResponder及触摸点是否在其视图范围内以及判断其是否能接受事件:alpha = 0或userInteractionEnabled = NO或hidden = YES不能接受事件),最上层继承自UIResponder的对象调用touch方法,判断是否实现touch方法,没有实现默认会将事件传递给上一个响应者,直至UIApplication如果事件,仍没得到响应,则事件被丢弃。
14.如何制作一个静态库/动态库,它们的区别是什么?
AN:制作静态库New->Project->Cocoa Touch Static Library;指定静态库需要公开的头文件;分别用真机和模拟器编译静态库会生成相对应的静态库文件,如有需要可以在终端用lipo –create路径1路径2 –output路径3命令合并/静态库在编译链接时,会被完整的复制到可执行文件中;动态库是在运行时加载到内存中,多个程序共用一份,但是Apple不允许上架有自定义动态库的项目。
15.描述下tableview cell的重用机制
AN:tableView维护着一个cell的资源池,一般只需创建屏幕出现cell数+1的cell即可循环复用,当cell完全滑出屏幕范围,会放入其资源池。当再次需要创建cell的时候,会根据reuserID去资源池中取,如果资源池中没有id对应的cell,则创建新的cell。
16.自定义一个控件,怎么做到在任何时候出现都在界面最上层?
AN:创建一个window,将控件添加到window上,获取UIApplication对象的windows数组中lastobject元素的level,将新创建window的level设置为其level+1,即可实现总是出现在界面的最上层,甚至能盖住系统的键盘、弹窗等。
17.说说你熟悉的第三方框架都有哪些,你是怎么理解它们各自的实现原理的?
AN:
SD_WebImage,通过对UIImagView的类别扩展来实现异步加载显示图片,并采用三级缓存机制实现对图片的缓存。加载图片时,会先显示PlaceHolderImage,然后根据URL从缓存中查找图片是否已经下载,如果有通过代理回调显示图片,若内存中没有生成NSInvocationOperation添加队列开始从硬盘查找图片是否存在,若存在将图片添加到内存缓存中,代理回调显示图片,若没有生成下载器下载图片,下载完成后做图片解码处理,解码完成后,回调显示图片,并在内存和硬盘中同时缓存。内存层面以key-value的形式存储图片,当内存不够时会清除所有的缓存图片。
/AFNetWorking,主要包含网络通信模块(AFURLSessionManager、AFHTTPSessionManager)、网络状态监听(Reachability)、网络通信安全策略模块(Security)、网络通信信息序列化反序列化等几个核心模块。其作用体现在,帮我们做个各种请求方式request的拼接,做了一些公用参数(session)和一些私用参数(task)的分离,并且帮我们做了自定义的https认证处理,对于请求到的数据,帮我们做了各种格式的数据解析,并且支持自定义数据方式,对于请求成功和失败的回调做了很多容错处理,并且对于线程、锁以及性能方面做出了最优化的处理。
/AsynDisplayKit,基本使用单元是node,ASDisplayNode是一个UIVIew层之上的封装,就像UIView是对CALayer的封装一样。跟View不一样的是,node是线程安全的,就是说你在非主线程对node进行初始化以及配置它们的层级操作都是安全的。AsynDisplayKit让你把image的解码、text sizing和渲染,以及其他的费时的UI操作放置在子线程中去执行。其核心组件包括ASDisplayNode与UIView对应,用来扩展生成定制的nodes;ASControlNode类似UIControl用来扩展生成button;ASImageNode类似UIImageView,图像的解码可以异步执行;ASTextNode类似UITextView,在TextKit上支持所有的富文本特性等。
/Masonry用代码来做布局适配。
18.如何实现H5和原生的交互,在实际开发中举例说明
AN:基于JSBridge开源框架实现H5和原生的双向交互。/如:签到,活动第三方分享成功后,给用户奖励,并且h5界面做相应的变化。首先对WebViewJavaScriptBridge对象初始化化,遵循其协议,与h5端约定方法名,调用方法注册的API,data参数是JS传递过来的信息,responseCallback中的字符串参数来将信息传递给JS,以此达成H5与原生双向交互的目的。
19.iOS开发你所知道有几种锁,谈谈你对它们的理解
AN:
原子锁,用于属性修饰符,但是由于当多线程执行读取操作时,其原子性并不是绝对的安全,并且很消耗性能,故而在声明属性时一般都声明为nonatomic即非原子性。
/同步,@sychronized(self){}自动对参数对象枷锁,保证代码块中线程安全;NSLock,需要初始化一个NSLock对象,在对象执行lock与unlock方法区间内加锁,保证其作用域内线程安全。
/死锁,在某一个串行队列中,同步的向这个队列添加block操作会造成死锁。如,在主线程中下面代码就会造成死锁,
dispatch_sync(dispatch_get_main_queue(),^(void){
NSLog(@”1”);
})
NSLog(@”2”);
dispatch_sync这个函数会把一个block加入到指定队列中,而且会一直等到执行完block,这个函数才会返回,而在同步的主线程中,操作是按顺序执行的,故而两个操作会相互等待,阻塞主线程造成死锁。
20.https与http的区别是什么,描述下https的认证流程
AN:https协议需要申请SSL证书,由SSL+http协议构建的可进行加密传输、身份认证的网络协议比较安全,所用端口号为433;http是超文本传输协议,信息是明文传输,安全性较低,其所用端口号为80;
https的认证流程:
1.客户端向服务器发送SSL版本号及随机数等信息
2.服务器返回公钥证书及随机数等信息
3.客户端使用服务器返回的信息验证服务器的合法性
4.客户端向服务器发送自己所能支持的对称加密方案,供服务端选择
5.服务端选择加密方案并将加密方案以明文的方式返回客户端
6.客户端使用服务端返回的加密方式生成随机码,用作通信过程中对称加密的密钥,使用服务端返回的公钥进行加密,将加密后的随机码发送至服务器
7.服务器收到客户端返回的加密信息后,使用自己的私钥进行解密,获取对称加密密钥
8.在接下来的会话中,服务器和客户端将会使用该密码进行对称加密,保证通信过程中的安全。