【最新】經典面試100問,附答案

本文由公衆號「字節傳說」整理,設計到的內容由java基礎、數據庫、SSM框架、redis、消息隊列、spring boot、spring cloud、git及一些前端知識。整理時間爲2019-11-19,首發於微信公衆號「字節傳說」,關注微信公衆號「字節傳說」,回覆面試領取該pdf版資料。公衆號二維碼以下:html

byte.jpg

2019年java面試經典100問,進入BAT不是夢。若是該pdf幫助到您,請您傳閱給您的小夥伴,一塊兒複習,共同作一個offer收割機,文章目錄以下:前端

1、java基礎

一、面向對象的特徵有哪些方面? 【基礎】java

答:面向對象的特徵主要有如下幾個方面:mysql

1)抽象:抽象就是忽略一個主題中與當前目標無關的那些方面,以便更充分地注意與當前目標有關的方面。抽象並不打算了解所有問題,而只是選擇其中的一部分,暫時不用部分細節。抽象包括兩個方面,一是過程抽象,二是數據抽象。nginx

2)繼承:繼承是一種聯結類的層次模型,而且容許和鼓勵類的重用,它提供了一種明確表述共性的方法。對象的一個新類能夠從現有的類中派生,這個過程稱爲類繼承。新類繼承了原始類的特性,新類稱爲原始類的派生類(子類),而原始類稱爲新類的基類(父類)。派生類能夠從它的基類那裏繼承方法和實例變量,而且類能夠修改或增長新的方法使之更適合特殊的須要。git

3)封裝:封裝是把過程和數據包圍起來,對數據的訪問只能經過已定義的界面。面向對象計算始於這個基本概念,即現實世界能夠被描繪成一系列徹底自治、封裝的對象,這些對象經過一個受保護的接口訪問其餘對象。程序員

4)多態性:多態性是指容許不一樣類的對象對同一消息做出響應。多態性包括參數化多態性和包含多態性。多態性語言具備靈活、抽象、行爲共享、代碼共享的優點,很好的解決了應用程序函數同名問題。面試

二、int 和Integer 有什麼區別? 【基礎】正則表達式

答:Java 提供兩種不一樣的類型:引用類型和原始類型(或內置類型);

int 是java 的原始數據類型,Integer 是java 爲int 提供的封裝類。

Java 爲每一個原始類型提供了封裝類:

原始類型: boolean,char,byte,short,int,long,float,double

封裝類型:Boolean,Character,Byte,Short,Integer,Long,Float,Double引用類型和原始類型的行爲徹底不一樣,而且它們具備不一樣的語義。引用類型和原始類型具備不一樣的特徵和用法,它們包括:大小和速度問題,這種類型以哪一種類型的數據結構存儲,當引用類型和原始類型用做某個類的實例數據時所指定的缺省值。對象引用實例變量的缺省值爲null,而原始類型實例變量的缺省值與它們的類型有關。

三、Math.round(11.5) 等於多少? Math.round(-11.5)等於多少? 【基礎】

答:Math.round(11.5)==12 Math.round(-11.5)==-11 round 方法返回與參數最接近的長整數,參數加1/2 後求其floor。

四、編程題: 用最有效率的方法算出2 乘以8 等於幾? 【基礎】

答: 2 << 3。

五、數組有沒有 length()方法?String 有沒有 length()方法?【基礎】

答:數組沒有 length()方法,有 length 的屬性。String 有 length()方法。JavaScript 中,得到字符串的長度是經過 length 屬性獲得的,這一點容易和 Java 混淆。

六、構造器(constructor)是否可被重寫(override)?【基礎】

答:構造器不能被繼承,所以不能被重寫,但能夠被重載。

七、是否能夠繼承String 類? 【基礎】

答:String 類是final 類,故不能夠繼承。

八、當一個對象被看成參數傳遞到一個方法後,此方法可改變這個對象的屬性,並可返回變化後的結果,那麼這裏究竟是值傳遞仍是引用傳遞? 【基礎】

答:是值傳遞。Java 編程語言只有值傳遞參數。當一個對象實例做爲一個參數被傳遞到方法中時,參數的值就是對該對象的引用。對象的內容能夠在被調用的方法中改變,但對象的引用是永遠不會改變的。

九、String 和StringBuffer 的區別?【基礎】

答:JAVA 平臺提供了兩個類:String 和StringBuffer,它們能夠儲存和操做字符串,即包含多個字符的字符數據。這個String 類提供了數值不可改變的字符串。而這個StringBuffer 類提供的字符串進行修改。當你知道字符數據要改變的時候你就能夠使用StringBuffer。典型地,你能夠使用StringBuffers 來動態構造字符數據。

十、String, StringBuffer StringBuilder 的區別。【基礎】

答:String 的長度是不可變的;StringBuffer 的長度是可變的,若是你對字符串中的內容常常進行操做,特別是內容要修改時,那麼使用StringBuffer.若是最後須要String,那麼使用StringBuffer 的toString()方法,線程安全;StringBuilder 是從JDK 5 開始,爲StringBuffer 該類補充了一個單個線程使用的等價類;一般應該優先使用StringBuilder 類,由於它支持全部相同的操做,但因爲它不執行同步,因此速度更快,線程不安全。

十一、重載(Overload)和重寫(Override)的區別。重載的方法可否根據返回類型進行區分?【基礎】

答:方法的重載和重寫都是實現多態的方式,區別在於前者實現的是編譯時的多態性,然後者實現的是運行時的多態性。重載發生在一個類中,同名的方法若是有不一樣的參數列表(參數類型不一樣、參數個數不一樣或者兩者都不一樣)則視爲重載;重寫發生在子類與父類之間,重寫要求子類被重寫方法與父類被重寫方法有相同的返回類型,比父類被重寫方法更好訪問,不能比父類被重寫方法聲明更多的異常(里氏代換原則)。重載對返回類型沒有特殊的要求。

十二、描述一下 JVM 加載 class 文件的原理機制?【中等】

答:JVM 中類的裝載是由類加載器(ClassLoader)和它的子類來實現的,Java 中的類加載器是一個重要的 Java 運行時系統組件,它負責在運行時查找和裝入類文件中的類。

因爲 Java 的跨平臺性,通過編譯的 Java 源程序並非一個可執行程序,而是一個或多個類文件。當 Java 程序須要使用某個類時,JVM 會確保這個類已經被加載、鏈接(驗證、準備和解析)和初始化。類的加載是指把類的.class 文件中的數據讀入到內存中,一般是建立一個字節數組讀入.class 文件,而後產生與所加載類對應的 Class 對象。加載完成後,Class 對象還不完整,因此此時的類還不可用。當類被加載後就進入鏈接階段,這一階段包括驗證、準備(爲靜態變量分配內存並設置默認的初始值)和解析(將符號引用替換爲直接引用)三個步驟。最後 JVM 對類進行初始化,包括:

1)若是類存在直接的父類而且這個類尚未被初始化,那麼就先初始化父類;

2)若是類中存在初始化語句,就依次執行這些初始化語句。

從 Java 2(JDK 1.2)開始,類加載過程採起了雙親委託機制(PDM)。PDM 更好的保證了 Java 平臺的安全性,在該機制中,JVM 自帶的 Bootstrap 是根加載器,其餘的加載器都有且僅有一個父類加載器。類的加載首先請求父類加載器加載,父類加載器無能爲力時才由其子類加載器自行加載。

1三、interface能夠有方法的實現嗎?【中等】

答:jdk1.8之後有方法的實現,用default修飾。

1四、是否能夠從一個static 方法內部發出對非static 方法的調用?【基礎】

答:不能夠,若是其中包含對象的method(),不能保證對象初始化。

