【JAVA】【面試】【 基礎篇】- 基本功

再快不能快基礎,再爛不能爛語言! java

【基礎篇】- 基本功

  • 什麼是面向對象

    現實世界存在的任務事物均可以稱之爲對象,面向對象是對現實世界建模的一種方式,將一種抽象的思想給具體實例化,對象中包含的內容特徵是它的屬性,對象的一些操做行爲是它的方法。例如簡歷就是一個對象,裏面的內容是它的屬性,看、拿、放均可以稱爲這個對象的方法。mysql

  • 面向對象的特徵

    封裝:把描述一個對象的屬性和行爲封裝成一個類,把具體的業務邏輯功能實現封裝成一個方法,其次封裝的意義還有效的保護屬性經過訪問修飾符私有化屬性(成員變量),公有化方法。面試

    繼承:實現代碼的複用,全部的子類所共有的行爲和屬性抽取爲一個父類,全部的子類繼承該類可具有父類的屬性和行爲,繼承具備單一性和傳遞性。sql

    多態:程序中定義的引用類型變量所指向的具體類型和調用的具體方法在程序編譯階段沒法肯定,而是在運行期才能肯定該引用類型變量指向具體哪一個對象而調用在哪一個類中聲明的方法。數據庫

    多態的表現形式有強制類型轉換,向上造型等,多態可分爲行爲多態和對象多態。編程

    • 行爲多態:同一個run( ){ }方法,不一樣的對象調用時會有不一樣的實現,貓調用時是跑,魚調用時是遊,鳥調用時是飛。數組

    • 對象多態:同一個對象,能夠被造型爲不一樣的類型,好比同一我的對象,能夠被造型爲兒子,父親,員工等。瀏覽器

  • 面向對象的七大設計原則

    1. 開閉原則(Open-Closed Principle, OCP)安全

    軟件實體應對擴展開放,對修改關閉。在不修改現有代碼的基礎上去擴展新功能。bash

    2. 單一職責原則(Single Responsibility Principle)

    定義一個類,應該只有一個職責。若是一個類有一個以上的職責,多個職責耦合在一塊兒,會致使設計的侷限性以及代碼的複用性。

    3. 里氏替換原則(Liskov Substitution Principle)

    子類型必須可以替換掉它們的父類型。子類能夠擴展父類的功能,但不能改變父類原有的功能。當子類的方法重載父類的方法時,方法的前置條件(即方法的形參)要比父類方法的輸入參數更寬鬆。當子類的方法實現父類的抽象方法時,方法的後置條件(即方法的返回值)要比父類更嚴格。

    4. 迪米特法則(Law Of Demeter)

    迪米特法則又稱爲最少知道原則,即一個對象應該對其餘對象保持最少的瞭解,只與直接的朋友通訊。若是兩個類沒必要彼此直接通訊,那麼這兩個類就不該當發生直接的相互做用。儘可能減小類與類之間的耦合。軟件編程的總原則:低耦合高內聚。迪米特法則的初衷就是下降類之間的耦合,因爲每一個類都減小了沒必要要的依賴,所以的確能夠下降耦合關係。

    5. 依賴倒置原則(Dependence Inversion Principle)

    高層模塊不該該依賴低層模塊,兩者都應該依賴其抽象;抽象不該該依賴細節;細節應該依賴抽象。依賴倒置原則就是要咱們面向接口編程,理解了面向接口編程,也就理解了依賴倒置。

    6. 接口隔離原則(Interface Segregation Principle)

    客戶端不該該依賴它不須要的接口;一個類對一個類的依賴應該創建在最小的接口上。

    7. 合成/聚合原則(Composite/Aggregate Reuse Principle,CARP)

    儘可能使用合成/聚合,儘可能不要使用繼承。原則:一個類中有另外一個的對象。

  • 低耦合高內聚的理解

內聚:每一個模塊儘量獨立完成本身功能,不依賴與模塊外部的代碼。

耦合:模塊與模塊之間接口的複雜程度,模塊之間聯繫越複雜耦合度越高,牽一髮而動全身。

