首頁 > 軟體

Java經典面試題最全彙總208道(五)

2023-01-18 14:00:55

前言 

短時間提升自己最快的手段就是背面試題,最近總結了Java常用的面試題,分享給大家,希望大家都能圓夢大廠,加油,我命由我不由天。

152、什麼是 YAML?

YAML是JSON的一個超集,可以非常方便地將外部設定以層次結構形式儲存起來。

YAML可以作為properties組態檔的替代。

YAML使用的注意事項:

  1. 在properties檔案中是以"."進行分割的,在yml中是用"."進行分割的;
  2. yml的資料格式和json的格式很像,都是K-V格式,並且通過":"進行賦值;
  3. 每個冒號後面一定要加一個空格;

153、如何使用 Spring Boot 實現分頁和排序?

使用Spring Data Jpa可以實現將可分頁的傳遞給儲存庫方法。

154、如何使用 Spring Boot 實現例外處理?

1、使用 @ExceptionHandler 註解處理區域性異常(只能處理當前controller中的ArithmeticException和NullPointerException異常,缺點就是隻能處理單個controller的異常)

@Controller
public class ExceptionHandlerController {
	
	@RequestMapping("/excep")
	public String exceptionMethod(Model model) throws Exception {
		String a=null;
		System.out.println(a.charAt(1));
		int num = 1/0;
		model.addAttribute("message", "沒有丟擲異常");
		return "index";
	}
 
	@ExceptionHandler(value = {ArithmeticException.class,NullPointerException.class})
	public String arithmeticExceptionHandle(Model model, Exception e) {
		model.addAttribute("message", "@ExceptionHandler" + e.getMessage());
		return "index";
	}
}

2、使用 @ControllerAdvice + @ExceptionHandler 註解處理全域性異常(value後面可以填寫陣列)

@ControllerAdvice
public class ControllerAdviceException {
	
	@ExceptionHandler(value = {NullPointerException.class})
	public String NullPointerExceptionHandler(Model model, Exception e) {
		model.addAttribute("message", "@ControllerAdvice + @ExceptionHandler :" + e.getMessage());
		return "index";
	}
}

3、設定 SimpleMappingExceptionResolver 類處理異常(設定類)

@Configuration
public class SimpleMappingException {
	@Bean
	public SimpleMappingExceptionResolver getSimpleMappingExceptionResolver(){
 
		SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver();
		Properties mappings = new Properties();
		//第一個引數為異常全限定名,第二個為跳轉檢視名稱
		mappings.put("java.lang.NullPointerException", "index");
		mappings.put("java.lang.ArithmeticException", "index");
		//設定異常與檢視對映資訊的
		resolver.setExceptionMappings(mappings);
		return resolver;
	}
}

4、實現 HandlerExceptionResolver 介面處理異常

@Configuration
public class HandlerException implements HandlerExceptionResolver {
	@Override
	public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
 
		ModelAndView modelAndView = new ModelAndView();
		modelAndView.addObject("message", "實現HandlerExceptionResolver介面");
 
		//判斷不同異常型別,做不同檢視跳轉
		if(ex instanceof NullPointerException){
			modelAndView.setViewName("index");
		}
		if(ex instanceof ArithmeticException){
			modelAndView.setViewName("index");
		}
		return modelAndView;
	}
}

155、單點登入

1、概念

單點登入SSO,說的是在一個多系統共存的環境下,使用者在一處登入後,就不用在其他系統中登入,也就是使用者的一次登入能得到其他所有系統的信任。

2、單點登入的要點

  • 儲存信任;
  • 驗證信任;

3、實現單點登入的三種方式

(1)以cookie作為憑證

最簡單的單點登入實現方式,是使用cookie作為媒介,存放使用者憑證。

使用者登入父應用之後,應用返回一個加密的cookie,當用戶存取子應用的時候,攜帶上這個cookie,授權應用解密cookie進行校驗,校驗通過則登入當前使用者。

缺點:

cookie不安全

通過加密可以保證安全性,但如果對方掌握瞭解密演演算法就完蛋了。

不能跨域實現免登

