侧边栏壁纸
博主头像
伯虔

追求源于热爱,极致源于梦想!

  • 累计撰写 98 篇文章
  • 累计创建 30 个标签
  • 累计收到 4 条评论

目 录CONTENT

文章目录

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

伯虔
2016-11-23 / 0 评论 / 0 点赞 / 694 阅读 / 14,653 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2022-03-27,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。
  1. 「Timhbw博客」iOS基础问答面试题连载(一)-附答案
  2. 「Timhbw博客」iOS基础问答面试题连载(二)-附答案
  3. 「Timhbw博客」iOS基础问答面试题连载(三)-附答案
  4. 「Timhbw博客」iOS基础问答面试题连载(四)

以下是一些自己收集的比较基础的问题(大神可以忽略),附上答案,方便大家阅读。俗话说得好,基础不牢,地动山摇。文章末尾会提供PDF版的文档,方便大家木有网的时候也可以用移动设备观看。

面试题

11月24日修正一处错误:18、19题目一样,答案不一样(其实是两种理解,修改为最优的一种放上来.多谢读者提醒)

以下是一些自己收集的网络多线程方面比较基础的问题(大神可以忽略),附上答案,方便大家阅读。俗话说得好,基础不牢,地动山摇。文章末尾会提供PDF版的文档,方便大家木有网的时候也可以用移动设备观看。

1.请简单说明多线程技术的优点和缺点?

  • 优点:
    能够适当提高程序的执行效率;
    能够适当的提高资源的利用率,比如CPU、内存。

  • 缺点:
    创建线程有额外开销
    程序的代码更加复杂
    线程越多,CPU在调度线程上的开销就越大
    如果开启大量线程,反而会降低程序的性能

2.请简单说明线程和进程,以及他们之间的关系?

进程是CPU调度和分配资源的单位。
线程是CPU调用的最小单位
关系:
进程包含线程;
一个程序可以对应多个进程,一个进程中可以有多个线程,但至少要有一个线程;
同一个进程内的线程共享进程的资源。

3.请简单说明在iOS开发中有哪些多线程的实现方案?

  • PThread
  • NSThread
  • GCD
  • NSOperation

4.请简单说明主线程的作用,以及使用注意点?

主线程:默认启动的线程
作用:(1)显示和刷新UI界面 (2)处理UI事件
注意点:
不要将耗时操作放在主线程中执行
UI操作必须在主线程中执行 !!!

5.请简单列出NSThread线程的几种状态,并说明状态转换的逻辑?

新建->就绪 CPU调度当前任务->运行->阻塞->死亡
CPU调度其他任务->就绪

6.请简单说明如何简单的解决多线程访问同一块资源造成的线程安全的问题,以及注意点?

加同步(互斥)锁,
@synchronized
OC中的同步锁:(锁对象) + {要锁住的代码}
锁对象:要求是全局唯一的属性
注意点:
要注意加锁的位置
加锁需要耗费性能,因此需要注意加锁的条件(多线程访问同一块资源)
专业术语:线程同步

7.请简单介绍下什么是原子和非原子属性?

  • atomic:原子属性,会为setter方法加锁,默认为atomic。线程安全,会消耗大量资源
  • nonatomic:非原子属性,不会为setter方法加锁。非线程安全,适合内存小的移动设备。

8.请简单介绍下GCD这门技术?

  • 全称 Grand Central Dispatch,中枢调度器。
  • GCD中有2个核心概念:任务和队列。
  • GCD使用:封装任务,将封装好的任务添加到队列中,遵循FIFO。

9.请简单介绍GCD中的几种队列?(4种)

并发队列:多个任务同时执行,会开启多个线程同时执行任务,只有在异步函数下才有效。
串行队列:任务只能一个接一个的去执行,不会开启多个线程,主队列属于串行队列,主队列所有的任务必须在主线程中执行。
全局队列
主队列

10.如果当前有多个任务,这些任务都需要开子线程执行,而多个任务之间有一定的依赖关系,如果使用GCD来实现请试着给出一些解决方案。

使用异步函数(同步函数)+主队列

11.请简单说明单例模式的特点(作用)?

如果一个类实现了单例,那么可以保证在程序运行过程,一个类只有一个实例
单例对象易于供外界访问(通常会提供一个类方法)
实现了单例模式后,可以方便地控制了实例个数,并节约系统资源

12.请简单介绍操作队列?

