android面試題及進階拓展(附答案)(三)

android進階面試知識

1、AsyncTask的工作原理

AsyncTask是Android本身提供的一種輕量級的異步任務(wù)類。它可以在線程池中執(zhí)行后臺任務(wù),然后把執(zhí)行的進度和最終的結(jié)果傳遞給主線程更新UI。實際上,AsyncTask內(nèi)部是封裝了Thread和Handler。雖然AsyncTask很方便的執(zhí)行后臺任務(wù),以及在主線程上更新UI,但是,AsyncTask并不合適進行特別耗時的后臺操作,對于特別耗時的任務(wù),個人還是建議使用線程池。

AsyncTask提供有4個核心方法:

1、onPreExecute():該方法在主線程中執(zhí)行,在執(zhí)行異步任務(wù)之前會被調(diào)用,一般用于一些準(zhǔn)備工作。

2、doInBackground(String... params):這個方法是在線程池中執(zhí)行,此方法用于執(zhí)行異步任務(wù)。在這個方法中可以通過publishProgress方法來更新任務(wù)的進度,publishProgress方法會調(diào)用onProgressUpdate方法,另外,任務(wù)的結(jié)果返回給onPostExecute方法。

3、onProgressUpdate(Object... values):該方法在主線程中執(zhí)行,主要用于任務(wù)進度更新的時候,該方法會被調(diào)用。

4、onPostExecute(Long aLong):在主線程中執(zhí)行,在異步任務(wù)執(zhí)行完畢之后,該方法會被調(diào)用,該方法的參數(shù)及為后臺的返回結(jié)果。

除了這幾個方法之外還有一些不太常用的方法,如onCancelled(),在異步任務(wù)取消的情況下,該方法會被調(diào)用。

源碼可以知道從上面的execute方法內(nèi)部調(diào)用的是executeOnExecutor()方法,即executeOnExecutor(sDefaultExecutor, params);

而sDefaultExecutor實際上是一個串行的線程池。而onPreExecute()方法在這里就會被調(diào)用了。接著看這個線程池。

AsyncTask的執(zhí)行是排隊執(zhí)行的,因為有關(guān)鍵字synchronized,而AsyncTask的Params參數(shù)就封裝成為FutureTask類,F(xiàn)utureTask這個類是一個并發(fā)類,在這里它充當(dāng)了Runnable的作用。

接著FutureTask會交給SerialExecutor的execute方法去處理,而SerialExecutor的executor方法首先就會將FutureTask添加到mTasks隊列中,如果這個時候沒有任務(wù),就會調(diào)用scheduleNext()方法,執(zhí)行下一個任務(wù)。如果有任務(wù)的話,則執(zhí)行完畢后最后在調(diào)用 scheduleNext();執(zhí)行下一個任務(wù)。直到所有任務(wù)被執(zhí)行完畢。而AsyncTask的構(gòu)造方法中有一個call()方法,而這個方法由于會被FutureTask的run方法執(zhí)行。所以最終這個call方法會在線程池中執(zhí)行。

而doInBackground這個方法就是在這里被調(diào)用的。我們好好研究一下這個call()方法。mTaskInvoked.set(true);表示當(dāng)前任務(wù)已經(jīng)執(zhí)行過了。接著執(zhí)行doInBackground方法,最后將結(jié)果通過postResult(result);方法進行傳遞。postResult()方法中通過sHandler來發(fā)送消息,sHandler的中通過消息的類型來判斷一個MESSAGE_POST_RESULT,這種情況就是調(diào)用onPostExecute(result)方法或者是onCancelled(result)。另一種消息類型是MESSAGE_POST_PROGRESS則調(diào)用更新進度onProgressUpdate。

2、Binder的工作機制

image.png

直觀來說,Binder是Android中的一個類,它實現(xiàn)了IBinder接口,從IPC的角度來說,Binder是Android中的一種跨進程通信的一種方式,同時還可以理解為是一種虛擬的物理設(shè)備,它的設(shè)備驅(qū)動是/dev/binder/。從Framework角度來說,Binder是ServiceManager的橋梁。從應(yīng)用層來說,Binder是客戶端和服務(wù)端進行通信的媒介。

我們先來了解一下這個類中每個方法的含義:

DESCRIPTOR:Binder的唯一標(biāo)識,一般用于當(dāng)前Binder的類名表示。

asInterface(android.os.IBinder obj):用于將服務(wù)端的Binder對象轉(zhuǎn)換成客戶端所需的AIDL接口類型的對象,這種轉(zhuǎn)化過程是區(qū)分進程的,如果客戶端和服務(wù)端位于同一個進程,那么這個方法返回的是服務(wù)端的stub對象本身,否則返回的是系統(tǒng)封裝后的Stub.proxy對象。

