復(fù)習(xí)

java相關(guān):面試中關(guān)于Java你所需知道的的一切

一:架構(gòu)方面

1、模塊化組件化開發(fā)架構(gòu)

一開始使用比較簡單的架構(gòu) ,界面->邏輯層->工具包層,后面改為分業(yè)務(wù)模塊->工具包,但是業(yè)務(wù)模塊之間存在大量耦合?,F(xiàn)在將業(yè)務(wù)模塊再具體劃分,比如購物流程模塊,地址選擇管理模塊,消息模塊。自己寫的router,沒有用注解,沒有依賴注入,寫了大量的映射和接口注冊。借鑒阿里的Arouter[Alibaba-ARouter] 新版本解讀與控制反轉(zhuǎn)在移動端的應(yīng)用

Android開發(fā):由模塊化到組件化

Arouter:自定義注解

采用arr方式解決重復(fù)依賴

采用新的網(wǎng)絡(luò)請求框架Retrofit+OkHttp,新的圖片及下載框架,okhttp,規(guī)范了接口定義以及數(shù)據(jù)加密等。

當(dāng)然,我們還做了很多的新的嘗試,RecycleView替換了ListView,狀態(tài)欄Immersive Mode設(shè)計,組件化開發(fā)的嘗試,App功能動態(tài)化配置,通用自定義控件設(shè)計以及國際化設(shè)配等。

ARouter的優(yōu)勢:

編譯器處理注解產(chǎn)生映射文件,運行期加載映射文件實現(xiàn)路由

Bootstrapping、Extensibility以及Simple & Enough

編譯期間:頁面自動注冊—注解&注解處理器

運行期間:動態(tài)加載—–分組管理,按需加載

全局?jǐn)r截器

依賴注入

運行期動態(tài)修改路由

降級問題

2、hybrid架構(gòu)

① NativeUI組件,header組件、消息類組件

② 通訊錄、系統(tǒng)、設(shè)備信息讀取接口

③ H5與Native的互相跳轉(zhuǎn),比如H5如何跳到一個Native頁面,H5如何新開Webview做動畫跳到另一個H5頁面

4、數(shù)據(jù)請求,數(shù)據(jù)操作的接口,工具包之類

android中通信方式:

1、傳統(tǒng)的JavascriptInterface,setJavaScriptEnabled呀小心xss攻擊,4.2已修復(fù)

2、JSbridge,定義一套協(xié)議

3、代碼重構(gòu)的經(jīng)驗

首先講述自己的工程架構(gòu)演變,由普通依賴到模塊化組件化,路由結(jié)構(gòu),通信原理,怎樣解耦。然后問面試官對中小型公司自己這一套改進有沒有什么建議,引用RXjava這類開源框架。提到自己對知識的渴望,然而在小公司人員不足和業(yè)務(wù)量不龐大的情況體驗不到它的好處,特別想進大的平臺加深自己對整個架構(gòu)的優(yōu)點的深入理解。

4、AOP OOP

面向切面(從左到右的關(guān)系,將那些與業(yè)務(wù)無關(guān),卻為業(yè)務(wù)模塊所共同調(diào)用的邏輯或責(zé)任封裝到一個可重用模塊,并將其名為“Aspect”)。Android中應(yīng)用:網(wǎng)絡(luò)請求,圖片操作,數(shù)據(jù)解析,文件操作,Log,格式轉(zhuǎn)換等共用型Util包。

面向?qū)ο螅鹤⒅厣舷聦?,封裝、繼承和多態(tài)性等概念來建立一種對象層次結(jié)構(gòu),允許你定義從上到下的關(guān)系,但并不適合定義從左到右的關(guān)系

二:性能優(yōu)化和內(nèi)存優(yōu)化具體經(jīng)驗

Runtime.getRuntime().maxMemory()最大可分配內(nèi)存

Runtime.getRuntime().freeMemory()當(dāng)前空閑內(nèi)存

Runtime.getRuntime().totalMemory()當(dāng)前占用內(nèi)存

內(nèi)存檢測工具MemoMonitor,android device monitor

優(yōu)化:

數(shù)據(jù)結(jié)構(gòu)的優(yōu)化(1、StringBuilder拼接;2、SparseArray(2個數(shù)組,int型的Key數(shù)組,value數(shù)組)、ArrayMap(hash值的Key數(shù)組,keyvalue成對的數(shù)組)(添加、刪除、查找數(shù)據(jù)的時候都是先使用二分查找法得到相應(yīng)的index)代替HashMap,HashMap初始就會創(chuàng)建容量為16的數(shù)組,而且每次都是以2倍的容量遞增,SparseArray、ArrayMap;3、內(nèi)存抖動;4、使用parcelable代替serializebal,serializebal會產(chǎn)生大量臨時變量引起GC)

對象復(fù)用:列表布局里單Item的復(fù)用,避免在ondraw里進行對象的創(chuàng)建

避免內(nèi)存泄露:內(nèi)存泄漏會導(dǎo)致heap可用內(nèi)存越來越少,這時當(dāng)有一個稍大的內(nèi)存占用,很可能會造成OOM,還有一點它會讓GC頻繁的觸發(fā)造成內(nèi)存抖動。造成內(nèi)存泄漏的一些點:單例使用了context(使用applicationcontext),匿名內(nèi)部類,handler,static變量,資源未關(guān)閉(io流,cursor使用了一定要及時關(guān)閉),asyntask,耗時操作可以考慮使用service

OOM優(yōu)化:大部分是圖片造成的。使用軟引用弱引用;臨死bitmap的及時回收;某些大內(nèi)存分配時可以使用try/catch,即使失敗了也不會崩潰;加載bitmap時注意(縮放比例、解碼格式ARGB_4444、局部加載),LUR cache

三:用到的開源框架原理

okhttp原理:

首先使用建造者模式構(gòu)建request,然后經(jīng)過一系列攔截器(包括跟服務(wù)器橋接的響應(yīng)BridgeInterapter,CacheInterapter,ConnectInterapter,Callserver),攔截器連成了一條鏈InterappetChain.底層用了okio連接,socket。異步請求做了一個線程池的封裝。

多路復(fù)用機制(nextconnection從connection池里獲取到的話,就復(fù)用,獲取不到才create),重連機制(判斷是否能onresponce,獲取不到則recovery,循環(huán))

支持HTTP2/SPDY黑科技

socket自動選擇最好路線,并支持自動重連

擁有自動維護的socket連接池,減少握手次數(shù)

擁有隊列線程池,輕松寫并發(fā)

擁有Interceptors輕松處理請求與響應(yīng)(比如透明GZIP壓縮,LOGGING)

實現(xiàn)基于Headers的緩存策略

volley原理,

glide原理

glide .with(context):所有request請求是通過requestmanagerrechiver這個類把requestmanager綁定到activity或fragment類。創(chuàng)建了一個fragment把requestmanager傳給fragmengt,與activity生命周期綁定

.load(url) : 創(chuàng)建DrawableTypeRequest,添加一系列條件初始化

.into里面將imageview與lifecycle生命周期關(guān)聯(lián)了起來,里面的核心是一個引擎類Engine,里面有個Load,先從緩存中讀取,Engine中包含LruCache緩存及一個當(dāng)前正在使用的active資源Cache(弱引用),Cache優(yōu)先級LruCache>activeCache,從LruCache取出使用了則會放到activeCache,緩存沒有則通過線程池去獲取圖片,Engine在初始化時要傳入兩個ExecutorService,即會有兩個線程池,一個用來從DiskCache獲取resource,另一個用來從Source中獲?。ㄍǔJ窍螺d)。先進入DiskCacheService中執(zhí)行獲取,如果沒找到則進入SourceState,進到SourceService中執(zhí)行下載。

Glide的Target:

負(fù)責(zé)圖片加載的回調(diào)中

4.4以前是Bitmap復(fù)用必須長寬相等才可以復(fù)用

4.4及以后是Size>=所需就可以復(fù)用,只不過需要調(diào)用reconfigure來調(diào)整尺寸

Glide用AttributeStategy和SizeStrategy來實現(xiàn)兩種策略

圖片池在收到傳來的Bitmap之后,通過長寬或者Size來從KeyPool中獲取Key(對象復(fù)用到了極致,連Key都用到了Pool),然后再每個Key對應(yīng)一個雙向鏈表結(jié)構(gòu)來存儲。每個Key下可能有很多個待用Bitmap

取出后要減少圖片池中記錄的當(dāng)前Size等,并對Bitmap進行eraseColor(Color.TRANSPAENT)操作確保可用

butterknife原理

四:Framework層常用模塊原理

AMS和WMS原理

audioflinger原理,

