Android开发 面试问题总结

一、 数据结构相关

LinkedList和ArrayList的差别

参考链接:android区别——ArrayList和LinkedList
LinkedListArrayList的差别主要来自于Array和LinkedList数据结构的不同。ArrayList 采用的是数组形式来保存对象的,这种方式将对象放在连续的位置中,所以最大的缺点就是插入删除时非常麻烦。而LinkedList 采用的将对象存放在独立的空间中,且在每个空间中还保存下一个链接的索引,但是缺点就是查找非常麻烦,需要从第一个索引开始。
在Android开发中,常见的ArrayList和LinkedList区别还有以下几种:

①ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。
②对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。
③对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。
④ArrayList线程是不同步

二、 前端

1、 活动Activity的启动模式
  • standard
    活动默认的启动方式
  • singleTop
    在启动活动时如果发现返回栈的栈顶已经是该活动,则认为可以直接使用它,不会再创建新的活动实例。
  • singleTask
    每次启动该活动时,系统首先会在返回栈中检查是否存在该实例,如果发现已存在则直接使用该实例,并把这个活动之上的所有活动统统出栈,如果没有发现就会创建一个新的活动实例。
  • singleInstance
    启用一个新的返回栈管理这个活动,解决共享活动实例的问题。
2、 自定义控件的自定义属性
SurfaceView
  • 双缓冲技术
  • 自带画布,支持在子线程中更新画布内容
3、程序无响应处理方法
ANR异常
什么是ANR异常

参考链接:ANR异常总结
ANR异常是指应用程序未响应,Android系统对于一些事件需要在一定的时间范围内完成,如果超过预定时间能未能得到有效响应或者响应时间过长,都会造成ANR。

android 开发过程中有时会遇见项目无响应异常,这类异常异常并不像Crash那样打印log信息,因此无法被捕获。

如何定位ANR异常

参考链接:Android ANR程序无响应及其异常定位

定位ANR异常不能只看异常日志

AndroidStudio 3.1 打开DDMS
进入系统磁盘找到AndroidSDK目录
sdk -->tools -->monitor.bat
点击monitor.bat文件打开DDMS 界面

4、单例模式

单例模式实现方式:
参考链接:Android中单例模式的几种实现方式

5、事件分发机制
click点击事件运行机制

参考链接:【Android】针对面试的事件分发

事件分发的过程:
总结:就是当我们执行这个操作后,当我们点击屏幕后,首先是activity接受到任务,调用方法dispatchTouchEvent,将事件分发给phonewindow,调用superDispatchTouchEvent,然后在调用里面的内部方法decorView的dispatchTouchEvent,然后DecorView又会调用dispatchTouchEvent去进行事件分发,如果不拦截,默认false,就会继续下传到rootview,操作一样,同样再distpatch内部调用OnIntercepter去判断是否拦截,不拦截就分发给viewgroup,viewgroup里面有内部方法拦截事件,通过返回的true或者false,来判断是否要拦截,或者是分发。最底层view,没有拦截事件,true就是onTouchEvent自己进行消费,false就根据上面的顺序执行,如果长传到最顶层仍然没有人消费,事件最终会被销毁。
在这里插入图片描述

viewgroup里面有内部方法拦截事件,通过返回的true或者false,来判断是否要拦截,或者是分发
如果从底层又长传到最顶层仍然没有人消费,事件最终会被销毁。

OnTouch的传递

执行完onTouch方法之后,会有一个返回值,如果返回这为true的话代表要自身消费,为false的话就表示点击事件继续往下面的view传递,就会执行onTouchEvent方法,onClick方法就是在onTouchEvent中被调用的

FragmentStatePageAdapter与FragmentPageAdapter有什么不同
  • FragmentStatePageAdapter 中的Fragment的对象没有实现复用
  • FragmentPageAdapter 中的Fragment对象复用了

FragmentStatePageAdapter适用于Fragment较多的情况下,FragmentPageAdapter用于固定的少量Fragment的情况。

三、App性能调优(判断是否为高级外包的必要条件)

  1. AndroidStudio自带工具:
  • findbus
  • checkstyle
  • monitor
  1. 查看页面耗内存量
  2. oom
  3. 内存泄漏
  4. 布局优化

四、客户端架构

参考链接:
android基本架构
浅谈Android App架构

怎么理解mvc、mvp

mvc模式
M 指模型层(网络IO、文件IO等操作)
V 指视图层(对应Android中的Layout和Activity/Fragment)
C 指控制层(对应Android中的Activity/Fragment)

在Android中,Activity/Fragment既充当控制层又充当视图层,这就导致了V和C这两层耦合在一起,当业务比较复杂时,Activity/Fragment文件就很庞大,导致难以维护和测试。

