2018過度到2019 面試題

中高級面試題,總結

1、Service生命週期?
service 啓動方式有兩種,一種是通過startService()方式進行啓動,另一種是通過bindService()方式進行啓動。不同的啓動方式他們的生命週期是不一樣.
通過startService()這種方式啓動的service,生命週期是這樣:調用startService() --> onCreate()–> onStartConmon()–> onDestroy()。這種方式啓動的話,需要注意一下幾個問題,第一:當我們通過startService被調用以後,多次在調用startService(),onCreate()方法也只會被調用一次,而onStartConmon()會被多次調用當我們調用stopService()的時候,onDestroy()就會被調用,從而銷燬服務。第二:當我們通過startService啓動時候,通過intent傳值,在onStartConmon()方法中獲取值的時候,一定要先判斷intent是否爲null。
通過bindService()方式進行綁定,這種方式綁定service,生命週期走法:bindService–>onCreate()–>onBind()–>unBind()–>onDestroy() bingservice 這種方式進行啓動service好處是更加便利activity中操作service,比如加入service中有幾個方法,a,b ,如果要在activity中調用,在需要在activity獲取ServiceConnection對象,通過ServiceConnection來獲取service中內部類的類對象,然後通過這個類對象就可以調用類中的方法,當然這個類需要繼承Binder對象

2、Broadcast註冊方式與區別
此處延伸:什麼情況下用動態註冊

Broadcast廣播,註冊方式主要有兩種.
第一種是靜態註冊,也可成爲常駐型廣播,這種廣播需要在Androidmanifest.xml中進行註冊,這中方式註冊的廣播,不受頁面生命週期的影響,即使退出了頁面,也可以收到廣播這種廣播一般用於想開機自啓動啊等等,由於這種註冊的方式的廣播是常駐型廣播,所以會佔用CPU的資源。

第二種是動態註冊,而動態註冊的話,是在代碼中註冊的,這種註冊方式也叫非常駐型廣播,收到生命週期的影響,退出頁面後,就不會收到廣播,我們通常運用在更新UI方面。這種註冊方式優先級較高。最後需要解綁,否會會內存泄露
廣播是分爲有序廣播和無序廣播。

3、HttpClient與HttpUrlConnection的區別
此處延伸:Volley裏用的哪種請求方式(2.3前HttpClient,2.3後HttpUrlConnection)

首先HttpClient和HttpUrlConnection 這兩種方式都支持Https協議,都是以流的形式進行上傳或者下載數據,也可以說是以流的形式進行數據的傳輸,還有ipv6,以及連接池等功能。HttpClient這個擁有非常多的API,所以如果想要進行擴展的話,並且不破壞它的兼容性的話,很難進行擴展,也就是這個原因,Google在Android6.0的時候,直接就棄用了這個HttpClient.
而HttpUrlConnection相對來說就是比較輕量級了,API比較少,容易擴展,並且能夠滿足Android大部分的數據傳輸。比較經典的一個框架volley,在2.3版本以前都是使用HttpClient,在2.3以後就使用了HttpUrlConnection。

