iOS的一些面试题分析总结(1)

本篇主要说一下多线程的东西,因为东西比较多,所以直接拿出一整个篇幅来说它了。

3、 多线程的底层实现?

1、先说一下什么是进程,什么是线程、什么是多线程。

进程是资源分配的单位,线程是调度运行的基本单位。多线程简而言之就是一个应用程序中,多个线程同步执行;多用于处理用户界面响应和网络访问的处理的同事进行,通常用子线程处理如网络访问等一些比较耗时的操作,同时不影响主线程在用户界面对用户操作的响应。

2、 Mach

Mach是第一个以多线程方式处理任务的系统,因此多线程的底层实现机制是基于Mach的线程,开发中很少用Mach级的线程,因为Mach级的线程没有提供多线程的基本特征,线程之间是独立的。

3、 开发中实现多线程的方案

1、C语言的pthread

2、OC的NSThread

3、 GCD

4、NSOperation和NSOperationQueue

4、线程间怎么通信?

这里借用这个问题,比较详细的回顾一下比较常用的三种多线程方案: NSThread、GCD、NSOperation和NSOperationQueue。

1、NSThread

先看它的线程间通讯:

1 //去子线程执行耗时任务
2 //    [self performSelectorInBackground:@selector(downloadSomething:) withObject:url];
3
4 //    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(downloadSomething:) object:url];
5 //    // 设置线程的优先级(0.0 - 1.0,1.0最高级)
6 //    //thread.threadPriority = 1.0;
7 //    [thread start];
8
9     [NSThread detachNewThreadSelector:@selector(downloadSomething:) toTarget:self withObject:url];

去子线程执行任务的三种方式。

1 //回到主线程刷新界面
2     //    [self performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:NO];
3
4     //    [self.imageView performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:NO];
5
6     [self.imageView performSelector:@selector(setImage:) onThread:[NSThread mainThread] withObject:image waitUntilDone:NO];

耗时任务执行完毕之后回主线程刷新界面的三种方式。

还有一些其他的简单操作可以去demo看一下,这里就不多赘述了。

NSThread比其他两种多线程方案较轻量级,更直观地控制线程对象。但是需要自己管理线程的生命周期,线程同步。线程同步对数据的加锁会有一定的系统开销。

2、GCD

GCD的线程间通讯:

 1     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
 2
 3         NSData *data = [NSData dataWithContentsOfURL:url];
 4         NSData *data1 = [NSData dataWithContentsOfURL:url1];
 5         UIImage *image = [UIImage imageWithData:data];
 6         UIImage *image1 = [UIImage imageWithData:data1];
 7         dispatch_async(dispatch_get_main_queue(), ^{
 8             self.imageView.image = image;
 9             self.imageView1.image = image1;
10         });
11
12     });

在子线程下载两张图片,回到主线程更新界面。

下面再看一下Dispatch Group:

Dispatch Group可以用来阻塞一个线程, 直到group关联的所有的任务完成执行。适用于有时候你必须等待任务完成的结果,然后才能继续后面的处理的情况。但是下面的这种场景其实个人认为是不需要这么做的,用上面的方式就好了。这里只为演示代码。

 1 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
 2
 3     dispatch_async(queue, ^{
 4         dispatch_group_t group = dispatch_group_create();
 5         dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
 6         __block UIImage *image = nil; //注意block给image赋值,必须加__block前缀
 7         __block UIImage *image1 = nil;
 8         //往组中添加任务
 9         dispatch_group_async(group, queue, ^{
10             NSData *data = [NSData dataWithContentsOfURL:url];
11             image = [UIImage imageWithData:data];
12         });
13         //往组中添加任务
14         dispatch_group_async(group, queue, ^{
15             NSData *data1 = [NSData dataWithContentsOfURL:url1];
16             image1 = [UIImage imageWithData:data1];
17         });
18         // 等待组中的任务执行完毕,回到主线程执行block回调
19         dispatch_group_notify(group, dispatch_get_main_queue(), ^{
20             self.imageView.image = image;
21             self.imageView1.image = image1;
22         });
23     });

还有以下GCD的其他用法,写在demo里了,这里就不再赘述。下面看NSOperation和NSOperationQueue。

