《Java程序員面試筆試寶典》學(xué)習(xí)筆記(持續(xù)更新……)

????本文是我自己在秋招復(fù)習(xí)時的讀書筆記陋气,整理的知識點劳吠,也是為了防止忘記,尊重勞動成果巩趁,轉(zhuǎn)載注明出處哦痒玩!如果你也喜歡,那就點個小心心,文末贊賞一杯豆奶吧蠢古,嘻嘻奴曙。 讓我們共同成長吧……


一、Java基礎(chǔ)知識

基本概念

1草讶、Java語言特點

????????面向?qū)ο笄⒃恪⑵脚_無關(guān)、很多內(nèi)置庫堕战、對web應(yīng)用開發(fā)的支持坤溃、較好的安全性和健壯性、出去C++中的指針多繼承等特性

2嘱丢、Java與C++的異同

????????同:都是面向?qū)ο笳Z言薪介,都有繼承、封裝和多態(tài)的面向?qū)ο笏枷?/p>

????????異:Java為解釋型語言屿讽,C++是編譯型昭灵,Java執(zhí)行速度比C++慢;

????????Java可以跨平臺伐谈,但是C++不行;

????????Java為純面向?qū)ο笳Z言烂完,Java中沒有指針概念;

????????Java不支持多繼承诵棵;

????????Java不需要開發(fā)人員進(jìn)行內(nèi)存的分配和釋放抠蚣;

????????Java不支持運算符重載;

3履澳、為什么需要 public static void main(String[] args)這個方法

????????該方法是程序的入口嘶窄,JVM運行程序時會查找該方法。其中距贷,字符串?dāng)?shù)組args為開發(fā)人員在命令行下與程序交互提供了一種手段柄冲。

public與static沒有先后關(guān)系;可以用final修飾該方法忠蝗;也可以用synchronized修飾該方法现横;只要保證main的返回值為void并且有static和public修飾,不能用abstract修飾阁最。

????????雖然每個類都可以定義main()方法戒祠,但是只有與文件名相同的用public修飾的類中的main()方法才能作文整個程序的入口。

4速种、如何在main()方法執(zhí)行前輸出內(nèi)容姜盈?

????????用靜態(tài)代碼塊

5、Java程序初始化順序

????(1)靜態(tài)對象(變量)>非靜態(tài)對象(變量)配阵。其中馏颂,靜態(tài)對象(變量)初始化1次

????????? 非靜態(tài)對象(變量)可初始化多次

????(2)父類 > 子類初始化

????(3)按照成員變量定義順序初始化

????????執(zhí)行順序:父類靜態(tài)變量示血、父類靜態(tài)代碼塊、子類靜態(tài)變量饱亮、子類靜態(tài)代碼塊矾芙、父類非靜態(tài)變量、父類非靜態(tài)代碼塊近上、父類構(gòu)造函數(shù)剔宪、子類非靜態(tài)變量、子類非靜態(tài)代碼塊壹无、子類構(gòu)造函數(shù)葱绒。

6、Java中的作用域

????成員變量的4種作用域:

?????????????????????????當(dāng)前類????同一包????????子類(其他包)????????其他包

????????public????????????√? ? ? ? ? ? ?√????????????????√????????????????????????????????√

????????protected????????√????????????√????????????????√?

????????default? ? ? ? ? ? ?√? ? ? ? ? ? √??

????????private? ? ? ? ? ? ? √???

????????上述4種只能修飾成員變量斗锭,不能修飾局部變量5氐怼!岖是!private帮毁、protected不能修飾類。

7豺撑、一個Java文件是否可以定義多個類

????????可以烈疚,但是最多只能1個類被public修飾,并且該類名與文件名必須相同聪轿。如沒有public類爷肝,則文件名隨意。

8陆错、what is 構(gòu)造函數(shù)灯抛?

????構(gòu)造函數(shù):對對象實例化時初始化對象的成員變量

????特點:

????????構(gòu)造函數(shù)與類同名,不能有返回值音瓷,不能為void

????????每個類可有多個構(gòu)造函數(shù)(重載)对嚼,沒有會提供默認(rèn)構(gòu)造函數(shù)

????????構(gòu)造函數(shù)可有0個以上參數(shù)

????????構(gòu)造函數(shù)伴隨著new操作一起調(diào)用,完成初始化工作

????子類通過super來顯示調(diào)用父類的構(gòu)造绳慎,當(dāng)父類沒有無參構(gòu)造纵竖,子類構(gòu)造函數(shù)必須顯式調(diào)用父類構(gòu)造函數(shù);如果父類提供了無參構(gòu)造偷线,則子類可以不用顯式調(diào)用父類構(gòu)造。

9沽甥、為什么Java有些接口沒有任何方法声邦?

????????接口:是抽象方法的集合,是一種特殊的抽象類摆舟。接口成員的修飾符為public亥曹,常量的修飾符public static? final

????????標(biāo)識接口:你沒有任何方法聲明邓了,實現(xiàn)該接口不用實現(xiàn)任何方法。如Cloneable和Serializable

10媳瞪、Java中clone方法的作用虫几?

????????Object類中有clone()方法杏头,使用步驟:

????????????實現(xiàn)克隆的類先實現(xiàn)Cloneable 接口

????????????在類中重寫clone()方法

????????????在clone()方法中調(diào)用super.clone()。

????????????把淺賦值的引用指向原型對象新的克隆體

11、what is 反射亭枷?

????????反射提供的功能:得到對象所屬的類獲得一個類的所有成員變量和方法;在運行時創(chuàng)建對象植捎;在運行時調(diào)用對象的方法

????????獲取Class類的方法:

????????????????Class.forName(''類的路徑名');

????????????????類名.Class;

????????????????實例.getClass();

????????Java對象創(chuàng)建有4種方式:new贩挣;反射;clone();反序列化方法

12把将、 package作用轻专?

????????提供層次命名空間,解決命名沖突察蹲;對類按功能劃分请垛,是項目組織更加清晰

13、如何實現(xiàn)類似于C語言中的函數(shù)指針的功能洽议?

????????利用接口和類來實現(xiàn)宗收。具體而言,先定義一個接口绞铃,然后在接口中聲明要調(diào)用的方法镜雨,接著實現(xiàn)這個接口,最后把這個實現(xiàn)類的一個對象作為參數(shù)傳給調(diào)用程序儿捧,調(diào)用程序通過這個參數(shù)來調(diào)用指定的函數(shù)荚坞。


面向?qū)ο蠹夹g(shù)

1、面向?qū)ο笈c面向過程的區(qū)別菲盾?

????????出發(fā)點不同颓影。面向?qū)ο髮栴}域的直接要領(lǐng)直接映射到對象以及對象之間的接口上;面向過程強(qiáng)調(diào)過程的抽象化與模塊化

????????層次邏輯不同懒鉴。

????????數(shù)據(jù)處理方式與控制程序不同

2诡挂、面向?qū)ο笥心男┨卣鳎?/h4>

????????抽象、繼承临谱、封裝璃俗、多態(tài)

3、面向?qū)ο箝_發(fā)方式特點悉默?

????????較高的開發(fā)效率城豁;保證軟件的魯棒性(健壯性);保證軟件的高可維護(hù)性

4抄课、what is 繼承唱星?

????????繼承使得子類可以使用父類的一些成員變量和方法雳旅,提高代碼復(fù)用性,提高開發(fā)效率间聊。

????????特征:單繼承攒盈;子類只能繼承父類非私有的(public protected)成員變量和方法;當(dāng)子類方法和父類相同哎榴,子類方法覆蓋父類方法型豁;子類成員變量與父類相同,子類會覆蓋父類的成員變量

5叹话、組合和繼承的區(qū)別偷遗?

????????是代碼復(fù)用的兩種方式。

????????組合:指在新類中創(chuàng)建原來類的對象驼壶,重復(fù)已有類的功能氏豌,…h(huán)as …

????????繼承:通過繼承來復(fù)用父類的功能,… is? a …

6、多態(tài)實現(xiàn)機(jī)制

????????Java中多態(tài)表現(xiàn)形式:

????????方法的重載(overload):同類中多個同名的方法热凹,但這些方法有不同的參數(shù)泵喘,在編譯時就知道調(diào)用哪個方法,這是編譯時多態(tài)般妙,可看成一個類中的方法多態(tài)性纪铺。

????????方法的覆蓋(override):子類覆蓋父類的方法。java中父類引用可以指向本身和子類的對象碟渺,接口引用也可指向其實現(xiàn)類的對象鲜锚。這樣調(diào)用方法時,在運行時才動態(tài)綁定到具體的方法苫拍,這是運行時多態(tài)芜繁。

????????成員變量是無法實現(xiàn)多態(tài)的,成員變量的取值取決于所定義變量的類型绒极,這是在編譯期間確定的骏令。

7、重載和覆蓋的區(qū)別

????????重載:在同一個類中垄提,通過方法參數(shù)區(qū)別(不同參數(shù)個數(shù)榔袋,不同參數(shù)類型。參數(shù)順序)铡俐,不能通過訪問權(quán)限凰兑,返回值類型,拋出的異常區(qū)分审丘。

????????覆蓋:子類和父類之間吏够,方法的函數(shù)名和參數(shù)相同,返回值相同,拋出異常一致稿饰;對于父類的private方法是無法實現(xiàn)覆蓋的

8、抽象類和接口的區(qū)別

????????有抽象方法的類一定是抽象類露泊,抽象類可以沒有抽象方法喉镰,用abstract修飾;接口中的所有方法都是抽象的和default修飾的默認(rèn)方法惭笑,用interface修飾侣姆。二者都是支持抽象類定義的兩種機(jī)制。

????????同: 都不能實例化沉噩;接口和抽象類的子類只有全部實現(xiàn)接口或者抽象類中的方法才能實例化捺宗;

????????異:接口中只有方法的定義,而抽象類中有方法的定義和實現(xiàn)川蒙;接口被實現(xiàn)蚜厉,抽象類被繼承,接口可以多實現(xiàn)畜眨,抽象類只能單繼承昼牛;接口是 has a關(guān)系,抽象類是is a關(guān)系康聂;接口中的成員變量修飾符是public static final 贰健,成員方法是public abstract 的

9、內(nèi)部類有哪些恬汁?

????????內(nèi)部類:靜態(tài)內(nèi)部類伶椿、成員內(nèi)部類、局部內(nèi)部類氓侧、匿名內(nèi)部類

????????靜態(tài)內(nèi)部類:static修飾脊另,不能與外部內(nèi)同名,不能訪問外部類的普通成員

????????成員內(nèi)部類:可以訪問靜態(tài)和非靜態(tài)的成員甘苍,但不可定義靜態(tài)的屬性和方法尝蠕,沒有靜態(tài)成員

????????局部內(nèi)部類:在代碼塊、方法中的類载庭,不能被public看彼、protected 、private囚聚、static 修飾靖榕,只能訪問方法中定義為final的局部變量。

????????匿名內(nèi)部類:不能有構(gòu)造顽铸,不能有靜態(tài)成員茁计、方法和類;不能是public谓松、protected星压、private践剂、static;只能創(chuàng)建一個匿名內(nèi)部類實例娜膘;是局部內(nèi)部類的一種

10逊脯、獲取父類類名

????????this.getClass().getName();和super.getClass().getName();返回的都是運行時類的名字。getClass返回的是運行時的類竣贪。

????????獲取父類的名稱:使用java的反射機(jī)制军洼,getClass().getSuperclass().getName()

11、this和super的區(qū)別

????????this:指向當(dāng)前實例對象演怎,主要用來區(qū)分成員變量和方法的形參匕争。

????????super:可以用來訪問父類的方法或者成員變量。

????????this()和super()在構(gòu)造中必須位于第一行爷耀。


關(guān)鍵字

1甘桑、變量的命名規(guī)則

????????標(biāo)識符:只能有字母、數(shù)字歹叮、下劃線扇住、$組成,首字母不能為數(shù)字盗胀。不能為關(guān)鍵字艘蹋,不能有空白字符,區(qū)分大小寫

2票灰、break女阀、continue、return的區(qū)別

????????break:直接強(qiáng)行跳出循環(huán)屑迂,不在執(zhí)行剩余代碼浸策,程序從循環(huán)之后的代碼開始執(zhí)行。

????????continue:停止當(dāng)次循環(huán)惹盼,執(zhí)行下一次循環(huán)往声。

????????return:結(jié)束方法

3怔鳖、final套啤、finally英支、finalize有什么區(qū)別

????????final:用來聲明屬性、方法掩蛤、類枉昏。分別為屬性不可修改、方法不可覆蓋揍鸟、類不可被繼承

????????finally:異常處理的一部分兄裂,在try/cathch語句中,并且附帶一個語句塊,表示這段語句最終一定會被執(zhí)行

????????finalize:是Object類的一個方法晰奖,

????????JDK中哪些類不能被繼承:final修飾的類不能被繼承谈撒,如:String、StringBuffer等

4匾南、assert作用

????????斷言(assert):軟件調(diào)試的一種方法港华,主要是對一個boolean表達(dá)式進(jìn)行檢查,主要用來保證程序的正確性午衰。

????????斷言表達(dá)式:

????????assert? expression1

????????assert? expression1 :expression2

????????其中,expression1為boolean表達(dá)式冒萄,expression2表示基本類型或者對象

5臊岸、static關(guān)鍵的作用

????????為特定的數(shù)據(jù)類型或者對象分配單一的存儲空間;實現(xiàn)某個屬性或者方法與類在一起而不是與對象在一起

????????static主要的4中使用情況:成員變量尊流、成員方法帅戒、代碼塊、內(nèi)部類

6崖技、使用switch時需要注意什么逻住?

????????switch(expr),expr為基本類型,枚舉迎献、字符串瞎访;在case語句結(jié)尾要有break。

7吁恍、volatile作用

????????volatile是一個類型修飾符扒秸,用來修飾被不同線程訪問和修改的變量。被改關(guān)鍵修飾的變量冀瓦,當(dāng)系統(tǒng)用到改變量時直接從內(nèi)存中提取伴奥,而不是在緩存中提取變量值。使得任何線程在任何時候考到的值都是相同的翼闽。但是volatile不是原子操作拾徙,只能保證可見性。

8感局、instanceof作用

????????判斷一個對象是否是一個類(或者接口尼啡、抽象類、父類)的實例询微,返回結(jié)果是boolean.

9玄叠、strictfp作用

????????strictfp是strict float point的縮寫,指的是精確浮點數(shù)拓提,用來確保浮點數(shù)運算的精確性读恃。JVM執(zhí)行浮點數(shù)運算時,沒有指定strictfp,結(jié)算結(jié)果可能不精確。用strictfp修飾的類寺惫、接口疹吃、方法,在其聲明范圍內(nèi)計算結(jié)果是精確的西雀。

基本類型與運算

1萨驶、Java中的基本數(shù)據(jù)類型

????????8中基本數(shù)據(jù)類型:byte(1字節(jié)=8位)、short(2字節(jié))艇肴、int(4字節(jié)腔呜、默認(rèn))、long(8字節(jié))再悼、float(4字節(jié))核畴、double(8字節(jié)、默認(rèn))冲九、char(2字節(jié))谤草、boolean(1字節(jié))

????????基本數(shù)據(jù)類型被聲明之后立刻在棧上分配空間。

????????java還提供了對基本數(shù)據(jù)類型的封裝類莺奸。

????????java還提供了void基本類型丑孩,其封裝類是java.lang.void

2、不可變類

????????不可變類:指的是當(dāng)創(chuàng)建這個類的實例之后灭贷,就不允許修改它的值了温学。

????????在Java類庫中。所有的基本類型包裝類都是不可變類甚疟,String也是不可變類枫浙。

????????創(chuàng)建不可變類的

????????創(chuàng)建不可變類的5個基本原則:

????????類中所有成員變量被private修飾

????????類中沒有修改成員變量的方法,只提供構(gòu)造函數(shù)一次生成古拴,永不改變

????????確保類中的所有方法不會被子類覆蓋箩帚,用final修飾類或者修飾方法來達(dá)到目的