1五、GC 是什麼? 爲何要有GC? 【基礎】

答:GC 是垃圾收集的意思(Gabage Collection),內存處理是編程人員容易出現問題的地方,忘記或者錯誤的內存回收會致使程序或系統的不穩定甚至崩潰,Java 提供的GC 功能能夠自動監測對象是否超過做用域從而達到自動回收內存的目的,Java 語言沒有提供釋放已分配內存的顯示操做方法。Java 程序員不用擔憂內存管理,由於垃圾收集器會自動進行管理。要請求垃圾收集,能夠調用下面的方法之一:System.gc() 或Runtime.getRuntime().gc()

1六、垃圾回收器的基本原理是什麼?垃圾回收器能夠立刻回收內存嗎?有什麼辦法主動通知虛擬機進行垃圾回收?【基礎】

答:對於GC 來講,當程序員建立對象時,GC 就開始監控這個對象的地址、大小以及使用狀況。一般,GC 採用有向圖的方式記錄和管理堆(heap)中的全部對象。經過這種方式肯定哪些對象是"可達的",哪些對象是"不可達的"。當GC 肯定一些對象爲"不可達"時,GC 就有責任回收這些內存空間。能夠。程序員能夠手動執行System.gc(),通知GC 運行,可是Java 語言規範並不保證GC 必定會執行。

1七、一個「.java」源文件中是否能夠包含多個類(不是內部類)?有什麼限制?【基礎】

答:能夠;必須只有一個類名與文件名相同。

1八、Java 中的 final 關鍵字有哪些用法?【基礎】

答:(1)修飾類:表示該類不能被繼承;(2)修飾方法:表示方法不能被重寫;(3)修飾變量:表示變量只能一次賦值之後值不能被修改(常量)。

1九、編碼轉換:怎樣將GB2312 編碼的字符串轉換爲ISO-8859-1 編碼的字符串?【基礎】

答:示例代碼以下:

String s1 = "你好";

String s2 = new String(s1.getBytes("GB2312"), "ISO-8859-1");

20、error 和exception 有什麼區別? 【基礎】

答:error 表示系統級的錯誤和程序沒必要處理的異常,是恢復不是不可能但很困難的狀況下的一種嚴重問題;好比內存溢出,不可能期望程序能處理這樣的狀況;exception 表示須要捕捉或者須要程序進行處理的異常,是一種設計或實現問題;也就是說,它表示若是程序運行正常,從不會發生的狀況。

2一、try{}裏有一個return語句,那麼緊跟在這個try後的finally{}裏的代碼會不會被執行,何時被執行,在return前仍是後?【基礎】

答:會執行,在方法返回調用者前執行。

注意:在finally中改變返回值的作法是很差的,由於若是存在finally代碼塊,try中的return語句不會立馬返回調用者,而是記錄下返回值待finally代碼塊執行完畢以後再向調用者返回其值,而後若是在finally中修改了返回值,就會返回修改後的值。顯然,在finally中返回或者修改返回值會對程序形成很大的困擾,C#中直接用編譯錯誤的方式來阻止程序員幹這種齷齪的事情,Java中也能夠經過提高編譯器的語法檢查級別來產生警告或錯誤,Eclipse中能夠在如圖所示的地方進行設置,強烈建議將此項設置爲編譯錯誤。

2二、List,Set,Map 是否繼承自Collection 接口?【基礎】

答:List,Set 是;Map 不是。

2三、說出ArrayList,Vector, LinkedList 的存儲性能和特性?【基礎】

答:ArrayList 和Vector 都是使用數組方式存儲數據,此數組元素數大於實際存儲的數據以便增長和插入元素,它們都容許直接按序號索引元素,可是插入元素要涉及數組元素移動等內存操做,因此索引數據快而插入數據慢,Vector 因爲使用了synchronized 方法(線程安全),一般性能上較ArrayList 差,而LinkedList 使用雙向鏈表實現存儲,按序號索引數據須要進行前向或後向遍歷,可是插入數據時只須要記錄本項的先後項便可,因此插入速度較快。

2四、HashMap 和Hashtable 的區別? 【基礎】

答:兩者都實現了Map 接口,是將唯一鍵映射到特定的值上;主要區別在於:

1)HashMap 沒有排序,容許一個null 鍵和多個null 值,而Hashtable 不容許;

2)HashMap 把Hashtable 的contains 方法去掉了,改爲containsvalue 和containsKey,由於contains 方法容易讓人引發誤解;

3)Hashtable 繼承自Dictionary 類,HashMap 是Java1.2 引進的Map 接口的實現;

4)Hashtable 的方法是Synchronize 的,而HashMap 不是,在多個線程訪問Hashtable 時,不須要本身爲它的方法實現同步,而HashMap 就必須爲之提供外同步。Hashtable 和HashMap 採用的hash/rehash 算法大體同樣,因此性能不會有很大的差別。

2五、Arraylist 與Vector 區別?【基礎】

答:就ArrayList 與Vector 主要從二方面來講:

1)同步性:Vector 是線程安全的(同步),而ArrayList 是線程序不安全的;

2)數據增加:當須要增加時,Vector 默認增加一倍,而ArrayList 倒是一半。

2六、List、Map、Set 三個接口,存取元素時,各有什麼特色?【基礎】

答:List 以特定次序來持有元素,可有重複元素。Set 沒法擁有重複元素,內部排序。Map 保存key-value 值,value 可多值。

2七、sleep() 和wait() 有什麼區別? 【基礎】

答:sleep 是線程類(Thread)的方法,致使此線程暫停執行指定時間,給執行機會給其餘線程,可是監控狀態依然保持,到時後會自動恢復。調用sleep 不會釋放對象鎖。wait 是Object 類的方法,對此對象調用wait 方法致使本線程放棄對象鎖,進入等待此對象的等待鎖定池,只有針對此對象發出notify 方法(或notifyAll)後本線程才進入對象鎖定池準備得到對象鎖進入運行狀態。

2八、當一個線程進入一個對象的一個synchronized 方法後,其它線程是否可進入此對象的其它方法? 【基礎】

答:其它線程只能訪問該對象的其它非同步方法,同步方法則不能進入。

2九、多線程有幾種實現方法,都是什麼?同步有幾種實現方法,都是什麼? 【基礎】

答:多線程有兩種實現方法,分別是繼承Thread 類與實現Runnable 接口,同步的實現方面有兩種,分別是synchronized,wait 與notify。

30、當一個線程進入一個對象的 synchronized 方法 A 以後,其它線程是否可進入此對象的 synchronized 方法 B?【中等】

答:不能。其它線程只能訪問該對象的非同步方法,同步方法則不能進入。由於非靜態方法上的 synchronized 修飾符要求執行方法時要得到對象的鎖,若是已經進入 A 方法說明對象鎖已經被取走,那麼試圖進入 B 方法的線程就只能在等鎖池(注意不是等待池哦)中等待對象的鎖

3一、簡述synchronized 和java.util.concurrent.locks.Lock 的異同?【中等】

答:主要相同點:Lock 能完成synchronized 所實現的全部功能;主要不一樣點:Lock 有比synchronized 更精確的線程語義和更好的性能。synchronized 會自動釋放鎖,而Lock 必定要求程序員手工釋放,而且必須在finally 從句中釋放。

3二、編寫多線程程序有幾種實現方式?【中等】

答:Java 5 之前實現多線程有兩種實現方法:一種是繼承 Thread 類;另外一種是實現 Runnable 接口。兩種方式都要經過重寫 run()方法來定義線程的行爲,推薦使用後者,由於 Java 中的繼承是單繼承,一個類有一個父類,若是繼承了 Thread 類就沒法再繼承其餘類了,顯然使用 Runnable 接口更爲靈活。

