iOS面试题大全(附带答案)

C语言相关面试题

1.static有什么用途?

答案:在C语言中,static主要定义全局静态变量,定义局部静态变量,定义静态函数。
static 属于静态变量,使用它修饰的变量生命周期是整个源程序。
@1.在函数体内的 static 变量的作用范围为该函数体,该变量的内存只被分配一次,因此其值在下次调用时仍维持上次的值;
@2.在模块内的 static 全局变量可以被模块内所有函数访问,但不能被模块外其它函数访问;
@3.在模块内的 static 函数只被这一模块内的其它函数调用,这个函数的使用范围被限制在声明它的模块内;

2.说下冒泡排序的原理?

答案:1.两两比较,质量大的下沉,质量小的上浮;
2.外层循环用于控制排序次数,n个数需要n-1次;
3.内层循环用于两两比较,每次找出最大的沉到最底部;

for(i=1; i ary[j+1]){
            temp = ary[j];
            ary[j] = ary[j+1];
            ary[j+1] = temp;
        }
    }
 }  

3.说下选择排序的原理?

答案:1.每次获取一个关键字与它后面的数进行一一比较,找出最小的数与关键字进行交换;
2.外层循环用于获取关键字,同时控制循环次数(n个数需要n-1次);
3.内层循环用于将关键字与它后面的数一一比较,找出最小的数与关键字进行交换;

        for(i=0; i ary[j]){-->这里ary[i]就是关键字
                temp = ary[i];
                ary[i] = ary[j];
                ary[j] = temp;
            }
        }
        }   

第一趟选择排序:从n个数中找出最小的数,将它与第一个数(即关键字)交换,结果最小的数被安置在第一个元素位置上;
第二趟选择排序:从n-1个数中找出次小的数,将它与第二个数(即关键字)交换,结果次小的数被安置在第二个元素位置上;
重复上述过程,共经过n-1趟排序后,排序结束。

4.说下二分查找的原理和先决条件?

答案:1.先决条件:必须是一维顺序数组;
2.原理:取中,比较;
3.设置最小索引和最大索引,定一个while循环语句条件是最小索引<最大索引,首先判断要查找的值等不等于这2个索引对应的值,等于就查找成功了。不等于再定义一个中间索引,判断要查找的值等不等于中间索引对应的值,等于就查找成功了。不等于那就判断要查找的值是否小于中间索引对应的值,小于的话就把中间索引减1赋值给最大索引,反之就把中间索引加1赋值给最小索引。

设置数组r最小索引low,最大索引high,求数组的中间索引mid=(low+high)/2; //设置数组的最大和最小索引,求数组的中间索引
若r[mid]==k,查找成功; //若中间索引的值等于要查找的数,则查找成功
若r[mid]>k,设置high=mid-1,继续进行二分查找; //若中间索引的值大于要查找的数,设置最大索引为中间索引减1,继续进行二分查找
若r[mid]

5.说下你对C语言指针的理解?

答案:1.指针就是内存的地址,是C语言中广泛使用的一种数据类型。运用指针编程是C语言最主要的风格之一。
2.C语言允许用一个变量来存放指针,这种变量称为指针变量。利用指针变量可以表示各种数据结构;能很方便地使用数组和字符串;从而编出精炼而高效的程序。

6.C语言里的顺序链表如何实现呢?

答案:定义几个结构体,每个结构体里面包含俩个成员,一个整形变量,一个指针变量。让一个结构体里的指针变量指向另一个结构体的地址,而另一个结构体里的指针变量又指向另一个结构体的地址。从而形成一个顺序链表。

7.C语言里的循环链表如何实现呢?

答案:定义几个结构体,每个结构体里面包含俩个成员,一个整形变量,一个指针变量。让一个结构体里的指针变量指向另一个结构体的地址,而另一个结构体里的指针变量又指向另一个结构体地址。然后让最后一个结构体里的指针变量指向开始那个结构体的地址,从而形成一个循环链表。

8.说下你对C语言二叉树的了解?

答案:在计算机科学中,二叉树是每个节点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用于实现二叉查找树和二叉堆。

9.C语言里typedef与define有什么区别呢?

答案:#define 是在预编译时处理的,它只能作简单的字符串替换。
typedef 是在编译时处理的,它是给已有类型起别名。

10.写一个标准宏MIN,这个宏输入两个参数并返回较小的一个?

