很多Java开发人员会到巴克莱、瑞士信贷、花旗等投资银行申请Java开发职位,但他们中很多人都不知道面试时会遇到什么类型的问题。


在这篇文章中,我将分享一些3年以上经验Java开发人员频繁被银行问到的问题。是的,这些问题不是为新人或者1-2经验的开发人员准备的-通常,银行不通过公开面试雇用他们。相反,他们大多以毕业培训生的身份加入银行。


我不能保证你会被问到这些问题,但它们足以让你了解真正的面试中会出现哪种类型的问题。


还有,准备得越多,你就准备得越好。所以,如果你觉得这10个问题不够,还需要更多,可以查看这40个电话面试java问题200多个问题列表,以做更好的准备。


40个电话面试java问题

http://www.java67.com/2015/03/top-40-core-java-interview-questions-answers-telephonic-round.html

200多个问题列表

https://www.udemy.com/java-interview-questions-and-answers/?siteID=JVFxdTr9V80-s7n3raAgjp7ZDS_xHSd4lg&LSNPUBID=JVFxdTr9V80


一旦你见识过这些问题,参加任何Java面试你都会自信很多。


废话少说,下面是我列举的一些投资银行最常问到的Java问题:


问题1: 在多线程环境中使用HashMap有什么问题?调用get()方法什么时候会进入无限循环?


首先,这并没什么错 — 它取决于你怎样使用它。例如,如果你仅仅使用一个线程初始化 HashMap 而所有的线程只是读取它,这可以很好的工作。


还有一个例子是包含配置属性的 Map。当多个线程更新这个 HashMap,如添加、修改或删除任何一个键值对时,真正的问题来了。


因为 put() 会造成 HashMap 扩容操作,又会进一步导致无限循环,这就是为什么你应该使用 Hashtable 或 ConcurrentHashMap(后面一个更好)。


问题2. 不覆盖 hashCode()方法会有性能问题吗?


这是一个很好的问题,大家都应该有所了解。据我所知,一个效率低的 hashCode 方法会导致 HashMap内部频繁的冲突,最终添加对象到这个 HashMap 要花费更多时间。


从 Java8 开始, Hash冲突已经不会像先前版本那么影响性能了, 因为超过临界值后,链表会被二叉树替换,在最坏情况下也可以达到 O(log N) 复杂度。相比之下,链表的复杂度是O(N)。


这是你将面对的几个棘手的Java问题之一。很多开发者都只知道要重写 equals 和 hashcode 方法。而没有考虑它们对性能影响。


问题3:不变对象的所有属性都需要声明为final吗?


不需要。如上所述,你可以通过声明成员变量为 private 而不是 final 实现相同的功能, — 除了构造方法,没有其他途径修改它们。


不要为它们提供 setter 方法,如果它是一个可变的对象,不要泄漏这个成员的任何引用。


记住,声明一个引用属性为 final 只能保证它不会再指向另一个值,但你仍然可以改变这个引用指向对象的各个属性。


这是面试官希望从应聘者那里听到的一个关键点。提到这点,你可以得到一些赞赏分。


问题4:String中的substring ()方法是怎样工作的?


很多开发者都知道这个答案:”子字符串通过获取原始字符串的一部分,从原 string 对象中创建一个新对象“。


但我觉得这个答案是不完善的。


这个问题主要是为了考察开发者是否熟悉子字符串造成的内存泄漏风险。


直到Java 1.7, 子字符串保持着原始字符数组引用,这意味着即使5个字符长的子字符串也能阻止1GB的字符数组被垃圾回收器回收,因为子字符串保持着它的一个强引用。


这个问题在 Java1.7 被修复, 原始字符数组不再被引用,但这个改变也造成创建子字符串要花费多一点时间。之前,它在 O(1) 复杂度内完成,在 Java7 中最坏情况下,它会达到 O(N) 复杂度。


问题5:你能写出单例的关键代码片段吗?


这个关键的 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;

    }

}


问题6:当你用 Java 编写存储写入程序或存储读取程序时,你怎么处理错误?


这也是一个棘手的Java问题,它同样面向所有人。我有一个朋友不知道答案,但他不介意告诉我。


我的看法是,如果一些写入存储操作失败,就应该返回一个错误code,但如果是这个程序本身失败,那唯一的选择就是捕获SQL异常了。


问题7:Executor.submit()方法和Executer.execute()有什么不同?


这个Java面试问题来自我的50个多线程问题列表,它是银行用于针对有经验的程序员的。


http://www.importnew.com/javarevisited.blogspot.sg/2014/07/top-50-java-multithreading-interview-questions-answers.html#axzz4jaJmaqbE


因为现在对拥有良好并发技能的 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 中,再重新抛出。


问题8: 工厂模式和抽象工厂模式有什么不同?


相比工厂模式,抽象工厂提供了更多一层的抽象。


不同的工厂可以继承自同一个抽象工厂,并基于工厂的类型创建不同类别的对象。


例如,AbstractFactory 可以被 AutomobileFactory、UserFactory、RoleFactory等工厂继承。


每个特定的工厂负责创建某一种类型的对象。


这是工厂模式和抽象工厂模式的UML图:


图片


问题9: 什么是单例?整个方法同步和代码临界片段同步哪个更好?


Java 中单例是指在整个 Java 应用中 class 只有一个实例。例如 java.lang.Runtime 就是一个单例。


在 Java5 中,创建单例很麻烦,但 Java5 引入了枚举后,就容易很多了。


请看看我的文章《怎样在Java中创建线程安全的单例》,可以获得使用枚举和双重检查锁模式编写单例的更多细节,这些正是这个java面试问题的考察目的。


怎样在Java中创建线程安全的单例

http://www.importnew.com/javarevisited.blogspot.sg/2012/07/why-enum-singleton-are-better-in-java.html#axzz4tzMEHSJw


问题10:在Java4和Java5中,你能不能写下迭代遍历HashMaps的代码?


这是也是一个棘手的问题,正如回答者所说,他努力使用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 应用程序的性能。


更多相关文章

  1. Java多线程打辅助的三个小伙子
  2. 深入学习 Java 线程池
  3. Java 多线程:volatile 变量、happens-before 关系及内存一致性
  4. 到底多少线程算是线程数太多?
  5. 工厂模式理解了没有?
  6. 多线程之死锁就是这么简单
  7. 线程池你真不来了解一下吗?
  8. LockSupport:一个很灵活的线程工具类
  9. 源码实战 | 从线程池理论聊聊为什么要看源码

随机推荐

  1. Google code android开源项目(一)
  2. android源码链接
  3. Android 使用AsyncHttpClient文件上传与
  4. 第一行代码Android第三课
  5. Android 开源源代码收集(不断更新中...)
  6. Android ADT & SDK离线下载地址
  7. Android中创建和检测快捷方式
  8. 获取android手机基本信息
  9. android 默认系统音量定义
  10. Android中回调下载事件处理实现步骤