JAVA基础理解(六)

1.List, Set,Map是否继承自Collection接口?

只有List和Set接口继承于Collection接口,Map是与Collection并列的接口概念。

2.字符串常量池到底存在于内存空间的哪里?

jdk6.0字符串常量池在方法区,方法区的具体体现可以看做是堆中的永久区。

jdk7.0java虚拟机规范中不在声明方法区,字符串常量池存放在堆空间中。

jdk8.0 java虚拟机规范中又声明了元空间,字符串常量池存放在元空间中。

3.Java中的编译器常量是什么?使用它又有什么风险?

公共静态不可变(public static final) 变量也就是我们所说的编译器常量,这里的public 可选的。实际上这些变量在编译时会被替换掉,因为编译器知道这些变量的值,并且知道这些变量在运行时不能改变。这种方式存在的一个问题是你使用了一个内部的或第三方库中的公有编译时常量,但是这个值后面被其他人改变了,但是你的客户端仍然在使用老的值,甚至你已经部署了一个新的jar。为了避免这种情况,当你在更新依赖JAR文件时,确保重新编译你的程序。

4.用哪两种方式来实现集合的排序?

你可以使用有序集合,如TreeSet 或 TreeMap, 你也可以使用有顺序的集合。如list,然后通过Collections.sort()来排序

5.说出JDK1.7中的三个新特性

try-with-resource语句,这样在使用流或者资源时候,就不需要手动关闭,java会自动关闭,

Fork-Join池某种程度上实现Java版的Map-reduce。允许Switch中有String变量和文本。菱形操作符(<>)用于类型推断,不再需要在变量声明的右边声明泛型,因此可以写出可读写更强、更简洁的代码。另一个值得一提的特性是改善异常处理,如允许在同一个catch块中捕获多个异常。

6.说出5个JDK1.8引入的新特性?

JAVA 8 在 Java 历史上 是一个开创新的版本,下面JDK8中5 个主要的特性: Lambda表达式,允许像对象一样传递匿名函数Stream API,充分利用现代多核CPU,可以写出很简洁的代码Date与Time API,最终,有一个稳定、简单的日期和时间库可供你使用 扩展方法,现在,接口中可以有静态、默认方法。重复注解,现在你可以将相同的注解在同一类型上使用多次。

7.ArrayList 源码分析

  1. ArrayList 是一种变长的集合类,基于定长数组实现,使用默认构造方法初始化出来的容量是10(1.7之后都是延迟初始化,即第一次调用add方法添加元素的时候才将elementData容量初始化为10)。

  2. ArrrayList 允许空值和重复元素,当往 ArrayList 中添加的元素数量大于其底层数组容量时,其会通过扩容机制重新生成一个更大的数组。ArrayList扩容的长度是原长度的1.5倍

  1. 由于ArrayList底层基于数组实现,所以其可以保证在o(1)复杂度下完成随机查找操作。

  2. ArrayList 是非线程安全类,并发环境下,多个线程同时操作 ArrayList,会引发不可预知的异常和错误。

  3. 顺序添加很方便

  4. 删除和插入需要复制数组,性能差(可以使用LinkedList)

  5. Integer.MAX_VALUE-8:主要是考虑到不同的JVM,有的JVM会在加入一些数据头,当扩容后的容量大于MAX_ARRAY_SIZE,我们会去比较最小需要容量和MAX_ARRAY_SIZE作比较,如果比它大,只能取Integer.MAX_VALUE,否则Integer.MAX_VALUE-8。这个是从jdk1.7开始有的。

8.HashMap源码分析

jdk1.8之前list+ 链表

jdk1.8之后list+链表(当链表长度到8时,转化为红黑树)

HashMap的扩容因子

默认0.75,也就是会浪费1/4的空间,达到扩容因子时,会将list扩容一倍,0.75是时间与空间的一个平衡值。

9.ConcurrentHashMap 源码分析

ConcurrentHashMap所使用的锁分段技术,首先将数据分成一段一段的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据的时候,其他段的数据也能被其他线程访问。有些方法需要跨段,比如size()和containsValue(),它们可能需要锁定整个表而不仅仅是某个段,这需要按顺序锁定所有段,操作完毕后又按顺序释放所有段的锁。这里“按顺序”是很重要的,否则极有可能出现死锁,在ConcurrentHashMap内部,段数组是final的,并且其成员变量实际上也是final的。但是,仅仅是将数组声明为final的并不保证数组成员也是final的,这需要实现上的保证,这可以确保不会出现死锁,因为获得锁的顺序是固定的。

ConcurrentHashMap 是由Segement数组结构的HashEntry数组结构组成,Segment是一种可重入锁ReentrantLock,在ConcurrentHashMap里扮演锁的角色,HashEntry则用于存储键值对数据。一个ConcurrentHashMap里包含一个Segment数组,Segment的结构和HashMap类似,是一种数组和链表结构,一个Segment里面包含一个HashEntry数组,每个HashEntry是一个链表结构的元素,每个Segment守护者一个HashEntry数组,每个HashEntry是一个链表结构的元素,每个Segment守护者一个HashEntry数组里的元素,当对HashEntry数组的数据进行修改时,必须首先获得它对应的Segment锁。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章