面試問題總結

基礎篇

1、談談多態,及多態的好處

多態,父類引用指向子類。

當把不同的子類對象都當做父類類型來看待,可以屏蔽不同子類對象之間的實現差異,從而寫出通用的代碼達到通用編程,以適應需求的不斷變化。

在實際開發中,父類類型作爲方法形式參數,傳遞子類對象給方法,進行方法的調用,更能體現出多態的拓展性和便利

方便代碼維護和拓展

2、談談繼承,繼承得好處

從上層往下層看,當定義類B時,如果類A有和B相同的內容,且A和B屬於同一類型,這是B就可繼承自A

從下層往上層看,當定義的多個類屬於同一類型,且有相同的內容,可以向上抽取出一個類,這便形成了繼承關係

繼承得好處:

簡化了人們對事物的認識和描述,能清晰體現相關類間的層次結構關係;

能清晰體現相關類間的層次結構關係;繼承提供了軟件複用功能。這種做法能減小代碼和數據的冗餘度,大大增加程序的重用

性;提供多重繼承機制;

大大增加了程序的易維護性。

3、爲什麼用封裝

簡化代碼,方便複用,在實現一個功能的時候只需要關注結果,而不需要關注裏面做了什麼(隱藏信息,實現細節 )。

4、講講protect在java中的作用,什麼時候用它

protected修飾的變量或方法只能被當前類,同包類或者子孫類繼承或使用

一般情況下爲了實現純粹的封裝用的就是private,而使用protected可以封裝也可以繼承

當一些類,需要繼承,但是不想公開的時候可以用protect

5、串行、並行和併發

       順序執行:你吃飯吃到一半,電話來了,你一直到吃完了以後纔去接,這就說明你不支持併發也不支持並行。

  併發:你吃飯吃到一半,電話來了,你停了下來接了電話,接完後繼續吃飯,這說明你支持併發。

  並行:你吃飯吃到一半,電話來了,你一邊打電話一邊吃飯,這說明你支持並行。

 

併發,指的是多個事情,在同一時間段內同時發生了。  
並行,指的是多個事情,在同一時間點上同時發生了。

6、設計模式(單例)

單例:就是整個程序有且僅有一個實例。該類負責創建自己的對象,同時確保只有一個對象被創建。

懶漢模式,餓漢模式,雙重鎖機制,單例模式一般用的比較多,雙重鎖的話是處理多線程任務時,使用的一種機制。

懶漢模式:線程不安全,延遲初始化

public class Singleton {  
    private static Singleton instance;  
    private Singleton (){}  
  
    public static Singleton getInstance() {  
    if (instance == null) {  
        instance = new Singleton();  
    }  
    return instance;  
    }  
}

餓漢模式:線程安全,比較常用,但容易產生垃圾,因爲一開始就初始化

public class Singleton {  
    private static Singleton instance = new Singleton();  
    private Singleton (){}  
    public static Singleton getInstance() {  
    return instance;  
    }  
}

雙重鎖機制:線程安全,延遲初始化。這種方式採用雙鎖機制,安全且在多線程情況下能保持高性能。 

(注意volatile關鍵字)

public class Singleton {  
    private volatile static Singleton singleton;  
    private Singleton (){}  
    public static Singleton getSingleton() {  
    if (singleton == null) {  
        synchronized (Singleton.class) {  
        if (singleton == null) {  
            singleton = new Singleton();  
        }  
        }  
    }  
    return singleton;  
    }  
}

雙重檢查模式,進行了兩次的判斷,第一次是爲了避免不要的實例,第二次是爲了進行同步,避免多線程問題。由於singleton=new Singleton()對象的創建在JVM中可能會進行重排序,在多線程訪問下存在風險,使用volatile修飾signleton實例變量有效,解決該問題 

靜態內部類單例模式

public class Singleton { 
    private Singleton(){
    }
      public static Singleton getInstance(){  
        return Inner.instance;  
    }  
    private static class Inner {  
        private static final Singleton instance = new Singleton();  
    }  
}

