美文网首页Android进阶之路Android开发Android开发经验谈
2020阿里大佬总结面试题系列!大厂面试之图片(含答案+学习笔记

2020阿里大佬总结面试题系列!大厂面试之图片(含答案+学习笔记

作者: 程序员的Vere | 来源:发表于2020-04-11 12:20 被阅读0次

作者:爱雨浮龙

一、图片

  1、图片库对比
  2、LRUCache原理
  3、图片加载原理
  4、自己去实现图片库,怎么做?
  5、Glide源码解析
  6、Glide使用什么缓存?
  7、Glide内存缓存如何控制大小?

参考答案:

1、图片库对比

Picasso Glide Fresco

Picasso 毕加索 Square

   Picasso 没有实现本地缓存功能,交给了 Square 的另外一个网络库 okhttp 去实现,
这样的好处是可以通过请求 Response Header 中的 Cache-Control 及 Expired 控制图片的过期时间。
  • 使用简单,代码简洁
  • Square其他类库搭配兼容性好,Retrofit OkHttp

缺点:

  • 功能简单 图片加载
  • 性能(加载速度等等)较(GlideFresco)差
  • 自身没有实现"本地缓存"

Glide Google 开源

  支持 Gif WebP Video
  生命周期继承
  高效缓存策略
  • 支持MemoryDisk缓存
  • Picasso只会缓存原始尺寸图片,而Glide缓存时多种规格
  • 内存开销小,默认 RGB_565Picasso默认是ARGB_8888

缺点:

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

Fresco Facebook

  • 大大减少OOM,底层使用C++技术解决图片缓存问题
  • 使用加单,几乎全部功能都能在xml上定制

缺点:

  • 用法变得更加复杂
  • 依赖包更大了 2~3M
  • 底层C++,阅读源码困难

juejin.im/entry/5af9a…

对比项 Picasso Glide Fresco
地址 github.com/square/pica… github.com/bumptech/gl… github.com/facebook/fr…
发布时间 2013年5月 2014年9月 2015年5月
是否支持gif false true true
是否支持webP true true true
视频缩略图 false true true
大小 100k 500 KB 2~3M
加载速度
Disk+Men Cache true true true
Easy of use low mediun difficult
star 13160 14709 12444
开发者 Square主导 Google主导 Facebook主导

详细属性对比

对比项 Glide Fresco
配置 compile 'com.github.bumptech.glide:glide:XXX.XXX' compile 'com.facebook.fresco:fresco:XXX.XXX
初始化 直接使用 Fresco.initialize(this);
layout 普通ImageView 独有的SimpleDraweeView
圆角, 圆形 需要自己实现圆角,继承自BitmapTransformation操作bitmap对象实现 通过RoundingParams设置参数
缓存 Glide内存和磁盘缓存 三级缓存,分别是 Bitmap缓存,未解码图片缓存, 文件缓存。
缓存图像大小 Glide则会根据ImageView控件尺寸获得对应的大小的bitmap来展示,从而缓存也可以针对不同的对象:原始图像(source),结果图像(result) 缓存原始图像
加载策略 Glide只有占位图 先加载小尺寸图片,再加载大尺寸的
加载进度 false true
  Bitmap myBitmap = Glide.with(上下文)  
      .load(url)  
      .asBitmap() //必须    
      .get()
  //同样在DataSubscriber中获取
  FileBinaryResource resource = (FileBinaryResource) Fresco.getImagePipelineFactory().getMainFileCache().getResource(new SimpleCacheKey(url));
  if (resource != null && resource.getFile() != null) {           
      setImage(ImageSource.uri(Uri.fromFile(resource.getFile())));
  }

2、LRUCache原理

blog.csdn.net/u010983881/…

LruCache DiskLruCache

LruCache是Android 3.1所提供的一个缓存类DisLruCache目前在Android还不是Android SDK的一部分,但Android官方文档推荐使用该算法来实现硬盘缓存。

LinkedHashMap 它使用了一个双向链表来存储Map中的Entry顺序关系,这种顺序有两种,一种是LRU顺序,一种是插入顺序

put()重要的就是在添加过缓存对象后,调用trimToSize()方法,来判断缓存是否已满,如果满了就要删除近期最少使用的算法。

trimToSize()方法不断地删除LinkedHashMap中队头的元素,即近期最少访问的,直到缓存大小小于最大值

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

3、图片加载原理

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

blog.csdn.net/github_3713…

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

5、Glide源码解析

  RequestManager with(Context context)
  RequestManager with(android.app.Activity)
  RequestManager with(android.app.Fragment)
  RequestManager with(android.support.v4.app.Fragment)
  RequestManager with(android.support.v4.app.FragmentActivity)

无论使用什么参数,最终都会进入如下三个方法创建 RequestManager

  RequestManager fragmentGet(Context context, android.app.FragmentManager fm);
  RequestManager supportFragmentGet(Context context, 
  android.support.v4.app.FragmentManager fm);
  RequestManager getApplicationManager(Context context);

结论:

  • Activity--FragmentManager--RequestManagerFragment--RequestManager,所以一个 Activity 对应一个 RequestManager
  • 一个 Fragment对应一个RequestManager
  • Activity 包含FragmentFragment包含 Fragment,若分别创建Glide请求是并不会只创建一个 RequestManager
  • 子线程发起Glide请求或传入对象为ApplicationContext,则使用全局单例的 RequestManager

创建 RequestBuilderload方法有很多:

  RequestBuilder<Drawable> load(@Nullable Bitmap bitmap);
  RequestBuilder<Drawable> load(@Nullable Drawable drawable);
  RequestBuilder<Drawable> load(@Nullable String string);
  RequestBuilder<Drawable> load(@Nullable Uri uri);
  RequestBuilder<Drawable> load(@Nullable File file);
  RequestBuilder<Drawable> load(@RawRes @DrawableRes @Nullable Integer resourceId);
  RequestBuilder<Drawable> load(@Nullable URL url);
  RequestBuilder<Drawable> load(@Nullable byte[] model);
  RequestBuilder<Drawable> load(@Nullable Object model);

看看有这么多重载方法,没一个都代表不同的加载源。 除此之外还有两个特殊的方法:

  RequestBuilder<File> downloadOnly();
  RequestBuilder<File> download(@Nullable Object model);

再创建 RequestManager 时会先创建一个不可见的Fragment,通过FM加入到当前页面,用这个不可见的Fragment即可检测页面的生命周期。

Request 主要的实现类有三个:

  SingleRequest
  ThumbnailRequestCoordinator
  ErrorRequestCoordinator

6、Glide使用什么缓存?

  BitmapPool 大小通过 MemorySizeCalculator 设置;
  使用 LRU 算法维护 BitmapPool ;
  Glide 会根据 Bitmap 的大小与 Config 生成一个 Key;
  Key 也有自己对应的对象池,使用 Queue 实现;
  数据最终存储在 GroupedLinkedMap 中;
  GroupedLinkedMap 使用哈希表、循环链表、List 来存储数据。

7、Glide内存缓存如何控制大小?

blog.csdn.net/github_3713…

一种是Resource缓存,一类是Bitmap缓存。

Resource缓存: 图片从网络加载,将图片缓存到本地,当需要再次使用时,直接从缓存中取出而无需再次请求网络。

Glide在缓存Resource使用三层缓存,包括:

  一级缓存:缓存被回收的资源,使用LRU算法(Least Frequently Used,最近最少使用算法)。当需要再次使用到被回收的资源,直接从内存返回。
  二级缓存:使用弱引用缓存正在使用的资源。当系统执行gc操作时,会回收没有强引用的资源。使用弱引用缓存资源,既可以缓存正在使用的强引用资源,也不阻碍系统需要回收无引用资源。
  三级缓存:磁盘缓存。网络图片下载成功后将以文件的形式缓存到磁盘中。

Bitmap缓存 通过Bitmap压缩质量参数:Glide默认使用RGB_565,比系统默认使用的ARGB_8888节省一半的资源,但RGB_565无法显示透明度。

Bitmap缓存算法:

  在Glide中,使用BitmapPool来缓存Bitmap,使用的也是LRU算法。
  当需要使用Bitmap时,从Bitmap的池子中取出合适的Bitmap,若取不到合适的,则再新创建。
  当Bitmap使用完后,不直接调用Bitmap.recycler()回收,而是放入Bitmap的池子。

8.Fresco 源码分析

  初始化Fresco。
  获取DataSource。
  绑定Controller与Hierarchy。
  从内存缓存/磁盘缓存/网络获取图片,并设置到对应的Drawable层。

  缓冲缓存层:由BufferedDiskCache实现,提供缓冲功能。
  文件缓存层:由DiskStorageCache实现,提供实际的缓存功能。
  文件存储层:由DefaultDiskStorage实现,提供磁盘文件读写的功能。

  DiskStorageCache:实现了FileCache接口与DiskTrimmable接口是缓存的主要实现类。
  DefaultDiskStorage:实现了DiskStorage接口,封装了磁盘IO的读写逻辑。
  BufferedDiskCache:在DiskStorageCache的基础上提供了Buffer功能。

private static final String CONTENT_FILE_EXTENSION = ".cnt"; private static final String TEMP_FILE_EXTENSION = ".tmp";

未解码图片内存缓存:由EncodedImage描述真正的缓存对象。 已解码图片内存缓存:由BitmapMemoryCache描述真正的缓存对象。

作为一个Android程序员,要学的东西有太多太多了,对于进阶这条路而言,学习是会有回报的!

你把你的时间投资在学习上,就意味着你可以收获技能,更有机会增加收入。

分享我的Android学习PDF大全来学习,这份Android学习PDF大全真的包含了方方面面了,内含Java基础知识点、Android基础、Android进阶延伸、算法合集等等

我的这份学习合集,可以有效的帮助大家掌握知识点。

总之也是在这里帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习

学习PDF大全+字节跳动真题+简历模板

无论是大大小小的面试,要想心理不慌,刷题必不可少!平时写文章更新有点慢,给大家看看我的大厂面试题合集!

计算机基础面试题、数据结构和算法面试题、Java面试题、Android面试题、其他扩展面试题、非技术面试题总共五个章节354页。

面试时HR也是不可以忽略的环节,我们经常也会遇到很多关于简历制作,职业困惑、HR经典面试问题回答等有关面试的问题。

有全套简历制作、春招困惑、HR面试等问题解析参考建议。

上述字节跳动真题解析、 Android 知识大全PDF、简历模板可以关注我看个人简介或者简信我免费获取

相关文章

网友评论

    本文标题:2020阿里大佬总结面试题系列!大厂面试之图片(含答案+学习笔记

    本文链接:https://www.haomeiwen.com/subject/wuxymhtx.html