安卓SDK常见面试题

2020-12-01  本文已影响0人  陈二狗想吃肉

1,断点续传原理?

在本地下载过程中要使用数据库实时存储到底存储到文件的哪个位置了,这样点击开始继续传递时,才能通过HTTP的GET请求中的setRequestProperty()方法可以告诉服务器,数据从哪里开始,到哪里结束。

同时在本地的文件写入时,RandomAccessFile的seek()方法也支持在文件中的任意位置进行写入操作。同时通过广播将子线程的进度告诉Activity的ProcessBar。

2,android网络图片加载优化?

1.找现有图片格式的替换者

在众多的图片格式中,选择了Google的WebP。原因很简单:压缩效率高,而且对Android的支持好(毕竟就是Google提出来的)。使用 WebP 之后,相对于JPG格式的图片,流量省了将近 25% 到 35 %;相对于 PNG 格式的图片,流量省了将近80%。最重要的是使用WebP之后图片质量还没改变。

2.按照设备处理图片的能力来加载图片

在之前,都是统一加载最大分辨率的图片,这样做是为了让用户可以自由的缩放图片。后来改进之后,app最先加载的图片大小适合显示这个图片窗口大小一样。如果需要缩略图,app就只加载缩略图大小的图片,用户需要更高分辨率的图片,app也能加载,而且之前的统一加载最大分辨率的图片了。

3.调整缓存和重用图片的策略。

使用手机的缓存,对经常使用的图片,比如首页的图片,以及经常点开的图片设置算法进行缓存

4.优化网络请求

使用OkHttp。OkHttp 支持在糟糕的网络环境下面更快的重试,并且还能利用 SPDY 协议进行快速的并发网络请求。

利用Okhttp调整图片的预先抓取算法,确保app中下载队列前面的图片被优先处理,防止队列阻塞时间过长。

3,Android内存泄露及管理

(1)内存溢出(OOM)和内存泄露(对象无法被回收)的区别。 (2)引起内存泄露的原因

(3)内存泄露检测工具---->LeakCanary

内存溢出 out of memory:是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出。内存溢出通俗的讲就是内存不够用。

内存泄露 memory leak:是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光;

内存泄露原因:

Handler 引起的内存泄漏。

解决:将Handler声明为静态内部类,就不会持有外部类SecondActivity的引用,其生命周期就和外部类无关,如果Handler里面需要context的话,可以通过弱引用方式引用外部类

单例模式引起的内存泄漏。

解决:Context是ApplicationContext,由于ApplicationContext的生命周期是和app一致的,不会导致内存泄漏

非静态内部类创建静态实例引起的内存泄漏。

解决:把内部类修改为静态的就可以避免内存泄漏了

非静态匿名内部类引起的内存泄漏。

解决:将匿名内部类设置为静态的。

注册/反注册未成对使用引起的内存泄漏。

注册广播接受器、EventBus等,记得解绑。

资源对象没有关闭引起的内存泄漏。

在这些资源不使用的时候,记得调用相应的类似close()、destroy()、recycler()、release()等方法释放。

集合对象没有及时清理引起的内存泄漏。

通常会把一些对象装入到集合中,当不使用的时候一定要记得及时清理集合,让相关对象不再被引用。

4,mvc、mvp、mvvm:

1.mvc:数据、View、Activity,View将操作反馈给Activity,Activitiy去获取数据,数据通过观察者模式刷新给View。循环依赖

1.Activity重,很难单元测试

2.View和Model耦合严重

2.mvp:数据、View、Presenter,View将操作给Presenter,Presenter去获取数据,数据获取好了返回给Presenter,Presenter去刷新View。PV,PM双向依赖

1.接口爆炸

2.Presenter很重

3.mvvm:数据、View、ViewModel,View将操作给ViewModel,ViewModel去获取数据,数据和界面绑定了,数据更新界面更新。

1.viewModel的业务逻辑可以单独拿来测试

2.一个view 对应一个 viewModel 业务逻辑可以分离,不会出现全能类

3.数据和界面绑定了,不用写垃圾代码,但是复用起来不舒服

5,Binder 机制

Binder的工作机制

直观来说,Binder是Android中的一个类,它实现了IBinder接口,从IPC的角度来说,Binder是Android中的一种跨进程通信的一种方式,同时还可以理解为是一种虚拟的物理设备,它的设备驱动是/dev/binder/。从Framework角度来说,Binder是ServiceManager的桥梁。从应用层来说,Binder是客户端和服务端进行通信的媒介。

我们先来了解一下这个类中每个方法的含义:

DESCRIPTOR:Binder的唯一标识,一般用于当前Binder的类名表示。

asInterface(android.os.IBinder obj):用于将服务端的Binder对象转换成客户端所需的AIDL接口类型的对象,这种转化过程是区分进程的,如果客户端和服务端位于同一个进程,那么这个方法返回的是服务端的stub对象本身,否则返回的是系统封装后的Stub.proxy对象。

asBinder():用于返回当前Binder对象。

onTransact:该方法运行在服务端的Binder线程池中,当客户端发起跨进程通信请求的时候,远程请求通过系统底层封装后交给该方法处理。注意这个方法public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags),服务端通过code可以确定客户端所请求的目标方法是什么,接着从data中取出目标方法所需的参数,然后执行目标方法。当目标方法执行完毕后,就像reply中写入返回值。这个方法的执行过程就是这样的。如果这个方法返回false,客户端是会请求失败的,所以我们可以在这个方法中做一些安全验证。

Binder的工作机制但是要注意一些问题:1、当客户端发起请求时,由于当前线程会被挂起,直到服务端返回数据,如果这个远程方法很耗时的话,那么是不能够在UI线程,也就是主线程中发起这个远程请求的。