????????如果類成員不是不可變變量,那么在初始化或者get時獲取該成員時黄痪,需要通過clone()確保類的不可變性

????????如有必要紧帕,可以覆蓋Object類的equal和hashCode方法

3、值傳遞和引用傳遞的區(qū)別

????????Java中參數(shù)傳遞的方式:

????????值傳遞

????????????在方法的調(diào)用中桅打,實參將值傳遞給形參是嗜,形參用這個實參的值初始化一個臨時的存儲單元,對形參值的操作不影響實參的值挺尾。

????????引用傳遞

????????????在方法的調(diào)用中鹅搪,傳遞的是對象(就是對象的地址),這時形參和實參對象都指向同一塊存儲單元遭铺。

????????java中基本數(shù)據(jù)類型都是按照值傳遞丽柿;其他按照引用傳遞

4恢准、不同數(shù)據(jù)類型轉(zhuǎn)換規(guī)則

????????自動數(shù)據(jù)類型轉(zhuǎn)換:byte -> short -> char -> int -> long -> float -> double

????????注:char轉(zhuǎn)換為高級類型(int long)會轉(zhuǎn)換為其對應(yīng)的ASCII碼

????????byte? short? char 在進(jìn)行運算時會自動轉(zhuǎn)換為int,但使用“+=”運算不會自動轉(zhuǎn)換

????????基本類型與boolean不會自動轉(zhuǎn)換

????????強(qiáng)制數(shù)據(jù)類型轉(zhuǎn)換

????????強(qiáng)制轉(zhuǎn)換會損失精度

5甫题、強(qiáng)制類型轉(zhuǎn)換注意事項

對于“+=”Java語言對其進(jìn)行特殊處理馁筐,因此,short s1=1; s1+=1能編譯通過

6坠非、運算符優(yōu)先級

????運算符優(yōu)先級助記口訣:單目乘除位關(guān)系敏沉,邏輯三目后賦值。?

單目:單目運算符+ –(負(fù)數(shù)) ++ -- 等?

乘除:算數(shù)單目運算符* / % + -?

位:位移單目運算符<< >>?

關(guān)系:關(guān)系單目運算符> < >= <= == !=?

邏輯:邏輯單目運算符&& || & | ^?

三目:三目單目運算符A > B ? X : Y?

后:無意義炎码,僅僅為了湊字?jǐn)?shù)?

賦值:賦值=

7盟迟、Math類中round、ceil潦闲、floor方法的功能

round:四舍五入

ceil:向上取整

floor:向下取整

8攒菠、++i和i++區(qū)別

9、如何實現(xiàn)無符號數(shù)的右移操作

>>? :有符號右移矫钓,整數(shù)最高位補(bǔ)0,負(fù)數(shù)最高位補(bǔ)1

>>>:無符號右移舍杜,無論正負(fù)新娜,最高位補(bǔ)0

對于byte? short? char會自動轉(zhuǎn)換為int類型,然后進(jìn)行以為操作

<< :有符號左移

10既绩、char是否可以存儲一個中文漢字概龄?

可以。


字符串與數(shù)組

1饲握、字符串創(chuàng)建于存儲的機(jī)制是什么?

????????String實現(xiàn)采用了Flyweight(享元)設(shè)計模式救欧。

????????字符串聲明和初始化主要有以下兩種情況:

????????對于String s1 = new String("abc");和String s2 = new String("abc"); 存在2個內(nèi)容相同的引用對象衰粹,但是內(nèi)存地址不同

????????String s1 = "abc";和String s2 = "abc";在JVM中存在字符串常量池,當(dāng)創(chuàng)建一個字符串常量時笆怠,會先使用String類的equals(Object o)方法檢查字符串常量池是否有相同的字符串被定義铝耻。

2、“==”蹬刷、equals和hashCode()有什么區(qū)別

????????1瓢捉、==用來比較兩個變量的值是否相等(比較對應(yīng)內(nèi)存所存儲的數(shù)值是否相同)

????????????(1)、比較兩個基本類型的數(shù)值是否相等

????????????(2)办成、比較兩個引用變量是否相等泡态。即判斷兩個對象是否指向同一塊存儲空間

????????2、equals是Object類中提供的方法

????????????(1)迂卢、比較兩個基本類型的數(shù)據(jù)是否相等

????????????(2)某弦、比較兩個實例對象的內(nèi)容是否相等桐汤。(equals方法被覆蓋之后的功能,沒有覆蓋和“==”一樣)

????????????如String類中的equals方法

????????????????(1)刀崖、String類中的equals首先比較地址惊科,如果是同一個對象的引用,可知對象相等亮钦,返回true馆截。

????????????????(2)、若不是同一個對象蜂莉,equals方法挨個比較兩個字符串對象內(nèi)的字符蜡娶,只有完全相等才返回true,否則返回false映穗。

????????3窖张、hashCode

????????????(1)、判斷兩個對象是否相等蚁滋。即判斷兩個對象是否指向同一塊存儲空間

????????????(2)宿接、默認(rèn)情況下,Object類中的hashCode()方法返回對象在內(nèi)存中地址轉(zhuǎn)換成的一個int值辕录。也就是說睦霎,若對象不重寫該方法,則返回相應(yīng)對象的內(nèi)存地址走诞。

????????????(3)效五、若沒有重寫hashCode()方法虚缎,任何對象的hashCode()方法是不相等的古毛。

????4彰触、equals()方法與hashCode()方法

????????(1)、x.equals(y)為true塞绿,則這兩個對象中任一個的hashCode()方法產(chǎn)生的結(jié)果相同

????????(2)沟涨、x.equals(y)為false,則x和y的hashCode()返回值有兩種情況:相等异吻、不相等拷窜。

3、String涧黄、StringBuffer篮昧、StringBuilder和StringTokenizer區(qū)別

?是否可變類實例化的方法是否線程安全速度

String不可變類兩種:賦值、構(gòu)造函數(shù)??

StringBuffer可變類一種:構(gòu)造函數(shù)線程安全速度慢

StringBuilder可變類一種:構(gòu)造函數(shù)線程不安全速度快

1笋妥、String

(1)懊昨、String是不可變類,一旦創(chuàng)建一個對象春宣,該對象的值不能修改酵颁。

(2)嫉你、對于已經(jīng)存在的String對象的修改都是重新創(chuàng)建一個新的對象,然后把新的值保

存進(jìn)去躏惋。

(3)幽污、String是final類,即不能被繼承簿姨。

2距误、StringBuffer

(1)、是一個可變對象扁位,當(dāng)對他進(jìn)行修改的時候不會像String那樣重新建立對象准潭。只能

通過構(gòu)造函數(shù)來建立。

(2)域仇、只能通過構(gòu)造函數(shù)來建立刑然,不能通過賦值符號初始化對象

3、StringTokenizer

StringTokenizer是用來分割字符串的工具類(java.util.StringTokenizer)

4暇务、Java中的數(shù)組是不是對象泼掠?

????????是對象。

5垦细、數(shù)組的初始化方式择镇?

一維數(shù)組聲明:

type aaryName[ ]或type[ ] arrayName

一維數(shù)組創(chuàng)建:

arrayName = new type[arraySize];

二維數(shù)組:

type aaryName[ ][ ]

type[ ][ ]? aaryName;

type[ ]aaryName[ ]? ;

6、length屬性和length()方法的區(qū)別蝠检?

數(shù)組中有l(wèi)ength屬性獲取數(shù)組的長度沐鼠。

字符串是length()方法獲取字符串長度

對于集合是size()方法查看元素個數(shù)


異常處理

1挚瘟、finally塊中的代碼什么時候被執(zhí)行

finally塊的作用是保證該塊不論什么情況下都會執(zhí)行叹谁。

由于return代表當(dāng)前函數(shù)的結(jié)束,乘盖,因此任何代碼都只能在return前執(zhí)行焰檩,因此finally代碼塊也是在return前執(zhí)行。

此外订框,如果try-finally或者catch-finally中都有return析苫,那么finally中的return會覆蓋其他的return語句。

當(dāng)程序進(jìn)入try語句之前出現(xiàn)異常穿扳,或者在try塊中強(qiáng)制退出都不會執(zhí)行finally塊中的代碼衩侥。

2、異常處理的原理是矛物?

異常處理的目的是:提高程序的安全性和魯棒性(健壯性)茫死。

基類java.lang.THrowable作為所有異常的父類,異常分為Error和Exception兩大類履羞。

3峦萎、運行時異常和普通異常有什么區(qū)別屡久?

檢查異常:IO異常和SQL異常,發(fā)生在編譯階段爱榔,強(qiáng)制處理被环,放在try中或者拋出

運行時異常:編譯期不要求強(qiáng)制處理,若沒處理详幽,出現(xiàn)異常會有JVm處理筛欢。常見異常有:NullPointerException(空指針異常)、ClassCastException(類型轉(zhuǎn)換異常)妒潭、ArrayIndexOutOfBoundsException(數(shù)組越界異常)悴能、ArrayStoreException(數(shù)組存儲異常)、BufferOverflowException(緩沖區(qū)溢出異常)雳灾、ArithmeticException(算術(shù)異常)


輸入輸出流

1漠酿、Java IO流的實現(xiàn)機(jī)制

Java IO類采用了Decorator(裝飾者)設(shè)計模式

2、管理文件和目錄的類

File常用方法:

boolean canRead()??? //檢查能否讀取指定文件

boolean canWrite()??? //檢查能否寫入指定文件

boolean equals(Object obj)??? //將指定對象與調(diào)用函數(shù)的對象進(jìn)行比較

boolean exists()???? ? ? //測試文件是否存在

String getAbsolutePath()????? //返回此對象表示的文件的絕對路徑名

String getName()????? //返回此對象表示的文件的名稱

String getParent()???? //返回此File對象的路徑名的上一級谎亩,如果路徑名沒有上一級炒嘲,

? ? 則返回null

boolean isAbsolute()???? //測試此File對象表示的文件是否是絕對路徑名

boolean isDirectory()??? //測試此File對象表示的文件是否是目錄

boolean isFile()????? //測試此File對象表示的文件是否是普通文件

boolean delete()???? //刪除此對象指定的文件

boolean createNewFile()??? //創(chuàng)建空文件

boolean mkdir()?? //創(chuàng)建由該File對象表示的目錄

boolean mkdirs()??? //創(chuàng)建包括父目錄的目錄

3、Java Socket

Socket成為套接字匈庭,分為兩種類型:面向連接的Socket通信協(xié)議(TCP)夫凸、面向無連接的Socket通信(UDP)

Socket的生命周期:打開Socket、使用Socket收發(fā)數(shù)據(jù)阱持、關(guān)閉Socket

4夭拌、Java NIO

NIO就是非阻塞IO.采用了Reactor(反應(yīng)器)設(shè)計模式

NIO通過Selector、Channel衷咽、Buffer來實現(xiàn)非阻塞的IO操作鸽扁,實現(xiàn)原理如下:

5、Java 序列化

Java提供了2中對象序列化的方式:序列化镶骗、外部序列化

序列化

實現(xiàn)Serializable接口桶现,再使用輸出流(如FileOutputStream)構(gòu)造ObjectOutputStream對象,調(diào)用該對象的writeObject()將對象寫出鼎姊,恢復(fù)時使用對應(yīng)的輸入流骡和。

特點:

若一個類能被序列化,那么它的子類也能被序列化相寇。

static修飾的類成員和transient修飾的臨時數(shù)據(jù)不會被序列化慰于。

Java中實現(xiàn)序列化的接口:ObjectOutput、ObjectInput唤衫、ObjectOutputStream等婆赠。

當(dāng)需要網(wǎng)絡(luò)發(fā)送對象或者存儲到數(shù)據(jù)庫中使用序列化;序列化可以實現(xiàn)對象深復(fù)制战授,即可以復(fù)制引用的對象页藻。

外部序列化


Java平臺與內(nèi)存管理

1桨嫁、Java平臺獨立性原理

字節(jié)碼和JVM

2、JVM加載class文件的原理機(jī)制

類加載方式有:顯式加載份帐、隱式加載

隱式加載:指程序使用 new創(chuàng)建對象時璃吧,會隱式的調(diào)用類加載器把對應(yīng)的類加載到JVM中。

顯式加載:指通過class.forName()把所需要的類加載到JVM中废境。

類加載器:BootStrapLoader? ExtClassLoader(SystemClassLoader) APPClassLoader

類加載步驟:

加載:根據(jù)路徑查找對應(yīng)的class文件畜挨,然后導(dǎo)入

連接

檢查:檢查待加載的class文件的正確性

準(zhǔn)備:給類中的靜態(tài)變量分配存儲空間

解析:將符號引用轉(zhuǎn)換成直接引用

初始化:對靜態(tài)變量和靜態(tài)代碼塊執(zhí)行初始化工作。

3噩凹、what is GC

判斷對象是否有用的方法:

引用計數(shù)器法

可達(dá)性分析法

垃圾回收算法

標(biāo)記-整理算法

標(biāo)記-清除算法

復(fù)制算法

分代收集算法

4巴元、Java是否存在內(nèi)存泄漏問題

內(nèi)存泄漏:指一個不再被程序使用的對象或者變量還在內(nèi)存中占有存儲空間。

內(nèi)存泄漏主要有2種情況:(1)堆中申請的空間沒有釋放驮宴;(1)對象不再使用但在內(nèi)存中保留著逮刨。

java垃圾回收可以解決(1)。java中的內(nèi)存泄漏指第二種情況堵泽。

引起內(nèi)存泄漏的原因:靜態(tài)集合類修己、各種連接、監(jiān)聽器迎罗、變量不合理的作用域睬愤、單例模式可能造成內(nèi)存泄漏

5、Java中的隊和棧的區(qū)別


棧:基本數(shù)據(jù)類型變量纹安、引用變量

堆:對象 string


容器

1尤辱、Java Collections框架

Collection是一個集合接口,提供了對集合對象進(jìn)行基本操作(排序厢岂、查找光督、反轉(zhuǎn)、替換咪笑、復(fù)制等)的通用接口可帽,實現(xiàn)該接口的類有:List娄涩、Set窗怒、Queue、Stack蓄拣。

Collections是針對集合類的一個包裝類扬虚,提供了一系列靜態(tài)方法以實現(xiàn)對各種集合的搜索、排序球恤、線程安全化等操作辜昵,其中大多數(shù)方法都是用來處理線性表。Collections類不能實例化咽斧,服務(wù)于Collection框架堪置。

Set:元素?zé)o序躬存、不重復(fù),HashSet舀锨、TreeSet

List: 有序岭洲、可重復(fù) LinkedList、ArrayList Vector

Map:? HashMap坎匿、TreeMap盾剩、LinkedHashMap

2、迭代器

迭代器(Iterator)

使用容器的iterator()方法返回一個Iterator對象替蔬,然后通過Iterator的next()方法返回第一個元素告私;使用Iterator的hasNext判斷是否有元素;可以使用remove()刪除迭代器返回的元素

3承桥、ArrayList驻粟、Vector肖油、LinkedList

三者均為可伸縮數(shù)組叫胁,即可以動態(tài)改變長度的數(shù)組凿滤。三者都實現(xiàn)了List接口查近,主要區(qū)別在于實現(xiàn)方式的不同满着,所以對不同的操作具有不同的效率雀摘。ArrayList和Vector都是基于Object[ ] array來實現(xiàn)实愚,當(dāng)需要擴(kuò)充時Vector為原來的2倍纬傲,ArrayList為原來的1.5倍襟衰。

1贴铜、ArrayList

是一個可改變大小的數(shù)組(本質(zhì)上是一個數(shù)組),當(dāng)更多的元素加入到ArrayList中時瀑晒,其大小將會動態(tài)的增長绍坝,內(nèi)部的元素可以直接通過get與set方法進(jìn)行訪問。

2苔悦、LinkedList-非線程安全

是一個雙向鏈表轩褐,在添加、刪除時具有較好的性能玖详,但是不能進(jìn)行隨機(jī)存取把介。

3、Vector

和ArrayList類似蟋座,但是屬于線程安全的拗踢。

