赞
踩
本文将带你了解Android应用开发之Android实习面面试题+答案,希望本文对大家学Android有所帮助。
<
题
二面:
application里面创建子线程处理耗时任务能不能代替service里面处理耗时任务
子线程里面能不能创建两个looper
快速排序(口述)和排序的复杂度
prim算法
如何证明贪心算法
双亲委派模型
权限关键字的含义,private除了set,get方法访问,还有什么方法
java中的四种引用
内存泄露和内存溢出的区别
java注解的实现
解答
application里面创建子线程处理耗时任务能不能代替service里面处理耗时任务
题目很有误导性。service也是运行在主线程中的,处理耗时任务依然要开启子线程。所以问题就变成了这样:application容器可以取代service容器吗先不讨论这个,先讨论activity容器和service容器的区别。前者如果是后台的容易被杀。application在app的生命周期内,都不会被杀。但是也不意味着可以取代。serivce是依附于进程的,如果它不依附于app进程,而且他所在的进程不被杀,那么他的生命周期可以比application更长。
子线程里面能不能创建两个looper
当然不行。你在Looper.myLooper()的时候会进行一个创建。然后存放在ThreadLocal里。他首先会进行一个threadLocal.get()的判断,如果不为空,会提示你只能创建一个。
手撸一个快排和计算他的复杂度
快排就是通过比较著名的挖坑填数法来理解的。(下面的快排代码新手可能得理解好一会了)
void quick_sort(int[] a, int start, int end) {
int base = a[start];
int s = start;
int e = end;
while(s
//从右向左搜,搜到比keng小的数
while(s
e--;
if(s
a[s++] = a[e];//坑就是哨兵处
}
while(s a[s]) {
s++;
if(s
a[e--] = a[s];
}
}
a[s] = base;//最后初始坑放入最后生成的坑,此时s==e
//递归
quick_sort(int[] a, start, i - 1);
quick_sork(int[] a, i + 1, end);
}
时间复杂度:因为这个是递归的情形,所以最好情况是55分,一次递归会比较n次,深度这样算:n n/2...1
经过k次,1变为n,2^k=n,k=log2n,所以深度是lgn,总复杂度是nlgn
最坏情况是已经排好序的数组,会比n-1次,n-2次,。。。1次,总和是n^2/2
平均情况挺难算的,但是思路也要了解:C(n)=n-1+1/n (C(0)+C(n-1)..)n次的和。第一层是n-1,后面的层数是取一个平均值,这点很容易理解。计算就比较坑了,网上也没有讲解,最后渐进于2nlnn
prim算法和贪心算法的证明
这两题,我选择不做,因为,没有意义。已经属于偏难怪的范畴了。要是安卓里的偏难怪题我还可以接受
类加载器+双亲委派模型
类加载器:在类加载的时候,需要通过类的全限定名->获取定义这个类的二进制流。
这个二进制流可以从class获取,可以从jar、war获取,可以从网络获取,可以由jsp文件生成。。。
类加载器+和类本身共同确定一个类,如果不是这个类加载器加载的,那么就不是同一个类。所以加载一个类如下:ClassLoaderTest.class.getClassLoader().loadClass("com.jvm.classloading.ClassLoaderTest").newInstance();
先获取这个类的类加载器,再去加载这个类,再去newInstance创建实例。
类加载器种类:从JVM角度,有两种类加载器:1.启动类加载器2.所有其他的类加载器
开发者角度1.启动类加载器,负责加载jar包等类库2.标准扩展类加载器:它负责将Java_Home /lib/ext或者由系统变量 java.ext.dir指定位置中的类库加载到内存中3.应用程序类加载器:将系统类路径(CLASSPATH)中指定的类库加载到内存中4.自定义类加载器
他们之间的层次关系就是:双亲委派模型,除了启动类加载器,其他的都应该有父加载器。
所以当一个加载器接到任务,是一层层向上抛任务的。父类能解决最好,不能解决还是他自己处理。
还有就是找父类的时候,找不到,一般就指定启动类加载器作为父类。
就这么简单,不过得好好理解,好好记忆。
private的属性,除了set和get,还能怎么访问
太简单了,反射呗。
Class.getDeclaredFields和Class.getDeclaredMethod。
前者是获取所有属性,后者是获取所有方法。
简单写一下吧。
比如Book对象,你想要拿他的一个private的bookName字段。
Field field = book.getClass().getDeclaredFields("bookName");
field.setAccessible(true)。
String bookName = field.get(book).toString();
就好了。注意下那个setAccessible方法,他就是让private的子段,变得可访问。
但是Class.getDeclaredFields拿不到继承的,Class.getField好像可以拿到继承的,但是不能拿到私有的,保护的。
内存泄漏和内存溢出的区别
我觉得内存泄漏你得从垃圾回收机制出发,好好讲讲。还是拿Handler的内存泄漏打比方。Looper,message,message.target=Handler,Activity。依然是可达的,故而不可释放。
注解的实现
我个人感觉这个东西很好用,也用它封装了很多控件。但是我对他的应用还很粗浅--就是简单的指明是运行时注解,指明你要从哪里获取(类上还是方法上还是字段上。。。)然后根据取得的值,进行处理。这是一种很好的封装方式。理解这点,估计暂时够用了。哦,对了,本质还是反射。Class.getAnnotion仍然是在程序运行时,获知了类中的一切,只不过我们获知的东西有点特殊,是依附于某个东西的(类上还是方法上还是字段上。。。)。
本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标移动开发之Android频道!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。