面试2

JAVA 相关

 

1.静态内部类、内部类、匿名内部类,为何内部类会持有外部类的引用?持有的引用是this?仍是其它?html

 

静态内部类:使用static修饰的内部类java

 

内部类:就是在某个类的内部又定义了一个类,内部类所嵌入的类称为外部类linux

 

匿名内部类:使用new生成的内部类android

 

由于内部类的产生依赖于外部类,持有的引用是类名.this算法

 

2.Java中try catch finally的执行顺序sql

 

先执行try中代码,若是发生异常执行catch中代码,最后必定会执行finally中代码数据库

 

3.equals与==的区别:数组

 

==是判断两个变量或实例是否是指向同一个内存空间 equals是判断两个变量或实例所指向的内存空间的值是否是相浏览器

 

4.Object有哪些公用方法?缓存

 

方法equals测试的是两个对象是否相等

 

方法clone进行对象拷贝

 

方法getClass返回和当前对象相关的Class对象

 

方法notify,notifyall,wait都是用来对给定对象进行线程同步的

 

5.String、StringBuffer与StringBuilder的区别

 

String 类型和 StringBuffer 类型的主要性能区别其实在于 String 是不可变的对象 StringBuffer和StringBuilder底层是 char[]数组实现的 StringBuffer是线程安全的,而StringBuilder是线程不安全的

 

6.Java的四种引用的区别

 

强引用:若是一个对象具备强引用,它就不会被垃圾回收器回收。即便当前内存空间不足,JVM 也不会回收它,而是抛出 OutOfMemoryError 错误,使程序异常终止。若是想中断强引用和某个对象之间的关联,能够显式地将引用赋值为null,这样一来的话,JVM在合适的时间就会回收该对象

 

软引用:在使用软引用时,若是内存的空间足够,软引用就能继续被使用,而不会被垃圾回收器回收,只有在内存不足时,软引用才会被垃圾回收器回收。

 

弱引用:具备弱引用的对象拥有的生命周期更短暂。由于当 JVM 进行垃圾回收,一旦发现弱引用对象,不管当前内存空间是否充足,都会将弱引用回收。不过因为垃圾回收器是一个优先级较低的线程,因此并不必定能迅速发现弱引用对象

 

虚引用:顾名思义,就是形同虚设,若是一个对象仅持有虚引用,那么它至关于没有引用,在任什么时候候均可能被垃圾回收器回收。

 

7.介绍垃圾回收机制

 

标记回收法:遍历对象图而且记录可到达的对象,以便删除不可到达的对象,通常使用单线程工做而且可能产生内存碎片

 

标记-压缩回收法:前期与第一种方法相同,只是多了一步,将全部的存活对象压缩到内存的一端,这样内存碎片就能够合成一大块可再利用的内存区域,提升了内存利用率

 

复制回收法:把现有内存空间分红两部分,gc运行时,它把可到达对象复制到另外一半空间,再清空正在使用的空间的所有对象。这种方法适用于短生存期的对象,持续复制长生存期的对象则致使效率下降。

 

分代回收发:把内存空间分为两个或者多个域,如年轻代和老年代,年轻代的特色是对象会很快被回收,所以在年轻代使用效率比较高的算法。当一个对象通过几回回收后依然存活,对象就会被放入称为老年的内存空间,老年代则采起标记-压缩算法

集合、数据结构相关

1.你用过哪些集合类

数据结构中用于存储数据的有哪些

数组

数组存储区间是连续的,占用内存严重,故空间复杂的很大。但数组的二分查找时间复杂度小,为O(1);数组的特色是:寻址容易,插入和删除困难;

链表

链表存储区间离散,占用内存比较宽松,故空间复杂度很小,但时间复杂度很大,达O(N)。链表的特色是:寻址困难,插入和删除容易。

2.说说hashMap是怎样实现的

哈希表:由数组+链表组成的

当咱们往HashMap中put元素的时候,先根据key的hashCode从新计算hash值,根据hash值获得这个元素在数组中的位置(即下标),若是数组该位置上已经存放有其余元素了,那么在这个位置上的元素将以链表的形式存放,新加入的放在链头,最早加入的放在链尾。若是数组该位置上没有元素,就直接将该元素放到此数组中的该位置上。

