您的位置:首页 > 职场人生

经典面试题(不断更新中)

2016-10-05 02:59 148 查看
——————————————————————–史上最强面试题————————————————————————————-

AIDL

1、 要使用AIDL的前提的条件我们要只知道它是干什么的?
#AIDL 也就是在Android中定义的一个语言,他是进行进程间通讯的一种实现方式,通过定义AIDL接口,可以实现进程间通讯机制
2、 要知道它的使用步骤,前提条件??
#需求:比如现在有2个进程需要通信,那么他们是怎么进行通讯,使用步骤是什么??一个A,一个是B,B要用A里面的服务;
1)、首先在A中写一个服务,在服务里面定义一个方法进行暴露出去 ;
2)、刚刚我们说了要将这个方法暴露出去那么怎么暴露出去,现在就要用到AIDL来实现进程间通讯的机制了 ;
3)、定义一个接口.把要暴露的方法定义在接口中,不要有public之类的修饰符,不然会报错!,然后把这个接口的后缀名改为aidl格式 ;系统会自动在gen生成二个文件其中有一个是以接口名字.java命名的
4)、在A服务中定义一个中间人对象,写一个类继承Stub(实现接口它的本身已经已经实现了我们AIDL接口语言)实现暴露出去的方法.
5)、现在B中想要调用A中的服务,那么就可以通过我们刚刚写的AIDL来实现2个进程间的通信,把A中的AIDLCody到B的SRC目录下
6)、通过BindService绑定到A中的服务,然后在bindService里面创一个服务连接成功的接口,
7)、写一个类实现ServiceConnection,里面有连接成功和失败的方法,我们现在就可以在连接成功的时候通过Stub这个对象里面的asInterface这个方法可以获取到中间人对象,
8)、现在有中间人这个对象你就可以对A里面任意操作了,因为已经建立起关系了;


Handler

首先要知道Handler是干什么用的??
1、要明白Handler,Looper,MesagerQuque,Mesager三者的关系
1). Mesager 是消息的意思那么它的消息是通过MesagerQueque来进行维护消息的;
2). MesagerQuque 是消息队列的意思,消息最终会进行这个里面,是以发送的时间顺序进行以链表的形式进入消息队列的;
3). Handler 这个是个重要角色 他是进行处理消息和发送消的关键所在,跟Looper建立起联系的
4). Looper 自身具备循环机制,是不断重消息队列里面取消息的;
2、明白当在子线程发送消息的是怎么在主线程中收到消息的
1)当我们在主线程创建一个Handler对象会进入Handler的构造方法,构造方法里面有一个Looper.myLooper对象,当我们点击进去发现有一个当前线程get方法,那么有get就有set,set方法里面创建一个了一个Looper对象,looper对象里面会创建一个消息队列,现在有了消息对列,那消息是怎么进入到我这个消息队列里面的??又是怎么出去的???
2). 消息入队,enqueueMessage就是消息队列的里面的方法,它就是进行入队的,那么是怎么入队了,因为当我们不管是通过Handler.XXX发送消息最终都会都到sendMesagerAtTime方法,然后消息对象是以时间进行排序进入消息对列里面,现在我们知道消息怎么进入队列,哪消息怎么出去了??
3). 消息出队,是在Looper.loop里面Looper对象.消息队列,通过next取出消息,一直是死循环取消息,这里有可能会造成线程阻塞,为什么会造成阻塞(有可能又在主线程中做耗时的操作了),现在知道消息的入队和出队了  那么怎么消息就跑到主线程了
4). 刚刚在Looper.loop()里面取完消息的时候就会mes.tager.dispatchMessage(msg);把消息分发出去.tager就代表发送消息的handler;
5). 刚刚在Looper里面分发完消息,现在就回到Handler.dispatchMessage(),通过看先消息自身的回调如果不等于null的话,就调用自身的run方法,否则调用Callback中的handleMessage,如果前面都不满足的话  ,最后才调用Handler自身的HandlerMeaaseger方法更新UI


自定义控件

1、明白继承View的流程
1). 自定义View的属性
2). 在View的构造方法中获取我们自定义的属性
3). 重写onMesure
4). 重写onDraw


Android中的设计模式

1. 明白单列的好处???
1). 避免创建多个对象,占用内存空间
明白创建单列模式有哪些方式???
1). 我喜欢用内部类的形式
好处: 节省内存,线程安全
2). 双重锁懒汉式  安全  但是效率不好
单例模式

定义

保证一个类仅有一个实例,并提供一个访问它的全局访问点。
Singleton:负责创建Singleton类自己的唯一实例,并提供一个getInstance的方法,让外部来访问这个类的唯一实例。
饿汉式:  private static Singleton uniqueInstance = new Singleton();
懒汉式  private static Singleton uniqueInstance = null;
功能

单例模式是用来保证这个类在运行期间只会被创建一个类实例,另外,单例模式还提供了一个全局唯一访问这个类实例的访问点,就是getInstance方法。

范围

Java里面实现的单例是一个虚拟机的范围。因为装载类的功能是虚拟机的,所以一个虚拟机在通过自己的ClassLoader装载饿汉式实现单例类的时候就会创建一个类的实例。

懒汉式单例有延迟加载和缓存的思想

优缺点

懒汉式是典型的时间换空间
饿汉式是典型的空间换时间
不加同步的懒汉式是线程不安全的。比如,有两个线程,一个是线程A,一个是线程B,它们同时调用getInstance方法,就可能导致并发问题。

饿汉式是线程安全的,因为虚拟机保证只会装载一次,在装载类的时候是不会发生并发的。

如何实现懒汉式的线程安全?

加上synchronized即可

public static synchronized Singleton getInstance(){}
但这样会降低整个访问的速度,而且每次都要判断。可以用双重检查加锁。

双重加锁机制,指的是:并不是每次进入getInstance方法都需要同步,而是先不同步,进入方法过后,先检查实例是否存在,如果不存在才进入下面的同步块,这是第一重检查。进入同步块后,再次检查实例是否存在,如果不存在,就在同步的情况下创建一个实例。这是第二重检查。

双重加锁机制的实现会使用一个关键字volatile,它的意思是:被volatile修饰的变量的值,将不会被本地线程缓存,所有对该变量的读写都是直接操作共享内存,从而确保多个线程能正确的处理该变量。

/**
* 双重检查加锁的单例模式
* @author dream
*
*/
public class Singleton {

/**
* 对保存实例的变量添加volitile的修饰
*/
private volatile static Singleton instance = null;
private Singleton(){

}

public static Singleton getInstance(){
//先检查实例是否存在,如果不存在才进入下面的同步块
if(instance == null){
//同步块,线程安全的创建实例
synchronized (Singleton.class) {
//再次检查实例是否存在,如果不存在才真正的创建实例
instance = new Singleton();
}
}
return instance;
}


}

一种更好的单例实现方式

public class Singleton {

/**
* 类级的内部类,也就是静态类的成员式内部类,该内部类的实例与外部类的实例
* 没有绑定关系,而且只有被调用时才会装载,从而实现了延迟加载
* @author dream
*
*/
private static class SingletonHolder{
/**
* 静态初始化器,由JVM来保证线程安全
*/
private static final Singleton instance = new Singleton();
}

/**
* 私有化构造方法
*/
private Singleton(){

}

public static Singleton getInstance(){
return SingletonHolder.instance;
}


}

根据《高效Java第二版》中的说法,单元素的枚举类型已经成为实现Singleton的最佳方法。

package example6;

/**
* 使用枚举来实现单例模式的示例
* @author dream
*
*/
public class Singleton {

/**
* 定义一个枚举的元素,它就代表了Singleton的一个实例
*/
uniqueInstance;

/**
* 示意方法,单例可以有自己的操作
*/
public void singletonOperation(){
//功能树立
}
}

本质

控制实例数量

何时选用单例模式

