1. 程式人生 > 實用技巧 >java面試題2-自己整合的

java面試題2-自己整合的

1.HashMap的底層實現原理

HashMap是陣列+連結串列組成的實現了Map、Cloneable、Serializable介面,繼承了AbstractMap類

HashMap是否執行緒安全?
HashMap是執行緒不安全的,在併發的環境下可以使用ConcurrentHashMap。

基本方法的使用

HashMap<Integer,String> map=new HashMap<>();
        //新增元素
        map.put(1, "a");
        map.put(2, "b");
        map.put(3, "c");
        //鍵不可重複,值被覆蓋
        map.put(3, "C");
        
        //通過鍵刪除整個鍵值對
        map.remove(3);
        //清空
        map.clear();
        //是否為空
        System.out.println(map.isEmpty());//false
        //是否包含4
        System.out.println(map.containsKey(4));//false
        //是否包含“b”值
        System.out.println(map.containsValue("b"));//true
        //獲取集合元素個數
        System.out.println(map.size());//3
        //通過鍵獲取值
        System.out.println(map.get(3));//C
        //獲取所有值構成的集合
        Collection<String> values=map.values();
        for(String v:values){
            System.out.println("值:"+v);//值:a    值:b   值:c
        }
        
        System.out.println(map);
    }

兩種遍歷方式

public static void main(String[] args) {
    Map<String,Integer> map=new HashMap<>();
    map.put("小林",21);
    map.put("小張",35);
    map.put("小王",18);
    demo1(map);
    demo2(map);
  }
  //通過Set<K>  setKey()方法遍歷
  private static void demo1(Map<String,Integer> map) {
    Set<String> keys=map.keySet();
    for (String key:keys){
      Integer value=map.get(key);
      System.out.println("鍵為:"+key+"值為:"+value);//鍵為:小林值為:21
                                                      //鍵為:小王值為:18
                                                      //鍵為:小張值為:35
    }
  }
  //通過Set<Map.Entry<K,V>> entrySet()方法遍歷
  private static void demo2(Map<String, Integer> map) {
    Set<Map.Entry<String,Integer>> kvs=map.entrySet();
    for (Map.Entry<String,Integer> kv:kvs){
      String kstring=kv.getKey();
      Integer istring=kv.getValue();
      System.out.println(kstring+"-----"+istring);
      //小林-----21
      //小王-----18
      //小張-----35
    }
  }

2.HashMap和HashTable的區別
1、繼承的父類不同
HashMap繼承自AbstractMap類。但二者都實現了Map介面。
Hashtable繼承自Dictionary類,Dictionary類是一個已經被廢棄的類(見其原始碼中的註釋)。 父類都被廢棄,自然而然也沒人用它的子類Hashtable了。
2、HashMap執行緒不安全,HashTable執行緒安全
3.包含的contains方法不同
HashMap是沒有contains方法的,而包括containsValue和containsKey方法;hashtable則保 留了contains方法,效果同containsValue,還包括containsValue和containsKey方法。
4.是否允許null值
Hashmap是允許key和value為null值的,用containsValue和containsKey方法判斷是否包含對 應鍵值對;HashTable鍵值對都不能為空,否則包空指標異常。
5.計算hash值方式不同
6.擴容方式不同(容量不夠)
7.解決hash衝突方式不同(地址衝突)

3.Spring中的常用註解和作用

@Controller 處理http請求的控制器

@RestController

Spring4之後新加入的註解,原來返回json需要@ResponseBody和@Controller配合。
即@RestController是@ResponseBody和@Controller的組合註解。

@RestController
public class HelloController {

    @RequestMapping(value="/hello",method= RequestMethod.GET)
    public String sayHello(){
        return "hello";
    }
}

@RequestMapping 配置url對映

@RequestMapping此註解即可以作用在控制器的某個方法上,也可以作用在此控制器類上;	@RequestMapping中的method引數有很多中選擇,一般使用get/post.

