iOS 开发面试题(技术基础类)

1. Object-C有多继承吗?没有的话用什么代替?


2. Object-C有私有方法吗?私有变量呢?


3. #import和#include的区别,@class代表什么?


4. 线程和进程的区别?


5. 堆和栈的区别?


6. Object-C的内存管理?


7. 浅复制和深复制的区别?


8.lldb(gdb)常用的调试命令?


9.如何调试BAD_ACCESS错误?


10.若一个类有实例变量NSString *_foo,调用setValue:forKey:时,可以以foo还是_foo作为key?


11.在block内如何修改block外部变量?


12.如何修改ARC为MRC?


13.@property 后面可以有哪些修饰符?


15.常见的Crash有哪些?


====================================================================================================================


答案:


I.cocoa 中所有的类都是NSObject 的子类


多继承在这里是用protocol 委托代理 来实现的 你不用去考虑繁琐的多继承 ,虚基类的概念. ood的多态特性 在 obj-c 中通过委托来实现.




II.objective-c – 类里面的方法只有两种, 静态方法和实例方法. 这似乎就不是完整的面向对象了,按照OO的原则就是一个对象只暴露有用的东西. 如果没有了私有方法的话, 对于一些小范围的代码重用就不那么顺手了.


在类里面声名一个私有方法


@interface Controller : NSObject { NSString *something; } 
+ (void)thisIsAStaticMethod; – (void)thisIsAnInstanceMethod;
 @end


@interface Controller (private) 
- (void)thisIsAPrivateMethod; 
- @end
@private可以用来修饰私有变量


在Objective‐C中,所有实例变量默认都是私有的,所有实例方法默认都是公有的


III.@class一般用于头文件中需要声明该类的某个实例变量的时候用到,在m文件中还是需要使用#import‘


而#import比起#include的好处就是不会引起重复包含


IV.进程和线程都是由操作系统所体会的程序运行的基本单元,系统利用该基本单元实现系统对应用的并发性。


进程和线程的主要差别在于它们是不同的操作系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。


V.管理方式:对于栈来讲,是由编译器自动管理,无需我们手工控制;对于堆来说,释放工作由程序员控制,容易产生memory leak。 申请大小:


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


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


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


分配方式:堆都是动态分配的,没有静态分配的堆。栈有2种分配方式:静态分配和动态分配。静态分配是编译器完成的,比如局部变量的分配。动态分配由alloca函数进行分配,但是栈的动态分配和堆是不同的,他的动态分配是由编译器进行释放,无需我们手工实现。 分配效率:栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。堆则是C/C++函数库提供的,它的机制是很复杂的。




VI.a.当你使用new,alloc和copy方法创建一个对象时,该对象的保留计数器值为1.当你不再使用该对象时,你要负责向该对象发送一条release或autorelease消息.这样,该对象将在使用寿命结束时被销毁.


b.当你通过任何其他方法获得一个对象时,则假设该对象的保留计数器值为1,而且已经被设置为自动释放,你不需要执行任何操作来确保该对象被清理.如果你打算在一段时间内拥有该对象,则需要保留它并确保在操作完成时释放它.


c.如果你保留了某个对象,你需要(最终)释放或自动释放该对象.必须保持retain方法和release方法的使用次数相等.


VII.浅层复制:只复制指向对象的指针,而不复制引用对象本身。


深层复制:复制引用对象本身。


意思就是说我有个A对象,复制一份后得到A_copy对象后,对于浅复制来说,A和A_copy指向的是同一个内存资源,复制的只不过是是一个指针,对象本身资源 还是只有一份,那如果我们对A_copy执行了修改操作,那么发现A引用的对象同样被修改,这其实违背了我们复制拷贝的一个思想。深复制就好理解了,内存中存在了 两份独立对象本身。


用网上一哥们通俗的话将就是:


浅复制好比你和你的影子,你完蛋,你的影子也完蛋


深复制好比你和你的克隆人,你完蛋,你的克隆人还活着。


VIII. po 对象


IX.设置全局断点快速定位问题代码所在行


X.都可以


XI.通过 __bock修改的外部变量,可以在block内部修改


XII.设置 Targets -> Build Phases ->Compile Sources 编译参数-fno -objc -arc


XIII.线程安全的:atomic,nonatomic 访问权限的:readonly,readwrite 
     内存管理(ARC):assign,strong,weak,copy 
     内存管理(MRC):assign,retain,copy:指定方法名称:setter= getter=
XIIII.内存管理错误,程序逻辑错误,SDK错误,主线程阻塞.
      程序逻辑错误主要有:访问无效或失效对象;数组越界或插入空对象;访问不存在的方法;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值