加载中

面试

文章分类

浏览该分类下的所有文章

29 篇文章 3

每日一题(2022/1/20)

代码演示了 Java 中字符串比较的细节。`s1` 通过 `new String("xiaozou")` 在堆中创建了独立对象,`s2` 直接引用常量池中的字面量,两者地址不同,`s1 == s2` 为 `false`。调用 `s1.intern()` 时,若常量池已有相同内容的字符串,则返回该池中对象的引用,否则将其加入池中。因为常量池已经存在 `"xiaozou"`,`s3` 获得的正是 `s2` 的引用,故 `s2 == s3` 为 `true`。文章通过源码解释说明了 `intern()` 的工作原理及其在字符串共享中的作用。

每日一题(2022/1/19)

本文给出一个面试题:在保持 `String s` 引用不变的前提下,使其输出由 `"abc"` 变为 `"abcd"`。常规做法如 `StringBuilder.append` 或 `String.replace` 均无效,因为它们不会修改原对象。正确做法是利用反射访问并修改 `String` 的私有 final 字段 `value`:先通过 `getDeclaredField("value")` 设置可访问,再用 `set(s, "abcd".toCharArray())`。但在 JDK 11 及以上运行时会抛出 IllegalArgumentException,提示非法的反射访问并禁止对 final 字段赋值,这是因为 JVM 在编译期已将 `String` 常量化并强化了访问限制。

equals方法该如何重写?

文章说明何时需要重写Object的equals方法,何时可以不写,并详细阐述重写时必须遵守的五条原则(自反、对称、传递、一致、非空),以及常见违规例子。随后以AbstractSet的实现为模板,提供编写高质量equals的步骤:先检查引用相等、类型匹配、大小比较,再用containsAll逐域比较,并配合对应的hashCode实现,强调参数类型必须保持Object。

如何避免创建不必要的对象?

在 Java 开发中,应尽量避免创建功能相同的对象以节省内存和提升性能。使用字符串常量池代替 `new String`,在循环中复用同一 `String`;根据需求选用 `String`(不可变)、`StringBuilder`(可变、单线程)或 `StringBuffer`(线程安全)。对布尔值使用 `Boolean.valueOf` 而非 `new Boolean`,因为前者直接返回已缓存的实例。尽量避免自动装箱/拆箱导致的对象创建,优先使用基本类型 `int` 而非包装类 `Integer`。正则表达式应先 `Pattern.compile` 再复用匹配器,避免在循环中重复编译。上述技巧均可显著降低对象创建次数,提升程序运行效率。

如何正确的释放资源?

文章指出传统的 try‑catch‑finally 方式关闭 I/O 流代码冗长且易漏关闭,推荐使用 Java 7 的 try‑with‑resources,前提是资源实现 AutoCloseable。示例展示了改写前后对比,代码更简洁、可读性高,且自动释放资源,避免手动关闭时的顺序和异常处理问题。文中还提供了一个可变参数的 close 方法作为备选,但强调最优解仍是 try‑with‑resources。