摘要:可實現單例模式代碼塊初始化靜態變量,只被執行一次內部類不能與外部類重名,只能訪問外部類靜態數據包括私有多分支選擇整型或字符類型變量或整數表達式開始支持。
前言
大學期間接觸 Java 的時間也不短了,不論學習還是實習,都讓我發覺基礎的重要性。互聯網發展太快了,各種框架各種技術更新迭代的速度非常快,可能你剛好掌握了一門技術的應用,它卻已經走在淘汰的邊緣了。
而學習新技術總要付出一定的時間成本,那么怎么降低時間成本呢?那就是打好基礎,技術再怎么革新,底層的東西也很少會變動,牢固的基礎會幫助你在各種新技術的學習中游刃有余,快速上手。
因為我選擇的方向是后臺開發,所以談談我認為的基礎有哪些。其他方向肯定也有自己的體系,從低層到高層,可以自己摸索。后臺的話,我覺得網絡知識,各種協議,web 知識,數據庫知識,Linux 基本操作以及自己選擇的后臺語言知識,這些是最基礎最需要牢固掌握的。
所以從今天起,會出一系列與后臺基礎相關的博文,一是對自己過去學習的一個總結,二是分享出來,希望可以幫助到需要的人。
概要Java 基礎我做了 10 個方面的總結,包括基本概念,面向對象,關鍵字,基本類型與運算,字符串與數組,異常處理,Java 平臺與內存管理,分布式 Java 應用,多線程,IO。以下對這些內容做一些簡單的總結,同時我也有完整的思維導圖,博客上不方便展示,若有需要,聯系我。
細節 1. 基本概念純面向對象
平臺無關性
內置類庫
支持web
安全性
防止代碼攻擊
健壯性
強類型機制
垃圾回收器
異常處理
安全檢查機制
去除C++中難以理解易混淆的特性
解釋編譯混合型語言,執行速度慢,跨平臺
純面向對象,只有類,不存在全局變量或全局函數
無指針,無多繼承,可多實現
垃圾回收器自動管理內存
Java程序入口方法
可由final,synchronized修飾,不能用abstract
靜態優于非靜態
父類優于子類
按照成員變量的定義順序
總共10個
靜態變量屬于類
局部變量屬于花括號
成員變量看下一條
public、protected、default、private 可見性依次遞減
與類名相同,無返回值
可重載,不能被繼承,即不能被覆蓋
參數個數任意
伴隨new 一起調用,為系統調用
完成對象的初始化工作
子類可通過super顯式調用父類。父類沒有提供無參,子類必須顯式調用
未定義,默認無參,修飾符取決于類修飾符
無任何方法聲明
表示實現它的類屬于一個特定的類型
實現Cloneable接口
重寫Object類中的clone()
clone()中調用super.clone()
把淺復制引用指向新的克隆體
定義:允許程序在運行時進行自我檢查,也允許對其內部成員進行操作
功能
得到一個對象所屬的類
獲取一個類的所有成員和方法
運行時創建對象
在運行時調用對象的方法
獲取類的方式
class.forName("類路徑")
類名.class
實例.getClass()
new
反射機制
clone()
反序列化
提供多層命名空間,解決命名沖突
對類按功能進行分類,使項目組織更加清晰
2. 面向對象
層次邏輯關系不同。
面向對象是通過類的層次結構來體現類之間的繼承與發展
面向過程是通過模塊的層次結構概括模塊與模塊間的關系與功能
數據處理方式不同與控制程序方式不同
面向對象是數據與操作封裝成一個整體,通過事件驅動來激活和運行程序
面向過程是數據多帶帶存儲,控制程序方式上按照設計調用或返回程序
抽象
繼承
多態
封裝
開發效率高。代碼重用
保證軟件的魯棒性。經過長期測試的已有代碼
保證軟件的高可維護性。設計模式成熟
單繼承
只能繼承父類的非私有成員變量和方法
同名成員變量,子類覆蓋,不會繼承
相同函數簽名,子類覆蓋,不會繼承
組合:在新類中創建原有類的對象。has a
繼承是 is a
方法重載
編譯時多態
方法覆蓋
運行時多態
成員變量無多態概念
子父類關系,垂直;同類方法間關系,水平
一對方法發生關系;多個方法發生關系
參數列表相同;參數列表不同
調用的方法根據對象的類型決定;根據調用時的實參表決定方法體
同
不能被實例化
接口的實現類實現了接口,抽象類的子類實現了方法,才能被實例化
異
接口只能定義方法,不能實現;抽象類可以有定義和實現
接口需要被實現;抽象類需要被繼承
接口強調特定功能的實現;抽象類強調所屬關系
接口成員變量默認為 public static final,成員方法 public abstract
抽象類變量默認default,方法不能用 private、static、synchronized、native 修飾
靜態內部類
static 修飾
只能訪問外部類中的static數據
成員內部類
與實例綁定
不可定義靜態屬性和方法
外部實例化后,該內部類才能被實例化
局部內部類
代碼塊內
不能被public、protected、private以及static修飾
只能訪問final 局部變量
匿名內部類
無類名
無構造函數,必須繼承或實現其他類
原則
無構造函數
無靜態成員,方法和類
不能是public、protected、private、static
只能創建匿名內部類的一個實例
new 后面有繼承或實現
特殊的局部內部類
利用反射:obj.getClass().getSuperClass().getName()
不使用super.getClass()原因:該方法在 Object中為final與native,子類不能覆蓋,返回此Object運行時類
指向當前實例對象
區分成員變量與方法形參
訪問父類成員變量或方法
子類同名會覆蓋,訪問父類只能通過super
子類構造函數需顯示調用父類構造函數時,super()必須為構造函數的第一條語句
3. 關鍵字英文字母
數字
_和$
不能包含空白字符
首字符不能為數字
保留字不能做標識符
區分大小寫
軟件調試
運行時開啟 -ea
特定類的統一存儲空間,類綁定
成員變量:屬于類,內存中只有一個復制
成員方法:調靜態數據。可實現單例模式
代碼塊:初始化靜態變量,只被執行一次
內部類:不能與外部類重名,只能訪問外部類靜態數據(包括私有)
多分支選擇
整型或字符類型變量或整數表達式
Java 7 開始支持 String。原理是String的hashCode()返回的int類型值匹配
保證線程間的可見性
從內存中取數據,而不是緩存
不保證原子性
二元運算符
判斷一個引用類型的變量所指向的對象是否是一個類的實例
即左邊對象是否是右邊類的實例
精確浮點
確保浮點運算的準確性
若不指定,結果依賴于虛擬機平臺
指定后依賴于統一標準,保證各平臺的一致性
不是合法的Object實例
無內存
表明該引用目前沒有指向任何對象
4. 基本類型與運算
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 無法直接對其進行操作
實例創建后,值不可變
所有的基本類型的包裝類+String
優點
使用簡單
線程安全
節省內存
缺點:會因為值的不同而產生新的對象,導致無法預料的問題
隱式類型轉換
低精度到高精度
byte->short->char->int->long->float->double
顯式類型轉換
反之
可能會損失精度
類型自動轉換
低到高
char類型會轉換為其對應的ASCII碼
byte、char、short參與運算自動轉為int,但"+=",不轉
基本數據類型與boolean不能相互轉換
多種類型混合運算,自動轉成容量最大類型
運算符優先級
點 () [] +(正) -(負) ++ -- ~ ! * / %
+(加) -(減) << >> >>> < <= > >= instanceof == != & | ^ && || ?: = += -= *= /= %= &= |= ^= ~= <<= >>= >>>=5. 字符串與數組
堆
常量池
new String("abc")創建1個或2個對象
== 比較引用,內存
未覆蓋,同==;比較內容
hashCode鑒定對象是否相等,返回整數
String:不可變,執行效率最低
StringBuffer:可修改,線程安全,效率較高
StringBuilder:可修改,線程不安全,效率最高
數組初始化方式
length屬性和length()方法
6. 異常處理若try中有return,在return前
若try-finally或catch-finally中都有return,finally會覆蓋
程序進入try之前出現異常
try中調用System.exit(0)
嚴重錯誤,不可恢復
可恢復,編譯器可捕捉
檢查性異常
IO
SQL
運行時異常
JVM處理
NullPointException
ClassCastException
ArrayIndexOutOfBoundsException
出現異常后,一直往上層拋,直到遇到處理代碼或最上層
多態。若先捕獲基類,再捕獲子類。子類處理代碼將永遠不會得到執行
7. Java平臺與內存管理純軟件,包括JVM與JAVA API
JVM虛擬,不跨平臺
代碼編譯為class:sun jdk 中javac
裝載class:ClassLoader
執行class
解釋執行
編譯執行
client compiler
server compiler
詞法分析器組件:Token流
語法分析器組件:語法樹
語義分析器組件:注解語法樹
將語法樹中的名字、表達式等元素與變量、方法、類型等聯系到一起
檢查變量使用前是否已聲明
推導泛型方法的類型參數
檢查類型匹配性
進行常量折疊
檢查所有語句都可到達
檢查變量的確定性賦值
解除語法糖
將泛型JAVA轉成普通Java
檢查所有checked exception都被捕獲或拋出
將含語法糖的語法樹轉成簡單語法樹eg:foreach,自動折疊
代碼生成器組件:字節碼
裝載:全限定名+類加載器加載類
鏈接
校驗
格式不符,拋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
解釋執行
JVM字節碼為中間代碼,由JVM在運行期對其解釋并執行
invokestatic
invokevirtual
invokeinterface
invokespecial
基于棧
代碼緊湊,體積小
線程創建后,產生PC和Stack
指令解釋執行
棧頂緩存:棧頂值緩存在寄存器上
部分棧幀共享
編譯執行
client compiler
輕量級,占內存少
方法內聯
去虛擬化
冗余消除
server compiler
重量級,占內存多
逃逸分析是C2進行很多優化的基礎
標量替換:用標量替換聚合量
棧上分配
若對象未逃逸,C2會選擇在棧上直接創建Point對象實例,而不是在堆上
棧上分配更快速,對象易回收
同步消除:如果發現同步的對象未逃逸,那也沒有同步的必要。C2會去掉同步代碼塊
方法區:類信息,線程共享
堆
對象實例+數組
分代管理
新生代
舊生代
本地方法棧:支持native方法,Sun JDK的實現中本地方法棧和JVM方法棧是同一個
PC寄存器:線程私有
JVM方法棧:線程私有
Java對象,堆上分配,分配需加鎖,開銷大
當堆上空間不足-->GC-->仍不足-->拋OutOfMemory
Sun JDK 為新創建的線程在Eden上分配TLAB
多個小對象比大對象分配更高效
基于逃逸分析直接從棧上分配
收集器
引用計數收集器
計數器增減有消耗
不適合循環引用
跟蹤收集器
集中式管理
全局記錄數據的引用狀態
從根集合掃描對象,可能會造成應用程序暫停
三種實現算法
復制
適用于回收空間中存活對象較少
缺點:需要增加一塊空的內存空間及進行對象的移動
標記-清除:會產生內存碎片
標記-壓縮:不產生內存碎片
Sun JDK中可用GC
新生代
串行GC(Serial GC):復制算法
Minor GC
強軟弱虛
并行回收GC(Parrallel Scavenge):掃描復制多線程
并行 GC(ParNew):配合舊生代 CMS
舊生代和持久代可用GC
串行:標記壓縮+清除
并行:標記壓縮
并發:CMS
標記:暫停
并發標記:恢復,輪詢著色對象,以標記它們
重新標記:暫停
并發收集:恢復
CMS內存回收易產生碎片,但是它提供了整理碎片的功能
浮動垃圾:CMS回收時產生應該回收但要等到下次CMS才能被回收掉的對象
Full GC
對新生代舊生代及持久代都進行的GC
觸發的四種情況
舊生代空間不足
持久代空間滿
CMS GC出現promotion failed和concurrent mode failure
統計得到的Minor GC晉升到舊生代的平均大小大于舊生代的剩余空間
一個不再被程序使用的對象或變量還在內存中占有存儲空間
符合垃圾回收標準
對象賦空值null
給對象賦予新值,重新分配了內存空間
泄露的兩種情況
堆中申請的空間沒有被釋放
對象不再被使用,但仍然存活在內存中
泄露原因
靜態集合類
各種連接
監聽器
變量不合理的作用域
單例模式
8. 分布式Java應用
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方式阻塞當前線程
遠程調用方式
系統間通信和系統內一樣
讓使用者感覺調用遠程同調用本地一樣
基于Java自身技術
RMI:客戶端代理,stub,封裝對象,序列化為流,TCP/IP BIO,Skeleton,反序列化,獲取對象實例,調用
WebService
服務端的服務生成WSDL文件
將應用+WSDL文件放入HTTP服務器
借用Java輔助工具根據WSDL文件生成客戶端stub代碼
stub將產生的對象請求信息封裝為標準化的SOAP格式數據,并發請求到服務器端
服端在接收到SOAP格式數據時進行轉化,反射調用相應的Java類
SOAP優點支持跨語言,缺點對復雜對象結構難支持
Spring RMI
9. 多線程
JVM保證以下操作順序
同一線程操作
對于main Memory 上的同一個變量的操作
對于加了鎖的main Memory上的對象操作
為避免資源操作的臟數據問題,JVM提供了
synchronized
volatile
lock/unlock
目的是控制資源競爭
基于Object的wait/notify/notifyAll
為避免假喚醒,需要double check
調用對象的wait-->wait sets--->釋放鎖--->其他線程notify---->wait sets---->執行此對象線程--->刪除sets中此線程
基于JDK 5 并發包,支持線程交互
Semphore的acquire,release
Condition的await,signal
CountDownLatch的await和countDown
New
Runnable
Running
Wait
TimedWait
Blocked
Terminated
sleep
暫停一段時間執行
Thread的靜態方法
不釋放鎖
需要捕獲異常
wait
使線程暫停執行
Object方法,用于線程間通信
釋放鎖
后臺提供服務
用戶線程全部終止,只剩下守護線程時,JVM就會退出
調用start()之前,調用線程對象的setDaemon(true)
調用該方法的線程在執行完run()后,再執行join方法后面的代碼
線程合并,實現同步功能
10. IO數據傳輸
字節流:不使用緩存
字符流
碼表映射
使用緩存
運行時動態給對象增加額外的職責
是你還有你,一切拜托你
FilterInputStream
ServerSocket server = new ServerSocket(2000);
Socker socket = server.accept();
客戶端:Socket socket = new Socket("localhost",2000);
Channel--Selector--Buffer
反應器模式
對象持久化方式
解決在對對象流進行讀寫操作時引發的問題
對象寫進流里進行網絡傳輸,保存到文件,數據庫
實現Serializable接口
使用FileOutputStream來構造ObjectOutputStream對象
使用該對象的writeObject(obj)方法將對象寫出
要恢復時,使用對應的輸入流
一個類能被序列化,它的子類也能被序列化
static代表類成員,transient代表臨時數據。均不能被序列化
序列化影響性能,需要才使用
需要通過網絡來發送對象,或對象的狀態需要被持久化到數據庫或文件中
序列化能實現深復制,即可以復制引用的對象
將流轉化為對象
UID最好自己定義。優點
提高程序運行效率。省去計算過程
提高程序不同平臺兼容性。不同計算方式,反序列化失敗
增強程序各個版本的可兼容性。加入新屬性,默認UID變化
實現Externalizable接口控制
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/77195.html
摘要:今天總結下與網絡相關的知識,不是那么詳細,但是包含了我認為重要的所有點。概要網絡知識我做了個方面的總結,包括協議,協議,協議,協議,協議,,攻擊,其他協議。跨域名如今被普遍用在網絡中,例如等。擁塞窗口的大小又取決于網絡的擁塞狀況。 前言 無論是 C/S 開發還是 B/S 開發,無論是前端開發還是后臺開發,網絡總是無法避免的,數據如何傳輸,如何保證正確性和可靠性,如何提高傳輸效率,如何解...
摘要:作用域分類作用域共有兩種主要的工作模型。換句話說,作用域鏈是基于調用棧的,而不是代碼中的作用域嵌套。詞法作用域詞法作用域中,又可分為全局作用域,函數作用域和塊級作用域。 一篇鞏固基礎的文章,也可能是一系列的文章,梳理知識的遺漏點,同時也探究很多理所當然的事情背后的原理。 為什么探究基礎?因為你不去面試你就不知道基礎有多重要,或者是說當你的工作經歷沒有亮點的時候,基礎就是檢驗你好壞的一項...
閱讀 720·2023-04-25 20:32
閱讀 2266·2021-11-24 10:27
閱讀 4519·2021-09-29 09:47
閱讀 2241·2021-09-28 09:36
閱讀 3633·2021-09-22 15:27
閱讀 2756·2019-08-30 15:54
閱讀 370·2019-08-30 11:06
閱讀 1271·2019-08-30 10:58