2021年面试常问的JAVA基础知识点包含容器、多线程、垃圾回收机制、反射JVM等

上传人:孙盼 文档编号:195122140 上传时间:2021-09-04 格式:DOCX 页数:14 大小:211.51KB
返回 下载 相关 举报
2021年面试常问的JAVA基础知识点包含容器、多线程、垃圾回收机制、反射JVM等_第1页
第1页 / 共14页
2021年面试常问的JAVA基础知识点包含容器、多线程、垃圾回收机制、反射JVM等_第2页
第2页 / 共14页
2021年面试常问的JAVA基础知识点包含容器、多线程、垃圾回收机制、反射JVM等_第3页
第3页 / 共14页
2021年面试常问的JAVA基础知识点包含容器、多线程、垃圾回收机制、反射JVM等_第4页
第4页 / 共14页
2021年面试常问的JAVA基础知识点包含容器、多线程、垃圾回收机制、反射JVM等_第5页
第5页 / 共14页
点击查看更多>>
资源描述

《2021年面试常问的JAVA基础知识点包含容器、多线程、垃圾回收机制、反射JVM等》由会员分享,可在线阅读,更多相关《2021年面试常问的JAVA基础知识点包含容器、多线程、垃圾回收机制、反射JVM等(14页珍藏版)》请在金锄头文库上搜索。

1、JAVA基础知识1 容器1.1 容器有哪些?JAVA的容器主要分为两大类:Collection和Map。Java中的容器集合分为两大阵营,一个是Collection,一个是MapCollection下分为Set,List,QueueSet的常用实现类有HashSet,TreeSet等List的常用实现类有ArrayList,LinkedList等Queue的常用实现类有LinkedList,ArrayBlockingQueue等Map下没有进一步分类,它的常用实现类有HashMap,ConcurrentHashMap等1.2 Collection 和 Collections 有什么区别?Col

2、lection是一个集合接口,提供了一系列对集合对象进行基本操作的通用方法,所有集合都是他的子类。Collections是一个工具类,它服务于Collection框架,它用于对集合对象进行排序、搜索等操作。1.3 List、Set和Map的区别?区别:元素是否可以重复、元素是否有序。1.4 HashMap和HashTable的区别?1) HashMap不是线程安全的,HashTable是线程安全的,因此HashMap的效率略高。2) HashMap允许键值为空,HashTable不允许。3) HashTable是同步的,HashMap不是同步的。4) HashMap的底层数组默认是16,一定是

3、2的指数;hashtable默认是11,每次扩充2+15) 一般不建议使用Hashtable(1)HashTable是遗留类,内部实现很多没优化和冗余。(2)即使在多线程环境下,现在也有同步的ConcurrentHashMap替代,没有必要因为是多线程而用HashTable。HashMap和TreeMap的区别:TreeMap在可以实现按照键值排序。LinkedHashMap:输入和输出的顺序相同。Weakhashmap:key采用弱引用,key不再被外部引用时就会被GC回收,而hashmap是强引用,只有key从hashmap删除才会被GC回收。1.5 HashMap的原理:HashMap

4、基于 Hash 算法实现的,我们一般用HashMap存储key-value类型的数据,它的底层是一个数组,当我们调用put(key,value)方法的时候,首先会对key进行计算得出一个hash值,然后根据hash值计算出(key,value)存放在数组上的位置这个时候我们会遇到两种情况:一是数组上该位置为空,可以直接放入数据;还有一种情况是该位置已经存放值了,这就发生了哈希冲突。在现在使用较为普遍的JDK1.8中是这样处理哈希冲突的:先用链表把冲突的元素串起来,如果链表的长度达到了8,并且哈希表的长度大于64,则把链表转为红黑树。(在JDK1.7中没有转化为红黑树这一步,只用链表解决冲突)细

5、节:HashMap如何确定Key存放在数组的位置?Key的hashcode()得到hash值(4字节),然后把hash值的高16位和低16位异或的结果与数组的长度-1的值进行按位与操作得到的结果就是key在数组里存放的下标。为什么不直接用key的hashcode而要把高16位和低16位异或?通常数组的长度不会超过216,如果不异或的话高16位就不会起作用了。所以把高16位和低16位异或,使得高位的影响稀释到低位中,使得计算key位置的操作能够充分散列均匀。为什么要把链表转为红黑树?阈值为啥是8?在极端情况下,比如说key的hashCode()返回的值不合理,或者多个密钥共享一个hashCode

6、,很有可能会在同一个位置产生严重的哈希冲突。这种情况下,如果我们仍然使用链表把多个冲突的元素串起来,这些元素的查询效率就会从O(1)下降为O(N)。为了能够在这种极端情况下仍保证较为高效的查询效率,HashMap选择把链表转换为红黑树,红黑树是一种常用的平衡二叉搜索树,添加,删除,查找元素等操作的时间复杂度均为O(logN)至于阈值为什么是8,这是HashMap的作者根据概率论的知识得到的。当key的哈希码分布均匀时,数组同一个位置上的元素数量是成泊松分布的,同一个位置上出现8个元素的概率已经接近千分之一了,这侧面说明如果链表的长度达到了8,key的hashCode()肯定是出了大问题,这个时

7、候需要红黑树来保证性能,所以选择8作为阈值。HashMap的扩容原理?Hashmap里面维护了一个容量值和一个加载因子,当数组里的元素个数超过容量值*加载因子后就会触发扩容机制。,默认每次扩充为原来的二倍。首先得到新的容量值和新的扩容阈值,默认都是原来大小的两倍。然后根据新容量创建新的数组最后把元素从旧数组中迁移到新数组中在JDK1.7中,迁移数据的时候所有元素都重新计算了hash,并根据新的hash重新计算数组中的位置。在JDK1.8中,这个过程进行了优化:如果当前节点是单独节点(后面没有接着链表),则根据该节点的hash值与新容量减一的值按位与得到新的地址。如果当前节点后面带有链表,则根据

