2020年10月份面試問題記錄

映客

1.ConstraintLayout 、FrameLayout  右下方放一個view

        約束佈局,可以對他的子view,比如TextView,約束其右邊界在某某控件的右部一側,約束其底部在某某控件的底部一側,layout_constraintRight_toRightOf="parent",layout_constraintBottom_toBottomOf="parent";FrameLayout,默認其子控件都是堆疊在佈局的左上角,如果要實現將一個View放在其右下角,可以給view設置layout_gravity="right|bottom"屬性,相對其父控件居右、居底。

2.從架構層面介紹自己設計的模塊

 

3.項目中遇到多線程的問題

       

4.Recycler中onCreateViewHolder何時被調用多次 ,利用RecyclerView如何畫圓環

 

5.線程池的原理,線程個數最優分配  ,如果是無限長隊列,如何設置拒絕策略

 

6.volatile的作用

 

7.Activity生命週期方法,透明和非透明兩種

 

8.onDraw方法需要注意什麼

 

9.圖片壓縮的幾種方式

 

10.大圖片加載

 

11.jpg和png的差別

 

12.數據庫升級遇到的過什麼問題,怎麼解決?

 

TraxChina

1.String  、StringBuffer 、 StringBuilder區分

2.Invalidatefinish方法

3.是否可以在方法裏定義靜態變量

public void test(){

 Static int a = 3;

}

跟誰學

1.Android事件分發機制,dispatchTouchEvent方法返回true、false、super.dispatchTouchEvent各表示什麼意思

2.屬性動畫、和幀動畫,從性能上有何優缺點。

3.Arouter核心原理

4.Glide核心原理

5.如何從view層性能優化,TraceView如何使用

6.Activity的啓動流程,可以從哪些地方做優化

7.UI卡頓的檢查、處理

8.HashMap底層原理,ArrayList底層原理

9.兩個int類型的鏈表,合併成一個鏈表並按順序排列。

作業幫

1.ClassLoader的雙親委派機制

2.HashTable、HashMap原理

3.Arouter關聯表關係,EventBus實現原理。

4.對象的結構

5.IPC Binder機制

6.歸併排序,二叉樹遍歷

7.View.post()和handler.postDelay()實現原理

8.系統源碼有沒有留意單例的使用

9.LogUtils的封裝

10.線程池阻塞隊列的實現原理

11.WebView優化    (加載的時候先將資源緩存)

12.泛型擦除

微博一面

1.方法鎖、類鎖的區別

2.ThreadLocal的實現原理

3.一個view被繪製到頁面上的流程

4.OkHttp原理

5.事件分發流程,如果所有View都不消耗,最後事件由誰處理

6.怎樣確保A、B、C三個線程都執行完後,才執行D線程

7.觀察者模式和訂閱者模式的區別

8.UI優化

9.亮點功能

微博二面:

1.Glide緩存原理,LruCache如何實現,如果讓你自己實現該如何做?

2.內存優化都做了哪些優化?

3.Handler機制原理,可否利用handler機制監控頁面卡頓,怎麼做?

4.Dalvik和ART虛擬機差別?

5.青蛙跳箱子問題

WiFi鑰匙

1.什麼是服務,前臺服務和後臺服務有沒有了解?

2.AIDL流程

千喜鶴

1.HashMap底層原理,怎麼判斷存鏈表還是存紅黑樹?

2.ConcurrentHashMap如何使用,如何保證線程安全?

3.Handler消息機制,同步消息、異步消息、消息屏障區別,post和send的區別

4.APP繪製流程

