大家好!我们继续为初级、中级和高级开发人员寻找250 多个问题的答案。这些问题很有趣,我自己也喜欢分析它们:在这种时候你可以发现理论知识的差距,以及最意想不到的地方。前一部分可以在这篇文章中找到。但在我们开始之前,我想提醒您:
- 我将跳过与本系列文章交叉的问题,以免再次重复信息。我建议阅读这些材料,因为它们包含最常见(流行)的 Java Core 面试问题。
- 关于 DOU 的问题以乌克兰语提出,但我将用俄语提供所有内容。
- 答案可以更详细地描述,但我不会,因为那样每个问题的答案可能需要整篇文章。他们不会在任何面试中询问你如此详细的问题。
11.命名Object类的所有方法
Object类有11个方法:- Class<?> getClass() — 获取当前对象的类;
- int hashCode() — 获取当前对象的哈希码;
- boolean equals(Object obj) - 当前对象与另一个对象的比较;
- 对象clone() ——创建并返回当前对象的副本;
- String toString() — 获取对象的字符串表示形式;
- void notify() - 唤醒一个在此对象的监视器上等待的线程(线程选择是随机的);
- void notifyAll() - 唤醒在此对象的监视器上等待的所有线程;
- void wait() - 在当前监视器上将当前线程切换到待机模式(冻结它),仅在同步块中工作,直到某些notify或notifyAll唤醒线程;
- void wait(long timeout) - 还冻结当前监视器上的当前线程(在当前同步的监视器上),但使用计时器退出此状态(或者再次:直到notify或notifyAll唤醒);
- void wait(long timeout, int nanos) - 一种与上述方法类似的方法,但具有更精确的退出冻结计时器;
- void Finalize() - 在删除此对象之前,垃圾收集器调用此方法(最后)。它用于清理占用的资源。
12.处理资源时try-with-resources和try-catch-finally有什么区别?
通常,当使用try-catch-finally 时, final 块用于关闭资源。Java 7 引入了一种新型运算符try-with-resources ,它与try-catch-finally类似,用于释放资源,但更加紧凑和可读。让我们记住try-catch-finally是什么样子的:String text = "some text......";
BufferedWriter bufferedWriter = null;
try {
bufferedWriter = new BufferedWriter(new FileWriter("someFileName"));
bufferedWriter.write(text);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
bufferedWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
现在让我们重写这段代码,但使用try-with-resources:
String text = "some text......";
try(BufferedWriter bufferedWriter =new BufferedWriter(new FileWriter("someFileName"))) {
bufferedWriter.write(text);
} catch (IOException e) {
e.printStackTrace();
}
它以某种方式变得更容易,你不觉得吗?除了简化之外,还有以下几点:
-
在try-with-resources中,括号中声明的资源(将被关闭)必须实现 AutoCloseable 接口及其唯一方法close()。
close方法在隐式的finally 块中执行,否则程序如何准确地理解如何关闭给定的资源?
但是,很可能您很少会编写自己的资源实现及其关闭方法。
-
块执行顺序:
- 尝试阻止。
- 终于隐了。
- 用于捕获前面步骤中的异常的catch块。
- 终于明确了。
通常,列表中显示较低的异常会中断显示在较高位置的异常。
13.什么是按位运算?
位运算是对位串的运算,包括逻辑运算和按位移位。 逻辑运算:-
按位与- 比较位值,在此过程中,任何设置为 0(假)的位都会将结果中的相应位设置为 0。也就是说,如果在比较的两个值中该位为 1(真),则结果也将是1。
表示为 - AND , &
示例:10111101 & 01100111 = 00100101
-
按位或是前一运算的逆运算。任何设置为 1 的位都会将结果中类似的位设置为 1。因此,如果两个比较值中该位均为 0,则结果位也将为 0。
表示为 - OR , |
示例:10100101 | 01100011 = 11100111
-
按位非- 应用于一个值,翻转(反转)位。即那些原来为1的位将变为0;那些原来为 0 的将变成 1。
表示为 - NOT , ~
示例:~10100101 = 01011010
按位 异或- 比较位值,如果两个值中该位都等于 1,则结果将为 0,如果两个值中该位都等于 0,则结果将为 0。即,要使结果等于 1,只有一位必须等于 1,第二位必须等于 0。 表示为 - XOR , ^
示例:10100101 ^ 01100011 = 11000110
- 01100011 >> 4 = 00000110
- 01100011 << 3 = 00011000
14. Java 中哪些标准的不可变类是对象?
不可变是不允许改变其原始参数的对象。它可能具有返回给定类型的新对象的方法,以及您想要更改的参数。一些标准的不可变对象:- 到目前为止,Java 中最著名的不可变对象是 String;
- 包装标准类型的包装类的实例:Boolean、Character、Byte、Short、Integer、Long、Double、Float;
- 通常用于特别大的数字的对象 - BigInteger 和 BigDecimal;
- 作为堆栈跟踪中的一个单元的对象(例如,在异常堆栈跟踪中) StackTraceElement;
- File 类的对象 - 可以更改文件,但同时它本身是不可变的;
- UUID - 通常用作元素的唯一 ID;
- java.time 包的所有类对象;
- 区域设置 - 用于定义地理、政治或文化区域。
15. 不可变对象相对于常规对象有哪些优点?
- 此类对象在多线程环境中使用时是安全的。通过使用它们,您不必担心由于线程竞争条件而丢失数据。与使用普通对象不同:在这种情况下,您必须非常仔细地思考并找出在并行环境中使用对象的机制。
- 不可变对象是映射中的好键,因为如果您使用可变对象,然后该对象更改其状态,那么在使用 HashMap 时可能会变得混乱:该对象仍然存在,而如果您使用containsKey(),它可能不会存在被发现。
- 不可变对象非常适合存储在程序运行时永远不应更改的不可变(常量)数据。
- “失败的原子性”——如果一个不可变的对象抛出异常,它仍然不会保持在不需要的(损坏的)状态。
- 这些类很容易测试。
- 不需要诸如复制构造函数和克隆实现之类的附加机制。
关于面向对象编程的问题
16. 与过程式编程相比,OOP 总体上有哪些优点?
那么,OOP的优点:- 复杂的应用程序比过程式编程更容易编写,因为所有内容都被分解为小模块(彼此交互的对象),因此,编程归结为对象之间的关系。
- 使用 OOP 编写的应用程序更容易修改(只要遵循设计概念)。
- 由于其上的数据和操作形成单个实体,因此它们不会在整个应用程序中被涂抹(这通常发生在过程编程中)。
- 信息封装可以保护用户最关键的数据。
- 可以对不同的数据重用相同的代码,因为类允许您创建许多对象,每个对象都有自己的属性值。
- 继承和多态性还允许您重用和扩展现有代码(而不是重复类似的功能)。
- 比过程方法更容易扩展应用程序。
- OOP 方法使得从实现细节中抽象出来成为可能。
17.告诉我们OOP有哪些缺点
不幸的是,他们也存在:- OOP 需要大量的理论知识,在你可以编写任何东西之前需要掌握这些知识。
- OOP 的思想并不那么容易理解并在实践中应用(你需要有一点内心的哲学家)。
- 当使用OOP时,由于系统的组织更加复杂,软件的性能会略有下降。
- OOP方法需要更多的内存,因为一切都由类、接口、方法组成,它们比普通变量占用更多的内存。
- 初始分析所需的时间比程序分析所需的时间长。
18.什么是静态多态和动态多态
多态性允许对象对于同一类或接口有不同的行为。多态性有两种类型,也称为早期结合和晚期结合。 静态多态性,或更早的绑定:- 发生在编译时(程序生命周期的早期);
- 决定在编译时执行哪个方法;
- 方法重载是静态多态性的一个例子;
- 早期绑定包括私有方法、静态方法和终端方法;
- 早期绑定不涉及继承;
- 静态多态不涉及具体的对象,而是涉及类的信息,类的类型表示在变量名的左侧。
- 发生在运行时(程序运行时);
- 动态多态性决定了一个方法在运行时会有什么样的具体实现;
- 方法重写是动态多态性的一个例子;
- 后期绑定是对特定对象、其类型或其超类的引用的赋值;
- 继承与动态多态性相关。
GO TO FULL VERSION