Android常見問題簡單總結

  • 1、https,如何避免Client和Server中間劫持?
    客戶端是如何校驗證書的呢?這裏發生在第三步,客戶端接收到服務端的證書,裏面主要包含公鑰和簽名。根據證書上的簽發機構去瀏覽器內置的CA簽發證書裏面找到保存的證書公鑰,而後用這個公鑰解開簽名,獲得數字摘要(digest,證書內容的hash值),和服務端的證書進行對比驗證。 因此https能夠被攔截,可是不能被劫持。html

  • 2、插件化hook IActivityManager採用什麼代理方式?爲何? hook IActivityManager是採用動態代理的方式。由於它並無一個具體的實現類,而是使用代理的方式。java

  • 3、找車App白屏問題,內存泄漏
    找車app是汽車之家主app裏面很重要的一個模塊,在無網絡的狀況下也須要可以展現默認數據。這些默認數據會在app第一次啓動的時候須要序列化到數據庫裏面,因爲在主線程作的會有一下子白屏。
    須要把這個序列化放在後端作處理,這裏我用AsyncTask,在後端去作處理。可是這裏若是匿名內部類會有持有Activity的引用,這樣若是退出Activity後臺操做尚未處理完成,那麼activity就無法被回收,會有內存泄漏問題。
    這裏使用靜態內部類來解決這個問題,可是若是想要在onPostExecute裏面去去處理調用activity的成員變量就變得不可能了,那麼怎麼辦?這裏用到弱引用,用弱引用保存當前Activity引用,那麼久能夠經過get獲取到Activity了。react

  • 4、HashMap的數據結構
    (1)HashMap是鏈表的數組,是Entry的集合,Entry是隊列也是健值對。在Java8的時候鏈表長度大於8則採用紅黑樹。程序員

  • 5、爲何HashMap線程不安全?算法

  1. 由於HashMap在put的時候有可能兩個線程put一個hashCode相同的key,這個時候在相同的bucket上,A線程獲取了鏈表的頭節點;正好A的時間片用完了,切換到了B,B在這個節點頭上掛了一個元素,在切換成A線程,A也直接把B給替換了,這樣B線程的元素就丟失了。sql

  2. resize會致使死循環鏈表。 綜合上面兩點,能夠說明HashMap是線程不安全的。 ConcurrentHashMap在Java1.7採用的架構是segment+hashEntry+ReentrantLock。而在Java1.8中採用的是Node + CAS + Synchronized的結構。爲何Java1.8的get操做不須要枷鎖都能保證數據安全呢?那是由於在Java1.8的Node節點和value是volatile修飾,保證了線程的可見性。數據庫

  3. 既然volatile修飾數組對get操做沒有效果那加在數組上的volatile的目的是什麼呢?
    其實就是爲了使得Node數組在擴容的時候對其餘線程具備可見性而加的volatile後端

  4. 在1.8中ConcurrentHashMap的get操做全程不須要加鎖,這也是它比其餘併發集合好比hashtable、用Collections.synchronizedMap()包裝的hashmap;安全效率高的緣由之一。數組

  5. get操做全程不須要加鎖是由於Node的成員val是用volatile修飾的和數組用volatile修飾沒有關係。 數組用volatile修飾主要是保證在數組擴容的時候保證可見性。 www.cnblogs.com/keeya/p/963…promise

  • 6、AsyncTask能夠設置線程池嗎? 能夠的,經過excuteOnExecutor(Executor exec, Params... params)來設置線程

  • 7、線程如何同步? join、wait/notify

  • 9、有哪些跨進城的方式,底層是binder的算一種,能說說binder嗎?
    一、Intent跨進程訪問別的Activity
    二、ContentProvider的底層是採用 Android中的Binder機制
    三、廣播(Broadcast)
    四、AIDL服務
    五、文件
    六、socket

  • Android Jetpack 一個有生命週期的可觀察的數據持有者。
    LiveData如何實現數據可觀察: 其實LiveData的原理仍是訂閱。從observe方法開始,註冊owner,和Observer,把owner封裝成LifecycleBoundObserver包裝類,讓這個監聽者安全,即inactive的時候不回調。而後把這個包裝類put進去課迭代的Map中。最後,更改數據都會走到setValue();這個方法把map裏面的觀察者遍歷出來,挨個判斷與之關聯的owner是否是mActive,是就調用onChanged方法。

