菜鳥面試修行記

面試問題總結:
1、service 啓動方式
分爲兩種:
一、Context.startService()方式啓動 
Context.startService()方式的生命週期: 啓動時,startService –> onCreate() –> onStart()停止時,stopService –> onDestroy()如果調用者直接退出而沒有停止Service,則Service 會一直在後臺運行 Context.startService()方法啓動服務,在服務未被創建時,系統會先調用服務的onCreate()方法,接着調用onStart()方法。如果調用startService()方法前服務已經被創建,多次調用startService()方法並不會導致多次創建服務,但會導致多次調用onStart()方法。採用startService()方法啓動的服務,只能調用Context.stopService()方法結束服務,服務結束時會調用onDestroy()方法附代碼
二、Context.bindService()方式啓動

Context.bindService()方式的生命週期: 綁定時,bindService -> onCreate() –> onBind()調用者退出了,即解綁定時,Srevice就會unbindService –>onUnbind() –> onDestory()Context.bindService()方式啓動 Service的方法:綁定Service需要三個參數:bindService(intent, conn, Service.BIND_AUTO_CREATE);第一個:Intent對象,第二個:ServiceConnection對象,創建該對象要實現它的onServiceConnected()和 onServiceDisconnected()來判斷連接成功或者是斷開連接第三個:如何創建Service,一般指定綁定的時候自動創建


2、Bitmap存儲位置
在Android3.0之前,Bitmap的內存分配分爲兩部分,一部分是分配在Dalvik的VM堆中,而像素數據的內存是分配在Native堆中,而到了Android3.0之後,Bitmap的內存則已經全部分配在VM堆上,這兩種分配方式的區別在於,Native堆的內存不受Dalvik虛擬機的管理,我們想要釋放Bitmap的內存,必須手動調用Recycle方法,而到了Android 3.0之後的平臺,我們就可以將Bitmap的內存完全放心的交給虛擬機管理了,我們只需要保證Bitmap對象遵守虛擬機的GC Root Tracing的回收規則即可。


3、多線程&多線程間通信

多線程:

Android提供了四種常用的操作多線程的方式,分別是:
1. Handler+Thread
2. AsyncTask
3. ThreadPoolExecutor
4. IntentService


 Handler+Thread:

Android主線程包含一個消息隊列(MessageQueue),該消息隊列裏面可以存入一系列的Message或Runnable對象。通過一個Handler你可以往這個消息隊列發送Message或者Runnable對象,並且處理這些對象。每次你新創建一個Handle對象,它會綁定於創建它的線程(也就是UI線程)以及該線程的消息隊列,從這時起,這個handler就會開始把Message或Runnable對象傳遞到消息隊列中,並在它們出隊列的時候執行它們。

Handler可以把一個Message對象或者Runnable對象壓入到消息隊列中,進而在UI線程中獲取Message或者執行Runnable對象,Handler把壓入消息隊列有兩類方式,Post和sendMessage.
Post方式:
Post允許把一個Runnable對象入隊到消息隊列中。它的方法有:
post(Runnable)/postAtTime(Runnable,long)

postDelayed(Runnable,long)
對於Handler的Post方式來說,它會傳遞一個Runnable對象到消息隊列中,在這個Runnable對象中,重寫run()方法。一般在這個run()方法中寫入需要在UI線程上的操作。


sendMessage:
sendMessage允許把一個包含消息數據的Message對象壓入到消息隊列中。它的方法有:

sendEmptyMessage(int)

sendMessage(Message)

sendMessageAtTime(Message,long)

sendMessageDelayed(Message,long)


Handler如果使用sendMessage的方式把消息入隊到消息隊列中,需要傳遞一個Message對象,而在Handler中,需要重寫handleMessage()方法,用於獲取工作線程傳遞過來的消息,此方法運行在UI線程上。Message是一個final類,所以不可被繼承。


優缺點
1. Handler用法簡單明瞭,可以將多個異步任務更新UI的代碼放在一起,清晰明瞭
2. 處理單個異步任務代碼略顯多
適用範圍
1. 多個異步任務的更新UI

