JAVA經(jīng)典面試題目答案_第1頁(yè)
JAVA經(jīng)典面試題目答案_第2頁(yè)
JAVA經(jīng)典面試題目答案_第3頁(yè)
JAVA經(jīng)典面試題目答案_第4頁(yè)
JAVA經(jīng)典面試題目答案_第5頁(yè)
已閱讀5頁(yè),還剩22頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1forword和redirect的區(qū)別以及各自的應(yīng)用場(chǎng)景直接轉(zhuǎn)發(fā)方式(Forward),客戶端和瀏覽器只發(fā)出一次請(qǐng)求,Servlet、HTML、JSP或其它信息資源,由第二個(gè)信息資源響應(yīng)該請(qǐng)求,在請(qǐng)求對(duì)象request中,保存的對(duì)象對(duì)于一個(gè)每個(gè)信息資源是共享的。場(chǎng)景:Web應(yīng)用程序大多會(huì)有一個(gè)控制器。由控制器來(lái)控制請(qǐng)求應(yīng)該轉(zhuǎn)發(fā)給那個(gè)信息資源。然后由這些信息資源處理請(qǐng)求,處理完以后還可能轉(zhuǎn)發(fā)給另外的信息資源來(lái)返回給用戶,這個(gè)過(guò)程就是經(jīng)典的MVC模式。間接轉(zhuǎn)發(fā)方式(Redirect)實(shí)際是兩次HTTP請(qǐng)求,服務(wù)器端在響應(yīng)第一次請(qǐng)求的時(shí)候,讓瀏覽器再向另外一個(gè)URL發(fā)出請(qǐng)求,從而達(dá)到轉(zhuǎn)發(fā)的目的。場(chǎng)景:一般用于避免用戶的非正常訪問(wèn)。例如:用戶在沒(méi)有登錄的情況下訪問(wèn)后臺(tái)資源,Servlet可以將該HTTP請(qǐng)求重定向到登錄頁(yè)面,讓用戶登錄以后再訪問(wèn)。區(qū)別Forward和Redirect代表了兩種請(qǐng)求轉(zhuǎn)發(fā)方式:直接轉(zhuǎn)發(fā)和間接轉(zhuǎn)發(fā)。對(duì)應(yīng)到代碼里,分別是RequestDispatcher類的forward()方法和HttpServletRequest類的sendRedirect()方法。對(duì)于間接方式,服務(wù)器端在響應(yīng)第一次請(qǐng)求的時(shí)候,讓瀏覽器再向另外一個(gè)URL發(fā)出請(qǐng)求,從而達(dá)到轉(zhuǎn)發(fā)的目的。它本質(zhì)上是兩次HTTP請(qǐng)求,對(duì)應(yīng)兩個(gè)request對(duì)象。對(duì)于直接方式,客戶端瀏覽器只發(fā)出一次請(qǐng)求,Servlet把請(qǐng)求轉(zhuǎn)發(fā)給Servlet、HTML、JSP或其它信息資源,由第2個(gè)信息資源響應(yīng)該請(qǐng)求,兩個(gè)信息資源共享同一個(gè)request對(duì)象。2Spring套餐描述Spring容器初始化過(guò)程Ioc容器的初始化是由refresh()方法來(lái)啟動(dòng)的,這個(gè)方法標(biāo)志著Ioc容器的正式啟動(dòng)。具體來(lái)說(shuō)這個(gè)啟動(dòng)過(guò)程包括三個(gè)基本過(guò)程:1>.BeanDifinition的Resource定位指的是BeanDifinition的資源定位,它由ResourceLoader通過(guò)統(tǒng)一的Resource接口來(lái)完成,這些 BeanDifinition的存在形式,比如,在文件系統(tǒng)中的Bean定義信息可以使用FileSystemResource來(lái)進(jìn)行 抽象,在類路徑中的Bean定義信息可以使用ClassPathResource。2>.BeanDifinition的載入與解析把用戶定義好的Bean表示成Ioc容器內(nèi)部的數(shù)據(jù)結(jié)構(gòu),而這個(gè)容器內(nèi)部的數(shù)據(jù)結(jié)構(gòu)就是BeanDifinition。具體來(lái)說(shuō),BeanDifinition實(shí)際上就是POJO對(duì)象在IOC容器中的抽象,通過(guò)這個(gè)BeanDifinition定義的數(shù)據(jù)結(jié)構(gòu),使IOC容器能夠方便的對(duì)POJO對(duì)象也就是Bean進(jìn)行管理。3>.BeanDifinition在Ioc容器中的注冊(cè)這個(gè)操作是通過(guò)調(diào)用BeanDifinitionRegistry借口來(lái)實(shí)現(xiàn)的。這個(gè)注冊(cè)過(guò)程把載入過(guò)程中解析得到的BeanDifinition向Ioc容器進(jìn)行注冊(cè)。在閱讀源碼中可知,在IOC容器內(nèi)部將BeanDifinition注入到一個(gè)HashMap中去,Ioc容器就是通過(guò)這個(gè)HashMap來(lái)持有這些BeanDifinition數(shù)據(jù)的。2、為什么要進(jìn)行事務(wù)管理,Spring是如何進(jìn)行事務(wù)管理支持的Spring事務(wù)是

Spring

AOP

的一種實(shí)現(xiàn),本質(zhì)是基于動(dòng)態(tài)代理技術(shù)對(duì)所需要管理的bean進(jìn)行加載,并在方法調(diào)用前后加入合適的事務(wù)管理代碼實(shí)現(xiàn)事務(wù)的提交與產(chǎn)生異常時(shí)回滾。spring的事務(wù)聲明有兩種方式,編程式和聲明式。spring主要是通過(guò)“聲明式事務(wù)”的方式對(duì)事務(wù)進(jìn)行管理,即在配置文件中進(jìn)行聲明,通過(guò)AOP將事務(wù)切面切入程序,最大的好處是大大減少了代碼量。Spring如何配置數(shù)據(jù)庫(kù)驅(qū)動(dòng)<bean

id="dataSource"class="mons.dbcp.BasicDataSource"><property

name="driverClassName"value="com.mysql.jdbc.Driver"></property><property

name="url"value="jdbc:mysql://localhost:3306/test"></property><property

name="username"

value="root"></property><property

name="password"

value="admin"></property></bean>解釋一下DI依賴注入和IOC控制反轉(zhuǎn),Spring中是如何做的

IOC(控制反轉(zhuǎn))是spring的核心,由Spring管理創(chuàng)建響應(yīng)的對(duì)象,即由IOC容器幫對(duì)象管理響應(yīng)的依賴關(guān)系,并在運(yùn)行時(shí)將對(duì)象注入,而不是通過(guò)傳統(tǒng)的new來(lái)主動(dòng)創(chuàng)建對(duì)象。而DI則是實(shí)現(xiàn)IOC注入關(guān)聯(lián)對(duì)象的方式,有三種:set方法注入、構(gòu)造函數(shù)注入和參數(shù) (常量)注入。控制反轉(zhuǎn)和依賴注入是同一個(gè)東西在不同的角度進(jìn)行分析,在實(shí)際項(xiàng)目開(kāi)發(fā)中我們需要把bean都放在spring中管理,告訴spring不同bean之間的依賴關(guān)系,而具體的創(chuàng)建注入都是由spring容器幫我們實(shí)現(xiàn)的,即通過(guò)控制反轉(zhuǎn)和依賴注入,本質(zhì)實(shí)現(xiàn)都是基于反射機(jī)制來(lái)實(shí)現(xiàn)的。Spring中的BeanFactory與ApplicationContext的作用有那些BeanFactory提供了配制框架及基本功能,負(fù)責(zé)對(duì)象實(shí)例化、定位、配置應(yīng)用程序中的對(duì)象及建立這些對(duì)象間的依賴。而ApplicationContext則增加了更多支持企業(yè)核心內(nèi)容的功 能。比如更易與SpringAOP集成、消息資源處理(國(guó)際化處理)、事件傳遞及各種不同應(yīng)用層的context實(shí)現(xiàn)(如針對(duì)web應(yīng)用的WebApplicationContext)。Spring中的核心類有那些,各有什么作用BeanFactory:產(chǎn)生一個(gè)新的實(shí)例,可以實(shí)現(xiàn)單例模式BeanWrapper:提供統(tǒng)一的get及set方法ApplicationContext:提供框架的實(shí)現(xiàn),包括BeanFactory的所有功能什么是aop,aop的作用是什么面向切面編程,或AOP允許程序員模塊化橫向業(yè)務(wù)邏輯,將系統(tǒng)中非核心的業(yè)務(wù)提取出來(lái),進(jìn)行單獨(dú)處理,解決系統(tǒng)代碼耦合度過(guò)高的問(wèn)題。使代碼重用度高、易于維護(hù)。例如權(quán)限認(rèn)證、日志管理和事務(wù)管理。springbean的創(chuàng)建方式和生命周期三種創(chuàng)建方式:①構(gòu)造器注入創(chuàng)建②工廠方法(靜態(tài)工廠)③工廠類(實(shí)例工廠)1)Bean實(shí)例化:Bean的默認(rèn)構(gòu)造函數(shù)。2)Bean的初始化:Init()方法中可以進(jìn)行初始化。3)Bean的使用:getBean()方法可以獲取當(dāng)前的Bean,從而做相對(duì)應(yīng)的業(yè)務(wù)操作。4)Bean的銷毀:destroy()方法執(zhí)行bean的銷毀。9、spring與springMVC的區(qū)別Spring是一個(gè)輕量級(jí)的控制反轉(zhuǎn)(IoC)和面向切面(AOP)的容器框架。springmvc類似于struts的一個(gè)MVC開(kāi)框架,其實(shí)都是屬于spring,springmvc需要有spring的架包作為支撐才能跑起來(lái)。3HashMap(或者Hashtable/ArrayList。。。)的數(shù)據(jù)結(jié)構(gòu)(實(shí)現(xiàn)方式)HashMap:key:value底層使用數(shù)組(table)+鏈表(entry)結(jié)構(gòu),通過(guò)key進(jìn)行二次hash計(jì)算出的hashCode%table.length確定對(duì)應(yīng)的數(shù)組下標(biāo)的位置存放value。HashTable:key:valueHashtable

