你都是會點啥技術(四)--- Java

你都是會點啥技術(四)— Java

寫在前面的話:到2019年6月份爲止,真正使用java有兩年了,在大學期間老師教過一遍java(學的不好),看過兩三個老師講解的java視頻,每次學習都會有新的體驗和收穫,也讀過《java編程思想》和《深入理解Java虛擬機》,從我對我自己的審視來看,萬萬不敢說掌握了java這門語言,這次是把java從基礎到高級梳理一遍,一方面是對java知識回顧,一方面補充工作中遇到的問題,理論和實踐相結合吧, 我想這肯定對我的java功底有一個很大的提升。這次總結也算給自己的java基礎畫一個小小的句號。。。讓我踏着java去開拓更廣闊的領域去吧。重點:集合 IO 線程

一、入門基礎及環境搭建

做飯之前需要準備好廚房(生產環境)和廚具,對於java來說,JDK就是做飯的廚房(生產環境),廚具的話流行的有Eclipse,Idea,拿蒸米飯來說,使用高壓鍋比使用普通鐵鍋,不僅節省時間而且還不容易糊,還可以讓你做米飯事半功倍。
Java初學者必須面對的一步,就是Java JDK的安裝及環境變量配置了,這步還沒有熟練和掌握的可以參考
JDK下載安裝和環境變量作用的詳解
一個簡單的java程序的基本要素有:標識符、關鍵字、註釋、修飾符、語句、塊、類以及 main() 方法。
我們的java程序就是是靠着這些基本要素按照規範組合使用!
拓展點:
1.java程序的運行過程。
2.jdk,jre,jvm區別。
3.判斷標識符是否合法。
4.修飾符的作用。
實戰:
1.main方法傳值。

二、程序設計基礎

廚房(生產環境)和廚具準備好了,做一頓美味的菜。佐料是必不可少的,每種佐料都能發揮出它不同的特色味道。java中的佐料有:算術運算符、賦值運算符、邏輯運算符、關係運算符、自增和自減運算符、位運算符、條件運算符,而java中的數據類型相當於不同食物的原料,例如,小麥,水稻…。
這些佐料都用於變量上,變量是一個具有適當的數據類型的數值。
拓展點:
1、變量的作用域,final常量特點
2、數據類型
(1.)基本數據類型:

類型名稱 關鍵字 佔用內存(內存空間) 取值範圍 默認值
字節型 byte 1字節(8位) -128~127 0
短整型 short 2字節(16位) -32768~32767 0
整型 int 4字節(32位) -2147483648~2147483647 0
長整型 long 8字節(64位) -9223372036854775808L~9223372036854775807L 0L
單精度浮點型 float 4字節(32位) +/-3.4E+38F(6~7 個有效位) 0.0f
雙精度浮點型 double 8字節(64位) +/-1.8E+308 (15 個有效位) 0.0d
字符型 char 2字節(16位) ISO 單一字符集 ‘u0000’
布爾型 boolean 1字節(8位) true 或 false false

(2.)數值的隱式類型轉化和強制類型或轉換
在這裏插入圖片描述
(3.)數據類型結構
在這裏插入圖片描述
整數類型等號右邊默認是int類型,如果想要表示long類型,需要在值後面加L
浮點型等號右邊默認是double類型,如果想要表示float類型,需要在值後面加F
3、char字符型對應的ASCII十進制值
0-9:30-39
A-Z:65-90
a-z:97-122
4、邏輯運算符中的短路與和短路或的特點。
5、 成員變量和局部變量的定義以及生命週期?(面)
局部變量:

  1. 定義在方法中;
  2. 沒有默認值,必須自行設定初始值;
  3. 方法被調用時,存在棧中,方法調用結束時局部變量從棧中清除;
    成員變量:
  4. 定義在類中,方法外;
  5. 由系統設定默認初始值,可以不顯式初始化;
  6. 所在類被實例化後,存在堆中,對象被回收時,成員變量失效;
三、流程控制語句

當廚房(生產環境),廚具,佐料都準備好後,我們就開始生火做飯了。這個火候怎麼把握呢,java中有順序結構、選擇結構和循環結構三種結構來控制火候。
順序結構:系統則默認自上而下一行一行地執行
選擇結構:if和else的組合使用,switch case的使用
循環結構:while,do while,for,foreach(遍歷)
終止函數的執行或退出類的方法:return
強行退出循環:break
中止當前迭代的循環,進入下一次的迭代:continue
拓展點:
1.switch 語句中的變量類型可以是: byte、short、int 或者 char。從 Java SE 7 開始,switch 支持字符串 String 類型了,同時 case 標籤必須爲字符串常量或字面量。

三、字符串處理

當大廚把飯做好之後,接下來就開始美美的拼盤了,java中對字符串進行操作,就像對食物進行加工雕刻拼盤,最後一份色香味俱全的美味就出現了。
定義字符串:String類的特點
連接字符串:+,concat,append
獲取字符串長度:str.length()
轉換大小寫:str.toLowerCase()/str.toUpperCase()轉小寫/大寫非字母不受影響
去空格:str.trim()
截取字符串:substring() 按字符截取
分割字符串:str.split()返回字符串數組
替換字符串:replace(),replaceFirst()和replaceAll()匹配正則表達式進行替換
比較字符串:equals(),equalsIgnoreCase() 比較時不區分大小寫,compareTo() 方法用於按字典順序比較兩個字符串的大小,該比較是基於字符串各個字符的 Unicode 值。
查找字符串:indexOf() 方法和 lastlndexOf() 方法用於在字符串中獲取匹配字符(串)的索引值,charAt() 方法可以在字符串內根據指定的索引查找字符
利用正則表達式驗證字符串
在這裏插入圖片描述
擴展:
1、String,StringBuffer,StringBuilder的區別
2、String類的特點

