iOS面试题(部分)

1.堆和栈的区别?

管理方式:

对于栈来说,是由编译器自动管理,无需我们手工控制;对于堆来说,释放工作由程序员控制,容易产生memory leak(内存泄漏)。

申请大小:

栈:在Widows下,栈是向低地址扩展的数据结构,是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在Widows下,栈的大小是2M(也有的说是1M,总之是一个编译时就确定的常数),如果申请空间超过栈的剩余空间时,将提示overflow(溢出)。因此,能从栈获得的空间较小。

堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于操作系统是用链表示来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。

碎片问题:

对于堆来讲,频繁的new/delete势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低。对于栈来讲,则不会存在这个问题,因为栈是先进后出的队列,他们是如此的一一对应,以致于永远都不可能有一个内存块从栈中间弹出

分配方式:

栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。堆则是C/C++函数库提供的,它的机制是很复杂的。


总结:

堆和栈的区别可以用如下的比喻来看出:
使用栈就象我们去饭馆里吃饭,只管点菜(发出申请)、付钱、和吃(使用),吃饱了就走,不必理会切菜、洗菜等准备工作和洗碗、刷锅等扫尾工作,他的好处是快捷,但是自由度小。
使用堆就象是自己动手做喜欢吃的菜肴,比较麻烦,吃完之后还得清洗、打扫等后续工作(不然用完了不清洗就不好再用),但是比较符合自己的口味,而且自由度大


2.static 关键字的作用?

1)函数体内 static 变量的作用范围为该函数体,不同于 auto 变量,该变量的内存只被分配一次,因此其值在下次调用时仍维持上次的值

2)在模块内的 static 全局变量可以被模块内所用函数访问,但不能被模块外其他函数访问;

3)在模块内的 static 函数只可被这一模块内其他函数调用,这个函数的使用范围被限制在声明它的模块内;

4)在类中的 static 成员变量属于整个类所拥有,对类的所有对象只有一份拷贝;

5)在类中的 static 成员函数属于整个类所拥有,这个函数不接收 this 指针,因而只能访问类的 static 成员变量


3.写一算法进行排序   {9,4,2,6,1,3,5}

    NSArray *array = @[@9,@4,@2,@6,@1,@3,@5];
    NSMutableArray *mArray = [NSMutableArray array];
    for (int i = 0; i<array.count; i++)
    {
        [mArray addObject:array[i]];
    }
    NSLog(@"排序前%@",mArray);
    for (int i = 0; i<mArray.count-1; i++)
    {
        for (int j = 0; j<mArray.count-1-i; j++)
        {
            NSString *first = mArray[j];
            NSString *secend = mArray[j+1];
            if ([first compare:secend] == NSOrderedDescending)
            {
                [mArray exchangeObjectAtIndex:j withObjectAtIndex:j+1];
            }
        }
    }
    NSLog(@"排序后%@",mArray);


4.有一条绳,长30米,短的一截是长的一截的3/5,长的一截有多少米?




1.类和类的扩展的区别?

category和extensions的不同在于后者可以添加属性。另外后者添加的方法是必须要实现的

extensions可以认为是一个私有的category


2.Objcetive-C的类可以多重继承吗?可以实现多个接口嘛?Category 是什么?

Objective-C不可以实现多重继承;可以实现多个接口,通过实现多个接口可以完成C++的多重继承;Category是类别,用Category去重写类的方法,仅对本Category有效,不会影响到其他类与原有类的关系。


3.Object-C属性特征
(assign, retain, copy, readonly, readwrite, atomic, nonatomic)

1)assign:赋值特性,setter方法将传入参数赋值给实例变量;仅设置变量时;

2)retain:表示持有特性,setter方法将传入参数先保留,再赋值,传入参数时retainCount会+1;

3)copy:表示赋值特性,setter方法将传入对象复制一份,需要完全一份新的变量时;

4)readonly:只读特性,只会生成getter方法,不会生成setter方法,不希望属性在类外改变

5)readwrite:可读可写特性,需要生成getter方法和setter方法时

6)nonatomic:非原子操作,决定编译器生成的setter getter是否是原子操作;atomic表示多线程安全,一般使用nonatomic


4.写一个 setter 方法用于完成@property(nonatomic,retain)NSString *name,写一个 setter 方法用于完成 property(nonatomic,copy)NSString *name