2、由于Service的Binder方法运行在线程池中,所以Binder方法不管是耗时还是不耗时都应该采用同步的方式,因为它已经运行在一个线程中了。

6,用过什么图片加载框架,怎么做技术选型的:

(1)分别有ImageLoader, Picasso, GLide, Fresco,ImageLoader是比较久远的库,Picasso比Glide包体要小,但是加载性能没Glide好(GLide支持三级缓存和生命周期绑定,picasso不支持磁盘缓存,且glide默认采用RGB565,picasso是RGB8888),Fresco加载性能最好,功能最齐全(通过开辟一个共享内存从而做到了不占用堆内存)

总结是应用需要处理较多图片时采用Fresco,一般情况下Glide可以满足需求;

(2)讲下Glide的缓存原理(这里会结合你在项目中用到的框架,这里以Glide举例)

相较于常见的内存+磁盘缓存,Glide将其缓存分成了4层。

活动资源 (Active Resources):

当需要加载某张图片能够从内存缓存中获得的时候,在图片加载时主动将对应图片从内存缓存中移除,加入到活动资源中。

这样也可以避免因为达到内存缓存最大值或者系统内存压力导致的内存缓存清理,从而释放掉活动资源中的图片(recycle)。

活动资源中是一个”引用计数"的图片资源的弱引用集合。

因为同一张图片可能在多个地方被同时使用,每一次使用都会将引用计数+1,而当引用计数为0时候,则表示这个图片没有被使用也就是没有强引用了。这样则会将图片从活动资源中移除,并加入内存缓存。

内存缓存 (Memory Cache):内存缓存默认使用LRU(缓存淘汰算法/最近最少使用算法),当资源从活动资源移除的时候,会加入此缓存。使用图片的时候会主动从此缓存移除,加入活动资源。

资源类型(Resource Disk Cache):被解码后的图片写入磁盘文件中,解码的过程可能修改了图片的参数(如:inSampleSize、inPreferredConfig)

原始数据 (Data Disk Cache):图片原始数据在磁盘中的缓存(从网络、文件中直接获得的原始数据)

其中Glide将磁盘缓存分为了 资源类型(Resource Disk Cache)和 原始数据 (Data Disk Cache);

7,线程:(1)线程的状态(2)线程的创建(3)Thread为什么不能用stop方法停止线程

(4)锁(5)ThreadLocal的理解(6)线程池等

8,GC机制

(1)垃圾回收机制的主要解决问题和主要任务;

(2)判断方法:引用计数法和可达性分析法其中相关知识点

注:在Java中可作为GCRoots的对象:1).虚拟机栈(栈帧中的本地变量表)中引用的对象;2).方法区中类静态属性引用的对象;3).方法区中常量引用的对象;4).本地方法栈中JNI引用的对象

(3)垃圾收集算法;

(4)垃圾收集器;

(5)了解JVM内存模型

9,hashmap的底层数据结构,为什么HashMap线程不安全(hash碰撞与扩容导致)?

10,大图加载的核心原理;

BitmapRegionDecoder:区域解码器;

加载大图,支持拖动查看,双击放大,手指缩放自定义view

(1)初始化变量(2)设置需要加载的图片(3)获取View的宽高,计算缩放制(4)绘制(5)分发事件

(6)处理GestureDetector中的事件(7)处理双击事件(8)处理手指缩放事件;

11,Android性能优化

主要是从以下几个方面进行优化的: 稳定(内存溢出、崩溃) 流畅(卡顿) 耗损(耗电、流量) 安装包(APK瘦身) 影响稳定性的原因很多,比如内存使用不合理、代码异常场景考虑不周全、代码逻辑不合理等,都会对应用的稳定性造成影响。其中最常见的两个场景是:Crash 和 ANR,这两个错误将会使得程序无法使用。所以做好Crash全局监控,处理闪退同时把崩溃信息、异常信息收集记录起来,以便后续分析;合理使用主线程处理业务,不要在主线程中做耗时操作,防止ANR程序无响应发生;

(1) 稳定--内存优化

(2) 流畅--卡顿优化

1,布局优化

2,绘制优化

3,启动优化

(3) 节省-耗电优化

1,计算优化。算法,for循环优化避开浮点运算;

2,避免 Wake Lock 使用不当

3,使用Job Scheduler 管理后台任务;

(4) 安装包-APK瘦身

1,安装包的组成结构

2,减少安装包大小

冷启动和热启动;

框架方面,根据自己使用的框架加以深入了解;

12,OkHttp相关?

OkHttp支持同步和异步数据请求,但异步请求是在子线程 (因为原生OkHttp的使用时回调方法是在子线程进行的,要刷新界面还需要用Handler作处理,可以使用第三方的okhttp-utils,Okgo等等);

OkHttp里面封装了线程池、数据转换、GZIP压缩(减少流量的传输)、HTTP协议缓存等,

OKHttp优点—-使用GZip压缩减少传输的数据量,缓存(减少重复请求);

失败重试(如果你的服务有多个IP地址,如果第一次连接失败,OKHttp将使用备用地址)

OKhttp是对http协议的封装,比较底层,因此拓展性强,便于封装;

OKhttp基于NIO(JDK1.5,非阻塞式IO)效率更高

Rxjava概念,常用操作符及拓展?

简介:

一款优雅的异步框架,代替之前的AsyncTask / Handler / XXX / …

其强大的操作符和链式写法,线程切换等有助于提高开发效率和快速定位Bug

与Retrofit搭配使用更是有意想不到的效果,

底层原理:观察者模式

等一些相应的博客

缺点:

1:操作符太多会增加学习成本时间

2:使用不好,容易导致内存泄露(解决方式,推荐Rxlifecycle结合Rxjava,规避内存泄漏风险)

上一篇下一篇

猜你喜欢

热点阅读