四、數字和日期處理

數字和日期這兩種食物的拼盤開始啦!
數值運算:Math 類封裝了常用的數學運算,提供了基本的數學操作,如指數、對數、平方根和三角函數等,當我們需要進行數值運算的時候就可以直接利用了。
生成隨機數:Math中的random() 方法只能產生 double 類型的 0~1 的隨機數,Random 類提供了豐富的隨機數生成方法,可以產生 boolean、int、long、float, byte 數組以及 double 類型的隨機數。
數字格式化:DecimalFormat類對結果進行格式化處理
大數字運算: BigInteger 類是針對整型大數字的處理類,而 BigDecimal 類是針對大小數的處理類,他倆用於高精度計算。
時間日期的處理:Date 類主要封裝了系統的日期和時間的信息,並提供了一些日期操作的常用方法。
Calendar類是一個抽象類,它通過getInstance() 方法返回一個 Calendar 對象,
例子:
Calendar calendar = Calendar.getInstance();
calendar.get(Calendar.DAY_OF_YEAR);
Calendar.YEAR:年份。
Calendar.MONTH:月份。(月份從 0 開始,需要加 1)
Calendar.DATE:日期。
Calendar.DAY_OF_MONTH:日期,和上面的字段意義完全相同。
Calendar.HOUR:12小時制的小時。
Calendar.HOUR_OF_DAY:24 小時制的小時。
Calendar.MINUTE:分鐘。
Calendar.SECOND:秒。
Calendar.DAY_OF_WEEK:星期幾。獲取今天星期幾(以星期日爲第一天)
日期格式化:使用 DateFormat 類和 SimpleDateFormat 類來格式化日期
創建DateFormat對象需要用
DateFormat df=DateFormat.getDatelnstance();日期
DateFormat df=DateFormat.getTimeInstance();時間
SHORT:完全爲數字,如 12.5.10 或 5:30pm。
MEDIUM:較長,如 May 10,2016。
LONG:更長,如 May 12,2016 或 11:15:32am。
FULL:是完全指定,如 Tuesday、May 10、2012 AD 或 11:l5:42am CST。

日期和時間相關類

在這裏插入圖片描述

五、內置包裝類

我們把原料小麥加工成麪粉,原料水稻加工成大米,相當於對原料進行了一次加工包裝。java中也提供原料的包裝類,比如int對應Integer,short對應Short等。
Object類:

方法 說明
Object clone() 創建與該對象的類相同的新對象
boolean equals(Object) 比較兩對象是否相等
void finalize() 當垃圾回收器確定不存在對該對象的更多引用時,對象的圾回收器調用該方法
Class getClass() 返回一個對象運行時的實例類
int hashCode() 返回該對象的散列碼值
void notify() 激活等待在該對象的監視器上的一個線程
void notifyAll() 激活等待在該對象的監視器上的全部線程
String toString() 返回該對象的字符串表示
void wait() 在其他線程調用此對象的 notify() 方法或 notifyAll() 方法前,導致當前線程等待
數據類型轉換

在這裏插入圖片描述
Integer類:

方法 返回值 說明
byteValue() byte 以 byte 類型返回該 Integer 的值
shortValue() short 以 short 類型返回該 Integer 的值
intValue() int 以 int 類型返回該 Integer 的值
toString String 返回一個表示該 Integer值的 String 對象
equals(Object obj) boolean 比較此對象與指定對象是否相等
compareTo(IntegeranotherInteger) int 在數字上比較兩個 Integer 對象,如相等,則返回 0; 如調用對象的數值小於 anotherlnteger 的數值,則返回負值; 如調用對象的數值大於 anotherlnteger 的數值,則返回正值
valueOf(String s) Integer 返回保存指定的 String 值的 Integer 對象
parseInt(String s) toString() 將數字字符串轉換爲 int 數值

Float類:

方法 返回值 說明
byteValue() byte 以 byte 類型返回該 Float 的值
doubleValue() double 以 double 類型返回該 Float 的值
floatValue() float 以float類型返回該Float的值
intValue() int 以 int 類型返回該 Float 的值(強制轉換爲 int 類型)
longValue() long 以long類型返回該Float的值(強制轉換爲long類型)
shortValue() short 以 short 類型返回該 Float 的值(強制轉換爲short類型)
isNaN() noolean 如果此 Float 值是一個非數字值,則返回 true,否則返回 false
isNaN(float v) boolean 如果指定的參數是一個非數字值,則返回 true,否則返回 false
toString String 返回一個表示該 Float值的 String 對象
valueOf(String s) Float 返回保存指定的 String 值的 Float 對象
parseFloatString s) toString() 將數字字符串轉換爲 float 數值

Double類:

方法 返回值 說明
byteValue() byte 以 byte 類型返回該 Double 的值
doubleValue() double 以 double 類型返回該 Double 的值
floatValue() float 以float類型返回該Double的值
intValue() int 以 int 類型返回該 Double 的值(強制轉換爲 int 類型)
longValue() long 以long類型返回該Double的值(強制轉換爲long類型)
shortValue() short 以 short 類型返回該 Double 的值(強制轉換爲short類型)
isNaN() noolean 如果此 Double 值是一個非數字值,則返回 true,否則返回 false
isNaN(float v) boolean 如果指定的參數是一個非數字值,則返回 true,否則返回 false
toString String 返回一個表示該 Double值的 String 對象
valueOf(String s) Float 返回保存指定的 String 值的 Double 對象
parseFloatString s) toString() 將數字字符串轉換爲 double 數值