-(void)setName:(NSString *)str
{
     [str retain];
     [name release];
     name = str;
}

-(void)setName:(NSString *)str
{
     id = [str copy];
     [name release];
     name = str;
}


5.Object-C 如何对内存管理的,说说你的看法和解决办法?ARC 和 MRC 的内存管理区别在哪里?

Object-C的内存管理主要有三种方式:ARC(自动内存计数),MRC(手动内存计数),内存池。

1)ARC(自动内存技术):ARC就是在代码编译时为你自动在合适的位置插入release或autorelease,你只需要去申请内存,使用它,而不需要如何去释放它,系统会帮你解决,ARC比MRC节省了大量代码,使得开发效率更高,iOS5/Mac OS X 10.7开始导入,ARC不同于垃圾回收机制

2)MRC(手动内存技术):就是说从一段内存被申请之后,就存在一个变量用于保存这段内存被使用的次数,我们暂时把它称为计数器,当计数器变为0的时候,那么就是释放这段内存的时候。比如说,当在程序A里面一段内存被成功申请完成之后,那么这个计数器就从0变成1(我们把这个过程叫做alloc),然后程序B也需要使用这个内存,那么计数器就从1变成2(我们把这过程叫做retain)。紧接着程序A不再需要这段内存了,那么程序A就把这个计数器减1(我们把这个过程叫做release)。程序B也不需要这个内存的时候,那么也把计数器减1(这个过程还是release)。当系统(也就是Foundation)发现这个计数器变成0了,那么就会调用内存回收程序把这段内存回收(我们把这个过程叫做dealloc)。如果没有Foundation,那么维护计数器,释放内存等工作需要你手工来完成。解决:一般是由类的静态方法创建的,函数名中不会出现alloc或init字样,如[NSString string]和[NSArray arratWithObject:],创建后引用计数+0,在函数出栈后释放,既相当于一个栈上的局部变量,当然也可以通过retain延长对象的长存期。

3)内存池:可以通过创建和释放内存池控制内存申请和回收的时机。解决:是由autorelease加入系统内存池,内存池是可以嵌套的,每个内存池都需要有一个创建释放对,就像main函数中写的一样。使用也很加单,比如[[[NSString alloc] initWithFormat:@"Hey you!"] autorelease],即将一个NSString对象加入到最内层的系统内存池,当我们释放这个内存池时,其中的对象都会被释放。

ARC和MRC的区别

其实arc 内部机制原理也是来源于mrc ,arc 是在 iOS 5/ Mac OS X 10.7 开始导入,利用 Xcode4.2 可以使用该机能。arc的首要目的就是让代码简洁化,编程简单化,开发更顺心应手,减少不必要的小问题小疏忽;顾名思义,自动引用计数管理,关于内存的申请,使用和释放过程都交给系统自动实现,我们可也不用关系里面的过程,但是事实上还是mrc的原理,只是是系统帮我们做了管理;
mrc,手动引用计数器管理,是在我们申请到某一块内存,在使用之后,要手动释放,释放机理涉及到计数器问题,如果未释放内存,会造成内存的浪费,俗称内存泄露,甚至引起很多未知的错误结果,这对程序有威胁很大,但是,何时释放,怎么释放,注意哪些问题,很有讲究,这就是mrc的不便之处,也是苹果推出arc的缘由;
mrc的具体机理,计数器是什么,在程序过程中的变化,在达到什么程度会释放内存,怎么操作;建议查阅相关文档;
mrc ,在代码上下形式主要表现为,调用该对象时,要做retain操作,使用完成后要release,最后还要重写dealloc方法,对该类的所有对象做释放,所以在mrc的代码会有autorelease,retain,release等词语,
而arc不允许有这些词汇,应为这些操作都由系统自动完成。

引用计数器
1.和内存管理相关的方法
1)alloc 引用计数器自动设为1
2)retain 引用计数器+1 返回了经过+1以后的当前实例对象
3)release 引用计数器-1,并不一定是释放
4)retainCount 获取引用计数器的值
5)dealloc 当实例对象被销毁之前,系统自动调用。
一定要调[super dealloc]

和内存管理相关的名词
1)僵尸对象:此对象被销毁,不能再使用,不能给它发送任何消息
2)野指针:指向僵尸对象(不可用的内存)的指针,给野指针发送消息将会产生不可控的后果。
3)空指针:没有指向任何对象的指针,给空指针发消息不会产生任何行为

