by? hzwusibo 20190504
最近換工作,面試了一波。? ?本篇文章分享下面試中的真題回憶,與個(gè)別地方記得不是很清楚了。
拼多多面試
一面:?
1、byte、char區(qū)別
byte?是字節(jié)數(shù)據(jù)類型?,是有符號(hào)型的,占1?個(gè)字節(jié);大小范圍為-128—127 。char?是字符數(shù)據(jù)類型?,是無(wú)符號(hào)型的,占2字節(jié)(Unicode碼?);大小范圍?是0—65535?;char是一個(gè)16位二進(jìn)制的Unicode字符,JAVA用char來(lái)表示一個(gè)字符?。
char可以表中文字符,byte不可以。
1byte?存1個(gè)英文字母,2個(gè)byte存一個(gè)漢字。
Java默認(rèn)的字符編碼是Unicode。
https://blog.csdn.net/witnessai1/article/details/52540910
2、recycleview的優(yōu)點(diǎn) 缺點(diǎn)

a.替代Listview和GridView,既可以加載列表也可以加載表格
b.支持瀑布流這樣高級(jí)的顯示方式
c.內(nèi)置了強(qiáng)大的垃圾回收機(jī)制
d.規(guī)范了Viewholder的使用
RecycleView和ListView的區(qū)別
https://blog.csdn.net/u012221316/article/details/80297036
RecyclerView使用總結(jié)-------上
http://m.itdecent.cn/p/5ad99a1170ab
https://www.cnblogs.com/cr330326/p/5534915.html
因?yàn)镴ava代碼是非常容易反編碼的,況且Android開(kāi)發(fā)的應(yīng)用程序是用Java代碼寫(xiě)的,為了很好的保護(hù)Java源代碼,我們需要對(duì)編譯好后的class文件進(jìn)行混淆。
ProGuard是一個(gè)混淆代碼的開(kāi)源項(xiàng)目,它的主要作用是混淆代碼,殊不知ProGuard還包括以下4個(gè)功能。
壓縮(Shrink):檢測(cè)并移除代碼中無(wú)用的類、字段、方法和特性(Attribute)。
優(yōu)化(Optimize):對(duì)字節(jié)碼進(jìn)行優(yōu)化,移除無(wú)用的指令。
混淆(Obfuscate):使用a,b,c,d這樣簡(jiǎn)短而無(wú)意義的名稱,對(duì)類、字段和方法進(jìn)行重命名。
預(yù)檢(Preveirfy):在Java平臺(tái)上對(duì)處理后的代碼進(jìn)行預(yù)檢,確保加載的class文件是可執(zhí)行的。
總而言之,根據(jù)官網(wǎng)的翻譯:Proguard是一個(gè)Java類文件壓縮器、優(yōu)化器、混淆器、預(yù)校驗(yàn)器。壓縮環(huán)節(jié)會(huì)檢測(cè)以及移除沒(méi)有用到的類、字段、方法以及屬性。優(yōu)化環(huán)節(jié)會(huì)分析以及優(yōu)化方法的字節(jié)碼。混淆環(huán)節(jié)會(huì)用無(wú)意義的短變量去重命名類、變量、方法。這些步驟讓代碼更精簡(jiǎn),更高效,也更難被逆向(破解)。
4、內(nèi)存泄露,優(yōu)化,使用的工具
見(jiàn)內(nèi)存優(yōu)化,什么情況導(dǎo)致內(nèi)存泄漏
5、兩個(gè)A、B? 相互應(yīng)用
軟引用
6、anr問(wèn)題總結(jié) (null指針不是)
有遇到那些anr
怎么避免anr
http://m.itdecent.cn/p/9db73a26a8bd
7、okhttp優(yōu)缺點(diǎn)、源碼,? ? ? 網(wǎng)絡(luò):? HTTP2相對(duì)于http1優(yōu)點(diǎn), (為什么)? https原理(怎么進(jìn)行的連接),為什么比http更耗時(shí)(要進(jìn)行一個(gè)密鑰傳輸)
關(guān)于 HTTP2 和 HTTPS,這些你必須要知道
http://wemedia.ifeng.com/72005448/wemedia.shtml
HTTP2 詳解
http://m.itdecent.cn/p/e57ca4fec26f

2、多路復(fù)用 (MultiPlexing)
在一個(gè) TCP 連接上,我們可以向?qū)Ψ讲粩喟l(fā)送幀,每幀的 stream id 的標(biāo)明這一幀屬于哪個(gè)流,然后在對(duì)方接收時(shí),根據(jù) stream id 拼接每個(gè)流的所有幀組成一整塊數(shù)據(jù)。流的概念實(shí)現(xiàn)了單連接上多請(qǐng)求 - 響應(yīng)并行,解決了線頭阻塞的問(wèn)題,減少了 TCP 連接數(shù)量和 TCP 連接慢啟動(dòng)造成的問(wèn)題。
https原理
https://blog.csdn.net/qq_32998153/article/details/80022489

