2019.12 - 騰訊、快手、美團(tuán)外賣 Android 面試題雜記

致那些面試中的辛酸坎坷史.....

一、騰訊

面試時(shí)間:2019.12.18
面試部門:QQ 瀏覽器

  1. 你是如何來優(yōu)化業(yè)務(wù) RN 頁面的性能的?

  2. 在治理 RN 頁面的 JS 錯(cuò)誤時(shí),你的方案是什么,如何設(shè)計(jì)的方案?

  3. MRN 比 原生 RN,有什么功能優(yōu)勢?

  4. MRN 頁面你們關(guān)注的性能指標(biāo)有哪些?為什么要關(guān)注這些指標(biāo)?

  5. 構(gòu)造一個(gè)出現(xiàn)死鎖的情況

  6. 實(shí)現(xiàn)一個(gè)線程同步的計(jì)數(shù)器

  7. synchronized 底層實(shí)現(xiàn)

  8. 說兩個(gè)線程同步的集合類

  9. 進(jìn)程間通信的方式有哪些?

  10. Activity 與 Service 的區(qū)別?Service 一定沒界面嗎,Activity 一定有界面嗎?

  • Activity 不是一定有界面。比如一個(gè)跳轉(zhuǎn)邏輯控制類(機(jī)票的支付中間類)、透明頁
  • Service 也不是一定沒界面。Service 并不依賴于用戶可視的 UI 界面,但這也不是絕對的,如前臺(tái) Service 就是與 Notification 界面結(jié)合使用的;Service 中也可以彈 Toast;
  • Service中執(zhí)行 LayoutInflate 是合法的,但是會(huì)使用系統(tǒng)默認(rèn)的主題樣式,如果你自定義了某些樣式可能不會(huì)被使用。所以從理論上看也是可以有界面的
  1. Activity 按 back 鍵退出,與強(qiáng)殺進(jìn)程退出有啥區(qū)別?

(1)應(yīng)用被強(qiáng)殺

  • 整個(gè)App進(jìn)程都被殺掉了,所有變量全都被清空,包括Application實(shí)例,更別提靜態(tài)變量;
  • 雖然變量被清空了,但 Activity 棧沒有被清空,也就是說 A -> B -> C 這個(gè)棧還保存了,只是ABC 這幾個(gè) Activity 實(shí)例沒有了。所以回到 App 時(shí),顯示的還是 C 頁面。另外當(dāng) Activity 被強(qiáng)殺時(shí),系統(tǒng)會(huì)調(diào)用 onSaveInstance 去讓你保存一些變量;
  • 當(dāng)應(yīng)用回到前臺(tái)時(shí),如果C頁面中有靜態(tài)變量或有些Application的全局變量,就NullPointer了;
  • C頁面不會(huì)正常走完生命周期onStop & onDestory

(2)按 Back 鍵回退

  • 應(yīng)用進(jìn)程不會(huì)被殺掉;Activity 棧由 A -> B -> C 變成 A -> B;
  • C頁面會(huì)正常走完生命周期onStop & onDestory
  1. 構(gòu)造一個(gè)內(nèi)存泄露的場景

  2. Android 虛擬機(jī)有哪些?區(qū)別是什么?

  3. 如何做屏幕適配,是否對小屏手機(jī)有專門的適配?

(1)Android 目前穩(wěn)定高效的UI適配方案、今日頭條屏幕適配方案 AndroidAutoSize

  • dpi:屏幕像素密度,指的是在系統(tǒng)軟件上指定的單位尺寸的像素?cái)?shù)量,它往往是寫在系統(tǒng)出廠配置文件的一個(gè)固定值;
  • ppi:也是屏幕像素密度,但這個(gè)是物理上的概念,它是客觀存在的不會(huì)改變。dpi是軟件參考了物理像素密度后,人為指定的一個(gè)值,這樣保證了某一個(gè)區(qū)間內(nèi)的物理像素密度在軟件上都使用同一個(gè)值
  • dp加上自適應(yīng)布局和weight比例布局能解決90%的適配問題。因?yàn)椴⒉皇撬械?080P的手機(jī)dpi都是480,比如Google 的Pixel2(1920*1080)的dpi是420
  • 寬高限定符適配:窮舉市面上所有的Android手機(jī)的寬高像素值,設(shè)定一個(gè)基準(zhǔn)的分辨率,其他分辨率都根據(jù)這個(gè)基準(zhǔn)分辨率來計(jì)算,在不同的尺寸文件夾內(nèi)部,根據(jù)該尺寸編寫對應(yīng)的dimens文件。但其有一個(gè)致命的缺陷,那就是需要精準(zhǔn)命中才能適配,App包體積也會(huì)變大

