2019最新Android面試題

原文鏈接:https://blog.csdn.net/wen_hah...
版權聲明:本文爲博主原創文章,轉載請附上博文鏈接!

前言

金三銀四到來了,找工作的好時候到了,小夥伴們是不是都在忙着找工作呢,小弟前一陣也是忙着在找工作,面試了好多公司,所幸的是進到了自己心儀的公司,也是很幸運的。下面我將自己親身實戰的面試題及收到的面試題總結並分享答案出來。歡迎各位大哥指導、指點。

下面這些只是Android方面的知識,如果有需要Java方面的面試題的話,可以在下面留言。

1.Activity生命週期(這個是必問的)

onCreate() 創建活動,做一些數據初始化操作

onStart() 由不可見變爲可見

onResume() 可以與用戶進行交互,位於棧頂

onPause() 暫停,啓動或恢復另一個活動時調用

onStop() 停止,變爲不可見

onDestroy() 銷燬

onRestart() 由停止狀態變爲運行狀態

2.Fragment生命週期 (這個有可能會問到,問的機率不是很大)

image.png

3.Service生命週期

onCreate()

首次創建服務時,系統將調用此方法。如果服務已在運行,則不會調用此方法,該方法只調用一次。

onStartCommand()

當另一個組件通過調用startService()請求啓動服務時,系統將調用此方法。

onDestroy()

當服務不再使用且將被銷燬時,系統將調用此方法。

onBind()

當另一個組件通過調用bindService()與服務綁定時,系統將調用此方法。

onUnbind()

當另一個組件通過調用unbindService()與服務解綁時,系統將調用此方法。

onRebind()

當舊的組件與服務解綁後,另一個新的組件與服務綁定,onUnbind()返回true時,系統將調用此方法。

4.Service啓動方式(問到Service,這個肯定是要問到的)

1.startService

①.定義一個類繼承service

②.在manifest.xml文件中配置該service

③.使用context的startService(intent)啓動該service

④.不再使用時,調用stopService(Intent)停止該服務

2.bindService

①.創建bindService服務段,繼承自service並在類中,創建一個實現binder接口的實例對象並提供公共方法給客戶端調用

②.從onbind()回調方法返回此binder實例

③.在客戶端中,從onserviceconnected()回調方法接收binder,並使用提供的方法調用綁定服務

5.Activity的啓動方式(偶爾會問)

①.standard模式

a.Activity的默認啓動模式

b.每啓動一個Activity就會在棧頂創建一個新的實例。例如:鬧鐘程序

缺點:當Activity已經位於棧頂時,而再次啓動Activity時還需要在創建一個新的實例,不能直接複用。

②.singleTop模式

特點:該模式會判斷要啓動的Activity實例是否位於棧頂,如果位於棧頂直接複用,否則創建新的實例。 例如:瀏覽器的書籤

​缺點:如果Activity並未處於棧頂位置,則可能還會創建多個實例。

③.singleTask模式

特點:使Activity在整個應用程序中只有一個實例。每次啓動Activity時系統首先檢查棧中是否存在當前Activity實例,如果存在

則直接複用,並把當前Activity之上所有實例全部出棧。例如:瀏覽器主界面

④.singleInstance模式

特點:該模式的Activity會啓動一個新的任務棧來管理Activity實例,並且該勢力在整個系統中只有一個。無論從那個任務棧中啓動該Activity,都會是該Activity所在的任務棧轉移到前臺,從而使Activity顯示。主要作用是爲了在不同程序中共享一個Activity

6.Touch事件傳遞機制

在我們點擊屏幕時,會有下列事件發生:

Activity調用dispathTouchEvent()方法,把事件傳遞給Window;

Window再將事件交給DecorView(DecorView是View的根佈局);

DecorView再傳遞給ViewGroup;

Activity ——> Window ——> DecorView ——> ViewGroup——> View

事件分發的主要有三個關鍵方法

