溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

ndroid11道A性能優(yōu)化面試題

發(fā)布時(shí)間:2020-08-03 09:36:26 來(lái)源:億速云 閱讀:144 作者:Leah 欄目:web開(kāi)發(fā)

本篇文章給大家分享的是有關(guān)ndroid11道A性能優(yōu)化面試題,小編覺(jué)得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話(huà)不多說(shuō),跟著小編一起來(lái)看看吧。


1、圖片的三級(jí)緩存中,圖片加載到內(nèi)存中,如果內(nèi)存快爆了,會(huì)發(fā)生什么?怎么處理?

  • 參考回答:
    • 首先我們要清楚圖片的三級(jí)緩存是如何的

      ndroid11道A性能優(yōu)化面試題

      如果內(nèi)存足夠時(shí)不回收。內(nèi)存不夠時(shí)就回收軟引用對(duì)象

2、內(nèi)存中如果加載一張500*500的png高清圖片.應(yīng)該是占用多少的內(nèi)存?

  • 參考回答:
    • 不考慮屏幕比的話(huà):占用內(nèi)存=500 * 500 * 4 = 1000000B ≈ 0.95MB
    • 考慮屏幕比的的話(huà):占用內(nèi)存= 寬度像素 x (inTargetDensity / inDensity) x 高度像素 x (inTargetDensity / inDensity)x 一個(gè)像素所占的內(nèi)存字節(jié)大小

inDensity表示目標(biāo)圖片的dpi(放在哪個(gè)資源文件夾下),inTargetDensity表示目標(biāo)屏幕的dpi

ndroid11道A性能優(yōu)化面試題

3、WebView的性能優(yōu)化 ?

  • 參考回答:
    • 一個(gè)加載網(wǎng)頁(yè)的過(guò)程中,native、網(wǎng)絡(luò)、后端處理、CPU都會(huì)參與,各自都有必要的工作和依賴(lài)關(guān)系;讓他們相互并行處理而不是相互阻塞才可以讓網(wǎng)頁(yè)加載更快:
      • WebView初始化慢,可以在初始化同時(shí)先請(qǐng)求數(shù)據(jù),讓后端和網(wǎng)絡(luò)不要閑著。
      • 常用 JS 本地化及延遲加載,使用第三方瀏覽內(nèi)核
      • 后端處理慢,可以讓服務(wù)器分trunk輸出,在后端計(jì)算的同時(shí)前端也加載網(wǎng)絡(luò)靜態(tài)資源。
      • 腳本執(zhí)行慢,就讓腳本在最后運(yùn)行,不阻塞頁(yè)面解析。
      • 同時(shí),合理的預(yù)加載、預(yù)緩存可以讓加載速度的瓶頸更小。
      • WebView初始化慢,就隨時(shí)初始化好一個(gè)WebView待用。
      • DNS和鏈接慢,想辦法復(fù)用客戶(hù)端使用的域名和鏈接。

        ndroid11道A性能優(yōu)化面試題

4、Bitmap如何處理大圖,如一張30M的大圖,如何預(yù)防OOM?

  • 參考回答:避免OOM的問(wèn)題就需要對(duì)大圖片的加載進(jìn)行管理,主要通過(guò)縮放來(lái)減小圖片的內(nèi)存占用。
    • BitmapFactory提供的加載圖片的四類(lèi)方法(decodeFile、decodeResource、decodeStream、decodeByteArray)都支持BitmapFactory.Options參數(shù),通過(guò)inSampleSize參數(shù)就可以很方便地對(duì)一個(gè)圖片進(jìn)行采樣縮放
    • 比如一張10241024的高清圖片來(lái)說(shuō)。那么它占有的內(nèi)存為102410244,即4MB,如果inSampleSize為2,那么采樣后的圖片占用內(nèi)存只有5125124,即1MB(注意:根據(jù)最新的官方文檔指出,inSampleSize的取值應(yīng)該總是為2的指數(shù),即1、2、4、8等等,如果外界輸入不足為2的指數(shù),系統(tǒng)也會(huì)默認(rèn)選擇最接近2的指數(shù)代替,比如2*)
    • 綜合考慮。通過(guò)采樣率即可有效加載圖片,流程如下
      • 將BitmapFactory.Options的inJustDecodeBounds參數(shù)設(shè)為true并加載圖片
      • 從BitmapFactory.Options中取出圖片的原始寬高信息,它們對(duì)應(yīng)outWidth和outHeight參數(shù)
      • 根據(jù)采樣率的規(guī)則并結(jié)合目標(biāo)View的所需大小計(jì)算出采樣率inSampleSize
      • 將BitmapFactory.Options的inJustDecodeBounds參數(shù)設(shè)為false,重新加載圖片

        ndroid11道A性能優(yōu)化面試題