当需要控制一个类的实例只能有一个,而且客户只能从一个全局访问点访问它时,可以选用单例模式,这些功能恰好是单例模式要解决的问题。
2. 适配器模式:ListView,GridView的Adapter
1). 简介: 不同的数据提供使用一个适配器来想一个相同的客服提供服务
3. 建造者模式:AlertDialog.Builder
1). 简介: 可以分步地构造每一部分.
4. 享元模式:Message.obtainMessage通过Message对象来避免大量的Message对象被频繁的创建和销毁
1). 运用共享技术有效的支持大量细粒度的对象
5. 命令模式: Handler.post后Handler.handlerMessage
1). 简介: 把请求封装成一二对象发送出去,方便定制、排队、取消.
6. 迭代器模式: 如通过Hashtable.elements方法可以得到一个Enumeration,然后通过这个Enumeration访问Hashtable中的数据,而不用关心Hashtable中的数据存放方式
1). 提供一个方法顺序访问数据集合中的所有数据而又不暴露对象的内部表示
7. 备忘录模式:Activity的onSaveInstanceState和onRestoreInstanceState就是通过Bundle这种序列化的数据结构来存储Activity的状态,至于其中存储的数据结构,这两个方法不用关心
1). 简介: 不需要了解对象的内部结构的情况下备份对象的状态,方便以后恢复
8. 观察者模式: 我们可以通过BaseAdapter.registerDataSetObserver和BaseAdapter.unregisterDataSetObserver两方法来向BaseAdater注册、注销一个DataSetObserver。这个过程中,DataSetObserver就是一个观察者,它一旦发现BaseAdapter内部数据有变量,就会通过回调方法DataSetObserver.onChanged和DataSetObserver.onInvalidated来通知DataSetObserver的实现类。事件通知也是观察者模式
1). 简介:一个对象发生改变时,所有信赖于它的对象自动做相应改变。
9. 原型模式:比如我们需要一张Bitmap的几种不同格式:ARGB_8888、RGB_565、ARGB_4444、ALAPHA_8等。那我们就可以先创建一个ARGB_8888的Bitmap作为原型,在它的基础上,通过调用Bitmap.copy(Config)来创建出其它几种格式的Bitmap。另外一个例子就是Java中所有对象都有的一个名字叫clone的方法,已经原型模式的代名词了
1). 简介:在系统中要创建大量的对象,这些对象之间具有几乎完全相同的功能,只是在细节上有一点儿差别。
10. 状态模式:View.onVisibilityChanged方法,就是提供了一个状态模式的实现,允许在View的visibility发生改变时,引发执行onVisibilityChanged方法中的动作。
1). 简介:状态发生改变时,行为改变。
11. 策略模式:
举例:Java.util.List就是定义了一个增(add)、删(remove)、改(set)、查(indexOf)策略,至于实现这个策略的ArrayList、LinkedList等类,只是在具体实现时采用了不同的算法。但因为它们策略一样,不考虑速度的情况下,使用时完全可以互相替换使用。
1). 简介: 定义了一系封装了算法、行为的对象,他们可以相互替换.
12. 调解者模式
简介:一个对象的某个操作需要调用N个对象的M个方法来完成时,把这些调用过程封装起来,就成了一个调解者
举例:如Resource.getDrawable方法的实现逻辑是这样的:创建一个缓存来存放所有已经加载过的,如果getDrawable中传入的id所对应的Drawable以前没有被加载过,那么它就会根据id所对应的资源类型,分别调用XML解析器生成,或者通过读取包中的图片资源文件来创建Drawable。而Resource.getDrawable把涉及到多个对象、多个逻辑的操作封装成一个方法,就实现了一个调解者的角色。
12. 抽象工程模式
DAO与Service的使用


大图片造成的OOM是怎么解决的

1、通过压缩的方式,具体怎么压缩??
直接使用ImageView显示bitmap会占用较多资源,特别是图片较大的时候,可能导致崩溃。
使用BitmapFactory.Options设置inSampleSize, 这样做可以减少对系统资源的要求。
属性值inSampleSize表示缩略图大小为原始图片大小的几分之一,即如果这个值为2,则取出的缩略图的宽和高都是原始图片的1/2,图片大小就为原始大小的1/4。

BitmapFactory.Options bitmapFactoryOptions = new BitmapFactory.Options();
bitmapFactoryOptions.inJustDecodeBounds = true;
bitmapFactoryOptions.inSampleSize = 2;
// 这里一定要将其设置回false,因为之前我们将其设置成了true
// 设置inJustDecodeBounds为true后,decodeFile并不分配空间,即,BitmapFactory解码出来的Bitmap为Null,但可计算出原始图片的长度和宽度
options.inJustDecodeBounds = false;
Bitmap bmp = BitmapFactory.decodeFile(sourceBitmap, options);

2、通过LRU缓存的方式,具体怎么实现的??
指定内存空间,我们自己分分配缓存大小


项目中MVC用到的多吗??都代表什么意思??

目前项目中用的基本上都是MVC 因为MVC模式它是将视图和数据,逻辑代码都剥离了出来,这样做的效果就是便于以后添加功能比较方便,便于维护
M:Model   负责处理数据  比如javaBean,联网处理,
V:View    处理界面展示结果的 XML
C:Controller  控制器  就是起桥梁作用,负责Model,View层数据之间的通信
好处: 便于后期维护和添加新功能
缺点: 它的首要职责是加载应用的布局和初始化用户的界面,并接受来自用户的操作请求,进而做响应.Activty类的职责不断增加,以致变得庞大臃肿.


大概说一下MVP???

M: model提供数据
V: 负责显示
P: 负责逻辑处理


MVC与MVP之前的区别???

View与Model并不直接交互,而是通过与Presenter交互来与Model直接交互
通常View与Presenter是一对一的,但复杂的View可能绑定多个Presenter来处理逻辑,而Controller是基于行为的,并且可以被多个View共享,Controller可以负责决定显示那个View


将一讲你在项目中线程池用的多吗???

将一讲你在项目中对象池用的多吗(听都听不懂)???

ArrayList(集合里面有1~100的数,怎么用2种方法可以使偶数去重)

怎么读取N个大文件效率怎么最高(思路:创建多个线程);

反射(你在项目中用的多吗,具体谈谈)

1). fromName(全类名);(读取配置文件)
2). 类名.Class();(当做静态方法的锁对象)
3). 对象名.getClass();(判断是不是同一个字节码对象)


Android属性动画怎么获取变化中的ARGB值(利用ValuesAnimontor)

通过属性动画中的值动画添加一个监听器通过监听器中的对象名获取变化中的值


事件传递机制(将一讲事件处理,如果都不要事件,最后事件都被谁消费了)

ListView Item上面有一个Button,当我点击ListView的时候,Button把事件抢走了,这怎么处理啊?

购物车中增加物品数量逻辑怎么实现

getMeasuredWidth与getWidth区别

1). getMeasuredWidth方法获得的值是setMeasuredDimension方法设置的值,它的值在measure方法运行后就会确定
2). getWidth方法获得是layout方法中传递的四个参数中的mRight-mLeft,它的值是在layout方法运行后确定的
3). 一般情况下在onLayout方法中使用getMeasuredWidth方法,而在除onLayout方法之外的地方用getWidth方法。


Service中的onStartCommand和onStart()方法有什么区别???

1). 在Android API 2.0 之后 实现onStart等于实现了onStartCommand()方法;
2). 在AndroidAPI  2.0之后onStart()被onStartCommand()方法取代了;
3). 无论何时, 都会先调用onStartCommand(),在调用onStart()。
注意:onStartCommand()方法必须返回一个整数,这个整数是一个描述了在系统的杀死事件中,系统应该如何继续这个服务的值(虽然你能够修改这个值,但是IntentService处理还是为你提供了默认实现)。从onStartCommand()方法中返回的值必须是以下常量:
1. START_NOT_STICKY
如果系统在onStartCommand()方法返回之后杀死这个服务,那么直到接受到新的Intent对象,这个服务才会被重新创建。这是最安全的选项,用来避免在不需要的时候运行你的服务。
2. START_STICKY
如果系统在onStartCommand()返回后杀死了这个服务,系统就会重新创建这个服务并且调用onStartCommand()方法,但是它不会重新传递最后的Intent对象,系统会用一个null的Intent对象来调用onStartCommand()方法,在这个情况下,除非有一些被发送的Intent对象在等待启动服务。这适用于不执行命令的媒体播放器(或类似的服务),它只是无限期的运行着并等待工作的到来。
3. START_REDELIVER_INTENT
如果系统在onStartCommand()方法返回后,系统就会重新创建了这个服务,并且用发送给这个服务的最后的Intent对象调用了onStartCommand()方法。任意等待中的Intent对象会依次被发送。这适用于那些应该立即恢复正在执行的工作的服务,如下载文件。


Http协议

协议就是字段和格式描述的文档
1). 字段
帮助辨识数据的含义
2). 格式 : 帮助将数据归类
JSON : 数据格式简单,数据精简,节约数据流量
XML  : 格式良好,复杂,耗费流量但是扩展性好


TCP/IP协议

IP: 就是每台电脑上的IP地址,端口用于查找电脑运行的应用;
TCP:用于传输数据的
TCP:面向连接,三次握手,是稳定的传输协议
UDP:面向无连接,数据不安全,传输的数据有可能丢失


事件分发机制

1). 点击屏幕的时候触发Activity的onTouch()事件,当Activity接收到触摸事件的时候,将遍历子View进行Down事件分发ViewGroup可以看做是递归的,分发事件的目的就是要看是哪个子View需要Down事件,如果需要就在子View的onTouchEvent()方法中放回true,事件将有它消费,不在进行分发;
2). 当ViewGroup中所有子View都不需要Down事件的话,最终事件会调用父类View的dispatchTouchEvent(),在所有子View都不处理的情况下,会调用Activity本身的onTouch()方法;


2016/9/29

onClick()怎么处理??

1). btn1.setOnClickListener(new OnClickListener())
2). Xml布局中定义"onClick"
3). 让当前类实现onClickListener();
4). btn_call.setOnClickListener(new MyOnClickListener());


OOM与泄露区别??leakcanary

1.内存溢出 out of memory
是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出。
2.内存泄露 memory leak
是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。
3.二者的联系
内存泄露最终会导致内存溢出

