面试题 一

来源:互联网 发布:python金融实战 编辑:程序博客网 时间:2024/06/06 00:51
//(1).输出是什么@implementation Son : Father- (id)init{self = [super init];if (self) {NSLog(@"%@", NSStringFromClass([self class]));NSLog(@"%@", NSStringFromClass([super class]));}return self;}@end//(2).以下代码运行结果如何?- (void)viewDidLoad{[super viewDidLoad];NSLog(@"1");dispatch_sync(dispatch_get_main_queue(), ^{NSLog(@"2");});NSLog(@"3");}

 

1. 控制器的生命周期

2. 自动释放池是什么?如何工作?

3. 什么情况使用 weak 关键字,相比 assign 有什么不同?

4. 这个写法会出什么问题: @property (copy) NSMutableArray *array;

5. 内存中堆区和栈区的区别?

6. 代理delegate 与通知Notification,block的使用区别

7. const int a , int const a,int *const a, const int *a 各代表什么含义?

8. Http协议的特点,GET请求与POST请求的区别,什么是https协议?

9. http和scoket通信的区别。

10. 如何给原有的类添加属性和方法

11. 对于单例的理解

12. 对iOS 中的多线程的理解,什么时候选择使用GCD,什么时候选择NSOperation?

13. 对iOS中绘图和动画的理解

14. runloop和线程有什么关系?说说对runloop的理解

  

(1)Son Son

(2)1 

 

1、 控制器的生命周期

1, 生明周期图

 

2, 详细步骤:

  1. init函数(init,initWithFrame,initWithCoder) ---初始化函数

  2. awakeFromNib函数 ---如果有nib会调用这个函数,加载视图loadView函数之前调用

  3. loadView函数 ---加载当前视图,当前视图不存在的时候会调用一次,存在的时候不会调用

  4. viewDidLoad函数 ---一个viewController的生命周期中 loadView 和 viewDidLoad 都只会调用一次

  5. viewWillAppear函数 ---视图将要出现

  6. viewWillLayoutSubviews函数 ---将要对子视图进行布局

  7. viewDidLayoutSubviews函数 ---完成对子视图的布局

  8. viewDidAppear函数 ---视图已经渲染到屏幕上

  9. viewWillDisappear函数 ---视图将要消失

  10. viewDidDisappear函数 ---视图已经消失

PS:整个过程中 didReceiveMemoryWarning函数会在内存不足时调用,应当进行适当的内存释放,不然系统会强制关闭当前app

 

2、 自动释放池是什么?如何工作?

  NSAutoreleasePool 自动释放池是OC抽象出来的池子,通过一种引用计数的方式来管理内存。当您向一个对象发送一个autorelease消息时,Cocoa就会将该对象的一个引用放入到最新的自动释放池。它仍然是个合法的对象,因此自动释放池定义的作用域内的其它对象可以向它发送消息。当程序执行到作用域结束的位置时,自动释放池就会被释放,池中的所有对象也就被释放。autorelease和release没什么区别,只是引用计数减一的时机不同而已,autorelease会在对象的使用真正结束的时候才做引用计数减一,release是在语句执行完就会使对象引用计数减一,不管autorelease还是release,如果对象引用计数减一为零,Cocoa会释放该对象。

 

3、 什么情况使用 weak 关键字,相比 assign 有什么不同?

  strong与weak是由ARC新引入的对象变量属性。之前的版本使用的是retain和assign,是不支持ARC的。xcode 4.3(ios5和以上版本)之后就有了ARC,并且开始使用 strong与weak 。

  在ARC中的 assign 和 weak 可以说非常相像,导致有很多人误以为他们是一摸一样的,在任何时候都可以划等价,但事实却不是这样。 weak 比 assign 多了一个功能就是当属性所指向的对象消失的时候(也就是内存引用计数为0)会自动赋值为 nil ,这样再向 weak 修饰的属性发送消息就不会导致野指针操作crash。在 ARC 模式下编程时,指针变量一定要用 weak 修饰,只有基本数据类型和结构体需要用 assgin ,例如 delegate ,一定要用 weak 修饰。

 