繼承于Dictionary,實(shí)現(xiàn)了Map、Cloneable、Java.io.Serializable接口,Hashtable的函數(shù)都是同步的,這意味著它是線程安全的。它的key、value都不可以為null。此外,Hashtable中的映射不是有序的。底層使用數(shù)組(table)+鏈表(entry)結(jié)構(gòu),hash計(jì)算方法是直接使用key的hashcode對(duì)table數(shù)組的長(zhǎng)度直接進(jìn)行取模。ArrayList:線性鏈表(線程不安全),最核心的兩個(gè)成員變量是存儲(chǔ)數(shù)據(jù)的數(shù)組和數(shù)組大小。a.ArrayList是通過(guò)將底層Object數(shù)組復(fù)制的方式(System.arraycopy方法)來(lái)處理數(shù)組的增長(zhǎng);

b.當(dāng)ArrayList的容量不足時(shí),其擴(kuò)充容量的方式:先將容量擴(kuò)充至當(dāng)前容量的1.5倍,若還不夠,則將容量擴(kuò)充至當(dāng)前需要的數(shù)量。4GET與POST的區(qū)別,分別用在什么場(chǎng)景合適?GET一般用于獲取/查詢資源信息,而POST一般用于更新資源信息。get是把參數(shù)數(shù)據(jù)隊(duì)列加到提交表單的ACTION屬性所指的URL中,值和表單內(nèi)各個(gè)字段一一對(duì)應(yīng),在URL中可以看到。post是通過(guò)HTTPpost機(jī)制,將表單內(nèi)各個(gè)字段與其內(nèi)容放置在HTMLHEADER內(nèi)一起傳送到ACTION屬性所指的URL地址。用戶看不到這個(gè)過(guò)程。對(duì)于get方式,服務(wù)器端用doGet獲取變量的值,對(duì)于post方式,服務(wù)器端用doPost獲取提交的數(shù)據(jù)。get傳送的數(shù)據(jù)量較小,不能大于2KB。post傳送的數(shù)據(jù)量較大,一般被默認(rèn)為不受限制。get安全性非常低,post安全性較高。但是執(zhí)行效率卻比Post方法好。5什么是單例模式,有哪些實(shí)現(xiàn)方式,寫出其中兩種Singleton是一種創(chuàng)建型模式,指某個(gè)類采用Singleton模式,則在這個(gè)類被創(chuàng)建后,只可能產(chǎn)生一個(gè)實(shí)例供外部訪問(wèn),并且提供一個(gè)全局的訪問(wèn)點(diǎn)。第一種(懶漢,線程不安全):略(參考第二種)第二種(懶漢,線程安全):

public

class

Singleton

{

private

static

Singleton

instance;

private

Singleton

(){}

public

static

synchronized

Singleton

getInstance()

{

if

(instance

==

null)

{

instance

=

new

Singleton();

}

return

instance;

}

}

這種寫法能夠在多線程中很好的工作,而且看起來(lái)它也具備很好的lazyloading,但是,遺憾的是,效率很低,99%情況下不需要同步。第三種(餓漢):

public

class

Singleton

{

private

static

Singleton

instance

=

new

Singleton();

private

Singleton

(){}

public

static

Singleton

getInstance()

{

return

instance;

}

}

第四種(靜態(tài)內(nèi)部類):

public

class

Singleton

{

private

static

class

SingletonHolder

{

private

static

final

Singleton

INSTANCE

=

new

Singleton();

}

private

Singleton

(){}

public

static

final

Singleton

getInstance()

{

return

SingletonHolder.INSTANCE;

}

}

這種方式同樣利用了classloder的機(jī)制來(lái)保證初始化instance時(shí)只有一個(gè)線程,它跟第三種方式不同的是(很細(xì)微的差別):第三種是只要Singleton類被裝載了,那么instance就會(huì)被實(shí)例化(沒(méi)有達(dá)到lazyloading效果),而這種方式是Singleton類被裝載了,instance不一定被初始化。因?yàn)镾ingletonHolder類沒(méi)有被主動(dòng)使用,只有顯示通過(guò)調(diào)用getInstance方法時(shí),才會(huì)顯示裝載SingletonHolder類,從而實(shí)例化instance。想象一下,如果實(shí)例化instance很消耗資源,我想讓他延遲加載,另外一方面,我不希望在Singleton類加載時(shí)就實(shí)例化,因?yàn)槲也荒艽_保Singleton類還可能在其他的地方被主動(dòng)使用從而被加載,那么這個(gè)時(shí)候?qū)嵗痠nstance顯然是不合適的。這個(gè)時(shí)候,這種方式相比第三方式就顯得很合理。第五種(枚舉):

public

enum

Singleton

{

INSTANCE;

public

void

instance()

{

}

}

這種方式是EffectiveJava作者JoshBloch提倡的方式,它不僅能避免多線程同步問(wèn)題,而且還能防止反序列化重新創(chuàng)建新的對(duì)象,可謂是很堅(jiān)強(qiáng)的壁壘啊,不過(guò),個(gè)人認(rèn)為由于1.5中才加入enum特性,用這種方式寫不免讓人感覺(jué)生疏,在實(shí)際工作中,我也很少看見(jiàn)有人這么寫過(guò)。第六種(雙重校驗(yàn)鎖):

public

class

Singleton

{

private

volatile

static

Singleton

singleton;

private

Singleton

(){}

public

static

Singleton

getSingleton()

{

if

(singleton

==

null)

{

synchronized

(Singleton.class)

{

if

(singleton

==

null)

{

singleton

=

new

Singleton();

}

}

}

return

singleton;

}

}

