一、Java基礎語法
1.參數傳遞
void change(String s, Integer x, Double f, ArrayList<Integer> list, Node node, char[] a);
- 前三個是傳值調用,方法里修改形參不會對原來的值造成影響;
- 后三個是引用調用,方法里修改形參會對原來的值(地址中的值)造成影響;
2.靜態變量能否用this調用?
在語法上行得通,但是靜態變量是所有實例共享的一個變量,而this通常指當前對象;用對象名調用普通變量,用類名調用靜態變量更加直觀。許多題目把this調用直接打死,按它們的來。
3.形參引用
靜態變量或普通變量a和方法形參a同名,不論類型是否相同,在方法里都是優先使用形參。方法里形參是老大,所以set方法形參同名需要加上this,不同名可以不加this。
4.初始化二維數組
不一定按照n*m矩陣來初始化
int[][] a=new int[][]{ {1,2},{3,4,5,6,7},{1},{33},{21,352} };
a.length=5;a[0].length=2;a[1].length=5;
等號左邊合法的有:int[][] a、int[] b[]、int c[][];等號右邊合法的有new int[5][5]、new int[5][]、{}、{{}};
5.try-catch-finally
- try中有異常不會執行異常語句后的代碼,因此有異常時try中的return作廢;
- catch,有異常才會執行,return等級>try的return;
- finally,有沒有異常都會執行,return等級>catch>try;
- try必然要有,catch和finally至少保留一個;
(1)try和finally都沒有return
- 如果try沒有異常則執行try→finally;
- 如果try有異常,則執行try→catch→finally;
- 並且會繼續執行finally后的代碼塊,若是停了那就體現不出捕獲異常的作用了;
如果try里有異常並且finally里又有異常,如果不捕獲finally里的異常則程序終止(不會運行finally后的代碼),捕獲則按常理度之;
(2)try有return,catch沒有return,finally沒有return
由於try中異常語句后的代碼不會執行,所以finally代碼塊后還有需要有return語句兜底;
- 如果try有異常,執行try-catch-finally,最終返回值取finally代碼塊后的return;(如果catch里有return 則取catch里的,最后的return語句作廢;)
- 如果沒有異常,執行try代碼塊就跑了,返回值取try里的;
(3)try有return,catch有return,finally沒有return
- try沒有異常,返回值取try的;
- try有異常,返回值取catch的;
finally代碼塊后不可以有代碼,因為try或者catch會返回函數,不執行到后面;
(4)finally有return
不論try和catch有沒有return,返回值都取finally里的,並且finally代碼塊后不允許有代碼了;
(5)沒有catch,有finally
無返回值時,發生異常程序終止(不會執行finally后的語句),因此catch是解決異常的關鍵;
6.運算&賦值
- System.out.println( (5>4)?8:4.05 );//輸出8.0
- (short)10/10.2*2; 結果是double類型,先將10強轉為short,又因為運算過程自動向上轉型變成double的運算,最后結果是double類型
- int x=20,y=5;System.out.println(x+y+""+(x+y)+y);//25255
- System.out.println(5+6+""+5+7);//1157 任何字符與字符串相加都是字符串,但是字符串前面的按原格式相加后拼接,字符串后面的直接按字符串拼接
- 運算優先級:>、<、&&、||。例如b=x>50&&y>60||x>50&&y<-60||x<-50&&y>60||x<-50&&y<-60;變成b=(x>50&&y>60)||(x>50&&y<-60)||(x<-50&&y>60)||(x<-50&&y<-60);
- 乘除模運算優先級相同,10%3*2=1*2=2;
- int a=1_0_2_4;數值間插入下划線這是合法的;
- char、byte和short參與運算時會自動將這些值轉換為int類型再進行運算;short a1=3,a2=4,a3;a3=a1*a2;這樣會報錯,但是a3=3*4;不會報錯;
7.Java變量
- 實例變量:定義在類中但不在方法里,即類的成員屬性。具有默認值,數值類型默認0,布爾類型默認false,引用類型默認null,可以在聲明時指定,也可以在構造方法中指定;
- 局部變量:方法中的變量,需要先賦值再運算。不賦值直接使用會導致 編譯不通過。在方法中任意寫個花括號也屬於一個局部,在花括號內定義的變量不能用在括號外;
- 靜態變量:類似方法,只加載一次,放在堆里,類的多個對象共享一個靜態變量(方法);
8.StringBuilder、StringBuffer、String
- 線程安全性:StringBuffer和String線程安全,StringBulider線程不安全。
- 運行速度:StringBuilder>StringBuffer>String。
9.數組復制效率
System.arraycopy > clone > Arrays.copyOf > for循環
System.arraycopy和clone都是native方法,記一下就好。Arrays.copyOf是對System.arraycopy的調用,多了一層肯定不是最快的,for循環我都會寫肯定是最慢的。
10.Java程序的種類
內嵌於Web文件中由瀏覽器觀看的Applet;可獨立運行的Application;服務器端的Servlets。
11.注釋與編譯
注釋是給人看的,不是給機器看的。編譯器不會編譯注釋中的內容;字節碼文件也沒有注釋內容;注釋過多也不會導致編譯后的程序尺寸變大。
點開一些jar包的看看字節碼文件.class,發現全都沒有注釋,然而Java文件就有注釋。
12.基本數據類型的聲明
double d0=1;//正確,輸出1.0 double d1=1.0;//正確,輸出1.0 Double d2=1.0;//正確,輸出1.0 Double d3=1;//錯誤;正確的是1D,輸出1.0 double d4=666.00;//正確,輸出666.0 float f1=4.0;//錯誤;正確的是4.0F,輸出4.0 float f2=4;//正確,輸出4.0 Float f3=4;//錯誤;正確的是4F,輸出4.0 Float f4=4.0;//錯誤;正確的是4.0F,輸出4.0 int i=(int)true;//錯誤,boolean不可以和其他類型轉換 long l1=012;//正確 0前導表示八進制,0x表示十六進制 long l2=12;//正確 Long l3=12;//錯誤;正確的是12L Long l4=012;//錯誤;正確的是012L
13.集合類的線程安全
14.構造方法
- 構造方法沒有返回值,並不是void;
- 構造方法優先級最低;
- 構造函數不能被繼承,構造方法只能被顯式或隱式的調用。
15.初始化代碼執行順序
父類靜態變量→父類靜態代碼塊→子類靜態變量→子類靜態代碼塊→
父類普通變量→父類普通代碼塊→父類構造方法→
子類普通變量→子類普通代碼塊→子類構造方法
嚴格的說,靜態變量+靜態代碼塊=靜態域,不包括靜態方法,誰先誰后根據在類中的位置,由於一般都是先聲明變量的,所以有這樣的總結。這里有一個難以想象的題目,十有八九會被坑,詳看代碼及注釋,節省篇幅。