(1)、Vector是一個用synchronize修飾的線程安全的動態(tài)數(shù)組向臀。

(2)巢墅、擴(kuò)容方法

計算新容量的大小newsize=oldsize+(increment>0)?increment:oldsize。

若增長因子小于0,每次擴(kuò)容大小為增長前的一倍君纫;若增長因子大于0驯遇,每次擴(kuò)容大小為增長因子的大小。

4蓄髓、ArrayList和Vector

(1)妹懒、相同點

A、都是基于存儲元素的Object[] array來實現(xiàn)

B双吆、使用連續(xù)的空間存儲眨唬,支持用下標(biāo)來訪問元素

C、插入元素時好乐,需要移動容器中的元素匾竿,動態(tài)地擴(kuò)充存儲空間

(2)、區(qū)別

ArrayList數(shù)組非同步非線程安全

Vector數(shù)組同步線程安全

LinkedList雙向鏈表非同步非線程安全

4蔚万、HashMap岭妖、HashTable、TreeMap和WeakHashMap區(qū)別

1反璃、HashMap

(1)昵慌、實現(xiàn)原理

HashMap采用鏈地址法,即底層是一個數(shù)組實現(xiàn)淮蜈,數(shù)組的每一項(即一個Entry)又是一個鏈表斋攀。

(2)、HashMap的存儲機(jī)制

根據(jù)key計算出該key對應(yīng)的Entry在數(shù)組中的位置index=hashcode%length梧田;判斷該Entry是否在該位置對應(yīng)的鏈表中淳蔼,不在:插入鏈表的頭部,在:更新該鏈表中對應(yīng)Entry的value裁眯。

(3)鹉梨、HashMap的擴(kuò)容

每當(dāng)初始化一個HashMap,默認(rèn)的數(shù)組大小為16穿稳,默認(rèn)的增長因子為0.75存皂;當(dāng)元素個數(shù)超過數(shù)組大小的增長因子時,就會對數(shù)組進(jìn)行擴(kuò)容逢艘;HashMap采用的擴(kuò)容方法旦袋,每次把數(shù)組大小擴(kuò)大一倍,然后重新計算HashMap中每個元素在數(shù)組中的位置埋虹。

(4)猜憎、HashMap迭代器Iterator

Iterator迭代器采用fail-fast機(jī)制娩怎,由于HashMap不是線程安全的搔课,因此如果在使用迭代器的過程中,有其他線程修改了map,則拋出ConcurrentModificationException爬泥,這就是fail-fast策略柬讨。

(5)、實現(xiàn)HashMap的同步

Map m=Collections.synchronizedMap(new HashMap())

2袍啡、ConcurrentHashMap

ConcurrentHashMap和HashTable的主要區(qū)別就是圍繞著鎖的粒度以及如何鎖踩官。HashTable的實現(xiàn)方式-鎖整個hash表,ConcurrentHashMap的實現(xiàn)方式-鎖桶(或段)境输。ConcurrentHashMap將hash表默認(rèn)分為16個桶蔗牡,get,put,remove等常用操作只鎖當(dāng)前需要用到的桶,其他線程依然可以使用其他桶嗅剖,因此提高了并發(fā)性辩越。

3、HashTable

HashTable實現(xiàn)了Map接口,HashTable通過synchronize實現(xiàn)線程安全信粮。

(1)黔攒、實現(xiàn)原理

原理與HashMap相同,采用數(shù)組+鏈表的結(jié)構(gòu)實現(xiàn)

(2)强缘、HashTable的擴(kuò)容

HashTable的默認(rèn)大小為11督惰;數(shù)組位置的計算方法不同,index=(hashcode&MAX_VALUE)旅掂;擴(kuò)容的方法為newlength=oldlength*2+1赏胚;HashTable不允許key值為null,也不允許value為null商虐。

?線程安全性是否空值同步迭代器速度

HashMap非線程安全允許空鍵值非同步Iterator(fail-fast迭代器)快

HashTable線程安全不允許空鍵值同步Enumerator(不是fail-fast)慢


多線程

1栅哀、什么是線程?與進(jìn)程的區(qū)別称龙?為什么使用多線程留拾?

線程:指程序正在執(zhí)行過程中,能夠執(zhí)行程序代碼的一個執(zhí)行單元鲫尊。

進(jìn)程:指正在執(zhí)行的程序痴柔。

2、同步和異步的區(qū)別

1疫向、? 同步

指一個進(jìn)程在執(zhí)行某個請求的時候咳蔚,若該請求需要一段時間才能返回信息,則該進(jìn)程將會一直等待下去搔驼,直到收到返回信息才繼續(xù)執(zhí)行下去谈火。

2、? 異步

指進(jìn)程不需要一直等下去舌涨,而是繼續(xù)執(zhí)行下面的操作糯耍,不管其他進(jìn)程的狀態(tài),當(dāng)有消息返回時,系統(tǒng)會通知進(jìn)程進(jìn)行處理温技,這樣可以提高執(zhí)行的效率革为。

3、? 實現(xiàn)同步的機(jī)制

(1)舵鳞、臨界區(qū)??? 通過對多線程的串行化來訪問公共資源或一段代碼

(2)震檩、互斥???????? 只有擁有互斥對象的線程才有訪問公共資源的權(quán)限

(3)、信號量??? 允許多個線程在同一時刻訪問同一資源蜓堕,但限制最大線程數(shù)目

(4)抛虏、事件???????? 通過通知操作的方式來保持線程的同步

3、如何實現(xiàn)多線程

方法有3:

繼承Thread類套才,重寫run()方法

實現(xiàn)Runnable接口嘉蕾,并實現(xiàn)run方法

實現(xiàn)Callable接口,重寫call()方法

4霜旧、run()和start()方法的區(qū)別

start方法是線程啟動方法错忱,此時線程處于就緒狀態(tài)。run 方法是需要線程執(zhí)行任務(wù)的地方挂据,當(dāng)線程啟動后以清,JVM調(diào)用線程就會執(zhí)行run方法。直接調(diào)用run方法和執(zhí)行普通方法沒什么區(qū)別

5崎逃、多線程同步實現(xiàn)的方法

Java提供實現(xiàn)同步的3種方法:

synchronized關(guān)鍵字

wait()和notify() notifyAll()

Lock

6掷倔、sleep()方法與wait()方法

1、? 原理不同

(1)个绍、sleep()方法是Thread類的靜態(tài)方法

(2)勒葱、wait()方法是Object類的方法,用于線程間的通信

2巴柿、? 對鎖的處理機(jī)制不同

(1)凛虽、調(diào)用sleep()方法不會釋放鎖,容易導(dǎo)致死鎖問題

(2)广恢、調(diào)用wait()方法凯旋,線程會釋放其所占用的鎖,需要借助notify()方法蘇醒

3钉迷、? 使用區(qū)域不同

(1)至非、sleep()方法可以放在任何地方使用

(2)、wait()方法必須放在同步方法或同步塊中使用

4糠聪、? sleep()方法必須捕獲異常

wait()荒椭、notify()、notifyAll()不需要捕獲異常

引申:

sleep給其他線程運行機(jī)會不考慮優(yōu)先級舰蟆,而yield只會給相同或者更高優(yōu)先級的線程運行機(jī)會

sleep使得線程進(jìn)入阻塞狀態(tài)趣惠,而yield使得線程重新回到就緒狀態(tài)

sleep拋出InterruptedException狸棍,而yiel沒有

sleep比yield具有更好的可移植性

7、線程終止的方法

使用stop()方法與suspend()方法終止線程的執(zhí)行

1信卡、Thread.stop()

終止線程時隔缀,釋放已經(jīng)鎖定的所有監(jiān)視資源

2题造、suspend()

終止線程時傍菇,該方法不會釋放鎖,容易產(chǎn)生死鎖界赔。

3丢习、讓線程自行結(jié)束進(jìn)入Dead狀態(tài)(建議)

通過設(shè)置一個flag標(biāo)識來控制循環(huán)是否執(zhí)行,通過這種方法來讓線程離開run()方法淮悼,從而終止線程咐低。

8箱歧、Synchronized和lock的區(qū)別

類別SynchronizedLock

存在層次Java的關(guān)鍵字蚂斤,在JVM層面上是一個類

鎖的釋放1、? 以獲取鎖的線程執(zhí)行完同步代碼姥饰,釋放鎖羹令。

2鲤屡、? 線程執(zhí)行發(fā)生異常,JVM會讓線程釋放鎖福侈。

在finally中必須釋放鎖酒来,不然容易造成線程死鎖。

鎖的獲取若A線程獲得鎖肪凛,B線程等待堰汉;若A線程阻塞,B線程會一直等待伟墙。分情況而定翘鸭,Lock有多個獲取鎖的方式。

鎖狀態(tài)無法判斷可以判斷

鎖類型可重入鎖戳葵、不可中斷鎖矮固、非公平鎖、公平鎖可重入譬淳、可判斷档址、可公平(兩者皆可)

性能少量同步大量同步

1、synchronized關(guān)鍵字

synchronized使用Object對象本身的notify邻梆、wait守伸、notifyAll調(diào)度機(jī)制

2、Lock

提供了Lock接口以及它的一個實現(xiàn)類ReentrantLock(重入鎖)浦妄,Lock使用Condition進(jìn)行線程之間的調(diào)度尼摹。

(1)见芹、lock()??????? 以阻塞的方式獲取鎖

(2)、tryLock()? 以非阻塞的方式獲取鎖

(3)蠢涝、tryLock(long timeout,TimeUnit unit)

(4)玄呛、lockInterruptibly()??

3、兩者的主要區(qū)別

(1)和二、用法不一樣

Synchronized用于同步方法徘铝、同步代碼塊中,托管給JVM執(zhí)行惯吕。

Lock顯示地指定起始位置和終止位置惕它,通過代碼實現(xiàn)。

(2)废登、性能不一樣

資源競爭不激烈的情況下淹魄,synchronized的性能好。

資源競爭激烈的情況下堡距,ReetrantLock的性能好(Lock接口的實現(xiàn)類)

(3)甲锡、鎖機(jī)制不一樣

Synchronized在塊結(jié)構(gòu)中獲得鎖和釋放鎖,自動解鎖羽戒。

Lock在finnally塊中釋放缤沦,由開發(fā)人員手動去釋放。

9半醉、守護(hù)線程

10疚俱、join()方法作用

join()方法是讓調(diào)用該方法的線程在執(zhí)行完run()方法之后,再執(zhí)行join方法后面的代碼缩多。


Java數(shù)據(jù)庫操作

1呆奕、如何通過JDBC訪問數(shù)據(jù)庫

2、JDBC處理事務(wù)采用什么方法

commit()衬吆、rollback()

JDBC事務(wù)隔離級別:

不支持事務(wù)

讀未提交

讀已提交

可重復(fù)讀

可序列化

3梁钾、Class.forName()的作用

將類加載到JVM中。

4逊抡、getString()與getObject()之間的區(qū)別


二姆泻、JavaWeb

Servlet與JSP

1、頁面請求的工作流程

2冒嫡、HTTP中g(shù)et和post方法有什么區(qū)別

HTTP請求的方法:get拇勃、post、head孝凌、trace方咆、option等

get上傳數(shù)據(jù)是在URL后面加上?然后是 屬性名=屬性值&屬性名=屬性值……上傳的數(shù)據(jù)量小蟀架,1024字節(jié)左右瓣赂;而post傳遞數(shù)據(jù)通過HTTP請求的附件進(jìn)行的榆骚,上傳的數(shù)據(jù)量更大,一般不受限制

get方式上傳數(shù)據(jù)不安全煌集;而post方法向服務(wù)器提交的內(nèi)容不會在URL中明文顯示妓肢,更加安全

3、什么是Servlet

動態(tài)頁面生成技術(shù):公共網(wǎng)關(guān)接口(CGI,Common Gateway Interface)和Servlet

Servlet是java語言編寫的服務(wù)器端程序苫纤,運行在Web容器中的Servlet容器中碉钠,主要的功能是提供請求/響應(yīng)的web服務(wù)模式,可以動態(tài)生成web內(nèi)容方面。

優(yōu)點:較好的移植性放钦,執(zhí)行效率高色徘,功能強(qiáng)大恭金,使用方便,擴(kuò)展性強(qiáng)

Servlet處理客戶端請求的流程:

1褂策、? 用戶通過單擊一個鏈接來向Servlet發(fā)起請求横腿。

2、?Web服務(wù)器接收到該請求后斤寂,把該請求交給相應(yīng)的容器處理耿焊。當(dāng)容器發(fā)現(xiàn)這是對Servlet發(fā)起的請求后,容器此時會創(chuàng)建兩個對象:HttpServletResponse遍搞、HttpServletRequest罗侯。

3、? 容器根據(jù)請求消息中的URL消息找到對應(yīng)的Servlet溪猿,針對該請求創(chuàng)建一個單獨的線程钩杰,同時把HttpServletResponse和HttpServletRequest兩個對象以參數(shù)的形式傳遞到新創(chuàng)建的線程中。

4诊县、? 容器調(diào)用Servlet的service()方法來完成對用戶的請求響應(yīng)讲弄,service()方法會調(diào)用doPost()或者doGet()方法來完成具體的響應(yīng)任務(wù),同時把生成的動態(tài)內(nèi)容返回給容器依痊。

5避除、?容器把響應(yīng)消息組裝成HTTP格式返回給客戶端。并刪除HttpServletResponse胸嘁、HttpServletRequest瓶摆。

4、Servlet生命周期

Servlet生命周期只有兩種狀態(tài):未創(chuàng)建狀態(tài)和初始化狀態(tài)性宏。這兩種狀態(tài)轉(zhuǎn)換由init()群井、service()、destroy()來控制衔沼。

Servlet的生命周期:加載蝌借、創(chuàng)建昔瞧、初始化、處理客戶請求菩佑、卸載自晰。

5、JSP

JSP(Java Server Pages) = Java代碼片段+HTML

讓Servlet負(fù)責(zé)業(yè)務(wù)邏輯處理稍坯,JSP負(fù)責(zé)頁面展示

6酬荞、JSP與Servlet的異同

同:JSP是一種特殊的Servlet,jsp最終裝換為Servlet來運行瞧哟,都是Servlet混巧。

異:

Servlet是在Java中嵌入HTMl代碼,JSP是在HTML嵌入java代碼

Servlet沒有內(nèi)置對象勤揩,JSP中的內(nèi)置對象必須通過HttpServletRequest對象咧党、HttpServletResponse對象、HttpServlet對象得到

7陨亡、如何使用JSP和Servlet實現(xiàn)MVC模型

Model: JavaBean

View:JSP

Controller:Servlet

8傍衡、Servlet中forward和redirect之間的區(qū)別

Servlet之間跳轉(zhuǎn)的方式

forward:服務(wù)器內(nèi)部的重定向,客戶端不知道负蠕,客戶端瀏覽器的地址不會變化蛙埂。

redirect:客戶端的重定向,完全跳轉(zhuǎn)遮糖,瀏覽器地址欄發(fā)生變化绣的,比forward多了一次網(wǎng)絡(luò)請求,效率相對較低欲账。

9屡江、JSP內(nèi)置對象

9個內(nèi)置對象:request、response敬惦、pageContext盼理、session、application俄删、out宏怔、config、page畴椰、exception

10臊诊、request對象主要方法

setAttribute(String name,Object):設(shè)置名字為name的request 的參數(shù)值?

getAttribute(String name):返回由name指定的屬性值?

getAttributeNames():返回request 對象所有屬性名字集合,結(jié)果是一個枚舉的實例?

getCookies():返回客戶端的所有 Cookie 對象斜脂,結(jié)果是一個Cookie 數(shù)組?

getCharacterEncoding() :返回請求中的字符編碼方式?

getContentLength() :返回請求的 Body的長度?

getHeader(String name) :獲得HTTP協(xié)議定義的文件頭信息?

getHeaders(String name) :返回指定名字的request Header 的所有值抓艳,結(jié)果是一個枚舉的實例?

getHeaderNames() :返回所以request Header 的名字,結(jié)果是一個枚舉的實例?

