版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、1 . struts1 和 struts2區(qū)別:Struts2 從本質(zhì)上講已不是從 Struts1 擴(kuò)展而來(lái)的, 說(shuō)它是一個(gè)換了品牌標(biāo)簽的 WebWork 更合適。從 Struts1 升級(jí)到 Struts2:Struts1 里使用 ActionServlet 作為控制器; Struts2 使用了一個(gè)過(guò)濾器作為控制器Struts1 中每個(gè) HTML 表單都對(duì)應(yīng)一個(gè) ActionForm 實(shí)例. Struts2 中, HTML 表單將被直接映射到一個(gè) POJO.Struts1 的驗(yàn)證邏輯編寫(xiě)在 ActionForm 中; Struts2 中的驗(yàn)證邏輯編寫(xiě)在 Action 中.Struts1 中,
2、Action 類必須繼承類; Struts2 中任何一個(gè) POJO 都可以是一個(gè) Action 類. Struts2 在頁(yè)面里使用 OGNL 來(lái)顯示各種對(duì)象模型, 可以不再使用 EL 和 JSTLPS:POJO(Plain Ordinary Java Object)簡(jiǎn)單的Java對(duì)象,實(shí)際就是普通JavaBeans2. struts1的缺陷: 1).單元測(cè)試?yán)щy: HttpServletRequest和HttpServletResponse是由Servlet容器負(fù)責(zé)實(shí)例化的,因此Acton類的測(cè)試就要依賴于Web容器,單元測(cè)試很難實(shí)現(xiàn)。當(dāng)然,也可以使用第三方的測(cè)試工具-JUnit的擴(kuò)展工具St
3、rutsTestCase來(lái)對(duì)Action進(jìn)行單元測(cè)試,但是測(cè)試相對(duì)來(lái)說(shuō)比較困難這是不爭(zhēng)的事實(shí)! 2) Action是單例模式并且必須是線程安全的 因?yàn)閮H有Action的一個(gè)實(shí)例來(lái)處理求。單例策略限制了Struts1Action能作的事,并且要在開(kāi)發(fā)時(shí)特別小心。Action資源必須是線程安全的或同步的。 3).對(duì)Servlet的依賴性太大 4). Struts1使用ActionForm對(duì)象捕獲輸入 所有的ActionForm必須繼承一個(gè)基類。因?yàn)槠渌鸍avaBean不能用作ActionForm,開(kāi)發(fā)者經(jīng)常創(chuàng)建多余的類捕獲輸入。動(dòng)態(tài)Bean(DynaBeans)可以作為創(chuàng)建傳統(tǒng)ActionForm
4、的選擇,但是,開(kāi)發(fā)者可能是在重新描述(創(chuàng)建)已經(jīng)存在的JavaBean(仍然會(huì)導(dǎo)致有冗余的javabean) 5)每配置一下 struts-config,須重新啟動(dòng)tomcat,而且配置煩所,頁(yè)面轉(zhuǎn)向過(guò)多,導(dǎo)致forword配置過(guò)多使得 struts-config文件內(nèi)容過(guò)多,尋找東西比較困難 6)到了struts3.0的時(shí)候,發(fā)現(xiàn)建一個(gè)action就必須要有相應(yīng)的actionform與之對(duì)應(yīng)。導(dǎo)致沒(méi)必要有actionform的action都要建立actionform。要不然web頁(yè)面是提交不到action的。3. 分布式存儲(chǔ)集群文件系統(tǒng)是指運(yùn)行在多臺(tái)計(jì)算機(jī)之上,之間通過(guò)某種方式相互通信從而將
5、集群內(nèi)所有存儲(chǔ)空間資源整合、虛擬化并對(duì)外提供文件訪問(wèn)服務(wù)的文件系統(tǒng)。其與NTFS、EXT等本地文件系統(tǒng)的目的不同,前者是為了擴(kuò)展性,后者運(yùn)行在單機(jī)環(huán)境,純粹管理塊和文件之間的映射以及文件屬性。集群文件系統(tǒng)分為多類,按照對(duì)存儲(chǔ)空間的訪問(wèn)方式,可分為共享存儲(chǔ)型集群文件系統(tǒng)和分布式集群文件系統(tǒng),前者是多臺(tái)計(jì)算機(jī)識(shí)別到同樣的存儲(chǔ)空間,并相互協(xié)調(diào)共同管理其上的文件,又被稱為共享文件系統(tǒng);后者則是每臺(tái)計(jì)算機(jī)各自提供自己的存儲(chǔ)空間,并各自協(xié)調(diào)管理所有計(jì)算機(jī)節(jié)點(diǎn)中的文件。Veritas的VxFS/VCS,昆騰Stornext,中科藍(lán)鯨BWFS,EMC的MPFS,屬于共享存儲(chǔ)型集群文件系統(tǒng)。而HDFS、Glus
6、ter、Ceph、Swift等互聯(lián)網(wǎng)常用的大規(guī)模集群文件系統(tǒng)無(wú)一例外都屬于分布式集群文件系統(tǒng)。分布式集群文件系統(tǒng)可擴(kuò)展性更強(qiáng),目前已知最大可擴(kuò)展至10K節(jié)點(diǎn)。按照元數(shù)據(jù)的管理方式,可分為對(duì)稱式集群文件系統(tǒng)和非對(duì)稱式集群文件系統(tǒng)。前者每個(gè)節(jié)點(diǎn)的角色均等,共同管理文件元數(shù)據(jù),節(jié)點(diǎn)間通過(guò)高速網(wǎng)絡(luò)進(jìn)行信息同步和互斥鎖等操作,典型代表是Veritas的VCS。而非對(duì)稱式集群文件系統(tǒng)中,有專門(mén)的一個(gè)或者多個(gè)節(jié)點(diǎn)負(fù)責(zé)管理元數(shù)據(jù),其他節(jié)點(diǎn)需要頻繁與元數(shù)據(jù)節(jié)點(diǎn)通信以獲取最新的元數(shù)據(jù)比如目錄列表文件屬性等等,后者典型代表比如HDFS、GFS、BWFS、Stornext等。對(duì)于集群文件系統(tǒng),其可以是分布式+對(duì)稱式、
7、分布式+非對(duì)稱式、共享式+對(duì)稱式、共享式+非對(duì)稱式,兩兩任意組合。按照文件訪問(wèn)方式來(lái)分類,集群文件系統(tǒng)可分為串行訪問(wèn)式和并行訪問(wèn)式,后者又被俗稱為并行文件系統(tǒng)。串行訪問(wèn)是指客戶端只能從集群中的某個(gè)節(jié)點(diǎn)來(lái)訪問(wèn)集群內(nèi)的文件資源,而并行訪問(wèn)則是指客戶端可以直接從集群中任意一個(gè)或者多個(gè)節(jié)點(diǎn)同時(shí)收發(fā)數(shù)據(jù),做到并行數(shù)據(jù)存取,加快速度。HDFS、GFS、pNFS等集群文件系統(tǒng),都支持并行訪問(wèn),需要安裝專用客戶端,傳統(tǒng)的NFS/CIFS客戶端不支持并行訪問(wèn)。對(duì)于分布式集群,其對(duì)文件元數(shù)據(jù)的管理方式又可以分為single path image和single filesystem image兩種方式,具體可以參考
8、大話存儲(chǔ)終極版中對(duì)集群文件系統(tǒng)的描述。以上總結(jié)于大話存儲(chǔ)終極版4. JVM底層結(jié)構(gòu)Java虛擬機(jī)(Java Virtual Machine) 簡(jiǎn)稱JVM Java虛擬機(jī)是一個(gè)想象中的機(jī)器,在實(shí)際的計(jì)算機(jī)上通過(guò)軟件模擬來(lái)實(shí)現(xiàn)。Java虛擬機(jī)有自己想象中的硬件,如處理器、堆棧、寄存器等,還具有相應(yīng)的指令系統(tǒng)。下面我們就來(lái)看一下這幾部分比較重要的java虛擬機(jī)的結(jié)構(gòu)JVM寄存器所有的CPU均包含用于保存系統(tǒng)狀態(tài)和處理器所需信息的寄存器組。如果虛擬機(jī)定義義較多的寄存器,便可以從中得到更多的信息而不必對(duì)?;騼?nèi)存進(jìn)行訪問(wèn),這有利于提高運(yùn)行速度。然而,如果虛擬機(jī)中的寄存器比實(shí)際CPU的寄存器多,在實(shí)現(xiàn)虛擬機(jī)
9、時(shí)就會(huì)占用處理器大量的時(shí)間來(lái)用常規(guī)存儲(chǔ)器模擬寄存器,這反而會(huì)降低虛擬機(jī)的效率。針對(duì)這種情況,JVM只設(shè)置了4個(gè)最為常用的寄存器。它們是:pc程序計(jì)數(shù)器,optop操作數(shù)棧頂指針 ,frame當(dāng)前執(zhí)行環(huán)境指針, vars指向當(dāng)前執(zhí)行環(huán)境中第一個(gè)局部變量的指針, 所有寄存器均為32位。pc用于記錄程序的執(zhí)行。optop,frame和vars用于記錄指向Java棧區(qū)的指針。JVM棧結(jié)構(gòu)作為基于棧結(jié)構(gòu)的計(jì)算機(jī),Java棧是JVM存儲(chǔ)信息的主要方法。當(dāng)JVM得到一個(gè)java字節(jié)碼應(yīng)用程序后,便為該代碼中一個(gè)類的每一個(gè)方法創(chuàng)建一個(gè)??蚣?,以保存該方法的狀態(tài)信息。每個(gè)??蚣馨ㄒ韵氯愋畔ⅲ壕植孔兞繄?zhí)行環(huán)境
10、操作數(shù)棧 局部變量用于存儲(chǔ)一個(gè)類的方法中所用到的局部變量。vars寄存器指向該變量表中的第一個(gè)局部變量。執(zhí)行環(huán)境用于保存解釋器對(duì)Java字節(jié)碼進(jìn)行解釋過(guò)程中所需的信息。它們是:上次調(diào)用的方法、局部變量指針和操作數(shù)棧的棧頂和棧底指針。執(zhí)行環(huán)境是一個(gè)執(zhí)行一個(gè)方法的控制中心。例如:如果解釋器要執(zhí)行iadd(整數(shù)加法),首先要從frame寄存器中找到當(dāng)前執(zhí)行環(huán)境,而后便從執(zhí)行環(huán)境中找到操作數(shù)棧,從棧頂彈出兩個(gè)整數(shù)進(jìn)行加法運(yùn)算,最后將結(jié)果壓入棧頂。操作數(shù)棧用于存儲(chǔ)運(yùn)算所需操作數(shù)及運(yùn)算的結(jié)果。JVM碎片回收堆Java類的實(shí)例所需的存儲(chǔ)空間是在堆上分配的。解釋器具體承擔(dān)為類實(shí)例分配空間的工作。解釋器在為一個(gè)
11、實(shí)例分配完存儲(chǔ)空間后,便開(kāi)始記錄對(duì)該實(shí)例所占用的內(nèi)存區(qū)域的使用。一旦對(duì)象使用完畢,便將其回收到堆中。在Java語(yǔ)言中,除了new語(yǔ)句外沒(méi)有其他方法為一對(duì)象申請(qǐng)和釋放內(nèi)存。對(duì)內(nèi)存進(jìn)行釋放和回收的工作是由Java運(yùn)行系統(tǒng)承擔(dān)的。這允許Java運(yùn)行系統(tǒng)的設(shè)計(jì)者自己決定碎片回收的方法。在SUN公司開(kāi)發(fā)的Java解釋器和Hot Java環(huán)境中,碎片回收用后臺(tái)線程的方式來(lái)執(zhí)行。這不但為運(yùn)行系統(tǒng)提供了良好的性能,而且使程序設(shè)計(jì)人員擺脫了自己控制內(nèi)存使用的風(fēng)險(xiǎn)。JVM存儲(chǔ)區(qū)JVM有兩類存儲(chǔ)區(qū):常量緩沖池和方法區(qū)。常量緩沖池用于存儲(chǔ)類名稱、方法和字段名稱以及串常量。方法區(qū)則用于存儲(chǔ)Java方法的字節(jié)碼。對(duì)于這兩
12、種存儲(chǔ)區(qū)域具體實(shí)現(xiàn)方式在JVM規(guī)格中沒(méi)有明確規(guī)定。這使得Java應(yīng)用程序的存儲(chǔ)布局必須在運(yùn)行過(guò)程中確定,依賴于具體平臺(tái)的實(shí)現(xiàn)方式。JVM是為Java字節(jié)碼定義的一種獨(dú)立于具體平臺(tái)的規(guī)格描述,是Java平臺(tái)獨(dú)立性的基礎(chǔ)。目前的JVM還存在一些限制和不足,有待于進(jìn)一步的完善,但無(wú)論如何,JVM的思想是成功的。對(duì)比分析:如果把Java原程序想象成我們的C+原程序,Java原程序編譯后生成的字節(jié)碼就相當(dāng)于C+原程序編譯后的80x86的機(jī)器碼(二進(jìn)制程序文件),JVM虛擬機(jī)相當(dāng)于80x86計(jì)算機(jī)系統(tǒng),Java解釋器相當(dāng)于80x86CPU。在80x86CPU上運(yùn)行的是機(jī)器碼,在Java解釋器上運(yùn)行的是Ja
13、va字節(jié)碼。Java解釋器相當(dāng)于運(yùn)行Java字節(jié)碼的“CPU”,但該“CPU”不是通過(guò)硬件實(shí)現(xiàn)的,而是用軟件實(shí)現(xiàn)的。Java解釋器實(shí)際上就是特定的平臺(tái)下的一個(gè)應(yīng)用程序。只要實(shí)現(xiàn)了特定平臺(tái)下的解釋器程序,Java字節(jié)碼就能通過(guò)解釋器程序在該平臺(tái)下運(yùn)行,這是Java跨平臺(tái)的根本。當(dāng)前,并不是在所有的平臺(tái)下都有相應(yīng)Java解釋器程序,這也是Java并不能在所有的平臺(tái)下都能運(yùn)行的原因,它只能在已實(shí)現(xiàn)了Java解釋器程序的平臺(tái)下運(yùn)行。Java虛擬機(jī)從啟動(dòng)到結(jié)束的生命周期,當(dāng)java虛擬機(jī)啟動(dòng)后,在如下幾種情況下,Java虛擬機(jī)將結(jié)束生命周期:1.執(zhí)行了System.exit()方法 2.程序正常執(zhí)行結(jié)束
14、 3.程序在執(zhí)行過(guò)程中遇到了異?;蝈e(cuò)誤而異常終止4.由于操作系統(tǒng)出現(xiàn)錯(cuò)誤而導(dǎo)致Java虛擬機(jī)進(jìn)程終止 Java虛擬機(jī)的棧有三個(gè)區(qū)域:局部變量區(qū)、運(yùn)行環(huán)境區(qū)、操作數(shù)區(qū)。局部變量區(qū)每個(gè)Java方法使用一個(gè)固定大小的局部變量集。它們按照與vars寄存器的字偏移量來(lái)尋址。局部變量都是32位的。長(zhǎng)整數(shù)和雙精度浮點(diǎn)數(shù)占據(jù)了兩個(gè)局部變量的空間,卻按照第一個(gè)局部變量的索引來(lái)尋址。(例如,一個(gè)具有索引n的局部變量,如果是一個(gè)雙精度浮點(diǎn)數(shù),那么它實(shí)際占據(jù)了索引n和n+1所代表的存儲(chǔ)空間)虛擬機(jī)規(guī)范并不要求在局部變量中的64位的值是64位對(duì)齊的。虛擬機(jī)提供了把局部變量中的值裝載到操作數(shù)棧的指令,也提供了把操作數(shù)棧中
15、的值寫(xiě)入局部變量的指令。運(yùn)行環(huán)境區(qū)在運(yùn)行環(huán)境中包含的信息用于動(dòng)態(tài)鏈接,正常的方法返回以及異常捕捉。操作數(shù)棧區(qū)機(jī)器指令只從操作數(shù)棧中取操作數(shù),對(duì)它們進(jìn)行操作,并把結(jié)果返回到棧中。選擇棧結(jié)構(gòu)的原因是:在只有少量寄存器或非通用寄存器的機(jī)器(如Intel486)上,也能夠高效地模擬虛擬機(jī)的行為。操作數(shù)棧是32位的。它用于給方法傳遞參數(shù),并從方法接收結(jié)果,也用于支持操作的參數(shù),并保存操作的結(jié)果。例如,iadd指令將兩個(gè)整數(shù)相加。相加的兩個(gè)整數(shù)應(yīng)該是操作數(shù)棧頂?shù)膬蓚€(gè)字。這兩個(gè)字是由先前的指令壓進(jìn)堆棧的。這兩個(gè)整數(shù)將從堆棧彈出、相加,并把結(jié)果壓回到操作數(shù)棧中。每個(gè)原始數(shù)據(jù)類型都有專門(mén)的指令對(duì)它們進(jìn)行必須的操
16、作。每個(gè)操作數(shù)在棧中需要一個(gè)存儲(chǔ)位置,除了long和double型,它們需要兩個(gè)位置。操作數(shù)只能被適用于其類型的操作符所操作。例如,壓入兩個(gè)int類型的數(shù),如果把它們當(dāng)作是一個(gè)long類型的數(shù)則是非法的。在Sun的虛擬機(jī)實(shí)現(xiàn)中,這個(gè)限制由字節(jié)碼驗(yàn)證器強(qiáng)制實(shí)行。但是,有少數(shù)操作(操作符dupe和swap),用于對(duì)運(yùn)行時(shí)數(shù)據(jù)區(qū)進(jìn)行操作時(shí)是不考慮類型的。本地方法棧,當(dāng)一個(gè)線程調(diào)用本地方法時(shí),它就不再受到虛擬機(jī)關(guān)于結(jié)構(gòu)和安全限制方面的約束,它既可以訪問(wèn)虛擬機(jī)的運(yùn)行期數(shù)據(jù)區(qū),也可以使用本地處理器以及任何類型的棧。例如,本地棧是一個(gè)C語(yǔ)言的棧,那么當(dāng)C程序調(diào)用C函數(shù)時(shí),函數(shù)的參數(shù)以某種順序被壓入棧,結(jié)果則
17、返回給調(diào)用函數(shù)。在實(shí)現(xiàn)Java虛擬機(jī)時(shí),本地方法接口使用的是C語(yǔ)言的模型棧,那么它的本地方法棧的調(diào)度與使用則完全與C語(yǔ)言的棧相同。 Java虛擬機(jī)的運(yùn)行過(guò)程:上面對(duì)虛擬機(jī)的各個(gè)部分進(jìn)行了比較詳細(xì)的說(shuō)明,下面通過(guò)一個(gè)具體的例子來(lái)分析它的運(yùn)行過(guò)程。虛擬機(jī)通過(guò)調(diào)用某個(gè)指定類的方法main啟動(dòng),傳遞給main一個(gè)字符串?dāng)?shù)組參數(shù),使指定的類被裝載,同時(shí)鏈接該類所使用的其它的類型,并且初始化它們。例如對(duì)于程序:class HelloApp public static void main(String args) "Hello World!"); for (int i = 0; i &l
18、t; args.length; i+ ) argsi); 編譯后在命令行模式下鍵入: java HelloApp run virtual machine將通過(guò)調(diào)用HelloApp的方法main來(lái)啟動(dòng)java虛擬機(jī),傳遞給main一個(gè)包含三個(gè)字符串"run"、"virtual"、"machine"的數(shù)組?,F(xiàn)在我們略述虛擬機(jī)在執(zhí)行HelloApp時(shí)可能采取的步驟。 開(kāi)始試圖執(zhí)行類HelloApp的main方法,發(fā)現(xiàn)該類并沒(méi)有被裝載,也就是說(shuō)虛擬機(jī)當(dāng)前不包含該類的二進(jìn)制代表,于是虛擬機(jī)使用ClassLoader試圖尋找這樣的二進(jìn)制代表。如果
19、這個(gè)進(jìn)程失敗,則拋出一個(gè)異常。類被裝載后同時(shí)在main方法被調(diào)用之前,必須對(duì)類HelloApp與其它類型進(jìn)行鏈接然后初始化。鏈接包含三個(gè)階段:檢驗(yàn),準(zhǔn)備和解析。檢驗(yàn)檢查被裝載的主類的符號(hào)和語(yǔ)義,準(zhǔn)備則創(chuàng)建類或接口的靜態(tài)域以及把這些域初始化為標(biāo)準(zhǔn)的默認(rèn)值,解析負(fù)責(zé)檢查主類對(duì)其它類或接口的符號(hào)引用,在這一步它是可選的。類的初始化是對(duì)類中聲明的靜態(tài)初始化函數(shù)和靜態(tài)域的初始化構(gòu)造方法的執(zhí)行。一個(gè)類在初始化之前它的父類必須被初始化。整個(gè)過(guò)程如下:5. 面向?qū)ο蟮娜筇卣鳌⑽宕蠡驹瓌t:三大特性是:封裝,繼承,多態(tài) 所謂封裝,也就是把客觀事物封裝成抽象的類,并且類可以把自己的數(shù)據(jù)和方法只讓可信的類或者對(duì)象
20、操作,對(duì)不可信的進(jìn)行信息隱藏。封裝是面向?qū)ο蟮奶卣髦?,是?duì)象和類概念的主要特性。 簡(jiǎn)單的說(shuō),一個(gè)類就是一個(gè)封裝了數(shù)據(jù)以及操作這些數(shù)據(jù)的代碼的邏輯實(shí)體。在一個(gè)對(duì)象內(nèi)部,某些代碼或某些數(shù)據(jù)可以是私有的,不能被外界訪問(wèn)。通過(guò)這種方式,對(duì)象對(duì)內(nèi)部數(shù)據(jù)提供了不同級(jí)別的保護(hù),以防止程序中無(wú)關(guān)的部分意外的改變或錯(cuò)誤的使用了對(duì)象的私有部分。所謂繼承是指可以讓某個(gè)類型的對(duì)象獲得另一個(gè)類型的對(duì)象的屬性的方法。它支持按級(jí)分類的概念。繼承是指這樣一種能力:它可以使用現(xiàn)有類的所有功能,并在無(wú)需重新編寫(xiě)原來(lái)的類的情況下對(duì)這些功能進(jìn)行擴(kuò)展。 通過(guò)繼承創(chuàng)建的新類稱為“子類”或“派生類”,被繼承的類稱為“基類”、“父類”或“
21、超類”。繼承的過(guò)程,就是從一般到特殊的過(guò)程。要實(shí)現(xiàn)繼承,可以通過(guò)“繼承”(Inheritance)和“組合”(Composition)來(lái)實(shí)現(xiàn)。繼承概念的實(shí)現(xiàn)方式有二類:實(shí)現(xiàn)繼承與接口繼承。實(shí)現(xiàn)繼承是指直接使用基類的屬性和方法而無(wú)需額外編碼的能力;接口繼承是指僅使用屬性和方法的名稱、但是子類必須提供實(shí)現(xiàn)的能力;所謂多態(tài)就是指一個(gè)類實(shí)例的相同方法在不同情形有不同表現(xiàn)形式。多態(tài)機(jī)制使具有不同內(nèi)部結(jié)構(gòu)的對(duì)象可以共享相同的外部接口。這意味著,雖然針對(duì)不同對(duì)象的具體操作不同,但通過(guò)一個(gè)公共的類,它們(那些操作)可以通過(guò)相同的方式予以調(diào)用。五大基本原則 單一職責(zé)原則SRP(Single Responsibi
22、lity Principle):指一個(gè)類的功能要單一,不能包羅萬(wàn)象。如同一個(gè)人一樣,分配的工作不能太多,否則一天到晚雖然忙忙碌碌的,但效率卻高不起來(lái)。開(kāi)放封閉原則OCP(OpenClose Principle) :一個(gè)模塊在擴(kuò)展性方面應(yīng)該是開(kāi)放的而在更改性方面應(yīng)該是封閉的。比如:一個(gè)網(wǎng)絡(luò)模塊,原來(lái)只服務(wù)端功能,而現(xiàn)在要加入客戶端功能,那么應(yīng)當(dāng)在不用修改服務(wù)端功能代碼的前提下,就能夠增加客戶端功能的實(shí)現(xiàn)代碼,這要求在設(shè)計(jì)之初,就應(yīng)當(dāng)將服務(wù)端和客戶端分開(kāi),公共部分抽象出來(lái)。替換原則(the Liskov Substitution Principle LSP) :子類應(yīng)當(dāng)可以替換父類并出現(xiàn)在父類能夠
23、出現(xiàn)的任何地方。比如:公司搞年度晚會(huì),所有員工可以參加抽獎(jiǎng),那么不管是老員工還是新員工,也不管是總部員工還是外派員工,都應(yīng)當(dāng)可以參加抽獎(jiǎng),否則這公司就不和諧了。依賴原則(the Dependency Inversion Principle DIP): 具體依賴抽象,上層依賴下層。假設(shè)B是較A低的模塊,但B需要使用到A的功能,這個(gè)時(shí)候,B不應(yīng)當(dāng)直接使用A中的具體類: 而應(yīng)當(dāng)由B定義一抽象接口,并由A來(lái)實(shí)現(xiàn)這個(gè)抽象接口,B只使用這個(gè)抽象接口:這樣就達(dá)到了依賴倒置的目的,B也解除了對(duì)A的依賴,反過(guò)來(lái)是A依賴于B定義的抽象接口。通過(guò)上層模塊難以避免依賴下層模塊,假如B也直接依賴A的實(shí)現(xiàn),那么就可能造成
24、循環(huán)依賴。一個(gè)常見(jiàn)的問(wèn)題就是編譯A模塊時(shí)需要直接包含到B模塊的cpp文件,而編譯B時(shí)同樣要直接包含到A的cpp文件。接口分離原則(the Interface Segregation Principle ISP) :模塊間要通過(guò)抽象接口隔離開(kāi),而不是通過(guò)具體的類強(qiáng)耦合起來(lái)6、String、StringBuilder與StringBuffer的區(qū)別(1)可變與不可變:String類中使用字符數(shù)組保存字符串,如下就是,因?yàn)橛小癴inal”修飾符,所以可以知道string對(duì)象是不可變的。private final char value;StringBuilder與StringBuffer都繼承自Abs
25、tractStringBuilder類,在AbstractStringBuilder中也是使用字符數(shù)組保存字符串,如下就是,可知這兩種對(duì)象都是可變的。char value;(2).是否多線程安全String中的對(duì)象是不可變的,也就可以理解為常量,顯然線程安全。AbstractStringBuilder是StringBuilder與StringBuffer的公共父類,定義了一些字符串的基本操作,如expandCapacity、append、insert、indexOf等公共方法。StringBuffer對(duì)方法加了同步鎖或者對(duì)調(diào)用的方法加了同步鎖,所以是線程安全的??慈缦略创a:復(fù)制代碼 publi
26、c synchronized StringBuffer reverse() super.reverse(); return this; public int indexOf(String str) return indexOf(str, 0); /存在 public synchronized int indexOf(String str, int fromIndex) 方法 StringBuilder并沒(méi)有對(duì)方法進(jìn)行加同步鎖,所以是非線程安全的。 (3)StringBuilder與StringBuffer共同點(diǎn)StringBuilder與StringBuffer有公共父類AbstractStr
27、ingBuilder(抽象類)。抽象類與接口的其中一個(gè)區(qū)別是:抽象類中可以定義一些子類的公共方法,子類只需要增加新的功能,不需要重復(fù)寫(xiě)已經(jīng)存在的方法;而接口中只是對(duì)方法的申明和常量的定義。StringBuilder、StringBuffer的方法都會(huì)調(diào)用AbstractStringBuilder中的公共方法,如super.append(.)。只是StringBuffer會(huì)在方法上加synchronized關(guān)鍵字,進(jìn)行同步。最后,如果程序不是多線程的,那么使用StringBuilder效率高于StringBuffer。7. Map 集合(1)什么是Java集合API:Java集合框架API是用來(lái)
28、表示和操作集合的統(tǒng)一框架,它包含接口、實(shí)現(xiàn)類、以及幫助程序員完成一些編程的算法。簡(jiǎn)言之,API在上層完成以下幾件事: 編程更加省力,提高城程序速度和代碼質(zhì)量非關(guān)聯(lián)的API提高互操作性 節(jié)省學(xué)習(xí)使用新API成本 節(jié)省設(shè)計(jì)新API的時(shí)間 鼓勵(lì)、促進(jìn)軟件重用具體來(lái)說(shuō),有6個(gè)集合接口,最基本的是Collection接口,由三個(gè)接口Set、List、SortedSet繼承,另外兩個(gè)接口是Map、SortedMap,這兩個(gè)接口不繼承Collection,表示映射而不是真正的集合。(2) 什么是Iterator一些集合類提供了內(nèi)容遍歷的功能,通過(guò)接口。這些接口允許遍歷對(duì)象的集合。依次操作每個(gè)元素對(duì)象。當(dāng)使用
29、 Iterators時(shí),在獲得Iterator的時(shí)候包含一個(gè)集合快照。通常在遍歷一個(gè)Iterator的時(shí)候不建議修改集合本省。(3)、Iterator與ListIterator有什么區(qū)別?Iterator:只能正向遍歷集合,適用于獲取移除元素。ListIerator:繼承Iterator,可以雙向列表的遍歷,同樣支持元素的修改。(4) 什么是HaspMap和Map?Map是接口,Java 集合框架中一部分,用于存儲(chǔ)鍵值對(duì),HashMap是用哈希算法實(shí)現(xiàn)Map的類。(5)、HashMap與HashTable有什么區(qū)別?對(duì)比Hashtable VS HashMap兩者都是用key-value方式獲
30、取數(shù)據(jù)。Hashtable是原始集合類之一(也稱作遺留類)。HashMap作為新集合框架的一部分在Java2的1.2版本中加入。它們之間有一下區(qū)別:HashMap和Hashtable大致是等同的,除了非同步和空值(HashMap允許null值作為key和value,而Hashtable不可以)。 HashMap沒(méi)法保證映射的順序一直不變,但是作為HashMap的子類LinkedHashMap,如果想要預(yù)知的順序迭代(默認(rèn)按照插入順序),你可以很輕易的置換為HashMap,如果使用Hashtable就沒(méi)那么容易了。 HashMap不是同步的,而Hashtable是同步的。 迭代HashMap采用
31、快速失敗機(jī)制,而Hashtable不是,所以這是設(shè)計(jì)的考慮點(diǎn)。(6)、在Hashtable上下文中同步是什么意思?同步意味著在一個(gè)時(shí)間點(diǎn)只能有一個(gè)線程可以修改哈希表,任何線程在執(zhí)行hashtable的更新操作前需要獲取對(duì)象鎖,其他線程等待鎖的釋放。(7)、什么叫做快速失敗特性從高級(jí)別層次來(lái)說(shuō)快速失敗是一個(gè)系統(tǒng)或軟件對(duì)于其故障做出的響應(yīng)。一個(gè)快速失敗系統(tǒng)設(shè)計(jì)用來(lái)即時(shí)報(bào)告可能會(huì)導(dǎo)致失敗的任何故障情況,它通常用來(lái)停止正常的操作而不是嘗試?yán)^續(xù)做可能有缺陷的工作。當(dāng)有問(wèn)題發(fā)生時(shí),快速失敗系統(tǒng)即時(shí)可見(jiàn)地發(fā)錯(cuò)錯(cuò)誤告警。在Java中,快速失敗與iterators有關(guān)。如果一個(gè)iterator在集合對(duì)象上創(chuàng)建了
32、,其它線程欲“結(jié)構(gòu)化”的修改該集合對(duì)象,并發(fā)修改異常 (ConcurrentModificationException) 拋出。(8)、怎樣使Hashmap同步?HashMap可以通過(guò)Map m = Collections.synchronizedMap(hashMap)來(lái)達(dá)到同步的效果。(9)、什么時(shí)候使用Hashtable,什么時(shí)候使用HashMap基本的不同點(diǎn)是Hashtable同步HashMap不是的,所以無(wú)論什么時(shí)候有多個(gè)線程訪問(wèn)相同實(shí)例的可能時(shí),就應(yīng)該使用Hashtable,反之使用HashMap。非線程安全的數(shù)據(jù)結(jié)構(gòu)能帶來(lái)更好的性能。如果在將來(lái)有一種可能你需要按順序獲得鍵值對(duì)的方
33、案時(shí),HashMap是一個(gè)很好的選擇,因?yàn)橛蠬ashMap的一個(gè)子類 LinkedHashMap。所以如果你想可預(yù)測(cè)的按順序迭代(默認(rèn)按插入的順序),你可以很方便用LinkedHashMap替換HashMap。反觀要是使用的Hashtable就沒(méi)那么簡(jiǎn)單了。同時(shí)如果有多個(gè)線程訪問(wèn)HashMap,Collections.synchronizedMap()可以代替,總的來(lái)說(shuō)HashMap更靈活。(10)、為什么Vector類認(rèn)為是廢棄的或者是非官方地不推薦使用?或者說(shuō)為什么我們應(yīng)該一直使用ArrayList而不是Vector你應(yīng)該使用ArrayList而不是Vector是因?yàn)槟J(rèn)情況下你是非同步訪
34、問(wèn)的,Vector同步了每個(gè)方法,你幾乎從不要那樣做,通常有想要同步的是整個(gè)操作序列。同步單個(gè)的操作也不安全(如果你迭代一個(gè)Vector,你還是要加鎖,以避免其它線程在同一時(shí)刻改變集合).而且效率更慢。當(dāng)然同樣有鎖的開(kāi)銷即使你不需要,這是個(gè)很糟糕的方法在默認(rèn)情況下同步訪問(wèn)。你可以一直使用Collections.sychronizedList來(lái)裝飾一個(gè)集合。事實(shí)上Vector結(jié)合了“可變數(shù)組”的集合和同步每個(gè)操作的實(shí)現(xiàn)。這是另外一個(gè)設(shè)計(jì)上的缺陷。Vector還有些遺留的方法在枚舉和元素獲取的方法,這些方法不同于List接口,如果這些方法在代碼中程序員更趨向于想用它。盡管枚舉速度更快,但是他們不能
35、檢查如果集合在迭代的時(shí)候修改了,這樣將導(dǎo)致問(wèn)題。盡管以上諸多原因,oracle也從沒(méi)宣稱過(guò)要廢棄Vector。8、Socket通信過(guò)程:10、查詢、插入、刪除等幾種情況,分別選用ArrayList、LinkList、Vector哪一個(gè)合適?ArrayList底層使用的是數(shù)組數(shù)據(jù)結(jié)構(gòu),因?yàn)閿?shù)組有索引(角標(biāo))所以ArrayList的查詢速度快,而添加刪除元素速度稍慢。因?yàn)?,你每刪除或者添加一個(gè)元素,你都要移動(dòng)所添加或刪除元素后面的所有數(shù)據(jù),該集合是線程不同步的LinkedList底層使用的是鏈表數(shù)據(jù)結(jié)構(gòu),鏈表數(shù)據(jù)結(jié)構(gòu)是沒(méi)有索引的,當(dāng)前元素只和他的前一個(gè)和后一個(gè)元素有關(guān)聯(lián)就像一串珠子一樣,該數(shù)據(jù)結(jié)構(gòu)
36、的特點(diǎn)是,增加刪除快,而查詢比較慢,因?yàn)樵黾觿h除只需要找到當(dāng)前元素,然后斷掉當(dāng)前元素與它前一個(gè)和后一個(gè)元素的關(guān)聯(lián)即可,和數(shù)組比,鏈表不用重復(fù)大部分的數(shù)據(jù)移動(dòng)工作,但是因?yàn)闆](méi)有索引所以鏈表數(shù)據(jù)結(jié)構(gòu)要一個(gè)一個(gè)的查詢數(shù)據(jù),所以LinkedList的查詢速度稍慢Vector:底層使用的是數(shù)組數(shù)據(jù)結(jié)構(gòu),和ArrayList的功能相當(dāng),但是Vector是線程同步的,JDK已經(jīng)對(duì)Vector的底層源碼中可能出現(xiàn)同步的操作加上了同步鎖,但是線程同步之后有弊端,那就是每當(dāng)操作Vector集合,都會(huì)去判斷同步鎖,較為浪費(fèi)系統(tǒng)資源。而我們完全可以使用ArrayList來(lái)代替Vector,如果需要同步代碼,我們也可以
37、自己手動(dòng)加上同步鎖11. Java訪問(wèn)數(shù)據(jù)庫(kù)的過(guò)程?JDBC連接數(shù)據(jù)庫(kù) 創(chuàng)建一個(gè)以JDBC連接數(shù)據(jù)庫(kù)的程序,包含7個(gè)步驟: (1)、加載JDBC驅(qū)動(dòng)程序: 在連接數(shù)據(jù)庫(kù)之前,首先要加載想要連接的數(shù)據(jù)庫(kù)的驅(qū)動(dòng)到JVM(Java虛擬機(jī)), 這通過(guò)類的靜態(tài)方法forName(String className)實(shí)現(xiàn)。 例如: try /加載MySql的驅(qū)動(dòng)類 Class.forName( catch(ClassNotFoundException e) 找不到驅(qū)動(dòng)程序類 ,加載驅(qū)動(dòng)失?。?quot;); e.printStackTrace() ; 成功加載后,會(huì)將Driver類的實(shí)例注冊(cè)到DriverM
38、anager類中。 (2)、提供JDBC連接的URL 連接URL定義了連接數(shù)據(jù)庫(kù)時(shí)的協(xié)議、子協(xié)議、數(shù)據(jù)源標(biāo)識(shí)。 書(shū)寫(xiě)形式:協(xié)議:子協(xié)議:數(shù)據(jù)源標(biāo)識(shí) 協(xié)議:在JDBC中總是以jdbc開(kāi)始 子協(xié)議:是橋連接的驅(qū)動(dòng)程序或是數(shù)據(jù)庫(kù)管理系統(tǒng)名稱。 數(shù)據(jù)源標(biāo)識(shí):標(biāo)記找到數(shù)據(jù)庫(kù)來(lái)源的地址與連接端口。 例如:(MySql的連接URL) jdbc:mysql: /localhost:3306/test?useUnicode=true&characterEncoding=gbk ; useUnicode=true:表示使用Unicode字符集。如果characterEncoding設(shè)置為 gb2312或G
39、BK,本參數(shù)必須設(shè)置為true 。characterEncoding=gbk:字符編碼方式。 (3)、創(chuàng)建數(shù)據(jù)庫(kù)的連接 要連接數(shù)據(jù)庫(kù),需要向請(qǐng)求并獲得Connection對(duì)象, 該對(duì)象就代表一個(gè)數(shù)據(jù)庫(kù)的連接。 使用DriverManager的getConnectin(String url , String username , String password )方法傳入指定的欲連接的數(shù)據(jù)庫(kù)的路徑、數(shù)據(jù)庫(kù)的用戶名和 密碼來(lái)獲得。 例如: /連接MySql數(shù)據(jù)庫(kù),用戶名和密碼都是root String url = "jdbc:mysql:/localhost:3306/test"
40、; ; String username = "root" ; String password = "root" ; try Connection con = DriverManager.getConnection(url , username , password ) ; catch(SQLException se) 數(shù)據(jù)庫(kù)連接失?。?quot;); se.printStackTrace() ; (4)、創(chuàng)建一個(gè)Statement 要執(zhí)行SQL語(yǔ)句,必須獲得實(shí)例,Statement實(shí)例分為以下3 種類型: 執(zhí)行靜態(tài)SQL語(yǔ)句。通常通過(guò)Statement實(shí)
41、例實(shí)現(xiàn)。 執(zhí)行動(dòng)態(tài)SQL語(yǔ)句。通常通過(guò)PreparedStatement實(shí)例實(shí)現(xiàn)。 執(zhí)行數(shù)據(jù)庫(kù)存儲(chǔ)過(guò)程。通常通過(guò)CallableStatement實(shí)例實(shí)現(xiàn)。 具體的實(shí)現(xiàn)方式: Statement stmt = con.createStatement() ; PreparedStatement pstmt = con.prepareStatement(sql) ; CallableStatement cstmt = con.prepareCall("CALL demoSp(? , ?)") ; (5)、執(zhí)行SQL語(yǔ)句 Statement接口提供了三種執(zhí)行SQL語(yǔ)句的方法:ex
42、ecuteQuery 、executeUpdate 和execute ResultSet executeQuery(String sqlString):執(zhí)行查詢數(shù)據(jù)庫(kù)的SQL語(yǔ)句 ,返回一個(gè)結(jié)果集(ResultSet)對(duì)象。 int executeUpdate(String sqlString):用于執(zhí)行INSERT、UPDATE或 DELETE語(yǔ)句以及SQL DDL語(yǔ)句,如:CREATE TABLE和DROP TABLE等 execute(sqlString):用于執(zhí)行返回多個(gè)結(jié)果集、多個(gè)更新計(jì)數(shù)或二者組合的 語(yǔ)句。 具體實(shí)現(xiàn)的代碼: ResultSet rs = stmt.executeQ
43、uery("SELECT * FROM .") ; int rows = stmt.executeUpdate("INSERT INTO .") ; boolean flag = stmt.execute(String sql) ; (6)、處理結(jié)果 兩種情況: 執(zhí)行更新返回的是本次操作影響到的記錄數(shù)。 執(zhí)行查詢返回的結(jié)果是一個(gè)ResultSet對(duì)象。 ResultSet包含符合SQL語(yǔ)句中條件的所有行,并且它通過(guò)一套get方法提供了對(duì)這些 行中數(shù)據(jù)的訪問(wèn)。 使用結(jié)果集(ResultSet)對(duì)象的訪問(wèn)方法獲取數(shù)據(jù): while(rs.next() Str
44、ing name = rs.getString("name") ; String pass = rs.getString(1) ; / 此方法比較高效 (列是從左到右編號(hào)的,并且從列1開(kāi)始) (7)、關(guān)閉JDBC對(duì)象 操作完成以后要把所有使用的JDBC對(duì)象全都關(guān)閉,以釋放JDBC資源,關(guān)閉順序和聲 明順序相反: 關(guān)閉記錄集 關(guān)閉聲明 關(guān)閉連接對(duì)象 if(rs != null) / 關(guān)閉記錄集 try rs.close() ; catch(SQLException e) e.printStackTrace() ; if(stmt != null) / 關(guān)閉聲明 try stm
45、t.close() ; catch(SQLException e) e.printStackTrace() ; if(conn != null) / 關(guān)閉連接對(duì)象 try conn.close() ; catch(SQLException e) e.printStackTrace() ; 11、數(shù)據(jù)庫(kù)索引什么是索引?數(shù)據(jù)庫(kù)索引好比是一本書(shū)前面的目錄,能加快數(shù)據(jù)庫(kù)的查詢速度。例如這樣一個(gè)查詢:select * from table1 where id=44。如果沒(méi)有索引,必須遍歷整個(gè)表,直到ID等于44的這一行被找到為止;有了索引之后(必須是在ID這一列上建立的索引),直接在索引里面找 44(也
46、就是在ID這一列找),就可以得知這一行的位置,也就是找到了這一行。可見(jiàn),索引是用來(lái)定位的。索引分為聚簇索引和非聚簇索引兩種,聚簇索引 是按照數(shù)據(jù)存放的物理位置為順序的,而非聚簇索引就不一樣了;聚簇索引能提高多行檢索的速度,而非聚簇索引對(duì)于單行的檢索很快。建立索引的目的是加快對(duì)表中記錄的查找或排序。為表設(shè)置索引要付出代價(jià)的:一是增加了數(shù)據(jù)庫(kù)的存儲(chǔ)空間,二是在插入和修改數(shù)據(jù)時(shí)要花費(fèi)較多的時(shí)間(因?yàn)樗饕惨S之變動(dòng))。為什么要?jiǎng)?chuàng)建索引?創(chuàng)建索引可以大大提高系統(tǒng)的性能。第一,通過(guò)創(chuàng)建唯一性索引,可以保證數(shù)據(jù)庫(kù)表中每一行數(shù)據(jù)的唯一性。第二,可以大大加快數(shù)據(jù)的檢索速度,這也是創(chuàng)建索引的最主要的原因。第三,
47、可以加速表和表之間的連接,特別是在實(shí)現(xiàn)數(shù)據(jù)的參考完整性方面特別有意義。第四,在使用分組和排序子句進(jìn)行數(shù)據(jù)檢索時(shí),同樣可以顯著減少查詢中分組和排序的時(shí)間。第五,通過(guò)使用索引,可以在查詢的過(guò)程中,使用優(yōu)化隱藏器,提高系統(tǒng)的性能。也許會(huì)有人要問(wèn):增加索引有如此多的優(yōu)點(diǎn),為什么不對(duì)表中的每一個(gè)列創(chuàng)建一個(gè)索引呢?因?yàn)?,增加索引也有許多不利的方面。第一,創(chuàng)建索引和維護(hù)索引要耗費(fèi)時(shí)間,這種時(shí)間隨著數(shù)據(jù)量的增加而增加。第二,索引需要占物理空間,除了數(shù)據(jù)表占數(shù)據(jù)空間之外,每一個(gè)索引還要占一定的物理空間,如果要建立聚簇索引,那么需要的空間就會(huì)更大。第三,當(dāng)對(duì)表中的數(shù)據(jù)進(jìn)行增加、刪除和修改的時(shí)候,索引也要?jiǎng)討B(tài)的維護(hù)
48、,這樣就降低了數(shù)據(jù)的維護(hù)速度。在哪建索引?索引是建立在數(shù)據(jù)庫(kù)表中的某些列的上面。在創(chuàng)建索引的時(shí)候,應(yīng)該考慮在哪些列上可以創(chuàng)建索引,在哪些列上不能創(chuàng)建索引。一般來(lái)說(shuō),應(yīng)該在這些列上創(chuàng)建索引:(1)在經(jīng)常需要搜索的列上,可以加快搜索的速度;(2).在作為主鍵的列上,強(qiáng)制該列的唯一性和組織表中數(shù)據(jù)的排列結(jié)構(gòu);(3)在經(jīng)常用在連接的列上,這些列主要是一些外鍵,可以加快連接的速度;在經(jīng)常需要根據(jù)范圍進(jìn)行搜索的列上創(chuàng)建索引,因?yàn)樗饕呀?jīng)排序,其指定的范圍是連續(xù)的;(4).在經(jīng)常需要排序的列上創(chuàng)建索引,因?yàn)樗饕呀?jīng)排序,這樣查詢可以利用索引的排序,加快排序查詢時(shí)間;(5).在經(jīng)常使用在WHERE子句中的列上
49、面創(chuàng)建索引,加快條件的判斷速度。對(duì)于有些列不應(yīng)該創(chuàng)建索引。一般來(lái)說(shuō),不應(yīng)該創(chuàng)建索引的的這些列具有下列特點(diǎn):第一,對(duì)于那些在查詢中很少使用或者參考的列不應(yīng)該創(chuàng)建索引。這是因?yàn)?,既然這些列很少使用到,因此有索引或者無(wú)索引,并不能提高查詢速度。相反,由于增加了索引,反而降低了系統(tǒng)的維護(hù)速度和增大了空間需求。第二,對(duì)于那些只有很少數(shù)據(jù)值的列也不應(yīng)該增加索引。這是因?yàn)椋捎谶@些列的取值很少,例如人事表的性別列,在查詢的結(jié)果中,結(jié)果集的數(shù)據(jù)行占了表中數(shù)據(jù)行的很大比例,即需要在表中搜索的數(shù)據(jù)行的比例很大。增加索引,并不能明顯加快檢索速度。第三,對(duì)于那些定義為text, image和bit數(shù)據(jù)類型的列不應(yīng)該增
50、加索引。這是因?yàn)椋@些列的數(shù)據(jù)量要么相當(dāng)大,要么取值很少,不利于使用索引。第四,當(dāng)修改性能遠(yuǎn)遠(yuǎn)大于檢索性能時(shí),不應(yīng)該創(chuàng)建索引。這是因?yàn)椋薷男阅芎蜋z索性能是互相矛盾的。當(dāng)增加索引時(shí),會(huì)提高檢索性能,但是會(huì)降低修改性能。當(dāng)減少索引時(shí),會(huì)提高修改性能,降低檢索性能。因此,當(dāng)修改操作遠(yuǎn)遠(yuǎn)多于檢索操作時(shí),不應(yīng)該創(chuàng)建索引。索引的數(shù)據(jù)結(jié)構(gòu):B-tree,B是balance,一般用于數(shù)據(jù)庫(kù)的索引。使用B-tree結(jié)構(gòu)可以顯著減少定位記錄時(shí)所經(jīng)歷的中間過(guò)程,從而加快存取速度。而B(niǎo)+tree是B-tree的一個(gè)變種,大名鼎鼎的MySQL就普遍使用B+tree實(shí)現(xiàn)其索引結(jié)構(gòu)。插入(insert)操作:插入一個(gè)元素
51、時(shí),首先在B-tree中是否存在,如果不存在,即在葉子結(jié)點(diǎn)處結(jié)束,然后在葉子結(jié)點(diǎn)中插入該新的元素,注意:如果葉子結(jié)點(diǎn)空間足夠,這里需要向右移動(dòng)該葉子結(jié)點(diǎn)中大于新插入關(guān)鍵字的元素,如果空間滿了以致沒(méi)有足夠的空間去添加新的元素,則將該結(jié)點(diǎn)進(jìn)行“分裂”,將一半數(shù)量的關(guān)鍵字元素分裂到新的其相鄰右結(jié)點(diǎn)中,中間關(guān)鍵字元素上移到父結(jié)點(diǎn)中(當(dāng)然,如果父結(jié)點(diǎn)空間滿了,也同樣需要“分裂”操作),而且當(dāng)結(jié)點(diǎn)中關(guān)鍵元素向右移動(dòng)了,相關(guān)的指針也需要向右移。如果在根結(jié)點(diǎn)插入新元素,空間滿了,則進(jìn)行分裂操作,這樣原來(lái)的根結(jié)點(diǎn)中的中間關(guān)鍵字元素向上移動(dòng)到新的根結(jié)點(diǎn)中,因此導(dǎo)致樹(shù)的高度增加一層。刪除(delete)操作:首先查
52、找B-tree中需刪除的元素,如果該元素在B-tree中存在,則將該元素在其結(jié)點(diǎn)中進(jìn)行刪除,如果刪除該元素后,首先判斷該元素是否有左右孩子結(jié)點(diǎn),如果有,則上移孩子結(jié)點(diǎn)中的某相近元素到父節(jié)點(diǎn)中,然后是移動(dòng)之后的情況;如果沒(méi)有,直接刪除后,移動(dòng)之后的情況.。刪除元素,移動(dòng)相應(yīng)元素之后,如果某結(jié)點(diǎn)中元素?cái)?shù)目小于ceil(m/2)-1,則需要看其某相鄰兄弟結(jié)點(diǎn)是否豐滿(結(jié)點(diǎn)中元素個(gè)數(shù)大于ceil(m/2)-1),如果豐滿,則向父節(jié)點(diǎn)借一個(gè)元素來(lái)滿足條件;如果其相鄰兄弟都剛脫貧,即借了之后其結(jié)點(diǎn)數(shù)目小于ceil(m/2)-1,則該結(jié)點(diǎn)與其相鄰的某一兄弟結(jié)點(diǎn)進(jìn)行“合并”成一個(gè)結(jié)點(diǎn),以此來(lái)滿足條件。下面結(jié)合
53、例子詳細(xì)講解mysql中索引的使用索引是快速搜索的關(guān)鍵。MySQL索引的建立對(duì)于MySQL的高效運(yùn)行是很重要的。下面介紹幾種常見(jiàn)的MySQL索引類型。在數(shù)據(jù)庫(kù)表中,對(duì)字段建立索引可以大大提高查詢速度。假如我們創(chuàng)建了一個(gè) mytable表:CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL ); 我們隨機(jī)向里面插入了10000條記錄,其中有一條:5555, admin。在查找username="admin"的記錄 SELECT * FROM mytable WHERE username=
54、39;admin'時(shí),如果在username上已經(jīng)建立了索引,MySQL無(wú)須任何掃描,即準(zhǔn)確可找到該記錄。相反,MySQL會(huì)掃描所有記錄,即要查詢10000條記錄。索引分單列索引和組合索引。單列索引,即一個(gè)索引只包含單個(gè)列,一個(gè)表可以有多個(gè)單列索引,但這不是組合索引。組合索引,即一個(gè)索包含多個(gè)列。MySQL索引類型包括:(1)普通索引這是最基本的索引,它沒(méi)有任何限制。它有以下幾種創(chuàng)建方式:創(chuàng)建索引CREATE INDEX indexName ON mytable(username(length); 如果是CHAR,VARCHAR類型,length可以小于字段實(shí)際長(zhǎng)度;如果是BLOB和T
55、EXT類型,必須指定 length,下同。修改表結(jié)構(gòu)ALTER mytable ADD INDEX indexName ON (username(length)創(chuàng)建表的時(shí)候直接指定CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL, INDEX indexName (username(length) ); 刪除索引的語(yǔ)法:DROP INDEX indexName ON mytable;(2)唯一索引它與前面的普通索引類似,不同的就是:索引列的值必須唯一,但允許有空值。如果是組合索引,則列值的組合必須唯一。它有以下幾種創(chuàng)建方式:創(chuàng)建索引CREATE UNIQUE INDEX indexName
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度綠色建筑項(xiàng)目HSE管理體系優(yōu)化合同3篇
- 2024版有機(jī)化肥技術(shù)服務(wù)合同
- 2024版美容師合同
- 幼兒園外教2025年度聘用合同2篇
- 全球電子商務(wù)人才培養(yǎng)2025年度國(guó)際協(xié)調(diào)項(xiàng)目合同
- 年度地震電磁輻射觀測(cè)儀產(chǎn)業(yè)分析報(bào)告
- 2024版社工項(xiàng)目合同范本
- 二零二五年度智能樓宇電梯全面維保及保養(yǎng)服務(wù)合同2篇
- 二零二四年??漆t(yī)院聘任康復(fù)治療師服務(wù)合同3篇
- 重慶市二零二五年度房屋買賣中介服務(wù)合同2篇
- 《請(qǐng)柬及邀請(qǐng)函》課件
- 中小銀行上云趨勢(shì)研究分析報(bào)告
- 機(jī)電安裝工程安全培訓(xùn)
- 遼寧省普通高中2024-2025學(xué)年高一上學(xué)期12月聯(lián)合考試語(yǔ)文試題(含答案)
- 青海原子城的課程設(shè)計(jì)
- 常州大學(xué)《新媒體文案創(chuàng)作與傳播》2023-2024學(xué)年第一學(xué)期期末試卷
- 麻醉蘇醒期躁動(dòng)患者護(hù)理
- 英語(yǔ)雅思8000詞匯表
- 小學(xué)好詞好句好段摘抄(8篇)
- JT-T-1059.1-2016交通一卡通移動(dòng)支付技術(shù)規(guī)范第1部分:總則
- 《茶藝文化初探》(教學(xué)設(shè)計(jì))-六年級(jí)勞動(dòng)北師大版
評(píng)論
0/150
提交評(píng)論