Java基礎
1.什麼是樂觀鎖?
- 樂觀鎖:假設每次去拿數據都認爲別人不會修改,所以不會上鎖.但是在更新的時候會判斷一下此期間別人有沒有去更新這個數據. 一般用在讀比較多,寫比較少的情況.
- 悲觀鎖:假設每次都是最壞情況,每次去拿數據時別人都會修改,所以每次拿數據的時候都會上鎖,這樣別人想拿這個數據就會被阻塞直到它拿到鎖. 多寫少讀時使用.
2.volatile關鍵字
- 保證可見性,不保證原子性
- 禁止指令重排序
- 不緩存,每次都是從主存中取
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 差不多.
紅黑樹
- 平衡的二叉查找樹
- 節點是紅色或者是黑色
- 根節點是黑色
- 每個葉子的節點都是黑色的空節點(NULL)
- 每個紅色節點的兩個子節點都是黑色的
- 從任意節點到其每個葉子的所有路徑都包含相同的黑色節點
- 插入時會涉及到變色和旋轉
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對象返回,頻繁重新生成容易生成很多垃圾.
........
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.0
Android 9.0
- 利用 Wi-Fi RTT 進行室內定位
- 劉海屏 API 支持
- 多攝像頭支持和攝像頭更新
- 不允許調用hide api
- 限制明文流量的網絡請求 http
Android 10
- 暗黑模式
- 隱私增強(後臺能否訪問定位)
- 限制程序訪問剪貼板
- 應用黑盒
- 權限細分需兼容
- 後臺定位單獨權限需兼容
- 設備唯一標示符需兼容
- 後臺打開Activity 需兼容
- 非 SDK 接口限制 需兼容
2.熱修復原理
原理
- 安卓在加載class時會通過雙親委託機制去加載一個類,先讓父類去加載,如果找不到再讓子類去加載某個類。
- 通過查看ClassLoader源碼發現findClass方法是由每個子類自己實現的,比如BootClassLoader或者BaseDexClassLoader。而PathClassLoader是繼承自BaseDexClassLoader的,它的findClass也是在BaseDexClassLoader裏面實現的。
- BaseDexClassLoader的findClass裏面使用了另一個對象DexPathList去查找對應的class,這是安卓裏面特有的實現。在DexPathList對象裏面有一個屬性dexElements,dexElements是用於存放加載好了的dex數組的,查找class是從這個dexElements數組裏面去找的。
.........
一句話總結
將修復好的類放在dexElements的最前面,這樣在加載類的時候就會被優先加載到而達到修復的目的.
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上.
4.組件化的好處
- 任意修改都需要編譯整個工程,效率低下。
- 解耦,有利於多人團隊協作開發
- 功能複用
5.app啓動流程
- Launcher startActivity
- AMS startActivity
- Zygote fork進程
- Activity main()
- ActivityThread 進程loop循環
- 開啓Activity,開始生命週期回調...
6.Activity啓動流程
- Activity startActivityForResult
- Instrumentation execStartActivity
- AMS startActivity
- ApplicationThread scheduleLaunchActivity
- ActivityThread.H handleMessage -> performLaunchActivity
- Activity attach
- Instrumentation callActivityOnCreate
7.app體積優化
- 可以使用lint工具,檢測出沒有用的文件,同時可以開啓資源壓縮,自動刪除無用的資源。
- 儘量多使用可繪製對象,某些圖像不需要靜態圖像資源,框架可以在運行時動態繪製圖像。儘量自己寫Drawable,能不用UI切圖就不用,佔用空間小。
- 重用資源。比如一個三角按鈕,點擊前三角朝上代表收起的意思,點擊後三角朝下,代表展開,一般情況下,我們會用兩張圖來切換,我們其實完全可以用旋轉的形式去改變。
..........
8.app啓動優化
- 利用提前展示出來的Window,快速展示出來一個節目,給用戶快速反饋的體驗,障眼法,治標不治本.
- 避免在啓動時做密集沉重的初始化(Heavy app initialization)。
- 啓動時 避免I/O操作,反序列化,網絡操作,佈局嵌套等耗時操作
9.app佈局優化
- 如果父控件有顏色,也是自己需要的顏色,那麼就不必在子控件加背景顏色
- 如果子控件有背景顏色,並且能完全覆蓋父控件,那麼父控件不用設置背景顏色
- 儘量減少不必要的嵌套
- 能用LinearLayout和FrameLayout,就不要用RelativeLayout,因爲RelativeLayout相對比較複雜,測繪也相對耗時.
- include和merge一起使用,增加複用,減少層級
- ViewStub按需加載,更加輕便
- 複雜界面選擇ConstraintLayout,可有效減少層級
10.app內存優化
- 頻繁使用字符串拼接用StringBuilder或者StringBuffer
- ArrayMap、SparseArray替換HashMap
- 避免內存泄漏
- 集合類泄漏(集合一直引用着被添加進來的元素對象)
- 單例/靜態變量造成的內存泄漏(生命週期長的持有了生命週期短的引用)
- 匿名內部類/非靜態內部類
- 資源未關閉造成的內存泄漏
- 檢測內存泄漏的幾個工具:LeakCanary,TraceView,Systrace,Android Lint,Memory Monitor+mat
11.內存泄漏有哪些
- 集合類泄漏(集合一直引用着被添加進來的元素對象)
- 單例/靜態變量造成的內存泄漏(生命週期長的持有了生命週期短的引用)
- 匿名內部類/非靜態內部類
- 資源未關閉造成的內存泄漏
- 網絡,文件等流忘記關閉
- 手動註冊廣播時,退出時忘記unregisterReceiver()
- Service執行完成後忘記stopSelf()
- EventBus等觀察者模式的框架忘記手動解除註冊
12.app線程優化
線程池 避免存在大量的Thread,重用線程池內部的線程,從而避免了線程的創建和銷燬帶來的性能開銷,同時能有效控制線程池的最大併發數,避免大量線程因互相搶佔系統資源而導致阻塞線現象發生。推薦閱讀 《Android開發藝術探索》 第11章。
分類
- FixedThreadPool 數量固定的線程池
- CachedThreadPool 只有非核心線程,數量不定,空閒線程有超時機制,比較適合執行大量耗時較少的任務
- ScheduledThreadPool 核心線程數量固定,非核心線程沒有限制.主要用於執行定時任務和具有固定中週期的重複任務.
- SingleThreadPool 只有一個核心線程,確保所有的任務在同一個線程順序執行,統一外界任務到一個線程中,這使得在這些任務之間不需要處理線程同步 的問題. 優點
- 減少在創建和銷燬線程上所花的時間以及系統資源的開銷
- 不使用線程池有可能造成系統創建大量的線程而導致消耗完系統內存以及"過度切換" 注意點
13.Android換膚如何實現,原理
重新設置LayoutInflater的Factory2,從而攔截創建View的過程,然後搞成自己的控件,想怎麼換膚就怎麼換膚.
14.fresco原理,glide原理,兩者區別,哪個更省內存
這塊暫時不懂,加入todo
15.DialogFragment 黑邊
16.Handler原理,Android 消息機制
Handler機制的關鍵在於對於ThreadLocal原理的理解,線程私有數據,利用ThreadLocal機制將Looper存放到線程內部,perfect !
17.Android 系統架構
應用層,應用框架層,系統運行庫層,硬件抽象層和Linux內核層
18.常用佈局有哪些
- FrameLayout,LinearLayout,RelativeLayout,ConstraintLayout,CoordinatorLayout等
19.Android數據存儲有幾種方式
- SharedPreferences: 小東西,最終是xml文件中,key-value的形式存儲的.
- 文件
- 數據庫
- ContentProvider
- 網絡
20.View,SurfaceView
- View是Android中所有控件的基類
- View適用於主動更新的情況,而SurfaceView則適用於被動更新的情況,比如頻繁刷新界面。
- View在主線程中對頁面進行刷新,而SurfaceView則開啓一個子線程來對頁面進行刷新。
- View在繪圖時沒有實現雙緩衝機制,SurfaceView在底層機制中就實現了雙緩衝機制。
21.jni調用流程
隔壁老李頭的系列文章非常棒,地址在這裏
22.組件之間相互引用 如何解決
- 調用其他組件的對外提供的方法:之前看到過一種思路,利用"接口+實現"的方式,定義一個ComponentBase 中間層,然後裏面有每個組件對外提供方法調用的Interface,每個組件在初始化的時候就把這些Interface給實現了,然後其他組件需要用的時候就從ComponentBase裏面取。
- 界面跳轉:ARouter
23.自定義View 餅狀圖,點擊事件,畫文字
這個大家可以跟着hencoder老師的文章系統學習一下.
24.Android 數字簽名
校驗用戶身份,校驗數據的完整性
25.fragment用在哪裏,與Activity的區別
- 當Activity需要模塊化的時候
- 不同設備上的適配,比如平臺和手機
- Activity相對Fragment而言,非常笨重,一般小界面小模塊用Fragment比較合適.或者首頁的tab之類的.
26.RxJava原理
觀察者模式,鏈式
27.EventBus原理
不太瞭解原理,很少使用,好像也是基於觀察者模式的一個框架。
28.View繪製原理
主要是分析measure,layout,draw的過程。
29.Retrofit和OkHttp原理,攔截器
- Retrofit的話,源碼寫的非常非常棒.主要是通過動態代理+獲取方法上面的註解等,然後組裝請求網絡的參數,最後用OkHttp去請求網絡
- OkHttp的攔截器鏈設計得非常巧妙,是典型的責任鏈模式.並最終由最後一個鏈處理了網絡請求,並拿到結果.
30.點擊事件傳遞機制,事件分爲哪幾種
事件傳遞大體過程: Activity--> Window-->DecorView --> View樹從上往下
,傳遞過程中誰想攔截就攔截自己處理,MotionEvent是Android中的點擊事件。
主要事件類型
- ACTION_DOWN 手機初次觸摸到屏幕事件
- ACTION_MOVE 手機在屏幕上滑動時觸發,會回調多次
- ACTION_UP 手指離開屏幕時觸發
31.anr如何產生,Service觸發anr是多長時間(20秒),如何解決anr?如何解決那種莫名其妙的anr?
我覺得anr就是在主線程做了耗時操作,比如io、讀寫文件、數據庫操作等等。 anr發生之後一般會有日誌,在/data/anr/traces.txt裏面。
2.32 Dialog和Activity是同一個Window?
不是同一個。
- Activity的attach方法,這裏是爲Activity實例化了一個PhoneWindow實例
- Dialog的構造方法裏面也是實例化了一個PhoneWindow實例
33.Window,Activity,Dectorview之間的關係
Activity裏面實例化了一個Window,Window裏面有一個DecorView(根佈局)。
34.ConstraintLayout和RelativeLayout在繪製方面有何差別?
todo
35.onClick事件和onTouchListener在哪裏回調?
如果一個View需要處理事件,它設置了OnTouchListener,那麼OnTouchListener的onTouch方法會被回調。如果onTouch返回false,則onTouchEvent會被調用,反之不會。在onTouchEvent方法中,事件爲Action,UP的時候會回調OnClickListener的onClick方法,可見OnClickListener的優先級很低。
36.應用如何保活?
這個確實不怎麼了解,主要是不建議保活,提升用戶體驗,特別是安卓高版本,谷歌是封殺得很嚴格的,不建議保活。
37.LinearLayout是如何測量(measure)的?如果有weight又是如何測量的?
先做一次測量,做完之後有空間剩餘,有weight的View再測量一下,分一下剩餘的空間。
38.屏幕適配
先前有鴻神的AndroidAutoLayout,根據寬高進行控件縮放,非常經典,很多項目可能都還在使用,但是已經停止更新了。然後就是有名的今日頭條方案,出來還是有點時間了。原理其實就是更改density。
屏幕的寬度=設計稿寬度 * density
然後有AndroidAutoSize庫,將今日頭條方案融合進去還完善了很多問題,易用,完美。
3. 其他
1. Java四種引用
- 強引用,默認就是,寧願OOM,也不回收
- 弱引用,內存不夠會被回收
- 軟引用,GC時會被回收
- 虛引用,它的作用在於跟蹤垃圾回收過程,在對象被收集器回收時收到一個系統通知。
2.項目中遇到的最困難的事情是什麼?如何解決的?
每個人遇到的情況不同,這個提前思考一下自己做過的項目最有挑戰的地方。
3.Git基本操作
4.Kotlin優勢
- 完全兼容java
- 空安全
- 支持lambda表達式
- 支持擴展函數
- 更少的代碼量,更快的開發速度
缺點就是有時候代碼閱讀性可能會降低。
5.Kotlin 協程是什麼?
就是一個線程框架,提供了一套操作線程的api.
6.二叉樹,廣度優先遍歷,深度優先遍歷
推薦小灰的漫畫算法
7.tcp,http,https,socket
8.敏捷開發
9.你經常使用哪些設計模式,常見設計模式的運用
10.3年之後工資怎麼想的
11.你的優勢
12.職業規劃(3年後幹啥,5年後幹啥)
13.應用,進程,線程之間的區別
進大廠的訣竅
經過這幾年的“摸爬滾打”,我發現進大廠確實有一些訣竅,對於和我一樣背景一般的同學,只要你抓住了訣竅,進大廠不是夢。
1)一定要提前準備,至少準備個一個月,網上的面試題多看看,對於那些高頻題目,帶着理解去學習,實在不能理解的就背下來,大家高考的時候不都是背過來的。
2)大廠通常有很多部門,每個部門的hc數和招人標準都不一樣,即便是同個部門,如果hr不同,標準肯定也不一樣,重複投簡歷可以增大我們拿到面試機會的概率。同理,重複面試不同的部門,也可以增大我們進大廠的概率。
3)大廠經常會佈局新業務,新業務需要快速啓動入場,hc通常會有很多,因此招人的標準會稍微降低,這個時候是個絕佳的機會。我當時進的就是個新的業務部門。
面試系統複習路線
有時候,選擇比努力更加重要,機遇比奮鬥更加重要。但是,機會只留給有準備的人。我們只有時刻準備着,才能在機會到來的時候,去抓住它。
這裏給大家分享一下我的面試複習路線,有需要的朋友可以參考一下:
1、看視頻進行系統學習
前幾年的Crud經歷,讓我明白自己真的算是菜雞中的戰鬥機,也正因爲Crud,導致自己技術比較零散,也不夠深入不夠系統,所以重新進行學習是很有必要的。我差的是系統知識,差的結構框架和思路,所以通過視頻來學習,效果更好,也更全面。關於視頻學習,個人可以推薦去B站進行學習,B站上有很多學習視頻,唯一的缺點就是免費的容易過時。
2、進行系統梳理知識,提升儲備
客戶端開發的知識點就那麼多,面試問來問去還是那麼點東西。所以面試沒有其他的訣竅,只看你對這些知識點準備的充分程度。so,出去面試時先看看自己複習到了哪個階段就好。
系統學習方向:
架構師築基必備技能:深入Java泛型+註解深入淺出+併發編程+數據傳輸與序列化+Java虛擬機原理+反射與類加載+動態代理+高效IO
Android高級UI與FrameWork源碼:高級UI晉升+Framework內核解析+Android組件內核+數據持久化
360°全方面性能調優:設計思想與代碼質量優化+程序性能優化+開發效率優化
解讀開源框架設計思想:熱修復設計+插件化框架解讀+組件化框架設計+圖片加載框架+網絡訪問框架設計+RXJava響應式編程框架設計+IOC架構設計+Android架構組件Jetpack
NDK模塊開發:NDK基礎知識體系+底層圖片處理+音視頻開發
微信小程序:小程序介紹+UI開發+API操作+微信對接
Hybrid 開發與Flutter:Html5項目實戰+Flutter進階
知識梳理完之後,就需要進行查漏補缺,所以針對這些知識點,我手頭上也準備了不少的電子書和筆記,這些筆記將各個知識點進行了完美的總結。
3、讀源碼,看實戰筆記,學習大神思路
“編程語言是程序員的表達的方式,而架構是程序員對世界的認知”。所以,程序員要想快速認知並學習架構,讀源碼是必不可少的。閱讀源碼,是解決問題 + 理解事物,更重要的:看到源碼背後的想法;程序員說:讀萬行源碼,行萬種實踐。
4、面試前夕,刷題衝刺
面試的前一週時間內,就可以開始刷題衝刺了。請記住,刷題的時候,技術的優先,算法的看些基本的,比如排序等即可,而智力題,除非是校招,否則一般不怎麼會問。
關於面試刷題,我個人也準備了一套系統的面試題,幫助你舉一反三:
以上內容均免費分享給大家,需要完整版的朋友,點這裏可以看到全部內容。或者關注主頁掃描加 微信 獲取。