這個(gè)是第二種方式的升級(jí)版,俗稱雙重檢查鎖定,但僅在JDK1.5之后有效。6常見(jiàn)的設(shè)計(jì)模式有哪些,并寫出簡(jiǎn)單的示例代碼單例模式(略):工廠模式(普通、多方法和靜態(tài)工廠方法、抽象工廠):該模式主要功能是統(tǒng)一提供實(shí)例對(duì)象的引用建造者模式:一個(gè)對(duì)象的組成可能有很多其他的對(duì)象一起組成的,比如說(shuō),一個(gè)對(duì)象的實(shí)現(xiàn)非常復(fù)雜,有很多的屬性,而這些屬性又是其他對(duì)象的引用,可能這些對(duì)象的引用又包括很多的對(duì)象引用。封裝這些復(fù)雜性,就可以使用建造模式。策略模式:這個(gè)模式是將行為的抽象,即當(dāng)有幾個(gè)類有相似的方法,將其中通用的部分都提取出來(lái),從而使擴(kuò)展更容易。門面模式:這個(gè)模式個(gè)人感覺(jué)像是Service層的一個(gè)翻版。比如Dao我們定義了很多持久化方法,我們通過(guò)Service層將Dao的原子方法組成業(yè)務(wù)邏輯,再通過(guò)方法向上層提供服務(wù)。門面模式道理其實(shí)是一樣的。代理模式:其實(shí)每個(gè)模式名稱就表明了該模式的作用,代理模式就是多一個(gè)代理類出來(lái),替原對(duì)象進(jìn)行一些操作,比如我們?cè)谧夥孔拥臅r(shí)候回去找中介,為什么呢?因?yàn)槟銓?duì)該地區(qū)房屋的信息掌握的不夠全面,希望找一個(gè)更熟悉的人去幫你做,此處的代理就是這個(gè)意思。7原生JS的繼承是怎么實(shí)現(xiàn)的,都有哪幾種?①對(duì)象冒充functionParent(username){...}functionChild(username,password){//第一步:this.method是作為一個(gè)臨時(shí)的屬性,并且指向Parent所指向的對(duì)象,this.method=Parent;//第二步:執(zhí)行this.method方法,即執(zhí)行Parent所指向的對(duì)象函數(shù)this.method(username);//最關(guān)鍵的一行//第三步:銷毀this.method屬性,即此時(shí)Child就已經(jīng)擁有了Parent的所有屬性和方法deletethis.method;...}②call方法call方法是Function類中的方法call方法的第一個(gè)參數(shù)的值賦值給類(即方法)中出現(xiàn)的thiscall方法的第二個(gè)參數(shù)開(kāi)始依次賦值給類(即方法)所接受的參數(shù)functionParent(username){...}functionChild(username,password){Parent.call(this,username);...}③apply()方法方式

apply方法接受2個(gè)參數(shù),

A、第一個(gè)參數(shù)與call方法的第一個(gè)參數(shù)一樣,即賦值給類(即方法)中出現(xiàn)的this

B、第二個(gè)參數(shù)為數(shù)組類型,這個(gè)數(shù)組中的每個(gè)元素依次賦值給類(即方法)所接受的參數(shù)functionParent(username){...}functionChild(username,password){Parent.apply(this,newArray(username));...}④原型鏈方式,即子類通過(guò)prototype將所有在父類中通過(guò)prototype追加的屬性和方法都追加到Child,從而實(shí)現(xiàn)了繼承。functionPerson(){}Ptotype.hello="hello";Ptotype.sayHello=function(){alert(this.hello);}functionChild(){}

Ctotype=newPerson();//這行的作用是:將Parent中將所有通過(guò)prototype追加的屬性和方法都追加到Child,從而實(shí)現(xiàn)了繼承

Ctotype.world="world";

Ctotype.sayWorld=function(){alert(this.world);}⑤混合方式(略):混合了call方式、原型鏈方式8數(shù)據(jù)庫(kù)優(yōu)化方式有哪些?(下面是可能會(huì)連貫性問(wèn)到的問(wèn)題)MySQL和Oracle的區(qū)別,在什么情況下更適合?MySQL開(kāi)源免費(fèi),適合中小型應(yīng)用系統(tǒng),ORACLE龐大健全用于大型應(yīng)用系統(tǒng)和安全性要求較高的領(lǐng)域。使用細(xì)節(jié)也有些區(qū)別,例如:①mysql中組函數(shù)在select語(yǔ)句中可以隨意使用,但在oracle中如果查詢語(yǔ)句中有組函數(shù),那其他列名必須是組函數(shù)處理過(guò)的,或者是groupby子句中的列否則報(bào)錯(cuò)selectname,count(money)fromuser;這個(gè)放在mysql中沒(méi)有問(wèn)題在oracle中就有問(wèn)題了。②自動(dòng)增長(zhǎng)列的實(shí)現(xiàn)MYSQL有自動(dòng)增長(zhǎng)的數(shù)據(jù)類型,插入記錄時(shí)不用操作此字段,會(huì)自動(dòng)獲得數(shù)據(jù)值。ORACLE沒(méi)有自動(dòng)增長(zhǎng)的數(shù)據(jù)類型,需要建立一個(gè)自動(dòng)增長(zhǎng)的序列號(hào),插入記錄時(shí)要把序列號(hào)的下一個(gè)值賦于此字段。③單引號(hào)處理MYSQL里可以用雙引號(hào)包起字符串,ORACLE里只可以用單引號(hào)包起字符串。④分頁(yè)處理MYSQL使用limit即可,ORACLE必須使用三層子查詢結(jié)合ROWNUM實(shí)現(xiàn)⑤日期字段MYSQL日期字段分DATE和TIME兩種,ORACLE日期字段只有DATE,包含年月日時(shí)分秒信息,用當(dāng)前數(shù)據(jù)庫(kù)的系統(tǒng)時(shí)間為SYSDATE,精確到秒。⑥空字符串MYSQL的非空字段也有空的內(nèi)容,ORACLE里定義了非空字段就不容許有空的內(nèi)容。按MYSQL的NOTNULL來(lái)定義ORACLE表結(jié)構(gòu),導(dǎo)數(shù)據(jù)的時(shí)候會(huì)產(chǎn)生錯(cuò)誤。因此導(dǎo)數(shù)據(jù)時(shí)要對(duì)空字符進(jìn)行判斷,如果為NULL或空字符,需要把它改成一個(gè)空格的字符串。MySQL的性能方面你了解多少?比如一個(gè)正常的讀寫操作你覺(jué)得多少時(shí)間算是正常?服務(wù)器12核24線程,64G內(nèi)存,SATA盤的情況下:讀1.5~3W/s,寫4000~10000/s,TPS800~1500/s。,平均響應(yīng)10ms以內(nèi)正常。如果一張表的查詢速度慢了.你會(huì)從哪些方面去優(yōu)化?①慢查詢定位及改進(jìn):Show命令、慢查詢?nèi)罩尽xplain分析查詢、profiling分析②索引優(yōu)化合理建立索引、優(yōu)化索引相關(guān)的查詢SQL1>.

當(dāng)結(jié)果集只有一行數(shù)據(jù)時(shí)使用LIMIT12>.

避免SELECT*,始終指定你需要的列3>.

使用連接(JOIN)來(lái)代替子查詢(Sub-Queries)4>.

使用合理的字段屬性長(zhǎng)度5>.

盡可能的使用NOTNULL6>.

固定長(zhǎng)度的表會(huì)更快7>.

拆分大的DELETE

或INSERT

語(yǔ)句8>.

查詢的列越小越快有些where條件會(huì)導(dǎo)致索引無(wú)效:?

where子句的查詢條件里有!=,MySQL將無(wú)法使用索引。?

where子句使用了Mysql函數(shù)的時(shí)候,索引將無(wú)效?