asBinder():用于返回當(dāng)前Binder對象。

onTransact:該方法運行在服務(wù)端的Binder線程池中,當(dāng)客戶端發(fā)起跨進程通信請求的時候,遠程請求通過系統(tǒng)底層封裝后交給該方法處理。注意這個方法public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags),服務(wù)端通過code可以確定客戶端所請求的目標(biāo)方法是什么,接著從data中取出目標(biāo)方法所需的參數(shù),然后執(zhí)行目標(biāo)方法。當(dāng)目標(biāo)方法執(zhí)行完畢后,就像reply中寫入返回值。這個方法的執(zhí)行過程就是這樣的。如果這個方法返回false,客戶端是會請求失敗的,所以我們可以在這個方法中做一些安全驗證。

Binder的工作機制但是要注意一些問題:

1、當(dāng)客戶端發(fā)起請求時,由于當(dāng)前線程會被掛起,直到服務(wù)端返回數(shù)據(jù),如果這個遠程方法很耗時的話,那么是不能夠在UI線程,也就是主線程中發(fā)起這個遠程請求的。

2、由于Service的Binder方法運行在線程池中,所以Binder方法不管是耗時還是不耗時都應(yīng)該采用同步的方式,因為它已經(jīng)運行在一個線程中了。

3、view的事件分發(fā)和view的工作原理

Android自定義view,我們都知道實現(xiàn)有三部曲,onMeasure(),onLayout(),onDraw()。View的繪制流程是從viewRoot的perfromTraversal方法開始的。它經(jīng)過measure,layout,draw方法才能夠?qū)iew繪制出來。其中measure是測量寬高的,layout是確定view在父容器上的擺布位置的,draw是將view繪制到屏幕上的。

Measure:

view的測量是需要MeasureSpc(測量規(guī)格),它代表一個32位int值,高2位代表SpecMode(測量模式),低(30)位的代表SpecSize(某種測量模式下的規(guī)格大小)。而一組SpecMode和SpeSize可以打包為一個MeasureSpec,反之,MeasureSpec可以解包得到SpecMode和SpeSize的值。SpecMode有三類:

unSpecified:父容器不對view有任何限制,要多大有多大。一般系統(tǒng)用這個多。

Exactly:父容器已經(jīng)檢測出view所需要的精確大小,這個時候,view的大小就是SpecSize所指定的值,它對應(yīng)者layout布局中的math_parent或者是具體的數(shù)值

At_most:父容器指定了一個可用大小的SpecSize,view的大小不能夠大于這個值,它對應(yīng)這布局中的wrao_content.

對于普通的view,它的MeasureSpec是由父容器的MeasureSpec和自身的layoutParam共同決定的,一旦MeasureSpec確定后,onMeasure就可以確定view的寬高了。

View的measure過程:

onMeasure方法中有個setMeasureDimenSion方法來設(shè)置view的寬高測量值,而setMeasureDimenSion有個getDefaultSize()方法作為參數(shù)。一般情況下,我們只需要關(guān)注at_most和exactly兩種情況,getDefaultSize的返回值就是measureSpec中的SpecSize,而這個值基本就是view測量后的大小。而UnSpecified這種情況,一般是系統(tǒng)內(nèi)部的測量過程,它是需要考慮view的背景這些因素的。

前面說的是view的測量過程,而viewGroup的measure過程:

對于viewGroup來說,除了完成自己的measure過程以外,還要遍歷去調(diào)用子類的measure方法,各個子元素在遞歸執(zhí)行這個過程,viewGroup是一個抽象的類,沒有提供有onMeasure方法,但是提供了一個measureChildren的方法。measureChild方法的思想就是取出子元素的layoutParams,然后通過getChildMeasureSpec來常見子元素的MeasureSpec,然后子元素在電泳measure方法進行測量。由于viewGroup子類有不同的布局方式,導(dǎo)致他們的測量細節(jié)不一樣,所以viewGroup不能象view一樣調(diào)用onMeasure方法進行測量。

注意:在activity的生命周期中是沒有辦法正確的獲取view的寬高的,原因就是view沒有測量完。

在onWindowFocuschanged方法中獲取 ----改方法含義是view已經(jīng)初始化完畢
View.post()方法,將潤那邊了投遞到消息隊列的尾部。
使用viewTreeObserver的回調(diào)來完成。
通過view.measure方式手動測量。

onLayout

普通的view的話,可以通過setFrame方法來的到view四個頂點的位置,也就確定了view在父容器的位置,接著就調(diào)用onLayout方法,該方法是父容器確定子元素的位置。

onDraw

該方法就是將view繪制到屏幕上。分以下幾步

  1. 繪制背景,

  2. 繪制自己,

  3. 繪制child,

  4. 繪制裝飾。

