騰訊校招被問Android網絡相關面試題,2021華為Android面試真題解

A求知若渴 2021-09-18 08:31:33 阅读数:633

android android
* 3xx:錶示服務器要求客戶端重定向
* 4xx:錶示客戶端的請求有非法內容
* 400 Bad Request:錶示客戶端請求有語法錯誤,不能被服務器所理解
* 401 Unauthonzed:錶示請求未經授權,該狀態代碼必須與 WWW-Authenticate 報頭域一起使用
* 403 Forbidden:錶示服務器收到請求,但是拒絕提供服務,通常會在響應正文中給出不提供服務的原因
* 404 Not Found:請求的資源不存在,例如,輸入了錯誤的URL
* 5xx:錶示服務器未能正常處理客戶端的請求而出現意外錯誤
* 500 Internal Server Error:錶示服務器發生不可預期的錯誤,導致無法完成客戶端的請求
* 503 Service Unavailable:錶示服務器當前不能够處理客戶端的請求,在一段時間之後,服務器可能會恢複正常

Q:get和post的區別?

  • 技術點:HTTP請求方法
  • 參考回答:
    • GET:當客戶端要從服務器中讀取某個資源時使用GET;一般用於獲取/查詢資源信息;GET參數通過URL傳遞,傳遞的參數是有長度限制,不能用來傳遞敏感信息
    • POST:當客戶端給服務器提供信息較多時可以使用POST;POST會附帶用戶數據,一般用於更新資源信息;POST將請求參數封裝在HTTP 請求數據中,可以傳輸大量數據,傳參方式比GET更安全

Q:HTTP1.0、HTTP1.1、HTTP2.0的區別?

  • 技術點:HTTP協議發展
  • 參考回答:
  • (1)HTTP1.0和HTTP1.1的區別:
    • HTTP1.0默認使用短連接,HTTP1.1開始默認使用長連接
    • HTTP1.1增加更多的請求頭和響應頭來改進和擴充HTTP1.0的功能,比如身份認證、狀態管理和Cache緩存等
  • (2)HTTP2.0和HTTP1.X相比的新特性:
    • 新的二進制格式:HTTP2.0的協議解析决定采用二進制格式,實現方便且健壯,不同於HTTP1.x的解析是基於文本
    • 多路複用:連接共享,即每一個request都是是用作連接共享機制的
    • 服務端推送:服務器主動向客戶端推送消息
  • 引申:長連接和短連接的優缺點和適用場景,[HTTP 長連接和短連接](

)

Q:HTTP和TCP的區別

  • 技術點:HTTP、TCP
  • 參考回答:
    • TCP是傳輸層協議,定義數據傳輸和連接方式的規範。通過三次握手建立連接、四次揮手釋放連接。
    • HTTP是應用層協議,定義的是傳輸數據的內容的規範。HTTP的連接使用"請求-響應"方式。基於TCP協議傳輸,默認端口號是80。

Q:HTTP和HTTPS的區別

  • 技術點:HTTP、HTTPS
    • HTTP(超文本傳輸協議):運行在TCP之上;傳輸的內容是明文;端口是80
    • HTTPS(安全為目標的HTTP):運行在SSL/TLS之上,SSL/TLS運行在TCP之上;傳輸的內容經過加密;端口是443

Q:HTTP和Socket的區別-

  • 技術點:HTTP、Socket
  • 參考回答:
    • HTTP是應用層協議;基於TCP協議;使用“請求—響應”方式建立連接,在請求時需要先建立連接且客戶端要先發出請求,可見服務器需要等到客戶端發送一次請求後才能將數據傳回給客戶端
    • Socket(套接字)是對TCP/IP協議的封裝,是接口而不是協議;創建Socket連接時可以指定傳輸層協議TCP或UDP;Socket建立連接過程三步驟:服務器監聽->客戶端請求->連接確認,可見服務器可以直接將數據傳送給客戶端(HTTP2.0也增加了服務端推送的功能)

