您好,登錄后才能下訂單哦!
本篇文章給大家分享的是有關ndroid11道A性能優化面試題,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。
1、圖片的三級緩存中,圖片加載到內存中,如果內存快爆了,會發生什么?怎么處理?
- 參考回答:
首先我們要清楚圖片的三級緩存是如何的
如果內存足夠時不回收。內存不夠時就回收軟引用對象
2、內存中如果加載一張500*500的png高清圖片.應該是占用多少的內存?
- 參考回答:
- 不考慮屏幕比的話:占用內存=500 * 500 * 4 = 1000000B ≈ 0.95MB
- 考慮屏幕比的的話:占用內存= 寬度像素 x (inTargetDensity / inDensity) x 高度像素 x (inTargetDensity / inDensity)x 一個像素所占的內存字節大小
inDensity表示目標圖片的dpi(放在哪個資源文件夾下),inTargetDensity表示目標屏幕的dpi
3、WebView的性能優化 ?
4、Bitmap如何處理大圖,如一張30M的大圖,如何預防OOM?
- 參考回答:避免OOM的問題就需要對大圖片的加載進行管理,主要通過縮放來減小圖片的內存占用。
- BitmapFactory提供的加載圖片的四類方法(decodeFile、decodeResource、decodeStream、decodeByteArray)都支持BitmapFactory.Options參數,通過inSampleSize參數就可以很方便地對一個圖片進行采樣縮放
- 比如一張10241024的高清圖片來說。那么它占有的內存為102410244,即4MB,如果inSampleSize為2,那么采樣后的圖片占用內存只有5125124,即1MB(注意:根據最新的官方文檔指出,inSampleSize的取值應該總是為2的指數,即1、2、4、8等等,如果外界輸入不足為2的指數,系統也會默認選擇最接近2的指數代替,比如2*)
- 綜合考慮。通過采樣率即可有效加載圖片,流程如下
- 將BitmapFactory.Options的inJustDecodeBounds參數設為true并加載圖片
- 從BitmapFactory.Options中取出圖片的原始寬高信息,它們對應outWidth和outHeight參數
- 根據采樣率的規則并結合目標View的所需大小計算出采樣率inSampleSize
- 將BitmapFactory.Options的inJustDecodeBounds參數設為false,重新加載圖片
5、內存回收機制與GC算法(各種算法的優缺點以及應用場景);GC原理時機以及GC對象
- 參考回答:
- 內存判定對象可回收有兩種機制:
- 引用計數算法:給對象中添加一個引用計數器,每當有一個地方引用它時,計數器值就加1;當引用失效時,計數器值就減1;任何時刻計數器為0的對象就是不可能再被使用的。然而在主流的Java虛擬機里未選用引用計數算法來管理內存,主要原因是它難以解決對象之間相互循環引用的問題,所以出現了另一種對象存活判定算法。
- 可達性分析法:通過一系列被稱為『GCRoots』的對象作為起始點,從這些節點開始向下搜索,搜索所走過的路徑稱為引用鏈,當一個對象到GC Roots沒有任何引用鏈相連時,則證明此對象是不可用的。其中可作為GC Roots的對象:虛擬機棧中引用的對象,主要是指棧幀中的本地變量、本地方法棧中Native方法引用的對象、方法區中類靜態屬性引用的對象、方法區中常量*引用的對象
- GC回收算法有以下四種:
- 分代收集算法:是當前商業虛擬機都采用的一種算法,根據對象存活周期的不同,將Java堆劃分為新生代和老年代,并根據各個年代的特點采用最適當的收集算法。
- 新生代:大批對象死去,只有少量存活。使用『復制算法』,只需復制少量存活對象即可。
- 復制算法:把可用內存按容量劃分為大小相等的兩塊,每次只使用其中的一塊。當這一塊的內存用盡后,把還存活著的對象『復制』到另外一塊上面,再將這一塊內存空間一次清理掉。實現簡單,運行高效。在對象存活率較高時就要進行較多的復制操作,效率將會變低
- 老年代:對象存活率高。使用『標記—清理算法』或者『標記—整理算法』,只需標記較少的回收對象即可。
- 標記-清除算法:首先『標記』出所有需要回收的對象,然后統一『清除』所有被標記的對象。標記和清除兩個過程的效率都不高,清除之后會產生大量不連續的內存碎片,空間碎片太多可能會導致以后在程序運行過程中需要分配較大對象時,無法找到足夠的連續內存而不得不提前觸發另一次垃圾收集動作。
- 標記-整理算法:首先『標記』出所有需要回收的對象,然后進行『整理』,使得存活的對象都向一端移動,最后直接清理掉端邊界以外的內存。標記整理算法會將所有的存活對象移動到一端,并對不存活對象進行處理,因此其不會產生內存碎片
6、內存泄露和內存溢出的區別 ?AS有什么工具可以檢測內存泄露
- 參考回答:
- 內存溢出(out of memory):是指程序在申請內存時,沒有足夠的內存空間供其使用,出現out of memory;比如申請了一個integer,但給它存了long才能存下的數,那就是內存溢出。
- 內存泄露(memory leak):是指程序在申請內存后,無法釋放已申請的內存空間,一次內存泄露危害可以忽略,但內存泄露堆積后果很嚴重,無論多少內存,遲早會被占光。memory leak會最終會導致out of memory!
- 查找內存泄漏可以使用Android Studio 自帶的AndroidProfiler工具或MAT
7、性能優化,怎么保證應用啟動不卡頓? 黑白屏怎么處理?
- 參考回答:
- 應用啟動速度,取決于你在application里面時候做了什么事情,比如你集成了很多sdk,并且sdk的init操作都需要在主線程里實現所以會有卡頓的感覺。在非必要的情況下可以把加載延后或則開啟子線程處理
- 另外,影響界面卡頓的兩大因素,分別是界面繪制和數據處理。
- 布局優化(使用include,merge標簽,復雜布局推薦使用ConstraintLayout等)
- onCreate() 中不執行耗時操作 把頁面顯示的 View 細分一下,放在 AsyncTask 里逐步顯示,用 Handler 更好。這樣用戶的看到的就是有層次有步驟的一個個的 View 的展示,不會是先看到一個黑屏,然后一下顯示所有 View。最好做成動畫,效果更自然。
- 利用多線程的目的就是盡可能的減少 onCreate() 和 onReume() 的時間,使得用戶能盡快看到頁面,操作頁面。
- 減少主線程阻塞時間。
- 提高 Adapter 和 AdapterView 的效率。
- 黑白屏產生原因:當我們在啟動一個應用時,系統會去檢查是否已經存在這樣一個進程,如果不存在,系統的服務會先檢查startActivity中的intent的信息,然后在去創建進程,最后啟動Acitivy,即冷啟動。而啟動出現白黑屏的問題,就是在這段時間內產生的。系統在繪制頁面加載布局之前,首先會初始化窗口(Window),而在進行這一步操作時,系統會根據我們設置的Theme來指定它的Theme 主題顏色,我們在Style中的設置就決定了顯示的是白屏還是黑屏。
- windowIsTranslucent和windowNoTitle,將這兩個屬性都設置成true (會有明顯的卡頓體驗,不推薦)
- 如果啟動頁只是是一張圖片,那么為啟動頁專一設置一個新的主題,設置主題的android:windowBackground屬性為啟動頁背景圖即可
- 使用layer-list制作一張圖片launcher_layer.xml,將其設置為啟動頁專一主題的背景,并將其設置為啟動頁布局的背景。
8、強引用置為null,會不會被回收?
- 參考回答:
- 不會立即釋放對象占用的內存。 如果對象的引用被置為null,只是斷開了當前線程棧幀中對該對象的引用關系,而 垃圾收集器是運行在后臺的線程,只有當用戶線程運行到安全點(safe point)或者安全區域才會掃描對象引用關系,掃描到對象沒有被引用則會標記對象,這時候仍然不會立即釋放該對象內存,因為有些對象是可恢復的(在 finalize方法中恢復引用 )。只有確定了對象無法恢復引用的時候才會清除對象內存。
9、ListView跟RecyclerView的區別
- 參考回答:
- 動畫區別:
- 在RecyclerView中,內置有許多動畫API,例如:notifyItemChanged(), notifyDataInserted(), notifyItemMoved()等等;如果需要自定義動畫效果,可以通過實現(RecyclerView.ItemAnimator類)完成自定義動畫效果,然后調用RecyclerView.setItemAnimator();
- 但是ListView并沒有實現動畫效果,但我們可以在Adapter自己實現item的動畫效果;
- 刷新區別:
- ListView中通常刷新數據是用全局刷新notifyDataSetChanged(),這樣一來就會非常消耗資源;本身無法實現局部刷新,但是如果要在ListView實現局部刷新,依然是可以實現的,當一個item數據刷新時,我們可以在Adapter中,實現一個onItemChanged()方法,在方法里面獲取到這個item的position(可以通過getFirstVisiblePosition()),然后調用getView()方法來刷新這個item的數據;
- RecyclerView中可以實現局部刷新,例如:notifyItemChanged();
- 緩存區別:
- RecyclerView比ListView多兩級緩存,支持多個離ItemView緩存,支持開發者自定義緩存處理邏輯,支持所有RecyclerView共用同一個RecyclerViewPool(緩存池)。
- ListView和RecyclerView緩存機制基本一致,但緩存使用不同
10、ListView的adapter是什么adapter
參考回答:
- BaseAdapter:抽象類,實際開發中我們會繼承這個類并且重寫相關方法,用得最多的一個適配器!
- ArrayAdapter:支持泛型操作,最簡單的一個適配器,只能展現一行文字?
- SimpleAdapter:同樣具有良好擴展性的一個適配器,可以自定義多種效果!
- SimpleCursorAdapter:用于顯示簡單文本類型的listView,一般在數據庫那里會用到,不過有點過時,不推薦使用!
11、LinearLayout、FrameLayout、RelativeLayout性能對比,為什么?
- 參考回答:
- RelativeLayout會讓子View調用2次onMeasure,LinearLayout 在有weight時,也會調用子 View 2次onMeasure
- RelativeLayout的子View如果高度和RelativeLayout不同,則會引發效率問題,當子View很復雜時,這個問題會更加嚴重。如果可以,盡量使用padding代替margin。
- 在不影響層級深度的情況下,使用LinearLayout和FrameLayout而不是RelativeLayout。
以上就是ndroid11道A性能優化面試題,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。