Java基礎(chǔ)面試題總結(jié)二
1,什么是字符串常量池?
字符串的分配,和其他的對(duì)象分配一樣,耗費(fèi)高昂的時(shí)間與空間代價(jià)。JVM為了提高性能和減少內(nèi)存開銷,在實(shí)例化字符串常量的時(shí)候進(jìn)行了一些優(yōu)化。為 了減少在JVM中創(chuàng)建的字符串的數(shù)量,字符串類維護(hù)了一個(gè)字符串池,每當(dāng)代碼創(chuàng)建字符串常量時(shí),JVM會(huì)首先檢查字符串常量池。如果字符串已經(jīng)存在池中, 就返回池中的實(shí)例引用。如果字符串不在池中,就會(huì)實(shí)例化一個(gè)字符串并放到池中。Java能夠進(jìn)行這樣的優(yōu)化是因?yàn)樽址遣豢勺兊模梢圆挥脫?dān)心數(shù)據(jù)沖突 進(jìn)行共享。
2,重載和重寫的區(qū)別?
①重寫:
表示子類中的方法可以與父類中的某個(gè)方法的名稱和參數(shù)完全相同,通過子類創(chuàng)建的實(shí)例對(duì)象調(diào)用這個(gè)方法時(shí),將調(diào)用子類中的定義方法,這相當(dāng)于把父類中定義的那個(gè)完全相同的方法給覆蓋了,這也是面向?qū)ο缶幊痰亩鄳B(tài)性的一種表現(xiàn)。子類覆蓋父類的方法時(shí),只能比父類拋出更少的異常,或者是拋出父類拋出的異常的子異常,因?yàn)樽宇惪梢越鉀Q父類的一些問題,不能比父類有更多的問題。子類方法的訪問權(quán)限只能比父類的更大,不能更小。如果父類的方法是private類型,那么,子類則不存在覆蓋的限制,相當(dāng)于子類中增加了一個(gè)全新的方法。
②重載:
在一個(gè)類中,同名的方法如果有不同的參數(shù)列表(參數(shù)類型不同、參數(shù)個(gè)數(shù)不同甚至是參數(shù)順序不同)則視為重載。同時(shí),重載對(duì)返回類型沒有要求,可以相同也可以不同,但不能通過返回類型是否相同來(lái)判斷重載。
總結(jié):
方法的重載和重寫都是實(shí)現(xiàn)多態(tài)的方式,區(qū)別在于前者實(shí)現(xiàn)的是編譯時(shí)的多態(tài)性,而后者實(shí)現(xiàn)的是運(yùn)行時(shí)的多態(tài)性。重載發(fā)生在一個(gè)類中,同名的方法如果有不同的參數(shù)列表(參數(shù)類型不同、參數(shù)個(gè)數(shù)不同或者二者都不同)則視為重載;重寫發(fā)生在子類與父類之間,重寫要求子類被重寫方法與父類被重寫方法有相同的參數(shù)列表,有兼容的返回類型,比父類被重寫方法更好訪問,不能比父類被重寫方法聲明更多的異常(里氏代換原則)。重載對(duì)返回類型沒有特殊的要求,不能根據(jù)返回類型進(jìn)行區(qū)分。
————————————————
https://blog.csdn.net/wintershii/article/details/80558739
3,throw和throws的區(qū)別?
throws是用來(lái)聲明一個(gè)方法可能拋出的所有異常信息,throws是將異常聲明但是不處理,而是將異常往上傳,誰(shuí)調(diào)用我就交給誰(shuí)處理。而throw則是指拋出的一個(gè)具體的異常類型。throw代表動(dòng)作,表示拋出一個(gè)異常的動(dòng)作;throws代表一種狀態(tài),代表方法可能有異常拋出;throw用在方法實(shí)現(xiàn)中,而throws用在方法聲明中;throw只能用于拋出一種異常,而throws可以拋出多個(gè)異常。
4,hashmap實(shí)現(xiàn)原理?
HashMap采用了(數(shù)組 + 鏈表 + 紅黑樹)的實(shí)現(xiàn)結(jié)構(gòu),數(shù)組的一個(gè)元素稱作位桶。
HashMap基于hashing原理,我們通過put()和get()方法儲(chǔ)存和獲取對(duì)象。當(dāng)我們將鍵值對(duì)傳遞給put()方法時(shí),它調(diào)用鍵對(duì)象的hashCode()方法來(lái)計(jì)算hashcode,讓后找到bucket位置來(lái)儲(chǔ)存值對(duì)象。當(dāng)獲取對(duì)象時(shí),通過鍵對(duì)象的equals()方法找到正確的鍵值對(duì),然后返回值對(duì)象。如果該位置中沒有元素,則直接把元素存儲(chǔ)在此位置,如果該位置有元素了,則把元素以鏈表的形式存放在鏈表的尾部。HashMap使用鏈表來(lái)解決碰撞問題,當(dāng)發(fā)生碰撞了,對(duì)象將會(huì)儲(chǔ)存在鏈表的下一個(gè)節(jié)點(diǎn)中。 HashMap在每個(gè)鏈表節(jié)點(diǎn)中儲(chǔ)存鍵值對(duì)對(duì)象。
當(dāng)兩個(gè)不同的鍵對(duì)象的hashcode相同時(shí)會(huì)發(fā)生什么? 它們會(huì)儲(chǔ)存在同一個(gè)bucket位置的鏈表中。鍵對(duì)象的equals()方法用來(lái)找到鍵值對(duì)。
hashmap和hashtable的區(qū)別:
①HashMap可以接受為null的鍵值(key)和值(value),而Hashtable則不行。
②HashMap是非synchronized,而Hashtable是synchronized,這意味著Hashtable是線程安全的,多個(gè)線程可以共享一個(gè)Hashtable;而如果沒有正確的同步的話,多個(gè)線程是不能共享HashMap的。Java 5提供了ConcurrentHashMap,它是HashTable的替代,比HashTable的擴(kuò)展性更好。
③HashMap的迭代器(Iterator)是fail-fast迭代器,而Hashtable的enumerator迭代器不是fail-fast的。
④由于Hashtable是線程安全的也是synchronized,所以在單線程環(huán)境下它比HashMap要慢。如果你不需要同步,只需要單一線程,那么使用HashMap性能要好過Hashtable
⑤Hashtable每次擴(kuò)容,容量都為原來(lái)的2倍加1,而HashMap為原來(lái)的2倍。
5,什么是Servlet,Servlet生命周期方法?
Servlet是一個(gè)基于Java技術(shù)的動(dòng)態(tài)網(wǎng)頁(yè)技術(shù),運(yùn)行在服務(wù)器端,由Servlet容器管理,用于生產(chǎn)動(dòng)態(tài)的內(nèi)容。是jsp的前身。
Servlet是平臺(tái)獨(dú)立的符合特定規(guī)范的java類,編寫一個(gè)Servlet實(shí)際上就是按照Servlet規(guī)范編寫一個(gè)java類。
Servlet不是由用戶或程序直接調(diào)用,而是由容器管理,沒有main方法。
生命周期方法:
init()
service()
destory()
Servlet運(yùn)行過程:
①類加載
②Web服務(wù)器首先檢查是否已經(jīng)裝載并創(chuàng)建了該Servlet的實(shí)例對(duì)象。如果是,則直接執(zhí)行第⑤步,否則,執(zhí)行第③步。
③裝載并創(chuàng)建該Servlet的一個(gè)實(shí)例對(duì)象。
④調(diào)用Servlet實(shí)例對(duì)象的init()方法。
⑤創(chuàng)建一個(gè)用于封裝HTTP請(qǐng)求消息的HttpServletRequest對(duì)象和一個(gè)代表HTTP響應(yīng)消息的HttpServletResponse對(duì)象,然后調(diào)用Servlet的service()方法,根據(jù)提交方式選擇執(zhí)行doGet()方法或者doPost()方法,并將請(qǐng)求和響應(yīng)對(duì)象作為參數(shù)傳遞進(jìn)去。
⑥WEB應(yīng)用程序被停止或重新啟動(dòng)之前,Servlet引擎將卸載Servlet,并在卸載之前調(diào)用Servlet的destroy()方法。
6,JSP的隱式對(duì)象有哪些?
request,response,out,session,application,pageContext,page,config,exception
7,JSP的四個(gè)域?qū)ο蟮淖饔梅秶?/h3>
pageContext:作用范圍:當(dāng)前jsp頁(yè)面。
request:一次請(qǐng)求范圍內(nèi),轉(zhuǎn)發(fā)有效重定向失效。
session:存活時(shí)間內(nèi)(默認(rèn)30分鐘),一次會(huì)話內(nèi)有效,轉(zhuǎn)發(fā)和重定向都有效。瀏覽器打開到關(guān)閉就是一次會(huì)話。
application:最大作用范圍,范圍限于當(dāng)前web應(yīng)用,只要在一處設(shè)置了,當(dāng)前web應(yīng)用下的其他servlet和jsp都可以訪問。
8,轉(zhuǎn)發(fā)和重定向的區(qū)別?
①重定向訪問服務(wù)器兩次,轉(zhuǎn)發(fā)只訪問服務(wù)器一次。
②重定向可以看見目標(biāo)頁(yè)面的URL,轉(zhuǎn)發(fā)只能看見第一次訪問的頁(yè)面URL,以后的工作都是有服務(wù)器來(lái)做的。
③重定向跳轉(zhuǎn)后必須加上return,要不然頁(yè)面雖然跳轉(zhuǎn)了,但是還會(huì)執(zhí)行跳轉(zhuǎn)后面的語(yǔ)句,轉(zhuǎn)發(fā)是執(zhí)行了跳轉(zhuǎn)頁(yè)面,下面的代碼就不會(huì)在執(zhí)行了。
④在request級(jí)別使用信息共享,使用重定向必然出錯(cuò)。
⑤還有一個(gè)大的區(qū)別就是,重定向可以訪問自己web應(yīng)用以外的資源。
詳情:https://blog.csdn.net/xybelieve1990/article/details/49486751
第一范式(1NF)所謂第一范式(1NF)是指數(shù)據(jù)庫(kù)表的每一列都是不可分割的基本數(shù)據(jù)項(xiàng),同一列中不能有多個(gè)值,即實(shí)體中的某個(gè)屬性不能有多個(gè)值或者不能有重復(fù)的屬性。如果出現(xiàn)重復(fù)的屬性,就可能需要定義一個(gè)新的實(shí)體,新的實(shí)體由重復(fù)的屬性構(gòu)成,新實(shí)體與原實(shí)體之間為一對(duì)多關(guān)系。在第一范式(1NF)中表的每一行只包含一個(gè)實(shí)例的信息。在任何一個(gè)關(guān)系數(shù)據(jù)庫(kù)中,第一范式(1NF)是對(duì)關(guān)系模式的基本要求,不滿足第一范式(1NF)的數(shù)據(jù)庫(kù)就不是關(guān)系數(shù)據(jù)庫(kù)。理解注釋:列不可分。
第二范式(2NF)第二范式(2NF)是在第一范式(1NF)的基礎(chǔ)上建立起來(lái)的,即滿足第二范式(2NF)必須先滿足第一范式(1NF)。第二范式(2NF)要求數(shù)據(jù)庫(kù)表中的每個(gè)實(shí)例或行必須可以被惟一的區(qū)分。為實(shí)現(xiàn)區(qū)分通常需要為表加上一個(gè)列,以存儲(chǔ)各個(gè)實(shí)例的惟一標(biāo)識(shí)。要求實(shí)體的屬性完全依賴于主關(guān)鍵字。理解注釋:不能部分依賴。即:一張表存在組合主鍵時(shí),其他非主鍵字段不能部分依賴。
第三范式(3NF)滿足第三范式(3NF)必須先滿足第二范式(2NF)。簡(jiǎn)而言之,第三范式(3NF)要求一個(gè)數(shù)據(jù)庫(kù)表中不包含已在其它表中已包含的非主關(guān)鍵字信息。在第二范式的基礎(chǔ)上,數(shù)據(jù)表中如果不存在非關(guān)鍵字段對(duì)任一候選關(guān)鍵字段的傳遞函數(shù)依賴則符合第三范式。理解注釋:不能存在傳遞依賴。即:除主鍵外,其他字段必須依賴主鍵。
還是這個(gè)容易理解
10數(shù)據(jù)庫(kù)連接池原理?
對(duì)于一個(gè)復(fù)雜的數(shù)據(jù)庫(kù)應(yīng)用,頻繁的建立、關(guān)閉連接,會(huì)極大的減低系統(tǒng)的性能,因?yàn)閷?duì)于連接的使用成了系統(tǒng)性能的瓶頸。連接復(fù)用,通過建立一個(gè)數(shù)據(jù)庫(kù)連接池以及一套連接使用管理策略,使得一個(gè)數(shù)據(jù)庫(kù)連接可以得到高效、安全的復(fù)用,避免了數(shù)據(jù)庫(kù)連接頻繁建立、關(guān)閉的開銷。
對(duì)于共享資源,有一個(gè)很著名的設(shè)計(jì)模式:資源池。該模式正是為了解決資源頻繁分配、釋放所造成的問題的。把該模式應(yīng)用到數(shù)據(jù)庫(kù)連接管理領(lǐng)域,就是建立一個(gè)數(shù)據(jù)庫(kù)連接池。
數(shù)據(jù)庫(kù)連接池是負(fù)責(zé)分配、管理和釋放數(shù)據(jù)庫(kù)連接,它允許應(yīng)用程序重復(fù)使用一個(gè)現(xiàn)有的數(shù)據(jù)庫(kù)連接,而不是再重新建立一個(gè)。
數(shù)據(jù)庫(kù)連接池的基本原理是在內(nèi)部對(duì)象池中維護(hù)一定數(shù)量的數(shù)據(jù)庫(kù)連接,就是預(yù)先在池中放入一定數(shù)量的數(shù)據(jù)庫(kù)連接管道,需要時(shí),從池子中取出管道進(jìn)行使用,操作完畢后,在將管道放入池子中,從而避免了頻繁的向數(shù)據(jù)庫(kù)申請(qǐng)資源,釋放資源帶來(lái)的性能損耗。并對(duì)外暴露數(shù)據(jù)庫(kù)連接獲取和返回方法。如:
外部使用者可通過getConnection 方法獲取連接,使用完畢后再通過releaseConnection 方法將連接返回,注意此時(shí)連接并沒有關(guān)閉,而是由連接池管理器回收,并為下一次使用做好準(zhǔn)備。
11,Spring的IOC和AOP機(jī)制?
①IOC
在使用Spring框架之后,對(duì)象的實(shí)例不在由調(diào)用者來(lái)創(chuàng)建,而是由Spring容器來(lái)創(chuàng)建,Spring容器會(huì)負(fù)責(zé)控制程序之間的關(guān)系,而不是由調(diào)用者的程序代碼直接控制。這樣,控制權(quán)由應(yīng)用代碼轉(zhuǎn)移到Spring容器,控制權(quán)發(fā)生了反轉(zhuǎn),這就是Spring的控制反轉(zhuǎn)。
②AOP
在傳統(tǒng)的業(yè)務(wù)處理代碼中,通常都會(huì)進(jìn)行事務(wù)處理,日志記錄等操作。雖然使用OOP可以通過組合或者繼承的方式來(lái)達(dá)到代碼的重用,但如果要實(shí)現(xiàn)某個(gè)功能(如日志記錄),同樣的代碼任然會(huì)分散到各個(gè)方法中。這樣,如果想關(guān)閉某個(gè)功能,或者對(duì)其進(jìn)行修改,就必須要修改多有的相關(guān)方法。這不但增加了開發(fā)人員的工作量,而且提高了代碼的出錯(cuò)率。
為了解決這一問題,AOP思想隨之產(chǎn)生。AOP采取橫向抽取機(jī)制,將分散在各個(gè)方法中的重復(fù)代碼提取出來(lái),然后在程序編譯運(yùn)行時(shí),再將這些提取出來(lái)的代碼應(yīng)用到需要執(zhí)行的地方。
12,Spring中Autowired和Resource關(guān)鍵字的區(qū)別?
@Autowired::用于對(duì)bean的屬性變量,屬性的setter方法及構(gòu)造方法進(jìn)行標(biāo)注,配合對(duì)應(yīng)的注解處理器完成bean的自動(dòng)配置工作。默認(rèn)按照bean的類型進(jìn)行裝配。
@Resource:作用與@Autowired一樣。兩個(gè)重要屬性:name和type。Spring將name屬性解析為Bean實(shí)例名稱,type屬性解析為Bean實(shí)例類型。如果指定name屬性,則按照實(shí)例名稱進(jìn)行裝配,如果是type屬性,則按照Bean類型進(jìn)行裝配;如果都不指定,則先按Bean實(shí)例名稱裝配,如果不能匹配,再按照Bean類型進(jìn)行裝配;如果都無(wú)法匹配,則拋出NoSuchBeanDefinitionException 異常。
區(qū)別在于@Autowired默認(rèn)按照Bean類型裝配,而@Resource默認(rèn)按照Bean實(shí)例名稱進(jìn)行裝配。
13,依賴注入的方式有幾種,各是什么?
屬性setter方法注入:通過調(diào)用無(wú)參構(gòu)造器或者無(wú)參靜態(tài)工廠方法實(shí)例化Bean后,調(diào)用Bean的setter方法,即可實(shí)現(xiàn)基于setter方法的依賴注入。
構(gòu)造方法注入:通過調(diào)用帶參數(shù)的構(gòu)造方法來(lái)實(shí)現(xiàn),每個(gè)參數(shù)代表著一個(gè)依賴。
14,Spring容器對(duì)bean組件是如何管理的?
Bean對(duì)象創(chuàng)建
默認(rèn)是隨著容器創(chuàng)建
可以使用 lazy-init=true:在調(diào)用 getBean 延遲創(chuàng)建
也可以用 <beans default-lazy-init="true"/> 批量延遲創(chuàng)建
Bean對(duì)象的創(chuàng)建模式
默認(rèn)是單例,可以使用scope屬性改變。
singleton:?jiǎn)卫看握{(diào)用getBean返回同一個(gè)對(duì)象
prototype:原型,每次調(diào)用getBean返回一個(gè)新的對(duì)象
Bean對(duì)象初始化和銷毀
init-method 屬性用于指定初始化方法
spring 容器創(chuàng)建完對(duì)象后,將會(huì)執(zhí)行 xml 文件中指定的初始化方法,單例模式中初始化方法只會(huì)執(zhí)行一次
destroy-method 屬性用于指定銷毀方法,僅適用于 singleton 模式,
在調(diào)用 AbstractApplicationContext 對(duì)象的 close() 方法時(shí)觸發(fā)
三種實(shí)例化bean的方式
1.使用類構(gòu)造器實(shí)例化
1 <bean id=“userService" class="service.UserService"/>
2.使用靜態(tài)工廠方法實(shí)例化
<bean id="userService" class="service.UserFactory" factory-method="createUser"/> public class UserFactory { public static UserService createUser(){ return new UserService(); } }
3.使用實(shí)例工廠方法實(shí)例化:
<bean id="userServiceFactory" class="service.UserFactory"/> <bean id="userService" factory-bean="userServiceFactory" factory-method="createUser"/> public class UserFactory { public UserService createUser(){ return new UserService(); } }
http://www.rzrgm.cn/loveer/p/11576408.html
15,Spring容器是如何創(chuàng)建的?
①BeanFactory
②ApplicationContext
1,通過ClassPathXmlApplicationContext創(chuàng)建
2,通過FileSystemXmlApplicationContext創(chuàng)建
16,SpringMVC如何處理JSON數(shù)據(jù)?
@RequestBody注解用于讀取http請(qǐng)求的內(nèi)容(字符串),通過springmvc提供的HttpMessageConverter接口將讀到的內(nèi)容(json數(shù)據(jù))轉(zhuǎn)換為java對(duì)象并綁定到Controller方法的形參上。
@ResponseBody注解用于將Controller的方法返回的對(duì)象,通過springmvc提供的HttpMessageConverter接口轉(zhuǎn)換為指定格式的數(shù)據(jù)如:json,xml等,通過Response響應(yīng)給客戶端。
17,SpringMVC攔截器原理,如何自定義攔截器?
瀏覽器請(qǐng)求
DispatcherServlet 執(zhí)行調(diào)用 doService(request, response) 作為 Servlet 主要執(zhí)行者,
doService(request, response) 通過調(diào)用 doDispatch(request, response) 來(lái)真正執(zhí)行請(qǐng)求處理
doDispatch(request, response) 中完成攔截器的添加和攔截器攔截處理
通過 getHandler(HttpServletRequest request) 獲取到 HandlerExecutionChain 處理器執(zhí)行鏈,
將攔截器注入到 HandlerExecutionChain 的屬性中。
分別調(diào)用 HandlerExecutionChain 的三個(gè)方法,applyPreHandle、applyPostHandle、triggerAfterCompletion,
實(shí)現(xiàn)前置攔截/請(qǐng)求提交攔截和請(qǐng)求完成后攔截。
使用責(zé)任鏈的設(shè)計(jì)模式,實(shí)際調(diào)用的是HandleInterceptor的三個(gè)接口,分別對(duì)應(yīng)
- preHandle
返回值為true:繼續(xù)執(zhí)行后面的攔截器或者Controller
返回值為false:不再執(zhí)行后面的攔截器和Controller,并調(diào)用返回true的攔截器的afterCompletion方法
- postHandle
在執(zhí)行完Controller方法之后,渲染視圖之前執(zhí)行,如果需要對(duì)響應(yīng)相關(guān)的數(shù)據(jù)進(jìn)行處理,可以選擇在該方法中完成
- afterCompletion
調(diào)用完Controller接口,渲染View頁(yè)面后調(diào)用。返回true的攔截器都會(huì)調(diào)用該攔截器的afterCompletion方法,順序相反。
自定義攔截器:
自定義攔截器一般繼承自HandlerInterceptorAdapter 或者實(shí)現(xiàn) HandlerInterceptor 接口。 實(shí)現(xiàn)接口需要實(shí)現(xiàn)對(duì)應(yīng)的3中方法,繼承父類只需要實(shí)現(xiàn)需要的方法即可。
詳細(xì)源碼分析:http://www.rzrgm.cn/loveer/p/11577949.html#766671773
https://www.jianshu.com/p/61eae2ad7320
18,SpringMVC常見注解有哪些?
Controller RequestMapping
組合注解:GetMapping PostMapping PutMapping DeleteMapping PatchMapping
19,MyBatis中#和$的區(qū)別?
#傳入的參數(shù)在SQL中顯示為字符串,#方式能夠很大程度防止sql注入;$傳入的參數(shù)在SqL中直接顯示為傳入的值,$方式無(wú)法防止Sql注入。

浙公網(wǎng)安備 33010602011771號(hào)