中移在線:一面問題及答案(提問內容:java基礎,框架,數據庫)沒有提問計算機網絡

基礎部分:

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.讀過哪些技術上的書,讀了多少,有哪些收穫,詳細講一個?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章