Q:在地址欄打入URL會發生什麼?

  • 技術點:理解網絡模型
  • 參考回答:在瀏覽器地址欄鍵入URL,按下回車之後會經曆以下流程:
    • 瀏覽器向DNS服務器請求解析該URL中的域名所對應的IP地址
    • 解析出IP地址後,根據該IP地址和默認端口80,和服務器建立TCP連接
    • 瀏覽器發出讀取文件的HTTP請求,該請求報文作為TCP三次握手的第三個報文的數據發送給服務器
    • 服務器對瀏覽器請求作出響應,並把對應的html文本發送給瀏覽器
    • 釋放TCP連接,若connection模式為close,則服務器主動關閉TCP連接,客戶端被動關閉連接,釋放TCP連接;若connection模式為keepalive,則該連接會保持一段時間,在該時間內可以繼續接收請求
    • 客戶端將服務器響應的html文本解析並顯示

1.4 JVM

Q:JVM內存是如何劃分的?

  • 技術點:JVM內存管理
  • 思路:分條解釋每部分內存的作用,詳見[要點提煉| 理解JVM之內存管理](

)

  • 參考回答:JVM會用一段空間來存儲執行程序期間需要用到的數據和相關信息,這段空間就是運行時數據區(Runtime Data Area),也就是常說的JVM內存。JVM會將它所管理的內存劃分為線程私有數據區線程共享數據區兩大類:
    • 線程私有數據區包含:
      • 程序計數器:是當前線程所執行的字節碼的行號指示器
      • 虛擬機棧:是Java方法執行的內存模型
      • 本地方法棧:是虛擬機使用到的Native方法服務
    • 線程共享數據區包含:
      • Java堆:用於存放幾乎所有的對象實例和數組;是垃圾收集器管理的主要區域,也被稱做“GC堆”;是Java虛擬機所管理的內存中最大的一塊
      • 方法區:用於存儲已被虛擬機加載的類信息、常量、靜態變量、即時編譯器編譯後的代碼等數據;Class文件中除了有類的版本、字段、方法、接口等描述信息外,還有一項信息是常量池(Constant Pool Table),用於存放編譯期生成的各種字面量和符號引用,這部分內容將在類加載後進入方法區的運行時常量池中存放
  • 引申:談談JVM的堆和棧差別

Q:談談垃圾回收機制?為什麼引用計數器判定對象是否回收不可行?知道哪些垃圾回收算法?

  • 技術點:垃圾回收機制
  • 思路:從如何判定對象可回收、如果回收具體算法這兩方面展開談垃圾回收機制,詳見[要點提煉| 理解JVM之GC](

)

  • 參考回答:
  • (1)判定對象可回收有兩種方法:
    • 引用計數算法:給對象中添加一個引用計數器,每當有一個地方引用它時,計數器值就加1;當引用失效時,計數器值就减1;任何時刻計數器為0的對象就是不可能再被使用的。然而在主流的Java虛擬機裏未選用引用計數算法來管理內存,主要原因是它難以解决對象之間相互循環引用的問題,所以出現了另一種對象存活判定算法。
    • 可達性分析法:通過一系列被稱為『GC Roots』的對象作為起始點,從這些節點開始向下搜索,搜索所走過的路徑稱為引用鏈,當一個對象到GC Roots沒有任何引用鏈相連時,則證明此對象是不可用的。其中可作為GC Roots的對象:虛擬機棧中引用的對象,主要是指棧幀中的本地變量、本地方法棧中Native方法引用的對象、方法區中類靜態屬性引用的對象、方法區中常量引用的對象
  • (2)回收算法有以下四種:
    • 分代收集算法:是當前商業虛擬機都采用的一種算法,根據對象存活周期的不同,將Java堆劃分為新生代和老年代,並根據各個年代的特點采用最適當的收集算法。
      • 新生代:大批對象死去,只有少量存活。使用『複制算法』,只需複制少量存活對象即可。
        • 複制算法:把可用內存按容量劃分為大小相等的兩塊,每次只使用其中的一塊。當這一塊的內存用盡後,把還存活著的對象『複制』到另外一塊上面,再將這一塊內存空間一次清理掉。
      • 老年代:對象存活率高。使用『標記—清理算法』或者『標記—整理算法』,只需標記較少的回收對象即可。
        • 標記-清除算法:首先『標記』出所有需要回收的對象,然後統一『清除』所有被標記的對象。
        • 標記-整理算法:首先『標記』出所有需要回收的對象,然後進行『整理』,使得存活的對象都向一端移動,最後直接清理掉端邊界以外的內存。
  • 引申:談談每種回收算法的優缺點

