android2017经典面试题汇总
新的一天,祝愿大家工作愉快。
请一一简述Android中的五类进程。
①前台进程(Foreground process):用来处理用户正在进行的工作的进程。
②可见进程( Visible process):这种进程并不包含任何前台组件,但是包含仍然被用户可见的组件。
③服务进程(Service process):其中运行着使用startService()方法启动的Service,并且没有变为更高的两个级别的进程。
④后台进程(Background process):处理后台事务的进程,比如其中运行着执行了onStop()方法而处于停止态的Activity等
。⑤空进程(Empty process):不包含任何活动的应用程序组件的进程。
如果在新开的工作线程中更新了UI,而又因为只能在UI线程中更新UI,所以Android提供了三种方式来解决这个问题。请写出这三种解决方式。
①使其他线程尝试访问UI线程,并委托后者更新UI。
②在线程间进行通信,让想更新UI的其他线程给UI线程发送消息,UI线程根据消息更新UI
③使用Android提供的AsyncTask。
Handler的概念
Handler对象可以发送和处理与一个线程的消息队列相关联的Message和Runnable对象。每一个Handler的实例都与一个独立的线程及其消息队列相关联。当一个新的Handler对象被创建,它就会被绑定到创建它的线程的消息队列之上,从这一刻开始,这个Handler对象便会将Message和Runnable对象发送给它所绑定的消息队列,并且在这些对象离开队列后,处理他们。
handler机制的原理。
andriod提供了 Handler 和 Looper 来满足线程间的通信。Handler 先进先出原则。Looper类用来管理特定线程内对象之间的消息交换(Message Exchange)。
Looper: 一个线程可以产生一个Looper对象,由它来管理此线程里的Message Queue(消息队列)。
Handler: 你可以构造Handler对象来与Looper沟通,以便push新消息到Message Queue里;或者接收Looper从Message Queue取出)所送来的消息。
Message Queue(消息队列):用来存放线程放入的消息。
线程:UI thread 通常就是main thread,而Android启动程序时会替它建立一个Message Queue。
对looper的理解
请解释下在单线程模型中Message、Handler、Message Queue、Looper之间的关系。
:Message Queue(消息队列):用来存放通过Handler发布的消息,通常附属于某一个创建它的线程,可以通过Looper.myQueue()得到当前线程的消息队列。
Handler:可以发布或者处理一个消息或者操作一个Runnable,通过Handler发布消息,消息将只会发送到与它关联的消息队列,然也只能处理该消息队列中的消息。
Looper:是Handler和消息队列之间通讯桥梁,程序组件首先通过Handler把消息传递给Looper,Looper把消息放入队列。Looper也把消息队列里的消息广播给所有的。
Handler,Handler接受到消息后调用handleMessage进行处理。
Message:消息的类型,在Handler类中的handleMessage方法中得到单个的消息进行处理。
请解释什么是进程(Process)与线程(Thread)。
答案:
①进程是操作系统结构的基础,是计算机中正在运行的程序实例,它可以被分配给处理机并被处理机执行。通俗地说,就是一个正在运行的应用程序实体。
②线程是进程中某个单一顺序的控制流,它也被称为轻量级进程(Lightweight Process),它是处理机调度的基本单位。
请分析说明进程与线程的四点区别。
答案:
①地址空间和数据资源:进程间相互独立;同一进程的各线程间共享,但某进程内的线程在其它进程不可见。
②通信:进程间通信需要专门的机制;线程间可以直接读写全局变量来进行通信,不过需要同步和互斥手段的辅助,以保证数据的一致性。
③调度和切换:线程上下文切换比进程上下文切换要快得多。
④在多线程OS中,进程不是一个可执行的实体。
android中线程与线程,进程与进程之间如何通信
1、一个 Android 程序开始运行时,会单独启动一个Process。 默认情况下,所有这个程序中的Activity或者Service都会跑在这个Process。默认情况下,一个Android程序也只有一个Process,但一个Process下却可以有许多个Thread。
2、一个 Android 程序开始运行时,就有一个主线程Main Thread被创建。该线程主要负责UI界面的显示、更新和控件交互,所以又叫UI Thread。 一个Android程序创建之初,一个Process呈现的是单线程模型--即Main Thread,所有的任务都在一个线程中运行。所以,Main Thread所调用的每一个函数,其耗时应该越短越好。而对于比较费时的工作,应该设法交给子线程去做,以避免阻塞主线程(主线程被阻塞,会导致程序假死 现象)。
3、Android单线程模型:Android UI操作并不是线程安全的并且这些操作必须在UI线程中执行。如果在子线程中直接修改UI,会导致异常。
Session就是一种保存上下文信息的机制,它通过SessionID来区分不同的客户。请简单描述它的三种保存Session ID的方式。
①使用Cookie:保存session id的方式可以采用Cookie,这样在交互过程中浏览器可以自动的按照规则把这个标识发送给服务器。
②URL重写:由于Cookie可以被人为的禁止,必须有其它的机制以便在Cookie被禁止时仍然能够把Session ID传递回服务器,经常采用的一种技术叫做URL重写,就是把Session ID附加在URL路径的后面,附加的方式也有两种,一种是作为URL路径的附加信息,另一种是作为查询字符串附加在URL后面。网络在整个交互过程中始终保持状态,就必须在每个客户端可能请求的路径后面都包含这个Session ID。
③表单隐藏字段:另一种技术叫做表单隐藏字段。就是服务器会自动修改表单,添加一个隐藏字段,以便在表单提交时能够把Session ID传递回服务器。
请解释什么叫TCP和UDP。
答案
①TCP叫传输控制协议,它是一种可靠的连接,即有服务器和客户端,只有当双方建立好连接后,才能互相发送数据。(TCP---传输控制协议,提供的是面向连接、可靠的字节流服务。当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接,之后才能传输数据。TCP提供超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能从一端传到另一端。)
②UDP叫用户数据报协议,它是一种不可靠的连接,即发送发在没有建立好连接的情况下,就可以直接向目标主机发送数据。(UDP---用户数据报协议,是一个简单的面向数据报的运输层协议。UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地。由于UDP在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快。)
请简析TCP和UDP的区别。
答案:
TCP---传输控制协议,提供的是面向连接、可靠的字节流服务。当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接,之后才能传输数据。TCP提供超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能从一端传到另一端。
UDP---用户数据报协议,是一个简单的面向数据报的运输层协议。UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地。由于UDP在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快。
请请写出GET和POST方法主要的三点区别。
答案:
①POST请求可以向服务器传送数据,而且数据放在HTML HEADER内一起传送到服务端URL地址,数据对用户不可见。而GET是把参数数据队列加到提交的URL中,值和表单内各个字段一一对应,例如(
②GET传送的数据量较小,不能大于2KB。POST传送的数据量较大,一般被默认为不受限制。但理论上,IIS4中最大量为80KB,IIS5中为100KB。
③GET安全性非常低,POST安全性较高
例举一种ORM框架,说说它的优缺点。
我熟悉的两种GreenDao3和AndroidActive,GreenDao 比较常规,注解不多(我这里都是指3.0版本后,之前的版本在生存实体的时候略显麻烦。),AndroidActive 相对而言注解较多,最后的综合性能上 GreenDao 排第一毫无争议。硬要说缺点的话就是 GreenDao 体积稍大。
对于同一个Service,在被start启动之后还能不能被bind?
能
服务基本上分为两种形式:
启动 当应用组件(如 Activity)通过调用 startService() 启动服务时,服务即处于“启动”状态。一旦启动,服务即可在后台无限期运行,即使启动服务的组件已被销毁也不受影响。 已启动的服务通常是执行单一操作,而且不会将结果返回给调用方。例如,它可能通过网络下载或上传文件。 操作完成后,服务会自行停止运行。
绑定
当应用组件通过调用 bindService() 绑定到服务时,服务即处于“绑定”状态。绑定服务提供了一个客户端-服务器接口,允许组件与服务进行交互、发送请求、获取结果,甚至是利用进程间通信 (IPC) 跨进程执行这些操作。 仅当与另一个应用组件绑定时,绑定服务才会运行。 多个组件可以同时绑定到该服务,但全部取消绑定后,该服务即会被销毁。
虽然本文档是分开概括讨论这两种服务,但是您的服务可以同时以这两种方式运行,也就是说,它既可以是启动服务(以无限期运行),也允许绑定。问题只是在于您是否实现了一组回调方法:onStartCommand()(允许组件启动服务)和 onBind()(允许绑定服务)。 (来自官方文档)
静态内部类、内部类、匿名内部类,为什么内部类会持有外部类的引用?持有的引用是this?还是其它?
静态内部类:使用static修饰的内部类
内部类:就是在某个类的内部又定义了一个类,内部类所嵌入的类称为外部类
匿名内部类:使用new生成的内部类
因为内部类的产生依赖于外部类,持有的引用是类名.this
Java中try catch finally的执行顺序
先执行try中代码,如果发生异常执行catch中代码,最后一定会执行finally中代码
equals与==的区别:
==是判断两个变量或实例是不是指向同一个内存空间 equals是判断两个变量或实例所指向的内存空间的值是不是相
Object有哪些公用方法?
方法equals测试的是两个对象是否相等
方法clone进行对象拷贝
方法getClass返回和当前对象相关的Class对象
方法notify,notifyall,wait都是用来对给定对象进行线程同步的
String、StringBuffer与StringBuilder的区别
String 类型和 StringBuffer 类型的主要性能区别其实在于 String 是不可变的对象
StringBuffer和StringBuilder底层是 char[]数组实现的
StringBuffer是线程安全的,而StringBuilder是线程不安全的
Java的四种引用的区别
强引用:如果一个对象具有强引用,它就不会被垃圾回收器回收。即使当前内存空间不足,JVM 也不会回收它,而是抛出 OutOfMemoryError 错误,使程序异常终止。如果想中断强引用和某个对象之间的关联,可以显式地将引用赋值为null,这样一来的话,JVM在合适的时间就会回收该对象
软引用:在使用软引用时,如果内存的空间足够,软引用就能继续被使用,而不会被垃圾回收器回收,只有在内存不足时,软引用才会被垃圾回收器回收。
弱引用:具有弱引用的对象拥有的生命周期更短暂。因为当 JVM 进行垃圾回收,一旦发现弱引用对象,无论当前内存空间是否充足,都会将弱引用回收。不过由于垃圾回收器是一个优先级较低的线程,所以并不一定能迅速发现弱引用对象
虚引用:顾名思义,就是形同虚设,如果一个对象仅持有虚引用,那么它相当于没有引用,在任何时候都可能被垃圾回收器回收。
介绍垃圾回收机制
标记回收法:遍历对象图并且记录可到达的对象,以便删除不可到达的对象,一般使用单线程工作并且可能产生内存碎片
标记-压缩回收法:前期与第一种方法相同,只是多了一步,将所有的存活对象压缩到内存的一端,这样内存碎片就可以合成一大块可再利用的内存区域,提高了内存利用率
复制回收法:把现有内存空间分成两部分,gc运行时,它把可到达对象复制到另一半空间,再清空正在使用的空间的全部对象。这种方法适用于短生存期的对象,持续复制长生存期的对象则导致效率降低。
分代回收发:把内存空间分为两个或者多个域,如年轻代和老年代,年轻代的特点是对象会很快被回收,因此在年轻代使用效率比较高的算法。当一个对象经过几次回收后依然存活,对象就会被放入称为老年的内存空间,老年代则采取标记-压缩算法
设计一套图片异步加载缓存方案
Android内存泄露及管理
Activity与Fragment通信
Fragment的那些坑
Android UI适配
这里给出hongyang大神的方案
布局优化
Http Https
网络请求优化
数据库优化
图片优化
HybridJAVA 与JS交互
单例
Java GC原理
?
ANR
Volley
JAVA注解反射原理
算法
设计模式
如果你觉得此文对您有所帮助,欢迎入群 QQ交流群 :232203809 微信公众号:终端研发部
Hello,伙伴们
长按二维码就可以关注我们啦!
(欢迎关注学习和交流)