getInputStream() :返回請求的輸入流帚戳,用于獲得請求中的數(shù)據(jù)?

getMethod() :獲得客戶端向服務(wù)器端傳送數(shù)據(jù)的方法?

getParameter(String name) :獲得客戶端傳送給服務(wù)器端的有 name指定的參數(shù)值?

getParameterNames() :獲得客戶端傳送給服務(wù)器端的所有參數(shù)的名字玷或,結(jié)果是一個枚舉的實例?

getParameterValues(String name):獲得有name指定的參數(shù)的所有值?

getProtocol():獲取客戶端向服務(wù)器端傳送數(shù)據(jù)所依據(jù)的協(xié)議名稱?

getQueryString() :獲得查詢字符串?

getRequestURI() :獲取發(fā)出請求字符串的客戶端地址?

getRemoteAddr():獲取客戶端的 IP 地址?

getRemoteHost() :獲取客戶端的名字?

getSession([Boolean create]) :返回和請求相關(guān) Session?

getServerName() :獲取服務(wù)器的名字?

getServletPath():獲取客戶端所請求的腳本文件的路徑?

getServerPort():獲取服務(wù)器的端口號?

removeAttribute(String name):刪除請求中的一個屬性

11儡首、JSP的動作

6個基本動作:

jsp:include、jsp:useBean偏友、jsp:setProperty蔬胯、jsp:getProperty、jsp:forward位他、jsp:plugin

12氛濒、JSP中include指令和include動作之間的區(qū)別

include指令是編譯階段指令。

13鹅髓、會話跟蹤技術(shù)

page舞竿、request、session窿冯、application

14骗奖、cookie和session的區(qū)別

cookie是在客戶端瀏覽器中保存數(shù)據(jù),session是在服務(wù)器端保存數(shù)據(jù)

cookie安全性不如session好

cookie性能更好些

單個cookie保存數(shù)據(jù)不能超過4KB靡菇,每個瀏覽器最多保存20個cookie异剥。session不存在此問題

框架

1妈橄、HTTP請求方法

????????1、? GET??????????? 通過請求URI得到資源

????????2车吹、? POST????????? 添加新的內(nèi)容

????????3育苟、? PUT??????????? 修改某個內(nèi)容

????????4较鼓、? DELETE????? 刪除某個內(nèi)容

2、HTTP請求報文

HTTP請求報文由請求行(request line)违柏、請求頭部(header)博烂、空行和請求數(shù)據(jù)4個部分組成。

(1)漱竖、請求行

請求行由請求方法字段禽篱、URL字段和HTTP協(xié)議版本字段3個字段組成,他們用空格分隔馍惹。如:GET /index.html HTTP/1.1

請求方法有:GET(通過請求URI得到資源)躺率、POST(用于添加新的內(nèi)容)、PUT(用于修改某個內(nèi)容)万矾、DELETE(刪除某個內(nèi)容)

(2)請求頭部

請求頭部由關(guān)鍵字/值對組成悼吱,每行一對,關(guān)鍵字和值用英文冒號”:”分隔良狈。請求頭部通知服務(wù)器有關(guān)于客戶端請求的信息后添。

(3)空行

最后一個請求頭之后是一個空行,發(fā)送回車符和換行符薪丁,通知服務(wù)器以下不再有請求頭遇西。

(4)請求數(shù)據(jù)

請求數(shù)據(jù)不在GET方法中使用馅精,而是在POST方法中使用。POST方法適用于需要客戶填寫表單的場合粱檀。與請求數(shù)據(jù)相關(guān)的最長使用的請求頭是Content-Type和Content-Length硫嘶。

3、Http和Https

????????1梧税、? Http? 超文本傳輸協(xié)議沦疾,傳輸?shù)臄?shù)據(jù)是未加密的,不安全

????????是一個客戶端和服務(wù)器端請求和應(yīng)答的標(biāo)準(zhǔn)TCP第队,用于從WWW服務(wù)器傳輸超文本到本地瀏覽器的傳輸協(xié)議哮塞,可以使瀏覽器更加高效,使網(wǎng)絡(luò)傳輸減少凳谦。

????????2忆畅、? Https

????????由SSL+Http協(xié)議構(gòu)建的可進(jìn)行加密傳輸,身份認(rèn)證的網(wǎng)絡(luò)協(xié)議尸执。是以安全為目標(biāo)的Http通道家凯,是Http的安全版。即Http下加入SSl層如失。

????????3绊诲、SSL????? Secure Sockets Layer協(xié)議

????????用于對HTTP協(xié)議傳輸?shù)臄?shù)據(jù)進(jìn)行加密,從而誕生了Https

????????4褪贵、Http和Https的區(qū)別

????????????(1)掂之、Https協(xié)議需要到CA申請證書,一般免費證書較少脆丁,因而需要一定費用世舰。

????????????(2)、Http是超文本傳輸協(xié)議槽卫,信息是明文傳輸跟压, Https是具有安全性的SSL加密傳輸協(xié)議

????????????(3)、Http和Https使用的是完全不同的連接方式歼培,使用的端口也不同 Http(80端口)震蒋、Https(443端口)

????????????(4)、Http的連接很簡單丐怯,是無狀態(tài)的

???????? ????Https協(xié)議是由SSL+Http協(xié)議構(gòu)建的可進(jìn)行加密傳輸喷好、身份認(rèn)證的網(wǎng)絡(luò)協(xié)議,比Http安全读跷。

4梗搅、HTTP狀態(tài)碼

常見的狀態(tài)碼:

HTTP:Status 200????? 服務(wù)器成功返回網(wǎng)頁

HTTP:Status 404????? 請求的網(wǎng)頁不存在

HTTP:Status 503????? 服務(wù)不可用

HTTP:Status 1xx臨時響應(yīng)表示臨時響應(yīng)并需要請求者繼續(xù)執(zhí)行操作的狀態(tài)代碼。

?100繼續(xù)請求者應(yīng)當(dāng)繼續(xù)提出請求。

服務(wù)器返回此代碼表示已收到請求的第一部分无切,正在等待其余部分荡短。

101切換協(xié)議請求者已要求服務(wù)器切換協(xié)議,服務(wù)器已確認(rèn)并準(zhǔn)備切換哆键。

HTTP:Status 2xx成功表示成功處理了請求的狀態(tài)代碼

?200成功服務(wù)器成功返回網(wǎng)頁掘托,服務(wù)器已成功處理了請求。

201已創(chuàng)建請求成功并且服務(wù)器創(chuàng)建了新的資源籍嘹。

202已接受服務(wù)器已接受請求闪盔,但尚未處理。

203非授權(quán)信息服務(wù)器已成功處理了請求辱士,但返回的信息可能來自另一來源泪掀。

204無內(nèi)容服務(wù)器成功處理了請求,但沒有返回任何內(nèi)容颂碘。

205重置內(nèi)容服務(wù)器成功處理了請求异赫,但沒有返回任何內(nèi)容。

206部分內(nèi)容服務(wù)器成功處理了部分GET請求头岔。

HTTP:Status 4xx請求錯誤表示請求可能出錯塔拳,妨礙了服務(wù)器的處理

?400錯誤請求?

401未授權(quán)?

403禁止?

404未找到請求的網(wǎng)頁不存在,服務(wù)器找不到請求的網(wǎng)頁峡竣。

405方法禁用?

406不接受?

407需要代理授權(quán)?

408請求超時?

409沖突?

410已刪除?

411需要有效長度?

412為滿足前提條件?

413請求實體過大?

414請求的URI過長?

415不支持的媒體類型?

416請求范圍不符合要求?

417為滿足期望值?

HTTP:Status 5xx服務(wù)器錯誤表示服務(wù)器在嘗試處理請求時發(fā)生內(nèi)部錯誤靠抑,這些錯誤可能是服務(wù)器本身的錯誤,而不是請求出錯澎胡。

?500服務(wù)器內(nèi)部錯誤?

?501尚未實施?

?502錯誤網(wǎng)關(guān)?

?503服務(wù)不可用?

?504網(wǎng)關(guān)超時?

?505HTTP版本不受支持?

5孕荠、連接和長連接

1、? 短連接 ??? 連接->傳輸數(shù)據(jù)->關(guān)閉連接

(1)攻谁、HTTP是無狀態(tài)的,瀏覽器和服務(wù)器每進(jìn)行一次HTTP操作弯予,就建立一次連接戚宦,但任務(wù)結(jié)束就中斷連接。

(2)锈嫩、短連接是指Socket連接后受楼,發(fā)送,接收完數(shù)據(jù)后馬上斷開連接呼寸。

2艳汽、? 長連接????? 連接->傳輸數(shù)據(jù)->保持連接->傳輸數(shù)據(jù)->…->關(guān)閉連接

(1)、長連接是指Socket連接后对雪,不管是否使用都保持連接河狐,但安全性較差。

3、HTTP協(xié)議的長連接和短連接馋艺,實際上是TCP協(xié)議的長連接和短連接栅干。

4、TCP短連接

(1)捐祠、TCP短連接的情況

A碱鳞、Client向Server發(fā)起連接請求,Server接到連接請求踱蛀,雙方建立連接

B窿给、Client向Server發(fā)送消息,Server回應(yīng)Client率拒,一次讀寫完成

C填大、Client發(fā)起Close操作。

(2)俏橘、短連接的優(yōu)點

管理簡單允华、存在的連接都是有用的連接、不需要額外的控制手段

(3)寥掐、短連接的缺點

若客戶請求頻繁靴寂,將在TCP的建立和關(guān)閉操作上浪費時間和帶寬。

5召耘、TCP長連接

(1)百炬、長連接的情況

A、Client向Server發(fā)起連接污它,Server接受Client連接剖踊,雙方建立連接。

B衫贬、Client與Server完成一次讀寫操作后德澈,它們之間的連接不會主動關(guān)閉,后續(xù)的讀寫操作會繼續(xù)使用這個連接固惯。

(2)梆造、若一個給定的連接在2小時內(nèi)沒有任何動作,則服務(wù)器就會向客戶端發(fā)送一個探測報文段葬毫,客戶主機(jī)必須處于一下4個狀態(tài)之一:

A镇辉、客戶主機(jī)依然正常運行,并從服務(wù)器可達(dá)贴捡。

B忽肛、客戶主機(jī)已經(jīng)崩潰,并且關(guān)閉或者正在重新啟動烂斋。

C屹逛、客戶主機(jī)奔潰并已經(jīng)重新啟動

D础废、客戶主機(jī)正常,但是服務(wù)器不可達(dá)煎源。

(3)色迂、長連接的優(yōu)點

省去較多的TCP建立和關(guān)閉的操作、減少浪費手销、節(jié)約時間歇僧。

(4)、長連接的缺點

存活功能的探測周期太長锋拖、在長連接時诈悍,Client端一般不會主動關(guān)閉連接,若Client與Server之間的連接一直不關(guān)閉兽埃,當(dāng)客戶端越老越多時侥钳,消耗Server的資源。

6柄错、Spring框架

Spring是一個J2EE的框架舷夺,這個框架提供了對輕量級IoC的良好支持,同時也提供了對AOP技術(shù)非常好的封裝售貌。Spring框架的設(shè)計更加模塊化给猾,框架內(nèi)的每個模塊都能完成特定的工作,而且各個模塊可以獨立地運行颂跨,不會相互牽制敢伸。

Spring框架的好處:

1、Spring有效地管理了中間層的代碼恒削,采用了IoC控制反轉(zhuǎn)和AOP面向切面編程的思想池颈,易進(jìn)行單獨測試。

2钓丰、使用面向接口編程而不是面向類編程躯砰,有更好的可擴(kuò)展性。

3斑粱、Spring對數(shù)據(jù)的存取提供了一個一致的框架弃揽。

Spring框架主要由7個模塊組成:

Spring AOPSpring ORMSpring WebSpring Web MVC

Spring DAOSpring Context

Spring Core

1痕慢、Spring AOP???????? 面向切面

采用了面向切面編程的思想快骗,使Spring框架管理的對象支持AOP方篮,同時這個模塊也提供了事物管理,可以不依賴具體的EJB組件匕得,就可以將事物管理集成到應(yīng)用程序中汁掠。

2、Spring ORM??????? 對象關(guān)系映射???????? (對象關(guān)系映射集币,對象模型->關(guān)系模型)

提供了對現(xiàn)有ORM框架的支持资铡,例如Hibernate启搂、JDO等。

3、Spring DAO???????? 數(shù)據(jù)訪問對象

(1)沮明、提供了對數(shù)據(jù)訪問對象(Data Access Object,DAO)模式和JDBC的支持卖局。

(2)纯陨、DAO可以實現(xiàn)把業(yè)務(wù)邏輯與數(shù)據(jù)庫訪問的代碼實現(xiàn)分離,從而降低代碼的耦合度趾访。

(3)态秧、通過對JDBC的抽象,簡化了開發(fā)工作扼鞋,同時簡化了對異常的處理申鱼。

4、Spring Web

提供了Servlet監(jiān)聽器的Context和Web應(yīng)用的上下文云头。

5捐友、Spring Context

擴(kuò)展核心容器,提供了Spring上下文環(huán)境溃槐。

6匣砖、Spring Web MVC

提供了一個構(gòu)建Web應(yīng)用程序的MVC的實現(xiàn)。

7昏滴、Spring Core

(1)猴鲫、Spring框架的核心容器,提供了Spring框架的基本功能谣殊。

(2)拂共、該模塊中最主要的一個組件為:BeanFactory

7、Spring的IoC

?1姻几、IoC控制反轉(zhuǎn)

是一種降低對象之間耦合關(guān)系的設(shè)計思想宜狐。通過讀取XML文件的方式來實例化對象势告。

2、分層體系結(jié)構(gòu)與IoC方式的區(qū)別

(1)抚恒、分層體系結(jié)構(gòu)

上層調(diào)用下層的接口咱台,上層依賴于下層的執(zhí)行,即調(diào)用者依賴于被調(diào)用者俭驮。

(2)回溺、IoC方式

上層不再依賴下層的接口。即通過采用一定的機(jī)制選擇不同的下層實現(xiàn)表鳍,完成控制反轉(zhuǎn)馅而,使得由調(diào)用者來決定被調(diào)用者。

3譬圣、IoC的優(yōu)點

(1)瓮恭、采用Ioc機(jī)制能夠提高系統(tǒng)的可擴(kuò)展性

(2)、通過IoC容器(如Spring)厘熟,開發(fā)人員不需要關(guān)注對象如何被創(chuàng)建

方便增加新類屯蹦、只需修改配置文件即可實現(xiàn)對象的“熱插拔”。

(3)绳姨、IoC容器可通過配置文件來確定需要注入的實例化對象登澜,便于單元測試。

4飘庄、IoC的缺點

(1)脑蠕、對象是通過反射機(jī)制實例化出來的,對系統(tǒng)有一定的影響跪削。

(2)谴仙、創(chuàng)建對象的流程變得比較復(fù)雜。

5碾盐、IoC的應(yīng)用

抽象工廠模式

8晃跺、Spring動態(tài)代理

AOP面向切面編程

面向?qū)ο蟮奶攸c是繼承、多態(tài)和封裝毫玖。而封裝就要求將功能分散到不同的對象中去(職責(zé)分配)掀虎,即讓不同的類設(shè)計不同的方法。好處是:降低了代碼的重復(fù)程度付枫,使類可重用烹玉。缺點:在分散代碼的同時,增加了代碼的重復(fù)性阐滩。如:在兩個類中春霍,可能都需要在每個方法中做日志,根據(jù)面向?qū)ο蟮姆椒ㄒ睹迹仨氃趦蓚€類的方法中都加入日志的內(nèi)容址儒。雖然內(nèi)容相同,但是因為面向?qū)ο蟮脑O(shè)計讓類與類之間無法聯(lián)系衅疙,導(dǎo)致不能將這些重復(fù)的代碼統(tǒng)一起來莲趣。

可以在運行時,動態(tài)地將代碼切入到類的指定方法饱溢、指定位置上的編程思想就是面向切面的編程喧伞。

