JAVASE學(xué)習(xí)筆記

1.導(dǎo)包

ctrl+shift+字母o ,回車

2.保留指定位數(shù)的小數(shù)

(1)保留幾位小數(shù)??“%.nf” ,n保留的小數(shù)位數(shù) ,保留2位小數(shù) "%.2f"

(2)//借助 java.text.DecimalFormat類 炭晒,格式化數(shù)字??保留幾位小數(shù),就留幾個(gè)“0”

????????DecimalFormat df = new DecimalFormat(".000");

????????//借助df格式化pi????str="3.142" ,是一個(gè)字符串???

????????//format()方法筒严,將 double 按指定格式 輸出成字符串

????????String str = df.format(pi);

????????System.out.println("str="+str);

????????// 將字符串 轉(zhuǎn)換成 double類型的浮點(diǎn)數(shù)

????????double result = Double.parseDouble(str);

3.Math.round(a)

4.多重if

范圍打亂闸昨,順序?qū)Y(jié)果又影響 ,要么從大往小寫箫攀,要么從小往大寫磁餐,對于順序打亂违崇,解決辦法:加上邏輯限制條件。

5.隨機(jī)數(shù)

[min, max) 整數(shù)???(int)(Math.random()*(max-min)+min);

Random??ra??= new Random();

[min, max)????整數(shù):???ra.nextInt(max-min)+min

6.冒泡排序

????int[] arr = {5,4,3,2,1};

????????????//聲明中間變量诊霹,用于交換

????????????int temp=0;

????????????//控制輪數(shù)

????????????for(int k=0;k<arr.length-1;k++){

????????????????System.out.println("\n\n第"+(k+1)+"輪開始時(shí):"+Arrays.toString(arr));

????????????????//內(nèi)層控制的每一輪比較的次數(shù)羞延,要保證比較次數(shù)在減少, 取值畅哑,4肴楷,3水由,2荠呐,1

????????????????for(int i=0;i<arr.length-1-k;i++){

????????????????????//如果前一個(gè)比后一個(gè)大需要交換

????????????????????if(arr[i]>arr[i+1]){

????????????????????????temp=arr[i];

????????????????????????arr[i]= arr[i+1];

????????????????????????arr[i+1]=temp;

????????????????????}

????????????????????System.out.println("第"+(k+1)+"輪第"+(i+1)+"次比較:"+Arrays.toString(arr));

????????????????}

????????????????System.out.println("第"+(k+1)+"輪結(jié)束后:"+Arrays.toString(arr)+"\n\n");

????????????}

選擇排序

????public static void main(String[] args) {


?????int [] arr=new int [] {45,65,32,33,12,1};

?????for(int i=0;i<arr.length-1;i++) {

????????int index=i;

????????for(int j=i+1;j<arr.length;j++) {

????????????if(arr[j]<arr[index]) {

????????????????int temp=arr[index];

????????????????arr[index]=arr[j];

????????????????arr[j]=temp;

????????????}

????????}


?????}

?????System.out.println(Arrays.toString(arr));

????}

快速排序


????public static void main(String[] args) {

????????int[] arr = new int[] { 1, 2, 4, 5, 7, 4, 5, 3, 9, 0 };

?????//System.out.println(Arrays.toString(arr));

????????quickSort(arr);

????????System.out.println(Arrays.toString(arr));

????}

????private static void quickSort(int[] arr) {

????????if (arr.length > 0) {

????????????quickSort(arr, 0, arr.length - 1);

????????}

????}

????private static void quickSort(int[] arr, int low, int high) {

????????// 1.遞歸算法出口

????????if (low > high) { // 放在key之前,防止下標(biāo)越界

????????????return;

????????}

????????// 2. 存

????????int i = low;

????????int j = high;

????????// key

????????int key = arr[i];

????????// 3.完成一趟排序

????????while (i < j) {

????????????// 從右往左找到第一個(gè)小于key的數(shù)

????????????while (i < j && arr[j] > key) {

????????????????j--;

????????????}

????????????// 從左往右找第一個(gè)大于key的數(shù)

????????????while (i < j && arr[i] <= key) {

????????????????i++;

????????????}

????????????// 交換

????????????if (i < j) {

????????????????int temp = arr[i];

????????????????arr[i] = arr[j];

????????????????arr[j] = temp;

????????????}

????????}

????????// 當(dāng)i==j時(shí)砂客,調(diào)整key的位置

????????int p = arr[i];

????????arr[i] = arr[low];

????????arr[low] = p;

????????// 對key左邊的數(shù)快排

????????quickSort(arr, low, i - 1);

????????// 對key右邊的數(shù)快排

????????quickSort(arr, i + 1, high);

????}

http://developer.51cto.com/art/201403/430986.htm

7.數(shù)組拷貝

???????(1) int[] arr = {10,12,13,14,15};

???????int[] brr = arr.clone();??//clone()

???????(2)System.arraycopy(要拷貝的原始數(shù)組arr,原始數(shù)組中元素的起始下標(biāo)從0開始srcfrom泥张,目標(biāo)數(shù)組brr,目標(biāo)數(shù)組中起始位置destfrom,要拷貝的元素個(gè)數(shù)num)?

?????*?需要滿足的條件:

?????*?srcfrom>=0

?????*?destfrom>=0

?????*?srcfrom +num <= arr.length

?????*?destfrom+num<=brr.length

???????(3)copyOf(int[] original, int newLength)?

??????*?copyOf(要拷貝的原始數(shù)組鞠值,要拷貝的元素個(gè)數(shù)num)


???????(4)copyOfRange(要拷貝的原始數(shù)組媚创,拷貝的起始索引從0開始from ,結(jié)束索引to)

??????*?拷貝的索引范圍:[from, to) 左閉右開 ,拷貝的元素個(gè)數(shù) to-from


8 .??字符串轉(zhuǎn)數(shù)組

(1)使用Java split() 方法

????split() 方法根據(jù)匹配給定的正則表達(dá)式來拆分字符串彤恶。

????注意: . 钞钙、 | 和 * 等轉(zhuǎn)義字符鳄橘,必須得加 \\。多個(gè)分隔符芒炼,可以用 | 作為連字符瘫怜。????

????String str = "0,1,2,3,4,5";

????String[] arr = str.split(","); // 用,分割

????System.out.println(Arrays.toString(arr));


` int a=Integer.parseInt(arr[]) String類型轉(zhuǎn)int型`

9。數(shù)組轉(zhuǎn)字符串

?????String str2 = ArrayUtils.toString(arr, ","); // 數(shù)組轉(zhuǎn)字符串(逗號分隔,首尾加大括號)


????String str4 = StringUtils.join(arr, ","); //StringUtils的join方法

10.charAt(2) 取出指定位置的字符

lastIndexOf()最后一個(gè)索引的位置

endWith() /startsWith("aa")判斷是否以aa開頭本刽,返回布爾值

trim() 去掉兩邊空格

11鲸湃。 int---》String??Int型轉(zhuǎn)字符串型

????String s1 = String.valueOf(num);

String---》 int???字符串型轉(zhuǎn)int型

????int num2 = Integer.parseInt(s2);

????double num3 =Double.parseDouble(s2);

12 . 截取字符串


//取出10??subString(from,to)??[from,to) 左閉右開

???????String num1Str = s.substring(s.indexOf("從")+1, s.indexOf("數(shù)到"));

???????String num1Str = s.substring(s.indexOf("從")+1, s.indexOf("數(shù)到"));

13.//靜態(tài)變量??,可以類名.屬性名 ,也可以對象名.屬性名

//非static變量/普通變量??,只能通過對象名.屬性名來訪問

//靜態(tài)方法ceshi4(),只能調(diào)用靜態(tài)方法ceshi1(),不能調(diào)用普通方法ceshi2();

14.//1個(gè)類:靜態(tài)成員變量子寓,實(shí)例成員變量(普通的成員變量)暗挑,靜態(tài)代碼塊,普通代碼塊 斜友,構(gòu)造

//執(zhí)行順序: 靜態(tài)成員----》靜態(tài)代碼塊 ----》實(shí)例成員----》普通代碼塊----》構(gòu)造

/

//1.父類的靜態(tài)成員

//???父類的靜態(tài)代碼塊

// 2.子類的靜態(tài)成員

// 子類的靜態(tài)代碼塊

// 3.父類的實(shí)例成員

//???父類的普通代碼塊(非static代碼塊)

//4.父類的構(gòu)造Father()

// 5.子類的實(shí)例成員

//???子類的普通代碼塊(非static代碼塊)

// 6.子類的構(gòu)造Son()

15.this() :表示調(diào)用本類的無參構(gòu)造

?*?this(屬性名):表示調(diào)用本類的帶參構(gòu)造??,this(屬性1炸裆,屬性2....) 可以構(gòu)造的調(diào)用,需要放到第1句

16.基本數(shù)據(jù)類型---》包裝類

//直接裝箱??int類型的變量蝙寨,直接賦值給Integer類型的變量 num2

????????Integer num2 = num1;

????//int--->Integer

????int num1=10;

????Integer num2 = new Integer(num1);

????Integer num7 = Integer.valueOf(num1);

????//String--->Integer

????????String s="10";?

????????Integer num3 = new Integer(s);????

????????Integer num8 = Integer.valueOf(s);

17.包裝類----》基本數(shù)據(jù)類型

