Android開發面試經——6.常見面試官提問Android題②

轉自:http://blog.csdn.net/finddreams/article/details/44560061


關注finddreams博客:http://blog.csdn.net/finddreams/article/details/44560061 
1.HttpURLConnection和HttpClient他們各自的優缺點是什麼? 
HttpUrlConnection 在 2.3 以前的版本是有 bug 的,所以之前的版本推薦使用 HttpClient,但是 google 現在已經不維護 HttpClient 了,5.1裏面已經把 HttpClient 標過期。另外 HttpURLConnection 支持gzip壓縮等,推薦首選它。 
在 Froyo(2.2) 之前,HttpURLConnection 有個重大 Bug,調用 close() 函數會影響連接池,導致連接複用失效,所以在 Froyo 之前使用 HttpURLConnection 需要關閉 keepAlive。 
另外在 Gingerbread(2.3) HttpURLConnection 默認開啓了 gzip 壓縮,提高了 HTTPS 的性能,Ice Cream Sandwich(4.0) HttpURLConnection 支持了請求結果緩存。 
再加上 HttpURLConnection 本身 API 相對簡單,所以對 Android 來說,在 2.3 之後建議使用 HttpURLConnection,之前建議使用 AndroidHttpClient。

2.Android開發中XML解析方式的比較 ,及優缺點? 
DOM,SAX,Pull解析。 
SAX解析器的優點是解析速度快,佔用內存少;

DOM在內存中以樹形結構存放,因此檢索和更新效率會更高。但是對於特別大的文檔,解析和加載整個文檔將會很耗資源,不適合移動端;

PULL解析器的運行方式和SAX類似,都是基於事件的模式,PULL解析器小巧輕便,解析速度快,簡單易用,非常適合在Android移動設備中使用,Android系統內部在解析各種XML時也是用PULL解析器。

3.請問平時開發過程中,你是如何做到多分辨率適配的? 
1.根據不同分辨率建立不同的佈局文件 
2.根據分辨率不同建立不同分辨率的資源圖片 
3.在程序啓動時,獲取當前屏幕的分辨率和密度,在代碼中進行適配 
4.爲不同分辨率的寫不同的dimen文件。 
5.其實還有就是多使用fragement

4. 談談你在工作中是怎樣解決一個bug的? 
1.看Log日誌 
2.Log解決不了就斷點調試 
3.如果debug不行 
4.就在異常代碼的附近Log.e(“error”,”1”);,2,3,4,5,6,7,8,9 每隔一行一個Log輸出,看結果 
5.找到問題,自行找思路。如果是技術瓶頸,就google之

5.聲明ViewHolder內部類時,爲什麼建議使用static關鍵字? 
其實這個是考靜態內部類和非靜態內部類的主要區別之一。非靜態內部類會隱式持有外部類的引用,就像大家經常將自定義的adapter在Activity類裏,然後在adapter類裏面是可以隨意調用外部activity的方法的。當你將內部類定義爲static時,你就調用不了外部類的實例方法了,因爲這時候靜態內部類是不持有外部類的引用的。聲明ViewHolder靜態內部類,可以將ViewHolder和外部類解引用。大家會說一般ViewHolder都很簡單,不定義爲static也沒事吧。確實如此,但是如果你將它定義爲static的,說明你懂這些含義。萬一有一天你在這個ViewHolder加入一些複雜邏輯,做了一些耗時工作,那麼如果ViewHolder是非靜態內部類的話,就很容易出現內存泄露。如果是靜態的話,你就不能直接引用外部類,迫使你關注如何避免相互引用。 所以將 ViewHolder內部類 定義爲靜態的,是一種好習慣. 
非靜態內部類隱式持有外部類的強引用,只是可能會導致內存泄露,而一般情況下在使用viewhodler是不會導致內存泄露的,加static是一個比較好的習慣

6.如何在不失真的條件下顯示一張超高清的圖片或者長圖? 
1、通過計算BitmapFactory.Options 對象的inSamleSize 值 等比的壓縮圖片 。 
2、使用WebView來加載該圖片; 
3、使用MapView或者TileView來顯示圖片(類似地圖的機制);

7. Android中有哪些方法實現定時和延時任務?它們的適用場景是什麼? 
倒計時類 
用CountDownTimer

