android面试题准备-Java知识

版权声明:本文为博主原创文章,转载请标明地址。 https://blog.csdn.net/u013034413/article/details/79507043

面试题来源:
https://www.jianshu.com/p/c70989bd5f29

1.java中==和equals和hashCode的区别

参考地址:
http://blog.csdn.net/dove_knowledge/article/details/71027170
http://blog.csdn.net/tiantiandjava/article/details/46988461

1.1 ==

对于基本数据类型就是比较大小是否相等.(byte,boolean,short,char,int,float,long,double)

对于引用类型就是指向的内存地址是否相等(String,Integer,Date,对象)

1.2 equals

默认是引用类型,判断执行的内存地址是否相等。但是可以自己覆盖这个方法,根据需求提供不同的实现。

1.3 hashCode

如果两个对象根据equals()方法比较是相等的,那么调用这两个对象中任意一个对象的hashCode方法都必须产生同样的整数结果。
如果两个对象根据equals()方法比较是不相等的,那么调用这两个对象中任意一个对象的hashCode方法,则不一定要产生相同的整数结果
如果hashCode()方法的返回值不相等,一定能推出equals()方法的返回值也不相等,如果hashCode()方法的返回值相等,equals()方法的返回值则可能相等,也可能不相等。

一般在覆盖equals()方法的同时也要覆盖hashCode()方法,否则,就会违反Object.hashCode的通用约定,从而导致该类无法与所有基于散列值(hash)集合类(HashMap、HashSet和Hashtable)结合在一起正常运行。

在集合操作的时候有如下规则:
将对象放入到集合中时,首先判断要放入对象的hashcode值与集合中的任意一个元素的hashcode值是否相等,如果不相等直接将该对象放入集合中。如果hashcode值相等,然后再通过equals方法判断要放入对象与集合中的任意一个对象是否相等,如果equals判断不相等,直接将该元素放入到集合中,否则不放入。

2.int、char、long各占多少字节数

参考:http://blog.csdn.net/yushulinfengprc/article/details/70227156

Java基本类型占用的字节数:
1字节: byte , boolean
2字节: short , char
4字节: int , float
8字节: long , double
注:1字节(byte)=8位(bits)

3.int与Integer的区别

参考:https://www.cnblogs.com/guodongdidi/p/6953217.html
int是基本数据数据类型,默认值是0;integer是引用类型(通过new方法生成时可以看作是一个对象),默认值是null

两者比较

Integer与int,会自动拆包,比较的数值是否相等
两个通过new生成的Integer比较,永远不相等
两个不是通过new生成的Integer比较,如果数值大小都属于[-128,127],那么就是比较数值大小是否相等(有一个常量缓存池,都指向的常量池对象),否则永远不等。
一个new生成的Integer和一个非new生成的Integer永不相等(一个是自己单独生成的Integer,一个是常量池里的Integer)

4.对java多态的理解

参考:https://www.cnblogs.com/liujinhong/p/6003144.html

java面向对象的三大特性:封装、继承、多态

多态三要素 继承、重写、父类引用指向子类对象

父类引用指向子类对象,在执行期间判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。

方法执行时,(Father,Son类,Son继承自Father)

public class Father{
    public void tell(Father f){}        
}
public class extends Father{
    public void tell(Son s){}
    public void tell(Father f){}
}
Father f= new Son();
Son son2 = new Son();
f.tell(son2);

五步走:
1.直接去看Father中是否有tell(Son s);有直接执行,没有看第二步(这里没有)
2.Father的父类是否有tell(Son s);这里Father没有父类,走第三步
3.Father中是否有Father.tell(Father f);有直接执行,没有走第四步(这里走第五步)
4.Father的父类中是否有tell(Father f);有直接执行
5.这里准备执行tell(Father f);但是运行时发现子类重写了tell(Father f)那么就走Son类的tell(Father f);
具体查看上面的参考地址,讲解的很清楚。

5.String、StringBuffer、StringBuilder区别

参考:http://blog.csdn.net/rmn190/article/details/1492013
String 多个String对象之间互相拼接效率低下,生成额外的String对象。
StringBuffer 线程安全,对本身进行操作,不生成额外的对象。
StringBuilder 非线程安全,但是效率比StringBuffer高。

什么是内部类?内部类的作用

参考:https://www.cnblogs.com/dolphin0520/p/3811445.html
一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类。

1.成员内部类

定义在另一个类里面,也就是类中类。成员内部类可以无条件地访问外部类的成员,外部类想访问内部类的成员时需要new一个内部类,然后访问。可以简化代码,公开成员内部类的成员方法,隐藏外部类的成员方法。
使用:类中类

2.局部内部类

定义在一个方法,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内。局部内部类就像是方法里面的一个局部变量一样,是不能有public、protected、private以及static修饰符的。
使用:通过内部类和接口达到一个强制的弱耦合,用局部内部类来实现接口,并在方法中返回接口类型,使局部内部类不可见,屏蔽实现类的可见性。

3.匿名内部类

唯一一种没有构造器的类,例如OnClickListener(),在编译的时候由系统自动起名为Outter$1.class,
使用:一般用于接口回调,例如OnClickListener