内存溢出(00M)
内存溢出是指当对象的内存占用已经超出内存的控件大小,这时未经处理的异常就会抛出
.比如常见的内存溢出情况有: Bitmap过来;引用没有释放;资源对象没有关闭
简单而言,内存溢出就是要求分配的内存超出了系统能给的,系统不能满足需求,于是产生溢出
1). 长期保持某些资源Context的引用,垃圾回收器就无法回收它
2). Android中常见就是Activity被应用在调用finish之后却没有释放,第二次打开activity又重新创建
3). Android的每个应用程序都会使用一个专有的虚拟机来运行,他是由Zygote服务进程孵化出来的,也就是说每个应用程序都是在属于自己的进程中运行的.
4). 占用内存较多的对象
保存了多个耗用内存过大的对象或加载单个超大的图片,造成内存超出限制.

内存泄露(memory Leak)----memory leak 会最终导致oom(可以用heap来观察)
有些对象只有有限的生命周期.当他们的任务完成之后,他们将被垃圾回收,如果对象还被一系列的引用,他就会导致内存泄露.随着泄露的累积,app将消耗完内存.
1). 资源对象没有关闭(File,Cursor,SqLite)
2). 使用Adapter时,没有使用缓存
3). 没有即时调用recycle()释放不在使用bitmap
4). 使用application的context替代activity的context
5). 广播注册没有取消
6). handler应该声明为静态对象,并在其内部类中保存一个对外部类的弱引用;


说说三级缓存具体怎么实现???

1). 内存(我们自己指定缓存的大小和有效时间)
2). 本地(SD卡或者getDirChche())
3). 网络(请求网络获取数据)


内存优化???

单列
listView 复用
Bitmap压缩
三级缓存
内存检测
heap
adb
ddms
Memory Analyzer(MAT)


自我介绍???

开启广播的方式,区别??

清单文件中注册(生命周期是最长的)
代码中注册(随着Activity销毁而销毁)
有序广播  可以终止广播
无序广播  在规定的时候段定时播放


之前薪资和现在薪资,为什么要那么多???

根据目前北京的市场,毕竟是3年的工作经验


现在住在那 , 做多少路车过来???

海淀,出门提前把路线规划好


回去了解下直播???

即时通讯

1. 申请主应用的APP证明.
2. 注册成功之后,登录后台:填写应用包名,应用名等相关信息
3. 点击确认,进行申请.
这样appauth就申请成功了,点击后面的复制.粘贴到项目中的Androidmanifest文件中即可
4. 配权限
5. 导入SDK


你该怎么提升自己

看博客,,逛GitHub,自己写总结


Android中内存优化

答:android 内存泄露容易导致内存溢出,又称为 OOM。
Android 内存优化策略:
1)在循环内尽量不要使用局部变量
2)不用的对象即时释放,即指向 NULL
3)数据库的 cursor 即时关闭。
4)构造 adapter 时使用缓存 contentview
5)调用 registerReceiver()后在对应的生命周期方法中调用 unregisterReceiver()
6)即时关闭 InputStream/OutputStream。
7) android 系统给图片分配的内存只有 8M, 图片尽量使用软引用, 较大图片可通过 BitmapFactory缩放后再使用,并及时 recycle
8)尽量避免 static 成员变量引用资源耗费过多的实例。


说说对象池???

对象池使用的基本思路是:将用过的对象保存起来,等下一次需要这种对象的时候,再拿出来重复使用,从而在一定程度上减少频繁创建对象所造成的开销。 并非所有对象都适合拿来池化――因为维护对象池也要造成一定开销。对生成时开销不大的对象进行池化,反而可能会出现“维护对象池的开销”大于“生成新对象的开销”,从而使性能降低的情况。但是对于生成时开销可观的对象,池化技术就是提高性能的有效策略了


线程池???

线程池的基本思想还是一种对象池的思想,开辟一块内存空间,里面存放了众多(未死亡)的线程,池中线程执行调度由池管理器来处理。当有线程任务时,从池中取一个,执行完成后线程对象归池,这样可以避免反复创建线程对象所带来的性能开销,节省了系统的资源。
比如:一个应用要和网络打交道,有很多步骤需要访问网络,为了不阻塞主线程,每个步骤都创建个线程,在线程中和网络交互,用线程池就变的简单,线程池是对线程的一种封装,让线程用起来更加简便,只需要创一个线程池,把这些步骤像任务一样放进线程池,在程序销毁时只要调用线程池的销毁函数即可。
java提供了ExecutorService和Executors类,我们可以应用它去建立线程池。


如何不让外界应用接收到你的广播???

LocalBroadcastManager是Android Support包提供了一个工具,是用来在同一个应用内的不同组件间发送Broadcast的。
使用LocalBroadcastManager有如下好处:
发送的广播只会在自己App内传播,不会泄露给其他App,确保隐私数据不会泄露
其他App也无法向你的App发送该广播,不用担心其他App会来搞破坏
比系统全局广播更加高效。


Android中的Parcelable???

1). 实现Parcelable就是为来进行序列化,那么,为什么要序列化??
一. 永久性保存对象,保存对象的字节序列到本地文件中;
二. 通过序列化对象在网络中传递对象;
三. 通过序列化在进程间传递对象;
2). 实现序列化的方法
Android中实现序列化有2个选择: 一是实现Serializable接口(是Java本身就支持的),二是实现Parcelable接口()
是Android特有的功能,效率比实现Serializable接口高效,可用于Intent数据传递,也可以用于进程间通讯(IPC)Serializable接口非常简单,声明一下就可以了,而实现Parcelable接口稍微复杂一些,但效率更高,推荐用这种性能
注: Android中Intent传递对象有两种方法:一是Bundle.putSerializable(Key,Object),另一种是Bundle.putParcelable(Key,Object)。当然这些Object是有一定的条件的,前者是实现了Serializable接口,而后者是实现了Parcelable接口。
3). 选择序列化方法的原则
一. 在使用内存的时候,Parcelable比Serializable性能高,所以推荐使用Parcelable;
二. Serializable在序列化的时候会产生大量的临时变量,从而引起频繁的GC;
三. Parcelable不能使用在要将数据存储在磁盘上的情况,因为Parcelable不能很好的保证数据的持续性在外界有变化的情况下。尽管Serializable效率低点,但此时还是建议使用Serializable ;
4). 应用场景
需要在多个部件(Activity或Service)之间通过Intent传递一些数据,简单类型(如:数字、字符串)的可以直接放入Intent。复杂类型必须实现Parcelable接口;
5). Parcelable接口定义

public interface Parcelable


{

//内容描述接口,基本不用管

public int describeContents();

//写入接口函数,打包

public void writeToParcel(Parcel dest, int flags);

//读取接口,目的是要从Parcel中构造一个实现了Parcelable的类的实例处理。因为实现类在这里还是不可知的,所以需要用到模板的方式,继承类名通过模板参数传入

//为了能够实现模板参数的传入,这里定义Creator嵌入接口,内含两个接口函数分别返回单个和多个继承类实例

public interface Creator

{

public T createFromParcel(Parcel source);

public T[] newArray(int size);

}

}

6). 实现Parcelable步骤
1). implements Parcelable
2). 重写writeToParcel方法,将你的对象序列化为一个Parcel对象,即:将类的数据写入外部提供的Parcel中,打包需要传递的数据到Parcel容器保存,以便从 Parcel容器获取数据
3). 重写describeContents方法,内容接口描述,默认返回0就可以
4). 实例化静态内部对象CREATOR实现接口Parcelable.Creator
`public static final Parcelable.Creator<T> CREATOR`
`注`:其中public static final一个都不能少,内部对象CREATOR的名称也不能改变,必须全部大写。需重写本接口中的两个方法:createFromParcel(Parcel in) 实现从Parcel容器中读取传递数据值,封装成Parcelable对象返回逻辑层,newArray(int size) 创建一个类型为T,长度为size的数组,仅一句话即可(return new T[size]),供外部类反序列化本类数组使用。
`简而言之`:通过writeToParcel将你的对象映射成Parcel对象,再通过createFromParcel将Parcel对象映射成你的对象。也可以将Parcel看成是一个流,通过writeToParcel把对象写到流里面,在通过createFromParcel从流里读取对象,只不过这个过程需要你来实现,因此写的顺序和读的顺序必须一致。
代码如下:
`public class MyParcelable implements Parcelable


{

private int mData;

public int describeContents()
{
return 0;
}

public void writeToParcel(Parcel out, int flags)
{
out.writeInt(mData);
}

public static final Parcelable.Creator<MyParcelable> CREATOR = new Parcelable.Creator<MyParcelable>()
{
public MyParcelable createFromParcel(Parcel in)
{
return new MyParcelable(in);
}

public MyParcelable[] newArray(int size)
{
return new MyParcelable[size];
}
};

private MyParcelable(Parcel in)
{
mData = in.readInt();
}


}`

8). Serializable实现与Parcelabel实现的区别

1). Serializable的实现,只需要implements Serializable 即可。这只是给对象打了一个标记,系统会自动将其序列化

2). Parcelabel的实现,不仅需要implements Parcelabel,还需要在类中添加一个静态成员变量CREATOR,这个变量需要实现 Parcelable.Creator 接口

如何高效的关闭打开多个activity的应用

sp的提交方式

关于RecyclerView的特点,与listview相比的优点,点击事件的实现。

关于线程池

AsynTask的内部实现 线程池及Handler的维护

关于OOM的认识

自定义控件的流程

观察者模式

——————————————————————-JAVA中多线程难点—————————————————————————-

####Java中多线程同步是什么???

