2020阿里大佬總結面試題系列!大廠面試之圖片(含答案+學習筆記)

yilian發表於2020-04-11

作者:愛雨浮龍

一、圖片

  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++,閱讀原始碼困難

對比項 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原理

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、自己去實現圖片庫,怎麼做?

  圖片的同步載入
  圖片的非同步載入
  圖片壓縮
  記憶體快取
  磁碟快取
  網路拉取

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記憶體快取如何控制大小?

一種是 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進階延伸、演算法合集等等

我的這份學習合集,可以有效的幫助大家掌握知識點。

總之也是在這裡幫助大家學習提升進階,也節省大家在網上搜尋資料的時間來學習,也可以分享給身邊好友一起學習

無論是大大小小的面試,要想心理不慌,刷題必不可少!平時寫文章更新有點慢,給大家看看我的大廠面試題合集!

計算機基礎面試題、資料結構和演算法面試題、Java面試題、Android面試題、其他擴充套件面試題、非技術面試題總共五個章節354頁。

面試時 HR也是不可以忽略的環節,我們經常也會遇到很多關於簡歷製作,職業困惑、 HR經典面試問題回答等有關面試的問題。

有全套簡歷製作、春招困惑、HR面試等問題解析參考建議。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69952849/viewspace-2685599/,如需轉載,請註明出處,否則將追究法律責任。

相關文章