9、 oom能不能被捕獲,為什么, 有沒(méi)有分配bitmap成功?
https://blog.csdn.net/gvvbn/article/details/79454701
只有在一種情況下,這樣做是可行的:
在try語(yǔ)句中聲明了很大的對(duì)象,導(dǎo)致OOM,并且可以確認(rèn)OOM是由try語(yǔ)句中的對(duì)象聲明導(dǎo)致的,那么在catch語(yǔ)句中,可以釋放掉這些對(duì)象,解決OOM的問(wèn)題,繼續(xù)執(zhí)行剩余語(yǔ)句。
但是這通常不是合適的做法。
Java中管理內(nèi)存除了顯式地catch OOM之外還有更多有效的方法:比如SoftReference, WeakReference, 硬盤(pán)緩存等。
在JVM用光內(nèi)存之前,會(huì)多次觸發(fā)GC,這些GC會(huì)降低程序運(yùn)行的效率。
如果OOM的原因不是try語(yǔ)句中的對(duì)象(比如內(nèi)存泄漏),那么在catch語(yǔ)句中會(huì)繼續(xù)拋出OOM
https://blog.csdn.net/Mr_LiaBill/article/details/50209617
10、handler的原理, loop怎么與handler進(jìn)行綁定
https://blog.csdn.net/lqb3732842/article/details/54947159
https://blog.csdn.net/lmj623565791/article/details/38377229
handler獲取當(dāng)前線程中的looper對(duì)象,looper用來(lái)從存放Message的MessageQueue中取出Message,再有handler進(jìn)行Message的分發(fā)與處理。
a、首先Looper.prepare()在本線程中保存一個(gè)Looper實(shí)例,然后該實(shí)例中保存一個(gè)MessageQueue對(duì)象;因?yàn)長(zhǎng)ooper.prepare()在一個(gè)線程中只能調(diào)用一次,所以MessageQueue在一個(gè)線程中只會(huì)存在一個(gè)。
b、Looper.loop()會(huì)讓當(dāng)前線程進(jìn)入一個(gè)無(wú)限循環(huán),不端從MessageQueue的實(shí)例中讀取消息,然后回調(diào)msg.target.dispatchMessage(msg)方法。
c、Handler的構(gòu)造方法,會(huì)首先得到當(dāng)前線程中保存的Looper實(shí)例,進(jìn)而與Looper實(shí)例中的MessageQueue想關(guān)聯(lián)。
d、Handler的sendMessage方法,會(huì)給msg的target賦值為handler自身,然后加入MessageQueue中。
e、在構(gòu)造Handler實(shí)例時(shí),我們會(huì)重寫(xiě)handleMessage方法,也就是msg.target.dispatchMessage(msg)最終調(diào)用的方法。
11、介紹下項(xiàng)目:
12、glide優(yōu)缺點(diǎn), 源碼、Glide會(huì)自動(dòng)判斷ImageView的大小,然后只將這么大的圖片像素加載到內(nèi)存當(dāng)中?
怎么實(shí)現(xiàn)的
Glide也并沒(méi)有使用什么神奇的魔法,它內(nèi)部的實(shí)現(xiàn)原理其實(shí)就是上面那篇文章當(dāng)中介紹的技術(shù),因此掌握了最基本的實(shí)現(xiàn)原理,你也可以自己實(shí)現(xiàn)一套這樣的圖片壓縮機(jī)制。Android高效加載大圖、多圖解決方案,有效避免程序OOM
35、Android高效加載大圖、多圖解決方案,有效避免程序OOM
https://blog.csdn.net/guolin_blog/article/details/9316683
36、inSampleSize優(yōu)化
http://m.itdecent.cn/p/f15cd2ed6ec0
13、httpUrlconnetion有沒(méi)有緩存
有
大搜車(chē):
1、mvc、mvp缺點(diǎn)
MVC缺點(diǎn):隨著界面及其邏輯的復(fù)雜度不斷提升,Activity類的職責(zé)不斷增加,以致變得龐大臃腫。
mvp的問(wèn)題在于view層和presenter層是通過(guò)接口連接,在復(fù)雜的界面中,維護(hù)過(guò)多接口的成本很大。?
解決辦法是定義一些基類接口,把網(wǎng)絡(luò)請(qǐng)求結(jié)果,toast等通用邏輯放在里面,然后供定義具體業(yè)務(wù)的接口集成。
2、rxjava
優(yōu)雅的實(shí)現(xiàn)方法 - 基于事件流的鏈?zhǔn)秸{(diào)用
map和flapmap區(qū)別
?flatMap()?和?map()?有一個(gè)相同點(diǎn):它也是把傳入的參數(shù)轉(zhuǎn)化之后返回另一個(gè)對(duì)象。但需要注意,和?map()不同的是,?flatMap()?中返回的是個(gè)?Observable?對(duì)象,并且這個(gè)?Observable?對(duì)象并不是被直接發(fā)送到了?Subscriber?的回調(diào)方法中。
?flatMap()?的原理是這樣的:1. 使用傳入的事件對(duì)象創(chuàng)建一個(gè)?Observable?對(duì)象;2. 并不發(fā)送這個(gè)?Observable, 而是將它激活,于是它開(kāi)始發(fā)送事件;3. 每一個(gè)創(chuàng)建出來(lái)的?Observable?發(fā)送的事件,都被匯入同一個(gè)?Observable?,而這個(gè)?Observable?負(fù)責(zé)將這些事件統(tǒng)一交給?Subscriber?的回調(diào)方法。這三個(gè)步驟,把事件拆成了兩級(jí),通過(guò)一組新創(chuàng)建的?Observable?將初始的對(duì)象『鋪平』之后通過(guò)統(tǒng)一路徑分發(fā)了下去。而這個(gè)『鋪平』就是?flatMap()?所謂的 flat。
3、手寫(xiě)單利模式, (線性安全的)

4、view的事件分發(fā)機(jī)制,什么設(shè)計(jì)模式
職責(zé)鏈
dispatchTouchEvent 分發(fā)事件
onInterceptTouchEvent 攔截事件只有viewgroup才有,view和activity沒(méi)
onTouchEvent 處理點(diǎn)擊事件
1,圖解ACTION_DOWN 事件分發(fā),如果面試的時(shí)候能把下面的圖畫(huà)出來(lái)。能增分不少
dispatchTouchEvent和 onTouchEvent的框里有個(gè)【true---->消費(fèi)】的字,表示的意思是如果方法返回true,那么代表事件就此消費(fèi),不會(huì)繼續(xù)往別的地方傳了,事件終止

2,紅色的箭頭代表ACTION_DOWN 事件的流向
藍(lán)色的箭頭代表ACTION_MOVE 和 ACTION_UP 事件的流向

image
5、 給一個(gè)Arraylist<String >? list 去除中間? ? string 等于 A的 item , 返回list
list中元素可能有重復(fù)
6、view的測(cè)量
https://blog.csdn.net/suyimin2010/article/details/80991737
MeasureSpec這個(gè)類通過(guò)計(jì)算后得出的int值是包裝了View測(cè)量模式和尺寸的,這個(gè)得出的值一個(gè)32位的整型數(shù),高兩位代表了測(cè)量模式,后30位代表了測(cè)量尺寸,View的測(cè)量的模式分為3種,分別對(duì)應(yīng)了UNSPECIFIED、EXACTLY、AT_MOST


7、fragment生命周期

8、onSaveInstanceState(Bundle outState)?、onRestoreInstanceState(Bundle savedInstanceState) 方法
https://blog.csdn.net/u011068702/article/details/70217576
存儲(chǔ):

恢復(fù):

9、注解的保留時(shí)機(jī)
https://blog.csdn.net/cts529269539/article/details/79073115
Retention(保留)注解說(shuō)明,這種類型的注解會(huì)被保留到那個(gè)階段. 有三個(gè)值:
1.RetentionPolicy.SOURCE —— 這種類型的Annotations只在源代碼級(jí)別保留,編譯時(shí)就會(huì)被忽略
2.RetentionPolicy.CLASS —— 這種類型的Annotations編譯時(shí)被保留,在class文件中存在,但JVM將會(huì)忽略
3.RetentionPolicy.RUNTIME —— 這種類型的Annotations將被JVM保留,所以他們能在運(yùn)行時(shí)被JVM或其他使用反射機(jī)制的代碼所讀取和使用.
https://www.cnblogs.com/kingcode/p/7203568.html
10、 工作中最優(yōu)成就感的事情是什么?
11、Glide圖片裁剪
12、進(jìn)程之間通訊方式
bindle? 文件共享? aidl? contentprovider? socket
13、git 恢復(fù)誤刪的分支,怎么恢復(fù)
https://www.cnblogs.com/xd502djj/p/9319980.html
從最近一次commit 中檢出分支,可重命名,本例chon重命名為:reback_remove_branch
git checkout -b reback_remove_branch ddd94a4
媽媽幫
1、Android中為什么主線程不會(huì)因?yàn)長(zhǎng)ooper.loop()方法造成阻塞
2、okhttp源碼
3、gilde源碼
4、介紹項(xiàng)目
5、bindler機(jī)制
百度一面:
1、介紹項(xiàng)目:
2、進(jìn)程通訊方式、bindler原理,bindler怎么進(jìn)行數(shù)據(jù)交換:
3、自己怎么實(shí)現(xiàn)一個(gè)listview? ,事件分發(fā)的處理,? 里面的事件是怎么傳遞,? item中一個(gè)button怎么進(jìn)行監(jiān)聽(tīng) (中onTouch與onClick兩種監(jiān)聽(tīng))
Android ListView工作原理完全解析,帶你從源碼的角度徹底理解
https://blog.csdn.net/guolin_blog/article/details/44996879
Android視圖繪制流程完全解析,帶你一步步深入了解View(二)
https://blog.csdn.net/guolin_blog/article/details/16330267
https://blog.csdn.net/zzsakurazz/article/details/52604173
http://m.itdecent.cn/p/a02cc07b25b1
view的onmseuare、 onlayout、ondraw
Android ViewGroup和View的傳遞事件
https://blog.csdn.net/gyh790005156/article/details/47316343
Android中onTouch與onClick兩種監(jiān)聽(tīng)的完全解析
https://blog.csdn.net/ll530304349/article/details/53036276
4、okhttp源碼,? 源碼設(shè)計(jì)大概流程,OkHttp怎么復(fù)用連接池
https://www.cnblogs.com/qlky/p/7298995.html
okhttp連接池復(fù)用機(jī)制
https://blog.csdn.net/tangjiean/article/details/51729371
5、glide源碼:
6、怎么實(shí)現(xiàn)代碼規(guī)范:
7、說(shuō)說(shuō)用過(guò)異步, 鎖、 lock和synchorinzed的區(qū)別, 在實(shí)現(xiàn)上區(qū)別 ,sync在jvm實(shí)現(xiàn)原理。
synchronized是托管給JVM執(zhí)行的,而lock是java寫(xiě)的控制鎖的代碼
synchronized原始采用的是CPU悲觀鎖機(jī)制,即線程獲得的是獨(dú)占鎖。獨(dú)占鎖意味著其他線程只能依靠阻塞來(lái)等待線程釋放鎖。而在CPU轉(zhuǎn)換線程阻塞時(shí)會(huì)引起線程上下文切換,當(dāng)有很多線程競(jìng)爭(zhēng)鎖的時(shí)候,會(huì)引起CPU頻繁的上下文切換導(dǎo)致效率很低。
而Lock用的是樂(lè)觀鎖方式。所謂樂(lè)觀鎖就是,每次不加鎖而是假設(shè)沒(méi)有沖突而去完成某項(xiàng)操作,如果因?yàn)闆_突失敗就重試,直到成功為止。
Java synchronized 關(guān)鍵字的實(shí)現(xiàn)原理
https://www.cnblogs.com/lykm02/p/4516777.html
Java鎖--Lock實(shí)現(xiàn)原理(底層實(shí)現(xiàn))
https://blog.csdn.net/qpzkobe/article/details/78586619
https://www.cnblogs.com/duanxz/p/3559510.html
8、檢測(cè)內(nèi)存泄露工具,LeakCanary實(shí)現(xiàn)原理。? 有那些內(nèi)存泄露
1、RefWatcher.watch()創(chuàng)建了一個(gè)KeyedWeakReference用于去觀察對(duì)象。
2、然后,在后臺(tái)線程中,它會(huì)檢測(cè)引用是否被清除了,并且是否沒(méi)有觸發(fā)GC。
3、如果引用仍然沒(méi)有被清除,那么它將會(huì)把堆棧信息保存在文件系統(tǒng)中的.hprof文件里。
4、HeapAnalyzerService被開(kāi)啟在一個(gè)獨(dú)立的進(jìn)程中,并且HeapAnalyzer使用了HAHA開(kāi)源庫(kù)解析了指定時(shí)刻的堆??煺瘴募eap dump。
5、從heap dump中,HeapAnalyzer根據(jù)一個(gè)獨(dú)特的引用key找到了KeyedWeakReference,并且定位了泄露的引用。
6、HeapAnalyzer為了確定是否有泄露,計(jì)算了到GC Roots的最短強(qiáng)引用路徑,然后建立了導(dǎo)致泄露的鏈?zhǔn)揭谩?/p>
7、這個(gè)結(jié)果被傳回到app進(jìn)程中的DisplayLeakService,然后一個(gè)泄露通知便展現(xiàn)出來(lái)了。
看完這篇 LeakCanary 原理分析,又可以虐面試官了!
https://mp.weixin.qq.com/s/1jFY_22hoWgCw3CDo2rpOA
拼多多二面
1,項(xiàng)目(? 有聲書(shū)sdk,解析器sdk,主導(dǎo)書(shū)架模塊重構(gòu),接口能不能合并,為什么(批量接口)),
音頻焦點(diǎn)AudioFocus使用
2,? 說(shuō)說(shuō)興趣愛(ài)好,說(shuō)說(shuō)最近看到有沒(méi)有什么框架很有亮點(diǎn)
bravh, gilde的優(yōu)點(diǎn)源碼
3, 項(xiàng)目 怎么實(shí)現(xiàn)正文截圖
4、手寫(xiě)代碼 lrucache緩存, Linkedhashmap的數(shù)據(jù)結(jié)構(gòu)
https://www.cnblogs.com/Java3y/p/8798058.html
內(nèi)存緩存LruCache實(shí)現(xiàn)原理
https://www.cnblogs.com/liuling/archive/2015/09/24/2015-9-24-1.html
5、說(shuō)說(shuō)java的 GC算法
拼多多三面
1、多進(jìn)程有哪些,畫(huà)出bundle的實(shí)現(xiàn)圖,怎么實(shí)現(xiàn)數(shù)據(jù)的通訊, 數(shù)據(jù)怎么拷貝(序列化,反序列化),說(shuō)說(shuō)aidl實(shí)現(xiàn)過(guò)程
http://m.itdecent.cn/p/09cf72d934a7
2、說(shuō)說(shuō)rxjava
3、覺(jué)得項(xiàng)目最大的亮點(diǎn)
(說(shuō)的自定義view)
說(shuō)說(shuō)自己實(shí)現(xiàn)? 繼承viewgroup
4、 jsbrige實(shí)現(xiàn)原理 ,相互怎么調(diào)用
5、 json數(shù)據(jù)解析類型(比較)
https://blog.csdn.net/qidasheng2012/article/details/82996405
6、MainActivity的啟動(dòng)流程(系統(tǒng)啟動(dòng)流程)
Zygote進(jìn)程 –> SystemServer進(jìn)程 –> 各種系統(tǒng)服務(wù) –> 應(yīng)用進(jìn)程
當(dāng)所有的服務(wù)都啟動(dòng)完畢后,SystemServer會(huì)打印出“Making services ready”,然后通過(guò)ActivityManager啟動(dòng)Home界面,并發(fā)送“ACTION_BOOT_COMPLETED”廣播消息