MutableLiveData 數據持有者的最簡單的實現類
MediatorLiveData
能夠合併多個Livedata的數據持有者
Transformations.map()
能夠對數據流作一些鏈式操做的的方法,入加入一些數據
Transformations.switchMap() 能夠根據條件選擇監聽那個數據持有者(LiveData) 看源碼可知道,LiveData可被監聽數據的變化的原理就是訂閱。 裏面維護着能夠迭代的健值對數組

Lifecycle 和 LifecycleObserver ,讓咱們作MVP的時候Presenter層能夠完美和View分離開來。 Lifecycle源碼解讀 ViewModel是經過ViewModelFactory反射建立的,同時保存在ViewModelStore裏面。

  • 單例模式有幾種寫法?

  • AsyncTask的優缺點 優勢:簡單、好用,封裝性好 缺點: 一、容易內存泄漏
    二、AsyncTask是默認(execute())在線程池串行執行的,並無徹底發揮線程池的做用。能夠經過setDefaultExcutor()設置本身的線程池,也能夠經過execueOnExcutor()設置本身的線程池,達到並行的目的。
    三、不少開發者會認爲一個在Activity中建立的AsyncTask會隨着Activity的銷燬而銷燬,事實並非,沒有及時取消AsyncTask所帶來的問題,AsyncTask.cancel()進行取消。

防止handler帶來的內存泄漏: 一、弱引用(沒有第二種好,由於Google說它的虛擬機不擅長處理非強引用的對象)
二、在onDestroy 移除消息
handler.removeMessages();
handler.removeCallbacksAndMessages();

  • Android系統架構 應用層 //應用
    Framework層 //應用框架層 ContentProvider ViewSystem 各大Manager
    Library層 Native C/C++ 一些三方庫好比SQLite, WebKit OpenGL Android Runtime
    HAL層 硬件層BlueTooth Audio Camera Sensors
    Linux內核層 Linux kernel (BlueTooth Audio Camera)的驅動

  • 若是開啓多個頁面,如何避免OOM?(目前還不知道,知道的請告知我) Okhttp設置支持https、封裝緩存配置,封裝get、post請求
    Okhttp的緩存設置:
    Okhttp是經過Cache對象來設置緩存路徑和緩存大小的。以後經過讀取後端數據的header的Cache-Control配置來決定多久更新數據。若是後彈沒有設置能夠本身配置緩存的CacheInterceptor。實現intercept方法,在裏面給Response添加Cache-Control配置。固然個性化配置Okhttp還提供了CacheConCrol來個性化配置緩存過時時間。 www.2cto.com/kf/201611/5…

  • 如何計算一張圖片大小,Lrucache 加載一張本地資源圖片,那麼它佔用的內存 = 1、圖像佔用空間的大小計算: 大小=分辨率位深/8 (位深: 一個像素所佔的內存。) 分辨率=寬高(如:1024768,640480) 位深:如24位,16位,8位 /8計算的是字節數。

例如:
一幅圖像分辨率:1024768,24位,則其大小計算以下: 大小=1024768×24/8=2359296byte=2304KB

  • SQLite、資源保存性能、總結有深度的技術點 SQLite性能優化: 一、使用Sql語句預編譯,即sql語句生成SQLiteStatement,須要傳的參數使用?佔坑。 這樣不用每次的編譯語句,變化的只是參數。

二、顯示的使用事務優化寫操做,頻繁的開閉IO是很耗性能的,用事務來提交多條語句,會先把數據緩存到系統中,而後再一次性提交更改到數據文件,此時數據文件的IO只須要開閉一次。大大提升性能。

三、使用索引提升查詢效率。

四、查詢儘可能只查詢須要的信息

五、合理調整ContentValues容量,減小擴容次數。

