2019校招Android面試題解1.0(下篇)
1.3 計算機網路
- 基礎
Q:五層協議的體系結構分別是什麼?每一層都有哪些協議?
- 技術點:網路模型、協議
- 思路:分條解釋每層名字以及協議
- 參考回答:
Q:為何有MAC地址還要IP地址?
- 技術點:MAC地址、IP地址
- 參考回答:
- 每臺主機在出廠時都有一個唯一的MAC地址,但是IP地址的分配是根據網路的拓樸結構,得以保證路由選擇方案建立在網路所處的拓撲位置基礎而不是裝置製造商的基礎上
- 使用IP地址更方便資料傳輸。資料包在這些節點之間的移動都是由ARP協議負責將IP地址對映到MAC地址上來完成的。
- TCP
Q:TCP和UDP的區別?
- 技術點:傳輸層協議對比
- 參考回答:
- TCP傳輸控制協議:面向連線;使用全雙工的可靠通道;提供可靠的服務,即無差錯、不丟失、不重複且按序到達;擁塞控制、流量控制、超時重發、丟棄重複資料等等可靠性檢測手段;面向位元組流;每條TCP連線只能是點到點的;用於傳輸可靠性要求高、資料量大的資料
- UDP使用者資料報協議:無連線;使用不可靠通道;盡最大努力交付,即不保證可靠交付;無擁塞控制等;面向報文;支援一對一、一對多、多對一和多對多的互動通訊;用於傳輸可靠性要求不高、資料量小的資料
Q:擁塞控制和流量控制都是什麼,兩者的區別?
- 技術點:擁塞控制、流量控制
- 參考回答:
- 擁塞控制:對網路中的路由和鏈路傳輸進行速度限制,避免網路過載;包含四個過程:慢啟動、擁塞避免、快重傳和快恢復
- 流量控制 :對點和點/傳送方和接收方之間進行速度匹配,由於接收方的應用程式讀取速度不一定很迅速,加上快取有限,因此需要避免傳送速度過快;相關技術:TCP滑動視窗、回退N針協議
Q:談談TCP為什麼要三次握手?為什麼要四次揮手?
- 技術點:TCP可靠保證
- 參考回答:
-
(1)建立TCP連線:TCP的三次握手
- 客戶端向服務端傳送一個表示建立連線的報文段SYN報文段;一旦包含SYN報文段的IP資料報到達伺服器主機,伺服器從IP資料報中提取出TCP、SYN報文段,為該TCP連線分配需要的快取和變數,並向客戶端傳送表示允許連線的報文段ACK;在收到ACK報文段之後,客戶端也要給該連線分配快取和變數,客戶端向伺服器再發送一個報文段ACK,表示對允許連線的報文段進行了確認。自此完成一次TCP連線。
- 第三次握手可以避免由於客戶端延遲的請求連線的請求,使得服務端無故再次建立連線。
-
(2)斷開TCP連線:TCP的四次揮手
- 由於TCP連線是全雙工的,因此每個方向都必須單獨關閉。客戶端在資料傳送完畢後傳送一個結束資料段FIN,且服務端也返回確認資料段ACK,此時結束了客戶端到服務端的連線;然後客戶端接收到服務端傳送的FIN,且服務端也收到了ACK之後,自此雙方的資料通訊完全結束。簡單說來是 “先關讀,後關寫”,一共需要四個階段:伺服器讀通道關閉->客戶機寫通道關閉->客戶機讀通道關閉->伺服器寫通道關閉。
- 引申:談談客戶端到達的TIME_WAIT狀態時間是MaximumSegmentLifetime的兩倍,而不是直接進入CLOSED狀態的原因。(保證TCP協議的全雙工連線能夠可靠關閉、保證本次連線的重複資料段從網路中消失)
Q:播放視訊用TCP還是UDP?為什麼?
- 技術點:傳輸層協議適用場景
- 參考回答:播放視訊適合用UDP。UDP適用於對網路通訊質量要求不高、要求網路通訊速度能儘量快的實時性應用;而TCP適用於對網路通訊質量有要求的可靠性應用。而且視訊區分關鍵幀和普通幀,雖然UDP會丟幀但如果只是丟普通幀損失並不大,取而代之的是高速率和實時性。
- 引申:TCP、UDP適用的場景
- HTTP
Q:瞭解哪些響應狀態碼?
- 技術點:響應狀態碼
- 思路:
- 參考回答:狀態碼由三位數字組成,第一位數字表示響應的型別,常用的狀態碼有五大類:
- 1xx:表示伺服器已接收了客戶端請求,客戶端可繼續傳送請求
- 2xx:表示伺服器已成功接收到請求並進行處理
- 200 OK:表示客戶端請求成功
- 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記憶體管理
- 思路:分條解釋每部分記憶體的作用,詳見 ofollow,noindex">要點提煉| 理解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堆劃分為新生代和老年代,並根據各個年代的特點採用最適當的收集演算法。
- 新生代:大批物件死去,只有少量存活。使用『複製演算法』,只需複製少量存活物件即可。
- 複製演算法 :把可用記憶體按容量劃分為大小相等的兩塊,每次只使用其中的一塊。當這一塊的記憶體用盡後,把還存活著的物件『複製』到另外一塊上面,再將這一塊記憶體空間一次清理掉。
- 老年代:物件存活率高。使用『標記—清理演算法』或者『標記—整理演算法』,只需標記較少的回收物件即可。
- 標記-清除演算法 :首先『標記』出所有需要回收的物件,然後統一『清除』所有被標記的物件。
- 標記-整理演算法 :首先『標記』出所有需要回收的物件,然後進行『整理』,使得存活的物件都向一端移動,最後直接清理掉端邊界以外的記憶體。
- 新生代:大批物件死去,只有少量存活。使用『複製演算法』,只需複製少量存活物件即可。
- 分代收集演算法 :是當前商業虛擬機器都採用的一種演算法,根據物件存活週期的不同,將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記憶體模型就是通過定義程式中各個 變數 的 訪問規則 ,即在虛擬機器中將變數儲存到記憶體和從記憶體中取出變數這樣的底層細節。
- 模型結構如圖:
- 保證併發過程的原子性、可見性和有序性的措施:
- 原子性 (Atomicity):一個操作要麼都執行要麼都不執行。
- 可直接保證的原子性變數操作有:
read
、load
、assign
、use
、store
和write
,因此可認為基本資料型別的訪問讀寫是具備原子性的。 - 若需要保證更大範圍的原子性,可通過更高層次的位元組碼指令
monitorenter
和monitorexit
來隱式地使用lock
和unlock
這兩個操作,反映到Java程式碼中就是同步程式碼塊synchronized
關鍵字。
- 可直接保證的原子性變數操作有:
- 可見性 (Visibility):當一個執行緒修改了共享變數的值,其他執行緒能夠立即得知這個修改。
- 通過在變數修改後將新值同步回主記憶體,在變數讀取前從主記憶體重新整理變數值這種依賴主記憶體作為傳遞媒介的方式來實現。
- 提供三個關鍵字保證可見性:
volatile
能保證新值能 立即 同步到主記憶體,且每次使用前立即從主記憶體重新整理;synchronized
對一個變數執行unlock操作之前可以先把此變數同步回主記憶體中;被final
修飾的欄位在構造器中一旦初始化完成且構造器沒有把this
的引用傳遞出去,就可以在其他執行緒中就能看見final欄位的值。
- 有序性 (Ordering):程式程式碼按照指令順序執行。
- 如果在本執行緒內觀察,所有的操作都是有序的,指“執行緒內表現為序列的語義”;如果在一個執行緒中觀察另一個執行緒,所有的操作都是無序的,指“指令重排序”現象和“工作記憶體與主記憶體同步延遲”現象。
- 提供兩個關鍵字保證有序性:
volatile
本身就包含了禁止指令重排序的語義;synchronized
保證一個變數在同一個時刻只允許一條執行緒對其進行lock操作,使得持有同一個鎖的兩個同步塊只能序列地進入。
- 原子性 (Atomicity):一個操作要麼都執行要麼都不執行。
- 模型結構如圖:
Q:JVM、Dalvik、ART的區別?
- 技術點:虛擬機器對比
- 思路:分別談談JVM和Dalvik、Dalvik和ART的區別,詳見 Jvm、Dalvik和Art的區別
- 參考回答:
- Dalvik :是Google公司自己設計用於Android平臺的Java虛擬機器,不是Java虛擬機器,沒有遵循Java虛擬機器規範,具體區別如下圖:
- ART:代替Dalvik,應用無需每次執行都要先編譯,而是在安裝時就 預編譯 位元組碼到機器語言,提升執行時效率;預先編譯也使得ART佔用空間比Dalvik大,即用時間換空間;由於減少執行時重複編譯,可明顯改善電池續航,降低了能耗。
- Dalvik :是Google公司自己設計用於Android平臺的Java虛擬機器,不是Java虛擬機器,沒有遵循Java虛擬機器規範,具體區別如下圖:
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的 優勢 :
- MVVM的含義:與MVP類似,利用 資料繫結 (Data Binding)、 依賴屬性 (Dependency Property)、 命令 (Command)、 路由事件 (Routed Event)等新特性,打造了一個更加靈活高效的架構。
- MVVM相比於MVP的 優勢 :在常規的開發模式中,資料變化需要更新UI的時候,需要先獲取UI控制元件的引用,然後再更新UI,獲取使用者的輸入和操作也需要通過UI控制元件的引用,但在MVVM中,這些都是通過 資料驅動 來自動完成的,資料變化後會自動更新UI,UI的改變也能自動反饋到資料層,資料成為主導因素。這樣MVVM層在業務邏輯處理中只要關心資料,不需要直接和UI打交道,在業務處理過程中簡單方便很多。
- MVP的含義:
Q:如何理解生產者消費者模型?
- 技術點:生產者消費者模型
- 參考回答:生產者消費者模型通過一個快取佇列,既解決了生產者和消費者之間強耦合的問題,又平衡了生產者和消費者的處理能力。
- 具體規則:生產者只在快取區未滿時進行生產,快取區滿時生產者程序被阻塞;消費者只在快取區非空時進行消費,快取區為空時消費者程序被阻塞;當消費者發現快取區為空時會通知生產者生產;當生產者發現快取區滿時會通知消費者消費。
- 實現關鍵:synchronized保證物件只能被一個執行緒佔用;wait()讓當前執行緒進入等待狀態,並釋放它所持有的鎖;notify()¬ifyAll()喚醒一個(所有)正處於等待狀態的執行緒
Q:是否能從Android中舉幾個例子說說用到了什麼設計模式?
- 技術點:設計模式
- 參考回答:
Q:裝飾模式和代理模式有哪些區別?
- 技術點:裝飾模式、代理模式
- 參考回答:
- 使用目的不同:代理模式是給目標物件提供一個代理物件,並由代理物件控制對目標物件的引用;裝飾模式是在不必改變原類檔案和使用繼承的情況下,動態地擴充套件一個物件的功能
- 構造不同:代理模式內部保持對目標物件的引用;裝飾模式是通過建構函式傳參的方式得到目標物件
Q:實現單例模式有幾種方法?懶漢式中雙層鎖的目的是什麼?兩次判空的目的又是什麼?
- 技術點:單例模式
- 參考回答:實現單例模式常見的兩種方式:
(1)懶漢式:延遲載入,同時也要保證多執行緒環境下會產生多個single物件
public class Singleton { private Singleton() {} pprivate volatile static Singleton instance;//第一層鎖:保證變數可見性 public static Singleton getInstance() { if (single == null) {//第一次判空:無需每次都加鎖,提高效能 synchronized (Singleton.class) {//第二層鎖:保證執行緒同步 if (single == null) {//第二次判空:避免多執行緒同時執行getInstance()產生多個single物件 single = new Singleton(); } } } return single; } }
(2)餓漢式:在類載入初始化時就建立好一個靜態的物件供外部使用
public class Singleton { private Singleton() {} private static Singleton single = new Singleton(); public static Singleton getInstance() { return single; } }
Q:談談了解的設計模式原則?
- 技術點:設計模式原則
- 參考回答:
- 單一職責原則:一個類只負責一個功能領域中的相應職責
- 開放封閉原則:對擴充套件開放,對修改關閉
- 依賴倒置原則:抽象不應該依賴於細節,細節應當依賴於抽象。換言之,要針對介面程式設計,而不是針對實現程式設計
- 迪米特法則:應該儘量減少物件之間的互動,如果兩個物件之間不必彼此直接通訊,那麼這兩個物件就不應當發生任何直接的相互作用,如果其中的一個物件需要呼叫另一個物件的某一個方法的話,可以通過第三者轉發這個呼叫
- 合成/聚合複用原則:要儘量使用合成/聚合,儘量不要使用繼承
1.8 資料庫
Q:資料庫中的事務瞭解嗎?事務的四大特性?
- 技術點:事務
- 參考回答:
- 事務是併發控制的單位,是使用者定義的一個操作序列。它指這些操作要麼都做,要麼都不做,以便伺服器保持資料的完整性。
- 事務通常是以BEGIN TRANSACTION開始,以COMMIT或ROLLBACK結束。
- 事務的四大特性(ACID特性):原子性(Atomicity)表示事務中包括的諸操作要麼全做,要麼全不做;一致性(Consistency)表示事務執行的結果必須是使資料庫從一個一致性狀態變到另一個一致性狀態;隔離性(Isolation)表示一個事務的執行不能被其他事務干擾;持續性(Durability)表示一個事務一旦提交,它對資料庫中資料的改變就應該是永久性的
- 引申:談談資料庫事務的併發控制
Q:如何理解資料庫的正規化?
- 技術點:正規化
- 思路:詳見例項講解 資料庫的3大正規化和5大約束
- 參考回答:
- 第一正規化(1NF):資料表中的每個欄位必須是不可拆分的最小單元,即確保每一列的原子性
- 第二正規化(2NF):滿足1NF後,要求表中的所有列,都必須依賴於主鍵,而不能有任何一列與主鍵沒有關係
- 第三正規化(3NF):必須先滿足第二正規化,要求表中的每一列只與主鍵直接相關而不是間接相關,即表中的每一列只能依賴於主鍵
1.9 hr問題
Q:請簡單的自我介紹一下
- 可能意圖:開場白;短期內快速瞭解候選人情況;考察表達能力和邏輯思維;是否有備而來;第一印象
- 思路:說亮點、語言精煉、熟練回答
Q:談談專案經歷,為什麼會做,怎麼做的,遇到的難點?
Q:談談實習經歷,做了什麼,收穫有哪些?
Q:談談學習Android的經歷,有哪些學習方法和技巧?
Q:成績怎麼樣?獎學金情況?
Q:學過哪些課程?那門課印象最深刻/最有意義/學的最好/最不喜歡?為什麼?
Q:學習生活中遇到什麼挫折,如何解決的?
Q:家是哪裡的?是獨生子女嗎?從小的家庭環境如何?
Q:平常有哪些興趣愛好?大學參加了哪些校園活動?
Q:評價一下自己的優缺點?/用x個詞形容你自己。/別人都是怎樣評價你的?
Q:覺得自己部落格寫的最好的文章是什麼?為什麼?
Q:覺得自己的優勢是什麼?
- 可能意圖:瞭解候選人的性格、各方面特質,是否符合企業價值觀;瞭解其溝通表達能力、學習能力等才能,是否具有可塑性
- 思路:結合具體例項體現自己確是企業想要的人才
Q:是否會考研?/為何不保研?
Q:近x年的職業規劃?
Q:為什麼想來我們公司?/為何不轉正留在xx?
Q:對公司/部門是否有了解?
Q:為何會選擇做技術?/對女生做開發的看法?
Q:還投過那些公司,進展如何?如果xx和xx都給你發offer會如何選擇?
Q:有男/女朋友嗎?未來有什麼規劃?
Q:如何看待加班?
Q:意向工作城市是哪?/是否會考慮在xx發展?
Q:對於薪酬有什麼想法?
- 可能意圖:瞭解候選人對企業的意向度和忠誠度,是否值得給發offer
- 思路:表現出想去該公司的態度、並已為之做了準備
Q:有什麼問題想要問我?
- 可能意圖:結束語;主動權交由候選人
- 思路:諮詢和崗位&部門&公司發展相關的情況、探討對某技術的看法、詢問面試官對你的評價、尋求學習等方面的建議、瞭解後續面試流程和進度; 注意 ,避免問薪資和加班問題、也不要直接說“沒有問題”
1.10 專案相關、實習相關技術問題(略)
- 技術點:版本控制工具
- 參考回答:Git和SVN的區別有以下幾點:
- Git是分散式的,而SVN是集中式的(核心區別)
- Git按元資料方式儲存內容,而SVN按檔案儲存內容
- 在Git上每個工作成員可以任意在自己的本地版本庫開啟無限個分支且互不影響,而對於SVN分支是一個完整的目錄且這個目錄擁有完整的實際檔案
- Git沒有一個全域性的版本號,而SVN有
- Git 的內容完整性要優於SVN
- 在Git中的絕大多數操作都只需要訪問本地檔案和資源,不必聯網就可以看到所有的歷史版本記錄,而SVN 卻需要聯網
- 引申:談談兩種版本控制工具的優缺點: SVN與GIT的優缺點對比
Q:瞭解Git工具嗎?用過哪些命令?解決衝突時git merge和git rebase的區別?
- 技術點:版本控制工具Git
- 思路:通過圖記憶Git常用命令,詳見Git、GitHub、Stash
- 參考回答: 常用命令見圖,源自 一篇文章,教你學會Git
(持續更新...)
2.彩蛋時刻
之前因一篇總結文獲得各路大佬的喜愛,很是受寵若驚,更有前輩願與小白我切磋交流,實在不敢當。深知自己才疏學淺,還需再接再厲,以下都是個人拙見,如有不當,還請包涵。
Q:有關個人背景
之前有簡單介紹過,這裡再具體下,更加深刻意識到自己的菜orz。我妹子一隻,現在大連理工大學讀大四,明年畢業,專業是資訊管理與資訊系統,屬於管理學院,由於非科班,少學一些專業課,尤其演算法很渣。
很多人好奇為什麼一個妹子選擇做開發,其實是學長帶坑的hhh,當然我還會堅持把這個坑挖的更深,至少做技術是一定的,畢竟對此還是饒有興趣。但隨著技術的日新月異,將來在哪條路上繼續另當別論了。
Q:有關學習經歷/推薦書目/面試準備
這部分內容詳見春招總結: 2018Android暑期實習面試總結 。
關於校招面試多做些補充,主要是常常聽到一些同學會埋怨,“ 為何筆試多少多少AC卻沒面試通知? ”、“ 為何面試問題基本都回答上來卻不通過? ”。
對於前一個問題強調很多次,筆試成績只作參考,面試官還會綜合簡歷去決定是否願意對你發起面試,因此簡歷的作用不言而喻。好簡歷的幾個必備點: 排版美觀、重點突出、語言精煉、一頁紙、充分展示個人亮點 (部落格&Github、學歷&成績&實驗室、實習&專案、競賽&論文&榮譽獎勵......)。如果說不清楚實習&專案的情況,建議分條列舉出重要的技術點(+影響力)。
對於後一個問題,可能的原因有: 硬實力足夠但是軟實力欠缺 ,是否有良好的溝通表達能力、積極向上的性格、端正的學習態度等等;再就是 缺少一點運氣 ,除了客觀因素比如崗位競爭激烈、候選者又很厲害、崗位hc還少,再就是眼緣等主觀感受。
所以不得不說我能有好成績真的很走運,今年校招不少廠子缺移動端簡歷,反而演算法崗過熱,相對競爭小機會大;加上快人一步,提前上車,搶先奪個好印象。
再多說一句,之前的總結文針對的都是 校招面試 ,可見側重於基礎;而 社招面試 大多針對有工作經驗的求職者,更偏向專案&場景、考察工程思維,側重點會稍有不同,當然還是因面試官而異了。
Q:面試中演算法考察的難度
雖說工作後確實很少需要演算法,但作為考察手寫程式碼能力的一項指標,演算法題還是必不可少的。那就有人就會問對於移動端開發崗演算法題難度如何,只能說因為我水平太菜,校招時面試官都很好並沒有太為難,但自認為最基礎的資料結構、還有劍指offer是要刷的吧,所以這也是後期學習的一個小目標。學有餘力如果能再來個LeetCode就更好了。
Q:文章的排版&作圖
我的筆記都是用標記語言Markdown編輯的,美觀且容易上手,各大部落格也大多支援Markdown線上編輯文章。如若需要離線,可參考早前的一篇部落格 MarkdownPad 2在win10上安裝及破解 、MacBook推薦用MacDown。
不少文章會有配圖,有些取自他人技術文,會標明出處,還有些就是用Photoshop和ProcessOn渣技術作圖的,若有好的作圖產品歡迎推薦!
Q:學習習慣小分享
會有簡友在看完我的部落格後,覺得我一定是沒日沒夜地埋頭苦學才有如此學習成果。其實不然,實則“小懶蟲”一個,犯困的時候一定會小憩一下,並不是所謂的早睡早起的好孩子。這裡就簡單談談我的“學習理論”吧!
一來自認為只有精神好才能集中注意力、更 專注 才能高效率(睡懶覺的藉口),事實證明在大多數環境下,我都能聚精會神地做事情,進而高效利用時間;
二來就是摸索出一套適合自己的 學習法 ,即“系統學習+總結歸納+理解記憶+定時複習”,看起來很簡單但如果能配合好往往能事半功倍;
三來就是從小就有 做學習計劃 的習慣,無論是上學還是放假,大學還特意為自己做了個記事APP。但能100%完成計劃並非一蹴而就之事,還需要鍛鍊這些能力: 充分了解自己實力、擺脫拖延症、可靈活變通 ,即既是計劃者又是執行者。
總之用得當的計劃、高效的學習技巧、加上專注力,不斷給學習的小火車助力,加速前進。當然適合自己的學習習慣才是最好的,不要一味地模仿別人,而是用實踐出真知,何況好習慣是長期培養出來的。
Q:最終去向?
經過慎重的考慮,最終決定去了深圳騰訊(主要因為男票也在那hhh)
Q:想和我交流?
無公眾號無交流群,另有CSDN和掘金賬號,ID、發表的文章和簡書都是一樣的,Github上沒什麼有價值的東西orz,後續會進一步開發......
有問題歡迎在評論區留言,如有必要也會在文中統一回復;想和我私下交流可私戳或者評論,我會單獨給你發簡信並留下個人聯絡方式~