setContentView 其內部是通過PhoneWindow將我們的佈局添加到其內部的mContentParent中。在ActivityThread的handleResumeActivity中,會調用WindowManager的addView方法將DecorView添加到WMS中,這樣DecorView被渲染到屏幕上顯示,並且可以接收屏幕觸摸事件;而WindowManager的最終實現是WindowManagerGlobal,在其setView方法中創建了一個最關鍵的對象ViewRootImpl對象,通過ViewRootImpl的setView方法,執行requestLayout()完成測量繪製,並將View添加WMS中,而且在setView中還設置了輸入事件的處理,設置了一系列的輸入管道。一個觸屏事件發生後,經過驅動層一系列計算通過Socket跨進程通知WMS,最終屏幕事件會被髮送到輸入管道里,最終調用PhoneWindow的dispatchTouchEvent,其內部的callback指的就是activity,這樣事件就到了Activity的dispatchTouchEvent中了。

5.AMS、PMS

6.6.0~10.0的適配

7.Glide使用流程,傳入Application和Activity有什麼區別

8.OKHTTP原理,攔截器加載順序

9.Retrofit的使用

10.APP啓動流程

1.ActivityA --> ActivityManagerService:我們的調用startActivity後最終交由Instrumentation的exeStartActivity方法,Instrumentation是用來做應用進程和系統進程交互的,在其方法內通過AIDL 來調用AMS的startActivity方法。

2.ActivityManagerService --> ApplicationThread:AMS只做了兩件事,一是綜合處理LaunchMode和Intent的flag標誌位,並根據處理結果生成一個目標Activity對象,二是判斷是否要爲目標對象創建一個新的進程或新的任務棧。我們在執行Instrumentation的方法時傳入了一個ApplicationThread的引用,這個類就是負責進程間通信的,AMS最終就是調用了B進程中的一個ApplicationThread引用,從而間接通知B進程進行相應操作。

3.ApplicationThread -> Activity:通過ApplicationThread引用,最終調用ActivityThread的scheduleTransaction方法,該方法通過Handler發送了一個Message,Message的obj就是啓動Activity的事務對象,最終調用事務的execute方法,最終調用ActivityThread的handleLaunchActivity方法,通過反射創建指定的Activity,最終通過Instrumentation調用其onCreate方法。

 

小紅書

1.自定義view ,在draw方法裏畫個背景,設置Wrap_content,放到一個100*100的父佈局裏,view的寬高多大

不處理wrap_content,默認是match_parent的效果,我們可以在wrap_content的時候設置一個最小默認寬高,來解決這個問題;

2.在onCreate能獲取View的寬高嗎,onResume裏可以嗎?

都不可以,在onResume方法裏,DecorView才被添加到WMS中,觸發View的繪製。

在onCreate中

3.EventBus原理,EventBus是跨進程的嗎?

不是跨進程的。

首先在EventBus的register方法中通過反射遍歷註冊對象的所有方法,將帶有@Subscribe標籤的方法放入到一個列表裏,最後以註冊對象爲key,以列表爲value放入一個HashMap中。

訂閱事件和訂閱者之間也有一個關聯關係表,當post執行的時候會查找訂閱了該Event的訂閱者並調用其方法。

postSticky的時候會將event和event.getClass保存起來,當有新事件要註冊監聽時,遍歷map,如果有會執行一次回調。

4.在ListView和RecyclerView中LayoutInflater的inflate方法,最後一個布爾值設置什麼,設置爲true會有問題嗎?

  1. root不能爲空,否則佈局文件中設置的佈局參數不會起作用
  2. attach不能設置爲true,否則inflate返回的佈局爲RecylerView,而不是我們希望返回的自定義佈局對象
  3. 必須爲RecylerView指定LayoutManager,否則會拋出異常

就拿我們的Adapter來說吧,在創建item佈局時,有下列幾種情況:

  • inflate(R.layout.xxx,null);
  • inflate(R.layout.xxx,parent,false);
  • inflate(R.layout.xxx,parent,true);

那麼就講一下這三種情況把。

首先,inflate(R.layout.xxx,null) 。這是最簡單的寫法,這樣生成的佈局就是根據http://R.layout.xxx返回的View。要知道,這個佈局文件中的寬高屬性都是相當於父佈局而言的。由於沒有指定parent,所以他的寬高屬性就失效了,因此不管你怎麼改寬高屬性,都無法按你想象的那樣顯示。

