java基礎(chǔ)
String
==用來判斷兩個變量是否相等時,如果兩個變量是基本類型變量,且都是數(shù)值類型(不要求數(shù)據(jù)類型嚴(yán)格相同),則只要兩個變量的值相等,就返回true;對于兩個引用類型變量,必須指向同一個對象,==才會返回true。
java中使用new String("hello")時,jvm會先使用常量池來管理"hello"常量,再調(diào)用String類的構(gòu)造器創(chuàng)建一個新的String對象,新創(chuàng)建的對象被保存在堆內(nèi)存中;而直接使用"hello"的字符串直接量,jvm會用常量池來管理這些字符串。故上述程序中str=="hello"返回結(jié)果為false
重載
方法重載是指在一個類中定義多個同名的方法,但要求每個方法具有不同的參數(shù)的類型或參數(shù)的個數(shù)。
原則如下:
一.方法名一定要相同。
二.方法的參數(shù)表必須不同,包括參數(shù)的類型或個數(shù),以此區(qū)分不同的方法體。
1.如果參數(shù)個數(shù)不同,就不管它的參數(shù)類型了!
2.如果參數(shù)個數(shù)相同,那么參數(shù)的類型或者參數(shù)的順序必須不同。
三.方法的返回類型、修飾符可以相同,也可不同。
Arraylist linklist
A. ArrayList是實現(xiàn)了基于動態(tài)數(shù)組的數(shù)據(jù)結(jié)構(gòu),LinkedList基于鏈表的數(shù)據(jù)結(jié)構(gòu)。 //正確,這里的所謂動態(tài)數(shù)組并不是那個“ 有多少元素就申請多少空間 ”的意思,通過查看源碼,可以發(fā)現(xiàn),這個動態(tài)數(shù)組是這樣實現(xiàn)的,如果沒指定數(shù)組大小,則申請默認(rèn)大小為10的數(shù)組,當(dāng)元素個數(shù)增加,數(shù)組無法存儲時,系統(tǒng)會另個申請一個長度為當(dāng)前長度1.5倍的數(shù)組,然后,把之前的數(shù)據(jù)拷貝到新建的數(shù)組。
B. 對于隨機(jī)訪問get和set,ArrayList覺得優(yōu)于LinkedList,因為LinkedList要移動指針。//正確,ArrayList是數(shù)組,所以,直接定位到相應(yīng)位置取元素,LinkedLIst是鏈表,所以需要從前往后遍歷。
C. 對于新增和刪除操作add和remove,LinedList比較占優(yōu)勢,因為ArrayList要移動數(shù)據(jù)。//正確,ArrayList的新增和刪除就是數(shù)組的新增和刪除,LinkedList與鏈表一致。
D. ArrayList的空間浪費主要體現(xiàn)在在list列表的結(jié)尾預(yù)留一定的容量空間,而LinkedList的空間花費則體現(xiàn)在它的每一個元素都需要消耗相當(dāng)?shù)目臻g。//正確,因為ArrayList空間的增長率為1.5倍,所以,最后很可能留下一部分空間是沒有用到的,因此,會造成浪費的情況。對于LInkedList的話,由于每個節(jié)點都需要額外的指針,所以,你懂的。
抽象類 最終類
抽象類和最終類都可以被聲明使用。
這里只是說“聲明”,并沒有說“實例化”;如果只是聲明是可以的,最常見的使用方式就是:
1、父類類型的引用指向子類的對象;
2、 接口類型的引用指向該接口的實現(xiàn)類的對象;
以上兩種使用方式也就是所謂的“向上轉(zhuǎn)型”。
ps:最終類就是被final修飾的類,最終方法就是被final修飾的方法。最終類不能被繼承,最終方法不能被重寫。
Collection Collections
Collection是單列集合的頂層接口,Map是雙列集合的頂層接口
Collections是一個集合的工具類,提供了排序、查找等操作集合的一些常用方法
servlet層級結(jié)構(gòu)和常用類
Java中有關(guān)servlet的層級結(jié)構(gòu)和常用的類的描述:
- GenericServlet類:抽象類,定義一個通用的、獨立于底層協(xié)議的Servlet。
- 大多數(shù)Servlet通過從GenericServlet或HttpServlet類進(jìn)行擴(kuò)展來實現(xiàn)
- ServletConfig接口定義了在Servlet初始化的過程中由Servlet容器傳遞給Servlet得配置信息對象
- HttpServletRequest接口擴(kuò)展ServletRequest接口,為HTTP Servlet提供HTTP請求信息
HttpServlet是GenericServlet的子類。
GenericServlet是個抽象類,必須給出子類才能實例化。它給 出了設(shè)計servlet的一些骨架,定義了servlet生命周期,還有一些得到名字、配置、初始化參數(shù)的方法,其設(shè)計的是和應(yīng)用層協(xié)議無關(guān)的,也就是說 你有可能用非http協(xié)議實現(xiàn)它。
HttpServlet是子類,當(dāng)然就具有GenericServlet的一切特性,還添加了doGet, doPost, doDelete, doPut, doTrace等方法對應(yīng)處理http協(xié)議里的命令的請求響應(yīng)過程。
一般沒有特殊需要,自己寫的Servlet都擴(kuò)展HttpServlet 。
Ant 與 Maven
Ant和Maven都是基于Java的構(gòu)建(build)工具。理論上來說,有些類似于(Unix)C中的make ,但沒有make的缺陷。Ant是軟件構(gòu)建工具,Maven的定位是軟件項目管理和理解工具。
Ant特點 ?
沒有一個約定的目錄結(jié)構(gòu) ?必須明確讓ant做什么,什么時候做,然后編譯,打包 ?沒有生命周期,必須定義目標(biāo)及其實現(xiàn)的任務(wù)序列 ?沒有集成依賴管理
Maven特點
?擁有約定,知道你的代碼在哪里,放到哪里去 ?擁有一個生命周期,例如執(zhí)行 mvn install 就可以自動執(zhí)行編譯,測試,打包等構(gòu)建過程 ?只需要定義一個pom.xml,然后把源碼放到默認(rèn)的目錄,Maven幫你處理其他事情 ?擁有依賴管理,倉庫管理
java運(yùn)行時的數(shù)據(jù)區(qū)
Java運(yùn)行時的數(shù)據(jù)區(qū)包括:(其中前兩個是線程共享的)
1.方法區(qū)(Method Area) 存儲已被虛擬機(jī)加載的類信息、常量、靜態(tài)變量、即時編譯器編譯后的代碼等數(shù)據(jù)
2.堆(Heap) 存放對象實例,幾乎所有對象實例都在這里分配內(nèi)存
3.虛擬機(jī)棧(VM Stack) 描述的是Java方法執(zhí)行的內(nèi)存模型:每個方法在執(zhí)行的同時會創(chuàng)建一個Stack Frame(方法運(yùn)行時的基礎(chǔ)數(shù)據(jù)結(jié)構(gòu))用于存儲局部變量表、操作數(shù)棧、動態(tài)連接、方法出口等信息
4.本地方法棧(Native Method Stack) 與虛擬機(jī)棧了類似,不過則為虛擬機(jī)使用的到的Native方法服務(wù)。(有的虛擬機(jī)譬如Sun HotSpot虛擬機(jī)直接把本地方法棧和虛擬機(jī)棧合二為一)
5.程序計數(shù)器(Program Counter Register) 可看作當(dāng)前線程所執(zhí)行的字節(jié)碼的行號的標(biāo)識器
Object Condition Thread線程控制方法(wait notify notifyAll)
wait()、notify()和notifyAll()是 Object類 中的方法
從這三個方法的文字描述可以知道以下幾點信息:
1)wait()、notify()和notifyAll()方法是本地方法,并且為final方法,無法被重寫。
2)調(diào)用某個對象的wait()方法能讓當(dāng)前線程阻塞,并且當(dāng)前線程必須擁有此對象的monitor(即鎖)
3)調(diào)用某個對象的notify()方法能夠喚醒一個正在等待這個對象的monitor的線程,如果有多個線程都在等待這個對象的monitor,則只能喚醒其中一個線程;
4)調(diào)用notifyAll()方法能夠喚醒所有正在等待這個對象的monitor的線程;
有同學(xué)可能會有疑問:為何這三個不是Thread類聲明中的方法,而是Object類中聲明的方法
(當(dāng)然由于Thread類繼承了Object類,所以Thread也可以調(diào)用者三個方法)?其實這個問
題很簡單,由于每個對象都擁有monitor(即鎖),所以讓當(dāng)前線程等待某個對象的鎖,當(dāng)然
應(yīng)該通過這個對象來操作了。而不是用當(dāng)前線程來操作,因為當(dāng)前線程可能會等待多個線程
的鎖,如果通過線程來操作,就非常復(fù)雜了。
上面已經(jīng)提到,如果調(diào)用某個對象的wait()方法,當(dāng)前線程必須擁有這個對象的monitor(即
鎖),因此調(diào)用wait()方法必須在同步塊或者同步方法中進(jìn)行(synchronized塊或者
synchronized方法)。
調(diào)用某個對象的wait()方法,相當(dāng)于讓當(dāng)前線程交出此對象的monitor,然后進(jìn)入等待狀態(tài),
等待后續(xù)再次獲得此對象的鎖(Thread類中的sleep方法使當(dāng)前線程暫停執(zhí)行一段時間,從
而讓其他線程有機(jī)會繼續(xù)執(zhí)行,但它并不釋放對象鎖);
notify()方法能夠喚醒一個正在等待該對象的monitor的線程,當(dāng)有多個線程都在等待該對象
的monitor的話,則只能喚醒其中一個線程,具體喚醒哪個線程則不得而知。
同樣地,調(diào)用某個對象的notify()方法,當(dāng)前線程也必須擁有這個對象的monitor,因此調(diào)用
notify()方法必須在同步塊或者同步方法中進(jìn)行(synchronized塊或者synchronized方法)。
nofityAll()方法能夠喚醒所有正在等待該對象的monitor的線程,這一點與notify()方法是不同的。Condition是在java 1.5中才出現(xiàn)的,它用來替代傳統(tǒng)的Object的wait()、notify()實現(xiàn)線程間的協(xié)作,相比使用Object的wait()、notify(),使用Condition的await()、signal()這種方式實現(xiàn)線程間協(xié)作更加安全和高效。因此通常來說比較推薦使用Condition,阻塞隊列實際上是使用了Condition來模擬線程間協(xié)作。
Condition是個接口,基本的方法就是await()和signal()方法;
Condition依賴于Lock接口,生成一個Condition的基本代碼是lock.newCondition()
調(diào)用Condition的await()和signal()方法,都必須在lock保護(hù)之內(nèi),就是說必須在lock.lock()和lock.unlock之間才可以使用Conditon中的await()對應(yīng)Object的wait(); Condition中的signal()對應(yīng)Object的notify(); Condition中的signalAll()對應(yīng)Object的notifyAll()。Thread類對線程執(zhí)行控制的方法是sleep。
forward 和 redirect的區(qū)別
- 從地址欄顯示來說
forward是服務(wù)器請求資源,服務(wù)器直接訪問目標(biāo)地址的URL,把那個URL的響應(yīng)內(nèi)容讀取過來,然后把這些內(nèi)容再發(fā)給瀏覽器.瀏覽器根本不知道服務(wù)器發(fā)送的內(nèi)容從哪里來的,所以它的地址欄還是原來的地址.
redirect是服務(wù)端根據(jù)邏輯,發(fā)送一個狀態(tài)碼,告訴瀏覽器重新去請求那個地址.所以地址欄顯示的是新的URL. - 從數(shù)據(jù)共享來說
forward:轉(zhuǎn)發(fā)頁面和轉(zhuǎn)發(fā)到的頁面可以共享request里面的數(shù)據(jù).
redirect:不能共享數(shù)據(jù). - 從運(yùn)用地方來說
forward:一般用于用戶登陸的時候,根據(jù)角色轉(zhuǎn)發(fā)到相應(yīng)的模塊.
redirect:一般用于用戶注銷登陸時返回主頁面和跳轉(zhuǎn)到其它的網(wǎng)站等. - 從效率來說
forward:高.
redirect:低.
本質(zhì)區(qū)別
- 解釋一
一句話,轉(zhuǎn)發(fā)是服務(wù)器行為,重定向是客戶端行為。為什么這樣說呢,這就要看兩個動作的工作流程:
轉(zhuǎn)發(fā)過程:
客戶瀏覽器發(fā)送http請求----》web服務(wù)器接受此請求--》調(diào)用內(nèi)部的一個方法在容器內(nèi)部完成請求處理和轉(zhuǎn)發(fā)動作----》將目標(biāo)資源 發(fā)送給客戶;在這里,轉(zhuǎn)發(fā)的路徑必須是同一個web容器下的url,其不能轉(zhuǎn)向到其他的web路徑上去,中間傳遞的是自己的容器內(nèi)的request。在客 戶瀏覽器路徑欄顯示的仍然是其第一次訪問的路徑,也就是說客戶是感覺不到服務(wù)器做了轉(zhuǎn)發(fā)的。轉(zhuǎn)發(fā)行為是瀏覽器只做了一次訪問請求。
重定向過程:
客戶瀏覽器發(fā)送http請求----》web服務(wù)器接受后發(fā)送302狀態(tài)碼響應(yīng)及對應(yīng)新的location給客戶瀏覽器--》客戶瀏覽器發(fā)現(xiàn) 是302響應(yīng),則自動再發(fā)送一個新的http請求,請求url是新的location地址----》服務(wù)器根據(jù)此請求尋找資源并發(fā)送給客戶。在這里 location可以重定向到任意URL,既然是瀏覽器重新發(fā)出了請求,則就沒有什么request傳遞的概念了。在客戶瀏覽器路徑欄顯示的是其重定向的 路徑,客戶可以觀察到地址的變化的。重定向行為是瀏覽器做了至少兩次的訪問請求的。
- 解釋二
重定向,其實是兩次request, 第一次,客戶端request A,服務(wù)器響應(yīng),并response回來,告訴瀏覽器,你應(yīng)該去B。這個時候IE可以看到地址變了,而且歷史的回退按鈕也亮了。重定向可以訪問自己web應(yīng)用以外的資源。在重定向的過程中,傳輸?shù)男畔粊G失。 - 解釋三
假設(shè)你去辦理某個執(zhí)照,
重定向:
你先去了A局,A局的人說:“這個事情不歸我們管,去B局”,然后,你就從A退了出來,自己乘車去了B局。
轉(zhuǎn)發(fā):
你先去了A局,A局看了以后,知道這個事情其實應(yīng)該B局來管,但是他沒有把你退回來,而是讓你坐一會兒,自己到后面辦公室聯(lián)系了B的人,讓他們辦好后,送了過來。
AOP和OOP差別
AOP和OOP都是一套方法論,也可以說成設(shè)計模式、思維方式、理論規(guī)則等等。
AOP不能替代OOP,OOP是obejct abstraction,而AOP是concern abstraction,前者主要是對對象的抽象,諸如抽象出某類業(yè)務(wù)對象的公用接口、報表業(yè)務(wù)對象的邏輯封裝,更注重于某些共同對象共有行為的抽象,如報表模塊中專門需要報表業(yè)務(wù)邏輯的封裝,其他模塊中需要其他的邏輯抽象 ,而AOP則是對分散在各個模塊中的共同行為的抽象,即關(guān)注點抽象。一些系統(tǒng)級的問題或者思考起來總與業(yè)務(wù)無關(guān)又多處存在的功能,可使用AOP,如異常信息處理機(jī)制統(tǒng)一將自定義的異常信息寫入響應(yīng)流進(jìn)而到前臺展示、行為日志記錄用戶操作過的方法等,這些東西用OOP來做,就是一個良好的接口、各處調(diào)用,但有時候會發(fā)現(xiàn)太多模塊調(diào)用的邏輯大都一致、并且與核心業(yè)務(wù)無大關(guān)系,可以獨立開來,讓處理核心業(yè)務(wù)的人專注于核心業(yè)務(wù)的處理,關(guān)注分離了,自然代碼更獨立、更易調(diào)試分析、更具好維護(hù)。
核心業(yè)務(wù)還是要OOP來發(fā)揮作用,與AOP的側(cè)重點不一樣,前者有種縱向抽象的感覺,后者則是橫向抽象的感覺, AOP只是OOP的補(bǔ)充,無替代關(guān)系。
ArrayList構(gòu)造函數(shù)
ArrayList的構(gòu)造函數(shù)總共有三個:
(1)ArrayList()構(gòu)造一個初始容量為 10 的空列表。
(2)ArrayList(Collection<? extends E> c)構(gòu)造一個包含指定 collection 的元素的列表,這些元素是按照該 collection 的迭代器返回它們的順序排列的。
(3)ArrayList(int initialCapacity)構(gòu)造一個具有指定初始容量的空列表。
異常類

