2019 初級Android開發工程師面經

1. Java基礎

1.1 什麼是樂觀鎖?

  • 樂觀鎖:假設每次去拿數據都認爲別人不會修改,因此不會上鎖.可是在更新的時候會判斷一下此期間別人有沒有去更新這個數據. 通常用在讀比較多,寫比較少的狀況.
  • 悲觀鎖:假設每次都是最壞狀況,每次去拿數據時別人都會修改,因此每次拿數據的時候都會上鎖,這樣別人想拿這個數據就會被阻塞直到它拿到鎖. 多寫少讀時使用.

擴展資料: www.cnblogs.com/renhui/p/97…html

1.2 volatile關鍵字

  1. 保證可見性,不保證原子性
  2. 禁止指令重排序
  3. 不緩存,每次都是從主存中取

擴展資料: www.cnblogs.com/zhengbin/p/…java

1.3 hashmap 原理,紅黑樹是什麼?

  • 1.7 數組+鏈表,鏈表過長時,會致使查詢效率退化
  • 1.8 數組+鏈表+紅黑樹,當鏈表長度大於8轉爲紅黑樹
  • HashMap 的默認初始大小爲 16,初始化大小必須爲 2 的冪,最大大小爲 2 的 30 次方。數組中存儲的鏈表節點 Entry 類實現於 Map.Entry 接口,它實現了對節點的通用操做。HashMap 的閾值默認爲 「容量 * 0.75f」,當存儲節點數量超過該值,則對 map 進行擴容處理。
  • 線程不安全的容器,解決併發問題使用ConcurrentHashMap(高效)或者是Collections.synchronizedMap().Collections.synchronizedMap()其實就是每一個方法加一個synchronize,其實和HashTable 差很少.

紅黑樹android

  • 平衡的二叉查找樹
  • 節點是紅色或者是黑色
  • 根節點是黑色
  • 每一個葉子的節點都是黑色的空節點(NULL)
  • 每一個紅色節點的兩個子節點都是黑色的
  • 從任意節點到其每一個葉子的全部路徑都包含相同的黑色節點
  • 插入時會涉及到變色和旋轉

擴展資料: blog.csdn.net/justloveyou… www.360doc.com/content/18/…程序員

1.4 jvm內存分配

Java虛擬機書中第二章面試

  • 程序計數器
  • Java虛擬機棧
  • 本地方法棧
  • Java堆
  • 方法區
  • 運行時常量池
  • 直接內存

1.5 String,StringBuffer,StringBuilder 區別

  • String,StringBuffer,StringBuilder最終底層存儲與操做的都是char數組.可是String裏面的char數組是final的,而StringBuffer,StringBuilder不是,也就是說,String是不可變的,想要新的字符串只能從新生成String.而StringBuffer和StringBuilder只須要修改底層的char數組就行.相對來講,開銷要小不少.
  • String的大多數方法都是從新new一個新String對象返回,頻繁從新生成容易生成不少垃圾.
  • StringBuffer是線程安全的,StringBuilder是線程不安全的.由於StringBuffer的方法是加了synchronized鎖起來了的,而StringBuilder沒有.
  • 增刪比較多時用StringBuffer或StringBuilder(注意單線程與多線程)。實際狀況按需而取吧,既然已經知道了裏面的原理。

2. 安卓基礎

2.1 安卓各版本大變化(Android 6.0到10.0有哪些大點變化),兼容適配

Android 5.0算法

  • Material Design
  • ART虛擬機

Android 6.0數據庫

  • 應用權限管理
  • 官方指紋支持
  • Doze電量管理
  • 運行時權限機制->須要動態申請權限

Android 7.0設計模式

  • 多窗口模式
  • 支持Java 8語言平臺
  • 須要使用FileProvider訪問照片
  • 安裝apk須要兼容

Android 8.0api

  • 通知,渠道->適配
  • 畫中畫
  • 自動填充
  • 後臺限制
  • 自適應桌面圖標->適配
  • 隱式廣播限制
  • 開啓後臺Service限制

Android 9.0數組

  • 利用 Wi-Fi RTT 進行室內定位
  • 劉海屏 API 支持
  • 多攝像頭支持和攝像頭更新
  • 不容許調用hide api
  • 限制明文流量的網絡請求 http

Android 10

  • 暗黑模式
  • 隱私加強(後臺可否訪問定位)
  • 限制程序訪問剪貼板
  • 應用黑盒
  • 權限細分需兼容
  • 後臺定位單獨權限需兼容
  • 設備惟一標示符需兼容
  • 後臺打開Activity 需兼容
  • 非 SDK 接口限制 需兼容