AsyncTask:
AsyncTask是android提供的輕量級的異步類,可以直接繼承AsyncTask,在類中實現異步操作,並提供接口反饋當前異步執行的程度(可以通過接口實現UI進度更新),最後反饋執行的結果給UI主線程。
AsyncTask通過一個阻塞隊列BlockingQuery<Runnable>存儲待執行的任務,利用靜態線程池THREAD_POOL_EXECUTOR提供一定數量的線程,默認128個。在Android 3.0以前,默認採取的是並行任務執行器,3.0以後改成了默認採用串行任務執行器,通過靜態串行任務執行器SERIAL_EXECUTOR控制任務串行執行,循環取出任務交給THREAD_POOL_EXECUTOR中的線程執行,執行完一個,再執行下一個。

優缺點
1. 處理單個異步任務簡單,可以獲取到異步任務的進度
2. 可以通過cancel方法取消還沒執行完的AsyncTask
3. 處理多個異步任務代碼顯得較多
適用範圍
1. 單個異步任務的處理

ThreadPoolExecutor:
ThreadPoolExecutor提供了一組線程池,可以管理多個線程並行執行。這樣一方面減少了每個並行任務獨自建立線程的開銷,另一方面可以管理多個併發線程的公共資源,從而提高了多線程的效率。所以ThreadPoolExecutor比較適合一組任務的執行。Executors利用工廠模式對ThreadPoolExecutor進行了封裝,使用起來更加方便。

Executors提供了四種創建ExecutorService的方法,他們的使用場景如下:

1. Executors.newFixedThreadPool()
   創建一個定長的線程池,每提交一個任務就創建一個線程,直到達到池的最大長度,這時線程池會保持長度不再變化
2. Executors.newCachedThreadPool()
   創建一個可緩存的線程池,如果當前線程池的長度超過了處理的需要時,它可以靈活的回收空閒的線程,當需要增加時,
    它可以靈活的添加新的線程,而不會對池的長度作任何限制
3. Executors.newScheduledThreadPool()
   創建一個定長的線程池,而且支持定時的以及週期性的任務執行,類似於Timer
4. Executors.newSingleThreadExecutor()
   創建一個單線程化的executor,它只創建唯一的worker線程來執行任務
適用範圍
1. 批處理任務


IntentService:
IntentService繼承自Service,是一個經過包裝的輕量級的Service,用來接收並處理通過Intent傳遞的異步請求。客戶端通過調用startService(Intent)啓動一個IntentService,利用一個work線程依次處理順序過來的請求,處理完成後自動結束Service。

特點
1. 一個可以處理異步任務的簡單Service

線程間通信:

在Android中提供了兩種線程間的通信方式:一種是AsyncTask機制(只能用於時間短的操作,最多幾秒就應該結束),另一種是Handler機制


4、進程&進程間通信
在Android SDK中提供了4種用於跨進程通訊的方式。這4種方式正好對應於android系統中4種應用程序組件:Activity、Content Provider、Broadcast和Service。其中Activity可以跨進程調用其他應用程序的Activity;Content Provider可以跨進程訪問其他應用程序中的數據(以Cursor對象形式返回),當然,也可以對其他應用程序的數據進行增、刪、改操作;Broadcast可以向android系統中所有應用程序發送廣播,而需要跨進程通訊的應用程序可以監聽這些廣播;Service和Content Provider類似,也可以訪問其他應用程序中的數據,但不同的是,Content Provider返回的是Cursor對象,而Service返回的是Java對象,這種可以跨進程通訊的服務叫AIDL服務。