在多线程程序下,同步能控制对共享资源的访问。如果没有同步,当一个 Java 线程在修改一个共享变量时,另外一个线程正在使用或者更新同一个变量,这样容易导致程序出现错误的结果。


解释实现多线程的几种方法?

1). Java 线程可以实现 Runnable 接口或者继承 Thread 类来实现,当你打算多重继承时,优先选择实现 Runnable


Thread.start ()与 Thread.run ()有什么区别?

1). Thread.start ()方法(native)启动线程,使之进入就绪状态,当 cpu 分配时间该线程时,由 JVM 调度执行 run ()方法。


为什么需要 run ()和 start ()方法,我们可以只用 run ()方法来完成任务吗

1). 我们需要 run ()&start ()这两个方法是因为 JVM 创建一个单独的线程不同于普通方法的调用,所以这项工作由线程的 start 方法来完成,start 由本地方法实现,需要显示地被调用,使用这俩个方法的另外一个好处是任何一个对象都可以作为线程运行,只要实现了 Runnable 接口,这就避免因继承了 Thread 类而造成的 Java 的多继承问题


什么是 ThreadLocal 类,怎么使用它

ThreadLocal 是一个线程级别的局部变量,并非“本地线程”。ThreadLocal 为每个使用该变量的线程提供了一个独立的变量副本,每个线程修改副本时不影响其它线程对象的副本(译者注).

下面是线程局部变量(ThreadLocal variables)的关键点:
一个线程局部变量(ThreadLocal variables)为每个线程方便地提供了一个单独的变量。
ThreadLocal 实例通常作为静态的私有的(private static)字段出现在一个类中,这个类用来关联一个线程。
当多个线程访问 ThreadLocal 实例时,每个线程维护 ThreadLocal 提供的独立的变量副本。
常用的使用可在 DAO 模式中见到,当 DAO 类作为一个单例类时,数据库链接(connection)被每一个线程独立的维护,互不影响。(基于线程的单例)


什么时候抛出 InvalidMonitorStateException 异常,为什么?

调用 wait ()/notify ()/notifyAll ()中的任何一个方法时,如果当前线程没有获得该对象的锁,那么就会抛出 IllegalMonitorStateException 的异常(也就是说程序在没有执行对象的任何同步块或者同步方法时,仍然尝试调用 wait ()/notify ()/notifyAll ()时)。由于该异常是 RuntimeExcpetion 的子类,所以该异常不一定要捕获(尽管你可以捕获只要你愿意).作为 RuntimeException,此类异常不会在 wait (),notify (),notifyAll ()的方法签名提及


Sleep ()、suspend ()和 wait ()之间有什么区别

Thread.sleep ()使当前线程在指定的时间处于“非运行”(Not Runnable)状态。线程一直持有对象的监视器。比如一个线程当前在一个同步块或同步方法中,其它线程不能进入该块或方法中。如果另一线程调用了 interrupt ()方法,它将唤醒那个“睡眠的”线程。

注意:sleep ()是一个静态方法。这意味着只对当前线程有效,一个常见的错误是调用t.sleep (),(这里的t是一个不同于当前线程的线程)。即便是执行t.sleep (),也是当前线程进入睡眠,而不是t线程。t.suspend ()是过时的方法,使用 suspend ()导致线程进入停滞状态,该线程会一直持有对象的监视器,suspend ()容易引起死锁问题。

object.wait ()使当前线程出于“不可运行”状态,和 sleep ()不同的是 wait 是 object 的方法而不是 thread。调用 object.wait ()时,线程先要获取这个对象的对象锁,当前线程必须在锁对象保持同步,把当前线程添加到等待队列中,随后另一线程可以同步同一个对象锁来调用 object.notify (),这样将唤醒原来等待中的线程,然后释放该锁。基本上 wait ()/notify ()与 sleep ()/interrupt ()类似,只是前者需要获取对象锁


在静态方法上使用同步时会发生什么事

同步静态方法时会获取该类的“Class”对象,所以当一个线程进入同步的静态方法中时,线程监视器获取类本身的对象锁,其它线程不能进入这个类的任何静态同步方法。它不像实例方法,因为多个线程可以同时访问不同实例同步实例方法


当一个同步方法已经执行,线程能够调用对象上的非同步实例方法吗?

可以,一个非同步方法总是可以被调用而不会有任何问题。实际上,Java 没有为非同步方法做任何检查,锁对象仅仅在同步方法或者同步代码块中检查。如果一个方法没有声明为同步,即使你在使用共享数据 Java 照样会调用,而不会做检查是否安全,所以在这种情况下要特别小心。一个方法是否声明为同步取决于临界区访问(critial section access),如果方法不访问临界区(共享资源或者数据结构)就没必要声明为同步的。

下面有一个示例说明:Common 类有两个方法 synchronizedMethod1()和 method1(),MyThread 类在独立的线程中调用这两个方法


在一个对象上两个线程可以调用两个不同的同步实例方法吗

不能,因为一个对象已经同步了实例方法,线程获取了对象的对象锁。所以只有执行完该方法释放对象锁后才能执行其它同步方法。


什么是死锁

死锁就是两个或两个以上的线程被无限的阻塞,线程之间相互等待所需资源。这种情况可能发生在当两个线程尝试获取其它资源的锁,而每个线程又陷入无限等待其它资源锁的释放,除非一个用户进程被终止。就 JavaAPI 而言,线程死锁可能发生在一下情况。

当两个线程相互调用 Thread.join ()
当两个线程使用嵌套的同步块,一个线程占用了另外一个线程必需的锁,互相等待时被阻塞就有可能出现死锁。


什么是线程饿死,什么是活锁

线程饿死和活锁虽然不想是死锁一样的常见问题,但是对于并发编程的设计者来说就像一次邂逅一样。

当所有线程阻塞,或者由于需要的资源无效而不能处理,不存在非阻塞线程使资源可用。JavaAPI 中线程活锁可能发生在以下情形:

当所有线程在程序中执行 Object.wait (0),参数为 0 的 wait 方法。程序将发生活锁直到在相应的对象上有线程调用 Object.notify ()或者 Object.notifyAll ()。
当所有线程卡在无限循环中


————————————————————–JAVA基础经典面试题————————————————————————–

九种基本数据类型的大小,以及他们的封装类。

boolean  (8位但是只能为true false)  Boolean
byte      8       Byte
char      16       Character
short     16        Short
int       32       Integer
long      64       Long
float     32       Float
double    64       Double
void                Void


Switch能否用string做参数?

java7 以前不行是用转换为枚举实现,现在直接可以


equals与==的区别。

equals检查内容是否一致
==检查内存存储的地址是否一致


Object有哪些公用方法?

hashCode();wait();notify();equals();getClass();toString();  clone();finalize();


Java的四种引用,强弱软虚,用到的场景。

强引用:我们一般用的都是强引用,不会被回收
软引用:内存敏感的高速缓存,当jvm 报out of memery时回收
弱引用:gc时必须被回收
虚引用:gc时紧收到消息,不能做任何操作


Hashcode的作用。

用于比较两个对象是否相同,比如set的相同就是用hashcode


ArrayList、LinkedList、Vector的区别。

都是数组实现list接口,
vector是连续线程安全,
ArrayList是连续内存,查找方便,
LinkedList是链表结构,增删方便


String、StringBuffer与StringBuilder的区别。

String是字符串常量,不可改变,其余的是字符串变量,主要用于字符串的修改,
buffer线程安全,
builder非线程安全


Map、Set、List、Queue、Stack的特点与用法。

键值对:hashmap,hashtable,weakhashmap,sortedmap
不重复集合:sortedset,hashset
有序数列:linkedList,arraylist,vector
队列:先进先出  栈:先进后出


HashMap和HashTable的区别。

hashtable线程安全,不接受键值对为nul


HashMap和ConcurrentHashMap的区别,HashMap的底层源码。

ConcurrentHashMap通过分段实现线程安全


TreeMap、HashMap、LindedHashMap的区别。

Collection包结构,与Collections的区别。

Collections,是一个工具类,比如:Collections.sort(list)


try catch finally,try里有return,finally还执行么?

return后还执行,但是无法修改已经返回的内容


Excption与Error包结构。OOM你遇到过哪些情况,SOF你遇到过哪些情况。

Java面向对象的三个特征与含义。

封装:方法与属性封装
继承:节省代码,扩展
多态:父类引用指向不同的实例,重写,重载


Override和Overload的含义去区别。

重写:子类中有一个父类中名字参数一样的函数,异常变少,访问权限变大
重载:同类当中参数列表不一致


Interface与abstract类的区别。

一个是类,一个是接口
接口内部变量必须public static final  可以有实现的方法,接口全部没实现  访问权限:接口只有public和protected  多继承、构造方法


Static class 与non static class的区别。

java多态的实现原理。

父类引用指向不同的实例,重写,重载


实现多线程的两种方法:Thread与Runable。

Thread与Runable。
继承类,实现接口


线程同步的方法:sychronized、lock、reentrantLock等。

sychronized:修饰的方法,块一次只有一个线程可以访问,其他的阻塞
lock:一个接口,用于try的finally中可以主动的释放锁,trylock方法可以指定等待时间,灵活
reentrantLock:lock的实现类


锁的等级:方法锁、对象锁、类锁。

