很多Java开发人员会到巴克莱、瑞士信贷、花旗等投资银行申请Java开发职位,但他们中很多人都不知道面试时会遇到什么类型的问题。
在这篇文章中,我将分享一些3年以上经验Java开发人员频繁被银行问到的问题。是的,这些问题不是为 新人 或者1-2经验的开发人员准备的-通常,银行不通过公开面试雇用他们。相反,他们大多以毕业培训生的身份加入银行。
我不能保证你会被问到这些问题,但它们足以让你了解真正的面试中会出现哪种类型的问题。
还有,准备得越多,你就准备得越好。所以,如果你觉得这10个问题不够,还需要更多,可以查看这 40个电话面试java问题 和 200多个问题列表 ,以做更好的准备。
一旦你见识过这些问题,参加任何Java面试你都会自信很多。
废话少说,下面是我列举的一些投资银行最常问到的Java问题:
首先,这并没什么错 — 它取决于你怎样使用它。例如,如果你仅仅使用一个线程初始化 HashMap 而所有的线程只是读取它,这可以很好的工作。
还有一个例子是包含配置属性的 Map。当多个线程更新这个 HashMap,如添加、修改或删除任何一个键值对时,真正的问题来了。
因为 put() 会造成 HashMap 扩容操作,又会进一步导致无限循环,这就是为什么你应该使用 Hashtable 或 ConcurrentHashMap (后面一个更好)。
这是一个很好的问题,大家都应该有所了解。据我所知,一个效率低的 hashCode 方法会导致 HashMap内部频繁的冲突 ,最终添加对象到这个 HashMap 要花费更多时间。
从 Java8 开始, Hash冲突已经不会像先前版本那么影响性能了, 因为超过临界值后,链表会被二叉树替换,在最坏情况下也可以达到 O(log N) 复杂度。相比之下,链表的复杂度是O(N)。
这是你将面对的几个 棘手的Java问题 之一。很多开发者都只知道要重写 equals 和 hashcode 方法。而没有考虑它们对性能影响。
不需要。如上所述,你可以通过声明成员变量为 private而不是 final 实现相同的功能, — 除了构造方法,没有其他途径修改它们。
不要为它们提供setter 方法,如果它是一个可变的对象,不要泄漏这个成员的任何引用。
记住,声明一个引用属性为final只能保证它不会再指向另一个值,但你仍然可以改变这个引用指向对象的各个属性。
这是面试官希望从应聘者那里听到的一个关键点。提到这点,你可以得到一些赞赏分。
很多开发者都知道这个答案:” 子字符串通过获取原始字符串的一部分,从原 string 对象中创建一个新对象“ 。
但我觉得这个答案是不完善的。
这个问题主要是为了考察开发者是否熟悉子字符串造成的内存泄漏风险。
直到Java 1.7, 子字符串保持着原始字符数组引用,这意味着即使5个字符长的子字符串也能阻止1GB的字符数组被垃圾回收器回收,因为子字符串保持着它的一个强引用。
这个问题在 Java1.7 被修复, 原始字符数组不再被引用,但这个改变也造成创建子字符串要花费多一点时间。之前,它在 O(1) 复杂度内完成,在 Java7 中最坏情况下,它会达到 O(N) 复杂度。
这个关键的 Java 问题是前一个问题的后续。希望应聘者使用 双重检查锁模式 写出java单例。
记住使用 volatile 变量确保单例线程安全。
以下是使用双重检查锁模式实现线程安全单例的核心代码:
public class Singleton { private static volatile Singleton _instance; /** * Double checked locking code on Singleton * @return Singelton instance */ public static Singleton getInstance() { if (_instance == null) { synchronized(Singleton.class) { if (_instance == null) { _instance = new Singleton(); } } } return _instance; } }
这也是一个棘手的Java问题,它同样面向所有人。我有一个朋友不知道答案, 但他不介意告诉我 。
我的看法是,如果一些写入存储操作失败,就应该返回一个错误code,但如果是这个程序本身失败,那唯一的选择就是捕获SQL异常了。
这个Java面试问题来自我的50个多线程问题列表,它是银行用于针对有经验的程序员的。
因为现在对拥有良好并发技能的 Java 开发人员有巨大需求,这问题也正日益流行。另外,如果你正认真地打造你的并发技能,Heinz Kabutz的 《Java Concurrency in Practice》 是一个很好的开始。这是最高级的java并发课程,它基于经典java书籍,Brian Goetz和其公司的《 Java Concurrency in Practice 》。
总之,这个 Java 面试问题的答案是前者返回一个Future对象,可以通过这个对象从工作线程中获取结果。
观察异常处理,你会发现另外一个不同之处。如果你的任务抛出一个异常( 异常由execute的任务触发 ),这个异常将会交由未捕捉异常处理器来处理(当你没有提供一个确切的处理器,默认处理器只会打印异常栈轨迹到 System.err)。
如果你submit的任务触发了异常,不管是不是 受检异常 ,它们都是这个任务返回状态的一部分。因为这个任务是被 submit 的,并以异常终结,Future.get() 会将这个异常封装在 ExecutionException 中,再重新抛出。
相比工厂模式,抽象工厂提供了更多一层的抽象。
不同的工厂可以继承自同一个抽象工厂,并基于工厂的类型创建不同类别的对象。
例如,AbstractFactory 可以被 AutomobileFactory、UserFactory、RoleFactory等工厂继承。
每个特定的工厂负责创建某一种类型的对象。
这是 工厂模式 和抽象工厂模式的UML图:
Java 中单例是指在整个 Java 应用中 class 只有一个实例。例如 java.lang.Runtime 就是一个单例。
在 Java5 中,创建单例很麻烦,但 Java5 引入了枚举后,就容易很多了。
请看看我的文章 《怎样在Java中创建线程安全的单例》 ,可以获得使用枚举和双重检查锁模式编写单例的更多细节,这些正是这个java面试问题的考察目的。
这是也是一个棘手的问题,正如回答者所说,他努力使用while和for循环完成。实际上,在Java中有 4种方法遍历Map 。
一个方法是使用 keySet() 来遍历所有的 key,然后使用 get() 方法来检索值,但这样成本有点昂贵。
第二种方法是使用 entrySet(),通过 for 循环或者结合 Iterator.hasNext() 方法使用 while 循环遍历它们。
这是一个更好的方法,因为在你遍历时,键和值都是可得的,你不需要调用get()方法来检索值。如果 HashMap 的 bucket 中有一个巨大的链表,它会造成 O(N) 时间复杂度。
如果你使用 Java8,情况会好点,Java8 会使用树来替换链表。
这就是投资银行常见的Java面试问题。如果你准备成为一名 Java 开发人员,那您应该多关注Java并发、多线程、集合、JVM内部结构,垃圾回收以及如何提高 Java 应用程序的性能。
在这篇文章中,我没有涉及到准备Java面试时需要的所有专题,但如果你正在认真准备,这里有些有用的资源,可以找到更多结构化和专题问题:
1. 200+ Java面试问题 – 指南
2. 针对2到5年经验开发人员的130+java核心问题
3. 破解编码面试-189个问题和解决方案
4. Java面试攻略希望可以帮到你的下一个工作面试。如果你理解问题有任何困难或者你正寻找最近面试遇到问题的答案,请随时与我们分享。
我会尽力回答好那些问题。
原文链接: dzone 翻译:ImportNew.com -大瓜细瓜
译文链接:[]