3、NSOperation和NSOperationQueue

 1     NSOperationQueue *queue = [[NSOperationQueue alloc] init];
 2
 3     __block UIImage *image0 = nil;
 4     __block UIImage *image1 = nil;
 5
 6     // 创建3个操作
 7     NSOperation *a = [NSBlockOperation blockOperationWithBlock:^{
 8         NSData *data = [NSData dataWithContentsOfURL:url0];
 9         image0 = [UIImage imageWithData:data];
10         NSLog(@"当前调用线程:%@", [NSThread currentThread]);
11     }];
12     NSOperation *b = [NSBlockOperation blockOperationWithBlock:^{
13         NSData *data = [NSData dataWithContentsOfURL:url1];
14         image1 = [UIImage imageWithData:data];
15         NSLog(@"当前调用线程:%@", [NSThread currentThread]);
16     }];
17     NSOperation *c = [NSBlockOperation blockOperationWithBlock:^{
18         [self.imageView performSelectorOnMainThread:@selector(setImage:) withObject:image0 waitUntilDone:NO];
19         [self.imageView1 performSelectorOnMainThread:@selector(setImage:) withObject:image1 waitUntilDone:NO];
20     }];
21
22     // 添加依赖
23     [b addDependency:a];
24 //    [c addDependency:a];
25     [c addDependency:b];
26
27     // 执行操作
28     [queue addOperation:a];
29     [queue addOperation:b];
30     [queue addOperation:c];

GCD和NSOperationQueue都属于不需要自己直接操作线程的,本人一般情况下都直接用GCD比较多,一来因为它高效,二来简洁方便。但是在像上面需要顺序执行,也就是需要用到依赖的时候,用NSOperationQueue比较方便。

同样的,其他关于NSOperation和NSOperationQueue的使用在这里不多赘述,希望再多了解一些的可以自行去demo看一下代码。

demo:https://github.com/alan12138/Interview-question/tree/master/4

5、GCD内部怎么实现的?

1、 iOS和OS X的核心是XNU内核,GCD是基于XNU内核实现的

2、 GCD的API全部在libdispatch库中

3、 GCD的底层实现主要有Dispatch Queue和Dispatch Source

Dispatch Queue :管理block(操作)

Dispatch Source :处理事件

6、 你用过NSOperationQueue么?如果用过或者了解的话,你为什么要使用NSOperationQueue,实现了什么?请描述它和GCD的区别和类似的地方(提示:可以从两者的实现机制和适用范围来描述)。

1、GCD是纯C语言的API,NSOperationQueue是基于GCD的OC版本封装

2、 GCD的执行速度比NSOperationQueue快

3、GCD只支持FIFO的队列,NSOperationQueue可以很方便地调整执行顺序、设置最大并发数量

4、 NSOperationQueue可以在轻松在Operation间设置依赖关系,而GCD需要写很多的代码才能实现

5、 NSOperationQueue支持KVO,可以监测operation是否正在执行(isExecuted)、是否结束(isFinished),是否取消(isCanceld)

6、如何选择:任务之间不太互相依赖:GCD;任务之间有依赖\或者要监听任务的执行情况:NSOperationQueue

7.、既然提到GCD,那么问一下在使用GCD以及block时要注意些什么?它们两是一回事儿么?block在ARC中和传统的MRC中的行为和用法有没有什么区别,需要注意些什么?

Block的使用注意:

1、 block的内存管理(前面的题有讲到block)

2、防止强引用循环

避免强引用循环:

* 非ARC(MRC):__block(还有修改外部临时变量)

*  ARC:__weak\__unsafe_unretained

时间: 2024-10-24 13:24:51

iOS的一些面试题分析总结(1)的相关文章

iOS开发-基础面试题(一) 分类: 面试题

iOS开发-基础面试题(一) 1.Difference between shallow copy and deep copy??浅复制和深复制的区别?? 答:浅层复制:只复制指向对象的指针,而不复制引用对象本身.?深层复制:复制引用对象本身.?意思就是说我有个A对象,复制一份后得到A_copy对象后,对于浅复制来说,A和A_copy指向的是同一个内存资源,复制的只不过是是一个指针,对象本身资源?还是只有一份,那如果我们对A_copy执行了修改操作,那么发现A引用的对象同样被修改,这其实违背了我们

