1、activity四种启动模式,singleTask启动模式是如何,以及应用场景?
答:singleTask:栈内复用模式。这是一种单实例模式,在这种模式下,只要Activity在一个栈中存在,那么多次此Activity都不会重新创建实例,同时它的onNewIntent被调用,并且处于此Activity任务栈以上的Activity全部出栈。singleTask适合作为程序入口点,例如浏览器的主界面或者是桌面悬浮框。
2、算法面试题:如何在一堆数字中快速找到出现次数最多的一个?
答:
/** 找出一个数组中一个数字出现次数最多的数字 * 用HashMap的
key来存放数组中存在的数字,value存放该数字在数组中出现的次数
*/
public static void findMaxNumber(){
int[] array = {2, 1, 2, 3, 4, 5, 2, 2, 2, 2};
//map的key存放数组中存在的数字,value存放该数字在数组中出现的次数
HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
for(int i = 0; i < array.length; i++) {
if(map.containsKey(array[i])){
int temp = map.get(array[i]);
map.put(array[i], temp + 1);
} else{
map.put(array[i], 1);
}
}
Collection<Integer> count = map.values();
//找出map的value中最大的数字,也就是数组中数字出现最多的次数
int maxCount = Collections.max(count);
int maxNumber = 0;
for(Map.Entry<Integer, Integer> entry : map.entrySet()) {
//得到value为maxCount的key,也就是数组中出现次数最多的数字
if(maxCount == entry.getValue()) {
maxNumber = entry.getKey();
}
}
Log.i(TAG,"出现次数最多的数字为:" + maxNumber);
Log.i(TAG,"该数字一共出现" + maxCount + "次");}
3、UDP和TCP区别和用途
答:
TCP(Transmission Control Protocol,传输控制协议)是基于连接的协议,也就是说,在正式收发数据前,必须和对方建立可靠的连接。一个TCP连接必须要经过三次“对话”才能建立起来,其中的过程非常复杂,我们这里只做简单、形象的介绍,你只要做到能够理解这个过程即可。我们来看看这三次对话的简单过程:主机A向主机B发出连接请求数据包:“我想给你发数据,可以吗?”,这是第一次对话;主机B向主机A发送同意连接和要求同步(同步就是两台主机一个在发送,一个在接收,协调工作)的数据包:“可以,你什么时候发?”,这是第二次对话;主机A再发出一个数据包确认主机B的要求同步:“我现在就发,你接着吧!”,这是第三次对话。三次“对话”的目的是使数据包的发送和接收同步,经过三次“对话”之后,主机A才向主机B正式发送数据。
UDP(User Data Protocol,用户数据报协议)是与TCP相对应的协议。它是面向非连接的协议,它不与对方建立连接,而是直接就把数据包发送过去!
UDP适用于一次只传送少量数据、对可靠性要求不高的应用环境。比如,我们经常使用“ping”命令来测试两台主机之间TCP/IP通信是否正常,其实“ping”命令的原理就是向对方主机发送UDP数据包,然后对方主机确认收到数据包,如果数据包是否到达的消息及时反馈回来,那么网络就是通的。例如,在默认状态下,一次“ping”操作发送4个数据包。大家可以看到,发送的数据包数量是4包,收到的也是4包(因为对方主机收到后会发回一个确认收到的数据包)。这充分说明了UDP协议是面向非连接的协议,没有建立连接的过程。正因为UDP协议没有连接的过程,所以它的通信效果高;但也正因为如此,它的可靠性不如TCP协议高。
4、线程的优先级?如何防止servie被杀死?
答:
对于Android平台上的线程优先级设置来说可以处理很多并发线程的阻塞问题,比如很多无关紧要的线程会占用大量的CPU时间,虽然通过了MultiThread来解决慢速I/O但是合理分配优先级对于并发编程来说十分重要。Android在线程方面主要使用的是Java本身的Thread类,我们可以在Thread或Runnable接口中的run方法首句加入Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); //设置线程优先级为后台,这样当多个线程并发后很多无关紧要的线程分配的CPU时间将会减少,有利于主线程的处理,相关的Thread优先级Android平台专有的定义罗列有以下几种:
int THREAD_PRIORITY_AUDIO //标准音乐播放使用的线程优先级
int THREAD_PRIORITY_BACKGROUND //标准后台程序
int THREAD_PRIORITY_DEFAULT // 默认应用的优先级
int THREAD_PRIORITY_DISPLAY //标准显示系统优先级,主要是改善UI的刷新
int THREAD_PRIORITY_FOREGROUND //标准前台线程优先级
int THREAD_PRIORITY_LESS_FAVORABLE //低于favorable
int THREAD_PRIORITY_LOWEST //有效的线程最低的优先级
int THREAD_PRIORITY_MORE_FAVORABLE //高于favorable
int THREAD_PRIORITY_URGENT_AUDIO //标准较重要音频播放优先级
int THREAD_PRIORITY_URGENT_DISPLAY //标准较重要显示优先级,对于输入事件同样适用
通过以上关于线程优先级的分析,可采用通过闹钟(AlertManager) 定时唤醒,触发onStartCommond方法,从而服务进程不被杀死
5、Http方式下载图片资源,如何解决手机提供商访问劫持?
答:
通过在Http Header头中设置标识信息,如token或者文件名称或文件MD5值,从而识别当前下载的图片,是否为目标文件,这种做法也可以用在头像的动态更新。
6、如何防止网页代码挟持,如字符串javascript:alert("hello");
答:面试题目没有理解清楚,无法作答
7、TCP如何防止消息体阻塞?
答:发送消息体后,再收到ack消息回执后,在发送第二个,从而保证消息发送在网络不是很好的情况下,出现消息阻塞现象。
8、android里面main函数入口?
答:每个应用启动,zygote进程的ZygoteInit()方法创建的一个新进程,即ActivityThread(UI主线程),同时执行main函数。而main函数的入口,则对于的是Androidmanifest.xml注册<action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" />的activity。
9、简述常用设计模式
答:观察者模式和策略模式。
10、ListView的优化方式?
答:通过新建静态ViewHolder类,contentView.setTag()方式复用布局,从而减少内存开销,图片加载则可以采用facebook的fresco框架,可以避免应用OOM。
11、用过哪些android内存分析工具?
答:Memory Monitor、Allocation Tracking、Heap Tool 与 MAT、LeakCanary(开源项目)。
12、Handler和Message的区别和联系?
答:
Handler简介:
一个Handler允许你发送和处理Message和Runable对象,这些对象和一个线程的MessageQueue相关联。每一个线程实例和一个单独的线程以及该线程的MessageQueue相关联。当你创建一个新的Handler时,它就和创建它的线程绑定在一起了。这里,线程我们也可以理解为线程的MessageQueue。从这一点上来看,Handler把Message和Runable对象传递给MessageQueue,而且在这些对象离开MessageQueue时,Handler负责执行他们。
Handler有两个主要的用途:(1)确定在将来的某个时间点执行一个或者一些Message和Runnable对象。(2)在其他线程(不是Handler绑定线程)中排入一些要执行的动作。
Scheduling Message,即(1),可以通过以下方法完成:
post(Runnable):Runnable在handler绑定的线程上执行,也就是说不创建新线程。
postAtTime(Runnable,long):
postDelayed(Runnable,long):
sendEmptyMessage(int):
sendMessage(Message):
sendMessageAtTime(Message,long):
sendMessageDelayed(Message,long):
post这个动作让你把Runnable对象排入MessageQueue,MessageQueue受到这些消息的时候执行他们,当然以一定的排序。sendMessage这个动作允许你把Message对象排成队列,这些Message对象包含一些信息,Handler的hanlerMessage(Message)会处理这些Message.当然,handlerMessage(Message)必须由Handler的子类来重写。这是编程人员需要作的事。
当posting或者sending到一个Hanler时,你可以有三种行为:当MessageQueue准备好就处理,定义一个延迟时间,定义一个精确的时间去处理。后两者允许你实现timeout,tick,和基于时间的行为。
当你的应用创建一个新的进程时,主线程(也就是UI线程)自带一个MessageQueue,这个MessageQueue管理顶层的应用对象(像activities,broadcastreceivers等)和主线程创建的窗体。你可以创建自己的线程,并通过一个Handler和主线程进行通信。这和之前一样,通过post和sendmessage来完成,差别在于在哪一个线程中执行这么方法。在恰当的时候,给定的Runnable和Message将在Handler的MessageQueue中被Scheduled。
Message简介:
Message类就是定义了一个信息,这个信息中包含一个描述符和任意的数据对象,这个信息被用来传递给Handler.Message对象提供额外的两个int域和一个Object域,这可以让你在大多数情况下不用作分配的动作。
尽管Message的构造函数是public的,但是获取Message实例的最好方法是调用Message.obtain(),或者Handler.obtainMessage()方法,这些方法会从回收对象池中获取一个。
MessageQueue简介:
这是一个包含message列表的底层类。Looper负责分发这些message。Messages并不是直接加到一个MessageQueue中,而是通过MessageQueue.IdleHandler关联到Looper。
你可以通过Looper.myQueue()从当前线程中获取MessageQueue。
Looper简介:
Looper类被用来执行一个线程中的message循环。默认情况,没有一个消息循环关联到线程。在线程中调用prepare()创建一个Looper,然后用loop()来处理messages,直到循环终止。
大多数和message
loop的交互是通过Handler。
13、对c++语言的了解?
答:了解c++基本语法,熟悉NDK中java和c++之间的相互调用。
14、如何理解android中跨进程通信?
1、AIDL:定义了客户端可用的方法和数据的接口,另一个应用通过绑定服务,绑定成功后,就可以调用aidl定义的方法;
2、ContentProvider:内容提供者,夸应用通过Uri访问封装SQLite3增、删、改、查方法。
15、谈谈对framework层launcher的理解
答:
16、apk中的resource.arsc文件是用来存放什么的?
答:用于存放资源文件,如:drawable,menu,layout,string,attr,color,style。
17、对于android逆向原生的理解
答:《Android软件安全与逆向分析》,通过修改smali语句,重新加壳和重新打包,可以防止应用信息被劫持或者支付不安全现象。
18、对于静态变量的内存回收处理
答: