(3/100)

学习思路如下:

面试准备思路

一、JavaSE部分—题目

4、集合
1、Map和ConcurrentHashMap的区别?
2、hashMap内部具体如何实现的?
3、如果hashMap的key是一个自定义的类,怎么办?
4、ArrayList和LinkedList的区别,如果一直在list的尾部添加元素,用哪个效率高?
5、HashMap底层,负载因子,为啥是2^n?
6、ConcurrentHashMap锁加在了哪些地方?
7、TreeMap底层,红黑树原理?
8、concurrenthashmap有啥优势,1.7,1.8区别?
9、ArrayList是否会越界?
10、什么是TreeMap?
11、ConcurrentHashMap的原理是什么?
12、Java集合类框架的基本接口有哪些?
13、为什么集合类没有实现Cloneable和Serializable接口?
14、什么是迭代器?
15、Iterator和ListIterator的区别是什么?
16、快速失败(fail-fast)和安全失败(fail-safe)的区别是什么?
17、HashMap和Hashtable有什么区别?
18、ArrayList和LinkedList有什么区别?
19、ArrayList,Vector,LinkedList的存储性能和特性是什么?
20、Collection 和 Collections的区别。
21、你所知道的集合类都有哪些?主要方法?
22、List、Set、Map是否继承自Collection接口?
23、阐述ArrayList、Vector、LinkedList的存储性能和特性
24、List、Map、Set三个接口存取元素时,各有什么特点?

答案部分:4)集合

1、Map和ConcurrentHashMap的区别?

答:详细链接—https://blog.csdn.net/liuyanming123/article/details/79662511

2、hashMap内部具体如何实现的?

答:hashmap是数组+链表实现,数组是主体部分,而数组中的每一个元素可以就是一个链表的头节点。
链表主要是为了用来解决hash冲突。

HashMap

3、如果hashMap的key是一个自定义的类,怎么办?

答:如果hashMap的key是一个自定义的类,必须重写该类的hashcode()方法和equals()方法。
详细链接—https://blog.csdn.net/weixin_38780073/article/details/80728362

4、ArrayList和LinkedList的区别,如果一直在list的尾部添加元素,用哪个效率高?

答:动态数组查询特定元素比较快,插入和删除不如链表快

ArrayList实现了List接口,底层使用的是动态数组,之所以称为动态数组,是因为Arraylist在数组元素超过其容量大,Arraylist可以进行扩容(针对JDK1.8 数组扩容后的容量是扩容前的1.5倍);LinkedList底层使用的是链表

具体: 如果一直在尾部添加元素的话,ArrayList的效率会更高一些,LinkedList每次增加会new一个Node对象来保存新增加的元素,当数据量比较小的时候时间不明显,数据量很大的时候new一个Node的时间会大于动态数组扩容的时间,这样ArrayList的效率就高了。

5、HashMap底层,负载因子,为啥是2^n?

答:1.减小哈希冲突概率;2.提高计算下标的效率
详细链接—https://blog.csdn.net/a_long_/article/details/51594159


6、ConcurrentHashMap锁加在了哪些地方?

答:ConcurrentHashMap—参考:https://www.cnblogs.com/theRhyme/p/9404082.html
1)Java7 是由Segment数组实现的,一个Segment锁住几个HashEntry元素;
2)Java8 是由synchronized锁住transient volatile Node<K,V>[] table 数组的一个元素(即头结点,锁粒度比Java7低),还通过CAS(Unsafe对象)操作数据更新、插入等。

7、TreeMap底层,红黑树原理?

答:TreeMap的实现是红黑树算法的实现,所以要了解TreeMap就必须对红黑树有一定的了解。
参考:https://my.oschina.net/90888/blog/1626065

8、concurrenthashmap有啥优势,1.7,1.8区别?

答:参考—https://www.jianshu.com/p/933289f27270

Concurrenthashmap线程安全的:

1) 1.7是在jdk1.7中采用Segment + HashEntry的方式进行实现的,lock加在Segment上面。1.7size计算是先采用不加锁的方式,连续计算元素的个数,最多计算3次:

如果前后两次计算结果相同,则说明计算出来的元素个数是准确的;

如果前后两次计算结果都不同,则给每个Segment进行加锁,再计算一次元素的个数;

2) 1.8中放弃了Segment臃肿的设计,取而代之的是采用Node + CAS + Synchronized来保证并发安全进行实现,1.8中使用一个volatile类型的变量baseCount记录元素的个数,当插入新数据或则删除数据时,会通过addCount()方法更新baseCount,通过累加baseCount和CounterCell数组中的数量,即可得到元素的总个数.

9、ArrayList是否会越界?

答:https://blog.csdn.net/u010010428/article/details/51258783

可能会越界,在多线程操作同一个ArrayList的时候,两个线程同时执行Add,在线程1已经将size++,而线程2在读取的时候导致越界线程在被挂起的时候,执行的位置不一样 Size是一个共有变量,自增是个非原子操作

