当前位置: 代码迷 >> Android >> Android 面试题小结(一)
  详细解决方案

Android 面试题小结(一)

热度:133   发布时间:2016-04-24 11:31:30.0
Android 面试题总结(一)

前言

  • 这里不断总结在面试中问到的一些问题,作为以后面试复习的资料.在此记录也是为了方便各位读者.

Java

1.设计模式和其UML类图:比较常用的
- 单例http://blog.csdn.net/qq_28690547/article/details/50479241
- Builderhttp://blog.csdn.net/qq_28690547/article/details/50493099
- 工厂方法http://blog.csdn.net/qq_28690547/article/details/50660376
- 原型http://blog.csdn.net/qq_28690547/article/details/50626237
- 策略http://blog.csdn.net/qq_28690547/article/details/50683310
- 状态http://blog.csdn.net/qq_28690547/article/details/50706448
- 观察者http://blog.csdn.net/qq_28690547/article/details/50661603
- 命令http://blog.csdn.net/qq_28690547/article/details/50708061
- 模板方法http://blog.csdn.net/qq_28690547/article/details/50708547
- 访问者http://blog.csdn.net/qq_28690547/article/details/50710061
- 代理http://blog.csdn.net/qq_28690547/article/details/50734045
- 中介者http://blog.csdn.net/qq_28690547/article/details/50710622

2.Volatile关键字:http://www.infoq.com/cn/articles/java-memory-model-4
对一个volatile变量的读,总是能看到(任意线程)对这个volatile变量最后的写入。
volatile变量的写-读可以实现线程之间的通信.
当写一个volatile变量时,JMM会把该线程对应的本地内存中的共享变量刷新到主内存。
当读一个volatile变量时,JMM会把该线程对应的本地内存置为无效。线程接下来将从主内存中读取共享变量。
下面对volatile写和volatile读的内存语义做个总结:
线程A写一个volatile变量,实质上是线程A向接下来将要读这个volatile变量的某个线程发出了(其对共享变量所在修改的)消息。
线程B读一个volatile变量,实质上是线程B接收了之前某个线程发出的(在写这个volatile变量之前对共享变量所做修改的)消息。
线程A写一个volatile变量,随后线程B读这个volatile变量,这个过程实质上是线程A通过主内存向线程B发送消息。

Android

3.AsyncTask:
AsyncTask首次引入时,异步任务是在一个独立的线程中顺序执行,一直只能执行一个任务,不能并行得执行.
1.6-2.3的版本,AsyncTask引入了线程池,支持同时执行5个异步任务,也就是说同时只能由5个线程运行,超过的线程等待.
3.0以后的版本,每次只启动一个线程执行一个任务,完成之后再执行第二个任务,也就是相当于只有一个后台线程在执行所提交的所有任务.

1.生命周期:
AsyncTask不会随着activity的生命周期终止而终止,activity生命结束,AsyncTask会一直执行到doInBackground()方法执行完毕.在activity销毁前,必须取消AsyncTask通过cancle()这个方法.但有一种情况是,在doInBackground()如果执行了BitmapFactory.decodeStream()这个方法,那么这个操作会继续下去.
2.内存泄露:
如果AsyncTask被声明为activity的非静态的内部类,那么AsyncTask会保留一个对activity的引用,如果activity已经被销毁,AsyncTask的后台还在执行,它将继续在内存保留这个引用,导致activity无法被回收,从而内存泄露
3.结果丢失:
屏幕旋转或者其他操作导致activity被重建,之前运行的AsyncTask会持有之前activity的引用,因此更新界面将不再生效.
4.并行和串行的问题:
1.6以前,AsyncTask是串行的
1.6-2.3,AsyncTask是并行的
2.3以后,AsyncTask中调用execute()是串行执行,executeOnExecytor(Executor)是并行执行.

4.activity,fragment,service的生命周期:
常见例子:程序运行过程中被其他应用终止,调用onPause-onStop,恢复onStart-onPause;如果打断这个应用程序的Theme为Translucent或者dialog的activity那么只是onPause,恢复的时候onResume;
onCreate:创建界面的时候,做一些数据的初始化工作
onStart:到这一步变成用户可见不可交互的
onResume:变成和用户可交互的
onPause:到这一步是可见但不可交互,系统会停止动画等消耗CPU的事情,这个方法要做的事情很短,因为下一个activity不会等到这个方法完成在启动.
onStop:变得不可见,被下一个activity覆盖了
onDestory:
启动另一个activity然后finish当前的activity,先调用旧activity的onPause方法,然后调用新的activity的onCreate-onStop-onResume方法,然后调用旧activity的onStop-onDestory方法
如果旧activity没有被finish掉,那么在onStop之前 还会调用onSaveInstanceState的方法;