(2)今日頭條-通過反射修正系統(tǒng)的 density 值

  1. Java中中文字符和英文字符的大小分別多少?在網(wǎng)絡(luò)上傳輸大小又分別是多少?

  2. Java GC機(jī)制,為什么要執(zhí)行 GC

那些不可能再被任何途徑使用的對象,需要被回收,否則內(nèi)存遲早都會(huì)被消耗空

  1. 平時(shí)開發(fā)中你是怎么保證質(zhì)量的,團(tuán)隊(duì)項(xiàng)目的質(zhì)量又是如何保證的?

  2. 如何使用 git 來協(xié)作團(tuán)隊(duì)開發(fā)流程的

  3. 項(xiàng)目 A 依賴 項(xiàng)目B,項(xiàng)目 B 依賴項(xiàng)目 C,項(xiàng)目C又依賴項(xiàng)目 A,這樣會(huì)有問題嗎?

  4. 上面的問題,給出有問題或沒問題的原因,怎么解決?

  5. 說一個(gè)你覺得讓你成長很大,或者印象比較深刻的項(xiàng)目

  6. 給你一個(gè)開發(fā)項(xiàng)目,如何管理,怎么制定開發(fā)規(guī)范

  7. 你覺得你相對其他的人的優(yōu)勢是什么,劣勢是什么?

  8. 假設(shè)現(xiàn)在給你一個(gè)很有挑戰(zhàn)的難題去攻關(guān),你會(huì)樂意去做嗎?

  9. 附:三個(gè)面過的騰訊算法題

  • 求一個(gè)整數(shù)的二進(jìn)制中 1 的個(gè)數(shù)
  • 不知道頭結(jié)點(diǎn)的鏈表,刪除指定結(jié)點(diǎn)
  • 字符串找首位最大重復(fù)子串

二、快手

面試時(shí)間:2019.12.19
面試部門:商業(yè)化

  1. hashcode 與 equal 區(qū)別?

(1)關(guān)系操作符 ==

  • 若操作數(shù)的類型是基本數(shù)據(jù)類型,則該關(guān)系操作符判斷的是左右兩邊操作數(shù)的值是否相等
  • 若操作數(shù)的類型是引用數(shù)據(jù)類型,則該關(guān)系操作符判斷的是左右兩邊操作數(shù)的內(nèi)存地址是否相同。也就是說,若此時(shí)返回 true, 則該操作符作用的一定是同一個(gè)對象

(2)equals(內(nèi)部實(shí)現(xiàn)三個(gè)步驟)

  • 先 比較引用是否相同 (是否為同一對象)
  • 判斷類型是否一致(是否為同一類型)
  • 最后 比較內(nèi)容是否一致
  • 注:equal 的默認(rèn)行為是比較引用,所以除非在自己的新類中覆蓋了 equal() 方法,否則不可能表現(xiàn)出我們希望的行為

(3)hashCode

  • hashcode 是系統(tǒng)用來快速檢索對象而使用(一般在需要用哈希算法的數(shù)據(jù)結(jié)構(gòu)中才有用,比如 HashSet, HashMap 和 Hashtable)
  • 重寫 equals 方法和 hashcode 方法時(shí),equals 方法中用到的成員變量也必定會(huì)在 hashcode 方法中用到,只不過前者作為比較項(xiàng),后者作為生成摘要的信息項(xiàng),本質(zhì)上所用到的數(shù)據(jù)是一樣的,從而保證二者的一致性

(4)equals 與 hashCode 關(guān)系

  • 如果兩個(gè)對象 equals,那么它們的 hashCode 必然相等
  • 但是 hashCode 相等,equals 不一定相等

傳送門: Java 中的 ==, equals 與 hashCode 的區(qū)別與聯(lián)系

  1. hashmap 實(shí)現(xiàn)原理,給一個(gè) key 如何計(jì)算槽位,如何取值?

  2. 如何做的 RN 頁面的性能優(yōu)化

  3. Flutter 有了解過沒有?與 RN 的區(qū)別是什么

  4. RN 與 Native 的對比

  5. 造成 oom 的原因

  6. 說一些引起內(nèi)存泄漏的場景

  7. 內(nèi)存泄漏怎么來檢測,LeakCanary 的原理是什么

  8. 檢測到內(nèi)存泄漏怎么修復(fù)

  9. service 的 bindservice() 與 startService 區(qū)別

