java android面试题分析总结

本文参考多处,一并感谢!

http://www.blogjava.net/fanyingjie/archive/2007/06/27/126467.aspx

http://baike.baidu.com/view/1788559.htm

http://jeff-tang.blog.163.com/blog/static/141686909201022010522906/

http://www.cnblogs.com/mgod/archive/2007/08/05/844011.html

参考过的书籍

《深入理解Java虚拟机:JVM高级特性与最佳实践》

12.ArrayList,Vector,LinkedList的区别

 ArrayListVectorLinkedList
实现原理数组数组双向链表
线程安全
优点1.数组实现优于遍历
2.非线程安全,效率较高
1.数组实现优于遍历
2.线程安全
1.节点的增删无需对象的重建
2.空间利用毫无浪费
缺点1.非线程安全
2.数组中未使用元素照成了空间的浪费
3.扩容可能引起对象的重建
4.增删有可能引起数组元素的移动
1.数组中未使用的元素造成空间的浪费
2.扩容可能引起对象的重建
3.线程安全,效率相对低
4.增删有可能引起数组元素的移动
1.遍历效率较低
2.非线程安全
扩容0.5倍增量1倍增量按需增删
使用场景1.无线程的要求。
2.遍历较多,增删较少
1.有线程安全的要求
2.遍历场景较多,增删场景较少
增删场景较多的时候

11.int与Integer的区别

 intInteger
类型基本类型复合类型
默认值0null
存储栈(局部变量)
堆(成员变量,有待进一步确认)
堆上(只能通过new创建)
方法基本类型无方法
速度快(栈上 的操作相对快)
泛型支持否(java中的泛型不支持,C++中的模板支持)支持
容器类支持否(直接使用通常会进行装箱操作)支持
存在意义1.历史原因(顺延C/C++中存在)
2.方便快速(无需new)
基本类型int的包装类
提供了对泛型,容器类的支持

9.向一个List<Integer>的容器里放入String对象

需要了解的一些知识

  • Java中的泛型是伪泛型。(可参见周志明的《深入理解Java虚拟机:JVM高级特性与最佳实践》)
    • 泛型是编译器的语法糖,并非产生了实际类型List<Integer>。
    • 对于List<Integer>和List<String>都是在编译之后,都是作为List<Object>类型来使用的。
    • 在Java虚拟机中,没有泛型的概念。
  • 通过反射可以把一些强制性的检查推迟到运行期。
    • 如果直接向List<Integer>中插入String对象,肯定会得到编译器的检查,并提示错误。
    • 而反射机制可以把这种错误的检查延迟到运行期。(这是反射的一个缺点,会把编译期能够检查到的问题,推迟到了运行期发现)
  • 由于List<Integer>对象在运行期,本身就是以List<Object>的形式存在,故其在运行期不会产生错误。
  • 反射机制,通过编译期的检查骗过了我们。而我们又可以通过反射骗过了编译器的检查。
实现代码
packagecom.jue.test;


importjava.lang.reflect.InvocationTargetException;
importjava.lang.reflect.Method;
importjava.util.ArrayList;
importjava.util.List;


publicclassTestMain{


List<Integer>mIntList=newArrayList<Integer>();


publicstaticvoidmain(String[]args)throwsSecurityException,
NoSuchFieldException,IllegalArgumentException,
IllegalAccessException,InvocationTargetException,
NoSuchMethodException{


TestMaintm=newTestMain();


MethodaddMethod=List.class.getMethod("add",
newClass[]{Object.class});


//使用反射,我们避免了编译期的强制检查
addMethod.invoke(tm.mIntList,newObject[]{newString("abc")});
addMethod.invoke(tm.mIntList,newObject[]{newString("123")});
addMethod.invoke(tm.mIntList,newObject[]{newString("cde")});
addMethod.invoke(tm.mIntList,newObject[]{newString("fgh")});


for(Objecto:tm.mIntList){
System.out.println(o);
}
}
}

输出结果:

abc
123
cde
fgh

10.List<Integer>与List<String>在编译后都是List<Object>形式存在

packagecom.jue.test;


importjava.util.List;


publicclassTestMain{


publicvoidtestList(List<Integer>list){


}


publicvoidtestList(List<String>list){


}
}

结果:编译失败!

分析:

  • 如上所述,Java的泛型是编译器的语法糖,在编译后,统一使用List<Object>代替。
  • 对于重载,方面名相同,而签名不同,由于参数都将是List<Object>,故编译失败,因为不可能产生签名一样的两个方法。

1.short转换相关的

其一,

packagecom.jue.test;


publicclassTestMain{
publicstaticvoidmain(Stringargs[]){
shorts1=1;
s1=s1+1;
}


}

编译结果

DescriptionResourcePathLocationType
Type mismatch: cannot convert from int to short TestMain.java/TestShort/src/com/jue/testline 6Java Problem

分析:

s1+1会自动转换成int类型,导致s1= s1+1;损失精度。

其二,

packagecom.jue.test;


publicclassTestMain{
publicstaticvoidmain(Stringargs[]){
shorts2=2;
s2+=2;
}
}

编译结果:成功

分析:

反编译之后

packagecom.jue.test;


publicclassTestMain
{
publicstaticvoidmain(String[]args)
{
shorts2=2;
s2=(short)(s2+2);
}
}

故猜测:这可能是java编译器的语法糖。

