夯實基礎系列一:Java 基礎總結

前言

大學期間接觸 Java 的時間也不短了,不論學習仍是實習,都讓我發覺基礎的重要性。互聯網發展太快了,各類框架各類技術更新迭代的速度很是快,可能你恰好掌握了一門技術的應用,它卻已經走在淘汰的邊緣了。java

而學習新技術總要付出必定的時間成本,那麼怎麼下降時間成本呢?那就是打好基礎,技術再怎麼革新,底層的東西也不多會變更,牢固的基礎會幫助你在各類新技術的學習中游刃有餘,快速上手。web

由於我選擇的方向是後臺開發,因此談談我認爲的基礎有哪些。其餘方向確定也有本身的體系,從低層到高層,能夠本身摸索。後臺的話,我以爲網絡知識,各類協議,web 知識,數據庫知識,Linux 基本操做以及本身選擇的後臺語言知識,這些是最基礎最須要牢固掌握的。算法

因此從今天起,會出一系列與後臺基礎相關的博文,一是對本身過去學習的一個總結,二是分享出來,但願能夠幫助到須要的人。數據庫

概要

Java 基礎我作了 10 個方面的總結,包括基本概念,面向對象,關鍵字,基本類型與運算,字符串與數組,異常處理,Java 平臺與內存管理,分佈式 Java 應用,多線程,IO。如下對這些內容作一些簡單的總結,同時我也有完整的思惟導圖,博客上不方便展現,如有須要,聯繫我設計模式

Java 基礎大綱

細節

1. 基本概念

1.1 語言特色
  • 純面向對象
  • 平臺無關性
  • 內置類庫
  • 支持web
  • 安全性數組

    • 防止代碼攻擊
  • 健壯性緩存

    • 強類型機制
    • 垃圾回收器
    • 異常處理
    • 安全檢查機制
  • 去除C++中難以理解易混淆的特性
1.2 與C++比較
  • 解釋編譯混合型語言,執行速度慢,跨平臺
  • 純面向對象,只有類,不存在全局變量或全局函數
  • 無指針,無多繼承,可多實現
  • 垃圾回收器自動管理內存
1.3 main函數知識
  • Java程序入口方法
  • 可由final,synchronized修飾,不能用abstract
1.4 Java程序初始化順序
  • 靜態優於非靜態
  • 父類優於子類
  • 按照成員變量的定義順序
  • 總共10個
1.5 做用域與可見性
  • 靜態變量屬於類
  • 局部變量屬於花括號
  • 成員變量看下一條
  • public、protected、default、private 可見性依次遞減
1.6 構造函數
  • 與類名相同,無返回值
  • 可重載,不能被繼承,即不能被覆蓋
  • 參數個數任意
  • 伴隨new 一塊兒調用,爲系統調用
  • 完成對象的初始化工做
  • 子類可經過super顯式調用父類。父類沒有提供無參,子類必須顯式調用
  • 未定義,默認無參,修飾符取決於類修飾符
1.7 標識接口
  • 無任何方法聲明
  • 表示實現它的類屬於一個特定的類型
1.8 clone 方法
  • 實現Cloneable接口
  • 重寫Object類中的clone()
  • clone()中調用super.clone()
  • 把淺複製引用指向新的克隆體
1.9 反射
  • 定義:容許程序在運行時進行自我檢查,也容許對其內部成員進行操做
  • 功能安全

    • 獲得一個對象所屬的類
    • 獲取一個類的全部成員和方法
    • 運行時建立對象
    • 在運行時調用對象的方法
  • 獲取類的方式服務器

    • class.forName("類路徑")
    • 類名.class
    • 實例.getClass()
1.10 建立對象的四種方式
  • new
  • 反射機制
  • clone()
  • 反序列化
1.11 package 做用
  • 提供多層命名空間,解決命名衝突
  • 對類按功能進行分類,使項目組織更加清晰

2. 面向對象

2.1 與面向過程區別
  • 層次邏輯關係不一樣。網絡

    • 面向對象是經過類的層次結構來體現類之間的繼承與發展
    • 面向過程是經過模塊的層次結構歸納模塊與模塊間的關係與功能
  • 數據處理方式不一樣與控制程序方式不一樣

    • 面向對象是數據與操做封裝成一個總體,經過事件驅動來激活和運行程序
    • 面向過程是數據單獨存儲,控制程序方式上按照設計調用或返回程序
2.2 特性
  • 抽象
  • 繼承
  • 多態
  • 封裝
2.3 這種開發方式優勢
  • 開發效率高。代碼重用
  • 保證軟件的魯棒性。通過長期測試的已有代碼
  • 保證軟件的高可維護性。設計模式成熟