Q:Java中引用有幾種類型?在Android中常用於什麼情景?

  • 技術點:Java引用類型
  • 思路:分條解釋每種類型的特點和適用場景,詳見[要點提煉| 理解JVM之GC](

)

  • 參考回答:引用的四種類型
    • 强引用(StrongReference):具有强引用的對象不會被GC;即便內存空間不足,JVM寧願拋出OutOfMemoryError使程序异常終止,也不會隨意回收具有强引用的對象。
    • 軟引用(SoftReference):只具有軟引用的對象,會在內存空間不足的時候被GC;軟引用常用來實現內存敏感的高速緩存
    • 弱引用(WeakReference):只被弱引用關聯的對象,無論當前內存是否足够都會被GC;强度比軟引用更弱,常用於描述非必需對象;常用於解决內存泄漏的問題
    • 虛引用(PhantomReference):僅持有虛引用的對象,在任何時候都可能被GC;常用於跟踪對象被GC回收的活動;必須和引用隊列 (ReferenceQueue)聯合使用,當垃圾回收器准備回收一個對象時,如果發現它還有虛引用,就會在回收對象的內存之前,把這個虛引用加入到與之關聯的引用隊列中。

Q:類加載的全過程是怎樣的?什麼是雙親委派模型?

  • 技術點:類加載機制、雙親委派模型
  • 思路:類加載機制的含義以及每個階段的作用,在解釋雙親委派模型之前需要先理解類加載器,詳見[要點提煉| 理解JVM之類加載機制](

)

  • 參考回答:
  • (1)類加載機制:是虛擬機把描述類的數據從Class文件加載到內存,並對數據進行校驗轉換解析初始化,最終形成可被虛擬機直接使用的Java類型的過程。另外,類型的加載、連接和初始化過程都是在程序運行期完成的,從而通過犧牲一些性能開銷來換取Java程序的高度靈活性。下面介紹類加載每個階段的任務:
    • 加載(Loading):通過類的全限定名來獲取定義此類的二進制字節流;將該二進制字節流所代錶的靜態存儲結構轉化為方法區的運行時數據結構,該數據存儲數據結構由虛擬機實現自行定義;在內存中生成一個代錶這個類的java.lang.Class對象,它將作為程序訪問方法區中的這些類型數據的外部接口
    • 驗證(Verification):確保Class文件的字節流中包含的信息符合當前虛擬機的要求,包括文件格式驗證、元數據驗證、字節碼驗證和符號引用驗證
    • 准備(Preparation):為類變量分配內存,因為這裏的變量是由方法區分配內存的,所以僅包括類變量而不包括實例變量,後者將會在對象實例化時隨著對象一起分配在Java堆中;設置類變量初始值,通常情况下零值
    • 解析(Resolution):虛擬機將常量池內的符號引用替換為直接引用的過程
    • 初始化(Initialization):是類加載過程的最後一步,會開始真正執行類中定義的Java字節碼。而之前的類加載過程中,除了在『加載』階段用戶應用程序可通過自定義類加載器參與之外,其餘階段均由虛擬機主導和控制
  • (2)類加載器:不僅用於加載類,還和這個類本身一起作為在JVM中的唯一標識。常見類加載器類型有:
    • 啟動類加載器:是虛擬機自身的一部分
    • 擴展類加載器、應用程序類加載器、自定義類加載器:獨立於虛擬機外部
  • (3)雙親委派模型:錶示類加載器之間的層次關系。
    • 前提:除了頂層啟動類加載器外,其餘類加載器都應當有自己的父類加載器,且它們之間關系一般不會以繼承(Inheritance)關系來實現,而是通過組合(Composition)關系來複用父加載器的代碼。
    • 工作過程:若一個類加載器收到了類加載的請求,它先會把這個請求委派給父類加載器,並向上傳遞,最終請求都傳送到頂層的啟動類加載器中。只有當父加載器反饋自己無法完成這個加載請求時,子加載器才會嘗試自己去加載。

