Java基礎
Q: 容器類, ArrayList和Vector的主要區(qū)別HashMap原理
1. List 接口支持通過索引的方法來訪問元素:ArrayList 隨機訪問快改慢;LinkedList改快隨機訪問慢;Vector實現(xiàn)了同步,因而比ArrayList慢
- LinkedList使用雙向鏈表實現(xiàn)LinkedList提供額外的get,remove,insert方法在LinkedList的首部或尾部。這些操作使LinkedList可被用作堆棧(stack),隊列(queue)或雙向隊列(deque)。
3. ArrayList沒有定義增長算法,當需要插入大量元素是,可調(diào)用ensureCapacity方法提高添加效率
4. Vector類似與ArrayList,但是是同步的,多線程安全(另外一點區(qū)別是ArrayList擴容時默認增長一半,Vector增長一倍)。無論是單線程還是多線程,Vector都比ArrayList慢
5. Stack繼承自Vector,實現(xiàn)一個后進先出的堆棧
TreeSet, HashSet, LinkedHashSet(HashSet,TreeSet不是線程安全的)
- TreeSet是SortedSet接口的唯一實現(xiàn)類,TreeSet可以確保集合元素處于排序狀態(tài),效率很高,可提高程序的效率;TreeSet通過compareTo或者compare排序,因而只要值相等即使equals不等(不同對象)也不能加到集合中(fails to obey Set interface)
2. HashSet,效率很高,和TreeSet不同的是通過比較對象的equals區(qū)分不同對象,這樣不同的對象可以不被重復的加入到集合中。hashCode()函數(shù)不好確定,對象默認的hashCode函數(shù)試對象的內(nèi)存地址值,hashCode函數(shù)的好壞是HashSet性能的關鍵。
3. LinkedHashSet,和HashSet相同,同樣是根據(jù)元素的hashCode值來決定元素的存儲位置,但是它同時使用鏈表維護元素的次序。LinkedHashSet在迭代訪問Set中的全部元素時,性能比HashSet好,但是插入時性能稍微遜色于HashSet。
- Set可以插入null,最多一個null
http://www.cnblogs.com/wishyouhappy/p/3669198.html
http://blog.csdn.net/softwave/article/details/4166598
Q:string/stringbuilder/stringbuffer
都是 final 類, 都不允許被繼承;
String 長度是不可變的, StringBuffer、StringBuilder 長度是可變的;
StringBuffer 是線程安全的, StringBuilder 不是線程安全的。
Q:線程synchronized、lock
synchronized關鍵字是用來控制線程同步的,就是在多線程的環(huán)境下,控制synchronized代碼段不被多個線程同時執(zhí)行。synchronized既可以加在一段代碼上,也可以加在方法上。
用sychronized修飾的方法或者語句塊在代碼執(zhí)行完之后鎖自動釋放,而用Lock需要我們手動釋放鎖,所以為了保證鎖最終被釋放(發(fā)生異常情況),要把互斥區(qū)放在try內(nèi),釋放鎖放在finally內(nèi)。
http://blog.csdn.net/ghsau/article/details/7461369
Q:thread、runnable
在程序開發(fā)中只要是多線程肯定永遠以實現(xiàn)Runnable接口為主,因為實現(xiàn)Runnable接口相比繼承Thread類有如下好處:
避免點繼承的局限,一個類可以繼承多個接口。
適合于資源的共享
Q:匿名內(nèi)部類使用規(guī)范
匿名內(nèi)部類我們必須要繼承一個父類或者實現(xiàn)一個接口,當然也僅能只繼承一個父類或者實現(xiàn)一個接口。同時它也是沒有class關鍵字,這是因為匿名內(nèi)部類是直接使用new來生成一個對象的引用。當然這個引用是隱式的。
對于匿名內(nèi)部類的使用它是存在一個缺陷的,就是它僅能被使用一次,創(chuàng)建匿名內(nèi)部類時它會立即創(chuàng)建一個該類的實例,該類的定義會立即消失,所以匿名內(nèi)部類是不能夠被重復使用。對于上面的實例,如果我們需要對test()方法里面內(nèi)部類進行多次使用,建議重新定義類,而不是使用匿名內(nèi)部類。
在使用匿名內(nèi)部類的過程中,我們需要注意如下幾點:
1、使用匿名內(nèi)部類時,我們必須是繼承一個類或者實現(xiàn)一個接口,但是兩者不可兼得,同時也只能繼承一個類或者實現(xiàn)一個接口。
2、匿名內(nèi)部類中是不能定義構造函數(shù)的。
3、匿名內(nèi)部類中不能存在任何的靜態(tài)成員變量和靜態(tài)方法。
4、匿名內(nèi)部類為局部內(nèi)部類,所以局部內(nèi)部類的所有限制同樣對匿名內(nèi)部類生效。
5、匿名內(nèi)部類不能是抽象的,它必須要實現(xiàn)繼承的類或者實現(xiàn)的接口的所有抽象方法。
簡單理解就是,拷貝引用,為了避免引用值發(fā)生改變,例如被外部類的方法修改等,而導致內(nèi)部類得到的值不一致,于是用final來讓該引用不可改變。
故如果定義了一個匿名內(nèi)部類,并且希望它使用一個其外部定義的參數(shù),那么編譯器會要求該參數(shù)引用是final的。
http://www.cnblogs.com/chenssy/p/3390871.html
Q:異常try-catch機制
java 的異常處理中,
在不拋出異常的情況下,程序執(zhí)行完 try 里面的代碼塊之后,該方法并不會立即結束,而是繼續(xù)試圖去尋找該方法有沒有 finally 的代碼塊,
如果沒有 finally 代碼塊,整個方法在執(zhí)行完 try 代碼塊后返回相應的值來結束整個方法;
如果有 finally 代碼塊,此時程序執(zhí)行到 try 代碼塊里的 return 語句之時并不會立即執(zhí)行 return,而是先去執(zhí)行 finally 代碼塊里的代碼,
若 finally 代碼塊里沒有 return 或沒有能夠終止程序的代碼,程序將在執(zhí)行完 finally 代碼塊代碼之后再返回 try 代碼塊執(zhí)行 return 語句來結束整個方法;
若 finally 代碼塊里有 return 或含有能夠終止程序的代碼,方法將在執(zhí)行完 finally 之后被結束,不再跳回 try 代碼塊執(zhí)行 return。
在拋出異常的情況下,原理也是和上面的一樣的,你把上面說到的 try 換成 catch 去理解就 OK 了
http://www.blogjava.net/fancydeepin/archive/2012/07/08/382508.html
Q:泛型
如果我們只寫一個排序方法,就能夠對整形數(shù)組、字符串數(shù)組甚至支持排序的任何類型的數(shù)組進行排序,這該多好啊。
Java泛型方法和泛型類支持程序員使用一個方法指定一組相關方法,或者使用一個類指定一組相關的類型。
Java泛型(generics)是JDK 5中引入的一個新特性,泛型提供了編譯時類型安全檢測機制,該機制允許程序員在編譯時檢測到非法的類型。
使用Java泛型的概念,我們可以寫一個泛型方法來對一個對象數(shù)組排序。然后,調(diào)用該泛型方法來對整型數(shù)組、浮點數(shù)數(shù)組、字符串數(shù)組等進行排序。
http://www.w3cschool.cc/java/java-generics.html
Q:線程池
newCachedThreadPool創(chuàng)建一個可緩存線程池,如果線程池長度超過處理需要,可靈活回收空閑線程,若無可回收,則新建線程。
newFixedThreadPool 創(chuàng)建一個定長線程池,可控制線程最大并發(fā)數(shù),超出的線程會在隊列中等待。
newScheduledThreadPool 創(chuàng)建一個定長線程池,支持定時及周期性任務執(zhí)行。
newSingleThreadExecutor 創(chuàng)建一個單線程化的線程池,它只會用唯一的工作線程來執(zhí)行任務,保證所有任務按照指定順序(FIFO, LIFO, 優(yōu)先級)執(zhí)行。
http://blog.csdn.net/mazhimazh/article/details/19243889
Q:引用機制(WeakReference, SoftReference, ReferenceQueue理解, WeakHashMap的原理)
強引用(StrongReference)
強引用是使用最普遍的引用。如果一個對象具有強引用,那垃圾回收器絕不會回收它。
軟引用(SoftReference)
如果一個對象只具有軟引用,則內(nèi)存空間足夠,垃圾回收器就不會回收它;如果內(nèi)存空間不足了,就會回收這些對象的內(nèi)存。只要垃圾回收器沒有回收它,該對象就可以被程序使用。軟引用可用來實現(xiàn)內(nèi)存敏感的高速緩存。
弱引用(WeakReference)
弱引用與軟引用的區(qū)別在于:只具有弱引用的對象擁有更短暫的生命周期。在垃圾回收器線程掃描它所管轄的內(nèi)存區(qū)域的過程中,一旦發(fā)現(xiàn)了只具有弱引用的對象,不管當前內(nèi)存空間足夠與否,都會回收它的內(nèi)存。不過,由于垃圾回收器是一個優(yōu)先級很低的線程,因此不一定會很快發(fā)現(xiàn)那些只具有弱引用的對象。
虛引用(PhantomReference)
“虛引用”顧名思義,就是形同虛設,與其他幾種引用都不同,虛引用并不會決定對象的生命周期。如果一個對象僅持有虛引用,那么它就和沒有任何引用一樣,在任何時候都可能被垃圾回收器回收。
虛引用主要用來跟蹤對象被垃圾回收器回收的活動。虛引用與軟引用和弱引用的一個區(qū)別在于:虛引用必須和引用隊列 (ReferenceQueue)聯(lián)合使用。當垃圾回收器準備回收一個對象時,如果發(fā)現(xiàn)它還有虛引用,就會在回收對象的內(nèi)存之前,把這個虛引用加入到與之 關聯(lián)的引用隊列中。
Q:exception,throwable,error
throwable 類是 Java 語言中所有錯誤或異常的超類。它的兩個子類是Error和Exception;
Error 是 Throwable 的子類,用于指示合理的應用程序不應該試圖捕獲的嚴重問題。大多數(shù)這樣的錯誤都是異常條件。雖然 ThreadDeath 錯誤是一個“正規(guī)”的條件,但它也是 Error 的子類,因為大多數(shù)應用程序都不應該試圖捕獲它。在執(zhí)行該方法期間,無需在其 throws 子句中聲明可能拋出但是未能捕獲的 Error 的任何子類,因為這些錯誤可能是再也不會發(fā)生的異常條件。 Exception 類及其子類是 Throwable 的一種形式,它指出了合理的應用程序想要捕獲的條件??梢允强杀豢刂?checked) 或不可控制的(unchecked) ,表示一個由程序員導致的錯誤 ,應該在應用程序級被處理??偸遣豢煽刂频?unchecked) ,經(jīng)常用來用于表示系統(tǒng)錯誤或低層資源的錯誤 ,如何可能的話,應該在系統(tǒng)級被捕捉。
RuntimeException 是那些可能在 Java 虛擬機正常運行期間拋出的異常的超類??赡茉趫?zhí)行方法期間拋出但未被捕獲的RuntimeException 的任何子類都無需在 throws 子句中進行聲明。它是Exception的子類。
http://blog.csdn.net/liuj2511981/article/details/8524418
Q:finallize
finalize是在java.lang.object里定義的,也就是說每一個對象都有這么個方法。這個方法在gc啟動,該對象被回收的時候被調(diào)用。其實gc可以回收大部分的對象(凡是new出來的對象,gc都能搞定,一般情況下我們又不會用new以外的方式去創(chuàng)建對象),所以一般是不需要程序員去實現(xiàn)finalize的。
特殊情況下,需要程序員實現(xiàn)finalize,當對象被回收的時候釋放一些資源,比如:一個socket鏈接,在對象初始化時創(chuàng)建,整個生命周期內(nèi)有效,那么就需要實現(xiàn)finalize,關閉這個鏈接。
Q:volatile/Atomic
http://www.cnblogs.com/Mainz/p/3556430.html
Q:Object類hashCode(), equals()方法的理解(HashMap等類庫中如何利用這兩個方法的)
等號(==):
對比對象實例的內(nèi)存地址(也即對象實例的ID),來判斷是否是同一對象實例;又可以說是判斷對象實例是否物理相等;
equals():
對比兩個對象實例是否相等。
當對象所屬的類沒有重寫根類Object的equals()方法時,equals()判斷的是對象實例的ID(內(nèi)存地址),是否是同一對象實例;該方法就是使用的等號(==)的判斷結果,如Object類的源代碼所示:
public boolean equals(Object obj) {
return (this == obj);
}
1.如果兩個對象相同,那么它們的hashCode值一定要相同;
2.如果兩個對象的hashCode相同,它們并不一定相同(這里說的對象相同指的是用eqauls方法比較)。
如不按要求去做了,會發(fā)現(xiàn)相同的對象可以出現(xiàn)在Set集合中,同時,增加新元素的效率會大大下降。
3.equals()相等的兩個對象,hashcode()一定相等;equals()不相等的兩個對象,卻并不能證明他們的hashcode()不相等。
1.重點是equals,重寫hashCode只是技術要求(為了提高效率)
2.為什么要重寫equals呢?因為在java的集合框架中,是通過equals來判斷兩個對象是否相等的
3.在hibernate中,經(jīng)常使用set集合來保存相關對象,而set集合是不允許重復的。在向HashSet集合中添加元素時,其實只要重寫equals()這一條也可以。但當hashset中元素比較多時,或者是重寫的equals()方法比較復雜時,我們只用equals()方法進行比較判斷,效率也會非常低,所以引入了hashCode()這個方法,只是為了提高效率,且這是非常有必要的
http://bijian1013.iteye.com/blog/1972404
Q: 反射機制理解
JAVA反射機制是在運行狀態(tài)中,對于任意一個類,都能夠知道這個類的所有屬性和方法;對于任意一個對象,都能夠調(diào)用它的任意一個方法和屬性;這種動態(tài)獲取的信息以及動態(tài)調(diào)用對象的方法的功能稱為java語言的反射機制。
反射一般用來寫一些通用的框架。比如ide的自動提示就是根據(jù)反射來實現(xiàn)的。
http://www.cnblogs.com/rollenholt/archive/2011/09/02/2163758.html
Q: 從[K,K+N-1]共N個整數(shù)中隨機去除一個,剩余的N-1個數(shù)亂序后放入數(shù)組,請找出被去除的一個
/**
* 快速排序的具體實現(xiàn),排正序
*
* @param data
* @param low
* @param high
*/
private static void quickSortAsc(int data[], int low, int high) {
int i, j, x;
if (low < high) { // 這個條件用來結束遞歸
i = low;
j = high;
x = data[i];
while (i < j) {
while (i < j && data[j] > x) {
j--; // 從右向左找第一個小于x的數(shù)
}
if (i < j) {
data[i] = data[j];
i++;
}
while (i < j && data[i] < x) {
i++; // 從左向右找第一個大于x的數(shù)
}
if (i < j) {
data[j] = data[i];
j--;
}
}
data[i] = x;
qsort_asc(data, low, i - 1);
qsort_asc(data, i + 1, high);
}
}
/**
* 快速排序的具體實現(xiàn),排倒序
*
* @param data
* @param low
* @param high
*/
private static void quickSortDesc(int data[], int low, int high) {
int i, j, x;
if (low < high) { // 這個條件用來結束遞歸
i = low;
j = high;
x = data[i];
while (i < j) {
while (i < j && data[j] < x) {
j--; // 從右向左找第一個小于x的數(shù)
}
if (i < j) {
data[i] = data[j];
i++;
}
while (i < j && data[i] > x) {
i++; // 從左向右找第一個大于x的數(shù)
}
if (i < j) {
data[j] = data[i];
j--;
}
}
data[i] = x;
qsort_desc(data, low, i - 1);
qsort_desc(data, i + 1, high);
}
}
public static void binarySearch(int array[], int searchValue) {
int low = 0;
int high = array.length;
while (low <= high) {
int mid = (low + high) / 2;
if (searchValue == array[mid]) {
System.out.println("此數(shù)值在list中的位置為:" + mid);
break;
}
if (searchValue > array[mid]) {
low = mid + 1; // 當小于時,是low指針向后移動,high指針不變
}
if (searchValue < array[mid]) {
high = mid - 1; // 當大于時,是high指針向前移動,low指針不變
}
}
if (low > high) {
System.out.println("沒有查到結果!");
}
}
http://blog.csdn.net/pzhtpf/article/details/7559896
Q:從長度為100萬的整數(shù)數(shù)組中找出最大的100個 (100萬的數(shù)組在內(nèi)存中,數(shù)組中數(shù)可能重復)
冒泡算法:冒泡算法的思路就是交換排序,通過相鄰數(shù)據(jù)的交換達到排序的目的。平均速度為o(n2).
選擇排序:選擇排序在每一步選取最小的值來重新排列。平均速度為o(nlogn)。
Shell排序:基于插入排序的思想。平均速度為o(n3/2)。
快速排序:快速排序也是基于交換思想,是冒泡排序的改進。平均速度為o(nlogn)。
堆排序:其利用二叉樹的一些性質和堆的數(shù)據(jù)結構完成數(shù)據(jù)的排序。
歸并排序:將多個有序鏈表合并成一個有序的數(shù)據(jù)表。如果參與排序的只有兩個有序鏈表,則稱為二路合并。
Q:用單向鏈表表示十進制整數(shù),求兩個整數(shù)的和(如給出鏈表A、B,返回C)
class Node {
int value;
Node nextNode;
public Node(int value) {
this.value = value;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public Node getNextNode() {
return nextNode;
}
public void setNextNode(Node nextNode) {
this.nextNode = nextNode;
}
}
/**
* 遍歷,將當前節(jié)點的下一個節(jié)點緩存后更改當前節(jié)點指針
*
*/
public static Node reverse(Node head) {
if (null == head) {
return head;
}
Node pre = head;
Node cur = head.getNextNode();
Node next;
while (null != cur) {
next = cur.getNextNode();
cur.setNextNode(pre);
pre = cur;
cur = next;
}
// 將原鏈表的頭節(jié)點的下一個節(jié)點置為null,再將反轉后的頭節(jié)點賦給head
head.setNextNode(null);
head = pre;
return head;
}
Android 基礎
Q:listview 多種Cell
重寫 getViewTypeCount() – 該方法返回多少個不同的布局
重寫 getItemViewType(int) – 根據(jù)position返回相應的Item
3)根據(jù)view item的類型,在getView中創(chuàng)建正確的convertView
http://blog.csdn.net/xyz_lmn/article/details/13745489
Q:launchmode 啟動模式
Standard
默認加載方式.每當需要一個Activity instance的時候系統(tǒng)都會創(chuàng)建一個新的實例給我們,并且將它置于棧頂.這種方式不關心原有的棧結構.
singleTop
系統(tǒng)首先會尋找棧中的instance,如果已有所需實例且位于棧頂,則直接使用;否則就重新創(chuàng)建新的實例.
singleTask
系統(tǒng)首先會尋找棧中的instance,若棧中已有所需實例,則移出該實例之上的所有實例并使用.
singleInstance
當Activity的launch mode 被設置為single instance時,該Activity 實例將被創(chuàng)建于一個新的棧中,且該棧只存在一個實例.如有需要則直接從該棧中取來使用.
Q:inflate形式
LayoutInflater layoutInflater = LayoutInflater.from(context);
LayoutInflater layoutInflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View.inflate
http://blog.sina.com.cn/s/blog_5da93c8f0100xm6n.html
Q:view繪制過程
流程一: mesarue()過程
主要作用:為整個View樹計算實際的大小,即設置實際的高(對應屬性:mMeasuredHeight)和寬(對應屬性: mMeasureWidth),每個View的控件的實際寬高都是由父視圖和本身視圖決定的。
具體的調(diào)用鏈如下:
ViewRoot根對象地屬性mView(其類型一般為ViewGroup類型)調(diào)用measure()方法去計算View樹的大小,回調(diào)View/ViewGroup對象的onMeasure()方法,該方法實現(xiàn)的功能如下:
1、設置本View視圖的最終大小,該功能的實現(xiàn)通過調(diào)用setMeasuredDimension()方法去設置實際的高(對應屬性: mMeasuredHeight)和寬(對應屬性:mMeasureWidth) ;
2 、如果該View對象是個ViewGroup類型,需要重寫該onMeasure()方法,對其子視圖進行遍歷的measure()過程。
2.1 對每個子視圖的measure()過程,是通過調(diào)用父類ViewGroup.java類里的measureChildWithMargins()方法去實現(xiàn),該方法內(nèi)部只是簡單地調(diào)用了View對象的measure()方法。(由于measureChildWithMargins()方法只是一個過渡層更簡單的做法是直接調(diào)用View對象的measure()方法)。
整個measure調(diào)用流程就是個樹形的遞歸過程
流程二、 layout布局過程:
主要作用 :為將整個根據(jù)子視圖的大小以及布局參數(shù)將View樹放到合適的位置上。
具體的調(diào)用鏈如下:
host.layout()開始View樹的布局,繼而回調(diào)給View/ViewGroup類中的layout()方法。具體流程如下
1 、layout方法會設置該View視圖位于父視圖的坐標軸,即mLeft,mTop,mLeft,mBottom(調(diào)用setFrame()函數(shù)去實現(xiàn))
接下來回調(diào)onLayout()方法(如果該View是ViewGroup對象,需要實現(xiàn)該方法,對每個子視圖進行布局) ;
2、如果該View是個ViewGroup類型,需要遍歷每個子視圖chiildView,調(diào)用該子視圖的layout()方法去設置它的坐標值。
流程三、 draw()繪圖過程
由ViewRoot對象的performTraversals()方法調(diào)用draw()方法發(fā)起繪制該View樹,值得注意的是每次發(fā)起繪圖時,并不會重新繪制每個View樹的視圖,而只會重新繪制那些“需要重繪”的視圖,View類內(nèi)部變量包含了一個標志位DRAWN,當該視圖需要重繪時,就會為該View添加該標志位。
調(diào)用流程 :
mView.draw()開始繪制,draw()方法實現(xiàn)的功能如下:
1 、繪制該View的背景
2 、為顯示漸變框做一些準備操作(見5,大多數(shù)情況下,不需要改漸變框)
3、調(diào)用onDraw()方法繪制視圖本身 (每個View都需要重載該方法,ViewGroup不需要實現(xiàn)該方法)
4、調(diào)用dispatchDraw ()方法繪制子視圖(如果該View類型不為ViewGroup,即不包含子視圖,不需要重載該方法)值得說明的是,ViewGroup類已經(jīng)為我們重寫了dispatchDraw ()的功能實現(xiàn),應用程序一般不需要重寫該方法,但可以重載父類函數(shù)實現(xiàn)具體的功能。
4.1 dispatchDraw()方法內(nèi)部會遍歷每個子視圖,調(diào)用drawChild()去重新回調(diào)每個子視圖的draw()方法(注意,這個 地方“需要重繪”的視圖才會調(diào)用draw()方法)。值得說明的是,ViewGroup類已經(jīng)為我們重寫了dispatchDraw()的功能實現(xiàn),應用程序一般不需要重寫該方法,但可以重載父類函數(shù)實現(xiàn)具體的功能。
Q:view的touch事件傳遞機制
. onTouch和onTouchEvent有什么區(qū)別,又該如何使用?
從源碼中可以看出,這兩個方法都是在View的dispatchTouchEvent中調(diào)用的,onTouch優(yōu)先于onTouchEvent執(zhí)行。如果在onTouch方法中通過返回true將事件消費掉,onTouchEvent將不會再執(zhí)行。
另外需要注意的是,onTouch能夠得到執(zhí)行需要兩個前提條件,第一mOnTouchListener的值不能為空,第二當前點擊的控件必須是enable的。因此如果你有一個控件是非enable的,那么給它注冊onTouch事件將永遠得不到執(zhí)行。對于這一類控件,如果我們想要監(jiān)聽它的touch事件,就必須通過在該控件中重寫onTouchEvent方法來實現(xiàn)。
dispatchTouchEvent->onTouch->onTouhEvent
ViewGroup
實際情況是,當你點擊了某個控件,首先會去調(diào)用該控件所在布局的dispatchTouchEvent方法,然后在布局的dispatchTouchEvent方法中找到被點擊的相應控件,再去調(diào)用該控件的dispatchTouchEvent方法。
。如果我們點擊了MyLayout中的按鈕,會先去調(diào)用MyLayout的dispatchTouchEvent方法,可是你會發(fā)現(xiàn)MyLayout中并沒有這個方法。那就再到它的父類LinearLayout中找一找,發(fā)現(xiàn)也沒有這個方法。那只好繼續(xù)再找LinearLayout的父類ViewGroup,你終于在ViewGroup中看到了這個方法,按鈕的dispatchTouchEvent方法就是在這里調(diào)用的。
1. Android事件分發(fā)是先傳遞到ViewGroup,再由ViewGroup傳遞到View的。
2. 在ViewGroup中可以通過onInterceptTouchEvent方法對事件傳遞進行攔截,onInterceptTouchEvent方法返回true代表不允許事件繼續(xù)向子View傳遞,返回false代表不對事件進行攔截,默認返回false。
3. 子View中如果將傳遞的事件消費掉,ViewGroup中將無法接收到任何事件。
http://blog.csdn.net/guolin_blog/article/details/9097463
Q:ansynctask原理
onPreExecute、doInBackground、onProgressUpdate、onPostExecute
一個SerialExecutor ArrayDeque 隊列管理線程
在doInBackground()方法中調(diào)用publishProgress()方法才可以從子線程切換到UI線程,從而完成對UI元素的更新操作。其實也沒有什么神秘的,因為說到底,AsyncTask也是使用的異步消息處理機制,只是做了非常好的封裝而已。
因此在3.0版本中AsyncTask的改動還是挺大的,在3.0之前的AsyncTask可以同時有5個任務在執(zhí)行,而3.0之后的AsyncTask同時只能有1個任務在執(zhí)行。為什么升級之后可以同時執(zhí)行的任務數(shù)反而變少了呢?這是因為更新后的AsyncTask已變得更加靈活,如果不想使用默認的線程池,還可以自由地進行配置。
http://blog.csdn.net/guolin_blog/article/details/11711405
Q:fragment、activity
getActivity 解決通信問題
1.獲取到FragmentManager,在Activity中可以直接通過getFragmentManager得到。
2.開啟一個事務,通過調(diào)用beginTransaction方法開啟。
3.向容器內(nèi)加入Fragment,一般使用replace方法實現(xiàn),需要傳入容器的id和Fragment的實例。
4.提交事務,調(diào)用commit方法提交。
http://blog.csdn.net/guolin_blog/article/details/8881711
Q: Task stack,Activity, 進程,及應用的理解
返回棧是一個典型的后進先出(last in, first out)的數(shù)據(jù)結構
alwaysRetainTaskState
如果將最底層的那個Activity的這個屬性設置為true,那么上面所描述的默認行為就將不會發(fā)生,任務中所有的Activity即使過了很長一段時間之后仍然會被繼續(xù)保留。
clearTaskOnLaunch
如果將最底層的那個Activity的這個屬性設置為true,那么只要用戶離開了當前任務,再次返回的時候就會將最底層Activity之上的所有其它Activity全部清除掉。簡單來講,就是一種和alwaysRetainTaskState完全相反的工作模式,它保證每次返回任務的時候都會是一種初始化狀態(tài),即使用戶僅僅離開了很短的一段時間。
finishOnTaskLaunch
這個屬性和clearTaskOnLaunch是比較類似的,不過它不是作用于整個任務上的,而是作用于單個Activity上。如果某個Activity將這個屬性設置成true,那么用戶一旦離開了當前任務,再次返回時這個Activity就會被清除掉。
http://www.cnblogs.com/hanyonglu/archive/2012/04/12/2443262.html
Q:Handler機制
是在主線程中可以直接創(chuàng)建Handler對象,而在子線程中需要先調(diào)用Looper.prepare()才能創(chuàng)建Handler對象。
http://blog.csdn.net/guolin_blog/article/details/9991569
Q:ui性能優(yōu)化 viewStub
減少布局層次,Listview holder機制,ViewStub懶加載模式
Q: Bitmap圖片加載
我們在編寫Android程序的時候經(jīng)常要用到許多圖片,不同圖片總是會有不同的形狀、不同的大小,但在大多數(shù)情況下,這些圖片都會大于我們程序所需要的大小。比如說系統(tǒng)圖片庫里展示的圖片大都是用手機攝像頭拍出來的,這些圖片的分辨率會比我們手機屏幕的分辨率高得多。大家應該知道,我們編寫的應用程序都是有一定內(nèi)存限制的,程序占用了過高的內(nèi)存就容易出現(xiàn)OOM(OutOfMemory)異常。我們可以通過下面的代碼看出每個應用程序最高可用內(nèi)存是多少。
http://blog.csdn.net/guolin_blog/article/details/9316683
Q:service啟動方式以及區(qū)別
Context.startService():Service會經(jīng)歷onCreate -> onStart(如果Service還沒有運行,則android先調(diào)用onCreate()然后調(diào)用onStart();如果Service已經(jīng)運行,則只調(diào)用onStart(),所以一個Service的onStart方法可能會重復調(diào)用多次 );stopService的時候直接onDestroy,如果是調(diào)用者自己直接退出而沒有調(diào)用stopService的話,Service會一直在后臺運行。該Service的調(diào)用者再啟動起來后可以通過stopService關閉Service。 注意,多次調(diào)用Context.startservice()不會嵌套(即使會有相應的onStart()方法被調(diào)用),所以無論同一個服務被啟動了多少次,一旦調(diào)用Context.stopService()或者stopSelf(),他都會被停止。補充說明:傳遞給startService()的Intent對象會傳遞給onStart()方法。調(diào)用順序為:onCreate --> onStart(可多次調(diào)用) --> onDestroy。
Context.bindService():Service會經(jīng)歷onCreate() -> onBind(),onBind將返回給客戶端一個IBind接口實例,IBind允許客戶端回調(diào)服務的方法,比如得到Service運行的狀態(tài)或其他操作。這個時候把調(diào)用者(Context,例如Activity)會和Service綁定在一起,Context退出了,Srevice就會調(diào)用onUnbind -> onDestroyed相應退出,所謂綁定在一起就共存亡了 。
補充說明:傳遞給bindService()的Intent對象會傳遞給onBind(),傳遞給unbindService()的Intent對象會傳遞給onUnbind()方法。 調(diào)用順序為:onCreate --> onBind(只一次,不可多次綁定) --> onUnbind --> onDestory。
onStartCommand
START_STICKY:如果service進程被kill掉,保留service的狀態(tài)為開始狀態(tài),但不保留遞送的intent對象。隨后系統(tǒng)會嘗試重新創(chuàng)建service,由于服務狀態(tài)為開始狀態(tài),所以創(chuàng)建服務后一定會調(diào)用onStartCommand(Intent,int,int)方法。如果在此期間沒有任何啟動命令被傳遞到service,那么參數(shù)Intent將為null.
START_NOT_STICKY:“非粘性的”。使用這個返回值時,如果在執(zhí)行完onStartCommand后,服務被異常kill掉,系統(tǒng)不會自動重啟該服務。
START_REDELIVER_INTENT:重傳Intent。使用這個返回值時,如果在執(zhí)行完onStartCommand后,服務被異常kill掉,系統(tǒng)會自動重啟該服務。
START_STICKY_COMPATIBILITY:START_STICKY的兼容版本,但不保證服務被kill后一定能重啟。
Q:xml/json 解析方式
SAX,DOM.XMLParser
JSON JackJson Gson
Q:csv文件讀取接口設計
http://developer.51cto.com/art/201104/253059.htm
Q:ANR問題
1. KeyDispatchTimeout(5 seconds) --主要類型按鍵或觸摸事件在特定時間內(nèi)無響應
2. BroadcastTimeout(10 seconds) --BroadcastReceiver在特定時間內(nèi)無法處理完成
3. ServiceTimeout(20 seconds) --小概率類型 Service在特定的時間內(nèi)無法處理完成
1. UI線程盡量只做跟UI相關的工作
2. 耗時的工作(比如數(shù)據(jù)庫操作,I/O,連接網(wǎng)絡或者別的有可能阻礙UI線程的操作)把它放入單獨的線程處理
3. 盡量用Handler來處理UIthread和別的thread之間的交互
http://www.cnblogs.com/purediy/p/3225060.html
Q:Drawable有哪些
http://blog.csdn.net/ouyang_peng/article/details/8800743
Q:ImageView: scaleType
ScaleType.CENTER
按圖片的原來size居中顯示,當圖片長/寬超過View的長/寬,則截取圖片的居中部分顯示
ScaleType.CENTER_CROP);
按比例擴大圖片的size居中顯示,使得圖片長(寬)等于或大于View的長(寬)
ScaleType.CENTER_INSIDE);
將圖片的內(nèi)容完整居中顯示,通過按比例縮小或原來的size使得圖片長/寬等于或小于View的長/寬
ScaleType.FIT_CENTER);
把圖片按比例擴大/縮小到View的寬度,居中顯示
FIT_START, FIT_END在圖片縮放效果上與FIT_CENTER一樣,只是顯示的位置不同,F(xiàn)IT_START是置于頂部,F(xiàn)IT_CENTER居中,F(xiàn)IT_END置于底部。
FIT_XY
不按比例縮放圖片,目標是把圖片塞滿整個View。
Q: 硬件加速
http://zuiniuwang.blog.51cto.com/3709988/721798
Q:版本演進、兼容,版本的差異,support-v4/7包,compat包
啟用硬件加速的最簡單方法就是為整個系統(tǒng)打開硬件加速的全局設置。如果你的程序是標準View或者是Drawable 則硬件加速的全局設這并不會造成不良的影響。然而硬件加速并不支持所有2D畫的操作,所以開啟硬件加速可能會對使用自定義組件的應用程序造成影響,問題常常表現(xiàn)在不可見的元素異常和錯誤的像素渲染,為了解決這個問題Android可以讓你選擇啟動或者禁用以下級別的硬件加速:Application Activity Window 和 View 。
http://blog.csdn.net/uniquerhythm/article/details/12570381
Android Support v4 是最早(2011年4月份)實現(xiàn)的庫。用在Android1.6 (API lever 4)或者更高版本之上。它包含了相對V4, V13大的多的功能。
例如:Fragment,NotificationCompat,LoadBroadcastManager,ViewPager,PageTabAtrip,Loader,F(xiàn)ileProvider 等。
Android Support v7: 這個包是為了考慮Android2.1(API level 7) 及以上版本而設計的,但是v7是要依賴v4這個包的,也就是如果要使用,兩個包得同時引用。v7支持了Action Bar
Android Support v13:這個包的設計是為了android 3.2及更高版本的,一般我們都不常用,平板開發(fā)中能用到
http://blog.csdn.net/qq530918474/article/details/39996311
Q:android項目build過程
第一步:打包資源文件,生成R.java文件
【輸入】Resource文件(就是工程中res中的文件)、Assets文件(相當于另外一種資源,這種資源Android系統(tǒng)并不像對res中的文件那樣優(yōu)化它)、AndroidManifest.xml文件(包名就是從這里讀取的,因為生成R.java文件需要包名)、Android基礎類庫(Android.jar文件)
【輸出】打包好的資源(一般在Android工程的bin目錄可以看到一個叫resources.ap_的文件就是它了)、R.java文件(在gen目錄中,大家應該很熟悉了)
【工具】aapt工具,它的路徑在${ANDROID_SDK_HOME}/platform-tools/aapt(如果你使用的是Windows系統(tǒng),按慣例路徑應該這樣寫:%ANDROID_SDK_HOME%\platform-tools\aapt.exe,下同)。
第二步:處理AIDL文件,生成對應的.java文件(當然,有很多工程沒有用到AIDL,那這個過程就可以省了)
【輸入】源碼文件、aidl文件、framework.aidl文件
【輸出】對應的.java文件
【工具】aidl工具
第三步:編譯Java文件,生成對應的.class文件
【輸入】源碼文件(包括R.java和AIDL生成的.java文件)、庫文件(.jar文件)
【輸出】.class文件
【工具】javac工具
第四步:把.class文件轉化成Davik VM支持的.dex文件
【輸入】 .class文件(包括Aidl生成.class文件,R生成的.class文件,源文件生成的.class文件),庫文件(.jar文件)
【輸出】.dex文件
【工具】javac工具
第五步:打包生成未簽名的.apk文件
【輸入】打包后的資源文件、打包后類文件(.dex文件)、libs文件(包括.so文件,當然很多工程都沒有這樣的文件,如果你不使用C/C++開發(fā)的話)
【輸出】未簽名的.apk文件
【工具】apkbuilder工具
第六步:對未簽名.apk文件進行簽名
【輸入】未簽名的.apk文件
【輸出】簽名的.apk文件
【工具】jarsigner
第七步:對簽名后的.apk文件進行對齊處理(不進行對齊處理是不能發(fā)布到Google Market的)
【輸入】簽名后的.apk文件
【輸出】對齊后的.apk文件
【工具】zipalign工具
Q:lint、hierarchyviewer、mat、findbugs、traceview、proguard工具
Lint 代碼優(yōu)化工具,去除無效的資源文件 Android Tools
Hierarchyviewer UI優(yōu)化工具
Mat 內(nèi)存分析工具
findbugs可用于對java代碼進行靜態(tài)檢查,檢查bug類型包括:
Bad practice 壞的實踐:常見代碼錯誤,序列化錯誤,用于靜態(tài)代碼檢查時進行缺陷模式匹配
Correctness 可能導致錯誤的代碼,如空指針引用等
國際化相關問題:如錯誤的字符串轉換
可能受到的惡意攻擊,如訪問權限修飾符的定義等
多線程的正確性:如多線程編程時常見的同步,線程調(diào)度問題。
運行時性能問題:如由變量定義,方法調(diào)用導致的代碼低效問題。
traceview性能調(diào)優(yōu)工具TraceView的使用及通過其確定性能點。
Proguard 防反編譯、混淆文件