臨近雙11.有了這些中高端面試專題.大廠還會遠嗎?

這裏講的是大公司須要用到的一些高端Android技術,這裏專門整理了一個文檔,但願你們均可以看看。這些題目有點技術含量,須要好點時間去研究一下的。java

爲此我吧這些知識整理成了一個983的PDF,從基礎到進階。含有BATJ.字節跳動面試專題,算法專題,高端技術專題,混合開發專題,java面試專題,Android,Java小知識,到性能優化.線程.View.OpenCV.NDK等應有盡有。還有輔之相關的視頻+學習筆記
android

(更多完整項目下載。未完待續。源碼。圖文知識後續上傳github。)
能夠點擊
github.com/xiangjiana/…c++

獲取完整PDFgit

一.圖片

一、圖片庫對比
二、LRUCache原理

LruCache是個泛型類,主要原理是:把最近使用的對象用強引用存儲在LinkedHashMap中,當緩存滿時,把最近最少使用的對象從內存中移除,並提供get/put方法完成緩存的獲取和添加。LruCache是線程安全的,由於使用了synchronized關鍵字。github

當調用put()方法,將元素加到鏈表頭,若是鏈表中沒有該元素,大小不變,若是沒有,需調用trimToSize方法判斷是否超過最大緩存量,trimToSize()方法中有一個while(true)死循環,若是緩存大小大於最大的緩存值,會不斷刪除LinkedHashMap中隊尾的元素,即最少訪問的,直到緩存大小小於最大緩存值。當調用LruCache的get方法時,LinkedHashMap會調用recordAccess方法將此元素加到鏈表頭部。面試

三、圖片加載原理
四、本身去實現圖片庫,怎麼作?
五、Glide源碼解析

1)Glide.with(context)建立了一個RequestManager,同時實現加載圖片與組件生命週期綁定:在Activity上建立一個透明的ReuqestManagerFragment加入到FragmentManager中,經過添加的Fragment感知Activty`Fragment的生命週期。由於添加到Activity中的Fragment會跟隨Activity的生命週期。在RequestManagerFragment中的相應生命週期方法中經過liftcycle傳遞給在lifecycle中註冊的LifecycleListener`算法

2)RequestManager.load(url) 建立了一個RequestBuilder<T>對象 T能夠是Drawable對象或是ResourceTypesql

3 )RequestBuilder.into(view)-->into(glideContext.buildImageViewTarget(view, transcodeClass))返回的是一個DrawableImageViewTarget, Target用來最終展現圖片的,buildImageViewTarget-->ImageViewTargetFactory.buildTarget()根據傳入class參數不一樣構建不一樣的Target對象,這個Class是根據構建Glide時是否調用了asBitmap()方法,若是調用了會構建出BitmapImageViewTarget,不然構建的是GlideDrawableImageViewTarget對象。數據庫

-->GenericRequestBuilder.into(Target),該方法進行了構建Request,並用RequestTracker.runRequest()編程

Request request = buildRequest(target);//構建Request對象,Request是用來發出加載圖片的,它調用了buildRequestRecursive()方法以,內部調用了GenericRequest.obtain()方法
target.setRequest(request);
lifecycle.addListener(target);
requestTracker.runRequest(request);//判斷Glide當前是否是處於暫停狀態,若不是則調用Request.begin()方法來執行Request,不然將Request添加到待執行隊列裏,等暫停態解除了後再執行
複製代碼

-->GenericRequest.begin()

4)onSizeReady()·--> Engine.load(signature, width,height, dataFetcher, loadProvider, transformation, transcoder,
priority, isMemoryCacheable,diskCacheStrategy, this) --> a)先構建EngineKey; b)loadFromCache從緩存中獲取EngineResource,若是緩存中獲取到cache就調用cb.onResourceReady(cached); c)若是緩存中不存在調用loadFromActiveResources從active中獲取,若是獲取到就調用cb.onResourceReady(cached);d)若是active中也不存在,調用EngineJob.start(EngineRunnable), 從而調用decodeFromSource()/decodeFromCache()-->若是是調用decodeFromSource()-->ImageVideoFetcher.loadData()-->HttpUrlFetcher()調用HttpUrlConnection進行網絡請求資源-->得於InputStream()後,調用decodeFromSourceData()-->loadProvider.getSourceDecoder().decode()方法解碼-->GifBitmapWrapperResourceDecoder.decode()-->decodeStream()先從流中讀取2個字節判斷是GIF仍是普通圖,如果GIF調用decodeGifWrapper()來解碼,如果普通靜圖則調用decodeBitmapWrapper()來解碼-->bitmapDecoder.decode()

