Q1:android:layout_weight的真实含义
解答:首先声明只有在Linearlayout中,该属性才有效。之所以android:layout_weight会引起争议,是因为在设置该属性的同时,设置android:layout_width为wrap_content和match_parent会造成两种截然相反的效果。
android:layout_weight的真实含义是:一旦View设置了该属性(假设有效的情况下,那么该 View的宽度等于原有宽度(android:layout_width)加上剩余空间的占比。
详见:android:layout_weight的真实含义
Q2线性布局中如何按比例显示子控件?
如果线性布局是垂直,子控件设置属性android:layout_height=“0”,然后使用android:layout_weight可以按比例显示子控件。
Q3打开一个应用,返回桌面,然后再次返回应用,activity分别经历了怎么样的生命周期?
打开一个应用,调用 onCreate()->onStart()->onResume();
返回桌面 onPause()->onStop();
再次打开应用 onRestart()->onStart()->onResume();
Q4equals和==的区别
等于
equals相同
如果比较对象是值变量,只能用,equals是不存在的。
如果比较对象是引用型变量:
==:比较两个引用是不是指向同一个对象实例。
equals:比较两个引用指向的对象实例的值是不是相同。
参考如何“记住” equals 和 == 的区别?
Q5switch能够使用String做参数?
在Jdk1.7之前只支持byte,short,int,char或者对应的封装类以及Enum类型,不支持String和long类型。
在Jdk1.7中加入String支持,String不能传null做参数,同时case语句中使用的字符串也不能为null,因为底层是通过equals和hashmap实现的。
Q6 Object有哪些公共方法?
Object类有11个方法,有两个protected的方法,其中一个为clone方法,另一个是finalize()方法。
1.所有方法:
- getClass()
- hashCode()
- equals()
- toString()
- clone()
- wait()
- notify()
- notifyAll()
- finalize()
2.各个方法作用:
方法摘要
protected Object clone() 创建并返回此对象的一个副本。
boolean equals(Object obj) 指示某个其他对象是否与此对象“相等”。
protected void finalize() 当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。
Class getClass() 返回一个对象的运行时类。
int hashCode() 返回该对象的哈希码值。
void notify() 唤醒在此对象监视器上等待的单个线程。
void notifyAll() 唤醒在此对象监视器上等待的所有线程。
String toString() 返回该对象的字符串表示。
void wait() 导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法。
void wait(long timeout) 导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者超过指定的时间量。
void wait(long timeout, int nanos) 导致当前的线程等待,直到其他线程调用此对象的 notify()。Q7 java中的四种引用
从jdk1.2版本开始,把对象的引用分为四种级别,这四种级别由高到低依次为:强引用,软引用,弱引用和虚引用。
1强引用:
如果一个对象具有强引用,垃圾回收器绝不会回收它。当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会回收具有强引用的对象来解决内存不足问题。如果想中断强引用和某个对象之间的关联,可以显示地将引用赋值为null,这样一来的话JVM在合适的时机就会回收该对象。
2 软引用:
如果内存空间足够,垃圾回收器就不会回收它,如果内存空间不足了,软引用就会被垃圾回收器回收。只要垃圾回收器没有回收它,该对象就可以被程序使用。软引用可用来实现内存敏感的高速缓存。
软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收,Java虚拟机就会把这个软引用加入到与之关联的引用队列中。
3 弱引用
具有弱引用的对象拥有更短暂的生命周期。因为当JVM进行垃圾回收,一旦发现弱引用对象,无论当前内存空间是否充足,都会将弱引用回收,不过垃圾回收器是一个优先级较低的线程,所以并不一定能迅速发现弱引用对象。
弱引用可以和一个引用队列(ReferenceQueue)联合使用,如果弱引用所引用的对象被垃圾回收,Java虚拟机就会把这个弱引用加入到与之关联的引用队列中。
4 虚引用
“虚引用”顾名思义,就是形同虚设,与其他几种引用都不同,虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收。
虚引用主要用来跟踪对象被垃圾回收的活动。虚引用与软引用和弱引用的一个区别在于:虚引用必须和引用队列(ReferenceQueue)联合使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。程序如果发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取必要的行动。
Q8内存泄露的情况有哪些?
参考资料
英文版:
https://android-developers.googleblog.com/2009/01/avoiding-memory-leaks.html
中文翻译版:
http://yuweiguocn.github.io/android-avoiding-memory-leaks/
1) 不要长时间持有Activity的上下文引用,尝试使用Application的上下文引用(尽量避免activity的context在自己的范围外被使用,这样会导致activity无法释放)。
非静态内部类持有外部类的实例。避免在Activity中使用非静态内部类,应该使用静态内部类并对Activity作弱引用(WeakReference)处理。(原因:静态内部类不持有外部类的引用,)
2) 静态变量导致内存泄露。
静态变量持有当前 Activity。导致当前 Activity 结束时候,静态变量仍然持有它的引用。
3) 声明ViewHolder内部类时使用static修饰符。
4) 资源性对象比如(Cursor,File文件等)往往都用了一些缓存,在不使用的时候,应该即使关闭它们,以便它们的缓冲及时回收内存。不关闭他们,往往会造成内存泄露。因为对于资源性对象在不使用的时候,应该调用它的close()函数,将其关闭掉,然后才置为null。
5) 使用Adapter时,没有使用系统缓存的convertView。
6) 注册没取消造成内存泄露,如广播。
7) 集合中的对象没清理造成的内存泄露。我们通常把一些对象的引用加入到了集合中,当我们不需要该对象时,并没有把它的引用从集合中清理掉,这样这个集合就会越来越大。如果这个集合是static的话,那情况就更严重了。
8) Bitmap对象不在使用时调用recycle()释放内存。
Q9OOM是怎么引起的?怎样避免OOM问题的出现?
参考http://hukai.me/android-performance-oom/
OOM是内存溢出的意思。
1)使用更轻量级的数据结构,比如:可以考虑使用ArrayMap/SparseArray而不是HashMap等传统数据结构。
2)避免在Android里面使用Enum。
3)加载大对象,如Bitmap。优化方法:1采用低内存占用量的编码方式 2图片压缩 3及时回收图像。
4)相应资源太多,来不及释放。
解决方法:1在内存引用上做些处理,常用的由软引用、强引用、弱引用。
5)在内存中加载图片时直接在内存中做处理,如边界压缩。
6)及时回收内存。
7)ListView/GridView等出现大量重复子组件的视图里面对ConvertView的复用。
8)StringBuilder。
9)内存对象的重复利用-利用对象池技术。
10)避免对象的内存泄露。
Q10什么是ANR问题,为什么会引起ANR?
ANR Application Not Response应用程序无响应。
1) 在Service后台执行耗时操作。
2) BroadcastReceiver的onReceiver方法中执行耗时操作。
3) 应用程序可以接收输入事件(按键、触屏、轨迹球等),当5秒内没有处理完毕时,则会引发ANR。
ANR机制以及问题分析https://duanqz.github.io/2015-10-12-ANR-Analysis
Q11 主线程中的Looper.loop()一直无限循环为什么不会造成ANR
参考:来自http://www.jianshu.com/p/cfe50b8b0a41
正如我们所知,在Android中如果主线程中进行耗时操作会引发ANR异常。
造成ANR的原因一般有两种:
1 当前的事件没有机会得到处理(即主线程正在处理一个事件,没有及时地完成或者looper被某种原因阻塞住了)
2 当前的事件正在处理,但没有及时完成。
因为Android 的是由事件驱动的,looper.loop() 不断地接收事件、处理事件,每一个点击触摸或者说Activity的生命周期都是运行在 Looper.loop() 的控制之下,如果它停止了,应用也就停止了。只能是某一个消息或者说对消息的处理阻塞了 Looper.loop(),而不是 Looper.loop() 阻塞它。
也就说我们的代码其实就是在这个循环里面去执行的,当然不会阻塞了。
Q12Socket编程步骤
Socket编程步骤分为:服务器端(ServerSocket)和客户端(Socket)
服务器端Socket:ServerSocket
1 在服务器端建立一个ServerSocket绑定相应的端口号,并且在指定的端口进行侦听,等待客户端连接。ServerSocket serverSocket = new ServerSocket(9090);
2 客户端创建连接Socket,并且向服务器端发送请求。
3 服务器收到请求,并且接受客户端的请求信息。调用accept方法等待客户连接。accept方法是一个阻塞的方法,一旦由客户请求,它就会返回一个新的Socket对象用于同客户进行交互。
4 客户端与服务器端通过相应的输入/输出流进行数据的交换。
5 当客户端和服务器端通信完毕后,需要分别关闭socket。
服务器端:
1.创建ServerSocket对象,绑定监听端口
2.通过accept()方法监听客户端请求
3.连接建立后,通过输入流读取客户端发送的请求信息
4.通过输出流向客户端发送响应信息
5.关闭相关资源
客户端:
1.创建Socket对象,指明需要连接的服务器的地址和端口号
2.连接建立后,通过输出流向服务器端发送请求信息
3.通过输入流获取服务器响应的信息
4.关闭相关资源
Q13 java垃圾回收机制
在Java中,如果不再有引用指向对象,这样的对象将不可到达(unreachable)。垃圾回收用于释放不可到达对象所占据的内存。这是垃圾回收的基本原则。
怎么判断一个对象是否需要回收?
- 引用计数(最简单古老的方法):指将资源(可以是对象、内存或磁盘空间等等)的被引用次数保存起来,当被引用次数变为零时就将其释放的过程。缺点:无法检测出循环引用
- 跟踪收集器。对象引用遍历(现在大多数 jvm 使用的方法):对象引用遍历从一组对象开始,沿着整个对象图上的每条链接,递归确定可到达(reachable)的对象。如果某对象不能从这些根对象的一个(至少一个)到达,则将它作为垃圾收集。
垃圾收集算法: - 标记清除算法:遍历对象图并且记录可到达的对象,以便删除不可到达的对象,一般使用单线程工作并且可能产生内存碎片。
- 标记-压缩回收法:前期与第一种方法相同,只是多了一步,将所有的存活对象压缩到内存的一端,这样内存碎片就可以合成一大块可再利用的内存区域,提高了内存利用率。
- 复制回收法:把现有内存空间分成两部分,gc运行时,它把可到达对象复制到另一半空间,再清空正在使用的空间的全部对象。这种方法适用于短生存期的对象,持续复制长生存期的对象则导致效率降低。
- 分代回收法:把内存空间分为两个或者多个域,如年轻代和老年代,年轻代的特点是对象会很快被回收,因此在年轻代使用效率比较高的算法。当一个对象经过几次回收后依然存活,对象就会被放入称为老年的内存空间,老年代则采取标记-压缩算法。
Q14 IntentService使用步骤
1 创建一个类继承IntentService类,并重写onHandleIntent()方法,需要在AndroidManifest.xml中使用标签注册该类。
2 发送工作任务到IntentService,通过Intent对象显示指定该类,调用startService方法完成。
3将后台任务执行结果回传给Activity或Fragment,通过LocalBroadcastManager.sendBroadcast()来发送广播。
原理和实例代码详见:
http://blog.csdn.net/lmj623565791/article/details/47143563
Q15ListView滑动卡顿和解决方法
1 ListView对应的适配器,使用ViewHolder机制,重用contentView,避免每次调用getView方法都创建contentView。
2不要在getView方法中执行耗时操作。
3 控制异步任务的执行频率。
4 如果listview需要显示的item很多,就要考虑分页加载。比如一共要显示100条或者更多的时候,我们可以考虑先加载20条,等用户拉到列表底部的时候再去加载接下来的20条。
5 在列表滑动的时候停止加载图片,尽管这个过程是异步的,等列表停下来以后再加载图。
Q16 接口和抽象类的区别
1一个类只能继承单个类,但是可以实现多个接口。
2接口强调特定功能的实现,而抽象类强调所属关系。
3抽象类中的所有方法并不一定要是抽象的,你可以选择在抽象类中实现一些基本的方法。而接口要求所有的方法都必须是抽象的。
4 抽象类是abstract class修饰,接口是interface修饰。
5抽象类可以有任意类型的属性,接口只能有静态常量修饰的属性。
6 抽象类可以有普通方法和抽象方法,接口的方法都是抽象方法。
7 抽象类和接口都不能实例化,但是抽象类由构造方法,接口没有构造方法。
Q17String, StringBuilder和StringBuffer的区别
String类型和StringBuffer类型的主要性能区别其实在于String是不可变的对象。
StringBuilder和StringBuffer底层是char[]数组实现的。
StringBuffer是线程安全的,而StringBuilder是线程不安全的。
Q18Override和Overload的含义区别
Override是重写的意思,在子类继承父类的时候子类中可以定义某方法与其父类有相同的名称和参数,当子类在调用这一函数时自动调用子类的方法,而父类相当于被覆盖(重写)了。
Overload顾名思义是重新加载,它可以表现类的多态性,可以是函数里面又相同的函数名但是参数名,返回值,类型不相同。
Q19wait()和sleep()的区别
1 sleep()来自Thread类,而wait来自Object类
2 调用sleep()方法的过程中,线程不会释放对象锁,而调用wait方法线程会释放对象锁。
3 sleep睡眠后不出让系统资源,wait让出系统资源其他线程可以占用CPU
4 sleep(milliseconds)需要指定一个睡眠时间,时间一到会自动唤醒。
Q20ListView滑动卡顿和解决方案
1 ListView对应的适配器,使用ViewHolder机制,重用contentView,避免每次调用getView方法都创建contentView。
2不要在getView方法中执行耗时操作。
3 控制异步任务的执行频率。
4 如果listview需要显示的item很多,就要考虑分页加载。比如一共要显示100条或者更多的时候,我们可以考虑先加载20条,等用户拉到列表底部的时候再去加载接下来的20条。
5在列表滑动的时候停止加载图片,尽管这个过程是异步的,等列表停下来以后再加载图片。
Q21解析xml的几种方式的原理和特点:DOM,SAX,PULL
DOM:消耗内存,先把xml文档都都读到内存中,然后再用DOM API来访问树形结构,并获取数据。这个写起来很简单,但是很消耗内存。
SAX:解析效率高,占用内存少,基于事件驱动的。更加简单的说就是对文档进行顺序扫描,当扫描到文档开始与结束,元素开始与结束,文档结束等地方时通知事件处理函数做相应动作,然后继续同样的扫描,直至文档结束。
PULL:与SAX类似,也是基于事件驱动,我们可以调用它的next方法,来获取下一个解析事件(就是开始文档,结束文档,开始标签,结束标签),当处于某个元素时可以调用XmlPullParser的getAttributte()方法来获取属性的值,也可调用它的nextText()获取本节点的值。在PULL解析过程中,我们需要自己获取产生的事件然后做相应的操作,而不像SAX那样由处理器触发一种事件的方法,执行我们的代码。PULL解析器小巧轻便,解析速度块,简单易用,非常适合在android移动设备中使用,android系统内部在解析各种xml时也是用PULL解析器。
Q22java内部类和内部类分类
java类中方法间定义的类称为java的内部类,可以访问其外部类的私有变量和方法。
分类
- 成员内部类
- 局部内部类
- 匿名内部类
- 静态内部类(定义在类中,任何方法外,用static修饰)
静态内部类
生成一个静态内部类不需要外部类成员。这是静态内部类和成员内部类的区别。静态内部类的对象可以直接生成:Outer.Inner in=new Outer.Inner();而不需要通过生成外部类对象来生成。这样实际上使静态内部类成为了一个顶级类。可以定义私有静态内部类。
静态内部类和非静态内部类的区别: - 非静态内部类中不可以声明静态成员变量和静态成员方法。
- 一般非静态内部类可以随意访问其外部类的成员变量以及方法(包括声明为private的方法);静态内部类只能访问其外部类的静态成员变量和静态成员方法,不能访问非静态成员变量和方法。
- 在一个类中创建非静态内部类,内部类的实例一定要绑定在外部类的实例中,在一个外部类中定义一个静态的内部类,不需要利用关键字new来创建内部类的实例,也就是说创建静态内部类对象时,不需要其外部类的对象。
Q23 Fragment生命周期
Fragment生命周期
Q24 Java中Collection和Collections的区别(面试题)
1 java.util.Collection是一个集合接口,它提供了对集合对象进行基本操作的通用接口方法。Collection接口在Java类库中有很多具体的实现。Collection接口的意义是为各种具体的集合提供了最大化的统一操作方式。
Collection
├List
│├LinkedList
│├ArrayList
│└Vector
│ └Stack
└Set
2Collections是一个包装类,它包含各种有关集合操作的静态方法,此类不能实例化。
Q25android 中进程的优先级
前台进程
可见进程
服务进程
后台进程
空进程
Q26ArrayList和Vector的主要区别是什么,HashMap和Hashtable的区别是什么?
ArrayList在Java1.2引入,用于替换Vector。
Vector:
线程同步
当Vector中的元素超过它的初始大小时,Vector会将它的容量翻倍。
ArrayList:
线程不同步,但性能很好
当ArrayList中的元素超过它的初始大小时,ArrayList只增加50%的大小。
HashMap是线程不安全且能放空键或空值,Hashtable线程安全且不能放空键或空值。
原文链接地址
Q27ArrayList,LinkedList的区别
1 ArrayList 内部通过数组实现,它允许对元素进行快速随机访问。当在ArrayList的中间位置不断插入或者删除元素时,需要对数组进行复制,移动,代价比较高,因此适合随机查找和遍历,不适合插入和删除。不同步,允许重复元素
2 LinkedList 它是用链表结构存储数据的,很适合数据的动态插入和删除,随机访问和遍历速度比较慢。
Q28静态内部类、内部类、匿名内部类、为什么内部类会持有外部类的引用?持有的引用是this|还是其他?
静态内部类是static修改的内部类
内部类:在某个类的内部又定义了一个类,内部类所嵌入的类称为外部类。
匿名内部类使用new生产的内部类
因为内部类的产生依赖于外部类,持有的引用是类名.this
题目来自2016Android某公司面试题
Q29 Service生命周期,Service中可以执行耗时操作吗?
Service有两种启动方式,bindService()和startService()。
call to bindService()
onCreate()->onBind()->Clients are bound to service->onUnbind()->onDestroy()
Service shut down
call to startService()
onCreate()->onStartCommand()->Service running ->->onDestroy()
Service shut down
Service是运行在主线程的后台服务,不可执行耗时操作,否则出现ANR错误。
Q30 SharedPreferences.Editor 的commit和apply区别
参考API描述,可见:
apply()方法没有返回值,commit()方法有返回值
commit()方法当两个Editor同时修改值,最后一个调用的会生效。如果你不关系返回值,并且在主线程中调用,可以考虑使用apply()方法。先写入内存,然后同步写入持久化存储设备,并返回是否写入成功。
apply()方法当两个Editor同时修改值,最后一个调用的会生效,同步提交到内存,异步提交到硬盘。
原理分析可参考:SharedPreferences 的commit和apply分析
Q31 几种单例模式写法的区别?
Q32androidstudio常用快捷键
Ctrl+ALT+L 代码格式化,比如对齐;
Ctrl+Alt+向左箭头 返回上一次浏览位置/光标所在位置;
Ctrl+Alt+向右箭头 返回下一次浏览位置/光标所在位置;
Q33 WebView的pauseTimers方法中断了所有js请求,所以此方法需谨慎使用。
Q34 Fiddler mock数据环境搭建
1 选中左侧url,右键弹出窗依次选择:Save->Response->Response Body…
2 弹出窗口并保存文件,默认文件名是:client.action.txt。打开此文件,修改数据然后保存。
3 在Fiddler的AutoResponder页面,去除勾选Enable rules和Enable Latency,点击AddRule。在Rule Editor填写可以匹配到接口地址的关键字,然后选择mock数据存储的文件,即client.action.txt。然后选中Rule,Enable rules和Enable Latency勾选上。然后再次请求接口,接口返回结果就是返回mock数据了。
Q35 StringBuilder使用注意事项
1、StringBuilder构造方法
public StringBuilder(String str)
str可以为空,但不能为null。构造方法内部调用append方法,将str添加到StringBuilder中
public StringBuilder(int capacity)
capacity是初始容量大小。** 注意**
2、append方法
append方法添加的数据类型比较全,参数可传String,boolean,char,int,long,float,double,char[],StringBuffer,Object obj等等。比如传null,将添加一个"null"字符串。
Q36 h5页面如何获取手机的imei值
android中获取手机Imei值比较简单,可定义一个方法,然后js与java的交互通过js桥接方式,js调用android中获取手机Imei值的方法。
Q37 LayoutInflater inflate参数解析
LayoutInflater类的inflate方法
public View inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot)
参数含义:
root参数:布局映射的父视图
attachToRoot参数:
attachToRoot取值true,添加到父布局root作为子View,并返回父布局root
attachToRoot取值false,映射布局文件resource和父布局root没有任何关联,就是将布局文件生成成一个View对象。