然後,inflate(R.layout.xxx,parent,false)。相較於前者,這裏加了父佈局,不管後面是true還是false,由於有了parent,佈局文件的寬高屬性是有依靠了,這時候顯示的寬高樣式就是佈局文件中的那樣了。

最後,inflate(R.layout.xxx,parent,true)。這樣……等等,報錯了???哦,不要驚奇,分析一下原因:首先,有了parent,所以可以正確處理佈局文件的寬高屬性。然後,既然attachToRoot爲true,那麼根據上面的源碼就會知道,這裏會調用root的addView方法。而如果root是listView或者RecyclerView都會報錯。

adpater裏面不要用true。那麼什麼時候用true呢?答案是fragment。在爲fragment創建佈局時,如果爲true,那麼這個佈局文件就會被添加到父activity中盛放fragment的佈局中

5.自定義view滑動的時候,通過設置什麼方法實現滑動位置。

   在MOVE事件裏獲取座標,然後設置setX(),setY()

6.啓動優化都做了哪些?

影響啓動速度的因素有:

  1. 高耗時任務:比如三方框架初始化、MultiDex的加載、大文件讀取導致c阻塞;
  2. 複雜的View層級:嵌套的Layout過多,導致View渲染過程中,影響Measure、layout的執行速度;
  3. 類過於複雜:Java對象創建需要一定的時間,如果一個類結構特別複雜,new一個對象也比較耗資源,特別是單例;
  4. 主題及Activity配置:由於主題切換,可能導致白屏,或者點了icon,過了一會才啓動頁面;

解決方案:

  1. 優化方法數:通過配置minify選項,打包時刪除掉沒有用的方法,少用一些不必要的框架,或者找輕量級框架;
  2. Dex懶加載,將dex的加載放到Splash頁面;
  3. 三方框架放到線程池裏初始化,或者通過異步工作協程;
  4. 一些優先級低的三方庫初始化,我們可以通過Looper.myQueue().addIdleHandler(),向MessageQueue中插入一條IdleHandler,IdleHandler只會在主線程空閒時纔會被Looper從隊列中取出來執行。
  5. 避免在APP啓動的時候做數據庫的耗時任務;
  6. 通過Studio工具Layout Inspector,分析層級嵌套,優化佈局;
  7. 使用沒有ActionBar、TitleBar的主題,相當於在DecorView裏少了一個view,所以能有效提高啓動速度;(全屏主題,並設置背景爲layer-list,這樣不 生成view,減少view繪製時間)

7.怎麼優化Activity的啓動速度,怎麼優化跨進程的Activity啓動速度

通過Studio工具Layout Inspector,分析層級嵌套,優化佈局;在onPause方法裏少做操作;在第二個頁面裏儘量避免大對象的使用;

8.Arouter原理,Arouter怎麼生成java文件

Arouter使用Apt技術,在編譯階段將路由path和組件類生成具有映射關係類,Arouter根據用戶請求的postcard,需要要跳轉的目標地址。

Arouter採用了分組+按需加載的思想,分組就是在原來的path到目標的map外,再加一個新的map,這個map保存了組名到組加載器的映射關係,組加載器是一個類,可以加載組內的path到目標的映射關係。按需加載時,當調用navigation方法時,線程內存裏的path到目標的映射表去找(第一次通常爲空),找不到然後再從通過組名找到對應的組加載器,組加載器加載改組內的路由映射關閉,並將其添加到緩存中。

9.ConcurrentHashMap支持併發讀嗎,支持併發寫嗎?

10.事件分發流程。

11.HashMap插入鏈表的時候,是在表頭插入還是表尾插入?

12.Kotlin

13.Glide的加載流程

14.二叉樹遍歷

前、中、後遍歷,以根節點父節點的遍歷順序來區分的,如果先遍歷父節點,再遍歷左子樹、右子樹就是前序遍歷;

15.Android做了哪些適配,8.0通知欄適配,和10.0適配