只有第一次調用getInstance方法時,虛擬機才加載 Inner 並初始化instance ,只有一個線程可以獲得對象的初始化鎖,其他線程無法進行初始化,保證對象的唯一性。目前此方式是所有單例模式中最推薦的模式,但具體還是根據項目選擇。

枚舉(擴展):默認枚舉實例的創建是線程安全的,並且在任何情況下都是單例。

public enum Singleton  {
    INSTANCE 
 
    //doSomething 該實例支持的行爲
      
    //可以省略此方法,通過Singleton.INSTANCE進行操作
    public static Singleton getInstance() {
        return Singleton.INSTANCE;
    }
}
  • 枚舉類隱藏了私有的構造器。
  • 枚舉類的域 是相應類型的一個實例對象
  • 枚舉的單例生產中使用較少,主要是太簡單以致可讀性差

6、設計模式(裝飾者設計模式(動態代理))

 

 

7、[a,b,c]、[a,b]、[a]三個索引哪一個搜的快,爲什麼

 

8、講講hashMap

hashMap鍵唯一,值可以不唯一。鍵是set集合,set集合保證鍵唯一的方法是,如果存的鍵是空,則默認爲0,否則進行hash值比較,如果hash值相同,則在在鍵後跟鏈表(處理hash衝突),當達到8時鏈表轉換成紅黑樹(jdk1.8之後)。

 //判斷鍵值是否爲空,是則默認爲0 
static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }

 

9、講講紅黑樹

 

 

10、講講GC

 

11、servlet生命週期

首先加載servlet的class,實例化servlet,然後初始化servlet調用init()的方法,接着調用服務的service的方法處理doGet和doPost方法,最後是我的還有容器關閉時候調用destroy 銷燬方法。

12、jsp和servlet的區別

jsp本質就是servlet,Jsp是Servlet的一種簡化,使用Jsp只需要完成程序員需要輸出到客戶端的內容,Jsp中的Java腳本如何鑲嵌到一個類中,由Jsp容器完成。

但jsp內有內置對象,servlet沒有,

jsp更擅長表現於頁面顯示,servlet更擅長於邏輯控制.

13、講講對事物的理解

 

14、講講ThreadLocal

 

15、StringBuilder、StringBuffer、String的區別

 

16、http和tcp的區別

 

17、post請求,和get請求的區別

 

技術篇

1、springboot定時器的配置

1、在啓動類中加入定時器的註解@EnableScheduling來註冊定時任務

2、在定時任務的方法上加上@Scheduled(cron = "0/30 * * * * ?") 並在裏面寫cron表達式

2、springboot定時器的配置多線程任務

配置一個配置類ScheduleConfig實現SchedulingConfigurer接口,並重寫裏面的方法,設定定時任務池,來實現多線程的計時任務

下面這篇博文寫的很好,可以參考 

https://blog.csdn.net/u013456370/article/details/79411952 

3、spingboot 定時器搭建集羣的話怎麼設置 (百度面試的)

 

4、springcloud運行過程中如果一臺服務處故障了,這時候怎麼處理

通常會搭建服務集羣,如果一臺服務宕機壞掉了,會Erake註冊中心映射到另一臺服務上。

5、springcloud的優點

 

6、springcloud的缺點

維護起來難(面試的馬上就會問,怎麼難了。。。。舉個例子,我舉你個鬼啊)

 

7、講講倒排索引

 

8、有三個索引【a,b,c】【a,b】【a】哪一個查的快,爲什麼

 

9、redis的五中數據類型,其中list裏面一條數據中間出錯了,能不能修改,能的話,怎麼修改,不能的話爲什麼

 

10、講講緩存穿透,緩存擊穿,緩存雪崩

緩存穿透:緩存中和數據庫中都沒有數據,但是用戶不停的連續發生這樣的請求,這時的用戶很可能是攻擊者,攻擊會導致數

