2022高级java面试题:2022Java面试题大全
2022高级java面试题:2022Java面试题大全private void fastRemove(int index) { modCount ; int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData index 1 elementData index numMoved); elementData[--size] = null; // Let gc do its work }按一般执行路径会走到else路径下最终调用faseRemove方法:public static void remove(ArrayList<String> list) { for (String s : list) { if (s.equals("bb")) { list.remove(s); } } }要分析产生上述错误
1. 遍历ArrayList时如何正确移除一个元素
错误写法示例一:
public static void remove(ArrayList<String> list) { for (int i = 0; i < list.size(); i ) { String s = list.get(i); if (s.equals("bb")) { list.remove(s); } } }
错误写法示例二:
public static void remove(ArrayList<String> list) { for (String s : list) { if (s.equals("bb")) { list.remove(s); } } }
要分析产生上述错误现象的原因唯有翻一翻jdk的ArrayList源码,先看下ArrayList中的remove方法(注意ArrayList中的remove有两个同名方法,只是入参不同,这里看的是入参为Object的remove方法)是怎么实现的:
public boolean remove(Object o) { if (o == null) { for (int index = 0; index < size; index ) if (elementData[index] == null) { fastRemove(index); return true; } } else { for (int index = 0; index < size; index ) if (o.equals(elementData[index])) { fastRemove(index); return true; } } return false; }
按一般执行路径会走到else路径下最终调用faseRemove方法:
private void fastRemove(int index) { modCount ; int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData index 1 elementData index numMoved); elementData[--size] = null; // Let gc do its work }
可以看到会执行System.arraycopy方法,导致删除元素时涉及到数组元素的移动。针对错误写法一,在遍历第二个元素字符串bb时因为符合删除条件,所以将该元素从数组中删除,并且将后一个元素移动(也是字符串bb)至当前位置,导致下一次循环遍历时后一个字符串bb并没有遍历到,所以无法删除。 针对这种情况可以倒序删除的方式来避免:
public static void remove(ArrayList<String> list) { for (int i = list.size() - 1; i >= 0; i--) { String s = list.get(i); if (s.equals("bb")) { list.remove(s); } } }
因为数组倒序遍历时即使发生元素删除也不影响后序元素遍历。
而错误二产生的原因却是foreach写法是对实际的Iterable、hasNext、next方法的简写,问题同样处在上文的fastRemove方法中,可以看到第一行把modCount变量的值加一,但在ArrayList返回的迭代器(该代码在其父类AbstractList中):
public iterator<E> iterator() { return new Itr(); }
这里返回的是AbstractList类内部的迭代器实现private class Itr implements Iterator,看这个类的next方法:
public E next() { checkForComodification(); try { E next = get(cursor); lastRet = cursor ; return next; } catch (IndexOutOfBoundsException e) { checkForComodification(); throw new NoSuchElementException(); } }
第一行checkForComodification方法:
final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); }
这里会做迭代器内部修改次数检查,因为上面的remove(Object)方法把修改了modCount的值,所以才会报出并发修改异常。要避免这种情况的出现则在使用迭代器迭代时(显示或foreach的隐式)不要使用ArrayList的remove,改为用Iterator的remove即可。
public static void remove(ArrayList<String> list) { Iterator<String> it = list.iterator(); while (it.hasNext()) { String s = it.next(); if (s.equals("bb")) { it.remove(); } } }
2. 说一说ArrayList 的扩容机制吧
ArrayList扩容的本质就是计算出新的扩容数组的size后实例化,并将原有数组内容复制到新数组中去。
public boolean add(E e) { //扩容 ensureCapacityInternal(size 1); // Increments modCount!! elementData[size ] = e; return true; } private void ensureCapacityInternal(int minCapacity) { ensureExplicitCapacity(calculateCapacity(elementData minCapacity)); }
private static int calculateCapacity(Object[] elementData int minCapacity) { //如果传入的是个空数组则最小容量取默认容量与minCapacity之间的最大值 if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { return Math.max(DEFAULT_CAPACITY minCapacity); } return minCapacity; } private void ensureExplicitCapacity(int minCapacity) { modCount ; // 如果最小需要空间比elementData的内存空间要大,则需要扩容 // overflow-conscious code if (minCapacity - elementData.length > 0) grow(minCapacity); } private void grow(int minCapacity) { // 获取elementData数组的内存空间长度 int oldCapacity = elementData.length; // 扩容至原来的1.5倍 int newCapacity = oldCapacity (oldCapacity >> 1); //校验容量是否够 if (newCapacity - minCapacity < 0) newCapacity = minCapacity; //若预设值大于默认的最大值,检查是否溢出 if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); // 调用Arrays.copyOf方法将elementData数组指向新的内存空间 //并将elementData的数据复制到新的内存空间 elementData = Arrays.copyOf(elementData newCapacity); }
————————————————
版权声明:本文为CSDN博主「Java涛仔」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_64513388/article/details/122481846
3. HashMap是怎么解决哈希冲突的
Hashmap解决hash冲突,使用的是链地址法,即数组 链表的形式来解决。put执行首先判断table[i]位置,如果为空就直接插入,不为空判断和当前值是否相等,相等就覆盖,如果不相等的话,判断是否是红黑树节点,如果不是,就从table[i]位置开始遍历链表,相等覆盖,不相等插入。
4. String 类的常用方法都有那些?
indexOf():返回指定字符的索引。
charAt():返回指定索引处的字符。
replace():字符串替换。
trim():去除字符串两端空白。
split():分割字符串,返回一个分割后的字符串数组。
getbytes():返回字符串的 byte 类型数组。
length():返回字符串长度。
toLowerCase():将字符串转成小写字母。
toUpperCase():将字符串转成大写字符。
subString():截取字符串。
equals():字符串比较。
5. 简述Java中的集合
Collection下:List系(有序、元素允许重复)和Set系(无序、元素不重复) “ set根据equals和hashCode判断,一个对象要存储在Set中,必须重写equals和hashCode方法 ”
Map下:HashMap线程不同步;TreeMap线程同步
Collection系列和Map系列:Map是对Collection的补充,两个没什么关系
“ 后面的问题,大家可以先自己独立思考一下。 另外我把所有Java相关的面试题和答案都整理出来了,需要的私信,即可免费获取哦!
6. EnumSet是什么?
7. 创建String对象的不同方式有哪些?
8. 为何Map接口不继承Collection接口?
9. HashMap和Hashtable的区别
10. ArrayList和HashMap默认大小?
11. LinkedList的是单向链表还是双向?
12. 当一个集合被作为参数传递给一个函数时,如何才可以确保函数不能修改它?
13. 在Java中,HashMap是如何工作的?
14. TreeMap和TreeSet在排序时如何比较元素?Collections工具类中的sort()方法如何比较元素?
15. HashSet和TreeSet有什么区别?
16. String是不可变的有什么好处?
17. Java集合类框架的最佳实践有哪些?
18. HashSet是如何保证不重复的
19. HashMap的实现原理
20. Iterater和ListIterator之间有什么区别?
21. 队列和栈是什么,列出它们的区别?
22. HashMap线程安全吗?
23. 写一段代码在遍历 ArrayList 时移除一个元素
24. 有没有有顺序的Map实现类,如果有,他们是怎么保证有序的
25. ArrayList Vector LinkedList的存储性能和特性
26. 什么是字符串池?
27. 哪些集合类提供对元素的随机访问?
28. hashCode()和equals()方法有何重要性?
29. 我们能否使用任何类作为Map的key?
30. # 总结
31. 集合框架中的泛型有什么优点?
32. ArrayList和Vector有何异同点?
33. HashMap,HashTable,ConcurrentHash的共同点和区别
34. Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()?
35. Java中的同步集合与并发集合有什么区别
36. String str="i"与 String str=new String("i")一样吗?
37. 下面这条语句一共创建了多少个对象:String s="a" "b" "c" "d"
38. 如果想用Object作为hashMap的Key?;
39. Java 中操作字符串都有哪些类?它们之间有什么区别?
40. 谈谈线程池阻塞队列吧~
41. Java集合框架是什么?说出一些集合框架的优点?
42. 与Java集合框架相关的有哪些最好的实践?
43. TreeMap底层?
44. ArrayList和LinkedList有何区别?
45. 我们如何从给定集合那里创建一个synchronized的集合?
46. Java中怎么打印数组?
47. 当一个集合被作为参数传递给一个函数时,如何才可以确保函数不能修改它?
48. 如何决定选用HashMap还是TreeMap?
49. HashMap总结
50. 说出ArrayList LinkedList的存储性能和特性
51. Collections类是什么?
52. Comparator和Comparable的区别?
53. Iterator和ListIterator的区别是什么?
54. List、Map、Set三个接口,存取元素时,各有什么特点?
55. Comparable和Comparator接口有何区别?
56. Map接口提供了哪些不同的集合视图?
57. 哪些集合类是线程安全的?哪些不安全?
58. 通过迭代器fail-fast属性,你明白了什么?
59. HashMap和HashTable有何不同?
60. 为何Iterator接口没有具体的实现?
61. 如何实现集合排序?
62. 如何比较两个字符串?
63. 讲讲红黑树的特点?
64. 遍历一个List有哪些不同的方式?
65. 集合框架里实现的通用算法有哪些?
66. UnsupportedOperationException是什么?
67. 为何没有像Iterator.add()这样的方法,向集合中添加元素?
68. 如何实现数组和 List之间的转换?
69. Collection与Collections的区别是什么?
70. LinkedHashMap的应用,底层,原理
71. ArrayList 和 HashMap 的默认大小是多数?
72. HashMap自动扩容
73. HashMap在JDK1.7和JDK1.8中有哪些不同?
74. 什么是String,它是什么数据类型?
75. Set里的元素是不能重复的,那么用什么方法来区分重复与否呢?是用==还是equals()?它们有何区别?
76. ArrayList和Vector的区别
77. 在迭代一个集合的时候,如何避免ConcurrentModificationException?
78. 如何判断两个String是否相等?
79. LinkedHashMap和PriorityQueue的区别
80. String s = new String("xyz");创建了几个StringObject?是否可以继承String类?
81. HashMap为什么不直接使用hashCode()处理后的哈希值直接作为table的下标?
82. Collections.sort和Arrays.sort的实现原理
83. 为何迭代器没有一个方法可以直接获取下一个元素,而不需要移动游标?
84. 如何打印数组内容
85. 大写的O是什么?举几个例子?
86. 为什么HashMap中String、Integer这样的包装类适合作为key?
87. 如何将String转换为byte array 反过来呢?
88. BlockingQueue是什么?
89. 阻塞队列的实现,ArrayBlockingQueue的底层实现?
90. 如何分割一个String?
91. Array和ArrayList有何区别?什么时候更适合用Array?
92. 如何让一个字符串变成小写或大写形式?
93. 说一下HashSet的实现原理?
94. 迭代器 Iterator 是什么?怎么用,有什么特点?
95. fail-fast与fail-safe有什么区别?
96. ArrayList和LinkedList区别?
97. String、StringBuffer和StringBuilder区别(类似上一题)
98. 怎么确保一个集合不能被修改?
99. Iterator是什么?
100. ArrayList和LinkedList的区别?
101. ArrayList集合加入1万条数据,应该怎么提高效率
102. 为什么要引入SpringBuffer、StringBuilder两种字符串处理类?
103. HashMap的扩容操作是怎么实现的?
104. 什么是Java优先级队列(Priority Queue)?
105. ArrayList和Array有什么区别?
106. ConcurrentHashMap和Hashtable的区别?
107. Comparable和Comparator接口是什么?
108. HashMap 的长度为什么是2的幂次方,以及其他常量定义的含义~
109. ConcurrenHashMap 原理?1.8 中为什么要用红黑树?
110. Java集合框架的基础接口有哪些?
111. Enumeration和Iterator接口的区别?
112. 我们如何对一组对象进行排序?
113. WeakHashMap与HashMap的区别是什么?
114. 如何将String转换为char 反过来呢?
115. 并发集合类是什么?
116. poll()方法和remove()方法区别?
117. Java中的集合及其继承关系
118. 为何Collection不从Cloneable和Serializable接口继承?
119. HashMap的put方法的具体流程?
120. TreeMap的实现原理
121. 如何对Object的list排序
122. Array 和 ArrayList 有何区别?
如果本文对你有帮助,别忘记给我个3连 ,点赞,转发,评论,
咱们下期见。
原文链接:https://blog.csdn.net/qq_64513388/article/details/122481846