复杂面试归纳

作者: LeafRead | 来源:发表于2016-07-13 17:31 被阅读67次

    1.简述你对缓存的实现和管理

    首先:介绍一片博客里面对iOS的缓存做了很详细的说明:http://www.cnblogs.com/qiqibo/p/3520635.html

    TCP和UDP

    1.在通信协议中,TCP和UDP属于传输层协议  socket只是一种连接模式

    2.TCP和UDP和最基本通信协议,其他协议基本上是基于这两个协议的,而用socket可以创建tcp和udp协议

    3.tcp和udp 的主要区别是tcp可以提供可靠的数据选择

    4.TCP---传输控制协议,提供的是面向连接、可靠的字节流服务。当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接,之后才能传输数据。TCP提供超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能从一端传到另一端。

    5.UDP---用户数据报协议,是一个简单的面向数据报的运输层协议。UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地。由于UDP在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快

    Cookies 和 Session的区别和共同点:

    1.cookie和session的共同之处在于:cookie和session都是用来跟踪浏览器用户身份的会话方式。

    2.cookie和session的区别是:

    1)cookie数据存放在客户的浏览器上,session数据放在服务器上

    2)cookie不是很安全,别人可以分析存放在本地的cookie并进行cookie欺骗,如果主要考虑到安全应当使用session

    3)session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能,如果主要考虑到减轻服务器性能方面,应当使用cookie

    4)单个cookie在客户端的限制是3K,就是说一个站点在客户端存放的COOKIE不能3K。

    5)如何选择:一般将登陆信息等重要信息存放为SESSION;其他信息如果需要保留,可以放在COOKIE中

    手写单例的实现

    +(AccountManager *)sharedManager {

    static AccountManager *sharedAccountManagerInstance = nil; static dispatch_once_t predicate;

    dispatch_once(&predicate, ^{

    sharedAccountManagerInstance = [[self alloc] init];

    });

    return sharedAccountManagerInstance;

    }

    问题一: 遇到APP闪退问题怎么处理?

    1.可以通过第三方查看奔溃日志,定位奔溃位置;

    2.查看客户的测试环境和我们的测试环境差异,排除系统版本和软件版本的差异

    3.排除是否存在内存溢出的问题,系统版本不匹配造成API使用不当的奔溃

    4.自己重新测试复现,打断点查看,leak工具查看

    问题二: 远程推送的原理步骤

    原理: 公司服务器通过APNs服务器找到装有我们APP的设备,并给设备上面的这个应用推送消息; 我们需要配置推送证书获得DeviceToken,推送证书需要知道我们的BundleID和UDID,还有服务器的UDID    证书申请步骤(1.注册一个苹果远程通知证书,2.绑定BundleID和苹果ID,并添加我们需要的服务3.配置推送证书;4.需要导入一个crs签名文件;5,在钥匙串中下载好crs文件,load进行配置,配置好了就直接下载下来;6.双击进行安装,在代理方法中就可以获得tokenID)

    问题三:kvc和kvo底层实现原理

    kvc :键值编码

    kvo:键值监听

    kvo是基于runtime实现的,也是kvc 关键技术之一,是一种观察者模式,利用它可以很容易的实现视图组件和数据模型的分离,当数据模型的属性值发生改变之后,监听器的视图组件就会被激活,激发时回调监听器自身

    kvc 设置属性时,会优先调用set方法,如果没有该方法,则优先考虑搜索带下划线的变量,如果仍然没有则搜索成员变量,如果也没有,则会抵用undefinekey方法,如果没有实现这个方法,则会直接奔溃

    kvc 读取属性时,会优先调用getter方法,如果没有则会优先搜索带下划线的成员变量,如果没有则会调用同名成员变量,最后还没有搜索到的话,则会调用undefinekey这个方法,如果没有实现,就会奔溃

    kvc 可以用来访问系统的私有属性 (列如 tabbar)

    问题四:sqlite异步请求数据  ??

    1.直接在请求数据时,开启一个异步线程进行数据请求,数据请求回来之后,通过线程间的通信回到主线程刷新UI

    问题二:怎么样对tableview进行性能优化

    1.适当的对cell进行复用

    2.正确的缓存,复用图片和数据

    3.在调用比较频繁的方法中,尽量减少逻辑计算时间 (把一些计算属性交给模型处理

    ,cell只负责展示数据)

    4.对cell的高度进行缓存,不要重复计算(在模型中重写cellHeight的getter方法)

    5.尽量避免在cell上使用图形特效 (图形越多,cell上面的UI组件渲染越慢)

    6.减少cell的层次结构,可以使用coreText进行绘图,cell的内容为图片显示.

    7.减少不必要的cell 显示和网络请求

    问题七:SDWebImage的底层实现

    SDWebImage开始下载任务,先进入SDWebImageManager-downloadWithURL:delegate:options:userinfo:   交给SDImageCache从缓存中查找图片是否已经下载,queryDiskCacheForKey:delegate:userinfo ;如果缓存中有图片,就会通过代理回调给SDWebImage并通过UIImage+webCache等前端展示图片;  如果缓存中没有,那么会生成NSInvocationOperation添加到队列中开始去沙盒中查找,在沙盒中是根据图片的URLKey进行图片的读取的,这一步是在NSOperation子线程中进行操作的,所以如果读取到沙盒中有图片,会回到主线程结束回调 ;如果沙盒中读取不到图片,说明所有的缓存和沙盒中都没有该图片,需要下载图片,接着回调imageCache:didNotFindImageForKey:userInfo; 并重新生成一个下载器SDWebImageDownloader开始下载图片;图片下载是由NSURLConnection来完成的,实现相关的delegate来判断图片下载状态

    问题八:AFNetworking的底层实现

    首先,AFNetworking这个库是在NSURLSession和NSURLConnection的基础上进行封装的,逻辑简单清楚,设计思想也比较好;,

    NSURLConnection是苹果IOS2.0之后推出的用于加载URL资源的API,使用比较简单,分为同步和异步请求,同步请求和异步请求的底层实现都是一样的,都是告诉系统请求一个URL资源,系统会有自己的私有线程去load资源,在load完成之后告诉调用者.唯一的不同是,同步会阻塞线程,然后程序一直等待,直到load完成,一般不会再主线程中调用同步方法,这样会阻塞用户的交互.  而异步方法,在程序调用完成之后就不用管了.程序还会继续往下执行,在load 完成之后会通知调用者,通知调用者的方式有两种,一种是通过代理,系统会在connection的调用线程中通知代理,第二种是queue方式,系统会在指定的queue中通知调用者

    AFNetworking是利用异步加载数据的方法,通过代理方式放回给调用者;首先请求调用必须有一个线程来执行.那么我们必须要处理这个请求在哪个线程中执行,因此AFNetworking就包含有connection和nsoperation;当然只满足于这两点显然是不够的,线程的并发数难以控制,这样就得引入NSOperationQueue来管理线程并发,然而在数据量比较大,线程比较多的情况下,线程之间的load速度不一样,一个线程的load任务完成之后,就只能等待其他线程的执行,比较浪费时间,因此可以让NSOperation去通知一个共同的线程去执行NSOperation的load方法;最后AF的模型为 NSConnection+NSOperation+NSOperationQueue+CommentNSTread

    我的理解:

    AFNetworking内部由NSURLSession实现,AFHTTPSessionManager的接口GET/POST,其内部实现如下:

    1、调用AFURLRequestSerialization的接口,对参数进行处理

    2、拿到参数已经处理好的NSURLRequest,调用父类AFURLSessionManager的接口,创建任务

    3、resume

    注:在执行resume方法时,此处用到Swizzling Method,详情见AFURLSessionManager.m文件中的_AFURLSessionTaskSwizzling类

    其中第2步的父类接口内部实现如下:

    1、直接拿到NSURLSession执行task(在AFURLSessionManager的构造方法中,给它设置了NSURLSession属性,并且设置了NSOperationQueue且最大并发数为1,设置为NSURLSession的代理)

    2、将NSURLSession与AFURLSessionManagerTaskDelegate相关联(通过NSProgress关联),进行上传/下载进度回调

    3、当NSURLSession任务执行完毕后,AFURLSessionManager将代理任务下发给AFURLSessionManagerTaskDelegate,TaskDelegate调用AFURLResponseSerialization的接口进行JSON解析,进行失败/成功回调

    其中AFURLResponseSerialization的接口内部由NSXMLParser/NSJSONSerialization实现,根据我们服务器数据的不同进行不同解析。

    相关文章

      网友评论

        本文标题:复杂面试归纳

        本文链接:https://www.haomeiwen.com/subject/titejttx.html