Android高频面试题:该怎样在Android面试中聊聊多线程不被忽悠?

浩浩
• 阅读 900

Android高频面试题:该怎样在Android面试中聊聊多线程不被忽悠?

多线程可以说是Android面试的高频问题了,而多线程涉及的内容非常多,因此在面试当中往往不知道从何说起,本文并不是为了科普多线程或者研究多线程的知识,而是尝试组织语言以便在面试当中更好地忽悠面试官。

语言表达在面试当中虽说很重要, 不过更重要的还是相关知识技能过硬。

假如在一场Android面试当中,面试官让你聊聊多线程,你可以试试这样回答。

Android中的线程

在Android当中, 当应用启动的时候,系统会给应用分配一个进程,顺便一提, 大部分应用都是单进程的,不过也可以通过设置来使不同组件运行在不同的进程中,在创建进程的同时会创建一个线程,应用的大部分操作都会在这个线程中运行,所以称为主线程,同时所有的UI控件相关的操作也要求在这个线程中操作,所以也称为UI线程

UI线程和工作线程

因为所有的UI控件的操作都在UI线程中执行,如果在UI线程中执行耗时操作,例如网络请求等,就会阻塞UI线程,导致系统报ANR(Application Not Response)错误。因此对于耗时操作需要创建工作线程来执行而不能直接在UI线程中执行。这样就需要在应用中使用多线程,但是Android提供的UI工具包并不是线程安全的,也就是说不能直接在工作线程中访问UI控件,否则会导致不能预测的问题,因此需要额外的机制来进行线程交互,主要是让其他线程可以访问UI线程。

线程交互 - Handler机制

在Android当中,工作线程主要通过Handler机制来访问UI线程。当然还有一些封装好的类例如AsyncTask可以使用,但是本质仍是使用Handler。

Handler机制主要由4部分组成,Looper,消息队列,消息类和Handler组成,其中Looper和消息队列是和线程绑定的,每个线程只会有一个Looper和一个消息队列,当Looper启动时,它会无限循环尝试从消息队列中获取消息实例,如果没有消息则会阻塞等待。当Handler发送消息时会把消息实例放入消息队列中,Looper从中取得消息实例然后就会调用Handler的相关方法,因为Looper是线程绑定的,如果绑定的是UI线程,那么此时Handler的方法就会在UI线程中得到执行,线程间就是这样进行交互的。

java中的线程

而Handler机制的底层实现则是使用java多线程相关的类。

java当中主要使用Thread和Executor来实现多线程。Thread用于直接创建线程,在Android中也可以直接使用这个类,Looper中就包含一个Thread实例。Executor是一个接口,大部分java中自带的实现都使用了线程池来管理多线程。

线程池

因为在系统中创建线程是一个比较耗费资源的事,所以不能频繁创建和释放线程,因此在效率上考虑通常会使用线程池,同时也便于线程的管理。Android中的AsyncTask就使用了线程池。

线程安全

另一个在使用多线程时需要注意的是线程安全的问题,因为同一进程中的线程可以共享内存,虽然这种方式效率很高,但是会导致线程干扰和内存一致性的问题。

解决这些问题的主要方法是使用Synchronized关键字来加锁。基本原理就是线程要对对象进行操作前需要先获取锁,如果一个线程正在操作某个对象,那么它就会持有相应的锁,后来的线程想要操作这个对象,只能等待前面的线程释放锁之后才有机会获取锁并进行操作。

死锁和活锁

引入锁之后仍有可能出现一些问题,例如死锁,饥饿(Starvation)和活锁。

多线程工具包

同时java还提供不少工具来使用多线程,例如刚刚提到的Executor,另外常用的还有线程安全的集合,例如ConcurrentMap,可以用来避免内存一致性的问题。

如果你是面试官,你被忽悠到了吗?欢迎在讨论区说说你的看法。

最后

以上面试中问到的题目基本上都可以在上面找到答案,所以做准备是很重要的,但技术是一点点积累的,就算你全会背了,面试过了,真正等到工作的时候还是会捉襟见肘的,所以踏实点吧骚年。

最后为了帮助大家深刻理解Android相关知识点的原理以及面试相关知识,这里放上相关的我搜集整理的24套腾讯、字节跳动、阿里、百度2019-2020BAT 面试真题解析,我把大厂面试中常被问到的技术点整理成了视频和PDF(实际上比预期多花了不少精力),包知识脉络 + 诸多细节。

还有 高级架构技术进阶脑图 帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。

点赞
收藏
评论区
推荐文章
Jacquelyn38 Jacquelyn38
1年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。 1、使用解构获取json数据let jsonData   id: 1, status: "OK", data: ['a', 'b'] ; let  id, status, data: number   jsonData; console.log(id, status, number )
blmius blmius
1年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录 问题 用navicat导入数据时,报错: 原因这是因为当前的MySQL不支持datetime为0的情况。 解决修改sql\mode: sql\mode:SQL Mode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。 全局s
Stella981 Stella981
1年前
Opencv中Mat矩阵相乘——点乘、dot、mul运算详解
Opencv中Mat矩阵相乘——点乘、dot、mul运算详解 ============================== 2016年09月02日 00:00:36 [\-牧野-](https://www.oschina.net/action/GoToLink?url=https%3A%2F%2Fme.csdn.net%2Fdcrmg) 阅读数:59593
Easter79 Easter79
1年前
swap空间的增减方法
(1)增大swap空间 去激活swap交换区: #swapoff -v /dev/vg00/lvswap 扩展交换lv: #lvextend -L 10G /dev/vg00/lvswap 重新生成swap交换区: #mkswap /dev/vg00/lvswap 激活新生成的交换区: #swapon -v /dev/vg00/lvswap
Stella981 Stella981
1年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置 1、virsh edit centos7 找到“memory”和“vcpu”标签,将 <name>centos7</name> <uuid>2220a6d1-a36a-4fbb-8523-e078b3dfe795</uuid>
Easter79 Easter79
1年前
Twitter的分布式自增ID算法snowflake (Java版)
概述 == 分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。 有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。 而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
1年前
MySQL查询按照指定规则排序
1.按照指定(单个)字段排序 select * from table_name order id desc; 2.按照指定(多个)字段排序 select * from table_name order id desc,status desc; 3.按照指定字段和规则排序 selec
Wesley13 Wesley13
1年前
Java日期时间API系列36
  十二时辰,古代劳动人民把一昼夜划分成十二个时段,每一个时段叫一个时辰。二十四小时和十二时辰对照表: **时辰** **时间** **24时制** 子时 深夜 11:00 - 凌晨 01:00 23:00 - 01 :00 丑时 上午 01:00 - 上午 03:00 01:00 - 03 :00 寅时 上午 03:00 - 上午 0
Stella981 Stella981
1年前
Angular material mat
Icon Icon Name mat-icon code _add\_comment_ add comment icon <mat-icon> add\_comment</mat-icon> _attach\_file_ attach file icon <mat-icon> attach\_file</mat-icon> _attach\
Wesley13 Wesley13
1年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
#### 背景描述 # Time: 2019-01-24T00:08:14.705724+08:00 # User@Host: **[**] @ [**] Id: ** # Schema: sentrymeta Last_errno: 0 Killed: 0 # Query_time: 0.315758 Lock_
helloworld_34035044 helloworld_34035044
4个月前
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。 uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid() 或 uuid(sep)参数说明:sep 布尔值,生成的uuid中是否包含分隔符'',缺省为