8、每个节点的hash值与旧数组容量进行按位与的结果进行划分。如果得到的值为0,这些元素会被分配回原来的位置;如果得到的结果不为0,则分配到新位置,新位置的下标为当前位置下标加上旧数组容量。如果被除数是2的幂次方,对数组长度取余的方法就等价于对数组长度减一的值进行按位与操作。计算机中位运算的效率远高于取模运算。1.6 ArrayList 和 LinkedList 的区别是什么?数据结构实现(本质区别:底层实现不同):ArrayList 是动态数组的数据结构实现,而 LinkedList 是双向链表的数据结构实现。随机访问效率:ArrayList 比 LinkedList 在随机访问的时候效率要高,

9、因为 LinkedList 是线性的数据存储方式,所以需要移动指针从前往后依次查找。增加和删除效率:在非首尾的增加和删除操作,LinkedList 要比 ArrayList 效率要高,因为 ArrayList 增删操作要影响数组内的其他数据的下标。综合来说,在需要频繁读取集合中的元素时,更推荐使用 ArrayList,而在插入和删除操作较多时,更推荐使用 LinkedList。1.7 如何实现数组和 List 之间的转换?数组转list:Arrays.asList(array)List转数组:list.toArray()1.8 ArrayList和Vector线程:Vector是线程安全的,A

10、rraylist不是线程安全的。Vector对外提供的方法都是synchronized修饰的。性能:ArrayList的性能略高于Vector。都可以根据需要扩容,vector每次扩大一倍,arraylist每次扩大50%1.9 Queue中的poll和remove有何区别?相同点:都是返回第一个元素,并在队列中删除返回的对象。不同点:如果没有元素poll()会返回 null,而 remove()会直接抛出 NoSuchElementException 异常1.10 迭代器 Iterator 是什么?怎么用?有何特点?Iterator 接口提供遍历任何 Collection 的接口。Itera

11、tor 的特点是更加安全,因为它可以确保,在当前遍历的集合元素被更改的时候,就会抛出 ConcurrentModificationException 异常。1.11 Iterator 和 ListIterator 有什么区别?Iterator可以遍历 Set 和 List 集合,而 ListIterator 只能遍历 List。Iterator 只能单向遍历,而 ListIterator 可以双向遍历(向前/后遍历)。ListIterator 从 Iterator 接口继承,然后添加了一些额外的功能,比如添加一个元素、替换一个元素、获取前面或后面元素的索引位置。1.12 Java集合的fail

12、-fast和fail-safe机制?fail-fast是一种错误检测机制,Java在适合单线程使用的集合容器中很好地实现了fail-fast机制,举一个简单的例子:在多线程并发环境下,A线程在通过迭代器遍历一个ArrayList集合,B线程同时对该集合进行增删元素操作,这个时候线程A就会抛出并发修改异常,中断正常执行的逻辑。fail-safe机制更像是一种对fail-fast机制的补充,它被广泛地实现在各种并发容器集合中。回头看上面的例子,如果线程A遍历的不是一个ArrayList,而是一个CopyOnWriteArrayList,则符合fail-safe机制,线程B可以同时对该集合的元素进行

13、增删操作,线程A不会抛出任何异常。要理解这两种机制的表象,我们得了解这两种机制背后的实现原理:我们同样用ArrayList解释fail-fast背后的原理:首先ArrayList自身会维护一个modCount变量,每当进行增删元素等操作时,modCount变量都会进行自增。当使用迭代器遍历ArrayList时,迭代器会新维护一个初始值等于modCount的expectedModCount变量,每次获取下一个元素的时候都会去检查expectModCount和modCount是否相等。在上面举的例子中,由于B线程增删元素会导致modCount自增,当A线程遍历元素时就会发现两个变量不等,从而抛出异

14、常。CopyOnWriteArrayList所实现的fail-safe在上述情况下没有抛出异常,它的原理是:当使用迭代器遍历集合时,会基于原数组拷贝出一个新的数组(ArrayList的底层是数组),后续的遍历行为在新数组上进行。所以线程B同时进行增删操作不会影响到线程A的遍历行为。1.13 如何一边遍历一边删除Collection的元素?2 多线程2.1 什么是线程、守护线程?线程是操作系统进行独立运算调度的最小单元,被包含在进程中,是进程中的实际运作单位。线程和进程的区别:进程是资源分配的最小单元,线程是程序执行的最小单元。进程拥有自己的资源空间,线程共享进程中的资源。一个进程中包括多个线程

15、,线程是轻量级的进程。守护线程是运行在后台的一种特殊进程。它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。在 Java 中垃圾回收线程就是特殊的守护线程。2.2 创建线程的方式?创建线程有三种方式:继承 Thread 重写 run 方法;实现 Runnable 接口,重写run方法;实现 Callable 接口,重写call方法。Callable oneCallable = new Tickets();FutureTask oneTask = new FutureTask(oneCallable); Thread t = new Thread(oneTask);t.start();runable和callable的区别:callable有返回值、call方法可以抛出异常,可以拿到一个future对象。2.3 start和run的区别?系统调用一个线程类的start方法之后,这个线程处于就绪状态,而非运行状态,调度过程中,JVM调用run方法完成实际的操作。如果直接调用run方法,这个方法就会被当做一个普通的方法被调用,程序中仍然只有主线程这一个线程。也就是说start()方法能够异步的调用run方法。也就是说只有通过调用线程的start方法才能真正达到多线程的目的。2.4 sleep和wait和y

展开阅读全文
相关资源
相关搜索

当前位置:首页 > IT计算机/网络 > Java

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号