全國咨詢(xún)熱線(xiàn):400-009-1906

第一篇:面試題匯總

Java基礎、語(yǔ)法
1.Java跨平臺原理(字節碼文件、虛擬機) 2.Java的安全性 3.Java三大版本 4.什么是JVM?什么是JDK? 什么是JRE? 5.Java三種注釋類(lèi)型 6.8種基本數據類(lèi)型及其字節數 7.i++和++i的異同之處 8.&和&&的區別和聯(lián)系,|和||的區別和聯(lián)系 9.用最有效率的方法算出2乘以8等于多少 10.基本數據類(lèi)型的類(lèi)型轉換規則 11.if多分支語(yǔ)句和switch多分支語(yǔ)句的異同之處 12.while和do-while循環(huán)的區別 13.break和continue的作用 14.請使用遞歸算法計算n! 15.遞歸的定義和優(yōu)缺點(diǎn) 16.數組的特征 17.請寫(xiě)出冒泡排序代碼 18.請寫(xiě)出選擇排序的代碼 19.請寫(xiě)出插入排序的代碼 20.可變參數的作用和特點(diǎn) 21.類(lèi)和對象的關(guān)系 22.面向過(guò)程和面向對象的區別 23.this和super關(guān)鍵字的作用 24.static關(guān)鍵字的作用 25.final和abstract關(guān)鍵字的作用 26.final、finally、finalize的區別 27.寫(xiě)出java.lang.Object類(lèi)的六個(gè)常用方法 28.private/默認/protected/public權限修飾符的區別 29.繼承條件下構造方法的執行過(guò)程 30.==和equals的區別和聯(lián)系 31.談?wù)凧ava的多態(tài) 32.簡(jiǎn)述Java的垃圾回收機制 33.基本數據類(lèi)型和包裝類(lèi) 34.Integer與int的區別 35.java.sql.Date和java.util.Date的聯(lián)系和區別 36.使用遞歸算法輸出某個(gè)目錄下所有文件和子目錄列表 37.關(guān)于Java編譯,下面哪一個(gè)正確()(選擇一項) 38.下列說(shuō)法正確的有()(選擇一項) 39.Java中接口的修飾符可以為()(選擇一項) 40.給定以下代碼,程序將輸出 ()(選擇一項) 41.下列關(guān)于關(guān)鍵字的使用說(shuō)法錯誤的是()(選擇一項) 42.下列哪些語(yǔ)句關(guān)于內存回收的說(shuō)法是正確的()(選擇一項) 43.選出合理的標識符()(選擇兩項) 44.下列說(shuō)法正確的是()(選擇多項) 45.定義一個(gè)類(lèi)名為”MyClass.java”的類(lèi),并且該類(lèi)可被一個(gè)工程中的所有類(lèi)訪(fǎng)問(wèn),那么該類(lèi)的正確聲明為()(選擇兩項) 46.面向對象的特征有哪些方面?請用生活中的例子來(lái)描述。 47.說(shuō)明內存泄漏和內存溢出的區別和聯(lián)系,結合項目經(jīng)驗描述Java程序中如何檢測?如何解決? 48.什么是Java的序列化,如何實(shí)現Java的序列化?列舉在哪些程序中見(jiàn)過(guò)Java序列化? 49.不通過(guò)構造函數也能創(chuàng )建對象嗎? 50.匿名內部類(lèi)可不可以繼承或實(shí)現接口。為什么? 在Java中,為什么基本類(lèi)型不能做為HashMap的鍵值,而只能是引用類(lèi)型,把引用類(lèi)型做為HashMap的健值,需要注意哪些地方。 52.簡(jiǎn)述Java中如何實(shí)現多態(tài) 53.以下對繼承的描述錨誤的是 () 54.Java 中 Math.random()/Math.random()值為? 55.Java中,如果Manager是Employee的子類(lèi),那么Pair< Manager>是Pair< Employee>的子類(lèi)嗎? 56.接口和抽象類(lèi)的區別 57.同步代碼塊和同步方法有什么區別 58.靜態(tài)內部類(lèi)和內部類(lèi)有什么區別 59.反射的概念與作用 60.提供Java存取數據庫能力的包是() 61.下列運算符合法的是()(多選) 62.執行如下程序代碼,c的值打印出來(lái)是() 63.下列哪一種敘述是正確的() 64.下列語(yǔ)句正確的是() 65.下列哪種說(shuō)法是正確的() 66.Java程序的種類(lèi)有()(多選) 67.下列說(shuō)法正確的有()(多選) 68.下列標識符不合法的有()(多選) 69.下列說(shuō)法錯誤的有()(多選) 70.不能用來(lái)修飾interface的有()(多選) 71.下列正確的有()(多選) 72.下列說(shuō)法錯誤的有()(多選) 73.下列說(shuō)法錯誤的有()(多選) 74.下列說(shuō)法錯誤的有()(多選) 75.請問(wèn)0.3332的數據類(lèi)型是() 76.Java接口的修飾符可以為() 77.不通過(guò)構造函數也能創(chuàng )建對象么() 78.存在使i+1< i的數么? 79.接口可否繼承接口?抽象類(lèi)是否可實(shí)現接口?抽象類(lèi)是否可繼承實(shí)體類(lèi)? 80.int與Integer有什么區別? 81.可序列化對象為什么要定義serialversionUID值? 82.寫(xiě)一個(gè)Java正則,能過(guò)濾出html中的 < a href=”url” >title< /a>形式中的鏈接地址和標題. 83.十進(jìn)制數72轉換成八進(jìn)制數是多少? 84.Java程序中創(chuàng )建新的類(lèi)對象,使用關(guān)鍵字new,回收無(wú)用的類(lèi)對象使用關(guān)鍵字free正確么? 85.Class類(lèi)的getDeclaredFields()方法與getFields()的區別? 86.在switch和if-else語(yǔ)句之間進(jìn)行選取,當控制選擇的條件不僅僅依賴(lài)于一個(gè)x時(shí),應該使用switch結構;正確么? 88.使用final關(guān)鍵字修飾符一個(gè)變量時(shí),是引用不能變,還是引用的對象不能變? 88.使用final關(guān)鍵字修飾符一個(gè)變量時(shí),是引用不能變,還是引用的對象不能變? 89.請解釋以下常用正則含義:\d,\D,\s,.,*,?,|,[0-9]{6},\d+ 90.已知表達式int m[] = {0,1,2,3,4,5,6}; 下面那個(gè)表達式的值與數組的長(cháng)度相等() 91.下面那些聲明是合法的?() 92.以下選項中選擇正確的java表達式() 93.下列代碼的輸出結果是 94.以下哪些運算符是含有短路運算機制的?請選擇:() 95.下面哪個(gè)函數是public void example(){....}的重載函數?() 96.給定某java程序片段,該程序運行后,j的輸出結果為() 97.在java中,無(wú)論測試條件是什么,下列()循環(huán)將至少執行一次。 98.打印結果: 99.指出下列程序的運行結果 100.解釋繼承、重載、覆蓋。 101.什么是編譯型語(yǔ)言,什么是解釋型語(yǔ)言?java可以歸類(lèi)到那種? 102.簡(jiǎn)述操作符(&,|)與操作符(&&,||)的區別 &和&&的聯(lián)系(共同點(diǎn)) 103.try{}里面有一個(gè)return語(yǔ)句,那么緊跟在這個(gè)try后的finally, 里面的語(yǔ)句在異常出現后,都會(huì )執行么?為什么? 104.有一段java應用程序,它的主類(lèi)名是al,那么保存它的源文件可以是?() 105.Java類(lèi)可以作為() 106.在調用方法時(shí),若要使方法改變實(shí)參的值,可以?() 107.Java語(yǔ)言具有許多優(yōu)點(diǎn)和特點(diǎn),哪個(gè)反映了java程序并行機制的() 108.下關(guān)于構造函數的描述錯誤是() 109.若需要定義一個(gè)類(lèi)域或類(lèi)方法,應使用哪種修飾符?() 110.下面代碼執行后的輸出是什么() 111.給出如下代碼,如何使成員變量m被函數fun()直接訪(fǎng)問(wèn)() 112.下面哪幾個(gè)函數是public void example(){….}的重載函數() 113.請問(wèn)以下代碼執行會(huì )打印出什么? 114.如果有兩個(gè)類(lèi)A、B(注意不是接口),你想同時(shí)使用這兩個(gè)類(lèi)的功能,那么你會(huì )如何編寫(xiě)這個(gè)C類(lèi)呢? 115.一個(gè)類(lèi)的構造方法是否可以被重載(overloading),是否可以被子類(lèi)重寫(xiě)(overrding)? 116.Java中byte表示的數值范圍是什么? 117.如何將日期類(lèi)型格式化為:2013-02-18 10:53:10? 118.不通過(guò)構造函數也能創(chuàng )建對象嗎() 119.下面哪些是對稱(chēng)加密算法() 120.下面的代碼段,當輸入為2的時(shí)候返回值是() 121.以下Java代碼段會(huì )產(chǎn)生幾個(gè)對象 122.Math.round(-11.2)的運行結果是。 123.十進(jìn)制數278的對應十六進(jìn)制數 124.Java中int.long占用的字節數分別是 125.System.out.println(‘a(chǎn)’+1);的結果是 126.下列語(yǔ)句那一個(gè)正確() 127.下列說(shuō)法正確的有() 128.執行如下程序代碼() 129.下列哪一種敘述是正確的() 130.下列語(yǔ)句正確的是() 131.成員變量用static修飾和不用static修飾有什么區別? 132.如果變量用final修飾,則怎樣?如果方法final修飾,則怎樣? 133.在二進(jìn)制數據中,小數點(diǎn)向右移一位,則數據() 134.面向對象的特征有哪些方面? 135.float f=3.4;是否正確? 136.short s1 = 1; s1 = s1 + 1;有錯嗎?short s1 = 1; s1 += 1;有錯嗎? 137.Java 有沒(méi)有g(shù)oto? 138.int 和Integer 有什么區別? 139.&和&&的區別? 140.Math.round(11.5) 等于多少? Math.round(-11.5)等于多少? 141.swtich 是否能作用在byte 上,是否能作用在long 上,是否能作用在String上? 142.用最有效率的方法計算2乘以8? 143.在Java 中,如何跳出當前的多重嵌套循環(huán)? 144.構造器(constructor)是否可被重寫(xiě)(override)? 145.兩個(gè)對象值相同(x.equals(y) == true),但卻可有不同的hash code,這句話(huà)對不對? 146.當一個(gè)對象被當作參數傳遞到一個(gè)方法后,此方法可改變這個(gè)對象的屬性,并可返回變化后的結果,那么這里到底是值傳遞還是引用傳遞? 147.重載(Overload)和重寫(xiě)(Override)的區別。重載的方法能否根據返回類(lèi)型進(jìn)行區分? 148.華為的面試題中曾經(jīng)問(wèn)過(guò)這樣一個(gè)問(wèn)題:為什么不能根據返回類(lèi)型來(lái)區分重載,為什么? 149.靜態(tài)嵌套類(lèi)(Static Nested Class)和內部類(lèi)(Inner Class)的不同? 150.抽象的(abstract)方法是否可同時(shí)是靜態(tài)的(static),是否可同時(shí)是本地方法(native),是否可同時(shí)被synchronized修飾? 151.靜態(tài)變量和實(shí)例變量的區別? 152.是否可以從一個(gè)靜態(tài)(static)方法內部發(fā)出對非靜態(tài)(non-static)方法的調用? 153.如何實(shí)現對象克??? 154.接口是否可繼承(extends)接口? 抽象類(lèi)是否可實(shí)現(implements)接口? 抽象類(lèi)是否可繼承具體類(lèi)(concrete class)? 155.一個(gè)“.java”源文件中是否可以包含多個(gè)類(lèi)(不是內部類(lèi))?有什么限制? 156.Anonymous Inner Class(匿名內部類(lèi))是否可以繼承其它類(lèi)?是否可以實(shí)現接口? 157.內部類(lèi)可以引用它的包含類(lèi)(外部類(lèi))的成員嗎?有沒(méi)有什么限制? 158.Java 中的final關(guān)鍵字有哪些用法? 159.指出下面程序的運行結果: 160.說(shuō)說(shuō)數據類(lèi)型之間的轉換: 161.如何實(shí)現字符串的反轉及替換? 162.怎樣將GB2312編碼的字符串轉換為ISO-8859-1編碼的字符串? 163.Java中的日期和時(shí)間: 164.打印昨天的當前時(shí)刻。 165.Java反射技術(shù)主要實(shí)現類(lèi)有哪些,作用分別是什么? 166.Class類(lèi)的作用?生成Class對象的方法有哪些? 167.反射的使用場(chǎng)合和作用、及其優(yōu)缺點(diǎn) 168.面向對象設計原則有哪些
String相關(guān)
169.下面程序的運行結果是()(選擇一項) 170.Java語(yǔ)言中,String類(lèi)中的indexOf()方法返回值的類(lèi)型是() 171.給定以下代碼,程序的運行結果是 ()(選擇一項) 172.執行下列代碼后,哪個(gè)結論是正確的()(選擇兩項) 173.實(shí)現String類(lèi)的replaceAll方法 174.在“=”后填寫(xiě)適當的內容: 175.是否可以繼承String類(lèi)? 176.給定兩個(gè)字符串s和t, 寫(xiě)一個(gè)函數來(lái)決定是否t是s的重組詞。你可以假設字符串只包含小寫(xiě)字母。 177.String s=new String(“abc”);創(chuàng )建了幾個(gè)String對象。 178.輸出結果? 179.下列程序的輸出結果是什么? 180.關(guān)于java.lang.String類(lèi),以下描述正確的一項是() 181.下面哪個(gè)是正確的() 182.已知如下代碼:執行結果是什么() 183.字符串如何轉換為int類(lèi)型 184.寫(xiě)一個(gè)方法,實(shí)現字符串的反轉,如:輸入abc,輸出cba 185.編寫(xiě)java,將“I follow Bill Gate.Tom Gate.John Gate”中的“Gate”全部替換為“Gates” 186.String 是最基本的數據類(lèi)型嗎? 187.String 和StringBuilder、StringBuffer 的區別? 188.String類(lèi)為什么是final的 189.String類(lèi)型是基本數據類(lèi)型嗎?基本數據類(lèi)型有哪些 190.String?s="Hello";s=s+"world!";執行后,是否是對前面s指向空間內容的修改? 191.String s = new String("xyz");創(chuàng )建幾個(gè)String Object? 192.下面這條語(yǔ)句一共創(chuàng )建了多少個(gè)對象:String s="a"+"b"+"c"+"d";
集合
193.Java集合體系結構(List、Set、Collection、Map的區別和聯(lián)系) 194.Vector和ArrayList的區別和聯(lián)系 195.ArrayList和LinkedList的區別和聯(lián)系 196.HashMap和Hashtable的區別和聯(lián)系 197.HashSet的使用和原理(hashCode()和equals()) 198.TreeSet的原理和使用(Comparable和comparator) 199.集合和數組的比較(為什么引入集合) 200.Collection和Collections的區別 201.下列說(shuō)法正確的有()(選擇一項) 202.Java的HashMap和Hashtable有什么區別HashSet和HashMap有什么區別?使用這些結構保存的數需要重載的方法是哪些? 203.列出Java中的集合類(lèi)層次結構? 204.List,Set,Map各有什么特點(diǎn) 205.ArrayList list=new ArrayList(20);中的list擴充幾次() 206.List、Set、Map哪個(gè)繼承自Collection接口,一下說(shuō)法正確的是() 207.合并兩個(gè)有序的鏈表 208.用遞歸方式實(shí)現鏈表的轉置。 209.給定一個(gè)不包含相同元素的整數集合,nums,返回所有可能的子集集合。解答中集合不能包含重復的子集。 210.以下結構中,哪個(gè)具有同步功能() 211.以下結構中,插入性能最高的是() 212.以下結構中,哪個(gè)最適合當作stack使用() 213.Map的實(shí)現類(lèi)中,哪些是有序的,哪些是無(wú)序的,有序的是如何保證其有序性,你覺(jué)得哪個(gè)有序性性能更高,你有沒(méi)有更好或者更高效的實(shí)現方式? 214.下面的代碼在絕大部分時(shí)間內都運行得很正常,請問(wèn)什么情況下會(huì )出現問(wèn)題?根源在哪里? 215.TreeMap和TreeSet在排序時(shí)如何比較元素?Collections工具類(lèi)中的sort()方法如何比較元素? 216.List里面如何剔除相同的對象?請簡(jiǎn)單用代碼實(shí)現一種方法 217.Java.util.Map的實(shí)現類(lèi)有 218.下列敘述中正確的是() 219.List、Set、Map 是否繼承自Collection 接口? 220.說(shuō)出ArrayList、Vector、LinkedList 的存儲性能和特性? 221.List、Map、Set 三個(gè)接口,存取元素時(shí),各有什么特點(diǎn)? 222.TreeMap和TreeSet在排序時(shí)如何比較元素?Collections工具類(lèi)中的sort()方法如何比較元素?
多線(xiàn)程
223.下面程序的運行結果()(選擇一項) 224.下列哪個(gè)方法可用于創(chuàng )建一個(gè)可運行的類(lèi)() 225.說(shuō)明類(lèi)java.lang.ThreadLocal的作用和原理。列舉在哪些程序中見(jiàn)過(guò)ThreadLocal的使用? 226.說(shuō)說(shuō)樂(lè )觀(guān)鎖與悲觀(guān)鎖 227.在Java中怎么實(shí)現多線(xiàn)程?描述線(xiàn)程狀態(tài)的變化過(guò)程。 228.請寫(xiě)出多線(xiàn)程代碼使用Thread或者Runnable,并說(shuō)出兩種的區別。 229.在多線(xiàn)程編程里,wait方法的調用方式是怎樣的? 230.Java線(xiàn)程的幾種狀態(tài) 231.在Java多線(xiàn)程中,請用下面哪種方式不會(huì )使線(xiàn)程進(jìn)入阻塞狀態(tài)() 232.volatile關(guān)鍵字是否能保證線(xiàn)程安全? 233.請寫(xiě)出常用的Java多線(xiàn)程啟動(dòng)方式,Executors線(xiàn)程池有幾種常用類(lèi)型? 234.關(guān)于sleep()和wait(),以下描述錯誤的一項是() 235.進(jìn)程和線(xiàn)程的區別是什么? 236.以下鎖機機制中,不能保證線(xiàn)程安全的是() 237.創(chuàng )建n多個(gè)線(xiàn)程,如何保證這些線(xiàn)程同時(shí)啟動(dòng)?看清,是“同時(shí)”。 238.同步和異步有何異同,在什么情況下分別使用它們? 239.Java線(xiàn)程中,sleep()和wait()區別 240.下面所述步驟中,是創(chuàng )建進(jìn)程做必須的步驟是() 241.無(wú)鎖化編程有哪些常見(jiàn)方法?() 242.sleep()和yield()有什么區別? 243.當一個(gè)線(xiàn)程進(jìn)入一個(gè)對象的synchronized方法A之后,其它線(xiàn)程是否可進(jìn)入此對象的synchronized方法? 244.請說(shuō)出與線(xiàn)程同步相關(guān)的方法。 245.編寫(xiě)多線(xiàn)程程序有幾種實(shí)現方式? 246.synchronized關(guān)鍵字的用法? 247.啟動(dòng)一個(gè)線(xiàn)程是用run()還是start()方法? 248.什么是線(xiàn)程池(thread pool)? 249.線(xiàn)程的基本狀態(tài)以及狀態(tài)之間的關(guān)系? 250.簡(jiǎn)述synchronized 和java.util.concurrent.locks.Lock的異同? 251.創(chuàng )建線(xiàn)程的兩種方式分別是什么,優(yōu)缺點(diǎn)是什么? 252.Java創(chuàng )建線(xiàn)程后,調用start()方法和run()的區別 253.線(xiàn)程的生命周期 254.如何實(shí)現線(xiàn)程同步? 255.說(shuō)說(shuō)關(guān)于同步鎖的更多細節 256.Java中實(shí)現線(xiàn)程通信的三個(gè)方法的作用是什么?
Web方面相關(guān)
291.WEB應用中如果有.class和.jar類(lèi)型的文件一般分別應該放在什么位置? 292.元素中有一個(gè)輸入框(< input type=‘text’ name=’username‘id=’username”value=‘’"/>,請用JavaScript語(yǔ)言寫(xiě)一行代碼,取得這個(gè)輸入框中的值。 293.簡(jiǎn)單描述一下Servlet與JSP的的相同點(diǎn)和區別點(diǎn)。 294.請簡(jiǎn)單描述下幾個(gè)您熟悉JavaScript庫,它們有哪些作用和特點(diǎn)? 295.簡(jiǎn)單描述HTML,CSS,Javascript在Web開(kāi)發(fā)中分別起什么作用? 296.當DOM加載完成后要執行的函數,下面哪個(gè)是正確的() 297.舉例說(shuō)明JAVA中如何解析xml,不同方式有和優(yōu)缺點(diǎn)? 298.char型變量中能不能存儲一個(gè)中文漢字? 299.一個(gè)類(lèi)可以實(shí)現多個(gè)接口,但只能繼承一個(gè)抽象類(lèi)。 300.比較一下Java 和JavaSciprt 301.什么時(shí)候用assert? 302.UML是什么?UML中有哪些圖? 303.XML 文檔定義有幾種形式?它們之間有何本質(zhì)區別?解析XML 文檔有哪幾種方式? 304.你在項目中哪些地方用到了XML? 305.用JavaScript實(shí)現用正則表達式驗證,某個(gè)字符串是合法的6位數字的郵編的函數 306.請使用JQuery將頁(yè)面上的所有元素邊框設置為2pix寬的虛線(xiàn)? 307.如何設定JQuery異步調用還是同步調用? 308.說(shuō)出3條以上firefox和IE的瀏覽器兼容問(wèn)題? 309.請用Jquery語(yǔ)言寫(xiě)出ajax請求或者post請求代碼 310.body中的onload ()函數和jQuery中document.ready()有什么區別? 311.jQuery中有哪幾種類(lèi)型的選擇器? 312.EasyUI中datagrid刷新當前數據的方法? 313.分別寫(xiě)出一個(gè)div居中和其中的內容居中的css屬性設置 314.概述一下session與cookie的區別 315.JavaScript 中 null和 undefined 是否有區別?有哪些區別? 316.Servlet中的doPost和doGet方法有什么區別?它們在傳遞和獲取參數上有什么區別? 317.請寫(xiě)出一段jQuery代碼,實(shí)現把當前頁(yè)面中所有的a元索中class 屬性為“view-link”的鏈接都改為在新窗口中打開(kāi) 318.如下JavaScript代碼的輸出為: 319.Jquery中’.get()’與’.eq()’的區別 320.如何給weblogic定內存的大??? 321.TCP為何采用三次握手來(lái)建立連接,若釆用二次握手可以嗎,請說(shuō)明理由? 322.以下HTTP相應狀態(tài)碼的含義描述正確的是() 323.JSP頁(yè)面包括哪些元素?() 324.Ajax有四種技術(shù)組成:DOM,CSS,JavaScript,XmlHttpRequest,其中控制文檔結構的是() 325.下面關(guān)于session的用法哪些是錯誤的?() 326.Jsp九大內置對象 327.如何配置一個(gè)servlet? 328.JavaScript,如何定義含有數值1至8的數組? 329.以下JavaScipt語(yǔ)句會(huì )產(chǎn)生運行錯誤的是_() 330.在JSP中,下面__()__塊中可以定義一個(gè)新類(lèi): 331.HTML含義和版本變化 332.什么是錨鏈接 333.HTML字符實(shí)體的作用及其常用字符實(shí)體 334.HTML表單的作用和常用表單項類(lèi)型 335.表格、框架、div三種HTML布局方式的特點(diǎn) 336.form中input設置為readonly和disabled的區別 337.CSS的定義和作用 338.CSS2常用選擇器類(lèi)型及其含義 339.引入樣式的三種方式及其優(yōu)先級別 340.盒子模型 341.JavaScript語(yǔ)言及其特點(diǎn) 342.JavaScript常用數據類(lèi)型有哪些 343.html語(yǔ)法中哪條命令用于使一行文本折行,而不是插入一個(gè)新的段落? (B) 344.Ajax的優(yōu)點(diǎn)和缺點(diǎn) 345.怎樣防止表單刷新重復提交問(wèn)題?(說(shuō)出思路即可) 346.JQuery.get()和JQuery.ajax()方法之間的區別是什么? 347.Jquery里的緩存問(wèn)題如何解決?例如($.ajax()以及$.get()) 348.Javascript是面向對象的,怎么體現Javascript的繼承關(guān)系? 349.Javascript的有幾種種變量。變量范圍有什么不同? 350.Js如何獲取頁(yè)面的dom對象 351.Servlet API中forward() 與redirect()的區別? 352.Session域和request域什么區別? 353.頁(yè)面中有一個(gè)命名為bankNo的下拉列表,寫(xiě)js腳本獲取當前選項的索引值,如果用jquery如何獲取 354.寫(xiě)出要求11位數字的正則表達式 355.分別獲取指定name、Id的javascript對象,如果用jquey如何獲取 356.一個(gè)頁(yè)面有兩個(gè)form,如何獲取第一個(gè)form 357.如何設置一個(gè)層的可見(jiàn)/隱藏 358.描述JSP中動(dòng)態(tài)INCLUDE與靜態(tài)INCLUDE的區別? 359.列舉JSP的內置對象及方法 360.列舉jsp的四大作用域 361.html和xhtml的區別是什么? 362.你做的頁(yè)面用哪些瀏覽器測試過(guò)?這些測試的內核分別是什么? 363.你遇到了哪些瀏覽器的兼容性問(wèn)題?怎么解決的? 364.你知道的常用的js庫有哪些? 365.Js中的三種彈出式消息提醒(警告窗口、確認窗口、信息輸入窗口)的命令是什么? 366.談?wù)刯s的閉包 367.寫(xiě)一段js,遍歷所有的li,將每個(gè)li的內容逐個(gè)alert出來(lái) 368.頁(yè)面上如何用JavaScript對多個(gè)checkbox全選 369.寫(xiě)一個(gè)簡(jiǎn)單的JQuery的ajax 370.Js截取字符串a(chǎn)bcdefg的efg 371.http的請求頭信息包含了什么? 372.http的響應碼200,404,302,500表示的含義分別是? 373.Servlet中request對象的方法有? 374.Javascript的常用對象有哪些 375.DOM和BOM及其關(guān)系 376.JavaScript中獲取某個(gè)元素的三種方式JavaScript中的三種彈出式消息提醒命令是什么? 377.JavaScript操作CSS的兩種方式 378.靜態(tài)網(wǎng)頁(yè)和動(dòng)態(tài)網(wǎng)頁(yè)的聯(lián)系和區別 379.JSP/ASP/PHP的比較 380.CGI/Servlet/JSP的比較 381.HTTP協(xié)議工作原理及其特點(diǎn) 382.get和post的區別 383.如何解決表單提交的中文亂碼問(wèn)題 384.絕對路徑、根路徑、相對路徑的含義及其區別 385.如實(shí)現servlet的單線(xiàn)程模式 386.Servlet的生命周期 387.轉發(fā)和重定向的區別 388.JSP的執行過(guò)程 389.JSP動(dòng)作有哪些,簡(jiǎn)述作用? 390.page/request/session/application作用域區別 391.JSP和Servlet的區別和聯(lián)系 392.談?wù)勥^(guò)濾器原理及其作用? 393.jQuery相比JavaScript的優(yōu)勢在哪里 394.DOM對象和jQuery對象的區別及其轉換 395.jQuery中$的作用主要有哪些 396.Ajax含義及其主要技術(shù) 397.Ajax的工作原理 398.JSON及其作用 399.文件上傳組件Common-fileUpload的常用類(lèi)及其作用? 400.說(shuō)出Servlet的生命周期,并說(shuō)出Servlet和CGI的區別? 401.JSP 和Servlet 有有什么關(guān)系? 402.JSP中的四種作用域? 403.如何實(shí)現JSP或Servlet的單線(xiàn)程模式? 404.實(shí)現會(huì )話(huà)跟蹤的技術(shù)有哪些? 405.過(guò)濾器有哪些作用和用法? 406.監聽(tīng)器有哪些作用和用法? 407.你的項目中使用過(guò)哪些JSTL標簽? 408.使用標簽庫有什么好處?如何自定義JSP標簽? 409.表達式語(yǔ)言(EL)的隱式對象及其作用? 410.表達式語(yǔ)言(EL)支持哪些運算符? 411.Servlet 3中的異步處理指的是什么? 412.如何在基于Java的Web項目中實(shí)現文件上傳和下載? 413.簡(jiǎn)述值棧(Value-Stack)的原理和生命周期 414.闡述Session加載實(shí)體對象的過(guò)程。 415.怎么防止重復提交 416.$(document).ready(function(){}) jQuery(document).ready(function(){}); 有什么區別? 417.寫(xiě)出輸出結果 418.web項目從瀏覽器發(fā)起交易響應緩慢,請簡(jiǎn)述從哪些方面如數分析
高級框架
431.什么是Maven? 432.Maven和ANT的區別 433.Maven倉庫是什么 434.Maven的工程類(lèi)型有哪些? 435.Maven常用命令有哪些? 436.ZooKeeper的作用是什么? 437.什么是Znode? 438.Znode節點(diǎn)類(lèi)型有哪些? 439.什么是Dubbo? 440.什么是RPC遠程過(guò)程調用? 441.Dubbo中有哪些角色? 442.Dubbo執行流程什么是? 443.說(shuō)說(shuō)Dubbo支持的協(xié)議有哪些? 444.Dubbo支持的注冊中心有哪些? 445.SessionFactory是線(xiàn)程安全的嗎?Session是線(xiàn)程安全的嗎,兩個(gè)線(xiàn)程能夠共享同一個(gè)Session嗎? 446.Session的load和get方法的區別是什么? 447.Session的save()、update()、merge()、lock()、saveOrUpdate()和persist()方法有什么區別? 448.什么是VSFTPD? 449.什么是Nginx? 450.Nginx有哪些作用? 451.什么是正向代理? 452.什么是反向代理? 453.什么是Redis? 454.Redis的特點(diǎn)什么是? 455.Redis數據類(lèi)型有哪些? 456.Redis中的常用命令哪些? 457.Redis的配置以及持久化方案有幾種? 458.什么是RDB方式? 459.什么是AOF方式? 460.什么是全文檢索? 461.什么是Lucene? 462.什么是Solr? 463.Solr是由哪兩個(gè)部分構成? 464.什么是正排索引? 465.什么是倒排索引? 466.什么是ActiveMQ? 467.消息服務(wù)的應用場(chǎng)景有哪些? 468.什么是JMS? 469.JMS有哪些模型? 470.什么是JsonP? 471.什么是跨域? 472.什么是同源策略? 473.什么是MyCat? 474.什么是縱向切分/垂直切分? 475.簡(jiǎn)述Tomcat,Apache,JBoss和WebLogic的區別和聯(lián)系 476.以下可以實(shí)現負載均衡的是() 477.Tomcat/ WebSphere/WebLogic的作用和特點(diǎn) 478.B/S和C/S的含義及其區別 479.說(shuō)說(shuō)你對容器的理解 480.為什么要使用連接池? 481.數據庫連接池的原理 482.MVC模式及其優(yōu)缺點(diǎn) 483.MVC模式完成分頁(yè)功能的基本思路是什么? 484.常用的Web容器 485.Java Web開(kāi)發(fā)的Model 1和Model 2分別指的是什么? 486.說(shuō)說(shuō)什么是框架: 487.簡(jiǎn)單說(shuō)一下MVC框架? 488.簡(jiǎn)單講一下struts2的執行流程 489.Struts2中的攔截器,你都用它干什么? 490.簡(jiǎn)單講一下SpringMVC的執行流程? 491.簡(jiǎn)單說(shuō)一下struts2和springMVC有什么不同 492.說(shuō)一下Spring中的兩大核心 493.講一下Spring的事務(wù)的傳播特性 494.什么是ORM 495.Hibernate對象的狀態(tài) 496.介紹一下Hibernate的緩存 497.簡(jiǎn)單講一下webservice使用的場(chǎng)景 498.簡(jiǎn)單介紹一下activity? 499.什么是MyBatis? 500.Mybatis是如何進(jìn)行分頁(yè)的?分頁(yè)插件的原理是什么? 501.MyBatis與Hibernate有哪些不同? 502.簡(jiǎn)述Mybatis的Xml映射文件和Mybatis內部數據結構之間的映射關(guān)系? 503.什么是MyBatis的接口綁定,有什么好處? 504.Mybatis能執行一對一、一對多的關(guān)聯(lián)查詢(xún)嗎?都有哪些實(shí)現方式,以及它們之間的區別? 505.MyBatis里面的動(dòng)態(tài)Sql是怎么設定的?用什么語(yǔ)法? 506.使用MyBatis的mapper接口調用時(shí)有哪些要求? 507.Mybatis是如何將sql執行結果封裝為目標對象并返回的?都有哪些映射形式? 508.MyBatis接口綁定有幾種實(shí)現方式,分別是怎么實(shí)現的? 509.MyBatis實(shí)現一對一有幾種方式?具體怎么操作的? 510.什么情況下用注解綁定,什么情況下用xml綁定? 511.MyBatis的好處是什么?
微服務(wù)框架
512.Spring Boot有哪些優(yōu)點(diǎn)? 513.如何重新加載Spring Boot上的更改,而無(wú)需重新啟動(dòng)服務(wù)器? 514.常見(jiàn)的系統架構風(fēng)格有哪些?各有什么優(yōu)缺點(diǎn)? 515.什么是AKF拆分原則? 516.什么是Spring Cloud? 517.Spring Cloud與Dubbo的區別是什么? 518.什么是Eureka注冊中心? 519.簡(jiǎn)單談一下Eureka中的三種角色分別是什么? 520.什么是Ribbon 521.集中式與進(jìn)程內負載均衡的區別 522.Ribbon的常見(jiàn)負載均衡策略有哪些? 523.簡(jiǎn)單說(shuō)說(shuō)什么是Feign? 524.什么是聲明式,有什么作用,解決什么問(wèn)題? 525.什么是服務(wù)的災難性的雪崩效應? 526.如何解決災難性雪崩效應? 527.線(xiàn)程池隔離和信號量隔離的區別 528.請回答微服務(wù)架構的六種常用設計模式是什么? 529.什么是網(wǎng)關(guān)服務(wù)? 530.網(wǎng)關(guān)服務(wù)中,路由器的4種路由規則方法是什么? 531.為什么要使用spring cloud config 配置中心?它解決了什么問(wèn)題? 532.什么是Spring Cloud Bus 533.消息驅動(dòng)Stream解決了什么問(wèn)題? 534.為什么要使用微服務(wù)跟蹤?它解決了什么問(wèn)題? 535.什么是ELK(ElasticSearch, Logstash, Kibana) 536.為什么要用ELK,它解決了什么問(wèn)題? 537.什么是分布式跟蹤?:?Zipki?
數據庫
538.下列屬于關(guān)系型數據庫的是()(選擇兩項) 539.請列出Java常見(jiàn)的開(kāi)源數據連接池,并對參數做出簡(jiǎn)單的說(shuō)明 540.儲蓄所有多個(gè)儲戶(hù),儲戶(hù)在多個(gè)儲戶(hù)所存取款,儲蓄所與儲戶(hù)之間是() 541.視圖是一個(gè)“虛表”,視圖的構造基于() 542.設有關(guān)系R(A,B,C,D)及其上的函數相關(guān)性集合F={B→A,BC→D},那么關(guān)系R最高是() 543.什么是DAO模式? 544.數據庫MySQL,Oracle,SqlServer分頁(yè)時(shí)用的語(yǔ)句 545.Oracle完成分頁(yè)功能的三層子查詢(xún)語(yǔ)句及其含義? 546.問(wèn)SQL怎么優(yōu)化執行效率更高 547.談?wù)剶祿烊タ崭竦那闆r 548.根據你以往的經(jīng)驗簡(jiǎn)單敘述一下MYSQL的優(yōu)化 549.以Oracle11R為例簡(jiǎn)述數據庫集群部署 550.說(shuō)一下數據庫的存儲過(guò)程? 551.數據庫創(chuàng )建索引的缺點(diǎn)? 552.有兩張表;請用SQL查詢(xún),所有的客戶(hù)訂單日期最新的前五條訂單記錄。(分別注明MySQL. Oracle寫(xiě)法) 553.關(guān)于HQL與SQL,以下哪些說(shuō)法正確?() 554.下面是學(xué)生表(student)的結構說(shuō)明 555.為管理崗位業(yè)務(wù)培訓信息,有如下3個(gè)表: 556.用Java怎么實(shí)現有每天有1億條記錄的DB儲存?MySQL上億記錄數據量的數據庫如何設計? 557.Mysql的引擎有哪些?支持事物么?DB儲存引擎有哪些? 558.以下是學(xué)生考試結果表 559.庫中已經(jīng)存在雇用表表名: 560.如下表1中的數據,表名為:t_test,記錄某場(chǎng)比賽的結果。 561.請將如下數據庫語(yǔ)句進(jìn)行優(yōu)化,使其執行效率更高(提示:…不需要更改) 562.請簡(jiǎn)述如何將Oracle中的數據庫轉至DB2中,需要保證表結構和數據不變 563.學(xué)生成績(jì)表 564.Oracl數據庫中有兩張表Stu(學(xué)生表)和Grade(分數表),如下圖所示: 565.下面是學(xué)生表(Student)的結構說(shuō)明: 566.取出sql表中低31到40的記錄(以自動(dòng)增長(cháng)ID為主鍵) 567.下列兩個(gè)表,需要用一條sql語(yǔ)句把b表中的ID和NAME 字段的數值復制到A表中 568.什么是基本表,什么是視圖,兩者的區別和聯(lián)系是什么? 569.什么是事務(wù)?什么是鎖? 570.Student學(xué)生表(學(xué)號,姓名、性別、年齡、組織部門(mén)),Course 課程表(編號,課程名稱(chēng)),Sc選課表(學(xué)號,課程編號,成績(jì)) 571.sql查詢(xún)
Linux操作
580.請寫(xiě)出常用的linux指令不低于10個(gè),請寫(xiě)出linux tomcat啟動(dòng)。 581.當使用RMI技術(shù)實(shí)現遠程方法調用時(shí),能為遠程對象生成Sub和Skeleton命令的是() 582.以下哪個(gè)是服務(wù)() 583.下面的網(wǎng)絡(luò )協(xié)議中,面向連接的的協(xié)議是: () 584.在/etc/fstab 文件中指定的文件系統加載參數中, () 參數一般用于CD-ROM 等移動(dòng)設備。 585.Linux 文件權限一共10 位長(cháng)度,分成四段,第三段表示的內容是 () 586.終止一個(gè)前臺進(jìn)程可能用到的命令和操作 () 587.在使用mkdir 命令創(chuàng )建新的目錄時(shí),在其父目錄不存在時(shí)先創(chuàng )建父目錄的選項是 () 588.下面關(guān)于i 節點(diǎn)描述錯誤的是 () 589.一個(gè)文件名字為rr.Z,可以用來(lái)解壓縮的命令是: () 590.具有很多C 語(yǔ)言的功能,又稱(chēng)過(guò)濾器的是 () 591.一臺主機要實(shí)現通過(guò)局域網(wǎng)與另一個(gè)局域網(wǎng)通信,需要做的工作是 () 592.建立動(dòng)態(tài)路由需要用到的文件有 () 593.局域網(wǎng)的網(wǎng)絡(luò )地址192.168.1.0/24,局域網(wǎng)絡(luò )連接其它網(wǎng)絡(luò )的網(wǎng)關(guān)地址是192.168.1.1。主機192.168.1.20 訪(fǎng)問(wèn)172.16.1.0/24 網(wǎng)絡(luò )時(shí),其路由設置正確的是 () 594.下列提法中,不屬于ifconfig 命令作用范圍的是 () 595.下列關(guān)于鏈接描述,錯誤的是() 596.在局域網(wǎng)絡(luò )內的某臺主機用ping 命令測試網(wǎng)絡(luò )連接時(shí)發(fā)現網(wǎng)絡(luò )內部的主機都可以連同,而不能與公網(wǎng)連通,問(wèn)題可能是() 597.下列文件中,包含了主機名到IP 地址的映射關(guān)系的文件是: 598.不需要編譯內核的情況是() 599.在shell 中變量的賦值有四種方法,其中,采用name=12 的方法稱(chēng) () 600.()命令可以從文本文件的每一行中截取指定內容的數據。 601.下列不是Linux 系統進(jìn)程類(lèi)型的是() 602.在日常管理中,通常CPU 會(huì )影響系統性能的情況是: () 603.若一臺計算機的內存為128MB,則交換分區的大小通常是 604.在安裝Linux 的過(guò)程中的第五步是讓用戶(hù)選擇安裝方式,如果用戶(hù)希望安裝部分組件(軟件程序),并在選擇好后讓系統自動(dòng)安裝,應該選擇的選項是() 605.Linux 有三個(gè)查看文件的命令,若希望在查看文件內容過(guò)程中可以用光標上下移動(dòng)來(lái)查看文件內容,應使用()命令 606.下列信息是某系統用ps –ef 命令列出的正在運行的進(jìn)程 ()進(jìn)程是運行Internet 超級服務(wù)器,它負責監聽(tīng)Internet sockets 上的連接,并調用合適的服務(wù)器來(lái)處理接收的信息。 607.在TCP/IP 模型中,應用層包含了所有的高層協(xié)議,在下列的一些應用協(xié)議中, ()是能夠實(shí)現本地與遠程主機之間的文件傳輸工作 608.當我們與某遠程網(wǎng)絡(luò )連接不上時(shí),就需要跟蹤路由查看,以便了解在網(wǎng)絡(luò )的什么位置出現了問(wèn)題,滿(mǎn)足該目的的命令是() 609.對名為fido 的文件用chmod 551 fido 進(jìn)行了修改,則它的許可權是() 610.用ls –al 命令列出下面的文件列表,()文件是符號連接文件 611.DNS 域名系統主要負責主機名和()之間的解析。 612.WWW 服務(wù)器是在Internet 上使用最為廣泛,它采用的是()結構 613.Linux 系統通過(guò)()命令給其他用戶(hù)發(fā)消息。 614.NFS 是()系統。 615.()命令可以在Linux 的安全系統中完成文件向磁帶備份的工作 616.Linux 文件系統的文件都按其作用分門(mén)別類(lèi)地放在相關(guān)的目錄中,對于外部設備文件,一般應將其放在()目錄中 617.在重新啟動(dòng)Linux 系統的同時(shí)把內存中的信息寫(xiě)入硬盤(pán),應使用()命令實(shí)現 618.網(wǎng)絡(luò )管理具備以下幾大功能:配置管理、()、性能管理、安全管理和計費管理等 619.關(guān)閉linux 系統(不重新啟動(dòng))可使用命令() 620.實(shí)現從IP 地址到以太網(wǎng)MAC 地址轉換的命令為: () 621.在vi 編輯器中的命令模式下,鍵入()可在光標當前所在行下添加一新行 622.在vi 編輯器中的命令模式下,刪除當前光標處的字符使用()命令 623.在vi 編輯器中的命令模式下,重復上一次對編輯的文本進(jìn)行的操作,可使用()命令 624.刪除文件命令為: () 625.退出交互模式的shell,應鍵入()
算法分析及手寫(xiě)代碼
626.判斷身份證:要么是15位,要么是18位,最后一位可以為字母,并寫(xiě)出程序提出其中年月日。要求: 627.對于一個(gè)字符串,請設計一個(gè)高效算法,找到第一次重復出現的字符保證字符串中有重復的字符,字符串的長(cháng)度小于等于500. 628.寫(xiě)一個(gè)完整函數,實(shí)現拷貝數組 629.寫(xiě)一排序算法,輸入10個(gè)數字,以逗號分開(kāi),可根據參數選擇升序或者降序排序,須注明是何種排序算法。 630.判斷字符串是否是這樣的組成的,第一個(gè)字母,后面可以是字母、數字、下劃線(xiàn)、總長(cháng)度為5-20。 631.已排好序的數組A,一般來(lái)說(shuō)可用二分查找可以很快找到,現有一特殊數組A,它是循環(huán)遞增的,如a[]={17, 19 ,20, 25, 1, 4, 7, 9},在這樣的數組中找一元素,看看是否存在。請寫(xiě)出你的算法,必要時(shí)可寫(xiě)偽代碼,并分析其空間,時(shí)間復雜度。 632.請編寫(xiě)一個(gè)完整的程序,實(shí)現如下功能:從鍵盤(pán)輸入數字n,程序自動(dòng)計算n!并輸出。(注1:n!=1*2*3...*n, 注2:請使用遞歸實(shí)現) 633.請用遞歸的方法計算斐波那契數列的同項F(n),已知F0=0,F1=1,F(n)=F(n-1)+F(n-2)(n>=2,n∈N*). 634.現在有整數數組{11,66,22,0,55,32},請任意選擇一種排序算法,用Java程序實(shí)現 635.請根據注釋?zhuān)幋a實(shí)現下面類(lèi)的方法 636.二分法查詢(xún)(遞歸實(shí)現) 637.編寫(xiě)一段Java程序,把一句英語(yǔ)中的每個(gè)單詞中的字母次序倒轉,單詞次序保持不變,例入輸入為“There is a dog.”,輸出結果應該是“erehT si a god.”要求不使用Java的庫函數,例如String類(lèi)的split,reverse方法。 638.手寫(xiě)9x9乘法表,冒泡排序 639.題目: 給定一個(gè)整數數組,找到是否該數組包含任何重復數字。你的函數應該返回true只要有任何數字 在該數組中重復出現,否則返回false。 640.給定一個(gè)數組nums, 寫(xiě)一個(gè)函數來(lái)移動(dòng)所有0元素到數組末尾,同時(shí)維持數組中非0元素的相對順序不變。要求不能申請額外的內存空間,并且最小化操作次數。 641.給定一顆二叉樹(shù),返回節點(diǎn)值得先序遍歷,請使用迭代(非遞歸)方式實(shí)現。 642.驗證一棵樹(shù)是否為有效的二叉搜索樹(shù)BST 643.從一個(gè)鏈表中刪除節點(diǎn) 644.二叉搜索樹(shù)BST中第Kth小的元素 題目:給定?個(gè)BST,寫(xiě)一個(gè)函數kthSmallest來(lái)找到第kth小的元素 645.題目:給定含有n個(gè)整數的數組S,S中是否存在三個(gè)元素a,b,c使得a + b + c = 0? 找到所有這樣的三元 組,并且結果集中不包含重復的三元組。 646.子集問(wèn)題 647.迭代方法實(shí)現二叉樹(shù)的先序遍歷:題目: 給定一顆?叉樹(shù),返回節點(diǎn)值得先序遍歷,請使用迭代(非遞歸)方式實(shí)現。 648.驗證二叉搜索樹(shù)BST:題目: 驗證一棵樹(shù)是否為有效的二叉搜索樹(shù)BST比如,二叉樹(shù)[2, 1, 3],返回true二叉樹(shù)[1, 2, 3], 返回false 649.編輯距離題目: 給定兩個(gè)單詞word1和word2,找到最小的操作步驟使得word1轉換成word2,每次操作算作一 步。你可以對單詞進(jìn)行以下三種操作:1)插入一個(gè)字符2)刪除一個(gè)字符3)替換一個(gè)字符 650.買(mǎi)賣(mài)股票問(wèn)題:題目: 你有一個(gè)數組,第i個(gè)元素表示第i天某個(gè)股票的價(jià)格,設計一個(gè)算法找到最大的利潤,并且你只能最多完成兩次交易。 651.[編程]任給n個(gè)整數和一個(gè)整數x。請計算n個(gè)整數中有多少對整數之和等于x。 652.[編程]請說(shuō)明快速排序算法的設計思想和時(shí)間復雜度,并用高級語(yǔ)言寫(xiě)出對整數數組進(jìn)行一趟快排的函數實(shí)現。 653.對于一段形如:1,-1~3,1~15×3的輸入 654.有兩個(gè)字符串:目標串S=“s1s2.......sn”,模式串T="t1t2.......tm"。若存在T的每個(gè)字符一次和S中的一個(gè)連續字符序列相等,則匹配成功,返回T中第一個(gè)字符在S中的位置。否則匹配不成功,返回0。寫(xiě)出你的算法,要求線(xiàn)性時(shí)間復雜度 655.如何生成一個(gè)0-100的隨機整數? 656.請編寫(xiě)一段Java程序將兩個(gè)有序數組合并成一個(gè)有序數組 657.在最佳情況下,以下哪個(gè)時(shí)間復雜度最高(D) 658.一個(gè)數組,元素為從0到m的整數,判斷其中是否有重復元素,使用java語(yǔ)言編寫(xiě)一個(gè)方法 659.某二叉樹(shù)的先序遍歷是12453,中序遍歷是42513,那么其后序遍歷是(A) 660.設一顆二叉樹(shù)中有3個(gè)葉子節點(diǎn),有八個(gè)度為1的節點(diǎn),則該二叉樹(shù)中總的節點(diǎn)數為() 661.給出下面的二叉樹(shù)先序、中序、后序遍歷的序列? 662.你知道的排序算法都哪些?用Java寫(xiě)一個(gè)排序系統 663.寫(xiě)一個(gè)二分查找(折半搜索)的算法。 664.統計一篇英文文章單詞個(gè)數。 665.輸入年月日,計算該日期是這一年的第幾天。 666.回文素數:所謂回文數就是順著(zhù)讀和倒著(zhù)讀一樣的數(例如:11,121,1991…),回文素數就是既是回文數又是素數(只能被1和自身整除的數)的數。編程找出11~9999之間的回文素數。 667.全排列:給出五個(gè)數字12345的所有排列。 668.對于一個(gè)有N個(gè)整數元素的一維數組,找出它的子數組(數組中下標連續的元素組成的數組)之和的最大值。 669.用遞歸實(shí)現字符串倒轉 670.輸入一個(gè)正整數,將其分解為素數的乘積。 671.一個(gè)有n級的臺階,一次可以走1級、2級或3級,問(wèn)走完n級臺階有多少種走法。 672.寫(xiě)一個(gè)算法判斷一個(gè)英文單詞的所有字母是否全都不同(不區分大小寫(xiě)) 673.有一個(gè)已經(jīng)排好序的整數數組,其中存在重復元素,請將重復元素刪除掉,例如,A= [1, 1, 2, 2, 3],處理之后的數組應當為A= [1, 2, 3]。 674.給一個(gè)數組,其中有一個(gè)重復元素占半數以上,找出這個(gè)元素。 675.編寫(xiě)一個(gè)方法求一個(gè)字符串的字節長(cháng)度?
第三篇:熱門(mén)專(zhuān)業(yè)學(xué)習之路
前言

本題集由尚學(xué)堂學(xué)員整理,列舉了眾多IT公司面試真題,對應聘Java程序員職位的常見(jiàn)考點(diǎn)和知識體系都進(jìn)行的分類(lèi)和歸納整理。

本題集適合應聘Java和JavaEE職位的程序員作為面試復習、學(xué)習和強化的資料,也適合其他程序員作為拓展讀物進(jìn)行閱讀。

本題集包含了常見(jiàn)的算法、面試題,也包含了新的高級技術(shù),比如:微服務(wù)架構等技術(shù)的面試題目。本題集非常全面,對于工作1-5年左右的java程序員面試有非常好的指導作用。

大家也可以訪(fǎng)問(wèn)(直接在線(xiàn)觀(guān)看最新版的面試題):www.thehomosexualagenda.com/javamianshiti.html

1.大學(xué)生高端復合人才成長(cháng)
1.JAVA專(zhuān)業(yè),1000課 3.大數據專(zhuān)業(yè),500課
2.Python專(zhuān)業(yè),500課    4.人工智能專(zhuān)業(yè),500課

四個(gè)專(zhuān)業(yè)都要學(xué),從零開(kāi)始2000小時(shí),成為高端人才,打下一生技術(shù)基礎,不再是低端碼農。

2.掃一掃,咨詢(xún)詳情:

訪(fǎng)問(wèn)官網(wǎng) www.itbaizhan.cn

Java基礎、語(yǔ)法:

1.Java跨平臺原理(字節碼文件、虛擬機)

C/C++語(yǔ)言都直接編譯成針對特定平臺機器碼。如果要跨平臺,需要使用相應的編譯器重新編譯。

Java源程序(.java)要先編譯成與平臺無(wú)關(guān)的字節碼文件(.class),然后字節碼文件再解釋成機器碼運行。解釋是通過(guò)Java虛擬機來(lái)執行的。

字節碼文件不面向任何具體平臺,只面向虛擬機。

Java虛擬機是可運行Java字節碼文件的虛擬計算機。不同平臺的虛擬機是不同的,但它們都提供了相同的接口。

Java語(yǔ)言具有一次編譯,到處運行的特點(diǎn)。就是說(shuō)編譯后的.class可以跨平臺運行,前提是該平臺具有相應的Java虛擬機。但是性能比C/C++要低。

Java的跨平臺原理決定了其性能沒(méi)有C/C++高

2.Java的安全性

語(yǔ)言層次的安全性主要體現在:

Java取消了強大但又危險的指針,而代之以引用。由于指針可進(jìn)行移動(dòng)運算,指針可隨便指向一個(gè)內存區域,而不管這個(gè)區域是否可用,這樣做是危險的,因為原來(lái)這個(gè)內存地址可能存儲著(zhù)重要數據或者是其他程序運行所占用的,并且使用指針也容易數組越界。

垃圾回收機制:不需要程序員直接控制內存回收,由垃圾回收器在后臺自動(dòng)回收不再使用的內存。避免程序忘記及時(shí)回收,導致內存泄露。避免程序錯誤回收程序核心類(lèi)庫的內存,導致系統崩潰。

異常處理機制:Java異常機制主要依賴(lài)于try、catch、finally、throw、throws五個(gè)關(guān)鍵字。

強制類(lèi)型轉換:只有在滿(mǎn)足強制轉換規則的情況下才能強轉成功。

底層的安全性可以從以下方面來(lái)說(shuō)明

Java在字節碼的傳輸過(guò)程中使用了公開(kāi)密鑰加密機制(PKC)。

在運行環(huán)境提供了四級安全性保障機制:

字節碼校驗器 -類(lèi)裝載器 -運行時(shí)內存布局 -文件訪(fǎng)問(wèn)限制

3.Java三大版本

Java2平臺包括標準版(J2SE)、企業(yè)版(J2EE)和微縮版(J2ME)三個(gè)版本:

Standard Edition(標準版) J2SE 包含那些構成Java語(yǔ)言核心的類(lèi)。

比如:數據庫連接、接口定義、輸入/輸出、網(wǎng)絡(luò )編程

Enterprise Edition(企業(yè)版) J2EE 包含J2SE 中的類(lèi),并且還包含用于開(kāi)發(fā)企業(yè)級應用的類(lèi)。

比如servlet、JSP、XML、事務(wù)控制

Micro Edition(微縮版) J2ME 包含J2SE中一部分類(lèi),用于消費類(lèi)電子產(chǎn)品的軟件開(kāi)發(fā)。

比如:呼機、智能卡、手機、PDA、機頂盒

他們的范圍是:J2SE包含于J2EE中,J2ME包含了J2SE的核心類(lèi),但新添加了一些專(zhuān)有類(lèi)

應用場(chǎng)合,API的覆蓋范圍各不相同。

4.什么是JVM?什么是JDK? 什么是JRE?

JVM :JVM是Java Virtual Machine(Java虛擬機)的縮寫(xiě),它是整個(gè)java實(shí)現跨平臺的最核心的部分,所有的java程序會(huì )首先被編譯為.class的類(lèi)文件,這種類(lèi)文件可以在虛擬機上執行,也就是說(shuō)class并不直接與機器的操作系統相對應,而是經(jīng)過(guò)虛擬機間接與操作系統交互,由虛擬機將程序解釋給本地系統執行。JVM是Java平臺的基礎,和實(shí)際的機器一樣,它也有自己的指令集,并且在運行時(shí)操作不同的內存區域。?JVM通過(guò)抽象操作系統和CPU結構,提供了一種與平臺無(wú)關(guān)的代碼執行方法,即與特殊的實(shí)現方法、主機硬件、主機操作系統無(wú)關(guān)。JVM的主要工作是解釋自己的指令集(即字節碼)到CPU的指令集或對應的系統調用,保護用戶(hù)免被惡意程序騷擾。?JVM對上層的Java源文件是不關(guān)心的,它關(guān)注的只是由源文件生成的類(lèi)文件(.class文件)。

JRE:JRE是java runtime environment(java運行環(huán)境)的縮寫(xiě)。光有JVM還不能讓class文件執行,因為在解釋class的時(shí)候JVM需要調用解釋所需要的類(lèi)庫lib。在JDK的安裝目錄里你可以找到j(luò )re目錄,里面有兩個(gè)文件夾bin和lib,在這里可以認為bin里的就是jvm,lib中則是jvm工作所需要的類(lèi)庫,而jvm和lib和起來(lái)就稱(chēng)為jre。所以,在你寫(xiě)完java程序編譯成.class之后,你可以把這個(gè).class文件和jre一起打包發(fā)給朋友,這樣你的朋友就可以運行你寫(xiě)程序了(jre里有運行.class的java.exe)。JRE是Sun公司發(fā)布的一個(gè)更大的系統,它里面就有一個(gè)JVM。JRE就與具體的CPU結構和操作系統有關(guān),是運行Java程序必不可少的(除非用其他一些編譯環(huán)境編譯成.exe可執行文件……),JRE的地位就象一臺PC機一樣,我們寫(xiě)好的Win32應用程序需要操作系統幫我們運行,同樣的,我們編寫(xiě)的Java程序也必須要JRE才能運行。?

JDK:JDK是java development kit(java開(kāi)發(fā)工具包)的縮寫(xiě)。每個(gè)學(xué)java的人都會(huì )先在機器上裝一個(gè)JDK,那 讓我們看一下JDK的安裝目錄。在目錄下面有六個(gè)文件夾、一個(gè)src類(lèi)庫源碼壓縮包、和其他幾個(gè)聲明文件。其中,真正在運行java時(shí)起作用的是以下四個(gè)文件夾:bin、include、lib、jre?,F在我們可以看出這樣一個(gè)關(guān)系,JDK包含JRE,而JRE包含JVM。

bin:最主要的是編譯器(javac.exe)

include:java和JVM交互用的頭文件

lib:類(lèi)庫??????

jre:java運行環(huán)境?

(注意:這里的bin、lib文件夾和jre里的bin、lib是不同的)總的來(lái)說(shuō)JDK是用于java程序的開(kāi)發(fā),而jre則是只能運行class而沒(méi)有編譯的功能。eclipse、idea等其他IDE有自己的編譯器而不是用JDK?bin目錄中自帶的,所以在安裝時(shí)你會(huì )發(fā)現他們只要求你選jre路徑就ok了。

JDK,JRE,JVM三者關(guān)系概括如下:

jdk是JAVA程序開(kāi)發(fā)時(shí)用的開(kāi)發(fā)工具包,其內部也有JRE運行環(huán)境JRE。JRE是JAVA程序運行時(shí)需要的運行環(huán)境,就是說(shuō)如果你光是運行JAVA程序而不是去搞開(kāi)發(fā)的話(huà),只安裝JRE就能運行已經(jīng)存在的JAVA程序了。JDk、JRE內部都包含JAVA虛擬機JVM,JAVA虛擬機內部包含許多應用程序的類(lèi)的解釋器和類(lèi)加載器等等。

5.Java三種注釋類(lèi)型

共有單行注釋、多行注釋、文檔注釋3種注釋類(lèi)型。使用如下:

單行注釋?zhuān)捎谩?/”方式.只能注釋一行代碼。如://類(lèi)成員變量

多行注釋?zhuān)捎谩?*...*/”方式,可注釋多行代碼,其中不允許出現嵌套。如:

/*System.out.println("a");

System.out.println("b");

System.out.println("c");*/

文檔注釋?zhuān)捎谩?**...*/”方式。如:

/**

* 子類(lèi) Dog

* @author Administrator

**/

public class Dog extends Animal{}

6.8種基本數據類(lèi)型及其字節數
數據類(lèi)型 關(guān)鍵字 字節數
數值型 整數型 byte 1
short 2
int 4
long 8
浮點(diǎn)型 float 4
double 8
布爾型 boolean 1(位)
字符型 char 2
7.i++和++i的異同之處

共同點(diǎn):

1、i++和++i都是變量自增1,都等價(jià)于i=i+1

2、如果i++,++i是一條單獨的語(yǔ)句,兩者沒(méi)有任何區別

3、i++和++i的使用僅僅針對變量。 5++和++5會(huì )報錯,因為5不是變量。

不同點(diǎn):

如果i++,++i不是一條單獨的語(yǔ)句,他們就有區別i++ :先運算后增1。如:

int x=5;
int y=x++;
System.out.println("x="+x+", y="+y);
    //以上代碼運行后輸出結果為:x=6, y=5

++i : 先增1后運算。如:

int x=5;
int y=++x;
System.out.println("x="+x+", y="+y);
    //以上代碼運行后輸出結果為:x=6, y=6
8.&和&&的區別和聯(lián)系,|和||的區別和聯(lián)系

&和&&的聯(lián)系(共同點(diǎn)):

&和&&都可以用作邏輯與運算符,但是要看使用時(shí)的具體條件來(lái)決定。

操作數1&操作數2,操作數1&&操作數2,

表達式1&表達式2,表達式1&&表達式2,

情況1:當上述的操作數是boolean類(lèi)型變量時(shí),&和&&都可以用作邏輯與運算符。

情況2:當上述的表達式結果是boolean類(lèi)型變量時(shí),&和&&都可以用作邏輯與運算符。

表示邏輯與(and),當運算符兩邊的表達式的結果或操作數都為true時(shí),整個(gè)運算結果才為true,否則,只要有一方為false,結果都為false。

&和&&的區別(不同點(diǎn)):

(1)、&邏輯運算符稱(chēng)為邏輯與運算符,&&邏輯運算符稱(chēng)為短路與運算符,也可叫邏輯與運算符。

對于&:無(wú)論任何情況,&兩邊的操作數或表達式都會(huì )參與計算。

對于&&:當&&左邊的操作數為false或左邊表達式結果為false時(shí),&&右邊的操作數或表達式將不參與計算,此時(shí)最終結果都為false。

綜上所述,如果邏輯與運算的第一個(gè)操作數是false或第一個(gè)表達式的結果為false時(shí),對于第二個(gè)操作數或表達式是否進(jìn)行運算,對最終的結果沒(méi)有影響,結果肯定是false。推介平時(shí)多使用&&,因為它效率更高些。

、&還可以用作位運算符。當&兩邊操作數或兩邊表達式的結果不是boolean類(lèi)型時(shí),&用于按位與運算符的操作。

|和||的區別和聯(lián)系與&和&&的區別和聯(lián)系類(lèi)似

9.用最有效率的方法算出2乘以8等于多少

使用位運算來(lái)實(shí)現效率最高。位運算符是對操作數以二進(jìn)制比特位為單位進(jìn)行操作和運算,操作數和結果都是整型數。對于位運算符“<<”, 是將一個(gè)數左移n位,就相當于乘以了2的n次方,那么,一個(gè)數乘以8只要將其左移3位即可,位運算cpu直接支持的,效率最高。所以,2乘以8等于幾的最效率的方法是2 << 3

10.基本數據類(lèi)型的類(lèi)型轉換規則

基本類(lèi)型轉換分為自動(dòng)轉換和強制轉換。

自動(dòng)轉換規則:容量小的數據類(lèi)型可以自動(dòng)轉換成容量大的數據類(lèi)型,也可

以說(shuō)低級自動(dòng)向高級轉換。這兒的容量指的不是字節數,而是指類(lèi)型表述的范圍。

強制轉換規則:高級變?yōu)榈图壭枰獜娭妻D換。

如何轉換:

(1)賦值運算符“=”右邊的轉換,先自動(dòng)轉換成表達式中級別最高的數據類(lèi)型,再進(jìn)行運算。

(2)賦值運算符“=”兩側的轉換,若左邊級別>右邊級別,會(huì )自動(dòng)轉換;若左邊級別 == 右邊級別,不用轉換;若左邊級別 < 右邊級別,需強制轉換。

(3)可以將整型常量直接賦值給byte, short, char等類(lèi)型變量,而不需要進(jìn)行強制類(lèi)型轉換,前提是不超出其表述范圍,否則必須進(jìn)行強制轉換。

11.if多分支語(yǔ)句和switch多分支語(yǔ)句的異同之處

相同之處:都是分支語(yǔ)句,多超過(guò)一種的情況進(jìn)行判斷處理。

不同之處:

switch更適合用于多分支情況,就是有很多種情況需要判斷處理,判斷條件類(lèi)型單一,只有一個(gè)入口,在分支執行完后(如果沒(méi)有break跳出),不加判斷地執行下去;而if—elseif---else多分枝主要適用于分支較少的分支結構,判斷類(lèi)型不是單一,只要一個(gè)分支被執行后,后邊的分支不再執行。switch為等值判斷(不允許比如>= <=),而if為等值和區間都可以,if的使用范圍大。

12.while和do-while循環(huán)的區別

while先判斷后執行,第一次判斷為false,循環(huán)體一次都不執行

do while先執行 后判斷,最少執行1次。

如果while循環(huán)第一次判斷為true, 則兩種循環(huán)沒(méi)有區別。

13.break和continue的作用

break: 結束當前循環(huán)并退出當前循環(huán)體。

break還可以退出switch語(yǔ)句

continue: 循環(huán)體中后續的語(yǔ)句不執行,但是循環(huán)沒(méi)有結束,繼續進(jìn)行循環(huán)條件的判斷(for循環(huán)還會(huì )i++)。continue只是結束本次循環(huán)。

14.請使用遞歸算法計算n!
package com.bjsxt;
import java.io.File;
public class $ {
public static void main(String[] args) {
        String path = "D:/301SXT";
        test(path);
    }
    private static void test(String path) {
        File f = new File(path);
        File[] fs = f.listFiles();
        if (fs == null) {
            return;
        }
        for (File file : fs) {
            if (file.isFile()) {
                System.out.println(file.getPath());
            } else {
                test(file.getPath());
            }
        }
    }
15.遞歸的定義和優(yōu)缺點(diǎn)

遞歸算法是一種直接或者間接地調用自身算法的過(guò)程。在計算機編寫(xiě)程序中,遞歸算法對解決一大類(lèi)問(wèn)題是十分有效的,它往往使算法的描述簡(jiǎn)潔而且易于理解。

遞歸算法解決問(wèn)題的特點(diǎn):

(1) 遞歸就是在過(guò)程或函數里調用自身。

(2) 在使用遞歸策略時(shí),必須有一個(gè)明確的遞歸結束條件,稱(chēng)為遞歸出口。

(3) 遞歸算法解題通常顯得很簡(jiǎn)潔,但運行效率較低。所以一般不提倡用遞歸算法設計程序。

(4) 在遞歸調用的過(guò)程當中系統為每一層的返回點(diǎn)、局部量等開(kāi)辟了棧來(lái)存儲。遞歸次數過(guò)多容易造成棧溢出等。所以一般不提倡用遞歸算法設計程序。

16.數組的特征

數組是(相同類(lèi)型數據)的(有序)(集合)

數組會(huì )在內存中開(kāi)辟一塊連續的空間,每個(gè)空間相當于之前的一個(gè)變量,稱(chēng)為數組的元素element

元素的表示 數組名[下標或者索引] scores[7] scores[0] scores[9]

索引從0開(kāi)始

每個(gè)數組元素有默認值 double 0.0 boolean false int 0

數組元素有序的,不是大小順序,是索引 的順序

數組中可以存儲基本數據類(lèi)型,可以存儲引用數據類(lèi)型;但是對于一個(gè)數組而言,數組的類(lèi)型是固定的,只能是一個(gè)

length:數組的長(cháng)度

數組的長(cháng)度是固定的,一經(jīng)定義,不能再發(fā)生變化(數組的擴容)

17.請寫(xiě)出冒泡排序代碼
package com.bjsxt;

public class TestBubbleSort {
public static void sort(int[] a) {
int temp = 0;
// 外層循環(huán),它決定一共走幾趟
for (int i = 0; i <a.length-1; ++i) {
//內層循環(huán),它決定每趟走一次
for (int j = 0; j <a.length-i-1 ; ++j) {
//如果后一個(gè)大于前一個(gè)
if (a[j + 1] < a[j]) {
//換位
temp = a[j];a[j] = a[j + 1];a[j + 1] = temp;
}
}
}

public static void sort2(int[] a) {
int temp = 0;
for (int i = 0; i <a.length-1; ++i) {
//通過(guò)符號位可以減少無(wú)謂的比較,如果已經(jīng)有序了,就退出循環(huán)
int flag = 0;
for (int j = 0; j <a.length-1-i ; ++j) {
if (a[j + 1] < a[j]) {
temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
flag = 1;
}
}
if(flag == 0){
break;
}
}
}
}
18.請寫(xiě)出選擇排序的代碼
package com.bjsxt;

public class TestSelectSort {
public static void sort(int arr[]) {
int temp = 0;
for (int i = 0; i < arr.length - 1; i++) {
// 認為目前的數就是最小的, 記錄最小數的下標
int minIndex = i;
for (int j = i + 1; j < arr.length; j++) {
if (arr[minIndex] > arr[j]) {
// 修改最小值的下標
minIndex = j;
}
}
// 當退出for就找到這次的最小值
if (i != minIndex) {
temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
}
}
}
}
19.請寫(xiě)出插入排序的代碼
package com.bjsxt;

public class TestInsertSort {
public static void sort(int arr[]) {
int i, j;
for (i = 1; i < arr.length; i++) {
int temp = arr[i];
for (j = i; j > 0 && temp < arr[j - 1]; j--) {
arr[j] = arr[j - 1];
}
arr[j] = temp;
}
}
}
20.可變參數的作用和特點(diǎn)

總結1:可變參數

1.可變參數的形式 ...

2.可變參數只能是方法的形參

3.可變參數對應的實(shí)參可以0,1,2.....個(gè),也可以是一個(gè)數組

4.在可變參數的方法中,將可變參數當做數組來(lái)處理

5.可變參數最多有一個(gè),只能是最后一個(gè)

6.可變參數好處:方便 簡(jiǎn)單 減少重載方法的數量

7.如果定義了可變參數的方法,不允許同時(shí)定義相同類(lèi)型數組參數的方法

總結2:數組做形參和可變參數做形參聯(lián)系和區別

聯(lián)系:

1.實(shí)參都可以是數組;2.方法體中,可變參數當做數組來(lái)處理

區別:

1.個(gè)數不同 可變參數只能有一個(gè)數組參數可以多個(gè)

2.位置不同 可變參數只能是最后一個(gè) 數組參數位置任意

3.實(shí)參不同 可變參數實(shí)參可以0,1,2.....個(gè),也可以是一個(gè)數組,數組的實(shí)參只能是數組

21.類(lèi)和對象的關(guān)系

類(lèi)是對象的抽象,而對象是類(lèi)的具體實(shí)例。類(lèi)是抽象的,不占用內存,而對象是具體的,占用存儲空間。類(lèi)是用于創(chuàng )建對象的藍圖,它是一個(gè)定義包括在特定類(lèi)型的對象中的方法和變量的軟件模板。

類(lèi)和對象好比圖紙和實(shí)物的關(guān)系,模具和鑄件的關(guān)系。

比如人類(lèi)就是一個(gè)概念,人類(lèi)具有身高,體重等屬性。人類(lèi)可以做吃飯、說(shuō)話(huà)等方法。

小明就是一個(gè)具體的人,也就是實(shí)例,他的屬性是具體的身高200cm,體重180kg,他做的方法是具體的吃了一碗白米飯,說(shuō)了“12345”這樣一句話(huà)。

22.面向過(guò)程和面向對象的區別

兩者都是軟件開(kāi)發(fā)思想,先有面向過(guò)程,后有面向對象。在大型項目中,針對面向過(guò)程的不足推出了面向對象開(kāi)發(fā)思想。

比喻

蔣介石和毛澤東分別是面向過(guò)程和面向對象的杰出代表,這樣充分說(shuō)明,在解決復制問(wèn)題時(shí),面向對象有更大的優(yōu)越性。

面向過(guò)程是蛋炒飯,面向對象是蓋澆飯。蓋澆飯的好處就是“菜”“飯”分離,從而提高了制作蓋澆飯的靈活性。飯不滿(mǎn)意就換飯,菜不滿(mǎn)意換菜。用軟件工程的專(zhuān)業(yè)術(shù)語(yǔ)就是“可維護性”比較好,“飯” 和“菜”的耦合度比較低。

區別

編程思路不同: 面向過(guò)程以實(shí)現功能的函數開(kāi)發(fā)為主,而面向對象要首先抽象出類(lèi)、屬性及其方法,然后通過(guò)實(shí)例化類(lèi)、執行方法來(lái)完成功能。

封裝性:都具有封裝性,但是面向過(guò)程是封裝的是功能,而面向對象封裝的是數據和功能。

面向對象具有繼承性和多態(tài)性,而面向過(guò)程沒(méi)有繼承性和多態(tài)性,所以面向對象優(yōu)勢是明顯。

方法重載和方法重寫(xiě)(覆蓋)的區別

英文 位置不同 作用不同
重載 overload 同一個(gè)類(lèi)中 在一個(gè)類(lèi)里面為一種行為提供多種實(shí)現方式并提高可讀性
重寫(xiě) override 子類(lèi)和父類(lèi)間 父類(lèi)方法無(wú)法滿(mǎn)足子類(lèi)的要求,子類(lèi)通過(guò)方法重寫(xiě)滿(mǎn)足要求
修飾符 返回值 方法名 參數 拋出異常
重載 無(wú)關(guān) 無(wú)關(guān) 相同 不同 無(wú)關(guān)
重寫(xiě) 大于等于 小于等于 相同 相同 小于等于
23.this和super關(guān)鍵字的作用

this是對象內部指代自身的引用,同時(shí)也是解決成員變量和局部變量同名問(wèn)題;this可以調用成員變量,不能調用局部變量;this也可以調用成員方法,但是在普通方法中可以省略this,在構造方法中不允許省略,必須是構造方法的第一條語(yǔ)句。,而且在靜態(tài)方法當中不允許出現this關(guān)鍵字。

super代表對當前對象的直接父類(lèi)對象的引用,super可以調用直接父類(lèi)的成員變量(注意權限修飾符的影響,比如不能訪(fǎng)問(wèn)private成員)

super可以調用直接父類(lèi)的成員方法(注意權限修飾符的影響,比如不能訪(fǎng)問(wèn)private成員);super可以調用直接父類(lèi)的構造方法,只限構造方法中使用,且必須是第一條語(yǔ)句。

24.static關(guān)鍵字的作用

static可以修飾變量、方法、代碼塊和內部類(lèi)

static屬性屬于這個(gè)類(lèi)所有,即由該類(lèi)創(chuàng )建的所有對象共享同一個(gè)static屬性??梢詫ο髣?chuàng )建后通過(guò)對象名.屬性名和類(lèi)名.屬性名兩種方式來(lái)訪(fǎng)問(wèn)。也可以在沒(méi)有創(chuàng )建任何對象之前通過(guò)類(lèi)名.屬性名的方式來(lái)訪(fǎng)問(wèn)。

static變量和非static變量的區別(都是成員變量,不是局部變量)

1.在內存中份數不同

不管有多少個(gè)對象,static變量只有1份。對于每個(gè)對象,實(shí)例變量都會(huì )有單獨的一份

static變量是屬于整個(gè)類(lèi)的,也稱(chēng)為類(lèi)變量。而非靜態(tài)變量是屬于對象的,也稱(chēng)為實(shí)例變量

2.在內存中存放的位置不同

2.在內存中存放的位置不同

3.訪(fǎng)問(wèn)的方式不同

實(shí)例變量: 對象名.變量名 stu1.name="小明明";

靜態(tài)變量:對象名.變量名 stu1.schoolName="西二旗小學(xué)"; 不推薦如此使用

類(lèi)名.變量名 Student.schoolName="東三旗小學(xué)"; 推薦使用

4.在內存中分配空間的時(shí)間不同

Student.schoolName="東三旗小學(xué)";或者Student stu1 = new Student("小明","男",20,98);

static方法也可以通過(guò)對象名.方法名和類(lèi)名.方法名兩種方式來(lái)訪(fǎng)問(wèn)

static代碼塊。當類(lèi)被第一次使用時(shí)(可能是調用static屬性和方法,或者創(chuàng )建其對象)執行靜態(tài)代碼塊,且只被執行一次,主要作用是實(shí)現static屬性的初始化。

static內部類(lèi):屬于整個(gè)外部類(lèi),而不是屬于外部類(lèi)的每個(gè)對象。不能訪(fǎng)問(wèn)外部類(lèi)的非靜態(tài)成員(變量或者方法),.可以訪(fǎng)問(wèn)外部類(lèi)的靜態(tài)成員

25.final和abstract關(guān)鍵字的作用

final和abstract是功能相反的兩個(gè)關(guān)鍵字,可以對比記憶

abstract可以用來(lái)修飾類(lèi)和方法,不能用來(lái)修飾屬性和構造方法;使用abstract修飾的類(lèi)是抽象類(lèi),需要被繼承,使用abstract修飾的方法是抽象方法,需要子類(lèi)被重寫(xiě)。

final可以用來(lái)修飾類(lèi)、方法和屬性,不能修飾構造方法。使用final修飾的類(lèi)不能被繼承,使用final修飾的方法不能被重寫(xiě),使用final修飾的變量的值不能被修改,所以就成了常量。

特別注意:final修飾基本類(lèi)型變量,其值不能改變,由原來(lái)的變量變?yōu)槌A?;但是final修飾引用類(lèi)型變量,棧內存中的引用不能改變,但是所指向的堆內存中的對象的屬性值仍舊可以改變。例如

package com.bjsxt;

class Test {
    public static void main(String[] args) {
        final Dog dog = new Dog("歐歐");
        dog.name = "美美";//正確
        dog = new Dog("亞亞");//錯誤
    }
}
26.final、finally、finalize的區別

final修飾符(關(guān)鍵字)如果一個(gè)類(lèi)被聲明為final,意味著(zhù)它不能再派生出新的子類(lèi),不能作為父類(lèi)被繼承例如:String類(lèi)、Math類(lèi)等。將變量或方法聲明為final,可以保證它們在使用中不被改變。被聲明為final的變量必須在聲明時(shí)給定初值,而在以后的引用中只能讀取,不可修改。被聲明為final的方法也同樣只能使用,不能重寫(xiě),但是能夠重載。 使用final修飾的對象,對象的引用地址不能變,但是對象的值可以變!

finally在異常處理時(shí)提供 finally 塊來(lái)執行任何清除操作。如果有finally的話(huà),則不管是否發(fā)生異常,finally語(yǔ)句都會(huì )被執行。一般情況下,都把關(guān)閉物理連接(IO流、數據庫連接、Socket連接)等相關(guān)操作,放入到此代碼塊中。

finalize方法名。Java 技術(shù)允許使用 finalize() 方法在垃圾收集器將對象從內存中清除出去之前做必要清理工作。finalize() 方法是在垃圾收集器刪除對象之前被調用的。它是在 Object 類(lèi)中定義的,因此所有的類(lèi)都繼承了它。子類(lèi)覆蓋 finalize() 方法以整理系統資源或者執行其他清理工作。 一般情況下,此方法由JVM調用,程序員不要去調用!

27.寫(xiě)出java.lang.Object類(lèi)的六個(gè)常用方法

(1)public boolean equals(java.lang.Object)

比較對象的地址值是否相等,如果子類(lèi)重寫(xiě),則比較對象的內容是否相等;

(2)public native int hashCode() 獲取哈希碼

(3)public java.lang.String toString() 把數據轉變成字符串

(4)public final native java.lang.Class getClass() 獲取類(lèi)結構信息

(5)protected void finalize() throws java.lang.Throwable

垃圾回收前執行的方法

(6)protected native Object clone() throws

java.lang.CloneNotSupportedException 克隆

(7)public final void wait() throws java.lang.InterruptedException

多線(xiàn)程中等待功能

(8)public final native void notify() 多線(xiàn)程中喚醒功能

(9)public final native void notifyAll() 多線(xiàn)程中喚醒所有等待線(xiàn)程的功能

28.private/默認/protected/public權限修飾符的區別
同一個(gè)類(lèi) 同一個(gè)包 子類(lèi) 所有類(lèi)
private *
defailt * *
protected * * *
public * * * *

類(lèi)的訪(fǎng)問(wèn)權限只有兩種

public公共的 可被同一項目中所有的類(lèi)訪(fǎng)問(wèn)。 (必須與文件名同名)

default默認的 可被同一個(gè)包中的類(lèi)訪(fǎng)問(wèn)。

成員(成員變量或成員方法)訪(fǎng)問(wèn)權限共有四種:

public 公共的 可以被項目中所有的類(lèi)訪(fǎng)問(wèn)。(項目可見(jiàn)性)

protected 受保護的 可以被這個(gè)類(lèi)本身訪(fǎng)問(wèn);同一個(gè)包中的所有其他的類(lèi)訪(fǎng)問(wèn);被它的子類(lèi)(同一個(gè)包以及不同包中的子類(lèi))訪(fǎng)問(wèn)。(子類(lèi)可見(jiàn)性)

default 默認的被這個(gè)類(lèi)本身訪(fǎng)問(wèn);被同一個(gè)包中的類(lèi)訪(fǎng)問(wèn)。(包可見(jiàn)性)

private 私有的 只能被這個(gè)類(lèi)本身訪(fǎng)問(wèn)。(類(lèi)可見(jiàn)性)

29.繼承條件下構造方法的執行過(guò)程

繼承條件下構造方法的調用規則如下:

情況1:如果子類(lèi)的構造方法中沒(méi)有通過(guò)super顯式調用父類(lèi)的有參構造方法,也沒(méi)有通過(guò)this顯式調用自身的其他構造方法,則系統會(huì )默認先調用父類(lèi)的無(wú)參構造方法。在這種情況下,寫(xiě)不寫(xiě)“super();”語(yǔ)句,效果是一樣的。

情況2:如果子類(lèi)的構造方法中通過(guò)super顯式調用父類(lèi)的有參構造方法,那將執行父類(lèi)相應構造方法,而不執行父類(lèi)無(wú)參構造方法。

情況3:如果子類(lèi)的構造方法中通過(guò)this顯式調用自身的其他構造方法,在相應構造方法中應用以上兩條規則。

特別注意的是,如果存在多級繼承關(guān)系,在創(chuàng )建一個(gè)子類(lèi)對象時(shí),以上規則會(huì )多次向更高一級父類(lèi)應用,一直到執行頂級父類(lèi)Object類(lèi)的無(wú)參構造方法為止。

30.==和equals的區別和聯(lián)系

“==”是關(guān)系運算符,equals()是方法,同時(shí)他們的結果都返回布爾值;

“==”使用情況如下:

a) 基本類(lèi)型,比較的是值

b) 引用類(lèi)型,比較的是地址

c) 不能比較沒(méi)有父子關(guān)系的兩個(gè)對象

equals()方法使用如下:

a) 系統類(lèi)一般已經(jīng)覆蓋了equals(),比較的是內容。

b) 用戶(hù)自定義類(lèi)如果沒(méi)有覆蓋equals(),將調用父類(lèi)的equals (比如是Object),而Object的equals的比較是地址(return (this == obj);)

c) 用戶(hù)自定義類(lèi)需要覆蓋父類(lèi)的equals()

注意:Object的==和equals比較的都是地址,作用相同

31.談?wù)凧ava的多態(tài)

實(shí)現多態(tài)的三個(gè)條件(前提條件,向上轉型、向下轉型)

1、繼承的存在;(繼承是多態(tài)的基礎,沒(méi)有繼承就沒(méi)有多態(tài))

2、子類(lèi)重寫(xiě)父類(lèi)的方法。(多態(tài)下會(huì )調用子類(lèi)重寫(xiě)后的方法)

3、父類(lèi)引用變量指向子類(lèi)對象。(涉及子類(lèi)到父類(lèi)的類(lèi)型轉換)

向上轉型 Student person = new Student()

將一個(gè)父類(lèi)的引用指向一個(gè)子類(lèi)對象,成為向上轉型,自動(dòng)進(jìn)行類(lèi)型轉換。此時(shí)通過(guò)父類(lèi)引用變量調用的方法是子類(lèi)覆蓋或繼承父類(lèi)的方法,而不是父類(lèi)的方法此時(shí)通過(guò)父類(lèi)引用變量無(wú)法調用子類(lèi)特有的方法。

向下轉型 Student stu = (Student)person;

將一個(gè)指向子類(lèi)對象的引用賦給一個(gè)子類(lèi)的引用,成為向下轉型,此時(shí)必須進(jìn)行強制類(lèi)型轉換。向下轉型必須轉換為父類(lèi)引用指向的真實(shí)子類(lèi)類(lèi)型,,否則將出現ClassCastException,不是任意的強制轉換

向下轉型時(shí)可以結合使用instanceof運算符進(jìn)行強制類(lèi)型轉換,比如出現轉換異常---ClassCastException

32.簡(jiǎn)述Java的垃圾回收機制

傳統的C/C++語(yǔ)言,需要程序員負責回收已經(jīng)分配內存。

顯式回收垃圾回收的缺點(diǎn):

1)程序忘記及時(shí)回收,從而導致內存泄露,降低系統性能。

2)程序錯誤回收程序核心類(lèi)庫的內存,導致系統崩潰。

Java語(yǔ)言不需要程序員直接控制內存回收,是由JRE在后臺自動(dòng)回收不再使用的內存,稱(chēng)為垃圾回收機制,簡(jiǎn)稱(chēng)GC;

1)可以提高編程效率。

2)保護程序的完整性。

3)其開(kāi)銷(xiāo)影響性能。Java虛擬機必須跟蹤程序中有用的對象,確定哪些是無(wú)用的。

垃圾回收機制的 特點(diǎn)

1)垃圾回收機制回收JVM堆內存里的對象空間,不負責回收棧內存數據。

2)對其他物理連接,比如數據庫連接、輸入流輸出流、Socket連接無(wú)能為力。

3)垃圾回收發(fā)生具有不可預知性,程序無(wú)法精確控制垃圾回收機制執行。

4)可以將對象的引用變量設置為null,暗示垃圾回收機制可以回收該對象。

現在的JVM有多種垃圾回收 實(shí)現算法,表現各異。

垃圾回收機制回收任何對象之前,總會(huì )先調用它的finalize方法(如果覆蓋該方法,讓一個(gè)新的引用變量重新引用該對象,則會(huì )重新激活對象)。

程序員可以通過(guò)System.gc()或者Runtime.getRuntime().gc()來(lái)通知系統進(jìn)行垃圾回收,會(huì )有一些效果,但是系統是否進(jìn)行垃圾回收依然不確定。

永遠不要主動(dòng)調用某個(gè)對象的finalize方法,應該交給垃圾回收機制調用。

33.基本數據類(lèi)型和包裝類(lèi)

1) 八個(gè)基本數據類(lèi)型的包裝類(lèi)

基本數據類(lèi)型 包裝類(lèi)
byte Byte
boolean Boolean
short Short
char Character
int Integer
long Long
float Float
double Double

2)為什么為基本類(lèi)型引入包裝類(lèi)

2.1基本數據類(lèi)型有方便之處,簡(jiǎn)單、高效。

2.2但是Java中的基本數據類(lèi)型卻是不面向對象的(沒(méi)有屬性、方法),這在實(shí)際使用時(shí)存在很多的不便(比如集合的元素只能是Object)。

為了解決這個(gè)不足,在設計類(lèi)時(shí)為每個(gè)基本數據類(lèi)型設計了一個(gè)對應的類(lèi)進(jìn)行包裝,這樣八個(gè)和基本數據類(lèi)型對應的類(lèi)統稱(chēng)為包裝類(lèi)(Wrapper Class)。

3) 包裝類(lèi)和基本數據類(lèi)型之間的轉換

3.1包裝類(lèi)------ wrapperInstance.xxxValue() ------>基本數據類(lèi)型

3.2包裝類(lèi)-------new WrapperClass(primitive)

3.2包裝類(lèi)-------new WrapperClass(primitive)

4) 自動(dòng)裝箱和自動(dòng)拆箱

JDK1.5提供了自動(dòng)裝箱(autoboxing)和自動(dòng)拆箱(autounboxing)功能, 從而實(shí)現了包裝類(lèi)和基本數據類(lèi)型之間的自動(dòng)轉換

5) 包裝類(lèi)還可以實(shí)現基本類(lèi)型變量和字符串之間的轉換

基本類(lèi)型變量--->String.valueof()--->字符串 基本類(lèi)型變量<---WrapperClass.parseXxx(string)---字符串

34.Integer與int的區別

int是java提供的8種原始數據類(lèi)型之一,Java為每個(gè)原始類(lèi)型提供了封裝類(lèi),Integer是java為int提供的封裝類(lèi)。

int是java提供的8種原始數據類(lèi)型之一,Java為每個(gè)原始類(lèi)型提供了封裝類(lèi),Integer是java為int提供的封裝類(lèi)。

在Hibernate中,如果將OID定義為Integer類(lèi)型,那么Hibernate就可以根據其值是否為null而判斷一個(gè)對象是否是臨時(shí)的,如果將OID定義為了int類(lèi)型,還需要在hbm映射文件中設置其unsaved-value屬性為0。

另外,Integer提供了多個(gè)與整數相關(guān)的操作方法,例如,將一個(gè)字符串轉換成整數,Integer中還定義了表示整數的最大值和最小值的常量。

35.java.sql.Date和java.util.Date的聯(lián)系和區別

1) java.sql.Date是java.util.Date的子類(lèi),是一個(gè)包裝了毫秒值的瘦包裝器,允許 JDBC 將毫秒值標識為 SQL DATE 值。毫秒值表示自 1970 年 1 月 1 日 00:00:00 GMT 以來(lái)經(jīng)過(guò)的毫秒數。 為了與 SQL DATE 的定義一致,由 java.sql.Date 實(shí)例包裝的毫秒值必須通過(guò)將時(shí)間、分鐘、秒和毫秒設置為與該實(shí)例相關(guān)的特定時(shí)區中的零來(lái)“規范化”。 說(shuō)白了,java.sql.Date就是與數據庫Date相對應的一個(gè)類(lèi)型,而java.util.Date是純java的Date。

2)JAVA里提供的日期和時(shí)間類(lèi),java.sql.Date和java.sql.Time,只會(huì )從數據庫里讀取某部分值,這有時(shí)會(huì )導致丟失數據。例如一個(gè)包含2002/05/22 5:00:57 PM的字段,讀取日期時(shí)得到的是2002/05/22,而讀取時(shí)間時(shí)得到的是5:00:57 PM. 你需要了解數據庫里存儲時(shí)間的精度。有些數據庫,比如MySQL,精度為毫秒,然而另一些數據庫,包括Oracle,存儲SQL DATE類(lèi)型數據時(shí),毫秒部分的數據是不保存的。以下操作中容易出現不易被發(fā)現的BUG:獲得一個(gè)JAVA里的日期對象。 從數據庫里讀取日期 試圖比較兩個(gè)日期對象是否相等。如果毫秒部分丟失,本來(lái)認為相等的兩個(gè)日期對象用Equals方法可能返回false。.sql.Timestamp類(lèi)比java.util.Date類(lèi)精確度要高。這個(gè)類(lèi)包了一個(gè)getTime()方法,但是它不會(huì )返回額外精度部分的數據,因此必須使用...

總之,java.util.Date 就是Java的日期對象,而java.sql.Date 是針對SQL語(yǔ)句使用的,只包含日期而沒(méi)有時(shí)間部分。

36.使用遞歸算法輸出某個(gè)目錄下所有文件和子目錄列表
package com.bjsxt;
import java.io.File;
public class $ {
public static void main(String[] args) {
        String path = "D:/301SXT";
        test(path);
    }
    private static void test(String path) {
        File f = new File(path);
        File[] fs = f.listFiles();
        if (fs == null) {
            return;
        }
        for (File file : fs) {
            if (file.isFile()) {
                System.out.println(file.getPath());
            } else {
                test(file.getPath());
            }
        }
    }
37.關(guān)于Java編譯,下面哪一個(gè)正確()(選擇一項)
A Java程序經(jīng)編譯后產(chǎn)生machine code
B. Java程序經(jīng)編譯后會(huì )生產(chǎn)byte code
C. Java程序經(jīng)編譯后會(huì )產(chǎn)生DLL
D. 以上都不正確
答案:B
分析: Java是解釋型語(yǔ)言,編譯出來(lái)的是字節碼; 因此A不正確,C是C/C++語(yǔ)言編譯動(dòng)態(tài)鏈接庫的文件為.DLL; 正確答案為B
38.下列說(shuō)法正確的有()(選擇一項)
A class中的construtor不可省略
B. construtor與class同名,但方法不能與class同名
C. construtor在一個(gè)對象被new時(shí)執行
D. 一個(gè)class只能定義一個(gè)construtor
答案:C
分析:A:如果class中的construtor省略不寫(xiě),系統會(huì )默認提供一個(gè)無(wú)參構造
B:方法名可以與類(lèi)名同名,只是不符合命名規范
D:一個(gè)class中可以定義N多個(gè)construtor,這些construtor構成構造方法的重載
39.Java中接口的修飾符可以為()(選擇一項)
A private
B. protected
C. final
D. abstract
答案:D
分析:接口中的訪(fǎng)問(wèn)權限修飾符只可以是public或default
接口中的所有的方法必須要實(shí)現類(lèi)實(shí)現,所以不能使用final
接口中所有的方法默認都是abstract的,所以接口可以使用abstract修飾,但通常abstract可以省略不寫(xiě)
40.給定以下代碼,程序將輸出 ()(選擇一項)
class A {
public A(){
System.out.println("A");
}
}
class B extends A{
public B(){
System.out.println("B");
}
public static void main(String[] args) {
B b=new B();
}
}
A 不能通過(guò)編譯
B. 通過(guò)編譯,輸出AB
C. 通過(guò)編譯,輸出B
D. 通過(guò)編譯,輸出A
答案:B
分析:在繼承關(guān)系下,創(chuàng )建子類(lèi)對象,先執行父類(lèi)的構造方法,再執行子類(lèi)的構造方法。
41.下列關(guān)于關(guān)鍵字的使用說(shuō)法錯誤的是()(選擇一項)
A abstract不能與final并列修飾同一個(gè)類(lèi)
B. abstract類(lèi)中可以有private的成員
C. abstract方法必須在abstract類(lèi)中
D. static方法能處理非static的屬性
答案:D
分析:因為static得方法在裝載class得時(shí)候首先完成,比 構造方法早,此時(shí)非static得屬性和方法還沒(méi)有完成初始化所以不能調用。
42.下列哪些語(yǔ)句關(guān)于內存回收的說(shuō)法是正確的()(選擇一項)
A 程序員必須創(chuàng )建一個(gè)線(xiàn)程來(lái)釋放內存
B. 內存回收程序負責釋放無(wú)用內存
C. 內存回收程序允許程序員直接釋放內存
D. 內存回收程序可以在指定的時(shí)間釋放內存對象
答案:B
分析: A. 程序員不需要創(chuàng )建線(xiàn)程來(lái)釋放內存.
C. 也不允許程序員直接釋放內存.
D. 不一定在什么時(shí)刻執行垃圾回收.
43.選出合理的標識符()(選擇兩項)
A _sysl_111
B. 2 mail
C. $change
D. class
答案:AC
分析: 標識符的命令規范,可以包含字母、數字、下劃線(xiàn)、$,不能以數字開(kāi)頭,不能是Java關(guān)鍵字
44.下列說(shuō)法正確的是()(選擇多項)
A java.lang.Cloneable是類(lèi)
B. java.langRunnable是接口
C. Double對象在java.lang包中
D. Double a=1.0是正確的java語(yǔ)句
Double a=1.0是正確的java語(yǔ)句
分析:java.lang.Cloneable是接口
45.定義一個(gè)類(lèi)名為”MyClass.java”的類(lèi),并且該類(lèi)可被一個(gè)工程中的所有類(lèi)訪(fǎng)問(wèn),那么該類(lèi)的正確聲明為()(選擇兩項)
A 45.定義一個(gè)類(lèi)名為”MyClass.java”的類(lèi),并且該類(lèi)可被一個(gè)工程中的所有類(lèi)訪(fǎng)問(wèn),那么該類(lèi)的正確聲明為()(選擇兩項)
B. class MyClass extends Object
C. public class MyClass
D. public class MyClass extends Object
答案:CD
分析: A 類(lèi)的訪(fǎng)問(wèn)權限只能是public或default
B使用默認訪(fǎng)問(wèn)權限的類(lèi),只能在本包中訪(fǎng)問(wèn)
46.面向對象的特征有哪些方面?請用生活中的例子來(lái)描述。

答: 面向對象的三大特征:封裝、繼承、多態(tài)。

舉例:(比如設計一個(gè)游戲)我現在創(chuàng )建了一個(gè)對象,名叫戰士。

戰士的屬性是—性別,年齡,職業(yè),等級,戰斗力,血量。

它的方法—戰斗,逃跑,吃飯,睡覺(jué),死。

后來(lái),我又建了一個(gè)對象,叫人。

屬性:性別,年齡,職業(yè),等級,血量

方法:逃跑,吃飯,睡覺(jué),死。

我讓人,成為戰士的父類(lèi),戰士可以直接繼承人的屬性和方法。

戰士修改成—

屬性:戰斗力。

方法:戰斗。

看上去戰士的資料變少了,實(shí)際上沒(méi)有,我們仍然可以調用方法—戰士.死。

而且我們還可以重載戰士.死的方法,簡(jiǎn)稱(chēng)重載死法。

我還建了一個(gè)對象—法師,父類(lèi)也是人。

屬性:法力值

方法:施法,泡妞。

你看,用了繼承,創(chuàng )建對象變得更方便了。

再后來(lái),我又建立了一個(gè)對象,叫怪物。

屬性:等級,戰力,血量。

方法:戰斗,死。

建了個(gè)對象,叫白兔怪,父類(lèi)怪物,可繼承怪物所有的屬性和方法。

屬性:毛色。

方法:賣(mài)萌,吃胡蘿卜。

47.說(shuō)明內存泄漏和內存溢出的區別和聯(lián)系,結合項目經(jīng)驗描述Java程序中如何檢測?如何解決?

答:

內存溢出 out of memory,是指程序在申請內存時(shí),沒(méi)有足夠的內存空間供其使用,出現out of memory;比如申請了一個(gè)integer,但給它存了long才能存下的數,那就是內存溢出。

內存泄露 memory leak,是指程序在申請內存后,無(wú)法釋放已申請的內存空間,一次內存泄露危害可以忽略,但內存泄露堆積后果很?chē)乐?,無(wú)論多少內存,遲早會(huì )被占光。

memory leak會(huì )最終會(huì )導致out of memory!

48.什么是Java的序列化,如何實(shí)現Java的序列化?列舉在哪些程序中見(jiàn)過(guò)Java序列化?

答:Java中的序列化機制能夠將一個(gè)實(shí)例對象(只序列化對象的屬性值,而不會(huì )去序列化什么所謂的方法。)的狀態(tài)信息寫(xiě)入到一個(gè)字節流中使其可以通過(guò)socket進(jìn)行傳輸、或者持久化到存儲數據庫或文件系統中;然后在需要的時(shí)候通過(guò)字節流中的信息來(lái)重構一個(gè)相同的對象。一般而言,要使得一個(gè)類(lèi)可以序列化,只需簡(jiǎn)單實(shí)現java.io.Serializable接口即可。

對象的序列化主要有兩種用途:

1) 把對象的字節序列永久地保存到硬盤(pán)上,通常存放在一個(gè)文件中;

2) 在網(wǎng)絡(luò )上傳送對象的字節序列。

在很多應用中,需要對某些對象進(jìn)行序列化,讓它們離開(kāi)內存空間,入住物理硬盤(pán),以便長(cháng)期保存。比如最常見(jiàn)的是Web服務(wù)器中的Session對象,當有 10萬(wàn)用戶(hù)并發(fā)訪(fǎng)問(wèn),就有可能出現10萬(wàn)個(gè)Session對象,內存可能吃不消,于是Web容器就會(huì )把一些seesion先序列化到硬盤(pán)中,等要用了,再把保存在硬盤(pán)中的對象還原到內存中。

當兩個(gè)進(jìn)程在進(jìn)行遠程通信時(shí),彼此可以發(fā)送各種類(lèi)型的數據。無(wú)論是何種類(lèi)型的數據,都會(huì )以二進(jìn)制序列的形式在網(wǎng)絡(luò )上傳送。發(fā)送方需要把這個(gè)Java對象轉換為字節序列,才能在網(wǎng)絡(luò )上傳送;接收方則需要把字節序列再恢復為Java對象。

49.不通過(guò)構造函數也能創(chuàng )建對象嗎?

答:Java創(chuàng )建對象的幾種方式(重要):

1、 用new語(yǔ)句創(chuàng )建對象,這是最常見(jiàn)的創(chuàng )建對象的方法。

2、 運用反射手段,調用java.lang.Class或者java.lang.reflect.Constructor類(lèi)的newInstance()實(shí)例方法。

3、 調用對象的clone()方法。

4、運用反序列化手段,調用java.io.ObjectInputStream對象的 readObject()方法。

(1)和(2)都會(huì )明確的顯式的調用構造函數 ;(3)是在內存上對已有對象的影印,所以不會(huì )調用構造函數 ;(4)是從文件中還原類(lèi)的對象,也不會(huì )調用構造函數。

50.匿名內部類(lèi)可不可以繼承或實(shí)現接口。為什么?

答:匿名內部類(lèi)是沒(méi)有名字的內部類(lèi),不能繼承其它類(lèi),但一個(gè)內部類(lèi)可以作為一個(gè)接口,由另一個(gè)內部類(lèi)實(shí)現.

1、由于匿名內部類(lèi)沒(méi)有名字,所以它沒(méi)有構造函數。因為沒(méi)有構造函數,所以它必須完全借用父類(lèi)的構造函數來(lái)實(shí)例化,換言之:匿名內部類(lèi)完全把創(chuàng )建對象的任務(wù)交給了父類(lèi)去完成。

2、在匿名內部類(lèi)里創(chuàng )建新的方法沒(méi)有太大意義,但它可以通過(guò)覆蓋父類(lèi)的方法達到神奇效果,如上例所示。這是多態(tài)性的體現。

3、因為匿名內部類(lèi)沒(méi)有名字,所以無(wú)法進(jìn)行向下的強制類(lèi)型轉換,持有對一個(gè)匿名內部類(lèi)對象引用的變量類(lèi)型一定是它的直接或間接父類(lèi)類(lèi)型。

51.在Java中,為什么基本類(lèi)型不能做為HashMap的鍵值,而只能是引用類(lèi)型,把引用類(lèi)型做為HashMap的健值,需要注意哪些地方。

(1) 在Java中是使用泛型來(lái)約束HashMap中的key和value的類(lèi)型的,即HashMap< K, V>;而泛型在Java的規定中必須是對象Object類(lèi)型的,也就是說(shuō)HashMap< K, V>可以理解為HashMap< Object, Object>,很顯然基本數據類(lèi)型不是Object類(lèi)型的,因此不能作為鍵值,只能是引用類(lèi)型。雖然我們在HashMap中可以這樣添加數據:“map.put(1, “Java”);”,但實(shí)際上是將其中的key值1進(jìn)行了自動(dòng)裝箱操作,變?yōu)榱薎nteger類(lèi)型。

(1) 在Java中是使用泛型來(lái)約束HashMap中的key和value的類(lèi)型的,即HashMap< K, V>;而泛型在Java的規定中必須是對象Object類(lèi)型的,也就是說(shuō)HashMap< K, V>可以理解為HashMap< Object, Object>,很顯然基本數據類(lèi)型不是Object類(lèi)型的,因此不能作為鍵值,只能是引用類(lèi)型。雖然我們在HashMap中可以這樣添加數據:“map.put(1, “Java”);”,但實(shí)際上是將其中的key值1進(jìn)行了自動(dòng)裝箱操作,變?yōu)榱薎nteger類(lèi)型。

52.簡(jiǎn)述Java中如何實(shí)現多態(tài)

實(shí)現多態(tài)有三個(gè)前提條件:

1、 繼承的存在;(繼承是多態(tài)的基礎,沒(méi)有繼承就沒(méi)有多態(tài))。

2、子類(lèi)重寫(xiě)父類(lèi)的方法。(多態(tài)下會(huì )調用子類(lèi)重寫(xiě)后的方法)。

3、父類(lèi)引用變量指向子類(lèi)對象。(涉及子類(lèi)到父類(lèi)的類(lèi)型轉換)。

最后使用父類(lèi)的引用變量調用子類(lèi)重寫(xiě)的方法即可實(shí)現多態(tài)。

53.以下對繼承的描述錨誤的是 ()
A Java中的繼承允許一個(gè)子類(lèi)繼承多個(gè)父類(lèi)
B. 父類(lèi)更具有通用性,子類(lèi)更具體
C. Java中的繼承存在著(zhù)傳遞性
D. 當實(shí)例化子類(lèi)時(shí)會(huì )遞歸調用父類(lèi)中的構造方法
答案:A
分析:Java是單繼承的,一個(gè)類(lèi)只能繼承一個(gè)父類(lèi)。
54.Java 中 Math.random()/Math.random()值為?

54.Java 中 Math.random()/Math.random()值為?

如果除數與被除數均為0.0的話(huà),則運行結果為NaN(Not a Number的簡(jiǎn)寫(xiě)),計算錯誤。

55.Java中,如果Manager是Employee的子類(lèi),那么Pair是Pair的子類(lèi)嗎?

不是,兩者沒(méi)有任何關(guān)聯(lián);

Pair是單獨的類(lèi),只不過(guò)用不同類(lèi)型的參數(泛型)進(jìn)行了相應的實(shí)例化而已;所以,Pair< Manager>和Pair< Employee>不是子類(lèi)的關(guān)系。

56.接口和抽象類(lèi)的區別

56.接口和抽象類(lèi)的區別

抽象類(lèi)和接口均包含抽象方法,類(lèi)必須實(shí)現所有的抽象方法,否則是抽象類(lèi)

抽象類(lèi)和接口都不能實(shí)例化,他們位于繼承樹(shù)的頂端,用來(lái)被其他類(lèi)繼承和實(shí)現

兩者的區別主要體現在兩方面:語(yǔ)法方面和設計理念方面

語(yǔ)法方面的區別是比較低層次的,非本質(zhì)的,主要表現在:

接口中只能定義全局靜態(tài)常量,不能定義變量。抽象類(lèi)中可以定義常量和變量。

接口中所有的方法都是全局抽象方法。抽象類(lèi)中可以有0個(gè)、1個(gè)或多個(gè),甚至全部都是抽象方法。

抽象類(lèi)中可以有構造方法,但不能用來(lái)實(shí)例化,而在子類(lèi)實(shí)例化是執行,完成屬于抽象類(lèi)的初始化操作。接口中不能定義構造方法。

一個(gè)類(lèi)只能有一個(gè)直接父類(lèi)(可以是抽象類(lèi)),但可以充實(shí)實(shí)現多個(gè)接口。一個(gè)類(lèi)使用extends來(lái)繼承抽象類(lèi),使用implements來(lái)實(shí)現接口。

一個(gè)類(lèi)只能有一個(gè)直接父類(lèi)(可以是抽象類(lèi)),但可以充實(shí)實(shí)現多個(gè)接口。一個(gè)類(lèi)使用extends來(lái)繼承抽象類(lèi),使用implements來(lái)實(shí)現接口。

抽象類(lèi)體現了一種繼承關(guān)系,目的是復用代碼,抽象類(lèi)中定義了各個(gè)子類(lèi)的相同代碼,可以認為父類(lèi)是一個(gè)實(shí)現了部分功能的“中間產(chǎn)品”,而子類(lèi)是“最終產(chǎn)品”。父類(lèi)和子類(lèi)之間必須存在“is-a”的關(guān)系,即父類(lèi)和子類(lèi)在概念本質(zhì)上應該是相同的。

接口并不要求實(shí)現類(lèi)和接口在概念本質(zhì)上一致的,僅僅是實(shí)現了接口定義的約定或者能力而已。接口定義了“做什么”,而實(shí)現類(lèi)負責完成“怎么做”,體現了功能(規范)和實(shí)現分離的原則。接口和實(shí)現之間可以認為是一種“has-a的關(guān)系”

57.同步代碼塊和同步方法有什么區別

相同點(diǎn):

同步方法就是在方法前加關(guān)鍵字synchronized,然后被同步的方法一次只能有一個(gè)線(xiàn)程進(jìn)入,其他線(xiàn)程等待。而同步代碼塊則是在方法內部使用大括號使得一個(gè)代碼塊得到同步。同步代碼塊會(huì )有一個(gè)同步的“目標”,使得同步塊更加靈活一些(同步代碼塊可以通過(guò)“目標”決定需要鎖定的對象)。

一般情況下,如果此“目標”為this,同步方法和代碼塊沒(méi)有太大的區別。

區別:

同步方法直接在方法上加synchronized實(shí)現加鎖,同步代碼塊則在方法內部加鎖。很明顯,同步方法鎖的范圍比較大,而同步代碼塊范圍要小點(diǎn)。一般同步的范圍越大,性能就越差。所以一般需要加鎖進(jìn)行同步的時(shí)候,范圍越小越好,這樣性能更好。

58.靜態(tài)內部類(lèi)和內部類(lèi)有什么區別

靜態(tài)內部類(lèi)不需要有指向外部類(lèi)的引用。但非靜態(tài)內部類(lèi)需要持有對外部類(lèi)的引用。

靜態(tài)內部類(lèi)可以有靜態(tài)成員(方法,屬性),而非靜態(tài)內部類(lèi)則不能有靜態(tài)成員(方法,屬性)。

非靜態(tài)內部類(lèi)能夠訪(fǎng)問(wèn)外部類(lèi)的靜態(tài)和非靜態(tài)成員。靜態(tài)內部類(lèi)不能訪(fǎng)問(wèn)外部類(lèi)的非靜態(tài)成員,只能訪(fǎng)問(wèn)外部類(lèi)的靜態(tài)成員。

實(shí)例化方式不同:

1) 靜態(tài)內部類(lèi):不依賴(lài)于外部類(lèi)的實(shí)例,直接實(shí)例化內部類(lèi)對象

2) 非靜態(tài)內部類(lèi):通過(guò)外部類(lèi)的對象實(shí)例生成內部類(lèi)對象

59.反射的概念與作用

反射的概念:

反射,一種計算機處理方式。是程序可以訪(fǎng)問(wèn)、檢測和修改它本身狀態(tài)或行為的一種能力。

Java反射可以于運行時(shí)加載,探知和使用編譯期間完全未知的類(lèi).

程序在運行狀態(tài)中, 可以動(dòng)態(tài)加載一個(gè)只有名稱(chēng)的類(lèi), 對于任意一個(gè)已經(jīng)加載的類(lèi),都能夠知道這個(gè)類(lèi)的所有屬性和方法; 對于任意一個(gè)對象,都能調用他的任意一個(gè)方法和屬性;

加載完類(lèi)之后, 在堆內存中會(huì )產(chǎn)生一個(gè)Class類(lèi)型的對象(一個(gè)類(lèi)只有一個(gè)Class對象), 這個(gè)對象包含了完整的類(lèi)的結構信息,而且這個(gè)Class對象就像一面鏡子,透過(guò)這個(gè)鏡子看到類(lèi)的結構,所以被稱(chēng)之為:反射.

java反射使得我們可以在程序運行時(shí)動(dòng)態(tài)加載一個(gè)類(lèi),動(dòng)態(tài)獲取類(lèi)的基本信息和定義的方法,構造函數,域等。

除了檢閱類(lèi)信息外,還可以動(dòng)態(tài)創(chuàng )建類(lèi)的實(shí)例,執行類(lèi)實(shí)例的方法,獲取類(lèi)實(shí)例的域值。反射使java這種靜態(tài)語(yǔ)言有了動(dòng)態(tài)的特性。

反射的作用:

通過(guò)反射可以使程序代碼訪(fǎng)問(wèn)裝載到JVM 中的類(lèi)的內部信息

1) 獲取已裝載類(lèi)的屬性信息

2) 獲取已裝載類(lèi)的方法

3) 獲取已裝載類(lèi)的構造方法信息

反射的優(yōu)點(diǎn):

增加程序的靈活性。

如struts中。請求的派發(fā)控制。

當請求來(lái)到時(shí)。struts通過(guò)查詢(xún)配置文件。找到該請求對應的action。已經(jīng)方法。

然后通過(guò)反射實(shí)例化action。并調用響應method。

如果不適用反射,那么你就只能寫(xiě)死到代碼里了。

所以說(shuō),一個(gè)靈活,一個(gè)不靈活。

很少情況下是非用反射不可的。大多數情況下反射是為了提高程序的靈活性。因此一般框架中使用較多。因為框架要適用更多的情況。對靈活性要求較高。

60.提供Java存取數據庫能力的包是()
A java.sql
B. java.awt
C. java.lang
D. java.swing
答案:A
分析:
java.awt和javax.swing兩個(gè)包是圖形用戶(hù)界面編程所需要的包;
java.lang包則提供了Java編程中用到的基礎類(lèi)。
61.下列運算符合法的是()(多選)
A &&
B. <>
C. if
D. =
答案:AD
分析:
&&是邏輯運算符中的短路與;
<>表示不等于,但是Java中不能這么使用,應該是!=;
if不是運算符;
=是賦值運算符。

62.執行如下程序代碼,c的值打印出來(lái)是()
public class Test1 {
public static void main(String[] args) {
int a = 0;
int c = 0;
do{
--c;
a = a - 1;
} while (a > 0);
System.out.println(c);
}
}
A 0
B. 1
C. -1
D. 死循環(huán)
答案:C
分析:
do-while循環(huán)的特點(diǎn)是先執行后判斷,所以代碼先執行--c操作,得到c為-1,之后執行a=a-1的操作,得到a為-1,然后判斷a是否大于0,判斷條件不成立,退出循環(huán),輸出c為-1。
63.下列哪一種敘述是正確的()
A abstract修飾符可修飾字段,方法和類(lèi)
B. 抽象方法的body部分必須用一對大括號{}包住
C. 聲明抽象方法,大括號可有可無(wú)
D. 聲明抽象方法不可寫(xiě)出大括號
答案:D
分析:
abstract只能修飾方法和類(lèi),不能修飾字段;
抽象方法不能有方法體,即沒(méi)有{};
同B。
64.下列語(yǔ)句正確的是()
A 形式參數可被視為local Variable
B. 形式參數可被視為local Variable
C. 形式參數可被所有的字段修飾符修飾
D. 形式參數為方法被調用時(shí),真正被傳遞的參數
答案:A
分析:
local Variable為局部變量,形參和局部變量一樣都只有在方法內才會(huì )發(fā)生作用,也只能在方法中使用,不會(huì )在方法外可見(jiàn);
對于形式參數只能用final修飾符,其它任何修飾符都會(huì )引起編譯器錯誤;
真正被傳遞的參數是實(shí)參;
形式參數可是基本數據類(lèi)型也可以是引用類(lèi)型(對象)。
65.下列哪種說(shuō)法是正確的()
A 實(shí)例方法可直接調用超類(lèi)的實(shí)例方法
B. 實(shí)例方法可直接調用超類(lèi)的類(lèi)方法
C. 實(shí)例方法可直接調用其他類(lèi)的實(shí)例方法
D. 實(shí)例方法可直接調用本類(lèi)的類(lèi)方法
答案:D
分析:
實(shí)例方法不可直接調用超類(lèi)的私有實(shí)例方法;
實(shí)例方法不可直接調用超類(lèi)的私有的類(lèi)方法;
要看訪(fǎng)問(wèn)權限。
66.Java程序的種類(lèi)有()(多選)
A 類(lèi) (Class)
B. Applet
C. Application
D. Servlet
答案:BCD
分析:
是Java中的類(lèi),不是程序;
內嵌于Web文件中,由瀏覽器來(lái)觀(guān)看的Applet;
可獨立運行的 Application;
服務(wù)器端的 Servlet。
67.下列說(shuō)法正確的有()(多選)
A 環(huán)境變量可在編譯source code時(shí)指定
B. 在編譯程序時(shí),所指定的環(huán)境變置不包括class path
C. javac —次可同時(shí)編譯數個(gè)Java 源文件
D. javac.exe能指定編譯結果要置于哪個(gè)目錄(directory)
答案:BCD
分析:
環(huán)境變量一般都是先配置好再編譯源文件。
68.下列標識符不合法的有()(多選)
A new
B. $Usdollars
C. 1234
D. car.taxi
答案:ACD
分析:
new是Java的關(guān)鍵字;
C. 數字不能開(kāi)頭;
D. 不能有“.”。
69.下列說(shuō)法錯誤的有()(多選)
A 數組是—種對象
B. 數組屬于一種原生類(lèi)
C. int number[]=(31,23,33,43,35,63)
D. 數組的大小可以任意改變
答案:BCD
分析:
B. Java中的原生類(lèi)(即基本數據類(lèi)型)有8種,但不包括數組;
C. 語(yǔ)法錯誤,應該“{···}”,而不是“(···)”;
D. 數組的長(cháng)度一旦確定就不能修改。
70.不能用來(lái)修飾interface的有()(多選)
A private
B. public
C. protected
D. static
答案:ACD
分析:
能夠修飾interface的只有public、abstract以及默認的三種修飾符。
71.下列正確的有()(多選)
A call by value不會(huì )改變實(shí)際參數的數值
B. call by reference能改變實(shí)際參數的參考地址
C. call by reference 不能改變實(shí)際參數的參考地址
D. call by reference 能改變實(shí)際參數的內容
答案:ACD
分析:
Java中參數的傳遞有兩種,一種是按值傳遞(call by value:傳遞的是具體的值,如基礎數據類(lèi)型),另一種是按引用傳遞(call by reference:傳遞的是對象的引用,即對象的存儲地址)。前者不能改變實(shí)參的數值,后者雖然不能改變實(shí)參的參考地址,但可以通過(guò)該地址訪(fǎng)問(wèn)地址中的內容從而實(shí)現內容的改變。
72.下列說(shuō)法錯誤的有()(多選)
A 在類(lèi)方法中可用this來(lái)調用本類(lèi)的類(lèi)辦法
B. 在類(lèi)方法中調用本類(lèi)的類(lèi)方法時(shí)可以直接調用
C. 在類(lèi)方法中只能調用本類(lèi)中的類(lèi)方法
D. 在類(lèi)方法中絕對不能調用實(shí)例方法
答案:ACD
分析:
類(lèi)方法是在類(lèi)加載時(shí)被加載到方法區存儲的,此時(shí)還沒(méi)有創(chuàng )建對象,所以不能使用this或者super關(guān)鍵字;
C. 在類(lèi)方法中還可以調用其他類(lèi)的類(lèi)方法;
D. 在類(lèi)方法可以通過(guò)創(chuàng )建對象來(lái)調用實(shí)例方法。
73.下列說(shuō)法錯誤的有()(多選)
A Java面向對象語(yǔ)言容許單獨的過(guò)棧與函數存在
B. Java面向對象語(yǔ)言容許單獨的方法存在
C. Java語(yǔ)言中的方法屬于類(lèi)中的成員(member)
D. Java語(yǔ)言中的方法必定隸屬于某一類(lèi)(對象),調用方法與過(guò)程或函數相同
答案:ABC
分析:
B. Java不允許單獨的方法,過(guò)程或函數存在,需要隸屬于某一類(lèi)中;
C. 靜態(tài)方法屬于類(lèi)的成員,非靜態(tài)方法屬于對象的成員。
74.下列說(shuō)法錯誤的有()(多選)
A 能被java.exe成功運行的java class文件必須有main()方法
B. J2SDK就是Java API
C. Appletviewer.exe可利用jar選項運行.jar文件
D. 能被Appletviewer成功運行的java class文件必須有main()方法
答案:BCD
分析:
B. J2SDK是sun公司編程工具,API是指的應用程序編程接口;
C. Appletviewer.exe就是用來(lái)解釋執行java applet應用程序的,一種執行HTML文件上的Java小程序類(lèi)的Java瀏覽器;
D. 能被Appletviewer成功運行的java class文件可以沒(méi)有main()方法。
75.請問(wèn)0.3332的數據類(lèi)型是()
A float
B. double
C. Float
D. Double
答案:B
分析:
小數默認是雙精度浮點(diǎn)型即double類(lèi)型的。
76.Java接口的修飾符可以為()
A private
B. protected
C. final
D. abstract
答案:D
分析:
能夠修飾interface的只有public、abstract以及默認的三種修飾符。
77.不通過(guò)構造函數也能創(chuàng )建對象么()
A
B.
答案:A
分析:
Java創(chuàng )建對象的幾種方式:
(1) 用new語(yǔ)句創(chuàng )建對象,這是最常見(jiàn)的創(chuàng )建對象的方法。
(2) 運用反射手段,調用java.lang.Class或者
java.lang.reflect.Constructor類(lèi)的newInstance()實(shí)例方法。
(3) 調用對象的clone()方法。
(4) 運用反序列化手段,調用java.io.ObjectInputStream對象的readObject()方法。
(1)和(2)都會(huì )明確的顯式的調用構造函數;(3)是在內存上對已有對象的影印,所以不會(huì )調用構造函數;(4)是從文件中還原類(lèi)的對象,也不會(huì )調用構造函數。
78.存在使i+1< i的數么?

78.存在使i+1< i的數么?

79.接口可否繼承接口?抽象類(lèi)是否可實(shí)現接口?抽象類(lèi)是否可繼承實(shí)體類(lèi)?

接口可以繼承接口,抽象類(lèi)可以實(shí)現接口,抽象類(lèi)可以繼承實(shí)體類(lèi)。

80.int與Integer有什么區別?

int是java提供的8種原始數據類(lèi)型之一。Java為每個(gè)原始類(lèi)型提供了封裝類(lèi),Integer是java為int提供的封裝類(lèi)。int的默認值為0,而Integer的默認值為null,即Integer可以區分出未賦值和值為0的區別,int則無(wú)法表達出未賦值的情況,例如,要想表達出沒(méi)有參加考試和考試成績(jì)?yōu)?的區別,則只能使用Integer。在JSP開(kāi)發(fā)中,Integer的默認為null,所以用el表達式在文本框中顯示時(shí),值為空白字符串,而int默認的默認值為0,所以用el表達式在文本框中顯示時(shí),結果為0,所以,int不適合作為web層的表單數據的類(lèi)型。

在Hibernate中,如果將OID定義為Integer類(lèi)型,那么Hibernate就可以根據其值是否為null而判斷一個(gè)對象是否是臨時(shí)的,如果將OID定義為了int類(lèi)型,還需要在hbm映射文件中設置其unsaved-value屬性為0。另外,Integer提供了多個(gè)與整數相關(guān)的操作方法,例如,將一個(gè)字符串轉換成整數,Integer中還定義了表示整數的最大值和最小值的常量。

81.可序列化對象為什么要定義serialversionUID值?

SerialVersionUid,簡(jiǎn)言之,其目的是序列化對象版本控制,有關(guān)各版本反序列化時(shí)是否兼容。如果在新版本中這個(gè)值修改了,新版本就不兼容舊版本,反序列化時(shí)會(huì )拋出InvalidClassException異常。如果修改較小,比如僅僅是增加了一個(gè)屬性,我們希望向下兼容,老版本的數據都能保留,那就不用修改;如果我們刪除了一個(gè)屬性,或者更改了類(lèi)的繼承關(guān)系,必然不兼容舊數據,這時(shí)就應該手動(dòng)更新版本號,即SerialVersionUid。

82.寫(xiě)一個(gè)Java正則,能過(guò)濾出html中的< a href=”url”>title< /a>形式中的鏈接地址和標題.

< a\b[^>]+\bhref="([^"]*)"[^>]*>([\s\S]*?)< /a>

< a\b[^>]+\bhref="([^"]*)"[^>]*>([\s\S]*?)< /a>

83.十進(jìn)制數72轉換成八進(jìn)制數是多少?

答: 110

84.Java程序中創(chuàng )建新的類(lèi)對象,使用關(guān)鍵字new,回收無(wú)用的類(lèi)對象使用關(guān)鍵字free正確么?

答:Java程序中創(chuàng )建新的類(lèi)對象,使用關(guān)鍵字new是正確的; 回收無(wú)用的類(lèi)對象使用關(guān)鍵字free是錯誤的.

85.Class類(lèi)的getDeclaredFields()方法與getFields()的區別?

答:getDeclaredFields(): 可以獲取所有本類(lèi)自己聲明的方法, 不能獲取繼承的方法

getFields(): 只能獲取所有public聲明的方法, 包括繼承的方法

86.在switch和if-else語(yǔ)句之間進(jìn)行選取,當控制選擇的條件不僅僅依賴(lài)于一個(gè)x時(shí),應該使用switch結構;正確么?

答:不正確。

通常情況下,進(jìn)行比較判斷的處理,switch 和if-else可以互相轉換來(lái)寫(xiě);if-else作用的范圍比switch-case作用范圍要大,但是當switch-case和if-else都可以用的情況下,通常推薦使用switch-case。

比如:

switch (ch) {
case 'a':
System.out.println("A");
break;
case 'b':
System.out.println("B");
break;
case 'c':
System.out.println("C");
break;
case 'd':
System.out.println("D");
break;
case 'e':
System.out.println("E");
break;
default:
System.out.println("other");
break;
}

換為if-else

if (ch == 'a') {
System.out.println("A");
} else if (ch == 'b') {
System.out.println('B');
} else if (ch == 'c') {
System.out.println("C");
} else if (ch == 'd') {
System.out.println("D");
} else if (ch == 'e') {
System.out.println("E");
} else {
System.out.println("Other");
}
87.描述&和&&的區別。

&和&&的聯(lián)系(共同點(diǎn)):

&和&&都可以用作邏輯與運算符,但是要看使用時(shí)的具體條件來(lái)決定。

操作數1&操作數2,操作數1&&操作數2,

操作數1&操作數2,操作數1&&操作數2,

情況1:當上述的操作數是boolean類(lèi)型變量時(shí),&和&&都可以用作邏輯與運算符。

情況2:當上述的表達式結果是boolean類(lèi)型變量時(shí),&和&&都可以用作邏輯與運算符。

表示邏輯與(and),當運算符兩邊的表達式的結果或操作數都為true時(shí),整個(gè)運算結果才為true,否則,只要有一方為false,結果都為false。

表示邏輯與(and),當運算符兩邊的表達式的結果或操作數都為true時(shí),整個(gè)運算結果才為true,否則,只要有一方為false,結果都為false。

(1)、&邏輯運算符稱(chēng)為邏輯與運算符,&&邏輯運算符稱(chēng)為短路與運算符,也可叫邏輯與運算符。

對于&:無(wú)論任何情況,&兩邊的操作數或表達式都會(huì )參與計算。

對于&&:當&&左邊的操作數為false或左邊表達式結果為false時(shí),&&右邊的操作數或表達式將不參與計算,此時(shí)最終結果都為false。

綜上所述,如果邏輯與運算的第一個(gè)操作數是false或第一個(gè)表達式的結果為false時(shí),對于第二個(gè)操作數或表達式是否進(jìn)行運算,對最終的結果沒(méi)有影響,結果肯定是false。推介平時(shí)多使用&&,因為它效率更高些。

(2)、&還可以用作位運算符。當&兩邊操作數或兩邊表達式的結果不是boolean類(lèi)型時(shí),&用于按位與運算符的操作。

88.使用final關(guān)鍵字修飾符一個(gè)變量時(shí),是引用不能變,還是引用的對象不能變?

final修飾基本類(lèi)型變量,其值不能改變。

但是final修飾引用類(lèi)型變量,棧內存中的引用不能改變,但是所指向的堆內存中的對象的屬性值仍舊可以改變。

例如:

class Test {
    public static void main(String[] args) {
        final Dog dog = new Dog("歐歐");
        dog.name = "美美";//正確
        dog = new Dog("亞亞");//錯誤
    }
}
89.請解釋以下常用正則含義:\d,\D,\s,.,*,?,|,[0-9]{6},\d+

\d: 匹配一個(gè)數字字符。等價(jià)于[0-9]

\D: 匹配一個(gè)非數字字符。等價(jià)于[^0-9]

\s: 匹配任何空白字符,包括空格、制表符、換頁(yè)符等等。等價(jià)于 [ \f\n\r\t\v]

. :匹配除換行符 \n 之外的任何單字符。要匹配 . ,請使用 \. 。

*:匹配前面的子表達式零次或多次。要匹配 * 字符,請使用 \*。

+:匹配前面的子表達式一次或多次。要匹配 + 字符,請使用 \+。

|:將兩個(gè)匹配條件進(jìn)行邏輯“或”(Or)運算

[0-9]{6}:匹配連續6個(gè)0-9之間的數字

\d+:匹配至少一個(gè)0-9之間的數字

90.已知表達式int m[] = {0,1,2,3,4,5,6}; 下面那個(gè)表達式的值與數組的長(cháng)度相等()
A m.length()
B. m.length
C. m.length()+1
D. m.length+1
答案:B
分析:數組的長(cháng)度是.length
91.下面那些聲明是合法的?()
A long l = 4990
B. int i = 4L
C. float f = 1.1
D. double d = 34.4
答案:AD
分析:B int屬于整數型應該是int=4 C應該是float f=1.1f
92.以下選項中選擇正確的java表達式()
A int k=new String(“aa”)
B. String str = String(“bb”)
C. char c=74;
D. long j=8888;
答案:CD
分析:A需要強制類(lèi)型轉換 B String str =new String(“bb”)
93.下列代碼的輸出結果是
System.out.println(""+("12"=="12"&&"12".equals("12")));
(“12”==”12”&&”12”.equals(“12”))
“12”==”12”&&”12”.equals(“12”)

true

false

94.以下哪些運算符是含有短路運算機制的?請選擇:()
A &
B. &&
C. |
D. ||
答案:BD
分析:A C是邏輯與計算
95.下面哪個(gè)函數是public void example(){....}的重載函數?()
A private void example(int m){...}
B. public int example(){...}
C. public void example2(){...}
D. public int example(int m.float f){...}
答案:AD
分析:BC定義的是新函數
96.給定某java程序片段,該程序運行后,j的輸出結果為()
int  i=1;
 Int  j=i++;
 If((j>++j)&&(i++==j)){j+=i:}
 System.out.println(j);
A 1
B. 2
C. 3
D. 4
答案:B
分析: i++先引用后。++i 先增加后引用
97.在java中,無(wú)論測試條件是什么,下列()循環(huán)將至少執行一次。
A for
B. do...while
C. while
D. while...do
答案:B
分析: ACD都不一定進(jìn)行循環(huán)
98.打印結果:
package com.bjsxt;

public class smaillT{
public static void main(String args[]){
smaillT t=new smaillT();
int b = t.get();
System.out.println(b);
}

public int get()
{
try {
return 1;
}finally{
return 2;
}
}
}

輸出結果:2

99.指出下列程序的運行結果
int i=9;
switch (i) {
default:
System.out.println("default");
case 0:
System.out.println("zero");
break;
case 1:
System.out.println("one");
break;
case 2:
System.out.println("two");
break;
}

打印結果:

打印結果:

zero

100.解釋繼承、重載、覆蓋。

繼承(英語(yǔ):inheritance)是面向對象軟件技術(shù)當中的一個(gè)概念。如果一個(gè)類(lèi)別A“繼承自”另一個(gè)類(lèi)別B,就把這個(gè)A稱(chēng)為“B的子類(lèi)別”,而把B稱(chēng)為“A的父類(lèi)別”也可以稱(chēng)“B是A的超類(lèi)”。繼承可以使得子類(lèi)別具有父類(lèi)別的各種屬性和方法,而不需要再次編寫(xiě)相同的代碼。在令子類(lèi)別繼承父類(lèi)別的同時(shí),可以重新定義某些屬性,并重寫(xiě)某些方法,即覆蓋父類(lèi)別的原有屬性和方法,使其獲得與父類(lèi)別不同的功能。另外,為子類(lèi)別追加新的屬性和方法也是常見(jiàn)的做法。 一般靜態(tài)的面向對象編程語(yǔ)言,繼承屬于靜態(tài)的,意即在子類(lèi)別的行為在編譯期就已經(jīng)決定,無(wú)法在執行期擴充。

那么如何使用繼承呢?用extends關(guān)鍵字來(lái)繼承父類(lèi)。

如上面A類(lèi)與B類(lèi),當寫(xiě)繼承語(yǔ)句時(shí), class A類(lèi) extends B類(lèi){ } 其中A類(lèi)是子類(lèi),B類(lèi)是父類(lèi)。

英文 位置不同 作用不同
重載 overload 同一個(gè)類(lèi)中
在一個(gè)類(lèi)里面為一種行為提供多種實(shí)現方式并提高可讀性
現方式并提高可讀性
重寫(xiě) override 子類(lèi)和父類(lèi)間
父類(lèi)方法無(wú)法滿(mǎn)足子類(lèi)的要求,子類(lèi)通
過(guò)方法重寫(xiě)滿(mǎn)足要求
101.什么是編譯型語(yǔ)言,什么是解釋型語(yǔ)言?java可以歸類(lèi)到那種?

計算機不能直接理解高級語(yǔ)言,只能理解和運行機器語(yǔ)言,所以必須要把高級語(yǔ)言翻譯成機器語(yǔ)言,計算機才能運行高級語(yǔ)言所編寫(xiě)的程序。翻譯的方式有兩種,一個(gè)是編譯,一個(gè)是解釋。

用編譯型語(yǔ)言寫(xiě)的程序執行之前,需要一個(gè)專(zhuān)門(mén)的編譯過(guò)程,通過(guò)編譯系統把高級語(yǔ)言翻譯成機器語(yǔ)言,把源高級程序編譯成為機器語(yǔ)言文件,比如windows下的exe文件。以后就可以直接運行而不需要編譯了,因為翻譯只做了一次,運行時(shí)不需要翻譯,所以一般而言,編譯型語(yǔ)言的程序執行效率高。

解釋型語(yǔ)言在運行的時(shí)候才翻譯,比如VB語(yǔ)言,在執行的時(shí)候,專(zhuān)門(mén)有一個(gè)解釋器能夠將VB語(yǔ)言翻譯成機器語(yǔ)言,每個(gè)語(yǔ)句都是執行時(shí)才翻譯。這樣解釋型語(yǔ)言每執行一次就要翻譯一次,效率比較低。

編譯型與解釋型,兩者各有利弊。前者由于程序執行速度快,同等條件下對系統要求較低,因此像開(kāi)發(fā)操作系統、大型應用程序、數據庫系統等時(shí)都采用它,像C/C++、Pascal/Object Pascal(Delphi)等都是編譯語(yǔ)言,而一些網(wǎng)頁(yè)腳本、服務(wù)器腳本及輔助開(kāi)發(fā)接口這樣的對速度要求不高、對不同系統平臺間的兼容性有一定要求的程序則通常使用解釋性語(yǔ)言,如JavaScript、VBScript、Perl、Python、Ruby、MATLAB 等等。

JAVA語(yǔ)言是一種編譯型-解釋型語(yǔ)言,同時(shí)具備編譯特性和解釋特性(其實(shí),確切的說(shuō)java就是解釋型語(yǔ)言,其所謂的編譯過(guò)程只是將.java文件編程成平臺無(wú)關(guān)的字節碼.class文件,并不是向C一樣編譯成可執行的機器語(yǔ)言,在此請讀者注意Java中所謂的“編譯”和傳統的“編譯”的區別)。作為編譯型語(yǔ)言,JAVA程序要被統一編譯成字節碼文件——文件后綴是class。此種文件在java中又稱(chēng)為類(lèi)文件。java類(lèi)文件不能再計算機上直接執行,它需要被java虛擬機翻譯成本地的機器碼后才能執行,而java虛擬機的翻譯過(guò)程則是解釋性的。java字節碼文件首先被加載到計算機內存中,然后讀出一條指令,翻譯一條指令,執行一條指令,該過(guò)程被稱(chēng)為java語(yǔ)言的解釋執行,是由java虛擬機完成的。

102.簡(jiǎn)述操作符(&,|)與操作符(&&,||)的區別&和&&的聯(lián)系(共同點(diǎn))

&和&&都可以用作邏輯與運算符,但是要看使用時(shí)的具體條件來(lái)決定。

操作數1&操作數2 操作數1&&操作數2
表達式1&表達式2 表達式1&&表達式2

情況1:當上述的操作數是boolean類(lèi)型變量時(shí),&和&&都可以用作邏輯與運算符。

情況2:當上述的表達式結果是boolean類(lèi)型變量時(shí),&和&&都可以用作邏輯與運算符。

表示邏輯與(and),當運算符兩邊的表達式的結果或操作數都為true時(shí),整個(gè)運算結果才為true,否則,只要有一方為false,結果都為false。

&和&&的區別(不同點(diǎn)):

(1)、&邏輯運算符稱(chēng)為邏輯與運算符,&&邏輯運算符稱(chēng)為短路與運算符,也可叫邏輯與運算符。

對于&:無(wú)論任何情況,&兩邊的操作數或表達式都會(huì )參與計算。

對于&&:當&&左邊的操作數為false或左邊表達式結果為false時(shí),&&右邊的操作數或表達式將不參與計算,此時(shí)最終結果都為false。

綜上所述,如果邏輯與運算的第一個(gè)操作數是false或第一個(gè)表達式的結果為false時(shí),對于第二個(gè)操作數或表達式是否進(jìn)行運算,對最終的結果沒(méi)有影響,結果肯定是false。推介平時(shí)多使用&&,因為它效率更高些。

(2)、&還可以用作位運算符。當&兩邊操作數或兩邊表達式的結果不是boolean類(lèi)型時(shí),&用于按位與運算符的操作。

|和||的區別和聯(lián)系與&和&&的區別和聯(lián)系類(lèi)似

103.try{}里面有一個(gè)return語(yǔ)句,那么緊跟在這個(gè)try后的finally, 里面的語(yǔ)句在異常出現后,都會(huì )執行么?為什么?

在異常處理時(shí)提供 finally 塊來(lái)執行任何清除操作。

如果有finally的話(huà),則不管是否發(fā)生異常,finally語(yǔ)句都會(huì )被執行,包括遇到return語(yǔ)句。

finally中語(yǔ)句不執行的唯一情況中執行了System.exit(0)語(yǔ)句。

104.有一段java應用程序,它的主類(lèi)名是al,那么保存它的源文件可以是?()
A al.java
B. al.class
C. al
D. 都對
答案:A
分析:.class是java的解析文件
105.Java類(lèi)可以作為()
A 類(lèi)型定義機制
B. 數據封裝機制
C. 類(lèi)型定義機制和數據封裝機制
D. 上述都不對
答案:C
106.在調用方法時(shí),若要使方法改變實(shí)參的值,可以?()
A 用基本數據類(lèi)型作為參數
B. 用對象作為參數
C. A和B都對
D. A和B都不對
答案:B
分析:基本數據類(lèi)型不能改變實(shí)參的值
107.Java語(yǔ)言具有許多優(yōu)點(diǎn)和特點(diǎn),哪個(gè)反映了java程序并行機制的()
A 安全性
B. 多線(xiàn)性
C. 跨平臺
D. 可移植
可移植
108.下關(guān)于構造函數的描述錯誤是()
A 構造函數的返回類(lèi)型只能是void型
B. 構造函數是類(lèi)的一種特殊函數,它的方法名必須與類(lèi)名相同
C. 構造函數的主要作用是完成對類(lèi)的對象的初始化工作
D. 一般在創(chuàng )建新對象時(shí),系統會(huì )自動(dòng)調用構造函數
答案:A
分析:構造函數的名字與類(lèi)的名字相同,并且不能指定返回類(lèi)型。
109.若需要定義一個(gè)類(lèi)域或類(lèi)方法,應使用哪種修飾符?()
A static
B. package
C. private
D. public
答案:A
110.下面代碼執行后的輸出是什么()
package com.bjsxt;
public class Test {
public static void main(String[] args) {
outer: for (int i = 0; i < 3; i++)
inner: for (int j = 0; j < 2; j++) {
if (j == 1)
continue outer;
System.out.println(j + " and " + i);
}
}
}
A
0 and 0
0 and 1
0 and 2
B.
1 and 0
1 and 1
1 and 2
C.
2 and 0
2 and 1
2 and 2
答案:A
111.給出如下代碼,如何使成員變量m被函數fun()直接訪(fǎng)問(wèn)()
package com.bjsxt;
public class Test {
private int m;

public static void fun() {
// some code…
}
}
A 將private int m 改為 protected int m
B. 將private int m 改為 public int m
C. 將private int m 改為 static int m
D. 將private int m 改為int m
答案:C
112.下面哪幾個(gè)函數是public void example(){….}的重載函數()

A public void example(int m){…}
B. public int example(int m){…}
C. public void example2(){…}
D. public int example(int m,float f){…}
答案:ABD
113.請問(wèn)以下代碼執行會(huì )打印出什么?

父類(lèi):

package com.bjsxt;

public class FatherClass {
public FatherClass() {
System.out.println("FatherClassCreate");
}
}

子類(lèi):

package com.bjsxt;

import com.bjsxt.FatherClass;
public class ChildClass extends FatherClass {
public ChildClass() {
System.out.println("ChildClass Create");
}
public static void main(String[] args) {
FatherClass fc = new FatherClass();
ChildClass cc = new ChildClass();
}
}

執行:C:\>java com.bjsxt.ChildClass

輸出結果:?

答:

FatherClassCreate

FatherClassCreate

ChildClass Create

114.如果有兩個(gè)類(lèi)A、B(注意不是接口),你想同時(shí)使用這兩個(gè)類(lèi)的功能,那么你會(huì )如何編寫(xiě)這個(gè)C類(lèi)呢?

答:因為類(lèi)A、B不是接口,所以是不可以直接實(shí)現的,但可以將A、B類(lèi)定義成父子類(lèi),那么C類(lèi)就能實(shí)現A、B類(lèi)的功能了。假如A為B的父類(lèi),B為C的父類(lèi),此時(shí)C就能使用A、B的功能。

115.一個(gè)類(lèi)的構造方法是否可以被重載(overloading),是否可以被子類(lèi)重寫(xiě)(overrding)?

答:構造方法可以被重載,但是構造方法不能被重寫(xiě),子類(lèi)也不能繼承到父類(lèi)的構造方法

116.Java中byte表示的數值范圍是什么?

答:范圍是-128至127

117.如何將日期類(lèi)型格式化為:2013-02-18 10:53:10?
public class TestDateFormat2 {
public static void main(String[] args) throws Exception {
//第一步:將字符串(2013-02-18 10:53:10)轉換成日期Date
DateFormat  sdf=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
String sdate="2013-02-18 10:53:10";
Date date=sdf.parse(sdate);
System.out.println(date);

//第二步:將日期Date轉換成字符串String
DateFormat  sdf2=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
String sdate2=sdf2.format(date);
System.out.println(sdate2);
}
}
118.不通過(guò)構造函數也能創(chuàng )建對象嗎()
A.
B.
分析:答案:A
Java創(chuàng )建對象的幾種方式(重要):
(1) 用new語(yǔ)句創(chuàng )建對象,這是最常見(jiàn)的創(chuàng )建對象的方法。
(2) 運用反射手段,調用java.lang.Class或者
java.lang.reflect.Constructor類(lèi)的newInstance()實(shí)例方法。
(3) 調用對象的clone()方法
(4) 運用反序列化手段,調用java.io.ObjectInputStream對象的 readObject()方法。
(1)和(2)都會(huì )明確的顯式的調用構造函數 ;(3)是在內存上對已有對象的影印,所以不會(huì )調用構造函數 ;(4)是從文件中還原類(lèi)的對象,也不會(huì )調用構造函數。
(1)和(2)都會(huì )明確的顯式的調用構造函數 ;(3)是在內存上對已有對象的影印,所以不會(huì )調用構造函數 ;(4)是從文件中還原類(lèi)的對象,也不會(huì )調用構造函數。
119.下面哪些是對稱(chēng)加密算法()

A. DES
B. MD5
C. DSA
D. RSA
分析:答案:A
分析:常用的對稱(chēng)加密算法有:DES、3DES、RC2、RC4、AES
常用的非對稱(chēng)加密算法有:RSA、DSA、ECC
使用單向散列函數的加密算法:MD5、SHA
120.下面的代碼段,當輸入為2的時(shí)候返回值是()
publicstaticint get Value(int i){
int result=0;
switch(i){
case 1:
result=result +i
case 2:
result=result+i*2
case 3:
result=result+i*3
}
return result;
}
A. 0
B. 2
C. 4
D. 10
答案:C
分析:result = 0 + 2 * 2;
121.以下Java代碼段會(huì )產(chǎn)生幾個(gè)對象
publicvoid test(){
String a="a";
String b="b";
String c="c";
c=a+""+b+""+c;
System.out.print(c);
}

分析:答案: 一個(gè)對象,因為編譯期進(jìn)行了優(yōu)化,3個(gè)字符串常量直接折疊為一個(gè)

122.Math.round(-11.2)的運行結果是。

答案: -11

分析:小數點(diǎn)后第一位=5

正數:Math.round(11.5)=12

負數:Math.round(-11.5)=-11

小數點(diǎn)后第一位<5

正數:Math.round(11.46)=11

負數:Math.round(-11.46)=-11

小數點(diǎn)后第一位>5

正數:Math.round(11.68)=12

負數:Math.round(-11.68)=-12

根據上面例子的運行結果,我們還可以按照如下方式總結,或許更加容易記憶:

參數的小數點(diǎn)后第一位<5,運算結果為參數整數部分。

參數的小數點(diǎn)后第一位>5,運算結果為參數整數部分絕對值+1,符號(即正負)不變。

參數的小數點(diǎn)后第一位=5,正數運算結果為整數部分+1,負數運算結果為整數部分。

終結:大于五全部加,等于五正數加,小于五全不加。

123.十進(jìn)制數278的對應十六進(jìn)制數

分析:十進(jìn)制數278的對應十六進(jìn)制數是116

124.Java中int.long占用的字節數分別是

分析:

1:“字節”是byte,“位”是bit ;

2: 1 byte = 8 bit ;

char 在Java中是2個(gè)字節。java采用unicode,2個(gè)字節(16位)來(lái)表示一個(gè)字符。

short 2個(gè)字節

int 4個(gè)字節

long 8個(gè)字節

125.System.out.println(‘a(chǎn)’+1);的結果是

分析:'a'是char型,1 是int行,int與char相加,char會(huì )被強轉為int行,char的ASCII碼對應的值是97,所以加一起打印98

126.下列語(yǔ)句那一個(gè)正確()
A. java程序經(jīng)編譯后會(huì )產(chǎn)生machine code
B. java程序經(jīng)編譯后會(huì )產(chǎn)生 byte code
C. java程序經(jīng)編譯后會(huì )產(chǎn)生DLL
D. 以上都不正確
答案:B
分析:java程序編譯后會(huì )生成字節碼文件,就是.class文件
127.下列說(shuō)法正確的有()
A. class中的constructor不可省略
B. constructor必須與class同名,但方法不能與class同名
C. constructor在一個(gè)對象被new時(shí)執行
D. 一個(gè)class只能定義一個(gè)constructor
答案:C
128.執行如下程序代碼()
a=0;c=0;
do{
——c;
a=a-1;
}while(a>0);
后,c的值是()
A. 0
B. 1
C. -1
D. 死循環(huán)
答案:C
do{...}while(...);語(yǔ)句至少執行一次
129.下列哪一種敘述是正確的()
A. abstract修飾符可修飾字段、方法和類(lèi)
B. 抽象方法的body部分必須用一對大括號{}包住
C. 聲明抽象方法,大括號可有可無(wú)
D. 聲明抽象方法不可寫(xiě)出大括號
答案:D
分析: abstract不能修飾字段。既然是抽象方法,當然是沒(méi)有實(shí)現的方法,根本就沒(méi)有body部分。
130.下列語(yǔ)句正確的是()
A. 形式參數可被視為local variable
B. 形式參數可被字段修飾符修飾
C. 形式參數為方法被調用時(shí),真正被傳遞的參數
D. 形式參數不可以是對象
答案A:
分析:
A:形式參數可被視為local variable。形參和局部變量一樣都不能離開(kāi)方法。都只有在方法內才會(huì )發(fā)生作用,也只有在方法中使用,不會(huì )在方法外可見(jiàn)。
B:對于形式參數只能用final修飾符,其它任何修飾符都會(huì )引起編譯器錯誤。但是用這個(gè)修飾符也有一定的限制,就是在方法中不能對參數做任何修改。 不過(guò)一般情況下,一個(gè)方法的形參不用final修飾。只有在特殊情況下,那就是:方法內部類(lèi)。? 一個(gè)方法內的內部類(lèi)如果使用了這個(gè)方法的參數或者局部變量的話(huà),這個(gè)參數或局部變量應該是final。?
C:形參的值在調用時(shí)根據調用者更改,實(shí)參則用自身的值更改形參的值(指針、引用皆在此列),也就是說(shuō)真正被傳遞的是實(shí)參。
D:方法的參數列表指定要傳遞給方法什么樣的信息,采用的都是對象的形式。因此,在參數列表中必須指定每個(gè)所傳遞對象的類(lèi)型及名字。想JAVA中任何傳遞對象的場(chǎng)合一樣,這里傳遞的實(shí)際上也是引用,并且引用的類(lèi)型必須正確。--《Thinking in JAVA》
131.成員變量用static修飾和不用static修飾有什么區別?

1、兩個(gè)變量的生命周期不同。

成員變量隨著(zhù)對象的創(chuàng )建而存在,隨著(zhù)對象的被回收而釋放。

靜態(tài)變量隨著(zhù)類(lèi)的加載而存在,隨著(zhù)類(lèi)的消失而消失。

2、調用方式不同。

成員變量只能被對象調用。

成員變量只能被對象調用。

成員變量只能被對象調用。

類(lèi)名調用 :Person.country

3、別名不同。

成員變量也稱(chēng)為實(shí)例變量。

靜態(tài)變量稱(chēng)為類(lèi)變量。?

4、數據存儲位置不同。

成員變量數據存儲在堆內存的對象中,所以也叫對象的特有數據.

靜態(tài)變量數據存儲在方法區(共享數據區)的靜態(tài)區,所以也叫對象的共享數據.

132.如果變量用final修飾,則怎樣?如果方法final修飾,則怎樣?

1、用final修飾的類(lèi)不能被擴展,也就是說(shuō)不可能有子類(lèi);

2、用final修飾的方法不能被替換或隱藏:

① 使用final修飾的實(shí)例方法在其所屬類(lèi)的子類(lèi)中不能被替換(overridden);

② 使用final修飾的靜態(tài)方法在其所屬類(lèi)的子類(lèi)中不能被重定義(redefined)而隱藏(hidden);

3、用final修飾的變量最多只能賦值一次,在賦值方式上不同類(lèi)型的變量或稍有不同:

① 靜態(tài)變量必須明確賦值一次(不能只使用類(lèi)型缺省值);作為類(lèi)成員的靜態(tài)變量,賦值可以在其聲明中通過(guò)初始化表達式完成,也可以在靜態(tài)初始化塊中進(jìn)行;作為接口成員的靜態(tài)變量,賦值只能在其聲明中通過(guò)初始化表達式完成;

② 實(shí)例變量同樣必須明確賦值一次(不能只使用類(lèi)型缺省值);賦值可以在其聲明中通過(guò)初始化表達式完成,也可以在實(shí)例初始化塊或構造器中進(jìn)行;

③ 方法參數變量在方法被調用時(shí)創(chuàng )建,同時(shí)被初始化為對應實(shí)參值,終止于方法體 (body)結束,在此期間其值不能改變;

④ 構造器參數變量在構造器被調用(通過(guò)實(shí)例創(chuàng )建表達式或顯示的構造器調用)時(shí)創(chuàng )建,同時(shí)被初始化,為對應實(shí)參值,終止于構造器體結束,在此期間其值不能改變;

⑤ 異常處理器參數變量在有異常被try語(yǔ)句的catch子句捕捉到時(shí)創(chuàng )建,同時(shí)被初始化為實(shí)際的異常對象,終止于catch語(yǔ)句塊結束,在此期間其值不能改變;

⑥ 局部變量在其值被訪(fǎng)問(wèn)之前必須被明確賦值;

133.在二進(jìn)制數據中,小數點(diǎn)向右移一位,則數據()
A. 除以10
B. 除以2
C. 乘以2
D. 乘以10
乘以10
分析:可以看個(gè)例子
101.1 對應的十進(jìn)制為 2^2*1 + 2^1*0 + 2^0*1 + 2^-1*1 = 5.5小數點(diǎn)右移一位
1011 對應的十進(jìn)制為 2^3*1 + 2^2*0 + 2^1*1 + 2^0*1 = 11所以是擴大到原來(lái)的2倍
134.面向對象的特征有哪些方面?

答:面向對象的特征主要有以下幾個(gè)方面:

1、抽象:抽象是將一類(lèi)對象的共同特征總結出來(lái)構造類(lèi)的過(guò)程,包括數據抽象和行為抽象兩方面。抽象只關(guān)注對象有哪些屬性和行為,并不關(guān)注這些行為的細節是什么。

2、繼承:繼承是從已有類(lèi)得到繼承信息創(chuàng )建新類(lèi)的過(guò)程。提供繼承信息的類(lèi)被稱(chēng)為父類(lèi)(超類(lèi)、基類(lèi));得到繼承信息的類(lèi)被稱(chēng)為子類(lèi)(派生類(lèi))。繼承讓變化中的軟件系統有了一定的延續性,同時(shí)繼承也是封裝程序中可變因素的重要手段(如果不能理解請閱讀閻宏博士的《Java與模式》或《設計模式精解》中關(guān)于橋梁模式的部分)。

3、封裝:通常認為封裝是把數據和操作數據的方法綁定起來(lái),對數據的訪(fǎng)問(wèn)只能通過(guò)已定義的接口。面向對象的本質(zhì)就是將現實(shí)世界描繪成一系列完全自治、封閉的對象。我們在類(lèi)中編寫(xiě)的方法就是對實(shí)現細節的一種封裝;我們編寫(xiě)一個(gè)類(lèi)就是對數據和數據操作的封裝??梢哉f(shuō),封裝就是隱藏一切可隱藏的東西,只向外界提供最簡(jiǎn)單的編程接口(可以想想普通洗衣機和全自動(dòng)洗衣機的差別,明顯全自動(dòng)洗衣機封裝更好因此操作起來(lái)更簡(jiǎn)單;我們現在使用的智能手機也是封裝得足夠好的,因為幾個(gè)按鍵就搞定了所有的事情)。

4、多態(tài)性:多態(tài)性是指允許不同子類(lèi)型的對象對同一消息作出不同的響應。簡(jiǎn)單的說(shuō)就是用同樣的對象引用調用同樣的方法但是做了不同的事情。多態(tài)性分為編譯時(shí)的多態(tài)性和運行時(shí)的多態(tài)性。如果將對象的方法視為對象向外界提供的服務(wù),那么運行時(shí)的多態(tài)性可以解釋為:當A系統訪(fǎng)問(wèn)B系統提供的服務(wù)時(shí),B系統有多種提供服務(wù)的方式,但一切對A系統來(lái)說(shuō)都是透明的(就像電動(dòng)剃須刀是A系統,它的供電系統是B系統,B系統可以使用電池供電或者用交流電,甚至還有可能是太陽(yáng)能,A系統只會(huì )通過(guò)B類(lèi)對象調用供電的方法,但并不知道供電系統的底層實(shí)現是什么,究竟通過(guò)何種方式獲得了動(dòng)力)。方法重載(overload)實(shí)現的是編譯時(shí)的多態(tài)性(也稱(chēng)為前綁定),而方法重寫(xiě)(override)實(shí)現的是運行時(shí)的多態(tài)性(也稱(chēng)為后綁定)。運行時(shí)的多態(tài)是面向對象最精髓的東西,要實(shí)現多態(tài)需要做兩件事:1. 方法重寫(xiě)(子類(lèi)繼承父類(lèi)并重寫(xiě)父類(lèi)中已有的或抽象的方法);2. 對象造型(用父類(lèi)型引用引用子類(lèi)型對象,這樣同樣的引用調用同樣的方法就會(huì )根據子類(lèi)對象的不同而表現出不同的行為)。

135.float f=3.4;是否正確?

答:不正確。3.4是雙精度數,將雙精度型(double)賦值給浮點(diǎn)型(float)屬于下轉型(down-casting,也稱(chēng)為窄化)會(huì )造成精度損失,因此需要強制類(lèi)型轉換float f =(float)3.4; 或者寫(xiě)成float f =3.4F;。

136.short s1 = 1; s1 = s1 + 1;有錯嗎?short s1 = 1; s1 += 1;有錯嗎?

答:對于short s1 = 1; s1 = s1 + 1;由于1是int類(lèi)型,因此s1+1運算結果也是int 型,需要強制轉換類(lèi)型才能賦值給short型。而short s1 = 1; s1 += 1;可以正確編譯,因為s1+= 1;相當于s1 = (short)(s1 + 1);其中有隱含的強制類(lèi)型轉換。

137.Java 有沒(méi)有g(shù)oto?

答: goto 是Java中的保留字,在目前版本的Java中沒(méi)有使用。(根據James Gosling(Java之父)編寫(xiě)的《The Java Programming Language》一書(shū)的附錄中給出了一個(gè)Java關(guān)鍵字列表,其中有g(shù)oto和const,但是這兩個(gè)是目前無(wú)法使用的關(guān)鍵字,因此有些地方將其稱(chēng)之為保留字,其實(shí)保留字這個(gè)詞應該有更廣泛的意義,因為熟悉C語(yǔ)言的程序員都知道,在系統類(lèi)庫中使用過(guò)的有特殊意義的單詞或單詞的組合都被視為保留字)

138.int 和Integer 有什么區別?

答:Java是一個(gè)近乎純潔的面向對象編程語(yǔ)言,但是為了編程的方便還是引入不是對象的基本數據類(lèi)型,但是為了能夠將這些基本數據類(lèi)型當成對象操作,Java為每一個(gè)基本數據類(lèi)型都引入了對應的包裝類(lèi)型(wrapper class),int的包裝類(lèi)就是Integer,從JDK 1.5開(kāi)始引入了自動(dòng)裝箱/拆箱機制,使得二者可以相互轉換。

Java 為每個(gè)原始類(lèi)型提供了包裝類(lèi)型:

原始類(lèi)型: boolean,char,byte,short,int,long,float,double

包裝類(lèi)型:Boolean,Character,Byte,Short,Integer,Long,Float,Double

package com.bjsxt;

public class AutoUnboxingTest {

    public static void main(String[] args) {
        Integer a = new Integer(3);
        Integer b = 3;              // 將3自動(dòng)裝箱成Integer類(lèi)型
        int c = 3;
        System.out.println(a == b); // false 兩個(gè)引用沒(méi)有引用同一對象
        System.out.println(a == c); // true a自動(dòng)拆箱成int類(lèi)型再和c比較
    }
}

補充:最近還遇到一個(gè)面試題,也是和自動(dòng)裝箱和拆箱相關(guān)的,代碼如下所示:

public class Test03 {

   public static void main(String[] args) {
       Integer f1 = 100, f2 = 100, f3 = 150, f4 = 150;
        System.out.println(f1 == f2);
        System.out.println(f3 == f4);
    }
}

如果不明就里很容易認為兩個(gè)輸出要么都是true要么都是false。首先需要注意的是f1、f2、f3、f4四個(gè)變量都是Integer對象,所以下面的==運算比較的不是值而是引用。裝箱的本質(zhì)是什么呢?當我們給一個(gè)Integer對象賦一個(gè)int值的時(shí)候,會(huì )調用Integer類(lèi)的靜態(tài)方法valueOf,如果看看valueOf的源代碼就知道發(fā)生了什么。

public static Integer valueOf(int i) {
       if (i >= IntegerCache.low && i <= IntegerCache.high)
          return IntegerCache.cache[i + (-IntegerCache.low)];
       return new Integer(i);
   }

IntegerCache是Integer的內部類(lèi),其代碼如下所示:

/* Cache to support the object identity semantics of autoboxing for values between
     * -128 and 127 (inclusive) as required by JLS.
     *
     * The cache is initialized on first usage.  The size of the cache
     * may be controlled by the {@code -XX:AutoBoxCacheMax=<size>} option.
     * During VM initialization, java.lang.Integer.IntegerCache.high property
     * may be set and saved in the private system properties in the
     * sun.misc.VM class.
     */

    private static class IntegerCache {
        static final int low = -128;
        static final int high;
        static final Integer cache[];

        static {
            // high value may be configured by property
            int h = 127;
            String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null) {
                try {
                    int i = parseInt(integerCacheHighPropValue);
                    i = Math.max(i, 127);
                    // Maximum array size is Integer.MAX_VALUE
                    h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                } catch( NumberFormatException nfe) {
                    // If the property cannot be parsed into an int, ignore it.
                }
            }
            high = h;

            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);

            // range [-128, 127] must be interned (JLS7 5.1.7)
            assert IntegerCache.high >= 127;
        }

        private IntegerCache() {}
}

簡(jiǎn)單的說(shuō),如果字面量的值在-128到127之間,那么不會(huì )new新的Integer對象,而是直接引用常量池中的Integer對象,所以上面的面試題中f1==f2的結果是true,而f3==f4的結果是false。越是貌似簡(jiǎn)單的面試題其中的玄機就越多,需要面試者有相當深厚的功力。

139.&和&&的區別?

答:&運算符有兩種用法:(1)按位與;(2)邏輯與。&&運算符是短路與運算。邏輯與跟短路與的差別是非常巨大的,雖然二者都要求運算符左右兩端的布爾值都是true整個(gè)表達式的值才是true。&&之所以稱(chēng)為短路運算是因為,如果&&左邊的表達式的值是false,右邊的表達式會(huì )被直接短路掉,不會(huì )進(jìn)行運算。很多時(shí)候我們可能都需要用&&而不是&,例如在驗證用戶(hù)登錄時(shí)判定用戶(hù)名不是null而且不是空字符串,應當寫(xiě)為:username != null &&!username.equals(“”),二者的順序不能交換,更不能用&運算符,因為第一個(gè)條件如果不成立,根本不能進(jìn)行字符串的equals比較,否則會(huì )產(chǎn)生NullPointerException異常。注意:邏輯或運算符(|)和短路或運算符(||)的差別也是如此。

補充:如果你熟悉JavaScript,那你可能更能感受到短路運算的強大,想成為 JavaScript的高手就先從玩轉短路運算開(kāi)始吧。

140.Math.round(11.5) 等于多少? Math.round(-11.5)等于多少?

答:Math.round(11.5)的返回值是12,Math.round(-11.5)的返回值是-11。四舍五入的原理是在參數上加0.5然后進(jìn)行下取整。

141.swtich 是否能作用在byte 上,是否能作用在long 上,是否能作用在String上?

答:早期的JDK中,switch(expr)中,expr可以是byte、short、char、int。從1.5版開(kāi)始,Java中引入了枚舉類(lèi)型(enum),expr也可以是枚舉,從JDK 1.7版開(kāi)始,還可以是字符串(String)。長(cháng)整型(long)是不可以的。

142.用最有效率的方法計算2乘以8?

答: 2 << 3(左移3位相當于乘以2的3次方,右移3位相當于除以2的3次方)。

補充: 我們?yōu)榫帉?xiě)的類(lèi)重寫(xiě)hashCode方法時(shí),可能會(huì )看到如下所示的代碼,其實(shí)我們不太理解為什么要使用這樣的乘法運算來(lái)產(chǎn)生哈希碼(散列碼),而且為什么這個(gè)數是個(gè)素數,為什么通常選擇31這個(gè)數?前兩個(gè)問(wèn)題的答案你可以自己百度一下,選擇31是因為可以用移位和減法運算來(lái)代替乘法,從而得到更好的性能。說(shuō)到這里你可能已經(jīng)想到了:31 * num <==> (num << 5) - num,左移5位相當于乘以2的5次方(32)再減去自身就相當于乘以31?,F在的VM都能自動(dòng)完成這個(gè)優(yōu)化。

package com.bjsxt;

public class PhoneNumber {
    private int areaCode;
    private String prefix;
    private String lineNumber;

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + areaCode;
        result = prime * result
                + ((lineNumber == null) ? 0 : lineNumber.hashCode());
        result = prime * result + ((prefix == null) ? 0 : prefix.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        PhoneNumber other = (PhoneNumber) obj;
        if (areaCode != other.areaCode)
            return false;
        if (lineNumber == null) {
            if (other.lineNumber != null)
                return false;
        } else if (!lineNumber.equals(other.lineNumber))
            return false;
        if (prefix == null) {
            if (other.prefix != null)
                return false;
        } else if (!prefix.equals(other.prefix))
            return false;
        return true;
    }

}
143.在Java 中,如何跳出當前的多重嵌套循環(huán)?

答:在最外層循環(huán)前加一個(gè)標記如A,然后用break A;可以跳出多重循環(huán)。(Java中支持帶標簽的break和continue語(yǔ)句,作用有點(diǎn)類(lèi)似于C和C++中的goto語(yǔ)句,但是就像要避免使用goto一樣,應該避免使用帶標簽的break和continue,因為它不會(huì )讓你的程序變得更優(yōu)雅,很多時(shí)候甚至有相反的作用,所以這種語(yǔ)法其實(shí)不知道更好)

144.構造器(constructor)是否可被重寫(xiě)(override)?

答:構造器不能被繼承,因此不能被重寫(xiě),但可以被重載。

145.兩個(gè)對象值相同(x.equals(y) == true),但卻可有不同的hash code,這句話(huà)對不對?

答:不對,如果兩個(gè)對象x和y滿(mǎn)足x.equals(y) == true,它們的哈希碼(hash code)應當相同。Java對于eqauls方法和hashCode方法是這樣規定的:(1)如果兩個(gè)對象相同(equals方法返回true),那么它們的hashCode值一定要相同;(2)如果兩個(gè)對象的hashCode相同,它們并不一定相同。當然,你未必要按照要求去做,但是如果你違背了上述原則就會(huì )發(fā)現在使用容器時(shí),相同的對象可以出現在Set集合中,同時(shí)增加新元素的效率會(huì )大大下降(對于使用哈希存儲的系統,如果哈希碼頻繁的沖突將會(huì )造成存取性能急劇下降)。

補充:關(guān)于equals和hashCode方法,很多Java程序都知道,但很多人也就是僅僅知道而已,在Joshua Bloch的大作《Effective Java》(很多軟件公司,《Effective Java》、《Java編程思想》以及《重構:改善既有代碼質(zhì)量》是Java程序員必看書(shū)籍,如果你還沒(méi)看過(guò),那就趕緊去亞馬遜買(mǎi)一本吧)中是這樣介紹equals方法的:首先equals方法必須滿(mǎn)足自反性(x.equals(x)必須返回true)、對稱(chēng)性(x.equals(y)返回true時(shí),y.equals(x)也必須返回true)、傳遞性(x.equals(y)和y.equals(z)都返回true時(shí),x.equals(z)也必須返回true)和一致性(當x和y引用的對象信息沒(méi)有被修改時(shí),多次調用x.equals(y)應該得到同樣的返回值),而且對于任何非null值的引用x,x.equals(null)必須返回false。實(shí)現高質(zhì)量的equals方法的訣竅包括:1. 使用==操作符檢查“參數是否為這個(gè)對象的引用”;2. 使用instanceof操作符檢查“參數是否為正確的類(lèi)型”;3. 對于類(lèi)中的關(guān)鍵屬性,檢查參數傳入對象的屬性是否與之相匹配;4. 編寫(xiě)完equals方法后,問(wèn)自己它是否滿(mǎn)足對稱(chēng)性、傳遞性、一致性;5. 重寫(xiě)equals時(shí)總是要重寫(xiě)hashCode;6. 不要將equals方法參數中的Object對象替換為其他的類(lèi)型,在重寫(xiě)時(shí)不要忘掉@Override注解。

146.當一個(gè)對象被當作參數傳遞到一個(gè)方法后,此方法可改變這個(gè)對象的屬性,并可返回變化后的結果,那么這里到底是值傳遞還是引用傳遞?

答:是值傳遞。Java 編程語(yǔ)言只有值傳遞參數。當一個(gè)對象實(shí)例作為一個(gè)參數被傳遞到方法中時(shí),參數的值就是對該對象的引用。對象的屬性可以在被調用過(guò)程中被改變,但對象的引用是永遠不會(huì )改變的。C++和C#中可以通過(guò)傳引用或傳輸出參數來(lái)改變傳入的參數的值。

補充:Java中沒(méi)有傳引用實(shí)在是非常的不方便,這一點(diǎn)在Java 8中仍然沒(méi)有得到改進(jìn),正是如此在Java編寫(xiě)的代碼中才會(huì )出現大量的Wrapper類(lèi)(將需要通過(guò)方法調用修改的引用置于一個(gè)Wrapper類(lèi)中,再將Wrapper對象傳入方法),這樣的做法只會(huì )讓代碼變得臃腫,尤其是讓從C和C++轉型為Java程序員的開(kāi)發(fā)者無(wú)法容忍。

147.重載(Overload)和重寫(xiě)(Override)的區別。重載的方法能否根據返回類(lèi)型進(jìn)行區分?

答:Java的三大特征之一,多態(tài)機制,包括方法的多態(tài)和對象的多態(tài);方法的重載和重寫(xiě)都是實(shí)現多態(tài)的方式,區別在于前者實(shí)現的是編譯時(shí)的多態(tài)性,而后者實(shí)現的是運行時(shí)的多態(tài)性。重載(overload)發(fā)生在同一個(gè)類(lèi)中,相同的方法,如果有不同的參數列表(參數類(lèi)型不同、參數個(gè)數不同或者二者都不同)則視為重載;重寫(xiě)(override)發(fā)生在子類(lèi)與父類(lèi)之間也就是繼承機制當中,當父類(lèi)的方法不能滿(mǎn)足子類(lèi)的要求,此時(shí)子類(lèi)重寫(xiě)父類(lèi)的方法;要求:方法名、形參列表相同;返回值類(lèi)型和異常類(lèi)型,子類(lèi)小于等于父類(lèi);訪(fǎng)問(wèn)權限,子類(lèi)大于等于父類(lèi),切記父類(lèi)的私有方法以及被final修飾的方法不能被子類(lèi)重寫(xiě);重載對返回類(lèi)型沒(méi)有特殊的要求。

148.華為的面試題中曾經(jīng)問(wèn)過(guò)這樣一個(gè)問(wèn)題:為什么不能根據返回類(lèi)型來(lái)區分重載,為什么?

答:方法的重載,即使返回值類(lèi)型不同,也不能改變實(shí)現功能相同或類(lèi)似這一既定事實(shí);同時(shí)方法的重載只是要求兩同三不同,即在同一個(gè)類(lèi)中,相同的方法名稱(chēng),參數列表當中的參數類(lèi)型、個(gè)數、順序不同;跟權限修飾符和返回值類(lèi)無(wú)關(guān)

149.靜態(tài)嵌套類(lèi)(Static Nested Class)和內部類(lèi)(Inner Class)的不同?

答:內部類(lèi)就是在一個(gè)類(lèi)的內部定義的類(lèi),內部類(lèi)中不能定義靜態(tài)成員(靜態(tài)成員不是對象的特性,只是為了找一個(gè)容身之處,所以需要放到一個(gè)類(lèi)中而已,這么一點(diǎn)小事,你還要把它放到類(lèi)內部的一個(gè)類(lèi)中,過(guò)分了??!提供內部類(lèi),不是為讓你干這種事情,無(wú)聊,不讓你干。我想可能是既然靜態(tài)成員類(lèi)似c語(yǔ)言的全局變量,而內部類(lèi)通常是用于創(chuàng )建內部對象用的,所以,把“全局變量”放在內部類(lèi)中就是毫無(wú)意義的事情,既然是毫無(wú)意義的事情,就應該被禁止),內部類(lèi)可以直接訪(fǎng)問(wèn)外部類(lèi)中的成員變量,內部類(lèi)可以定義在外部類(lèi)的方法外面,也可以定義在外部類(lèi)的方法體中,如下所示:

public class Outer
{
        int out_x  = 0;
        public void method()
              {
               Inner1 inner1 = new Inner1();
               public class Inner2  //在方法體內部定義的內部類(lèi)
               {
                      public method()
                      {
                             out_x = 3;
                      }
               }
               Inner2 inner2 = new Inner2();
        }

        public class Inner1  //在方法體外面定義的內部類(lèi)
        {
        }

}

在方法體外面定義的內部類(lèi)的訪(fǎng)問(wèn)類(lèi)型可以是public,protecte,默認的,private等4種類(lèi)型,這就好像類(lèi)中定義的成員變量有4種訪(fǎng)問(wèn)類(lèi)型一樣,它們決定這個(gè)內部類(lèi)的定義對其他類(lèi)是否可見(jiàn);對于這種情況,我們也可以在外面創(chuàng )建內部類(lèi)的實(shí)例對象,創(chuàng )建內部類(lèi)的實(shí)例對象時(shí),一定要先創(chuàng )建外部類(lèi)的實(shí)例對象,然后用這個(gè)外部類(lèi)的實(shí)例對象去創(chuàng )建內部類(lèi)的實(shí)例對象,代碼如下:

Outer outer = new Outer();

Outer.Inner1 inner1 = outer.new Innner1();

在方法內部定義的內部類(lèi)前面不能有訪(fǎng)問(wèn)類(lèi)型修飾符,就好像方法中定義的局部變量一樣,但這種內部類(lèi)的前面可以使用final或abstract修飾符。這種內部類(lèi)對其他類(lèi)是不可見(jiàn)的其他類(lèi)無(wú)法引用這種內部類(lèi),但是這種內部類(lèi)創(chuàng )建的實(shí)例對象可以傳遞給其他類(lèi)訪(fǎng)問(wèn)。這種內部類(lèi)必須是先定義,后使用,即內部類(lèi)的定義代碼必須出現在使用該類(lèi)之前,這與方法中的局部變量必須先定義后使用的道理也是一樣的。這種內部類(lèi)可以訪(fǎng)問(wèn)方法體中的局部變量,但是,該局部變量前必須加final修飾符。

對于這些細節,只要在eclipse寫(xiě)代碼試試,根據開(kāi)發(fā)工具提示的各類(lèi)錯誤信息就可以馬上了解到。

在方法體內部還可以采用如下語(yǔ)法來(lái)創(chuàng )建一種匿名內部類(lèi),即定義某一接口或類(lèi)的子類(lèi)的同時(shí),還創(chuàng )建了該子類(lèi)的實(shí)例對象,無(wú)需為該子類(lèi)定義名稱(chēng):

public class Outer
{
        public void start()
        {
               new Thread(
new Runable(){
         public void run(){};
}
).start();
        }
}

最后,在方法外部定義的內部類(lèi)前面可以加上static關(guān)鍵字,從而成為Static Nested Class,它不再具有內部類(lèi)的特性,所有,從狹義上講,它不是內部類(lèi)。Static Nested Class與普通類(lèi)在運行時(shí)的行為和功能上沒(méi)有什么區別,只是在編程引用時(shí)的語(yǔ)法上有一些差別,它可以定義成public、protected、默認的、private等多種類(lèi)型,而普通類(lèi)只能定義成public和默認的這兩種類(lèi)型。在外面引用Static Nested Class類(lèi)的名稱(chēng)為“外部類(lèi)名.內部類(lèi)名”。在外面不需要創(chuàng )建外部類(lèi)的實(shí)例對象,就可以直接創(chuàng )建Static Nested Class,例如,假設Inner是定義在Outer類(lèi)中的Static Nested Class,那么可以使用如下語(yǔ)句創(chuàng )建Inner類(lèi):

Outer.Inner inner = newOuter.Inner();

由于static Nested Class不依賴(lài)于外部類(lèi)的實(shí)例對象,所以,static Nested Class能訪(fǎng)問(wèn)外部類(lèi)的非static成員變量(不能直接訪(fǎng)問(wèn),需要創(chuàng )建外部類(lèi)實(shí)例才能訪(fǎng)問(wèn)非靜態(tài)變量)。當在外部類(lèi)中訪(fǎng)問(wèn)Static Nested Class時(shí),可以直接使用Static Nested Class的名字,而不需要加上外部類(lèi)的名字了,在Static Nested Class中也可以直接引用外部類(lèi)的static的成員變量,不需要加上外部類(lèi)的名字。

在靜態(tài)方法中定義的內部類(lèi)也是Static Nested Class,這時(shí)候不能在類(lèi)前面加static關(guān)鍵字,靜態(tài)方法中的Static Nested Class與普通方法中的內部類(lèi)的應用方式很相似,它除了可以直接訪(fǎng)問(wèn)外部類(lèi)中的static的成員變量,還可以訪(fǎng)問(wèn)靜態(tài)方法中的局部變量,但是,該局部變量前必須加final修飾符。

備注:首先根據你的印象說(shuō)出你對內部類(lèi)的總體方面的特點(diǎn):例如,在兩個(gè)地方可以定義,可以訪(fǎng)問(wèn)外部類(lèi)的成員變量,不能定義靜態(tài)成員,這是大的特點(diǎn)。然后再說(shuō)一些細節方面的知識,例如,幾種定義方式的語(yǔ)法區別,靜態(tài)內部類(lèi),以及匿名內部類(lèi)。

Static Nested Class是被聲明為靜態(tài)(static)的內部類(lèi),它可以不依賴(lài)于外部類(lèi)實(shí)例被實(shí)例化。而通常的內部類(lèi)需要在外部類(lèi)實(shí)例化后才能實(shí)例化,其語(yǔ)法看起來(lái)挺詭異的,如下所示。

package com.bjsxt;
/**
* 撲克類(lèi)(一副撲克)
  * @author sxt
  *
 */
public class Poker {
    private static String[] suites = {"黑桃", "紅桃", "草花", "方塊"};
    private static int[] faces = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
          private Card[] cards;
    /**
      * 構造器
     */
    public Poker() {
        cards = new Card[52];
        for(int i = 0; i < suites.length; i++) {
              for(int j = 0; j < faces.length; j++) {
                cards[i * 13 + j] = new Card(suites[i], faces[j]);
            }
        }
    }

    /**
          * 洗牌 (隨機亂序)
          */
    public void shuffle() {
        for(int i = 0, len = cards.length; i < len; i++) {
            int index = (int) (Math.random() * len);
                   Card temp = cards[index];
            cards[index] = cards[i];
            cards[i] = temp;
        }
    }
     /**
     * 發(fā)牌
     * @param index 發(fā)牌的位置
     */
    public Card deal(int index) {
        return cards[index];
    }

    /**
     * 卡片類(lèi)(一張撲克)
     * [內部類(lèi)]
     * @author sxt
     */
    public class Card {
  private String suite;   // 花色
        private int face;       // 點(diǎn)數
  public Card(String suite, int face) {
            this.suite = suite;
            this.face = face;
       }
        @Override
        public String toString() {
            String faceStr = "";
            switch(face) {
                  case 1: faceStr = "A"; break;
            case 11: faceStr = "J"; break;
            case 12: faceStr = "Q"; break;
            case 13: faceStr = "K"; break;
            default: faceStr = String.valueOf(face);
            }
            return suite + faceStr;
        }
    }
}

測試類(lèi):

package com.bjsxt;

class PokerTest {
   public static void main(String[] args) {
        Poker poker = new Poker();
        poker.shuffle();            // 洗牌
        Poker.Card c1 = poker.deal(0);  // 發(fā)第一張牌
              // 對于非靜態(tài)內部類(lèi)Card
        // 只有通過(guò)其外部類(lèi)Poker對象才能創(chuàng  )建Card對象
        Poker.Card c2 = poker.new Card("紅心", 1);    // 自己創(chuàng  )建一張牌
        System.out.println(c1);     // 洗牌后的第一張
        System.out.println(c2);     // 打印: 紅心A
    }
}
150.抽象的(abstract)方法是否可同時(shí)是靜態(tài)的(static),是否可同時(shí)是本地方法(native),是否可同時(shí)被synchronized修飾?

答:都不能。抽象方法需要子類(lèi)重寫(xiě),而靜態(tài)的方法是無(wú)法被重寫(xiě)的,因此二者是矛盾的。本地方法是由本地代碼(如C代碼)實(shí)現的方法,而抽象方法是沒(méi)有實(shí)現的,也是矛盾的。synchronized和方法的實(shí)現細節有關(guān),抽象方法不涉及實(shí)現細節,因此也是相互矛盾的。

151.靜態(tài)變量和實(shí)例變量的區別?

答:靜態(tài)變量是被static修飾符修飾的變量,也稱(chēng)為類(lèi)變量,它屬于類(lèi),不屬于類(lèi)的任何一個(gè)對象,一個(gè)類(lèi)不管創(chuàng )建多少個(gè)對象,靜態(tài)變量在內存中有且僅有一個(gè)拷貝;實(shí)例變量必須依存于某一實(shí)例,需要先創(chuàng )建對象然后通過(guò)對象才能訪(fǎng)問(wèn)到它,靜態(tài)變量可以實(shí)現讓多個(gè)對象共享內存。兩者的相同點(diǎn):都有默認值而且在類(lèi)的任何地方都可以調用。在Java開(kāi)發(fā)中,上下文類(lèi)和工具類(lèi)中通常會(huì )有大量的靜態(tài)成員。?

152.是否可以從一個(gè)靜態(tài)(static)方法內部發(fā)出對非靜態(tài)(non-static)方法的調用?

答:不可以,靜態(tài)方法只能訪(fǎng)問(wèn)靜態(tài)成員,因為非靜態(tài)方法的調用要先創(chuàng )建對象,因此在調用靜態(tài)方法時(shí)可能對象并沒(méi)有被初始化。?

153.如何實(shí)現對象克???
package com.bjsxt;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class MyUtil {
      private MyUtil() {
        throw new AssertionError();
    }
      public static <T> T clone(T obj) throws Exception {
        ByteArrayOutputStream bout = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bout);
        oos.writeObject(obj);
        ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bin);
        return (T) ois.readObject();
        // 說(shuō)明:調用ByteArrayInputStream或ByteArrayOutputStream對象的close方法沒(méi)有任何意義
        // 這兩個(gè)基于內存的流只要垃圾回收器清理對象就能夠釋放資源
}
}

答:有兩種方式:

1.實(shí)現Cloneable接口并重寫(xiě)Object類(lèi)中的clone()方法;

2.實(shí)現Serializable接口,通過(guò)對象的序列化和反序列化實(shí)現克隆,可以實(shí)現真正的深度克隆,代碼如下。

下面是測試代碼:

package com.bjsxt;
import java.io.Serializable;
/**
 * 人類(lèi)
 * @author sxt
*/
class Person implements Serializable {
    private static final long serialVersionUID = -9102017020286042305L;
    private String name;    // 姓名
    private int age;        // 年齡
    private Car car;        // 座駕

    public Person(String name, int age, Car car) {
        this.name = name;
        this.age = age;
        this.car = car;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public Car getCar() {
        return car;
    }
    public void setCar(Car car) {
        this.car = car;
    }
    @Override
    public String toString() {
     return "Person [name=" + name + ", age=" + age + ", car=" + car + "]";
    }
  }
  /**
 * 小汽車(chē)類(lèi)
 * @author sxt
*/
class Car implements Serializable {
    private static final long serialVersionUID = -5713945027627603702L;
    private String brand;       // 品牌
    private int maxSpeed;       // 最高時(shí)速

    public Car(String brand, int maxSpeed) {
        this.brand = brand;
        this.maxSpeed = maxSpeed;
    }
    public String getBrand() {
        return brand;
    }
    public void setBrand(String brand) {
        this.brand = brand;
    }
    public int getMaxSpeed() {
        return maxSpeed;
    }

    public void setMaxSpeed(int maxSpeed) {
        this.maxSpeed = maxSpeed;
    }

    @Override
    public String toString() {
        return "Car [brand=" + brand + ", maxSpeed=" + maxSpeed + "]";
    }
  }

class CloneTest {
  public static void main(String[] args) {
        try {
            Person p1 = new Person("Hao LUO", 33, new Car("Benz", 300));
            Person p2 = MyUtil.clone(p1);   // 深度克隆
            p2.getCar().setBrand("BYD");
            // 修改克隆的Person對象p2關(guān)聯(lián)的汽車(chē)對象的品牌屬性
            // 原來(lái)的Person對象p1關(guān)聯(lián)的汽車(chē)不會(huì )受到任何影響
            // 因為在克隆Person對象時(shí)其關(guān)聯(lián)的汽車(chē)對象也被克隆了
            System.out.println(p1);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

注意:基于序列化和反序列化實(shí)現的克隆不僅僅是深度克隆,更重要的是通過(guò)泛型限定,可以檢查出要克隆的對象是否支持序列化,這項檢查是編譯器完成的,不是在運行時(shí)拋出異常,這種是方案明顯優(yōu)于使用Object類(lèi)的clone方法克隆對象。

154.接口是否可繼承(extends)接口? 抽象類(lèi)是否可實(shí)現(implements)接口? 抽象類(lèi)是否可繼承具體類(lèi)(concrete class)?

答:接口可以繼承接口。抽象類(lèi)可以實(shí)現(implements)接口,抽象類(lèi)可以繼承具體類(lèi)。抽象類(lèi)中可以有靜態(tài)的main方法。

備注:只要明白了接口和抽象類(lèi)的本質(zhì)和作用,這些問(wèn)題都很好回答,你想想,如果你是java語(yǔ)言的設計者,你是否會(huì )提供這樣的支持,如果不提供的話(huà),有什么理由嗎?如果你沒(méi)有道理不提供,那答案就是肯定的了。

只有記住抽象類(lèi)與普通類(lèi)的唯一區別就是不能創(chuàng )建實(shí)例對象和允許有abstract方法。?

155.一個(gè)“.java”源文件中是否可以包含多個(gè)類(lèi)(不是內部類(lèi))?有什么限制?

答:可以,但一個(gè)源文件中最多只能有一個(gè)公開(kāi)類(lèi)(public class)而且文件名必須和公開(kāi)類(lèi)的類(lèi)名完全保持一致。?

156.Anonymous Inner Class(匿名內部類(lèi))是否可以繼承其它類(lèi)?是否可以實(shí)現接口?

答:可以繼承其他類(lèi)或實(shí)現其他接口,在Swing編程中常用此方式來(lái)實(shí)現事件監聽(tīng)和回調。?但是有一點(diǎn)需要注意,它只能繼承一個(gè)類(lèi)或一個(gè)接口。

157.內部類(lèi)可以引用它的包含類(lèi)(外部類(lèi))的成員嗎?有沒(méi)有什么限制?

答:一個(gè)內部類(lèi)對象可以訪(fǎng)問(wèn)創(chuàng )建它的外部類(lèi)對象的成員,包括私有成員。如果要訪(fǎng)問(wèn)外部類(lèi)的局部變量,此時(shí)局部變量必須使用final修飾,否則無(wú)法訪(fǎng)問(wèn)。

158.Java 中的final關(guān)鍵字有哪些用法?

(1) 修飾類(lèi):表示該類(lèi)不能被繼承;

(2) 修飾方法:表示方法不能被重寫(xiě)但是允許重載;

(3) 修飾變量:表示變量只能一次賦值以后值不能被修改(常量);

(4) 修飾對象:對象的引用地址不能變,但是對象的初始化值可以變。

159.指出下面程序的運行結果:
package com.bjsxt;
class A{
  static{
        System.out.print("1");
    }
  public A(){
        System.out.print("2");
    }
}
class B extends A{
  static{
        System.out.print("a");
    }
    public B(){
        System.out.print("b");
    }
}

public class Hello{
  public static void main(String[] args){
        A ab = new B();
        ab = new B();
    }
}

答:執行結果:1a2b2b。創(chuàng )建對象時(shí)構造器的調用順序是:先初始化靜態(tài)成員,然后調用父類(lèi)構造器,再初始化非靜態(tài)成員,最后調用自身構造器。?

考點(diǎn):靜態(tài)代碼塊優(yōu)先級 > 構造方法的優(yōu)先級如果再加一個(gè)普通代碼塊,優(yōu)先順序如下:靜態(tài)代碼塊>普通代碼塊>構造方法

160.說(shuō)說(shuō)數據類(lèi)型之間的轉換:

1 ) 如何將字符串轉換為基本數據類(lèi)型?

2 ) 如何將基本數據類(lèi)型轉換為字符串?

答:

1 ) 調用基本數據類(lèi)型對應的包裝類(lèi)中的方法parseXXX(String)或valueOf(String)即可返回相應基本類(lèi)型;

2 ) 一種方法是將基本數據類(lèi)型與空字符串(””)連接(+)即可獲得其所對應的字符串;另一種方法是調用String 類(lèi)中的valueOf(…)方法返回相應字符串?

161.如何實(shí)現字符串的反轉及替換?

答:方法很多,可以自己寫(xiě)實(shí)現也可以使用String或StringBuffer / StringBuilder中的方法。有一道很常見(jiàn)的面試題是用遞歸實(shí)現字符串反轉,代碼如下所示:

package com.bjsxt;
public class A{
    public static String reverse(String originStr) {
 if(originStr == null || originStr.length() <= 1)
     return originStr;
       return reverse(originStr.substring(1)) + originStr.charAt(0);
     }
}
162.怎樣將GB2312編碼的字符串轉換為ISO-8859-1編碼的字符串?

答:代碼如下所示:

String s1 = "你好";

String s2 = newString(s1.getBytes("GB2312"), "ISO-8859-1");?

在String類(lèi)的構造方法當中,存在一個(gè)字符集設置的方法,具體如下:

163.Java中的日期和時(shí)間:

1 ) 如何取得年月日、小時(shí)分鐘秒?

2 ) 如何取得從1970年1月1日0時(shí)0分0秒到現在的毫秒數?

3 ) 如何取得某月的最后一天?

4 ) 如何格式化日期?

答:操作方法如下所示:

1 ) 創(chuàng )建java.util.Calendar 實(shí)例,調用其get()方法傳入不同的參數即可獲得參數所對應的值

2 ) 以下方法均可獲得該毫秒數:

Calendar.getInstance().getTimeInMillis();

time.getActualMaximum(Calendar.DAY_OF_MONTH);

4 ) 利用java.text.DataFormat 的子類(lèi)(如SimpleDateFormat類(lèi))中的format(Date)方法可將日期格式化。

164.打印昨天的當前時(shí)刻。
package com.bjsxt;
import java.util.Calendar;
public class YesterdayCurrent {
 public static void main(String[] args){
 Calendar cal = Calendar.getInstance();
 cal.add(Calendar.DATE, -1);
 System.out.println(cal.getTime());
 }
}
165.Java反射技術(shù)主要實(shí)現類(lèi)有哪些,作用分別是什么?

在JDK中,主要由以下類(lèi)來(lái)實(shí)現Java反射機制,這些類(lèi)都位于java.lang.reflect包中

1)Class類(lèi):代表一個(gè)類(lèi)

2)Field 類(lèi):代表類(lèi)的成員變量(屬性)

3)Method類(lèi):代表類(lèi)的成員方法

4)Constructor 類(lèi):代表類(lèi)的構造方法

5)Array類(lèi):提供了動(dòng)態(tài)創(chuàng )建數組,以及訪(fǎng)問(wèn)數組的元素的靜態(tài)方法

166.Class類(lèi)的作用?生成Class對象的方法有哪些?

Class類(lèi)是Java 反射機制的起源和入口,用于獲取與類(lèi)相關(guān)的各種信息,提供了獲取類(lèi)信息的相關(guān)方法。Class類(lèi)繼承自Object類(lèi)

Class類(lèi)是所有類(lèi)的共同的圖紙。每個(gè)類(lèi)有自己的對象,好比圖紙和實(shí)物的關(guān)系;每個(gè)類(lèi)也可看做是一個(gè)對象,有共同的圖紙Class,存放類(lèi)的 結構信息,能夠通過(guò)相應方法取出相應信息:類(lèi)的名字、屬性、方法、構造方法、父類(lèi)和接口

方 法
示 例
對象名
.getClass()
String str="bdqn";
Class clazz = str.getClass();
對象名
.getSuperClass()
Student stu = new Student();
Class c1 = stu.getClass();
Class c2 = stu.getSuperClass();
Class.forName()
Class clazz = Class.forName("java.lang.Object");
Class.forName("oracle.jdbc.driver.OracleDriver");
類(lèi)名.class
類(lèi)名.class
Class c2 = Student.class;
Class c2 = int.class
包裝類(lèi).TYPE
包裝類(lèi).TYPE
Class c2 = Boolean.TYPE;
167.反射的使用場(chǎng)合和作用、及其優(yōu)缺點(diǎn)

1)使用場(chǎng)合

在編譯時(shí)根本無(wú)法知道該對象或類(lèi)可能屬于哪些類(lèi),程序只依靠運行時(shí)信息來(lái)發(fā)現該對象和類(lèi)的真實(shí)信息。

2)主要作用

通過(guò)反射可以使程序代碼訪(fǎng)問(wèn)裝載到JVM 中的類(lèi)的內部信息,獲取已裝載類(lèi)的屬性信息,獲取已裝載類(lèi)的方法,獲取已裝載類(lèi)的構造方法信息

3)反射的優(yōu)點(diǎn)

反射提高了Java程序的靈活性和擴展性,降低耦合性,提高自適應能力。它允許程序創(chuàng )建和控制任何類(lèi)的對象,無(wú)需提前硬編碼目標類(lèi);反射是其它一些常用語(yǔ)言,如C、C++、Fortran 或者Pascal等都不具備的

4) Java反射技術(shù)應用領(lǐng)域很廣,如軟件測試等;許多流行的開(kāi)源框架例如Struts、Hibernate、Spring在實(shí)現過(guò)程中都采用了該技術(shù)

5)反射的缺點(diǎn)

性能問(wèn)題:使用反射基本上是一種解釋操作,用于字段和方法接入時(shí)要遠慢于直接代碼。因此Java反射機制主要應用在對靈活性和擴展性要求很高的系統框架上,普通程序不建議使用。

使用反射會(huì )模糊程序內部邏輯:程序人員希望在源代碼中看到程序的邏輯,反射等繞過(guò)了源代碼的技術(shù),因而會(huì )帶來(lái)維護問(wèn)題。反射代碼比相應的直接代碼更復雜。

168.面向對象設計原則有哪些

面向對象設計原則是面向對象設計的基石,面向對象設計質(zhì)量的依據和保障,設計模式是面向對象設計原則的經(jīng)典應用

1)單一職責原則SRP

2)開(kāi)閉原則OCP

3)里氏替代原則LSP

4)依賴(lài)注入原則DIP

5)接口分離原則ISP

6)迪米特原則LOD

7)組合/聚合復用原則CARP

8)開(kāi)閉原則具有理想主義的色彩,它是面向對象設計的終極目標。其他設計原則都可以看作是開(kāi)閉原則的實(shí)現手段或方法

String相關(guān):

169.下面程序的運行結果是()(選擇一項)
String str1="hello";

String str2=new String("hello");

System.out.println(str1==str2);
A. true
B. false
C. hello
D. he
答案:B
分析:str1沒(méi)有使用new關(guān)鍵字,在堆中沒(méi)有開(kāi)辟空間,其值”hello”在常量池中,str2使用new關(guān)鍵字創(chuàng )建了一個(gè)對象,在堆中開(kāi)辟了空間,”==”比較的是對象的引用,即內存地址,所以str1與str2兩個(gè)對象的內存地址是不相同的
170.Java語(yǔ)言中,String類(lèi)中的indexOf()方法返回值的類(lèi)型是()
A. int16
B. int32
C. int
D. long
答案:C
171.給定以下代碼,程序的運行結果是 ()(選擇一項)
public class Example {
String str=new String("good");
char [] ch={'a','b','c'};

public static void main(String[] args) {
Example ex=new Example();
ex.change(ex.str, ex.ch);
System.out.print(ex.str+"and");
System.out.print(ex.ch);
}

public void change(String  str,char ch[]){
str="test ok";
ch[0]='g';
}
}
A. goodandabc
B. goodandgbc
C. test okandabc
D. test okandgbc
答案:B
分析:在方法調用時(shí),在change方法中對str的值進(jìn)行修改,是將str指向了常量江池中的”test ok”,而主方法中的ex.str仍然指向的是常量池中的”good”。字符型數組在方法調用時(shí),將主方法中ex.ch的引用傳遞給change方法中的ch,指向是堆中的同一堆空間,所以修改ch[0]的時(shí)候,ex.ch可以看到相同的修改后的結果。
172.執行下列代碼后,哪個(gè)結論是正確的()(選擇兩項)

String[] s=new String[10];

A. s[10]為””
B. s[9]為null
C. s[0]為未定義
D. s.length為10
答案:BD
分析: 引用數據類(lèi)型的默認值均為null
s.length數組的長(cháng)度
173.實(shí)現String類(lèi)的replaceAll方法

思路說(shuō)明:replaceAll方法的本質(zhì)是使用正則表達式進(jìn)行匹配,最終調用的其實(shí)是Matcher對象的replaceAll方法。

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class TestStringReplaceAll {
public static void main(String[] args) {
String str = "a1s2d3f4h5j6k7";
// 將字符串中的數字全部替換為0
System.out.println(replaceAll(str, "\\d", "0"));
}

/**
 * @param str:源字符串
 * @param regex:正則表達式
 * @param newStr:替換后的子字符串
 * @return 返回替換成功后的字符串
 */
public static String replaceAll(String str, String regex, String newStr) {
Pattern pattern = Pattern.compile(regex);
Matcher mathcer = pattern.matcher(str);
String reslut = mathcer.replaceAll(newStr);
return reslut;
}
}
174.在“=”后填寫(xiě)適當的內容:

String []a=new String[10];

則:a[0]~a[9]=null;

a.length=10;

如果是int[]a=new int[10];

則:a[0]~a[9]= (0)

a.length= (10)

175.是否可以繼承String類(lèi)?

答:不可以,因為String類(lèi)有final修飾符,而final修飾的類(lèi)是不能被繼承的,實(shí)現細節不允許改變。

public final class String implements java.io.Serializable,

Comparable< String>, CharSequence

176.給定兩個(gè)字符串s和t, 寫(xiě)一個(gè)函數來(lái)決定是否t是s的重組詞。你可以假設字符串只包含小寫(xiě)字母。
public class Solution {
    public boolean isAnagram(String s, String t) {
        if(s.length()!=t.length())
            return false;
        int bit[] = new int[26];
        for(int i=0;i<s.length();i++){
            bit[s.charAt(i)-'a']++;
        }

        for(int i=0;i<s.length();i++){
            if(--bit[t.charAt(i)-'a']<0)
                return false;
        }
        return true;
    }

}
177.String s=new String(“abc”);創(chuàng )建了幾個(gè)String對象。

兩個(gè)或一個(gè),”abc”對應一個(gè)對象,這個(gè)對象放在字符串常量緩沖區,常量”abc”不管出現多少遍,都是緩沖區中的那一個(gè)。New String每寫(xiě)一遍,就創(chuàng )建一個(gè)新的對象,它一句那個(gè)常量”abc”對象的內容來(lái)創(chuàng )建出一個(gè)新String對象。如果以前就用過(guò)’abc’,這句代表就不會(huì )創(chuàng )建”abc”自己了,直接從緩沖區拿。

178.輸出結果?
String str1=“hello”;
Sring str2=“he”+new String(“l(fā)lo”);
Sysem.out.println(str1==str2));
Sysem.out.println(str.equal(str2));

false

true

179.下列程序的輸出結果是什么?
import java.util.*;
public class Test 6{
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
Integer k=new Integer(i);
System.out.println(k+" Hello world");
}
}
}

0 Hello world

1 Hello world

2 Hello world

3 Hello world

4 Hello world

5 Hello world

6 Hello world

7 Hello world

8 Hello world

9 Hello world

180.關(guān)于java.lang.String類(lèi),以下描述正確的一項是()
A. String類(lèi)是final類(lèi)故不可繼承
B. String類(lèi)final類(lèi)故可以繼承
C. String類(lèi)不是final類(lèi)故不可繼承
D. String;類(lèi)不是final類(lèi)故可以繼承
答案:A
181.下面哪個(gè)是正確的()
A. String temp[ ] = new String{“a”,”b”,”c”};
B. String temp[ ] = {“a”,”b”,”c”};
C. String temp= {“a”,”b”,”c”};
D. String[ ] temp = {“a”,”b”,”c”};
答案:BD
182.已知如下代碼:執行結果是什么()
package com.bjsxt;
public class Test {
public static void main(String[] args) {
String s1 = new String("Hello");
String s2 = new String("Hello");
System.out.print(s1 == s2);
String s3 = "Hello";
String s4 = "Hello";
System.out.print(s3 == s4);
s1 = s3;
s2 = s4;
System.out.print(s1 == s2);
}
}
A. false true true
B. true false true
C. true true false
D. true true false
答案:A
183.字符串如何轉換為int類(lèi)型
public class Test {
public static void main(String[] args) {
 //方式一
 int num=Integer.parseInt("123");
 //方式二
 int num2=Integer.valueOf("123");
 System.out.println(num+"  "+num2);
}
}
184.寫(xiě)一個(gè)方法,實(shí)現字符串的反轉,如:輸入abc,輸出cba
public class Test {
public static void main(String[] args) {
String result=reverse("abc");
System.out.println(result);
}
public static String reverse(String str){
StringBuilder result=new StringBuilder("");
char[] chArra=str.toCharArray();
for(int i=chArra.length-1;i>=0;i--){
char ch=chArra[i];
result.append(ch);
}
return result.toString();
}
}
185.編寫(xiě)java,將“I follow Bill Gate.Tom Gate.John Gate”中的“Gate”全部替換為“Gates”
public classDemo1 {
publicstaticvoid main(String[] args) {
String s="I follow Bill Gate.Tom Gate.John Gate";
System.out.println(s);
s=s.replaceAll("Gate","Gates");
System.out.println(s);
}
}
186.String 是最基本的數據類(lèi)型嗎?

答: 不是 。Java中的基本數據類(lèi)型只有8個(gè):byte、short、int、long、float、double、char、boolean;除了基本類(lèi)型(primitive type)和枚舉類(lèi)型(enumeration type),剩下的都是引用類(lèi)型(reference type)。

187.String 和StringBuilder、StringBuffer 的區別?

答: Java 平臺提供了兩種類(lèi)型的字符串:String和StringBuffer / StringBuilder

相同點(diǎn):

它們都可以?xún)Υ婧筒僮髯址?,同時(shí)三者都使用final修飾,都屬于終結類(lèi)不能派生子類(lèi),操作的相關(guān)方法也類(lèi)似例如獲取字符串長(cháng)度等;

不同點(diǎn):

其中String是只讀字符串,也就意味著(zhù)String引用的字符串內容是不能被改變的,而StringBuffer和StringBuilder類(lèi)表示的字符串對象可以直接進(jìn)行修改,在修改的同時(shí)地址值不會(huì )發(fā)生改變。StringBuilder是JDK 1.5中引入的,它和StringBuffer的方法完全相同,區別在于它是在單線(xiàn)程環(huán)境下使用的,因為它的所有方面都沒(méi)有被synchronized修飾,因此它的效率也比StringBuffer略高。在此重點(diǎn)說(shuō)明一下,String、StringBuffer、StringBuilder三者類(lèi)型不一樣,無(wú)法使用equals()方法比較其字符串內容是否一樣!

補充1:有一個(gè)面試題問(wèn):有沒(méi)有哪種情況用+做字符串連接比調用StringBuffer / StringBuilder對象的append方法性能更好?如果連接后得到的字符串在靜態(tài)存儲區中是早已存在的,那么用+做字符串連接是優(yōu)于StringBuffer / StringBuilder的append方法的。

補充2:下面也是一個(gè)面試題,問(wèn)程序的輸出,看看自己能不能說(shuō)出正確答案。

package com.bjsxt;
public class smallT {
public static void main(String[] args) {
        String a = "Programming";
        String b = new String("Programming");
        String c = "Program" + "ming";
              System.out.println(a == b);
              System.out.println(a == c);
               System.out.println(a.equals(b));
               System.out.println(a.equals(c));
               System.out.println(a.intern() == b.intern());
}
}

解析:

String類(lèi)存在intern()方法,含義如下:返回字符串對象的規范化表示形式。它遵循以下規則:對于任意兩個(gè)字符串 s 和 t,當且僅當 s.equals(t) 為 true 時(shí),s.intern()?==?t.intern() 才為 true。

字符串比較分為兩種形式,一種使用比較運算符”==”比較,他們比較的是各自的字符串在內存當中的地址值是否相同;一種是使用equals()方法進(jìn)行比較,比較的是兩個(gè)字符串的內容是否相同!

結果如下:

a == b-->false

a == c-->true

a.equals(b)-->true

a.equals(c)-->true

a.intern() == b.intern()-->true

188.String類(lèi)為什么是final的

答:1) 為了效率。若允許被繼承,則其高度的被使用率可能會(huì )降低程序的性能。

2)為了安全。JDK中提供的好多核心類(lèi)比如String,這類(lèi)的類(lèi)的內部好多方法的實(shí)現都不是java編程語(yǔ)言本身編寫(xiě)的,好多方法都是調用的操作系統本地的API,這就是著(zhù)名的“本地方法調用”,也只有這樣才能做事,這種類(lèi)是非常底層的,和操作系統交流頻繁的,那么如果這種類(lèi)可以被繼承的話(huà),如果我們再把它的方法重寫(xiě)了,往操作系統內部寫(xiě)入一段具有惡意攻擊性質(zhì)的代碼什么的,這不就成了核心病毒了么?不希望別人改,這個(gè)類(lèi)就像一個(gè)工具一樣,類(lèi)的提供者給我們提供了, 就希望我們直接用就完了,不想讓我們隨便能改,其實(shí)說(shuō)白了還是安全性,如果隨便能改了,那么java編寫(xiě)的程序肯定就很不穩定,你可以保證自己不亂改, 但是將來(lái)一個(gè)項目好多人來(lái)做,管不了別人,再說(shuō)有時(shí)候萬(wàn)一疏忽了呢?他也不是估計的, 所以這個(gè)安全性是很重要的,java和C++相比,優(yōu)點(diǎn)之一就包括這一點(diǎn)。

189.String類(lèi)型是基本數據類(lèi)型嗎?基本數據類(lèi)型有哪些

1) 基本數據類(lèi)型包括byte、short/char、int、long、float、double、boolean

2 ) java.lang.String類(lèi)是引用數據類(lèi)型,并且是final類(lèi)型的,因此不可以繼承這個(gè)類(lèi)、不能修改這個(gè)類(lèi)。為了提高效率節省空間,我們應該用StringBuffer類(lèi)

190.String?s="Hello";s=s+"world!";執行后,是否是對前面s指向空間內容的修改?

答:不是對前面s指向空間內容的直接修改。

因為String被設計成不可變(immutable)類(lèi),所以它的所有對象都是不可變對象。在這段代碼中,s原先指向一個(gè)String對象,內容是 "Hello",然后我們對s進(jìn)行了+操作,那么s所指向的那個(gè)對象是否發(fā)生了改變呢?答案是沒(méi)有。這時(shí),s不指向原來(lái)那個(gè)對象了,而指向了另一個(gè) String對象,內容為"Hello?world!",原來(lái)那個(gè)對象還存在于內存之中,只是s這個(gè)引用變量不再指向它了。

通過(guò)上面的說(shuō)明,我們很容易導出另一個(gè)結論,如果經(jīng)常對字符串進(jìn)行各種各樣的修改,或者說(shuō),不可預見(jiàn)的修改,那么使用String來(lái)代表字符串的話(huà)會(huì )引起很大的內存開(kāi)銷(xiāo)。因為 String對象建立之后不能再改變,所以對于每一個(gè)不同的字符串,都需要一個(gè)String對象來(lái)表示。這時(shí),應該考慮使用StringBuffer類(lèi),它允許修改,而不是每個(gè)不同的字符串都要生成一個(gè)新的對象。并且,這兩種類(lèi)的對象轉換十分容易。

同時(shí),我們還可以知道,如果要使用內容相同的字符串,不必每次都new一個(gè)String。例如我們要在構造器中對一個(gè)名叫s的String引用變量進(jìn)行初始化,把它設置為初始值,應當這樣做:

public class Demo {
private String s;
...
public Demo {
s = "Initial Value";
}
...
}

而非

s?=?new?String("Initial?Value");

后者每次都會(huì )調用構造器,生成新對象,性能低下且內存開(kāi)銷(xiāo)大,并且沒(méi)有意義,因為String對象不可改變,所以對于內容相同的字符串,只要一個(gè)String對象來(lái)表示就可以了。也就說(shuō),多次調用上面的構造器創(chuàng )建多個(gè)對象,他們的String類(lèi)型屬性s都指向同一個(gè)對象。

上面的結論還基于這樣一個(gè)事實(shí):對于字符串常量,如果內容相同,Java認為它們代表同一個(gè)String對象。而用關(guān)鍵字new調用構造器,總是會(huì )創(chuàng )建一個(gè)新的對象,無(wú)論內容是否相同。

至于為什么要把String類(lèi)設計成不可變類(lèi),是它的用途決定的。其實(shí)不只String,很多Java標準類(lèi)庫中的類(lèi)都是不可變的。在開(kāi)發(fā)一個(gè)系統的時(shí)候,我們有時(shí)候也需要設計不可變類(lèi),來(lái)傳遞一組相關(guān)的值,這也是面向對象思想的體現。不可變類(lèi)有一些優(yōu)點(diǎn),比如因為它的對象是只讀的,所以多線(xiàn)程并發(fā)訪(fǎng)問(wèn)也不會(huì )有任何問(wèn)題。當然也有一些缺點(diǎn),比如每個(gè)不同的狀態(tài)都要一個(gè)對象來(lái)代表,可能會(huì )造成性能上的問(wèn)題。所以Java標準類(lèi)庫還提供了一個(gè)可變版本,即 StringBuffer。

191.String s = new String("xyz");創(chuàng )建幾個(gè)String Object?

答:兩個(gè)或一個(gè),”xyz”對應一個(gè)對象,這個(gè)對象放在字符串常量緩沖區,常量”xyz”不管出現多少遍,都是緩沖區中的那一個(gè)。New String每寫(xiě)一遍,就創(chuàng )建一個(gè)新的對象,它一句那個(gè)常量”xyz”對象的內容來(lái)創(chuàng )建出一個(gè)新String對象。如果以前就用過(guò)’xyz’,這句代表就不會(huì )創(chuàng )建”xyz”自己了,直接從緩沖區拿。

192.下面這條語(yǔ)句一共創(chuàng )建了多少個(gè)對象:String s="a"+"b"+"c"+"d";

答:對于如下代碼:

String s1 = "a";

String s2 = s1 + "b";

String s3 = "a" + "b";

System.out.println(s2 == "ab");

System.out.println(s3 == "ab");

第一條語(yǔ)句打印的結果為false,第二條語(yǔ)句打印的結果為true,這說(shuō)明javac編譯可以對字符串常量直接相加的表達式進(jìn)行優(yōu)化,不必要等到運行期去進(jìn)行加法運算處理,而是在編譯時(shí)去掉其中的加號,直接將其編譯成一個(gè)這些常量相連的結果。

題目中的第一行代碼被編譯器在編譯時(shí)優(yōu)化后,相當于直接定義一個(gè)”abcd”的字符串,所以,上面的代碼應該只創(chuàng )建了一個(gè)String對象。

寫(xiě)如下兩行代碼,

String s = "a" + "b" + "c" + "d";

System.out.println(s == "abcd");

最終打印的結果應該為true。

集合:

193.Java集合體系結構(List、Set、Collection、Map的區別和聯(lián)系)

1、Collection 接口存儲一組不唯一,無(wú)序的對象

2、List 接口存儲一組不唯一,有序(插入順序)的對象

3、Set 接口存儲一組唯一,無(wú)序的對象

4、Map接口存儲一組鍵值對象,提供key到value的映射。Key無(wú)序,唯一。value不要求有序,允許重復。(如果只使用key存儲,而不使用value,那就是Set)

194.Vector和ArrayList的區別和聯(lián)系

相同點(diǎn):

1)實(shí)現原理相同---底層都使用數組

2)功能相同---實(shí)現增刪改查等操作的方法相似

3)都是長(cháng)度可變的數組結構,很多情況下可以互用

不同點(diǎn):

1)Vector是早期JDK版本提供,ArrayList是新版本替代Vector的

2)Vector線(xiàn)程安全,ArrayList重速度輕安全,線(xiàn)程非安全長(cháng)度需增長(cháng)時(shí),Vector默認增長(cháng)一倍,ArrayList增長(cháng)50%

195.ArrayList和LinkedList的區別和聯(lián)系

相同點(diǎn):

兩者都實(shí)現了List接口,都具有List中元素有序、不唯一的特點(diǎn)。

不同點(diǎn):

ArrayList實(shí)現了長(cháng)度可變的數組,在內存中分配連續空間。遍歷元素和隨機訪(fǎng)問(wèn)元素的效率比較高;

LinkedList采用鏈表存儲方式。插入、刪除元素時(shí)效率比較高

196.HashMap和Hashtable的區別和聯(lián)系

相同點(diǎn):

實(shí)現原理相同,功能相同,底層都是哈希表結構,查詢(xún)速度快,在很多情況下可以互用

不同點(diǎn):

1、Hashtable是早期提供的接口,HashMap是新版JDK提供的接口

2、Hashtable繼承Dictionary類(lèi),HashMap實(shí)現Map接口

3、Hashtable線(xiàn)程安全,HashMap線(xiàn)程非安全

4、Hashtable不允許null值,HashMap允許null值

197.HashSet的使用和原理(hashCode()和equals())

1)哈希表的查詢(xún)速度特別快,時(shí)間復雜度為O(1)。

2)HashMap、Hashtable、HashSet這些集合采用的是哈希表結構,需要用到hashCode哈希碼,hashCode是一個(gè)整數值。

3)系統類(lèi)已經(jīng)覆蓋了hashCode方法 自定義類(lèi)如果要放入hash類(lèi)集合,必須重寫(xiě)hashcode。如果不重寫(xiě),調用的是Object的hashcode,而Object的hashCode實(shí)際上是地址。

4)向哈希表中添加數據的原理:當向集合Set中增加對象時(shí),首先集合計算要增加對象的hashCode碼,根據該值來(lái)得到一個(gè)位置用來(lái)存放當前對象,如在該位置沒(méi)有一個(gè)對象存在的話(huà),那么集合Set認為該對象在集合中不存在,直接增加進(jìn)去。如果在該位置有一個(gè)對象存在的話(huà),接著(zhù)將準備增加到集合中的對象與該位置上的對象進(jìn)行equals方法比較,如果該equals方法返回false,那么集合認為集合中不存在該對象,在進(jìn)行一次散列,將該對象放到散列后計算出的新地址里。如果equals方法返回true,那么集合認為集合中已經(jīng)存在該對象了,不會(huì )再將該對象增加到集合中了。

5)在哈希表中判斷兩個(gè)元素是否重復要使用到hashCode()和equals()。hashCode決定數據在表中的存儲位置,而equals判斷是否存在相同數據。

6) Y=K(X) :K是函數,X是哈希碼,Y是地址

198.TreeSet的原理和使用(Comparable和comparator)

1)TreeSet集合,元素不允許重復且有序(自然順序)

2)TreeSet采用樹(shù)結構存儲數據,存入元素時(shí)需要和樹(shù)中元素進(jìn)行對比,需要指定比較策略。

3)可以通過(guò)Comparable(外部比較器)和Comparator(內部比較器)來(lái)指定比較策略,實(shí)現了Comparable的系統類(lèi)可以順利存入TreeSet。自定義類(lèi)可以實(shí)現Comparable接口來(lái)指定比較策略。

4)可創(chuàng )建Comparator接口實(shí)現類(lèi)來(lái)指定比較策略,并通過(guò)TreeSet構造方法參數傳入。這種方式尤其對系統類(lèi)非常適用。

199.集合和數組的比較(為什么引入集合)

數組不是面向對象的,存在明顯的缺陷,集合完全彌補了數組的一些缺點(diǎn),比數組更靈活更實(shí)用,可大大提高軟件的開(kāi)發(fā)效率而且不同的集合框架類(lèi)可適用于不同場(chǎng)合。具體如下:

1)數組的效率高于集合類(lèi).

2)數組能存放基本數據類(lèi)型和對象,而集合類(lèi)中只能放對象。

3)數組容量固定且無(wú)法動(dòng)態(tài)改變,集合類(lèi)容量動(dòng)態(tài)改變。

4)數組無(wú)法判斷其中實(shí)際存有多少元素,length只告訴了array的容量。

5)集合有多種實(shí)現方式和不同的適用場(chǎng)合,而不像數組僅采用順序表方式。

6)集合以類(lèi)的形式存在,具有封裝、繼承、多態(tài)等類(lèi)的特性,通過(guò)簡(jiǎn)單的方法和屬性調用即可實(shí)現各種復雜操作,大大提高軟件的開(kāi)發(fā)效率。

200.Collection和Collections的區別

1)Collection是Java提供的集合接口,存儲一組不唯一,無(wú)序的對象。它有兩個(gè)子接口List和Set。

2)Java中還有一個(gè)Collections類(lèi),專(zhuān)門(mén)用來(lái)操作集合類(lèi) ,它提供一系列靜態(tài)方法實(shí)現對各種集合的搜索、排序、線(xiàn)程安全化等操作。

201.下列說(shuō)法正確的有()(選擇一項)
A. LinkedList繼承自L(fǎng)ist
B. AbstractSet繼承自Set
C. HashSet繼承自AbstractSet
D. TreeMap繼承自HashMap
答案: C
分析:A:LinkedList實(shí)現List接口
B:AbstractSet實(shí)現Set接口
D:TreeMap繼承AbstractMap
202.Java的HashMap和Hashtable有什么區別HashSet和HashMap有什么區別?使用這些結構保存的數需要重載的方法是哪些?

答:HashMap與Hashtable實(shí)現原理相同,功能相同,底層都是哈希表結構,查詢(xún)速度快,在很多情況下可以互用

兩者的主要區別如下

1、Hashtable是早期JDK提供的接口,HashMap是新版JDK提供的接口

2、Hashtable繼承Dictionary類(lèi),HashMap實(shí)現Map接口

3、Hashtable線(xiàn)程安全,HashMap線(xiàn)程非安全

4、Hashtable不允許null值,HashMap允許null值

HashSet與HashMap的區別

1、HashSet底層是采用HashMap實(shí)現的。HashSet 的實(shí)現比較簡(jiǎn)單,HashSet 的絕大部分方法都是通過(guò)調用 HashMap 的方法來(lái)實(shí)現的,因此 HashSet 和 HashMap 兩個(gè)集合在實(shí)現本質(zhì)上是相同的。

2、HashMap的key就是放進(jìn)HashSet中對象,value是Object類(lèi)型的。

3、當調用HashSet的add方法時(shí),實(shí)際上是向HashMap中增加了一行(key-value對),該行的key就是向HashSet增加的那個(gè)對象,該行的value就是一個(gè)Object類(lèi)型的常量

203.列出Java中的集合類(lèi)層次結構?

答:Java中集合主要分為兩種:Collection和Map。Collection是List和Set接口的父接口;ArrayList和LinkedList是List的實(shí)現類(lèi);HashSet和TreeSet是Set的實(shí)現類(lèi);LinkedHashSet是HashSet的子類(lèi)。HashMap和TreeMap是Map的實(shí)現類(lèi);LinkedHashMap是HashMap的子類(lèi)。

圖中:虛線(xiàn)框中為接口,實(shí)線(xiàn)框中為類(lèi)。

204.List,Set,Map各有什么特點(diǎn)

答:List 接口存儲一組不唯一,有序(插入順序)的對象。

Set 接口存儲一組唯一,無(wú)序的對象。

Map接口存儲一組鍵值對象,提供key到value的映射。key無(wú)序,唯一。value不要求有序,允許重復。(如果只使用key存儲,而不使用value,那就是Set)。

205.ArrayList list=new ArrayList(20);中的list擴充幾次()
A. 0
B. 1
C. 2
D. 3
答案:A
分析:已經(jīng)指定了長(cháng)度, 所以不擴容
206.List、Set、Map哪個(gè)繼承自Collection接口,一下說(shuō)法正確的是()
A. List Map
B. Set Map
C. List Set
D. List Map Set
答案:C
分析:Map接口繼承了java.lang.Object類(lèi),但沒(méi)有實(shí)現任何接口.
207.合并兩個(gè)有序的鏈表
public class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
if (l1 == null || l2 == null) {
            return l1 != null ? l1 : l2;
        }
        ListNode head = l1.val < l2.val ? l1 : l2;
        ListNode other = l1.val >= l2.val ? l1 : l2;
        ListNode prevHead = head;
        ListNode prevOther = other;
        while (prevHead != null) {
            ListNode next = prevHead.next;
            if (next != null && next.val > prevOther.val) {
                prevHead.next = prevOther;
                prevOther = next;
            }
            if(prevHead.next==null){
                prevHead.next=prevOther;
                break;
            }
            prevHead=prevHead.next;
        }
        return head;
}
}
208.用遞歸方式實(shí)現鏈表的轉置。
/**
Definition for singly-linked list.
public class ListNode {
int val;
ListNode next;
ListNode(int x) { val = x; }
* }
*/
public class Solution {
public ListNode reverseList(ListNode head) {
if(head==null||head.next ==null)
            return head;
        ListNode prev = reverseList(head.next);
        head.next.next = head;
        head.next = null;
        return prev;
}
}
209.給定一個(gè)不包含相同元素的整數集合,nums,返回所有可能的子集集合。解答中集合不能包含重復的子集。
public class Solution {
    public List<List<Integer>> subsets (int[] nums) {
        List<List<Integer>> res = new ArrayList<ArrayList<Integer>>();
        List<Integer> item = new ArrayList<Integer>();
        if(nums.length == 0 || nums == null)
            return res;
        Arrays.sort(nums); //排序
        dfs(nums, 0, item, res);  //遞歸調用
        res.add(new ArrayList<Integer>());  //最后加上一個(gè)空集
        return res;
    }
    public static void dfs(int[] nums, int start, List<Integer> item, List<List<Integer>> res){
        for(int i = start; i < nums.length; i ++){
            item.add(nums[i]);
            //item是以整數為元素的動(dòng)態(tài)數組,而res是以數組為元素的數組,在這一步,當item增加完元素后,item所有元素構成一個(gè)完整的子串,再由res納入
            res.add(new ArrayList<Integer>(item));
            dfs(nums, i + 1, item, res);
            item.remove(item.size() - 1);
        }
    }
}
210.以下結構中,哪個(gè)具有同步功能()
A. HashMap
B. ConcurrentHashMap
C. WeakHashMap
D. TreeMap
答案:B
分析:
A,C,D都線(xiàn)程不安全,B線(xiàn)程安全,具有同步功能
211.以下結構中,插入性能最高的是()
A. ArrayList
B. Linkedlist
C. tor
D. Collection
答案:B
分析:
數組插入、刪除效率差,排除A
tor不是java里面的數據結構,是一種網(wǎng)絡(luò )路由技術(shù);因此排除C
Collection 是集合的接口,不是某種數據結構;因此排除D
212.以下結構中,哪個(gè)最適合當作stack使用()
A. LinkedHashMap
B. LinkedHashSet
C. LinkedList
LinkedList
分析:
Stack是先進(jìn)后出的線(xiàn)性結構;所以鏈表比較合適;不需要散列表的數據結構
213.Map的實(shí)現類(lèi)中,哪些是有序的,哪些是無(wú)序的,有序的是如何保證其有序性,你覺(jué)得哪個(gè)有序性性能更高,你有沒(méi)有更好或者更高效的實(shí)現方式?

答:1. Map的實(shí)現類(lèi)有HashMap,LinkedHashMap,TreeMap

2. HashMap是有無(wú)序的,LinkedHashMap和TreeMap都是有序的(LinkedHashMap記錄了添加數據的順序;TreeMap默認是自然升序)

3. LinkedHashMap底層存儲結構是哈希表+鏈表,鏈表記錄了添加數據的順序

4. TreeMap底層存儲結構是二叉樹(shù),二叉樹(shù)的中序遍歷保證了數據的有序性

5. LinkedHashMap有序性能比較高,因為底層數據存儲結構采用的哈希表

214.下面的代碼在絕大部分時(shí)間內都運行得很正常,請問(wèn)什么情況下會(huì )出現問(wèn)題?根源在哪里?
package com.bjsxt;
import java.util.LinkedList;
public class Stack {
LinkedList list = new LinkedList();
public synchronized void push(Object x) {
synchronized (list) {
list.addLast(x);
notify();
}
}
public  synchronized Object pop() throws  Exception{
synchronized(list){
if(list.size()<=0){
wait();
}
return list.removeLast( );
}
}
}

答:將if( list.size() <= 0 )改成:while( list.size() <= 0 )

215.TreeMap和TreeSet在排序時(shí)如何比較元素?Collections工具類(lèi)中的sort()方法如何比較元素?

答:TreeSet要求存放的對象所屬的類(lèi)必須實(shí)現Comparable接口,該接口提供了比較元素的compareTo()方法,當插入元素時(shí)會(huì ) 回調該方法比較元素的大小。TreeMap要求存放的鍵值對映射的鍵必須實(shí)現Comparable接口從而根據鍵對元素進(jìn)行排序。Collections 工具類(lèi)的sort方法有兩種重載的形式,第一種要求傳入的待排序容器中存放的對象比較實(shí)現Comparable接口以實(shí)現元素的比較;第二種不強制性的要求容器中的元素必須可比較,但是要求傳入第二個(gè)參數,參數是Comparator接口的子類(lèi)型(需要重寫(xiě)compare方法實(shí)現元素的比較),相當于一個(gè)臨時(shí)定義的排序規則,其實(shí)就是是通過(guò)接口注入比較元素大小的算法,也是對回調模式的應用。

216.List里面如何剔除相同的對象?請簡(jiǎn)單用代碼實(shí)現一種方法
public class Test {
public static void main(String[] args) {
  List<String> li1 = new ArrayList<String>();
  li1.add("8");
  li1.add("8");
  li1.add("9");
  li1.add("9");
  li1.add("0");
  System.out.println(li1);
  //方法:將List中數據取出來(lái)來(lái)存到Set中
  HashSet<String> set = new HashSet<String>();
  for(int i=0;i<li1.size();i++){
  set.add(li1.get(i));
  }
  System.out.println(set);
}
}
217.Java.util.Map的實(shí)現類(lèi)有

分析:Java中的java.util.Map的實(shí)現類(lèi)

1、HashMap

2、Hashtable

3、LinkedHashMap

4、TreeMap

218.下列敘述中正確的是()
A. 循環(huán)隊列有隊頭和隊尾兩個(gè)指針,因此,循環(huán)隊列是非線(xiàn)性結構
B. 在循環(huán)隊列中,只需要隊頭指針就能反映隊列中元素的動(dòng)態(tài)變化情況
C. 在循環(huán)隊列中,只需要隊尾指針就能反映隊列中元素的動(dòng)態(tài)變化情況
D. 在循環(huán)隊列中元素的個(gè)數是由隊頭指針和隊尾指針共同決定的
答案:D
分析:循環(huán)隊列中元素的個(gè)數是由隊首指針和隊尾指針共同決定的,元素的動(dòng)態(tài)變化也是通過(guò)隊首指針和隊尾指針來(lái)反映的,當隊首等于隊尾時(shí),隊列為空。
219.List、Set、Map 是否繼承自Collection 接口?

答:List、Set 的父接口是Collection,Map 不是其子接口,而是與Collection接口是平行關(guān)系,互不包含。

Map是鍵值對映射容器,與List和Set有明顯的區別,而Set存儲的零散的元素且不允許有重復元素(數學(xué)中的集合也是如此),List是線(xiàn)性結構的容器,適用于按數值索引訪(fǎng)問(wèn)元素的情形。?

220.說(shuō)出ArrayList、Vector、LinkedList 的存儲性能和特性?

答:ArrayList 和Vector都是使用數組方式存儲數據,此數組元素數大于實(shí)際存儲的數據以便增加和插入元素,它們都允許直接按序號索引元素,但是插入元素要涉及數組元素移動(dòng)等內存操作,所以索引數據快而插入數據慢,Vector由于使用了synchronized 方法(線(xiàn)程安全),通常性能上較ArrayList 差,而LinkedList 使用雙向鏈表實(shí)現存儲(將內存中零散的內存單元通過(guò)附加的引用關(guān)聯(lián)起來(lái),形成一個(gè)可以按序號索引的線(xiàn)性結構,這種鏈式存儲方式與數組的連續存儲方式相比,其實(shí)對內存的利用率更高),按序號索引數據需要進(jìn)行前向或后向遍歷,但是插入數據時(shí)只需要記錄本項的前后項即可,所以插入速度較快。Vector屬于遺留容器(早期的JDK中使用的容器,除此之外Hashtable、Dictionary、BitSet、Stack、Properties都是遺留容器),現在已經(jīng)不推薦使用,但是由于A(yíng)rrayList和LinkedListed都是非線(xiàn)程安全的,如果需要多個(gè)線(xiàn)程操作同一個(gè)容器,那么可以通過(guò)工具類(lèi)Collections中的synchronizedList方法將其轉換成線(xiàn)程安全的容器后再使用(這其實(shí)是裝潢模式最好的例子,將已有對象傳入另一個(gè)類(lèi)的構造器中創(chuàng )建新的對象來(lái)增加新功能)。

補充:遺留容器中的Properties類(lèi)和Stack類(lèi)在設計上有嚴重的問(wèn)題,Properties是一個(gè)鍵和值都是字符串的特殊的鍵值對映射,在設計上應該是關(guān)聯(lián)一個(gè)Hashtable并將其兩個(gè)泛型參數設置為String類(lèi)型,但是Java API中的Properties直接繼承了Hashtable,這很明顯是對繼承的濫用。這里復用代碼的方式應該是HAS-A關(guān)系而不是IS-A關(guān)系,另一方面容器都屬于工具類(lèi),繼承工具類(lèi)本身就是一個(gè)錯誤的做法,使用工具類(lèi)最好的方式是HAS-A關(guān)系(關(guān)聯(lián))或USE-A關(guān)系(依賴(lài)) 。同理,Stack類(lèi)繼承Vector也是不正確的。?

221.List、Map、Set 三個(gè)接口,存取元素時(shí),各有什么特點(diǎn)?

答:List以特定索引來(lái)存取元素,可有重復元素。

Set不能存放重復元素(用對象的equals()方法來(lái)區分元素是否重復) 。Map保存鍵值對(key-value pair)映射,映射關(guān)系可以是一對一或多對一。Set和Map容器都有基于哈希存儲和排序樹(shù)(紅黑樹(shù))的兩種實(shí)現版本,基于哈希存儲的版本理論存取時(shí)間復雜度為O(1),而基于排序樹(shù)版本的實(shí)現在插入或刪除元素時(shí)會(huì )按照元素或元素的鍵(key)構成排序樹(shù)從而達到排序和去重的效果。?

222.TreeMap和TreeSet在排序時(shí)如何比較元素?Collections工具類(lèi)中的sort()方法如何比較元素?

答:TreeSet要求存放的對象所屬的類(lèi)必須實(shí)現Comparable接口,該接口提供了比較元素的compareTo()方法,當插入元素時(shí)會(huì )回調該方法比較元素的大小。

TreeMap要求存放的鍵值對映射的鍵必須實(shí)現Comparable接口從而根據鍵對元素進(jìn)行排序。

Collections工具類(lèi)的sort方法有兩種重載的形式,第一種要求傳入的待排序容器中存放的對象比較實(shí)現Comparable接口以實(shí)現元素的比較;第二種不強制性的要求容器中的元素必須可比較,但是要求傳入第二個(gè)參數,參數是Comparator接口的子類(lèi)型 (需要重寫(xiě)compare方法實(shí)現元素的比較),相當于一個(gè)臨時(shí)定義的排序規則,其實(shí)就是是通過(guò)接口注入比較元素大小的算法,也是對回調模式的應用。

例子1:

Student.java

package com.bjsxt;

public class Student implements Comparable<Student> {
    private String name;        // 姓名
    private int age;            // 年齡
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    @Override
    public String toString() {
        return "Student [name=" + name + ", age=" + age + "]";
    }
    @Override
    public int compareTo(Student o) {
        return this.age - o.age; // 比較年齡(年齡的升序)
    }
  }

Test01.java

package com.bjsxt;
import java.util.Set;
import java.util.TreeSet;

class Test01 {
  public static void main(String[] args) {
        Set<Student> set = new TreeSet<>();     // Java 7的鉆石語(yǔ)法(構造器后面的尖括號中不需要寫(xiě)類(lèi)型)
        set.add(new Student("Hao LUO", 33));
        set.add(new Student("XJ WANG", 32));
        set.add(new Student("Bruce LEE", 60));
        set.add(new Student("Bob YANG", 22));
          for(Student stu : set) {
            System.out.println(stu);
        }
//      輸出結果:
//      Student [name=Bob YANG, age=22]
//      Student [name=XJ WANG, age=32]
//      Student [name=Hao LUO, age=33]
//      Student [name=Bruce LEE, age=60]
    }
}

例子2:

Student.java

package com.bjsxt;

public class Student {
    private String name;    // 姓名
    private int age;        // 年齡
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    /**
     * 獲取學(xué)生姓名
     */
    public String getName() {
        return name;
    }
    /**
     * 獲取學(xué)生年齡
     */
    public int getAge() {
        return age;
    }
    @Override
    public String toString() {
        return "Student [name=" + name + ", age=" + age + "]";
    }
  }

Test02.java

package com.bjsxt;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

  class Test02 {
   public static void main(String[] args) {
        List<Student> list = new ArrayList<>();     // Java 7的鉆石語(yǔ)法(構造器后面的尖括號中不需要寫(xiě)類(lèi)型)
        list.add(new Student("Hao LUO", 33));
        list.add(new Student("XJ WANG", 32));
        list.add(new Student("Bruce LEE", 60));
        list.add(new Student("Bob YANG", 22));

        // 通過(guò)sort方法的第二個(gè)參數傳入一個(gè)Comparator接口對象
        // 相當于是傳入一個(gè)比較對象大小的算法到sort方法中
        // 由于Java中沒(méi)有函數指針、仿函數、委托這樣的概念
        // 因此要將一個(gè)算法傳入一個(gè)方法中唯一的選擇就是通過(guò)接口回調
        Collections.sort(list, new Comparator<Student> () {
         @Override
            public int compare(Student o1, Student o2) {
                return o1.getName().compareTo(o2.getName());    // 比較學(xué)生姓名
            }
        });

        for(Student stu : list) {
            System.out.println(stu);
        }
//      輸出結果:
//      Student [name=Bob YANG, age=22]
//      Student [name=Bruce LEE, age=60]
//      Student [name=Hao LUO, age=33]
//      Student [name=XJ WANG, age=32]
    }
}

多線(xiàn)程:

223.下面程序的運行結果()(選擇一項)
public static void main(String[] args) {
Thread t=new Thread(){
public void run(){
pong();
}
};
t.run();
System.out.println("ping");
}
static void pong(){
System.out.println("pong");
}
A. pingpong
B. pongping
C. pingpong和pongping都有可能
D. 都不輸出
答案:B
分析:?jiǎn)?dòng)線(xiàn)程需要調用start()方法,而t.run()方法,則是使用對象名.分析:?jiǎn)?dòng)線(xiàn)程需要調用start()方法,而t.run()方法,則是使用對象名.
224.下列哪個(gè)方法可用于創(chuàng )建一個(gè)可運行的類(lèi)()
A. public class X implements Runnable{public void run() {……}}
B. public class X extends Thread{public void run() {……}}
C. public class X extends Thread{public int run() {……}}
D. public class X implements Runnable{protected void run() {……}}
答案:AB
分析: 繼承Thread和實(shí)現Runable接口
225.說(shuō)明類(lèi)java.lang.ThreadLocal的作用和原理。列舉在哪些程序中見(jiàn)過(guò)ThreadLocal的使用?

作用:

要編寫(xiě)一個(gè)多線(xiàn)程安全(Thread-safe)的程序是困難的,為了讓線(xiàn)程共享資源,必須小心地對共享資源進(jìn)行同步,同步帶來(lái)一定的效能延遲,而另一方面,在處理同步的時(shí)候,又要注意對象的鎖定與釋放,避免產(chǎn)生死結,種種因素都使得編寫(xiě)多線(xiàn)程程序變得困難。

嘗試從另一個(gè)角度來(lái)思考多線(xiàn)程共享資源的問(wèn)題,既然共享資源這么困難,那么就干脆不要共享,何不為每個(gè)線(xiàn)程創(chuàng )造一個(gè)資源的復本。將每一個(gè)線(xiàn)程存取數據的行為加以隔離,實(shí)現的方法就是給予每個(gè)線(xiàn)程一個(gè)特定空間來(lái)保管該線(xiàn)程所獨享的資源。

比如:在Hibernate中的Session就有使用。

ThreadLocal的原理

ThreadLocal是如何做到為每一個(gè)線(xiàn)程維護變量的副本的呢?其實(shí)實(shí)現的思路很簡(jiǎn)單,在ThreadLocal類(lèi)中有一個(gè)Map,用于存儲每一個(gè)線(xiàn)程的變量的副本。

226.說(shuō)說(shuō)樂(lè )觀(guān)鎖與悲觀(guān)鎖

答:悲觀(guān)鎖(Pessimistic Lock), 顧名思義,就是很悲觀(guān),每次去拿數據的時(shí)候都認為別人會(huì )修改,所以每次在拿數據的時(shí)候都會(huì )上鎖,這樣別人想拿這個(gè)數據就會(huì )block直到它拿到鎖。傳統的關(guān)系型數據庫里邊就用到了很多這種鎖機制,比如行鎖,表鎖等,讀鎖,寫(xiě)鎖等,都是在做操作之前先上鎖。

樂(lè )觀(guān)鎖(Optimistic Lock), 顧名思義,就是很樂(lè )觀(guān),每次去拿數據的時(shí)候都認為別人不會(huì )修改,所以不會(huì )上鎖,但是在更新的時(shí)候會(huì )判斷一下在此期間別人有沒(méi)有去更新這個(gè)數據,可以使用版本號等機制。樂(lè )觀(guān)鎖適用于多讀的應用類(lèi)型,這樣可以提高吞吐量,像數據庫如果提供類(lèi)似于write_condition機制的其實(shí)都是提供的樂(lè )觀(guān)鎖。

兩種鎖各有優(yōu)缺點(diǎn),不可認為一種好于另一種,像樂(lè )觀(guān)鎖適用于寫(xiě)比較少的情況下,即沖突真的很少發(fā)生的時(shí)候,這樣可以省去了鎖的開(kāi)銷(xiāo),加大了系統的整個(gè)吞吐量。但如果經(jīng)常產(chǎn)生沖突,上層應用會(huì )不斷的進(jìn)行retry,這樣反倒是降低了性能,所以這種情況下用悲觀(guān)鎖就比較合適。

227.在Java中怎么實(shí)現多線(xiàn)程?描述線(xiàn)程狀態(tài)的變化過(guò)程。

答:當多個(gè)線(xiàn)程訪(fǎng)問(wèn)同一個(gè)數據時(shí),容易出現線(xiàn)程安全問(wèn)題,需要某種方式來(lái)確保資源在某一時(shí)刻只被一個(gè)線(xiàn)程使用。需要讓線(xiàn)程同步,保證數據安全線(xiàn)程同步的實(shí)現方案: 同步代碼塊和同步方法,均需要使用synchronized關(guān)鍵字

同步代碼塊:public void makeWithdrawal(int amt) {

synchronized (acct) { }

}

同步方法:public synchronized void makeWithdrawal(int amt) { }

線(xiàn)程同步的好處:解決了線(xiàn)程安全問(wèn)題

線(xiàn)程同步的缺點(diǎn):性能下降,可能會(huì )帶來(lái)死鎖

228.請寫(xiě)出多線(xiàn)程代碼使用Thread或者Runnable,并說(shuō)出兩種的區別。

方式1:繼承Java.lang.Thread類(lèi),并覆蓋run() 方法。優(yōu)勢:編寫(xiě)簡(jiǎn)單;劣勢:無(wú)法繼承其它父類(lèi)

public class ThreadDemo1 {
public static void main(String args[]) {
MyThread1 t = new MyThread1();
t.start();
while (true) {
System.out.println("兔子領(lǐng)先了,別驕傲");
}
}
}
class MyThread1 extends Thread {
public void run() {
while (true) {
System.out.println("烏龜領(lǐng)先了,加油");
}
}
}

方式2:實(shí)現Java.lang.Runnable接口,并實(shí)現run()方法。優(yōu)勢:可繼承其它類(lèi),多線(xiàn)程可共享同一個(gè)Thread對象;劣勢:編程方式稍微復雜,如需訪(fǎng)問(wèn)當前線(xiàn)程,需調用Thread.currentThread()方法

public class ThreadDemo2 {
public static void main(String args[]) {
MyThread2 mt = new MyThread2();
Thread t = new Thread(mt);
t.start();
while (true) {
System.out.println("兔子領(lǐng)先了,加油");
}
}
}
class MyThread2 implements Runnable {
public void run() {
while (true) {
System.out.println("烏龜超過(guò)了,再接再厲");
}
}
}
229.在多線(xiàn)程編程里,wait方法的調用方式是怎樣的?

答:wait方法是線(xiàn)程通信的方法之一,必須用在 synchronized方法或者synchronized代碼塊中,否則會(huì )拋出異常,這就涉及到一個(gè)“鎖”的概念,而wait方法必須使用上鎖的對象來(lái)調用,從而持有該對象的鎖進(jìn)入線(xiàn)程等待狀態(tài),直到使用該上鎖的對象調用notify或者notifyAll方法來(lái)喚醒之前進(jìn)入等待的線(xiàn)程,以釋放持有的鎖。

230.Java線(xiàn)程的幾種狀態(tài)

答:線(xiàn)程是一個(gè)動(dòng)態(tài)執行的過(guò)程,它有一個(gè)從產(chǎn)生到死亡的過(guò)程,共五種狀態(tài):

新建(new Thread)

當創(chuàng )建Thread類(lèi)的一個(gè)實(shí)例(對象)時(shí),此線(xiàn)程進(jìn)入新建狀態(tài)(未被啟動(dòng))

例如:Thread t1=new Thread();

就緒(runnable)

線(xiàn)程已經(jīng)被啟動(dòng),正在等待被分配給CPU時(shí)間片,也就是說(shuō)此時(shí)線(xiàn)程正在就緒隊列中排隊等候得到CPU資源。例如:t1.start();

運行(running)

線(xiàn)程獲得CPU資源正在執行任務(wù)(run()方法),此時(shí)除非此線(xiàn)程自動(dòng)放棄CPU資源或者有優(yōu)先級更高的線(xiàn)程進(jìn)入,線(xiàn)程將一直運行到結束。

死亡(dead)

當線(xiàn)程執行完畢或被其它線(xiàn)程殺死,線(xiàn)程就進(jìn)入死亡狀態(tài),這時(shí)線(xiàn)程不可能再進(jìn)入就緒狀態(tài)等待執行。

自然終止:正常運行run()方法后終止

異常終止:調用stop()方法讓一個(gè)線(xiàn)程終止運行

堵塞(blocked)

由于某種原因導致正在運行的線(xiàn)程讓出CPU并暫停自己的執行,即進(jìn)入堵塞狀態(tài)。

正在睡眠:用sleep(long t) 方法可使線(xiàn)程進(jìn)入睡眠方式。一個(gè)睡眠著(zhù)的線(xiàn)程在指定的時(shí)間過(guò)去可進(jìn)入就緒狀態(tài)。

正在等待:調用wait()方法。(調用motify()方法回到就緒狀態(tài))

被另一個(gè)線(xiàn)程所阻塞:調用suspend()方法。(調用resume()方法恢復)

231.在Java多線(xiàn)程中,請用下面哪種方式不會(huì )使線(xiàn)程進(jìn)入阻塞狀態(tài)()
A. sleep()
B. Suspend()
C. wait()
D. yield()
答案:D
分析:yield會(huì )是線(xiàn)程進(jìn)入就緒狀態(tài)
232.volatile關(guān)鍵字是否能保證線(xiàn)程安全?

答:不能。雖然volatile提供了同步的機制,但是知識一種弱的同步機制,如需要強線(xiàn)程安全,還需要使用synchronized。

Java語(yǔ)言提供了一種稍弱的同步機制,即volatile變量,用來(lái)確保將變量的更新操作通知到其他線(xiàn)程。當把變量聲明為volatile類(lèi)型后,編譯器與運行時(shí)都會(huì )注意到這個(gè)變量是共享的,因此不會(huì )將該變量上的操作與其他內存操作一起重排序。volatile變量不會(huì )被緩存在寄存器或者對其他處理器不可見(jiàn)的地方,因此在讀取volatile類(lèi)型的變量時(shí)總會(huì )返回最新寫(xiě)入的值。

一、volatile的內存語(yǔ)義是:

當寫(xiě)一個(gè)volatile變量時(shí),JMM會(huì )把該線(xiàn)程對應的本地內存中的共享變量值立即刷新到主內存中。

當讀一個(gè)volatile變量時(shí),JMM會(huì )把該線(xiàn)程對應的本地內存設置為無(wú)效,直接從主內存中讀取共享變量。

二、volatile底層的實(shí)現機制

如果把加入volatile關(guān)鍵字的代碼和未加入volatile關(guān)鍵字的代碼都生成匯編代碼,會(huì )發(fā)現加入volatile關(guān)鍵字的代碼會(huì )多出一個(gè)lock前綴指令。

1 、重排序時(shí)不能把后面的指令重排序到內存屏障之前的位置

2、使得本CPU的Cache寫(xiě)入內存

3、寫(xiě)入動(dòng)作也會(huì )引起別的CPU或者別的內核無(wú)效化其Cache,相當于讓新寫(xiě)入的值對別的線(xiàn)程可見(jiàn)。

233.請寫(xiě)出常用的Java多線(xiàn)程啟動(dòng)方式,Executors線(xiàn)程池有幾種常用類(lèi)型?

(1) 繼承Thread類(lèi)

public class java_thread extends Thread{
    public static void main(String args[]) {
        new java_thread().run();
        System.out.println("main thread run ");
    }
    public synchronized  void run() {
        System.out.println("sub thread run ");
    }
}

(2) 實(shí)現Runnable接口

public class java_thread implements Runnable{
    public static void main(String args[]) {
        new Thread(new java_thread()).start();
        System.out.println("main thread run ");
    }
    public void run() {
        System.out.println("sub thread run ");
    }
}

在Executor框架下,利用Executors的靜態(tài)方法可以創(chuàng )建三種類(lèi)型的常用線(xiàn)程池:

1)FixedThreadPool這個(gè)線(xiàn)程池可以創(chuàng )建固定線(xiàn)程數的線(xiàn)程池。

2)SingleThreadExecutor是使用單個(gè)worker線(xiàn)程的Executor。

3)CachedThreadPool是一個(gè)”無(wú)限“容量的線(xiàn)程池,它會(huì )根據需要創(chuàng )建新線(xiàn)程。

234.關(guān)于sleep()和wait(),以下描述錯誤的一項是()
A. sleep是線(xiàn)程類(lèi)(Thread)的方法,wait是Object類(lèi)的方法
B. Sleep不釋放對象鎖,wait放棄對象鎖
C. Sleep暫停線(xiàn)程、但監控狀態(tài)任然保持,結束后會(huì )自動(dòng)恢復
D. Wait后進(jìn)入等待鎖定池,只針對此對象發(fā)出notify方法后獲取對象鎖進(jìn)入運行狀態(tài)。
答案:D
分析:針對此對象的notify方法后獲取對象鎖并進(jìn)入就緒狀態(tài),而不是運行狀態(tài)。另外針對此對象的notifyAll方法后也可能獲取對象鎖并進(jìn)入就緒狀態(tài),而不是運行狀態(tài)
235.進(jìn)程和線(xiàn)程的區別是什么?

進(jìn)程是具有一定獨立功能的程序關(guān)于某個(gè)數據集合上的一次運行活動(dòng),進(jìn)程是系統進(jìn)行資源分配和調度的一個(gè)獨立單位.

線(xiàn)程是進(jìn)程的一個(gè)實(shí)體,是CPU調度和分派的基本單位,它是比進(jìn)程更小的能獨立運行的基本單位.線(xiàn)程自己基本上不擁有系統資源,只擁有一點(diǎn)在運行中必不可少的資源(如程序計數器,一組寄存器和棧),但是它可與同屬一個(gè)進(jìn)程的其他的線(xiàn)程共享進(jìn)程所擁有的全部資源.

區別 進(jìn)程 線(xiàn)程
根本區別? 作為資源分配的單位? 調度和執行的單位
開(kāi)銷(xiāo)? 每個(gè)進(jìn)程都有獨立的代碼和數據空間(進(jìn)程上下文),進(jìn)程間的切換會(huì )有較大的開(kāi)銷(xiāo)。? 線(xiàn)程可以看成時(shí)輕量級的進(jìn)程,同一類(lèi)線(xiàn)程共享代碼和數據空間,每個(gè)線(xiàn)程有獨立的運行棧和程序計數器(PC),線(xiàn)程切換的開(kāi)銷(xiāo)小。?
所處環(huán)境? 系統在運行的時(shí)候會(huì )為每個(gè)進(jìn)程分配不同的內存區域? 除了CPU之外,不會(huì )為線(xiàn)程分配內存(線(xiàn)程所使用的資源是它所屬的進(jìn)程的資源),線(xiàn)程組只能共享資源?
分配內存? 系統在運行的時(shí)候會(huì )為每個(gè)進(jìn)程分配不同的內存區域? 除了CPU之外,不會(huì )為線(xiàn)程分配內存(線(xiàn)程所使用的資源是它所屬的進(jìn)程的資源),線(xiàn)程組只能共享資源?
包含關(guān)系? 沒(méi)有線(xiàn)程的進(jìn)程是可以被看作單線(xiàn)程的,如果一個(gè)進(jìn)程內擁有多個(gè)線(xiàn)程,則執行過(guò)程不是一條線(xiàn)的,而是多條線(xiàn)(線(xiàn)程)共同完成的。? 線(xiàn)程是進(jìn)程的一部分,所以線(xiàn)程有的時(shí)候被稱(chēng)為是輕權進(jìn)程或者輕量級進(jìn)程。?
236.以下鎖機機制中,不能保證線(xiàn)程安全的是()
A. Lock
B. Synchronized
C. Volatile
答案:C
237.創(chuàng )建n多個(gè)線(xiàn)程,如何保證這些線(xiàn)程同時(shí)啟動(dòng)?看清,是“同時(shí)”。

答:用一個(gè)for循環(huán)創(chuàng )建線(xiàn)程對象,同時(shí)調用wait()方法,讓所有線(xiàn)程等待;直到最后一個(gè)線(xiàn)程也準備就緒后,調用notifyAll(), 同時(shí)啟動(dòng)所有線(xiàn)程。

比如:給你n個(gè)賽車(chē),讓他們都在起跑線(xiàn)上就緒后,同時(shí)出發(fā),Java多線(xiàn)程如何寫(xiě)代碼?

思路是,來(lái)一輛賽車(chē)就加上一把鎖,并修改對應的操作數,如果沒(méi)有全部就緒就等待,并釋放鎖,直到最后一輛賽車(chē)到場(chǎng)后喚醒所有的賽車(chē)線(xiàn)程。代碼參考如下:

public class CarCompetion {
    // 參賽賽車(chē)的數量
    protected final int totalCarNum = 10;
    // 當前在起跑線(xiàn)的賽車(chē)數量
    protected int nowCarNum = 0;
}
public class Car implements Runnable{
    private int carNum;
    private CarCompetion competion = null;
    public Car(int carNum, CarCompetion competion) {
        this.carNum = carNum;
        this.competion = competion;
    }
    @Override
    public void run() {
        synchronized (competion) {
            competion.nowCarNum++;
            while (competion.nowCarNum < competion.totalCarNum) {
                try {
                    competion.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            competion.notifyAll();
        }
        startCar();
    }
    private void startCar() {
        System.out.println("Car num " + this.carNum + " start to run.");
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Car num " + this.carNum + " get to the finish line.");
    }
}
public static void main(String[] args) {
    CarCompetion carCompetion = new CarCompetion();
    final ExecutorService carPool =
        Executors.newFixedThreadPool(carCompetion.totalCarNum);
    for (int i = 0; i < carCompetion.totalCarNum; i++) {
        carPool.execute(new Car(i, carCompetion));

}
238.同步和異步有何異同,在什么情況下分別使用它們?

答:1.如果數據將在線(xiàn)程間共享。例如正在寫(xiě)的數據以后可能被另一個(gè)線(xiàn)程讀到,或者正在讀的數據可能已經(jīng)被另一個(gè)線(xiàn)程寫(xiě)過(guò)了,那么這些數據就是共享數據,必須進(jìn)行同步存取。

2.當應用程序在對象上調用了一個(gè)需要花費很長(cháng)時(shí)間來(lái)執行的方法,并且不希望讓程序等待方法的返回時(shí),就應該使用異步編程,在很多情況下采用異步途徑往往更有效率。

3.舉個(gè)例子: 打電話(huà)是同步 發(fā)消息是異步

239.Java線(xiàn)程中,sleep()和wait()區別

答:sleep是線(xiàn)程類(lèi)(Thread)的方法;作用是導致此線(xiàn)程暫停執行指定時(shí)間,給執行機會(huì )給其他線(xiàn)程,但是監控狀態(tài)依然保持,到時(shí)后會(huì )自動(dòng)恢復;調用sleep()不會(huì )釋放對象鎖。

wait是Object類(lèi)的方法;對此對象調用wait方法導致本線(xiàn)程放棄對象鎖,進(jìn)入等 待此對象的等待鎖定池。只有針對此對象發(fā)出notify方法(或notifyAll)后本線(xiàn)程才進(jìn)入對象鎖定池,準備獲得對象鎖進(jìn)行運行狀態(tài)。

240.下面所述步驟中,是創(chuàng )建進(jìn)程做必須的步驟是()
A. 由調度程序為進(jìn)程分配CPU
B. 建立一個(gè)進(jìn)程控制塊
C. 為進(jìn)程分配內存
D. 為進(jìn)程分配文件描述符
答案:BC
241.無(wú)鎖化編程有哪些常見(jiàn)方法?()
A. 針對計數器,可以使用原子加
B. 只有一個(gè)生產(chǎn)者和一個(gè)消費者,那么就可以做到免鎖訪(fǎng)問(wèn)環(huán)形緩沖區(Ring Buffer)
C. RCU(Read-Copy-Update),新舊副本切換機制,對于舊副本可以采用延遲釋放的做法
D. CAS(Compare-and-Swap),如無(wú)鎖棧,無(wú)鎖隊列等待
答案:D
分析:A 這方法雖然不太好,但是常見(jiàn)
B ProducerConsumerQueue就是這個(gè),到處都是
C linux kernel里面大量使用
D 本質(zhì)上其實(shí)就是樂(lè )觀(guān)鎖,操作起來(lái)很困難。。單生產(chǎn)者多消費者或者多生產(chǎn)者單消費者的情況下比較常見(jiàn),也不容易遇到ABA問(wèn)題。
242.sleep()和yield()有什么區別?

答:① sleep()方法給其他線(xiàn)程運行機會(huì )時(shí)不考慮線(xiàn)程的優(yōu)先級,因此會(huì )給低優(yōu)先級的線(xiàn)程以運行的機會(huì );yield()方法只會(huì )給相同優(yōu)先級或更高優(yōu)先級的線(xiàn)程以運行的機會(huì );

② 線(xiàn)程執行sleep()方法后轉入阻塞(blocked)狀態(tài),而執行yield()方法后轉入就緒(ready)狀態(tài);

③ sleep()方法聲明拋出InterruptedException,而yield()方法沒(méi)有聲明任何異常;

④ sleep()方法比yield()方法(跟操作系統相關(guān))具有更好的可移植性。?

243.當一個(gè)線(xiàn)程進(jìn)入一個(gè)對象的synchronized方法A之后,其它線(xiàn)程是否可進(jìn)入此對象的synchronized方法?

答:不能。其它線(xiàn)程只能訪(fǎng)問(wèn)該對象的非同步方法,同步方法則不能進(jìn)入。?只有等待當前線(xiàn)程執行完畢釋放鎖資源之后,其他線(xiàn)程才有可能進(jìn)行執行該同步方法!

延伸 對象鎖分為三種:共享資源、this、當前類(lèi)的字節碼文件對象

244.請說(shuō)出與線(xiàn)程同步相關(guān)的方法。

答:1. wait():使一個(gè)線(xiàn)程處于等待(阻塞)狀態(tài),并且釋放所持有的對象的鎖;

2. sleep():使一個(gè)正在運行的線(xiàn)程處于睡眠狀態(tài),是一個(gè)靜態(tài)方法,調用此方法要捕捉InterruptedException 異常;

3. notify():喚醒一個(gè)處于等待狀態(tài)的線(xiàn)程,當然在調用此方法的時(shí)候,并不能確切的喚醒某一個(gè)等待狀態(tài)的線(xiàn)程,而是由JVM確定喚醒哪個(gè)線(xiàn)程,而且與優(yōu)先級無(wú)關(guān);

4. notityAll():喚醒所有處入等待狀態(tài)的線(xiàn)程,注意并不是給所有喚醒線(xiàn)程一個(gè)對象的鎖,而是讓它們競爭;

5. JDK 1.5通過(guò)Lock接口提供了顯式(explicit)的鎖機制,增強了靈活性以及對線(xiàn)程的協(xié)調。Lock接口中定義了加鎖(lock())和解鎖(unlock())的方法,同時(shí)還提供了newCondition()方法來(lái)產(chǎn)生用于線(xiàn)程之間通信的Condition對象;

6. JDK 1.5還提供了信號量(semaphore)機制,信號量可以用來(lái)限制對某個(gè)共享資源進(jìn)行訪(fǎng)問(wèn)的線(xiàn)程的數量。在對資源進(jìn)行訪(fǎng)問(wèn)之前,線(xiàn)程必須得到信號量的許可(調用Semaphore對象的acquire()方法);在完成對資源的訪(fǎng)問(wèn)后,線(xiàn)程必須向信號量歸還許可(調用Semaphore對象的release()方法)。

下面的例子演示了100個(gè)線(xiàn)程同時(shí)向一個(gè)銀行賬戶(hù)中存入1元錢(qián),在沒(méi)有使用同步機制和使用同步機制情況下的執行情況。

銀行賬戶(hù)類(lèi):

package com.bjsxt;
/**
 * 銀行賬戶(hù)
 * @author sxt
 *
 */
public class Account {
    private double balance;     // 賬戶(hù)余額
    /**
     * 存款
     * @param money 存入金額
     */
    public void deposit(double money) {
        double newBalance = balance + money;
        try {
            Thread.sleep(10);   // 模擬此業(yè)務(wù)需要一段處理時(shí)間
        }
        catch(InterruptedException ex) {
            ex.printStackTrace();
        }
        balance = newBalance;
    }
    /**
     * 獲得賬戶(hù)余額
     */
    public double getBalance() {
        return balance;
    }
}

存錢(qián)線(xiàn)程類(lèi):

package com.bjsxt;
/**
 * 存錢(qián)線(xiàn)程
 * @author sxt李端陽(yáng)
 *
 */
public class AddMoneyThread implements Runnable {
    private Account account;    // 存入賬戶(hù)
    private double money;       // 存入金額

    public AddMoneyThread(Account account, double money) {
        this.account = account;
        this.money = money;
    }

    @Override
    public void run() {
        account.deposit(money);
    }
 }

測試類(lèi):

package com.bjsxt;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

 public class Test01 {
public static void main(String[] args) {
        Account account = new Account();
        ExecutorService service = Executors.newFixedThreadPool(100);
        for(int i = 1; i <= 100; i++) {
            service.execute(new AddMoneyThread(account, 1));
        }
        service.shutdown();
        while(!service.isTerminated()) {}
        System.out.println("賬戶(hù)余額: " + account.getBalance());
    }
}

在沒(méi)有同步的情況下,執行結果通常是顯示賬戶(hù)余額在10元以下,出現這種狀況的原因是,當一個(gè)線(xiàn)程A試圖存入1元的時(shí)候,另外一個(gè)線(xiàn)程B也能夠進(jìn)入存款的方法中,線(xiàn)程B讀取到的賬戶(hù)余額仍然是線(xiàn)程A存入1元錢(qián)之前的賬戶(hù)余額,因此也是在原來(lái)的余額0上面做了加1元的操作,同理線(xiàn)程C也會(huì )做類(lèi)似的事情,所以最后100個(gè)線(xiàn)程執行結束時(shí),本來(lái)期望賬戶(hù)余額為100元,但實(shí)際得到的通常在10元以下。解決這個(gè)問(wèn)題的辦法就是同步,當一個(gè)線(xiàn)程對銀行賬戶(hù)存錢(qián)時(shí),需要將此賬戶(hù)鎖定,待其操作完成后才允許其他的線(xiàn)程進(jìn)行操作,代碼有如下幾種調整方案:

1. 在銀行賬戶(hù)的存款(deposit)方法上同步(synchronized)關(guān)鍵字

package com.bjsxt;
/**
 * 銀行賬戶(hù)
 * @author SXT李端陽(yáng)
*/
public class Account {
    private double balance;     // 賬戶(hù)余額
    /**
     * 存款
     * @param money 存入金額
     */
    public synchronized void deposit(double money) {
        double newBalance = balance + money;
        try {
            Thread.sleep(10);   // 模擬此業(yè)務(wù)需要一段處理時(shí)間
        }
        catch(InterruptedException ex) {
            ex.printStackTrace();
        }
        balance = newBalance;
    }

    /**
     * 獲得賬戶(hù)余額
     */
    public double getBalance() {
        return balance;
    }
}

2. 在線(xiàn)程調用存款方法時(shí)對銀行賬戶(hù)進(jìn)行同步

package com.bjsxt;
/**
 * 存錢(qián)線(xiàn)程
 * @author SXT
 *
 */
public class AddMoneyThread implements Runnable {
    private Account account;    // 存入賬戶(hù)
    private double money;       // 存入金額

    public AddMoneyThread(Account account, double money) {
        this.account = account;
        this.money = money;
    }
    @Override
    public void run() {
        synchronized (account) {
            account.deposit(money);
        }
    }
}

3. 通過(guò)JDK 1.5顯示的鎖機制,為每個(gè)銀行賬戶(hù)創(chuàng )建一個(gè)鎖對象,在存款操作進(jìn)行加鎖和解鎖的操作

package com.bjsxt;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 銀行賬戶(hù)
 *
 * @author SXT李端陽(yáng)
 *
 */
public class Account {
    private Lock accountLock = new ReentrantLock();
    private double balance; // 賬戶(hù)余額
   /**
     * 存款
     *
     * @param money
     *            存入金額
     */
    public void deposit(double money) {
        accountLock.lock();
        try {
            double newBalance = balance + money;
            try {
                Thread.sleep(10); // 模擬此業(yè)務(wù)需要一段處理時(shí)間
            }
            catch (InterruptedException ex) {
                ex.printStackTrace();
            }
            balance = newBalance;
        }
        finally {
            accountLock.unlock();
        }
    }
    /**
     * 獲得賬戶(hù)余額
     */
    public double getBalance() {
        return balance;
    }
}

按照上述三種方式對代碼進(jìn)行修改后,重寫(xiě)執行測試代碼Test01,將看到最終的賬戶(hù)余額為100元。?

245.編寫(xiě)多線(xiàn)程程序有幾種實(shí)現方式?

答:Java 5以前實(shí)現多線(xiàn)程有兩種實(shí)現方法:一種是繼承Thread類(lèi);另一種是實(shí)現Runnable接口。兩種方式都要通過(guò)重寫(xiě)run()方法來(lái)定義線(xiàn)程的行為,推薦使用后者,因為Java中的繼承是單繼承,一個(gè)類(lèi)有一個(gè)父類(lèi),如果繼承了Thread類(lèi)就無(wú)法再繼承其他類(lèi)了,同時(shí)也可以實(shí)現資源共享,顯然使用Runnable接口更為靈活。

補充:Java 5以后創(chuàng )建線(xiàn)程還有第三種方式:實(shí)現Callable接口,該接口中的call方法可以在線(xiàn)程執行結束時(shí)產(chǎn)生一個(gè)返回值,代碼如下所示:

package com.bjsxt;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

  class MyTask implements Callable<Integer> {
    private int upperBounds;

    public MyTask(int upperBounds) {
        this.upperBounds = upperBounds;
    }

    @Override
    public Integer call() throws Exception {
        int sum = 0;
        for(int i = 1; i <= upperBounds; i++) {
            sum += i;
        }
        return sum;
    }

}

public class Test {
  public static void main(String[] args) throws Exception {
        List<Future<Integer>> list = new ArrayList<>();
        ExecutorService service = Executors.newFixedThreadPool(10);
        for(int i = 0; i < 10; i++) {
        list.add(service.submit(new MyTask((int) (Math.random() * 100))));
        }
        int sum = 0;
        for(Future<Integer> future : list) {
            while(!future.isDone()) ;
            sum += future.get();
        }
          System.out.println(sum);
    }
}
246.synchronized關(guān)鍵字的用法?

答:synchronized關(guān)鍵字可以將對象或者方法標記為同步,以實(shí)現對對象和方法的互斥訪(fǎng)問(wèn),可以用synchronized(對象) { … }定義同步代碼塊,或者在聲明方法時(shí)將synchronized作為方法的修飾符。在第60題的例子中已經(jīng)展示了synchronized關(guān)鍵字的用法。?

247.啟動(dòng)一個(gè)線(xiàn)程是用run()還是start()方法?

答:?jiǎn)?dòng)一個(gè)線(xiàn)程是調用start()方法,使線(xiàn)程所代表的虛擬處理機處于可運行狀態(tài),這意味著(zhù)它可以由JVM 調度并執行,這并不意味著(zhù)線(xiàn)程就會(huì )立即運行。run()方法是線(xiàn)程啟動(dòng)后要進(jìn)行回調(callback)的方法。?

API解釋如下:

248.什么是線(xiàn)程池(thread pool)?

答:在面向對象編程中,創(chuàng )建和銷(xiāo)毀對象是很費時(shí)間的,因為創(chuàng )建一個(gè)對象要獲取內存資源或者其它更多資源。在Java中更是如此,虛擬機將試圖跟蹤每一個(gè)對象,以便能夠在對象銷(xiāo)毀后進(jìn)行垃圾回收。所以提高服務(wù)程序效率的一個(gè)手段就是盡可能減少創(chuàng )建和銷(xiāo)毀對象的次數,特別是一些很耗資源的對象創(chuàng )建和銷(xiāo)毀,這就是"池化資源"技術(shù)產(chǎn)生的原因。線(xiàn)程池顧名思義就是事先創(chuàng )建若干個(gè)可執行的線(xiàn)程放入一個(gè)池(容器)中,需要的時(shí)候從池中獲取線(xiàn)程不用自行創(chuàng )建,使用完畢不需要銷(xiāo)毀線(xiàn)程而是放回池中,從而減少創(chuàng )建和銷(xiāo)毀線(xiàn)程對象的開(kāi)銷(xiāo)。

Java 5+中的Executor接口定義一個(gè)執行線(xiàn)程的工具。它的子類(lèi)型即線(xiàn)程池接口是ExecutorService。要配置一個(gè)線(xiàn)程池是比較復雜的,尤其是對于線(xiàn)程池的原理不是很清楚的情況下,因此在工具類(lèi)Executors面提供了一些靜態(tài)工廠(chǎng)方法,生成一些常用的線(xiàn)程池,如下所示:

newSingleThreadExecutor:創(chuàng )建一個(gè)單線(xiàn)程的線(xiàn)程池。這個(gè)線(xiàn)程池只有一個(gè)線(xiàn)程在工作,也就是相當于單線(xiàn)程串行執行所有任務(wù)。如果這個(gè)唯一的線(xiàn)程因為異常結束,那么會(huì )有一個(gè)新的線(xiàn)程來(lái)替代它。此線(xiàn)程池保證所有任務(wù)的執行順序按照任務(wù)的提交順序執行。

newFixedThreadPool:創(chuàng )建固定大小的線(xiàn)程池。每次提交一個(gè)任務(wù)就創(chuàng )建一個(gè)線(xiàn)程,直到線(xiàn)程達到線(xiàn)程池的最大大小。線(xiàn)程池的大小一旦達到最大值就會(huì )保持不變,如果某個(gè)線(xiàn)程因為執行異常而結束,那么線(xiàn)程池會(huì )補充一個(gè)新線(xiàn)程。

newCachedThreadPool:創(chuàng )建一個(gè)可緩存的線(xiàn)程池。如果線(xiàn)程池的大小超過(guò)了處理任務(wù)所需要的線(xiàn)程,那么就會(huì )回收部分空閑(60秒不執行任務(wù))的線(xiàn)程,當任務(wù)數增加時(shí),此線(xiàn)程池又可以智能的添加新線(xiàn)程來(lái)處理任務(wù)。此線(xiàn)程池不會(huì )對線(xiàn)程池大小做限制,線(xiàn)程池大小完全依賴(lài)于操作系統(或者說(shuō)JVM)能夠創(chuàng )建的最大線(xiàn)程大小。

newScheduledThreadPool:創(chuàng )建一個(gè)大小無(wú)限的線(xiàn)程池。此線(xiàn)程池支持定時(shí)以及周期性執行任務(wù)的需求。

newSingleThreadExecutor:創(chuàng )建一個(gè)單線(xiàn)程的線(xiàn)程池。此線(xiàn)程池支持定時(shí)以及周期性執行任務(wù)的需求。

有通過(guò)Executors工具類(lèi)創(chuàng )建線(xiàn)程池并使用線(xiàn)程池執行線(xiàn)程的代碼。如果希望在服務(wù)器上使用線(xiàn)程池,強烈建議使用newFixedThreadPool方法來(lái)創(chuàng )建線(xiàn)程池,這樣能獲得更好的性能。?

249.線(xiàn)程的基本狀態(tài)以及狀態(tài)之間的關(guān)系?

除去起始(new)狀態(tài)和結束(finished)狀態(tài),線(xiàn)程有三種狀態(tài),分別是:就緒(ready)、運行(running)和阻塞(blocked)。其中就緒狀態(tài)代表線(xiàn)程具備了運行的所有條件,只等待CPU調度(萬(wàn)事俱備,只欠東風(fēng));處于運行狀態(tài)的線(xiàn)程可能因為CPU調度(時(shí)間片用完了)的原因回到就緒狀態(tài),也有可能因為調用了線(xiàn)程的yield方法回到就緒狀態(tài),此時(shí)線(xiàn)程不會(huì )釋放它占有的資源的鎖,坐等CPU以繼續執行;運行狀態(tài)的線(xiàn)程可能因為I/O中斷、線(xiàn)程休眠、調用了對象的wait方法而進(jìn)入阻塞狀態(tài)(有的地方也稱(chēng)之為等待狀態(tài));而進(jìn)入阻塞狀態(tài)的線(xiàn)程會(huì )因為休眠結束、調用了對象的notify方法或notifyAll方法或其他線(xiàn)程執行結束而進(jìn)入就緒狀態(tài)。注意:調用wait方法會(huì )讓線(xiàn)程進(jìn)入等待池中等待被喚醒,notify方法或notifyAll方法會(huì )讓等待鎖中的線(xiàn)程從等待池進(jìn)入等鎖池,在沒(méi)有得到對象的鎖之前,線(xiàn)程仍然無(wú)法獲得CPU的調度和執行。

250.簡(jiǎn)述synchronized 和java.util.concurrent.locks.Lock的異同?

答:Lock是Java 5以后引入的新的API,和關(guān)鍵字synchronized相比主要相同點(diǎn):Lock 能完成synchronized所實(shí)現的所有功能;主要不同點(diǎn):Lock 有比synchronized 更精確的線(xiàn)程語(yǔ)義和更好的性能。synchronized 會(huì )自動(dòng)釋放鎖,而Lock 一定要求程序員手工釋放,并且必須在finally 塊中釋放(這是釋放外部資源的最好的地方)。?

251.創(chuàng )建線(xiàn)程的兩種方式分別是什么,優(yōu)缺點(diǎn)是什么?

方式1:繼承Java.lang.Thread類(lèi),并覆蓋run() 方法。

優(yōu)勢:編寫(xiě)簡(jiǎn)單;

劣勢:?jiǎn)卫^承的限制----無(wú)法繼承其它父類(lèi),同時(shí)不能實(shí)現資源共享。

package com.bjsxt;

public class ThreadDemo1 {
public static void main(String args[]) {
MyThread1 t = new MyThread1();
t.start();
while (true) {
System.out.println("兔子領(lǐng)先了,別驕傲");
}
}
}
class MyThread1 extends Thread {
public void run() {
while (true) {
System.out.println("烏龜領(lǐng)先了,加油");
}
}
}

方式2:實(shí)現Java.lang.Runnable接口,并實(shí)現run()方法。

優(yōu)勢:可繼承其它類(lèi),多線(xiàn)程可共享同一個(gè)Thread對象;

劣勢:編程方式稍微復雜,如需訪(fǎng)問(wèn)當前線(xiàn)程,需調用Thread.currentThread()方法

package com.bjsxt;

public class ThreadDemo2 {
public static void main(String args[]) {
MyThread2 mt = new MyThread2();
Thread t = new Thread(mt);
t.start();
while (true) {
System.out.println("兔子領(lǐng)先了,加油");
}
}
}
class MyThread2 implements Runnable {
public void run() {
while (true) {
System.out.println("烏龜超過(guò)了,再接再厲");
}
}
}
252.Java創(chuàng )建線(xiàn)程后,調用start()方法和run()的區別

兩種方法的區別

1) start方法:

用start方法來(lái)啟動(dòng)線(xiàn)程,真正實(shí)現了多線(xiàn)程運行,這時(shí)無(wú)需等待run方法體代碼執行完畢而直接繼續執行下面的代碼。通過(guò)調用Thread類(lèi)的start()方法來(lái)啟動(dòng)一個(gè)線(xiàn)程,這時(shí)此線(xiàn)程處于就緒(可運行)狀態(tài),并沒(méi)有運行,一旦得到cpu時(shí)間片,就開(kāi)始執行run()方法,這里方法run()稱(chēng)為線(xiàn)程體,它包含了要執行的這個(gè)線(xiàn)程的內容,Run方法運行結束,此線(xiàn)程隨即終止。

2) run():

run()方法只是類(lèi)的一個(gè)普通方法而已,如果直接調用run方法,程序中依然只有主線(xiàn)程這一個(gè)線(xiàn)程,其程序執行路徑還是只有一條,還是要順序執行,還是要等待,run方法體執行完畢后才可繼續執行下面的代碼,這樣就沒(méi)有達到寫(xiě)線(xiàn)程的目的。

總結:調用start方法方可啟動(dòng)線(xiàn)程,而run方法只是thread的一個(gè)普通方法調用,還是在主線(xiàn)程里執行。這兩個(gè)方法應該都比較熟悉,把需要并行處理的代碼放在run()方法中,start()方法啟動(dòng)線(xiàn)程將自動(dòng)調用 run()方法,這是由jvm的內存機制規定的。并且run()方法必須是public訪(fǎng)問(wèn)權限,返回值類(lèi)型為void。

兩種方式的比較 :

實(shí)際中往往采用實(shí)現Runable接口,一方面因為java只支持單繼承,繼承了Thread類(lèi)就無(wú)法再繼續繼承其它類(lèi),而且Runable接口只有一個(gè)run方法;另一方面通過(guò)結果可以看出實(shí)現Runable接口才是真正的多線(xiàn)程。

253.線(xiàn)程的生命周期

線(xiàn)程是一個(gè)動(dòng)態(tài)執行的過(guò)程,它也有一個(gè)從產(chǎn)生到死亡的過(guò)程。

生命周期的五種狀態(tài)

新建(new Thread)

當創(chuàng )建Thread類(lèi)的一個(gè)實(shí)例(對象)時(shí),此線(xiàn)程進(jìn)入新建狀態(tài)(未被啟動(dòng))

例如:Thread t1=new Thread();

就緒(runnable)

線(xiàn)程已經(jīng)被啟動(dòng),正在等待被分配給CPU時(shí)間片,也就是說(shuō)此時(shí)線(xiàn)程正在就緒隊列中排隊等候得到CPU資源。例如:t1.start();

運行(running)

線(xiàn)程獲得CPU資源正在執行任務(wù)(run()方法),此時(shí)除非此線(xiàn)程自動(dòng)放棄CPU資源或者有優(yōu)先級更高的線(xiàn)程進(jìn)入,線(xiàn)程將一直運行到結束。

死亡(dead)

當線(xiàn)程執行完畢或被其它線(xiàn)程殺死,線(xiàn)程就進(jìn)入死亡狀態(tài),這時(shí)線(xiàn)程不可能再進(jìn)入就緒狀態(tài)等待執行。

自然終止:正常運行run()方法后終止

異常終止:調用stop()方法讓一個(gè)線(xiàn)程終止運行

堵塞(blocked)

由于某種原因導致正在運行的線(xiàn)程讓出CPU并暫停自己的執行,即進(jìn)入堵塞狀態(tài)。

正在睡眠:用sleep(long t) 方法可使線(xiàn)程進(jìn)入睡眠方式。一個(gè)睡眠著(zhù)的線(xiàn)程在指定的時(shí)間過(guò)去可進(jìn)入就緒狀態(tài)。

正在等待:調用wait()方法。(調用motify()方法回到就緒狀態(tài))

被另一個(gè)線(xiàn)程所阻塞:調用suspend()方法。(調用resume()方法恢復)

254.如何實(shí)現線(xiàn)程同步?

當多個(gè)線(xiàn)程訪(fǎng)問(wèn)同一個(gè)數據時(shí),容易出現線(xiàn)程安全問(wèn)題,需要某種方式來(lái)確保資源在某一時(shí)刻只被一個(gè)線(xiàn)程使用。需要讓線(xiàn)程同步,保證數據安全

線(xiàn)程同步的實(shí)現方案:

1)同步代碼塊,使用synchronized關(guān)鍵字

同步代碼塊:

synchronized (同步鎖) {
授課代碼;
}

同步方法:

public synchronized void makeWithdrawal(int amt) { }

線(xiàn)程同步的好處:解決了線(xiàn)程安全問(wèn)題

線(xiàn)程同步的缺點(diǎn):性能下降,可能會(huì )帶來(lái)死鎖

注意: 同步代碼塊,所使用的同步鎖可以是三種,

1、this 2、 共享資源 3、 字節碼文件對象

同步方法所使用的同步鎖,默認的是this

255.說(shuō)說(shuō)關(guān)于同步鎖的更多細節

答:Java中每個(gè)對象都有一個(gè)內置鎖。

當程序運行到非靜態(tài)的synchronized同步方法上時(shí),自動(dòng)獲得與正在執行代碼類(lèi)的當前實(shí)例(this實(shí)例)有關(guān)的鎖。獲得一個(gè)對象的鎖也稱(chēng)為獲取鎖、鎖定對象、在對象上鎖定或在對象上同步。

當程序運行到synchronized同步方法或代碼塊時(shí)才該對象鎖才起作用。

一個(gè)對象只有一個(gè)鎖。所以,如果一個(gè)線(xiàn)程獲得該鎖,就沒(méi)有其他線(xiàn)程可以獲得鎖,直到第一個(gè)線(xiàn)程釋放(或返回)鎖。這也意味著(zhù)任何其他線(xiàn)程都不能進(jìn)入該對象上的synchronized方法或代碼塊,直到該鎖被釋放。

釋放鎖是指持鎖線(xiàn)程退出了synchronized同步方法或代碼塊。

關(guān)于鎖和同步,有一下幾個(gè)要點(diǎn):

1)只能同步方法,而不能同步變量和類(lèi);

2)每個(gè)對象只有一個(gè)鎖;當提到同步時(shí),應該清楚在什么上同步?也就是說(shuō),在哪個(gè)對象上同步?

3)不必同步類(lèi)中所有的方法,類(lèi)可以同時(shí)擁有同步和非同步方法。

4)如果兩個(gè)線(xiàn)程要執行一個(gè)類(lèi)中的synchronized方法,并且兩個(gè)線(xiàn)程使用相同的實(shí)例來(lái)調用方法,那么一次只能有一個(gè)線(xiàn)程能夠執行方法,另一個(gè)需要等待,直到鎖被釋放。也就是說(shuō):如果一個(gè)線(xiàn)程在對象上獲得一個(gè)鎖,就沒(méi)有任何其他線(xiàn)程可以進(jìn)入(該對象的)類(lèi)中的任何一個(gè)同步方法。

5)如果線(xiàn)程擁有同步和非同步方法,則非同步方法可以被多個(gè)線(xiàn)程自由訪(fǎng)問(wèn)而不受鎖的限制。

6)線(xiàn)程睡眠時(shí),它所持的任何鎖都不會(huì )釋放。

7)線(xiàn)程可以獲得多個(gè)鎖。比如,在一個(gè)對象的同步方法里面調用另外一個(gè)對象的同步方法,則獲取了兩個(gè)對象的同步鎖。

8)同步損害并發(fā)性,應該盡可能縮小同步范圍。同步不但可以同步整個(gè)方法,還可以同步方法中一部分代碼塊。

9)在使用同步代碼塊時(shí)候,應該指定在哪個(gè)對象上同步,也就是說(shuō)要獲取哪個(gè)對象的鎖。

256.Java中實(shí)現線(xiàn)程通信的三個(gè)方法的作用是什么?

Java提供了3個(gè)方法解決線(xiàn)程之間的通信問(wèn)題,均是java.lang.Object類(lèi)的方法,都只能在同步方法或者同步代碼塊中使用,否則會(huì )拋出異常。

方法名 作 用
final void wait() 表示線(xiàn)程一直等待,直到其它線(xiàn)程通知
void wait(long timeout) 線(xiàn)程等待指定毫秒參數的時(shí)間
final void wait(long timeout,int nanos) 線(xiàn)程等待指定毫秒、微妙的時(shí)間
final void notify() 喚醒一個(gè)處于等待狀態(tài)的線(xiàn)程。注意的是在調用此方法的時(shí)候,并不能確切的喚醒某一個(gè)等待狀態(tài)的線(xiàn)程,而是由JVM確定喚醒哪個(gè)線(xiàn)程,而且不是按優(yōu)先級。
final void notifyAll() 喚醒同一個(gè)對象上所有調用wait()方法的線(xiàn)程,注意并不是給所有喚醒線(xiàn)程一個(gè)對象的鎖,而是讓它們競爭
IO流:
257.下面哪個(gè)流類(lèi)屬于面向字符的輸入流()選擇一項)
A. BufferedWriter
B. FileInputStream
C. ObjectInputStream
D. InputStreamReader
答案:D
分析:A:字符輸出的緩沖流
B:字節輸入流
C:對象輸入流

258.要從文件”file.dat”文件中讀出第10個(gè)字節到變量c中,下列哪個(gè)正確()(選擇一項)
A.
FileInputStream in=new FileInputStream("file.dat");
in.skip(9);
int c=in.read();
B.
FileInputStream in=new FileInputStream("file.dat");
in.skip(10);
int c=in.read();
C.
FileInputStream in=new FileInputStream("file.dat");
int c=in.read();
D.
RandomAccessFile in=new RandomAccessFile("file.dat");
in.skip(7);
int c=in.readByte();
答案:A
分析: skip(long n)該方法中的n指的是要跳過(guò)的字節數
259.新建一個(gè)流對象,下面那個(gè)選項的代碼是錯誤的?()
A. new BufferedWriter(new FileWriter(“a.txt”));
B. new BufferedReader (new FileInputStream(“a.dat”));
C. new GZIPOutputStream(new FileOutputStream(“a.zip”));
D. new ObjectInputStream(new FileInputStream(“a.dat”));
答案:B
分析:BufferedReader類(lèi)的參數只能是Reader類(lèi)型的,不能是InputStream類(lèi)型。
260.下面哪個(gè)流是面向字符的輸入流()
A. BufferedWriter
B. FileInputStream
C. ObjectInputStream
D. InputStreamReader
答案:D
以InputStream(輸入流)/OutputStream(輸出流)為后綴的是字節流;
以Reader(輸入流)/Writer(輸出流)為后綴的是字符流。
261.Java類(lèi)庫中,將信息寫(xiě)入內存的類(lèi)是()
A. Java.io.FileOutputStream
B. java.ByteArrayOutputStream
C. java.io.BufferedOutputStream
D. java,.io.DataOutputStream
答案:B
分析: ACD都是io到文件
262.請寫(xiě)出一段代碼,能夠完成將字符串寫(xiě)入文件
public class test {
public static void main(String[] args) {
String str = "bjsxt";
writeFile(str);
}

public static void writeFile(String str) {
File file = new File("c:/test.txt");
PrintStream ps = null;
try {
OutputStream fos = new FileOutputStream(file);
ps = new PrintStream(fos);
ps.print(str);
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
ps.close();
}
}
}
263.下面哪個(gè)流類(lèi)屬于面向字符的輸入流()
A. BufferedWriter
B. FileInputStream
C. ObjectInputStream
D. InputStreamReader
答案:D
264.Java中如何實(shí)現序列化,有什么意義?

答:序列化就是一種用來(lái)處理對象流的機制,所謂對象流也就是將對象的內容進(jìn)行流化??梢詫α骰蟮膶ο筮M(jìn)行讀寫(xiě)操作,也可將流化后的對象傳輸于網(wǎng)絡(luò )之間。序列化是為了解決對象流讀寫(xiě)操作時(shí)可能引發(fā)的問(wèn)題(如果不進(jìn)行序列化可能會(huì )存在數據亂序的問(wèn)題)。

要實(shí)現序列化,需要讓一個(gè)類(lèi)實(shí)現Serializable接口,該接口是一個(gè)標識性接口,標注該類(lèi)對象是可被序列化的,然后使用一個(gè)輸出流來(lái)構造一個(gè)對象輸出流并通過(guò)writeObject(Object obj)方法就可以將實(shí)現對象寫(xiě)出(即保存其狀態(tài));如果需要反序列化則可以用一個(gè)輸入流建立對象輸入流,然后通過(guò)readObject方法從流中讀取對象。序列化除了能夠實(shí)現對象的持久化之外,還能夠用于對象的深度克?。▍⒁?jiàn)Java面試題集1-29題)?

265.Java 中有幾種類(lèi)型的流?

答:兩種流分別是字節流,字符流。

字節流繼承于InputStream、OutputStream,字符流繼承于Reader、Writer。在java.io 包中還有許多其他的流,主要是為了提高性能和使用方便。

補充:關(guān)于Java的IO需要注意的有兩點(diǎn):一是兩種對稱(chēng)性(輸入和輸出的對稱(chēng)性,字節和字符的對稱(chēng)性);二是兩種設計模式(適配器模式和裝潢模式)。另外Java中的流不同于C#的是它只有一個(gè)維度一個(gè)方向。

補充:下面用IO和NIO兩種方式實(shí)現文件拷貝,這個(gè)題目在面試的時(shí)候是經(jīng)常被問(wèn)到的。

package com.bjsxt;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class MyUtil {
  private MyUtil() {
        throw new AssertionError();
    }

    public static void fileCopy(String source, String target) throws IOException {
        try (InputStream in = new FileInputStream(source)) {
            try (OutputStream out = new FileOutputStream(target)) {
                byte[] buffer = new byte[4096];
                int bytesToRead;
                while((bytesToRead = in.read(buffer)) != -1) {
                    out.write(buffer, 0, bytesToRead);
                }
            }
        }
    }

    public static void fileCopyNIO(String source, String target) throws IOException {
        try (FileInputStream in = new FileInputStream(source)) {
            try (FileOutputStream out = new FileOutputStream(target)) {
                FileChannel inChannel = in.getChannel();
                FileChannel outChannel = out.getChannel();
                ByteBuffer buffer = ByteBuffer.allocate(4096);
                while(inChannel.read(buffer) != -1) {
                    buffer.flip();
                    outChannel.write(buffer);
                    buffer.clear();
                 }
            }
        }
    }
}

注意:上面用到Java 7的TWR,使用TWR后可以不用在finally中釋放外部資源 ,從而讓代碼更加優(yōu)雅。

266.寫(xiě)一個(gè)方法,輸入一個(gè)文件名和一個(gè)字符串,統計這個(gè)字符串在這個(gè)文件中出現的次數。

答:代碼如下:

package com.bjsxt;
import java.io.BufferedReader;
import java.io.FileReader;

public class Account {
    // 工具類(lèi)中的方法都是靜態(tài)方式訪(fǎng)問(wèn)的因此將構造器私有不允許創(chuàng  )建對象(絕對好習慣)
    private Account() {
        throw new AssertionError();
    }
    /**
     * 統計給定文件中給定字符串的出現次數
     * @param filename  文件名
     * @param word 字符串
     * @return 字符串在文件中出現的次數
     */
    public static int countWordInFile(String filename, String word) {
        int counter = 0;
        try (FileReader fr = new FileReader(filename)) {
            try (BufferedReader br = new BufferedReader(fr)) {
                String line = null;
                while ((line = br.readLine()) != null) {
                    int index = -1;
                    while (line.length() >= word.length() && (index = line.indexOf(word)) >= 0) {
                        counter++;
                        line = line.substring(index + word.length());
                    }
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return counter;
    }
}
267.輸入流和輸出流聯(lián)系和區別,節點(diǎn)流和處理流聯(lián)系和區別

首先,你要明白什么是“流”。直觀(guān)地講,流就像管道一樣,在程序和文件之間,輸入輸出的方向是針對程序而言,向程序中讀入東西,就是輸入流,從程序中向外讀東西,就是輸出流。

輸入流是得到數據,輸出流是輸出數據,而節點(diǎn)流,處理流是流的另一種劃分,按照功能不同進(jìn)行的劃分。節點(diǎn)流,可以從或向一個(gè)特定的地方(節點(diǎn))讀寫(xiě)數據。處理流是對一個(gè)已存在的流的連接和封裝,通過(guò)所封裝的流的功能調用實(shí)現數據讀寫(xiě)。如BufferedReader。處理流的構造方法總是要帶一個(gè)其他的流對象做參數。一個(gè)流對象經(jīng)過(guò)其他流的多次包裝,稱(chēng)為流的鏈接。

268.字符流字節流聯(lián)系區別;什么時(shí)候使用字節流和字符流?

字符流和字節流是流的一種劃分,按處理照流的數據單位進(jìn)行的劃分。兩類(lèi)都分為輸入和輸出操作。在字節流中輸出數據主要是使用OutputStream完成,輸入使的是InputStream,在字符流中輸出主要是使用Writer類(lèi)完成,輸入流主要使用Reader類(lèi)完成。這四個(gè)都是抽象類(lèi)。

字符流處理的單元為2個(gè)字節的Unicode字符,分別操作字符、字符數組或字符串,而字節流處理單元為1個(gè)字節,操作字節和字節數組。字節流是最基本的,所有的InputStrem和OutputStream的子類(lèi)都是,主要用在處理二進(jìn)制數據,它是按字節來(lái)處理的 但實(shí)際中很多的數據是文本,又提出了字符流的概念,它是按虛擬機的編碼來(lái)處理,也就是要進(jìn)行字符集的轉化 這兩個(gè)之間通過(guò) InputStreamReader,OutputStreamWriter來(lái)關(guān)聯(lián),實(shí)際上是通過(guò)byte[]和String來(lái)關(guān)聯(lián)的。

269.列舉常用字節輸入流和輸出流并說(shuō)明其特點(diǎn),至少5對。

FileInputStream 從文件系統中的某個(gè)文件中獲得輸入字節。

FileOutputStream 從程序當中的數據,寫(xiě)入到指定文件。

ObjectInputStream 對以前使用 ObjectOutputStream 寫(xiě)入的基本數據和對象進(jìn)行反序列化。 ObjectOutputStream 和ObjectInputStream 分別與FileOutputStream 和 FileInputStream 一起使用時(shí),可以為應用程序提供對對象圖形的持久存儲。ObjectInputStream 用于恢復那些以前序列化的對象。其他用途包括使用套接字流在主機之間傳遞對象,或者用于編組和解組遠程通信系統中的實(shí)參和形參。

ByteArrayInputStream 包含一個(gè)內部緩沖區,該緩沖區包含從流中讀取的字節。內部計數器跟蹤 read 方法要提供的下一個(gè)字節。

FilterInputStream 包含其他一些輸入流,它將這些流用作其基本數據源,它可以直接傳輸數據或提供一些額外的功能。FilterInputStream 類(lèi)本身只是簡(jiǎn)單地重寫(xiě)那些將所有請求傳遞給所包含輸入流的 InputStream 的所有方法。FilterInputStream 的子類(lèi)可進(jìn)一步重寫(xiě)這些方法中的一些方法,并且還可以提供一些額外的方法和字段。

StringBufferInputStream此類(lèi)允許應用程序創(chuàng )建輸入流,在該流中讀取的字節由字符串內容提供。應用程序還可以使用ByteArrayInputStream 從 byte 數組中讀取字節。 只有字符串中每個(gè)字符的低八位可以由此類(lèi)使用。

ByteArrayOutputStream此類(lèi)實(shí)現了一個(gè)輸出流,其中的數據被寫(xiě)入一個(gè) byte 數組。緩沖區會(huì )隨著(zhù)數據的不斷寫(xiě)入而自動(dòng)增長(cháng)??墒褂?toByteArray() 和 toString() 獲取數據。

FileOutputStream文件輸出流是用于將數據寫(xiě)入 File 或FileDescriptor 的輸出流。文件是否可用或能否可以被創(chuàng )建取決于基礎平臺。特別是某些平臺一次只允許一個(gè) FileOutputStream(或其他文件寫(xiě)入對象)打開(kāi)文件進(jìn)行寫(xiě)入。在這種情況下,如果所涉及的文件已經(jīng)打開(kāi),則此類(lèi)中的構造方法將失敗。

FilterOutputStream類(lèi)是過(guò)濾輸出流的所有類(lèi)的超類(lèi)。這些流位于已存在的輸出流(基礎 輸出流)之上,它們將已存在的輸出流作為其基本數據接收器,但可能直接傳輸數據或提供一些額外的功能。 FilterOutputStream 類(lèi)本身只是簡(jiǎn)單地重寫(xiě)那些將所有請求傳遞給所包含輸出流的 OutputStream 的所有方法。FilterOutputStream 的子類(lèi)可進(jìn)一步地重寫(xiě)這些方法中的一些方法,并且還可以提供一些額外的方法和字段。

ObjectOutputStream 將 Java 對象的基本數據類(lèi)型和圖形寫(xiě)入 OutputStream??梢允褂?ObjectInputStream 讀?。ㄖ貥嫞ο?。通過(guò)在流中使用文件可以實(shí)現對象的持久存儲。如果流是網(wǎng)絡(luò )套接字流,則可以在另一臺主機上或另一個(gè)進(jìn)程中重構對象。

PipedOutputStream可以將管道輸出流連接到管道輸入流來(lái)創(chuàng )建通信管道。管道輸出流是管道的發(fā)送端。通常,數據由某個(gè)線(xiàn)程寫(xiě)入 PipedOutputStream 對象,并由其他線(xiàn)程從連接的 PipedInputStream 讀取。不建議對這兩個(gè)對象嘗試使用單個(gè)線(xiàn)程,因為這樣可能會(huì )造成該線(xiàn)程死鎖。如果某個(gè)線(xiàn)程正從連接的管道輸入流中讀取數據字節,但該線(xiàn)程不再處于活動(dòng)狀態(tài),則該管道被視為處于毀壞狀態(tài)。

270.說(shuō)明緩沖流的優(yōu)點(diǎn)和原理

不帶緩沖的流的工作原理:

它讀取到一個(gè)字節/字符,就向用戶(hù)指定的路徑寫(xiě)出去,讀一個(gè)寫(xiě)一個(gè),所以就慢了。

帶緩沖的流的工作原理:

讀取到一個(gè)字節/字符,先不輸出,等湊足了緩沖的最大容量后一次性寫(xiě)出去,從而提高了工作效率

優(yōu)點(diǎn):減少對硬盤(pán)的讀取次數,降低對硬盤(pán)的損耗。

271.序列化的定義、實(shí)現和注意事項

想把一個(gè)對象寫(xiě)在硬盤(pán)上或者網(wǎng)絡(luò )上,對其進(jìn)行序列化,把他序列化成為一個(gè)字節流。

實(shí)現和注意事項:

1)實(shí)現接口Serializable Serializable接口中沒(méi)有任何的方法,實(shí)現該接口的類(lèi)不需要實(shí)現額外的方法。

2)如果對象中的某個(gè)屬性是對象類(lèi)型,必須也實(shí)現Serializable接口才可以,序列化對靜態(tài)變量無(wú)效

3)如果不希望某個(gè)屬性參與序列化,不是將其static,而是transient串行化保存的只是變量的值,對于變量的任何修飾符,都不能保存序列化版本不兼容

272.使用IO流完成文件夾復制

(結合遞歸)

package com.bjsxt;

import java.io.*;
/**
 * CopyDocJob定義了實(shí)際執行的任務(wù),即
 * 從源目錄拷貝文件到目標目錄
*/
public class CopyDir2 {
public static void main(String[] args) {
try {
copyDirectiory("d:/301sxt","d:/301sxt2");
} catch (IOException e) {
e.printStackTrace();
}
}
/**
 * 復制單個(gè)文件
 * @param sourceFile 源文件
 * @param targetFile 目標文件
 * @throws IOException
 */
    private static void copyFile(File sourceFile, File targetFile) throws IOException {
        BufferedInputStream inBuff = null;
        BufferedOutputStream outBuff = null;
        try {
            // 新建文件輸入流
            inBuff = new BufferedInputStream(new FileInputStream(sourceFile));
            // 新建文件輸出流
            outBuff = new BufferedOutputStream(new FileOutputStream(targetFile));
            // 緩沖數組
            byte[] b = new byte[1024 * 5];
            int len;
            while ((len = inBuff.read(b)) != -1) {
                outBuff.write(b, 0, len);
            }
            // 刷新此緩沖的輸出流
            outBuff.flush();
        } finally {
            // 關(guān)閉流
            if (inBuff != null)
                inBuff.close();
            if (outBuff != null)
                outBuff.close();
        }
    }

    /**
     * 復制目錄
     * @param sourceDir 源目錄
     * @param targetDir 目標目錄
     * @throws IOException
     */
    private static void copyDirectiory(String sourceDir, String targetDir) throws IOException {
        // 檢查源目錄
     File fSourceDir = new File(sourceDir);
     if(!fSourceDir.exists() || !fSourceDir.isDirectory()){
      return;
     }
     //檢查目標目錄,如不存在則創(chuàng  )建
     File fTargetDir = new File(targetDir);
     if(!fTargetDir.exists()){
      fTargetDir.mkdirs();
     }
        // 遍歷源目錄下的文件或目錄
        File[] file = fSourceDir.listFiles();
        for (int i = 0; i < file.length; i++) {
            if (file[i].isFile()) {
                // 源文件
                File sourceFile = file[i];
                // 目標文件
                File targetFile = new File(fTargetDir, file[i].getName());
                copyFile(sourceFile, targetFile);
            }
            //遞歸復制子目錄
            if (file[i].isDirectory()) {
                // 準備復制的源文件夾
                String subSourceDir = sourceDir + File.separator + file[i].getName();
                // 準備復制的目標文件夾
                String subTargetDir = targetDir + File.separator + file[i].getName();
                // 復制子目錄
                copyDirectiory(subSourceDir, subTargetDir);
            }
        }
    }
}
273.說(shuō)說(shuō)BIO、NIO和AIO的區別

Java BIO: 同步并阻塞,服務(wù)器實(shí)現模式為一個(gè)連接一個(gè)線(xiàn)程,即客戶(hù)端有連接請求時(shí)服務(wù)器端就需要啟動(dòng)一個(gè)線(xiàn)程進(jìn)行處理,如果這個(gè)連接不做任何事情會(huì )造成不必要的線(xiàn)程開(kāi)銷(xiāo),當然可以通過(guò)線(xiàn)程池機制改善。

Java NIO: 同步非阻塞,服務(wù)器實(shí)現模式為一個(gè)請求一個(gè)線(xiàn)程,即客戶(hù)端發(fā)送的連接請求都會(huì )注冊到多路復用器上,多路復用器輪詢(xún)到連接有I/O請求時(shí)才啟動(dòng)一個(gè)線(xiàn)程進(jìn)行處理。

Java AIO: 異步非阻塞,服務(wù)器實(shí)現模式為一個(gè)有效請求一個(gè)線(xiàn)程,客戶(hù)端的I/O請求都是由OS先完成了再通知服務(wù)器應用去啟動(dòng)線(xiàn)程進(jìn)行處理。

NIO比BIO的改善之處是把一些無(wú)效的連接擋在了啟動(dòng)線(xiàn)程之前,減少了這部分資源的浪費(因為我們都知道每創(chuàng )建一個(gè)線(xiàn)程,就要為這個(gè)線(xiàn)程分配一定的內存空間)

AIO比NIO的進(jìn)一步改善之處是將一些暫時(shí)可能無(wú)效的請求擋在了啟動(dòng)線(xiàn)程之前,比如在NIO的處理方式中,當一個(gè)請求來(lái)的話(huà),開(kāi)啟線(xiàn)程進(jìn)行處理,但這個(gè)請求所需要的資源還沒(méi)有就緒,此時(shí)必須等待后端的應用資源,這時(shí)線(xiàn)程就被阻塞了。

適用場(chǎng)景分析:

BIO方式適用于連接數目比較小且固定的架構,這種方式對服務(wù)器資源要求比較高,并發(fā)局限于應用中,JDK1.4以前的唯一選擇,但程序直觀(guān)簡(jiǎn)單易理解,如之前在A(yíng)pache中使用。

NIO方式適用于連接數目多且連接比較短(輕操作)的架構,比如聊天服務(wù)器,并發(fā)局限于應用中,編程比較復雜,JDK1.4開(kāi)始支持,如在 Nginx,Netty中使用。

AIO方式使用于連接數目多且連接比較長(cháng)(重操作)的架構,比如相冊服務(wù)器,充分調用OS參與并發(fā)操作,編程比較復雜,JDK7開(kāi)始支持,在成長(cháng)中,Netty曾經(jīng)使用過(guò),后來(lái)放棄。

網(wǎng)絡(luò )編程:

274.IP地址和端口號

1)IP地址

用來(lái)標志網(wǎng)絡(luò )中的一個(gè)通信實(shí)體的地址。通信實(shí)體可以是計算機,路由器等。

2)IP地址分類(lèi)

IPV4:32位地址,以點(diǎn)分十進(jìn)制表示,如192.168.0.1

IPV6:128位(16個(gè)字節)寫(xiě)成8個(gè)16位的無(wú)符號整數,每個(gè)整數用四個(gè)十六進(jìn)制位表示,數之間用冒號(:)分開(kāi),如:3ffe:3201:1401:1280:c8ff:fe4d:db39:1984

3)特殊的IP地址

127.0.0.1 本機地址

192.168.0.0--192.168.255.255私有地址,屬于非注冊地址,專(zhuān)門(mén)為組織機構內部使用。

4)端口:port

IP地址用來(lái)標志一臺計算機,但是一臺計算機上可能提供多種應用程序,使用端口來(lái)區分這些應用程序。 端口是虛擬的概念,并不是說(shuō)在主機上真的有若干個(gè)端口。通過(guò)端口,可以在一個(gè)主機上運行多個(gè)網(wǎng)絡(luò )應用程序。 端口范圍0---65535,16位整數

5)端口分類(lèi)

公認端口 0—1023 比如80端口分配給WWW,21端口分配給FTP,22端口分配給SSH,23端口分配給telnet,25端口分配給smtp

注冊端口 1024—49151 分配給用戶(hù)進(jìn)程或應用程序

動(dòng)態(tài)/私有端口 49152--65535

6)理解IP和端口的關(guān)系

IP地址好比每個(gè)人的地址(門(mén)牌號),端口好比是房間號。必須同時(shí)指定IP地址和端口號才能夠正確的發(fā)送數據

IP地址好比為電話(huà)號碼,而端口號就好比為分機號。

275.介紹OSI七層模型和TCP/IP模型

OSI(Open System Interconnection),開(kāi)放式系統互聯(lián)參考模型 。是一個(gè)邏輯上的定義,一個(gè)規范,它把網(wǎng)絡(luò )協(xié)議從邏輯上分為了7層。每一層都有相關(guān)、相對應的物理設備,比如常規的路由器是三層交換設備,常規的交換機是二層交換設備。OSI七層模型是一種框架性的設計方法,建立七層模型的主要目的是為解決異種網(wǎng)絡(luò )互連時(shí)所遇到的兼容性問(wèn)題,其最主要的功能就是幫助不同類(lèi)型的主機實(shí)現數據傳輸。它的最大優(yōu)點(diǎn)是將服務(wù)、接口和協(xié)議這三個(gè)概念明確地區分開(kāi)來(lái),通過(guò)七個(gè)層次化的結構模型使不同的系統不同的網(wǎng)絡(luò )之間實(shí)現可靠的通訊。

TCP/IP協(xié)議是Internet最基本的協(xié)議、Internet國際互聯(lián)網(wǎng)絡(luò )的基礎,主要由網(wǎng)絡(luò )層的IP協(xié)議和傳輸層的TCP協(xié)議組成。TCP/IP 定義了電子設備如何連入因特網(wǎng),以及數據如何在它們之間傳輸的標準。協(xié)議采用了4層的層級結構,每一層都呼叫它的下一層所提供的協(xié)議來(lái)完成自己的需求。

ISO制定的OSI參考模型的過(guò)于龐大、復雜招致了許多批評。伴隨著(zhù)互聯(lián)網(wǎng)的流行,其本身所采用的TCP/IP協(xié)議棧獲得了更為廣泛的應用和認可。在TCP/IP參考模型中,去掉了OSI參考模型中的會(huì )話(huà)層和表示層(這兩層的功能被合并到應用層實(shí)現)。同時(shí)將OSI參考模型中的數據鏈路層和物理層合并為主機到網(wǎng)絡(luò )層。

276.TCP協(xié)議和UDP協(xié)議的比較

TCP和UDP是TCP/IP協(xié)議棧中傳輸層的兩個(gè)協(xié)議,它們使用IP路由功能把數據包發(fā)送到目的地,從而為應用程序及應用層協(xié)議(包括:HTTP、SMTP、SNMP、FTP和Telnet)提供網(wǎng)絡(luò )服務(wù)。

TCP的server和client之間通信就好比兩個(gè)人打電話(huà),需要互相知道對方的電話(huà)號碼,然后開(kāi)始對話(huà)。所以在兩者的連接過(guò)程中間需要指定端口和地址。

UDP的server和client之間的通信就像兩個(gè)人互相發(fā)信。我只需要知道對方的地址,然后就發(fā)信過(guò)去。對方是否收到我不知道,也不需要專(zhuān)門(mén)對口令似的來(lái)建立連接。具體區別如下:

1)TCP是面向連接的傳輸。UDP是無(wú)連接的傳輸

2)TCP有流量控制、擁塞控制,檢驗數據數據按序到達,而UDP則相反。

3)TCP的路由選擇只發(fā)生在建立連接的時(shí)候,而UDP的每個(gè)報文都要進(jìn)行路由選擇

4)TCP是可靠性傳輸,他的可靠性是由超時(shí)重發(fā)機制實(shí)現的,而UDP則是不可靠傳輸

5)UDP因為少了很多控制信息,所以傳輸速度比TCP速度快

6)TCP適合用于傳輸大量數據,UDP適合用于傳輸小量數據

277.什么是Socket編程

Socket編程的定義如下:

所謂socket通常也稱(chēng)作"套接字",用于描述IP地址和端口,是一個(gè)通信鏈的句柄。應用程序通常通過(guò)"套接字"向網(wǎng)絡(luò )發(fā)出請求或者應答網(wǎng)絡(luò )請求。

我們開(kāi)發(fā)的網(wǎng)絡(luò )應用程序位于應用層,TCP和UDP屬于傳輸層協(xié)議,在應用層如何使用傳輸層的服務(wù)呢?在應用層和傳輸層之間,則是使用套接字來(lái)進(jìn)行分離。

套接字就像是傳輸層為應用層開(kāi)的一個(gè)小口,應用程序通過(guò)這個(gè)小口向遠程發(fā)送數據,或者接收遠程發(fā)來(lái)的數據;而這個(gè)小口以?xún)?,也就是數據進(jìn)入這個(gè)口之后,或者數據從這個(gè)口出來(lái)之前,是不知道也不需要知道的,也不會(huì )關(guān)心它如何傳輸,這屬于網(wǎng)絡(luò )其它層次的工作。

Socket實(shí)際是傳輸層供給應用層的編程接口。傳輸層則在網(wǎng)絡(luò )層的基礎上提供進(jìn)程到進(jìn)程問(wèn)的邏輯通道,而應用層的進(jìn)程則利用傳輸層向另一臺主機的某一進(jìn)程通信。Socket就是應用層與傳輸層之間的橋梁

使用Socket編程可以開(kāi)發(fā)客戶(hù)機和服務(wù)器應用程序,可以在本地網(wǎng)絡(luò )上進(jìn)行通信,也可通過(guò)Internet在全球范圍內通信。

生活案例1如果你想寫(xiě)封郵件發(fā)給遠方的朋友,如何寫(xiě)信、將信打包,屬于應用層。信怎么寫(xiě),怎么打包完全由我們做主;而當我們將信投入郵筒時(shí),郵筒的那個(gè)口就是套接字,在進(jìn)入套接字之后,就是傳輸層、網(wǎng)絡(luò )層等(郵局、公路交管或者航線(xiàn)等)其它層次的工作了。我們從來(lái)不會(huì )去關(guān)心信是如何從西安發(fā)往北京的,我們只知道寫(xiě)好了投入郵筒就OK了。

生活案例2:可以把Socket比作是一個(gè)港口碼頭,應用程序只要將數據交給Socket,就算完成了數據的發(fā)送,具體細節由Socket來(lái)完成,細節不必了解。同理,對于接收方,應用程序也要創(chuàng )建一個(gè)碼頭,等待數據的到達,并獲取數據。

278.簡(jiǎn)述基于TCP和UDP的Socket編程的主要步驟

Java分別為T(mén)CP和UDP 兩種通信協(xié)議提供了相應的Socket編程類(lèi),這些類(lèi)存放在java.net包中。與TCP對應的是服務(wù)器的ServerSocket和客戶(hù)端的Socket,與UDP對應的是DatagramSocket。

基于TCP創(chuàng )建的套接字可以叫做流套接字,服務(wù)器端相當于一個(gè)監聽(tīng)器,用來(lái)監聽(tīng)端口。?服務(wù)器與客服端之間的通訊都是輸入輸出流來(lái)實(shí)現的?;赨DP的套接字就是數據報套接字,?? 兩個(gè)都要先構造好相應的數據包。

基于TCP協(xié)議的Socket編程的主要步驟

服務(wù)器端(server):

1. 構建一個(gè)ServerSocket實(shí)例,指定本地的端口。這個(gè)socket就是用來(lái)監聽(tīng)指定端口的連接請求的。

2. 重復如下幾個(gè)步驟:

a. 調用socket的accept()方法來(lái)獲得下面客戶(hù)端的連接請求。通過(guò)accept()方法返回的socket實(shí)例,建立了一個(gè)和客戶(hù)端的新連接。

b. 通過(guò)這個(gè)返回的socket實(shí)例獲取InputStream和OutputStream,可以通過(guò)這兩個(gè)stream來(lái)分別讀和寫(xiě)數據。

c. 結束的時(shí)候調用socket實(shí)例的close()方法關(guān)閉socket連接。

客戶(hù)端(client):

1.構建Socket實(shí)例,通過(guò)指定的遠程服務(wù)器地址和端口來(lái)建立連接。

2.通過(guò)Socket實(shí)例包含的InputStream和OutputStream來(lái)進(jìn)行數據的讀寫(xiě)。

3.操作結束后調用socket實(shí)例的close方法,關(guān)閉。

UDP

服務(wù)器端(server):

1. 構造DatagramSocket實(shí)例,指定本地端口。

2. 通過(guò)DatagramSocket實(shí)例的receive方法接收DatagramPacket.DatagramPacket中間就包含了通信的內容。

3. 通過(guò)DatagramSocket的send和receive方法來(lái)收和發(fā)DatagramPacket.

客戶(hù)端(client):

1. 構造DatagramSocket實(shí)例。

2. 通過(guò)DatagramSocket實(shí)例的send和receive方法發(fā)送DatagramPacket報文。

3. 結束后,調用DatagramSocket的close方法關(guān)閉。

異常處理:

279.下列哪種異常是檢查型異常,需要在編寫(xiě)程序時(shí)聲明()
A. NullPointerException
B. ClassCastException
C. FileNotFoundException
D. IndexOutOfBoundsException
答案:C
分析:NullPointerException空指針異常
ClassCastException類(lèi)型轉換異常
IndexOutOfBoundsException索引超出邊界的異常
以上這些異常都是程序在運行時(shí)發(fā)生的異常,所以不需要在編寫(xiě)程序時(shí)聲明
280.Java出現OutOf MemoryError(OOM 錯誤)的原因有哪些?出現OOM錯誤后,怎么解決?

答:OutOf MemoryError這種錯誤可以細分為多種不同的錯誤,每種錯誤都有自身的原因和解決辦法,如下所示:

java.lang.OutOfMemoryError: Java heap space

錯誤原因:此OOM是由于JVM中heap的最大值不滿(mǎn)足需要。

解決方法:1) 調高heap的最大值,即-Xmx的值調大。2) 如果你的程序存在內存泄漏,一味的增加heap空間也只是推遲該錯誤出現的時(shí)間而已,所以要檢查程序是否存在內存泄漏。

java.lang.OutOfMemoryError: GC overhead limit exceeded

錯誤原因:此OOM是由于JVM在GC時(shí),對象過(guò)多,導致內存溢出,建議調整GC的策略,在一定比例下開(kāi)始GC而不要使用默認的策略,或者將新代和老代設置合適的大小,需要進(jìn)行微調存活率。

解決方法:改變GC策略,在老代80%時(shí)就是開(kāi)始GC,并且將-XX:SurvivorRatio(-XX:SurvivorRatio=8)和-XX:NewRatio(-XX:NewRatio=4)設置的更合理。

java.lang.OutOfMemoryError: Java perm space

錯誤原因:此OOM是由于JVM中perm的最大值不滿(mǎn)足需要。

解決方法:調高heap的最大值,即-XX:MaxPermSize的值調大。

另外,注意一點(diǎn),Perm一般是在JVM啟動(dòng)時(shí)加載類(lèi)進(jìn)來(lái),如果是JVM運行較長(cháng)一段時(shí)間而不是剛啟動(dòng)后溢出的話(huà),很有可能是由于運行時(shí)有類(lèi)被動(dòng)態(tài)加載進(jìn)來(lái),此時(shí)建議用CMS策略中的類(lèi)卸載配置。如:-XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled。

java.lang.OutOfMemoryError: unable to create new native thread

錯誤原因:當JVM向OS請求創(chuàng )建一個(gè)新線(xiàn)程時(shí),而OS卻由于內存不足無(wú)法創(chuàng )建新的native線(xiàn)程。

解決方法:如果JVM內存調的過(guò)大或者可利用率小于20%,可以建議將heap及perm的最大值下調,并將線(xiàn)程棧調小,即-Xss調小,如:-Xss128k。

java.lang.OutOfMemoryError: Requested array size exceeds VM limit

錯誤原因:此類(lèi)信息表明應用程序(或者被應用程序調用的APIs)試圖分配一個(gè)大于堆大小的數組。例如,如果應用程序new一個(gè)數組對象,大小為512M,但是最大堆大小為256M,因此OutOfMemoryError會(huì )拋出,因為數組的大小超過(guò)虛擬機的限制。

解決方法:1) 首先檢查heap的-Xmx是不是設置的過(guò)小。2) 如果heap的-Xmx已經(jīng)足夠大,那么請檢查應用程序是不是存在bug,例如:應用程序可能在計算數組的大小時(shí),存在算法錯誤,導致數組的size很大,從而導致巨大的數組被分配。

java.lang.OutOfMemoryError: request < size> bytes for < reason>. Out of swap space

錯誤原因:拋出這類(lèi)錯誤,是由于從native堆中分配內存失敗,并且堆內存可能接近耗盡。這類(lèi)錯誤可能跟應用程序沒(méi)有關(guān)系,例如下面兩種原因也會(huì )導致錯誤的發(fā)生:1) 操作系統配置了較小的交換區。2)系統的另外一個(gè)進(jìn)程正在消耗所有的內存。

解決辦法:1) 檢查os的swap是不是沒(méi)有設置或者設置的過(guò)小。2) 檢查是否有其他進(jìn)程在消耗大量的內存,從而導致當前的JVM內存不夠分配。

注意:雖然有時(shí)< reason>部分顯示導致OOM的原因,但大多數情況下,< reason>顯示的是提示分配失敗的源模塊的名稱(chēng),所以有必要查看日志文件,如crash時(shí)的hs文件。

281.列舉常見(jiàn)的運行時(shí)異常

答:ClassCastException(類(lèi)轉換異常)

比如 Object obj=new Object(); String s=(String)obj;?

IndexOutOfBoundsException(下標越界異常)

NullPointerException(空指針異常)

ArrayStoreException(數據存儲異常,操作數組時(shí)類(lèi)型不一致)

BufferOverflowException(IO操作時(shí)出現的緩沖區上溢異常)

InputMismatchException(輸入類(lèi)型不匹配異常)

ArithmeticException(算術(shù)異常)

注意:運行時(shí)異常都是RuntimeException子類(lèi)異常。

282.下面關(guān)于 Java.lang.Exception類(lèi)的說(shuō)法正確的是()
A. 繼承自 Throwable
B. 不支持Serializable
C. 繼承自 AbstractSet
D. 繼承自FitelnputStream
答案:A
分析:Throwable是Exception和Error的父類(lèi),Exception雖然沒(méi)有實(shí)現Serializable接口,但是其父類(lèi)Throwable已經(jīng)實(shí)現了該接口,因此Exception也支持Serializable。
283.Unsupported major.minor version 52是什么異常,怎么造成的,如何解決?

答:?jiǎn)?wèn)題的根本原因是工程中某個(gè)jar包的版本(jar包編譯時(shí)的所用的jdk版本)高于工程build path中jdk的版本,這個(gè)是不兼容的! 編程中遇到此異常Unsupported major.minor version 52.0(根據版本號,這里可以為其他數值,52是1.8jdk jar包與 1.8以下低版本jdk不匹配),在將build path中jdk的版本調整與jar包匹配后,解決異常。

284.try{}里有一個(gè)return語(yǔ)句,那么緊跟在這個(gè)try后的finally{}里的code會(huì )不會(huì )被執行,什么時(shí)候被執行,在return前還是后?

答:會(huì )執行,在方法返回調用者前執行。Java允許在finally中改變返回值的做法是不好的,因為如果存在finally代碼塊,try中的return語(yǔ)句不會(huì )立馬返回調用者,而是記錄下返回值待finally代碼塊執行完畢之后再向調用者返回其值,然后如果在finally中修改了返回值,這會(huì )對程序造成很大的困擾,C#中就從語(yǔ)法上規定不能做這樣的事。?

(也許你的答案是在return之前,但往更細地說(shuō),我的答案是在return中間執行,請看下面程序代碼的運行結果:

public classTest {

    /**
     * @paramargs add by zxx ,Dec 9, 2008
     */
    public static voidmain(String[] args) {
       // TODO Auto-generated method stub
       System.out.println(newTest().test());;
    }

    static int test()
    {
       int x = 1;
       try
       {
           returnx;
       }
       finally
       {
           ++x;
       }
    }

}

執行結果

運行結果是1,為什么呢?主函數調用子函數并得到結果的過(guò)程,好比主函數準備一個(gè)空罐子,當子函數要返回結果時(shí),先把結果放在罐子里,然后再將程序邏輯返回到主函數。所謂返回,就是子函數說(shuō),我不運行了,你主函數繼續運行吧,這沒(méi)什么結果可言,結果是在說(shuō)這話(huà)之前放進(jìn)罐子里的。

285.Java 語(yǔ)言如何進(jìn)行異常處理,關(guān)鍵字:throws、throw、try、catch、finally分別如何使用?

答:Java 通過(guò)面向對象的方法進(jìn)行異常處理,把各種不同的異常進(jìn)行分類(lèi),并提供了良好的接口。在Java 中,每個(gè)異常都是一個(gè)對象,它是Throwable 類(lèi)或其子類(lèi)的實(shí)例。當一個(gè)方法出現異常后便拋出一個(gè)異常對象,該對象中包含有異常信息,調用這個(gè)對象的方法可以捕獲到這個(gè)異常并進(jìn)行處理。Java 的異常處理是通過(guò)5 個(gè)關(guān)鍵詞來(lái)實(shí)現的:try、catch、throw、throws和finally。一般情況下是用try來(lái)執行一段程序,如果出現異常,系統會(huì )拋出(throw)一個(gè)異常,這時(shí)候你可以通過(guò)它的類(lèi)型來(lái)捕捉(catch)它,或最后(finally)由缺省處理器來(lái)處理;try用來(lái)指定一塊預防所有“異?!钡某绦?;catch 子句緊跟在try塊后面,用來(lái)指定你想要捕捉的“異?!钡念?lèi)型;throw 語(yǔ)句用來(lái)明確地拋出一個(gè)“異?!?;throws用來(lái)標明一個(gè)成員函數可能拋出的各種“異?!?;finally 為確保一段代碼不管發(fā)生什么“異?!倍急粓绦幸欢未a;可以在一個(gè)成員函數調用的外面寫(xiě)一個(gè)try語(yǔ)句,在這個(gè)成員函數內部寫(xiě)另一個(gè)try語(yǔ)句保護其他代碼。每當遇到一個(gè)try 語(yǔ)句,“異?!钡目蚣芫头诺綏I厦?,直到所有的try語(yǔ)句都完成。如果下一級的try語(yǔ)句沒(méi)有對某種“異?!边M(jìn)行處理,棧就會(huì )展開(kāi),直到遇到有處理這種“異?!钡膖ry 語(yǔ)句。?

286.運行時(shí)異常與受檢異常有何異同?

答:異常表示程序運行過(guò)程中可能出現的非正常狀態(tài),運行時(shí)異常表示虛擬機的通常操作中可能遇到的異常,是一種常見(jiàn)運行錯誤,只要程序設計得沒(méi)有問(wèn)題通常就不會(huì )發(fā)生。受檢異常跟程序運行的上下文環(huán)境有關(guān),即使程序設計無(wú)誤,仍然可能因使用的問(wèn)題而引發(fā)。Java編譯器要求方法必須聲明拋出可能發(fā)生的受檢異常,但是并不要求必須聲明拋出未被捕獲的運行時(shí)異常。異常和繼承一樣,是面向對象程序設計中經(jīng)常被濫用的東西,神作《Effective Java》中對異常的使用給出了以下指導原則:

不要將異常處理用于正常的控制流(設計良好的API不應該強迫它的調用者為了正常的控制流而使用異常)

對可以恢復的情況使用受檢異常,對編程錯誤使用運行時(shí)異常

避免不必要的使用受檢異常(可以通過(guò)一些狀態(tài)檢測手段來(lái)避免異常發(fā)生)

優(yōu)先使用標準的異常

每個(gè)方法拋出的異常都要有文檔

保持異常的原子性

不要在catch中忽略掉捕獲到的異常?

(異常表示程序運行過(guò)程中可能出現的非正常狀態(tài),運行時(shí)異常表示虛擬機的通常操作中可能遇到的異常,是一種常見(jiàn)運行錯誤。java編譯器要求方法必須聲明拋出可能發(fā)生的非運行時(shí)異常,但是并不要求必須聲明拋出未被捕獲的運行時(shí)異常。)

287.類(lèi)ExampleA 繼承Exception,類(lèi)ExampleB 繼承ExampleA

有如下代碼片斷:

try{
throw new ExampleB("b")
}catch(ExampleA e){
System.out.println("ExampleA");
}catch(Exception e){
System.out.println("Exception");
}
 }

請問(wèn)執行此段代碼的輸出是什么?

答:輸出:ExampleA。(根據里氏代換原則[能使用父類(lèi)型的地方一定能使用子類(lèi)型],抓取ExampleA類(lèi)型異常的catch塊能夠抓住try塊中拋出的ExampleB類(lèi)型的異常)

補充: 比此題略復雜的一道面試題如下所示(此題的出處是《Java編程思想》),說(shuō)出你的答案吧!

package com.bjsxt;
class Annoyance extends Exception {}
class Sneeze extends Annoyance {}
 class Human {
  public static void main(String[] args)
        throws Exception {
        try {
            try {
                throw new Sneeze();
            }
            catch ( Annoyance a ) {
                System.out.println("Caught Annoyance");
                throw a;
            }
        }
        catch ( Sneeze s ) {
            System.out.println("Caught Sneeze");
            return ;
        }
        finally {
            System.out.println("Hello World!");
        }
    }
}

輸出為:

Caught Annoyance

Caught Sneeze

Hello World!

288.Error和Exception的區別

Error類(lèi),表示僅靠程序本身無(wú)法恢復的嚴重錯誤,比如說(shuō)內存溢出、動(dòng)態(tài)鏈接異常、虛擬機錯誤。應用程序不應該拋出這種類(lèi)型的對象。假如出現這種錯誤,除了盡力使程序安全退出外,在其他方面是無(wú)能為力的。所以在進(jìn)行程序設計時(shí),應該更關(guān)注Exception類(lèi)。

Exception類(lèi),由Java應用程序拋出和處理的非嚴重錯誤,比如所需文件沒(méi)有找到、零作除數,數組下標越界等。它的各種不同子類(lèi)分別對應不同類(lèi)型異常??煞譃閮深?lèi):Checked異常和Runtime異常

289.Java異常處理try-catch-finally的執行過(guò)程

try-catch-finally程序塊的執行流程以及執行結果比較復雜。

基本執行過(guò)程如下:

1)程序首先執行可能發(fā)生異常的try語(yǔ)句塊。

2)如果try語(yǔ)句沒(méi)有出現異常則執行完后跳至finally語(yǔ)句塊執行;

3)如果try語(yǔ)句出現異常,則中斷執行并根據發(fā)生的異常類(lèi)型跳至相應的catch語(yǔ)句塊執行處理。

4)catch語(yǔ)句塊可以有多個(gè),分別捕獲不同類(lèi)型的異常。

5)catch語(yǔ)句塊執行完后程序會(huì )繼續執行finally語(yǔ)句塊。

finally語(yǔ)句是可選的,如果有的話(huà),則不管是否發(fā)生異常,finally語(yǔ)句都會(huì )被執行。需要注意的是即使try和catch塊中存在return語(yǔ)句,finally語(yǔ)句也會(huì )執行,是在執行完finally語(yǔ)句后再通過(guò)return退出。

290.異常處理中throws和throw的區別

1)作用不同:

throw用于程序員自行產(chǎn)生并拋出異常;

throws用于聲明在該方法內拋出了異常

2) 使用的位置不同:

throw位于方法體內部,可以作為單獨語(yǔ)句使用;

throws必須跟在方法參數列表的后面,不能單獨使用。

3)內容不同:

throw拋出一個(gè)異常對象,且只能是一個(gè);

throws后面跟異常類(lèi),而且可以有多個(gè)。

Web方面相關(guān):
291.WEB應用中如果有.class和.jar類(lèi)型的文件一般分別應該放在什么位置?

答:.class文件放在WEB-INF/classes文件下,.jar文件放在WEB-INF/lib文件夾下

292.元素中有一個(gè)輸入框(< input type='text' name=”username”id=”username”value=””/>,請用JavaScript語(yǔ)言寫(xiě)一行代碼,取得這個(gè)輸入框中的值。

答:document.getElementById(“username”).value;

293.簡(jiǎn)單描述一下Servlet與JSP的的相同點(diǎn)和區別點(diǎn)。

區別:

JSP是在HTML代碼里寫(xiě)JAVA代碼,框架是HTML;而Servlet是在JAVA代碼中寫(xiě)HTML代碼,本身是個(gè)JAVA類(lèi)。

JSP使人們把顯示和邏輯分隔成為可能,這意味著(zhù)兩者的開(kāi)發(fā)可并行進(jìn)行;而Servlet并沒(méi)有把兩者分開(kāi)。

Servlet獨立地處理靜態(tài)表示邏輯與動(dòng)態(tài)業(yè)務(wù)邏輯.這樣,任何文件的變動(dòng)都需要對此服務(wù)程序重新編譯;JSP允許用特殊標簽直接嵌入到HTML頁(yè)面, HTML內容與JAVA內容也可放在單獨文件中,HTML內容的任何變動(dòng)會(huì )自動(dòng)編譯裝入到服務(wù)程序.

Servlet需要在web.xml中配置,而JSP無(wú)需配置。

目前JSP主要用在視圖層,負責顯示,而Servlet主要用在控制層,負責調度

聯(lián)系:

都是Sun公司推出的動(dòng)態(tài)網(wǎng)頁(yè)技術(shù)。

先有Servlet,針對Servlet缺點(diǎn)推出JSP。JSP是Servlet的一種特殊形式,每個(gè)JSP頁(yè)面就是一個(gè)Servlet實(shí)例——JSP頁(yè)面由系統翻譯成Servlet,Servlet再負責響應用戶(hù)請求。

294.請簡(jiǎn)單描述下幾個(gè)您熟悉JavaScript庫,它們有哪些作用和特點(diǎn)?

JavaScript 高級程序設計(特別是對瀏覽器差異的復雜處理),通常很困難也很耗時(shí)。為了應對這些調整,許多的 JavaScript庫應運而生。這些 JavaScript 庫常被稱(chēng)為 JavaScript 框架。

jQuery:

Ext JS - 可定制的 widget,用于構建富因特網(wǎng)應用程序(rich Internet applications)。

Prototype

MooTools。

YUI - Yahoo! User Interface Framework,涵蓋大量函數的大型庫,從簡(jiǎn)單的 JavaScript 功能到完整的 internet widget。

295.簡(jiǎn)單描述HTML,CSS,Javascript在Web開(kāi)發(fā)中分別起什么作用?

1、什么是HTML(超文本標記語(yǔ)言 Hyper Text Markup Language),HTML 是用來(lái)描述網(wǎng)頁(yè)的一種語(yǔ)言。

2、CSS(層疊樣式表 Cascading Style Sheets),樣式定義如何顯示 HTML 元素,語(yǔ)法為:selector {property:value} (選擇符 {屬性:值})

3、JavaScript是一種腳本語(yǔ)言,其源代碼在發(fā)往客戶(hù)端運行之前不需經(jīng)過(guò)編譯,而是將文本格式的字符代碼發(fā)送給瀏覽器由瀏覽器解釋運行

對于一個(gè)網(wǎng)頁(yè),HTML定義網(wǎng)頁(yè)的結構,CSS描述網(wǎng)頁(yè)的樣子,JavaScript設置一個(gè)很經(jīng)典的例子是說(shuō)HTML就像 一個(gè)人的骨骼、器官,而CSS就是人的皮膚,有了這兩樣也就構成了一個(gè)植物人了,加上javascript這個(gè)植物人就可以對外界刺激做出反應,可以思 考、運動(dòng)、可以給自己整容化妝(改變CSS)等等,成為一個(gè)活生生的人。

如果說(shuō)HTML是肉身、CSS就是皮相、Javascript就是靈魂。沒(méi)有Javascript,HTML+CSS是植物人,沒(méi)有Javascript、CSS是個(gè)毀容的植物人。

如果說(shuō)HTML是建筑師,CSS就是干裝修的,Javascript是魔術(shù)師。

296.當DOM加載完成后要執行的函數,下面哪個(gè)是正確的()
A. JQuery(expression, [context])
B. JQuery(html, [ownerDocument])
C. JQuery(callback)
答案:C
297.舉例說(shuō)明JAVA中如何解析xml,不同方式有和優(yōu)缺點(diǎn)?

答:1. DOM(Document Object Model)

DOM是用與平臺和語(yǔ)言無(wú)關(guān)的方式表示XML文檔的官方W3C標準。DOM是以層次結構組織的節點(diǎn)或信息片斷的集合。這個(gè)層次結構允許開(kāi)發(fā)人員在樹(shù)中尋找特定信息。分析該結構通常需要加載整個(gè)文檔和構造層次結構,然后才能做任何工作。由于它是基于信息層次的,因而DOM被認為是基于樹(shù)或基于對象的。

【優(yōu)點(diǎn)】

①允許應用程序對數據和結構做出更改。

②訪(fǎng)問(wèn)是雙向的,可以在任何時(shí)候在樹(shù)中上下導航,獲取和操作任意部分的數據。

【缺點(diǎn)】

①通常需要加載整個(gè)XML文檔來(lái)構造層次結構,消耗資源大。

2. SAX(Simple API for XML)

SAX處理的優(yōu)點(diǎn)非常類(lèi)似于流媒體的優(yōu)點(diǎn)。分析能夠立即開(kāi)始,而不是等待所有的數據被處理。而且,由于應用程序只是在讀取數據時(shí)檢查數據,因此不需要將數據存儲在內存中。這對于大型文檔來(lái)說(shuō)是個(gè)巨大的優(yōu)點(diǎn)。事實(shí)上,應用程序甚至不必解析整個(gè)文檔;它可以在某個(gè)條件得到滿(mǎn)足時(shí)停止解析。一般來(lái)說(shuō),SAX還比它的替代者DOM快許多。

選擇DOM還是選擇SAX? 對于需要自己編寫(xiě)代碼來(lái)處理XML文檔的開(kāi)發(fā)人員來(lái)說(shuō), 選擇DOM還是SAX解析模型是一個(gè)非常重要的設計決策。 DOM采用建立樹(shù)形結構的方式訪(fǎng)問(wèn)XML文檔,而SAX采用的是事件模型。

DOM解析器把XML文檔轉化為一個(gè)包含其內容的樹(shù),并可以對樹(shù)進(jìn)行遍歷。用DOM解析模型的優(yōu)點(diǎn)是編程容易,開(kāi)發(fā)人員只需要調用建樹(shù)的指令,然后利用navigation APIs訪(fǎng)問(wèn)所需的樹(shù)節點(diǎn)來(lái)完成任務(wù)??梢院苋菀椎奶砑雍托薷臉?shù)中的元素。然而由于使用DOM解析器的時(shí)候需要處理整個(gè)XML文檔,所以對性能和內存的要求比較高,尤其是遇到很大的XML文件的時(shí)候。由于它的遍歷能力,DOM解析器常用于XML文檔需要頻繁的改變的服務(wù)中。

SAX解析器采用了基于事件的模型,它在解析XML文檔的時(shí)候可以觸發(fā)一系列的事件,當發(fā)現給定的tag的時(shí)候,它可以激活一個(gè)回調方法,告訴該方法制定的標簽已經(jīng)找到。SAX對內存的要求通常會(huì )比較低,因為它讓開(kāi)發(fā)人員自己來(lái)決定所要處理的tag.特別是當開(kāi)發(fā)人員只需要處理文檔中所包含的部分數據時(shí),SAX這種擴展能力得到了更好的體現。但用SAX解析器的時(shí)候編碼工作會(huì )比較困難,而且很難同時(shí)訪(fǎng)問(wèn)同一個(gè)文檔中的多處不同數據。

【優(yōu)勢】

①不需要等待所有數據都被處理,分析就能立即開(kāi)始。

②只在讀取數據時(shí)檢查數據,不需要保存在內存中。

③可以在某個(gè)條件得到滿(mǎn)足時(shí)停止解析,不必解析整個(gè)文檔。

④效率和性能較高,能解析大于系統內存的文檔。

【缺點(diǎn)】

①需要應用程序自己負責TAG的處理邏輯(例如維護父/子關(guān)系等),文檔越復雜程序就越復雜。

②單向導航,無(wú)法定位文檔層次,很難同時(shí)訪(fǎng)問(wèn)同一文檔的不同部分數據,不支持XPath。

3. JDOM(Java-based Document Object Model)

JDOM的目的是成為Java特定文檔模型,它簡(jiǎn)化與XML的交互并且比使用DOM實(shí)現更快。由于是第一個(gè)Java特定模型,JDOM一直得到大力推廣和促進(jìn)。正在考慮通過(guò)“Java規范請求JSR-102”將它最終用作“Java標準擴展”。從2000年初就已經(jīng)開(kāi)始了JDOM開(kāi)發(fā)。

JDOM與DOM主要有兩方面不同。首先,JDOM僅使用具體類(lèi)而不使用接口。這在某些方面簡(jiǎn)化了API,但是也限制了靈活性。第二,API大量使用了Collections類(lèi),簡(jiǎn)化了那些已經(jīng)熟悉這些類(lèi)的Java開(kāi)發(fā)者的使用。

JDOM文檔聲明其目的是“使用20%(或更少)的精力解決80%(或更多)Java/XML問(wèn)題”(根據學(xué)習曲線(xiàn)假定為20%)。JDOM對于大多數Java/XML應用程序來(lái)說(shuō)當然是有用的,并且大多數開(kāi)發(fā)者發(fā)現API比DOM容易理解得多。JDOM還包括對程序行為的相當廣泛檢查以防止用戶(hù)做任何在XML中無(wú)意義的事。然而,它仍需要您充分理解XML以便做一些超出基本的工作(或者甚至理解某些情況下的錯誤)。這也許是比學(xué)習DOM或JDOM接口都更有意義的工作。

JDOM自身不包含解析器。它通常使用SAX2解析器來(lái)解析和驗證輸入XML文檔(盡管它還可以將以前構造的DOM表示作為輸入)。它包含一些轉換器以將JDOM表示輸出成SAX2事件流、DOM模型或XML文本文檔。JDOM是在A(yíng)pache許可證變體下發(fā)布的開(kāi)放源碼。

【優(yōu)點(diǎn)】

①使用具體類(lèi)而不是接口,簡(jiǎn)化了DOM的API。

②大量使用了Java集合類(lèi),方便了Java開(kāi)發(fā)人員。

【缺點(diǎn)】

①沒(méi)有較好的靈活性。

②性能較差。

4. DOM4J(Document Object Model for Java)

雖然DOM4J代表了完全獨立的開(kāi)發(fā)結果,但最初,它是JDOM的一種智能分支。它合并了許多超出基本XML文檔表示的功能,包括集成的XPath支持、XML Schema支持以及用于大文檔或流化文檔的基于事件的處理。它還提供了構建文檔表示的選項,它通過(guò)DOM4J API和標準DOM接口具有并行訪(fǎng)問(wèn)功能。從2000下半年開(kāi)始,它就一直處于開(kāi)發(fā)之中。

為支持所有這些功能,DOM4J使用接口和抽象基本類(lèi)方法。DOM4J大量使用了API中的Collections類(lèi),但是在許多情況下,它還提供一些替代方法以允許更好的性能或更直接的編碼方法。直接好處是,雖然DOM4J付出了更復雜的API的代價(jià),但是它提供了比JDOM大得多的靈活性。

在添加靈活性、XPath集成和對大文檔處理的目標時(shí),DOM4J的目標與JDOM是一樣的:針對Java開(kāi)發(fā)者的易用性和直觀(guān)操作。它還致力于成為比JDOM更完整的解決方案,實(shí)現在本質(zhì)上處理所有Java/XML問(wèn)題的目標。在完成該目標時(shí),它比JDOM更少強調防止不正確的應用程序行為。

DOM4J是一個(gè)非常非常優(yōu)秀的Java XML API,具有性能優(yōu)異、功能強大和極端易用使用的特點(diǎn),同時(shí)它也是一個(gè)開(kāi)放源代碼的軟件。如今你可以看到越來(lái)越多的Java軟件都在使用DOM4J來(lái)讀寫(xiě)XML,特別值得一提的是連Sun的JAXM也在用DOM4J.

【優(yōu)點(diǎn)】

①大量使用了Java集合類(lèi),方便Java開(kāi)發(fā)人員,同時(shí)提供一些提高性能的替代方法。

②支持XPath。

③有很好的性能。

【缺點(diǎn)】

①大量使用了接口,API較為復雜。

二、比較

1. DOM4J性能最好,連Sun的JAXM也在用DOM4J。目前許多開(kāi)源項目中大量采用DOM4J,例如大名鼎鼎的Hibernate也用DOM4J來(lái)讀取XML配置文件。如果不考慮可移植性,那就采用DOM4J.

2. JDOM和DOM在性能測試時(shí)表現不佳,在測試10M文檔時(shí)內存溢出,但可移植。在小文檔情況下還值得考慮使用DOM和JDOM.雖然JDOM的開(kāi)發(fā)者已經(jīng)說(shuō)明他們期望在正式發(fā)行版前專(zhuān)注性能問(wèn)題,但是從性能觀(guān)點(diǎn)來(lái)看,它確實(shí)沒(méi)有值得推薦之處。另外,DOM仍是一個(gè)非常好的選擇。DOM實(shí)現廣泛應用于多種編程語(yǔ)言。它還是許多其它與XML相關(guān)的標準的基礎,因為它正式獲得W3C推薦(與基于非標準的Java模型相對),所以在某些類(lèi)型的項目中可能也需要它(如在JavaScript中使用DOM)。

3. SAX表現較好,這要依賴(lài)于它特定的解析方式-事件驅動(dòng)。一個(gè)SAX檢測即將到來(lái)的XML流,但并沒(méi)有載入到內存(當然當XML流被讀入時(shí),會(huì )有部分文檔暫時(shí)隱藏在內存中)。

我的看法:如果XML文檔較大且不考慮移植性問(wèn)題建議采用DOM4J;如果XML文檔較小則建議采用JDOM;如果需要及時(shí)處理而不需要保存數據則考慮SAX。但無(wú)論如何,還是那句話(huà):適合自己的才是最好的,如果時(shí)間允許,建議大家講這四種方法都嘗試一遍然后選擇一種適合自己的即可。

298.char型變量中能不能存儲一個(gè)中文漢字?

答:1.java采用unicode編碼,2個(gè)字節(16位)來(lái)表示一個(gè)字符, 無(wú)論是漢字還是數字,字母,或其他語(yǔ)言都可以存儲。

2.char 在java中是2個(gè)字節,所以可以存儲中文

299.一個(gè)類(lèi)可以實(shí)現多個(gè)接口,但只能繼承一個(gè)抽象類(lèi)。

下面接著(zhù)再說(shuō)說(shuō)兩者在應用上的區別:

接口更多的是在系統架構設計方法發(fā)揮作用,主要用于定義模塊之間的通信契約。而抽象類(lèi)在代碼實(shí)現方面發(fā)揮作用,可以實(shí)現代碼的重用,例如,模板方法設計模式是抽象類(lèi)的一個(gè)典型應用,假設某個(gè)項目的所有Servlet類(lèi)都要用相同的方式進(jìn)行權限判斷、記錄訪(fǎng)問(wèn)日志和處理異常,那么就可以定義一個(gè)抽象的基類(lèi),讓所有的Servlet都繼承這個(gè)抽象基類(lèi),在抽象基類(lèi)的service方法中完成權限判斷、記錄訪(fǎng)問(wèn)日志和處理異常的代碼,在各個(gè)子類(lèi)中只是完成各自的業(yè)務(wù)邏輯代碼,偽代碼如下:

public abstract classBaseServlet extends HttpServlet{
        public final void service(HttpServletRequest request,HttpServletResponse response) throws IOExcetion,ServletException       {
               記錄訪(fǎng)問(wèn)日志
               進(jìn)行權限判斷
if(具有權限){
       try{
              doService(request,response);
}
       catch(Excetpion e)  {
                     記錄異常信息
       }
}
        }
        protected abstract void doService(HttpServletRequest request,HttpServletResponse response) throws IOExcetion,ServletException;
//注意訪(fǎng)問(wèn)權限定義成protected,顯得既專(zhuān)業(yè),又嚴謹,因為它是專(zhuān)門(mén)給子類(lèi)用的
}

public class MyServlet1 extendsBaseServlet
{
protected voiddoService(HttpServletRequest request, HttpServletResponse response) throwsIOExcetion,ServletException
        {
               本Servlet只處理的具體業(yè)務(wù)邏輯代碼
        }

}

父類(lèi)方法中間的某段代碼不確定,留給子類(lèi)干,就用模板方法設計模式。

備注:這道題的思路是先從總體解釋抽象類(lèi)和接口的基本概念,然后再比較兩者的語(yǔ)法細節,最后再說(shuō)兩者的應用區別。比較兩者語(yǔ)法細節區別的條理是:先從一個(gè)類(lèi)中的構造方法、普通成員變量和方法(包括抽象方法),靜態(tài)變量和方法,繼承性等6個(gè)方面逐一去比較回答,接著(zhù)從第三者繼承的角度的回答,特別是最后用了一個(gè)典型的例子來(lái)展現自己深厚的技術(shù)功底。

300.比較一下Java 和JavaSciprt

答:JavaScript 與Java是兩個(gè)公司開(kāi)發(fā)的不同的兩個(gè)產(chǎn)品。Java 是原Sun 公司推出的面向對象的程序設計語(yǔ)言,特別適合于互聯(lián)網(wǎng)應用程序開(kāi)發(fā);而JavaScript是Netscape公司的產(chǎn)品,為了擴展Netscape瀏覽器的功能而開(kāi)發(fā)的一種可以嵌入Web頁(yè)面中運行的基于對象和事件驅動(dòng)的解釋性語(yǔ)言,它的前身是LiveScript;而Java 的前身是Oak語(yǔ)言。

下面對兩種語(yǔ)言間的異同作如下比較:

1)基于對象和面向對象:Java是一種真正的面向對象的語(yǔ)言,即使是開(kāi)發(fā)簡(jiǎn)單的程序,必須設計對象;JavaScript是種腳本語(yǔ)言,它可以用來(lái)制作與網(wǎng)絡(luò )無(wú)關(guān)的,與用戶(hù)交互作用的復雜軟件。它是一種基于對象(Object-Based)和事件驅動(dòng)(Event-Driven)的編程語(yǔ)言。因而它本身提供了非常豐富的內部對象供設計人員使用;

2)解釋和編譯:Java 的源代碼在執行之前,必須經(jīng)過(guò)編譯;JavaScript 是一種解釋性編程語(yǔ)言,其源代碼不需經(jīng)過(guò)編譯,由瀏覽器解釋執行;

3)強類(lèi)型變量和類(lèi)型弱變量:Java采用強類(lèi)型變量檢查,即所有變量在編譯之前必須作聲明;JavaScript中變量聲明,采用其弱類(lèi)型。即變量在使用前不需作聲明,而是解釋器在運行時(shí)檢查其數據類(lèi)型;

4)代碼格式不一樣。

補充:上面列出的四點(diǎn)是原來(lái)所謂的標準答案中給出的。其實(shí)Java和JavaScript最重要的區別是一個(gè)是靜態(tài)語(yǔ)言,一個(gè)是動(dòng)態(tài)語(yǔ)言。目前的編程語(yǔ)言的發(fā)展趨勢是函數式語(yǔ)言和動(dòng)態(tài)語(yǔ)言。在Java中類(lèi)(class)是一等公民,而JavaScript中函數(function)是一等公民。對于這種問(wèn)題,在面試時(shí)還是用自己的語(yǔ)言回答會(huì )更加靠譜。?

301.什么時(shí)候用assert?

答:assertion(斷言)在軟件開(kāi)發(fā)中是一種常用的調試方式,很多開(kāi)發(fā)語(yǔ)言中都支持這種機制。一般來(lái)說(shuō),assertion用于保證程序最基本、關(guān)鍵的正確性。assertion檢查通常在開(kāi)發(fā)和測試時(shí)開(kāi)啟。為了提高性能,在軟件發(fā)布后, assertion檢查通常是關(guān)閉的。在實(shí)現中,斷言是一個(gè)包含布爾表達式的語(yǔ)句,在執行這個(gè)語(yǔ)句時(shí)假定該表達式為true;如果表達式計算為false,那么系統會(huì )報告一個(gè)AssertionError。

斷言用于調試目的:

assert(a > 0); // throws an AssertionError if a <= 0

斷言可以有兩種形式:

assert Expression1;

assert Expression1 : Expression2 ;

Expression1 應該總是產(chǎn)生一個(gè)布爾值。

Expression2 可以是得出一個(gè)值的任意表達式;這個(gè)值用于生成顯示更多調試信息的字符串消息。

斷言在默認情況下是禁用的,要在編譯時(shí)啟用斷言,需使用source 1.4 標記:

javac -source 1.4 Test.java

要在運行時(shí)啟用斷言,可使用-enableassertions 或者-ea 標記。

要在運行時(shí)選擇禁用斷言,可使用-da 或者-disableassertions 標記。

要在系統類(lèi)中啟用斷言,可使用-esa 或者-dsa 標記。還可以在包的基礎上啟用或者禁用斷言??梢栽陬A計正常情況下不會(huì )到達的任何位置上放置斷言。斷言可以用于驗證傳遞給私有方法的參數。不過(guò),斷言不應該用于驗證傳遞給公有方法的參數,因為不管是否啟用了斷言,公有方法都必須檢查其參數。不過(guò),既可以在公有方法中,也可以在非公有方法中利用斷言測試后置條件。另外,斷言不應該以任何方式改變程序的狀態(tài)。?

302.UML是什么?UML中有哪些圖?

答:UML是統一建模語(yǔ)言(Unified Modeling Language)的縮寫(xiě),它發(fā)表于1997年,綜合了當時(shí)已經(jīng)存在的面向對象的建模語(yǔ)言、方法和過(guò)程,是一個(gè)支持模型化和軟件系統開(kāi)發(fā)的圖形化語(yǔ)言,為軟件開(kāi)發(fā)的所有階段提供模型化和可視化支持。使用UML可以幫助溝通與交流,輔助應用設計和文檔的生成,還能夠闡釋系統的結構和行為。UML定義了多種圖形化的符號來(lái)描述軟件系統部分或全部的靜態(tài)結構和動(dòng)態(tài)結構,包括:用例圖(use case diagram)、類(lèi)圖(class diagram)、時(shí)序圖(sequence diagram)、協(xié)作圖(collaboration diagram)、狀態(tài)圖(statechart diagram)、活動(dòng)圖(activity diagram)、構件圖(component diagram)、部署圖(deployment diagram)等。在這些圖形化符號中,有三種圖最為重要,分別是:用例圖(用來(lái)捕獲需求,描述系統的功能,通過(guò)該圖可以迅速的了解系統的功能模塊及其關(guān)系)、類(lèi)圖(描述類(lèi)以及類(lèi)與類(lèi)之間的關(guān)系,通過(guò)該圖可以快速了解系統)、時(shí)序圖(描述執行特定任務(wù)時(shí)對象之間的交互關(guān)系以及執行順序,通過(guò)該圖可以了解對象能接收的消息也就是說(shuō)對象能夠向外界提供的服務(wù))。

用例圖:

303.XML 文檔定義有幾種形式?它們之間有何本質(zhì)區別?解析XML 文檔有哪幾種方式?

答: XML文檔定義分為DTD和Schema兩種形式;其本質(zhì)區別在于Schema本身也是一個(gè)XML文件,可以被XML解析器解析。對XML的解析主要有DOM(文檔對象模型)、SAX、StAX(JDK 1.6中引入的新的解析XML的方式,Streaming API for XML) 等,其中DOM處理大型文件時(shí)其性能下降的非常厲害,這個(gè)問(wèn)題是由DOM 的樹(shù)結構所造成的,這種結構占用的內存較多,而且DOM 必須在解析文件之前把整個(gè)文檔裝入內存,適合對XML 的隨機訪(fǎng)問(wèn)(典型的用空間換取時(shí)間的策略);SAX是事件驅動(dòng)型的XML解析方式,它順序讀取XML文件,不需要一次全部裝載整個(gè)文件。當遇到像文件開(kāi)頭,文檔結束,或者標簽開(kāi)頭與標簽結束時(shí),它會(huì )觸發(fā)一個(gè)事件,用戶(hù)通過(guò)在其回調事件中寫(xiě)入處理代碼來(lái)處理XML文件,適合對XML 的順序訪(fǎng)問(wèn);如其名稱(chēng)所暗示的那樣,StAX把重點(diǎn)放在流上。實(shí)際上,StAX與其他方法的區別就在于應用程序能夠把XML作為一個(gè)事件流來(lái)處理。將XML作為一組事件來(lái)處理的想法并不新穎(事實(shí)上 SAX 已經(jīng)提出來(lái)了),但不同之處在于StAX允許應用程序代碼把這些事件逐個(gè)拉出來(lái),而不用提供在解析器方便時(shí)從解析器中接收事件的處理程序。?

304.你在項目中哪些地方用到了XML?

答: XML的主要作用有兩個(gè)方面:數據交換(曾經(jīng)被稱(chēng)為業(yè)界數據交換的事實(shí)標準,現在此項功能在很多時(shí)候都被JSON取代)和信息配置。在做數據交換時(shí),XML將數據用標簽組裝成起來(lái),然后壓縮打包加密后通過(guò)網(wǎng)絡(luò )傳送給接收者,接收解密與解壓縮后再從XML文件中還原相關(guān)信息進(jìn)行處理。目前很多軟件都使用XML來(lái)存儲配置信息,很多項目中我們通常也會(huì )將作為配置的硬代碼(hard code)寫(xiě)在XML文件中,Java的很多框架也是這么做的。?

305.用JavaScript實(shí)現用正則表達式驗證,某個(gè)字符串是合法的6位數字的郵編的函數
Function testE(ss){
  var reg=/^[1-9][0-9]{5}$/;
  if(req.test(ss)){
    alert(“郵編OK”)
}else{
  alert(“郵編格式不正確”);
}
}
306.請使用JQuery將頁(yè)面上的所有元素邊框設置為2pix寬的虛線(xiàn)?

$(“*”).css(“border”,”2px dashed”)

307.如何設定JQuery異步調用還是同步調用?

答案:調用jQuery中的ajax函數,設置其async屬性來(lái)表明是異步還是同步,如下:

$.ajax({
async:true//表示異步,false表示同步
})

308.說(shuō)出3條以上firefox和IE的瀏覽器兼容問(wèn)題?

答案:兼容firefox的 outerHTML,FF中沒(méi)有outerHtml的方法

IE下,可以使用()或[]獲取集合類(lèi)對象;Firefox下,只能使用[]獲取集合類(lèi)對象.解決方法:統一使用[]獲取集合類(lèi)對象.

IE下,可以使用獲取常規屬性的方法來(lái)獲取自定義屬性,也可以使用getAttribute()獲取自定義屬性;Firefox下,只能使用getAttribute()獲取自定義屬性.解決方法:統一通過(guò)getAttribute()獲取自定義屬性

309.請用Jquery語(yǔ)言寫(xiě)出ajax請求或者post請求代碼
$.post(“show”,{uname=”張三”,pwd=”123”},function(data){
  alert(data)
})
310.body中的onload ()函數和jQuery中document.ready()有什么區別?

答案:ready 事件的觸發(fā),表示文檔結構已經(jīng)加載完成(不包含圖片等非文字媒體文件)

onload 事件的觸發(fā),表示頁(yè)面包含圖片等文件在內的所有元素都加載完成。

311.jQuery中有哪幾種類(lèi)型的選擇器?

答案:

基本選擇器

層次選擇器

基本過(guò)濾選擇器

內容過(guò)濾選擇器

可見(jiàn)性過(guò)濾選擇器

屬性過(guò)濾選擇器

子元素過(guò)濾選擇器

表單選擇器

表單過(guò)濾選擇器

312.EasyUI中datagrid刷新當前數據的方法?

答案:使用reload()即可

313.分別寫(xiě)出一個(gè)div居中和其中的內容居中的css屬性設置

Div居中:

margin:auto 0px;

內容居中:

text-align:center;

314.概述一下session與cookie的區別

答案:

存儲角度:

Session是服務(wù)器端的數據存儲技術(shù),cookie是客戶(hù)端的數據存儲技術(shù)

解決問(wèn)題角度:

Session解決的是一個(gè)用戶(hù)不同請求的數據共享問(wèn)題,cookie解決的是不同請求的請求數據的共享問(wèn)題

生命周期角度:

Session的id是依賴(lài)于cookie來(lái)進(jìn)行存儲的,瀏覽器關(guān)閉id就會(huì )失效

Cookie可以單獨的設置其在瀏覽器的存儲時(shí)間。

315.JavaScript 中 null和 undefined 是否有區別?有哪些區別?

答案:

賦值角度說(shuō)明:

null 表示此處沒(méi)有值,undefined表示此處定義了但是沒(méi)有賦值

從數據轉換角度:

Null在做數值轉換時(shí)會(huì )被轉換為0,undefined會(huì )被轉換為NaN

316.Servlet中的doPost和doGet方法有什么區別?它們在傳遞和獲取參數上有什么區別?

答案:

區別:doPost用來(lái)處理post請求,doGet用來(lái)處理get請求,獲取參數:獲取的參數是相同的都是HttpServletRequest \HttpServletResponse

317.請寫(xiě)出一段jQuery代碼,實(shí)現把當前頁(yè)面中所有的a元索中class 屬性為“view-link”的鏈接都改為在新窗口中打開(kāi)

答案:$(“a[class=view-link]”).attr(“target”,”_blank”)

318.如下JavaScript代碼的輸出為:
var scope ="global scope";
function checkscope() {
var scope ="local scope”;
 return function() { return scope}
}
console.log (checkscope()());

319.Jquery中’.get()’與’.eq()’的區別

eq返回的是一個(gè)jquery對象 get返回的是一個(gè)html對象

320.如何給weblogic定內存的大???

在啟動(dòng)Weblogic的腳本中(位于所在Domian對應服務(wù)器目錄下的startServerName),增加set MEM_ARGS=-Xms32m -Xmx200m,可以調整最小內存為32M,最大200M

321.TCP為何采用三次握手來(lái)建立連接,若釆用二次握手可以嗎,請說(shuō)明理由?

三次握手是為了防止已失效的連接請求再次傳送到服務(wù)器端。 二次握手不可行,因為:如果由于網(wǎng)絡(luò )不穩定,雖然客戶(hù)端以前發(fā)送的連接請求以到達服務(wù)方,但服務(wù)方的同意連接的應答未能到達客戶(hù)端。則客戶(hù)方要重新發(fā)送連接請求,若采用二次握手,服務(wù)方收到重傳的請求連接后,會(huì )以為是新的請求,就會(huì )發(fā)送同意連接報文,并新開(kāi)進(jìn)程提供服務(wù),這樣會(huì )造成服務(wù)方資源的無(wú)謂浪費

322.以下HTTP相應狀態(tài)碼的含義描述正確的是()
A. 200ok表示請求成功
B. 400不良請求表示服務(wù)器未發(fā)現與請求URL匹配內容
C. 404未發(fā)現表示由于語(yǔ)法錯誤兒導致服務(wù)器無(wú)法理解請求信息
D. 500內部服務(wù)器錯誤,無(wú)法處理請求
答案:D
分析:
A 200ok 表示的意思是一切正常。一般用于相應GET和POST請求。這個(gè)狀態(tài)碼對servlet是缺省的;如果沒(méi)有調用setStatus方法的話(huà),就會(huì )得到200。
B 400 表示指出客戶(hù)端請求中的語(yǔ)法錯誤
C 404 客戶(hù)端所給的地址無(wú)法找到任何資源
323.JSP頁(yè)面包括哪些元素?()
A. JSP命令
B. JSP Action
C. JSP腳本
D. JSP控件
答案:C
分析:JSP頁(yè)面元素構成如下,因此ABD錯誤
A 200ok 表示的意思是一切正常。一般用于相應GET和POST請求。這個(gè)狀態(tài)碼對servlet是缺省的;如果沒(méi)有調用setStatus方法的話(huà),就會(huì )得到200。
B 400 表示指出客戶(hù)端請求中的語(yǔ)法錯誤
C 404 客戶(hù)端所給的地址無(wú)法找到任何資源
324.Ajax有四種技術(shù)組成:DOM,CSS,JavaScript,XmlHttpRequest,其中控制文檔結構的是()
A. DOM
B. CSS
C. JavaScript
D. XmlHttpRequest
答案:A
325.下面關(guān)于session的用法哪些是錯誤的?()
A. HttpSession session=new HttpSession();
B. String haha=session getParameler(:haha”);
C. session.removeAttribute(“haha”);
D. session.setAttribute(:haha:);XmlHttpRequest
答案:A
326.Jsp九大內置對象

答案:1、request對象

request 對象是 javax.servlet.httpServletRequest類(lèi)型的對象。 該對象代表了客戶(hù)端的請求信息,主要用于接受通過(guò)HTTP協(xié)議傳送到服務(wù)器的數據。(包括頭信息、系統信息、請求方式以及請求參數等)。request對象的作用域為一次請求。

2、response對象

response 代表的是對客戶(hù)端的響應,主要是將JSP容器處理過(guò)的對象傳回到客戶(hù)端。response對象也具有作用域,它只在JSP頁(yè)面內有效。

3、session對象

session 對象是由服務(wù)器自動(dòng)創(chuàng )建的與用戶(hù)請求相關(guān)的對象。服務(wù)器為每個(gè)用戶(hù)都生成一個(gè)session對象,用于保存該用戶(hù)的信息,跟蹤用戶(hù)的操作狀態(tài)。session對象內部使用Map類(lèi)來(lái)保存數據,因此保存數據的格式為 “Key/value”。 session對象的value可以使復雜的對象類(lèi)型,而不僅僅局限于字符串類(lèi)型。

4、application對象

?application 對象可將信息保存在服務(wù)器中,直到服務(wù)器關(guān)閉,否則application對象中保存的信息會(huì )在整個(gè)應用中都有效。與session對象相比,application對象生命周期更長(cháng),類(lèi)似于系統的“全局變量”。

5、out 對象

out 對象用于在Web瀏覽器內輸出信息,并且管理應用服務(wù)器上的輸出緩沖區。在使用 out 對象輸出數據時(shí),可以對數據緩沖區進(jìn)行操作,及時(shí)清除緩沖區中的殘余數據,為其他的輸出讓出緩沖空間。待數據輸出完畢后,要及時(shí)關(guān)閉輸出流。

6、pageContext 對象

pageContext 對象的作用是取得任何范圍的參數,通過(guò)它可以獲取 JSP頁(yè)面的out、request、reponse、session、application 等對象。pageContext對象的創(chuàng )建和初始化都是由容器來(lái)完成的,在JSP頁(yè)面中可以直接使用 pageContext對象。

7、config 對象

config 對象的主要作用是取得服務(wù)器的配置信息。通過(guò) pageConext對象的 getServletConfig() 方法可以獲取一個(gè)config對象。當一個(gè)Servlet 初始化時(shí),容器把某些信息通過(guò) config對象傳遞給這個(gè) Servlet。 開(kāi)發(fā)者可以在web.xml 文件中為應用程序環(huán)境中的Servlet程序和JSP頁(yè)面提供初始化參數。

8、page 對象

page 對象代表JSP本身,只有在JSP頁(yè)面內才是合法的。 page隱含對象本質(zhì)上包含當前 Servlet接口引用的變量,類(lèi)似于Java編程中的 this 指針。

9、exception 對象

exception 對象的作用是顯示異常信息,只有在包含 isErrorPage="true" 的頁(yè)面中才可以被使用,在一般的JSP頁(yè)面中使用該對象將無(wú)法編譯JSP文件。excepation對象和Java的所有對象一樣,都具有系統提供的繼承結構。exception 對象幾乎定義了所有異常情況。在Java程序中,可以使用try/catch關(guān)鍵字來(lái)處理異常情況; 如果在JSP頁(yè)面中出現沒(méi)有捕獲到的異常,就會(huì )生成 exception 對象,并把 exception 對象傳送到在page指令中設定的錯誤頁(yè)面中,然后在錯誤頁(yè)面中處理相應的 exception 對象。

327.如何配置一個(gè)servlet?

在web.xml中使用如下標簽:

<servlet>
 <servlet-name></servlet-name>
 <servlet-class></servlet-class>
</servlet>
<servlet-mapping>
 <servlet-name></servlet-name>
 <url-pattern></url-pattern>
 </servlet-mapping>
 或者使用注解方式:
@WebServlet(name="servlet", urlPatterns={"/*"})
328.JavaScript,如何定義含有數值1至8的數組?

答: var arr=[1,2,3,4,5,6,7,8]

329.以下JavaScipt語(yǔ)句會(huì )產(chǎn)生運行錯誤的是_()
A. var obj=( );
B. var obj=[ ];
C. var obj=//;
D. var obj=1;
答案:AC
330.在JSP中,下面__()__塊中可以定義一個(gè)新類(lèi):
A. <% %>
B. <% ! %>
C. <%@ %>
D. <%=%>
答案:B
分析:B <% ! %> 可用作聲明
A不正確
C為引用xxx,比如<% @page xxxxx%>
D為表達式
331.HTML含義和版本變化

HTML含義:

Hyper Text Markup Language 超文本標記語(yǔ)言,是一種用來(lái)制作“網(wǎng)頁(yè)”的簡(jiǎn)單標記語(yǔ)言;用HTML編寫(xiě)的超文本文檔稱(chēng)為HTML文檔,HTML文檔的擴展名是html或者htm

版本變化:

HTML1.0——在1993年6月作為IETF工作草案發(fā)布(并非標準)

HTML 2.0——1995年11月作為RFC 1866發(fā)布

HTML 3.2——1997年1月14日,W3C推薦標準

HTML 4.0——1997年12月18日,W3C推薦標準

HTML 4.01(微小改進(jìn))——1999年12月24日,W3C推薦標準

HTML 5—2014年10月28日,W3C推薦標準HTML文檔結構;

HTML 5.1 - 2016年

HTML 5.2 – 2018年最新版本

HTML 5.3 is coming…

332.什么是錨鏈接

錨鏈接是帶有文本的超鏈接??梢蕴D到頁(yè)面的某個(gè)位置,適用于頁(yè)面內容較多,超過(guò)一屏的場(chǎng)合 。分為頁(yè)面內的錨鏈接和頁(yè)面間的錨鏈接 。

例如:1F2F

跳轉到2F標記位置

說(shuō)明:

1.在標記位置利用a標簽的name屬性設置標記。

2.在導航位置通過(guò)a標簽的href屬性用#開(kāi)頭加name屬性值即可跳轉錨點(diǎn)位置。

333.HTML字符實(shí)體的作用及其常用字符實(shí)體

有些字符,比如說(shuō)“<”字符,在HTML中有特殊的含義,因此不能在文本中使用。想要在HTML中顯示一個(gè)小于號“<”,需要用到字符實(shí)體:<或者<

字符實(shí)體擁有三個(gè)部分:一個(gè)and符號(&),一個(gè)實(shí)體名或者一個(gè)實(shí)體號,最后是一個(gè)分號(;)

常用字符實(shí)體:

顯示結果 描述 實(shí)體 實(shí)體號
空格    
< 小于 < <
> 大于 > &#
& and符號 & &
' 單引號 ' (IE不支持) '
" 引號 " "
英鎊 £ £
人民幣元 ¥ ¥
§ 章節 ¥ ¥
? 版權 © ©
334.HTML表單的作用和常用表單項類(lèi)型

表單的作用:

利用表單可以收集客戶(hù)端提交的有關(guān)信息。

常用表單項類(lèi)型:

input標簽
type屬性
功能 input標簽
type屬性
功能
text 單行本框 reset 重置按鈕
password 密碼框 submit 提交按鈕
radio 單選按鈕 textarea 文本域
checkbox 復選框 select 下拉框
button 普通按鈕 hidden 隱藏域

335.表格、框架、div三種HTML布局方式的特點(diǎn)

優(yōu)點(diǎn) 缺點(diǎn) 應用場(chǎng)合
表格 方便排列有規律、結構均勻的內容或數據 產(chǎn)生垃圾代碼、影響頁(yè)面下載時(shí)間、靈活性不大難于修改 內容或數據整齊的頁(yè)面
框架 支持滾動(dòng)條、方便導航 節省頁(yè)面下載時(shí)間等 兼容性不好,保存時(shí)不方便、應用范圍有限 小型商業(yè)網(wǎng)站、論壇后臺管理
Div 代碼精簡(jiǎn)、提高頁(yè)面下載速度、表現和內容分離 比較靈活、難于控制 復雜的不規則頁(yè)面、業(yè)務(wù)種類(lèi)較多的大型商業(yè)網(wǎng)站

336.form中input設置為readonly和disabled的區別

readonly disabled
有效對象 .只針對type為text/password有效 對所有表單元素有效
表單提交 當表單元素設置readonly后,表單提交能將該表單元素的值傳遞出去。 當表單元素設置disabled后,表單提交不能將該表單元素的值傳遞出去。

337.CSS的定義和作用

CSS的定義:CSS是Cascading Style Sheets(層疊樣式表)的簡(jiǎn)稱(chēng)。

CSS是一系列格式規則,它們控制網(wǎng)頁(yè)內容的外觀(guān)。CSS簡(jiǎn)單來(lái)說(shuō)就是用來(lái)美化網(wǎng)頁(yè)用的。

CSS的具體作用包括:

使網(wǎng)頁(yè)豐富多彩,易于控制。

頁(yè)面的精確控制,實(shí)現精美、復雜頁(yè)面 。

338.CSS2常用選擇器類(lèi)型及其含義

選擇器名稱(chēng) 案例 語(yǔ)法格式
標簽選擇器 h3{font-size:24px;font-family:"隸書(shū)“; }< h3>JSP< /h3> 元素標簽名{樣式屬性}
類(lèi)選擇器 .red {color:#F00;} < li class="red">Oracle< /li> . 元素標簽class屬性值{樣式屬性}
ID選擇器 #p1 {background-color:#0F0;} < p id="p1">content< /p> #元素標簽id屬性值{樣式屬性}
包含選擇器 div h3{color:red;} < div> < h3>CSS層疊樣式表< /h3> < /div> 父元素標簽 子元素標簽{ 樣式屬性 }
子選擇器 div>ul{color:blue;} < div> < ul> < li>測試1 < ol> < li>嵌套元素< /li> < li>嵌套元素< /li> < li>嵌套元素< /li> < li>嵌套元素< /li> < /ol> < /li> < li>測試1< /li> < li>測試1< /li> < /ul> < /div> 父元素標簽名>子元素名{ 樣式屬性 }

339.引入樣式的三種方式及其優(yōu)先級別

三種引用方式:

1. 外部樣式表(存放.css文件中)

不需要style標簽

< link rel=”stylesheet” href=”引用文件地址” />

2. 嵌入式樣式表

< style type=“text/css”>

p{color:red;}

< /style>

3.內聯(lián)樣式

標簽屬性名為style

< p style=“color:red;”>< /p>

優(yōu)先級級別:內聯(lián)定義最高、內部CSS次之、外部CSS優(yōu)先級最低。。

340.盒子模型

盒子模型類(lèi)似于生活中的盒子,具有4個(gè)屬性,外邊距,內邊距,邊框,內容。

外邊距:margin,用于設置元素和其他元素之間的距離。

內邊距:padding,用于設置元素內容和邊框之間的距離。

邊框:border,用于設置元素邊框粗細,顏色,線(xiàn)型。

內容:width,height,用于設置元素內容顯示的大小。

例如:

<style>
    body{
      margin: 0;  /*取消body默認的外邊距*/
    }
#img1{
width:200px;   /*設置圖片的寬度*/
border: 2px solid black; /*設置圖片邊框*/
margin: 5px;
/*設置圖片外邊距(表示該圖片與其他圖片的距離為5px)*/
padding:10px; /*設置圖片與邊框之間的距離*/
}
#img2{
height: 200px; /* 設置圖片的高度*/
border: 2px solid black; /*設置圖片的邊框*/
margin: 5px; /*設置圖片外邊距*/
padding: 20px; /*設置圖片與邊框之間的距離*/
}
</style>
<img id="img1" src="img/2.jpg" />
<img id="img2" src="img/lss.jpg" />

341.JavaScript語(yǔ)言及其特點(diǎn)

Javascript一種基于對象(object-based)和事件驅動(dòng)(Event Driven)的簡(jiǎn)單的并具有安全性能的腳本語(yǔ)言。特點(diǎn):

解釋性: JavaScript不同于一些編譯性的程序語(yǔ)言,例如C、C++等,它是一種解釋性的程序語(yǔ)言,它的源代碼不需要經(jīng)過(guò)編譯,而直接在瀏覽器中運行時(shí)被解釋。

基于對象:?JavaScript是一種基于對象的語(yǔ)言。這意味著(zhù)它能運用自己已經(jīng)創(chuàng )建的對象。因此,許多功能可以來(lái)自于腳本環(huán)境中對象的方法與腳本的相互作用。

事件驅動(dòng): JavaScript可以直接對用戶(hù)或客戶(hù)輸入做出響應,無(wú)須經(jīng)過(guò)Web服務(wù)程序。它對用戶(hù)的響應,是以事件驅動(dòng)的方式進(jìn)行的。所謂事件驅動(dòng),就是指在主頁(yè)中執行了某種操作所產(chǎn)生的動(dòng)作,此動(dòng)作稱(chēng)為“事件”。比如按下鼠標、移動(dòng)窗口、選擇菜單等都可以視為事件。當事件發(fā)生后,可能會(huì )引起相應的事件響應。

跨平臺:JavaScript依賴(lài)于瀏覽器本身,與操作環(huán)境無(wú)關(guān),只要能運行瀏覽器的計算機,并支持JavaScript的瀏覽器就可正確執行。

342.JavaScript常用數據類(lèi)型有哪些

1、數值型(Number):整數和浮點(diǎn)數統稱(chēng)為數值。例如85或3.1415926等。

2、字符串型(String):由0個(gè),1個(gè)或多個(gè)字符組成的序列。在JavaScript中,用雙引號或單引號括起來(lái)表示,如“您好”、‘學(xué)習JavaScript’等。 不區分單引號、雙引號。

3、邏輯(布爾)型(Boolean):用true或false來(lái)表示。

4、空(null)值(Null):表示沒(méi)有值,用于定義空的或不存在的引用。

要注意,空值不等同于空字符串""或0。

5、未定義(Undefined)值:它也是一個(gè)保留字。表示變量雖然已經(jīng)聲明,但卻沒(méi)有賦值。

除了以上五種基本的數據類(lèi)型之外,JavaScript還支持復合數據類(lèi)型,包括對象和數組兩種。

343.html語(yǔ)法中哪條命令用于使一行文本折行,而不是插入一個(gè)新的段落? (B)

A. < TD>
B. < BR>
C. < P>
D. < H1>
分析:
A < td>定義標準表格
C < p>表示文本一個(gè)段落
D < h1>表示對文本標題進(jìn)行強調的一種標簽

344.Ajax的優(yōu)點(diǎn)和缺點(diǎn)

優(yōu)點(diǎn):減輕服務(wù)器的負擔,按需取數據,最大程度的減少冗余請求,局部刷新頁(yè)面,減少用戶(hù)心理和實(shí)際的等待時(shí)間,帶來(lái)更好的用戶(hù)體驗,基于xml標準化,并被廣泛支持,不需安裝插件等,進(jìn)一步促進(jìn)頁(yè)面和數據的分離

缺點(diǎn):AJAX大量的使用了javascript和ajax引擎,這些取決于瀏覽器的支持.在編寫(xiě)的時(shí)候考慮對瀏覽器的兼容性.

345.怎樣防止表單刷新重復提交問(wèn)題?(說(shuō)出思路即可)

JS腳本方式:

第一種:定義全局變量,在form提交前判斷是否已有提交過(guò)

<script>
   var checkSubmitFlg = false;
   function checkSubmit(){
     if(checkSubmitFlg == true){
return false;
     }
     checkSubmitFlg = true;
     return true;
  }
 </script>
<form action="" onsubmit="return checkSubmit();">
</form>

第二種:?jiǎn)螕籼峤话粹o后,立刻禁用改按鈕

第三種:?jiǎn)螕籼峤话粹o后,彈出屏蔽層,防止用戶(hù)第二次點(diǎn)擊

346.JQuery.get()和JQuery.ajax()方法之間的區別是什么?

JQuery.ajax()是對原生的javaScript的ajax的封裝,簡(jiǎn)化了ajax的步驟,用戶(hù)可用JQuery.ajax()發(fā)送get或者post方式請求,Jquery.get()是對ajax的get方式的封裝,只能發(fā)送get方式的請求。

347.Jquery里的緩存問(wèn)題如何解決?例如($.ajax()以及$.get())

$.ajax()請求時(shí)候加上cache:false的參數,如:

$.ajax({
    type : "get",
    url : "XX",
    dataType : "json",
    cache:false,
    success : function(json) {
    }
});

$.get()請求時(shí)候加上時(shí)間,如:

$.get("url","data"+new Date(),function(data){});

348.Javascript是面向對象的,怎么體現Javascript的繼承關(guān)系?

Javascript里面沒(méi)有像java那樣的繼承,javascript中的繼承機制僅僅是靠模擬的,可以使用prototype原型來(lái)實(shí)現

349.Javascript的有幾種種變量。變量范圍有什么不同?

可以分為三種

1、原生類(lèi)型(string,number,boolean)

2、對象(Date,Array)

3、特殊類(lèi)型(var vara;(只什么沒(méi)有定義),var varb = null;(定義一個(gè)變量并賦值為null))

350.Js如何獲取頁(yè)面的dom對象

1、直接獲取

//1.1 -- id方式獲取

var varid = document.getElementById("unameid");

//1.2 -- name獲取(獲取的是數組對象)

var varname = document.getElementsByName("sex");

//1.3 -- 元素獲取(獲取的是數組對象)

var varinput = document.getElementsByTagName("input");

2、間接方式獲取

//2.1 父子關(guān)系 --childNodes

var varchilds = document.getElementById("div01").childNodes;

//2.2 子父關(guān)系--parentNode

var varfather2 = document.getElementById("unameid").parentNode;

//2.3 兄弟之間相互獲取 nextSibling:下一個(gè)節點(diǎn) previousSibling:上一個(gè)節點(diǎn)

351.Servlet API中forward() 與redirect()的區別?

答:為實(shí)現程序的模塊化,就需要保證在不同的Servlet之間可以相互跳轉,而Servlet中主要有兩種實(shí)現跳轉的方式:FORWARD方式與redirect方式。?

Forward() : 是服務(wù)器內部的重定向,服務(wù)器直接訪(fǎng)問(wèn)目標地址的URL,把那個(gè)URL的響應內容讀取出來(lái),而客戶(hù)端并不知道,因此在客戶(hù)端瀏覽器的地址欄里不會(huì )顯示跳轉后的地址,還是原來(lái)的地址。由于在整個(gè)定向的過(guò)程中用的是同一個(gè)Request,因此FORWARD會(huì )將Request的信息帶到被定向的JSP或Servlet中使用。

Redirect():則是客戶(hù)端的重定向,是完全的跳轉,即客戶(hù)端瀏覽器會(huì )獲取跳轉后的地址,然后重新發(fā)送請求,因此瀏覽器中會(huì )顯示跳轉后的地址。同時(shí),由于這種方式比FORWARD方式多了一次網(wǎng)絡(luò )請求,因此其效率低于FORWARD方式,需要注意到的是,客戶(hù)端的重定向可以通過(guò)設置特定的HTTP 頭或寫(xiě)JavaScript腳本來(lái)實(shí)現。

鑒于以上的區別,一般當FORWARD方式可以滿(mǎn)足需求時(shí),盡可能的使用FORWARD方式。但在有些情況下,例如,需要跳轉到一個(gè)其他服務(wù)器上的資源時(shí),則必須使用redirect 方式。

352.Session域和request域什么區別?

作用域:存放數據,獲取數據(傳遞數據)

有效的作用域:生命周期,作用范圍

httpServeltRequest:

生命周期:一次請求之間

作用范圍:所有被請求轉發(fā)過(guò)的servlet都能獲取到

httpSession:

生命周期:一次會(huì )話(huà)

作用范圍:所有的servlet都可以獲取到

servletContex:

生命周期:從項目開(kāi)始運行到服務(wù)器關(guān)閉

作用范圍:所有的servlet都可以獲取到?

作用域如何選用?

httpServeltRequest:和當前請求有關(guān)的信息

httpSession:和當前用戶(hù)有關(guān)的信息

servletContex:訪(fǎng)問(wèn)量比較大,不易更改

353.頁(yè)面中有一個(gè)命名為bankNo的下拉列表,寫(xiě)js腳本獲取當前選項的索引值,如果用jquery如何獲取

var a = document.getElementsByName("bankNo")[0].value;

var b = $("select[name=bankNo]").val();

354.寫(xiě)出要求11位數字的正則表達式

^[1-9]\d{10}$

355.分別獲取指定name、Id的javascript對象,如果用jquey如何獲取

js:
  id--document.getElementById("id");
  name--document.getElementsByName("name");
jquery
  id--$("#id");
  name--$("元素名稱(chēng)[name="name值"]");

356.一個(gè)頁(yè)面有兩個(gè)form,如何獲取第一個(gè)form

用id方式獲??;document.getElementById("id");

357.如何設置一個(gè)層的可見(jiàn)/隱藏

可見(jiàn) : document.getElementById("divid").style.display = "block";

隱藏 : document.getElementById("divid").style.display = "none";

358.描述JSP中動(dòng)態(tài)INCLUDE與靜態(tài)INCLUDE的區別?

動(dòng)態(tài)導入

1、會(huì )將多個(gè)jsp頁(yè)面分別再編寫(xiě)成java文件,編譯成class文件

2、jsp文件中允許有相同的變量名,每個(gè)頁(yè)面互不影響

3、當java代碼比較多優(yōu)先選用動(dòng)態(tài)導入

4、效率相對較低,耦合性低

靜態(tài)導入

1、會(huì )將多個(gè)jsp頁(yè)面合成一個(gè)jsp頁(yè)面,再編寫(xiě)成java文件,編譯成class文件

2、jsp文件中不允許有相同的變量名

3、當java代碼比較少或者沒(méi)有java代碼是優(yōu)先選用靜態(tài)導入

4、效率相對較高,耦合性高

359.列舉JSP的內置對象及方法

request表示HttpServletRequest對象。它包含了有關(guān)瀏覽器請求的信息,并且提供了幾個(gè)用于獲取cookie,?header,?和session數據的有用的方法。?

response表示HttpServletResponse對象,并提供了幾個(gè)用于設置送回?瀏覽器的響應的方法(如cookies,頭信息等)?

out對象是javax.jsp.JspWriter的一個(gè)實(shí)例,提供了幾個(gè)方法使你能用于向瀏覽器回送輸出結果

pageContext表示一個(gè)javax.servlejt.sp.PageContext對象。它是用于方便存取各種范圍的名字空間、servlet相關(guān)的對象的API,并且包裝了通用的servlet相關(guān)功能的方法。?

session表示一個(gè)請求的javax.servlet.http.HttpSession對象。Session可以存貯用戶(hù)的狀態(tài)信息

applicaton?表示一個(gè)javax.servle.ServletContext對象。這有助于查找有關(guān)servlet引擎和servlet環(huán)境的信息?

config表示一個(gè)javax.servlet.ServletConfig對象。該對象用于存取servlet實(shí)例的初始化參數。?

page表示從該頁(yè)面產(chǎn)生的一個(gè)servlet實(shí)例

Exception異常

360.列舉jsp的四大作用域

page、request、session、application

361.html和xhtml的區別是什么?

HTML與XHTML之間的差別,粗略可以分為兩大類(lèi)比較:一個(gè)是功能上的差別,另外是書(shū)寫(xiě)習慣的差別。關(guān)于功能上的差別,主要是XHTML可兼容各大瀏覽器、手機以及PDA,并且瀏覽器也能快速正確地編譯網(wǎng)頁(yè)。

因為XHTML的語(yǔ)法較為嚴謹, 所以如果你是習慣松散結構的HTML編寫(xiě)者,那需要特別注意XHTML的規則。但也不必太過(guò)擔心,因為XHTML的規則并不太難。下面列出了幾條容易犯的錯誤,供大家引用。

1:所有標簽都必須小寫(xiě)

在XHTML中,所有的標簽都必須小寫(xiě),不能大小寫(xiě)穿插其中,也不能全部都是大寫(xiě)??匆粋€(gè)例子。

錯誤:< Head>< /Head>< Body>< /Body>

正確:< head>< /head>< body>< /body>

2:標簽必須成雙成對

像是< p>...< /p>、< a>...< /a>、< div>...< /div>標簽等,當出現一個(gè)標簽時(shí),必須要有對應的結束標簽,缺一不可,就像在任何程序語(yǔ)言中的括號一樣。

錯誤:大家好< p>我是muki

正確:< p>大家好< /p>< p>我是muki< /p>

3:標簽順序必須正確

標簽由外到內,一層層包覆著(zhù),所以假設你先寫(xiě)div后寫(xiě)h1,結尾就要先寫(xiě)h1后寫(xiě)div。只要記住一個(gè)原則“先進(jìn)后出”,先彈出的標簽要后結尾。

錯誤:< div>< h1>大家好< /div>< /h1>

正確:< div>< h1>大家好< /h1>< /div>

4:所有屬性都必須使用雙引號

在XHTML 1.0中規定連單引號也不能使用,所以全程都得用雙引號。

錯誤:< div style=font-size:11px>hello< /div>

正確:< div style="font-size:11px">hello< /div

5:不允許使用target="_blank"

從XHTML 1.1開(kāi)始全面禁止target屬性,如果想要有開(kāi)新窗口的功能,就必須改寫(xiě)為rel="external",并搭配JavaScript實(shí)現此效果。

錯誤:< a target="_blank">MUKI space< /a>

正確:< a rel="external">MUKI space< /a>

362.你做的頁(yè)面用哪些瀏覽器測試過(guò)?這些測試的內核分別是什么?

1、Trident內核代表產(chǎn)品Internet Explorer,又稱(chēng)其為IE內核。?Trident(又稱(chēng)為MSHTML),是微軟開(kāi)發(fā)的一種排版引擎。使用Trident渲染引擎的瀏覽器包括:IE、傲游、世界之窗瀏覽器、Avant、騰訊TT、Netscape 8、NetCaptor、Sleipnir、GOSURF、GreenBrowser和KKman等。?

2、Gecko內核代表作品Mozilla?,FirefoxGecko是一套開(kāi)放源代碼的、以C++編寫(xiě)的網(wǎng)頁(yè)排版引擎。Gecko是最流行的排版引擎之一,僅次于Trident。使用它的最著(zhù)名瀏覽器有Firefox、Netscape6至9

3、WebKit內核代表作品Safari、Chromewebkit?, 是一個(gè)開(kāi)源項目,包含了來(lái)自KDE項目和蘋(píng)果公司的一些組件,主要用于Mac OS系統,它的特點(diǎn)在于源碼結構清晰、渲染速度極快。缺點(diǎn)是對網(wǎng)頁(yè)代碼的兼容性不高,導致一些編寫(xiě)不標準的網(wǎng)頁(yè)無(wú)法正常顯示。主要代表作品有Safari和Google的瀏覽器Chrome。?

4、Presto內核代表作品OperaPresto,?是由Opera Software開(kāi)發(fā)的瀏覽器排版引擎,供Opera 7.0及以上使用。它取代了舊版Opera 4至6版本使用的Elektra排版引擎,包括加入動(dòng)態(tài)功能,例如網(wǎng)頁(yè)或其部分可隨著(zhù)DOM及Script語(yǔ)法的事件而重新排版。

363.你遇到了哪些瀏覽器的兼容性問(wèn)題?怎么解決的?

答:因為不同的瀏覽器對同一段代碼有不同的解析,造成頁(yè)面顯示效果不統一的情況;這是我們常見(jiàn)的兼容性問(wèn)題。

解決方法:

1、針對不同的瀏覽器寫(xiě)不同的代碼

2、使用jquery屏蔽瀏覽器差異

遇到不同的兼容問(wèn)題,需要針對前端進(jìn)行兼容適配;

364.你知道的常用的js庫有哪些?

1.moment.js

舉個(gè)例子:

用js轉換時(shí)間戳為日期

let date = new Date(1437925575663);
        let year = date.getFullYear() + '-';
        let month = ( date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) :
date.getMonth() + 1 ) + '-';
        let day = date.getDate();
...
        return year + month + day;
用moment.js
return moment(1437925575663).format('YYYY-MM-DD HH:mm:ss')

2.chart.js

繪制簡(jiǎn)單的柱狀圖,曲線(xiàn)圖,蛛網(wǎng)圖,環(huán)形圖,餅圖等完全夠用,用法比較簡(jiǎn)單。

3.D3.js

功能太強大了,看首頁(yè)就知道了,感覺(jué)沒(méi)有什么圖d3繪不出來(lái)的。

4.Rx.js

很好的解決了異步和事件組合的問(wèn)題。

5.lodash.js

365.Js中的三種彈出式消息提醒(警告窗口、確認窗口、信息輸入窗口)的命令是什么?

alter(),confirm(),prompt()

366.談?wù)刯s的閉包

答:閉包無(wú)處不在,比如:jQuery、zepto的核心代碼都包含在一個(gè)大的閉包中,所以下面我先寫(xiě)一個(gè)最簡(jiǎn)單最原始的閉包,以便讓你在大腦里產(chǎn)生閉包的畫(huà)面:

function A(){
function B(){
console.log("Hello Closure!");
}
return B;
}
var C = A();
C();//Hello Closure!

這是最簡(jiǎn)單的閉包。

有了初步認識后,我們簡(jiǎn)單分析一下它和普通函數有什么不同,上面代碼翻譯成自然語(yǔ)言如下:

(1)定義普通函數 A

(2)在 A 中定義普通函數 B

(3)在 A 中返回 B

(4)執行 A, 并把 A 的返回結果賦值給變量 C

(5)執行 C

把這5步操作總結成一句話(huà)就是:

函數A的內部函數B被函數A外的一個(gè)變量 c 引用。

把這句話(huà)再加工一下就變成了閉包的定義:

當一個(gè)內部函數被其外部函數之外的變量引用時(shí),就形成了一個(gè)閉包。

因此,當你執行上述5步操作時(shí),就已經(jīng)定義了一個(gè)閉包!

這就是閉包。

367.寫(xiě)一段js,遍歷所有的li,將每個(gè)li的內容逐個(gè)alert出來(lái)

<body>
      <ul>
        <li>張三:123</li>
        <li>李四:456</li>
        <li>王五:789</li>
        <li>趙六:147</li>
<ul>
   <body>
function test(){
  var varli = document.getElementsByTagName("li");
  for (var i=0;i<varli.length;i++) {
    alert(varli[i].innerText);
  }
}

368.頁(yè)面上如何用JavaScript對多個(gè)checkbox全選

//全選
function checkAll(){
//獲取復選框對象--數組對象
var varcheck = document.getElementsByName("name");
//alert(varcheck.length);
//遍歷for
for(var i=0;i<varcheck.length;i++){
varcheck[i].checked = true;
}
}

369.寫(xiě)一個(gè)簡(jiǎn)單的JQuery的ajax

<script type="text/javascript" src="js/jquery-1.9.1.js" charset="utf-8"></script>

<script type="text/javascript">
function testJqAjax(){
//url  :請求地址
//type :請求的方式 get/post
//data :請求的參數(json/String)
//cache:true(走緩存 )  false(不走緩存)
//result:當ajax發(fā)送成功后會(huì )調用success后面的函數,result:相當于形參,返回的數據
//async:是否為異步請求 默認true異步 , false同步
$.ajax({
url:"TestJqAjax",
type:"get",
/* data:"uname=zhangsan&realname=張三豐", */
data:{uname:"zhangsan",realname:"張三豐"},
cache:false,
async:false,
success:function(result){
alert(result);
}
});
}

//ajax的get方式的請求
function jqAjaxGet(){
//url,[data],[callback](當ajax發(fā)送成功后調用的函數)
$.get("TestJqAjax",{uname:"zhangsan",realname:"張三豐"},function(result){
alert(result);
});

}

function  jqAjaxPost() {
//url,[data],[callback](當ajax發(fā)送成功后調用的函數)
$.post("TestJqAjax",{uname:"zhangsan",realname:"張三豐"},function(result){
alert(result);
});
}
</script>

370.Js截取字符串a(chǎn)bcdefg的efg

function test2(){
var str = "abcdefg";
var substr = str.substring(4);
alert(substr);
}

371.http的請求頭信息包含了什么?

請求行(請求方式,資源路徑,協(xié)議和協(xié)議版本號)

若干請求頭

請求實(shí)體內容

372.http的響應碼200,404,302,500表示的含義分別是?

200 - 確定??蛻?hù)端請求已成功

302 - 臨時(shí)移動(dòng)轉移,請求的內容已臨時(shí)移動(dòng)新的位置

404 - 未找到文件或目錄

500 - 服務(wù)器內部錯誤

373.Servlet中request對象的方法有?

/獲取網(wǎng)絡(luò )信息
private void getNet(HttpServletRequest req, HttpServletResponse resp) {
System.out.println("TestHttpRequest.getNet(獲取客戶(hù)端的ip):"+req.getRemoteAddr());
System.out.println("TestHttpRequest.getNet(獲取客戶(hù)端的端口):"+req.getRemotePort());
System.out.println("TestHttpRequest.getNet(獲取服務(wù)器的ip):"+req.getLocalAddr());
System.out.println("TestHttpRequest.getNet(獲取服務(wù)器的端口):"+req.getLocalPort());

}

//獲取實(shí)體內容
private void getContent(HttpServletRequest req, HttpServletResponse resp) {
//獲取單條信息
String uname = req.getParameter("uname");
//獲取多條信息,數組格式
String[] favs = req.getParameterValues("fav");
//遍歷數組
//判斷
if(favs!=null&&favs.length>0){
for (int i = 0; i < favs.length; i++) {
System.out.println("TestHttpRequest.getContent(fav):"+favs[i]);
}
}


String un = req.getParameter("un");
System.out.println("TestHttpRequest.getContent():"+uname+"--"+favs+"--"+un);

}

//獲取請求頭信息
private void getHeads(HttpServletRequest req, HttpServletResponse resp) {
//獲取單條頭信息
//System.out.println("TestHttpRequest.getHeads(獲取請求頭信息-瀏覽器頭信息):"+req.getHeader("User-Agent"));
//獲取所有頭信息--返回枚舉類(lèi)型
Enumeration strHeads = req.getHeaderNames();
//遍歷枚舉類(lèi)型
while (strHeads.hasMoreElements()) {
String strhead = (String) strHeads.nextElement();
System.out.println("TestHttpRequest.getHeads(獲取頭信息):"+req.getHeader(strhead));
}

}

//獲取請求行的信息
private void getLines(HttpServletRequest req, HttpServletResponse resp) {
System.out.println("TestHttpRequest.getLines(請求方式***):"+req.getMethod());
System.out.println("TestHttpRequest.getLines(資源路徑):"+req.getRequestURI());
System.out.println("TestHttpRequest.getLines(地址):"+req.getRequestURL());
System.out.println("TestHttpRequest.getLines(協(xié)議):"+req.getScheme());
System.out.println("TestHttpRequest.getLines(協(xié)議的版本號):"+req.getProtocol());
System.out.println("TestHttpRequest.getLines(獲取參數信息):"+req.getQueryString());
System.out.println("TestHttpRequest.getLines(項目名稱(chēng)***):"+req.getContextPath());
}

374.Javascript的常用對象有哪些

常用對象包括日期對象Date,字符串對象String,數組對象Array

//獲取并顯示系統當前時(shí)間

function testDate(){
var date = new Date();
var fmtDate = date.getFullYear()+"-"+(date.getMonth()+1)+
"-"+date.getDate()+"-"+date.getHours()
+":"+date.getMinutes()+":"+date.getSeconds();
alert(fmtDate);
}

//獲取出’sxt’的下標位置

function testString(){
var str = 'welcome to beijingsxt';
alert(str.indexOf('sxt'));
 }

//遍歷數組信息

function testArray(){
var arr = new Array('a',123,'c',true,'e');
for(var item in arr){
   document.write(arr[item]+" ");
}
}

375.DOM和BOM及其關(guān)系

BOM瀏覽器對象模型,由一系列對象組成,是訪(fǎng)問(wèn)、控制、修改瀏覽器的屬性的方法。

DOM文檔對象模型,由一系列對象組成,是訪(fǎng)問(wèn)、檢索、修改XHTML文檔內容與結構的標準方法。

關(guān)系:

–BOM描述了與瀏覽器進(jìn)行交互的方法和接口

–DOM描述了處理網(wǎng)頁(yè)內容的方法和接口

–DOM屬于BOM的一個(gè)屬性

376.JavaScript中獲取某個(gè)元素的三種方式JavaScript中的三種彈出式消息提醒命令是什么?

window.alert() 顯示一個(gè)提示信息

window.confirm() 顯示一個(gè)帶有提示信息、確定和取消按鈕的對話(huà)框

window.prompt() 顯示可提示用戶(hù)輸入的對話(huà)框

setTimeout與setInterval 的區別

setTimeout和setInterval的語(yǔ)法相同。它們都有兩個(gè)參數,一個(gè)是將要執行的代碼字符串,還有一個(gè)是以毫秒為單位的時(shí)間間隔,當過(guò)了那個(gè)時(shí)間段之后就將執行那段代碼。

不過(guò)這兩個(gè)函數還是有區別的,setInterval在執行完一次代碼之后,經(jīng)過(guò)了那個(gè)固定的時(shí)間間隔,它還會(huì )自動(dòng)重復執行代碼,而setTimeout只執行一次那段代碼。

window.setTimeout("function",time);//設置一個(gè)超時(shí)對象,只執行一次,無(wú)周期

window.setInterval("function",time);//設置一個(gè)超時(shí)對象,周期='交互時(shí)間'

377.JavaScript操作CSS的兩種方式

第一種方式:操作元素的屬性(對象.style.樣式名=樣式值;)

//改變直接樣式

var child2 = document.createElement("div");
    child2.innerHTML = "child2";
    child2.style.fontWeight = "bold";
    parent.appendChild(child2);

第二種方式:操作元素的類(lèi)(對象.className=類(lèi);)

例如:

var parent = document.getElementById("parent");
   //改變className
   var child0 = document.createElement("div");
   child0.innerHTML = "child0";
   child0.className = "newDiv";
parent.appendChild(child0);

378.靜態(tài)網(wǎng)頁(yè)和動(dòng)態(tài)網(wǎng)頁(yè)的聯(lián)系和區別

聯(lián)系:

1)靜態(tài)網(wǎng)頁(yè)是網(wǎng)站建設的基礎,靜態(tài)網(wǎng)頁(yè)和動(dòng)態(tài)網(wǎng)頁(yè)都要使用到HTMl語(yǔ)言。

2)靜態(tài)網(wǎng)頁(yè)是相對于動(dòng)態(tài)網(wǎng)頁(yè)而言,指沒(méi)有后臺數據庫、不含程序和不可交互的網(wǎng)頁(yè)、是標準的HTML文件,它的文件擴展名是.htm或.html。你編的是什么它顯示的就是什么、不會(huì )有任何改變。

3)靜態(tài)網(wǎng)頁(yè)和動(dòng)態(tài)網(wǎng)頁(yè)之間并不矛盾,為了網(wǎng)站適應搜索引擎檢索的需要,動(dòng)態(tài)網(wǎng)站可以采用靜動(dòng)結合的原則,適合采用動(dòng)態(tài)網(wǎng)頁(yè)的地方用動(dòng)態(tài)網(wǎng)頁(yè),如果必要使用靜態(tài)網(wǎng)頁(yè),則可以考慮用靜態(tài)網(wǎng)頁(yè)的方法來(lái)實(shí)現,在同一個(gè)網(wǎng)站上,動(dòng)態(tài)網(wǎng)頁(yè)內容和靜態(tài)網(wǎng)頁(yè)內容同時(shí)存在也是很常見(jiàn)的事情。

區別:

1)程序是否在服務(wù)器端運行,是重要標志。在服務(wù)器端運行的程序、網(wǎng)頁(yè)、組件,屬于動(dòng)態(tài)網(wǎng)頁(yè),它們會(huì )隨不同客戶(hù)、不同時(shí)間,返回不同的網(wǎng)頁(yè),例如ASP、PHP、JSP、ASP.net、CGI等。運行于客戶(hù)端的程序、網(wǎng)頁(yè)、插件、組件,屬于靜態(tài)網(wǎng)頁(yè),例如html頁(yè)、Flash、javascript、VBscript等等,它們是永遠不變的。

2)編程技術(shù)不同。靜態(tài)網(wǎng)頁(yè)和動(dòng)態(tài)網(wǎng)頁(yè)主要根據網(wǎng)頁(yè)制作的語(yǔ)言來(lái)區分。靜態(tài)網(wǎng)頁(yè)使用語(yǔ)言:HTML。 動(dòng)態(tài)網(wǎng)頁(yè)使用語(yǔ)言:HTML+ASP 或 HTML+PHP 或 HTML+JSP 等其它網(wǎng)站動(dòng)態(tài)語(yǔ)言。

3)被搜索引擎收錄情況不同。由于編程技術(shù)不容,靜態(tài)網(wǎng)頁(yè)是純粹HTML格式的網(wǎng)頁(yè),頁(yè)面內容穩定,不論是網(wǎng)頁(yè)是否被訪(fǎng)問(wèn),頁(yè)面都被保存在網(wǎng)站服務(wù)器上,很容易被搜索引擎收錄。而動(dòng)態(tài)網(wǎng)頁(yè)的內容是當用戶(hù)點(diǎn)擊請求時(shí)才從數據庫中調出返回給用戶(hù)一個(gè)網(wǎng)頁(yè)的內容,并不是存放在服務(wù)器上的獨立文件,相比較于靜態(tài)網(wǎng)頁(yè)而言,動(dòng)態(tài)網(wǎng)頁(yè)很難被搜索引擎收錄。

4)用戶(hù)訪(fǎng)問(wèn)速度不同。用戶(hù)訪(fǎng)問(wèn)動(dòng)態(tài)網(wǎng)頁(yè)時(shí),網(wǎng)頁(yè)在獲得搜索指令后經(jīng)過(guò)數據庫的調查匹配,再將與指令相符的內容傳遞給服務(wù)器,通過(guò)服務(wù)器的編譯將網(wǎng)頁(yè)編譯成標準的HTML代碼,從而傳遞給用戶(hù)瀏覽器,多個(gè)讀取過(guò)程大大降低了用戶(hù)的訪(fǎng)問(wèn)速度。而靜態(tài)網(wǎng)頁(yè)不同,由于網(wǎng)頁(yè)內容直接存取在服務(wù)器上,省去了服務(wù)器的編譯過(guò)程,用戶(hù)訪(fǎng)問(wèn)網(wǎng)頁(yè)速度很快。

5)制作和后期維護工作量不同。動(dòng)態(tài)網(wǎng)頁(yè)的設計以數據庫技術(shù)為基礎,可以實(shí)現多種功能,降低了網(wǎng)站維護的工作量。而靜態(tài)網(wǎng)頁(yè)由于沒(méi)有數據庫的支持,網(wǎng)頁(yè)內容更改時(shí)需要直接修改代碼,在網(wǎng)站內容制作和維護中,所需的工作量更大。動(dòng)態(tài)網(wǎng)頁(yè)與靜態(tài)網(wǎng)頁(yè)各有特點(diǎn),網(wǎng)站設計師在網(wǎng)頁(yè)設計時(shí),主要根據網(wǎng)站的功能需求和網(wǎng)站內容多少選擇不同網(wǎng)頁(yè)。如,網(wǎng)站包含信息量太大時(shí),就需要選擇動(dòng)態(tài)網(wǎng)頁(yè),反之,則選擇靜態(tài)網(wǎng)頁(yè)。

379.JSP/ASP/PHP的比較

ASP(Active Server Pages),JSP(JavaServer Pages),PHP(Hypertext Preprocessor)是目前主流的三種動(dòng)態(tài)網(wǎng)頁(yè)語(yǔ)言。

ASP是微軟(Microsoft)所開(kāi)發(fā)的一種后臺腳本語(yǔ)言,它的語(yǔ)法和Visual BASIC類(lèi)似,可以像SSI(Server Side Include)那樣把后臺腳本代碼內嵌到HTML頁(yè)面中。雖然ASP簡(jiǎn)單易用,但是它自身存在著(zhù)許多缺陷,最重要的就是安全性問(wèn)題。

PHP是一種跨平臺的服務(wù)器端的嵌入式腳本語(yǔ)言。它大量地借用C,Java和Perl語(yǔ)言的語(yǔ)法, 并耦合PHP自己的特性,使WEB開(kāi)發(fā)者能夠快速地寫(xiě)出動(dòng)態(tài)產(chǎn)生頁(yè)面。它支持目前絕大多數數據庫。

JSP是一個(gè)簡(jiǎn)化的Servlet,它是由Sun公司倡導、許多公司參與一起建立的一種動(dòng)態(tài)網(wǎng)頁(yè)技術(shù)標準。JSP技術(shù)有點(diǎn)類(lèi)似ASP技術(shù),它是在傳統的網(wǎng)頁(yè)HTML中插入Java程序段和JSP標記(tag),從而形成JSP文件,后綴名為(*.jsp)。 用JSP開(kāi)發(fā)的Web應用是跨平臺的,既能在Linux下運行,也能在其他操作系統上運行。

ASP優(yōu)點(diǎn): 無(wú)需編譯、易于生成、獨立于瀏覽器、面向對象、與任何ActiveX scripting 語(yǔ)言兼容、源程序碼不會(huì )外漏。

缺點(diǎn):

1)Windows本身的所有問(wèn)題都會(huì )一成不變的也累加到了它的身上。安全性、穩定性、跨平臺性都會(huì )因為與NT的捆綁而顯現出來(lái)。

2)ASP由于使用了COM組件所以它會(huì )變的十分強大,但是這樣的強大由于Windows NT系統最初的設計問(wèn)題而會(huì )引發(fā)大量的安全問(wèn)題。只要在這樣的組件或是操作中一不注意,那么外部攻擊就可以取得相當高的權限而導致網(wǎng)站癱瘓或者數據丟失。

3)還無(wú)法完全實(shí)現一些企業(yè)級的功能:完全的集群、負載均橫。

PHP優(yōu)點(diǎn):

1)一種能快速學(xué)習、跨平臺、有良好數據庫交互能力的開(kāi)發(fā)語(yǔ)言。

2)簡(jiǎn)單輕便,易學(xué)易用。

3 ) 與Apache及其它擴展庫結合緊密。

缺點(diǎn):

1 ) 數據庫支持的極大變化。

2 ) 不適合應用于大型電子商務(wù)站點(diǎn)。

JSP優(yōu)點(diǎn):

1 ) 一處編寫(xiě)隨處運行。

2 ) 系統的多臺平支持。

3 ) 強大的的可伸縮性。

4 ) 多樣化和功能強大的開(kāi)發(fā)工具支持。

缺點(diǎn):

1) 與ASP一樣,Java的一些優(yōu)勢正是它致命的問(wèn)題所在。

2 ) 開(kāi)發(fā)速度慢

380.CGI/Servlet/JSP的比較

CGI(Common Gateway Interface),通用網(wǎng)關(guān)接口,是一種根據請求信息動(dòng)態(tài)產(chǎn)生回應內容的技術(shù)。

通過(guò)CGI,Web 服務(wù)器可以將根據請求不同啟動(dòng)不同的外部程序,并將請求內容轉發(fā)給該程序,在程序執行結束后,將執行結果作為回應返回給客戶(hù)端。也就是說(shuō),對于每個(gè)請求,都要產(chǎn)生一個(gè)新的進(jìn)程進(jìn)行處理。

Servlet 是在服務(wù)器上運行的小程序。在實(shí)際運行的時(shí)候Java Servlet與Web服務(wù)器會(huì )融為一體。與CGI不同的是,Servlet對每個(gè)請求都是單獨啟動(dòng)一個(gè)線(xiàn)程,而不是進(jìn)程。這種處理方式大幅度地降低了系統里的進(jìn)程數量,提高了系統的并發(fā)處理能力。

比較:

1) JSP從本質(zhì)上說(shuō)就是Servlet。JSP技術(shù)產(chǎn)生于Servlet之后,兩者分工協(xié)作,Servlet側重于解決運算和業(yè)務(wù)邏輯問(wèn)題,JSP則側重于解決展示問(wèn)題。

2 ) 與CGI相比,Servlet效率更高。Servlet處于服務(wù)器進(jìn)程中,它通過(guò)多線(xiàn)程方式運行其service方法,一個(gè)實(shí)例可以服務(wù)于多個(gè)請求,并且其實(shí)例一般不會(huì )銷(xiāo)毀。而CGI對每個(gè)請求都產(chǎn)生新的進(jìn)程,服務(wù)完成后就銷(xiāo)毀,所以效率上低于Servlet 。

3)與CGI相比,Servlet更容易使用,功能更強大,具有更好的可移植性,更節省投資。在未來(lái)的技術(shù)發(fā)展過(guò)程中,Servlet有可能徹底取代CGI。

381.HTTP協(xié)議工作原理及其特點(diǎn)

超文本傳輸協(xié)議(HTTP:Hypertext Transport Protocol)是萬(wàn)維網(wǎng)應用層的協(xié)議,它通過(guò)兩個(gè)程序實(shí)現:一個(gè)是客戶(hù)端程序(各種瀏覽器),另一個(gè)是服務(wù)器 (常稱(chēng)Web服務(wù)器) 。這兩個(gè)通常運行在不同的主機上,通過(guò)交換報文來(lái)完成網(wǎng)頁(yè)請求和響應,報文可簡(jiǎn)單分為請求報文和響應報文。

工作原理(流程):

客戶(hù)機與服務(wù)器建立連接后,瀏覽器可以向web服務(wù)器發(fā)送請求并顯示收到的網(wǎng)頁(yè),當用戶(hù)在瀏覽器地址欄中輸入一個(gè)URL或點(diǎn)擊一個(gè)超連接時(shí),瀏覽器就向服務(wù)器發(fā)出了HTTP請求,請求方式的格式為:統一資源標識符、協(xié)議版本號,后邊是MIME(Multipurpose Internet Mail Extensions)信息包括請求修飾符、客戶(hù)機信息和可能的內容。該請求被送往由URL指定的WEB服務(wù)器,WEB服務(wù)器接收到請求后,進(jìn)行相應反映,其格式為:一個(gè)狀態(tài)行包括信息的協(xié)議版本號、一個(gè)成功或錯誤的代碼,后邊服務(wù)器信息、實(shí)體信息和可能的內容。即以HTTP規定的格式送回所要求的文件或其他相關(guān)信息,再由用戶(hù)計算機上的瀏覽器負責解釋和顯示。

特點(diǎn):

1)支持客戶(hù)/服務(wù)器模式。

2)簡(jiǎn)單快速:客戶(hù)向服務(wù)器請求服務(wù)時(shí),只需傳送請求方法和路徑。請求方法常用的有GET、HEAD、POST。每種方法規定了客戶(hù)與服務(wù)器聯(lián)系的類(lèi)型不同。由于HTTP協(xié)議簡(jiǎn)單,使得HTTP服務(wù)器的程序規模小,因而通信速度很快。

3)靈活:HTTP允許傳輸任意類(lèi)型的數據對象。正在傳輸的類(lèi)型由Content-Type加以標記。

4)無(wú)連接:無(wú)連接的含義是限制每次連接只處理一個(gè)請求。服務(wù)器處理完客戶(hù)的請求,并收到客戶(hù)的應答后,即斷開(kāi)連接。采用這種方式可以節省傳輸時(shí)間。

5)無(wú)狀態(tài):HTTP協(xié)議是無(wú)狀態(tài)協(xié)議。無(wú)狀態(tài)是指協(xié)議對于事務(wù)處理沒(méi)有記憶能力。缺少狀態(tài)意味著(zhù)如果后續處理需要前面的信息,則它必須重傳,這樣可能導致每次連接傳送的數據量增大。另一方面,在服務(wù)器不需要先前信息時(shí)它的應答就較快。

382.get和post的區別

1. Get是不安全的,因為在傳輸過(guò)程,數據被放在請求的URL中;Post的所有操作對用戶(hù)來(lái)說(shuō)都是不可見(jiàn)的。

2. Get傳送的數據量較小,這主要是因為受URL長(cháng)度限制;Post傳送的數據量較大,一般被默認為不受限制。

3. Get限制Form表單的數據集的值必須為ASCII字符;而Post支持整個(gè)ISO10646字符集。

4. Get執行效率卻比Post方法好。Get是form提交的默認方法。

383.如何解決表單提交的中文亂碼問(wèn)題

1)設置頁(yè)面編碼,若是jsp頁(yè)面,需編寫(xiě)代碼

<%@page language="java" pageEncoding="UTF-8" contentType="text/html;charset=UTF-8" %>

若是html頁(yè)面,在網(wǎng)頁(yè)頭部(< head>< /head>)中添加下面這段代碼

< meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

2)將form表單提交方式變?yōu)閜ost方式,即添加method="post";)在Servlet類(lèi)中編寫(xiě)代碼request.setCharacterEncoding("UTF-8"),而且必須寫(xiě)在第一行。

3)如果是get請求,在Servlet類(lèi)中編寫(xiě)代碼

byte [] bytes = str.getBytes("iso-8859-1");

String cstr = new String(bytes,"utf-8");

或者直接修改Tomcat服務(wù)器配置文件server.xml增加內容:

URIEncoding="utf-8"

384.絕對路徑、根路徑、相對路徑的含義及其區別

絕對路徑指對站點(diǎn)的根目錄而言某文件的位置,相對路徑指以當前文件所處目錄而言某文件的位置,相對路徑-以引用文件之網(wǎng)頁(yè)所在位置為參考基礎,而建立出的目錄路徑。絕對路徑-以Web站點(diǎn)根目錄為參考基礎的目錄路徑。

先給出一個(gè)網(wǎng)站結構圖做實(shí)例加深理解,A網(wǎng)站(域名為http://www.a.com):/include/a-test.html,/img/a-next.jpg;B網(wǎng)站(域名為http://www.b.com):/include/b-test.html,/img/b-next.jpg。

相對路徑是從引用的網(wǎng)頁(yè)文件本身開(kāi)始構建的,如果在A(yíng)網(wǎng)站中的a-test.html中要插入圖片a-next.jpg,可以這樣做:< img src="../img/a-next.jpg" />,重點(diǎn)是img前面的../,表示從html處于的include開(kāi)始起步,輸入一個(gè)../表示回到上面一級父文件夾下,然后再接著(zhù)img/表示又從父級文件夾下的img文件開(kāi)始了,最后定位img下面的next.jpg。

根路徑是從網(wǎng)站的最底層開(kāi)始起,一般的網(wǎng)站的根目錄就是域名下對應的文件夾,就如D盤(pán)是一個(gè)網(wǎng)站,雙擊D盤(pán)進(jìn)入到D盤(pán)看到的就是網(wǎng)站的根目錄,這種路徑的鏈接樣式是這樣的:如果在A(yíng)網(wǎng)站中的a-test.html中要插入圖片a-next.jpg,可以這樣做:< img src="/img/a-next.jpg" >,以/開(kāi)頭表示從網(wǎng)站根目錄算起,找到根目錄下面的img文件夾下的next.jpg。

絕對路徑就很好理解了,這種路徑一般帶有網(wǎng)站的域名,如果在A(yíng)網(wǎng)站中的a-test.html中要插入圖片a-next.jpg,需要這樣這樣寫(xiě):< img src="http://www.a.com/img/a-next.jpg" >,將圖片路徑上帶有了域名信息,再打個(gè)比方:如果在A(yíng)網(wǎng)站中的a-test.html中要插入B網(wǎng)站的圖片b-next.jpg,就需要這樣寫(xiě):< img src="http://www.b.com/img/b-next.jpg" >,這種方法適用與在不同網(wǎng)站之間插入外部網(wǎng)站的圖片。

385.如實(shí)現servlet的單線(xiàn)程模式

實(shí)現servlet的單線(xiàn)程的jsp命令是: <%@ page isThreadSafe=”false”%>。默認isThreadSafe值為true。

屬性isThreadSafe=false模式表示它是以Singleton模式運行,該模式implements了接口SingleThreadMode, 該模式同一時(shí)刻只有一個(gè)實(shí)例,不會(huì )出現信息同步與否的概念。若多個(gè)用戶(hù)同時(shí)訪(fǎng)問(wèn)一個(gè)這種模式的頁(yè)面,那么先訪(fǎng)問(wèn)者完全執行完該頁(yè)面后,后訪(fǎng)問(wèn)者才開(kāi)始執行。

屬性isThreadSafe=true模式表示它以多線(xiàn)程方式運行。該模式的信息同步,需訪(fǎng)問(wèn)同步方法(用synchronized標記的)來(lái)實(shí)現。 一般格式如下:

 public synchronized void syncmethod(...){
      while(...) {
        this.wait();
      }
      this.notifyAll();
 }

386.Servlet的生命周期

1、加載:在下列時(shí)刻加載 Servlet:(1)如果已配置自動(dòng)加載選項,則在啟動(dòng)服務(wù)器時(shí)自動(dòng)

2、加載 (web.xml中設置< load-on-start>);(2)在服務(wù)器啟動(dòng)后,客戶(hù)機首次向 Servlet 發(fā)出請求時(shí);(3)重新加載 Servlet 時(shí)(只執行一次)

3、實(shí)例化:加載 Servlet 后,服務(wù)器創(chuàng )建一個(gè) Servlet 實(shí)例。(只執行一次)

4、初始化:調用 Servlet 的 init() 方法。在初始化階段,Servlet 初始化參數被傳遞給 Servlet 配置對象ServletConfig。 (只執行一次)

5、請求處理:對于到達服務(wù)器的客戶(hù)機請求,服務(wù)器創(chuàng )建針對此次請求的一個(gè)“請求”對象和一個(gè)“響應”對象。服務(wù)器調用 Servlet 的 service() 方法,該方法用于傳遞“請求”和“響應”對象。service() 方法從“請求”對象獲得請求信息、處理該請求并用“響應”對象的方法以將響應傳回客戶(hù)機。service() 方法可以調用其它方法來(lái)處理請求,例如 doGet()、doPost() 或其它的方法。(每次請求都執行該步驟)

6、銷(xiāo)毀:當服務(wù)器不再需要 Servlet, 或重新裝入 Servlet 的新實(shí)例時(shí),服務(wù)器會(huì )調用 Servlet 的 destroy() 方法。(只執行一次)

387.轉發(fā)和重定向的區別

轉發(fā)是在服務(wù)端直接做的事情,是對客戶(hù)端的同一個(gè)request進(jìn)行傳遞,瀏覽器并不知道。重定向是由瀏覽器來(lái)做的事情。重定向時(shí),服務(wù)端返回一個(gè)response,里面包含了跳轉的地址,由瀏覽器獲得后,自動(dòng)發(fā)送一個(gè)新request。轉發(fā)像呼叫轉移或者110報警中心,重定向似114查號臺。

a) 區別1:跳轉效率的不同

轉發(fā)效率相對高;重定向效率相對低

b) 區別2:實(shí)現語(yǔ)句不同

轉發(fā) request.getRequestDispatcher("xxxx").forward(request,response) ;

重定向 response.sendRedirect("xxxx")

c) 區別3:是否共有同一個(gè)request的數據

轉發(fā)源組件與目標組件共有同一個(gè)request數據

重定向源組件與目標組件不共有同一個(gè)request數據(可使用session共有數據)

d) 區別4:瀏覽器URL地址的不同

轉發(fā)后瀏覽器URL地址保持不變(源組件地址)

重定向后瀏覽器URL地址改變?yōu)橹囟ㄏ蚝蟮牡刂罚繕私M件地址)

e) 區別5:"/"路徑的含義不同

轉發(fā)時(shí)"/"代表當前項目的根路徑 ;重定向時(shí)"/"代表當前服務(wù)器的根路徑

f) 區別6:跳轉范圍的不同

只能轉發(fā)到同一應用中的URL(默認) ;可以重定向任何服務(wù)器、任何應用的URL

g) 區別7:刷新是否導致重復提交

轉發(fā)會(huì )導致重復提交(可以通過(guò)同步令牌解決);重定向不會(huì )導致重復提交

h) 區別8:是否經(jīng)過(guò)過(guò)濾器

轉發(fā)不經(jīng)過(guò)過(guò)濾器(默認情況);重定向經(jīng)過(guò)過(guò)濾器

388.JSP的執行過(guò)程

在JSP運行過(guò)程中,首先由客戶(hù)端發(fā)出請求,Web服務(wù)器接收到請求后,如果是第一次訪(fǎng)問(wèn)某個(gè)jsp頁(yè)面,Web服務(wù)器對它進(jìn)行以下3個(gè)操作。

1)翻譯:由.jsp變?yōu)?java,由JSP引擎實(shí)現。

2)編譯:由.java變?yōu)?class,由 Java編譯器實(shí)現。

3)執行:由.class變?yōu)?html,用Java虛擬機執行編譯文件,然后將執行結果返回給Web服務(wù)器,并最終返回給客戶(hù)端

如果不是第一次訪(fǎng)問(wèn)某個(gè)JSP頁(yè)面,則只執行第三步。所以第一次訪(fǎng)問(wèn)JSP較慢。

389.JSP動(dòng)作有哪些,簡(jiǎn)述作用?

jsp:include:在頁(yè)面被請求的時(shí)候引入一個(gè)文件。

jsp:useBean:尋找或者實(shí)例化一個(gè)JavaBean。 jsp:setProperty:設置JavaBean的屬性。

jsp:getProperty:輸出某個(gè)JavaBean的屬性。

jsp:forward:把請求轉到一個(gè)新的頁(yè)面。 jsp:plugin:根據瀏覽器類(lèi)型為Java插件生成OBJECT或EMBED標記。

390.page/request/session/application作用域區別

page:當前頁(yè)面范圍

request:當前頁(yè)面范圍+轉發(fā)頁(yè)面(forward)+包含頁(yè)面(include)

session:當前會(huì )話(huà):session在以下幾種情況下失效

1)銷(xiāo)毀session:Session.invalidate();

2)超過(guò)最大非活動(dòng)間隔時(shí)間

3)手動(dòng)關(guān)閉瀏覽器(session并沒(méi)有立刻失效,因為服務(wù)器端session仍舊存在,超過(guò)最大非活動(dòng)間隔時(shí)間后真正失效)

application:當前應用;服務(wù)器重新啟動(dòng)前一直有效

391.JSP和Servlet的區別和聯(lián)系

區別:

1)JSP是在HTML代碼里寫(xiě)JAVA代碼,框架是HTML;而Servlet是在JAVA代碼中寫(xiě)HTML代碼,本身是個(gè)JAVA類(lèi)。

2)JSP使人們把顯示和邏輯分隔成為可能,這意味著(zhù)兩者的開(kāi)發(fā)可并行進(jìn)行;而Servlet并沒(méi)有把兩者分開(kāi)。

3)Servlet獨立地處理靜態(tài)表示邏輯與動(dòng)態(tài)業(yè)務(wù)邏輯.這樣,任何文件的變動(dòng)都需要對此服務(wù)程序重新編譯;JSP允許用特殊標簽直接嵌入到HTML頁(yè)面, HTML內容與JAVA內容也可放在單獨文件中,HTML內容的任何變動(dòng)會(huì )自動(dòng)編譯裝入到服務(wù)程序.

4)Servlet需要在web.xml中配置,而JSP無(wú)需配置。

5)目前JSP主要用在視圖層,負責顯示,而Servlet主要用在控制層,負責調度

聯(lián)系:

1)都是Sun公司推出的動(dòng)態(tài)網(wǎng)頁(yè)技術(shù)。

2)先有Servlet,針對Servlet缺點(diǎn)推出JSP。JSP是Servlet的一種特殊形式,每個(gè)JSP頁(yè)面就是一個(gè)Servlet實(shí)例——JSP頁(yè)面由系統翻譯成Servlet,Servlet再負責響應用戶(hù)請求。

392.談?wù)勥^(guò)濾器原理及其作用?

原理:

?過(guò)濾器是運行在服務(wù)器端的一個(gè)攔截作用的web組件,一個(gè)請求來(lái)到時(shí),web容器會(huì )判斷是否有過(guò)濾器與該信息資源相關(guān)聯(lián),如果有則交給過(guò)濾器處理,然后再交給目標資源,響應的時(shí)候則以相反的順序交給過(guò)濾器處理,最后再返回給用戶(hù)瀏覽器

?一般用于日志記錄、性能、安全、權限管理等公共模塊。

過(guò)濾器開(kāi)發(fā):

?過(guò)濾器是一個(gè)實(shí)現了javax.servlet.Filter接口的java類(lèi)

?主要業(yè)務(wù)代碼放在doFilter方法中

?業(yè)務(wù)代碼完成后要將請求向后傳遞,即調用FilterChain對象的doFilter方法

配置:

在web.xml中增加如下代碼
<filter>
    <filter-name>MyFilter</filter-name>
    <filter-class>Filter完整類(lèi)名</filter-class>
</filter>
<filter-mapping>
    <filter-name>MyFilter</filter-name>
    <url-pattern>/*(要過(guò)慮的url,此處*表示過(guò)慮所有的url)</url-pattern>
</filter-mapping>

談?wù)劚O聽(tīng)器作用及其分類(lèi)?

監聽(tīng)器也叫Listener,是一個(gè)實(shí)現特定接口的java類(lèi),使用時(shí)需要在web.xml中配置,它是web服務(wù)器端的一個(gè)組件,它們用于監聽(tīng)的事件源分別為SerlvetConext,HttpSession和ServletRequest這三個(gè)域對象

主要有以下三種操作:

–監聽(tīng)三個(gè)域對象創(chuàng )建和銷(xiāo)毀的事件監聽(tīng)器

–監聽(tīng)域對象中屬性的增加和刪除的事件監聽(tīng)器

–監聽(tīng)綁定到HttpSession域中的某個(gè)對象的狀態(tài)的時(shí)間監聽(tīng)器

接口分類(lèi):

–ServletContextListener

HttpSessionListener

–ServletRequestListener

–ServletContextAttributeListener

–HttpSessionAttributeListener

ServletRequestAttributeListener

–HttpSessionBindingListener(不需要配置)

–HttpSessionActivationListener(不需要配置)

配置:

< listener>< listener-class>實(shí)現以上任意接口的java類(lèi)全名< /listener-class>< /listener>

393.jQuery相比JavaScript的優(yōu)勢在哪里

jQuery的語(yǔ)法更加簡(jiǎn)單。

jQuery消除了JavaScript跨平臺兼容問(wèn)題。

相比其他JavaScript和JavaScript庫,jQuery更容易使用。

jQuery有一個(gè)龐大的庫/函數。

jQuery有良好的文檔和幫助手冊。

jQuery支持AJAX

394.DOM對象和jQuery對象的區別及其轉換

DOM對象,是我們用傳統的方法(javascript)獲得的對象,jQuery對象即是用jQuery類(lèi)庫的選擇器獲得的對象,它是對DOM對象的一種封裝,jQuery對象不能使用DOM對象的方法,只能使用jQuery對象自己的方法。

普通的dom對象一般可以通過(guò)$()轉換成jquery對象

如:var cr=document.getElementById("cr"); //dom對象

var $cr = $(cr); //轉換成jquery對象

由于jquery對象本身是一個(gè)集合。所以如果jquery對象要轉換為dom對象則必須取出其中的某一項,一般可通過(guò)索引取出

如:$("#msg")[0],$("div").eq(1)[0],$("div").get()[1],$("td")[5]這幾種語(yǔ)法在jQuery中都是合法的

395.jQuery中$的作用主要有哪些

1)$用作選擇器

例如:根據id獲得頁(yè)面元素$("#元素ID")

2)$相當于window.onload 和 $(document).ready(...)

例如:$(function(){...}); function(){...}會(huì )在DOM樹(shù)加載完畢之后執行。

3)$用作JQuery的工具函數的前綴

例如: var str = ' Welcome to shanghai.com ';

str = $.trim(str);去掉空格

4)$(element):把DOM節點(diǎn)轉化成jQuery節點(diǎn)

例如:var cr=document.getElementById("cr"); //dom對象

var $cr = $(cr); //轉換成jquery對象

5)$(html):使用HTML字符串創(chuàng )建jQuery節點(diǎn)

例如:var obj = $("< div>尚學(xué)堂,實(shí)戰化教學(xué)第一品牌< /div>")

396.Ajax含義及其主要技術(shù)

Ajax (Asynchronous JavaScript and XML 阿賈克斯)不是一個(gè)新的技術(shù),事實(shí)上,它是一些舊有的成熟的技術(shù)以一種全新的更加強大的方式整合在一起。

Ajax的關(guān)鍵技術(shù):

1)使用CSS構建用戶(hù)界面樣式,負責頁(yè)面排版和美工

2)使用DOM進(jìn)行動(dòng)態(tài)顯示和交互,對頁(yè)面進(jìn)行局部修改

3)使用XMLHttpRequest異步獲取數據

4)使用JavaScript將所有元素綁定在一起

397.Ajax的工作原理

Ajax的原理簡(jiǎn)單來(lái)說(shuō)通過(guò)XmlHttpRequest對象來(lái)向服務(wù)器發(fā)異步請求,從服務(wù)器獲得數據,然后用javascript來(lái)操作DOM而更新頁(yè)面。這其中最關(guān)鍵的一步就是從服務(wù)器獲得請求數據。要清楚這個(gè)過(guò)程和原理,我們必須對 XMLHttpRequest有所了解。

XMLHttpRequest是ajax的核心機制,它是在IE5中首先引入的,是一種支持異步請求的技術(shù)。簡(jiǎn)單的說(shuō),也就是javascript可以及時(shí)向服務(wù)器提出請求和處理響應,而不阻塞用戶(hù)。達到無(wú)刷新的效果。

398.JSON及其作用

JSON(JavaScript Object Notation) 是一種輕量級的數據交換格式,采用完全獨立于語(yǔ)言的文本格式,是理想的數據交換格式。同時(shí),JSON是 JavaScript 原生格式,這意味著(zhù)在 JavaScript 中處理 JSON數據不須要任何特殊的 API 或工具包。

在JSON中,有兩種結構:對象和數組。

?{} 對象

?[] 數組

?, 分隔屬性

: 左邊為屬性名,右邊為屬性值?

屬性名可用可不用引號括起,屬性值為字符串一定要用引號括起

舉例:

varo={
    "xlid": "cxh",
    "xldigitid": 123456,
    "topscore": 2000,
    "topplaytime": "2009-08-20"
};

jsonranklist=[
    {
        "xlid": "cxh",
        "xldigitid": 123456,
        "topscore": 2000,
        "topplaytime": "2009-08-20"
    },
    {
        "xlid": "zd",
        "xldigitid": 123456,
        "topscore": 1500,
        "topplaytime": "2009-11-20"
    }
];

399.文件上傳組件Common-fileUpload的常用類(lèi)及其作用?

DiskFileItemFactory:磁盤(pán)文件工廠(chǎng)類(lèi),設置上傳文件保存的磁盤(pán)目錄,緩沖區大小。

ServletFileUpload:上傳處理類(lèi),此類(lèi)真正讀取客戶(hù)上傳的文件,同時(shí)可以設置最大接收大小。

FileItem:上傳的文件對象,可以是多個(gè)文件,每個(gè)上傳的文件都是一個(gè)單獨的FileItem對象。

400.說(shuō)出Servlet的生命周期,并說(shuō)出Servlet和CGI的區別?

答:Web容器加載Servlet并將其實(shí)例化后,Servlet生命周期開(kāi)始,容器運行其init()方法進(jìn)行Servlet的初始化;請求到達時(shí)調用Servlet的service方法,service方法會(huì )調用與請求對應的doGet或doPost等方法;當服務(wù)器關(guān)閉會(huì )項目被卸載時(shí)服務(wù)器會(huì )將Servlet實(shí)例銷(xiāo)毀,此時(shí)會(huì )調用Servlet的destroy方法。Servlet與CGI的區別在于Servlet處于服務(wù)器進(jìn)程中,它通過(guò)多線(xiàn)程方式運行其service方法,一個(gè)實(shí)例可以服務(wù)于多個(gè)請求,并且其實(shí)例一般不會(huì )銷(xiāo)毀,而CGI 對每個(gè)請求都產(chǎn)生新的進(jìn)程,服務(wù)完成后就銷(xiāo)毀,所以效率上低于Servlet。

【補充1】SUN公司在1996年發(fā)布Servlet技術(shù)就是為了和CGI進(jìn)行競爭,Servlet是一個(gè)特殊的Java程序,一個(gè)基于Java的Web應用通常包含一個(gè)或多個(gè)Servlet類(lèi)。 Servlet不能夠自行創(chuàng )建并執行,它是在Servlet容器中運行的,容器將用戶(hù)的請求傳遞給Servlet程序,此外將Servlet的響應回傳給用戶(hù)。通常一個(gè)Servlet會(huì )關(guān)聯(lián)一個(gè)或多個(gè)JSP頁(yè)面。以前CGI經(jīng)常因為性能開(kāi)銷(xiāo)上的問(wèn)題被詬病,然而Fast CGI早就已經(jīng)解決了CGI效率上的問(wèn)題,所以面試的時(shí)候大可不必詬病CGI,騰訊的網(wǎng)站就使用了CGI技術(shù),相信你也沒(méi)感覺(jué)它哪里不好。

【補充2】Servlet接口定義了5個(gè)方法,其中前三個(gè)方法與Servlet生命周期相關(guān):

void init(ServletConfig config) throws ServletException

void service(ServletRequest req, ServletResponse resp) throws ServletException, java.io.IOException

void destory()

java.lang.String getServletInfo()

ServletConfig getServletConfig()

401.JSP 和Servlet 有有什么關(guān)系?

答:其實(shí)這個(gè)問(wèn)題在上面已經(jīng)闡述過(guò)了,Servlet是一個(gè)特殊的Java程序,它運行于服務(wù)器的JVM中,能夠依靠服務(wù)器的支持向瀏覽器提供顯示內容。JSP本質(zhì)上是Servlet的一種簡(jiǎn)易形式, JSP會(huì )被服務(wù)器處理成一個(gè)類(lèi)似于Servlet的Java程序,可以簡(jiǎn)化頁(yè)面內容的生成。Servlet和JSP最主要的不同點(diǎn)在于,Servlet 的應用邏輯是在Java 文件中,并且完全從表示層中的HTML分離開(kāi)來(lái)。而JSP的情況是Java和HTML可以組合成一個(gè)擴展名為.jsp 的文件(有人說(shuō),Servlet就是在Java中寫(xiě)HTML,而JSP就是在HTML中寫(xiě)Java代碼,當然,這個(gè)說(shuō)法還是很片面的)。JSP側重于視圖,Servlet更側重于控制邏輯,在MVC架構模式中,JSP適合充當視圖(view)而Servlet適合充當控制器(controller)。

402.JSP中的四種作用域?

答:page、request、session和application,具體如下:

①page 代表與一個(gè)頁(yè)面相關(guān)的對象和屬性。

②request 代表與Web客戶(hù)機發(fā)出的一個(gè)請求相關(guān)的對象和屬性。一個(gè)請求可能跨越多個(gè)頁(yè)面,涉及多個(gè)Web 組件;需要在頁(yè)面顯示的臨時(shí)數據可以置于此作用域

③session代表與某個(gè)用戶(hù)與服務(wù)器建立的一次會(huì )話(huà)相關(guān)的對象和屬性。跟某個(gè)用戶(hù)相關(guān)的數據應該放在用戶(hù)自己的session中

④application代表與整個(gè)Web應用程序相關(guān)的對象和屬性,它實(shí)質(zhì)上是跨越整個(gè)Web應用程序,包括多個(gè)頁(yè)面、請求和會(huì )話(huà)的一個(gè)全局作用域。

403.如何實(shí)現JSP或Servlet的單線(xiàn)程模式?

<%@page isThreadSafe=”false”%>

【補充】Servlet默認的工作模式是單實(shí)例多線(xiàn)程,如果Servlet實(shí)現了標識接口SingleThreadModel又或是JSP頁(yè)面通過(guò)page指令設置isThreadSafe屬性為false,那么它們生成的Java代碼會(huì )以單線(xiàn)程多實(shí)例方式工作。顯然,這樣做會(huì )導致每個(gè)請求創(chuàng )建一個(gè)Servlet實(shí)例,這種實(shí)踐將導致嚴重的性能問(wèn)題。

404.實(shí)現會(huì )話(huà)跟蹤的技術(shù)有哪些?

答:由于HTTP協(xié)議本身是無(wú)狀態(tài)的,服務(wù)器為了區分不同的用戶(hù),就需要對用戶(hù)會(huì )話(huà)進(jìn)行跟蹤,簡(jiǎn)單的說(shuō)就是為用戶(hù)進(jìn)行登記,為用戶(hù)分配唯一的ID,下一次用戶(hù)在請求中包含此ID,服務(wù)器據此判斷到底是哪一個(gè)用戶(hù)。

①URL 重寫(xiě):在URL中添加用戶(hù)會(huì )話(huà)的信息作為請求的參數,或者將唯一的會(huì )話(huà)ID添加到URL結尾以標識一個(gè)會(huì )話(huà)。

②設置表單隱藏域:將和會(huì )話(huà)跟蹤相關(guān)的字段添加到隱式表單域中,這些信息不會(huì )在瀏覽器中顯示但是提交表單時(shí)會(huì )提交給服務(wù)器。

這兩種方式很難處理跨越多個(gè)頁(yè)面的信息傳遞,因為如果每次都要修改URL或在頁(yè)面中添加隱式表單域來(lái)存儲用戶(hù)會(huì )話(huà)相關(guān)信息,事情將變得非常麻煩。

③cookie:cookie有兩種,一種是基于窗口的,瀏覽器窗口關(guān)閉后,cookie就沒(méi)有了;另一種是將信息存儲在一個(gè)臨時(shí)文件中,并設置存在的時(shí)間。當用戶(hù)通過(guò)瀏覽器和服務(wù)器建立一次會(huì )話(huà)后,會(huì )話(huà)ID就會(huì )隨響應信息返回存儲在基于窗口的cookie中,那就意味著(zhù)只要瀏覽器沒(méi)有關(guān)閉,會(huì )話(huà)沒(méi)有超時(shí),下一次請求時(shí)這個(gè)會(huì )話(huà)ID又會(huì )提交給服務(wù)器讓服務(wù)器識別用戶(hù)身份。會(huì )話(huà)中可以為用戶(hù)保存信息。會(huì )話(huà)對象是在服務(wù)器內存中的,而基于窗口的cookie是在客戶(hù)端內存中的。如果瀏覽器禁用了cookie,那么就需要通過(guò)下面兩種方式進(jìn)行會(huì )話(huà)跟蹤。當然,在使用cookie時(shí)要注意幾點(diǎn):首先不要在cookie中存放敏感信息;其次cookie存儲的數據量有限(4k),不能將過(guò)多的內容存儲cookie中;再者瀏覽器通常只允許一個(gè)站點(diǎn)最多存放20個(gè)cookie。當然,和用戶(hù)會(huì )話(huà)相關(guān)的其他信息(除了會(huì )話(huà)ID)也可以存在cookie方便進(jìn)行會(huì )話(huà)跟蹤。

④HttpSession:在所有會(huì )話(huà)跟蹤技術(shù)中,HttpSession對象是最強大也是功能最多的。當一個(gè)用戶(hù)第一次訪(fǎng)問(wèn)某個(gè)網(wǎng)站時(shí)會(huì )自動(dòng)創(chuàng )建HttpSession,每個(gè)用戶(hù)可以訪(fǎng)問(wèn)他自己的HttpSession??梢酝ㄟ^(guò)HttpServletRequest對象的getSession方法獲得HttpSession,通過(guò)HttpSession的setAttribute方法可以將一個(gè)值放在HttpSession中,通過(guò)調用HttpSession對象的getAttribute方法,同時(shí)傳入屬性名就可以獲取保存在HttpSession中的對象。與上面三種方式不同的是,HttpSession放在服務(wù)器的內存中,因此不要將過(guò)大的對象放在里面,即使目前的Servlet容器可以在內存將滿(mǎn)時(shí)將HttpSession中的對象移到其他存儲設備中,但是這樣勢必影響性能。添加到HttpSession中的值可以是任意Java對象,這個(gè)對象最好實(shí)現了Serializable接口,這樣Servlet容器在必要的時(shí)候可以將其序列化到文件中,否則在序列化時(shí)就會(huì )出現異常。

405.過(guò)濾器有哪些作用和用法?

答: Java Web開(kāi)發(fā)中的過(guò)濾器(filter)是從Servlet 2.3規范開(kāi)始增加的功能,并在Servlet 2.4規范中得到增強。對Web應用來(lái)說(shuō),過(guò)濾器是一個(gè)駐留在服務(wù)器端的Web組件,它可以截取客戶(hù)端和服務(wù)器之間的請求與響應信息,并對這些信息進(jìn)行過(guò)濾。當Web容器接受到一個(gè)對資源的請求時(shí),它將判斷是否有過(guò)濾器與這個(gè)資源相關(guān)聯(lián)。如果有,那么容器將把請求交給過(guò)濾器進(jìn)行處理。在過(guò)濾器中,你可以改變請求的內容,或者重新設置請求的報頭信息,然后再將請求發(fā)送給目標資源。當目標資源對請求作出響應時(shí)候,容器同樣會(huì )將響應先轉發(fā)給過(guò)濾器,再過(guò)濾器中,你可以對響應的內容進(jìn)行轉換,然后再將響應發(fā)送到客戶(hù)端。

常見(jiàn)的過(guò)濾器用途主要包括:對用戶(hù)請求進(jìn)行統一認證、對用戶(hù)的訪(fǎng)問(wèn)請求進(jìn)行記錄和審核、對用戶(hù)發(fā)送的數據進(jìn)行過(guò)濾或替換、轉換圖象格式、對響應內容進(jìn)行壓縮以減少傳輸量、對請求或響應進(jìn)行加解密處理、觸發(fā)資源訪(fǎng)問(wèn)事件、對XML的輸出應用XSLT等。

和過(guò)濾器相關(guān)的接口主要有:Filter、FilterConfig、FilterChain

406.監聽(tīng)器有哪些作用和用法?

答:Java Web開(kāi)發(fā)中的監聽(tīng)器(listener)就是application、session、request三個(gè)對象創(chuàng )建、銷(xiāo)毀或者往其中添加修改刪除屬性時(shí)自動(dòng)執行代碼的功能組件,如下所示:

①ServletContextListener:對Servlet上下文的創(chuàng )建和銷(xiāo)毀進(jìn)行監聽(tīng)。

②ServletContextAttributeListener:監聽(tīng)Servlet上下文屬性的添加、刪除和替換。

③HttpSessionListener:對Session的創(chuàng )建和銷(xiāo)毀進(jìn)行監聽(tīng)。

補充:session的銷(xiāo)毀有兩種情況:1session超時(shí)(可以在web.xml中通過(guò)< session-config>/< session-timeout>標簽配置超時(shí)時(shí)間);2通過(guò)調用session對象的invalidate()方法使session失效。

④HttpSessionAttributeListener:對Session對象中屬性的添加、刪除和替換進(jìn)行監聽(tīng)。

⑤ServletRequestListener:對請求對象的初始化和銷(xiāo)毀進(jìn)行監聽(tīng)。

⑥ServletRequestAttributeListener:對請求對象屬性的添加、刪除和替換進(jìn)行監聽(tīng)。

407.你的項目中使用過(guò)哪些JSTL標簽?

答:項目中主要使用了JSTL的核心標簽庫,包括< c:if>、< c:choose>、< c: when>、< c: otherwise>、< c:forEach>等,主要用于構造循環(huán)和分支結構以控制顯示邏輯。

【說(shuō)明】雖然JSTL標簽庫提供了core、sql、fmt、xml等標簽庫,但是實(shí)際開(kāi)發(fā)中建議只使用核心標簽庫(core),而且最好只使用分支和循環(huán)標簽并輔以表達式語(yǔ)言(EL),這樣才能真正做到數據顯示和業(yè)務(wù)邏輯的分離,這才是最佳實(shí)踐。

408.使用標簽庫有什么好處?如何自定義JSP標簽?

答:使用標簽庫的好處包括以下幾個(gè)方面:

分離JSP頁(yè)面的內容和邏輯,簡(jiǎn)化了Web開(kāi)發(fā);

開(kāi)發(fā)者可以創(chuàng )建自定義標簽來(lái)封裝業(yè)務(wù)邏輯和顯示邏輯;

標簽具有很好的可移植性、可維護性和可重用性;

避免了對Scriptlet(小腳本)的使用(很多公司的項目開(kāi)發(fā)都不允許在JSP中書(shū)寫(xiě)小腳本)

自定義JSP標簽包括以下幾個(gè)步驟:

編寫(xiě)一個(gè)Java類(lèi)實(shí)現實(shí)現Tag/BodyTag/IterationTag接口(通常不直接實(shí)現這些接口而是繼承TagSupport/BodyTagSupport/SimpleTagSupport類(lèi),這是對適配器模式中缺省適配模式的應用)

重寫(xiě)doStartTag()、doEndTag()等方法,定義標簽要完成的功能

編寫(xiě)擴展名為tld的標簽描述文件對自定義標簽進(jìn)行部署,tld文件通常放在WEB-INF文件夾或其子目錄

在JSP頁(yè)面中使用taglib指令引用該標簽庫

下面是一個(gè)例子:

package com.bjsxt;
package com.lovo.tags;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.TagSupport;

public class TimeTag extends TagSupport {
    private static final long serialVersionUID = 1L;

    private String format = "yyyy-MM-dd hh:mm:ss";
    private String foreColor = "black";
    private String backColor = "white";

    public int doStartTag() throws JspException {
         SimpleDateFormat sdf = new SimpleDateFormat(format);
         JspWriter writer = pageContext.getOut();
         StringBuilder sb = new StringBuilder();
         sb.append(String.format("<span style='color:%s;background-color:%s'>%s</span>",
             foreColor, backColor, sdf.format(new Date())));
         try {
           writer.print(sb.toString());
         } catch(IOException e) {
           e.printStackTrace();
         }
         return SKIP_BODY;
      }

    public void setFormat(String format) {
        this.format = format;
    }

    public void setForeColor(String foreColor) {
        this.foreColor = foreColor;
    }

    public void setBackColor(String backColor) {
        this.backColor = backColor;
    }
}

標簽庫描述文件(該文件通常放在WEB-INF目錄或其子目錄下)

<?xml version="1.0" encoding="UTF-8" ?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
    http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
    version="2.0">

    <description>定義標簽庫</description>
    <tlib-version>1.0</tlib-version>
    <short-name>MyTag</short-name>
    <tag>
        <name>time</name>
        <tag-class>com.lovo.tags.TimeTag</tag-class>
        <body-content>empty</body-content>
        <attribute>
            <name>format</name>
            <required>false</required>
        </attribute>
        <attribute>
            <name>foreColor</name>
        </attribute>
        <attribute>
            <name>backColor</name>
        </attribute>
    </tag>
</taglib>

JSP頁(yè)面

<%@ page pageEncoding="UTF-8"%>
<%@ taglib prefix="my" uri="/WEB-INF/tld/my.tld" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE html>
<html>
  <head>
    <base href="<%=basePath%>">
    <title>首頁(yè)</title>
    <style type="text/css">
        * { font-family: "Arial"; font-size:72px; }
    </style>
  </head>

  <body>
    <my:time format="yyyy-MM-dd" backColor="blue" foreColor="yellow"/>
  </body>
</html>

運行結果

【注意】如果要將自定義的標簽庫發(fā)布成JAR文件,需要將標簽庫描述文件(tld文件)放在JAR文件的META-INF目錄下,可以JDK自帶的jar工具完成JAR文件的生成。

409.表達式語(yǔ)言(EL)的隱式對象及其作用?

答: pageContext、initParam(訪(fǎng)問(wèn)上下文參數)、param(訪(fǎng)問(wèn)請求參數)、paramValues、header(訪(fǎng)問(wèn)請求頭)、headerValues、cookie(訪(fǎng)問(wèn)cookie)、applicationScope(訪(fǎng)問(wèn)application作用域)、sessionScope(訪(fǎng)問(wèn)session作用域)、requestScope(訪(fǎng)問(wèn)request作用域)、pageScope(訪(fǎng)問(wèn)page作用域)。用法如下所示:

${pageContext.request.method}

${pageContext["request"]["method"]}

${pageContext.request["method"]}

${pageContext["request"].method}

${initParam.defaultEncoding}

${header["accept-language"]}

${headerValues["accept-language"][0]}

${cookie.jsessionid.value}

${sessionScope.loginUser.username}

【補充】表達式語(yǔ)言的.和[]運算作用是一致的,唯一的差別在于如果訪(fǎng)問(wèn)的屬性名不符合Java標識符命名規則,例如上面的accept-language就不是一個(gè)有效的Java標識符,那么這時(shí)候就只能用[]運算符而不能使用.獲取它的值

410.表達式語(yǔ)言(EL)支持哪些運算符?

答:除了.和[]運算符,EL還提供了:

算術(shù)運算符:+、-、*、/或div、%或mod

關(guān)系運算符:==或eq、!=或ne、>或gt、>=或ge、< 或lt、< =或le

邏輯運算符:&&或and、||或or、!或not

條件運算符:${statement? A : B}(跟Java的條件運算符類(lèi)似)

empty運算符:檢查一個(gè)值是否為null或者空(數組長(cháng)度為0或集合中沒(méi)有元素也返回true)

411.Servlet 3中的異步處理指的是什么?

答:在Servlet 3中引入了一項新的技術(shù)可以讓Servlet異步處理請求。有人可能會(huì )質(zhì)疑,既然都有多線(xiàn)程了,還需要異步處理請求嗎?答案是肯定的,因為如果一個(gè)任務(wù)處理時(shí)間相當長(cháng),那么Servlet或Filter會(huì )一直占用著(zhù)請求處理線(xiàn)程直到任務(wù)結束,隨著(zhù)并發(fā)用戶(hù)的增加,容器將會(huì )遭遇線(xiàn)程超出的風(fēng)險,這這種情況下很多的請求將會(huì )被堆積起來(lái)而后續的請求可能會(huì )遭遇拒絕服務(wù),直到有資源可以處理請求為止。異步特性可以幫助應用節省容器中的線(xiàn)程,特別適合執行時(shí)間長(cháng)而且用戶(hù)需要得到結果的任務(wù),如果用戶(hù)不需要得到結果則直接將一個(gè)Runnable對象交給Executor(如果不清楚請查看前文關(guān)于多線(xiàn)程和線(xiàn)程池的部分)并立即返回即可。

【補充】多線(xiàn)程在Java誕生初期無(wú)疑是一個(gè)亮點(diǎn),而Servlet單實(shí)例多線(xiàn)程的工作方式也曾為其贏(yíng)得美名,然而技術(shù)的發(fā)展往往會(huì )顛覆我們很多的認知,就如同當年愛(ài)因斯坦的相對論顛覆了牛頓的經(jīng)典力學(xué)一般。事實(shí)上,異步處理絕不是Serlvet 3首創(chuàng ),如果你了解Node.js的話(huà),對Servlet 3的這個(gè)重要改進(jìn)就不以為奇了。

412.如何在基于Java的Web項目中實(shí)現文件上傳和下載?

答:(稍后呈現,我準備用HTML5寫(xiě)一個(gè)帶進(jìn)度條的客戶(hù)端,然后再用Servlet 3提供的文件上傳支持來(lái)做一個(gè)多文件上傳的例子)

413.簡(jiǎn)述值棧(Value-Stack)的原理和生命周期

答: Value-Stack貫穿整個(gè) Action 的生命周期,保存在request作用域中,所以它和request的生命周期一樣。當Struts 2接受一個(gè)請求時(shí),會(huì )創(chuàng )建ActionContext、Value-Stack和Action對象,然后把Action存放進(jìn)Value-Stack,所以Action的實(shí)例變量可以通過(guò)OGNL訪(fǎng)問(wèn)。由于A(yíng)ction是多實(shí)例的,和使用單例的Servlet不同, 每個(gè)Action都有一個(gè)對應的Value-Stack,Value-Stack存放的數據類(lèi)型是該Action的實(shí)例,以及該Action中的實(shí)例變量,Action對象默認保存在棧頂。

414.闡述Session加載實(shí)體對象的過(guò)程。

答:Session加載實(shí)體對象的步驟是:

① Session在調用數據庫查詢(xún)功能之前, 首先會(huì )在緩存中進(jìn)行查詢(xún), 在一級緩存中, 通過(guò)實(shí)體類(lèi)型和主鍵進(jìn)行查找, 如果一級緩存查找命中且數據狀態(tài)合法, 則直接返回

② 如果一級緩存沒(méi)有命中, 接下來(lái)Session會(huì )在當前NonExists記錄(相當于一個(gè)查詢(xún)黑名單, 如果出現重復的無(wú)效查詢(xún)可以迅速判斷, 從而提升性能)中進(jìn)行查找, 如果NonExists中存在同樣的查詢(xún)條件,則返回null

③ 對于load方法, 如果一級緩存查詢(xún)失敗則查詢(xún)二級緩存, 如果二級緩存命中則直接返回

④ 如果之前的查詢(xún)都未命中, 則發(fā)出SQL語(yǔ)句, 如果查詢(xún)未發(fā)現對應記錄則將此次查詢(xún)添加到Session的NonExists中加以記錄, 并返回null

⑤ 根據映射配置和SQL語(yǔ)句得到ResultSet,并創(chuàng )建對應的實(shí)體對象

⑥ 將對象納入Session(一級緩存)管理

⑦ 執行攔截器的onLoad方法(如果有對應的攔截器)

⑧ 將數據對象納入二級緩存

⑨ 返回數據對象

415.怎么防止重復提交

1.禁掉提交按鈕。表單提交后使用Javascript使提交按鈕disable。這種方法防止心急的用戶(hù)多次點(diǎn)擊按鈕。但有個(gè)問(wèn)題,如果客戶(hù)端把Javascript給禁止掉,這種方法就無(wú)效了。

2.Post/Redirect/Get模式。在提交后執行頁(yè)面重定向,這就是所謂的Post-Redirect-Get (PRG)模式。簡(jiǎn)言之,當用戶(hù)提交了表單后,你去執行一個(gè)客戶(hù)端的重定向,轉到提交成功信息頁(yè)面。

這能避免用戶(hù)按F5導致的重復提交,而其也不會(huì )出現瀏覽器表單重復提交的警告,也能消除按瀏覽器前進(jìn)和后退按導致的同樣問(wèn)題。

3.在session中存放一個(gè)特殊標志。當表單頁(yè)面被請求時(shí),生成一個(gè)特殊的字符標志串,存在session中,同時(shí)放在表單的隱藏域里。接受處理表單數據時(shí),檢查標識字串是否存在,并立即從session中刪除它,然后正常處理數據。

如果發(fā)現表單提交里沒(méi)有有效的標志串,這說(shuō)明表單已經(jīng)被提交過(guò)了,忽略這次提交。

4.在數據庫里添加約束。在數據庫里添加唯一約束或創(chuàng )建唯一索引,防止出現重復數據。這是最有效的防止重復提交數據的方法。

416.$(document).ready(function(){}) jQuery(document).ready(function(){}); 有什么區別?

window.jQuery = window.$ = jQuery;

這兩者可以互換使用。一般建議優(yōu)先使用$

417.寫(xiě)出輸出結果

<script>
                        function Foo() {
                        getName = function (){alert(1);};
                        return this;
                        }
                        Foo.getName = function() {alert (2);};
                        Foo.prototype.getName = function (){ alert (3);};
                        var getName = function (){alert (4);};
                        function getName(){alert (5);}
                        </script>

//請寫(xiě)出以下輸出結果:

Foo.getName(); // 2

getName(); // 4

Foo().getName(); // 1

getName(); // 1

new Foo.getName(); // 2

new Foo().getName(); // 3

new new Foo().getName(); // 3

418.web項目從瀏覽器發(fā)起交易響應緩慢,請簡(jiǎn)述從哪些方面如數分析

從前端后端分別取考慮,后臺是不是數據庫死鎖等。

前臺看看是不是js 錯誤,或者圖片過(guò)大,dom 渲染dom樹(shù),畫(huà)面優(yōu)化。cmd amd 規范等

設計模式
419.請寫(xiě)出您熟悉的幾種設計模式,并做簡(jiǎn)單介紹。

答:工廠(chǎng)設計模式:程序在接口和子類(lèi)之間加入了一個(gè)過(guò)渡端,通過(guò)此過(guò)渡端可以動(dòng)態(tài)取得實(shí)現了共同接口的子類(lèi)實(shí)例化對象。

代理設計模式:指由一個(gè)代理主題來(lái)操作真實(shí)主題,真實(shí)主題執行具體的業(yè)務(wù)操作,而代理主題負責其他相關(guān)業(yè)務(wù)的處理。比如生活中的通過(guò)代理訪(fǎng)問(wèn)網(wǎng)絡(luò ),客戶(hù)通過(guò)網(wǎng)絡(luò )代理連接網(wǎng)絡(luò )(具體業(yè)務(wù)),由代理服務(wù)器完成用戶(hù)權限和訪(fǎng)問(wèn)限制等與上網(wǎng)相關(guān)的其他操作(相關(guān)業(yè)務(wù))

適配器模式:如果一個(gè)類(lèi)要實(shí)現一個(gè)具有很多抽象方法的接口,但是本身只需要實(shí)現接口中的部分方法便可以達成目的,所以此時(shí)就需要一個(gè)中間的過(guò)渡類(lèi),但此過(guò)渡類(lèi)又不希望直接使用,所以將此類(lèi)定義為抽象類(lèi)最為合適,再讓以后的子類(lèi)直接繼承該抽象類(lèi)便可選擇性的覆寫(xiě)所需要的方法,而此抽象類(lèi)便是適配器類(lèi)。

420.寫(xiě)出你用過(guò)的設計模式,并至少寫(xiě)出2種模式的類(lèi)圖或關(guān)鍵代碼。

工廠(chǎng)設計模式:

思路說(shuō)明:由一個(gè)工廠(chǎng)類(lèi)根據傳入的參數(一般是字符串參數),動(dòng)態(tài)決定應該創(chuàng )建哪一個(gè)產(chǎn)品子類(lèi)(這些產(chǎn)品子類(lèi)繼承自同一個(gè)父類(lèi)或接口)的實(shí)例,并以父類(lèi)形式返回

優(yōu)點(diǎn):客戶(hù)端不負責對象的創(chuàng )建,而是由專(zhuān)門(mén)的工廠(chǎng)類(lèi)完成;客戶(hù)端只負責對象的調用,實(shí)現了創(chuàng )建和調用的分離,降低了客戶(hù)端代碼的難度;

缺點(diǎn):如果增加和減少產(chǎn)品子類(lèi),需要修改簡(jiǎn)單工廠(chǎng)類(lèi),違背了開(kāi)閉原則;如果產(chǎn)品子類(lèi)過(guò)多,會(huì )導致工廠(chǎng)類(lèi)非常的龐大,違反了高內聚原則,不利于后期維護。

public class SimpleFactory {
public static Product createProduct(String pname){
Product product=null;
if("p1".equals(pname)){
product = new Product1();
}else if("p2".equals(pname)){
product = new Product2();
}else if("pn".equals(pname)){
product = new ProductN();
}
return product;
}
}

單例模式

/**
 * 餓漢式的單例模式
 * 在類(lèi)加載的時(shí)候創(chuàng  )建單例實(shí)例,而不是等到第一次請求實(shí)例的時(shí)候的時(shí)候創(chuàng  )建
* 1、私有 的無(wú)參數構造方法Singleton(),避免外部創(chuàng  )建實(shí)例
 * 2、私有靜態(tài)屬性instance
 * 3、公有靜態(tài)方法getInstance()
 */
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton(){ }
public static Singleton getInstance(){
return instance;
}
}
/**
 * 懶漢式的單例模式
 *在類(lèi)加載的時(shí)候不創(chuàng  )建單例實(shí)例,只有在第一次請求實(shí)例的時(shí)候的時(shí)候創(chuàng  )建
*/
public class Singleton {
private static Singleton instance;
private Singleton(){ }
/**
 * 多線(xiàn)程情況的單例模式,避免創(chuàng  )建多個(gè)對象
*/
public static Singleton getInstance(){
if(instance ==null){//避免每次加鎖,只有第一次沒(méi)有創(chuàng  )建對象時(shí)才加鎖
synchronized(Singleton.class){//加鎖,只允許一個(gè)線(xiàn)程進(jìn)入
if(instance==null){ //只創(chuàng  )建一次對象
instance = new Singleton();
}
}
}
return instance;
}}
421.列出除Singleton外的常用的3種設計模式,并簡(jiǎn)單描述

答:工廠(chǎng)模式:工廠(chǎng)模式是 Java 中最常用的設計模式之一。這種類(lèi)型的設計模式屬于創(chuàng )建型模式,它提供了一種創(chuàng )建對象的最佳方式。在工廠(chǎng)模式中,我們在創(chuàng )建對象時(shí)不會(huì )對客戶(hù)端暴露創(chuàng )建邏輯,并且是通過(guò)使用一個(gè)共同的接口來(lái)指向新創(chuàng )建的對象。

適配器模式:適配器模式是作為兩個(gè)不兼容的接口之間的橋梁。這種類(lèi)型的設計模式屬于結構型模式,它結合了兩個(gè)獨立接口的功能。這種模式涉及到一個(gè)單一的類(lèi),該類(lèi)負責加入獨立的或不兼容的接口功能。

模板模式:在模板模式中,一個(gè)抽象類(lèi)公開(kāi)定義了執行它的方法的方式/模板。它的子類(lèi)可以按需要重寫(xiě)方法實(shí)現,但調用將以抽象類(lèi)中定義的方式進(jìn)行。

422.Action是單實(shí)例還是多實(shí)例,為什么?

答:struts2中action是多例的,即一個(gè)session產(chǎn)生一個(gè)action

背景:

1) Struts2會(huì )對每一個(gè)請求,產(chǎn)生一個(gè)Action的實(shí)例來(lái)處理.

2) Spring的Ioc容器管理的bean默認是單實(shí)例的.

首先從數據安全性的問(wèn)題上考慮,我們的Action應該保證是多例的,這樣才不會(huì )出現數據問(wèn)題。但是如果有的action比如只有admin才能操作,或者某些action,全站公用一個(gè)來(lái)提高性能,這樣的話(huà),就可以使用單例模式。

不過(guò)幸好,Spring的bean可以針對每一個(gè)設置它的scope,所以,上面的問(wèn)題就不是問(wèn)題了。如果用單例,就在spring的action bean配置的時(shí)候設置scope=”prototype”

如果是單例的話(huà),若出現兩個(gè)用戶(hù)都修改一個(gè)對象的屬性值,則會(huì )因為用戶(hù)修改時(shí)間不同,兩個(gè)用戶(hù)訪(fǎng)問(wèn)得到的屬性不一樣,操作得出的結果不一樣.

舉個(gè)例子:有一塊布長(cháng)度300cm,能做一件上衣(用掉100cm)和一件褲子(用掉200cm);甲和乙同時(shí)訪(fǎng)問(wèn)得到的長(cháng)度都是300cm,

甲想做上衣和褲子,他先截取100cm去做上衣,等上衣做完再去做褲子,而乙這時(shí)正好也拿100cm去做上衣,那好,等甲做完上衣再做褲子的時(shí)候發(fā)現剩下的布(100cm)已經(jīng)不夠做褲子了…..這就是影響系統的性能,解決的辦法就是給甲和乙一人一塊300cm的布,就不會(huì )出現布被別人偷用的事情,也是就單實(shí)例和多實(shí)例的區別

如果設置成單例,那么多個(gè)線(xiàn)程會(huì )共享一個(gè)ActionContext和ValueStack,這樣并發(fā)訪(fǎng)問(wèn)的時(shí)候就會(huì )出現問(wèn)題了

struts 2的Action是多實(shí)例的并非單例,也就是每次請求產(chǎn)生一個(gè)Action的對象。原因是:struts 2的Action中包含數據,例如你在頁(yè)面填寫(xiě)的數據就會(huì )包含在A(yíng)ction的成員變量里面。如果Action是單實(shí)例的話(huà),這些數據在多線(xiàn)程的環(huán)境下就會(huì )相互影響,例如造成別人填寫(xiě)的數據被你看到了。所以Struts2的Action是多例模式的。

問(wèn)題出現了,可以讓Struts2的action變成單例模式么?

Struts2中,可以使用注解開(kāi)發(fā),在A(yíng)ction上@Scope(“prototype”) 指定為多例 , 默認為singleton()單例)

基本上action的scope需要是prototype,就是每次請求都建立新的線(xiàn)程

不寫(xiě)的話(huà),默認是singleton了

423.寫(xiě)一個(gè)單例類(lèi)

答:?jiǎn)卫J街饕饔檬潜WC在Java應用程序中,一個(gè)類(lèi)只有一個(gè)實(shí)例存在。下面給出兩種不同形式的單例:

第一種形式:餓漢式單例?

package com.bjsxt;

public class Singleton {
    private Singleton(){}
    private static Singleton instance = new Singleton();
    public static Singleton getInstance(){
        return instance;
    }
}

第二種形式:懶漢式單例

package com.bjsxt;

public class Singleton {
    private static Singleton instance = null;
    private Singleton() {}
    public static synchronized Singleton getInstance(){
        if (instance==null) instance=newSingleton();
        return instance;
    }
}

單例的特點(diǎn):外界無(wú)法通過(guò)構造器來(lái)創(chuàng )建對象,該類(lèi)必須提供一個(gè)靜態(tài)方法向外界提供該類(lèi)的唯一實(shí)例。

【補充】用Java進(jìn)行服務(wù)器端編程時(shí),使用單例模式的機會(huì )還是很多的,服務(wù)器上的資源都是很寶貴的,對于那些無(wú)狀態(tài)的對象其實(shí)都可以單例化或者靜態(tài)化(在內存中僅有唯一拷貝),如果使用了spring這樣的框架來(lái)進(jìn)行對象托管,Spring的IoC容器在默認情況下對所有托管對象都是進(jìn)行了單例化處理的。?

424.說(shuō)說(shuō)你所熟悉或聽(tīng)說(shuō)過(guò)的設計模式以及你對設計模式的看法

答:在GoF的《Design Patterns: Elements of Reusable Object-Oriented Software》中給出了三類(lèi)(創(chuàng )建型[對類(lèi)的實(shí)例化過(guò)程的抽象化]、結構型[描述如何將類(lèi)或對象結合在一起形成更大的結構]、行為型[對在不同的對象之間劃分責任和算法的抽象化])共23種設計模式,包括:Abstract Factory(抽象工廠(chǎng)模式),Builder(建造者模式),Factory Method(工廠(chǎng)方法模式),Prototype(原始模型模式),Singleton(單例模式);Facade(門(mén)面模式),Adapter(適配器模式),Bridge(橋梁模式),Composite(合成模式),Decorator(裝飾模式),Flyweight(享元模式),Proxy(代理模式);Command(命令模式),Interpreter(解釋器模式),Visitor(訪(fǎng)問(wèn)者模式),Iterator(迭代子模式),Mediator(調停者模式),Memento(備忘錄模式),Observer(觀(guān)察者模式),State(狀態(tài)模式),Strategy(策略模式),Template Method(模板方法模式), Chain Of Responsibility(責任鏈模式)。

所謂設計模式,就是一套被反復使用的代碼設計經(jīng)驗的總結(情境中一個(gè)問(wèn)題經(jīng)過(guò)證實(shí)的一個(gè)解決方案)。使用設計模式是為了可重用代碼、讓代碼更容易被他人理解、保證代碼可靠性。設計模式使人們可以更加簡(jiǎn)單方便的復用成功的設計和體系結構。將已證實(shí)的技術(shù)表述成設計模式也會(huì )使新系統開(kāi)發(fā)者更加容易理解其設計思路。

【補充】設計模式并不是像某些地方吹噓的那樣是遙不可及的編程理念,說(shuō)白了設計模式就是對面向對象的編程原則的實(shí)踐,面向對象的編程原則包括:

單一職責原則:一個(gè)類(lèi)只做它該做的事情。(單一職責原則想表達的就是“高內聚”,寫(xiě)代碼最終極的原則只有六個(gè)字“高內聚、低耦合”,就如同葵花寶典或辟邪劍譜的中心思想就八個(gè)字“欲練此功必先自宮”,所謂的高內聚就是一個(gè)代碼模塊只完成一項功能,在面向對象中,如果只讓一個(gè)類(lèi)完成它該做的事,而不涉及與它無(wú)關(guān)的領(lǐng)域就是踐行了高內聚的原則,這個(gè)類(lèi)就只有單一職責。我們都知道一句話(huà)叫“因為專(zhuān)注,所以專(zhuān)業(yè)”,一個(gè)對象如果承擔太多的職責,那么注定它什么都做不好。這個(gè)世界上任何好的東西都有兩個(gè)特征,一個(gè)是功能單一,好的相機絕對不是電視購物里面賣(mài)的那種一個(gè)機器有一百多種功能的,它基本上只能照相;另一個(gè)是模塊化,好的自行車(chē)是組裝車(chē),從減震叉、剎車(chē)到變速器,所有的部件都是可以拆卸和重新組裝的,好的乒乓球拍也不是成品拍,一定是底板和膠皮可以拆分和自行組裝的,一個(gè)好的軟件系統,它里面的每個(gè)功能模塊也應該是可以輕易的拿到其他系統中使用的,這樣才能實(shí)現軟件復用的目標。)

開(kāi)閉原則:軟件實(shí)體應當對擴展開(kāi)放,對修改關(guān)閉。(在理想的狀態(tài)下,當我們需要為一個(gè)軟件系統增加新功能時(shí),只需要從原來(lái)的系統派生出一些新類(lèi)就可以,不需要修改原來(lái)的任何一行代碼。要做到開(kāi)閉有兩個(gè)要點(diǎn):①抽象是關(guān)鍵,一個(gè)系統中如果沒(méi)有抽象類(lèi)或接口系統就沒(méi)有擴展點(diǎn);②封裝可變性,將系統中的各種可變因素封裝到一個(gè)繼承結構中,如果多個(gè)可變因素混雜在一起,系統將變得復雜而換亂,如果不清楚如何封裝可變性,可以參考《設計模式精解》一書(shū)中對橋梁模式的講解的章節。)

依賴(lài)倒轉原則:面向接口編程。(該原則說(shuō)得直白和具體一些就是聲明方法的參數類(lèi)型、方法的返回類(lèi)型、變量的引用類(lèi)型時(shí),盡可能使用抽象類(lèi)型而不用具體類(lèi)型,因為抽象類(lèi)型可以被它的任何一個(gè)子類(lèi)型所替代,請參考下面的里氏替換原則。)

里氏替換原則:任何時(shí)候都可以用子類(lèi)型替換掉父類(lèi)型。(關(guān)于里氏替換原則的描述,Barbara Liskov女士的描述比這個(gè)要復雜得多,但簡(jiǎn)單的說(shuō)就是能用父類(lèi)型的地方就一定能使用子類(lèi)型。里氏替換原則可以檢查繼承關(guān)系是否合理,如果一個(gè)繼承關(guān)系違背了里氏替換原則,那么這個(gè)繼承關(guān)系一定是錯誤的,需要對代碼進(jìn)行重構。例如讓貓繼承狗,或者狗繼承貓,又或者讓正方形繼承長(cháng)方形都是錯誤的繼承關(guān)系,因為你很容易找到違反里氏替換原則的場(chǎng)景。需要注意的是:子類(lèi)一定是增加父類(lèi)的能力而不是減少父類(lèi)的能力,因為子類(lèi)比父類(lèi)的能力更多,把能力多的對象當成能力少的對象來(lái)用當然沒(méi)有任何問(wèn)題。)

接口隔離原則:接口要小而專(zhuān),絕不能大而全。(臃腫的接口是對接口的污染,既然接口表示能力,那么一個(gè)接口只應該描述一種能力,接口也應該是高度內聚的。例如,琴棋書(shū)畫(huà)就應該分別設計為四個(gè)接口,而不應設計成一個(gè)接口中的四個(gè)方法,因為如果設計成一個(gè)接口中的四個(gè)方法,那么這個(gè)接口很難用,畢竟琴棋書(shū)畫(huà)四樣都精通的人還是少數,而如果設計成四個(gè)接口,會(huì )幾項就實(shí)現幾個(gè)接口,這樣的話(huà)每個(gè)接口被復用的可能性是很高的。Java中的接口代表能力、代表約定、代表角色,能否正確的使用接口一定是編程水平高低的重要標識。)

合成聚合復用原則:優(yōu)先使用聚合或合成關(guān)系復用代碼。(通過(guò)繼承來(lái)復用代碼是面向對象程序設計中被濫用得最多的東西,因為所有的教科書(shū)都無(wú)一例外的對繼承進(jìn)行了鼓吹從而誤導了初學(xué)者,類(lèi)與類(lèi)之間簡(jiǎn)單的說(shuō)有三種關(guān)系,IS-A關(guān)系、HAS-A關(guān)系、USE-A關(guān)系,分別代表繼承、關(guān)聯(lián)和依賴(lài)。其中,關(guān)聯(lián)關(guān)系根據其關(guān)聯(lián)的強度又可以進(jìn)一步劃分為關(guān)聯(lián)、聚合和合成,但說(shuō)白了都是HAS-A關(guān)系,合成聚合復用原則想表達的是優(yōu)先考慮HAS-A關(guān)系而不是IS-A關(guān)系復用代碼,原因嘛可以自己從百度上找到一萬(wàn)個(gè)理由,需要說(shuō)明的是,即使在Java的API中也有不少濫用繼承的例子,例如Properties類(lèi)繼承了Hashtable類(lèi),Stack類(lèi)繼承了Vector類(lèi),這些繼承明顯就是錯誤的,更好的做法是在Properties類(lèi)中放置一個(gè)Hashtable類(lèi)型的成員并且將其鍵和值都設置為字符串來(lái)存儲數據,而Stack類(lèi)的設計也應該是在Stack類(lèi)中放一個(gè)Vector對象來(lái)存儲數據。記?。喝魏螘r(shí)候都不要繼承工具類(lèi),工具是可以擁有并可以使用的(HAS/USE),而不是拿來(lái)繼承的。)

迪米特法則:迪米特法則又叫最少知識原則,一個(gè)對象應當對其他對象有盡可能少的了解。(迪米特法則簡(jiǎn)單的說(shuō)就是如何做到“低耦合”,門(mén)面模式和調停者模式就是對迪米特法則的踐行。對于門(mén)面模式可以舉一個(gè)簡(jiǎn)單的例子,你去一家公司洽談業(yè)務(wù),你不需要了解這個(gè)公司內部是如何運作的,你甚至可以對這個(gè)公司一無(wú)所知,去的時(shí)候只需要找到公司入口處的前臺美女,告訴她們你要做什么,她們會(huì )找到合適的人跟你接洽,前臺的美女就是公司這個(gè)系統的門(mén)面。再復雜的系統都可以為用戶(hù)提供一個(gè)簡(jiǎn)單的門(mén)面,Java Web開(kāi)發(fā)中作為前端控制器的Servlet或Filter不就是一個(gè)門(mén)面嗎,瀏覽器對服務(wù)器的運作方式一無(wú)所知,但是通過(guò)前端控制器就能夠根據你的請求得到相應的服務(wù)。調停者模式也可以舉一個(gè)簡(jiǎn)單的例子來(lái)說(shuō)明,例如一臺計算機,CPU、內存、硬盤(pán)、顯卡、聲卡各種設備需要相互配合才能很好的工作,但是如果這些東西都直接連接到一起,計算機的布線(xiàn)將異常復雜,在這種情況下,主板作為一個(gè)調停者的身份出現,它將各個(gè)設備連接在一起而不需要每個(gè)設備之間直接交換數據,這樣就減小了系統的耦合度和復雜度。迪米特法則用通俗的話(huà)來(lái)將就是不要和陌生人打交道,如果真的需要,找一個(gè)自己的朋友,讓他替你和陌生人打交道。)

425.Java企業(yè)級開(kāi)發(fā)中常用的設計模式有哪些?

答: 按照分層開(kāi)發(fā)的觀(guān)點(diǎn),可以將應用劃分為:表示層、業(yè)務(wù)邏輯層和持久層,每一層都有屬于自己類(lèi)別的設計模式。

表示層設計模式:

1) Interceptor Filter:攔截過(guò)濾器,提供請求預處理和后處理的方案,可以對請求和響應進(jìn)行過(guò)濾。/p>

2) Front Controller:通過(guò)中央控制器提供請求管理和處理,管理內容讀取、安全性、視圖管理和導航等功能。Struts 2中的StrutsPrepareAndExecuteFilter、Spring MVC中的DispatcherServlet都是前端控制器,后者如下圖所示:

3) View Helper:視圖幫助器,負責將顯示邏輯和業(yè)務(wù)邏輯分開(kāi)。顯示的部分放在視圖組件中,業(yè)務(wù)邏輯代碼放在幫助器中,典型的功能是內容讀取、驗證與適配。

4) Composite View:復合視圖。

業(yè)務(wù)邏輯層設計模式:

1) Business Delegate:業(yè)務(wù)委托,減少表示層和業(yè)務(wù)邏輯層之間的耦合。

2) Value Object:值對象,解決層之間交換數據的開(kāi)銷(xiāo)問(wèn)題。

3) Session Fa?ade:會(huì )話(huà)門(mén)面,隱藏業(yè)務(wù)邏輯組件的細節,集中工作流程。

4) Value Object Assembler:靈活的組裝不同的值對象

5) Value List Handler:提供執行查詢(xún)和處理結果的解決方案,還可以緩存查詢(xún)結果,從而達到提升性能的目的。

6) Service Locator:服務(wù)定位器,可以查找、創(chuàng )建和定位服務(wù)工廠(chǎng),封裝其實(shí)現細節,減少復雜性,提供單個(gè)控制點(diǎn),通過(guò)緩存提高性能。

持久層設計模式:

Data Access Object:數據訪(fǎng)問(wèn)對象,以面向對象的方式完成對數據的增刪改查。

【補充】如果想深入的了解Java企業(yè)級應用的設計模式和架構模式,可以參考這些書(shū)籍:?《Pro Java EE Spring Patterns》、《POJO in Action》、《Patterns of Enterprise Application Architecture》。

426.你在開(kāi)發(fā)中都用到了那些設計模式?用在什么場(chǎng)合?

答:面試被問(wèn)到關(guān)于設計模式的知識時(shí),可以?huà)畛S玫淖鞔?,例如?/p>

1) 工廠(chǎng)模式:工廠(chǎng)類(lèi)可以根據條件生成不同的子類(lèi)實(shí)例,這些子類(lèi)有一個(gè)公共的抽象父類(lèi)并且實(shí)現了相同的方法,但是這些方法針對不同的數據進(jìn)行了不同的操作(多態(tài)方法)。當得到子類(lèi)的實(shí)例后,開(kāi)發(fā)人員可以調用基類(lèi)中的方法而不必考慮到底返回的是哪一個(gè)子類(lèi)的實(shí)例。

2) 代理模式:給一個(gè)對象提供一個(gè)代理對象,并由代理對象控制原對象的引用。實(shí)際開(kāi)發(fā)中,按照使用目的的不同,代理可以分為:遠程代理、虛擬代理、保護代理、Cache代理、防火墻代理、同步化代理、智能引用代理。

3) 適配器模式:把一個(gè)類(lèi)的接口變換成客戶(hù)端所期待的另一種接口,從而使原本因接口不匹配而無(wú)法在一起使用的類(lèi)能夠一起工作。

4) 模板方法模式:提供一個(gè)抽象類(lèi),將部分邏輯以具體方法或構造器的形式實(shí)現,然后聲明一些抽象方法來(lái)迫使子類(lèi)實(shí)現剩余的邏輯。不同的子類(lèi)可以以不同的方式實(shí)現這些抽象方法(多態(tài)實(shí)現),從而實(shí)現不同的業(yè)務(wù)邏輯。

除此之外,還可以講講上面提到的門(mén)面模式、橋梁模式、單例模式、裝潢模式(Collections工具類(lèi)里面的synchronizedXXX方法把一個(gè)線(xiàn)程不安全的容器變成線(xiàn)程安全容器就是對裝潢模式的應用,而Java IO里面的過(guò)濾流(有的翻譯成處理流)也是應用裝潢模式的經(jīng)典例子)等,反正原則就是揀自己最熟悉的用得最多的作答,以免言多必失。?

427.什么是設計模式,設計模式的作用。

設計模式是一套被反復使用的、多數人知曉、經(jīng)過(guò)分類(lèi)編目的優(yōu)秀代碼設計經(jīng)驗的總結。特定環(huán)境下特定問(wèn)題的處理方法。

1)重用設計和代碼 重用設計比重用代碼更有意義,自動(dòng)帶來(lái)代碼重用

2)提高擴展性 大量使用面向接口編程,預留擴展插槽,新的功能或特性很容易加入到系統中來(lái)

3)提高靈活性 通過(guò)組合提高靈活性,可允許代碼修改平穩發(fā)生,對一處修改不會(huì )波及到其他模塊

4) 提高開(kāi)發(fā)效率 正確使用設計模式,可以節省大量的時(shí)間

428.23種經(jīng)典設計模式都有哪些,如何分類(lèi)。
429.寫(xiě)出簡(jiǎn)單工廠(chǎng)模式的示例代碼
package com.bjsxt;

public class SimpleFactory {
public static Product createProduct(String pname){
Product product=null;
if("p1".equals(pname)){
product = new Product();
}else if("p2".equals(pname)){
product = new Product();
}else if("pn".equals(pname)){
product = new Product();
}
return product;
}
}

基本原理:由一個(gè)工廠(chǎng)類(lèi)根據傳入的參數(一般是字符串參數),動(dòng)態(tài)決定應該創(chuàng )建哪一個(gè)產(chǎn)品子類(lèi)(這些產(chǎn)品子類(lèi)繼承自同一個(gè)父類(lèi)或接口)的實(shí)例,并以父類(lèi)形式返回

優(yōu)點(diǎn):客戶(hù)端不負責對象的創(chuàng )建,而是由專(zhuān)門(mén)的工廠(chǎng)類(lèi)完成;客戶(hù)端只負責對象的調用,實(shí)現了創(chuàng )建和調用的分離,降低了客戶(hù)端代碼的難度;

缺點(diǎn):如果增加和減少產(chǎn)品子類(lèi),需要修改簡(jiǎn)單工廠(chǎng)類(lèi),違背了開(kāi)閉原則;如果產(chǎn)品子類(lèi)過(guò)多,會(huì )導致工廠(chǎng)類(lèi)非常的龐大,違反了高內聚原則,不利于后期維護

430.請對你所熟悉的一個(gè)設計模式進(jìn)行介紹

分析:建議挑選有一定技術(shù)難度,并且在實(shí)際開(kāi)發(fā)中應用較多的設計模式??梢蕴暨x裝飾模式和動(dòng)態(tài)代理模式。此處挑選動(dòng)態(tài)代理設計模式。

講解思路:生活案例引入、技術(shù)講解、優(yōu)缺點(diǎn)分析、典型應用。

1、生活案例引入:送生日蛋糕:

MM們要過(guò)生日了,怎么也得表示下吧。最起碼先送個(gè)蛋糕。蛋糕多種多樣了。巧克力,冰淇淋,奶油等等。這都是基本的了,再加點(diǎn)額外的裝飾,如蛋糕里放點(diǎn)花、放賀卡、放點(diǎn)干果吃著(zhù)更香等等。

分析:

方案1:如果采用繼承會(huì )造成大量的蛋糕子類(lèi)

方案2:蛋糕作為主體,花,賀卡,果仁等是裝飾者,需要時(shí)加到蛋糕上。要啥我就加啥。

技術(shù)講解

裝飾模式(別名Wrapper)是在不必改變原類(lèi)文件和使用繼承的情況下,動(dòng)態(tài)的擴展一個(gè)對象的功能。它通過(guò)創(chuàng )建一個(gè)包裝對象,也就是裝飾來(lái)包裹真實(shí)對象,提供了比繼承更具彈性的代替方案。

裝飾模式一般涉及到的角色

抽象構建角色(Component):給出一個(gè)抽象的接口,以規范準備接受附加責任的對象。

具體的構建角色(ConcreteComponent):定義一個(gè)將要接受附加責任的類(lèi)。

抽象的裝飾角色 (Decorator):持有一個(gè)抽象構建(Component)角色的引用,并定義一個(gè)與抽象構件一致的接口。

具體的裝飾角色(ConcreteDecorator):負責給構建對象“貼上”附加的責任。

3、優(yōu)缺點(diǎn)分析

優(yōu)點(diǎn)

1)Decorator模式與繼承關(guān)系的目的都是要擴展對象的功能,但是Decorato更多的靈活性。

2)把類(lèi)中的裝飾功能從類(lèi)中搬移出去,這樣可以簡(jiǎn)化原有的類(lèi)。有效地把類(lèi)的核心功能和裝飾功能區分開(kāi)了。

3)通過(guò)使用不同的具體裝飾類(lèi)以及這些裝飾類(lèi)的排列組合,可創(chuàng )造出很多不同行為的組合。

缺點(diǎn)

這種比繼承更加靈活機動(dòng)的特性,也同時(shí)意味著(zhù)更加多的復雜性。

裝飾模式會(huì )導致設計中出現許多小類(lèi),如果過(guò)度使用,會(huì )使程序變得很復雜。

符合的設計原則:

多用組合,少用繼承。利用繼承設計子類(lèi)的行為是在編譯時(shí)靜態(tài)決定的,且所有的子類(lèi)都會(huì )繼承到相同的行為。如能夠利用組合擴展對象的行為,就可在運行時(shí)動(dòng)態(tài)進(jìn)行擴展。

類(lèi)應設計的對擴展開(kāi)放,對修改關(guān)閉。

4、典型應用

java IO中需要完成對不同輸入輸出源的操作,如果單純的使用繼承這一方式,無(wú)疑需要很多的類(lèi)。比如說(shuō),我們操作文件需要一個(gè)類(lèi),實(shí)現文件的字節讀取需要一個(gè)類(lèi),實(shí)現文件的字符讀取又需要一個(gè)類(lèi)....一次類(lèi)推每個(gè)特定的操作都需要一個(gè)特定的類(lèi)。這無(wú)疑會(huì )導致大量的IO繼承類(lèi)的出現。顯然對于編程是很不利的。而是用裝飾模式則可以很好的解決這一問(wèn)題,在裝飾模式中:節點(diǎn)流(如FileInputStream)直接與輸入源交互,之后通過(guò)過(guò)濾流(FilterInputStream)進(jìn)行裝飾,這樣獲得的io對象便具有某幾個(gè)的功能,很好的拓展了IO的功能。

高級框架

431.什么是Maven?

Maven使用項目對象模型(POM)的概念,可以通過(guò)一小段描述信息來(lái)管理項目的構建,報告和文檔的軟件項目管理工具。

Maven 除了以程序構建能力為特色之外,還提供高級項目管理工具。由于 Maven 的缺省構建規則有較高的可重用性,所以常常用兩三行 Maven 構建腳本就可以構建簡(jiǎn)單的項目。由于 Maven 的面向項目的方法,許多 Apache Jakarta 項目發(fā)布時(shí)使用 Maven,而且公司項目采用 Maven 的比例在持續增長(cháng)。

Maven的出現,解決了開(kāi)發(fā)過(guò)程中的jar包升級及依賴(lài)的難題。它可以對項目依賴(lài)的jar包進(jìn)行管理,可以讓你的項目保持基本的依賴(lài),排除冗余jar包,并且可以讓你非常輕松的對依賴(lài)的jar包進(jìn)行版本升級。而這些僅僅是Maven最基本的功能,它可以在這基礎上對項目進(jìn)行清理、編譯、測試、打包、發(fā)布等等構建項目的工作。?

可以說(shuō),Maven是現在Java社區中最強大的項目管理和項目構建工具,而更加值得慶幸的是,這樣一個(gè)強大的工具,它的使用也是非常簡(jiǎn)單的。

現在,JavaEE項目使用的開(kāi)源軟件都可以通過(guò)Maven來(lái)獲取,并且,越來(lái)越多的公司也開(kāi)始使用Maven來(lái)管理構建項目了。

432.Maven和ANT的區別

1.maven&ant同屬apach是流行的構建工具。

都是為了簡(jiǎn)化軟件開(kāi)發(fā)而存在的。但是maven因為自身管理一個(gè)項目對象模型(project object model),這個(gè)模型其實(shí)就是抽象了一個(gè)項目的開(kāi)發(fā)流程,它包含了一個(gè)項目的生命周期的各個(gè)階段,并將這個(gè)周期固定下來(lái),這也就是約定大于配置。約定大于配置的意思就是,我maven將項目開(kāi)發(fā)的各個(gè)階段固定起來(lái)了,每個(gè)文件的存放位置,每個(gè)階段要生成什么文件、保存為什么格式并且要把它放在什么位置,我都固定好了。我知道一個(gè)軟件是怎么開(kāi)發(fā)出來(lái),如果一個(gè)項目要使用maven,可以,但你要遵循我的規則,文件目錄不要亂建亂放,只有這樣maven才會(huì )將源碼用起來(lái)。這就是約定大于配置,因為maven已經(jīng)將流程固定下來(lái)了,只要遵守約定,就不需要自己手動(dòng)去配置了,這將大大地提高開(kāi)發(fā)效率。就像是開(kāi)車(chē)一樣,只要知道點(diǎn)火、油門(mén)、方向、剎車(chē),就可以將車(chē)子開(kāi)東起來(lái)(當然出于安全和法律考慮,還是要考駕照的。),關(guān)于車(chē)子內部的傳動(dòng)原理,電氣原理,工程原理,普通人并不需要了解多少,日常夠用就好了。這也是約定大于配置的一個(gè)例子。配置就是自己造一輛車(chē)去開(kāi),有必要,有能力,有時(shí)間嗎?

2.maven的中央倉庫和pom.xml文件。中央倉庫統一存放了開(kāi)發(fā)用到的各種jar包,要用時(shí)只需要添加依賴(lài)到pom文件中,maven就會(huì )自動(dòng)下載,當然為了方便一般會(huì )在本地建一個(gè)倉庫,減少下載時(shí)間。pom文件是maven的配置文件,maven就是通過(guò)管理pom文件和一些核心插件來(lái)管理項目。當然我前面將maven擬人化了,其實(shí)maven是沒(méi)有智力的,一切都是封裝好的流程,只是maven將很多操作隱藏起來(lái)了。

3.ant的build.xml文件。build文件是ant的配置文件,ant依靠它來(lái)執行操作,與maven不同的是ant沒(méi)有固定一條程序鏈。你想要執行什么操作以及操作之間的順序和依賴(lài)關(guān)系,都需要手動(dòng)添加到build文件中,一點(diǎn)一滴都要寫(xiě)清楚,否則ant就不會(huì )執行。

4.maven和ant區別

Maven 擁有約定,只要遵守約定,它就知道你的源代碼在哪里。Maven 是聲明式的。你需要做的只是創(chuàng )建一個(gè) pom.xml 文件然后將源代碼放到默認的目錄。Maven 會(huì )幫你處理其它的事情。Maven 有一個(gè)生命周期,當你運行 mvn install 的時(shí)候被調用。這條命令告訴 Maven 執行一系列的有序的步驟,直到到達你指定的生命周期。缺點(diǎn)是運行許多默認目標。

而ant沒(méi)有約定,項目生命周期,它是命令式的。所有操作都要手動(dòng)去創(chuàng )建、布置。甚至連build.xml文件都需要手動(dòng)創(chuàng )建。

433.Maven倉庫是什么

Maven倉庫是基于簡(jiǎn)單文件系統存儲的,集中化管理Java API資源(構件)的一個(gè)服務(wù)。倉庫中的任何一個(gè)構件都有其唯一的坐標,根據這個(gè)坐標可以定義其在倉庫中的唯一存儲路徑。得益于 Maven 的坐標機制,任何 Maven項目使用任何一個(gè)構件的方式都是完全相同的,Maven 可以在某個(gè)位置統一存儲所有的 Maven 項目共享的構件,這個(gè)統一的位置就是倉庫,項目構建完畢后生成的構件也可以安裝或者部署到倉庫中,供其它項目使用。

對于Maven來(lái)說(shuō),倉庫分為兩類(lèi):本地倉庫和遠程倉庫。

434.Maven的工程類(lèi)型有哪些?

POM工程

POM工程是邏輯工程。用在父級工程或聚合工程中。用來(lái)做jar包的版本控制。

JAR工程

將會(huì )打包成jar用作jar包使用。即常見(jiàn)的本地工程 - Java Project。

WAR工程

將會(huì )打包成war,發(fā)布在服務(wù)器上的工程。如網(wǎng)站或服務(wù)。即常見(jiàn)的網(wǎng)絡(luò )工程 - Dynamic Web Project。war工程默認沒(méi)有WEB-INF目錄及web.xml配置文件,IDE通常會(huì )顯示工程錯誤,提供完整工程結構可以解決。

435.Maven常用命令有哪些?

install

本地安裝, 包含編譯,打包,安裝到本地倉庫

編譯 - javac

打包 - jar, 將java代碼打包為jar文件

安裝到本地倉庫 - 將打包的jar文件,保存到本地倉庫目錄中。

clean

清除已編譯信息。

刪除工程中的target目錄。

compile

只編譯。 javac命令

deploy

部署。 常見(jiàn)于結合私服使用的命令。

相當于是install+上傳jar到私服。

包含編譯,打包,安裝到本地倉庫,上傳到私服倉庫。

package

打包。 包含編譯,打包兩個(gè)功能。

436.ZooKeeper的作用是什么?

配置管理

在我們的應用中除了代碼外,還有一些就是各種配置。比如數據庫連接等。一般我們都是使用配置文件的方式,在代碼中引入這些配置文件。當我們只有一種配置,只有一臺服務(wù)器,并且不經(jīng)常修改的時(shí)候,使用配置文件是一個(gè)很好的做法,但是如果我們配置非常多,有很多服務(wù)器都需要這個(gè)配置,這時(shí)使用配置文件就不是個(gè)好主意了。這個(gè)時(shí)候往往需要尋找一種集中管理配置的方法,我們在這個(gè)集中的地方修改了配置,所有對這個(gè)配置感興趣的都可以獲得變更。Zookeeper就是這種服務(wù),它使用Zab這種一致性協(xié)議來(lái)提供一致性?,F在有很多開(kāi)源項目使用Zookeeper來(lái)維護配置,比如在HBase中,客戶(hù)端就是連接一個(gè)Zookeeper,獲得必要的HBase集群的配置信息,然后才可以進(jìn)一步操作。還有在開(kāi)源的消息隊列Kafka中,也使用Zookeeper來(lái)維護broker的信息。在A(yíng)libaba開(kāi)源的SOA框架Dubbo中也廣泛的使用Zookeeper管理一些配置來(lái)實(shí)現服務(wù)治理。

名字服務(wù)

名字服務(wù)這個(gè)就很好理解了。比如為了通過(guò)網(wǎng)絡(luò )訪(fǎng)問(wèn)一個(gè)系統,我們得知道對方的IP地址,但是IP地址對人非常不友好,這個(gè)時(shí)候我們就需要使用域名來(lái)訪(fǎng)問(wèn)。但是計算機是不能是域名的。怎么辦呢?如果我們每臺機器里都備有一份域名到IP地址的映射,這個(gè)倒是能解決一部分問(wèn)題,但是如果域名對應的IP發(fā)生變化了又該怎么辦呢?于是我們有了DNS這個(gè)東西。我們只需要訪(fǎng)問(wèn)一個(gè)大家熟知的(known)的點(diǎn),它就會(huì )告訴你這個(gè)域名對應的IP是什么。在我們的應用中也會(huì )存在很多這類(lèi)問(wèn)題,特別是在我們的服務(wù)特別多的時(shí)候,如果我們在本地保存服務(wù)的地址的時(shí)候將非常不方便,但是如果我們只需要訪(fǎng)問(wèn)一個(gè)大家都熟知的訪(fǎng)問(wèn)點(diǎn),這里提供統一的入口,那么維護起來(lái)將方便得多了。

分布式鎖

其實(shí)在第一篇文章中已經(jīng)介紹了Zookeeper是一個(gè)分布式協(xié)調服務(wù)。這樣我們就可以利用Zookeeper來(lái)協(xié)調多個(gè)分布式進(jìn)程之間的活動(dòng)。比如在一個(gè)分布式環(huán)境中,為了提高可靠性,我們的集群的每臺服務(wù)器上都部署著(zhù)同樣的服務(wù)。但是,一件事情如果集群中的每個(gè)服務(wù)器都進(jìn)行的話(huà),那相互之間就要協(xié)調,編程起來(lái)將非常復雜。而如果我們只讓一個(gè)服務(wù)進(jìn)行操作,那又存在單點(diǎn)。通常還有一種做法就是使用分布式鎖,在某個(gè)時(shí)刻只讓一個(gè)服務(wù)去干活,當這臺服務(wù)出問(wèn)題的時(shí)候鎖釋放,立即fail over到另外的服務(wù)。這在很多分布式系統中都是這么做,這種設計有一個(gè)更好聽(tīng)的名字叫Leader Election(leader選舉)。比如HBase的Master就是采用這種機制。但要注意的是分布式鎖跟同一個(gè)進(jìn)程的鎖還是有區別的,所以使用的時(shí)候要比同一個(gè)進(jìn)程里的鎖更謹慎的使用。

集群管理

在分布式的集群中,經(jīng)常會(huì )由于各種原因,比如硬件故障,軟件故障,網(wǎng)絡(luò )問(wèn)題,有些節點(diǎn)會(huì )進(jìn)進(jìn)出出。有新的節點(diǎn)加入進(jìn)來(lái),也有老的節點(diǎn)退出集群。這個(gè)時(shí)候,集群中其他機器需要感知到這種變化,然后根據這種變化做出對應的決策。比如我們是一個(gè)分布式存儲系統,有一個(gè)中央控制節點(diǎn)負責存儲的分配,當有新的存儲進(jìn)來(lái)的時(shí)候我們要根據現在集群目前的狀態(tài)來(lái)分配存儲節點(diǎn)。這個(gè)時(shí)候我們就需要動(dòng)態(tài)感知到集群目前的狀態(tài)。還有,比如一個(gè)分布式的SOA架構中,服務(wù)是一個(gè)集群提供的,當消費者訪(fǎng)問(wèn)某個(gè)服務(wù)時(shí),就需要采用某種機制發(fā)現現在有哪些節點(diǎn)可以提供該服務(wù)(這也稱(chēng)之為服務(wù)發(fā)現,比如Alibaba開(kāi)源的SOA框架Dubbo就采用了Zookeeper作為服務(wù)發(fā)現的底層機制)。還有開(kāi)源的Kafka隊列就采用了Zookeeper作為Cosnumer的上下線(xiàn)管理。

437.什么是Znode?

在Zookeeper中,znode是一個(gè)跟Unix文件系統路徑相似的節點(diǎn),可以往這個(gè)節點(diǎn)存儲或獲取數據。

Zookeeper底層是一套數據結構。這個(gè)存儲結構是一個(gè)樹(shù)形結構,其上的每一個(gè)節點(diǎn),我們稱(chēng)之為“znode”

zookeeper中的數據是按照“樹(shù)”結構進(jìn)行存儲的。而且znode節點(diǎn)還分為4中不同的類(lèi)型。

每一個(gè)znode默認能夠存儲1MB的數據(對于記錄狀態(tài)性質(zhì)的數據來(lái)說(shuō),夠了)

可以使用zkCli命令,登錄到zookeeper上,并通過(guò)ls、create、delete、get、set等命令操作這些znode節點(diǎn)

438.Znode節點(diǎn)類(lèi)型有哪些?

答:(1)PERSISTENT 持久化節點(diǎn): 所謂持久節點(diǎn),是指在節點(diǎn)創(chuàng )建后,就一直存在,直到有刪除操作來(lái)主動(dòng)清除這個(gè)節點(diǎn)。否則不會(huì )因為創(chuàng )建該節點(diǎn)的客戶(hù)端會(huì )話(huà)失效而消失。

(2)PERSISTENT_SEQUENTIAL 持久順序節點(diǎn):這類(lèi)節點(diǎn)的基本特性和上面的節點(diǎn)類(lèi)型是一致的。額外的特性是,在ZK中,每個(gè)父節點(diǎn)會(huì )為他的第一級子節點(diǎn)維護一份時(shí)序,會(huì )記錄每個(gè)子節點(diǎn)創(chuàng )建的先后順序?;谶@個(gè)特性,在創(chuàng )建子節點(diǎn)的時(shí)候,可以設置這個(gè)屬性,那么在創(chuàng )建節點(diǎn)過(guò)程中,ZK會(huì )自動(dòng)為給定節點(diǎn)名加上一個(gè)數字后綴,作為新的節點(diǎn)名。這個(gè)數字后綴的范圍是整型的最大值。?在創(chuàng )建節點(diǎn)的時(shí)候只需要傳入節點(diǎn) “/test_”,這樣之后,zookeeper自動(dòng)會(huì )給”test_”后面補充數字。

(3)EPHEMERAL 臨時(shí)節點(diǎn):和持久節點(diǎn)不同的是,臨時(shí)節點(diǎn)的生命周期和客戶(hù)端會(huì ) 話(huà)綁定。也就是說(shuō),如果客戶(hù)端會(huì )話(huà)失效,那么這個(gè)節點(diǎn)就會(huì )自動(dòng)被清除掉。注意,這里提到的是會(huì )話(huà)失效,而非連接斷開(kāi)。另外,在臨時(shí)節點(diǎn)下面不能創(chuàng )建子節點(diǎn)。?

這里還要注意一件事,就是當你客戶(hù)端會(huì )話(huà)失效后,所產(chǎn)生的節點(diǎn)也不是一下子就消失了,也要過(guò)一段時(shí)間,大概是10秒以?xún)?,可以試一下,本機操作生成節點(diǎn),在服務(wù)器端用命令來(lái)查看當前的節點(diǎn)數目,你會(huì )發(fā)現客戶(hù)端已經(jīng)stop,但是產(chǎn)生的節點(diǎn)還在。

EPHEMERAL_SEQUENTIAL 臨時(shí)自動(dòng)編號節點(diǎn):此節點(diǎn)是屬于臨時(shí)節點(diǎn),不過(guò)帶有順序,客戶(hù)端會(huì )話(huà)結束節點(diǎn)就消失。

439.什么是Dubbo?

Dubbo是阿里巴巴公司開(kāi)源的一個(gè)高性能優(yōu)秀的服務(wù)框架,使得應用可通過(guò)高性能的 RPC 實(shí)現服務(wù)的輸出和輸入功能,可以和Spring框架無(wú)縫集成。Dubbo框架,是基于容器運行的.。容器是Spring。

其核心部分包含:

1. 遠程通訊: 提供對多種基于長(cháng)連接的NIO框架抽象封裝,包括多種線(xiàn)程模型,序列化,以及“請求-響應”模式的信息交換方式。

2. 集群容錯: 提供基于接口方法的透明遠程過(guò)程調用,包括多協(xié)議支持,以及軟負載均衡,失敗容錯,地址路由,動(dòng)態(tài)配置等集群支持。

3. 自動(dòng)發(fā)現: 基于注冊中心目錄服務(wù),使服務(wù)消費方能動(dòng)態(tài)的查找服務(wù)提供方,使地址透明,使服務(wù)提供方可以平滑增加或減少機器。

Dubbo能做什么?

1.透明化的遠程方法調用,就像調用本地方法一樣調用遠程方法,只需簡(jiǎn)單配置,沒(méi)有任何API侵入。 ? ? ?

2.軟負載均衡及容錯機制,可在內網(wǎng)替代F5等硬件負載均衡器,降低成本,減少單點(diǎn)。

3. 服務(wù)自動(dòng)注冊與發(fā)現,不再需要寫(xiě)死服務(wù)提供方地址,注冊中心基于接口名查詢(xún)服務(wù)提供者的IP地址,并且能夠平滑添加或刪除服務(wù)提供者。

Dubbo的存在簡(jiǎn)單來(lái)說(shuō)就是要減小service層的壓力。

440.什么是RPC遠程過(guò)程調用?

遠程過(guò)程調用協(xié)議,它是一種通過(guò)網(wǎng)絡(luò )從遠程計算機程序上請求服務(wù),而不需要了解底層網(wǎng)絡(luò )技術(shù)的協(xié)議。RPC協(xié)議假定某些傳輸協(xié)議的存在,如TCP或UDP,為通信程序之間攜帶信息數據。在OSI網(wǎng)絡(luò )通信模型中,RPC跨越了傳輸層和應用層。RPC使得開(kāi)發(fā)包括網(wǎng)絡(luò )分布式多程序在內的應用程序更加容易。

441.Dubbo中有哪些角色?

registry

注冊中心. 是用于發(fā)布和訂閱服務(wù)的一個(gè)平臺.用于替代SOA結構體系框架中的ESB服務(wù)總線(xiàn)的。

發(fā)布

開(kāi)發(fā)服務(wù)端代碼完畢后, 將服務(wù)信息發(fā)布出去. 實(shí)現一個(gè)服務(wù)的公開(kāi).

訂閱

客戶(hù)端程序,從注冊中心下載服務(wù)內容 這個(gè)過(guò)程是訂閱.

訂閱服務(wù)的時(shí)候, 會(huì )將發(fā)布的服務(wù)所有信息,一次性下載到客戶(hù)端.

客戶(hù)端也可以自定義, 修改部分服務(wù)配置信息. 如: 超時(shí)的時(shí)長(cháng), 調用的重試次數等.

Consumer

服務(wù)的消費者, 就是服務(wù)的客戶(hù)端.

消費者必須使用Dubbo技術(shù)開(kāi)發(fā)部分代碼. 基本上都是配置文件定義.

provider

服務(wù)的提供者, 就是服務(wù)端.

服務(wù)端必須使用Dubbo技術(shù)開(kāi)發(fā)部分代碼. 以配置文件為主.

container

容器. Dubbo技術(shù)的服務(wù)端(Provider), 在啟動(dòng)執行的時(shí)候, 必須依賴(lài)容器才能正常啟動(dòng).

默認依賴(lài)的就是spring容器. 且Dubbo技術(shù)不能脫離spring框架.

在2.5.3版本的dubbo中, 默認依賴(lài)的是spring2.5版本技術(shù). 可以選用spring4.5以下版本.

在2.5.7版本的dubbo中, 默認依賴(lài)的是spring4.3.10版本技術(shù). 可以選擇任意的spring版本.

monitor

監控中心. 是Dubbo提供的一個(gè)jar工程.

主要功能是監控服務(wù)端(Provider)和消費端(Consumer)的使用數據的. 如: 服務(wù)端是什么,有多少接口,多少方法, 調用次數, 壓力信息等. 客戶(hù)端有多少, 調用過(guò)哪些服務(wù)端, 調用了多少次等.

442.Dubbo執行流程什么是?

0 start: 啟動(dòng)Spring容器時(shí),自動(dòng)啟動(dòng)Dubbo的Provider

1、register: Dubbo的Provider在啟動(dòng)后自動(dòng)會(huì )去注冊中心注冊?xún)热?注冊的內容包括:

1.1 Provider的 IP

1.2 Provider 的端口.

1.3 Provider 對外提供的接口列表.哪些方法.哪些接口類(lèi)

1.4 Dubbo 的版本.

1.5 訪(fǎng)問(wèn)Provider的協(xié)議.

2、subscribe: 訂閱.當Consumer啟動(dòng)時(shí),自動(dòng)去Registry獲取到所已注冊的服務(wù)的信息.

3、notify: 通知.當Provider的信息發(fā)生變化時(shí), 自動(dòng)由Registry向Consumer推送通知.

4、invoke: 調用. Consumer 調用Provider中方法

4.1 同步請求.消耗一定性能.但是必須是同步請求,因為需要接收調用方法后的結果.

5、count:次數. 每隔2分鐘,provoider和consumer自動(dòng)向Monitor發(fā)送訪(fǎng)問(wèn)次數.Monitor進(jìn)行統計.

443.說(shuō)說(shuō)Dubbo支持的協(xié)議有哪些?

1、Dubbo協(xié)議(官方推薦協(xié)議)

優(yōu)點(diǎn):

采用NIO復用單一長(cháng)連接,并使用線(xiàn)程池并發(fā)處理請求,減少握手和加大并發(fā)效率,性能較好(推薦使用)

缺點(diǎn):

大文件上傳時(shí),可能出現問(wèn)題(不使用Dubbo文件上傳)

2、RMI(Remote Method Invocation)協(xié)議

優(yōu)點(diǎn):

JDK自帶的能力??膳c原生RMI互操作,基于TCP協(xié)議

缺點(diǎn):

偶爾連接失敗.

3、Hessian協(xié)議

優(yōu)點(diǎn):

可與原生Hessian互操作,基于HTTP協(xié)議

缺點(diǎn):

需hessian.jar支持,http短連接的開(kāi)銷(xiāo)大

444.Dubbo支持的注冊中心有哪些?

1、Zookeeper(官方推薦)

優(yōu)點(diǎn):支持分布式.很多周邊產(chǎn)品.

缺點(diǎn): 受限于Zookeeper軟件的穩定性.Zookeeper專(zhuān)門(mén)分布式輔助軟件,穩定較優(yōu)

2、Multicast

優(yōu)點(diǎn):去中心化,不需要單獨安裝軟件.

缺點(diǎn):Provider和Consumer和Registry不能跨機房(路由)

3、Redis

優(yōu)點(diǎn):支持集群,性能高

缺點(diǎn):要求服務(wù)器時(shí)間同步.否則可能出現集群失敗問(wèn)題.

4、Simple

優(yōu)點(diǎn): 標準RPC服務(wù).沒(méi)有兼容問(wèn)題

缺點(diǎn): 不支持集群.

445.SessionFactory是線(xiàn)程安全的嗎?Session是線(xiàn)程安全的嗎,兩個(gè)線(xiàn)程能夠共享同一個(gè)Session嗎?

答:SessionFactory對應Hibernate的一個(gè)數據存儲的概念,它是線(xiàn)程安全的,可以被多個(gè)線(xiàn)程并發(fā)訪(fǎng)問(wèn)。SessionFactory一般只會(huì )在啟動(dòng)的時(shí)候構建。對于應用程序,最好將SessionFactory通過(guò)單例的模式進(jìn)行封裝以便于訪(fǎng)問(wèn)。Session是一個(gè)輕量級非線(xiàn)程安全的對象(線(xiàn)程間不能共享session),它表示與數據庫進(jìn)行交互的一個(gè)工作單元。Session是由SessionFactory創(chuàng )建的,在任務(wù)完成之后它會(huì )被關(guān)閉。Session是持久層服務(wù)對外提供的主要接口。Session會(huì )延遲獲取數據庫連接(也就是在需要的時(shí)候才會(huì )獲?。?。為了避免創(chuàng )建太多的session,可以使用ThreadLocal來(lái)取得當前的session,無(wú)論你調用多少次getCurrentSession()方法,返回的都是同一個(gè)session。

446.Session的load和get方法的區別是什么?

答:主要有以下三項區別:

1)如果沒(méi)有找到符合條件的記錄, get方法返回null,load方法拋出異常

2)get方法直接返回實(shí)體類(lèi)對象, load方法返回實(shí)體類(lèi)對象的代理

3)在Hibernate 3之前,get方法只在一級緩存(內部緩存)中進(jìn)行數據查找, 如果沒(méi)有找到對應的數據則越過(guò)二級緩存, 直接發(fā)出SQL語(yǔ)句完成數據讀取; load方法則可以充分利用二級緩存中的現有數據;當然從Hibernate 3開(kāi)始,get方法不再是對二級緩存只寫(xiě)不讀,它也是可以訪(fǎng)問(wèn)二級緩存的

簡(jiǎn)單的說(shuō),對于load()方法Hibernate認為該數據在數據庫中一定存在可以放心的使用代理來(lái)實(shí)現延遲加載,如果沒(méi)有數據就拋出異常,而通過(guò)get()方法去取的數據可以不存在。

447.Session的save()、update()、merge()、lock()、saveOrUpdate()和persist()方法有什么區別?

答:Hibernate的對象有三種狀態(tài):瞬態(tài)、持久態(tài)和游離態(tài)。游離狀態(tài)的實(shí)例可以通過(guò)調用save()、persist()或者saveOrUpdate()方法進(jìn)行持久化;脫管狀態(tài)的實(shí)例可以通過(guò)調用 update()、0saveOrUpdate()、lock()或者replicate()進(jìn)行持久化。save()和persist()將會(huì )引發(fā)SQL的INSERT語(yǔ)句,而update()或merge()會(huì )引發(fā)UPDATE語(yǔ)句。save()和update()的區別在于一個(gè)是將瞬態(tài)對象變成持久態(tài),一個(gè)是將游離態(tài)對象變?yōu)槌志脩B(tài)。merge方法可以完成save()和update()方法的功能,它的意圖是將新的狀態(tài)合并到已有的持久化對象上或創(chuàng )建新的持久化對象。按照官方文檔的說(shuō)明:(1)persist()方法把一個(gè)瞬態(tài)的實(shí)例持久化,但是并"不保證"標識符被立刻填入到持久化實(shí)例中,標識符的填入可能被推遲到flush的時(shí)間;(2) persist"保證",當它在一個(gè)事務(wù)外部被調用的時(shí)候并不觸發(fā)一個(gè)Insert語(yǔ)句,當需要封裝一個(gè)長(cháng)會(huì )話(huà)流程的時(shí)候,一個(gè)persist這樣的函數是需要的。(3)save"不保證"第2條,它要返回標識符,所以它會(huì )立即執行Insert語(yǔ)句,不管是不是在事務(wù)內部還是外部。update()方法是把一個(gè)已經(jīng)更改過(guò)的脫管狀態(tài)的對象變成持久狀態(tài);lock()方法是把一個(gè)沒(méi)有更改過(guò)的脫管狀態(tài)的對象變成持久狀態(tài)。

448.什么是VSFTPD?

vsftpd 是“very secure FTP daemon”的縮寫(xiě),安全性是它的一個(gè)最大的特點(diǎn)。vsftpd 是一個(gè) UNIX 類(lèi)操作系統上運行的服務(wù)器的名字,它可以運行在諸如 Linux、BSD、Solaris、 HP-UNIX等系統上面,是一個(gè)完全免費的、開(kāi)放源代碼的ftp服務(wù)器軟件,支持很多其他的 FTP 服務(wù)器所不支持的特征。

449.什么是Nginx?

Nginx?(engine x) 是一個(gè)高性能的HTTP和反向代理服務(wù)。Nginx是由伊戈爾·賽索耶夫為俄羅斯訪(fǎng)問(wèn)量第二的Rambler.ru站點(diǎn)(俄文:Рамблер)開(kāi)發(fā)的,第一個(gè)公開(kāi)版本0.1.0發(fā)布于2004年10月4日。

Nginx 是一個(gè)很強大的高性能Web和反向代理服務(wù),它具有很多非常優(yōu)越的特性:在連接高并發(fā)的情況下,Nginx是Apache服務(wù)不錯的替代品:Nginx在美國是做虛擬主機生意的老板們經(jīng)常選擇的軟件平臺之一。

450.Nginx有哪些作用?

答:http協(xié)議代理

搭建虛擬主機

服務(wù)的反向代理

在反向代理中配置集群的負載均衡

451.什么是正向代理?

正向代理,意思是一個(gè)位于客戶(hù)端和原始服務(wù)器(origin server)之間的服務(wù)器,為了從原始服務(wù)器取得內容,客戶(hù)端向代理發(fā)送一個(gè)請求并指定目標(原始服務(wù)器),然后代理向原始服務(wù)器轉交請求并將獲得的內容返回給客戶(hù)端??蛻?hù)端才能使用正向代理。

452.什么是反向代理?

反向代理(Reverse Proxy)方式是指以代理服務(wù)器來(lái)接受internet上的連接請求,然后將請求轉發(fā)給內部網(wǎng)絡(luò )上的服務(wù)器,并將從服務(wù)器上得到的結果返回給internet上請求連接的客戶(hù)端,此時(shí)代理服務(wù)器對外就表現為一個(gè)反向代理服務(wù)器。

453.什么是Redis?

答:Remote Dictionary Server(Redis)是一個(gè)開(kāi)源的使用ANSI?C語(yǔ)言編寫(xiě)、支持網(wǎng)絡(luò )、可基于內存亦可持久化的日志型、Key-Value數據庫,并提供多種語(yǔ)言的API。

它通常被稱(chēng)為數據結構服務(wù)器,因為值(value)可以是 字符串(String), 哈希(Map), 列表(list), 集合(sets) 和 有序集合(sorted sets)等類(lèi)型。

454.Redis的特點(diǎn)什么是?

1. 支持多種數據結構,如 string(字符串)、 list(雙向鏈表)、dict(hash表)、set(集合)、zset(排序set)、hyperloglog(基數估算)

2. 支持持久化操作,可以進(jìn)行aof及rdb數據持久化到磁盤(pán),從而進(jìn)行數據備份或數據恢復等操作,較好的防止數據丟失的手段。

3. 支持通過(guò)Replication進(jìn)行數據復制,通過(guò)master-slave機制,可以實(shí)時(shí)進(jìn)行數據的同步復制,支持多級復制和增量復制,master-slave機制是Redis進(jìn)行HA的重要手段。

單進(jìn)程請求,所有命令串行執行,并發(fā)情況下不需要考慮數據一致性問(wèn)題。

455.Redis數據類(lèi)型有哪些?

答:String(字符串)

Hash(hash表)

List(鏈表)

Set(集合)

SortedSet(有序集合zset)

456.Redis中的常用命令哪些?

incr 讓當前鍵值以1的數量遞增,并返回遞增后的值

incrby 可以指定參數一次增加的數值,并返回遞增后的值

incrby 可以指定參數一次增加的數值,并返回遞增后的值

decrby 可以指定參數一次遞減的數值,并返回遞減后的值

incrbyfloat 可以遞增一個(gè)雙精度浮點(diǎn)數

append 作用是向鍵值的末尾追加value。如果鍵不存在則將該鍵的值設置為value。返回值是追加后字符串的總長(cháng)度。

mget/mset 作用與get/set相似,不過(guò)mget/mset可以同時(shí)獲得/設置多個(gè)鍵的鍵值

del 根據key來(lái)刪除value

flushdb 清除當前庫的所有數據

hset 存儲一個(gè)哈希鍵值對的集合

hget獲取一個(gè)哈希鍵的值

hmset 存儲一個(gè)或多個(gè)哈希是鍵值對的集合

hmget 獲取多個(gè)指定的鍵的值

hexists 判斷哈希表中的字段名是否存在 如果存在返回1 否則返回0

hdel 刪除一個(gè)或多個(gè)字段

hgetall 獲取一個(gè)哈希是鍵值對的集合

hvals 只返回字段值

hkeys 只返回字段名

hlen 返回key的hash的元素個(gè)數

lpush key value向鏈表左側添加

rpush key value向鏈表右側添加

lpop key 從左邊移出一個(gè)元素

rpop key 從右邊移出一個(gè)元素

llen key 返回鏈表中元素的個(gè)數 相當于關(guān)系型數據庫中 select count(*)

lrange key start end lrange命令將返回索引從start到stop之間的所有元素。Redis的列表起始索引為0。

lrange也支持負索引 lrange nn -2 -1 如 -1表示最右邊第一個(gè)元素 -2表示最右邊第二個(gè)元素,依次類(lèi)推。

lindex key indexnumber 如果要將列表類(lèi)型當做數組來(lái)用,lindex命令是必不可少的。lindex命令用來(lái)返回指定索引的元素,索引從0開(kāi)始

如果是負數表示從右邊開(kāi)始計算的索引,最右邊元素的索引是-1。

Lset key indexnumber value 是另一個(gè)通過(guò)索引操作列表的命令,它會(huì )將索引為index的元素賦值為value。

sadd?key value?添加一個(gè)string元素到,key對應的set集合中,成功返回1,如果元素已經(jīng)在集合中返回0

scard?key?返回set的元素個(gè)數,如果set是空或者key不存在返回0

smembers?key?返回key對應set的所有元素,結果是無(wú)序的

sismember?key value?判斷value 是否在set中,存在返回1,0表示不存在或者key不存在

srem key value 從key對應set中移除給定元素,成功返回1,如果value 在集合中不存在或者key不存在返回0

zadd key score value 將一個(gè)或多個(gè)value及其socre加入到set中

zrange key start end 0和-1表示從索引為0的元素到最后一個(gè)元素(同LRANGE命令相似)

zrange key 0 -1 withscores 也可以連同score一塊輸出,使用WITHSCORES參數

zremrangebyscore key start end 可用于范圍刪除操作

ping 測試redis是否鏈接 如果已鏈接返回 PONG

echo value測試redis是否鏈接 如果已鏈接返回 echo命令后給定的值

keys * 返回所有的key 可以加*通配

exists key判斷string類(lèi)型一個(gè)key是否存在 如果存在返回1 否則返回0

expire key time(s) 設置一個(gè)key的過(guò)期時(shí)間 單位秒。時(shí)間到達后會(huì )刪除key及value

ttl key 查詢(xún)已設置過(guò)期時(shí)間的key的剩余時(shí)間 如果返回-2表示該鍵值對已經(jīng)被刪除

persist 移除給定key的過(guò)期時(shí)間

select dbindex 選擇數據庫(0-15)

move key dbIndex 將當前數據庫中的key轉移到其他數據庫中

dbsize 返回當前數據庫中的key的數目

info 獲取服務(wù)器的信息和統計

flushdb 刪除當前選擇的數據庫中的key

flushall 刪除所有數據庫中的所有key

quit 退出連接

457.Redis的配置以及持久化方案有幾種?

答:以下兩種

RDB方式

AOF方式

458.什么是RDB方式?

答:是RDB是對內存中數據庫狀態(tài)進(jìn)行快照

RDB方式:將Redis在內存中的數據庫狀態(tài)保存到磁盤(pán)里面,RDB文件是一個(gè)經(jīng)過(guò)壓縮的二進(jìn)制文件,通過(guò)該文件可以還原生成RDB文件時(shí)的數據庫狀態(tài)(默認下,持久化到dump.rdb文件,并且在redis重啟后,自動(dòng)讀取其中文件,據悉,通常情況下一千萬(wàn)的字符串類(lèi)型鍵,1GB的快照文件,同步到內存中的 時(shí)間是20-30秒)

RDB的生成方式:

 1、執行命令手動(dòng)生成

有兩個(gè)Redis命令可以用于生成RDB文件,一個(gè)是SAVE,另一個(gè)是BGSAVE SAVE命令會(huì )阻塞Redis服務(wù)器進(jìn)程,直到RDB文件創(chuàng )建完畢為止,在服務(wù)器進(jìn)程阻塞期間,服務(wù)器不能處理任何命令請求,BGSAVE命令會(huì )派生出一個(gè)子進(jìn)程,然后由子進(jìn)程負責創(chuàng )建RDB文件,服務(wù)器進(jìn)程(父進(jìn)程)繼續處理命令請求,創(chuàng )建RDB文件結束之前,客戶(hù)端發(fā)送的BGSAVE和SAVE命令會(huì )被服務(wù)器拒絕

2、通過(guò)配置自動(dòng)生成

可以設置服務(wù)器配置的save選項,讓服務(wù)器每隔一段時(shí)間自動(dòng)執行一次BGSAVE命令,可以通過(guò)save選項設置多個(gè)保存條件,但只要其中任意一個(gè)條件被滿(mǎn)足,服務(wù)器就會(huì )執行BGSAVE命令

例如:

save 900 1

save 300 10

save 60 10000

那么只要滿(mǎn)足以下三個(gè)條件中的任意一個(gè),BGSAVE命令就會(huì )被執行

服務(wù)器在900秒之內,對數據庫進(jìn)行了至少1次修改

服務(wù)器在300秒之內,對數據庫進(jìn)行了至少10次修改

服務(wù)器在60秒之內,對數據庫進(jìn)行了至少10000次修改

459.什么是AOF方式?

AOF持久化方式在redis中默認是關(guān)閉的,需要修改配置文件開(kāi)啟該方式。

AOF:把每條命令都寫(xiě)入文件,類(lèi)似mysql的binlog日志

AOF方式:是通過(guò)保存Redis服務(wù)器所執行的寫(xiě)命令來(lái)記錄數據庫狀態(tài)的文件。

AOF文件刷新的方式,有三種:

appendfsync always - 每提交一個(gè)修改命令都調用fsync刷新到AOF文件,非常非常慢,但也非常安全

appendfsync everysec - 每秒鐘都調用fsync刷新到AOF文件,很快,但可能會(huì )丟失一秒以?xún)鹊臄祿?/p>

appendfsync no - 依靠OS進(jìn)行刷新,redis不主動(dòng)刷新AOF,這樣最快,但安全性就差

默認并推薦每秒刷新,這樣在速度和安全上都做到了兼顧

AOF數據恢復方式

服務(wù)器在啟動(dòng)時(shí),通過(guò)載入和執行AOF文件中保存的命令來(lái)還原服務(wù)器關(guān)閉之前的數據庫狀態(tài),具體過(guò)程:

載入AOF文件

創(chuàng )建模擬客戶(hù)端

從AOF文件中讀取一條命令

使用模擬客戶(hù)端執行命令

循環(huán)讀取并執行命令,直到全部完成

如果同時(shí)啟用了RDB和AOF方式,AOF優(yōu)先,啟動(dòng)時(shí)只加載AOF文件恢復數據

460.什么是全文檢索?

答:什么叫做全文檢索呢?這要從我們生活中的數據說(shuō)起。

我們生活中的數據總體分為兩種:結構化數據和非結構化數據。

1)結構化數據:指具有固定格式或有限長(cháng)度的數據,如數據庫,元數據等。

2)非結構化數據:指不定長(cháng)或無(wú)固定格式的數據,如郵件,word文檔等。

非結構化數據又一種叫法叫全文數據。

?按照數據的分類(lèi),搜索也分為兩種:

1)對結構化數據的搜索:如對數據庫的搜索,用SQL語(yǔ)句。

2)對非結構化數據的搜索:如利用windows的搜索也可以搜索文件內容,

全文檢索: 就是一種將文件中所有文本與檢索項匹配的文字資料檢索方法。全文檢索首先將要查詢(xún)的目標文檔中的詞提取出來(lái),組成索引,通過(guò)查詢(xún)索引達到搜索目標文檔的目的。這種先建立索引,再對索引進(jìn)行搜索的過(guò)程就叫全文檢索(Full-text Search)。

461.什么是Lucene?

Lucene是一個(gè)高效的,基于Java的全文檢索庫。

Lucene是apache軟件基金會(huì )4 jakarta項目組的一個(gè)子項目,是一個(gè)開(kāi)放源代碼的全文檢索引擎工具包,但它不是一個(gè)完整的全文檢索引擎,而是一個(gè)全文檢索引擎的架構,Lucene的目的是為軟件開(kāi)發(fā)人員提供一個(gè)簡(jiǎn)單易用的工具包,以方便的在目標系統中實(shí)現全文檢索的功能,或者是以此為基礎建立起完整的全文檢索引擎。Lucene是一套用于全文檢索和搜尋的開(kāi)源程序庫,由Apache軟件基金會(huì )支持和提供。Lucene提供了一個(gè)簡(jiǎn)單卻強大的應用程序接口,能夠做全文索引和搜尋。在Java開(kāi)發(fā)環(huán)境里L(fēng)ucene是一個(gè)成熟的免費開(kāi)源工具。就其本身而言,Lucene是當前以及最近幾年最受歡迎的免費Java信息檢索程序庫。

462.什么是Solr?

答:Solr是一個(gè)獨立的企業(yè)級搜索應用服務(wù)器,它對外提供類(lèi)似于Web-service的API接口。

Solr是一個(gè)高性能,采用Java開(kāi)發(fā),基于Lucene的全文搜索服務(wù)器。同時(shí)對其進(jìn)行了擴展,提供了比Lucene更為豐富的查詢(xún)語(yǔ)言,同時(shí)實(shí)現了可配置、可擴展并對查詢(xún)性能進(jìn)行了優(yōu)化,并且提供了一個(gè)完善的功能管理界面,是一款非常優(yōu)秀的全文檢索引擎。

文檔通過(guò)Http利用XML 加到一個(gè)搜索集合中。查詢(xún)該集合也是通過(guò)http收到一個(gè)XML/JSON響應來(lái)實(shí)現。它的主要特性包括:高效、靈活的緩存功能,垂直搜索功能,高亮顯示搜索結果,通過(guò)索引復制來(lái)提高可用性,提供一套強大Data Schema來(lái)定義字段,類(lèi)型和設置文本分析,提供基于Web的管理界面等。

463.Solr是由哪兩個(gè)部分構成?

答:如下兩個(gè)部分

Solr的web服務(wù)

Solr的索引庫

464.什么是正排索引?

正排索引是以文檔的ID為關(guān)鍵字,索引文檔中每個(gè)字的位置信息,查找時(shí)掃描索引中每個(gè)文檔中字的信息直到找出所有包含查詢(xún)關(guān)鍵字的文檔。

但是在查詢(xún)的時(shí)候需對所有的文檔進(jìn)行掃描以確保沒(méi)有遺漏,這樣就使得檢索時(shí)間大大延長(cháng),檢索效率低下。 ? ??

盡管正排索引的工作原理非常的簡(jiǎn)單,但是由于其檢索效率太低,除非在特定情況下,否則實(shí)用性?xún)r(jià)值不大。

465.什么是倒排索引?

對數據進(jìn)行分析,抽取出數據中的詞條,以詞條作為key,對應數據的存儲位置作為value,實(shí)現索引的存儲。這種索引稱(chēng)為倒排索引。

當solr存儲文檔時(shí),solr會(huì )首先對文檔數據進(jìn)行分詞,創(chuàng )建索引庫和文檔數據庫。所謂的分詞是指:將一段字符文本按照一定的規則分成若干個(gè)單詞。

466.什么是ActiveMQ?

ActiveMQ是一種開(kāi)源的,實(shí)現了JMS1.1規范的,面向消息(MOM)的中間件,為應用程序提供高效的、可擴展的、穩定的和安全的企業(yè)級消息通信。ActiveMQ使用Apache提供的授權,任何人都可以對其實(shí)現代碼進(jìn)行修改。

ActiveMQ的設計目標是提供標準的,面向消息的,能夠跨越多語(yǔ)言和多系統的應用集成消息通信中間件。

ActiveMQ實(shí)現了JMS標準并提供了很多附加的特性。這些附加的特性包括,JMX管理(java Management Extensions,即java管理擴展),主從管理(master/salve,這是集群模式的一種,主要體現在可靠性方面,當主中介(代理)出現故障,那么從代理會(huì )替代主代理的位置,不至于使消息系統癱瘓)、消息組通信(同一組的消息,僅會(huì )提交給一個(gè)客戶(hù)進(jìn)行處理)、有序消息管理(確保消息能夠按照發(fā)送的次序被接受者接收)。消息優(yōu)先級(優(yōu)先級高的消息先被投遞和處理)、訂閱消息的延遲接收(訂閱消息在發(fā)布時(shí),如果訂閱者沒(méi)有開(kāi)啟連接,那么當訂閱者開(kāi)啟連接時(shí),消息中介將會(huì )向其提交之前的,其未處理的消息)、接收者處理過(guò)慢(可以使用動(dòng)態(tài)負載平衡,將多數消息提交到處理快的接收者,這主要是對PTP消息所說(shuō))、虛擬接收者(降低與中介的連接數目)、成熟的消息持久化技術(shù)(部分消息需要持久化到數據庫或文件系統中,當中介崩潰時(shí),信息不會(huì )丟失)、支持游標操作(可以處理大消息)、支持消息的轉換、通過(guò)使用Apache的Camel可以支持EIP、使用鏡像隊列的形式輕松的對消息隊列進(jìn)行監控等。

467.消息服務(wù)的應用場(chǎng)景有哪些?

答:如下3個(gè)場(chǎng)景都可以使用消息服務(wù)

1、異步處理

2、應用的解耦

3、流量的削峰

468.什么是JMS?

JMS(Java Messaging Service)是Java平臺上有關(guān)面向消息中間件的技術(shù)規范,它便于消息系統中的Java應用程序進(jìn)行消息交換,并且通過(guò)提供標準的產(chǎn)生、發(fā)送、接收消息的接口,簡(jiǎn)化企業(yè)應用的開(kāi)發(fā)。

469.JMS有哪些模型?

答:JMS消息機制主要分為兩種模型:PTP模型和Pub/Sub模型。

1、PTP模型:(Point? to Point 對點(diǎn)模型) 每一個(gè)消息傳遞給一個(gè)消息消費者,保證消息傳遞給消息消費者,且消息不會(huì )同時(shí)被多個(gè)消費者接收。如果消息消費者暫時(shí)不在連接范圍內,JMS會(huì )自動(dòng)保證消息不會(huì )丟失,直到消息消費者進(jìn)入連接,消息將自動(dòng)送達。因此,JMS需要將消息保存到永久性介質(zhì)上,例如數據庫或者文件。

2、Pub-Sub模型:(publish-subscription 發(fā)布者訂閱者模型)每個(gè)主題可以擁有多個(gè)訂閱者。JMS系統負責將消息的副本傳給該主題的每個(gè)訂閱者。

如果希望每一條消息都能夠被處理,那么應該使用PTP消息模型。如果并不要求消息都必須被消息消費者接收到的情況下,可使用pub-sub消息模型。Pub-Sub模型可以在一對多的消息廣播時(shí)使用。

470.什么是JsonP?

Jsonp(JSON with Padding) 是 json 的一種"使用模式",可以讓網(wǎng)頁(yè)從別的域名(網(wǎng)站)那獲取資料,即跨域讀取數據。

471.什么是跨域?

跨域是指一個(gè)域(網(wǎng)站)下的文檔或腳本試圖去請求另一個(gè)域(網(wǎng)站)下的資源。

472.什么是同源策略?

同源策略/SOP(Same origin policy)是一種約定,由Netscape公司1995年引入瀏覽器,它是瀏覽器最核心也最基本的安全功能,現在所有支持JavaScript 的瀏覽器都會(huì )使用這個(gè)策略。如果缺少了同源策略,瀏覽器很容易受到XSS、CSFR等攻擊。所謂同源是指"協(xié)議+域名+端口"三者相同,即便兩個(gè)不同的域名指向同一個(gè)ip地址,也非同源

473.什么是MyCat?

MyCat是目前最流行的基于java語(yǔ)言編寫(xiě)的數據庫中間件,是一個(gè)實(shí)現了MySQL協(xié)議的服務(wù)器,前端用戶(hù)可以把它看作是一個(gè)數據庫代理,用MySQL客戶(hù)端工具和命令行訪(fǎng)問(wèn),而其后端可以用MySQL原生協(xié)議與多個(gè)MySQL服務(wù)器通信,也可以用JDBC協(xié)議與大多數主流數據庫服務(wù)器通信,其核心功能是分庫分表。配合數據庫的主從模式還可實(shí)現讀寫(xiě)分離。

MyCat是基于阿里開(kāi)源的Cobar產(chǎn)品而研發(fā),Cobar的穩定性、可靠性、優(yōu)秀的架構和性能以及眾多成熟的使用案例使得MyCat變得非常的強大。

MyCat發(fā)展到目前的版本,已經(jīng)不是一個(gè)單純的MySQL代理了,它的后端可以支持MySQL、SQL Server、Oracle、DB2、PostgreSQL等主流數據庫,也支持MongoDB這種新型NoSQL方式的存儲,未來(lái)還會(huì )支持更多類(lèi)型的存儲。而在最終用戶(hù)看來(lái),無(wú)論是那種存儲方式,在MyCat里,都是一個(gè)傳統的數據庫表,支持標準的SQL語(yǔ)句進(jìn)行數據的操作,這樣一來(lái),對前端業(yè)務(wù)系統來(lái)說(shuō),可以大幅降低開(kāi)發(fā)難度,提升開(kāi)發(fā)速度。

474.什么是縱向切分/垂直切分?

就是把原本存儲于一個(gè)庫的數據存儲到多個(gè)庫上。

由于對數據庫的讀寫(xiě)都是對同一個(gè)庫進(jìn)行操作,所以單庫并不能解決大規模并發(fā)寫(xiě)入的問(wèn)題。

例如,我們會(huì )建立定義數據庫workDB、商品數據庫payDB、用戶(hù)數據庫userDB、日志數據庫logDB等,分別用于存儲項目數據定義表、商品定義表、用戶(hù)數據表、日志數據表等。

優(yōu)點(diǎn)

1)減少增量數據寫(xiě)入時(shí)的鎖對查詢(xún)的影響。

2)由于單表數量下降,常見(jiàn)的查詢(xún)操作由于減少了需要掃描的記錄,使得單表單次查詢(xún)所需的檢索行數變少,減少了磁盤(pán)IO,時(shí)延變短。

缺點(diǎn):

無(wú)法解決單表數據量太大的問(wèn)題。

橫向切分/水平切分

把原本存儲于一個(gè)表的數據分塊存儲到多個(gè)表上。當一個(gè)表中的數據量過(guò)大時(shí),我們可以把該表的數據按照某種規則,進(jìn)行劃分,然后存儲到多個(gè)結構相同的表,和不同的庫上。

例如,我們userDB中的userTable中數據量很大,那么可以把userDB切分為結構相同的多個(gè)userDB:part0DB、part1DB等,再將userDB上的userTable,切分為很多userTable:userTable0、userTable1等,然后將這些表按照一定的規則存儲到多個(gè)userDB上。

優(yōu)點(diǎn):

1)單表的并發(fā)能力提高了,磁盤(pán)I/O性能也提高了。

2)如果出現高并發(fā)的話(huà),總表可以根據不同的查詢(xún),將并發(fā)壓力分到不同的小表里面。

缺點(diǎn):無(wú)法實(shí)現表連接查詢(xún)。

475.簡(jiǎn)述Tomcat,Apache,JBoss和WebLogic的區別和聯(lián)系

答:Apache:全球應用最廣泛的http服務(wù)器,免費,出自apache基金組織?

Tomcat:應用也算非常廣泛的web 服務(wù)器,支持部分j2ee,免費,出自 apache基金組織?

JBoss:開(kāi)源的應用服務(wù)器,比較受人喜愛(ài),免費(文檔要收費)?

weblogic:應該說(shuō)算是業(yè)界第一的app server,全部支持j2ee1.4(收費)

JBoss也支持j2ee

JBoss和WebLogic都含有Jsp和Servlet容器,也就可以做web容器,?

JBoss和WebLogic也包含EJB容器,是完整的J2EE應用服務(wù)器

tomcat 只能做jsp和servlet的container

476.以下可以實(shí)現負載均衡的是()
A. nagios
B. Jenkins
C. nginx
D. docker
分析:答案: C Nginx是一款輕量級的Web?服務(wù)器/反向代理服務(wù)器及電子郵件(IMAP/POP3)代理服務(wù)器,并在一個(gè)BSD-like 協(xié)議下發(fā)行。其特點(diǎn)是占有內存少,并發(fā)能力強,事實(shí)上nginx的并發(fā)能力確實(shí)在同類(lèi)型的網(wǎng)頁(yè)服務(wù)器中表現較好,中國大陸使用nginx網(wǎng)站用戶(hù)有:百度、京東、新浪、網(wǎng)易、騰訊、淘寶等
477.Tomcat/ WebSphere/WebLogic的作用和特點(diǎn)

作用:

Tomcat:目前應用非常廣泛的免費web服務(wù)器,支持部分j2ee。

WebSphere:是IBM集成軟件平臺??勺鰓eb服務(wù)器,WebSphere提供了可靠、靈活和健壯的集成軟件。

Weblogic:是美國bea公司出品的一個(gè)基于j2ee架構的中間件。BEA WebLogic是用于開(kāi)發(fā)、集成、部署和管理大型分布式Web應用、網(wǎng)絡(luò )應用和數據庫應用的Java應用服務(wù)器。

特點(diǎn)(區別):

1)價(jià)位不同:Tomcat的是免費的;WebLogic與WebSphere是收費的,而且價(jià)格不菲。

2) 開(kāi)源性不同:Tomcat的是完全開(kāi)源的,而其他兩個(gè)不是。WebLogic與WebSphere都是對業(yè)內多種標準的全面支持,包括JSB、JMS、JDBC、XML和WML,使Web應用系統實(shí)施更簡(jiǎn)單,且保護投資,同時(shí)也使基于標準的解決方案的開(kāi)發(fā)更加簡(jiǎn)便。

3) 擴展性的不同:WebLogic和WebSphere都是以其高擴展的架構體系聞名于業(yè)內,包括客戶(hù)機連接的共享、資源 pooling以及動(dòng)態(tài)網(wǎng)頁(yè)。

4)應用范圍的區別:Tomcat 是一個(gè)小型的輕量級應用服務(wù)器,在中小型系統和并發(fā)訪(fǎng)問(wèn)用戶(hù)不是很多的場(chǎng)合下被普遍使用,是開(kāi)發(fā)和調試JSP 程序的首選。WebLogic和WebSphere是商業(yè)軟件,功能齊全強大,主要應用于大型企業(yè)的大型項目。

5)安全性問(wèn)題區別:因為T(mén)omcat是開(kāi)源的,所以它們的安全性相對來(lái)說(shuō)比較低,萬(wàn)一應用服務(wù)器本身有什么漏洞,你是沒(méi)辦法向Apache索賠的。而WebLogic和WebSphere其容錯、系統管理和安全性能已經(jīng)在全球數以千記的關(guān)鍵任務(wù)環(huán)境中得以驗證。

478.B/S和C/S的含義及其區別

C/S結構,即Client/Server(客戶(hù)機/服務(wù)器)結構,通過(guò)將任務(wù)合理分配到Client端和Server端,降低了系統的通訊開(kāi)銷(xiāo),可充分利用兩端硬件環(huán)境優(yōu)勢。早期軟件系統多以此作為首選設計標準。

B/S結構,即Browser/Server(瀏覽器/服務(wù)器)結構,是隨著(zhù)Internet技術(shù)的興起,對C/S結構的一種變化或者改進(jìn)的結構。在這種結構下,用戶(hù)界面完全通過(guò)WWW瀏覽器實(shí)現,一部分事務(wù)邏輯在前端實(shí)現,但是主要事務(wù)邏輯在服務(wù)器端實(shí)現,節約了開(kāi)發(fā)成本,便于軟件維護。

區別

1、C/S是建立在局域網(wǎng)的基礎上的。B/S是建立在廣域網(wǎng)的基礎上的,但并不是說(shuō)B/S結構不能在局域網(wǎng)上使用。

2、B/S業(yè)務(wù)擴展簡(jiǎn)單方便,通過(guò)增加頁(yè)面即可增加服務(wù)器功能。C/S的客戶(hù)端還需要安裝專(zhuān)用的客戶(hù)端軟件,不利于擴展。

3、B/S維護簡(jiǎn)單方便。開(kāi)發(fā)、維護等幾乎所有工作也都集中在服務(wù)器端,當企業(yè)對網(wǎng)絡(luò )應用進(jìn)行升級時(shí),只需更新服務(wù)器端的軟件就可以,這減輕了異地用戶(hù)系統維護與升級的成本

4、B/S響應速度不及C/S;

5、B/S用戶(hù)體驗效果不是很理想

479.說(shuō)說(shuō)你對容器的理解

容器也是 java 程序,它的主要作用是為應用程序提供運行環(huán)境。容器用來(lái)接管安全性、并發(fā)性、事務(wù)處理、交換到輔助存儲器和其它服務(wù)的責任

以tomcat為例:Tomcat是一個(gè)后臺服務(wù)進(jìn)程,其它的servlet(相當于DLL)是在Tomcat容器內運行,Broswer只與Tomcat通迅; Tomcat接受browser的請求,經(jīng)過(guò)一系列動(dòng)作(如果是靜態(tài)網(wǎng)頁(yè),那么裝載,按http協(xié)議形成響應流;如果是動(dòng)態(tài)的如JSP,那就要調用JDK 中的servlet.jsp接口,解釋形成靜態(tài)網(wǎng)頁(yè),按http協(xié)議生成響應流發(fā)送回browser)后,形成靜態(tài)網(wǎng)頁(yè),返回響應。

480.為什么要使用連接池?

?傳統的數據庫連接方式

一個(gè)連接對象對應一個(gè)物理連接

每次操作都打開(kāi)一個(gè)物理連接,

使用完都關(guān)閉連接,造成系統性能低下。

?連接池技術(shù)

客戶(hù)程序得到的連接對象是連接池中物理連接的一個(gè)句柄,調用連接對象的close()方法,物理連接并沒(méi)有關(guān)閉,數據源的實(shí)現只是刪除了客戶(hù)程序中的連接對象和池中的連接對象之間的聯(lián)系.

?數據庫連接的建立及關(guān)閉是耗費系統資源的操作,在大型應用中對系統的性能影響尤為明顯。為了能重復利用數據庫連接對象,縮短請求的響應時(shí)間和提高服務(wù)器的性能,支持更多的客戶(hù),應采用連接池技術(shù).

481.數據庫連接池的原理

數據庫連接池的原理

傳統連接方式:

首先調用Class.forName()方法加載數據庫驅動(dòng),

然后調用DriverManager.getConnection()方法建立連接.

連接池技術(shù):

連接池解決方案是在應用程序啟動(dòng)時(shí)就預先建立多個(gè)數據庫連接對象,然后將連接對象保存到連接池中。

當客戶(hù)請求到來(lái)時(shí),從池中取出一個(gè)連接對象為客戶(hù)服務(wù)。

當請求完成時(shí),客戶(hù)程序調用close()方法,將連接對象放回池中.

對于多于連接池中連接數的請求,排隊等待。

應用程序還可根據連接池中連接的使用率,動(dòng)態(tài)增加或減少池中的連接數。

482.MVC模式及其優(yōu)缺點(diǎn)

一、MVC原理

MVC是一種程序開(kāi)發(fā)設計模式,它實(shí)現了顯示模塊與功能模塊的分離。提高了程序的可維護性、可移植性、可擴展性與可重用性,降低了程序的開(kāi)發(fā)難度。它主要分模型、視圖、控制器三層。

1、模型(model)它是應用程序的主體部分,主要包括業(yè)務(wù)邏輯模塊和數據模塊。模型與數據格式無(wú)關(guān),這樣一個(gè)模型能為多個(gè)視圖提供數據。由于應用于模型的代碼只需寫(xiě)一次就可以被多個(gè)視圖重用,所以減少了代碼的重復性

2、視圖(view) 用戶(hù)與之交互的界面、在web中視圖一般由jsp,html組成

3、控制器(controller)接收來(lái)自界面的請求 并交給模型進(jìn)行處理 在這個(gè)過(guò)程中控制器不做任何處理只是起到了一個(gè)連接的作用

二、MVC的優(yōu)點(diǎn)

1、降低代碼耦合性。在MVC模式中,三個(gè)層各施其職,所以如果一旦哪一層的需求發(fā)生了變化,就只需要更改相應的層中的代碼而不會(huì )影響到其他層中的代碼。

2、有利于分工合作。在MVC模式中,由于按層把系統分開(kāi),那么就能更好的實(shí)現開(kāi)發(fā)中的分工。網(wǎng)頁(yè)設計人員可進(jìn)行開(kāi)發(fā)視圖層中的JSP,而對業(yè)務(wù)熟悉的人員可開(kāi)發(fā)業(yè)務(wù)層,而其他開(kāi)發(fā)人員可開(kāi)發(fā)控制層。

3、有利于組件的重用。如控制層可獨立成一個(gè)能用的組件,表示層也可做成通用的操作界面??梢詾橐粋€(gè)模型在運行時(shí)同時(shí)建立和使用多個(gè)視圖。

三、MVC的不足之處

1、增加了系統結構和實(shí)現的復雜性。對于簡(jiǎn)單的界面,嚴格遵循MVC,使模型、視圖與控制器分離,會(huì )增加結構的復雜性,并可能產(chǎn)生過(guò)多的更新操作,降低運行效率。

2、視圖與控制器間的過(guò)于緊密的連接。視圖與控制器是相互分離,但確實(shí)聯(lián)系緊密的部件,視圖沒(méi)有控制器的存在,其應用是很有限的,反之亦然,這樣就妨礙了他們的獨立重用。

3、視圖對模型數據的低效率訪(fǎng)問(wèn)。依據模型操作接口的不同,視圖可能需要多次調用才能獲得足夠的顯示數據。對未變化數據的不必要的頻繁訪(fǎng)問(wèn),也將損害操作性能。

4、目前,一般高級的界面工具或構造器不支持模式。改造這些工具以適應MVC需要和建立分離的部件的代價(jià)是很高的,從而造成MVC使用的困難。

483.MVC模式完成分頁(yè)功能的基本思路是什么?

1)頁(yè)面提交頁(yè)碼(第幾頁(yè))到Servlet中

2)Servlet接收到頁(yè)碼后,將頁(yè)碼傳遞給分頁(yè)工具類(lèi)(PageBean)

3)Servlet中調用Service層傳入PageBean對象

4)Service層調用DAO層傳入PageBean對象

5)Servlet中得到查詢(xún)出來(lái)的數據,并setAttrivute保存

6)在頁(yè)面中得到(getAttribute)數據,遍歷輸出

484.常用的Web容器

答: Unix和Linux平臺下使用最廣泛的免費HTTP服務(wù)器是Apache服務(wù)器,而Windows平臺的服務(wù)器通常使用IIS作為Web服務(wù)器。選擇Web服務(wù)器應考慮的因素有:性能、安全性、日志和統計、虛擬主機、代理服務(wù)器、緩沖服務(wù)和集成應用程序等。下面是對常用服務(wù)器的簡(jiǎn)介:

IIS:Microsoft的Web服務(wù)器產(chǎn)品為Internet Information Services。IIS 是允許在公共Intranet或Internet上發(fā)布信息的Web服務(wù)器。IIS是目前最流行的Web服務(wù)器產(chǎn)品之一,很多著(zhù)名的網(wǎng)站都是建立在IIS的平臺上。IIS提供了一個(gè)圖形界面的管理工具,稱(chēng)為Internet服務(wù)管理器,可用于監視配置和控制Internet服務(wù)。IIS是一種Web服務(wù)組件,其中包括Web服務(wù)器、FTP服務(wù)器、NNTP服務(wù)器和SMTP服務(wù)器,分別用于網(wǎng)頁(yè)瀏覽、文件傳輸、新聞服務(wù)和郵件發(fā)送等方面,它使得在網(wǎng)絡(luò )(包括互聯(lián)網(wǎng)和局域網(wǎng))上發(fā)布信息成了一件很容易的事。它提供ISAPI(Intranet Server API)作為擴展Web服務(wù)器功能的編程接口;同時(shí),它還提供一個(gè)Internet數據庫連接器,可以實(shí)現對數據庫的查詢(xún)和更新。

Kangle:Kangle Web服務(wù)器是一款跨平臺、功能強大、安全穩定、易操作的高性能Web服務(wù)器和反向代理服務(wù)器軟件。此外,Kangle也是一款專(zhuān)為做虛擬主機研發(fā)的Web服務(wù)器。實(shí)現虛擬主機獨立進(jìn)程、獨立身份運行。用戶(hù)之間安全隔離,一個(gè)用戶(hù)出問(wèn)題不影響其他用戶(hù)。支持PHP、ASP、ASP.NET、Java、Ruby等多種動(dòng)態(tài)開(kāi)發(fā)語(yǔ)言。

WebSphere:WebSphere Application Server是功能完善、開(kāi)放的Web應用程序服務(wù)器,是IBM電子商務(wù)計劃的核心部分,它是基于Java的應用環(huán)境,用于建立、部署和管理Internet和Intranet Web應用程序,適應各種Web應用程序服務(wù)器的需要,范圍從簡(jiǎn)單到高級直到企業(yè)級。

WebLogic:BEA WebLogic Server是一種多功能、基于標準的Web應用服務(wù)器,為企業(yè)構建自己的應用提供了堅實(shí)的基礎。各種應用開(kāi)發(fā)、部署所有關(guān)鍵性的任務(wù),無(wú)論是集成各種系統和數據庫,還是提交服務(wù)、跨Internet協(xié)作,Weblogic都提供了相應的支持。由于它具有全面的功能、對開(kāi)放標準的遵從性、多層架構、支持基于組件的開(kāi)發(fā),基于Internet的企業(yè)都選擇它來(lái)開(kāi)發(fā)、部署最佳的應用。BEA WebLogic Server在使應用服務(wù)器成為企業(yè)應用架構的基礎方面一直處于領(lǐng)先地位,為構建集成化的企業(yè)級應用提供了穩固的基礎,它們以 Internet的容量和速度,在連網(wǎng)的企業(yè)之間共享信息、提交服務(wù),實(shí)現協(xié)作自動(dòng)化。

Apache:目前Apache仍然是世界上用得最多的Web服務(wù)器,市場(chǎng)占有率約為60%左右。世界上很多著(zhù)名的網(wǎng)站都是Apache的產(chǎn)物,它的成功之處主要在于它的源代碼開(kāi)放、有一支強大的開(kāi)發(fā)團隊、支持跨平臺的應用(可以運行在幾乎所有的Unix、Windows、Linux系統平臺上)以及它的可移植性等方面。

Tomcat:Tomcat是一個(gè)開(kāi)放源代碼、運行Servlet和JSP的容器。TomcatServer實(shí)現了Servlet和JSP規范。此外,Tomcat還實(shí)現了Apache-Jakarta規范而且比絕大多數商業(yè)應用軟件服務(wù)器要好,因此目前也有不少的Web服務(wù)器都選擇了Tomcat。

Nginx:讀作"engine x",是一個(gè)高性能的HTTP和反向代理服務(wù)器,也是一個(gè)IMAP/POP3/SMTP代理服務(wù)器。 Nginx是由Igor Sysoev為俄羅斯訪(fǎng)問(wèn)量第二的 Rambler.ru站點(diǎn)開(kāi)發(fā)的,第一個(gè)公開(kāi)版本0.1.0發(fā)布于2004年10月4日。其將源代碼以類(lèi)BSD許可證的形式發(fā)布,因它的穩定性、豐富的功能集、示例配置文件和低系統資源的消耗而聞名。

485.Java Web開(kāi)發(fā)的Model 1和Model 2分別指的是什么?

答:Model 1是以頁(yè)面為中心的Java Web開(kāi)發(fā),只適合非常小型的應用程序,Model 2是基于MVC架構模式的應用,這一點(diǎn)在前文的面試題中已經(jīng)詳細講解過(guò)了。

486.說(shuō)說(shuō)什么是框架:

框架(framework)是一個(gè)框子--》指約束性,也是一個(gè)架子--》指支撐性IT語(yǔ)境中的框架,特指為解決一個(gè)開(kāi)放性問(wèn)題而設計的具有一定約束性的支撐結構,在此結構上可以根據具體問(wèn)題擴展、按插更多的組成部分,從而更迅速和方便地架構完整的解決問(wèn)題的方案。

1)框架本身一般不完整到可以解決特定問(wèn)題,但是可以幫助您快速解決特定問(wèn)題:

沒(méi)有框架所有的工作都從零開(kāi)始做,有了框架,為我們提供了一定的功能。我們就可以在框架的基礎上開(kāi)發(fā),極大的解決了生產(chǎn)力。

不同的框架,是為了解決不同領(lǐng)域的問(wèn)題,一定要為了解決問(wèn)題才去學(xué)習框架。

2)框架天生就是為了擴展而設計的

3)框架里面可以為后續的組件提供很多輔助性、支撐性的方便易用的實(shí)用工具(utilities),也就是框架時(shí)常配套一些幫組解決某類(lèi)問(wèn)題的庫(libraries)或工具(tools).

在java中就是一系列的jar包,其本質(zhì)就是對jdk功能的擴展。

487.簡(jiǎn)單說(shuō)一下MVC框架?

是為了解決傳統MVC模式(jsp+servlet+javabean)一些問(wèn)題而出現的框架

傳統MVC模式模式問(wèn)題:

1) 所有的Servlet和Servlet映射都要配置在web.xml中,如果項目太大,web.xml就太龐大并且不能實(shí)現模塊化管理。

2)Servlet的主要功能就是接受參數、調用邏輯、跳轉頁(yè)面,比如像其他字符編碼、文件上傳等功能也要寫(xiě)在Servlet中,不能讓Servlet主要功能而需要做處理一些特例。

3)接受參數比較麻煩

(String name = request.getParameter(“name”)),不能通過(guò)model接受,只能單個(gè)接收,接收完成后轉換封裝model。

4)跳轉頁(yè)面方式比較單一(forward,redirect),并且當我們的頁(yè)面名稱(chēng)發(fā)生改變時(shí)需要改變Servlet源代碼。

現在比較常用的MVC框架:

webwork

Struts

Struts2

SpringMVC

488.簡(jiǎn)單講一下struts2的執行流程

?一個(gè)請求在struts2框架中處理大概分為一下幾個(gè)步驟:

1)客戶(hù)瀏覽器發(fā)送一個(gè)指向Servlet容器(例如Tomcat)的請求

2)這個(gè)請求經(jīng)過(guò)一系列的過(guò)濾器(Filter)(這些過(guò)濾器中有一個(gè)叫做ActionContextCleanUp的可選過(guò)濾器,這個(gè)過(guò)濾器對于Struts2和其他框架的集成很有幫助,例如:SiteMesh Plugin)

3)接著(zhù)FilterDispatcher(StrutsPrepareAndExecuteFilter)被調用,FilterDispatcher詢(xún)問(wèn)ActionMapper來(lái)決定這個(gè)請是否需要調用某個(gè)Action

4)如果ActionMapper決定需要調用某個(gè)Action,FilterDispatcher把請求的處理交給ActionProxy

5)ActionProxy通過(guò)Configuration Manager詢(xún)問(wèn)框架的配置文件,找到需要調用的Action類(lèi)

6)ActionProxy創(chuàng )建一個(gè)ActionInvocation的實(shí)例。

7)ActionInvocation實(shí)例使用命名模式來(lái)調用,在調用Action的過(guò)程前后,涉及到相關(guān)攔截器(Intercepter)的調用。

8)一旦Action執行完畢,ActionInvocation負責根據struts.xml中的配置找到對應的返回結果。返回結果通常是(但不總是,也 可 能是另外的一個(gè)Action鏈)一個(gè)需要被表示的JSP或者FreeMarker的模版。在表示的過(guò)程中可以使用Struts2 框架中繼承的標簽。在這個(gè)過(guò)程中需要涉及到ActionMapper

489.Struts2中的攔截器,你都用它干什么?

java里的攔截器是動(dòng)態(tài)攔截Action調用的對象,它提供了一種機制可以使開(kāi)發(fā)者定義一個(gè)action執行的前后執行的代碼,也可以在一個(gè)action執行前阻止其執行,同時(shí)也提供了一種可以提取action中可重用部分的方式。

在A(yíng)OP(Aspect Oriented Programming)中攔截器用于在某個(gè)方法或字段被訪(fǎng)問(wèn)之前,進(jìn)行攔截后在之前或之后加入某些操作

1)struts2中的功能(參數處理、文件上傳、字符編碼等)都是通過(guò)系統攔截器實(shí)現的

2)當然我們也可以自定義攔截器,進(jìn)行可插拔配置,可以執行Action的方法前后,加入相關(guān)邏輯完成業(yè)務(wù)。

使用場(chǎng)景:

1)用戶(hù)登錄判斷,在執行action的前面判斷是否已經(jīng)登錄,如果沒(méi)有登錄的就跳轉登錄頁(yè)面。

2)用戶(hù)權限判斷,在執行action的前面判斷是否具有,如果沒(méi)有權限就給出提示信息。

3)操作日志...

490.簡(jiǎn)單講一下SpringMVC的執行流程?

1)用戶(hù)向服務(wù)器發(fā)送請求,請求被Spring 前端控制Servelt DispatcherServlet捕獲;

2)DispatcherServlet 對請求URL進(jìn)行解析,得到請求資源標識符(URI)。然后根據該URI,調用HandlerMapping獲得該Handler配置的所有相關(guān)的對象 (包括Handler對象以及Handler對象對應的攔截器),最后以HandlerExecutionChain對象的形式返回;

3)DispatcherServlet 根據獲得的Handler,選擇一個(gè)合適的HandlerAdapter。(附注:如果成功獲得HandlerAdapter后,此時(shí)將開(kāi)始執行攔截器的preHandler(...)方法)

4) 提取Request中的模型數據,填充Handler入參,開(kāi)始執行Handler(Controller)。 在填充Handler的入參過(guò)程中,根據你的配置,Spring將幫你做一些額外的工作:

HttpMessageConveter: 將請求消息(如Json、xml等數據)轉換成一個(gè)對象,將對象轉換為指定的響應信息

數據轉換:對請求消息進(jìn)行數據轉換。如String轉換成Integer、Double等

數據根式化:對請求消息進(jìn)行數據格式化。 如將字符串轉換成格式化數字或格式化日期等

數據驗證: 驗證數據的有效性(長(cháng)度、格式等),驗證結果存儲到BindingResult或Error中

5)Handler執行完成后,向DispatcherServlet?返回一個(gè)ModelAndView對象;

6)根據返回的ModelAndView,選擇一個(gè)適合的ViewResolver(必須是已經(jīng)注冊到Spring容器中的ViewResolver)返回給DispatcherServlet?;

7)ViewResolver 結合Model和View,來(lái)渲染視圖

8)將渲染結果返回給客戶(hù)端。

快速記憶:

核心控制器捕獲請求,查找Hander,執行Handler,選擇ViewResolver,通過(guò)ViewResoler渲染視圖并返回

491.簡(jiǎn)單說(shuō)一下struts2和springMVC有什么不同

目前企業(yè)中使用SpringMvc的比例已經(jīng)遠遠超過(guò)Struts2,那么兩者到底有什么區別,是很多初學(xué)者比較關(guān)注的問(wèn)題,下面我們就來(lái)對SpringMvc和Struts2進(jìn)行各方面的比較:

1)核心控制器(前端控制器、預處理控制器):對于使用過(guò)mvc框架的人來(lái)說(shuō)這個(gè)詞應該不會(huì )陌生,核心控制器的主要用途是處理所有的請求,然后對那些特殊的請求 (控制器)統一的進(jìn)行處理(字符編碼、文件上傳、參數接受、異常處理等等),spring mvc核心控制器是Servlet,而Struts2是Filter。

2)控制器實(shí)例:Spring Mvc會(huì )比Struts快一些(理論上)。Spring Mvc是基于方法設計,而Sturts是基于對象,每次發(fā)一次請求都會(huì )實(shí)例一個(gè)action,每個(gè)action都會(huì )被注入??屬性,而Spring更像Servlet一樣,只有一個(gè)實(shí)例,每次請求執行對應的方法即可(注意:由于是單例實(shí)例,所以應當避免全局變量的修改,這樣會(huì )產(chǎn)生線(xiàn)程安全問(wèn)題 )

3)管理方式:大部分的公司的核心架構中,就會(huì )使用到spring,而spring mvc又是spring中的一個(gè)模塊,所以spring對于spring mvc的控制器管理更加簡(jiǎn)單方便,而且提供了全 注解方式進(jìn)行管理,各種功能的注解都比較全面,使用簡(jiǎn)單,而struts2需要采用XML很多的配置參數來(lái)管理(雖然也可以采用注解,但是幾乎沒(méi)有公司那 樣使用)

4)參數傳遞:Struts2中自身提供多種參數接受,其實(shí)都是通過(guò)(ValueStack)進(jìn)行傳遞和賦值,而SpringMvc是通過(guò)方法的參數進(jìn)行接收。

5)學(xué)習難度:Struts更加很多新的技術(shù)點(diǎn),比如攔截器、值棧及OGNL表達式,學(xué)習成本較高,springmvc 比較簡(jiǎn)單,很較少的時(shí)間都能上手。

6)intercepter 的實(shí)現機制:struts有以自己的interceptor機制,spring mvc用的是獨立的AOP方式。這樣導致struts的配置文件量還是比spring mvc大,雖然struts的配置能繼承,所以我覺(jué)得論使用上來(lái)講,spring mvc使用更加簡(jiǎn)潔,開(kāi)發(fā)效率Spring MVC確實(shí)比struts2高。spring mvc是方法級別的攔截,一個(gè)方法對應一個(gè)request上下文,而方法同時(shí)又跟一個(gè)url對應,所以說(shuō)從架構本身上spring3 mvc就容易實(shí)現restful url。struts2是類(lèi)級別的攔截,一個(gè)類(lèi)對應一個(gè)request上下文;實(shí)現restful url要費勁,因為struts2 action的一個(gè)方法可以對應一個(gè)url;而其類(lèi)屬性卻被所有方法共享,這也就無(wú)法用注解或其他方式標識其所屬方法了。spring3 mvc的方法之間基本上獨立的,獨享request response數據,請求數據通過(guò)參數獲取,處理結果通過(guò)ModelMap交回給框架方法之間不共享變量,而struts2搞的就比較亂,雖然方法之間 也是獨立的,但其所有Action變量是共享的,這不會(huì )影響程序運行,卻給我們編碼,讀程序時(shí)帶來(lái)麻煩。

7)spring mvc處理ajax請求,直接通過(guò)返回數據,方法中使用注解@ResponseBody,spring mvc自動(dòng)幫我們對象轉換為JSON數據。而struts2是通過(guò)插件的方式來(lái)處理。

在springMVC流行起來(lái)之前,struts2在MVC框架中占核心地位,隨著(zhù)SpringMVC的出現,SpringMVC慢慢的取代了struts2,但是很多的企業(yè)原來(lái)搭建的框架都是使用struts2。

492.說(shuō)一下Spring中的兩大核心

Spring是什么?

Spring是J2EE應用程序框架,是輕量級的IOC和AOP的容器框架,主要針對JavaBean的生命周期進(jìn)行管理的輕量級容器,可以單獨使用,也可以和struts框架,ibatis框架等組合使用。

1)IOC(Inversion of Control)

ioc控制反轉,又稱(chēng)為“依賴(lài)注入”;

IOC的基本概念是:不創(chuàng )建對象,但是描述創(chuàng )建它們的方式。在代碼中不直接與對象和服務(wù)連接,但在配置文件中描述哪一個(gè)組件需要哪一項服務(wù)。容器負責將這些聯(lián)系在一起。   

其原理是基于OO設計原則的The Hollywood Principle:Don't call us, we'll call you(別找我,我會(huì )來(lái)找你的)。也就是說(shuō),所有的組件都是被動(dòng)的(Passive),所有的組件初始化和調用都由容器負責。組件處在一個(gè)容器當中,由容 器負責管理。   

簡(jiǎn)單的來(lái)講,就是由容器控制程序之間的關(guān)系,而非傳統實(shí)現中,由程序代碼直接操控。這也就是所謂“控制反轉”的概念所在:控制權由應用代碼中轉到了外部容器,控制權的轉移,是所謂反轉。

2)AOP 面向切面編程

核心原理:使用動(dòng)態(tài)代理的設計模式在執行方法前后或出現異常常做加入相關(guān)邏輯

我們使用AOP來(lái)做:

1)事務(wù)處理:執行方法前開(kāi)啟事務(wù),執行完成后關(guān)閉事務(wù),出現異常后回滾事務(wù)

2)權限判斷:在執行方法前,判斷是否具有權限

3)日志:在執行前進(jìn)行日志處理

493.講一下Spring的事務(wù)的傳播特性

多個(gè)事物存在是怎么處理的策略

1)PROPAGATION_REQUIRED:如果存在一個(gè)事務(wù),則支持當前事務(wù),如果當前沒(méi)有事務(wù),就新建一個(gè)事務(wù)。這是最常見(jiàn)的選擇。

2)PROPAGATION_SUPPORTS:如果存在一個(gè)事務(wù),支持當前事務(wù),如果當前沒(méi)有事務(wù),就以非事務(wù)方式執行。

3)PROPAGATION_MANDATORY:如果存在一個(gè)事務(wù),支持當前事務(wù),如果當前沒(méi)有事務(wù),就拋出異常。

4)PROPAGATION_REQUIRES_NEW:新建事務(wù),如果當前存在事務(wù),把當前事務(wù)掛起。

5)PROPAGATION_NOT_SUPPORTED:以非事務(wù)方式執行操作,如果當前存在事務(wù),就把當前事務(wù)掛起。

6)PROPAGATION_NEVER:以非事務(wù)方式執行,如果當前存在事務(wù),則拋出異常。

7)PROPAGATION_NESTED:支持當前事務(wù),新增Savepoint點(diǎn),與當前事務(wù)同步提交或回滾。

494.什么是ORM

對象關(guān)系映射(Object Relation Mapping,簡(jiǎn)稱(chēng)ORM)模式是一種為了解決面向對象與關(guān)系數據庫存在的互不匹配的現象的技術(shù),簡(jiǎn)單的說(shuō),ORM是通過(guò)使用描述對象和數據庫之間映射的元數據,將程序中的對象自動(dòng)持久化到關(guān)系數據庫中,那么到底如何實(shí)現持久化呢?一種簡(jiǎn)單的方案時(shí)采用硬編碼方式(jdbc操作sql方式),為每一種可能的數據庫訪(fǎng)問(wèn)操作提供單獨的方法。

這種方案存在以下不足:

1. 持久化層缺乏彈性,一旦出現業(yè)務(wù)需求變更,就必須修改持久化層的接口

2. 持久化層同時(shí)與域模型與關(guān)系數據庫模型綁定,不管域模型還是關(guān)系數據庫模型發(fā)生變化,都要修改持久化層的相關(guān)程序代碼,增加軟件的維護難度。

ORM提供了實(shí)現持久化層的另一種模式,它采用映射元數據來(lái)描述對象關(guān)系的映射,使得ORM中間件能在任何一個(gè)應用的業(yè)務(wù)邏輯層和數據庫層之間充當橋梁,Java典型的ORM框架有:Hibernate,ibatis(mybtis),speedframework。

ORM框架的方法論基于三個(gè)核心原則:

簡(jiǎn)單:以最基本的形式建模數據

傳達性:數據庫結構被任何人都能理解的語(yǔ)言文檔化

精確性:基于數據模型創(chuàng )建正確標準化了結構

對象關(guān)系映射(Object Relation Mapping,簡(jiǎn)稱(chēng)ORM)模式是一種為了解決面向對象與關(guān)系數據庫存在的互不匹配的現象的技術(shù),可以簡(jiǎn)單的方案采用硬編碼方式(jdbc操作sql方式),為每一種可能的數據庫訪(fǎng)問(wèn)操作提供單獨的方法,這種方法存在很多缺陷,使用ORM框架(為了解決面向對象與關(guān)系數據庫存在互不匹配的現象的框架)來(lái)解決。

495.Hibernate對象的狀態(tài)

臨時(shí)狀態(tài)/瞬時(shí)狀態(tài)(transient):剛剛用new語(yǔ)句創(chuàng )建,沒(méi)有被持久化,無(wú)id

不處于session中(沒(méi)有使用session的方法去操作臨時(shí)對象),該對象成為臨時(shí)對象

持久化狀態(tài),托管狀態(tài)(persistent):已經(jīng)被持久化,加入session的緩存中,session是沒(méi)有關(guān)閉

該狀態(tài)的對象為持久化對象。

游離狀態(tài),脫管狀態(tài)(detached):已經(jīng)被持久化,但不處于session中,該狀態(tài)的對象為游離對象。

刪除狀態(tài)(removed):對象有關(guān)聯(lián)的id,并且在session管理下,但是已經(jīng)被計劃(事務(wù)提交的時(shí)候,commit)刪除,如果沒(méi)有事務(wù)就不能刪除

相互轉換

496.介紹一下Hibernate的緩存

答:一、why(為什么要用Hibernate緩存?)

Hibernate是一種持久化層框架,經(jīng)常訪(fǎng)問(wèn)物理數據庫。

為了降低應用程序對物理數據源訪(fǎng)問(wèn)的頻次,從而提高應用程序的運行性能

緩存內的數據是對物理數據源中的數據的復制,應用程序在運行時(shí)從緩存讀寫(xiě)數據,在特定的時(shí)刻或事件會(huì )同步緩存和物理數據源的數據。

為了提高訪(fǎng)問(wèn)速度,把磁盤(pán)或者數據庫訪(fǎng)問(wèn)變成內存訪(fǎng)問(wèn)

二、what(Hibernate緩存原理是怎樣的?)Hibernate緩存包括兩大類(lèi):Hibernate 一級緩存和Hibernate二級緩存

1. Hibernate一級緩存又稱(chēng)為”session的緩存”。

session緩存內置不能被卸載,session的緩存是事務(wù)范圍的緩存(session對象的生命周期通常對應一個(gè)數據庫事務(wù)或者一個(gè)應用事務(wù))。

一級緩存中,持久化類(lèi)的每個(gè)實(shí)例都具有唯一的OID

2. Hibernate的二級緩存又稱(chēng)為”sessionFactory的緩存”。

由于sessionFactory對象的生命周期和應用程序的整個(gè)過(guò)程對應,因此Hibernate二級緩存是進(jìn)程范圍或者集群范圍的緩存,有可能出現并發(fā)問(wèn)題,因此需要采用適當的并發(fā)訪(fǎng)問(wèn)策略,該策略為被緩存的數據提供了事務(wù)隔離級別。

第二級緩存是可選的,是一個(gè)可配置的插件,默認下sessionFactory不會(huì )啟用這個(gè)插件。

什么樣的數據適合存放到二級緩存中?

1) 很少被修改的數據 (帖子的最后回復時(shí)間)

2) 經(jīng)常被查詢(xún)的數據 (電商的地點(diǎn))

3) 不是很重要的數據,允許出現偶爾并發(fā)的數據

4) 不會(huì )被并發(fā)訪(fǎng)問(wèn)的數據

5) 常量數據

擴展:Hibernate的二級緩存默認是不支持分布式緩存的,使用memcache,redis等中央緩存來(lái)代替二級緩存。

497.簡(jiǎn)單講一下webservice使用的場(chǎng)景

webservice是一個(gè)SOA(面向服務(wù)的編程)的架構,它是不依賴(lài)于語(yǔ)言,不依賴(lài)于平臺,可以實(shí)現不同的語(yǔ)言間的相互調用,通過(guò)Internet進(jìn)行基于http協(xié)議的網(wǎng)絡(luò )應用間的交互。

1、異構系統(不同的開(kāi)發(fā)語(yǔ)言)的整合

2、不同客戶(hù)端的整合 (瀏覽器、手機端(android\ios)、微信)

3、實(shí)實(shí)在在的例子:

天氣預報:可以通過(guò)實(shí)現webservice客戶(hù)端調用遠程天氣服務(wù)實(shí)現的

4、單點(diǎn)登錄:一個(gè)服務(wù)實(shí)現所有系統的登錄

498.簡(jiǎn)單介紹一下activity?

Activity是一個(gè)業(yè)務(wù)流程管理(BPM)和工作流系統,適用于開(kāi)發(fā)人員和系統管理員,其核心是超快速,穩定的BPMN2的流程引擎,它易于與Spring集成使用。

主要用在OA中,把線(xiàn)下流程放在線(xiàn)上,把現實(shí)生活中一些流程固話(huà)定義到系統中,然后通過(guò)輸入表單數據完成業(yè)務(wù)。

他可以用在OA系統的流程管理中

請假流程(小于三天,一級主管審批,大于三天二級主管審批)

報銷(xiāo)流程(價(jià)格區間)

499.什么是MyBatis?

答:MyBatis是一個(gè)可以自定義SQL、存儲過(guò)程和高級映射的持久層框架。

500.Mybatis是如何進(jìn)行分頁(yè)的?分頁(yè)插件的原理是什么?

答:1)Mybatis使用RowBounds對象進(jìn)行分頁(yè),也可以直接編寫(xiě)sql實(shí)現分頁(yè),也可以使用Mybatis的分頁(yè)插件。

2)分頁(yè)插件的原理:實(shí)現Mybatis提供的接口,實(shí)現自定義插件,在插件的攔截方法內攔截待執行的sql,然后重寫(xiě)sql。

舉例:select * from student,攔截sql后重寫(xiě)為:select t.* from (select * from student)t limit 0,10

501.MyBatis與Hibernate有哪些不同?

答:1)Mybatis和hibernate不同,它不完全是一個(gè)ORM框架,因為MyBatis需要程序員自己編寫(xiě)Sql語(yǔ)句,不過(guò)mybatis可以通過(guò)XML或注解方式靈活配置要運行的sql語(yǔ)句,并將java對象和sql語(yǔ)句映射生成最終執行的sql,最后將sql執行的結果再映射生成java對象。

2)Mybatis學(xué)習門(mén)檻低,簡(jiǎn)單易學(xué),程序員直接編寫(xiě)原生態(tài)sql,可嚴格控制sql執行性能,靈活度高,非常適合對關(guān)系數據模型要求不高的軟件開(kāi)發(fā),例如互聯(lián)網(wǎng)軟件、企業(yè)運營(yíng)類(lèi)軟件等,因為這類(lèi)軟件需求變化頻繁,一但需求變化要求成果輸出迅速。但是靈活的前提是mybatis無(wú)法做到數據庫無(wú)關(guān)性,如果需要實(shí)現支持多種數據庫的軟件則需要自定義多套sql映射文件,工作量大。

3)Hibernate對象/關(guān)系映射能力強,數據庫無(wú)關(guān)性好,對于關(guān)系模型要求高的軟件(例如需求固定的定制化軟件)如果用hibernate開(kāi)發(fā)可以節省很多代碼,提高效率。但是Hibernate的缺點(diǎn)是學(xué)習門(mén)檻高,要精通門(mén)檻更高,而且怎么設計O/R映射,在性能和對象模型之間如何權衡,以及怎樣用好Hibernate需要具有很強的經(jīng)驗和能力才行。

總之,按照用戶(hù)的需求在有限的資源環(huán)境下只要能做出維護性、擴展性良好的軟件架構都是好架構,所以框架只有適合才是最好。

502.簡(jiǎn)述Mybatis的Xml映射文件和Mybatis內部數據結構之間的映射關(guān)系?

答: Mybatis將所有Xml配置信息都封裝到All-In-One重量級對象Configuration內部。在Xml映射文件中,< parameterMap>標簽會(huì )被解析為ParameterMap對象,其每個(gè)子元素會(huì )被解析為ParameterMapping對象。< resultMap>標簽會(huì )被解析為ResultMap對象,其每個(gè)子元素會(huì )被解析為ResultMapping對象。每一個(gè)< select>、< insert>、< update>、< delete>標簽均會(huì )被解析為MappedStatement對象,標簽內的sql會(huì )被解析為BoundSql對象。

503.什么是MyBatis的接口綁定,有什么好處?

答:接口映射就是在MyBatis中任意定義接口,然后把接口里面的方法和SQL語(yǔ)句綁定,我們直接調用接口方法就可以,這樣比起原來(lái)了SqlSession提供的方法我們可以有更加靈活的選擇和設置.

504.Mybatis能執行一對一、一對多的關(guān)聯(lián)查詢(xún)嗎?都有哪些實(shí)現方式,以及它們之間的區別?

答:能,Mybatis不僅可以執行一對一、一對多的關(guān)聯(lián)查詢(xún),還可以執行多對一,多對多的關(guān)聯(lián)查詢(xún),多對一查詢(xún),其實(shí)就是一對一查詢(xún),只需要把selectOne()修改為selectList()即可;多對多查詢(xún),其實(shí)就是一對多查詢(xún),只需要把selectOne()修改為selectList()即可。

關(guān)聯(lián)對象查詢(xún),有兩種實(shí)現方式,一種是單獨發(fā)送一個(gè)sql去查詢(xún)關(guān)聯(lián)對象,賦給主對象,然后返回主對象。另一種是使用嵌套查詢(xún),嵌套查詢(xún)的含義為使用join查詢(xún),一部分列是A對象的屬性值,另外一部分列是關(guān)聯(lián)對象B的屬性值,好處是只發(fā)一個(gè)sql查詢(xún),就可以把主對象和其關(guān)聯(lián)對象查出來(lái)。

505.MyBatis里面的動(dòng)態(tài)Sql是怎么設定的?用什么語(yǔ)法?

答:MyBatis里面的動(dòng)態(tài)Sql一般是通過(guò)if節點(diǎn)來(lái)實(shí)現,通過(guò)OGNL語(yǔ)法來(lái)實(shí)現,但是如果要寫(xiě)的完整,必須配合where,trim節點(diǎn),where節點(diǎn)是判斷包含節點(diǎn)有內容就插入where,否則不插入,trim節點(diǎn)是用來(lái)判斷如果動(dòng)態(tài)語(yǔ)句是以and 或or開(kāi)始,那么會(huì )自動(dòng)把這個(gè)and或者or取掉。

506.使用MyBatis的mapper接口調用時(shí)有哪些要求?

答:1)Mapper接口方法名和mapper.xml中定義的每個(gè)sql的id相同

2)Mapper接口方法的輸入參數類(lèi)型和mapper.xml中定義的每個(gè)sql 的parameterType的類(lèi)型相同

3)Mapper接口方法的輸出參數類(lèi)型和mapper.xml中定義的每個(gè)sql的resultType的類(lèi)型相同

4)Mapper.xml文件中的namespace即是mapper接口的類(lèi)路徑。

507.Mybatis是如何將sql執行結果封裝為目標對象并返回的?都有哪些映射形式?

答:第一種是使用< resultMap>標簽,逐一定義列名和對象屬性名之間的映射關(guān)系。

第二種是使用sql列的別名功能,將列別名書(shū)寫(xiě)為對象屬性名,比如T_NAME AS NAME,對象屬性名一般是name,小寫(xiě),但是列名不區分大小寫(xiě),Mybatis會(huì )忽略列名大小寫(xiě),智能找到與之對應對象屬性名,你甚至可以寫(xiě)成T_NAME AS NaMe,Mybatis一樣可以正常工作。

有了列名與屬性名的映射關(guān)系后,Mybatis通過(guò)反射創(chuàng )建對象,同時(shí)使用反射給對象的屬性逐一賦值并返回,那些找不到映射關(guān)系的屬性,是無(wú)法完成賦值的。

508.MyBatis接口綁定有幾種實(shí)現方式,分別是怎么實(shí)現的?

答:接口綁定有兩種實(shí)現方式,一種是通過(guò)注解綁定,就是在接口的方法上面加上@Select@Update等注解里面包含Sql語(yǔ)句來(lái)綁定,另外一種就是通過(guò)xml里面寫(xiě)SQL來(lái)綁定,在這種情況下,要指定xml映射文件里面的namespace必須為接口的全路徑名.

509.MyBatis實(shí)現一對一有幾種方式?具體怎么操作的?

答:有聯(lián)合查詢(xún)和嵌套查詢(xún),聯(lián)合查詢(xún)是幾個(gè)表聯(lián)合查詢(xún),只查詢(xún)一次,通過(guò)在resultMap里面配置association節點(diǎn)配置一對一的類(lèi)就可以完成;嵌套查詢(xún)是先查一個(gè)表,根據這個(gè)表里面的結果的外鍵id,去再另外一個(gè)表里面查詢(xún)數據,也是通過(guò)association配置,但另外一個(gè)表的查詢(xún)通過(guò)select屬性配置。

510.什么情況下用注解綁定,什么情況下用xml綁定?

答:當Sql語(yǔ)句比較簡(jiǎn)單時(shí)候,用注解綁定;當SQL語(yǔ)句比較復雜時(shí)候,用xml綁定,一般用xml綁定的比較多

511.MyBatis的好處是什么?

答:1) MyBatis把sql語(yǔ)句從Java源程序中獨立出來(lái), 放在單獨的XML文件中編寫(xiě),給程序的維護帶來(lái)了很大便利。

2) MyBatis封裝了底層JDBC API的調用細節,并能自動(dòng)將結果集轉換成Java Bean對象,大大簡(jiǎn)化了Java數據庫編程的重復工作。

3) 因為MyBatis需要程序員自己去編寫(xiě)sql語(yǔ)句,程序員可以結合數據庫自身的特點(diǎn)靈活控制sql語(yǔ)句, 因此能夠實(shí)現比Hibernate等全自動(dòng)orm框架更高的查詢(xún)效率,能夠完成復雜查詢(xún)。

微服務(wù)框架

512.Spring Boot有哪些優(yōu)點(diǎn)?

答:Spring Boot的優(yōu)點(diǎn)有:

減少開(kāi)發(fā),測試時(shí)間和努力。

使用JavaConfig有助于避免使用XML。

避免大量的Maven導入和各種版本沖突。

提供意見(jiàn)發(fā)展方法。

通過(guò)提供默認值快速開(kāi)始開(kāi)發(fā)。

沒(méi)有單獨的Web服務(wù)器需要。這意味著(zhù)你不再需要啟動(dòng)Tomcat,Glassfish或其他任何東西。

需要更少的配置 因為沒(méi)有web.xml文件。只需添加用@ Configuration注釋的類(lèi),然后添加用@Bean注釋的方法,Spring將自動(dòng)加載對象并像以前一樣對其進(jìn)行管理。您甚至可以將@Autowired添加到bean方法中,以使Spring自動(dòng)裝入需要的依賴(lài)關(guān)系中。

基于環(huán)境的配置 使用這些屬性,您可以將您正在使用的環(huán)境傳遞到應用程序:-Dspring.profiles.active = {enviornment}。在加載主應用程序屬性文件后,Spring將在(application{environment} .properties)中加載后續的應用程序屬性文件。

513.如何重新加載Spring Boot上的更改,而無(wú)需重新啟動(dòng)服務(wù)器?

答:這可以使用DEV工具來(lái)實(shí)現。通過(guò)這種依賴(lài)關(guān)系,您可以節省任何更改,嵌入式tomcat將重新啟動(dòng)。Spring Boot有一個(gè)開(kāi)發(fā)工具(DevTools)模塊,它有助于提高開(kāi)發(fā)人員的生產(chǎn)力。Java開(kāi)發(fā)人員面臨的一個(gè)主要挑戰是將文件更改自動(dòng)部署到服務(wù)器并自動(dòng)重啟服務(wù)器。開(kāi)發(fā)人員可以重新加載Spring Boot上的更改,而無(wú)需重新啟動(dòng)服務(wù)器。這將消除每次手動(dòng)部署更改的需要。Spring Boot在發(fā)布它的第一個(gè)版本時(shí)沒(méi)有這個(gè)功能。這是開(kāi)發(fā)人員最需要的功能。DevTools模塊完全滿(mǎn)足開(kāi)發(fā)人員的需求。該模塊將在生產(chǎn)環(huán)境中被禁用。它還提供H2數據庫控制臺以更好地測試應用程序。

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
514.常見(jiàn)的系統架構風(fēng)格有哪些?各有什么優(yōu)缺點(diǎn)?

1、單體架構

單體架構也稱(chēng)之為單體系統或者是單體應用。就是一種把系統中所有的功能、模塊耦合在一個(gè)應用中的架構方式。

單體架構特點(diǎn):打包成一個(gè)獨立的單元(導成一個(gè)唯一的jar包或者是war包),會(huì )一個(gè)進(jìn)程的方式來(lái)運行。

單體架構的優(yōu)點(diǎn)、缺點(diǎn)

優(yōu)點(diǎn):

項目易于管理

部署簡(jiǎn)單

缺點(diǎn):

測試成本高

可伸縮性差

可靠性差

迭代困難

跨語(yǔ)言程度差

團隊協(xié)作難

2、MVC架構

MVC架構特點(diǎn):

MVC是模型(Model)、視圖(View)、控制器(Controller)3個(gè)單詞的縮寫(xiě)。 下面我們從這3個(gè)方面來(lái)講解MVC中的三個(gè)要素。

Model是指數據模型,是對客觀(guān)事物的抽象。 如一篇博客文章,我們可能會(huì )以一個(gè)Post類(lèi)來(lái)表示,那么,這個(gè)Post類(lèi)就是數據對象。 同時(shí),博客文章還有一些業(yè)務(wù)邏輯,如發(fā)布、回收、評論等,這一般表現為類(lèi)的方法,這也是model的內容和范疇。 對于Model,主要是數據、業(yè)務(wù)邏輯和業(yè)務(wù)規則。相對而言,這是MVC中比較穩定的部分,一般成品后不會(huì )改變。 開(kāi)發(fā)初期的最重要任務(wù),主要也是實(shí)現Model的部分。這一部分寫(xiě)得好,后面就可以改得少,開(kāi)發(fā)起來(lái)就快。

View是指視圖,也就是呈現給用戶(hù)的一個(gè)界面,是model的具體表現形式,也是收集用戶(hù)輸入的地方。 如你在某個(gè)博客上看到的某一篇文章,就是某個(gè)Post類(lèi)的表現形式。 View的目的在于提供與用戶(hù)交互的界面。換句話(huà)說(shuō),對于用戶(hù)而言,只有View是可見(jiàn)的、可操作的。 事實(shí)上也是如此,你不會(huì )讓用戶(hù)看到Model,更不會(huì )讓他直接操作Model。 你只會(huì )讓用戶(hù)看到你想讓他看的內容。 這就是View要做的事,他往往是MVC中變化頻繁的部分,也是客戶(hù)經(jīng)常要求改來(lái)改去的地方。 今天你可能會(huì )以一種形式來(lái)展示你的博文,明天可能就變成別的表現形式了。

Contorller指的是控制器,主要負責與model和view打交道。 換句話(huà)說(shuō),model和view之間一般不直接打交道,他們老死不相往來(lái)。view中不會(huì )對model作任何操作, model不會(huì )輸出任何用于表現的東西,如HTML代碼等。這倆甩手不干了,那總得有人來(lái)干吧,只能Controller上了。 Contorller用于決定使用哪些Model,對Model執行什么操作,為視圖準備哪些數據,是MVC中溝通的橋梁。

MVC架構優(yōu)缺點(diǎn)

優(yōu)點(diǎn):

各施其職,互不干涉。

在MVC模式中,三個(gè)層各施其職,所以如果一旦哪一層的需求發(fā)生了變化,就只需要更改相應的層中的代碼而不會(huì )影響到其它層中的代碼。

有利于開(kāi)發(fā)中的分工。

在MVC模式中,由于按層把系統分開(kāi),那么就能更好的實(shí)現開(kāi)發(fā)中的分工。網(wǎng)頁(yè)設計人員可以進(jìn)行開(kāi)發(fā)視圖層中的JSP,對業(yè)務(wù)熟悉的開(kāi)發(fā)人員可開(kāi)發(fā)業(yè)務(wù)層,而其它開(kāi)發(fā)人員可開(kāi)發(fā)控制層。

有利于組件的重用。

分層后更有利于組件的重用。如控制層可獨立成一個(gè)能用的組件,視圖層也可做成通用的操作界面。

缺點(diǎn):

增加了系統結構和實(shí)現的復雜性。

視圖與控制器間的過(guò)于緊密的連接。

視圖對模型數據的低效率訪(fǎng)問(wèn)。

3、面向服務(wù)架構(SOA)

面向服務(wù)的架構(SOA)是一個(gè)組件模型,它將應用程序拆分成不同功能單元(稱(chēng)為服務(wù))通過(guò)這些服務(wù)之間定義良好的接口和契約聯(lián)系起來(lái)。接口是采用中立的方式進(jìn)行定義的,它應該獨立于實(shí)現服務(wù)的硬件平臺、操作系統和編程語(yǔ)言。這使得構建在各種各樣的系統中的服務(wù)可以以一種統一和通用的方式進(jìn)行交互。

面向服務(wù)架構特點(diǎn):

系統是由多個(gè)服務(wù)構成

每個(gè)服務(wù)可以單獨獨立部署

每個(gè)服務(wù)之間是松耦合的。服務(wù)內部是高內聚的,外部是低耦合的。高內聚就是每個(gè)服務(wù)只關(guān)注完成一個(gè)功能。

服務(wù)的優(yōu)點(diǎn)、缺點(diǎn)

優(yōu)點(diǎn):

測試容易

可伸縮性強

可靠性強

跨語(yǔ)言程度會(huì )更加靈活

團隊協(xié)作容易

系統迭代容易

缺點(diǎn):

運維成本過(guò)高,部署數量較多

接口兼容多版本

分布式系統的復雜性

分布式事務(wù)

515.什么是AKF拆分原則?

業(yè)界對于可擴展的系統架構設計有一個(gè)樸素的理念,就是:通過(guò)加機器就可以解決容量和可用性問(wèn)題。(如果一臺不行那就兩臺)。

我是個(gè)段子:(世界上沒(méi)有什么事是一頓燒烤不能解決的。如果有,那就兩頓。)

這一理念在“云計算”概念瘋狂流行的今天,得到了廣泛的認可!對于一個(gè)規模迅速增長(cháng)的系統而言,容量和性能問(wèn)題當然是首當其沖的。但是隨著(zhù)時(shí)間的向前,系統規模的增長(cháng),除了面對性能與容量的問(wèn)題外,還需要面對功能與模塊數量上的增長(cháng)帶來(lái)的系統復雜性問(wèn)題以及業(yè)務(wù)的變化帶來(lái)的提供差異化服務(wù)問(wèn)題。而許多系統,在架構設計時(shí)并未充分考慮到這些問(wèn)題,導致系統的重構成為常態(tài),從而影響業(yè)務(wù)交付能力,還浪費人力財力!對此,《可擴展的藝術(shù)》一書(shū)提出了一個(gè)更加系統的可擴展模型——?AKF可擴展立方?(Scalability Cube) 。這個(gè)立方體中沿著(zhù)三個(gè)坐標軸設置分別為:X、Y、Z。

Y軸擴展會(huì )將龐大的整體應用拆分為多個(gè)服務(wù)。每個(gè)服務(wù)實(shí)現一組相關(guān)的功能,如訂單管理、客戶(hù)管理等。在工程上常見(jiàn)的方案是?服務(wù)化架構(SOA)?。比如對于一個(gè)電子商務(wù)平臺,我們可以拆分成不同的服務(wù)

X軸擴展與我們前面樸素理念是一致的,通過(guò)絕對平等地復制服務(wù)與數據,以解決容量和可用性的問(wèn)題。其實(shí)就是將微服務(wù)運行多個(gè)實(shí)例,做集群加負載均衡的模式。

Z軸擴展通常是指基于請求者或用戶(hù)獨特的需求,進(jìn)行系統劃分,并使得劃分出來(lái)的子系統是相互隔離但又是完整的。以生產(chǎn)汽車(chē)的工廠(chǎng)來(lái)舉例:福特公司為了發(fā)展在中國的業(yè)務(wù),或者利用中國的廉價(jià)勞動(dòng)力,在中國建立一個(gè)完整的子工廠(chǎng),與美國工廠(chǎng)一樣,負責完整的汽車(chē)生產(chǎn)。這就是一種Z軸擴展。

516.什么是Spring Cloud?

Spring Cloud是一個(gè)微服務(wù)框架,相比Dubbo等RPC框架,?Spring Cloud提供的全套的分布式系統解決方案。

Spring Cloud對微服務(wù)基礎框架Netflix的多個(gè)開(kāi)源組件進(jìn)行了封裝,同時(shí)又實(shí)現了和云端平臺以及和Spring Boot開(kāi)發(fā)框架的集成。

Spring Cloud為微服務(wù)架構開(kāi)發(fā)涉及的配置管理,服務(wù)治理,熔斷機制,智能路由,微代理,控制總線(xiàn),一次性token,全局一致性鎖,leader選舉,分布式session,集群狀態(tài)管理等操作提供了一種簡(jiǎn)單的開(kāi)發(fā)方式。

Spring Cloud 為開(kāi)發(fā)者提供了快速構建分布式系統的工具,開(kāi)發(fā)者可以快速的啟動(dòng)服務(wù)或構建應用、同時(shí)能夠快速和云平臺資源進(jìn)行對接

517.Spring Cloud與Dubbo的區別是什么?
518.什么是Eureka注冊中心?

Eureka是Netflix開(kāi)發(fā)的服務(wù)發(fā)現組件,本身是一個(gè)基于REST的服務(wù)。Spring Cloud將它集成在其子項目spring-cloud-netflix中,以實(shí)現Spring Cloud的服務(wù)注冊于發(fā)現,同時(shí)還提供了負載均衡、故障轉移等能力。

519.簡(jiǎn)單談一下Eureka中的三種角色分別是什么?

1、Eureka Server

通過(guò)Register、Get、Renew等接口提供服務(wù)的注冊和發(fā)現。

2、Application Service (Service Provider)

服務(wù)提供方

把自身的服務(wù)實(shí)例注冊到Eureka Server中

3、Application Client (Service Consumer)

服務(wù)調用方

通過(guò)Eureka Server 獲取服務(wù)列表,消費服務(wù)。

520.什么是Ribbon

1.Ribbon 是一個(gè)基于Http和TCP的客服端負載均衡工具,它是基于Netflix Ribbon實(shí)現的。

2.它不像spring cloud服務(wù)注冊中心、配置中心、API網(wǎng)關(guān)那樣獨立部署,但是它幾乎存在于每個(gè)spring cloud 微服務(wù)中。包括feign提供的聲明式服務(wù)調用也是基于該Ribbon實(shí)現的。

3.ribbon默認提供很多種負載均衡算法,例如 輪詢(xún)、隨機 等等。甚至包含自定義的負載均衡算法。

521.集中式與進(jìn)程內負載均衡的區別

目前業(yè)界主流的負載均衡方案可分成兩類(lèi):

第一類(lèi):集中式負載均衡, 即在consumer和provider之間使用獨立的負載均衡設施(可以是硬件,如F5, 也可以是軟件,如nginx), 由該設施負責把 訪(fǎng)問(wèn)請求 通過(guò)某種策略轉發(fā)至provider;

第二類(lèi):進(jìn)程內負載均衡,將負載均衡邏輯集成到consumer,consumer從服務(wù)注冊中心獲知有哪些地址可用,然后自己再從這些地址中選擇出一個(gè)合適的provider。

Ribbon就屬于后者,它只是一個(gè)類(lèi)庫,集成于consumer進(jìn)程,consumer通過(guò)它來(lái)獲取到provider的地址。

522.Ribbon的常見(jiàn)負載均衡策略有哪些?
id 策略名稱(chēng) 策略對應的類(lèi)名 實(shí)現原理
1 輪詢(xún)策略(默認) RoundRobinRule 輪詢(xún)策略表示每次都順序取下一個(gè)provider,比如一共有5個(gè)provider,第1次取第1個(gè),第2次取第2個(gè),第3次取第3個(gè),以此類(lèi)推
2 權重輪詢(xún)策略 WeightedResponseTimeRule 1.根據每個(gè)provider的響應時(shí)間分配一個(gè)權重,響應時(shí)間越長(cháng),權重越小,被選中的可能性越低。 2.原理:一開(kāi)始為輪詢(xún)策略,并開(kāi)啟一個(gè)計時(shí)器,每30秒收集一次每個(gè)provider的平均響應時(shí)間,當信息足夠時(shí),給每個(gè)provider附上一個(gè)權重,并按權重隨機選擇provider,高權越重的provider會(huì )被高概率選中。
3 隨機策略 RandomRule 從provider列表中隨機選擇一個(gè)provider
4 最少并發(fā)數策略 BestAvailableRule 選擇正在請求中的并發(fā)數最小的provider,除非這個(gè)provider在熔斷中。
5 在“選定的負載均衡策略”基礎上進(jìn)行重試機制 RetryRule 1.“選定的負載均衡策略”這個(gè)策略是輪詢(xún)策略RoundRobinRule 2.該重試策略先設定一個(gè)閾值時(shí)間段,如果在這個(gè)閾值時(shí)間段內當選擇provider不成功,則一直嘗試采用“選定的負載均衡策略:輪詢(xún)策略”最后選擇一個(gè)可用的provider
6 可用性敏感策略 AvailabilityFilteringRule 過(guò)濾性能差的provider,有2種: 第一種:過(guò)濾掉在eureka中處于一直連接失敗provider 第二種:過(guò)濾掉高并發(fā)的provider
7 區域敏感性策略 ZoneAvoidanceRule 1.以一個(gè)區域為單位考察可用性,對于不可用的區域整個(gè)丟棄,從剩下區域中選可用的provider 2.如果這個(gè)ip區域內有一個(gè)或多個(gè)實(shí)例不可達或響應變慢,都會(huì )降低該ip區域內其他ip被選中的權重。
523.簡(jiǎn)單說(shuō)說(shuō)什么是Feign?

Feign是一種聲明式、模板化的HTTP客戶(hù)端技術(shù)(僅在consumer中使用)。

524.什么是聲明式,有什么作用,解決什么問(wèn)題?

聲明式調用就像調用本地方法一樣調用遠程方法;無(wú)感知遠程http請求。

1、Spring Cloud的聲明式調用, 可以做到使用 HTTP請求遠程服務(wù)時(shí)能就像調用本地方法一樣的體驗,開(kāi)發(fā)者完全感知不到這是遠程方法,更感知不到這是個(gè)HTTP請求。

2、它像Dubbo一樣,consumer直接調用接口方法調用provider,而不需要通過(guò)常規的Http Client構造請求再解析返回數據。

3、它解決了讓開(kāi)發(fā)者調用遠程接口就跟調用本地方法一樣,無(wú)需關(guān)注與遠程的交互細節,更無(wú)需關(guān)注分布式環(huán)境開(kāi)發(fā)。

525.什么是服務(wù)的災難性的雪崩效應?

在微服務(wù)架構中,一個(gè)請求需要調用多個(gè)服務(wù)是非常常見(jiàn)的。如客戶(hù)端訪(fǎng)問(wèn)A服務(wù),而A服務(wù)需要調用B服務(wù),B服務(wù)需要調用C服務(wù),由于網(wǎng)絡(luò )原因或者自身的原因,如果B服務(wù)或者C服務(wù)不能及時(shí)響應,A服務(wù)將處于阻塞狀態(tài),直到B服務(wù)C服務(wù)響應。此時(shí)若有大量的請求涌入,容器的線(xiàn)程資源會(huì )被消耗完畢,導致服務(wù)癱瘓。服務(wù)與服務(wù)之間的依賴(lài)性,故障會(huì )傳播,造成連鎖反應,會(huì )對整個(gè)微服務(wù)系統造成災難性的嚴重后果,這就是服務(wù)故障的“雪崩”效應

526.如何解決災難性雪崩效應?

降級

超時(shí)降級、資源不足時(shí)(線(xiàn)程或信號量)降級,降級后可以配合降級接口返回托底數據。實(shí)現一個(gè)fallback方法, 當請求后端服務(wù)出現異常的時(shí)候, 可以使用fallback方法返回的值.

隔離(線(xiàn)程池隔離和信號量隔離)

限制調用分布式服務(wù)的資源使用,某一個(gè)調用的服務(wù)出現問(wèn)題不會(huì )影響其他服務(wù)調用。

熔斷

當失敗率(如因網(wǎng)絡(luò )故障/超時(shí)造成的失敗率高)達到閥值自動(dòng)觸發(fā)降級,熔斷器觸發(fā)的快速失敗會(huì )進(jìn)行快速恢復。

緩存

提供了請求緩存。

請求合并

提供請求合并。

527.線(xiàn)程池隔離和信號量隔離的區別
528.請回答微服務(wù)架構的六種常用設計模式是什么?

答:如下這六種
代理設計模式
聚合設計模式
鏈條設計模式
聚合鏈條設計模式
數據共享設計模式
異步消息設計模式

529.什么是網(wǎng)關(guān)服務(wù)?

答:網(wǎng)關(guān)服務(wù),通常是外部訪(fǎng)問(wèn)服務(wù)的唯一接口,訪(fǎng)問(wèn)內部的所有服務(wù)都必須先經(jīng)過(guò)網(wǎng)關(guān)服務(wù)。網(wǎng)關(guān)服務(wù)的主要功能是消息解析過(guò)濾,路由,轉發(fā)等。

530.網(wǎng)關(guān)服務(wù)中,路由器的4種路由規則方法是什么?

答:采用URL指定路由方式

采用服務(wù)名稱(chēng)指定路由方式

路由的排除方法

路由的添加前綴方法

531.為什么要使用spring cloud config 配置中心?它解決了什么問(wèn)題?
532.什么是Spring Cloud Bus
533.消息驅動(dòng)Stream解決了什么問(wèn)題?
534.為什么要使用微服務(wù)跟蹤?它解決了什么問(wèn)題?
535.什么是ELK(ElasticSearch, Logstash, Kibana)

ELK是三個(gè)工具的集合,Elasticsearch + Logstash + Kibana,這三個(gè)工具組合形成了一套實(shí)用、易用的監控架構,很多公司利用它來(lái)搭建可視化的海量日志分析平臺。

1. ElasticSearch

ElasticSearch是一個(gè)基于Lucene的搜索服務(wù)器。它提供了一個(gè)分布式多用戶(hù)能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java開(kāi)發(fā)的,并作為Apache許可條款下的開(kāi)放源碼發(fā)布,是當前流行的企業(yè)級搜索引擎。設計用于云計算中,能夠達到實(shí)時(shí)搜索,穩定,可靠,快速,安裝使用方便。

2. Logstash

Logstash是一個(gè)用于管理日志和事件的工具,你可以用它去收集日志、轉換日志、解析日志并將他們作為數據提供給其它模塊調用,例如搜索、存儲等。

3. Kibana

Kibana是一個(gè)優(yōu)秀的前端日志展示框架,它可以非常詳細的將日志轉化為各種圖表,為用戶(hù)提供強大的數據可視化支持。

536.為什么要用ELK,它解決了什么問(wèn)題?
537.什么是分布式跟蹤?:?Zipki?

數據庫

538.下列屬于關(guān)系型數據庫的是()(選擇兩項)
A. Oracle
B. MySql
C. IMS
D. MongoDB
答案:AB分析: IMS 是IP Mulitimedia Subsystem的縮寫(xiě),是IP多媒體系統 MongoDB分布式文檔存儲數據庫
539.請列出Java常見(jiàn)的開(kāi)源數據連接池,并對參數做出簡(jiǎn)單的說(shuō)明

答:在Java中開(kāi)源的常用的數據庫連接池有以下幾種 :

(1)DBCP

DBCP是一個(gè)依賴(lài)Jakarta commons-pool對象池機制的數據庫連接池.DBCP可以直接的在應用程序中使用,Tomcat的數據源使用的就是DBCP。

(2)c3p0

c3p0是一個(gè)開(kāi)放源代碼的JDBC連接池,它在lib目錄中與Hibernate一起發(fā)布,包括了實(shí)現jdbc3和jdbc2擴展規范說(shuō)明的Connection 和Statement 池的DataSources 對象。

(3)Druid

阿里出品,淘寶和支付寶專(zhuān)用數據庫連接池,但它不僅僅是一個(gè)數據庫連接池,它還包含一個(gè)ProxyDriver,一系列內置的JDBC組件庫,一個(gè)SQL Parser。支持所有JDBC兼容的數據庫,包括Oracle、MySql、Derby、Postgresql、SQL Server、H2等等。

540.儲蓄所有多個(gè)儲戶(hù),儲戶(hù)在多個(gè)儲戶(hù)所存取款,儲蓄所與儲戶(hù)之間是()
A. 一對一的聯(lián)系
B. 多對一的聯(lián)系
C. 一對多的聯(lián)系
D. 多對多的聯(lián)系
答案:D
541.視圖是一個(gè)“虛表”,視圖的構造基于()
A. 基本表或視圖
B. 視圖
C. 數據字典
D. 基本表
答案:A