答案:#define MIN(X,Y) ((X)>(Y)?(Y):(X))
define只会是纯替换作用,所以X,Y均需要加括号,以防止X,Y为表达式的情况

三目条件运算符,语法格式;x?y:z;
其中x为bool类型表达式,先计算x的值,若为true则结果为表达式y的值,否则结果为表达式z的值。

二.内存管理面试题6个

1.说下你对内存管理的理解?

答案:1.在非ARC的情况下,谁创建谁释放,当对对象进行alloc,new,retain,copy时,需要调用release或autorelease释放。当引用计数为0的时候,会调用dealloc方法销毁当前对象。
2.在ARC的情况下,任何强指针(strong,retain)指向的对象就会被销毁;任何弱指针(assign)指向的对象就不会被销毁;默认情况下对象都是强指针类型。
3.自动释放池是OC的一种内存自动回收机制,可以将一些临时变量通过自动释放池来回收统一释放;内存池autoreleasepool是用于管理那些被声明为autorelease的对象,系统中有成千上万个内存池,系统内存不足时,系统会从栈中取最顶层的池子把引用计数为0的对象释放掉,收回的内存給当前应用程序使用。
自动释放池本身销毁的时候,池子里面所有的对象都会做一次release操作。
在使用block的时候,一定要注意不能在block里面直接对对象进行操作,而是要是要使用__block或__weak进行修饰,避免循环引用,造成内存泄漏。

2.ARC环境下有内存泄漏吗?如果有,请举例说明。

答案:有。比如:两个用strong修饰的对象相互引用或 某个控制器里有循环引用都会导致内存泄漏。

3.说下深拷贝与浅拷贝的区别?

答案:浅拷贝指的是只复制对象的指针,而不会复制对象的属性的地址。
深拷贝指的是即会复制对象的指针也会复制对象的属性的地址。

4.什么是自动释放池?它的底层是怎么实现的?

答案:1.自动释放池是OC的一种内存自动回收机制。当对象调用autorelease时,该对象就会被放入到自动释放池中。当自动释放池被回收时,就会从栈中删除,并且会给池子里面的所有对象都会做一次release操作。

答案:自动释放池是OC的一种内存自动回收机制,可以将一些临时变量通过自动释放池来回收统一释放;
内存池autoreleasepool是用于管理那些被声明为autorelease的对象,系统中有成千上万个内存池,系统内存不足时,系统会从栈中取最顶层的池子把引用计数为0的对象释放掉,收回的内存給当前应用程序使用。
自动释放池本身销毁的时候,池子里面所有的对象都会做一次release操作。

5.程序出现内存泄漏,该如何解决?

答案: 1.单步断点调试,找出内存泄漏的地方,
2.使用全局断点,锁定程序闪退的地方,找出内存泄漏的原因
3.使用僵尸变量,根据打印日志,然后分析原因,找出内存泄漏的地方
4.分段调试,找出内存泄漏的地方
5.使用Instrument当中的Leak检测工具

6.实际开发中,如何对内存进行优化呢?

答案:1.用ARC管理内存,它能保证释放掉不再需要的对象内存
2.尽量把VIew设置成透明
3.避免反复处理数据
4.优化tableVIew
5.当对视图控制器进行pop或dismiss操作的时候,把该视图控制器的视图对象等于nil或者直接remove掉。
6.在使用block的时候,一定要注意不能在block里面直接对对象进行操作,而是要是要使用__block或__weak进行修饰,避免循环引用,造成内存泄漏。
7. 使用Instrument当中的Leak检测工具
8. 使用Autorelease Pool

三.Objective-C语言相关面试题16个

1.描述一下你对OC堆和栈的理解?

答案:堆由开发人员控制,比如:alloc的对象,要手工释放或交由系统释放;
栈是由编译器自动管理,无需我们手动控制。

2.什么是单例呢?

答案:单例模式的意思就是只有一个实例对象。而且自行实例化并向整个系统提供这个实例。

答案:单例就是使得一个类的对象成为系统中唯一的实例对象,需要用static创建这个全局对象。

3.ARC环境下创建单例有哪两种方式,请举例说明?

答案:1.创建一个全局静态实例并设置成nil;实现一个实例构造方法并进行同步处理,再判断上面声明的静态实例是否为nil,如果是则新建并返回这个实例对象;
2.使用GCD线程中的只执行一次的方法来创建单例。

