計算機網路實驗(1)
== 與 equals
==是一個比較運算子,基本資料型別比較的是值,引用資料型別比較的是地址值。
equals()是一個方法,只能比較引用資料型別。重寫前比較的是地址值,重寫後比較的物件屬性。
public static void main(String[]args){ Integer a=new Integer(100); Integer b=new Integer(100); int i=100; Integer j=100; System.out.println("a == b: "+(a==b) ); //falseSystem.out.println("i == j: "+(i==j)); //true System.out.println("i ==a :"+(a.equals(i))); //true System.out.println("b == j"+(b.equals(j))); //true }
Integer的equals原始碼
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
{ String s=new String("11"); String s1=new String("11"); String s2="11"; System.out.println("s == s1 :" +(s==s1)); //false System.out.println("s ==s1 :"+(s.equals(s1))); //true System.out.println("s ==s2 :"+(s==s2)); //false System.out.println("s ==s2 :"+(s.equals(s2))); //true }
String原始碼
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String aString = (String)anObject;
if (coder() == aString.coder()) {
return isLatin1() ? StringLatin1.equals(value, aString.value)
: StringUTF16.equals(value, aString.value);
}
}
return false;
}
Object物件的 hashCode equals方法的區別:
Java判重需要依次執行以上兩個方法,為什麼呢?首先hashCode方法會對物件生成一個hash值,效率非常高,但是並完全不可靠。有以下的推斷
1.equal()相等的兩個物件他們的hashCode()肯定相等,也就是用equal()對比是絕對可靠的。
2.hashCode()相等的兩個物件他們的equal()不一定相等,也就是hashCode()不是絕對可靠的。
所以解決方式是:每當需要對比的時候,首先用hashCode()去對比,如果hashCode()不一樣,則表示這兩個物件肯定不相等(也就是不必再用equal()去再對比了),如果hashCode()相同,此時再對比他們的equal(),如果equal()也相同,則表示這兩個物件是真的相同了,這樣既能大大提高了效率也保證了對比的絕對正確性!
hashset 簡單實現原理
HashSet它不保證儲存元素的迭代順序;此類允許使用null元素。
HashSet中不允許有重複元素,這是因為HashSet是基於HashMap實現的,HashSet中的元素都存放在HashMap的key上面,而value中的值都是統一的一個固定物件private static final Object PRESENT = new Object();
HashSet中add方法呼叫的是底層HashMap中的put()方法,而如果是在HashMap中呼叫put,首先會判斷key是否存在,如果key存在則修改value值,如果key不存在這插入這個key-value。而在set中,因為value值沒有用,也就不存在修改value值的說法,因此往HashSet中新增元素,首先判斷元素(也就是key)是否存在,如果不存在這插入,如果存在著不插入,這樣HashSet中就不存在重複值。
所以判斷key是否存在就要重寫元素的類的equals()和hashCode()方法,當向Set中新增物件時,首先呼叫此物件所在類的hashCode()方法,計算次物件的雜湊值,此雜湊值決定了此物件在Set中存放的位置;若此位置沒有被儲存物件則直接儲存,若已有物件則通過物件所在類的equals()比較兩個物件是否相同,相同則不能被新增。
ConcurrentHashMap問題?
1.7 是靠採用Segment陣列
+HashEntry陣列實現,每段Segment都有不同的鎖,使用Reentranlock加鎖;1.8 是採用
Node陣列
+CAS
+Synchronized
來保證併發安全進行實現。
Segment陣列預設的大小是16,Node陣列也是16。
get 方法實現,value宣告為volatile,保證了修改的可見性,因此不需要加鎖
put 方法:
size:1.7 首先採用不加鎖的方式計算兩次,如果兩次結果相同則返回,若不一致,則鎖住所有的Segment求和 1.8中使用一個volatile
型別的變數baseCount
記錄元素的個數,當插入新資料或則刪除資料時,會通過addCount()
方法更新baseCount
resize 1.7 跟hashmap一樣,但是在單執行緒中擴容 1.8支援併發擴容,HashMap擴容在1.8中由頭插改為尾插(為了避免死迴圈問題)
序列化問題:收藏
執行緒問題:
執行緒複用是呼叫run方法,是執行緒池底層的Worker不斷執行run方法,從佇列裡得到Task物件,執行Run方法。
造成執行緒停止執行的情況:丟擲一個異常 ; 呼叫sleep方法,執行緒是暫停執行,建立一個新執行緒和優先順序更高的執行緒進入就緒狀態,是搶佔,不是終止。
執行緒執行start方法成為就緒態
Java型別轉換:
short s=23;
s+=12;
float f=23+23.23; // 錯誤,型別轉換double - >float
short s1=23;
s1=s1+23; // 錯誤,int - > short
byte a=0,b=3;
byte c= (a+b); // int - > byte ,
Java中的byte,short,char進行計算時都會提升為int型別。
RandonAccessFile 的方法區別 seek 絕對定位,能定位到檔案的具體位置,消耗大; skipBytes ,相對定位,能跳過相對的位元組數。
內部類:
劃分:靜態內部類,成員內部類,區域性內部類,匿名內部類。
引用成員內部類OuterClass.this new InnerClass();
下列關於內部類的說法不正確的是
A)內部類的類名只能在定義它的類或程式段中或在表示式內部匿名使用
B)內部類可以使用它所在類的靜態成員變數和例項成員變數
C)內部類不可以用abstract修飾符定義為抽象類
D)內部類可作為其他類的成員,而且可訪問它所在類的成員
答案:C,內部類可以是抽象的。
集合
ArrayList 的初始化大小是10,增量按照1.5倍增長
類載入
classloader.loadClass("classname") ;這條語句是把類載入到記憶體中
class.forName("class") ; // 這種情況是 5 種對 類 進行初始化的情況之一,通過反射
不會觸發類的初始化:
訪問類的 static final 靜態常量(基本型別和字串)不會觸發初始化 類物件 // 但如果static final 修飾的類屬性是 引用型別,比如new String("jk") ; 那麼需要類初始化。
.class 不會觸發初始化
建立該類的陣列不會觸發初始化
引數傳遞:
Java中只有值傳遞,String , Integer 等物件都是不可變的,及final 修飾的,傳遞給方法引數時,原來的引用沒有發生變化,會建立一個新的引用指向方法接受的。
java的方法引數也能被final修飾
如果一個類有兩個方法,method(Object o) method(String s) , 現在呼叫這個方法,method(null) ,實際呼叫的是method(String s)這個方法,因為根據Java的引數判斷,String 和 Object 都能接受null,但是String是子類,更解決null,所有呼叫的方法是第二個。
JVM虛擬機器和垃圾回收
垃圾回收的執行緒優先順序相當低;GC程式開發者只能推薦回收,至於JVM何時進行,回收那些記憶體空間,程式設計師不能進行控制;垃圾回收只是回收那些不再使用的JVM記憶體,如果有嚴重的BUG,也會造成記憶體洩漏;進入DEAD的執行緒,也能再次恢復,不被回收。
shell
大於或大於等於 ge gt
開啟子shell sh bash ./ 不開啟子shell source
增加執行 r4 w 2 x1
chmod 755 / chmod a+x /chmod u+x //u =owner , o=other
函式:函式宣告可以不寫關鍵字function , 而函式呼叫的正確方式是直接寫函式名,不需要加上括號。 function_name
計算問題
字串
若串S=”UP!UP!JD”,則其子串的數目。一共八個字元| U | P | ! | U | P | ! | J | D |,子串必須連續,不考慮重不重複。8+7+6+5+4+3+2+1,(1+8)*8/2=36,然後再加上一個空串,所以一共37。
堆疊
有n個數組成的序列,現在要把它們存入堆疊後,再出來,有多少種方式,C(2n,n)/ (n+1) 種。
二叉樹
節點問題:葉子節點等於度為2節點加上1 , n0=n2+1 ; n=n0+n1+n2
平衡樹,的樹高等於 high=log2(n) n是二叉樹的節點數量
資料庫索引:
普通索引
唯一索引,值必須是唯一的,但允許為NULL,如果是組合索引,那麼列值的組合必須唯一。
全文索引,只有在 char varchar text欄位能建立,5.6以前版本只有MyISAM支援,5.6以後Innodb也支援 ;和常用的模糊匹配使用 like + % 不同,全文索引有自己的語法格式,使用 match 和 against 關鍵字 ,match必須指出全文索引的列,全文索引比普通的模糊匹配效率高,但是可能會存在精度問題。
組合索引(最左字首) :有兩個以上的列值 ,比如如果在3個欄位上建立索引,(state, city ,zip ) 根據最左字首原則,它只能匹配以下欄位才會用到索引 state , state city , state city zip 。
組合索引的使用場景:全欄位匹配,匹配部分最左字首,匹配第一列,匹配第一列範圍查詢(可用用like a%,但不能使用like %b),精確匹配某一列和範圍匹配另外一列 where order by 可以使用如上5種情況的
例如,建立多列索引(name, age, id),只能使用索引的前兩列。in是範圍查詢
... where name='nginx.cn' and age in(15,16,17) order by id ||使用整個索引,in是按值查詢... where name='nginx.cn' and age in(15,16,17) and id ='3'
索引失效情況:
查詢中有 or ,
注意:要想使用or,又想讓索引生效,只能將or條件中的每個列都加上索引
組合索引,不按照最左字首原則使用索引
like查詢,使用%開頭
如果列型別是字串,條件資料中的值 需要用 引號 把字串包起來
進行控制判斷 is null , is not null, != ,< >,
在索引列上做操作,比如計算,函式,手動,自動型別轉換,會導致索引失效
SQL語句的子類: 資料定義語言DDL 資料查詢語言DQL 事務控制語言TCL ; 資料插入語言不是SQL語句的子類
資料庫
drop 刪除資料和表
delete 隱藏資料,資料不可見,主鍵不清空,繼續增長
truncate 刪除資料,主鍵歸0