當控制器在類級別上新增@RequestMapping註解時,這個註解會應用到控制器的所有處理器	方法上。處理器方法上的@RequestMapping註解會對類級別上的@RequestMapping的宣告	進行補充。
	@RequestMapping(value="/queryById") 普通請求
	@RequestMapping(value="/hello",method= RequestMethod.GET) get請求 

	@RequestMapping(value="/hello",method= RequestMethod.POST) post請求 

常用的基本上就value和method了。其簡化註解有

	@GetMapping 等同於 @RequestMapping(method = RequestMethod.GET)
	@PostMapping 等同於 @RequestMapping(method = RequestMethod.POST)
	@PutMapping 等同於 @RequestMapping(method = RequestMethod.PUT)
	@DeleteMapping 等同於 @RequestMapping(method = RequestMethod.DELETE)
	@PatchMapping 等同於 @RequestMapping(method = RequestMethod.PATCH)

下面是三層的

@Component 最普通的元件,可以被注入到spring容器進行管理
@Repository 作用於持久層
@Service 作用於業務邏輯層@Resource(這個註解屬於J2EE的),預設安照名稱進行裝配,名稱可以通過name屬性進行指定
@Resource(這個註解屬於J2EE的),預設安照名稱進行裝配,名稱可以通過name屬性進行指定(例:@Resource(name="userService"))

4.SpringMVC的執行原理
SpringMVC流程:

01、使用者傳送出請求到前端控制器DispatcherServlet。

02、DispatcherServlet收到請求呼叫HandlerMapping(處理器對映器)。

03、HandlerMapping找到具體的處理器(可查詢xml配置或註解配置),生成處理器物件及處理器攔截器(如果有),再一起返回給DispatcherServlet。

04、DispatcherServlet呼叫HandlerAdapter(處理器介面卡)。

05、HandlerAdapter經過適配呼叫具體的處理器(Handler/Controller)。

06、Controller執行完成返回ModelAndView物件。

07、HandlerAdapter將Controller執行結果ModelAndView返回給DispatcherServlet。

08、DispatcherServlet將ModelAndView傳給ViewReslover(檢視解析器)。

09、ViewReslover解析後返回具體View(檢視)。

10、DispatcherServlet根據View進行渲染檢視(即將模型資料填充至檢視中)。

11、DispatcherServlet響應使用者。

涉及元件分析:

1、前端控制器DispatcherServlet(不需要程式設計師開發),由框架提供,在web.xml中配置。

作用:接收請求,響應結果,相當於轉發器,中央處理器。

2、處理器對映器HandlerMapping(不需要程式設計師開發),由框架提供。

作用:根據請求的url查詢Handler(處理器/Controller),可以通過XML和註解方式來對映。

3、處理器介面卡HandlerAdapter(不需要程式設計師開發),由框架提供。

作用:按照特定規則(HandlerAdapter要求的規則)去執行Handler。

4、處理器Handler(也稱之為Controller,需要工程師開發)

注意:編寫Handler時按照HandlerAdapter的要求去做,這樣介面卡才可以去正確執行Handler。

作用:接受使用者請求資訊,呼叫業務方法處理請求,也稱之為後端控制器。

5、檢視解析器ViewResolver(不需要程式設計師開發),由框架提供

作用:進行檢視解析,把邏輯檢視名解析成真正的物理檢視。

SpringMVC框架支援多種View檢視技術,包括:jstlView、freemarkerView、pdfView等。

6、檢視View(需要工程師開發)

作用:把資料展現給使用者的頁面

View是一個介面,實現類支援不同的View技術(jsp、freemarker、pdf等)

具體元件的配置相關,請查閱

spring-webmvc-4.3.2.RELEASE.jar 包

下面

/org/springframework/web/servlet/DispatcherServlet.properties 的相關配置

