溫馨提示×

溫馨提示×

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

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

把面試官唬住了,就要50K。沒唬住,就要5K!Android

發(fā)布時間:2020-02-29 09:09:29 來源:網(wǎng)絡 閱讀:355 作者:Android丶VG 欄目:移動開發(fā)

記錄之前一次面試。

先說一下面試問到的需要的點:tcp/udp.volatile關(guān)鍵字.多進程.hashmap.anr.activity.MVP.算法題.自定義view.OKHTTP.java相關(guān).數(shù)據(jù)結(jié)構(gòu).性能優(yōu)化.

為此我整理了一份983頁的PDF,把自己平時收集的面試題,和平時工作中碰到的都融合進去了
把面試官唬住了,就要50K。沒唬住,就要5K!Android
(更多完整項目下載。未完待續(xù)。源碼。圖文知識后續(xù)上傳github。)
可以點擊關(guān)于我聯(lián)系我獲取完整PDF
(VX:mm14525201314)

  • 自定義view的過程
  • java線程,安卓線程池
  • handle
  • gc,gc的使用方式
  • okhttp源碼
  • 設計模式
  • hashmap源碼
  • 線程安全性
  • hash運算過程
  • java相關(guān)(面向?qū)ο蟮睦斫?多態(tài)的實習 接口和抽象類 內(nèi)存模型 多線程 線程池原理)
  • 性能優(yōu)化相關(guān)

問到的問題中,還是性能優(yōu)化相關(guān)的對我的印象比較深刻,所以著重講一下(答案僅供參考)

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

首先我們要清楚圖片的三級緩存是如何的
把面試官唬住了,就要50K。沒唬住,就要5K!Android

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

2、內(nèi)存中如果加載一張 500*500 的 png 高清圖片.應該是占用多少的內(nèi)存?
  • 不考慮屏幕比的話: 占用內(nèi)存=500 500 4 = 1000000B ≈
    0.95MB
  • 考慮屏幕比的的話: 占用內(nèi)存= 寬度像素 x (inTargetDensity /inDensity) x 高度像素 x(inTargetDensity / inDensity)x 一個像素所占的內(nèi)存字節(jié)
    大小
  • inDensity 表示目標圖片的 dpi(放在哪個資源文件夾下),
    inTargetDensity表示目標屏幕的 dpi
    把面試官唬住了,就要50K。沒唬住,就要5K!Android
    3、WebView 的性能優(yōu)化 ?

    一個加載網(wǎng)頁的過程中,native、網(wǎng)絡、后端處理、CPU 都會
    參與,各自都有必要的工作和依賴關(guān)系;讓他們相互并行處理
    而不是相互阻塞才可以讓網(wǎng)頁加載更快:

  • WebView 初始化慢,可以在初始化同時先請求數(shù)據(jù),
    讓后端和網(wǎng)絡不要閑著。
  • 常用 JS 本地化及延遲加載,使用第三方瀏覽內(nèi)核
  • 后端處理慢,可以讓服務器分 trunk 輸出,在后端計算
    的同時前端也加載網(wǎng)絡靜態(tài)資源。
  • 腳本執(zhí)行慢,就讓腳本在最后運行,不阻塞頁面解析。
  • 同時,合理的預加載、預緩存可以讓加載速度的瓶頸更
    小。
  • WebView 初始化慢,就隨時初始化好一個 WebView
    待用。
  • DNS 和鏈接慢,想辦法復用客戶端使用的域名和鏈接。
    把面試官唬住了,就要50K。沒唬住,就要5K!Android
    4、Bitmap 如何處理大圖,如一張 30M 的大圖,如何預防 OOM?

    參考回答: 避免 OOM 的問題就需要對大圖片的加載進行管理,主要通
    過縮放來減小圖片的內(nèi)存占用。

  • BitmapFactory 提供的加載圖片的四類方法(decodeFile、
    decodeResourcedecodeStream、decodeByteArray
    都支持 BitmapFactory.Options 參數(shù),通過 inSampleSize
    數(shù)就可以很方便地對一個圖片進行采樣縮放
  • 比如一張 10241024 的高清圖片來說。那么它占有的內(nèi)存為
    102410244,即 4MB,如果 inSampleSize 為 2,那么采樣后
    的圖片占用內(nèi)存只有 512512*4,即 1MB(注意:根據(jù)最新的官
    方文檔指出,inSampleSize 的取值應該總是為 2 的指數(shù),即
    1、2、4、8 等等,如果外界輸入不足為 2 的指數(shù),系統(tǒng)也會默
    認選擇最接近 2 的指數(shù)代替,比如 2)
  • 綜合考慮。通過采樣率即可有效加載圖片,流程如下
    • BitmapFactory.Options
      inJustDecodeBounds 參數(shù)設為 true 并加載圖片
    • BitmapFactory.Options 中取出圖片的原始寬高信
      息,它們對應 outWidth 和 outHeight 參數(shù)
    • 根據(jù)采樣率的規(guī)則并結(jié)合目標 View 的所需大小計算出
      采樣率 inSampleSize
    • BitmapFactory.Options
      inJustDecodeBounds 參數(shù)設為 false,重新加載圖片
5、內(nèi)存回收機制與 GC 算法(各種算法的優(yōu)缺點以及應用場景);GC 原理時機以及 GC 對象

參考回答:

內(nèi)存判定對象可回收有兩種機制:

  • 引用計數(shù)算法: 給對象中添加一個引用計數(shù)器,每當有
    一個地方引用它時,計數(shù)器值就加 1;當引用失效時,
    計數(shù)器值就減 1;任何時刻計數(shù)器為 0 的對象就是不可
    能再被使用的。然而在主流的 Java 虛擬機里未選用引用
    計數(shù)算法來管理內(nèi)存,主要原因是它難以解決對象之間相互循環(huán)引用的問題,所以出現(xiàn)了另一種對象存活判定
    算法。

  • 可達性分析法: 通過一系列被稱為『GCRoots』的對象
    作為起始點,從這些節(jié)點開始向下搜索,搜索所走過的
    路徑稱為引用鏈,當一個對象到 GC Roots 沒有任何引
    用鏈相連時,則證明此對象是不可用的。其中可作為 GC
    Roots 的對象:虛擬機棧中引用的對象,主要是指棧幀
    中的本地變量*、本地方法棧中 Native 方法引用的對
    象、方法區(qū)中類靜態(tài)屬性引用的對象、方法區(qū)中常量引
    用的對象

GC 回收算法有以下四種:

  • 分代收集算法: 是當前商業(yè)虛擬機都采用的一種算法,
    根據(jù)對象存活周期的不同,將 Java 堆劃分為新生代和老
    年代,并根據(jù)各個年代的特點采用最適當?shù)氖占惴ā?/li>
  • 新生代: 大批對象死去,只有少量存活。使用『復制算
    法』,只需復制少量存活對象即可。
    • 復制算法: 把可用內(nèi)存按容量劃分為大小相等的
      兩塊,每次只使用其中的一塊。當這一塊的內(nèi)存
      用盡后,把還存活著的對象『復制』到另外一塊
      上面,再將這一塊內(nèi)存空間一次清理掉。實現(xiàn)簡單,運行高效。在對象存活率較高時就要進行較多的復制操作,效率將會變低
  • 老年代: 對象存活率高。使用『標記—清理算法』或者
    『標記—整理算法』,只需標記較少的回收對象即可。
    • 標記-清除算法: 首先『標記』出所有需要回收
      的對象,然后統(tǒng)一『清除』所有被標記的對象。
      標記和清除兩個過程的效率都不高,清除之后會
      產(chǎn)生大量不連續(xù)的內(nèi)存碎片,空間碎片太多可能
      會導致以后在程序運行過程中需要分配較大對象
      時,無法找到足夠的連續(xù)內(nèi)存而不得不提前觸發(fā)
      另一次垃圾收集動作。
    • 標記-整理算法: 首先『標記』出所有需要回收
      的對象,然后進行『整理』,使得存活的對象都
      向一端移動,最后直接清理掉端邊界以外的內(nèi)
      存。標記整理算法會將所有的存活對象移動到一
      端,并對不存活對象進行處理,因此其不會產(chǎn)生
      內(nèi)存碎片
      6、內(nèi)存泄露和內(nèi)存溢出的區(qū)別 ?AS 有什么工具可以檢測內(nèi)存泄露
  • 內(nèi)存溢出(out of memory): 是指程序在申請內(nèi)存時,沒有足
    夠的內(nèi)存空間供其使用,出現(xiàn) out of memory;比如申請了一
    個 integer,但給它存了 long 才能存下的數(shù),那就是內(nèi)存溢
    出。
  • 內(nèi)存泄露(memory leak): 是指程序在申請內(nèi)存后,無法釋放
    已申請的內(nèi)存空間,一次內(nèi)存泄露危害可以忽略,但內(nèi)存泄露
    堆積后果很嚴重,無論多少內(nèi)存,遲早會被占光。memory leak
    會最終會導致 out of memory!
  • 查找內(nèi)存泄漏可以使用 Android Studio 自帶的
    AndroidProfiler 工具或 MAT
