1、进程和线程的区别?

(1)进程是个静态的容器,可以理解为正在执行的应用程序实例,它里面容纳了很多个线程,线程则是一系列方法的线性执行路径(CPU调度的基本单位)。

(2)进程拥有独立的资源空间(资源分配基本单位),共享起来比较复杂,常使用IPC方式进行同步,同步起来简单,线程间共享所属进程空间,资源共享简单但同步复杂,常使用加锁等方式进行同步。

(3)进程崩溃不会影响其他进程,一个线程崩溃则会导致整个进程崩溃

2、iOS中多线程有几种实现方式?分别有什么区别?

(1)pthread(POSIX Threads):一套C语言编写的跨平台多线程API,使用难度大,需要手动管理线程生命周期。

(2)NSThread:面向对象操作线程,使用相对简单,需要手动管理线程生命周期。

(3)GCD:苹果多核编程解决方案,使用起来非常方便。需要自己实现如:限制并发数,任务间的依赖等功能。自动管理线程生命周期。

(4)NSOperation:基于GCD的封装,面向对象操作线程,提供了比GCD更丰富的API:限制最大并发数,设置任务依赖关系。但是它不能直接使用,因为它是一个抽象类,可以继承它或者使用系统定义NSInvocationOperation或NSBlockOperation。自动管理线程生命周期。

3、NSOperationQueue和GCD有什么区别?
(1) GCD底层是C语言构成的API。NSOperationQueue及相关对象是Objc对象。在GCD中,在队列中执行的是由block构成的任务,这是一个轻量级的数据结构。而NSOperation作为一个对象,为我们提供了更多的选择。

(2) 在NSOperationQueue中,取消任务非常方便,而GCD没法停止已经加入queue的block。

(3) NSOperation能够方便的设置依赖关系,还能设置NSOperation的priority优先级,能够使同一个并行队列中的任务区分先后地执行。在GCD中,我们只能区分不同任务队列的优先级,如果要区分block任务优先级也需要大量复杂代码。
NSOperationQueue还可以设置最大并发数,GCD则需要自己实现。

(4)NSOperation任务状态属性支持KVO,可以通过KVO来监听operation的就绪、取消、执行中、执行完成等状态。GCD则无法判断当前任务执行状态。

4、iOS中线程间如何通信?

线程间通信主要是线程间的同步:
(1)GCD:dispatch_group_t、dispatch_barrier、dispatch_semaphore
(2)NSOperationQueue:任务间添加依赖关系控制同步
(3)线程锁:NSLock、NSRecursiveLock等

涉及到线程异步数据传递:
(1)Mach port:NSMachPort结合RunLoop实现

  • 创建NSMachPort对象并设置代理
  • 将NSMachPort对象添加到RunLoop中
  • 实现NSMachPortDelegate方法
  • 创建一个新线程,在新的线程中调用之前创建的NSMachPort对象,往对应的RunLoop发送消息

(2)NSObject 对象相关API:


performSelector:onThread:withObject:waitUntilDone:modes:
performSelectorOnMainThread:withObject:waitUntilDone:modes:
......

5、iOS中线程有哪几种状态?

新建、就绪、运行、阻塞、死亡


At the application level, all threads behave in essentially the same way as on other platforms.
After starting a thread, the thread runs in one of three main states: running, ready, or blocked.
If a thread is not currently running, it is either blocked and waiting for input or it is ready to run but not scheduled to do so yet.
The thread continues moving back and forth among these states until it finally exits and moves to the terminated state.

6、主队列一定在主线程执行吗?

主队列一定在主线程执行,但主线程执行的任务不一定都是主队列的任务。
在SDWebImage中有下面这么一段宏定义,它就是为了保证任务始终在主队列中执行。


#ifndef dispatch_main_async_safe
#define dispatch_main_async_safe(block)\if (dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL) == dispatch_queue_get_label(dispatch_get_main_queue())) {\block();\} else {\dispatch_async(dispatch_get_main_queue(), block);\}
#endif

7、什么场景下会出现死锁?

同步+串行(主线程)