(2)通過JSONP實現

對於跨域問題,可以使用JSONP實現。使用者在父應用中登入後,跟session匹配的cookie會存到使用者端中,當用戶需要登入子應用的時候,授權應用存取父應用提供的JSONP介面,並在請求中帶上父應用域名下的cookie,父應用接收到請求,驗證使用者的登入狀態,返回加密的資訊,子應用通過解析返回來的加密資訊來驗證使用者,如果通過驗證則登入使用者。

缺點:

這種方法雖然能解決跨域問題,但是治標不治本,沒有解決cookie安全性的問題。

(3)通過頁面重定向的方式

最後一種介紹的方式,是通過父應用和子應用來回重定向進行通訊,實現資訊的安全傳遞。

父應用提供一個GET方式的登入介面A(此時的父應用介面固定,攻擊者無法去偽造),使用者通過子應用重定向連線的方式存取這個介面

如果使用者還沒有登入,則返回一個登入頁面,使用者輸入賬號密碼進行登入

如果使用者已經登入了,則生成加密的token,並且重定向到子應用提供的驗證token的介面B(此時的子應用介面固定,攻擊者無法去偽造)

通過解密和校驗之後,子應用登入當前使用者。

缺點:

這種方式較前面的兩種方式,是解決了安全性和跨域的問題,但是並沒有前面兩種方式簡單,安全與方便,本來就是矛盾的。

4、使用獨立登入系統

一般來說,大型應用會把授權的邏輯和使用者資訊的相關邏輯獨立成一個應用,稱為使用者中心。

使用者中心不處理業務邏輯,只是處理使用者資訊的管理以及授權給第三方應用。

第三方應用需要登入的時候,則把使用者的登入請求轉發給使用者中心進行處理,使用者處理完畢後返回憑證,第三方應用驗證憑證,通過後就登入使用者。

5、sso(單點登入)與OAuth2.0(授權)的區別?

(1)sso(單點登入)

  • 通常處理的是一個公司的不同應用間的存取登入問題,如企業應用有很多子系統,只需登入一個系統,就可以實現不同子系統間的跳轉,而避免了登入操作;
  • 通過cookie、jsonp、重定向來實現;

(2)OAuth2.0(授權)

解決的是服務提供方(如微信)給第三方應用授權的問題,簡稱微信登入;

是一種具體的協定,只是為使用者資源的授權提供了一個安全的、開放的而又簡易的標準,OAuth2.0(授權)為客戶開發者開發web應用,桌面應用程式,移動應用及客廳裝置提供特定的授權流程。

156、Spring Boot比Spring多哪些註解

Spring Boot常用註解(絕對經典)

157、打包和部署

Spring和Spring Boot都支援maven和Gradle通用打包管理技術。

Spring Boot相對Spring的一些優點:

  • 提供嵌入式容器支援;
  • 使用命令java -jar獨立執行jar;
  • 部署時可以靈活指定組態檔;

最近專案是分散式的專案,都是通過分專案打包部署,然後部署在docker中執行。

158、Spring Boot如何存取不同的資料庫

可以使用druidDataSource建立DataSource,然後通過jdbcTemplate執行sql。

159、查詢網站線上人數

通過監聽session物件的方式來實現線上人數的統計和線上人資訊展示,並且讓超時的自動銷燬。

對session物件實現監聽,首先必須繼承HttpSessionListener類,該程式的基本原理就是當瀏覽器存取頁面的時候必定會產生一個session物件,當關閉該頁面的時候必然會刪除session物件。

所以每當產生一個新的session物件就讓線上人數+1,當刪除一個session物件就讓線上人數-1。

還要繼承一個HttpSessionAttributeListener,來實現對其屬性的監聽。

分別實現attributeAdded方法,attributeReplace方法以及attributeRemove方法。

sessionCreated//新建一個對談的時候觸發,也可以說是使用者端第一次喝伺服器互動時觸發。

sessionDestroyed//銷燬對談的時候,一般來說只有某個按鈕觸發進行銷燬,或者設定定時銷燬。

HttpSessionAttributeListener有三個方法需要實現

attributeAdded//在session中新增物件時觸發此操作 籠統的說就是呼叫setAttribute這個方法時候會觸發的

attributeRemoved//修改、刪除session中新增物件時觸發此操作  籠統的說就是呼叫 removeAttribute這個方法時候會觸發的

attributeReplaced//在Session屬性被重新設定時。

160、easyExcel如何實現

非同步讀取

新建一個  ExcelModelListener 監聽類出來,並且 繼承 AnalysisEventListener 類

package com.zh.oukele.listener;
 
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.zh.oukele.model.ExcelMode;
 
import java.util.ArrayList;
import java.util.List;
 
/***
 *  監聽器
 */
public class ExcelModelListener extends AnalysisEventListener<ExcelMode> {
 
    /**
     * 每隔5條儲存資料庫,實際使用中可以3000條,然後清理list ,方便記憶體回收
     */
    private static final int BATCH_COUNT = 5;
    List<ExcelMode> list = new ArrayList<ExcelMode>();
    private static int count = 1;
    @Override
    public void invoke(ExcelMode data, AnalysisContext context) {
        System.out.println("解析到一條資料:{ "+ data.toString() +" }");
        list.add(data);
        count ++;
        if (list.size() >= BATCH_COUNT) {
            saveData( count );
            list.clear();
        }
    }
 
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        saveData( count );
        System.out.println("所有資料解析完成!");
        System.out.println(" count :" + count);
    }
 
    /**
     * 加上儲存資料庫
     */
    private void saveData(int count) {
        System.out.println("{ "+ count +" }條資料,開始儲存資料庫!" + list.size());
        System.out.println("儲存資料庫成功!");
    }
 
}

161、什麼是 Swagger?你用 Spring Boot 實現了它嗎?

Swagger是用於生成RestFul Web服務的視覺化表示工具,它使檔案和伺服器視覺化更新;

當定義好Swagger後,可以呼叫伺服器端介面,來檢視介面的返回值,驗證返回資料的正確性;

162、資料庫的三正規化是什麼?

1、列不可再分;

2、每一行資料只做一件事,只與一列相關,主鍵;

3、每個屬性都與主鍵有直接關係,而不是間接關係;

三大正規化只是設計資料庫的基本理念,可以建立冗餘較小、結構合理的資料庫。

如果有特殊情結,當然要特殊對待,資料庫設計最重要的是看需求和效能,需求>效能>表結構。

所以不能一味的追求三正規化建立資料庫。

163、一張自增表裡面總共有 7 條資料,刪除了最後 2 條資料,重啟 mysql 資料庫,又插入了一條資料,此時 id 是幾?

一般情況下,我們建立的表型別是InnoDB。

  • 不重啟MySQL,如果新增一條記錄,id是8;
  • 重啟,ID是6;因為InnoDB表只把自增主鍵的最大ID記錄在記憶體中,如果重啟,已刪除的最大ID會丟失。
  • 如果表型別是MyISAM,重啟之後,最大ID也不會丟失,ID是8;

InnoDB必須有主鍵(建議使用自增主鍵,不用UUID,自增主鍵索引查詢效率高)、支援外來鍵、支援事務、支援行級鎖。

系統崩潰後,MyISAM很難恢復;

綜合考慮,優先選擇InnoDB,MySQL預設也是InnoDB。

164、如何獲取當前資料庫版本?

//MySQL,,mysql -v
select version();
//Oracle 
select * from v$version;

165、說一下 ACID 是什麼?

ACID是資料庫事務執行的四大基本要素,包括原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)、永續性(Durability)。

1、原子性

整個事務中的所有操作,要麼全部完成,要不全部不完成,不可能停滯在中間某個環節。

事務在執行過程中發生錯誤,會被roolback回滾到事務開始前的狀態,就像這個事務從未執行過一樣。

2、一致性

事務必須始終保持系統處於一致的狀態,不管在任何給定的時間並行事務有多少。

3、隔離性

隔離狀態執行事務,使他們好像是系統在給定時間內執行的唯一操作。