Q:工作內存和主內存的關系?在Java內存模型有哪些可以保證並發過程的原子性、可見性和有序性的措施?

  • 技術點:JVM內存模型、線程安全
  • 思路:理解Java內存模型的結構、詳見[要點提煉| 理解JVM之內存模型&線程](

)

  • 參考回答:Java內存模型就是通過定義程序中各個變量訪問規則,即在虛擬機中將變量存儲到內存和從內存中取出變量這樣的底層細節。
    • 模型結構如圖:

      騰訊校招被問Android網絡相關面試題,2021華為Android面試真題解_移動開發

      其中 ,主內存(Main Memory)是所有變量的存儲比特置,每條線程還有自己的工作內存,用於保存被該線程使用到的變量的主內存副本拷貝。為了獲取更好的運行速度,虛擬機可能會讓工作內存優先存儲於寄存器和高速緩存中。

    • 保證並發過程的原子性、可見性和有序性的措施:

      • 原子性(Atomicity):一個操作要麼都執行要麼都不執行。
        • 可直接保證的原子性變量操作有:readloadassignusestorewrite,因此可認為基本數據類型的訪問讀寫是具備原子性的。
        • 若需要保證更大範圍的原子性,可通過更高層次的字節碼指令monitorentermonitorexit來隱式地使用lockunlock這兩個操作,反映到Java代碼中就是同步代碼塊synchronized關鍵字。
      • 可見性(Visibility):當一個線程修改了共享變量的值,其他線程能够立即得知這個修改。
        • 通過在變量修改後將新值同步回主內存,在變量讀取前從主內存刷新變量值這種依賴主內存作為傳遞媒介的方式來實現。
        • 提供三個關鍵字保證可見性:volatile能保證新值能立即同步到主內存,且每次使用前立即從主內存刷新;synchronized對一個變量執行unlock操作之前可以先把此變量同步回主內存中;被final修飾的字段在構造器中一旦初始化完成且構造器沒有把this的引用傳遞出去,就可以在其他線程中就能看見final字段的值。
      • 有序性(Ordering):程序代碼按照指令順序執行。
        • 如果在本線程內觀察,所有的操作都是有序的,指“線程內錶現為串行的語義”;如果在一個線程中觀察另一個線程,所有的操作都是無序的,指“指令重排序”現象和“工作內存與主內存同步延遲”現象。
        • 提供兩個關鍵字保證有序性:volatile 本身就包含了禁止指令重排序的語義;synchronized保證一個變量在同一個時刻只允許一條線程對其進行lock操作,使得持有同一個鎖的兩個同步塊只能串行地進入。

Q:JVM、Dalvik、ART的區別?

  • 技術點:虛擬機對比
  • 思路:分別談談JVM和Dalvik、Dalvik和ART的區別,詳見 Jvm、Dalvik和Art的區別
  • 參考回答:
    • Dalvik :是Google公司自己設計用於Android平臺的Java虛擬機,不是Java虛擬機,沒有遵循Java虛擬機規範,具體區別如下圖:

      騰訊校招被問Android網絡相關面試題,2021華為Android面試真題解_移動開發_02

    • ART:代替Dalvik,應用無需每次運行都要先編譯,而是在安裝時就預編譯字節碼到機器語言,提昇運行時效率;預先編譯也使得ART占用空間比Dalvik大,即用空間換時間;由於减少運行時重複編譯,可明顯改善電池續航,降低了能耗。

Q:Java中堆和棧的區別?

  • 技術點:內存管理
  • 思路:從存放數據和內存回收角度出發
  • 參考回答: 在java中,堆和棧都是內存中存放數據的地方,具題區別是:
    • 棧內存:主要用來存放基本數據類型局部變量;當在代碼塊定義一個變量時會在棧中為這個變量分配內存空間,當超過變量的作用域後這塊空間就會被自動釋放掉。
    • 堆內存:用來存放運行時創建的對象,比如通過new關鍵字創建出來的對象和數組;需要由Java虛擬機的自動垃圾回收器來管理。

