java基础面试题2

1,从数组中找出三个数,使它们的和为定值,求出所有这样的组合。

2,抽象类和接口的区别
抽象类主要用来抽象类别,接口主要用来抽象功能.
多态性:一个类只能继承一个抽象类,但可以实现多个接口。
接口只能做方法申明,抽象类中可以做方法申明,也可以做方法实现,但是不用abstract关键字
接口里定义的变量只能是公共的静态的常量,抽象类中的变量是普通变量。
接口是设计的结果 ,抽象类是重构的结果
抽象方法要被实现,所以不能是静态的,也不能是私有的。

3,hashMap底层实现原理及非线程安全原理分析
数组+链表,初始容量16,加载因子0.75。
hashMap在常规构造器中,没有为数组table分配内存空间(有一个入参为指定Map的构造器例外),而是在执行put操作的时候才真正构建table数组。
hashMap非线程安全的,扩容时可能会导致死循环或者元素丢失,
如果扩容前相邻的两个Entry在扩容后还是分配到相同的table位置上,就会出现死循环的BUG。在复杂的生产环境中,这种情况尽管不常见,但是可能会碰到。

put函数:
如果key为null,存储位置为table[0]或table[0]的冲突链上。
当size超过临界阈值threshold,并且即将发生哈希冲突时进行扩容。
如果该对应数据已存在,执行覆盖操作。用新value替换旧value,并返回旧value。

为何HashMap的数组长度一定是2的次幂:
获取table中的实际位置h & (length-1),取余位运算,效率高,数组索引更加均匀。
HashMap中不能有get方法来判断是否存在某个键,应该使用containsKey()方法;
JDK8之前头插法,
JDK1.8之后用尾插法,当链表长度大于8时会被转化成红黑树。

4,String对象比较(equals)及源码实现
先用==比较地址是否相等;接着使用instanceof判断参数对象是否是String类型,接着判断String的byte数组长度是否相等;相等的话判断byte数组的每个值是否相等。

5,红黑树
性质:
节点为红节点或者黑节点。
根节点是黑色。
每个叶子(NIL节点,空节点)节点是黑色。
红节点的两个子节点一定是黑色节点。
从根节点到叶子节点的路径所经过的黑节点数目是一定的。
以上性质隐藏了关键的一条性质:从根节点到叶子节点的最长路径不会到达最短路径的2倍。
插入节点,如果父节点是红色的,需要经过树的旋转变换来重新满足红黑树的性质。

6,ConcurrentHashMap原理及源码实现
concurrentHashMap是线程安全且且高效的hashMap。
锁分段技术:首先将数据分成一段一段的存储,然后每一段数据配一把锁,当一个线程占用锁访问其中一个段数据的时候,其他段数据也可以被其他线程访问。

  ConcurrentHashMap是由Segment数组和HashEntry数组结构构成。Segment是一种可重入锁.

一个ConcurrentHashMap包含一个segment数组,一个segment包含一个hashEntry数组,每个HashEntry是一个链表结构的元素。
对HashEntry数组进行修改时,必须首先获得与他对应的segment锁。

java基础面试题2_第1张图片
ConcurrentHashMap.png

JDK8对ConcurrentHashMap的改进:
改进一:取消segments字段,直接采用transient volatile HashEntry[] table保存数据,采用table数组元素作为锁,从而实现了对每一行数据进行加锁,进一步减少并发冲突的概率。

改进二:将原先table数组+单向链表的数据结构,变更为table数组+单向链表+红黑树的结构。对于hash表来说,最核心的能力在于将key hash之后能均匀的分布在数组中。如果hash之后散列的很均匀,那么table数组中的每个队列长度主要为0或者1。但实际情况并非总是如此理想,虽然ConcurrentHashMap类默认的加载因子为0.75,但是在数据量过大或者运气不佳的情况下,还是会存在一些队列长度过长的情况,如果还是采用单向列表方式,那么查询某个节点的时间复杂度为O(n);因此,对于个数超过8(默认值)的列表,jdk1.8中采用了红黑树的结构,那么查询的时间复杂度可以降低到O(logN),可以改进性能。

你可能感兴趣的:(java基础面试题2)