六、Glide使用什麼緩存?

1) 內存緩存LruResourceCache(memory)+弱引用activeResources

Map<Key, WeakReference<EngineResource<?>>> activeResources正在使用的資源,當acquired變量大於0,說明圖片正在使用,放到activeResources弱引用緩存中,通過release()後,acquired=0,說明圖片再也不使用,會把它放進LruResourceCache

2)磁盤緩存DiskLruCache,這裏分爲Source(原始圖片)和Result(轉換後的圖片)

第一次獲取圖片,確定網絡取,而後存active\disk中,再把圖片顯示出來,第二次讀取相同的圖片,並加載到相同大小的imageview中,會先從memory中取,沒有再去active中獲取。若是activity執行到onStop時,圖片被回收,active中的資源會被保存到memory中,active中的資源被回收。當再次加載圖片時,會從memory中取,再放入active中,並將memory中對應的資源回收。

之因此須要activeResources,它是一個隨時可能被回收的資源,memory的強引用頻繁讀寫可能形成內存激增頻繁GC,而形成內存抖動。資源在使用過程當中保存在activeResources中,而activeResources是弱引用,隨時被系統回收,不會形成內存過多使用和泄漏。

七、Glide內存緩存如何控制大小?

Glide內存緩存最大空間(maxSize)=每一個進程可用最大內存

0.4(低配手機是 每一個進程可用最大內存
0.33)

磁盤緩存大小是250MB int DEFAULT_DISK_CACHE_SIZE = 250 * 1024 * 1024;

二網絡和安全機制

1.網絡框架對比和源碼分析
2.本身去設計網絡請求框架,怎麼作?
3.okhttp源碼
4.網絡請求緩存處理,okhttp如何處理網絡緩存的;

(1)網絡緩存優先考慮強制緩存,再考慮對比緩存

  • 首先判斷強制緩存中的數據的是否在有效期內。若是在有效期,則直接使用緩存。若是過了有效期,則進入對比緩存。
  • 在對比緩存過程當中,判斷ETag是否有變更,若是服務端返回沒有變更,說明資源未改變,使用緩存。若是有變更,判斷Last-Modified。
  • 判斷Last-Modified,若是服務端對比資源的上次修改時間沒有變化,則使用緩存,不然從新請求服務端的數據,並做緩存工做。

(2)okhttp緩存

開啓使用Okhttp的緩存其實很簡單,只須要給OkHttpClient對象設置一個Cache對象便可,建立一個Cache時指定緩存保存的目錄和緩存最大的大小便可。

//新建一個cache,指定目錄爲外部目錄下的okhttp_cache目錄,大小爲100M
Cache cache = new Cache(new File(Environment.getExternalStorageDirectory() + "/okhttp_cache/"), 100 * 1024 * 1024);
//將cache設置到OkHttpClient中,這樣緩存就開始生效了。
OkHttpClient client = new OkHttpClient.Builder().cache(cache).build();
複製代碼

相關的類有:
1)CacheControl( HTTP中的Cache-Control和Pragma緩存控制):指定緩存規則

2)Cache(緩存類)

3)DiskLruCache(文件化的LRU緩存類)
(1)讀取緩存:先獲限OkHttpClient的Cache緩存對象,就是上面建立OkHttpClient設置的Cahce; 傳Request請求到Cache的get方法查找緩存響應數據Response;構造一個緩存策略,再調用它的get去決策使用網絡請求仍是緩存響應。若使用緩存,它的cacheResponse不爲空,networkRequest爲空,用緩存構造響應直接返回。若使用請求,則cacheResponse爲空,networkRequest不爲空,開始網絡請求流程。

Cache的get獲取緩存方法,計算request的key值(請求url進行md5加密),根據key值去DisLruCache查找是否存在緩存內容,存則則建立繪存Entry實體。ENTRY_METADATA表明響應頭信息,ENTRY_BODY表明響應體信息。若是緩存存在,在指定目錄下會有兩個文件****.0 *****.1分別存儲某個請求緩存響應頭和響應體信息。

CacheStrategy的get方法

  • 若緩存響應爲空
  • 請求是https但緩存響應沒有握手信息;
  • 請求和緩存響應都是不可緩存的;
  • 請求是onCache,而且又包含if-Modified-Since或If-None-Match則不使用緩存; 再計算請求有效時間是否符合響應的過時時間,若響應在有效範圍內,則緩存策略使用緩存,不然建立一個新的有條件的請求,返回有條件的緩存策略。

