2019高级面试知识篇

2019-06-13  本文已影响0人  暖心幽瞳

前言:经过一个星期的面试、总结下这几天面试遇到的问题以及做一次归纳总结、以便日后复习、也便于大家学习和鉴别指正。如有不对请指出一起学习。

Define和Const的区别?

A: Define 不能调试,Const 常量可以调试.

B: Define 在预处理阶段进行替换,Const 常量在编译阶段使用.

C: Define 定义的常量在替换后运行过程中会不断地占用内存,而 Const 定义的常量存储在数据段只有一份 Copy,效率更高。

Static的作用?

A : static修饰的函数是一个内部函数,只能在本文件中调用,其他文件不能调用

B:  static修饰的全部变量是一个内部变量,只能在本文件中使用,其他文件不能使用

C:  static修饰的局部变量只会初始化一次,并且在程序退出时才会回收内存

Socket的粘包是如何处理的? 一般有2种方法。

注意和服务器确定数据头的定义格式问题,

第一种就是服务器返回的字段中有可识别的头和尾,我们可以根据可识别的头和尾来拆包。

第二种是服务器返回的数据只包含头,头里面有数据的长度,我们可以根据这个头包含的数据长度来进行拆包。本文采用的便是第二种方案。

NSArray与NSMutableArray用Copy修饰还是Strong?

一:NSMutableArray 被copy、strong修饰后的变化:

使用Copy:

把NSMutbleArray使用Copy修饰时有时候回产生Crash,因为对这个数组进行了增删改操作,而copy后的数组变成了不可变数组NSArray,没有响应的增删改方法,所以对其进行增删改操作就会报错。

使用Strong:

如果是strong,直接是赋值a = b;右边是什么,左边就是什么,并且是强引用新值,左边的类型会与右边的相同,不会改变。

二、NSArray 被copy、strong修饰后的变化:

使用Strong:

被strong修饰之后,由于只是强引用,所以副本对象数组和源对象数组只是指向同一个内存区域,这样就会造成副本对象数组会随着源对象数组的改变而改变,即便有时候你并不想让副本对象跟着改变。

使用Copy:

 被copy修饰之后,源对象数组被copy了一份,源对象数组和副本对象数组是不同的,所以副本对象数组并不会随着源对象数组改变。

听听大神怎说:iOS内存管理NSArray与NSMutableArray用copy修饰还是strong

Runtime底层实现、有几个指针

可听听大神怎么说的:Runtime详细解说

有3个指针、分别是 isa、IMP、SEL

什么情况下回导致离屏渲染性能问题并且如何处理?

重写drawRect方法,设置圆角、阴影、模糊效果,光栅化都会导致离屏渲染。

设置阴影效果是加上阴影路径。

滑动时若需要圆角效果,开启光栅化。

如何处理如下

一:设置UIView、UITextField、UITextView等大部分控件设置圆角及背景颜色的时候该考虑一下设置方式

     通过layer的方式设置 label.layer.cornerRadius =10.f;

     通过layer的方式设置 label.layer.backgroundColor = [UIColorwhiteColor].CGColor;

二:对于UIButton、UIIMageView使用DrawInRect绘制UIImage圆角,参考代码

UIBezierPath*bezierPath = [UIBezierPathbezierPathWithRoundedRect:rect cornerRadius:cornerRadius];UIGraphicsBeginImageContextWithOptions(rect.size,false, [UIScreenmainScreen].scale);CGContextAddPath(UIGraphicsGetCurrentContext(), bezierPath.CGPath);CGContextClip(UIGraphicsGetCurrentContext());[selfdrawInRect:rect];CGContextDrawPath(UIGraphicsGetCurrentContext(), kCGPathFillStroke);UIImage*image =UIGraphicsGetImageFromCurrentImageContext();UIGraphicsEndImageContext();

iOS中的方法Methond执行过程?

1:根据对象的isa指针找到类对象id,在查询类对象里面的methodLists方法函数列表查找,如果没有,