7、性能優(yōu)化,怎么保證應用啟動不卡頓? 黑白屏怎么處理?
  • 應用啟動速度,取決于你在 application 里面時候做了什么事
    情,比如你集成了很多 sdk,并且 sdk 的 init 操作都需要在主
    線程里實現(xiàn)所以會有卡頓的感覺。在非必要的情況下可以把加
    載延后或則開啟子線程處理
  • 另外,影響界面卡頓的兩大因素,分別是界面繪制和數(shù)據(jù)處
    理。

    • 布局優(yōu)化(使用 include,merge 標簽,復雜布局推薦使
      ConstraintLayout等)
    • onCreate() 中不執(zhí)行耗時操作 把頁面顯示的 View 細
      分一下,放在 AsyncTask 里逐步顯示,用 Handler
      更好。這樣用戶的看到的就是有層次有步驟的一個個的
      View 的展示,不會是先看到一個黑屏,然后一下顯示
      所有 View。最好做成動畫,效果更自然。
    • 利用多線程的目的就是盡可能的減少 onCreate()
      onReume() 的時間,使得用戶能盡快看到頁面,操作
      頁面。
    • 減少主線程阻塞時間。
    • 提高 Adapter 和 AdapterView 的效率。
  • 黑白屏產(chǎn)生原因: 當我們在啟動一個應用時,系統(tǒng)會去檢查是
    否已經(jīng)存在這樣一個進程,如果不存在,系統(tǒng)的服務會先檢查
    startActivity 中的 intent 的信息,然后在去創(chuàng)建進程,最后啟
    Acitivy,即冷啟動。而啟動出現(xiàn)白黑屏的問題,就是在這段
    時間內(nèi)產(chǎn)生的。系統(tǒng)在繪制頁面加載布局之前,首先會初始化
    窗口(Window),而在進行這一步操作時,系統(tǒng)會根據(jù)我們設
    置的 Theme 來指定它的 Theme 主題顏色,我們在 Style 中的
    設置就決定了顯示的是白屏還是黑屏。
    • windowIsTranslucentwindowNoTitle,將這兩個
      屬性都設置成 true (會有明顯的卡頓體驗,不推薦)
    • 如果啟動頁只是是一張圖片,那么為啟動頁專一設置一
      個新的主題,設置主題的
      android:windowBackground 屬性為啟動頁背景圖即
  • 使用 layer-list 制作一張圖片 launcher_layer.xml,將其
    設置為啟動頁專一主題的背景,并將其設置為啟動頁布
    局的背景。
    8、強引用置為 null,會不會被回收?

    不會立即釋放對象占用的內(nèi)存。 如果對象的引用被置為 null,
    只是斷開了當前線程棧幀中對該對象的引用關(guān)系,而 垃圾收集
    器是運行在后臺的線程,只有當用戶線程運行到安全點(safe
    point)或者安全區(qū)域才會掃描對象引用關(guān)系,掃描到對象沒有被
    引用則會標記對象,這時候仍然不會立即釋放該對象內(nèi)存,因
    為有些對象是可恢復的(在 finalize 方法中恢復引用 )。只有
    確定了對象無法恢復引用的時候才會清除對象內(nèi)存。

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