六、提早獲取索引,cursor.getColumnIndex放在循環外

  • Android虛擬機Dalvik和Art用什麼算法來進行垃圾回收?

  • 一、如何實現進程間通訊的總線訂閱模式?

  • 二、自定義控件的過程 www.jianshu.com/p/a5758c69e…

  • 舉例自定義GroupView:

  • 一、重寫onMeasure(),在方法裏面迭代子View,而後調用measureChild,測量每一個字View的長度和寬度,計算。而後根據父View傳來的建議寬高,和mode決定是否選擇建議寬高仍是計算的,AT_MOST酒選擇咱們計算的不然選擇建議的,就是match_parent的意思。

  • 二、重寫onLayout,迭代子View,根據measure的寬高,調用child的layout來佈局子View。

  • 三、若是要在佈局裏面設置能夠建立attr文件,在裏面建立屬性,而後在構造方法的attrs入餐獲取用戶傳來的參數來作計算。

自定義View: 重寫onDraw()方法,不要在裏面作耗時長的操做,減小建立對象。不要在裏面建立bitmap等大的對象在構造方法建立。

  • React native 和 原生的相互通訊RN->native、native->RN

(1)以引用模塊的方式調用原聲方法RN->native: 自定義module類繼承自ReactContextBaseJavaModule,重寫getName,返回react層的調用名。 建立一個方法,方法裏面使用@ReactMoudle,方法裏面能夠傳Callback callback(或者Promise promise),來返回數據給RN。 在RN層使用NativeModules調用相應模塊。示例: NativeModus.[ToastExample中getName的返回值].[ToastExample中的方法]來調用原生的方法

(2)原生調用RN native->RN:

reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(eventName,params); 再原生能夠經過 DeviceEventEmitter.addListener('EventName',(msg)=>{});來註冊監聽。

六、requestLayout、invalidate、postInvalidate

通常來講,若是View肯定自身再也不適合當前區域,好比說它的LayoutParams發生了改變,須要父佈局對其進行從新測量、佈局、繪製這三個流程,每每使用requestLayout。而invalidate則是刷新當前View,使當前View進行重繪,不會進行測量、佈局流程,所以若是View只須要重繪而不須要測量,佈局的時候,使用invalidate方法每每比requestLayout方法更高效。
   postInvalidate與invalidate方法的做用是同樣的,都是使View樹重繪,但二者的使用條件不一樣,postInvalidate是在非UI線程中調用,invalidate則是在UI線程中調用。
複製代碼

接下來咱們分析postInvalidate方法的原理。 原文連接:blog.csdn.net/a553181867/…

  • 一、另外一個進程的Service被殺死了,怎麼知道? onStartCommand() 返回START_STICKY能夠重啓一次Service。

  • 二、如何減小讀取磁盤的次數

  • 三、binder的原理,爲何只須要拷貝一次。弄懂、用binder通訊一次。

  • 四、用什麼取代SharedPreferences跨進城同步數據?
    SharedPreferences底層是經過讀寫XML來實現的,多進程併發顯然是可能出問題的,因此SharedPreferences不支持多進程。能夠用ContentProvider替代。經過ContentProvider對於數據的操做都是同步的,不過contentResolver.notifyChange通知是異步的。因此ContentProvider能夠替代SharedPreferences。

五、

  • 構建者模式的好處是什麼?(對比構造方法) 目的: 爲了將構建對象的過程和構建部件解耦開來,使得構建過程和部件的表示隔離開來。 定義: 講一個複雜的對象的構建和他的表示分離開來,使得一個形同的構建可以=建立不一樣的表示。

一、動態代理和靜態代理的區別 靜態代理類:由程序員建立或由特定工具自動生成源代碼,再對其編譯。在程序運行前,代理類的.class文件就已經存在了。 動態代理類:在程序運行時,運用反射機制動態建立而成。 blog.csdn.net/tb9125256/a…

  • 三、爲何 Activity 間傳遞對象須要序列化?
    Intent在啓動其餘組件時,會離開當前應用程序進程,進入ActivityManagerService進程(intent.prepareToLeaveProcess())
    這也就意味着,Intent所攜帶的數據要可以在不一樣進程間傳輸。
    首先咱們知道,Android是基於Linux系統,不一樣進程之間的java對象是沒法傳輸,
    因此咱們此處要對對象進行序列化,從而實現對象在 應用程序進程 和 ActivityManagerService進程 之間傳輸。

送給本身的話:

不少東西不是會用就能夠 了的,你要深刻去解剖它的原理,你須要瞭解的不是同樣東西,而是一類東西。

相關文章
相關標籤/搜索