使用LIKE進(jìn)行搜索匹配的時(shí)候,模糊匹配不能放在前面,否則失效。如’%xxxx’③配置優(yōu)化MySQL服務(wù)器全局參數(shù)優(yōu)化④分表(橫、縱)減少單表的數(shù)據(jù)量及將常用列和不常用列、大列和小列分到不同的表。你做的三個(gè)項(xiàng)目里應(yīng)該都會(huì)用到權(quán)限設(shè)計(jì),你對(duì)表是怎么設(shè)計(jì)的?按照RBAC權(quán)限體系設(shè)計(jì)通用的權(quán)限管理表你們對(duì)表的設(shè)計(jì)怎么優(yōu)化?你覺(jué)得一張表裝多少行數(shù)據(jù)才會(huì)影響性能?數(shù)據(jù)類型:數(shù)字類型盡量不選擇double、float,盡量使用decimal、int和long類型。字符類型除非非得是TEXT,而要盡量使用CHAR和VARCHAR。日期時(shí)間類型盡量使用TIMESTAMP,對(duì)于精確到某天的日期類型盡量選擇DATE。盡量不使用BLOB/CLOB等LOB類型。適當(dāng)拆分:縱向分表適度冗余:空間換時(shí)間,將常用的需要連接查詢的數(shù)據(jù)放到主表。不過(guò),冗余的同時(shí)需要確保數(shù)據(jù)的一致性不會(huì)遭到破壞,確保更新的同時(shí)冗余字段也被更新。避免NULL:NULL類型比較特殊,SQL難優(yōu)化。雖然MySQLNULL類型和Oracle的NULL有差異,會(huì)進(jìn)入索引中,但如果是一個(gè)組合索引,那么這個(gè)NULL類型的字段會(huì)極大影響整個(gè)索引的效率。此外,NULL在索引中的處理也是特殊的,也會(huì)占用額外的存放空間。Mysql單表如果數(shù)據(jù)結(jié)構(gòu)簡(jiǎn)單2000W以下幾乎可以支撐,如果復(fù)雜的數(shù)據(jù)結(jié)構(gòu)500W既可以考慮分表,一般而言如果單表超過(guò)5000W,那么性能下降比較厲害。數(shù)據(jù)庫(kù)最基本,最常用的優(yōu)化是什么?表結(jié)構(gòu)優(yōu)化:正確的數(shù)據(jù)類型選擇、橫向/縱向分表、建立索引、刪除不必要的字段、適度冗余索引優(yōu)化:主鍵索引、獨(dú)立索引、聯(lián)合索引SQL語(yǔ)句優(yōu)化:盡量使用索引、盡量不對(duì)條件左邊的對(duì)象進(jìn)行運(yùn)算(包括函數(shù)運(yùn)算)、盡量不使用(!=/<>/not/or)等,可用union代替betweenand區(qū)間的取值、盡量使用exists代替in、使用like時(shí)盡量使用左匹配’key%’、一般表連接比子查詢更快存儲(chǔ)過(guò)程:利用存儲(chǔ)過(guò)程完成復(fù)雜且傳輸數(shù)據(jù)量大的邏輯。數(shù)據(jù)庫(kù)儲(chǔ)存引擎myisam/innodb的區(qū)別①M(fèi)yISAM不支持事務(wù),而InnoDB支持②InnoDB支持?jǐn)?shù)據(jù)行鎖定,MyISAM不支持行鎖定,只支持鎖定整個(gè)表③InnoDB支持外鍵,MyISAM不支持④InnoDB的主鍵范圍更大,最大是MyISAM的2倍。⑤InnoDB不支持全文索引和GIS數(shù)據(jù),而MyISAM支持。⑥MyISAM磁盤上是3個(gè)文件,.frm文件存儲(chǔ)表定義。數(shù)據(jù)文件的擴(kuò)展名為.MYD(MYData)。索引文件的擴(kuò)展名是.MYI(MYIndex)。InnoDB:所有的表都保存在同一個(gè)數(shù)據(jù)文件中(也可能是多個(gè)文件,或者是獨(dú)立的表空間文件),InnoDB表的大小只受限于操作系統(tǒng)文件的大小,一般為2GB。⑦M(jìn)yISAM:可被壓縮,存儲(chǔ)空間較小。支持三種不同的存儲(chǔ)格式:靜態(tài)表(默認(rèn),但是注意數(shù)據(jù)末尾不能有空格,會(huì)被去掉)、動(dòng)態(tài)表、壓縮表。InnoDB:需要更多的內(nèi)存和存儲(chǔ),它會(huì)在主內(nèi)存中建立其專用的緩沖池用于高速緩沖數(shù)據(jù)和索引。模糊查詢可以使用索引嗎?可以,但必須是左匹配’key%’索引的優(yōu)缺點(diǎn)優(yōu)點(diǎn):加快查詢效率和表連接的效率、減少分組和排序時(shí)間。缺點(diǎn):創(chuàng)建和更新索引需要耗費(fèi)時(shí)間,隨著數(shù)據(jù)量的增加而增加。索引會(huì)額外占用磁盤存儲(chǔ)空間。9java中4種修飾符分別為public、protect、default、private的區(qū)別修飾符同類同包子類公共private(私有)√默認(rèn)不寫√√protected(受保護(hù))√√√public(公共)√√√√主要是修飾類中的成員(字段、方法、構(gòu)造方法,內(nèi)部類); public默認(rèn)不寫:可以修飾類 privateprotedted:不能夠修飾類(外部類)10介紹一下Hibernate的緩存機(jī)制(或者問(wèn):二級(jí)緩存)Hibernate中的緩存分一級(jí)緩存和二級(jí)緩存。一級(jí)緩存就是Session級(jí)別的緩存,在事務(wù)范圍內(nèi)有效是,內(nèi)置的不能被卸載。二級(jí)緩存是SesionFactory級(jí)別的緩存,從應(yīng)用啟動(dòng)到應(yīng)用結(jié)束有效。是可選的,默認(rèn)沒(méi)有二級(jí)緩存,需要手動(dòng)開(kāi)啟。保存數(shù)據(jù)庫(kù)后,在內(nèi)存中保存一份,如果更新了數(shù)據(jù)庫(kù)就要同步更新。什么樣的數(shù)據(jù)適合存放到第二級(jí)緩存中?1)很少被修改的數(shù)據(jù)帖子的最后回復(fù)時(shí)間2)經(jīng)常被查詢的數(shù)據(jù)電商的地點(diǎn)2)不是很重要的數(shù)據(jù),允許出現(xiàn)偶爾并發(fā)的數(shù)據(jù)3)不會(huì)被并發(fā)訪問(wèn)的數(shù)據(jù)4)常量數(shù)據(jù)擴(kuò)展:hibernate的二級(jí)緩存默認(rèn)是不支持分布式緩存的。使用memcahe,redis等中央緩存來(lái)代替二級(jí)緩存。11說(shuō)說(shuō)你日常用到存儲(chǔ)過(guò)程與觸發(fā)器的場(chǎng)景觸發(fā)器:①實(shí)施復(fù)雜的安全性檢查(例如:禁止在非工作時(shí)間插入新員工數(shù)據(jù))②數(shù)據(jù)確認(rèn)或?qū)徲?jì)(例如:漲薪水,漲后的薪水不能小于漲前)③數(shù)據(jù)備份與同步(給更新員工信息后自動(dòng)備份新信息到備份表,或更新和員工相關(guān)連的冗余信息)存儲(chǔ)過(guò)程:定時(shí)性的ETL任務(wù)、報(bào)表統(tǒng)計(jì)函數(shù)及復(fù)雜業(yè)務(wù)(大量SQL及大數(shù)據(jù)量傳輸)可以采用存儲(chǔ)過(guò)程處理,另外涉及到算法或數(shù)據(jù)保密的情況也可以將保密邏輯及數(shù)據(jù)放到存儲(chǔ)過(guò)程中計(jì)算完成,程序只關(guān)注傳入?yún)?shù)及返回結(jié)果。12String,StringBuffer,StringBuilder的區(qū)別String(JDK1.0時(shí)代)

不可變字符序列StringBuffer(JDK1.0時(shí)代)

線程安全的可變字符序列StringBuilder(JDK1.5時(shí)代)

非線程安全的可變字符序列

①String和StringBuffer中的value[]都用于存儲(chǔ)字符序列,String中的是常量(final)數(shù)組,只能被賦值一次。StringBuffer中的value[]就是一個(gè)很普通的數(shù)組,而且可以通過(guò)append()方法將新字符串加入value[]末尾。②StringBuffer線程安全,而StringBuilder不是。③StringBuilder的效率比StringBuffer稍高,如果不考慮線程安全,StringBuilder應(yīng)該是首選。④StringBuffer對(duì)象的append效率要高于String對(duì)象的"+"連接操作。13int與Integer的區(qū)別①int是基本數(shù)據(jù)類型,Integer是其包裝類,注意是一個(gè)類。②Integer默認(rèn)值是null,而int默認(rèn)值是0;③聲明為Integer的變量需要實(shí)例化,而聲明為int的變量不需要實(shí)例化;④Integer是對(duì)象,用一個(gè)引用指向這個(gè)對(duì)象,而int是基本類型,直接存儲(chǔ)數(shù)值。14如何實(shí)現(xiàn)序列化,有什么意義,適用于那些場(chǎng)景?(追問(wèn):序列化接口在JVM是怎么實(shí)現(xiàn)的)序列化就是一種用來(lái)處理對(duì)象流的機(jī)制,所謂對(duì)象流也就是將對(duì)象的內(nèi)容進(jìn)行流化??梢詫?duì)流化后的對(duì)象進(jìn)行讀寫操作,也可將流化后的對(duì)象傳輸于網(wǎng)絡(luò)之間。序列化是為了解決對(duì)象流讀寫操作時(shí)可能引發(fā)的問(wèn)題(如果不進(jìn)行序列化可能會(huì)存在數(shù)據(jù)亂序的問(wèn)題)。要實(shí)現(xiàn)序列化,需要讓一個(gè)類實(shí)現(xiàn)Serializable接口,該接口是一個(gè)標(biāo)識(shí)性接口,標(biāo)注該類對(duì)象是可被序列化的,然后使用一個(gè)輸出流來(lái)構(gòu)造一個(gè)對(duì)象輸出流并通過(guò)writeObject(Object)方法就可以將實(shí)現(xiàn)對(duì)象寫出(即保存其狀態(tài));如果需要反序列化則可以用一個(gè)輸入流建立對(duì)象輸入流,然后通過(guò)readObject方法從流中讀取對(duì)象。序列化除了能夠?qū)崿F(xiàn)對(duì)象的持久化之外,還能夠用于對(duì)象的深度克隆。只有實(shí)現(xiàn)了serializable和Externalizable接口的類的對(duì)象才能被序列化

后者是前者的子類

實(shí)現(xiàn)這個(gè)借口的類完全由自身來(lái)控制序列化的行為,而僅僅實(shí)現(xiàn)前者的類可以采用默認(rèn)的序列化方式。實(shí)現(xiàn)這兩個(gè)接口標(biāo)志著對(duì)象可以被序列化了Java

串行化技術(shù)可以使你將一個(gè)對(duì)象的狀態(tài)寫入一個(gè)Byte

流里,并且可以從其它地方把該Byte

