java面试题每日一练(4)


1、throw和throws有什么区别?

throws子句:声明可能会出现的异常
throw语句:抛出异常
1、throw关键字用来在程序中明确的抛出异常,相反,如果一个方法可能会出现异常,但没有能力处理这种异常,则可以用throws子句来声明抛出异常;
2、throw用于方法内部,throws用于方法声明上
3、throw后跟异常对象,throws后跟异常类型
4、throw后只能跟一个异常对象,throws后可以一次声明多种异常类型

2、Colliection和Collections有什么区别?

1、Collection 是一个集合接口。它提供了对集合对象进行基本操作的通用接口方法。Collection接口在Java 类库中有很多具体的实现。Collection接口的意义是为各种具体的集合提供了最大化的统一操作方式。
2、Collections 是一个包装类。它包含有各种有关集合操作的静态多态方法。此类不能实例化,就像一个工具类,服务于Java的Collection框架

参考链接:https://blog.csdn.net/m0_46420991/article/details/119136931

3、Override(重写)和Overload(重载)有什么区别?

相同点:

  • 都要求方法名相同。
  • 都可以用于抽象方法和非抽象方法之间。

不同点:

  • 重写要求参数签名必须一致,而方法重载要求参数签名必须不一致。
  • 重写要求返回类型必须一致,而重载对此不做限制
  • 重写只能用于子类覆盖父类的方法,重载用于同一个类的所有方法(包括从父类中继承而来的方法)
  • 重写对方法的访问权限和抛出的异常有特殊的要求,而重载在这方面没有限制
  • 父类的一个方法只能被子类重写一次,而一个方法在所在的类中可以被重载多次

4、Math.round(5.5)等于多少?Math.round(-5.5)等于多少?

Math.round是四舍五入,实际上就是:加0.5向下取整
所以Math.round(5.5)=6; Math.round(-5.5)=-5

5、>>和>>>有什么区别?

1、>>表示是带符号的右移:

按照二进制把数字右移指定数位,高位如符号位为正补零,符号位负补一,低位直接移除

2、>>>表示无符号的右移:

按照二进制把数字右移指定数位,高位直接补零,低位移除。

6、java中比较器Comparator和Comparable有什么区别?

Comparable接口用来定义对象的自然顺序,而Comparator接口通常用于定义用户自定义的顺序。Comparable接口总是只有一个,是由java.lang提供的定义好的接口,即不可修改。而Comparator是由java.util提供的,集合外部实现的排序,可以通过实现他的方法进行修改,可以有多个Comparator来定制对象的顺序。

总结
如果不需要自定义排序的话,简单排序实现Comparable即可。使Comparator可以实现不同的排序,而Comparable不可以实现。

参考链接:https://blog.csdn.net/qq_42461639/article/details/81503454

7、使用至少三种使得Map集合为线程安全的集合

第一种:使用hashtable
第二种:使用synchronizedMap

Map<String,Object> synchronizedMap= synchronizedMap(new Hashtable<String,Object>());

第三种:使用ConcurrentHashMap

Map<String,Object> concurrentHashMap=new ConcurrentHashMap<String,Object>();

8、HashSet的底层实现原理

HashSet存储元素的顺序并不是按照存入时的顺序,而是按照哈希值来存的,所以取数据也是按照哈希值取得。元素的哈希值是通过元素的hashcode方法来获取的,HashSet先判断两个元素的哈希值,如果哈希值一样,接着会比较equals方法,如果equals结果为true。HashSet就视为同一个元素。如果为false,就不是同一个元素

HashSet通过hashcode值来确定元素在内存中的位置,一个hashcode位置上可以存放多个元素,多个元素间通过重写的equals方法来判断是否是同一个

9、HashSet集合如何检查重复?

其实原理:HashSet会通过元素的hashcode()和equals()方法进行判断,当试图将元素加入到Set集合中,HashSet首先会使用对象的hashcode来判断对象加入的位置。同时也会与其他已经加入的对象的hashcode进行比较,如果没有相等的hashcode,HashSet就认为这个对象之前不存在,如果之前存在同样的hashcode值,就会进一步的比较equals()方法,如果equals()比较返回结果是true,那么认为该对象在集合中的对象是一模一样的,不会将其加入;如果比较返回的是false,那么HashSet认为新加入的对象没有重复,可以正确加入。