10、什么是TreeMap?

答:TreeMap继承AbstractMap,实现NavigableMap、Cloneable、Serializable三个接口,能按自然顺序或自定义顺序遍历

定义: 基于红黑二叉树的NavigableMap的实现,线程非安全,不允许null,key不可以重复,value允许重复,存入TreeMap的元素应当实现Comparable接口或者实现Comparator接口, 会按照排序后的顺序迭代元素,两个相比较的key不得抛出classCastException。

作用: 主要用于存入元素的时候对元素进行自动排序,迭代输出的时候就按排序顺序输出。

11、ConcurrentHashMap的原理是什么?

答:参考—https://www.cnblogs.com/banjinbaijiu/p/9147434.html
ConcurrentHashMap相比HashMap而言,是多线程安全的,其底层数据与HashMap的数据结构相同,数据结构如下:
ConcurrentHashMap
说明:ConcurrentHashMap的数据结构(数组+链表+红黑树),桶中的结构可能是链表,也可能是红黑树,红黑树是为了提高查找效率。

12、Java集合类框架的基本接口有哪些?

答:基本接口有两类——Collection类+Map类
1)Collection类: 元素集合,List和Set继承了Collection接口,List是有序元素集合,set是无序元素集合,ArrayList和LinkedList实现了list接口。HashSet实现的是set接口,Set中的元素是不能重复的,List中的元素是可以重复的。
2)Map类: 键值对集合,HashTable与HashMap实现了Map类,HashTable是线程安全的但是HashMap效率高,因为HashTable由Sychronized修饰,每次只有一个线程更新HashTable。

13、为什么集合类没有实现Cloneable和Serializable接口?

答:克隆(cloning)或序列化(serialization)的语义和含义是跟具体的实现相关的。应由集合类的具体实现类来决定如何被克隆或序列化。

1)什么是克隆?
把一个对象里面的属性值,复制给另一个对象。而不是对象引用的复制

2)实现Serializable序列化的作用
1.将对象的状态保存在存储媒体中一边可以在以后重写创建出相同的副本
2.按值将对象从一个应用程序域,发相另一个应用程序域

注意: 实现Serializable接口的作用就是可以把对象存到字节流,然后可以恢复。所以你想你的对象没有序列化,怎么才能在网络传输呢?要网络传输就得转为字节流,所以在分布式应用中,你就得实现序列化。如果你不需要分布式应用,那就没必要实现序列化

14、什么是迭代器?

答:迭代器是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象,而开发人员不需要了解该序列的底层结构。迭代器通常被称为“轻量级”对象,因为创建它的代价小。

Java中的Iterator功能比较简单,并且只能单向移动:

(1) 使用方法iterator()要求容器返回一个Iterator。第一次调用Iterator的next()方法时,它返回序列的第一个元素。
注意:iterator()方法是java.lang.Iterable接口,被Collection继承。

(2) 使用next()获得序列中的下一个元素。

(3) 使用hasNext()检查序列中是否还有元素。

(4) 使用remove()将迭代器新返回的元素删除。

Iterator是Java迭代器最简单的实现,为List设计的ListIterator具有更多的功能,它可以从两个方向遍历List,也可以从List中插入和删除元素。

15、Iterator和ListIterator的区别是什么?

答:区别如下:
1) Iterator可用来遍历Set和List集合,但是ListIterator只能用来遍历List。

2) Iterator对集合只能是前向遍历,ListIterator既可以前向也可以后向。

3) ListIterator实现了Iterator接口,并包含其他的功能,比如:增加元素,替换元素,获取前一个和后一个元素的索引

16、快速失败(fail-fast)和安全失败(fail-safe)的区别是什么?

答:
一:快速失败(fail—fast)

       1)定义: 在用迭代器遍历一个集合对象时,如果遍历过程中对集合对象的内容进行了修改(增加、删除、修改),则会抛出Concurrent Modification Exception。

       2)原理: 迭代器在遍历时直接访问集合中的内容,并且在遍历过程中使用一个 modCount 变量。集合在被遍历期间如果内容发生变化,就会改变modCount的值。每当迭代器使用hashNext()/next()遍历下一个元素之前,都会检测modCount变量是否为expectedmodCount值,是的话就返回遍历;否则抛出异常,终止遍历。

       3)注意: 这里异常的抛出条件是检测到 modCount != expectedmodCount 这个条件。如果集合发生变化时修改modCount值刚好又设置为了expectedmodCount值,则异常不会抛出。因此,不能依赖于这个异常是否抛出而进行并发操作的编程,这个异常只建议用于检测并发修改的bug。

       4)场景: java.util包下的集合类都是快速失败的,不能在多线程下发生并发修改(迭代过程中被修改)。