4.MRC下怎么创建单例模式呢?

答案:必须重写allocWithZone,copyWithZone,release和autorelease方法,用来保证其他人直接使用alloc和init试图获得一个新实例时不产生新实例。

5.说下KVC与KVO的区别?

答案:1.KVC是键值编码,即通过字符串的名字(key)来访问类属性。而不是通过调用Setter、Getter方法来访问。即使这个属性它没有Set和Get方法,我们也能访问;注意:当这个属性有Set方法系统会优先调用Set方法,通过KVC设值对象,此对象会被retain。
2.KVO是键值监听,即指定观察的对象属性被修改后,KVO就会自动通知相应的观察者,用完后需要在dealloc方法中移除观察者。如果开启了ARC机制后也可以调用dealloc方法,只不过不能调用[super dealloc],然后在dealloc方法中移除观察者。

6.描述下synthesize与dynamic的作用?

答案:1.@property有两个对应的词,一个是@synthesize,一个是@dynamic。如果@synthesize和@dynamic都没写,那么默认的就是@syntheszie var = _var;
2.@synthesize的语义是如果你没有手动实现setter方法和getter方法,那么编译器会自动为你加上这两个方法。
3.@dynamic告诉编译器,属性的setter与getter方法由用户自己实现,不自动生成。(当然对于readonly的属性只需提供getter即可)。假如一个属性被声明为@dynamic var,然后你没有提供@setter方法和@getter方法,编译的时候没问题,但是当程序运行到instance.var =someVar,由于缺setter方法会导致程序崩溃;或者当运行到 someVar = var时,由于缺getter方法同样会导致崩溃。编译时没问题,运行时才执行相应的方法,这就是所谓的动态绑定。

7.类与类之间的消息传递,有哪几种方式呢?

答案:委托代理delegate,消息通知,KVO键值监听,block块。

8.描述下你对消息通知的理解?

答案:通知(NSNotificationCenter)是一对多的关系,当一个类需要跟多个类进行信息传递的时候,我们一般都是用消息通知,
①通知时同步的,使用时必须先注册并绑定接收通知的方法,
②消息中心创建消息内容,然后发送通知
③不在监听时调用dealloc方法移除通知对象!

答案:用于通知多个对象某个事件,在对象中实现对象监听及监听的方法;是一对多的模式,只要接收通知都能响应方法。

9.主线程注册通知事件,子线程发通知事件,那响应方法在哪个线程完成呢?

答案:子线程完成,在哪个线程发送通知就在哪个线程响应

10.描述一下你对委托代理的理解,它支持一对多吗?如果支持,如何实现?

答案:委托代理是类与类之间信息传递的一种方式,使用委托代理的时候,必须先声明协议,确认协议并实现协议中声明的方法,添加要委托的对象,最后才能使用,
它支持一对多吗?:可以!即可以把委托delegate改成数组保存多个委托对象,调用时取出每一个委托对象进行信息传递。

答案:委托代理是类与类之间信息传递的一种方式,协议只声明了方法,不具体实现,接受协议的对象负责实现;

11.什么是类别?什么是延展?详细描述一下你的理解。

答案:类别是给已有类添加新的方法且对外界公开,不能添加实例变量;
延展是给类添加私有变量,属性及方法。对外界不公开。

12.详细描述一下你对block的理解,它的作用有哪些呢?

答案:block 是IOS4.0之后新增一种语法结构,也称闭包
SDK4.0,新增的API大量使用了block
block类似一个匿名的函数代码块,此代码块可以作为参数传递对象或方法,也可以作为方法的返回值;
block可以实现两个类之间的信息传递,
并且block对局部变量是只读的,如果要修改可以加__block进行修饰。
block是获取其他函数局部变量的匿名函数功能是保存代码片段, 预先准备好代码, 并在需要的时候执行.
作用:在两个类之间的信息传递 或者对代码封装作为参数进行传递 或者作为方法的返回值 利用block实现代理委托delegate

13.ARC环境下使用block会产生内存泄漏吗?如果会,该如何解决呢?

答案:当在block里面直接调用局部对象或者当前对象self的属性或方法的时候,局部对像或当前对象,就会block隐性的retain一次,导致相互引用,内存泄漏!
可以加__block,或使用完之后立即释放block,防止内存泄漏
1.使用__block修饰当前对象 2.block使用完后立即释放,即self.block=nil