6.0隱私權限動態申請;7.0的FileProvider,和不支持權限組申請;

Android 8.0通知欄消息分渠道,如果不適配,消息通知可能無法完全彈出,所以一定要適配。我們可以創建自己的通知渠道,然後在自定義通知的時候設置下發到哪個渠道。

Android8.0應用圖標適配,將其分爲前景層和背景層。

Android9.0默認不支持Http協議;要求啓動前臺服務的時候要先請求FOREGROUND_SERVICE權限。

Android10.0設備id非系統APP無法獲取,可以通過硬件信息加上一些計算生成一個;取消讀寫本地文件的權限,新增獲取系統媒體文件的權限;

 

16.怎樣啓動一個Activity,是new出來的嗎?

ActivityThread調用performLaunchActivity方法,通過反射創建Activity對象,並執行其attach方法,Window就是在attach方法中被創建的;

17.Http和Https區別,抓包方式有差異嗎,Http的post請求和get請求能抓包嗎,都是明文傳輸嗎?

阿里影業

1.Handler機制裏Message是怎麼獲取的,Message類似什麼設計模式

2.session機制過期,後續的處理邏輯是怎樣的,要注意哪些(比如多個請求session失效,請求隊列存儲)

3.Kotlin、Jetpack

4.vue知識

5.Okhttp裏線程池的阻塞隊列和兩個隊列怎麼配合使用的?

6.SharePreferences是線程安全的嗎,是進程安全的嗎,commit和apply的區別?

sp是線程安全的,谷歌使用3把鎖保證多線程下sp的寫操作安全;commit是在UI線程做提交,apply是在子線程中操作,設計apply的初衷是爲了解決ANR,但也無法完全規避,當Activity.onStop()以及Service處理onStop等相關方法時,則會執行 QueuedWork.waitToFinish()等待所有的等待鎖釋放,因此如果SharedPreferences一直沒有完成更新任務,有可能會導致卡在主線程,最終超時導致ANR;sp沒有使用跨進程鎖,所以是進程不安全的,跨進程讀寫會有數據丟失的可能,我們可以使用文件鎖,保證同一時刻只有一個進程在操作sp,也可以使用谷歌倡導的跨進程通信組件ContentProvider,其他進程通過定製ContentProvider,用於訪問sp,同樣也能保證sp的進程安全。同時sp在寫的時候也有文件備份機制,能夠保證之前存儲的數據恢復。

滴滴

startActivity是同步還是異步,哪個線程給哪個線程發消息?

Hander能發送同樣的消息嗎

Postdelay 1秒和10秒,誰先執行

按執行時間插入排序,所以1秒的先執行,只是他只能保證1秒後執行,不能保證正好在1秒的時候執行。

Aidl是同步還是異步

類點class是什麼類型的對象

在主線程做耗時操作會報什麼異常

如果在主線程做網絡請求,會拋NetWorkOnMainThreadException異常,如果做其他耗時操作比如遍歷大數組,IO,會導致ANR。

對象鎖類鎖會不會互相影響

靜態變量是在什麼時候被加載到內存的

Retroit livedata

Socket 和aidl差別

掌閱

有沒有遇到過https安全性問題

證書篡改、DNS劫持

美團

1.LeakCanary原理

它通過監控Activity的聲明週期,當activity調用onDestroy方法時,將activity對象包裝到弱引用中,如果該弱引用對象被回收,弱引用對象就會被放到ReferenceQueue隊列中,通過監控隊列裏的內容就能檢查到Activity是否被真正回收。

2.OKHTTP相比HTTPURLConnection的優點是哪裏

透明的gzip壓縮;各種攔截器;支持多種類型的數據緩存;

3.TCP和UDP的區別

有沒有遇到過線上OOM的情況

一般批量圖片加載的時候,或者加載大圖時,容易OOM,線上遇到過窗體泄漏、棧溢出的情況(遞歸的結束條件沒處理好),線程池使用時有可能OOM。

插件化原理