public class B { public static B t1 = new B(); public static B t2 = new B(); { System.out.println("構造塊"); } static { System.out.println("靜態塊"); } public static void main(String[] args) { B t = new B(); } } /** 輸出: 構造塊 構造塊 靜態塊 構造塊 -------------------------------------------------- 解釋: 1.加載B.class 2.按照順序先對t1和t2進行初始化,默認為null 3.又需要對t1和t2進行顯示初始化,所以需要加載默認的構造方法和普通代碼塊 4.為什么不會加載靜態代碼塊呢? 5.因為剛開始加載B.class時就算是加載了靜態域,現在還沒加載完,又不能重復加載,所以沒有在初始化t1的時候輸出靜態塊 6.t1和t2加載完了按順序就輪到靜態代碼塊了 7.走main方法,又創建一次B對象,執行構造方法和普通代碼塊 要點:靜態域只加載一次,不能重復加載 */
16.內部類
普通內部類
- private:本類
- default:本類、本包
- protected:本類、本包、子類(哪怕子類外包)
- public:本類、本包、子類、外包
靜態內部類才可以聲明靜態方法,靜態方法不能使用非靜態變量。
17.泛型
提高數據安全性,不提高性能。(又方便又能提高性能簡直沒天理了,有得必有失。)
泛型是語法糖,不會影響JVM生成的匯編代碼,在編譯階段會有類型擦除,還原成沒有泛型的代碼,所以運行速度提高或者降低應該都是不對的,應該是編譯速度慢一點而已。
18.重寫
只要是被子類重寫的方法,不被super調用都是調用子類方法

public class Main{ static int[] a=new int[5]; static int[] vis=new int[5]; static int ans=0; public static void main(String []args) { Base base=new Derived(); base.methodOne();//ABDC } } class Base { public void methodOne() { System.out.print("A"); methodTwo(); } public void methodTwo() { System.out.print("B"); } } class Derived extends Base { public void methodOne() { super.methodOne(); System.out.print("C"); } public void methodTwo() { super.methodTwo(); System.out.print("D"); } }
19.棧與堆
(1)整型常量池,byte、int、short、long都對[-128,127]之間的數創建了常量池,如果沒有顯示調用new方法,默認不開辟新的堆內存,統一指向堆中常量池的地址。(至於不同類型同一個數字是不是同一個常量池就不清楚了,hashcode直接返回值看不出來,==則說不同類型無法比較)
(2)拆箱,任何比較中有基本數據類型例如i2,全部自動拆箱比較數值,i1至i6與i2比較都返回true
20.ASCII碼
- 標准ASCII只使用7個bit,擴展的ASCII使用8個bit;
- ASCII碼包含一些特殊空字符,所以不全都是可以印字符,例如'\0';
21.取模和取余
取模運算(“Modulus Operation”)和取余運算(“Remainder Operation ”)兩個概念有重疊的部分但又不完全一致。主要的區別在於對負整數進行除法運算時操作不同。取模主要是用於計算機術語中,取余則更多是數學概念。
刷算法題也好、業務也好,用的都是小學數學教的取余運算。x%y中,x叫做被除數,y叫做除數,x%y的結果,符號與被除數x相同,數值部分按照兩個都是正數來算。
int x,y; x=12;y=5;//x%y=2 x=-12;y=-5;//x%y=-2 x=-12;y=5;//x%y=-2 x=12;y=-5;//x%y=2
22.字符串分割
String.split(String regex)
沒有切割的匹配字符串時將原字符串放入字符串數組
String s="";//s.length()=0 String[] res=s.split(",");//res.length=1;res[0]=""; s="123"; res=s.split(",");//res.length=1;res[0]="123";
23.序列化
序列化保存的是類對象的狀態,靜態變量屬於類的狀態;因此,靜態變量不會被序列化。
用關鍵字transient修飾的變量也不會被序列化。
24.接口interface
(1)接口方法默認public abstract,變量默認為public static final。
(2)方法和變量不可以使用private修飾;因為接口本身就是為了實現,用private就失去意義了。
(3)接口方法不可以用靜態static修飾
25.主函數main
public static void main(String[] args){};嚴格一致才是主函數;
public void main(String[] args){};可以存在,不是主函數;
private static void main(String[] args){};可以存在,不是主函數;
26.關鍵字
尤其注意幾個容易混淆的非關鍵字,true、false、null、sizeof
27.異常
- throw用於拋出異常;
- throws關鍵字可以在方法上聲明該方法要拋出的異常,然后在方法內部通過throw拋出異常對象;
編譯時異常必須顯示處理,就是IDEA看到的那些爆紅,手動去改;運行時異常交給虛擬機,看不出來的,運行的時候去捕獲、拋出;
運行時異常如果不處理,出現異常后就層層上拋:多線程由Thread.run()拋出,線程終止;單線程由main()拋出,主程序終止;
28.浮點數和數組比較
(!)浮點數比較
- 切記不要用==比較
- 一般認定一個閾值THRESHOLD,精度差小於某個閾值即可,Math.abs(a-b)<THRESHOLD
- BigDecimal類,用compareTo()方法比較;BigDecimal類的equals()方法會比較位數,導致1.0和1.00不一致
- 在運算過程中會產生精度差 double d1=0.1*3;//0.30000000000000004 double d2=0.3;//0.3
(2)數組比較
- 數組a.equals(數組b):比較地址,相當於==
- Arrays.equals(數組a,數組b):逐個比較元素
29.重載和重寫
重載:同一個類、方法名相同、形參列表不同(個數不同 或者 類型不同);與修飾符、返回值無關;
重寫:兩同、兩小、一大。方法名和參數列表相同;拋出異常類型和返回值類型<=父類;訪問權限>=父類;
30.常規&偏門概念
(1)前台線程指非守護線程如main函數,后台線程指守護線程例如GC,JRE判斷程序結束是否執行結束的標准是所有前台線程執行完畢
(2)一般關系數據模型和對象數據模型之間有以下對應關系:表對應類,記錄對應對象,表的字段對應類的屬性。沒有上升到類的依賴層面
(3)Java程序中public修飾的類名必須與文件名一樣
(4)jdk、jre、jvm、javac之間的關系
- jdk:java development kit,是Java開發工具包
- jre:java runtime environment,是指java運行環境。
- jvm:java virtual machine,就是我們常說的java虛擬機,它是整個java實現跨平台的最核心的部分,.class文件就是在這里運行
- javac:java編譯器,讀取Java源代碼,將其編譯為字節碼文件.class文件
關系:jdk包含jre和javac,jre包含jvm。
(5)Java的屏幕坐標是以像素為單位,容器的左上角被確定為坐標的起點。
(6)一個Java源程序文件中定義幾個類和接口,則編譯該文件后生成幾個以.class為后綴的字節碼文件。
31.字符串拼接和替換問題
(1)字符串拼接
String test="javaandpython"; String str1="java"; String str2="and"; String str3="python"; String str4=str1+str2+str3; System. out. println(test=="java"+"and"+"python");//true System. out. println(test ==str1 + str2 + str3);//false System.out.println(test=="java"+"and"+str3);//false System.out.println(test==str4);//false
- 字面量拼接,編譯器會進行優化“+”操作得到一個“javaandpython”的字符串,如果常量池沒有這個字符串,就創建一個,有就直接用。這是在編譯期間進行的;
- 引用量拼接,運算在Java運行期間執行的,會在堆中重新創建一個字符串對象,引用量的存在證明前面已經對引用量賦值了,常量池本就有str1、str2、str3的存在;因此,凡是有引用量進行操作的都在運行期間生成的對象,==比較會返回fasle;
(2)字符串替換
- 普通替換:String replace(char/String a, char/String b),字符換字符或者字符串換字符串;
- 正則表達式替換:String replaceAll(String regex, String replacement),第一個參數是正則表達式,例如"."表示全部字符替換成后者;
32.字節流和字符流
字符流是字節流根據編碼集解析獲得的,簡言之,字符流=字節流+編碼集
- 字節流:以Stream結尾
- 字符流:以Reader或者Writer結尾
33.中英文字符串的字節數和長度
英文每個字符占1字節、1長度。
中文每個字符占1長度,GBK編碼占2字節,UTF-8占3字節,Java默認使用UTF-8。
34.Math的三個取整相關方法
- public static double floor(double a):floor意為地板,向下取整,返回不大於它的最大整數,注意正負並且返回的是浮點數!
- public static double ceil(double a):ceil意為天花板,向上取整,返回不小於它的最大整數,注意正負並且返回的是浮點數!
- public static long round(double a)或者public static int round(float a):round意為大約,表示“四舍五入”,注意正負並且返回的是整數;
35.移位運算
移位運算是補碼在移位,不是原碼,由於一般都是正數在計算,補碼和原碼一樣,讓人誤以為是二進制原碼在移位。
(1)左移<<,只有<<,沒有<<<,因為都是右邊補0,不需要管左邊的符號位
(2)右移>>,左邊正數補符號位0,負數補符號位1
(3)無符號右移>>>,左邊補0

public static void main(String[] args) { int a; a=-5; /** -5 * 原碼:10000000 00000000 00000000 00000101 * 反碼:11111111 11111111 11111111 11111010 * 補碼:11111111 11111111 11111111 11111011 */ System.out.println(a<<5);//-160 /** -160 * 原碼:10000000 00000000 00000000 10100000 * 反碼:11111111 11111111 11111111 01011111 * 補碼:11111111 11111111 11111111 01100000 */ a=5; /** 5 * 原碼:00000000 00000000 00000000 00000101 * 反碼:00000000 00000000 00000000 00000101 * 補碼:00000000 00000000 00000000 00000101 */ System.out.println(a<<2);//20 /** 20 * 原碼:00000000 00000000 00000000 00010100 * 反碼:00000000 00000000 00000000 00010100 * 補碼:00000000 00000000 00000000 00010100 */ a=234567; /** 234567 * 原碼:00000000 00000011 10010100 01000111 * 反碼:00000000 00000011 10010100 01000111 * 補碼:00000000 00000011 10010100 01000111 */ System.out.println(a>>2);//58641 System.out.println(a>>>2);//58641 /** 58641 * 原碼:00000000 00000000 11100101 00010001 * 反碼:00000000 00000000 11100101 00010001 * 補碼:00000000 00000000 11100101 00010001 */ a=-123456; /** -123456 * 原碼:10000000 00000001 11100010 01000000 * 反碼:11111111 11111110 00011101 10111111 * 補碼:11111111 11111110 00011101 11000000 */ System.out.println(a>>2);//-30864 /** -30864 * 原碼:10000000 00000000 01111000 10010000 * 反碼:11111111 11111111 10000111 01101111 * 補碼:11111111 11111111 10000111 01110000 */ System.out.println(a>>>5);//134213870 /** 1073710960 * 原碼:00000111 11111111 11110000 11101110 * 反碼:00000111 11111111 11110000 11101110 * 補碼:00000111 11111111 11110000 11101110 */ }
二、數據庫
1.有一個成績表tb_course,有姓名name、科目course、分數字段score,用一條SQL語句查詢出所有單科成績都大於80分的學生姓名
select name from tb_course group by name having (Min(score)>80);
2.事務隔離
- 讀未提交:臟讀,針對未提交的數據;
- 讀已提交:不可重復讀,針對已提交的數據項;
- 可重復讀(MySQL默認隔離):幻讀,針對已提交的一批數據;
- 序列化:不會產生讀取問題
3.MySQL中的關鍵字不可以用作字段名,加上反單引號`可以使關鍵字作為字段名,選擇題中默認不可以
4.組合索引
例如index( name,age )作為組合索引,左邊第一個字段(name)需要作為條件才可以在查詢中使用索引
- where name like 'shoulinniao' [ and age=22 ] 使用索引,explain執行計划的type為range級別
- where name = 'shoulinniao' [ and age=22 ] 使用索引,explain執行計划的type為ref級別
- where age = 22 不使用索引,explain執行計划的type為ALL級別
5.Oracle數據文件和表空間
數據文件由表空間進行組織管理,表空間是數據文件的邏輯集合。
一個表空間至少包含一個數據文件,一個數據文件只能屬於一個表空間。
6.主鍵索引可以是聯合索引
三、經典問題
1.虛數概念
i = i; i2 = -1; i3 = i2 * i = -i; i4 = i2 * i2 = (-1)*(-1)=1;
2.生日悖論
只要23個人,至少兩人生日是同一天的概率高達50%
3.三門問題
這是一個游戲,有三個門,一個有禮物,兩個空的;
參與者先選定一個門但是不打開;
主持人隨機打開剩下的兩個門的其中一個,發現是空的;
主持人問參與者要不要修改剛才選擇的門?
不改中獎率是1/3,改了中獎率是2/3。
4.紅帽子和黑帽子
舞會上人均一個帽子,非紅即黑,全場至少有1頂黑帽子,每個人只能看別人的帽子,不能看到自己的帽子,不能交流,關燈時認為自己是黑帽子就打自己一巴掌。
- 假設只有一頂黑帽子,那么他看到的都是紅帽子,則自己就是黑帽子,第一次關燈就打自己;
- 假設只有兩頂黑帽子,那么他們都看到外面有一頂黑帽子,第一次關燈都在等那個黑帽子自己掌嘴,結果對面也在等自己掌嘴,說明全場不止一頂黑帽子,但是看到的只有一頂黑帽子,那自己就是黑帽子,第二次關燈兩個人都掌嘴;
三次至n次同理,需要第3次至第n次關燈才有人掌嘴;
5.銀行家算法
以銀行借貸系統的分配策略為基礎,判斷並保證系統的安全運行。有以下規定:
- 客戶的最大需求資金不超過銀行的現有資金時,可以接納該客戶;
- 客戶可以分期貸款,相當於進程后續需要再申請資源,但是貸款總額度不應該超過最大需求資金;
- 如果當前銀行不能滿足某個客戶,則讓這個客戶等待,但是會在有限時間里(避免死鎖)接納該客戶;
- 客戶獲取資金后,能在有限時間內歸還資金;
有兩個常見結論:安全狀態一定不會導致死鎖;不安全狀態不一定會導致死鎖。
6.哲學家用餐問題(互斥訪問有限資源的競爭問題)
五位哲學家圍起來,任意兩個哲學家之間有一根筷子,如何避免死鎖?
- 至多4個哲學家同時拿起左筷子,這能保證至少有一個哲學家正常用餐,最后釋放兩只筷子給其他人使用
- 規定奇數號哲學家先拿左筷子再拿右筷子,偶數則相反
- 當哲學家左右兩根筷子都可以用時,才拿起它們
- 拿起一只筷子后無法獲取另一根筷子時,放下筷子,隨機等待一段時間后再嘗試獲取
7.讀者-寫者問題
四、算法與數據結構
2.關鍵路徑是起點到終點之間最長路徑長度的路徑
3.環形隊列大小 size = (rear + n - front)%n;
五、JVM
1.jvm指令,混個臉熟
- jps:查看本機Java進程信息;
- jstack:打印線程的棧信息,制作線程dump文件
- jmap:打印內存映射,制作堆dump文件
- jstat:性能監控工具
- jhat:內存分析工具
- jconsole:簡易的可視化控制台
- jvisualvm:功能強大的控制台
2.JVM內存五大區域
PC寄存器就是程序計數器,方法區和堆是線程共享的,其他屬於線程私有。
3.堆外內存off-heap
不受JVM管控,直接受操作系統管控。
將對象從堆中脫離出來序列化,然后存儲在一大塊內存中,這就像它存儲到磁盤上一樣,但它仍然在RAM(主存)中。對象在這種狀態下不能直接使用,它們必須首先反序列化,也不受垃圾收集。序列化和反序列化將會影響部分性能(所以可以考慮使用FST-serialization)使用堆外內存能夠降低GC導致的暫停。堆外內存不受垃圾收集器管理,也不屬於老年代,新生代。
六、計算機網絡
1.各層協議
2.狀態碼
200:請求成功
403:服務器理解請求客戶端的請求,但是拒絕執行此請求
404:服務器無法根據客戶端的請求找到資源(網頁)。通過此代碼,網站設計人員可設置"您所請求的資源無法找到"的個性頁面
500:服務器內部錯誤,無法完成請求
3.單播、多播、廣播、任播
單播對象是針對某一台機,廣播對象是與本機的相連的所有機,多播對象是限定某組里多台機,任播是限定某組里一台機。
七、操作系統
1.緩存淘汰算法
2.頁面置換算法
3.段頁式存儲
4.虛擬內存容量只受硬盤剩余空間的限制
5.計算機所能處理的最小的數據項是位
6.孤兒進程
孤兒進程指的是在其父進程執行完成或被終止后仍繼續運行的一類進程。這些孤兒進程將被init進程(進程號為1)所收養,並由init進程對它們完成狀態收集工作。init進程就好像是一個民政局,專門負責處理孤兒進程的善后工作。
7.僵屍進程zimbie
子進程比父進程先退出,但是父進程沒有調用wait/waitpid回收子進程的資源,則子進程變成僵屍進程,等父親收屍。
(1)造成什么影響?
子進程一直處於z狀態,需要進程控制塊PCB維護,浪費資源,導致內存泄漏。
(2)如何避免?
改寫父進程,在子進程死后要為它收屍。具體做法是接管SIGCHLD信號。子進程死后, 會發送SIGCHLD信號給父進程,父進程收到此信號后,執行 waitpid()函數為子進程收屍。這是基於這樣的原理:就算父進程沒有調用wait,內核也會向它發送SIGCHLD消息,盡管對的默認處理是忽略, 如果想響應這個消息,可以設置一個處理函數。
把父進程殺死,讓僵屍進程成為孤兒進程。
8.操作系統的調度
一般說來,作業從進人系統到最后完成,可能要經歷三級調度:高級調度、中級調度和低級調度。
高級調度:作業調度
中級調度:為了使內存中同時存放的進程數目不至於太多,有時需要把某些進程從內存中移到外存中,以減少多道程序的數目。特別是在采用虛擬存儲技術的系統中或分時系統中。引入中級調度的主要目的是為了提高內存的利用率和系統吞吐量。它實際上就是存儲器中的對換功能。
低級調度:進程調度
生產調度:生產指揮者對當日生產過程的具體安排和實時的調整,對生產過程發出的是指令性的命令。
十、設計模式
1.設計模式六大原則
- 開閉原則:對擴展開放、對修改關閉。要擴展時不改動原來的代碼。這是最基礎的設計原則,其他五個原則都是開閉原則的具體形態。
- 單一職責原則:一個類只負責一個功能領域中的相應職責,不能承載太多功能,導致被復用的可能性變小。
- 里氏替換原則:所有引用父類的地方必須能透明地使用其子類對象,即子類的所有方法必須在父類中聲明,盡量把父類設計為抽象類或接口。
- 依賴倒置原則:細節依賴抽象,核心思想是面向接口編程。每個類盡量提供接口或抽象類,任何類不應從具體類派生。
- 接口隔離原則:接口粒度合適,只服務一個模塊業務,不要把太多方法堆在一個接口里。單一職責原則注重的是職責、約束類,接口隔離原則注重接口隔離、針對抽象和整體框架的構建。
- 迪米特法則:只和朋友對話,不要和陌生人說話。如果真的有需要,通過中間人傳遞信息。朋友指的是和當前對象有關聯的。
2.JDBC使用了橋接模式,提供兩套接口,一個面向數據庫廠商,一個面向JDBC使用者
隨緣刷題,持續更新修正!