3.ArrayList,LinkedList的区别

ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。

对于随机访问get和set,ArrayList以为优于LinkedList,由于LinkedList要移动指针。

对于新增和删除操做add和remove,LinedList比较占优点,由于ArrayList要移动数据。

4.ArrayList和Vector的主要区别是什么?

ArrayList 和Vector底层是采用数组方式存储数据

Vector:

线程同步

当Vector中的元素超过它的初始大小时,Vector会将它的容量翻倍,

ArrayList:

线程不一样步,但性能很好

当ArrayList中的元素超过它的初始大小时,ArrayList只增长50%的大小

5.HashMap和 HashTable 的区别:

HashTable比较老,是基于Dictionary 类实现的,HashTable 则是基于 Map接口实现的

HashTable 是线程安全的, HashMap 则是线程不安全的

HashMap可让你将空值做为一个表的条目的key或value

 

算法相关

1.排序算法和稳定性,快排何时状况最坏?

2.给最外层的rootview,把这个根视图下的所有button背景设置成红色,手写代码,不准用递归

算法原理:

Android的view视图是按树形结构分布,因此按树形结构遍历

循环判断每一层的ViewGroup元素,将其入栈;不然判断当前view是不是Button类实例,是则改写背景色

当前ViewGroup检查childView完成后,判断栈是否非空,取出栈顶元素ViewGroup重复步骤2直至栈为空。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void changeAllBtnBGColor(View view, int color) {
if (view == null || !(view instanceof ViewGroup))
return ;
Stack m = new Stack<>();
while (view != null ) {
ViewGroup tmpGroup = (ViewGroup) view;
int count = tmpGroup.getChildCount();
for ( int i = 0 ; i < count; i++) { View child = tmpGroup.getChildAt(i);
if (child instanceof ViewGroup) m.add(child);
else if (child instanceof Button) { child.setBackgroundColor(color);
} }
if (m.isEmpty()) break ;
else view = m.pop();
}
}

Thread、AsynTask相关

1.wait()和sleep()的区别

sleep来自Thread类,和wait来自Object类

调用sleep()方法的过程当中,线程不会释放对象锁。而 调用 wait 方法线程会释放对象锁

sleep睡眠后不出让系统资源,wait让出系统资源其余线程能够占用CPU

sleep(milliseconds)须要指定一个睡眠时间,时间一到会自动唤醒

2.若Activity已经销毁,此时AsynTask执行完而且返回结果,会报异常吗?

当一个App旋转时,整个Activity会被销毁和重建。当Activity重启时,AsyncTask中对该Activity的引用是无效的,所以onPostExecute()就不会起做用,若AsynTask正在执行,折会报 view not attached to window manager 异常

一样也是生命周期的问题,在 Activity 的onDestory()方法中调用Asyntask.cancal方法,让两者的生命周期同步

3.Activity销毁但Task若是没有销毁掉,当Activity重启时这个AsyncTask该如何解决?

仍是屏幕旋转这个例子,在重建Activity的时候,会回掉Activity.onRetainNonConfigurationInstance()从新传递一个新的对象给AsyncTask,完成引用的更新

4.Android 线程间通讯有哪几种方式(重要)

共享内存(变量);

文件,数据库;

Handler;

Java 里的 wait(),notify(),notifyAll()

5.请介绍下 AsyncTask的内部实现,适用的场景是

AsyncTask 内部也是 Handler 机制来完成的,只不过 Android 提供了执行框架来提供线程池来

执行相应地任务,由于线程池的大小问题,因此 AsyncTask 只应该用来执行耗时时间较短的任务,

好比 HTTP 请求,大规模的下载和数据库的更改不适用于 AsyncTask,由于会致使线程池堵塞,没有

线程来执行其余的任务,致使的情形是会发生 AsyncTask 根本执行不了的问题。

网络相关

1.TCP三次握手

2.为何TCP是可靠的,UDP早不可靠的?为何UDP比TCP快?

TCP/IP协议高,由于其拥有三次握手双向机制,这一机制保证校验了数据,保证了他的可靠性。

UDP就没有了,udp信息发出后,不验证是否到达对方,因此不可靠。