场景一:同步+主队列[self task1];
dispatch_sync(dispatch_get_main_queue(), ^{[self task2];NSLog(@"同步线程执行主队列任务");
});
[self task3];(1)执行task1
(2)阻塞同步线程,把task2加入到主队列的队尾
(3)task3需要等待task2执行完成后执行,但是此时task2又排在task3后面,所以造成了死锁场景二:异步串行队列嵌套同步串行队列dispatch_queue_t myQueue = dispatch_queue_create("com.bg.sQueue", DISPATCH_QUEUE_SERIAL);
[self task1];
dispatch_async(myQueue, ^{[self task2];dispatch_sync(myQueue, ^{[self task3];});[self task4];
});
[self task5];(1)执行task1
(2)执行task5
(3)执行task2
(4)阻塞同步线程,把task3加入到队列myQueue的队尾
(5)task4需要等待task3执行完成后执行,但是此时task3又排在task4后面,所以造成了死锁场景三:信号量阻塞主线程dispatch_semaphore_t sem = dispatch_semaphore_create(0);
dispatch_async(dispatch_get_main_queue(), ^{dispatch_semaphore_signal(sem);NSLog(@"the sem +1");
});
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
NSLog(@"the sem -1");主线程中dispatch_semaphore_wait一直等着dispatch_semaphore_signal改变信号量(+1操作),但是dispatch_semaphore_wait却阻塞了主线程导致dispatch_semaphore_signal无法执行,从而造成了死锁。

8、多线程中dispatch_barrier_async为什么不能用全局队列?

dispatch_barrier_async必须用自定义的DISPATCH_QUEUE_CONCURRENT队列,如果使用全局队列或同步队列,则起不到栅栏函数的作用,相当于dispatch_async。

9、这段代码会有什么问题:

for (int i = 0; i < 100000; i++) {NSString *queueN = [NSString stringWithFormat:@"c%dqueue", i];dispatch_queue_t cQueue = dispatch_queue_create(queueN.UTF8String, DISPATCH_QUEUE_CONCURRENT);dispatch_async(cQueue, ^{NSLog(@"the queue = %s", dispatch_queue_get_label(cQueue));});
}

上述代码会一下子创建很多线程,造成线程爆炸。类似这种多线程循环执行任务场景,可以使用dispatch_apply来实现,因为dispatch_apply的线程全部由GCD管理。从而避免了手动创建线程爆炸问题。

// 解决线程爆炸​方案
dispatch_queue_t queue = dispatch_queue_create("xxQueue", DISPATCH_QUEUE_CONCURRENT);dispatch_apply(100000, queue, ^(size_t t) {NSLog(@"the current thread = %@, t = %ld", NSThread.currentThread, t);
});

10、GCD的任务能取消吗?

11、自旋锁和互斥锁有什么区别?

12、如何解决多线程安全问题?NSLock是什么锁?

13、如何实现一个常驻线程?(线程保活)

14、如何用GCD实现任务间的依赖?

15、如何使用GCD来实现控制最大并发数?

16、如果需要同时开启3个线程,并按顺序执行任务,使用GCD如何实现?

参考资料:

  • 线程编程指引
  • SDWebImage

完整优秀版请移步小专栏:
iOS面试题(多线程篇)

更多好文推荐,扫描下方的二维码,关注《iOS开发秘籍》公众号,免费解锁完整版

本文内容中部分来自网络,后续会持续更新完善。欢迎一起学习交流!

如需转载,请注明出处

iOS面试题(多线程篇)

