編輯:關於Android編程
自上周怒辭職以後,就開始苦逼的各種面試生涯,生活完全靠私活來接濟,時有時沒有,真難,還能快樂的玩耍嗎,最多一天面試了5家,哎感覺都是不急招人,各種等待通知,好不容易等來一家,還克扣了薪資,從我要的12k到他們給8k,感覺累覺不愛。
面試都是基本過了二面的,大到騰訊,阿裡,百度,網易,小到15人的創業公司我都去了,難得今天休息一下,總結下面試經驗,以便下次面試用到。技術題目我就不說了,這是基礎,不會的還是把基礎看下吧。後面的題目都是讓人蛋疼的機制問題。
線程就是程序執行流中最小單元,是系統獨立調度的基本單位,線程不具有任何系統資源,這裡需要特別注意,
就象程序一樣,線程有生命周期:它們啟動、執行,然後完成。一個程序或進程也許包含多個線程,而這些線程看來互相單獨地執行。
線程是通過實例化Thread對象或實例化繼承Thread的對象來創建的,但在對新的Thread對象調用start()方法之前,這個線程並沒有開始執行。當線程運行到其run()方法的末尾或拋出未經處理的異常時,它們就結束了。
sleep()方法可以用於等待一段特定時間;而join()方法可能用於等到另一個線程完成。
線程的一些基本方法:
isAlive():判斷線程是否還"活"著
getPriority():獲得線程的優先級數值
setPriority():設置線程的優先級數值
Thread.sleep():將當前線程睡眠指定毫秒數
join():調用某線程的該方法,將當前線程與該線程"合並",即等待該線程結束,再恢復當前線程的運行
yield():讓出cpu,當前線程進入就緒隊列等待調度
wait():當前線程進入對象的wait pool
notify()/notifyAll():喚醒對象的wait pool中的一個/所有等待線程
特別注意sleep和wait的區別:
Wait是Object類的方法,范圍是使該Object實例所處的線程。
Sleep()是Thread類專屬的靜態方法,針對一個特定的線程。
Wait方法使實體所處線程暫停執行,從而使對象進入等待狀態,直到被notify方法通知或者wait的等待的時間到。Sleep方法使持有的線程暫停運行,從而使線程進入休眠狀態,直到用interrupt方法來打斷他的休眠或者sleep的休眠的時間到。
線程和進程的區別:
(1)地址空間:進程內的一個執行單元;進程至少有一個線程;它們共享進程的地址空間;而進程有自己獨立的地址空間;
(2)資源擁有:進程是資源分配和擁有的單位,同一個進程內的線程共享進程的資源
(3)線程是處理器調度的基本單位,但進程不是.
多線程
許多線程在執行中必須考慮與其他線程之間共享數據或協調執行狀態。這就需要同步機制。在Java中每個對象都有一把鎖與之對應。synchronized語句計算一個對象引用,試圖對該對象完成鎖操作, 並且在完成鎖操作前停止處理。當鎖操作完成synchronized語句體得到執行。當語句體執行完畢(無論正常或異常),解鎖操作自動完成。作為面向對象的語言,synchronized經常與方法連用。一種比較好的辦法是,如果某個變量由一個線程賦值並由別的線程引用或賦值,那麼所有對該變量的訪問都必須在某個synchromized語句或synchronized方法內。
1、MessageQueue:是一種數據結構,見名知義,就是一個消息隊列,存放消息的地方。每一個線程最多只可以擁有一個MessageQueue數據結構。創建一個線程的時候,並不會自動創建其MessageQueue。通常使用一個Looper對象對該線程的MessageQueue進行管理。主線程創建時,會創建一個默認的Looper對象,而Looper對象的創建,將自動創建一個Message Queue。其他非主線程,不會自動創建Looper,要需要的時候,通過調用prepare函數來實現。
2、Message:消息對象,Message Queue中的存放的對象。一個Message Queue中包含多個Message。Message實例對象的取得,通常使用Message類裡的靜態方法obtain(),該方法有多個重載版本可供選擇;它的創建並不一定是直接創建一個新的實例,而是先從Message Pool(消息池)中看有沒有可用的Message實例,存在則直接取出返回這個實例。如果Message Pool中沒有可用的Message實例,則才用給定的參數創建一個Message對象。調用removeMessages()時,將Message從Message Queue中刪除,同時放入到Message Pool中。除了上面這種方式,也可以通過Handler對象的obtainMessage()獲取一個Message實例。
3、Looper:
是MessageQueue的管理者。每一個MessageQueue都不能脫離Looper而存在,Looper對象的創建是通過prepare函數來實現的。同時每一個Looper對象和一個線程關聯。通過調用Looper.myLooper()可以獲得當前線程的Looper對象創建一個Looper對象時,會同時創建一個MessageQueue對象。除了主線程有默認的Looper,其他線程默認是沒有MessageQueue對象的,所以,不能接受Message。如需要接受,自己定義一個Looper對象(通過prepare函數),這樣該線程就有了自己的Looper對象和MessageQueue數據結構了。Looper從MessageQueue中取出Message然後,交由Handler的handleMessage進行處理。處理完成後,調用Message.recycle()將其放入Message Pool中。
4、Handler:
消息的處理者,handler負責將需要傳遞的信息封裝成Message,通過調用handler對象的obtainMessage()來實現;將消息傳遞給Looper,這是通過handler對象的sendMessage()來實現的。繼而由Looper將Message放入MessageQueue中。當Looper對象看到MessageQueue中含有Message,就將其廣播出去。該handler對象收到該消息後,調用相應的handler對象的handleMessage()方法對其進行處理。
這個比較簡單一些,了解了上面的內容就知道子線程發送message,通過handler的handleMessage方法去獲取message然後更新UI。
Oom是指內存溢出,一般情況是圖片過大造成的。解決方案:
(1)緩存圖像到內存,采用軟引用緩存到內存,而不是在每次使用的時候都從新加載到內存;
(2)調整圖像大小,手機屏幕尺寸有限,分配給圖像的顯示區域本身就更小,有時圖像大小可以做適當調整;
(3)采用低內存占用量的編碼方式,比如Bitmap.Config.ARGB_4444比Bitmap.Config.ARGB_8888更省內存;
(4)及時回收圖像,如果引用了大量Bitmap對象,而應用又不需要同時顯示所有圖片,可以將暫時用不到的Bitmap對象及時回收掉;
(5)自定義堆內存分配大小,優化Dalvik虛擬機的堆內存分配;
Garbage Collection簡稱為GC,是垃圾回收的意思、內存處理器是編程人員容易出現問題的地方,忘記或者錯誤的內存回收會導致程序或系統的不穩定甚至崩潰。Java語言提供的GC功能可以自動的檢測對象是否超過作用域,從而達到自動回收內存的目的,java語言沒有提供釋放已分配內存的顯示操作方法,資源回收工作全部交由GC來完成,程序員不能精確的控制垃圾回收的時機。
GC在實現垃圾回收時的基本原理:
Java的內存管理實際就是對象的管理,其中包括對像的分配和釋放。對於程序員來說,分配對象使用new關鍵字,釋放對象時只是將對象賦值為null,讓程序員不能夠再訪問到這個對象,該對象被稱為“不可達”。GC將負責回收所有“不可達”對象的內存空間。
對於GC來說,當程序員創建對象時,GC就開始監控這個對象地址、大小以及使用情況。通常GC采用有向圖的方式記錄並管理堆中的所有對象,通過這種方式確定哪些對象是“可達”的,哪些對象是“不可達”的。當GC確定一些對象為“不可達時”GC就有責任回收這些內存空間,但為了GC能夠在不同的平台上實現,java規范對GC的很多行為都沒有進行嚴格的規定。例如對於采用什麼類型的回收算法、什麼時候進行回收等重要問題都沒有明確的規定,因此不同的JVM實現著不同的的實現算法,這也給JAVA程序員的開發帶來了很多不確定性。
根據GC的工作原理,可以通過一些技巧和方式讓GC運行更快,高效而又合理。編程建議如下:
1、盡早釋放無用對象的引用,特別注意一些復雜對象,如數組,隊列等。對於此類對象,GC回收它們的效率一般較低,如果程序允許,應盡早將不用的引用對象賦為null,這樣可以加速GC的工作。
2、盡量少用finalize函數。finalize是java提供給程序員用來釋放對象或資源的函數,但是它會加大GC的工作量,因此盡量少采用finalize函數回收資源。
Android系統中大量使用了基於C/S模式的通信方式。諸如短信操作,電話操作,視頻音頻捕獲,傳感器等都以服務(Service)的形式提供,並由相應的Server負責管理,應用程序作為Client只需要與這些Server建立連接並發送請求便能使用這些服務。因此,開發者完全不必關心Service的實現細節,直接與Server建立連接然後使用其提供的接口即可。Client和Server一般是運行在不同的進程中的,這就涉及到進程間通信(IPC,Inter-ProcessCommunication)。為了保證系統安全性,提高通信效率以及提供對C/S模式的支持,Android采用了一種基於共享內存的IPC機制——Binder機制。
具體的實現方法就是AIDL,這屬於技術方面了,不懂的可以百度。
http重點是url和httpclient。
狀態碼為1這一類型的狀態碼,代表請求已被接受,需要繼續處理。這類響應是臨時響應,只包含狀態行和某些可選的響應頭信息,並以空行結束。
狀態碼為2這一類型的狀態碼,代表請求已成功被服務器接收、理解、並接受。
狀態碼為3這類狀態碼代表需要客戶端采取進一步的操作才能完成請求。通常,這些狀態碼用來重定向,後續的請求地址(重定向目標)在本次響應的 Location 域中指明。
狀態碼為4為錯誤碼
狀態碼為5服務器錯誤
TCP重點就是sokect。
自定義view重要的是復寫ondraw方法。
View是繼承viewgroup的,所以復寫viewgroup能實現我們想要一切東西,viewgroup主要的方法:
Onlayout()方法負責把該view放在參數指定位置。
onMeasure()方法不但可以為ViewGroup指定大小,還可以通過遍歷為每一個子View指定大小,在自定義ViewGroup中添加上面代碼為ViewGroup中的每一個子View分配了顯示的寬高。
onDraw重繪view
Android:使用AppCompatAutoCompleteTextView:我們先看看實現的效果吧,也就是我們俗話說的自動提示功能。這裡我實現了點擊AppCompat
NumberPickerViewanother NumberPicker with more flexible attributes on Android platfor
在Android開發當中,在界面上彈出一個Dialog對話框使我們經常需要做的,本篇隨筆將詳細的講解Dialog對話框這個概念,包括定義不同樣式的對話框。一、Dialog
最近做的項目中需要實現斷點下載,即用戶一次下載可以分多次進行,下載過程可以中斷,在目前大多數的帶離線緩存的軟件都是需要實現這一功能。本文闡述了通過sqlite3簡單實現了