7、說(shuō)說(shuō)activity、window、fragment之間的關(guān)系,分別干什么
https://blog.csdn.net/qq_34378183/article/details/52785669

8、線程的幾種狀態(tài),? (? 線程在jni中的狀態(tài)(答,目前項(xiàng)目沒(méi)用jni))
https://blog.csdn.net/pange1991/article/details/53860651
拼多多hr面
1、為什么想離職
2、為什么想來(lái)拼多多
3、薪資
4、上家公司職級(jí)
5、有沒(méi)有在面其他公司
6、有沒(méi)有什么想問(wèn)的
百度二面
1、手寫(xiě)代碼 線程安全的觀察者模式,synchromzd和lock區(qū)別, 有什么什么方式讓同步塊更細(xì)。
2、mvc mvp mvvm模式優(yōu)缺點(diǎn),有沒(méi)有使用過(guò)mvvm模式
3、項(xiàng)目 在升級(jí)target中做的一些事 ,? fileprovider是替換什么
Android O N適配文檔
4、 rxjava的線程切換 ,subscribeOn()?和?observeOn()?作用范圍,為什么是這樣,原理是什么。
5、 項(xiàng)目中有沒(méi)有rxjava與 Retrofit 的結(jié)合,講下okhttp源碼,用okhttp和 Retrofit? 分別作用是什么
用okhttp和 Retrofit? 分別作用是什么 , 原來(lái)的網(wǎng)絡(luò)庫(kù)是什么,為什么要替換成okhttp。
http://m.itdecent.cn/p/4d67fe493ebf
6、koltin優(yōu)缺點(diǎn),什么地方使用。
7、 為什么要替換老的圖片庫(kù),新的(gilde)有什么優(yōu)點(diǎn), gilde緩存(原始圖片和尺寸的圖片)
//DiskCacheStrategy.SOURCE:緩存原始數(shù)據(jù),
// DiskCacheStrategy.RESULT:緩存變換后的資源數(shù)據(jù),
// DiskCacheStrategy.NONE:什么都不緩存,
DiskCacheStrategy.ALL:緩存SOURC和RESULT。
? // 默認(rèn)采用DiskCacheStrategy.RESULT策略
8、為什么要用recycleview 優(yōu)點(diǎn),? item復(fù)用的原理是什么
9、 覺(jué)得項(xiàng)目中的亮點(diǎn)是什么?
性能優(yōu)化方面的工作(書(shū)架重構(gòu)(分層設(shè)計(jì),三層解耦), 內(nèi)存泄露排查等), 一些復(fù)雜的自定義view的實(shí)現(xiàn)。(不能滿足交互需求)
10、有沒(méi)有去看過(guò)一些比較好的框架,有沒(méi)有去看過(guò)一些源碼
11 、說(shuō)一說(shuō)android內(nèi)存泄露,有使用哪些工具,LeakCanary原理,為什么非靜態(tài)內(nèi)部類默認(rèn)會(huì)持有外部類的引用。hander造成的內(nèi)存泄露應(yīng)該怎么處理。 webview沒(méi)有釋放為什么會(huì)造成內(nèi)存泄露。? ? 有沒(méi)有使用過(guò)as的一些工具,有什么功能能檢測(cè)到內(nèi)存泄露, 如何排查?
非靜態(tài)內(nèi)部類為什么持有外部類的this引用
https://blog.csdn.net/beixiaozhang/article/details/52950669
內(nèi)部類雖然和外部類寫(xiě)在同一個(gè)文件中, 但是編譯完成后, 還是生成各自的class文件,內(nèi)部類通過(guò)this訪問(wèn)外部類的成員。
1 編譯器自動(dòng)為內(nèi)部類添加一個(gè)成員變量, 這個(gè)成員變量的類型和外部類的類型相同, 這個(gè)成員變量就是指向外部類對(duì)象(this)的引用;
2 編譯器自動(dòng)為內(nèi)部類的構(gòu)造方法添加一個(gè)參數(shù), 參數(shù)的類型是外部類的類型, 在構(gòu)造方法內(nèi)部使用這個(gè)參數(shù)為內(nèi)部類中添加的成員變量賦值;
3在調(diào)用內(nèi)部類的構(gòu)造函數(shù)初始化內(nèi)部類對(duì)象時(shí),會(huì)默認(rèn)傳入外部類的引用。
12、為什么WebView會(huì)造成的內(nèi)存泄露
Android 5.1 WebView內(nèi)存泄漏問(wèn)題及解決
https://blog.csdn.net/u013085697/article/details/53259116
13、說(shuō)說(shuō)http2
關(guān)于 HTTP2 和 HTTPS,這些你必須要知道
http://wemedia.ifeng.com/72005448/wemedia.shtml
14、 Lrucache原理,linkhashmap的數(shù)據(jù)結(jié)構(gòu)是什么樣的
內(nèi)存緩存LruCache實(shí)現(xiàn)原理
https://www.cnblogs.com/liuling/archive/2015/09/24/2015-9-24-1.html
LruCache是通過(guò)LinkedHashMap來(lái)實(shí)現(xiàn)的。LinkedHashMap繼承了HashMap,它使用一個(gè)雙向鏈表來(lái)存儲(chǔ)Map中的Entry順序關(guān)系,這種順序有兩種,一種是LRU順序,一種是插入順序,這可以由其構(gòu)造函數(shù)public LinkedHashMap(int initialCapacity,float loadFactor, boolean accessOrder)指定。對(duì)于get、put、remove等操作,LinkedHashMap除了要做HashMap做的事情,還做些調(diào)整Entry順序鏈表的工作。LruCache中將LinkedHashMap的順序設(shè)置為L(zhǎng)RU順序來(lái)實(shí)現(xiàn)LRU緩存,每次調(diào)用get(也就是從內(nèi)存緩存中取圖片),則將該對(duì)象移到鏈表的尾端。調(diào)用put插入新的對(duì)象也是存儲(chǔ)在鏈表尾端,這樣當(dāng)內(nèi)存緩存達(dá)到設(shè)定的最大值時(shí),將鏈表頭部的對(duì)象(近期最少用到的)移除。
百度三面
1,算法:? 寫(xiě)代碼, 一個(gè)url,得到最近的5個(gè),? 得到使用次數(shù)最多的5個(gè),有什么優(yōu)化空間,時(shí)間復(fù)雜度是多少, 什么數(shù)據(jù)結(jié)構(gòu)是有序列的(堆),有沒(méi)有使用過(guò)
Linkhashmap
通過(guò)反射,獲取linkedHashMap的最后一個(gè)鍵值對(duì)。對(duì)map按照值進(jìn)行排序。
https://www.cnblogs.com/liyafei/p/9620894.html
Map<Integer, Integer> map = new LinkedHashMap<>();? ? ? ? ? ?
Field tail = map.getClass().getDeclaredField("tail");
? ? ? ? ? ? tail.setAccessible(true);
? ? ? ? ? ? Map.Entry<Integer,Integer> entry=(Map.Entry<Integer, Integer>) tail.get(map);
? ? ? ? ? ? Integer key = entry.getKey();
? ? ? ? ? ? Integer value = entry.getValue();
2,koltin優(yōu)缺點(diǎn),中的靜態(tài)變量用什么表示。? 會(huì)不會(huì)一些高級(jí)的用法(? 委托什么,? 不經(jīng)常使用)
Kotlin靜態(tài)方法和靜態(tài)類
https://blog.csdn.net/YULU5216/article/details/80083084

