1. GC中如何判断对象需要被回收?
引用的概念:
简单的理解,如果一个变量的类型是 类类型,而非基本类型,那么该变量又叫做引用,类类型创建的对象都可以称为引用。
引用计数:
上面讲过了什么是引用,其实 java在GC时也会去看这个对象有没有任何引用与之关联,如果存在引用关系则表示这个对象还有用,不能被回收,如果不存在引用则可以基本定性为可被回收的对象了。使用此方式效率确实很高,但是有个致命的缺点,无法解决循环引用的问,例如下面这段代码:
public class Main {
public static void main(String[] args) {
MyObject object1 = new MyObject();
MyObject object2 = new MyObject();
object1.object = object2;
object2.object = object1;
object1 = null;
object2 = null;
}
}
class MyObject{
public Object object = null;
}
可以看到将object1和object2赋值为null,也就是说object1和object2指向的对象已经不可能再被访问,但是由于它们互相引用对方,导致它们的引用计数都不为0,那么垃圾收集器就永远不会回收它们。因此在Java中并没有采用这种方式。
正向可达:
为了解决循环引用的问题,java中采取了正向可达的方式,主要是通过Roots对象作为起点进行搜索,搜索走过的路径称为“引用链”,当一个对象到 Roots 没有任何的引用链相连时,证明此对象不可用,当然被判定为不可达的对象不一定就会成为可回收对象。被判定为不可达的对象要成为可回收对象必须至少经历两次标记过程,如果在这两次标记过程中仍然没有逃脱成为可回收对象的可能性,则基本上就真的成为可回收对象了,能否被回收其实主要还是要看finalize()方法有没有与引用链上的对象关联,如果在finalize()方法中有关联则自救成功,改对象不可被回收,反之如果没有关联则成功被二次标记成功,就可以称为要被回收的垃圾了。
Roots对象:
面试常问的问题,Roots对象有哪些?
1、引用栈帧中的本地变量表的所有对象;
2、引用方法区中静态属性的所有对象;
3、引用方法区中常量的所有对象;
4、引用Native方法的所有对象。
2.多线程中的i++线程安全吗?为什么?
不安全。每个线程都有自己的工作内存,每个线程需要对共享变量操作时必须把共享变量从主内存中加载到自己的工作内存。等完成操作再保存到内存中。如果一个线程运算完成后还没刷到主内存中,另一个线程又对这个共享变量进行操作,那么读取到的数据就是脏数据了。
3. object的hash该怎么设计
hash方法 - (NSUInteger)hash返回一个整数,这个数代表的就是当前对象的哈希值 有一个很重要的规范 : 如果两个对象相等,他们的hash值必须相等, 如果某个类自定义了isEqual方法,并且这个类的实例有可能会被加入到集合中,一点要确保hash方法被重新定义 和数组把元素存储在一系列连续的地址中不同,哈希算法使得 NSSet 和 NSDictionary 能够非常快速地(O(1)) 进行元素查找,哈希表会在内存中分配n个位置,然后使用一个函数来计算出位置范围之内的某个具体位置. 在数组和hash表中要判断一个元素是不是存在的算法和效率是不一样的,数组需要对数组中每个元素的位置都进行检查,hash有一个更快速的查找方式. 一个好的 hash函数在不需要太多计算量的情况下,可以使得生成的位置分布接近于均匀分布,当两个不同的对象计算出相同的散列值时,我们称其为发生了 哈希碰撞 。当出现碰撞时,哈希表会从碰撞产生的位置开始向后寻找,把新的元素放在第一个可供放置的位置,随着哈希表变得越来越致密,发生碰撞的可能性也会随之增加,导致查找可用位置花费的时间也会增加(这也是为什么我们希望哈希函数的结果分布更接近于均匀分布)
4.请问Query接口的list方法和iterate方法有什么区别?
1.返回的类型不一样,list返回List,iterate返回iterator
2.查询策略不同。
获取数据的方式不一样,list会直接查询数据库,iterate会先到数据库中把id取出来,然后真正要遍历某个对象的时候先到缓存中找,如果找不到,以id为条件再发一条sql到数据库,这样如果缓存中没有数据,则查询数据库的次数为n+1
3.iterate会查询2级缓存,list只会缓存,但不会使用缓存(除非结合查询缓存)。
4.list中返回的list中每个对象都是原本的对象,iterate中返回的对象是代理对象
参考: https://www.cnblogs.com/hmy-1365/p/5783838.html
5. 数组中只出现一次的数字
一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
示例代码:
//num1,num2分别为长度为1的数组。传出参数
//将num1[0],num2[0]设置为返回结果
public class Solution {
public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
}
}
实现代码:
import java.util.Map;
import java.util.hashMap;
//num1,num2分别为长度为1的数组。传出参数
//将num1[0],num2[0]设置为返回结果
public class Solution {
public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
Map<Integer,Integer> map=new HashMap<>();
for(int i=0;i<array.length;i++){
if(!map.containsKey()){//determine whether repeating
map.put(array[i],1);
}else{
map.put(array[i],map.get(array[i]+1));
}
}
int count=0;//accounter
for(int i=0;i<map.size();i++){
if(map.get(array[i])==1){
if(count==0){
num1[0]=array[i];
count++;
}else{
num2[0]=array[i];
}
}
}
}
}