android面试

 转自:http://www.itlanbao.com/ns/news.aspx?s=600030


 

ArrayList

Vector

LinkedList

实现原理

数组

数组

双向链表

线程安全

优点

1.数组实现优于遍历 2.非线程安全,效率较高

1.数组实现优于遍历 2.线程安全

1.节点的增删无需对象的重建 2.空间利用毫无浪费

缺点

1.非线程安全 2.数组中未使用元素照成了空间的浪费 3.扩容可能引起对象的重建 4.增删有可能引起数组元素的移动

1.数组中未使用的元素造成空间的浪费 2.扩容可能引起对象的重建 3.线程安全,效率相对低 4.增删有可能引起数组元素的移动

1.遍历效率较低 2.非线程安全

扩容

0.5倍增量

1倍增量

按需增删

使用场景

1.无线程的要求。 2.遍历较多,增删较少

1.有线程安全的要求 2.遍历场景较多,增删场景较少

增删场景较多的时候


  • int与Integer的区别

 

int

Integer

类型

基本类型

复合类型

默认值

0

null

存储

栈(局部变量) 堆(成员变量,有待进一步确认)

堆上(只能通过new创建)

方法

基本类型无方法

速度

快(栈上 的操作相对快)

泛型支持

否(java中的泛型不支持,C++中的模板支持)

支持

容器类支持

否(直接使用通常会进行装箱操作)

支持

存在意义

1.历史原因(顺延C/C++中存在) 2.方便快速(无需new)

基本类型int的包装类 提供了对泛型,容器类的支持

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

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

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


 

RuntimeException

普通Exception

Error

受控异常

产生原因

开发者的编程错误

由于外界环境所限, 本身潜在的一些问题

Java运行时的系统错误,资源耗尽,是一种严重的, 程序无法修复的问题

例子

NullPointerException ArrayOutOfIndexException ClassCastException ArithmeticException UnsupportedOperationException

ClassNotFoundException IOException FileNotFoundException

VirtualMachineError StackOverflowError OutOfMemoryError

4.final,finalize,finally的区别
  

final:关键字,表不变