2.4 繼承
  • 單繼承
  • 只能繼承父類的非私有成員變量和方法
  • 同名成員變量,子類覆蓋,不會繼承
  • 相同函數簽名,子類覆蓋,不會繼承
2.5 組合和繼承區別
  • 組合:在新類中建立原有類的對象。has a
  • 繼承是 is a
2.6 多態
  • 方法重載

    • 編譯時多態
  • 方法覆蓋

    • 運行時多態
  • 成員變量無多態概念
2.7 覆蓋和重載區別
  • 子父類關係,垂直;同類方法間關係,水平
  • 一對方法發生關係;多個方法發生關係
  • 參數列表相同;參數列表不一樣
  • 調用的方法根據對象的類型決定;根據調用時的實參表決定方法體
2.8 抽象類與接口異同

  • 不能被實例化
  • 接口的實現類實現了接口,抽象類的子類實現了方法,才能被實例化

  • 接口只能定義方法,不能實現;抽象類能夠有定義和實現
  • 接口須要被實現;抽象類須要被繼承
  • 接口強調特定功能的實現;抽象類強調所屬關係
  • 接口成員變量默認爲 public static final,成員方法 public abstract
  • 抽象類變量默認default,方法不能用 private、static、synchronized、native 修飾
2.9 內部類
  • 靜態內部類

    • static 修飾
    • 只能訪問外部類中的static數據
  • 成員內部類

    • 與實例綁定
    • 不可定義靜態屬性和方法
    • 外部實例化後,該內部類才能被實例化
  • 局部內部類

    • 代碼塊內
    • 不能被public、protected、private以及static修飾
    • 只能訪問final 局部變量
  • 匿名內部類

    • 無類名
    • 無構造函數,必須繼承或實現其餘類
    • 原則

      • 無構造函數
      • 無靜態成員,方法和類
      • 不能是public、protected、private、static
      • 只能建立匿名內部類的一個實例
      • new 後面有繼承或實現
      • 特殊的局部內部類
2.10 如何獲取父類類名
  • 利用反射:obj.getClass().getSuperClass().getName()
  • 不使用super.getClass()緣由:該方法在 Object中爲final與native,子類不能覆蓋,返回此Object運行時類
2.11 this
  • 指向當前實例對象
  • 區分紅員變量與方法形參
2.12 super
  • 訪問父類成員變量或方法
  • 子類同名會覆蓋,訪問父類只能經過super
  • 子類構造函數需顯示調用父類構造函數時,super()必須爲構造函數的第一條語句

3. 關鍵字

3.1 變量命名
  • 英文字母
  • 數字
  • _和$
  • 不能包含空白字符
  • 首字符不能爲數字
  • 保留字不能作標識符
  • 區分大小寫
3.2 assert
  • 軟件調試
  • 運行時開啓 -ea
3.3 static
  • 特定類的統一存儲空間,類綁定
  • 成員變量:屬於類,內存中只有一個複製
  • 成員方法:調靜態數據。可實現單例模式
  • 代碼塊:初始化靜態變量,只被執行一次
  • 內部類:不能與外部類重名,只能訪問外部類靜態數據(包括私有)
3.4 switch
  • 多分支選擇
  • 整型或字符類型變量或整數表達式
  • Java 7 開始支持 String。原理是String的hashCode()返回的int類型值匹配
3.5 volatile
  • 保證線程間的可見性
  • 從內存中取數據,而不是緩存
  • 不保證原子性
3.6 instanceof
  • 二元運算符
  • 判斷一個引用類型的變量所指向的對象是不是一個類的實例
  • 即左邊對象是不是右邊類的實例
3.7 strictfp
  • 精確浮點
  • 確保浮點運算的準確性
  • 若不指定,結果依賴於虛擬機平臺
  • 指定後依賴於統一標準,保證各平臺的一致性
3.8 null
  • 不是合法的Object實例
  • 無內存
  • 代表該引用目前沒有指向任何對象

4. 基本類型與運算

4.1 基本數據類型
  • int長度

    • byte(8 bit)
    • short(16 bit)
    • int(32 bit)
    • long(64 bit)
  • float長度

    • 單精度(32 bit float)
    • 雙精度(64 bit double)
  • boolean 類型變量的取值

    • true
    • false
  • char數據類型:Unicode字符(16 bit)
  • void:java.lang.Void 沒法直接對其進行操做
4.2 不可變類
  • 實例建立後,值不可變
  • 全部的基本類型的包裝類+String
  • 優勢

    • 使用簡單
    • 線程安全
    • 節省內存
  • 缺點:會由於值的不一樣而產生新的對象,致使沒法預料的問題