(2)存儲緩存流程:從HttpEnginereadResponse()發送請求開始,判斷hasBody(userResponse),若是緩存的話,maybeCache()緩存響應頭信息,unzip(cacheWritingResponse(storeRequest, userResponse))緩存響應體。

5.從網絡加載一個10M的圖片,說下注意事項
6.TCP的3次握手和四次揮手
7.TCP與UDP的區別
8.TCP與UDP的應用*
9.HTTP協議
10.HTTP1.0與2.0的區別
11.HTTP報文結構
12.HTTP與HTTPS的區別以及如何實現安全性
13.如何驗證證書的合法性?
14.https中哪裏用了對稱加密,哪裏用了非對稱加密,對加密算法(如RSA)等是否有了解?
15.client如何肯定本身發送的消息被server收到?
16.談談你對WebSocket的理解
17.WebSocket與socket的區別
18.談談你對安卓簽名的理解。
19.請解釋安卓爲啥要加簽名機制?**
20.視頻加密傳輸
21.App 是如何沙箱化,爲何要這麼作?
22.權限管理系統(底層的權限是如何進行 grant 的)?

三.數據庫

1.sqlite升級,增長字段的語句
2.數據庫框架對比和源碼分析
3.數據庫的優化
4.數據庫數據遷移問題

四.算法

1.排序算法有哪些?
2.最快的排序算法是哪一個?
3.手寫一個冒泡排序
4.手寫快速排序代碼
5.快速排序的過程、時間複雜度、空間複雜度
6.手寫堆排序
7.堆排序過程、時間複雜度及空間複雜度
8.寫出你所知道的排序算法及時空複雜度,穩定性
9.二叉樹給出根節點和目標節點,找出從根節點到目標節點的路徑
10.給阿里2萬多名員工按年齡排序應該選擇哪一個算法?
11.GC算法(各類算法的優缺點以及應用場景)
12.蟻羣算法與蒙特卡洛算法
13.子串包含問題(KMP 算法)寫代碼實現
14一個無序,不重複數組,輸出N個元素,使得N個元素的和相加爲M,給出時間複雜度、.空間複雜度。手寫算法**
15.萬億級別的兩個URL文件A和B,如何求出A和B的差集C(提示:Bit映射->hash分組->多文件讀寫效率->磁盤尋址以及應用層面對尋址的優化)
16.百度POI中如何試下查找最近的商家功能(提示:座標鏡像+R樹)。
17.兩個不重複的數組集合中,求共同的元素。
18.兩個不重複的數組集合中,這兩個集合都是海量數據,內存中放不下,怎麼求共同的元素?
19.一個文件中有100萬個整數,由空格分開,在程序中判斷用戶輸入的整數是否在此文件中。說出最優的方法
20.一張Bitmap所佔內存以及內存佔用的計算

一張圖片(bitmap)佔用的內存影響因素:圖片原始長、寬,手機屏幕密度,圖片存放路徑下的密度,單位像素佔用字節數

bitmapSize=圖片長度

(inTargetDensity手機的density / inDensity圖片存放目錄的density)
寬度
(手機的inTargetDensity / inDensity目標存放目錄的density)
單位像素佔用的字節數(圖片長寬單位是像素)

1)圖片長寬單位是像素:單位像素字節數由其參數
BitmapFactory.Options.inPreferredConfig變量決定,它是Bitmap.Config類型,包括如下幾種值:ALPHA_8圖片只有alpha值,佔用一個字節;ARGB_4444一個像素佔用2個字節,A\R\G\B各佔4bitsARGB_8888一個像素佔用4個字節,A\R\G\B各佔8bits(高質量圖片格式,bitmap默認格式);ARGB_565一個像素佔用2字節,不支持透明和半透明,R佔5bit, Green佔6bit, Blue佔用5bit. 從Android4.0開始該項無效。

2)inTargetDensity 手機的屏幕密度(跟手機分辨率有關係)