1.5 操作系統

Q:操作系統中進程和線程的區別?

  • 技術點:進程、線程
  • 參考回答:
    • 進程是操作系統分配和管理資源的單比特,線程是CPU調度和管理的單比特,是CPU調度的最小單元
    • 進程擁有獨立的地址空間,而線程間共享地址空間
    • 進程創建的開銷比較大,線程創建的開銷小
  • 引申:可談談安卓系統中對進程和線程的理解

Q:進程死鎖的產生和避免?

  • 技術點:死鎖
  • 思路:可從死鎖含義、產生條件、解决辦法、避免手段出發
  • 參考回答:死鎖是指多個進程因循環等待資源而造成無法執行的現象,它會造成進程無法執行,同時會造成系統資源的極大浪費。
    • 死鎖產生的條件:
      • 互斥使用:指進程對所分配到的資源進行排它性使用,即在一段時間內某資源只由一個進程占用。如果此時還有其它進程請求資源,則請求者只能等待,直至占有資源的進程用畢釋放。
      • 不可搶占:指進程已獲得的資源,在未使用完之前,不能被剝奪,只能在使用完時由自己釋放。
      • 請求和保持:指進程已經保持至少一個資源,但又提出了新的資源請求,而該資源已被其它進程占有,此時請求進程阻塞,但又對自己已獲得的其它資源保持不放。
      • 循環等待:指在發生死鎖時,必然存在一個進程——資源的環形鏈,即進程集合{P0,P1,P2,···,Pn}中的P0正在等待一個P1占用的資源;P1正在等待P2占用的資源,……,Pn正在等待已被P0占用的資源。
    • 解决死鎖的策略:
      • 銀行家算法:判斷此次請求是否造成死鎖若會造成死鎖,否則拒絕該請求
      • 鴕鳥算法:忽略該問題,常用於在極少發生死鎖的的情况
    • 死鎖的避免:通過合理的資源分配算法來確保永遠不會形成環形等待的封閉進程鏈,即“如果一個進程的當前請求的資源會導致死鎖,系統拒絕啟動該進程;如果一個資源的分配會導致下一步的死鎖,系統就拒絕本次的分配”

1.6 數據結構&算法

Q:怎麼理解數據結構?
Q:什麼是斐波那契數列?
Q:迭代和遞歸的特點,並比較優缺點
Q:了解哪些查找算法,時間複雜度都是多少?
Q:了解哪些排序算法,並比較一下,以及適用場景
Q:快排的基本思路是什麼?最差的時間複雜度是多少?如何優化?
Q:AVL樹插入或删除一個節點的過程是怎樣的?
Q:什麼是紅黑樹?
Q:100盞燈問題
Q:老鼠和毒藥問題,加個條件,必須要求第二天出結果
Q:海量數據問題
Q:(手寫算法)二分查找
Q:(手寫算法)反轉鏈錶
Q:(手寫算法)用兩個棧實現隊列
Q:(手寫算法)多線程輪流打印問題
Q:(手寫算法)如何判斷一個鏈有環/兩條鏈交叉
Q:(手寫算法)快速從一組無序數中找到第k大的數/前k個大的數
Q:(手寫算法)最長(不)重複子串

  • 技術點:數據結構、手寫算法
  • 思路:篇幅問題,該部分將單獨做一篇總結

1.7 設計模式