2.2 熱修復原理

原理

  1. 安卓在加載class時會經過雙親委託機制去加載一個類,先讓父類去加載,若是找不到再讓子類去加載某個類.
  2. 經過查看ClassLoader源碼發現findClass方法是由每一個子類本身實現的,好比BootClassLoader或者BaseDexClassLoader.而PathClassLoader是繼承自BaseDexClassLoader的,它的findClass也是在BaseDexClassLoader裏面實現的.
  3. BaseDexClassLoader的findClass裏面使用了另外一個對象DexPathList去查找對應的class,這是安卓裏面特有的實現.在DexPathList對象裏面有一個屬性dexElements,dexElements是用於存放加載好了的dex數組的,查找class是從這個dexElements數組裏面去找的.
  4. dexElements裏面存放的是Element對象,findClass最終會交給Element去實現,Element又會交給Element裏面的一個屬性DexFile去實現.我看了下,最終是用native實現的.
  5. 回到上面的第3步中的DexPathList對象從dexElements數組裏面查找class,從數組的前面日後找,找到了就返回結果,再也不繼續查找.
  6. 因此當咱們把修復好bug了的class,搞成dex,而後經過反射等技術放到dexElements的最前面,這樣系統在經過PathClassLoader找到class時,就能先找到咱們放置的修復好bug的class,而後就不會再日後找了,至關於實現了熱修復.這樣有bug的class就不會被用了.應了一句古話,近水樓臺先得月.
  7. 第6點中的反射,流程是:獲取到PathClassLoader,而後反射獲取到父類中的DexPathList對象,而後再反射到DexPathList對象中的dexElements數組.而後將補丁(dex)轉爲Element對象,插入到dexElements數組的前面(先複製出來,再合併,再經過反射放回去).

一句話總結

將修復好的類放在dexElements的最前面,這樣在加載類的時候就會被優先加載到而達到修復的目的.

2.3 MVC,MVP,MVVM

首先須要知道的是爲何要進行技術框架的設計? 確定是爲了低耦合,提升開發效率是吧.因此不要爲了設計而設計.

MVC

在Android中View和Controller通常就是被Activity充當了,當邏輯很是多,操做很是複雜時,Activity代碼量很是龐大,不易維護.

  • Model : 模型層,業務邏輯+數據存儲等
  • View : 用戶界面,通常就是xml+Activity
  • Controller : 控制層,通常就是Activity

MVP

我我的角度,如今(2019年10月29日20:02:49)大可能是使用這種方式,既不復雜也解耦合了.

  • Model:模型層,業務邏輯+數據存儲+網絡請求
  • View:視圖層,View繪製和用戶交互等,通常是Activity
  • Presenter:呈現層,鏈接V層和M層,完成他們之間的交互

MVVM

爲了更加分離M,V層,因此有了MVVM.

  • Model:模型層,業務邏輯+數據存儲+網絡請求
  • View:視圖層,View繪製和用戶交互等,通常是Activity
  • ViewModel:其實就是Presenter和View的數據模型的合體.雙向綁定,View的變更會反應到ViewModel中,數據的變更也會反應到View上.

2.4 組件化的好處

  1. 任意修改都須要編譯整個工程,效率低下。
  2. 解耦,有利於多人團隊協做開發
  3. 功能複用

2.5 app啓動流程

以前我寫過一篇文章 死磕Android_App 啓動過程(含 Activity 啓動過程)

  1. Launcher startActivity
  2. AMS startActivity
  3. Zygote fork進程
  4. Activity main()
  5. ActivityThread 進程loop循環
  6. 開啓Activity,開始生命週期回調...

2.6 Activity啓動流程

看2.5推薦的那篇文章裏面有

  1. Activity startActivityForResult
  2. Instrumentation execStartActivity
  3. AMS startActivity
  4. ApplicationThread scheduleLaunchActivity
  5. ActivityThread.H handleMessage -> performLaunchActivity 
  6. Activity attach
  7. Instrumentation callActivityOnCreate

2.7 app體積優化

