2、android面试线程 & 多线程

600 阅读4分钟

今天我们从面试的角度谈谈线程这个概念,我分享我个人的一些经验,希望能帮助到大家。

主线程

app启动的第一个线程,拥有很高的优先级,是主线程,是ui线程,对于app来说,16ms的帧同步信号需要在此线程调度,用户触摸屏事件需要在此线程响应,动画效果需要在此线程呈现。如果此线程效率不高,就会引发卡顿,掉帧,严重情况甚至会发生ANR。关于主线程会涉及到的面试问题,我个人比较喜欢了解以下几个方面:

  • 主线程是如何判断?机制原理是什么?
  • 主线程交互,AsyncTask、AsyncLayoutInflator、IntentService、Handler等的了解
  • Dialog.show()、Toast.show()、PopWindow.showAtLocation()能不能在非主线程调用?
  • UI组件是不是线程安全的?错误线程操作UI组件会引起什么问题?要如何处理?
  • 什么情况下会引发ANR?如何防护避免ANR?
  • 如何监控UI操作耗时?如何检查UI线程卡顿?

针对上面的问题,我们还可以追问一句,请举例说明/你平时有解决过/你是怎么应用的,这样可以进一步挖掘候选人编程习惯/风格,解决问题的思路/能力,临场分析/应对能力。如果候选人能一劳永逸,建立系统方案从代码检测到问题解决,那水平就很高。

工作线程

工作线程是主线程以外的一个概念,用户处理耗时问题。i/o操作,耗时操作,阻塞操作等就在此线程编写。这是一个与主线程对称的线程概念,我们就工作线程而言,已经没有太多的问题。于我个人而言,会了解一下候选人下面几个情况:

  • 启动线程的方式有多少种,请列举一下。你平时是使用哪一种?为什么?
  • 请简单介绍一下Service和IntentService的区别。
  • 你是如何终止一个线程的执行的?
  • 请你给出一个方案,如何监控统计一个线程的执行时间?
  • 如何获得线程异常的线程堆栈信息?

如果想继续深入了解候选人的技能,还可以试着了解:

  • 请简单介绍一下线程的几种状态?
  • 请说详细明一下线程挂起/线程睡眠吗?
  • sleep()、wait()、yield()有什么区别?
  • notify()、notifyAll()有什么区别?
  • 线程阻塞会有多少种实现方式?

可能还有其他的深入的知识点问题没有涉及到,请大家自行补充。

线程池

上面都是单独介绍一个单独的线程实例,关于线程池的知识就会突然增加,因为还包含了线程管理,通信,数据安全,同步,工作任务的协同。我们简单来列一下问题,答案在网上都有。

  • 线程池的分类,针对线程池参数进行详细追问。你平时怎么使用?
  • 线程安全的概念,以及如何保障线程安全?根据性能和效率继续追问。
  • concurrent包的了解以及使用。举例说明。
  • 线程协同。多个线程按顺序执行方案如何实现?
  • 线程滥用引发oom问题以及处理方式?
  • 如果涉及三方库使用,详细了解原理和源码逻辑。
  • 死锁的概念?死锁的条件?死锁如何检测?如何避免?
  • 锁的概念?锁的分类,公平/非公平,乐观/悲观等

线程池分类这里,很多人会不知道还有ForkJoinPool这个类型。另外可以针对性考察候选人对线程池的适用场景,譬如CachedThreadPool适用什么场景?在什么著名框架使用到?源码分析一下?

线程协同也有很复杂的应用场景,譬如音视频两种数据的处理协同,数据包如何分片,音频和视频如何同步?

如何统一app的线程池?如何阻断线程导致的内存泄漏?

协程

对于android来说这是一个新的概念,kotlin引入之后才有,如果说线程是进程概念的细分,那么协程就是线程概念的细分,大家可以去看看。关于kotlin协程,我会了解以下几个情况

  • 启动协程有多少种方式?
  • Flow和Channel的情况?为什么说flow是冷的,channel是热?
  • 协程的实现机制?suspend关键字的含义?
  • 参数为什么是any?
  • 协程异常处理?

暂时想到就这么多,后续再补充。