2018面試總結(jié)

[toc]

2018面試總結(jié)

重載以及重寫的區(qū)別:

重寫(override)
重寫是子類對父類的允許訪問的方法的實(shí)現(xiàn)過程進(jìn)行重新編寫,返回值和形參都不可以改變。

規(guī)則

  • 參數(shù)列表必須與被重寫方法相同
  • 返回類型必須與被重寫方法相同
  • 訪問權(quán)限不能比父類中被重寫的方法的訪問權(quán)限更低
  • 父類的成員方法只能被它的子類 重寫
  • 聲明為final的方法不能被重寫
  • 聲明為static的方法不能被重寫,但是能夠被再次聲明
  • 子類和父類不在同一個包中,那么子類可以重寫父類所有的方法,除了聲明為final和private的方法之外
  • 子類和父類不在同一個包中,那么子類只能夠重寫父類的public和protected的非final方法
  • 重寫的方法能夠拋出任何非強(qiáng)制異常,無論被重寫的方法是否拋出異常。但是,重寫的方法不能拋出新的強(qiáng)制性異常,或者比被重寫方法聲明的更廣泛的強(qiáng)制性異常,反之則可以。
  • 構(gòu)造方法不可以被重寫
  • 如果不能繼承一個方法,則不能重寫這個方法。

重載(Overload)
重載是在一個類里面,方法名字相同,而參數(shù)不同。返回類型可以相同也可以不同。
每個重載的方法(或者構(gòu)造函數(shù))都必須有一個獨(dú)一無二的參數(shù)類型列表。

規(guī)則

  • 被重載得方法必須改變參數(shù)列表(個數(shù)或者類型)
  • 被重載得方法可以改變返回類型
  • 被重載得方法可以改變訪問修飾符
  • 被重載得方法可以聲明或者更廣得檢查異常
  • 方法能夠在同一個類中或者在一個子類中被重載
  • 無法以返回值類型作為重載函數(shù)的區(qū)分標(biāo)準(zhǔn)
區(qū)別點(diǎn) 重載overload 重寫override
參數(shù)列表 必須修改 不可以修改
返回類型 可以修改 不可以修改
異常 可以修改 可以減少或者刪除,一定不能拋出新的或者更廣的異常
訪問 可以修改 一定不能做更嚴(yán)格的限制(可以降低限制)
發(fā)生時期 編譯期(在編譯期就可以根據(jù)參數(shù)類型來選擇運(yùn)行哪個方法) 運(yùn)行期(編譯期在編譯期并不知道要運(yùn)行哪個方法,只有在代碼運(yùn)行的時候jvm才可以做出決定)

Service以及IntentService的區(qū)別

區(qū)別點(diǎn) Service IntentService
運(yùn)行線程 依附于主線程 自身內(nèi)部新開了線程
是否是完整的生命周期

IntentService繼承于Service,所以它有service的所有特性,也包括service的生命周期,與Service不同的是,IntentService在執(zhí)行oncreate的時候,內(nèi)部開辟了一個新線程,去執(zhí)行所要執(zhí)行的耗時操作,而普通的service是依賴于應(yīng)用的主線程的,所以service事實(shí)上并不能做耗時操作(不開異步線程的話)
具體參考參考

區(qū)別點(diǎn) Service IntentService
運(yùn)行線程 依附于主線程 自身內(nèi)部新開了線程
是否是完整的生命周期

線程間的通訊方式

  • runOnUiThread(Runnable)
  • View.postDelay(Runnable , long)/new Handler().postDelayed(Runnable)
  • Message/Handler
  • AsyncTask

進(jìn)程間通信的方式

  • Bundle/Intent傳遞數(shù)據(jù)

可傳遞基本類型,String,實(shí)現(xiàn)了Serializable或Parcellable接口的數(shù)據(jù)結(jié)構(gòu)。Serializable是Java的序列化方法,Parcellable是Android的序列化方法,前者代碼量少(僅一句),但I(xiàn)/O開銷較大,一般用于輸出到磁盤或網(wǎng)卡;后者實(shí)現(xiàn)代碼多,效率高,一般用戶內(nèi)存間序列化和反序列化傳輸。

  • 文件共享:

對同一個文件先后寫讀,從而實(shí)現(xiàn)傳輸,Linux機(jī)制下,可以對文件并發(fā)寫,所以要注意同步。順便一提,Windows下不支持并發(fā)讀或?qū)憽?/p>

  • Messenger:

Messenger是基于AIDL實(shí)現(xiàn)的,服務(wù)端(被動方)提供一個Service來處理客戶端(主動方)連接,維護(hù)一個Handler來創(chuàng)建Messenger,在onBind時返回Messenger的binder。雙方用Messenger來發(fā)送數(shù)據(jù),用Handler來處理數(shù)據(jù)。Messenger處理數(shù)據(jù)依靠Handler,所以是串行的,也就是說,Handler接到多個message時,就要排隊(duì)依次處理。

  • AIDL:

AIDL通過定義服務(wù)端暴露的接口,以提供給客戶端來調(diào)用,AIDL使服務(wù)器可以并行處理,而Messenger封裝了AIDL之后只能串行運(yùn)行,所以Messenger一般用作消息傳遞。通過編寫aidl文件來設(shè)計(jì)想要暴露的接口,編譯后會自動生成響應(yīng)的java文件,服務(wù)器將接口的具體實(shí)現(xiàn)寫在Stub中,用iBinder對象傳遞給客戶端,客戶端bindService的時候,用asInterface的形式將iBinder還原成接口,再調(diào)用其中的方法。

  • ContentProvider:

系統(tǒng)四大組件之一,底層也是Binder實(shí)現(xiàn),主要用來為其他APP提供數(shù)據(jù),可以說天生就是為進(jìn)程通信而生的。自己實(shí)現(xiàn)一個ContentProvider需要實(shí)現(xiàn)6個方法,其中onCreate是主線程中回調(diào)的,其他方法是運(yùn)行在Binder之中的。自定義的ContentProvider注冊時要提供authorities屬性,應(yīng)用需要訪問的時候?qū)傩园b成Uri.parse(“content://authorities”)。還可以設(shè)置permission,readPermission,writePermission來設(shè)置權(quán)限。 ContentProvider有query,delete,insert等方法,看起來貌似是一個數(shù)據(jù)庫管理類,但其實(shí)可以用文件,內(nèi)存數(shù)據(jù)等等一切來充當(dāng)數(shù)據(jù)源,query返回的是一個Cursor,可以自定義繼承AbstractCursor的類來實(shí)現(xiàn)。

  • Socket:

學(xué)過計(jì)算機(jī)網(wǎng)絡(luò)的對Socket不陌生,所以不需要詳細(xì)講述。只需要注意,Android不允許在主線程中請求網(wǎng)絡(luò),而且請求網(wǎng)絡(luò)必須要注意聲明相應(yīng)的permission。然后,在服務(wù)器中定義ServerSocket來監(jiān)聽端口,客戶端使用Socket來請求端口,連通后就可以進(jìn)行通信。

  • 廣播(Broadcast)

廣播是一種被動跨進(jìn)程通訊的方式。當(dāng)某個程序向系統(tǒng)發(fā)送廣播時,其他的應(yīng)用程序只能被動地接收廣播數(shù)據(jù)。這就象電臺進(jìn)行廣播一樣,聽眾只能被動地收聽,而不能主動與電臺進(jìn)行溝通。 在應(yīng)用程序中發(fā)送廣播比較簡單。只需要調(diào)用sendBroadcast方法即可。該方法需要一個Intent對象。通過Intent對象可以發(fā)送需要廣播的數(shù)據(jù)。

ArrayList以及LinkList的區(qū)別

相同點(diǎn)

  1. 都是List接口的實(shí)現(xiàn)類,所以都實(shí)現(xiàn)了List的所有未實(shí)現(xiàn)的方法(面向接口開發(fā),List->Collection->Iterable)

不同點(diǎn)

  1. ArrayList實(shí)現(xiàn)了List接口,是以數(shù)組的形式來進(jìn)行實(shí)現(xiàn)的,所以可以很方便地使用索引的方法來快速定位對象的位置(所以對于要求快速取得對象的需求,用ArrayList更加方便
  2. LinkedList是使用鏈表的方式來進(jìn)行實(shí)現(xiàn)的,他本身有自己的對應(yīng)方法:addFirst(),addLast()等等,由于是采用鏈表的方式實(shí)現(xiàn)的,所以在insert,remove的時候要比ArrayList方便快捷得多,適合用來實(shí)現(xiàn)Stack(堆棧),Queue(隊(duì)列)

問題

  1. 在刪除和插入數(shù)據(jù)的時候,為什么ArrayList的效率會比較低呢?
    答:因?yàn)锳rrayList是使用數(shù)組實(shí)現(xiàn)的,如果要從數(shù)組中插入或者刪除一個對象,需要移動后半部分的元素,從而需要重新調(diào)整索引順序,而這個需要耗費(fèi)一定時間,所以速度上就慢了很多;而LinkedList是使用鏈表實(shí)現(xiàn)的,如果要從鏈表中刪除或者插入一個數(shù)據(jù)對象,只需要改變前后對象的引用就可以了。

數(shù)組,ArrayList的區(qū)別

相同點(diǎn)

ArrayList是基于數(shù)組實(shí)現(xiàn)的,所以理論上ArrayList包含了數(shù)組的所有方法

不同點(diǎn)

  1. 數(shù)組可以包含基本數(shù)據(jù)類型和對象類型,ArrayList只能包含對象類型
  2. 數(shù)組的大小是固定的,而ArrayList是可以擴(kuò)容的(擴(kuò)容1.5倍)---> 在添加數(shù)據(jù)的時候,ArrayList會去檢查是否超過了他的存儲臨界點(diǎn),如果是超過了,那么他會自我擴(kuò)容:創(chuàng)建新的內(nèi)部數(shù)組(長度為老數(shù)組的1.5倍),把老的數(shù)據(jù)copy進(jìn)去,再銷毀老的數(shù)組。
  3. ArrayList通過拓展api提供了更多的方便api供開發(fā)者使用
  4. 對于基本數(shù)據(jù)類型,ArrayList使用自動封箱來減少編碼工作量,但是,如果數(shù)據(jù)的長度是固定的話,這種方式比數(shù)組更慢(因?yàn)閿?shù)據(jù)的長度已經(jīng)固定了,數(shù)組的大小也可以確定了)