優化這一塊,S大佬有一篇文章寫得特別受用,原文在這裏

  • 可使用lint工具,檢測出沒有用的文件.同時能夠開啓資源壓縮,自動刪除無用的資源.
  • 儘可能多使用可繪製對象,某些圖像不須要靜態圖像資源,框架能夠在運行時動態繪製圖像.儘可能本身寫Drawable,能不用UI切圖就不用,佔用空間小.
  • 重用資源. 好比一個三角按鈕,點擊前三角朝上表明收起的意思,點擊後三角朝下,表明展開,通常狀況下,咱們會用兩張圖來切換,咱們其實徹底能夠用旋轉的形式去改變.
  • 好比同一圖像的着色不一樣,咱們能夠用android:tint和tintMode屬性,低版本可使用ColorFilter
  • 壓縮PNG和JPEG文件.能夠減小PNG文件的大小,而不會丟失圖像質量.
  • 使用WebP文件格式,可使用WebP文件格式,而不是使用PNG或JPEG文件. 可使用AS將現有的BMP,JPG,PNG或靜態GIF圖像轉換成WebP格式.
  • 使用矢量圖形. svg
  • 代碼混淆. 使用proGuard代碼混淆器工具,它包括壓縮,優化,混淆等功能.這個你們太熟悉.
  • 插件化. 將功能模塊放服務器上,按需下載,能夠減小安裝包大小.

2.8 app啓動優化

  • 利用提早展現出來的Window,快速展現出來一個節目,給用戶快速反饋的體驗.障眼法,治標不治本.
  • 避免在啓動時作密集沉重的初始化(Heavy app initialization).某些SDK初始化放在異步去加載(好比友盟,bugly這樣的業務非必要能夠異步加載),好比地圖,推送等,非第一時間須要的能夠在主線程作延時啓動(好比閃屏頁),當程序已經啓動起來以後,再進行初始化. 對於網絡,圖片請求框架就必須在主線程中初始化了.
  • 啓動時 避免I/O操做,反序列化,網絡操做,佈局嵌套等耗時操做

延伸閱讀:

2.9 app佈局優化

  • 若是父控件有顏色,也是本身須要的顏色,那麼就沒必要在子控件加背景顏色
  • 若是子控件有背景顏色,而且能徹底覆蓋父控件,那麼父控件不用設置背景顏色
  • 儘可能減小沒必要要的嵌套
  • 能用LinearLayout和FrameLayout,就不要用RelativeLayout,由於RelativeLayout相對比較複雜,測繪也相對耗時.
  • include和merge一塊兒使用,增長複用,減小層級
  • ViewStub按需加載,更加輕便
  • 複雜界面選擇ConstraintLayout,可有效減小層級

2.10 app內存優化

  • 頻繁使用字符串拼接用StringBuilder或者StringBuffer
  • ArrayMap、SparseArray替換HashMap
  • 避免內存泄漏
    • 集合類泄漏(集合一直引用着被添加進來的元素對象)
    • 單例/靜態變量形成的內存泄漏(生命週期長的持有了生命週期短的引用)
    • 匿名內部類/非靜態內部類
    • 資源未關閉形成的內存泄漏
  • 檢測內存泄漏的幾個工具: LeakCanary,TraceView,Systrace,Android Lint,Memory Monitor+mat

2.11 內存泄漏有哪些

  • 集合類泄漏(集合一直引用着被添加進來的元素對象)
  • 單例/靜態變量形成的內存泄漏(生命週期長的持有了生命週期短的引用)
  • 匿名內部類/非靜態內部類
  • 資源未關閉形成的內存泄漏
    • 網絡,文件等流忘記關閉
    • 手動註冊廣播時,退出時忘記unregisterReceiver()
    • Service執行完成後忘記stopSelf()
    • EventBus等觀察者模式的框架忘記手動解除註冊

2.12 app線程優化

線程池 避免存在大量的Thread,重用線程池內部的線程,從而避免了線程的建立和銷燬帶來的性能開銷,同時能有效控制線程池的最大併發數,避免大量線程因互相搶佔系統資源而致使阻塞線現象發生. 推薦閱讀 《Android開發藝術探索》 第11章.

分類

  • FixedThreadPool 數量固定的線程池
  • CachedThreadPool 只有非核心線程,數量不定,空閒線程有超時機制,比較適合執行大量耗時較少的任務
  • ScheduledThreadPool 核心線程數量固定,非核心線程沒有限制.主要用於執行定時任務和具備固定中週期的重複任務.
  • SingleThreadPool 只有一個核心線程,確保全部的任務在同一個線程順序執行,統一外界任務到一個線程中,這使得在這些任務之間不須要處理線程同步 的問題. 優勢
  • 減小在建立和銷燬線程上所花的時間以及系統資源的開銷
  • 不使用線程池有可能形成系統建立大量的線程而致使消耗完系統內存以及"過分切換" 注意點
  1. 若是線程池中的數量未達到核心線程的數量,則直接啓動一個核心線程來執行任務
  2. 若是線程池中的數量已經達到或超過核心線程的數量,則任何會被插入到任務隊列中等待執行
  3. 若是2中的任務沒法插入到任務隊列中,因爲任務隊列已滿,這時候若是線程數量未達到線程池規定的最大值,則會啓動一個非核心線程來執行任務
  4. 若是3中的線程數量已經達到線程池最大值,則會拒絕執行此任務,ThreadPoolExecutor會調用RejectedExecutionHandler的rejectedExecution()方法通知調用者