dispatchTouchEvent() 分發

onInterceptTouchEvent() 攔截 ,只有ViewGroup獨有此方法

onTouchEvent() 處理觸摸事件

Activity首先調用dispathTouchEvent()進行分發,接着調用super向下傳遞

ViewGroup首先調用dispathTouchEvent()進行分發,接着會調用onInterceptTouchEvent()(攔截事件)。若攔截事件返回爲true,表示攔截,事件不會向下層的ViewGroup或者View傳遞;false,表示不攔截,繼續分發事件。默認是false,需要提醒一下,View是沒有onInterceptTouchEvent()方法的

事件在ViewGroup和ViewGroup、ViewGroup和View之間進行傳遞,最終到達View;

View調用dispathTouchEvent()方法,然後在OnTouchEvent()進行處理事件;OnTouchEvent() 返回true,表示消耗此事件,不再向下傳遞;返回false,表示不消耗事件,交回上層處理。

7.介紹下實現一個自定義View的基本流程

①.自定義View的屬性 編寫attr.xml文件

②.在layout佈局文件中引用,同時引用命名空間

③.在View的構造方法中獲得我們自定義的屬性 ,在自定義控件中進行讀取(構造方法拿到attr.xml文件值)

④.重寫onMesure

⑥.重寫onDraw

8.Android中的動畫有哪些

逐幀動畫(Frame Animation)

加載一系列Drawable資源來創建動畫,簡單來說就是播放一系列的圖片來實現動畫效果,可以自定義每張圖片的持續時間

補間動畫(Tween Animation)

Tween可以對View對象實現一系列動畫效果,比如平移,縮放,旋轉,透明度等。但是它並不會改變View屬性的值,只是改變了View的繪製的位置,比如,一個按鈕在動畫過後,不在原來的位置,但是觸發點擊事件的仍然是原來的座標。

屬性動畫(Property Animation)

動畫的對象除了傳統的View對象,還可以是Object對象,動畫結束後,Object對象的屬性值被實實在在的改變了

9.ANR是什麼?怎樣避免和解決ANR

Application Not Responding,即應用無響應

出現的原因有三種:

a)KeyDispatchTimeout(5 seconds)主要類型按鍵或觸摸事件在特定時間內無響應

b)BroadcastTimeout(10 seconds)BoradcastReceiver在特定的時間內無法處理

c)ServiceTimeout(20 seconds)小概率類型Service在特定的時間內無法處理完成

避免ANR最核心的一點就是在主線程減少耗時操作。通常需要從那個以下幾個方案下手:

a)使用子線程處理耗時IO操作

b)降低子線程優先級,使用Thread或者HandlerThread時,調用Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND)設置優先級,否則仍然會降低程序響應,因爲默認Thread的優先級和主線程相同

c)使用Handler處理子線程結果,而不是使用Thread.wait()或者Thread.sleep()來阻塞主線程

d)Activity的onCreate和onResume回調中儘量避免耗時的代碼

e)BroadcastReceiver中onReceiver代碼也要儘量減少耗時操作,建議使用intentService處理。intentService是一個異步的,會自動停止的服務,很好解決了傳統的Service中處理完耗時操作忘記停止並銷燬Service的問題

10.如何優化ListView(偶爾會問)

①Item佈局,層級越少越好,使用hierarchyview工具查看優化。

②複用convertView

③使用ViewHolder

④item中有圖片時,異步加載

⑤快速滑動時,不加載圖片

⑥item中有圖片時,應對圖片進行適當壓縮

⑦實現數據的分頁加載

11.設備橫豎屏切換的時候,生面週期的變化(這個偶爾會問)

不設置Activity的android:configChanges時,切屏會重新調用各個生命週期,切橫屏時會執行一次,切豎屏時會執行兩次

設置Activity的android:configChanges=”orientation”時,切屏還是會重新調用各個生命週期,切橫、豎屏時只會執行一次