iOS基础问答面试题连载(三)-附答案

「Tim的博客」iOS基础问答面试题连载(一)-附答案 「Tim的博客」iOS基础问答面试题连载(二)-附答案 「Tim的博客」iOS基础问答面试题连载(三)-附答案 「Tim的博客」iOS基础问答面试题连载(四) 这次的问题是网络多线程相关的哟,面试的时候也是必问的,大家多看看 11月24日修正一处错误:18.19题目一样,答案不一样(其实是两种理解,修改为最优的一种放上来.多谢读者提醒) 以下是一些自己收集的网络多线程方面比较基础的问题(大神可以忽略),附上答案,方便大家阅读.俗话说得好,基

CSDN 夏令营程序 试题分析 (2)

题目:若需要在O(nlogn)(以2为底)的时间内完成对数组的排序,且要求排序是稳定的,则可选择的排序方法是: A.快速排序       B.堆排序            C.归并排序  D.直接插入排序 首先咱们来看一下这个表,稳定排序的有直接插入排序.冒泡排序.归并排序和基数排序. 直接插入排序: 最好的情况下:正序有序(从小到大),这样只需要比较n次,不需要移动.因此时间复杂度为O(n) 最坏的情况下:逆序有序,这样每一个元素就需要比较n次,共有n个元素,因此实际复杂度为O(n-2) 平均

关于阿里的一道笔试题分析

其题目如下: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 #pragma pack(2) class A { public:     int i;     union U     {         char buff[13];         int i;     }u;     void foo() {    }     typedef char* (*f)(void*);     enum{red, green, blue} color; }a; class A

上星期IOS的一个面试题。

美丽说面试题 1,IOS是怎样进行内存管理的,什么是ARC. 2,声明Property时,assign,nonatomic,readonly,retain,copy(各什么意思,括号里没打印出来,我猜得) 3,delegate需要retain吗? 4,什么是designated initlalizer?执行[super init]后会发生什么事? 5,isKindOfClass和isMemberOfClass有什么区别? 6,简述UIViewController的生命周期,比较重要的几个方法分别

工厂设计模式的探讨——iOS类簇的应用分析

工厂设计模式的探讨--iOS类簇的应用分析 一.何为设计模式 什么是设计模式,先来看段度娘的话: 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性. 毫无疑问,设计模式于己于他人于系统都是多赢的:设计模式使代码编制真正工程化:设计模式是软件工程的基石脉络,如同大厦的结构一样. 其实我们不需要这么专业,在我的理解,设计模式就是一种规范化的编程习惯,养成了这样的思想与习惯,

iOS开发工程师笔试题

iOS开发工程师笔试题 分类: IOS 面试题2013-01-17 10:28 820人阅读 评论(0) 收藏 举报 随着iOS平台开发的职位的增加,笔试.面试也越来越有“套路”,这里我总结了一些面试题,多数是Objective-C的基础知识,适合于面试新人,答案是我自己答的,不准确的地方,欢迎指出. 1.   Object-c的类可以多重继承么?可以实现多个接口么?Category是什么?重写一个类的方式用继承好还是分类好?为什么? Object-c的类不可以多重继承:可以实现多个接口,通过实

QQ群里收集的外企iOS开发的笔试题

一组外企iOS开发的笔试题,您能回答出来吗?从群里收集来的. 1 why can't NSArray contain NSInteger Instance? with which extra step can you do it?2.complete this code so that it becomes syntacticallty correct using no more than one additional word and  square branckets NsInteger [

试题分析(第三套)

解析:B.需求规格说明阐述一个软件系统必须提供的功能和性能以及它所要考虑的限制条件,它不仅是系统测试和用户文档的基础,也是所有子系列项目规划.设计和编码的基础.它应该尽可能完整地描述系统预期的外部行为和用户可视化行为.除了设计和实现上的限制,软件需求规格说明不应该包括设计.构造.测试或工程管理的细节. 解析:D . 解析:A.应改为创建与之相关的Servlet方法 解析:B.异常类型是ClassNotFoundException 试题分析(第三套)