Android简单的面试题

选择题

1.activity对一些资源以及状态的操作保存,最好是保存在生命周期的哪个函数中进行( a )

a.onPause()  b.onCreate()  c.onStop()  d.onResume()

2.我们都知道Hanlder是线程与Activity通信的桥梁,如果线程处理不当,你的机器就会变得越慢,那么线程销毁的方法是( a )

a.onDestroy()  b.onClear()  c.onStop()  d.onFinish()

3.下面退出Activity错误的方法是(c)

a.finish()  b.抛异常强制退出  c.System.exit()  d.onStop()

4.下面关于Android dvm的进程和Linux的进程,应用程序的进程说法正确的是(d)

a.DVM指dalivk的虚拟机.每一个Android应用程序都在它自己的进程中运行,不一定拥有一个独立 的Dalvik虚拟机实例.而每一个DVM都是在Linux 中的一个进程,所以说可以认为是同一个概念.

b.DVM指dalivk的虚拟机.每一个Android应用程序都在它自己的进程中运行,不一定拥有一个独立的Dalvik虚拟机实例.而每一个DVM不一定都是在Linux 中的一个进程,所以说不是一个概念.

c.DVM指dalivk的虚拟机.每一个Android应用程序都在它自己的进程中运行,都拥有一个独立的Dalvik虚拟机实例.而每一个DVM不一定都是在Linux 中的一个进程,所以说不是一个概念.

d.DVM指dalivk的虚拟机.每一个Android应用程序都在它自己的进程中运行,都拥有一个独立的 Dalvik虚拟机实例.而每一个DVM都是在Linux 中的一个进程,所以说可以认为是同一个概念.

5.下面异常是属于Runtime Exception 的是(abcd)(多选)

a.ArithmeticException  b.IllegalArgumentException  c.NullPointerException  d.BufferUnderflowException

6.下列哪些语句关于内存回收的说明正确的是(b)

a.程序员必须创建一个线程来释放内存  
b.内存回收程序负责释放无用内存

c.内存回收程序允许程序员直接释放内存  
d.内存回收程序可以在指定的时间释放内存对象

7. android 中下列属于Intent的作用的是(c)

a.实现应用程序间的数据共享

b.是一段长的生命周期,没有用户界面的程序,可以保持应用在后台运行,而不会因为切换页面而消失

c.可以实现界面间的切换,可以包含动作和动作数据,连接四大组件的纽带

d.处理一个应用程序整体性的工作

8.在android中使用Menu时可能需要重写的方法有(ac)(多选)

a.onCreateOptionsMenu()  b.onCreateMenu()  
c.onOptionsItemSelected()  d.onItemSelected()

9.android 关于service生命周期的onCreate()和onStart()说法正确的是(ad)(多选)

a.当第一次启动的时候先后调用onCreate()和onStart()方法

b.当第一次启动的时候只会调用onCreate()方法

c.如果service已经启动,将先后调用onCreate()和onStart()方法

d.如果service已经启动,只会执行onStart()方法,不在执行onCreate()方法

10.下面属于android的动画分类的有(ab)(多项)

a.Tween   b.Frame   c.Draw   d.Animation

11.Android项目工程下面的assets目录的作用是什么 (b)

a.放置应用到的图片资源  b.主要放置多媒体等数据文件

c.放置字符串,颜色,数组等常量数据  d.放置一些与UI相应的布局文件,都是xml文件

12.关于res/raw目录说法正确的是 (a)

a.这里的文件是原封不动的存储到设备上不会转换为二进制的格式

b.这里的文件是原封不动的存储到设备上会转换为二进制的格式

c.这里的文件最终以二进制的格式存储到指定的包中

d.这里的文件最终不会以二进制的格式存储到指定的包中

填空题

问答题

1.本地广播和全局广播有什么差别?

a.本地广播只在app内部传递,不会泄漏给其他app,隐私保护的很好