4、 这个写法会出什么问题: @property (copy) NSMutableArray *array;

  程序运行会crash,报 unrecognized selector sent to instance 这个错误,因为 NSMutableArray在copy之后 属于NSArray对象,这个对象没有 可变对象 操作(增删改查)元素的方法

 

5、 内存中堆区和栈区的区别? 

堆区:调用malloc函数,程序运行中创建对象 会在堆区开辟空间。特点:主动去释放free 

栈区:普通函数调用,压栈/出栈会在栈区开辟/释放空间,局部变量在栈区储存。特点:先进后出FILO

 

栈区(stack)由编译器分配释放,存放方法的参数值,局部变量的值。

堆区(heap)一般由程序员分配与释放,若没有释放会造成内存溢出。

 

6、 代理delegate 与通知Notification,block的使用区别

  代理delegate 与block,通知Notification都用于通信回调处理。

  1. delegate与block一般只用于两个对象1对1之间的通信交互,delegate需要定义协议方法,代理对象实现协议方法,并且需要建立代理关系才可以实现通信。

  2. block更加简洁,不需要定义繁琐的协议方法,如果通信事件有多个步骤,使用delegate比较好,条理清晰。

  3. Notification只要用于1对多情况下通信,而且通信对象之间不需要建立关系,因此代码可读性比较差,建议少用。

 

7、 const int a , int const a, int *const a, const int *a 各代表什么含义?

  1. 不带 "*" 的 "const" 在这里修饰a不能改变,也就是代码不能出现a=xxx。

  2. " *前const " 用来修饰*a不能改变,即代码不能出现*a=xxx,但是可以a=xxx;

  3. " *后const " 用来修饰a不能改变,即代码不能出现a=xxx,但是可以*a=xxx;

 

 

8、 Http协议的特点,GET请求与POST请求的区别,什么是https协议?

  1. http协议属于短连接的。客户端主动发送请求,服务器做出响应,服务器响应之后,连接则断开。get请求没有请求体,post请求含有请求体,请求参数可以放在请求体重,所以post请求常用于提交大量数据。

  2. https是安全超文本传输协议,它是一个安全通信通道,基于http开发,用于客户机和服务器之间交换信息。它使用安全套接字(ssl)进行交换,简单来说,就是http的安全版。

 

9、 http和scoket通信的区别。

  1. HTTP:超文本传输协议,首先它是一个协议,并且是基于TCP/IP协议基础之上的应用层协议。TCP/IP协议是传输层协议,主要解决数据如何在网络中传输,HTTP是应用层协议,主要解决如何包装数据。HTTP协议详细规定了浏览器与服务器之间相互通信的规则,是万维网交换信息的基础。HTTP是基于请求-响应形式并且是短连接,并且是无状态的协议。针对其无状态特性,在实际应用中又需要有状态的形式,因此一般会通过session/cookie技术来解决此问题。

  Socket:Socket不属于协议范畴,而是一个调用接口(API),Socket是对TCP/IP协议的封装,通过调用Socket,才能使用TCP/IP协议。Socket连接是长连接,理论上客户端和服务器端一旦建立连接将不会主动断开此连接。Socket连接属于请求-响应形式,服务端可主动将消息推送给客户端。

  2. HTTP是客户端用http协议进行请求,发送请求时候需要封装http请求头,并绑定请求的数据服务器一般有web服务器配合,http请求方式为客户端主动发起请求,服务器才能给响应,一次请求完毕后则断开连接,以节省资源。服务器不能主动给客户端响应,除非采取http长连接 技术,iOS主要使用类是NSUrlConnection。 

  Socket是客户端跟服务器直接使用socket“套接字”进行连接,并没有规定连接后断开,所以客户端和服务器可以保持连接通道,双方都可以主动发送数据。一般在游戏开发或股票开发这种要求即时性很强并且保持发送数据量比较大的场合使用。主要使用类是CFSocketRef 

 