如果有兩個事務,執行在相同的時間內,執行相同的功能,事務的隔離性確保每一個事務在系統中認為只有自己在使用系統。

這種屬性稱為序列化,為了防止事務操作間的混淆,必須序列化或序列化請求,使得在同一時間僅有一個請求用於同一資料。

4、永續性

一個成功的事務將永久的改變系統的狀態。

166、char 和 varchar 的區別是什麼?

  1. char的長度是固定的,varchar的長度的可變的;
  2. char的效率比varchar的效率高;
  3. char佔用空間比varchar大,char在查詢時需要使用trim;

167、float 和 double 的區別是什麼?

1、float 和 double 的區別是什麼?

(1)記憶體中佔有的位元組數不同

  • 單精度浮點數在記憶體中佔有4個位元組;
  • 雙精度浮點數在記憶體中佔有8個位元組;

(2)有效數位位數不同

  • 單精度浮點數有效數位8位元;
  • 雙精度浮點數有效數位16位元;

(3)數值取值範圍不同

  • 單精度浮點數的表示範圍:-3.40E+38~3.40E+38
  • 雙精度浮點數的表示範圍:-1.79E+308~-1.79E+308

(4)在程式中處理速度不同

一般來說,CPU處理單精度浮點數的速度比雙精度浮點數的速度快

如果不宣告,預設小數是double型別,如果想用float,要進行強轉;

2、例如

float f = 1.3;會編譯報錯,正確的寫法是float f = (float)1.3;或者float a = 1.3f;(f或F都可以不區分大小寫)

3、注意

float是八位有效數位,第七位會四捨五入;

4、面試題

(1)java中3*0.1==0.3將會返回什麼?true還是false?

答:返回false,因為浮點數不能完全精確的表示出來,一般會損失精度;

(2)java中float f = 3.4;是否正確?

答:不正確。因為3.4是雙精度浮點數,將雙精度賦給單精度屬於向下轉型,會造成精度損失,因此需要強制型別轉換float=(float)3.4;或者寫成float f = 3.4f;

168、Oracle分頁sql

#不帶排序的
SELECT * FROM (
SELECT ROWNUM AS rowno, t.* FROM worker t where ROWNUM <=20) table_alias 
WHERE table_alias.rowno > 10;
#帶排序的
SELECT * FROM (
SELECT tt.*, ROWNUM AS rowno FROM (  
SELECT t.* FROM worker t ORDER BY wkid aSC) tt WHERE ROWNUM <= 20) table_alias 
WHERE table_alias.rowno >= 10;

169、資料庫如何保證主鍵唯一性

1、主鍵約束

主鍵列上沒有任何兩行具有相同值(即重複值),不允許空(NULL);

2、唯一性約束

保證一個欄位或者一組欄位裡的資料都與表中其它行的對應資料不同。

和主鍵約束不同,唯一性約束允許為null,但是隻能有一行;

3、唯一性索引

不允許具有索引值相同的行,從而禁止重複的索引和鍵值;

4、三者的區別

  • 約束是用來檢查資料的正確性;索引是用來優化查詢的;
  • 建立唯一性約束會建立一個約束和一個唯一性索引;
  • 建立唯一性索引只會建立一個唯一性索引;
  • 主鍵約束和唯一性約束都會建立一個唯一性索引

170、如何設計資料庫

1、資料庫設計最起碼要佔用這個專案開發的40%以上的時間

2、資料庫設計不僅僅停留在頁面demo的表面

頁面內容所需欄位,在資料庫設計中只是一部分,還有系統運轉、模組互動、中轉資料、表之間的聯絡等等所需要的欄位

因此資料庫設計絕對不是簡單的基本資料儲存,還有邏輯資料儲存。

3、資料庫設計完成後,專案80%的設計開發都要存在你的腦海中

每個欄位的設計都要有他存在的意義,要清楚的知道程式中如何去運用這些欄位,多張表的聯絡在程式中是如何體現的。

4、資料庫設計時就要考慮效率和優化問題

資料量大的表示粗粒度的,會冗餘一些必要欄位,達到用最少的表,最弱的表關係去儲存海量的資料。

