1.jdk,jre,jvm三者区别和联系
JDK:Java Development Kit java开发工具
- 定义: JDK是Java开发工具包,提供了Java应用程序的开发环境。
- 包含内容: JDK包含了JRE以及用于Java开发的一系列工具,例如编译器(javac)、调试器(jdb)、JavaDoc生成器等。
- 用途: JDK是用于开发Java应用程序的完整工具包,包括了编写、编译和调试代码所需的一切。
JRE:Java Runtime Environment java运行时环境
- 定义: JRE是Java运行时环境,为Java应用程序的运行提供了必要的支持。
- 包含内容: JRE包含了Java虚拟机(JVM)和一组核心类库,这些类库是Java应用程序运行所必需的。
- 用途: JRE适用于在用户计算机上执行已经编译好的Java应用程序,而不涉及开发过程。
JVM:Java Virtual Machine java虚拟机
简而言之,JDK用于开发Java应用程序,包括了JRE和开发工具;JRE用于运行已经编译好的Java应用程序,包含了JVM和核心类库;JVM是Java程序的运行引擎,负责将Java字节码转换为机器码并执行。
2.什么是面向对象(oop)
在面向对象编程中,软件系统被看作是一组相互作用的对象,每个对象都有自己的状态(属性)和行为(方法),并且能够与其他对象进行交互。
- 定义: JVM是Java虚拟机,是Java程序的运行引擎。
- 功能: JVM负责在计算机上执行Java字节码(由Java源代码编译而成),将其转换为机器码并执行。
- 用途: JVM使得Java程序能够在不同平台上实现“一次编写,到处运行”的目标,因为它提供了一个抽象层,使得Java程序可以独立于底层硬件和操作系统运行。
-
联系和关系:
- JDK包含JRE,因为在开发过程中,开发者需要JRE来验证他们的代码在运行时的表现。
- JRE包含JVM,因为JVM是执行Java程序的核心引擎,而JRE则是为Java程序提供运行时环境的集合。
- JDK不仅包含JRE,还包含了一系列用于开发的工具和库,因此可以说JDK是一个更大的集成包。
-
封装(Encapsulation): 封装是将对象的状态(属性)和行为(方法)捆绑在一起的机制。通过封装,对象的内部细节被隐藏,外部调用无需关心内部方法的实现。就比如Javabean的属性是私有的,提供getset对外访问,因为属性的赋值或者获取逻辑只能由javabean本身决定,而不能由外部胡乱修改
-
继承(Inheritance): 继承是一种机制,允许一个类(子类/派生类)继承另一个类(父类/基类)的属性和方法。通过继承,子类可以重用父类的代码,并且可以在不修改父类代码的情况下添加新的功能或修改行为。这有助于提高代码的重用性和扩展性。
-
多态(Polymorphism):继承,方法重写,父类引用指向子类对象
基于对象所属类的不同,外部对同一方法的调用,实际执行逻辑不同,无法调用子类特有的功能
3.==和equals
==对比的是栈中的值,基本数据类型是变量的值,引用类型是堆中内存对象的地址
equals:object中默认也是采用==比较,通常会重写
String重写equals方法,比较字符串的内容
4.final
修饰类:表示类不可被继承
修饰方法:表示方法不可以被子类覆盖,但是可以重载
修饰变量:表示变量一旦被赋值就不可以更改它的值
5.重写和重载
- 重写(Overriding) 发生在子类中,用于覆盖父类的方法,保持方法签名相同,但提供不同的实现。方法名和参数列表必须相同,返回值范围小于等于父类,抛出异常范围小于等于父类,访问修饰符范围大于等于父类,如果父类方法访问修饰符为private则子类就不能重写该方法。
- 重载(Overloading) 发生在同一个类中,用于定义多个具有相同名字但参数列表不同的方法,以处理不同的输入。方法名必须相同,参数类型不同,个数不同,顺序不同,方法返回值和访问修饰符可以不同,发生在编译时。
6.String,StringBuffer,StringBuilder区别和使用场景
String是final修饰的,不可变,每次操作都会产生新的String对象
StringBuffer和StringBuilder都是在原对象上操作
StringBuffer是线程安全的,StringBuilder是线程不安全的
StringBuffer方法都是synchronized修饰的
性能:StringBuilder>StringBuffer>String
优先使用StringBuilder,多线程使用共享变量时使用StringBuffer
7.接口和抽象类的区别
1.抽象类可以存在普通成员函数,而接口中只能存在public abstract方法
2.抽象类只能继承一个,接口可以实现多个
3.抽象类中的成员变量是各种类型的,而接口中的成员变量只能是public static final类型的
接口只留下静态变量和方法更精简 抽象类还有成员属性和构造器
抽象类是对类本质的抽象,而接口是对行为的抽象
8.List和Set的区别
List:有序,按对象进入的顺序保存对象,可重复,允许多个Null元素对象,可以使用Iterator取出所有元素并逐一遍历,还可以使用get(int index)获取指定下标元素
Set:无序,不可重复,最多允许有一个Null元素对象,获取元素时只能用Iterator接口取得所有元素,在逐一遍历各元素
9.hashCode和equals
- 如果两个对象通过
equals
方法比较相等,那么它们的hashCode
应该相等。 - 如果两个对象通过
hashCode
相等,它们并不一定相等。这是由于哈希冲突,即不同对象可能产生相同的哈希码。 - equals方法被覆盖则hashCode方法也必须覆盖
10.ArrayList和LinkedList区别
ArrayList:基于动态数组,连续内存存储,适合下标访问
LinkedList:基于链表,可以存储在分散的内存
-
底层数据结构:
- ArrayList: 使用动态数组作为底层数据结构。数组的元素在内存中是连续存储的。
- LinkedList: 使用双向链表作为底层数据结构。链表中的元素在内存中不一定是连续存储的,每个元素都包含对前一个和后一个元素的引用。
-
随机访问性能:
- ArrayList: 支持快速的随机访问,因为它是基于数组的,可以通过索引直接访问元素。
- LinkedList: 随机访问性能相对较差,因为需要从头部或尾部开始遍历链表,直到找到目标元素。
-
插入和删除性能:
- ArrayList: 在中间或末尾插入/删除元素时,需要移动后续元素,性能相对较差。
- LinkedList: 在中间或末尾插入/删除元素时,性能较好,因为只需要改变相邻元素的引用。
-
内存占用:
- ArrayList: 比较节省内存,因为它只需要存储元素和数组长度。
- LinkedList: 需要额外的空间存储链表节点的引用,因此内存占用相对较高。
-
迭代性能:
- ArrayList: 适用于大部分的迭代操作,因为可以通过索引直接访问元素。
- LinkedList: 在迭代时,尤其是大规模数据集合时,性能相对较差。
-
适用场景:
- ArrayList: 适用于读取操作较多的场景,例如通过索引快速访问元素的情况。
- LinkedList: 适用于插入和删除操作较多的场景,特别是在链表中部插入/删除元素的操作。