版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
一:20K技術(shù)總結(jié):1.基本的OO,AOP設(shè)計(jì)能力,設(shè)計(jì)模式基本框架:SSH,SSM,Springboot,dubbo.項(xiàng)目構(gòu)建,mavenLinux操作,基本命令。Nginx原理,常見web服務(wù)器安裝,調(diào)優(yōu)JVM基本原理,調(diào)優(yōu)。幾種數(shù)據(jù)庫(kù),緩存系統(tǒng)redis。消息中心,rabbitmq。原理及應(yīng)用。大數(shù)據(jù)基礎(chǔ),Hadoop,Hbase,Hive,Spark,Scala。數(shù)據(jù)分析,數(shù)據(jù)采集throwable:繼承自O(shè)bject類,實(shí)現(xiàn)serializable接口,兩個(gè)子類error和exception二者的不同之處:Exception:1.可以是可被控制(checked)或不可控制的(unchecked)。2.表示一個(gè)由程序員導(dǎo)致的錯(cuò)誤。3.應(yīng)該在應(yīng)用程序級(jí)被處理。Error:1.總是不可控制的(unchecked)。2.經(jīng)常用來用于表示系統(tǒng)錯(cuò)誤或低層資源的錯(cuò)誤。一般指與虛擬機(jī)相關(guān)的問題,如系統(tǒng)崩潰,內(nèi)存溢出等。對(duì)于這類錯(cuò)誤,僅靠程序本身無(wú)法恢復(fù)和預(yù)防,遇到這樣的錯(cuò)誤,建議讓程序終止。3.如何可能的話,應(yīng)該在系統(tǒng)級(jí)被捕捉。Java中定義了兩類異常:1)Checkedexception:這類異常都是Exception的子類。異常的向上拋出機(jī)制進(jìn)行處理,假如子類可能產(chǎn)生A異常,那么在父類中也必須throwsA異常。可能導(dǎo)致的問題:代碼效率低,耦合度過高。2)Uncheckedexception:這類異常都是RuntimeException的子類,雖然RuntimeException同樣也是Exception的子類,但是它們是非凡的,它們不能通過clientcode來試圖解決,所以稱為Uncheckedexception。常見的幾種RuntimeException如下:NullPointerException-空指針引用異常
ClassCastException-類型強(qiáng)制轉(zhuǎn)換異常。
IllegalArgumentException-傳遞非法參數(shù)異常。
ArithmeticException-算術(shù)運(yùn)算異常
ArrayStoreException-向數(shù)組中存放與聲明類型不兼容對(duì)象異常
IndexOutOfBoundsException-下標(biāo)越界異常
NegativeArraySizeException-創(chuàng)建一個(gè)大小為負(fù)數(shù)的數(shù)組錯(cuò)誤異常
NumberFormatException-數(shù)字格式異常
SecurityException-安全異常
UnsupportedOperationException-不支持的操作異常Jvm和垃圾回收:Jvm的物理結(jié)構(gòu)1)堆:所有通過new創(chuàng)建的對(duì)象的內(nèi)存都在堆中分配,其大小可以通過-Xmx和-Xms來控制。堆被劃分為新生代和舊生代,新生代又被進(jìn)一步劃分為Eden和Survivor區(qū),最后Survivor由FromSpace和ToSpace組成,新生代。新建的對(duì)象都是用新生代分配內(nèi)存,Eden空間不足的時(shí)候,會(huì)把存活的對(duì)象轉(zhuǎn)移到Survivor中,新生代大小可以由-Xmn來控制,也可以用-XX:SurvivorRatio來控制Eden和Survivor的比例舊生代。用于存放新生代中經(jīng)過多次垃圾回收仍然存活的對(duì)象2)棧每個(gè)線程執(zhí)行每個(gè)方法的時(shí)候都會(huì)在棧中申請(qǐng)一個(gè)棧幀,每個(gè)棧幀包括局部變量區(qū)和操作數(shù)棧,用于存放此次方法調(diào)用過程中的臨時(shí)變量、參數(shù)和中間結(jié)果3)本地方法棧用于支持native方法的執(zhí)行,存儲(chǔ)了每個(gè)native方法調(diào)用的狀態(tài)4)方法區(qū)存放了要加載的類信息、靜態(tài)變量、final類型的常量、屬性和方法信息。JVM用持久代(PermanetGeneration)來存放方法區(qū),可通過-XX:PermSize和-XX:MaxPermSize來指定最小值和最大值一、JavaJVM內(nèi)存介紹JVM管理兩種類型的內(nèi)存,堆和非堆。按照官方的說法:“Java虛擬機(jī)具有一個(gè)堆,堆是運(yùn)行時(shí)數(shù)據(jù)區(qū)域,所有類實(shí)例和數(shù)組的內(nèi)存均從此處分配。堆是在Java虛擬機(jī)啟動(dòng)時(shí)創(chuàng)建的?!薄霸贘VM中堆之外的內(nèi)存稱為非堆內(nèi)存(Non-heapmemory)”。簡(jiǎn)單來說堆就是Java代碼可及的內(nèi)存,是留給開發(fā)人員使用的;非堆就是JVM留給自己用的,所以方法區(qū)、JVM內(nèi)部處理或優(yōu)化所需的內(nèi)存(如JIT編譯后的代碼緩存)、每個(gè)類結(jié)構(gòu)(如運(yùn)行時(shí)常數(shù)池、字段和方法數(shù)據(jù))以及方法和構(gòu)造方法的代碼都在非堆內(nèi)存中,它和堆不同,運(yùn)行期內(nèi)GC不會(huì)釋放其空間。Jvm虛擬機(jī)JVM=
類加載器
classloader+
執(zhí)行引擎
executionengine+
運(yùn)行時(shí)數(shù)據(jù)區(qū)域
runtimedataarea首先Java源代碼文件被Java編譯器編譯為字節(jié)碼文件,然后JVM中的類加載器加載完畢之后,交由JVM執(zhí)行引擎執(zhí)行。在整個(gè)程序執(zhí)行過程中,JVM中的運(yùn)行時(shí)數(shù)據(jù)區(qū)(內(nèi)存)會(huì)用來存儲(chǔ)程序執(zhí)行期間需要用到的數(shù)據(jù)和相關(guān)信息。因此,在Java中我們常常說到的內(nèi)存管理就是針對(duì)這段空間進(jìn)行管理(如何分配和回收內(nèi)存空間)。Java堆(1)Java堆是JVM所管理的最大的一塊內(nèi)存。它是被所有線程共享的一塊內(nèi)存區(qū)域,在虛擬機(jī)啟動(dòng)時(shí)創(chuàng)建。(2)幾乎所有的實(shí)例對(duì)象都是在這塊區(qū)域中存放。(JIT編譯器貌似不是這樣的)。(3)Java堆是垃圾收集管理的主要戰(zhàn)場(chǎng)。所有Java堆可以細(xì)分為:新生代和老年代。再細(xì)致分就是把新生代分為:Eden空間、FromSurvivor空間、ToSurvivor空間4.UNION用的比較多unionall是直接連接,取到得是所有值,記錄可能有重復(fù)union是取唯一值,記錄沒有重復(fù)1、對(duì)重復(fù)結(jié)果的處理:UNION在進(jìn)行表鏈接后會(huì)篩選掉重復(fù)的記錄,UnionAll不會(huì)去除重復(fù)記錄。
2、對(duì)排序的處理:Union將會(huì)按照字段的順序進(jìn)行排序;UNIONALL只是簡(jiǎn)單的將兩個(gè)結(jié)果合并后就返回。
從效率上說,UNIONALL要比UNION快很多,所以,如果可以確認(rèn)合并的兩個(gè)結(jié)果集中不包含重復(fù)數(shù)據(jù)且不需要排序時(shí)的話,那么就使用UNIONALL。5.Oracle查詢優(yōu)化原則一:注意WHERE子句中的連接順序:
ORACLE采用自下而上的順序解析WHERE子句,根據(jù)這個(gè)原理,表之間的連接必須寫在其他WHERE條件之前,那些可以過濾掉最大數(shù)量記錄的條件必須寫在WHERE子句的末尾.
尤其是“主鍵ID=?”這樣的條件。原則二:SELECT子句中避免使用‘*‘:
ORACLE在解析的過程中,會(huì)將'*'依次轉(zhuǎn)換成所有的列名,這個(gè)工作是通過查詢數(shù)據(jù)字典完成的,這意味著將耗費(fèi)更多的時(shí)間。簡(jiǎn)單地講,語(yǔ)句執(zhí)行的時(shí)間越短越好(尤其對(duì)于系統(tǒng)的終端用戶來說)。而對(duì)于查詢語(yǔ)句,由于全表掃描讀取的數(shù)據(jù)多,尤其是對(duì)于大型表不僅查詢速度慢,而且對(duì)磁盤IO造成大的壓力,通常都要避免,而避免的方式通常是使用索引Index使用索引的優(yōu)勢(shì)與代價(jià)。
優(yōu)勢(shì):
1)索引是表的一個(gè)概念部分,用來提高檢索數(shù)據(jù)的效率,ORACLE使用了一個(gè)復(fù)雜的自平衡B-tree結(jié)構(gòu).通常,通過索引查詢數(shù)據(jù)比全表掃描要快.當(dāng)ORACLE找出執(zhí)行查詢和Update語(yǔ)句的最佳路徑時(shí),ORACLE優(yōu)化器將使用索引.同樣在聯(lián)結(jié)多個(gè)表時(shí)使用索引也可以提高效率.
2)另一個(gè)使用索引的好處是,它提供了主鍵(primarykey)的唯一性驗(yàn)證.。那些LONG或LONGRAW數(shù)據(jù)類型,你可以索引幾乎所有的列.通常,在大型表中使用索引特別有效.當(dāng)然,你也會(huì)發(fā)現(xiàn),在掃描小表時(shí),使用索引同樣能提高效率.
代價(jià):
雖然使用索引能得到查詢效率的提高,但是我們也必須注意到它的代價(jià).索引需要空間來存儲(chǔ),也需要定期維護(hù),每當(dāng)有記錄在表中增減或索引列被修改時(shí),索引本身也會(huì)被修改.這意味著每條記錄的INSERT,DELETE,UPDATE將為此多付出4,5次的磁盤I/O.因?yàn)樗饕枰~外的存儲(chǔ)空間和處理,那些不必要的索引反而會(huì)使查詢反應(yīng)時(shí)間變慢.。而且表越大,影響越嚴(yán)重。1、避免在索引列上使用NOT,
我們要避免在索引列上使用NOT,NOT會(huì)產(chǎn)生在和在索引列上使用函數(shù)相同的影響.當(dāng)ORACLE”遇到”NOT,他就會(huì)停止使用索引轉(zhuǎn)而執(zhí)行全表掃描.2、避免在索引列上使用計(jì)算.
WHERE子句中,如果索引列是函數(shù)的一部分.優(yōu)化器將不使用索引而使用全表掃描.舉例:低效:SELECT…FROMDEPTWHERESAL*12>25000;高效:SELECT…FROMDEPTWHERESAL>25000/12;3、避免在索引列上使用ISNULL和ISNOTNULL
避免在索引中使用任何可以為空的列,ORACLE性能上將無(wú)法使用該索引.對(duì)于單列索引,如果列包含空值,索引中將不存在此記錄.對(duì)于復(fù)合索引,如果每個(gè)列都為空,索引中同樣不存在此記錄.如果至少有一個(gè)列不為空,則記錄存在于索引中.舉例:如果唯一性索引建立在表的A列和B列上,并且表中存在一條記錄的A,B值為(123,null),ORACLE將不接受下一條具有相同A,B值(123,null)的記錄(插入).然而如果所有的索引列都為空,ORACLE將認(rèn)為整個(gè)鍵值為空而空不等于空.因此你可以插入1000條具有相同鍵值的記錄,當(dāng)然它們都是空!因?yàn)榭罩挡淮嬖谟谒饕兄?所以WHERE子句中對(duì)索引列進(jìn)行空值比較將使ORACLE停用該索引.低效:(索引失效)SELECT…FROMDEPARTMENTWHEREDEPT_CODEISNOTNULL;高效:(索引有效)SELECT…FROMDEPARTMENTWHEREDEPT_CODE>=0;4、注意通配符%的影響
使用通配符的情況下Oracle可能會(huì)停用該索引。如:6、索引的一些“脾氣”
a.如果檢索數(shù)據(jù)量超過30%的表中記錄數(shù).使用索引將沒有顯著的效率提高.
b.在特定情況下,使用索引也許會(huì)比全表掃描慢,但這是同一個(gè)數(shù)量級(jí)上的區(qū)別.而通常情況下,使用索引比全表掃描要塊幾倍乃至幾千倍!
除了使用索引,我們還有其他能減少資源消耗的方法:
1、用EXISTS替換DISTINCT:
當(dāng)提交一個(gè)包含一對(duì)多表信息(比如部門表和雇員表)的查詢時(shí),避免在SELECT子句中使用DISTINCT.一般可以考慮用EXIST替換,EXISTS使查詢更為迅速,因?yàn)镽DBMS核心模塊將在子查詢的條件一旦滿足后,立刻返回結(jié)果.
7、通常來說,如果語(yǔ)句能夠避免子查詢的使用,就盡量不用子查詢。因?yàn)樽硬樵兊拈_銷是相當(dāng)昂貴的。具體的例子在后面的案例“一條SQL的優(yōu)化過程”中。8.當(dāng)一個(gè)線程進(jìn)入一個(gè)對(duì)象的一個(gè)synchronized方法后,其它線程是否可進(jìn)入此對(duì)象的其它方法?分幾種情況:1.其他方法前是否加了synchronized關(guān)鍵字,如果沒加,則能。2.如果這個(gè)方法內(nèi)部調(diào)用了wait,則可以進(jìn)入其他synchronized方法。3.如果其他個(gè)方法都加了synchronized關(guān)鍵字,并且內(nèi)部沒有調(diào)用wait,則不能。4.如果其他方法是static,它用的同步鎖是當(dāng)前類的字節(jié)碼,與非靜態(tài)的方法不能同步,因?yàn)榉庆o態(tài)的方法用的是this。狀態(tài):就緒,運(yùn)行,synchronize阻塞,wait和sleep掛起,結(jié)束。wait必須在synchronized內(nèi)部調(diào)用。調(diào)用線程的start方法后線程進(jìn)入就緒狀態(tài),線程調(diào)度系統(tǒng)將就緒狀態(tài)的線程轉(zhuǎn)為運(yùn)行狀態(tài),遇到synchronized語(yǔ)句時(shí),由運(yùn)行狀態(tài)轉(zhuǎn)為阻塞9.HashMap和Hashtable的區(qū)別HashMap是Hashtable的輕量級(jí)實(shí)現(xiàn)(非線程安全的實(shí)現(xiàn)),他們都完成了Map接口,HashMap允許將null作為一個(gè)entry的key或者value,而Hashtable不允許。10.62、List,Set,Map是否繼承自Collection接口?List,Set是,Map不是11.為什么Java中1000==1000為false而100==100為true?這就是它有趣的地方了。如果你看去看Integer.Java類,你會(huì)發(fā)現(xiàn)有一個(gè)內(nèi)部私有類,IntegerCache.java,它緩存了從-128到127之間的所有的整數(shù)對(duì)象。如果值的范圍在-128到127之間,它就從高速緩存返回實(shí)例。在此范圍內(nèi)的“小”整數(shù)使用率比大整數(shù)要高,因此,使用相同的底層對(duì)象是有價(jià)值的,可以減少潛在的內(nèi)存占用。而超過這個(gè)范圍,就要new對(duì)象了,不是同一個(gè)對(duì)象(在這個(gè)范圍內(nèi),直接從緩存中獲?。?2,說說String/StringBuffer/StringBuilder它們之間的區(qū)別?在大部分情況下,字符串的拼接速度為:StringBuilder>StringBuffer>String。String是不可變的,因此每次對(duì)其操作改變其變量值,其實(shí)是生成一個(gè)新的對(duì)象,然后將變量引用指向新對(duì)象;因此速度慢。StringBuffer則不同,對(duì)其操作即直接操作對(duì)象指向的引用,無(wú)需產(chǎn)生新對(duì)象,速度很快;它是線程安全的,在維護(hù)多線程的同步等也會(huì)消耗一點(diǎn)性能。StringBuilder是jdk5之后新增的,其用法與StringBuffer完全一致,但它是線程不安全的,在單線程中最佳,因?yàn)槠洳恍枰S護(hù)線程的安全,因此是最快的。String字符串常量(線程安全)。StringBuffer字符串變量(線程安全)。StringBuilder字符串變量(非線程安全)。String是不可變的,StringBuffer/StringBuilder是可變的;String/StringBuffer是線程安全的,StringBuilder是非線程安全的。String是存放在常量池,在編譯期已經(jīng)被確定了。newString()不是字符串常量,它有自己的地址空間,存放在堆空間。而其它兩個(gè)都存放在堆空間。13.14.Stirng是最基本的數(shù)據(jù)類型嗎?
答:不是.
java中的基本數(shù)據(jù)類型就八種:byte,short,int,long,float,double,char,
boolean.剩下的都是引用類型(referencetype).15.floatf=1.1;正確嗎?答:不正確.1.1是雙精度,將雙精度賦值給浮點(diǎn)型,屬于向下轉(zhuǎn)型,會(huì)造成精度的丟失.如果要強(qiáng)制類型轉(zhuǎn)換,可以寫成這樣floatf=(float)1.1;或者floatf=1.1F;16.shorta=1;a=a+1和shorta=1;a+=1有什么區(qū)別?
答:對(duì)于a=a+1因?yàn)?是int值類型,所以計(jì)算的結(jié)果是int,要賦值給short,需要強(qiáng)制類型裝換才能賦值給short.對(duì)于a+=1;其相當(dāng)于a=(short)(a+1);其中已經(jīng)做了強(qiáng)制類型裝換.17.下面代碼打印結(jié)果?Integera=100,b=100,c=130,d=130;
System.out.println(a==>b);
System.out.println(c==d);第一個(gè)是true,第二個(gè)是false.
因?yàn)閍,b,c,d四個(gè)變量都是integer對(duì)象的引用,所以==比較的不是值,而是引用.如果整型字面量的值在-128到127之間,那么不會(huì)new新的Integer對(duì)象,而是直接引用常量池中的Integer對(duì)象.18.String類可以被繼承嗎?答:不可以.因?yàn)镾tring類是final類.19.String和StringBuilder,StringBuffer的區(qū)別?答:String是只讀字符串,String引用的字符串內(nèi)容是不能被改變的.而StringBuffer和StringBuilder是可變字符串.StringBuilder和StringBuffer的用法相同,區(qū)別是StringBuffer被synchronized修飾,效率比StringBuilder低。20.構(gòu)造器是否可以被重寫?答:構(gòu)造器不能被繼承,因此不能被重寫,但是可以被重載.21.抽象類和接口的相同點(diǎn)和不同點(diǎn).答:1.抽象類和接口都不能實(shí)例化對(duì)象,但是可以定義抽象類和接口類型的引用.
2.繼承抽象類和實(shí)現(xiàn)接口都要對(duì)其中的抽象方法全部實(shí)現(xiàn)
3.接口比抽象類更加抽象,抽象類中可以定義構(gòu)造器,可以有抽象方法和具體方法.
4.接口中方法全部都是抽象方法.
5.抽象類中的成員可以是private,protected,public,接口全部都是public
6.抽象類中可以定義成員變量,而接口中定義的成員變量實(shí)際上都是常量.
7.有抽象方法的類必須聲明為抽象類,而抽象類未必要有抽象方法.22.java中會(huì)存在內(nèi)存泄露嗎?答:理論上java不會(huì)存在內(nèi)存泄露的問題,應(yīng)為有垃圾回收機(jī)制(GC).然而在實(shí)際開發(fā)中,可能會(huì)存在無(wú)用但可達(dá)的對(duì)象,這些對(duì)象不能被GC回收,因此會(huì)導(dǎo)致內(nèi)存泄露.例如hibernated的Session中的對(duì)象屬于持久態(tài),垃圾回收器不會(huì)回收這些對(duì)象,這些對(duì)象中有可能存在無(wú)用的垃圾對(duì)象.如果關(guān)閉不及時(shí),一級(jí)緩存就可能導(dǎo)致內(nèi)存泄露.23.try{}里面return,finally里的代碼會(huì)不會(huì)執(zhí)行,什么時(shí)候被執(zhí)行?答:會(huì)執(zhí)行.在方法返回給調(diào)用者前執(zhí)行.因?yàn)槿绻嬖趂inally代碼塊,try中的return語(yǔ)句不會(huì)立馬返回調(diào)用者,而是記錄下返回值待finally代碼塊執(zhí)行完畢之后在返回.24.List,Map,Set三個(gè)接口存取元素時(shí),各自有什么特點(diǎn)?答:List以特定的索引來存取元素,可以有重復(fù)元素Set不能存放重復(fù)元素.Map保存鍵值對(duì)的映射,映射關(guān)系可以是一對(duì)一或多對(duì)一.Set和Map容器都有基于哈希存儲(chǔ)和排序樹的兩種實(shí)現(xiàn)版本,基于哈希存儲(chǔ)理論存取時(shí)間復(fù)雜度是O(1).25.Thread類中的sleep()和對(duì)象的wait()有什么區(qū)別?答:sleep()方法是線程類的靜態(tài)方法,調(diào)用此方法會(huì)讓當(dāng)前線程暫停執(zhí)行指定時(shí)間.將CPU時(shí)間片分給其他線程,但是對(duì)象的鎖依然保持,休眠時(shí)間結(jié)束會(huì)自動(dòng)回復(fù)到就緒狀態(tài).wait()是Object類的方法,調(diào)用對(duì)象的wait()方法導(dǎo)致當(dāng)前線程放棄對(duì)象的鎖,線程暫停執(zhí)行,進(jìn)入對(duì)象的等待池,只有調(diào)用對(duì)象的notify()方法或notifyAll()方法時(shí),才能喚醒等待池中的線程進(jìn)入等鎖池,如果線程重新獲得對(duì)象的鎖就可以進(jìn)入就緒狀態(tài)26.當(dāng)一個(gè)線程進(jìn)入一個(gè)對(duì)象的synchronized方法A之后,其它線程是否可進(jìn)入此對(duì)象的synchronized方法B?答:不能。其它線程只能訪問該對(duì)象的非同步方法,同步方法則不能進(jìn)入。因?yàn)榉庆o態(tài)方法上的synchronized修飾符要求執(zhí)行方法時(shí)要獲得對(duì)象的鎖,如果已經(jīng)進(jìn)入A方法說明對(duì)象鎖已經(jīng)被取走,那么試圖進(jìn)入B方法的線程就只能在等鎖池(注意不是等待池哦)中等待對(duì)象的鎖27.說說synchronized關(guān)鍵字的用法?
答:synchronized關(guān)鍵字可以將對(duì)象或者方法標(biāo)記為同步,以實(shí)現(xiàn)對(duì)對(duì)象和方法的互斥訪問,可以用synchronized(對(duì)象){…}定義同步代碼塊,或者在聲明方法時(shí)將synchronized作為方法的修飾符28.Java如何實(shí)現(xiàn)序列化,有什么意義?答:序列化就是一種用來處理對(duì)象流的機(jī)制,所謂對(duì)象流也就是將對(duì)象的內(nèi)容進(jìn)行流化。可以對(duì)流化后的對(duì)象進(jìn)行讀寫操作,也可將流化后的對(duì)象傳輸于網(wǎng)絡(luò)之間。序列化是為了解決對(duì)象流讀寫操作時(shí)可能引發(fā)的問題(如果不進(jìn)行序列化可能會(huì)存在數(shù)據(jù)亂序的問題)要實(shí)現(xiàn)序列化,讓類實(shí)現(xiàn)Serializable接口.該接口是一個(gè)標(biāo)識(shí)性接口,標(biāo)注該類對(duì)象是可被序列化的,然后使用一個(gè)輸出流來構(gòu)造一個(gè)對(duì)象輸出流并通過writeObject(Object)方法就可以將實(shí)現(xiàn)對(duì)象寫出如果需要反序列化則可以用一個(gè)輸入流建立對(duì)象輸入流,然后通過readObject方法從流中讀取對(duì)象。序列化除了能夠?qū)崿F(xiàn)對(duì)象的持久化之外,還能夠用于對(duì)象的深度克隆29.線程的sleep()方法和yield()方法有什么區(qū)別?答:sleep()方法給其他線程運(yùn)行機(jī)會(huì)時(shí)不考慮線程的優(yōu)先級(jí),因此會(huì)給低優(yōu)先級(jí)的線程以運(yùn)行的機(jī)會(huì);yield()方法只會(huì)給相同優(yōu)先級(jí)或更高優(yōu)先級(jí)的線程以運(yùn)行的機(jī)會(huì);
線程執(zhí)行sleep()方法后轉(zhuǎn)入阻塞(blocked)狀態(tài),而執(zhí)行yield()方法后轉(zhuǎn)入就緒(ready)狀態(tài);
sleep()方法聲明拋出InterruptedException,而yield()方法沒有聲明任何異常;sleep()方法比yield()方法(跟操作系統(tǒng)CPU調(diào)度相關(guān))具有更好的可移植性。30.說說你對(duì)同步和異步的理解.答:如果系統(tǒng)中存在臨界資源(資源數(shù)量少于競(jìng)爭(zhēng)資源的線程數(shù)量的資源),例如正在寫的數(shù)據(jù)以后可能被另一個(gè)線程讀到,或者正在讀的數(shù)據(jù)可能已經(jīng)被另一個(gè)線程寫過了,那么這些數(shù)據(jù)就必須進(jìn)行同步存?。〝?shù)據(jù)庫(kù)操作中的排他鎖就是最好的例子)當(dāng)應(yīng)用程序在對(duì)象上調(diào)用了一個(gè)需要花費(fèi)很長(zhǎng)時(shí)間來執(zhí)行的方法,并且不希望讓程序等待方法的返回時(shí),就應(yīng)該使用異步編程,在很多情況下采用異步途徑往往更有效率。事實(shí)上,所謂的同步就是指阻塞式操作,而異步就是非阻塞式操作。31.轉(zhuǎn)發(fā)(forward)和重定向(redirect)的區(qū)別?答:forward是容器中控制權(quán)的轉(zhuǎn)向,是服務(wù)器請(qǐng)求資源,服務(wù)器直接訪問目標(biāo)地址的URL,把那個(gè)URL的響應(yīng)內(nèi)容讀取過來,然后把這些內(nèi)容再發(fā)給瀏覽器,瀏覽器根本不知道服務(wù)器發(fā)送的內(nèi)容是從哪兒來的,所以它的地址欄中還是原來的地址redirect就是服務(wù)器端根據(jù)邏輯,發(fā)送一個(gè)狀態(tài)碼,告訴瀏覽器重新去請(qǐng)求那個(gè)地址,因此從瀏覽器的地址欄中可以看到跳轉(zhuǎn)后的鏈接地址,很明顯redirect無(wú)法訪問到服務(wù)器保護(hù)起來資源,但是可以從一個(gè)網(wǎng)站redirect到其他網(wǎng)站。32.說一說spring中依賴注入和AOP的實(shí)現(xiàn)機(jī)制。答:實(shí)現(xiàn)依賴注入的方式包括:構(gòu)造器注入、設(shè)值注入和接口(回調(diào))注入。Spring中可以通過設(shè)值注入(setter方法注入)和構(gòu)造器注入實(shí)現(xiàn)IoC,推薦使用的方式為設(shè)值注入。實(shí)現(xiàn)AOP的方式包括:編譯時(shí)AOP(需要特殊的編譯器)、運(yùn)行時(shí)AOP(代理模式)、加載時(shí)AOP(需要特殊的類加載器)。Spring中使用了運(yùn)行時(shí)的AOP,主要通過代理的方式對(duì)原來的代碼進(jìn)行增強(qiáng)實(shí)現(xiàn)。對(duì)于實(shí)現(xiàn)了接口的類,Spring通過Java的動(dòng)態(tài)代理(請(qǐng)參考Proxy類和InvocationHandler接口)來進(jìn)行增強(qiáng);對(duì)于沒有實(shí)現(xiàn)接口的類,Spring使用第三方字節(jié)碼生成工具CGLIB,通過繼承的方式對(duì)原有代碼進(jìn)行增強(qiáng)33.什么是ORM?答:對(duì)象關(guān)系映射(Object-RelationalMapping,簡(jiǎn)稱ORM)是一種為了解決程序的面向?qū)ο竽P团c數(shù)據(jù)庫(kù)的關(guān)系模型互不匹配問題的技術(shù);簡(jiǎn)單的說,ORM是通過使用描述對(duì)象和數(shù)據(jù)庫(kù)之間映射的元數(shù)據(jù)(在Java中可以用XML或者是注解),將程序中的對(duì)象自動(dòng)持久化到關(guān)系數(shù)據(jù)庫(kù)中或者將關(guān)系數(shù)據(jù)庫(kù)表中的行轉(zhuǎn)換成Java對(duì)象,其本質(zhì)上就是將數(shù)據(jù)從一種形式轉(zhuǎn)換到另外一種形式。
34.簡(jiǎn)述一下面向?qū)ο蟮?六原則一法則"答:單一職責(zé)原則:一個(gè)類只做它該做的事情。單一職責(zé)原則想表達(dá)的就是"高內(nèi)聚"開閉原則:軟件實(shí)體應(yīng)當(dāng)對(duì)擴(kuò)展開放,對(duì)修改關(guān)閉.要做到開閉有兩個(gè)要點(diǎn):抽象是關(guān)鍵,一個(gè)系統(tǒng)中如果沒有抽象類或接口系統(tǒng)就沒有擴(kuò)展點(diǎn);封裝可變性,將系統(tǒng)中的各種可變因素封裝到一個(gè)繼承結(jié)構(gòu)中,依賴倒轉(zhuǎn)原則:面向接口編程,就是聲明方法的參數(shù)類型、方法的返回類型、變量的引用類型時(shí),盡可能使用抽象類型而不用具體類型,因?yàn)槌橄箢愋涂梢员凰娜魏我粋€(gè)子類型所替代里氏替換原則:任何時(shí)候都可以用子類型替換掉父類型接口隔離原則:接口要小而專,絕不能大而全。接口也應(yīng)該是高度內(nèi)聚的.Java中的接口代表能力、代表約定、代表角色,能否正確的使用接口一定是編程水平高低的重要標(biāo)識(shí)合成聚合復(fù)用原則:優(yōu)先使用聚合或合成關(guān)系復(fù)用代碼33.Oracle。Oracle的應(yīng)用,主要在傳統(tǒng)行業(yè)的數(shù)據(jù)化業(yè)務(wù)中,比如:銀行、金融這樣的對(duì)可用性、健壯性、安全性、實(shí)時(shí)性要求極高的業(yè)務(wù);零售、物流這樣對(duì)海量數(shù)據(jù)存儲(chǔ)分析要求很高的業(yè)務(wù)MySQL。MySQL基本是生于互聯(lián)網(wǎng),長(zhǎng)于互聯(lián)網(wǎng)。其應(yīng)用實(shí)例也大都集中于互聯(lián)網(wǎng)方向,MySQL的高并發(fā)存取能力并不比大型數(shù)據(jù)庫(kù)差,同時(shí)價(jià)格便宜,安裝使用簡(jiǎn)便快捷,深受廣大互聯(lián)網(wǎng)公司的喜愛。并且由于MySQL的開源特性,針對(duì)一些對(duì)數(shù)據(jù)庫(kù)有特別要求的應(yīng)用,可以通過修改代碼來實(shí)現(xiàn)定向優(yōu)化MSSQLServer。windows生態(tài)系統(tǒng)的產(chǎn)品,好處壞處都很分明。好處就是,高度集成化,微軟也提供了整套的軟件方案,基本上一套win系統(tǒng)裝下來就齊活了。因此,不那么缺錢,但很缺IT人才的中小企業(yè),會(huì)偏愛MSSQLServer。例如,自建ERP系統(tǒng)、商業(yè)智能、垂直領(lǐng)域零售商、餐飲、事業(yè)單位等等。35.10、實(shí)現(xiàn)一種排序?答: //冒泡排序 publicclassBubbleSort{ publicBubbleSort(){ int[]arr={30,12,34,56,78,48}; for(inti=1;i<arr.length;i++){ for(intj=0;j<arr.length-i;j++){ inttemp; if(arr[j]>arr[j+1]){ temp=arr[j]; arr[j]=arr[j+1]; arr[j+1]=temp; } } } for(inti=0;i<arr.length;i++){ System.out.print(arr[i]+""); } } publicstaticvoidmain(String[]args){ //TODOAuto-generatedmethodstub BubbleSortbs=newBubbleSort(); }}36.8、得到Class的三個(gè)過程是什么答: (1)類.class (2)對(duì)象.getClass(); (3)Class.forName("類全名")37.3、Hibernate的優(yōu)化策略答: 1、盡量使用新版本的hibernate; 2、制定合理的緩存策略; 3、采用合理的session管理機(jī)制; 4、盡量使用延遲加載; 5、設(shè)定合理的批處理參數(shù); 6、盡量使用uuid作為主鍵生成策略; 7、就有可能的話,使用vision的樂觀鎖代替悲觀鎖; 8、開發(fā)過程中,打開hibernate的Sql日志輸出(hibernate.show_sql=true),觀察sql語(yǔ)句進(jìn)一步的指定實(shí)施策略;38.數(shù)據(jù)庫(kù)的三大范式?答:1、不可拆分(原子性):數(shù)據(jù)庫(kù)的第一范式是在數(shù)據(jù)庫(kù)表的設(shè)計(jì)時(shí),確保數(shù)據(jù)庫(kù)表的字段具有不可拆分的原子性;比如, 一格字段為地址,而在實(shí)際查詢中多次用到省、市,那么我們要將地址改為兩個(gè)字段省和市。 2、完全依賴:確保表中的每列都和主鍵相關(guān),也就是說一張數(shù)據(jù)庫(kù)表只能存儲(chǔ)一種數(shù)據(jù),不能將多種數(shù)據(jù)存儲(chǔ)在一張表 中,比如,將訂單信息和商品信息存在同一張表中。 3、消除傳遞依賴:每一列數(shù)據(jù)都和主鍵直接相關(guān),而不能間接相關(guān); 34,常見設(shè)計(jì)模式以及spring用了哪些設(shè)計(jì)模式?設(shè)計(jì)模式的六大原則1、開閉原則(OpenClosePrinciple)開閉原則的意思是:對(duì)擴(kuò)展開放,對(duì)修改關(guān)閉。在程序需要進(jìn)行拓展的時(shí)候,不能去修改原有的代碼,實(shí)現(xiàn)一個(gè)熱插拔的效果。簡(jiǎn)言之,是為了使程序的擴(kuò)展性好,易于維護(hù)和升級(jí)。想要達(dá)到這樣的效果,我們需要使用接口和抽象類,后面的具體設(shè)計(jì)中我們會(huì)提到這點(diǎn)。2、里氏代換原則(LiskovSubstitutionPrinciple)里氏代換原則是面向?qū)ο笤O(shè)計(jì)的基本原則之一。里氏代換原則中說,任何基類可以出現(xiàn)的地方,子類一定可以出現(xiàn)。LSP是繼承復(fù)用的基石,只有當(dāng)派生類可以替換掉基類,且軟件單位的功能不受到影響時(shí),基類才能真正被復(fù)用,而派生類也能夠在基類的基礎(chǔ)上增加新的行為。里氏代換原則是對(duì)開閉原則的補(bǔ)充。實(shí)現(xiàn)開閉原則的關(guān)鍵步驟就是抽象化,而基類與子類的繼承關(guān)系就是抽象化的具體實(shí)現(xiàn),所以里氏代換原則是對(duì)實(shí)現(xiàn)抽象化的具體步驟的規(guī)范。3、依賴倒轉(zhuǎn)原則(DependenceInversionPrinciple)這個(gè)原則是開閉原則的基礎(chǔ),具體內(nèi)容:針對(duì)接口編程,依賴于抽象而不依賴于具體。4、接口隔離原則(InterfaceSegregationPrinciple)這個(gè)原則的意思是:使用多個(gè)隔離的接口,比使用單個(gè)接口要好。它還有另外一個(gè)意思是:降低類之間的耦合度。由此可見,其實(shí)設(shè)計(jì)模式就是從大型軟件架構(gòu)出發(fā)、便于升級(jí)和維護(hù)的軟件設(shè)計(jì)思想,它強(qiáng)調(diào)降低依賴,降低耦合。5、迪米特法則,又稱最少知道原則(DemeterPrinciple)最少知道原則是指:一個(gè)實(shí)體應(yīng)當(dāng)盡量少地與其他實(shí)體之間發(fā)生相互作用,使得系統(tǒng)功能模塊相對(duì)獨(dú)立。6、合成復(fù)用原則(CompositeReusePrinciple)合成復(fù)用原則是指:盡量使用合成/聚合的方式,而不是使用繼承。38.spring中用到哪些設(shè)計(jì)模式1.工廠模式,這個(gè)很明顯,在各種BeanFactory以及ApplicationContext創(chuàng)建中都用到了;2.模版模式,這個(gè)也很明顯,在各種BeanFactory以及ApplicationContext實(shí)現(xiàn)中也都用到了;3.代理模式,在Aop實(shí)現(xiàn)中用到了JDK的動(dòng)態(tài)代理;4.單例模式,這個(gè)比如在創(chuàng)建bean的時(shí)候。5.Tomcat中有很多場(chǎng)景都使用到了外觀模式,因?yàn)門omcat中有很多不同的組件,每個(gè)組件需要相互通信,但又不能將自己內(nèi)部數(shù)據(jù)過多地暴露給其他組件。用外觀模式隔離數(shù)據(jù)是個(gè)很好的方法。6.策略模式在Java中的應(yīng)用,這個(gè)太明顯了,因?yàn)镃omparator這個(gè)接口簡(jiǎn)直就是為策略模式而生的。Comparable和Comparator的區(qū)別一文中,詳細(xì)講了Comparator的使用。比方說Collections里面有一個(gè)sort方法,因?yàn)榧侠锩娴脑赜锌赡苁菑?fù)合對(duì)象,復(fù)合對(duì)象并不像基本數(shù)據(jù)類型,可以根據(jù)大小排序,復(fù)合對(duì)象怎么排序呢?基于這個(gè)問題考慮,Java要求如果定義的復(fù)合對(duì)象要有排序的功能,就自行實(shí)現(xiàn)Comparable接口或Comparator接口.7.原型模式:使用原型模式創(chuàng)建對(duì)象比直接new一個(gè)對(duì)象在性能上好得多,因?yàn)镺bject類的clone()方法是一個(gè)native方法,它直接操作內(nèi)存中的二進(jìn)制流,特別是復(fù)制大對(duì)象時(shí),性能的差別非常明顯。8.迭代器模式:Iterable接口和Iterator接口
這兩個(gè)都是迭代相關(guān)的接口,可以這么認(rèn)為,實(shí)現(xiàn)了Iterable接口,則表示某個(gè)對(duì)象是可被迭代的;Iterator接口相當(dāng)于是一個(gè)迭代器,實(shí)現(xiàn)了Iterator接口,等于具體定義了這個(gè)可被迭代的對(duì)象時(shí)如何進(jìn)行迭代的39,Hibernate的緩存處理 Hibernate就是對(duì)JDBC進(jìn)行的封裝 帶來的就是數(shù)據(jù)訪問效率的降低,和性能的下降 對(duì)于Hibernate這類ORM而言,緩存顯的尤為重要,它是持久層性能提升的關(guān)鍵####緩存分類 使用的生命周期和Session的生命周期同步(從openSession到mit再到session.rollback()都屬于事務(wù)范圍) 1.一級(jí)緩存(事務(wù)級(jí)緩存):即在當(dāng)前事務(wù)范圍內(nèi)的數(shù)據(jù)緩存 -就Hibernate來講,(一級(jí)緩存)事務(wù)級(jí)緩存是基于 Session的生命周期實(shí)現(xiàn)的。 在一級(jí)緩存失效的時(shí)候,才開始二級(jí)緩存。 2.應(yīng)用級(jí)(二級(jí))緩存:即在某個(gè)應(yīng)用中或應(yīng)用中某個(gè)獨(dú)立數(shù)據(jù)庫(kù)訪問子集中的共享緩存,此緩存可由多個(gè)事務(wù)共享. 在Hibernate中,應(yīng)用級(jí)緩存由SessionFactory實(shí)現(xiàn)。 對(duì)同一資源的訪問,可能會(huì)引起數(shù)據(jù)同步錯(cuò)誤,但如果對(duì)訪問線程進(jìn)行同步處理,又會(huì)影響并發(fā)性能。 3.分布式緩存:即在多個(gè)應(yīng)用實(shí)例,多個(gè)JVM間共享的緩存策略。 分布式服務(wù)器:多個(gè)服務(wù)器之間使用網(wǎng)關(guān)——————把多個(gè)請(qǐng)求隨機(jī)分布在多個(gè)服務(wù)器上進(jìn)行處理; 還可以使用均衡的分配方式,設(shè)定某一個(gè)服務(wù)器最大承載量,超過的話就會(huì)分配黑另外一個(gè)服務(wù)器; 這些服務(wù)器之間有個(gè)要求,就是同步,服務(wù)器處理之后的數(shù)據(jù)是同步的,服務(wù)器之間都會(huì)認(rèn)可##持久層框架的查詢順序 1.先找一級(jí)緩存:如果有就拿來用。 2.如果沒有一級(jí)緩存,就進(jìn)入二級(jí)緩存,從二級(jí)緩存再找一次。 3.如果還是沒有二級(jí)緩存,那么就進(jìn)入數(shù)據(jù)庫(kù)進(jìn)行SQL查詢?cè)诙?jí)緩存和數(shù)據(jù)庫(kù)之間會(huì)加一個(gè)**即時(shí)加載**或**延遲加載**(關(guān)聯(lián)關(guān)系時(shí)候用的最多)##Hibernate的延遲加載 在有關(guān)聯(lián)的持久類對(duì)象中,對(duì)一個(gè)對(duì)象進(jìn)行的查詢也會(huì)向另一個(gè)對(duì)象進(jìn)行查詢。 所謂延遲加載就是當(dāng)在真正需要數(shù)據(jù)的時(shí)候,才真正執(zhí)行數(shù)據(jù)加載操作。 hibernate3.X的lazy(延遲加載)默認(rèn)值是true,需要注意。 延遲加載類型 1.實(shí)體對(duì)象的延遲加載 2.集合的延遲加載 3.屬性的延遲加載40.applicationContext.xml配置 第一步,制定自動(dòng)掃描規(guī)則,將@Service,@Repository,@Component <context:component-scanbase-package="com"> </context:component-scan> 第二步,配置數(shù)據(jù)源連接信息 <beanid="dataSource"class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <propertyname="driverClassName"value="org.gjt.mm.mysql.Driver"></property> <propertyname="url"value="jdbc:mysql://localhost:3306/sm?useUnicode=true&characterEncoding=UTF-8&useSSL=true"></property> <propertyname="username"value="root"></property> <propertyname="password"value="lovo"></property> </bean> 第三步,配置Session工廠 <beanid="sqlSessionFactory"class="org.mybatis.spring.SqlSessionFactoryBean"> <propertyname="dataSource"ref="dataSource"></property> <propertyname="configLocation"value="classpath:mybatis.cfg.xml"></property> <propertyname="typeAliasesPackage"value="com.forest.datamag.beans,com.forest.eventmag.beans,com.forest.logmag.beans,com.forest.usermag.beans"></property> </bean> 掃描MapperScanner文件,并與Session進(jìn)行關(guān)聯(lián) <beanid="mapperScanner"class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <propertyname="basePackage"value="com.forest.datamag.mapper,com.forest.eventmag.mapper,com.forest.logmag.mapper,com.forest.usermag.mapper"></property> <propertyname="sqlSessionFactory"ref="sqlSessionFactory"></property> </bean> 配置事務(wù)管理 <beanid="txManage"class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <propertyname="dataSource"ref="dataSource"></property> </bean> 第一種事務(wù)管理方式,注解來管理事務(wù),只適合單數(shù)據(jù)庫(kù)操作,并且在開發(fā)中使用較少,因?yàn)檫@種方式,還是屬于編程式事務(wù)范疇 <tx:annotation-driventransaction-manager="txManage"/> 第二種聲明式事務(wù)方式,采用AOP的思想來完成 <tx:adviceid="txAdvice"transaction-manager="txManage"> <tx:attributes> <tx:methodname="*"propagation="REQUIRED"read-only="true"rollback-for="java.lang.Exception"></tx:method> <tx:methodname="insert*"propagation="REQUIRED"read-only="false"rollback-for="java.lang.Exception"isolation="REPEATABLE_READ"></tx:method> <tx:methodname="save*"propagation="REQUIRED"read-only="false"rollback-for="java.lang.Exception"isolation="REPEATABLE_READ"></tx:method> <tx:methodname="update*"propagation="REQUIRED"read-only="false"rollback-for="java.lang.Exception"isolation="REPEATABLE_READ"></tx:method> <tx:methodname="delete*"propagation="REQUIRED"read-only="false"rollback-for="java.lang.Exception"isolation="REPEATABLE_READ"></tx:method> <tx:methodname="get*"propagation="SUPPORTS"read-only="true"></tx:method> <tx:methodname="query*"propagation="SUPPORTS"read-only="true"></tx:method> <tx:methodname="select*"propagation="SUPPORTS"read-only="true"></tx:method> </tx:attributes> </tx:advice> <aop:config> <aop:pointcutexpression="execution(*com.forest.*.service.impl.*.*(..))"id="serviceMethods"></aop:pointcut> <aop:advisoradvice-ref="txAdvice"pointcut-ref="serviceMethods"></aop:advisor> </aop:config> 編程事務(wù)管理聲明事務(wù)管理:將事務(wù)聲明在Spring配置文件中,被容器進(jìn)行事務(wù)管理,通過AOP的思想進(jìn)行事務(wù)管理。##事務(wù)傳播級(jí)別7種事務(wù)的傳播:當(dāng)多個(gè)具有事務(wù)控制能力的Service實(shí)現(xiàn)類的方法互調(diào)時(shí),事務(wù)是如何傳播控制的。 1.REQUIRED 如果當(dāng)前沒有事務(wù),就新建一個(gè)事務(wù)--CUD使用。如果已經(jīng)存在一個(gè)事務(wù)中,加入到這個(gè)事務(wù)中。這是最常見的選擇. 2.SUPPORTS 支持當(dāng)前事務(wù),如果當(dāng)前沒有事務(wù),就以非事務(wù)方式執(zhí)行 3.MANDATORY 使用當(dāng)前的事務(wù),如果當(dāng)前沒有事務(wù),就拋出異常。 4.REQUIRES_NEW 無(wú)論有沒有事務(wù),都新建一個(gè)事務(wù),如果當(dāng)前存在事務(wù),把當(dāng)前事務(wù)掛起。 5.NOT_SUPPORTED 以非事務(wù)方式執(zhí)行操作,如果當(dāng)前存在事務(wù),就把當(dāng)前事務(wù)掛起。 6.NEVER 以非事務(wù)方式執(zhí)行,如果當(dāng)前存在事務(wù),則拋出異常。 7.NESTED 如果當(dāng)前存在事務(wù),則在嵌套事務(wù)內(nèi)執(zhí)行。如果當(dāng)前沒有事務(wù),則執(zhí)行與REQUIRED類似的操作HashMap概述HashMap是基于哈希表的Map接口的非同步實(shí)現(xiàn)。此實(shí)現(xiàn)提供所有可選的映射操作,并允許使用null值和null鍵。此類不保證映射的順序,特別是它不保證該順序恒久不變。HashMap的數(shù)據(jù)結(jié)構(gòu)在Java編程語(yǔ)言中,最基本的結(jié)構(gòu)就是兩種,一個(gè)是數(shù)組,另外一個(gè)是模擬指針(引用),所有的數(shù)據(jù)結(jié)構(gòu)都可以用這兩個(gè)基本結(jié)構(gòu)來構(gòu)造的,HashMap也不例外。HashMap實(shí)際上是一個(gè)“鏈表散列”的數(shù)據(jù)結(jié)構(gòu),即數(shù)組和鏈表的結(jié)合體。從上圖中可以看出,HashMap底層就是一個(gè)數(shù)組結(jié)構(gòu),數(shù)組中的每一項(xiàng)又是一個(gè)鏈表。當(dāng)新建一個(gè)HashMap的時(shí)候,就會(huì)初始化一個(gè)數(shù)組。簡(jiǎn)單來說,HashMap由數(shù)組+鏈表組成的,數(shù)組是HashMap的主體,鏈表則是主要為了解決哈希沖突而存在的,如果定位到的數(shù)組位置不含鏈表(當(dāng)前entry的next指向null),那么對(duì)于查找,添加等操作很快,僅需一次尋址即可;如果定位到的數(shù)組包含鏈表,對(duì)于添加操作,其時(shí)間復(fù)雜度依然為O(1),因?yàn)樽钚碌腅ntry會(huì)插入鏈表頭部,僅需簡(jiǎn)單改變引用鏈即可,而對(duì)于查找操作來講,此時(shí)就需要遍歷鏈表,然后通過key對(duì)象的equals方法逐一比對(duì)查找。所以,性能考慮,HashMap中的鏈表出現(xiàn)越少,性能才會(huì)越好HashMap的工作原理以及存取方法過程HashMap的工作原理:HashMap是基于散列法(又稱哈希法hashing)的原理,使用put(key,value)存儲(chǔ)對(duì)象到HashMap中,使用get(key)從HashMap中獲取對(duì)象。當(dāng)我們給put()方法傳遞鍵和值時(shí),我們先對(duì)鍵調(diào)用hashCode()方法,返回的hashCode用于找到bucket(桶)位置來儲(chǔ)存Entry對(duì)象。”HashMap是在bucket中儲(chǔ)存鍵對(duì)象和值對(duì)象,作為Map.Entry。并不是僅僅只在bucket中存儲(chǔ)值。HashMap具體的存取過程如下:
put鍵值對(duì)的方法的過程是:
1、獲取key;
2、通過hash函數(shù)得到hash值;
inthash=key.hashCode();//獲取key的hashCode,這個(gè)值是一個(gè)固定的int值3、得到桶號(hào)(一般都為hash值對(duì)桶數(shù)求模),也即數(shù)組下標(biāo)intindex=hash%Entry[].length。//獲取數(shù)組下標(biāo):key的hash值對(duì)Entry數(shù)組長(zhǎng)度進(jìn)行取余4、存放key和value在桶內(nèi)。
table[index]=Entry對(duì)象;get值方法的過程是:
1、獲取key
2、通過hash函數(shù)得到hash值
inthash=key.hashCode();3、得到桶號(hào)(一般都為hash值對(duì)桶數(shù)求模)
intindex=hash%Entry[].length;4、比較桶的內(nèi)部元素是否與key相等,若都不相等,則沒有找到。5、取出相等的記錄的value。HashMap中直接地址用hash函數(shù)生成;解決沖突,用比較函數(shù)解決。如果每個(gè)桶內(nèi)部只有一個(gè)元素,那么查找的時(shí)候只有一次比較。當(dāng)許多桶內(nèi)沒有值時(shí),許多查詢就會(huì)更快了(指查不到的時(shí)候)。HashMap和HashTable的區(qū)別一種比較簡(jiǎn)單的回答是:(1)HashMap是非線程安全的,HashTable是線程安全的。(2)HashMap的鍵和值都允許有null存在,而HashTable則都不行。(3)因?yàn)榫€程安全、哈希效率的問題,HashMap效率比HashTable的要高。6.
HashTable和ConCurrentHashMap的對(duì)比
先對(duì)ConcurrentHashMap進(jìn)行一些介紹吧,它是線程安全的HashMap的實(shí)現(xiàn)。HashTable里使用的是synchronized關(guān)鍵字,這其實(shí)是對(duì)對(duì)象加鎖,鎖住的都是對(duì)象整體,當(dāng)Hashtable的大小增加到一定的時(shí)候,性能會(huì)急劇下降,因?yàn)榈鷷r(shí)需要被鎖定很長(zhǎng)的時(shí)間。ConcurrentHashMap算是對(duì)上述問題的優(yōu)化ConcurrentHashMap引入了分割(Segment),上面代碼中的最后一行其實(shí)就可以理解為把一個(gè)大的Map拆分成N個(gè)小的HashTable,在put方法中,會(huì)根據(jù)hash(paramK.hashCode())來決定具體存放進(jìn)哪個(gè)Segment,如果查看Segment的put操作,我們會(huì)發(fā)現(xiàn)內(nèi)部使用的同步機(jī)制是基于lock操作的,這樣就可以對(duì)Map的一部分(Segment)進(jìn)行上鎖,這樣影響的只是將要放入同一個(gè)Segment的元素的put操作,保證同步的時(shí)候,鎖住的不是整個(gè)Map(HashTable就是這么做的),相對(duì)于HashTable提高了多線程環(huán)境下的性能,因此HashTable已經(jīng)被淘汰了。
7.
HashMap和ConCurrentHashMap的對(duì)比最后對(duì)這倆兄弟做個(gè)區(qū)別總結(jié)吧:(1)經(jīng)過4.2的分析,我們知道ConcurrentHashMap對(duì)整個(gè)桶數(shù)組進(jìn)行了分割分段(Segment),然后在每一個(gè)分段上都用lock鎖進(jìn)行保護(hù),相對(duì)于HashTable的syn關(guān)鍵字鎖的粒度更精細(xì)了一些,并發(fā)性能更好,而HashMap沒有鎖機(jī)制,不是線程安全的。(2)HashMap的鍵值對(duì)允許有null,但是ConCurrentHashMap都不允許。(3)有并發(fā)訪問的時(shí)候用concurrentHashMap效率比用鎖的hashmap好,功能上是可以的,但是畢竟concurrentHashMap這種數(shù)據(jù)結(jié)構(gòu)要復(fù)雜一些,如果能保證只在單一縣城下讀寫,不會(huì)發(fā)生并發(fā)的讀寫,就可以使用hashMap,concurrentHashMap讀不加鎖,寫只加部分鎖。在多線程下得高性能讀寫用比較好。但是這也是要用空間來?yè)Q的。(4)HashMap.所有已經(jīng)實(shí)現(xiàn)的接口:serializable,cloneable,Map?;诠1淼膍ap接口的實(shí)現(xiàn)。此實(shí)現(xiàn)提供所有可選的映射操作。并允許使用null值和null鍵。(除了非同步和允許使用null之外,hashmap類與hashtable大致相同。此類不保證映射順序,特別是它不保證該順序恒久不變)類concurrenthashmap實(shí)現(xiàn)接口:serializable,concurrentmap,map4.數(shù)據(jù)庫(kù)索引:索引有單列索引
復(fù)合索引之說
如何某表的某個(gè)字段有主鍵約束和唯一性約束,則Oracle則會(huì)自動(dòng)在相應(yīng)的約束列上建議唯一索引。數(shù)據(jù)庫(kù)索引主要進(jìn)行提高訪問速度。建設(shè)原則:1、索引應(yīng)該經(jīng)常建在Where子句經(jīng)常用到的列上。如果某個(gè)大表經(jīng)常使用某個(gè)字段進(jìn)行查詢,并且檢索行數(shù)小于總表行數(shù)的5%。則應(yīng)該考慮。2、對(duì)于兩表連接的字段,應(yīng)該建立索引。如果經(jīng)常在某表的一個(gè)字段進(jìn)行OrderBy則也經(jīng)過進(jìn)行索引。3、不應(yīng)該在小表上建設(shè)索引。創(chuàng)建索引:
單一索引:CreateIndex<Index-Name>On<Table_Name>(Column_Name);復(fù)合索引:CreateIndexi_deptno_jobonemp(deptno,job);—>在emp表的deptno、job列建立索引。select*fromempwheredeptno=66andjob='sals'->走索引。select*fromempwheredeptno=66ORjob='sals'->將進(jìn)行全表掃描。不走索引select*fromempwheredeptno=66->走索引。select*fromempwherejob='sals'->進(jìn)行全表掃描、不走索引。如果在where子句中有OR操作符或單獨(dú)引用Job列(索引列的后面列)則將不會(huì)走索引,將會(huì)進(jìn)行全表掃描。Sql優(yōu)化:當(dāng)Oracle數(shù)據(jù)庫(kù)拿到SQL語(yǔ)句時(shí),其會(huì)根據(jù)查詢優(yōu)化器分析該語(yǔ)句,并根據(jù)分析結(jié)果生成查詢執(zhí)行計(jì)劃。
也就是說,數(shù)據(jù)庫(kù)是執(zhí)行的查詢計(jì)劃,而不是Sql語(yǔ)句。
查詢優(yōu)化器有rule-based-optimizer(基于規(guī)則的查詢優(yōu)化器)和Cost-Based-optimizer(基于成本的查詢優(yōu)化器)。
其中基于規(guī)則的查詢優(yōu)化器在10g版本中消失。
對(duì)于規(guī)則查詢,其最后查詢的是全表掃描。而CBO則會(huì)根據(jù)統(tǒng)計(jì)信息進(jìn)行最后的選擇。
1、先執(zhí)行From->Where->GroupBy->聚集函數(shù)->having->計(jì)算表達(dá)式->select字段->OrderBy2、執(zhí)行From字句是從右往左進(jìn)行執(zhí)行。因此必須選擇記錄條數(shù)最少的表放在右邊。這是為什么呢?3、對(duì)于Where字句其執(zhí)行順序是從后向前執(zhí)行、因此可以過濾最大數(shù)量記錄的條件必須寫在Where子句的末尾,而對(duì)于多表之間的連接,則寫在之前。
因?yàn)檫@樣進(jìn)行連接時(shí),可以去掉大多不重復(fù)的項(xiàng)。4.SELECT子句中避免使用(*)ORACLE在解析的過程中,會(huì)將’*’依次轉(zhuǎn)換成所有的列名,這個(gè)工作是通過查詢數(shù)據(jù)字典完成的,這意味著將耗費(fèi)更多的時(shí)間5、索引失效的情況:
①NotNull/Null如果某列建立索引,當(dāng)進(jìn)行Select*fromempwheredeptoisnotnull/isnull。則會(huì)是索引失效。
②索引列上不要使用函數(shù),SELECTColFROMtblWHEREsubstr(name,1,3)='ABC'
或者SELECTColFROMtblWHEREnameLIKE'%ABC%'而SELECTColFROMtblWHEREnameLIKE'ABC%'會(huì)使用索引。③索引列上不能進(jìn)行計(jì)算SELECTColFROMtblWHEREcol/10>10則會(huì)使索引失效,應(yīng)該改成
SELECTColFROMtblWHEREcol>10*10④索引列上不要使用NOT(!=、<>)如:SELECTColFROMtblWHEREcol!=10
應(yīng)該改成:SELECTColFROMtblWHEREcol>10ORcol<10。6、用UNION替換OR(適用于索引列)
union:是將兩個(gè)查詢的結(jié)果集進(jìn)行追加在一起,它不會(huì)引起列的變化。由于是追加操作,需要兩個(gè)結(jié)果集的列數(shù)應(yīng)該是相關(guān)的,
并且相應(yīng)列的數(shù)據(jù)類型也應(yīng)該相當(dāng)?shù)?。union返回兩個(gè)結(jié)果集,同時(shí)將兩個(gè)結(jié)果集重復(fù)的項(xiàng)進(jìn)行消除。如果不進(jìn)行消除,用UNOINALL.通常情況下,用UNION替換WHERE子句中的OR將會(huì)起到較好的效果.對(duì)索引列使用OR將造成全表掃描.注意,以上規(guī)則只針對(duì)多個(gè)索引列有效.
如果有column沒有被索引,查詢效率可能會(huì)因?yàn)槟銢]有選擇OR而降低.在下面的例子中,LOC_ID和REGION上都建有索引.高效:
SELECTLOC_ID,LOC_DESC,REGION
FROMLOCATION
WHERELOC_ID=10
UNION
SELECTLOC_ID,LOC_DESC,REGION
FROMLOCATION
WHEREREGION=“MELBOURNE”低效:
SELECTLOC_ID,LOC_DESC,REGION
FROMLOCATION
WHERELOC_ID=10ORREGION=“MELBOURNE”
如果你堅(jiān)持要用OR,那就需要返回記錄最少的索引列寫在最前面.7.用EXISTS替代IN、用NOTEXISTS替代NOTIN
在許多基于基礎(chǔ)表的查詢中,為了滿足一個(gè)條件,往往需要對(duì)另一個(gè)表進(jìn)行聯(lián)接.在這種情況下,使用EXISTS(或NOTEXISTS)通常將提高查詢的效率.
在子查詢中,NOTIN子句將執(zhí)行一個(gè)內(nèi)部的排序和合并.無(wú)論在哪種情況下,NOTIN都是最低效的(因?yàn)樗鼘?duì)子查詢中的表執(zhí)行了一個(gè)全表遍歷).
為了避免使用NOTIN,我們可以把它改寫成外連接(OuterJoins)或NOTEXISTS.例子:高效:SELECT*FROMEMP(基礎(chǔ)表)WHEREEMPNO>0ANDEXISTS(SELECT‘X’FROMDEPTWHEREDEPT.DEPTNO=EMP.DEPTNOANDLOC=‘MELB’)低效:SELECT*FROMEMP(基礎(chǔ)表)WHEREEMPNO>0ANDDEPTNOIN(SELECTDEPTNOFROMDEPTWHERELOC=‘MELB’)EXISTS與IN的使用效率的問題,通常情況下采用exists要比in效率高,因?yàn)镮N不走索引,但要看實(shí)際情況具體使用:
IN適合于外表大而內(nèi)表小的情況;EXISTS適合于外表小而內(nèi)表大的情況應(yīng)該在表中經(jīng)常搜索的列或者按照順序訪問的列上創(chuàng)建聚簇索引。當(dāng)創(chuàng)建聚簇索引時(shí),應(yīng)該考慮這些因素:每一個(gè)表只能有一個(gè)聚簇索引,因?yàn)楸碇袛?shù)據(jù)的物理順序
只能有一個(gè);在創(chuàng)建任何非聚簇索引之前創(chuàng)建聚簇索引,這是因?yàn)榫鄞厮饕淖兞吮碇行械奈锢眄樞?,?shù)據(jù)行按
照一定的順序排列,并且自動(dòng)維護(hù)這個(gè)順序.聚簇索引的平均大小大約是數(shù)據(jù)表的百分之五,但是,實(shí)際的聚簇索引的大小常常根據(jù)索引列的大小變化而變化;在索引的創(chuàng)建過程中,SQLServer臨時(shí)使用當(dāng)前\o"MySQL知識(shí)庫(kù)"數(shù)據(jù)庫(kù)的磁盤空間,當(dāng)創(chuàng)建聚簇索引時(shí),需要1.2倍的表空間的大小,因此,一定要保證有足夠的空間來創(chuàng)建聚簇索引。
當(dāng)系統(tǒng)訪問有非聚簇索引的表中數(shù)據(jù)時(shí),并且這種非聚簇索引創(chuàng)建在聚簇索引上,那么
它首先從非聚簇索引來找到指向聚簇索引的指針,然后通過使用聚簇索引來找到數(shù)據(jù)。
當(dāng)需要以多種方式檢索數(shù)據(jù)時(shí),非聚簇索引是非常有用的。當(dāng)創(chuàng)建非聚簇索引時(shí),要考慮這些情況:在缺省情況下,所創(chuàng)建的索引是非聚簇索引;在每一個(gè)表上面,可以創(chuàng)建不多于249個(gè)非聚簇索引,而聚簇索引最多只能有一個(gè)。
6.mysql索引的優(yōu)缺點(diǎn)一、為什么要?jiǎng)?chuàng)建索引呢(優(yōu)點(diǎn))?創(chuàng)建索引可以大大提高系統(tǒng)的性能。
第一,
通過創(chuàng)建唯一性索引,可以保證數(shù)據(jù)庫(kù)表中每一行數(shù)據(jù)的唯一性。
第二,
可以大大加快數(shù)據(jù)的檢索速度,這也是創(chuàng)建索引的最主要的原因。
第三,
可以加速表和表之間的連接,特別是在實(shí)現(xiàn)數(shù)據(jù)的參考完整性方面特別有意義。
第四,
在使用分組和排序子句進(jìn)行數(shù)據(jù)檢索時(shí),同樣可以顯著減少查詢中分組和排序的時(shí)間。
第五,
通過使用索引,可以在查詢的過程中,使用優(yōu)化隱藏器,提高系統(tǒng)的性能。
二、建立方向索引的不利因素(缺點(diǎn))也許會(huì)有人要問:增加索引有如此多的優(yōu)點(diǎn),為什么不對(duì)表中的每一個(gè)列創(chuàng)建一個(gè)索引呢?這種想法固然有其合理性,然而也有其片面性。雖然,索引有許多優(yōu)點(diǎn),但是,為表中的每一個(gè)列都增加索引,是非常不明智的。這是因?yàn)椋黾铀饕灿性S多不利的一個(gè)方面。
第一,
創(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ù),這樣就降低了數(shù)據(jù)的維護(hù)速度。
三、創(chuàng)建方向索引的準(zhǔn)則索引是建立在數(shù)據(jù)庫(kù)表中的某些列的上面。因此,在創(chuàng)建索引的時(shí)候,應(yīng)該仔細(xì)考慮在哪些列上可以創(chuàng)建索引,在哪些列上不能創(chuàng)建索引。
一般來說,應(yīng)該在這些列上創(chuàng)建索引。
第一,
在經(jīng)常需要搜索的列上,可以加快搜索的速度;
第二,
在作為主鍵的列上,強(qiáng)制該列的唯一性和組織表中數(shù)據(jù)的排列結(jié)構(gòu);
第三,
在經(jīng)常用在連接的列上,這些列主要是一些外鍵,可以加快連接的速度;
第四,
在經(jīng)常需要根據(jù)范圍進(jìn)行搜索的列上創(chuàng)建索引,因?yàn)樗饕呀?jīng)排序,其指定的范圍是連續(xù)的;
第五,
在經(jīng)常需要排序的列上創(chuàng)建索引,因?yàn)樗饕呀?jīng)排序,這樣查詢可以利用索引的排序,加快排序查詢時(shí)間;
第六,
在經(jīng)常使用在WHERE子句中的列上面創(chuàng)建索引,加快條件的判斷速度。
同樣,對(duì)于有些列不應(yīng)該創(chuàng)建索引。一般來說,不應(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)該增加索引。這是因?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)建索引。
四、創(chuàng)建索引的方法創(chuàng)建索引有多種方法,這些方法包括直接創(chuàng)建索引的方法和間接創(chuàng)建索引的方法。
第一,
直接創(chuàng)建索引,例如使用CREATEINDEX語(yǔ)句或者使用創(chuàng)建索引向?qū)А?/p>
第二,
間接創(chuàng)建索引,例如在表中定義主鍵約束或者唯一性鍵約束時(shí),同時(shí)也創(chuàng)建了索引。
雖然,這兩種方法都可以創(chuàng)建索引,但是,它們創(chuàng)建索引的具體內(nèi)容是有區(qū)別的。
使用CREATEINDEX語(yǔ)句或者使用創(chuàng)建索引向?qū)韯?chuàng)建索引,這是最基本的索引創(chuàng)建方式,并且這種方法最具有柔性,可以定制創(chuàng)建出符合自己需要的索引。在使用這種方式創(chuàng)建索引時(shí),可以使用許多選項(xiàng),例如指定數(shù)據(jù)頁(yè)的充滿度、進(jìn)行排序、整理統(tǒng)計(jì)信息等,這樣可以優(yōu)化索引。使用這種方法,可以指定索引的類型、唯一性和復(fù)合性,也就是說,既可以創(chuàng)建聚簇索引,也可以創(chuàng)建非聚簇索引,既可以在一個(gè)列上創(chuàng)建索引,也可以在兩個(gè)或者兩個(gè)以上的列上創(chuàng)建索引。
通過定義主鍵約束或者唯一性鍵約束,也可以間接創(chuàng)建索引。主鍵約束是一種保持?jǐn)?shù)據(jù)完整性的邏輯,它限制表中的記錄有相同的主鍵記錄。在創(chuàng)建主鍵約束時(shí),系統(tǒng)自動(dòng)創(chuàng)建了一個(gè)唯一性的聚簇索引。雖然,在邏輯上,主鍵約束是一種重要的結(jié)構(gòu),但是,在物理結(jié)構(gòu)上,與主鍵約束相對(duì)應(yīng)的結(jié)構(gòu)是唯一性的聚簇索引。換句話說,在物理實(shí)現(xiàn)上,不存在主鍵約束,而只存在唯一性的聚簇索引。同樣,在創(chuàng)建唯一性鍵約束時(shí),也同時(shí)創(chuàng)建了索引,這種索引則是唯一性的非聚簇索引。因此,當(dāng)使用約束創(chuàng)建索引時(shí),索引的類型和特征基本上都已經(jīng)確定了,由用戶定制的余地比較小。
當(dāng)在表上定義主鍵或者唯一性鍵約束時(shí),如果表中已經(jīng)有了使用CREATEINDEX語(yǔ)句創(chuàng)建的標(biāo)準(zhǔn)索引時(shí),那么主鍵約束或者唯一性鍵約束創(chuàng)建的索引覆蓋以前創(chuàng)建的標(biāo)準(zhǔn)索引。也就是說,主鍵約束或者唯一性鍵約束創(chuàng)建的索引的優(yōu)先級(jí)高于使用CREATEINDEX語(yǔ)句創(chuàng)建的索引。
五、索引的特征
索引有兩個(gè)特征,即唯一性索引和復(fù)合索引。
唯一性索引保證在索引列中的全部數(shù)據(jù)是唯一的,不會(huì)包含冗余數(shù)據(jù)。如果表中已經(jīng)有一個(gè)主鍵約束或者唯一性鍵約束,那么當(dāng)創(chuàng)建表或者修改表時(shí),SQLServer自動(dòng)創(chuàng)建一個(gè)唯一性索引。然而,如果必須保證唯一性,那么應(yīng)該創(chuàng)建主鍵約束或者唯一性鍵約束,而不是創(chuàng)建一個(gè)唯一性索引。當(dāng)創(chuàng)建唯一性索引時(shí),應(yīng)該認(rèn)真考慮這些規(guī)則:當(dāng)在表中創(chuàng)建主鍵約束或者唯一性鍵約束時(shí),SQLServer自動(dòng)創(chuàng)建一個(gè)唯一性索引;如果表中已經(jīng)包含有數(shù)據(jù),那么當(dāng)創(chuàng)建索引時(shí),SQLServer檢查表中已有數(shù)據(jù)的冗余性;每當(dāng)使用插入語(yǔ)句插入數(shù)據(jù)或者使用修改語(yǔ)句修改數(shù)據(jù)時(shí),SQLServer檢查數(shù)據(jù)的冗余性:如果有冗余值,那么SQLServer取消該語(yǔ)句的執(zhí)行,并且返回一個(gè)錯(cuò)誤消息;確保表中的每一行數(shù)據(jù)都有一個(gè)唯一值,這樣可以確保每一個(gè)實(shí)體都可以唯一確認(rèn);只能在可以保證實(shí)體完整性的列上創(chuàng)建唯一性索引,例如,不能在人事表中的姓名列上創(chuàng)建唯一性索引,因?yàn)槿藗兛梢杂邢嗤男彰?/p>
復(fù)合索引就是一個(gè)索引創(chuàng)建在兩個(gè)列或者多個(gè)列上。在搜索時(shí),當(dāng)兩個(gè)或者多個(gè)列作為一個(gè)關(guān)鍵值時(shí),最好在這些列上創(chuàng)建復(fù)合索引。當(dāng)創(chuàng)建復(fù)合索引時(shí),應(yīng)該考慮這些規(guī)則:最多可以把16個(gè)列合并成一個(gè)單獨(dú)的復(fù)合索引,構(gòu)成復(fù)合索引的列的總長(zhǎng)度不能超過900字節(jié),也就是說復(fù)合列的長(zhǎng)度不能太長(zhǎng);在復(fù)合索引中,所有的列必須來自同一個(gè)表中,不能跨表建立復(fù)合列;在復(fù)合索引中,列的排列順序是非常重要的,因此要認(rèn)真排列列的順序,原則上,應(yīng)該首先定義最唯一的列,例如在(COL1,COL2)上的索引與在(COL2,COL1)上的索引是不相同的,因?yàn)閮蓚€(gè)索引的列的順序不同;為了使查詢優(yōu)化器使用復(fù)合索引,查詢語(yǔ)句中的WHERE子句必須參考復(fù)合索引中第一個(gè)列;當(dāng)表中有多個(gè)關(guān)鍵列時(shí),復(fù)合索引是非常有用的;使用復(fù)合索引可以提高查詢性能,減少在一個(gè)表中所創(chuàng)建的索引數(shù)量。
六、索引的類型根據(jù)索引的順序與數(shù)據(jù)表的物理順序是否相同,可以把索引分成兩種類型。一種是數(shù)據(jù)表的物理順序與索引順序相同的聚簇索引,另一種是數(shù)據(jù)表的物理順序與索引順序不相同的非聚簇索引。
七、聚簇索引的體系結(jié)構(gòu)索引的結(jié)構(gòu)類似于樹狀結(jié)構(gòu),樹的頂部稱為葉級(jí),樹的其它部分稱為非葉級(jí),樹的根部在非葉級(jí)中。同樣,在聚簇索引中,聚簇索引的葉級(jí)和非葉級(jí)構(gòu)成了一個(gè)樹狀結(jié)構(gòu),索引的最低級(jí)是葉級(jí)。在聚簇索引中,表中的數(shù)據(jù)所在的數(shù)據(jù)頁(yè)是葉級(jí),在葉級(jí)之上的索引頁(yè)是非葉級(jí),索引數(shù)據(jù)所在的索引頁(yè)是非葉級(jí)。在聚簇索引中,數(shù)據(jù)值的順序總是按照升序排列。
應(yīng)該在表中經(jīng)常搜索的列或者按照順序訪問的列上創(chuàng)建聚簇索引。當(dāng)創(chuàng)建聚簇索引時(shí),應(yīng)該考慮這些因素:每一個(gè)表只能有一個(gè)聚簇索引,因?yàn)楸碇袛?shù)據(jù)的物理順序只能有一個(gè);表中行的物理順序和索引中行的物理順序是相同的,在創(chuàng)建任何非聚簇索引之前創(chuàng)建聚簇索引,這是因?yàn)榫鄞厮饕淖兞吮碇行械奈锢眄樞颍瑪?shù)據(jù)行按照一定的順序排列,并且自動(dòng)維護(hù)這個(gè)順序;關(guān)鍵值的唯一性要么使用UNIQUE關(guān)鍵字明確維護(hù),要么由一個(gè)內(nèi)部的唯一標(biāo)識(shí)符明確維護(hù),這些唯一性標(biāo)識(shí)符是系統(tǒng)自己使用的,用戶不能訪問;聚簇索引的平均大小大約是數(shù)據(jù)表的百分之五,但是,實(shí)際的聚簇索引的大小常常根據(jù)索引列的大小變化而變化;在索引的創(chuàng)建過程中,SQLServer臨時(shí)使用當(dāng)前數(shù)據(jù)庫(kù)的磁盤空間,當(dāng)創(chuàng)建聚簇索引時(shí),需要1.2倍的表空間的大小,因此,一定要保證有足夠的空間來創(chuàng)建聚簇索引。
當(dāng)系統(tǒng)訪問表中的數(shù)據(jù)時(shí),首先確定在相應(yīng)的列上是否存在有索引和該索引是否對(duì)要檢索的數(shù)據(jù)有意義。如果索引存在并且該索引非常有意義,那么系統(tǒng)使用該索引訪問表中的記錄。系統(tǒng)從索引開始瀏覽到數(shù)據(jù),索引瀏覽則從樹狀索引的根部開始。從根部開始,搜索值與每一個(gè)關(guān)鍵值相比較,確定搜索值是否大于或者等于關(guān)鍵值。這一步重復(fù)進(jìn)行,直到碰上一個(gè)比搜索值大的關(guān)鍵值,或者該搜索值大于或者等于索引頁(yè)上所有的關(guān)鍵值為止。
系統(tǒng)如何訪問表中的數(shù)據(jù)
一般地,系統(tǒng)訪問數(shù)據(jù)庫(kù)中的數(shù)據(jù),可以使用兩種方法:表掃描和索引查找。第一種方法是表掃描,就是指系統(tǒng)將指針放置在該表的表頭數(shù)據(jù)所在的數(shù)據(jù)頁(yè)上,然后按照數(shù)據(jù)頁(yè)的排列順序,一頁(yè)一頁(yè)地從前向后掃描該表數(shù)據(jù)所占有的全部數(shù)據(jù)頁(yè),直至掃描完表中的全部記錄。在掃描時(shí),如果找到符合查詢條件的記錄,那么就將這條記錄挑選出來。最后,將全部挑選出來符合查詢語(yǔ)句
溫馨提示
- 1. 本站所有資源如無(wú)特殊說明,都需要本地電腦安裝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ù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- GB/T 2812-2024頭部防護(hù)通用測(cè)試方法
- 二零二五版裝修工程合同范本:合同生效與解除條件2篇
- 2024跨區(qū)域電網(wǎng)工程建設(shè)與運(yùn)營(yíng)管理合同
- 二零二五版家居行業(yè)導(dǎo)購(gòu)員聘用與考核合同3篇
- 二零二五年餐飲行業(yè)食堂承包合作協(xié)議范本3篇
- 二零二五版家庭住家保姆綜合能力培訓(xùn)聘用合同3篇
- 2025年度新能源出租車特許經(jīng)營(yíng)合同3篇
- 二零二五年度跨境電商進(jìn)口商品代理銷售合同9篇
- 二零二五年股權(quán)質(zhì)押貸款擔(dān)保合同3篇
- 二零二五按揭房離婚財(cái)產(chǎn)分割與子女監(jiān)護(hù)協(xié)議范本3篇
- 患者跌倒墜床的應(yīng)急預(yù)案試題及答案
- GB/T 24128-2018塑料塑料防霉劑的防霉效果評(píng)估
- 福建省地方標(biāo)準(zhǔn)《先張法預(yù)應(yīng)力混凝土管樁基礎(chǔ)技術(shù)規(guī)程》DBJ13-2023
- 危險(xiǎn)作業(yè)監(jiān)護(hù)人員培訓(xùn)
- 職業(yè)病防治企業(yè)臺(tái)賬樣本
- 充電樁驗(yàn)收表
- 城市水環(huán)境新型污染物的去除新技術(shù)課件
- 中長(zhǎng)期貸款按實(shí)際投向統(tǒng)計(jì)統(tǒng)計(jì)制度
- 新媒體營(yíng)銷完整版教學(xué)課件最全ppt整套教程電子講義(最新)
- 鍋爐專業(yè)2020年防非停措施
- 中國(guó)鐵塔股份有限公司通信鐵塔、機(jī)房施工及驗(yàn)收規(guī)范(試行)
評(píng)論
0/150
提交評(píng)論