Android面试总结
来源:互联网 发布:可以打电话的软件 编辑:程序博客网 时间:2024/06/10 14:21
前段在找工作,现在将面试过程中最常见的问题总结一下,希望对大家有帮助。如果有不足或者错误的地方,请指正!
1.事件分发机制
事件由父View传递给子View,ViewGroup可以通过onInterceptTouchEvent()方法对事件拦截,停止其向子view传递,由自身的onTouchEvent()进行处理
如果事件从上往下传递过程中一直没有被停止,且最底层子View没有消费事件,事件会反向往上传递,这时父View(ViewGroup)可以进行消费,如果还是没有被消费的话,最后会到Activity的onTouchEvent()(用于事件处理)函数。
如果View没有对ACTION_DOWN进行消费,之后的其他事件不会传递过来,也就是说ACTION_DOWN必须返回true,之后的事件才会传递进来
OnTouchListener优先于onTouchEvent()对事件进行消费。
2.Android性能优化
--1.减少布局层级,重用布局layout merge
--2.仅在需要的时候才加载布局,viewstub,没有绘制功能,不参与布局
--3.在不影响布局层级的情况下,尽量使用LinearLayout布局,因为RelativeLayout会绘制两次
2.代码优化
--1.常量声明成 static final,编译器首次创建,之后访问时只会去查找,不会重新创建
--2.避免创建不必要的对象 比如:StringBuffer替代String
--3.使用增强for循环
--4.避免使用float类型,建议用int类型替换
--5.避免在ondraw或for循环中创建对象
3.内存泄漏分析及解决办法
内存泄漏就是我们对某一内存空间的使用,使用完成后没有释放。
1,资源对象使用完没有关闭,如file,cursor
2.构建adapter时,没有复用convertview,解决:使用viewHolder
Context使用不当造成的内存泄漏,比如在单例中引用的Context,当Activity 结束了,单例对象还是存在,这将使得该对象继续持有 Context 的引用,造成内存泄漏。解决:使用Application 的 Context。
4.监听器没取消造成的内存泄漏,比如广播,ContentObserver
5.集合中对象没及时清理
6.Handler造成的内存泄漏,比如Activity被finish,延时任务还存在,它会持有该activity的引用,所以该activity就不会被回收从未造成内存泄漏,解决方法:Static + WeakReference的方式来达到断开Handler与Activity之间存在引用关系的目的。其存活时间就与activity无关了
4.怎样避免OOM
2.避免在Android中使用枚举
3.减少bitmap对象内存的占用,解决:1.按比例缩放 2.选择解码格式
4.内存对象的重复利用,如:利用线程池技术,LRU
5.不要在类似ondraw这样频繁调用的方法中创建对象,这样会引起频繁的GC,甚至内存的抖动。
6.内存对象的泄漏,会导致一些不再使用的对象无法及时释放,这样一方面占用了宝贵的内存空间,很容易导致后续需要分配内存的时候,空闲空间不足而出现OOM。
7.优化布局层次,减少内存消耗
5.MVP模式
Model:负责存储、检索、操纵数据(有时也实现一个Model interface用来降低耦合)
Presenter:作为View与Model交互的中间纽带,处理与用户交互的负责逻辑。
View interface:需要View实现的接口,View通过View interface与Presenter进行交互,降低耦合,方便进行单元测试
6.Handler机制
7.Activity启动模式及应用场景
singleTop,栈顶不是该类型的Activity,创建一个新的Activity。否则,onNewIntent。
singleTask,回退栈中没有该类型的Activity,创建Activity,否则,onNewIntent+ClearTop。
singleInstance,回退栈中,只有这一个Activity,没有其他Activity。
例如,某个新闻客户端的新闻内容页面,如果收到10个新闻推送,每次都打开一个新闻内容页面是很烦人的。
例如浏览器的主界面。不管从多少个应用启动浏览器,只会启动主界面一次,其余情况都会走onNewIntent,并且会清空主界面上面的其他页面。
singleInstance应用场景:
闹铃的响铃界面。 你以前设置了一个闹铃:上午6点。在上午5点58分,你启动了闹铃设置界面,并按 Home 键回桌面;在上午5点59分时,你在微信和朋友聊天;在6点时,闹铃响了,并且弹出了一个对话框形式的 Activity(名为 AlarmAlertActivity) 提示你到6点了(这个 Activity 就是以 SingleInstance 加载模式打开的),你按返回键,回到的是微信的聊天界面,这是因为 AlarmAlertActivity 所在的 Task 的栈只有他一个元素, 因此退出之后这个 Task 的栈空了。如果是以 SingleTask 打开 AlarmAlertActivity,那么当闹铃响了的时候,按返回键应该进入闹铃设置界面。
8.Service两种启动方式区别
Service会经历 onCreate 到onStart,然后处于运行状态,stopService的时候调用onDestroy方法。如果是调用者自己直接退出而没有调用stopService的话,Service会一直在后台运行。
2 通过bindService
Service会运行onCreate,然后是调用onBind, 这个时候调用者和Service绑定在一起。调用者退出了,Srevice就会调用onUnbind->onDestroyed方法。
所谓绑定在一起就共存亡了。调用者也可以通过调用unbindService方法来停止服务,这时候Srevice就会调用onUnbind->onDestroyed方法。
9.手写单例模式
public class Singleton { private static Singleton instance; private Singleton (){} public static Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }
以上单例有什么问题,怎么改进?
public class Singleton { private volatile static Singleton singleton; private Singleton (){} public static Singleton getSingleton() { if (singleton == null) { synchronized (Singleton.class) { if (singleton == null) { singleton = new Singleton(); } } } return singleton; } }
10.多线程访问ArrayList会有什么问题,怎么解决?
假如你创建的代码如下:List<Map<String,Object>> data=new ArrayList<Map<String,Object>>();
那么为了解决这个线程安全问题你可以这么使用Collections.synchronizedList(),如:
List<Map<String,Object>> data=Collections.synchronizedList(new ArrayList<Map<String,Object>>());
其他的都没变,使用的方法也几乎与ArrayList一样,大家可以参考下api文档;
额外说下 ArrayList与LinkedList;这两个都是接口List下的一个实现,用法都一样,但用的场所的有点不同,ArrayList适合于进行大量的随机访问的情况下使用,LinkedList适合在表中进行插入、删除时使用,二者都是非线程安全,解决方法同上(为了避免线程安全,以上采取的方法,特别是第二种,其实是非常损耗性能的)。
3.CopyOnWriteArrayList
原理:在对其实例进行修改时,会创建一个临时数据修改,修改完毕后,再将原来的引用指向新的数组。
11.描述一次完整的网络请求
-1.建立TCP/IP连接,客户端通过与服务器通过Socket三次握手进行连接。
-2.客户端向服务器发送请求
-3.客户端发送请求信息,请求内容,最后会发送一个空行,表示客户端请求完毕
-4.服务器会做出应答,并向客户端发送应答头消息
-5.服务器在向客户端发送完应答头消息后,也会发送一个空行表示消息发送完毕,接着就以content-typey要求的数据格式发送数据给客户端
-6.发送数据完毕后,服务器会关闭TCP连接
12.View的刷新机制
由ViewRoot对象的performTraversals()方法调用draw()方法发起绘制该View树,值得注意的是每次发起绘图时,并不会重新绘制每个View树的视图,而只会重新绘制那些“需要重绘”的视图,View类内部变量包含了一个标志位DRAWN,当该视图需要重绘时,就会为该View添加该标志位。
调用流程 :
mView.draw()开始绘制,draw()方法实现的功能如下:
绘制该View的背景
为显示渐变框做一些准备操作(见5,大多数情况下,不需要改渐变框)
调用onDraw()方法绘制视图本身(每个View都需要重载该方法,ViewGroup不需要实现该方法)调用dispatchDraw ()方法绘制子视图(如果该View类型不为ViewGroup,即不包含子视图,不需要重载该方法)值得说明的是,ViewGroup类已经为我们重写了dispatchDraw ()的功能实现,应用程序一般不需要重写该方法,但可以重载父类函数实现具体的功能。
13.自定义View
这个问题几乎是面试中必问的问题,,所以大家对这个多看看吧,网上教程太多了,,不重复造轮子了。
- android面试-面试知识点总结
- android面试基础总结
- android面试基础总结
- Android 面试总结
- android面试基础总结
- android面试基础总结
- android初级面试总结
- Android 面试总结
- Android面试总结经
- Android面试总结
- Android面试总结
- Android面试总结
- Android 面试总结
- Android面试题目总结
- Android 面试总结
- Android面试总结
- android面试总结二
- Android面试题目总结
- Valgrind快速入门指南
- postgre的数组使用
- 卷积神经网络传播过程中感受野的理解以及feature map size 、receptive field size的计算(代码)
- AndroidStudio 线程
- django-rest-swagger的优化使用
- Android面试总结
- 文本文件(ASCII)的读写
- iOS开发之深复制和浅复制
- ImageEditor库详解—————StickerView详解
- 深入理解事务--事务ACID特性及隔离级别
- Gitlab不更新Activity的解决方案
- Valgrind用户手册
- 【bzoj4390】[Usaco2015 dec]Max Flow
- 基于vue2框架的机器人自动回复mini-project