//直接拆箱???Integer類型變量num2,直接賦值給int類型的變量num3

????int num3 = num2;

?????//Integer---》int

?????Integer num1 = new Integer(10);

?????int num2 = num1.intValue();

????//String--->int

????????String s="123";

????????int num5=Integer.parseInt(s);

**封裝**(降低耦合

將類的信息隱藏在類的內(nèi)部晒衩,對外提供公有的方法,實(shí)現(xiàn)對該成員屬性的存取操作

封裝的好處:隱藏類的實(shí)現(xiàn)細(xì)節(jié)墙歪,讓使用者使用提供的方法來訪問數(shù)據(jù)听系,可以方便的加入存取操作,限制不合理的操作

**繼承**

一個(gè)類可以由其他類派生虹菲,子類繼承父類特征和方法靠胜。

只支持單繼承

子類可以繼承父類Public和protected修飾的屬性和方法

在同一個(gè)包中可以繼承除private以外的所有修飾的屬性和方法

子類無法繼承父類的構(gòu)造方法

子類不能拋出 比父類更多的異常

父類的靜態(tài)方法不能被子類覆蓋為非靜態(tài)方法,同樣父類的非靜態(tài)方法不能被子類覆蓋為靜態(tài)方法

**繼承下構(gòu)造方法的執(zhí)行過程**

注意:加載順序:啟動(dòng)類(java虛擬機(jī)啟動(dòng)時(shí)毕源,被標(biāo)明為啟動(dòng)類的類)的static block 最先加載(父類靜態(tài)成員浪漠,靜態(tài)代碼塊----子類靜態(tài)成員,靜態(tài)代碼塊---父類實(shí)例成員霎褐,代碼塊-----父類構(gòu)造函數(shù)------子類實(shí)例成員址愿,代碼塊---子類構(gòu)造函數(shù))

*重寫*

方法名相同 參數(shù)列表相同 返回值類型相同或是其子類 不能縮小被重寫方法的訪問權(quán)限

**final關(guān)鍵字**

final 修飾成員變量,則成為實(shí)例常量

final修飾類冻璃,類不能被繼承

final修飾成員方法响谓,則該方法不能被子類重寫。

**super關(guān)鍵字**

在子類構(gòu)造方法中調(diào)用且必須為第一句(調(diào)用父類的帶參構(gòu)造方法)super(屬性1省艳,屬性2..)

使用super關(guān)鍵字 直接調(diào)用父類的方法

**多態(tài)**

同一引用類型娘纷,使用不同的實(shí)例而執(zhí)行不同的操作。

舉例說明多態(tài):動(dòng)物類父類??有“叫”的這樣一個(gè)動(dòng)作跋炕,??繼承它的都是普通類貓 狗等??每個(gè)子類叫的方法實(shí)現(xiàn)都不一樣??赖晶,現(xiàn)在要實(shí)現(xiàn)各種動(dòng)物的叫聲??,如何動(dòng)態(tài)實(shí)現(xiàn)??寫一個(gè)方法把父類做形參傳進(jìn)去

????主人類始終要修改辐烂,只要新增寵物子類遏插,主人類就需要添加具體動(dòng)物看病的方式捂贿,子類寫不盡的,Host類始終需要修改胳嘲,不合理?

?????*??解決辦法:多態(tài)來來解決

?????*??1.創(chuàng)建Cat子類眷蜓,extends Pet父類,Cat類中是Cat特有的屬性

?????*??2. Host類胎围,不需要修改的吁系,只提供一個(gè)空方法,帶寵物看病

?????*?public void cure(Pet pet){

?????*???????pet.toHospital();

?????*?}

?????*??3.父類Pet中白魂,提供1個(gè)空方法 汽纤,public??void toHospital(){}

?????*??4.每個(gè)子類,看病的方式不同福荸,就把各自子類看病的方式蕴坪,放到各自的子類中去完成

?????*???每個(gè)子類,去重寫父類的toHospital()方法

?????*???

?????*??5.調(diào)用的時(shí)候敬锐,父類引用背传,指向子類對象,執(zhí)行的是各自不同的子類對應(yīng)的操作

**abstract抽象**

抽象方法(只有方法聲明台夺,沒有方法實(shí)現(xiàn))*abstract void fun()径玖;*

抽象類 :包含抽象方法的類是抽象類;

抽象類不能實(shí)例化颤介,可以實(shí)例化子類來實(shí)現(xiàn)父類的方法

??*?子類必須重寫所有抽象方法才能實(shí)例化梳星,否則子類還是一個(gè)抽象類*

抽象類有構(gòu)造方法,可以被本類其他構(gòu)造方法調(diào)用滚朵,如果不是private修飾冤灾,可以被其子類中的構(gòu)造方法調(diào)用。

abstract修飾類和方法辕近,不能修飾屬性和構(gòu)造方法

**接口**

接口中不能定義變量??可以定義常量??自動(dòng)用public static final修飾??全局靜態(tài)常量

接口中所有方法都是抽象方法 自動(dòng)public abstract 修飾

接口不能實(shí)例化 不能有構(gòu)造方法

接口的實(shí)現(xiàn)類必須要實(shí)現(xiàn)接口的全部方法韵吨,除非這個(gè)類是抽象類

一個(gè)接口不能實(shí)現(xiàn)另一個(gè)接口,但可以繼承多個(gè)其他接口

**Date類**

????Date??date=new??Date()移宅;

????System.out.println("date="+date);

3個(gè)子類構(gòu)造

????//java.sql.Date??,默認(rèn)格式“yyyy-MM-dd"

????????Date date = new Date(System.currentTimeMillis());

????????// date=2019-03-25

????//java.sql.Time???归粉,默認(rèn)格式:“HH:mm:ss”

????????Time date2 = new Time(System.currentTimeMillis());

????????//date2=11:53:09?

????//java.sql.Timestamp??默認(rèn)格式“ yyyy-MM-dd HH:mm:ss.SSS" 精確到毫秒

????????//1s = 1000ms ,毫秒的范圍[000,999]

????????Timestamp date3 = new Timestamp(System.currentTimeMillis());

????????//date3=2019-03-25 11:54:20.097

DateFormat:日期格式化類吞杭。抽象類無法使用

SimpleDateFormat是其子類可以使用

(1 格式化java.util.Date對象??盏浇,讓其按指定的格式來顯式

?????將Date對象 ----format()方法-----》字符串String 來顯式

(2 public static String getStrFromDate(Date date,String pattern){

????DateFormat df = new SimpleDateFormat("yyyy-MM-dd");

????Date date = new Date();????

????String result = df.format(date);

????System.out.println("date="+date+",格式化后="+DateUtil.getStrFromDate(date, "yyyy-MM-dd"));


**Calendar類**

Calendar:抽象類变丧,不能直接實(shí)例化 芽狗,可以使用其子類 GregorianCalendar

????Calendar cal = new GregorianCalendar();

獲取時(shí)間

????Calendar cal = Calendar.getInstance();

設(shè)置時(shí)間

Calendar cal = Calendar.getInstance();

????// 如果想設(shè)置為某個(gè)日期,可以一次設(shè)置年月日時(shí)分秒痒蓬,由于月份下標(biāo)從0開始賦值月份要-1

????// cal.set(year, month, date, hourOfDay, minute, second);

???????cal.set(2018, 1, 15, 23, 59, 59);

**異常**

*??error與exceptionde 區(qū)別*

error表示不可處理的異常??通常為內(nèi)存溢出??jvm崩潰等童擎。

exception表示需要捕捉或者處理的異常

*??throw和throws的區(qū)別*

throw在程序中拋出異常滴劲,出現(xiàn)在方法體內(nèi),如果執(zhí)行則一定拋出某種異常對象顾复,且只能拋出一個(gè)班挖。

throws表示拋出異常的聲明,出現(xiàn)在方法頭芯砸,聲明拋出異常的一種可能性萧芙,throws后面可以跟多個(gè)異常類。

*?try catch finally*

try塊必須???catch??finally必須出現(xiàn)一個(gè)

finally一定會執(zhí)行假丧,除非System.exit(n)

try塊中有return語句双揪,finally語句也會執(zhí)行,執(zhí)行return語句會記下返回值包帚,待finally執(zhí)行結(jié)束后渔期,再向調(diào)用者返回其值。

*常見的5種RunTimeException*

NullPointerException渴邦,空指針異常疯趟。

NumberFormatException,數(shù)據(jù)格式轉(zhuǎn)換錯(cuò)誤谋梭。

ClassCastException信峻,強(qiáng)制類型轉(zhuǎn)換異常。

IndexOutOfBoundsException,越界異常瓮床。

ArithmeticException 算術(shù)異常站欺。

除RuntimeException及其子類其他所有的異常都是檢查型異常(可查異常)

運(yùn)行時(shí)異常的特點(diǎn)是Java編譯器不會檢查它,也就是說纤垂,當(dāng)程序中可能出現(xiàn)這類異常矾策,即使沒有用try-catch語句捕獲它,也沒有用throws子句聲明拋出它峭沦,也會編譯通過贾虽。

使用自定義異常的步驟:



1.定義異常類(繼承 Throwable 類,Exception類 RuntimeException)吼鱼。

2.編寫構(gòu)造方法蓬豁,繼承父類的實(shí)現(xiàn)。

3.實(shí)例化自定義異常對象菇肃。

4.使用throw 拋出地粪。

**String、StringBuffer與StringBuilder之間的區(qū)別**

1.String含義為引用數(shù)據(jù)類型,是字符串常量.是不可變的對象,(顯然線程安全)在每次對string類型進(jìn)行改變的時(shí)候其實(shí)都等同與生成了一個(gè)新的String對象.然后指針指向新的String對象,所以經(jīng)常改變內(nèi)容的字符串最好不使用String,因?yàn)槊看紊蓪ο蠖紩ο到y(tǒng)性能產(chǎn)生影響,特別當(dāng)內(nèi)存中無引用對象多了之后.JVM的垃圾回收(GC)就會開始工作,對系統(tǒng)的性能會產(chǎn)生影響

2.StringBuffer ?線程安全的可變字符序列:對StringBuffer對象本身進(jìn)行操作,而不是生成新的對象.所所以在改變對象引用條件下,一般推薦使用StringBuffer.同時(shí)主要是使用append和insert方法,

3.StringBuilder?線程不安全的可變字符序列.提供一個(gè)與StringBuffer兼容的API,但不同步.設(shè)計(jì)作為StringBuffer的一個(gè)簡易替換,用在字符緩沖區(qū)被單個(gè)線程使用的時(shí)候.效率比StringBuffer更快

區(qū)別:

a.執(zhí)行速度:StringBuilder > StringBuffer > String

b.線程安全:StringBuffer線程安全.StringBuilder線程不安全

c.String適用與少量字符串操作

StringBuilder適用單線程下在字符緩沖區(qū)下進(jìn)行大量操作的情況

StringBuffer使用多線程下在字符緩沖區(qū)進(jìn)行大量操作的情況

**集合**

????Collection 接口存儲一組不唯一琐谤,無序的對象蚪腐。

????List接口存儲一組不唯一惰蜜,有序憔鬼,可重復(fù)的對象喉磁。ArrayList、LinkedList和Vector(淘汰)是主要的實(shí)現(xiàn)類

????Set接口存儲唯一,無序的對象。HashSet和TreeSet是主要的實(shí)現(xiàn)類。

????Map接口存儲一組鍵—值對象砰粹,提供Key—Value的映射。其中key列就是一個(gè)集合造挽,key不能重復(fù)碱璃,但是value可以重復(fù)。 HashMap饭入、TreeMap和Hashtable是Map的主要實(shí)現(xiàn)類厘贼。

**Vector擴(kuò)容機(jī)制**

vector 默認(rèn)的擴(kuò)容機(jī)制是按照容器現(xiàn)有容量的一倍進(jìn)行增長。由于 Vector 容器分配的是一塊連續(xù)的內(nèi)存空間, 每次容器的增長并不是在原有連續(xù)的內(nèi)容空間后進(jìn)行簡單的疊加, 而是重新申請一塊更大的新內(nèi)存, 并把現(xiàn)有容器中的元素逐個(gè)復(fù)制過去, 然后銷毀原有內(nèi)存圣拄。

舉例:vector 初始化時(shí)申請的空間大小為 6 , 存入了 6 個(gè)元素, 當(dāng)向 vector 中插入第 7 個(gè)元素“ 6” 時(shí), vector 會利用自己的擴(kuò)容機(jī)制重新申請空間, 數(shù)據(jù)存放結(jié)構(gòu)如圖 1 所示(_First 指向使用空間的頭部,_Last 指向使用空間大小(size)的尾部,_End 指向使用空間容量(capacity)的尾部)嘴秸。

![](https://i.imgur.com/oHemGds.png)

**ArrayList底層實(shí)現(xiàn)原理**

ArrayList的底層數(shù)據(jù)結(jié)構(gòu)就是一個(gè)數(shù)組,數(shù)組元素的類型為Object類型庇谆,對ArrayList的所有操作底層都是基于數(shù)組的

ArrayList繼承AbstractList抽象父類岳掐,實(shí)現(xiàn)了List接口(規(guī)定了List的操作規(guī)范)、RandomAccess(可隨機(jī)訪問)饭耳、Cloneable(可拷貝)串述、Serializable(可序列化)。

ArrayList是List接口的可變數(shù)組非同步實(shí)現(xiàn)寞肖,并允許包括null在內(nèi)的所有元素纲酗。

底層使用數(shù)組實(shí)現(xiàn)

該集合是可變長度數(shù)組,數(shù)組擴(kuò)容時(shí)新蟆,會將老數(shù)組中的元素重新拷貝一份到新的數(shù)組中觅赊,每次數(shù)組容量增長大約是其容量的1.5倍,這種操作的代價(jià)很高琼稻。

采用了Fail-Fast機(jī)制吮螺,面對并發(fā)的修改時(shí),迭代器很快就會完全失敗帕翻,而不是冒著在將來某個(gè)不確定時(shí)間發(fā)生任意不確定行為的風(fēng)險(xiǎn)

remove方法會讓下標(biāo)到數(shù)組末尾的元素向前移動(dòng)一個(gè)單位鸠补,并把最后一位的值置空,方便GC

(補(bǔ)充)

**LinkedList底層實(shí)現(xiàn)原理**

LinkedList是List接口的雙向鏈表非同步實(shí)現(xiàn)嘀掸,并允許包括null在內(nèi)的所有元素紫岩。

底層的數(shù)據(jù)結(jié)構(gòu)是基于雙向鏈表的,該數(shù)據(jù)結(jié)構(gòu)我們稱為節(jié)點(diǎn)

雙向鏈表節(jié)點(diǎn)對應(yīng)的類Node的實(shí)例睬塌,Node中包含成員變量:prev泉蝌,next歇万,item。其中梨与,prev是該節(jié)點(diǎn)的上一個(gè)節(jié)點(diǎn),next是該節(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn)文狱,item是該節(jié)點(diǎn)所包含的值粥鞋。

它的查找是分兩半查找,先判斷index是在鏈表的哪一半瞄崇,然后再去對應(yīng)區(qū)域查找呻粹,這樣最多只要遍歷鏈表的一半節(jié)點(diǎn)即可找到

**HashMap底層實(shí)現(xiàn)原理(jdk1.8)**

從結(jié)構(gòu)上講,hashmap是位桶(Node數(shù)組)+鏈表+紅黑樹實(shí)現(xiàn)的苏研,鏈表是為了解決hash沖突的等浊,當(dāng)鏈表長度超過閾值(8)時(shí),將鏈表轉(zhuǎn)換為紅黑樹摹蘑,大大減少查找時(shí)間筹燕。

主干是Node數(shù)組,包含一個(gè)鍵值對衅鹿,實(shí)現(xiàn)了Map.entry接口撒踪,它的初始容量為16, 當(dāng)鏈表數(shù)組的容量超過初始容量的0.75時(shí)大渤,再散列將鏈表數(shù)組擴(kuò)大2倍制妄,把原鏈表數(shù)組的搬移到新的數(shù)組中

*如何getValue*

get方法時(shí)獲取key的Hash值,通過計(jì)算hash&(n-1)得到在鏈表數(shù)組中的位置泵三,判斷計(jì)算的key與參數(shù)key是否相等耕捞,不等集遍歷后面的鏈表找到相同的key值返回對應(yīng)的Value值即可。

*如何put<K烫幕,V>*

判斷鍵值對數(shù)組tab[]是否為空或?yàn)閚ull俺抽,否則以默認(rèn)大小resize();

根據(jù)鍵值key計(jì)算hash值得到插入的數(shù)組索引i较曼,如果tab[i]==null凌埂,直接新建節(jié)點(diǎn)添加

判斷當(dāng)前數(shù)組中處理hash沖突的方式為鏈表還是紅黑樹(check第一個(gè)節(jié)點(diǎn)類型即可),分別處理

*HasMap的擴(kuò)容機(jī)制resize();*

構(gòu)造hash表時(shí),如果不指明初始大小诗芜,默認(rèn)大小為16(即Node數(shù)組大小16)瞳抓,如果Node[]數(shù)組中的元素達(dá)到(填充比*Node.length)重新調(diào)整HashMap大小 變?yōu)樵瓉?倍大小,擴(kuò)容很耗時(shí)

**Hashtable實(shí)現(xiàn)原理**

不允許出現(xiàn)null值null鍵,線程同步伏恐,et/put所有相關(guān)操作都是synchronized的孩哑,這相當(dāng)于給整個(gè)哈希表加了一把大鎖,多線程訪問時(shí)候翠桦,只要有一個(gè)線程訪問或操作該對象横蜒,那其他線程只能阻塞胳蛮,相當(dāng)于將所有的操作串行化。??????線程安全丛晌。

**ConcurrentHashMap實(shí)現(xiàn)原理**

ConcurrentHashMap是Java并發(fā)包中提供的一個(gè)線程安全且高效的HashMap實(shí)現(xiàn)仅炊。

ConcurrentHashMap采用了非常精妙的"分段鎖"策略,ConcurrentHashMap的主干是個(gè)Segment數(shù)組澎蛛。

?????final Segment<K,V>[] segments;

ConcurrentHashMap完全允許多個(gè)讀操作并發(fā)進(jìn)行抚垄,讀操作并不需要加鎖。如果使用傳統(tǒng)的技術(shù)谋逻,如HashMap中的實(shí)現(xiàn)呆馁,如果允許可以在hash鏈的中間添加或刪除元素,讀操作不加鎖將得到不一致的數(shù)據(jù)毁兆。ConcurrentHashMap實(shí)現(xiàn)技術(shù)是保證HashEntry幾乎是不可變的浙滤。HashEntry代表每個(gè)hash鏈中的一個(gè)節(jié)點(diǎn),其結(jié)構(gòu)如下所示

?????tatic final class HashEntry<K,V> {??

?????final K key;??

?????final int hash;??

?????volatile V value;??

?????final HashEntry<K,V> next;??

????}?

可以看到除了value不是final的气堕,其它值都是final的纺腊,這意味著不能從hash鏈的中間或尾部添加或刪除節(jié)點(diǎn),因?yàn)檫@需要修改next 引用值茎芭,所有的節(jié)點(diǎn)的修改只能從頭部開始摹菠。對于put操作,可以一律添加到Hash鏈的頭部骗爆。但是對于remove操作次氨,可能需要從中間刪除一個(gè)節(jié)點(diǎn),這就需要將要?jiǎng)h除節(jié)點(diǎn)的前面所有節(jié)點(diǎn)整個(gè)復(fù)制一遍摘投,最后一個(gè)節(jié)點(diǎn)指向要?jiǎng)h除結(jié)點(diǎn)的下一個(gè)結(jié)點(diǎn)煮寡。這在講解刪除操作時(shí)還會詳述。為了確保讀操作能夠看到最新的值犀呼,將value設(shè)置成volatile幸撕,這避免了加鎖。