可是就速度来讲,仍是UDP协议更高,毕竟其无需重复返回验证,只是一次性的

3.http协议了解多少,说说里面的协议头部有哪些字段?

http(超文本传输协议)是一个基于请求与响应模式的、无状态的、应用层的协议;http请求由三部分组成,分别是:请求行、消息报头、请求正文。

HTTP消息报头包括普通报头、请求报头、响应报头、实体报头

4.https了解多少

HTTPS(全称:Hyper Text Transfer Protocol over Secure Socket Layer),是以安全为目标的HTTP通道,简单讲是HTTP的安全版。即HTTP下加入SSL层,HTTPS的安全基础是SSL,所以加密的详细内容就须要SSL。

5.谈谈 HTTP 中Get 和 Post 方法的区别

GET - 从指定的服务器中获取数据,明文发送内容

POST - 提交数据给指定的服务器处理

1. POST请求不能被缓存下来

2. POST请求不会保存在浏览器浏览记录中

3. 以POST请求的URL没法保存为浏览器书签

4. POST请求没有长度限制

6.推送心跳包是TCP包仍是UDP包或者HTTP包

心跳包的实现是调用了socket.sendUrgentData(0xFF)这句代码实现的,因此,固然是TCP包。

7.如何实现文件断点上传

在 Android 中上传文件能够采用 HTTP 方式,也能够采用 Socket 方式,可是 HTTP 方式不能上传

大文件,这里介绍一种经过 Socket 方式来进行断点续传的方式,服务端会记录下文件的上传进度,

当某一次上传过程意外终止后,下一次能够继续上传,这里用到的其实仍是 J2SE 里的知识。

这个上传程序的原理是:客户端第一次上传时向服务端发送

“Content-Length=35;filename=WinRAR_3.90_SC.exe;sourceid=“这种格式的字符串,服务端

收到后会查找该文件是否有上传记录,若是有就返回已经上传的位置,不然返回新生成的 sourceid

以及 position 为 0,相似 sourceid=2324838389;position=0“这样的字符串,客户端收到返回后

的字符串后再从指定的位置开始上传文件。

Fragment相关

1.Fragment 如何实现相似 Activity 栈的压栈和出栈效果的?

Fragment 的事物管理器内部维持了一个双向链表结构,该结构能够记录咱们每次 add 的

Fragment 和 replace 的 Fragment,而后当咱们点击 back 按钮的时候会自动帮咱们实现退栈操做。

2.Fragment 在大家项目中的使用

Fragment 是 android3.0 之后引入的的概念,作局部内容更新更方便,原来为了到达这一点要

把多个布局放到一个 activity 里面,如今能够用多 Fragment 来代替,只有在须要的时候才加载

Fragment,提升性能。

Fragment 的好处:

1. Fragment 可使你可以将 activity 分离成多个可重用的组件,每一个都有它本身的生命周期和

UI。

2. Fragment 能够轻松得建立动态灵活的 UI 设计,能够适应于不一样的屏幕尺寸。从手机到平板电

脑。

3. Fragment 是一个独立的模块,牢牢地与 activity 绑定在一块儿。能够运行中动态地移除、加入、

交换等。

4. Fragment 提供一个新的方式让你在不一样的安卓设备上统一你的 UI。

5. Fragment 解决 Activity 间的切换不流畅,轻量切换。

6. Fragment 替代 TabActivity 作导航,性能更好。

7. Fragment 在 4.2.版本中新增嵌套 fragment 使用方法,可以生成更好的界面效果

3.如何切换 fragement,不从新实例化

正确的切换方式是 add(),切换时 hide(),add()另外一个 Fragment;再次切换时,只需 hide()当前,

show()另外一个

四大组件相关

1.Activity和Fragment生命周期有哪些?

Activity——onCreate->onStart->onResume->onPause->onStop->onDestroy

Fragment——onAttach->onCreate->onCreateView->onActivityCreated->onStart->onResume->onPause->onStop->onDestroyView->onDestroy->onDetach

2.广播的两种注册方式及有什么区别

3.内存不足时,怎么保持Activity的一些状态,在哪一个方法里面作具体操做?