一般實現方式有反射、hook等方案,插件化原理多用hook方案,比如hook主IActivityManager,先在清單文件裏佔坑,再在合適時候將目標對象塞到啓動佔坑頁面的Intent中,在將要啓動佔坑頁面的時候再修改具體要跳轉的Activity。

火花思維

深拷貝、淺拷貝區別

引用拷貝:創建一個指向對象的引用變量的拷貝,它指向同一個對象。

對象拷貝:創建對象本身的一個副本。對象拷貝的方法,調用對象的clone方法,比如Student stu2 = stu1.clone();

深拷貝和淺拷貝都是對象拷貝,區別如下:

淺拷貝,拷貝原對象裏的屬性,但如果屬性有對象屬性,那麼只是拷貝對象屬性的引用;深拷貝的話,是拷貝原對象的所有,包括其屬性是對象類型的,也會clone新的地址。

什麼是泛型,作用是什麼?

泛型字面意思就是廣泛的類型,可以是接口、類、方法應用於非常廣泛的類型,它使代碼和他們操作的數據類型不再綁定在一起,同一套代碼可以用於多種數據類型。降低耦合性、提高代碼複用性、安全性。

編譯的時候,編譯器會將泛型轉爲非泛型的對象,將泛型擦除,替換爲Object,插入必要的強制類型轉換。

什麼是反射?

反射就是讓我們獲得一個類的所有信息。

HashMap相關問題

1.HashMap的初始容量是怎麼計算的?

通過位運算,將傳入的參數右移一位、兩位、四位、8位這樣,然後做異或,計算出第一個大於該參數的2的n次冪。HashMap初始容量是16,初始擴容因子是0.75,之所以用位運算,是因爲其效率高。

2.hash函數是怎麼計算的?

static final hash(Object key){
    int h ;
    return (key == null)? 0 : (h = key.hashCode()^(h >>> 16));
}

key.hashCode()返回的是一個int類型,也即32位的數。然後將其右移16位後做異或(異或就是相同返回0,不同返回1)。

hash函數計算出的結果值,再和(容量-1)做與運算,便得出下標索引。

3.put過程是怎樣的?

先獲取位置,然後獲取位置上的值,如果沒有則放置上,如果有,則遍歷節點,通過key判斷是否有和其相同key的Node,如果有直接覆蓋,如果沒有,則採用頭插法,插入元素。

4.什麼時候擴容,機制時怎麼實現的?

HashMap容量達到容器長度*擴容因子時,就會擴容。原容量左移一位,也即是原容量的二倍;遍歷原數組,其中每個item變成遊離的狀態,重新計算各個元素下標,如果下標處沒有值,直接複製,如果有值,變成頭結點,之前的值變成子節點。

5.鏈表過長,每次遍歷這個鏈表,會影響性能嗎?

紅黑樹:能夠減小查找範圍,不用從頭到尾遍歷。紅黑樹是一個搜索樹,是一種接近平衡的二叉樹。

紅黑樹的特性:每個節點要麼是黑色,要麼是紅色;根節點是黑色;如果節點是紅色,那麼它的子節點必須是黑色(反之不一定成立);從根節點到葉節點或者空子節點的每條路徑,都包含相同數目的黑色節點;

6.HashMap,線程不安全,可能出現兩種情況,一可能同一個位置的值被覆蓋;二可能會在擴容的過程中拋異常;

Android中setOnTouchListener、onTouchEvent、setOnClickListener的調用順序?

setOnTouchListener  ---->   onTouchEvent   ---->    setOnClickListener。setOnTouchEvent的onTouch事件,返回true表示不想下傳遞,就不進入到onTouchEvent中了。

onTouchEvent的返回值,返回true、false、super.onTouchEvent()的區別?

true,表示消費此次時間,false即不消費;super.onTouchEvent()即直接交由父view的onTouchEvent()方法。

LeakCanary原理

1.通過ActivityLifeCycleCallbacks監聽Activity的聲明週期,在其onDestroy被調用的時候,將Activity包裝成一個WeakReference對象,並在弱引用的構造方法裏傳入一個ReferenceQueue。