流里的數(shù)據(jù)讀出來(lái),重新構(gòu)造一個(gè)相同的對(duì)象。這種機(jī)制允許你將對(duì)象通過(guò)網(wǎng)絡(luò)進(jìn)行傳播,并可以隨時(shí)把對(duì)象持久化到數(shù)據(jù)庫(kù)、文件等系統(tǒng)里。Java的串行化機(jī)制是RMI、EJB等技術(shù)的技術(shù)基礎(chǔ)。用途:利用對(duì)象的串行化實(shí)現(xiàn)保存應(yīng)用程序的當(dāng)前工作狀態(tài),下次再啟動(dòng)的時(shí)候?qū)⒆詣?dòng)地恢復(fù)到上次執(zhí)行的狀態(tài)。15JDBC連接數(shù)據(jù)庫(kù)的步驟①加載數(shù)據(jù)庫(kù)驅(qū)動(dòng)Class.forName("com.mysql.jdbc.Driver");②創(chuàng)建數(shù)據(jù)庫(kù)連接Connectioncon=DriverManager.getConnection(url,username,password);③創(chuàng)建一個(gè)Statement1、執(zhí)行靜態(tài)SQL語(yǔ)句。通常通過(guò)Statement實(shí)例實(shí)現(xiàn)。2、執(zhí)行動(dòng)態(tài)SQL語(yǔ)句。通常通過(guò)PreparedStatement實(shí)例實(shí)現(xiàn)。3、執(zhí)行數(shù)據(jù)庫(kù)存儲(chǔ)過(guò)程。通常通過(guò)CallableStatement實(shí)例實(shí)現(xiàn)。④執(zhí)行SQL語(yǔ)句Statement接口提供了三種執(zhí)行SQL語(yǔ)句的方法:executeQuery、executeUpdate和execute方法。⑤處理結(jié)果ResultSet⑥關(guān)閉JDBC對(duì)象關(guān)閉記錄集ResultSet、聲明Statement和連接Connection16Mybatis中#{...}和${...}的區(qū)別#{}語(yǔ)法,MyBatis會(huì)產(chǎn)生PreparedStatement語(yǔ)句中,并且安全的設(shè)置PreparedStatement參數(shù),這個(gè)過(guò)程中MyBatis會(huì)進(jìn)行必要的安全檢查和轉(zhuǎn)義。${}是直接輸出變量的值,未經(jīng)過(guò)預(yù)編譯的,僅僅是取變量的值,是非安全的,存在sql注入.盡量使用#,但是${}在什么情況下使用呢?有時(shí)候可能需要直接插入一個(gè)不做任何修改的字符串到SQL語(yǔ)句中。這時(shí)候應(yīng)該使用${}語(yǔ)法。比如,動(dòng)態(tài)SQL中的字段名,如:ORDERBY${columnName}17什么是樂(lè)觀鎖,什么是悲觀鎖,兩者的區(qū)別是什么悲觀鎖:假定會(huì)發(fā)生并發(fā)沖突,屏蔽一切可能違反數(shù)據(jù)完整性的操作。開(kāi)始改變對(duì)象時(shí)鎖住直到完成所有操作后才釋放。樂(lè)觀鎖:假設(shè)不會(huì)發(fā)生并發(fā)沖突,只在提交操作時(shí)檢查是否違反數(shù)據(jù)完整性。修改過(guò)程不鎖定對(duì)象,直到提交所做更改時(shí)才將對(duì)象鎖住。讀取時(shí)不加鎖,因此可能會(huì)造成臟讀。樂(lè)觀鎖的實(shí)現(xiàn)方式①使用自增長(zhǎng)的整數(shù)表示數(shù)據(jù)版本號(hào)。更新時(shí)檢查版本號(hào)是否一致,比如數(shù)據(jù)庫(kù)中數(shù)據(jù)版本為6,更新提交時(shí)version=6+1,使用該version值(=7)與數(shù)據(jù)庫(kù)version+1(=7)作比較,如果相等,則可以更新,如果不等則有可能其他程序已更新該記錄,所以返回錯(cuò)誤。②使用時(shí)間戳來(lái)實(shí)現(xiàn).注:對(duì)于以上兩種方式,Hibernate自帶實(shí)現(xiàn)方式:在使用樂(lè)觀鎖的字段前加annotation:@Version,Hibernate在更新時(shí)自動(dòng)校驗(yàn)該字段。在實(shí)際生產(chǎn)環(huán)境里邊,如果并發(fā)量不大且不允許臟讀,可以使用悲觀鎖解決并發(fā)問(wèn)題;但如果系統(tǒng)的并發(fā)非常大的話,悲觀鎖定會(huì)帶來(lái)非常大的性能問(wèn)題,所以我們就要選擇樂(lè)觀鎖定的方法.18VectorArrayListLinkedList的區(qū)別這三者都實(shí)現(xiàn)了List接口.所有使用方式也很相似,主要區(qū)別在于因?yàn)閷?shí)現(xiàn)方式的不同,所以對(duì)不同的操作具有不同的效率。ArrayList是一個(gè)可改變大小的數(shù)組.當(dāng)更多的元素加入到ArrayList中時(shí),其大小將會(huì)動(dòng)態(tài)地增長(zhǎng).內(nèi)部的元素可以直接通過(guò)get與set方法進(jìn)行訪問(wèn),因?yàn)锳rrayList本質(zhì)上就是一個(gè)數(shù)組.LinkedList是一個(gè)雙鏈表,在添加和刪除元素時(shí)具有比ArrayList更好的性能.但在get與set方面弱于ArrayList.當(dāng)然,這些對(duì)比都是指數(shù)據(jù)量很大或者操作很頻繁的情況下的對(duì)比,如果數(shù)據(jù)和運(yùn)算量很小,那么對(duì)比將失去意義.Vector和ArrayList類似,但屬于強(qiáng)同步類。如果你的程序本身是線程安全的(thread-safe,沒(méi)有在多個(gè)線程之間共享同一個(gè)集合/對(duì)象),那么使用ArrayList是更好的選擇。Vector和ArrayList在更多元素添加進(jìn)來(lái)時(shí)會(huì)請(qǐng)求更大的空間。Vector每次請(qǐng)求其大小的雙倍空間,而ArrayList每次對(duì)size增長(zhǎng)50%.而LinkedList還實(shí)現(xiàn)了Queue接口,該接口比List提供了更多的方法,包括offer(),peek(),poll()等.注意:默認(rèn)情況下ArrayList的初始容量非常小,所以如果可以預(yù)估數(shù)據(jù)量的話,分配一個(gè)較大的初始值屬于最佳實(shí)踐,這樣可以減少調(diào)整大小的開(kāi)銷。19HashtableHashMapTreeMap的區(qū)別

Hashmap是一個(gè)最常用的Map,它根據(jù)鍵的HashCode值存儲(chǔ)數(shù)據(jù),根據(jù)鍵可以直接獲取它的值,具有很快的訪問(wèn)速度。HashMap最多只允許一條記錄的鍵為Null;允許多條記錄的值為Null;HashMap不支持線程的同步,即任一時(shí)刻可以有多個(gè)線程同時(shí)寫HashMap;可能會(huì)導(dǎo)致數(shù)據(jù)的不一致。如果需要同步,可以用Collections的synchronizedMap方法使HashMap具有同步的能力.

Hashtable與HashMap類似,但是主要有6點(diǎn)不同。

1.HashTable的方法是同步的,HashMap未經(jīng)同步,所以在多線程場(chǎng)合要手動(dòng)同步HashMap這個(gè)區(qū)別就像Vector和ArrayList一樣。

2.HashTable不允許null值,key和value都不可以,HashMap允許null值,key和value都可以。HashMap允許key值只能由一個(gè)null值,因?yàn)閔ashmap如果key值相同,新的key,

value將替代舊的。

3.HashTable有一個(gè)contains(Object

value)功能和containsValue(Object

value)功能一樣。

4.HashTable使用Enumeration,HashMap使用Iterator。

5.HashTable中hash數(shù)組默認(rèn)大小是11,增加的方式是

old*2+1。HashMap中hash數(shù)組的默認(rèn)大小是16,而且一定是2的指數(shù)。

6.哈希值的使用不同,HashTable直接使用對(duì)象的hashCode。

TreeMap能夠把它保存的記錄根據(jù)鍵排序,默認(rèn)是按升序排序,也可以指定排序的比較器,當(dāng)用Iterator遍歷TreeMap時(shí),得到的記錄是排過(guò)序的。20TomcatApachejbossweblogic的區(qū)別Apache:全球應(yīng)用最廣泛的http服務(wù)器,免費(fèi),出自apache基金組織Tomcat:應(yīng)用也算非常廣泛的web服務(wù)器,支持部分j2ee,免費(fèi),出自apache基金組織JBoss:開(kāi)源的應(yīng)用服務(wù)器,比較受人喜愛(ài),免費(fèi)(文檔要收費(fèi))Weblogic:應(yīng)該說(shuō)算是業(yè)界第一的appserver,全部支持j2ee1.4,對(duì)于開(kāi)發(fā)者,有免費(fèi)使用一年的許可證。Apache支持靜態(tài)頁(yè),Tomcat支持動(dòng)態(tài)的,比如Servlet等,一般使用Apache+Tomcat的話,Apache只是作為一個(gè)轉(zhuǎn)發(fā),對(duì)JSP的處理是由Tomcat來(lái)處理的。Apche可以支持PHPcgiperl,但是要使用Java的話,你需要Tomcat在Apache后臺(tái)支撐,將Java請(qǐng)求由Apache轉(zhuǎn)發(fā)給Tomcat處理。Apache是Web服務(wù)器,Tomcat是應(yīng)用(Java)服務(wù)器,它只是一個(gè)Servlet(JSP也翻譯成Servlet)容器,可以認(rèn)為是Apache的擴(kuò)展,但是可以獨(dú)立于Apache運(yùn)行。JBoss和WebLogic都含有Jsp和Servlet容器,也就可以做web容器,也包含EJB容器,是完整的J2EE應(yīng)用服務(wù)器。Tomcat只能做jsp和servlet的container21SessionCookie的區(qū)別①cookie數(shù)據(jù)存放在客戶的瀏覽器上,session數(shù)據(jù)放在服務(wù)器上。②cookie不是很安全,別人可以分析存放在本地的COOKIE并進(jìn)行COOKIE欺騙考慮到安全應(yīng)當(dāng)使用session。③session會(huì)在一定時(shí)間內(nèi)保存在服務(wù)器上。當(dāng)訪問(wèn)增多,會(huì)比較占用你服務(wù)器的性能

