问题一:在多线程环境中使用HashMap会有什么问题?在什么情况下使用get()方法会产生无限循环?
HashMap本身没有什么问题,有没有问题取决于你是如何使用它的。比如,你在一个线程里初始化了一个HashMap然后在多个其他线程里对其进行读取,这肯定没有任何问题。有个例子就是使用HashMap来存储系统配置项。当有多于一个线程对HashMap进行修改操作的时候才会真正产生问题,比如增加、删除、更新键值对的时候。因为put()操作可以造成重新分配存储大小(re-sizeing)的动作,因此有可能造成无限循环的发生,所以这时需要使用Hashtable或者ConcurrentHashMap,而后者更优。
问题二:不重写Bean的hashCode()方法是否会对性能带来影响?
这个问题非常好,每个人可能都会有自己的体会。按照我掌握的知识来说,如果一个计算hash的方法写得不好,直接的影响是,当向HashMap中添加元素的时候会更频繁地造成冲突,因此最终增加了耗时。但是自从Java8开始,这种影响不再像前几个版本那样显著了,因为当冲突的发生超出了一定的限度之后,链表类的实现将会被替换成二叉树(binarytree)实现,这时你仍可以得到O(logN)的开销,优于链表类的O(n)。
问题三:对于一个不可修改的类,它的每个对象是不是都必须声明成final的?
不尽然,因为你可以通过将成员声明成非final且private,并且不要在除了构造函数的其他地方来修改它。不要为它们提供setter方法,同时不会通过任何函数泄露出对此成员的引用。需要记住的是,把对象声明成final仅仅保证了它不会被重新赋上另外一个值,你仍然可以通过此引用来修改引用对象的属性。这一点是关键,面试官通常喜欢听到你强调这一点。
问题四:String的substring()方法内部是如何实现的?
又一个Java面试的好问题,你应该答出“substring方法通过原字符串创建了一个新的对象”,否则你的回答肯定是不能令人满意的。这个问题也经常被拿来测试应聘者对于substring()可能带来的内存泄漏风险是否有所了解。直到Java1.7版本之前,substring会保存一份原字符串的字符数组的引用,这意味着,如果你从1GB大小的字符串里截取了5个字符,而这5个字符也会阻止那1GB内存被回收,因为这个引用是强引用。
到了Java1.7,这个问题被解决了,原字符串的字符数组已经不再被引用,但是这个改变也使得substring()创建字符串的操作更加耗时,以前的开销是O(1),现在最坏情况是O(n)。
问题五:你在写存储过程或者在Java里调用存储过程的时候如何来处理错误情况?
这是个很棘手的Java面试题,答案也并不固定。我的答案是,写存储过程的时候一旦有操作失败,则一定要返回错误码。但是在调用存储过程的时候出错的话捕捉SQLException却是唯一能做的。
问题六:Executor.submit()和Executor.execute()这两个方法有什么区别?
此问题来自另外一篇文章,《15个最流行的java多线程面试问题》,现在对熟练掌握并发技能的开发者的需求越来越大,因此这个问题也越来越引起大家的重视。答案是:前者返回一个Future对象,可以通过这个对象来获得工作线程执行的结果。
当我们考察异常处理的时候,又会发现另外一个不同。当你使用execute提交的任务抛出异常时,此异常将会交由未捕捉异常处理过程来处理(uncaughtexceptionhandler),当你没有显式指定一个异常处理器的话,默认情况下仅仅会通过System.err打印出错误堆栈。当你用submit来提交一个任务的时候,这个任务一旦抛出异常(无论是否是运行时异常),那这个异常是任务返回对象的一部分。对这样一种情形,当你调用Future.get()方法的时候,这个方法会重新抛出这个异常,并且会使用ExecutionException进行包装。
问题七:工厂模式和抽象工厂模式有何不同?
抽象工厂模式提供了多一级的抽象。不同的工厂类都继承了同一个抽象工厂方法,但是却根据工厂的类别创建不同的对象。例如,AutomobileFactory,UserFactory,RoleFactory都继承了AbstractFactory,但是每个工厂类创建自己对应类型的对象。下面是工厂模式和抽象工厂模式对应的UML图。
问题八:什么是单例模式?创建单例对象的时候是将整个方法都标记为synchronized好还是仅仅把创建的的语句标记为synchronized好?
在Java中,单例类是指那些在整个Java程序中只存在一份实例的类,例如java.lang.Runtime就是一个单例类。在Java4版本及以前创建单例会有些麻烦,但是自从Java5引入了Enum类型之后,事情就变得简单了。可以去看看我的关于如何使用Enum来创建单例类的文章,同时再看看问题五来看看如何在创建单例类的时候进行双重检查。
问题九:能否写一段用Java4或5来遍历一个HashMap的代码?
事实上,用Java可以有四种方式来遍历任何一个Map,一种是使用keySet()方法获取所有的键,然后遍历这些键,再依次通过get()方法来获取对应的值。第二种方法可以使用entrySet()来获取键值对的集合,然后使用foreach语句来遍历这个集合,遍历的时候获得的每个键值对已经包含了键和值。这种算是一种更优的方式,因为每轮遍历的时候同时获得了key和value,无需再调用get()方法,get()方法在那种如果bucket位置有一个巨大的链表的时候的性能开销是O(n)。第三种方法是获取entrySet之后用iterator依次获取每个键值对。第四种方法是获得keyset之后用iterator依次获取每个key,然后再根据key来调用get方法。
问题十:你在什么时候会重写hashCode()和equals()方法?
当你需要根据业务逻辑来进行相等性判断、而不是根据对象相等性来判断的时候你就需要重写这两个函数了。例如,两个Employee对象相等的依据是它们拥有相同的emp_id,尽管它们有可能是两个不同的Object对象,并且分别在不同的地方被创建。同时,如果你准备把它们当作HashMap中的key来使用的话,你也必须重写这两个方法。现在,作为Java中equals-hashcode的一个约定,当你重写equals的时候必须也重写hashcode,否则你会打破诸如Set,Map等集合赖以正常工作的约定。你可以看看我的另外一篇博文来理解这两个方法之间的微妙区别与联系。
以上就是北大青鸟长沙麓谷校区Java培训机构小编介绍的“来自银行的10个Java面试题”的内容,希望对大家有帮助,如有疑问,请在线咨询,有专业老师随时为你服务。
相关推荐
最新最全java面试题及答案(初级到高级)
史上最全的中高级JAVA工程师面试题及答案汇总
Java高级开发工程师面试题
2019史上最全java面试题题库大全800题
哪有资深java工程师面试题