Activity的 onSaveInstanceState() 和 onRestoreInstanceState()并非生命周期方法,它们不一样于 onCreate()、onPause()等生命周期方法,它们并不必定会被触发。当应用遇到意外状况(如:内存不足、用户直接按Home键)由系统销毁一个Activity,onSaveInstanceState() 会被调用。可是当用户主动去销毁一个Activity时,例如在应用中按返回键,onSaveInstanceState()就不会被调用。除非该activity是被用户主动销毁的,一般onSaveInstanceState()只适合用于保存一些临时性的状态,而onPause()适合用于数据的持久化保存。

4.启动service的两种方法?有什么区别?

一种是startService(),另外一种是bindService()。这二者的区别是第一种方式调用者开启了服务,即会与服务失去联系,二者没有关联。即便访问者退出了,服务仍在运行。如需解除服务必须显式的调用stopService方法。主要用于调用者与服务没有交互的状况下,也就是调用者不须要获取服务里的业务方法。好比电话录音。然后者调用者与服务绑定在一块儿的。当调用者退出的时候,服务也随之退出。用于须要与服务交互。

5.Android中的Context, Activity,Appliction有什么区别?

相同:Activity和Application都是Context的子类。

Context从字面上理解就是上下文的意思,在实际应用中它也确实是起到了管理上下文环境中各个参数和变量的总用,方便咱们能够简单的访问到各类资源。

不一样:维护的生命周期不一样。 Context维护的是当前的Activity的生命周期,Application维护的是整个项目的生命周期。

使用context的时候,当心内存泄露,防止内存泄露,注意一下几个方面:

1. 不要让生命周期长的对象引用activity context,即保证引用activity的对象要与activity自己生命周期是同样的。

2. 对于生命周期长的对象,可使用application,context。

3. 避免非静态的内部类,尽可能使用静态类,避免生命周期问题,注意内部类对外部对象引用致使的生命周期变化。

6.Context是什么?

它描述的是一个应用程序环境的信息,即上下文。

该类是一个抽象(abstract class)类,Android提供了该抽象类的具体实现类(ContextIml)。

经过它咱们能够获取应用程序的资源和类,也包括一些应用级别操做,例如:启动一个Activity,发送广播,接受Intent,信息,等。

7.Service 是否在 main thread 中执行, service 里面是否能执行耗时的操

做?

默认状况,若是没有显示的指 servic 所运行的进程, Service 和 activity 是运行在当前 app 所在进

程的 main thread(UI 主线程)里面。

service 里面不能执行耗时的操做(网络请求,拷贝数据库,大文件 )

 

特殊状况 ,能够在清单文件配置 service 执行所在的进程 ,让 service 在另外的进程中执行
 

?
1
2
3
4
5
<service
android:name= "com.baidu.location.f"
android:enabled= "true"
android:process= ":remote" >
</service>

 

8.Activity 怎么和 Service 绑定,怎么在 Activity 中启动本身对应的

Service?

Activity 经过 bindService(Intent service, ServiceConnection conn, int flags)跟 Service 进行

绑定,当绑定成功的时候 Service 会将代理对象经过回调的形式传给 conn,这样咱们就拿到了

Service 提供的服务代理对象。

在 Activity 中能够经过 startService 和 bindService 方法启动 Service。通常状况下若是想获取

Service 的服务对象那么确定须要经过 bindService()方法,好比音乐播放器,第三方支付等。如

果仅仅只是为了开启一个后台任务那么可使用 startService()方法。

9.说说 Activity、Intent、Service 是什么关系

他们都是 Android 开发中使用频率最高的类。其中 Activity 和 Service 都是 Android 四大组件

之一。他俩都是 Context 类的子类 ContextWrapper 的子类,所以他俩能够算是兄弟关系吧。不过

兄弟俩各有各自的本领,Activity 负责用户界面的显示和交互,Service 负责后台任务的处理。Activity

和 Service 之间能够经过 Intent 传递数据,所以能够把 Intent 看做是通讯使者。

10.请描述一下 BroadcastReceiver

BroadCastReceiver 是 Android 四大组件之一,主要用于接收系统或者 app 发送的广播事件。

广播分两种:有序广播和无序广播。

内部通讯实现机制:经过 Android 系统的 Binder 机制实现通讯。

