译:面试投行的20个Java问题 (3)

换句话说, 只需要在你创建对象的时候生效。一旦对象被创建,不需要任何同步。实际上,这种方法耗时很少。同步方法耗时是只同步临界区的10到20倍。

这是单例模式的UML图:

image

顺便提一句,有几种方法可以创建线程安全的单例,包括枚举,在这个问题里面我们也能提一下、

如果你想多学点,可以看这个免费课学习Java创建型设计模式

问题14:在HashMap的get()操作中,equals()方法和hashCode()方法什么时候起作用?()

这个问题是前面问题的更进一步,候选人需要知道一但你提hashCode,很有可能被问HashMap里面的应用。

一但你提供一个key对象,hashcode方法会被调用用来计算桶位置。一个桶包含一个链表,每一个Map.Entry对象使用equals()方法来看是否已经存在相同key的value。

强烈推荐你阅读我的博客Java中HashMap如何工作, 可以帮助你学习这个主题。

image

问题15: Java中如何避免死锁(答案)

: 死锁发生是因为两个线程试图获取被对方持有的资源。但是要想发生这种情况,必须满足以下四个条件:

相互排斥——至少一个进程必须处于非共享模式

保持并等待——必须有一个进程持有一个资源并等待另一个资源

没有抢占—— 资源不能被抢占

循环等待 —— 存在进程集合

通过中断循环等待可以避免死锁。可以通过在代码中指定获取和释放锁的顺序来达到这一目的。

如果多个锁通过一致的顺序被获取和释放,不会有互相等待对方释放锁的情况。

你可以看我的博客如何避免死锁, 查看示例代码和更加详细的解释。 同时推荐在通用Java模式上使用并发和多线程 这个课程来更好的理解多线程模式。

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

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

String str = new String("Test") 不会把str放到String池中,我们需要调用String.intern()方法,会把它放到String池中。

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

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

这是我的知识盲区直到读者在我的博客 中给我提建议,如果想学习更多关于String字面量和String对象的知识,看这里

image

问题17:什么是不可变对象?你可以写一个不可变类吗?(答案)

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

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

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

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

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

相同的优化需要在返回一个可变成员时执行。返回另一个独立拷贝给客户端;不要返回可变对象的原始引用。你也可以看我的这篇博客Java中如何创建一个不可变对象, 这里有按步骤的引导和示例代码。

问题18:不用性能分析工具,给出一个简单的办法找到一个方法运行耗时

:请求前和请求后记录时间,计算时间差值。如果一个方法耗时太小可能显示0毫秒,那么可以让方法变的足够大,比如重复执行足够多次。算总时间。

问题19:当你使用Object作为HashMap里面的key的时候,哪两个方法需要实现?

为了在hashMap或者hashtable中把对象作为key,它必须实现equals和方法。

你也可以阅读Java在HashMap中是如何工作的,了解相关实现细节。

问题20:如何防止客户端直接实例化你的具体类?例如你有一个Cache接口和两个实现类:MemoryCache和DiskCache。如何确保没有任何这两个类的对象通过new()关键字被创建出来?

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wsxxzg.html