Android最新面試實(shí)戰(zhàn)總結(jié)

所謂,君子性非異也,善假于物也!~

那么,本文意在給大家提供快速、全面、高效的面試解決方案;

為大家節(jié)約尋找面試、筆試答案的時(shí)間;

讓閱讀本文或收藏本文的開發(fā)者成為Android面試場(chǎng)上的最強(qiáng)王者;

更是為開發(fā)者量身定制立志成為面試官的夢(mèng)魘而奮斗!

現(xiàn)筆者將自己親身實(shí)戰(zhàn)的面試題及收到的面試題總結(jié)并分享答案出來(lái)。歡迎各位Developer斧正和指點(diǎn),也希望看到本文的小伙伴積極提供面試題以供分享,內(nèi)容分為Java和Android兩大篇。

(介于篇幅較長(zhǎng),且長(zhǎng)期更新,希望各位開發(fā)者多多支持多多收藏和點(diǎn)贊)

JAVA:

volatitle關(guān)鍵字及其原理?

Volatile是輕量級(jí)的synchronized,它在多線程開發(fā)中保證了共享變量的“可見性”。可見性的意思是當(dāng)一個(gè)線程修改一個(gè)共享變量時(shí),另外一個(gè)線程能讀到這個(gè)修改的值。它在某些情況下比synchronized的開銷更小,如果一個(gè)字段被聲明成volatile,java線程內(nèi)存模型確保所有線程看到這個(gè)變量的值是一致的(比較常用的就是單例模式中,對(duì)字段的聲明,加上這個(gè)關(guān)鍵字)。

Volatile原理:

處理器為了提高處理速度,不直接和內(nèi)存進(jìn)行通訊,而是先將系統(tǒng)內(nèi)存的數(shù)據(jù)讀到內(nèi)部緩存(L1,L2或其他)后再進(jìn)行操作,但操作完之后不知道何時(shí)會(huì)寫到內(nèi)存,如果對(duì)聲明了Volatile變量進(jìn)行寫操作,JVM就會(huì)向處理器發(fā)送一條Lock前綴的指令,將這個(gè)變量所在緩存行的數(shù)據(jù)寫回到系統(tǒng)內(nèi)存。但是就算寫回到內(nèi)存,如果其他處理器緩存的值還是舊的,再執(zhí)行計(jì)算操作就會(huì)有問題,所以在多處理器下,為了保證各個(gè)處理器的緩存是一致的,就會(huì)實(shí)現(xiàn)緩存一致性協(xié)議,每個(gè)處理器通過(guò)嗅探在總線上傳播的數(shù)據(jù)來(lái)檢查自己緩存的值是不是過(guò)期了,當(dāng)處理器發(fā)現(xiàn)自己緩存行對(duì)應(yīng)的內(nèi)存地址被修改,就會(huì)將當(dāng)前處理器的緩存行設(shè)置成無(wú)效狀態(tài),當(dāng)處理器要對(duì)這個(gè)數(shù)據(jù)進(jìn)行修改操作的時(shí)候,會(huì)強(qiáng)制重新從系統(tǒng)內(nèi)存里把數(shù)據(jù)讀到處理器緩存里。

原理總結(jié) (重點(diǎn)):先將當(dāng)前處理器緩存行的數(shù)據(jù)會(huì)寫回到系統(tǒng)內(nèi)存\,其次,這個(gè)寫回內(nèi)存的操作會(huì)引起在其他CPU里緩存了該內(nèi)存地址的數(shù)據(jù)無(wú)效。最后,當(dāng)處理器要對(duì)這個(gè)數(shù)據(jù)進(jìn)行修改操作的時(shí)候,會(huì)強(qiáng)制重新從系統(tǒng)內(nèi)存里把數(shù)據(jù)讀到處理器緩存里。如此循環(huán)反復(fù)保證共享變量的值是一致的

synchronize的理解及原理

A: 每個(gè)對(duì)象有一個(gè)監(jiān)視器鎖(monitor)。當(dāng)monitor被占用時(shí)就會(huì)處于鎖定狀態(tài),線程執(zhí)行monitorenter指令時(shí)嘗試獲取monitor的所有權(quán),過(guò)程如下:

1、如果monitor的進(jìn)入數(shù)為0,則該線程進(jìn)入monitor,然后將進(jìn)入數(shù)設(shè)置為1,該線程即為monitor的所有者。

2、如果線程已經(jīng)占有該monitor,只是重新進(jìn)入,則進(jìn)入monitor的進(jìn)入數(shù)加1.

3.如果其他線程已經(jīng)占用了monitor,則該線程進(jìn)入阻塞狀態(tài),直到monitor的進(jìn)入數(shù)為0,再重新嘗試獲取monitor的所有權(quán)。

B:執(zhí)行monitorexit的線程必須是objectref所對(duì)應(yīng)的monitor的所有者。

指令執(zhí)行時(shí),monitor的進(jìn)入數(shù)減1,如果減1后進(jìn)入數(shù)為0,那線程退出monitor,不再是這個(gè)monitor的所有者。其他被這個(gè)monitor阻塞的線程可以嘗試去獲取這個(gè) monitor 的所有權(quán)。

可能你看暈了,沒事,附上鏈接:synchronize原理探索

簡(jiǎn)述多態(tài)?

? ? ? 多態(tài)就是指程序中定義的引用變量所指向的具體類型和通過(guò)該引用變量發(fā)出的方法調(diào)用在編程時(shí)并不確定,而是在程序運(yùn)行期間才確定,即一個(gè)引用變量倒底會(huì)指向哪個(gè)類的實(shí)例對(duì)象,該引用變量發(fā)出的方法調(diào)用到底是哪個(gè)類中實(shí)現(xiàn)的方法,必須在由程序運(yùn)行期間才能決定。簡(jiǎn)稱:父類引用指向子類對(duì)象

? ? 由多態(tài)引申的概念:向上轉(zhuǎn)型?

? ? 它只能訪問父類中擁有的方法和屬性,而對(duì)于子類中存在而父類中不存在的方法,該引用是不能使用的,盡管是重載該方法。若子類重寫了父類中的某些方法,在調(diào)用該些方法的時(shí)候,必定是使用子類中定義的這些方法(動(dòng)態(tài)連接、動(dòng)態(tài)調(diào)用)。

? ? Java實(shí)現(xiàn)多態(tài)有三個(gè)必要條件:繼承、重寫、向上轉(zhuǎn)型。

? ? 更詳細(xì)的說(shuō)明和補(bǔ)充可以點(diǎn)擊這里了解多態(tài)

對(duì)Java的理解?

? ? ?可以從面向?qū)ο蟆?a target="_blank">分布式、健壯性安全性、平臺(tái)獨(dú)立與可移植性、多線程、動(dòng)態(tài)性等特點(diǎn)。Java可以編寫桌面應(yīng)用程序、Web應(yīng)用程序、分布式系統(tǒng)嵌入式系統(tǒng)應(yīng)用程序,Android開發(fā)等等回答.

抽象類與接口的聯(lián)系與區(qū)別?

相同點(diǎn):

都不能直接實(shí)例化,

接口的實(shí)現(xiàn)類或抽象類的子類都只有實(shí)現(xiàn)了接口或抽象類中的方法后才能被實(shí)例化

區(qū)別:

1、抽象類變量必須指向?qū)崿F(xiàn)所有抽象方法的子類對(duì)象,接口變量必須指向?qū)崿F(xiàn)所有接口方法的類對(duì)象。

2、抽象類要被子類繼承,接口要被類實(shí)現(xiàn)。

3、接口只能做方法申明,抽象類中可以做方法申明,也可以做方法實(shí)現(xiàn)

4、接口里定義的變量只能是公共的靜態(tài)的常量,抽象類中的變量是普通變量。

5、抽象類里的抽象方法必須全部被子類所實(shí)現(xiàn),如果子類不能全部實(shí)現(xiàn)父類抽象方法,那么該子類只能是抽象類。同樣,一個(gè)實(shí)現(xiàn)接口的時(shí)候,如不能全部實(shí)現(xiàn)接口方法,那么該類也只能為抽象類。

6、抽象方法只能申明,不能實(shí)現(xiàn)。abstract void abc();不能寫成abstract void abc(){}。

7、抽象類里可以沒有抽象方法

8、如果一個(gè)類里有抽象方法,那么這個(gè)類只能是抽象類

9、抽象方法要被實(shí)現(xiàn),所以不能是靜態(tài)的,也不能是私有的。

10、接口可繼承接口,并可多繼承接口,但類只能單根繼承。

綜述 : 特別是對(duì)于公用的實(shí)現(xiàn)代碼,抽象類有它的優(yōu)點(diǎn)。抽象類能夠保證實(shí)現(xiàn)的層次關(guān)系,避免代碼重復(fù)。然而,即使在使用抽 象類的場(chǎng)合,也不要忽視通過(guò)接口定義行為模型的原則。從實(shí)踐的角度來(lái)看,如果依賴于抽象類來(lái)定義行為,往往導(dǎo)致過(guò)于復(fù)雜的繼承關(guān)系,而通過(guò)接口定義行為能 夠更有效地分離行為與實(shí)現(xiàn),為代碼的維護(hù)和修改帶來(lái)方便。

float f=2.3;是否正確?

不正確。2.3是雙精度數(shù),將雙精度型(double)賦值給浮點(diǎn)型(float)屬于下轉(zhuǎn)型(down-casting,也稱為窄化)會(huì)造成精度損失,因此需要強(qiáng)制類型轉(zhuǎn)換float f =(float)2.3; 或者寫成float f =2.3F;。

