最最常用的(没有之一)Java面试专题系列(一)

PS:亦可移步BAT直通车获取更为详解的介绍

这里总结了老司机们最最常用的Java面试题,有些题虽然简单,但依然很多人依旧还在犯错,甚至一些有经验的工程师依然会在下面的问题中犯错,导致线上问题,所以无论是学生还是老司机都可以好好看一下。

这里分四部分展开:

第一部分主要集中在8个基本核心问题上,更关注于Java的基本功;

第二部分主要集中在8个框架和设计上的问题,关注于面试者的架构和常用框架的掌握能力;

第三部分主要关注于8个Java核心的相关技术,更关注与考察面试者对Java的内存、垃圾回收、并发等更为深入的问题的考察;

第四部分主要关注于常用的算法,这里包括较为深入的算法知识(机器学习算法),以及Java工程师需要掌握的常用算法。

这里老司机会带你一步一深入了解。

这里写图片描述


先看看8个考察基本功的问题

1.HashMap的内部实现机制,hash是怎样实现的,什么时候rehash?

这个问题其实一方面是想要考察,面试者是否掌握了HashMap的实现机制,另一方面其实是想考察面试者是否掌握HashMap的更为核心的东西——线程不安全。

HashMap是Java集合框架(Java Collection Framework)中一个基础类,自从加入到Java版本中。在此之后,Map接口本身除了在Java5中引入了泛型以外,再没有发生过明显变化。然而HashMap的实现,则为了提升性能,不断地在改变。很多人都看过JDK1.7以前的实现版本,但JDK1.8开始对HashMap的实现做了很大的调整,这里直接从1.8开始说。

很多HashMap的问题除了同步问题,还有就是Hash碰撞问题。实现HashMap时一个重要的考量,就是如何尽可能地规避哈希碰撞。而HashMap的改进,也大多与此相关。

更详细的介绍可以参考这篇博客http://blog.csdn.net/c139352227/article/details/47861815

有一个并不常见的Hash的坑,需要注意,就是在服务器端产生的HASH碰撞,进而引发DOS(Denial of Service 拒绝服务)攻击。

一旦使用了hashmap这种数据结构那么必须考虑到hash碰撞。如果提交post不做限制,邪恶的人就会构造一个超级大的post数据体,并且这个数据里面的所有数据的key的hascode一致。

由于Tomcat等Web服务器在处理用户提交的参数时,直接把参数“键值对”放入了HashMap中。如果数据量足够大, 那么就可以使得服务器端在计算, 查找, 插入的时候, 造成大量的CPU占用, 从而导致所谓的DOS攻击。

在Tomcat在6.0.35之后的版本中都加入了补丁,这个补丁其实就是限制post数据的大小:

在tomcat的server.xml中设置maxParameterCount和maxPostSize两个参数就可以限制post数据的大小

<Connector maxParameterCount="1000"     maxPostSize="2097152" />

2.Hashtable和HashMap的区别

HashTable在Java出现之初,就已经被引入,而HashMap直到Java 2,才随着JCF出现到人们的视野之中。HashTable和HashMap一样,也实现了Map接口,因此他们从函数的视角上是等价的。

    public class Hashtable<K,V> extends Dictionary<K,V> implements Map<K,V>, Cloneable, java.io.Serializable

    public class HashMap<K,V> extends       AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable

然而,在它们之间,有许多处不同。首先,HashTable是一个线程安全的API,它的方法通过synchronized关键字进行修饰。尽管并不推荐使用HashTable来开发一个高性能的应用,但是它确实能够保证你的应用线程安全。相反,HashMap并不保证线程安全。因此当你构建一个多线程应用时,请使用ConcurrentHashMap。而在单线程应用中,HashMap有这个比HashTable更好的性能,这得益于HashMap使用了多种方式来规避哈希碰撞,其中,使用辅助Hash函数是一种著名的方式。

HashTable和HashMap都是基础的关联数组,哈希指的是一种通过Key来获取数据的过程(映射)。


3.ConcurrentHashMap的特点和实现机制

这个问题面试官其实想考察的是面试者对于ConcurrentHashMap的实现原理的理解,当然在JDK1.7以前和1.8以后有着巨大的变化,这里笔者简要介绍一下1.8的实现机制。