b.其他app也无法向你传递该广播,不用担心其他app来搞破坏

c.相对于全局广播,本地广播更加高效

//本地广播
  LocalBroadcastManager instance = LocalBroadcastManager.getInstance(this);
    instance.registerReceiver(new BroadcastReceiver() {
      @Override
      public void onReceive(Context context, Intent intent) {

      }
    }, new IntentFilter("wangzhong"));
    instance.sendBroadcast(new Intent("wangzhong"));

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

a.可以发送特定广播,在需要结束应用的时候,发送特定的广播。每个Activity收到广播之后,关闭即可

b.递归退出,记录你打开的每个activity,在退出的时候,关闭每一个activity即可

3.如何优化自定义view?

a.首先,你得代码得规范,对于频繁调用的方法,尽量减少不必要的代码。

b.其次,数据初始化,尽量不要在ondraw里面,放在构造方法里面

c.接着,在调用invalidate()方法的时候,尽量少调用无参的,无参的是整个view更新,能调用4个参数的局部更新的方法就调用局部更新

4.Android 中布局的优化措施都有哪些?

a.尽量减少布局嵌套层级

b.尽量不要设置没必要的背景

c.使用include标签复用相同布局的代码

d.使用merge标签减少视图层次结构

5.请描述事件分发机制?

a.首先,分三个方法:负责分发的dispatch方法,负责拦截的onIntercept方法,负责处理逻辑的onTouchEvent方法。

b.其次,就是整个流程是一个责任链模式。谁能处理,谁的拦截方法返回true就拦截下来,在ontouch方法里面处理逻辑。

c.接着,总共有五层activity,phoneView,DecorViw,viewGroup,View就是activity作为初始点,他没有拦截方法,要么分发,要么处理。view作为终点,他没有分发,没有拦截方法。我们一般处理逻辑,没有第二层,没有第三层,一般都是activity,viewGroup,View。

d.我们刚也说了,责任链模式,一层一层往下传递,传到View,如果,都不处理,那么就会一层一层往回传,传到activity,activity也不处理,辣么就会抛弃这个事件。

6.请简述activity有哪几种启动模式以及它们之间的区别

四种启动模式:Standard,SingleTop,SingleTask,SingleInstance

Standard模式: 默认模式,也是标准模式,如果不特意注明启动方式就是该方式,他每次启动都是新建一个新的activity,并加入activity栈中。都会重新走activity的生命周期

SingleTop模式: 栈顶复用模式。

a.如果栈中不存在启动的activity,或者栈顶的那个ativity并不是你要启动的activity,辣么,此时SingleTop模式启动的activity的启动方式和standard一样,都是重新创建实例,走onCreate,onStart方法。

b.如果栈顶的那个activity和你需要启动的activity相同,辣么,就会复用栈顶的那个activity,不会新建实例也就不会走onCreate,onStart方法了,走onNewIntent方法

SingleTask: 栈内复用模式。

我们先说一个属性:taskAffinity,表面意思:任务相关性。我的理解就是Activity任务栈的代号。为什么要先说这个属性呢?栈内复用模式跟这个属性有关,前面两种:标准,栈顶复用,这个属性不论你指不指定都是一样的。每一个activity启动都会在一个activity任务栈里面。还有一个要说明的是,栈遵循的原则是先进后出原则,也就是先启动的activity位于栈底,后启动的位于栈顶

a.先说没有指定了taskAffinity属性,也就是启动的activity在同一个任务栈里面。当你启动一个activity,如果这个activity不存在,则新建,并入栈。如果存在,不管是不是位于栈顶,都走onNewIntent,然后把该activity上面的activity都移除栈,使该activity位于栈顶

b.如果指定的taskAffinity属性,他会先找有没有这个任务栈,如果没有就新建,如果有,就找需要启动的activity在那个栈中有没有,没有就新建,有就走onNewIntent,然后把该activity上面的activity都移除栈,使该activity位于栈顶