short s1 = 1; s1 = s1 + 1;有錯(cuò)嗎?short s1 = 1; s1 += 1;有錯(cuò)嗎?

對(duì)于short s1 = 1; s1 = s1 + 1;由于1是int類型,因此s1+1運(yùn)算結(jié)果也是int 型,需要強(qiáng)制轉(zhuǎn)換類型才能賦值給short型。而short s1 = 1; s1 += 1;可以正確編譯,因?yàn)閟1+= 1;相當(dāng)于s1 = (short)(s1 + 1);其中有隱含的強(qiáng)制類型轉(zhuǎn)換。

當(dāng)一個(gè)對(duì)象被當(dāng)作參數(shù)傳遞到一個(gè)方法后,此方法可改變這個(gè)對(duì)象的屬性,并可返回變化后的結(jié)果,那么這里到底是值傳遞還是引用傳遞?

值傳遞。Java語(yǔ)言的方法調(diào)用只支持參數(shù)的值傳遞。當(dāng)一個(gè)對(duì)象實(shí)例作為一個(gè)參數(shù)被傳遞到方法中時(shí),參數(shù)的值就是對(duì)該對(duì)象的引用。對(duì)象的屬性可以在被調(diào)用過(guò)程中被改變,但對(duì)對(duì)象引用的改變是不會(huì)影響到調(diào)用者的。

如何保證線程安全?

簡(jiǎn)單來(lái)說(shuō),線程安全就是:在多線程環(huán)境中,能永遠(yuǎn)保證程序的正確性。因此,只有存在共享數(shù)據(jù)時(shí)才需要考慮線程安全問題。

解決方案1:Java多線程支持引入同步監(jiān)視器來(lái)解決這個(gè)問題,使用同步監(jiān)視器的通用方法就是同步代碼塊,使用synchronize(obj)代碼塊,(目的:任何時(shí)刻只能有一個(gè)線程可以獲得對(duì)同步監(jiān)視器的鎖定,當(dāng)同步代碼塊執(zhí)行完成后,該線程會(huì)釋放對(duì)該同步監(jiān)視器的鎖定) 推薦使用可能被并發(fā)訪問的共享資源充當(dāng)同步監(jiān)視器,邏輯大概就是 ? 加鎖-->修改-->釋放鎖?

解決方案2:通過(guò)顯示定義同步鎖對(duì)象實(shí)現(xiàn)同步,在這種機(jī)制下,同步鎖用Lock對(duì)象充當(dāng),Lock允許實(shí)現(xiàn)更靈活的結(jié)構(gòu),有差別很大的屬性,使用Lock對(duì)象來(lái)進(jìn)行同步,加鎖和釋放鎖出現(xiàn)在不同的作用范圍內(nèi),通常建議使用finally塊來(lái)確保在必要時(shí)候釋放鎖

簡(jiǎn)述Java中為什么會(huì)出現(xiàn)死鎖?

當(dāng)兩個(gè)線程相互等待對(duì)方釋放同步監(jiān)視器時(shí)就會(huì)發(fā)生死鎖,Java虛擬機(jī)沒有監(jiān)測(cè)也沒有采取措施來(lái)處理死鎖情況,所以多線程編程時(shí)應(yīng)該采取措施避免死鎖出現(xiàn).一旦出現(xiàn)死鎖,整個(gè)程序既不會(huì)發(fā)生任何異常,也不會(huì)給出任何提示,只是所有線程處于阻塞狀態(tài),無(wú)法繼續(xù).

簡(jiǎn)述Java中的四種引用?

1) 強(qiáng)引用(StrongReference)

強(qiáng)引用是使用最普遍的引用。比如new 對(duì)象等等,如果一個(gè)對(duì)象具有強(qiáng)引用,那垃圾回收器絕不會(huì)回收它。當(dāng)內(nèi)存空間不足,Java虛擬機(jī)寧愿拋出OutOfMemoryError錯(cuò)誤,使程序異常終止,也不會(huì)靠隨意回收具有強(qiáng)引用的對(duì)象來(lái)解決內(nèi)存不足的問題。

2) 軟引用(SoftReference)

如果一個(gè)對(duì)象只具有軟引用,則內(nèi)存空間足夠,垃圾回收器就不會(huì)回收它;如果內(nèi)存空間不足了,就會(huì)回收這些對(duì)象的內(nèi)存。軟引用可用來(lái)實(shí)現(xiàn)內(nèi)存敏感的高速緩存。

3) 弱引用(WeakReference)

在java中,用java.lang.ref.WeakReference類來(lái)表示弱引用. ?與軟引用的區(qū)別在于:弱引用的對(duì)象擁有更短暫的生命周期。在垃圾回收器線程掃描它所管轄的內(nèi)存區(qū)域的過(guò)程中,一旦發(fā)現(xiàn)了只具有弱引用的對(duì)象,不管當(dāng)前內(nèi)存空間足夠與否,都會(huì)回收它的內(nèi)存。不過(guò),由于垃圾回收器是一個(gè)優(yōu)先級(jí)很低的線程,因此不一定會(huì)很快發(fā)現(xiàn)那些只具有弱引用的對(duì)象。

4)虛引用(PhantomReference)

“虛引用”顧名思義,就是形同虛設(shè),與其他幾種引用都不同,虛引用并不會(huì)決定對(duì)象的生命周期。在java中用java.lang.ref.PhantomReference類表示。

強(qiáng)引用置為null,會(huì)不會(huì)被回收?

只要是強(qiáng)引用就證明這個(gè)內(nèi)存是在的,但是置為null,因此回收器在適當(dāng)?shù)臅r(shí)候回收,什么是適當(dāng)時(shí)候,大體是使用內(nèi)存占申請(qǐng)內(nèi)存75%的時(shí)候,就啟動(dòng)回收線程。(關(guān)于申請(qǐng)內(nèi)存75% 這個(gè)結(jié)論,筆者是查了一些資料)

如何保證多線程讀寫文件的安全?

加鎖,可以參考上面的線程安全

單例模式的常見寫法和優(yōu)缺點(diǎn)分析?

懶漢式:

第一次獲取單例類的實(shí)例時(shí)創(chuàng)建。(優(yōu)點(diǎn):寫法簡(jiǎn)單,且不存在多線程同步問題,避免了synchronized所造成的性能問題;缺點(diǎn)是:初始化類的時(shí)候就需要構(gòu)造實(shí)例,(即便你還沒有用到這個(gè)實(shí)例),因此在某些特定條件下會(huì)耗費(fèi)內(nèi)存。)

餓漢式:

在類被加載的時(shí)候創(chuàng)建單例類的對(duì)象,類加載器負(fù)責(zé)加載類,并會(huì)保證只有一個(gè)線程在實(shí)例化單例類, (優(yōu)點(diǎn):這種寫法比較簡(jiǎn)單,就是在類裝載的時(shí)候就完成實(shí)例化。避免了線程同步問題。缺點(diǎn):在類裝載的時(shí)候就完成實(shí)例化,沒有達(dá)到Lazy Loading的效果。如果從始至終從未使用過(guò)這個(gè)實(shí)例,則會(huì)造成內(nèi)存的浪費(fèi)。)

單例模式個(gè)人覺得最經(jīng)典在項(xiàng)目里經(jīng)常使用的寫法(也稱雙重鎖機(jī)制):


雙重校驗(yàn)鎖

更多細(xì)節(jié)可以參考單例模式的8種寫法

單例模式的拓展?

1:使用靜態(tài)內(nèi)部類 實(shí)現(xiàn)單例模式


靜態(tài)內(nèi)部類單例模式

第一次加載Singleton類時(shí)并不會(huì)初始化sInstance,只有第一次調(diào)用getInstance方法時(shí)虛擬機(jī)加載SingletonHolder 并初始化sInstance ,這樣不僅能確保線程安全也能保證Singleton類的唯一性,在《java并發(fā)編程實(shí)踐》一書中推薦使用靜態(tài)內(nèi)部類單例模式。當(dāng)然,可以根據(jù)個(gè)人偏好去使用

2:使用容器 實(shí)現(xiàn)單例模式


容器單例模式

用SingletonManager 將多種的單例類統(tǒng)一管理,在使用時(shí)根據(jù)key獲取對(duì)象對(duì)應(yīng)類型的對(duì)象,代碼可讀性強(qiáng)。這種方式使得我們可以管理多種類型的單例,并且在使用時(shí)可以通過(guò)統(tǒng)一的接口進(jìn)行獲取操作,降低了用戶的使用成本,也對(duì)用戶隱藏了具體實(shí)現(xiàn),降低了耦合度。

StringBuffer和StringBuilder的區(qū)別?

StringBuilder:線程非安全的,但是效率高

StringBuffer:線程安全的,效率相對(duì)較低

.單線程操作字符串緩沖區(qū)下操作大量數(shù)據(jù)推薦使用:StringBuilder

?多線程操作字符串緩沖區(qū)下操作大量數(shù)據(jù)推薦使用:StringBuffer

數(shù)組和鏈表的區(qū)別?

答:二者都屬于一種數(shù)據(jù)結(jié)構(gòu)

從邏輯結(jié)構(gòu)來(lái)看

1. 數(shù)組必須事先定義固定的長(zhǎng)度(元素個(gè)數(shù)),不能適應(yīng)數(shù)據(jù)動(dòng)態(tài)地增減的情況。當(dāng)數(shù)據(jù)增加時(shí),可能超出原先定義的元素個(gè)數(shù);當(dāng)數(shù)據(jù)減少時(shí),造成內(nèi)存浪費(fèi);數(shù)組可以根據(jù)下標(biāo)直接存取。