fragment的生命周期:
onAttach-onCreate-onCreateView-onActivityCreated-onStart-onResume
onPause-onStop-onDestoryView-onDestory-onDetach

5.四大启动模式:
这里写图片描述

5.1**onNewIntent():**
大家遇到一个应用的Activity供多种方式调用启动的情况,多个调用希望只有一个Activity的实例存在,这就需要Activity的onNewIntent(Intent intent)方法了。只要在Activity中加入自己的onNewIntent(intent)的实现加上Manifest中对Activity设置lanuchMode=“singleTask”or “singleTop”就可以。
onNewIntent()非常好用,Activity第一启动的时候执行onCreate()—->onStart()—->onResume()等后续生命周期函数,也就时说第一次启动Activity并不会执行到onNewIntent(). 而后面如果再有想启动Activity的时候,那就是执行onNewIntent()—->onResart()——>onStart()—–>onResume().

6.onSaveInstanceState()和onRestoryInstanceState():
当应用遇到意外情况(例如:内存不足,用户直接按home键,屏幕方向改变,设备语言设定,键盘弹出)由系统销毁一个activity时,onSaveInstanceState()这个方法就会被调用,用来保存一些临时性的状态.然后该状态可以在onCreate()或者onRestoryInstanceState()中恢复.

7.android 5.0特性:http://blog.csdn.net/qq_28690547/article/details/50975739

9.MVP架构:http://blog.csdn.net/qq_28690547/article/details/50711786
MVP 是从经典的模式MVC演变而来,它们的基本思想有相通的地方:Controller/Presenter负责逻辑的处理,Model提供数据,View负责显示.作为一种新的模式,MVP与MVC有着一个重大的区别:在MVP中View并不直接使用Model,它们之间的通信是通过Presenter (MVC中的Controller)来进行的,所有的交互都发生在Presenter内部,而在MVC中View会从直接Model中读取数据而不是通过 Controller。
view层不再和model层存在耦合。MVP主要解决就是把逻辑层抽出来成P层,要是遇到需求逻辑上的更改就可以只需要修改P层了或者遇到逻辑上的大概我们可以直接从写一个P也可以,我们会经常把所有的东西都写在了Activity/Fragment里面这样一来遇到频繁改需求或者逻辑越来越复杂的时候,Activity /Fragment里面就会出现过多的混杂逻辑导致出错,所以MVP模式对于APP来对控制逻辑和UI的解耦来说是一个不错的选择!

10.ART和Dalvik区别:
ART上应用启动快\运行快,但是消耗更多存储空间,安装时间长,总的来说ART的功效就是空间换时间.
Dalvik是Google公司自己设计用于Android平台的Java虚拟机.Dalvik虚拟机是Google等厂商合作开发的Android移动设备平台的核心组成部分之一.它可以支持已转换的.dex格式的java应用程序的运行,.dex格式是专为Dalvik设计的一种压缩格式,适合内存和处理器速度有限的系统.Dalvik经过优化,允许在有限的内存中同事运行多个虚拟机的实例,并且每一个Dalvik应用作为一个独立的Linux进程执行.独立的进程可以防止在虚拟机崩溃的时候所有程序都关闭.
ART代表android runtime,其处理应用程序的执行方式完全不同于Dalvik,Dalvik是依靠一个Just-In-Time编译器去解释字节码.开发者编译后的应用需要通过一个解释器在用户的设备上运行,这一机制并不高效,但让应用能更容易在不同硬件和架构上运行.ART则完全改变了这套做法,在应用安装时就预编译字节码到机器语言,这一机制教Ahead-Of-Time编译.在移除解释代码这一过程后,应用程序执行将更有效率,启动更快
ART优点:
1.性能提升显著.
2.应用启动更快\运行更快\体验更流畅\触感反馈更及时.
3.更长的电池续航能力
4.支持更低的硬件
ART缺点:
1.更大储存空间占用,可能会增加10%-20%
2.更长应用安装时间