1. 无序广播:彻底异步,逻辑上能够被任何广播接收者接收到。优势是效率较高。缺点是一个接收者不

能将处理结果传递给下一个接收者,并没有法终止广播 intent 的传播。

2. 有序广播:按照被接收者的优先级顺序,在被接收者中依次传播。好比有三个广播接收者 A,B,C,

优先级是 A > B > C。那这个消息先传给 A,再传给 B,最后传给 C。每一个接收者有权终止广播,比

如 B 终止广播,C 就没法接收到。此外 A 接收到广播后能够对结果对象进行操做,当广播传给 B 时,

B 能够从结果对象中取得 A 存入的数据。

在经过 Context.sendOrderedBroadcast(intent, receiverPermission, resultReceiver, scheduler,

initialCode, initialData, initialExtras)时咱们能够指定 resultReceiver 广播接收者,这个接收者咱们

能够认为是最终接收者,一般状况下若是比他优先级更高的接收者若是没有终止广播,那么他的

onReceive 会被执行两次,第一次是正常的按照优先级顺序执行,第二次是做为最终接收者接收。

若是比他优先级高的接收者终止了广播,那么他依然能接收到广播

11.为何要用 ContentProvider?它和 sql 的实现上有什么差异?

ContentProvider 屏蔽了数据存储的细节,内部实现对用户彻底透明,用户只须要关心操做数据的

uri 就能够了,ContentProvider 能够实现不一样 app 之间共享。

Sql 也有增删改查的方法,可是 sql 只能查询本应用下的数据库。而 ContentProvider 还可

以去增删改查本地文件. xml 文件的读取等。

12.说说 ContentProvider、ContentResolver、ContentObserver 之间的关系

a. ContentProvider 内容提供者,用于对外提供数据

b. ContentResolver.notifyChange(uri)发出消息

c. ContentResolver 内容解析者,用于获取内容提供者提供的数据

d. ContentObserver 内容监听器,能够监听数据的改变状态

e. ContentResolver.registerContentObserver()监听消息。

View 相关

1.onInterceptTouchEvent()和onTouchEvent()的区别

onInterceptTouchEvent()用于拦截触摸事件

onTouchEvent()用于处理触摸事件

2.RemoteView在哪些功能中使用

APPwidget和Notification中

3. SurfaceView和View的区别是什么?

SurfaceView中采用了双缓存技术,在单独的线程中更新界面

View在UI线程中更新界面

4.View的绘制过程

一个View要显示在界面上,须要经历一个View树的遍历过程,这个过程又能够分为三个过程,也就是自定义View中的三要素:大小,位置,画什么,即onMesure(),onLayout(),onDraw()。

1.onMesure()肯定一个View的大小;

2.onLayout()肯定View在父节点上的位置;

3.onDraw()绘制View 的内容;

5.如何自定义ViewGroup

1.指定的LayoutParams

2.onMeasure中计算全部childView的宽和高,而后根据childView的宽和高,计算本身的宽和高。(固然,若是不是wrap_content,直接使用父ViewGroup传入的计算值便可)

3.onLayout中对全部的childView进行布局。

6.View中onTouch,onTouchEvent,onClick的执行顺序

dispatchTouchEvent—->onTouch—->onTouchEvent—–>onClick。在全部ACTION_UP事件以后才触发onClick点击事件。

性能优化相关

1.ListView卡顿的缘由与性能优化,越多越好

重用converView: 经过复用converview来减小没必要要的view的建立,另外Infalte操做会把xml文件实例化成相应的View实例,属于IO操做,是耗时操做。

减小findViewById()操做: 将xml文件中的元素封装成viewholder静态类,经过converview的setTag和getTag方法将view与相应的holder对象绑定在一块儿,避免没必要要的findviewbyid操做

避免在 getView 方法中作耗时的操做: 例如加载本地 Image 须要载入内存以及解析 Bitmap ,都是比较耗时的操做,若是用户快速滑动listview,会由于getview逻辑过于复杂耗时而形成滑动卡顿现象。用户滑动时候不要加载图片,待滑动完成再加载,可使用这个第三方库glide

Item的布局层次结构尽可能简单,避免布局太深或者没必要要的重绘