整個音頻系統(tǒng)的核心與難點,啟到承上(為上層提供訪問接口)啟下(通過HAL來管理音頻設(shè)備)的作用。

audiotrack原理,

播放聲音,2種模式,AudioTrack中有MODE_STATIC和MODE_STREAM兩種分類。STREAM的意思是由用戶在應(yīng)用程序通過write方式把數(shù)據(jù)一次一次得寫到audiotrack中。這個和我們在socket中發(fā)送數(shù)據(jù)一樣,應(yīng)用層從某個地方獲取數(shù)據(jù),例如通過編解碼得到PCM數(shù)據(jù),然后write到audiotrack。

這種方式的壞處就是總是在JAVA層和Native層交互,效率損失較大。

而STATIC的意思是一開始創(chuàng)建的時候,就把音頻數(shù)據(jù)放到一個固定的buffer,然后直接傳給audiotrack,后續(xù)就不用一次次得write了。AudioTrack會自己播放這個buffer中的數(shù)據(jù)。

這種方法對于鈴聲等內(nèi)存占用較小,延時要求較高的聲音來說很適用。

vold框架原理,

1,有一個netlinkmanager接收來自Linux內(nèi)核的uevent消息,例如sd卡的插拔會引起kernel向NM發(fā)送uevent消息,

2,netlinkmanager將這些消息轉(zhuǎn)發(fā)給volumeManager,volumeManager做一些操作后將消息通過CommandListener發(fā)送給MountService.MountService收到消息后做進一步處理。比如volumeManager----disk insert-----MountService----Mount----Vold,表示掛載這個SD卡

4,CommandListener內(nèi)部封裝了一個socket用于跨進程通信,在vold進程中屬于服務(wù)端,接收來自mountservice的控制命令,同時volumeManager和netlinkmanager又通過它發(fā)送消息給MountService

dhcp協(xié)議

binder原理:

傳統(tǒng)·IPC·:需要做兩次拷貝:用戶空間->內(nèi)核空間->用戶空間

binder:由Binder驅(qū)動負(fù)責(zé)管理數(shù)據(jù)接收緩存,驅(qū)動會根據(jù)發(fā)送數(shù)據(jù)包的大小,使用最佳匹配算法從緩存池中找到一塊大小合適的空間,將數(shù)據(jù)從發(fā)送緩存區(qū)復(fù)制過來,mmap()分配的內(nèi)存是映射在接收方用戶空間里的.為了實現(xiàn)用戶空間到用戶空間的拷貝,mmap()分配的內(nèi)存除了映射進了接收方進程里,還映射進了內(nèi)核空間。所以調(diào)用copy_from_user()將數(shù)據(jù)拷貝進內(nèi)核空間也相當(dāng)于拷貝進了接收方的用戶空間,這就是Binder只需一次拷貝的‘秘密’。

五:android重要知識點

Android開發(fā)--如何減小Apk文件的大小


靜態(tài)編譯和動態(tài)編譯

靜態(tài) include $(BUILD_STATIC_JAVA_LIBRARY)

動態(tài) include $(BUILD_JAVA_LIBRARY)

a、可以在apk的Android.mk中去添加動態(tài)jar包的依賴,使用的時候jar包的類可以直接調(diào)用

b、apk編譯的時候如果不在android.mk中做動態(tài)jar包的依賴的話,可以在使用的時候去動態(tài)尋找system/framework/SkyFramework的jar包,去load此jar包,在去找jar包中的 ? class;這種方法?apk中可以直接調(diào)用接口中自己定義的方法,編譯時不需要去做android.mk的依賴。 實現(xiàn)的地方直接繼承接口即可,打包到動態(tài)jar包中。

這樣可以實現(xiàn)分離,接口的定義和實現(xiàn)做到分離,在開發(fā)階段非常有用,不同部門直接可以并行進行。

網(wǎng)絡(luò)編程,服務(wù)器端編程

安卓中Fragment應(yīng)用,相比Activity的好處

Fragment可以使你能夠?qū)ctivity分離成多個可重用的組件,每個都有它自己的生命周期和UI。

Fragment可以輕松得創(chuàng)建動態(tài)靈活的UI設(shè)計,可以適應(yīng)于不同的屏幕尺寸。從手機到平板電腦。

Fragment是一個獨立的模塊,緊緊地與activity綁定在一起??梢赃\行中動態(tài)地移除、加入、交換等。

