1. 为什么 Java 是一种平台无关语言?
Java 语言是以这样一种方式开发的,它不依赖于任何硬件或软件,因为编译器编译代码,然后将其转换为可以在多个系统上运行的独立于平台的字节码。
2. 为什么Java 不是纯粹的面向对象语言?
3. C/C++ 中使用指针。为什么Java不使用指针?
指针对于初学者来说非常复杂且不安全。Java 注重代码的简单性,指针的使用使其具有挑战性。指针的使用也可能导致潜在的错误。此外,如果使用指针,安全性也会受到影响,因为用户可以在指针的帮助下直接访问内存。
因此,通过在 Java 中不包含指针,提供了一定程度的抽象。此外,指针的使用会使垃圾收集过程变得非常缓慢和错误。与指针不同,Java 使用引用,因为它们不能被操纵。
4、你怎么理解实例变量和局部变量?
实例变量是类中所有方法都可以访问的变量。它们在方法外部和类内部声明。这些变量描述了一个对象的属性。
该类的每个实例都将拥有它独自的实例变量以供使用。如果对这些变量进行了任何修改,那么只有该实例会受到它的影响,而所有其他类实例将继续保持不受影响。
局部变量是存在于方法中并且只能在它们内部访问的那些变量。变量的使用仅限于当前方法范围。
5、数据封装是什么意思?
这是在 Object 类中定义的方法。 | 它是 Java 中的运算符。 |
此方法用于根据指定的业务逻辑检查两个对象之间的内容是否相等。 | 对于引用数据类型来说,该运算符用于比较引用的地址是否相同。 |
死循环是那些无限运行而没有任何中断条件的循环。
构造方法重载是在类中创建多个名字相同,参数不同的过程。根据参数的数量及其对应的类型,由编译器来区分不同类型的构造函数。
此处定义了三个构造函数,但它们因参数类型和编号而异。
在 Java 中,通过在由相同名称组成的同一类中引入不同的方法来实现方法重载。尽管如此,所有函数在参数的数量或类型上都不同。它发生在一个类中,并增强了程序的可读性。
方法返回类型的唯一区别不构成方法重载。
这两个函数具有相同的名称,但参数数量不同。第一种方法计算矩形的面积,而第二种方法计算长方体的面积。
方法重写是两个具有相同方法签名的方法存在于两个不同的类中的概念,其中存在继承关系。通过使用方法重写,子类可以实现特定的方法实现(已经存在于父类中)。
让我们看一下这个例子:
这两个类方法都具有名称 walk 和相同的参数、距离和时间。如果调用子类方法,则父类方法 walk 将被子类的方法重写。
是的,可以存在多个 catch 块,但特定的方法应该先于通用方法,因为只有满足 catch 条件的第一个 catch 块才会被执行。给定的代码说明了相同的内容:
在这里,由于除以 0 (i / x),将执行第二个 catch 块。如果 x 大于 0,则第一个 catch 块将执行,因为 for 循环运行直到 i = n 并且数组索引直到 n-1。
在 Java 中,final 关键字用于定义常量。
modifier final not allowed here
所有三个关键字在编程时都有自己的作用。
Final:如果需要对类、变量或方法进行任何限制,则 final 关键字会派上用场。final 类的继承和 final 方法的覆盖受 final 关键字的使用限制。合并 final 关键字后,变量值变为固定值。例子:
第二个语句会抛出错误。
最后:它是程序中存在的块,其中写入的所有代码都会执行,而不管异常处理如何。例子:
Finalize:在对象的垃圾回收之前,调用 finalize 方法以便实现清理活动。jdk9中已经被废弃,例子:
是的!一个类中可以有两个或多个具有相同名称但输入参数不同的静态方法。
16. 静态方法可以覆盖吗?
17.垃圾收集的主要目标是什么?
这个过程的主要目的是通过删除那些不可达的对象来释放Java程序执行过程中不必要的和不可达的对象所占用的内存空间。
18. 内存的哪一部分 - 堆栈或堆 - 在垃圾收集过程中被清理?
19. 除了安全方面,在 Java 中使字符串不可变的原因是什么?
String的源码中是由final修饰的数组,final修饰的变量不可变,从其他因素来看有这几个因素导致的:
21. 使用相关属性突出接口和抽象类之间的差异。
22. 在 Java 中,可以覆盖静态方法和私有方法。这种说法是否正确。
上下文中的陈述是完全错误的。静态方法与对象无关,这些方法属于类级别。在子类的情况下,具有与父类完全相同的方法签名的静态方法可以存在,甚至不会引发任何编译错误。
这里提到的现象通常称为方法隐藏,覆盖肯定是不可能的。私有方法覆盖是不可想象的,因为私有方法的可见性仅限于父类。因此,只能促进隐藏而不是覆盖。
24. 为什么字符数组比字符串更适合存储机密信息?
因此,如果黑客非法访问内存转储,黑客可能会因从事有害活动而窃取重要信息。可以通过使用可变对象或结构(如字符数组)来存储任何变量来消除此类风险。字符数组变量的工作完成后,可以将变量同时配置为空白。因此,它有助于节省堆内存,也不会给黑客提取重要数据的机会。
JDK 是用于开发 Java 应用程序的完整软件开发工具包。它包括 JRE、JavaDoc、编译器、调试器等。 | JRE 是一个软件包,提供 Java 类库、JVM 和运行 Java 应用程序所需的所有组件。 | JVM 是一个依赖于平台的抽象机器,由 3 个规范组成——描述 JVM 实现要求的文档、满足 JVM 要求的计算机程序和用于执行 Java 字节码并提供运行时环境的实例对象。 |
JDK 主要用于代码开发和执行。 | JRE 主要用于创建环境来执行代码。 | JVM 为 JRE 的所有实现提供了规范。 |
JDK 为代码开发提供了编译器、调试器等工具 | JRE 提供了 JVM 运行程序所需的库和类。 | JVM 不包含任何工具,而是提供了实现规范。 |
HashMap 不是同步的,因此更适合非线程应用程序。 | HashTable 是同步的,因此它适用于线程应用程序。 |
只允许一个空键,但值中允许任意数量的空值。 | 这不允许在键或值中使用 null。 |
reflection
用于描述代码对其自身或其系统的其他代码的检查能力,并在运行时对其进行修改。
使用 Runnable 接口的方法实现线程是更优选和有利的,因为 Java 不支持类的多重继承。start()
方法用于为线程执行创建单独的调用堆栈。一旦创建了调用堆栈,JVM 就会调用该run()
调用堆栈中执行线程的方法。
构造函数用于初始化对象状态。 | 方法用于暴露对象的行为。 |
构造函数没有返回类型。 | 方法应该有一个返回类型。即使它不返回任何内容,返回类型也是无效的。 |
必须在对象上显式调用方法。 | |
如果未定义构造函数,则由 java 编译器提供默认构造函数。 | 如果未定义方法,则编译器不提供它。 |
构造函数名称应等于类名称。 | 方法名可以是任意名称,也可以是类名。 |
最终变量实例化在构造函数中是可能的,并且 this 的范围适用于整个类及其对象。 | 如果在方法内初始化,则最终变量可确保变量不能仅在该方法的范围内更改。 |
Java 总是作为“传值”工作。Java 中没有所谓的“通过引用传递”。但是,当对象在任何方法中传递时,由于 Java 中对象处理的性质,传递的是值的地址。传递对象时,Java 创建引用的副本并将其传递给方法。对象指向相同的内存位置。方法内部可能会发生2种情况:
StringBuffer 本质上是可变的和动态的,而 String 是不可变的。String 的每次更新/修改都会创建一个新的 String,从而使字符串池中包含不必要的对象超载。因此,在大量更新的情况下,总是首选使用 StringBuffer,因为它会减少在字符串池中创建多个 String 对象的开销。
transient
关键字的同时声明属性,如下所示:
someInfo
可以序列化的所有字段。
不会有任何编译错误。但随后程序运行,由于JVM无法映射主方法签名,代码在运行时抛出“NoSuchMethodError”错误。
程序无法编译,因为编译器说该方法已在类中定义。
36.异常如何在代码中传播?
当异常发生时,它首先搜索以定位匹配的 catch 块。如果找到匹配的 catch 块,则将执行该块。否则,异常会通过方法调用堆栈传播并进入调用者方法,在那里执行匹配 catch 块的过程。这种传播一直发生,直到找到匹配的 catch 块。如果未找到匹配项,则程序将在 main 方法中终止。
不,在 try 块之后没有必要出现 catch 块。- try 块之后应该跟一个 catch 块或一个 finally 块。如果异常可能性更大,则应使用方法的 throws 子句声明它们。
无论异常与否,finally 块都将被执行。不执行 finally 块的唯一情况是当它在 try/catch 块中的任何地方遇到“System.exit()”方法时。
39. 你能在另一个构造函数中调用一个类的构造函数吗?
是的,这个概念可以称为构造函数链接,可以使用this()
.
40. 连续的内存位置通常用于在数组中而不是在 ArrayList 中存储实际值
在 ArrayList 的情况下,无法以原始数据类型(如 int、float 等)的形式存储数据。ArrayList 中存在的数据成员/对象具有对位于内存中不同位置的对象的引用。因此,实际对象或非原始数据类型(如整数、双精度等)的存储发生在不同的内存位置。
但是,这不适用于数组。对象或原始类型值可以存储在连续内存位置的数组中,因此每个元素不需要对下一个元素的任何引用。
41. 虽然继承是一个流行的 OOPs 概念,但它不如组合有利。解释。
在以下场景中,继承落后于组合:
在上面的例子中,遵循了继承。现在,对 Top 类进行了一些修改,如下所示:
如果按照Top类的新实现,Bottom类必然会出现编译时错误。Top.stop() 函数存在不兼容的返回类型。必须对 Top 或 Bottom 类进行更改以确保兼容性。但是,可以利用组合技术来解决给定的问题:
当字符串在赋值运算符的帮助下形成为文字时,它会进入字符串常量池,以便可以进行字符串实习。如果两个对象的内容相同,则堆中的同一个对象将被不同的字符串引用。
当两个变量引用相同的内容时,checking() 函数将返回 true。
相反,当在 new() 运算符的帮助下形成字符串时,不会发生实习。即使存在相同的内容对象,该对象也会在堆内存中创建。
由于两个变量未引用相同的内容,因此checking() 函数将返回false。
是的,尽管存在垃圾收集器,程序仍有可能耗尽内存。垃圾收集有助于识别和消除程序中不再需要的那些对象,以释放它们使用的资源。
在程序中,如果某个对象不可访问,则垃圾收集的执行将针对该对象进行。如果创建新对象所需的内存量不足,则在垃圾收集器的帮助下,为那些不再在范围内的对象释放内存。当释放的内存不足以创建新对象时,就会超出程序的内存限制。
此外,如果对象的创建方式使它们保留在作用域中并消耗内存,则会耗尽堆内存。开发人员应确保在完成工作后取消引用该对象。尽管垃圾收集器尽最大努力尽可能多地回收内存,但仍然可能超出内存限制。
让我们看一下下面的例子:
通过同步可以同时执行不同的进程。当多个线程共享特定资源时,可能会出现多个线程需要相同共享资源的情况。
同步有助于解决问题,资源一次由一个线程共享。让我们举个例子来更清楚地理解它。例如,您有一个 URL,您必须找出对其发出的请求数。两个同时请求可能会使计数不稳定。
如果一个线程Thread1查看计数为10,它将增加1到11。同时,如果另一个线程Thread2查看计数为10,它会增加1到11。因此,计数值不一致,因为预期的最终值是 12,但我们得到的实际最终值将是 11。
现在,函数increase() 是同步的,因此不能同时进行访问。
如果线程 Thread1 将计数视为 10,它将增加 1 到 11,然后线程 Thread2 将看到计数为 11,它将增加 1 到 12。因此,计数值发生了一致性。
...
一个称为 varargs(可变参数)的特性,它是作为 Java 5 的一部分引入的。
...
上面例子中的函数表明它可以接收数据类型字符串的多个参数。
Java线程生命周期如下:
下面的流程图清楚地解释了 Java 中线程的生命周期。
O(log n)
而无序数组的时间复杂度为O(n)
。
可以多次导入一个类或包,但是,这是多余的,因为 JVM 在内部只加载一次包或类。
这是一个很大的问题。我们需要明白,一个包的子包的导入需要显式的完成。导入父包只会导致导入其中的类,而不是其子/子包的内容。
不。程序 post 的控制System.exit(0)
立即消失,程序终止,这就是 finally 块永远不会执行的原因。
标记接口,也称为标记接口,是那些没有定义方法和常量的接口。它们用于帮助编译器和 JVM 获取有关对象的运行时相关信息。
这是在 Java 中初始化任何集合的便捷方式。考虑下面的例子。
在上面的例子中,我们看到 stringSets 是使用双括号初始化的。
通过此方法初始化时应小心,因为该方法涉及创建匿名内部类,这可能会在垃圾收集或序列化过程中引起问题,也可能导致内存泄漏。
现在,如果字符串包含增补字符,则长度函数会将其计为 2 个单位,并且 length() 函数的结果将与预期不同。
换句话说,如果有 2 个单位的 1 个增补字符,则该单个字符的长度被认为是两个 - 注意这里的不准确吗?根据java文档,这是预期的,但根据实际逻辑,它是不准确的。
如果在双引号(或字符串文字)中使用字母,则“位”将是打印的结果。但问题是使用了字符文字(单引号),这就是不会发生连接的原因。将添加每个字符的相应 ASCII 值,并打印该总和的结果。
第一种方法:一旦达到对象创建目的,将对象引用设置为 null。
第二种方法:将引用变量指向另一个对象。这样做,引用变量之前引用的对象将有资格进行 GC。
方法三:孤岛方法:当2个引用变量指向同一个类的实例,并且这些变量只相互引用,而这2个变量所指向的对象没有其他引用时,则称有形成了一个“隔离岛”,这两个对象有资格进行 GC。
56. 使用递归检查给定的字符串是否是回文。
主要思想是验证字符串的长度,如果发现相等,则将字符串转换为字符数组,然后对数组进行排序并检查两者是否相等。
想法是使用公式找到n个自然数的总和,然后找到给定数组中数字的总和。减去这两个总和得出的数字是实际缺失的数字。这导致 O(n) 时间复杂度和 O(1) 空间复杂度。
第五、Java 面试小测(答案请写在评论里哦)
用于编译、调试和执行java程序的组件是什么?
2.字节码到机器码转换的任务是什么组件?
3.下面哪个是java解释器的功能?
4.当一个对象有自己的生命周期并且它的子对象不能属于另一个父对象时,它叫什么?
5.下面这段代码的输出是什么?
6.以下代码的输出是什么?
7.当垃圾收集进程在线程执行期间启动时,以下哪项会发生?
8.下面代码的输出是什么?
10.下面代码的输出是什么?
11. 以下代码的输出是什么?