**IO操作**

*?1.刪除文件及其下面的子目錄外臂,子文件坐儿,不包括最外層的父文件夾

????????public static void delAllFileExceptOuter(File dir){

????????????if(dir.exists() && dir.isDirectory()){

????????????????//獲取子文件列表

????????????????File[] arr = dir.listFiles();

????????????????//遍歷

????????????????for(File f:arr){

????????????????????//遞歸調(diào)用自身方法,繼續(xù)內(nèi)層的刪除

????????????????????delAllFileExceptOuter(f);

????????????????????f.delete();

????????????????}

????????????}

????????}


*?2.刪除文件及其下面的子目錄宋光,子文件貌矿,包括最外層的父文件夾

*?

???????????public static void delAllFileIncludeOuter(File dir){

????????????if(dir.exists() && dir.isDirectory()){

????????????????//獲取子文件列表

????????????????File[] arr = dir.listFiles();

????????????????//遍歷

????????????????for(File f:arr){

????????????????????//遞歸調(diào)用自身方法,繼續(xù)內(nèi)層的刪除

????????????????????delAllFileIncludeOuter(f);

????????????????????f.delete();

????????????????}

????????????????dir.delete();

????????????}

????????}


*?3.拷貝所有的子文件夾罪佳,不拷貝子文件

????????public static void copyAllDir(File src,File dest){

????????????if(src.isDirectory()){

????????????????if(!dest.exists()){

????????????????????dest.mkdirs();

????????????????}


????????????????//獲取src的子文件列表?

????????????????File[] arr = src.listFiles();

????????????????//遍歷

????????????????for(File f:arr){

????????????????????//構(gòu)建新的子文件對象??subSrc=new File("E:/others/", c);

????????????????????// subDest = new File("D:/others", c);

????????????????????File subSrc = new File(src,f.getName());

????????????????????File subDest = new File(dest,f.getName());

????????????????????System.out.println("###subSrc="+subSrc+",subDest="+subDest);

????????????????????//遞歸調(diào)用自身方法

????????????????????copyAllDir(subSrc, subDest);

????????????????}

????????????}


????????}

*?4.拷貝單個(gè)子文件


????????public static void copySingleFile(File src,File dest){

????????????if(src.isDirectory()){

????????????????System.out.println("只能拷貝文件逛漫!");

????????????????return;

????????????}


????????//

????????if(dest.isDirectory()){

????????????System.out.println("要拷貝的文件和父目錄中的文件夾重名,不能拷貝赘艳!");

????????????return;

????????}


????????//聲明輸入流對象酌毡,輸出流對象

????????FileInputStream fis=??null;

????????FileOutputStream fos = null;


????????try {

????????????//建立輸入流和源文件之間的聯(lián)系?

????????????fis = new FileInputStream(src);

????????????//建立輸出流和目標(biāo)文件之間的聯(lián)系

????????????fos = new FileOutputStream(dest);


????????????//聲明byte[]數(shù)組克握,用來存儲讀取的內(nèi)容??,數(shù)組的容量 n:整數(shù)值,任意定枷踏,項(xiàng)目中一般用1024

????????????byte[] buffer = new byte[3];?

????????????//聲明int變量菩暗,用來存儲read()方法的返回值,實(shí)際上存儲就是實(shí)際讀取到的字節(jié)個(gè)數(shù)?

????????????int len=fis.read(buffer);


????????????while(len!=-1){

????????????????//讀取的內(nèi)容報(bào)錯(cuò)在byte數(shù)組中??旭蠕,需要轉(zhuǎn)換成String停团,才能打印輸出

//????????????String data = new String(buffer,0,len);

//????????????????System.out.println("len="+len+"data="+data);


????????????????//讀多少,寫多少出去

????????????????fos.write(buffer, 0, len);

????????????????//刷新

????????????????fos.flush();

????????????????//接著讀

????????????????len=fis.read(buffer);

????????????}


????????} catch (FileNotFoundException e) {

????????????e.printStackTrace();

????????} catch (IOException e) {

????????????e.printStackTrace();

????????} finally{

????????????//釋放資源 下梢、關(guān)閉流?

????????????//先打開的后關(guān)閉客蹋,先創(chuàng)建的后關(guān)閉

????????????if(null!=fos){

????????????????try {

????????????????????fos.close();

????????????????} catch (IOException e) {

????????????????????e.printStackTrace();

????????????????}

????????????}


????????????if(null!=fis){

????????????????try {

????????????????????fis.close();

????????????????} catch (IOException e) {

????????????????????e.printStackTrace();

????????????????}

????????????}

????????}


????}

*?5.拷貝所有的子文件塞蹭,子目錄

????????public static void copyAllFiles(File src,File dest){

????????if(src.getParent()==null && dest.getParent()==null){

????????????//證明相對路徑下孽江,同級之間的拷貝,允許通過

????????}else if((src.getParent()==null && dest.getParent()!=null) && (dest.getAbsolutePath().contains(src.getAbsolutePath()))){

????????????System.out.println("***父目錄不能拷貝到子目錄中番电!");

????????????return;

????????}else if(dest.getAbsolutePath().contains(src.getAbsolutePath()) &&??!src.getParent().equals(dest.getParent())){

????????????//src的parent()和dest的parent()不同

????????????System.out.println("父目錄不能拷貝到子目錄中岗屏!");

????????????return;

????????}


????????if(src.isDirectory()){//如果是目錄,拷貝對應(yīng)的目錄

????????????if(!dest.exists()){

????????????????dest.mkdirs();

????????????}


????????????//獲取src的子文件列表?

????????????File[] arr = src.listFiles();

????????????//遍歷

????????????for(File f:arr){

????????????????//構(gòu)建新的子文件對象?

????????????????File subDest = new File(dest,f.getName());

????????????????//遞歸調(diào)用自身方法

????????????????copyAllFiles(f, subDest);

????????????}

????????}else if(src.isFile()){ //如果是文件漱办,拷貝文件

????????????copySingleFile(src, dest);

????????}

????}


**IO流**

????????* 面試題: 字符串和字節(jié)數(shù)組这刷,字符串和字符數(shù)組之間的相互轉(zhuǎn)換??

?????????*??String??s---->byte[]??buffer?

?????????*??String s="asd";

?????????*??byte[] buffer=new byte[1024];

?????????*???buffer = s.getBytes();??

?????????*??

?????????*???byte[] buffer ---->String s??

?????????*s = new String(buffer);?

?????????*s = new String(buffer,int from, int len);??

?????????*from:buffer數(shù)組的起始索引?

?????????*len:要轉(zhuǎn)換的字節(jié)數(shù) (有幾個(gè)字節(jié))

?????????*

?????????*??

?????????*??String s ---->char[] buffer?

?????????*buffer = s.toCharArray();

?????????*

?????????*???char[] buffer----->String s??

?????????*??s = new String(buffer);??

?????????*??

?????????*??s= new String(buffer,int from,int len);?

?????????*??from:buffer字符數(shù)組的起始索引

?????????*??len:要轉(zhuǎn)換的字符個(gè)數(shù) (與幾個(gè)字符)

**IO流文件流FileInputStream/FileOutstream**

???????聲明輸入輸入流輸出流對象


??????FileInputStream fis=null娩井;

??????FileOutputStream fos=null暇屋;


??????建立輸入流,輸出流與源文件的聯(lián)系


??????fis=new FileInputStream(" ");

??????fos=new FileOutputStream(" ");


???????聲明byte[]字節(jié)數(shù)組洞辣,用于存儲讀取的內(nèi)容

???????byte[] buffer=new byte[1024];

???????int len=0咐刨;

???????while((len=fis.read(buffer))!=-1){

???????String data=new String(buffer,0,len);

???????syso(data);

???????len=fis.read(buffer,0,buffer.length);


????????fos.write(buffer,0,len);

????????fos.flush();


???????}

拷貝

???????????//聲明輸入流對象,輸出流對象

????????FileReader fr = null;

????????FileWriter fw = null;