Number類: 是一個抽象類,也是一個超類(即父類)。Number 類屬於 java.lang 包,所有的包裝類(如 Double、Float、Byte、Short、Integer 以及 Long)都是抽象類 Number 的子類。
Character類:

方法 描述
void Character(char value) 構造一個新分配的 Character 對象,用以表示指定的 char 值
char charValue() 返回此 Character 對象的值,此對象表示基本 char 值
int compareTo(Character anotherCharacter) 根據數字比較兩個 Character 對象
boolean equals(Character anotherCharacter) 將此對象與指定對象比較,當且僅當參數不是 null,而 是一個與此對象 包含相同 char 值的 Character 對象時, 結果纔是 true
boolean isDigit(char ch) 確定指定字符是否爲數字,如果通過 Character. getType(ch) 提供的字 符的常規類別類型爲 DECIMAL_DIGIT_NUMBER,則字符爲數字
boolean isLetter(int codePoint) 確定指定字符(Unicode 代碼點)是否爲字母
boolean isLetterOrDigit(int codePoint) 確定指定字符(Unicode 代碼點)是否爲字母或數字
boolean isLowerCase(char ch) 確定指定字符是否爲小寫字母
boolean isUpperCase(char ch) 確定指定字符是否爲大寫字母
char toLowerCase(char ch) 使用來自 UnicodeData 文件的大小寫映射信息將字符參數轉換爲小寫
char toUpperCase(char ch) 使用來自 UnicodeData 文件的大小寫映射信息將字符參數轉換爲大寫

Boolan類:

方法 返回值 說明
booleanValue() boolean 將 Boolean 對象的值以對應的 boolean 值返回
equals(Object obj) boolean 判斷調用該方法的對象與 obj 是否相等。當且僅當參數不是 null,且與調用該方法的對象一樣都表示同一個 boolean 值的 Boolean 對象時,才返回 true
parseBoolean(String s) boolean 將字符串參數解析爲 boolean 值
toString String 返回表示該 boolean 值的 String 對象
valueOf(String s) Float 返回一個用指定的字符串表示的 boolean 值

Byte類:

方法 返回值 說明
byteValue() byte 以一個 byte 值返回 Byte 對象
compareTo(Byte byte) int 在數字上比較兩個 Byte 對象
doubleValue() double 以一個 double 值返回此 Byte 的值
intValue() int 以一個 int 值返回此 Byte 的值
parseByte(String s) byte 將 String 型參數解析成等價的 byte 形式
toString() String 返回表示此 byte 值的 String 對象
valueOf(String s) Byte 返回一個保持指定 String 所給出的值的 Byte 對象
equals(Object obj) boolean 將此對象與指定對象比較,如果調用該方法的對象與 obj 相等 則返回 true,否則返回 false

System 類:
系統級的很多屬性和控制方法都在該類內部,該類構造方法時private的,所以無法創建該類的對象,也就是無法實例化該類,System 類內部的成員變量和成員方法都是 static 的,所以可以方便地進行調用。
System類的3 個靜態成員變量,分別是 PrintStream out、InputStream in 和 PrintStream err。
(1、)PrintStream out:標準輸出流。
(2、)InputStream in:標準輸入流。
(3、)PrintStream err:標準的錯誤輸出流。
System類的成員方法
常用的方法有 arraycopy()、currentTimeMillis()、exit()、gc() 和 getProperty()。
(1、)arraycopy() :該方法的作用是數組複製,即從指定源數組中複製一個數組,複製從指定的位置開始,到目標數組的指定位置結束。
(2、)currentTimeMillis() :該方法的作用是返回當前的計算機時間。
(3、)exit() :該方法的作用是終止當前正在運行的 Java 虛擬機,status 的值爲 0 時表示正常退出,非零時表示異常退出。使用該方法可以在圖形界面編程中實現程序的退出功能等。
(4、)gc():該方法的作用是請求系統進行垃圾回收。至於系統是否立刻回收,取決於系統中垃圾回收算法的實現以及系統執行時的情況。
(5、)getProperty():

屬性名 描述
java.version Java運行時環境版本
java.home Java安裝目錄
os.name 操作系統的名稱
os.version 操作系統的版本
user.name 用戶的賬戶名稱
user.home 用戶的主目錄
user.dir 用戶的當前工作目錄
六、數組處理
七、類和對象

本章主要內容就是像做飯的過程,只能在實踐中慢慢體會啦!

[public][abstract|final]class<class_name>[extends<class_name>]
[implements<interface_name>]
{
    //定義屬性部分
    <property_type><property1>;
    <property_type><property2>;
    <property_type><property3>;//定義方法部分
    function1();
    function2();
    function3();}
上述語法中各關鍵字的描述如下。

public:表示“共有”的意思。如果使用 public 修飾,則可以被其他類和程序訪問。每個 Java 程序的主類都必須是 public 類,作爲公共工具供其他類和程序使用的類應定義爲 public 類。
abstract:如果類被 abstract 修飾,則該類爲抽象類,抽象類不能被實例化,但抽象類中可以有抽象方法(使用 abstract 修飾的方法)和具體方法(沒有使用 abstract 修飾的方法)。繼承該抽象類的所有子類都必須實現該抽象 類中的所有抽象方法(除非子類也是 抽象類)。
final:如果類被 final 修飾,則不允許被繼承。
class:聲明類的關鍵字。
class_name:類的名稱。
extends:表示繼承其他類。
implements:表示實現某些接口。
property_type:表示成員變量的類型。
property:表示成員變量名稱。
function():表示成員方法名稱。