4、java虛擬機和Dalvik虛擬機的區別
Java虛擬機:
1、java虛擬機基於棧。 基於棧的機器必須使用指令來載入和操作棧上數據,所需指令更多更多。
2、java虛擬機運行的是java字節碼。(java類會被編譯成一個或多個字節碼.class文件)
Dalvik虛擬機:
1、dalvik虛擬機是基於寄存器的
2、Dalvik運行的是自定義的.dex字節碼格式。(java類被編譯成.class文件後,會通過一個dx工具將所有的.class文件轉換成一個.dex文件,然後dalvik虛擬機會從其中讀取指令和數據
3、常量池已被修改爲只使用32位的索引,以 簡化解釋器。
4、一個應用,一個虛擬機實例,一個進程(所有android應用的線程都是對應一個linux線程,都運行在自己的沙盒中,不同的應用在不同的進程中運行。每個android dalvik應用程序都被賦予了一個獨立的linux PID(app_*))

5、講解一下Context
Context是一個抽象基類。在翻譯爲上下文,也可以理解爲環境,是提供一些程序的運行環境基礎信息。Context下有兩個子類,ContextWrapper是上下文功能的封裝類,而ContextImpl則是上下文功能的實現類。而ContextWrapper又有三個直接的子類, ContextThemeWrapper、Service和Application。其中,ContextThemeWrapper是一個帶主題的封裝類,而它有一個直接子類就是Activity,所以Activity和Service以及Application的Context是不一樣的,只有Activity需要主題,Service不需要主題。Context一共有三種類型,分別是Application、Activity和Service。這三個類雖然分別各種承擔着不同的作用,但它們都屬於Context的一種,而它們具體Context的功能則是由ContextImpl類去實現的,因此在絕大多數場景下,Activity、Service和Application這三種類型的Context都是可以通用的。不過有幾種場景比較特殊,比如啓動Activity,還有彈出Dialog。出於安全原因的考慮,Android是不允許Activity或Dialog憑空出現的,一個Activity的啓動必須要建立在另一個Activity的基礎之上,也就是以此形成的返回棧。而Dialog則必須在一個Activity上面彈出(除非是System Alert類型的Dialog),因此在這種場景下,我們只能使用Activity類型的Context,否則將會出錯。

getApplicationContext()和getApplication()方法得到的對象都是同一個application對象,只是對象的類型不一樣。
Context數量 = Activity數量 + Service數量 + 1 (1爲Application

6、四種LaunchMode及其使用場景
此處延伸:棧(First In Last Out)與隊列(First In First Out)的區別
棧與隊列的區別:

  1. 隊列先進先出,棧先進後出
  2. 對插入和刪除操作的"限定"。 棧是限定只能在表的一端進行插入和刪除操作的線性表。 隊列是限定只能在表的一端進行插入和在另一端進行刪除操作的線性表。
  3. 遍歷數據速度不同
    standard 模式
    這是默認模式,每次激活Activity時都會創建Activity實例,並放入任務棧中。使用場景:大多數Activity。
    singleTop 模式
    如果在任務的棧頂正好存在該Activity的實例,就重用該實例( 會調用實例的 onNewIntent() ),否則就會創建新的實例並放入棧頂,即使棧中已經存在該Activity的實例,只要不在棧頂,都會創建新的實例。使用場景如新聞類或者閱讀類App的內容頁面。
    singleTask 模式
    如果在棧中已經有該Activity的實例,就重用該實例(會調用實例的 onNewIntent() )。重用時,會讓該實例回到棧頂,因此在它上面的實例將會被移出棧。如果棧中不存在該實例,將會創建新的實例放入棧中。使用場景如瀏覽器的主界面。不管從多少個應用啓動瀏覽器,只會啓動主界面一次,其餘情況都會走onNewIntent,並且會清空主界面上面的其他頁面。
    singleInstance 模式
    在一個新棧中創建該Activity的實例,並讓多個應用共享該棧中的該Activity實例。一旦該模式的Activity實例已經存在於某個棧中,任何應用再激活該Activity時都會重用該棧中的實例( 會調用實例的 onNewIntent() )。其效果相當於多個應用共享一個應用,不管誰激活該 Activity 都會進入同一個應用中。使用場景如鬧鈴提醒,將鬧鈴提醒與鬧鈴設置分離。singleInstance不要用於中間頁面,如果用於中間頁面,跳轉會有問題,比如:A -> B (singleInstance) -> C,完全退出後,在此啓動,首先打開的是B。

7、Android內存泄露及管理
(1)內存溢出(OOM)和內存泄露(對象無法被回收)的區別。
(2)引起內存泄露的原因
(3) 內存泄露檢測工具 ------>LeakCanary

內存溢出 out of memory:是指程序在申請內存時,沒有足夠的內存空間供其使用,出現out of memory;比如申請了一個integer,但給它存了long才能存下的數,那就是內存溢出。內存溢出通俗的講就是內存不夠用。
內存泄露 memory leak:是指程序在申請內存後,無法釋放已申請的內存空間,一次內存泄露危害可以忽略,但內存泄露堆積後果很嚴重,無論多少內存,遲早會被佔光
內存泄露原因:
一、Handler 引起的內存泄漏。
解決:將Handler聲明爲靜態內部類,就不會持有外部類SecondActivity的引用,其生命週期就和外部類無關,
如果Handler裏面需要context的話,可以通過弱引用方式引用外部類
二、單例模式引起的內存泄漏。
解決:Context是ApplicationContext,由於ApplicationContext的生命週期是和app一致的,不會導致內存泄漏
三、非靜態內部類創建靜態實例引起的內存泄漏。
解決:把內部類修改爲靜態的就可以避免內存泄漏了
四、非靜態匿名內部類引起的內存泄漏。
解決:將匿名內部類設置爲靜態的。
五、註冊/反註冊未成對使用引起的內存泄漏。
註冊廣播接受器、EventBus等,記得解綁。
六、資源對象沒有關閉引起的內存泄漏。
在這些資源不使用的時候,記得調用相應的類似close()、destroy()、recycler()、release()等方法釋放。
七、集合對象沒有及時清理引起的內存泄漏。
通常會把一些對象裝入到集合中,當不使用的時候一定要記得及時清理集合,讓相關對象不再被引用。

8、Fragment與Fragment、Activity通信的方式
1.直接在一個Fragment中調用另外一個Fragment中的方法
2.使用接口回調
3.使用廣播
4.Fragment直接調用Activity中的public方法

9、Android UI適配
字體使用sp,使用dp,多使用match_parent,wrap_content,weight
圖片資源,不同圖片的的分辨率,放在相應的文件夾下可使用百分比代替。

10、RecyclerView和ListView的區別
RecyclerView可以完成ListView,GridView的效果,還可以完成瀑布流的效果。同時還可以設置列表的滾動方向(垂直或者水平);
RecyclerView中view的複用不需要開發者自己寫代碼,系統已經幫封裝完成了。
RecyclerView可以進行局部刷新。
RecyclerView提供了API來實現item的動畫效果。
在性能上:
如果需要頻繁的刷新數據,需要添加動畫,則RecyclerView有較大的優勢。
如果只是作爲列表展示,則兩者區別並不是很大。

11、Xutils, OKhttp, Volley, Retrofit對比
Xutils這個框架非常全面,可以進行網絡請求,可以進行圖片加載處理,可以數據儲存,還可以對view進行註解,使用這個框架非常方便,但是缺點也是非常明顯的,使用這個項目,會導致項目對這個框架依賴非常的嚴重,一旦這個框架出現問題,那麼對項目來說影響非常大的。、
OKhttp:Android開發中是可以直接使用現成的api進行網絡請求的。就是使用HttpClient,HttpUrlConnection進行操作。okhttp針對Java和Android程序,封裝的一個高性能的http請求庫,支持同步,異步,而且okhttp又封裝了線程池,封裝了數據轉換,封裝了參數的使用,錯誤處理等。API使用起來更加的方便。但是我們在項目中使用的時候仍然需要自己在做一層封裝,這樣才能使用的更加的順手。
Volley:Volley是Google官方出的一套小而巧的異步請求庫,該框架封裝的擴展性很強,支持HttpClient、HttpUrlConnection, 甚至支持OkHttp,而且Volley裏面也封裝了ImageLoader,所以如果你願意你甚至不需要使用圖片加載框架,不過這塊功能沒有一些專門的圖片加載框架強大,對於簡單的需求可以使用,稍複雜點的需求還是需要用到專門的圖片加載框架。Volley也有缺陷,比如不支持post大數據,所以不適合上傳文件。不過Volley設計的初衷本身也就是爲頻繁的、數據量小的網絡請求而生。
Retrofit:Retrofit是Square公司出品的默認基於OkHttp封裝的一套RESTful網絡請求框架,RESTful是目前流行的一套api設計的風格, 並不是標準。Retrofit的封裝可以說是很強大,裏面涉及到一堆的設計模式,可以通過註解直接配置請求,可以使用不同的http客戶端,雖然默認是用http ,可以使用不同Json Converter 來序列化數據,同時提供對RxJava的支持,使用Retrofit + OkHttp + RxJava + Dagger2 可以說是目前比較潮的一套框架,但是需要有比較高的門檻。
Volley VS OkHttp
Volley的優勢在於封裝的更好,而使用OkHttp你需要有足夠的能力再進行一次封裝。而OkHttp的優勢在於性能更高,因爲 OkHttp基於NIO和Okio ,所以性能上要比 Volley更快。IO 和 NIO這兩個都是Java中的概念,如果我從硬盤讀取數據,第一種方式就是程序一直等,數據讀完後才能繼續操作這種是最簡單的也叫阻塞式IO,還有一種是你讀你的,程序接着往下執行,等數據處理完你再來通知我,然後再處理回調。而第二種就是 NIO 的方式,非阻塞式, 所以NIO當然要比IO的性能要好了,而 Okio是 Square 公司基於IO和NIO基礎上做的一個更簡單、高效處理數據流的一個庫。理論上如果Volley和OkHttp對比的話,更傾向於使用 Volley,因爲Volley內部同樣支持使用OkHttp,這點OkHttp的性能優勢就沒了, 而且 Volley 本身封裝的也更易用,擴展性更好些。
OkHttp VS Retrofit
毫無疑問,Retrofit 默認是基於 OkHttp 而做的封裝,這點來說沒有可比性,肯定首選 Retrofit。
Volley VS Retrofit
這兩個庫都做了不錯的封裝,但Retrofit解耦的更徹底,尤其Retrofit2.0出來,Jake對之前1.0設計不合理的地方做了大量重構, 職責更細分,而且Retrofit默認使用OkHttp,性能上也要比Volley佔優勢,再有如果你的項目如果採用了RxJava ,那更該使用 Retrofit 。所以這兩個庫相比,Retrofit更有優勢,在能掌握兩個框架的前提下該優先使用 Retrofit。但是Retrofit門檻要比Volley稍高些,要理解他的原理,各種用法,想徹底搞明白還是需要花些功夫的,如果你對它一知半解,那還是建議在商業項目使用Volley吧。

12、String,StringBuffer,StringBuilder區別
1、三者在執行速度上:StringBuilder > StringBuffer > String (由於String是常量,不可改變,拼接時會重新創建新的對象)。
2、StringBuffer是線程安全的,StringBuilder是線程不安全的。(由於StringBuffer有緩衝區)

13、Java中重載和重寫的區別:
1、重載:一個類中可以有多個相同方法名的,但是參數類型和個數都不一樣。這是重載。
2、重寫:子類繼承父類,則子類可以通過實現父類中的方法,從而新的方法把父類舊的方法覆蓋。

14、Http https區別
此處延伸:https的實現原理

1、https協議需要到ca申請證書,一般免費證書較少,因而需要一定費用。
2、http是超文本傳輸協議,信息是明文傳輸,https則是具有安全性的ssl加密傳輸協議。
3、http和https使用的是完全不同的連接方式,用的端口也不一樣,前者是80,後者是443。
4、http的連接很簡單,是無狀態的;HTTPS協議是由SSL+HTTP協議構建的可進行加密傳輸、身份認證的網絡協議,比http協議安全。

https實現原理:
(1)客戶使用https的URL訪問Web服務器,要求與Web服務器建立SSL連接。
(2)Web服務器收到客戶端請求後,會將網站的證書信息(證書中包含公鑰)傳送一份給客戶端。
(3)客戶端的瀏覽器與Web服務器開始協商SSL連接的安全等級,也就是信息加密的等級。
(4)客戶端的瀏覽器根據雙方同意的安全等級,建立會話密鑰,然後利用網站的公鑰將會話密鑰加密,並傳送給網站。
(5)Web服務器利用自己的私鑰解密出會話密鑰。
(6)Web服務器利用會話密鑰加密與客戶端之間的通信。

15、Http位於TCP/IP模型中的第幾層?爲什麼說Http是可靠的數據傳輸協議?
tcp/ip的五層模型:
從下到上:物理層->數據鏈路層->網絡層->傳輸層->應用層
其中tcp/ip位於模型中的網絡層,處於同一層的還有ICMP(網絡控制信息協議)。http位於模型中的應用層
由於tcp/ip是面向連接的可靠協議,而http是在傳輸層基於tcp/ip協議的,所以說http是可靠的數據傳輸協議。

16、HTTP鏈接的特點
HTTP連接最顯著的特點是客戶端發送的每次請求都需要服務器回送響應,在請求結束後,會主動釋放連接。
從建立連接到關閉連接的過程稱爲“一次連接”。

17、TCP和UDP的區別
tcp是面向連接的,由於tcp連接需要三次握手,所以能夠最低限度的降低風險,保證連接的可靠性。
udp 不是面向連接的,udp建立連接前不需要與對象建立連接,無論是發送還是接收,都沒有發送確認信號。所以說udp是不可靠的。
由於udp不需要進行確認連接,使得UDP的開銷更小,傳輸速率更高,所以實時行更好。

18、Socket建立網絡連接的步驟
建立Socket連接至少需要一對套接字,其中一個運行與客戶端–ClientSocket,一個運行於服務端–ServiceSocket
1、服務器監聽:服務器端套接字並不定位具體的客戶端套接字,而是處於等待連接的狀態,實時監控網絡狀態,等待客戶端的連接請求。
2、客戶端請求:指客戶端的套接字提出連接請求,要連接的目標是服務器端的套接字。注意:客戶端的套接字必須描述他要連接的服務器的套接字,
指出服務器套接字的地址和端口號,然後就像服務器端套接字提出連接請求。
3、連接確認:當服務器端套接字監聽到客戶端套接字的連接請求時,就響應客戶端套接字的請求,建立一個新的線程,把服務器端套接字的描述
發給客戶端,一旦客戶端確認了此描述,雙方就正式建立連接。而服務端套接字則繼續處於監聽狀態,繼續接收其他客戶端套接字的連接請求。

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