補充:Java 5 之後建立線程還有第三種方式:實現 Callable 接口,該接口中的 call 方法能夠在線程執行結束時產生一個返回值,代碼以下所示:

import java.util.ArrayList;

import java.util.List;
import java.util.concurrent.Callable;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import java.util.concurrent.Future;


class MyTask implements Callable<Integer> {

    private int upperBounds;

    public MyTask(int upperBounds) {
    
        this.upperBounds = upperBounds;
    }

    @Override

    public Integer call() throws Exception {
      int sum = 0;

        for(int i = 1; i <= upperBounds; i++) {

            sum += i;
        }

    return sum;

    }

}

class Test {

    public static void main(String[] args) throws Exception { 
    List<Future<Integer>> list = new ArrayList<>(); 
    ExecutorService service = Executors.newFixedThreadPool(10);

    for(int i = 0; i < 10; i++) {

        list.add(service.submit(new MyTask((int) (Math.random() * 100))));
    }

    int sum = 0;

    for(Future<Integer> future : list) {

        //while(!future.isDone()) ; 
        sum += future.get();

    }

    System.out.println(sum);

    }
}

3三、Java 中如何實現序列化,有什麼意義?【中等】

答:序列化就是一種用來處理對象流的機制,所謂對象流也就是將對象的內容進行流化。能夠對流化後的對象進行讀寫操做,也可將流化後的對象傳輸於網絡之間。序列化是爲了解決對象流讀寫操做時可能引起的問題(若是不進行序列化可能會存在數據亂序的問題)。要實現序列化,須要讓一個類實現 Serializable 接口,該接口是一個標識性接口,標註該類對象是可被序列化的,而後使用一個輸出流來構造一個對象輸出流並經過 writeObject(Object)方法就能夠將實現對象寫出(即保存其狀態);若是須要反序列化則能夠用一個輸入流創建對象輸入流,而後經過 readObject 方法從流中讀取對象。

2、數據庫

3四、闡述 JDBC 操做數據庫的步驟。【基礎】

答:下面的代碼以鏈接本機的 Oracle 數據庫爲例,演示 JDBC 操做數據庫的步驟。

//加載驅動。
Class.forName("oracle.jdbc.driver.OracleDriver");

//建立鏈接。
Connection con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:orcl", "scott", "tiger");

//建立語句。
PreparedStatement ps = con.prepareStatement("select * from emp where sal between ? and ?"); ps.setInt(1, 1000);

ps.setInt(2, 3000);

//執行語句。
ResultSet rs = ps.executeQuery();

//處理結果。
while(rs.next()) {
    System.out.println(rs.getInt("empno") + " - " + rs.getString("ename"));
}

