Android 面試複習

try catch編程

public static int getNum() {
        try {
            int a = 1 / 0;
            return 1;
        } catch (Exception e) {
            System.out.println("1");
//            int b = 2 / 0;
//throw new Exception("asdasd");
            System.out.println("2");
            return 2;
        } finally {

            return 5;
        }
    }
複製代碼

總結: catch 中,遇到 return 或者再發生 catch ,將會直接執行 finally, 若是沒有 finally 只有 再發生 catch 那就拋出異常。緩存

toast :bash

這是由於Toast顯示須要NotificationManagerService(查看Android源碼)

部分手機把通知權限關閉了,因此Toast沒法正常彈出
複製代碼

線程問題:多線程

1,wait 和 sleep 的區別併發

wait 會釋放鎖,sleep 會有持有鎖。wait 用來線程間交互,sleep 用於暫停執行。
複製代碼

2,synchronized 和 volatile volatile:框架

1)保證了不一樣線程對這個變量進行操做時的可見性,即一個線程修改某個變量的值,這新值對於其餘線程可見。(線程緩存無效,取主存中的值,具備原子性)

2)禁止進行指令重排

發散:
1.原子性
    i = 1 這種操做,i ++, j = i 都不是原子操做  
2.可見性
    Java就是利用volatile來提供可見性的。 當一個變量被volatile修飾時,那麼對它的修改會馬上刷新到主存,當其它線程須要讀取該變量時,會去內存中讀取新值。而普通變量則不能保證這一點。
    其實經過synchronized和Lock也可以保證可見性,線程在釋放鎖以前,會把共享變量值都刷回主存,可是synchronized和Lock的開銷都更大。
3.有序性
    JMM是容許編譯器和處理器對指令重排序的,可是規定了as-if-serial語義,即無論怎麼重排序,程序的執行結果不能改變。
    JMM保證了重排序不會影響到單線程的執行,可是在多線程中卻容易出問題。
    
例子:
    1,單例模式的實現,典型的雙重檢查鎖定(DCL)   
    2,標記變量
複製代碼

3,線程池ide

1,線程池優點

第一:下降資源消耗。經過重複利用已建立的線程下降線程建立和銷燬形成的消耗。 

第二:提升響應速度。當任務到達時,任務能夠不須要等到線程建立就能當即執行。 

第三:提升線程的可管理性。線程是稀缺資源,若是無限制的建立,不只會消耗系統資源,還會下降系統的穩定
性,使用線程池能夠進行統一的分配,調優和監控。


2,線程池策略

    a. 若是正在運行的線程數量小於 corePoolSize,那麼立刻建立線程運行這個任務;
    
    b. 若是正在運行的線程數量大於或等於 corePoolSize,那麼將這個任務放入隊列。
   
    c. 若是這時候隊列滿了,並且正在運行的線程數量小於 maximumPoolSize,那麼仍是要建立線程運行這
    個任務;
    
    d. 若是隊列滿了,並且正在運行的線程數量大於或等於 maximumPoolSize,那麼線程池會拋出異常,告訴調用者「我不能再接受任務了」。
    
    注意:
    
    一、當一個線程完成任務時,它會從隊列中取下一個任務來執行。
    
    二、當一個線程無事可作,超過必定的時間(keepAliveTime)時,線程池會判斷,若是當前運行的線程數大於
    corePoolSize,那麼這個線程就被停掉。因此線程池的全部任務完成後,它最終會收縮到 corePoolSize 的大小。
複製代碼

4,如何控制某個方法容許併發訪問線程的個數函數

Semaphore
semaphore.acquire();
semaphore.release();
複製代碼

5,反射ui

ava 中的反射首先是可以獲取到 Java 中要反射類的字節碼,獲取字節碼有三種方法, 1.Class.forName(className) 2.類名.class 3.this.getClass()。而後將字節碼中的方法,變量,構造函數等映射 成相應的 Method、Filed、Constructor 等類,這些類提供了豐富的方法能夠被咱們所使用。

1)動態代理
複製代碼
final List<String> list = new ArrayList<String>();
List<String> proxyInstance = (List<String>) Proxy.newProxyInstance(list.getClass().getClassLoader(), list.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws
Throwable {
return method.invoke(list, args); }
}); proxyInstance.add("你好"); System.out.println(list);
複製代碼
2)動態代理與靜態代理的區別
    靜態代理一般只代理一個類,動態代理是代理一個接口下的多個實現類。 靜態代理事先知道要代理的是什麼,而動態代理不知道要代理什麼東西,只有在運行時才知道。 動態代理是實現 JDK 裏的 InvocationHandler 接口的 invoke 方法,但注意的是代理的是接口,也就是你的
業務類必需要實現接口,經過 Proxy 裏的 newProxyInstance 獲得代理對象。
還有一種動態代理 CGLIB,代理的是類,不須要業務類繼承接口,經過派生的子類來實現代理。經過在運行
時,動態修改字節碼達到修改類的目的。
AOP 編程就是基於動態代理實現的,好比著名的 Spring 框架、Hibernate 框架等等都是動態代理的使用例子。
複製代碼
相關文章
相關標籤/搜索