延遲類 
CountDownTimer,可巧妙的將countDownInterval設成和millisInFuture一樣,這樣就只會調用一次onTick和一次onFinish 
handler.sendMessageDelayed,可參考CountDownTimer的內部實現,簡化一下,個人比較推薦這個 
TimerTask,代碼寫起來比較亂 
Thread.sleep,感覺這種不太好 
使用Handler方法postDelay(runnable, delayTime)

定時類 
參照延遲類的,自己計算好要延遲多少時間 
handler.sendMessageAtTime 
AlarmManager,適用於定時比較長遠的時間,例如鬧鈴

8.談談你對StrongReference、WeakReference和SoftReference的認識 
強引用(StrongReference):就是在代碼中普遍存在的,類似Object obj = new Object()這類的引用,只要強引用還存在,GC永遠不會回收掉被引用的對象。 
軟引用(SoftReference):用來描述一些還有用但非必須的對象。對於軟引用關聯着的對象,在系統將要發生內存溢出異常時,將會把這些對象列入回收範圍之中進行第二次回收。如果這次回收還沒有足夠的內存,纔會拋出內存溢出異常。在JDK 1.2之後,提供了SoftReference類來實習軟引用。

弱引用(WeakReference):也是用來描述非必須對象的,但是它的強度比軟引用更弱一些,被弱引用關聯的對象只能生存到了下一次GC發生之前。當GC工作時,無論當時內存是否足夠,都會回收只被弱引用關聯的對象。在JDK 1.2之後,提供了WeakReference類來實現弱引用。

虛引用(PhantomReference):這個引用po主沒有提到,不過也可以順帶了解一下。虛引用也稱幽靈引用或者幻影引用,它是最弱的一種引用關係。一個對象是否有虛引用的存在,完全不會對其生存時間構成影響,也無法通過虛引用來取得一個對象實例。爲一個對象設置虛引用的唯一目的就是在這個對象被GC回收是收到一個系統通知。在JDK 1.2之後提供了PhantomReference類來實現虛引用。

9.你應用中的網絡層是怎麼設計的? 
1. android-async-http. 
封裝了下常用的方法,get post 上傳 下載 ,所有的請求我都是用的同步請求. 
具體的用法一般都是和業務邏輯在一起,而我的業務邏輯是用異步去處理的. 
關於網絡請求結果的緩存,我是單獨處理的.並沒有放在網絡層.

2.在HttpUrlConnection基礎上封裝, 包括請求成功, 失敗, 請求中, 網絡問題等封裝, 利用廣播與UI交互 
3.直接使用xUtils,afinal,okHttp,Volley等開源第三方框架;

Bitmap是android中經常使用的一個類,它代表了一個圖片資源。 
Bitmap消耗內存很嚴重,如果不注意優化代碼,經常會出現OOM問題,優化方式通常有這麼幾種: 
1. 使用緩存; 
2. 壓縮圖片; 
3. 及時回收;

10.談談你對Bitmap的理解, 什麼時候應該手動調用bitmap.recycle()? 
至於什麼時候需要手動調用recycle,這就看具體場景了,原則是當我們不再使用Bitmao時,需要回收之。另外,我們需要注意,2.3之前Bitmap對象與像素數據是分開存放的,Bitmap對象存在java Heap中而像素數據存放在Native Memory中,這時很有必要調用recycle回收內存。但是2.3之後,Bitmap對象和像素數據都是存在Heap中,GC可以回收其內存。

11.ViewPager中加載Fragment的優化問題?如何做到微信那樣切換界面時的延時加載? 
利用fragment中的setUserVisibleHint這個方法可以來做到.

<code
 class="hljs java has-numbering" style="display: block; padding: 0px; 
color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', 
monospace;font-size:undefined; white-space: pre; border-radius: 0px; 
word-wrap: normal; background: transparent;"><span 
class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
border-box;">private</span> <span class="hljs-keyword" 
style="color: rgb(0, 0, 136); box-sizing: 
border-box;">boolean</span> hasLoadedOnce = <span 
class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
border-box;">false</span>; <span class="hljs-comment" 
style="color: rgb(136, 0, 0); box-sizing: border-box;">// your 
boolean field</span>