2:在沿着superClass,寻找父类,再在父类methodLists方法列表里面查询,最终找到SEL,根据id和SEL确认IMP(指针函数),在发送消息;

iOS浅拷贝、深拷贝的意义和区别?

1、浅拷贝

     浅拷贝就是对内存地址的复制,让目标对象指针和源对象指向同一片内存空间,当内存销毁的时候,指向这片内存的几个指针需要重新定义才可以使用,要不然会成为野指针。

计数器是这样的: 浅拷贝就是拷贝指向原来对象的指针,使原对象的引用计数+1,可以理解为创建了一个指向原对象的新指针而已,并没有创建一个全新的对象。

2、深拷贝

      深拷贝是指拷贝对象的具体内容,而内存地址是自主分配的,拷贝结束之后,两个对象虽然存的值是相同的,但是内存地址不一样,两个对象也互不影响,互不干涉。

计数器是这样的:深拷贝就是拷贝出和原来仅仅是值一样,使原对象的引用计数保存原理一致,但是内存地址完全不一样的新的对象,创建后和原对象没有任何关系。

3、总结:

深拷贝就是内容拷贝,浅拷贝就是指针拷贝。本质区别在于:

是否开启新的内存地址

是否影响内存地址的引用计数

介绍下iOS网络HTTP、TCP、UDP、Socket 的知识

短连接和长链接的概念及使用场景

短连接

连接 -> 传输数据->关闭连接。就建立一次,但任务结束就中断连接,安全性高。

使用场景:WEB网站的http服务一般都用短链接。

长连接

连接 -> 传输数据 -> 保持连接 -> 传输数据。。。-> 关闭连接。是指连接后不管是否使用都保持连接,但安全性较差。

使用场景:长连接多用于操作频繁,点对点的通讯,而且连接数不能太多的情况下。

如何断开长连接:

1:设置timeout=20网络异常时间,表示这个TCP通道可以保持20秒。

2:设置最大请求数量max=XXX,表示这个长连接最多接收XXX次请求就断开。

3:服务端可能主动发起四次握手断开TCP连接,客户端能够知道该TCP连接已经无效;

4:发送心跳包来检测当前连接是否还活着来断开连接

HTTP:http协议即超文本传送协议,是web联网的基础,也是手机联网常用协议之一,http协议是建立在tcp协议之上的一种应用。

http连接最显著的特点是客户端发送的每次请求都需要服务器回送响应,在请求结束后,会主动释放连接。从建立连接到关闭连接的过程称为“一次连接”。

1:在HTTP 1.0中,客户端的每次请求都要求建立一次单独的连接,在处理完本次请求后,就自动释放连接。

2:在HTTP 1.1中则可以在一次连接中处理多个请求,并且多个请求可以重叠进行,不需要等待一个请求结束后再发送下一个请求。

Socket:套接字(socket)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元。建立Socket链接需要客服端(ClientSocket)和服务端(ServerSocket)组合才能建立完成。

Socket的连接过程分为三个步骤:服务器监听,客户端请求,连接确认。

服务器监听:服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态,等待客户端的连接请求。

客户端请求:指客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。

连接确认:当服务器端套接字监听到或者说接收到客户端套接字的连接请求时,就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端,一旦客户端确认了此描述,双方就正式建立连接。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。

TCP与UDP的区别

TCP:面向连接、传输可靠(保证数据正确性,保证数据顺序)、用于传输大量数据(流模式)、速度慢,建立连接需要开销较多(时间,系统资源)。

UDP:面向非连接、传输不可靠、用于传输少量数据(数据包模式)、速度快。

TCP三次握手:指建立一个TCP连接时,需要客户端和服务器总共发送3个包。

第一次握手:客户端发送一个TCP的SYN标志位置1的包指明客户打算连接的服务器的端口,以及初始序号X,保存在包头的序列号(Sequence Number)字段里。

第二次握手:服务器发回确认包(ACK)应答。即SYN标志位和ACK标志位均为1同时,将确认序号(Acknowledgement Number)设置为客户的序列号加1以,即X+1。