Android中性能優(yōu)化

由于手機硬件的限制,內(nèi)存和CPU都無法像pc一樣具有超大的內(nèi)存,Android手機上,過多的使用內(nèi)存,會容易導(dǎo)致oom,過多的使用CPU資源,會導(dǎo)致手機卡頓,甚至導(dǎo)致anr。我主要是從一下幾部分進行優(yōu)化:

布局優(yōu)化,繪制優(yōu)化,內(nèi)存泄漏優(yōu)化,響應(yīng)速度優(yōu)化,listview優(yōu)化,bitmap優(yōu)化,線程優(yōu)化

布局優(yōu)化:工具 hierarchyviewer,解決方式:

1、刪除無用的空間和層級。

2、選擇性能較低的viewgroup,如Relativelayout,如果可以選擇Relativelayout也可以使用LinearLayout,就優(yōu)先使用LinearLayout,因為相對來說Relativelayout功能較為復(fù)雜,會占用更多的CPU資源。

3、使用標(biāo)簽<include/>重用布局,<Merge/>減少層級,<viewStub/>進行預(yù)加載,使用的時候才加載。

繪制優(yōu)化

繪制優(yōu)化指view在ondraw方法中避免大量的耗時操作,由于ondraw方法可能會被頻繁的調(diào)用。

1、ondraw方法中不要創(chuàng)建新的局部變量,ondraw方法被頻繁的調(diào)用,很容易引起GC。

2、ondraw方法不要做耗時操作。

內(nèi)存優(yōu)化:參考內(nèi)存泄漏。

響應(yīng)優(yōu)化

主線程不能做耗時操作,觸摸事件5s,廣播10s,service20s。

listview優(yōu)化:

1、getview方法中避免耗時操作。

2、view的復(fù)用和viewholder的使用。

3、滑動不適合開啟異步加載。

4、分頁處理數(shù)據(jù)。

5、圖片使用三級緩存。

Bitmap優(yōu)化:

1、等比例壓縮圖片。

2、不用的圖片,及時recycler掉

線程優(yōu)化

線程優(yōu)化的思想是使用線程池來管理和復(fù)用線程,避免程序中有大量的Thread,同時可以控制線程的并發(fā)數(shù),避免相互搶占資源而導(dǎo)致線程阻塞。

其他優(yōu)化

1、少用枚舉,枚舉占用空間大。

2、使用Android特有的數(shù)據(jù)結(jié)構(gòu),如SparseArray來代替hashMap。

3、適當(dāng)?shù)氖褂密浺煤腿跻谩?/p>

java相關(guān)基礎(chǔ)知識

1、Http https區(qū)別

1、https協(xié)議需要到ca申請證書,一般免費證書較少,因而需要一定費用。

2、http是超文本傳輸協(xié)議,信息是明文傳輸,https則是具有安全性的ssl加密傳輸協(xié)議。

3、http和https使用的是完全不同的連接方式,用的端口也不一樣,前者是80,后者是443。

4、http的連接很簡單,是無狀態(tài)的;HTTPS協(xié)議是由SSL+HTTP協(xié)議構(gòu)建的可進行加密傳輸、身份認證的網(wǎng)絡(luò)協(xié)議,比http協(xié)議安全。

2、https實現(xiàn)原理

(1)客戶使用https的URL訪問Web服務(wù)器,要求與Web服務(wù)器建立SSL連接。

(2)Web服務(wù)器收到客戶端請求后,會將網(wǎng)站的證書信息(證書中包含公鑰)傳送一份給客戶端。

(3)客戶端的瀏覽器與Web服務(wù)器開始協(xié)商SSL連接的安全等級,也就是信息加密的等級。

(4)客戶端的瀏覽器根據(jù)雙方同意的安全等級,建立會話密鑰,然后利用網(wǎng)站的公鑰將會話密鑰加密,并傳送給網(wǎng)站。

(5)Web服務(wù)器利用自己的私鑰解密出會話密鑰。

(6)Web服務(wù)器利用會話密鑰加密與客戶端之間的通信。

3、Http位于TCP/IP模型中的第幾層?為什么說Http是可靠的數(shù)據(jù)傳輸協(xié)議?
tcp/ip的五層模型:
從下到上:物理層->數(shù)據(jù)鏈路層->網(wǎng)絡(luò)層->傳輸層->應(yīng)用層
其中tcp/ip位于模型中的網(wǎng)絡(luò)層,處于同一層的還有ICMP(網(wǎng)絡(luò)控制信息協(xié)議)。http位于模型中的應(yīng)用層
由于tcp/ip是面向連接的可靠協(xié)議,而http是在傳輸層基于tcp/ip協(xié)議的,所以說http是可靠的數(shù)據(jù)傳輸協(xié)議。