inDensity原始資源密度(mdpi:160; hdpi:240; xhdpi:320; xxhdpi:480; xxxhdpi:640

當Bitmap對象在不使用時,應該先調用recycle(),再將它設置爲null,雖然Bitmap在被回收時可經過BitmapFinalizer來回收內存。但只有系統垃圾回收時纔會回收。Android4.0以前,Bitmap內存分配在Native堆中,Android4.0開始,Bitmap的內存分配在dalvik堆中,即Java堆中,調用recycle()並不能當即釋放Native內存。

21. 2000萬個整數,找出第五十大的數字?
22.燒一根不均勻的繩,從頭燒到尾總共須要1個小時。如今有若干條材質相同的繩子,問如何用燒繩的方法來計時一個小時十五分鐘呢?
23.求1000之內的水仙花數以及40億之內的水仙花數
24. 5枚硬幣,2正3反如何劃分爲兩堆而後經過翻轉讓兩堆中正面向上的硬8幣和反面向上的硬幣個數相同
25.時針走一圈,時針分針重合幾回
26*.NN的方格紙,裏面有多少個正方形
27.x個蘋果,一天只能吃一個、兩個、或者三個,問多少天能夠吃完?

五.插件化、模塊化、組件化、熱修復、增量更新、Gradle

1.對熱修復和插件化的理解
2.插件化原理分析
3.模塊化實現(好處,緣由)
4.熱修復,插件化
5.項目組件化的理解
6.描述清點擊 Android Studio 的 build 按鈕後發生了什麼

六.架構設計和設計模式

1.談談你對Android設計模式的理解
2.MVC MVP MVVM原理和區別
3.你所知道的設計模式有哪些?
4.項目中經常使用的設計模式
5.手寫生產者/消費者模式
6.寫出觀察者模式的代碼
7.適配器模式,裝飾者模式,外觀模式的異同?
8.用到的一些開源框架,介紹一個看過源碼的,內部實現過程。
9.談談對RxJava的理解

RxJava是基於響應式編程,基於事件流、實現異步操(相似於Android中的AsyncTaskHandler做用)做的庫,基於事件流的鏈式調用,使得RxJava邏輯簡潔、使用簡單。RxJava原理是基於一種擴展的觀察者模式,有四種角色:被觀察者Observable 觀察者Observer 訂閱subscribe 事件Event。RxJava原理可總結爲:被觀察者Observable經過訂閱(subscribe)按順序發送事件(Emitter)給觀察者(Observer), 觀察者按順序接收事件&做出相應的響應動做。

RxJava中的操做符:

1)defer():直到有觀察者(Observer)訂閱時,纔會動態建立被觀察者對象(Observer)&發送事件,經過Observer工廠方法建立被觀察者對象,每次訂閱後,都會獲得一個剛建立的最新的Observer對象,能夠確保Observer對象裏的數據是最新的。defer()方法只會定義Observable對象,只有訂閱操做纔會建立對象。

Observable<T> observable = Observable.defer(new Callable<ObservableSource<? extends T>>() {
    @Override
    public ObservableSource<? extends T> call() throws Exception {
        return Observable.just();
    }
}
複製代碼

2)timer() 快速建立一個被觀察者(Observable),延遲指定時間後,再發送事件

Observable.timer(2, TimeUnit.SECONDS)//也能夠自定義線程timer(long, TimeUnit, Scheduler)
    .subscribe(new Observer<Long>() {
        @Override
        public void onSubscribe(Disposable d) {
        }
        ...
 
     });
複製代碼

3) interval() intervalRange() 快速建立一個被觀察者對象(Observable),每隔指定時間就發送事件

//interval三個參數,參數1:第一次延遲時間  參數2:間隔時間數字   參數3:時間單位
Observable.interval(3, 1, TimeUnit.SECONDS).subscribe();
//intervalRange五個參數,參數1:事件序列起始點  參數2:事件數量  參數3:第一次延遲時間 參數4:間隔時間數字   參數5:時間單位
Observable.intervalRange(3, 10, 2, 1, TimeUnit.SECONDS).subscribe();
RxJava的功能與原理實現
複製代碼
10.Rxjava發送事件步驟:

1)建立被觀察者對象Observable&定義須要發送的事件

Observable.create(new ObservableOnSubscribe<T>(){
    @Override
    public void subscribe(ObservableEmitter<T> emitter) throws Exception {
        //定義發送事件的行爲
    }
});
複製代碼

Observable.create()方法實際建立了一個ObservableCreate對象,它是Observable的子類,傳入一個ObservableOnSubscribe對象,複寫了發送事件行爲的subscribe()方法。
2)建立觀察者對象Observer&定義響應事件的行爲

Observer observer = new Observer<T>() {
 
    @Override
    public void onSubscribe(Disposable d){//Disposable對象可用於結束事件
        //默認最早調用
    }
    
    @Override
    public void onNext(T t){
    
    }
 
    @Override
    public void onError(Throwable d){
    
    }
 
    @Override
public void onComplete(){
    
    }
}
複製代碼

3)經過subscribe()方法使觀察者訂閱被觀察者

Observable.subscribe(Observer observer);//實際調用的是ObservableCreate.subscribeActual()方法,具體實現以下
 
