iOS面试、笔试题目总结

第一波

//【static关键字】简述static关键字在C和C++程序里的作用。

1、隐藏:未加static前缀的全局变量和函数都具有全局可见性,其它的源文件也能访问。如果加了static,就会对其它源文件隐藏。利用这一特性可以在不同的文件中定义同名函数和同名变量,而不必担心命名冲突。static可以用作函数和变量的前缀,对于函数来讲,static的作用仅限于隐藏。

2、保持变量内容的持久:存储在静态数据区的变量会在程序刚开始运行时就完成初始化,也是唯一的一次初始化。共有两种变量存储在静态存储区:全局变量和static变量,只不过和全局变量比起来,static可以控制变量的可见范围,说到底static还是用来隐藏的。虽然这种用法不常见。

3、默认初始化为0:其实全局变量也具备这一属性,因为全局变量也存储在静态数据区。在静态数据区,内存中所有的字节默认值都是0x00,某些时候这一特点可以减少程序员的工作量。比如初始化一个稀疏矩阵,我们可以一个一个地把所有元素都置0,然后把不是0的几个元素赋值。如果定义成静态的,就省去了一开始置0的操作。再比如要把一个字符数组当字符串来用,但又觉得每次在字符数组末尾加‘\0’;太麻烦。如果把字符串定义成静态的,就省去了这个麻烦。

综上所述,首先static的最主要功能是隐藏,其次因为static变量存放在静态存储区,所以它具备持久性和默认值0.

4、C++中的类成员声明static,静态数据成员是类的成员,而不是对象的。

参考:C/C++中static关键字作用总结


//【C++和OC的对比】简述C++和Objective-C的异同。

1 、两者最大的相同便是: 都是从 C 演化而来的面向对象语言, 两者都兼容标准 C 语言。

2 、两者最大的不同便是: Objective C 是完全动态的,而 C++是部分动态的。

3、Objective C 不支持多重继承, 而 C++ 支持。

参考:Objective-C 与 C++ 的异同


//【OC内存管理】简述assign,retain,copy的不同作用。

assign: 简单赋值,不更改索引计数
             对基础数据类型 (NSInteger)和C数据类型(int, float, double, char, 等)
copy:建立一个索引计数为1的对象,然后释放旧对象  
           对NSString 
retain:释放旧的对象,将旧对象的值赋予输入对象,再提高输入对象的索引计数为1
             对其他NSObject和其子类

也就是说,retain 是指针拷贝,copy 是内容拷贝。

参考:nonatomic,assign,copy,retain的区别


//【OC委托和通知】简述委托(delegate)和通知(notification)区别?为什么委托属性不推荐用retain?

delegate针对one-to-one关系,并且reciever可以返回值给sender;

notification 可以针对one-to-one/many/none,reciever无法返回值给sender;

所以,delegate用于sender希望接受到reciever的某个功能反馈值,notification用于通知多个object某个事件。

delegate用assign而不是retain是因为:delegate的生命周期不需要让该对象去控制,如果该对象对其使用retain很可能导致delegate所指向的对象无法正确的释放。

参考:iOS中NSNotification、delegate、KVO三者之间的区别与联系?

          为什么delegate属性使用delegate而不是retain?


//【iOS与设计模式】iOS自身常用的设计模式,举例说明。

(一)代理模式

应用场景:当一个类的某些功能需要由别的类来实现,但是又不确定具体会是哪个类实现。

优势:解耦合

敏捷原则:开放-封闭原则

实例:tableview的 数据源delegate,通过和protocol的配合,完成委托诉求。

列表row个数delegate

自定义的delegate

(二)观察者模式

应用场景:一般为model层对,controller和view进行的通知方式,不关心谁去接收,只负责发布信息。

优势:解耦合

敏捷原则:接口隔离原则,开放-封闭原则

实例:Notification通知中心,注册通知中心,任何位置可以发送消息,注册观察者的对象可以接收。

kvo,键值对改变通知的观察者,平时基本没用过。

(三)MVC模式

应用场景:是一中非常古老的设计模式,通过数据模型,控制器逻辑,视图展示将应用程序进行逻辑划分。

优势:使系统,层次清晰,职责分明,易于维护

敏捷原则:对扩展开放-对修改封闭

实例:model-即数据模型,view-视图展示,controller进行UI展现和数据交互的逻辑控制。

(四)单例模式

应用场景:确保程序运行期某个类,只有一份实例,用于进行资源共享控制。

优势:使用简单,延时求值,易于跨模块

敏捷原则:单一职责原则

实例:[UIApplication sharedApplication]。

注意事项:确保使用者只能通过 getInstance方法才能获得,单例类的唯一实例。

java,C++中使其没有公有构造函数,私有化并覆盖其构造函数。

object c中,重写allocWithZone方法,保证即使用户用 alloc方法直接创建单例类的实例,返回的也只是此单例类的唯一静态变量。

(五)策略模式

应用场景:定义算法族,封装起来,使他们之间可以相互替换。

优势:使算法的变化独立于使用算法的用户

敏捷原则:接口隔离原则;多用组合,少用继承;针对接口编程,而非实现。

实例:排序算法,NSArray的sortedArrayUsingSelector;经典的鸭子会叫,会飞案例。

注意事项:1,剥离类中易于变化的行为,通过组合的方式嵌入抽象基类

2,变化的行为抽象基类为,所有可变变化的父类

3,用户类的最终实例,通过注入行为实例的方式,设定易变行为,防止了继承行为方式,导致无关行为污染子类。完成了策略封装和可替换性。

(六)工厂模式

应用场景:工厂方式创建类的实例,多与proxy模式配合,创建可替换代理类。

优势:易于替换,面向抽象编程,application只与抽象工厂和易变类的共性抽象类发生调用关系。

