JavaRush /Java 博客 /Random-ZH /Java 开发人员访谈问答分析。第2部分

Java 开发人员访谈问答分析。第2部分

已在 Random-ZH 群组中发布
大家好!我们继续为初级、中级和高级开发人员寻找250 多个问题的答案。这些问题很有趣,我自己也喜欢分析它们:在这种时候你可以发现理论知识的差距,以及最意想不到的地方。前一部分可以在这篇文章中面试问题及答案分析。 第 2 - 1 部分找到。但在我们开始之前,我想提醒您:
  1. 我将跳过与本系列文章交叉的问题,以免再次重复信息。我建议阅读这些材料,因为它们包含最常见(流行)的 Java Core 面试问题。
  2. 关于 DOU 的问题以乌克兰语提出,但我将用俄语提供所有内容。
  3. 答案可以更详细地描述,但我不会,因为那样每个问题的答案可能需要整篇文章。他们不会在任何面试中询问你如此详细的问题。
如果有必要,我会留下更深入研究的链接。让我们飞!

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() - 在删除此对象之前,垃圾收集器调用此方法(最后)。它用于清理占用的资源。
要正确使用hashCodeequals​ 、clonetoString和 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();
}
它以某种方式变得更容易,你不觉得吗?除了简化之外,还有以下几点:
  1. try-with-resources中,括号中声明的资源(将被关闭)必须实现 AutoCloseable 接口及其唯一方法close()

    close方法在隐式的finally 块中执行,否则程序如何准确地理解如何关闭给定的资源?

    但是,很可能您很少会编写自己的资源实现及其关闭方法。

  2. 块执行顺序:

    1. 尝试阻止。
    2. 终于隐了。
    3. 用于捕获前面步骤中的异常的catch块。
    4. 终于明确了。

    通常,列表中显示较低的异常会中断显示在较高位置的异常。

想象一下这样一种情况,当使用try-catch-finally时,您的try中发生了异常。因此,特定的catch块立即开始执行,您在其中编写另一个异常(例如,使用更详细地描述错误的消息),并且您希望该方法进一步抛出此异常。接下来是finally块的执行,其中也抛出了异常。但这是不同的。该方法最终会抛出这两个异常中的哪一个?最后块抛出异常!但try-with-resources也有一点。现在让我们看看相同情况下try-with-resources的行为。当我们尝试在close()方法中(即隐式的finally中)关闭资源时,我们会在try块中遇到异常。这些异常中的哪一个会被捕获被try块抛出的那个!来自隐式finally(来自close()方法)的异常将被忽略。这种忽略也称为异常抑制。

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

按位移位- >><<将值的位沿指定方向移位指定的数字。空出的位置用零填充。例如:
  1. 01100011 >> 4 = 00000110
  2. 01100011 << 3 = 00011000
右移负数时也有一个例外。正如您所记得的,第一位负责符号,如果该位等于 1,则该数字为负数。如果移动负数,则空出的位置将不再用零填充,而是用 1 填充,因为需要保留符号位。例如:10100010 >> 2 = 11101000 同时,在Java中还多了一个无符号右移运算符>>>这个运算符类似于>>,移位时,空出的位置都补0,无论是否数字是负数还是正数。例如: 10100010 >>> 2 = 00101000在此处阅读有关按位运算的更多信息。面试问题及答案分析。 第 2 - 2 部分作为在 Java 中使用按位移位的示例,您可以引用HashMap 的hash()方法,该方法用于确定键的特殊内部哈希码:面试问题及答案分析。 第 2 - 3 部分该方法允许您均匀分布 HashMap 中的数据,以最大限度地减少数据量。碰撞次数。

14. Java 中哪些标准的不可变类是对象?

不可变是不允许改变其原始参数的对象。它可能具有返回给定类型的新对象的方法,以及您想要更改的参数。一些标准的不可变对象:
  • 到目前为止,Java 中最著名的不可变对象是 String;
  • 包装标准类型的包装类的实例:Boolean、Character、Byte、Short、Integer、Long、Double、Float;
  • 通常用于特别大的数字的对象 - BigInteger 和 BigDecimal;
  • 作为堆栈跟踪中的一个单元的对象(例如,在异常堆栈跟踪中) StackTraceElement;
  • File 类的对象 - 可以更改文件,但同时它本身是不可变的;
  • UUID - 通常用作元素的唯一 ID;
  • java.time 包的所有类对象;
  • 区域设置 - 用于定义地理、政治或文化区域。

