发表时间:2022-03-25来源:网络
各类面试题

Java基础到框架面试题

Java面试集锦

其他资源

5、数据封装是什么意思?
数据封装是一种面向对象的编程概念,将数据属性及其行为隐藏在一个单元中。它通过确保每个对象通过拥有自己的方法、属性和功能而独立于其他对象,帮助开发人员在开发软件时遵循模块化。它用于对象私有属性的安全性,因此用于数据隐藏的目的。
6. 谈一谈 JIT 编译器
JIT 全称是 Just-In-Time,用于提高运行时的性能。它同时完成编译部分具有相似功能的字节代码的任务,从而减少代码运行的编译时间。编译器只不过是源代码到机器可执行代码的翻译器。但是 JIT 编译器有什么特别之处呢?让我们看看它是如何工作的:首先,Java 源代码 (.java) 到字节码 (.class) 的转换是在 javac 编译器的帮助下发生的。然后,JVM 在运行时加载 .class 文件,并在解释器的帮助下,将这些文件转换为机器可理解的代码。JIT 编译器是 JVM 的一部分。启用 JIT 编译器后,JVM 会分析 .class 文件中的方法调用并编译它们以获得更高效的本机代码。它还确保优化优先级方法调用。完成上述步骤后,JVM 将直接执行优化后的代码,而不是再次解释代码。这提高了执行的性能和速度。
笔记:
在类中未重写 equals 方法的情况下,该类使用父类的 equals 方法的默认实现。Object类被认为是所有java类的父类。Object 类中的 equals 方法的实现使用 == 运算符来比较两个对象。可以根据业务逻辑覆盖此默认实现。死循环是那些无限运行而没有任何中断条件的循环。
使用 For 循环:for (;;) { // Business logic // Any break logic }使用while循环:while(true){ // Business logic // Any break logic }使用 do-while 循环:do{ // Business logic // Any break logic }while(true);构造方法重载是在类中创建多个名字相同,参数不同的过程。根据参数的数量及其对应的类型,由编译器来区分不同类型的构造函数。
class Hospital { int variable1, variable2; double variable3; public Hospital(int doctors, int nurses) { variable1 = doctors; variable2 = nurses; } public Hospital(int doctors) { variable1 = doctors; } public Hospital(double salaries) { variable3 = salaries } }
此处定义了三个构造函数,但它们因参数类型和编号而异。
在 Java 中,通过在由相同名称组成的同一类中引入不同的方法来实现方法重载。尽管如此,所有函数在参数的数量或类型上都不同。它发生在一个类中,并增强了程序的可读性。
方法返回类型的唯一区别不构成方法重载。
class OverloadingHelp { public int findarea (int l, int b) { int var1; var1 = l * b; return var1; } public int findarea (int l, int b, int h) { int var2; var2 = l * b * h; return var2; } }
这两个函数具有相同的名称,但参数数量不同。第一种方法计算矩形的面积,而第二种方法计算长方体的面积。
方法重写是两个具有相同方法签名的方法存在于两个不同的类中的概念,其中存在继承关系。通过使用方法重写,子类可以实现特定的方法实现(已经存在于父类中)。
让我们看一下这个例子:

这两个类方法都具有名称 walk 和相同的参数、距离和时间。如果调用子类方法,则父类方法 walk 将被子类的方法重写。
是的,可以存在多个 catch 块,但特定的方法应该先于通用方法,因为只有满足 catch 条件的第一个 catch 块才会被执行。给定的代码说明了相同的内容:
public class MultipleCatch { public static void main(String args[]) { try { int n = 1000, x = 0; int arr[] = new int[n]; for (int i = 0; i 多线程:关于 String 对象的线程安全是 Java 中的一个重要方面。如果 String 对象是不可变的,则不需要外部同步。因此,可以编写更清晰的代码来跨不同线程共享 String 对象。这种方法促进了并发的复杂过程。集合:在 Hashtables 和 HashMaps 的情况下,键是 String 对象。如果 String 对象不是不可变的,那么它可以在它驻留在 HashMap 期间被修改。因此,无法检索所需的数据。这种不断变化的状态带来了很多风险。因此,使字符串不可变是非常安全的。20. 你如何区分 String、StringBuffer 和 StringBuilder?
可变性: String 是不可变的,而 StringBuilder 和 StringBuffer 都是可变的。线程安全:在线程环境的情况下,使用 StringBuilder 和 StringBuffer 而没有使用 String。但是StringBuilder适合单线程环境,StringBuffer适合多线程。句法:
// String String first = "InterviewBit"; String second = new String("InterviewBit"); // StringBuffer StringBuffer third = new StringBuffer("InterviewBit"); // StringBuilder StringBuilder fourth = new StringBuilder("InterviewBit");21. 使用相关属性突出接口和抽象类之间的差异。
方法的可用性:接口中只有抽象方法可用,而非抽象方法可以与抽象类中的抽象方法一起出现。变量类型:静态和最终变量只能在接口的情况下声明,而抽象类也可以有非静态和非最终变量。继承:接口促进了多重继承,而抽象类不促进多重继承。数据成员可访问性:默认情况下,接口的类数据成员是公共类型的。相反,抽象类的类成员也可以是受保护的或私有的。实现:借助抽象类,可以轻松实现接口。然而,反之则不然。抽象类示例:
public abstract class Athlete { public abstract void walk(); }接口示例:
public interface Walkable { void walk(); }22. 在 Java 中,可以覆盖静态方法和私有方法。这种说法是否正确。
上下文中的陈述是完全错误的。静态方法与对象无关,这些方法属于类级别。在子类的情况下,具有与父类完全相同的方法签名的静态方法可以存在,甚至不会引发任何编译错误。
这里提到的现象通常称为方法隐藏,覆盖肯定是不可能的。私有方法覆盖是不可想象的,因为私有方法的可见性仅限于父类。因此,只能促进隐藏而不是覆盖。
23. HashSet 与 TreeSet 有何不同?
尽管 HashSet 和 TreeSet 都不同步并确保不存在重复项,但还是有某些属性可以将 HashSet 与 TreeSet 区分开来。
24. 为什么字符数组比字符串更适合存储机密信息?
在 Java 中,字符串基本上是不可变的,即它不能被修改。在它声明之后,只要不以垃圾的形式被移除,它就会继续留在字符串池中。换句话说,在执行字符串值处理后,字符串会在内存的堆部分驻留一段不受限制且未指定的时间间隔。
因此,如果黑客非法访问内存转储,黑客可能会因从事有害活动而窃取重要信息。可以通过使用可变对象或结构(如字符数组)来存储任何变量来消除此类风险。字符数组变量的工作完成后,可以将变量同时配置为空白。因此,它有助于节省堆内存,也不会给黑客提取重要数据的机会。
25、Java中JVM、JRE和JDK的区别是什么?
标准JDKJREJVM缩写Java 开发工具包Java运行时环境Java虚拟机定义JDK 是用于开发 Java 应用程序的完整软件开发工具包。它包括 JRE、JavaDoc、编译器、调试器等。JRE 是一个软件包,提供 Java 类库、JVM 和运行 Java 应用程序所需的所有组件。JVM 是一个依赖于平台的抽象机器,由 3 个规范组成——描述 JVM 实现要求的文档、满足 JVM 要求的计算机程序和用于执行 Java 字节码并提供运行时环境的实例对象。主要目的JDK 主要用于代码开发和执行。JRE 主要用于创建环境来执行代码。JVM 为 JRE 的所有实现提供了规范。提供的工具JDK 为代码开发提供了编译器、调试器等工具JRE 提供了 JVM 运行程序所需的库和类。JVM 不包含任何工具,而是提供了实现规范。概括JDK = (JRE) + 开发工具JRE = (JVM) + 执行应用程序的库JVM = 执行 Java 字节码的运行时环境。使用 Runnable 接口的方法实现线程是更优选和有利的,因为 Java 不支持类的多重继承。start()方法用于为线程执行创建单独的调用堆栈。一旦创建了调用堆栈,JVM 就会调用该run()调用堆栈中执行线程的方法。
实现Callable接口Java 总是作为“传值”工作。Java 中没有所谓的“通过引用传递”。但是,当对象在任何方法中传递时,由于 Java 中对象处理的性质,传递的是值的地址。传递对象时,Java 创建引用的副本并将其传递给方法。对象指向相同的内存位置。方法内部可能会发生2种情况:
情况 1:当对象指向另一个位置时:在这种情况下,对该对象所做的更改在传递给方法之前不会反映原始对象,因为引用指向另一个位置。例如:
class InterviewBitTest{ int num; InterviewBitTest(int x){ num = x; } InterviewBitTest(){ num = 0; } } class Driver { public static void main(String[] args) { //create a reference InterviewBitTest ibTestObj = new InterviewBitTest(20); //Pass the reference to updateObject Method updateObject(ibTestObj); //After the updateObject is executed, check for the value of num in the object. System.out.println(ibTestObj.num); } public static void updateObject(InterviewBitTest ibObj) { // Point the object to new reference ibObj = new InterviewBitTest(); // Update the value ibObj.num = 50; } } Output: 20情况 2:当对象引用未被修改时:在这种情况下,由于我们拥有指向同一内存位置的主对象的引用副本,因此对象内容的任何更改都会反映在原始对象中。例如:
class InterviewBitTest{ int num; InterviewBitTest(int x){ num = x; } InterviewBitTest(){ num = 0; } } class Driver{ public static void main(String[] args) { //create a reference InterviewBitTest ibTestObj = new InterviewBitTest(20); //Pass the reference to updateObject Method updateObject(ibTestObj); //After the updateObject is executed, check for the value of num in the object. System.out.println(ibTestObj.num); } public static void updateObject(InterviewBitTest ibObj) { // no changes are made to point the ibObj to new location // Update the value of num ibObj.num = 50; } } Output: 50StringBuffer 本质上是可变的和动态的,而 String 是不可变的。String 的每次更新/修改都会创建一个新的 String,从而使字符串池中包含不必要的对象超载。因此,在大量更新的情况下,总是首选使用 StringBuffer,因为它会减少在字符串池中创建多个 String 对象的开销。
不会有任何编译错误。但随后程序运行,由于JVM无法映射主方法签名,代码在运行时抛出“NoSuchMethodError”错误。
程序无法编译,因为编译器说该方法已在类中定义。
36.异常如何在代码中传播?
当异常发生时,它首先搜索以定位匹配的 catch 块。如果找到匹配的 catch 块,则将执行该块。否则,异常会通过方法调用堆栈传播并进入调用者方法,在那里执行匹配 catch 块的过程。这种传播一直发生,直到找到匹配的 catch 块。如果未找到匹配项,则程序将在 main 方法中终止。

37. 在 try 块之后是否必须遵循 catch 块?
不,在 try 块之后没有必要出现 catch 块。- try 块之后应该跟一个 catch 块或一个 finally 块。如果异常可能性更大,则应使用方法的 throws 子句声明它们。
38. 当 return 语句写在 try 块和 catch 块的末尾时,finally 块是否会被执行,如下所示
public int someMethod(int i){ try{ //some statement return 1; }catch(Exception e){ //some statement return 999; }finally{ //finally block statements } }无论异常与否,finally 块都将被执行。不执行 finally 块的唯一情况是当它在 try/catch 块中的任何地方遇到“System.exit()”方法时。
39. 你能在另一个构造函数中调用一个类的构造函数吗?
是的,这个概念可以称为构造函数链接,可以使用this().

40. 连续的内存位置通常用于在数组中而不是在 ArrayList 中存储实际值
在 ArrayList 的情况下,无法以原始数据类型(如 int、float 等)的形式存储数据。ArrayList 中存在的数据成员/对象具有对位于内存中不同位置的对象的引用。因此,实际对象或非原始数据类型(如整数、双精度等)的存储发生在不同的内存位置。

但是,这不适用于数组。对象或原始类型值可以存储在连续内存位置的数组中,因此每个元素不需要对下一个元素的任何引用。

41. 虽然继承是一个流行的 OOPs 概念,但它不如组合有利。解释。
在以下场景中,继承落后于组合:
Java 中无法实现多重继承。类只能从一个超类扩展。在需要多种功能的情况下,例如 - 将信息读取和写入文件,组合模式是首选。可以通过将作者和读者功能视为私有成员来使用作者和读者功能。组合物有助于获得高灵活性并防止封装破裂。单元测试可以通过组合而不是继承来实现。当开发者想要测试一个组成不同类的类时,可以创建 Mock Object 来表示组成的类,以方便测试。这种技术在继承的帮助下是不可能的,因为如果没有继承中超类的帮助,就无法测试派生类。组合的松耦合特性优于继承的紧耦合特性。让我们举个例子:
package comparison; public class Top { public int start() { return 0; } } class Bottom extends Top { public int stop() { return 0; } }在上面的例子中,遵循了继承。现在,对 Top 类进行了一些修改,如下所示:
public class Top { public int start() { return 0; } public void stop() { } }如果按照Top类的新实现,Bottom类必然会出现编译时错误。Top.stop() 函数存在不兼容的返回类型。必须对 Top 或 Bottom 类进行更改以确保兼容性。但是,可以利用组合技术来解决给定的问题:
class Bottom { Top par = new Top(); public int stop() { par.start(); par.stop(); return 0; } }当字符串在赋值运算符的帮助下形成为文字时,它会进入字符串常量池,以便可以进行字符串实习。如果两个对象的内容相同,则堆中的同一个对象将被不同的字符串引用。
public bool checking() { String first = "InterviewBit"; String second = "InterviewBit"; if (first == second) return true; else return false; }当两个变量引用相同的内容时,checking() 函数将返回 true。

相反,当在 new() 运算符的帮助下形成字符串时,不会发生实习。即使存在相同的内容对象,该对象也会在堆内存中创建。
public bool checking() { String first = new String("InterviewBit"); String second = new String("InterviewBit"); if (first == second) return true; else return false; }由于两个变量未引用相同的内容,因此checking() 函数将返回false。

是的,尽管存在垃圾收集器,程序仍有可能耗尽内存。垃圾收集有助于识别和消除程序中不再需要的那些对象,以释放它们使用的资源。
在程序中,如果某个对象不可访问,则垃圾收集的执行将针对该对象进行。如果创建新对象所需的内存量不足,则在垃圾收集器的帮助下,为那些不再在范围内的对象释放内存。当释放的内存不足以创建新对象时,就会超出程序的内存限制。
此外,如果对象的创建方式使它们保留在作用域中并消耗内存,则会耗尽堆内存。开发人员应确保在完成工作后取消引用该对象。尽管垃圾收集器尽最大努力尽可能多地回收内存,但仍然可能超出内存限制。
让我们看一下下面的例子:
List example = new LinkedList(); while(true){ example.add(new String("Memory Limit Exceeded")); }通过同步可以同时执行不同的进程。当多个线程共享特定资源时,可能会出现多个线程需要相同共享资源的情况。
同步有助于解决问题,资源一次由一个线程共享。让我们举个例子来更清楚地理解它。例如,您有一个 URL,您必须找出对其发出的请求数。两个同时请求可能会使计数不稳定。
无同步:
package anonymous; public class Counting { private int increase_counter; public int increase() { increase_counter = increase_counter + 1; return increase_counter; } }
如果一个线程Thread1查看计数为10,它将增加1到11。同时,如果另一个线程Thread2查看计数为10,它会增加1到11。因此,计数值不一致,因为预期的最终值是 12,但我们得到的实际最终值将是 11。
现在,函数increase() 是同步的,因此不能同时进行访问。
同步:
package anonymous; public class Counting { private int increase_counter; public synchronized int increase() { increase_counter = increase_counter + 1; return increase_counter; } }
如果线程 Thread1 将计数视为 10,它将增加 1 到 11,然后线程 Thread2 将看到计数为 11,它将增加 1 到 12。因此,计数值发生了一致性。
Java线程生命周期如下:
New – 当线程的实例被创建并且 start() 方法未被调用时,线程被认为是活动的,因此处于 NEW 状态。Runnable – 一旦 start() 方法被调用,在 JVM 调用 run() 方法之前,线程被称为处于 RUNNABLE(准备运行)状态。这种状态也可以从线程的 Waiting 或 Sleeping 状态进入。运行- 当 run() 方法被调用并且线程开始执行时,线程被称为处于 RUNNING 状态。不可运行(阻塞/等待) ——当线程尽管处于活动状态而无法运行时,该线程被称为处于不可运行状态。理想情况下,在其活跃一段时间后,线程应该进入可运行状态。如果一个线程想要进入同步代码,但它无法进入,则称该线程处于阻塞状态,因为另一个线程正在同一对象的同步块中运行。第一个线程必须等到另一个线程退出同步块。如果一个线程正在等待来自另一个线程的信号执行,即它等待工作直到接收到信号,则称该线程处于等待状态。下面的流程图清楚地解释了 Java 中线程的生命周期。

可以多次导入一个类或包,但是,这是多余的,因为 JVM 在内部只加载一次包或类。
这是一个很大的问题。我们需要明白,一个包的子包的导入需要显式的完成。导入父包只会导致导入其中的类,而不是其子/子包的内容。
不。程序 post 的控制System.exit(0)立即消失,程序终止,这就是 finally 块永远不会执行的原因。
标记接口,也称为标记接口,是那些没有定义方法和常量的接口。它们用于帮助编译器和 JVM 获取有关对象的运行时相关信息。
这是在 Java 中初始化任何集合的便捷方式。考虑下面的例子。
import java.util.HashSet; import java.util.Set; public class IBDoubleBraceDemo{ public static void main(String[] args){ Set stringSets = new HashSet() { { add("set1"); add("set2"); add("set3"); } }; doSomething(stringSets); } private static void doSomething(Set stringSets){ System.out.println(stringSets); } }在上面的例子中,我们看到 stringSets 是使用双括号初始化的。
第一个大括号执行创建匿名内部类的任务,该类具有访问父类行为的能力。在我们的示例中,我们创建了 HashSet 的子类,以便它可以使用 HashSet 的 add() 方法。第二个大括号执行初始化实例的任务。通过此方法初始化时应小心,因为该方法涉及创建匿名内部类,这可能会在垃圾收集或序列化过程中引起问题,也可能导致内存泄漏。
现在,如果字符串包含增补字符,则长度函数会将其计为 2 个单位,并且 length() 函数的结果将与预期不同。
换句话说,如果有 2 个单位的 1 个增补字符,则该单个字符的长度被认为是两个 - 注意这里的不准确吗?根据java文档,这是预期的,但根据实际逻辑,它是不准确的。
如果在双引号(或字符串文字)中使用字母,则“位”将是打印的结果。但问题是使用了字符文字(单引号),这就是不会发生连接的原因。将添加每个字符的相应 ASCII 值,并打印该总和的结果。
'b'、'i'、't' 的 ASCII 值是:
98 + 105 + 116 = 319
因此将打印 319。
第一种方法:一旦达到对象创建目的,将对象引用设置为 null。
public class IBGarbageCollect { public static void main (String [] args){ String s1 = "Some String"; // s1 referencing String object - not yet eligible for GC s1 = null; // now s1 is eligible for GC } }第二种方法:将引用变量指向另一个对象。这样做,引用变量之前引用的对象将有资格进行 GC。
public class IBGarbageCollect { public static void main(String [] args){ String s1 = "To Garbage Collect"; String s2 = "Another Object"; System.out.println(s1); // s1 is not yet eligible for GC s1 = s2; // Point s1 to other object pointed by s2 /* Here, the string object having the content "To Garbage Collect" is not referred by any reference variable. Therefore, it is eligible for GC */ } }方法三:孤岛方法:当2个引用变量指向同一个类的实例,并且这些变量只相互引用,而这2个变量所指向的对象没有其他引用时,则称有形成了一个“隔离岛”,这两个对象有资格进行 GC。
public class IBGarbageCollect { IBGarbageCollect ib; public static void main(String [] str){ IBGarbageCollect ibgc1 = new IBGarbageCollect(); IBGarbageCollect ibgc2 = new IBGarbageCollect(); ibgc1.ib = ibgc2; //ibgc1 points to ibgc2 ibgc2.ib = ibgc1; //ibgc2 points to ibgc1 ibgc1 = null; ibgc2 = null; /* * We see that ibgc1 and ibgc2 objects refer * to only each other and have no valid * references- these 2 objects for island of isolcation - eligible for GC */ } }56. 使用递归检查给定的字符串是否是回文。
/* * Java program to check if a given inputted string is palindrome or not using recursion. */ import java.util.*; public class InterviewBit { public static void main(String args[]) { Scanner s = new Scanner(System.in); String word = s.nextLine(); System.out.println("Is "+word+" palindrome? - "+isWordPalindrome(word)); } public static boolean isWordPalindrome(String word){ String reverseWord = getReverseWord(word); //if word equals its reverse, then it is a palindrome if(word.equals(reverseWord)){ return true; } return false; } public static String getReverseWord(String word){ if(word == null || word.isEmpty()){ return word; } return word.charAt(word.length()- 1) + getReverseWord(word.substring(0, word.length() - 1)); } }主要思想是验证字符串的长度,如果发现相等,则将字符串转换为字符数组,然后对数组进行排序并检查两者是否相等。
import java.util.Arrays; import java.util.Scanner; public class InterviewBit { public static void main(String[] args) { Scanner s = new Scanner(System.in); //Input from two strings System.out.print("First String: "); String string1 = s.nextLine(); System.out.print("Second String: "); String string2 = s.nextLine(); // check for the length if(string1.length() == string2.length()) { // convert strings to char array char[] characterArray1 = string1.toCharArray(); char[] characterArray2 = string2.toCharArray(); // sort the arrays Arrays.sort(characterArray1); Arrays.sort(characterArray2); // check for e, if found equal then anagram, else not an anagram boolean isAnagram = Arrays.equals(characterArray1, characterArray2); System.out.println("Anagram: "+ isAnagram); } }第五、Java 面试小测(答案请写在评论里哦)
用于编译、调试和执行java程序的组件是什么?

2.字节码到机器码转换的任务是什么组件?

3.下面哪个是java解释器的功能?

4.当一个对象有自己的生命周期并且它的子对象不能属于另一个父对象时,它叫什么?

5.下面这段代码的输出是什么?
class InterviewBit { public void method1 (int num1,float num2){ System.out.println("int-float method"); } public void method1(float num1,int num2){ System.out.println("float-int method"); } public static void main(String[] args){ InterviewBit interviewBit=new InterviewBit(); interviewBit.method1(40,20); } }
6.以下代码的输出是什么?
class InterviewBit{ int fun (int n) { int result; result = fun (n - 1); return result; } } class Driver{ public static void main(String args[]) { InterviewBit ib = new InterviewBit() ; System.out.print(ib.fun(12)); } }
7.当垃圾收集进程在线程执行期间启动时,以下哪项会发生?

8.下面代码的输出是什么?
class InterviewBit{ public static void main(String args[]) { String obj = "Hello"; String obj1 = "InterviewBit"; String obj2 = "Hello"; System.out.println(obj.equals(obj1) + " " + obj.equals(obj2)); } }
9.Getinstance () 的功能是什么?

10.下面代码的输出是什么?
class InterviewBit{ public int num1; static int num2; void calculate(int a, int b) { num1 += a ; num2 += b; } } class Driver{ public static void main(String args[]) { InterviewBit obj1 = new InterviewBit(); InterviewBit obj2 = new InterviewBit(); obj1.num1 = 0; obj1.num2 = 0; obj1.calculate(1, 2); obj2.num1 = 0; obj2.calculate(2, 3); System.out.println(obj1.num1 + " " + obj2.num2); } }
11. 以下代码的输出是什么?
class InterviewBit{ int calculate(int a, int b) { try{ return a-b; }catch(Exception e){ return a+b; }finally{ return a*b; } } } class Driver{ public static void main(String args[]) { InterviewBit obj1 = new InterviewBit(); int result = obj1.calculate(2, 3); System.out.println("Result: " + result); } }
皓盘云建最新版下载v9.0 安卓版
53.38MB |商务办公
ris云客移动销售系统最新版下载v1.1.25 安卓手机版
42.71M |商务办公
粤语翻译帮app下载v1.1.1 安卓版
60.01MB |生活服务
人生笔记app官方版下载v1.19.4 安卓版
125.88MB |系统工具
萝卜笔记app下载v1.1.6 安卓版
46.29MB |生活服务
贯联商户端app下载v6.1.8 安卓版
12.54MB |商务办公
jotmo笔记app下载v2.30.0 安卓版
50.06MB |系统工具
鑫钜出行共享汽车app下载v1.5.2
44.7M |生活服务
2022-03-26
2022-03-26
2022-03-26
2022-03-26
2022-03-26
2022-03-26
2022-03-26
2022-03-26
2022-02-15
2022-02-14