????????try {

????????????//建立輸入流和源文件之間的聯(lián)系

????????????fr = new FileReader("E:/others/ceshi.txt");

????????????//建立輸出流和目標(biāo)文件之間的聯(lián)系

????????????fw = new FileWriter("D:/test/ceshi.txt");


????????????char[] buffer = new char[4];

????????????//len實(shí)際讀取的字符數(shù)

????????????int len=0;

????????????while((len=fr.read(buffer))!=-1){

?????????//????fw.write(buffer, 0, len);

????????????????//拷貝的時(shí)候扬霜,一定要帶上偏移量

????????????????String s = new String(buffer,0,len);

????????????????fw.write(s);

????????????????fw.flush();

????????????}

**緩沖流BufferInputStream/BufferOuputStream/BUfferReader/bufferWriter**


?????//聲明輸入流對象定鸟,輸出流對象

????????BufferedReader br = null;

????????BufferedWriter bw = null;



????????try {

????????????//建立輸入流和源文件之間的聯(lián)系

????????????br = new BufferedReader(new FileReader("E:/others/ceshi.txt"));

????????????//建立輸出流和目標(biāo)文件之間的聯(lián)系

????????????bw = new BufferedWriter(new FileWriter("D:/test/ceshi.txt"));


????????????//聲明String變量,用于存儲讀取的內(nèi)容?

????????????String data = null;

????????????while((data=br.readLine())!=null){

????????????????bw.write(data);

????????????????//刷新

????????????????bw.flush();

????????????????//寫一行著瓶,換一行

????????????????bw.newLine();

????????????}

????????}

復(fù)制圖片

????//聲明輸入流联予,輸出流對象

????????BufferedInputStream bis = null;

????????BufferedOutputStream bos = null;


????????try {

????????????//建立輸入流和源文件之間的聯(lián)系?

????????????bis = new BufferedInputStream(new FileInputStream(new File("E:/others/cat.png")));

????????????//建立輸出流和目標(biāo)文之間的聯(lián)系

????????????bos = new BufferedOutputStream(new FileOutputStream(new File("D:/test/cat.png")));

????????????//聲明byte[]數(shù)組

????????????byte[] buffer = new byte[1024];

????????????//聲明int變量

????????????int len=0;

????????????while((len=bis.read(buffer))!=-1){

????????????????String s = new String(buffer,0,len);

????????????????System.out.println("len="+len+",s="+s);

????????????????bos.write(buffer, 0, len);

????????????????bos.flush();

????????????}


**亂碼原因**

?*?1.兩邊的編碼方式不一致

?*?2.保存的不完整,數(shù)據(jù)有丟失

?*?InputStreamReader,提供構(gòu)造材原,可以傳入編碼方式

?*?InputStreamReader(InputStream in, String charsetName)

??????????創(chuàng)建使用指定字符集的 InputStreamReader沸久。

?*?ANSI ----->程序中g(shù)bk

?*?

?*?UTF-8----->程序中UTF-8

?*?

?*?亂碼因?yàn)椋篶eshi.txt ANSI??,本地程序中UTF-8,不一致導(dǎo)致的。

?*?

?*????解決辦法1:ceshi.txt 右擊 另存為 UTF-8

?*????

?*????解決辦法2:用InputStreamReader流

????//聲明輸入流對象

????????InputStreamReader isr = null;


????????try {

????????????//建立輸入流和源文件之間的聯(lián)系

????????????isr = new InputStreamReader(new FileInputStream("E:/others/ceshi.txt"),"gbk");

????????????//聲明char[]數(shù)組余蟹,用于存儲讀取的內(nèi)容

????????????char[] buffer = new char[4];

????????????//聲明int變量麦向,用來存儲實(shí)際讀取的字符數(shù)

????????????int len = 0;

????????????while(-1 !=(len=isr.read(buffer))){

????????????????String s = new String(buffer,0,len);

????????????????System.out.println(s);

????????????}

** FileInputStream與FileReader區(qū)別**:

FileInputStream是字節(jié)流,F(xiàn)ileReader是字符流客叉,用字節(jié)流讀取中文的時(shí)候诵竭,可能會出現(xiàn)亂碼话告,而用字符流則不會出現(xiàn)亂碼,而且用字符流讀取的速度比字節(jié)流要快卵慰;

**FileInputStream與BufferedInputStream區(qū)別**

FileInputStream是字節(jié)流沙郭,BufferedInputStream是字節(jié)緩沖流,使用BufferedInputStream讀資源比FileInputStream讀取資源的效率高(BufferedInputStream的read方法會讀取盡可能多的字節(jié)裳朋,執(zhí)行read時(shí)先從緩沖區(qū)讀取病线,當(dāng)緩沖區(qū)數(shù)據(jù)讀完時(shí)再把緩沖區(qū)填滿。)鲤嫡,因此送挑,當(dāng)每次讀取的數(shù)據(jù)量很小時(shí),F(xiàn)ileInputStream每次都是從硬盤讀入暖眼,而BufferedInputStream大部分是從緩沖區(qū)讀入惕耕。讀取內(nèi)存速度比讀取硬盤速度快得多,因此BufferedInputStream效率高诫肠,且FileInputStream對象的read方法會出現(xiàn)阻塞司澎;BufferedInputStream的默認(rèn)緩沖區(qū)大小是8192字節(jié)。當(dāng)每次讀取數(shù)據(jù)量接近或遠(yuǎn)超這個(gè)值時(shí)栋豫,兩者效率就沒有明顯差別了挤安。

**ObjectOutputStream/ObjectInputStream**

java.io.ObjectOutputStream代表對象輸出流,它的writeObject(Object obj)方法可對參數(shù)指定的obj對象進(jìn)行序列化丧鸯,把得到的字節(jié)序列寫到一個(gè)目標(biāo)輸出流中蛤铜。

java.io.ObjectInputStream代表對象輸入流,它的readObject()方法從一個(gè)源輸入流中讀取字節(jié)序列丛肢,再把它們反序列化為一個(gè)對象围肥,并將其返回。

**序列化**

只有實(shí)現(xiàn)了Serializable(si瑞爾奈zi包)和Externalizable接口的類的對象才能被序列化摔踱。

transient修飾屬性避免序列化

序列化是指將對象轉(zhuǎn)換成字節(jié)序列的過程稱為對象的序列化虐先,反序列化則是將字節(jié)序列恢復(fù)為對象的過程

對象的序列化通常有兩種用途

1、把對象的字節(jié)序列永久的保存到硬盤上派敷,通常存放到一個(gè)文件中

2蛹批、在網(wǎng)絡(luò)上傳送對象的序列化

*序列化步驟*

1) 創(chuàng)建一個(gè)對象輸出流,它可以包裝一個(gè)其他類型的目標(biāo)輸出流篮愉,如文件輸出流腐芍;

2) 通過對象輸出流的writeObject()方法寫對象。

????//聲明輸出流對象

????????ObjectOutputStream oos = null;

????????try {

????????????//建立輸出流和目標(biāo)文件之間的聯(lián)系??oos需要包裝其他的底層流

????????????oos = new ObjectOutputStream(new FileOutputStream(filePath));

????????????//調(diào)用write()方法寫出?

????????????List<Student> list=new ArrayList<Student>();

?????????????list.add(new Student("張偉",18));

?????????????list.add(new Student("張偉1",28));

?????????????list.add(new Student("張偉2",38));

????????????//刷新

?????????????oos.writeObject(list);?

????????????oos.flush();

????????}

*反序列化步驟*

1) 創(chuàng)建一個(gè)對象輸入流试躏,它可以包裝一個(gè)其他類型的源輸入流猪勇,如文件輸入流;

2) 通過對象輸入流的readObject()方法讀取對象颠蕴。

對象序列化和反序列范例:

????// 聲明輸入流對象

????????ObjectInputStream ois = null;

????????try {

????????????// 建立輸入流和源文件之間的聯(lián)系 泣刹,ois需要包裝其他的底層流

????????????ois = new ObjectInputStream(new FileInputStream(filepath));

????????????// 通過read()方法讀取

????????????List<Student> list = (List) ois.readObject();

????????????for (Student temp : list) {

????????????????System.out.println("取出的學(xué)生名:" + temp.getName() + ",年齡:" + temp.getAge() + ",性別:" + temp.getSex());

????????????}

????????}

*s?e?r?i?a?l?V?e?r?s?i?o?n?U?I?D?:?*

?字?面?意?思?上?是?序?列?化?的?版?本?號?助析,凡是實(shí)現(xiàn)Serializable接口的類都有一個(gè)表示序列化版本標(biāo)識符的靜態(tài)變量

????private static final long serialVersionUID

*顯式地定義serialVersionUID有兩種用途:*

1、 在某些場合椅您,希望類的不同版本對序列化兼容外冀,因此需要確保類的不同版本具有相同的serialVersionUID;

2掀泳、 在某些場合雪隧,不希望類的不同版本對序列化兼容,因此需要確保類的不同版本具有不同的serialVersionUID员舵。

**RandomAccessFile類**

RandomAccessFile類的主要功能是完成隨機(jī)讀取功能脑沿,可以讀取指定位置的內(nèi)容。

之前的File類只是針對文件本身進(jìn)行操作的马僻,而如果要想對文件內(nèi)容進(jìn)行操作庄拇,則可以使用RandomAccessFile類,此類屬于隨機(jī)讀取類巫玻,可以隨機(jī)讀取一個(gè)文件中指定位置的數(shù)據(jù)丛忆。

???????*?RandomAccessFile:既可以當(dāng)輸出流負(fù)責(zé)寫出祠汇,也可以當(dāng)輸入流負(fù)責(zé)讀取

?????*?體現(xiàn)它隨機(jī)訪問的特點(diǎn)??seek() skipBytes()

?????*?先將3個(gè)用戶信息仍秤,寫入到E:/others/user.txt中

?????*??然后讀取出來

?????*??

?????*??寫入的時(shí)候,構(gòu)造上 可很,mode模式選用:rw,文件不存在诗力,則創(chuàng)建

?????*??

?????*??讀取的時(shí)候??mode:r 只讀

?????*??

?????*??1.2個(gè)方法,一個(gè)方法負(fù)責(zé)寫入

?????*??一個(gè)方法負(fù)責(zé)讀取

?????*?@author Administrator

?????*

?????*/

????public class TestRandomAccess01 {

????????public static void main(String[] args) {

????????????String path = "E:/others/user.txt";

????????????save(path);


????//????????readFirst(path);

????????}


????/**

?????* 順序 我抠,1苇本,2,3?

?????* RandomAccessFile 當(dāng) 輸入流用

?????* @param filePath

?????*/

????public static void readFirst(String filePath){

????????//聲明輸入流對象

????????RandomAccessFile ra= null;

????????try {

????????????//建立輸入流和源文件之間的聯(lián)系

????????????ra = new RandomAccessFile(new File(filePath), "r");

????????????byte[] buffer = new byte[8];

????????????for(int i=0;i<buffer.length;i++){

????????????????buffer[i] = ra.readByte();

????????????}

????????????//讀取整數(shù)值

????????????int age = ra.readInt();

????????????System.out.println("第一個(gè)人信息:"+new String(buffer)+"---"+age);


????????????//讀取第2個(gè)人??

????????????for(int i=0;i<buffer.length;i++){

????????????????buffer[i] = ra.readByte();

????????????}

????????????//讀取整數(shù)值

????????????age = ra.readInt();

????????????System.out.println("第二個(gè)人信息:"+new String(buffer)+"---"+age);




????????????//讀取第3個(gè)人

????????????for(int i=0;i<buffer.length;i++){

????????????????buffer[i] = ra.readByte();

????????????}

????????????//讀取整數(shù)值

????????????age = ra.readInt();

????????????System.out.println("第三個(gè)人信息:"+new String(buffer)+"---"+age);


????????} catch (FileNotFoundException e) {

????????????e.printStackTrace();

????????} catch (IOException e) {

????????????e.printStackTrace();

????????} finally{

????????????if(ra!=null){

????????????????try {

????????????????????ra.close();

????????????????} catch (IOException e) {

????????????????????e.printStackTrace();

????????????????}

????????????}

????????}


????}


????/**

?????* 存儲

?????* RandomAccessFile 當(dāng)輸出流用

?????* @param filePath

?????*/

????public static void save(String filePath){

????????RandomAccessFile ra = null;

????????try {

????????????//建立輸出流和目標(biāo)文件之間的聯(lián)系菜拓,同時(shí)指定模式

????????????ra = new RandomAccessFile(new File(filePath), "rw");


????????????//調(diào)用write()方法寫出?

????????????ra.writeBytes("zhangsan");

????????????ra.writeInt(30);

????????????ra.writeBytes("lisi????");

????????????ra.writeInt(31);

????????????ra.writeBytes("wangwu??");

????????????ra.writeInt(32);


????????} catch (FileNotFoundException e) {

????????????e.printStackTrace();

????????} catch (IOException e) {

????????????e.printStackTrace();

????????} finally{

????????????if(ra!=null){

????????????????try {

????????????????????ra.close();

????????????????} catch (IOException e) {

????????????????????e.printStackTrace();

????????????????}

????????????}

????????}


????}

**線程**

進(jìn)程:運(yùn)行的程序瓣窄,動(dòng)態(tài)。是資源分配的基本單位纳鼎。 一個(gè)進(jìn)程可擁有多個(gè)并行的(concurrent)線程俺夕。

線程:進(jìn)程中一段代碼的執(zhí)行過程。是執(zhí)行和調(diào)度的基本單位贱鄙。是進(jìn)程中執(zhí)行運(yùn)算單位的最小單位劝贸,是進(jìn)程內(nèi)部的一個(gè)執(zhí)行單元。

**實(shí)現(xiàn)多線程兩種方式**

*繼承Thread類*

1.定義子類繼承Thread類

2.子類重寫Thread類run方法

3.創(chuàng)建Thread子類對象逗宁,即創(chuàng)建線程對象

4.調(diào)用線程對象的start()方法映九,啟動(dòng)線程

????public class Rabbit extends Thread {

????private int step = 1;

????// (1)線程類中定義一個(gè)標(biāo)志位

????private boolean isRunning = true;

????public Rabbit() {

????}

????public Rabbit(String name) {

????????super(name); // 調(diào)用父類Thread的帶參構(gòu)造

????}

????@Override

????public void run() {

????????// (2)線程體中使用該標(biāo)志位

????????while (isRunning) {

????????????System.out.println(Thread.currentThread().getName() + "跑了"

????????????????????+ (step++) + "步");

????????}

????}

????// 提供一個(gè)更改此標(biāo)志位的方法

????public void stopThread() {

????????isRunning=false;

????}

????}

????public static void main(String[] args) {

????????//新生狀態(tài)

????????Rabbit ra = new Rabbit();

????????ra.setName("兔子");

????????//就緒狀態(tài)

????????ra.start();

????????System.out.println("A判斷兔子線程的是否處于活動(dòng)狀態(tài):"+ra.isAlive());

????????//延遲2ms?

????????try {

????????????Thread.sleep(2);

????????} catch (InterruptedException e) {

????????????e.printStackTrace();

????????}

????????//終止線程?

????????//ra.stop();??//可以用,但是不建議用瞎颗,已過時(shí)的方法

????????//ra.destroy();//不可以用 件甥,不起作用

????????//(4)外部測試時(shí)候捌议,調(diào)用更改此標(biāo)志位的方法

????????ra.stopThread();

????????try {

????????????Thread.sleep(2);

????????} catch (InterruptedException e) {

????????????e.printStackTrace();

????????}

????????System.out.println("B判斷兔子線程的是否處于活動(dòng)狀態(tài):"+ra.isAlive());

????}

*實(shí)現(xiàn)Runnable接口*

1.定義子類實(shí)現(xiàn)Runnable接口

2.重寫Runnable接口run()方法

3.通過Thread含構(gòu)造器創(chuàng)建線程對象

4.將Runnable接口的子類對象作為實(shí)際參數(shù)傳遞給Thread類的構(gòu)造方法中

5.調(diào)用Thread類的start()方法

優(yōu)點(diǎn):1.避免單繼承

2.方便共享資源,同一份資源引有,多個(gè)代理訪問

**java中終止線程**

*1.使用標(biāo)志位*

*2.中斷策略*

使用標(biāo)志位這種方法有個(gè)很大的局限性禁灼,那就是通過循環(huán)來使每次的操作都需要檢查一下標(biāo)志位。

java還提供了中斷協(xié)作機(jī)制轿曙,能夠使一個(gè)線程要求另外一個(gè)線程停止當(dāng)前工作弄捕。其大致的思想為:調(diào)用線程Thread的interrupt([??nt??r?pt])方法,在線程內(nèi)部通過捕獲InterruptedException異常來決定線程是否繼續(xù)還是退出导帝。如下:

?????class InterruptRunnable implements Runnable{

????????private BlockingQueue queue = new ArrayBlockingQueue(10);

????????@Override

????????public void run() {

????????????int i= 0;

????????????for (;;) {

????????????????try {

????????????????????//線程的操作

????????????????????i++;

????????????????????queue.put(i);

????????????????} catch (InterruptedException e) {

????????????????????//捕獲到了異常 該怎么做

????????????????????System.out.println(queue);

????????????????????e.printStackTrace();

????????????????????return;

????????????????}

????????????}

??????????}

??????上述代碼通過BlockingQueue的put方法來拋出InterruptedException異常守谓。

??????當(dāng)內(nèi)部捕獲到該異常時(shí),從而決定是否繼續(xù)還是直接退出了

??????public void testInterruptRunnable() throws InterruptedException {

????????InterruptRunnable runnable = new InterruptRunnable();

????????Thread thread = new Thread(runnable);

????????thread.start();

????????System.err.println(thread.isAlive());

????????Thread.sleep(1000);

????????thread.interrupt();

????????Thread.sleep(1000);

????????System.err.println(thread.isAlive());

????????Thread.sleep(1000);

????????System.err.println(thread.isAlive());

????}

????該測試方法大致同使用標(biāo)志位的測試方法您单,同樣啟動(dòng)該線程后斋荞,1秒后調(diào)用線程的interrupt方法,從而觸發(fā)Runnable的內(nèi)部queue.put(i)操作拋出InterruptedException異常虐秦。

**進(jìn)程的幾種通信方式**

進(jìn)程間通信(IPC平酿,InterProcess Communication)是指在不同進(jìn)程之間傳播或交換信息。

IPC的方式通常有管道(包括無名管道和命名管道)悦陋、消息隊(duì)列蜈彼、信號量、共享存儲俺驶、Socket幸逆、Streams等。其中 Socket和Streams支持不同主機(jī)上的兩個(gè)進(jìn)程IPC暮现。

**多線程之線程間的通信方式**

*?wait/notify 等待

*?Volatile 內(nèi)存共享

**Yied放棄時(shí)間片(暫停線程)**

?*?yield: 暫停當(dāng)前正在執(zhí)行的線程對象还绘,并執(zhí)行其他線程

?*??yield:加在哪個(gè)線程體里,就暫停誰 栖袋,暫停不一定生效

????????class YieldDemo implements Runnable{

????????@Override

????????public void run() {

????????????for(int i=0;i<=1000;i++){

????????????????/*if(i%20==0){

????????????????????Thread.yield();??//暫停的線程A

????????????????}*/

????????????????System.out.println(Thread.currentThread().getName()+"----"+i);

????????????}

????????}

????????}


??????????public class TestYield {

??????????public static void main(String[] args) {

????????????//創(chuàng)建真實(shí)角色類的實(shí)例

????????????YieldDemo yd = new YieldDemo();

????????????//創(chuàng)建代理角色拍顷,代理持有對真實(shí)角色的引用

????????????Thread th = new Thread(yd,"線程A");

????????????//通過代理開啟

????????????th.start();

????????????//main()主線程中??

????????????for(int i=0;i<=1000;i++){

????????????????if(i%20==0){

????????????????????Thread.yield();??//暫停的main(),線程A獲得執(zhí)行的機(jī)會

????????????????}

????????????????System.out.println(Thread.currentThread().getName()+"----"+i);

????????????}

????????}

????????}



**Join合并線程**

?*?join:等待該線程終止。

?*?阻塞線程塘幅,合并線程

?*?join()阻塞自身昔案,讓其他線程獲得執(zhí)行的機(jī)會,等其他線程執(zhí)行完畢晌块,自身才接著執(zhí)行 爱沟。

?*?加在哪個(gè)線程體里,就阻塞誰


???????????class JoinDemo implements Runnable{

????????????@Override

????????????public void run() {

????????????????for(int i=0;i<=1000;i++){

????????????????????System.out.println(Thread.currentThread().getName()+"----"+i);

????????????????}

????????????}

?????????}



?????????public class TestJoin {

????????????public static void main(String[] args) {

????????????????//創(chuàng)建真實(shí)角色

????????????????JoinDemo jd = new JoinDemo();

????????????????//創(chuàng)建代理匆背,代理持有對真實(shí)角色的引用

????????????????Thread th = new Thread(jd,"線程a");

????????????????//通過代理啟動(dòng)

????????????????th.start();


????????????for(int i=0;i<=1000;i++){

????????????????if(i==50){

????????????????????try {

????????????????????????th.join(); //阻塞main線程

????????????????????} catch (InterruptedException e) {

????????????????????????e.printStackTrace();

????????????????????}?

????????????????}

????????????????System.out.println(Thread.currentThread().getName()+"----"+i);

????????????}

????????}

????????}


**Synchronized線程的同步與鎖**

*?Synchronized允許加在方法前呼伸,表示方法是線程安全的。

*?多個(gè)代理訪問同一份資源,出現(xiàn)資源搶奪的問題括享,同步 :并發(fā)搂根,多個(gè)線程訪問同一份資源,確保資源安?????????全----線程安全

*?方式一:同步代碼塊

synchronized(引用類型铃辖、this/類.class){??..... }

注意:使用實(shí)現(xiàn)Runnable接口方式創(chuàng)建多線程剩愧,同步代碼塊中的鎖可以用this,如何使繼承Thread類娇斩,慎this

*?方式二:同步方法

訪問修飾符??synchornized 返回值類型 方法名 (){...}

**單例模式**

單例模式的意思就是只有一個(gè)實(shí)例仁卷。單例模式確保某一個(gè)類只有一個(gè)實(shí)例,而且自行實(shí)例化并向整個(gè)系統(tǒng)提供這個(gè)實(shí)例犬第。這個(gè)類稱為單例類锦积。

關(guān)鍵點(diǎn):

1)一個(gè)類只有一個(gè)實(shí)例???????這是最基本的

2)它必須自行創(chuàng)建這個(gè)實(shí)例

3)它必須自行向整個(gè)系統(tǒng)提供這個(gè)實(shí)例

兩種實(shí)現(xiàn)方式:

*懶漢模式*

(類加載時(shí)不初始化)

?????public class LazySingleton {

????//懶漢式單例模式

????//比較懶,在類加載時(shí)歉嗓,不創(chuàng)建實(shí)例丰介,因此類加載速度快,但運(yùn)行時(shí)獲取對象的速度慢



????private static LazySingleton intance = null;//靜態(tài)私用成員鉴分,沒有初始化


????private LazySingleton()

????{

????????//私有構(gòu)造函數(shù)

????}


????public static synchronized LazySingleton getInstance()????//靜態(tài)哮幢,同步,公開訪問點(diǎn)

????{

????????if(intance == null)

????????{

????????????intance = new LazySingleton();

????????}

????????return intance;

????}

????}

*餓漢模式*

(在類加載時(shí)就完成了初始化志珍,所以類加載較慢橙垢,但獲取對象的速度快)

?????public class EagerSingleton {

????//餓漢單例模式

????//在類加載時(shí)就完成了初始化,所以類加載較慢碴裙,但獲取對象的速度快


????private static EagerSingleton instance = new EagerSingleton();//靜態(tài)私有成員钢悲,已初始化

????private EagerSingleton()?

????{

????????//私有構(gòu)造函數(shù)

????}

????public static EagerSingleton getInstance()????//靜態(tài)点额,不用同步(類加載時(shí)已初始化舔株,不會有多線程的問題)

????{

????????return instance;

????}

????}

**wait()和notify()**

?*?wait()方法:調(diào)用wait()方法,會掛起當(dāng)前線程还棱,并釋放共享資源的鎖.

*?notify()方法:調(diào)用了任意對象的notify()方法會在因調(diào)用該對象的wait()方法而阻塞的線程中隨機(jī)選擇一個(gè)解除阻塞载慈,但要等到獲得鎖后才可真正執(zhí)行。

*?notifyAll()方法:調(diào)用了notifyAll()方法會將因調(diào)用該對象的wait()方法而阻塞的所有線程一次性全部解除阻塞珍手。

*?wait(),notify(),和notifyall()這3個(gè)方法都是Object類中的final方法办铡,被所有的類繼承且不允許重寫。這3個(gè)方法只能在同步方法或同步代碼塊中使用琳要,否則會拋出異常寡具。

**wait()方法和sleep()方法??區(qū)別**

*?wait() :線程進(jìn)入等待狀態(tài),不占用任何資源稚补,不增加時(shí)間限制童叠,因?yàn)閣ait方法會釋放鎖,所以調(diào)用該方法時(shí)课幕,要確保調(diào)用wait()方法的時(shí)候擁有鎖厦坛,即五垮,wait()方法的調(diào)用必須放在synchronized方法或synchronized塊中。

*?sleep():線程睡眠杜秸,線程被調(diào)用時(shí)放仗,占著cpu不工作,消耗內(nèi)存資源撬碟,增加時(shí)間限制

诞挨,必須捕獲異常

**同步和異步的區(qū)別**

同步是指兩個(gè)線程的運(yùn)行是相關(guān)的,其中一個(gè)線程要阻塞等待另外一個(gè)線程的運(yùn)行呢蛤。異步的意思是兩個(gè)線程毫無相關(guān)亭姥,自己運(yùn)行自己的。

以通訊為例

??????????同步:發(fā)送一個(gè)請求,等待返回,然后再發(fā)送下一個(gè)請求?

異步:發(fā)送一個(gè)請求,不等待返回,隨時(shí)可以再發(fā)送下一個(gè)請求

??????????并發(fā):同時(shí)發(fā)送多個(gè)請求

**socket編程**

套接字使用Tcp提供了兩臺計(jì)算機(jī)之間的通信機(jī)制

區(qū)分不同應(yīng)用程序進(jìn)程之間的網(wǎng)絡(luò)通信和連接

ServerSocket用于服務(wù)器端顾稀,通過accept()監(jiān)聽請求达罗,然后返回Socket。

Socket用于客戶端

**TCP和UDP的區(qū)別**

Tcp提供面向連接的静秆,可靠的字節(jié)流傳輸粮揉,并且提供了擁塞控制和流量控制機(jī)制

UDP提供面向無連接的,不可靠的數(shù)據(jù)報(bào)的傳輸抚笔,不提供擁塞控制和流量控制機(jī)制

**Socket通信實(shí)現(xiàn)步驟:**

簡化出Socket通信的實(shí)現(xiàn)步驟:

1.創(chuàng)建ServerSocket和Socket扶认,建立連接

2.打開鏈接到Socket的輸入/輸出流

3.按照協(xié)議對Socket進(jìn)行讀/寫操作

4.關(guān)閉輸入輸出流、關(guān)閉Socket

*使用多線程實(shí)現(xiàn)多客戶端的通信:*

多線程基本步驟:

1.服務(wù)器端創(chuàng)建ServerSocket殊橙,循環(huán)調(diào)用accept()等待客戶端連接辐宾。

2.客戶端創(chuàng)建一個(gè)socket并請求和服務(wù)器端連接。

3.服務(wù)器端接收客戶端請求膨蛮,創(chuàng)建socket與該客戶建立專線連接叠纹。