八、繼承和多態

java三大特性:繼承,封裝,多態。

封裝的優點:
  1. 良好的封裝能夠減少耦合。

  2. 類內部的結構可以自由修改。

  3. 可以對成員變量進行更精確的控制。

  4. 隱藏信息,實現細節。

繼承的特性:

子類擁有父類非 private 的屬性、方法。

子類可以擁有自己的屬性和方法,即子類可以對父類進行擴展。

子類可以用自己的方式實現父類的方法。

Java 的繼承是單繼承,但是可以多重繼承,單繼承就是一個子類只能繼承一個父類,多重繼承就是,例如 A 類繼承 B 類,B 類繼承 C 類,所以按照關係就是 C 類是 B 類的父類,B 類是 A 類的父類,這是 Java 繼承區別於 C++ 繼承的一個特性。

提高了類之間的耦合性(繼承的缺點,耦合度高就會造成代碼之間的聯繫越緊密,代碼獨立性越差)。

多態的優點:
  1. 消除類型之間的耦合關係
  2. 可替換性
  3. 可擴充性
  4. 接口性
  5. 靈活性
  6. 簡化性
多態存在的三個必要條件:繼承 重寫 父類引用指向子類對象

內部類的學習!

九、異常處理

java異常使用筆記總結
在這裏插入圖片描述

十、集合、泛型和枚舉

瞭解數據結構學習集合會更好一點。

Collection接口框架圖

在這裏插入圖片描述
在這裏插入圖片描述

Map接口框架圖

在這裏插入圖片描述

十一、反射機制

在程序運行時由用戶輸入一個類名,然後動態獲取該類擁有的構造、屬性和方法,甚至調用任意類的任意方法。

類型 訪問方法 返回值類型 說明
包路徑 getPackage() Package 對象 獲取該類的存放路徑
類名稱 getName() String 對象 獲取該類的名稱
繼承類 getSuperclass() Class 對象 獲取該類繼承的類
實現接口 getlnterfaces() Class 型數組 獲取該類實現的所有接口
構造方法 getConstructors() Constructor 型數組 獲取所有權限爲 public 的構造方法
構造方法 getDeclaredContxuectors() Constructor 對象 獲取當前對象的所有構造方法
方法 getMethods() Methods 型數組 獲取所有權限爲 public 的方法
方法 getDeclaredMethods() Methods 對象 獲取當前對象的所有方法
成員變量 getFields() Field 型數組 獲取所有權限爲 public 的成員變量
成員變量 getDeclareFileds() Field 對象 獲取當前對象的所有成員變量
內部類 getClasses() Class 型數組 獲取所有權限爲 public 的內部類
內部類 getDeclaredClasses() Class 型數組 獲取所有內部類
內部類的聲明類 getDeclaringClass() Class 對象 如果該類爲內部類,則返回它的成員類,否則返回 null

在調用 getFields() 和 getMethods() 方法時將會依次獲取權限爲 public 的字段和變量,然後將包含從超類中繼承到的成員實量和方法。而通過 getDeclareFields() 和 getDeclareMethod()只是獲取在本類中定義的成員變量和方法。
(1.)訪問構造方法

方法名稱 說明
isVarArgs() 查看該構造方法是否允許帶可變數量的參數,如果允許,返回 true,否則返回false
getParameterTypes() 按照聲明順序以 Class 數組的形式獲取該構造方法各個參數的類型
getExceptionTypes() 以 Class 數組的形式獲取該構造方法可能拋出的異常類型
newInstance(Object … initargs) 通過該構造方法利用指定參數創建一個該類型的對象,如果未設置參數則表示採用默認無參的構造方法
setAccessiable(boolean flag) 如果該構造方法的權限爲 private,默認爲不允許通過反射利用 netlnstance()方法創建對象。如果先執行該方法,並將入口參數設置爲 true,則允許創建對象
getModifiers() 獲得可以解析出該構造方法所採用修飾符的整數

(2.)訪問方法

方法名稱 說明
getName() .獲取該方法的名稱
getParameterType() 按照聲明順序以 Class 數組的形式返回該方法各個參數的類型
getRetumType() 以 Class 對象的形式獲得該方法的返回值類型
getExceptionTypes() 以 Class 數組的形式獲得該方法可能拋出的異常類型
invoke(Object obj,Object…args) 利用 args 參數執行指定對象 obj 中的該方法,返回值爲 Object 類型
isVarArgs() 查看該方法是否允許帶有可變數量的參數,如果允許返回 true,否 則返回 false
getModifiers() 獲得可以解析出該方法所採用修飾符的整數

(3.)訪問成員變量