1、AOP面向切面編程:Aspect-Oriented Programming

允許開發(fā)人員在不改變原來模型的基礎(chǔ)上動態(tài)的修改模型以滿足新的要求绩郎。如:在不改變原來業(yè)務(wù)邏輯模型的基礎(chǔ)上潘鲫,可動態(tài)地增加日志,安全或異常處理的功能肋杖。

1溉仑、過濾器

Filter使用戶可以改變一個request并且修改一個response。Filter不是一個Servlet状植,不能產(chǎn)生一個response浊竟,但它能夠在一個request到達(dá)Servlet之前預(yù)處理request,也可以在離開Servlet時處理response津畸。Filter其實是一個”Servlet Chainning”(Servlet鏈)

一個filter的作用包括以下幾個方面:

(1)振定、在Servlet被調(diào)用之前截獲

(2)、在Servlet被調(diào)用之前檢查Servlet Request肉拓。

(3)后频、根據(jù)需要修改Request頭和Request數(shù)據(jù)。

(4)暖途、根據(jù)需要修改Response頭和Response數(shù)據(jù)卑惜。

(5)、在Servlet被調(diào)用之后截獲丧肴。

2残揉、優(yōu)點和缺點:

過濾器可以對幾乎所有請求進(jìn)行過濾,缺點是一個過濾器實例只能在容器初始化時調(diào)用一次芋浮。

3抱环、使用過濾器的目的

用來做一些過濾操作,獲取我們想要獲取的數(shù)據(jù)纸巷。如:在過濾器中修改字符編碼镇草;在過濾器中修改HttpServletRequest的一些參數(shù),包括:過濾低俗文字瘤旨、危險字符等梯啤。

10、攔截器Interceptor

攔截器不依賴于Servlet容器存哲,依賴于Web框架因宇,在SpringMVC中就是依賴于SpringMVC框架七婴。在實現(xiàn)上基于Java的反射機(jī)制,屬于面向切面編程(AOP)的一種應(yīng)用察滑。

由于攔截器是基于web框架的調(diào)用打厘,因此可以使用Spring的控制反轉(zhuǎn)獲取容器中的各個bean,進(jìn)行一些業(yè)務(wù)操作贺辰,同時一個攔截器實例在一個controller生命周期之內(nèi)可以多次調(diào)用户盯。缺點:只能對controller請求進(jìn)行攔截,對其他的一些(如直接訪問靜態(tài)資源的請求)則沒辦法攔截處理饲化,攔截器在堆請求權(quán)限鑒定方面有很大用處莽鸭。

Spring過濾器和攔截器的區(qū)別

1、聯(lián)系

(1)吃靠、Spring中攔截器與Servlet的過濾器硫眨,二者都是AOP編程思想的體現(xiàn)。

(2)撩笆、都能實現(xiàn)權(quán)限檢查捺球、日志記錄等。

2夕冲、區(qū)別

(1)氮兵、使用范圍不同

Filter過濾器是Servlet規(guī)定的,只能用于web程序歹鱼;

Interceptor攔截器既可以用于Web程序泣栈,也可用于Apllication,Swing程序中弥姻。

(2)南片、規(guī)范不同

Filter過濾器是Servlet規(guī)范定義的,是Servlet容器支持的庭敦;

Interceptor攔截器是在Spring容器內(nèi)的疼进,Spring框架所支持的。

(3)秧廉、使用資源不同

同其他代碼塊一樣伞广,攔截器是一個Spring的組件,由Spring管理疼电。配置在Spring中嚼锄,因此能使用Spring中的任何資源、對象蔽豺,例如Service對象区丑、數(shù)據(jù)源、事務(wù)管理等。該實現(xiàn)可以通過IoC(控制反轉(zhuǎn))注入到攔截器即可沧侥,而filter過濾器則不能可霎。

(4)、深度不同

Filter只在Servlet前后起作用正什,而攔截器能深入到方法前后啥纸,異常拋出前后因為攔截器的使用具有更大的彈性,所以在spring中優(yōu)先使用攔截器婴氮。


數(shù)據(jù)庫原理

1、SQL語言的功能

SQL結(jié)構(gòu)化查詢語言盾致,其功能有:數(shù)據(jù)查詢主经、數(shù)據(jù)操縱、數(shù)據(jù)定義庭惜、數(shù)據(jù)控制

delete和truncate命令的區(qū)別

同:都可以用來刪除表中的數(shù)據(jù)

不同:

truncate是數(shù)據(jù)定義語言罩驻,會被隱式的提交,一旦執(zhí)行不可回滾护赊;delete是一次刪除一行數(shù)據(jù)惠遏,刪除操作保存在日志中,可以回滾

delete后骏啰,被刪除的數(shù)據(jù)存儲空間還在节吮,可以恢復(fù);truncate刪除后空間釋放判耕,數(shù)據(jù)不可恢復(fù)

truncate執(zhí)行速度比delete快

2透绩、內(nèi)連接與外連接

1、? 內(nèi)連接(自然連接)

只有兩個表相匹配的行才能在結(jié)果集中出現(xiàn)壁熄,返回的結(jié)果集選取了兩個表中所有相匹配的數(shù)據(jù)帚豪,舍棄了不匹配的數(shù)據(jù)。

select fieldlist from table1 [inner] join table2 on table1.column=table2.column

2草丧、? 外連接

外連接不僅包含符合連接條件的行狸臣,而且還包括左表(左外連接)、右表(右外連接)昌执、兩個邊接表(全外連接)的所有數(shù)據(jù)行烛亦。

SQL的外連接共有3種類型:

(1)、左外連接???????? left outer join

select * from A? left outer join B on A.column=B.column

(2)仙蚜、右外連接???????? right outer join

select * from B right outer join B on A.column=B.column

(3)此洲、全外連接???????? full outer join

select * from A full outer join B on A.column=B.column

3、事務(wù)

事務(wù):是由一條或多條對數(shù)據(jù)庫操作的SQL語句所組成的一個不可分割的工作單元委粉。

結(jié)束事務(wù)的方法:

(1)呜师、commit()方法:完成對事務(wù)的提交

(2)、rollback()方法:完成事務(wù)回滾贾节,用于在處理事務(wù)的過程中出現(xiàn)了異常的情況

3.設(shè)置禁止自動提交

setAutoCommit(false)

4汁汗、事務(wù)的4個屬性(ACID)

(1)锐涯、原子性 Atomicity

事務(wù)是一個不可分割的整體,為了保證事務(wù)的總體目標(biāo)苇侵,事務(wù)必須具有原子性站超,即當(dāng)數(shù)據(jù)修改時,要么全執(zhí)行角寸,要么全不執(zhí)行菩混,不允許事務(wù)部分地完成。

(2)扁藕、一致性 Consistency

一個事務(wù)執(zhí)行之前和執(zhí)行之后沮峡,數(shù)據(jù)庫數(shù)據(jù)必須保持一致性狀態(tài)。

由于并發(fā)操作帶來的數(shù)據(jù)不一致性包括:讀臟數(shù)據(jù)亿柑、不可重復(fù)讀邢疙、虛讀

(3)、隔離性 Isolation

當(dāng)兩個或多個事務(wù)并發(fā)執(zhí)行時望薄,為了保證數(shù)據(jù)的安全性疟游,將一個事務(wù)內(nèi)部的操作與事務(wù)的操作隔離起來,不被其他正在進(jìn)行的事務(wù)看到痕支,即一個事務(wù)的執(zhí)行不能被其他事務(wù)干擾颁虐。對任何一對事務(wù)T1和T2,對T1而言采转,T2要么在T1開始之前已經(jīng)結(jié)束聪廉,要么在T1完成之后再開始執(zhí)行。

4種類型的事務(wù)隔離級別:不提交讀故慈、提交讀板熊、可重復(fù)讀、可序列化察绷。

因為隔離性使得每個事務(wù)的更新在它被提交之前干签,對其他事務(wù)都是不可見的,所以拆撼,實現(xiàn)隔離性是解決臨時更新與消除級聯(lián)回滾的一種方式容劳。

(4)、持久性 Durability

事務(wù)完成以后闸度,DBMS保證它對數(shù)據(jù)庫中的數(shù)據(jù)的修改是永久性的竭贩,當(dāng)系統(tǒng)或介質(zhì)發(fā)生故障時,該修改也永久保持莺禁。

持久性一般通過數(shù)據(jù)庫備份與恢復(fù)來保證留量。

4、五種事務(wù)隔離級別

(1)、transaction_none jdb????? ??????????????????????????? 不支持事務(wù)

(2)楼熄、transaction_read_uncommitted???? ???????? 未提交讀

在提交前忆绰,一個事務(wù)可以看到另一個事務(wù)的變化。

允許讀臟數(shù)據(jù)可岂、不可重復(fù)讀错敢、虛讀

(3)、transaction_read_committed?????????????????? 已提交讀

不允許讀取未提交的數(shù)據(jù)

允許不可重復(fù)讀缕粹、虛讀

(4)稚茅、transaction_repeatable_read?????????????????? 可重復(fù)讀

事務(wù)能夠保證再次讀取相同的數(shù)據(jù)而不會失敗

允許虛讀

(5)、transaction_seriabizable???????????????????????????? 可序列化(串行化)

事務(wù)的最高級別

防止讀臟數(shù)據(jù)致开、不可重復(fù)讀峰锁、虛讀

5、設(shè)置事務(wù)的隔離級別

通過Connection對象的conn.setTransactionLevel()方法

6双戳、確定當(dāng)前事務(wù)的隔離級別

通過Connextion對象的conn.getTransactionIsolation()方法

4、數(shù)據(jù)庫范式

按照“數(shù)據(jù)庫規(guī)范化”對表進(jìn)行設(shè)計糜芳,其目的是減少數(shù)據(jù)庫中的數(shù)據(jù)冗余飒货,以增加數(shù)據(jù)的一致性

1、? 第一范式1NF

強(qiáng)調(diào)列的原子性峭竣,即列不能再分成其他幾列塘辅。

2、? 第二范式2NF

首先是1NF皆撩,另外包含兩部分內(nèi)容:

(1)扣墩、表必須有一個主鍵

(2)、沒有包含在主鍵中的列必須完全依賴于主鍵扛吞,而不能只依賴主鍵的一部分呻惕。

3、? 第三范式3NF

首先是2NF滥比,且非主鍵列必須直接依賴于主鍵亚脆,不能存在傳遞依賴。

即盲泛,不能存在非主鍵列A依賴于非主鍵列B濒持,非主鍵列B依賴于主鍵的情況。

4寺滚、2NF和3NF的區(qū)分

(1)柑营、2NF,非主鍵列是否完全依賴于主鍵村视,不能依賴于主鍵的一部分官套。

(2)、3NF,非主鍵列直接依賴于主鍵虏杰,不能直接依賴于非主鍵列讥蟆。

5、BCNF

首先是3NF纺阔,每個屬性都不傳遞依賴于主鍵

5瘸彤、視圖

1、? 視圖是由數(shù)據(jù)庫的基本表中選取出來的數(shù)據(jù)組成的邏輯窗口笛钝,是一個虛表质况。

2、? 在數(shù)據(jù)庫中玻靡,存放的只是視圖的定義结榄,視圖包含的數(shù)據(jù)項仍然存放在原來的基本表結(jié)構(gòu)中。

3囤捻、? 視圖的作用

(1)臼朗、可以簡化數(shù)據(jù)查詢語句

(2)、使用戶能從多角度看待同一數(shù)據(jù)

(3)蝎土、通過引入視圖视哑,可以提高數(shù)據(jù)的安全性

(4)、視圖提供了一定程度的邏輯獨立性誊涯。

6挡毅、樂觀鎖、悲觀鎖暴构,介紹樂觀鎖在項目中怎么使用的

1跪呈、? 悲觀鎖(悲觀并發(fā)控制)

(1)、假定其他用戶企圖訪問或者修改你正在訪問取逾,更改的對象概率極高耗绿。若一個事務(wù)執(zhí)行的操作讀某行數(shù)據(jù)應(yīng)用了鎖,只有當(dāng)該事務(wù)把鎖釋放菌赖,其他事務(wù)才能夠執(zhí)行與該鎖沖突的操作缭乘。

(2)、悲觀鎖的缺陷

加鎖的時間較長琉用,長時間的限制其他用戶的訪問堕绩;悲觀鎖的并發(fā)性不好。

(3)邑时、悲觀鎖的使用

select * from A where name=’李四’ for update

2奴紧、? 樂觀鎖(樂觀并發(fā)控制)

(1)、假設(shè)多用戶并發(fā)的事務(wù)在處理時不會互相影響晶丘,各事務(wù)能在不產(chǎn)生鎖的情況下處理各自影響的那部分?jǐn)?shù)據(jù)黍氮。在提交數(shù)據(jù)更新之前唐含,每個事務(wù)會先檢查在該事務(wù)讀取數(shù)據(jù)后,有沒有其他事務(wù)修改了該數(shù)據(jù)沫浆。若其他事務(wù)有更新的話捷枯,正在提交的事務(wù)會進(jìn)行回滾。

(2)专执、樂觀鎖的使用

start transaction

select * from A where name=’李四’

update A set sex=’男’ where name=’李四’ and updatetime=上面查出值

commit id,name,sex updatename

7淮捆、并發(fā)控制的主要技術(shù)

1、? 封鎖Locking

在事務(wù)T對某個數(shù)據(jù)對象(表本股、記錄)等操作之前攀痊,先向系統(tǒng)發(fā)出請求,對其加鎖拄显,在事務(wù)T釋放它的鎖之前苟径,其他事務(wù)不能更新此數(shù)據(jù)對象。

基本的鎖有兩種:排它鎖(X鎖)躬审、共享鎖(S鎖)

(1)棘街、排它鎖(X鎖、寫鎖)

排它鎖又稱為寫鎖承边。若事務(wù)T對數(shù)據(jù)對象A加上X鎖蹬碧,則只允許T讀取和修改A,其他任何事務(wù)都不能再對A加任何類型的鎖炒刁,直到T釋放A上的鎖。這就保證了其他事務(wù)在T釋放A上的鎖之前不能再讀取和修改A誊稚。

(2)翔始、共享鎖(S鎖、讀鎖)

共享鎖又被稱為讀鎖里伯。當(dāng)事務(wù)T對數(shù)據(jù)對象A加上S鎖城瞎,則事務(wù)T可以讀A但不能修改A,其他事務(wù)只能再對A加S鎖疾瓮,而不能加X鎖脖镀,直到T釋放A上的S鎖。這就保證了其他事務(wù)可以讀A狼电,但在T釋放A上的S鎖之前不能對A做任何修改蜒灰。

2、? 時間戳Timestamp

3肩碟、? 樂觀控制法

8强窖、死鎖和活鎖

1、活鎖

T1T2T3T4

Lock(R)???

?Lock(R)??

?等待Lock(R)?

Unlock(R)等待Lock(R)Lock(R)

?等待Unlock(R)等待

?等待?Lock(R)

(1)削祈、形成活鎖的原因

A翅溺、若事務(wù)T1封鎖了數(shù)據(jù)R脑漫,事務(wù)T2又請求封鎖R,則T2等待咙崎。

B优幸、T3也請求封鎖R,當(dāng)T1釋放了R上的封鎖后褪猛,系統(tǒng)首先批準(zhǔn)了T3的請求网杆,T2仍等待。

C握爷、T4又請求封鎖R跛璧,當(dāng)T3釋放了R上的封鎖之后,系統(tǒng)又批準(zhǔn)了T4的請求新啼。

D追城、T2可能永遠(yuǎn)等待,形成了活鎖燥撞。

(2)座柱、避免活鎖的方法

采用先來先服務(wù)的策略

2、死鎖

T1T2

Lock(R1)?

?Lock(R2)

Lock(R2)?

等待Lock(R1)

等待等待

(1)物舒、形成死鎖的原因

A色洞、事務(wù)T1封鎖了數(shù)據(jù)R1,事務(wù)T2封鎖了數(shù)據(jù)R2

B冠胯、T1請求封鎖R2火诸,于是T1等待T2釋放R2上的鎖

