border++;
}
}
for(int j=0;j<a.length;j++){
System.out.println(a[j]);
}
}
//方法2
public void setParted1(int[] a,int left,int right){
if(left>=right||lefta.length||right0){
for(int i=0;i<a.length;i++){
System.out.println(a[i]);
}
return ;
}
while(a[left]<0){
left++;
}
while(a[right]>=0){
right–;
}
if(left>=right||lefta.length||right0){
for(int i=0;i<a.length;i++){
System.out.println(a[i]);
}
return;
}
swap(a,left,right);
left++;
right–;
setParted1(a,left,right);
}
private void swap(int a[],int left,int right){
int temp=0;
temp=a[left];
a[left]=a[right];
a[right]=temp;
}
public static void main(String[] args) {
int a[]={1,2,-1,-5,-6,7,-7,-10};
new PartTest().setParted1(a,0,a.length-1);
}
显然,第二种实现的难点比较高,不过只要此种满足条件。
第二面
1,bundle的数据结构,如何存储,既然有了Intent.putExtra,为啥还要用bundle。
bundle的内部结构其实是Map,传递的数据可以是boolean、byte、int、long、float、double、string等基本类型或它们对应的数组,也可以是对象或对象数组。当Bundle传递的是对象或对象数组时,必须实现Serializable 或Parcelable接口。
2,android的IPC通信方式,是否使用过
这方面的资料比较多,也不方便阐述
3,Android的多点触控如何传递 核心类
4,asynctask的原理 AsyncTask是对Thread和Handler的组合包装。
5,android 图片加载框架有哪些,对比下区别
6,图片框架的一些原理知识
7,其他的一些Android的模块化开发,热更新,组件化等知识。
三面;主流框架
在Android面试的时候,经常会被问到一些Android开发中用到的一些开发框架,如常见的网络请求框架Retrofit/OkHttp,组件通信框架EventBus/Dagger2,异步编程RxJava/RxAndroid等。结合本次面试,整理下上面的几个框架,大家可以拿去,面试备用
1. EventBus
EventBus是一个Android发布/订阅事件总线,简化了组件间的通信,让代码更加简介,但是如果滥用EventBus,也会让代码变得更加辅助。
面试EventBus的时候一般会谈到如下几点
(1)EventBus是通过注解+反射来进行方法的获取的
(2)使用ConcurrentHashMap来保存映射关系 调用实体的构建:调用实体中对于Object,也就是实际执行方法的对象不应该使用强引用而是应该使用弱引用,因为Map的static的,生命周期有可能长于被调用的对象,如果使用强引用就会出现内存泄漏的问题。
(3)方法的执行 使用Dispatcher进行方法的分派,异步则使用线程池来处理,同步就直接执行,而UI线程则使用MainLooper创建一个Handler,投递到主线程中去执行。
2.Retrofit
要明确EventBus中最核心的,就是动态代理技术。
Java中的动态代理:
首先动态代理是区别于静态代理的,代理模式中需要代理类和实际执行类同时实现一个相同的接口,并且在每个接口定义的方法前后都要加入相同的代码,这样有可能很多方法代理类都需要重复。而动态代理就是将这个步骤放入运行时的过程,一个代理类只需要实现InvocationHandler接口中的invoke方法,当需要动态代理时只需要根据接口和一个实现了InvocationHandler的代理对象A生成一个最终的自动生成的代理对象A_。这样最终的代理对象A_无论调用什么方法,都会执行InvocationHandler的代理对象A的invoke函数,你就可以在这个invoke函数中实现真正的代理逻辑。
Retrofit中的动态代理
Retrofit中使用了动态代理是不错,但是并不是为了真正的代理才使用的,它只是为了动态代理一个非常重要的功能,就是“拦截”功能。我们知道动态代理中自动生成的A_对象的所有方法执行都会调用实际代理类A中的invoke方法,再由我们在invoke中实现真正代理的逻辑,实际上也就是A_的所有方法都被A对象给拦截了。 而Retrofit的功能就是将代理变成像方法调用那么简单。
Retrofit作用
Retrofit实际上是为了更方便的使用Okhttp,因为Okhttp的使用就是构建一个Call,而构建Call的大部分过程都是相似的,而Retrofit正是利用了代理机制带我们动态的创建Call,而Call的创建信息就来自于你的注解。
3.OkHttp
请求任务队列
Okhttp使用了一个线程池来进行异步网络任务的真正执行,而对于任务的管理采用了任务队列的模型来对任务执行进行相应的管理,有点类似服务器的反向代理模型。Okhttp使用分发器Dispatcher来维护一个正在运行任务队列和一个等待队列。如果当前并发任务数量小于64,就放入执行队列中并且放入线程池中执行。而如果当前并发数量大于64就放入等待队列中,在每次有任务执行完成之后就在finally块中调用分发器的finish函数,在等待队列中查看是否有空余任务,如果有就进行入队执行。Okhttp就是使用任务队列的模型来进行任务的执行和调度的。
复用连接池
Http使用的TCP连接有长连接和短连接之分,对于访问某个服务器的频繁通信,使用短连接势必会造成在建立连接上大量的时间消耗;而长连接的长时间无用保持又会造成资源你的浪费。Okhttp底层是采用Socket建立流连接,而连接如果不手动close掉,就会造成内存泄漏,那我们使用Okhttp时也没有做close操作,其实是Okhttp自己来进行连接池的维护的。在Okhttp中,它使用类似引用计数的方式来进行连接的管理,这里的计数对象是StreamAllocation,它被反复执行aquire与release操作,这两个函数其实是在改变Connection中的
List<WeakReference<StreamAllocation>>
大小。List中Allocation的数量也就是物理socket被引用的计数(Refference Count),如果计数为0的话,说明此连接没有被使用,是空闲的,需要通过淘汰算法实现回收。
4. RxJava
从15年开始,前端掀起了一股异步编程的热潮,在移动Android编程过程中,经常会听到观察者与被观察者等概念。
观察者与被观察者通信
Observable的通过create函数创建一个观察者对象。
public final static Observable create(OnSubscribe f) {
return new Observable(hook.onCreate(f));
}
Observable的构造函数如下:
protected Observable(OnSubscribe f) {
this.onSubscribe = f;
}
创建了一个Observable我们记为Observable1,保存了传入的OnSubscribe对象为onSubscribe,这个很重要,后面会说到。
onSubscribe方法
public final Subscription subscribe(Subscriber<? super T> subscriber) {
return Observable.subscribe(subscriber, this);
}
private static Subscription subscribe(Subscriber<? super T> subscriber, Observable observable) {
…
subscriber.onStart();
onSubscribe.call(subscriber);
return hook.onSubscribeReturn(subscriber);
}
线程切换过程(Scheduler)
RxJava最好用的特点就是提供了方便的线程切换,但它的原理归根结底还是lift,使用subscribeOn()的原理就是创建一个新的Observable,把它的call过程开始的执行投递到需要的线程中;而 observeOn() 则是把线程切换的逻辑放在自己创建的Subscriber中来执行。把对于最终的Subscriber1的执行过程投递到需要的线程中来进行。
Android进阶之路
对我们开发者来说,一定要打好基础,随时准备战斗。不论寒冬是否到来,都要把自己的技术做精做深。虽然目前移动端的招聘量确实变少了,但中高端的职位还是很多的,这说明行业只是变得成熟规范起来了。竞争越激烈,产品质量与留存就变得更加重要,我们进入了技术赋能业务的时代。
**技术之路就是漫长的打怪升级,不断学习前人的踩坑经验才能提升自己,切忌闭门造车!**所谓独乐乐不如众乐乐,在我当时确立好Android方向时,就已经开始梳理自己的成长路线了,包括技术要怎么系统地去学习,都列得非常详细,免费分享给大家。
从架构基础开始,分了8个模块来逐步从基础进阶到架构师的环节:
架构师筑基语言基础
目前Android APP开发主流语言就是Java语言,Java语言最大的特性就是提高了软件的交互可能性,可以说安卓手机几乎所有应用程序都是利用Java语言来进行编写的。
设计思想解读开源框架
最后
赠送大家一套完整的Android学习资料吧。
以前一直是自己在网上东平西凑的找,找到的东西也是零零散散,很多时候都是看着看着就没了,时间浪费了,问题却还没得到解决,很让人抓狂。
后面我就自己整理了一套资料,还别说,真香!
资料有条理,有系统,还很全面,我不方便直接放出来,大家可以先看看有没有用得到的地方吧。
附上白嫖地址:《Android架构视频+BATJ面试专题PDF+学习笔记》
%E4%B8%8D%E4%BC%9A%E8%BF%99%E4%BA%9B%EF%BC%9F%E5%A6%82%E4%BD%95%E9%9D%A2%E8%AF%95%E6%8B%BF%E9%AB%98%E8%96%AA%EF%BC%81.md)**
[外链图片转存中…(img-TjjC6FXa-1643795293010)]
[外链图片转存中…(img-59CsBtTk-1643795293010)]
[外链图片转存中…(img-IOlrOmnu-1643795293011)]
[外链图片转存中…(img-ldkpKFQu-1643795293011)]
[外链图片转存中…(img-8lf4YjJO-1643795293011)]