方法名稱 說明
getName() 獲得該成員變量的名稱
getType() 獲取表示該成員變量的 Class 對象
get(Object obj) 獲得指定對象 obj 中成員變量的值,返回值爲 Object 類型
set(Object obj,Object value) 將指定對象 obj 中成員變量的值設置爲 value
getlnt(0bject obj) 獲得指定對象 obj 中成員類型爲 int 的成員變量的值
setlnt(0bject obj,int i) 將指定對象 obj 中成員變量的值設置爲 i
setFloat(Object obj,float f) 將指定對象 obj 中成員變量的值設置爲 f
getBoolean(Object obj) 獲得指定對象 obj 中成員類型爲 boolean 的成員變量的值
setBoolean(Object obj,boolean b) 將指定對象 obj 中成員變量的值設置爲 b
getFloat(Object obj) 獲得指定對象 obj 中成員類型爲 float 的成員變量的值
setAccessible(boolean flag) 此方法可以設置是否忽略權限直接訪問 private 等私有權限的成員變量
getModifiers() 獲得可以解析出該方法所採用修飾符的整數
十二、輸入/輸出流

學習輸入/輸出流感觸最深的就是使用java的多態性。。。

主要的類如下:
 1. File(文件特徵與管理):用於文件或者目錄的描述信息,例如生成新目錄,修改文件名,刪除文件,判斷文件所在路徑等。

 2. InputStream(二進制格式操作):抽象類,基於字節的輸入操作,是所有輸入流的父類。定義了所有輸入流都具有的共同特徵。

 3. OutputStream(二進制格式操作):抽象類。基於字節的輸出操作。是所有輸出流的父類。定義了所有輸出流都具有的共同特徵。

 4.Reader(文件格式操作):抽象類,基於字符的輸入操作。

 5. Writer(文件格式操作):抽象類,基於字符的輸出操作。

 6. RandomAccessFile(隨機文件操作):一個獨立的類,直接繼承至Object.它的功能豐富,可以從文件的任意位置進行存取(輸入輸出)操作。
IO流的分類

根據處理數據類型的不同分爲:字符流和字節流
根據數據流向不同分爲:輸入流和輸出流
按數據來源(去向)分類:
1、File(文件): FileInputStream, FileOutputStream, FileReader, FileWriter
2、byte[]:ByteArrayInputStream, ByteArrayOutputStream
3、Char[]: CharArrayReader,CharArrayWriter
4、String:StringBufferInputStream, StringReader, StringWriter
5、網絡數據流:InputStream,OutputStream, Reader, Writer

在這裏插入圖片描述
Java 中的字符是 Unicode 編碼,即雙字節的,而 InputerStream 是用來處理單字節的,在處理字符文本時不是很方便。這時可以使用 Java 的文本輸入流 Reader 類!
所有輸入流類都是 InputStream 抽象類(字節輸入流)和 Reader 抽象類(字符輸入流)的子類。

InputStream 類是字節輸入流的抽象類,是所有字節輸入流的父類:

在這裏插入圖片描述
InputStream 類的常用子類如下。
ByteArrayInputStream 類:將字節數組轉換爲字節輸入流,從中讀取字節。
FileInputStream 類:從文件中讀取數據。
PipedInputStream 類:連接到一個 PipedOutputStream(管道輸出流)。
SequenceInputStream 類:將多個字節輸入流串聯成一個字節輸入流。
ObjectInputStream 類:將對象反序列化,操作的對象必須實現序列化接口。

InputStream中的三個基本的讀方法

(1.)int read() :讀取一個字節數據,並返回讀到的數據,如果返回-1,表示讀到了輸入流的末尾。
(2.)int read(byte[] b) :將數據讀入一個字節數組,同時返回實際讀取的字節數。如果返回-1,表示讀到了輸入流的末尾。
(3.)int read(byte[] b, int off, int len):將數據讀入一個字節數組,同時返回實際讀取的字節數。如果返回-1,表示讀到了輸入流的末尾。off指定在數組b中存放數據的起始偏移位置;len指定讀取的最大字節數。

流結束的判斷:方法read()的返回值爲-1時;readLine()的返回值爲null時。
其它方法

long skip(long n)):在輸入流中跳過n個字節,並返回實際跳過的字節數。
int available() :返回在不發生阻塞的情況下,可讀取的字節數。
void close() :關閉輸入流,釋放和這個流相關的系統資源。
void mark(int readLimit):在輸入流的當前位置放置一個標記,如果讀取的字節數多於readlimit設置的值,則流忽略這個標記。
void reset() :返回到上一個標記。
boolean markSupported() :測試當前流是否支持mark和reset方法。如果支持,返回true,否則返回false。

所有表示字節輸出流類的父類是 OutputStream,它也是一個抽象類,同樣子類需要重新定義父類的抽象方法:

ByteArrayOutputStream 類:向內存緩衝區的字節數組中寫數據。
FileOutputStream 類:向文件中寫數據。
PipedOutputStream 類:連接到一個 PipedlntputStream(管道輸入流)。
ObjectOutputStream 類:將對象序列化。

方法名及返回值類型 說明
void write(int b) 向輸出流寫入一個字節。這裏的參數是 int 類型,但是它允許使用表達式,而不用強制轉換成 byte 類型。爲了提高 I/O 操作的效率,建議儘量使用write() 方法的另外兩種形式
void write(byte[] b) 把參數 b 指定的字節數組中的所有字節寫到輸出流中
void write(byte[] b,int off,int len) 把參數 b 指定的字節數組中的若干字節寫到輸出流中。其中,off 指定字節數組中的起始下標,len 表示元素個數
void close() 關閉輸出流。寫操作完成後,應該關閉輸出流。系統將會釋放與這個輸出流相關的資源。注意,OutputStream 類本身的 close() 方法不執行任何操作,但是它的許多子類重寫了 close() 方法
void flush() 爲了提高效率,在向輸出流中寫入數據時,數據一般會先保存到內存緩衝區中,只有當緩衝區中的數據達到一定程度時,緩衝區中的數據纔會被寫入輸出流中。使用 flush() 方法則可以強制將緩衝區中的數據寫入輸 出流,並清空緩衝區
Java 的文本輸入流 Reader 類,該類是字符輸入流的抽象類,即所有字符輸入流的實現都是它的子類:

在這裏插入圖片描述
Reader 類的常用子類如下:
CharArrayReader 類:將字符數組轉換爲字符輸入流,從中讀取字符。
StringReader 類:將字符串轉換爲字符輸入流,從中讀取字符。
BufferedReader 類:爲其他字符輸入流提供讀緩衝區。
PipedReader 類:連接到一個 PipedWriter。
InputStreamReader 類:將字節輸入流轉換爲字符輸入流,可以指定字符編碼。

方法名及返回值類型 說明
int read() 從輸入流中讀取一個字符,並把它轉換爲 0~65535 的整數。如果返回 -1, 則表示已經到了輸入流的末尾。爲了提高 I/O 操作的效率,建議儘量使 用下面兩種 read()方法
int read(char[] cbuf) 從輸入流中讀取若干個字符,並把它們保存到參數 cbuf 指定的字符數組中。 該方法返回讀取的字符數,如果返回 -1,則表示已經到了輸入流的末尾
int read(char[] cbuf,int off,int len) 從輸入流中讀取若干個字符,並把它們保存到參數 cbuf 指定的字符數組中。其中,off 指定在字符數組中開始保存數據的起始下標,len 指定讀 取的字符數。該方法返回實際讀取的字符數,如果返回 -1,則表示已經 到了輸入流的末尾

Writer 類的常用子類如下。
CharArrayWriter 類:向內存緩衝區的字符數組寫數據。
StringWriter 類:向內存緩衝區的字符串(StringBuffer)寫數據。
BufferedWriter 類:爲其他字符輸出流提供寫緩衝區。
PipedWriter 類:連接到一個 PipedReader。
OutputStreamReader 類:將字節輸出流轉換爲字符輸出流,可以指定字符編碼。

方法名及返回值類型 說明
void write(int c) 向輸出流中寫入一個字符
void write(char[] cbuf) 把參數 cbuf 指定的字符數組中的所有字符寫到輸出流中
void write(char[] cbuf,int off,int len) 把參數 cbuf 指定的字符數組中的若干字符寫到輸出流中。其中,off 指定字符數組中的起始下標,len 表示元素個數
void write(String str) 向輸出流中寫入一個字符串
void write(String str, int off,int len) 向輸出流中寫入一個字符串中的部分字符。其中,off 指定字符串中的起始偏移量,len 表示字符個數
append(char c) 將參數 c 指定的字符添加到輸出流中
append(charSequence esq) 將參數 esq 指定的字符序列添加到輸出流中
append(charSequence esq,int start,int end) 將參數 esq 指定的字符序列的子序列添加到輸出流中。其中,start 指定子序列的第一個字符的索引,end 指定子序列中最後一個字符後面的字符的索引,也就是說子序列的內容包含 start 索引處的字符,但不包括 end索引處的字符
使用過程中比較常用的:

在這裏插入圖片描述

十三、多線程編程

程序員的懶惰讓他們很少有時間去編寫沒有人需要的代碼

1.併發優缺點

併發優點:

發揮多處理的強大的功能
建模的簡單性
異步事件的簡化處理
響應更加靈敏的用戶界面

併發的缺點:

安全性問題
活躍性問題
性能問題
java監視和管理控制檯:cmd命名輸入 jconsole

2.理解多線程與併發之間的聯繫與區別
區別:多線程其實並不是多個線程一起執行,而是線程之間因爲切換的速度非常的快,所以,我們看起來像不間斷的執行。
並行表示的是多個任務同時執行
聯繫:多線程並不一定是併發,如果是併發執行,那麼肯定是多個線程在一塊執行。

3.多線程與多進程的聯繫
進程是資源分配的基本單位
進程中包含多個線程,線程共享進程的資源
線程是處理器調度的基本單位

4.線程垃圾收集器(多線程執行的垃圾收集器,並行執行的垃圾收集器,serial單線程執行的垃圾收集器。)
(單線程一味的收集幹活,一直等它幹完活就結束,多線程一邊想着幹活,一邊進行線程之間的切換。對於佔用內存比較少,回收時間本來就比較短,可以使用單線程的垃圾收集器來進行收集,而它的性能是遠比多線程要快的,因此在某些情境下單線程是遠比多線程要快的)。
多線程下載並不是多線程提高了速度,也不是多線程的性能提高了,而是,由於外部服務器對資源的限制,爲每一個鏈接分配一定的帶寬,而不是將全部帶寬分給一個鏈接,也就是說多線程下載並不是多線程提高了速度,不是多線程的性能提高了,而是多個鏈接突破了這個遠程服務器的限制,也就導致了性能的提高。

5.線程的狀態以及各狀態之間的轉換詳解
創建狀態:new一個線程後,該進程就處於新建狀態,此時由JVM爲其分配內存,並初始化成員變量的值。
就緒狀態:調用start()方法之後,該線程處於就緒狀態。java虛擬機會爲其創建方法調用棧和程序計數器等待調度運行。
運行狀態:處於就緒狀態的線程搶佔到CPU,開始執行run()方法的線程執行體,則該線程處於運行狀態。
阻塞狀態:當處於運行狀態的線程失去所佔用資源之後,便進入阻塞狀態。
死亡狀態:線程結束或者出現異常或錯誤,該線程結束生命週期。