設置Activity的android:configChanges=”orientation|keyboardHidden”時,切屏不會重新調用各個生命週期,只會執行onConfigurationChanged方法

12.AndroidUI的適配

字體使用sp,使用dp,多使用match_parent,wrap_content,weight

圖片資源,不同圖片的的分辨率,放在相應的文件夾下可使用百分比代替。

13.RecyclerView和ListView的區別(這個是必問的)

RecyclerView可以完成ListView,GridView的效果,還可以完成瀑布流的效果。同時還可以設置列表的滾動方向(垂直或者水平);

RecyclerView中view的複用不需要開發者自己寫代碼,系統已經幫封裝完成了。

RecyclerView可以進行局部刷新。

RecyclerView提供了API來實現item的動畫效果。

在性能上:

如果需要頻繁的刷新數據,需要添加動畫,則RecyclerView有較大的優勢。

如果只是作爲列表展示,則兩者區別並不是很大。

14,Android異步消息處理機制(這個也會經常問到)

異步消息處理機制主要是用來解決子線程更新UI的問題

主要有四個部分:

①. Message (消息)中

在線程之間傳遞,可在內部攜帶少量信息,用於不同線程之間交換數據

可以使用what、arg1、arg2字段攜帶整型數據

obj字段攜帶Object對象

②. Handler (處理者)

主要用於發送和處理消息,sendMessage()用來發送消息,最終會回到handleMessage()進行處理

③. MessageQueue (消息隊列)

主要存放所有通過Handler發送的消息,它們會一直存在於隊列中等待被處理

每個線程只有一個MessageQueue

④. Looper (循環器)

調用loop()方法後,會不斷從MessageQueue 取出待處理的消息,然後傳遞到handleMessage進行處理

15.內存泄漏和內存溢出是什麼?一般怎麼處理內存泄漏?

(1)內存溢出(OOM)和內存泄露(對象無法被回收)的區別。

(2)引起內存泄露的原因

(3)內存泄露檢測工具 ------>LeakCanary

內存溢出 out of memory:是指程序在申請內存時,沒有足夠的內存空間供其使用,出現out of memory;比如申請了一個integer,但給它存了long才能存下的數,那就是內存溢出。內存溢出通俗的講就是內存不夠用。

內存泄露 memory leak:是指程序在申請內存後,無法釋放已申請的內存空間,一次內存泄露危害可以忽略,但內存泄露堆積後果很嚴重,無論多少內存,遲早會被佔光

內存泄露原因以及解決:

一、Handler 引起的內存泄漏。

解決:將Handler聲明爲靜態內部類,就不會持有外部類SecondActivity的引用,其生命週期就和外部類無關,

如果Handler裏面需要context的話,可以通過弱引用方式引用外部類

二、單例模式引起的內存泄漏

解決:Context是ApplicationContext,由於ApplicationContext的生命週期是和app一致的,不會導致內存泄漏

三、非靜態內部類創建靜態實例引起的內存泄漏。

解決:把內部類修改爲靜態的就可以避免內存泄漏了

四、非靜態匿名內部類引起的內存泄漏。

解決:將匿名內部類設置爲靜態的。

五、註冊/反註冊未成對使用引起的內存泄漏。

註冊廣播接受器、EventBus等,記得解綁。

六、資源對象沒有關閉引起的內存泄漏。

在這些資源不使用的時候,記得調用相應的類似close()、destroy()、recycler()、release()等方法釋放。

七、集合對象沒有及時清理引起的內存泄漏。

通常會把一些對象裝入到集合中,當不使用的時候一定要記得及時清理集合,讓相關對象不再被引用。

16.圖片加載框架有哪些?他們之間的區別是什麼?(這個也是必問的)

ImageLoader :

優點:

① 支持下載進度監聽;

② 可以在 View 滾動中暫停圖片加載;