據庫壓力過大

解決方案:將搜索信息和ip作爲key,搜索次數作爲value存進redis,設置緩存有效時間,一定時間內訪問超過一定次數的話進行攔截。

緩存擊穿:    緩存擊穿是指緩存中沒有但數據庫中有的數據(一般是緩存時間到期),這時由於併發用戶特別多,同時讀緩存沒讀到數據,又同時去數據庫去取數據,引起數據庫壓力瞬間增大,造成過大壓力

解決方案:設置redis永久有效;設置互斥鎖,當redis獲取爲空時,先獲取鎖,去數據庫中取數據,並更新redis,如果更新成功則釋放鎖;而如果拿不到鎖,證明服務正在想數據庫中獲取數據,此時線程休眠一定時間,知道拿到鎖。

緩存雪崩:緩存雪崩是指緩存中數據大批量到過期時間,而查詢數據量巨大,引起數據庫壓力過大甚至down機。和緩存擊穿不同的是,        緩存擊穿指併發查同一條數據,緩存雪崩是不同數據都過期了,很多數據都查不到從而查數據庫。

解決方案:

  1. 緩存數據的過期時間設置隨機,防止同一時間大量數據過期現象發生。
  2. 如果緩存數據庫是分佈式部署,將熱點數據均勻分佈在不同的緩存數據庫中。
  3. 設置熱點數據永遠不過期

11、rabbitMQ 發送消息的時候,如果消息一斤發送出去,這個時候系統出了故障,rabbitmq返回一個錯誤,又重新發送了,用戶收到了兩份內容,請問如何避免

處理這樣的問題儘量避開MQ的處理,因爲MQ處理的話會,降低消息的吞吐量。儘量在應用層設置

收消息方,收到是1,沒收到是0,還需要處理一下異常讓他不進行二次發送。

12、rabbit發送兩條消息,怎樣保證發送順序

在 MQ 層面支持消息的順序處理開銷太大,爲了極少量的需求,增加整體上的複雜度得不償失。所以,還是在應用層面處理比較好,或者業務邏輯進行處理。

應用層處理方法:

1:“同步執行”:當一個消息執行完之後,再發布下一個消息。

2、消息實體中增加:版本號 & 狀態機 & msgid & parent_msgid,通過 parent_msgid 判斷消息的順序(需要全局存儲,記錄消息的執行狀態)。

處理方式

13、講講集羣

 

14、ES怎麼存數據

使用ES,需要先創建相關的實體類,實體類上需要有相應的註解標明映射和類型

@Document(indexName = "skuinfo", type = "docs")

同時各個字段也要有響應註解說明是否創建索引,是否分詞,採用什麼分詞器等等

存儲數據時,需要先根據實體類創建相關索引和映射

 //創建索引

        elasticsearchTemplate.createIndex(SkuInfo.class);
        //創建映射
        elasticsearchTemplate.putMapping(SkuInfo.class);

在創建操作es的dao類,需要繼承 ElasticsearchRepository並規定泛型

public interface SkuInfoDao extends ElasticsearchRepository<SkuInfo,Long> {
}

 然後直接利用裏面封裝的方法存數據

業務篇

1、講講購物車實現原理,如果購物車裏面有8件商品,提交其中兩件,問怎麼操作

 

2、怎樣實現秒殺,

 

編碼篇

1、一個數組Integer array = {2,5,1,8080,3306,9200,3,5,5,2},計算裏面出現最多的數字,如果出現相同次數的數字,返回最大的數字的次數,如上面數組中5出現3次。時間複雜度要儘可能的低,越低,分熟越高

這裏可以用HashMap存儲相關的值,達到一次遍歷即得出結果,相關代碼自己想。

 

2、一個student表,有No,name,class,score共計四個字段

問1:用一條sql語句得到及格人數大於30的班級

 

問2:用一條sql得到每個班及格人數和不及格人數

 

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