5.LinkedList和ArrayList的區別
LinkedList():連結串列(節點)。記憶體空間不連續。執行緒不安全。便於增刪不便於查詢。
ArrayList() :陣列。記憶體空間連續。預設初始容量是10,每次增加一半(右移),執行緒不安全。 便於查詢而不便於增刪
兩種列表的區別:1.ArrayList是實現了基於動態陣列的資料結構,LinkedList基於連結串列的資料結 構。

2.對於隨機訪問get和set,ArrayList覺得優於LinkedList,因為LinkedList要移動指標。

3.對於新增和刪除操作add和remove,LinedList比較佔優勢,因為ArrayList要移動資料。


6.反射的原理
1、反bai射的原理,即是jvm通過位元組碼class檔案,生成相應的對du象。
就像正zhi常生成一個物件一樣,都是來源於字dao節碼class檔案,
之所以叫反射,只是因為他不像正常的物件宣告,如A a=new A()的方式。
2、反射在框架中的應用太廣,只舉一個典型的例子,即Spring中Bean的注入。
bean總是先宣告class路徑,然後依次生成就可以了。

7.Mybatis的執行原理

一、mybatis的工作原理:
MyBatis 是支援普通 SQL查詢,儲存過程和高bai級對映的優秀持久層框架。MyBatis 消除du了幾zhi乎所有的JDBC程式碼和引數的手工設定以及結果集的檢索。

       MyBatis使用簡單的 XML或註解用於配置和原始對映,將介面和 Java 的POJOs(Plain Ordinary Java Objects,普通的 Java物件)對映成資料庫中的記錄。

每個MyBatis應用程式主要都是使用SqlSessionFactory例項的,一個SqlSessionFactory例項可以通過SqlSessionFactoryBuilder獲得。用xml檔案構建SqlSessionFactory例項是非常簡單的事情。

推薦在這個配置中使用類路徑資源,但可以使用任何Reader例項,包括用檔案路徑或file://開頭的url建立的例項。MyBatis有一個實用類----Resources,它有很多方法,可以方便地從類路徑及其它位置載入資源。

二、使用mybatis的原因:因為mybatis具有許多的優點,具體如下:

1、簡單易學:本身就很小且簡單。沒有任何第三方依賴,最簡單安裝只要兩個jar檔案+配置幾個sql對映檔案易於學習,易於使用,通過文件和原始碼,可以比較完全的掌握它的設計思路和實現。

2、靈活:mybatis不會對應用程式或者資料庫的現有設計強加任何影響。 sql寫在xml裡,便於統一管理和優化。通過sql語句可以滿足操作資料庫的所有需求。

3、解除sql與程式程式碼的耦合:通過提供DAO層,將業務邏輯和資料訪問邏輯分離,使系統的設計更清晰,更易維護,更易單元測試。sql和程式碼的分離,提高了可維護性。

4、提供對映標籤,支援物件與資料庫的orm欄位關係對映。

5、提供物件關係對映標籤,支援物件關係組建維護。

6、提供xml標籤,支援編寫動態sql。

擴充套件資料:

mybatis的功能構架:

1、API介面層:提供給外部使用的介面API,開發人員通過這些本地API來操縱資料庫。介面層一接收到呼叫請求就會呼叫資料處理層來完成具體的資料處理。

2、資料處理層:負責具體的SQL查詢、SQL解析、SQL執行和執行結果對映處理等。它主要的目的是根據呼叫的請求完成一次資料庫操作。

3、基礎支撐層:負責最基礎的功能支撐,包括連線管理、事務管理、配置載入和快取處理,這些都是共用的東西,將他們抽取出來作為最基礎的元件。為上層的資料處理層提供最基礎的支撐。

8.執行緒的實現方法
①. 繼承Thread類建立執行緒類

定義Thread類的子類,並重寫該類的run方法,該run方法的方法體就代表了執行緒要完成的任務。因此把run()方法稱為執行體。
建立Thread子類的例項,即建立了執行緒物件。
呼叫執行緒物件的start()方法來啟動該執行緒。

②. 通過Runnable介面建立執行緒類