巨量資料的表要建立索引,方便查詢。對於含有計算、資料互動、統計這類需求時,還有考慮是否有必要採用儲存過程。

5、新增必要的冗餘欄位

像建立時間、修改時間、操作使用者IP、備註這些欄位,在每張表中最好都有,一些冗餘的欄位便於日後維護、分析、拓展而新增。

6、設計合理的表關聯 

若兩張表之間的關係複雜,建議採用第三張對映表來關聯維護兩張表之間的關係,以降低表之間的直接耦合度。

7、設計表時不加主外來鍵等約束關聯,系統編碼階段完成後再新增約束性關聯

8、選擇合適的主鍵生成策略

資料庫的設計難度其實比單純的技術實現難很多,他充分體現了一個人的全域性設計能力和掌控能力,最後說一句,資料庫設計,很重要,很複雜。

171、性別是否適合做索引

區分度不高的欄位不適合做索引,因為索引頁是需要有開銷的,需要儲存的,不過這類欄位可以做聯合索引的一部分。

172、如何查詢重複的資料

1、查詢重複的單個欄位(group by)

select 重複欄位A, count(*) from 表 group by 重複欄位A having count(*) > 1

2、查詢重複的多個欄位(group by)

select 重複欄位A, 重複欄位B, count(*) from 表 group by 重複欄位A, 重複欄位B having count(*) > 1

173、資料庫一般會採取什麼樣的優化方法?

1、選取適合的欄位屬性

  • 為了獲取更好的效能,可以將表中的欄位寬度設得儘可能小。
  • 儘量把欄位設定成not null執行查詢的時候,資料庫不用去比較null值。
  • 對某些省份或者性別欄位,將他們定義為enum型別,enum型別被當做數值型資料來處理,而數值型資料被處理起來的速度要比文字型別塊很多。

2、使用join連線代替子查詢

3、使用聯合union來代替手動建立的臨時表

注意:union用法中,兩個select語句的欄位型別要匹配,而且欄位個數要相同。

4、事務

要麼都成功,要麼都失敗。

可以保證資料庫中資料的一致性和完整性。

事務以begin開始,commit關鍵字結束。

如果出錯,rollback命令可以將資料庫恢復到begin開始之前的狀態。

事務的另一個重要作用是當多個使用者同時使用相同的資料來源時,它可以利用鎖定資料庫的方式為使用者提供一種安全的存取方式,這樣就可以保證使用者的操作不被其他的使用者干擾。

5、鎖定表

儘管事務是維護資料庫完整性的一個非常好的方法,但卻因為它的獨佔性,有時會影響資料庫的效能,尤其是在大應用中。

由於在事務執行的過程中,資料庫會被鎖定,因此其它使用者只能暫時等待直到事務結束。

有的時候可以用鎖定表的方法來獲得更好的效能,

共用鎖:其它使用者只能看,不能修改

lock table person in share mode;

對於通過lock table 命令主動新增的鎖來說,如果要釋放它們,只需發出rollback命令即可。

6、使用外來鍵

鎖定表的方法可以維護資料的完整性,但是它卻不能保證資料的關聯性,這個時候可以使用外來鍵。

7、使用索引

索引是提高資料庫查詢速度的常用方法,尤其是查詢語句中包含max()、min()、order by這些命令的時候,效能提高更為顯著。

一般來說索引應該建在常用於join、where、order by的欄位上。儘量不要對資料庫中含有大量重複的值得欄位建立索引。

8、優化的查詢語句

在索引的欄位上儘量不要使用函數進行操作。

儘量不要使用like關鍵字和萬用字元,這樣做法很簡單,但卻是以犧牲效能為代價的。

避免在查詢中進行自動型別轉換,因為型別轉換也會使索引失效。

174、索引怎麼定義,分哪幾種

  1. b-tree索引,如果不建立索引的情況下,oracle就自動給每一列都加一個B 樹索引;
  2. normal:普通索引
  3. unique:唯一索引
  4. bitmap:點陣圖索引,點陣圖索引特定於只有幾個列舉值的情況,比如性別欄位;
  5. 基於函數的索引