5、內(nèi)存回收機(jī)制與GC算法(各種算法的優(yōu)缺點(diǎn)以及應(yīng)用場(chǎng)景);GC原理時(shí)機(jī)以及GC對(duì)象

  • 參考回答:
    • 內(nèi)存判定對(duì)象可回收有兩種機(jī)制:
      • 引用計(jì)數(shù)算法:給對(duì)象中添加一個(gè)引用計(jì)數(shù)器,每當(dāng)有一個(gè)地方引用它時(shí),計(jì)數(shù)器值就加1;當(dāng)引用失效時(shí),計(jì)數(shù)器值就減1;任何時(shí)刻計(jì)數(shù)器為0的對(duì)象就是不可能再被使用的。然而在主流的Java虛擬機(jī)里未選用引用計(jì)數(shù)算法來(lái)管理內(nèi)存,主要原因是它難以解決對(duì)象之間相互循環(huán)引用的問(wèn)題,所以出現(xiàn)了另一種對(duì)象存活判定算法。
      • 可達(dá)性分析法:通過(guò)一系列被稱(chēng)為『GCRoots』的對(duì)象作為起始點(diǎn),從這些節(jié)點(diǎn)開(kāi)始向下搜索,搜索所走過(guò)的路徑稱(chēng)為引用鏈,當(dāng)一個(gè)對(duì)象到GC Roots沒(méi)有任何引用鏈相連時(shí),則證明此對(duì)象是不可用的。其中可作為GC Roots的對(duì)象:虛擬機(jī)棧中引用的對(duì)象,主要是指棧幀中的本地變量、本地方法棧中Native方法引用的對(duì)象、方法區(qū)中類(lèi)靜態(tài)屬性引用的對(duì)象、方法區(qū)中常量*引用的對(duì)象
    • GC回收算法有以下四種:
      • 分代收集算法:是當(dāng)前商業(yè)虛擬機(jī)都采用的一種算法,根據(jù)對(duì)象存活周期的不同,將Java堆劃分為新生代和老年代,并根據(jù)各個(gè)年代的特點(diǎn)采用最適當(dāng)?shù)氖占惴ā?/li>
      • 新生代:大批對(duì)象死去,只有少量存活。使用『復(fù)制算法』,只需復(fù)制少量存活對(duì)象即可。
        • 復(fù)制算法:把可用內(nèi)存按容量劃分為大小相等的兩塊,每次只使用其中的一塊。當(dāng)這一塊的內(nèi)存用盡后,把還存活著的對(duì)象『復(fù)制』到另外一塊上面,再將這一塊內(nèi)存空間一次清理掉。實(shí)現(xiàn)簡(jiǎn)單,運(yùn)行高效。在對(duì)象存活率較高時(shí)就要進(jìn)行較多的復(fù)制操作,效率將會(huì)變低
      • 老年代:對(duì)象存活率高。使用『標(biāo)記—清理算法』或者『標(biāo)記—整理算法』,只需標(biāo)記較少的回收對(duì)象即可。
        • 標(biāo)記-清除算法:首先『標(biāo)記』出所有需要回收的對(duì)象,然后統(tǒng)一『清除』所有被標(biāo)記的對(duì)象。標(biāo)記和清除兩個(gè)過(guò)程的效率都不高,清除之后會(huì)產(chǎn)生大量不連續(xù)的內(nèi)存碎片,空間碎片太多可能會(huì)導(dǎo)致以后在程序運(yùn)行過(guò)程中需要分配較大對(duì)象時(shí),無(wú)法找到足夠的連續(xù)內(nèi)存而不得不提前觸發(fā)另一次垃圾收集動(dòng)作。
        • 標(biāo)記-整理算法:首先『標(biāo)記』出所有需要回收的對(duì)象,然后進(jìn)行『整理』,使得存活的對(duì)象都向一端移動(dòng),最后直接清理掉端邊界以外的內(nèi)存。標(biāo)記整理算法會(huì)將所有的存活對(duì)象移動(dòng)到一端,并對(duì)不存活對(duì)象進(jìn)行處理,因此其不會(huì)產(chǎn)生內(nèi)存碎片

