Android面试题(六)

您所在的位置:网站首页 胜天半子超清图片 Android面试题(六)

Android面试题(六)

2023-07-12 04:58| 来源: 网络整理| 查看: 265

六、常用算法

1、快速排序

 

把整个序列看做一个数组,把第零个位置看做中轴,和最后一个比,如果比它小交换,比它大不做任何处理;交换了以后再和小的那端比,比它小不交换,比他大交换。这样循环往复,一趟排序完成,左边就是比中轴小的,右边就是比中轴大的,然后再用分治法,分别对这两个独立的数组进行排序。

 

public class QuickSort {

private static int[] a = {6,1,2,7,9,3,4,5,10,8};

public static void main(String[] args){

System.out.println("原数组值:");

for (int i : a) {

System.out.print(i+" ");

}

System.out.println();

quickSort(0, a.length-1);

System.out.println("排序后数组值:");

for (int i : a) {

System.out.print(i+" ");

}

System.out.println();

}

public static void quickSort(int left,int right){

int i,j,temp;

if(left>right){

return;

}

temp=a[left]; //temp中存的就是基准数

i=left;

j=right;

while(i!=j){

//顺序很重要,要先从右边开始找 ,直到找到一个小于基准的值

while(a[j]>=temp && i

i++;

}

//交换两个数在数组中的位置

if(i

quickSort(left,i-1);//继续处理左边的,这里是一个递归的过程

}

if(right>j+1){

quickSort(i+1,right);//继续处理右边的 ,这里是一个递归的过程

}

}

}

2、选择排序

从数组一端选择一个数组中的一个元素,通过比较对比取出最小值(或者最大值)放在array的左边(右边 这里主要视遍历的开始为左还是右);逐个遍历;

/**选择排序

*遍历数组 然后每次遍历到一个元素之后 继续遍历该元素之后的所有元素 然后找 到最小的元素 和其换位置*/

public static int[] select(int[] array){

for (int i = 0; i < array.length; i++) {

int minPos = i;

for (int j = i + 1; j < array.length; j++) {

if (array[j] < array[minPos]){

minPos = j;

}

}

if (array[i] > array[minPos]){

int temp = array[i];

array[i] = array[minPos];

array[minPos] = temp;

}

}

return array;

}

3、插入排序

/***插入排序

*相当于 从0开始一直++ 然后一直排列索引跟之前的元素

* */

public static int[] insert(int[] array){

for (int i = 1; i < array.length; i++) {

int temp = array[i];

for (int j = i - 1; j >= 0 ; j--) {

if (array[j] > temp ){

array[j + 1] = array[j];

array[j] = temp;

}

 

}

 

}

return array;

}

4、冒泡排序

每次冒泡排序操作都会将相邻的两个元素进行比较,看是否满足大小关系要求,如果不满足,就交换这两个相邻元素的次序,一次冒泡至少让一个元素移动到它应该排列的位置,重复N次,就完成了冒泡排序。

public void bubbleSort(Integer[] arr) {

for(int i=0;i

if(arr[j]>arr[j+1]) {

int temp=arr[j];

arr[j]=arr[j+1];

arr[j+1]=temp;

}

}

}

}

七、图片处理

1、Android缓存机制——LruCache

LRU是近期最少使用的算法,它的核心思想是当缓存满时,会优先淘汰那些近期最少使用的缓存对象。采用LRU算法的缓存有两种:LrhCache和DisLruCache,分别用于实现内存缓存和硬盘缓存,其核心思想都是LRU缓存算法。

import android.util.LruCache;

public class MyImageLoader {

private LruCache mLruCache;

public MyImageLoader(){

//设置最大缓存空间为运行时内存的1/8

int maxMemory = (int) (Runtime.getRuntime().totalMemory()/1024);

int cacheSize = maxMemory / 8;

mLruCache = new LruCache(cacheSize){

@Override

protected int sizeOf(String key, Bitmap value) {

return value.getRowBytes()*value.getHeight()/1024;

}

};

}

 

/**

* 添加图片到LruCache

* @param key

* @param bitmap

*/

public void addBitmap(String key,Bitmap bitmap){

if (getBitmap(key) == null){

mLruCache.put(key,bitmap);

}

}

 

/**

* 从缓存中获取图片Bitmap

* @param key

* @return

*/

public Bitmap getBitmap(String key){

return mLruCache.get(key);

}

 

/**

* 从缓存中删除指定的Bitmap

* @param key

*/

public void removeBitmapFromMemory(String key){

mLruCache.remove(key);

}

}

LruCache的核心思想很好理解,就是要维护一个缓存对象列表,其中对象列表的排列方式是按照访问顺序实现的,即一直没访问的对象,将放在队尾,即将被淘汰。而最近访问的对象将放在队头,最后被淘汰。

LruCache中维护了一个集合LinkedHashMap,该LinkedHashMap是以访问顺序排序的。当调用put()方法时,就会在结合中添加元素,并调用trimToSize()判断缓存是否已满,如果满了就用LinkedHashMap的迭代器删除队尾元素,即近期最少访问的元素。当调用get()方法访问缓存对象时,就会调用LinkedHashMap的get()方法获得对应集合元素,同时会更新该元素到队头。

 

2、Android图片库对比

Android主流图片加载库

PicassoGlideFresco

介绍& 对比

1.Picasso

Picasso中文翻译为’毕加索’,由Square公司开源的一个适用于Android的强大图像下载和缓存库.

功能介绍