C、T2請求封鎖R1荠察,于是T2等待T1釋放R1上的鎖

D置蜀、這種互相等待對方的資源,形成死鎖悉盆。

(2)盯荤、解決死鎖的方法

A、破壞產(chǎn)生死鎖的條件焕盟,采取一定措施預(yù)防死鎖的發(fā)生:一次封鎖法秋秤、順序封鎖法

B、允許發(fā)生死鎖脚翘,采用一定手段定期診斷系統(tǒng)中有無死鎖灼卢,若有,則解除堰怨。

9芥玉、數(shù)據(jù)庫是怎么實現(xiàn)隔離級別的

數(shù)據(jù)庫有4種隔離級別:

1、? read_uncommited??? 未提交讀

(1)灿巧、原理

事物對當(dāng)前被讀取的數(shù)據(jù)不加鎖似舵;事物在更新某數(shù)據(jù)的瞬間(發(fā)生更新的瞬間)扰柠,必須先對其加“行級共享鎖”,直到事物結(jié)束才釋放。

(2)积瞒、表現(xiàn)

在提交前筷狼,一個事物可以看到另一個事物的變化劳吠;允許讀臟數(shù)據(jù)懒闷、不可重復(fù)讀、虛讀

2告抄、? read_commited???????? 已提交讀

(1)撰茎、原理

事物對當(dāng)前被讀取的數(shù)據(jù)加“航級共享鎖”(當(dāng)讀到時才加鎖),一旦讀完該行打洼,立即釋放該行級共享鎖

(2)龄糊、表現(xiàn)

不允許讀取未提交的數(shù)據(jù);允許不可重復(fù)讀募疮、虛讀炫惩。

3、? repeatable read???????? 可重復(fù)讀

(1)阿浓、原理

事物在讀取某數(shù)據(jù)的瞬間(開始讀取的瞬間)他嚷,必須先對其加“行級共享鎖”,直到事物結(jié)束后才釋放芭毙;事物在更新某數(shù)據(jù)的瞬間(發(fā)生更新的瞬間)爸舒,必須先對其加“行級排他鎖”,直到事物結(jié)束才釋放稿蹲。

(2)、表現(xiàn)

數(shù)據(jù)能夠保證在此讀取相同的數(shù)據(jù)而不會失斎到薄苛聘;允許虛讀。

4忠聚、? serializable????????????????? 可序列化

(1)设哗、原理

事務(wù)在讀取數(shù)據(jù)時,必須先對其叫“表級共享鎖”两蟀,直到事物結(jié)束才釋放网梢;事務(wù)在更新數(shù)據(jù)時,必須先對其加“表級排他鎖”赂毯,直到事務(wù)結(jié)束才釋放战虏。

(2)拣宰、表現(xiàn)

事物的最高級別;防止讀臟數(shù)據(jù)烦感、不可重復(fù)讀巡社、虛讀。

10手趣、讀臟數(shù)據(jù)晌该、不可重復(fù)讀、虛讀

1绿渣、讀臟數(shù)據(jù)

一個事務(wù)讀取了另一個事務(wù)尚未提交的數(shù)據(jù)朝群。當(dāng)事務(wù)A與事務(wù)B并發(fā)執(zhí)行時,當(dāng)事務(wù)A更新后中符,事務(wù)B查詢讀取到A尚未提交的數(shù)據(jù)姜胖,此時事務(wù)A回滾,則事務(wù)B讀到的數(shù)據(jù)是無效的臟數(shù)據(jù)舟茶。

事務(wù)A事務(wù)B

R(C)=100?

C <- C*2?

W(C)=200?

?R(C)=200

ROLLBACK?

C恢復(fù)為100?

2谭期、不可重復(fù)讀

一個事務(wù)的操作導(dǎo)致另一個事務(wù)前后兩次讀取到不同的數(shù)據(jù)。

當(dāng)事務(wù)A與事務(wù)B并發(fā)執(zhí)行時吧凉,事務(wù)A讀取數(shù)據(jù)后隧出,事務(wù)B執(zhí)行更新操作,使A無法再現(xiàn)前一次讀取結(jié)果阀捅。

事務(wù)A事務(wù)B

R(A)=50?

R(B)=100?

求和=150?

?R(B)=100

?B <- B*2

?W(B)=200

R(A)=50?

R(B)=200?

求和=250?

驗算不對?

3胀瞪、虛讀

一個事務(wù)的操作導(dǎo)致另一個事務(wù)前后兩次查詢的結(jié)果數(shù)量不同。

當(dāng)事務(wù)B查詢讀取數(shù)據(jù)后饲鄙,事務(wù)A新增或刪除了一條滿足B的查詢條件的記錄凄诞,此時,事務(wù)B再次查詢忍级,發(fā)現(xiàn)查詢到前次不存在的記錄帆谍。

11、索引

索引是一種結(jié)構(gòu)轴咱,加快檢索表中數(shù)據(jù)汛蝙。索引允許數(shù)據(jù)庫迅速地找到表中的數(shù)據(jù),而不必掃描整個數(shù)據(jù)庫朴肺。

1窖剑、? create index語句用于在表中創(chuàng)建索引。

2戈稿、? 在不讀取整個表的情況下西土,索引使數(shù)據(jù)庫應(yīng)用程序可以更快地查找數(shù)據(jù)。用戶無法看到索引鞍盗,只能被用來加速搜索/查詢需了。

3跳昼、? 更新一個包含索引的表比更新一個沒有索引的表需要更多的時間,因為索引本身也需要更新援所。

4庐舟、? 索引是對數(shù)據(jù)庫表中一列或多列的值進(jìn)行排序的一種結(jié)構(gòu),使用索引可快速訪問數(shù)據(jù)庫表中的特定信息住拭。

5挪略、? 索引的特點

(1)、索引可以加快數(shù)據(jù)庫的檢索速度

(2)滔岳、索引降低了數(shù)據(jù)庫插入杠娱、修改、刪除等維護(hù)任務(wù)的速度

(3)谱煤、索引創(chuàng)建在表上摊求,不能創(chuàng)建在視圖上。(視圖是一個虛表)

(4)刘离、使用查詢處理器執(zhí)行SQL語句室叉,在一個表上,一次只能使用一個索引硫惕。

6茧痕、索引的缺點

(1)、創(chuàng)建索引和維護(hù)索引需要消耗時間恼除,隨著數(shù)據(jù)量的增加而增加踪旷。

(2)、索引需要占物理空間豁辉,除了數(shù)據(jù)表占數(shù)據(jù)空間外令野,每一個索引還要占一定的物理空間,若簡歷聚集索引徽级,則需要的空間就會更大气破。

(3)、對表中的數(shù)據(jù)進(jìn)行增加餐抢、刪除和修改時堵幽,索引要動態(tài)的維護(hù),降低了數(shù)據(jù)的維護(hù)速度弹澎。

12、聚集索引和非聚集索引的區(qū)別

兩者的區(qū)別:表記錄的排序順序與索引的排列順序是否一致努咐。

1苦蒿、? 聚集索引(一個表中只能有一個聚集索引)

(1)、聚集索引的定義

為提高某個屬性(或?qū)傩越M)的查詢速度渗稍,把這個或這些屬性上具有相同值的元組幾種存放在連續(xù)的物理塊稱為聚集佩迟。

(2)团滥、聚集的作用

將某一列(或是多列)在磁盤中的物理順序改變,為和在SQL SERVER表中的邏輯順序一致报强。

(3)灸姊、聚集索引

在SQL SERVER中,聚集索引的存儲是以B樹存儲秉溉,B樹的葉子直接存儲聚集索引的數(shù)據(jù)力惯。由于聚集索引改變的是其所在表的物理存儲順序,因此召嘶,每個表只能有一個聚集索引父晶。

2、? 非聚集索引

(1)弄跌、非聚集索引并不改變其所在表的物理結(jié)構(gòu)甲喝,而是額外生成一個聚集索引的B樹結(jié)構(gòu)。

(2)铛只、葉子節(jié)點是對于其所在表的引用埠胖。若其所在表上沒有聚集索引,引用行號淳玩;若其所在表上有聚集索引直撤,引用聚集索引的頁。

(3)凯肋、若其所在表的物理結(jié)構(gòu)改變后(加上或是刪除聚集索引)谊惭,則所有非聚集索引都需要被重建。

3侮东、聚集索引和非聚集索引的區(qū)別

(1)圈盔、根本區(qū)別:表記錄的排列順序和索引的排列順序是否一致。

聚集索引表記錄的排列順序和索引的排列順序一致悄雅;非聚集索引表記錄的排列順序和索引的排列順序不一致驱敲。

(2)、聚集索引查詢速度快

使用聚集索引找到包含第一個值的行后宽闲,便可以確保包含后續(xù)索引值的行在物理相鄰众眨,從而減少了磁盤掃描。

(3)容诬、聚集索引的缺點:對表進(jìn)行修改速度較慢

為了保持記錄表中的記錄的物理順序和索引順序一致娩梨,把記錄插入到數(shù)據(jù)頁的相應(yīng)位置時,必須在數(shù)據(jù)頁中進(jìn)行數(shù)據(jù)重排览徒,降低了執(zhí)行速度狈定。

(4)、聚集索引和非聚集索引都采用B+樹的結(jié)構(gòu),聚集索引的葉節(jié)點是數(shù)據(jù)節(jié)點纽什,非聚集索引的葉節(jié)點是索引節(jié)點措嵌。


設(shè)計模式

1、設(shè)計模式的六大原則

1芦缰、開閉原則(Open Close Principle)

開閉原則的意思是:對擴(kuò)展開放企巢,對修改關(guān)閉。

2让蕾、里氏代換原則(Liskov Substitution Principle)

里氏代換原則是面向?qū)ο笤O(shè)計的基本原則之一浪规。 里氏代換原則中說,任何基類可以出現(xiàn)的地方涕俗,子類一定可以出現(xiàn)罗丰。

3、依賴倒轉(zhuǎn)原則(Dependence Inversion Principle)

這個原則是開閉原則的基礎(chǔ)再姑,具體內(nèi)容:針對接口編程萌抵,依賴于抽象而不依賴于具體。

4元镀、接口隔離原則(Interface Segregation Principle)

使用多個隔離的接口绍填,比使用單個接口要好。降低類之間的耦合度栖疑。

5讨永、迪米特法則,又稱最少知道原則(Demeter Principle)

一個實體應(yīng)當(dāng)盡量少地與其他實體發(fā)生相互作用遇革,使得系統(tǒng)功能模塊相對立卿闹。

6、合成復(fù)用原則(Composite Reuse Principle)

合成復(fù)用原則是指:盡量使用合成/聚合的方式萝快,而不是使用繼承

2锻霎、單例模式

分為單線程和多線程2中情況

3、工廠模式

包括:

簡單工廠模式:根據(jù)提供的參數(shù)動態(tài)的穿件某一類型的對象揪漩。

工廠方法模式:定義一個用于創(chuàng)建產(chǎn)品對象的工廠接口旋恼,將實際創(chuàng)建工作推遲到工廠接口的子類中。

抽象工廠模式:

4奄容、適配器模式

5冰更、觀察者模式(發(fā)布/訂閱模式)


數(shù)據(jù)結(jié)構(gòu)與算法

1、鏈表

單鏈表的增刪操作

可定義如下鏈表類來存儲結(jié)點信息

public class Node {

? ? int data;

? ? Node next = null;

? ? public Node(int data) {

? ? ? ? this.data = data;

? ? }

}

鏈表的基本操作:

public class MyLinkedList {? ? Node head = null; //鏈表頭結(jié)點? ? /**

? ? * 向鏈表中添加一個元素

? ? * @param data:添加的元素

? ? */? ? public void addNode(int data){

? ? ? ? Node newNode = new Node(data);

? ? ? ? if(head == null){

? ? ? ? ? ? head = newNode;

? ? ? ? ? ? return;

? ? ? }

? ? ? ? Node temp = head;

? ? ? ? while(temp.next != null){

? ? ? ? ? ? temp = temp.next;

? ? ? ? }

? ? ? ? temp.next = newNode;

? ? }

? ? /**

? ? * 刪除第index個基點

? ? * @param index:待刪除結(jié)點索引

? ? * @return 成功返回true昂勒,失敗返回false

? ? */? ? public boolean deleteNode(int index){

? ? ? ? //如果刪除元素位置不合理? ? ? ? if(index<1 || index>length()){

? ? ? ? ? ? return false;

? ? ? ? }

? ? ? ? //刪除第index個結(jié)點的元素? ? ? ? if(index == 1){

? ? ? ? ? ? head = head.next;

? ? ? ? ? ? return true;

? ? ? ? }

? ? ? ? int i = 2;

? ? ? ? Node preNode = head;

? ? ? ? Node curNode = head.next;

? ? ? ? while(curNode != null){

? ? ? ? ? ? if(i == index){

? ? ? ? ? ? ? ? preNode.next = curNode.next;

? ? ? ? ? ? ? ? return true;

? ? ? ? ? ? }

? ? ? ? ? ? preNode = curNode;

? ? ? ? ? ? curNode = curNode.next;

? ? ? ? ? ? i++;

? ? ? ? }

? ? ? ? return true;

? ? }

? ? /**

? ? * @return 返回鏈表的長度

? ? */? ? public int length(){

? ? ? ? int length = 0;

? ? ? ? Node temp = head;

? ? ? ? while(temp != null){

? ? ? ? ? ? length++;

? ? ? ? ? ? temp = temp.next;

? ? ? ? }

? ? ? ? return length;

? ? }

? ? /**

? ? * 對鏈表進(jìn)行排序

? ? * @return 返回排序后鏈表的頭結(jié)點

? ? */? ? public Node orderList(){

? ? ? ? int temp = 0;

? ? ? ? Node curNode = head;

? ? ? ? Node nextNode = null;

? ? ? ? while(curNode.next != null){

? ? ? ? ? ? nextNode = curNode.next;

? ? ? ? ? ? while(nextNode != null){

? ? ? ? ? ? ? ? if(curNode.data > nextNode.data){

? ? ? ? ? ? ? ? ? ? temp = curNode.data;

? ? ? ? ? ? ? ? ? ? curNode.data = nextNode.data;

? ? ? ? ? ? ? ? ? ? nextNode.data = temp;

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? nextNode = nextNode.next;

? ? ? ? ? ? }

? ? ? ? ? ? curNode = curNode.next;

? ? ? ? }

? ? ? ? return head;

? ? }

? ? /**

? ? * 打印鏈表

? ? */? ? public void printList(){

? ? ? ? Node temp = head;

? ? ? ? while(temp != null){

? ? ? ? ? ? System.out.print(temp.data);

? ? ? ? ? ? temp = temp.next;

? ? ? ? }

? ? }

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

? ? ? ? MyLinkedList list = new MyLinkedList();

? ? ? ? list.addNode(2);

? ? ? ? list.addNode(1);

? ? ? ? list.addNode(2);

? ? ? ? list.addNode(3);

? ? ? ? list.addNode(5);

? ? ? ? System.out.println("before order:");

? ? ? ? list.printList();

? ? ? ? list.orderList();

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

? ? ? ? System.out.println("after order:");

? ? ? ? list.printList();

? ? ? ? list.deleteNode(2);

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

? ? ? ? System.out.println("刪除第二個節(jié)點后:");

? ? ? ? list.printList();

? ? }

}

2.如何從鏈表中刪除重復(fù)數(shù)據(jù)

方法1:(最容易想到)

遍歷鏈表蜀细,將遍歷到的值存儲到HashTable中,若當(dāng)前遍歷的值在HashTable中

存在戈盈,則說明當(dāng)前數(shù)據(jù)是重復(fù)的奠衔,因此刪除。

public void deleteDuplecate(Node head){

HashTable table=new HashTable<>();

Node tmp=head;

Node pre=null;

while(tmp!=null){

if(table.containsKey(tmp.data)){

pre.next=tmp.next;

}else{

table.put(tmp.data,1);

pre=tmp;

}

}

}

優(yōu)點:時間復(fù)雜度低

缺點:需要額外的存儲空間

方法2:

對鏈表進(jìn)行雙重循環(huán)遍歷,外循環(huán)正常遍歷鏈表涣觉,假設(shè)外循環(huán)當(dāng)前遍歷的節(jié)點為

cur,內(nèi)循環(huán)從cur開始遍歷,若遇到與cur相同的值血柳,則刪除這個重復(fù)的節(jié)點官册。

public void deleteDuplecate(Node head){

Node p=head;

while(p!=null){

Node q=p;

while(q.next!=null){

if(p.data==q.next.data){

q.next=q.next.next;

}else{

q=q.next;

}

}

p=p.next;

}

}

優(yōu)點:不需要額外存儲空間

缺點:時間復(fù)雜度高

3抄淑、如何找出單鏈表中的倒數(shù)第K個元素

方法1:

先遍歷一遍鏈表計算出鏈表長度n,要求出倒數(shù)第k個元素农曲,轉(zhuǎn)化為正數(shù)第n-k個元素,然后在遍歷一遍鏈表欧聘,得到倒數(shù)第k個元素根吁。

缺點:要遍歷2遍鏈表

方法2:

設(shè)置2個指針员淫,讓其中一個比另外一個先前移k-1步,然后兩個指針同時往前移動击敌。循環(huán)直到現(xiàn)行的指針值為null,另一個指針?biāo)诘奈恢镁褪撬檎业奈恢谩?/p>

public Node findElem(Node head,int k){

? ? ? ? if(k<1 || head == null){

? ? ? ? ? ? return null;

? ? ? ? }

? ? ? ? Node p1 = head;

? ? ? ? Node p2 = head;

? ? ? ? for (int i = 0; i < k - 1; i++) { //前移k-1步? ? ? ? ? ? if(p2.next != null){

? ? ? ? ? ? ? ? p2 = p2.next;

? ? ? ? ? ? }else {

? ? ? ? ? ? ? ? return null;

? ? ? ? ? ? }

? ? ? ? while (p2 != null) {

? ? ? ? ? ? p1 = p1.next;

? ? ? ? ? ? p2 = p2.next;

? ? ? ? }

? ? ? ? return p2;

? ? }

4介返、如何實現(xiàn)鏈表的反轉(zhuǎn)

反轉(zhuǎn)前:a->b->c->d

反轉(zhuǎn)后:a<-b<-c<-d

public void ReverseIteratively(Node? head){

Node? pReversedHead = NULL;

Node? pNode = head;

Node? pPrev = NULL;

? ? while(pNode != NULL){

Node? pNext = pNode.next;

if(pNext == NULL)

pReversedHead = pNode;

pNode.next = pPrev;

pPrev = pNode;

pNode = pNext;

? ? }

? ? return this.head= pReversedHead;

}

5、如何從尾到頭輸出單鏈表

方法1:

將鏈表反轉(zhuǎn)沃斤,然后遍歷輸出

缺點:需要額外的操作

方法2:

從頭到尾遍歷鏈表圣蝎,將每個節(jié)點值放入棧中,遍歷完鏈表后衡瓶,從棧頂輸出元素

缺點:需要額外的椗枪空間

方法3:

遞歸的本質(zhì)是棧結(jié)構(gòu)

要反轉(zhuǎn)輸出鏈表,每訪問一個節(jié)點哮针,先遞歸輸出它后面的節(jié)點关面,再輸出該節(jié)點自

身,這樣鏈表就反過來輸出了十厢。

public void printListReversely(Node? pListHead) {

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

? ? ? ? ? ? printListReversely(pListHead.next);? ? ? ? }

? ? ? System.out.println(pListHead.data);

? ? }

6等太、如何尋找單鏈表的中間結(jié)點

方法1:

遍歷鏈表求出鏈表長度length,然后再遍歷length/2的距離寿烟,即可查到中間結(jié)點澈驼。

缺點:2次遍歷鏈表

方法2:

若是雙向鏈表,可以首尾同時并行筛武,當(dāng)2個指針相遇缝其,就找到了中間元素。

若是單鏈表徘六,也采用雙指針的方法内边,具體而言:(1)有兩個指針同時從頭開始遍歷;

(2)一個快指針每次走2步待锈,一個慢指針一次走1步漠其;(3)快指針先到鏈表尾部,而慢指針剛好到達(dá)鏈表中部(當(dāng)快指針到達(dá)尾部,若是奇數(shù)個元素和屎,則慢指針指向的就是中間元素拴驮;若是偶數(shù)個元素,則慢指針指向的結(jié)點和慢指針的下一個結(jié)點都是中間結(jié)點柴信。)

public Node? SearchMid(Node head){

Node p=this.head;

Node q=this.head;

while(p!=null&&q.next!=null&&p.next.next!=null){

p=p.next.next;

q=q.next;

}

return q;

}

7套啤、如何檢測一個鏈表中是否有環(huán)

定義兩個指針fast和slow,初始都指向鏈表頭随常,fast每次前進(jìn)兩步潜沦,slow每次走一步,兩個指針同時向前移動绪氛,快指針每次移動都要和慢指針進(jìn)行比較唆鸡,直到快指針等于慢指針,就證明這個鏈表是帶環(huán)的單向鏈表枣察,否則争占,證明是循環(huán)鏈表(fast先行到達(dá)尾部為null,則鏈表為無環(huán)鏈表)询件。

public boolean IsLoop(Node head)? {

Node fast = head;

Node slow = head;

if(fast==null){

return false;

}

while( fast != null&& fast->next != null)? {

fast = fast.next.next;?

? ? ? ? ? slow = slow.next;

? ? ? ? ? if(fast == slow)? {?

? ? ? ? ? return true;

}

}

return? !(fast ==null || fast.next==null);

}?

檢測環(huán)的入口:

public Node? FindLoopPort(Node head)? {?

? ? Node fast = head;?

? ? Node slow = head;?

? ? while( fast != null&& fast->next != null) {?

fast = fast.next.next;?

? ? ? ? ? ? slow = slow.next;? ? ? ? if(fast == slow)? {?

? ? ? ? ? break;?

? ? }?

? ? ? ? ? }?

? ? if(fast == null|| fast.next == null)?

? ? ? ? return null;?

? slow = head;?

? ? while(slow != fast) {?

? ? ? ? slow = slow.next;?

? ? ? fast = fast.next;?

? }?

? return slow;?

}?

8燃乍、如何在不知道頭指針的情況下刪除指定結(jié)點

分2種情況談?wù)摚?/p>

若待刪除的結(jié)點為鏈表尾結(jié)點,則無法刪除宛琅,因為刪除后無法使其前驅(qū)結(jié)點的next指針置為空刻蟹;

若待刪除的結(jié)點不為尾結(jié)點,則可以通過交換這個結(jié)點與其后繼結(jié)點的值嘿辟,然后刪除后繼結(jié)點

public boolean deleteNode(Node? n){

if(n==null || n.next==null)

return fasle;

int tmp=n.data;

n.data=n.next.data;

n.next=n.next.next;

return trun;

}

9舆瘪、如何判斷兩個鏈表是否相交

如果兩個鏈表相交,那么他們一定有相同的尾結(jié)點红伦。

public boolean isIntersect(Node h1,Node h2){

if(h1==null || h2==null)

return false;

Node tail1=h1;

while(tail1.next!=null){

tail1=tail1.next;

}

Node tail2=h2;

while(tail2.next!=null){

tail2=tail2.next;

}

return tail1==tail2;

}

時間復(fù)雜度:O(len1+len2)

引申:如果兩個鏈表相交英古,如何找到它們相交的第一個結(jié)點?

首先昙读,分別計算兩個鏈表head1召调、head2的長度len1、len2(假設(shè)len1>len2)蛮浑,接著先對鏈表head1遍歷(len1-len2)個結(jié)點到結(jié)點p唠叛,此時結(jié)點p和head2到它們相交的結(jié)點的距離相同,此時同時遍歷兩個鏈表沮稚,直到遇到相同的結(jié)點為止艺沼,這個結(jié)點就是相交的第一個結(jié)點。

public static Node? getFirstMeetNode(Node h1,Mode h2){

if(h1==null || h2 ==null){

return null;

}

Node tail1=h1;

int len1=1;

while(tail1.next!=null){

tail1=tail1.next;

len1++;

}

Node tail2=h2;

int len2=1;

while(tail2.next!=null){

tail2=tail2.next;

len1++;

}

if(tail1 !=tail2)

return null;

Node t1=h1;

NOde t2=h2;

if(len1>len2){

int d=len1-len2;

while(d!=0){

t1=t1.next;

d--;

}

}else{

int d=len2-len1;

while(d!=0){

t2=t2.next;

d--;

}

}

while(t1!=t2){

t1=t1.next;

t2=t2.next;

}

return t1;

}

缺點:需要遍歷2遍

O(len1+len2)

2蕴掏、棧與隊列

1障般、站與隊列的區(qū)別

棧:先進(jìn)后出

隊列:先進(jìn)先出

2调鲸、如何實現(xiàn)棧

可以采用數(shù)組和鏈表兩種方式實現(xiàn)棧。

3挽荡、如何用O(1)的時間復(fù)雜度求棧中最小元素

一個棧存儲數(shù)據(jù)藐石,另一個棧存儲最小元素。

實現(xiàn)思路如下:

(1)使用 elem 和 min 兩個棧結(jié)構(gòu)定拟,elem 用來存儲數(shù)據(jù)贯钩,min 用來存儲 elem 棧的最小元素。

(2)在入棧時办素,如果當(dāng)前入棧的元素比原來棧中的最小值還小,則把這個值壓入 min 棧中祸穷;

(3)在出棧時性穿,如果當(dāng)前出棧的元素巧好為當(dāng)前棧中的最小值,則 min 棧的棧頂元素也出棧雷滚,是的當(dāng)前最小值變?yōu)槠淙霔V暗哪莻€最小值需曾。

public class GetStackMinEle {

? ? MyStack elem;

? ? MyStack min;

? ? public GetStackMinEle() {

? ? ? ? elem = new MyStack();

? ? ? ? min = new MyStack();

? ? }

? ? // 入棧時需要考慮當(dāng)前元素是否是當(dāng)前棧最小元素,是的話當(dāng)前元素也要壓入 min 棧中? ? public void push(int data) {

? ? ? ? elem.push(data);

? ? ? ? if(min.isEmpty())

? ? ? ? ? ? min.push(data);

? ? ? ? else {

? ? ? ? ? ? if(data < min.peek())

? ? ? ? ? ? ? ? min.push(data);

? ? ? ? }

? ? }

? ? //出棧時祈远,需要判斷 elem 棧頂元素是否為當(dāng)前棧的最小值呆万,是的話,min 棧頂元素也要出棧? ? public int pop() {

? ? ? ? int topData = elem.peek();

? ? ? ? elem.pop();

? ? ? ? if(topData == this.min())

? ? ? ? ? ? min.pop();

? ? ? ? return topData;

? ? }

? ? public int min() {

? ? ? ? if(min.isEmpty())

? ? ? ? ? ? return Integer.MAX_VALUE;

? ? ? ? else? ? ? ? ? ? return min.peek();

? ? }

}

4车份、如何實現(xiàn)隊列

隊列實現(xiàn):數(shù)組和鏈表

5谋减、如何使用兩個棧模擬隊列操作

3、排序

1扫沼、選擇排序

原理:給定一組記錄出爹,經(jīng)過第一輪比較后得到最小的記錄,然后將該記錄與第一個記錄位置交換缎除;接著將不包括第一個記錄的其他記錄記性第二輪比較严就,得到最小記錄并于第二個記錄位置交換;以此類推器罐。

public? static void? selectSort(int[] a){

int temp=0;

int flag=0;

for(int i=0;i

temp=a[i];

flag=i;

for(int j=i+1;j

if(a[j]

temp=a[j];

flag=j;

}

}

if(flag!=i){

a[flag]=a[i];

a[i]=temp;

}

}

}

2梢为、插入排序

原理:給定一組記錄,初始時假設(shè)第一個記錄是有序的轰坊,其余的為無序的铸董。從第二個記錄開始,將記錄插入到之前有序的序列中衰倦,直到最后一個記錄插入到有序序列中袒炉。

public static void insertSort(int[] a){

for(int i=1;i

int temp=a[i],j=i;

if(temp

while(j>=1&&temp

a[j]=a[j-1];

j--;

}

}

a[j]=temp;

}

}

3、冒泡排序

原理:對于給定的一組記錄樊零,從第一個記錄開始依次對相鄰的兩個記錄進(jìn)行比較我磁,當(dāng)前面的大于后面的記錄時孽文,交換位置,進(jìn)行一輪比較和交換之后夺艰,n個記錄最大的位于第n位置上芋哭;然后對前n-1個記錄進(jìn)行類似操作。

public static void BubbleSort(int[] a){

for(int i=a.length-1;i>=0;i--){

for(j=0;j

if(a[j]>a[j+1]){

int tmp=a[j];

a[j]=a[j+1];

a[j+1]=tmp;

}

}

}

}

4郁副、歸并排序

原理:對于給定的記錄减牺,現(xiàn)將每兩個相鄰長度為1的子序列進(jìn)行遞歸,得到n/2個長度為2或者1的有序子序列存谎,再將其兩兩歸并拔疚,如此反復(fù)

public static void MergeSort(int[] array, int low, int high) {

int mid = (low + high) / 2;

if (low < high) {

// 左邊

sort(array, low, mid);

// 右邊

sort(array, mid + 1, high);

// 左右歸并

merge(array, low, mid, high);

}

}

public static void merge(int[] array, int low, int mid, int high) {

int[] temp = new int[high - low + 1];

int i = low;// 左指針

int j = mid + 1;// 右指針

int k = 0;

// 把較小的數(shù)先移到新數(shù)組中

while (i <= mid && j <= high) {

if (array[i] < array[j]) {

temp[k++] = array[i++];

} else {

temp[k++] = array[j++];

}

}

// 把左邊剩余的數(shù)移入數(shù)組

while (i <= mid) {

temp[k++] = array[i++];

}

// 把右邊邊剩余的數(shù)移入數(shù)組

while (j <= high) {

temp[k++] = array[j++];

}

// 把新數(shù)組中的數(shù)覆蓋array數(shù)組

for (int k2 = 0; k2 < temp.length; k2++) {

array[k2 + low] = temp[k2];

}

}

5、快速排序

原理:

public static void quickSort(int a[], int low, int hight) {

? ? ? ? int i, j, index;

? ? ? ? if (low > hight) {

? ? ? ? ? ? return;

? ? ? ? }

? ? ? ? i = low;

? ? ? ? j = hight;

? ? ? ? index = a[i]; // 用子表的第一個記錄做基準(zhǔn)

? ? ? ? while (i < j) { // 從表的兩端交替向中間掃描

? ? ? ? ? ? while (i < j && a[j] >= index)

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

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

? ? ? ? ? ? ? ? a[i++] = a[j];// 用比基準(zhǔn)小的記錄替換低位記錄

? ? ? ? ? ? while (i < j && a[i] < index)

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

? ? ? ? ? ? if (i < j) // 用比基準(zhǔn)大的記錄替換高位記錄

? ? ? ? ? ? ? ? a[j--] = a[i];

? ? ? ? }

? ? ? ? a[i] = index;// 將基準(zhǔn)數(shù)值替換回 a[i]

? ? ? ? sort(a, low, i - 1); // 對低子表進(jìn)行遞歸排序

? ? ? ? sort(a, i + 1, hight); // 對高子表進(jìn)行遞歸排序

? ? }

6既荚、希爾排序(縮小增量排序)

原理:先講待排序數(shù)組分為多個子序列稚失,使得每個子序列的元素個數(shù)相對較少,然后對各個子序列分別進(jìn)行直接插入排序