尽可能能保证 Adapter 的 hasStableIds() 返回 true 这样在 notifyDataSetChanged() 的时候,若是item内容并无变化,ListView 将不会从新绘制这个 View,达到优化的目的

在一些场景中,ScollView内会包含多个ListView,能够把listview的高度写死固定下来。 因为ScollView在快速滑动过程当中须要大量计算每个listview的高度,阻塞了UI线程致使卡顿现象出现,若是咱们每个item的高度都是均匀的,能够经过计算把listview的高度肯定下来,避免卡顿现象出现

使用 RecycleView 代替listview: 每一个item内容的变更,listview都须要去调用notifyDataSetChanged来更新所有的item,太浪费性能了。RecycleView能够实现当个item的局部刷新,而且引入了增长和删除的动态效果,在性能上和定制上都有很大的改善

ListView 中元素避免半透明: 半透明绘制须要大量乘法计算,在滑动时不停重绘会形成大量的计算,在比较差的机子上会比较卡。 在设计上能不半透明就不不半透明。实在要弄就把在滑动的时候把半透明设置成不透明,滑动完再从新设置成半透明。

尽可能开启硬件加速: 硬件加速提高巨大,避免使用一些不支持的函数致使含泪关闭某个地方的硬件加速。固然这一条不仅是对 ListView。

2.如何避免 OOM 问题的出现

使用更加轻量的数据结构 例如,咱们能够考虑使用ArrayMap/SparseArray而不是HashMap等传统数据结构。一般的HashMap的实现方式更加消耗内存,由于它须要一个额外的实例对象来记录Mapping操做。另外,SparseArray更加高效,在于他们避免了对key与value的自动装箱(autoboxing),而且避免了装箱后的解箱。

避免在Android里面使用Enum Android官方培训课程提到过“Enums often require more than twice as much memory as static constants. You should strictly avoid using enums on Android.”,具体原理请参考《Android性能优化典范(三)》,因此请避免在Android里面使用到枚举。

减少Bitmap对象的内存占用 Bitmap是一个极容易消耗内存的大胖子,减少建立出来的Bitmap的内存占用可谓是重中之重,,一般来讲有如下2个措施: ++inSampleSize++:缩放比例,在把图片载入内存以前,咱们须要先计算出一个合适的缩放比例,避免没必要要的大图载入。 ++decode format++:解码格式,选择ARGB_6666/RBG_545/ARGB_4444/ALPHA_6,存在很大差别

Bitmap对象的复用 缩小Bitmap的同时,也须要提升BitMap对象的复用率,避免频繁建立BitMap对象,复用的方法有如下2个措施 LRUCache : “最近最少使用算法”在Android中有极其广泛的应用。ListView与GridView等显示大量图片的控件里,就是使用LRU的机制来缓存处理好的Bitmap,把近期最少使用的数据从缓存中移除,保留使用最频繁的数据, inBitMap高级特性:利用inBitmap的高级特性提升Android系统在Bitmap分配与释放执行效率。使用inBitmap属性能够告知Bitmap解码器去尝试使用已经存在的内存区域,新解码的Bitmap会尝试去使用以前那张Bitmap在Heap中所占据的pixel data内存区域,而不是去问内存从新申请一块区域来存放Bitmap。利用这种特性,即便是上千张的图片,也只会仅仅只须要占用屏幕所可以显示的图片数量的内存大小

使用更小的图片 在涉及给到资源图片时,咱们须要特别留意这张图片是否存在能够压缩的空间,是否可使用更小的图片。尽可能使用更小的图片不只能够减小内存的使用,还能避免出现大量的InflationException。假设有一张很大的图片被XML文件直接引用,颇有可能在初始化视图时会由于内存不足而发生InflationException,这个问题的根本缘由实际上是发生了OOM。

StringBuilder 在有些时候,代码中会须要使用到大量的字符串拼接的操做,这种时候有必要考虑使用StringBuilder来替代频繁的“+”。

避免在onDraw方法里面执行对象的建立 相似onDraw等频繁调用的方法,必定须要注意避免在这里作建立对象的操做,由于他会迅速增长内存的使用,并且很容易引发频繁的gc,甚至是内存抖动。

避免对象的内存泄露

3.三级缓存的原理

从缓存中加载。

从本地文件中加载(数据库,SD)