<span class="hljs-annotation" style="color: rgb(155, 133, 157); 
box-sizing: border-box;">@Override</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
border-box;">public</span> <span class="hljs-keyword" 
style="color: rgb(0, 0, 136); box-sizing: 
border-box;">void</span> <span class="hljs-title" 
style="box-sizing: 
border-box;">setUserVisibleHint</span>(<span 
class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
border-box;">boolean</span> isVisibleToUser) {
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); 
box-sizing: 
border-box;">super</span>.setUserVisibleHint(isVisibleToUser);

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); 
box-sizing: border-box;">if</span> (<span 
class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
border-box;">this</span>.isVisible()) {
        <span class="hljs-comment" style="color: rgb(136, 0, 0); 
box-sizing: border-box;">// we check that the fragment is becoming 
visible</span>
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); 
box-sizing: border-box;">if</span> (isVisibleToUser && 
!hasLoadedOnce) {
                <span class="hljs-comment" style="color: rgb(136, 0, 
0); box-sizing: border-box;">//do something</span>
            }
        }
    }
}</code><ul class="pre-numbering" style="box-sizing: 
border-box; position: absolute; width: 50px; top: 0px; left: 0px; 
margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; 
border-right-style: solid; border-right-color: rgb(221, 221, 221); 
list-style: none; text-align: right; background-color: rgb(238, 238, 
238);"><li style="box-sizing: border-box; padding: 0px 
5px;">1</li><li style="box-sizing: border-box; padding: 0px 
5px;">2</li><li style="box-sizing: border-box; padding: 0px 
5px;">3</li><li style="box-sizing: border-box; padding: 0px 
5px;">4</li><li style="box-sizing: border-box; padding: 0px 
5px;">5</li><li style="box-sizing: border-box; padding: 0px 
5px;">6</li><li style="box-sizing: border-box; padding: 0px 
5px;">7</li><li style="box-sizing: border-box; padding: 0px 
5px;">8</li><li style="box-sizing: border-box; padding: 0px 
5px;">9</li><li style="box-sizing: border-box; padding: 0px 
5px;">10</li><li style="box-sizing: border-box; padding: 0px
 5px;">11</li><li style="box-sizing: border-box; padding: 
0px 5px;">12</li><li style="box-sizing: border-box; padding:
 0px 5px;">13</li><li style="box-sizing: border-box; 
padding: 0px 5px;">14</li></ul>

12什麼是aar?aar和jar有什麼區別? 
“aar”包是 Android 的類庫項目的二進制發行包。

文件擴展名是.aar,maven 項目類型應該也是aar,但文件本身是帶有以下各項的 zip 文件:

/AndroidManifest.xml (mandatory) 
/classes.jar (mandatory) 
/res/ (mandatory) 
/R.txt (mandatory) 
/assets/ (optional) 
/libs/*.jar (optional) 
/jni//*.so (optional) 
/proguard.txt (optional) 
/lint.jar (optional) 
這些條目是直接位於 zip 文件根目錄的。 
其中R.txt 文件是aapt帶參數–output-text-symbols的輸出結果。

jar打包不能包含資源文件,比如一些drawable文件、xml資源文件之類的,aar可以。

13.如何加密Url防止被黑? 
加密到JNI裏面還是會通過抓包工具抓取到.最後的方式就是進行HTTPS證書雙向加密驗證

14.Android fragment和activity的區別 
你可以理解Fragment是一種特殊的View,負責一個模塊或者一個特殊部分的展示。 
大部分Fragment是依託於Activity存在的,由Activity的FragmentManager來管理 
Fragment可以解決多Activity的問題,即將3.0之前的頻繁Activity跳轉改成一個Activity內Fragment的切換。 
Fragment可以解決碎片化的問題。 
fragment是android3.0新增的 
fragment可以重用 
fragment必須嵌套在activity中使用,它的生命週期受activity的影響。

15.Service和廣播 BroadcastReceivre會不會出現ANR? 
Service,廣播 會出現ANR 
服務, 廣播都是主線程中, 既然是主線程 當然會anr 所以耗時操作還是必須另起線程 
通俗的說超時時間:Activity 5秒, Broadcast 10秒, Server 20秒

16.你在平時開發中會使用到哪些設計模式,能談談這些設計模式的使用場景嗎? 
平時用的比較多有單例模式(在內存中僅實例化一個對象時使用),適配器模式(典型的就是ListView和GridView的適配器),建造者模式(AlertDialog.Builder),觀察者模式可能比較隱蔽,在Android源碼中BaseAdapater的NotifyDataSetChanged的實現(?) 
單例:DownloadManager

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章