23 個(gè)安卓重難點(diǎn)突破,帶你吃透 Service 知識(shí)點(diǎn)

  1. requestLayout,invalidate 的區(qū)別

  2. 下面代碼是否能編譯通過:

Number[] a = new Integer[] {0};  // 能通過

List<Number> a = new ArrayList<Integer> ();  // 不能通過
  1. Serializable 與 Parcelable 的區(qū)別?

  2. Serializable 中的 serialVersionUID 作用,如果修改了一個(gè)值,這個(gè)ID是否會(huì)改變?

  3. Android Touch 事件的分發(fā)機(jī)制

  4. 橫向 ScrollView、縱向 ListView 怎么處理滑動(dòng)手勢沖突

Android 實(shí)踐之 ScrollView 中滑動(dòng)沖突處理

  1. 數(shù)據(jù)結(jié)構(gòu)-二叉樹的廣度遍歷

  2. 其他若干項(xiàng)目相關(guān)問題

三、美團(tuán)外賣

面試時(shí)間:2019.12.25
面試部門:外賣商家端
面試情況:已通過

  1. Java 虛擬機(jī)類加載器分類,類加載器的代理機(jī)制有什么好處?

(1)類加載器分類

  • 啟動(dòng)類加載器:加載 Java 的核心庫,是用原生代碼來實(shí)現(xiàn)的,并不繼承自 java.lang.ClassLoader;
  • 擴(kuò)展類加載器:加載 Java 的擴(kuò)展庫。Java 虛擬機(jī)的實(shí)現(xiàn)會(huì)提供一個(gè)擴(kuò)展庫目錄。該類加載器在此目錄里面查找并加載 Java 類;
  • 系統(tǒng)/應(yīng)用類加載器:它根據(jù) Java 應(yīng)用的類路徑(CLASSPATH)來加載 Java 類。一般來說,Java 應(yīng)用的類都是由它來完成加載的??梢酝ㄟ^ ClassLoader.getSystemClassLoader()來獲取它;
  • 注:類加載器樹狀組織結(jié)構(gòu),除了引導(dǎo)類加載器之外,所有的類加載器都有一個(gè)父類加載器。類加載器 Java 類如同其它的 Java 類一樣,也是要由類加載器來加載的。

(2)類加載器的代理機(jī)制

  • 原理:類加載器在嘗試自己去查找某個(gè)類的字節(jié)代碼并定義它時(shí),會(huì)先代理給其父類加載器,由父類加載器先去嘗試加載這個(gè)類,依次類推;
  • 作用:代理模式是為了保證 Java 核心庫的類型安全。對于Java 核心庫的類的加載工作由引導(dǎo)類加載器來統(tǒng)一完成,保證了 Java 應(yīng)用所使用的都是同一個(gè)版本的 Java 核心庫的類,是互相兼容的。

傳送門:深入探討 Java 類加載器

  1. Java 虛擬機(jī)是如何判定兩個(gè) Java 類是相同的?
  • Java 虛擬機(jī)不僅要看類的全名是否相同,還要看加載此類的類加載器 (defining loader) 是否一樣。即便是同樣的字節(jié)代碼,被不同的類加載器加載之后所得到的類,也是不同的;
  • 不同的類加載器為相同名稱的類創(chuàng)建了額外的名稱空間。相同名稱的類可以并存在 Java 虛擬機(jī)中,只需要用不同的類加載器來加載它們即可。不同類加載器加載的類之間是不兼容的,這就相當(dāng)于在 Java 虛擬機(jī)內(nèi)部創(chuàng)建了一個(gè)個(gè)相互隔離的 Java 類空間。
  1. Java 類的加載過程是什么?

Java 類的加載過程 - 三個(gè)主要步驟:加載、鏈接、初始化:
(1)加載 - 將字節(jié)碼數(shù)據(jù)從不同的數(shù)據(jù)源讀取到 JVM 中,并映射為 JVM 認(rèn)可的數(shù)據(jù)結(jié)構(gòu) (Class 對象)

  • 由于類加載器的代理機(jī)制,啟動(dòng)類加載過程的類加載器和真正完成類加載工作的類加載器,有可能不同;
  • 啟動(dòng)類的加載過程通過調(diào)用loadClass()來實(shí)現(xiàn),稱為初始加載器 (initiating loader);而完成類的加載工作通過調(diào)用defineClass()來實(shí)現(xiàn),稱為類的定義加載器 (defining loader)。在 Java 虛擬機(jī)判斷兩個(gè)類是否相同的時(shí)候,使用的是類的定義加載器;
  • loadClass() 拋出的是 java.lang.ClassNotFoundException 異常,而 defineClass() 拋出的是 java.lang.NoClassDefFoundError 異常;
  • 類加載器在成功加載某個(gè)類之后,會(huì)把得到的 java.lang.Class 類的實(shí)例緩存起來。下次再請求加載該類的時(shí)候,類加載器會(huì)直接使用緩存的類的實(shí)例,而不會(huì)嘗試再次加載 (即 loadClass()不會(huì)被重復(fù)調(diào)用)

