Android开发面试经——4.常见Android进阶笔试题(更新中...)

 

关注finddreams博客:http://blog.csdn.net/finddreams/article/details/44301359html

上一篇文章咱们已经了解了Android笔试的一些基础题目, 
[《Android开发面试经——2.常见Android基础笔试题》 ] 
(http://blog.csdn.net/finddreams/article/details/44219231
笔试完,就是面试官问你问题了,相比笔试,面试咱们每每会有些许紧张,由于不知道面试官会问什么奇怪的问题,要是问的问题恰好不懂,这时就更加头皮发麻了。为了能在面试提问中取得一个满意的表现,我特别整理了一下常见的面试官提的技术问题: 
Android开发面试经——5.常见面试官提问Android题① 
Android开发面试经——6.常见面试官提问Android题②(更新中…)java

可是作为一个有经验的开发者,仅仅知道基础题仍是不够的,你的简历上说有两年以上工做经验的话,那面试官确定会问一些深刻性的问题,看你可否回答的出。因此为了找一个更好的工做,咱们还须要去了解一下Android进阶的笔试题目:android

1.什么是ANR,如何避免? 
ANR:Application Not Responding。 
在 Android 中,活动管理器和窗口管理器这两个系统服务负责监视应用程序的响应。当出现下列状况时,Android 就会显示 ANR 对话框了: 
①.用户对应用程序的操做(如输入事件,按键、触摸屏事件)在5秒内无响应 
②. 广播接受器(BroadcastReceiver)在10秒内仍未执行完毕 
Android 应用程序彻底运行在一个独立的线程中(例如 main)。这就意味着,任何在主 线程中运行的,须要消耗大量时间的操做都会引起 ANR。由于此时,你的应用程序已经没有机会去响应输入事件和意向广播(Intentbroadcast)。 
避免方法:Activity 应该在它的关键生命周期方法(如 onCreate()和 onResume())里尽量少的去作建立操做, 
潜在的耗时操做。例如网络或数据库操做,或者高耗时的计算如改变位图尺寸,应该在子线程里(或者异步方式)来完成。 
主线程应该为子线程提供一个 Handler,以便完成时可以提交给主线程。面试

2.Handler机制原理? 
andriod 提供了 Handler 和 Looper 来知足线程间的通讯。Handler 先进先出原则。 
Looper 类用来管理特定线程内对象之间的消息交换 (MessageExchange)。 
1)Looper: 一个线程能够产生一个 Looper 对象,由它来管理此线程里的 MessageQueue(消息队列)。 
2)Handler: 你能够构造 Handler 对象来与 Looper 沟通,以便 push 新消息到 MessageQueue 里;或者接收 Looper 从 MessageQueue 取出)所送来的消息。 
3) Message Queue(消息队列 ): 用来存放线程放入的消息。 
4)线程: UI thread 一般就是 main thread, 而 Android 启动程序时会替它创建一个 MessageQueue。数据库

