美文网首页
面试复习笔记

面试复习笔记

作者: Kevin_wzx | 来源:发表于2020-06-17 16:09 被阅读0次

    目录

    1.解决报错libc++abi.dylib handler threw exception
    2.什么情况使用 weak 关键字,相比 assign 有什么不同?
    3.内存优化举例说几点?
    4.MVVM简要描述
    5.利用第三方库实现OC与JS的交互(WebViewJavaScriptBridge)
    6.使用FMDB、SQLite进行数据库的CRUD简单写法
    7.如何解析XML数据?
    8.UIView动画与Core Animation的区别和选择?
    9.多线程:NSThread、NSOprention和gcd的差别与联系?
    10.容错处理你们一般是注意哪些?
    11.Objective-C框架
    12.说说自己平时定制了哪些UI?
    13.一般开始做一个项目,你的架构是如何思考的?
    14.在使用AFNetWorking的时候你是直接用还是二次封装,二次封装你是怎么做的?
    15.在你使用的众多第三方库中,你觉得哪个对你来说印象深刻,使用的时候需要注意什么?遇到过什么问题没有,怎么解决?看过哪些源码,讲讲思路(SD、YY、AFN、MJ等)
    16.UIView 与CALayer
    17.HTTPS的加密方式、单双向认证的理解?
    18.runtime的理解
    19.什么时候会报unrecognized selector的异常?(考iOS消息转发机制-runtime)
    20.BAD_ACCESS在什么情况下出现?
    21.runLoop的理解:在下拉刷新表格时如何让上面的轮播图也继续自动轮播
    22.事件传递与响应
    23.内存中的栈和堆的区别是什么?那些数据在栈上,哪些在堆上?
    24.#define和const定义的变量,有什么区别?
    25.block在内存管理上的特点、需要注意循环引⽤,如何解决循环引⽤?
    26.block与__block与__weak与__storng这些啥关系、用法
    27.单例举例
    28.下面代码输出什么?
    29.你在项目中遇到过什么问题没有?
    30.地图的使用?
    31.即时通讯怎么实现的?
    32.iOS开发过程
    33.值得看的文章

    1.解决报错libc++abi.dylib handler threw exception

    https://blog.csdn.net/weixin_30838873/article/details/99636122

    2.什么情况使用 weak 关键字,相比 assign 有什么不同?

    https://www.jianshu.com/p/fec68e84cee9

    • 补充:IBOutlet连出来的视图属性为什么可以被设置成weak?

    在 storyboard 中添加一个控件引用关系是这样的(以 UIbutton 为例): UIviewController -> UIview -> UIbutton。此时 UIviewController 强引用着 UIview , UIview 强引用着 UIbutton , IBoutlet 连线到控制器的. m 或者. h 中作为视图的属性时用 weak 修饰就可以了, (觉得用 strong 修饰也可以但是没有必要)。添加到子控件也是强引用: UIbutton 就是添加到了 UIviewController 的 view 上

    3.内存优化举例说几点?

    https://www.jianshu.com/p/8662b2efbb23
    总结下来,主要有下面几方面原因导致内存占用高:
    1.使用了不合理的API
    2.网络下载的图片过大
    3.第三方库的缓存机制
    4.Masonry布局框架
    5.没必要常驻内存的对象,实现为常驻内存
    6.数据模型中冗余的字段
    7.内存泄漏

    • 1.图片相关:

    1.1 图片加载方式有imageNamed和imageWithContentsOfFile;仅使用一次或是使用频率很低的大图片资源,应该使用后者,不会缓存,再没有被引用会清除。

    1.2 在没有必要的情况下,使用了-[UIColor colorWithPatternImage:]这个方法,比如将label的背景色设定为一个图片会用到。这个方法会引用到一个加载到内存中的图片,然后又会在内存中创建出另一个图像,而图像的内存占用是很大的。

    1.3 如果用于显示图片的视图很小,而下载的图片很大,那么我们应该对图片进行缩放处理,然后将缩放后的图片保存到SDWebImage的内存缓存中加载网络数据下载图片时,使用异步加载并缓存

    iOS图片存放的3种方式:https://juejin.im/post/6844903978262773774

    • 2.数据模型相关:

    对于从服务端返回的数据,解析为模型时,随着版本的迭代,可能有一些字段已经不再使用了。如果这样的模型对象会生成很多,那么对于模型中的冗余字段进行清理,也可以节省一定数量的内存占用。

    • 3.内存泄漏:

    内存泄漏会导致应用的内存占用一直升高,需要规范防止循环引用的发生。基于此,在项目中引入ReactiveObjC中的两个牛X的宏,@weakify, @strongify,并遵循以下写法规范:在block外部使用@weakify(self),可以一次定义多个weak引用。
    在block内部的开头使用@strongify(self),可以一次定义多个strong引用。

    • 4.UITableviewCell:(UITableview的卡顿内存优化?)

    4.1 重用单元格,cell的重用, 注册重用标识符

    4.2 避免cell的重新布局(比较耗时)减少视图数目等方式对表格视图进行优化

    4.3通过使用不透明的视图提高渲染速度;不要使用ClearColor,无背景色,透明度也不要设置为0(渲染耗时比较长)

    4.4使用局部更新,尽量避免全局更新

    4.5 尽量不要切圆角操作,耗性能,可以通过贝泽尔曲线绘制

    4.MVVM简要描述

    https://blog.csdn.net/Jimwayne/article/details/103062600
    为了给Controller瘦身,后来又从MVC衍生出了一种新的架构模式MVVM架构。就是把数据请求和事件绑定全部放到viewmodel里面去做的,相当于减少了vc的代码,其他的职能差不多的。MVVM会结合RAC、响应式编程使用。

    • 补充1:RAC

    https://www.jianshu.com/p/92300d42d624
    https://www.jianshu.com/p/d49dd1e58b43
    https://blog.csdn.net/qq_41597968/article/details/79430223

    • 补充2:响应式编程

    https://www.jianshu.com/p/70a4c48f6d14
    https://www.jianshu.com/p/d3363efa5bf5

    5.利用第三方库实现OC与JS的交互(WebViewJavaScriptBridge)

    这个需要和前端配合,要么我们调他们的方法要么他们调我们的。一般的活动页都需要交户,比如按钮点击之后需要调原生方法,比如web获取原生的token。
    https://www.jianshu.com/p/2ceec8235ef6

    • 补充:原生实现OC与JS的交互

    使用原生的WKWebView实现OC与JS的交互
    相关链接:https://xiaozhuanlan.com/topic/1605279438
    https://www.jianshu.com/p/7fe022b072b4
    demo链接:

    6.使用FMDB、SQLite进行数据库的CRUD简单写法

    https://blog.csdn.net/qwertyuiopasdfgg/article/details/89647640
    https://zhuanlan.zhihu.com/p/86879491

    • 查询所有列:
      select * from classes;
      select * from 表名;

    • 查询指定列:
      select id,name from classes;
      select 列1,列2,... from 表名;

    • 增加:
      insert into students values(0,’郭靖‘,1,'蒙古','2016-1-2');
      insert into 表名 values(...)

    • 修改:
      update students set gender=0,hometown='北京' where id=5;
      update 表名 set 列1=值1,列2=值2... where 条件

    • 删除:
      delete from students where id=5;
      delete from 表名 where 条件

    CREATE TABLE IF NOT EXISTS 创建表,
    INSERT INTO插入数据,
    SELECT * FROM查询数据,
    DELETE FROM删除数据。

    • 补充:FMDB的使用中,如果开始创建的表里有2个字断,现在后台返回多一个字断,需要在不创建表的情况下怎么加这个字断?

    7.如何解析XML数据?

    可以用GDataXML(不支持ARC;使用时要混编,ARC和MRC一起)第三方来解析XML数据格式;xml里面数据是标签形式的;也可用KissXML(支持ARC)

    8.UIView动画与Core Animation的区别和选择?

    UIview的动画是对core animation的简单封装;使用简单的动画可以用UIview的动画,更复杂的还是要用core animation去实现才行。

    UIView动画是应用在一个view上面的,实现的动画实时修改对象的属性;
    Core Animation动画是应用在一个layer上面的,它的动画仅仅是表象, 并不会真正修改对象的frame\size等值,通常用在不需要与用户交互的动画(如转场动画/下载进度动画)

    9. 多线程:NSThread、NSOprention和gcd的差别与联系?

    https://www.cnblogs.com/kenshincui/p/3983982.html
    https://www.jianshu.com/p/7649fad15cdb
    https://www.jianshu.com/p/2c5840b96ff1
    补充:https://www.jianshu.com/p/4f3c4cde8177

    • 多线程的三种实现技术怎么选择?

    1.NSThread:基于C语言,比较轻量化,使用简单。缺点是需要程序员自己去操作线程、管理线程的生命周期等,比较麻烦。

    2.NSOperation:
    1.基于OC语言,是面向对象的,不需要程序员管理线程
    2.封装程度没有GCD高,所以相对比较自由;当需要进行自定义线程管理的时候可以使用这个,即需要去操作一些线程的就用这个
    举例:比如一些暂停、重启等线程操作,比如用于自定义一些三方框架等对线程操作

    3.GCD:
    1.基于C语言,提供了强大的函数,API更简洁
    2.以block的形式进行回调,代码更精简,封装性比较强(所以自由性比较弱)
    举例:如果用于一些简单的操作,比如一些同步、单例等可以用这个

    • GCD的一些知识点?
    • 1.两种队列的区别:(有串行队列、并发队列;两者都符合FIFO即先进先出原则)

    1.两者的执行顺序不同,以及开启的线程数不同。
    2.串行是一次只有一个任务被执行;只开启一个线程,一个任务执行完毕后执行下一个任务。
    3.并发是多个任务可以同时执行,可以开启多个线程同时执行任务。(注意:并发队列的并发功能只有在异步函数下才有效)

    • 2.执行任务的方式:同步、异步
      1.dispatch_sync同步函数会发生堵塞;堵塞在同步函数以下的函数,即堵塞在接下来的函数操作(因为FIFO原则,按顺序执行)
    • 3.GCD死锁
      死锁就是线程相互等待造成;通俗的解释:面试官说只要你告诉我死锁就让你进公司,面试者说只要你让我进公司就告诉你死锁。


      死锁
    将主线程放到同步线程会出现死锁 死锁
    • 4.GCD通过信号量控制并发数
      注意:NSoperation可以直接设置并发数,就没有这么麻烦了
    • 5.GCD:2个核心就是任务和队列;在线程池里取出队列,把任务添加放进队列里面进行执行
    • 6.GCD:栅栏
      场景:有时需要异步执行两组操作,而且第一组操作执行完之后,才能开始执行第二组操作;可以通过栅栏实现,也可以通过线程组来实现。

    栅栏实现:这样我们就需要一个相当于栅栏一样的一个方法将两组异步执行的操作组给分割起来,当然这里的操作组里可以包含一个或多个任务,需要用到dispatch_barrier_async方法在两个操作组间形成栅栏

    • 7.使用GCD的时候如何让线程同步?目前就三种(6的栅栏当中就是一种)
      1.dispatch_group(线程组):
      2.dispatch_barrier(栅栏)
      3.dispatch_semaphore(信号量)

    实际应用:在开发中我们需要等待某个网络回调完之后才执行后面的操作,即上面说的同步。具体例子比如做通讯录的时候需要判断权限,才能获取通讯录

    其他问法:如何用GCD同步若干个异步调用?(如根据若干个url异步加载多张图片,然后在都下载完成后合成一张整图)

    • 信号量特别说明(https://www.jianshu.com/p/04ca5470f212
      有三个函数:
      dispatch_semaphore_create 创建一个semaphore;(可以理解成信号总量)
      dispatch_semaphore_signal 发送一个信号;(信号总量+1)
      dispatch_semaphore_wait 等待信号;(当信号总量少于0的时候就会一直等待,否则就可以正常的执行,并让信号总量-1)

    注意:信号量为0则阻塞线程,大于0则不会阻塞。我们通过改变信号量的值,来控制是否阻塞线程,从而达到线程同步。

    // 创建队列组
        dispatch_group_t group = dispatch_group_create();   
    // 创建信号量,并且设置值为10
      dispatch_semaphore_t semaphore = dispatch_semaphore_create(10);   
      dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);   
        for (int i = 0; i < 100; i++)   
        {   // 由于是异步执行的,所以每次循环Block里面的dispatch_semaphore_signal根本还没有执行就会
    执行dispatch_semaphore_wait,从而semaphore-1.当循环10此后,semaphore等于0,则会阻塞线程,直到
    执行了Block的dispatch_semaphore_signal 才会继续执行
    
            dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);   
            dispatch_group_async(group, queue, ^{   
                NSLog(@"%i",i);   
                sleep(2);   
    // 每次发送信号则semaphore会+1,
                dispatch_semaphore_signal(semaphore);   
            });   
        }   
    

    上面的注释已经把如何通过控制信号量来控制线程同步解释的比较浅显了。关键就是这句:
    // 由于是异步执行的,所以每次循环Block里面的dispatch_semaphore_signal根本还没有执行就会执行dispatch_semaphore_wait,从而semaphore-1.当循环10此后,semaphore等于0,则会阻塞线程,直到执行了Block的dispatch_semaphore_signal 才会继续执行

    • 1.NSOperation 实现多线程的使用步骤分为三步:
      1.创建操作:先将需要执行的操作封装到一个 NSOperation 对象中
      2.创建队列:创建 NSOperationQueue 对象
      3.将操作加入到队列中:将 NSOperation 对象添加到 NSOperationQueue 对象中
      之后呢,系统就会自动将 NSOperationQueue 中的 NSOperation 取出来,在新线程中执行操作。
    • 2.相比GCD:
      NSOperation、NSOperationQueue 是基于 GCD 更高一层的封装,完全面向对象;比 GCD 更简单易用、代码可读性也更高。既然是基于 GCD 的更高一层的封装,那么GCD 中的一些概念同样适用于 NSOperation、NSOperationQueue。在 NSOperation、NSOperationQueue 中也有类似的任务(操作)和队列(操作队列)的概念。
    • 3.操作(Operation)
      执行操作的意思,换句话说就是你在线程中执行的那段代码。在 GCD 中是放在 block 中的。在 NSOperation 中,我们使用 NSOperation 子类 NSInvocationOperation、NSBlockOperation,或者自定义子类来封装操作。
    • 4.操作队列(Operation Queues)

    1.注意这里的队列指操作队列,即用来存放操作的队列,不同于 GCD 中的调度队列 FIFO(先进先出)的原则。
    解释:NSOperationQueue 对于添加到队列中的操作,首先进入准备就绪的状态(就绪状态取决于操作之间的依赖关系),然后进入就绪状态的操作的开始执行顺序(非结束执行顺序)由操作之间相对的优先级决定(优先级是操作对象自身的属性)

    2.操作队列通过设置最大并发操作数(maxConcurrentOperationCount)来控制并发、串行

    3.NSOperationQueue 为我们提供了两种不同类型的队列:主队列和自定义队列。主队列运行在主线程之上,而自定义队列在后台执行

    10.容错处理你们一般是注意哪些?

    在团队协作开发当中,由于每个团队成员的水平不一,很难控制代码的质量,保证代码的健壮性,经常会发生由于后台返回异常数据造成app崩溃闪退的情况,为了避免这样的情况项目中做一些容错处理,显得格外重要,极大程度上降低了因为数据容错不到位产生崩溃闪退的概率。例如:1.字典、2.数组、3.野指针、4.NSNull。

    备注:如果项目开始容错处理没做,如何防止拦截潜在的崩溃?(举例)
    1.category给类添加方法用来替换掉原本存在潜在崩溃的方法
    2.利用runtime方法交换技术,将系统方法替换成类添加的新方法
    3.利用异常的捕获来防止程序的崩溃,并且进行相应的处理

    总结:
    1.不要过分相信服务器返回的数据会永远的正确
    2.在对数据处理上,要进行容错处理,进行相应判断之后再处理数据,这是一个良好的编程习惯
    注意:防止野指针(发送消息可能程序奔溃)、防止内存泄露(如循环引用,内存不断增高可能程序奔溃)、空数据处理(后台返回的值为空奔溃,有些后台那边不判断)

    11.Objective-C框架

    12. 说说自己平时定制了哪些UI?

    13.一般开始做一个项目,你的架构是如何思考的?

    进行MVC的架构:
    UI:封装一些基础共用的控件(如何控制性能、减少代码量、提高复用性,避免耦合性)
    业务逻辑:把一些难的或者功能性很大的业务逻辑抽出来写在viewModel里面
    封装网络层和基础框架类
    https://casatwy.com/iosying-yong-jia-gou-tan-wang-luo-ceng-she-ji-fang-an.html

    14.在使用AFNetWorking的时候你是直接用还是二次封装,二次封装你是怎么做的?

    二次封装;
    1.首先创建一个基础类,用于转发AFN的block。将自己所需的基础配置写好,这里可以设计post、get、上传和下载的通用接口,这样在其他地方就可以直接用了。
    2.写一个协议将成功和失败的回调转发出来,然后在实现了协议的地方就可以回调,这样可以把网络操作集中起来。
    3.对于一些特定的网络请求可以调用前面的基础类,实现更高程度的封装

    • 你怎么理解AFNetWorking的的大概实现流程?

    http://blog.cnbang.net/tech/2320/

    15.在你使用的众多第三方库中,你觉得哪个对你来说印象深刻,使用的时候需要注意什么?遇到过什么问题没有,怎么解决?看过哪些源码,讲讲思路(SD、YY、AFN、MJ等)

    SDWebImage的实现原理(给UIImageView加载图片的逻辑;sd_setImageWithURL:placeholderImage:)
    1.先在SDWebImageCache中寻找图片是否有对应的缓存,以url作为数据的索引先从内存(字典)中找图片(当这个图片在本次使用程序的过程中已经被加载过就会缓存下来),找到直接使用。
    2.如果缓存未找到,就会通过MD5处理过的key在磁盘中查询对应的数据,找到了就会把磁盘中的数据加载到内存并将图片显示出来。(即从沙盒中找(当这个图片在之前使用程序的过程中被加载过),找到使用,缓存到内存中)
    3.如果内存和磁盘中都没有找到则向远程服务器请求下载图片,下载后会存到缓存中并写入磁盘。(即从网络上获取使用,缓存到内存,缓存到沙盒)
    注意:整个获取图片的过程都在子线程中执行,获取图片后回到主线程将图片展示出来

    16.UIView 与CALayer

    UIView和CALayer是相互依赖的关系。UIView依赖与calayer提供的内容,CALayer依赖uivew提供的容器来显示绘制的内容。UIView是用来显示内容的,可以响应处理用户事件;CALayer是用来绘制内容的,对内容进行动画处理依赖与UIView来进行显示,不能响应处理用户事件。

    17.HTTPS的加密方式、单双向认证的理解?

    • 几种常用的数据加密方式

    1.常见的数据加密方式有对称加密和非对称加密,还有就是 MD5 的不可逆加密
    2.对称加密常用的有 AES 对称加密,可用于网络请求的内容加密;还有DES
    3.非对称加密常用的有 RSA,还有DSA

    补充1:解释对称加密;如AES 加密和解密效率高,双方必须使用同一个秘钥,如果不考虑秘钥被偷窃,那么AES 是很安全的

    补充2:解释非对称加密;
    概念:如果B只给A传加密数据,那么B需要A给的公钥,B用这个公钥进行加密,A用自己对应的私钥解密即可。

    场景问题:公钥是公开的,大家都可以给A传数据,A都能用自己的私钥解开(因为大家都是用对应且公开的公钥加密的),那么A就不晓得到底哪个才会B发送的,所以就有了签名。签名就是用私钥签名(说白了就是用私钥加密,只有公钥才能解开)。为了让A知道是B发送的,所以B需要给A自己的公钥(这个公钥不是上面说的公钥,而是B提供的另一套公私-钥匙)

    补充3:Base64 只是编码,不是加密;Base64的意思就是:考虑到多语言原因,有的特殊字符传输不兼容,因为很多都是只支持ASSIC码,那么特殊字符就会找不到对应的ASSIC码,所以采用BASE64 可以叫全天下所有字符用 64中字符表示,而且这64种字符都在 ASSIC 中,所以在网络传输中很流行。

    Base64特点:
    1.Base64这个算法是编码,算法可逆,解码方便,不用于私密信息通信;
    2.虽然解码方便,但毕竟编码了,肉眼还是不能直接看出原始内容;
    3.加密后的字符串只有[0-9a-zA-Z+/=],不可打印字符(包括转移字符)也可传输。

    • HTTPS的加密

    HTTPS 中的加密过程用到了非对称加密进行密钥的传递,然后再用对称加密就行数据传输。非对称加密是很耗时的一种加密方式,但是比较安全,对称相对没有那么安全,但是效率高。所以兼顾安全与效率,采用了两者结合。
    1.服务器端的公钥和私钥,用来进行:非对称加密
    2.客户端生成的随机密钥,用来进行:对称加密,HTTPS的对称加密就是加密的实际的数据

    小结:
    1.对称加密的意思是,大家拿到一样的秘钥进行加密解密。非对称加密的意思是,需要公钥和私钥才能进行加解密。
    2.非对称加密可以理解成开始的时候是非对称加密获取对称加密的秘钥。然后拿到对称加密的秘钥之后,再用这个秘钥进行对称加密。因为非对称加密需要的时间更长,长时间的交互数据是不可取的。所以非对称加密只是在一开始拿到对称加密的秘钥用到了,后续的数据交互还是用到了更快捷的对称加密。
    3.单向和双向的区别在于,单向的服务器端是不会验证客户端的,并且在给服务器的加密方式也是没有加密的。

    图解:

    单向认证 双向认证

    补充1:APP 的安全性主要采用的 HTTPS 双向认证,通过 AFNetworking 的 AFSecurityPolicy 类实现对通道的双向验证,达到对数据交互的安全加 密,之前是采用的 RSA 非对称加密,直接采用的内容加密。(你们项目为什么会用双向认证,你们的证书放到哪的?)

    https://blog.csdn.net/superviser3000/article/details/80812263
    当时是做贷款的APP,最开始是用的内容加密,因为用的非对称加密,比较的慢,所以才换成了https双向认证;证书是放到服务器的。AFNetworking 的 AFSecurityPolicy 类实现对通道的双向验证这个你就说,放在封装好的几个回调里面,具体的方法名字忘记了

    补充2:通过 NSURLProtocol 拦截前端的网络请求,然后通过 HTTPS 双向认证进行加密,这个怎么理解啊?

    NSURLProtocol 拦截前端的网络请求这个类的用法就是,先注册然后再方法里面筛选你想拦截的请求。

    18.runtime的理解

    注意:oc的动态性全都是runtime支持的。oc类的类型和数据变量的类型都是在运行时确定的,而不是在编译时确定。运行时(runtime)特性,我们可以动态的添加方法,或者替换方法。
    快速上手runtime:https://www.jianshu.com/p/e071206103a4
    runtime 系统的知识:http://yulingtianxia.com/blog/2014/11/05/objective-c-runtime/

    • 1.weak释放nil的过程

    Runtime会对weak属性进行内存布局,构建hash表:以weak属性对象内存地址为key,weak属性值(weak自身地址)为value。当对象引用计数为0 dealloc时,会将weak属性值自动置nil。(Hash表你理解成字典就行)

    • 2.iOS消息转发机制原理?(Runtime相关)

    https://www.jianshu.com/p/45db86af7b60

    基本分为三个步骤:1.动态方法解析 2.备用接受者 3.完整转发

    • 动态方法解析
      对象在接收到未知的消息时,首先会调用所属类的类方法+resolveInstanceMethod:(实例方法)或者+resolveClassMethod:(类方法)进行判断。如果YES则能接受消息,NO不能接受消息,进入第二步

    • 备用接受者
      动态方法解析无法处理消息,则会走备用接受者。这个备用接受者只能是一个新的对象,不能是self本身,否则就会出现无限循环。如果我们没有指定相应的对象来处理aSelector,则应该调用父类的实现来返回结果

    • 完整消息转发
      如果第2步返回self或者nil,则说明没有可以响应的目标,则进入第三步走完整消息转发

    • 3.runtime的实际应用举例

    例子1:友盟统计埋点时候交换系统方法
    友盟的方法照着文档写就可以;runtime那个就是交换系统的方法达到无侵入的埋点。主要看要交换的方法,比如最常见的vc的那几个周期方法。无侵入的意思就是不要到处都去写。

    例子2:修改重写KVC的undefinedKey方法
    KVC键值对的时候key找不到vaue的时候就会调用undefinedKey方法,就无法字典转模型,这个时候可以利用runtime修改重写这个undefinedKey方法解决奔溃,就可以继续使用KVC进行字典转模型来使用。

    19.什么时候会报unrecognized selector的异常?(考iOS消息转发机制-runtime)

    1.对象未实现该方法;2.对象已经被释放
    比如当调用对象的某个方法时,该对象未实现此方法,就会出现这种情况。

    iOS有哪些机制来避免走到这一步?看下图
    (objc是动态语言,每个方法在运行时会被动态转为消息发送,即:objc_msgSend(receiver, selector))
    https://www.jianshu.com/p/c7dedcd0b662
    https://www.jianshu.com/p/fdd8f5225f0c

    runtime的消息机制可以避免走到这一步

    20.BAD_ACCESS在什么情况下出现?

    1.访问了野指针的时候,比如一个已经释放的对象执行了release、访问已经释放对象的成员变量或者发消息。
    2.死循环的时候也会。

    21.runLoop的理解:在下拉刷新表格时如何让上面的轮播图也继续自动轮播

    主线程的 RunLoop 里有两个预置的 Mode:kCFRunLoopDefaultMode 和 UITrackingRunLoopMode。这两个 Mode 都已经被标记为"Common"属性,DefaultMode 是 App 平时所处的状态,TrackingRunLoopMode 是追踪 ScrollView 滑动时的状态。当你创建一个 Timer 并加到 DefaultMode 时,Timer 会得到重复回调,但此时滑动一个TableView时,RunLoop 会将 mode 切换为 TrackingRunLoopMode,这时 Timer 就不会被回调,不会影响到滑动操作(滑动时定时器不工作了)。如果想让定时器继续工作,就切换Mode,也就是滑动与不滑动取决于你timer的runloop的mode是什么模式的(kCFRunLoopDefaultMode::App的默认 Mode,通常主线程是在这个 Mode 下运行的;)
    https://www.jianshu.com/p/2ca582f14100

    • 补充1:runloop和线程有什么关系?

    https://www.cnblogs.com/huangzs/p/7574260.html
    https://www.jianshu.com/p/71d8bc0e2497

    • 补充2:runloop的mode作用是什么?

    https://www.jianshu.com/p/730adaa296f4
    https://www.cnblogs.com/haotianToch/p/6442860.html

    22.事件传递与响应

    传递:UIApplication -> keywindow -> 父视图 -> 子视图 ->递归查找
    响应(响应链):子视图 -> 父视图 ->keywindow -> UIApplication -> 丢弃

    23.内存中的栈和堆的区别是什么?那些数据在栈上,哪些在堆上?

    1.栈由编译器自动分配,是一块连续的内存区域,在运行的时候就确定了大小;堆由程序员管理控制,是不连续的内存区域
    2.栈存放基本数据类型、形式参数、局部变量(在方法和语句块内部定义的变量:当方法和语句块一结束,空间马上释放),速度快;
    堆存放的是成员变量(也叫属性,在方法外,在类里,定义的变量):随着对象而产生,随对象销毁而销毁

    • 优缺点:

    1.栈数据可以共享,优点速度快(所以用来执行程序);缺点是:栈的数据大小与生存期必须是确定的,缺乏灵活性
    2.堆优点:可以动态地分配内存大小(可动态扩张或缩减,内存可以随时在堆中分配和销毁),生存期也不必事先告诉编译器;缺点是:由于要在运行时动态分配内存,存取速度较慢

    • 备注:

    栈内存分配原则:先进后出(相当于水杯单向)
    队列内存分配原则:先进先出(相当于火车站买票,双向出口)

    栈与堆的比较

    24. #define和const定义的变量,有什么区别?

    1.define是宏定义,程序在预处理阶段将用define定义的内容进行了替换。因此程序运行时,常量表中并没有用define定义的常量,系统不为它分配内存;
    const定义的常量,在程序运行时在常量表中,系统为它分配内存;const 定义不可变的变量,只能访问不能修改

    2.define定义的常量,预处理时只是直接进行了替换,所以编译时不能进行数据类型检验;
    const定义的常量,在编译时进行严格的类型检验,可以避免出错

    25.block在内存管理上的特点、需要注意循环引⽤,如何解决循环引⽤?

    • block在内存管理上的特点

    https://zhidao.baidu.com/question/555374149788762652.html

    • 在block内如何修改block外部变量?

    https://www.jianshu.com/p/a1c8532e172d

    • 使用block时什么情况会发生引用循环,如何解决?

    一个对象中强引用了block,在block中又强引用了该对象,就会产生循环引用。
    解决方法是将该对象使用__weak或者__block修饰符修饰之后再在block中使用。
    id weak weakSelf = self; 或者 weak __typeof(&*self)weakSelf = self该方法可以设置宏。id __block weakSelf = self;或者将其中一方强制制空xxx = nil。
    检测代码中是否存在循环引用问题,可使用 Facebook 开源的一个检测工具FBRetainCycleDetector

    • 代理和block怎么选择使用?

    26.block与__block与__weak与__storng这些啥关系、用法

    __block是修饰在block中需要改变的变量,一般的变量就是放在栈上面的,__block相当于将变量从栈拷贝到堆上面。如果不声明的话,编译器会报错的。__weak是将修饰的对象弱引用,一般用在循环引用的时候。破坏掉循环的闭环。__storong是在__weak使用之后在block里面对weak修饰的对象进行一个强引用,这个强引用是防止在block里面被提前释放,但是并不会引发循环引用。

    27.单例举例

    用户的个人信息登陆后用nsuserdefaults 存储,对登录类进一步采用单例封装方便全局访问、应用的配置信息。系统为我们提供的单例类有:UIApplication(应用程序实例类)、NSNotificationCenter(消息中心类)、NSUserDefaults(应用程序设置)等等

    单例代码的写法

    28.下面代码输出什么?

    https://www.cnblogs.com/zxykit/p/5421181.html

    29.你在项目中遇到过什么问题没有?

    这是面试官很喜欢问的一个问题,也是会刁难你的一个地方。如果你在项目中是核心解决了一些技术难题,那这个问题对你来说应该是很好回答的,你可以说出这个项目遇到的技术问题,以及你是怎么解决的。

    • 思路:这种问题往往可以从并发,稳定性,容错,性能等方面入手。可以给出一个场景,自己设计一种可行的解决方案,予以阐述。
      https://www.jianshu.com/p/59d12b3b94f3

    30.地图的使用?

    • 地图怎么解决定位偏差问题?

    1.苹果原生地图使用地球坐标,除了中国全球通用(国外不用转换);在中国其使用高德的数据所以要将其转换为火星坐标才能使用不出偏差
    2.高德地图使用的火星坐标,已经封装好了,取得就是火星坐标,不用转直接用
    3.百度地图使用的是百度坐标,是将火星坐标进行处理;同理也已经封装好了,不用转直接用

    1.司机端:首先司机出发的时候,即点击导航的时候,代表去接客,这时候往乘客端发送一条出发的信息。然后高德地图会有开始导航的接口,也有位置改变的接口,所以在这个接口里面将对应的消息发给乘客就行。

    乘客端:乘客端的地图界面,即主界面需要实现一个信息接收的监听接口

    • 地图轨迹的开发

    可以使用百度地图的鹰眼

    • 百度地图后台切换出现黑屏

    当app切换到后台再切换回前台,mapView可能会产生黑屏的情况,此时只需在AppDelegate.m中的applicationWillResignActive:(UIApplication *)application和applicationDidBecomeActive:(UIApplication *)application添加如下代码:

    - (void)applicationWillResignActive:(UIApplication *)application {
        //程序将要进入后台
        [BMKMapView willBackGround];
    }
    - (void)applicationDidBecomeActive:(UIApplication *)application {
        //程序进入前台
        [BMKMapView didForeGround];
    }
    
    

    31.即时通讯怎么实现的?(环线、融云)

    1.通过CoCoaPod下载环信的SDK进行集成
    2.在环信的官网后台进行相关应用的创建、配置,获取通信的一些基本信息,比如token、key之类
    3.根据官方文档及App需求在App中进行注册、相关方法的调用;以及推送证书的配置(开发与测试环境)

    32.iOS开发过程

    iOS个人开发

    33.值得看的文章

    iOS面试知识总结之文章收录:http://www.cocoachina.com/ios/20180315/22624.html
    iOS经典面试题汇总:https://www.jianshu.com/p/2ca582f14100
    知识点面试集:https://www.jianshu.com/p/0d4d8a79fd97
    iOS系统13新特性:https://www.jianshu.com/p/2036e821e912
    提醒:https://www.jianshu.com/p/e2a4b0ab958a

    相关文章

      网友评论

          本文标题:面试复习笔记

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