低耦合是指減小對其餘類的依賴,高內聚是指調用的方法儘可能寫在本類中,對一個項目來講,就是減小第三方依賴。
複製代碼
  • final、finally、finalize的區別

    final:能夠用來修飾類、方法和變量(成員變量或局部變量)

    • 修飾類:當修飾類的時候,表面該類不能被繼承,注意:final類中全部的成員方法都會隱式的定義爲final方法。
    • 修飾方法:把方法鎖定,防止繼承對其修改。final修飾過的方法不能被重寫。注意:若父類中final方法權限爲private,子類不能繼承,若子類從新定義相同方法名的函數,會認爲是子類中的一個新方法。
    • 修飾變量:final成員變量表示常量。只能被賦值一次,賦值後其值再也不改變。當final修飾一個基本數據類型時,表示該基本數據類型的值一旦初始化後便不能發生變化;若是final修飾一個引用類型時,則在對其初始化以後便不能再讓其指向其餘對象了,但該引用所指向的對象的內容是能夠發生變化的。final修飾成員變量,必需要初始化。

    finally:finally做爲異常處理的一部分,它只能用在try/catch語句中,而且附帶一個語句塊,表示這段語句最終必定會被執行。

    如下這幾種狀況是不會被執行的:

    • 調用了System.exit()方法
    • JVM崩潰了(異常狀況致使)

    finalize:finalize()是在java.lang.Object理定義的,也就是每個對象都有這麼一個方法。這個對象在gc啓動時,該對象被回收的時候被調用。其實gc能夠回收大部分對象(凡是new出來的對象,gc都能搞定),因此通常不須要去實現finalize的。

  • int 和 Integer的區別

    1. Integer是int的包裝類,int是java的一種基本數據類型。
    2. Integer變量必須實例化後才能使用,int變量不須要。
    3. Integer實際是對象的引用,當new一個Integer時,其實是對一個指針指向此對象;而int則是直接存儲數據值。
    4. Integer的默認值是null,int默認值是0.
    public static void main(String[] args) {
        Integer i = 10;
        Integer j = 10;
        System.out.println(i == j);     //true
          
        Integer a = 128;
        Integer b = 128;
        System.out.println(a == b);     //false
         
        int k = 10;
        System.out.println(k == i);     //true
        int kk = 128;
        System.out.println(kk == a);    //true
          
        Integer m = new Integer(10);
        Integer n = new Integer(10);
        System.out.println(m == n);     //false
    }
    複製代碼
  • 重載和重寫的區別

    重載(Overloading):重載發生在本類,方法名相同,參數列表不一樣,與返回值無關,只和方法名、參數列表、參數的類型有關。

    • 方法名必須相同
    • 方法的參數列表必定不同
    • 訪問修飾符和返回類型能夠相同也能夠不一樣

    重寫(Overriding):重寫發生在父類和子類之間,通常表示父類和子類之間的關係。

    • 方法名必須相同,返回類型必須相同
    • 參數列表必須相同
    • 訪問權限不能比父類中被重寫的方法的訪問權限更低。例如:父類的一個方法聲明爲public,那麼子類重寫後就不能聲明爲protected。
  • 抽象類和接口的區別

    抽象類:抽象類用abstract來修飾,抽象類是用來捕捉子類的通用性,它不能被實例化,只能用做子類的超類,抽象類是被用來建立繼承層級裏子類的模版。

    接口:接口是抽象方法的集合,若是一個類實現了某個接口,那麼它就繼承了這個接口的抽象方法,就像契約模式,若是實現了這個接口,那麼久必須保證使用這些方法,而且實現這些方法,接口是一種形式,接口自身不能作任何事情,接口裏面的方法默認都是abstract的。

    使用場景:

    • 若是擁有一些方法,並想讓他們中的一些有默認的具體實現,請選擇抽象類。
    • 若是想實現多重繼承,那麼請使用接口,因爲java不支持多繼承,子類不能繼承多個類,但一個類能夠實現多個接口,所以可使用接口來解決。
    • 若是基本功能在不斷變化,那麼久使用抽象類,若是使用接口,那麼每次變動都須要相應的去改變實現該接口的全部類。
    參數 抽象類 接口
    默認的方法實現 能夠有默認的方法實現 徹底抽象,根本不存在方法實現
    實現方式 子類用extends關鍵字來繼承抽象類,若是子類不是抽象類的話,

    它須要實現父類抽象類中全部抽象方法,父類中非抽象方法可重寫也可不重寫

    子類用implements去實現接口,須要實現接口中全部方法
    構造器 抽象類能夠有構造器(構造器不能用abstract修飾) 接口不能有構造器
    與正常Java類區別 正常Java類可被實例化,抽象類不能被實例化 接口和正常java類是不一樣的類型
    訪問修飾符 抽象方法能夠用public、protected、default修飾 接口默認是public、不能用別的修飾符去修飾
    main方法 抽象類能夠有main方法,能夠運行 接口中不能有main方法
    多繼承 抽象類可繼承一個類和實現多個接口 接口能繼承一個或多個接口
  • 說說反射的用途及實現

    反射:反射的核心是JVM在運行時才動態加載或調用方法/訪問屬性,它不須要事先(寫代碼或者編譯期)知道運行對象是誰。注意:因爲反射會額外消耗必定的系統資源,所以若是不須要動態地建立一個對象,那麼久不須要反射。

    反射框架提供的功能:

    • 在運行時判斷任意一個對象所屬的類;
    • 在運行時構造任意一個類的對象;
    • 在運行時判斷任意一個類所具備的成員變量和方法(經過反射甚至能夠調用private方法);
    • 在運行時調用任意一個對象的方法

    反射的用途:反射最重要的用途就是開發各類通用框架。

    反射的基本實現:得到Class對象、判斷是否爲某個類的實例、建立實例、獲取方法、獲取構造器信息、獲取類的成員變量、調用方法、利用反射建立數組。

  • 說說自定義註解的場景及實現

    java中有四種元註解:

    @Retention:定義該註解的生命週期(何時使用該註解)

    RetentionPolicy.RUNTIME:始終不會丟棄,運行期也保留註解,所以可使用反射機制讀取該註解的信息。自定義註解時一般使用這種方式。

    @Inherited:定義該註釋和子類的關係(是否容許子類繼承該註解),若是一個使用了@Inherited修飾的annotation類型被用於一個class,則這個annotation將被用於該class的子類。

    @Documented:一個簡單的Annotations標記註解,表示是否將註解信息添加在java文檔中(註解是否將包含在JavaDoc中)

    @Target:表示該註解用在什麼地方(註解用於什麼地方)

    ElementType.TYPE用於描述類、接口(包括註解類型)或enum聲明。

    @Retention(RetentionPolicy.RUNTIME)
    @Inherited
    @Documented
    @Target({ElementType.FIELD,ElementType.METHOD})
    @interface MyAnno{
        public String name() default "zhangsan";
        public String email() default "hello@example.com";
    }
     
    //建立用戶類
    class  User{
     
        @MyAnno(name = "zhang")
        private String name;
     
        @MyAnno(name = "zhang@example.com")
        private String email;
     
     
        @MyAnno(name = "sayHelloWorld")
        public String sayHello(){
            return "";
        }
    複製代碼
  • HTTP請求的GET和POST方式的區別

    Get:通常用於獲取、查詢資源信息

    POST:通常用於更新資源信息

    Get請求 POST請求
    請求參數會顯示在地址欄中 請求參數不會顯示在地址欄中
    請求體是空 請求體是請求參數
    請求參數顯示在請求首行中(GET/name=aaa) 請求參數不顯示在請求首行中(POST/ )
    請求參數顯示地址欄中【不安全】 地址欄不顯示請求參數【相對安全】
    請求參數放首行,http對請求首行顯示1kb 請求參數放請求體,請求體沒有大小限制
    請求參數不能經過request.setCharacterEncoding("gbk")來設置編碼 request.setCharacterEncoding("gbk")只能設置請求體的編碼集
  • session和cookie區別

    1. session存儲在服務器端,cookie存儲在客戶端(瀏覽器)。
    2. cookie不是很安全,別人能夠分析存放在本地的cookie並進行cookie欺騙,考慮到安全應當使用session。
    3. session會在必定時間內保存在服務器上。當訪問增多,會比較佔用服務器的性能,考慮到減輕服務器性能方面,應當使用cookie。
    4. 單個cookie保存的數據不能超過4k,不少瀏覽器都限制一個站點最多保存20個cookie。
    5. 能夠考慮將登錄信息等重要信息存放爲session,其餘信息如需保留,能夠放在cookie中。
  • session分佈式處理

    1. 客戶端cookie加密。(通常用於內網中企業級的系統中,要求用戶瀏覽器端的cookie不能禁用,禁用的話,該方案會失效)。
    2. 集羣中,各個應用服務器提供了session複製的功能,Tomcat和Jboss都實現了這樣的功能。特定:性能隨着服務器增長急劇降低,容易引發廣播風暴;session數據須要序列化,影響性能。
    3. session的持久化,使用數據庫來保存session。就算宕機了也沒有事,數據庫的session照樣存在。特色:每次請求session都要讀寫數據庫,會帶來性能開銷。使用內存數據庫,會提升性能,可是宕機會丟失數據(像支付寶的宕機,有同城災備,異地災備)。
    4. 使用共享存儲來保存session。和數據庫相似,就算宕機了也沒事。其實就是專門搞一臺服務器,所有對session落地。特定:頻繁的進行序列化和反序列化會影響性能。
    5. 使用memcached來保存session。本質上是內存數據庫的解決方案。特色:存入memcached的數據須要序列化,效率極低。
  • JDBC流程

    1. 註冊驅動程序:Class.forName("com.mysql.jdbc.Driver");
    2. 使用驅動管理類來獲取數據鏈接對象:conn = DriverManager.getConnection(...);
    3. 獲取數據庫操做對象:Statement state = conn.createStatement();
    4. 定義操做的SQl語句
    5. 執行state.executeQuery(sql);
    6. 處理結果集:ResultSet,若是SQl前有參數值就設置參數值setXXX()
    7. 關閉對象,回收數據庫資源(關閉結果集->關閉數據庫操做對象->關閉鏈接)
public class JDBCTest {
    /**
     * 使用JDBC鏈接並操做mysql數據庫
     */
    public static void main(String[] args) {
        // 數據庫驅動類名的字符串
        String driver = "com.mysql.jdbc.Driver";
        // 數據庫鏈接串
        String url = "jdbc:mysql://127.0.0.1:3306/jdbctest";
        // 用戶名
        String username = "root";
        // 密碼
        String password = "1234";
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        try {
            // 一、加載數據庫驅動( 成功加載後,會將Driver類的實例註冊到DriverManager類中)
            Class.forName(driver);
            // 二、獲取數據庫鏈接
            conn = DriverManager.getConnection(url, username, password);
            // 三、獲取數據庫操做對象
            stmt = conn.createStatement();
            // 四、定義操做的SQL語句
            String sql = "select * from user where id = 100";
            // 五、執行數據庫操做
            rs = stmt.executeQuery(sql);
            // 六、獲取並操做結果集
            while (rs.next()) {
                System.out.println(rs.getInt("id"));
                System.out.println(rs.getString("name"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 七、關閉對象,回收數據庫資源
            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 {
                    if (!conn.isClosed()) {
                        conn.close();
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
複製代碼
  • MVC設計思想

MVC是Model-View-Controller的簡稱,它是一種架構模式,它分離了表現與交互。分爲三個核心部件:模型、視圖、控制器。

Model(模型),是程序的主體部分,主要包含業務數據和業務邏輯。在模型層,還會涉及到用戶發佈的服務,在服務中會根據不一樣的業務需求,更新業務模型中的數據。

View(視圖),是程序呈現給用戶的部分,是用戶和程序交互的接口,用戶會根據具體的業務需求,在View視圖層輸入本身特定的業務數據,並經過界面的事件交互
將對應的輸入參數提交給後臺控制器進行處理。

Controller(控制器),Controller是用來處理用戶輸入數據,以及更新業務模型的部分。控制器中接收了用戶與界面交互時傳遞過來的數據,並根據數據業務邏輯來
執行服務的調用和更新業務模型的數據和狀態。

MVC架構的控制流程
1.全部的終端用戶請求被髮送到控制器。
2.控制器依賴請求去選擇加載哪一個模塊,並把模型附加到對應的視圖。
3.附加了模型數據的最終視圖作爲相應發送給終端用戶。
複製代碼
  • equals與==的區別

    比較基本數據類型時,只能採用==,比較的是數值

    當比較引用數據類型時,==比較的是引用地址,而equals其實也是,equals是Object定義的方法,而其默認的顯示也是比較地址。咱們經常使用的String類型,由於重寫了equals方法,其內部比較的是內容。

更詳細的面試總結連接請戳:👇👇
juejin.im/post/5db8d9…

【推薦篇】- 書籍內容整理筆記 連接地址
【推薦】【Java編程思想】【筆記】 juejin.im/post/5dbb7a…
【推薦】【Java核心技術 卷Ⅰ】【筆記】 juejin.im/post/5dbb7b…

如有錯誤或者理解不當的地方,歡迎留言指正,但願咱們能夠一塊兒進步,一塊兒加油!😜😜

相關文章
相關標籤/搜索