因為實際開發(fā)與參考答案會有所不同,再者怕誤導(dǎo)大家,所以這些面試題答案還是自己去理解!面試官會針對簡歷中提到的知識點由淺入深提問,所以不要背答案,多理解。
目前成都創(chuàng)新互聯(lián)公司已為上千多家的企業(yè)提供了網(wǎng)站建設(shè)、域名、網(wǎng)站空間、網(wǎng)站運營、企業(yè)網(wǎng)站設(shè)計、涼山州網(wǎng)站維護等服務(wù),公司將堅持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長,共同發(fā)展。
1、圖片的三級緩存中,圖片加載到內(nèi)存中,如果內(nèi)存快爆了,會發(fā)生什么?怎么處理?
參考回答:首先我們要清楚圖片的三級緩存是如何的
如果內(nèi)存足夠時不回收。內(nèi)存不夠時就回收軟引用對象
2、內(nèi)存中如果加載一張500*500的png高清圖片.應(yīng)該是占用多少的內(nèi)存?
參考回答: 不考慮屏幕比的話:占用內(nèi)存=500 * 500 * 4 = 1000000B ≈ 0.95MB考慮屏幕比的的話:占用內(nèi)存= 寬度像素 x (inTargetDensity / inDensity) x 高度像素 x (inTargetDensity / inDensity)x 一個像素所占的內(nèi)存字節(jié)大小inDensity表示目標(biāo)圖片的dpi(放在哪個資源文件夾下),inTargetDensity表示目標(biāo)屏幕的dpi
3、WebView的性能優(yōu)化 ?
參考回答: 一個加載網(wǎng)頁的過程中,native、網(wǎng)絡(luò)、后端處理、CPU都會參與,各自都有必要的工作和依賴關(guān)系;讓他們相互并行處理而不是相互阻塞才可以讓網(wǎng)頁加載更快: WebView初始化慢,可以在初始化同時先請求數(shù)據(jù),讓后端和網(wǎng)絡(luò)不要閑著。常用 JS 本地化及延遲加載,使用第三方瀏覽內(nèi)核后端處理慢,可以讓服務(wù)器分trunk輸出,在后端計算的同時前端也加載網(wǎng)絡(luò)靜態(tài)資源。腳本執(zhí)行慢,就讓腳本在最后運行,不阻塞頁面解析。同時,合理的預(yù)加載、預(yù)緩存可以讓加載速度的瓶頸更小。WebView初始化慢,就隨時初始化好一個WebView待用。DNS和鏈接慢,想辦法復(fù)用客戶端使用的域名和鏈接。
4、Bitmap如何處理大圖,如一張30M的大圖,如何預(yù)防OOM?
參考回答:避免OOM的問題就需要對大圖片的加載進行管理,主要通過縮放來減小圖片的內(nèi)存占用。 BitmapFactory提供的加載圖片的四類方法(decodeFile、decodeResource、decodeStream、decodeByteArray)都支持BitmapFactory.Options參數(shù),通過inSampleSize參數(shù)就可以很方便地對一個圖片進行采樣縮放比如一張10241024的高清圖片來說。那么它占有的內(nèi)存為102410244,即4MB,如果inSampleSize為2,那么采樣后的圖片占用內(nèi)存只有5125124,即1MB(注意:根據(jù)最新的官方文檔指出,inSampleSize的取值應(yīng)該總是為2的指數(shù),即1、2、4、8等等,如果外界輸入不足為2的指數(shù),系統(tǒng)也會默認選擇最接近2的指數(shù)代替,比如2*)綜合考慮。通過采樣率即可有效加載圖片,流程如下 將BitmapFactory.Options的inJustDecodeBounds參數(shù)設(shè)為true并加載圖片從BitmapFactory.Options中取出圖片的原始寬高信息,它們對應(yīng)outWidth和outHeight參數(shù)根據(jù)采樣率的規(guī)則并結(jié)合目標(biāo)View的所需大小計算出采樣率inSampleSize將BitmapFactory.Options的inJustDecodeBounds參數(shù)設(shè)為false,重新加載圖片
5、內(nèi)存回收機制與GC算法(各種算法的優(yōu)缺點以及應(yīng)用場景);GC原理時機以及GC對象
參考回答: 內(nèi)存判定對象可回收有兩種機制: 引用計數(shù)算法:給對象中添加一個引用計數(shù)器,每當(dāng)有一個地方引用它時,計數(shù)器值就加1;當(dāng)引用失效時,計數(shù)器值就減1;任何時刻計數(shù)器為0的對象就是不可能再被使用的。然而在主流的Java虛擬機里未選用引用計數(shù)算法來管理內(nèi)存,主要原因是它難以解決對象之間相互循環(huán)引用的問題,所以出現(xiàn)了另一種對象存活判定算法。可達性分析法:通過一系列被稱為『GCRoots』的對象作為起始點,從這些節(jié)點開始向下搜索,搜索所走過的路徑稱為引用鏈,當(dāng)一個對象到GC Roots沒有任何引用鏈相連時,則證明此對象是不可用的。其中可作為GC Roots的對象:虛擬機棧中引用的對象,主要是指棧幀中的本地變量、本地方法棧中Native方法引用的對象、方法區(qū)中類靜態(tài)屬性引用的對象、方法區(qū)中常量*引用的對象GC回收算法有以下四種: 分代收集算法:是當(dāng)前商業(yè)虛擬機都采用的一種算法,根據(jù)對象存活周期的不同,將Java堆劃分為新生代和老年代,并根據(jù)各個年代的特點采用最適當(dāng)?shù)氖占惴?。新生代:大批對象死去,只有少量存活。使用『?fù)制算法』,只需復(fù)制少量存活對象即可。 復(fù)制算法:把可用內(nèi)存按容量劃分為大小相等的兩塊,每次只使用其中的一塊。當(dāng)這一塊的內(nèi)存用盡后,把還存活著的對象『復(fù)制』到另外一塊上面,再將這一塊內(nèi)存空間一次清理掉。實現(xiàn)簡單,運行高效。在對象存活率較高時就要進行較多的復(fù)制操作,效率將會變低老年代:對象存活率高。使用『標(biāo)記—清理算法』或者『標(biāo)記—整理算法』,只需標(biāo)記較少的回收對象即可。 標(biāo)記-清除算法:首先『標(biāo)記』出所有需要回收的對象,然后統(tǒng)一『清除』所有被標(biāo)記的對象。標(biāo)記和清除兩個過程的效率都不高,清除之后會產(chǎn)生大量不連續(xù)的內(nèi)存碎片,空間碎片太多可能會導(dǎo)致以后在程序運行過程中需要分配較大對象時,無法找到足夠的連續(xù)內(nèi)存而不得不提前觸發(fā)另一次垃圾收集動作。標(biāo)記-整理算法:首先『標(biāo)記』出所有需要回收的對象,然后進行『整理』,使得存活的對象都向一端移動,最后直接清理掉端邊界以外的內(nèi)存。標(biāo)記整理算法會將所有的存活對象移動到一端,并對不存活對象進行處理,因此其不會產(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)存泄露堆積后果很嚴(yán)重,無論多少內(nèi)存,遲早會被占光。memory leak會最終會導(dǎo)致out of memory!查找內(nèi)存泄漏可以使用Android Studio 自帶的AndroidProfiler工具或MAT
7、性能優(yōu)化,怎么保證應(yīng)用啟動不卡頓? 黑白屏怎么處理?
參考回答: 應(yīng)用啟動速度,取決于你在application里面時候做了什么事情,比如你集成了很多sdk,并且sdk的init操作都需要在主線程里實現(xiàn)所以會有卡頓的感覺。在非必要的情況下可以把加載延后或則開啟子線程處理另外,影響界面卡頓的兩大因素,分別是界面繪制和數(shù)據(jù)處理。布局優(yōu)化(使用include,merge標(biāo)簽,復(fù)雜布局推薦使用ConstraintLayout等)onCreate() 中不執(zhí)行耗時操作 把頁面顯示的 View 細分一下,放在 AsyncTask 里逐步顯示,用 Handler 更好。這樣用戶的看到的就是有層次有步驟的一個個的 View 的展示,不會是先看到一個黑屏,然后一下顯示所有 View。最好做成動畫,效果更自然。利用多線程的目的就是盡可能的減少 onCreate() 和 onReume() 的時間,使得用戶能盡快看到頁面,操作頁面。減少主線程阻塞時間。提高 Adapter 和 AdapterView 的效率。黑白屏產(chǎn)生原因:當(dāng)我們在啟動一個應(yīng)用時,系統(tǒng)會去檢查是否已經(jīng)存在這樣一個進程,如果不存在,系統(tǒng)的服務(wù)會先檢查startActivity中的intent的信息,然后在去創(chuàng)建進程,最后啟動Acitivy,即冷啟動。而啟動出現(xiàn)白黑屏的問題,就是在這段時間內(nèi)產(chǎn)生的。系統(tǒng)在繪制頁面加載布局之前,首先會初始化窗口(Window),而在進行這一步操作時,系統(tǒng)會根據(jù)我們設(shè)置的Theme來指定它的Theme 主題顏色,我們在Style中的設(shè)置就決定了顯示的是白屏還是黑屏。 windowIsTranslucent和windowNoTitle,將這兩個屬性都設(shè)置成true (會有明顯的卡頓體驗,不推薦)如果啟動頁只是是一張圖片,那么為啟動頁專一設(shè)置一個新的主題,設(shè)置主題的android:windowBackground屬性為啟動頁背景圖即可使用layer-list制作一張圖片launcher_layer.xml,將其設(shè)置為啟動頁專一主題的背景,并將其設(shè)置為啟動頁布局的背景。
8、強引用置為null,會不會被回收?
參考回答: 不會立即釋放對象占用的內(nèi)存。 如果對象的引用被置為null,只是斷開了當(dāng)前線程棧幀中對該對象的引用關(guān)系,而 垃圾收集器是運行在后臺的線程,只有當(dāng)用戶線程運行到安全點(safe point)或者安全區(qū)域才會掃描對象引用關(guān)系,掃描到對象沒有被引用則會標(biāo)記對象,這時候仍然不會立即釋放該對象內(nèi)存,因為有些對象是可恢復(fù)的(在 finalize方法中恢復(fù)引用 )。只有確定了對象無法恢復(fù)引用的時候才會清除對象內(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)的,當(dāng)一個item數(shù)據(jù)刷新時,我們可以在Adapter中,實現(xiàn)一個onItemChanged()方法,在方法里面獲取到這個item的position(可以通過getFirstVisiblePosition()),然后調(diào)用getView()方法來刷新這個item的數(shù)據(jù);RecyclerView中可以實現(xiàn)局部刷新,例如:notifyItemChanged();緩存區(qū)別: RecyclerView比ListView多兩級緩存,支持多個離ItemView緩存,支持開發(fā)者自定義緩存處理邏輯,支持所有RecyclerView共用同一個RecyclerViewPool(緩存池)。ListView和RecyclerView緩存機制基本一致,但緩存使用不同
10、ListView的adapter是什么adapter
參考回答:
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次onMeasureRelativeLayout的子View如果高度和RelativeLayout不同,則會引發(fā)效率問題,當(dāng)子View很復(fù)雜時,這個問題會更加嚴(yán)重。如果可以,盡量使用padding代替margin。在不影響層級深度的情況下,使用LinearLayout和FrameLayout而不是RelativeLayout。