//關閉資源。
finally {
    if(con != null) {
        try {
            con.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

提示:關閉外部資源的順序應該和打開的順序相反,也就是說先關閉 ResultSet、再關閉Statement、在關閉 Connection。上面的代碼只關閉了 Connection(鏈接),雖然一般狀況下在關閉鏈接時,鏈接上建立的語句和打開的遊標也會關閉,但不能保證老是如此,所以應該按照剛纔說的順序分別關閉。此外,第一步加載驅動在 JDBC 4.0 中是能夠省略的(自動從類路徑中加載驅動),可是咱們建議保留。

3五、使用 JDBC 操做數據庫時,如何提高讀取數據的性能?如何提高更新數據的性能?【中等】

答:要提高讀取數據的性能,能夠指定經過結果集(ResultSet)對象的 setFetchSize()方法指定每次抓取的記錄數(典型的空間換時間策略);要提高更新數據的性能能夠使用 PreparedStatement 語句構建批處理,將若干 SQL 語句置於一個批處理中執行。

3六、在進行數據庫編程時,鏈接池有什麼做用?【基礎】

答:因爲建立鏈接和釋放鏈接都有很大的開銷(尤爲是數據庫服務器不在本地時,每次創建鏈接都須要進行 TCP 的三次握手,釋放鏈接須要進行 TCP 四次握手,形成的開銷是不可忽視的),爲了提高系統訪問數據庫的性能,能夠事先建立若干鏈接置於鏈接池中,須要時直接從鏈接池獲取,使用結束時歸還鏈接池而沒必要關閉鏈接,從而避免頻繁建立和釋放鏈接所形成的開銷,這是典型的用空間換取時間的策略(浪費了空間存儲鏈接,但節省了建立和釋放鏈接的時間)。池化技術在 Java 開發中是很常見的,在使用線程時建立線程池的道理與此相同。基於 Java 的開源數據庫鏈接池主要有:C3P0、Proxool、DBCP、BoneCP、Druid 等。

3七、事務的ACID是指什麼?【基礎】

答:

  • 原子性(Atomic):事務中各項操做,要麼全作要麼全不作,任何一項操做的失敗都會致使整個事務的失敗;

  • 一致性(Consistent):事務結束後系統狀態是一致的;

  • 隔離性(Isolated):併發執行的事務彼此沒法看到對方的中間狀態;
  • 持久性(Durable):事務完成後所作的改動都會被持久化,即便發生災難性的失敗。經過日誌和同步備份能夠在故障發生後重建數據。

3八、談談髒讀、幻讀和不可重複讀?【中等】

髒讀(Dirty Read):A 事務讀取 B 事務還沒有提交的數據並在此基礎上操做,而 B 事務執行回滾,那麼 A 讀取到的數據就是髒數據。

時間轉帳事務 A 取款事務 B
T1 開始事務
T2 開始事務
T3 查詢帳戶餘額爲 1000 元
T4 取出 500 元餘額修改成 500
T5 查詢帳戶餘額爲 500 元(髒讀)
T6 撤銷事務餘額恢復爲 1000 元
T7 匯入 100 元把餘額修改成 600 元
T8 提交事務

不可重複讀(Unrepeatable Read):事務 A 從新讀取前面讀取過的數據,發現該數據已經被另外一個已提交的事務 B 修改過了。

時間轉帳事務 A 取款事務 B
T1 開始事務
T2 開始事務
T3 查詢帳戶餘額爲 1000 元
T4 查詢帳戶餘額爲 1000 元
T5 取出 100 元修改餘額爲 900 元
T6 提交事務
T7 查詢帳戶餘額爲 900 元(不可重複讀)

幻讀(Phantom Read):事務 A 從新執行一個查詢,返回一系列符合查詢條件的行,發現其中插入了被事務 B 提交的行。

時間統計金額事務 A 轉帳事務 B
T1 開始事務
T2 開始事務
T3 統計總存款爲 10000 元
T4 新增一個存款帳戶存入 100 元
T5 提交事務
T6 再次統計總存款爲 10100 元(幻讀)

第 1 類丟失更新:事務 A 撤銷時,把已經提交的事務 B 的更新數據覆蓋了。

時間取款事務 A 轉帳事務 B

時間取款事務 A 轉帳事務 B
T1 開始事務
T2 開始事務
T3 查詢帳戶餘額爲 1000 元
T4 查詢帳戶餘額爲 1000 元
T5 匯入 100 元修改餘額爲 1100 元
T6 提交事務
T7 取出 100 元將餘額修改成 900 元
T8 撤銷事務
T9 餘額恢復爲 1000 元(丟失更新)
第 2 類丟失更新:事務 A 覆蓋事務 B 已經提交的數據,形成事務 B 所作的操做丟失。
時間轉帳事務 A 取款事務 B
T1 開始事務
T2 開始事務
T3 查詢帳戶餘額爲 1000 元
T4 查詢帳戶餘額爲 1000 元
T5 取出 100 元將餘額修改成 900 元
T6 提交事務
T7 匯入 100 元將餘額修改成 1100 元
T8 提交事務
T9 查詢帳戶餘額爲 1100 元(丟失更新)

數據併發訪問所產生的問題,在有些場景下多是容許的,可是有些場景下可能就是致命的,數據庫一般會經過鎖機制來解決數據併發訪問問題,按鎖定對象不一樣能夠分爲表級鎖和行級鎖;按併發事務鎖定關係能夠分爲共享鎖和獨佔鎖,具體的內容你們能夠自行查閱資料進行了解。直接使用鎖是很是麻煩的,爲此數據庫爲用戶提供了自動鎖機制,只要用戶指定會話的事務隔離級別,數據庫就會經過分析 SQL 語句而後爲事務訪問的資源加上合適的鎖,此外,數據庫還會維護這些鎖經過各類手段提升系統的性能,這些對用戶來講都是透明的(就是說你不用理解,事實上我確實也不知道)。

ANSI/ISO SQL 92 標準定義了4 個等級的事務隔離級別,以下表所示:

隔離級別 髒讀 不可重複讀幻讀 第一類丟失更新第二類丟失更新
READ UNCOMMITED 容許 容許 容許 不容許 容許
READ COMMITTED 不容許 容許 容許 不容許 容許
REPEATABLE READ 不容許 不容許 容許 不容許 不容許
SERIALIZABLE 不容許 不容許 不容許 不容許 不容許

須要說明的是,事務隔離級別和數據訪問的併發性是對立的,事務隔離級別越高併發性就越差。因此要根據具體的應用來肯定合適的事務隔離級別,這個世界沒有萬能的原則。

3九、JDBC中如何進行事務處理?【中等】

答:Connection 提供了事務處理的方法,經過調用setAutoCommit(false)能夠設置手動提交事務;當事務完成後用 commit()顯式提交事務;若是在事務處理過程當中發生異常則經過 rollback()進行事務回滾。除此以外,從 JDBC 3.0 中還引入了 Savepoint(保存點)的概念,容許經過代碼設置保存點並讓事務回滾到指定的保存點。

40、得到一個類的類對象有哪些方式?【基礎】

答:

  • 方法 1:類型.class,例如:String.class

  • 方法 2:對象.getClass(),例如:"hello".getClass()

  • 方法 3:Class.forName(),例如:Class.forName("java.lang.String")

4一、JSP 有哪些內置對象?做用分別是什麼?【基礎】

答:JSP 有 9 個內置對象:

  • request:封裝客戶端的請求,其中包含來自 GET 或 POST 請求的參數;

  • response:封裝服務器對客戶端的響應;

  • pageContext:經過該對象能夠獲取其餘對象;

  • session:封裝用戶會話的對象;

  • application:封裝服務器運行環境的對象;

  • out:輸出服務器響應的輸出流對象;

  • config:Web 應用的配置對象;

  • page:JSP 頁面自己(至關於 Java 程序中的 this);

  • exception:封裝頁面拋出異常的對象。

4二、get 和 post 請求的區別?【基礎】

答:①get 請求用來從服務器上得到資源,而 post 是用來向服務器提交數據;

②get 將表單中數據按照 name=value 的形式,添加到 action 所指向的 URL 後面,而且二者使用"?"鏈接,而各個變量之間使用"&"鏈接;post 是將表單中的數據放在 HTTP 協議的請求頭或消息體中,傳遞到 action 所指向 URL;

③get 傳輸的數據要受到 URL 長度限制(1024 字節);而 post 能夠傳輸大量的數據,上傳文件一般要使用 post 方式;

④使用 get 時參數會顯示在地址欄上,若是這些數據不是敏感數據,那麼能夠使用 get;對於敏感數據仍是應用使用 post;

⑤get 使用 MIME 類型 application/x-www-form-urlencoded 的 URL 編碼(也叫百分號編碼)

文本的格式傳遞參數,保證被傳送的參數由遵循規範的文本組成,例如一個空格的編碼是"%20"。

4三、講解 JSP 中的四種做用域。【基礎】

答:JSP 中的四種做用域包括 page、request、session 和 application,具體來講:

  • page 表明與一個頁面相關的對象和屬性。

  • request 表明與 Web 客戶機發出的一個請求相關的對象和屬性。一個請求可能跨越多個頁面,涉及多個 Web 組件;須要在頁面顯示的臨時數據能夠置於此做用域。

  • session 表明與某個用戶與服務器創建的一次會話相關的對象和屬性。跟某個用戶相關的數據應該放在用戶本身的 session 中。

  • application 表明與整個 Web 應用程序相關的對象和屬性,它實質上是跨越整個 Web 應用程序,包括多個頁面、請求和會話的一個全局做用域。

3、SSM框架

4四、MyBatis 中使用#和$書寫佔位符有什麼區別?【中等】

答:#將傳入的數據都當成一個字符串,會對傳入的數據自動加上引號;$將傳入的數據直接顯示生成在 SQL 中。注意:使用$佔位符可能會致使 SQL 注射攻擊,能用#的地方就不要使用$,寫 order by 子句的時候應該用$而不是#。

4五、解釋一下 MyBatis 中命名空間(namespace)的做用。【中等】

答:在大型項目中,可能存在大量的 SQL 語句,這時候爲每一個 SQL 語句起一個惟一的標識(ID)就變得並不容易了。爲了解決這個問題,在 MyBatis 中,能夠爲每一個映射文件起一個惟一的命名空間,這樣定義在這個映射文件中的每一個 SQL 語句就成了定義在這個命名空間中的一個 ID。只要咱們可以保證每一個命名空間中這個 ID 是惟一的,即便在不一樣映射文件中的語句 ID 相同,也不會再產生衝突了。

4六、什麼是 IoC 和 DI?DI 是如何實現的?【中等】

答:IoC 叫控制反轉,是 Inversion of Control 的縮寫,DI(Dependency Injection)叫依賴注入,是對 IoC 更簡單的詮釋。控制反轉是把傳統上由程序代碼直接操控的對象的調用權交給容器,經過容器來實現對象組件的裝配和管理。所謂的"控制反轉"就是對組件對象控制權的轉移,從程序代碼自己轉移到了外部容器,由容器來建立對象並管理對象之間的依賴關係。IoC 體現了好萊塢原則 - "Don’t call me, we will call you"。依賴注入的基本原則是應用組件不該該負責查找資源或者其餘依賴的協做對象。配置對象的工做應該由容器負責,查找資源的邏輯應該從應用組件的代碼中抽取出來,交給容器來完成。DI 是對 IoC 更準確的描述,即組件之間的依賴關係由容器在運行期決定,形象的來講,即由容器動態的將某種依賴關係注入到組件之中。

4七、解釋一下什麼叫 AOP(面向切面編程)?【基礎】

答:AOP(Aspect-Oriented Programming)指一種程序設計範型,該範型以一種稱爲切面(aspect)的語言構造爲基礎,切面是一種新的模塊化機制,用來描述分散在對象、類或方法中的橫切關注點(crosscutting concern)。

4八、你是如何理解"橫切關注"這個概念的?【中等】

答:"橫切關注"是會影響到整個應用程序的關注功能,它跟正常的業務邏輯是正交的,沒有必然的聯繫,可是幾乎全部的業務邏輯都會涉及到這些關注功能。一般,事務、日誌、安全性等關注就是應用中的橫切關注功能。

4九、你如何理解 AOP 中的鏈接點(Joinpoint)、切點(Pointcut)、加強(Advice)、引介(Introduction)、織入(Weaving)、切面(Aspect)這些概念?【基礎】

答:a. 鏈接點(Joinpoint):程序執行的某個特定位置(如:某個方法調用前、調用後,方法拋出異常後)。一個類或一段程序代碼擁有一些具備邊界性質的特定點,這些代碼中的特定點就是鏈接點。Spring 僅支持方法的鏈接點。

b. 切點(Pointcut):若是鏈接點至關於數據中的記錄,那麼切點至關於查詢條件,一個切點能夠匹配多個鏈接點。Spring AOP 的規則解析引擎負責解析切點所設定的查詢條件,找到對應的鏈接點。

c. 加強(Advice):加強是織入到目標類鏈接點上的一段程序代碼。Spring 提供的加強接口都是帶方位名的,如:BeforeAdvice、AfterReturningAdvice、ThrowsAdvice 等。不少資料上將加強譯爲「通知」,這明顯是個詞不達意的翻譯,讓不少程序員困惑了許久。

說明: Advice 在國內的不少書面資料中都被翻譯成"通知",可是很顯然這個翻譯沒法表達其本質,有少許的讀物上將這個詞翻譯爲"加強",這個翻譯是對 Advice 較爲準確的詮釋,咱們經過 AOP 將橫切關注功能加到原有的業務邏輯上,這就是對原有業務邏輯的一種加強,這種加強能夠是前置加強、後置加強、返回後加強、拋異常時加強和包圍型加強。

d. 引介(Introduction):引介是一種特殊的加強,它爲類添加一些屬性和方法。這樣,即便一個業務類本來沒有實現某個接口,經過引介功能,能夠動態的未該業務類添加接口的實現邏輯,讓業務類成爲這個接口的實現類。

e. 織入(Weaving):織入是將加強添加到目標類具體鏈接點上的過程,AOP 有三種織入方式:①編譯期織入:須要特殊的 Java 編譯期(例如 AspectJ 的 ajc);②裝載期織入:要求使用特殊的類加載器,在裝載類的時候對類進行加強;③運行時織入:在運行時爲目標類生成代理實現加強。Spring 採用了動態代理的方式實現了運行時織入,而 AspectJ 採用了編譯期織入和裝載期織入的方式。

f. 切面(Aspect):切面是由切點和加強(引介)組成的,它包括了對橫切關注功能的定義,也包括了對鏈接點的定義。

50、Spring 支持的事務管理類型有哪些?你在項目中使用哪一種方式?【中等】

答:Spring 支持編程式事務管理和聲明式事務管理。許多 Spring 框架的用戶選擇聲明式事務管理,由於這種方式和應用程序的關聯較少,所以更加符合輕量級容器的概念。聲明式事務管理要優於編程式事務管理,儘管在靈活性方面它弱於編程式事務管理,由於編程式事務容許你經過代碼控制業務。

5一、Spring MVC的工做原理是怎樣的?【基礎】

答:SpringMVC工做原理圖以下:

① 客戶端的全部請求都交給前端控制器 DispatcherServlet 來處理,它會負責調用系統的其餘模塊來真正處理用戶的請求。

② DispatcherServlet 收到請求後,將根據請求的信息(包括 URL、HTTP 協議方法、請求頭、請求參數、Cookie 等)以及 HandlerMapping 的配置找處處理該請求的 Handler(任何一個對象均可以做爲請求的 Handler)。

③在這個地方 Spring 會經過 HandlerAdapter 對該處理器進行封裝。

④ HandlerAdapter 是一個適配器,它用統一的接口對各類 Handler 中的方法進行調用。

⑤ Handler 完成對用戶請求的處理後,會返回一個 ModelAndView 對象給 DispatcherServlet, ModelAndView 顧名思義,包含了數據模型以及相應的視圖的信息。

⑥ ModelAndView 的視圖是邏輯視圖,DispatcherServlet 還要藉助 ViewResolver 完成從邏輯視圖到真實視圖對象的解析工做。

⑦ 當獲得真正的視圖對象後,DispatcherServlet 會利用視圖對象對模型數據進行渲染。

⑧ 客戶端獲得響應,多是一個普通的 HTML 頁面,也能夠是 XML 或 JSON 字符串,還能夠是一張圖片或者一個 PDF 文件。

5二、什麼是 XSS 攻擊?【困難】

答: XSS(Cross Site Script,跨站腳本攻擊)是向網頁中注入惡意腳本在用戶瀏覽網頁時在用戶瀏覽器中執行惡意腳本的攻擊方式。跨站腳本攻擊分有兩種形式:反射型攻擊(誘使用戶點擊一個嵌入惡意腳本的連接以達到攻擊的目標,目前有不少攻擊者利用論壇、微博發佈含有惡意腳本的 URL 就屬於這種方式)和持久型攻擊(將惡意腳本提交到被攻擊網站的數據庫中,用戶瀏覽網頁時,惡意腳本從數據庫中被加載到頁面執行,QQ 郵箱的早期版本就曾經被利用做爲持久型跨站腳本攻擊的平臺)。XSS 雖然不是什麼新鮮玩意,可是攻擊的手法卻不斷翻新,防範 XSS 主要有兩方面:消毒(對危險字符進行轉義)和 HttpOnly (防範 XSS 攻擊者竊取 Cookie 數據)。

5三、SQL 注入攻擊?【困難】

答: SQL 注入攻擊是注入攻擊最多見的形式(此外還有 OS 注入攻擊(Struts 2 的高危漏洞就是經過 OGNL 實施 OS 注入攻擊致使的)),當服務器使用請求參數構造 SQL 語句時,惡意的 SQL 被嵌入到 SQL 中交給數據庫執行。SQL 注入攻擊須要攻擊者對數據庫結構有所瞭解才能進行,攻擊者想要得到表結構有多種方式:(1)若是使用開源系統搭建網站,數據庫結構也是公開的(目前有不少現成的系統能夠直接搭建論壇,電商網站,雖然方便快 捷可是風險是必需要認真評估的);(2)錯誤回顯(若是將服務器的錯誤信息直接顯示在頁面上,攻擊者能夠經過非法參數引起頁面錯誤從而經過錯誤信息瞭解數據庫結構,Web應用應當設置友好的錯誤頁,一方面符合最小驚訝原則,一方面屏蔽掉可能給系統帶來危險的錯誤回顯信息);(3)盲注。防範 SQL 注入攻擊也能夠採用消毒的方式,經過正則表達式對請求參數進行驗證,此外,參數綁定也是很好的手段,這樣惡意的 SQL 會被當作 SQL 的參數而不是命令被執行,JDBC 中的 PreparedStatement 就是支持參數綁定的語句對象,從性能和安全性上都明顯優於 Statement。

5四、什麼是CSRF攻擊?【困難】

答: CSRF 攻擊(Cross Site Request Forgery,跨站請求僞造)是攻擊者經過跨站請求,以合法的用戶身份進行非法操做(如轉帳或發帖等)。CSRF 的原理是利用瀏覽器的 Cookie 或服務器的 Session,盜取用戶身份,其原理以下圖所示。防範 CSRF 的主要手段是識別請求者的身份,主要有如下幾種方式:

(1)在表單中添加令牌(token);

(2)驗證碼;

(3)檢查請求頭中的 Referer。

令牌和驗證都具備一次消費性的特徵,所以在原理上一致的,可是驗證碼是一種糟糕的用戶體驗,不是必要的狀況下不要輕易使用驗證碼,目前不少網站的作法是若是在短期內屢次提交一個表單未得到成功後纔要求提供驗證碼,這樣會得到較好的用戶體驗。

4、redis

5五、使用redis有哪些好處?【基礎】

答:

  • 速度快,由於數據存在內存中,相似於HashMap,HashMap的優點就是查找和操做的時間複雜度都是O(1)

  • 支持豐富數據類型,支持string,list,set,sorted set,hash

  • 支持事務,操做都是原子性,所謂的原子性就是對數據的更改要麼所有執行,要麼所有不執行

  • 豐富的特性:可用於緩存,消息,按key設置過時時間,過時後將會自動刪除

5六、Redis有哪些數據結構?【基礎】

答:字符串String、字典Hash、列表List、集合Set、有序集合SortedSet。

5七、若是有大量的key須要設置同一時間過時,通常須要注意什麼?【中等】

答:若是大量的key過時時間設置的過於集中,到過時的那個時間點,redis可能會出現短暫的卡頓現象。通常須要在時間上加一個隨機值,使得過時時間分散一些。

5八、爲何Redis須要把全部數據放到內存中?【中等】

答:Redis爲了達到最快的讀寫速度將數據都讀到內存中,並經過異步的方式將數據寫入磁盤。因此redis具備快速和數據持久化的特徵。若是不將數據放在內存中,磁盤I/O速度爲嚴重影響redis的性能。在內存愈來愈便宜的今天,redis將會愈來愈受歡迎。 若是設置了最大使用的內存,則數據已有記錄數達到內存限值後不能繼續插入新值。

5九、Redis提供了哪幾種持久化方式?【中等】

答:

  1. RDB持久化方式可以在指定的時間間隔能對你的數據進行快照存儲。
  2. AOF持久化方式記錄每次對服務器寫的操做,當服務器重啓的時候會從新執行這些命令來恢復原始的數據,AOF命令以redis協議追加保存每次寫的操做到文件末尾。Redis還能對AOF文件進行後臺重寫,使得AOF文件的體積不至於過大。
  3. 若是你只但願你的數據在服務器運行的時候存在,你也能夠不使用任何持久化方式。
  4. 你也能夠同時開啓兩種持久化方式, 在這種狀況下, 當redis重啓的時候會優先載入AOF文件來恢復原始的數據,由於在一般狀況下AOF文件保存的數據集要比RDB文件保存的數據集要完整。
  5. 最重要的事情是瞭解RDB和AOF持久化方式的不一樣,讓咱們以RDB持久化方式開始。

60、如何選擇合適的持久化方式?【中等】

答:通常來講, 若是想達到足以媲美PostgreSQL的數據安全性, 你應該同時使用兩種持久化功能。若是你很是關心你的數據, 但仍然能夠承受數分鐘之內的數據丟失,那麼你能夠只使用RDB持久化。

有不少用戶都只使用AOF持久化,但並不推薦這種方式:由於定時生成RDB快照(snapshot)很是便於進行數據庫備份, 而且 RDB 恢復數據集的速度也要比AOF恢復的速度要快,除此以外, 使用RDB還能夠避免以前提到的AOF程序的bug。

6一、redis支持的java客戶端你用過哪一個?【基礎】

答: Jedis,Jedis是Redis的Java實現的客戶端,其API提供了比較全面的Redis命令的支持。

6二、Redis集羣的主從複製模型是怎樣的?【困難】

答:爲了使在部分節點失敗或者大部分節點沒法通訊的狀況下集羣仍然可用,因此集羣使用了主從複製模型,每一個節點都會有N-1個複製品。

6三、Redis集羣之間是如何複製的?【中等】

答:異步複製。

6四、怎麼測試Redis的連通性?【基礎】

ping。

5、消息隊列

6五、爲何要用消息隊列?【中等】

解耦、異步、削峯

  • A系統調用B系統、C系統,傳統的調用是直接調用,可是當B系統說我不須要你提供數據了,這時候A須要改代碼,C系統說我不須要某個字段了,這時候A也要改代碼,若是又多了一個D系統,A又要寫代碼。爲了實現解耦,引入消息隊列,A將產生的數據丟到消息隊列中,哪一個系統須要 哪一個系統就去取;
  • A系統調用B系統,B系統因爲某個須要調用第三方接口超時,致使A系統響應速度慢,而B系統的好壞又不會影響業務邏輯,因此能夠改成A異步調用B,A將消息丟到消息隊列中,B系統訂閱消息,實現A的快速響應;
  • 當大量流量請求到系統A時,因爲數據庫的處理能力有限,形成數據庫鏈接異常。使用消息隊列,大量請求先丟到消息隊列中,系統A使用按批拉數據的方式,批量處理數據,生產中,高峯期短暫的消息積壓是容許的。

6六、使用消息隊列有什麼缺點【中等】

  • 系統複雜性增長:加了消息隊列,須要保證消息不會重複消費,須要保證消息的可靠性,須要保證消息隊列的高可用
  • 系統的可用性下降:若是消息隊列掛了,那麼系統也會受到影響

6七、爲何選用RocketMQ;RocketMQ和ActiveMQ的區別【困難】

RocketMQ模型簡單、接口易用,在阿里大規模使用,社區活躍,單機吞吐量10萬級,可用性很是高,消息理論上不會丟失;

  • ActiveMQ嚴格遵循JMS規範,可持久化到內存、文件、數據庫,可用性高主要是主從,多語言支持,消失丟失率低;
  • RocketMQ持久化到磁盤文件,可用性很是高,支持分佈式,只支持Java,消息理論上不會丟失;

6八、RocketMQ是怎麼保證系統高可用的?【困難】

  • 多Master部署,防止單點故障;
  • 主從結構,消息冗餘,防止消息丟失;

6九、消息中間件集羣崩潰,如何保證百萬生產數據不丟失?【中等】
答: 把消息持久化寫入到磁盤上去 。

6、spring boot

70、Spring Boot 的核心配置文件有哪幾個?它們的區別是什麼?【中等】

Spring Boot 的核心配置文件是 application 和 bootstrap 配置文件。

application 配置文件這個容易理解,主要用於 Spring Boot 項目的自動化配置。

bootstrap 配置文件有如下幾個應用場景:

  • 使用 Spring Cloud Config 配置中心時,這時須要在 bootstrap 配置文件中添加鏈接到配置中心的配置屬性來加載外部配置中心的配置信息;

  • 一些固定的不能被覆蓋的屬性;

  • 一些加密/解密的場景;

7一、Spring Boot 的配置文件有哪幾種格式?它們有什麼區別?【中等】

.properties 和 .yml,它們的區別主要是書寫格式不一樣。

1).properties

app.user.name = javastack

2).yml

app:
  user:
    name: javastack

另外,.yml 格式不支持 @PropertySource 註解導入配置。

7二、Spring Boot 的核心註解是哪一個?它主要由哪幾個註解組成的?【基礎】

啓動類上面的註解是@SpringBootApplication,它也是 Spring Boot 的核心註解,主要組合包含了如下 3 個註解:

  • @SpringBootConfiguration:組合了 @Configuration 註解,實現配置文件的功能。

  • @EnableAutoConfiguration:打開自動配置的功能,也能夠關閉某個自動配置的選項,如關閉數據源自動配置功能:@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })。

  • @ComponentScan:Spring組件掃描。