操作队列本身是OC语言的,在iOS开发中可以用来实现多线程编程
操作队列有两大核心的概念,一个是操作(NSOperation),一个是队列(NSOperationQueue),操作用来封装任务,队列用来存放操作
要使用操作队列进行多线程编程,只需要把封装好的操作提交到相应的队列中即可,系统内部会视情况自动开启相应的线程来执行任务
在操作队列这门技术中,系统提供了两个子类可以来封装任务,一个是NSInvocationOperation,一个是NSBlockOperation,除此之外也可以直接自定义操作
操作队列中有两种队列,一种是通过[NSOperationQueue mainQueue]获得的主队列,一种是通过[[NSOperationQueue alloc]init]方法获得的非主队列
主队列是和主线程相关的串行队列,提交到主队列中的操作将被安排在主线程中执行(可以利用该特性来处理线程间通信的相关逻辑)
操作+队列:
NSInvocationOperation
NSBlockOperatio
NSOperationQueue
自己创建 [[NSOperationQueue alloc]init];
主队列   [NSOperationQueue main];

13.如果有多个操作如何来设置依赖关系,如何监听到某个操作执行完毕事件?

设置依赖关系:假设有有两个操作分别是op1和op2,op1需要依赖于op2,那么只需要使用[op1 addDependency:op2]方法设置即可。
操作依赖补充:使用操作队列可以方便的指定多个操作间的依赖关系,甚至可以实现跨队列的操作依赖,但是在使用的时候需要注意操作之间不能有循环依赖关系
操作监听:可以使用^completionBlock来实现操作监听

14.请简单比较GCD中的全局并发队列和使用dispatch_queue_create函数创建的并发队列异同?

全局并发队列在整个应用程序中本身是默认存在的并且对应有高优先级、默认优先级、低优先级和后台优先级一共四个并发队列,我们只是选择其中的一个直接拿来用。而Create函数是实打实的从头开始去创建一个队列。
在iOS6.0之前,在GCD中凡是使用了带Create和retain的函数在最后都需要做一次release操作。而主队列和全局并发队列不需要我们手动release。当然了,在iOS6.0之后GCD已经被纳入到了ARC的内存管理范畴中,即便是使用retain或者create函数创建的对象也不再需要开发人员手动释放,我们像对待普通OC对象一样对待GCD就OK。
在使用栅栏函数的时候,栅栏函数只有在和使用create函数自己的创建的并发队列一起使用的时候才有效
其它区别涉及到XNU内核的系统级线程编程,不一一列举。

15.请简单说明对图片进行二级缓存的实现思路?

在显示图片的时候

1.先检查该图片对应的内存缓存

1.如果存在内存缓存,则

a.直接使用设置并显示图片;

2.如果内存缓存中没有,则

a.继续检查该图片对应的磁盘缓存是否存在,跳转到第2步。

2.检查该图片对应的磁盘缓存

1.如果存在磁盘缓存,则

a.先保存一份到内存缓存中(方便下次使用)

b.然后设置并显示图片

2.如果不存在磁盘缓存,则直接下载该图片,下载完成后

a.保存一份到内存缓存中

b.保存一份到磁盘缓存中

c.设置并显示图片

16.请简单对比下GCD和NSOperation两种多线程的实现方案?

GCD是纯C语言的API,而操作队列则是Object-C的对象。
在GCD中,任务用块(block)来表示,而块是个轻量级的数据结构;相反操作队列中的『操作』NSOperation则是个更加重量级的Object-C对象。
具体该使用GCD还是使用NSOperation需要看具体的情况,如果只是想简单开一个子线程执行任务推荐使用GCD,如果有很多任务需要开多个子线程下载推荐使用操作队列

17.请按照自己的理解,说一说在进行多线程编程的时候相对于GCD而言,操作队列有哪些优势?

NSOperation和NSOperationQueue的好处有:
NSOperationQueue可以方便的调用cancel方法来取消某个操作,而GCD中的任务是无法被取消的(安排好任务之后就不管了)。
NSOperation可以方便的指定操作间的依赖关系。
NSOperation可以通过KVO提供对NSOperation对象的精细控制(如监听当前操作是否被取消或是否已经完成等)
NSOperation可以方便的指定操作优先级。操作优先级表示此操作与队列中其它操作之间的优先关系,优先级高的操作先执行,优先级低的后执行。
通过自定义NSOperation的子类可以实现操作重用

18.请谈一谈,自定义操作的好处?

自定义操作,对操作进行封装,那么以后在使用的时候只需要alloc init即可,创建该操作的人不需要关系内部的代码实现,信息隐蔽。
自定义操作有助于代码重用

19.请简单介绍GCD中的一次性代码?

一次性代码:
static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

NSLog(@“-------”);

});
2.特点:

在整个程序运行过程中block中的代码只会被执行一次

一次性代码本身是线程安全的

3.常用于单例模式的实现中

20.GCD中的dispatch_after是延迟把任务提交到队列还是先提交到队列再延迟执行?

是延迟之后在把任务提交到队列执行,把任务提交到队列中在延迟执行难度较大,不容易实现.

21.请