4.建立連接的兩個(gè)socket在一個(gè)單獨(dú)的線程上對話。

5.服務(wù)器端繼續(xù)等待新的連接

**NIO主要原理及使用**

NIO采取通道(Channel)和緩沖區(qū)(Buffer)來傳輸和保存數(shù)據(jù)敞葛,它是非阻塞式的I/O誉察,即在等待連接、讀寫數(shù)據(jù)(這些都是在一線程以客戶端的程序中會阻塞線程的操作)的時(shí)候惹谐,程序也可以做其他事情持偏,以實(shí)現(xiàn)線程的異步操作。

考慮一個(gè)即時(shí)消息服務(wù)器氨肌,可能有上千個(gè)客戶端同時(shí)連接到服務(wù)器鸿秆,但是在任何時(shí)刻只有非常少量的消息需要讀取和分發(fā)(如果采用線程池或者一線程一客戶端方式,則會非常浪費(fèi)資源)怎囚,這就需要一種方法能阻塞等待卿叽,直到有一個(gè)信道可以進(jìn)行I/O操作。NIO的Selector選擇器就實(shí)現(xiàn)了這樣的功能,一個(gè)Selector實(shí)例可以同時(shí)檢查一組信道的I/O狀態(tài)附帽,它就類似一個(gè)觀察者埠戳,只要我們把需要探知的SocketChannel告訴Selector,我們接著做別的事情,當(dāng)有事件(比如蕉扮,連接打開整胃、數(shù)據(jù)到達(dá)等)發(fā)生時(shí),它會通知我們喳钟,傳回一組SelectionKey,我們讀取這些Key,就會獲得我們剛剛注冊過的SocketChannel,然后屁使,我們從這個(gè)Channel中讀取數(shù)據(jù),接著我們可以處理這些數(shù)據(jù)奔则。

Selector內(nèi)部原理實(shí)際是在做一個(gè)對所注冊的Channel的輪詢訪問蛮寂,不斷的輪詢(目前就這一個(gè)算法),一旦輪詢到一個(gè)Channel有所注冊的事情發(fā)生易茬,比如數(shù)據(jù)來了酬蹋,它就會讀取Channel中的數(shù)據(jù),并對其進(jìn)行處理抽莱。

要使用選擇器范抓,需要?jiǎng)?chuàng)建一個(gè)Selector實(shí)例,并將其注冊到想要監(jiān)控的信道上(通過Channel的方法實(shí)現(xiàn))食铐。最后調(diào)用選擇器的select()方法匕垫,該方法會阻塞等待,直到有一個(gè)或多個(gè)信道準(zhǔn)備好了I/O操作或等待超時(shí)虐呻,或另一個(gè)線程調(diào)用了該選擇器的wakeup()方法∠蟊茫現(xiàn)在,在一個(gè)單獨(dú)的線程中斟叼,通過調(diào)用select()方法偶惠,就能檢查多個(gè)信道是否準(zhǔn)備好進(jìn)行I/O操作,由于非阻塞I/O的異步特性犁柜,在檢查的同時(shí)洲鸠,我們也可以執(zhí)行其他任務(wù)。

基于NIO的TCP連接的建立步驟

服務(wù)端

????1馋缅、傳建一個(gè)Selector實(shí)例;

????2绢淀、將其注冊到各種信道萤悴,并指定每個(gè)信道上感興趣的I/O操作;

????3皆的、重復(fù)執(zhí)行:

????????1)調(diào)用一種select()方法覆履;

????????2)獲取選取的鍵列表;

????????3)對于已選鍵集中的每個(gè)鍵:

???????????a、獲取信道硝全,并從鍵中獲取附件(如果為信道及其相關(guān)的key添加了附件的話)栖雾;

???????????b、確定準(zhǔn)備就緒的操縱并執(zhí)行伟众,如果是accept操作析藕,將接收的信道設(shè)置為非阻塞模式,并注冊到選擇器凳厢;

???????????c账胧、如果需要怪与,修改鍵的興趣操作集梭域;

???????????d、從已選鍵集中移除鍵

客戶端

與基于多線程的TCP客戶端大致相同筏勒,只是這里是通過信道建立的連接遮精,但在等待連接建立及讀寫時(shí)居夹,我們可以異步地執(zhí)行其他任務(wù)。

**double轉(zhuǎn)byte類型**

????private static byte[] data;

????public static byte[] convert(double num) throws IOException {

????????data = null;

????????ByteArrayOutputStream bos = new ByteArrayOutputStream();

????????DataOutputStream dos = new DataOutputStream(bos);

????????dos.writeDouble(num);

????????dos.flush();

????????data = bos.toByteArray();

????????dos.close();

????????return data;

????}

**byte轉(zhuǎn)double類型**

????public static double convert(byte[] data) throws IOException {

????????DataInputStream dis = new DataInputStream(new ByteArrayInputStream(data));

????????double num = dis.readDouble();

????????dis.close();

????????return num;

????}

**UDP通信**

*發(fā)送引用數(shù)據(jù)類型*

*????客戶端:

1)????創(chuàng)建客戶端 DatagramSocket類 +指定端口

2)????準(zhǔn)備數(shù)據(jù)??字節(jié)數(shù)組

3)????打包 DatagramPacket +服務(wù)器地址及端口

4)????發(fā)送

5)????釋放資源

*????服務(wù)器:

1)????創(chuàng)建服務(wù)端DatagramSocket類+指定端口

2)????準(zhǔn)備接受容器??字節(jié)數(shù)組 封裝DatagramPacket(封裝成包)

3)????包 接收數(shù)據(jù)

4)????分析

5)????釋放資源

*發(fā)送基本數(shù)據(jù)類型*

*????客戶端:


1)????創(chuàng)建客戶端 DatagramSocket類 +指定端口

2)????準(zhǔn)備數(shù)據(jù) 基本數(shù)據(jù)類型轉(zhuǎn)換成字節(jié)數(shù)組(字節(jié)數(shù)組輸出流ByteArrayOutputStream toByteArray 數(shù)據(jù)字節(jié)輸出流DataOutputStream)

3)????打包 DatagramPacket +服務(wù)器地址及端口(發(fā)送的地點(diǎn)以及端口)

4)????發(fā)送

5)????釋放資源

*????服務(wù)器:

1)????創(chuàng)建服務(wù)端DatagramSocket類+指定端口

2)????準(zhǔn)備接受容器??字節(jié)數(shù)組 封裝DatagramPacket(封裝成包)

3)????包 接收數(shù)據(jù)

4)????分析數(shù)據(jù) 字節(jié)數(shù)組轉(zhuǎn)換成基本數(shù)據(jù)類型(字節(jié)數(shù)組輸入流ByteArrayOutputStream 數(shù)據(jù)字節(jié)輸入流DataInputStream)

5)????釋放資源

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末本冲,一起剝皮案震驚了整個(gè)濱河市吮播,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌眼俊,老刑警劉巖意狠,帶你破解...
    沈念sama閱讀 222,807評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異疮胖,居然都是意外死亡环戈,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,284評論 3 399
  • 文/潘曉璐 我一進(jìn)店門澎灸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來院塞,“玉大人,你說我怎么就攤上這事性昭±怪梗” “怎么了?”我有些...
    開封第一講書人閱讀 169,589評論 0 363
  • 文/不壞的土叔 我叫張陵糜颠,是天一觀的道長汹族。 經(jīng)常有香客問我,道長其兴,這世上最難降的妖魔是什么顶瞒? 我笑而不...
    開封第一講書人閱讀 60,188評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮元旬,結(jié)果婚禮上榴徐,老公的妹妹穿的比我還像新娘守问。我一直安慰自己,他們只是感情好坑资,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,185評論 6 398
  • 文/花漫 我一把揭開白布耗帕。 她就那樣靜靜地躺著,像睡著了一般袱贮。 火紅的嫁衣襯著肌膚如雪仿便。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,785評論 1 314
  • 那天字柠,我揣著相機(jī)與錄音探越,去河邊找鬼。 笑死窑业,一個(gè)胖子當(dāng)著我的面吹牛钦幔,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播常柄,決...
    沈念sama閱讀 41,220評論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼鲤氢,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了西潘?” 一聲冷哼從身側(cè)響起卷玉,我...
    開封第一講書人閱讀 40,167評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎喷市,沒想到半個(gè)月后相种,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,698評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡品姓,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,767評論 3 343
  • 正文 我和宋清朗相戀三年寝并,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片腹备。...
    茶點(diǎn)故事閱讀 40,912評論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡衬潦,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出植酥,到底是詐尸還是另有隱情镀岛,我是刑警寧澤,帶...
    沈念sama閱讀 36,572評論 5 351
  • 正文 年R本政府宣布友驮,位于F島的核電站漂羊,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏喊儡。R本人自食惡果不足惜拨与,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,254評論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望艾猜。 院中可真熱鬧买喧,春花似錦、人聲如沸匆赃。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,746評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽算柳。三九已至低淡,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間瞬项,已是汗流浹背蔗蹋。 一陣腳步聲響...
    開封第一講書人閱讀 33,859評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留囱淋,地道東北人猪杭。 一個(gè)月前我還...
    沈念sama閱讀 49,359評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像妥衣,于是被迫代替她去往敵國和親皂吮。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,922評論 2 361

推薦閱讀更多精彩內(nèi)容