面试本质上,是对问题的理解程度以及求职者是否符合用人单位的预期。但是繁杂的面试题目,让求职者忙于应付。因此,在这里按照之前java的学习路线维度,精炼出提问率最高的知识点(该篇幅主要以java基础为主)
集合下的三大类:List,map和set
1.List的三大实现类:ArrayList、LinkedList、Vector的区别。
1.1 LinkedList
基于链表实现,链表内存是散列的,增删快,查找慢;
1.2 ArrayList
基于数组实现,非线程安全,效率高,增删慢,查找快;
1.3 Vector
基于数组实现,线程安全,效率低,增删慢,查找慢;
2.Map的三大实现类:HashMap、和HashTable和TreeMap的区别
2.1 HashMap
基于 hash 表的实现,非线程安全,高效,支持 null 值和 null键;
2.2 HashTable
线程安全,低效,不支持 null 值和 null 键;
2.3 TreeMap接口
能够把它保存的记录根据键排序,默认是键值的升序排序
3.Set的两个实现类:HashSet和LinkedHashSet
3.1 HashSet
底层是由 Hash Map 实现,不允许集合中有重复的值,使用该方式时需要重写 equals()和 hash Code()方法;
3.2 LinkedHashSet
继承于 HashSet,同时又基于 LinkedHashMap 来进行实现,底层使用的是 LinkedHashMap
衍生的问题:
1. 三者的区别
1.1 List 集合中对象按照索引位置排序,可以有重复对象,允许按照对象在集合中的索引位置检索对象,例如通过list.get(i)方法来获取集合中的元素;
1.2 Map 以键值对结构出现,对象不可以重复,但值对象可以重复;
1.3 Set 不能存储重复对象,但是实现类能对集合中的对象按照特定的方式排序,例如 TreeSet 等,在java1.8中,也可以通过实现 Java.util.Comparator< Type >接口来自定义排序。”
2. HashMap和HashTree哪个耗时多?
HashTree,因为tree需要在插入后,还要进行一轮排序操作。
3. Vector为什么是线程安全的?
线程安全:所谓的线程安全是指调用类的成员方法时,其他线程不能再访问该对象。
3.1 Vector的同步操作有synchronized关键字
3.2 Vector类的成员方法时,其他线程不能再访问该Vector对象。
字符串下的类型:String, StringBuffer和StringBuilder
1.String
String是字符串常量,它的值不能改变,改变的是引用
2.StringBuilder
StringBuilder是字符串变量,它的值是可以改变的,StringBuilder支持单线程
3.StringBuffer
StringBuffer是线程安全版的StringBuilder,继承StringBuilder的特性,StringBuffer支持多线程
衍生的问题:
1. 三者的区别
1.1 String为字符串常量,而StringBuilder和StringBuffer均为字符串变量,常量在创建后不可改变,变量则是可以改变的。
1.2 StringBuilder是线程不安全的,而StringBuffer是线程安全的。(线程安全上面已经解释)StringBuffer中很多方法可以带有synchronized关键字,所以可以保证线程是安全的,但StringBuilder的方法则没有该关键字,所以不能保证线程安全。
1.3 因此,String适用于字符串对象少且更改频次小的操作,StringBuilder适用於单线程下在字符缓冲区进行大量操作的情况,StringBuffer适用多线程下在字符缓冲区进行大量操作的情况。
HashMap和ConcurrentHashMap的区别
1. HashMap
线程不安全
2.ConcurrentHashMap
线程安全,效率高,天然支持多线程
衍生的问题:
ConcurrentHashMap经常会被问起,而且由于1.8的更改,使得这个数据结构越发经典。毫不夸张的说,如果世界上只剩下一种数据结构,那么我一定考虑HashMap,但是由于其线程不安全的特性,我会更进一步的考虑ConcurrentHashMap。
1. 先从HashMap说起,因为线程不安全,在并发操作下,会引起死循环的情况。而ConcurrentHashMap则是线程安全的,利用经典的“锁分段”思路来引导了整个数据结构的线程安全。
2. 为什么叫“锁分段”呢?
简单来说,一个数据结构同一时间加一个锁,下一个进程进入后,要等这个锁解开,才可以进行下一段的操作,这样就可以通过锁来保证线程安全。但是ConcurrentHashMap不一样,他一次性给数据结构加多个锁,每一个锁对应自己数据结构中的拆分出来的一部分数据,这样的情况下,就能给天然的支持并发了。
3. 那么这样的结构是怎么实现的呢?
ConcurrentHashMap 类中包含两个静态内部类 HashEntry 和 Segment。HashEntry 用来封装映射表的键 / 值对;Segment 用来充当锁的角色,每个 Segment 对象守护整个散列映射表的若干个桶。每个Segment守护者一个HashEntry数组里的元素,当对HashEntry数组的数据进行修改时,必须首先获得它对应的Segment锁。
更多信息,微信搜索“计算机俱乐部”