6、內(nèi)存泄露和內(nèi)存溢出的區(qū)別 ?AS有什么工具可以檢測(cè)內(nèi)存泄露

  • 參考回答:
    • 內(nèi)存溢出(out of memory):是指程序在申請(qǐng)內(nèi)存時(shí),沒(méi)有足夠的內(nèi)存空間供其使用,出現(xiàn)out of memory;比如申請(qǐng)了一個(gè)integer,但給它存了long才能存下的數(shù),那就是內(nèi)存溢出。
    • 內(nèi)存泄露(memory leak):是指程序在申請(qǐng)內(nèi)存后,無(wú)法釋放已申請(qǐng)的內(nèi)存空間,一次內(nèi)存泄露危害可以忽略,但內(nèi)存泄露堆積后果很?chē)?yán)重,無(wú)論多少內(nèi)存,遲早會(huì)被占光。memory leak會(huì)最終會(huì)導(dǎo)致out of memory!
    • 查找內(nèi)存泄漏可以使用Android Studio 自帶的AndroidProfiler工具或MAT

7、性能優(yōu)化,怎么保證應(yīng)用啟動(dòng)不卡頓? 黑白屏怎么處理?

  • 參考回答:
    • 應(yīng)用啟動(dòng)速度,取決于你在application里面時(shí)候做了什么事情,比如你集成了很多sdk,并且sdk的init操作都需要在主線(xiàn)程里實(shí)現(xiàn)所以會(huì)有卡頓的感覺(jué)。在非必要的情況下可以把加載延后或則開(kāi)啟子線(xiàn)程處理
    • 另外,影響界面卡頓的兩大因素,分別是界面繪制和數(shù)據(jù)處理。
      • 布局優(yōu)化(使用include,merge標(biāo)簽,復(fù)雜布局推薦使用ConstraintLayout等)
      • onCreate() 中不執(zhí)行耗時(shí)操作 把頁(yè)面顯示的 View 細(xì)分一下,放在 AsyncTask 里逐步顯示,用 Handler 更好。這樣用戶(hù)的看到的就是有層次有步驟的一個(gè)個(gè)的 View 的展示,不會(huì)是先看到一個(gè)黑屏,然后一下顯示所有 View。最好做成動(dòng)畫(huà),效果更自然。
      • 利用多線(xiàn)程的目的就是盡可能的減少 onCreate() 和 onReume() 的時(shí)間,使得用戶(hù)能盡快看到頁(yè)面,操作頁(yè)面。
      • 減少主線(xiàn)程阻塞時(shí)間。
      • 提高 Adapter 和 AdapterView 的效率。
    • 黑白屏產(chǎn)生原因:當(dāng)我們?cè)趩?dòng)一個(gè)應(yīng)用時(shí),系統(tǒng)會(huì)去檢查是否已經(jīng)存在這樣一個(gè)進(jìn)程,如果不存在,系統(tǒng)的服務(wù)會(huì)先檢查startActivity中的intent的信息,然后在去創(chuàng)建進(jìn)程,最后啟動(dòng)Acitivy,即冷啟動(dòng)。而啟動(dòng)出現(xiàn)白黑屏的問(wèn)題,就是在這段時(shí)間內(nèi)產(chǎn)生的。系統(tǒng)在繪制頁(yè)面加載布局之前,首先會(huì)初始化窗口(Window),而在進(jìn)行這一步操作時(shí),系統(tǒng)會(huì)根據(jù)我們?cè)O(shè)置的Theme來(lái)指定它的Theme 主題顏色,我們?cè)赟tyle中的設(shè)置就決定了顯示的是白屏還是黑屏。
      • windowIsTranslucent和windowNoTitle,將這兩個(gè)屬性都設(shè)置成true (會(huì)有明顯的卡頓體驗(yàn),不推薦)
      • 如果啟動(dòng)頁(yè)只是是一張圖片,那么為啟動(dòng)頁(yè)專(zhuān)一設(shè)置一個(gè)新的主題,設(shè)置主題的android:windowBackground屬性為啟動(dòng)頁(yè)背景圖即可
      • 使用layer-list制作一張圖片launcher_layer.xml,將其設(shè)置為啟動(dòng)頁(yè)專(zhuān)一主題的背景,并將其設(shè)置為啟動(dòng)頁(yè)布局的背景。