iOS面试题(多线程篇)相关推荐

  1. ios 面试题代码篇_iOS面试准备指南快速一周中的30天代码挑战5 5

    ios 面试题代码篇 This is the last week of the 30-Day Code Challenge. I hope you feel your iOS and Swift sk ...

  2. iOS面试题-UI篇

    http://www.360doc.com/content/20/0630/21/31460730_921535347.shtml 这里有关于面试方面汇总:关于iOS面试题汇总(栏目持续更新)http ...

  3. 2021年大厂iOS 面试题 - 前篇

    Swift好多坑,一个人填不来,怎么办 问身边同事吧,又怕被暗笑技术差劲 1.如何追踪app崩溃率,如何解决线上闪退 当iOS设备上的App应用闪退时,操作系统会生成一个crash日志,保存在设备上. ...

  4. iOS面试题02-UI篇

    Size Classes 具体使用 对屏幕进行分类 复制代码 UIView和CALayer是什么关系? UIView显示在屏幕上归功于CALayer,通过调用drawRect方法来渲染自身的内容,调节 ...

  5. iOS开发多线程篇—多线程简介

    iOS开发多线程篇-多线程简介 一.进程和线程 1.什么是进程 进程是指在系统中正在执行的一个应用程序 每一个进程之间是独立的.每一个进程均执行在其专用且受保护的内存空间内 比方同一时候打开QQ.Xc ...

  6. iOS开发多线程篇—自定义NSOperation

    iOS开发多线程篇-自定义NSOperation 一.实现一个简单的tableView显示效果 实现效果展示: 代码示例(使用以前在主控制器中进行业务处理的方式) 1.新建一个项目,让控制器继承自UI ...

  7. iOS开发多线程篇—线程的状态

    iOS开发多线程篇-线程的状态 一.简单介绍 线程的创建: self.thread=[[NSThread alloc]initWithTarget:self selector:@selector(te ...

  8. 面试题汇总二 Java 多线程篇

    前言 题目汇总来源 史上最全各类面试题汇总,没有之一,不接受反驳 面试题汇总一 Java 语言基础篇 面试题汇总二 Java 多线程篇 面试题汇总三 Java 集合篇 面试题汇总四 JVM 篇 面试题 ...

  9. 整理的一篇iOS面试题大全

    #一.基础知识点 1. 设计模式是什么? 你知道哪些设计模式,并简要叙述? 设计模式是一种编码经验,就是用比较成熟的逻辑去处理某一种类型的事情. 1). MVC模式:Model View Contro ...

  10. 【Java实习生面试题系列】-- 多线程篇四

    文章目录 1. 说下对同步器 AQS 的理解? 2. AQS 的原理是什么? 3. AQS 底层使用了模板方法模式,你能说出几个需要重写的方法吗? 4. 说下对 Semaphore.CountDown ...

最新文章

  1. 大数据分布式集群搭建(6)
  2. 2!=5 or 0在python中是否正确-Python 中的 or and 运算,看这一篇就够
  3. 【剑指offer】面试题31:连续子数组的最大和
  4. 美国东北大学khoury计算机学院,2021年美国东北大学计算机研究生专业有哪些?入学要求高吗?...
  5. Pytorch 反向传播实例,梯度下降
  6. io读取文件无地址_流的基本概念和IO流入门
  7. keil复制代码乱码_成都控制器开发:容易忽略!用KEIL编码汉字也会有BUG
  8. Flink之Watermark滑动窗口案例
  9. 黄聪:mysql 存在该记录则更新,不存在则插入记录的sql
  10. 快速打开 Mac OS X 隐藏的用户资源库文件夹
  11. JavaScript基础-前端开发
  12. 推荐两个高仿抖音 App 项目
  13. xdoj-81-字符串查找
  14. 微信中将时间戳转换为聊天时间(二)
  15. 快速在数据库添加一年的日期,区分休息日和工作日
  16. golang 如何快速清空数组
  17. linux查找以c开头的的文件夹,【Linux】 find指令(文件查找)
  18. System.Net.Mail发邮件标题过长出现乱码问题
  19. git bash里ln -s
  20. 简陋无比的 Python 抠图方案,好像还挺像回事儿?

热门文章

  1. 最优化理论与算法(袁亚湘)学习笔记---最优性条件和最优化算法的基本结构
  2. 网络战武器——震网(Stuxnet)病毒
  3. 数学分析(一)数列与数列极限
  4. OA系统新流程创建与管理办法
  5. 华为 IoTDA(物联网平台)如何使用Python SDK 实现应用侧连接
  6. 基础篇:6.10)形位公差-包容原则与可逆原则的标注步骤全解;
  7. 连点脚本java,按键精灵如何设置自动连续点击 自动连点脚本设置教程
  8. 如何设置局域网共享打印机及问题解决
  9. Android开发环境
  10. 微软服务器监控软件,Windows监控,Windows监控软件