Android技术面试Java部分
0.集合List、Set、Map的原理?
答:所有的集合类都是Collection接口的子类。Collection有两个子类接口一个是List接口,一个是Set接口。List接口的子类集合是有序集合,可以根据集合中的角标对集合中元素进行操作,可以存在相同元素。而Set接口的子类集合是无序集合,但是他不允许存在相同的元素。
(1)List接口下有三个子类,分别是ArrayList,LinkedList,Vector。
ArrayList底层是数组结构,所以如果数据较大查询的效率较高。LinkedList底层是链表结构,每一个元素都是跟自己前一个和后一个元素发生关系,所以他的增删操作只需要改变与其位置相关联的两个元素关系即可,所以效率比较高。Vector同ArrayList,底层都是数组结构,但是不同的是Vector是线程同步的,在一般情况下回大大降低效率。
(2)Set接口下的子类有HashSet和TreeSet。
HashSet的底层结构是哈希表(实际上是一个HashMap实例)。HashSet集合是通过元素中继承自Object超类的hashCode()方法和equal()方法来判断两个对象是否相同的。TreeSet集合的底层是二叉树数据结构,他不仅不允许相同元素存在,更可以帮我们排序。我们将元素存入TreeSet集合之后他是按照自然顺序排序的。
(3) 另外,Map和Set的原理。
Map是以key-value的形式存取,set以key形式存取,他们的底层都是以红黑树的结构实现,因此插入删除等操作都在O(logn)时间内完成,因此可以完成高效的插入删除。由于是他们的底层是红黑树,因此在插入时候他们会默认执行排序操作,且他们key都是唯一的,因此从这个角度看,他们在某种程度上可以实现过滤重复值和排序(默认升序)的功能。
1.HashMap、HashTable、ConcurrentHashMap的区别?
答:首先,HashTable和HashMap采用相同的存储机制,二者的实现基本一致,不同的是:
(1)HashMap是非线程安全的,HashTable是线程安全的,内部的方法基本都经过synchronized修饰。
(2)因为同步、哈希性能等原因,性能肯定是HashMap更佳,因此HashTable已被淘汰。
(3) HashMap允许有null值的存在,而在HashTable中put进的键值只要有一个null,直接抛出NullPointerException。
(4)HashMap默认初始化数组的大小为16,HashTable为11。前者扩容时乘2,使用位运算取得哈希,效率高于取模。而后者为乘2加1,都是素数和奇数,这样取模哈希结果更均匀。
其次,ConcurrentHashMap它是线程安全的HashMap的实现。HashTable里使用的是synchronized关键字,这其实是对对象加锁,锁住的都是对象整体,当Hashtable的大小增加到一定的时候,性能会急剧下降,因为迭代时需要被锁定很长的时间。ConcurrentHashMap算是对上述问题的优化,其构造函数如下,默认传入的是16,0.75,16。
ConcurrentHashMap引入了分割(Segment),它其实就是把一个大的Map拆分成N个小的HashTable,在put方法中,会根据hash(paramK.hashCode())来决定具体存放进哪个Segment,Segment的使用的同步机制是基于lock操作的,这样就可以对Map的一部分(Segment)进行上锁,这样影响的只是将要放入同一个Segment的元素的put操作,保证同步的时候,锁住的不是整个Map(HashTable就是这么做的),相对于HashTable提高了多线程环境下的性能,因此HashTable已经被淘汰了。
扩展:HashMap Vs SparseArray ???
注意:HashMap在JDK1.7 使用一个Entry数组来存储数据,用key的hashcode取模来决定key会被放到数组里的位置。HashMap在JDK1.8使用一个Node数组来存储数据,但这个Node可能是链表结构(key不超过8个),也可能是红黑树结构(key超过8个)。
2.Java的垃圾回收机制
3.Java类加载机制
4.线程、线程池、锁等一系列问题
答:略。
5.强引用、软引用、弱引用、虚引用的区别?
答:Java中提供这四种引用类型主要有两个目的:第一是可以让程序员通过代码的方式决定某些对象的生命周期;第二是有利于JVM进行垃圾回收。软引用使用场景:图片缓存加载。
(1).强引用(StrongReference)
强引用就是指在程序代码之中普遍存在的,只要某个对象有强引用与之关联,JVM必定不会回收这个对象,即使在内存不足的情况下,JVM宁愿抛出OutOfMemory错误也不会回收这种对象。
(2).软引用(SoftReference)
软引用是用来描述一些有用但并不是必需的对象,在Java中用java.lang.ref.SoftReference类来表示。对于软引用关联着的对象,只有在内存不足的时候JVM才会回收该对象。因此,这一点可以很好地用来解决OOM的问题,并且这个特性很适合用来实现缓存:比如网页缓存、图片缓存等。
(3).弱引用(WeakReference)
弱引用也是用来描述非必需对象的,当JVM进行垃圾回收时,无论内存是否充足,都会回收被弱引用关联的对象。在java中,用java.lang.ref.WeakReference类来表示。
(4).虚引用(PhantomReference)
虚引用和前面的软引用、弱引用不同,它并不影响对象的生命周期。在java中用java.lang.ref.PhantomReference类表示。如果一个对象与虚引用关联,则跟没有引用与之关联一样,在任何时候都可能被垃圾回收器回收。
6.设计模式
单例模式、工厂模式、适配器模式、过滤器模式、代理模式、观察者模式、桥接模式、生产者消费者模式、MVC模式。
7.其他
JVM虚拟机内存结构以及作用