乐趣区

关于android:史上最全的Android面试题集锦十

原文链接:https://blog.csdn.net/xiangzh…

5、类加载器

程序在启动的时候,并不会一次性加载程序所要用的所有 class 文件,而是依据程序的须要,通过 Java 的类加载机制(ClassLoader)来动静加载某个 class 文件到内存当中的,从而只有 class 文件被载入到了内存之后,能力被其它 class 所援用。所以 ClassLoader 就是用来动静加载 class 文件到内存当中用的。

5.1、双亲委派原理
每个 ClassLoader 实例都有一个父类加载器的援用(不是继承关系,是一个蕴含的关系),虚拟机内置的类加载器(Bootstrap ClassLoader)自身没有父类加载器,然而能够用做其余 ClassLoader 实例的父类加载器。

当一个 ClassLoader 实例须要加载某个类时,它会试图在亲自搜寻这个类之前先把这个工作委托给它的父类加载器,这个过程是由上而下顺次查看的,首先由顶层的类加载器 Bootstrap CLassLoader 进行加载,如果没有加载到,则把工作转交给 Extension CLassLoader 视图加载,如果也没有找到,则转交给 AppCLassLoader 进行加载,还是没有的话,则交给委托的发起者,由它到指定的文件系统或者网络等 URL 中进行加载类。还没有找到的话,则会抛出 CLassNotFoundException 异样。否则将这个类生成一个类的定义,并将它加载到内存中,最初返回这个类在内存中的 Class 实例对象。

5.2、为什么应用双亲委托模型
JVM 在判断两个 class 是否雷同时,不仅要判断两个类名是否雷同,还要判断是否是同一个类加载器加载的。

防止反复加载,父类曾经加载了,则子 CLassLoader 没有必要再次加载。
思考平安因素,假如自定义一个 String 类,除非扭转 JDK 中 CLassLoader 的搜寻类的默认算法,否则用户自定义的 CLassLoader 如法加载一个本人写的 String 类,因为 String 类在启动时就被疏导类加载器 Bootstrap CLassLoader 加载了。

对于 Android 的双亲委托机制,能够参考 android classloader 双亲委托模式

6、汇合

Java 汇合类次要由两个接口派生出:Collection 和 Map,这两个接口是 Java 汇合的根接口。

Collection 接口是汇合类的根接口,Java 中没有提供这个接口的间接的实现类。然而却让其被继承产生了两个接口,就是 Set 和 List。Set 中不能蕴含反复的元素。List 是一个有序的汇合,能够蕴含反复的元素,提供了按索引拜访的形式。

Map 是 Java.util 包中的另一个接口,它和 Collection 接口没有关系,是互相独立的,然而都属于汇合类的一部分。Map 蕴含了 key-value 对。Map 不能蕴含反复的 key,然而能够蕴含雷同的 value。

6.1、区别
List,Set 都是继承自 Collection 接口,Map 则不是;
List 特点:元素有放入程序,元素可反复; Set 特点:元素无放入程序,元素不可反复,反复元素会笼罩掉,(留神:元素尽管无放入程序,然而元素在 set 中的地位是有该元素的 HashCode 决定的,其地位其实是固定的,退出 Set 的 Object 必须定义 equals() 办法;
LinkedList、ArrayList、HashSet 是非线程平安的,Vector 是线程平安的;
HashMap 是非线程平安的,HashTable 是线程平安的;

6.2、List 和 Vector 比拟
Vector 是多线程平安的,线程平安就是说多线程拜访同一代码,不会产生不确定的后果。而 ArrayList 不是,这个能够从源码中看出,Vector 类中的办法很多有 synchronized 进行润饰,这样就导致了 Vector 在效率上无奈与 ArrayList 相比;
两个都是采纳的线性间断空间存储元素,然而当空间有余的时候,两个类的减少形式是不同。
Vector 能够设置增长因子,而 ArrayList 不能够。
Vector 是一种老的动静数组,是线程同步的,效率很低,个别不赞成应用。

6.3、HashSet 如何保障不反复
HashSet 底层通过 HashMap 来实现的,在往 HashSet 中增加元素是

`public boolean add(E e) {
return map.put(e, PRESENT)==null;
}

// Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object();
`

在 HashMap 中进行查找是否存在这个 key,value 始终是一样的,次要有以下几种状况:

  • 如果 hash 码值不雷同,阐明是一个新元素,存;
  • 如果 hash 码值雷同,且 equles 判断相等,阐明元素曾经存在,不存;
  • 如果 hash 码值雷同,且 equles 判断不相等,阐明元素不存在,存;
  • 如果有元素和传入对象的 hash 值相等,那么,持续进行 equles()判断,如果依然相等,那么就认为传入元素曾经存在,不再增加,完结,否则依然增加;

6.4、HashSet 与 Treeset 的实用场景

  • HashSet 是基于 Hash 算法实现的,其性能通常都优于 TreeSet。为疾速查找而设计的 Set,咱们通常都应该应用 HashSet,在咱们须要排序的性能时,咱们才应用 TreeSet。
  • TreeSet 是二叉树(红黑树的树据构造)实现的,Treeset 中的数据是主动排好序的,不容许放入 null 值
  • HashSet 是哈希表实现的,HashSet 中的数据是无序的,能够放入 null,但只能放入一个 null,两者中的值都不能反复,就如数据库中惟一束缚。
  • HashSet 是基于 Hash 算法实现的,其性能通常都优于 TreeSet。为疾速查找而设计的 Set,咱们通常都应该应用 HashSet,在咱们须要排序的性能时,咱们才应用 TreeSet。

6.5、HashMap 与 TreeMap、HashTable 的区别及实用场景
HashMap 非线程平安,基于哈希表(散列表) 实现。应用 HashMap 要求增加的键类明确定义了 hashCode()和 equals()[能够重写 hashCode()和 equals()],为了优化 HashMap 空间的应用,您能够调优初始容量和负载因子。其中散列表的抵触解决次要分两种,一种是凋谢定址法,另一种是链表法。HashMap 的实现中采纳的是链表法。
TreeMap:非线程平安基于红黑树实现,TreeMap 没有调优选项,因为该树总处于均衡状态

点击下方链接收费获取 Android 进阶材料:

https://shimo.im/docs/tXXKHgd…

退出移动版