2. 鏈表動(dòng)態(tài)地進(jìn)行存儲(chǔ)分配,可以適應(yīng)數(shù)據(jù)動(dòng)態(tài)地增減的情況,且可以方便地插入、刪除數(shù)據(jù)項(xiàng)。(數(shù)組中插入、刪除數(shù)據(jù)項(xiàng)時(shí),需要移動(dòng)其它數(shù)據(jù)項(xiàng),非常繁瑣)鏈表必須根據(jù)next指針找到下一個(gè)元素

從內(nèi)存存儲(chǔ)來(lái)看

1. (靜態(tài))數(shù)組從棧中分配空間, 對(duì)于程序員方便快速,但是自由度小

2. 鏈表從堆中分配空間, 自由度大但是申請(qǐng)管理比較麻煩

從上面的比較可以看出,如果需要快速訪問數(shù)據(jù),很少或不插入和刪除元素,就應(yīng)該用數(shù)組;相反, 如果需要經(jīng)常插入和刪除元素就需要用鏈表數(shù)據(jù)結(jié)構(gòu)了。

HashMap? TreeMap LinkedHashMap

HashMap中的元素是沒有順序的 基于hash表實(shí)現(xiàn) ;使用HashMap定義了hashcode() 和equals()方法

TreeMap中所有的元素有某一固定順序 基于紅黑樹實(shí)現(xiàn) 要改變其排序可以自己寫一個(gè)Comparator(比較器)

HashMap TreeMap都不是線程安全的

LinkedHashMap有序,繼承HashMap LinkedHashMap也是線程不安全的

HashMap 內(nèi)部的 Node 數(shù)組默認(rèn)的大小是16 ,loadFactor 為0.75;當(dāng) HashMap 中的元素超過(guò)16\0.75=12時(shí),會(huì)把數(shù)組大小擴(kuò)展為2*16=32

HashMap為什么不安全?

1:多個(gè)線程同時(shí)使用put方法添加元素,這兩個(gè) key 會(huì)添加到數(shù)組的同一個(gè)位置,

這樣最終就會(huì)發(fā)生其中一個(gè)線程的 put 的數(shù)據(jù)被覆蓋

2:HashMap 在并發(fā)執(zhí)行 put 操作時(shí)會(huì)引起死循環(huán),導(dǎo)致 CPU 利用率接近100%。

ConcurrentHashMap、Hashtable 是線程安全的

線程和進(jìn)程的區(qū)別?

進(jìn)程有獨(dú)立的地址空間,一個(gè)進(jìn)程崩潰后,在保護(hù)模式下不會(huì)對(duì)其它進(jìn)程產(chǎn)生影響,

而線程只是一個(gè)進(jìn)程中的不同執(zhí)行路徑。線程有自己的堆棧和局部變量,但線程之間沒有單獨(dú)的地址空間,一個(gè)線程死掉就等于整個(gè)進(jìn)程死掉,所以多進(jìn)程的程序要比多線程的程序健壯,但在進(jìn)程切換時(shí),耗費(fèi)資源較大,效率要差一些。但對(duì)于一些要求同時(shí)進(jìn)行并且又要共享某些變量的并發(fā)操作,只能用線程,不能用進(jìn)程。

1) 簡(jiǎn)而言之,一個(gè)程序至少有一個(gè)進(jìn)程,一個(gè)進(jìn)程至少有一個(gè)線程.

2) 線程的劃分尺度小于進(jìn)程,使得多線程程序的并發(fā)性高。

3) 另外,進(jìn)程在執(zhí)行過(guò)程中擁有獨(dú)立的內(nèi)存單元,而多個(gè)線程共享內(nèi)存,從而極大地提高了程序的運(yùn)行效率。

4) 線程在執(zhí)行過(guò)程中與進(jìn)程還是有區(qū)別的。每個(gè)獨(dú)立的線程有一個(gè)程序運(yùn)行的入口、順序執(zhí)行序列和程序的出口。但是線程不能夠獨(dú)立執(zhí)行,必須依存在應(yīng)用程序中,由應(yīng)用程序提供多個(gè)線程執(zhí)行控制。

5) 從邏輯角度來(lái)看,多線程的意義在于一個(gè)應(yīng)用程序中,有多個(gè)執(zhí)行部分可以同時(shí)執(zhí)行。但操作系統(tǒng)并沒有將多個(gè)線程看做多個(gè)獨(dú)立的應(yīng)用,來(lái)實(shí)現(xiàn)進(jìn)程的調(diào)度和管理以及資源分配。這就是進(jìn)程和線程的重要區(qū)別。

線程池的概念以及應(yīng)用場(chǎng)景?

多線程編程下如果并發(fā)的線程數(shù)量很多,并且每個(gè)線程都是執(zhí)行一個(gè)時(shí)間很短的任務(wù)就結(jié)束了,這樣頻繁創(chuàng)建線程就會(huì)大大降低系統(tǒng)的效率,因?yàn)轭l繁創(chuàng)建線程和銷毀線程需要時(shí)間。那么有沒有一種辦法使得線程可以復(fù)用,就是執(zhí)行完一個(gè)任務(wù),并不被銷毀,而是可以繼續(xù)執(zhí)行其他的任務(wù),線程池技術(shù)的出現(xiàn)就很好的解決了上面問題,可以更好的提供性能,并有效控制系統(tǒng)中并發(fā)線程的數(shù)量(線程池的最大線程數(shù)參數(shù)可以控制系統(tǒng)中并發(fā)線程數(shù)不超過(guò)此數(shù))

關(guān)鍵字:ThreadPoolExecutor

Session 、Cookie?、Token相關(guān)?

Cookie:? 它是保存在本地終端的數(shù)據(jù)。cookie由服務(wù)器生成,發(fā)送給瀏覽器,瀏覽器把cookie以key - Value 形式保存到某個(gè)目錄下的文本文件內(nèi),下一次請(qǐng)求同一網(wǎng)站時(shí)會(huì)把該cookie發(fā)送給服務(wù)器。由于cookie是存在客戶端上的,所以瀏覽器加入了一些限制確保cookie不會(huì)被惡意使用,同時(shí)不會(huì)占據(jù)太多磁盤空間,所以每個(gè)域的cookie數(shù)量是有限的.(Cookie的作用是為了解決HTTP協(xié)議無(wú)狀態(tài)的缺陷所作的努力)

cookie的內(nèi)容主要包括:名字、值、過(guò)期時(shí)間、路徑和域。

路徑與域一起構(gòu)成cookie的作用范圍。

若不設(shè)置過(guò)期時(shí)間,則表示這個(gè)cookie的生命期為瀏覽器會(huì)話期間,關(guān)閉瀏覽器窗口,cookie就消失。這種生命期為瀏覽器會(huì)話期的cookie被稱為會(huì)話cookie.會(huì)話cookie一般不存儲(chǔ)在硬盤上而是保存在內(nèi)存里,當(dāng)然這種行為 并不是規(guī)范規(guī)定的。

若設(shè)置了過(guò)期時(shí)間,瀏覽器就會(huì)把cookie保存在硬盤上,關(guān)閉后再次打開瀏覽器,這些cookie仍然有效直到超過(guò)設(shè)定的過(guò)期時(shí)間。存儲(chǔ)在硬盤上的cookie可以在不同的瀏覽器進(jìn)程間共享,比如兩個(gè)IE窗口。而對(duì)于保存在內(nèi)存里cookie,不同的瀏覽器有不同的處理方式。


Session :? session的中文翻譯是“會(huì)話”,當(dāng)用戶打開某個(gè)web應(yīng)用時(shí),便與web服務(wù)器產(chǎn)生一次session。

簡(jiǎn)單的理解就是 : 服務(wù)器要知道當(dāng)前發(fā)請(qǐng)求給自己的是誰(shuí)。為了做這種區(qū)分,服務(wù)器就要給每個(gè)客戶端分配不同的“身份標(biāo)識(shí)”,然后客戶端每次向服務(wù)器發(fā)請(qǐng)求的時(shí)候,都帶上這個(gè)“身份標(biāo)識(shí)”,服務(wù)器就知道這個(gè)請(qǐng)求來(lái)自于誰(shuí)了。

?服務(wù)器使用session把用戶的信息臨時(shí)保存在了服務(wù)器上,用戶離開網(wǎng)站后session會(huì)被銷毀。這種用戶信息存儲(chǔ)方式相對(duì)Cookie來(lái)說(shuō)更安全 . 但是session有一個(gè)缺陷:如果web服務(wù)器做了負(fù)載均衡,那么下一個(gè)操作請(qǐng)求到了另一臺(tái)服務(wù)器的時(shí)候session會(huì)丟失。


Token: (英譯漢 : 象征; 記號(hào); 代幣;)

token是用戶身份的驗(yàn)證方式,最簡(jiǎn)單的token組成:uid(用戶唯一的身份標(biāo)識(shí))、time(當(dāng)前時(shí)間的時(shí)間戳)、sign(簽名,由token的前幾位+鹽以哈希算法壓縮成一定長(zhǎng)的十六進(jìn)制字符串,可以防止惡意第三方拼接token請(qǐng)求服務(wù)器)。還可以把不變的參數(shù)也放進(jìn)token,避免多次查庫(kù)

Cookie和Session的區(qū)別

1、cookie數(shù)據(jù)存放在客戶的瀏覽器上,session數(shù)據(jù)放在服務(wù)器上。

2、cookie不是很安全,別人可以分析存放在本地的cookie并進(jìn)行cookie欺騙,考慮到安全應(yīng)當(dāng)使用session。

3、session會(huì)在一定時(shí)間內(nèi)保存在服務(wù)器上。當(dāng)訪問增多,會(huì)比較占用你服務(wù)器的性能,考慮到減輕服務(wù)器性能方面,應(yīng)當(dāng)使用cookie。

4、單個(gè)cookie保存的數(shù)據(jù)不能超過(guò)4K,很多瀏覽器都限制一個(gè)站點(diǎn)最多保存20個(gè)cookie。

5、所以個(gè)人建議:

將登陸信息等重要信息存放為session

其他信息如果需要保留,可以放在cookie中

Token 和 Session 的區(qū)別

session和 token并不矛盾,作為身份認(rèn)證token安全性比session好,因?yàn)槊總€(gè)請(qǐng)求都有簽名還能防止監(jiān)聽以及重放攻擊,而session就必須靠鏈路層來(lái)保障通訊安全了。如上所說(shuō),如果你需要實(shí)現(xiàn)有狀態(tài)的會(huì)話,仍然可以增加session來(lái)在服務(wù)器端保存一些狀態(tài)

App通常用restful api跟server打交道。Rest是stateless的,也就是app不需要像browser那樣用cookie來(lái)保存session,因此用session token來(lái)標(biāo)示自己就夠了,session/state由api server的邏輯處理。如果你的后端不是stateless的rest api,那么你可能需要在app里保存session.可以在app里嵌入webkit,用一個(gè)隱藏的browser來(lái)管理cookie session.

Session是一種HTTP存儲(chǔ)機(jī)制,目的是為無(wú)狀態(tài)的HTTP提供的持久機(jī)制。所謂Session認(rèn)證只是簡(jiǎn)單的把User信息存儲(chǔ)到Session里,因?yàn)镾ID的不可預(yù)測(cè)性,暫且認(rèn)為是安全的。這是一種認(rèn)證手段。而Token,如果指的是OAuth Token或類似的機(jī)制的話,提供的是 認(rèn)證 和 授權(quán) ,認(rèn)證是針對(duì)用戶,授權(quán)是針對(duì)App。其目的是讓 某App有權(quán)利訪問 某用戶 的信息。這里的Token是唯一的。不可以轉(zhuǎn)移到其它App上,也不可以轉(zhuǎn)到其它 用戶 上。轉(zhuǎn)過(guò)來(lái)說(shuō)Session。Session只提供一種簡(jiǎn)單的認(rèn)證,即有此SID,即認(rèn)為有此User的全部權(quán)利。是需要嚴(yán)格保密的,這個(gè)數(shù)據(jù)應(yīng)該只保存在站方,不應(yīng)該共享給其它網(wǎng)站或者第三方App。所以簡(jiǎn)單來(lái)說(shuō),如果你的用戶數(shù)據(jù)可能需要和第三方共享,或者允許第三方調(diào)用API接口,用Token。如果永遠(yuǎn)只是自己的網(wǎng)站,自己的App,用什么就無(wú)所謂了。

token就是令牌,比如你授權(quán)(登錄)一個(gè)程序時(shí),他就是個(gè)依據(jù),判斷你是否已經(jīng)授權(quán)該軟件;cookie就是寫在客戶端的一個(gè)txt文件,里面包括你登錄信息之類的,這樣你下次在登錄某個(gè)網(wǎng)站,就會(huì)自動(dòng)調(diào)用cookie自動(dòng)登錄用戶名;session和cookie差不多,只是session是寫在服務(wù)器端的文件,也需要在客戶端寫入cookie文件,但是文件里是你的瀏覽器編號(hào).Session的狀態(tài)是存儲(chǔ)在服務(wù)器端,客戶端只有session id;而Token的狀態(tài)是存儲(chǔ)在客戶端。

Http,Https相關(guān)?

Http:?(HTTP-Hypertext transfer protocol)又稱:超文本傳輸協(xié)議 , 是一種詳細(xì)規(guī)定了瀏覽器和萬(wàn)維網(wǎng)服務(wù)器之間互相通信的規(guī)則,通過(guò)因特網(wǎng)傳送萬(wàn)維網(wǎng)文檔的數(shù)據(jù)傳送協(xié)議。

Https:(全稱:Hypertext Transfer Protocol over Secure Socket Layer),是以安全為目標(biāo)的HTTP通道,簡(jiǎn)單講是HTTP的安全版。即HTTP下加入SSL層,HTTPS的安全基礎(chǔ)是SSL,因此加密的詳細(xì)內(nèi)容就需要SSL。Https情況下,電腦與服務(wù)器之間收發(fā)的信息傳輸將更加安全。


HTTP協(xié)議的主要特點(diǎn)可概括如下:

1.支持客戶/服務(wù)器模式。

2.簡(jiǎn)單快速:客戶向服務(wù)器請(qǐng)求服務(wù)時(shí),只需傳送請(qǐng)求方法和路徑。請(qǐng)求方法常用的有GET、HEAD、POST。每種方法規(guī)定了客戶與服務(wù)器聯(lián)系的類型不同。由于HTTP協(xié)議簡(jiǎn)單,使得HTTP服務(wù)器的程序規(guī)模小,因而通信速度很快。

3.靈活:HTTP允許傳輸任意類型的數(shù)據(jù)對(duì)象。正在傳輸?shù)念愋陀蒀ontent-Type加以標(biāo)記。

4.無(wú)連接:無(wú)連接的含義是限制每次連接只處理一個(gè)請(qǐng)求。服務(wù)器處理完客戶的請(qǐng)求,并收到客戶的應(yīng)答后,即斷開連接。采用這種方式可以節(jié)省傳輸時(shí)間。

5.無(wú)狀態(tài):HTTP協(xié)議是無(wú)狀態(tài)協(xié)議。無(wú)狀態(tài)是指協(xié)議對(duì)于事務(wù)處理沒有記憶能力。缺少狀態(tài)意味著如果后續(xù)處理需要前面的信息,則它必須重傳,這樣可能導(dǎo)致每次連接傳送的數(shù)據(jù)量增大。另一方面,在服務(wù)器不需要先前信息時(shí)它的應(yīng)答就較快。

加密相關(guān):

對(duì)稱加密:

采用單鑰密碼系統(tǒng)的加密方法,同一個(gè)密鑰可以同時(shí)用作信息的加密和解密(注意:是同一個(gè)密鑰),這種加密方法稱為對(duì)稱加密,也稱為單密鑰加密所謂對(duì)稱,就是采用這種加密方法的雙方使用方式用同樣的密鑰進(jìn)行加密和解密。密鑰是控制加密及解密過(guò)程的指令。算法是一組規(guī)則,規(guī)定如何進(jìn)行加密和解密。因此,加密的安全性不僅取決于加密算法本身,密鑰管理的安全性更是重要。因?yàn)榧用芎徒饷芏际褂猛粋€(gè)密鑰,如何把密鑰安全地傳遞到解密者手上就成了必須要解決的問題。在對(duì)稱加密中,數(shù)據(jù)發(fā)送方將明文(原始數(shù)據(jù))和加密密鑰一起經(jīng)過(guò)特殊加密算法處理后,使其變成復(fù)雜的加密密文發(fā)送出去。接收方收到密文后,若想解讀原文,則需要使用加密密鑰及相同算法的逆算法對(duì)密文進(jìn)行解密,才能使其恢復(fù)成可讀明文。在對(duì)稱加密算法中,使用的密鑰只有一個(gè),發(fā)收信雙方都使用這個(gè)密鑰對(duì)數(shù)據(jù)進(jìn)行加密和解密。

對(duì)稱加密算法的優(yōu)點(diǎn) ? ?: ? ?算法公開、計(jì)算量小、加密速度快、加密效率高。

對(duì)稱加密算法的缺點(diǎn) ? ?: ? ?在數(shù)據(jù)傳送前,發(fā)送方和接收方必須商定好秘鑰,然后使雙方都能保存好秘鑰。其次如果一方的秘鑰被泄露,那么加密信息也就不安全了。另外,每對(duì)用戶每次使用對(duì)稱加密算法時(shí),都需要使用其他人不知道的唯一秘鑰,這會(huì)使得收、發(fā)雙方所擁有的鑰匙數(shù)量巨大,密鑰管理成為雙方的負(fù)擔(dān)。

對(duì)稱加密算法中常用的算法有:DES、3DES、TDEA、Blowfish、RC2、RC4、RC5、IDEA、SKIPJACK、AES等

非對(duì)稱加密:

對(duì)稱加密算法在加密和解密時(shí)使用的是同一個(gè)秘鑰;

非對(duì)稱加密算法需要兩個(gè)密鑰來(lái)進(jìn)行加密和解密。

這兩個(gè)秘鑰是公開密鑰(public key,簡(jiǎn)稱公鑰)和私有密鑰(private key,簡(jiǎn)稱私鑰)。

公開密鑰與私有密鑰是一對(duì),如果用公開密鑰對(duì)數(shù)據(jù)進(jìn)行加密,只有用對(duì)應(yīng)的私有密鑰才能解密;如果用私有密鑰對(duì)數(shù)據(jù)進(jìn)行加密,那么只有用對(duì)應(yīng)的公開密鑰才能解密。因?yàn)榧用芎徒饷苁褂玫氖莾蓚€(gè)不同的密鑰,所以這種算法叫作非對(duì)稱加密算法。