10、 如何给原有的类添加属性和方法

  1. 继承

  2. 分类category可以扩展类的方法,associative运行时拓展泪的属性

 

11、 对于单例的理解

1, 单例模式特点?
  1. 单例类只能有一个实例。
  2. 单例类必须自己创建自己的唯一实例。
  3. 单例类必须给所有其他对象提供这一实例。

2, 单例模式的作用?
  Singleton模式保证在应用程序中,只有一个实例存在。

3, 单例模式的创建形式?

  a. 标准单例,标准单例需要重写retain,copy,release,autorelease等方法,保证不管调用什么函数,程序始终只有一个对象

@implementation Singleton//定义静态全局变量static Singleton * single = nil ;+ (Singleton *)sharedSingleton {    //考虑线程安全    @synchronized(self){        if (single == nil) {            single = [[[self class] alloc] init];        }    }    return single;}//调用 alloc的时候 会调用allocWithZone函数+ (id)allocWithZone:(NSZone *)zone {    @synchronized(self) {        if (single == nil) {            //创建对象            single = [super allocWithZone:zone];            return single;        }    }    return single; //}//确保使用同一块内存地址 返回的是同一个对象- (id)copyWithZone:(NSZone *)zone {    return self;//返回自己}- (id)retain {    return self;//确保计数唯一}- (unsigned int)retainCount {    return UINT_MAX;  //返回最大值}//oneway这一般是线程之间通信的接口定义。表示单向的调用//使用oneway 异步调用 不使用那么是同步调用 可能会阻塞- (oneway void)release {    //do nothing}- (id)autorelease {    return self;}@end    

  

  b. 非标准单例

    1. @synchronized创建

+ (Singleton *)sharedSingleton {    static Singleton *single = nil;    //考虑线程安全    @synchronized(self){        if (single == nil) {            single = [[self alloc] init];        }    }    return single;}

  

    2. gcd创建

+ (id)sharedInstance {    static dispatch_once_t onceToken;    static id single = nil;    dispatch_once(&onceToken, ^{        single = [[self alloc] init];    });    return single;}

 

12、 对iOS 中的多线程的理解,什么时候选择使用GCD,什么时候选择NSOperation?

戳这里:iOS多线程总结    iOS多线程详解

 

13、 对iOS中绘图和动画的理解

在IOS开发中 苹果公司向开发者提供了强大的框架来处理图形和动画,这些框架和技术有:

  UIKit:cocoa touch 框架,高层次的框架,允许开发人员创建视图、窗口、按钮和其他UI组件。同时将一些低级别的api引入到易于使用的高级别API中。

  Quartz 2D:IOS上绘图的主要引擎;UIKit上就使用Quartz。

  Core Graphics:它支持图形上下文、加载图像、绘制图像,等等。

  Core Animation 帮助开发者在IOS上实现动画的框架。

戳这里:iOS上的图形和动画理解

 

 

14、 runloop和线程有什么关系?说说对runloop的理解

  1. 线程和 RunLoop 之间是一一对应的。

  2. 默认主线程RunLoop自动开启,main函数里面的UIApplicationMain()函数会为主线程设置一个NSRunLoop对象。

  3. 其他线程RunLoop需要手动开启。如果需要多线程交互可以手动配置和启动。如果线程只是去执行一个长时间的已确定的任务则不需要。

  4. RunLoop 实际上就是一个对象,每个线程的RunLoop都可以通过[NSRunLoop currentRunLoop]获取,这个对象管理了其需要处理的事件和消息,并提供了一个入口函数来执行上面 Event Loop 的逻辑。线程执行了这个函数后,就会一直处于这个函数内部 "接受消息->等待->处理" 的循环中,直到这个循环结束,函数返回

戳这里:RunLoop-Developer-Apple    深入理解RunLoop

 

原创粉丝点击