java八股

1.JDK、JRE、JVM之间的区别

  • JDK(Java SE Develoment Kit),Java标准开发包,它提供了编译运行Java程序所需的各种工具和资源,包括java编译器,Java运行时环境,以及常用的Java类库等。
  • JRE(Java Runtime Enviroment),Java运行环境,用于运行Java字节码文件。JRE中包括了JVM以及JVM工作所需要的类库,普通用户只需要安装JRE来运行Java程序,而程序开发者必须安装JDK来编译,调试程序。
  • JVM(Java Virtual Mechinal),Java虚拟机,是JRE的一部分,它是整个Java实现跨平台的最核心的部分,负责运行字节码文件。

我们写Java代码,用txt就可以写,但写出来的Java代码,想要运行,需要先编译成字节码,那就需要编译器,而JDK中就包含了编译器javac,编译后的字节码,想要运行,就需要一个可执行字节码程序,这个 程序就是JVM(Java虚拟机),专门用来执行Java字节码。

如果我们要开发Java程序,那么就需要JDK,因为要编译源文件。
如果我们只想运行已经编译好的Java字节码文件,也就是*.class文件,那么只需要JRE。
JDK中包含了JRE,JRE中包含了JVM。
另外,JVM在执行Java字节码时,需要把字节码解释为机器指令,而不同操作系统的机器指令是有可能不一样的 ,所以就导致不同操作系统上的JVM是不一样的,所以我们在安装JDK时需要选择操作系统。
另外,JVM是用来执行Java字节码的 ,所以凡是某个代码编译之后是Java字节码,那就都能在JVM上运行,比如Apache Groovy,Scala and Kotlin等等。

2.hashcode()与equals()之间的关系

在Java中,每个对象都可以调用自己的hashCode()方法得到自己的哈希值(hashCode),相当于对象的 指纹信息,通常来说世界上没有完全相同的两个指纹,但是在Java中做不到那么绝对,但是我们仍然可以利用hashCode来做一些提前的 判断,比如:

  • 如果两个对象的hashCode不相同,那么对象肯定不是同一个对象
  • 如果两个对象都hashCode相同,不代表两个对象一定是同一个对象,也可能是两个对象
  • 入股两个对象 相等,那么他们的hashCode就一定相同

在Java的一些集合类的实现中,比较两个对象是否相等时,会根据上面的原则,会 先调用对象的 hashCode()方法得到hashCode进行比较 ,如果hashCode不相同,就可以直接认为这两个对象不相同,那么就会进一步调用equals()方法进行比较。而equals()方法,就是用来最终确定两个对象是不是相等的,通常equals方法的实现会比较重,逻辑比较多,而hashCode()主要就是得到一个哈希值,实际上就一个数字,相对而言比较轻,所以比较两个对象时,通常都会先根据hashCode先比较一下。

所以我们就需要注意,如果我们重写了equals()方法,那么就要注意hashCode()方法,一定要保证能遵守上述规则。

在这里插入图片描述
hashCode相同时才会调用equals方法判断值是否相同

3.string、StringBuffer、StringBuilder的区别

1.String是不可变的,如果尝试去修改,会生成一个字符串对象,StingBuffer和StringBuilder是可变的
2.StringBuffer是线程安全的,StringBuilder是线程不安全的,所以在单线程环境下StringBuilder效率会更高

4.泛型中extends和super的区别

1.<? extends T>表示包括T在内的 任何T的子类
2.<? super T>表示包括T在内的任何父类

另外泛型只在编译时有效果,在运行时没有效果
在这里插入图片描述
最后输出为true

5.==和equals方法的区别

  • ==:如果是基本数据类型比较的是值,如果是引用数据类型比较的是引用地址。
  • equals:具体看各个类重写equals方法后的比较逻辑,比如Sring类,虽然是引用类型,但是Srting类中重写了equals方法,方法内部比较的是字符串中各个字符是否全部相等。

6.重载和重写的区别

  • 重载(Overload):在一个类中,同名方法如果有不同的参数列表(比如参数个数不同,参数类型不同)则视为重载。
    在这里插入图片描述
    返回值不同时,不是重载,编译报错
  • 重写(Override):就是在子类中把父类本身有的方法重写一边。子类基础了父类的方法,但有时子类并不想原封不动的继承父类中的某个方法没所以在方法名,参数列表,返回类型都相同(子类中方法的返回值可以是父类中方法返回值的子类)的情况下,对方法进行修改,这就是重写。但要注意子类方法的访问修饰权限不能小于父类的,如果父类的访问修饰符为private,则不能重写。

7.List和Set的区别

  • List:有序,按对象插入顺序保存对象,可重复,允许多个Null元素对象,可以使用Iterator取出所有元素,在逐一遍历,还可以使用get(int index)获取指定下标的元素
  • Set:无序,不可重复,最多允许有一个Null元素对象,取元素时只能用Iterator接口取得所有元素,在逐一遍历个元素

8.ArrayList和LinkedList区别

  1. 首先,他们的底层数据结构不同,ArrayList底层是基于数组实现的,LinkedList底层是基于链表实现的
  2. 由于底层数据结构不同,他们所适用的场景也不同,ArrayList更适合随机查找,LinkedList更适合删除和添加,查询、添加、删除的时间复杂度不同
  3. 另外ArrayList和LinkedList都实现了List接口,但是LinkedList还额外实现了Deque接口,所以LinkedList还可以当做队列来使用
    在这里插入图片描述

9.谈谈ConcurrentHashMap的扩容机制

1.7版本
1.7版本的ConcurrentHashMap是基于Segment分段实现的
每个Segment相对于一个小型的HashMap
每个Segment内部会进行扩容,和HashMap的扩容逻辑类似
先生成新的数组,然后转移元素到新数组中
扩容的判断也是每个Segment内部单独判断的,判断是否超过阈值

1.8版本
1.8版本的ConcurrentHashMap不再基于Segment实现
当某个线程进行put时,如果发现ConcurrentHashMap正在进行扩容那么该线程一起进行扩容
如果某个线程put时,发现没有正在进行扩容,则将key-value添加到ConcurrentHashMap中,然后判断是否超过阈值,超过了则进行扩容
ConcurrentHashMap是支持多个线程同时扩容的
扩容之前也先生成一个新的数组
在转移元素时,先将原数组分组,将每组分给不同的线程来进行元素的转移,每个线程负责一组或多组的元素转移工作

10.Jdk1.7到Jdk1.8 HashMap 发生了什么变化(底层)?

1、1.7中底层是数组+链表,1.8中底层是数组+链表+红黑树,加红黑树的目的是提高HashMap插入和查询整体效率
2、1.7中链表插入使用的是头插法,1.8中链表插入使用的是尾插法,因为1.8中插入key和value时需要判断链表元素个数,所以需要遍历链表统计链表元素个数,所以正好就直接使用尾插法
3、1.7中哈希算法比较复杂,存在各种右移与异或运算,1.8中进行了简化,因为复杂的哈希算法的目的就是提高散列性,来提供HashMap的整体效率,而1.8中新增了红黑树,所以可以适当的简化哈希算法,节省CPU资源

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值