2019 android面試題(拼多多、百度、阿里、頭條等)

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

3、ProGuard代碼混淆技術(shù)詳解

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ù)用連接池

TCP連接與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

Lock的實(shí)現(xiàn)原理

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

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

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