从网络加载。

a.加载 bitmap 的时候无需考虑 bitmap 加载过程当中出现的 oom(内存溢出)和 android 容器快速

滑动的时候出现的图片错位等现象。(16M)

b. 支持加载网络图片和本地图片。

c. 内存管理使用的 lru 算法(移除里面是有频率最少的对象),更好的管理 bitmap 的内存

Android其余

1.讲一下android中进程的优先级?

前台进程

可见进程

服务进程

后台进程

空进程

2.介绍Handle的机制

Handler经过调用sendmessage方法把消息放在消息队列MessageQueue中,Looper负责把消息从消息队列中取出来,从新再交给Handler进行处理,三者造成一个循环

经过构建一个消息队列,把全部的Message进行统一的管理,当Message不用了,并不做为垃圾回收,而是放入消息队列中,供下次handler建立消息时候使用,提升了消息对象的复用,减小系统垃圾回收的次数

每个线程,都会单独对应的一个looper,这个looper经过ThreadLocal来建立,保证每一个线程只建立一个looper,looper初始化后就会调用looper.loop建立一个MessageQueue,这个方法在UI线程初始化的时候就会完成,咱们不须要手动建立

3.Dalvik虚拟机与JVM有什么区别

Dalvik 基于寄存器,而 JVM 基于栈。基于寄存器的虚拟机对于更大的程序来讲,在它们编译的时候,花费的时间更短。

Dalvik执行.dex格式的字节码,而JVM执行.class格式的字节码。

4.每一个应用程序对应多少个Dalvik虚拟机

每个Android应用在底层都会对应一个独立的Dalvik虚拟机实例,其代码在虚拟机的解释下得以执行 ,而全部的Android应用的线程都对应一个Linux线程

5.应用常驻后台,避免被第三方杀掉的方法

Service设置成START_STICKY kill 后会被重启(等待5秒左右),重传Intent,保持与重启前同样

经过 startForeground将进程设置为前台进程, 作前台服务,优先级和前台应用一个级别,除非在系统内存很是缺,不然此进程不会被 kill

双进程Service: 让2个进程互相保护对方,其中一个Service被清理后,另外没被清理的进程能够当即重启进程