修饰:

  • 方法:方法不可Override
  • 类:不可被继承
  • 基本类型量:常量,值不可变
  • 符合类型量:引用不可变,即引用的值不可
  1. final Object o1 = new Object();  
  2. o1 = new Object();  
  finally:关键字,Java异常处理机制的一部分,在异常发生时,用来提供一个必要的清理的机会。
  finalize:Object类的方法(参考自百度百科
  意义:Java技术允许使用finalize()方法在垃圾回收器将对象回收之前,做一些必要的清理操作。
调用前提:这个对象确定没有被引用到。
工作原理:
垃圾收集器准备好释放对象占用的空间。
  • 首先调用其finalize方法。
  • 下一次垃圾收集过程中,真正回收内存。
  • 不确定性:
  finalize的执行时间是不缺定的。
  • 一个对象引用另一个对象,并不能保证finalize的方法按照特定的执行顺序。
5.Override,Overload
 

Override

Overload

签名+返回值

相同

方法名相同,签名不同

关系

父子类继承关系

通常是同一类层次中

识别

运行时多态 根据具体的对象, 查询对象的虚方法表,确定调用关系

编译时多态 由对象的外观类型(即声明类型)决定

修饰符限制

非private 非static 非final

无特别

异常关系

子类方法不能抛出被父类方法更多的异常

无特别

可见性关系

子类不能比父类访问权限更窄 (里氏替换原则决定)

无特别

6.Collection Collections

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

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

7.Integer 缓存

package com.jue.test;

public class TestMain {

public static void main(String[] args) {

Integer i1 = 1;

Integer i11 = 1;

System.out.println(i1 == i11);

Integer i2 = 200;

Integer i22 = 200;

System.out.println(i2 == i22);

}

}

 结果 :True,false

分析:反编译结果为   Integer i1 = Integer.valueOf(1);

  可以看出,对于Integer i = 1;编译器做了额外的处理,即Integer.valueof();可以看出Integer对于一定 范围内的数字从Cache中取得,对于额外的,调用new创建。

 故可以知道Integer的大小,默认是从-128到127,对于这个范围内的数组做了缓存的处理。 对于额外的,调用new创建

 

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

wait

sleep

所属类

Object

Thread

意义

让线程挂起

让线程休眠指定的时间

释放锁

否(这个跟锁本来就没有关系)

恢复 

1.有参:wait指定时间 2.无参:等待其他线程notify

1.根据参数长度自动恢复。 2.异常打断

使用限制

wait,notify必须持有当前对象锁的情况下调用

无特别

抛出异常

静态方法

9.HashMap和Hashtable的区别。 

    HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口,主要区别在于HashMap允许空(null)键值(key),由于非线程安全,效率上可能高于Hashtable。

HashMap允许将null作为一个entry的key或者value,而Hashtable不允许。

HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。因为contains方法容易让人引起误解。

 

10、设计模式的分类

总体来说设计模式分为三大类:

创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。

结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。

行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

其实还有两类:并发型模式和线程池模式。用一个图片来整体描述一下:



http://www.cnblogs.com/maowang1991/archive/2013/04/15/3023236.html

 

 

 一:工厂模式:

(1):工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的。

 

首先,创建二者的共同接口:

[java] view plaincopy
public interface Sender {  
    public void Send();  
}  

其次,创建实现类:

[java] view plaincopy
public class MailSender implements Sender {  
    @Override  
    public void Send() {  
        System.out.println("this is mailsender!");  
    }  
}  

[java] view plaincopy
public class SmsSender implements Sender {  
  
    @Override  
    public void Send() {  
        System.out.println("this is sms sender!");  
    }  
}  

最后,建工厂类:

[java] view plaincopy
public class SendFactory {  
  
    public Sender produce(String type) {  
        if ("mail".equals(type)) {  
            return new MailSender();  
        } else if ("sms".equals(type)) {  
            return new SmsSender();  
        } else {  
            System.out.println("请输入正确的类型!");  
            return null;  
        }  
    }  
}  

我们来测试下:
public class FactoryTest {  
  
    public static void main(String[] args) {  
        SendFactory factory = new SendFactory();  
        Sender sender = factory.produce("sms");  
        sender.Send();  
    }  
}  

输出:this is sms sender!

 

 

a、多个工厂方法模式,是对普通工厂方法模式的改进,在普通工厂方法模式中,如果传递的字符串出错,则不能正确创建对象,而多个工厂方法模式是提供多个工厂方法,分别创建对象。关系图:



将上面的代码做下修改,改动下SendFactory类就行,如下:

[java] view plaincopypublic class SendFactory {  

   public Sender produceMail(){  
        return new MailSender();  
    }  
      
    public Sender produceSms(){  
        return new SmsSender();  
    }  
}  

测试类如下:

[java] view plaincopy
public class FactoryTest {  
  
    public static void main(String[] args) {  
        SendFactory factory = new SendFactory();  
        Sender sender = factory.produceMail();  
        sender.Send();  
    }  
}  

输出:this is mailsender!

 

b、静态工厂方法模式,将上面的多个工厂方法模式里的方法置为静态的,不需要创建实例,直接调用即可。

[java] view plaincopy
public class SendFactory {  
      
    public static Sender produceMail(){  
        return new MailSender();  
    }  
      
    public static Sender produceSms(){  
        return new SmsSender();  
    }  
}  

[java] view plaincopy
public class FactoryTest {  
  
    public static void main(String[] args) {      
        Sender sender = SendFactory.produceMail();  
        sender.Send();  
    }  
}  

输出:this is mailsender!

总体来说,工厂模式适合:凡是出现了大量的产品需要创建,并且具有共同的接口时,可以通过工厂方法模式进行创建。在以上的三种模式中,第一种如果传 入的字符串有误,不能正确创建对象,第三种相对于第二种,不需要实例化工厂类,所以,大多数情况下,我们会选用第三种——静态工厂方法模式。

 
可以看出工厂方法的加入,使得对象的数量成倍增长。当产品种类非常多时,会出现大量的与之对应的工厂对象,这不是我们所希望的。因为如果不能避免这种情 况,可以考虑使用简单工厂模式与工厂方法模式相结合的方式来减少工厂类:即对于产品树上类似的种类(一般是树的叶子中互为兄弟的)使用简单工厂模式来实 现。

 

c、简单工厂和工厂方法模式的比较

 工厂方法模式和简单工厂模式在定义上的不同是很明显的。工厂方法模式的核心是一个抽象工厂类,而不像简单工厂模式, 把核心放在一个实类上。工厂方法模式可以允许很多实的工厂类从抽象工厂类继承下来, 从而可以在实际上成为多个简单工厂模式的综合,从而推广了简单工厂模式。 
反过来讲,简单工厂模式是由工厂方法模式退化而来。设想如果我们非常确定一个系统只需要一个实的工厂类, 那么就不妨把抽象工厂类合并到实的工厂类中去。而这样一来,我们就退化到简单工厂模式了。

d、抽象工厂模式

代码:

//抽象工厂类

public abstract class AbstractFactory {
     public abstract Vehicle createVehicle();
     public abstract Weapon createWeapon();
     public abstract Food createFood();
 }

//具体工厂类,其中Food,Vehicle,Weapon是抽象类,

public class DefaultFactory extends AbstractFactory{
     @Override
     public Food createFood() {
         return new Apple();
     }
     @Override
     public Vehicle createVehicle() {
         return new Car();
     }
     @Override
     public Weapon createWeapon() {
         return new AK47();
     }
 }

//测试类

public class Test {
     public static void main(String[] args) {
         AbstractFactory f = new DefaultFactory();
         Vehicle v = f.createVehicle();
         v.run();
         Weapon w = f.createWeapon();
         w.shoot();
         Food a = f.createFood();
         a.printName();
     }
 }

在抽象工厂模式中,抽象产品 (AbstractProduct) 可能是一个或多个,从而构成一个或多个产品族(Product Family)。 在只有一个产品族的情况下,抽象工厂模式实际上退化到工厂方法模式。


 六、总结。

 (1)简单工厂模式是由一个具体的类去创建其他类的实例,父类是相同的,父类是具体的。 
(2)工厂方法模式是有一个抽象的父类定义公共接口,子类负责生成具体的对象,这样做的目的是将类的实例化操作延迟到子类中完成。 
(3)抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口,而无须指定他们具体的类。它针对的是有多个产品的等级结构。而工厂方法模式针对的是一个产品的等级结构。

 

 

 

 

二、单例模式(Singleton)

单例对象(Singleton)是一种常用的设计模式。在Java应用中,单例对象能保证在一个JVM中,该对象只有一个实例存在。这样的模式有几个好处:

1、某些类创建比较频繁,对于一些大型的对象,这是一笔很大的系统开销。

2、省去了new操作符,降低了系统内存的使用频率,减轻GC压力。

3、有些类如交易所的核心交易引擎,控制着交易流程,如果该类可以创建多个的话,系统完全乱了。(比如一个军队出现了多个司令员同时指挥,肯定会乱成一团),所以只有使用单例模式,才能保证核心交易服务器独立控制整个流程。

首先我们写一个简单的单例类:

[java] view plaincopy
public class Singleton {  
  
    /* 持有私有静态实例,防止被引用,此处赋值为null,目的是实现延迟加载 */  
    private static Singleton instance = null;  
  
    /* 私有构造方法,防止被实例化 */  
    private Singleton() {  
    }  
  
    /* 静态工程方法,创建实例 */  
    public static Singleton getInstance() {  
        if (instance == null) {  
            instance = new Singleton();  
        }  
        return instance;  
    }  
  
    /* 如果该对象被用于序列化,可以保证对象在序列化前后保持一致 */  
    public Object readResolve() {  
        return instance;  
    }  
}  


这个类可以满足基本要求,但是,像这样毫无线程安全保护的类,如果我们把它放入多线程的环境下,肯定就会出现问题了,如何解决?我们首先会想到对getInstance方法加synchronized关键字,如下:

[java] view plaincopy
public static synchronized Singleton getInstance() {  
        if (instance == null) {  
            instance = new Singleton();  
        }  
        return instance;  
    }  

但是,synchronized关键字锁住的是这个对象,这样的用法,在性能上会有所下降,因为每次调用getInstance(),都要对对象上锁,事实上,只有在第一次创建对象的时候需要加锁,之后就不需要了,所以,这个地方需要改进。我们改成下面这个:

[java] view plaincopy
public static Singleton getInstance() {  
        if (instance == null) {  
            synchronized (instance) {  
                if (instance == null) {  
                    instance = new Singleton();  
                }  
            }  
        }  
        return instance;  
    }  

 

1、最简单的实现

首先,能想到的最简单的实现是,把类的构造函数写成private的,从而保证别的类不能实例化此类。然后在类中返回一个静态示例并返回给调用者。这样,调用者就可以通过这个引用使用这个实例了。

public class Singleton{    private static final Singleton singleton = new Singleton();        public static Singleton getInstance(){        return singleton;    }        private Singleton(){        }}

如上例,外部使用者如果需要使用SingletonClass的实例,只能通过getInstance()方法,并且它的构造方法是private的,这样就保证了只能有一个对象存在。

 

posted on 2015-11-03 10:08  I love Android  阅读(259)  评论(0编辑  收藏  举报