对象锁:对象的方法,代码块上锁了,获取对象锁才能访问
方法锁:方法上锁
类锁:static方法上锁


写出生产者消费者模式。

生产者(入队) 缓冲区(队列管理) 消费者(出队)
优点:解耦  并发  闲忙不均


ThreadLocal的设计理念与作用。

多线程多实例的数据传递问题,底层有个ThreadlLocalMap来管理


ThreadPool用法与优势。

newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。


Concurrent包里的其他东西:ArrayBlockingQueue、CountDownLatch等等。

wait()和sleep()的区别。

sleep没有放弃对象锁,wait放弃了,thread和object,需要notify唤醒。


foreach与正常for循环效率对比。

简便了编程与不会越界,但是只能用于遍历


Java IO与NIO。

IO                NIO
面向流            面向缓冲
阻塞IO            非阻塞IO
无                选择器


反射的作用于原理。

泛型常用特点,List能否转为List。

灵活变换参数类型,可以


解析XML的几种方式的原理与特点:DOM、SAX、PULL。

DOM:获取整个DOM树,便于节点操作,
SAX:一边解析,一边处理数据,必须自己维护父子关系
JDOM:比较适合比较小的,不需要实时处理的
DOM4J:可移植性差


Java与C++对比。

java的完全封装,类外无函数,万物皆对象  gc,指针,接口,多继承的实现


Java1.7与1.8新特性。

java1.7:switch支持String;集合类的支持,安全加减乘除;char的equals操作
java1.8:Lambda 表达式,接口支持


设计模式:单例、工厂、适配器、责任链、观察者等等。

JNI的使用。

System.LoadLibrary("");//引入库文件
public native static void set(int i); //native跨语言调用
testdll test = new testdll(); //申明方式
test.set(10);调用


————————————————————–JVM 经典面试题————————————————————————————-

内存模型以及分区,需要详细到每个区放什么。

heap:对象实例  method
area:常量池,变量信息,方法信息
stack:方法的调用出入
program counter:程序偏移量
native method area:本地方法


堆里面的分区:

Eden,survival from to,老年代,各自的特点。


对象创建方法,对象的内存分配,对象的访问定位。

GC的两种判定方法:

引用计数与引用链。
引用计数为0;gc root不可达


GC的三种收集方法:标记清除、标记整理、复制算法的原理与特点,分别用在什么地方,如果让你优化收集方法,有什么思路?

先标记后清除,内存碎片  标记整理,先标记后移动内存,开销大  复制:等分,一块使用,一块清理,内存减半


GC收集器有哪些

CMS收集器与G1收集器的特点


Minor GC与Full GC分别在什么时候发生?

几种常用的内存调试工具:

jmap、jstack、jconsole。


类加载的五个过程:

加载、验证、准备、解析、初始化。


双亲委派模型:

Bootstrap ClassLoader、Extension ClassLoader、ApplicationClassLoader。


分派

静态分派与动态分派


————————————————————–操作系统经典面试题———————————————————————————-

进程和线程的区别

CPU调度的基本单位;程序资源管理分配的单位


死锁的必要条件,怎么处理死锁。

互斥条件(Mutual exclusion)   :资源不能被共享,只能由一个进程使用。
请求与保持条件(Hold and wait) :已经得到资源的进程可以再次申请新的资源。
非剥夺条件(No pre-emption)    :已经分配的资源不能从相应的进程中被强制地剥夺。
循环等待条件(Circular wait)   : 系统中若干进程组成环路,该环路中每个进程都在等待相邻进  程正占用的资源。   合理动态分配,检查并恢复,打破死锁条件


Window内存管理方式:段存储,页存储,段页存储。

按页大小分页分隔虚拟内存,外碎片没有,内碎片不会大于页的大小
按函数或内容分段,可以分开编写等独立
段页式:先分段再分页,有点都有开销变大


进程的几种状态。

IPC几种通信方式。

1.管道中还有命名管道和非命名管道(即匿名管道)之分,非命名管道(即匿名管道)只能用于父子进 程通讯,命名管道可用于非父子进程,命名管道就是FIFO,管道是先进先出的通讯方式
2.消息队列是用于两个进程之间的通讯,首先在一个进程中创建一个消息队列,然后再往消息队列 中写数据,而另一个进程则从那个消息队列中取数据。需要注意的是,消息队列是用创建文件的方 式建立的,如果一个进程向某个消息队列中写入了数据之后,另一个进程并没有取出数据,即使向 消息队列中写数据的进程已经结束,保存在消息队列中的数据并没有消失,也就是说下次再从这个 消息队列读数据的时候,就是上次的数据!!!!
3.信号量,它与WINDOWS下的信号量是一样的,所以就不用多说了
4.共享内存,类似于WINDOWS下的DLL中的共享变量,但LINUX下的共享内存区不需要像DLL这样的东 西,只要首先创建一个共享内存区,其它进程按照一定的步骤就能访问到这个共享内存区中的数据 ,当然可读可写


以上几种方式的比较:

1.管道:速度慢,容量有限,只有父子进程能通讯

2.FIFO:任何进程间都能通讯,但速度慢

3.消息队列:容量受到系统限制,且要注意第一次读的时候,要考虑上一次没有读完数据的问题

4.信号量:不能传递复杂消息,只能用来同步

5.共享内存区:能够很容易控制容量,速度快,但要保持同步,比如一个进程在写的时候,另一个 进程要注意读写的问题,相当于线程中的线程安全,当然,共享内存区同样可以用作线程间通讯, 不过没这个必要,线程间本来就已经共享了同一进程内的一块内存

什么是虚拟内存

虚拟的一段连续的内存空间,通常是分隔的物理内存碎片


虚拟地址、逻辑地址、线性地址、物理地址的区别。

————————————————————– TCP/IP 经典面试题 ——————————————————————————-

OSI与TCP/IP各层的结构与功能,都有哪些协议

物理层,数据链路层,网络层,运输层,会话层,表示层,应用层


TCP与UDP的区别。

面向连接,可靠(掉包乱序),快慢,数据量大小的问题


TCP报文结构。

TCP的三次握手与四次挥手过程,各个状态名称与含义,TIMEWAIT的作用。

SYN=1,seg=x    SYN=1,ACK=1,ack=x+1,seq=y  ACK=1,seq=x+1,ack=y+1
FIN ACK:FIN ACK  TIMEWAIT重发最后丢失的ACK包


TCP拥塞控制

“慢启动”“拥塞避免”“快速重传 ”“快速恢复”


TCP滑动窗口与回退N针协议

Http的报文结构。

请求行 首部 主体


Http的状态码含义。

1.消息,被接受需处理
2.成功
3.重定向
4.请求错误
5.服务器错误


Http request的几种类型。

post改,get查,delete删,put增  位置url请求行  实体键值对  数据量的大小


Http1.1和Http1.0的区别

1.Persistent Connection(持久连接)   在HTTP1.0中,每对Request/Response都使用一个新的连接。   HTTP 1.1则支持Persistent Connection, 并且默认使用persistent connection.  2.HTTP1.1在Request消息头里头多了一个Host域
3.100 (Continue) Status      100 (Continue) 状态代码的使用,允许客户端在发request消息body之前先用request    header试探一下server,看server要不要接收request body,再决定要不要发request    body。            客户端在Request头部中包含   Expect: 100-continue   Server看到之后呢如果回100 (Continue) 这个状态代码,客户端就继续发request body
4.新增了些状态码  5.HTTP1.1增加了OPTIONS, PUT, DELETE, TRACE, CONNECT这些Request方法


Http怎么处理长连接

http keep-alive,1.1版本默认长连接


Cookie与Session的作用于原理。

浏览器端的cookie和服务端的session会话


电脑上访问一个网页,整个过程是怎么样的