(2)鏈接 - 將原始的類定義信息平滑地轉(zhuǎn)化入 JVM 運(yùn)行的過程中

  • 驗(yàn)證:核驗(yàn)字節(jié)信息是符合 Java 虛擬機(jī)規(guī)范;
  • 準(zhǔn)備:創(chuàng)建類或接口中的靜態(tài)變量并初始化,側(cè)重分配所需要的內(nèi)存空間(與初始化階段區(qū)分開);
  • 解析:替換常量池中的符號(hào)引用為直接引用,類、接口、方法和字段等各個(gè)方面的解析等

(3)初始化 - 真正執(zhí)行類初始化的代碼邏輯,包括靜態(tài)字段賦值的動(dòng)作,以及類中靜態(tài)初始化塊內(nèi)的邏輯。編譯器在編譯階段就會(huì)把這部分邏輯整理好,父類型的初始化邏輯優(yōu)先于當(dāng)前類型的邏輯

  1. Java 中的幾種引用類型,虛引用的使用場景?

  2. Java GC 的幾種算法

  3. Java GC 是如何判斷對象是可以被回收的?

Java 垃圾收集的原理:

  • 自動(dòng)垃圾收集的前提是清楚哪些內(nèi)存可以被釋放,主要有兩個(gè)方面,最主要部分就是對象實(shí)例,存儲(chǔ)在堆上的;另一個(gè)是方法區(qū)中的元數(shù)據(jù)等信息,例如類型不再使用,卸載該 Java 類比較合理;
  • 對象實(shí)例收集主要是兩種基本算法,引用計(jì)數(shù)和可達(dá)性分析,Java 選擇的可達(dá)性分析。JVM 會(huì)把虛擬機(jī)棧和本地方法棧中正在引用的對象、靜態(tài)屬性引用的對象常量**,作為 GC Roots。
  1. synchronized 的 4 種狀態(tài)
  1. 訪問 synchronized 修飾 static 方法、synchronized (類.class) 是否會(huì)沖突受干擾

synchronized 詳解

  1. okhttp 在 response 返回后,調(diào)用了 response.toString(),后面再使用 response 會(huì)用什么問題?

調(diào)用 response.toString() 連接會(huì)斷開,后面的取值會(huì)出問題!魔性的問題...

  1. Handler 空閑會(huì)不會(huì)阻塞主線程,IdleHandler 使用場景

  2. LeakCanary 的收集內(nèi)存泄露是在 Activity 的什么時(shí)機(jī),大致原理

  3. 如何修復(fù)匿名內(nèi)部類 handler 造成的內(nèi)存泄露?

  4. Handler 機(jī)制中是怎么保證每個(gè)線程的 Looper 是唯一的?

  5. 泛型擦除發(fā)生的時(shí)機(jī)是什么時(shí)候?

編譯期。我眼中的Java-Type體系

  1. MRN 單工程多 bundle,單工程單 bundle 的優(yōu)缺點(diǎn)對比

  2. MRN 長列表的性能問題,頁面白屏

  3. 介紹下 Redux 的工作原理

  4. 創(chuàng)建線程池的幾個(gè)關(guān)鍵參數(shù)(核心線程、最大線程....)

  5. Retrofit 的實(shí)現(xiàn)原理,使用了什么的設(shè)計(jì)模式?優(yōu)勢是什么?

  6. Gradle 的工作原理

  1. RN中,JS 與 Native 是怎么通信的?

  2. MRN 的初始化過程?如何加載 NativeModule 的?

  3. MRN 的頁面(也就是bundle)緩存機(jī)制

  4. 對于 MRN,你們是怎么處理 JNI 異常的?

  5. 其他項(xiàng)目相關(guān)問題

文中若有不對的地方,歡迎大家批評斧正,謝謝~

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

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