2.RuntimeException与普通异常,error的区别。

Checked Exception:在编译时就能够被Java编译器所检测到的。

UncheckedException:则是编译时,java编译器不能检查到。

 RuntimeException普通ExceptionError
受控异常
产生原因开发者的编程错误由于外界环境所限,
本身潜在的一些问题
Java运行时的系统错误,资源耗尽,是一种严重的,
程序无法修复的问题
例子NullPointerException
ArrayOutOfIndexException
ClassCastException
ArithmeticException
UnsupportedOperationException
ClassNotFoundException
IOException
FileNotFoundException
VirtualMachineError
StackOverflowError
OutOfMemoryError

3.finally的一个面试题

packagecom.jue.test;


importjava.util.ArrayList;
importjava.util.List;


publicclassTestMain{


publicstaticvoidmain(String[]args){
test();
}


privatestaticvoidtest(){
Listlist=newArrayList();
try{
System.out.println("return!!");
return;
}catch(Exceptione){
System.out.println("catchException!!");
}finally{
System.out.println("finally!!");
}
}


}


结果:

return!!
finally!!

分析:即便在try中return;finally总会被执行的意义不变,仍然会执行。

4.final,finalize,finally的区别

final:关键字,表不变

修饰:

  • 方法:方法不可Override
  • 类:不可被继承
  • 基本类型量:常量,值不可变
  • 符合类型量:引用不可变,即引用的值不可变
finalObjecto1=newObject();
o1=newObject();

finally:关键字,Java异常处理机制的一部分,在异常发生时,用来提供一个必要的清理的机会。

finalize:Object类的方法(参考自百度百科

意义:Java技术允许使用finalize()方法在垃圾回收器将对象回收之前,做一些必要的清理操作。

调用前提:这个对象确定没有被引用到。

工作原理:

  • 垃圾收集器准备好释放对象占用的空间。
  • 首先调用其finalize方法。
  • 下一次垃圾收集过程中,真正回收内存。

不确定性:

  • finalize的执行时间是不缺定的。
  • 一个对象引用另一个对象,并不能保证finalize的方法按照特定的执行顺序。

5.Override,Overload

 OverrideOverload
签名+返回值相同方法名相同,签名不同
关系父子类继承关系通常是同一类层次中
识别运行时多态
根据具体的对象,
查询对象的虚方法表,确定调用关系
编译时多态
由对象的外观类型(即声明类型)决定
修饰符限制非private
非static
非final
无特别
异常关系子类方法不能抛出被父类方法更多的异常无特别
可见性关系子类不能比父类访问权限更窄
(里氏替换原则决定)
无特别

6.Collection Collections

Collection:接口,集合类的接口,一个契约,提供了集合基本的大小,添加,清除,遍历方法等。

Collections:工具类,提供了很多静态方法,给集合提供一些查询,比较,排序,交换,线程安全化等方法。

7.Integer 缓存

packagecom.jue.test;


publicclassTestMain{


publicstaticvoidmain(String[]args){
Integeri1=1;
Integeri11=1;
System.out.println(i1==i11);


Integeri2=200;
Integeri22=200;
System.out.println(i2==i22);


}


}

结果 :

true

false

分析:反编译结果为

packagecom.jue.test;


importjava.io.PrintStream;


publicclassTestMain
{
publicstaticvoidmain(String[]args)
{
Integeri1=Integer.valueOf(1);
Integeri11=Integer.valueOf(1);
System.out.println(i1==i11);


Integeri2=Integer.valueOf(200);
Integeri22=Integer.valueOf(200);
System.out.println(i2==i22);
}
}

可以看出,对于Integer i = 1;编译器做了额外的处理,即Integer.valueof();

Integer source code

publicstaticIntegervalueOf(inti){
assertIntegerCache.high>=127;
if(i>=IntegerCache.low&&i<=IntegerCache.high)
returnIntegerCache.cache[i+(-IntegerCache.low)];
returnnewInteger(i);
}

可以看出Integer对于一定 范围内的数字从Cache中取得,对于额外的,调用new创建。

IntegerCache源码如下:

privatestaticclassIntegerCache{
staticfinalintlow=-128;
staticfinalinthigh;
staticfinalIntegercache[];
static{
//highvaluemaybeconfiguredbyproperty
inth=127;
StringintegerCacheHighPropValue=sun.misc.VM
.getSavedProperty("java.lang.Integer.IntegerCache.high");
if(integerCacheHighPropValue!=null){
inti=parseInt(integerCacheHighPropValue);
i=Math.max(i,127);
//MaximumarraysizeisInteger.MAX_VALUE
h=Math.min(i,Integer.MAX_VALUE-(-low));
}
high=h;
cache=newInteger[(high-low)+1];
intj=low;
for(intk=0;k<cache.length;k++)
cache[k]=newInteger(j++);
}


privateIntegerCache(){
}
}
故可以知道Integer的大小,默认是从-128到127,对于这个范围内的数组做了缓存的处理。

8.sleep方法和wait方法的区别

 waitsleep
所属类ObjectThread
意义让线程挂起让线程休眠指定的时间
释放锁否(这个跟锁本来就没有关系)
恢复1.有参:wait指定时间
2.无参:等待其他线程notify
1.根据参数长度自动恢复。
2.异常打断
使用限制wait,notify必须持有当前对象锁的情况下调用无特别
抛出异常
静态方法

相关推荐