考慮到減輕服務(wù)器性能方面,應(yīng)當(dāng)使用COOKIE。④單個(gè)cookie保存的數(shù)據(jù)不能超過(guò)4K,很多瀏覽器都限制一個(gè)站點(diǎn)最多保存20個(gè)cookie。22JDBC、Hibernate、Mybatis的區(qū)別JDBC->Mybatis->Hibernate:原生->半自動(dòng)化->全自動(dòng)化1)從層次上看,JDBC是較底層的持久層操作方式,而Hibernate和MyBatis都是在JDBC的基礎(chǔ)上進(jìn)行了封裝使其更加方便程序員對(duì)持久層的操作。2)從功能上看,JDBC就是簡(jiǎn)單的建立數(shù)據(jù)庫(kù)連接,然后創(chuàng)建statement,將sql語(yǔ)句傳給statement去執(zhí)行,如果是有返回結(jié)果的查詢語(yǔ)句,會(huì)將查詢結(jié)果放到ResultSet對(duì)象中,通過(guò)對(duì)ResultSet對(duì)象的遍歷操作來(lái)獲取數(shù)據(jù);Hibernate是將數(shù)據(jù)庫(kù)中的數(shù)據(jù)表映射為持久層的Java對(duì)象,實(shí)現(xiàn)數(shù)據(jù)表的完整性控制;MyBatis是將sql語(yǔ)句中的輸入?yún)?shù)和輸出參數(shù)映射為java對(duì)象,放棄了對(duì)數(shù)據(jù)表的完整性控制,但是獲得了更靈活和響應(yīng)性能更快的優(yōu)勢(shì)。3)從使用上看,如果進(jìn)行底層編程,而且對(duì)性能要求極高的話,應(yīng)該采用JDBC的方式;如果要對(duì)數(shù)據(jù)庫(kù)進(jìn)行完整性控制的話建議使用Hibernate;如果要靈活使用sql語(yǔ)句的話建議采用MyBatis框架。23SpringMVC與Struts2的區(qū)別目前企業(yè)中使用SpringMvc的比例已經(jīng)遠(yuǎn)遠(yuǎn)超過(guò)Struts2,那么兩者到底有什么區(qū)別,是很多初學(xué)者比較關(guān)注的問(wèn)題,下面我們就來(lái)對(duì)SpringMvc和Struts2進(jìn)行各方面的比較:1.核心控制器(前端控制器、預(yù)處理控制器):對(duì)于使用過(guò)mvc框架的人來(lái)說(shuō)這個(gè)詞應(yīng)該不會(huì)陌生,核心控制器的主要用途是處理所有的請(qǐng)求,然后對(duì)那些特殊的請(qǐng)求(控制器)統(tǒng)一的進(jìn)行處理(字符編碼、文件上傳、參數(shù)接受、異常處理等等),springmvc核心控制器是Servlet,而Struts2是Filter。2.控制器實(shí)例:SpringMvc會(huì)比Struts快一些(理論上)。SpringMvc是基于方法設(shè)計(jì),而Sturts是基于對(duì)象,每次發(fā)一次請(qǐng)求都會(huì)實(shí)例一個(gè)action,每個(gè)action都會(huì)被注入屬性,而Spring更像Servlet一樣,只有一個(gè)實(shí)例,每次請(qǐng)求執(zhí)行對(duì)應(yīng)的方法即可(注意:由于是單例實(shí)例,所以應(yīng)當(dāng)避免全局變量的修改,這樣會(huì)產(chǎn)生線程安全問(wèn)題)。3.管理方式:大部分的公司的核心架構(gòu)中,就會(huì)使用到spring,而springmvc又是spring中的一個(gè)模塊,所以spring對(duì)于springmvc的控制器管理更加簡(jiǎn)單方便,而且提供了全注解方式進(jìn)行管理,各種功能的注解都比較全面,使用簡(jiǎn)單,而struts2需要采用XML很多的配置參數(shù)來(lái)管理(雖然也可以采用注解,但是幾乎沒(méi)有公司那樣使用)。4.參數(shù)傳遞:Struts2中自身提供多種參數(shù)接受,其實(shí)都是通過(guò)(ValueStack)進(jìn)行傳遞和賦值,而SpringMvc是通過(guò)方法的參數(shù)進(jìn)行接收。5.學(xué)習(xí)難度:Struts更加很多新的技術(shù)點(diǎn),比如攔截器、值棧及OGNL表達(dá)式,學(xué)習(xí)成本較高,springmvc比較簡(jiǎn)單,很較少的時(shí)間都能上手。6.intercepter的實(shí)現(xiàn)機(jī)制:struts有以自己的interceptor機(jī)制,springmvc用的是獨(dú)立的AOP方式。這樣導(dǎo)致struts的配置文件量還是比springmvc大,雖然struts的配置能繼承,所以我覺(jué)得論使用上來(lái)講,springmvc使用更加簡(jiǎn)潔,開(kāi)發(fā)效率SpringMVC確實(shí)比struts2高。springmvc是方法級(jí)別的攔截,一個(gè)方法對(duì)應(yīng)一個(gè)request上下文,而方法同時(shí)又跟一個(gè)url對(duì)應(yīng),所以說(shuō)從架構(gòu)本身上spring3mvc就容易實(shí)現(xiàn)restfulurl。struts2是類級(jí)別的攔截,一個(gè)類對(duì)應(yīng)一個(gè)request上下文;實(shí)現(xiàn)restfulurl要費(fèi)勁,因?yàn)閟truts2action的一個(gè)方法可以對(duì)應(yīng)一個(gè)url;而其類屬性卻被所有方法共享,這也就無(wú)法用注解或其他方式標(biāo)識(shí)其所屬方法了。spring3mvc的方法之間基本上獨(dú)立的,獨(dú)享requestresponse數(shù)據(jù),請(qǐng)求數(shù)據(jù)通過(guò)參數(shù)獲取,處理結(jié)果通過(guò)ModelMap交回給框架方法之間不共享變量,而struts2搞的就比較亂,雖然方法之間也是獨(dú)立的,但其所有Action變量是共享的,這不會(huì)影響程序運(yùn)行,卻給我們編碼,讀程序時(shí)帶來(lái)麻煩。7.springmvc處理ajax請(qǐng)求,直接通過(guò)返回?cái)?shù)據(jù),方法中使用注解@ResponseBody,springmvc自動(dòng)幫我們對(duì)象轉(zhuǎn)換為JSON數(shù)據(jù)。而struts2是通過(guò)插件的方式進(jìn)行處理在SpringMVC流行起來(lái)之前,Struts2在MVC框架中占核心地位,隨著SpringMVC的出現(xiàn),SpringMVC慢慢的取代struts2,但是很多企業(yè)都是原來(lái)搭建的框架,使用Struts2較多。24請(qǐng)描述SpringMvc工作原理1、用戶向服務(wù)器發(fā)送請(qǐng)求,請(qǐng)求被Spring前端控制ServeltDispatcherServlet捕獲(捕獲)2、

DispatcherServlet對(duì)請(qǐng)求URL進(jìn)行解析,得到請(qǐng)求資源標(biāo)識(shí)符(URI)。然后根據(jù)該URI,調(diào)用HandlerMapping獲得該Handler配置的所有相關(guān)的對(duì)象(包括Handler對(duì)象以及Handler對(duì)象對(duì)應(yīng)的攔截器),最后以HandlerExecutionChain對(duì)象的形式返回;(查找handler)3、

DispatcherServlet根據(jù)獲得的Handler,選擇一個(gè)合適的HandlerAdapter。

提取Request中的模型數(shù)據(jù),填充Handler入?yún)ⅲ_(kāi)始執(zhí)行Handler(Controller),

Handler執(zhí)行完成后,向DispatcherServlet

返回一個(gè)ModelAndView對(duì)象(執(zhí)行handler)4、DispatcherServlet根據(jù)返回的ModelAndView,選擇一個(gè)適合的ViewResolver(必須是已經(jīng)注冊(cè)到Spring容器中的ViewResolver)

(選擇ViewResolver)5、通過(guò)ViewResolver結(jié)合Model和View,來(lái)渲染視圖,DispatcherServlet