非對(duì)稱加密與對(duì)稱加密相比,其安全性更好:對(duì)稱加密的通信雙方使用相同的秘鑰,如果一方的秘鑰遭泄露,那么整個(gè)通信就會(huì)被破解。而非對(duì)稱加密使用一對(duì)秘鑰,一個(gè)用來(lái)加密,一個(gè)用來(lái)解密,而且公鑰是公開的,秘鑰是自己保存的,不需要像對(duì)稱加密那樣在通信之前要先同步秘鑰。

非對(duì)稱加密的缺點(diǎn)是加密和解密花費(fèi)時(shí)間長(zhǎng)、速度慢,只適合對(duì)少量數(shù)據(jù)進(jìn)行加密。

在非對(duì)稱加密中使用的主要算法有:RSA、Elgamal、背包算法、Rabin、D-H、ECC(橢圓曲線加密算法)等。

MD5:?

MD5是一種信息摘要算法, 消息摘要是一種與消息認(rèn)證碼結(jié)合使用以確保消息完整性的技術(shù)。主要使用單向散列函數(shù)算法,可用于檢驗(yàn)消息的完整性,和通過(guò)散列密碼直接以文本形式保存等,目前廣泛使用的算法有MD4、MD5、SHA-1。

ANR相關(guān)?

ANR全名Application Not Responding, 也就是"應(yīng)用無(wú)響應(yīng)". 當(dāng)操作在一段時(shí)間內(nèi)系統(tǒng)無(wú)法處理時(shí), 系統(tǒng)層面會(huì)彈出上圖那樣的ANR對(duì)話框.

在Android里, App的響應(yīng)能力是由Activity Manager和Window Manager系統(tǒng)服務(wù)來(lái)監(jiān)控的. 通常在如下兩種情況下會(huì)彈出ANR對(duì)話框:

A) 5s內(nèi)無(wú)法響應(yīng)用戶輸入事件(例如鍵盤輸入, 觸摸屏幕等).

B) BroadcastReceiver在10s內(nèi)無(wú)法結(jié)束.

造成以上兩種情況的首要原因就是在主線程(UI線程)里面做了太多的阻塞耗時(shí)操作, 例如文件讀寫, 數(shù)據(jù)庫(kù)讀寫, 網(wǎng)絡(luò)查詢等等.

(持續(xù)更新.......)

Android:

今日頭條屏幕適配的原理?

1:首先計(jì)算出?density,計(jì)算公式:

當(dāng)前設(shè)備屏幕總寬度(單位為像素)/ 設(shè)計(jì)圖總寬度(單位為 dp) = density

density?的意思就是?1 dp?占當(dāng)前設(shè)備多少像素

計(jì)算density?的原因:在布局文件中填寫的是什么單位,最后都會(huì)被轉(zhuǎn)化為?px,系統(tǒng)就是通過(guò)上面的方法,將你在項(xiàng)目中任何地方填寫的單位都轉(zhuǎn)換為?px?

但是,今日頭條適配方案默認(rèn)項(xiàng)目中只能以高或?qū)捴械囊粋€(gè)作為基準(zhǔn),來(lái)進(jìn)行適配

簡(jiǎn)述Android中的加固和使用平臺(tái)?

加固:防止代碼反編譯,提高代碼安全性

加固三方平臺(tái),梆梆安全,360加固,愛加密等

區(qū)別:梆梆安全,360加固看不到項(xiàng)目中的類,愛加密看的到Java類,單看不到里面的方法實(shí)現(xiàn)體,效果比前面差一點(diǎn)點(diǎn)

加固的底層原理:第三方加固的應(yīng)用會(huì)生成一個(gè)Apk,然后把你的APK讀取出來(lái),在封裝到這個(gè)第三方應(yīng)用的APK里面.

如何對(duì)APK瘦身?

1)使用混淆,

2)開啟shrinkResourse(shrink-收縮),會(huì)將沒有用到的圖片變成一個(gè)像素點(diǎn)

3)刪除無(wú)用的語(yǔ)言資源(刪除國(guó)際化文件)

4)對(duì)于非透明的大圖,使用JPG(沒有透明度信息),代替PNG格式

5)使用tinypng進(jìn)行圖片壓縮

6)使用webp圖片格式,進(jìn)一步壓縮圖片資源

7)使用第三方包時(shí)把用到的代碼加到項(xiàng)目中來(lái),避免引用整一個(gè)第三方庫(kù)

簡(jiǎn)述多渠道打包及原理和常用操作?

針對(duì)每一個(gè)渠道(應(yīng)用市場(chǎng))都生成一個(gè)帶有渠道標(biāo)識(shí)的apk文件

原理:用戶下載啟動(dòng)應(yīng)用,獲取渠道標(biāo)識(shí),和設(shè)備的唯一標(biāo)識(shí),并上傳到服務(wù)器里面,服務(wù)器這里就 會(huì)根據(jù)獲取的記錄,根據(jù)渠道號(hào)然后判斷是否存在該服務(wù)器的表里面.(打標(biāo)記,取標(biāo)記,上傳標(biāo)記)

1)友盟多渠道打包:在清單文件中定義一個(gè)占位符,在gradle腳本中替換占位符(會(huì)使用到Python)

2)美團(tuán)打包,在meta-data中創(chuàng)建一個(gè)空的文件,以文件名標(biāo)識(shí)渠道,做一個(gè)解壓與壓縮的操作,速度會(huì)比較快

3)新一代多渠道打包,將渠道標(biāo)識(shí)添加到.apk文件的末尾,并不會(huì)對(duì)源文件損壞

Android下的數(shù)據(jù)存儲(chǔ)方式有那些?

1)內(nèi)部存儲(chǔ),直接存儲(chǔ)在內(nèi)部文件中

2)外部存儲(chǔ),首先要判斷外部存儲(chǔ)條件是否可用,然后進(jìn)行存儲(chǔ)

3)SP存儲(chǔ),底層是Xml實(shí)現(xiàn)的,以鍵值對(duì)形式存儲(chǔ)內(nèi)部的數(shù)據(jù),適宜于輕量級(jí)的存儲(chǔ),存儲(chǔ)的數(shù)據(jù)類型有,boolean,String,int

4)數(shù)據(jù)庫(kù)存儲(chǔ),SQlite存儲(chǔ),輕量級(jí)的數(shù)據(jù)庫(kù),強(qiáng)大的增刪改查功能

5)內(nèi)容提供者,ContentProvider,將自己愿意暴露的一部分?jǐn)?shù)據(jù)供外部使用操作

6)網(wǎng)絡(luò)存儲(chǔ),等等

Sharepreference 線程安全問題?

官方文檔明確指出,SharedPreferences不支持多線程,進(jìn)程也是不安全的

如果想要實(shí)現(xiàn)線程安全需重新實(shí)現(xiàn)其接口,如下


SP安全相關(guān)

假設(shè)在多進(jìn)程訪問SharePreferences的情況下,該如何保證進(jìn)程安全和共享數(shù)據(jù)?

解決辦法就是:將需要共享數(shù)據(jù)的字段提出來(lái)統(tǒng)一存儲(chǔ)到一個(gè)文件中。

Android開發(fā)下如何有效進(jìn)行屏幕適配?

1:機(jī)型適配,去一些統(tǒng)計(jì)網(wǎng)站諸如友盟,現(xiàn)在叫友盟+去看一下市場(chǎng)上最流行的Android機(jī)型,有針對(duì)性的切圖

2:屏幕適配,適配主流xhdpi屏幕尺寸,使用relativelayout,linerlayout等布局,多使用matchparent,wrapcontent,及配合weight,權(quán)重處理,

3:還有就是在代碼中,設(shè)計(jì)到具體尺寸的要使用dp2px的轉(zhuǎn)換,

4:圖片使用可拉伸.9圖片,imageview使用scaletype縮放;

5:使用權(quán)重,等比例,百分比布局等等

對(duì)象序列化:

為什么要序列化?

1)永久性保存對(duì)象,保存對(duì)象的字節(jié)序列到本地文件中;

2)通過(guò)序列化對(duì)象在網(wǎng)絡(luò)中傳遞對(duì)象;

3)通過(guò)序列化在進(jìn)程間傳遞對(duì)象。

在Android中實(shí)現(xiàn)序列化有兩個(gè)選擇:一是實(shí)現(xiàn)Serializable接口(是JavaSE本身就支持的),一是實(shí)現(xiàn)Parcelable接口(是Android特有功能,效率比實(shí)現(xiàn)Serializable接口高效,可用于Intent數(shù)據(jù)傳遞,也可以用于進(jìn)程間通信(IPC))。實(shí)現(xiàn)Serializable接口非常簡(jiǎn)單,聲明一下就可以了,而實(shí)現(xiàn)Parcelable接口稍微復(fù)雜一些,但效率更高,推薦用這種方法提高性能。兩種實(shí)現(xiàn)方式依舊是貼url,方便大家快速查詢

兩種序列化相關(guān)

既然Google推薦Parcelable這種序列化,在這里,推薦一鍵生成序列化的插件,

在Android Studio里面搜索插件,如下圖,寫起序列化(根本不用你寫)那就是一個(gè)美滋滋吶~


parcelable plugin


OkHttp相關(guān)?

OkHttp支持同步和異步數(shù)據(jù)請(qǐng)求,但異步請(qǐng)求是在子線程 (因?yàn)樵鶲kHttp的使用時(shí)回調(diào)方法是在子線程進(jìn)行的,要刷新界面還需要用Handler作處理,可以使用第三方的okhttp-utils,Okgo等等);

