2020阿里大佬總結面試題系列!大廠面試之圖片(含答案+學習筆記)
作者:愛雨浮龍
一、圖片
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
等
缺點:
- 功能簡單 圖片載入
- 效能(載入速度等等)較(
Glide
、Fresco
)差 - 自身沒有實現"本地快取"
Glide Google 開源
支援 Gif WebP Video 生命週期繼承 高效快取策略
- 支援
Memory
和Disk
快取 -
Picasso
只會快取原始尺寸圖片,而Glide
快取時多種規格 - 記憶體開銷小,預設
RGB_565
,Picasso
預設是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()
方法訪問快取物件時,就會呼叫
LinkedHashMap
的
get()
方法獲得對應集合元素,同時會更新該元素到隊尾。
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
包含Fragment
,Fragment
包含Fragment
,若分別建立Glide
請求是並不會只建立一個RequestManager
的 - 子執行緒發起
Glide
請求或傳入物件為ApplicationContext
,則使用全域性單例的RequestManager
建立
RequestBuilder
的
load
方法有很多:
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/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 十幾道含答案的大廠面試題總結面試題
- 面試過了,總結測試工程師面試題(含答案)工程師面試題
- [面試專題]一線網際網路大廠面試總結面試
- Java面試題全集學習筆記Java面試題筆記
- 記錄近期面試題,面試總結面試題
- 前端大廠面試一點總結前端面試
- JavaScript常見面試題彙總(含答案)JavaScript面試題
- 大佬分享:180+道Java面試題目!含答案解析!Java面試題
- 大小廠必問Java後端面試題(含答案)Java後端面試題
- 找工作學習筆記2------阿里巴巴實習生筆試題(含答案)筆記阿里筆試
- [面試題]大廠常見面試題整理面試題
- 阿里最全面試116題:阿里天貓、螞蟻金服、阿里巴巴面試題含答案阿里面試題
- 前端面試指南之JS面試題總結前端JS面試題
- Java大廠面試題Java面試題
- 大資料面試常見的面試題總結大資料面試題
- java面試筆試題大彙總Java面試筆試
- 2019 阿里java面試總結 (含面試題解析)阿里Java面試題
- Java工程師面試題之Dubbo(含答案)Java工程師面試題
- MySQL學習筆記之命令總結MySql筆記
- Hbase學習筆記問題總結筆記
- 面試了滴滴、美團、京東等4家大廠,我總結了70道大廠高頻Java面試題及解析Java面試題
- 2020年中大廠前端面試總結前端面試
- 面試題總結面試題
- 【助力2020面試】精心整理85道Java微服務面試題(含答案)Java微服務面試題
- 【面試】2018大廠高階前端面試題彙總前端面試題
- 2020 前端面試 | 第二波面試題總結前端面試題
- 面試總結:鵝廠Linux後臺開發面試筆試C++知識點參考筆記面試Linux筆試C++筆記
- 大廠微服務及後端基礎若干面試題總結微服務後端面試題
- 面試福利—最強前端面試題(二)(含答案)前端面試題
- Android面試總結,有了這些中高階面試專題-大廠還會遠嗎?Android面試題及解析Android面試題
- 面試題錦(大廠面試前夕的掙扎)面試題
- Java面試題總結(基礎面試題完結版,2020-10-13)Java面試題
- 阿里前端社招面試總結阿里前端面試
- 阿里JAVA開發面試常問問題總結阿里Java面試
- Android 面試題集 包含答案Android面試題
- css面試題總結CSS面試題
- iOS 面試題總結iOS面試題
- PHP面試題總結PHP面試題