24.任务与队列的几个面试题
一、 我们先看个面试题热热身
面试题一 - 串行队列
下面的打印输出会是什么样?
/// 串行队列
dispatch_queue_t queue = dispatch_queue_create("Ryukie.Queue", DISPATCH_QUEUE_SERIAL);
dispatch_async(queue, ^{
NSLog(@"1");
});
dispatch_async(queue, ^{
NSLog(@"2");
});
dispatch_sync(queue, ^{
NSLog(@"3");
});
NSLog(@"0");
dispatch_async(queue, ^{
NSLog(@"7");
});
dispatch_async(queue, ^{
NSLog(@"8");
});
dispatch_async(queue, ^{
NSLog(@"9");
});
A: 1230789
B: 1237890
C: 3120789
D: 2137890
分析
3
的同步任务,阻碍了0 7 8 9
的异步任务,故3
一定在0 7 8 9
前。7 8 9
三个任务的顺序不一定,但在0
之后。1 2 3
的顺序不一定。
满足上面几点的答案为:A C
这里很可能会觉得
12
一定在3
之前,要清楚3
阻塞的是3
之后的任务,123
的顺序并不一定。
如果是异步队列呢?
123 789 都是乱序的
面试题二 - while
输出会是多少呢?
__block int num = 0;
while (num < 10) {
dispatch_async(dispatch_get_global_queue(0, 0), ^{
num++;
});
}
printf("%d\n", num);
由于 num++ 是异步的,所以执行的次数大于等于 10
由于 while 循环条件阻塞,打印一定在 num >= 10 条件下输出
输出大于等于 10

面试题三 - for
输出会是多少呢?
__block int num = 0;
for (int i = 0; i < 1000; i++) {
dispatch_async(dispatch_get_global_queue(0, 0), ^{
num++;
});
}
printf("%d\n", num);
for 循环保证了循环次数,一定是1000次
for循环不会阻塞后面的 printf 函数执行
故:打印结果小于等于 1000(可能打印的时候还有 ++ 任务未执行完)

面试题三 - 死锁
下面几个分别输出是什么
- (void)deadLock1 {
// dispatch_queue_t queue = dispatch_queue_create("Ryukie", NULL);
dispatch_queue_t queue = dispatch_queue_create("Ryukie", DISPATCH_QUEUE_SERIAL);
NSLog(@"1");
dispatch_async(queue, ^{
NSLog(@"2");
dispatch_sync(queue, ^{
NSLog(@"3");
});
NSLog(@"4");
});
NSLog(@"5");
}
输出
1,5,2 死锁
分析
串行队列
async 放入队列一个 blockA 任务
blockA 内部又向队列内部添加了一个 blockB 任务
队列需要等待 blockA 执行完毕再执行下一个任务
但是添加 blockB 时,sync 阻断了 blockA 内部的执行,导致 blockA 无法执行完成
所以死锁了
- (void)deadLock2 {
dispatch_queue_t queue = dispatch_queue_create("Ryukie", DISPATCH_QUEUE_CONCURRENT);
NSLog(@"1");
dispatch_async(queue, ^{
NSLog(@"2");
dispatch_sync(queue, ^{
NSLog(@"3");
});
NSLog(@"4");
});
NSLog(@"5");
}
输出
1,5,2,3,4
- (void)deadLock3 {
// dispatch_queue_t queue = dispatch_queue_create("Ryukie", NULL);
dispatch_queue_t queue = dispatch_queue_create("Ryukie", DISPATCH_QUEUE_SERIAL);
NSLog(@"1");
dispatch_async(queue, ^{
NSLog(@"2");
dispatch_sync(queue, ^{
NSLog(@"3");
});
});
NSLog(@"5");
}
输出
1,5,2 死锁
和第一个一样
- (void)deadLock4 {
dispatch_queue_t queue = dispatch_queue_create("Ryukie", DISPATCH_QUEUE_SERIAL);
NSLog(@"1");
NSLog(@"2");
dispatch_sync(queue, ^{
NSLog(@"3");
});
NSLog(@"4");
NSLog(@"5");
}
输出
1,2,3,4,5
串行队列
同步任务,没有阻塞队列内任务的执行,没有死锁,正常执行
所以 同步任务 + 串行队列 不一定死锁
二、 任务与队列

Last updated
Was this helpful?