1.JDK和JRE和JVM的区别和联系
在Java开发中,JDK(Java Development Kit)、JRE(Java Runtime Environment)和JVM(Java Virtual Machine)是三个重要的概念。它们在Java应用程序的开发、编译和执行过程中发挥不同的作用。
-
JDK(Java Development Kit):JDK是Java开发工具包,它是开发Java应用程序的基础。JDK包含了Java编译器(javac)和其他一系列开发工具,以及Java类库(API)和相关文档。JDK提供了开发人员所需的工具和资源,用于编写、编译、调试和运行Java代码。
-
JRE(Java Runtime Environment):JRE是Java运行时环境,它是在计算机上运行Java应用程序所需的最小环境。JRE包含Java虚拟机(JVM)和Java类库(API),用于解释和执行Java字节码。JRE只提供了Java应用程序的运行环境,没有开发工具。
-
JVM(Java Virtual Machine):JVM是Java虚拟机,它是Java程序在计算机上执行的运行时环境。JVM负责解释和执行Java字节码,并提供了内存管理、垃圾回收等运行时支持。JVM的主要功能是将平台无关的Java字节码翻译成特定操作系统和硬件平台的机器码。
联系和区别:
-
JDK包含了JRE。JDK除了包含JRE的所有组件外,还包含了用于开发Java应用程序的编译器、调试器和其他开发工具。
-
JRE是Java应用程序的运行时环境,只提供了Java应用程序的执行支持,不包含开发工具。
-
JVM是JRE的一部分,它是在JRE中执行Java字节码的虚拟机。JVM负责解释和执行字节码,并提供了运行时环境和支持。
JDK>JRE>JVM
2.Java的基本数据类型
四类八种: 整数型:byte(1 字节型)、short(2 短整型)、int(4 整型)、long(8 长整型)
浮点型:float(4 单精度浮点型)、double(8 双精度浮点型)
字符型:char(2)
布尔型:boolean
3.在Java中如何创建一个数组?
(1)使用默认的初始值来初始化一个数组中的每一个元素
数组元素类型[]数组名称 = new 数组元素类型[数组长度]
int [] scores = new int [50];
(2)先声明一个数组,在赋值数组初始值
数组元素类型[]数组名称;
数组名称 = new 数组元素类型[数组长度]
int [] scores; scores = new int [50];
(3)先声明一个数组,再使用特定的初始值将其初始化
数组元素类型 [ ] 数组名称 = new 数组元素类型 [ ]{元素1,元素2,......}
int [] scores = new int [ ]{88,99,100,92}
(4)使用特定值对数组赋值(此种只能在声明时赋值) 语法:数组元素类型 [ ] 数组名称 = {元素1,元素2,...... } int [] scores = {88,99,100,92}
4.Java中数组的特点
1) 数组中只能存储同一类型的数据
2)数组长度不可变
3)数组是一个有序集合
4)数组元素的内存地址是相连的
5)数组中的元素可以重复
5.数组的静态初始化和动态初始化以及它们的区别?
静态初始化:1)在创建数组时,直接指定数组元素的初始值。
2)使用花括号'{}'来包含初始值列表。
3)数组的长度由初始值的个数决定。
动态初始化:1)在创建数组时,只指定数组的长度,而不指定元素的初始值。
2)使用'new'关键字来创建数组对象。
3)需要通过赋值语句为每个元素赋予初始值。
区别:1)语法不同
2)初始值不同
3)数组长度不同
4)灵活性
6.break和continue的区别?
break: 1)break语句用于立即终止当前循环(适用于for、while、do-while等循环结构和switch 语句中).
continue:2)跳过当前循环中剩余的代码,直接进入下一次循环的迭代(只能适用于for、while、 do-while等循环结构).
7.switch支持的数据类型?
Java5以前:byte、short、char、int
Java5开始:引入枚举类型 enum
Java7开始:引入字符串String
8.类和对象的联系和区别?
类:将一组对象中的特征和行为提取出来的抽象模板
对象:根据类具象化(实例化)出来的具体事务
联系:类是对象的模板,用于定义对象的属性和行为
对象是类的一个具体实例,它具有类定义的属性和行为
区别:类是抽象的概念,用于描述对象的共同特征和行为,它定义了对象的结构和行为的规范。
对象是具体的实体,它是一个类的实例化对象,拥有类定义的属性值和可以执行的方法。
类是一种数据类型,而对象是该数据类型的实际实例。
类可以看作是对象的模板,通过实例化类可以创建多个对象。
9.new关键字的作用?
创建对象:使用new关键字在内存中为类创建一个新的对象实例。
分配内存:new关键字会在堆内存中为对象分配所需的内存空间。
调用构造函数:new关键字会调用类的构造函数来初始化对象。构造函数用于初始化对象的状 态和设置初始值。
返回对象引用:new关键字返回一个指向新创建对象的引用,通过该引用可以访问和操作对象 的属性和方法。
10.成员变量和静态变量的区别?
成员变量:类里、方法外,作用域是整个类,可以被类中的任何方法、构造方法和语句块访问。 可被访问修饰符修饰。
静态变量:类里、方法外,作用域为整个类,可以被类中的任何方法、构造方法和语句块访问。 使用static关键字修饰。
区别:
1)所属范围不同:静态变量-类,成员变量-对象。
2)存活时间不同:成员变量的生命周期与对象的生命周期相同;静态变量的生命周期与 类的生命周期相同。
3)调用方式不同:静态变量可以被类名和对象调用;成员变量只能通过对象名调用。
4)存储位置不同:静态变量-方法区里的静态区;成员变量-堆栈内存区。
11.final修饰符的作用?
final:可以修饰变量、方法和类。
修饰类:最终类,不能被继承。
修饰方法:最终方法,只能重载不能重写。
修饰变量:常量,值一旦确定,就不可修改。
finally: 异常处理语句结构的一部分,表示不管抛不抛异常都执行
finally是一个关键字,用于定义在try-catch语句块中的一个代码块,无论是否发生异常,finally中的代码都会被执行。通常用于释放资源或者清理工作。
12.访问控制符的访问范围?
public(公开的):本类、本包、其它包、其它包的子孙类
protected(受保护的):本类、本包、其它类的子孙类
不加访问控制符:本类、本包
private(私有的):本类
13.什么是构造方法?
作用:在构造方法中为创建的对象初始化赋值
特点:与类同名,且没有返回值类型(包括void)
在使用new关键字创建对象时自动调用
可以有多个重载版本,根据参数类型和数量来区分
可以被重载,不能被继承
没有显式定义构造方法时,会有一个默认的无参构造方法
14.什么是构造函数?
构造函数的名称与类名相同,并且没有返回类型(void).构造函数在创建对象时被调用,它负责 初始化对象的状态,为对象的成员变量赋初始值
特点:构造函数创建对象时被隐式调用,使用new关键字实例化对象时会自动调用响应的构造函数
构造函数可以有参数,用于接收创建对象时提供的初始值
如果没有显式定义构造函数,Java会提供一个默认的无参构造函数,用于创建对象
15.接口和抽象类的区别?
接口: Java中接口使用Interface关键字修饰
抽象类: 被abstract修饰的类
区别:
相同点: 都不能被实例化
接口的实现类或抽象类的子类都只有实现了接口或抽象类中的方法后才能实例化
不同点: 1)接口只有定义,不能有方法的实现,而抽象类可以有定义与实现,方法可以在抽象 类中实现
2)实现接口的关键字为implements,继承抽象类的关键字为extends。一个类可以 实现多个接口,但一个类只能继承一个抽象类。
16.Java面向对象的三大特征:
1)封装:将数据和功能封装在类中,提供对外的安全访问接口,隐藏内部实现细节
优势:安全性,复用性,隐藏实现细节。
2)继承: 将类中共同的特征和行为,定义在一个类中。使用时只需继承过来即可
优点:代码复用性、扩展性
缺点:耦合度高
3)多态: 一个事物可以表现为多种形态
多态的体现:
1) 方法的重写: 子类中需要用到父类中的某些行为,但是该行为的实现方式 需要修改
1)方法名、参数列表、返回值类型相同,
2)子类中重写父类的方法
3)子类方法不能抛出比父类方法更多的异常(但子类方法可 以不抛出异常)。
4)方法被定义为final不能被重写
2) 方法的重载: 当前类中,某个方法的参数不满足需求时使用重载
方法名一样,参数列表不同
不能重载只有返回值不同的方法名。
存在于父类和子类、同类中。
3) 向上转型: 父类型变量引用子类型对象
优势: 松耦合
17.静态方法能重写吗?
父类的静态方法只能重载,不能重写
18.引用数据类型和基本数据类型的区别?
基本数据类型的值是不可变的,引用数据类型的值是可变的
基本数据类型不可以添加属性和方法,引用数据类型可以添加属性和方法
基本数据类型的赋值是简单赋值,引用数据类型的赋值是对象引用
基本数据类型的比较是值的比较,引用数据类型的比较是引用的比较
基本数据类型放在栈区,引用数据类型放在堆区和栈区
引用数据类型可以为null
19.== 和 equals的区别?
equals是方法,==是运算符
equals是用来比较方法两个对象的内容是否相等,==基本数据类型比较值,引用数据类型比较 内存地址
20.int和integer的区别?
数据类型不同:int是基本数据类型,Integer是包装数据类型
默认值不同:int默认值是0,integer默认值是null
内存中存储方式不同:int存储的是数据值,integer存储的是对象引用,new一个integer相当于生 成一个指针指向对象;
实例化方式不同:integer必须实例化才可以使用,int则不用
变量的比较方式不同:int可以使用==来对比两个变量是否相等,integer使用equals来比较两个 变量是否相等
21.List和数组的区别:
数组必须规定大小,List没有大小规定
数组里的数据必须是同一类型,List则没有规定
List是个接口,可以有N多实现
22.ArrayList和LinkedList的区别:
底层实现:ArrayList是基于数组实现的,LinkedList是基于双线链表实现的
插入和删除效率:ArrayList效率较低,LinkedList效率较高
随机访问效率:ArrayList效率高,LinkedList效率低
内存空间的占用:相同数量元素下ArrayList内存空间占用比LinkedList更低
23.接口和抽象类的区别?
抽象类:被abstract修饰的类
抽象类不能被实例化
抽象类中可定义的内容和普通类一模一样,只是抽象类可以定义抽象方法
接口: 定义一组统一的规范,接口自己不实现,谁需要使用该规范,谁负责实现
接口中定义的成员方法默认被public、abstract修饰
接口中定义的变量,默认为全局静态变量
类实现接口的关键字为implements
类实现接口时,也可以继承其它类
一个类可以实现多个接口,接口也可以继承多个接口
24.String、StringBuffer、StringBuilder的区别?
String:不可变字符序列,底层是一个数组不可扩容
StringBuffer、StringBuilder: 可变字符串,更改内容时在原对象上更改,不会产生新对象,本 质上是一个字符串的操作类
StringBuffer: 是JDK1.0的时候的,线程安全
StringBuilder: 是JDK1.5的时候的,线程不安全
效率区别:StringBuilder>StringBuffer>String
5个String类的方法.equals()、charAt(int index)、.substring()、.length(获取字符个 数)、.indexOf()
25.super和this的作用?
指代对象不同:super指代父类,用来访问当前类;this指代当前类
查找范围不同:super只能查找父类,this会先从本类找,找不到再去父类找
本类属性值不同:this可以用来为本类的实例属性赋值,super没有此功能
this可用于synchronized 注解:因为 this 表示当前对象,所以this 可用于 synchronized(this) {....} 加锁,而 super 则不能实现此功能。
26.&和&&的区别?
逻辑与(&&): 有假即为假;
& 符号的左右两边,无论真或假都要执行 && 符号的左边如果为假,符号的右边不再执行,提高了 代码的执行效率
&&:短路与,当某个表达式结果已经为false,后面的表达式不再执行
&:通路与,当某个表达式结果已经为false,后面的表达式继续进行
27.Java的初始化过程?
1.分配内存:在内存中为对象分配足够的内存空间
2.设置默认值:将对象的成员变量设置为默认值。数据类型为0,布尔类型为false,引用类型为null
3.执行初始化块: 如果有定义初始块(初始化块用花括号包围的代码块),则按照在代码中出现的顺序执行初 始化块
4.执行构造函数: 根据对象的实际类型,调用相应的构造函数。构造函数中的代码会被执行,以完成对象的初始化过程
注意:初始化顺序:初始化块和构造函数的执行顺序与它们在代码中的出现顺序相同
继承关系:对于继承关系的类,先执行父类的初始化过程1,然后在执行子类的初始化过程
静态成员初始化:静态成员(包括静态变量和静态初始块)会在类加载时执行,而不是在对象创建时执行。静态成员的初始化只会执行一次
28.List如何排序?
单条件降序、单条件升序、多条件降序、多条件升序
29.泛型中问号是什么?
问号在Java的泛型中也已作为通配符
只有一个问号:?,是表示可以存放任何类型。
? extends A,表示可以存放A的子类或孙类
? super A,表示可以存放A的父类或祖先类
30.String直接赋值和new String()的区别?
直接赋值方式:在Java中,使用直接赋值创建字符串常量时,Java会先在字符串常量池中查找是否有相同的字符串,如果有,则返回该字符串的引用。如果没有,则创建一个新的字符串对象,并将其添加到字符串常量池中。因此,对于相同的字符串常量,它们所引用的对象是同一个。3
new String() 方式:在Java中,使用 new 关键字和构造函数创建字符串时,会在堆内存中重新分配新的内存空间,并在该空间中创建一个新的字符串对象。由于是新的内存空间,因此即使创建两个内容相同的字符串,它们也相互独立。
直接赋值方式在Java中是建立字符串的常用方式。这种方式可以通过充分利用字符串常量池来提高性能,减小内存开销,而使用 new String() 的方式则会产生额外的内存开销,只在必要时才应该使用。
31.HashMap底层是什么?描述下添加键值对的过程?
HashMap底层采用哈希表结构(数组+链表、JDK1.8后为数组+链表+红黑树)实现,结合了数组和链表的优点:
数组的默认长度为
数组优点: 通过数组下标可以快速实现对数组元素的访问,效率极高;初始长度是16,存储的元素类型是Node类型。负载因子
链表优点: 插入或删除数据不需要移动元素,只需修改节点引用,效率极高。
总结HashMap的存储过程就一句话:HashMap内部维护了一个存储数据的Entry[]或者Node[]数组,采用链表来解决哈希冲突,每一个Entry或者Node节点其实都是一个单向链表。
32.LinkedHashMap和 HashMap 都是 Java 中用于存储键值对的映射表。主要区别在于:
-
顺序:LinkedHashMap 会按照元素插入的顺序遍历,而 HashMap 则没有特定的顺序。
-
实现:LinkedHashMap内部使用链表来维护元素的顺序,而 HashMap 使用数组+链表的结构。
-
性能:在需要保证顺序的场景下使用LinkedHashMap会有较差的性能,因为需要维护链表。而HashMap没有这样的限制,性能会更高。
-
常用用途:HashMap通常用于简单的键值映射,而LinkedHashMap 则多用于缓存和 LRU 算法中。
33.装箱和拆箱
装箱:基本数据类型转换为引用数据类型
拆箱:引用数据类型转换为基本数据类型
34.collention和collentions的区别?
Collection
接口提供了对集合的基本操作方法,如添加、删除、查询、遍历等。实现该接口的类主要有List和Set (对象)
表示一组对象的集合
Collection
是一个接口,表示集合对象的行为,而Collections
是一个实用(工具)类,提供了对集合的各种操作方法
34.什么是 Lambda表达式?
Lambda 表达式是 Java 8 引入的一种函数式编程的特性。它是一种匿名函数,可以作为参数传递给方法或存 入变量中,使得代码更加简洁和易读。
-
参数列表可以为空,或者包含一个或多个参数,用逗号分隔。
-
->
是 Lambda 运算符,将参数和代码块分隔开。 -
代码块可以是一条或多条语句,可以包含任意有效的 Java 代码。
-
如果代码块只有一条语句,可以省略花括号
{}
。 -
如果代码块中有返回值,可以使用
return
语句返回值。
35.(重复)引用数据类型和基本数据类型在Java中有以下区别
-
基本数据类型(Primitive data types):表示简单的数据类型,包括整数、浮点数、字符、布尔值等,如 int、double、char、boolean 等。
引用数据类型(Reference data types):表示复杂的数据类型,包括类、接口、数组等,如类对象、数组对象等。 -
存储方式:基本数据类型:存储在栈(Stack)内存中,直接存储数据的值。
引用数据类型:存储在堆(Heap)内存中,变量存储的是对象的引用,即内存地址。 -
默认值:基本数据类型:具有默认值,例如 int 类型的默认值为 0,boolean 类型的默认值为 false。
引用数据类型:默认值为 null,表示引用变量不指向任何对象。 -
大小:基本数据类型:占用固定的内存空间,大小与具体的数据类型有关。
引用数据类型:占用的内存空间大小由具体的对象决定,引用变量本身的大小是固定的。 -
传递方式:基本数据类型:按值传递,方法中对基本数据类型的修改不会影响到原始值。
引用数据类型:按引用传递,方法中对引用数据类型的修改会影响到原始对象。 -
操作:基本数据类型:支持基本的运算操作,如加减乘除、逻辑运算等。
引用数据类型:可以调用对象的方法和访问对象的属性。
36.TCP的连接过程和断开过程
三次握手(连接过程):
1) 客户端向服务器发送一个特殊的TCP报文段,称为SYN(同步)报文 段,包含一个初始序列号(ISN)。
2)服务器接收到SYN报文段后,会回复一个SYN-ACK(同步-应答)报文 段作为响应。该报文段中包含确认号(ACK)字段,用于确认客户端的 ISN,并包含服务器的初始序列号(ISN)。
3)客户端接收到服务器的SYN-ACK报文段后,会发送一个确认报文段 (ACK)来确认服务器的ISN。此时,TCP连接已建立,双方可以开始进 行数据传输。
四次挥手(断开过程):
1) 当一方希望关闭连接时,发送一个特殊的TCP报文段,称为FIN(结 束)报文段,表示不再发送数据。
2)接收到FIN报文段的一方发送一个确认报文段(ACK)作为响应,确认 接收到FIN报文段。此时,该方仍然可以发送数据,但不再接收新的数 据。
3)另一方确认接收到FIN后,也发送一个FIN报文段来关闭连接。
4)接收到第二个FIN报文段的一方再发送一个ACK报文段进行确认。此 时,TCP连接断开。