敏捷原则:DIP依赖倒置原则

实例:项目部署环境中依赖多个不同类型的数据库时,需要使用工厂配合proxy完成易用性替换

注意事项:项目初期,软件结构和需求都没有稳定下来时,不建议使用此模式,因为其劣势也很明显,增加了代码的复杂度,增加了调用层次,增加了内存负担。所以要注意防止模式的滥用。

参考:iOS开发中常用的几种设计模式


//【iOS持久化保存】本地持久化保存有哪几种方式?

plist文件(属性列表)

preference(偏好设置)

NSKeyedArchiver(归档)

SQLite 3

CoreData

参考:iOS中几种数据持久化方案:我要永远地记住你!


//【iOS开源库】列举并简要介绍你使用过或者了解过的开源库。

MBProgressHUD、AFNetworking、FMDB

参考:IOS开源库一览表


//【OC类的定义】写一个简单的objective-c的类定义,要求带实例变量,实例方法,静态方法,属性,父类,委托。

(略)


第二波

//写一个简单的单例

创建A类的单例模式,如下:

public class A {
private static A a = new A();
private A(){};
public static A getA(){
return a;
}
}
参考: 最简单的单例


//Block是什么?使用时注意点?Block里能否修改变量?如何修改?修改背后的原理是什么?

我们可以把Block当做Objective-C的匿名函数。Block允许开发者在两个对象之间将任意的语句当做数据进行传递,往往这要比引用定义在别处的函数直观。另外,block的实现具有封闭性(closure),而又能够很容易获取上下文的相关状态信息。

……(略)

参考:透彻了解块(Block)的里里外外


//UITableView使用时有哪些需要优化的点?

1、恰当的重用cell:这是第一步,也是最重要的一步。重用一个cell非常简单,但是很多应用都会漏了这一步。因此,你如果有很多性能问题,确保多次检查这方面的问题。

2、恰当的 缓存/重用 图片/数据:另外一个重要的步骤就是当返回一个cell显示的时候,减少数据加载和逻辑处理的时间。

3、减少总的加载和计算时间:并不是仅仅只有IO会减慢和阻塞UI线程;任何数据的处理都会减慢这个过程。因此,你应该总是尽可能的减少这个过程的处理时间。

4、自行绘制cell:在渲染table view的时候,为了充分利用GPU计算密集型的优势,你应该考虑使用直接绘制的方法。这样会显著的提升渲染的速度,增加测量的性能;fps几乎接近最大。你可以通过复写drawRect方法绘制自己的cell,然后在每个元素中调用不同的方法绘制每个UI元素。

5、透明度:当开发者将他们的UI元素放进view的时候,这是经常会遇到的小问题。如果他们没有设置view为不透明,渲染的时候就要对同一个点绘制两次或多次。

6、缓存高度:这是开发者经常会犯的另一个小错误。每当需要一个新的cell,每次都会有两个主要的方法被调用。

7、避免图形特效:在cell中有越多的特效,渲染的过程就越慢。因此,你应该对此进行测试。你可以使用CoreAnimation来查看每个UI元素渲染的效率。

8、编辑/重排序性能:滚动性能优化,对于编辑或重排序来说,可能会带来一些问题,因为UIKit和动画框架已经多subview进行了优化。如果你是自己绘制的话,这些框架的优化将不起作用。

参考:iOS中UITableView性能优化


//响应链(Responder Chain)是什么?

响应者链就是由一系列的响应者对象构成的一个层次结构。

参考:Responder一点也不神秘--iOS用户响应者链完全剖析


//Runtime是什么?使用场景?

Objective-C runtime是一个实现Objective-C语言的C库。对象可以用C语言中的结构体表示,而方法(methods)可以用C函数实现。除了封装,Objective-C runtime库也负责找出方法的最终执行代码。

使用场景:动态创建类、创建对象、消息派发、调试程序等。

参考:iOS开发:详解Objective-C runtime


//assign和weak有什么区别?

weak属性在释放的时候会自动将指针置为nil。而assign不会需要程序员自己手动置空。而当内存释放后将指针置空一种推荐的安全做法。因为object c中可以以nil为对象访问任意属性和方法。如[nil setProperty:someProperty]。但实际nil显然没有这个方法。但是程序实际什么都没做,却不会crash。但是如果一个已经被释放了内存的非空属性调用任意方法会造成程序crash。

参考:strong,weak, retain, assign的区别


//通知,代理,KVO的区别?分别在什么场景下使用?

1.  效率 肯定是delegate比NSNotification高。

delegate方法比notification更加直接,最典型的特征是,delegate方法往往需要关注返回值, 也就是delegate方法的结果。比如-windowShouldClose:,需要关心返回的是yes还是no。所以delegate方法往往包含 should这个很传神的词。也就是好比你做我的delegate,我会问你我想关闭窗口你愿意吗?你需要给我一个答案,我根据你的答案来决定如何做下一 步。相反的,notification最大的特色就是不关心接受者的态度, 我只管把通告放出来,你接受不接受就是你的事情,同时我也不关心结果。所以notification往往用did这个词汇,比如 NSWindowDidResizeNotification,那么NSWindow对象放出这个notification后就什么都不管了也不会等待接受者的反应。

2、KVO和NSNotification的区别 :

和delegate一样,KVO和NSNotification的作用也是类与类之间的通信,与delegate不同的是1)这两个都是负责发出通知,剩下的事情就不管了,所以没有返回值;2)delegate只是一对一,而这两个可以一对多。这两者也有各自的特点。

参考:IOS 如何选择delegate、notification、KVO?


//列出你经常使用的一些第三方库。

(同上)


转载于:https://www.cnblogs.com/fifteen718/p/9533976.html

你可能感兴趣的:(iOS面试、笔试题目总结)