1. 程式人生 > >面試題答案整理

面試題答案整理

反射的用途和實現?
java中的反射機制是指對於任意一個類都能知道這個類的所有屬性和方法,對於任意一個物件都能知道他的方法,反射的主要用途是各個框架的實現
實現:1.獲取例項物件(三種實現)
1.類.class
2.物件.getclass
3.Class.forName(“完整路徑”)

public static void main(String[] args) {
		//Foo的例項物件如何表示
		Foo foo1 = new Foo();//foo1就表示出來了.
		//Foo這個類 也是一個例項物件,Class類的例項物件,如何表示呢
		//任何一個類都是Class的例項物件,這個例項物件有三種表示方式
		
		//第一種表示方式--->實際在告訴我們任何一個類都有一個隱含的靜態成員變數class
		Class c1 = Foo.class;
		
		//第二中表達方式  已經知道該類的物件通過getClass方法
		Class c2 = foo1.getClass();
		
		/*官網 c1 ,c2 表示了Foo類的類型別(class type)
		 * 萬事萬物皆物件,
		 * 類也是物件,是Class類的例項物件
		 * 這個物件我們稱為該類的類型別
		 * 
		 */
		
		//不管c1  or c2都代表了Foo類的類型別,一個類只可能是Class類的一個例項物件
		System.out.println(c1 == c2);
		
		//第三種表達方式
		Class c3 = null;
		try {
			c3 = Class.forName("com.imooc.reflect.Foo");
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println(c2==c3);

動態載入
new一個物件是靜態載入,缺點是一旦啟動就要把所有的類都載入,耗費時間和空間,使用動態載入就可以避免這些問題。
具體使用來說:就是建立例項.newInstance()
獲得方法和成員變數資訊(主要就是getMethod方法)

public class ClassUtil {
	/**
	 * 列印類的資訊,包括類的成員函式、成員變數(只獲取成員函式)
	 * @param obj 該物件所屬類的資訊
	 */
	public static void printClassMethodMessage(Object obj){
		//要獲取類的資訊  首先要獲取類的類型別
		Class c = obj.getClass();//傳遞的是哪個子類的物件  c就是該子類的類型別
		//獲取類的名稱
		System.out.println("類的名稱是:"+c.getName());
		/*
		 * Method類,方法物件
		 * 一個成員方法就是一個Method物件
		 * getMethods()方法獲取的是所有的public的函式,包括父類繼承而來的
		 * getDeclaredMethods()獲取的是所有該類自己宣告的方法,不問訪問許可權
		 */
		Method[] ms = c.getMethods();//c.getDeclaredMethods()
		for(int i = 0; i < ms.length;i++){
			//得到方法的返回值型別的類型別
			Class returnType = ms[i].getReturnType();
			System.out.print(returnType.getName()+" ");
			//得到方法的名稱
			System.out.print(ms[i].getName()+"(");
			//獲取引數型別--->得到的是引數列表的型別的類型別
			Class[] paramTypes = ms[i].getParameterTypes();
			for (Class class1 : paramTypes) {
				System.out.print(class1.getName()+",");
			}
			System.out.println(")");
		}
	}
    /**
     * 獲取成員變數的資訊
     * @param obj
     */
	public static void printFieldMessage(Object obj) {
		Class c = obj.getClass();
		/*
		 * 成員變數也是物件
		 * java.lang.reflect.Field
		 * Field類封裝了關於成員變數的操作
		 * getFields()方法獲取的是所有的public的成員變數的資訊
		 * getDeclaredFields獲取的是該類自己宣告的成員變數的資訊
		 */
		//Field[] fs = c.getFields();
		Field[] fs = c.getDeclaredFields();
		for (Field field : fs) {
			//得到成員變數的型別的類型別
			Class fieldType = field.getType();
			String typeName = fieldType.getName();
			//得到成員變數的名稱
			String fieldName = field.getName();
			System.out.println(typeName+" "+fieldName);
		}
	}
	/**
	 * 列印物件的建構函式的資訊
	 * @param obj
	 */
	public static void printConMessage(Object obj){
		Class c = obj.getClass();
		/*
		 * 建構函式也是物件
		 * java.lang. Constructor中封裝了建構函式的資訊
		 * getConstructors獲取所有的public的建構函式
		 * getDeclaredConstructors得到所有的建構函式
		 */
		//Constructor[] cs = c.getConstructors();
		Constructor[] cs = c.getDeclaredConstructors();
		for (Constructor constructor : cs) {
			System.out.print(constructor.getName()+"(");
			//獲取建構函式的引數列表--->得到的是引數列表的類型別
			Class[] paramTypes = constructor.getParameterTypes();
			for (Class class1 : paramTypes) {
				System.out.print(class1.getName()+",");
			}
			System.out.println(")");
		}
	}
}
方法的反射:呼叫之前的獲得的方法.invoke()

get和post的區別:
post 相對 get 請求是 “安全” 的
get 請求傳送資料更小
get 能被快取,post 不能被快取

session和cookie的區別
1.cookie放在瀏覽器上,session放在伺服器上
2.session會在一定時間內儲存在伺服器上。當訪問增多,會比較佔用你伺服器的效能
考慮到減輕伺服器效能方面,應當使用COOKIE。
3. cookie不是很安全,別人可以分析存放在本地的COOKIE並進行COOKIE欺騙
考慮到安全應當使用session
JDBC流程:
1.註冊驅動
2.建立連結
3.建立sql語句
4執行語句
5.處理結果
6.釋放資源
MVC設計思想:
M:model主要處理資料
v:主要功能是展示頁面
c:作為m和v的橋樑,協調V和M

HashMap 和 ConcurrentHashMap 的區別
ConcurrentHashMap對整個桶陣列進行了分割分段(Segment),然後在每一個分段上都用lock鎖進行保護,相對於HashTable的syn關鍵字鎖的粒度更精細了一些,併發效能更好,而HashMap沒有鎖機制,不是執行緒安全的。
HashMap的鍵值對允許有null,但是ConCurrentHashMap都不允許

鎖的種類?correntHashMap底層實現原理?

sleep()、join()、wait()、yield的區別
sleep使當前執行緒回到阻塞狀態,不釋放物件鎖
join方法的意思線上程執行完前不執行該執行緒
wait方法導致該執行緒等待,但會釋放物件鎖,給其他執行緒機會
yield方法只是暫停當前執行緒重新回到可執行狀態,

CountDownLatch
標籤:併發程式設計
什麼是CountDownLatch?
他能夠讓一個執行緒等待其他執行緒完成各自的工作後再執行
應用場景:主程式啟動
原理:通過一個計數器實現,計數器初始化值為執行緒數量,每當一個執行緒完成工作後減1,當計數器為0時,閉鎖的執行緒恢復執行任務
重要方法:await():呼叫await方法的執行緒會被掛起,等待知道count值為0繼續執行
countdown:將count值減一

CyclicBarrier
標籤:併發程式設計
什麼是CyclicBarrier?
通過它可以實現讓一組執行緒等待至某個狀態之後再全部同時執行
原理:在CyclicBarrier的內部定義了一個Lock物件,每當一個執行緒呼叫await方法時,將攔截的執行緒數減1,然後判斷剩餘攔截數是否為初始值,如果不是進入Lock物件的條件佇列等待,如果是,執行barrierAction物件的Runnable方法,然後將鎖的條件佇列中的所有執行緒放入鎖等待佇列中,這些執行緒會依次的獲取鎖、釋放鎖
CountDownLatch和CyclicBarrier的比較:
1.前者時執行緒組之間的等待,後者是一個執行緒組內的等待
2.前者是減計數方式,後者是加計數方式
3.前者計數為0無法重置,而後者計數達到初始值,則可以重置
4.前者不可以複用,後者可以複用

Semaphore用法
1.什麼是Semaphore?
Semaphore可以控制同時訪問的執行緒個數,通過acquire()方法獲得許可,如果沒有就等待,而release()釋放一個許可。
2.重要方法:acquire()、release()方法
Exchager原理
1.什麼是Exchager?
執行緒之間互動資料,且在併發時候使用,兩兩交換,交換中不會因為執行緒多而混亂,傳送出去沒接收到會一直等,由互動器完成互動過程。
實現原理:
Exchanger的基本原理是維持一個槽(Slot),這個Slot中儲存一個Node的引用,這個Node中儲存了一個用來交換的Item和一個用來獲取物件的洞Hole。如果一個來“佔有”的執行緒看見Slot為null,則呼叫CAS方法(CAS方法在前面的文章中已經詳細介紹了https://zhuanlan.zhihu.com/p/27338395)使一個Node物件佔據這個Slot,並等待另一個執行緒前來交換。如果第二個來“填充”的執行緒看見Slot不為null,則呼叫CAS方法將其設定為null,同時使用CAS與Hole交換Item,然後喚醒等待的執行緒。注意所有的CAS操作都有可能失敗,因此CAS必須是迴圈呼叫的。
說說ThreadLocal原理:
1.什麼是ThreadLocal?
執行緒本地變數,ThreadLocal為每個變數線上程中建立了一個副本
2.重要方法:
get():獲取ThreadLocal在當前執行緒中儲存的變數副本
set():設定變數副本
remove():移除執行緒副本
initiaValue():protected方法寫的,用於重寫,延遲載入
get方法的實質:使用ThreadLocals用來存放副本,鍵值為當前ThreadLocal變數
初始化時,threadLocals為空,當通過ThreadLocal呼叫get方法時對threadLocals變數進行初始化,並以當前ThreadLocal變數為鍵值
應用場景:資料庫連線,session管理
講講執行緒池的實現原理
預先啟動一些執行緒執行緒無限迴圈從任務佇列中獲取一個任務進行執行,直到執行緒池關閉,如果某個異常執行緒因為執行某個任務而發生終止,那麼重寫建立一個新的執行緒,就這樣反覆迴圈
幾種方式:newCachedThreadPoll(可快取)
newFixedThreadPool(定長執行緒池, 指定併發數 newScheduledThreadPool(定時週期任務執行)
newSingleThreadExecutor(唯一執行緒執行任務)
執行緒生命週期:https://www.cnblogs.com/sunddenly/p/4106562.html