7三、開啓 Spring Boot 特性有哪幾種方式?【基礎】

1)繼承spring-boot-starter-parent項目

2)導入spring-boot-dependencies項目依賴

7四、Spring Boot 須要獨立的容器運行嗎?【基礎】

能夠不須要,內置了 Tomcat/ Jetty 等容器。
7五、如何在 Spring Boot 啓動的時候運行一些特定的代碼?【中等】

Spring Boot Runner啓動器,能夠實現接口 ApplicationRunner 或者 CommandLineRunner,這兩個接口實現方式同樣,它們都只提供了一個 run 方法。

7六、Spring Boot 有哪幾種讀取配置的方式?【中等】

Spring Boot 能夠經過 @PropertySource,@Value,@Environment, @ConfigurationProperties 來綁定變量。

實例:

單個注入:@Value("${book.author}"),

映射一個類:@ConfigurationProperties(prefix="author",locations={"classpath:author.properties"})經過prefix指定前綴,經過locations指定位置
7七、Spring Boot 如何定義多套不一樣環境配置?【中等】

提供多套配置文件,按照application-xxx.properties格式創建文件,並在application.properties中指定。如:

application.properties
 
application-dev.properties
 
application-test.properties
 
application-prod.properties

7八、SpringBoot中的定時任務如何實現?【中等】