4、HTTP鏈接的特點

HTTP連接最顯著的特點是客戶端發(fā)送的每次請求都需要服務(wù)器回送響應(yīng),在請求結(jié)束后,會主動釋放連接。

從建立連接到關(guān)閉連接的過程稱為“一次連接”。

5、TCP和UDP的區(qū)別

tcp是面向連接的,由于tcp連接需要三次握手,所以能夠最低限度的降低風(fēng)險,保證連接的可靠性。

udp 不是面向連接的,udp建立連接前不需要與對象建立連接,無論是發(fā)送還是接收,都沒有發(fā)送確認信號。所以說udp是不可靠的。

由于udp不需要進行確認連接,使得UDP的開銷更小,傳輸速率更高,所以實時行更好。

6、Socket建立網(wǎng)絡(luò)連接的步驟

建立Socket連接至少需要一對套接字,其中一個運行與客戶端--ClientSocket,一個運行于服務(wù)端--ServiceSocket

1、服務(wù)器監(jiān)聽:服務(wù)器端套接字并不定位具體的客戶端套接字,而是處于等待連接的狀態(tài),實時監(jiān)控網(wǎng)絡(luò)狀態(tài),等待客戶端的連接請求。

2、客戶端請求:指客戶端的套接字提出連接請求,要連接的目標(biāo)是服務(wù)器端的套接字。注意:客戶端的套接字必須描述他要連接的服務(wù)器的套接字,
指出服務(wù)器套接字的地址和端口號,然后就像服務(wù)器端套接字提出連接請求。

3、連接確認:當(dāng)服務(wù)器端套接字監(jiān)聽到客戶端套接字的連接請求時,就響應(yīng)客戶端套接字的請求,建立一個新的線程,把服務(wù)器端套接字的描述
發(fā)給客戶端,一旦客戶端確認了此描述,雙方就正式建立連接。而服務(wù)端套接字則繼續(xù)處于監(jiān)聽狀態(tài),繼續(xù)接收其他客戶端套接字的連接請求。

7、加密算法(base64、MD5、對稱加密和非對稱加密)和使用場景。

什么是Rsa加密?

RSA算法是最流行的公鑰密碼算法,使用長度可以變化的密鑰。RSA是第一個既能用于數(shù)據(jù)加密也能用于數(shù)字簽名的算法。

RSA算法原理如下:

1.隨機選擇兩個大質(zhì)數(shù)p和q,p不等于q,計算N=pq;

2.選擇一個大于1小于N的自然數(shù)e,e必須與(p-1)(q-1)互素。

3.用公式計算出d:d×e = 1 (mod (p-1)(q-1)) 。

4.銷毀p和q。

最終得到的N和e就是“公鑰”,d就是“私鑰”,發(fā)送方使用N去加密數(shù)據(jù),接收方只有使用d才能解開數(shù)據(jù)內(nèi)容。

RSA的安全性依賴于大數(shù)分解,小于1024位的N已經(jīng)被證明是不安全的,而且由于RSA算法進行的都是大數(shù)計算,使得RSA最快的情況也比DES慢上倍,這是RSA最大的缺陷,因此通常只能用于加密少量數(shù)據(jù)或者加密密鑰,但RSA仍然不失為一種高強度的算法。

使用場景:項目中除了登陸,支付等接口采用rsa非對稱加密,之外的采用aes對稱加密,今天我們來認識一下aes加密。

什么是MD5加密?

MD5英文全稱“Message-Digest Algorithm 5”,翻譯過來是“消息摘要算法5”,由MD2、MD3、MD4演變過來的,是一種單向加密算法,是不可逆的一種的加密方式。

MD5加密有哪些特點?

壓縮性:任意長度的數(shù)據(jù),算出的MD5值長度都是固定的。

容易計算:從原數(shù)據(jù)計算出MD5值很容易。

抗修改性:對原數(shù)據(jù)進行任何改動,哪怕只修改1個字節(jié),所得到的MD5值都有很大區(qū)別。

強抗碰撞:已知原數(shù)據(jù)和其MD5值,想找到一個具有相同MD5值的數(shù)據(jù)(即偽造數(shù)據(jù))是非常困難的。

MD5應(yīng)用場景:

一致性驗證

數(shù)字簽名

安全訪問認證

什么是aes加密?

高級加密標(biāo)準(zhǔn)(英語:Advanced Encryption Standard,縮寫:AES),在密碼學(xué)中又稱Rijndael加密法,是美國聯(lián)邦政府采用的一種區(qū)塊加密標(biāo)準(zhǔn)。這個標(biāo)準(zhǔn)用來替代原先的DES,已經(jīng)被多方分析且廣為全世界所使用。

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

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

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