2.13 Android換膚如何實現,原理

從新設置LayoutInflater的Factory2,從而攔截建立View的過程,而後搞成本身的控件,想怎麼換膚就怎麼換膚.

具體原理能夠參見我以前寫的一篇文章Android-skin-support 換膚原理全面解析

2.14 fresco原理,glide原理,二者區別,哪一個更省內存

這塊暫時不懂,加入todo

2.15 DialogFragment 黑邊

www.jianshu.com/p/c8044b2c2…

2.16 Handler原理,Android 消息機制

以前寫過一篇文章,死磕Android_Handler機制你須要知道的一切 .裏面介紹得很詳細,順便說了一下爲何loop不會阻塞主線程問題.

Handler機制的關鍵在於對於ThreadLocal原理的理解,線程私有數據.利用ThreadLocal機制將Looper存放到線程內部,perfect !

2.17 Android 系統架構

應用層,應用框架層,系統運行庫層,硬件抽象層和Linux內核層

2.18 經常使用佈局有哪些

  • FrameLayout,LinearLayout,RelativeLayout,ConstraintLayout,CoordinatorLayout等

2.19 Android數據存儲有幾種方式

  • SharedPreferences: 小東西,最終是xml文件中,key-value的形式存儲的.
  • 文件
  • 數據庫
  • ContentProvider
  • 網絡

2.20 View,SurfaceView

  • View是Android中全部控件的基類
  • View適用於主動更新的狀況,而SurfaceView則適用於被動更新的狀況,好比頻繁刷新界面。
  • View在主線程中對頁面進行刷新,而SurfaceView則開啓一個子線程來對頁面進行刷新。
  • View在繪圖時沒有實現雙緩衝機制,SurfaceView在底層機制中就實現了雙緩衝機制。

2.21 jni調用流程

我以前也寫過簡單的demo,JNI Java與C的相互調用與基本操做

隔壁老李頭的系列文章很是棒,地址在這裏

2.22 組件之間相互引用 如何解決

  • 調用其餘組件的對外提供的方法:以前看到過一種思路,利用"接口+實現"的方式,定義一個ComponentBase 中間層,而後裏面有每一個組件對外提供方法調用的Interface,每一個組件在初始化的時候就把這些Interface給實現了,而後其餘組件須要用的時候就從ComponentBase裏面取.
  • 界面跳轉:ARouter

2.23 自定義View 餅狀圖,點擊事件,畫文字

這個你們能夠跟着hencoder老師的文章系統學習一下.

2.24 Android 數字簽名

校驗用戶身份,校驗數據的完整性

2.25 fragment用在哪裏,與Activity的區別

  • 當Activity須要模塊化的時候
  • 不一樣設備上的適配,好比平臺和手機
  • Activity相對Fragment而言,很是笨重,通常小界面小模塊用Fragment比較合適.或者首頁的tab之類的.

2.26 RxJava原理

觀察者模式,鏈式

友好 RxJava2.x 源碼解析三部曲

給 Android 開發者的 RxJava 詳解

2.27 EventBus原理

不太瞭解原理,不多使用,好像也是基於觀察者模式的一個框架.

EventBus 原理解析

2.28 View繪製原理

主要是分析measure,layout,draw的過程,以前寫過一篇比較完整的,以下.

死磕Android_View工做原理你須要知道的一切

2.29 Retrofit和OkHttp原理,攔截器

  • Retrofit的話,源碼寫的很是很是棒.主要是經過動態代理+獲取方法上面的註解等,而後組裝請求網絡的參數,最後用OkHttp去請求網絡
  • OkHttp的攔截器鏈設計得很是巧妙,是典型的責任鏈模式.並最終由最後一個鏈處理了網絡請求,並拿到結果.

恰好以前寫過文章分析過,以下:

死磕Android_Retrofit 原理解析

死磕Android_OkHttp3 原理探究

2.30 點擊事件傳遞機制,事件分爲哪幾種

事件傳遞大致過程: Activity--> Window-->DecorView --> View樹從上往下,傳遞過程當中誰想攔截就攔截本身處理.MotionEvent是Android中的點擊事件

主要事件類型

  • ACTION_DOWN 手機初次觸摸到屏幕事件
  • ACTION_MOVE 手機在屏幕上滑動時觸發,會回調屢次
  • ACTION_UP 手指離開屏幕時觸發