175、mysql 的內連線、左連線、右連線有什麼區別?

  • 內連線,顯示兩個表中有聯絡的所有資料;
  • 左連結,以左表為參照,顯示所有資料,右表中沒有則以null顯示
  • 右連結,以右表為參照顯示資料,,左表中沒有則以null顯示

176、RabbitMQ的使用場景有哪些?

1、解決非同步問題

例如使用者註冊,傳送郵件和簡訊反饋註冊成功,可以使用RabbitMQ訊息佇列,使用者無需等待反饋。

2、服務間解耦

訂單系統和庫存系統,中間加入RabbitMQ訊息佇列,當庫存系統出現問題時,訂單系統依舊能正常使用,降低服務間耦合度。

3、秒殺系統

利用RabbitMQ的最大值,實現秒殺系統。

177、RabbitMQ有哪些重要的角色?有哪些重要的元件?

1、RabbitMQ有哪些重要的角色?

使用者端、RabbitMQ、伺服器端。

2、有哪些重要的元件?

(1)connectionFactory(連線管理器)

應用程式與RabbitMQ之間建立連線的管理器。

(2)Channel(通道)

訊息推播使用的通道。

(3)RoutingKey(路由鍵)

用於把生產者的資料分配到交換機上。

(4)Exchange(交換機)

用於接受和分配訊息。

(5)BindKey(繫結鍵)

用於把交換機的訊息繫結到佇列上

(6)Queue(佇列)

用於儲存生產者訊息。

178、RabbitMQ中 vhost 的作用是什麼?

vhost可以理解為mini版的RabbitMQ,其內部均含有獨立的交換機、繫結、佇列,最重要的是擁有獨立的許可權系統,可以做到vhost範圍內的使用者控制。

從RabbitMQ全域性考慮,不同的應用可以跑在不同的vhost上,作為不同許可權隔離的手段。

179、說一下 jvm 的主要組成部分?及其作用?

JVM包括類載入子系統、堆、方法區、棧、本地方法棧、程式計數器、直接記憶體、垃圾回收器、執行引擎。

1、類載入子系統

類載入子系統負責載入class資訊,載入的類資訊存放於方法區中。

2、直接記憶體

直接記憶體是在Java堆外的、直接向系統申請的記憶體空間。存取直接記憶體的速度會由於Java堆。

出於效能的考慮,讀寫頻繁的場合可能會考慮使用直接記憶體。

3、垃圾回收器

垃圾回收器可以對堆、方法區、直接記憶體進行回收。

4、執行引擎

執行引擎負責執行虛擬機器器的位元組碼,虛擬機器器會使用即時編譯技術將方法編譯成機器碼後再執行。

180、說一下 jvm 執行時資料區?

執行時資料區包括堆、方法區、棧、本地方法棧、程式計數器。

1、堆

堆解決的是物件範例儲存的問題,垃圾回收器管理的主要區域。

2、方法區

方法區可以認為是堆的一部分,用於儲存已被虛擬機器器載入的資訊,常數、靜態變數、即時編譯器編譯後的程式碼。

3、棧

棧解決的是程式執行的問題,棧裡面存的是棧幀,棧幀裡面存的是區域性變數表、運算元棧、動態連結、方法出口等資訊。

(1)棧幀

每個方法從呼叫到執行的過程就是一個棧幀在虛擬機器器棧中入棧到出棧的過程。

(2)區域性變數表

用於儲存函數的引數和區域性變數。

(3)運算元棧

運算元棧又稱操作棧,大多數指令都是從這裡彈出資料,執行運算,然後把結果壓回運算元棧。

4、本地方法棧

與棧功能相同,本地方法棧執行的是本地方法,一個Java呼叫非Java程式碼的介面。

5、程式計數器(PC暫存器)

程式計數器中存放的是當前執行緒所執行的位元組碼的行數。JVM工作時就是通過改變這個計數器的值來選取下一個需要執行的位元組碼指令。

到此這篇關於Java經典面試題最全彙總208道(五)的文章就介紹到這了,更多相關Java面試題內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com