③ 默認實現多種內存緩存算法這幾個圖片緩存都可以配置緩存算法,不過 ImageLoader 默認實現了較多緩存算法,如 Size 最大先刪除、使用最少先刪除、最近最少使用、先進先刪除、時間最長先刪除等;

④ 支持本地緩存文件名規則定義;

缺點:

缺點在於不支持GIF圖片加載, 緩存機制沒有和http的緩存很好的結合, 完全是自己的一套緩存機制

Picasso:

優點:

① 自帶統計監控功能,支持圖片緩存使用的監控,包括緩存命中率、已使用內存大小、節省的流量等。

② 支持優先級處理

③ 支持延遲到圖片尺寸計算完成加載

④ 支持飛行模式、併發線程數根據網絡類型而變,手機切換到飛行模式或網絡類型變換時會自動調整線程池最大併發數。

⑤ “無”本地緩存。Picasso 自己沒有實現本地緩存,而由okhttp 去實現,這樣的好處是可以通過請求 Response Header 中的 Cache-Control 及 Expired 控制圖片的過期時間。

缺點:

於不支持GIF,默認使用ARGB_8888格式緩存圖片,緩存體積大。

Glide:

優點:

① 圖片緩存->媒體緩存 ,支持 Gif、WebP、縮略圖。甚至是 Video。

② 支持優先級處理

③ 與 Activity/Fragment 生命週期一致,支持 trimMemory

④ 支持 okhttp、Volley。Glide 默認通過 UrlConnection 獲取數據,可以配合 okhttp 或是 Volley 使用。實際 ImageLoader、Picasso 也都支持 okhttp、Volley。

⑤ 內存友好,內存緩存更小圖片,圖片默認使用默認 RGB565 而不是 ARGB888

缺點:

清晰度差,但可以設置

Fresco:

優點:

① 圖片存儲在安卓系統的匿名共享內存, 而不是虛擬機的堆內存中,所以不會因爲圖片加載而導致oom, 同時也減少垃圾回收器頻繁調用回收Bitmap導致的界面卡頓,性能更高.

② 漸進式加載JPEG圖片, 支持圖片從模糊到清晰加載

③ 圖片可以以任意的中心點顯示在ImageView, 而不僅僅是圖片的中心.

④ JPEG圖片改變大小也是在native進行的, 不是在虛擬機的堆內存, 同樣減少OOM

⑤ 很好的支持GIF圖片的顯示

缺點:

框架較大, 影響Apk體積,使用較繁瑣

17.網絡框架有哪些?他們之間的區別是什麼?(這個也會問到)

Xutils

這個框架非常全面,可以進行網絡請求,可以進行圖片加載處理,可以數據儲存,還可以對view進行註解,使用這個框架非常方便,但是缺點也是非常明顯的,使用這個項目,會導致項目對這個框架依賴非常的嚴重,一旦這個框架出現問題,那麼對項目來說影響非常大的

OKhttp

Android開發中是可以直接使用現成的api進行網絡請求的。就是使用HttpClient,HttpUrlConnection進行操作。okhttp針對Java和Android程序,封裝的一個高性能的http請求庫,支持同步,異步,而且okhttp又封裝了線程池,封裝了數據轉換,封裝了參數的使用,錯誤處理等。API使用起來更加的方便。但是我們在項目中使用的時候仍然需要自己在做一層封裝,這樣才能使用的更加的順手。

Volley

Volley是Google官方出的一套小而巧的異步請求庫,該框架封裝的擴展性很強,支持HttpClient、HttpUrlConnection, 甚至支持OkHttp,而且Volley裏面也封裝了ImageLoader,所以如果你願意你甚至不需要使用圖片加載框架,不過這塊功能沒有一些專門的圖片加載框架強大,對於簡單的需求可以使用,稍複雜點的需求還是需要用到專門的圖片加載框架。Volley也有缺陷,比如不支持post大數據,所以不適合上傳文件。不過Volley設計的初衷本身也就是爲頻繁的、數據量小的網絡請求而生。

