面试题

容易出错的面试题

2019-03-14  本文已影响0人  sy随缘

本文的相关题目,都是查阅网上资料,如有疑问,欢迎讨论!

1、如果页面 A 跳转到 页面 B,A 的 viewDidDisappear 方法和 B 的 viewDidAppear 方法哪个先调用?

参考文章:iOS 转场时 appear 与 disappear 的调用顺序探索

  1. push


    image.png

2)系统present


image.png

3)自定义present


image.png

4)tabbar切换


image.png

2、HTTP协议中 POST方法和 GET方法有那些区别?

如果我告诉你GET和POST本质上没有区别你信吗?
让我们扒下GET和POST的外衣,坦诚相见吧!
GET和POST是什么?HTTP协议中的两种发送请求的方法。
HTTP是什么?HTTP是基于TCP/IP的关于数据如何在万维网中如何通信的协议。
HTTP的底层是TCP/IP。所以GET和POST的底层也是TCP/IP,也就是说,GET/POST都是TCP链接。GET和POST能做的事情是一样一样的。你要给GET加上request body,给POST带上url参数,技术上是完全行的通的。
HTTP只是个行为准则,而TCP才是GET和POST怎么实现的基本
GET和POST本质上就是TCP链接,并无差别。但是由于HTTP的规定和浏览器/服务器的限制,导致他们在应用过程中体现出一些不同
GET和POST还有一个重大区别
简单的说:
GET产生一个TCP数据包;POST产生两个TCP数据包。
长的说:
对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);
而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。
注意 :并不是所有浏览器都会在POST中发送两次包,Firefox就只发送一次。

3、delegate、notification、KVO各优缺点

4、 Runtime

5、weak是怎么实现的?

runtime维护了一个weak表,用于存储指向某个对象的所有weak指针。weak表其实就是一个hash(哈希)表,key是所指对象的地址,value是weak指针的地址(这个地址的值是所指对象指针的地址)数组。
初始化时:runtime会调用objc_initWeak函数,初始化一个新的weak指针指向对象的地址
添加引用时:objc_initWeak函数会调用storeWeak()函数【它的作用是更新指针指向,创建对应的弱引用表】
释放时:调用clearDeallocating函数,该函数首先根据对象地址,获取所有weak指针地址的数组,然后遍历这个数组,把其中的数据设为nil,最后把这个entry从weak表中删除,最后清理对象的记录。

6、copy、mutablecopy

iOS copy和mutableCopy
iOS copy和mutableCopy 整理

7、自定义一个通知如何实现?

iOS Notification实现原理

8、为什么assign不能用于修饰对象?

assign不能用于修饰对象

9、常用循环引用

常用循环引用
NSTimer循环引用分析,解决
解决NSTimer的循环引用
NSTimer定时器进阶——详细介绍,循环引用分析与解决
NSTimer循环引用解决方案

image.png

NSTimer:循环引用的原因

invalidate方法有2个功能:
一是将timer从runloop中移除,那么图中的L4就消失,
二是timer本身也会释放它持有资源,比如target、userinfo、block
invalidate方法调用必须在timer添加到的runloop所在的线程,如果不在的话:虽然timer本身会释放掉它自己持有的资源比如target、userinfo、block,图中的L3会消失。但是runloop不会释放timer,即图中的L4不会消失,假设,self被pop了-->L1无效-->self引用计数为0,self释放-->L2也消失。此时就剩runloop、timer、L4,timer也就永远不会释放了,造成内存泄露。

10、用weak来修饰block时,会发生什么?

iOS当用weak来修饰block时,会发生什么?

11、主线程主队列执行同步操作卡死原因?

GCD主线程上同步执行主队列方法卡死的解释

image.png

12、KVO底层实现分析

KVO底层实现分析

13、block有⼏种类型?block底层实际上是什么?block使⽤时的注意事项?

