面试:Handler的工作原理是怎样的?
Handler机制工作原理:
Handler 工作流程基本包括 Handler、Looper、Message、MessageQueue 四个部分。但我们在日常开发中,经常都只会用到 Handler 和 Message 两个类。Message 负责消息的搭载,里面有个 target 用于标记消息,obj 用于存放内容,Handler 负责消息的分发和处理。
下面具体给你讲解一下:
Handler机制是由Looper和MessageQueue来构建消息机制的。
MessageQueue:消息队列。虽然名为队列,但事实上它的内部存储结构并不是真正的队列,而是采用单链表的数据结构来存储消息列表的,其中主要有插入enqueue()和从中拿走并删除next()两个方法。
Looper:消息循环。MessageQueue来存储消息,Looper则是以无限循环的方式去查找是否有新消息,如有就去处理,若没有就standby(等待)。一个线程创建Handler时首先需要创建Looper的,不然报错:RuntimeException: No Looper; Looper.prepare() wasn't called on this thread,而且每个线程下只需要创建一个Looper,不然会报错:RuntimeException: Only one Looper may be created per thread。
面试中回答,建议能自己总结一套自己的专属答案,并理解透,那样当遇到这个问题,就能回答的游刃有余!
为什么用树不用链表?
树和链表都是数据结构中比较常见的存储模型,使用什么作为存储的数据结构根据场景,需求而定。
链表是什么?想象一根自行车链条,从中间折断,从一端到另一端刚好就是单向链表结构,在JAVA中每个链表节点作为一个类,属性为自身的数据和下一个节点的引用,一扣接一扣成为一张连续的链表!
链表的查找和删除,修改都需要从头部一个一个比较节点数据,直到找到匹配的那个数为止,很明显这样的查找次数大概为N/2(N为链表节点总数),也就是查询的效率使用大O表示法表示为O(N),线性级别;一个总数为N=1024的链表需要平均比较512次才能做后面的增删改操作,而修改和删除只需要改变节点引用,效率很高!
再来看树结构(以红黑树为例),就是生活中的树倒过来,所有的数据挂在根节点上,通过一定的策略(红黑树通过旋转,变色等,二叉搜索树通过比较父节点)放置在合适的位置上,通常树的深度都是常数级;
红黑树的查询速度是非常快的,因为查询效率为O(log2n),比如上面的1024的数据,最大的查询比较次数为10,效率非常惊人!删除节点也只需要最多三次旋转就可以实现平衡;
以上树结构举例使用红黑树,是因为红黑树是一种性能良好的平衡树,如果是二叉搜索树(规则为比父节点小的放在左子节点,大的放右子节点),如果插入的数据为顺序的,则二叉搜索树就退变为一个链表结构,效率降低!换句话说不是说树结构的查询效率一定比链表好!
在数据量很低的时候,推荐使用链表,因为数据结构简单,开发成本低,效率也不差!
在数据为顺序插入时,不应该使用二叉搜索树,在删除操作频繁的时候,不应该使用二叉搜索树(因为数据重新平衡需要很大的代价),而应该使用红黑树等有保证平衡的策略的树结构;
在数据量大的时候,使用平衡树结构的效率提升是显而易见的,从O(N)到O(log2n)的提升。
在JAVA8中,当hashMap的冲突(某个数组元素中的链表结构很长)达到一定值的时候,将会从链表结构转变为红黑树,提高hashMap的查找性能。
关于更多数据结构的问题,请持续关注,会有其他更多的分享提供,谢谢!
简单来说,所有的数据结构都是为了增删改查,那么数组/链表等线性表的优缺点分别是什么呢?
数组的搜索比较方便,可以直接用下标,但删除或者插入某些元素就比较麻烦。
链表与之相反,删除和插入元素很快,但查找很慢。
这个时候,就需要一个折中方案的产生,此时二叉树就既有链表的好处,也有数组的好处。
在处理大批量的动态的数据是比较有用。
文件系统和数据库系统一般都采用树(特别是B树)的数据结构数据,主要为排序和检索的效率。
平衡二叉树都有哪些应用场景
二叉树支持动态的插入和查找,保证操作时间在Olog(n)内完成,n为节点数。
线性表与二叉树优缺点比较:
顺序存储可能会浪费空间(在非完全二叉树的时候),但是读取某个指定的节点的时候效率比较高O(1)
链式存储相对二叉树比较大的时候浪费空间较少,但是读取某个指定节点的时候效率偏低O(nlogn)