OkHttp里面封裝了線程池、數(shù)據(jù)轉(zhuǎn)換、GZIP壓縮(減少流量的傳輸)、HTTP協(xié)議緩存等,

OKHttp優(yōu)點(diǎn)---使用GZip壓縮減少傳輸?shù)臄?shù)據(jù)量,緩存(減少重復(fù)請(qǐng)求);

失敗重試(如果你的服務(wù)有多個(gè)IP地址,如果第一次連接失敗,OKHttp將使用備用地址)

OKhttp是對(duì)http協(xié)議的封裝,比較底層,因此拓展性強(qiáng),便于封裝;

OKhttp基于NIO(JDK1.5,非阻塞式IO)效率更高

ButterKnife相關(guān)?

簡(jiǎn)介:

一款快速高效的注入框架,節(jié)約開發(fā)時(shí)間減少代碼量(依靠插件動(dòng)態(tài)生成View,點(diǎn)擊事件等等)

優(yōu)點(diǎn):

1.強(qiáng)大的View綁定和Click事件處理功能,簡(jiǎn)化代碼,提升開發(fā)效率

2.方便的處理Adapter里的ViewHolder綁定問題

3.運(yùn)行時(shí)不會(huì)影響APP效率,使用配置方便

4.代碼清晰,可讀性強(qiáng)

使用經(jīng)驗(yàn):

1.Activity ButterKnife.bind(this);必須在setContentView();之后,且父類bind綁定后,子類不需要再bind

2.Fragment ButterKnife.bind(this, mRootView);

3.屬性布局不能用private or static 修飾,否則會(huì)報(bào)錯(cuò),(注意權(quán)限)

4.setContentView()不能通過(guò)注解實(shí)現(xiàn)。(其他的有些注解框架可以)

原理:利用注解和反射去獲取綁定ViewID,

關(guān)于原理詳情可參考筆者的這一篇:Android-定制專屬ButterKnife框架,該文詳細(xì)介紹了ButterKnife框架并模仿了一個(gè)注解綁定View的框架

Rxjava概念,常用操作符及拓展?

簡(jiǎn)介:

一款優(yōu)雅的異步框架,代替之前的AsyncTask / Handler / XXX / ...?

其強(qiáng)大的操作符和鏈?zhǔn)綄懛?線程切換等有助于提高開發(fā)效率和快速定位Bug

與Retrofit搭配使用更是有意想不到的效果,

底層原理:觀察者模式

如何使用:Rxjava涉及的內(nèi)容太多太多,只能說(shuō)推薦引導(dǎo)大家看下這篇?Rxjava2相關(guān)?等一些相應(yīng)的博客

缺點(diǎn):

1:操作符太多會(huì)增加學(xué)習(xí)成本時(shí)間

2:使用不好,容易導(dǎo)致內(nèi)存泄露(解決方式,推薦Rxlifecycle結(jié)合Rxjava,規(guī)避內(nèi)存泄漏風(fēng)險(xiǎn))

(持續(xù)更新.......)

ANR相關(guān)?

ANR全名Application Not Responding, 也就是"應(yīng)用無(wú)響應(yīng)". 當(dāng)操作在一段時(shí)間內(nèi)系統(tǒng)無(wú)法處理時(shí), 系統(tǒng)層面會(huì)彈出上圖那樣的ANR對(duì)話框.

在Android里, App的響應(yīng)能力是由Activity Manager和Window Manager系統(tǒng)服務(wù)來(lái)監(jiān)控的. 通常在如下兩種情況下會(huì)彈出ANR對(duì)話框:

A) 5s內(nèi)無(wú)法響應(yīng)用戶輸入事件(例如鍵盤輸入, 觸摸屏幕等).

B) BroadcastReceiver在10s內(nèi)無(wú)法結(jié)束.

造成以上兩種情況的首要原因就是在主線程(UI線程)里面做了太多的阻塞耗時(shí)操作, 例如文件讀寫, 數(shù)據(jù)庫(kù)讀寫, 網(wǎng)絡(luò)查詢等等.

如何分析ANR?

ANR產(chǎn)生時(shí), 系統(tǒng)會(huì)生成一個(gè)traces.txt的文件放在/data/anr/下. 開發(fā)人員可通過(guò)adb命令將其導(dǎo)出到本地 ($adb pull data/anr/traces.txt .)通過(guò)分析,我們可以根據(jù)具體的日志查看Anr原因( 如: 普通阻塞,CPU滿負(fù)荷,內(nèi)存泄露 )

更多Anr細(xì)節(jié)可參考 ?Anr詳解 ,這位筆者非常詳細(xì)的介紹了Anr相關(guān)內(nèi)容

Android中那些場(chǎng)景是執(zhí)行在主線程的?

1)Activity生命周期回調(diào)都是執(zhí)行在主線程的.

2)Service默認(rèn)是執(zhí)行在主線程的.

3)BroadcastReceiver的onReceive回調(diào)是執(zhí)行在主線程的.

4)沒有使用子線程的looper的Handler的handleMessage, post(Runnable)是執(zhí)行在主線程的.

5)AsyncTask的回調(diào)中除了doInBackground, 其他都是執(zhí)行在主線程的.

6)View的post(Runnable)是執(zhí)行在主線程的.等等

三級(jí)緩存:

當(dāng)我們第一次打開應(yīng)用獲取圖片或其它資源時(shí),首先到網(wǎng)絡(luò)去下載,然后依次存入內(nèi)存緩存,磁盤緩存,

當(dāng)我們?cè)僖淮涡枰玫絼偛畔螺d的這張圖片時(shí),就不需要再重復(fù)的到網(wǎng)絡(luò)上去下載,直接可以從內(nèi)存緩存和磁盤緩存中找,由于內(nèi)存緩存速度較快,我們優(yōu)先到內(nèi)存緩存中尋找該圖片,如果找到則運(yùn)用,

如果沒有找到(內(nèi)存緩存大小有限),那么我們?cè)俚酱疟P緩存中去找。

只要我們合理的去協(xié)調(diào)這三層緩存運(yùn)用,便可以提升應(yīng)用性能,給用戶更好的體驗(yàn)

三級(jí)緩存指的是:內(nèi)存緩存、本地緩存、網(wǎng)絡(luò)緩存。其各自的特點(diǎn)是內(nèi)存緩存速度快, 優(yōu)先讀取,本地緩存速度其次, 內(nèi)存沒有該資源信息就去讀取本地內(nèi)存,網(wǎng)絡(luò)緩存速度較慢(比較對(duì)象是內(nèi)存緩存和本地緩存),假設(shè)本地內(nèi)存也沒有,才請(qǐng)求網(wǎng)絡(luò)獲取。

內(nèi)存泄漏:

當(dāng)應(yīng)用內(nèi)部不再需要某個(gè)實(shí)例后,但是這個(gè)對(duì)象卻仍然被引用,這個(gè)情況就叫做內(nèi)存泄露(Memory Leak)。安卓虛擬機(jī)為每一個(gè)應(yīng)用分配一定的內(nèi)存空間,當(dāng)內(nèi)存泄露到達(dá)一定的程度就會(huì)造成內(nèi)存溢出。

導(dǎo)致內(nèi)存泄露常見原因:

1)靜態(tài)變量直接或者間接地引用了Activity對(duì)象就會(huì)造成內(nèi)存泄露

2)Activity使用了靜態(tài)的View(View會(huì)持有Activity的對(duì)象的引用)

3)Activity定義了靜態(tài)View變量???

4)ImageSpan引用了Activity Context

5)單例中引用了Activity的Context(需要使用Application的Context)

6)對(duì)于使用了BraodcastReceiver,ContentObserver,F(xiàn)ile,Cursor,Stream,Bitmap等資源,應(yīng)該在Activity銷毀時(shí)及時(shí)關(guān)閉或者注銷,否則這些資源將不會(huì)被回收,從而造成內(nèi)存泄漏。

7)靜態(tài)集合保存的對(duì)象沒有及時(shí)消除(不使用的時(shí)候置為null)

8)在Java中,非靜態(tài)(匿名)內(nèi)部類會(huì)引用外部類對(duì)象,而靜態(tài)內(nèi)部類不會(huì)引用外部類對(duì)象

9)在Activity中,創(chuàng)建了非靜態(tài)內(nèi)部類(內(nèi)部類直接或者間接引用了Activity)的靜態(tài)成員變量

10)線程包括AsyncTask的使用,Activity退出后線程還在運(yùn)行(線程在死循環(huán)),并且在線程中使用了Activity或view對(duì)象(解決方法:不要直接寫死循環(huán),可以設(shè)置一個(gè)布爾類型的TAG,當(dāng)activity推出的時(shí)候,設(shè)置TAG為False)

11)Handler對(duì)象的使用,Activity退出后Handler還是有消息需要處理(解決方法:在退出activity之后,移除消息)

12)WebView造成的內(nèi)存泄漏(在onDestory中銷毀)

如何進(jìn)行內(nèi)存泄露分析?

A: 通過(guò)Android Studio 窗口進(jìn)行分析,查看內(nèi)存分配情況,如果操作應(yīng)用是內(nèi)存一直往上漲說(shuō)明存在內(nèi)存泄露

B: 定位內(nèi)存泄露分析的工具---MAT(Memory Analyzer tool)

C: 使用開源庫(kù)LeakCanary快速定位內(nèi)存泄露

Android中的四大組件相關(guān)?

Activity:

Activity是一個(gè)應(yīng)用程序組件,提供一個(gè)屏幕(狹義的理解就是當(dāng)前APP的界面),用戶可以用來(lái)交互為了完成某項(xiàng)任務(wù)。(點(diǎn)擊,登錄,跳轉(zhuǎn)頁(yè)面)

Activity中所有操作都與用戶密切相關(guān),是一個(gè)負(fù)責(zé)與用戶交互的組件,可以通過(guò)setContentView(View)來(lái)顯示指定控件(設(shè)置布局文件)。

在一個(gè)android應(yīng)用中,一個(gè)Activity通常就是一個(gè)單獨(dú)的屏幕,它上面可以顯示一些控件也可以監(jiān)聽并處理用戶的事件做出響應(yīng)。


Activty的生命周期


Activity四種啟動(dòng)模式?

Activity的啟動(dòng)模式指,可以根據(jù)實(shí)際開發(fā)需求為Activity設(shè)置對(duì)應(yīng)的啟動(dòng)模式,從而可以避免創(chuàng)建大量重復(fù)的Activity等問題。

1)standard

standard為Activity的默認(rèn)啟動(dòng)模式,可以不用寫配置。在這個(gè)模式下,都會(huì)默認(rèn)創(chuàng)建一個(gè)新的實(shí)例。因此,在這種模式下,可以有多個(gè)相同的實(shí)例,也允許多個(gè)相同Activity疊加。(點(diǎn)back鍵會(huì)依照棧順序依次退出)

2)singleTop

singleTop模式下,Activity可以有多個(gè)實(shí)例,但是不允許多個(gè)相同Activity疊加。即,如果Activity在棧頂?shù)臅r(shí)候,啟動(dòng)相同的Activity,不會(huì)創(chuàng)建新的實(shí)例,而會(huì)調(diào)用其onNewIntent方法。

3)singleTask

singleTask表示只有一個(gè)實(shí)例。在同一個(gè)應(yīng)用程序中啟動(dòng)他的時(shí)候,若Activity不存在,則會(huì)在當(dāng)前task創(chuàng)建一個(gè)新的實(shí)例,若存在,則會(huì)把task中在其之上的其它Activity destory掉并調(diào)用它的onNewIntent方法。如果是在別的應(yīng)用程序中啟動(dòng)它,則會(huì)新建一個(gè)task,并在該task中啟動(dòng)這個(gè)Activity,singleTask允許別的Activity與其在一個(gè)task中共存,也就是說(shuō),如果我在這個(gè)singleTask的實(shí)例中再打開新的Activity,這個(gè)新的Activity還是會(huì)在singleTask的實(shí)例的task中。

4)singleInstance

只有一個(gè)實(shí)例,并且這個(gè)實(shí)例獨(dú)立運(yùn)行在一個(gè)task中,這個(gè)task只有這個(gè)實(shí)例,不允許有別的Activity存在。


BraodcastReceiver:(待補(bǔ)充)

使用了設(shè)計(jì)模式中的觀察者模式:基于消息的發(fā)布/訂閱事件模型。

注冊(cè)的方式分為兩種:靜態(tài)注冊(cè)、動(dòng)態(tài)注冊(cè)

ContentProvider:(待補(bǔ)充)

外界可以通過(guò)ContentResolver接口來(lái)訪問ContentProvider(內(nèi)容提供者)中的數(shù)據(jù)。Uri 通用資源標(biāo)志符(Universal Resource Identifier)Uri代表要操作的數(shù)據(jù),Android中可用的每種資源 - 圖像、視頻片段等都可以用Uri來(lái)表示。
ContentProvider共享數(shù)據(jù)是通過(guò)定義一個(gè)對(duì)外開放的統(tǒng)一的接口來(lái)實(shí)現(xiàn)的。然而,應(yīng)用程序并不直接調(diào)用這些方法,而是使用一個(gè) ContentResolver 對(duì)象,調(diào)用它的方法作為替代。ContentResolver可以與任意內(nèi)容提供者進(jìn)行會(huì)話,與其合作來(lái)對(duì)所有相關(guān)交互通訊進(jìn)行管理。當(dāng)外部應(yīng)用需要對(duì)ContentProvider中的數(shù)據(jù)進(jìn)行添加、刪除、修改和查詢操作時(shí),可以使用ContentResolver類來(lái)完成,要獲取ContentResolver對(duì)象,可以使用Context提供的getContentResolver()方法。

IntentService:

IntentService是Service的子類,比普通的Service增加了額外的功能。IntentService會(huì)創(chuàng)建獨(dú)立的worker線程來(lái)處理所有的Intent請(qǐng)求;會(huì)創(chuàng)建獨(dú)立的worker線程來(lái)處理onHandleIntent()方法實(shí)現(xiàn)的代碼,無(wú)需處理多線程的問題;所有請(qǐng)求處理完成后,IntentService會(huì)自動(dòng)停止,開發(fā)者無(wú)需手動(dòng)調(diào)用stopSelf()方法停止Service;

簡(jiǎn)述System.exit(0) 、onDestory()、Activity.finish()三者的區(qū)別

1)System.exit(0)?是你正常結(jié)束程序,kill?掉當(dāng)前進(jìn)程,針對(duì)的是整個(gè)Application

2)onDestory()方法是Activity生命周期的最后一步,資源空間等就被回收了。當(dāng)重新進(jìn)入此Activity的時(shí)候,必須重新創(chuàng)建,執(zhí)行onCreate()方法.

3)Activity.finish()當(dāng)你調(diào)用此方法的時(shí)候,系統(tǒng)只是將最上面的Activity移出了棧,并沒有及時(shí)的調(diào)用onDestory()方法,也就是占用的資源沒有被及時(shí)釋放。

圖片優(yōu)化,以及圖片加載框架的使用,如Picasso、 Fresco、Glide等?

1)盡量使用小的圖片,對(duì)圖片進(jìn)行壓縮,bitmapfactory.options圖片配置類,insimplesize進(jìn)行縮放,設(shè)置圖片的編碼方式;對(duì)圖片使用軟引用,內(nèi)存不夠時(shí)即時(shí)釋圖片內(nèi)存;對(duì)圖片的復(fù)用,三級(jí)緩存的使用;

即時(shí)回收不再使用的bitmap對(duì)象;

2)Picasso,不支持gif,緩存的是Argb8888的原圖,占用內(nèi)存較大,圖片的框架使用了OkHttp緩存機(jī)制,使用Http協(xié)議緩存,也是異步加載.

3)Fresco,框架是FaceBook公司推出的,適合批量加載圖片,底層是通過(guò)三級(jí)緩存(2級(jí)內(nèi)存,1級(jí)磁盤)

加載成功后自動(dòng)替換成目標(biāo)圖片

4)glide,Google公司14年推出來(lái)的,可以加載GIF圖,也可以根據(jù)指定圖片清晰度,底層的原理:為Bitmap維護(hù)一個(gè)對(duì)象池,對(duì)象池的目的是通過(guò)減少對(duì)象的分配,以重用來(lái)提高性能.對(duì)象池也可以幫助提高滾動(dòng)的性能。API簡(jiǎn)潔易調(diào)用

Handle相關(guān):

Handler 工作流程基本包括 Handler、Looper、Message、MessageQueue 四個(gè)部分。但我們?cè)谌粘i_發(fā)中,經(jīng)常都只會(huì)用到 Handler 和 Message 兩個(gè)類。Message 負(fù)責(zé)消息的搭載,里面有個(gè)target用于標(biāo)記消息,obj用于存放內(nèi)容,Handler 負(fù)責(zé)消息的分發(fā)和處理。

一般在開發(fā)中是怎么使用 Handler 的?

官方不允許在子線程中更新 UI,所以我們經(jīng)常會(huì)把需要更新 UI 的消息直接發(fā)給處理器 Handler,通過(guò)重寫 Handler 的handleMessage()方法進(jìn)行 UI 的相關(guān)操作。

Handle使用中就沒什么需要注意的嗎?

有,Handler 如果設(shè)置為私有變量的話,Android Studio 會(huì)報(bào)警告,提示可能會(huì)造成內(nèi)存泄漏,這種情況可以通過(guò)設(shè)置為靜態(tài)內(nèi)部類 + 弱引用,或者在onDestroy()方法中調(diào)用Handler.removeCallbacksAndMessages(null)即可避免

Handler 整體工作流程淺析分為以下四個(gè)步驟:

異步通信準(zhǔn)備 => 消息入隊(duì) => 消息循環(huán) => 消息處理

A:異步通信準(zhǔn)備

I:假定是在主線程創(chuàng)建 Handler,則會(huì)直接在主線程中創(chuàng)建處理器對(duì)象Looper、消息隊(duì)列對(duì)象MessageQueue和 Handler 對(duì)象。

需要注意的是,Looper和MessageQueue均是屬于其創(chuàng)建線程的。

II:Looper對(duì)象的創(chuàng)建一般通過(guò)Looper.prepareMainLooper()和Looper.prepare()兩個(gè)方法,而創(chuàng)建Looper對(duì)象的同時(shí),將會(huì)自動(dòng)創(chuàng)建MessageQueue。

III:創(chuàng)建好MessageQueue后,Looper將自動(dòng)進(jìn)入消息循環(huán)。此時(shí),Handler自動(dòng)綁定了主線程的Looper和MessageQueue。

B:消息入隊(duì)

