Java - 面试题总结

Java里面所有的不变的属性需要用final修饰吗

答:没必要。你可以实现相同的功能通过以下操作:
设为非final的private 变量,且只有在构造函数中才能修改。不设set方法,如果是一个可变对象,不要泄露任何指向这个对象的引用。

设置一个引用变量为final 只能确保这个变量不会被赋予一个不同的引用,但是你仍然可以改变引用变量的属性值。

String的subString()实现原理

答:substring取原来string的一部分创建一个新的对象。这个问题主要想问substring可能导致的内存泄露风险。

直到Java1.7, substring 拥有原来的字符数组的引用,这意味着即使是五字符这么小的字符串,也可能会导致一个1GB字符数组无法被垃圾回收,因为有一个强引用。

这个问题在Java1.7中已经被修复,原来的字符数组不会被引用,但是会导致创建substring耗时会有点长,以前时间复杂度是 O(1), Java 7之后时间复杂度是 O(n)。

Java中如何处理写存储过程或者读存储过程时遇到的错误

答: 一个存储过程应该在操作错误时返回错误码,但是如果存储过程本身出问题,捕获 SQLException 是唯一选择。

工厂模式和抽象工厂模式有什么区别

答:抽象工场模式提供一个多层级的抽象。考虑不同的工厂继承自同一个抽象工厂,代表基于工厂的不同对象结构的创建,例如, AutomobileFactory,UserFactory,RoleFactory等都继承自 AbstractFactory。每一个独立的工厂代表那种类型物体的创造器。

下面是一个工厂模式和抽象工厂模式的UML图:
工厂模式和抽象工厂模式UML

什么时候重写 hashCode()和 equals()方法

答:当需要通过业务逻辑校验两个对象是否相等,而不是通过两个对象是否执行同一地址。例如两个员工对象在 emp_id 相等的时候相等,即使它们是通过不同的代码创建出来的两个不同对象。

另外,如果你使用一个对象作为 HashMap的key,你必须重写这两个方法。

作为java equals-hashcode约束的一部分,当你重写equals的时候,必须重写hashcode. 否则你不能在Set,Map这样的类里面使用,因为他们通过equals()方法来保证逻辑正确性。

双引号直接创建字符串和使用new()创建字符串有什么区别

答: 使用new()创建String对象,实例被创建在堆中, 不会被添加到String常量池中,当通过字面量创建时,会被放到堆中的永久区的String常量池中。

Stringstr = newString(“Test”) 不会把str放到String常量池中,需要调用String.intern()方法,才会把它放到String常量池中。

当使用String字面量创建String对象时,如通过String s = “Test”, java会自动放入String常量池中。

另外,如果把”Test”这样的String字面量传进去,也会创建另外一个对象:”Test” 在String常量池。

什么是不可变对象,如何写一个不可变类

答:不可变对象是指Java类的对象一单被创建,不能被修改。任何不可变对象对象的修改在创建时候就已经完成,例如,Java中String是不可变的。

大多数不可变类是final的, 这样可以防止因子类重写方法而导致不可变失效。

你也可以实现相同的功能通过让成员非final但是private,且除了构造方法任何其他方法无法修改。

另外,要确保没有暴露不可变对象的内部,尤其是它包含可变成员的时候。

同时,当你从客户端接收到可变的对象时,例如 java.util.Date, 使用clone() 方法 来获取一个独立的拷贝,防止恶意修改可变对象带来的风险。

相同的优化需要在返回一个可变成员时执行。返回另一个独立拷贝给客户端;不要返回可变对象的原始引用。

本文标题:Java - 面试题总结

文章作者:王洪博

发布时间:2018年11月23日 - 22:11

最后更新:2019年09月12日 - 10:09

原始链接:http://whb1990.github.io/posts/382a766.html

▄︻┻═┳一如果你喜欢这篇文章,请点击下方"打赏"按钮请我喝杯 ☕
0%