各种面试题(二)
轉(zhuǎn)載自??各種面試題(二)
1、面向?qū)ο蟮奶卣饔心男┓矫?/span>?
封裝:通常認(rèn)為封裝是把數(shù)據(jù)和操作數(shù)據(jù)的方法綁定起來,對數(shù)據(jù)的訪問只能通過已定義的接口。
多態(tài)性:多態(tài)性是指允許不同子類型的對象對同一消息作出不同的響應(yīng)。簡單的說就是用同樣的對象引用調(diào)用同樣的方法但是做了不同的事情。多態(tài)性分為編譯時(shí)的多態(tài)性和運(yùn)行時(shí)的多態(tài)性。方法重載(overload)實(shí)現(xiàn)的是編譯時(shí)的多態(tài)性(也稱為前綁定),而方法重寫(override)實(shí)現(xiàn)的是運(yùn)行時(shí)的多態(tài)性(也稱為后綁定)。
?
2、訪問修飾符public,private,protected,以及不寫(默認(rèn))時(shí)的區(qū)別?
作用域????當(dāng)前類??同包?子類?其他
public????????√????????√???????√??????√
protected??√????????√???????√??????×
default???????√???????√???????×??????×
private???????√????????×??????×??????×
類的成員不寫訪問修飾時(shí)默認(rèn)為default。默認(rèn)對于同一個(gè)包中的其他類相當(dāng)于公開 (public),對于不是同一個(gè)包中的其他類相當(dāng)于私有(private)。受保護(hù) (protected)對子類相當(dāng)于公開,對不是同一包中的沒有父子關(guān)系的類相當(dāng)于私有。
3、構(gòu)造器(constructor)是否可被重寫(override)?
答:構(gòu)造器不能被繼承,因此不能被重寫,但可以被重載。
4、兩個(gè)對象值相同(x.equals(y)?==?true),但卻可有不同的hash?code,這句話對不對?
答:不對,如果兩個(gè)對象x和y滿足x.equals(y)?==?true,它們的哈希碼(hash?code)應(yīng)當(dāng)相同。Java對于eqauls方法和hashCode方法是這樣規(guī)定的:(1)如果兩個(gè)對象相同(equals方法返回true),那么它們的hashCode值一定要相同;(2)如果兩個(gè)對象的hashCode相同,它們并不一定相同。
5、抽象類(abstract?class)和接口(interface)有什么異同?
答:抽象類和接口都不能夠?qū)嵗?#xff0c;但可以定義抽象類和接口類型的引用。一個(gè)類如果繼承了某個(gè)抽象類或者實(shí)現(xiàn)了某個(gè)接口都需要對其中的抽象方法全部進(jìn)?行實(shí)現(xiàn),否則該類仍然需要被聲明為抽象類。接口比抽象類更加抽象,因?yàn)槌橄箢愔锌梢远x構(gòu)造器,可以有抽象方法和具體方法,而接口中不能定義構(gòu)造器而且其?中的方法全部都是抽象方法。抽象類中的成員可以是private、默認(rèn)、protected、public的,而接口中的成員全都是public的。抽象?類中可以定義成員變量,而接口中定義的成員變量實(shí)際上都是常量。有抽象方法的類必須被聲明為抽象類,而抽象類未必要有抽象方法。抽象類和接口中都可以包含靜態(tài)成員變量。
6、抽象的(abstract)方法是否可同時(shí)是靜態(tài)的(static),是否可同時(shí)是本地方法(native),是否可同時(shí)被synchronized修飾?
答:都不能。抽象方法需要子類重寫,而靜態(tài)的方法是無法被重寫的,因此二者是矛盾的。本地方法是由本地代碼(如C代碼)實(shí)現(xiàn)的方法,而抽象方法是沒有實(shí)現(xiàn)的,也是矛盾的。synchronized和方法的實(shí)現(xiàn)細(xì)節(jié)有關(guān),抽象方法不涉及實(shí)現(xiàn)細(xì)節(jié),因此也是相互矛盾的。
7、接口是否可繼承(extends)接口??抽象類是否可實(shí)現(xiàn)(implements)接口??抽象類是否可繼承具體類(concrete?class)?
答:接口可以繼承接口。抽象類可以實(shí)現(xiàn)(implements)接口,抽象類可繼承具體類,但前提是具體類必須有明確的構(gòu)造函數(shù)。
8、Anonymous?Inner?Class(匿名內(nèi)部類)是否可以繼承其它類?是否可以實(shí)現(xiàn)接口?
答:可以繼承其他類或?qū)崿F(xiàn)其他接口,在Swing編程中常用此方式來實(shí)現(xiàn)事件監(jiān)聽和回調(diào)。
9、數(shù)據(jù)類型之間的轉(zhuǎn)換:
1)如何將字符串轉(zhuǎn)換為基本數(shù)據(jù)類型?
2)如何將基本數(shù)據(jù)類型轉(zhuǎn)換為字符串?
1)調(diào)用基本數(shù)據(jù)類型對應(yīng)的包裝類中的方法parseXXX(String)或valueOf(String)即可返回相應(yīng)基本類型;?Integer.parseInt(a)???Integer.valueOf(a)
2)一種方法是將基本數(shù)據(jù)類型與空字符串(””)連接(+)即可獲得其所對應(yīng)的字符串;另一種方法是調(diào)用String?類中的valueOf(…)方法返回相應(yīng)字符串?String.valueOf(int)???Integer.toString?
10、如何實(shí)現(xiàn)字符串的反轉(zhuǎn)及替換??
答:方法很多,可以自己寫實(shí)現(xiàn)也可以使用String或StringBuffer?/?StringBuilder中的方法。有一道很常見的面試題是用遞歸實(shí)現(xiàn)字符串反轉(zhuǎn),代碼如下所示:
[java]?view plain?copy
?1.public?static?String?reverse(String?originStr)?{????
?
11、列出一些你常見的運(yùn)行時(shí)異常??
答:
ArithmeticException(算術(shù)異常)
ClassCastException?(類轉(zhuǎn)換異常)
IllegalArgumentException?(非法參數(shù)異常)
IndexOutOfBoundsException?(下表越界異常)
NullPointerException?(空指針異常)
SecurityException?(安全異常)
12、List、Map、Set三個(gè)接口存取元素時(shí),各有什么特點(diǎn)??
答:List以特定索引來存取元素,可以有重復(fù)元素。Set不能存放重復(fù)元素(用對象的equals()方法來區(qū)分元素是否重復(fù))。Map保存鍵值對?(key-value?pair)映射,映射關(guān)系可以是一對一或多對一。Set和Map容器都有基于哈希存儲(chǔ)和排序樹的兩種實(shí)現(xiàn)版本,基于哈希存儲(chǔ)的版本理論存取時(shí)間復(fù)雜度為?O(1),而基于排序樹版本的實(shí)現(xiàn)在插入或刪除元素時(shí)會(huì)按照元素或元素的鍵(key)構(gòu)成排序樹從而達(dá)到排序和去重的效果。
13、什么是進(jìn)程,什么是線程?為什么需要多線程編程?
進(jìn)程是具有一定獨(dú)立功能的程序關(guān)于某個(gè)數(shù)據(jù)集合上的一次運(yùn)行活動(dòng),是操作系統(tǒng)進(jìn)行資源分配和調(diào)度的一個(gè)獨(dú)立單位;
線程是進(jìn)程的一個(gè)實(shí)體,是CPU調(diào)度和分?派的基本單位,是比進(jìn)程更小的能獨(dú)立運(yùn)行的基本單位。
線程的劃分尺度小于進(jìn)程,這使得多線程程序的并發(fā)性高;進(jìn)程在執(zhí)行時(shí)通常擁有獨(dú)立的內(nèi)存單元,而線程之間可以共享內(nèi)存。使用多線程的編程通常能夠帶來更好的性能和用戶體驗(yàn),但是多線程的程序?qū)τ谄渌绦蚴遣挥押玫?#xff0c;因?yàn)樗加昧烁嗟?/span>CPU資源。
14.闡述JDBC操作數(shù)據(jù)庫的步驟?
答:下面的代碼以連接本機(jī)的Oracle數(shù)據(jù)庫為例,演示JDBC操作數(shù)據(jù)庫的步驟。
1.?加載驅(qū)動(dòng)。
[java]?view plain?copy
?Class.forName("oracle.jdbc.driver.OracleDriver");??
?
2.?創(chuàng)建連接。
[java]?view plain?copy
?Connection?con?=?DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:orcl",?"scott",?"tiger");??
?
3.?創(chuàng)建語句。?
[java]?view plain?copy
?PreparedStatement?ps?=?con.prepareStatement("select?*?from?emp?where?sal?between???and??");?????
??ps.setInt(1,?1000);????
??ps.setInt(2,?3000);??
4.?執(zhí)行語句。
[java]?view plain?copy
?ResultSet?rs?=?ps.executeQuery();??
?
5.?處理結(jié)果。
[java]?view plain?copy
?while(rs.next())?{?????
?????System.out.println(rs.getInt("empno")?+?"?-?"?+?rs.getString("ename"));????}??
6.?關(guān)閉資源。
[java]?view plain?copy
?finally?{??????
?????if(con?!=?null)?{????????
???????try?{???????????????
????con.close();????????????
???}?catch?(SQLException?e)?{????????????????e.printStackTrace();????????????
???}????????
???}?????
??}??
15.Statement和PreparedStatement有什么區(qū)別?哪個(gè)性能更好??
與Statement相比
①PreparedStatement接口代表預(yù)編譯的語句,它主要的優(yōu)勢在于可以減少SQL的編譯錯(cuò)誤并增加SQL的安全性(減少SQL注射攻擊的可能性)
②PreparedStatement中的SQL語句是可以帶參數(shù)的,避免了用字符串連接拼接SQL語句的麻煩和不安全;
③當(dāng)批量處理SQL或頻繁執(zhí)行相同的查詢時(shí),PreparedStatement有明顯的性能上的優(yōu)勢,由于數(shù)據(jù)庫可以將編譯優(yōu)化后的SQL語句緩存起來,下次執(zhí)行相同結(jié)構(gòu)的語句時(shí)就會(huì)很快(不用再次編譯和生成執(zhí)行計(jì)劃)。
16、在進(jìn)行數(shù)據(jù)庫編程時(shí),連接池有什么作用??
????由于創(chuàng)建連接和釋放連接都有很大的開銷(尤其是數(shù)據(jù)庫服務(wù)器不在本地時(shí),每次建立連接都需要進(jìn)行TCP的三次握手,釋放連接需要進(jìn)行TCP四次握手,造成的開銷是不可忽視的),為了提升系統(tǒng)訪問數(shù)據(jù)庫的性能,可以事先創(chuàng)建若干連接置于連接池中,需要時(shí)直接從連接池獲取,使用結(jié)束時(shí)歸還連接池而不必關(guān)閉連接,從而避免頻繁創(chuàng)建和釋放連接所造成的開銷,這是典型的用空間換取時(shí)間的策略(浪費(fèi)了空間存儲(chǔ)連接,但節(jié)省了創(chuàng)建和釋放連接的時(shí)間)。池化技術(shù)在Java開發(fā)中是很常見的,在使用線程時(shí)創(chuàng)建線程池的道理與此相同。
17、Java中是如何支持正則表達(dá)式操作的??
答:Java中的String類提供了支持正則表達(dá)式操作的方法,包括:matches()、replaceAll()、replaceFirst()、split()。此外,Java中可以用Pattern類表示正則表達(dá)式對象,它提供了豐富的API進(jìn)行各種正則表達(dá)式操作,請參考下面面試題的代碼。
面試題:?-?如果要從字符串中截取第一個(gè)英文左括號之前的字符串,例如:北京市(朝陽區(qū))(西城區(qū))(海淀區(qū)),截取結(jié)果為:北京市,那么正則表達(dá)式怎么寫?
[java]?view plain?copy
?import?java.util.regex.Matcher;??
?import?java.util.regex.Pattern;??
?class?RegExpTest?{?????
??public?static?void?main(String[]?args){??
?String?str?=?"北京市(朝陽區(qū))(西城區(qū))(海淀區(qū))";???????
????Pattern?p?=?Pattern.compile(".*?(?=\\()");????????
???Matcher?m?=?p.matcher(str);????????
???if(m.find())?{??????????
?????System.out.println(m.group());????????}????
???}??
?}??
18、獲得一個(gè)類的類對象有哪些方式??
答:?
-?方法1:類型.class,例如:String.class?
-?方法2:對象.getClass(),例如:"hello".getClass()?
-?方法3:Class.forName(),例如:Class.forName("java.lang.String")
19、如何通過反射創(chuàng)建對象??
答:?
-?方法1:通過類對象調(diào)用newInstance()方法,例如:String.class.newInstance()?
-?方法2:通過類對象的getConstructor()或getDeclaredConstructor()方法獲得構(gòu)造器(Constructor)對象并調(diào)用其newInstance()方法創(chuàng)建對象,例如:String.class.getConstructor(String.class).newInstance("Hello");
20、如何通過反射調(diào)用對象的方法??
答:請看下面的代碼:
[java]?view plain?copy
?import?java.lang.reflect.Method;??
?class?MethodInvokeTest?{?????
??public?static?void?main(String[]?args)?throws?Exception?{??????
?????String?str?=?"hello";?????????
??Method?m?=?str.getClass().getMethod("toUpperCase");???????
????System.out.println(m.invoke(str));??
???//?HELLO?????
??}??
?}??
21、簡述一下面向?qū)ο蟮?/span>"六原則一法則"。?
答:?
1)單一職責(zé)原則:一個(gè)類只做它該做的事情。(單一職責(zé)原則想表達(dá)的就是"高內(nèi)聚",寫代碼最終極的原則只有六個(gè)字"高內(nèi)聚、低耦合")
2)開閉原則:軟件實(shí)體應(yīng)當(dāng)對擴(kuò)展開放,對修改關(guān)閉。(在理想的狀態(tài)下,當(dāng)我們需要為一個(gè)軟件系統(tǒng)增加新功能時(shí),只需要從原來的系統(tǒng)派生出一些新類就可以,不需要修改原來的任何一行代碼。要做到開閉有兩個(gè)要點(diǎn):①抽象是關(guān)鍵,一個(gè)系統(tǒng)中如果沒有抽象類或接口系統(tǒng)就沒有擴(kuò)展點(diǎn);②封裝可變性,將系統(tǒng)中的各種可變因素封裝到一個(gè)繼承結(jié)構(gòu)中,如果多個(gè)可變因素混雜在一起,系統(tǒng)將變得復(fù)雜而換亂)?
3)依賴倒轉(zhuǎn)原則:面向接口編程。(該原則說得直白和具體一些就是聲明方法的參數(shù)類型、方法的返回類型、變量的引用類型時(shí),盡可能使用抽象類型而不用具體類型,因?yàn)槌橄箢愋涂梢员凰娜魏我粋€(gè)子類型所替代)?
4)里氏替換原則:任何時(shí)候都可以用子類型替換掉父類型。(子類一定是增加父類的能力而不是減少父類的能力,因?yàn)樽宇惐雀割惖哪芰Ω?#xff0c;把能力多的對象當(dāng)成能力少的對象來用當(dāng)然沒有任何問題。)?
5)接口隔離原則:接口要小而專,絕不能大而全。(臃腫的接口是對接口的污染,既然接口表示能力,那么一個(gè)接口只應(yīng)該描述一種能力,接口也應(yīng)該是高度內(nèi)聚的。Java中的接口代表能力、代表約定、代表角色,能否正確的使用接口一定是編程水平高低的重要標(biāo)識(shí)。)?
6)合成聚合復(fù)用原則:優(yōu)先使用聚合或合成關(guān)系復(fù)用代碼。(通過繼承來復(fù)用代碼是面向?qū)ο蟪绦蛟O(shè)計(jì)中被濫用得最多的東西,記住:任何時(shí)候都不要繼承工具類,工具是可以擁有并可以使用的,而不是拿來繼承的。)?
迪米特法則:迪米特法則又叫最少知識(shí)原則,一個(gè)對象應(yīng)當(dāng)對其他對象有盡可能少的了解。(迪米特法則簡單的說就是如何做到"低耦合",門面模式和調(diào)停者模式就是對迪米特法則的踐行。Java?Web開發(fā)中作為前端控制器的Servlet或Filter不就是一個(gè)門面嗎,瀏覽器對服務(wù)器的運(yùn)作方式一無所知,但是通過前端控制器就能夠根據(jù)你的請求得到相應(yīng)的服務(wù)。調(diào)停者模式也可以舉一個(gè)簡單的例子來說明,例如一臺(tái)計(jì)算機(jī),CPU、內(nèi)存、硬盤、顯卡、聲卡各種設(shè)備需要相互配合才能很好的工作。迪米特法則用通俗的話來將就是不要和陌生人打交道,如果真的需要,找一個(gè)自己的朋友,讓他替你和陌生人打交道。)
22.簡述一下你了解的設(shè)計(jì)模式
-工廠模式:工廠類可以根據(jù)條件生成不同的子類實(shí)例,這些子類有一個(gè)公共的抽象父類并且實(shí)現(xiàn)了相同的方法,但是這些方法針對不同的數(shù)據(jù)進(jìn)行了不同的操作(多態(tài)方法)。當(dāng)?shù)玫阶宇惖膶?shí)例后,開發(fā)人員可以調(diào)用基類中的方法而不必考慮到底返回的是哪一個(gè)子類的實(shí)例。?
-?代理模式:給一個(gè)對象提供一個(gè)代理對象,并由代理對象控制原對象的引用。實(shí)際開發(fā)中,按照使用目的的不同,代理可以分為:遠(yuǎn)程代理、虛擬代理、保護(hù)代理、Cache代理、防火墻代理、同步化代理、智能引用代理。?
-?適配器模式:把一個(gè)類的接口變換成客戶端所期待的另一種接口,從而使原本因接口不匹配而無法在一起使用的類能夠一起工作。?
-?模板方法模式:提供一個(gè)抽象類,將部分邏輯以具體方法或構(gòu)造器的形式實(shí)現(xiàn),然后聲明一些抽象方法來迫使子類實(shí)現(xiàn)剩余的邏輯。不同的子類可以以不同的方式實(shí)現(xiàn)這些抽象方法(多態(tài)實(shí)現(xiàn)),從而實(shí)現(xiàn)不同的業(yè)務(wù)邏輯。?
23、用Java寫一個(gè)單例類。?
餓漢式單例
[java]?view plain?copy
?public?class?Singleton?{??
?????private?Singleton(){}?????
??private?static?Singleton?instance?=?new?Singleton();?????
??public?static?Singleton?getInstance(){????????return?instance;?????
??}??
?}??
懶漢式單例
[java]?view plain?copy
?public?class?Singleton?{??
?private?Singleton()?{}????
???private?static?Singleton?instance?=?null;??????
?????public?static?synchronized?Singleton?getInstance(){??????
?????if?(instance?==?null)??
??instance?=?new?Singleton();????????
???return?instance;?????
??}??
?}??
注意:實(shí)現(xiàn)一個(gè)單例有兩點(diǎn)注意事項(xiàng),①將構(gòu)造器私有,不允許外界通過構(gòu)造器創(chuàng)建對象;②通過公開的靜態(tài)方法向外界返回類的唯一實(shí)例。這里有一個(gè)問題可以思考:spring的IoC容器可以為普通的類創(chuàng)建單例,它是怎么做到的呢?
24.什么是DAO模式?
答:DAO(DataAccess?Object)顧名思義是一個(gè)為數(shù)據(jù)庫或其他持久化機(jī)制提供了抽象接口的對象,在不暴露數(shù)據(jù)庫實(shí)現(xiàn)細(xì)節(jié)的前提下提供了各種數(shù)據(jù)操作。將所有對數(shù)據(jù)源的訪問操作進(jìn)行抽象化后封裝在一個(gè)公共API中。在這個(gè)應(yīng)用程序中,當(dāng)需要和數(shù)據(jù)源進(jìn)行交互的時(shí)候則使用這個(gè)接口,并且編寫一個(gè)單獨(dú)的類來實(shí)現(xiàn)這個(gè)接口,在邏輯上該類對應(yīng)一個(gè)特定的數(shù)據(jù)存儲(chǔ)。DAO模式實(shí)際上包含了兩個(gè)模式,一是Data?Accessor(數(shù)據(jù)訪問器),二是Data?Object(數(shù)據(jù)對象),前者要解決如何訪問數(shù)據(jù)的問題,而后者要解決的是如何用對象封裝數(shù)據(jù)。
?
25.Servlet的生命周期
Web容器加載Servlet并將其實(shí)例化后,Servlet生命周期開始,容器運(yùn)行其init()方法進(jìn)行Servlet的初始化;請求到達(dá)時(shí)調(diào)用Servlet的service方法,service方法會(huì)調(diào)用與請求對應(yīng)的doGet或doPost等方法;當(dāng)服務(wù)器關(guān)閉會(huì)項(xiàng)目被卸載時(shí)服務(wù)器會(huì)將Servlet實(shí)例銷毀,此時(shí)會(huì)調(diào)用Servlet的destroy方法。
26.轉(zhuǎn)發(fā)(forward)和重定向(redirect)的區(qū)別?
1)forward是容器中控制權(quán)的轉(zhuǎn)向,是服務(wù)器請求資源,服務(wù)器直接訪問目標(biāo)地址的URL,把那個(gè)URL?的響應(yīng)內(nèi)容讀取過來,然后把這些內(nèi)容再發(fā)給瀏覽器,瀏覽器根本不知道服務(wù)器發(fā)送的內(nèi)容是從哪兒來的,所以它的地址欄中還是原來的地址。
2)redirect就是服務(wù)器端根據(jù)邏輯,發(fā)送一個(gè)狀態(tài)碼,告訴瀏覽器重新去請求那個(gè)地址,因此從瀏覽器的地址欄中可以看到跳轉(zhuǎn)后的鏈接地址。
3)前者更加高效,在前者可以滿足需要時(shí),盡量使用轉(zhuǎn)發(fā)(通過RequestDispatcher對象的forward方法,RequestDispatcher對象可以通過ServletRequest對象的getRequestDispatcher方法獲得),并且,這樣也有助于隱藏實(shí)際的鏈接;在有些情況下,比如,需要跳轉(zhuǎn)到一個(gè)其它服務(wù)器上的資源,則必須使用重定向(通過HttpServletResponse對象調(diào)用其sendRedirect方法)。
27.get和post請求的區(qū)別?
①get請求用來從服務(wù)器上獲得資源,而post是用來向服務(wù)器提交數(shù)據(jù);
②get將表單中數(shù)據(jù)按照name=value的形式,添加到action?所指向的URL?后面,并且兩者使用“?”連接,而各個(gè)變量之間使用“&”連接;post是將表單中的數(shù)據(jù)放在HTML頭部(header),傳遞到action所指向URL;
③get傳輸?shù)臄?shù)據(jù)要受到URL長度限制(1024字節(jié));而post可以傳輸大量的數(shù)據(jù),上傳文件只能使用post方式;
④使用get時(shí)參數(shù)會(huì)顯示在地址欄上,如果這些數(shù)據(jù)不是敏感數(shù)據(jù),那么可以使用get;對于敏感數(shù)據(jù)還是應(yīng)用使用post;
28、JSP?和Servlet?有有什么關(guān)系?
答:其實(shí)這個(gè)問題在上面已經(jīng)闡述過了,Servlet是一個(gè)特殊的Java程序,它運(yùn)行于服務(wù)器的JVM中,能夠依靠服務(wù)器的支持向?yàn)g覽器提供顯示內(nèi)容。??
JSP本質(zhì)上是Servlet的一種簡易形式,?JSP會(huì)被服務(wù)器處理成一個(gè)類似于Servlet的Java程序,可以簡化頁面內(nèi)容的生成。
Servlet和JSP最主要的不同點(diǎn)在于,Servlet?的應(yīng)用邏輯是在Java?文件中,并且完全從表示層中的HTML分離開來。而JSP的情況是Java和HTML可以組合成一個(gè)擴(kuò)展名為.jsp?的文件(有人說,Servlet就是在Java中寫HTML,而JSP就是在HTML中寫Java代碼,當(dāng)然,這個(gè)說法還是很片面的)。
JSP側(cè)重于視圖,Servlet更側(cè)重于控制邏輯,在MVC架構(gòu)模式中,JSP適合充當(dāng)視圖(view)而Servlet適合充當(dāng)控制器(controller)。
29、JSP中的四種作用域?
答:page、request、session和application,具體如下:
①page?代表與一個(gè)頁面相關(guān)的對象和屬性。
②request?代表與Web客戶機(jī)發(fā)出的一個(gè)請求相關(guān)的對象和屬性。一個(gè)請求可能跨越多個(gè)頁面,涉及多個(gè)Web?組件;需要在頁面顯示的臨時(shí)數(shù)據(jù)可以置于此作用域
③session代表與某個(gè)用戶與服務(wù)器建立的一次會(huì)話相關(guān)的對象和屬性。跟某個(gè)用戶相關(guān)的數(shù)據(jù)應(yīng)該放在用戶自己的session中
④application代表與整個(gè)Web應(yīng)用程序相關(guān)的對象和屬性,它實(shí)質(zhì)上是跨越整個(gè)Web應(yīng)用程序,包括多個(gè)頁面、請求和會(huì)話的一個(gè)全局作用域。
30.實(shí)現(xiàn)會(huì)話跟蹤的技術(shù)有哪些?
答:由于HTTP協(xié)議本身是無狀態(tài)的,服務(wù)器為了區(qū)分不同的用戶,就需要對用戶會(huì)話進(jìn)行跟蹤,簡單的說就是為用戶進(jìn)行登記,為用戶分配唯一的ID,下一次用戶在請求中包含此ID,服務(wù)器據(jù)此判斷到底是哪一個(gè)用戶。
①URL?重寫:在URL中添加用戶會(huì)話的信息作為請求的參數(shù),或者將唯一的會(huì)話ID添加到URL結(jié)尾以標(biāo)識(shí)一個(gè)會(huì)話。
②設(shè)置表單隱藏域:將和會(huì)話跟蹤相關(guān)的字段添加到隱式表單域中,這些信息不會(huì)在瀏覽器中顯示但是提交表單時(shí)會(huì)提交給服務(wù)器。
③cookie:cookie當(dāng)用戶通過瀏覽器和服務(wù)器建立一次會(huì)話后,會(huì)話ID就會(huì)隨響應(yīng)信息返回存儲(chǔ)在基于窗口的cookie中,那就意味著只要瀏覽器沒有關(guān)閉,會(huì)話沒有超時(shí),下一次請求時(shí)這個(gè)會(huì)話ID又會(huì)提交給服務(wù)器讓服務(wù)器識(shí)別用戶身份。會(huì)話中可以為用戶保存信息。會(huì)話對象是在服務(wù)器內(nèi)存中的,而基于窗口的cookie是在客戶端內(nèi)存中的。
④HttpSession:在所有會(huì)話跟蹤技術(shù)中,HttpSession對象是最強(qiáng)大也是功能最多的。當(dāng)一個(gè)用戶第一次訪問某個(gè)網(wǎng)站時(shí)會(huì)自動(dòng)創(chuàng)建HttpSession,每個(gè)用戶可以訪問他自己的HttpSession。與上面三種方式不同的是,HttpSession放在服務(wù)器的內(nèi)存中
31.JSP中的靜態(tài)包含和動(dòng)態(tài)包含有什么區(qū)別??
答:靜態(tài)包含是通過JSP的include指令包含頁面,動(dòng)態(tài)包含是通過JSP標(biāo)準(zhǔn)動(dòng)作<jsp:forward>包含頁面。靜態(tài)包含是編譯時(shí)包含,如果包含的頁面不存在則會(huì)產(chǎn)生編譯錯(cuò)誤,而且兩個(gè)頁面的"contentType"屬性應(yīng)保持一致,因?yàn)閮蓚€(gè)頁面會(huì)合二為一,只產(chǎn)生一個(gè)class文件,因此被包含頁面發(fā)生的變動(dòng)再包含它的頁面更新前不會(huì)得到更新。動(dòng)態(tài)包含是運(yùn)行時(shí)包含,可以向被包含的頁面?zhèn)鬟f參數(shù),包含頁面和被包含頁面是獨(dú)立的,會(huì)編譯出兩個(gè)class文件,如果被包含的頁面不存在,不會(huì)產(chǎn)生編譯錯(cuò)誤,也不影響頁面其他部分的執(zhí)行。代碼如下所示:
<%--?靜態(tài)包含?--%><%@?include?file="..."?%>?<%--?動(dòng)態(tài)包含?--%><jsp:include?page="...">????<jsp:param?name="..."?value="..."?/></jsp:include>
32、什么是Web?Service(Web服務(wù))??
答:從表面上看,Web?Service就是一個(gè)應(yīng)用程序,它向外界暴露出一個(gè)能夠通過Web進(jìn)行調(diào)用的API。例如可以創(chuàng)建一個(gè)提供天氣預(yù)報(bào)的Web?Service,那么無論你用哪種編程語言開發(fā)的應(yīng)用都可以通過調(diào)用它的API并傳入城市信息來獲得該城市的天氣預(yù)報(bào)。
補(bǔ)充:這里必須要提及的一個(gè)概念是SOA(Service-Oriented?Architecture,面向服務(wù)的架構(gòu))顯然,Web?Service是SOA的一種較好的解決方案,它更多的是一種標(biāo)準(zhǔn),而不是一種具體的技術(shù)。
33、hashmap和hashtable區(qū)別
???1.hashMap去掉了HashTable?的contains方法,但是加上了containsValue()和containsKey()方法。
???2.hashTable同步的,而HashMap是非同步的,效率上逼hashTable要高。
???3.hashMap允許空鍵值,而hashTable不允許。
?
34、Socket的通信機(jī)制?
套接字(socket)是通信的基石,是支持TCP/IP協(xié)議的網(wǎng)絡(luò)通信的基本操作單元。它是網(wǎng)絡(luò)通信過程中端點(diǎn)的抽象表示,包含進(jìn)行網(wǎng)絡(luò)通信必須的五種信息:連接使用的協(xié)議,本地主機(jī)的IP地址,本地進(jìn)程的協(xié)議端口,遠(yuǎn)地主機(jī)的IP地址,遠(yuǎn)地進(jìn)程的協(xié)議端口。
?
應(yīng)用層通過傳輸層進(jìn)行數(shù)據(jù)通信時(shí),TCP會(huì)遇到同時(shí)為多個(gè)應(yīng)用程序進(jìn)程提供并發(fā)服務(wù)的問題。多個(gè)TCP連接或多個(gè)應(yīng)用程序進(jìn)程可能需要通過同一個(gè)?
TCP協(xié)議端口傳輸數(shù)據(jù)。為了區(qū)別不同的應(yīng)用程序進(jìn)程和連接,許多計(jì)算機(jī)操作系統(tǒng)為應(yīng)用程序與TCP/IP協(xié)議交互提供了套接字(Socket)接口。應(yīng)用層可以和傳輸層通過Socket接口,區(qū)分來自不同應(yīng)用程序進(jìn)程或網(wǎng)絡(luò)連接的通信,實(shí)現(xiàn)數(shù)據(jù)傳輸?shù)牟l(fā)服務(wù)。
建立Socket連接至少需要一對套接字,其中一個(gè)運(yùn)行于客戶端,稱為ClientSocket?,另一個(gè)運(yùn)行于服務(wù)器端,稱為ServerSocket?。
套接字之間的連接過程分為三個(gè)步驟:服務(wù)器監(jiān)聽,客戶端請求,連接確認(rèn)。
?
服務(wù)器監(jiān)聽:服務(wù)器端套接字并不定位具體的客戶端套接字,而是處于等待連接的狀態(tài),實(shí)時(shí)監(jiān)控網(wǎng)絡(luò)狀態(tài),等待客戶端的連接請求。
?
客戶端請求:指客戶端的套接字提出連接請求,要連接的目標(biāo)是服務(wù)器端的套接字。為此,客戶端的套接字必須首先描述它要連接的服務(wù)器的套接字,指出服務(wù)器端套接字的地址和端口號,然后就向服務(wù)器端套接字提出連接請求。
?
連接確認(rèn):當(dāng)服務(wù)器端套接字監(jiān)聽到或者說接收到客戶端套接字的連接請求時(shí),就響應(yīng)客戶端套接字的請求,建立一個(gè)新的線程,把服務(wù)器端套接字的描述發(fā)給客戶端,一旦客戶端確認(rèn)了此描述,雙方就正式建立連接。而服務(wù)器端套接字繼續(xù)處于監(jiān)聽狀態(tài),繼續(xù)接收其他客戶端套接字的連接請求。
35、Http的通信機(jī)制?
HTTP協(xié)議即超文本傳送協(xié)議(Hypertext?Transfer?Protocol?
),是Web聯(lián)網(wǎng)的基礎(chǔ),也是手機(jī)聯(lián)網(wǎng)常用的協(xié)議之一,HTTP協(xié)議是建立在TCP協(xié)議之上的一種應(yīng)用。
?
HTTP連接最顯著的特點(diǎn)是客戶端發(fā)送的每次請求都需要服務(wù)器回送響應(yīng),在請求結(jié)束后,會(huì)主動(dòng)釋放連接。從建立連接到關(guān)閉連接的過程稱為“一次連接”。
?
1)在HTTP?1.0中,客戶端的每次請求都要求建立一次單獨(dú)的連接,在處理完本次請求后,就自動(dòng)釋放連接。
?
2)在HTTP?
1.1中則可以在一次連接中處理多個(gè)請求,并且多個(gè)請求可以重疊進(jìn)行,不需要等待一個(gè)請求結(jié)束后再發(fā)送下一個(gè)請求。
?
由于HTTP在每次請求結(jié)束后都會(huì)主動(dòng)釋放連接,因此HTTP連接是一種“短連接”,要保持客戶端程序的在線狀態(tài),需要不斷地向服務(wù)器發(fā)起連接請求。通常的做法是即時(shí)不需要獲得任何數(shù)據(jù),客戶端也保持每隔一段固定的時(shí)間向服務(wù)器發(fā)送一次“保持連接”的請求,服務(wù)器在收到該請求后對客戶端進(jìn)行回復(fù),表明知道客戶端“在線”。若服務(wù)器長時(shí)間無法收到客戶端的請求,則認(rèn)為客戶端“下線”,若客戶端長時(shí)間無法收到服務(wù)器的回復(fù),則認(rèn)為網(wǎng)絡(luò)已經(jīng)斷開。
由于通常情況下Socket連接就是TCP連接,因此Socket連接一旦建立,通信雙方即可開始相互發(fā)送數(shù)據(jù)內(nèi)容,直到雙方連接斷開。但在實(shí)際網(wǎng)絡(luò)應(yīng)用中,客戶端到服務(wù)器之間的通信往往需要穿越多個(gè)中間節(jié)點(diǎn),例如路由器、網(wǎng)關(guān)、防火墻等,大部分防火墻默認(rèn)會(huì)關(guān)閉長時(shí)間處于非活躍狀態(tài)的連接而導(dǎo)致?
Socket?連接斷連,因此需要通過輪詢告訴網(wǎng)絡(luò),該連接處于活躍狀態(tài)。
?
而HTTP連接使用的是“請求—響應(yīng)”的方式,不僅在請求時(shí)需要先建立連接,而且需要客戶端向服務(wù)器發(fā)出請求后,服務(wù)器端才能回復(fù)數(shù)據(jù)。
?
很多情況下,需要服務(wù)器端主動(dòng)向客戶端推送數(shù)據(jù),保持客戶端與服務(wù)器數(shù)據(jù)的實(shí)時(shí)與同步。此時(shí)若雙方建立的是Socket連接,服務(wù)器就可以直接將數(shù)據(jù)傳送給客戶端;若雙方建立的是HTTP連接,則服務(wù)器需要等到客戶端發(fā)送一次請求后才能將數(shù)據(jù)傳回給客戶端,因此,客戶端定時(shí)向服務(wù)器端發(fā)送連接請求,不僅可以保持在線,同時(shí)也是在“詢問”服務(wù)器是否有新的數(shù)據(jù),如果有就將數(shù)據(jù)傳給客戶端。
?
36、HttpServlet容器響應(yīng)Web客戶請求流程?
1)Web客戶向Servlet容器發(fā)出Http請求;
2)Servlet容器解析Web客戶的Http請求;
3)Servlet容器創(chuàng)建一個(gè)HttpRequest對象,在這個(gè)對象中封裝Http請求信息;
4)Servlet容器創(chuàng)建一個(gè)HttpResponse對象;
5)Servlet容器調(diào)用HttpServlet的service方法,這個(gè)方法中會(huì)根據(jù)request的Method來判斷具體是執(zhí)行doGet還是doPost,把HttpRequest和HttpResponse對象作為service方法的參數(shù)傳給HttpServlet對象;
6)HttpServlet調(diào)用HttpRequest的有關(guān)方法,獲取HTTP請求信息;
7)HttpServlet調(diào)用HttpResponse的有關(guān)方法,生成響應(yīng)數(shù)據(jù);
8)Servlet容器把HttpServlet的響應(yīng)結(jié)果傳給Web客戶
?
37、hibernate中Session的load和get方法的區(qū)別是什么??
答:主要有以下三項(xiàng)區(qū)別:?
①?如果沒有找到符合條件的記錄,get方法返回null,load方法拋出異常。?
②?get方法直接返回實(shí)體類對象,load方法返回實(shí)體類對象的代理。?
③?在Hibernate?3之前,get方法只在一級緩存中進(jìn)行數(shù)據(jù)查找,如果沒有找到對應(yīng)的數(shù)據(jù)則越過二級緩存,直接發(fā)出SQL語句完成數(shù)據(jù)讀取;load方法則可以從二級緩存中獲取數(shù)據(jù);從Hibernate?3開始,get方法不再是對二級緩存只寫不讀,它也是可以訪問二級緩存的。
說明:對于load()方法Hibernate認(rèn)為該數(shù)據(jù)在數(shù)據(jù)庫中一定存在可以放心的使用代理來實(shí)現(xiàn)延遲加載,如果沒有數(shù)據(jù)就拋出異常,而通過get()方法獲取的數(shù)據(jù)可以不存在。
38、如何理解Hibernate的延遲加載機(jī)制
答:延遲加載就是并不是在讀取的時(shí)候就把數(shù)據(jù)加載進(jìn)來,而是等到使用時(shí)再加載。Hibernate使用了虛擬代理機(jī)制實(shí)現(xiàn)延遲加載。返回給用戶的并不是實(shí)體本身,而是實(shí)體對象的代理。代理對象在用戶調(diào)用getter方法時(shí)就會(huì)去數(shù)據(jù)庫加載數(shù)據(jù)。
39、簡述Hibernate常見優(yōu)化策略。
①制定合理的緩存策略
②?采用合理的Session管理機(jī)制
③?盡量使用延遲加載特性
④如果可以,?選用基于version的樂觀鎖替代悲觀鎖
⑤在開發(fā)過程中,?開啟hibernate.show_sql選項(xiàng)查看生成的SQL,?從而了解底層的狀況;開發(fā)完成后關(guān)閉此選項(xiàng)
40、什么是IoC和DI?DI是如何實(shí)現(xiàn)的??
答:IoC叫控制反轉(zhuǎn),是Inversion?of?Control的縮寫,控制反轉(zhuǎn)是把傳統(tǒng)上由程序代碼直接操控的對象的調(diào)用權(quán)交給容器,通過容器來實(shí)現(xiàn)對象組件的裝配和管理。所謂的"控制反轉(zhuǎn)"就是對組件對象控制權(quán)的轉(zhuǎn)移,從程序代碼本身轉(zhuǎn)移到了外部容器,由容器來創(chuàng)建對象并管理對象之間的依賴關(guān)系。
控制反轉(zhuǎn)——Spring通過一種稱作控制反轉(zhuǎn)(IoC)的技術(shù)促進(jìn)了松耦合。當(dāng)應(yīng)用了IoC,一個(gè)對象依賴的其它對象會(huì)通過被動(dòng)的方式傳遞進(jìn)來,而不是這個(gè)對象自己創(chuàng)建或者查找依賴對象,是容器在對象初始化時(shí)不等對象請求就主動(dòng)將依賴傳遞給它。通過IOC反轉(zhuǎn)控制DI依賴注入完成各個(gè)層之間的注入,使得層與層之間實(shí)現(xiàn)完全脫耦,增加運(yùn)行效率利于維護(hù)。
?
41、解釋一下什么叫AOP(面向切面編程)??
答:
????spring的AOP面向切面編程,實(shí)現(xiàn)在不改變代碼的情況下完成對方法的增強(qiáng)。比較常用的就是spring的聲明式事務(wù)管理,底層通過AOP實(shí)現(xiàn),避免了我們每次都要手動(dòng)開啟事物,提交事務(wù)的重復(fù)性代碼,使得開發(fā)邏輯更加清晰。
???簡單點(diǎn)解釋,比方說你想在你的service層所有類中都加上一個(gè)打印‘你好’的功能這你經(jīng)可以用aop思想來做,你先寫個(gè)類寫個(gè)方法,方法經(jīng)實(shí)現(xiàn)打印‘你好’然后你Ioc這個(gè)類?ref=“service.*”讓每個(gè)類都注入。
???aop就是面向切面的編程。比如說你每做一次對數(shù)據(jù)庫操作,都要生成一句日志。如果,你對數(shù)據(jù)庫的操作有很多類,那你每一類中都要寫關(guān)于日志的方法。但是如果你用aop,那么你可以寫一個(gè)方法,在這個(gè)方法中有關(guān)于數(shù)據(jù)庫操作的方法,每一次調(diào)用這個(gè)方法的時(shí)候,就加上生成日志的操作。
?
42、選擇使用Spring框架的原因(Spring框架為企業(yè)級開發(fā)帶來的好處)?
答:可以從以下幾個(gè)方面作答:
1.?IoC容器:IoC容器幫助應(yīng)用程序管理對象以及對象之間的依賴關(guān)系,對象之間的依賴關(guān)系如果發(fā)生了改變只需要修改配置文件而不是修改代碼,因?yàn)榇a的修改可能意味著項(xiàng)目的重新構(gòu)建和完整的回歸測試。有了IoC容器,程序員再也不需要自己編寫工廠、單例,這一點(diǎn)特別符合Spring的精神“不要重復(fù)的發(fā)明輪子”。
2.?AOP:面向切面編程,將所有的橫切關(guān)注功能封裝到切面(aspect)中,通過配置的方式將橫切關(guān)注功能動(dòng)態(tài)添加到目標(biāo)代碼上,進(jìn)一步實(shí)現(xiàn)了業(yè)務(wù)邏輯和系統(tǒng)服務(wù)之間的分離。另一方面,有了AOP程序員可以省去很多自己寫代理類的工作。
3.?MVC:Spring的MVC框架是非常優(yōu)秀的,從各個(gè)方面都可以甩Struts?2幾條街,為Web表示層提供了更好的解決方案。
4.?事務(wù)管理:Spring以寬廣的胸懷接納多種持久層技術(shù),并且為其提供了聲明式的事務(wù)管理,在不需要任何一行代碼的情況下就能夠完成事務(wù)管理。
?43、?簡述攔截器的工作原理以及你在項(xiàng)目中使用過哪些自定義攔截器
答:Struts?2中定義了攔截器的接口以及默認(rèn)實(shí)現(xiàn),實(shí)現(xiàn)了Interceptor接口或繼承了AbstractInterceptor的類可以作為攔截器。接口中的init()方法在攔截器被創(chuàng)建后立即被調(diào)用,它在攔截器的生命周期內(nèi)只被調(diào)用一次,可以在該方法中對相關(guān)資源進(jìn)行必要的初始化。每攔截一個(gè)請求,intercept()方法就會(huì)被調(diào)用一次。destory()方法將在攔截器被銷毀之前被調(diào)用,?它在攔截器的生命周期內(nèi)也只被調(diào)用一次。
項(xiàng)目中使用過的有權(quán)限攔截器、執(zhí)行時(shí)間攔截器、令牌攔截器等。
44、談一下攔截器和過濾器的區(qū)別
答:攔截器和過濾器都可以用來實(shí)現(xiàn)橫切關(guān)注功能,其區(qū)別主要在于:
1、攔截器是基于java反射機(jī)制的,而過濾器是基于函數(shù)回調(diào)的。
2、過濾器依賴于servlet容器,而攔截器不依賴于servlet容器。
3、攔截器只能對Action請求起作用,而過濾器則可以對幾乎所有請求起作用。
4、攔截器可以訪問Action上下文、值棧里的對象,而過濾器不能。
5、在Action的生命周期中,攔截器可以多次調(diào)用,而過濾器只能在容器初始化時(shí)被調(diào)用一次。
?過濾器,是在java?web中,你傳入的request,response提前過濾掉一些信息,或者提前設(shè)置一些參數(shù),然后再傳入servlet或者struts的?action進(jìn)行業(yè)務(wù)邏輯,比如過濾掉非法url(不是login.do的地址請求,如果用戶沒有登陸都過濾掉),或者在傳入servlet或者struts的action前統(tǒng)一設(shè)置字符集,或者去除掉一些非法字符.
??攔截器,是在面向切面編程的就是在你的service或者一個(gè)方法,前調(diào)用一個(gè)方法,或者在方法后調(diào)用一個(gè)方法比如動(dòng)態(tài)代理就是攔截器的簡單實(shí)現(xiàn),在你調(diào)用方法前打印出字符串(或者做其它業(yè)務(wù)邏輯的操作),也可以在你調(diào)用方法后打印出字符串,甚至在你拋出異常的時(shí)候做業(yè)務(wù)邏輯的操作。
執(zhí)行順序:過濾前?-?攔截前?-?Action處理?-?攔截后?-?過濾后。
個(gè)人認(rèn)為過濾是一個(gè)橫向的過程,首先把客戶端提交的內(nèi)容進(jìn)行過濾(例如未登錄用戶不能訪問內(nèi)部頁面的處理);過濾通過后,攔截器將檢查用戶提交數(shù)據(jù)的驗(yàn)證,做一些前期的數(shù)據(jù)處理,接著把處理后的數(shù)據(jù)發(fā)給對應(yīng)的Action;Action處理完成返回后,攔截器還可以做其他過程(還沒想到要做啥),再向上返回到過濾器的后續(xù)操作。
?
45、struts1.2和struts2.0的區(qū)別?
???struts1.2和struts2.0的對比
???a、Action類:
??????struts1.2要求Action類繼承一個(gè)基類。struts2.0?Action要求繼承ActionSupport基類
???b、線程模式
??????struts1.2?Action是單例模式的并且必須是線程安全的,因?yàn)閮H有一個(gè)Action的實(shí)例來處理所有的請求。?struts2.0?Action為每一個(gè)請求產(chǎn)生一個(gè)實(shí)例,因此沒有線程安全問題。
???c、Servlet依賴
??????struts1.2?Action依賴于Servlet?API,因?yàn)楫?dāng)一個(gè)Action被調(diào)用時(shí)HttpServletRequest和HttpServletResponse被傳遞給execut方法。?struts2.0?Action不依賴于容器,允許Action脫離容器單獨(dú)測試。
?
46、常見的網(wǎng)絡(luò)協(xié)議有哪些?
????1.IP協(xié)議:互聯(lián)網(wǎng)協(xié)議
主要用于負(fù)責(zé)IP尋址、路由選擇和IP數(shù)據(jù)包的分割和組裝。通常我們所說的IP地址可以理解為符合IP協(xié)議的地址。
????2.TCP協(xié)議:傳輸控制協(xié)議
????該協(xié)議主要用于在主機(jī)間建立一個(gè)虛擬連接,以實(shí)現(xiàn)高可靠性的數(shù)據(jù)包交換。IP協(xié)議可以進(jìn)行IP數(shù)據(jù)包的分割和組裝,但是通過IP協(xié)議并不能清楚地了解到數(shù)據(jù)包是否順利地發(fā)送給目標(biāo)計(jì)算機(jī)。而使用TCP協(xié)議就不同了,在該協(xié)議傳輸模式中在將數(shù)據(jù)包成功發(fā)送給目標(biāo)計(jì)算機(jī)后,TCP會(huì)要求發(fā)送一個(gè)確認(rèn);如果在某個(gè)時(shí)限內(nèi)沒有收到確認(rèn),那么TCP將重新發(fā)送數(shù)據(jù)包。另外,在傳輸?shù)倪^程中,如果接收到無序、丟失以及被破壞的數(shù)據(jù)包,TCP還可以負(fù)責(zé)恢復(fù)。
????3.FTP(File?Transfer?Protocol):遠(yuǎn)程文件傳輸協(xié)議,允許用戶將遠(yuǎn)程主機(jī)上的文件拷貝到自己的計(jì)算機(jī)上。
????4.HTTP:超文本傳輸協(xié)議(HTTP,HyperText?Transfer?Protocol)是互聯(lián)網(wǎng)上應(yīng)用最為廣泛的一種網(wǎng)絡(luò)協(xié)議。所有的WWW文件都必須遵守這個(gè)標(biāo)準(zhǔn)。設(shè)計(jì)HTTP最初的目的是為了提供一種發(fā)布和接收HTML頁面的方法。
????5.ARP協(xié)議:AddressResolutionProtocol地址解析協(xié)議
簡單地說,ARP協(xié)議主要負(fù)責(zé)將局域網(wǎng)中的32為IP地址轉(zhuǎn)換為對應(yīng)的48位物理地址,即網(wǎng)卡的MAC地址。
?
47、計(jì)算機(jī)網(wǎng)絡(luò)分層,每層所用協(xié)議,協(xié)議所占端口
(1)應(yīng)用層:與其他計(jì)算機(jī)進(jìn)行通訊的一個(gè)應(yīng)用,它是對應(yīng)應(yīng)用程序的通信服務(wù)的。示例:telnet,HTTP,FTP,WWW,NFS,SMTP等。?
????(2)表示層:這一層的主要功能是定義數(shù)據(jù)格式及加密。示例:加密,ASII等。?
????(3)會(huì)話層:他定義了如何開始、控制和結(jié)束一個(gè)會(huì)話,包括對多個(gè)雙向小時(shí)的控制和管理,以便在只完成連續(xù)消息的一部分時(shí)可以通知應(yīng)用,從而使表示層看到的數(shù)據(jù)是連續(xù)的。示例:RPC,SQL等。?
???(4)傳輸層:這層的功能包括是否選擇差錯(cuò)恢復(fù)協(xié)議還是無差錯(cuò)恢復(fù)協(xié)議,及在同一主機(jī)上對不同應(yīng)用的數(shù)據(jù)流的輸入進(jìn)行復(fù)用,還包括對收到的順序不對的數(shù)據(jù)包的重新排序功能。示例:TCP,UDP,SPX。?
???(5)網(wǎng)絡(luò)層:這層對端到端的包傳輸進(jìn)行定義,他定義了能夠標(biāo)識(shí)所有結(jié)點(diǎn)的邏輯地址,還定義了路由實(shí)現(xiàn)的方式和學(xué)習(xí)的方式。。示例:IP,IPX等。?
???(6)數(shù)據(jù)鏈路層:他定義了在單個(gè)鏈路上如何傳輸數(shù)據(jù)。
???(7)物理層:OSI的物理層規(guī)范是有關(guān)傳輸介質(zhì)的特性標(biāo)準(zhǔn),這些規(guī)范通常也參考了其他組織制定的標(biāo)準(zhǔn)。
?
48、html訪問全過程
A)解析Web頁面的URL,得到Web服務(wù)器的域名
????B)通過DNS服務(wù)器獲得Web服務(wù)器的IP地址
I)與Web服務(wù)器建立TCP連接
????E)與Web服務(wù)器建立HTTP連接
C)從Web服務(wù)器獲得URL指定的文檔
????G)瀏覽器解釋頁面文檔,并顯示在屏幕
?
49、classloader原理
????1.classLoader的介紹及加載過程
與普通程序不同的是,Java程序(class文件)并不是本地的可執(zhí)行程序。當(dāng)運(yùn)行Java程序時(shí),首先運(yùn)行JVM(Java虛擬機(jī)),然后再把Java?class加載到JVM里頭運(yùn)行,負(fù)責(zé)加載Java?class的這部分就叫做Class?Loader。所以classLoader的目的在于把class文件裝入到jvm中。
那么classLoader又在那里的啦?又由誰調(diào)用呢?其實(shí)classLoader只是jvm的一個(gè)實(shí)現(xiàn)的一部分。Jvm提供的一個(gè)頂級的classLoader(bootStrap?classLoader),bootStrap?classLoader負(fù)責(zé)加載java核心的API以滿足java程序最基本的需求。Jvm還提供的兩個(gè)classLoader,其中Extension?ClassLoader負(fù)責(zé)加載擴(kuò)展的Java?class,Application?ClassLoader負(fù)責(zé)加載應(yīng)用程序自身的類。而Extension?ClassLoader和Application?ClassLoader則由bootStrap?classLoader加載。
2.classLoader加載的基本流程
???當(dāng)運(yùn)行一個(gè)程序的時(shí)候,JVM啟動(dòng),運(yùn)行bootstrap?classloader,該ClassLoader加載java核心API(ExtClassLoader和AppClassLoader也在此時(shí)被加載),然后調(diào)用ExtClassLoader加載擴(kuò)展API,最后AppClassLoader加載CLASSPATH目錄下定義的Class,這就是一個(gè)程序最基本的加載流程。
3.classLoader加載的方式
???其實(shí)classLoader在加載class文件的時(shí)候就采用的雙親委托模式。每一個(gè)自定義ClassLoader都必須繼承ClassLoader這個(gè)抽象類,而每個(gè)ClassLoader都會(huì)有一個(gè)parent?ClassLoader,我們可以看一下ClassLoader這個(gè)抽象類中有一個(gè)getParent()方法,這個(gè)方法用來返回當(dāng)前ClassLoader的parent。
?
50、快速排序原理
?原理:
????快速排序也是分治法思想的一種實(shí)現(xiàn),他的思路是使數(shù)組中的每個(gè)元素與基準(zhǔn)值(Pivot,通常是數(shù)組的首個(gè)值,A[0])比較,數(shù)組中比基準(zhǔn)值小的放在基準(zhǔn)值的左邊,形成左部;大的放在右邊,形成右部;接下來將左部和右部分別遞歸地執(zhí)行上面的過程:選基準(zhǔn)值,小的放在左邊,大的放在右邊。。。直到排序結(jié)束。
?步驟:
1.找基準(zhǔn)值,設(shè)Pivot?=?a[0]?
2.分區(qū)(Partition):比基準(zhǔn)值小的放左邊,大的放右邊,基準(zhǔn)值(Pivot)放左部與右部的之間。
3.進(jìn)行左部(a[0]?-?a[pivot-1])的遞歸,以及右部(a[pivot+1]?-?a[n-1])的遞歸,重復(fù)上述步驟。
//快速排序 void quick_sort(int s[], int l, int r) { if (l < r) { //Swap(s[l], s[(l + r) / 2]); //將中間的這個(gè)數(shù)和第一個(gè)數(shù)交換 參見注1 int i = l, j = r, x = s[l]; while (i < j) { while(i < j && s[j] >= x) // 從右向左找第一個(gè)小于x的數(shù) j--; if(i < j) s[i++] = s[j]; while(i < j && s[i] < x) // 從左向右找第一個(gè)大于等于x的數(shù) i++; if(i < j) s[j--] = s[i]; } s[i] = x; quick_sort(s, l, i - 1); // 遞歸調(diào)用 quick_sort(s, i + 1, r); } }51、各種集合類之間的區(qū)別
1.ArrayList:?元素單個(gè),效率高,多用于查詢
2.Vector:??元素單個(gè),線程安全,多用于查詢
3.LinkedList:元素單個(gè),多用于插入和刪除
4.HashMap:??元素成對,元素可為空
5.HashTable:?元素成對,線程安全,元素不可為空
?
52、內(nèi)存溢出和內(nèi)存泄漏
????內(nèi)存溢出是指已有的數(shù)據(jù)超過了其獲得到的內(nèi)存所能存儲(chǔ)的范圍,比如用一個(gè)字節(jié)存放1000這個(gè)數(shù)字就屬于內(nèi)存溢出。比如說你申請了一個(gè)integer,但給它存了long才能存下的數(shù),那就是內(nèi)存溢出。
????Java內(nèi)存泄漏就是沒有及時(shí)清理內(nèi)存垃圾,導(dǎo)致系統(tǒng)無法再給你提供內(nèi)存資源(內(nèi)存資源耗盡)。Java內(nèi)存泄露是說程序邏輯問題,造成申請的內(nèi)存無法釋放.這樣的話無論多少內(nèi)存,早晚都會(huì)被占用光的.最簡單的例子就是死循環(huán)了.由于程序判斷錯(cuò)誤導(dǎo)經(jīng)常發(fā)生此事。
?
53、jvm布局
????以下是JVM的一個(gè)基本架構(gòu)圖,在這個(gè)基本架構(gòu)圖中,棧有兩部份,Java線程棧以及本地方法棧
?
?
在JVM中堆空間劃分如下圖所示
?
?
?
上圖中,刻畫了Java程序運(yùn)行時(shí)的堆空間,可以簡述成如下2條
1.JVM中堆空間可以分成三個(gè)大區(qū),新生代、老年代、永久代
2.新生代可以劃分為三個(gè)區(qū),Eden區(qū),兩個(gè)幸存區(qū)
Jvm主要包括下面兩面方面:
·?Java代碼編譯和執(zhí)行的整個(gè)過程
·?JVM內(nèi)存管理及垃圾回收機(jī)制
54、在瀏覽器中輸入www.baidu.com后執(zhí)行的全部過程
1、客戶端瀏覽器通過DNS解析到www.baidu.com的IP地址220.181.27.48,通過這個(gè)IP地址找到客戶端到服務(wù)器的路徑??蛻舳藶g覽器發(fā)起一個(gè)HTTP會(huì)話到220.161.27.48,然后通過TCP進(jìn)行封裝數(shù)據(jù)包,輸入到網(wǎng)絡(luò)層。
2、在客戶端的傳輸層,把HTTP會(huì)話請求分成報(bào)文段,添加源和目的端口,如服務(wù)器使用80端口監(jiān)聽客戶端的請求,客戶端由系統(tǒng)隨機(jī)選擇一個(gè)端口如5000,與服務(wù)器進(jìn)行交換,服務(wù)器把相應(yīng)的請求返回給客戶端的5000端口。然后使用IP層的IP地址查找目的端。
3、客戶端的網(wǎng)絡(luò)層不用關(guān)系應(yīng)用層或者傳輸層的東西,主要做的是通過查找路由表確定如何到達(dá)服務(wù)器,期間可能經(jīng)過多個(gè)路由器,這些都是由路由器來完成的工作,我不作過多的描述,無非就是通過查找路由表決定通過那個(gè)路徑到達(dá)服務(wù)器。
4、客戶端的鏈路層,包通過鏈路層發(fā)送到路由器,通過鄰居協(xié)議查找給定IP地址的MAC地址,然后發(fā)送ARP請求查找目的地址,如果得到回應(yīng)后就可以使用ARP的請求應(yīng)答交換的IP數(shù)據(jù)包現(xiàn)在就可以傳輸了,然后發(fā)送IP數(shù)據(jù)包到達(dá)服務(wù)器的地址。
總結(jié)
- 上一篇: 伤敌一千自损八百的意思是什么 伤敌一千自
- 下一篇: 在Eclipse中使用JUnit4进行单