收集一些面试题,一边复习回顾,一边供日后查看.
1.面向对象都有哪些特征? 以及你对这些特征的理解?
- 封装
- 封装是把数据和操作数据的方法绑定起来,对数据的访问只能通过已定义的接口.
- 我们在类中编写的方法是对实现细节的一种封装;
- 我们编写一个类就是对数据和数据操作的封装.
- 可以说,
封装就是隐藏一切可以隐藏的东西,只向外界提供最简单的编程接口
- 继承
- 继承是
从已有类得到继承信息创建新类的过程
. - 提供继承信息的类被称为父类(超类,基类);
- 得到继承信息的类被称为子类(派生类).
- 继承让变化中的软件系统有了一定的延续性,同时继承也是封装程序中可变因素的重要手段.
- 继承是
- 多态
- 多态性指允许不同子类型的对象对同一消息做出不同的响应.简单的说就是用
同样的对象引用调用同样的方法但是做了不同的事情
. - 多态性分为
编译时
的多态性和运行时
的多态性. - 而方法重写(override)实现的是运行时的多态性(也称为后绑定).
- 运行时的多态是面向对象
最精髓
的东西,要实现多态需要做两件事:- 1是方法重写(子类继承父类并重写父类中已有的或抽象的方法)
- 2是对象造型(用父类型引用子类型对象,这样同样的引用调用同样的方法就会根据子类对象的不同而表现出不同的行为)
- 多态性指允许不同子类型的对象对同一消息做出不同的响应.简单的说就是用
- 抽象
- 抽象是
将一类对象的共同特征总结出来构造类的过程
,包括数据抽象和行为抽象两方面. - 抽象
只关注对象有哪些属性和行为
,并不关注这些行为的细节是什么
- 抽象是
2.简述NotificationCenter | KVC | KVO | Delegate? 并说明它们之间的区别?
- KVO
- 全称 : Key- Value-Observing
-
一对多
,观察者模式,键值观察机制 - 它提供了
观察某一属性变化
的方法,极大的简化了代码
- KVC
- 全称 : Key-Value-Coding
- 键值编码,一个对象在调用setValue的时候
- 首先检查是否存在相应key的set方法,存在就调用set方法
- set方法不存在,就查找_key的成员变量是否存在,存在就直接赋值
- 如果_key没找到,就查找相同名称的key,存在就赋值
- 如果没有就调用valueForUndefinedKey和setValue: forUndefinedKey.
- Delegate
- 通常发送者和接收者的关系是直接的
一对一
的关系. - 代理的目的是改变或传递控制链.允许一个类在某些特定时刻通知到其他类,而不需要获取到那些类的指针.
- 可以减少框架复杂度.消息的发送者告知接收者某个事件将要发生,delegate同意然后发送者响应事件,
delegate机制使得接收者可以改变发送者的行为
.
- 通常发送者和接收者的关系是直接的
- Notification
- 观察者模式,通常发送者和接收者的关系是间接的
多对多
关系.消息的发送者告知接收者事件已经发生或者将要发送,仅此而已,接收者并不能反过来影响发送者的行为
.
- 观察者模式,通常发送者和接收者的关系是间接的
- 区别
-
效率
: delegate比NSNotification 高 - delegate方法比Notification更加直接,需要关注返回值,所以delegate方法往往包含
should
这个很传神的词.相反,Notification最大的特色就是不关心结果.所以Notification往往用did这个词汇 - 两个模块之间联系不是很紧密,就用Notification传值,如多线程之间传值用Notification
- delegate只是一种较为简单的回调,且主要用在一个模块中,如底层功能完成了,需要把一些值传到上层去,就事先把上层的函数通过delegate传到底层,然后在底层call这个delegate,它们都在一个模块中,完成一个功能,如说NavigationController从B界面到A点返回按钮(调用popViewController方法)可以用delegate比较好.
-
3.什么是懒加载?
- 就是在用到的时候才去初始化.
- 也可以理解成延时加载.
- 我觉得最好也最简单的一个例子就是tableView中图片的加载显示了,一个延时加载,避免内存过高,一个异步加载,避免线程堵塞提高用户体验.
4.OC有多继承吗? 没有的话可以用什么方法替代?
- 多继承就是一个子类可以有多个父类,它继承了多个父类的特性.
- OC的类没有多继承,只支持单继承,如果要实现多继承的话,可以通过类别和协议的方式来实现.
- protocol(协议)可以实现多个接口,通过实现多个接口可以完成多继承.
- Category(类别)一般使用分类,用Category去重写类的方法,仅对本Category有效,不会影响到其他类与原有类的关系.
5.分别描述类别(categories)和延展(extensions)是什么?区别?继承和类别在实现中有什么区别?为什么Category只能为对象添加方法,却不能添加成员变量?
-
类别
: 在原类.m文件的基础上,给该类添加方法. -
延展
: 一种特殊形式的类别,主要在一个类的.m文件里声明和实现延展的作用,就是给某类添加私有方法或私有变量. - 区别:
- 延展可以添加属性并且它添加的方法是必须要实现的.延展可以认为是一个私有的类目.
- 类别可以在不知道,不改变原来代码的情况下往里面添加新的方法,只能添加,不能删除修改.
- 并且如果类别和原来类中的方法产生名称冲突,则类别将覆盖原来的方法,因为类别具有更高的优先级.
- 继承可以增加,修改删除方法,添加属性.
- Category只能为对象添加方法,却不能添加成员变量的原因:
- 如果可以添加成员变量,添加的成员变量没有办法初始化
6.浅复制(拷贝)和深复制的区别?
- 浅复制(copy)
- 只复制指向对象的指针, 而不复制引用对象本身
- 深复制(mutableCopy)
- 复制引用对象本身,深复制就好理解了,内存中存在了两份独立对象本身,当修改A时,A_copy不变.
7.NSString的时候用copy和strong的区别?
- OC中NSString为
不可变
字符串的时候,用copy和strong都是只分配一次内存,但是如果用copy的时候,需要先判断字符串是否是不可变字符串,如果是不可变字符串,就不再分配空间,如果是可变字符串才分配空间. - 如果程序中用到NSString的地方特别多,每一次都要先进行判断就会耗费性能,影响用户体验,用strong就不会再进行判断,所以,不可变字符串可以直接用strong
8.id和instancetype的区别?
- id类型
- 万能指针,能作为
参数
,也能作为方法的返回类型
- 万能指针,能作为
- instancetype
- 只能作为方法的返回类型,并且返回的类型是当前定义类的类型
9.load和initialize方法的区别?
load方法:
- 当
类对象
被引入项目时, runtime会向每一个类对象发送 load 消息. - load 方法会在
每一个类
甚至分类
被引入时仅调用一次
,调用的顺序 :父类优先于子类,子类优先于分类
. - load 方法
不会被类自动继承
+ (void)load;
initialize方法:
- 类对象的初始化方法.第一次使用这个类的时候会调用这个方法.
+ (void)initialize;
10.GET请求和POST请求的区别?
GET请求
- URL后面用?的形式跟上发给服务器的参数,多个参数之间用&隔开,并且URL长度有限制,通常不超过1KB
POST请求
- 发给服务器的参数放在请求体中,没有限制
二者如何选择?
- GET
- 仅仅是数据查询,建议GET
- POST
- 传递大量数据,如文件上传
- 机密信息,如账号密码等
- 增删改使用POST
11.NSURLSession相比NSURLConnection的优势?
- NSURLSession支持 http 2.0 协议
- 下载任务时可以直接把数据下载到磁盘
- 支持后台上传和下载
- 同一个session发送多个请求,只需要建立一次连接
- 提供了全局的session并且可以统一配置,使用方便
- 多线程异步下载,效率高
网友评论