Block技巧与底层解析【讲的很不错】
Block由浅入深(5):三种类型的Block
Objective-C中block的底层原理

14、事件传递与响应链

iOS触摸点击事件之runloop做了什么?

15、串行队列、并行队列、主队列、全局队列、同步和异步

IOS 主队列,全局队列的关系

  1. 主队列:专门负责调度主线程度的任务,没有办法开辟新的线程。所以,在主队列下的任务不管是异步任务还是同步任务都不会开辟线程,任务只会在主线程顺序执行。
  2. 主队列异步任务:现将任务放在主队列中,但是不是马上执行,等到主队列中的其它所有除我们使用代码添加到主队列的任务的任务都执行完毕之后才会执行我们使用代码添加的任务。
  3. 主队列同步任务:容易阻塞主线程,所以不要这样写。原因:我们自己代码任务需要马上执行,但是主线程正在执行代码任务的方法体,因此代码任务就必须等待,而主线程又在等待代码任务的完成好去完成下面的任务,因此就形成了相互等待。整个主线程就被阻塞了。

全局队列和并发队列的区别:
1,全局队列没有名字,但是并发队列有名字。有名字可以便于查看系统日志
2,全局队列是所有应用程序共享的。
3,在mrc的时候,全局队列不用手动释放,但是并发队列需要。

GCD功能解决--栅栏(barrier):

//如果传入自己创建的并行队列时,会阻塞当前队列执行,而不阻塞当前线程。
void dispatch_barrier_async(dispatch_queue_t queue, dispatch_block_t block);
//如果传入自己创建的并行队列时,阻塞当前队列的同时也会阻塞当前线程
void dispatch_barrier_sync(dispatch_queue_t queue, dispatch_block_t block);

并发队列如果发现接下来要处理的块是个栅栏块,那么就一直要等当前所有并发块都执行完毕,才会单独执行这个栅栏块。这待栅栏块执行完毕,在按正常方式继续向下处理。这样就解决了并发队列的同步问题。

16、分类为什么不能添加属性?协议的属性呢?

探究iOS分类为什么不能直接添加属性
OC-category 为什么不能添加成员变量
iOS Category实现原理

objc_category中少了 struct objc_ivar_list * _Nullable ivars也就是说没有ivar数组.

分类(category), 并不会改变原有类的内存分布的情况,它是在运行期间决定的,category是无法添加实例变量的【此时内存的分布已经确定,若此时再添加实例会改变内存的分布情况,这对编译性语言是灾难,是不允许的。】

扩展(extension), 作用是为一个已知的类添加一些私有的信息,必须有这个类的源码,才能扩展,它是在编译器生效的,所以能直接为类添加属性或者实例变量。
扩展就是类的一部分,在编译期和头文件里的@interface以及实现文件里的@implement一起形成一个完整的类,它伴随类的产生而产生,亦随之一起消亡。

protocol是一系列的协议,要求代理去实现,自己并没有实现,方法或属性都是这样,只是做了声明要求代理去实现。所以添加的属性也只是声明其代理有实现这个属性,自身并没有实现其getter、setter以及ivar。有兴趣的朋友可以实践看看。

17、网络:三次握手、四次挥手及面试题

TCP的三次握手与四次挥手理解及面试题(很全面)

18、block

18.1 block为啥可以修改全局变量而局部变量修改需要加__blcok?

block可以修改全局变量,是因为全局变量放在堆区,局部变量在栈区,所以不能修改,加上__block之后,相当于加了个标识位,遇到__block就把内存由栈区放在堆区。

19、类、对象、成员变量等的内存布局

OC类与对象的内存模型以及方法和成员变量的访问原理

20、如何解决NSTimer的循环引用问题

如何解决NSTimer的循环引用问题

21、编码规范相关

代码篇

22、@property相关

IBOutlet属性应该用Strong还是Weak来修饰?

上一篇下一篇

猜你喜欢

热点阅读