二:安全失败(fail—safe)

       1)定义: 采用安全失败机制的集合容器,在遍历时不是直接在集合内容上访问的,而是先复制原有集合内容,在拷贝的集合上进行遍历。

       2)原理: 由于迭代时是对原集合的拷贝进行遍历,所以在遍历过程中对原集合所作的修改并不能被迭代器检测到,所以不会触发Concurrent Modification Exception。

       3)缺点: 基于拷贝内容的优点是避免了Concurrent Modification Exception,但迭代器同样并不能访问到修改后的内容,即:迭代器遍历的是开始遍历那一刻拿到的集合拷贝,在遍历期间原集合发生的修改迭代器是不知道的。

       4)场景: java.util.concurrent包下的容器都是安全失败,可以在多线程下并发使用,并发修改。

17、HashMap和Hashtable有什么区别?

答:参考—https://www.cnblogs.com/williamjie/p/9099141.html

18、ArrayList和LinkedList有什么区别?

答:
1)ArrayList 是动态数组结构,有索引,查询快(时间复杂度O(1)),增删慢(因为要移动索引)
2)LinkedList 是链表结构,无索引,有指向前后的指针,查询需要从头开始向下寻找(时间复杂度O(n)),增删快(只需要修改链表中指针的指向,不需要移动其他)

1、ArrayList和LinkedList,一个是Array(动态数组)的数据结构,一个是Link(链表)的数据结构,都是List接口的实现。
前者是数组队列,相当于动态数组;后者为双向链表结构,也可当作堆栈、队列、双端队列

2、当随机访问List时(get和set操作),ArrayList比LinkedList的效率更高,因为LinkedList是线性的数据存储方式,所以需要移动指针从前往后依次查找。

3、当对数据进行增加和删除的操作时(add和remove操作),LinkedList比ArrayList的效率更高,因为ArrayList是数组,所以在其中进行增删操作时,会对操作点之后所有数据的下标索引造成影响,需要进行数据的移动。

4、从利用效率来看,ArrayList自由性较低,因为它需要手动的设置固定大小的容量,但是它的使用比较方便,只需要创建,然后添加数据,通过调用下标进行使用;而LinkedList自由性较高,能够动态的随数据量的变化而变化,但是它不便于使用。

5、ArrayList主要控件开销在于需要在lList列表预留一定空间;而LinkList主要控件开销在于需要存储结点信息以及结点指针信息。

19、ArrayList,Vector,LinkedList的存储性能和特性是什么?

答:
1)ArrayList 和Vector他们底层的实现都是一样的,都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢。

2)Vector中的方法由于添加了synchronized修饰,因此Vector是线程安全的容器,但性能上较ArrayList差,因此已经是Java中的遗留容器。

3)LinkedList使用双向链表实现存储(将内存中零散的内存单元通过附加的引用关联起来,形成一个可以按序号索引的线性结构,这种链式存储方式与数组的连续存储方式相比,内存的利用率更高),按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。

4)Vector属于遗留容器(Java早期的版本中提供的容器,除此之外,Hashtable、Dictionary、BitSet、Stack、Properties都是遗留容器),已经不推荐使用,但是由于ArrayList和LinkedListed都是非线程安全的,如果遇到多个线程操作同一个容器的场景,则可以通过工具类Collections中的synchronizedList方法将其转换成线程安全的容器后再使用(这是对装潢模式的应用,将已有对象传入另一个类的构造器中创建新的对象来增强实现)

20、Collection 和 Collections的区别。

答:参考—https://www.cnblogs.com/xiedashi/p/10828867.html
1) Collection是集合类的上级接口,继承与他的接口主要有Set 和List.
2) Collections是针对集合类的一个帮助类,提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。

21、你所知道的集合类都有哪些?主要方法?

答:主要有两种。一种Collection,另一种Map。
1)Collection包括:Set、List和Queue,Set(无序无重)又包括HashSet、LinkedHashSet及TreeSet,List(有序有重)又包括ArrayList、LinkedList及Vector;
2)Map包括:HashTable、LinkedHashMap、HashMap及TreeMap

详细链接—https://blog.csdn.net/guozhiwang_0311/article/details/79924370

22、List、Set、Map是否继承自Collection接口?

答:参考—https://blog.csdn.net/qq_41620160/article/details/79450365
图解

23、List、Map、Set三个接口存取元素时,各有什么特点?

答:详细链接—https://www.cnblogs.com/areyouready/p/7580489.html
1) List是有序的Collection,使用此接口能够精确的控制每个元素插入的位置。用户能够使用索引(元素在List中的位置,类似于数组下标)来访问List中的元素,这类似于Java的数组。

2) Set是不包含重复的元素的Collection,任意的两个元素e1和e2都有e1.equals(e2)=false,Set最多有一个null元素。

3) Map接口 :请注意,Map没有继承Collection接口,Map提供key到value的映射

第3天(1/1)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值