4.静态内部类

只有将某个内部类修饰为静态类,然后才能够在这个类中定义静态的成员变量与成员方法。这 是静态内部类都有的一个特性。
使用:实现单例,详见13

优点

1.每个内部类都能独立的继承一个接口的实现,所以无论外部类是否已经继承了某个(接口的)实现,对于内部类都没有影响。内部类使得多继承的解决方案变得完整,

  2.方便将存在一定逻辑关系的类组织在一起,又可以对外界隐藏。
  3.方便编写事件驱动程序
  4.方便编写线程代码

6.抽象类和接口区别

抽象类是父类,是一系列子类的共同部分,里面可以有子类共同的属性、逻辑、方法,而接口就仅仅是一个行为规范,谁都可以实现,只要实现指定的接口即可,实现者之间没有丝毫关联。

抽象类的意义

抽离了相同的部分,方便维护和重用,减少代码量。

接口的意义

一种合约,见名知义,解耦合,(经典MVP模式)

应用场所:

抽象类:有共同的属性、逻辑、变量
接口:只定义某一种行为规范,没有共同的属性、逻辑、方法,解耦合

7.泛型中extends和super的区别

参考:https://www.cnblogs.com/yepei/p/6591289.html

<?extends T>代表?<=T,能get,只能add(null);
<? super T>代表?>=T 能add,get只能用Object接受

8.父类的静态方法能否被子类重写

参考:http://blog.csdn.net/kdc18333608478/article/details/52040914
父类的静态方法可以被子类继承,但是不能重写。

 Father b = new Son();
 b.staticMethod();

执行的是 Father.staticMethod(),与成员方法不一样。

9.进程和线程的区别

参考:
http://blog.csdn.net/zhou753099943/article/details/51771220
https://www.zhihu.com/question/25532384
进程是cpu资源分配的最小单位,线程是cpu调度的最小单位。
进程和线程都是一个时间段的描述,是CPU工作时间段的描述,不过是颗粒大小不同。

10.final,finally,finalize的区别

参考:https://jingyan.baidu.com/article/597a064363b676312b5243ad.html
final用于声明属性,方法和类,分别表示属性不可改变,方法不可覆盖,类不可继承。
finally是异常处理语句结构的一部分,表示总是执行。
finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,供垃圾收集时的其他资源回收,例如关闭文件等。

11.序列化的方式

参考:
http://www.jb51.net/article/107434.htm
https://www.jianshu.com/p/a60b609ec7e7
https://www.cnblogs.com/lang-yu/p/6186718.html
java序列化:Java原生序列化,Serializable,Json,fastjson.
android一般使用Serializable与Parcelable

Serializable与Parcelable的区别

1.内存间数据传输时推荐使用Parcelable,效率高(Parcelable是为了在程序内不同组件间以及不同Android程序间(AIDL)高效的传输数据而设计,这些数据仅在内存中存在,Parcelable是通过IBinder通信的消息的载体。)
2.Serializable可将数据持久化方便保存,所以在需要保存或网络传输数据时选择Serializable,缺点是序列化时产生大量的临时变量,引起频繁的GC

12.静态属性和静态方法是否可以被继承?是否可以被重写?以及原因?

java中静态属性和静态方法可以被继承,但是没有被重写(overwrite)而是被隐藏.

静态方法和属性是属于类的,并不属于成员。

13.静态内部类的设计意图

参考:https://www.zhihu.com/question/28197253
降低包的深度,方便类的使用
A,B两个类,B有点特殊,虽然可以独立存在,但只被A使用,不想被 C使用。
使用场景:例如:静态内部类实现单例

参考:http://blog.csdn.net/chenrushui/article/details/71191672
public class Singleton {    
private Singleton() {  
}    
public static final Singleton getInstance() {  
    return SingletonHolder.INSTANCE;  
}  
public static class SingletonHolder {  
    private static final Singleton INSTANCE = new Singleton();  
}  
} 

14.闭包和局部内部类的区别

参考:
http://blog.csdn.net/u010412719/article/details/49453235
https://zhuanlan.zhihu.com/p/29245059
匿名内部类:其实Java就是把外部类的一个变量拷贝给了内部类里面的另一个变量。
闭包:内部类使用外部类的局部变量,实际上形成了闭包。

public Bar method(){
    //String str="wuranghao";
    int num=30;
    //局部内部类将输出这个局部变量
    class innerClass extends Bar{
        public void show(){
            System.out.println(num);//持有了num,形成闭包
        }
    }
    return new innerClass();
}

15.string 转换成 integer的方式及原理

Integer i = Integer.valueOf(String str);

 public static Integer valueOf(String s) throws 
                     NumberFormatException {
    return Integer.valueOf(parseInt(s, 10));
}

 public static Integer valueOf(String s, int radix) throws 
                     NumberFormatException {
    return Integer.valueOf(parseInt(s,radix));
}

public static int parseInt(String s, int radix)
            throws NumberFormatException
{
}

public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}

猜你喜欢

转载自blog.csdn.net/u013034413/article/details/79507043