3.请解释下在单线程模型中Message、Handler、Message Queue、Looper之间的关系。 
简单的说,Handler获取当前线程中的 looper对象,looper 用来从存放 Message 的 MessageQueue中取出 Message,再有 Handler 进行 Message 的分发和处理. 
Message Queue(消息队列): 用来存放经过 Handler 发布的消息, 一般附属于某一个建立它的线程,能够经过 Looper.myQueue()获得当前线程的消息队列 
Handler:能够发布或者处理一个消息或者操做一个 Runnable,经过 Handler发布消息, 消息将只会发送到与它关联的消息队列,然也只能处理该消息队列中的消息 
Looper:是 Handler 和消息队列之间通信桥梁,程序组件首先经过 Handler 把消息传递给 Looper,Looper 把消息放入队列。Looper 也把消息队列里的消息广播给全部的 
Handler:Handler 接受到消息后调用 handleMessage进行处理 
Message:消息的类型,在 Handler 类中的 handleMessage 方法中获得单个的消息进行处理 
在单线程模型下, 为了线程通讯问题, Android 设计了一个 Message Queue(消息队列), 线程间能够经过该 Message Queue 并结合 Handler 和 Looper 组件进行信息交换。 
下面将对它 们进行分别介绍: 
1. Message 
Message 消息,理解为线程间交流的信息,处理数据后台线程须要更新 UI ,则发送Message 内含一些数据给 UI 线程。 
2. Handler 
Handler处理者,是 Message 的主要处理者,负责 Message 的发送,Message 内容的执行处理。后台线程就是经过传进来的 Handler对象引用来 sendMessage(Message)。 
而使用 Handler,须要 implement 该类的 handleMessage(Message)方法,它是处理这些 
Message 的操做内容,例如 Update UI 。一般须要子类化 Handler 来实现 handleMessage方法。 
3. Message Queue 
Message Queue 消息队列,用来存放经过 Handler 发布的消息,按照先进先出执行。每一个 message queue 都会有一个对应的 Handler。Handler 会向 messagequeue 经过两种方法发送消息:sendMessage 或 post。这两种消息都会插在 message queue 队尾并 
按先进先出执行。但经过这两种方法发送的消息执行的方式略有不一样:经过 sendMessage发送的是一个 message 对象,会被 Handler 的 handleMessage()函数处理;而经过 post 方法发送的是一个 runnable 对象,则会本身执行。 
4. Looper 
Looper 是每条线程里的 Message Queue 的管家。Android 没有 Global 的MessageQueue,而 Android 会自动替主线程(UI 线程)创建 Message Queue,但在子线程里并无创建 Message Queue。 因此调用 Looper.getMainLooper()获得的主线程的 Looper 不为 NULL,但调用 Looper.myLooper()获得当前线程的 Looper 就有可能为 NULL。编程

4.Android 中线程与线程,进程与进程之间如何通讯 
一、一个 Android 程序开始运行时,会单独启动一个 Process。 
默认状况下,全部这个程序中的 Activity 或者 Service 都会跑在这个 Process。 
默认状况下,一个 Android 程序也只有一个 Process,但一个 Process 下却能够有许多个 Thread。 
二、一个 Android 程序开始运行时,就有一个主线程 MainThread 被建立。该线程主要负责 UI 界面的显示、更新和控件交互,因此又叫 UI Thread。 
一个 Android 程序建立之初,一个 Process 呈现的是单线程模型–即 Main Thread, 
全部的任务都在一个线程中运行。因此,Main Thread 所调用的每个函数,其耗时应该 
越短越好。而对于比较费时的工做,应该设法交给子线程去作,以免阻塞主线程(主线程被阻塞,会致使程序假死 现象) 。 
三、Android 单线程模型:Android UI 操做并非线程安全的而且这些操做必须在 UI 线程中执行。若是在子线程中直接修改 UI,会致使异常。 
4.Android 的 的 IPC ( 进程间通讯 ) 机制 
IPC 是内部进程通讯的简称, 是共享 ” 命名管道 ” 的资源。Android 中的 IPC机制是为了让 
Activity 和 Service之间能够随时的进行交互,故在 Android 中该机制,只适用于 Activity 和 Service之间的通讯,相似于远程方法调用,相似于 C/S 模式的访问。经过定义 AIDL 接口文件来定义 IPC 接口。Servier 端实现 IPC接口,Client 端调用 IPC接口本地代理。安全

5.Android应用程序框架 
这里写图片描述 
这里写图片描述markdown

6.View, surfaceView, GLSurfaceView的区别 
View 是最基础的,必须在 UI 主线程内更新画面,速度较慢。 
SurfaceView 是 view 的子类,相似使用双缓机制,在新的线程中更新画面因此刷新界面速度比 view 快 GLSurfaceView 是 SurfaceView 的子类,opengl 专用的。 
区别:SurfaceView是从View基类中派生出来的显示类,直接子类有GLSurfaceView和VideoView,能够看出GL和视频播放以及Camera摄像头通常均使用SurfaceView 
SurfaceView和View最本质的区别在于,surfaceView是在一个新起的单独线程中能够从新绘制画面而View必须在UI的主线程中更新画面。 
那么在UI的主线程中更新画面 可能会引起问题,好比你更新画面的时间过长,那么你的主UI线程会被你正在画的函数阻塞。那么将没法响应按键,触屏等消息。 
当使用surfaceView 因为是在新的线程中更新画面因此不会阻塞你的UI主线程。但这也带来了另一个问题,就是事件同步。好比你触屏了一下,你须要surfaceView中thread处理,通常就须要有一个event queue的设计来保存touch event,这会稍稍复杂一点,由于涉及到线程同步。网络