經過配置註解@EnableScheduline來開啓對計劃任務的支持,而後再要執行的任務上加註解@Scheduled。

7九、咱們如何鏈接一個像 MYSQL 或者 orcale 同樣的外部數據庫?【中等】

讓咱們以 MySQL 爲例來思考這個問題:

第一步 - 把 mysql 鏈接器的依賴項添加至 pom.xml

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>

第二步 - 配置你的 MySQL 數據庫鏈接

配置 application.properties

spring.datasource.url=jdbc:mysql://localhost:3306/todo_example
spring.datasource.username=todouser
spring.datasource.password=YOUR_PASSWORD

第三步 - 從新啓動,你就準備好了!

7、spring cloud

80、什麼是微服務【中等】

  • 之前的模式是 全部的代碼在同一個工程中 部署在同一個服務器中 同一個項目的不一樣模塊不一樣功能互相搶佔資源

  • 微服務 將工程根據不一樣的業務規則拆分紅微服務 微服務部署在不一樣的機器上 服務之間進行相互調用

  • Java微服務的框架有 dubbo(只能用來作微服務),spring cloud(提供了服務的發現,斷路器等)

8一、微服務之間是如何獨立通信的spring Cloud和 Dubbo有哪些區別?【困難】

答:

  • springcloud服務註冊中心是Spring Cloud Netflix Eureka

    dubbo的註冊中心通常是zookeeper

  • dubbo只是相似Netflix的一個子集只有註冊中心,其餘springcloud組件沒有

  • springcloud的調用方式是REST API

    dubbo的調用方式是RPC

    RPC服務提供方與調用方接口依賴方式太強

    咱們爲每一個微服務定義了各自的service抽象接口

    並經過持續集成發佈到私有倉庫中

    調用方應用對微服務提供的抽象接口存在強依賴關係

    REST方式的服務依賴要比RPC方式的依賴更爲靈活

  • Dubbo的文檔能夠說在國內開源框架中算是一流的,很是全,而且講解的也很是深刻,國內開發者來講,閱讀起來更加容易上手

