大佬帶你走進Android開發的世界,掌握了這些知識點,學習Android也可以很輕松。
核心分析內容
對于怎么學習Android,主要解決的是3個問題:學什么、怎么學 & 怎么用。
具體如下:
下面,我將帶著上述幾個問題,**詳細講解自身學習Android的方法和Android學習路徑;**最后,還會結合前面內容,給出綜合的具體執行學習Android的建議。
Android面試中有哪些常見問題匯總&答題思路
目錄:
1.網絡
2.Java 基礎&容器&同步&設計模式
3.Java 虛擬機&內存結構&GC&類加載&四種引用&動態代理
4.Android 基礎&性能優化&Framwork
5.Android 模塊化&熱修復&熱更新&打包&混淆&壓縮
6.音視頻&FFmpeg&播放器
1、網絡
網絡協議模型
應用層:負責處理特定的應用程序細節
HTTP、FTP、DNS
傳輸層:為兩臺主機提供端到端的基礎通信
TCP、UDP
網絡層:控制分組傳輸、路由選擇等
IP
鏈路層:操作系統設備驅動程序、網卡相關接口
TCP 和 UDP 區別
TCP 連接;可靠;有序;面向字節流;速度慢;較重量;全雙工;適用于文件傳輸、瀏覽器等
- 全雙工:A 給 B 發消息的同時,B 也能給 A 發
- 半雙工:A 給 B 發消息的同時,B 不能給 A 發
UDP 無連接;不可靠;無序;面向報文;速度快;輕量;適用于即時通訊、視頻通話等
TCP 三次握手
A:你能聽到嗎?
B:我能聽到,你能聽到嗎?
A:我能聽到,開始吧
A 和 B 兩方都要能確保:我說的話,你能聽到;你說的話,我能聽到。所以需要三次握手
TCP 四次揮手
A:我說完了
B:我知道了,等一下,我可能還沒說完
B:我也說完了
A:我知道了,結束吧
B 收到 A 結束的消息后 B 可能還沒說完,沒法立即回復結束標示,只能等說完后再告訴 A :我說完了。
POST 和 GET 區別
Get 參數放在 url 中;Post 參數放在 request Body 中
Get 可能不安全,因為參數放在 url 中
HTTPS
HTTP 是超文本傳輸協議,明文傳輸;HTTPS 使用 SSL 協議對 HTTP 傳輸數據進行了加密
HTTP 默認 80 端口;HTTPS 默認 443 端口
優點:安全
缺點:費時、SSL 證書收費,加密能力還是有限的,但是比 HTTP 強多了
2、Java 基礎&容器&同步&設計模式
StringBuilder、StringBuffer、+、String.concat 鏈接字符串:
- StringBuffer 線程安全,StringBuilder 線程不安全
- +實際上是用 StringBuilder 來實現的,所以非循環體可以直接用 +,循環體不行,因為會頻繁創建 StringBuilder
- String.concat 實質是 new String ,效率也低,耗時排序:StringBuilder < StringBuffer < concat < +
Java 泛型擦除
- 修飾成員變量等類結構相關的泛型不會被擦除
- 容器類泛型會被擦除
ArrayList、LinkedList
ArrayList
基于數組實現,查找快:o(1),增刪慢:o(n)
初始容量為10,擴容通過 System.arrayCopy 方法
LinkedList
基于雙向鏈表實現,查找慢:o(n),增刪快:o(1)
封裝了隊列和棧的調用
HashMap 、HashTable
HashMap
- 基于數組和鏈表實現,數組是 HashMap 的主體;鏈表是為解決哈希沖突而存在的
- 當發生哈希沖突且鏈表 size 大于閾值時會擴容,JAVA 8 會將鏈表轉為紅黑樹提高性能
允許 key/value 為 null
HashTable
- 數據結構和 HashMap 一樣
- 不允許 value 為 null
- 線程安全
ArrayMap、SparseArray
ArrayMap
1.基于兩個數組實現,一個存放 hash;一個存放鍵值對。擴容的時候只需要數組拷貝,不需要重建哈希表
2.內存利用率高
3.不適合存大量數據,因為會對 key 進行二分法查找(1000以下)
SparseArray
1.基于兩個數組實現,int 做 key
2.內存利用率高
3.不適合存大量數據,因為會對 key 進行二分法查找(1000以下)
volatile 關鍵字
- 只能用來修飾變量,適用修飾可能被多線程同時訪問的變量
- 相當于輕量級的 synchronized,volatitle 能保證有序性(禁用指令重排序)、可見性;后者還能保證原子性
- 變量位于主內存中,每個線程還有自己的工作內存,變量在自己線程的工作內存中有份拷貝,線程直接操作的是這個拷貝
- 被 volatile 修飾的變量改變后會立即同步到主內存,保持變量的可見性。
雙重檢查單例,為什么要加 volatile?
1.volatile想要解決的問題是,在另一個線程中想要使用instance,發現instance!=null,但是實際上instance還未初始化完畢這個問題
2.將instance =newInstance();拆分為3句話是。1.分配內存2.初始化3.將instance指向分配的內存空
3.volatile可以禁止指令重排序,確保先執行2,后執行3
wait 和 sleep
- sleep 是 Thread 的靜態方法,可以在任何地方調用
- wait 是 Object 的成員方法,只能在 synchronized 代碼塊中調用,否則會報 IllegalMonitorStateException 非法監控狀態異常
- sleep 不會釋放共享資源鎖,wait 會釋放共享資源鎖
lock 和 synchronized
- synchronized 是 Java 關鍵字,內置特性;Lock 是一個接口
- synchronized 會自動釋放鎖;lock 需要手動釋放,所以需要寫到 try catch 塊中并在 finally 中釋放鎖
- synchronized 無法中斷等待鎖;lock 可以中斷
- Lock 可以提高多個線程進行讀/寫操作的效率
- 競爭資源激烈時,lock 的性能會明顯的優于 synchronized
可重入鎖
- 定義:已經獲取到鎖后,再次調用同步代碼塊/嘗試獲取鎖時不必重新去申請鎖,可以直接執行相關代碼
- ReentrantLock 和 synchronized 都是可重入鎖
公平鎖
- 定義:等待時間最久的線程會優先獲得鎖
- 非公平鎖無法保證哪個線程獲取到鎖,synchronized 就是非公平鎖
- ReentrantLock 默認時非公平鎖,可以設置為公平鎖
樂觀鎖和悲觀鎖
- 悲觀鎖:線程一旦得到鎖,其他線程就掛起等待,適用于寫入操作頻繁的場景;synchronized 就是悲觀鎖
- 樂觀鎖:假設沒有沖突,不加鎖,更新數據時判斷該數據是否過期,過期的話則不進行數據更新,適用于讀取操作頻繁的場景
- 樂觀鎖 CAS:Compare And Swap,更新數據時先比較原值是否相等,不相等則表示數據過去,不進行數據更新
- 樂觀鎖實現:AtomicInteger、AtomicLong、AtomicBoolean
死鎖 4 個必要條件
- 互斥
- 占有且等待
- 不可搶占
- 循環等待
synchronized 原理
- 每個對象都有一個監視器鎖:monitor,同步代碼塊會執行 monitorenter 開始,motnitorexit 結束
- wait/notify 就依賴 monitor 監視器,所以在非同步代碼塊中執行會報 IllegalMonitorStateException 異常
3、Java 虛擬機&內存結構&GC&類加載&四種引用&動態代理
JVM
- 定義:可以理解成一個虛構的計算機,解釋自己的字節碼指令集映射到本地 CPU 或 OS 的指令集,上層只需關注 Class 文件,與操作系統無關,實現跨平臺
- Kotlin 就是能解釋成 Class 文件,所以可以跑在 JVM 上
JVM 內存模型
- Java 多線程之間是通過共享內存來通信的,每個線程都有自己的本地內存
- 共享變量存放于主內存中,線程會拷貝一份共享變量到本地內存
- volatile 關鍵字就是給內存模型服務的,用來保證內存可見性和順序性
JVM 內存結構
線程私有:
1.程序計數器:記錄正在執行的字節碼指令地址,若正在執行 Native 方法則為空
2.虛擬機棧:執行方法時把方法所需數據存為一個棧幀入棧,執行完后出棧
3.本地方法棧:同虛擬機棧,但是針對的是 Native 方法
線程共享:
1.堆:存儲 Java 實例,GC 主要區域,分代收集 GC 方法會吧堆劃分為新生代、老年代
2.方法區:存儲類信息,常量池,靜態變量等數據
GC
回收區域:只針對堆、方法區;線程私有區域數據會隨線程結束銷毀,不用回收
回收類型:
1.堆中的對象
- 分代收集 GC 方法會吧堆劃分為新生代、老年代
- 新生代:新建小對象會進入新生代;通過復制算法回收對象
- 老年代:新建大對象及老對象會進入老年代;通過標記-清除算法回收對象
2.方法區中的類信息、常量池
判斷一個對象是否可被回收:
1.引用計數法
缺點:循環引用
2.可達性分析法
定義:從 GC ROOT 開始搜索,不可達的對象都是可以被回收的
GC ROOT
1.虛擬機棧/本地方法棧中引用的對象
2.方法區中常量/靜態變量引用的對象
四種引用
- 強引用:不會被回收
- 軟引用:內存不足時會被回收
- 弱引用:gc 時會被回收
- 虛引用:無法通過虛引用得到對象,可以監聽對象的回收
ClassLoader
類的生命周期:
1.加載;2.驗證;3.準備;4.解析;5.初始化;6.使用;7.卸載
類加載過程:
1.加載:獲取類的二進制字節流;生成方法區的運行時存儲結構;在內存中生成 Class 對象
2.驗證:確保該 Class 字節流符合虛擬機要求
3.準備:初始化靜態變量
4.解析:將常量池的符號引用替換為直接引用
5.初始化:執行靜態塊代碼、類變量賦值
類加載時機:
1.實例化對象
2.調用類的靜態方法
3.調用類的靜態變量(放入常量池的常量除外)
類加載器:負責加載 class 文件
分類:
1.引導類加載器 - 沒有父類加載器
2.拓展類加載器 - 繼承自引導類加載器
3.系統類加載器 - 繼承自拓展類加載器
雙親委托模型:
當要加載一個 class 時,會先逐層向上讓父加載器先加載,加載失敗才會自己加載
為什么叫雙親?不考慮自定義加載器,系統類加載器需要網上詢問兩層,所以叫雙親
判斷是否是同一個類時,除了類信息,還必須時同一個類加載器
優點:
- 防止重復加載,父加載器加載過了就沒必要加載了
- 安全,防止篡改核心庫類
動態代理原理及實現
- InvocationHandler 接口,動態代理類需要實現這個接口
- Proxy.newProxyInstance,用于動態創建代理對象
- Retrofit 應用: Retrofit 通過動態代理,為我們定義的請求接口都生成一個動態代理對象,實現請求
4、Android 基礎&性能優化&Framwork
Activity 啟動模式
- standard 標準模式
- singleTop 棧頂復用模式,
- 推送點擊消息界面
- singleTask 棧內復用模式,
- 首頁
- singleInstance 單例模式,單獨位于一個任務棧中
- 撥打電話界面
細節: - taskAffinity:任務相關性,用于指定任務棧名稱,默認為應用包名
- allowTaskReparenting:允許轉移任務棧
- 撥打電話界面
View 工作原理
- DecorView (FrameLayout)
- LinearLayout
- titlebar
- Content
- 調用 setContentView 設置的 View
- LinearLayout
ViewRoot 的 performTraversals 方法調用觸發開始 View 的繪制,然后會依次調用:
- performMeasure:遍歷 View 的 measure 測量尺寸
- performLayout:遍歷 View 的 layout 確定位置
- performDraw:遍歷 View 的 draw 繪制
事件分發機制
- 一個 MotionEvent 產生后,按 Activity -> Window -> decorView -> View 順序傳遞,View 傳遞過程就是事件分發,主要依賴三個方法:
- dispatchTouchEvent:用于分發事件,只要接受到點擊事件就會被調用,返回結果表示是否消耗了當前事件
- onInterceptTouchEvent:用于判斷是否攔截事件,當 ViewGroup 確定要攔截事件后,該事件序列都不會再觸發調用此 ViewGroup 的 onIntercept
- onTouchEvent:用于處理事件,返回結果表示是否處理了當前事件,未處理則傳遞給父容器處理
- 細節:
- 一個事件序列只能被一個 View 攔截且消耗
- View 沒有 onIntercept 方法,直接調用 onTouchEvent 處理
- OnTouchListener 優先級比 OnTouchEvent 高,onClickListener 優先級最低
- requestDisallowInterceptTouchEvent 可以屏蔽父容器 onIntercet 方法的調用
Window 、 WindowManager、WMS、SurfaceFlinger
- Window:抽象概念不是實際存在的,而是以 View 的形式存在,通過 PhoneWindow 實現
- WindowManager:外界訪問 Window 的入口,內部與 WMS 交互是個 IPC 過程
- WMS:管理窗口 Surface 的布局和次序,作為系統級服務單獨運行在一個進程
- SurfaceFlinger:將 WMS 維護的窗口按一定次序混合后顯示到屏幕上
View 動畫、幀動畫及屬性動畫
View 動畫:
- 作用對象是 View,可用 xml 定義,建議 xml 實現比較易讀
- 支持四種效果:平移、縮放、旋轉、透明度
幀動畫:
- 通過 AnimationDrawable 實現,容易 OOM
屬性動畫:
- 可作用于任何對象,可用 xml 定義,Android 3 引入,建議代碼實現比較靈活
- 包括 ObjectAnimator、ValuetAnimator、AnimatorSet
- 時間插值器:根據時間流逝的百分比計算當前屬性改變的百分比
- 系統預置勻速、加速、減速等插值器
- 類型估值器:根據當前屬性改變的百分比計算改變后的屬性值
- 系統預置整型、浮點、色值等類型估值器
- 使用注意事項:
- 避免使用幀動畫,容易OOM
- 界面銷毀時停止動畫,避免內存泄漏
- 開啟硬件加速,提高動畫流暢性 ,硬件加速:
- 將 cpu 一部分工作分擔給 gpu ,使用 gpu 完成繪制工作
- 從工作分攤和繪制機制兩個方面優化了繪制速度
最后
總之啊,家里沒礦的同學們,如果你們想以后的日子過得好一些,多想想你們的業余時間怎么安排吧;
技術方面的提升肯定是重中之重,但是技術外的一些“軟實力”也不能完全忽視,很多時候升職確實是因為你的技術足夠強,但也與你的“軟實力”密切相關
在這我也分享一份大佬自己收錄整理的 Android學習PDF+架構視頻+面試文檔+源碼筆記 ,還有高級架構技術進階腦圖、Android開發面試專題資料,高級進階架構資料這些都是我閑暇還會反復翻閱并給下屬員工學習的精品資料。在腦圖中,每個知識點專題都配有相對應的實戰項目,可以有效的幫助大家掌握知識點。
總之也是在這里幫助大家學習提升進階,也節省大家在網上搜索資料的時間來學習,也可以分享給身邊好友一起學習
如果你有需要的話,可以點擊獲取
droid學習PDF+架構視頻+面試文檔+源碼筆記](https://docs.qq.com/doc/DSkNLaERkbnFoS0ZF)** ,還有高級架構技術進階腦圖、Android開發面試專題資料,高級進階架構資料這些都是我閑暇還會反復翻閱并給下屬員工學習的精品資料。在腦圖中,每個知識點專題都配有相對應的實戰項目,可以有效的幫助大家掌握知識點。
總之也是在這里幫助大家學習提升進階,也節省大家在網上搜索資料的時間來學習,也可以分享給身邊好友一起學習
如果你有需要的話,可以點擊獲取
[外鏈圖片轉存中…(img-3Omn4wKu-1618563073953)]
[外鏈圖片轉存中…(img-6nWu1wkF-1618563073955)]
相信自己,沒有做不到的,只有想不到的