Fragment提供一個新的方式讓你在不同的安卓設(shè)備上統(tǒng)一你的UI。

Fragment 解決Activity間的切換不流暢,輕量切換。

Fragment 替代TabActivity做導(dǎo)航,性能更好。

Fragment 在4.2.版本中新增嵌套fragment使用方法,能夠生成更好的界面效果。

Fragment做局部內(nèi)容更新更方便,原來為了到達這一點要把多個布局放到一個activity里面,現(xiàn)在可以用多Fragment來代替,只有在需要的時候才加載Fragment,提高性能。

可以從startActivityForResult中接收到返回結(jié)果,但是View不能。

recyclerview的復(fù)用原理

熱修復(fù)原理

android7.0原理--簽名機制:

android 7.0中引入了APK Signature Scheme V2(Full APK Signature),而V1(jar Signature) 來自JDK;

V1:僅驗證未解壓的文件內(nèi)容,這樣APK 簽署后可進行許多修改 ,可以移動甚至重新壓縮文件;

V2:驗證壓縮文件的所有字節(jié),而不是單個 ZIP 條目,因此,在簽名后無法再更改(包括 zipalign)。正因如此,現(xiàn)在在編譯過程中,我們將壓縮、調(diào)整和簽署合并成一步完成。好處顯而易見,更安全而且新的簽名可縮短在設(shè)備上進行驗證的時間(不需要費時地解壓縮然后驗證),從而加快應(yīng)用安裝速度。如有任何自定義任務(wù)篡改 APK 文件或?qū)ζ溥M行后處理(無論以任何方式),那么V2 簽名會有作廢的風(fēng)險,從而導(dǎo)致您的 APK 與 Android 7.0 及更高版本不兼容。


六:android重要知識點

java類加載機制

類加載的過程包括了加載(查找并加載類的二進制數(shù)據(jù))、驗證(確保被加載的類的正確性:確保Class文件的字節(jié)流中包含的信息符合當(dāng)前虛擬機的要求,并且不會危害虛擬機自身的安全)、準(zhǔn)備(為類的靜態(tài)變量分配內(nèi)存,并將其初始化為默認(rèn)值,public static int value = 3,這是設(shè)為0)、解析(把類中的符號引用轉(zhuǎn)換為直接引用)、初始化(類的靜態(tài)變量賦予正確的初始值,JVM負(fù)責(zé)對類進行初始化,主要對類變量進行初始化)五個階段。

解析階段則不一定,它在某些情況下可以在初始化階段之后開始,這是為了支持Java語言的運行時綁定(也成為動態(tài)綁定或晚期綁定)

類加載器:雙親委派模型,如果存在父類加載器,就委派給父類加載器加載,如果不存在父類加載器,就檢查是否是由啟動類加載器加載的類,通過調(diào)用本地方法,如果父類加載器和啟動類加載器都不能完成加載任務(wù),才調(diào)用自身的加載功能。

意義:系統(tǒng)類防止內(nèi)存中出現(xiàn)多份同樣的字節(jié)碼,-保證Java程序安全穩(wěn)定運行

java編譯過程

分析和輸入到符號表

注解處理

語義分析和生成class字節(jié)碼文件

GC

final用法,反射原理

反射:先講反射機制,反射就是程序運行期間JVM會對任意一個類洞悉它的屬性和方法,對任意一個對象都能夠訪問它的屬性和方法。依靠此機制,可以動態(tài)的創(chuàng)建一個類的對象和調(diào)用對象的方法。

其次就是反射相關(guān)的API,只講一些常用的,比如獲取一個Class對象。Class.forName(完整類名)。通過Class對象獲取類的構(gòu)造方法,class.getConstructor。根據(jù)class對象獲取類的方法,getMethod和getMethods。使用class對象創(chuàng)建一個對象,class.newInstance等。

最后可以說一下反射的優(yōu)點和缺點,優(yōu)點就是增加靈活性,可以在運行時動態(tài)獲取對象實例。缺點是反射的效率很低,而且會破壞封裝,通過反射可以訪問類的私有方法,不安全。

注解原理

io,nio區(qū)別和原理,NIO中select的實現(xiàn)機制

Java IO是面向流的,這意味著我們需要每次從流中讀取一個或多個字節(jié),直到讀取完所有字節(jié);NIO是面向緩沖的,也就是說會把數(shù)據(jù)讀取到一個緩沖區(qū)中,然后對緩沖區(qū)中的數(shù)據(jù)進行相應(yīng)處理。