6.線程的初始化,中斷和源碼分析
Java中線程兩種類型:用戶線程和守護線程 Thread.setDaemon(false)爲用戶線程,默認也爲用戶線程,Thread.setDaemon(true)設置爲守護線程。
區別:1.主線程結束後用戶線程還會繼續運行,JVM存活。
2.如果沒有用戶線程,都是守護線程,那麼JVM結束(隨之而來的是所有一切煙消雲散,包括所有的守護線程)。
stop()只是讓這個線程無限期的等待下去,這個線程所獲取得鎖、獲取得其他資源都沒有被釋放掉,因此這種方法已經不建議使用了。
interrupt():中斷線程,interrupted():查看當前線程是否中斷,isInterrupted():判斷當前這個線程是否中斷。
interrupted()是靜態方法:測試當前線程是否已經是中斷狀態,執行後具有清除狀態功能。
isInterrupted()是實例方法:測試線程Thread對象,是否已經是中斷狀態,但不會清除中斷狀態。

7-10.線程創建方式(8種)
繼承Thread類
實現Runnable接口
帶有返回值的線程繼承Callable接口,使用FutureTask創建線程對象
內部類3種方式
Timer定時器 timer.schedule(new TimerTask(){},0,1000)
spring註解@Async
Lambda表達式parallelStream併發流

11.瞭解多線程帶來的安全風險
線程安全性問題
活躍性問題 死鎖(哲學家吃飯) 飢餓問題(食堂打飯) 活鎖(兩人過獨木橋)
性能問題 線程切換

12.從線程的優先級看飢餓問題

飢餓問題出現的三種情況:

1.優先級高的線程吞噬掉了優先級低的線程的CPU時間片
2.線程被永久堵塞在一個等待進入同步塊的狀態
3.處於等待狀態的線程永遠不被喚醒

如何儘量避免飢餓問題:

1.設置合理的優先級
2.使用鎖來代替synchronized

13.從java字節碼看線程安全問題
java自帶分析字節碼文件工具javap -verbose name.class文件
線程安全性問題出現的條件:
多線程環境下
多個線程共享一個資源
對資源進行非原子性操作

14.synchronized保證線程安全的原理(理論層面)
內置鎖/互斥鎖
修飾普通方法:內置鎖就是當前實例
修飾靜態方法:內置鎖就是當前Class字節碼文件
修飾代碼塊:內置鎖是放入的對象

15.synchronized保證線程安全的原理(JVM層面)
鎖存在的位置:存在對象頭中
對象頭中的信息:Mark Word,Class Metadata Address,Array Length

Mark Word:

線程Id
Epoch
對象的分代年齡信息
是否是偏向鎖
鎖標誌位

偏向鎖:

每次獲取鎖和釋放鎖會浪費資源
很多情況下,競爭鎖不是有多個線程,而是隻有一個線程在使用
只有一個線程在訪問同步代碼塊的場景

輕量級鎖:

自旋
多線程使用

重量級鎖:

只能有一個鎖進入代碼塊

16.單例問題與線程安全性深入解析
餓漢式單例模式不會出現線程安全問題
懶漢式單例模式使用雙重檢查加鎖和volatile關鍵字提高CPU性能和避免線程安全性問題

17.理解自旋鎖,死鎖,重入鎖
自旋鎖就是代碼被多個線程訪問時,如果上一個鎖不被釋放,則下一個線程進入自旋狀態。
死鎖就是被訪問的資源被互相鎖住,就進入死鎖狀態
重人鎖就是一個對象被線程訪問時,可以進入另一個同步方法,線程不會出現死鎖。因爲這兩個方法鎖的是同一個對象。

18.深入理解volatile原理與使用
被volatile修飾的變量,在彙編中多了一個lock指令,lock指令將當前處理器緩存行的數據寫回到系統內存中,其他cpu緩存該內存地址的數據失效了,
這就保證了當我們一個線程修改volatile修飾的變量的時候,另一個線程是可見的。
大量使用volatile會使處理器的緩存失效了,也就是說大量使用volatile會降低性能。
對比:volatile只能保證變量的可見性,但是,並不能保證對這個變量所操作的原子性。因此,synchronized可以完全替代volatile,但是volatile並不能取代
synchronized。
volatile保證變量在多個線程之間可見,保證變量的一致性
volatile稱爲輕量級鎖,被volatile修飾的變量,在線程之間是可見的。(可見:一個線程修改了這個變量的值,在另外一個線程中能夠讀到這個修改後的值)
volatile除了線程之間互斥以外,另一個非常大的作用,就是保證可見性。

19.JDK5提供的原子類操作以及實現原理
AtomicInteger 對整形數據類型原子性操作
AtomicIntegerArray 對整形數組的原子性操作
AtomicReference<> 對實體對象的原子性操作
AtomicIntegerFieldUpdater<> a = AtomicIntegerFieldUpdater.newUpdater(A.class,“old”);對實體對象的字段進行原子性操作,字段需要用volatile操作。

20.Lock接口認識與使用
Lock可以非阻塞的獲取鎖,能被中斷的獲取鎖,超時獲取鎖。
提供的方法:lock()加鎖 unlock()解鎖 lockInterruptibly()中斷鎖boolean tryLock()獲取鎖。
Lock需要顯示地獲取和釋放鎖,繁瑣,但可以使代碼更靈活。
Synchronized不需要顯示地獲取和釋放鎖,使用簡單。
Lock lock = new ReentrantLock();可以方便的實現公平性。