kotlin委托(類似代理)
http://m.itdecent.cn/p/a70ba6436e75
委托模式是軟件設(shè)計(jì)模式中的一項(xiàng)基本技巧。在委托模式中,有兩個(gè)對(duì)象參與處理同一個(gè)請(qǐng)求,接受請(qǐng)求的對(duì)象將請(qǐng)求委托給另一個(gè)對(duì)象來(lái)處理。
3,rxjava使用? (背壓)
關(guān)于RxJava背壓 (很詳細(xì))http://flyou.ren/2017/04/05/%E5%85%B3%E4%BA%8ERxJava%E8%83%8C%E5%8E%8B/?utm_source=tuicool
4,handler的實(shí)現(xiàn)機(jī)制
Android 異步消息處理機(jī)制 讓你深入理解 Looper、Handler、Message三者關(guān)系
https://blog.csdn.net/lmj623565791/article/details/38377229
5,loop自循環(huán)為什么不會(huì)阻塞
https://blog.csdn.net/u013435893/article/details/50903082
Android是事件驅(qū)動(dòng),Looper內(nèi)部是一個(gè)while死循華,只有程序退出后循環(huán)才會(huì)停止,如果Looper使用中死掉了,任何事件都不會(huì)有反應(yīng)了。事件只會(huì)阻塞Looper,而Looper不會(huì)阻塞事件。
ActivityThread 有個(gè) getHandler 方法,得到這個(gè) handler 就可以發(fā)送消息,然后 loop 里就分發(fā)消息,然后就發(fā)給 handler, 然后就執(zhí)行到 H(Handler )里的對(duì)應(yīng)代碼。所以這些代碼就不會(huì)卡死~,有消息過(guò)來(lái)就能執(zhí)行。舉個(gè)例子,在 ActivityThread 里的內(nèi)部類 ApplicationThread 中就有很多 sendMessage 的方法。
簡(jiǎn)單的來(lái)說(shuō):
ActivityThread的main方法主要就是做消息循環(huán),一旦退出消息循環(huán),那么你的程序也就可以退出了。
從消息隊(duì)列中取消息可能會(huì)阻塞,取到消息會(huì)做出相應(yīng)的處理。如果某個(gè)消息處理時(shí)間過(guò)長(zhǎng),就可能會(huì)影響UI線程的刷新速率,造成卡頓的現(xiàn)象。
主要原因有2個(gè)
1、epoll模型 當(dāng)沒(méi)有消息的時(shí)候會(huì)epoll.wait,等待句柄寫(xiě)的時(shí)候再喚醒,? 主線程大多數(shù)時(shí)候都是處于休眠狀態(tài),并不會(huì)消耗大量CPU資源。
2、所有的ui操作都通過(guò)handler來(lái)發(fā)消息操作。 比如屏幕刷新16ms一個(gè)消息,你的各種點(diǎn)擊事件,所以就會(huì)有句柄寫(xiě)操作,喚醒上文的wait操作,所以不會(huì)被卡死了。
主線程的死循環(huán)一直運(yùn)行是不是特別消耗CPU資源呢? 這里涉及到Linux pipe/epoll機(jī)制,簡(jiǎn)單說(shuō)就是在主線程的MessageQueue沒(méi)有消息時(shí),便阻塞在loop的queue.next()中的nativePollOnce()方法,此時(shí)主線程會(huì)釋放CPU資源進(jìn)入休眠狀態(tài),直到下個(gè)消息到達(dá)或者有事務(wù)發(fā)生,通過(guò)往pipe管道寫(xiě)端寫(xiě)入數(shù)據(jù)來(lái)喚醒主線程工作。這里采用的epoll機(jī)制,是一種IO多路復(fù)用機(jī)制,可以同時(shí)監(jiān)控多個(gè)描述符,當(dāng)某個(gè)描述符就緒(讀或?qū)懢途w),則立刻通知相應(yīng)程序進(jìn)行讀或?qū)懖僮?,本質(zhì)同步I/O,即讀寫(xiě)是阻塞的。 所以說(shuō),主線程大多數(shù)時(shí)候都是處于休眠狀態(tài),并不會(huì)消耗大量CPU資源。
https://www.zhihu.com/question/34652589
百度四面:
1,覺(jué)得最有亮點(diǎn)的事是什么
優(yōu)化
架構(gòu),比如書(shū)架分層,數(shù)據(jù)層與界面層進(jìn)行解耦。
內(nèi)存泄露等優(yōu)化
( 對(duì)那些技術(shù)掌握的比較好)
2,職業(yè)規(guī)劃是什么,覺(jué)得做一個(gè)小產(chǎn)品(20萬(wàn)日活)和 一個(gè)大項(xiàng)目(2億日活)有一些什么不同, 這種切換要做一些什么準(zhǔn)備?
首先明確大項(xiàng)目和小項(xiàng)目都一樣重要,都需要扎實(shí)的基本功和項(xiàng)目推動(dòng)能力。小項(xiàng)目一搬一個(gè)人就能搞定,對(duì)個(gè)人能力要求比較高。? 然后大項(xiàng)目是由很多小項(xiàng)目一起構(gòu)成的, 同時(shí)往往涉及到多人合作或者跨部門(mén)合作等,除了對(duì)個(gè)人的能力要求之外,還需要有大局觀,協(xié)調(diào)能力,交際能力,是一個(gè)綜合素質(zhì)的體驗(yàn)。
需要準(zhǔn)備的就是基本功,溝通,反饋能力,能做到項(xiàng)目閉環(huán)。
另外技術(shù)上:
更要注重代碼質(zhì)量,相互review
分享思路,開(kāi)會(huì)解決
修改代碼,影響范圍文檔
多種方案的技術(shù)選型,比較
保證穩(wěn)定(關(guān)鍵)
3,如果版本中有定制功能開(kāi)發(fā)怎么去實(shí)現(xiàn)(技術(shù)和非技術(shù)上),怎么保證與主辦版一致?
a、可以根據(jù)渠道號(hào)、標(biāo)記等進(jìn)行區(qū)分
4,有沒(méi)有使用一些新的技術(shù),覺(jué)得最大的亮點(diǎn)是什么?
gilde okhttp? bravh等優(yōu)點(diǎn)
5,一個(gè)版本開(kāi)發(fā)中要注意什么,一些什么能力最重要?
非技術(shù)上:
a、 溝通能力
b:團(tuán)隊(duì)精神和協(xié)作能力
團(tuán)隊(duì)精神和協(xié)作能力是作為一個(gè)程序員應(yīng)具備的最基本的素質(zhì)。軟件工程已經(jīng)提了將近三十年了,當(dāng)今的軟件開(kāi)發(fā)已經(jīng)不是編程了,而是工程。獨(dú)行俠可以寫(xiě)一些程序也能賺錢(qián)發(fā)財(cái),但是進(jìn)入研發(fā)團(tuán)隊(duì),從事商業(yè)化和產(chǎn)品化的開(kāi)發(fā)任務(wù),就必須具備這種素質(zhì)。可以毫不夸張的說(shuō)這種素質(zhì)是一個(gè)程序員乃至一個(gè)團(tuán)隊(duì)的安身立命之本。
技術(shù)上:
還有最基本的技能, 能夠調(diào)研,技術(shù)積累,代碼review, 思路探討,影響范圍等。
c、文檔習(xí)慣
文檔是一個(gè)軟件系統(tǒng)的生命力。一個(gè)公司的產(chǎn)品再好、技術(shù)含量再高,如果沒(méi)有缺乏文檔,知識(shí)就沒(méi)有繼承,公司還是一個(gè)來(lái)料加工的軟件作坊。作為代碼程序員,必須將30%的工作時(shí)間寫(xiě)用于技術(shù)文檔。沒(méi)有文檔的程序員勢(shì)必會(huì)被淘汰。
d:規(guī)范化的代碼編寫(xiě)習(xí)慣
知名軟件公司的代碼的變量命名、注釋格式,甚至嵌套中行縮進(jìn)的長(zhǎng)度和函數(shù)間的空行數(shù)字都有明確規(guī)定,良好的編寫(xiě)習(xí)慣,不但有助于代碼的移植和糾錯(cuò),也有助于不同技術(shù)人員之間的協(xié)作。 一些所謂的高手甚至叫囂高手寫(xiě)的代碼一般人看不懂,我只能說(shuō)他不是一名合格的程序員。
e:需求理解能力
程序員要能正確理解任務(wù)單中描述的需求。在這里要明確一點(diǎn),程序員不僅僅要注意到軟件的功能需求,還應(yīng)注意軟件的性能需求,要能正確評(píng)估自己的模塊對(duì)整個(gè)項(xiàng)目中的影響及潛在的威脅,如果有著兩到三年項(xiàng)目經(jīng)驗(yàn)的熟練程序員對(duì)這一點(diǎn)沒(méi)有體會(huì)的話,只能說(shuō)明他或許是認(rèn)真工作過(guò),但是沒(méi)有用心工作。
6,為什么來(lái)上海,為什么從原來(lái)部門(mén)離職。
7,有什么事會(huì)覺(jué)得壓力大
8,如果一個(gè)項(xiàng)目一周要上線,但是當(dāng)前這個(gè)技術(shù)方案不是很好,怎么處理
a、人力
b、 和產(chǎn)品協(xié)商,?
c、 和領(lǐng)導(dǎo)溝通看有沒(méi)有其他人(善于解決這類問(wèn)題),
d、 能不能拆分版本,迭代上線。?
9? 領(lǐng)導(dǎo)給你一個(gè)不太好的績(jī)效時(shí)候,給比你能力弱的人好的績(jī)效時(shí)候,怎么去溝通
思考為什么沒(méi)有有達(dá)到領(lǐng)導(dǎo)對(duì)你的預(yù)期。
那些方面還可以進(jìn)行改進(jìn)。
10 有沒(méi)有去看過(guò)一些源碼
11 覺(jué)得好的架構(gòu)設(shè)計(jì)應(yīng)該是什么樣的
https://www.cnblogs.com/geek6/p/3951677.html
代碼上:
a、 總原則:開(kāi)閉原則(Open Close Principle)? ? 模塊解耦模塊化
開(kāi)閉原則就是說(shuō)對(duì)擴(kuò)展開(kāi)放,對(duì)修改關(guān)閉。在程序需要進(jìn)行拓展的時(shí)候,不能去修改原有的代碼,而是要擴(kuò)展原有代碼,實(shí)現(xiàn)一個(gè)熱插拔的效果。所以一句話概括就是:為了使程序的擴(kuò)展性好,易于維護(hù)和升級(jí)。
b、單一職責(zé)原則:? 不要存在多于一個(gè)導(dǎo)致類變更的原因,也就是說(shuō)每個(gè)類應(yīng)該實(shí)現(xiàn)單一的職責(zé),如若不然,就應(yīng)該把類拆分。
c、里氏代換原則面向?qū)ο笤O(shè)計(jì)的基本原則之一。 里氏代換原則中說(shuō),任何基類可以出現(xiàn)的地方,子類一定可以出現(xiàn)。實(shí)現(xiàn)“開(kāi)-閉”原則的關(guān)鍵步驟就是抽象化。而基類與子類的繼承關(guān)系就是抽象化的具體實(shí)現(xiàn),所以里氏代換原則是對(duì)實(shí)現(xiàn)抽象化的具體步驟的規(guī)范
d、依賴倒轉(zhuǎn)原則:? 這個(gè)是開(kāi)閉原則的基礎(chǔ),具體內(nèi)容:面向接口編程,依賴于抽象而不依賴于具體。寫(xiě)代碼時(shí)用到具體類時(shí),不與具體類交互,而與具體類的上層接口交互。
e、接口隔離原則:? 每個(gè)接口中不存在子類用不到卻必須實(shí)現(xiàn)的方法,如果不然,就要將接口拆分。使用多個(gè)隔離的接口,比使用單個(gè)接口(多個(gè)接口方法集合到一個(gè)的接口)要好。
f、 最少知道原則:? 一個(gè)類對(duì)自己依賴的類知道的越少越好。也就是說(shuō)無(wú)論被依賴的類多么復(fù)雜,都應(yīng)該將邏輯封裝在方法的內(nèi)部,通過(guò)public方法提供給外部。這樣當(dāng)被依賴的類變化時(shí),才能最小的影響該類。
g:合成復(fù)用原則: 原則是盡量首先使用合成/聚合的方式,而不是使用繼承。
其它的方面:
一個(gè)好的架構(gòu)并不是一定要什么牛逼的技術(shù),而是根據(jù)當(dāng)前業(yè)務(wù)的特點(diǎn),以合理的人力成本和硬件成本實(shí)現(xiàn),并且在未來(lái)幾年內(nèi)能滿足業(yè)務(wù)需求,高性能、高可用、易維護(hù),易擴(kuò)展,就是好的架構(gòu)。
12 如果是一個(gè)成熟的產(chǎn)品,沒(méi)有那么多功能迭代,怎么看
a、可以由更多的時(shí)間積累,預(yù)研新的技術(shù),做技術(shù)儲(chǔ)備
b、能夠?qū)系募夹g(shù)點(diǎn)進(jìn)行優(yōu)化,性能提升
c、可以更充足的進(jìn)行技術(shù)選型,找到最適合項(xiàng)目的技術(shù)。
13、如何推進(jìn)你開(kāi)發(fā)的sdk, 讓組內(nèi)其它成員了解,并使用。
a、 首先可以在周會(huì)上分享自己做的是個(gè)什么東西,能提供一些什么功能,性能能提升多少,一些原理等,讓組內(nèi)其他成員了解。
b、可以去看看其他產(chǎn)品有什么地方能夠替換, 可以幫忙列出list
c、可以拉個(gè)分支試著去改造,分享下能提升多少
d、可以寫(xiě)文檔,書(shū)面分享技術(shù),讓更多人去了解。
百度五面
1,是不是視覺(jué)給的切圖都直接使用
2,哪里人,為什么離職,怎么去的網(wǎng)易
3,在網(wǎng)易的職級(jí)
4,有沒(méi)有關(guān)注新的技術(shù),有沒(méi)有關(guān)注小程序
5,職業(yè)規(guī)劃
6,當(dāng)前工作的一些情況
7,當(dāng)前產(chǎn)品的情況
8,現(xiàn)在工作時(shí)間,工作結(jié)束后是學(xué)習(xí)還是加班
阿里一面
(喜歡問(wèn):? 為什么要這樣做, 什么場(chǎng)景下提出來(lái)。 這樣做的目的是什么)
1、介紹下項(xiàng)目,有一些什么部分(為什么要這樣做,這樣做的目的是什么, 希望達(dá)到什么樣的效果, 優(yōu)化了多少,結(jié)果)
自定義view、書(shū)架模塊化
2、Java 類加載機(jī)制(阿里面試題)-何時(shí)初始化類? ? (? 重點(diǎn)? )
https://www.cnblogs.com/aspirant/p/7200523.html
3、app的啟動(dòng)流程
4、helloword jvm是如何進(jìn)行繪制到屏幕上的(類的加載過(guò)程)
5、java jvm垃圾回收機(jī)制
6、有沒(méi)有看過(guò)什么源碼?
okhttp原理、gilde等
7、如何使用okhttp去使用代理模式
攔截
8、https 如何連接, 如何去申請(qǐng)證書(shū), 如何驗(yàn)證證書(shū), 證書(shū)如何傳遞
9、有什么工作是你主動(dòng)提出來(lái)的, 為什么要替換圖片庫(kù), 在shenm場(chǎng)景提出來(lái)的,別人提出了些什么
9、android中內(nèi)存泄露是什么,? 有一些什么場(chǎng)景? , 有什么常用的工具(原理)
10、一次完整的http請(qǐng)求是什么樣的
11、okhttp如何支持HTTP2的
頭條一面:
1、簡(jiǎn)單自我介紹、項(xiàng)目
2、說(shuō)一說(shuō)項(xiàng)目中的難點(diǎn)
3、自己設(shè)計(jì)一個(gè)圖片緩存怎么實(shí)現(xiàn),使用什么算法? (Lruchache),? LindedHashmap原理(內(nèi)部構(gòu)造),? 雙鏈表相對(duì)于單鏈表有什么區(qū)別(優(yōu)點(diǎn)), hashmap如何擴(kuò)容? , 是否是線程安全的。 線程安全的有哪些? 線程安全類鎖,對(duì)象鎖。
淺談單鏈表與雙鏈表的區(qū)別
https://blog.csdn.net/kangxidagege/article/details/80211225
LinkedHashMap就這么簡(jiǎn)單【源碼剖析】
https://www.cnblogs.com/Java3y/p/8798058.html
、Synchronized方法鎖、對(duì)象鎖、類鎖區(qū)別
https://blog.csdn.net/jerrywu145/article/details/79821094
https://www.cnblogs.com/yw-ah/p/5842354.html
4、Rxjava的使用,如何進(jìn)行線程切換,io 和 newThread()區(qū)別,(內(nèi)部是不是線程池) , 說(shuō)說(shuō)常用的操作符, 如何組合兩個(gè)網(wǎng)絡(luò)請(qǐng)求。
5、項(xiàng)目在什么情況下使用了koltin,優(yōu)缺點(diǎn)
6、內(nèi)存泄露,有哪些
7、算法、如何打亂一個(gè)有序數(shù)組,時(shí)間復(fù)雜度等
8、寫(xiě)算法,層次遍歷樹(shù)結(jié)構(gòu)
阿里二面:
1、自我介紹
2、覺(jué)得自己有沒(méi)有什么特別,在項(xiàng)目中
喜歡用新的技術(shù)
3、內(nèi)存優(yōu)化
4、流量?jī)?yōu)化、電量?jī)?yōu)化
5、怎么進(jìn)行層級(jí)優(yōu)化
LinearLayout 對(duì)比 RelativeLayout(百度)(Ricky)
RelativeLayout會(huì)讓子View調(diào)用2次onMeasure,LinearLayout 在有weight時(shí),也會(huì)調(diào)用子View2次onMeasure,RelativeLayout的子View如果高度和RelativeLayout不同,則會(huì)引發(fā)效率問(wèn)題,當(dāng)子View很復(fù)雜時(shí),這個(gè)問(wèn)題會(huì)更加嚴(yán)重。如果可以,盡量使用padding代替margin。在不影響層級(jí)深度的情況下,使用LinearLayout和FrameLayout而不是RelativeLayout。
最后再思考一下文章開(kāi)頭那個(gè)矛盾的問(wèn)題,為什么Google給開(kāi)發(fā)者默認(rèn)新建了個(gè)RelativeLayout,而自己卻在DecorView中用了個(gè)LinearLayout。因?yàn)镈ecorView的層級(jí)深度是已知而且固定的,上面一個(gè)標(biāo)題欄,下面一個(gè)內(nèi)容欄。采用RelativeLayout并不會(huì)降低層級(jí)深度,所以此時(shí)在根節(jié)點(diǎn)上用LinearLayout是效率最高的。而之所以給開(kāi)發(fā)者默認(rèn)新建了個(gè)RelativeLayout是希望開(kāi)發(fā)者能采用盡量少的View層級(jí)來(lái)表達(dá)布局以實(shí)現(xiàn)性能最優(yōu),因?yàn)閺?fù)雜的View嵌套對(duì)性能的影響會(huì)更大一些。
6、Java 的強(qiáng)引用、弱引用、軟引用、虛引用、
https://www.cnblogs.com/gudi/p/6403953.html
7、有沒(méi)有看過(guò)Android源碼
8、職業(yè)規(guī)劃
9、說(shuō)下緩存
10、MVP、MVVM。項(xiàng)目中有沒(méi)有使用過(guò)。 MVVM是用什么雙向綁定。
11、android進(jìn)程間的通訊、bindler原理、 bindler是怎么修改底層的數(shù)據(jù)
12、有沒(méi)有項(xiàng)目管理方面的實(shí)踐
頭條二面:
1、算法 反轉(zhuǎn)鏈表
2、多進(jìn)程通訊方式, bundle原理
3、進(jìn)行與線程區(qū)別
4、兩種序列化區(qū)別為什么
5、自定view怎么滑動(dòng),怎么解決滑動(dòng)沖突
6、介紹項(xiàng)目難點(diǎn)
7、java多線程安全, 有哪幾種, 對(duì)象鎖、類鎖區(qū)別、可重用鎖、volidate? 、threadlocal
8、類的加載
9、MeasureSpec