图片的异步加载(最基础功能)使用最少的内存完成复杂的图片转换,转换图片以适合所显示的ImageView,来减少内存消耗支持加载过程中和加载错误时显示对应图片在Adapter中的回收不在视野的ImageView和取消已经回收的ImageView下载进程支持加载多种数据源 网络、本地、资源、Assets 等自动添加磁盘和内存二级缓存功能支持优先级处理支持飞行模式、并发线程数根据网络类型而变Picasso 没有实现本地缓存功能,交给了 Square 的另外一个网络库 okhttp 去实现,这样的好处是可以通过请求 Response Header 中的 Cache-Control 及 Expired 控制图片的过期时间。 

与其他开源库对比

优点如下:

使用简单,代码简洁与Square 公司的其他开源库如 Retrofit 或者 OkHttp搭配使用兼容性会更好些,占用体积也会少些

缺点如下:

功能较为简单-图片加载;性能(加载速度等等)较(Glide、Fresco)较差自身无实现“本地缓存”

 

2.Glide

Glide是由Google开源的一个图片加载库,是一款快速高效的Android开源媒体管理和图像加载框架,它将媒体解码,内存和磁盘缓存以及资源池包装成简单易用的界面.

功能介绍

图片的异步加载(基础功能)支持设置加载尺寸、设置加载中以及加载失败图片、设置加载动画、设置图文混排多样式的媒体加载(设置缩略图支持:先加载缩略图 然后在加载全图)支持设置磁盘缓存策略、设置跳过内存缓存、清理缓存生命周期集成(然而还是有bug)

与其他开源库对比

优点如下:

支持多样化媒体加载 Glide 不仅是一个图片缓存,它支持 Gif、WebP、缩略图,甚至是 Video生命周期集成 通过设置绑定生命周期,我们可以更加高效的使用Glide提供的方式进行绑定,这样可以更好的让加载图片的请求的生命周期动态管理起来(使用还是有bug)高效的缓存策略 1.支持Memory和Disk图片缓存 2.Picasso 只会缓存原始尺寸的图片,而 Glide 缓存的是多种规格,即 Glide 会根据你 ImageView 的大小来缓存相应大小的图片尺寸 3.内存开销小,Glide 默认的 Bitmap 格式是 RGB_565 格式,而 Picasso 默认的是 ARGB_8888 格式,占用内存要小一半

缺点如下:

使用方法复杂,实现方法较多使用较Fresco简单,但性能(加载速度 & 缓存)却比不上Fresco

3.Fresco

Fresco是由Facebook开源的用于管理图像及其使用内存的Android库

功能介绍

具体功能请前往官方文档查看

优点如下

大大减少了OOM的发生,Facebook在底层使用了C++技术解决图片缓存问题使用简单,几乎全部功能都能在XML文件中直接制定

缺点如下:

用法变得更加复杂了依赖包更加大了(2-3M)底层设计C++等技术,源码阅读更加困难

 

3、图片加载库-Glide源码分析

glide:3.7.0 使用

引入

compile 'com.github.bumptech.glide:glide:3.7.0'

混淆

-keep public class * implements com.bumptech.glide.module.GlideModule -keep public class * extends com.bumptech.glide.module.AppGlideModule -keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** { **[] $VALUES; public *; } # for DexGuard only -keepresourcexmlelements manifest/application/meta-data@value=GlideModule

使用

使用的方式十分简单,和Picasso差不多

Glide.with(this).load(imgUrl) .placeholder(R.drawable.ic_launcher_background) .into(mIv);

同样也可以为他设置其他,例如 listener 、 centerCrop 、transform 、 sizeMultiplier

.listener(new RequestListener() { @Override public boolean onException(Exception e, String model, Target target, boolean isFirstResource) { return false; } @Override public boolean onResourceReady(GlideDrawable resource, String model, Target target, boolean isFromMemoryCache, boolean isFirstResource) { return false; } }) .centerCrop() ....

之类的,这些使用的方法和Picasso十分类似。

使用和源码分析:

https://blog.csdn.net/qq_37237245/article/details/72956121

https://www.jianshu.com/p/8771a7142eea

内存缓存

Glide内存缓存的实现自然也是使用的LruCache算法。不过除了LruCache算法之外,Glide还结合了一种弱引用的机制,共同完成了内存缓存功能。

Glide的图片加载过程中会调用两个方法来获取内存缓存,loadFromCache()和loadFromActiveResources()。这两个方法中一个使用的就是LruCache算法,另一个使用的就是弱引用。

 

当acquired变量大于0的时候,说明图片正在使用中,也就应该放到activeResources弱引用缓存当中。而经过release()之后, 如果acquired变量等于0了,说明图片已经不再被使用了,那么此时会调用listener的onResourceReleased()方法来释放资源

 

当图片不再使用时,首先会将缓存图片从activeResources中移除,然后再将它put到LruResourceCache当中。这样也就实现了正在使用中的图片使用弱引用来进行缓存,不在使用中的图片使用LruCache来进行缓存的功能。

 

硬盘缓存

Glide是使用的自己编写的DiskLruCache工具类,但是基本的实现原理都是差不多的。

 

一种是调用decodeFromCache()方法从硬盘缓存当中读取图片,一种是调用decodeFromSource()来读取原始图片。默认情况下Glide会优先从缓存当中读取,只有缓存中不存在要读取的图片时,才会去读取原始图片。

 

调用transform()方法来对图片进行转换,然后在writeTransformedToCache()方法中将转换过后的图片写入到硬盘缓存中,调用的同样是DiskLruCache实例的put()方法,不过这里用的缓存Key是resultKey(也就是调整图片大小后进行缓存)。

 

4、自己去实现图片库,怎么做

应该具备以下功能:

图片的同步加载图片的异步加载图片压缩内存缓存磁盘缓存网络拉取


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3