ConcurrentHashMap是conccurrent家族中的一个类,由于它可以高效地支持并发操作,以及被广泛使用,经典的开源框架Spring的底层数据结构就是使用ConcurrentHashMap实现的。与同是线程安全的HashTable相比,它已经更胜一筹,因此它的锁更加细化,而不是像HashTable一样为几乎每个方法都添加了synchronized锁,这样的锁无疑会影响到性能。

最新的ConcurrentHashMap实现线程安全的思想已经完全变了,它摒弃了锁段(Segment)的概念,而是启用了一种全新的方式实现,利用CAS算法(可以看看CAS相关以及Java中协程的概念)。它沿用了与它同时期的HashMap版本的思想,底层依然由“数组”+链表+红黑树的方式思想,但是为了做到并发,又增加了很多辅助的类,例如TreeBin,Traverser等对象内部类。

ConcurrentHashMap内部有Node这一最核心的内部类,它包装了key-value键值对,所有插入ConcurrentHashMap的数据都包装在这里面。与HashMap中的定义很相似,但它对value和next属性设置了volatile限制,不允许调用setValue方法直接改变Node的value域,增加了find方法辅助map.get()方法。

关于ConcurrentHashMap的更详细的介绍,可以参考这个博客,已经写得很详细了。

http://blog.csdn.net/u010723709/article/details/48007881

关于旧的1.7版本以前的实现,可以参考这篇博文,写得很好。

https://www.ibm.com/developerworks/cn/java/java-lo-concurrenthashmap/

4.ArrayList和LinkedList分别在什么情况下使用,有那些注意的地方?

这个题目的本意是想考察面试者对常用集合类的掌握情况,面试者除了要阐述这两个常用集合类的数据结构、区别、常见的问题解决方案,最好再抛出自己的一些使用经验,以及在此基础上进行常用集合类的扩展。下面先让老司机给你抛砖引玉,更详细的 可以自己看看源码或其他介绍的比较经典的。

首先说数据结构,LinkedList使用双向链表实现,ArrayList则是实现了一个动态数组。面试官其实就想考察面试者对这两种基本数据结构的认识,那么面试者就要准确的传达对这两种数据结构的认识,链表方便插入删除操作,所以LinkedList的插入与删除操作更为快捷,数组便于查询与遍历,所以ArrayList则对于查询与修改操作有更高的性能。所以这里要记住,List使用首选ArrayList,对于个别插入删除非常多的可以使用LinkedList。

其次在使用的时候,对于ArrayList的使用,最好给其指定容量大小。默认ArrayList的初始化空间大小是10,每次不够的时候就去new一个原来1.5+1倍的新空间,然后把原来的数据拷贝到新的空间,那么这就是导致ArrayList增加新元素性能略低的很大一个原因了。所以,以后在new ArrayList的时候,如果能够估算实际数据的多少,然后大概的制定一下ArrayList的空间大小(new ArrayList(1000)),这样就可以避免很多次的数据拷贝,从而提高系统性能!

最后,要记住这种考察基本功的地方你要尽量扩展来说,不要问什么只答什么,要尽量牵着面试官。关于集合类的详细信息可以自行搜索。


5.String、StringBuilder、StringBuffer的区别

这几乎是一个Java工程师都要被面到的问题,很多人都会去看String的源码,但面试时还是感觉到很多面试者掌握的不够全面。其实主要抓住两点就可以彰显你的基本功,一个是可变与否问题、一个是线程安全与否的问题。

StringBuffer、StringBuilder、String都是用来代表字符串。但String类是不可变类,任何对String的改变都 会引发新的String对象的生成;StringBuffer则是可变类,任何对它所指代的字符串的改变都不会产生新的对象.既然可变和不可变都有了,为何还有一个StringBuilder呢?当然是因为线程安全问题了。他们的原理和操作基本相同,区别在于StringBuffer是支持并发操作,线性安全的,适合多线程中使用。StringBuilder不支持并发操作,线性不安全的,不适合多线程中使用。新引入的StringBuilder类不是线程安全的,但其在单线程中的性能比StringBuffer高。

看一下下面代码来深入了解一下String:

String str1 = "";
String str2 = "";
String str3 = null;

String s = str1 + str2+ str3;
System.out.println(s);//null
System.out.println(s.length());//4

用+连接字符串,实际是通过 StringBuilder(或 StringBuffer)类及其 append 方法实现的,然后再通过toString()转换成字符串。那么上面的字符串拼接语句将被反编译为:

String s = (new StringBuilder()).append(str1).append(str2).append(str3).toString();

源码是这样说的

The characters of the String argument are appended, in order, increasing the length of this sequence by the length of the argument. If str is null, then the four characters "null" are appended.

最关键的是说:如果字符串为null,则追加4个字符”null”。所以Sring类型的变量最好不要初始化为null


6.简单说一下多态和重载的区别

这里不想过多说了,因为涉及到面向对象的概念知识实在是可以写太多,在这里,这个是想考察面试者对面向对象的概念的掌握。面试者要掌握面向对象的最基本的特征:抽象、继承、封装、多态,面试者要牢牢掌握这些的定义和区别。这里不多做赘述,直接google。


7.equals和hashcode这些方法使用场景,有那需要注意的地方?

这是个老生常谈的问题,即使这样还是有很多人经常会犯错,面试者可以搜搜这两个方法引发的血案。

需要记住:
A.如果2个对象调用equals(Object)方法相等,那么这个2个对象调用hashCode()返回的hash值也必须相等。
B.如果2个对象调用equals(Object)方法不相等,那么这个2个对象调用hashCode()返回的hash值没有必要一定不相

很多人在这里经常重写equals方法,但却忘了hashcode方法,一般情况下不太会出问题,但是遇到像HashMap这样的集合类就会出问题。如果用户定义了两个实例

TestObj a = TestObj(1)
TestObj b = TestObj(1)
a.equals(b)//true

Map<TestObj,String> map= new HashMap<TestObj,String>()
map.put(a,"1111")
System.out.println(map.containsKey(b))//false

Why?如果不注意不会注意这个问题,这种现象是因为HashMap会先判断容器中是否存在与TestObj相同hashCode的对象,如果找不到直接就返回false,如果找到了再调用equals(Object)方法判断2个对象是否相等。


8.讲解一下Java线程同步的几种方法

这里面试官其实是想考察面试者对线程同步的方法的掌握程度,面试者需要掌握常用的几种线程同步的方法。这里笔者暂时列出如下五种:

1.同步方法(synchronized)

2.同步代码块(synchronized)

3.使用特殊域变量(Volatile)实现线程同步

4.使用重入锁实现线程同步

5.使用ThreadLocal实现线程同步

面试者需要深入的了解和掌握这几种常用的方法,每个方法都要深入了解。对于volatile关键字可能实际用的比较少,但一些高质量的代码(一些中间件、开源框架中常见),所以面试者不妨深入了解一下。
像ThreadLocal这种,对于在校的同学其实使用就更低频了,但实际工作中却很有效,甚至有些刚入职的工程师也不能很好的掌握,需要有一定的积累才会更灵活的使用,所以面试者需要深入的了解一下。

当然更深入的学习可以移步并发编程网去系统、深入的学习一下


注意:这部分好几个问题都涉及到了hashmap,需要注意,HashMap是有大小上限的,如果使用的时候不加保护,存在写爆的可能,其上限是1<<30

好吧今天写到这里,后面继续写,欢迎大家持续关注”BAT直通车

更多关于笔试、面试中的题目和知识的详解,可以移步BAT直通车,获取老司机的宝贵经验和总结。

PS:BAT直通车总结BAT和国内众多IT、互联网公司近年的笔试、面试题目,由BAT的老司机进行重点解析和知识点总结,同时老司机们会经常总结自身经验,帮助广大学生和初入职场的新手司机快速提升,欢迎关注。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1.1 JAVA面试题解惑系列(一)——类的初始化顺序 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3 1.2 JAVA面试题解惑系列(二)——到底创建了几个String对象? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8 1.3 JAVA面试题解惑系列(三)——变量(属性)的覆盖 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .16 1.4 JAVA面试题解惑系列(四)——final、finally和finalize的区别 . . . . . . . . . . . . . . . . . . . . . . . . . . . .22 1.5 JAVA面试题解惑系列(五)——传了值还是传了引用? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .31 1.6 JAVA面试题解惑系列(六)——字符串(String)杂谈 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .36 1.7 JAVA面试题解惑系列(七)——日期和时间的处理 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .46 1.8 JAVA面试题解惑系列(八)——聊聊基本类型(内置类型) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .63 1.9 JAVA面试题解惑系列(九)——继承、多态、重载和重写 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .80 1.10 JAVA面试题解惑系列(十)——话说多线程 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .86 1.11 JAVA面试题解惑系列(十一)——这些运算符你是否还记得? . . . . . . . . . . . . . . . . . . . . . . . . . .103

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值