第三次握手:客户端再次发送确认包(ACK) SYN标志位为0,ACK标志位为1。并且把服务器发来ACK的序号字段+1,放在确定字段中发送给对方.并且在数据段放写序列号的+1。

如何选中TCP还是UDP?

如果是由客户端间歇性的发起无状态的查询,并且偶尔发生延迟是可以容忍,那么使用HTTP/HTTPS。

如果客户端和服务器都可以独立发包,但是偶尔发生延迟可以容忍(比如:在线的纸牌游戏,许多MMO类的游戏),那么使用TCP长连接。

如果客户端和服务器都可以独立发包,而且无法忍受延迟(比如:大多数的多人动作类游戏,一些MMO类游戏),那么使用UDP。

iOS中对象有哪些类型 4种

1:OBJC_ASSOCIATION_ASSIGN = 0,     

2:OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1,

3:OBJC_ASSOCIATION_COPY_NONATOMIC = 3,

4:OBJC_ASSOCIATION_COPY = 01403

KVC 和 KVO 的内部实现

KVC内部实现:

1.判断有没有指定key的set方法,如果有set方法,就会调用set方法,给该属性赋值

 2.如果没有set方法,判断有没有跟key值相同且带有下划线的成员属性(_key).如果有,直接给该成员属性进行赋值

 3.如果没有成员属性_key,判断有没有跟key相同名称的属性.如果有,直接给该属性进行赋值

 4.如果都没有,就会调用 valueforUndefinedKey 和setValue:forUndefinedKey:方法

KVC的使用场景

1.动态的取值和设值

2.用KVC来访问和修改私有变量

3.Model和字典转换

4.修改一些控件的内部属性

KVO内部实现:

当某个类的对象在第一次被观察时,系统会在运行时动态创建一个该类的派生类,在该派生类中重写setter方法真正实现通知机制;派生类重写了 class 方法以“欺骗”外部调用者它就是起初的那个类。然后系统将这个对象的isa指针指向这个新诞生的派生类,因此这个对象就成为该派生类的对象了,因而在该对象上对setter的调用就会调用重写的setter,从而激活键值通知机制。此外,派生类还重写了dealloc方法来释放资源。

KVO的使用场景

1:KVO用于监听对象属性的改变。

2:下拉刷新、下拉加载监听UIScrollView的contentoffsize;

3:webview混排监听contentsize;

4:监听模型属性实时更新UI;

5:监听控制器frame改变,实现抽屉效果。

iOS有几种设计模式,每一种设计模式是怎么样的?说一说?

1). MVC模式:Model View Control,把模型 视图 控制器 层进行解耦合编写。

2). MVVM模式:Model View ViewModel 把模型 视图 业务逻辑 层进行解耦和编写。

3). 单例模式:通过static关键词,声明全局变量。在整个进程运行期间只会被赋值一次。

4). 观察者模式:KVO是典型的通知模式,观察某个属性的状态,状态发生变化时通知观察者。

5). 委托模式:代理+协议的组合。实现1对1的反向传值操作。

6). 工厂模式:通过一个类方法,批量的根据已有模板生产对象。

介绍下ViewController生命周期

1.initWithCoder:通过nib文件初始化时触发。

2.awakeFromNib:nib文件被加载的时候,会发生一个awakeFromNib的消息到nib文件中的每个对象。

3.loadView:开始加载视图控制器自带的view。

4.viewDidLoad:视图控制器的view被加载完成。

5.viewWillAppear:视图控制器的view将要显示在window上。

6.updateViewConstraints:视图控制器的view开始更新AutoLayout约束。

7.viewWillLayoutSubviews:视图控制器的view将要更新内容视图的位置。

8.viewDidLayoutSubviews:视图控制器的view已经更新视图的位置。

9.viewDidAppear:视图控制器的view已经展示到window上。

10.viewWillDisappear:视图控制器的view将要从window上消失。

11.viewDidDisappear:视图控制器的view已经从window上消失。

看看其他大神的面试总结 iOS面试题及答案

上一篇下一篇

猜你喜欢

热点阅读