將渲染結(jié)果返回給客戶端。(渲染返回)25請(qǐng)描述ssm(springspringmvcmybatis)工作流程先寫實(shí)體類entity,定義對(duì)象的屬性,(可以參照數(shù)據(jù)庫(kù)中表的字段來(lái)設(shè)置,數(shù)據(jù)庫(kù)的設(shè)計(jì)應(yīng)該在所有編碼開(kāi)始之前)。寫Mapper.xml(Mybatis),其中定義你的功能,對(duì)應(yīng)要對(duì)數(shù)據(jù)庫(kù)進(jìn)行的那些操作,比如insert、selectAll、selectByKey、delete、update等。寫Mapper.java,將Mapper.xml中的操作按照id映射成Java函數(shù)。寫Service.java,為控制層提供服務(wù),接受控制層的參數(shù),完成相應(yīng)的功能,并返回給控制層。寫Controller.java,連接頁(yè)面請(qǐng)求和服務(wù)層,獲取頁(yè)面請(qǐng)求的參數(shù),通過(guò)自動(dòng)裝配,映射不同的URL到相應(yīng)的處理函數(shù),并獲取參數(shù),對(duì)參數(shù)進(jìn)行處理,之后傳給服務(wù)層。寫JSP頁(yè)面調(diào)用,請(qǐng)求哪些參數(shù),需要獲取什么數(shù)據(jù)26說(shuō)說(shuō)你對(duì)Java中反射的理解以及應(yīng)用場(chǎng)景JAVA反射機(jī)制是在運(yùn)行狀態(tài)中,對(duì)于任意一個(gè)類,都能夠知道這個(gè)類的所有屬性和方法;對(duì)于任意一個(gè)對(duì)象,都能夠調(diào)用它的任意一個(gè)方法;這種動(dòng)態(tài)獲取的信息以及動(dòng)態(tài)調(diào)用對(duì)象的方法的功能稱為java語(yǔ)言的反射機(jī)制。Java反射機(jī)制主要提供了以下功能:在運(yùn)行時(shí)判斷任意一個(gè)對(duì)象所屬的類;在運(yùn)行時(shí)構(gòu)造任意一個(gè)類的對(duì)象;在運(yùn)行時(shí)判斷任意一個(gè)類所具有的成員變量和方法;在運(yùn)行時(shí)調(diào)用任意一個(gè)對(duì)象的方法;生成動(dòng)態(tài)代理。應(yīng)用:①獲取某個(gè)對(duì)象的屬性②獲取類的靜態(tài)屬性③執(zhí)行某對(duì)象方法④執(zhí)行類的靜態(tài)方法⑤創(chuàng)建某個(gè)類的實(shí)例⑥判斷對(duì)象是否是某個(gè)類的實(shí)例27Servlet的生命周期Servlet生命周期:Servlet加載>實(shí)例化>服務(wù)>銷毀。init:在Servlet的生命周期中,僅執(zhí)行一次init()方法。它是在服務(wù)器裝入Servlet時(shí)執(zhí)行的,負(fù)責(zé)初始化Servlet對(duì)象??梢耘渲梅?wù)器,以在啟動(dòng)服務(wù)器或客戶機(jī)首次訪問(wèn)Servlet時(shí)裝入Servlet。無(wú)論有多少客戶機(jī)訪問(wèn)Servlet,都不會(huì)重復(fù)執(zhí)行init()。service:它是Servlet的核心,負(fù)責(zé)響應(yīng)客戶的請(qǐng)求。每當(dāng)一個(gè)客戶請(qǐng)求一個(gè)HttpServlet對(duì)象,該對(duì)象的Service()方法就要調(diào)用,而且傳遞給這個(gè)方法一個(gè)“請(qǐng)求”(ServletRequest)對(duì)象和一個(gè)“響應(yīng)”(ServletResponse)對(duì)象作為參數(shù)。在HttpServlet中已存在Service()方法。默認(rèn)的服務(wù)功能是調(diào)用與HTTP請(qǐng)求的方法相應(yīng)的do功能。destroy:

僅執(zhí)行一次,在服務(wù)器端停止且卸載Servlet時(shí)執(zhí)行該方法。當(dāng)Servlet對(duì)象退出生命周期時(shí),負(fù)責(zé)釋放占用的資源。一個(gè)Servlet在運(yùn)行service()方法時(shí)可能會(huì)產(chǎn)生其他的線程,因此需要確認(rèn)在調(diào)用destroy()方法時(shí),這些線程已經(jīng)終止或完成。創(chuàng)建Servlet對(duì)象的時(shí)機(jī):Servlet容器啟動(dòng)時(shí):讀取web.xml配置文件中的信息,構(gòu)造指定的Servlet對(duì)象,創(chuàng)建ServletConfig對(duì)象,同時(shí)將ServletConfig對(duì)象作為參數(shù)來(lái)調(diào)用Servlet對(duì)象的init方法。在Servlet容器啟動(dòng)后:客戶首次向Servlet發(fā)出請(qǐng)求,Servlet容器會(huì)判斷內(nèi)存中是否存在指定的Servlet對(duì)象,如果沒(méi)有則創(chuàng)建它,然后根據(jù)客戶的請(qǐng)求創(chuàng)建HttpRequest、HttpResponse對(duì)象,從而調(diào)用Servlet

對(duì)象的service方法。Servlet

Servlet容器在啟動(dòng)時(shí)自動(dòng)創(chuàng)建Servlet,這是由在web.xml文件中為Servlet設(shè)置的<load-on-startup>屬性決定的。從中我們也能看到同一個(gè)類型的Servlet對(duì)象在Servlet容器中以單例的形式存在。28equals相關(guān)問(wèn)題:Java中equals和==的區(qū)別是什么?相等的理解(==和equals)相等:傳統(tǒng)的理解一般都是數(shù)字值是否相等;在程序中任何東西都是數(shù)據(jù),都會(huì)比較是否相等==基本數(shù)據(jù)類型:比較的就是值是否相等;引用數(shù)據(jù)類型:比較的是對(duì)象的地址是否一樣;equals(最初定義在根類Object中的)基本數(shù)據(jù)類型:不能夠使用!基本數(shù)據(jù)類型不是對(duì)象,不能夠調(diào)用Object中的方法引用數(shù)據(jù)類型:在Object的源碼中定義的就是==進(jìn)行比較比較如果我們沒(méi)有去覆寫過(guò)equals方法而是直接調(diào)用到了Object中的此方法,那么結(jié)果和==比較應(yīng)用數(shù)據(jù)類型一樣的;在實(shí)際開(kāi)發(fā)中,我們一般比較對(duì)象都是通過(guò)對(duì)象的屬性值進(jìn)行比較(一般比較對(duì)象的地址沒(méi)有多大用處),所以我們會(huì)經(jīng)常覆寫Object中的此方法,把自己的規(guī)則寫在方法里面;覆寫equals方法必須覆寫hashCode方法嗎?你的理解是什么?不是必須。但是假如一個(gè)類要?jiǎng)?chuàng)建很多對(duì)象,而這些對(duì)象要存儲(chǔ)集合不確定,有可能是hashSet,也有可能是TreeSet,為了保證唯一性,所以最好復(fù)寫hashCode方法,因?yàn)閷?duì)象存入帶hash的集合,如hashSet,hashMap,都要基于hashCode和equals方法,當(dāng)hashCode方法返回的值一樣時(shí),還會(huì)調(diào)用equals方法判斷,如果兩個(gè)方法返回的都是一致,才判斷兩個(gè)對(duì)象是同一個(gè)對(duì)象,不存入集合(帶hash的集合都保證數(shù)據(jù)是唯一的?。?9開(kāi)發(fā)這么久了遇到了哪些異常?Nullpointerexception、classnotfoundexception、arrayindexoutofboundsexception、illegalargumentexception、ClassCastException、FileNotFoundException、NumberFormatException、NoSuchMethodException、IOException、SQLException、NoClassDefFoundError、OutOfMemoryError30你了解分布式和數(shù)據(jù)庫(kù)集群?jiǎn)??分布式是一個(gè)非常廣泛的概念,從系統(tǒng)的角度來(lái)說(shuō),可以理解為,一個(gè)業(yè)務(wù)分拆多個(gè)子業(yè)務(wù),部署在不同的服務(wù)器上,集群則是同一個(gè)業(yè)務(wù)部署在多個(gè)服務(wù)器上。JavaEE開(kāi)發(fā)過(guò)程中,常見(jiàn)的分布式框架有:Dubbo、Hadoop、Elasticsearch數(shù)據(jù)庫(kù)集群:MySQL集群是一個(gè)無(wú)共享的(shared-nothing)、分布式節(jié)點(diǎn)架構(gòu)的存儲(chǔ)方案,其目的是提供容錯(cuò)性和高性能。通過(guò)多個(gè)MySQL服務(wù)器分配負(fù)載,從而最大程序地達(dá)到高性能,通過(guò)在不同位置存儲(chǔ)數(shù)據(jù)保證高可用性和冗余。一般由一個(gè)主(寫)+一個(gè)備(寫)和N個(gè)從(讀)庫(kù)組成。31靜態(tài)變量和實(shí)例變量的區(qū)別?類變量也叫靜態(tài)變量,也就是在變量前加了static的變量;實(shí)例變量也叫對(duì)象變量,即沒(méi)加static的變量;區(qū)別在于:類變量是所有對(duì)象共有,其中一個(gè)對(duì)象將它值改變,其他對(duì)象得到的就是改變后的結(jié)果;而實(shí)例變量則屬對(duì)象私有,某一個(gè)對(duì)象將其值改變,不影響其他對(duì)象32Overload和Override的區(qū)別方法重載和方法重寫33MyBatis如何防止Sql注入①使用#{},避免使用${}。②使用存儲(chǔ)過(guò)程34svn提交代碼,發(fā)生沖突了如何處理①更新最新的服務(wù)器代碼下來(lái)②打開(kāi)沖突的文件進(jìn)行對(duì)比③簡(jiǎn)單沖突直接修改,復(fù)雜沖突找到上個(gè)提交人協(xié)助修改,修改完成后標(biāo)記為“已解決”④提交修改完成的文件35線程問(wèn)題進(jìn)程和線程的區(qū)別,簡(jiǎn)單描述進(jìn)程和線程?進(jìn)程是具有一定獨(dú)立功能的程序關(guān)于某個(gè)數(shù)據(jù)集合上的一次運(yùn)行活動(dòng),進(jìn)程是系統(tǒng)進(jìn)行資源分配和調(diào)度的一個(gè)獨(dú)立單位.線程是進(jìn)程的一個(gè)實(shí)體,是CPU調(diào)度和分派的基本單位,它是比進(jìn)程更小的能獨(dú)立運(yùn)行的基本單位.線程自己基本上不擁有系統(tǒng)資源,只擁有一點(diǎn)在運(yùn)行中必不可少的資源(如程序計(jì)數(shù)器,一組寄存器和棧),但是它可與同屬一個(gè)進(jìn)程的其他的線程共享進(jìn)程所擁有的全部資源.關(guān)系一個(gè)線程可以創(chuàng)建和撤銷另一個(gè)線程;同一個(gè)進(jìn)程中的多個(gè)線程之間可以并發(fā)執(zhí)行.相對(duì)進(jìn)程而言,線程是一個(gè)更加接近于執(zhí)行體的概念,它可以與同進(jìn)程中的其他線程共享數(shù)據(jù),但擁有自己的棧空間,擁有獨(dú)立的執(zhí)行序列。區(qū)別進(jìn)程和線程的主要差別在于它們是不同的操作系統(tǒng)資源管理方式。進(jìn)程有獨(dú)立的地址空間,一個(gè)進(jìn)程崩潰后,在保護(hù)模式下不會(huì)對(duì)其它進(jìn)程產(chǎn)生影響,而線程只是一個(gè)進(jìn)程中的不同執(zhí)行路徑。線程有自己的堆棧和局部變量,但線程之間沒(méi)有單獨(dú)的地址空間,一個(gè)線程死掉就等于整個(gè)進(jìn)程死掉,所以多進(jìn)程的程序要比多線程的程序健壯,但在進(jìn)程切換時(shí),耗費(fèi)資源較大,效率要差一些。但對(duì)于一些要求同時(shí)進(jìn)行并且又要共享某些變量的并發(fā)操作,只能用線程,不能用進(jìn)程。1)