須要關注的幾個方法

  • dispatchTouchEvent(event);
  • onInterceptTouchEvent(event);
  • onTouchEvent(event);

上面3個方法能夠用如下僞代碼來表示其關係:

public boolean dispatchTouchEvent(MotionEvent ev) {
    boolean consume = false;//事件是否被消費
    if (onInterceptTouchEvent(ev)) {//調用onInterceptTouchEvent判斷是否攔截事件
        consume = onTouchEvent(ev);//若是攔截則調用自身的onTouchEvent方法
    } else {
        consume = child.dispatchTouchEvent(ev);//不攔截調用子View的dispatchTouchEvent方法
    }
    return consume;//返回值表示事件是否被消費,true事件終止,false調用父View的onTouchEvent方法
}
複製代碼

詳細內容看我以前寫的一篇文章,Android View事件分發機制

2.31 anr如何產生,Service觸發anr是多長時間(20秒),如何解決anr?如何解決那種莫名其妙的anr?

我以爲anr就是在主線程作了耗時操做,好比io、讀寫文件、數據庫操做等等. anr發生以後通常會有日誌,在/data/anr/traces.txt裏面. 能夠參考個人這篇文章拿anr日誌,Android 未root查看ANR異常

2.32 Dialog和Activity是同一個Window?

不是同一個.

  • Activity的attach方法,這裏是爲Activity實例化了一個PhoneWindow實例
  • Dialog的構造方法裏面也是實例化了一個PhoneWindow實例

2.33 Window,Activity,Dectorview之間的關係

Activity裏面實例化了一個Window,Window裏面有一個DecorView(根佈局).

看一下這篇文章,兇殘的程序員 出品,精品啊,特別特別乾貨.Android Window 機制探索

2.34 ConstraintLayout和RelativeLayout在繪製方面有何差異?

todo

2.35 onClick事件和onTouchListener在哪裏回調?

若是一個View須要處理事件,它設置了OnTouchListener,那麼OnTouchListener的onTouch方法會被回調.若是onTouch返回false,則onTouchEvent會被調用,反之不會.在onTouchEvent方法中,事件爲Action.UP的時候會回調OnClickListener的onClick方法,可見OnClickListener的優先級很低.

2.36 應用如何保活?

這個確實不怎麼了解,主要是不建議保活,提高用戶體驗.特別是安卓高版本,谷歌是封殺得很嚴格的,不建議保活.

以前在皇叔那裏看到過一篇文章,能夠參考參考

2018年Android保活方案效果統計

2.37 LinearLayout是如何測量(measure)的?若是有weight又是如何測量的?

先作一次測量,作完以後有空間剩餘,有weight的View再測量一下,分一下剩餘的空間。

2.38 屏幕適配

先前有鴻神的AndroidAutoLayout,根據寬高進行控件縮放,很是經典,不少項目可能都還在使用,可是已經中止更新了。而後就是有名的今日頭條方案,出來仍是有點時間了。原理其實就是更改density。

屏幕的寬度=設計稿寬度 * density

而後有AndroidAutoSize庫,將今日頭條方案融合進去還完善了不少問題,易用,完美。

3. 其餘

3. Java四種引用

  • 強引用,默認就是,寧願OOM,也不回收
  • 弱引用,內存不夠會被回收
  • 軟引用,GC時會被回收
  • 虛引用,它的做用在於跟蹤垃圾回收過程,在對象被收集器回收時收到一個系統通知。

3.1 項目中遇到的最困難的事情是什麼?如何解決的?

每一個人遇到的狀況不一樣,這個提早思考一下本身作過的項目最有挑戰的地方。

3.2 Git基本操做

建議學習一下廖雪峯老師的課程。

3.3 Kotlin優點

  1. 徹底兼容java
  2. 空安全
  3. 支持lambda表達式
  4. 支持擴展函數
  5. 更少的代碼量,更快的開發速度

缺點就是有時候代碼閱讀性可能會下降。

3.4 Kotlin 協程是什麼?

就是一個線程框架,提供了一套操做線程的api.

3.5 二叉樹,廣度優先遍歷,深度優先遍歷

推薦小灰的漫畫算法

3.6 tcp,http,https,socket

3.7 敏捷開發

3.8 你常用哪些設計模式,常見設計模式的運用

3.9 3年以後工資怎麼想的

3.10 你的優點

3.11 職業規劃(3年後幹啥,5年後幹啥)

3.12 應用,進程,線程之間的區別

相關文章
相關標籤/搜索