1.为什么内部类会持有外部类的引用?
内部类:就是在某个类的内部又定义了一个类,内部类所嵌入的类称为外部类
匿名内部类:使用new生成的内部类
因为内部类的产生依赖于外部类,持有的引用是类名.this
3.Object有哪些公用方法?
方法equals测试的是两个对象是否相等
方法notify,notifyall,wait都是用来对给定对象进行线程同步的
方法clone进行对象拷贝
方法getClass返回和当前对象相关的Class对象
4.equals与==的区别:
==是判断两个变量或实例是不是指向同一个内存空间 equals是判断两个变量或实例所指向的内存空间的值是不是相
3、如果对象的equals方法被重写,那么对象的hashCode也尽量重写,并且产生hashCode使用的对象,一定要和equals方法中使用的一致,否则就会违反上面提到的第2点;
5.Java的四种引用的区别
-
强引用:如果一个对象具有强引用,它就不会被垃圾回收器回收。即使当前内存空间不足,JVM 也不会回收它,而是抛出 OutOfMemoryError 错误,使程序异常终止。如果想中断强引用和某个对象之间的关联,可以显式地将引用赋值为null,这样一来的话,JVM在合适的时间就会回收该对象
-
软引用:在使用软引用时,如果内存的空间足够,软引用就能继续被使用,而不会被垃圾回收器回收,只有在内存不足时,软引用才会被垃圾回收器回收。
-
弱引用:具有弱引用的对象拥有的生命周期更短暂。因为当 JVM 进行垃圾回收,一旦发现弱引用对象,无论当前内存空间是否充足,都会将弱引用回收。不过由于垃圾回收器是一个优先级较低的线程,所以并不一定能迅速发现弱引用对象
-
虚引用:顾名思义,就是形同虚设,如果一个对象仅持有虚引用,那么它相当于没有引用,在任何时候都可能被垃圾回收器回收。
6.JAVA垃圾回收原理
参考:
http://lemote.blog.163.com/blog/static/1748395072013111641050934/
面试过程中遇到一个问题:
java 垃圾回收器,回收没有引用指向的对象实例,那如果是A->B,B->A这种就一直回收不了了吗?
Q: Does unreachable mean when there are no more references to the object?这两个对象, 如果没有第三方引用到其中之一, 也就是外界无法访问到这两对象
A: No, but that is a common misunderstanding of garbage collection. You might think that the garbage collector keeps count of how many references there are to an object and then frees the object when the reference count is zero. However, it is easy to come up with a situation in which two objects need to be garbage collected, but each object has a reference to the other. If reference counting was being used, these two objects would never be freed.
问:当对象没有引用指向它时,就是unreachable吗?
答:不是,但这是关于垃圾回收的一个常见误解。你可能以为垃圾回收器会记录一个对象有多少个引用,当引用数为0时,就清理掉那个对象。但是,有一种很容易遇到的情况是,有2个对象需要被垃圾回收,但他们各自有一个指向对方的引用。如果使用引用数的话,这两个对象就永远不会被清理掉。
只有互相引用的话
这两个对象会连在一起 成为垃圾
可以被回收
这两个对象虽然有相互的引用,但是他们两个是无法使用的,因为没有外部引用指向其中任何一个对象,原来这就是unreachable的含义。
内存回收机制:
内存回收就是释放掉在内存中已经没用的对象。
首先,要判断怎样的对象是没用的对象。这里有2种方法:
1.采用标记计数的方法:
给内存中的对象给打上标记,对象被引用一次,计数就加1,引用被释放了,计数就减一,当这个计数为0的时候,这个对象就可以被回收了。当然,这也就引发了一个问题:循环引用的对象是无法被识别出来并且被回收的。所以就有了第二种方法:
2.采用根搜索算法:
垃圾回收他是在虚拟机空闲的时候或者内存紧张的时候执行的,什么时候回收不是由程序员来控制的,这也就是Java比较耗内存的原因之一。
还有在垃圾回收的时候当检测到对象没有用了,需要被回收的时候并不会马上被回收,而是将其放入到一个准备回收的队列,去执行finalize方法。。然等到下次内存回收的时候要是他还是没有被任何人引用的话,就将其给回收了。(如果在finalize方法中重新给对象加个引用,这样对象是有可能不会被回收的)不过finalize方法不推荐使用,他跟C++中的析构函数不同,我们既不能确定什么时候他回被回收,也不能保证这个方法一定会被执行。
7.数据结构中用于存储数据的有哪些
- 数组
数组存储区间是连续的,占用内存严重,故空间复杂的很大。但数组的二分查找时间复杂度小,为O(1);数组的特点是:寻址容易,插入和删除困难;
- 链表
链表存储区间离散,占用内存比较宽松,故空间复杂度很小,但时间复杂度很大,达O(N)。链表的特点是:寻址困难,插入和删除容易。
2.说说hashMap是怎样实现的
哈希表:由数组+链表组成的
更多资料,请点击。
当我们往HashMap中put元素的时候,先根据key的hashCode重新计算hash值,根据hash值得到这个元素在数组中的位置(即下标),如果数组该位置上已经存放有其他元素了,那么在这个位置上的元素将以链表的形式存放,新加入的放在链头,最先加入的放在链尾。如果数组该位置上没有元素,就直接将该元素放到此数组中的该位置上。
3.ArrayList,LinkedList的区别
-
ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。
-
对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。
-
对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。
-
4.ArrayList和Vector的主要区别是什么?
ArrayList 和Vector底层是采用数组方式存储数据
Vector:
线程同步
当Vector中的元素超过它的初始大小时,Vector会将它的容量翻倍,ArrayList:
线程不同步,但性能很好
当ArrayList中的元素超过它的初始大小时,ArrayList只增加50%的大小
5.HashMap和 HashTable 的区别:
HashTable比较老,是基于Dictionary 类实现的,HashTable 则是基于 Map接口实现的
HashTable 是线程安全的, HashMap 则是线程不安全的
HashMap可以让你将空值作为一个表的条目的key或value