public static void shellSort(int array[ ]){

? ? ? ? if(arrays == null || arrays.length <= 1){

? ? ? ? ? ? return;

? ? ? ? }

? ? ? ? //增量

? ? ? ? int incrementNum = arrays.length/2;

? ? ? ? while(incrementNum >=1){

? ? ? ? ? ? for(int i=0;i

? ? ? ? ? ? ? ? //進(jìn)行插入排序

? ? ? ? ? ? ? ? for(int j=i;j

? ? ? ? ? ? ? ? ? ? if(arrays[j]>arrays[j+incrementNum]){

? ? ? ? ? ? ? ? ? ? ? ? int temple = arrays[j];

? ? ? ? ? ? ? ? ? ? ? ? arrays[j] = arrays[j+incrementNum];

? ? ? ? ? ? ? ? ? ? ? ? arrays[j+incrementNum] = temple;

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? ? ? //設(shè)置新的增量

? ? ? ? ? ? incrementNum = incrementNum/2;

? ? ? ? }

}

7恰聘、堆排序

public void HeapAdjust(int[] array, int parent, int length) {

? ? int temp = array[parent]; // temp保存當(dāng)前父節(jié)點

? ? int child = 2 * parent + 1; // 先獲得左孩子

? ? while (child < length) {

? ? ? ? // 如果有右孩子結(jié)點句各,并且右孩子結(jié)點的值大于左孩子結(jié)點,則選取右孩子結(jié)點

? ? ? ? if (child + 1 < length && array[child] < array[child + 1]) {

? ? ? ? }

? ? ? ? // 如果父結(jié)點的值已經(jīng)大于孩子結(jié)點的值晴叨,則直接結(jié)束

? ? ? ? if (temp >= array[child])

? ? ? ? ? ? break;

? ? ? ? // 把孩子結(jié)點的值賦給父結(jié)點

? ? ? ? array[parent] = array[child];

? ? ? ? // 選取孩子結(jié)點的左孩子結(jié)點,繼續(xù)向下篩選

? ? ? ? parent = child;

? ? ? ? child = 2 * child + 1;

? ? }

? ? array[parent] = temp;

}

public void heapSort(int[] list) {

? ? // 循環(huán)建立初始堆

? ? for (int i = list.length / 2; i >= 0; i--) {

? ? ? ? HeapAdjust(list, i, list.length - 1);

? ? }

? ? // 進(jìn)行n-1次循環(huán)凿宾,完成排序

? ? for (int i = list.length - 1; i > 0; i--) {

? ? ? ? // 最后一個元素和第一元素進(jìn)行交換

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

? ? ? ? list[i] = list[0];

? ? ? ? list[0] = temp;

? ? ? ? // 篩選 R[0] 結(jié)點,得到i-1個結(jié)點的堆

? ? ? ? HeapAdjust(list, 0, i);

? ? ? ? System.out.format("第 %d 趟: \t", list.length - i);

? ? ? ? printPart(list, 0, list.length - 1);

? ? }

}

8兼蕊、各種排序算法優(yōu)劣

4初厚、位運算

1、如何用移位操作實現(xiàn)乘法運算

左移n位相當(dāng)于把一個數(shù)乘以2的n次方孙技;右移是除以2的n次方

2惧所、如何判斷一個數(shù)是否為2的n次方

方法1:

用1做移位操作,然后判斷移位后的值是否與給定的值相等绪杏。

方法2:

將待判斷的數(shù)減1然后再和待判斷的數(shù)進(jìn)行與操作

3下愈、求二進(jìn)制中1的個數(shù)

判斷這個數(shù)最后一位是否為1,如果為1蕾久,則計數(shù)器加1势似,然后將這個數(shù)右移1位丟棄掉最后一位。循環(huán)至這個數(shù)為0.判斷二進(jìn)制最后一位是否為1時僧著,可以采用與1與運算達(dá)到目的履因。

5、數(shù)組

1盹愚、如何尋找數(shù)組中的最小值與最大值

方法1:問題分解法栅迄。每次沒別找出最大值和最小值。一共需要遍歷2次數(shù)組皆怕。O(2n)

方法2:取單元素法毅舆。維持兩個變量min和max,每次取出一個元素先個最小值比較西篓,再與最大值比較。只需遍歷一次數(shù)組憋活。O(n)

方法3:取雙元素法岂津。O(1.5n)

2、如何找出數(shù)組中第二大的數(shù)

方法:定義兩個變量悦即,一個用于存儲數(shù)組的最大數(shù)吮成,初始值為數(shù)組首元素,另一個變量存儲數(shù)組元素的第二大數(shù)辜梳,初始值為最小負(fù)整數(shù)粱甫,然后遍歷數(shù)組元素,如果數(shù)組元素值比最大數(shù)變量的值大作瞄,則將第二大數(shù)值更新為最大數(shù)變量的值魔种,最大數(shù)變量的值更新為該數(shù)組的值,若該數(shù)組元素的值比最大數(shù)的值小粉洼,則判斷是否比第二大數(shù)值大,如數(shù)組元素的值比第二大數(shù)值大叶摄,則第二大數(shù)更新為該元素值属韧。

public static? int FindSecMax(int data[ ]){

int count=data.length;

int maxnumber=data[0];

int sec_max=Integer.MIN_VALUE;

for(int i=0;i

if(data[i]>maxnumber){

sec_max=maxnumber;

maxnumber=data[i];

}else{

if(data[i]>sec_max)

sec_max=data[i];

}

}

return sec_max;

}

3、如何求最大子數(shù)組之和

方法1:蠻力法蛤吓。O(n^3)

public static int maxSubArray(int arr[ ]){

int ThisSum=0,MaxSum=0;

for(int i=0;i

for(int j=i;j

ThisSum=0;

for(int k=i;k

ThisSum += arr[k];

if(ThisSum>MaxSum){

MaxSum=ThisSum;

}

}

}

}

return MaxSum;

}

方法2:O(n^2)

public static int maxSubArray(int arr[ ]){

int size=arr.length;

int maxSum=Integer.MIN_VALUE;

for(int i=0;i

int sum=0;

for(int j=i;j

sum += arr[j];

if(sum >maxSum){

maxSum=sum;

}

}

}

}

return MaxSum;

}

方法3:動態(tài)規(guī)劃法宵喂。O(n)

public static int maxSubArray(int arr[ ]){

int End[]=new int [n];

int All[]=new int [n];

End[n-1]=arr[n-1];

All[n-1]=arr[n-1];

End[0]=All[0]=arr[0];

for(int i=1;i

End[i]=max(End[i-1]+arr[i],arr[i]);

All[i]=max(End[i],All[i-1]);

}

return All[n-1];

}

4、如何找出數(shù)組中重復(fù)元素最多的數(shù)

方法1:空間換時間(不推薦)

方法2:使用Map表

public staticintfindMostFrequentInArray(int[] a){

int result=0;

int size=a.length;

if(size==0)

return Integer.MAX_VALUE;

Map m=new hashMap<>();

for(int i=0;i

if(m.containsKey(a[i])){

m.put(a[i],m.get(a[i])+1);

}else{

m.put(a[i],1);

}

}

int most=0;

Iterator iter=m.entrySet().iterator();

while(iter.hasNext()){

Map.Entry entry=(Map.Entry )iter.next();

int key=(Integer)entry.getkey();

int val=(Integer)entry.getVlaue();

if(val>most){

result=key;

most=val;

}

}

return result;

}

5会傲、如何求數(shù)組中兩兩相加等于20的組合種數(shù)

方法1:蠻力法O(n^2)

public static? void findSum(int[] a,int sum){

for(int i=0;i

for(int j=i;j

if(a[i]+a[j]==sum){

system.out.println(a[i]+","+a[j]);

}

}

}

}

方法2:排序法

先對數(shù)組元素進(jìn)行排序锅棕,采用堆或者快速排序,時間復(fù)雜度O(nlogn)淌山,然后對排序后的數(shù)組分別從前到后和從后到前遍歷裸燎,假設(shè)從前往后遍歷下標(biāo)為begin,從后往前遍歷下標(biāo)為end,那么滿足arr[begin]+arr[end]<20時泼疑,如果存在兩個數(shù)和為20德绿,那么這兩個數(shù)一定在[begin+1,end]之間;當(dāng)滿足arr[begin]+arr[end]>20,如果存在兩個數(shù)和為20退渗,那么這兩個數(shù)一定在[begin,end+1]之間移稳,這個過程時間復(fù)雜度O(n),因此整個復(fù)雜度O(nlogn).

public static? void findSum(int[] a,int sum){

Arrays.stor(a);

int begin=0;

int end=a.length-1;

while(begin

if(a[begin]+a[end]

begin++;

else if(a[begin]+a[end]

end--;

else{

Sysotem.oyt.println(a[begin]+","+a[end]);

begin++;

end--;

}

}

}

6会油、如何把一個數(shù)組循環(huán)右移k位 O(n)

public static void reverse(int[] a个粱,int b,int e){

for(;b

int temp=a[e];

a[e]=a[b];

a[b]=temp;

}

}

public static void shift_k(int a[],int k){

k=k%n;

reverse(a,n-k,n-1);

reverse(a,0,n-k-1);

reverse(a,0,n-1);

}

7、如何找出數(shù)組中第k個最小的數(shù)

方法1:排序法? O(nlogn)

將數(shù)組從小到大進(jìn)行排序翻翩,數(shù)組第k-1個就是第k個最小的元素都许。

方法2:剪枝法

采快速排序的思想來實現(xiàn)稻薇。思路:選取一個樞紐temp=a[n-1],把比它小的放在左邊梭稚,比它大的放在右邊颖低,然后判斷temp的位置。如果它的位置為k-1弧烤,則它就是第k個最小的元素忱屑;如果它的位置小于k-1,則說明第k個最小的元素一定在數(shù)組右半邊,采用遞歸在數(shù)組右邊繼續(xù)查找暇昂;否則在左半邊查找莺戒。

public static int quikStort(int array[],int low,int high,int k){

int i,j;

int temp;

if(low>hign)

return Integer.MIN_VALUE;

i=low+1;

j=hign;

temp=a[i];

while(i

while(i=temp)

j--;

if(j

array[i++]=array[j];

while(i

i++;

if(j

array[j--]=array[i];

}

array[i]=temp;

if(i+1==k)

return temp;

else if(i+1>k)

return quikStort(array,low,i-1,k);

esle

return quikStort(array,i+1,high,k);

}

8、如何查找數(shù)組中出現(xiàn)一次的數(shù)字

出現(xiàn)一次的數(shù)急波,其他出現(xiàn)2次

方法1:異或法

任何一個異或它本身為0从铲。

public static int findNotDouble(inr a[]){

int result=a[0];

for(int i=1;i

result^=a[i];

return result;

}

引申:上述方法只使用其他數(shù)字出現(xiàn)偶數(shù)次。

9澄暮、如何找出數(shù)組中唯一重復(fù)的元素

P272

異或法名段,空間換時間、位圖法

10泣懊、如何用遞歸求一個整數(shù)數(shù)組的最大元素

遞歸求解數(shù)組第一個元素和數(shù)組中其他元素組成的子數(shù)組的最大值伸辟。

private int max(int a,intr b){

return a>b?a:b;

}

public int maxNumber(int a[],int begin){

int length=a.length-begin;

if(length==1){

return a[begin];

}else{

return max(a[begin],maxNumber(a,begin+1));

}

}

11、如何求數(shù)對之差的最大值

p276

12馍刮、如何求絕對值最小的元素

13信夫、如何求數(shù)組中兩個元素最小距離

14吠卷、如何求指定數(shù)字在數(shù)組中第一次出現(xiàn)的位置

15鸣奔、如何對數(shù)組的兩個子有序段進(jìn)行合并

16、如何計算兩個有序整數(shù)數(shù)組的交集

17葫哗、如何判斷一個數(shù)組中的數(shù)值是否連續(xù)相鄰

18匈辱、如何求解數(shù)組中反序的個數(shù)

19振湾、如何求解最小三元組的距離

6、字符串

1亡脸、如何實現(xiàn)字符串反轉(zhuǎn)

public void swap(char cArr,int front,int end){

while(front

char tmp=cArr[end];

cArr[end]=cArr[front];

cArr[front]=tmp;

front++;

end--;

}

}

public String swapWords(String s){

char[] cArr=s.toCharArray();

//對整個字符串進(jìn)行反轉(zhuǎn)

swap(cArr,0,cArr.length-1);

int begin=0;

//對每個單詞進(jìn)行反轉(zhuǎn)

for(int i=1;i

if(cArr[i]==" "){

swap(cArr,begin,i-1);

begin=i+1;

}

}

}

2恰梢、如何判斷連個字符串是否由相同的字符組成

兩個字符串的字母以及相應(yīng)字母個數(shù)相同

方法1:排序法

先將字符串排序,梗掰,然后比較嵌言。

public static boolean compare(String s1,String? s2){

byte[] b1=s1.getBytes();

byte[] b2=s2.getBytes();

Arrays.sort(b1);

Arrays.sort(b2);

s1=new String(b1);

s2=new String(b2);

if(s1.equeal(s2)){

return true;

}else{

return false;

}

}

方法2:空間換時間

3、如何刪除字符串中重復(fù)的字符

P298

4及穗、如何統(tǒng)計一行字符中有多少個單詞

public static int wordCount(String? s){

int word=0;

int count=0;

for(int i=0;i

if(s.charAt(i)==" "){

word=0;

}else if(word==0){

word=1;

count++;

}

}

return count;

}

5摧茴、如何按要求打印數(shù)組的排列情況

6、如何輸出字符串的所有組合

7埂陆、二叉樹

一一一一一一一一一一一海量數(shù)據(jù)處理一一一一一一一一一一一一

1苛白、基本方法

hash法娃豹、Bit-map法、Bloom filter法购裙、數(shù)據(jù)庫優(yōu)化法懂版、倒排索引法、外排序法躏率、Trie樹躯畴、堆、雙層桶法薇芝、MapReduce法

Hash法

常見構(gòu)建散列函數(shù)的方法:

直接地址法:取關(guān)鍵字或者關(guān)鍵字的某個線性函數(shù)值為散列地址蓬抄。

取模法:

數(shù)字分析法:

折疊法:

平方取中法:

除留余數(shù)法:

隨機(jī)數(shù)法:

解決沖突的方法:開放地址法、鏈接地址法夯到、再散列法嚷缭、建立公共溢出區(qū)

Bit-map法

使用位圖數(shù)組表示某些元素是否存在

2、經(jīng)典實例分析

top K問題

方法:分治+Trie樹/hash+小頂堆

重復(fù)問題

方法:位圖法

排序問題

方法:數(shù)據(jù)庫排序耍贾、分治法阅爽、位圖法

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市荐开,隨后出現(xiàn)的幾起案子付翁,更是在濱河造成了極大的恐慌,老刑警劉巖誓焦,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異着帽,居然都是意外死亡杂伟,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進(jìn)店門仍翰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來赫粥,“玉大人,你說我怎么就攤上這事予借≡狡剑” “怎么了?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵灵迫,是天一觀的道長秦叛。 經(jīng)常有香客問我,道長瀑粥,這世上最難降的妖魔是什么挣跋? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮狞换,結(jié)果婚禮上避咆,老公的妹妹穿的比我還像新娘舟肉。我一直安慰自己,他們只是感情好查库,可當(dāng)我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布路媚。 她就那樣靜靜地躺著,像睡著了一般樊销。 火紅的嫁衣襯著肌膚如雪整慎。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天现柠,我揣著相機(jī)與錄音院领,去河邊找鬼。 笑死够吩,一個胖子當(dāng)著我的面吹牛比然,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播周循,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼强法,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了湾笛?” 一聲冷哼從身側(cè)響起饮怯,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎嚎研,沒想到半個月后蓖墅,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡临扮,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年论矾,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片杆勇。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡贪壳,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蚜退,到底是詐尸還是另有隱情闰靴,我是刑警寧澤,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布钻注,位于F島的核電站蚂且,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏幅恋。R本人自食惡果不足惜膘掰,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧识埋,春花似錦凡伊、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至惠豺,卻和暖如春银还,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背洁墙。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工蛹疯, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人热监。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓捺弦,卻偏偏與公主長得像,于是被迫代替她去往敵國和親孝扛。 傳聞我的和親對象是個殘疾皇子列吼,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,762評論 2 345

推薦閱讀更多精彩內(nèi)容