15. 不可变对象相对于常规对象有哪些优点?

  1. 此类对象在多线程环境中使用时是安全的。通过使用它们,您不必担心由于线程竞争条件而丢失数据。与使用普通对象不同:在这种情况下,您必须非常仔细地思考并找出在并行环境中使用对象的机制。
  2. 不可变对象是映射中的好键,因为如果您使用可变对象,然后该对象更改其状态,那么在使用 HashMap 时可能会变得混乱:该对象仍然存在,而如果您使用containsKey(),它可能不会存在被发现。
  3. 不可变对象非常适合存储在程序运行时永远不应更改的不可变(常量)数据。
  4. “失败的原子性”——如果一个不可变的对象抛出异常,它仍然不会保持在不需要的(损坏的)状态。
  5. 这些类很容易测试。
  6. 不需要诸如复制构造函数和克隆实现之类的附加机制。

关于面向对象编程的问题

面试问题及答案分析。 第 2 - 4 部分

16. 与过程式编程相比,OOP 总体上有哪些优点?

那么,OOP的优点:
  1. 复杂的应用程序比过程式编程更容易编写,因为所有内容都被分解为小模块(彼此交互的对象),因此,编程归结为对象之间的关系。
  2. 使用 OOP 编写的应用程序更容易修改(只要遵循设计概念)。
  3. 由于其上的数据和操作形成单个实体,因此它们不会在整个应用程序中被涂抹(这通常发生在过程编程中)。
  4. 信息封装可以保护用户最关键的数据。
  5. 可以对不同的数据重用相同的代码,因为类允许您创建许多对象,每个对象都有自己的属性值。
  6. 继承和多态性还允许您重用和扩展现有代码(而不是重复类似的功能)。
  7. 比过程方法更容易扩展应用程序。
  8. OOP 方法使得从实现细节中抽象出来成为可能。

17.告诉我们OOP有哪些缺点

不幸的是,他们也存在:
  1. OOP 需要大量的理论知识,在你可以编写任何东西之前需要掌握这些知识。面试问题及答案分析。 第 2 - 5 部分
  2. OOP 的思想并不那么容易理解并在实践中应用(你需要有一点内心的哲学家)。
  3. 当使用OOP时,由于系统的组织更加复杂,软件的性能会略有下降。
  4. OOP方法需要更多的内存,因为一切都由类、接口、方法组成,它们比普通变量占用更多的内存。
  5. 初始分析所需的时间比程序分析所需的时间长。

18.什么是静态多态和动态多态

多态性允许对象对于同一类或接口有不同的行为。多态性有两种类型,也称为早期结合和晚期结合静态多态性,或更早的绑定:
  • 发生在编译时(程序生命周期的早期);
  • 决定在编译时执行哪个方法;
  • 方法重载是静态多态性的一个例子;
  • 早期绑定包括私有方法、静态方法和终端方法;
  • 早期绑定不涉及继承;
  • 静态多态不涉及具体的对象,而是涉及类的信息,类的类型表示在变量名的左侧。
动态多态性,或后期结合:
  • 发生在运行时(程序运行时);
  • 动态多态性决定了一个方法在运行时会有什么样的具体实现;
  • 方法重写是动态多态性的一个例子;
  • 后期绑定是对特定对象、其类型或其超类的引用的赋值;
  • 继承与动态多态性相关。
您可以在本文中详细了解早期绑定和后期绑定之间的差异。

19.定义OOP中的抽象原则

OOP 中的抽象是一种突出对象的一组重要特征,排除不重要细节的方法。也就是说,当使用 OOP 方法设计程序时,您通常会关注模型,而不深入研究其实现的细节。在Java中,接口负责抽象。例如,您有一台机器,这将是界面。以及与之进行的各种交互 - 例如,启动发动机、使用变速箱 - 这些是我们使用的功能,无需深入了解实现细节。毕竟,当您驾驶汽车时,您不会考虑变速箱如何准确地实现其目的,或者钥匙如何启动发动机,或者方向盘如何准确地转动车轮。即使此功能之一的实现被替换(例如引擎),您也可能不会注意到。这对你来说并不重要:你不需要深入了解实现的细节。执行该行动对您来说很重要。实际上,这是对实现细节的抽象。今天我们就到此为止:未完待续!面试问题及答案分析。 第 2 - 6 部分
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION