Android --- 第十一期面试题

mac2026-02-02  0

每日Android面试题

1、HashMap与TreeMap、HashTable的区别及适用场景?

HashMap: 非线程安全

HashMap:基于哈希表(散列表)实现。

使用HashMap要求添加的键类明确定义了hashCode()和equals()

[可以重写hashCode()和equals()]

为了优化HashMap空间的使用,可以调优初始容量和负载因子。

其中散列表的冲突处理主要分两种,

一种是开放定址法,另一种是链表法。HashMap的实现中采用的是链表法。

TreeMap:非线程安全基于红黑树实现。TreeMap没有调优选项,因为该树总处于平衡状态。

适用场景分析:

HashMap和HashTable:HashMap去掉了HashTable的contains方法

但是加上了containsValue()和containsKey()方法

HashTable同步的,而HashMap是非同步的,效率上比HashTable要高。

HashMap允许空键值,而HashTable不允许。

HashMap:适用于Map中插入、删除和定位元素。

Treemap:适用于按自然顺序或自定义顺序遍历键(key)。

2、concurrentHashmap原理,原子类?

ConcurrentHashMap作为一种线程安全且高效的哈希表的解决方案尤其其中的"分段锁"的方

相比HashTable的全表锁在性能上的提升非常之大.

ConcurrentHashMap 有 16 个 Segments

所以理论上,这个时候,最多可以同时支持 16 个线程并发写

只要它们的操作分别分布在不同的 Segment 上

这个值可以在初始化的时候设置为其他值,但是一旦初始化以后,它是不可以扩容的。

再具体到每个 Segment 内部,其实每个 Segment 很像之前介绍的 HashMap,不过它要保证线程安全,所以处理起来要麻烦些。

initialCapacity:初始容量,这个值指的是整个 ConcurrentHashMap 的初始容量,实际操作的时候需要平均分给每个 Segment。

loadFactor:负载因子,之前我们说了,Segment 数组不可以扩容,所以这个负载因子是给每个 Segment 内部使用的。

Segment 内部是由 数组+链表 组成的。

3、HashSet与Treeset的适用场景?

TreeSet 是二叉树(红黑树的树据结构)实现的

Treeset中的数据是自动排好序的,不允许放入null值。

HashSet 是哈希表实现的,HashSet中的数据是无序的

可以放入null,但只能放入一个null,两者中的值都不能重复,就如数据库中唯一约束。

HashSet要求放入的对象必须实现HashCode()方法

放入的对象,是以hashcode码作为标识的

而具有相同内容的String对象,hashcode是一样,所以放入的内容不能重复

但是同一个类的对象可以放入不同的实例。

适用场景分析:

① HashSet是基于Hash算法实现的,其性能通常都优于TreeSet。

② 为快速查找而设计的Set,我们通常都应该使用HashSet

③ 在我们需要排序的功能时,我们才使用TreeSet。

多线程

1、什么是并发什么是并行

并行:多个cpu实例或者多台机器同时执行一段处理逻辑

并发:通过cpu调度算法,让用户看上去同时执行,实际上从cpu操作层面不是真正的同时。

并发往往在场景中有公用的资源,那么针对这个公用的资源往往产生瓶颈

我们会用TPS或者QPS来反应这个系统的处理能力。

Android针对并发一般都是采用静态页面的策略

2、什么是线程安全

线程安全:在并发的情况之下,该代码经过多线程使用,线程的调度顺序不影响任何结果。

这个时候使用多线程,我们只需要关注系统的内存,cpu是不是够用即可。

线程不安全:反过来,线程不安全就意味着线程的调度顺序会影响最终结果

3、什么是同步异步?

同步:就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回

要想实现同步操作,必须要获得线程的对象锁。

获得它可以保证在同一时刻只有一个线能够进入临界区,并且在这个锁被释放之前,其他的线程都不能再进入这个临界区。

如果其他线程想要获得这个对象的锁,只能进入等待队列等待。 只有当拥有该对象锁的线程退出临界区时,锁才会被释放,等待队列中优先级最高的线程才能获得该锁。

实现同步的方式有两种:同步方法、同步代码块。

异步:当一个异步过程调用发出后,调用者不会立刻得到结果。

实际处理这个吊用的部件是在调用发出后,通过状态、通知来通知调用者,或通过回调函数处理这个调用。

由于每个线程都包含了运行时自身所需要的数据或方法,

因此,在进行输入输出时,不必关系其他线程的状态或行为,也不必等到输入输出处理完毕才返回。

当应用程序在对象上调用了一个需要花费很长时间来执行的方法,并且不希望让程序等待方法的返回时,就应该使用异步编程,异步能够提高程序的效率。

4、什么是线程阻塞?

阻塞:阻塞调用是指调用结果返回之前,当前线程会被挂起。函数只有在得到结果之后才会返回。

非阻塞:指在不能立刻得到结果之前,该函数不会阻塞当前线程,而会立刻返回。

5、同步和阻塞有什么关系?

同步与阻塞同步是个过程

阻塞是线程的一种状态。

多个线程操作共享变量时可能会出现竞争。

这时需要同步来防止两个以上的线程同时进入临界区

在这个过程中,后进入临界区的线程将阻塞,等待先进入的线程走出临界区。

最新回复(0)