参考链接:https://blog.csdn.net/yt_19940616/article/details/90206441

10、如何在两个线程之间共享数据?

1.将数据抽象成一个类,并将数据的操作作为这个类的方法,这么设计可以和容易做到同步只要在方法上加"synchronized"

2.将Runnable对象作为一个类的内部类,共享数据作为这个类的成员变量,每个线程对共享数据的操作方法也封装在外部类,以便实现对数据的各个操作的同步和互斥,作为内部类的各个 Runnable 对象调用外部类的这些方法。

11、悲观锁和乐观锁在实现上有什么区别?

悲观锁
总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁(共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程)。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。Java中synchronized和ReentrantLock等独占锁就是悲观锁思想的实现。
乐观锁
总是假设最好的情况,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号机制和CAS算法实现。乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库提供的类似于write_condition机制,其实都是提供的乐观锁。在Java中java.util.concurrent.atomic包下面的原子变量类就是使用了乐观锁的一种实现方式CAS实现的。

参考链接:https://blog.csdn.net/qq_34337272/article/details/81072874

12、HashMap的长度为什么是2的冥次方?

HashMap为了存取高效,要尽量较少碰撞,就是要尽量把数据分配均匀,每个链表长度大致相同。想到的办法就是取模运算:hash%length,但是在计算机中取模运算效率与远不如位移运算(&)高。主要原因是位运算直接对内存数据进行操作,不需要转成十进制,因此处理速度非常快。所以官方决定采用使用位运算(&)来实现取模运算(%),也就是源码中优化为:hash&(length-1)

我们知道,当一个数是 2^n 时, 任意整数对2^n取模等效于:h % 2^n = h & (2^n -1) ,所以长度应设置为2^n(而且你会发现 2 ^ n - 1 的二进制都是1111…11这样的,很方便计算机计算)

13、阐述ConcurrentHashMap和Hashtable的区别?

ConcurrentHashMap和HashTable的区别主要体现在实现线程安全的方式上的不同:

底层数据结构:jdk7之前的ConcurrentHashMap底层采用的是分段的数组+链表实现,jdk8之后采用的是数组+链表/红黑树;HashTable采用的是数组+链表,数组是主体,链表是解决hash冲突存在的。

实现线程安全的方式:

  1. jdk8以前,ConcurrentHashMap采用分段锁,对整个数组进行了分段分割,每一把锁只锁容器里的一部分数据,多线程访问不同数据段里的数据,就不会存在锁竞争,提高了并发访问;jdk8以后,直接采用数组+链表/红黑树,并发控制使用CAS和synchronized操作,更加提高了速度。
  2. HashTable:所有的方法都加了锁来保证线程安全,但是效率非常的低下,当一个线程访问同步方法,另一个线程也访问的时候,就会陷入阻塞或者轮询的状态。

参考链接:https://blog.csdn.net/qq_38197844/article/details/109013959

14、引起线程上下文切换的原因有哪些?

上下文切换:
利用了时间片轮转的方式,CPU 给每个任务都服务一定的时间,然后把当前任务的状态保存下来,在加载下一任务的状态后,继续服务下一任务,任务的状态保存及再加载,这段过程就叫做上下文切换

  1. 当前执行任务的时间片用完之后,系统 CPU 正常调度下一个任务:
  2. 当前执行任务碰到 IO阻塞,调度器将此任务挂起,继续下一任务;
  3. 多个任务抢占锁资源,当前任务没有抢到锁资源,被调度器挂起,继续下一任务;
  4. 用户代码挂起当前任务,让出CPU时间:
  5. 硬件中断

15、简述造成死锁的原因有哪些?

死锁:
就是多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。

死锁的四个必要条件:
①互斥条件
某资源只能被多个进程互斥的访问。
②请求和保持条件
进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源已被其他进程占有,此时请求进程被阻塞,但对自己已获得的资源保持不放
③不可抢占条件
进程已获得的资源在未使用之前不能被抢占,只能在进程使用完由自己释放
④循环等待条件。
发生死锁,必然存在一个资源-资源的循环请求链,都被阻塞

往期回顾:java面试题每日一练(3)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

冰棍hfv

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

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

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

打赏作者

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

抵扣说明:

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

余额充值