14.类别和继承有什么区别呢?

答案:类别:是给已有的类添加新的方法,向对象添加非正式协议 ,使原有类的功能更加强大,但是不能添加实例变量!
继承:子类继承父类,子类就拥有了父类的成员、属性及方法,这样可以节省代码量,使程序更加简洁,也可以添加新的属性及方法,使功能更加强大!
成员也可以使用权限控制,@private私有的,@protected受保护的,@public公共的

答案:继承修改的方法不会对父类原方法产生影响;
类别修改的方法相当于替换了原有方法。

15.NSPredicate即谓词逻辑,可以用来做什么呢?

答案:redicate即谓词逻辑,用于从数据堆中根据条件进行筛选,大多用于数组对象的筛选。
(1). 可用于数组中数字对象和字符串对象的比较;
(2). 可用于筛选符合条件的数组元素;

16.描述下__block和__weak修饰符的区别?

答案:__block不管在ARC模式下还是MRC模式下,都可以使用,可以修饰对象,还可以修饰修饰基本数据类型
__weak只能在ARC的模式下使用,只能修饰对象,不能修饰基本的数据类型
__block对像可以在block中重新被赋值,__weak不可以

四.UI界面相关9个题

1.什么是MVC模式?什么是MVVM模式?详细说明一下。

答案:MVC模式
Model是数据层;View是用于显示界面;Controller将model和view绑定在一起,也是model和view通信的桥梁。
MVVM框架与传统的MVC框架极为相似,是MVC框架的延伸。
M:即Model层,数据模型,用来定制数据的。 创建的实体类都是放在这个文件夹里;
V: 即ViewController层,即视图控制器。 用来显示界面以及与用户交互;
它又可以细分成View层和Controller层,其中View层保存纯视图类,Controller层保存控制器;
VM: 即ViewModel层,即业务逻辑层。用来处理ViewController层的业务逻辑和界面逻辑, 比如:网络数据请求,
json解析,本地数据存储,用户登录密码校验,图片上传与下载等。说明了,就是把原来的ViewContrller
层的业务逻辑和页面逻辑等剥离出来放到ViewModel层。


2.描述一下UITableView的重用机制?

答案:tableview有个可重用队列,滑出去的会放到可重用队列里面,滑进来的会从可重用队列里面获取,如果没有,会创建一个cell,cell的可重用标示是用static静态变量声明的。

3.如果想让scrollview实现重用,有什么好的思路呢?

答案:可以把UITableView逆时针转90度,tableview里的cell顺时针转90度,使用它们的属性transform来实现。同时修改tableview的frame以及当前的cell的高度,即可实现。

4.视图控制器从创建到销毁分别经历哪些方法呢?

答案:alloc—init—loadview(创建并加载一个属于自己的根视图)—viewdidload(视图加载完成)—viewwillappear(视图将要显示)—viewdidappear(视图已经显示)—viewWillDisapper(视图将要消失)—viewDiddisappear(视图已经消失)—dealloc

5.描述一下事件的响应者链。

答案:当前触发事件--根视图上的子视图--视图控制器上的根视图--视图控制器--窗口--UIApplication对象--丢弃

6.didMoveToSuperView,layoutSubviews,drawRect都在什么时候调用呢?实际编码中用来做什么呢?

答案:didMoveToSuperView:当继承自UIView的子视图被贴到父视图时调用,可以在此方法中设置子视图自身的属性;
layoutsubviews:当添加到父视图或自己添加子视图时调用,当修改自己的frame或子视图的frame时也会调用,当自己调用setNeedsLayout方法时也会调用,父视图UIScrollView滚动时或屏幕旋转时也会调用(待求证)。可以在此方法对子视图进行重新布局;
drawRect:贴到父视图的时候调用,设置它的contentMode属性值为UIViewContentModeRedraw时,每次更改frame的时候调用,直接调用setNeedsDisplay或者setNeedsDisplayInRect:方法的时候调用。可以在此方法中绘制自己的内容。

7.CALayer和UIView的区别是什么呢?

答案:两者最大的区别是:图层不会直接渲染到屏幕上,UIView是IOS系统中界面元素的基础,所有的界面元素都是继承自它。它本身完全由CoreAnimation 来实现的。它真正的绘图部分,是由一个CALayer类来管理。UIView本

你可能感兴趣的:(iOS面试题,面试题大全,ios)