7. AIDL的全称是什么?如何工做? 
AIDL 全称 Android Interface Definition Language(Android 接口描述语言)是一种接口描述语言 ; 编译器能够经过 aidl文件生成一段代码, 经过预先定义的接口达到两个进程内 
部通讯进程跨界对象访问的目的.AIDL 的 IPC 的机制和 COM 或 CORBA 相似 , 是基于接口的, 但它是轻量级的。 它使用代理类在客户端和实现层间传递值 . 若是要使用 AIDL, 须要完成2件事情 : 
1. 引入AIDL的相关类 .; 
2. 调用 aidl产生的 class.理论上 , 参数能够传递基本数据类型和String, 还有就是Bundle的派生类 
当A进程要去调用B进程中的service时,并实现通讯,咱们一般都是经过AIDL来操做的 。 
A工程: 
首先咱们在net.blogjava.mobile.aidlservice包中建立一个RemoteService.aidl文件,在里面咱们自定义一个接口,含有方法get。ADT插件会在gen目录下自动生成一个RemoteService.Java文件,该类中含有一个名为RemoteService.stub的内部类,该内部类中含有aidl文件接口的get方法。 
说明一:aidl文件的位置不固定,能够任意 
而后定义本身的MyService类,在MyService类中自定义一个内部类去继承RemoteService.stub这个内部类,实现get方法。在onBind方法中返回这个内部类的对象,系统会自动将这个对象封装成IBinder对象,传递给他的调用者。 
其次须要在AndroidManifest.xml文件中配置MyService类,代码以下:

<!-- 注册服务 --> <service android:name=".MyService"> <intent-filter> <!-- 指定调用AIDL服务的ID --> <action android:name="net.blogjava.mobile.aidlservice.RemoteService" /> </intent-filter> </service>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

为何要指定调用AIDL服务的ID,就是要告诉外界MyService这个类可以被别的进程访问,只要别的进程知道这个ID,正是有了这个ID,B工程才能找到A工程实现通讯。 
说明:AIDL并不须要权限 
B工程: 
首先咱们要将A工程中生成的RemoteService.java文件拷贝到B工程中,在bindService方法中绑定aidl服务 
绑定AIDL服务就是将RemoteService的ID做为intent的action参数。 
说明:若是咱们单独将RemoteService.aidl文件放在一个包里,那个在咱们将gen目录下的该包拷贝到B工程中。若是咱们将RemoteService.aidl文件和咱们的其余类存放在一块儿,那么咱们在B工程中就要创建相应的包,以保证RmoteService.java文件的报名正确,咱们不能修改RemoteService.java文件 
bindService(new Inten(“net.blogjava.mobile.aidlservice.RemoteService”), serviceConnection, Context.BIND_AUTO_CREATE); 
ServiceConnection的onServiceConnected(ComponentName name, IBinder service)方法中的service参数就是A工程中MyService类中继承了RemoteService.stub类的内部类的对象。