用C编写守护进程(即子进程) : Android系统中当前进程(Process)fork出来的子进程,被系统认为是两个不一样的进程。当父进程被杀死的时候,子进程仍然能够存活,并不受影响(Android5.0以上的版本不可行

联系厂商,加入白名单

6.根据本身的理解描述下Android数字签名。

全部的应用程序都必须有数字证书,Android系统不会安装一个没有数字证书的应用程序

Android程序包使用的数字证书能够是自签名的,不须要一个权威的数字证书机构签名认证

若是要正式发布一个Android程序,必须使用一个合适的私钥生成的数字证书来给程序签名,而不能使用adt插件或者ant工具生成的调试证书来发布。

数字证书都是有有效期的,Android只是在应用程序安装的时候才会检查证书的有效期。若是程序已经安装在系统中,即便证书过时也不会影响程序的正常功能。

7.Dalvik基于JVM的改进

几个class变为一个dex,constant pool,省内存

Zygote,copy-on-write shared,省内存,省cpu,省电

基于寄存器的bytecode,省指令,省cpu,省电

Trace-based JIT,省cpu,省电,省内存

8.ARGB_8888占用内存大小

本题的答案,是4byte,即ARGB各占用8个比特来描述。

9.apk安装卸载的原理

安装过程:复制apk安装包到data/app目录下,解压并扫描安装包,把dex文件(dalvik字节码)保存到dalvik-cache目录,并data/data目录下建立对应的应用数据目录。

卸载过程:删除安装过程当中在上述三个目录下建立的文件及目录。

10.经过Intent传递一些二进制数据的方法有哪些?

使用Serializable接口实现序列化,这是Java经常使用的方法。

实现Parcelable接口,这里Android的部分类好比Bitmap类就已经实现了,同时Parcelable在Android AIDL中交换数据也很常见的。

11.横竖屏切换时Activity的生命周期

此时的生命周期跟清单文件里的配置有关系。

不设置Activity的android:configChanges时,切屏会从新调用各个生命周期默认首先销毁当前activity,而后从新加载。

设置Activity android:configChanges=”orientation|keyboardHidden|screenSize”时,切屏不会从新调用各个生命周期,只会执行onConfigurationChanged方法

12.Serializable 和 Parcelable 的区别

在使用内存的时候,Parcelable 类比 Serializable 性能高,因此推荐使用 Parcelable 类。

1. Serializable 在序列化的时候会产生大量的临时变量,从而引发频繁的 GC。

2. Parcelable 不能使用在要将数据存储在磁盘上的状况。尽管 Serializable 效率低点,但在这

种状况下,仍是建议你用 Serializable 。

13.Android 中如何捕获未捕获的异常

自 定 义 一 个 Application , 比 如 叫 MyApplication 继 承 Application 实 现

UncaughtExceptionHandler。

覆写 UncaughtExceptionHandler 的 onCreate 和 uncaughtException 方法。

14.Android 的权限规则

Android 中的 apk 必须签名

基于 UserID 的进程级别的安全机制

默认 apk 生成的数据对外是不可见的

AndroidManifest.xml 中的显式权限声明

15.多线程间通讯和多进程之间通讯有什么不一样,分别怎么实现?

1、进程间的通讯方式

1. 管道( pipe ):管道是一种半双工的通讯方式,数据只能单向流动,并且只能在具备亲缘关系的

进程间使用。进程的亲缘关系一般是指父子进程关系。

2. 有名管道 (namedpipe) : 有名管道也是半双工的通讯方式,可是它容许无亲缘关系进程间的

通讯。

3. 信号量(semophore ) : 信号量是一个计数器,能够用来控制多个进程对共享资源的访问。它

常做为一种锁机制,防止某进程正在访问共享资源时,其余进程也访问该资源。所以,主要做为进

程间以及同一进程内不一样线程之间的同步手段。

4. 消息队列( messagequeue ) : 消息队列是由消息的链表,存放在内核中并由消息队列标识符

标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。

5. 信号 (sinal ) : 信号是一种比较复杂的通讯方式,用于通知接收进程某个事件已经发生。

6. 共享内存(shared memory ) :共享内存就是映射一段能被其余进程所访问的内存,这段共享内

存由一个进程建立,但多个进程均可以访问。共享内存是最快的 IPC 方式,它是针对其余进程间

通讯方式运行效率低而专门设计的。它每每与其余通讯机制,如信号两,配合使用,来实现进程间

的同步和通讯。

7. 套接字(socket ) : 套解口也是一种进程间通讯机制,与其余通讯机制不一样的是,它可用于不一样

及其间的进程通讯。

2、线程间的通讯方式

1. 锁机制:包括互斥锁、条件变量、读写锁

*互斥锁提供了以排他方式防止数据结构被并发修改的方法。

*读写锁容许多个线程同时读共享数据,而对写操做是互斥的。

*条件变量能够以原子的方式阻塞进程,直到某个特定条件为真为止。对条件的测试是在互斥锁

的保护下进行的。条件变量始终与互斥锁一块儿使用。

2. 信号量机制(Semaphore):包括无名线程信号量和命名线程信号量

3. 信号机制(Signal):相似进程间的信号处理

线程间的通讯目的主要是用于线程同步,因此线程没有像进程通讯中的用于数据交换的通讯机

制。

16.说说 LruCache 底层原理

LruCache 使用一个 LinkedHashMap 简单的实现内存的缓存,没有软引用,都是强引用。若是添

加的数据大于设置的最大值,就删除最早缓存的数据来调整内存。

maxSize 是经过构造方法初始化的值,他表示这个缓存能缓存的最大值是多少。

size 在添加和移除缓存都被更新值,他经过 safeSizeOf 这个方法更新值。safeSizeOf 默认返回 1,

但通常咱们会根据 maxSize 重写这个方法,好比认为 maxSize 表明是 KB 的话,那么就以 KB 为单

位返回该项所占的内存大小。

除异常外首先会判断 size 是否超过 maxSize,若是超过了就取出最早插入的缓存,若是不为空就

删掉,并把 size 减去该项所占的大小。这个操做将一直循环下去,直到 size 比 maxSize 小或者缓存

为空。

相关文章
相关标签/搜索