ArrayList和Vector的區(qū)別

同步性

Vector是線程安全的(同步的),而ArrayList是線程不安全的(不同步的)

操作

Vector支持多線程操作,所以在效率上比不上ArrayList

數(shù)據(jù)增長

ArrayList和Vector都有一個初始的容量大小,當(dāng)存儲進(jìn)去它們里面的元素個數(shù)超出容量的時候,就需要增加ArrayList和Vector的存儲空間,每次增加存儲空間的時候不是只增加一個存儲單元,是增加多個存儲單元。
Vector默認(rèn)增加原來的一倍,ArrayList默認(rèn)增加原來的0.5倍。
Vector可以由我們自己來設(shè)置增長的大小,ArrayList沒有提供相關(guān)的方法。

Android事件分發(fā)的原理

具體概況

將點(diǎn)擊事件(MotionEvent)傳遞到某個具體的View & 處理的整個過程

參與角色

類型 簡介 備注
Activity 控制生命周期&處理事件(Controller) 統(tǒng)籌視圖的添加&顯示;通過其他回調(diào)方法與window,view進(jìn)行交互
View 所有UI組件的基類 基本上所有的視圖都是繼承自View
ViewGroup 一組View的集合 其本身也是View的子類;是安卓所有布局的父類;它實(shí)質(zhì)上也是一個View,但是比普通的View多了包含子View&定義布局參數(shù)的功能

事件類型

方法 作用 調(diào)用時刻
dispatchTouchEvent() 分發(fā)&傳遞點(diǎn)擊事件 當(dāng)事件能夠傳遞給當(dāng)前View的時候,該方法就會被調(diào)用
onInterceptTouchEvent() 判斷是否攔截了某個事件(該方法只存在于ViewGroup中,普通的View沒有這個方法) 在ViewGroup的dispatchTouchEvent()中被調(diào)用
onTouchEvent() 處理點(diǎn)擊事件 在dispatchTouchEvent()中被調(diào)用

事件流程

偷來的示意圖

equals以及hashcode

相同點(diǎn)

equals以及hashcode在java中的作用都是一樣的,都是用于判斷2個對象是否一致。

不同點(diǎn)

方法 好處 壞處
equals 比較全面,比較復(fù)雜 效率比較低
hashcode 單純生成一個hashcode進(jìn)行比較即可,效率更高 不同對象可能會生成一樣的hashcode,所以這個單純的比較并不是特別可靠

解決方案

由于他們2個分別存在有這樣那樣的問題,單純用equals比較效率太低,單純用hashcode去比較的話準(zhǔn)確率太低,所以我們得出一個解決方案:
用這2個一起去比較!綜合起來使用:需要比較的時候,我們先用hashCode()比較,如果hashCode()不一致了,那么這2個對象肯定不一致了,便無須進(jìn)行equals()的比較了;反之即再進(jìn)行equals()的比較,這樣在保證穩(wěn)定準(zhǔn)確的前提下提高了效率。
這也是為什么我們重寫了equals方法就一定要重寫另外一個hashcode方法的原因了。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 在一個方法內(nèi)部定義的變量都存儲在棧中,當(dāng)這個函數(shù)運(yùn)行結(jié)束后,其對應(yīng)的棧就會被回收,此時,在其方法體中定義的變量將不...
    Y了個J閱讀 4,575評論 1 14
  • 為什么使用單例模式 需要確保某個類只要一個對象,或創(chuàng)建一個類需要消耗的資源過多,如訪問IO和數(shù)據(jù)庫操作等,這時就需...
    Skyper閱讀 12,879評論 5 13
  • #師北宸一塊聽聽寫作課# 寫作課的第四次作業(yè),是“你所在的行業(yè)的頂級信息來源”。聽到這個作業(yè)的時候,呆了很久,不是...
    紫苑閱讀 250評論 4 3
  • 一首熟悉的老歌,總能讓我想起某個人,想起一段時光。 1 初識H君,是在我最幽暗的日子。 我們這些緊挨大學(xué)邊兒的落榜...
    芳菲晚閱讀 834評論 49 29

友情鏈接更多精彩內(nèi)容