mvp模式
参考链接:MVP模式:从最简单的mvp开始

M 指模型层(同MVC)
V 指视图层(同MVC)
P 指业务层(业务逻辑)
Activity/Fragment只充当视图层,不做任何的业务逻辑,将业务逻辑全部放在业务层,由Presenter和Model进行交互,避免Model直接操作View。MVP的优点:将业务从Activity/Fragment分离,便于后期维护和测试。MVP使用特点是面向接口编程

四、Java

Handeler

Handler机制主要由HandlerMessageQueue,Looper三个类实现,Handler把Message放进MessageQueue里面,looper循环读取MessageQueue中的消息,然后交由消息的targer处理,由于在Thread A中调用sendMessage()方法,Looper在Thread B中运行处理消息,因此能实现线程的切换。

MessageQueue 作用是存储消息,它的数据结构是一个单列表,MessageQueue主要有插入和读取删除两个操作

Looper 主要就是循环读取MessageQueue中的消息,然后交由Handler处理

Handler 主要职责就是发送和处理消息.
Handler工作流程

数据库SQLite

参考链接:
1、Android Studio SQLite数据库
2、Android Studio 通过一个登录功能介绍SQLite数据库的使用

模块化编程
掌握常用开源框架
1、Retrofit+Rxjava(网络库+异步)

参考链接:Android Retrofit + RxJava使用详解

Retrofit可以理解成一个封装好的网络请求库,是基于OkHttp进行封装的
Retrofit GitHub地址

Rxjava 的本质可以压缩为异步这一个词。说到根上,它就是一个实现异步操作的库
给 Android 开发者的 RxJava 详解

假设有这样一个需求:界面上有一个自定义的视图 imageCollectorView ,它的作用是显示多张图片,并能使用 addImage(Bitmap) 方法来任意增加显示的图片。现在需要程序将一个给出的目录数组 File[] folders 中每个目录下的 png 图片都加载出来并显示在 imageCollectorView 中。需要注意的是,由于读取图片的这一过程较为耗时,需要放在后台执行,而图片的显示则必须在 UI 线程执行。常用的实现方式有多种,其中之一:

new Thread() {    
	@Override    
	public void run() {        
		super.run();        
		for (File folder : folders) {            
			File[] files = folder.listFiles();           
 			for (File file : files) {                
 				if (file.getName().endsWith(".png")) {                    
 					final Bitmap bitmap = getBitmapFromFile(file);                    
 					getActivity().runOnUiThread(new Runnable() {                        
						 @Override                        
 						public void run() {                            
 							imageCollectorView.addImage(bitmap);                        
 						}                    
					 });                
 				}           
 	 		}        
  		}    
  }
}.start();

而如果使用 RxJava ,实现方式是这样的:
Observable(被观察者)

Observable.from(folders)    
		  .flatMap(new Func1<File, Observable<File>>() {        
				@Override        
				public Observable<File> call(File file) {            
					return Observable.from(file.listFiles());        
				}    
		  }).filter(new Func1<File, Boolean>() {        
				@Override        
				public Boolean call(File file) {            
					return file.getName().endsWith(".png");        
				}    
		  }).map(new Func1<File, Bitmap>() {        
				@Override       
 				public Bitmap call(File file) {            
 					return getBitmapFromFile(file);        
 				}    
 		 }) .subscribeOn(Schedulers.io())    
 			.observeOn(AndroidSchedulers.mainThread())    
 			.subscribe(new Action1<Bitmap>() {        
				 @Override       
  				public void call(Bitmap bitmap) {            
  					imageCollectorView.addImage(bitmap);        
  				}    
  		 });
2、volley

参考链接:Android Volley框架详细
Volley它适用于数据请求频繁且数据量较小的操作,本身就是异步,所以不需要再写异步请
关于Volley的思维导图

3、gson(json数据处理)
4、okhttp(网络库)
5、eventBus(事件传递总线)
6、arouter(路由)
7、greenDao(数据库)
8、glide(图片处理)

四、内存

内存优化

参考链接:

内存泄漏(out-of-memory,OOM)

参考链接:
Android常见内存泄漏分析
Android内存泄漏检测和定位

五、 Git/SVN 代码管理工具

六、Gradle

参考链接:这一次彻底弄明白Gradle
Gradle 本身并不知道如何编译 APK 文件,因为 Gradle 实际上是一个通用的构建工具。它不限于构建 Android 应用程序。
Android Plugin for Gradle 是一个使 Gradle 能够将您的代码编译成用你的密钥签名 APK 文件的插件,甚至将 APK 安装到你的模拟器或测试设备上。这个插件驱动你的整个构建系统。

常用配置。

多渠道打包。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值