8、強(qiáng)引用置為null,會(huì)不會(huì)被回收?

  • 參考回答:
    • 不會(huì)立即釋放對(duì)象占用的內(nèi)存。 如果對(duì)象的引用被置為null,只是斷開(kāi)了當(dāng)前線(xiàn)程棧幀中對(duì)該對(duì)象的引用關(guān)系,而 垃圾收集器是運(yùn)行在后臺(tái)的線(xiàn)程,只有當(dāng)用戶(hù)線(xiàn)程運(yùn)行到安全點(diǎn)(safe point)或者安全區(qū)域才會(huì)掃描對(duì)象引用關(guān)系,掃描到對(duì)象沒(méi)有被引用則會(huì)標(biāo)記對(duì)象,這時(shí)候仍然不會(huì)立即釋放該對(duì)象內(nèi)存,因?yàn)橛行?duì)象是可恢復(fù)的(在 finalize方法中恢復(fù)引用 )。只有確定了對(duì)象無(wú)法恢復(fù)引用的時(shí)候才會(huì)清除對(duì)象內(nèi)存。

9、ListView跟RecyclerView的區(qū)別

  • 參考回答:
    • 動(dòng)畫(huà)區(qū)別:
      • RecyclerView中,內(nèi)置有許多動(dòng)畫(huà)API,例如:notifyItemChanged(), notifyDataInserted(), notifyItemMoved()等等;如果需要自定義動(dòng)畫(huà)效果,可以通過(guò)實(shí)現(xiàn)(RecyclerView.ItemAnimator類(lèi))完成自定義動(dòng)畫(huà)效果,然后調(diào)用RecyclerView.setItemAnimator();
      • 但是ListView并沒(méi)有實(shí)現(xiàn)動(dòng)畫(huà)效果,但我們可以在Adapter自己實(shí)現(xiàn)item的動(dòng)畫(huà)效果;
    • 刷新區(qū)別:
      • ListView中通常刷新數(shù)據(jù)是用全局刷新notifyDataSetChanged(),這樣一來(lái)就會(huì)非常消耗資源;本身無(wú)法實(shí)現(xiàn)局部刷新,但是如果要在ListView實(shí)現(xiàn)局部刷新,依然是可以實(shí)現(xiàn)的,當(dāng)一個(gè)item數(shù)據(jù)刷新時(shí),我們可以在Adapter中,實(shí)現(xiàn)一個(gè)onItemChanged()方法,在方法里面獲取到這個(gè)item的position(可以通過(guò)getFirstVisiblePosition()),然后調(diào)用getView()方法來(lái)刷新這個(gè)item的數(shù)據(jù);
      • RecyclerView中可以實(shí)現(xiàn)局部刷新,例如:notifyItemChanged();
    • 緩存區(qū)別:
      • RecyclerView比ListView多兩級(jí)緩存,支持多個(gè)離ItemView緩存,支持開(kāi)發(fā)者自定義緩存處理邏輯,支持所有RecyclerView共用同一個(gè)RecyclerViewPool(緩存池)。
      • ListView和RecyclerView緩存機(jī)制基本一致,但緩存使用不同

10、ListView的adapter是什么adapter

參考回答:

ndroid11道A性能優(yōu)化面試題

  • BaseAdapter:抽象類(lèi),實(shí)際開(kāi)發(fā)中我們會(huì)繼承這個(gè)類(lèi)并且重寫(xiě)相關(guān)方法,用得最多的一個(gè)適配器!
  • ArrayAdapter:支持泛型操作,最簡(jiǎn)單的一個(gè)適配器,只能展現(xiàn)一行文字?
  • SimpleAdapter:同樣具有良好擴(kuò)展性的一個(gè)適配器,可以自定義多種效果!
  • SimpleCursorAdapter:用于顯示簡(jiǎn)單文本類(lèi)型的listView,一般在數(shù)據(jù)庫(kù)那里會(huì)用到,不過(guò)有點(diǎn)過(guò)時(shí),不推薦使用!

11、LinearLayout、FrameLayout、RelativeLayout性能對(duì)比,為什么?

  • 參考回答:
    • RelativeLayout會(huì)讓子View調(diào)用2次onMeasure,LinearLayout 在有weight時(shí),也會(huì)調(diào)用子 View 2次onMeasure
    • RelativeLayout的子View如果高度和RelativeLayout不同,則會(huì)引發(fā)效率問(wèn)題,當(dāng)子View很復(fù)雜時(shí),這個(gè)問(wèn)題會(huì)更加嚴(yán)重。如果可以,盡量使用padding代替margin。
    • 在不影響層級(jí)深度的情況下,使用LinearLayout和FrameLayout而不是RelativeLayout。

以上就是ndroid11道A性能優(yōu)化面試題,小編相信有部分知識(shí)點(diǎn)可能是我們?nèi)粘9ぷ鲿?huì)見(jiàn)到或用到的。希望你能通過(guò)這篇文章學(xué)到更多知識(shí)。更多詳情敬請(qǐng)關(guān)注億速云行業(yè)資訊頻道。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI