Java 面试题
Java 面试题
问题 1.解释 JVM、JRE 和 JDK。
JVM(Java 虚拟机):JVM(Java 虚拟机)充当运行 Java 应用程序的运行时引擎。JVM 是调用 Java 代码中存在的主方法的那个。JVM 是 JRE(Java 运行时环境)的一部分。 JRE(Java 运行时环境):JRE 是指可以在其中执行 Java 字节码的运行时环境。它实现了 JVM(Java 虚拟机),并提供 JVM 在运行时使用的所有类库和其他支持文件。因此,JRE 是一个软件包,其中包含运行 Java 程序所需的内容。它是物理存在的 JVM 的实现。 JDK(Java 开发工具包):它是编译、记录和打包 Java 程序所需的工具。JDK 完全包含 JRE,其中包含 Java 程序员的工具。Java 开发工具包是免费提供的。除了 JRE,它还包括一个解释器/加载器、一个编译器 (javac)、一个归档器 (jar)、一个文档生成器 (Javadoc) 以及 Java 开发所需的其他工具。简而言之,它包含 JRE + 开发工具。
问题 2.解释 public static void main(String args[])。
- Public:Public 是访问修饰符。Public 表示此方法可由任何类访问。
- static: 它是 Java 中的一个关键字,用于将其标识为基于类的,即无需创建类的实例即可访问它。由于我们希望在没有任何实例的情况下执行 main 方法,因此我们使用 static。
- Void: 它是方法的返回类型。Void 定义不会返回任何值的方法。
- main:这是 JVM 执行的第一个方法。该方法的签名必须相同。
问题 3.为什么 Java 是独立于平台的?
平台独立性实际上意味着 “一次编写,随处运行”。Java 之所以这样称呼,是因为它的 字节码 可以在任何系统上运行,而不管其底层作系统如何。
问题 4.为什么 Java 不是纯粹的面向对象的?
Java 不被认为是纯粹的面向对象的,因为它支持原始数据类型,例如 boolean、byte、char、int、float、double、long 和 short。
问题 5.定义类和对象。用一个使用 Java 的例子来解释它们。
- 类:类是用户定义的蓝图或原型,对象由此创建。它表示一组属性或方法,这些属性或方法对于一种类型的所有对象都是通用的。通常,类声明可以按顺序包含这些组件。
- 超类(如果有): 类的父类(超类)的名称(如果有),前面带有关键字 extends。一个类只能扩展(子类)一个父类。
- 接口: 类的父类(超类)的名称(如果有),前面带有关键字 extends。一个类只能扩展(子类)一个父类。
- 对象: 它是面向对象编程的基本单位,代表现实生活中的实体。典型的 Java 程序会创建许多对象,您知道,这些对象通过调用方法进行交互。对象由以下部分组成:
- 状态: 它由对象的属性表示。它还反映了对象的属性。
- 行为: 它由对象的方法表示。它还反映了对象对其他对象的响应。
- 标识: 它为对象提供唯一名称,并使一个对象能够与其他对象交互。
例如,Employee 是类的一个示例。具有唯一标识的特定员工是对象的一个示例。
class Employee
{
// 实例变量声明
// 方法定义
}
员工的对象是特定的员工
Employee empObj = new Employee();
Employee 的对象之一由 ‘empObj’ 引用
问题 6.什么是方法?提供方法的多个签名。
-
Java 方法是一组用于执行任务的语句。将方法放置在类中。
-
方法签名:方法的名称和参数(类型和顺序)构成方法签名。
-
方法的签名中可以包含以下元素:
- 访问说明符 – public、private、protected 等(非强制性)
- 访问修饰符 – static、synchronized 等(非强制性)
- 返回类型 – void、int、String 等(必选)
- 方法名称 – show() (强制性)
- 带或不带参数 – (int number, String name);(括号为必填项)
例:
class Test {
void fun1() {}
public double fun2(double x) {}
public static void fun3() {}
public static void fun4(String x) {}
}
问题 7.解释实例变量和类变量之间的区别。
实例变量是每个对象/实例具有一个副本的变量。这意味着每个对象都将有一个副本。类变量是每个类具有一个副本的变量。类变量在对象中没有副本。
例:
class Employee {
int empNo;
String empName, department;
double salary;
static int officePhone;
}
empObj1 引用的对象是使用以下命令创建的:
员工 empObj1 = new Employee();
实例变量 empObj1 和 empObj2 引用的对象具有单独的副本 empNo、empName、department 和 salary。但是,officePhone 属于类(类变量),可以作为 Employee.officePhone 访问。
问题 8.哪个类是所有类的超类?
java.lang.Object 是所有 Java 类的根类,我们不需要扩展它。
问题 9.Java 中的构造函数是什么?
在 Java 中,构造函数是指用于初始化对象的代码块。它必须与类的名称相同。此外,它没有返回类型,并在创建对象时自动调用。 如果类未明确声明任何参数,则 Java 编译器会自动提供无参数构造函数,也称为默认构造函数。 此默认构造函数调用类父类的无参数构造函数(因为它只包含一个语句,即 super();),或者如果该类没有其他父类(因为 Object 类是所有类的父类,无论是直接还是间接),则调用 Object 类构造函数。
有两种类型的构造函数:
- 默认构造函数
- 参数化构造函数
问题 10.在 Java 中创建对象有哪些不同的方法?
在 Java 中创建对象的方法有很多种。
1 使用 new 关键字
2 使用新实例
3 使用 clone() 方法
4 使用反序列化
5 使用构造函数类的 newInstance() 方法
问题 11.静态方法和静态变量的用途是什么?
当需要在类的多个对象之间共享方法或变量而不是为每个对象创建单独的副本时,我们使用 static 关键字使所有对象共享方法或变量。
静态变量:静态变量也称为类变量。
- 这些变量的声明方式与实例变量类似,不同之处在于静态变量是使用类中任何方法构造函数或块之外的 static 关键字声明的。
- 与实例变量不同,无论我们创建了多少个对象,每个类都只能有一个静态变量的副本。
- 静态变量在程序执行开始时创建,并在执行结束时自动销毁。
- 要访问静态变量,我们不需要创建该类的对象。
静态方法:无需创建对象即可访问静态方法。只需使用类名,即可访问该方法。静态方法只能访问静态变量,而不能访问本地或全局非静态变量。
例如:
class StaticMethod {
public static void printMe()
{
System.out.println("直接通过类名访问静态方法!");
}
}
class MainClass {
public static void main(String args[])
{
StaticMethod.printMe();
}
}
输出
直接通过类名访问静态方法!
问题 12.为什么静态方法不能访问非静态变量或方法?
静态方法不能访问非静态变量或方法,因为静态方法可以在不实例化类的情况下访问,因此如果类未实例化,则变量未初始化,因此无法从静态方法访问。
问题 13.什么是静态类?
如果类的所有变量和方法都是静态的,并且构造函数是私有的,则可以说该类是静态类。 将构造函数设为私有将阻止实例化该类。 因此,访问的唯一可能性是仅使用类名。
问题 14.解释 Java 中有多少种类型的变量?
Java 中有三种类型的变量:
- 局部变量
- 实例变量
- 静态变量
局部变量:在块或方法或构造函数中定义的变量称为局部变量。 这些变量是在进入块或调用函数时创建的,并在退出块或调用从函数返回后销毁。这些变量的作用域仅存在于声明变量的块内。即,我们只能在该块内访问这些变量。
// Java program to demonstrate local variables
public class LocalVariable
{
public void getLocalVarValue()
{
// 局部变量 年龄
int localVar = 0;
localVar = localVar + 11;
System.out.println("局部变量的值" +
" 是: " + localVar);
}
public static void main(String args[])
{
LocalVariable obj = new LocalVariable();
obj.getLocalVarValue();
}
}
输出:
局部变量的值是: 11
在上面的程序中,变量 localVar 是函数 getLocalVarValue() 的局部变量。如果我们在 getLocalVarValue() 函数之外使用变量 localVar,编译器将产生错误“找不到符号 localVar”。
实例变量:实例变量是非静态变量,在任何方法、构造函数或块之外的类中声明。由于实例变量是在类中声明的,因此这些变量是在创建类的对象时创建的,并在对象被销毁时销毁。与局部变量不同,我们可以对实例变量使用访问说明符。如果我们不指定任何访问说明符,则将使用默认访问说明符。
// Java program to demonstrate instance variables
public class InstanceVariable {
int instanceVarId;
String instanceVarName;
public static void main(String args[])
{
InstanceVariable obj = new InstanceVariable();
obj.instanceVarId = 0001;
obj.instanceVarName = "InstanceVariable1";
System.out.println("Displaying first Object:");
System.out.println("instanceVarId==" + obj.instanceVarId);
System.out.println("instanceVarName==" + obj.instanceVarName);
InstanceVariable obj1 = new InstanceVariable();
obj1.instanceVarId = 0002;
obj1.instanceVarName = "InstanceVariable2";
System.out.println("Displaying Second Object:");
System.out.println("instanceVarId==" + obj1.instanceVarId);
System.out.println("instanceVarName==" + obj1.instanceVarName);
}
}
输出
Displaying first Object:
instanceVarId==1
instanceVarName==InstanceVariable1
Displaying Second Object:
instanceVarId==2
instanceVarName==InstanceVariable2
在上述程序中,变量(即 instanceVarId、instanceVarName)是实例变量。如果我们有多个对象(如上述程序所示),则每个对象都会有自己的实例变量副本。从上述输出中可以清楚地看出,每个对象都会有自己的实例变量副本。 静态变量:静态变量也称为类变量。
- 这些变量的声明方式与实例变量类似,不同之处在于静态变量是使用类中任何方法构造函数或块之外的 static 关键字声明的。
- 与实例变量不同,无论我们创建了多少个对象,每个类都只能有一个静态变量的副本。
- 静态变量在程序执行开始时创建,并在执行结束时自动销毁。
要访问静态变量,我们不需要创建该类的对象,我们可以简单地访问变量:
// Java program to demonstrate static variables
public class StaticVar {
private static int count = 0;
private int nonStaticCount = 0;
public void incrementCounter()
{
count++;
nonStaticCount++;
}
public static int getStaticCount()
{
return count;
}
public int getNonStaticCount()
{
return nonStaticCount;
}
public static void main(String args[])
{
StaticVar stVarObj1 = new StaticVar();
StaticVar stVarObj2 = new StaticVar();
stVarObj1.incrementCounter();
stVarObj2.incrementCounter();
System.out.println("Static count for stVarObj1: " +
stVarObj1.getStaticCount());
System.out.println("NonStatic count for stVarObj1: " +
stVarObj1.getNonStaticCount());
System.out.println("Static count for stVarObj2: " +
stVarObj2.getStaticCount());
System.out.println("NonStatic count for stVarObj2: " +
stVarObj2.getNonStaticCount());
}
}
输出
Static count for stVarObj1: 2
NonStatic count for stVarObj1: 1
Static count for stVarObj2: 2
NonStatic count for stVarObj2: 1
在上面的程序中,stVarObj1 和 stVarObj2 共享同一个静态变量 count 实例,因此如果值增加一个对象,则增加的值将反映在 stVarObj1 和 stVarObj2 中。
问题 14.Set 和 List 界面有什么区别?
Set 和 List 都是 Collection 接口的子接口。它们之间有以下两个主要区别
- List 可以保存重复值,但 Set 不允许。
- 在 List 接口中,数据按插入顺序存在,但在 Set 的情况下,插入顺序不保留。
问题 15.StringBuffer 和 String 有什么区别?
String 类是一个不可变类,即一旦创建就无法修改其内容。而 StringBuffer 是一个可变类,这意味着您可以稍后更改其内容。每当我们更改 String 对象的内容时,它都会创建一个新字符串并引用该字符串,而不会修改现有字符串。这就是 StringBuffer 的性能优于 String 的原因。
问题 16.什么时候使用 super 关键字?
super 关键字用于指代:
- 直接父类构造函数
- 直接父类变量
- 直接父类方法
问题 17.Java 中 HashMap 和 HashTable 的区别。
- HashMap 是非同步的。它不是线程安全的,如果没有适当的同步代码,就不能在多个线程之间共享,而 Hashtable 是同步的。它是线程安全的,可以与多个线程共享。
- HashMap 允许一个空键和多个空值,而 Hashtable 不允许任何空键或值。
- 如果不需要线程同步,通常优先使用 HashMap 而不是 HashTable。
问题 18.如果从 main 方法中删除 static 修饰符会发生什么情况?
程序编译成功。但在运行时会引发错误 “NoSuchMethodError”。
问题 19.我们可以重载 main() 方法吗?
Java 中的 main 方法不是外星方法。除了 main() 与任何其他方法一样并且可以类似地重载之外,JVM 总是寻找方法签名来启动程序。
- 常规的 main 方法充当 JVM 开始执行程序的入口点。
- 可以在 Java 中重载 main 方法。但是当我们运行程序时,程序不会执行重载的 main 方法,我们只需要从实际的 main 方法调用重载的 main 方法。
问题 20.什么是 Java 中的包装器类?
包装类将 Java 原语转换为引用类型(对象)。每个原始数据类型都有一个专用的类。这些被称为包装类,因为它们将原始数据类型“包装”到该类的对象中。
问题 21.为什么 Java 中不使用指针?
Java 不使用指针,因为它们不安全并且会增加程序的复杂性。由于 Java 以代码简单而闻名,因此添加指针的概念将会产生矛盾。此外,由于 JVM 负责隐式内存分配,因此为了避免用户直接访问内存,Java 中不鼓励使用指针。
问题 22.Java 中的集合是什么意思?
该集合是一个框架,旨在存储对象并纵设计以存储对象。
集合用于执行以下作:
- 搜索
- 排序
- 操纵
- 插入
- 删除
一组对象称为集合。所有用于收集的类和接口都在 Java util 包中可用。
问题 23.什么是同步?
同步使一次只有一个线程访问一个代码块。如果多个线程访问该代码块,则最终结果可能会不准确。为了避免这个问题,我们可以为敏感的代码块提供同步。
synchronized关键字表示线程需要一个键来访问同步的代码。
每个 Java 对象都有一个锁。一个锁只有一个密钥。只有当线程可以获得要锁定的对象的密钥时,该线程才能访问同步方法。锁是每个对象的。
问题 24.同步的缺点是什么?
不建议使用同步来实现所有方法。因为如果一个线程访问同步代码,那么下一个线程应该必须等待。因此,这会降低另一端的性能。