8.关于AndroidOOM,以及如何避免? 
Android的虚拟机是基于寄存器的Dalvik,它的最大堆大小通常是16M,有的机器为24M。所以咱们所能利用的内存空间是有限的。若是咱们的内存占用超过了必定的水平就会出现OutOfMemory的错误。 
①.为何会出现内存不够用的状况呢?我想缘由主要有两个:因为咱们程序的失误,长期保持某些资源(如Context)的引用,形成内存泄露,资源形成得不到释放。保存了多个耗用内存过大的对象(如Bitmap),形成内存超出限制。 
② .如何避免优化? 
一、应该尽可能避免static成员变量引用资源耗费过多的实例,好比Context。Context尽可能使用Application Context,由于Application的Context的生命周期比较长,引用它不会出现内存泄露的问题。使用WeakReference代替强引用。好比可使用WeakReference mContextRef; 
二、线程也是形成内存泄露的一个重要的源头。线程产生内存泄露的主要缘由在于线程生命周期的不可控。将线程的内部类,改成静态内部类。三、Bitmap问题:能够说出现OutOfMemory问题的绝大多数人,都是由于Bitmap的问题。由于Bitmap占用的内存实在是太多了,它是一个“超级大胖子”,特别是分辨率大的图片,若是要显示多张那问题就更显著了。 
如何解决Bitmap带给咱们的内存问题? 
及时的销毁。  虽然,系统可以确认Bitmap分配的内存最终会被销毁,可是因为它占用的内存过多,因此极可能会超过java堆的限制。所以,在用完Bitmap时,要及时的recycle掉。recycle并不能肯定当即就会将Bitmap释放掉,可是会给虚拟机一个暗示:“该图片能够释放了”。设置必定的采样率。  有时候,咱们要显示的区域很小,没有必要将整个图片都加载出来,而只须要记载一个缩小过的图片,这时候能够设置必定的采样率,那么就能够大大减少占用的内存。以下面的代码: BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 2;//图片宽高都为原来的二分之一,即图片为原来的四分之一。 
四、巧妙的运用软引用(SoftRefrence)  有些时候,咱们使用Bitmap后没有保留对它的引用,所以就没法调用Recycle函数。这时候巧妙的运用软引用,可使Bitmap在内存快不足时获得有效的释放 
五、及时释放Cursor; 
六、尽可能使用9path图片。Adapter要使用convertView复用等等;

9. AsyncTask 的介绍 
在开发 Android 移动客户端的时候每每要使用多线程来进行操做, 咱们一般会将耗时的操做放在单独的线程执行, 避免其占用主线程而给用户带来很差的用户体验。 可是在子线程中没法 去操做主线程(UI 线程) ,在子线程中操做 UI 线程会出现错误。所以 android 提供了一个类 Handler 来在子线程中来更新 UI 线程,用发消息的机制更新 UI 界面,呈现给用户。 这样就解决了子线程更新 UI 的问题。可是费时的任务操做总会启动一些匿名的子线程,太多的子线程给系统带来巨大的负担,随之带来一些性能问题。所以 android 提供了一个工具类AsyncTask,顾名思义异步执行任务。这个 AsyncTask 生来就是处理一些后台的比较耗时的任务,给用户带来良好用户体验的,从编程的语法上显得优雅了许多,再也不须要子线程和Handler就能够完成异步操做而且刷新用户界面。

10.说说mvc模式的原理,它在android中的运用 
答:android的官方建议应用程序的开发采用mvc模式。何谓mvc? 
 mvc是model,view,controller的缩写,mvc包含三个部分: 
  l、模型(model)对象:是应用程序的主体部分,全部的业务逻辑都应该写在该层。 
  二、视图(view)对象:是应用程序中负责生成用户界面的部分。也是在整个mvc架构中用户惟一能够看到的一层,接收用户的输入,显示处理结果。 
  三、控制器(control)对象:是根据用户的输入,控制用户界面数据显示及更新model对象状态的部分,控制器更重要的一种导航功能,想用用户出发的相关事件,交给m处理。 
 android鼓励弱耦合和组件的重用,在android中mvc的具体体现以下: 
1)视图层(view):通常采用xml文件进行界面的描述,使用的时候能够很是方便的引入,固然,如何你对android了解的比较的多了话,就必定 能够想到在android中也可使用JavaScript+html等的方式做为view层,固然这里须要进行java和javascript之间的通 信,幸运的是,android提供了它们之间很是方便的通讯实现。 
 2)控制层(controller):android的控制层的重 任一般落在了众多的acitvity的肩上,这句话也就暗含了不要在acitivity中写代码,要经过activity交割model业务逻辑层处理, 这样作的另一个缘由是android中的acitivity的响应时间是5s,若是耗时的操做放在这里,程序就很容易被回收掉。 
 3)模型层(model):对数据库的操做、对网络等的操做都应该在model里面处理,固然对业务计算等操做也是必须放在的该层的。 
  
 11.根据本身的理解描述下Android数字签名。 
