基礎部分:
1.基本數據類型都有哪些?
2.訪問修飾符有哪些?
private : 在同一類內可見。使用對象:變量、方法。 注意:不能修飾類(外部類)
default (即缺省,什麼也不寫,不使用任何關鍵字): 在同一包內可見,不使用任何修飾符。使用對象:類、接口、變量、方法。
protected : 對同一包內的類和所有子類可見。使用對象:變量、方法。 注意:不能修飾類(外部類)。
public : 對所有類可見。使用對象:類、接口、變量、方法
3.講一下抽象類?
類:使用class關鍵字標識
抽象類:使用abstract關鍵字標識抽象類,使用extends關鍵字繼承抽象類
接口:使用interface關鍵字標識接口,使用implements關鍵字實現接口
抽象類和接口的對比:
抽象類是對類的抽象,是一種模板設計,接口是行爲的抽象,是一種行爲的規範。
相同點:
- 接口和抽象類都不能實例化
- 都位於繼承的頂端,用於被其他實現或繼承
- 都包含抽象方法,其子類都必須覆寫這些抽象方法
不同點:
普通類和抽象類有哪些區別?
- 普通類不能包含抽象方法,抽象類可以包含抽象方法。
- 抽象類不能直接實例化,普通類可以直接實例化。
4.講一下set集合?
Collection
|--List
有序(存儲順序和取出順序一致),可重複
|--Set
無序(存儲順序和取出順序不一致),唯一
HashSet:它不保證 set 的迭代順序;特別是它不保證該順序恆久不變。
注意:雖然Set集合的元素無序,但是,作爲集合來說,它肯定有它自己的存儲順序,
而你的順序恰好和它的存儲順序一致,這代表不了有序,你可以多存儲一些數據,就能看到效果。
Set集合中的對象不按特定的方式排序,並且沒有重複對象。是一個不可變集合,一旦定義內容和長度都不可變。
public class SetDemo {
public static void main(String[] args) {
Set<String> set = new HashSet<String>();
// 創建並添加元素
set.add("hello");
set.add("java");
set.add("world");
set.add("java");
set.add("world");
// 增強for
for (String s : set) {
System.out.println(s);
}
}
}
HashSet存儲字符串並遍歷
/*
* HashSet:存儲字符串並遍歷
* 問題:爲什麼存儲字符串的時候,字符串內容相同的只存儲了一個呢?
* 通過查看add方法的源碼,我們知道這個方法底層依賴 兩個方法:hashCode()和equals()。
* 步驟:
* 首先比較哈希值
* 如果相同,繼續走,比較地址值或者走equals()
* 如果不同,就直接添加到集合中
* 按照方法的步驟來說:
* 先看hashCode()值是否相同
* 相同:繼續走equals()方法
* 返回true: 說明元素重複,就不添加
* 返回false:說明元素不重複,就添加到集合
* 不同:就直接把元素添加到集合
* 如果類沒有重寫這兩個方法,默認使用的Object()。一般來說不同相同。
* 而String類重寫了hashCode()和equals()方法,所以,它就可以把內容相同的字符串去掉。只留下一個。
*/
public class HashSetDemo {
public static void main(String[] args) {
// 創建集合對象
HashSet<String> hs = new HashSet<String>();
// 創建並添加元素
hs.add("hello");
hs.add("world");
hs.add("java");
hs.add("world");
// 遍歷集合
for (String s : hs) {
System.out.println(s);
}
}
}
5.java反射機制?
JAVA反射機制是在運行狀態中:
1.對於任意一個類,都能夠知道這個類的所有屬性和方法;
2.對於任意一個對象,都能夠調用它的任意一個方法和屬性;
這種動態獲取的信息以及動態調用對象的方法的功能稱爲java語言的反射機制。
靜態編譯和動態編譯
- **靜態編譯:**在編譯時確定類型,綁定對象
- **動態編譯:**運行時確定類型,綁定對象
反射機制優缺點
- 優點: 運行期類型的判斷,動態加載類,提高代碼靈活度。
- 缺點: 性能瓶頸:反射相當於一系列解釋操作,通知 JVM 要做的事情,性能比直接的java代碼要慢很多。
Java獲取反射的三種方法
1.通過new對象實現反射機制 2.通過路徑實現反射機制 3.通過類名實現反射機制
6.如何處理空指針異常?(和異常處理)
由try-catch來處理:
- try語句出現異常後拋出異常
- catch接受異常進行處理
兩種解決異常的方法:
- 拋出的異常誰來處理呢,異常拋出到最後如果最終被catch且沒有再被拋出,那麼就是catch捕捉處理;
- 如果最終狀態還是被拋出的話,由系統自己處理:程序中斷。
jvm虛擬機:
7.垃圾回收?
運行時自身會運行相應的垃圾回收機制。程序員只需要申請內存,而不需要關注內存的釋放。垃圾回收器(GC)會在適當的時候將已經終止生命週期的變量的內存給釋放掉。GC的優點就在於它大大簡化了應用層開發的複雜度,降低了內存泄露的風險。
垃圾回收器的基本原理是什麼?
通常,GC採用有向圖的方式記錄和管理堆(heap)中的所有對象。通過這種方式確定哪些對象是"可達的",哪些對象是"不可達的"。當GC確定一些對象爲"不可達"時,GC就有責任回收這些內存空間。
怎麼判斷對象是否可以被回收?
一般有兩種方法來判斷:
11.引用計數器法: 爲每個對象創建一個引用計數,有對象引用時計數器 +1,引用被釋放時計數 -1,當計數器爲 0 時就可以被回收。它有一個缺點不能解決循環引用的問題;
12.可達性分析算法:從 GC Roots 開始向下搜索,搜索所走過的路徑稱爲引用鏈。當一個對象到 GC Roots 沒有任何引用鏈相連時,則證明此對象是可以被回收的。
說一下 JVM 有哪些垃圾回收算法?
- 標記-清除算法:標記無用對象,然後進行清除回收。缺點:效率不高,無法清除垃圾碎片。
- 複製算法:按照容量劃分二個大小相等的內存區域,當一塊用完的時候將活着的對象複製到另一塊上,然後再把已使用的內存空間一次清理掉。缺點:內存使用率不高,只有原來的一半。
- 標記-整理算法:標記無用對象,讓所有存活的對象都向一端移動,然後直接清除掉端邊界以外的內存。
- 分代算法:根據對象存活週期的不同將內存劃分爲幾塊,一般是新生代和老年代,新生代基本採用複製算法,老年代採用標記整理算法。
https://thinkwon.blog.csdn.net/article/details/104390752(垃圾回收算法)
servlet總結:
Servlet可以處理來自客戶端的HTTP請求,並生成響應返回給客戶端。
使用Servlet的基本流程如下:
客戶端通過HTTP提出請求。
Web服務器接受改請求並將其發給servlet。如果這個servlet尚未被加載,Web服務器將把它加載到Java虛擬機並且執行它。
Servlet將接收該HTTP請求執行某種處理。
Servlet將向Web服務器返回應答。
Web服務器將從servlet收到的應答發送給客戶端。
Servlet的優點:
1.可以移植性:
由於Servlet是用Java語言編寫的,因此它可以在不同的操作系統和服務器上移植。
2.安全:
Servlet也具有類型檢查特徵,並利用Java的垃圾收集和沒有指針的設計,使得Servlet避免了內存管理等問題。
3.高效:
Servlet加載執行後會常駐服務器內存中,當再次受到客戶端的請求時,服務器會產生新的線程而不是進程爲客戶端服務,這樣就提高了響應速度。
Servlet的生命週期:
Servlet的生命週期可以概括爲以下幾個階段:
1)當客戶端第一次請求Servlet時,Servlet被加載到內存中,容器會創建Servlet實例,並調用其init()方法進行初始化工作。
2)容器創建請求對象和響應對象,然後調用Servlet的service()方法爲客戶端提供服務。
3)當Servlet不再被需要時,容器調用Servlet的destory()方法將Servlet實例銷燬。
jdbc連接數據庫的六個步驟:
1、加載JDBC驅動程序:
在連接數據庫之前,首先要加載想要連接的數據庫的驅動到JVM(Java虛擬機),這通過java.lang.Class類的靜態方法forName(String className)實現。
例如:
try{//加載MySql的驅動類
Class.forName("com.mysql.jdbc.Driver") ;
}catch(ClassNotFoundException e){
System.out.println("找不到驅動程序類 ,加載驅動失敗!");
e.printStackTrace() ;
}
成功加載後,會將Driver類的實例註冊到DriverManager類中。
2、創建數據庫的連接
•要連接數據庫,需要向java.sql.DriverManager請求並獲得Connection對象,該對象就代表一個數據庫的連接。
•使用DriverManager的getConnectin(String url , String username , String password )方法傳入指定的欲連接的數據庫的路徑、數據庫的用戶名和密碼來獲得。
例如:
//連接MySql數據庫,用戶名和密碼都是root
String url = "jdbc:mysql://localhost:3306/test" ;
String username = "root" ;
String password = "root" ;
try{
Connection con = DriverManager.getConnection(url , username , password ) ;
}catch(SQLException se){
System.out.println("數據庫連接失敗!");
se.printStackTrace() ;
}
3、創建一個preparedStatement
•要執行SQL語句,必須獲得java.sql.Statement實例,Statement實例分爲以下3 種類型:
1、執行靜態SQL語句。通常通過Statement實例實現。
2、執行動態SQL語句。通常通過PreparedStatement實例實現。
3、執行數據庫存儲過程。通常通過CallableStatement實例實現。
•具體的實現方式:
Statement stmt = con.createStatement() ;
PreparedStatement pstmt = con.prepareStatement(sql) ;
CallableStatement cstmt = con.prepareCall("{CALL demoSp(? , ?)}") ;
4、執行SQL語句
•Statement接口提供了三種執行SQL語句的方法:executeQuery 、executeUpdate和execute
1、ResultSet executeQuery(String sqlString):執行查詢數據庫的SQL語句,返回一個結果集(ResultSet)對象。
2、int executeUpdate(String sqlString):用於執行INSERT、UPDATE或 DELETE語句以及SQL DDL語句,如:CREATE TABLE和DROP TABLE等
3、execute(sqlString):用於執行返回多個結果集、多個更新計數或二者組合的語句。
•具體實現的代碼:
ResultSet rs = stmt.executeQuery("SELECT * FROM ...") ;
int rows = stmt.executeUpdate("INSERT INTO ...") ;
boolean flag = stmt.execute(String sql) ;
5、遍歷結果集
兩種情況:
1、執行更新返回的是本次操作影響到的記錄數。
2、執行查詢返回的結果是一個ResultSet對象。
• ResultSet包含符合SQL語句中條件的所有行,並且它通過一套get方法提供了對這些
行中數據的訪問。
• 使用結果集(ResultSet)對象的訪問方法獲取數據:
while(rs.next()){
String name = rs.getString("name") ;
String pass = rs.getString(1) ; // 此方法比較高效
}
(列是從左到右編號的,並且從列1開始)
6、處理異常,關閉JDBC對象資源
•操作完成以後要把所有使用的JDBC對象全都關閉,以釋放JDBC資源,關閉順序和聲 明順序相反:
1、先關閉requestSet
2、再關閉preparedStatement
3、最後關閉連接對象connection
if(rs !=null){ // 關閉記錄集
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(stmt !=null){ // 關閉聲明
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn !=null){ // 關閉連接對象
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
框架:
8.講一下AOP和IOC?(AOP的兩種動態代理方式)
AOP,一般稱爲面向切面,作爲面向對象的一種補充,用於將那些與業務無關,但卻對多個對象產生影響的公共行爲和邏輯,抽取並封裝爲一個可重用的模塊,這個模塊被命名爲“切面”(Aspect),減少系統中的重複代碼,降低了模塊間的耦合度,同時提高了系統的可維護性。
例子: 可用於權限認證、日誌、事務處理,數據庫的鏈接,等。
AOP
AOP,一般稱爲面向切面,作爲面向對象的一種補充,用於將那些與業務無關,但卻對多個對象產生影響的公共行爲和邏輯,抽取並封裝爲一個可重用的模塊,這個模塊被命名爲“切面”(Aspect),減少系統中的重複代碼,降低了模塊間的耦合度,同時提高了系統的可維護性。可用於權限認證、日誌、事務處理。
AOP實現的關鍵在於 代理模式,AOP代理主要分爲靜態代理和動態代理。靜態代理的代表爲AspectJ;動態代理則以Spring AOP爲代表。
靜態代理和動態代理
(1)AspectJ是靜態代理的增強,所謂靜態代理,就是AOP框架會在編譯階段生成AOP代理類,因此也稱爲編譯時增強,他會在編譯階段將AspectJ(切面)織入到Java字節碼中,運行的時候就是增強之後的AOP對象。
(2)Spring AOP使用的動態代理,所謂的動態代理就是說AOP框架不會去修改字節碼,而是每次運行時在內存中臨時爲方法生成一個AOP對象,這個AOP對象包含了目標對象的全部方法,並且在特定的切點做了增強處理,並回調原對象的方法。
Spring AOP中的動態代理主要有兩種方式,JDK動態代理和CGLIB動態代理:
①JDK動態代理只提供接口的代理,不支持類的代理。核心InvocationHandler接口和Proxy類,InvocationHandler 通過invoke()方法反射來調用目標類中的代碼,動態地將橫切邏輯和業務編織在一起;接着,Proxy利用 InvocationHandler動態創建一個符合某一接口的的實例, 生成目標類的代理對象。
②如果代理類沒有實現 InvocationHandler 接口,那麼Spring AOP會選擇使用CGLIB來動態代理目標類。CGLIB(Code Generation Library),是一個代碼生成的類庫,可以在運行時動態的生成指定類的一個子類對象,並覆蓋其中特定方法並添加增強代碼,從而實現AOP。CGLIB是通過繼承的方式做的動態代理,因此如果某個類被標記爲final,那麼它是無法使用CGLIB做動態代理的。
IOC
(1)IOC就是控制反轉,是指創建對象的控制權的轉移,以前創建對象的主動權和時機是由自己把控的,而現在這種權力轉移到Spring容器中,並由容器根據配置文件去創建實例和管理各個實例之間的依賴關係。
(2)最直觀的表達就是,IOC讓對象的創建不用去new了,可以由spring自動生產,使用java的反射機制,根據配置文件在運行時動態的去創建對象以及管理對象,並調用對象的方法的。
(3)Spring的IOC有三種注入方式 :構造器注入、setter方法注入、根據註解注入。
9.mybatis裏面的#{}和${}的區別?
#{}是預編譯處理,${}是字符串替換。
Mybatis在處理#{}時,會將sql中的#{}替換爲?號,調用PreparedStatement的set方法來賦值;
Mybatis在處理${}時,就是把${}替換成變量的值。
使用#{}可以有效的防止SQL注入,提高系統安全性。
網絡編程:
10.講一下session和cookie的區別?
什麼是cookie
cookie是由Web服務器保存在用戶瀏覽器上的小文件(key-value格式),包含用戶相關的信息。客戶端向服務器發起請求,如果服務器需要記錄該用戶狀態,就使用response向客戶端瀏覽器頒發一個Cookie。客戶端瀏覽器會把Cookie保存起來。當瀏覽器再請求該網站時,瀏覽器把請求的網址連同該Cookie一同提交給服務器。服務器檢查該Cookie,以此來辨認用戶身份。
什麼是session
session是依賴Cookie實現的。session是服務器端對象
session 是瀏覽器和服務器會話過程中,服務器分配的一塊儲存空間。服務器默認爲瀏覽器在cookie中設置 sessionid,瀏覽器在向服務器請求過程中傳輸 cookie 包含 sessionid ,服務器根據 sessionid 獲取出會話中存儲的信息,然後確定會話的身份信息。
cookie與session區別
- 存儲位置與安全性:cookie數據存放在客戶端上,安全性較差,session數據放在服務器上,安全性相對更高;
- 存儲空間:單個cookie保存的數據不能超過4K,很多瀏覽器都限制一個站點最多保存20個cookie,session無此限制
- 佔用服務器資源:session一定時間內保存在服務器上,當訪問增多,佔用服務器性能,考慮到服務器性能方面,應當使用cookie
數據庫:
11.你瞭解過哪些數據庫,一次查詢兩個表?
SQL UNION 操作符
UNION 操作符用於合併兩個或多個 SELECT 語句的結果集。
請注意,UNION 內部的 SELECT 語句必須擁有相同數量的列。列也必須擁有相似的數據類型。同時,每條 SELECT 語句中的列的順序必須相同。
SQL UNION 語法
SELECT column_name(s) FROM table_name1
UNION
SELECT column_name(s) FROM table_name2
註釋:默認地,UNION 操作符選取不同的值。如果允許重複的值,請使用 UNION ALL。
SQL UNION ALL 語法
查詢多個表的不同列:
例子:
找出李某所借圖書的所有圖書的書名及借書日期。
SELECT
full_name,
book_name,
borrowdate
FROM
library,
borrow,
reader
WHERE
library.mastr_serial_number = borrow.mastr_serial_number
AND borrow.library_card_number = reader.library_card_number
AND full_name LIKE '李%'
非技術問題:
12.參加過哪些培訓?
13.用過哪些編譯器?
14.讀過哪些技術上的書,讀了多少,有哪些收穫,詳細講一個?