11.Java运行时机制JVM和android运行时机制:
JVM运行机制:
1.将Java代码编译成字节码
2.类加载,这个工作由类加载器完成,这个实际上就是把.class文件从一盘读到内存里.
3.类执行.
android运行时机制:
见第10.

12.如何避免ANR:
1.UI线程尽量只做跟UI相关的工作.
2.耗时工作把它放入单独的线程处理.
3.尽量用Handler来处理UIthread和逼得thread之间的交互.

13.状态模式和策略模式的比较:
两者虽然UML类图相类似,但是两种完全不同的思想.对状态进行建模时,状态迁移是一个核心内容,然而,在选择策略时,迁移与此毫无关系,用户关系的不同策略不同的输出结果.
1.策略模式是一组方案,他们可以相互替换选择一个策略,获得策略的输出.策略模式用于随不同外部环境采取不同行为的场合.
2.状态模式处理的核心问题是状态的迁移,因为在对象存在很多状态的情况下,各个状态之间跳转和迁移的过程都是非常复杂的.
在状态模式中,状态的变迁是由对象的内部条件决定,外界只需关心其接口,不必关心其状态对象的创建和转化;而策略模式里,采取何种策略由外部条件(C)决定

14.Android消息处理机制(Handler、Looper、MessageQueue与Message):http://blog.csdn.net/bboyfeiyu/article/details/38555547
1.消息的表示:Message
2.消息队列:MessageQueue,MessageQueue是Looper内部使用的
3.消息循环,用于循环去除消息进行处理:Looper
4.消息处理,消息循环从消息队列中取出消息后要对消息进行处理:Handler
这里写图片描述
在应用启动时,会开启一个主线程(UI线程),并且启动消息循环,应用不停地从该消息队列中取出、处理消息达到程序运行的效果。Looper对象封装了消息队列,Looper对象是ThreadLocal的,不同线程之间的Looper对象不能共享与访问。而Handler通过与Looper对象绑定来实现与执行线程的绑定,handler会把Runnable(包装成Message)或者Message对象追加到与线程关联的消息队列中,然后在消息循环中挨个取出消息,并且处理消息。当Handler绑定的Looper是主线程的Looper,则该Handler可以在handleMessage中更新UI,否则更新UI则会抛出异常!
其实我们可以把Handler、Looper、Thread想象成一个生产线,工人(搬运工)相当于Handler,负责将货物搬到传输带上(Handler将消息传递给消息队列);传送带扮演消息队列的角色,负责传递货物,货物会被挨取出,并且输送到目的地 ( target来处理 );而货物到达某个车间后再被工人处理,车间就扮演了Thread这个角色,每个车间有自己独立的传送带,车间A的货物不能被车间B的拿到,即相当于ThreadLocal( 车间独有 )。

15.ContentProvider和ContentResolver:

一个应用实现ContentProvider来提供内容给别的应用来操作,
一个应用通过ContentResolver来操作别的应用数据,当然在自己的应用中也可以。

8.RecyclerView:

  • 与ListView的区别:

    (1)**Item复用方面:**RecyclerView内置了RecyclerViewPool,多级缓存,ViewHolder.而AdapterView需要手动去添加ViewHolder且复用功能也没RecyclerView更加完善.
    (2)**样式丰富方面:**RecyclerView通过支持水平,垂直和表格列表及其他更复杂形式,而AdapterView只支持具体某一种.
    (3)**效果增强方面:**RecyclerView内置了ItemDecoration和ItemAnimator,可以自定义item的分割线和item项数据变化的动画效果,而用AdapterView实现时采取的做法是将这些特殊UI作为itemView的一部分,设置可见不可见决定是否展现,而数据变化时的动画效果也没有提供,实现起来比较麻烦.
    (4)**代码内聚方面:**RecyclerView将功能密切相关的类写成内部类,如ViewHolder,Adapter.而AdapterView没有.

  • 原理解析:
    (1)RecycledViewPool:用于多个RecyclerView之间共享View,只需要创建一个RecyclerViewPool实例,然后调用RecyclerView的setRecycledViewPool(RecycledViewPool)方法即可.RecyclerView默认会创建一个RecyclerViewPool实例.内部有两个SparseArray(它也是一个list,android系统建议我们用SparseArray来代替HashMap

  相关解决方案