DNS、HTTP、TCP、OSPF(开放式最短路径优先)、IP(网络之间包的转换)、ARP(数据链路层,IP转mac输入要网址 ->DNS通过浏览器中域名查找IP地址->浏览器给web服务器发送一个  HTTP请求(get,post使用tcp协议)->重定向地址(qq.com变为www.qq.com)->服务器“处理”请求->  服务器发回一个HTML响应->浏览器开始显示HTML->浏览器发送获取嵌入在HTML中的对象


Ping的整个过程。ICMP报文是什么。

同一网段:ARP协议查询mac地址(交换机学习IPmac),通过mac,IP发送ICMP报文要求回复报文
不同网段:查询路由器mac,通过路由器广播得到目标mac,同理


C/S模式下使用socket通信,几个关键函数

server:socket bind listen accept read write close
client:socket connect write read close


IP地址分类。

A:0 +7网络号+24主机号   255.0.0.0
B:10 +14网络号+16主机号 255.255.0.0
C:110 +21网络号+8主机号 255.255.255.0
D:1110   E:11110


路由器与交换机区别。

IP,路由选择   交换机主要是IP与mac转化


———————————————————数据结构与算法经典面试题———————————————————————————-

链表与数组。

队列和栈,出栈与入栈。

链表的删除、插入、反向。

字符串操作。

Hash表的hash函数,冲突解决方法有哪些。

乘法散列法,除法散列法等
开放定址法(迭代算法),
链地址法,再哈希(不同的算法)等


各种排序:

冒泡、选择、插入、希尔、归并、快排、堆排、桶排、基数的原理、平均时间复杂度、最坏时间复杂度、空间复杂度、是否稳定。


快排的partition函数与归并的Merge函数。

对冒泡与快排的改进。

二分查找,与变种二分查找。

二叉树、B+树、AVL树、红黑树、哈夫曼树。

二叉树的前中后续遍历:递归与非递归写法,层序遍历算法。

图的BFS与DFS算法,最小生成树prim算法与最短路径Dijkstra算法。

KMP算法。

排列组合问题。

动态规划、贪心算法、分治算法。(一般不会问到)

大数据处理:类似10亿条数据找出最大的1000个数………等等

————————————————————–Android经典面试题———————————————————————————-

GC:

引用计数法:缺点是无法处理循环引用问题
标记-清除法:标记所有从根结点开始的可达对象,缺点是会造成内存空间不连续,不连续的内存空间的工作效率低于连续的内存空间,不容易分配内存
复制算法:将内存空间分成两块,每次将正在使用的内存中存活对象复制到未使用的内存块中,之后清除正在使用的内存块。算法效率高,但是代价是系统内存折半。适用于新生代(存活对象少,垃圾对象多)
标记-压缩算法:标记-清除的改进,清除未标记的对象时还将所有的存活对象压缩到内存的一端,之后,清理边界所有空间既避免碎片产生,又不需要两块同样大小的内存快,性价比高。适用于老年代。
分代


Activity与Fragment的生命周期。

Acitivty的四中启动模式与特点。

Activity缓存方法。

Service的生命周期,两种启动方法,有什么区别。

怎么保证service不被杀死。

广播的两种注册方法,有什么区别。

Intent的使用方法,可以传递哪些数据类型。

ContentProvider使用方法。

Thread、AsycTask、IntentService的使用场景与特点。

五种布局: FrameLayout 、 LinearLayout 、 AbsoluteLayout 、 RelativeLayout 、TableLayout 各自特点及绘制效率对比。

Android的数据存储形式。

Sqlite的基本操作。

Android中的MVC模式。

Merge、ViewStub的作用。

Json有什么优劣势。

动画有哪三类,各有什么特点?

Handler、Loop消息队列模型,各部分的作用。

怎样退出终止App。

Asset目录与res目录的区别。

Android怎么加速启动Activity。

Android内存优化方法:ListView优化,及时关闭资源,图片缓存等等。

Android中弱引用与软引用的应用场景。

Bitmap的四中属性,与每种属性队形的大小。

View与View Group分类。自定义View过程:onMeasure()、onLayout()、onDraw()。

Touch事件分发机制。

Android长连接,怎么处理心跳机制。

Zygote的启动过程。

Android IPC:Binder原理。

你用过什么框架,是否看过源码,是否知道底层原理。

Android5.0、6.0新特性。

请解释下在单线程模型中Message,Handler,Message Queue,Looper之间的关系。

拿主线程来说,主线程启动时会调用Looper.prepare()方法,会初始化一个Looper,放入Threadlocal中,接着调用Looper.loop()不断遍历Message Queue,  Handler的创建依赖与当前线程中的Looper,如果当前线程没有Looper则必须调用Looper.prepare()。Handler , sendMessage到MessageQueue,Looper不断 从MessageQueue中取出消息,回调handleMessage方法。


如果有个100M大的文件,需要上传至服务器中,而服务器form表单最大只能上传2M,可以用什么方法。

这个问题不是很明确我觉得,首先来说使用http协议上传数据,特别在android下,跟form没什么关系。传统的在web中,在form中写文件上传,其实浏览器所做 的就是将我们的数据进行解析组拼成字符串,以流的方式发送到服务器,且上传文件用的都是POST方式,POST方式对大小没什么限制。  回到题目,可以说假设每次真的只能上传2M,那么可能我们只能把文件截断,然后分别上传了


内存溢出和内存泄漏有什么区别?何时会产生内存泄漏?内存优化有哪些方法?

内存溢出通俗理解就是软件(应用)运行需要的内存,超出了它可用的最大内存。 内存泄漏就是我们对某一内存空间的使用,使用完成后没有释放。  内存优化:Android中容易内存溢出的部分,就是图片的加载,我们可以使用图片的压缩加上使用LruCache缓存的目的来控制图片所能够使用的内存。  还有对于比较耗资源的对象及时的关闭,例如Database Conn , 各种传感器 , Service 等等。


AsyncTask使用在哪些场景?它的缺陷是什么?如何解决?

AsyncTask 运用的场景就是我们需要进行一些耗时的操作,耗时操作完成后更新主线程,或者在操作过程中对主线程的UI进行更新。  缺陷:AsyncTask中维护着一个长度为128的线程池,同时可以执行5个工作线程,还有一个缓冲队列,当线程池中已有128个线程,缓冲队列已满时,如果 此时向线程提交任务,将会抛出RejectedExecutionException。  解决:由一个控制线程来处理AsyncTask的调用判断线程池是否满了,如果满了则线程睡眠否则请求AsyncTask继续处理。


assest文件夹里放文件,对于文件的大小有没有限制?

assets目录更像一个附录类型的目录,Android不会为这个目录中的文件生成ID并保存在R类当中,因此它与Android中的一些类和方法兼容度更低。  同时,由于你需要一个字符串路径来获取这个目录下的文件描述符,访问的速度会更慢。但是把一些文件放在这个目录下会使一些操作更加方便,  比方说拷贝一个数据库文件到系统内存中。要注意的是,你无法在Android XML文件中引用到assets目录下的文件,只能通过AssetManager来访问  这些文件。数据库文件和游戏数据等放在这个目录下是比较合适的。另外,网上关于assets和raw的资料都千篇一律了,因此关于这两者中单个文件  大小不能超过1M的**错误**描述也在传播,即如果读取超过1M的文件会报"Data exceeds UNCOMPRESS_DATA_MAX (1314625 vs 1048576)"的  IOException,还引申出种种解决方案。个人认为不应该有这样的限制,为了验证这个说法写了个Demo,发现将近5M的压缩包在assets和raw中  都能正常访问,因此在这里纠正一下,理论上只要打包不超过Android APK 50M大小的限制都是没有问题的。当然了,不排除是Android很早期的
时候因为设备硬件原因aapt在编译的时候对这两个文件夹大小做出了限制,如果是这样,较新版的ADT应该不会出现这种情况。 来自:http://my.eoe.cn/futurexiong/archive/5350.html


启动一个程序,可以主界面点击图标进入,也可以从一个程序中跳转过去,二者有什么区别?

是因为启动程序(主界面也是一个app),发现了在这个程序中存在一个设置为<category android:name="android.intent.category.LAUNCHER" />的activity,  所以这个launcher会把icon提出来,放在主界面上。当用户点击icon的时候,发出一个Intent: Intent intent =  mActivity.getPackageManager().getLaunchIntentForPackage(packageName); mActivity.startActivity(intent);     跳过去可以跳到任意允许的页面,如一个程序可以下载,那么真正下载的页面可能不是首页(也有可能是首页),这时还是构造一个Intent,startActivity.  这个intent中的action可能有多种view,download都有可能。系统会根据第三方程序向系统注册的功能,为你的Intent选择可以打开的程序或者页面。所以唯一的一点 不同的是从icon的点击启动的intent的action是相对单一的,从程序中跳转或者启动可能样式更多一些。本质是相同的。


程序之间的亲和性的理解。

1、默认情况下一个应用的所有Activity都是具有相同的affinity,都是从application中继承,application的affinity默认就是manifest的包名。
2、affinity对Activity来说,就像是身份证一样,可以告诉所在的Task,自己属于其中的一员。
3、应用场合:
a:根据affinity重新为Activity选择合适的宿主Task;
b:与allowTaskReparenting属性配合;
c:启动Activity使用Intent设置了FLAG_ACTIVITY_NEW_TASK标记


同一个程序,但不同的Activity是否可以放在不同的Task任务栈中?

1、不设置Activity的android:configChanges时,切屏会重新调用各个生命周期,切横屏时会执行一次,切竖屏时会执行两次
2、设置Activity的android:configChanges="orientation"时,切屏还是会重新调用各个生命周期,切横、竖屏时只会执行一次
3、设置Activity的android:configChanges="orientation|keyboardHidden"时,切屏不会重新调用各个生命周期,只会执行onConfigurationChanged方法


AIDL的全称是什么?如何工作?

全称是:Android Interface Define Language
在Android中, 每个应用程序都可以有自己的进程. 在写UI应用的时候, 经常要用到Service. 在不同的进程中, 怎样传递对象呢?
显然, Java中不允许跨进程内存共享.  因此传递对象, 只能把对象拆分成操作系统能理解的简单形式, 以达到跨界对象访问的目的. 在J2EE中,采用RMI的方式, 可以通过序列化传递对象. 在Android中, 则  采用AIDL的方式. 理论上AIDL可以传递Bundle,实际上做起来却比较麻烦。
AIDL(AndRoid接口描述语言)是一种借口描述语言; 编译器可以通过aidl文件生成一段代码,通过预先定义的接口达到两个进程内部通信进程的目的. 如果需要 在一个Activity中, 访问另一个Service中的某个对象, 需要先将对象转化成AIDL可识别的参数(可能是多个参数), 然后使用AIDL来传递这些参数, 在消息的接收端, 使用  这些参数组装成自己需要的对象.AIDL的IPC的机制和COM或CORBA类似, 是基于接口的,但它是轻量级的。它使用代理类在客户端和实现层间传递值.
如果要使用AIDL,   需要完成2件事情:
1. 引入AIDL的相关类.;
2. 调用aidl产生的class.
AIDL的创建方法:  AIDL语法很简单,可以用来声明一个带一个或多个方法的接口,也可以传递参数和返回值。 由于远程调用的需要, 这些参数和返回值并不是任何类型.
下面是些AIDL支持的数据类型:
1. 不需要import声明的简单Java编程语言类型(int,boolean等)
2. String, CharSequence不需要特殊声明
3. List, Map和Parcelables类型, 这些类型内所包含的数据成员也只能是简单数据类型, String等其他比支持的类型.
4. (另外: 我没尝试Parcelables, 在Eclipse+ADT下编译不过, 或许以后会有所支持


dvm的进程和Linux的进程, 应用程序的进程是否为同一个概念

Dvm的进程是dalivk虚拟机进程,每个android程序都运行在自己的进程里面,每个android程序系统都会给他分配一个单独的liunx uid(user id), 每个dvm都是linux里面的一个进程.所以说这两个进程是一个进程.


什么是Activity?

四大组件之一,一般的,一个用户交互界面对应一个activity, activity 是Context的子类,同时实现了window.callback和keyevent.callback, 可以处理与窗体用户交互的事件. 我开发常用的的有ListActivity  , PreferenceActivity 等…如果界面有共同的特点或者功能的时候,还会自己定义一个BaseActivity


请描述一下Activity生命周期

生命周期描述的是一个类 从创建(new出来)到死亡(垃圾回收)的过程中会执行的方法..    在这个过程中 会针对不同的生命阶段会调用不同的方法        Activity从创建到销毁有多种状态,从一种状态到另一种状态时会激发相应的回调方法,这些回调方法包括:oncreate ondestroy onstop onstart onresume onpause    其实这些方法都是两两对应的,onCreate创建与onDestroy销毁;    onStart可见与onStop不可见;onResume可编辑(即焦点)与onPause;    这6个方法是相对应的,那么就只剩下一个onRestart方法了,这个方法在什么时候调用呢?

答案就是:在Activity被onStop后,但是没有被onDestroy,在再次启动此Activity时就调用onRestart(而不再调用onCreate)方法;    如果被onDestroy了,则是调用onCreate方法。    最后讲自己项目中的经验,比如说豆瓣客户端每次进入某个界面的时候要刷新列表,这个刷新列表的操作 就放在onStart()的方法里面.这样保证每次用户看到的数据都是最新的.        多媒体播放, 播放来电话. onStop() 视频, 视频声音设置为0 , 记录视频播放的位子    onStart() 根据保存的状态恢复现场.        在读文档的时候 还发现 activity还有两个方法 onPostResume() 和 OnPostCreate()这两个生命周期的方法,不过开发的时候没有用到过


两个Activity之间跳转时必然会执行的是哪几个方法

一般情况比如说有两个activity,分别叫A,B ,当在A里面激活B组件的时候, A 会调用 onPause()方法,然后B 调用onCreate() ,onStart(), OnResume() , 这个时候B覆盖了窗体, A会调用onStop()方法.  如果B呢 是个透明的,或者是对话框的样式, 就不会调用onStop()方法


横竖屏切换时候Activity的生命周期。

这个生命周期跟清单文件里的配置有关系
1、不设置Activity的android:configChanges时,切屏会重新调用各个生命周期    默认首先销毁当前activity,然后重新加载
2、设置Activity的android:configChanges="orientation|keyboardHidden"时,切屏不会重新调用各个生命周期,只会执行onConfigurationChanged方法


如何将一个Activity设置成窗口的样式

可以自定义一个activity的样式,详细见手机卫士的程序详细信息
android:theme="@style/FloatActivity"
E:\day9\mobilesafe\res\values\style


你后台的Activity被系统 回收怎么办?如果后台的Activity由于某原因被系统回收可了,如何在被系统回收之前保存当前状态?

除了在栈顶的activity,其他的activity都有可能在内存不足的时候被系统回收,一个activity越处于栈底,被回收的可能性越大.
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putLong("id", 1234567890);   }
public void onCreate(Bundle savedInstanceState) {
//判断 savedInstanceState是不是空.
//如果不为空就取出来
super.onCreate(savedInstanceState);   }


如何退出Activity?如何安全退出已调用多个Activity的Application?

1、抛异常强制退出:    该方法通过抛异常,使程序Force Close。    验证可以,但是,需要解决的问题是,如何使程序结束掉,而不弹出Force Close的窗口。
2、记录打开的Activity:    每打开一个Activity,就记录下来。在需要退出时,关闭每一个Activity即可。
3、发送特定广播:    在需要结束应用时,发送一个特定的广播,每个Activity收到广播后,关闭即可。
4、递归退出    在打开新的Activity时使用startActivityForResult,然后自己加标志,在onActivityResult中处理,递归关闭。
上面是网上的一些做法.    其实 可以通过 intent的flag 来实现.. intent.setFlag(FLAG_ACTIVITY_CLEAR_TOP)激活一个新的activity,然后在新的activity的oncreate方法里面 finish掉.


service是否在main thread中执行, service里面是否能执行耗时的操作?

默认情况,如果没有显示的指定service所运行的进程, Service和activity是运行在当前app
所在进程的main thread(UI主线程)里面


两个Activity之间怎么传递数据?

基本数据类型可以通过.  Intent 传递数据     extras.putDouble(key, value)    intent.putExtras(extras)
Application 全局里面存放 对象 ,自己去实现自己的application的这个类,基础系统的application , 每个activity都可以取到
让对象实现 implements  Serializable 接口把对象存放到文件上.
让类实现Serializable 接口,然后可以通过 ObjectOutputStream ObjectInputStream           //ObjectInputStream           //ObjectOutputStream
FileOutputStream fos  =  new  FileOutputStream(new  File("/sdcard/studnet.obj"));
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(new Student());


怎么让在启动一个Activity是就启动一个service

在activity的onCreate()方法里面 startService();


同一个程序,但不同的Activity是否可以放在不同的Task任务栈中

比方说在激活一个新的activity时候, 给intent设置flag
Intent的flag添加FLAG_ACTIVITY_NEW_TASK
这个被激活的activity就会在新的task栈里面…


Activity怎么和service绑定,怎么在activity中启动自己对应的service?

bindService().  让activity能够访问到 service里面的方法构建一个intent对象,
Intent service = new Intent(this,MyService.class);
通过bindService的方法去启动一个服务,
ServiceConnection  对 象 ( 重 写 onServiceConnected 和 OnServiceDisconnected方法) 和BIND_AUTO_CREATE.
private class myconn implements ServiceConnection     {
public void onServiceConnected(ComponentName name, IBinder service) {
// TODO Auto-generated method stub
//可以通过IBinder的对象 去使用service里面的方法                  }
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
}                           }


什么是Service以及描述下它的生命周期。Service有哪些启动方法,有什么区别,怎样停用Service?

在Service的生命周期中,被回调的方法比Activity少一些,只有onCreate, onStart, onDestroy,    onBind和onUnbind。
通常有两种方式启动一个Service,他们对Service生命周期的影响是不一样的。
1 通过startService   Service会经历 onCreate 到onStart,然后处于运行状态,stopService的时候调用onDestroy方法。 如果是调用者自己直接退出而没有调用stopService的话,Service会一直在后台运行。
2 通过bindService  Service会运行onCreate,然后是调用onBind, 这个时候调用者和Service绑定在一起。调用者退出了,Srevice就会调用onUnbind->onDestroyed方法。       所谓绑定在一起就共存亡了。调用者也可以通过调用unbindService方法来停止服务,这时候Srevice就会调用onUnbind->onDestroyed方法。    需要注意的是如果这几个方法交织在一起的话,会出现什么情况呢?    一个原则是Service的onCreate的方法只会被调用一次,就是你无论多少次的startService又bindService,Service只被创建一次。    如果先是bind了,那么start的时候就直接运行Service的onStart方法,如果先是start,那么bind的时候就直接运行onBind方法。 如果service运行期间调用了bindService,这时候再调用stopService的话,service是不会调用onDestroy方法的,service就stop不掉了,只能先UnbindService, 再StopService。如果一个service通过startService 被start之后,多次调用startService 的话,service会多次调用onStart方法。多次调用stopService的话,service只会调用一次onDestroyed方法如果一个service通过bindService被start之后,多次调用bindService的话,service只会调用一次onBind方法。 多次调用unbindService的话会抛出异常


不用service,B页面为音乐播放,从A跳转到B,再返回,如何使音乐继续播放?

这个问题问的很山寨.默认不做任何处理,B里面的音乐都能播放.    遇到问题, 可以随机应变,灵活发挥,多考虑些细节,比如说这个题就可以这样说,说说你对startActivityForResult的理解()
A开启B的时候,用startActivityForResult()方法,
B返回的时候把播放的状态信息返回给A ,A继续播放音乐.


什么是IntentService?有何优点?

普通的service ,默认运行在ui main 主线程
Sdk给我们提供的方便的,带有异步处理的service类,
OnHandleIntent() 处理耗时的操作


什么时候使用Service?

拥有service的进程具有较高的优先级
官方文档告诉我们,Android系统会尽量保持拥有service的进程运行,只要在该service已经被启动(start)或者客户端连接(bindService)到它。
当内存不足时,需要保持,拥有service的进程具有较高的优先级。
1. 如果service正在调用onCreate,  onStartCommand或者onDestory方法,那么用于当前service的进程相当于前台进程以避免被killed。
2. 如果当前service已经被启动(start),拥有它的进程则比那些用户可见的进程优先级低一些,但是比那些不可见的进程更重要,这就意味着service一般不会被killed.
3. 如果客户端已经连接到service (bindService),那么拥有Service的进程则拥有最高的优先级,可以认为service是可见的。
4. 如果service可以使用startForeground(int, Notification)方法来将service设置为前台状态,那么系统就认为是对用户可见的,并不会在内存不足时killed。
如果有其他的应用组件作为Service,Activity等运行在相同的进程中,那么将会增加该进程的重要性。
1.Service的特点可以让他在后台一直运行,可以在service里面创建线程去完成耗时的操作.
2.Broadcast receiver捕获到一个事件之后,可以起一个service来完成一个耗时的操作.
3.远程的service如果被启动起来,可以被多次bind, 但不会重新create.  索爱手机X10i的人脸识别的service可以被图库使用,可以被摄像机,照相机等程序使用.


请描述一下Intent 和 Intent Filter

Android 中通过 Intent 对象来表示一条消息,一个 Intent 对象不仅包含有这个消息的目的地,还可以包含消息的内容,这好比一封 Email,其中不仅应该包含收件地址,还可以包含具体的内容。对于一个 Intent 对象,消息“目的地”是必须的,而内容则是可选项。
通过Intent 可以实现各种系统组件的调用与激活.     Intent filter: 可以理解为邮局或者是一个信笺的分拣系统…    这个分拣系统通过3个参数来识别    Action: 动作       Data: 数据uri      Category : 而外的附加信息    Action 匹配    Action 是一个用户定义的字符串,用于描述一个 Android 应用程序组件,一个 Intent Filter 可以包含多个 Action。在 AndroidManifest.xml 的 Activity 定义时可以在其 <intent-filter >节点指定一个 Action 列表用于标示 Activity 所能接受的“动作”,
例如:
<intent-filter >
<action android:name="android.intent.action.MAIN" />
<action android:name="cn.itcast.action" />
……
</intent-filter>
如果我们在启动一个 Activity 时使用这样的 Intent 对象:
Intent intent =new Intent();
intent.setAction("cn.itcast");
那么所有的 Action 列表中包含了“cn.itcast”的 Activity 都将会匹配成功。
Android 预定义了一系列的 Action 分别表示特定的系统动作。这些 Action 通过常量的方式定义在 android.content. Intent中,以“ACTION_”开头。我们可以在 Android 提供的文档中找到它们的详细说明。
URI 数据匹配    一个 Intent 可以通过 URI 携带外部数据给目标组件。在 <intent-filter >节点中,通过 <data/>节点匹配外部数据。
mimeType 属性指定携带外部数据的数据类型,scheme 指定协议,host、port、path 指定数据的位置、端口、和路径。如下:
<data android:mimeType="mimeType"
android:scheme="scheme"
android:host="host"
android:port="port"
android:path="path"/>
电话的uri   tel://12345 http://www.baidu.com 自己定义的uri  itcast://cn.itcast/person/10
如果在 Intent Filter 中指定了这些属性,那么只有所有的属性都匹配成功时 URI 数据匹配才会成功。
Category 类别匹配
<intent-filter >节点中可以为组件定义一个 Category 类别列表,当 Intent 中包含这个列表的所有项目时 Category 类别匹配才会成功。    默认是DEFAULT


Intent传递数据时,可以传递哪些类型数据

1.一般的基本数据类型 Intent .putextra() intent.getextra();
2.数据的uri, intent.setData() intent.getData();


说说Activity,Intent,Service是什么关系

麦当劳和麦当娜的关系是什么关系?
这种问题,就讲下activity,讲一下service,说一下 通过intent去激活组件,传递数据.
说自己项目中有这样一个网络更新的功能,显示界面就用的activity, 后台有个service每隔半小时都去访问下服务器获取更新的数据…开启服务用的是intent来开启


请描述一下Broadcast Receiver

用于接收系统的广播通知, 系统会有很多sd卡挂载,手机重启,广播通知,低电量,来电,来短信等….
手机卫士中自定义一个broadcast receiver来获取短信到来的广播, 根据黑名单来判断是否拦截该短信.
画画板生成图片后,发送一个sd挂载的通知,通知系统的gallery去获取到新的图片.


在manifest和代码中如何注册和使 用 broadcast receiver

设置广播接收者的优先级,设置广播接受者的action名字 等…


请介绍下ContentProvider是如何实现数据共享的

把自己的数据通过uri的形式共享出去
需要去实现一个类去继承ContentProvider
public class PersonContentProvider extends ContentProvider{
public boolean onCreate(){                  //..          }
query(Uri, String[], String, String[], String)
insert(Uri, ContentValues)
update(Uri, ContentValues, String, String[])
delete(Uri, String, String[])   }


请介绍下Android的数据存储方式

文件  访问权限.
数据库 sqlite
SharedPreference
网络
内容提供者


为什么要用ContentProvider?它和sql的实现上有什么差别

屏蔽数据存储的细节,对用户透明,用户只需要关心操作数据的uri就可以了
不同app之间共享,操作数据
Sql也有增删改查的方法.
但是contentprovider 还可以去增删改查本地文件.


请介绍下Android中常用的五种布局

FrameLayout(框架布局),
LinearLayout (线性布局),
AbsoluteLayout(绝对布局),
RelativeLayout(相对布局),
TableLayout(表格布局)

FrameLayout
从屏幕的左上角开始布局,叠加显示, 实际应用 播放器的暂停按钮.
LinearLayout
线性布局,这个东西,从外框上可以理解为一个div,他首先是一个一个从上往下罗列在屏幕上。每一个LinearLayout里面又可分为垂直布局    (android:orientation="vertical")和水平布局(android:orientation="horizontal" )。当垂直布局时,每一行就只有一个元素,多个元素依次垂直往下;水平布局时,只有一行,每一个元素依次向右排列。
AbsoluteLayout
绝对布局犹如div指定了absolute属性,用X,Y坐标来指定元素的位置android:layout_x="20px"    android:layout_y="12px"    指定平板机型的游戏开发中经常用到绝对布局    指定机型的平板游戏开发.
RelativeLayout
相对布局可以理解为某一个元素为参照物,来定位的布局方式。主要属性有: 相对于某一个元素
android:layout_below="@id/aaa" 该元素在 id为aaa的下面
android:layout_toLeftOf="@id/bbb" 改元素的左边是bbb   相对于父元素的地方
android:layout_alignParentLeft="true"  在父元素左对齐
android:layout_alignParentRight="true" 在父元素右对齐
TableLayout
表格布局类似Html里面的Table。每一个TableLayout里面有表格行TableRow,TableRow里面可以具体定义每一个元素,设定他的对齐方式 android:gravity="" 。    每一个布局都有自己适合的方式,另外,这五个布局元素可以相互嵌套应用,做出美观的界面。
webview


谈谈UI中, Padding和Margin有什么区别

Padding 文字对边框, margin是控件对父窗体.


widget相对位置的完成在activity的哪个生命周期阶段实现

这个题没看懂… widget可以理解成桌面小控件, 也可以理解成 某个button, imageview这样的控件…


请解释下在单线程模型中Message、Handler、Message Queue、Looper之间的关系。

AIDL的全称是什么?如何工作?

Android interface definition language (android接口定义语言) , 用来跨进程的访问方法,    访问远程的服务的方法. 如何工作 day7 queryStudent .
手机卫士 Itelephony 接口挂断电话


请解释下Android程序运行时权限与文件系统权限的区别

Android程序执行需要读取到安全敏感项必需在androidmanifest.xml中声明相关权限请求, 打电话,访问网络,获取坐标,读写sd卡,读写联系人等..安装的时候会提示用户…
文件系统的权限是linux权限. 比如说sharedpreference里面的Context.Mode.private
Context.Mode.world_read_able
Context.Mode_world_writeable


系统上安装了多种浏览器,能否指定某浏览器访问指定页面

找到对应的浏览器的意图,传递数据URI , 激活这个意图


对android主线程的运用和理解

主ui线程不能执行耗时的操作


对android虚拟机的理解,包括内存管理机制垃圾回收机制

虚拟机很小,空间很小,谈谈移动设备的虚拟机的大小限制 16M , 谈谈加载图片的时候怎么处理大图片的,    垃圾回收,没有引用的对象,在某个时刻会被系统gc掉.


Framework工作方式及原理,Activity是如何生成一个view的,机制是什么

可以讲下activity的源码,比如说 每个activity里面都有window.callback和keyevent.callback,一些回调的接口或者函数吧. 框架把activity创建出来就会调用里面的这些回调方法,会调用activity生命周期相关的方法.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  面试题 android