工作線程通過(guò)Handler發(fā)送消息Message到消息隊(duì)列MessageQueue中,消息內(nèi)容一般是 UI 操作。發(fā)送消息一般都是通過(guò)Handler.sendMessage(Message msg)和Handler.post(Runnabe r)兩個(gè)方法來(lái)進(jìn)行的。而入隊(duì)一般是通過(guò)MessageQueue.enqueueeMessage(Message msg,long when)來(lái)處理。

C:消息循環(huán)

主要分為「消息出隊(duì)」和「消息分發(fā)」兩個(gè)步驟,Looper會(huì)通過(guò)循環(huán)取出消息隊(duì)列MessageQueue里面的消息Message,并分發(fā)到創(chuàng)建該消息的處理者Handler。如果消息循環(huán)過(guò)程中,消息隊(duì)列MessageQueue為空隊(duì)列的話,則線程阻塞。

D:消息處理

Handler接收到Looper發(fā)來(lái)的消息,開始進(jìn)行處理。

LRU全稱為L(zhǎng)east Recently Used,即最近最少使用原則

1)當(dāng)緩存空間滿了的時(shí)候,將最近最少使用的數(shù)據(jù)從緩存空間中刪除,以增加可用的緩存空間來(lái)緩存新數(shù)據(jù)

2)這個(gè)算法內(nèi)部有一個(gè)緩存列表,每當(dāng)一個(gè)緩存數(shù)據(jù)被訪問的時(shí)候,這個(gè)數(shù)據(jù)就會(huì)被提到列表尾部,每次都這樣的話,列表的頭部數(shù)據(jù)就是最近最不常使用的了,當(dāng)緩存空間不足時(shí),就會(huì)刪除列表頭部的緩存數(shù)據(jù)

3)內(nèi)部使用了 LinkedHashMap 進(jìn)行存儲(chǔ),總緩存大小一般為可用內(nèi)存的 1/8

拓展

先簡(jiǎn)單介紹下你自己?

分析:除了向面試官做簡(jiǎn)單的基本自我介紹之外,還需向面試官展現(xiàn)自身對(duì)該職業(yè)所必須具備的一些自身特質(zhì),

比如,面試程序員職業(yè)需要間接的向面試官表示自己思維嚴(yán)謹(jǐn),對(duì)細(xì)節(jié)的處理,理性思維,假設(shè)論證等等;面試產(chǎn)品等職業(yè),需要向面試官通過(guò)自己的一些故事間接展現(xiàn)對(duì)產(chǎn)品的看法以及獨(dú)特的思維個(gè)性等等

切入點(diǎn):自身特質(zhì)能否符合該職位的預(yù)期需求

自己的興趣愛好特長(zhǎng)有那些?

在企業(yè)和面試官看來(lái),如果求職者的愛好和應(yīng)聘的崗位在某些方面恰恰有正向關(guān)聯(lián),就會(huì)有興趣。面試官也會(huì)通過(guò)應(yīng)聘者的興趣愛好來(lái)判斷其價(jià)值觀是否與企業(yè)文化契合,能否很好地融入工作團(tuán)隊(duì)。求職者的回答將有可能為面試加分。

下列興趣愛好所反映出的一些性格和職業(yè)方向可供參考:

1.籃球,足球,排球:團(tuán)隊(duì)精神,適用大多數(shù)崗位。

2.圍棋,國(guó)際象棋:戰(zhàn)略意識(shí),適合市場(chǎng)類或高端職位。

3.閱讀,古典音樂:高雅,適合文職類的職位。

4.旅游:適應(yīng)不同環(huán)境的能力,快速學(xué)習(xí)的能力,適合銷售業(yè)務(wù)類職位。

5.舞蹈:外向,易溝通,適合公關(guān)、市場(chǎng)類的職位。

對(duì)自己的期望和規(guī)劃?

分析:職業(yè)發(fā)展規(guī)劃表面上看是在考察你(求職者)、職位、公司三者之間長(zhǎng)期的契合程度,但實(shí)際上,這么大的一個(gè)問題完全不是三眼兩語(yǔ)間能夠表達(dá)清楚的。面試官(無(wú)論HR還是專業(yè)部門的)主要是看你回答問題時(shí)的思路是否清晰,回答中表現(xiàn)出的工作態(tài)度如何,順便看看你是否對(duì)公司和職位有足夠的了解。所以不管答案如何,最關(guān)鍵的就是不能茫然。

切入點(diǎn):依舊自身特點(diǎn),對(duì)未來(lái)期望和規(guī)劃需表述清晰,思維敏捷


談?wù)勛约旱膬?yōu)點(diǎn)和缺點(diǎn)?

先談缺點(diǎn):

技術(shù)行業(yè)面試基本是由該崗位未來(lái)同事和上司進(jìn)行。這種面試技術(shù)性強(qiáng),行為問題主要考察就是你是否真心想做這個(gè)工作(而不是當(dāng)跳板或者聽說(shuō)高薪體面而來(lái))和你性格與文化是否相符。所有答案都應(yīng)該圍繞這兩點(diǎn)組織(即每個(gè)經(jīng)歷都應(yīng)回歸到你通過(guò)這個(gè)經(jīng)歷學(xué)到什么,該職位所需關(guān)鍵技巧,這些經(jīng)歷為何讓你想做這個(gè)工作,和該經(jīng)歷體現(xiàn)出你什么樣的個(gè)人風(fēng)格)。對(duì)這個(gè)問題因?yàn)楹玫幕卮鸲粝潞糜∠蠛茈y,

關(guān)鍵是避免留下壞印象。

要點(diǎn)以下:

1)避免避重就輕,不要談一個(gè)算不得缺點(diǎn)的缺點(diǎn)。比如熬夜會(huì)困,或者(待人接物)太客氣等等。

2)避免談非職業(yè)缺點(diǎn),比如有感情潔癖,挑食,不擅長(zhǎng)陪女友逛街,做飯經(jīng)常不懂會(huì)煮糊。

3)避免談到無(wú)法改善的弱點(diǎn),比如我算數(shù)必須用計(jì)算器,我腦子不好用看書不理解。

4)避免談到致命弱點(diǎn),比如脾氣怪異,不喜歡合作,遲到早退等。

那談什么最好呢?我認(rèn)為要點(diǎn)有三:

1)談已經(jīng)在改正的缺點(diǎn)/有明確計(jì)劃來(lái)改正的缺點(diǎn)。尤其是你能夠充分論證在近期就可以解決的缺點(diǎn)。

2)談一個(gè)利用你的優(yōu)點(diǎn)改正的缺點(diǎn),順便帶出一個(gè)優(yōu)點(diǎn)。(這是較高效的溝通技巧)

相對(duì)較好的回答:

1)喜歡追求細(xì)節(jié)導(dǎo)致項(xiàng)目/作業(yè)未能按期完成。通過(guò)時(shí)間管理能力改變工作方式,先完成框架再改善細(xì)節(jié)得以解決;

2)不知如何拒絕,同事要求幫忙一概攬下,影響自身工作進(jìn)度。通過(guò)多任務(wù)處理能力設(shè)定優(yōu)先順序,以該優(yōu)先順序表向求助同事展示自己手上工作,并給其一個(gè)自己在何時(shí)可以給予幫助的時(shí)間估計(jì),讓求助人自行決定是否求助,問題解決

3)對(duì)處理同一問題的解決辦法上,由于組員自己的技術(shù)偏好和技術(shù)構(gòu)成不一樣容易造成溝通障礙及影響項(xiàng)目計(jì)劃,所以,應(yīng)學(xué)會(huì)高效和有效溝通方式及工作技巧

End:

本文意在分享面試題目,因是筆者自己整理的一些面試答案,如有不足,也希望大家多多指正(碼字不易,且行且珍惜望收藏望點(diǎn)贊),

感謝文章中動(dòng)態(tài)鏈接的作者,忠于開源,樂于分享,我想,這才是Android開發(fā)的本質(zhì)及靈魂吧

千里之行,始于足下,希望能和大家一起學(xué)習(xí)成長(zhǎng),加油!

如果這篇文章對(duì)您有開發(fā)or學(xué)習(xí)上的些許幫助,希望各位看官留下寶貴的star,謝謝。

Ps:著作權(quán)歸作者所有,轉(zhuǎn)載請(qǐng)注明作者, 商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處(開頭或結(jié)尾請(qǐng)?zhí)砑愚D(zhuǎn)載出處,添加原文url地址),文章請(qǐng)勿濫用,也希望大家尊重筆者的勞動(dòng)成果,謝謝。

最后,祝愿大家通過(guò)自己的努力早日拿到心儀的Offer !

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

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

  • 從三月份找實(shí)習(xí)到現(xiàn)在,面了一些公司,掛了不少,但最終還是拿到小米、百度、阿里、京東、新浪、CVTE、樂視家的研發(fā)崗...
    時(shí)芥藍(lán)閱讀 42,874評(píng)論 11 349
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,324評(píng)論 25 708
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類相關(guān)的語(yǔ)法,內(nèi)部類的語(yǔ)法,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法,線程的語(yǔ)...
    子非魚_t_閱讀 34,839評(píng)論 18 399
  • 我家門前的花紅柳綠,看到花看到綠就覺得心情很好的樣子?;ㄒ獍蝗坏拇喝兆钸m合出去走走。只是說(shuō)了好多次要去,始終沒有真...
    bienvenue閱讀 573評(píng)論 3 2
  • 我們生活的世界是五彩繽紛的,每天都會(huì)有不同的事情發(fā)生,關(guān)鍵在于你有沒有一雙善于發(fā)現(xiàn)的眼睛。 對(duì)于鄉(xiāng)村教...
    桃子_939e閱讀 219評(píng)論 0 0

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