Java IO是阻塞IO,而NIO是非阻塞IO。

Java NIO中存在一個稱為選擇器(selector)的東西,它允許你把多個通道(channel)注冊到一個選擇器上,然后使用一個線程來監(jiān)視這些通道:若這些通道里有某個準(zhǔn)備好可以開始進行讀或?qū)懖僮髁耍瑒t開始對相應(yīng)的通道進行讀寫。而在等待某通道變?yōu)榭勺x/寫期間,請求對通道進行讀寫操作的線程可以去干別的事情。

多線程同步的幾個方式及區(qū)別

1、synchronized (托管給JVM執(zhí)行的),2、重入鎖(retrandlock,讀寫ReentrantReadWriteLock)3、volatile關(guān)鍵字,阻塞隊列(linkedblockingqueen),是java代碼自己實現(xiàn)的,4、局部變量(ThreadLocal,提到Looper.prepare)5、使用同步容器(vector,hashtable,ConcurrentHashMap),6、CountDownLatch

樂觀鎖和悲觀鎖的區(qū)別

悲觀鎖,就是很悲觀,每次去拿數(shù)據(jù)的時候都認(rèn)為別人會修改,所以每次在拿數(shù)據(jù)的時候都會上鎖,這樣別人想拿這個數(shù)據(jù)就會block直到它拿到鎖。傳統(tǒng)的關(guān)系型數(shù)據(jù)庫里邊就用到了很多這種鎖機制,比如行鎖,表鎖等,讀鎖,寫鎖等,都是在做操作之前先上鎖。

樂觀鎖,就是很樂觀,每次去拿數(shù)據(jù)的時候都認(rèn)為別人不會修改,所以不會上鎖,但是在更新的時候會判斷一下在此期間別人有沒有去更新這個數(shù)據(jù),可以使用版本號等機制。樂觀鎖適用于多讀的應(yīng)用類型,這樣可以提高吞吐量,像數(shù)據(jù)庫如果提供類似于write_condition機制的其實都是提供的樂觀鎖。

synchronized是基于悲觀鎖,比較適用于大量線程頻繁請求,lock是樂觀鎖,適用于不是很頻繁的

ReentrantLock非中斷鎖(一直等待)和中斷鎖(lock.lockInterruptibly()),得到中斷響應(yīng)則中斷,還提供公平鎖及非公平鎖。

stringbuffer和stringbuilder區(qū)別

stringbuffer是線程安全,適合多線程操作字符串,stringbuilder是非線程安全的,適合單線程大量操作字符串,在單線程中的性能比StringBuffer高

Java重寫hashCode(),equals()函數(shù)的時機

雖然 a 與 b不是同一個對象,但是你希望無論使用 a 還是 b 都可以從map中取出相同的 value,也就是你會認(rèn)為 a 與 b 的內(nèi)容是相同的,就是當(dāng)把他們作為索引值,或者在 set 中不會重復(fù)出現(xiàn),這些情況適用于重寫他們。重寫equals一定要重寫Hashcode,這是java規(guī)定的。如果不滿足這個條件則map, set等的處理會出現(xiàn)錯誤的。

get()和post()區(qū)別

語義的區(qū)別,設(shè)計不同,get是為請求,post是提交改變服務(wù)器狀態(tài)

1. GET使用URL或Cookie傳參。而POST將數(shù)據(jù)放在BODY中。

2. GET的URL會有長度上的限制,則POST的數(shù)據(jù)則可以非常大。

3. POST比GET安全,因為數(shù)據(jù)在地址欄上不可見。

成員變量的類型

靜態(tài)變量,實例變量,final修飾的常量

七:數(shù)據(jù)結(jié)構(gòu)算法相關(guān)

如何判斷一個鏈表中存在環(huán)

1遍歷做標(biāo)記,2:便利把指針反轉(zhuǎn),如果走到開始就有環(huán),3:雙指針 一個一次走一步,一個一次走兩步

各排序、冒泡排序、二分查找思想原理

二叉樹

問1000壇酒,里面有1壇毒酒,需要多少只老鼠才能判斷出毒酒是哪壇?

都轉(zhuǎn)為二進制 2的10次方為1024,10只老鼠


Linux中查看內(nèi)存使用狀況命令?查看網(wǎng)絡(luò)狀況?

cat/proc/meminfo? free

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容