都是Throwable的子類:
1.Exception(異常) :是程序本身可以處理的異常。
2.Error(錯誤): 是程序無法處理的錯誤。這些錯誤表示故障發(fā)生于虛擬機(jī)自身、或者發(fā)生在虛擬機(jī)試圖執(zhí)行應(yīng)用時,一般不需要程序處理。
3.檢查異常(編譯器要求必須處置的異常) : 除了Error,RuntimeException及其子類以外,其他的Exception類及其子類都屬于可查異常。這種異常的特點是Java編譯器會檢查它,也就是說,當(dāng)程序中可能出現(xiàn)這類異常,要么用try-catch語句捕獲它,要么用throws子句聲明拋出它,否則編譯不會通過。
4.非檢查異常(編譯器不要求處置的異常): 包括運(yùn)行時異常(RuntimeException與其子類)和錯誤(Error)。
數(shù)據(jù)庫
數(shù)據(jù)庫讀取
一、臟讀、不可重復(fù)讀、幻讀
1、臟讀:臟讀就是指當(dāng)一個事務(wù)正在訪問數(shù)據(jù),并且對數(shù)據(jù)進(jìn)行了修改,而這種修改還沒有提交到數(shù)據(jù)庫中,這時,另外一個事務(wù)也訪問這個數(shù)據(jù),然后使用了這個數(shù)據(jù)。
例如:
張三的工資為5000,事務(wù)A中把他的工資改為8000,但事務(wù)A尚未提交。
與此同時,
事務(wù)B正在讀取張三的工資,讀取到張三的工資為8000。
隨后,
事務(wù)A發(fā)生異常,而回滾了事務(wù)。張三的工資又回滾為5000。
最后,
事務(wù)B讀取到的張三工資為8000的數(shù)據(jù)即為臟數(shù)據(jù),事務(wù)B做了一次臟讀。
2、不可重復(fù)讀:是指在一個事務(wù)內(nèi),多次讀同一數(shù)據(jù)。在這個事務(wù)還沒有結(jié)束時,另外一個事務(wù)也訪問該同一數(shù)據(jù)。那么,在第一個事務(wù)中的兩次讀數(shù)據(jù)之間,由于第二個事務(wù)的修改,那么第一個事務(wù)兩次讀到的的數(shù)據(jù)可能是不一樣的。這樣就發(fā)生了在一個事務(wù)內(nèi)兩次讀到的數(shù)據(jù)是不一樣的,因此稱為是不可重復(fù)讀。
例如:
在事務(wù)A中,讀取到張三的工資為5000,操作沒有完成,事務(wù)還沒提交。
與此同時,
事務(wù)B把張三的工資改為8000,并提交了事務(wù)。
隨后,
在事務(wù)A中,再次讀取張三的工資,此時工資變?yōu)?000。在一個事務(wù)中前后兩次讀取的結(jié)果并不致,導(dǎo)致了不可重復(fù)讀。
3、幻讀:是指當(dāng)事務(wù)不是獨立執(zhí)行時發(fā)生的一種現(xiàn)象,例如第一個事務(wù)對一個表中的數(shù)據(jù)進(jìn)行了修改,這種修改涉及到表中的全部數(shù)據(jù)行。同時,第二個事務(wù)也修改這個表中的數(shù)據(jù),這種修改是向表中插入一行新數(shù)據(jù)。那么,以后就會發(fā)生操作第一個事務(wù)的用戶發(fā)現(xiàn)表中還有沒有修改的數(shù)據(jù)行,就好象發(fā)生了幻覺一樣。
例如:
目前工資為5000的員工有10人,事務(wù)A讀取所有工資為5000的人數(shù)為10人。
此時,
事務(wù)B插入一條工資也為5000的記錄。
這是,事務(wù)A再次讀取工資為5000的員工,記錄為11人。此時產(chǎn)生了幻讀。
4、提醒
不可重復(fù)讀的重點是修改:
同樣的條件,你讀取過的數(shù)據(jù),再次讀取出來發(fā)現(xiàn)值不一樣了
幻讀的重點在于新增或者刪除:
同樣的條件,第 1 次和第 2 次讀出來的記錄數(shù)不一樣