Q:談談MVC、MVP和MVVM,好在哪裏,不好在哪裏?

  • 技術點:MVC、MVP、MVVM
  • 思路:詳見 MVP、MVVM模式
  • 參考回答:
    • MVP的含義:
      • Model:數據層,負責存儲、檢索、操縱數據。
      • View:UI層,顯示數據,並向Presenter報告用戶行為。
      • Presenter:作為View與Model交互的中間紐帶,從Model拿數據,應用到UI層,管理UI的狀態,響應用戶的行為。
    • MVP相比於MVC的優勢
      • 分離了視圖邏輯和業務邏輯,降低了耦合。
      • Activity只處理生命周期的任務,代碼變得更加簡潔
      • 視圖邏輯和業務邏輯分別抽象到了View和Presenter的接口中去,提高代碼的可閱讀性。
      • Presenter被抽象成接口,可以有多種具體的實現,所以方便進行單元測試
      • 把業務邏輯抽到Presenter中去,避免後臺線程引用著Activity導致Activity的資源無法被系統回收從而引起內存泄露和OOM。
    • MVVM的含義:與MVP類似,利用數據綁定(Data Binding)、依賴屬性(Dependency Property)、命令(Command)、路由事件(Routed Event)等新特性,打造了一個更加靈活高效的架構。
    • MVVM相比於MVP的優勢:在常規的開發模式中,數據變化需要更新UI的時候,需要先獲取UI控件的引用,然後再更新UI,獲取用戶的輸入和操作也需要通過UI控件的引用,但在MVVM中,這些都是通過數據驅動來自動完成的,數據變化後會自動更新UI,UI的改變也能自動反饋到數據層,數據成為主導因素。這樣MVVM層在業務邏輯處理中只要關心數據,不需要直接和UI打交道,在業務處理過程中簡單方便很多。

Q:如何理解生產者消費者模型?

  • 技術點:生產者消費者模型
  • 參考回答:生產者消費者模型通過一個緩存隊列,既解决了生產者和消費者之間强耦合的問題,又平衡了生產者和消費者的處理能力。
    • 具體規則:生產者只在緩存區未滿時進行生產,緩存區滿時生產者進程被阻塞;消費者只在緩存區非空時進行消費,緩存區為空時消費者進程被阻塞;當消費者發現緩存區為空時會通知生產者生產;當生產者發現緩存區滿時會通知消費者消費。
    • 實現關鍵:synchronized保證對象只能被一個線程占用;wait()讓當前線程進入等待狀態,並釋放它所持有的鎖;notify()&notifyAll()喚醒一個(所有)正處於等待狀態的線程

Q:是否能從Android中舉幾個例子說說用到了什麼設計模式?

  • 技術點:設計模式
  • 參考回答:
    • View事件分發:責任鏈模式
    • BitmapFactory加載圖片:工廠模式
    • Adapter:適配器模式
    • Builder:建造者模式
    • Adapter.notifyDataSetChanged():觀察者模式
    • Binder機制:代理模式

Q:裝飾模式和代理模式有哪些區別?

  • 技術點:裝飾模式、代理模式
  • 參考回答:
    • 使用目的不同:代理模式是給目標對象提供一個代理對象,並由代理對象控制對目標對象的引用;裝飾模式是在不必改變原類文件和使用繼承的情况下,動態地擴展一個對象的功能
    • 構造不同:代理模式內部保持對目標對象的引用;裝飾模式是通過構造函數傳參的方式得到目標對象

Q:實現單例模式有幾種方法?懶漢式中雙層鎖的目的是什麼?兩次判空的目的又是什麼?

  • 技術點:單例模式
  • 參考回答:實現單例模式常見的兩種方式:
    (1)懶漢式:延遲加載,同時也要保證多線程環境下會產生多個single對象(DCL)
public class Singleton {
private Singleton() {}
private volatile static Singleton instance;//第一層鎖:保證變量可見性
public static Singleton getInstance() {
if (single == null) {//第一次判空:無需每次都加鎖,提高性能
synchronized (Singleton.class) {//第二層鎖:保證線程同步
if (single == null) {//第二次判空:避免多線程同時執行getInstance()產生多個single對象
single = new Singleton();
}
}
}
return single;
}
}

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.

最後

我這裏整理了一份完整的學習思維以及Android開發知識大全PDF。

騰訊校招被問Android網絡相關面試題,2021華為Android面試真題解_移動開發_03

 CodeChina開源項目:《Android學習筆記總結+移動架構視頻+大廠面試真題+項目實戰源碼》

當然實踐出真知,即使有了學習線路也要注重實踐,學習過的內容只有結合實操才算是真正的掌握。

版权声明:本文为[A求知若渴]所创,转载请带上原文链接,感谢。 https://gsmany.com/2021/09/20210918083132636u.html