21.手動實現一個可重入鎖
思路:繼承Lock接口,實現lock()和unlock()方法,聲名布爾型isLockd,線程LockBy,整形lockcount三個變量。
操作這三個變量,通過wait()和notify()函數控制線程運行。

22,23.AbstractQueuedSynchronizer(AQS)詳解
實現加鎖和重入鎖

24.公平鎖
公平是針對鎖的獲取而言的,如果一個鎖是公平的,那麼鎖的獲取順序就應該符合請求的絕對時間順序。

25.讀寫鎖
寫 :排他鎖
讀:共享鎖
讀-讀能共存,
讀-寫不能共存,
寫-寫不能共存

26.分析ReentrantReadWriteLock
tryAcquire(int acquires) 互斥鎖加鎖
tryRelease(int releases) 互斥鎖釋放
tryAcquireShared(int unused)共享鎖加鎖
tryReleaseShard(int unused) 共享鎖釋放

27.鎖降級和鎖升級
鎖降級是指寫鎖降級爲讀鎖,在寫鎖沒有釋放的時候,獲取到讀鎖。
把讀鎖升級爲寫鎖,在讀鎖沒有釋放的時候,獲取到寫鎖。

28.線程安全性問題總結

重複線程安全性問題出現的條件

多線程環境下
具有共享資源
對共享資源進行非原子性操作

解決線程性安全問題的途徑

使用synchronized
volatile
JDK原子類
使用Lock

29.線程間的通信
wait()和notify()必須放在同步代碼塊中。
調用wait()方法時會釋放鎖,調用notify()時會加鎖。釋放鎖和加鎖都是這當前鎖釋放時拿到的。

30.生產者和消費者問題
生產類實現Runnable,傳入對象
消費類實現Runnbale,傳入對象
對象類裏面做生產和消費,控制產品個數,設置產品數量,然後利用通信控制生產和消費。

31-33.Condition的使用及原理解析有界隊列,和源碼閱讀
Condition的作用是對鎖進行更精確的控制,它的await()相當於wait(),它的signal()相當於notify(),它的signalAll()相當於notifyAll()
不同的是它不需要與synchronized捆綁使用,但需要與互斥鎖和共享鎖捆綁使用。

34.實現數據庫連接池
連接池有助於數據庫性能的提升
初始化時建立一定個數的連接放到linklist裏,獲取連接時去池中拿連接,如果池中沒有連接則等待,釋放一個連接時,可以叫醒獲取連接的線程。

35.線程加塞join
語法:j.start();j.join()

36.ThreadLocal用於保存某個線程共享變量
get: 獲取ThreadLocal中當前線程共享變量的值。
set: 設置ThreadLocal中當前線程共享變量的值。
remove: 移除ThreadLocal中當前線程共享變量的值。
initialValue: ThreadLocal沒有被當前線程賦值時或當前線程剛調用remove方法後調用get方法,返回此方法值。

37-41.併發工具類:CountDownLatch,CyclicBarrier,Semaphore,Exchanger
Semaphore:一個計數信號量
CountDownLatch:一個同步輔助類,在完成一組正在其他線程中執行的操作之前,它允許一個或多個線程一直等待。
CyclicBarrier:一個同步輔助類,它允許一組線程互相等待,直到到達某個公共屏障點
Exchanger:方便了兩個共同操作線程之間的雙向交換
42-44.FuterTask
哎,沒理解透,找個好心情再出發: https://blog.csdn.net/codershamo/article/details/51901057
45.Fork/Join框架
拆分處理最後合併,能夠發揮多核服務器的優勢
ForkJoinTask 實現類 RecursiveTask
class A extends RecursiveTask
@Override
protected Integer compute(){
A a1 = new A();
A a2 = new A();
a1.fork();
a2.fork();
return a1.join() + a2.join();
}
ForkJoinPool pool = new ForkJoinPool();
Future f = pool.submit(new A());
結果:f.get();
46-48.同步容器和併發容器
Vector(線程安全) -----同步容器----> ArrayList(線程不安全)-----併發容器----->CopyOnWriteArrayList
Hashtable(線程安全)-------同步容器----> HashMap(線程不安全)----併發容器----->CopyOnWriteHashMap
併發容器:ConcurrentLinkedQueue
49.java中的阻塞隊列BlockingQueue
private BlockingQueue queue = new ArrayBlockingQueue<>(10);
queue.push(1)發送 queue.take()抓取
50.Executors框架
public static void main(String[] args) {
// ExecutorService threadPool = Executors.newFixedThreadPool(10);//分配固定的線程數
ExecutorService threadPool = Executors.newCachedThreadPool();// 根據需要自動建立相應的線程數
for (int i = 0; i < 50; i++) {
threadPool.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
});
}
threadPool.shutdown(); // 關閉線程池
}

十四、網絡編程

ServerSocket 類表示 Socket 服務器端,Socket 類表示 Socket 客戶端,兩者之間的交互過程如下:
服務器端創建一個 ServerSocket(服務器端套接字),調用 accept() 方法等待客戶端來連接。
客戶端程序創建一個 Socket,請求與服務器建立連接。
服務器接收客戶的連接請求,同時創建一個新的 Socket 與客戶建立連接,服務器繼續等待新的請求。

URLConnection 類來表示與 URL 建立的通信連接,URLConnection 類的對象使用 URL 類的 openConnection() 方法獲得.

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