8二、springcloud如何實現服務的註冊和發現【中等】

  • 服務在發佈時 指定對應的服務名(服務名包括了IP地址和端口) 將服務註冊到註冊中心(eureka或者zookeeper)

  • 這一過程是springcloud自動實現 只須要在main方法添加@EnableDisscoveryClient 同一個服務修改端口就能夠啓動多個實例

  • 調用方法:傳遞服務名稱經過註冊中心獲取全部的可用實例 經過負載均衡策略調用(ribbon和feign)對應的服務

8三、Ribbon和Feign的區別【中等】

Ribbon和Feign都是用於調用其餘服務的,不過方式不一樣。

1.啓動類使用的註解不一樣,Ribbon用的是@RibbonClient,Feign用的是@EnableFeignClients。

2.服務的指定位置不一樣,Ribbon是在@RibbonClient註解上聲明,Feign則是在定義抽象方法的接口中使用@FeignClient聲明。

3.調用方式不一樣,Ribbon須要本身構建http請求,模擬http請求而後使用RestTemplate發送給其餘服務,步驟至關繁瑣。

Feign則是在Ribbon的基礎上進行了一次改進,採用接口的方式,將須要調用的其餘服務的方法定義成抽象方法便可,不須要本身構建http請求。不過要注意的是抽象方法的註解、方法簽名要和提供服務的方法徹底一致。

8四、springcloud斷路器的做用【中等】

當一個服務調用另外一個服務因爲網絡緣由或者自身緣由出現問題時 調用者就會等待被調用者的響應 當更多的服務請求到這些資源時。致使更多的請求等待 這樣就會發生連鎖效應(雪崩效應) 斷路器就是解決這一問題

8五、springcloud如何實現服務的註冊和發現【中等】

答:服務在發佈時 指定對應的服務名,服務名包括了IP地址和端口,將服務註冊到註冊中心eureka或者zookeeper,這一過程是springcloud自動實現,只須要在main方法添加 @ EnableDisscoveryClient,同一個服務修改端口就能夠啓動多個實例。

8六、springcloud中的組件有那些?【中等】

答:獨挑大樑,獨自啓動不須要依賴其它組件

1)Eureka,服務註冊中心,特性有失效剔除、服務保護

2)Dashboard,Hystrix儀表盤,監控集羣模式和單點模式,其中集羣模式須要收集器Turbine配合

3)Zuul,API服務網關,功能有路由分發和過濾

4)Config,分佈式配置中心,支持本地倉庫、SVN、Git、Jar包內配置等模式

潤物無聲,融合在每一個微服務中、依賴其它組件併爲其提供服務

1)Ribbon,客戶端負載均衡,特性有區域親和,重試機制

2)Hystrix,客戶端容錯保護,特性有服務降級、服務熔斷、請求緩存、請求合併、依賴隔離

3)Feign,聲明式服務調用本質上就是Ribbon+Hystrix

4)Stream,消息驅動,有Sink、Source、Processor三種通道,特性有訂閱發佈、消費組、消息分區

5)Bus,消息總線,配合Config倉庫修改的一種Stream實現,

6)Sleuth,分佈式服務追蹤,須要搞清楚TraceID和SpanID以及抽樣,如何與ELK整合

8、其餘

8七、cookie和session的區別【基礎】

一、Cookies是一種可以讓網站服務器把少許數據儲存到客戶端的硬盤或內存,或是從客戶端的硬盤讀取數據的一種技術。Cookies是當你瀏覽某網站時,由Web服務器置於你硬盤上的一個很是小的文本文件,它能夠記錄你的用戶ID、密碼、瀏覽過的網頁、停留的時間等信息。session: 當用戶請求來自應用程序的 Web 頁時,若是該用戶尚未會話,則 Web 服務器將自動建立一個 Session 對象。當會話過時或被放棄後,服務器將終止該會話。cookie機制:採用的是在客戶端保持狀態的方案,而session機制採用的是在服務端保持狀態的方案。同時咱們看到因爲服務器端保持狀態的方案在客戶端也須要保存一個標識,因此session機制可能須要藉助cookie機制來達到保存標識的目的。

二、Session是服務器用來跟蹤用戶的一種手段,每一個Session都有一個惟一標識:session ID。當服務器建立了Session時,給客戶端發送的響應報文包含了Set-cookie字段,其中有一個名爲sid的鍵值對,這個鍵值Session ID。客戶端收到後就把Cookie保存瀏覽器,而且以後發送的請求報表都包含SessionID。HTTP就是經過Session和Cookie這兩個發送一塊兒合做來實現跟蹤用戶狀態,Session用於服務端,Cookie用於客戶端

8八、一次完整的http請求過程【中等】

域名解析 --> 發起TCP的3次握手 --> 創建TCP鏈接後發起http請求 --> 服務器響應http請求,瀏覽器獲得html代碼 --> 瀏覽器解析html代碼,並請求html代碼中的資源(如js、css、圖片等) --> 瀏覽器對頁面進行渲染呈現給用戶。

8九、講一下長鏈接【困難】

1、基於http協議的長鏈接

在HTTP1.0和HTTP1.1協議中都有對長鏈接的支持。其中HTTP1.0須要在request中增長」Connection: keep-alive「 header纔可以支持,而HTTP1.1默認支持.