5、xml解析/json解析
6、Java設計者模式
7、搭框架
8、Http方法
根據HTTP標準,HTTP請求可以使用多種請求方法。
HTTP1.0定義了三種請求方法: GET, POST 和 HEAD方法。
HTTP1.1新增了五種請求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。
方法 描述
GET    求指定的頁面信息,並返回實體主體。
HEAD 類似於get請求,只不過返回的響應中沒有具體的內容,用於獲取報頭
POST 向指定資源提交數據進行處理請求(例如提交表單或者上傳文件)。數據被包含在請求體中。POST請求可能會導致新的資源的建立和/或已有資源的修改。
PUT    從客戶端向服務器傳送的數據取代指定的文檔的內容。
DELETE 請求服務器刪除指定的頁面。
CONNECT HTTP/1.1協議中預留給能夠將連接改爲管道方式的代理服務器。
OPTIONS 允許客戶端查看服務器的性能。
TRACE 回顯服務器收到的請求,主要用於測試或診斷。
9、http請求和返回格式
10、get方法和post方法差別
Http定義了與服務器交互的不同方法,最基本的方法有4種,分別是GET,POST,PUT,DELETE。URL全稱是資源描述符,我們可以這樣認爲:一個URL地址,它用於描述一個網絡上的資源,而HTTP中的GET,POST,PUT,DELETE就對應着對這個資源的查,改,增,刪4個操作。到這裏,大家應該有個大概的瞭解了,GET一般用於獲取/查詢資源信息,而POST一般用於更新資源信息。
11、dalvik進程,Linux進程,線程區別
Dalvik是Google公司自己設計用於Android平臺的Java虛擬機,每一個Dalvik 應用作爲一個獨立的Linux 進程執行。獨立的進程可以防止在虛擬機崩潰的時候所有程序都被關閉。
12、安卓動畫哪兩種以及差別
補間動畫和幀動畫。所謂補間動畫,是指通過指定View的初末狀態和變化時間、方式,對View的內容完成一系列的圖形變換來實現動畫效果。主要包括四種效果:Alpha、Scale、Translate和Rotate。幀動畫就是Frame動畫,即指定每一幀的內容和停留時間,然後播放動畫。
13、網絡層協議有哪些,OSI 七層協議
14、xml解析方式有哪些,以及優缺點
15、Android最新佈局有哪些
16、Android 界面適配
17、MVC,MVP 模式
18、HashMap 是有序還是無序,有序的map是什麼,List基類是什麼
HashMap無須,
LinkedHashMap有序,輸出時保持數據存入時的順序
19、http協議,在發送請求的時候出現丟包情況,怎樣處理,有沒有攔截操作
20、Android加載網絡圖片的時候怎樣防止內存溢出(加載圖片的過程)
21、即時通信 (極光推送)


22、自定義 view 需要重寫方法或者說 Android layout 展示出來需要走哪些方法
一.自定義View的屬性
二.在View的構造方法中獲得我們自定義的屬性
三.[ 3、重寫onMesure ]
四.重寫onDraw


23、Android 數據存儲有哪些方式
一 使用SharedPreferences存儲數據
二 文件存儲數據      
三 SQLite數據庫存儲數據
四 使用ContentProvider存儲數據
五 網絡存儲數據
詳情看:
http://www.cnblogs.com/ITtangtang/p/3920916.html#type5

24、如何查詢數據庫中某字段包含 *** 所有數據


25、如何解決 message 複用問題(handler)
Handler在通過Message.obtain()獲取消息時,如果有消息,就複用,沒有的話,就new一條新消息


26、如何建立TCP/UDP連接
Java使用DatagramSocket代表UDP協議的Socket,DatagramSocket本身只是碼頭,不維護狀態,不能產生IO流,它的唯一作用就是接收和發送數據報,Java使用DatagramPacket來代表數據報,DatagramSocket接收和發送的數據都是通過DatagramPacket對象完成的。
使用UDP方式android端和服務器端接收可以看出,其實android端和服務器端的發送和接收大庭相徑,只要端口號正確了,相互通信就沒有問題,TCP使用的是流的方式發送,UDP是以包的形式發送。


27、想要listview 展示不同item樣式
一 getViewTypeCount()比較簡單,你的item有多少種可能的佈局就返回多少;
二 而對於getItemViewType(int position),你就根據你的需求定義多少個常量,簡單如下,一個表示收到文本消息,一個表示發出文本消息,然後在方法裏面根據你的消息判斷是收到的還是發出的,對應return該常數就行了。


28、Fragment 切換以及再展示怎麼處理
     FragmentTransaction transaction = fragmentManager.beginTransaction();
     transaction.replace(R.id.content, fg);
     transaction.commit();
 
另外:  
/**
 * 切換Fragment
 *
 * @param fromFragment:需要隱藏的Fragment
 * @param toFragment:需要顯示的Fragment
 */
private void switchFragment(Fragment fromFragment, Fragment toFragment) {
    if (fromFragment != toFragment) {
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        if (!toFragment.isAdded()) {
            fragmentTransaction.hide(fromFragment).add(R.id.framelayout_content_activity_home, toFragment).commit();
        } else {
            fragmentTransaction.hide(fromFragment).show(toFragment).commit();
        }
    }
}
29、單例模式怎樣防止new
自定義一個private 構造方法


30、service 與 intentservice 區別


31、Android 6.0 與 Android 7.0 有什麼不同,對於開發人員有什麼需要注意的地方


32、Android 事件分發機制


33、Activity四種啓動模式


34、Activity 與 Fragment 之間數據如何傳遞


35、Java 四種引用模式



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