2.同時這個弱引對象會標記一個隨機數key,並將這個key存儲在強引用set集合裏;

3.當系統gc的時候,會把被回收對象的弱引用都添加到ReferenceQueue中。主動觸發gc,遍歷隊列,將將隊列裏的弱引用對象的key從Set集合裏移出。遍歷完之後,仍然在Set集合裏的key,對應的WeakReference所包含的對象就是內存泄漏的對象。

BlockCanary原理

如果主線程被卡住,則其實是在Looper的loop方法裏的 msg.target.dispatchMessage(msg)耗時,我們可以記錄該方法執行前後的時間戳,得到差值再跟設置的閥值對比,大於閥值則dump出堆棧信息,以及CPU信息。

1.ContentProvider

它主要用來實現跨進程間數據共享,是一套安全的訪問機制,Android通過ContentProvider實現圖片、音頻、視頻數據共享。底層使用的是Binder機制。

1.Service

本地服務:指的是服務和啓動服務的activity在同一個進程中

遠程服務; 指的是服務和啓動服務的activity不在同一個進程中。

啓動本地服務用的是顯式啓動; 遠程服務的啓動要用到隱式啓動。

3.BroadCastReceiver

普通廣播:完全異步執行的廣播,當廣播發出後,幾乎所有廣播接收器都會在同一時間收到這條廣播。

有序廣播:是一種同步執行的廣播,廣播發出後,只會有一個廣播接收器能接收到廣播消息,當這個廣播接收器接收到後,廣播纔會繼承傳遞,對於有序廣播有了先後順序,在Android中提供了優先級的屬性(priority)來控制先後,有序廣播中可以截斷廣播,不被下一個廣播接收器接收,這是有序廣播的特點。

4.線程池的shutdown和shutDownNow區別

shutDown是將當前執行的線程狀態置爲SHUTDOWN狀態,而且不再往線程池裏添加任務,只在執行的任務執行完畢後才退出;shutDownNow是將當前執行線程狀態都置爲STOP,並試圖停止線程執行,而且不再往線程池裏添加任務,終止線程的辦法是通過調用Thread.interrupt()方法來實現的,但如果線程中沒有sleep、wait、Condition、定時鎖等,則無法響應中斷,所以仍然會執行下去。

阿里二面

1.final修飾的變量,如果是對象,對象裏的屬性能修改嗎?

final修飾的變量,如果是基本數據類型,則初始化後不能再被修改,如果是引用類型,初始化後則不能再指向別的對象,但他指向的對象,其內部屬性是可以更改的。

2.重寫equal和hashCode需要注意什麼?

==比較的是兩個引用的指針地址是否相等;equal方法則比較的是兩個對象的內容是否相等,不過Object的equal方法也是==判斷,比的是地址。

如果只重寫equal不重寫hashCode,則在一些集合容器裏,相同的對象會散列到不同的位置,導致相同對象不能覆蓋的問題。

小米

1.自己對自己的定位評價、能給團隊帶來什麼?

2.WebView + Recycler這種如何實現?

3.A (standard)、B(standard)、C(singleTask) D(singleInstance)、B、C,頁面銷燬的先後順序

C銷燬後,同棧裏的A銷燬,然後纔是單獨棧裏的D銷燬

4.一個大文件裏有很多很多個數,沒法一直讀取到內存,請找出最大的數?

5.強、軟、弱、虛的作用

強引用,只要對象和引用直接沒有切斷聯繫(沒有置null),即便內存不足,也不會被回收,會拋OOM;

軟引用,只有內存不足的時候纔會被GC回收,常用來實現緩存技術,圖片緩存、瀏覽器緩存等;

弱引用,GC時被回收,可以用來監控對象是否被回收;虛引用,隨時可能被回收,主要用於監控對象是否從內存中刪除。

6.ConcurrentHashMap 1.7和1.8的改動,爲什麼要這麼改?

