面试是我们每个人都要经历的事情,大部分人且不止一次,这里给大家总结最新的 2016 年面试题,让大家在找工作时候能够事半功倍.
1.Switch 能否用 string 做参数?
a. 在 Java 7 之前, switch 只能支持 byte,short,char,int 或者其对应的封装类以及 Enum 类型.在 JAVA 7 中, String 支持被加上了.
2.equals 与 == 的区别:
a.== 是判断两个变量或实例是不是指向同一个内存空间 equals 是判断两个变量或实例所指向的内存空间的值是不是相同
3.Object 有哪些公用方法?
a. 方法 equals 测试的是两个对象是否相等
b. 方法 clone 进行对象拷贝
c. 方法 getClass 返回和当前对象相关的 Class 对象
d. 方法 notify,notifyall,wait 都是用来对给定对象进行线程同步的
4.Java 的四种引用,强弱软虚,用到的场景
a. 利用软引用和弱引用解决 OOM 问题:用一个 HashMap 来保存图片的路径和相应图片对象关联的软引用之间的映射关系,在内存不足时,JVM 会自动回收这些缓存图片对象所占用的空间,从而有效地避免了 OOM 的问题
b. 通过软可及对象重获方法实现 Java 对象的高速缓存: 比如我们创建了一 Employee 的类,如果每次需要查询一个雇员的信息.哪怕是几秒中之前刚刚查询过的,都要重新构建一个实例,这是需要消耗很多时间的.我们可以通过软引用和 HashMap 的结合,先是保存引用方面:以软引用的方式对一个 Employee 对象的实例进行引用并保存该引用到 HashMap 上,key 为此雇员的 id,value 为这个对象的软引用,另一方面是取出引用,缓存中是否有该 Employee 实例的软引用,如果有,从软引用中取得.如果没有软引用,或者从软引用中得到的实例是 null,重新构建一个实例,并保存对这个新建实例的软引用
c. 强引用:如果一个对象具有强引用,它就不会被垃圾回收器回收.即使当前内存空间不足,JVM 也不会回收它,而是抛出 OutOfMemoryError 错误,使程序异常终止.如果想中断强引用和某个对象之间的关联,可以显式地将引用赋值为 null,这样一来的话,JVM 在合适的时间就会回收该对象
d. 软引用:在使用软引用时,如果内存的空间足够,软引用就能继续被使用,而不会被垃圾回收器回收,只有在内存不足时,软引用才会被垃圾回收器回收.
e. 弱引用:具有弱引用的对象拥有的生命周期更短暂.因为当 JVM 进行垃圾回收,一旦发现弱引用对象,无论当前内存空间是否充足,都会将弱引用回收.不过由于垃圾回收器是一个优先级较低的线程,所以并不一定能迅速发现弱引用对象
f. 虚引用:顾名思义,就是形同虚设,如果一个对象仅持有虚引用,那么它相当于没有引用,在任何时候都可能被垃圾回收器回收.
g. 使用场景:
5.Hashcode 的作用,与 equal 有什么区别
a. 同样用于鉴定 2 个对象是否相等的,java 集合中有 list 和 set 两类,其中 set 不允许元素重复实现,那个这个不允许重复实现的方法,如果用 equal 去比较的话,如果存在 1000 个元素,你 new 一个新的元素出来,需要去调用 1000 次 equal 去逐个和他们比较是否是同一个对象,这样会大大降低效率.hashcode 实际上是返回对象的存储地址,如果这个位置上没有元素,就把元素直接存储在上面,如果这个位置上已经存在元素,这个时候才去调用 equal 方法与新元素进行比较,相同的话就不存了,散列到其他地址上
6.String,StringBuffer 与 StringBuilder 的区别
a.String 类型和 StringBuffer 类型的主要性能区别其实在于 String 是不可变的对象
b.StringBuffer 和 StringBuilder 底层是 char[] 数组实现的
c.StringBuffer 是线程安全的,而 StringBuilder 是线程不安全的
7.Override 和 Overload 的含义去区别
a.Overload 顾名思义是重新加载,它可以表现类的多态性,可以是函数里面可以有相同的函数名但是参数名,返回值,类型不能相同;或者说可以改变参数,类型,返回值但是函数名字依然不变.
b. 就是 ride(重写) 的意思,在子类继承父类的时候子类中可以定义某方法与其父类有相同的名称和参数,当子类在调用这一函数时自动调用子类的方法,而父类相当于被覆盖(重写)了.
8. 抽象类和接口的区别
a. 一个类只能继承单个类,但是可以实现多个接口
b. 接口强调特定功能的实现,而抽象类强调所属关系
c. 抽象类中的所有方法并不一定要是抽象的,你可以选择在抽象类中实现一些基本的方法.而接口要求所有的方法都必须是抽象的
9. 解析 XML 的几种方式的原理与特点:DOM,SAX,PULL
a.DOM:消耗内存:先把 xml 文档都读到内存中,然后再用 DOM API 来访问树形结构,并获取数据.这个写起来很简单,但是很消耗内存.要是数据过大,手机不够牛逼,可能手机直接死机
b.SAX:解析效率高,占用内存少,基于事件驱动的:更加简单地说就是对文档进行顺序扫描,当扫描到文档 (document) 开始与结束,元素 (element) 开始与结束,文档 (document) 结束等地方时通知事件处理函数,由事件处理函数做相应动作,然后继续同样的扫描,直至文档结束.
c.SAX:与 SAX 类似,也是基于事件驱动,我们可以调用它的 next()方法,来获取下一个解析事件(就是开始文档,结束文档,开始标签,结束标签),当处于某个元素时可以调用 XmlPullParser 的 getAttributte() 方法来获取属性的值,也可调用它的 nextText() 获取本节点的值.
10.wait() 和 sleep() 的区别
sleep 来自 Thread 类,和 wait 来自 Object 类
调用 sleep() 方法的过程中,线程不会释放对象锁.而 调用 wait 方法线程会释放对象锁
sleep 睡眠后不出让系统资源,wait 让出系统资源其他线程可以占用 CPU
sleep(milliseconds) 需要指定一个睡眠时间,时间一到会自动唤醒
11.JAVA 中堆和栈的区别,说下 java 的内存机制
a. 基本数据类型比变量和对象的引用都是在栈分配的
b. 堆内存用来存放由 new 创建的对象和数组
c. 类变量(static 修饰的变量),程序在一加载的时候就在堆中为类变量分配内存,堆中的内存地址存放在栈中
d. 实例变量:当你使用 java 关键字 new 的时候,系统在堆中开辟并不一定是连续的空间分配给变量,是根据零散的堆内存地址,通过哈希算法换算为一长串数字以表征这个变量在堆中的 "物理位置", 实例变量的生命周期-当实例变量的引用丢失后,将被 GC(垃圾回收器)列入可回收 "名单" 中,但并不是马上就释放堆中内存
e. 局部变量: 由声明在某方法,或某代码段里(比如 for 循环),执行到它的时候在栈中开辟内存,当局部变量一但脱离作用域,内存立即释放
12.JAVA 多态的实现原理
a. 抽象的来讲,多态的意思就是同一消息可以根据发送对象的不同而采用多种不同的行为方式.(发送消息就是函数调用)
b. 实现的原理是动态绑定,程序调用的方法在运行期才动态绑定,追溯源码可以发现,JVM 通过参数的自动转型来找到合适的办法.
c.Java 学习交流 QQ 群:589809992 我们一起学 Java!
13.JAVA 垃圾回收机制
a. 标记回收法:遍历对象图并且记录可到达的对象,以便删除不可到达的对象,一般使用单线程工作并且可能产生内存碎片
b. 标记 - 压缩回收法:前期与第一种方法相同,只是多了一步,将所有的存活对象压缩到内存的一端,这样内存碎片就可以合成一大块可再利用的内存区域,提高了内存利用率
c. 复制回收法:把现有内存空间分成两部分,gc 运行时,它把可到达对象复制到另一半空间,再清空正在使用的空间的全部对象.这种方法适用于短生存期的对象,持续复制长生存期的对象则导致效率降低.
d. 分代回收发:把内存空间分为两个或者多个域,如年轻代和老年代,年轻代的特点是对象会很快被回收,因此在年轻代使用效率比较高的算法.当一个对象经过几次回收后依然存活,对象就会被放入称为老年的内存空间,老年代则采取标记 - 压缩算法
e. 引用计数(最简单古老的方法):指将资源(可以是对象,内存或磁盘空间等等)的被引用次数保存起来,当被引用次数变为零时就将其释放的过程
f. 对象引用遍历(现在大多数 jvm 使用的方法):对象引用遍历从一组对象开始,沿着整个对象图上的每条链接,递归确定可到达(reachable)的对象.如果某对象不能从这些根对象的一个(至少一个)到达,则将它作为垃圾收集
g. 什么是垃圾回收机:释放那些不再持有引用的对象的内存
h. 怎么判断一个对象是否需要收集?
i. 几种垃圾回收机制
14. 讲讲 Java 中的集合有多少种,区别是什么?
a.HashTable 比较老,是基于 Dictionary 类实现的,HashTable 则是基于 Map 接口实现的
b.HashTable 是线程安全的, HashMap 则是线程不安全的
c.HashMap 可以让你将空值作为一个表的条目的 key 或 value
d.ArrayList,LinkedList,Vector 的区别:ArrayList 和 Vector 底层是采用数组方式存储数据,Vector 由于使用了 synchronized 方法(线程安全)所以性能上比 ArrayList 要差,LinkedList 使用双向链表实现存储,随机存取比较慢
e.HashMap 的底层源码实现:当我们往 HashMap 中 put 元素的时候,先根据 key 的 hashCode 重新计算 hash 值,根据 hash 值得到这个元素在数组中的位置(即下标),如果数组该位置上已经存放有其他元素了,那么在这个位置上的元素将以链表的形式存放,新加入的放在链头,最先加入的放在链尾.如果数组该位置上没有元素,就直接将该元素放到此数组中的该位置上.
f.Fail-Fast 机制: 在使用迭代器的过程中有其他线程修改了 map,那么将抛出 ConcurrentModificationException,这就是所谓 fail-fast 机制.这一机制在源码中的实现是通过 modCount 域,modCount 顾名思义就是修改次数,对 HashMap 内容的修改都将增加这个值,那么在迭代器初始化过程中会将这个值赋给迭代器的 expectedModCount.在迭代过程中,判断 modCount 跟 expectedModCount 是否相等,如果不相等就表示已经有其他线程修改了 Map.
g.HashMap 和 HashTable 的区别.
我有一个微信公众号,经常会分享一些 Java 技术相关的干货.如果你喜欢我的分享,可以用微信搜索 "Java 团长" 或者 "javatuanzhang" 关注.
来源: http://geek.csdn.net/news/detail/252487