protected void subscribeActual(Observer<? super T> observer) {
 
              // 1. 建立1個CreateEmitter對象用於發射事件(封裝成1個Disposable對象)
            CreateEmitter<T> parent = new CreateEmitter<T>(observer);
            // 2. 調用觀察者(Observer)的onSubscribe()
            observer.onSubscribe(parent);
            try {
                // 3. 調用source對象的(ObservableOnSubscribe對象)subscribe()
                source.subscribe(parent);
            } catch (Throwable ex) {
                Exceptions.throwIfFatal(ex);
                parent.onError(ex);
            }
}
複製代碼
11.RxJava的做用,與平時使用的異步操做來比的優缺點
12.說說EventBus做用,實現方式,代替EventBus的方式
13.從0設計一款App總體架構,如何去作?
14.說一款你認爲當前比較火的應用並設計(好比:直播APP,P2P金融,小視頻等)
15.談談對java狀態機理解
16.Fragment若是在Adapter中使用應該如何解耦?
17.Binder機制及底層實現
18.對於應用更新這塊是如何作的?(解答:灰度,強制更新,分區域更新)?
19.實現一個Json解析器(能夠經過正則提升速度)
20.統計啓動時長,標準

七.性能優化

1.如何對Android 應用進行性能分析以及優化?
2.ddms 和 traceView
3.性能優化如何分析systrace?
4.用IDE如何分析內存泄漏?
5.Java多線程引起的性能問題,怎麼解決?
6.啓動頁白屏及黑屏解決?
7.啓動太慢怎麼解決?
8.怎麼保證應用啓動不卡頓?
9.App啓動崩潰異常捕捉
10自定義View注意事項
11.如今下載速度很慢,試從網絡協議的角度分析緣由,並優化(提示:網絡的5層均可以涉及)。
12.Https請求慢的解決辦法(提示:DNS,攜帶數據,直接訪問IP)
13.如何保持應用的穩定性
14.RecyclerView和ListView的性能對比
15.ListView的優化
16.RecycleView優化
17.View渲染
18.Bitmap如何處理大圖,如一張30M的大圖,如何預防OOM
19.java中的四種引用的區別以及使用場景
20.強引用置爲null,會不會被回收?

八.NDK、jni、Binder、AIDL、進程通訊有關

1.請介紹一下NDK
2.什麼是NDK庫?
3.jni用過嗎?
4.如何在jni中註冊native函數,有幾種註冊方式?
5.Java如何調用c、c++語言?
6.jni如何調用java層代碼?
7.進程間通訊的方式?
8.Binder機制
9.簡述IPC?
10.什麼是AIDL?
11.AIDL解決了什麼問題?
12.AIDL如何使用?
13.Android 上的 Inter-Process-Communication 跨進程通訊時如何工做的?
14.多進程場景碰見過麼?
15.Android進程分類?
16.進程和 Application 的生命週期?
17.進程調度
18.談談對進程共享和線程安全的認識
19談談對多進程開發的理解以及多進程應用場景
20.什麼是協程?

九.framework層、ROM定製、Ubuntu、Linux之類的問題

1.java虛擬機的特性
2.談談對jvm的理解
3.JVM內存區域,開線程影響哪塊內存
4.對Dalvik、ART虛擬機有什麼瞭解?
5.Art和Dalvik對比
6.虛擬機原理,如何本身設計一個虛擬機(內存管理,類加載,雙親委派)
7.談談你對雙親委派模型理解
8.JVM內存模型,內存區域
9.類加載機制
10.談談對ClassLoader(類加載器)的理解
11.談談對動態加載(OSGI)的理解
12.內存對象的循環引用及避免
13.內存回收機制、GC回收策略、GC原理時機以及GC對象
14.垃圾回收機制與調用System.gc()區別
15.Ubuntu編譯安卓系統
16.系統啓動流程是什麼?(提示:Zygote進程 –> SystemServer進程 –> 各類系統服務 –> 應用進程)
17.大致說清一個應用程序安裝到手機上時發生了什麼
18.簡述Activity啓動所有過程
19.App啓動流程,從點擊桌面開始
20.邏輯地址與物理地址,爲何使用邏輯地址?
21.Android爲每一個應用程序分配的內存大小是多少?
22.Android中進程內存的分配,能不能本身分配定額內存?
23.進程保活的方式
24.如何保證一個後臺服務不被殺死?(相同問題:如何保證service在後臺不被kill?)比較省電的方式是什麼?
25.App中喚醒其餘進程的實現方式

(更多完整項目下載。未完待續。源碼。圖文知識後續上傳github。)
能夠點擊
github.com/xiangjiana/…

獲取完整PDF

相關文章
相關標籤/搜索