return-1;
mid =(max+min)>>1;}
/ 105
return mid;}--------------------------java分了5片內存。
1:寄存器。2:本地方法區。3:方法區。4:棧。5:堆。
棧:存儲的都是局部變量(函數中定義的變量,函數上的參數,語句中的變量); 只要數據運算完成所在的區域結束,該數據就會被釋放。
堆:用于存儲數組和對象,也就是實體。啥是實體啊?就是用于封裝多個數據的。
1:每一個實體都有內存首地址值。
2:堆內存中的變量都有默認初始化值。因為數據類型不同,值也不一樣。3:垃圾回收機制。
-三:面向對象:★★★★★
特點:1:將復雜的事情簡單化。
2:面向對象將以前的過程中的執行者,變成了指揮者。3:面向對象這種思想是符合現在人們思考習慣的一種思想。
過程和對象在我們的程序中是如何體現的呢?過程其實就是函數;對象是將函數等一些內容進行了封裝。
匿名對象使用場景:
1:當對方法只進行一次調用的時候,可以使用匿名對象。如:new Person().age = 17;//使用一次之后就被銷毀了。
2:當對象對成員進行多次調用時,不能使用匿名對象。必須給對象起名字。
3.可作為實際參數進行傳遞;只在堆里面開辟存儲區域, 如:method(new Person());
在類中定義其實都稱之為成員。成員有兩種: 1:成員變量:其實對應的就是事物的屬性。
/ 105
2:成員函數:其實對應的就是事物的行為。
所以,其實定義類,就是在定義成員變量和成員函數。但是在定義前,必須先要對事物進行屬性和行為的分析,才可以用代碼來體現。
private int age;//私有的訪問權限最低,只有在本類中的訪問有效。注意:私有僅僅是封裝的一種體現形式而已。
私有的成員:其他類不能直接創建對象訪問,所以只有通過本類對外提供具體的訪問方式來完成對私有的訪問,可以通過對外提供函數的形式對其進行訪問。
好處:可以在函數中加入邏輯判斷等操作,對數據進行判斷等操作。
總結:開發時,記住,屬性是用于存儲數據的,直接被訪問,容易出現安全隱患,所以,類中的屬性通常被私有化,并對外提供公共的訪問方法。
這個方法一般有兩個,規范寫法:對于屬性 xxx,可以使用setXXX(),getXXX()對其進行操作。
類中怎么沒有定義主函數呢?
注意:主函數的存在,僅為該類是否需要獨立運行,如果不需要,主函數是不用定義的。主函數的解釋:保證所在類的獨立運行,是程序的入口,被jvm調用。
成員變量和局部變量的區別:
1:成員變量直接定義在類中。
局部變量定義在方法中,參數上,語句中。2:成員變量在這個類中有效。
局部變量只在自己所屬的大括號內有效,大括號結束,局部變量失去作用域。3:成員變量存在于堆內存中,隨著對象的產生而存在,消失而消失。局部變量存在于棧內存中,隨著所屬區域的運行而存在,結束而釋放。
/ 105
構造函數:用于給對象進行初始化,是給與之對應的對象進行初始化,它具有針對性,函數中的一種。特點:
1:該函數的名稱和所在類的名稱相同。2:不需要定義返回值類型。3:該函數沒有具體的返回值。
記?。核袑ο髣摻〞r,都需要初始化才可以使用。
注意事項:一個類在定義時,如果沒有定義過構造函數,那么該類中會自動生成一個空參數的構造函數,為了方便該類創建對象,完成初始化。如果在類中自定義了構造函數,那么默認的構造函數就沒有了。
一個類中,可以有多個構造函數,因為它們的函數名稱都相同,所以只能通過參數列表來區分。所以,一個類中如果出現多個構造函數。它們的存在是以重載體現的。
構造函數和一般函數有什么區別呢? 1:兩個函數定義格式不同。
2:構造函數是在對象創建時,就被調用,用于初始化,而且初始化動作只執行一次。
一般函數,是對象創建后,需要調用才執行,可以被調用多次。
什么時候使用構造函數呢?
分析事物時,發現具體事物一出現,就具備了一些特征,那就將這些特征定義到構造函數內。
構造代碼塊和構造函數有什么區別?
構造代碼塊:是給所有的對象進行初始化,也就是說,所有的對象都會調用一個代碼塊。只要對象一建立。就會調用這個代碼塊。
構造函數:是給與之對應的對象進行初始化。它具有針對性。
/ 105
Person p = new Person();創建一個對象都在內存中做了什么事情?
1:先將硬盤上指定位置的Person.class文件加載進內存。
2:執行main方法時,在棧內存中開辟了main方法的空間(壓棧-進棧),然后在main方法的棧區分配了一個變量p。
3:在堆內存中開辟一個實體空間,分配了一個內存首地址值。new 4:在該實體空間中進行屬性的空間分配,并進行了默認初始化。5:對空間中的屬性進行顯示初始化。6:進行實體的構造代碼塊初始化。
7:調用該實體對應的構造函數,進行構造函數初始化。()8:將首地址賦值給p,p變量就引用了該實體。(指向了該對象)------------------------------封 裝(面向對象特征之一):是指隱藏對象的屬性和實現細節,僅對外提供公共訪問方式。
好處:將變化隔離;便于使用;提高重用性;安全性。
封裝原則:將不需要對外提供的內容都隱藏起來,把屬性都隱藏,提供公共方法對其訪問。
this:代表對象。就是所在函數所屬對象的引用。
this到底代表什么呢?哪個對象調用了this所在的函數,this就代表哪個對象,就是哪個對象的引用。開發時,什么時候使用this呢?
在定義功能時,如果該功能內部使用到了調用該功能的對象,這時就用this來表示這個對象。
this 還可以用于構造函數間的調用。調用格式:this(實際參數);
this對象后面跟上.調用的是成員屬性和成員方法(一般方法); this對象后面跟上()調用的是本類中的對應參數的構造函數。
/ 105
注意:用this調用構造函數,必須定義在構造函數的第一行。因為構造函數是用于初始化的,所以初始化動作一定要執行。否則編譯失敗。
static:★★★ 關鍵字,是一個修飾符,用于修飾成員(成員變量和成員函數)。
特點:
1,想要實現對象中的共性數據的對象共享??梢詫⑦@個數據進行靜態修飾。
2,被靜態修飾的成員,可以直接被類名所調用。也就是說,靜態的成員多了一種調用方式。類名.靜態方式。3,靜態隨著類的加載而加載。而且優先于對象存在。
弊端:
1,有些數據是對象特有的數據,是不可以被靜態修飾的。因為那樣的話,特有數據會變成對象的共享數據。這樣對事物的描述就出了問題。所以,在定義靜態時,必須要明確,這個數據是否是被對象所共享的。2,靜態方法只能訪問靜態成員,不可以訪問非靜態成員。
因為靜態方法加載時,優先于對象存在,所以沒有辦法訪問對象中的成員。3,靜態方法中不能使用this,super關鍵字。
因為this代表對象,而靜態在時,有可能沒有對象,所以this無法使用。4,主函數是靜態的。
什么時候定義靜態成員呢?或者說:定義成員時,到底需不需要被靜態修飾呢? 成員分兩種:
1,成員變量。(數據共享時靜態化)該成員變量的數據是否是所有對象都一樣:
如果是,那么該變量需要被靜態修飾,因為是共享的數據。如果不是,那么就說這是對象的特有數據,要存儲到對象中。2,成員函數。(方法中沒有調用特有數據時就定義成靜態)
/ 105
如果判斷成員函數是否需要被靜態修飾呢? 只要參考,該函數內是否訪問了對象中的特有數據: 如果有訪問特有數據,那方法不能被靜態修飾。
如果沒有訪問過特有數據,那么這個方法需要被靜態修飾。
成員變量和靜態變量的區別:
1,成員變量所屬于對象。所以也稱為實例變量。靜態變量所屬于類。所以也稱為類變量。2,成員變量存在于堆內存中。靜態變量存在于方法區中。
3,成員變量隨著對象創建而存在。隨著對象被回收而消失。靜態變量隨著類的加載而存在。隨著類的消失而消失。4,成員變量只能被對象所調用。
靜態變量可以被對象調用,也可以被類名調用。
所以,成員變量可以稱為對象的特有數據,靜態變量稱為對象的共享數據。
靜態的注意:靜態的生命周期很長。
靜態代碼塊:就是一個有靜態關鍵字標示的一個代碼塊區域。定義在類中。
作用:可以完成類的初始化。靜態代碼塊隨著類的加載而執行,而且只執行一次(new 多個對象就只執行一次)。如果和主函數在同一類中,優先于主函數執行。
Public:訪問權限最大。
static:不需要對象,直接類名即可。void:主函數沒有返回值。Main:主函數特定的名稱。
/ 105
(String[] args):主函數的參數,是一個字符串數組類型的參數,jvm調用main方法時,傳遞的實際參數是 new String[0]。
jvm默認傳遞的是長度為0的字符串數組,我們在運行該類時,也可以指定具體的參數進行傳遞。可以在控制臺,運行該類時,在后面加入參數。參數之間通過空格隔開。jvm會自動將這些字符串參數作為args數組中的元素,進行存儲。
靜態代碼塊、構造代碼塊、構造函數同時存在時的執行順序:靜態代碼塊 ? 構造代碼塊 ? 構造函數;
生成Java幫助文檔:命令格式:javadoc –d 文件夾名 –auther –version *.java
/** //格式 *類描述 *@author 作者名 *@version 版本號 */ /** *方法描述 *@param 參數描述 *@return 返回值描述
*/ 設計模式:解決問題最行之有效的思想。是一套被反復使用、多數人知曉的、經過分類編目的、代碼設計經驗的總結。使用設計模式是為了可重用代碼、讓代碼更容易被他人理解、保證代碼可靠性。
java中有23種設計模式:
單例設計模式:★★★★★
解決的問題:保證一個類在內存中的對象唯一性。
比如:多程序讀取一個配置文件時,建議配置文件封裝成對象。會方便操作其中數據,又要保證多個程序讀到的 17 / 105
是同一個配置文件對象,就需要該配置文件對象在內存中是唯一的。
Runtime()方法就是單例設計模式進行設計的。
如何保證對象唯一性呢? 思想:
1,不讓其他程序創建該類對象。2,在本類中創建一個本類對象。
3,對外提供方法,讓其他程序獲取這個對象。
步驟:
1,因為創建對象都需要構造函數初始化,只要將本類中的構造函數私有化,其他程序就無法再創建該類對象; 2,就在類中創建一個本類的對象;
3,定義一個方法,返回該對象,讓其他程序可以通過方法就得到本類對象。(作用:可控)
代碼體現:
1,私有化構造函數;
2,創建私有并靜態的本類對象; 3,定義公有并靜態的方法,返回該對象。--------------//餓漢式 class Single{ private Single(){} //私有化構造函數。
private static Single s = new Single();//創建私有并靜態的本類對象。public static Single getInstance(){ //定義公有并靜態的方法,返回該對象。
return s;} }
/ 105
--------------//懶漢式:延遲加載方式。
class Single2{ private Single2(){} private static Single2 s = null;public static Single2 getInstance(){
if(s==null)
s = new Single2();
return s;} }----繼 承(面向對象特征之一)
好處:
1:提高了代碼的復用性。
2:讓類與類之間產生了關系,提供了另一個特征多態的前提。
父類的由來:其實是由多個類不斷向上抽取共性內容而來的。
java中對于繼承,java只支持單繼承。java雖然不直接支持多繼承,但是保留了這種多繼承機制,進行改良。
單繼承:一個類只能有一個父類。多繼承:一個類可以有多個父類。
為什么不支持多繼承呢?
因為當一個類同時繼承兩個父類時,兩個父類中有相同的功能,那么子類對象調用該功能時,運行哪一個呢?因為父類中的方法中存在方法體。
但是java支持多重繼承。A繼承B B繼承C C繼承D。
多重繼承的出現,就有了繼承體系。體系中的頂層父類是通過不斷向上抽取而來的。它里面定義的該體系最基本最共性內容的功能。
所以,一個體系要想被使用,直接查閱該系統中的父類的功能即可知道該體系的基本用法。那么想要使用一個體系時,需要建立對象。建議建立最子類對象,因為最子類不僅可以使用父類中的功能。還可以使用子類特有
/ 105
的一些功能。
簡單說:對于一個繼承體系的使用,查閱頂層父類中的內容,創建最底層子類的對象。
子父類出現后,類中的成員都有了哪些特點:
1:成員變量。
當子父類中出現一樣的屬性時,子類類型的對象,調用該屬性,值是子類的屬性值。
如果想要調用父類中的屬性值,需要使用一個關鍵字:super
This:代表是本類類型的對象引用。
Super:代表是子類所屬的父類中的內存空間引用。
注意:子父類中通常是不會出現同名成員變量的,因為父類中只要定義了,子類就不用在定義了,直接繼承過來用就可以了。
2:成員函數。
當子父類中出現了一模一樣的方法時,建立子類對象會運行子類中的方法。好像父類中的方法被覆蓋掉一樣。所以這種情況,是函數的另一個特性:覆蓋(復寫,重寫)什么時候使用覆蓋呢?當一個類的功能內容需要修改時,可以通過覆蓋來實現。3:構造函數。
發現子類構造函數運行時,先運行了父類的構造函數。為什么呢? 原因:子類的所有構造函數中的第一行,其實都有一條隱身的語句super();
super(): 表示父類的構造函數,并會調用于參數相對應的父類中的構造函數。而super():是在調用父類中空參數的構造函數。
為什么子類對象初始化時,都需要調用父類中的函數?(為什么要在子類構造函數的第一行加入這個super()?)因為子類繼承父類,會繼承到父類中的數據,所以必須要看父類是如何對自己的數據進行初始化的。所以子類在進行對象初始化時,先調用父類的構造函數,這就是子類的實例化過程。
/ 105
注意:子類中所有的構造函數都會默認訪問父類中的空參數的構造函數,因為每一個子類構造內第一行都有默認的語句super();如果父類中沒有空參數的構造函數,那么子類的構造函數內,必須通過super語句指定要訪問的父類中的構造函數。
如果子類構造函數中用this來指定調用子類自己的構造函數,那么被調用的構造函數也一樣會訪問父類中的構造函數。
問題:super()和this()是否可以同時出現的構造函數中。
兩個語句只能有一個定義在第一行,所以只能出現其中一個。
super()或者this():為什么一定要定義在第一行?
因為super()或者this()都是調用構造函數,構造函數用于初始化,所以初始化的動作要先完成。
繼承的細節: 什么時候使用繼承呢?
當類與類之間存在著所屬關系時,才具備了繼承的前提。a是b中的一種。a繼承b。狼是犬科中的一種。英文書中,所屬關系:“ is a ” 注意:不要僅僅為了獲取其他類中的已有成員進行繼承。
所以判斷所屬關系,可以簡單看,如果繼承后,被繼承的類中的功能,都可以被該子類所具備,那么繼承成立。如果不是,不可以繼承。
細節二:
在方法覆蓋時,注意兩點:
1:子類覆蓋父類時,必須要保證,子類方法的權限必須大于等于父類方法權限可以實現繼承。否則,編譯失敗。
/ 105
2:覆蓋時,要么都靜態,要么都不靜態。(靜態只能覆蓋靜態,或者被靜態覆蓋)
繼承的一個弊端:打破了封裝性。對于一些類,或者類中功能,是需要被繼承,或者復寫的。這時如何解決問題呢?介紹一個關鍵字,final:最終。
final特點:
1:這個關鍵字是一個修飾符,可以修飾類,方法,變量。2:被final修飾的類是一個最終類,不可以被繼承。3:被final修飾的方法是一個最終方法,不可以被覆蓋。4:被final修飾的變量是一個常量,只能賦值一次。
其實這樣的原因的就是給一些固定的數據起個閱讀性較強的名稱。
不加final修飾不是也可以使用嗎?那么這個值是一個變量,是可以更改的。加了final,程序更為嚴謹。常量名稱定義時,有規范,所有字母都大寫,如果由多個單詞組成,中間用 _ 連接。
抽象類: abstract 抽象:不具體,看不明白。抽象類表象體現。
在不斷抽取過程中,將共性內容中的方法聲明抽取,但是方法不一樣,沒有抽取,這時抽取到的方法,并不具體,需要被指定關鍵字abstract所標示,聲明為抽象方法。
抽象方法所在類一定要標示為抽象類,也就是說該類需要被abstract關鍵字所修飾。
抽象類的特點:
1:抽象方法只能定義在抽象類中,抽象類和抽象方法必須由abstract關鍵字修飾(可以描述類和方法,不可以描述變量)。
2:抽象方法只定義方法聲明,并不定義方法實現。3:抽象類不可以被創建對象(實例化)。
/ 105
4:只有通過子類繼承抽象類并覆蓋了抽象類中的所有抽象方法后,該子類才可以實例化。否則,該子類還是一個抽象類。
抽象類的細節:
1:抽象類中是否有構造函數?有,用于給子類對象進行初始化。2:抽象類中是否可以定義非抽象方法? 可以。其實,抽象類和一般類沒有太大的區別,都是在描述事物,只不過抽象類在描述事物時,有些功能不具體。所以抽象類和一般類在定義上,都是需要定義屬性和行為的。只不過,比一般類多了一個抽象函數。而且比一般類少了一個創建對象的部分。
3:抽象關鍵字abstract和哪些不可以共存?final , private , static 4:抽象類中可不可以不定義抽象方法?可以。抽象方法目的僅僅為了不讓該類創建對象。
--模板方法設計模式:
解決的問題:當功能內部一部分實現時確定,一部分實現是不確定的。這時可以把不確定的部分暴露出去,讓子類去實現。
abstract class GetTime{
public final void getTime(){ //此功能如果不需要復寫,可加final限定
} public abstract void code();//抽象不確定的功能,讓子類復寫實現 long start = System.currentTimeMillis();code();//不確定的功能部分,提取出來,通過抽象方法實現 long end = System.currentTimeMillis();System.out.println(“毫秒是:”+(end-start));} class SubDemo extends GetTime{
public void code(){ //子類復寫功能方法
for(int y=0;y<1000;y++){ System.out.println(“y”);}
/ 105 } } 接 口:★★★★★
1:是用關鍵字interface定義的。
2:接口中包含的成員,最常見的有全局常量、抽象方法。
注意:接口中的成員都有固定的修飾符。
成員變量:public static final 成員方法:public abstract interface Inter{ public static final int x = 3;public abstract void show();} 3:接口中有抽象方法,說明接口不可以實例化。接口的子類必須實現了接口中所有的抽象方法后,該子類才可以實例化。否則,該子類還是一個抽象類。
4:類與類之間存在著繼承關系,類與接口中間存在的是實現關系。繼承用extends ;實現用implements ;
5:接口和類不一樣的地方,就是,接口可以被多實現,這就是多繼承改良后的結果。java將多繼承機制通過多現實來體現。
6:一個類在繼承另一個類的同時,還可以實現多個接口。所以接口的出現避免了單繼承的局限性。還可以將類進行功能的擴展。
7:其實java中是有多繼承的。接口與接口之間存在著繼承關系,接口可以多繼承接口。
接口都用于設計上,設計上的特點:(可以理解主板上提供的接口)
1:接口是對外提供的規則。2:接口是功能的擴展。3:接口的出現降低了耦合性。
/ 105
抽象類與接口:
抽象類:一般用于描述一個體系單元,將一組共性內容進行抽取,特點:可以在類中定義抽象內容讓子類實現,可以定義非抽象內容讓子類直接使用。它里面定義的都是一些體系中的基本內容。接口:一般用于定義對象的擴展功能,是在繼承之外還需這個對象具備的一些功能。
抽象類和接口的共性:都是不斷向上抽取的結果。
抽象類和接口的區別:
1:抽象類只能被繼承,而且只能單繼承。
接口需要被實現,而且可以多實現。
2:抽象類中可以定義非抽象方法,子類可以直接繼承使用。
接口中都有抽象方法,需要子類去實現。3:抽象類使用的是 is a 關系。
接口使用的 like a 關系。4:抽象類的成員修飾符可以自定義。
接口中的成員修飾符是固定的。全都是public的。
在開發之前,先定義規則,A和B分別開發,A負責實現這個規則,B負責使用這個規則。至于A是如何對規則具體實現的,B是不需要知道的。這樣這個接口的出現就降低了A和B直接耦合性。
---多 態★★★★★(面向對象特征之一):函數本身就具備多態性,某一種事物有不同的具體的體現。
體現:父類引用或者接口的引用指向了自己的子類對象。//Animal a = new Cat();多態的好處:提高了程序的擴展性。
多態的弊端:當父類引用指向子類對象時,雖然提高了擴展性,但是只能訪問父類中具備的方法,不可以訪問子類中特有的方法。(前期不能使用后期產生的功能,即訪問的局限性)
/ 105
多態的前提:
多態的出現思想上也做著變化:以前是創建對象并指揮對象做事情。有了多態以后,我們可以找到對象的共性類型,直接操作共性類型做事情即可,這樣可以指揮一批對象做事情,即通過操作父類或接口實現。class 畢姥爺{
void 講課(){ } void 釣魚(){ System.out.println(“釣魚”);System.out.println(“企業管理”);1:必須要有關系,比如繼承、或者實現。2:通常會有覆蓋操作。
} } class 畢老師 extends 畢姥爺{
void 講課(){ System.out.println(“JAVA”);} void 看電影(){ System.out.println(“看電影”);} } class { public static void main(String[] args){ 畢姥爺 x = new 畢老師();//畢老師對象被提升為了畢姥爺類型。x.講課();x.看電影();//錯誤.畢老師 y =(畢老師)x;//將畢姥爺類型強制轉換成畢老師類型。
/ 105
// //
y.看電影();//在多態中,自始自終都是子類對象在做著類型的變化。
} }導入:類名稱變長,寫起來很麻煩。為了簡化,使用了一個關鍵字:import,可以使用這個關鍵字導入指定包中的類。記住:實際開發時,到的哪個類就導入哪個類,不建議使用*.import packa.*;//這個僅僅是導入了packa當前目錄下的所有的類。不包含子包。import packa.abc.*;//導入了packa包中的子包abc下的當前的所有類。
如果導入的兩個包中存在著相同名稱的類。這時如果用到該類,必須在代碼中指定包名。
常見的軟件包: java.lang : language java的核心包,Object System String Throwable jdk1.2版本后,該包中的類自動被導入。
java.awt : 定義的都是用于java圖形界面開發的對象。
javax.swing: 提供所有的windows桌面應用程序包括的控件,比如:Frame , Dialog, Table, List 等等,就是java的圖形界面庫。
java.net : 用于java網絡編程方面的對象都在該包中。
java.io : input output 用于操作設備上數據的對象都在該包中。比如:讀取硬盤數據,往硬盤寫入數據。java.util : java的工具包,時間對象,集合框架。
java.applet: application+let 客戶端java小程序。server+let--> servlet 服務端java小程序。
jar :java的壓縮包,主要用于存儲類文件,或者配置文件等。
命令格式:jar –cf 包名.jar 包目錄
解壓縮:jar –xvf 包名.jar
/ 105
將jar包目錄列表重定向到一個文件中:jar –tf 包名.jar >c:1.txt--多線程:★★★★
進程:正在進行中的程序。其實進程就是一個應用程序運行時的內存分配空間。
線程:其實就是進程中一個程序執行控制單元,一條執行路徑。進程負責的是應用程序的空間的標示。線程負責的是應用程序的執行順序。
一個進程至少有一個線程在運行,當一個進程中出現多個線程時,就稱這個應用程序是多線程應用程序,每個線程在棧區中都有自己的執行空間,自己的方法區、自己的變量。
jvm在啟動的時,首先有一個主線程,負責程序的執行,調用的是main函數。主線程執行的代碼都在main方法中。
當產生垃圾時,收垃圾的動作,是不需要主線程來完成,因為這樣,會出現主線程中的代碼執行會停止,會去運行垃圾回收器代碼,效率較低,所以由單獨一個線程來負責垃圾回收。
隨機性的原理:因為cpu的快速切換造成,哪個線程獲取到了cpu的執行權,哪個線程就執行。
返回當前線程的名稱:Thread.currentThread().getName()線程的名稱是由:Thread-編號定義的。編號從0開始。線程要運行的代碼都統一存放在了run方法中。
線程要運行必須要通過類中指定的方法開啟。start方法。(啟動后,就多了一條執行路徑)start方法:1)、啟動了線程;2)、讓jvm調用了run方法。
創建線程的第一種方式:繼承Thread,由子類復寫run方法。步驟:
1,定義類繼承Thread類;
2,目的是復寫run方法,將要讓線程運行的代碼都存儲到run方法中;
/ 105
3,通過創建Thread類的子類對象,創建線程對象; 4,調用線程的start方法,開啟線程,并執行run方法。
線程狀態:
被創建:start()運行:具備執行資格,同時具備執行權;
凍結:sleep(time),wait()—notify()喚醒;線程釋放了執行權,同時釋放執行資格; 臨時阻塞狀態:線程具備cpu的執行資格,沒有cpu的執行權; 消亡:stop()
創建線程的第二種方式:實現一個接口Runnable。步驟:
1,定義類實現Runnable接口。
2,覆蓋接口中的run方法(用于封裝線程要運行的代碼)。3,通過Thread類創建線程對象;
4,將實現了Runnable接口的子類對象作為實際參數傳遞給Thread類中的構造函數。為什么要傳遞呢?因為要讓線程對象明確要運行的run方法所屬的對象。
5,調用Thread對象的start方法。開啟線程,并運行Runnable接口子類中的run方法。
/ 105
Ticket t = new Ticket();/* 直接創建Ticket對象,并不是創建線程對象。
因為創建對象只能通過new Thread類,或者new Thread類的子類才可以。所以最終想要創建線程。既然沒有了Thread類的子類,就只能用Thread類。*/ Thread t1 = new Thread(t);//創建線程。/* 只要將t作為Thread類的構造函數的實際參數傳入即可完成線程對象和t之間的關聯 為什么要將t傳給Thread類的構造函數呢?其實就是為了明確線程要運行的代碼run方法。*/ t1.start();
為什么要有Runnable接口的出現?
1:通過繼承Thread類的方式,可以完成多線程的建立。但是這種方式有一個局限性,如果一個類已經有了自己的父類,就不可以繼承Thread類,因為java單繼承的局限性。
可是該類中的還有部分代碼需要被多個線程同時執行。這時怎么辦呢?
只有對該類進行額外的功能擴展,java就提供了一個接口Runnable。這個接口中定義了run方法,其實run方法的定義就是為了存儲多線程要運行的代碼。
所以,通常創建線程都用第二種方式。
因為實現Runnable接口可以避免單繼承的局限性。
2:其實是將不同類中需要被多線程執行的代碼進行抽取。將多線程要運行的代碼的位置單獨定義到接口中。為其他類進行功能擴展提供了前提。
所以Thread類在描述線程時,內部定義的run方法,也來自于Runnable接口。
實現Runnable接口可以避免單繼承的局限性。而且,繼承Thread,是可以對Thread類中的方法,進行子類復寫的。但是不需要做這個復寫動作的話,只為定義線程代碼存放位置,實現Runnable接口更方便一些。所
/ 105
以Runnable接口將線程要執行的任務封裝成了對象。------------------------//面試
new Thread(new Runnable(){ //匿名
}){
public void run(){ System.out.println(“runnable run”);} public void run(){ System.out.println(“subthread run”);} }.start();//結果:subthread run
--------------------------Try { Thread.sleep(10);}catch(InterruptedException e){}// 當刻意讓線程稍微停一下,模擬cpu 切換情況。
多線程安全問題的原因:
通過圖解:發現一個線程在執行多條語句時,并運算同一個數據時,在執行過程中,其他線程參與進來,并操作了這個數據。導致到了錯誤數據的產生。
涉及到兩個因素:
1,多個線程在操作共享數據。2,有多條語句對共享數據進行運算。
原因:這多條語句,在某一個時刻被一個線程執行時,還沒有執行完,就被其他線程執行了。
解決安全問題的原理:
只要將操作共享數據的語句在某一時段讓一個線程執行完,在執行過程中,其他線程不能進來執行就可以解決這個問題。
如何進行多句操作共享數據代碼的封裝呢?
/ 105
java中提供了一個解決方式:就是同步代碼塊。
格式:
synchronized(對象){ // 任意對象都可以。這個對象就是鎖。需要被同步的代碼;
}-同步:★★★★★
好處:解決了線程安全問題。
弊端:相對降低性能,因為判斷鎖需要消耗資源,產生了死鎖。
定義同步是有前提的:
1,必須要有兩個或者兩個以上的線程,才需要同步。2,多個線程必須保證使用的是同一個鎖。
同步的第二種表現形式:
同步函數:其實就是將同步關鍵字定義在函數上,讓函數具備了同步性。
同步函數是用的哪個鎖呢?
通過驗證,函數都有自己所屬的對象this,所以同步函數所使用的鎖就是this鎖。
當同步函數被static修飾時,這時的同步用的是哪個鎖呢?
靜態函數在加載時所屬于類,這時有可能還沒有該類產生的對象,但是該類的字節碼文件加載進內存就已經被封裝成了對象,這個對象就是該類的字節碼文件對象。
所以靜態加載時,只有一個對象存在,那么靜態同步函數就使用的這個對象。這個對象就是 類名.class
同步代碼塊和同步函數的區別?
/ 105
同步代碼塊使用的鎖可以是任意對象。
同步函數使用的鎖是this,靜態同步函數的鎖是該類的字節碼文件對象。
在一個類中只有一個同步,可以使用同步函數。如果有多同步,必須使用同步代碼塊,來確定不同的鎖。所以同步代碼塊相對靈活一些。
------------------------★考點問題:請寫一個延遲加載的單例模式?寫懶漢式;當出現多線程訪問時怎么解決?加同步,解決安全問題;效率高嗎?不高;怎樣解決?通過雙重判斷的形式解決。
//懶漢式:延遲加載方式。
當多線程訪問懶漢式時,因為懶漢式的方法內對共性數據進行多條語句的操作。所以容易出現線程安全問題。為了解決,加入同步機制,解決安全問題。但是卻帶來了效率降低。
為了效率問題,通過雙重判斷的形式解決。class Single{ private static Single s = null;private Single(){} public static Single getInstance(){ //鎖是誰?字節碼文件對象;
if(s == null){
synchronized(Single.class){
if(s == null)
s = new Single();
}
}
return s;} }--------------------------同步死鎖:通常只要將同步進行嵌套,就可以看到現象。同步函數中有同步代碼塊,同步代碼塊中還有同步函數。
線程間通信:思路:多個線程在操作同一個資源,但是操作的動作卻不一樣。1:將資源封裝成對象。
2:將線程執行的任務(任務其實就是run方法。)也封裝成對象。
/ 105
等待喚醒機制:涉及的方法:
wait:將同步中的線程處于凍結狀態。釋放了執行權,釋放了資格。同時將線程對象存儲到線程池中。notify:喚醒線程池中某一個等待線程。notifyAll:喚醒的是線程池中的所有線程。
注意:
1:這些方法都需要定義在同步中。2:因為這些方法必須要標示所屬的鎖。你要知道 A鎖上的線程被wait了,那這個線程就相當于處于A鎖的線程池中,只能A鎖的notify喚醒。3:這三個方法都定義在Object類中。為什么操作線程的方法定義在Object類中? 因為這三個方法都需要定義同步內,并標示所屬的同步鎖,既然被鎖調用,而鎖又可以是任意對象,那么能被任意對象調用的方法一定定義在Object類中。
wait和sleep區別: 分析這兩個方法:從執行權和鎖上來分析:
wait:可以指定時間也可以不指定時間。不指定時間,只能由對應的notify或者notifyAll來喚醒。sleep:必須指定時間,時間到自動從凍結狀態轉成運行狀態(臨時阻塞狀態)。wait:線程會釋放執行權,而且線程會釋放鎖。Sleep:線程會釋放執行權,但不是不釋放鎖。
線程的停止:通過stop方法就可以停止線程。但是這個方式過時了。
停止線程:原理就是:讓線程運行的代碼結束,也就是結束run方法。怎么結束run方法?一般run方法里肯定定義循環。所以只要結束循環即可。第一種方式:定義循環的結束標記。
第二種方式:如果線程處于了凍結狀態,是不可能讀到標記的,這時就需要通過Thread類中的interrupt方法,將其凍結狀態強制清除。讓線程恢復具備執行資格的狀態,讓線程可以讀到標記,并結束。
/ 105
---------< java.lang.Thread >----------interrupt():中斷線程。
setPriority(int newPriority):更改線程的優先級。getPriority():返回線程的優先級。
toString():返回該線程的字符串表示形式,包括線程名稱、優先級和線程組。Thread.yield():暫停當前正在執行的線程對象,并執行其他線程。
setDaemon(true):將該線程標記為守護線程或用戶線程。將該線程標記為守護線程或用戶線程。當正在運行的線程都是守護線程時,Java 虛擬機退出。該方法必須在啟動線程前調用。join:臨時加入一個線程的時候可以使用join方法。
當A線程執行到了B線程的join方式。A線程處于凍結狀態,釋放了執行權,B開始執行。A什么時候執行呢?只有當B線程運行結束后,A才從凍結狀態恢復運行狀態執行。----------------------------Lock接口:多線程在JDK1.5版本升級時,推出一個接口Lock接口。
解決線程安全問題使用同步的形式,(同步代碼塊,要么同步函數)其實最終使用的都是鎖機制。
到了后期版本,直接將鎖封裝成了對象。線程進入同步就是具備了鎖,執行完,離開同步,就是釋放了鎖。在后期對鎖的分析過程中,發現,獲取鎖,或者釋放鎖的動作應該是鎖這個事物更清楚。所以將這些動作定義在了鎖當中,并把鎖定義成對象。
所以同步是隱示的鎖操作,而Lock對象是顯示的鎖操作,它的出現就替代了同步。
在之前的版本中使用Object類中wait、notify、notifyAll的方式來完成的。那是因為同步中的鎖是任意對象,所以操作鎖的等待喚醒的方法都定義在Object類中。
而現在鎖是指定對象Lock。所以查找等待喚醒機制方式需要通過Lock接口來完成。而Lock接口中并沒有直接操作等待喚醒的方法,而是將這些方式又單獨封裝到了一個對象中。這個對象就是Condition,將Object中的 48 / 105
三個方法進行單獨的封裝。并提供了功能一致的方法 await()、signal()、signalAll()體現新版本對象的好處。
< java.util.concurrent.locks > Condition接口:await()、signal()、signalAll();
-------------------------class BoundedBuffer { final Lock lock = new ReentrantLock();
final Condition notFull = lock.newCondition();final Condition notEmpty = lock.newCondition();final Object[] items = new Object[100];int putptr, takeptr, count;public void put(Object x)throws InterruptedException { lock.lock();try {
while(count == items.length)notFull.await();items[putptr] = x;if(++putptr == items.length)putptr = 0;++count;notEmpty.signal();
} finally { lock.unlock();} } public Object take()throws InterruptedException { lock.lock();try {
while(count == 0)notEmpty.await();
Object x = items[takeptr];if(++takeptr == items.length)takeptr = 0;--count;notFull.signal();return x;} finally { lock.unlock();} } }---API:(Application Programming Interface,應用程序編程接口)是一些預先定義的函數,目的是提供應用程序與開發人員基于某軟件或硬件的以訪問一組例程的能力,而又無需訪問源碼,或理解內部工作機制的細節。
/ 105
--< java.lang >--String字符串:★★★☆
java中用String類進行描述。對字符串進行了對象的封裝。這樣的好處是可以對字符串這種常見數據進行方便的操作。對象封裝后,可以定義N多屬性和行為。
如何定義字符串對象呢?String s = “abc”;只要是雙引號引起的數據都是字符串對象。
特點:字符串一旦被初始化,就不可以被改變,存放在方法區中的常量池中。-----------------------String s1 = “abc”;// s1指向的內存中只有一個對象abc。
String s2 = new String(“abc”);// s2指向的內容中有兩個對象abc、new。
System.out.println(s1==s2);//false System.out.println(s1.equals(s2));//true,字符串中equals比較的是字符串內容是否相同。------------------------字符串的方法:
1:構造方法:將字節數組或者字符數組轉成字符串。
String s1 = new String();//創建了一個空內容的字符串。String s2 = null;//s2沒有任何對象指向,是一個null常量值。
String s3 = “";//s3指向一個具體的字符串對象,只不過這個字符串中沒有內容。//一般在定義字符串時,不用new。String s4 = new String(”abc“);String s5 = ”abc";一般用此寫法
new String(char[]);//將字符數組轉成字符串。
new String(char[],offset,count);//將字符數組中的一部分轉成字符串。
2:一般方法:
按照面向對象的思想:
/ 105
學習Java EE 心得體會
這學期通過對Java EE五部分的學習,掌握了java 的基本開發方法,學習JavaEE 基礎部分分為6大部分,分別是基礎服務,Java Web開發,Web Service,JSF框架,EJB部分和JPA。
其中第一部分是基礎服務部分,此部分包括六章:第一章是概述,介紹了java EE 的發展歷史,架構,組件,服務,容器等概念,并介紹了平臺角色以及開發環境和應用服務的選擇與安裝。第二章講了使用JNDI 訪問明明和目錄服務,介紹了什么是命名和服務目錄,以及如何通過JNDI 訪問Weblogic 提供的命名目錄服務。
第三章 講了使用JDBC 訪問數據庫,介紹了JDBC的基本用法以及連接池的配置和訪問。第四章講了使用JTA 進行事物處理,介紹了事物處理概念以及如何通過JTA進行事務處理。第五章 RMI :遠程方法調用,介紹了RMI 的結構以及如何使用RMI進行編程。第六章,使用JMS接發消息,介紹了消息服務的概念,在Weblogic 中消息服務相關的配置以及如何通過JMS開發消息發送和接受程序。
J2EE是一種技術,旨在簡化企業應用程序的設計和實施。在本教程中,您將學習J2EE是什么,它的好處,J2EE的主要組成部分,企業應用框架的演變,為什么要使用J2EE,J2EE平臺架構,J2EE API和技術和J2EE參考實現。在繼續之前,我們的J2EE討論讓定義企業應用程序是什么。企業應用程序是一個應用程序,它可能要繼續使用他們,同時添加或遷移到一個新的利用互聯網,電子商務等新技術的應用,集傳統的現有應用程序和數據庫。
Java EE 架構分為四層,客戶端層,Web層,EJB層和數據庫層,其中,數據庫層為系統提供數據存儲和數據庫管理功能,在整個企業級應用中可能村愛很多個數據庫,并且采用不同類型的數據庫管理系統進行管理。EJB層也稱為業務邏輯層,用于完成系統中復雜的或者共享的業務,這些功能主要是提供客戶端層和Web層調用,用戶不會直接調用該層。Web層是基于HTTP 的訪問方式,客戶通過Web層訪問系統的業務邏輯和數據等??蛻舳藢影ˋpplet客戶端和Application客戶端,客戶通過客戶端的形式訪問系統的業務邏輯和數據等。邏輯中的四層可能不同時出現在系統中,例如某個系統可能只提供Web形式的客戶端,并且不使用EJB技術,此時系統圖只留下Web層和數據庫層。
Java運行環境定義了五種類型的應用組件,包括客戶端組件Application和Applet,Web層組件JSP和Servlet,EJB組件等,這些組件類型是Java EE 產品必須支持的。
其中的JPA是我學習的重點。JPA包括以下3方面的技術:(1).ORM映射元數據,JPA支持XML和JDK 5.0注解兩種元數據的形式,元數據描述對象和表之間的映射關系,框架據此將實體對象持久化到數據庫表中.(2).JPA 的API,用來操作實體對象,執行CRUD操作,框架在后臺替我們完成所有的事情,開發者從繁瑣的JDBC和SQL代碼中解脫出來。(3).查詢語言,這是持久化操作中很重要的一個方面,通過面向對象而非面向數據庫的查詢語言查詢數據,避免程序的SQL語句緊密耦合。JPA的優勢包括:1 標準化,JPA 是 JCP 組織發布的 Java EE 標準之一,因此任何聲稱符合 JPA 標準的框架都遵循同樣的架構,提供相同的訪問 API,這保證了基于JPA開發的企業應用能夠經過少量的修改就能夠在不同的JPA框架下運行。2 對容器級特性的支持,JPA 框架中支持大數據集、事務、并發等容器級事務,這使得 JPA 超越了簡單持久化框架的局限,在企業應用發揮更大的作用。3 簡單易用,集成方便,JPA的主要目標之一就是提供更加簡單的編程模型:在JPA框架下創建實體和創建Java 類一樣簡單,沒有任何的約束和限制,只需要使用 javax.persistence.Entity進行注釋;JPA的框架和接口也都非常簡單,沒有太多特別的規則和設計模式的要求,開發者可以很容易的掌握。JPA基于非侵入式原則設計,因此可以很容易的和其它框架或者容器集成。4 可媲美JDBC的查詢能力,JPA的查詢語言是面向對象而非面向數據庫的,它以面向對象的自然語法構造查詢語句,可以看成是Hibernate HQL的等價物。JPA定義了獨特的JPQL(Java Persistence Query Language),JPQL是EJB QL的一種擴展,它是針對實體的一種查詢語言,操作對象是實體,而不是關系數據庫的表,而且能夠支持批量更新和修改、JOIN、GROUP BY、HAVING 等通常只有 SQL 才能夠提供的高級查詢特性,甚至還能夠支持子查詢。5 支持面向對象的高級特性,JPA 中能夠支持面向對象的高級特性,如類之間的繼承、多態和類之間的復雜關系,這樣的支持能夠讓開發者最大限度的使用面向對象的模型設計企業應用,而不需要自行處理這些特性在關系數據庫的持久化。
第二部分是Java Web 開發,其中第七章主要講了Java Web應用概述,介紹Java Web的主要技術,發展歷史,文檔結構,并通過一個簡單的例子介紹了Servlet和JSP的運行原理。第八章主要講了JSP的基本語法,對JSP的基本語法,指令,動作,內部對象和如何在MyEclipse中開發進行了介紹。第九章主要講了JavaServlet技術,介紹如何編寫Servlet,如何使用Servlet與客戶端進行交互以及Servlet過濾器和Servle監聽器的使用。第十章主要講EL,介紹EL的基本用法。其中的JSP是我學習的重點。JSP技術使用Java編成語言編寫類XML的tags和scriptlets,來封裝產生動態網頁的處理邏輯。網頁還能通過tags和scriptlets訪問存在于服務端的資源的應用邏輯。JSP將網頁邏輯與網頁設計和顯示分離,支持可重用的基于組件的設計,使基于Web的應用程序的開發變得迅速和容易。Web服務器在遇到訪問JSP網頁的請求時,首先執行其中的程序段,然后將執行結果連同JSP文件中的HTML代碼一起返回給客戶。插入的Java程序段可以操作數據庫、重新定向網頁等,以實現建立動態網頁所需要的功能。JSP與JavaServlet一樣,是在服務器端執行的,通常返回給客戶端的就是一個HTML文本,因此客戶端只要有瀏覽器就能瀏覽。JSP頁面由HTML代碼和嵌入其中的Java代碼所組成。服務器在頁面被客戶端請求以后對這些Java代碼進行處理,然后將生成的HTML頁面返回給客戶端的瀏覽器。Java Servlet是JSP的技術基礎,而且大型的Web應用程序的開發需要Java Servlet和JSP配合才能完成。JSP具備了Java技術的簡單易用,完全的面向對象,具有平臺無關性且安全可靠,主要面向因特網的所有特點。利用JSP技術,動態信息由JSP頁面來表現,JSP頁面由安裝在Web服務器或者使用JSP的應用服務器上的JSP引擎執行。JSP引擎接受客戶端對JSP頁面的請求,并且生成JSP頁面作為對客戶端的響應。JSP頁面通常被編譯成為Java Servlets,這是一個標準的Java擴展。頁面開發人員能夠訪問全部的Java應用環境,以利用Java技術的擴展性和可移植性。當JSP頁面第一次被調用時,如果它還不存在,就會被編譯成為一個Java Servlets類,并且存儲在服務器的內存中。這就使得在接下來的對該頁面的調用中,服務器會有非??斓捻憫ㄟ@避免了CGI-BIN為每個HTTP請求生成一個新的進程的問題)。JSP頁面可以包含在多種不同的應用體系結構或者模型中,可以用于由不同協議、組件和格式所組成的聯合體中?;贘SP的動態信息發布技術是一個開放的、可擴展的建立動態Web頁面的標準。不論采用什么創建工具,開發人員都可以使用JSP頁面來創建可移植的Web應用,在不同的Web應用服務器上運行。
第三部分主要講Web Service,本部分內容主要包括三章。第十三章主要講Web Service概述沒介紹了什么是Web Service以及相關概念,包括WSDL,SOAP和UDDI.第十四章主要講Java EE 對Web Service的支持,包括JAXR,JAXB和SAAJ.第十五章主要是使用JAX-WS開發Web Service,介紹如何使用JAX-WS 編寫WebService以及訪問WebService的客戶端,包括在MyEcilipse中的開發。Webservice 的概念是使用一個標準的輸出接口來定義代碼提供的功能,以便讓外界可以通過這個標準的輸出接口來調用,而所謂的標準輸出接口就是wsdl,wsdl是一個xml組成的文件,描述了實現程序對外提供函數的原型,客戶端可以通過wsdl來調用實現程序提供的服務代碼。
第四部分主要講了JSF 框架,內容包括五章。第十六章講了JSF概述,介紹了JSF 的體系結構,JSF的組成和生命周期等。第十七章將了一個簡單的JSF應用,介紹了在MyEclipse中如何開發JSF應用。第十八章主要講了UI組件,介紹了JSF提供的界面控件。第十九章主要講了在JSP中使用JSF,介紹了本地化,轉換器,時間監聽器,驗證器和導航的使用。第二十章主要是Bean,介紹了輔助Bean的配置,訪問和編寫。
在這部分中我主要學習了怎樣使用JSF編程,其過程主要包括以下幾點:第一步,創建web工程J2ee下創建web project,這沒什么說的了,不過以前在eclipse中總是不知道怎么創建web應用,夠傻的,原來需要插件,在myeclipse提供了全套的插件。不過Myeclipse需要破解。中國程序員似乎很少用正版的。言歸正傳,Myeclipse中需要在Open Perspective中選擇J2ee enterprse視圖。然后創建web project。這跟delphi的New一個project不太一樣,delphi把所有可以new的都放在一個窗口中,而eclipse有不同的視圖來提供管理,這算一種進步吧,插件化的進步。接下來需要 Add JSF Capability,因為這個類庫(不知道是否應該稱為類庫)支撐了JSF開發需要的組件。第二步,創建bean.在New-àother中的Myeclipse-àweb-JSF下有managed bean,創建bean可以連Java類文件一起創建,且可以將需要的屬性一起完成,myeclipse可以自動完成屬性的get,set方法。是個比較酷的功能。第三步,創建,編輯jsp文件.在工程的webroot-->web-inf下面有一個facesconfig.xml文件,這個文件是Javabean的管理文件,同時它管理了頁面之間的切換關系,起到導航頁面的作用。有趣的是這個文件居然有個漂亮的design界面,可以在上面創建新的jsp文件,且可以用拖拽方式定義頁面之間的關系,讓所有頁面的關系看起來很直觀。感覺這里是個很酷的設計。頁面的導航是根據一個字符串來作為判斷依據的,所以在配置導航關系時,只要設定From outcome的值為調用bean方法的返回值即可。值得注意的是,JSF對于導航值只允許string類型。Jsp頁面的編寫其實很方便,即使不太懂,因為myeclipse提供了拖拽式的頁面設計,如果熟練直接寫代碼也很好玩吧。我以前一直很討厭html的代碼,因為覺得太機械了,且不好記憶,這會得硬著頭皮學了,不過在這種拖拽式的設計中可以省不少力氣。記得jsp中使用Java采用””的方式,這會是:”#{}” 直接以bean來調用。第四步,本地化.如果需要考慮國際化的問題,那么需要創建一個.properties的文件,否則可以跳過這里。.properties文件需要創建到源碼文件的目錄下,否則在指定位置時便會找不到它。.properties文件的配置非常簡單,如同一個ini文件。如:“username=user name”, 如果要顯示中文的話,這里需要轉化為unicode,jdk帶了一個native2ascii的小工具可以輕松轉換,不過這個玩意每次復制的時候都要先將編輯設為“標記”。不知道有沒有更方便的工具。另外如果要支持中文的.properties文件需要以_zh_CN結尾才行。在jsp文件中使用下面形式定義:然后就如同Java中的類一樣使用了.第五部分主要是EJB部分,內容包括四章,地二十一章介紹了EJB 的目標,發展歷史,特點,角色,分類以及變成規約。第二十二章主要對會話Bean的開發以及運行原理進行了介紹。第二十三章介紹了消息驅動Bean以及客戶端程序的編寫。第二十四章講解了如何訪問數據源,定時服務和事務處理對象。其中EJB為學習的重點,EJB(Enterprise JavaBean)是J2EE的一部分,定義了一個用于開發基于組件的企業多重應用程序的標準。其特點包括網絡服務支持和核心開發工具(SDK)。在J2EE里,Enterprise Java Beans(EJB)稱為Java 企業柄,是Java的核心代碼,分為整體柄和片段柄和消息柄三個部分,其中的消息柄將在以后再作討論。EJB是sun的服務器端組件模型,最大的用處是部署。
JavaEE學習順序
第一階段:java基礎
技術:
1.java語法 2.面向對象 3.常用的api 4.界面編程 5.多線程 6.文件io 7.java網絡編程 視頻:
張孝祥 或者馬士兵java視頻 書籍:
《java2核心技術一二卷》 《java編程思想》研讀,精讀 《java模式》
第二階段:數據庫
技術:
1.oracle——主要的 2.mysql 3.sql server 視頻: 韓順平oracle視頻 書籍:Oracle使用教程
深入淺出Oracle 第三階段:web開發
技術:
1.html 2.css 3.javascript 視頻:
張孝祥 JavaScript視頻 書籍:
張孝祥配套書籍《JavaScript網頁開發》 別具光芒
孫鑫《HTML語言速成》
第四階段:JavaEE中級
技術:
1.servet 2.jsp 3.mvc 服務器:tomcat、jboss、weblogic、websphere 視頻:
韓順平servlet—jsp視頻 書籍: oreilly公司《jsp設計》《java servlet編程》
第五階段:JavaEE高級
技術
1.struts 2.hibernate 3.spring 視頻:
美河圖書《Servlet與JSP核心編程》
張小靜 Struts視頻
孫衛琴《精通Struts基于MVC的Java.Web設計與開發》 李興華 Hibernate視頻
孫衛琴《精通Java對象持久化技術詳解》
第六階段:其他流行技術
技術:
Xml ajax(jquery,dw)Junit ant Ejb
Enterprise JavaBeans技術2.0
Java消息服務(JMS)1.0
Java命名目錄接口(JNDI)1.2
Java事務API(JTA)1.0
JavaMail API 1.2
JavaBeans激活架構(JAF)1.0
J2EE連接器體系結構(JCA)1.0
Java認證和授權服務(JAAS)1.0
書籍: 《精通ejb》
常見的j2eeAPI:
JavaServer Pages(JSP)技術1.2
Java Servlet技術2.3
JDBC API 2.0
Java XML處理API(JAXP)1.1
Enterprise JavaBeans技術2.0
Java消息服務(JMS)1.0
Java命名目錄接口(JNDI)1.2
Java事務API(JTA)1.0
JavaMail API 1.2
JavaBeans激活架構(JAF)1.0
J2EE連接器體系結構(JCA)1.0
Java認證和授權服務(JAAS)1.0