http1.0請求與服務端的交互過程:

  1. 客戶端發出帶有包含一個header:」Connection: keep-alive「的請求

  2. 服務端接收到這個請求後,根據http1.0和」Connection: keep-alive「判斷出這是一個長鏈接,就會在response的header中也增長」Connection: keep-alive「,同是不會關閉已創建的tcp鏈接.

  3. 客戶端收到服務端的response後,發現其中包含」Connection: keep-alive「,就認爲是一個長鏈接,不關閉這個鏈接。並用該鏈接再發送request.轉到a)。

2、發心跳包。每隔幾秒就發一個數據包過去

90、TCP如何保證可靠傳輸?【困難】

  1. 三次握手。

  2. 將數據截斷爲合理的長度。應用數據被分割成 TCP 認爲最適合發送的數據塊(按字節編號,合理分片)

  3. 超時重發。當 TCP 發出一個段後,它啓動一個定時器,若是不能及時收到一個確認就重發

  4. 對於收到的請求,給出確認響應

  5. 校驗出包有錯,丟棄報文段,不給出響應

  6. 對失序數據進行從新排序,而後才交給應用層

  7. 對於重複數據 , 可以丟棄重複數據

  8. 流量控制。TCP 鏈接的每一方都有固定大小的緩衝空間。TCP 的接收端只容許另外一端發送接收端緩衝區所能接納的數據。這將防止較快主機導致較慢主機的緩衝區溢出。

  9. 擁塞控制。當網絡擁塞時,減小數據的發送。

9一、URI和URL的區別【中等】

URI,是uniform resource identifier,統一資源標識符,用來惟一的標識一個資源。Web上可用的每種資源如HTML文檔、圖像、視頻片斷、程序等都是一個來URI來定位的

URI通常由三部組成:

  1. 訪問資源的命名機制

  2. 存放資源的主機名

  3. 資源自身的名稱,由路徑表示,着重強調於資源。

URL是uniform resource locator,統一資源定位器,它是一種具體的URI,即URL能夠用來標識一個資源,並且還指明瞭如何locate這個資源。URL是Internet上用來描述信息資源的字符串,主要用在各類WWW客戶程序和服務器程序上,特別是著名的Mosaic。採用URL能夠用一種統一的格式來描述各類信息資源,包括文件、服務器的地址和目錄等。

URL通常由三部組成:

  1. 協議(或稱爲服務方式)

  2. 存有該資源的主機IP地址(有時也包括端口號)

  3. 主機資源的具體地址。如目錄和文件名等

9二、http和https的區別?【中等】

  1. https協議須要到CA申請證書,通常免費證書不多,須要交費。

  2. http是超文本傳輸協議,信息是明文傳輸;https 則是具備安全性的ssl加密傳輸協 議。

  3. http和https使用的是徹底不一樣的鏈接方式,用的端口也不同,前者是80,後者是443。

  4. http的鏈接很簡單,是無狀態的;HTTPS協議是由SSL+HTTP協議構建的可進行加密傳輸、身份認證的網絡協議,比http協議安全。

  5. http默認使用80端口,https默認使用443端口

9三、docker經常使用命令【中等】

1.docker images // 查看鏡像
2.docker run 鏡像名稱   // 生成一個正在運行的容器實例
3.docker stop 容器名稱   // 中止容器
4.docker rm 容器名稱  // 刪除容器
5.docker start 容器名稱  // 啓動容器
6.docker restart 容器名稱  //重啓容器
7.docker rmi 鏡像名稱  // 刪除鏡像
8.docker exec -it 容器名稱 /bin/bash  // 進入容器
9.docker ps  // 顯示正在運行的全部容器
10.docker ps -a  // 顯示全部容器(包括已經中止的)
11.docker pull 鏡像名稱:版本號  // 拉取鏡像

9四、什麼是Docker鏡像?【中等】

Docker鏡像是Docker容器的源代碼。換句話說,Docker鏡像用於建立容器。使用build命令建立映像,而且在使用run啓動時它們將生成容器。鏡像存儲在Docker註冊表http://registry.hub.docker.com中,由於它們可能變得很是大,鏡像被設計爲由其餘鏡像層組成,容許在經過網絡傳輸鏡像時發送最少許的數據。

9五、什麼是Docker容器?【中等】

Docker容器包括應用程序及其全部依賴項,但與其餘容器共享內核,做爲主機操做系統上用戶空間中的獨立進程運行。Docker容器不依賴於任何特定的基礎架構:它們能夠在任何計算機,任何基礎架構和任何雲中運行。

9六、什麼是Docker Hub?【中等】

Docker hub是一個基於雲的註冊表服務,容許您連接到代碼存儲庫,構建鏡像並測試它們,存儲手動推送的鏡像以及指向Docker雲的連接,以便您能夠將鏡像部署到主機。它爲整個開發流程中的容器鏡像發現,分發和變動管理,用戶和團隊協做以及工做流自動化提供了集中資源。

9七、什麼是 Git 復刻(fork)?復刻(fork)、分支(branch)和克隆(clone)之間有什麼區別?【中等】

  • 復刻(fork)

是對存儲倉庫(repository)進行的遠程的、服務器端的拷貝,從源頭上就有所區別。復刻實際上不是 Git 的範疇。它更像是個政治/社會概念。

  • 克隆(clone)

不是復刻,克隆是個對某個遠程倉庫的本地拷貝。克隆時,其實是拷貝整個源存儲倉庫,包括全部歷史記錄和分支。

  • 分支(branch)

是一種機制,用於處理單一存儲倉庫中的變動,並最終目的是用於與其餘部分代碼合併。

9八、「git pull」和「git fetch」之間有什麼區別?【中等】

簡單來講,git pull 是 git fetch + git merge。 當你使用 pull,Git 會試着自動爲你完成工做。它是上下文(工做環境)敏感的,因此 Git 會把全部拉取的提交合併到你當前處理的分支中。

pull 則是 自動合併提交而沒有讓你複查的過程。若是你沒有細心管理你的分支,你可能會頻繁遇到衝突。

當你 fetch,Git 會收集目標分支中的全部不存在的提交,並將這些提交存儲到本地倉庫中。但Git 不會把這些提交合併到當前分支中。這種處理邏輯在當你須要保持倉庫更新,在更新文件時又但願處理可能中斷的事情時,這將很是實用。而將提交合併到主分支中,則該使用 merge。

9九、使用Ajax的優缺點分別是什麼?【中等】

優勢

  • 交互性更好。來自服務器的新內容能夠動態更改,無需從新加載整個頁面。
  • 減小與服務器的鏈接,由於腳本和樣式只須要被請求一次。
  • 狀態能夠維護在一個頁面上。JavaScript 變量和 DOM 狀態將獲得保持,由於主容器頁面未被從新加載。
  • 基本上包括大部分 SPA 的優勢。

缺點

  • 動態網頁很難收藏。
  • 若是 JavaScript 已在瀏覽器中被禁用,則不起做用。
  • 有些網絡爬蟲不執行 JavaScript,也不會看到 JavaScript 加載的內容。
  • 基本上包括大部分 SPA 的缺點。

100、跨域問題,誰限制的跨域,怎麼解決【困難】

  1. 瀏覽器的同源策略致使了跨域
  2. 用於隔離潛在惡意文件的重要安全機制
  3. jsonp ,容許 script 加載第三方資源
  4. nginx 反向代理(nginx 服務內部配置 Access-Control-Allow-Origin *)
  5. cors 先後端協做設置請求頭部,Access-Control-Allow-Origin 等頭部信息
  6. iframe 嵌套通信,postmessage
相關文章
相關標籤/搜索