java筆試、面試題
筆試題
1、在面向物件方法中,實現資訊隱蔽是依靠
A.物件的繼承 B.物件的多型 C.物件的封裝 D.物件的分類
解析:物件的繼承:子類擁有父類所有的屬性和方法,子類共享父類的資料
物件的多型:解耦,不同的物件在接收到相同的訊息時,採用不同的動作
編譯的多型就是函式過載(方法名不同,引數個數也不同);
執行時多型就是函式重寫(具有相同的方法名、返回型別和引數表,則新方法將覆蓋原有的方法)
物件的封裝:實現資訊隱蔽
2、對成員的訪問控制保護最強的是
A.public B.預設 C.private D.protected(子類或同package)
3.可用作java識別符號的是
A.#123# [email protected]
4.屬於java輸入輸出流的、且處理的是char型別的類是
A.Reader類 B.InputStream類 C.OutputStream類 D.File類
解析:學習地址http://blog.csdn.net/hguisu/article/details/7418161
在電腦上的資料有三種儲存方式,一種是外存,一種是記憶體,一種是快取。比如電腦上的硬碟,磁碟,U盤等都是外存,在電腦上有記憶體條,快取是在CPU裡面的。外存的儲存量最大,其次是記憶體,最後是快取,但是外存的資料的讀取最慢,其次是記憶體,快取最快。
Java類庫中,IO部分的內容:標準輸入輸出,檔案的操作,網路上的資料流,字串流,物件流,
資料流:
一組有序,有起點和終點的位元組的資料序列。包括輸入流和輸出流。
輸入流(Input Stream):
程式從輸入流讀取資料來源。資料來源包括外界(鍵盤、檔案、網路…),即是將資料來源讀入到程式的通訊通道
輸出流:
程式向輸出流寫入資料。將程式中的資料輸出到外界(顯示器、印表機、檔案、網路…)的通訊通道。
採用資料流的目的就是使得輸出輸入獨立於裝置。
Input Stream不關心資料來源來自何種裝置(鍵盤,檔案,網路)
Output Stream不關心資料的目的是何種裝置(鍵盤,檔案,網路)
資料流分類:
流序列中的資料既可以是未經加工的原始二進位制資料,也可以是經一定編碼處理後符合某種格式規定的特定資料。因此Java中的流分為兩種:
1) 位元組流:資料流中最小的資料單元是位元組
2) 字元流:資料流中最小的資料單元是字元, Java中的字元是Unicode編碼,一個字元佔用兩個位元組。
Java.io包中最重要的就是5個類和一個介面:5個類指的是File、OutputStream、InputStream、Writer、Reader;一個介面指的是Serializable
Java I/O主要包括如下幾個層次,包含三個部分:
1.流式部分――IO的主體部分;
2.非流式部分――主要包含一些輔助流式部分的類,如:File類、RandomAccessFile類和FileDescriptor等類;
3.其他類--檔案讀取部分的與安全相關的類,如:SerializablePermission類,以及與本地作業系統相關的檔案系統的類,如:FileSystem類和Win32FileSystem類和WinNTFileSystem類。
主要的類如下:
1. File(檔案特徵與管理):用於檔案或者目錄的描述資訊,例如生成新目錄,修改檔名,刪除檔案,判斷檔案所在路徑等。
2. InputStream(二進位制格式操作):抽象類,基於位元組的輸入操作,是所有輸入流的父類。定義了所有輸入流都具有的共同特徵。
3. OutputStream(二進位制格式操作):抽象類。基於位元組的輸出操作。是所有輸出流的父類。定義了所有輸出流都具有的共同特徵。
Java中字元是採用Unicode標準,一個字元是16位,即一個字元使用兩個位元組來表示。為此,JAVA中引入了處理字元的流。
4. Reader(檔案格式操作):抽象類,基於字元的輸入操作。
5. Writer(檔案格式操作):抽象類,基於字元的輸出操作。
6. RandomAccessFile(隨機檔案操作):它的功能豐富,可以從檔案的任意位置進行存取(輸入輸出)操作。
Java中IO流的體系結構如圖:
非流式檔案類--File類
1)public boolean exists( ) 判斷檔案或目錄是否存在
2)public boolean isFile( ) 判斷是檔案還是目錄
3)public boolean isDirectory( ) 判斷是檔案還是目錄
4)public String getName( ) 返回檔名或目錄名
5)public String getPath( ) 返回檔案或目錄的路徑。
6)public long length( ) 獲取檔案的長度
7)public String[ ] list ( ) 將目錄中所有檔名儲存在字串陣列中返回。
2) public boolean renameTo( File newFile ); 重新命名檔案
2) public void delete( ); 刪除檔案
3) public boolean mkdir( ); 建立目錄
基本資料流的I/O
輸入/輸出 |
位元組流 |
字元流 |
輸入流 |
Inputstream |
Reader |
輸出流 |
OutputStream |
Writer |
IO框架:
5.下列語句中,屬於分支語句的是
A.if語句 B.swithc語句 C.do while 語句 D.for語句
6.設x=1,y=2,z=3,則表示式y+=z--/++x-x的值是
A.0 B.1 C.2 D.3
解析 :++x以後即使是同一個表示式裡x也成了++x的值
7.在java中,哪一個關鍵字使類不能派生出子類
A.final B.public C.private D.volatile
解析:volatile關鍵字的兩層語義
一旦一個共享變數(類的成員變數、類的靜態成員變數)被volatile修飾之後,那麼就具備了兩層語義:
1)保證了不同執行緒對這個變數進行操作時的可見性,即一個執行緒修改了某個變數的值,這新值對其他執行緒來說是立即可見的。
2)禁止進行指令重排序。
先看一段程式碼,假如執行緒1先執行,執行緒2後執行:
1 2 3 4 5 6 7 8 |
//執行緒1 boolean stop = false; while(!stop){ doSomething(); } //執行緒2 stop = true; |
這段程式碼是很典型的一段程式碼,很多人在中斷執行緒時可能都會採用這種標記辦法。但是事實上,這段程式碼會完全執行正確麼?即一定會將執行緒中斷麼?不一定,也許在大多數時候,這個程式碼能夠把執行緒中斷,但是也有可能會導致無法中斷執行緒(雖然這個可能性很小,但是隻要一旦發生這種情況就會造成死迴圈了)。
下面解釋一下這段程式碼為何有可能導致無法中斷執行緒。在前面已經解釋過,每個執行緒在執行過程中都有自己的工作記憶體,那麼執行緒1在執行的時候,會將stop變數的值拷貝一份放在自己的工作記憶體當中。
那麼當執行緒2更改了stop變數的值之後,但是還沒來得及寫入主存當中,執行緒2轉去做其他事情了,那麼執行緒1由於不知道執行緒2對stop變數的更改,因此還會一直迴圈下去。
但是用volatile修飾之後就變得不一樣了:
第一:使用volatile關鍵字會強制將修改的值立即寫入主存;
第二:使用volatile關鍵字的話,當執行緒2進行修改時,會導致執行緒1的工作記憶體中快取變數stop的快取行無效(反映到硬體層的話,就是CPU的L1或者L2快取中對應的快取行無效);
第三:由於執行緒1的工作記憶體中快取變數stop的快取行無效,所以執行緒1再次讀取變數stop的值時會去主存讀取。
那麼線上程2修改stop值時(當然這裡包括2個操作,修改執行緒2工作記憶體中的值,然後將修改後的值寫入記憶體),會使得執行緒1的工作記憶體中快取變數stop的快取行無效,然後執行緒1讀取時,發現自己的快取行無效,它會等待快取行對應的主存地址被更新之後,然後去對應的主存讀取最新的值。
8.下面答案中a,b結果正確的是 C
StringBuffer stringBuffer1 = new StringBuffer("abc");
StringBuffer stringBuffer2 = new StringBuffer("abc");
boolean a = (stringBuffer1.equals(stringBuffer2));
String empA = new String("abc");
String empB = new String("abc");
boolean b = (empA == empB)
A. true false B.true true C.false false D.false true
解析:
String:http://www.cnblogs.com/timecloud/p/6555868.html
9.下列不是Junit4支援的斷言方法的是
A.assertNotNull() B.assertEquals() C.assertRight() D.assertSame()
10.為了程式設計需要現需自己編寫一個異常類。一般來說,下面那個最為合適
A.class myClass extends Exception{... B.class myException extends Error{..
C.class myException extends RuntimeException{... D.class myException extends Exception{..
11.以下說法錯誤的有
A.在任何情況下都必須使用邊界值分析方法,經驗表明用這種方法設計出測試用例發現程式錯誤的能力最強
B.必要時用等價類劃分方法補充一些測試用例
C.對照程式邏輯,檢查已設計出的測試用例的邏輯覆蓋程度,如果沒有達到要求的覆蓋標準,應當再補充足夠的測試用例
D.如果程式的功能說明中含有輸入條件的組合情況,則一開始就可選用錯誤推測法
12.執行下列程式碼後,哪個結論是正確的String[] s = new String[10];
A.s[10]為"" B.s[9]為0 C.s[0]為未定義 D.s.length為10
13.在下述程式中,判斷i>j共執行的次數是
public static void main(String [] args){
int i=0,j=10,k=2,s=0;
for(;;){
i+=k;
if(i>j){
System.out.println(s);
break;
}
S+=i;
}
}
A.4 B.7 C.5 D.6
14.下列關於繼承的哪項敘述是正確的
A.在Java中允許多重繼承 B.在java中一個類只能實現一個介面
C.在java中一個類不能同時繼承一個類和實現一個介面 D.java的單一繼承使程式碼更可靠
15.執行緒的生命週期中正確的狀態是
A.新建狀態、執行狀態、和終止狀態
B.新建狀態、執行狀態、阻塞狀態和終止狀態
C.新建狀態、可執行狀態、執行狀態、阻塞狀態和終止狀態
D.新建狀態、可執行狀態、執行狀態、恢復狀態和終止狀態
解析:1.執行緒的生命週期
執行緒是一個動態執行的過程,它也有一個從產生到死亡的過程。
(1)生命週期的五種狀態
新建(new Thread)
當建立Thread類的一個例項(物件)時,此執行緒進入新建狀態(未被啟動)。
例如:Thread t1=new Thread();
就緒(runnable)
執行緒已經被啟動,正在等待被分配給CPU時間片,也就是說此時執行緒正在就緒佇列中排隊等候得到CPU資源。例如:t1.start();
執行(running)
執行緒獲得CPU資源正在執行任務(run()方法),此時除非此執行緒自動放棄CPU資源或者有優先順序更高的執行緒進入,執行緒將一直執行到結束。
死亡(dead)
當執行緒執行完畢或被其它執行緒殺死,執行緒就進入死亡狀態,這時執行緒不可能再進入就緒狀態等待執行。
自然終止:正常執行run()方法後終止
異常終止:呼叫stop()方法讓一個執行緒終止執行
堵塞(blocked)
由於某種原因導致正在執行的執行緒讓出CPU並暫停自己的執行,即進入堵塞狀態。
正在睡眠:用sleep(long t) 方法可使執行緒進入睡眠方式。一個睡眠著的執行緒在指定的時間過去可進入就緒狀態。
正在等待:呼叫wait()方法。(呼叫motify()方法回到就緒狀態)
被另一個執行緒所阻塞:呼叫suspend()方法。(呼叫resume()方法恢復)
2.常用方法
void run() 建立該類的子類時必須實現的方法
void start() 開啟執行緒的方法
static void sleep(long t) 釋放CPU的執行權,不釋放鎖
static void sleep(long millis,int nanos)
final void wait()釋放CPU的執行權,釋放鎖
final void notify()
static void yied()可以對當前執行緒進行臨時暫停(讓執行緒將資源釋放出來)
3.(1)結束執行緒原理:就是讓run方法結束。而run方法中通常會定義迴圈結構,所以只要控制住迴圈即可
(2)方法----可以boolean標記的形式完成,只要在某一情況下將標記改變,讓迴圈停止即可讓執行緒結束
(3)public final void join()//讓執行緒加入執行,執行某一執行緒join方法的執行緒會被凍結,等待某一執行緒執行結束,該執行緒才會恢復到可執行狀態
4. 臨界資源:多個執行緒間共享的資料稱為臨界資源
(1)互斥鎖
a.每個物件都對應於一個可稱為“互斥鎖”的標記,這個標記用來保證在任一時刻,只能有一個執行緒訪問該物件。
b.Java物件預設是可以被多個執行緒共用的,只是在需要時才啟動“互斥鎖”機制,成為專用物件。
c.關鍵字synchronized用來與物件的互斥鎖聯絡
d.當某個物件用synchronized修飾時,表明該物件已啟動“互斥鎖”機制,在任一時刻只能由一個執行緒訪問,即使該執行緒出現堵塞,該物件的被鎖定狀態也不會解除,其他執行緒任不能訪問該物件。
二、填空題
1,每個java應用程式都要有且只有一個__方法它是程式開始的執行點
2,ORM的全稱是__,常見的ORM框架有__,__(至少兩個) 解析:Entity EJB、Hibernate、IBATIS、TopLink、OJB
3,如果要在程式中使用鍵盤輸入語句,則需要預先匯入__包
4,在MVC中,M是模型,V是__,C是__
5,面向物件的三大基本特徵是抽象和__、繼承、__
6,java語言中,有一個類是所有類或介面的父類,這個類的名稱是__
7,在面向物件概念中,每一個物件都是由__,__兩個基本的部分組成的
8,關鍵字__是用來定義介面的,使用關鍵字__來定義某個類實現了介面
9,__語句可以終止當前一輪的迴圈,不再執行其下面的語句,直接進入下一輪的迴圈,__語句可以使程式從一個語句體的內部跳出去,繼續執行該語句體下面的語句
三、分析題
1、當一個物件被當作引數傳遞到一個方法後,此方法可改變這個物件的屬性,並可返回變化後的結果,那麼這裡到底是值傳遞還是引用傳遞?為什麼?
值傳遞,無論傳遞的是基本資料型別還是引用資料型別,都是傳遞的值或引用物件的地址的副本,最終仍然是值傳遞
2、給定下列程式碼:
public void test(){
try{
oneMethod();
System.out.println("condition 1");
return;
}catch(ArrayIndexOutofBoundException e){
System.out.println("condition 2");
}catch(Exception e){
System.out.println("condition 3");
}finally{
System.out.println("finally");
}
}
在方法oneMethod()執行正常的情況下程式執行的流程是什麼?
3、要求:書寫程式,寫一個JDBC程式連線資料庫,寫出連線資料庫的步驟和關鍵程式碼,並查詢所有資料列印。資料庫名為test,表名為users,有欄位id,username,password ,採用Mysql資料庫(資料庫名與密碼均為root)
連線資料庫的步驟:
1、註冊驅動(只做一次)
2、建立連線(Connection)
3、建立執行SQL的語句(Statement)
4、執行語句
5、處理執行結果(ResultSet)
6、釋放資源
PreparedStatement preparedStatement = null;
Connection conn = null;
Try{
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://192.168.101.44:3306/test";
String url = "jdbc:oracle:thin:@192.168.8.1:1521:test";
String user = "root";
String password = "root";
//連線到具體的資料庫
conn = DriverManager.getConnection(url, user, password);
String sql = "select id,username,password from users";
preparedStatement = conn.prepareStatement(sql);
}catch(Exception e){
e.printStackTrace();
}finally{
conn.close();
}
四、論述題
1、簡述Rest及其實現框架和作用:
http://blog.csdn.net/cws1214/article/details/52190659
Rest風格:REST 本質上是使用 URL 來訪問資源的一種方式,前後端分離(ajax/json)
“無狀態”的架構模式:任何時候都可以由客戶端發出請求到服務端,最終返回自己想要的資料,當前請求不會受到上次請求的影響。一種“輕量級”的 SOA(面向服務)實現技術
強調HTTP應當以資源為中心,並且規範了資源URI的風格;
規範了HTTP請求動作(PUT,POST等)的使用,具有對應的語義
好處:
URL具有很強可讀性的,具有自描述性;
資源描述與檢視的鬆耦合;
可提供OpenAPI,便於第三方系統整合,提高互操作性;
如果提供無狀態的服務介面,可提高應用的水平擴充套件性;
統一響應結構:使用Rest實現前後端分離,首先保證統一的json資料結構包含兩部分:元資料 與 返回值
實現物件序列化:在服務端從資料庫中獲取普通的 Java 物件資料,然後需要將這個 Java 物件轉換為 JSON 字串,並將其返回到瀏覽器中進行渲染,這個轉換過程稱為序列化;再比如,通過瀏覽器傳送了一個普通的 HTTP 請求,該請求攜帶了一個 JSON 格式的引數,在服務端需要將該 JSON 引數轉換為普通的 Java 物件,這個轉換過程稱為 反序列化。@RequestBody、@RestController
處理異常行為:編寫一個全域性的異常處理切面類,用它來統一處理所有的異常行為
支援引數驗證:建議將其引數驗證行為從 Controller 中剝離出來,放到另外的類中,通過Hibernate Validator 框架實現
解決跨域問題:整個架構包含兩個應用,前端應用提供純靜態的 HTML 頁面,後端應用釋出 REST API,前端需要通過 AJAX 呼叫後端釋出的 REST API,然而 AJAX 是不支援跨域訪問的。CORS 全稱為 Cross Origin Resource Sharing(跨域資源共享),服務端只需新增相關響應頭資訊,即可實現客戶端發出 AJAX 跨域請求。
提供安全機制:
當用戶登入成功後,在服務端生成一個 token,並將其放入記憶體中(可放入 JVM 或 Redis 中),同時將該 token 返回到客戶端。
在客戶端中將返回的 token 寫入 cookie 中,並且每次請求時都將 token 隨請求頭一起傳送到服務端。
提供一個 AOP 切面,用於攔截所有的 Controller 方法,在切面中判斷 token 的有效性。
當登出時,只需清理掉 cookie 中的 token 即可,服務端 token 可設定過期時間,使其自行移除。
2、簡述Spring的AOP和IOC
spring 的優點?
1.降低了元件之間的耦合性 ,實現了軟體各層之間的解耦
2.可以使用容易提供的眾多服務,如事務管理,訊息服務等
3.容器提供單例模式支援
4.容器提供了AOP技術,利用它很容易實現如許可權攔截,執行期監控等功能
5.容器提供了眾多的輔助類,能加快應用的開發
6.spring對於主流的應用框架提供了整合支援,如hibernate,JPA,Struts等
7.spring屬於低侵入式設計,程式碼的汙染極低
8.獨立於各種應用伺服器
9.spring的DI機制降低了業務物件替換的複雜性
10.Spring的高度開放性,並不強制應用完全依賴於Spring,開發者可以自由選擇spring的部分或全部
什麼是DI機制?
依賴注入(Dependecy Injection)和控制反轉(Inversion of Control)是同一個概念,具體的講:當某個角色需要另外一個角色協助的時候,在傳統的程式設計過程中,通常由呼叫者來建立被呼叫者的例項。但在spring中建立被呼叫者的工作不再由呼叫者來完成,因此稱為控制反轉。建立被呼叫者的工作由spring來完成,然後注入呼叫者
因此也稱為依賴注入。
spring以動態靈活的方式來管理物件 , 注入的兩種方式,設定注入和構造注入。
設定注入的優點:直觀,自然
構造注入的優點:可以在構造器中決定依賴關係的順序。
什麼是AOP?
面向切面程式設計(AOP)完善spring的依賴注入(DI),面向切面程式設計在spring中主要表現為兩個方面
1.面向切面程式設計提供宣告式事務管理
2.spring支援使用者自定義的切面
面向切面程式設計(aop)是對面向物件程式設計(oop)的補充,
面向物件程式設計將程式分解成各個層次的物件,面向切面程式設計將程式執行過程分解成各個切面。
AOP從程式執行角度考慮程式的結構,提取業務處理過程的切面,oop是靜態的抽象,aop是動態的抽象,
是對應用執行過程中的步驟進行抽象,,從而獲得步驟之間的邏輯劃分。
aop框架具有的兩個特徵:
1.各個步驟之間的良好隔離性
2.原始碼無關性
Spring的事務管理機制實現的原理,就是通過這樣一個動態代理對所有需要事務管理的Bean進行載入,並根據配置在invoke方法中對當前呼叫的 方法名進行判定,並在method.invoke方法前後為其加上合適的事務管理程式碼,這樣就實現了Spring式的事務管理。Spring中的AOP實 現更為複雜和靈活,不過基本原理是一致的。
3、簡述一下JVM中的垃圾回收機制
GC通過確定物件是否被活動物件引用來確定是否收集該物件。
2.1 觸發GC(Garbage Collector)的條件
1)GC在優先順序最低的執行緒中執行,一般在應用程式空閒即沒有應用執行緒在執行時被呼叫。但下面的條件例外。
2)Java堆記憶體不足時,GC會被呼叫。當應用執行緒在執行,並在執行過程中建立新物件,若這時記憶體空間不足,JVM就會強制呼叫GC執行緒。若GC一次之後仍不能滿足記憶體分配,JVM會再進行兩次GC,若仍無法滿足要求,則JVM將報“out of memory”的錯誤,Java應用將停止。
2.2 兩個重要方法
2.2.1 System.gc()方法
使用System.gc()可以不管JVM使用的是哪一種垃圾回收的演算法,都可以請求Java的垃圾回收。在命令列中有一個引數-verbosegc可以檢視Java使用的堆記憶體的情況,它的格式如下:java -verbosegc classfile 由於這種方法會影響系統性能,不推薦使用,所以不詳訴。
2.2.2 finalize()方法
在JVM垃圾回收器收集一個物件之前,一般要求程式呼叫適當的方法釋放資源,但在沒有明確釋放資源的情況下,Java提供了預設機制來終止該物件心釋放資源,這個方法就是finalize()。它的原型為:protected void finalize() throws Throwable 在finalize()方法返回之後,物件消失,垃圾收集開始執行。原型中的throws Throwable表示它可以丟擲任何型別的異常。
之所以要使用finalize(),是存在著垃圾回收器不能處理的特殊情況。例如:1)由於在分配記憶體的時候可能採用了類似 C語言的做法,而非JAVA的通常new做法。這種情況主要發生在native method中,比如native method呼叫了C/C++方法malloc()函式系列來分配儲存空間,但是除非呼叫free()函式,否則這些記憶體空間將不會得到釋放,那麼這個時候就可能造成記憶體洩漏。但是由於free()方法是在C/C++中的函式,所以finalize()中可以用本地方法來呼叫它。以釋放這些“特殊”的記憶體空間。2)又或者開啟的檔案資源,這些資源不屬於垃圾回收器的回收範圍。
2.3 減少GC開銷的措施
1)不要顯式呼叫System.gc()。此函式建議JVM進行主GC,雖然只是建議而非一定,但很多情況下它會觸發主GC,從而增加主GC的頻率,也即增加了間歇性停頓的次數。大大的影響系統性能。
2)儘量減少臨時物件的使用。臨時物件在跳出函式呼叫後,會成為垃圾,少用臨時變數就相當於減少了垃圾的產生,從而延長了出現上述第二個觸發條件出現的時間,減少了主GC的機會。
3)物件不用時最好顯式置為Null。一般而言,為Null的物件都會被作為垃圾處理,所以將不用的物件顯式地設為Null,有利於GC收集器判定垃圾,從而提高了GC的效率。
4)儘量使用StringBuffer,而不用String來累加字串。由於String是固定長的字串物件,累加String物件時,並非在一個String物件中擴增,而是重新建立新的String物件,如Str5=Str1+Str2+Str3+Str4,這條語句執行過程中會產生多個垃圾物件,因為對次作“+”操作時都必須建立新的String物件,但這些過渡物件對系統來說是沒有實際意義的,只會增加更多的垃圾。避免這種情況可以改用StringBuffer來累加字串,因StringBuffer是可變長的,它在原有基礎上進行擴增,不會產生中間物件。
5)能用基本型別如Int,Long,就不用Integer,Long物件。基本型別變數佔用的記憶體資源比相應物件佔用的少得多,如果沒有必要,最好使用基本變數。
6)儘量少用靜態物件變數。靜態變數屬於全域性變數,不會被GC回收,它們會一直佔用記憶體。
7)分散物件建立或刪除的時間。集中在短時間內大量建立新物件,特別是大物件,會導致突然需要大量記憶體,JVM在面臨這種情況時,只能進行主GC,以回收記憶體或整合記憶體碎片,從而增加主GC的頻率。集中刪除物件,道理也是一樣的。它使得突然出現了大量的垃圾物件,空閒空間必然減少,從而大大增加了下一次建立新物件時強制主GC的機會。
4、簡述一下JVM的類載入機制
一、關鍵
使用反射獲取類的資訊
使用反射建立物件
使用反序列化訪問屬性和方法
使用Array動態建立和訪問陣列
二、反射概述
1、反射機制:
Java特性之一,是構建框架技術的基礎所在
Java反射機制是指在執行狀態中,動態獲取資訊以及動態呼叫物件方法的功能
使用反射可以在程式執行時建立類的例項以及訪問其屬性和方法
Java反射有3個動態性質:
執行時生成物件例項;
執行期間呼叫方法;
執行時更改屬性。
Java程式執行過程:如下所示,要想java程式可執行,java類必須被java虛擬機器載入。執行的程式都是在編譯時就已經載入了所需要的類。
Person.java --->編譯器--->Person.class--->java虛擬機器--->執行程式
反射執行過程:如下所示,Java反射機制在編譯時並不知道是哪個類被載入了,而是在程式執行時才載入、探知、使用。
Java反射 ?? --->編譯器<--- --->執行程式
Java反射機制能夠知道類的基本結構,這種對java類結構的探知能力叫做”自省”。如eclipse的java程式碼自動提示功能。
通過java反射可以實現以下功能:
在執行時判斷任意一個物件所屬的類;
在執行時構造任意一個類的物件;
在執行時判斷任意一個類所具有的方法和屬性;
在執行時呼叫任意一個物件的方法。
2、java反射常用API
使用java反射技術常用的類如下:
Class類:反射的核心類,反射的所有操作都是圍繞該類來生成的。通過Class類,可以獲得類的屬性、方法等內容資訊;
Field類:表示類的屬性,可以獲取和設定類中屬性的值;
Method類:表示類的方法,可以用來獲取類中方法的資訊,或者執行方法;
Constructor類:表示類的構造方法。
在java程式中使用反射的基本步驟如下:
1)匯入java.lang.reflect.*;
2)獲得需要操作的類的java.lang.Class物件;
3)呼叫Class的方法獲取Field、Method等物件;
4)使用反射API進行操作。
三、反射的應用
1、獲取類的資訊
通過反射獲取類的資訊分兩步:首先獲取Class物件,然後通過Class物件獲取資訊
1)獲取Class物件
每個類被載入後,系統就會為該類生成一個Class物件,通過該Class物件就可以訪問到Java虛擬機器中的這個類。
Java程式中獲得Class物件通常有以下3種方式:
① 呼叫物件的getClass()
getClass()方法是Object中的一個方法,所有java物件都可呼叫該方法,該方法會返回該物件所屬類對應的Class物件
Student stu = new Student();
Class class = stu.getClass();
② 呼叫類的class屬性
呼叫某個類的class屬性可獲取該類對應的Class屬性,這種方式需在編譯器就知道類名。
Class class = Student.class;
③ 使用Class類的forName()靜態方法
使用Class類的forName()靜態方法也可獲取該類對應的Class屬性。該方式需傳入字串引數,該引數值是某個類的全名(完整報名+類名),否則會拋ClassNotFoundException
Class class = Class.forName(“com.vnb.test.Student”);
後兩種方式都是根據類來獲取該類對應的Class屬性,而通過呼叫某個類的class屬性來獲取對應的Class物件這種方式更有優勢,原因如以下兩點:
程式碼更安全,程式在編譯階段就可以檢查需要訪問的Class物件是否存在;
無需呼叫方法,程式效能更高。
2)從Class物件獲取資訊
① 訪問Class對應的類所包含的構造方法
getConstructors()/getDeclaredConstructors()
② 訪問Class對應的類所包含的方法
getMethods()/getDeclaredMethods()
③ 訪問Class對應的類所包含的屬性
getFields()/getDeclaredFields()
④ 訪問Class對應的類所包含的註釋
getAnnotations()/getDeclaredAnnotations()
⑤ 訪問Class對應的類的其他資訊
內部類、外部類、全部介面、所有修飾符、此類的包、類名、類的簡稱、該類超類的Class物件
Method、Contructor、Field這3個類都定義在java.lang.reflect包下,並實現了java.lang.reflect.Member介面,程式可以通過Method來執行對應的方法,通過Constructor來呼叫對應的構造方法建立物件,通過Field物件直接訪問並修改物件的屬性值。
2、建立物件
通過反射來建立物件有如下兩種方式:
(1)使用Class物件的newInstance()方法建立物件
要求該Class物件對應的類有預設的構造方法,而執行newInstance()實際上是利用預設的構造方法來建立該類的例項
Class class = Date.class;
Date date = (Date)class.newInstance();
(2)使用Constructor物件建立物件
要先使用Class物件,獲取指定的Constructor物件,再用Constructor物件的newInstance()來建立物件對應類的例項。通過這種方式可以選擇使用某個類的指定構造方法來建立例項
Class class = Date.class;
Constructor con = class.getConstructor(long.class);
Date date = (Date con .newInstance(1987);
3、訪問類的屬性
使用Field物件獲取物件的屬性。並通過Field物件可以對屬性進行取值或賦值操作
如:class Student{
Private String name;
Private int age;
}
Pubic class Test(){
Student p = new Student();
Class cla = Student.class;
}
//使用getDeclaredField()可獲取各種訪問修飾符級別的屬性
Field nameField = cla.getDeclaredField(“name”);
//設定通過反射訪問該Field時取消許可權檢查
nameField.setAccessible(true);
//通過set()為Student物件設定Field值
nameField.set(p,”Jack”);
4、訪問類的方法
使用Method物件可以呼叫物件的方法。在Method類中包含一個invoke()方法,定義如下:
Object invoke(Object obj,Object args);
Obj是執行該方法的物件;args是執行該方法傳的引數
例:
class Student{
Private String name;
Private int age;
Public void setName(String name){this.name = name}
}
Pubic class Test(){
Class cla = Student.class;
Student p = new Student();
//得到setName()方法
Method met = cla.getMethod(“setName”,String.class);
//呼叫setName()方法,為name賦值
Met.invoke(p,”Jack”);
}
若Student類中setName()方法設定訪問修飾符為私有,則會拋NoSuchMethodException;這是由於Method的invoke()方法要求必須擁有對應的方法訪問許可權,若沒有可使用setAccessible()設定,true表取消許可權檢查,false表使用許可權檢查
5、使用Array類動態建立和訪問陣列
Java.lang.reflect包下有一個Array類,該類物件可以代表所有的陣列。程式可以通過使用Array類來動態的建立陣列、運算元組元素等。
//建立陣列,型別為String,長度10
Object arr = Array.newInstance(String.class,10);
Array.set(arr,5,”Jack”);
Array.get(arr,5);
四、總結
使用反射機制開發程式碼靈活性強,但不能亂用,因為通過反射機制建立物件效能稍低。
實際上,反射機制只有在程式需要動態建立某個類的物件時才會考慮使用
通常在開發通用性比較廣、基礎平臺時才會大量使用。因為很多java框架中都需要根據配置檔案來建立java物件,從配置檔案讀取的只是某個類的字串類名,程式需要根據字串類名來建立java物件就必須使用反射機制
實際開發中沒必要使用反射來訪問已知的類的屬性和方法,只有在程式需要動態建立某個類的物件時才會考慮使用。例如,從配置檔案中讀取以字串形式表示的類時,就需要用反射來獲取它的方法和屬性
5、請介紹一下Junit4.4 Test Class 的生命週期
6、Junit中@Rule註解是什麼意思?如何用@Test測試異常?如果一個Junit測試方法的返回型別為String,那麼將會發生什麼?
面試題
1、你們這個專案中,安全性是怎麼解決的
引數過濾
cookies 安全設定
HttpOnly 主要是為了限制web頁面程式的瀏覽器端script程式讀取cookie
在web.xml 中配置
<session-config>
<cookie-config>
<http-only>true</http-only>
</cookie-config>
<session-timeout>1200</session-timeout>
</session-config>
在tomcat 中的server.xml 中配置
<Context path="" docBase="" useHttpOnly="true" />
http方法訪問方式設定
WebDAV (Web-based Distributed Authoring and Versioning)是基於 HTTP 1.1 的一個通訊協議。它為 HTTP 1.1 添加了一些擴充套件(就是在 GET、POST、HEAD 等幾個 HTTP 標準方法以外添加了一些新的方法)
,使得應用程式可以直接將檔案寫到 Web Server 上,並且在寫檔案時候可以對檔案加鎖,寫完後對檔案解鎖,還可以支援對檔案所做的版本控制。這個協議的出現極大地增加了 Web 作為一種創作媒體對於我們的價值。基於 WebDAV 可以實現一個功能強大的內容管理系統或者配置管理系統。
弱口令漏洞
解決方案:最好使用至少6位的數字、字母及特殊字元組合作為密碼。資料庫不要儲存明文密碼,應儲存MD5加密後的密文,由於目前普通的MD5加密已經可以被破解,最好可以多重MD5加密,或者多種加密方式疊加組合
未使用使用者名稱及密碼登入後臺可直接輸入後臺URL登入系統。
解決方案:通過配置filter來過濾掉無效使用者的連線請求
JSP頁面丟擲的異常可能暴露程式資訊。有經驗的入侵者,可以從JSP程式的異常中獲取很多資訊,比如程式的部分架構、程式的物理路徑、SQL注入爆出來的資訊等。
解決方案:自定義一個Exception,將異常資訊包裝起來不要拋到頁面上
合法使用者“登出”後,在未關閉瀏覽器的情況下,點選瀏覽器“後退”按鈕,可從本地頁面快取中讀取資料,繞過了服務端filter過濾。
解決方案:配置filter對存放敏感資訊的頁面限制頁面快取
SQL注入漏洞
檔案上傳漏洞。前臺僅使用JS對檔案字尾做了過濾,這隻能針對普通的使用者,而惡意攻擊者完全可以修改表單去掉JS校驗。
解決方案:前臺JS過濾加伺服器端程式過濾。具體過濾掉哪些檔案型別視具體情況而定
Java WEB容器預設配置漏洞。如TOMCAT後臺管理漏洞,預設使用者名稱及密碼登入後可直接上傳war檔案獲取webshell。
解決方案:最好刪除,如需要使用它來管理維護,可更改其預設路徑,口令及密碼。
日誌,建議增加服務的訪問日誌,記錄來訪者的 IP ,傳遞引數,對後臺操作使用者建立日誌,記錄其操作內容。完善的日誌記錄可以幫助你發現潛在的危險,找到已經發生的問題。
2、前端以什麼方式傳送請求的
3、請問你們安徽高速專案的場景就是什麼
4、在你們的無跳轉支付(token版)中,token的使用場景和作用是什麼
5、Tomcat 和 Weblogic 的區別是什麼
Tomcat和Weblogic的相同點:
Tomcat是Apache基金會提供的Servlet容器,它支援JSP, Servlet和JDBC等J2EE關鍵技術,所以使用者可以用Tomcat開發基於資料庫,Servlet和JSP頁面的Web應用。
Tomcat和Weblogic的不同點:
功能性:
Tomcat不是EJB容器;也就是說,Tomcat不支援J2EE的重要技術之一,EJB。那麼,使用EJB元件開發的Web應用程式就無法在Tomcat下面執行。眾所周知,EJB是分散式應用程式的核心技術,所以說凡是需要使用EJB來開發的應用(例如,銀行、電信等大型的分散式應用系統)就不能用Tomcat了。webLogic可以進行EJB釋出、jndi資料來源的配置;可以進行設定實現日誌管理,記憶體管理,資源配置管理;通過有限的資訊查詢故障,排除故障,但Tomcat卻不能;
擴充套件性:
用WebLogic執行標準的java可能並不是最好的方式,WebLogic裡支援他自己的一些東西,這些東西雖然是在純java基礎上開發的,但其他工具裡都沒有。WebLogic Server憑藉其出色的群集技術,擁有處理關鍵Web應用系統問題所需的效能、可擴充套件性和高可用性。WebLogic Server既實現了網頁群集,也實現了EJB元件群集,而且不需要任何專門的硬體或作業系統支援。網頁群集可以實現透明的複製、負載平衡以及表示內容容錯 。
無論是網頁群集,還是元件群集,對於電子商務解決方案所要求的可擴充套件性和可用性都是至關重要的。共享的客戶機/伺服器和資料庫連線以及資料快取和EJB都增強了效能表現。這是其它Web應用系統所不具備的。所以,在擴充套件性方面WebLogic是遠遠超越了Tomcat。
費用上:
Tomcat開源免費,WebLogic不開源不免費。
6、weblogic的熱部署是怎麼實現的(你們怎麼在weblogic啟動的情況下去修改檔案的)
Weblogic的控制檯中有如下三個配置的頁面:
servlet-reload-check-secs:是否執行 servlet檢查,-1永不檢查(生產環境預設),0總是檢查,1每秒檢查(開發環境中的預設值)
resource-reload-check-secs: Web應用程式範圍內資源路徑中發現的快取資源執行元資料快取:-1 表示元資料進行快取,但從不對磁碟進行檢查;0 表示不執行元資料快取。持續更改檔案的客戶必須將該引數設定為大於或等於 0的一個值;1 表示每秒重新載入一次。該值為開發環境中的預設值
JSP page-check-seconds:檢視 JSP檔案是否已更改:-1 表示永不檢查頁面。該值為生產環境中的預設值。 值 0 表示總是檢查頁面。 值 1 表示每秒檢查一次頁面。該值為開發環境中的預設值。
實現步驟:1:修改weblogic的啟動引數
使用domain中的startWebLogic.cmd來啟動weblogic的話,則在domain/bin下的setDomainEnv.cmd中將該引數配置上,在該檔案最後新增設定引數命令:set JAVA_OPTIONS=%JAVA_OPTIONS% -Dorg.apache.tapestry.disable-caching=true -Dorg.apache.tapestry.enable-reset-service=true
2、檢查weblogic.xml配置檔案,其中如果有:
<container-descriptor>
<servlet-reload-check-secs>0</servlet-reload-check-secs>
<resource-reload-check-secs>0</resource-reload-check-secs>
</container-descriptor>
<jsp-descriptor>
<jsp-param>
<param-name>pageCheckSeconds</param-name>
<param-value>0</param-value>
</jsp-param>
</jsp-descriptor>
請將上述數值都修改為0
3、配置Eclipse中的工程自動編譯
4、檢查ie選項中是否設定了每次訪問本頁時檢查最新
7、微信公眾號後臺系統怎麼去呼叫騰訊的介面的
配置微信公眾號平臺後臺地址;驗籤,加解密,加簽,封裝引數;呼叫介面
其他人面試題目:
1、springBoot知識:為什麼要使用這個技術,有哪些缺點,怎麼去避免
使用 Spring 專案引導頁面可以在幾秒構建一個專案方便對外輸出各種形式的服務,如 REST API、WebSocket、Web、Streaming、Tasks非常簡潔的安全策略整合支援關係資料庫和非關係資料庫支援執行期內嵌容器,如 Tomcat、Jetty強大的開發包,支援熱啟動自動管理依賴自帶應用監控支援各種 IED,如 IntelliJ IDEA 、NetBeans缺點是整合度較高,使用過程中不太容易瞭解底層。
感覺Spring Boot 比較適合做微服務,不適合做比較大型的專案
2、平時使用了哪些測試工具,怎麼進行測試,怎麼覆蓋全方位的測試案例
Loaderrunner,jmeter
3、linux作業系統
4、mybatis動態sql語句的形成、mybatis快取、mybatis怎麼做分頁
mybatis動態sql語句的形成:sqlBuilder、各種xml配置標籤 if where select等
MyBatis 提供了查詢快取來快取資料,以提高查詢的效能。MyBatis