簡(jiǎn)而言之,一個(gè)程序至少有一個(gè)進(jìn)程,一個(gè)進(jìn)程至少有一個(gè)線程.2)

線程的劃分尺度小于進(jìn)程,使得多線程程序的并發(fā)性高。3)

另外,進(jìn)程在執(zhí)行過(guò)程中擁有獨(dú)立的內(nèi)存單元,而多個(gè)線程共享內(nèi)存,從而極大地提高了程序的運(yùn)行效率。4)

線程在執(zhí)行過(guò)程中與進(jìn)程還是有區(qū)別的。每個(gè)獨(dú)立的線程有一個(gè)程序運(yùn)行的入口、順序執(zhí)行序列和程序的出口。但是線程不能夠獨(dú)立執(zhí)行,必須依存在應(yīng)用程序中,由應(yīng)用程序提供多個(gè)線程執(zhí)行控制。5)

從邏輯角度來(lái)看,多線程的意義在于一個(gè)應(yīng)用程序中,有多個(gè)執(zhí)行部分可以同時(shí)執(zhí)行。但操作系統(tǒng)并沒(méi)有將多個(gè)線程看做多個(gè)獨(dú)立的應(yīng)用,來(lái)實(shí)現(xiàn)進(jìn)程的調(diào)度和管理以及資源分配。這就是進(jìn)程和線程的重要區(qū)別。講講JDK的線程池ThreadPoolExecutor

ThreadPool中的線程不用手動(dòng)開(kāi)始,也不用手動(dòng)取消,要做的只是把工作函數(shù)排入線程池,剩下的工作由系統(tǒng)自動(dòng)完成,不能控制線程池中的線程。以下情況不適宜用ThreadPool:線程執(zhí)行時(shí)間長(zhǎng)、線程需要制定不同的優(yōu)先級(jí)、執(zhí)行過(guò)程中需要控制線程的睡眠和掛起等操作。所以ThreadPool適合并發(fā)運(yùn)行若干個(gè)運(yùn)行時(shí)間不長(zhǎng)且互不干擾的函數(shù)。①ThreadPoolExecutor作為java.util.concurrent包對(duì)外提供基礎(chǔ)實(shí)現(xiàn),以內(nèi)部線程池的形式對(duì)外提供管理任務(wù)執(zhí)行,線程調(diào)度,線程池管理等等服務(wù);②Executors方法提供的線程服務(wù),都是通過(guò)參數(shù)設(shè)置來(lái)實(shí)現(xiàn)不同的線程池機(jī)制。lock和synchronized區(qū)別①、ReentrantLock擁有Synchronized相同的并發(fā)性和內(nèi)存語(yǔ)義,此外還多了鎖投票,定時(shí)鎖等候和中斷鎖等候

線程A和B都要獲取對(duì)象O的鎖定,假設(shè)A獲取了對(duì)象O鎖,B將等待A釋放對(duì)O的鎖定,

如果使用synchronized,如果A不釋放,B將一直等下去,不能被中斷

如果使用ReentrantLock,如果A不釋放,可以使B在等待了足夠長(zhǎng)的時(shí)間以后,中斷等待,而干別的事情

ReentrantLock獲取鎖定與三種方式:

a)

lock(),如果獲取了鎖立即返回,如果別的線程持有鎖,當(dāng)前線程則一直處于休眠狀態(tài),直到獲取鎖

b)tryLock(),

如果獲取了鎖立即返回true,如果別的線程正持有鎖,立即返回false;

c)tryLock(long

timeout,TimeUnit

unit),

如果獲取了鎖定立即返回true,如果別的線程正持有鎖,會(huì)等待參數(shù)給定的時(shí)間,在等待的過(guò)程中,如果獲取了鎖定,就返回true,如果等待超時(shí),返回false;

d)lockInterruptibly:如果獲取了鎖定立即返回,如果沒(méi)有獲取鎖定,當(dāng)前線程處于休眠狀態(tài),直到或者鎖定,或者當(dāng)前線程被別的線程中斷

②、synchronized是在JVM層面上實(shí)現(xiàn)的,不但可以通過(guò)一些監(jiān)控工具監(jiān)控synchronized的鎖定,而且在代碼執(zhí)行時(shí)出現(xiàn)異常,JVM會(huì)自動(dòng)釋放鎖定,但是使用Lock則不行,lock是通過(guò)代碼實(shí)現(xiàn)的,要保證鎖定一定會(huì)被釋放,就必須將unLock()放到finally{}中

③、在資源競(jìng)爭(zhēng)不是很激烈的情況下,Synchronized的性能要優(yōu)于ReetrantLock,但是在資源競(jìng)爭(zhēng)很激烈的情況下,Synchronized的性能會(huì)下降幾十倍,但是ReetrantLock的性能能維持常態(tài);系統(tǒng)中的并發(fā)是怎樣解決的synchronized關(guān)鍵字主要解決多線程共享數(shù)據(jù)同步問(wèn)題。

ThreadLocal使用場(chǎng)合主要解決多線程中數(shù)據(jù)因并發(fā)產(chǎn)生不一致問(wèn)題。ThreadLocal和Synchonized都用于解決多線程并發(fā)訪問(wèn)。但是ThreadLocal與synchronized有本質(zhì)的區(qū)別:synchronized是利用鎖的機(jī)制,使變量或代碼塊在某一時(shí)該只能被一個(gè)線程訪問(wèn)。而ThreadLocal為每一個(gè)線程都提供了變量的副本,使得每個(gè)線程在某一時(shí)間訪問(wèn)到的并不是同一個(gè)對(duì)象,這樣就隔離了多個(gè)線程對(duì)數(shù)據(jù)的數(shù)據(jù)共享。而Synchronized卻正好相反,它用于在多個(gè)線程間通信時(shí)能夠獲得數(shù)據(jù)共享。Synchronized用于線程間的數(shù)據(jù)共享,

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論