Java面试题系列——JavaSE面试题(集合六)

1、数组,链表,哪个查询效率高,为什么高?

数组的查询效率比较高,因为数组在内存中的存储空间是一块连续的存储空间,可以快速遍历检索。而链表在内存中的存储空间不是连续的,因此查询效率会比较低下。

2、CurrentHashMap的在JDK1.7和1.8期间分别的特征?

JDK1.7:ConcurrentHashMap是由Segment数组结构和HashEntry数组结构组成。Segment实际继承自可重入锁(ReentrantLock),在ConcurrentHashMap里扮演锁的角色;HashEntry则用于存储键值对数据。一个ConcurrentHashMap里包含一个Segment数组,每个Segment里包含一个HashEntry数组,我们称之为table,每个HashEntry是一个链表结构的元素。初始化有三个参数:initialCapacity:初始容量大小 ,默认16。loadFactor, 扩容因子,默认0.75,当一个Segment存储的元素数量大于initialCapacity* loadFactor时,该Segment会进行一次扩容。concurrencyLevel 并发度,默认16。并发度可以理解为程序运行时能够同时更新ConccurentHashMap且不产生锁竞争的最大线程数,即ConcurrentHashMap中的分段锁个数,即Segment[]的数组长度。如果并发度设置的过小,会带来严重的锁竞争问题;如果并发度设置的过大,原本位于同一个Segment内的访问会扩散到不同的Segment中,CPU cache命中率会下降,从而引起程序性能下降。

JDK1.8:已摒弃Segment的概念,直接用Node数组+链表+红黑树的数据结构来实现,并发控制使用Synchronized和CAS来操作,是优化过且线程安全的HashMap。在JDK1.8中还能看到Segment的数据结构,但是已经简化了属性,只是为了兼容旧版本。

3、自旋锁的特征

1.自旋锁:线程获取锁的时候,如果锁被其他线程持有,则当前线程将循环等待,直到获取到锁。2.自旋锁等待期间,线程的状态不会改变,线程一直是用户态并且是活动的(active)。3.自旋锁如果持有锁的时间太长,则会导致其它等待获取锁的线程耗尽CPU。4.自旋锁本身无法保证公平性,同时也无法保证可重入性。5.基于自旋锁,可以实现具备公平性和可重入性质的锁。

4、遍历SetList的通用方法?

List<String> list = new ArrayList<String>();
Set<String> set = new HashSet<String>();
 
 
//1、使用for循环遍历
for (int i = 0; i < list.size(); i++) {
	System.out.println(list.get(i));
}
 
for(String str1:set) {
			System.out.println(str1);
}
 
//2、使用foreach遍历
for (String str : list) {
			System.out.println(str);
}
 
for(String str1:set) {
			System.out.println(str1);
}
 
 
 
//3、使用迭代器遍历
Iterator<String> it = list.iterator();
		while (it.hasNext()) {
			String string = it.next();
			System.out.println(string);
}
 
 
Iterator<String> it = set.iterator();
		while(it.hasNext()) {
			//定义一个字符串接收遍历的集合内容
			String str2=it.next();
			System.out.println(str2);
}
 
 
//4、使用lambda表达式遍历
list.forEach(n -> System.out.println(n));
set.forEach(n->System.out.println(n));

5、数组的排序算法,你都知道哪些?请列举并手写一个出来

选择排序:

1.i:i 每次循环数组下标i元素都会与数组其他的所有元素进行比较,并确定数组i下标元素比较其i下标后面的元素,为最大元素

2.j = i + 1:i 每次循环,都会与i+1进行比较,并确定i 元素大于 i+1元素。

for (int i = 0; i < arrs.length - 1; i++) {
            for (int j = i + 1; j < arrs.length; j++) {
                if (arrs[i] < arrs[j]) {
                    int t = arrs[i];
                    arrs[i] = arrs[j];
                    arrs[j] = t;
                }
            }
        }
        System.out.println(Arrays.toString(arrs));

持续更新中,敬请期待!

参考文章:

CurrentHashMap的jdk1.7与jdk1.8的区别_yuanyuan啊的博客-CSDN博客_currenthashmap1.7和1.8的区别CurrentHashMap基于JDK1.7和1.8的区别_学做锅包肉的博客-CSDN博客_currenthashmap1.7和1.8的区别CurrentHashMap的jdk1.7与jdk1.8的区别_yuanyuan啊的博客-CSDN博客_currenthashmap1.7和1.8的区别

 java中的锁——自旋锁_菜丸的博客-CSDN博客_java中的自旋锁

Java面试题系列——JavaSE面试题(集合三)_循环网络不循环的博客-CSDN博客

常见的几种数组排序的算法_扮夜的博客-CSDN博客_数组排序算法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小海海不怕困难

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值