7.Handler機制裏,入隊列不俺順序可以不?

百度

1.MVC,MVP、MVVM區別

MVC:View觸發事件,傳遞到Controller層,Controller層完成業務邏輯後,調用Model層更改狀態,Model處理完後將數據傳遞給View,View更新。所有的通信都是單向的。

MVP:以P層爲核心,從Model中取數據,並通過接口回調的形式填充到View中,Model和View不再有聯繫,P分別於View和Model保持雙向通信。

MVVM:它與MVP類似,V層和Model層不互相通信,ViewModel層取代了Presenter層,不同點是View和ViewModel採用雙向綁定,View的變動自動反應在ViewModel上。

2.Retrofit的使用

3.RxJava

RxJava把複雜的邏輯串成一條線,很簡潔的實現異步操作。RxJava的觀察者模式,Observable是被觀察者,Observer是觀察者,通過subscribe()方法實現訂閱關係。類比Android中的點擊事件也是觀察者模式,View是被觀察者,OnClickListener是觀察者,setOnClickListener來實現訂閱,也就是被觀察者持有觀察者的引用,當被觀察者的某種狀態改變時,調用觀察者的回調方法做通知。RxJava與之不同的是,他不但有onNext()方法,還有onComplete()和onError()方法來處理事件隊列是否正常執行,後兩個方法是互斥執行的。

RxJava默認的規則中,事件的發送和處理都是在同一個線程中。但觀察者模式本身的目的就是”後臺處理,前臺回調“的異步機制,RxJava實現異步的另外一個概念是Scheduler。

  • Schedulers.immediate(): 直接在當前線程運行,相當於不指定線程。這是默認的 Scheduler
  • Schedulers.newThread(): 總是啓用新線程,並在新線程執行操作。
  • Schedulers.io(): I/O 操作(讀寫文件、讀寫數據庫、網絡信息交互等)所使用的 Scheduler。行爲模式和 newThread() 差不多,區別在於 io() 的內部實現是是用一個無數量上限的線程池,可以重用空閒的線程,因此多數情況下 io() 比 newThread() 更有效率。不要把計算工作放在 io() 中,可以避免創建不必要的線程。

map()方法是一對一的對象轉換,flatMap()是一對多的轉換。

小米二面

1.EventBus的優點是什麼,爲什麼不用廣播,EventBus怎麼實現切線程?

2.靜態廣播和動態廣播的註冊時機分別是什麼時候?

3.EventBus使用反射影響效率,這個問題有沒有得到解決?

4.如何實現字母索引,繼承View可以實現嗎?

5.Sysnchronized與ReentrantLock實現原理有何不同?

6.volatile是線程安全的嗎?

7.startActivity的時候有哪個類加載器去加載?

PathClassLoader

8.APP啓動時發生的事情?

1.先去從zygote進程fork一個進程。

2.fork進程後,會調用ActivityThread的main()方法,new出一個ActivityThread對象,並且會把它與Application做關聯,即attach()方法;

3.attach會引發一些列的事件,這個過程會先後創建ClassLoader、appContext和Application,把Application和ActivityThread關聯到一起;

4.調用Instrumentation的callApplicationOnCreate(app)觸發Application的onCreate方法;

9.Synchronized和lock的底層實現原理

Synchronized是JVM層面的鎖,映射到字節碼指令時,會產生兩個指令,monitorEnter、monitorExit。當線程遇到monitorEnter的時候就會嘗試獲取鎖,monitorExit釋放鎖。Synchronized是悲觀鎖,而Lock底層是CAS和Volatile來實現。競爭激烈的環境下用lock鎖,競爭不激烈建議用Synchronized,因爲Synchronized鎖不可降級,經歷一個短暫的高峯之後,synchronized所有的鎖都會成爲重量級鎖,這個時候效率就會降低。

瓜子

1.組件間如何通信,大文件如何共享讀寫

2.通過腳本轉換格式

3.介紹一次網絡通信過程,以及可能遇到的問題

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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