4.3 類型轉換
  • 隱式類型轉換

    • 低精度到高精度
    • byte->short->char->int->long->float->double
  • 顯式類型轉換

    • 反之
    • 可能會損失精度
  • 類型自動轉換

    • 低到高
    • char類型會轉換爲其對應的ASCII碼
    • byte、char、short參與運算自動轉爲int,但"+=",不轉
    • 基本數據類型與boolean不能相互轉換
    • 多種類型混合運算,自動轉成容量最大類型
  • 運算符優先級

    點    ()    []
    +(正)    -(負)        ++    --    ~    !
    *    /    %
+(加)    -(減)
    <<    >>    >>>
    <    <=    >    >=    instanceof
    ==    !=
    &
    |
    ^
    &&
    ||
    ?:
    =    +=    -=    *=    /=    %=    &=       |=    ^=    ~=    <<=    >>=    >>>=

5. 字符串與數組

5.1 字符串建立與存儲機制
  • 常量池
  • new String("abc")建立1個或2個對象
5.2 ==、equals和hashCode區別
  • == 比較引用,內存
  • 未覆蓋,同==;比較內容
  • hashCode鑑定對象是否相等,返回整數
5.3 String,StringBuffer,StringBuilder
  • String:不可變,執行效率最低
  • StringBuffer:可修改,線程安全,效率較高
  • StringBuilder:可修改,線程不安全,效率最高
5.4 其餘
  • 數組初始化方式
  • length屬性和length()方法

6. 異常處理

6.1 finally塊執行時機
  • 若try中有return,在return前
  • 若try-finally或catch-finally中都有return,finally會覆蓋
6.2 finally代碼塊不是必定會被執行
  • 程序進入try以前出現異常
  • try中調用System.exit(0)
6.3 Error

嚴重錯誤,不可恢復

6.4 Exception
  • 可恢復,編譯器可捕捉
  • 檢查性異常

    • IO
    • SQL
  • 運行時異常

    • JVM處理
    • NullPointException
    • ClassCastException
    • ArrayIndexOutOfBoundsException
  • 出現異常後,一直往上層拋,直到遇處處理代碼或最上層
  • 多態。若先捕獲基類,再捕獲子類。子類處理代碼將永遠不會獲得執行

7. Java平臺與內存管理

7.1 Java平臺與其餘語言平臺的區別
  • 純軟件,包括JVM與JAVA API
  • JVM虛擬,不跨平臺
7.2 JAVA代碼的執行
  • 代碼編譯爲class:sun jdk 中javac
  • 裝載class:ClassLoader
  • 執行class

    • 解釋執行
    • 編譯執行

      • client compiler
      • server compiler
7.3 java源碼編譯機制
  • 詞法分析器組件:Token流
  • 語法分析器組件:語法樹
  • 語義分析器組件:註解語法樹

    • 將語法樹中的名字、表達式等元素與變量、方法、類型等聯繫到一塊兒
    • 檢查變量使用前是否已聲明
    • 推導泛型方法的類型參數
    • 檢查類型匹配性
    • 進行常量摺疊
    • 檢查全部語句均可到達
    • 檢查變量的肯定性賦值
    • 解除語法糖
    • 將泛型JAVA轉成普通Java
    • 檢查全部checked exception都被捕獲或拋出
    • 將含語法糖的語法樹轉成簡單語法樹eg:foreach,自動摺疊
  • 代碼生成器組件:字節碼