答:(1)全部的应用程序都必须有数字证书,Android系统不会安装一个没有数字证书的应用程序 
(2)Android程序包使用的数字证书能够是自签名的,不须要一个权威的数字证书机构签名认证 
(3)若是要正式发布一个Android ,必须使用一个合适的私钥生成的数字证书来给程序签名,而不能使用adt插件或者ant工具生成的调试证书来发布。 
(4)数字证书都是有有效期的,Android只是在应用程序安装的时候才会检查证书的有效期。若是程序已经安装在系统中,即便证书过时也不会影响程序的正常功能

12. 谈谈对 Android NDK 的理解 
NDK 全称:Native Development Kit。 
一、NDK 是一系列工具的集合。 * NDK 提供了一系列的工具,帮助开发者快速开发 C(或 C++)的动态库,并能自动将 so 和 java 应用 
一块儿打包成 apk。这些工具对开发者的帮助是巨大的。 * NDK 集成了交叉编译器,并提供了相应的 mk 文件隔离 CPU、平台、ABI 等差别,开发人员只须要简单修改 mk 文件(指出“哪些文件须要编译”、“编译特性要求”等) ,就能够建立出 so。 * NDK 能够自动地将 
so 和 Java 应用一块儿打包,极大地减轻了开发人员的打包工做。 
二、NDK 提供了一份稳定、功能有限的 API 头文件声明。 Google 明确声明该 API 是稳定的,在后续全部版本中都稳定支持当前发布的 API。从该版本的 NDK 中看出,这些 API 支持的功能很是有限, 
包含有:C 标准库(libc) 、标准数学库(libm) 、压缩库(libz) 、Log 库(liblog) 。

13.ViewStub的应用 
在开发应用程序的时候,常常会遇到这样的状况,会在运行时动态根据条件来决定显示哪一个View或某个布局。那么最一般的想法就是把可能用到的View都写在上面,先把它们的可见性都设为View.GONE,而后在代码中动态的更改它的可见性。这样的作法的优势是逻辑简单并且控制起来比较灵活。可是它的缺点就是,耗费资源。虽然把View的初始可见View.GONE可是在Inflate布局的时候View仍然会被Inflate,也就是说仍然会建立对象,会被实例化,会被设置属性。也就是说,会耗费内存等资源。 
推荐的作法是使用android.view.ViewStub,ViewStub是一个轻量级的View,它一个看不见的,不占布局位置,占用资源很是小的控件。能够为ViewStub指定一个布局,在Inflate布局的时候,只有ViewStub会被初始化,而后当ViewStub被设置为可见的时候,或是调用了ViewStub.inflate()的时候,ViewStub所向的布局就会被Inflate和实例化,而后ViewStub的布局属性都会传给它所指向的布局。这样,就可使用ViewStub来方便的在运行时,要仍是不要显示某个布局。 
但ViewStub也不是万能的,下面总结下ViewStub能作的事儿和何时该用ViewStub,何时该用可见性的控制。 
首先来讲说ViewStub的一些特色: 
1. ViewStub只能Inflate一次,以后ViewStub对象会被置为空。按句话说,某个被ViewStub指定的布局被Inflate后,就不会够再经过ViewStub来控制它了。 
2. ViewStub只能用来Inflate一个布局文件,而不是某个具体的View,固然也能够把View写在某个布局文件中。 
基于以上的特色,那么能够考虑使用ViewStub的状况有: 
1. 在程序的运行期间,某个布局在Inflate后,就不会有变化,除非从新启动。 
由于ViewStub只能Inflate一次,以后会被置空,因此没法期望后面接着使用ViewStub来控制布局。因此当须要在运行时不止一次的显示和隐藏某个布局,那么ViewStub是作不到的。这时就只能使用View的可见性来控制了。 
2. 想要控制显示与隐藏的是一个布局文件,而非某个View。 
由于设置给ViewStub的只能是某个布局文件的Id,因此没法让它来控制某个View。 
因此,若是想要控制某个View(如Button或TextView)的显示与隐藏,或者想要在运行时不断的显示与隐藏某个布局或View,只能使用View的可见性来控制。

 
11
2
相关文章
相关标签/搜索