動畫區(qū)別:

  • RecyclerView 中,內(nèi)置有許多動畫 API,例如:
    notifyItemChanged(), notifyDataInserted(),
    notifyItemMoved()等等;如果需要自定義動畫效果,
    可以通過實現(xiàn)(RecyclerView.ItemAnimator 類)完成
    自定義動畫效果,然后調(diào)用
    RecyclerView.setItemAnimator();
  • 但是 ListView 并沒有實現(xiàn)動畫效果,但我們可以在
    Adapter 自己實現(xiàn) item 的動畫效果;

刷新區(qū)別:

  • ListView 中通常刷新數(shù)據(jù)是用全局刷新
    notifyDataSetChanged(),這樣一來就會非常消耗資
    源;本身無法實現(xiàn)局部刷新,但是如果要在 ListView 實 現(xiàn)局部刷新,依然是可以實現(xiàn)的,當一個 item 數(shù)據(jù)刷新
    時,我們可以在 Adapter 中,實現(xiàn)一個
    onItemChanged()方法,在方法里面獲取到這個 item
    的 position(可以通過 getFirstVisiblePosition()),然
    后調(diào)用 getView()方法來刷新這個 item 的數(shù)據(jù);
  • RecyclerView 中可以實現(xiàn)局部刷新,例如:
    notifyItemChanged();

緩存區(qū)別:

  • RecyclerViewListView 多兩級緩存,支持多個離
    ItemView緩存,支持開發(fā)者自定義緩存處理邏輯,支
    持所有 RecyclerView共用同一個
    RecyclerViewPool(緩存池)。
  • ListViewRecyclerView 緩存機制基本一致,但緩存
    使用不同
10、ListView 的 adapter 是什么 adapter

把面試官唬住了,就要50K。沒唬住,就要5K!Android

  • BaseAdapter:抽象類,實際開發(fā)中我們會繼承這個類并且重
    寫相關(guān)方法,用得最多的一個適配器!
  • ArrayAdapter:支持泛型操作,最簡單的一個適配器,只能展
    現(xiàn)一行文字?
  • SimpleAdapter:同樣具有良好擴展性的一個適配器,可以自
    定義多種效果!
  • SimpleCursorAdapter:用于顯示簡單文本類型的 listView,
    一般在數(shù)據(jù)庫那里會用到,不過有點過時,不推薦使用!
11、LinearLayout、FrameLayout、RelativeLayout 性能對比,為什么?
  • RelativeLayout 會讓子 View 調(diào)用 2 次 onMeasure,
    LinearLayout 在有 weight 時,也會調(diào)用子 View 2 次
    onMeasure
  • RelativeLayout 的子 View 如果高度和RelativeLayout 不同,
    則會引發(fā)效率問題,當子 View 很復雜時,這個問題會更加嚴
    重。如果可以,盡量使用 padding 代替 margin。 o 在不影響層級深度的情況下,使用 LinearLayout
    FrameLayout 而不是 RelativeLayout。

把面試官唬住了,就要50K。沒唬住,就要5K!Android
請查看完整的PDF版
(更多完整項目下載。未完待續(xù)。源碼。圖文知識后續(xù)上傳github。)
可以點擊關(guān)于我聯(lián)系我獲取完整PDF
(VX:mm14525201314)

把面試官唬住了,就要50K。沒唬住,就要5K!Android

向AI問一下細節(jié)

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

AI