7.4 類加載機制
  • 裝載:全限定名+類加載器加載類
  • 連接

    • 校驗

      • 格式不符,拋VerifyError
      • 加載引用的類失敗:拋NoClassDefFoundError
    • 準備:靜態變量默認初始化
    • 解析:屬性、方法驗證(可選)
  • 初始化(不是類加載必須觸發的)

    • 靜態初始化代碼
    • 構造器代碼
    • 靜態屬性初始化
    • 觸發時機

      • 調用了new
      • 反射調用了類中的方法
      • 子類調用了初始化
      • JVM啓動過程當中指定的初始化類

        • Bootstrap Class Loader:$JAVA_HOME/jre/lib/rt.jar
        • Extension Class Loader:$JAVA_HOME/jre/lib/ext/*.jar
        • System Class Loader:$CLASSPATH
        • User Defined Class Loader
7.5 類執行機制
  • 解釋執行

    • JVM字節碼爲中間代碼,由JVM在運行期對其解釋並執行

      • invokestatic
      • invokevirtual
      • invokeinterface
      • invokespecial
    • 基於棧

      • 代碼緊湊,體積小
      • 線程建立後,產生PC和Stack
      • 指令解釋執行
      • 棧頂緩存:棧頂值緩存在寄存器上
      • 部分棧幀共享
  • 編譯執行

    • client compiler

      • 輕量級,佔內存少
      • 方法內聯
      • 去虛擬化
      • 冗餘消除
    • server compiler

      • 重量級,佔內存多
      • 逃逸分析是C2進行不少優化的基礎
      • 標量替換:用標量替換聚合量
      • 棧上分配

        • 若對象未逃逸,C2會選擇在棧上直接建立Point對象實例,而不是在堆上
        • 棧上分配更快速,對象易回收
      • 同步消除:若是發現同步的對象未逃逸,那也沒有同步的必要。C2會去掉同步代碼塊
7.6 內存空間
  • 方法區:類信息,線程共享
    • 對象實例+數組
    • 分代管理

      • 新生代
      • 舊生代
  • 本地方法棧:支持native方法,Sun JDK的實現中本地方法棧和JVM方法棧是同一個
  • PC寄存器:線程私有
  • JVM方法棧:線程私有
7.7 內存分配
  • Java對象,堆上分配,分配需加鎖,開銷大
  • 當堆上空間不足-->GC-->仍不足-->拋OutOfMemory
  • Sun JDK 爲新建立的線程在Eden上分配TLAB
  • 多個小對象比大對象分配更高效
  • 基於逃逸分析直接從棧上分配
7.8 內存回收
  • 收集器

    • 引用計數收集器

      • 計數器增減有消耗
      • 不適合循環引用
    • 跟蹤收集器

      • 集中式管理
      • 全局記錄數據的引用狀態
      • 從根集合掃描對象,可能會形成應用程序暫停
      • 三種實現算法

        • 複製

          • 適用於回收空間中存活對象較少
          • 缺點:須要增長一塊空的內存空間及進行對象的移動
        • 標記-清除:會產生內存碎片
        • 標記-壓縮:不產生內存碎片
  • Sun JDK中可用GC

    • 新生代

      • 串行GC(Serial GC):複製算法

        • Minor GC
        • 強軟弱虛
      • 並行回收GC(Parrallel Scavenge):掃描複製多線程
      • 並行 GC(ParNew):配合舊生代 CMS
    • 舊生代和持久代可用GC

      • 串行:標記壓縮+清除
      • 並行:標記壓縮
      • 併發:CMS

          1. 標記:暫停
          1. 併發標記:恢復,輪詢着色對象,以標記它們
          1. 從新標記:暫停
          1. 併發收集:恢復
        • CMS內存回收易產生碎片,可是它提供了整理碎片的功能
        • 浮動垃圾:CMS回收時產生應該回收但要等到下次CMS才能被回收掉的對象
  • Full GC

    • 對新生代舊生代及持久代都進行的GC
    • 觸發的四種狀況

      • 舊生代空間不足
      • 持久代空間滿
      • CMS GC出現promotion failed和concurrent mode failure
      • 統計獲得的Minor GC晉升到舊生代的平均大小大於舊生代的剩餘空間
7.9 內存泄露
  • 一個再也不被程序使用的對象或變量還在內存中佔有存儲空間
  • 符合垃圾回收標準

    • 對象賦空值null
    • 給對象賦予新值,從新分配了內存空間
  • 泄露的兩種狀況

    • 堆中申請的空間沒有被釋放
    • 對象再也不被使用,但仍然存活在內存中
  • 泄露緣由

    • 靜態集合類
    • 各類鏈接
    • 監聽器
    • 變量不合理的做用域
    • 單例模式

8. 分佈式Java應用

8.1 基於消息方式實現系統間的通訊
  • TCP/IP+BIO

    • socket.setSoTimeOut()設置等待響應的超時時間
    • 一鏈接一線程
    • 缺點:不管鏈接是否真實,都要建立線程
    • BIO下服務器端所能支撐的鏈接數目有限
  • TCP/IP+NIO

    • Channel

      • SocketChannel:創建鏈接,監聽事件,操做讀寫
      • ServerSocketChannel:監聽端口,監聽鏈接事件
    • Selector:獲取是否要處理的事件
    • Buffer:存放處理的數據
    • NIO Reactor模式,經過註冊感興趣的事件及掃描是否有感興趣的事件發生,從而作出相應的動做
    • 多個請求,鏈接複用
    • 只有在有真實的請求時,纔會建立線程
    • 一請求一線程
  • UDP/IP+BIO

    • DatagramSocket:負責監聽端口,讀寫數據
    • DatagramPacket:做爲數據流對象進行傳輸
  • UDP/IP+NIO

    • DatagramChannel:監聽端口,進行讀寫
    • ByteBuffer:數據流傳輸
  • NIO好處:只在有流要讀取或可寫入流時才作出相應的IO操做,而不像BIO方式阻塞當前線程
8.2 基於遠程調用方式實現系統間的通訊
  • 遠程調用方式

    • 系統間通訊和系統內同樣
    • 讓使用者感受調用遠程同調用本地同樣
  • 基於Java自身技術

    • RMI:客戶端代理,stub,封裝對象,序列化爲流,TCP/IP BIO,Skeleton,反序列化,獲取對象實例,調用
    • WebService

        1. 服務端的服務生成WSDL文件
        1. 將應用+WSDL文件放入HTTP服務器
        1. 借用Java輔助工具根據WSDL文件生成客戶端stub代碼
        1. stub將產生的對象請求信息封裝爲標準化的SOAP格式數據,併發請求到服務器端
        1. 服端在接收到SOAP格式數據時進行轉化,反射調用相應的Java類
      • SOAP優勢支持跨語言,缺點對複雜對象結構難支持
8.3 基於開源框架
  • Spring RMI

9. 多線程

9.1 線程資源同步機制
  • JVM保證如下操做順序

    • 同一線程操做
    • 對於main Memory 上的同一個變量的操做
    • 對於加了鎖的main Memory上的對象操做
  • 爲避免資源操做的髒數據問題,JVM提供了

    • synchronized
    • volatile
    • lock/unlock
    • 目的是控制資源競爭
9.2 線程交互機制
  • 基於Object的wait/notify/notifyAll

    • 爲避免假喚醒,須要double check
    • 調用對象的wait-->wait sets--->釋放鎖--->其餘線程notify---->wait sets---->執行此對象線程--->刪除sets中此線程
  • 基於JDK 5 併發包,支持線程交互

    • Semphore的acquire,release
    • Condition的await,signal
    • CountDownLatch的await和countDown
9.3 線程狀態
  • New
  • Runnable
  • Running
  • Wait
  • TimedWait
  • Blocked
  • Terminated
9.4 sleep()與wait()方法的區別
  • sleep

    • 暫停一段時間執行
    • Thread的靜態方法
    • 不釋放鎖
    • 須要捕獲異常
  • wait

    • 使線程暫停執行
    • Object方法,用於線程間通訊
    • 釋放鎖
9.5 守護線程
  • 後臺提供服務
  • 用戶線程所有終止,只剩下守護線程時,JVM就會退出
  • 調用start()以前,調用線程對象的setDaemon(true)
9.6 join
  • 調用該方法的線程在執行完run()後,再執行join方法後面的代碼
  • 線程合併,實現同步功能

10. IO

10.1 流本質
  • 數據傳輸
10.2 流分類
  • 字節流:不使用緩存
  • 字符流

    • 碼錶映射
    • 使用緩存
10.3 裝飾者模式
  • 運行時動態給對象增長額外的職責
  • 是你還有你,一切拜託你
  • FilterInputStream
10.4 Java Socket
  • ServerSocket server = new ServerSocket(2000);
  • Socker socket = server.accept();
  • 客戶端:Socket socket = new Socket("localhost",2000);
10.5 NIO
  • Channel--Selector--Buffer
  • 反應器模式
10.6 序列化
  • 對象持久化方式
  • 解決在對對象流進行讀寫操做時引起的問題
  • 對象寫進流裏進行網絡傳輸,保存到文件,數據庫
10.7 如何實現序列化
  • 實現Serializable接口
  • 使用FileOutputStream來構造ObjectOutputStream對象
  • 使用該對象的writeObject(obj)方法將對象寫出
  • 要恢復時,使用對應的輸入流
10.8 序列化特色
  • 一個類能被序列化,它的子類也能被序列化
  • static表明類成員,transient表明臨時數據。均不能被序列化
  • 序列化影響性能,須要才使用
  • 須要經過網絡來發送對象,或對象的狀態須要被持久化到數據庫或文件中
  • 序列化能實現深複製,便可以複製引用的對象
10.9 反序列化
  • 將流轉化爲對象
  • UID最好本身定義。優勢

    • 提升程序運行效率。省去計算過程
    • 提升程序不一樣平臺兼容性。不一樣計算方式,反序列化失敗
    • 加強程序各個版本的可兼容性。加入新屬性,默認UID變化
10.10 外部序列化
  • 實現Externalizable接口控制
相關文章
相關標籤/搜索