ps:不同的app,启动的activity可以在同一个任务栈中

singleInstance 全局唯一模式。

它具有栈内复用模式的特性。唯一区别就是:activity会单独占用一个线程,后面用该模式启动的activity都会复用第一个用这个模式启动的activity的onNewIntent方法。可以理解为:这个模式在activity系统中具有全局唯一性

7.简述Activity的生命周期

a.首先,七个生命周期:onCreate(),onStart(),onResume(),onPause(),onStop(),onDestory(),onRestart()

b.启动顺序:onCreate()->onStart()->onResume()

c.销毁顺序:onPause()->onStop()->onDestory()

d.当activity已经存在,重新进入,走的方法:onPause()->onRestart()->onStart()->onResume()

e.activity可见,但是不能与用户交互,处于:onStart()
activity可见并且可以与用户交互,处于:onResume(),此时,获取焦点

8.Fragment生命周期

a.首先,生命周期:onAttach(),onCreate(),onCreateView(),onActivityCreate(),onStart(),onResume(),onPause(),onStop(),onDestroyView(),onDestroy(),onDetach()。需要知道的一点就是:Fragment是依附于Activity存在的。

b.启动顺序:onAttach(),onCreate(),onCreateView(),onActivityCreate(),onStart(),onResume()

c.销毁顺序:,onPause(),onStop(),onDestroyView(),onDestroy(),onDetach()

d.重新打开:onStart(),onResume()

e.按home键:onPause(),onStop()

f.在Activity中加入Fragment,对应的生命周期:

1.打开

Fragment onCreate() 方法执行!

Fragment onCreateView() 方法执行!

Activity onCreate() 方法执行!

Fragment onActivityCreated() 方法执行!

Activity onStart() 方法执行!

Fragment onStart() 方法执行!

Activity onResume() 方法执行!

Fragment onResume() 方法执行!

2.销毁

Fragment onPause() 方法执行!

Activity onPause() 方法执行!

Fragment onStop() 方法执行!

Activity onStop() 方法执行!

Fragment onDestroyView() 方法执行!

Fragment onDestroy() 方法执行!

Fragment onDetach() 方法执行!

Activity onDestroy() 方法执行!

3.重新打开

Activity onRestart() 方法执行!

Activity onStart() 方法执行!

Fragment onStart() 方法执行!

Activity onResume() 方法执行!

Fragment onResume() 方法执行!

4.按home键

Fragment onPause() 方法执行!

Activity onPause() 方法执行!

Fragment onStop() 方法执行!

Activity onStop() 方法执行!

9.Android进程保活机制
a.一像素保活机制(QQ就是这种办法),监听锁屏广播,在锁屏的时候注册广播,并且启动一个像素大小的activity,解开屏幕的时候,关闭即可。考虑到app占用内存越大,也就越先被杀死。我们可以把上面说到的逻辑丢到一个服务里面,在MainActivity里面启动这个服务即可。也是这个原理就是前台进程不会优先被杀死,只是,我们前台用户看不到,只有1个像素

b.相互唤醒机制,开启两个进程服务,服务A唤醒服务B,服务B唤醒服务A。

c.设置onStartCommand方法的返回值为:START_STICKY,当服务被杀死后,系统将会重新创建服务,并依次调用onCreate,onStartCommand方法

10.图片压缩

a、大小压缩,根据图片的宽高,按照需要的比例压缩

b、质量压缩,通过设置bitmap.compress里面的quality的值,范围0-100。越小,图片大小越小。png是无损图片,无法进行质量压缩

c、ARGB-8888转成ARGB-565,ARGB-8888一个像素占8+8+8+8=32位,4个字节,ARGB-565一个像素占5+6+5=16位,2个字节。

11.简述android存储数据的方式有哪些以及他们的适用范围?SharePreference的存储流程

a、file存储,也就是I/O存储,适用于存储大容量的数据

b、ContentProvider,是所有应用程序之间数据存储和检索的一个桥梁,他的作用就是使得各个应用程序之间实现数据共享

c、SQLite数据库存储,支持SQL语句,增删改查

d、SharePreference存储数据,底层是xml格式的文件,以键值对的方式存储。适用于简单的数据存储。流程:
首先,通过Context对象获取SP对象
然后,利用edit()方法去获取Editor对象
接着,通过Editor对象存储key-value数据
最后,通过commit()方法提交数据

12、Handler机制的原理

android提供了Handler和Looper来满足线程间的通信,Handler满足先进先出的原则,Looper类用来管理特定线程内对象之间的信息交换(message exchange)。

a、Looper:一个线程可以产生一个Looper对象,并由Looper管理这个线程的消息队列(MessageQueue)。

b、Handler:你可以构造Handler对象与Looper沟通,以便push新消息到把MessageQueue。或者接收从Looper里面获取到的数据

c、MessageQueue:用来存放线程消息的队列

13、内存泄漏

a、资源未关闭造成的内存泄漏。如:操作数据库的cursor没有关闭造成内存泄漏;bitmap对象使用完之后调用recycle()方法释放内存等等

b、监听器没有注销造成的内存泄漏。如:广播

c、线程造成的内存泄漏。我们在Runnable方法中持有外部变量,在任务执行完毕之后没有释放

d、单例造成的内存泄漏,在创建单例的时候需要传context对象尽量传ApplicationContext对象。

14、ANR异常

ANR异常:Application Not Responding 即应用程序无响应。在Android中,ActivityManagerService(AMS)和WindowManageService(WMS)会检测应用程序的响应时间,检测的事件超时就会抛出ANR异常。分为3类:

a、KeyDispatchTimeout:5秒内,按键或者触摸事件无响应会抛出ANR异常

b、BroadcastTimeout:10秒内广播无法处理完成会抛出ANR异常

c、ServiceTimeout:20秒内服务无法处理完成会抛出ANR异常

造成的原因以及解决办法:由UI线程和非UI线程

由UI线程造成的:

1)、耗时操作,避免在UI线程中执行耗时操作,比如:网络请求,大数据的读写操作,数据库操作等等。尽量新开线程处理耗时操作

2)、Service忙导致超时无响应,Service默认是执行在住线程中的,所以,service耗时操作也新开线程处理

3)、Broadcast的onReceive的回调也是在主线程中。

4)、没有使用子线程的的Looper中post(Runnable)是执行在主线程的

等等,上面这几种都可以新开子线程处理,从而避免ANR异常

由非UI线程造成的:

1)、非主线程持有lock,导致主线程等待超时

2)、非主线程崩溃或者终止导致主线程一直等待

15、wait()和sleep()的区别

1)、sleep()是Thread的静态方法,wait()是Object类的方法

2)、调用sleep()的线程不会释放对象锁,调用wait()方法会释放对象锁

3)、调用wait()方法之后,需要调用notify,notifyAll来唤醒等待线程,sleep()方法则不需要

16、简述OOM异常

OutOfMemory即内存溢出:也就是运行内存超过了系统分配内存,导致应用异常退出的现象。解决办法:

1)、Bitmap导致OOM。在使用过大的Bitmap资源是要进行图片压缩,使用完之后要调用recycle()方法释放资源,并把对象置null

2)、界面横竖屏切换导致OOM。页面的切换会导致activity生命周期销毁,重新创建,所以,如果你在xml中设置的很大的背景图,它会重新加载,每次都会重新加载,最终会导致OOM。可以在onCreate里面设置背景,并在onDestroy释放,再不然就简单粗暴一点,禁止横竖屏切换就可以了

3)、再就是内存泄漏造成的OOM,解决对应的内存泄漏问题就可以了

17、简述Android动画

android动画分3类:帧动画(Frame Animation),补间动画(Tween Animation),属性动画(Property Animation)。

Frame Anitation:顾名思义,一帧一帧的动画,把一个动画分解成一帧一帧的放在一起,在一定时间内显示一遍。这种动画一般就是UI给出每一帧的图片,在animation-list中的每一个item设置一张,然后调用显示出来就可以了

Tween Animation:有四种:旋转(roate),平移(translate),缩放(scale),渐变(alpha)。一般是在xml中设置,可以复用。通过set标签,设置这个动画的集合,通过设置插值器来改变速率。

Property Animation:沿着一定的时间顺序,通过改变View的属性,从而得到的动画效果。一般,我用在自定义view里面,比方说一个进度的自定义view,通过设置动画时间,通过getAnimationValue,获取动画当前的值,显示到对应的位置

18、显式Intent和隐式Intent

显式Intent:顾名思义就是指定了需要跳转的activity,我们平时做的页面跳转基本上都是显式Intent。隐式Intent:相对于显式而言,就是没有指定Intent的跳转activity,它是在清单文件中注册好,设置过滤器,也就是intent-filter属性。显式Intent效率高,直接指定需要启动的组件,但是耦合度也高。

19、socket通信

TCP:是1对1。UDP:1对N

TCP:传输慢,必须等前一个传完了,才能传下一个。UDP:传输快,只负责发,不管客户收不收

TCP:安全,3次握手机制,采用全双工可靠信道。UDP:不安全

TCP:数据有序。UDP:数据无序

TCP:系统资源开销大,首部20个字节。UDP:系统资源开销小首部8个字节

先获取Socket套接字对象,绑定端口号,新开线程连接服务器。然后通过套接字获取它的输入流和输入流,新开两个线程,监听outputstream,和inputstream。输入流负责读从服务器返回的数据,输出流负责本地向服务器发送数据。这个时候就需要注意拆包,粘包的问题,返回数据需要统一格式,读数据的时候可以根据这个格式来区分是否是一条完整的数据。再就是需要监听网络状态的变化,若切换网络导致连接中断,这个时候就需要捕获异常,释放资源,再重新连接。

20、http和https的区别和3次握手机制,4次挥手机制

区别:

1)、http是明文传输,不安全,https是经过SSL,或者TSL加密后的密文传输

2)、http是免费的,https是收费的

3)、http是80端口,https是443端口

3次握手建立连接:

a、客户端先给服务端发一个标记(请求报文段),告诉服务端我要跟你建立连接,客户端就进入等待状态,等待服务端回复

b、服务端收到这个报文段,然后进行确认,发送服务端这个标记和字节确认的信息发送给客户端,然后服务器进入等待状态

c、客户端收到服务端回复的消息后,把服务端确认的信息再发送给服务端,这个报文发送完毕之后,两者就进入了建立连接状态

4次挥手断开连接:

a、主机1(可以是客户端,可以是服务端)向主机2发送FIN报文段。此时,主机1进入FIN_WAIT_1状态;这表示主机1已经没有消息发送给主机2了

b、主机2收到主机1发送的FIN报文段,向主机1回复一个ACK报文段,主机1进入FIN_WAIT_2状态,表示主机2已经同意了主机1的关闭请求

c、主机2向主机1发送FIN报文段,请求关闭连接,同时主机2进入LAST_ACK状态

d、主机1收到主机2发送的FIN报文段,向主机2发送ACK报文段,同时主机1进入TIME_WAIT状态;主机2收到主机1的ACK后就关闭连接,此时主机1依然没有收到主机2的回复消息,说明正常关闭了,那么此时,主机1也就主动关闭连接了

21、MVP的优缺点

优点:1)、解藕成功,模块职责划分明显,层次清晰。V层处理页面变化,P层处理逻辑

2)、当业务逻辑相同的情况下,P层可以复用

3)、增加Contract接口,便于模块的管理和拓展

4)、便于单元测试

缺点:1)、所有的逻辑代码都丢在P层,造成P层臃肿,不利于维护

2)、代码的复杂度变高,学习成本变高

3)、由于视图的渲染放在P层,所以视图和P层的交互会过于频繁。一旦视图需要变更,P层也要跟着变化

22、greendao如何处理几百万数据的读写

1)、可以在插入数据之前失效索引,插入数据完成之后重新检索索引

2)、greendao提供了AsyncSession异步封装类,就是说异步插入数据库。如果获取数据快,操作数据慢,可以调用waitForCompletion方法,等待插入数据完成,不然会内部阻塞队列

3)、内存优化方面,数据插入之后调用detachAll()方法

23、android中的跨进程方式,binder原理,数据要拷贝几次?android为什么要设计跨进程?

跨进程通信4种方式: 对应的四大主件,Activity,ContentProvide,Broadcast,Service(AIDL)

1)、Activity:最常见的就是

Intent intent = new  Intent(this , Test.class );  
startActivity(intent); 

它可以跨进程调用其他应用程序的Activity

2)、ContentProvide:这种方式就是运用手机本地的数据库,就是查询数据库中的数据。图片,音乐,联系人等等。它返回的是一个Cursor对象

3)、Broadcast:被动的跨进程通信方式,只能被动的接收从广播中发送数据,而不能主动沟通广播。

4)、AIDL服务:将程序中某个接口公开,这样其他应用程序就可以像访问本地对象一样访问AIDL服务

binder原理: 数据拷贝1次,内存0次,socket/管道/消息队列2次。

binder是android跨进程通信方式,它实现IBind接口,是ServiceManager连接各种Manager的桥梁。Android系统启动的过程中,会初始化各种Service,并将这些Service向ServiceManager注册,也就是让它管理。客户端想要某个Service直接向ServiceManager要即可。所以,客户端先向ServiceManager查询到Service具体的引用,通过这个引用向具体的服务发送请求,服务端执行完成之后就返回。

24、java设计模式

请跳转个人博客:haichenyi.com

25、抽象类和接口的异同

a、抽象类只能单继承,接口可以多继承

b、抽象类是用abstract标识,接口是用interface标识

c、抽象类可以即定义抽象方法,也可以定义普通方法;接口定义的方法不能实现

26、String,StringBuilder,StringBuffer的区别

a、线程安全方面:他们都是字符串常量,StringBuffer是线程安全,StringBuilder是线程不安全。因为StringBuffer绝大部分方法都带有synchronized关键字,StringBuilder则没有

b、运行速度方面:绝大部分情况下:StringBuilder > StringBuffer > String

c、用法:String:用于少量字符串操作
StringBuilder:用于多线程在缓冲区进行大量操作
StringBuffer:用于单线程在缓冲区进行大量操作
因为,只要是对String进行操作,每次都会重新创建一个String对象,而StringBuilder和StringBuffer则不会。

27、HashMap,HashSet,LinkedList,ArrayList实现原理

HashMap: 是基于hash表的Map接口的非同步实现,允许null键和null值,不保证映射顺序。底层是使用数组实现,数组中的每一项都是一个单向链表。数组扩容需要重新计算每一个元素在数组中的位置,很耗性能

HashSet: 是基于HashMap的实现,api也是对HashMap的封装

LinkedList: 是list接口的双向链表的非同步实现,允许包括null在内的所有元素。底层实现是基于双向链表。

ArrayList: 是list接口的可变数组实现,允许包括null在内的所有元素。底层实现是基于数组。每次扩容,把旧数组的数据拷贝到新数组中,新数组容量大约增加1.5倍,代价很高。

28、java中的三大特性

三大特性:封装(暴露调用方法,隐藏内部实现),继承(子类继承父类),多态(重写与重载)

你可能感兴趣的:(Android简单的面试题)