Retrofit

Retrofit是Square公司出品的默認基於OkHttp封裝的一套RESTful網絡請求框架,RESTful是目前流行的一套api設計的風格, 並不是標準。Retrofit的封裝可以說是很強大,裏面涉及到一堆的設計模式,可以通過註解直接配置請求,可以使用不同的http客戶端,雖然默認是用http ,可以使用不同Json Converter 來序列化數據,同時提供對RxJava的支持,使用Retrofit + OkHttp + RxJava + Dagger2 可以說是目前比較潮的一套框架,但是需要有比較高的門檻。

Volley VS OkHttp

Volley的優勢在於封裝的更好,而使用OkHttp你需要有足夠的能力再進行一次封裝。而OkHttp的優勢在於性能更高,因爲 OkHttp基於NIO和Okio ,所以性能上要比 Volley更快。IO 和 NIO這兩個都是Java中的概念,如果我從硬盤讀取數據,第一種方式就是程序一直等,數據讀完後才能繼續操作這種是最簡單的也叫阻塞式IO,還有一種是你讀你的,程序接着往下執行,等數據處理完你再來通知我,然後再處理回調。而第二種就是 NIO 的方式,非阻塞式, 所以NIO當然要比IO的性能要好了,而 Okio是 Square 公司基於IO和NIO基礎上做的一個更簡單、高效處理數據流的一個庫。理論上如果Volley和OkHttp對比的話,更傾向於使用 Volley,因爲Volley內部同樣支持使用OkHttp,這點OkHttp的性能優勢就沒了, 而且 Volley 本身封裝的也更易用,擴展性更好些。

OkHttp VS Retrofit

毫無疑問,Retrofit 默認是基於 OkHttp 而做的封裝,這點來說沒有可比性,肯定首選 Retrofit。

Volley VS Retrofit

這兩個庫都做了不錯的封裝,但Retrofit解耦的更徹底,尤其Retrofit2.0出來,Jake對之前1.0設計不合理的地方做了大量重構, 職責更細分,而且Retrofit默認使用OkHttp,性能上也要比Volley佔優勢,再有如果你的項目如果採用了RxJava ,那更該使用 Retrofit 。所以這兩個庫相比,Retrofit更有優勢,在能掌握兩個框架的前提下該優先使用 Retrofit。但是Retrofit門檻要比Volley稍高些,要理解他的原理,各種用法,想徹底搞明白還是需要花些功夫的,如果你對它一知半解,那還是建議在商業項目使用Volley吧。

18.熟悉哪些設計模式?

按照自己的實際情況回答,當然是越多越好。比如我自己也就熟悉個單例模式。

19.三級緩存(這個偶爾會問)

網絡加載,不優先加載,速度慢,浪費流量

本地緩存,次優先加載,速度快

內存緩存,優先加載,速度最快

首次加載Android App時,肯定要通過網絡交互來獲取圖片,之後我們可以將圖片保存至本地SD卡和內存中,之後運行APP時,優先訪問內存中的圖片緩存,若內存中沒有,則加載本地SD卡中圖片,最後選擇訪問網絡

20.Android與服務器交互的方式中的對稱加密和非對稱加密是什麼?

對稱加密,就是加密和解密數據都是使用同一個key,這方面的算法有DES。

非對稱加密,加密和解密是使用不同的key。發送數據之前要先和服務端約定生成公鑰和私鑰,使用公鑰加密的數據可以用私鑰解密,反之。這方面的算法有RSA。ssh 和 ssl都是典型的非對稱加密。

往期文章

十面阿里,七面頭條

在百人團隊參與遊戲研發體驗

除了敲代碼,你還有什麼副業嗎?

面試官:你分析過線程池源碼嗎?

淺談final、finally、finalize有什麼不同?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章