定義runnable介面的實現類,並重寫該介面的run()方法,該run()方法的方法體同樣是該執行緒的執行緒執行體。
建立 Runnable實現類的例項,並依此例項作為Thread的target來建立Thread物件,該Thread物件才是真正的執行緒物件。
呼叫執行緒物件的start()方法來啟動該執行緒。

③. 通過Callable和Future建立執行緒

建立Callable介面的實現類,並實現call()方法,該call()方法將作為執行緒執行體,並且有返回值。
建立Callable實現類的例項,使用FutureTask類來包裝Callable物件,該FutureTask物件封裝了該Callable物件的call()方法的返回值。
使用FutureTask物件作為Thread物件的target建立並啟動新執行緒。
呼叫FutureTask物件的get()方法來獲得子執行緒執行結束後的返回值。


9.如何建立執行緒池和常用執行緒池的使用


10.當前端傳送ajax請求返回200卻進入error,如何處理

出錯原因:

前臺dataType:"json",而後臺返回的資料不符合json規範。

解決方案有兩種:

1.前臺:讓ajax資料返回型別為text而不是json;即dataType: "text";

2.後臺:修改後臺返回值

11.使用資料庫,如何用一張表得到另外一張表

1、如果是整個表複製表達如下:
insert into table1 select*from table2

2、如果是有選擇性的複製資料表達如下:
insert into table1(column1,column2,column3...) select column1,column2,colunm3... from table2

3、一個數據庫中的表中的資料複製到另一個數據庫中的一個表,使用方法如下:
insert into 資料庫A.dbo.table1(col1,col2,col3...) select col1,col2,col3... from 資料庫B.dbo.table2

12.如何解決後臺給前端的介面中出現的跨域問題(@CrossOrigin和閘道器)


13.有沒有使用過ElasticSearch


14.說下你對 Spring AOP 和 IOC 的理解?
1.IOC

許多應用都是通過彼此間的相互合作來實現業務邏輯的,如類A要呼叫類B的方法,以前我們都是在類A中,通過自身new一個類B,然後在呼叫類B的方法,現在我們把new類B的事情交給spring來做,在我們呼叫的時候,容器會為我們例項化。

  1. IOC容器的初始化過程

資源定位,即定義bean的xml-------》載入--------》IOC容器註冊,註冊beanDefinition

IOC容器的初始化過程,一般不包含bean的依賴注入的實現,在spring IOC設計中,bean的註冊和依賴注入是兩個過程,,依賴注入一般發生在應用第一次索取bean的時候,但是也可以在xm中配置,在容器初始化的時候,這個bean就完成了初始化。

  1. 三種注入方式,構造器、介面、set注入,我們常用的是set注入

  2. bean是如何建立---  工廠模式

  3. 資料是如何注入-------反射
    6.AOP

面向切面程式設計,在我們的應用中,經常需要做一些事情,但是這些事情與核心業務無關,比如,要記錄所有update*方法的執行時間時間,操作人等等資訊,記錄到日誌,

通過spring的AOP技術,就可以在不修改update*的程式碼的情況下完成該需求。

7.AOP的實現原理------代理


15使用 Spring 或者 SpringBoot 有遇到過什麼印象深刻的問題嗎?當時是怎麼解決的?


16.在專案中如何使用上傳,使用什麼方式進行上傳(阿里的oos)


17.StringBuffer 和 StringBuilder 的 3 個區別
區別1:執行緒安全
StringBuffer:執行緒安全,StringBuilder:執行緒不安全。因為 StringBuffer 的所有公開方法都是 synchronized 修飾的,而 StringBuilder 並沒有 synchronized 修飾。
區別2:緩衝區
區別3:效能
既然 StringBuffer 是執行緒安全的,它的所有公開方法都是同步的,StringBuilder 是沒有對方法加鎖同步的,所以毫無疑問,StringBuilder 的效能要遠大於 StringBuffer。
所以,StringBuffer 適用於用在多執行緒操作同一個 StringBuffer 的場景,如果是單執行緒場合 StringBuilder 更適合。