内存管理原则
1.如果你想持有某个对象,就必须负责让做一次retain操作,引用计数器+1.
2.如果你想放弃对某个对象的持有权,就要负责让其做一次release操作,引用计数器-1.
3.谁retain,谁release


6.介绍一下协议 与 类别

类别:有时候我们需要在一个已经定义好的类中增加一些方法,而不是想去重写该类。比如,当工程已经很大,代码量比较多,或者类中已经包住很多方法,已经有其他代码调用了该类创建对象并使用该类的方法时,可以使用类别对该类扩充新的方法。

注意:类别只能扩充方法,而不能扩充成员变量。

协议:协议(protocol)类似于java语言里的接口(interface),定义了一组方法,而不提供具体实现,只有那些"遵守"(conform to)或"采用"(adopt)了这些Protocol的类来给出自己的实现。协议不是类本身,它们仅定义了其它对象有责任实现的接口。当在自己的类中实现协议的方法时,用户的类就是遵守这个协议的,协议声明的方法可以被任何一个类实现。

7.委托(代理)有什么作用?代理怎么实现,请简单代码举例?

委托(代理)作用:委托(代理)的作用有两个,一个是传值,一个是传事件。

1)传值就是在B类要把自己的一个数据或者对象传给A类,让A类去展示或者处理。(这个作用在两个View视图之间传递参数的时候特别有用)

2)传事件就是A类发生了什么事,把这事件告诉关注自己的人,也就是委托的对象,由委托的对象去考虑发生这个事件后应该做出什么反映。简单的说,假如A类发生了某个事件,它本身并不出来,而是通过委托delegate的形式,让它的委托对象B类去处理(当然委托对象B就要实现委托中的方法)。

实现:

在.h文件

@protocol EveryFrameDelegate<NSObject>

-(void)DoSomethingEveryFrame;

@end

@property(nonatomic,assign)id<EveryFrameDelegate>delegate;


8.描述一个你遇到过的 retain cycle例子


9.#import 和 #include 的区别 @class

#import是Objective-C导入头文件的关键字,#include是C/C++导入头文件的关键字,使用#import头文件会自动导入一次,不会重复导入,相当于#include和#pragma once;@class告诉编译器某个类的声明,当执行时,才去查看类的实现文件,可以解决头文件的相互包含;#import<>用来包含系统的文件,#import""用来包含用户头文件


10.在一个对象的方法里面:self.name = @“object” 和 _name = @“object”有什么不同

self.name = @"object"会调用对象的setName()方法;

_name = @"object"会直接把object赋值给当前对象的name属性


11.请简述 self.name = nil 的机制,以及与[_name release]的区别

self.name = nil;使用nil参数调用setName:方法

[_name release] 生成的访问器将自动释放以前的name对象


12.请解释一下 iOS应用的沙盒机制

iOS中的沙盒机制(sandBox)是一种安全体系,它规定了应用程序只能在为该应用创建的文件夹内读取文件,不可以访问其他地方的内容。所有的非代码文件都保存在这个地方,比如图片、声音、属性列表和文本文件等、

1)每个应用程序都在在即的沙盒内

2)不能随意跨越自己的沙盒去访问别的应用程序沙盒的内容

3)应用程序向外请求或接收数据都需要经过权限认证


13.Object-C中的数据类型有哪些,简述他们与基本数据类型的区别

Objective-C的数据类型有NSString、NSNumber、NSArray、NSMutableArray、NSData等待,这些都是class,创建后便是对象,而C语言的基本数据类型int,只是一定字节的内存空间,用于存放数值;NSInteger是基本数据类型,并不是NSObject的子类。NSInteger是基本数据类型int或者long的别名,它的区别在与,NSInteger会根据系统是32位还是64位来决定本身是int还是long。


14.iOS UI 的图像存储类型是什么

图像一般都存储为NSData类型


15.这段代码有什么问题?
-(void)setName:(NSString *)newName{

     self.name = newName;
}

死循环


16什么时候用 NSMutableArray? 什么时候使用 NSArray?

NSArray创建的是静态数组,一旦创建之后,就再也不能添加和删除数组中的对象了

NSMutableArray创建的是动态数组,可随意添加或删除数组中的元素

什么时候该用哪个,看工程需求

你可能感兴趣的:(ios)