本人近況
年底裁人了,一年半沒準備面試了,之前換也是內推的,在這個寒冬的冬天還經歷此遭,偏偏還趕上裁員
心態早已爆炸,大的環境不好,各位且干且珍惜....
記錄下最近的面試經歷,整理下讓自己不斷進步!
題外話
我不知道一個人人性究竟可以壞到什么程度,但是我最近親身經歷的確實是這樣,我一個安心想做技術的人跟你TMD HR部門的八竿子打不著,又何苦為難我呢? 之前有個公司的薪酬績效主管,邵X,只因為我在大會上頂撞了她一個問題,一味著揪著我的把柄不放,甚至特么的為了少給我一個季度的績效不允許提前轉正,真的是壞透了,可能這就是職場,這就是江湖充滿爾虞我詐,真的人真是身不由己的,本想與世無爭安心踏實做技術,但是某些人卻看不得你的安寧。。。還是那句話,出來混的遲早要還的,望好自為之
右劃
這公司是在拉勾上投的,CEO號稱曾于字節跳動,任視頻負責人,創建了頭條視頻APP。公司待遇15薪非常不錯,坐落于望京Soho對面的望京融科寫字樓
- 面試過程覺得自己挺失敗的沒有充分準備算法再加上由于一年半沒有再面試過了,有點手生,好多應該答上來的問題都沒有答好,面試官確實是大牛,沒會的問題也稍微講解了下,不過深度確實蠻深的
- 印象比較深的幾個問題:Lru算法,Binder機制,EventBus實現原理和為什么不能跨進程,Handler如何在handleMessage方法攔截之前發出的message,手寫二分法查找(沒準備直接跪了),后來讓我手寫冒泡,我覺得前面已經沒戲了(大致說了下雙重循環然后賦值也沒手寫),跨進程幾種方式,AIDL,handler機制,ThreadLocal實現原理(回答的很模糊,附上正確答案:每個Thread的對象都有一個ThreadLocalMap,當創建一個ThreadLocal的時候,就會將該ThreadLocal對象添加到該Map中,其中鍵就是ThreadLocal,值可以是任意類型。
在該類中,最重要的方法就是兩個:set()和get()方法。當調用ThreadLocal的get()方法的時候,會先找到當前線程的ThreadLocalMap,然后再找到對應的值。set()方法也是一樣。)系統是如何監聽ANR的(他說是androidframework層有一個單獨的進程),后來問到如何定位和排查我不小心說了blockCanary,他有追問了一下源碼和原理我回答的也不是很好(應用發生卡頓,一定是在dispatchMessage中執行了耗時操作。我們通過給主線程的Looper設置一個Printer,打點統計dispatchMessage方法執行的時間,如果超出閥值,表示發生卡頓,則dump出各種信息,提供開發者分析性能瓶頸。)
最后知道今天一定掛了,不過還是很有收獲的知道自己哪里不足...
PS:明天去五道口面試斗魚,希望能好好把握
斗魚
拉勾投的斗魚,據說最近在瘋狂裁人?只經歷了兩輪面試,一共面了兩個多小時,沒到HR,估計歇菜了
- 斗魚有份筆試題,還是蠻簡單的隨便寫寫就ok,一面問的蠻詳細的,問的大致是看簡歷寫的東西問的,中規中矩,記憶比較深刻的是問了handlerThread原理,MVP模式(因為斗魚目前的架構都是mvp),彈幕的實現原理和重疊問題(這個沒怎么做過,回答的不是太好,而且之前也是直接用的B站開源的那個庫),Kotlin協程(這個沒用過,kt的掌握程度還只是入門階段),Retrofit+Okhttp+Rxjava在華為的好多手機會OOM是由線程數溢出引起如何解決?堆內存,棧內存理解,棧如何轉換成堆?內存泄漏是發生在堆內存還是棧內存?為什么? BlockCanary原理?(第二次被問了?。?!看來真要看看源碼了)如何實現打印指定阻塞線程的方法名?LinkedHashMap與HashMap區別。。。
String a=“A” 與 String a = new String(“A”); 區別,分別存儲在哪個區域(這題有誤導嫌疑,第一個應該是常量區,堆棧都不是,第二個是堆)MutiDex 第一次ANR以及解決方式(答案參考:http://www.lxweimin.com/p/5a2e33a61ba2)
我覺得大部分的問題回答的還是不錯的,一面問了下薪資然后開始二面 - 二面印象最深的是根據面向對象設計一個電梯系統,問題的關鍵點在于所有的屬性都跟電梯有關,跟人無關,樓層數是固定的常量...我當時設計跑偏了,總聯想到人然后去設計。。
結束以后沒有HR面,估計歇菜了...再接再厲吧...
Zenjoy
這家公司是獵頭推薦的,坐落于銀河SohoA座,辦公環境蠻不錯的,產品方向是做海外項目的,不過前后歷經將近三個小時的面試著實很令人崩潰,我喝了將近三瓶小瓶怡寶礦泉水才撐到了最后。。。
一面&二面
一面,二面問的太多了根本記不住,只記得幾個印象深刻的問題,
- hashcode()和equals()的作用、區別、聯系?
因為hashCode()并不是完全可靠,有時候不同的對象他們生成的hashcode也會一樣(生成hash值得公式可能存在的問題),所以hashCode()只能說是大部分時候可靠,并不是絕對可靠,所以我們可以得出:
1.equal()相等的兩個對象他們的hashCode()肯定相等,也就是用equal()對比是絕對可靠的。
2.hashCode()相等的兩個對象他們的equal()不一定相等,也就是hashCode()不是絕對可靠的。) - Handler、Looper、MessageQueue、Thread關系?
一個線程可以有多個Handler實例,一個線程對應一個Looper,一個Looper也只對應一個MessageQueue,一個MessageQueue對應多個Message和Runnable。所以就形成了一對多的對應關系,一方:線程、Looper、MessageQueue;多方:Handler、Message。同時可以看出另一個一對一關系:一個Message實例對應一個Handler實例。 - Service 和 Activity如何交互, 如何在后臺下載任務, 并在Activity顯示進度?
- https握手過程,如何實現數據加密?客戶端如何保證安全實現雙重證書校驗?請你設計一個登錄功能,需要注意哪些安全問題?
- Hashmap實現原理和如何解決散列碰撞(必問),Hashmap底層為什么是線程不安全的?
- HandlerThread原理以及對比單個New Thread的好處,優點以及試用場景?需要注意的是HandlerThread 是單個線程的不太適合執行網絡的IO操作,要注意。。
- EventBus實現原理
- SurfaceView, TextureView區別?
從性能和安全性角度出發,使用播放器優先選SurfaceView。
1.在android 7.0上系統surfaceview的性能比TextureView更有優勢,支持對象的內容位置和包含的應用內容同步更新,平移、縮放不會產生黑邊。 在7.0以下系統如果使用場景有動畫效果,可以選擇性使用TextureView
2.SurfaceView優點及缺點優點:可以在一個獨立的線程中進行繪制,不會影響主線程,使用雙緩沖機制,播放視頻時畫面更流暢
缺點:Surface不在View hierachy中,它的顯示也不受View的屬性控制,所以不能進行平移,縮放等變換,也不能放在其它ViewGroup中。SurfaceView 不能嵌套使用
3.TextureView優點及缺點
優點:支持移動、旋轉、縮放等動畫,支持截圖
缺點:必須在硬件加速的窗口中使用,占用內存比SurfaceView高,在5.0以前在主線程渲染,5.0以后有單獨的渲染線程。 - handler postDelay這個延遲是怎么實現的?
- Appliction啟動過程(App啟動過程)?
- 如何測量應用啟動時間?
1.可以通過代碼打樁,計算啟動時間
2.命令
adb shell am start -W [packageName]/[packageName.launchActivity]
三面
根據之前獵頭的情報,三面是沒有技術相關的問題的,但是我這個不一樣,三面是總監面,首先先手寫一個算法,不難,大致意思是:給你一個無序的數組,又給了一個目標值,如果這個數組其中有兩個數相加等于這個目標值,請你輸出對應兩個數的下標?
思路也蠻簡單的,直接Arrays.sort先排序 按升序來,然后雙重循環就可以了。。。寫完總監會問下單層for循環時間復雜度---
for(int i=1;i <=n;i++) //O(N);
for(int j=1;j <=i;j++) //O(N^2);
然后是
- 設計模式
- Restful接口規范 我倆爭論了好半天
- 觀察者模式的原理
大概能記得的就是這些,總監可能比較注重基礎吧,自認為總體發揮一般可能一面和三面有一些瑕疵,主要二面有一些問題反問面試官也沒有給我相應的解釋比如那個handler postDelay怎么delay的。。。前前后后面了將近三個小時,最后HR進來讓我回去等消息,我知道估計涼涼了。。。
萊熙科技
這家公司我依稀記得去年年初考慮新機會的時候,那時候還在職,偷偷去面過,真心覺得面試官總是問一些我意想不到的問題,原本是要拒了的,可是Boss直聘上HR小姐姐一再要求要我再來一次,我就安排了今天的第三面(第一面已經拿到offer但是工資與預期差距較大,而且沒有太深的技術面再加上公司較小,與我預期的差距也很大就不寫了)依稀記得大概一年零八個月前吧,那時候他們還沒做海外項目,沒想到現在的產品居然是我上家公司的同類競品項目,他們做的叫LivU,Live Chat,在線視頻聊天~于是我決定去試試水。。。
一面
面試官還是1年零八個月之前的小哥,問題問的果然沒有辜負我對他的期望,因為產品做的都是一個路子還有用的框架也是Agora的,答起來輕車熟路,但是有好多讓我耳目一新的問題
- 使用GreenDao如何實現創建表、關聯表(一對一,一對多,多對多)?
- Java調用kotlin 如何不用companion object{}包裹?
我解答他之前一直糾結的:在Java中調用kotlin中靜態的成員
如果一個類中所有的成員都是靜態成員,將class改為object就不用每個方法都用companion object{}包裹了。但是小哥說據說是最新kotlin加個注解可以不需要這個包裹? - 斷點續傳實現
- 代理模式和裝飾器模式區別?
- java io 裝飾器模式。。當時問我用過的哪個包是裝飾器模式,我沒答上來!
- App啟動速度優化?
- Android 5.0-8.0新特性
- Dalvik與ART區別?
- 進程?;睿浚▊蚊})沒有真正意義的進程?;?,都是白明單才OK
- Retrofit CreateApi實現原理
二面
二面主要是總監面試,穿插了一些技術,不過總是暗示我來了需要加班啥的要我考慮清楚(我當然想你錢到位,啥都不是事)不過既然這么說了,因為我問了一些公司流程方面的事,他回答是產品快速迭代,本身需求不可能流程化,只能產品做出來去試水,然后再推翻,如此往復計劃跟不上變化快,大致我想要的工作方式并不是這樣,可能有點分歧,也可能由于本來之前本來三面三個小時心態崩潰,可能態度沒有順著他來,So二面失敗,HR小姐姐招人的傭金也沒了。。
PS:其實內心還是蠻想去的,不過由于之前可能這種工作流程不太適合我,我剛跳出坑,他可能看到了我的猶豫和顧慮吧,所以技術過了也把我Pass了。。不過佛系的我已經無所謂了。。
站酷(ZCOOL)
這家公司是拉勾投的,面試官貌似是幫別的部門招聘,應該是做一個在線教育的項目,聽名字貌似叫“高高手”?遇到答的不好的題面試官都給予了細致的講解,我覺得收獲蠻大。
具體的問題大概都有:
- Retrofit 如何實現文件(或圖片上傳)接口是如何定義的
大意要回答multipart/form-data 文件上傳表單中
它會將表單的數據處理為一條消息,以標簽為單元,用分隔符分開。既可以上傳鍵值對,也可以上傳文件。當上傳的字段是文件時,會有Content-Type來表名文件類型;content-disposition,用來說明字段的一些信息;
由于有boundary隔離,所以multipart/form-data既可以上傳文件,也可以上傳鍵值對,它采用了鍵值對的方式,所以可以上傳多個文件。 - 自定義View的屬性引用attr,styleable里定義的名稱可否與系統已經存在的name重復?當然是不可以的,編譯器會預先檢查系統已經存在或者之前已經定義重復的
- 自定義View OnMeasure方法的三種Mode
UNSPECIFIED(未指定),父控件對子控件不加任何束縛,子元素可以得到任意想要的大小,這種MeasureSpec一般是由父控件自身的特性決定的。比如ScrollView,它的子View可以隨意設置大小,無論多高,都能滾動顯示,這個時候,size一般就沒什么意義。
EXACTLY(完全),父控件為子View指定確切大小,希望子View完全按照自己給定尺寸來處理,跟上面的場景1跟2比較相似,這時的MeasureSpec一般是父控件根據自身的MeasureSpec跟子View的布局參數來確定的。一般這種情況下size>0,有個確定值。
AT_MOST(至多),父控件為子元素指定最大參考尺寸,希望子View的尺寸不要超過這個尺寸,跟上面場景3比較相似。這種模式也是父控件根據自身的MeasureSpec跟子View的布局參數來確定的,一般是子View的布局參數采用wrap_content的時候。 - WebView攔截Url和cookie相關?網頁需要設置登錄狀態等情形
- Android中為什么主線程不會因為Looper.loop()里的死循環卡死?
Android應用程序的主線程在進入消息循環過程前,會在內部創建一個Linux管道(Pipe),這個管道的作用是使得Android應用程序主線程在消息隊列為空時可以進入空閑等待狀態,并且使得當應用程序的消息隊列有消息需要處理時喚醒應用程序的主線程。 - 解決Android多線程訪問SQLite數據庫死鎖問題?database is locked
解決的辦法就是保持sqlite連接單例,保持單個SqliteOpenHelper實例,同時對所有數據庫操作的方法添加synchronized關鍵字。也就是說是讀寫數據庫時存在的同步問題,所以采用單例+同步鎖的方法,并且在每次數據庫操作后都關閉數據庫 - Android多進程解決單個進程內存分配?
微信貌似也用了拆分多進程去降低單個進程的heapSize - Android如何實現大圖加載?
- WeakReference使用場景?
- 在Service里實現下載如何刷新UI?
- Handler postDelay如何實現不阻塞UI線程?
1.postDelay()一個1秒鐘的MyTask任務、消息進隊,MessageQueue開始阻塞,Looper阻塞,mBlocked為true,在enqueueMessage的if中將needWake = mBlocked。
2.然后post一個新的任務、消息進隊,判斷現在A時間還沒到、正在阻塞,把新的任務插入消息隊列的頭部(MyTask任務的前面),然后此時needWake為true調用nativeWake()方法喚醒線程。
3.MessageQueue.next()方法被喚醒后,重新開始讀取消息鏈表,第一個消息B無延時,直接返回給Looper;
4.Looper處理完這個消息再次調用next()方法,MessageQueue繼續讀取消息鏈表,第二個消息A還沒到時間,計算一下剩余時間(假如還剩9秒)繼續阻塞;
5.直到阻塞時間到或者下一次有Message進隊;
心得
這次面試還算是比較全面的面試吧,無論是深度和廣度問的都很深,面試之后收獲了自己的不足,感覺自己表現還可以,可能由于這個崗位是剛開始招的,時間周期會很長不知道會不會給offer... 不過有收獲就是好的~
整理下最近面試的幾個常見問題
RxJava 變換操作符 map flatMap concatMap buffer?
- 常用的變換操作符
- map:【數據類型轉換】將被觀察者發送的事件轉換為另一種類型的事件
- flatMap:【化解循環嵌套和接口嵌套】將被觀察者發送的事件序列進行拆分 & 轉換 后合并成一個新的事件序列,最后再進行發送
- concatMap:【有序】與 flatMap 的 區別在于,拆分 & 重新合并生成的事件序列 的順序與被觀察者舊序列生產的順序一致
- flatMapIterable:相當于對 flatMap 的數據進行了二次扁平化
- buffer:定期從被觀察者發送的事件中獲取一定數量的事件并放到緩存區中,然后把這些數據集合打包發射
裝飾器模式和代理模式區別
代理模式,注重對對象某一功能的流程把控和輔助。它可以控制對象做某些事,重心是為了借用對象的功能完成某一流程,而非對象功能如何。
裝飾模式,注重對對象功能的擴展,它不關心外界如何調用,只注重對對象功能的加強,裝飾后還是對象本身。
所以:
對于代理類,如何調用對象的某一功能是思考重點,而不需要兼顧對象的所有功能;
對于裝飾類,如何擴展對象的某一功能是思考重點,同時也需要兼顧對象的其它功能,因為再怎么裝飾,本質也是對象本身,要擔負起對象應有的職責。
HashMap如何實現一個Key對應多個value?
其實就是Hashmap + ArrayList去實現的
例:
HashMap<Integer,ArrayList<String>> map = new HashMap<Integer,ArrayList<String>>();
ArrayList<String> list = new ArrayList<String>();
list.add("abc");
list.add("xyz");
map.put(100,list);
Android中ClassLoader的種類&特點
- BootClassLoader(Java的BootStrap ClassLoader)
用于加載Android Framework層class文件。 - PathClassLoader(Java的App ClassLoader)
用于加載已經安裝到系統中的apk中的class文件。 - DexClassLoader(Java的Custom ClassLoader)
用于加載指定目錄中的class文件。 - BaseDexClassLoader
是PathClassLoader和DexClassLoader的父類。
因為遵循雙親委派模型,Android中的ClassLoader具有兩個特點:
- 類加載共享
當一個class文件被任何一個ClassLoader加載過,就不會再被其他ClassLoader加載。 - 類加載隔離
不同ClassLoader加載的class文件肯定不是一個。舉個栗子,一些系統層級的class文件在系統初始化的時候被加載,比如java.net.String,這個是在應用啟動前就被系統加載好的。如果在一個應用里能簡單地用一個自定義的String類把這個String類替換掉的話,將有嚴重的安全問題。
最后
即將入職某影視公司Android Leader崗,面試暫時告一段落,希望面試心得能幫到大家,祝大家好運~