全國咨詢熱線:400-009-1906

第一篇:面試題匯總

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

本題集由尚學堂學員整理,列舉了眾多IT公司面試真題,對應聘Java程序員職位的常見考點和知識體系都進行的分類和歸納整理。

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

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

大家也可以訪問(直接在線觀看最新版的面試題):www.krazytentertainment.com/javamianshiti.html

1.大學生高端復合人才成長
1.JAVA專業,1000課 3.大數據專業,500課
2.Python專業,500課    4.人工智能專業,500課

四個專業都要學,從零開始2000小時,成為高端人才,打下一生技術基礎,不再是低端碼農。

2.掃一掃,咨詢詳情:

訪問官網 www.itbaizhan.cn

Java基礎、語法:

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

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

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

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

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

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

Java的跨平臺原理決定了其性能沒有C/C++高

2.Java的安全性

語言層次的安全性主要體現在:

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

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

異常處理機制:Java異常機制主要依賴于try、catch、finally、throw、throws五個關鍵字。

強制類型轉換:只有在滿足強制轉換規則的情況下才能強轉成功。

底層的安全性可以從以下方面來說明

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

在運行環境提供了四級安全性保障機制:

字節碼校驗器 -類裝載器 -運行時內存布局 -文件訪問限制

3.Java三大版本

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

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

比如:數據庫連接、接口定義、輸入/輸出、網絡編程

Enterprise Edition(企業版) J2EE 包含J2SE 中的類,并且還包含用于開發企業級應用的類。

比如servlet、JSP、XML、事務控制

Micro Edition(微縮版) J2ME 包含J2SE中一部分類,用于消費類電子產品的軟件開發。

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

他們的范圍是:J2SE包含于J2EE中,J2ME包含了J2SE的核心類,但新添加了一些專有類

應用場合,API的覆蓋范圍各不相同。

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

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

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

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

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

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

lib:類庫??????

jre:java運行環境?

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

JDK,JRE,JVM三者關系概括如下:

jdk是JAVA程序開發時用的開發工具包,其內部也有JRE運行環境JRE。JRE是JAVA程序運行時需要的運行環境,就是說如果你光是運行JAVA程序而不是去搞開發的話,只安裝JRE就能運行已經存在的JAVA程序了。JDk、JRE內部都包含JAVA虛擬機JVM,JAVA虛擬機內部包含許多應用程序的類的解釋器和類加載器等等。

5.Java三種注釋類型

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

單行注釋,采用“//”方式.只能注釋一行代碼。如://類成員變量

多行注釋,采用“/*...*/”方式,可注釋多行代碼,其中不允許出現嵌套。如:

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

System.out.println("b");

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

文檔注釋,采用“/**...*/”方式。如:

/**

* 子類 Dog

* @author Administrator

**/

public class Dog extends Animal{}

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

共同點:

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

2、如果i++,++i是一條單獨的語句,兩者沒有任何區別

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

不同點:

如果i++,++i不是一條單獨的語句,他們就有區別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.&和&&的區別和聯系,|和||的區別和聯系

&和&&的聯系(共同點):

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

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

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

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

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

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

&和&&的區別(不同點):

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

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

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

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

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

|和||的區別和聯系與&和&&的區別和聯系類似

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

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

10.基本數據類型的類型轉換規則

基本類型轉換分為自動轉換和強制轉換。

自動轉換規則:容量小的數據類型可以自動轉換成容量大的數據類型,也可

以說低級自動向高級轉換。這兒的容量指的不是字節數,而是指類型表述的范圍。

強制轉換規則:高級變為低級需要強制轉換。

如何轉換:

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

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

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

11.if多分支語句和switch多分支語句的異同之處

相同之處:都是分支語句,多超過一種的情況進行判斷處理。

不同之處:

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

12.while和do-while循環的區別

while先判斷后執行,第一次判斷為false,循環體一次都不執行

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

如果while循環第一次判斷為true, 則兩種循環沒有區別。

13.break和continue的作用

break: 結束當前循環并退出當前循環體。

break還可以退出switch語句

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

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.遞歸的定義和優缺點

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

遞歸算法解決問題的特點:

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

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

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

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

16.數組的特征

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

數組會在內存中開辟一塊連續的空間,每個空間相當于之前的一個變量,稱為數組的元素element

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

索引從0開始

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

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

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

length:數組的長度

數組的長度是固定的,一經定義,不能再發生變化(數組的擴容)

17.請寫出冒泡排序代碼
package com.bjsxt;

public class TestBubbleSort {
public static void sort(int[] a) {
int temp = 0;
// 外層循環,它決定一共走幾趟
for (int i = 0; i <a.length-1; ++i) {
//內層循環,它決定每趟走一次
for (int j = 0; j <a.length-i-1 ; ++j) {
//如果后一個大于前一個
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) {
//通過符號位可以減少無謂的比較,如果已經有序了,就退出循環
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.請寫出選擇排序的代碼
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.請寫出插入排序的代碼
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.可變參數的作用和特點

總結1:可變參數

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

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

3.可變參數對應的實參可以0,1,2.....個,也可以是一個數組

4.在可變參數的方法中,將可變參數當做數組來處理

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

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

7.如果定義了可變參數的方法,不允許同時定義相同類型數組參數的方法

總結2:數組做形參和可變參數做形參聯系和區別

聯系:

1.實參都可以是數組;2.方法體中,可變參數當做數組來處理

區別:

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

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

3.實參不同 可變參數實參可以0,1,2.....個,也可以是一個數組,數組的實參只能是數組

21.類和對象的關系

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

類和對象好比圖紙和實物的關系,模具和鑄件的關系。

比如人類就是一個概念,人類具有身高,體重等屬性。人類可以做吃飯、說話等方法。

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

22.面向過程和面向對象的區別

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

比喻

蔣介石和毛澤東分別是面向過程和面向對象的杰出代表,這樣充分說明,在解決復制問題時,面向對象有更大的優越性。

面向過程是蛋炒飯,面向對象是蓋澆飯。蓋澆飯的好處就是“菜”“飯”分離,從而提高了制作蓋澆飯的靈活性。飯不滿意就換飯,菜不滿意換菜。用軟件工程的專業術語就是“可維護性”比較好,“飯” 和“菜”的耦合度比較低。

區別

編程思路不同: 面向過程以實現功能的函數開發為主,而面向對象要首先抽象出類、屬性及其方法,然后通過實例化類、執行方法來完成功能。

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

面向對象具有繼承性和多態性,而面向過程沒有繼承性和多態性,所以面向對象優勢是明顯。

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

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

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

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

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

24.static關鍵字的作用

static可以修飾變量、方法、代碼塊和內部類

static屬性屬于這個類所有,即由該類創建的所有對象共享同一個static屬性??梢詫ο髣摻ê笸ㄟ^對象名.屬性名和類名.屬性名兩種方式來訪問。也可以在沒有創建任何對象之前通過類名.屬性名的方式來訪問。

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

1.在內存中份數不同

不管有多少個對象,static變量只有1份。對于每個對象,實例變量都會有單獨的一份

static變量是屬于整個類的,也稱為類變量。而非靜態變量是屬于對象的,也稱為實例變量

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

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

3.訪問的方式不同

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

靜態變量:對象名.變量名 stu1.schoolName="西二旗小學"; 不推薦如此使用

類名.變量名 Student.schoolName="東三旗小學"; 推薦使用

4.在內存中分配空間的時間不同

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

static方法也可以通過對象名.方法名和類名.方法名兩種方式來訪問

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

static內部類:屬于整個外部類,而不是屬于外部類的每個對象。不能訪問外部類的非靜態成員(變量或者方法),.可以訪問外部類的靜態成員

25.final和abstract關鍵字的作用

final和abstract是功能相反的兩個關鍵字,可以對比記憶

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

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

特別注意:final修飾基本類型變量,其值不能改變,由原來的變量變為常量;但是final修飾引用類型變量,棧內存中的引用不能改變,但是所指向的堆內存中的對象的屬性值仍舊可以改變。例如

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

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

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

27.寫出java.lang.Object類的六個常用方法

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

比較對象的地址值是否相等,如果子類重寫,則比較對象的內容是否相等;

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

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

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

(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

多線程中等待功能

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

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

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

類的訪問權限只有兩種

public公共的 可被同一項目中所有的類訪問。 (必須與文件名同名)

default默認的 可被同一個包中的類訪問。

成員(成員變量或成員方法)訪問權限共有四種:

public 公共的 可以被項目中所有的類訪問。(項目可見性)

protected 受保護的 可以被這個類本身訪問;同一個包中的所有其他的類訪問;被它的子類(同一個包以及不同包中的子類)訪問。(子類可見性)

default 默認的被這個類本身訪問;被同一個包中的類訪問。(包可見性)

private 私有的 只能被這個類本身訪問。(類可見性)

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

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

情況1:如果子類的構造方法中沒有通過super顯式調用父類的有參構造方法,也沒有通過this顯式調用自身的其他構造方法,則系統會默認先調用父類的無參構造方法。在這種情況下,寫不寫“super();”語句,效果是一樣的。

情況2:如果子類的構造方法中通過super顯式調用父類的有參構造方法,那將執行父類相應構造方法,而不執行父類無參構造方法。

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

特別注意的是,如果存在多級繼承關系,在創建一個子類對象時,以上規則會多次向更高一級父類應用,一直到執行頂級父類Object類的無參構造方法為止。

30.==和equals的區別和聯系

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

“==”使用情況如下:

a) 基本類型,比較的是值

b) 引用類型,比較的是地址

c) 不能比較沒有父子關系的兩個對象

equals()方法使用如下:

a) 系統類一般已經覆蓋了equals(),比較的是內容。

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

c) 用戶自定義類需要覆蓋父類的equals()

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

31.談談Java的多態

實現多態的三個條件(前提條件,向上轉型、向下轉型)

1、繼承的存在;(繼承是多態的基礎,沒有繼承就沒有多態)

2、子類重寫父類的方法。(多態下會調用子類重寫后的方法)

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

向上轉型 Student person = new Student()

將一個父類的引用指向一個子類對象,成為向上轉型,自動進行類型轉換。此時通過父類引用變量調用的方法是子類覆蓋或繼承父類的方法,而不是父類的方法此時通過父類引用變量無法調用子類特有的方法。

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

將一個指向子類對象的引用賦給一個子類的引用,成為向下轉型,此時必須進行強制類型轉換。向下轉型必須轉換為父類引用指向的真實子類類型,,否則將出現ClassCastException,不是任意的強制轉換

向下轉型時可以結合使用instanceof運算符進行強制類型轉換,比如出現轉換異常---ClassCastException

32.簡述Java的垃圾回收機制

傳統的C/C++語言,需要程序員負責回收已經分配內存。

顯式回收垃圾回收的缺點:

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

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

Java語言不需要程序員直接控制內存回收,是由JRE在后臺自動回收不再使用的內存,稱為垃圾回收機制,簡稱GC;

1)可以提高編程效率。

2)保護程序的完整性。

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

垃圾回收機制的 特點

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

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

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

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

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

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

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

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

33.基本數據類型和包裝類

1) 八個基本數據類型的包裝類

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

2)為什么為基本類型引入包裝類

2.1基本數據類型有方便之處,簡單、高效。

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

為了解決這個不足,在設計類時為每個基本數據類型設計了一個對應的類進行包裝,這樣八個和基本數據類型對應的類統稱為包裝類(Wrapper Class)。

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

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

3.2包裝類-------new WrapperClass(primitive)

3.2包裝類-------new WrapperClass(primitive)

4) 自動裝箱和自動拆箱

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

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

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

34.Integer與int的區別

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

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

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

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

35.java.sql.Date和java.util.Date的聯系和區別

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

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

總之,java.util.Date 就是Java的日期對象,而java.sql.Date 是針對SQL語句使用的,只包含日期而沒有時間部分。

36.使用遞歸算法輸出某個目錄下所有文件和子目錄列表
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.關于Java編譯,下面哪一個正確()(選擇一項)
A Java程序經編譯后產生machine code
B. Java程序經編譯后會生產byte code
C. Java程序經編譯后會產生DLL
D. 以上都不正確
答案:B
分析: Java是解釋型語言,編譯出來的是字節碼; 因此A不正確,C是C/C++語言編譯動態鏈接庫的文件為.DLL; 正確答案為B
38.下列說法正確的有()(選擇一項)
A class中的construtor不可省略
B. construtor與class同名,但方法不能與class同名
C. construtor在一個對象被new時執行
D. 一個class只能定義一個construtor
答案:C
分析:A:如果class中的construtor省略不寫,系統會默認提供一個無參構造
B:方法名可以與類名同名,只是不符合命名規范
D:一個class中可以定義N多個construtor,這些construtor構成構造方法的重載
39.Java中接口的修飾符可以為()(選擇一項)
A private
B. protected
C. final
D. abstract
答案:D
分析:接口中的訪問權限修飾符只可以是public或default
接口中的所有的方法必須要實現類實現,所以不能使用final
接口中所有的方法默認都是abstract的,所以接口可以使用abstract修飾,但通常abstract可以省略不寫
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 不能通過編譯
B. 通過編譯,輸出AB
C. 通過編譯,輸出B
D. 通過編譯,輸出A
答案:B
分析:在繼承關系下,創建子類對象,先執行父類的構造方法,再執行子類的構造方法。
41.下列關于關鍵字的使用說法錯誤的是()(選擇一項)
A abstract不能與final并列修飾同一個類
B. abstract類中可以有private的成員
C. abstract方法必須在abstract類中
D. static方法能處理非static的屬性
答案:D
分析:因為static得方法在裝載class得時候首先完成,比 構造方法早,此時非static得屬性和方法還沒有完成初始化所以不能調用。
42.下列哪些語句關于內存回收的說法是正確的()(選擇一項)
A 程序員必須創建一個線程來釋放內存
B. 內存回收程序負責釋放無用內存
C. 內存回收程序允許程序員直接釋放內存
D. 內存回收程序可以在指定的時間釋放內存對象
答案:B
分析: A. 程序員不需要創建線程來釋放內存.
C. 也不允許程序員直接釋放內存.
D. 不一定在什么時刻執行垃圾回收.
43.選出合理的標識符()(選擇兩項)
A _sysl_111
B. 2 mail
C. $change
D. class
答案:AC
分析: 標識符的命令規范,可以包含字母、數字、下劃線、$,不能以數字開頭,不能是Java關鍵字
44.下列說法正確的是()(選擇多項)
A java.lang.Cloneable是類
B. java.langRunnable是接口
C. Double對象在java.lang包中
D. Double a=1.0是正確的java語句
Double a=1.0是正確的java語句
分析:java.lang.Cloneable是接口
45.定義一個類名為”MyClass.java”的類,并且該類可被一個工程中的所有類訪問,那么該類的正確聲明為()(選擇兩項)
A 45.定義一個類名為”MyClass.java”的類,并且該類可被一個工程中的所有類訪問,那么該類的正確聲明為()(選擇兩項)
B. class MyClass extends Object
C. public class MyClass
D. public class MyClass extends Object
答案:CD
分析: A 類的訪問權限只能是public或default
B使用默認訪問權限的類,只能在本包中訪問
46.面向對象的特征有哪些方面?請用生活中的例子來描述。

答: 面向對象的三大特征:封裝、繼承、多態。

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

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

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

后來,我又建了一個對象,叫人。

屬性:性別,年齡,職業,等級,血量

方法:逃跑,吃飯,睡覺,死。

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

戰士修改成—

屬性:戰斗力。

方法:戰斗。

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

而且我們還可以重載戰士.死的方法,簡稱重載死法。

我還建了一個對象—法師,父類也是人。

屬性:法力值

方法:施法,泡妞。

你看,用了繼承,創建對象變得更方便了。

再后來,我又建立了一個對象,叫怪物。

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

方法:戰斗,死。

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

屬性:毛色。

方法:賣萌,吃胡蘿卜。

47.說明內存泄漏和內存溢出的區別和聯系,結合項目經驗描述Java程序中如何檢測?如何解決?

答:

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

內存泄露 memory leak,是指程序在申請內存后,無法釋放已申請的內存空間,一次內存泄露危害可以忽略,但內存泄露堆積后果很嚴重,無論多少內存,遲早會被占光。

memory leak會最終會導致out of memory!

48.什么是Java的序列化,如何實現Java的序列化?列舉在哪些程序中見過Java序列化?

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

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

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

2) 在網絡上傳送對象的字節序列。

在很多應用中,需要對某些對象進行序列化,讓它們離開內存空間,入住物理硬盤,以便長期保存。比如最常見的是Web服務器中的Session對象,當有 10萬用戶并發訪問,就有可能出現10萬個Session對象,內存可能吃不消,于是Web容器就會把一些seesion先序列化到硬盤中,等要用了,再把保存在硬盤中的對象還原到內存中。

當兩個進程在進行遠程通信時,彼此可以發送各種類型的數據。無論是何種類型的數據,都會以二進制序列的形式在網絡上傳送。發送方需要把這個Java對象轉換為字節序列,才能在網絡上傳送;接收方則需要把字節序列再恢復為Java對象。

49.不通過構造函數也能創建對象嗎?

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

1、 用new語句創建對象,這是最常見的創建對象的方法。

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

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

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

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

50.匿名內部類可不可以繼承或實現接口。為什么?

答:匿名內部類是沒有名字的內部類,不能繼承其它類,但一個內部類可以作為一個接口,由另一個內部類實現.

1、由于匿名內部類沒有名字,所以它沒有構造函數。因為沒有構造函數,所以它必須完全借用父類的構造函數來實例化,換言之:匿名內部類完全把創建對象的任務交給了父類去完成。

2、在匿名內部類里創建新的方法沒有太大意義,但它可以通過覆蓋父類的方法達到神奇效果,如上例所示。這是多態性的體現。

3、因為匿名內部類沒有名字,所以無法進行向下的強制類型轉換,持有對一個匿名內部類對象引用的變量類型一定是它的直接或間接父類類型。

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

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

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

52.簡述Java中如何實現多態

實現多態有三個前提條件:

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

2、子類重寫父類的方法。(多態下會調用子類重寫后的方法)。

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

最后使用父類的引用變量調用子類重寫的方法即可實現多態。

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

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

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

55.Java中,如果Manager是Employee的子類,那么Pair是Pair的子類嗎?

不是,兩者沒有任何關聯;

Pair是單獨的類,只不過用不同類型的參數(泛型)進行了相應的實例化而已;所以,Pair< Manager>和Pair< Employee>不是子類的關系。

56.接口和抽象類的區別

56.接口和抽象類的區別

抽象類和接口均包含抽象方法,類必須實現所有的抽象方法,否則是抽象類

抽象類和接口都不能實例化,他們位于繼承樹的頂端,用來被其他類繼承和實現

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

語法方面的區別是比較低層次的,非本質的,主要表現在:

接口中只能定義全局靜態常量,不能定義變量。抽象類中可以定義常量和變量。

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

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

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

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

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

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

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

相同點:

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

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

區別:

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

58.靜態內部類和內部類有什么區別

靜態內部類不需要有指向外部類的引用。但非靜態內部類需要持有對外部類的引用。

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

非靜態內部類能夠訪問外部類的靜態和非靜態成員。靜態內部類不能訪問外部類的非靜態成員,只能訪問外部類的靜態成員。

實例化方式不同:

1) 靜態內部類:不依賴于外部類的實例,直接實例化內部類對象

2) 非靜態內部類:通過外部類的對象實例生成內部類對象

59.反射的概念與作用

反射的概念:

反射,一種計算機處理方式。是程序可以訪問、檢測和修改它本身狀態或行為的一種能力。

Java反射可以于運行時加載,探知和使用編譯期間完全未知的類.

程序在運行狀態中, 可以動態加載一個只有名稱的類, 對于任意一個已經加載的類,都能夠知道這個類的所有屬性和方法; 對于任意一個對象,都能調用他的任意一個方法和屬性;

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

java反射使得我們可以在程序運行時動態加載一個類,動態獲取類的基本信息和定義的方法,構造函數,域等。

除了檢閱類信息外,還可以動態創建類的實例,執行類實例的方法,獲取類實例的域值。反射使java這種靜態語言有了動態的特性。

反射的作用:

通過反射可以使程序代碼訪問裝載到JVM 中的類的內部信息

1) 獲取已裝載類的屬性信息

2) 獲取已裝載類的方法

3) 獲取已裝載類的構造方法信息

反射的優點:

增加程序的靈活性。

如struts中。請求的派發控制。

當請求來到時。struts通過查詢配置文件。找到該請求對應的action。已經方法。

然后通過反射實例化action。并調用響應method。

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

所以說,一個靈活,一個不靈活。

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

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

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

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

79.接口可否繼承接口?抽象類是否可實現接口?抽象類是否可繼承實體類?

接口可以繼承接口,抽象類可以實現接口,抽象類可以繼承實體類。

80.int與Integer有什么區別?

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

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

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

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

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

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

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

83.十進制數72轉換成八進制數是多少?

答: 110

84.Java程序中創建新的類對象,使用關鍵字new,回收無用的類對象使用關鍵字free正確么?

答:Java程序中創建新的類對象,使用關鍵字new是正確的; 回收無用的類對象使用關鍵字free是錯誤的.

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

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

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

86.在switch和if-else語句之間進行選取,當控制選擇的條件不僅僅依賴于一個x時,應該使用switch結構;正確么?

答:不正確。

通常情況下,進行比較判斷的處理,switch 和if-else可以互相轉換來寫;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.描述&和&&的區別。

&和&&的聯系(共同點):

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

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

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

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

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

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

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

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

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

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

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

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

88.使用final關鍵字修飾符一個變量時,是引用不能變,還是引用的對象不能變?

final修飾基本類型變量,其值不能改變。

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

例如:

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: 匹配一個數字字符。等價于[0-9]

\D: 匹配一個非數字字符。等價于[^0-9]

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

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

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

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

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

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

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

90.已知表達式int m[] = {0,1,2,3,4,5,6}; 下面那個表達式的值與數組的長度相等()
A m.length()
B. m.length
C. m.length()+1
D. m.length+1
答案:B
分析:數組的長度是.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需要強制類型轉換 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.下面哪個函數是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中,無論測試條件是什么,下列()循環將至少執行一次。
A for
B. do...while
C. while
D. while...do
答案:B
分析: ACD都不一定進行循環
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.解釋繼承、重載、覆蓋。

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

那么如何使用繼承呢?用extends關鍵字來繼承父類。

如上面A類與B類,當寫繼承語句時, class A類 extends B類{ } 其中A類是子類,B類是父類。

英文 位置不同 作用不同
重載 overload 同一個類中
在一個類里面為一種行為提供多種實現方式并提高可讀性
現方式并提高可讀性
重寫 override 子類和父類間
父類方法無法滿足子類的要求,子類通
過方法重寫滿足要求
101.什么是編譯型語言,什么是解釋型語言?java可以歸類到那種?

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

用編譯型語言寫的程序執行之前,需要一個專門的編譯過程,通過編譯系統把高級語言翻譯成機器語言,把源高級程序編譯成為機器語言文件,比如windows下的exe文件。以后就可以直接運行而不需要編譯了,因為翻譯只做了一次,運行時不需要翻譯,所以一般而言,編譯型語言的程序執行效率高。

解釋型語言在運行的時候才翻譯,比如VB語言,在執行的時候,專門有一個解釋器能夠將VB語言翻譯成機器語言,每個語句都是執行時才翻譯。這樣解釋型語言每執行一次就要翻譯一次,效率比較低。

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

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

102.簡述操作符(&,|)與操作符(&&,||)的區別&和&&的聯系(共同點)

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

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

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

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

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

&和&&的區別(不同點):

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

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

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

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

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

|和||的區別和聯系與&和&&的區別和聯系類似

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

在異常處理時提供 finally 塊來執行任何清除操作。

如果有finally的話,則不管是否發生異常,finally語句都會被執行,包括遇到return語句。

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

104.有一段java應用程序,它的主類名是al,那么保存它的源文件可以是?()
A al.java
B. al.class
C. al
D. 都對
答案:A
分析:.class是java的解析文件
105.Java類可以作為()
A 類型定義機制
B. 數據封裝機制
C. 類型定義機制和數據封裝機制
D. 上述都不對
答案:C
106.在調用方法時,若要使方法改變實參的值,可以?()
A 用基本數據類型作為參數
B. 用對象作為參數
C. A和B都對
D. A和B都不對
答案:B
分析:基本數據類型不能改變實參的值
107.Java語言具有許多優點和特點,哪個反映了java程序并行機制的()
A 安全性
B. 多線性
C. 跨平臺
D. 可移植
可移植
108.下關于構造函數的描述錯誤是()
A 構造函數的返回類型只能是void型
B. 構造函數是類的一種特殊函數,它的方法名必須與類名相同
C. 構造函數的主要作用是完成對類的對象的初始化工作
D. 一般在創建新對象時,系統會自動調用構造函數
答案:A
分析:構造函數的名字與類的名字相同,并且不能指定返回類型。
109.若需要定義一個類域或類方法,應使用哪種修飾符?()
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()直接訪問()
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.下面哪幾個函數是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.請問以下代碼執行會打印出什么?

父類:

package com.bjsxt;

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

子類:

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.如果有兩個類A、B(注意不是接口),你想同時使用這兩個類的功能,那么你會如何編寫這個C類呢?

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

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

答:構造方法可以被重載,但是構造方法不能被重寫,子類也不能繼承到父類的構造方法

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

答:范圍是-128至127

117.如何將日期類型格式化為: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.不通過構造函數也能創建對象嗎()
A.
B.
分析:答案:A
Java創建對象的幾種方式(重要):
(1) 用new語句創建對象,這是最常見的創建對象的方法。
(2) 運用反射手段,調用java.lang.Class或者
java.lang.reflect.Constructor類的newInstance()實例方法。
(3) 調用對象的clone()方法
(4) 運用反序列化手段,調用java.io.ObjectInputStream對象的 readObject()方法。
(1)和(2)都會明確的顯式的調用構造函數 ;(3)是在內存上對已有對象的影印,所以不會調用構造函數 ;(4)是從文件中還原類的對象,也不會調用構造函數。
(1)和(2)都會明確的顯式的調用構造函數 ;(3)是在內存上對已有對象的影印,所以不會調用構造函數 ;(4)是從文件中還原類的對象,也不會調用構造函數。
119.下面哪些是對稱加密算法()

A. DES
B. MD5
C. DSA
D. RSA
分析:答案:A
分析:常用的對稱加密算法有:DES、3DES、RC2、RC4、AES
常用的非對稱加密算法有:RSA、DSA、ECC
使用單向散列函數的加密算法:MD5、SHA
120.下面的代碼段,當輸入為2的時候返回值是()
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代碼段會產生幾個對象
publicvoid test(){
String a="a";
String b="b";
String c="c";
c=a+""+b+""+c;
System.out.print(c);
}

分析:答案: 一個對象,因為編譯期進行了優化,3個字符串常量直接折疊為一個

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

答案: -11

分析:小數點后第一位=5

正數:Math.round(11.5)=12

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

小數點后第一位<5

正數:Math.round(11.46)=11

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

小數點后第一位>5

正數:Math.round(11.68)=12

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

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

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

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

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

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

123.十進制數278的對應十六進制數

分析:十進制數278的對應十六進制數是116

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

分析:

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

2: 1 byte = 8 bit ;

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

short 2個字節

int 4個字節

long 8個字節

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

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

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

1、兩個變量的生命周期不同。

成員變量隨著對象的創建而存在,隨著對象的被回收而釋放。

靜態變量隨著類的加載而存在,隨著類的消失而消失。

2、調用方式不同。

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

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

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

類名調用 :Person.country

3、別名不同。

成員變量也稱為實例變量。

靜態變量稱為類變量。?

4、數據存儲位置不同。

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

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

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

1、用final修飾的類不能被擴展,也就是說不可能有子類;

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

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

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

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

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

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

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

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

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

⑥ 局部變量在其值被訪問之前必須被明確賦值;

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

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

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

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

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

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

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

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

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

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

137.Java 有沒有goto?

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

138.int 和Integer 有什么區別?

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

Java 為每個原始類型提供了包裝類型:

原始類型: boolean,char,byte,short,int,long,float,double

包裝類型: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自動裝箱成Integer類型
        int c = 3;
        System.out.println(a == b); // false 兩個引用沒有引用同一對象
        System.out.println(a == c); // true a自動拆箱成int類型再和c比較
    }
}

補充:最近還遇到一個面試題,也是和自動裝箱和拆箱相關的,代碼如下所示:

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);
    }
}

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

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的內部類,其代碼如下所示:

/* 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() {}
}

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

139.&和&&的區別?

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

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

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

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

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

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

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

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

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

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 中,如何跳出當前的多重嵌套循環?

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

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

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

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

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

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

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

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

補充:Java中沒有傳引用實在是非常的不方便,這一點在Java 8中仍然沒有得到改進,正是如此在Java編寫的代碼中才會出現大量的Wrapper類(將需要通過方法調用修改的引用置于一個Wrapper類中,再將Wrapper對象傳入方法),這樣的做法只會讓代碼變得臃腫,尤其是讓從C和C++轉型為Java程序員的開發者無法容忍。

147.重載(Overload)和重寫(Override)的區別。重載的方法能否根據返回類型進行區分?

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

148.華為的面試題中曾經問過這樣一個問題:為什么不能根據返回類型來區分重載,為什么?

答:方法的重載,即使返回值類型不同,也不能改變實現功能相同或類似這一既定事實;同時方法的重載只是要求兩同三不同,即在同一個類中,相同的方法名稱,參數列表當中的參數類型、個數、順序不同;跟權限修飾符和返回值類無關

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

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

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

        public class Inner1  //在方法體外面定義的內部類
        {
        }

}

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

Outer outer = new Outer();

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

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

對于這些細節,只要在eclipse寫代碼試試,根據開發工具提示的各類錯誤信息就可以馬上了解到。

在方法體內部還可以采用如下語法來創建一種匿名內部類,即定義某一接口或類的子類的同時,還創建了該子類的實例對象,無需為該子類定義名稱:

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

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

Outer.Inner inner = newOuter.Inner();

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

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

備注:首先根據你的印象說出你對內部類的總體方面的特點:例如,在兩個地方可以定義,可以訪問外部類的成員變量,不能定義靜態成員,這是大的特點。然后再說一些細節方面的知識,例如,幾種定義方式的語法區別,靜態內部類,以及匿名內部類。

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

package com.bjsxt;
/**
* 撲克類(一副撲克)
  * @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;
        }
    }
     /**
     * 發牌
     * @param index 發牌的位置
     */
    public Card deal(int index) {
        return cards[index];
    }

    /**
     * 卡片類(一張撲克)
     * [內部類]
     * @author sxt
     */
    public class Card {
  private String suite;   // 花色
        private int face;       // 點數
  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;
        }
    }
}

測試類:

package com.bjsxt;

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

答:都不能。抽象方法需要子類重寫,而靜態的方法是無法被重寫的,因此二者是矛盾的。本地方法是由本地代碼(如C代碼)實現的方法,而抽象方法是沒有實現的,也是矛盾的。synchronized和方法的實現細節有關,抽象方法不涉及實現細節,因此也是相互矛盾的。

151.靜態變量和實例變量的區別?

答:靜態變量是被static修飾符修飾的變量,也稱為類變量,它屬于類,不屬于類的任何一個對象,一個類不管創建多少個對象,靜態變量在內存中有且僅有一個拷貝;實例變量必須依存于某一實例,需要先創建對象然后通過對象才能訪問到它,靜態變量可以實現讓多個對象共享內存。兩者的相同點:都有默認值而且在類的任何地方都可以調用。在Java開發中,上下文類和工具類中通常會有大量的靜態成員。?

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

答:不可以,靜態方法只能訪問靜態成員,因為非靜態方法的調用要先創建對象,因此在調用靜態方法時可能對象并沒有被初始化。?

153.如何實現對象克???
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();
        // 說明:調用ByteArrayInputStream或ByteArrayOutputStream對象的close方法沒有任何意義
        // 這兩個基于內存的流只要垃圾回收器清理對象就能夠釋放資源
}
}

答:有兩種方式:

1.實現Cloneable接口并重寫Object類中的clone()方法;

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

下面是測試代碼:

package com.bjsxt;
import java.io.Serializable;
/**
 * 人類
 * @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 + "]";
    }
  }
  /**
 * 小汽車類
 * @author sxt
*/
class Car implements Serializable {
    private static final long serialVersionUID = -5713945027627603702L;
    private String brand;       // 品牌
    private int maxSpeed;       // 最高時速

    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關聯的汽車對象的品牌屬性
            // 原來的Person對象p1關聯的汽車不會受到任何影響
            // 因為在克隆Person對象時其關聯的汽車對象也被克隆了
            System.out.println(p1);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

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

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

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

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

只有記住抽象類與普通類的唯一區別就是不能創建實例對象和允許有abstract方法。?

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

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

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

答:可以繼承其他類或實現其他接口,在Swing編程中常用此方式來實現事件監聽和回調。?但是有一點需要注意,它只能繼承一個類或一個接口。

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

答:一個內部類對象可以訪問創建它的外部類對象的成員,包括私有成員。如果要訪問外部類的局部變量,此時局部變量必須使用final修飾,否則無法訪問。

158.Java 中的final關鍵字有哪些用法?

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

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

(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。創建對象時構造器的調用順序是:先初始化靜態成員,然后調用父類構造器,再初始化非靜態成員,最后調用自身構造器。?

考點:靜態代碼塊優先級 > 構造方法的優先級如果再加一個普通代碼塊,優先順序如下:靜態代碼塊>普通代碼塊>構造方法

160.說說數據類型之間的轉換:

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

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

答:

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

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

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

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

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類的構造方法當中,存在一個字符集設置的方法,具體如下:

163.Java中的日期和時間:

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

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

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

4 ) 如何格式化日期?

答:操作方法如下所示:

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

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

Calendar.getInstance().getTimeInMillis();

time.getActualMaximum(Calendar.DAY_OF_MONTH);

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

164.打印昨天的當前時刻。
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反射技術主要實現類有哪些,作用分別是什么?

在JDK中,主要由以下類來實現Java反射機制,這些類都位于java.lang.reflect包中

1)Class類:代表一個類

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

3)Method類:代表類的成員方法

4)Constructor 類:代表類的構造方法

5)Array類:提供了動態創建數組,以及訪問數組的元素的靜態方法

166.Class類的作用?生成Class對象的方法有哪些?

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

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

方 法
示 例
對象名
.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");
類名.class
類名.class
Class c2 = Student.class;
Class c2 = int.class
包裝類.TYPE
包裝類.TYPE
Class c2 = Boolean.TYPE;
167.反射的使用場合和作用、及其優缺點

1)使用場合

在編譯時根本無法知道該對象或類可能屬于哪些類,程序只依靠運行時信息來發現該對象和類的真實信息。

2)主要作用

通過反射可以使程序代碼訪問裝載到JVM 中的類的內部信息,獲取已裝載類的屬性信息,獲取已裝載類的方法,獲取已裝載類的構造方法信息

3)反射的優點

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

4) Java反射技術應用領域很廣,如軟件測試等;許多流行的開源框架例如Struts、Hibernate、Spring在實現過程中都采用了該技術

5)反射的缺點

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

使用反射會模糊程序內部邏輯:程序人員希望在源代碼中看到程序的邏輯,反射等繞過了源代碼的技術,因而會帶來維護問題。反射代碼比相應的直接代碼更復雜。

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

面向對象設計原則是面向對象設計的基石,面向對象設計質量的依據和保障,設計模式是面向對象設計原則的經典應用

1)單一職責原則SRP

2)開閉原則OCP

3)里氏替代原則LSP

4)依賴注入原則DIP

5)接口分離原則ISP

6)迪米特原則LOD

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

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

String相關:

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

String str2=new String("hello");

System.out.println(str1==str2);
A. true
B. false
C. hello
D. he
答案:B
分析:str1沒有使用new關鍵字,在堆中沒有開辟空間,其值”hello”在常量池中,str2使用new關鍵字創建了一個對象,在堆中開辟了空間,”==”比較的是對象的引用,即內存地址,所以str1與str2兩個對象的內存地址是不相同的
170.Java語言中,String類中的indexOf()方法返回值的類型是()
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
分析:在方法調用時,在change方法中對str的值進行修改,是將str指向了常量江池中的”test ok”,而主方法中的ex.str仍然指向的是常量池中的”good”。字符型數組在方法調用時,將主方法中ex.ch的引用傳遞給change方法中的ch,指向是堆中的同一堆空間,所以修改ch[0]的時候,ex.ch可以看到相同的修改后的結果。
172.執行下列代碼后,哪個結論是正確的()(選擇兩項)

String[] s=new String[10];

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

思路說明:replaceAll方法的本質是使用正則表達式進行匹配,最終調用的其實是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.在“=”后填寫適當的內容:

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類?

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

public final class String implements java.io.Serializable,

Comparable< String>, CharSequence

176.給定兩個字符串s和t, 寫一個函數來決定是否t是s的重組詞。你可以假設字符串只包含小寫字母。
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”);創建了幾個String對象。

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

178.輸出結果?
String str1=“hello”;
Sring str2=“he”+new String(“llo”);
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.關于java.lang.String類,以下描述正確的一項是()
A. String類是final類故不可繼承
B. String類final類故可以繼承
C. String類不是final類故不可繼承
D. String;類不是final類故可以繼承
答案:A
181.下面哪個是正確的()
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類型
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.寫一個方法,實現字符串的反轉,如:輸入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.編寫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 是最基本的數據類型嗎?

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

187.String 和StringBuilder、StringBuffer 的區別?

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

相同點:

它們都可以儲存和操作字符串,同時三者都使用final修飾,都屬于終結類不能派生子類,操作的相關方法也類似例如獲取字符串長度等;

不同點:

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

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

補充2:下面也是一個面試題,問程序的輸出,看看自己能不能說出正確答案。

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類存在intern()方法,含義如下:返回字符串對象的規范化表示形式。它遵循以下規則:對于任意兩個字符串 s 和 t,當且僅當 s.equals(t) 為 true 時,s.intern()?==?t.intern() 才為 true。

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

結果如下:

a == b-->false

a == c-->true

a.equals(b)-->true

a.equals(c)-->true

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

188.String類為什么是final的

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

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

189.String類型是基本數據類型嗎?基本數據類型有哪些

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

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

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

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

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

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

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

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

而非

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

后者每次都會調用構造器,生成新對象,性能低下且內存開銷大,并且沒有意義,因為String對象不可改變,所以對于內容相同的字符串,只要一個String對象來表示就可以了。也就說,多次調用上面的構造器創建多個對象,他們的String類型屬性s都指向同一個對象。

上面的結論還基于這樣一個事實:對于字符串常量,如果內容相同,Java認為它們代表同一個String對象。而用關鍵字new調用構造器,總是會創建一個新的對象,無論內容是否相同。

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

191.String s = new String("xyz");創建幾個String Object?

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

192.下面這條語句一共創建了多少個對象: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");

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

題目中的第一行代碼被編譯器在編譯時優化后,相當于直接定義一個”abcd”的字符串,所以,上面的代碼應該只創建了一個String對象。

寫如下兩行代碼,

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

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

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

集合:

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

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

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

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

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

194.Vector和ArrayList的區別和聯系

相同點:

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

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

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

不同點:

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

2)Vector線程安全,ArrayList重速度輕安全,線程非安全長度需增長時,Vector默認增長一倍,ArrayList增長50%

195.ArrayList和LinkedList的區別和聯系

相同點:

兩者都實現了List接口,都具有List中元素有序、不唯一的特點。

不同點:

ArrayList實現了長度可變的數組,在內存中分配連續空間。遍歷元素和隨機訪問元素的效率比較高;

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

196.HashMap和Hashtable的區別和聯系

相同點:

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

不同點:

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

2、Hashtable繼承Dictionary類,HashMap實現Map接口

3、Hashtable線程安全,HashMap線程非安全

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

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

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

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

3)系統類已經覆蓋了hashCode方法 自定義類如果要放入hash類集合,必須重寫hashcode。如果不重寫,調用的是Object的hashcode,而Object的hashCode實際上是地址。

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

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

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

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

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

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

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

4)可創建Comparator接口實現類來指定比較策略,并通過TreeSet構造方法參數傳入。這種方式尤其對系統類非常適用。

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

數組不是面向對象的,存在明顯的缺陷,集合完全彌補了數組的一些缺點,比數組更靈活更實用,可大大提高軟件的開發效率而且不同的集合框架類可適用于不同場合。具體如下:

1)數組的效率高于集合類.

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

3)數組容量固定且無法動態改變,集合類容量動態改變。

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

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

6)集合以類的形式存在,具有封裝、繼承、多態等類的特性,通過簡單的方法和屬性調用即可實現各種復雜操作,大大提高軟件的開發效率。

200.Collection和Collections的區別

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

2)Java中還有一個Collections類,專門用來操作集合類 ,它提供一系列靜態方法實現對各種集合的搜索、排序、線程安全化等操作。

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

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

兩者的主要區別如下

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

2、Hashtable繼承Dictionary類,HashMap實現Map接口

3、Hashtable線程安全,HashMap線程非安全

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

HashSet與HashMap的區別

1、HashSet底層是采用HashMap實現的。HashSet 的實現比較簡單,HashSet 的絕大部分方法都是通過調用 HashMap 的方法來實現的,因此 HashSet 和 HashMap 兩個集合在實現本質上是相同的。

2、HashMap的key就是放進HashSet中對象,value是Object類型的。

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

203.列出Java中的集合類層次結構?

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

圖中:虛線框中為接口,實線框中為類。

204.List,Set,Map各有什么特點

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

Set 接口存儲一組唯一,無序的對象。

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

205.ArrayList list=new ArrayList(20);中的list擴充幾次()
A. 0
B. 1
C. 2
D. 3
答案:A
分析:已經指定了長度, 所以不擴容
206.List、Set、Map哪個繼承自Collection接口,一下說法正確的是()
A. List Map
B. Set Map
C. List Set
D. List Map Set
答案:C
分析:Map接口繼承了java.lang.Object類,但沒有實現任何接口.
207.合并兩個有序的鏈表
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.用遞歸方式實現鏈表的轉置。
/**
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.給定一個不包含相同元素的整數集合,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>());  //最后加上一個空集
        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是以整數為元素的動態數組,而res是以數組為元素的數組,在這一步,當item增加完元素后,item所有元素構成一個完整的子串,再由res納入
            res.add(new ArrayList<Integer>(item));
            dfs(nums, i + 1, item, res);
            item.remove(item.size() - 1);
        }
    }
}
210.以下結構中,哪個具有同步功能()
A. HashMap
B. ConcurrentHashMap
C. WeakHashMap
D. TreeMap
答案:B
分析:
A,C,D都線程不安全,B線程安全,具有同步功能
211.以下結構中,插入性能最高的是()
A. ArrayList
B. Linkedlist
C. tor
D. Collection
答案:B
分析:
數組插入、刪除效率差,排除A
tor不是java里面的數據結構,是一種網絡路由技術;因此排除C
Collection 是集合的接口,不是某種數據結構;因此排除D
212.以下結構中,哪個最適合當作stack使用()
A. LinkedHashMap
B. LinkedHashSet
C. LinkedList
LinkedList
分析:
Stack是先進后出的線性結構;所以鏈表比較合適;不需要散列表的數據結構
213.Map的實現類中,哪些是有序的,哪些是無序的,有序的是如何保證其有序性,你覺得哪個有序性性能更高,你有沒有更好或者更高效的實現方式?

答:1. Map的實現類有HashMap,LinkedHashMap,TreeMap

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

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

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

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

214.下面的代碼在絕大部分時間內都運行得很正常,請問什么情況下會出現問題?根源在哪里?
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在排序時如何比較元素?Collections工具類中的sort()方法如何比較元素?

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

216.List里面如何剔除相同的對象?請簡單用代碼實現一種方法
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中數據取出來來存到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的實現類有

分析:Java中的java.util.Map的實現類

1、HashMap

2、Hashtable

3、LinkedHashMap

4、TreeMap

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

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

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

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

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

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

221.List、Map、Set 三個接口,存取元素時,各有什么特點?

答:List以特定索引來存取元素,可有重復元素。

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

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

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

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

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

例子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的鉆石語法(構造器后面的尖括號中不需要寫類型)
        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;
    }
    /**
     * 獲取學生姓名
     */
    public String getName() {
        return name;
    }
    /**
     * 獲取學生年齡
     */
    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的鉆石語法(構造器后面的尖括號中不需要寫類型)
        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));

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

        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]
    }
}

多線程:

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
分析:啟動線程需要調用start()方法,而t.run()方法,則是使用對象名.分析:啟動線程需要調用start()方法,而t.run()方法,則是使用對象名.
224.下列哪個方法可用于創建一個可運行的類()
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和實現Runable接口
225.說明類java.lang.ThreadLocal的作用和原理。列舉在哪些程序中見過ThreadLocal的使用?

作用:

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

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

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

ThreadLocal的原理

ThreadLocal是如何做到為每一個線程維護變量的副本的呢?其實實現的思路很簡單,在ThreadLocal類中有一個Map,用于存儲每一個線程的變量的副本。

226.說說樂觀鎖與悲觀鎖

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

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

兩種鎖各有優缺點,不可認為一種好于另一種,像樂觀鎖適用于寫比較少的情況下,即沖突真的很少發生的時候,這樣可以省去了鎖的開銷,加大了系統的整個吞吐量。但如果經常產生沖突,上層應用會不斷的進行retry,這樣反倒是降低了性能,所以這種情況下用悲觀鎖就比較合適。

227.在Java中怎么實現多線程?描述線程狀態的變化過程。

答:當多個線程訪問同一個數據時,容易出現線程安全問題,需要某種方式來確保資源在某一時刻只被一個線程使用。需要讓線程同步,保證數據安全線程同步的實現方案: 同步代碼塊和同步方法,均需要使用synchronized關鍵字

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

synchronized (acct) { }

}

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

線程同步的好處:解決了線程安全問題

線程同步的缺點:性能下降,可能會帶來死鎖

228.請寫出多線程代碼使用Thread或者Runnable,并說出兩種的區別。

方式1:繼承Java.lang.Thread類,并覆蓋run() 方法。優勢:編寫簡單;劣勢:無法繼承其它父類

public class ThreadDemo1 {
public static void main(String args[]) {
MyThread1 t = new MyThread1();
t.start();
while (true) {
System.out.println("兔子領先了,別驕傲");
}
}
}
class MyThread1 extends Thread {
public void run() {
while (true) {
System.out.println("烏龜領先了,加油");
}
}
}

方式2:實現Java.lang.Runnable接口,并實現run()方法。優勢:可繼承其它類,多線程可共享同一個Thread對象;劣勢:編程方式稍微復雜,如需訪問當前線程,需調用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("兔子領先了,加油");
}
}
}
class MyThread2 implements Runnable {
public void run() {
while (true) {
System.out.println("烏龜超過了,再接再厲");
}
}
}
229.在多線程編程里,wait方法的調用方式是怎樣的?

答:wait方法是線程通信的方法之一,必須用在 synchronized方法或者synchronized代碼塊中,否則會拋出異常,這就涉及到一個“鎖”的概念,而wait方法必須使用上鎖的對象來調用,從而持有該對象的鎖進入線程等待狀態,直到使用該上鎖的對象調用notify或者notifyAll方法來喚醒之前進入等待的線程,以釋放持有的鎖。

230.Java線程的幾種狀態

答:線程是一個動態執行的過程,它有一個從產生到死亡的過程,共五種狀態:

新建(new Thread)

當創建Thread類的一個實例(對象)時,此線程進入新建狀態(未被啟動)

例如:Thread t1=new Thread();

就緒(runnable)

線程已經被啟動,正在等待被分配給CPU時間片,也就是說此時線程正在就緒隊列中排隊等候得到CPU資源。例如:t1.start();

運行(running)

線程獲得CPU資源正在執行任務(run()方法),此時除非此線程自動放棄CPU資源或者有優先級更高的線程進入,線程將一直運行到結束。

死亡(dead)

當線程執行完畢或被其它線程殺死,線程就進入死亡狀態,這時線程不可能再進入就緒狀態等待執行。

自然終止:正常運行run()方法后終止

異常終止:調用stop()方法讓一個線程終止運行

堵塞(blocked)

由于某種原因導致正在運行的線程讓出CPU并暫停自己的執行,即進入堵塞狀態。

正在睡眠:用sleep(long t) 方法可使線程進入睡眠方式。一個睡眠著的線程在指定的時間過去可進入就緒狀態。

正在等待:調用wait()方法。(調用motify()方法回到就緒狀態)

被另一個線程所阻塞:調用suspend()方法。(調用resume()方法恢復)

231.在Java多線程中,請用下面哪種方式不會使線程進入阻塞狀態()
A. sleep()
B. Suspend()
C. wait()
D. yield()
答案:D
分析:yield會是線程進入就緒狀態
232.volatile關鍵字是否能保證線程安全?

答:不能。雖然volatile提供了同步的機制,但是知識一種弱的同步機制,如需要強線程安全,還需要使用synchronized。

Java語言提供了一種稍弱的同步機制,即volatile變量,用來確保將變量的更新操作通知到其他線程。當把變量聲明為volatile類型后,編譯器與運行時都會注意到這個變量是共享的,因此不會將該變量上的操作與其他內存操作一起重排序。volatile變量不會被緩存在寄存器或者對其他處理器不可見的地方,因此在讀取volatile類型的變量時總會返回最新寫入的值。

一、volatile的內存語義是:

當寫一個volatile變量時,JMM會把該線程對應的本地內存中的共享變量值立即刷新到主內存中。

當讀一個volatile變量時,JMM會把該線程對應的本地內存設置為無效,直接從主內存中讀取共享變量。

二、volatile底層的實現機制

如果把加入volatile關鍵字的代碼和未加入volatile關鍵字的代碼都生成匯編代碼,會發現加入volatile關鍵字的代碼會多出一個lock前綴指令。

1 、重排序時不能把后面的指令重排序到內存屏障之前的位置

2、使得本CPU的Cache寫入內存

3、寫入動作也會引起別的CPU或者別的內核無效化其Cache,相當于讓新寫入的值對別的線程可見。

233.請寫出常用的Java多線程啟動方式,Executors線程池有幾種常用類型?

(1) 繼承Thread類

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) 實現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的靜態方法可以創建三種類型的常用線程池:

1)FixedThreadPool這個線程池可以創建固定線程數的線程池。

2)SingleThreadExecutor是使用單個worker線程的Executor。

3)CachedThreadPool是一個”無限“容量的線程池,它會根據需要創建新線程。

234.關于sleep()和wait(),以下描述錯誤的一項是()
A. sleep是線程類(Thread)的方法,wait是Object類的方法
B. Sleep不釋放對象鎖,wait放棄對象鎖
C. Sleep暫停線程、但監控狀態任然保持,結束后會自動恢復
D. Wait后進入等待鎖定池,只針對此對象發出notify方法后獲取對象鎖進入運行狀態。
答案:D
分析:針對此對象的notify方法后獲取對象鎖并進入就緒狀態,而不是運行狀態。另外針對此對象的notifyAll方法后也可能獲取對象鎖并進入就緒狀態,而不是運行狀態
235.進程和線程的區別是什么?

進程是具有一定獨立功能的程序關于某個數據集合上的一次運行活動,進程是系統進行資源分配和調度的一個獨立單位.

線程是進程的一個實體,是CPU調度和分派的基本單位,它是比進程更小的能獨立運行的基本單位.線程自己基本上不擁有系統資源,只擁有一點在運行中必不可少的資源(如程序計數器,一組寄存器和棧),但是它可與同屬一個進程的其他的線程共享進程所擁有的全部資源.

區別 進程 線程
根本區別? 作為資源分配的單位? 調度和執行的單位
開銷? 每個進程都有獨立的代碼和數據空間(進程上下文),進程間的切換會有較大的開銷。? 線程可以看成時輕量級的進程,同一類線程共享代碼和數據空間,每個線程有獨立的運行棧和程序計數器(PC),線程切換的開銷小。?
所處環境? 系統在運行的時候會為每個進程分配不同的內存區域? 除了CPU之外,不會為線程分配內存(線程所使用的資源是它所屬的進程的資源),線程組只能共享資源?
分配內存? 系統在運行的時候會為每個進程分配不同的內存區域? 除了CPU之外,不會為線程分配內存(線程所使用的資源是它所屬的進程的資源),線程組只能共享資源?
包含關系? 沒有線程的進程是可以被看作單線程的,如果一個進程內擁有多個線程,則執行過程不是一條線的,而是多條線(線程)共同完成的。? 線程是進程的一部分,所以線程有的時候被稱為是輕權進程或者輕量級進程。?
236.以下鎖機機制中,不能保證線程安全的是()
A. Lock
B. Synchronized
C. Volatile
答案:C
237.創建n多個線程,如何保證這些線程同時啟動?看清,是“同時”。

答:用一個for循環創建線程對象,同時調用wait()方法,讓所有線程等待;直到最后一個線程也準備就緒后,調用notifyAll(), 同時啟動所有線程。

比如:給你n個賽車,讓他們都在起跑線上就緒后,同時出發,Java多線程如何寫代碼?

思路是,來一輛賽車就加上一把鎖,并修改對應的操作數,如果沒有全部就緒就等待,并釋放鎖,直到最后一輛賽車到場后喚醒所有的賽車線程。代碼參考如下:

public class CarCompetion {
    // 參賽賽車的數量
    protected final int totalCarNum = 10;
    // 當前在起跑線的賽車數量
    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.如果數據將在線程間共享。例如正在寫的數據以后可能被另一個線程讀到,或者正在讀的數據可能已經被另一個線程寫過了,那么這些數據就是共享數據,必須進行同步存取。

2.當應用程序在對象上調用了一個需要花費很長時間來執行的方法,并且不希望讓程序等待方法的返回時,就應該使用異步編程,在很多情況下采用異步途徑往往更有效率。

3.舉個例子: 打電話是同步 發消息是異步

239.Java線程中,sleep()和wait()區別

答:sleep是線程類(Thread)的方法;作用是導致此線程暫停執行指定時間,給執行機會給其他線程,但是監控狀態依然保持,到時后會自動恢復;調用sleep()不會釋放對象鎖。

wait是Object類的方法;對此對象調用wait方法導致本線程放棄對象鎖,進入等 待此對象的等待鎖定池。只有針對此對象發出notify方法(或notifyAll)后本線程才進入對象鎖定池,準備獲得對象鎖進行運行狀態。

240.下面所述步驟中,是創建進程做必須的步驟是()
A. 由調度程序為進程分配CPU
B. 建立一個進程控制塊
C. 為進程分配內存
D. 為進程分配文件描述符
答案:BC
241.無鎖化編程有哪些常見方法?()
A. 針對計數器,可以使用原子加
B. 只有一個生產者和一個消費者,那么就可以做到免鎖訪問環形緩沖區(Ring Buffer)
C. RCU(Read-Copy-Update),新舊副本切換機制,對于舊副本可以采用延遲釋放的做法
D. CAS(Compare-and-Swap),如無鎖棧,無鎖隊列等待
答案:D
分析:A 這方法雖然不太好,但是常見
B ProducerConsumerQueue就是這個,到處都是
C linux kernel里面大量使用
D 本質上其實就是樂觀鎖,操作起來很困難。。單生產者多消費者或者多生產者單消費者的情況下比較常見,也不容易遇到ABA問題。
242.sleep()和yield()有什么區別?

答:① sleep()方法給其他線程運行機會時不考慮線程的優先級,因此會給低優先級的線程以運行的機會;yield()方法只會給相同優先級或更高優先級的線程以運行的機會;

② 線程執行sleep()方法后轉入阻塞(blocked)狀態,而執行yield()方法后轉入就緒(ready)狀態;

③ sleep()方法聲明拋出InterruptedException,而yield()方法沒有聲明任何異常;

④ sleep()方法比yield()方法(跟操作系統相關)具有更好的可移植性。?

243.當一個線程進入一個對象的synchronized方法A之后,其它線程是否可進入此對象的synchronized方法?

答:不能。其它線程只能訪問該對象的非同步方法,同步方法則不能進入。?只有等待當前線程執行完畢釋放鎖資源之后,其他線程才有可能進行執行該同步方法!

延伸 對象鎖分為三種:共享資源、this、當前類的字節碼文件對象

244.請說出與線程同步相關的方法。

答:1. wait():使一個線程處于等待(阻塞)狀態,并且釋放所持有的對象的鎖;

2. sleep():使一個正在運行的線程處于睡眠狀態,是一個靜態方法,調用此方法要捕捉InterruptedException 異常;

3. notify():喚醒一個處于等待狀態的線程,當然在調用此方法的時候,并不能確切的喚醒某一個等待狀態的線程,而是由JVM確定喚醒哪個線程,而且與優先級無關;

4. notityAll():喚醒所有處入等待狀態的線程,注意并不是給所有喚醒線程一個對象的鎖,而是讓它們競爭;

5. JDK 1.5通過Lock接口提供了顯式(explicit)的鎖機制,增強了靈活性以及對線程的協調。Lock接口中定義了加鎖(lock())和解鎖(unlock())的方法,同時還提供了newCondition()方法來產生用于線程之間通信的Condition對象;

6. JDK 1.5還提供了信號量(semaphore)機制,信號量可以用來限制對某個共享資源進行訪問的線程的數量。在對資源進行訪問之前,線程必須得到信號量的許可(調用Semaphore對象的acquire()方法);在完成對資源的訪問后,線程必須向信號量歸還許可(調用Semaphore對象的release()方法)。

下面的例子演示了100個線程同時向一個銀行賬戶中存入1元錢,在沒有使用同步機制和使用同步機制情況下的執行情況。

銀行賬戶類:

package com.bjsxt;
/**
 * 銀行賬戶
 * @author sxt
 *
 */
public class Account {
    private double balance;     // 賬戶余額
    /**
     * 存款
     * @param money 存入金額
     */
    public void deposit(double money) {
        double newBalance = balance + money;
        try {
            Thread.sleep(10);   // 模擬此業務需要一段處理時間
        }
        catch(InterruptedException ex) {
            ex.printStackTrace();
        }
        balance = newBalance;
    }
    /**
     * 獲得賬戶余額
     */
    public double getBalance() {
        return balance;
    }
}

存錢線程類:

package com.bjsxt;
/**
 * 存錢線程
 * @author sxt李端陽
 *
 */
public class AddMoneyThread implements Runnable {
    private Account account;    // 存入賬戶
    private double money;       // 存入金額

    public AddMoneyThread(Account account, double money) {
        this.account = account;
        this.money = money;
    }

    @Override
    public void run() {
        account.deposit(money);
    }
 }

測試類:

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("賬戶余額: " + account.getBalance());
    }
}

在沒有同步的情況下,執行結果通常是顯示賬戶余額在10元以下,出現這種狀況的原因是,當一個線程A試圖存入1元的時候,另外一個線程B也能夠進入存款的方法中,線程B讀取到的賬戶余額仍然是線程A存入1元錢之前的賬戶余額,因此也是在原來的余額0上面做了加1元的操作,同理線程C也會做類似的事情,所以最后100個線程執行結束時,本來期望賬戶余額為100元,但實際得到的通常在10元以下。解決這個問題的辦法就是同步,當一個線程對銀行賬戶存錢時,需要將此賬戶鎖定,待其操作完成后才允許其他的線程進行操作,代碼有如下幾種調整方案:

1. 在銀行賬戶的存款(deposit)方法上同步(synchronized)關鍵字

package com.bjsxt;
/**
 * 銀行賬戶
 * @author SXT李端陽
*/
public class Account {
    private double balance;     // 賬戶余額
    /**
     * 存款
     * @param money 存入金額
     */
    public synchronized void deposit(double money) {
        double newBalance = balance + money;
        try {
            Thread.sleep(10);   // 模擬此業務需要一段處理時間
        }
        catch(InterruptedException ex) {
            ex.printStackTrace();
        }
        balance = newBalance;
    }

    /**
     * 獲得賬戶余額
     */
    public double getBalance() {
        return balance;
    }
}

2. 在線程調用存款方法時對銀行賬戶進行同步

package com.bjsxt;
/**
 * 存錢線程
 * @author SXT
 *
 */
public class AddMoneyThread implements Runnable {
    private Account account;    // 存入賬戶
    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. 通過JDK 1.5顯示的鎖機制,為每個銀行賬戶創建一個鎖對象,在存款操作進行加鎖和解鎖的操作

package com.bjsxt;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 銀行賬戶
 *
 * @author SXT李端陽
 *
 */
public class Account {
    private Lock accountLock = new ReentrantLock();
    private double balance; // 賬戶余額
   /**
     * 存款
     *
     * @param money
     *            存入金額
     */
    public void deposit(double money) {
        accountLock.lock();
        try {
            double newBalance = balance + money;
            try {
                Thread.sleep(10); // 模擬此業務需要一段處理時間
            }
            catch (InterruptedException ex) {
                ex.printStackTrace();
            }
            balance = newBalance;
        }
        finally {
            accountLock.unlock();
        }
    }
    /**
     * 獲得賬戶余額
     */
    public double getBalance() {
        return balance;
    }
}

按照上述三種方式對代碼進行修改后,重寫執行測試代碼Test01,將看到最終的賬戶余額為100元。?

245.編寫多線程程序有幾種實現方式?

答:Java 5以前實現多線程有兩種實現方法:一種是繼承Thread類;另一種是實現Runnable接口。兩種方式都要通過重寫run()方法來定義線程的行為,推薦使用后者,因為Java中的繼承是單繼承,一個類有一個父類,如果繼承了Thread類就無法再繼承其他類了,同時也可以實現資源共享,顯然使用Runnable接口更為靈活。

補充:Java 5以后創建線程還有第三種方式:實現Callable接口,該接口中的call方法可以在線程執行結束時產生一個返回值,代碼如下所示:

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關鍵字的用法?

答:synchronized關鍵字可以將對象或者方法標記為同步,以實現對對象和方法的互斥訪問,可以用synchronized(對象) { … }定義同步代碼塊,或者在聲明方法時將synchronized作為方法的修飾符。在第60題的例子中已經展示了synchronized關鍵字的用法。?

247.啟動一個線程是用run()還是start()方法?

答:啟動一個線程是調用start()方法,使線程所代表的虛擬處理機處于可運行狀態,這意味著它可以由JVM 調度并執行,這并不意味著線程就會立即運行。run()方法是線程啟動后要進行回調(callback)的方法。?

API解釋如下:

248.什么是線程池(thread pool)?

答:在面向對象編程中,創建和銷毀對象是很費時間的,因為創建一個對象要獲取內存資源或者其它更多資源。在Java中更是如此,虛擬機將試圖跟蹤每一個對象,以便能夠在對象銷毀后進行垃圾回收。所以提高服務程序效率的一個手段就是盡可能減少創建和銷毀對象的次數,特別是一些很耗資源的對象創建和銷毀,這就是"池化資源"技術產生的原因。線程池顧名思義就是事先創建若干個可執行的線程放入一個池(容器)中,需要的時候從池中獲取線程不用自行創建,使用完畢不需要銷毀線程而是放回池中,從而減少創建和銷毀線程對象的開銷。

Java 5+中的Executor接口定義一個執行線程的工具。它的子類型即線程池接口是ExecutorService。要配置一個線程池是比較復雜的,尤其是對于線程池的原理不是很清楚的情況下,因此在工具類Executors面提供了一些靜態工廠方法,生成一些常用的線程池,如下所示:

newSingleThreadExecutor:創建一個單線程的線程池。這個線程池只有一個線程在工作,也就是相當于單線程串行執行所有任務。如果這個唯一的線程因為異常結束,那么會有一個新的線程來替代它。此線程池保證所有任務的執行順序按照任務的提交順序執行。

newFixedThreadPool:創建固定大小的線程池。每次提交一個任務就創建一個線程,直到線程達到線程池的最大大小。線程池的大小一旦達到最大值就會保持不變,如果某個線程因為執行異常而結束,那么線程池會補充一個新線程。

newCachedThreadPool:創建一個可緩存的線程池。如果線程池的大小超過了處理任務所需要的線程,那么就會回收部分空閑(60秒不執行任務)的線程,當任務數增加時,此線程池又可以智能的添加新線程來處理任務。此線程池不會對線程池大小做限制,線程池大小完全依賴于操作系統(或者說JVM)能夠創建的最大線程大小。

newScheduledThreadPool:創建一個大小無限的線程池。此線程池支持定時以及周期性執行任務的需求。

newSingleThreadExecutor:創建一個單線程的線程池。此線程池支持定時以及周期性執行任務的需求。

有通過Executors工具類創建線程池并使用線程池執行線程的代碼。如果希望在服務器上使用線程池,強烈建議使用newFixedThreadPool方法來創建線程池,這樣能獲得更好的性能。?

249.線程的基本狀態以及狀態之間的關系?

除去起始(new)狀態和結束(finished)狀態,線程有三種狀態,分別是:就緒(ready)、運行(running)和阻塞(blocked)。其中就緒狀態代表線程具備了運行的所有條件,只等待CPU調度(萬事俱備,只欠東風);處于運行狀態的線程可能因為CPU調度(時間片用完了)的原因回到就緒狀態,也有可能因為調用了線程的yield方法回到就緒狀態,此時線程不會釋放它占有的資源的鎖,坐等CPU以繼續執行;運行狀態的線程可能因為I/O中斷、線程休眠、調用了對象的wait方法而進入阻塞狀態(有的地方也稱之為等待狀態);而進入阻塞狀態的線程會因為休眠結束、調用了對象的notify方法或notifyAll方法或其他線程執行結束而進入就緒狀態。注意:調用wait方法會讓線程進入等待池中等待被喚醒,notify方法或notifyAll方法會讓等待鎖中的線程從等待池進入等鎖池,在沒有得到對象的鎖之前,線程仍然無法獲得CPU的調度和執行。

250.簡述synchronized 和java.util.concurrent.locks.Lock的異同?

答:Lock是Java 5以后引入的新的API,和關鍵字synchronized相比主要相同點:Lock 能完成synchronized所實現的所有功能;主要不同點:Lock 有比synchronized 更精確的線程語義和更好的性能。synchronized 會自動釋放鎖,而Lock 一定要求程序員手工釋放,并且必須在finally 塊中釋放(這是釋放外部資源的最好的地方)。?

251.創建線程的兩種方式分別是什么,優缺點是什么?

方式1:繼承Java.lang.Thread類,并覆蓋run() 方法。

優勢:編寫簡單;

劣勢:單繼承的限制----無法繼承其它父類,同時不能實現資源共享。

package com.bjsxt;

public class ThreadDemo1 {
public static void main(String args[]) {
MyThread1 t = new MyThread1();
t.start();
while (true) {
System.out.println("兔子領先了,別驕傲");
}
}
}
class MyThread1 extends Thread {
public void run() {
while (true) {
System.out.println("烏龜領先了,加油");
}
}
}

方式2:實現Java.lang.Runnable接口,并實現run()方法。

優勢:可繼承其它類,多線程可共享同一個Thread對象;

劣勢:編程方式稍微復雜,如需訪問當前線程,需調用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("兔子領先了,加油");
}
}
}
class MyThread2 implements Runnable {
public void run() {
while (true) {
System.out.println("烏龜超過了,再接再厲");
}
}
}
252.Java創建線程后,調用start()方法和run()的區別

兩種方法的區別

1) start方法:

用start方法來啟動線程,真正實現了多線程運行,這時無需等待run方法體代碼執行完畢而直接繼續執行下面的代碼。通過調用Thread類的start()方法來啟動一個線程,這時此線程處于就緒(可運行)狀態,并沒有運行,一旦得到cpu時間片,就開始執行run()方法,這里方法run()稱為線程體,它包含了要執行的這個線程的內容,Run方法運行結束,此線程隨即終止。

2) run():

run()方法只是類的一個普通方法而已,如果直接調用run方法,程序中依然只有主線程這一個線程,其程序執行路徑還是只有一條,還是要順序執行,還是要等待,run方法體執行完畢后才可繼續執行下面的代碼,這樣就沒有達到寫線程的目的。

總結:調用start方法方可啟動線程,而run方法只是thread的一個普通方法調用,還是在主線程里執行。這兩個方法應該都比較熟悉,把需要并行處理的代碼放在run()方法中,start()方法啟動線程將自動調用 run()方法,這是由jvm的內存機制規定的。并且run()方法必須是public訪問權限,返回值類型為void。

兩種方式的比較 :

實際中往往采用實現Runable接口,一方面因為java只支持單繼承,繼承了Thread類就無法再繼續繼承其它類,而且Runable接口只有一個run方法;另一方面通過結果可以看出實現Runable接口才是真正的多線程。

253.線程的生命周期

線程是一個動態執行的過程,它也有一個從產生到死亡的過程。

生命周期的五種狀態

新建(new Thread)

當創建Thread類的一個實例(對象)時,此線程進入新建狀態(未被啟動)

例如:Thread t1=new Thread();

就緒(runnable)

線程已經被啟動,正在等待被分配給CPU時間片,也就是說此時線程正在就緒隊列中排隊等候得到CPU資源。例如:t1.start();

運行(running)

線程獲得CPU資源正在執行任務(run()方法),此時除非此線程自動放棄CPU資源或者有優先級更高的線程進入,線程將一直運行到結束。

死亡(dead)

當線程執行完畢或被其它線程殺死,線程就進入死亡狀態,這時線程不可能再進入就緒狀態等待執行。

自然終止:正常運行run()方法后終止

異常終止:調用stop()方法讓一個線程終止運行

堵塞(blocked)

由于某種原因導致正在運行的線程讓出CPU并暫停自己的執行,即進入堵塞狀態。

正在睡眠:用sleep(long t) 方法可使線程進入睡眠方式。一個睡眠著的線程在指定的時間過去可進入就緒狀態。

正在等待:調用wait()方法。(調用motify()方法回到就緒狀態)

被另一個線程所阻塞:調用suspend()方法。(調用resume()方法恢復)

254.如何實現線程同步?

當多個線程訪問同一個數據時,容易出現線程安全問題,需要某種方式來確保資源在某一時刻只被一個線程使用。需要讓線程同步,保證數據安全

線程同步的實現方案:

1)同步代碼塊,使用synchronized關鍵字

同步代碼塊:

synchronized (同步鎖) {
授課代碼;
}

同步方法:

public synchronized void makeWithdrawal(int amt) { }

線程同步的好處:解決了線程安全問題

線程同步的缺點:性能下降,可能會帶來死鎖

注意: 同步代碼塊,所使用的同步鎖可以是三種,

1、this 2、 共享資源 3、 字節碼文件對象

同步方法所使用的同步鎖,默認的是this

255.說說關于同步鎖的更多細節

答:Java中每個對象都有一個內置鎖。

當程序運行到非靜態的synchronized同步方法上時,自動獲得與正在執行代碼類的當前實例(this實例)有關的鎖。獲得一個對象的鎖也稱為獲取鎖、鎖定對象、在對象上鎖定或在對象上同步。

當程序運行到synchronized同步方法或代碼塊時才該對象鎖才起作用。

一個對象只有一個鎖。所以,如果一個線程獲得該鎖,就沒有其他線程可以獲得鎖,直到第一個線程釋放(或返回)鎖。這也意味著任何其他線程都不能進入該對象上的synchronized方法或代碼塊,直到該鎖被釋放。

釋放鎖是指持鎖線程退出了synchronized同步方法或代碼塊。

關于鎖和同步,有一下幾個要點:

1)只能同步方法,而不能同步變量和類;

2)每個對象只有一個鎖;當提到同步時,應該清楚在什么上同步?也就是說,在哪個對象上同步?

3)不必同步類中所有的方法,類可以同時擁有同步和非同步方法。

4)如果兩個線程要執行一個類中的synchronized方法,并且兩個線程使用相同的實例來調用方法,那么一次只能有一個線程能夠執行方法,另一個需要等待,直到鎖被釋放。也就是說:如果一個線程在對象上獲得一個鎖,就沒有任何其他線程可以進入(該對象的)類中的任何一個同步方法。

5)如果線程擁有同步和非同步方法,則非同步方法可以被多個線程自由訪問而不受鎖的限制。

6)線程睡眠時,它所持的任何鎖都不會釋放。

7)線程可以獲得多個鎖。比如,在一個對象的同步方法里面調用另外一個對象的同步方法,則獲取了兩個對象的同步鎖。

8)同步損害并發性,應該盡可能縮小同步范圍。同步不但可以同步整個方法,還可以同步方法中一部分代碼塊。

9)在使用同步代碼塊時候,應該指定在哪個對象上同步,也就是說要獲取哪個對象的鎖。

256.Java中實現線程通信的三個方法的作用是什么?

Java提供了3個方法解決線程之間的通信問題,均是java.lang.Object類的方法,都只能在同步方法或者同步代碼塊中使用,否則會拋出異常。

方法名 作 用
final void wait() 表示線程一直等待,直到其它線程通知
void wait(long timeout) 線程等待指定毫秒參數的時間
final void wait(long timeout,int nanos) 線程等待指定毫秒、微妙的時間
final void notify() 喚醒一個處于等待狀態的線程。注意的是在調用此方法的時候,并不能確切的喚醒某一個等待狀態的線程,而是由JVM確定喚醒哪個線程,而且不是按優先級。
final void notifyAll() 喚醒同一個對象上所有調用wait()方法的線程,注意并不是給所有喚醒線程一個對象的鎖,而是讓它們競爭
IO流:
257.下面哪個流類屬于面向字符的輸入流()選擇一項)
A. BufferedWriter
B. FileInputStream
C. ObjectInputStream
D. InputStreamReader
答案:D
分析:A:字符輸出的緩沖流
B:字節輸入流
C:對象輸入流

258.要從文件”file.dat”文件中讀出第10個字節到變量c中,下列哪個正確()(選擇一項)
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指的是要跳過的字節數
259.新建一個流對象,下面那個選項的代碼是錯誤的?()
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類的參數只能是Reader類型的,不能是InputStream類型。
260.下面哪個流是面向字符的輸入流()
A. BufferedWriter
B. FileInputStream
C. ObjectInputStream
D. InputStreamReader
答案:D
以InputStream(輸入流)/OutputStream(輸出流)為后綴的是字節流;
以Reader(輸入流)/Writer(輸出流)為后綴的是字符流。
261.Java類庫中,將信息寫入內存的類是()
A. Java.io.FileOutputStream
B. java.ByteArrayOutputStream
C. java.io.BufferedOutputStream
D. java,.io.DataOutputStream
答案:B
分析: ACD都是io到文件
262.請寫出一段代碼,能夠完成將字符串寫入文件
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.下面哪個流類屬于面向字符的輸入流()
A. BufferedWriter
B. FileInputStream
C. ObjectInputStream
D. InputStreamReader
答案:D
264.Java中如何實現序列化,有什么意義?

答:序列化就是一種用來處理對象流的機制,所謂對象流也就是將對象的內容進行流化??梢詫α骰蟮膶ο筮M行讀寫操作,也可將流化后的對象傳輸于網絡之間。序列化是為了解決對象流讀寫操作時可能引發的問題(如果不進行序列化可能會存在數據亂序的問題)。

要實現序列化,需要讓一個類實現Serializable接口,該接口是一個標識性接口,標注該類對象是可被序列化的,然后使用一個輸出流來構造一個對象輸出流并通過writeObject(Object obj)方法就可以將實現對象寫出(即保存其狀態);如果需要反序列化則可以用一個輸入流建立對象輸入流,然后通過readObject方法從流中讀取對象。序列化除了能夠實現對象的持久化之外,還能夠用于對象的深度克?。▍⒁奐ava面試題集1-29題)?

265.Java 中有幾種類型的流?

答:兩種流分別是字節流,字符流。

字節流繼承于InputStream、OutputStream,字符流繼承于Reader、Writer。在java.io 包中還有許多其他的流,主要是為了提高性能和使用方便。

補充:關于Java的IO需要注意的有兩點:一是兩種對稱性(輸入和輸出的對稱性,字節和字符的對稱性);二是兩種設計模式(適配器模式和裝潢模式)。另外Java中的流不同于C#的是它只有一個維度一個方向。

補充:下面用IO和NIO兩種方式實現文件拷貝,這個題目在面試的時候是經常被問到的。

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中釋放外部資源 ,從而讓代碼更加優雅。

266.寫一個方法,輸入一個文件名和一個字符串,統計這個字符串在這個文件中出現的次數。

答:代碼如下:

package com.bjsxt;
import java.io.BufferedReader;
import java.io.FileReader;

public class Account {
    // 工具類中的方法都是靜態方式訪問的因此將構造器私有不允許創建對象(絕對好習慣)
    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.輸入流和輸出流聯系和區別,節點流和處理流聯系和區別

首先,你要明白什么是“流”。直觀地講,流就像管道一樣,在程序和文件之間,輸入輸出的方向是針對程序而言,向程序中讀入東西,就是輸入流,從程序中向外讀東西,就是輸出流。

輸入流是得到數據,輸出流是輸出數據,而節點流,處理流是流的另一種劃分,按照功能不同進行的劃分。節點流,可以從或向一個特定的地方(節點)讀寫數據。處理流是對一個已存在的流的連接和封裝,通過所封裝的流的功能調用實現數據讀寫。如BufferedReader。處理流的構造方法總是要帶一個其他的流對象做參數。一個流對象經過其他流的多次包裝,稱為流的鏈接。

268.字符流字節流聯系區別;什么時候使用字節流和字符流?

字符流和字節流是流的一種劃分,按處理照流的數據單位進行的劃分。兩類都分為輸入和輸出操作。在字節流中輸出數據主要是使用OutputStream完成,輸入使的是InputStream,在字符流中輸出主要是使用Writer類完成,輸入流主要使用Reader類完成。這四個都是抽象類。

字符流處理的單元為2個字節的Unicode字符,分別操作字符、字符數組或字符串,而字節流處理單元為1個字節,操作字節和字節數組。字節流是最基本的,所有的InputStrem和OutputStream的子類都是,主要用在處理二進制數據,它是按字節來處理的 但實際中很多的數據是文本,又提出了字符流的概念,它是按虛擬機的編碼來處理,也就是要進行字符集的轉化 這兩個之間通過 InputStreamReader,OutputStreamWriter來關聯,實際上是通過byte[]和String來關聯的。

269.列舉常用字節輸入流和輸出流并說明其特點,至少5對。

FileInputStream 從文件系統中的某個文件中獲得輸入字節。

FileOutputStream 從程序當中的數據,寫入到指定文件。

ObjectInputStream 對以前使用 ObjectOutputStream 寫入的基本數據和對象進行反序列化。 ObjectOutputStream 和ObjectInputStream 分別與FileOutputStream 和 FileInputStream 一起使用時,可以為應用程序提供對對象圖形的持久存儲。ObjectInputStream 用于恢復那些以前序列化的對象。其他用途包括使用套接字流在主機之間傳遞對象,或者用于編組和解組遠程通信系統中的實參和形參。

ByteArrayInputStream 包含一個內部緩沖區,該緩沖區包含從流中讀取的字節。內部計數器跟蹤 read 方法要提供的下一個字節。

FilterInputStream 包含其他一些輸入流,它將這些流用作其基本數據源,它可以直接傳輸數據或提供一些額外的功能。FilterInputStream 類本身只是簡單地重寫那些將所有請求傳遞給所包含輸入流的 InputStream 的所有方法。FilterInputStream 的子類可進一步重寫這些方法中的一些方法,并且還可以提供一些額外的方法和字段。

StringBufferInputStream此類允許應用程序創建輸入流,在該流中讀取的字節由字符串內容提供。應用程序還可以使用ByteArrayInputStream 從 byte 數組中讀取字節。 只有字符串中每個字符的低八位可以由此類使用。

ByteArrayOutputStream此類實現了一個輸出流,其中的數據被寫入一個 byte 數組。緩沖區會隨著數據的不斷寫入而自動增長??墒褂?toByteArray() 和 toString() 獲取數據。

FileOutputStream文件輸出流是用于將數據寫入 File 或FileDescriptor 的輸出流。文件是否可用或能否可以被創建取決于基礎平臺。特別是某些平臺一次只允許一個 FileOutputStream(或其他文件寫入對象)打開文件進行寫入。在這種情況下,如果所涉及的文件已經打開,則此類中的構造方法將失敗。

FilterOutputStream類是過濾輸出流的所有類的超類。這些流位于已存在的輸出流(基礎 輸出流)之上,它們將已存在的輸出流作為其基本數據接收器,但可能直接傳輸數據或提供一些額外的功能。 FilterOutputStream 類本身只是簡單地重寫那些將所有請求傳遞給所包含輸出流的 OutputStream 的所有方法。FilterOutputStream 的子類可進一步地重寫這些方法中的一些方法,并且還可以提供一些額外的方法和字段。

ObjectOutputStream 將 Java 對象的基本數據類型和圖形寫入 OutputStream??梢允褂?ObjectInputStream 讀?。ㄖ貥嫞ο?。通過在流中使用文件可以實現對象的持久存儲。如果流是網絡套接字流,則可以在另一臺主機上或另一個進程中重構對象。

PipedOutputStream可以將管道輸出流連接到管道輸入流來創建通信管道。管道輸出流是管道的發送端。通常,數據由某個線程寫入 PipedOutputStream 對象,并由其他線程從連接的 PipedInputStream 讀取。不建議對這兩個對象嘗試使用單個線程,因為這樣可能會造成該線程死鎖。如果某個線程正從連接的管道輸入流中讀取數據字節,但該線程不再處于活動狀態,則該管道被視為處于毀壞狀態。

270.說明緩沖流的優點和原理

不帶緩沖的流的工作原理:

它讀取到一個字節/字符,就向用戶指定的路徑寫出去,讀一個寫一個,所以就慢了。

帶緩沖的流的工作原理:

讀取到一個字節/字符,先不輸出,等湊足了緩沖的最大容量后一次性寫出去,從而提高了工作效率

優點:減少對硬盤的讀取次數,降低對硬盤的損耗。

271.序列化的定義、實現和注意事項

想把一個對象寫在硬盤上或者網絡上,對其進行序列化,把他序列化成為一個字節流。

實現和注意事項:

1)實現接口Serializable Serializable接口中沒有任何的方法,實現該接口的類不需要實現額外的方法。

2)如果對象中的某個屬性是對象類型,必須也實現Serializable接口才可以,序列化對靜態變量無效

3)如果不希望某個屬性參與序列化,不是將其static,而是transient串行化保存的只是變量的值,對于變量的任何修飾符,都不能保存序列化版本不兼容

272.使用IO流完成文件夾復制

(結合遞歸)

package com.bjsxt;

import java.io.*;
/**
 * CopyDocJob定義了實際執行的任務,即
 * 從源目錄拷貝文件到目標目錄
*/
public class CopyDir2 {
public static void main(String[] args) {
try {
copyDirectiory("d:/301sxt","d:/301sxt2");
} catch (IOException e) {
e.printStackTrace();
}
}
/**
 * 復制單個文件
 * @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 {
            // 關閉流
            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;
     }
     //檢查目標目錄,如不存在則創建
     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.說說BIO、NIO和AIO的區別

Java BIO: 同步并阻塞,服務器實現模式為一個連接一個線程,即客戶端有連接請求時服務器端就需要啟動一個線程進行處理,如果這個連接不做任何事情會造成不必要的線程開銷,當然可以通過線程池機制改善。

Java NIO: 同步非阻塞,服務器實現模式為一個請求一個線程,即客戶端發送的連接請求都會注冊到多路復用器上,多路復用器輪詢到連接有I/O請求時才啟動一個線程進行處理。

Java AIO: 異步非阻塞,服務器實現模式為一個有效請求一個線程,客戶端的I/O請求都是由OS先完成了再通知服務器應用去啟動線程進行處理。

NIO比BIO的改善之處是把一些無效的連接擋在了啟動線程之前,減少了這部分資源的浪費(因為我們都知道每創建一個線程,就要為這個線程分配一定的內存空間)

AIO比NIO的進一步改善之處是將一些暫時可能無效的請求擋在了啟動線程之前,比如在NIO的處理方式中,當一個請求來的話,開啟線程進行處理,但這個請求所需要的資源還沒有就緒,此時必須等待后端的應用資源,這時線程就被阻塞了。

適用場景分析:

BIO方式適用于連接數目比較小且固定的架構,這種方式對服務器資源要求比較高,并發局限于應用中,JDK1.4以前的唯一選擇,但程序直觀簡單易理解,如之前在Apache中使用。

NIO方式適用于連接數目多且連接比較短(輕操作)的架構,比如聊天服務器,并發局限于應用中,編程比較復雜,JDK1.4開始支持,如在 Nginx,Netty中使用。

AIO方式使用于連接數目多且連接比較長(重操作)的架構,比如相冊服務器,充分調用OS參與并發操作,編程比較復雜,JDK7開始支持,在成長中,Netty曾經使用過,后來放棄。

網絡編程:

274.IP地址和端口號

1)IP地址

用來標志網絡中的一個通信實體的地址。通信實體可以是計算機,路由器等。

2)IP地址分類

IPV4:32位地址,以點分十進制表示,如192.168.0.1

IPV6:128位(16個字節)寫成8個16位的無符號整數,每個整數用四個十六進制位表示,數之間用冒號(:)分開,如:3ffe:3201:1401:1280:c8ff:fe4d:db39:1984

3)特殊的IP地址

127.0.0.1 本機地址

192.168.0.0--192.168.255.255私有地址,屬于非注冊地址,專門為組織機構內部使用。

4)端口:port

IP地址用來標志一臺計算機,但是一臺計算機上可能提供多種應用程序,使用端口來區分這些應用程序。 端口是虛擬的概念,并不是說在主機上真的有若干個端口。通過端口,可以在一個主機上運行多個網絡應用程序。 端口范圍0---65535,16位整數

5)端口分類

公認端口 0—1023 比如80端口分配給WWW,21端口分配給FTP,22端口分配給SSH,23端口分配給telnet,25端口分配給smtp

注冊端口 1024—49151 分配給用戶進程或應用程序

動態/私有端口 49152--65535

6)理解IP和端口的關系

IP地址好比每個人的地址(門牌號),端口好比是房間號。必須同時指定IP地址和端口號才能夠正確的發送數據

IP地址好比為電話號碼,而端口號就好比為分機號。

275.介紹OSI七層模型和TCP/IP模型

OSI(Open System Interconnection),開放式系統互聯參考模型 。是一個邏輯上的定義,一個規范,它把網絡協議從邏輯上分為了7層。每一層都有相關、相對應的物理設備,比如常規的路由器是三層交換設備,常規的交換機是二層交換設備。OSI七層模型是一種框架性的設計方法,建立七層模型的主要目的是為解決異種網絡互連時所遇到的兼容性問題,其最主要的功能就是幫助不同類型的主機實現數據傳輸。它的最大優點是將服務、接口和協議這三個概念明確地區分開來,通過七個層次化的結構模型使不同的系統不同的網絡之間實現可靠的通訊。

TCP/IP協議是Internet最基本的協議、Internet國際互聯網絡的基礎,主要由網絡層的IP協議和傳輸層的TCP協議組成。TCP/IP 定義了電子設備如何連入因特網,以及數據如何在它們之間傳輸的標準。協議采用了4層的層級結構,每一層都呼叫它的下一層所提供的協議來完成自己的需求。

ISO制定的OSI參考模型的過于龐大、復雜招致了許多批評。伴隨著互聯網的流行,其本身所采用的TCP/IP協議棧獲得了更為廣泛的應用和認可。在TCP/IP參考模型中,去掉了OSI參考模型中的會話層和表示層(這兩層的功能被合并到應用層實現)。同時將OSI參考模型中的數據鏈路層和物理層合并為主機到網絡層。

276.TCP協議和UDP協議的比較

TCP和UDP是TCP/IP協議棧中傳輸層的兩個協議,它們使用IP路由功能把數據包發送到目的地,從而為應用程序及應用層協議(包括:HTTP、SMTP、SNMP、FTP和Telnet)提供網絡服務。

TCP的server和client之間通信就好比兩個人打電話,需要互相知道對方的電話號碼,然后開始對話。所以在兩者的連接過程中間需要指定端口和地址。

UDP的server和client之間的通信就像兩個人互相發信。我只需要知道對方的地址,然后就發信過去。對方是否收到我不知道,也不需要專門對口令似的來建立連接。具體區別如下:

1)TCP是面向連接的傳輸。UDP是無連接的傳輸

2)TCP有流量控制、擁塞控制,檢驗數據數據按序到達,而UDP則相反。

3)TCP的路由選擇只發生在建立連接的時候,而UDP的每個報文都要進行路由選擇

4)TCP是可靠性傳輸,他的可靠性是由超時重發機制實現的,而UDP則是不可靠傳輸

5)UDP因為少了很多控制信息,所以傳輸速度比TCP速度快

6)TCP適合用于傳輸大量數據,UDP適合用于傳輸小量數據

277.什么是Socket編程

Socket編程的定義如下:

所謂socket通常也稱作"套接字",用于描述IP地址和端口,是一個通信鏈的句柄。應用程序通常通過"套接字"向網絡發出請求或者應答網絡請求。

我們開發的網絡應用程序位于應用層,TCP和UDP屬于傳輸層協議,在應用層如何使用傳輸層的服務呢?在應用層和傳輸層之間,則是使用套接字來進行分離。

套接字就像是傳輸層為應用層開的一個小口,應用程序通過這個小口向遠程發送數據,或者接收遠程發來的數據;而這個小口以內,也就是數據進入這個口之后,或者數據從這個口出來之前,是不知道也不需要知道的,也不會關心它如何傳輸,這屬于網絡其它層次的工作。

Socket實際是傳輸層供給應用層的編程接口。傳輸層則在網絡層的基礎上提供進程到進程問的邏輯通道,而應用層的進程則利用傳輸層向另一臺主機的某一進程通信。Socket就是應用層與傳輸層之間的橋梁

使用Socket編程可以開發客戶機和服務器應用程序,可以在本地網絡上進行通信,也可通過Internet在全球范圍內通信。

生活案例1如果你想寫封郵件發給遠方的朋友,如何寫信、將信打包,屬于應用層。信怎么寫,怎么打包完全由我們做主;而當我們將信投入郵筒時,郵筒的那個口就是套接字,在進入套接字之后,就是傳輸層、網絡層等(郵局、公路交管或者航線等)其它層次的工作了。我們從來不會去關心信是如何從西安發往北京的,我們只知道寫好了投入郵筒就OK了。

生活案例2:可以把Socket比作是一個港口碼頭,應用程序只要將數據交給Socket,就算完成了數據的發送,具體細節由Socket來完成,細節不必了解。同理,對于接收方,應用程序也要創建一個碼頭,等待數據的到達,并獲取數據。

278.簡述基于TCP和UDP的Socket編程的主要步驟

Java分別為TCP和UDP 兩種通信協議提供了相應的Socket編程類,這些類存放在java.net包中。與TCP對應的是服務器的ServerSocket和客戶端的Socket,與UDP對應的是DatagramSocket。

基于TCP創建的套接字可以叫做流套接字,服務器端相當于一個監聽器,用來監聽端口。?服務器與客服端之間的通訊都是輸入輸出流來實現的?;赨DP的套接字就是數據報套接字,?? 兩個都要先構造好相應的數據包。

基于TCP協議的Socket編程的主要步驟

服務器端(server):

1. 構建一個ServerSocket實例,指定本地的端口。這個socket就是用來監聽指定端口的連接請求的。

2. 重復如下幾個步驟:

a. 調用socket的accept()方法來獲得下面客戶端的連接請求。通過accept()方法返回的socket實例,建立了一個和客戶端的新連接。

b. 通過這個返回的socket實例獲取InputStream和OutputStream,可以通過這兩個stream來分別讀和寫數據。

c. 結束的時候調用socket實例的close()方法關閉socket連接。

客戶端(client):

1.構建Socket實例,通過指定的遠程服務器地址和端口來建立連接。

2.通過Socket實例包含的InputStream和OutputStream來進行數據的讀寫。

3.操作結束后調用socket實例的close方法,關閉。

UDP

服務器端(server):

1. 構造DatagramSocket實例,指定本地端口。

2. 通過DatagramSocket實例的receive方法接收DatagramPacket.DatagramPacket中間就包含了通信的內容。

3. 通過DatagramSocket的send和receive方法來收和發DatagramPacket.

客戶端(client):

1. 構造DatagramSocket實例。

2. 通過DatagramSocket實例的send和receive方法發送DatagramPacket報文。

3. 結束后,調用DatagramSocket的close方法關閉。

異常處理:

279.下列哪種異常是檢查型異常,需要在編寫程序時聲明()
A. NullPointerException
B. ClassCastException
C. FileNotFoundException
D. IndexOutOfBoundsException
答案:C
分析:NullPointerException空指針異常
ClassCastException類型轉換異常
IndexOutOfBoundsException索引超出邊界的異常
以上這些異常都是程序在運行時發生的異常,所以不需要在編寫程序時聲明
280.Java出現OutOf MemoryError(OOM 錯誤)的原因有哪些?出現OOM錯誤后,怎么解決?

答:OutOf MemoryError這種錯誤可以細分為多種不同的錯誤,每種錯誤都有自身的原因和解決辦法,如下所示:

java.lang.OutOfMemoryError: Java heap space

錯誤原因:此OOM是由于JVM中heap的最大值不滿足需要。

解決方法:1) 調高heap的最大值,即-Xmx的值調大。2) 如果你的程序存在內存泄漏,一味的增加heap空間也只是推遲該錯誤出現的時間而已,所以要檢查程序是否存在內存泄漏。

java.lang.OutOfMemoryError: GC overhead limit exceeded

錯誤原因:此OOM是由于JVM在GC時,對象過多,導致內存溢出,建議調整GC的策略,在一定比例下開始GC而不要使用默認的策略,或者將新代和老代設置合適的大小,需要進行微調存活率。

解決方法:改變GC策略,在老代80%時就是開始GC,并且將-XX:SurvivorRatio(-XX:SurvivorRatio=8)和-XX:NewRatio(-XX:NewRatio=4)設置的更合理。

java.lang.OutOfMemoryError: Java perm space

錯誤原因:此OOM是由于JVM中perm的最大值不滿足需要。

解決方法:調高heap的最大值,即-XX:MaxPermSize的值調大。

另外,注意一點,Perm一般是在JVM啟動時加載類進來,如果是JVM運行較長一段時間而不是剛啟動后溢出的話,很有可能是由于運行時有類被動態加載進來,此時建議用CMS策略中的類卸載配置。如:-XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled。

java.lang.OutOfMemoryError: unable to create new native thread

錯誤原因:當JVM向OS請求創建一個新線程時,而OS卻由于內存不足無法創建新的native線程。

解決方法:如果JVM內存調的過大或者可利用率小于20%,可以建議將heap及perm的最大值下調,并將線程棧調小,即-Xss調小,如:-Xss128k。

java.lang.OutOfMemoryError: Requested array size exceeds VM limit

錯誤原因:此類信息表明應用程序(或者被應用程序調用的APIs)試圖分配一個大于堆大小的數組。例如,如果應用程序new一個數組對象,大小為512M,但是最大堆大小為256M,因此OutOfMemoryError會拋出,因為數組的大小超過虛擬機的限制。

解決方法:1) 首先檢查heap的-Xmx是不是設置的過小。2) 如果heap的-Xmx已經足夠大,那么請檢查應用程序是不是存在bug,例如:應用程序可能在計算數組的大小時,存在算法錯誤,導致數組的size很大,從而導致巨大的數組被分配。

java.lang.OutOfMemoryError: request < size> bytes for < reason>. Out of swap space

錯誤原因:拋出這類錯誤,是由于從native堆中分配內存失敗,并且堆內存可能接近耗盡。這類錯誤可能跟應用程序沒有關系,例如下面兩種原因也會導致錯誤的發生:1) 操作系統配置了較小的交換區。2)系統的另外一個進程正在消耗所有的內存。

解決辦法:1) 檢查os的swap是不是沒有設置或者設置的過小。2) 檢查是否有其他進程在消耗大量的內存,從而導致當前的JVM內存不夠分配。

注意:雖然有時< reason>部分顯示導致OOM的原因,但大多數情況下,< reason>顯示的是提示分配失敗的源模塊的名稱,所以有必要查看日志文件,如crash時的hs文件。

281.列舉常見的運行時異常

答:ClassCastException(類轉換異常)

比如 Object obj=new Object(); String s=(String)obj;?

IndexOutOfBoundsException(下標越界異常)

NullPointerException(空指針異常)

ArrayStoreException(數據存儲異常,操作數組時類型不一致)

BufferOverflowException(IO操作時出現的緩沖區上溢異常)

InputMismatchException(輸入類型不匹配異常)

ArithmeticException(算術異常)

注意:運行時異常都是RuntimeException子類異常。

282.下面關于 Java.lang.Exception類的說法正確的是()
A. 繼承自 Throwable
B. 不支持Serializable
C. 繼承自 AbstractSet
D. 繼承自FitelnputStream
答案:A
分析:Throwable是Exception和Error的父類,Exception雖然沒有實現Serializable接口,但是其父類Throwable已經實現了該接口,因此Exception也支持Serializable。
283.Unsupported major.minor version 52是什么異常,怎么造成的,如何解決?

答:問題的根本原因是工程中某個jar包的版本(jar包編譯時的所用的jdk版本)高于工程build path中jdk的版本,這個是不兼容的! 編程中遇到此異常Unsupported major.minor version 52.0(根據版本號,這里可以為其他數值,52是1.8jdk jar包與 1.8以下低版本jdk不匹配),在將build path中jdk的版本調整與jar包匹配后,解決異常。

284.try{}里有一個return語句,那么緊跟在這個try后的finally{}里的code會不會被執行,什么時候被執行,在return前還是后?

答:會執行,在方法返回調用者前執行。Java允許在finally中改變返回值的做法是不好的,因為如果存在finally代碼塊,try中的return語句不會立馬返回調用者,而是記錄下返回值待finally代碼塊執行完畢之后再向調用者返回其值,然后如果在finally中修改了返回值,這會對程序造成很大的困擾,C#中就從語法上規定不能做這樣的事。?

(也許你的答案是在return之前,但往更細地說,我的答案是在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,為什么呢?主函數調用子函數并得到結果的過程,好比主函數準備一個空罐子,當子函數要返回結果時,先把結果放在罐子里,然后再將程序邏輯返回到主函數。所謂返回,就是子函數說,我不運行了,你主函數繼續運行吧,這沒什么結果可言,結果是在說這話之前放進罐子里的。

285.Java 語言如何進行異常處理,關鍵字:throws、throw、try、catch、finally分別如何使用?

答:Java 通過面向對象的方法進行異常處理,把各種不同的異常進行分類,并提供了良好的接口。在Java 中,每個異常都是一個對象,它是Throwable 類或其子類的實例。當一個方法出現異常后便拋出一個異常對象,該對象中包含有異常信息,調用這個對象的方法可以捕獲到這個異常并進行處理。Java 的異常處理是通過5 個關鍵詞來實現的:try、catch、throw、throws和finally。一般情況下是用try來執行一段程序,如果出現異常,系統會拋出(throw)一個異常,這時候你可以通過它的類型來捕捉(catch)它,或最后(finally)由缺省處理器來處理;try用來指定一塊預防所有“異?!钡某绦?;catch 子句緊跟在try塊后面,用來指定你想要捕捉的“異?!钡念愋?;throw 語句用來明確地拋出一個“異?!?;throws用來標明一個成員函數可能拋出的各種“異?!?;finally 為確保一段代碼不管發生什么“異?!倍急粓绦幸欢未a;可以在一個成員函數調用的外面寫一個try語句,在這個成員函數內部寫另一個try語句保護其他代碼。每當遇到一個try 語句,“異?!钡目蚣芫头诺綏I厦?,直到所有的try語句都完成。如果下一級的try語句沒有對某種“異?!边M行處理,棧就會展開,直到遇到有處理這種“異?!钡膖ry 語句。?

286.運行時異常與受檢異常有何異同?

答:異常表示程序運行過程中可能出現的非正常狀態,運行時異常表示虛擬機的通常操作中可能遇到的異常,是一種常見運行錯誤,只要程序設計得沒有問題通常就不會發生。受檢異常跟程序運行的上下文環境有關,即使程序設計無誤,仍然可能因使用的問題而引發。Java編譯器要求方法必須聲明拋出可能發生的受檢異常,但是并不要求必須聲明拋出未被捕獲的運行時異常。異常和繼承一樣,是面向對象程序設計中經常被濫用的東西,神作《Effective Java》中對異常的使用給出了以下指導原則:

不要將異常處理用于正常的控制流(設計良好的API不應該強迫它的調用者為了正常的控制流而使用異常)

對可以恢復的情況使用受檢異常,對編程錯誤使用運行時異常

避免不必要的使用受檢異常(可以通過一些狀態檢測手段來避免異常發生)

優先使用標準的異常

每個方法拋出的異常都要有文檔

保持異常的原子性

不要在catch中忽略掉捕獲到的異常?

(異常表示程序運行過程中可能出現的非正常狀態,運行時異常表示虛擬機的通常操作中可能遇到的異常,是一種常見運行錯誤。java編譯器要求方法必須聲明拋出可能發生的非運行時異常,但是并不要求必須聲明拋出未被捕獲的運行時異常。)

287.類ExampleA 繼承Exception,類ExampleB 繼承ExampleA

有如下代碼片斷:

try{
throw new ExampleB("b")
}catch(ExampleA e){
System.out.println("ExampleA");
}catch(Exception e){
System.out.println("Exception");
}
 }

請問執行此段代碼的輸出是什么?

答:輸出:ExampleA。(根據里氏代換原則[能使用父類型的地方一定能使用子類型],抓取ExampleA類型異常的catch塊能夠抓住try塊中拋出的ExampleB類型的異常)

補充: 比此題略復雜的一道面試題如下所示(此題的出處是《Java編程思想》),說出你的答案吧!

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類,表示僅靠程序本身無法恢復的嚴重錯誤,比如說內存溢出、動態鏈接異常、虛擬機錯誤。應用程序不應該拋出這種類型的對象。假如出現這種錯誤,除了盡力使程序安全退出外,在其他方面是無能為力的。所以在進行程序設計時,應該更關注Exception類。

Exception類,由Java應用程序拋出和處理的非嚴重錯誤,比如所需文件沒有找到、零作除數,數組下標越界等。它的各種不同子類分別對應不同類型異常??煞譃閮深悾篊hecked異常和Runtime異常

289.Java異常處理try-catch-finally的執行過程

try-catch-finally程序塊的執行流程以及執行結果比較復雜。

基本執行過程如下:

1)程序首先執行可能發生異常的try語句塊。

2)如果try語句沒有出現異常則執行完后跳至finally語句塊執行;

3)如果try語句出現異常,則中斷執行并根據發生的異常類型跳至相應的catch語句塊執行處理。

4)catch語句塊可以有多個,分別捕獲不同類型的異常。

5)catch語句塊執行完后程序會繼續執行finally語句塊。

finally語句是可選的,如果有的話,則不管是否發生異常,finally語句都會被執行。需要注意的是即使try和catch塊中存在return語句,finally語句也會執行,是在執行完finally語句后再通過return退出。

290.異常處理中throws和throw的區別

1)作用不同:

throw用于程序員自行產生并拋出異常;

throws用于聲明在該方法內拋出了異常

2) 使用的位置不同:

throw位于方法體內部,可以作為單獨語句使用;

throws必須跟在方法參數列表的后面,不能單獨使用。

3)內容不同:

throw拋出一個異常對象,且只能是一個;

throws后面跟異常類,而且可以有多個。

Web方面相關:
291.WEB應用中如果有.class和.jar類型的文件一般分別應該放在什么位置?

答:.class文件放在WEB-INF/classes文件下,.jar文件放在WEB-INF/lib文件夾下

292.元素中有一個輸入框(< input type='text' name=”username”id=”username”value=””/>,請用JavaScript語言寫一行代碼,取得這個輸入框中的值。

答:document.getElementById(“username”).value;

293.簡單描述一下Servlet與JSP的的相同點和區別點。

區別:

JSP是在HTML代碼里寫JAVA代碼,框架是HTML;而Servlet是在JAVA代碼中寫HTML代碼,本身是個JAVA類。

JSP使人們把顯示和邏輯分隔成為可能,這意味著兩者的開發可并行進行;而Servlet并沒有把兩者分開。

Servlet獨立地處理靜態表示邏輯與動態業務邏輯.這樣,任何文件的變動都需要對此服務程序重新編譯;JSP允許用特殊標簽直接嵌入到HTML頁面, HTML內容與JAVA內容也可放在單獨文件中,HTML內容的任何變動會自動編譯裝入到服務程序.

Servlet需要在web.xml中配置,而JSP無需配置。

目前JSP主要用在視圖層,負責顯示,而Servlet主要用在控制層,負責調度

聯系:

都是Sun公司推出的動態網頁技術。

先有Servlet,針對Servlet缺點推出JSP。JSP是Servlet的一種特殊形式,每個JSP頁面就是一個Servlet實例——JSP頁面由系統翻譯成Servlet,Servlet再負責響應用戶請求。

294.請簡單描述下幾個您熟悉JavaScript庫,它們有哪些作用和特點?

JavaScript 高級程序設計(特別是對瀏覽器差異的復雜處理),通常很困難也很耗時。為了應對這些調整,許多的 JavaScript庫應運而生。這些 JavaScript 庫常被稱為 JavaScript 框架。

jQuery:

Ext JS - 可定制的 widget,用于構建富因特網應用程序(rich Internet applications)。

Prototype

MooTools。

YUI - Yahoo! User Interface Framework,涵蓋大量函數的大型庫,從簡單的 JavaScript 功能到完整的 internet widget。

295.簡單描述HTML,CSS,Javascript在Web開發中分別起什么作用?

1、什么是HTML(超文本標記語言 Hyper Text Markup Language),HTML 是用來描述網頁的一種語言。

2、CSS(層疊樣式表 Cascading Style Sheets),樣式定義如何顯示 HTML 元素,語法為:selector {property:value} (選擇符 {屬性:值})

3、JavaScript是一種腳本語言,其源代碼在發往客戶端運行之前不需經過編譯,而是將文本格式的字符代碼發送給瀏覽器由瀏覽器解釋運行

對于一個網頁,HTML定義網頁的結構,CSS描述網頁的樣子,JavaScript設置一個很經典的例子是說HTML就像 一個人的骨骼、器官,而CSS就是人的皮膚,有了這兩樣也就構成了一個植物人了,加上javascript這個植物人就可以對外界刺激做出反應,可以思 考、運動、可以給自己整容化妝(改變CSS)等等,成為一個活生生的人。

如果說HTML是肉身、CSS就是皮相、Javascript就是靈魂。沒有Javascript,HTML+CSS是植物人,沒有Javascript、CSS是個毀容的植物人。

如果說HTML是建筑師,CSS就是干裝修的,Javascript是魔術師。

296.當DOM加載完成后要執行的函數,下面哪個是正確的()
A. JQuery(expression, [context])
B. JQuery(html, [ownerDocument])
C. JQuery(callback)
答案:C
297.舉例說明JAVA中如何解析xml,不同方式有和優缺點?

答:1. DOM(Document Object Model)

DOM是用與平臺和語言無關的方式表示XML文檔的官方W3C標準。DOM是以層次結構組織的節點或信息片斷的集合。這個層次結構允許開發人員在樹中尋找特定信息。分析該結構通常需要加載整個文檔和構造層次結構,然后才能做任何工作。由于它是基于信息層次的,因而DOM被認為是基于樹或基于對象的。

【優點】

①允許應用程序對數據和結構做出更改。

②訪問是雙向的,可以在任何時候在樹中上下導航,獲取和操作任意部分的數據。

【缺點】

①通常需要加載整個XML文檔來構造層次結構,消耗資源大。

2. SAX(Simple API for XML)

SAX處理的優點非常類似于流媒體的優點。分析能夠立即開始,而不是等待所有的數據被處理。而且,由于應用程序只是在讀取數據時檢查數據,因此不需要將數據存儲在內存中。這對于大型文檔來說是個巨大的優點。事實上,應用程序甚至不必解析整個文檔;它可以在某個條件得到滿足時停止解析。一般來說,SAX還比它的替代者DOM快許多。

選擇DOM還是選擇SAX? 對于需要自己編寫代碼來處理XML文檔的開發人員來說, 選擇DOM還是SAX解析模型是一個非常重要的設計決策。 DOM采用建立樹形結構的方式訪問XML文檔,而SAX采用的是事件模型。

DOM解析器把XML文檔轉化為一個包含其內容的樹,并可以對樹進行遍歷。用DOM解析模型的優點是編程容易,開發人員只需要調用建樹的指令,然后利用navigation APIs訪問所需的樹節點來完成任務??梢院苋菀椎奶砑雍托薷臉渲械脑?。然而由于使用DOM解析器的時候需要處理整個XML文檔,所以對性能和內存的要求比較高,尤其是遇到很大的XML文件的時候。由于它的遍歷能力,DOM解析器常用于XML文檔需要頻繁的改變的服務中。

SAX解析器采用了基于事件的模型,它在解析XML文檔的時候可以觸發一系列的事件,當發現給定的tag的時候,它可以激活一個回調方法,告訴該方法制定的標簽已經找到。SAX對內存的要求通常會比較低,因為它讓開發人員自己來決定所要處理的tag.特別是當開發人員只需要處理文檔中所包含的部分數據時,SAX這種擴展能力得到了更好的體現。但用SAX解析器的時候編碼工作會比較困難,而且很難同時訪問同一個文檔中的多處不同數據。

【優勢】

①不需要等待所有數據都被處理,分析就能立即開始。

②只在讀取數據時檢查數據,不需要保存在內存中。

③可以在某個條件得到滿足時停止解析,不必解析整個文檔。

④效率和性能較高,能解析大于系統內存的文檔。

【缺點】

①需要應用程序自己負責TAG的處理邏輯(例如維護父/子關系等),文檔越復雜程序就越復雜。

②單向導航,無法定位文檔層次,很難同時訪問同一文檔的不同部分數據,不支持XPath。

3. JDOM(Java-based Document Object Model)

JDOM的目的是成為Java特定文檔模型,它簡化與XML的交互并且比使用DOM實現更快。由于是第一個Java特定模型,JDOM一直得到大力推廣和促進。正在考慮通過“Java規范請求JSR-102”將它最終用作“Java標準擴展”。從2000年初就已經開始了JDOM開發。

JDOM與DOM主要有兩方面不同。首先,JDOM僅使用具體類而不使用接口。這在某些方面簡化了API,但是也限制了靈活性。第二,API大量使用了Collections類,簡化了那些已經熟悉這些類的Java開發者的使用。

JDOM文檔聲明其目的是“使用20%(或更少)的精力解決80%(或更多)Java/XML問題”(根據學習曲線假定為20%)。JDOM對于大多數Java/XML應用程序來說當然是有用的,并且大多數開發者發現API比DOM容易理解得多。JDOM還包括對程序行為的相當廣泛檢查以防止用戶做任何在XML中無意義的事。然而,它仍需要您充分理解XML以便做一些超出基本的工作(或者甚至理解某些情況下的錯誤)。這也許是比學習DOM或JDOM接口都更有意義的工作。

JDOM自身不包含解析器。它通常使用SAX2解析器來解析和驗證輸入XML文檔(盡管它還可以將以前構造的DOM表示作為輸入)。它包含一些轉換器以將JDOM表示輸出成SAX2事件流、DOM模型或XML文本文檔。JDOM是在Apache許可證變體下發布的開放源碼。

【優點】

①使用具體類而不是接口,簡化了DOM的API。

②大量使用了Java集合類,方便了Java開發人員。

【缺點】

①沒有較好的靈活性。

②性能較差。

4. DOM4J(Document Object Model for Java)

雖然DOM4J代表了完全獨立的開發結果,但最初,它是JDOM的一種智能分支。它合并了許多超出基本XML文檔表示的功能,包括集成的XPath支持、XML Schema支持以及用于大文檔或流化文檔的基于事件的處理。它還提供了構建文檔表示的選項,它通過DOM4J API和標準DOM接口具有并行訪問功能。從2000下半年開始,它就一直處于開發之中。

為支持所有這些功能,DOM4J使用接口和抽象基本類方法。DOM4J大量使用了API中的Collections類,但是在許多情況下,它還提供一些替代方法以允許更好的性能或更直接的編碼方法。直接好處是,雖然DOM4J付出了更復雜的API的代價,但是它提供了比JDOM大得多的靈活性。

在添加靈活性、XPath集成和對大文檔處理的目標時,DOM4J的目標與JDOM是一樣的:針對Java開發者的易用性和直觀操作。它還致力于成為比JDOM更完整的解決方案,實現在本質上處理所有Java/XML問題的目標。在完成該目標時,它比JDOM更少強調防止不正確的應用程序行為。

DOM4J是一個非常非常優秀的Java XML API,具有性能優異、功能強大和極端易用使用的特點,同時它也是一個開放源代碼的軟件。如今你可以看到越來越多的Java軟件都在使用DOM4J來讀寫XML,特別值得一提的是連Sun的JAXM也在用DOM4J.

【優點】

①大量使用了Java集合類,方便Java開發人員,同時提供一些提高性能的替代方法。

②支持XPath。

③有很好的性能。

【缺點】

①大量使用了接口,API較為復雜。

二、比較

1. DOM4J性能最好,連Sun的JAXM也在用DOM4J。目前許多開源項目中大量采用DOM4J,例如大名鼎鼎的Hibernate也用DOM4J來讀取XML配置文件。如果不考慮可移植性,那就采用DOM4J.

2. JDOM和DOM在性能測試時表現不佳,在測試10M文檔時內存溢出,但可移植。在小文檔情況下還值得考慮使用DOM和JDOM.雖然JDOM的開發者已經說明他們期望在正式發行版前專注性能問題,但是從性能觀點來看,它確實沒有值得推薦之處。另外,DOM仍是一個非常好的選擇。DOM實現廣泛應用于多種編程語言。它還是許多其它與XML相關的標準的基礎,因為它正式獲得W3C推薦(與基于非標準的Java模型相對),所以在某些類型的項目中可能也需要它(如在JavaScript中使用DOM)。

3. SAX表現較好,這要依賴于它特定的解析方式-事件驅動。一個SAX檢測即將到來的XML流,但并沒有載入到內存(當然當XML流被讀入時,會有部分文檔暫時隱藏在內存中)。

我的看法:如果XML文檔較大且不考慮移植性問題建議采用DOM4J;如果XML文檔較小則建議采用JDOM;如果需要及時處理而不需要保存數據則考慮SAX。但無論如何,還是那句話:適合自己的才是最好的,如果時間允許,建議大家講這四種方法都嘗試一遍然后選擇一種適合自己的即可。

298.char型變量中能不能存儲一個中文漢字?

答:1.java采用unicode編碼,2個字節(16位)來表示一個字符, 無論是漢字還是數字,字母,或其他語言都可以存儲。

2.char 在java中是2個字節,所以可以存儲中文

299.一個類可以實現多個接口,但只能繼承一個抽象類。

下面接著再說說兩者在應用上的區別:

接口更多的是在系統架構設計方法發揮作用,主要用于定義模塊之間的通信契約。而抽象類在代碼實現方面發揮作用,可以實現代碼的重用,例如,模板方法設計模式是抽象類的一個典型應用,假設某個項目的所有Servlet類都要用相同的方式進行權限判斷、記錄訪問日志和處理異常,那么就可以定義一個抽象的基類,讓所有的Servlet都繼承這個抽象基類,在抽象基類的service方法中完成權限判斷、記錄訪問日志和處理異常的代碼,在各個子類中只是完成各自的業務邏輯代碼,偽代碼如下:

public abstract classBaseServlet extends HttpServlet{
        public final void service(HttpServletRequest request,HttpServletResponse response) throws IOExcetion,ServletException       {
               記錄訪問日志
               進行權限判斷
if(具有權限){
       try{
              doService(request,response);
}
       catch(Excetpion e)  {
                     記錄異常信息
       }
}
        }
        protected abstract void doService(HttpServletRequest request,HttpServletResponse response) throws IOExcetion,ServletException;
//注意訪問權限定義成protected,顯得既專業,又嚴謹,因為它是專門給子類用的
}

public class MyServlet1 extendsBaseServlet
{
protected voiddoService(HttpServletRequest request, HttpServletResponse response) throwsIOExcetion,ServletException
        {
               本Servlet只處理的具體業務邏輯代碼
        }

}

父類方法中間的某段代碼不確定,留給子類干,就用模板方法設計模式。

備注:這道題的思路是先從總體解釋抽象類和接口的基本概念,然后再比較兩者的語法細節,最后再說兩者的應用區別。比較兩者語法細節區別的條理是:先從一個類中的構造方法、普通成員變量和方法(包括抽象方法),靜態變量和方法,繼承性等6個方面逐一去比較回答,接著從第三者繼承的角度的回答,特別是最后用了一個典型的例子來展現自己深厚的技術功底。

300.比較一下Java 和JavaSciprt

答:JavaScript 與Java是兩個公司開發的不同的兩個產品。Java 是原Sun 公司推出的面向對象的程序設計語言,特別適合于互聯網應用程序開發;而JavaScript是Netscape公司的產品,為了擴展Netscape瀏覽器的功能而開發的一種可以嵌入Web頁面中運行的基于對象和事件驅動的解釋性語言,它的前身是LiveScript;而Java 的前身是Oak語言。

下面對兩種語言間的異同作如下比較:

1)基于對象和面向對象:Java是一種真正的面向對象的語言,即使是開發簡單的程序,必須設計對象;JavaScript是種腳本語言,它可以用來制作與網絡無關的,與用戶交互作用的復雜軟件。它是一種基于對象(Object-Based)和事件驅動(Event-Driven)的編程語言。因而它本身提供了非常豐富的內部對象供設計人員使用;

2)解釋和編譯:Java 的源代碼在執行之前,必須經過編譯;JavaScript 是一種解釋性編程語言,其源代碼不需經過編譯,由瀏覽器解釋執行;

3)強類型變量和類型弱變量:Java采用強類型變量檢查,即所有變量在編譯之前必須作聲明;JavaScript中變量聲明,采用其弱類型。即變量在使用前不需作聲明,而是解釋器在運行時檢查其數據類型;

4)代碼格式不一樣。

補充:上面列出的四點是原來所謂的標準答案中給出的。其實Java和JavaScript最重要的區別是一個是靜態語言,一個是動態語言。目前的編程語言的發展趨勢是函數式語言和動態語言。在Java中類(class)是一等公民,而JavaScript中函數(function)是一等公民。對于這種問題,在面試時還是用自己的語言回答會更加靠譜。?

301.什么時候用assert?

答:assertion(斷言)在軟件開發中是一種常用的調試方式,很多開發語言中都支持這種機制。一般來說,assertion用于保證程序最基本、關鍵的正確性。assertion檢查通常在開發和測試時開啟。為了提高性能,在軟件發布后, assertion檢查通常是關閉的。在實現中,斷言是一個包含布爾表達式的語句,在執行這個語句時假定該表達式為true;如果表達式計算為false,那么系統會報告一個AssertionError。

斷言用于調試目的:

assert(a > 0); // throws an AssertionError if a <= 0

斷言可以有兩種形式:

assert Expression1;

assert Expression1 : Expression2 ;

Expression1 應該總是產生一個布爾值。

Expression2 可以是得出一個值的任意表達式;這個值用于生成顯示更多調試信息的字符串消息。

斷言在默認情況下是禁用的,要在編譯時啟用斷言,需使用source 1.4 標記:

javac -source 1.4 Test.java

要在運行時啟用斷言,可使用-enableassertions 或者-ea 標記。

要在運行時選擇禁用斷言,可使用-da 或者-disableassertions 標記。

要在系統類中啟用斷言,可使用-esa 或者-dsa 標記。還可以在包的基礎上啟用或者禁用斷言??梢栽陬A計正常情況下不會到達的任何位置上放置斷言。斷言可以用于驗證傳遞給私有方法的參數。不過,斷言不應該用于驗證傳遞給公有方法的參數,因為不管是否啟用了斷言,公有方法都必須檢查其參數。不過,既可以在公有方法中,也可以在非公有方法中利用斷言測試后置條件。另外,斷言不應該以任何方式改變程序的狀態。?

302.UML是什么?UML中有哪些圖?

答:UML是統一建模語言(Unified Modeling Language)的縮寫,它發表于1997年,綜合了當時已經存在的面向對象的建模語言、方法和過程,是一個支持模型化和軟件系統開發的圖形化語言,為軟件開發的所有階段提供模型化和可視化支持。使用UML可以幫助溝通與交流,輔助應用設計和文檔的生成,還能夠闡釋系統的結構和行為。UML定義了多種圖形化的符號來描述軟件系統部分或全部的靜態結構和動態結構,包括:用例圖(use case diagram)、類圖(class diagram)、時序圖(sequence diagram)、協作圖(collaboration diagram)、狀態圖(statechart diagram)、活動圖(activity diagram)、構件圖(component diagram)、部署圖(deployment diagram)等。在這些圖形化符號中,有三種圖最為重要,分別是:用例圖(用來捕獲需求,描述系統的功能,通過該圖可以迅速的了解系統的功能模塊及其關系)、類圖(描述類以及類與類之間的關系,通過該圖可以快速了解系統)、時序圖(描述執行特定任務時對象之間的交互關系以及執行順序,通過該圖可以了解對象能接收的消息也就是說對象能夠向外界提供的服務)。

用例圖:

303.XML 文檔定義有幾種形式?它們之間有何本質區別?解析XML 文檔有哪幾種方式?

答: XML文檔定義分為DTD和Schema兩種形式;其本質區別在于Schema本身也是一個XML文件,可以被XML解析器解析。對XML的解析主要有DOM(文檔對象模型)、SAX、StAX(JDK 1.6中引入的新的解析XML的方式,Streaming API for XML) 等,其中DOM處理大型文件時其性能下降的非常厲害,這個問題是由DOM 的樹結構所造成的,這種結構占用的內存較多,而且DOM 必須在解析文件之前把整個文檔裝入內存,適合對XML 的隨機訪問(典型的用空間換取時間的策略);SAX是事件驅動型的XML解析方式,它順序讀取XML文件,不需要一次全部裝載整個文件。當遇到像文件開頭,文檔結束,或者標簽開頭與標簽結束時,它會觸發一個事件,用戶通過在其回調事件中寫入處理代碼來處理XML文件,適合對XML 的順序訪問;如其名稱所暗示的那樣,StAX把重點放在流上。實際上,StAX與其他方法的區別就在于應用程序能夠把XML作為一個事件流來處理。將XML作為一組事件來處理的想法并不新穎(事實上 SAX 已經提出來了),但不同之處在于StAX允許應用程序代碼把這些事件逐個拉出來,而不用提供在解析器方便時從解析器中接收事件的處理程序。?

304.你在項目中哪些地方用到了XML?

答: XML的主要作用有兩個方面:數據交換(曾經被稱為業界數據交換的事實標準,現在此項功能在很多時候都被JSON取代)和信息配置。在做數據交換時,XML將數據用標簽組裝成起來,然后壓縮打包加密后通過網絡傳送給接收者,接收解密與解壓縮后再從XML文件中還原相關信息進行處理。目前很多軟件都使用XML來存儲配置信息,很多項目中我們通常也會將作為配置的硬代碼(hard code)寫在XML文件中,Java的很多框架也是這么做的。?

305.用JavaScript實現用正則表達式驗證,某個字符串是合法的6位數字的郵編的函數
Function testE(ss){
  var reg=/^[1-9][0-9]{5}$/;
  if(req.test(ss)){
    alert(“郵編OK”)
}else{
  alert(“郵編格式不正確”);
}
}
306.請使用JQuery將頁面上的所有元素邊框設置為2pix寬的虛線?

$(“*”).css(“border”,”2px dashed”)

307.如何設定JQuery異步調用還是同步調用?

答案:調用jQuery中的ajax函數,設置其async屬性來表明是異步還是同步,如下:

$.ajax({
async:true//表示異步,false表示同步
})

308.說出3條以上firefox和IE的瀏覽器兼容問題?

答案:兼容firefox的 outerHTML,FF中沒有outerHtml的方法

IE下,可以使用()或[]獲取集合類對象;Firefox下,只能使用[]獲取集合類對象.解決方法:統一使用[]獲取集合類對象.

IE下,可以使用獲取常規屬性的方法來獲取自定義屬性,也可以使用getAttribute()獲取自定義屬性;Firefox下,只能使用getAttribute()獲取自定義屬性.解決方法:統一通過getAttribute()獲取自定義屬性

309.請用Jquery語言寫出ajax請求或者post請求代碼
$.post(“show”,{uname=”張三”,pwd=”123”},function(data){
  alert(data)
})
310.body中的onload ()函數和jQuery中document.ready()有什么區別?

答案:ready 事件的觸發,表示文檔結構已經加載完成(不包含圖片等非文字媒體文件)

onload 事件的觸發,表示頁面包含圖片等文件在內的所有元素都加載完成。

311.jQuery中有哪幾種類型的選擇器?

答案:

基本選擇器

層次選擇器

基本過濾選擇器

內容過濾選擇器

可見性過濾選擇器

屬性過濾選擇器

子元素過濾選擇器

表單選擇器

表單過濾選擇器

312.EasyUI中datagrid刷新當前數據的方法?

答案:使用reload()即可

313.分別寫出一個div居中和其中的內容居中的css屬性設置

Div居中:

margin:auto 0px;

內容居中:

text-align:center;

314.概述一下session與cookie的區別

答案:

存儲角度:

Session是服務器端的數據存儲技術,cookie是客戶端的數據存儲技術

解決問題角度:

Session解決的是一個用戶不同請求的數據共享問題,cookie解決的是不同請求的請求數據的共享問題

生命周期角度:

Session的id是依賴于cookie來進行存儲的,瀏覽器關閉id就會失效

Cookie可以單獨的設置其在瀏覽器的存儲時間。

315.JavaScript 中 null和 undefined 是否有區別?有哪些區別?

答案:

賦值角度說明:

null 表示此處沒有值,undefined表示此處定義了但是沒有賦值

從數據轉換角度:

Null在做數值轉換時會被轉換為0,undefined會被轉換為NaN

316.Servlet中的doPost和doGet方法有什么區別?它們在傳遞和獲取參數上有什么區別?

答案:

區別:doPost用來處理post請求,doGet用來處理get請求,獲取參數:獲取的參數是相同的都是HttpServletRequest \HttpServletResponse

317.請寫出一段jQuery代碼,實現把當前頁面中所有的a元索中class 屬性為“view-link”的鏈接都改為在新窗口中打開

答案:$(“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返回的是一個jquery對象 get返回的是一個html對象

320.如何給weblogic定內存的大???

在啟動Weblogic的腳本中(位于所在Domian對應服務器目錄下的startServerName),增加set MEM_ARGS=-Xms32m -Xmx200m,可以調整最小內存為32M,最大200M

321.TCP為何采用三次握手來建立連接,若釆用二次握手可以嗎,請說明理由?

三次握手是為了防止已失效的連接請求再次傳送到服務器端。 二次握手不可行,因為:如果由于網絡不穩定,雖然客戶端以前發送的連接請求以到達服務方,但服務方的同意連接的應答未能到達客戶端。則客戶方要重新發送連接請求,若采用二次握手,服務方收到重傳的請求連接后,會以為是新的請求,就會發送同意連接報文,并新開進程提供服務,這樣會造成服務方資源的無謂浪費

322.以下HTTP相應狀態碼的含義描述正確的是()
A. 200ok表示請求成功
B. 400不良請求表示服務器未發現與請求URL匹配內容
C. 404未發現表示由于語法錯誤兒導致服務器無法理解請求信息
D. 500內部服務器錯誤,無法處理請求
答案:D
分析:
A 200ok 表示的意思是一切正常。一般用于相應GET和POST請求。這個狀態碼對servlet是缺省的;如果沒有調用setStatus方法的話,就會得到200。
B 400 表示指出客戶端請求中的語法錯誤
C 404 客戶端所給的地址無法找到任何資源
323.JSP頁面包括哪些元素?()
A. JSP命令
B. JSP Action
C. JSP腳本
D. JSP控件
答案:C
分析:JSP頁面元素構成如下,因此ABD錯誤
A 200ok 表示的意思是一切正常。一般用于相應GET和POST請求。這個狀態碼對servlet是缺省的;如果沒有調用setStatus方法的話,就會得到200。
B 400 表示指出客戶端請求中的語法錯誤
C 404 客戶端所給的地址無法找到任何資源
324.Ajax有四種技術組成:DOM,CSS,JavaScript,XmlHttpRequest,其中控制文檔結構的是()
A. DOM
B. CSS
C. JavaScript
D. XmlHttpRequest
答案:A
325.下面關于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類型的對象。 該對象代表了客戶端的請求信息,主要用于接受通過HTTP協議傳送到服務器的數據。(包括頭信息、系統信息、請求方式以及請求參數等)。request對象的作用域為一次請求。

2、response對象

response 代表的是對客戶端的響應,主要是將JSP容器處理過的對象傳回到客戶端。response對象也具有作用域,它只在JSP頁面內有效。

3、session對象

session 對象是由服務器自動創建的與用戶請求相關的對象。服務器為每個用戶都生成一個session對象,用于保存該用戶的信息,跟蹤用戶的操作狀態。session對象內部使用Map類來保存數據,因此保存數據的格式為 “Key/value”。 session對象的value可以使復雜的對象類型,而不僅僅局限于字符串類型。

4、application對象

?application 對象可將信息保存在服務器中,直到服務器關閉,否則application對象中保存的信息會在整個應用中都有效。與session對象相比,application對象生命周期更長,類似于系統的“全局變量”。

5、out 對象

out 對象用于在Web瀏覽器內輸出信息,并且管理應用服務器上的輸出緩沖區。在使用 out 對象輸出數據時,可以對數據緩沖區進行操作,及時清除緩沖區中的殘余數據,為其他的輸出讓出緩沖空間。待數據輸出完畢后,要及時關閉輸出流。

6、pageContext 對象

pageContext 對象的作用是取得任何范圍的參數,通過它可以獲取 JSP頁面的out、request、reponse、session、application 等對象。pageContext對象的創建和初始化都是由容器來完成的,在JSP頁面中可以直接使用 pageContext對象。

7、config 對象

config 對象的主要作用是取得服務器的配置信息。通過 pageConext對象的 getServletConfig() 方法可以獲取一個config對象。當一個Servlet 初始化時,容器把某些信息通過 config對象傳遞給這個 Servlet。 開發者可以在web.xml 文件中為應用程序環境中的Servlet程序和JSP頁面提供初始化參數。

8、page 對象

page 對象代表JSP本身,只有在JSP頁面內才是合法的。 page隱含對象本質上包含當前 Servlet接口引用的變量,類似于Java編程中的 this 指針。

9、exception 對象

exception 對象的作用是顯示異常信息,只有在包含 isErrorPage="true" 的頁面中才可以被使用,在一般的JSP頁面中使用該對象將無法編譯JSP文件。excepation對象和Java的所有對象一樣,都具有系統提供的繼承結構。exception 對象幾乎定義了所有異常情況。在Java程序中,可以使用try/catch關鍵字來處理異常情況; 如果在JSP頁面中出現沒有捕獲到的異常,就會生成 exception 對象,并把 exception 對象傳送到在page指令中設定的錯誤頁面中,然后在錯誤頁面中處理相應的 exception 對象。

327.如何配置一個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語句會產生運行錯誤的是_()
A. var obj=( );
B. var obj=[ ];
C. var obj=//;
D. var obj=1;
答案:AC
330.在JSP中,下面__()__塊中可以定義一個新類:
A. <% %>
B. <% ! %>
C. <%@ %>
D. <%=%>
答案:B
分析:B <% ! %> 可用作聲明
A不正確
C為引用xxx,比如<% @page xxxxx%>
D為表達式
331.HTML含義和版本變化

HTML含義:

Hyper Text Markup Language 超文本標記語言,是一種用來制作“網頁”的簡單標記語言;用HTML編寫的超文本文檔稱為HTML文檔,HTML文檔的擴展名是html或者htm

版本變化:

HTML1.0——在1993年6月作為IETF工作草案發布(并非標準)

HTML 2.0——1995年11月作為RFC 1866發布

HTML 3.2——1997年1月14日,W3C推薦標準

HTML 4.0——1997年12月18日,W3C推薦標準

HTML 4.01(微小改進)——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到頁面的某個位置,適用于頁面內容較多,超過一屏的場合 。分為頁面內的錨鏈接和頁面間的錨鏈接 。

例如:1F2F

跳轉到2F標記位置

說明:

1.在標記位置利用a標簽的name屬性設置標記。

2.在導航位置通過a標簽的href屬性用#開頭加name屬性值即可跳轉錨點位置。

333.HTML字符實體的作用及其常用字符實體

有些字符,比如說“<”字符,在HTML中有特殊的含義,因此不能在文本中使用。想要在HTML中顯示一個小于號“<”,需要用到字符實體:<或者<

字符實體擁有三個部分:一個and符號(&),一個實體名或者一個實體號,最后是一個分號(;)

常用字符實體:

顯示結果 描述 實體 實體號
空格    
< 小于 < <
> 大于 > &#
& and符號 & &
' 單引號 ' (IE不支持) '
" 引號 " "
英鎊 £ £
人民幣元 ¥ ¥
§ 章節 ¥ ¥
? 版權 © ©
334.HTML表單的作用和常用表單項類型

表單的作用:

利用表單可以收集客戶端提交的有關信息。

常用表單項類型:

input標簽
type屬性
功能 input標簽
type屬性
功能
text 單行本框 reset 重置按鈕
password 密碼框 submit 提交按鈕
radio 單選按鈕 textarea 文本域
checkbox 復選框 select 下拉框
button 普通按鈕 hidden 隱藏域

335.表格、框架、div三種HTML布局方式的特點

優點 缺點 應用場合
表格 方便排列有規律、結構均勻的內容或數據 產生垃圾代碼、影響頁面下載時間、靈活性不大難于修改 內容或數據整齊的頁面
框架 支持滾動條、方便導航 節省頁面下載時間等 兼容性不好,保存時不方便、應用范圍有限 小型商業網站、論壇后臺管理
Div 代碼精簡、提高頁面下載速度、表現和內容分離 比較靈活、難于控制 復雜的不規則頁面、業務種類較多的大型商業網站

336.form中input設置為readonly和disabled的區別

readonly disabled
有效對象 .只針對type為text/password有效 對所有表單元素有效
表單提交 當表單元素設置readonly后,表單提交能將該表單元素的值傳遞出去。 當表單元素設置disabled后,表單提交不能將該表單元素的值傳遞出去。

337.CSS的定義和作用

CSS的定義:CSS是Cascading Style Sheets(層疊樣式表)的簡稱。

CSS是一系列格式規則,它們控制網頁內容的外觀。CSS簡單來說就是用來美化網頁用的。

CSS的具體作用包括:

使網頁豐富多彩,易于控制。

頁面的精確控制,實現精美、復雜頁面 。

338.CSS2常用選擇器類型及其含義

選擇器名稱 案例 語法格式
標簽選擇器 h3{font-size:24px;font-family:"隸書“; }< h3>JSP< /h3> 元素標簽名{樣式屬性}
類選擇器 .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.引入樣式的三種方式及其優先級別

三種引用方式:

1. 外部樣式表(存放.css文件中)

不需要style標簽

< link rel=”stylesheet” href=”引用文件地址” />

2. 嵌入式樣式表

< style type=“text/css”>

p{color:red;}

< /style>

3.內聯樣式

標簽屬性名為style

< p style=“color:red;”>< /p>

優先級級別:內聯定義最高、內部CSS次之、外部CSS優先級最低。。

340.盒子模型

盒子模型類似于生活中的盒子,具有4個屬性,外邊距,內邊距,邊框,內容。

外邊距:margin,用于設置元素和其他元素之間的距離。

內邊距:padding,用于設置元素內容和邊框之間的距離。

邊框:border,用于設置元素邊框粗細,顏色,線型。

內容: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語言及其特點

Javascript一種基于對象(object-based)和事件驅動(Event Driven)的簡單的并具有安全性能的腳本語言。特點:

解釋性: JavaScript不同于一些編譯性的程序語言,例如C、C++等,它是一種解釋性的程序語言,它的源代碼不需要經過編譯,而直接在瀏覽器中運行時被解釋。

基于對象:?JavaScript是一種基于對象的語言。這意味著它能運用自己已經創建的對象。因此,許多功能可以來自于腳本環境中對象的方法與腳本的相互作用。

事件驅動: JavaScript可以直接對用戶或客戶輸入做出響應,無須經過Web服務程序。它對用戶的響應,是以事件驅動的方式進行的。所謂事件驅動,就是指在主頁中執行了某種操作所產生的動作,此動作稱為“事件”。比如按下鼠標、移動窗口、選擇菜單等都可以視為事件。當事件發生后,可能會引起相應的事件響應。

跨平臺:JavaScript依賴于瀏覽器本身,與操作環境無關,只要能運行瀏覽器的計算機,并支持JavaScript的瀏覽器就可正確執行。

342.JavaScript常用數據類型有哪些

1、數值型(Number):整數和浮點數統稱為數值。例如85或3.1415926等。

2、字符串型(String):由0個,1個或多個字符組成的序列。在JavaScript中,用雙引號或單引號括起來表示,如“您好”、‘學習JavaScript’等。 不區分單引號、雙引號。

3、邏輯(布爾)型(Boolean):用true或false來表示。

4、空(null)值(Null):表示沒有值,用于定義空的或不存在的引用。

要注意,空值不等同于空字符串""或0。

5、未定義(Undefined)值:它也是一個保留字。表示變量雖然已經聲明,但卻沒有賦值。

除了以上五種基本的數據類型之外,JavaScript還支持復合數據類型,包括對象和數組兩種。

343.html語法中哪條命令用于使一行文本折行,而不是插入一個新的段落? (B)

A. < TD>
B. < BR>
C. < P>
D. < H1>
分析:
A < td>定義標準表格
C < p>表示文本一個段落
D < h1>表示對文本標題進行強調的一種標簽

344.Ajax的優點和缺點

優點:減輕服務器的負擔,按需取數據,最大程度的減少冗余請求,局部刷新頁面,減少用戶心理和實際的等待時間,帶來更好的用戶體驗,基于xml標準化,并被廣泛支持,不需安裝插件等,進一步促進頁面和數據的分離

缺點:AJAX大量的使用了javascript和ajax引擎,這些取決于瀏覽器的支持.在編寫的時候考慮對瀏覽器的兼容性.

345.怎樣防止表單刷新重復提交問題?(說出思路即可)

JS腳本方式:

第一種:定義全局變量,在form提交前判斷是否已有提交過

<script>
   var checkSubmitFlg = false;
   function checkSubmit(){
     if(checkSubmitFlg == true){
return false;
     }
     checkSubmitFlg = true;
     return true;
  }
 </script>
<form action="" onsubmit="return checkSubmit();">
</form>

第二種:單擊提交按鈕后,立刻禁用改按鈕

第三種:單擊提交按鈕后,彈出屏蔽層,防止用戶第二次點擊

346.JQuery.get()和JQuery.ajax()方法之間的區別是什么?

JQuery.ajax()是對原生的javaScript的ajax的封裝,簡化了ajax的步驟,用戶可用JQuery.ajax()發送get或者post方式請求,Jquery.get()是對ajax的get方式的封裝,只能發送get方式的請求。

347.Jquery里的緩存問題如何解決?例如($.ajax()以及$.get())

$.ajax()請求時候加上cache:false的參數,如:

$.ajax({
    type : "get",
    url : "XX",
    dataType : "json",
    cache:false,
    success : function(json) {
    }
});

$.get()請求時候加上時間,如:

$.get("url","data"+new Date(),function(data){});

348.Javascript是面向對象的,怎么體現Javascript的繼承關系?

Javascript里面沒有像java那樣的繼承,javascript中的繼承機制僅僅是靠模擬的,可以使用prototype原型來實現

349.Javascript的有幾種種變量。變量范圍有什么不同?

可以分為三種

1、原生類型(string,number,boolean)

2、對象(Date,Array)

3、特殊類型(var vara;(只什么沒有定義),var varb = null;(定義一個變量并賦值為null))

350.Js如何獲取頁面的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 父子關系 --childNodes

var varchilds = document.getElementById("div01").childNodes;

//2.2 子父關系--parentNode

var varfather2 = document.getElementById("unameid").parentNode;

//2.3 兄弟之間相互獲取 nextSibling:下一個節點 previousSibling:上一個節點

351.Servlet API中forward() 與redirect()的區別?

答:為實現程序的模塊化,就需要保證在不同的Servlet之間可以相互跳轉,而Servlet中主要有兩種實現跳轉的方式:FORWARD方式與redirect方式。?

Forward() : 是服務器內部的重定向,服務器直接訪問目標地址的URL,把那個URL的響應內容讀取出來,而客戶端并不知道,因此在客戶端瀏覽器的地址欄里不會顯示跳轉后的地址,還是原來的地址。由于在整個定向的過程中用的是同一個Request,因此FORWARD會將Request的信息帶到被定向的JSP或Servlet中使用。

Redirect():則是客戶端的重定向,是完全的跳轉,即客戶端瀏覽器會獲取跳轉后的地址,然后重新發送請求,因此瀏覽器中會顯示跳轉后的地址。同時,由于這種方式比FORWARD方式多了一次網絡請求,因此其效率低于FORWARD方式,需要注意到的是,客戶端的重定向可以通過設置特定的HTTP 頭或寫JavaScript腳本來實現。

鑒于以上的區別,一般當FORWARD方式可以滿足需求時,盡可能的使用FORWARD方式。但在有些情況下,例如,需要跳轉到一個其他服務器上的資源時,則必須使用redirect 方式。

352.Session域和request域什么區別?

作用域:存放數據,獲取數據(傳遞數據)

有效的作用域:生命周期,作用范圍

httpServeltRequest:

生命周期:一次請求之間

作用范圍:所有被請求轉發過的servlet都能獲取到

httpSession:

生命周期:一次會話

作用范圍:所有的servlet都可以獲取到

servletContex:

生命周期:從項目開始運行到服務器關閉

作用范圍:所有的servlet都可以獲取到?

作用域如何選用?

httpServeltRequest:和當前請求有關的信息

httpSession:和當前用戶有關的信息

servletContex:訪問量比較大,不易更改

353.頁面中有一個命名為bankNo的下拉列表,寫js腳本獲取當前選項的索引值,如果用jquery如何獲取

var a = document.getElementsByName("bankNo")[0].value;

var b = $("select[name=bankNo]").val();

354.寫出要求11位數字的正則表達式

^[1-9]\d{10}$

355.分別獲取指定name、Id的javascript對象,如果用jquey如何獲取

js:
  id--document.getElementById("id");
  name--document.getElementsByName("name");
jquery
  id--$("#id");
  name--$("元素名稱[name="name值"]");

356.一個頁面有兩個form,如何獲取第一個form

用id方式獲??;document.getElementById("id");

357.如何設置一個層的可見/隱藏

可見 : document.getElementById("divid").style.display = "block";

隱藏 : document.getElementById("divid").style.display = "none";

358.描述JSP中動態INCLUDE與靜態INCLUDE的區別?

動態導入

1、會將多個jsp頁面分別再編寫成java文件,編譯成class文件

2、jsp文件中允許有相同的變量名,每個頁面互不影響

3、當java代碼比較多優先選用動態導入

4、效率相對較低,耦合性低

靜態導入

1、會將多個jsp頁面合成一個jsp頁面,再編寫成java文件,編譯成class文件

2、jsp文件中不允許有相同的變量名

3、當java代碼比較少或者沒有java代碼是優先選用靜態導入

4、效率相對較高,耦合性高

359.列舉JSP的內置對象及方法

request表示HttpServletRequest對象。它包含了有關瀏覽器請求的信息,并且提供了幾個用于獲取cookie,?header,?和session數據的有用的方法。?

response表示HttpServletResponse對象,并提供了幾個用于設置送回?瀏覽器的響應的方法(如cookies,頭信息等)?

out對象是javax.jsp.JspWriter的一個實例,提供了幾個方法使你能用于向瀏覽器回送輸出結果

pageContext表示一個javax.servlejt.sp.PageContext對象。它是用于方便存取各種范圍的名字空間、servlet相關的對象的API,并且包裝了通用的servlet相關功能的方法。?

session表示一個請求的javax.servlet.http.HttpSession對象。Session可以存貯用戶的狀態信息

applicaton?表示一個javax.servle.ServletContext對象。這有助于查找有關servlet引擎和servlet環境的信息?

config表示一個javax.servlet.ServletConfig對象。該對象用于存取servlet實例的初始化參數。?

page表示從該頁面產生的一個servlet實例

Exception異常

360.列舉jsp的四大作用域

page、request、session、application

361.html和xhtml的區別是什么?

HTML與XHTML之間的差別,粗略可以分為兩大類比較:一個是功能上的差別,另外是書寫習慣的差別。關于功能上的差別,主要是XHTML可兼容各大瀏覽器、手機以及PDA,并且瀏覽器也能快速正確地編譯網頁。

因為XHTML的語法較為嚴謹, 所以如果你是習慣松散結構的HTML編寫者,那需要特別注意XHTML的規則。但也不必太過擔心,因為XHTML的規則并不太難。下面列出了幾條容易犯的錯誤,供大家引用。

1:所有標簽都必須小寫

在XHTML中,所有的標簽都必須小寫,不能大小寫穿插其中,也不能全部都是大寫??匆粋€例子。

錯誤:< Head>< /Head>< Body>< /Body>

正確:< head>< /head>< body>< /body>

2:標簽必須成雙成對

像是< p>...< /p>、< a>...< /a>、< div>...< /div>標簽等,當出現一個標簽時,必須要有對應的結束標簽,缺一不可,就像在任何程序語言中的括號一樣。

錯誤:大家好< p>我是muki

正確:< p>大家好< /p>< p>我是muki< /p>

3:標簽順序必須正確

標簽由外到內,一層層包覆著,所以假設你先寫div后寫h1,結尾就要先寫h1后寫div。只要記住一個原則“先進后出”,先彈出的標簽要后結尾。

錯誤:< 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開始全面禁止target屬性,如果想要有開新窗口的功能,就必須改寫為rel="external",并搭配JavaScript實現此效果。

錯誤:< a target="_blank">MUKI space< /a>

正確:< a rel="external">MUKI space< /a>

362.你做的頁面用哪些瀏覽器測試過?這些測試的內核分別是什么?

1、Trident內核代表產品Internet Explorer,又稱其為IE內核。?Trident(又稱為MSHTML),是微軟開發的一種排版引擎。使用Trident渲染引擎的瀏覽器包括:IE、傲游、世界之窗瀏覽器、Avant、騰訊TT、Netscape 8、NetCaptor、Sleipnir、GOSURF、GreenBrowser和KKman等。?

2、Gecko內核代表作品Mozilla?,FirefoxGecko是一套開放源代碼的、以C++編寫的網頁排版引擎。Gecko是最流行的排版引擎之一,僅次于Trident。使用它的最著名瀏覽器有Firefox、Netscape6至9

3、WebKit內核代表作品Safari、Chromewebkit?, 是一個開源項目,包含了來自KDE項目和蘋果公司的一些組件,主要用于Mac OS系統,它的特點在于源碼結構清晰、渲染速度極快。缺點是對網頁代碼的兼容性不高,導致一些編寫不標準的網頁無法正常顯示。主要代表作品有Safari和Google的瀏覽器Chrome。?

4、Presto內核代表作品OperaPresto,?是由Opera Software開發的瀏覽器排版引擎,供Opera 7.0及以上使用。它取代了舊版Opera 4至6版本使用的Elektra排版引擎,包括加入動態功能,例如網頁或其部分可隨著DOM及Script語法的事件而重新排版。

363.你遇到了哪些瀏覽器的兼容性問題?怎么解決的?

答:因為不同的瀏覽器對同一段代碼有不同的解析,造成頁面顯示效果不統一的情況;這是我們常見的兼容性問題。

解決方法:

1、針對不同的瀏覽器寫不同的代碼

2、使用jquery屏蔽瀏覽器差異

遇到不同的兼容問題,需要針對前端進行兼容適配;

364.你知道的常用的js庫有哪些?

1.moment.js

舉個例子:

用js轉換時間戳為日期

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

繪制簡單的柱狀圖,曲線圖,蛛網圖,環形圖,餅圖等完全夠用,用法比較簡單。

3.D3.js

功能太強大了,看首頁就知道了,感覺沒有什么圖d3繪不出來的。

4.Rx.js

很好的解決了異步和事件組合的問題。

5.lodash.js

365.Js中的三種彈出式消息提醒(警告窗口、確認窗口、信息輸入窗口)的命令是什么?

alter(),confirm(),prompt()

366.談談js的閉包

答:閉包無處不在,比如:jQuery、zepto的核心代碼都包含在一個大的閉包中,所以下面我先寫一個最簡單最原始的閉包,以便讓你在大腦里產生閉包的畫面:

function A(){
function B(){
console.log("Hello Closure!");
}
return B;
}
var C = A();
C();//Hello Closure!

這是最簡單的閉包。

有了初步認識后,我們簡單分析一下它和普通函數有什么不同,上面代碼翻譯成自然語言如下:

(1)定義普通函數 A

(2)在 A 中定義普通函數 B

(3)在 A 中返回 B

(4)執行 A, 并把 A 的返回結果賦值給變量 C

(5)執行 C

把這5步操作總結成一句話就是:

函數A的內部函數B被函數A外的一個變量 c 引用。

把這句話再加工一下就變成了閉包的定義:

當一個內部函數被其外部函數之外的變量引用時,就形成了一個閉包。

因此,當你執行上述5步操作時,就已經定義了一個閉包!

這就是閉包。

367.寫一段js,遍歷所有的li,將每個li的內容逐個alert出來

<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.頁面上如何用JavaScript對多個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.寫一個簡單的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發送成功后會調用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發送成功后調用的函數)
$.get("TestJqAjax",{uname:"zhangsan",realname:"張三豐"},function(result){
alert(result);
});

}

function  jqAjaxPost() {
//url,[data],[callback](當ajax發送成功后調用的函數)
$.post("TestJqAjax",{uname:"zhangsan",realname:"張三豐"},function(result){
alert(result);
});
}
</script>

370.Js截取字符串abcdefg的efg

function test2(){
var str = "abcdefg";
var substr = str.substring(4);
alert(substr);
}

371.http的請求頭信息包含了什么?

請求行(請求方式,資源路徑,協議和協議版本號)

若干請求頭

請求實體內容

372.http的響應碼200,404,302,500表示的含義分別是?

200 - 確定??蛻舳苏埱笠殉晒?/p>

302 - 臨時移動轉移,請求的內容已臨時移動新的位置

404 - 未找到文件或目錄

500 - 服務器內部錯誤

373.Servlet中request對象的方法有?

/獲取網絡信息
private void getNet(HttpServletRequest req, HttpServletResponse resp) {
System.out.println("TestHttpRequest.getNet(獲取客戶端的ip):"+req.getRemoteAddr());
System.out.println("TestHttpRequest.getNet(獲取客戶端的端口):"+req.getRemotePort());
System.out.println("TestHttpRequest.getNet(獲取服務器的ip):"+req.getLocalAddr());
System.out.println("TestHttpRequest.getNet(獲取服務器的端口):"+req.getLocalPort());

}

//獲取實體內容
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"));
//獲取所有頭信息--返回枚舉類型
Enumeration strHeads = req.getHeaderNames();
//遍歷枚舉類型
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(協議):"+req.getScheme());
System.out.println("TestHttpRequest.getLines(協議的版本號):"+req.getProtocol());
System.out.println("TestHttpRequest.getLines(獲取參數信息):"+req.getQueryString());
System.out.println("TestHttpRequest.getLines(項目名稱***):"+req.getContextPath());
}

374.Javascript的常用對象有哪些

常用對象包括日期對象Date,字符串對象String,數組對象Array

//獲取并顯示系統當前時間

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及其關系

BOM瀏覽器對象模型,由一系列對象組成,是訪問、控制、修改瀏覽器的屬性的方法。

DOM文檔對象模型,由一系列對象組成,是訪問、檢索、修改XHTML文檔內容與結構的標準方法。

關系:

–BOM描述了與瀏覽器進行交互的方法和接口

–DOM描述了處理網頁內容的方法和接口

–DOM屬于BOM的一個屬性

376.JavaScript中獲取某個元素的三種方式JavaScript中的三種彈出式消息提醒命令是什么?

window.alert() 顯示一個提示信息

window.confirm() 顯示一個帶有提示信息、確定和取消按鈕的對話框

window.prompt() 顯示可提示用戶輸入的對話框

setTimeout與setInterval 的區別

setTimeout和setInterval的語法相同。它們都有兩個參數,一個是將要執行的代碼字符串,還有一個是以毫秒為單位的時間間隔,當過了那個時間段之后就將執行那段代碼。

不過這兩個函數還是有區別的,setInterval在執行完一次代碼之后,經過了那個固定的時間間隔,它還會自動重復執行代碼,而setTimeout只執行一次那段代碼。

window.setTimeout("function",time);//設置一個超時對象,只執行一次,無周期

window.setInterval("function",time);//設置一個超時對象,周期='交互時間'

377.JavaScript操作CSS的兩種方式

第一種方式:操作元素的屬性(對象.style.樣式名=樣式值;)

//改變直接樣式

var child2 = document.createElement("div");
    child2.innerHTML = "child2";
    child2.style.fontWeight = "bold";
    parent.appendChild(child2);

第二種方式:操作元素的類(對象.className=類;)

例如:

var parent = document.getElementById("parent");
   //改變className
   var child0 = document.createElement("div");
   child0.innerHTML = "child0";
   child0.className = "newDiv";
parent.appendChild(child0);

378.靜態網頁和動態網頁的聯系和區別

聯系:

1)靜態網頁是網站建設的基礎,靜態網頁和動態網頁都要使用到HTMl語言。

2)靜態網頁是相對于動態網頁而言,指沒有后臺數據庫、不含程序和不可交互的網頁、是標準的HTML文件,它的文件擴展名是.htm或.html。你編的是什么它顯示的就是什么、不會有任何改變。

3)靜態網頁和動態網頁之間并不矛盾,為了網站適應搜索引擎檢索的需要,動態網站可以采用靜動結合的原則,適合采用動態網頁的地方用動態網頁,如果必要使用靜態網頁,則可以考慮用靜態網頁的方法來實現,在同一個網站上,動態網頁內容和靜態網頁內容同時存在也是很常見的事情。

區別:

1)程序是否在服務器端運行,是重要標志。在服務器端運行的程序、網頁、組件,屬于動態網頁,它們會隨不同客戶、不同時間,返回不同的網頁,例如ASP、PHP、JSP、ASP.net、CGI等。運行于客戶端的程序、網頁、插件、組件,屬于靜態網頁,例如html頁、Flash、javascript、VBscript等等,它們是永遠不變的。

2)編程技術不同。靜態網頁和動態網頁主要根據網頁制作的語言來區分。靜態網頁使用語言:HTML。 動態網頁使用語言:HTML+ASP 或 HTML+PHP 或 HTML+JSP 等其它網站動態語言。

3)被搜索引擎收錄情況不同。由于編程技術不容,靜態網頁是純粹HTML格式的網頁,頁面內容穩定,不論是網頁是否被訪問,頁面都被保存在網站服務器上,很容易被搜索引擎收錄。而動態網頁的內容是當用戶點擊請求時才從數據庫中調出返回給用戶一個網頁的內容,并不是存放在服務器上的獨立文件,相比較于靜態網頁而言,動態網頁很難被搜索引擎收錄。

4)用戶訪問速度不同。用戶訪問動態網頁時,網頁在獲得搜索指令后經過數據庫的調查匹配,再將與指令相符的內容傳遞給服務器,通過服務器的編譯將網頁編譯成標準的HTML代碼,從而傳遞給用戶瀏覽器,多個讀取過程大大降低了用戶的訪問速度。而靜態網頁不同,由于網頁內容直接存取在服務器上,省去了服務器的編譯過程,用戶訪問網頁速度很快。

5)制作和后期維護工作量不同。動態網頁的設計以數據庫技術為基礎,可以實現多種功能,降低了網站維護的工作量。而靜態網頁由于沒有數據庫的支持,網頁內容更改時需要直接修改代碼,在網站內容制作和維護中,所需的工作量更大。動態網頁與靜態網頁各有特點,網站設計師在網頁設計時,主要根據網站的功能需求和網站內容多少選擇不同網頁。如,網站包含信息量太大時,就需要選擇動態網頁,反之,則選擇靜態網頁。

379.JSP/ASP/PHP的比較

ASP(Active Server Pages),JSP(JavaServer Pages),PHP(Hypertext Preprocessor)是目前主流的三種動態網頁語言。

ASP是微軟(Microsoft)所開發的一種后臺腳本語言,它的語法和Visual BASIC類似,可以像SSI(Server Side Include)那樣把后臺腳本代碼內嵌到HTML頁面中。雖然ASP簡單易用,但是它自身存在著許多缺陷,最重要的就是安全性問題。

PHP是一種跨平臺的服務器端的嵌入式腳本語言。它大量地借用C,Java和Perl語言的語法, 并耦合PHP自己的特性,使WEB開發者能夠快速地寫出動態產生頁面。它支持目前絕大多數數據庫。

JSP是一個簡化的Servlet,它是由Sun公司倡導、許多公司參與一起建立的一種動態網頁技術標準。JSP技術有點類似ASP技術,它是在傳統的網頁HTML中插入Java程序段和JSP標記(tag),從而形成JSP文件,后綴名為(*.jsp)。 用JSP開發的Web應用是跨平臺的,既能在Linux下運行,也能在其他操作系統上運行。

ASP優點: 無需編譯、易于生成、獨立于瀏覽器、面向對象、與任何ActiveX scripting 語言兼容、源程序碼不會外漏。

缺點:

1)Windows本身的所有問題都會一成不變的也累加到了它的身上。安全性、穩定性、跨平臺性都會因為與NT的捆綁而顯現出來。

2)ASP由于使用了COM組件所以它會變的十分強大,但是這樣的強大由于Windows NT系統最初的設計問題而會引發大量的安全問題。只要在這樣的組件或是操作中一不注意,那么外部攻擊就可以取得相當高的權限而導致網站癱瘓或者數據丟失。

3)還無法完全實現一些企業級的功能:完全的集群、負載均橫。

PHP優點:

1)一種能快速學習、跨平臺、有良好數據庫交互能力的開發語言。

2)簡單輕便,易學易用。

3 ) 與Apache及其它擴展庫結合緊密。

缺點:

1 ) 數據庫支持的極大變化。

2 ) 不適合應用于大型電子商務站點。

JSP優點:

1 ) 一處編寫隨處運行。

2 ) 系統的多臺平支持。

3 ) 強大的的可伸縮性。

4 ) 多樣化和功能強大的開發工具支持。

缺點:

1) 與ASP一樣,Java的一些優勢正是它致命的問題所在。

2 ) 開發速度慢

380.CGI/Servlet/JSP的比較

CGI(Common Gateway Interface),通用網關接口,是一種根據請求信息動態產生回應內容的技術。

通過CGI,Web 服務器可以將根據請求不同啟動不同的外部程序,并將請求內容轉發給該程序,在程序執行結束后,將執行結果作為回應返回給客戶端。也就是說,對于每個請求,都要產生一個新的進程進行處理。

Servlet 是在服務器上運行的小程序。在實際運行的時候Java Servlet與Web服務器會融為一體。與CGI不同的是,Servlet對每個請求都是單獨啟動一個線程,而不是進程。這種處理方式大幅度地降低了系統里的進程數量,提高了系統的并發處理能力。

比較:

1) JSP從本質上說就是Servlet。JSP技術產生于Servlet之后,兩者分工協作,Servlet側重于解決運算和業務邏輯問題,JSP則側重于解決展示問題。

2 ) 與CGI相比,Servlet效率更高。Servlet處于服務器進程中,它通過多線程方式運行其service方法,一個實例可以服務于多個請求,并且其實例一般不會銷毀。而CGI對每個請求都產生新的進程,服務完成后就銷毀,所以效率上低于Servlet 。

3)與CGI相比,Servlet更容易使用,功能更強大,具有更好的可移植性,更節省投資。在未來的技術發展過程中,Servlet有可能徹底取代CGI。

381.HTTP協議工作原理及其特點

超文本傳輸協議(HTTP:Hypertext Transport Protocol)是萬維網應用層的協議,它通過兩個程序實現:一個是客戶端程序(各種瀏覽器),另一個是服務器 (常稱Web服務器) 。這兩個通常運行在不同的主機上,通過交換報文來完成網頁請求和響應,報文可簡單分為請求報文和響應報文。

工作原理(流程):

客戶機與服務器建立連接后,瀏覽器可以向web服務器發送請求并顯示收到的網頁,當用戶在瀏覽器地址欄中輸入一個URL或點擊一個超連接時,瀏覽器就向服務器發出了HTTP請求,請求方式的格式為:統一資源標識符、協議版本號,后邊是MIME(Multipurpose Internet Mail Extensions)信息包括請求修飾符、客戶機信息和可能的內容。該請求被送往由URL指定的WEB服務器,WEB服務器接收到請求后,進行相應反映,其格式為:一個狀態行包括信息的協議版本號、一個成功或錯誤的代碼,后邊服務器信息、實體信息和可能的內容。即以HTTP規定的格式送回所要求的文件或其他相關信息,再由用戶計算機上的瀏覽器負責解釋和顯示。

特點:

1)支持客戶/服務器模式。

2)簡單快速:客戶向服務器請求服務時,只需傳送請求方法和路徑。請求方法常用的有GET、HEAD、POST。每種方法規定了客戶與服務器聯系的類型不同。由于HTTP協議簡單,使得HTTP服務器的程序規模小,因而通信速度很快。

3)靈活:HTTP允許傳輸任意類型的數據對象。正在傳輸的類型由Content-Type加以標記。

4)無連接:無連接的含義是限制每次連接只處理一個請求。服務器處理完客戶的請求,并收到客戶的應答后,即斷開連接。采用這種方式可以節省傳輸時間。

5)無狀態:HTTP協議是無狀態協議。無狀態是指協議對于事務處理沒有記憶能力。缺少狀態意味著如果后續處理需要前面的信息,則它必須重傳,這樣可能導致每次連接傳送的數據量增大。另一方面,在服務器不需要先前信息時它的應答就較快。

382.get和post的區別

1. Get是不安全的,因為在傳輸過程,數據被放在請求的URL中;Post的所有操作對用戶來說都是不可見的。

2. Get傳送的數據量較小,這主要是因為受URL長度限制;Post傳送的數據量較大,一般被默認為不受限制。

3. Get限制Form表單的數據集的值必須為ASCII字符;而Post支持整個ISO10646字符集。

4. Get執行效率卻比Post方法好。Get是form提交的默認方法。

383.如何解決表單提交的中文亂碼問題

1)設置頁面編碼,若是jsp頁面,需編寫代碼

<%@page language="java" pageEncoding="UTF-8" contentType="text/html;charset=UTF-8" %>

若是html頁面,在網頁頭部(< head>< /head>)中添加下面這段代碼

< meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

2)將form表單提交方式變為post方式,即添加method="post";)在Servlet類中編寫代碼request.setCharacterEncoding("UTF-8"),而且必須寫在第一行。

3)如果是get請求,在Servlet類中編寫代碼

byte [] bytes = str.getBytes("iso-8859-1");

String cstr = new String(bytes,"utf-8");

或者直接修改Tomcat服務器配置文件server.xml增加內容:

URIEncoding="utf-8"

384.絕對路徑、根路徑、相對路徑的含義及其區別

絕對路徑指對站點的根目錄而言某文件的位置,相對路徑指以當前文件所處目錄而言某文件的位置,相對路徑-以引用文件之網頁所在位置為參考基礎,而建立出的目錄路徑。絕對路徑-以Web站點根目錄為參考基礎的目錄路徑。

先給出一個網站結構圖做實例加深理解,A網站(域名為http://www.a.com):/include/a-test.html,/img/a-next.jpg;B網站(域名為http://www.b.com):/include/b-test.html,/img/b-next.jpg。

相對路徑是從引用的網頁文件本身開始構建的,如果在A網站中的a-test.html中要插入圖片a-next.jpg,可以這樣做:< img src="../img/a-next.jpg" />,重點是img前面的../,表示從html處于的include開始起步,輸入一個../表示回到上面一級父文件夾下,然后再接著img/表示又從父級文件夾下的img文件開始了,最后定位img下面的next.jpg。

根路徑是從網站的最底層開始起,一般的網站的根目錄就是域名下對應的文件夾,就如D盤是一個網站,雙擊D盤進入到D盤看到的就是網站的根目錄,這種路徑的鏈接樣式是這樣的:如果在A網站中的a-test.html中要插入圖片a-next.jpg,可以這樣做:< img src="/img/a-next.jpg" >,以/開頭表示從網站根目錄算起,找到根目錄下面的img文件夾下的next.jpg。

絕對路徑就很好理解了,這種路徑一般帶有網站的域名,如果在A網站中的a-test.html中要插入圖片a-next.jpg,需要這樣這樣寫:< img src="http://www.a.com/img/a-next.jpg" >,將圖片路徑上帶有了域名信息,再打個比方:如果在A網站中的a-test.html中要插入B網站的圖片b-next.jpg,就需要這樣寫:< img src="http://www.b.com/img/b-next.jpg" >,這種方法適用與在不同網站之間插入外部網站的圖片。

385.如實現servlet的單線程模式

實現servlet的單線程的jsp命令是: <%@ page isThreadSafe=”false”%>。默認isThreadSafe值為true。

屬性isThreadSafe=false模式表示它是以Singleton模式運行,該模式implements了接口SingleThreadMode, 該模式同一時刻只有一個實例,不會出現信息同步與否的概念。若多個用戶同時訪問一個這種模式的頁面,那么先訪問者完全執行完該頁面后,后訪問者才開始執行。

屬性isThreadSafe=true模式表示它以多線程方式運行。該模式的信息同步,需訪問同步方法(用synchronized標記的)來實現。 一般格式如下:

 public synchronized void syncmethod(...){
      while(...) {
        this.wait();
      }
      this.notifyAll();
 }

386.Servlet的生命周期

1、加載:在下列時刻加載 Servlet:(1)如果已配置自動加載選項,則在啟動服務器時自動

2、加載 (web.xml中設置< load-on-start>);(2)在服務器啟動后,客戶機首次向 Servlet 發出請求時;(3)重新加載 Servlet 時(只執行一次)

3、實例化:加載 Servlet 后,服務器創建一個 Servlet 實例。(只執行一次)

4、初始化:調用 Servlet 的 init() 方法。在初始化階段,Servlet 初始化參數被傳遞給 Servlet 配置對象ServletConfig。 (只執行一次)

5、請求處理:對于到達服務器的客戶機請求,服務器創建針對此次請求的一個“請求”對象和一個“響應”對象。服務器調用 Servlet 的 service() 方法,該方法用于傳遞“請求”和“響應”對象。service() 方法從“請求”對象獲得請求信息、處理該請求并用“響應”對象的方法以將響應傳回客戶機。service() 方法可以調用其它方法來處理請求,例如 doGet()、doPost() 或其它的方法。(每次請求都執行該步驟)

6、銷毀:當服務器不再需要 Servlet, 或重新裝入 Servlet 的新實例時,服務器會調用 Servlet 的 destroy() 方法。(只執行一次)

387.轉發和重定向的區別

轉發是在服務端直接做的事情,是對客戶端的同一個request進行傳遞,瀏覽器并不知道。重定向是由瀏覽器來做的事情。重定向時,服務端返回一個response,里面包含了跳轉的地址,由瀏覽器獲得后,自動發送一個新request。轉發像呼叫轉移或者110報警中心,重定向似114查號臺。

a) 區別1:跳轉效率的不同

轉發效率相對高;重定向效率相對低

b) 區別2:實現語句不同

轉發 request.getRequestDispatcher("xxxx").forward(request,response) ;

重定向 response.sendRedirect("xxxx")

c) 區別3:是否共有同一個request的數據

轉發源組件與目標組件共有同一個request數據

重定向源組件與目標組件不共有同一個request數據(可使用session共有數據)

d) 區別4:瀏覽器URL地址的不同

轉發后瀏覽器URL地址保持不變(源組件地址)

重定向后瀏覽器URL地址改變為重定向后的地址(目標組件地址)

e) 區別5:"/"路徑的含義不同

轉發時"/"代表當前項目的根路徑 ;重定向時"/"代表當前服務器的根路徑

f) 區別6:跳轉范圍的不同

只能轉發到同一應用中的URL(默認) ;可以重定向任何服務器、任何應用的URL

g) 區別7:刷新是否導致重復提交

轉發會導致重復提交(可以通過同步令牌解決);重定向不會導致重復提交

h) 區別8:是否經過過濾器

轉發不經過過濾器(默認情況);重定向經過過濾器

388.JSP的執行過程

在JSP運行過程中,首先由客戶端發出請求,Web服務器接收到請求后,如果是第一次訪問某個jsp頁面,Web服務器對它進行以下3個操作。

1)翻譯:由.jsp變為.java,由JSP引擎實現。

2)編譯:由.java變為.class,由 Java編譯器實現。

3)執行:由.class變為.html,用Java虛擬機執行編譯文件,然后將執行結果返回給Web服務器,并最終返回給客戶端

如果不是第一次訪問某個JSP頁面,則只執行第三步。所以第一次訪問JSP較慢。

389.JSP動作有哪些,簡述作用?

jsp:include:在頁面被請求的時候引入一個文件。

jsp:useBean:尋找或者實例化一個JavaBean。 jsp:setProperty:設置JavaBean的屬性。

jsp:getProperty:輸出某個JavaBean的屬性。

jsp:forward:把請求轉到一個新的頁面。 jsp:plugin:根據瀏覽器類型為Java插件生成OBJECT或EMBED標記。

390.page/request/session/application作用域區別

page:當前頁面范圍

request:當前頁面范圍+轉發頁面(forward)+包含頁面(include)

session:當前會話:session在以下幾種情況下失效

1)銷毀session:Session.invalidate();

2)超過最大非活動間隔時間

3)手動關閉瀏覽器(session并沒有立刻失效,因為服務器端session仍舊存在,超過最大非活動間隔時間后真正失效)

application:當前應用;服務器重新啟動前一直有效

391.JSP和Servlet的區別和聯系

區別:

1)JSP是在HTML代碼里寫JAVA代碼,框架是HTML;而Servlet是在JAVA代碼中寫HTML代碼,本身是個JAVA類。

2)JSP使人們把顯示和邏輯分隔成為可能,這意味著兩者的開發可并行進行;而Servlet并沒有把兩者分開。

3)Servlet獨立地處理靜態表示邏輯與動態業務邏輯.這樣,任何文件的變動都需要對此服務程序重新編譯;JSP允許用特殊標簽直接嵌入到HTML頁面, HTML內容與JAVA內容也可放在單獨文件中,HTML內容的任何變動會自動編譯裝入到服務程序.

4)Servlet需要在web.xml中配置,而JSP無需配置。

5)目前JSP主要用在視圖層,負責顯示,而Servlet主要用在控制層,負責調度

聯系:

1)都是Sun公司推出的動態網頁技術。

2)先有Servlet,針對Servlet缺點推出JSP。JSP是Servlet的一種特殊形式,每個JSP頁面就是一個Servlet實例——JSP頁面由系統翻譯成Servlet,Servlet再負責響應用戶請求。

392.談談過濾器原理及其作用?

原理:

?過濾器是運行在服務器端的一個攔截作用的web組件,一個請求來到時,web容器會判斷是否有過濾器與該信息資源相關聯,如果有則交給過濾器處理,然后再交給目標資源,響應的時候則以相反的順序交給過濾器處理,最后再返回給用戶瀏覽器

?一般用于日志記錄、性能、安全、權限管理等公共模塊。

過濾器開發:

?過濾器是一個實現了javax.servlet.Filter接口的java類

?主要業務代碼放在doFilter方法中

?業務代碼完成后要將請求向后傳遞,即調用FilterChain對象的doFilter方法

配置:

在web.xml中增加如下代碼
<filter>
    <filter-name>MyFilter</filter-name>
    <filter-class>Filter完整類名</filter-class>
</filter>
<filter-mapping>
    <filter-name>MyFilter</filter-name>
    <url-pattern>/*(要過慮的url,此處*表示過慮所有的url)</url-pattern>
</filter-mapping>

談談監聽器作用及其分類?

監聽器也叫Listener,是一個實現特定接口的java類,使用時需要在web.xml中配置,它是web服務器端的一個組件,它們用于監聽的事件源分別為SerlvetConext,HttpSession和ServletRequest這三個域對象

主要有以下三種操作:

–監聽三個域對象創建和銷毀的事件監聽器

–監聽域對象中屬性的增加和刪除的事件監聽器

–監聽綁定到HttpSession域中的某個對象的狀態的時間監聽器

接口分類:

–ServletContextListener

HttpSessionListener

–ServletRequestListener

–ServletContextAttributeListener

–HttpSessionAttributeListener

ServletRequestAttributeListener

–HttpSessionBindingListener(不需要配置)

–HttpSessionActivationListener(不需要配置)

配置:

< listener>< listener-class>實現以上任意接口的java類全名< /listener-class>< /listener>

393.jQuery相比JavaScript的優勢在哪里

jQuery的語法更加簡單。

jQuery消除了JavaScript跨平臺兼容問題。

相比其他JavaScript和JavaScript庫,jQuery更容易使用。

jQuery有一個龐大的庫/函數。

jQuery有良好的文檔和幫助手冊。

jQuery支持AJAX

394.DOM對象和jQuery對象的區別及其轉換

DOM對象,是我們用傳統的方法(javascript)獲得的對象,jQuery對象即是用jQuery類庫的選擇器獲得的對象,它是對DOM對象的一種封裝,jQuery對象不能使用DOM對象的方法,只能使用jQuery對象自己的方法。

普通的dom對象一般可以通過$()轉換成jquery對象

如:var cr=document.getElementById("cr"); //dom對象

var $cr = $(cr); //轉換成jquery對象

由于jquery對象本身是一個集合。所以如果jquery對象要轉換為dom對象則必須取出其中的某一項,一般可通過索引取出

如:$("#msg")[0],$("div").eq(1)[0],$("div").get()[1],$("td")[5]這幾種語法在jQuery中都是合法的

395.jQuery中$的作用主要有哪些

1)$用作選擇器

例如:根據id獲得頁面元素$("#元素ID")

2)$相當于window.onload 和 $(document).ready(...)

例如:$(function(){...}); function(){...}會在DOM樹加載完畢之后執行。

3)$用作JQuery的工具函數的前綴

例如: var str = ' Welcome to shanghai.com ';

str = $.trim(str);去掉空格

4)$(element):把DOM節點轉化成jQuery節點

例如:var cr=document.getElementById("cr"); //dom對象

var $cr = $(cr); //轉換成jquery對象

5)$(html):使用HTML字符串創建jQuery節點

例如:var obj = $("< div>尚學堂,實戰化教學第一品牌< /div>")

396.Ajax含義及其主要技術

Ajax (Asynchronous JavaScript and XML 阿賈克斯)不是一個新的技術,事實上,它是一些舊有的成熟的技術以一種全新的更加強大的方式整合在一起。

Ajax的關鍵技術:

1)使用CSS構建用戶界面樣式,負責頁面排版和美工

2)使用DOM進行動態顯示和交互,對頁面進行局部修改

3)使用XMLHttpRequest異步獲取數據

4)使用JavaScript將所有元素綁定在一起

397.Ajax的工作原理

Ajax的原理簡單來說通過XmlHttpRequest對象來向服務器發異步請求,從服務器獲得數據,然后用javascript來操作DOM而更新頁面。這其中最關鍵的一步就是從服務器獲得請求數據。要清楚這個過程和原理,我們必須對 XMLHttpRequest有所了解。

XMLHttpRequest是ajax的核心機制,它是在IE5中首先引入的,是一種支持異步請求的技術。簡單的說,也就是javascript可以及時向服務器提出請求和處理響應,而不阻塞用戶。達到無刷新的效果。

398.JSON及其作用

JSON(JavaScript Object Notation) 是一種輕量級的數據交換格式,采用完全獨立于語言的文本格式,是理想的數據交換格式。同時,JSON是 JavaScript 原生格式,這意味著在 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的常用類及其作用?

DiskFileItemFactory:磁盤文件工廠類,設置上傳文件保存的磁盤目錄,緩沖區大小。

ServletFileUpload:上傳處理類,此類真正讀取客戶上傳的文件,同時可以設置最大接收大小。

FileItem:上傳的文件對象,可以是多個文件,每個上傳的文件都是一個單獨的FileItem對象。

400.說出Servlet的生命周期,并說出Servlet和CGI的區別?

答:Web容器加載Servlet并將其實例化后,Servlet生命周期開始,容器運行其init()方法進行Servlet的初始化;請求到達時調用Servlet的service方法,service方法會調用與請求對應的doGet或doPost等方法;當服務器關閉會項目被卸載時服務器會將Servlet實例銷毀,此時會調用Servlet的destroy方法。Servlet與CGI的區別在于Servlet處于服務器進程中,它通過多線程方式運行其service方法,一個實例可以服務于多個請求,并且其實例一般不會銷毀,而CGI 對每個請求都產生新的進程,服務完成后就銷毀,所以效率上低于Servlet。

【補充1】SUN公司在1996年發布Servlet技術就是為了和CGI進行競爭,Servlet是一個特殊的Java程序,一個基于Java的Web應用通常包含一個或多個Servlet類。 Servlet不能夠自行創建并執行,它是在Servlet容器中運行的,容器將用戶的請求傳遞給Servlet程序,此外將Servlet的響應回傳給用戶。通常一個Servlet會關聯一個或多個JSP頁面。以前CGI經常因為性能開銷上的問題被詬病,然而Fast CGI早就已經解決了CGI效率上的問題,所以面試的時候大可不必詬病CGI,騰訊的網站就使用了CGI技術,相信你也沒感覺它哪里不好。

【補充2】Servlet接口定義了5個方法,其中前三個方法與Servlet生命周期相關:

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 有有什么關系?

答:其實這個問題在上面已經闡述過了,Servlet是一個特殊的Java程序,它運行于服務器的JVM中,能夠依靠服務器的支持向瀏覽器提供顯示內容。JSP本質上是Servlet的一種簡易形式, JSP會被服務器處理成一個類似于Servlet的Java程序,可以簡化頁面內容的生成。Servlet和JSP最主要的不同點在于,Servlet 的應用邏輯是在Java 文件中,并且完全從表示層中的HTML分離開來。而JSP的情況是Java和HTML可以組合成一個擴展名為.jsp 的文件(有人說,Servlet就是在Java中寫HTML,而JSP就是在HTML中寫Java代碼,當然,這個說法還是很片面的)。JSP側重于視圖,Servlet更側重于控制邏輯,在MVC架構模式中,JSP適合充當視圖(view)而Servlet適合充當控制器(controller)。

402.JSP中的四種作用域?

答:page、request、session和application,具體如下:

①page 代表與一個頁面相關的對象和屬性。

②request 代表與Web客戶機發出的一個請求相關的對象和屬性。一個請求可能跨越多個頁面,涉及多個Web 組件;需要在頁面顯示的臨時數據可以置于此作用域

③session代表與某個用戶與服務器建立的一次會話相關的對象和屬性。跟某個用戶相關的數據應該放在用戶自己的session中

④application代表與整個Web應用程序相關的對象和屬性,它實質上是跨越整個Web應用程序,包括多個頁面、請求和會話的一個全局作用域。

403.如何實現JSP或Servlet的單線程模式?

<%@page isThreadSafe=”false”%>

【補充】Servlet默認的工作模式是單實例多線程,如果Servlet實現了標識接口SingleThreadModel又或是JSP頁面通過page指令設置isThreadSafe屬性為false,那么它們生成的Java代碼會以單線程多實例方式工作。顯然,這樣做會導致每個請求創建一個Servlet實例,這種實踐將導致嚴重的性能問題。

404.實現會話跟蹤的技術有哪些?

答:由于HTTP協議本身是無狀態的,服務器為了區分不同的用戶,就需要對用戶會話進行跟蹤,簡單的說就是為用戶進行登記,為用戶分配唯一的ID,下一次用戶在請求中包含此ID,服務器據此判斷到底是哪一個用戶。

①URL 重寫:在URL中添加用戶會話的信息作為請求的參數,或者將唯一的會話ID添加到URL結尾以標識一個會話。

②設置表單隱藏域:將和會話跟蹤相關的字段添加到隱式表單域中,這些信息不會在瀏覽器中顯示但是提交表單時會提交給服務器。

這兩種方式很難處理跨越多個頁面的信息傳遞,因為如果每次都要修改URL或在頁面中添加隱式表單域來存儲用戶會話相關信息,事情將變得非常麻煩。

③cookie:cookie有兩種,一種是基于窗口的,瀏覽器窗口關閉后,cookie就沒有了;另一種是將信息存儲在一個臨時文件中,并設置存在的時間。當用戶通過瀏覽器和服務器建立一次會話后,會話ID就會隨響應信息返回存儲在基于窗口的cookie中,那就意味著只要瀏覽器沒有關閉,會話沒有超時,下一次請求時這個會話ID又會提交給服務器讓服務器識別用戶身份。會話中可以為用戶保存信息。會話對象是在服務器內存中的,而基于窗口的cookie是在客戶端內存中的。如果瀏覽器禁用了cookie,那么就需要通過下面兩種方式進行會話跟蹤。當然,在使用cookie時要注意幾點:首先不要在cookie中存放敏感信息;其次cookie存儲的數據量有限(4k),不能將過多的內容存儲cookie中;再者瀏覽器通常只允許一個站點最多存放20個cookie。當然,和用戶會話相關的其他信息(除了會話ID)也可以存在cookie方便進行會話跟蹤。

④HttpSession:在所有會話跟蹤技術中,HttpSession對象是最強大也是功能最多的。當一個用戶第一次訪問某個網站時會自動創建HttpSession,每個用戶可以訪問他自己的HttpSession??梢酝ㄟ^HttpServletRequest對象的getSession方法獲得HttpSession,通過HttpSession的setAttribute方法可以將一個值放在HttpSession中,通過調用HttpSession對象的getAttribute方法,同時傳入屬性名就可以獲取保存在HttpSession中的對象。與上面三種方式不同的是,HttpSession放在服務器的內存中,因此不要將過大的對象放在里面,即使目前的Servlet容器可以在內存將滿時將HttpSession中的對象移到其他存儲設備中,但是這樣勢必影響性能。添加到HttpSession中的值可以是任意Java對象,這個對象最好實現了Serializable接口,這樣Servlet容器在必要的時候可以將其序列化到文件中,否則在序列化時就會出現異常。

405.過濾器有哪些作用和用法?

答: Java Web開發中的過濾器(filter)是從Servlet 2.3規范開始增加的功能,并在Servlet 2.4規范中得到增強。對Web應用來說,過濾器是一個駐留在服務器端的Web組件,它可以截取客戶端和服務器之間的請求與響應信息,并對這些信息進行過濾。當Web容器接受到一個對資源的請求時,它將判斷是否有過濾器與這個資源相關聯。如果有,那么容器將把請求交給過濾器進行處理。在過濾器中,你可以改變請求的內容,或者重新設置請求的報頭信息,然后再將請求發送給目標資源。當目標資源對請求作出響應時候,容器同樣會將響應先轉發給過濾器,再過濾器中,你可以對響應的內容進行轉換,然后再將響應發送到客戶端。

常見的過濾器用途主要包括:對用戶請求進行統一認證、對用戶的訪問請求進行記錄和審核、對用戶發送的數據進行過濾或替換、轉換圖象格式、對響應內容進行壓縮以減少傳輸量、對請求或響應進行加解密處理、觸發資源訪問事件、對XML的輸出應用XSLT等。

和過濾器相關的接口主要有:Filter、FilterConfig、FilterChain

406.監聽器有哪些作用和用法?

答:Java Web開發中的監聽器(listener)就是application、session、request三個對象創建、銷毀或者往其中添加修改刪除屬性時自動執行代碼的功能組件,如下所示:

①ServletContextListener:對Servlet上下文的創建和銷毀進行監聽。

②ServletContextAttributeListener:監聽Servlet上下文屬性的添加、刪除和替換。

③HttpSessionListener:對Session的創建和銷毀進行監聽。

補充:session的銷毀有兩種情況:1session超時(可以在web.xml中通過< session-config>/< session-timeout>標簽配置超時時間);2通過調用session對象的invalidate()方法使session失效。

④HttpSessionAttributeListener:對Session對象中屬性的添加、刪除和替換進行監聽。

⑤ServletRequestListener:對請求對象的初始化和銷毀進行監聽。

⑥ServletRequestAttributeListener:對請求對象屬性的添加、刪除和替換進行監聽。

407.你的項目中使用過哪些JSTL標簽?

答:項目中主要使用了JSTL的核心標簽庫,包括< c:if>、< c:choose>、< c: when>、< c: otherwise>、< c:forEach>等,主要用于構造循環和分支結構以控制顯示邏輯。

【說明】雖然JSTL標簽庫提供了core、sql、fmt、xml等標簽庫,但是實際開發中建議只使用核心標簽庫(core),而且最好只使用分支和循環標簽并輔以表達式語言(EL),這樣才能真正做到數據顯示和業務邏輯的分離,這才是最佳實踐。

408.使用標簽庫有什么好處?如何自定義JSP標簽?

答:使用標簽庫的好處包括以下幾個方面:

分離JSP頁面的內容和邏輯,簡化了Web開發;

開發者可以創建自定義標簽來封裝業務邏輯和顯示邏輯;

標簽具有很好的可移植性、可維護性和可重用性;

避免了對Scriptlet(小腳本)的使用(很多公司的項目開發都不允許在JSP中書寫小腳本)

自定義JSP標簽包括以下幾個步驟:

編寫一個Java類實現實現Tag/BodyTag/IterationTag接口(通常不直接實現這些接口而是繼承TagSupport/BodyTagSupport/SimpleTagSupport類,這是對適配器模式中缺省適配模式的應用)

重寫doStartTag()、doEndTag()等方法,定義標簽要完成的功能

編寫擴展名為tld的標簽描述文件對自定義標簽進行部署,tld文件通常放在WEB-INF文件夾或其子目錄

在JSP頁面中使用taglib指令引用該標簽庫

下面是一個例子:

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頁面

<%@ 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>首頁</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>

運行結果

【注意】如果要將自定義的標簽庫發布成JAR文件,需要將標簽庫描述文件(tld文件)放在JAR文件的META-INF目錄下,可以JDK自帶的jar工具完成JAR文件的生成。

409.表達式語言(EL)的隱式對象及其作用?

答: pageContext、initParam(訪問上下文參數)、param(訪問請求參數)、paramValues、header(訪問請求頭)、headerValues、cookie(訪問cookie)、applicationScope(訪問application作用域)、sessionScope(訪問session作用域)、requestScope(訪問request作用域)、pageScope(訪問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}

【補充】表達式語言的.和[]運算作用是一致的,唯一的差別在于如果訪問的屬性名不符合Java標識符命名規則,例如上面的accept-language就不是一個有效的Java標識符,那么這時候就只能用[]運算符而不能使用.獲取它的值

410.表達式語言(EL)支持哪些運算符?

答:除了.和[]運算符,EL還提供了:

算術運算符:+、-、*、/或div、%或mod

關系運算符:==或eq、!=或ne、>或gt、>=或ge、< 或lt、< =或le

邏輯運算符:&&或and、||或or、!或not

條件運算符:${statement? A : B}(跟Java的條件運算符類似)

empty運算符:檢查一個值是否為null或者空(數組長度為0或集合中沒有元素也返回true)

411.Servlet 3中的異步處理指的是什么?

答:在Servlet 3中引入了一項新的技術可以讓Servlet異步處理請求。有人可能會質疑,既然都有多線程了,還需要異步處理請求嗎?答案是肯定的,因為如果一個任務處理時間相當長,那么Servlet或Filter會一直占用著請求處理線程直到任務結束,隨著并發用戶的增加,容器將會遭遇線程超出的風險,這這種情況下很多的請求將會被堆積起來而后續的請求可能會遭遇拒絕服務,直到有資源可以處理請求為止。異步特性可以幫助應用節省容器中的線程,特別適合執行時間長而且用戶需要得到結果的任務,如果用戶不需要得到結果則直接將一個Runnable對象交給Executor(如果不清楚請查看前文關于多線程和線程池的部分)并立即返回即可。

【補充】多線程在Java誕生初期無疑是一個亮點,而Servlet單實例多線程的工作方式也曾為其贏得美名,然而技術的發展往往會顛覆我們很多的認知,就如同當年愛因斯坦的相對論顛覆了牛頓的經典力學一般。事實上,異步處理絕不是Serlvet 3首創,如果你了解Node.js的話,對Servlet 3的這個重要改進就不以為奇了。

412.如何在基于Java的Web項目中實現文件上傳和下載?

答:(稍后呈現,我準備用HTML5寫一個帶進度條的客戶端,然后再用Servlet 3提供的文件上傳支持來做一個多文件上傳的例子)

413.簡述值棧(Value-Stack)的原理和生命周期

答: Value-Stack貫穿整個 Action 的生命周期,保存在request作用域中,所以它和request的生命周期一樣。當Struts 2接受一個請求時,會創建ActionContext、Value-Stack和Action對象,然后把Action存放進Value-Stack,所以Action的實例變量可以通過OGNL訪問。由于Action是多實例的,和使用單例的Servlet不同, 每個Action都有一個對應的Value-Stack,Value-Stack存放的數據類型是該Action的實例,以及該Action中的實例變量,Action對象默認保存在棧頂。

414.闡述Session加載實體對象的過程。

答:Session加載實體對象的步驟是:

① Session在調用數據庫查詢功能之前, 首先會在緩存中進行查詢, 在一級緩存中, 通過實體類型和主鍵進行查找, 如果一級緩存查找命中且數據狀態合法, 則直接返回

② 如果一級緩存沒有命中, 接下來Session會在當前NonExists記錄(相當于一個查詢黑名單, 如果出現重復的無效查詢可以迅速判斷, 從而提升性能)中進行查找, 如果NonExists中存在同樣的查詢條件,則返回null

③ 對于load方法, 如果一級緩存查詢失敗則查詢二級緩存, 如果二級緩存命中則直接返回

④ 如果之前的查詢都未命中, 則發出SQL語句, 如果查詢未發現對應記錄則將此次查詢添加到Session的NonExists中加以記錄, 并返回null

⑤ 根據映射配置和SQL語句得到ResultSet,并創建對應的實體對象

⑥ 將對象納入Session(一級緩存)管理

⑦ 執行攔截器的onLoad方法(如果有對應的攔截器)

⑧ 將數據對象納入二級緩存

⑨ 返回數據對象

415.怎么防止重復提交

1.禁掉提交按鈕。表單提交后使用Javascript使提交按鈕disable。這種方法防止心急的用戶多次點擊按鈕。但有個問題,如果客戶端把Javascript給禁止掉,這種方法就無效了。

2.Post/Redirect/Get模式。在提交后執行頁面重定向,這就是所謂的Post-Redirect-Get (PRG)模式。簡言之,當用戶提交了表單后,你去執行一個客戶端的重定向,轉到提交成功信息頁面。

這能避免用戶按F5導致的重復提交,而其也不會出現瀏覽器表單重復提交的警告,也能消除按瀏覽器前進和后退按導致的同樣問題。

3.在session中存放一個特殊標志。當表單頁面被請求時,生成一個特殊的字符標志串,存在session中,同時放在表單的隱藏域里。接受處理表單數據時,檢查標識字串是否存在,并立即從session中刪除它,然后正常處理數據。

如果發現表單提交里沒有有效的標志串,這說明表單已經被提交過了,忽略這次提交。

4.在數據庫里添加約束。在數據庫里添加唯一約束或創建唯一索引,防止出現重復數據。這是最有效的防止重復提交數據的方法。

416.$(document).ready(function(){}) jQuery(document).ready(function(){}); 有什么區別?

window.jQuery = window.$ = jQuery;

這兩者可以互換使用。一般建議優先使用$

417.寫出輸出結果

<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>

//請寫出以下輸出結果:

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項目從瀏覽器發起交易響應緩慢,請簡述從哪些方面如數分析

從前端后端分別取考慮,后臺是不是數據庫死鎖等。

前臺看看是不是js 錯誤,或者圖片過大,dom 渲染dom樹,畫面優化。cmd amd 規范等

設計模式
419.請寫出您熟悉的幾種設計模式,并做簡單介紹。

答:工廠設計模式:程序在接口和子類之間加入了一個過渡端,通過此過渡端可以動態取得實現了共同接口的子類實例化對象。

代理設計模式:指由一個代理主題來操作真實主題,真實主題執行具體的業務操作,而代理主題負責其他相關業務的處理。比如生活中的通過代理訪問網絡,客戶通過網絡代理連接網絡(具體業務),由代理服務器完成用戶權限和訪問限制等與上網相關的其他操作(相關業務)

適配器模式:如果一個類要實現一個具有很多抽象方法的接口,但是本身只需要實現接口中的部分方法便可以達成目的,所以此時就需要一個中間的過渡類,但此過渡類又不希望直接使用,所以將此類定義為抽象類最為合適,再讓以后的子類直接繼承該抽象類便可選擇性的覆寫所需要的方法,而此抽象類便是適配器類。

420.寫出你用過的設計模式,并至少寫出2種模式的類圖或關鍵代碼。

工廠設計模式:

思路說明:由一個工廠類根據傳入的參數(一般是字符串參數),動態決定應該創建哪一個產品子類(這些產品子類繼承自同一個父類或接口)的實例,并以父類形式返回

優點:客戶端不負責對象的創建,而是由專門的工廠類完成;客戶端只負責對象的調用,實現了創建和調用的分離,降低了客戶端代碼的難度;

缺點:如果增加和減少產品子類,需要修改簡單工廠類,違背了開閉原則;如果產品子類過多,會導致工廠類非常的龐大,違反了高內聚原則,不利于后期維護。

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;
}
}

單例模式

/**
 * 餓漢式的單例模式
 * 在類加載的時候創建單例實例,而不是等到第一次請求實例的時候的時候創建
* 1、私有 的無參數構造方法Singleton(),避免外部創建實例
 * 2、私有靜態屬性instance
 * 3、公有靜態方法getInstance()
 */
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton(){ }
public static Singleton getInstance(){
return instance;
}
}
/**
 * 懶漢式的單例模式
 *在類加載的時候不創建單例實例,只有在第一次請求實例的時候的時候創建
*/
public class Singleton {
private static Singleton instance;
private Singleton(){ }
/**
 * 多線程情況的單例模式,避免創建多個對象
*/
public static Singleton getInstance(){
if(instance ==null){//避免每次加鎖,只有第一次沒有創建對象時才加鎖
synchronized(Singleton.class){//加鎖,只允許一個線程進入
if(instance==null){ //只創建一次對象
instance = new Singleton();
}
}
}
return instance;
}}
421.列出除Singleton外的常用的3種設計模式,并簡單描述

答:工廠模式:工廠模式是 Java 中最常用的設計模式之一。這種類型的設計模式屬于創建型模式,它提供了一種創建對象的最佳方式。在工廠模式中,我們在創建對象時不會對客戶端暴露創建邏輯,并且是通過使用一個共同的接口來指向新創建的對象。

適配器模式:適配器模式是作為兩個不兼容的接口之間的橋梁。這種類型的設計模式屬于結構型模式,它結合了兩個獨立接口的功能。這種模式涉及到一個單一的類,該類負責加入獨立的或不兼容的接口功能。

模板模式:在模板模式中,一個抽象類公開定義了執行它的方法的方式/模板。它的子類可以按需要重寫方法實現,但調用將以抽象類中定義的方式進行。

422.Action是單實例還是多實例,為什么?

答:struts2中action是多例的,即一個session產生一個action

背景:

1) Struts2會對每一個請求,產生一個Action的實例來處理.

2) Spring的Ioc容器管理的bean默認是單實例的.

首先從數據安全性的問題上考慮,我們的Action應該保證是多例的,這樣才不會出現數據問題。但是如果有的action比如只有admin才能操作,或者某些action,全站公用一個來提高性能,這樣的話,就可以使用單例模式。

不過幸好,Spring的bean可以針對每一個設置它的scope,所以,上面的問題就不是問題了。如果用單例,就在spring的action bean配置的時候設置scope=”prototype”

如果是單例的話,若出現兩個用戶都修改一個對象的屬性值,則會因為用戶修改時間不同,兩個用戶訪問得到的屬性不一樣,操作得出的結果不一樣.

舉個例子:有一塊布長度300cm,能做一件上衣(用掉100cm)和一件褲子(用掉200cm);甲和乙同時訪問得到的長度都是300cm,

甲想做上衣和褲子,他先截取100cm去做上衣,等上衣做完再去做褲子,而乙這時正好也拿100cm去做上衣,那好,等甲做完上衣再做褲子的時候發現剩下的布(100cm)已經不夠做褲子了…..這就是影響系統的性能,解決的辦法就是給甲和乙一人一塊300cm的布,就不會出現布被別人偷用的事情,也是就單實例和多實例的區別

如果設置成單例,那么多個線程會共享一個ActionContext和ValueStack,這樣并發訪問的時候就會出現問題了

struts 2的Action是多實例的并非單例,也就是每次請求產生一個Action的對象。原因是:struts 2的Action中包含數據,例如你在頁面填寫的數據就會包含在Action的成員變量里面。如果Action是單實例的話,這些數據在多線程的環境下就會相互影響,例如造成別人填寫的數據被你看到了。所以Struts2的Action是多例模式的。

問題出現了,可以讓Struts2的action變成單例模式么?

Struts2中,可以使用注解開發,在Action上@Scope(“prototype”) 指定為多例 , 默認為singleton()單例)

基本上action的scope需要是prototype,就是每次請求都建立新的線程

不寫的話,默認是singleton了

423.寫一個單例類

答:單例模式主要作用是保證在Java應用程序中,一個類只有一個實例存在。下面給出兩種不同形式的單例:

第一種形式:餓漢式單例?

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;
    }
}

單例的特點:外界無法通過構造器來創建對象,該類必須提供一個靜態方法向外界提供該類的唯一實例。

【補充】用Java進行服務器端編程時,使用單例模式的機會還是很多的,服務器上的資源都是很寶貴的,對于那些無狀態的對象其實都可以單例化或者靜態化(在內存中僅有唯一拷貝),如果使用了spring這樣的框架來進行對象托管,Spring的IoC容器在默認情況下對所有托管對象都是進行了單例化處理的。?

424.說說你所熟悉或聽說過的設計模式以及你對設計模式的看法

答:在GoF的《Design Patterns: Elements of Reusable Object-Oriented Software》中給出了三類(創建型[對類的實例化過程的抽象化]、結構型[描述如何將類或對象結合在一起形成更大的結構]、行為型[對在不同的對象之間劃分責任和算法的抽象化])共23種設計模式,包括:Abstract Factory(抽象工廠模式),Builder(建造者模式),Factory Method(工廠方法模式),Prototype(原始模型模式),Singleton(單例模式);Facade(門面模式),Adapter(適配器模式),Bridge(橋梁模式),Composite(合成模式),Decorator(裝飾模式),Flyweight(享元模式),Proxy(代理模式);Command(命令模式),Interpreter(解釋器模式),Visitor(訪問者模式),Iterator(迭代子模式),Mediator(調停者模式),Memento(備忘錄模式),Observer(觀察者模式),State(狀態模式),Strategy(策略模式),Template Method(模板方法模式), Chain Of Responsibility(責任鏈模式)。

所謂設計模式,就是一套被反復使用的代碼設計經驗的總結(情境中一個問題經過證實的一個解決方案)。使用設計模式是為了可重用代碼、讓代碼更容易被他人理解、保證代碼可靠性。設計模式使人們可以更加簡單方便的復用成功的設計和體系結構。將已證實的技術表述成設計模式也會使新系統開發者更加容易理解其設計思路。

【補充】設計模式并不是像某些地方吹噓的那樣是遙不可及的編程理念,說白了設計模式就是對面向對象的編程原則的實踐,面向對象的編程原則包括:

單一職責原則:一個類只做它該做的事情。(單一職責原則想表達的就是“高內聚”,寫代碼最終極的原則只有六個字“高內聚、低耦合”,就如同葵花寶典或辟邪劍譜的中心思想就八個字“欲練此功必先自宮”,所謂的高內聚就是一個代碼模塊只完成一項功能,在面向對象中,如果只讓一個類完成它該做的事,而不涉及與它無關的領域就是踐行了高內聚的原則,這個類就只有單一職責。我們都知道一句話叫“因為專注,所以專業”,一個對象如果承擔太多的職責,那么注定它什么都做不好。這個世界上任何好的東西都有兩個特征,一個是功能單一,好的相機絕對不是電視購物里面賣的那種一個機器有一百多種功能的,它基本上只能照相;另一個是模塊化,好的自行車是組裝車,從減震叉、剎車到變速器,所有的部件都是可以拆卸和重新組裝的,好的乒乓球拍也不是成品拍,一定是底板和膠皮可以拆分和自行組裝的,一個好的軟件系統,它里面的每個功能模塊也應該是可以輕易的拿到其他系統中使用的,這樣才能實現軟件復用的目標。)

開閉原則:軟件實體應當對擴展開放,對修改關閉。(在理想的狀態下,當我們需要為一個軟件系統增加新功能時,只需要從原來的系統派生出一些新類就可以,不需要修改原來的任何一行代碼。要做到開閉有兩個要點:①抽象是關鍵,一個系統中如果沒有抽象類或接口系統就沒有擴展點;②封裝可變性,將系統中的各種可變因素封裝到一個繼承結構中,如果多個可變因素混雜在一起,系統將變得復雜而換亂,如果不清楚如何封裝可變性,可以參考《設計模式精解》一書中對橋梁模式的講解的章節。)

依賴倒轉原則:面向接口編程。(該原則說得直白和具體一些就是聲明方法的參數類型、方法的返回類型、變量的引用類型時,盡可能使用抽象類型而不用具體類型,因為抽象類型可以被它的任何一個子類型所替代,請參考下面的里氏替換原則。)

里氏替換原則:任何時候都可以用子類型替換掉父類型。(關于里氏替換原則的描述,Barbara Liskov女士的描述比這個要復雜得多,但簡單的說就是能用父類型的地方就一定能使用子類型。里氏替換原則可以檢查繼承關系是否合理,如果一個繼承關系違背了里氏替換原則,那么這個繼承關系一定是錯誤的,需要對代碼進行重構。例如讓貓繼承狗,或者狗繼承貓,又或者讓正方形繼承長方形都是錯誤的繼承關系,因為你很容易找到違反里氏替換原則的場景。需要注意的是:子類一定是增加父類的能力而不是減少父類的能力,因為子類比父類的能力更多,把能力多的對象當成能力少的對象來用當然沒有任何問題。)

接口隔離原則:接口要小而專,絕不能大而全。(臃腫的接口是對接口的污染,既然接口表示能力,那么一個接口只應該描述一種能力,接口也應該是高度內聚的。例如,琴棋書畫就應該分別設計為四個接口,而不應設計成一個接口中的四個方法,因為如果設計成一個接口中的四個方法,那么這個接口很難用,畢竟琴棋書畫四樣都精通的人還是少數,而如果設計成四個接口,會幾項就實現幾個接口,這樣的話每個接口被復用的可能性是很高的。Java中的接口代表能力、代表約定、代表角色,能否正確的使用接口一定是編程水平高低的重要標識。)

合成聚合復用原則:優先使用聚合或合成關系復用代碼。(通過繼承來復用代碼是面向對象程序設計中被濫用得最多的東西,因為所有的教科書都無一例外的對繼承進行了鼓吹從而誤導了初學者,類與類之間簡單的說有三種關系,IS-A關系、HAS-A關系、USE-A關系,分別代表繼承、關聯和依賴。其中,關聯關系根據其關聯的強度又可以進一步劃分為關聯、聚合和合成,但說白了都是HAS-A關系,合成聚合復用原則想表達的是優先考慮HAS-A關系而不是IS-A關系復用代碼,原因嘛可以自己從百度上找到一萬個理由,需要說明的是,即使在Java的API中也有不少濫用繼承的例子,例如Properties類繼承了Hashtable類,Stack類繼承了Vector類,這些繼承明顯就是錯誤的,更好的做法是在Properties類中放置一個Hashtable類型的成員并且將其鍵和值都設置為字符串來存儲數據,而Stack類的設計也應該是在Stack類中放一個Vector對象來存儲數據。記?。喝魏螘r候都不要繼承工具類,工具是可以擁有并可以使用的(HAS/USE),而不是拿來繼承的。)

迪米特法則:迪米特法則又叫最少知識原則,一個對象應當對其他對象有盡可能少的了解。(迪米特法則簡單的說就是如何做到“低耦合”,門面模式和調停者模式就是對迪米特法則的踐行。對于門面模式可以舉一個簡單的例子,你去一家公司洽談業務,你不需要了解這個公司內部是如何運作的,你甚至可以對這個公司一無所知,去的時候只需要找到公司入口處的前臺美女,告訴她們你要做什么,她們會找到合適的人跟你接洽,前臺的美女就是公司這個系統的門面。再復雜的系統都可以為用戶提供一個簡單的門面,Java Web開發中作為前端控制器的Servlet或Filter不就是一個門面嗎,瀏覽器對服務器的運作方式一無所知,但是通過前端控制器就能夠根據你的請求得到相應的服務。調停者模式也可以舉一個簡單的例子來說明,例如一臺計算機,CPU、內存、硬盤、顯卡、聲卡各種設備需要相互配合才能很好的工作,但是如果這些東西都直接連接到一起,計算機的布線將異常復雜,在這種情況下,主板作為一個調停者的身份出現,它將各個設備連接在一起而不需要每個設備之間直接交換數據,這樣就減小了系統的耦合度和復雜度。迪米特法則用通俗的話來將就是不要和陌生人打交道,如果真的需要,找一個自己的朋友,讓他替你和陌生人打交道。)

425.Java企業級開發中常用的設計模式有哪些?

答: 按照分層開發的觀點,可以將應用劃分為:表示層、業務邏輯層和持久層,每一層都有屬于自己類別的設計模式。

表示層設計模式:

1) Interceptor Filter:攔截過濾器,提供請求預處理和后處理的方案,可以對請求和響應進行過濾。/p>

2) Front Controller:通過中央控制器提供請求管理和處理,管理內容讀取、安全性、視圖管理和導航等功能。Struts 2中的StrutsPrepareAndExecuteFilter、Spring MVC中的DispatcherServlet都是前端控制器,后者如下圖所示:

3) View Helper:視圖幫助器,負責將顯示邏輯和業務邏輯分開。顯示的部分放在視圖組件中,業務邏輯代碼放在幫助器中,典型的功能是內容讀取、驗證與適配。

4) Composite View:復合視圖。

業務邏輯層設計模式:

1) Business Delegate:業務委托,減少表示層和業務邏輯層之間的耦合。

2) Value Object:值對象,解決層之間交換數據的開銷問題。

3) Session Fa?ade:會話門面,隱藏業務邏輯組件的細節,集中工作流程。

4) Value Object Assembler:靈活的組裝不同的值對象

5) Value List Handler:提供執行查詢和處理結果的解決方案,還可以緩存查詢結果,從而達到提升性能的目的。

6) Service Locator:服務定位器,可以查找、創建和定位服務工廠,封裝其實現細節,減少復雜性,提供單個控制點,通過緩存提高性能。

持久層設計模式:

Data Access Object:數據訪問對象,以面向對象的方式完成對數據的增刪改查。

【補充】如果想深入的了解Java企業級應用的設計模式和架構模式,可以參考這些書籍:?《Pro Java EE Spring Patterns》、《POJO in Action》、《Patterns of Enterprise Application Architecture》。

426.你在開發中都用到了那些設計模式?用在什么場合?

答:面試被問到關于設計模式的知識時,可以揀最常用的作答,例如:

1) 工廠模式:工廠類可以根據條件生成不同的子類實例,這些子類有一個公共的抽象父類并且實現了相同的方法,但是這些方法針對不同的數據進行了不同的操作(多態方法)。當得到子類的實例后,開發人員可以調用基類中的方法而不必考慮到底返回的是哪一個子類的實例。

2) 代理模式:給一個對象提供一個代理對象,并由代理對象控制原對象的引用。實際開發中,按照使用目的的不同,代理可以分為:遠程代理、虛擬代理、保護代理、Cache代理、防火墻代理、同步化代理、智能引用代理。

3) 適配器模式:把一個類的接口變換成客戶端所期待的另一種接口,從而使原本因接口不匹配而無法在一起使用的類能夠一起工作。

4) 模板方法模式:提供一個抽象類,將部分邏輯以具體方法或構造器的形式實現,然后聲明一些抽象方法來迫使子類實現剩余的邏輯。不同的子類可以以不同的方式實現這些抽象方法(多態實現),從而實現不同的業務邏輯。

除此之外,還可以講講上面提到的門面模式、橋梁模式、單例模式、裝潢模式(Collections工具類里面的synchronizedXXX方法把一個線程不安全的容器變成線程安全容器就是對裝潢模式的應用,而Java IO里面的過濾流(有的翻譯成處理流)也是應用裝潢模式的經典例子)等,反正原則就是揀自己最熟悉的用得最多的作答,以免言多必失。?

427.什么是設計模式,設計模式的作用。

設計模式是一套被反復使用的、多數人知曉、經過分類編目的優秀代碼設計經驗的總結。特定環境下特定問題的處理方法。

1)重用設計和代碼 重用設計比重用代碼更有意義,自動帶來代碼重用

2)提高擴展性 大量使用面向接口編程,預留擴展插槽,新的功能或特性很容易加入到系統中來

3)提高靈活性 通過組合提高靈活性,可允許代碼修改平穩發生,對一處修改不會波及到其他模塊

4) 提高開發效率 正確使用設計模式,可以節省大量的時間

428.23種經典設計模式都有哪些,如何分類。
429.寫出簡單工廠模式的示例代碼
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;
}
}

基本原理:由一個工廠類根據傳入的參數(一般是字符串參數),動態決定應該創建哪一個產品子類(這些產品子類繼承自同一個父類或接口)的實例,并以父類形式返回

優點:客戶端不負責對象的創建,而是由專門的工廠類完成;客戶端只負責對象的調用,實現了創建和調用的分離,降低了客戶端代碼的難度;

缺點:如果增加和減少產品子類,需要修改簡單工廠類,違背了開閉原則;如果產品子類過多,會導致工廠類非常的龐大,違反了高內聚原則,不利于后期維護

430.請對你所熟悉的一個設計模式進行介紹

分析:建議挑選有一定技術難度,并且在實際開發中應用較多的設計模式??梢蕴暨x裝飾模式和動態代理模式。此處挑選動態代理設計模式。

講解思路:生活案例引入、技術講解、優缺點分析、典型應用。

1、生活案例引入:送生日蛋糕:

MM們要過生日了,怎么也得表示下吧。最起碼先送個蛋糕。蛋糕多種多樣了。巧克力,冰淇淋,奶油等等。這都是基本的了,再加點額外的裝飾,如蛋糕里放點花、放賀卡、放點干果吃著更香等等。

分析:

方案1:如果采用繼承會造成大量的蛋糕子類

方案2:蛋糕作為主體,花,賀卡,果仁等是裝飾者,需要時加到蛋糕上。要啥我就加啥。

技術講解

裝飾模式(別名Wrapper)是在不必改變原類文件和使用繼承的情況下,動態的擴展一個對象的功能。它通過創建一個包裝對象,也就是裝飾來包裹真實對象,提供了比繼承更具彈性的代替方案。

裝飾模式一般涉及到的角色

抽象構建角色(Component):給出一個抽象的接口,以規范準備接受附加責任的對象。

具體的構建角色(ConcreteComponent):定義一個將要接受附加責任的類。

抽象的裝飾角色 (Decorator):持有一個抽象構建(Component)角色的引用,并定義一個與抽象構件一致的接口。

具體的裝飾角色(ConcreteDecorator):負責給構建對象“貼上”附加的責任。

3、優缺點分析

優點

1)Decorator模式與繼承關系的目的都是要擴展對象的功能,但是Decorato更多的靈活性。

2)把類中的裝飾功能從類中搬移出去,這樣可以簡化原有的類。有效地把類的核心功能和裝飾功能區分開了。

3)通過使用不同的具體裝飾類以及這些裝飾類的排列組合,可創造出很多不同行為的組合。

缺點

這種比繼承更加靈活機動的特性,也同時意味著更加多的復雜性。

裝飾模式會導致設計中出現許多小類,如果過度使用,會使程序變得很復雜。

符合的設計原則:

多用組合,少用繼承。利用繼承設計子類的行為是在編譯時靜態決定的,且所有的子類都會繼承到相同的行為。如能夠利用組合擴展對象的行為,就可在運行時動態進行擴展。

類應設計的對擴展開放,對修改關閉。

4、典型應用

java IO中需要完成對不同輸入輸出源的操作,如果單純的使用繼承這一方式,無疑需要很多的類。比如說,我們操作文件需要一個類,實現文件的字節讀取需要一個類,實現文件的字符讀取又需要一個類....一次類推每個特定的操作都需要一個特定的類。這無疑會導致大量的IO繼承類的出現。顯然對于編程是很不利的。而是用裝飾模式則可以很好的解決這一問題,在裝飾模式中:節點流(如FileInputStream)直接與輸入源交互,之后通過過濾流(FilterInputStream)進行裝飾,這樣獲得的io對象便具有某幾個的功能,很好的拓展了IO的功能。

高級框架

431.什么是Maven?

Maven使用項目對象模型(POM)的概念,可以通過一小段描述信息來管理項目的構建,報告和文檔的軟件項目管理工具。

Maven 除了以程序構建能力為特色之外,還提供高級項目管理工具。由于 Maven 的缺省構建規則有較高的可重用性,所以常常用兩三行 Maven 構建腳本就可以構建簡單的項目。由于 Maven 的面向項目的方法,許多 Apache Jakarta 項目發布時使用 Maven,而且公司項目采用 Maven 的比例在持續增長。

Maven的出現,解決了開發過程中的jar包升級及依賴的難題。它可以對項目依賴的jar包進行管理,可以讓你的項目保持基本的依賴,排除冗余jar包,并且可以讓你非常輕松的對依賴的jar包進行版本升級。而這些僅僅是Maven最基本的功能,它可以在這基礎上對項目進行清理、編譯、測試、打包、發布等等構建項目的工作。?

可以說,Maven是現在Java社區中最強大的項目管理和項目構建工具,而更加值得慶幸的是,這樣一個強大的工具,它的使用也是非常簡單的。

現在,JavaEE項目使用的開源軟件都可以通過Maven來獲取,并且,越來越多的公司也開始使用Maven來管理構建項目了。

432.Maven和ANT的區別

1.maven&ant同屬apach是流行的構建工具。

都是為了簡化軟件開發而存在的。但是maven因為自身管理一個項目對象模型(project object model),這個模型其實就是抽象了一個項目的開發流程,它包含了一個項目的生命周期的各個階段,并將這個周期固定下來,這也就是約定大于配置。約定大于配置的意思就是,我maven將項目開發的各個階段固定起來了,每個文件的存放位置,每個階段要生成什么文件、保存為什么格式并且要把它放在什么位置,我都固定好了。我知道一個軟件是怎么開發出來,如果一個項目要使用maven,可以,但你要遵循我的規則,文件目錄不要亂建亂放,只有這樣maven才會將源碼用起來。這就是約定大于配置,因為maven已經將流程固定下來了,只要遵守約定,就不需要自己手動去配置了,這將大大地提高開發效率。就像是開車一樣,只要知道點火、油門、方向、剎車,就可以將車子開東起來(當然出于安全和法律考慮,還是要考駕照的。),關于車子內部的傳動原理,電氣原理,工程原理,普通人并不需要了解多少,日常夠用就好了。這也是約定大于配置的一個例子。配置就是自己造一輛車去開,有必要,有能力,有時間嗎?

2.maven的中央倉庫和pom.xml文件。中央倉庫統一存放了開發用到的各種jar包,要用時只需要添加依賴到pom文件中,maven就會自動下載,當然為了方便一般會在本地建一個倉庫,減少下載時間。pom文件是maven的配置文件,maven就是通過管理pom文件和一些核心插件來管理項目。當然我前面將maven擬人化了,其實maven是沒有智力的,一切都是封裝好的流程,只是maven將很多操作隱藏起來了。

3.ant的build.xml文件。build文件是ant的配置文件,ant依靠它來執行操作,與maven不同的是ant沒有固定一條程序鏈。你想要執行什么操作以及操作之間的順序和依賴關系,都需要手動添加到build文件中,一點一滴都要寫清楚,否則ant就不會執行。

4.maven和ant區別

Maven 擁有約定,只要遵守約定,它就知道你的源代碼在哪里。Maven 是聲明式的。你需要做的只是創建一個 pom.xml 文件然后將源代碼放到默認的目錄。Maven 會幫你處理其它的事情。Maven 有一個生命周期,當你運行 mvn install 的時候被調用。這條命令告訴 Maven 執行一系列的有序的步驟,直到到達你指定的生命周期。缺點是運行許多默認目標。

而ant沒有約定,項目生命周期,它是命令式的。所有操作都要手動去創建、布置。甚至連build.xml文件都需要手動創建。

433.Maven倉庫是什么

Maven倉庫是基于簡單文件系統存儲的,集中化管理Java API資源(構件)的一個服務。倉庫中的任何一個構件都有其唯一的坐標,根據這個坐標可以定義其在倉庫中的唯一存儲路徑。得益于 Maven 的坐標機制,任何 Maven項目使用任何一個構件的方式都是完全相同的,Maven 可以在某個位置統一存儲所有的 Maven 項目共享的構件,這個統一的位置就是倉庫,項目構建完畢后生成的構件也可以安裝或者部署到倉庫中,供其它項目使用。

對于Maven來說,倉庫分為兩類:本地倉庫和遠程倉庫。

434.Maven的工程類型有哪些?

POM工程

POM工程是邏輯工程。用在父級工程或聚合工程中。用來做jar包的版本控制。

JAR工程

將會打包成jar用作jar包使用。即常見的本地工程 - Java Project。

WAR工程

將會打包成war,發布在服務器上的工程。如網站或服務。即常見的網絡工程 - Dynamic Web Project。war工程默認沒有WEB-INF目錄及web.xml配置文件,IDE通常會顯示工程錯誤,提供完整工程結構可以解決。

435.Maven常用命令有哪些?

install

本地安裝, 包含編譯,打包,安裝到本地倉庫

編譯 - javac

打包 - jar, 將java代碼打包為jar文件

安裝到本地倉庫 - 將打包的jar文件,保存到本地倉庫目錄中。

clean

清除已編譯信息。

刪除工程中的target目錄。

compile

只編譯。 javac命令

deploy

部署。 常見于結合私服使用的命令。

相當于是install+上傳jar到私服。

包含編譯,打包,安裝到本地倉庫,上傳到私服倉庫。

package

打包。 包含編譯,打包兩個功能。

436.ZooKeeper的作用是什么?

配置管理

在我們的應用中除了代碼外,還有一些就是各種配置。比如數據庫連接等。一般我們都是使用配置文件的方式,在代碼中引入這些配置文件。當我們只有一種配置,只有一臺服務器,并且不經常修改的時候,使用配置文件是一個很好的做法,但是如果我們配置非常多,有很多服務器都需要這個配置,這時使用配置文件就不是個好主意了。這個時候往往需要尋找一種集中管理配置的方法,我們在這個集中的地方修改了配置,所有對這個配置感興趣的都可以獲得變更。Zookeeper就是這種服務,它使用Zab這種一致性協議來提供一致性?,F在有很多開源項目使用Zookeeper來維護配置,比如在HBase中,客戶端就是連接一個Zookeeper,獲得必要的HBase集群的配置信息,然后才可以進一步操作。還有在開源的消息隊列Kafka中,也使用Zookeeper來維護broker的信息。在Alibaba開源的SOA框架Dubbo中也廣泛的使用Zookeeper管理一些配置來實現服務治理。

名字服務

名字服務這個就很好理解了。比如為了通過網絡訪問一個系統,我們得知道對方的IP地址,但是IP地址對人非常不友好,這個時候我們就需要使用域名來訪問。但是計算機是不能是域名的。怎么辦呢?如果我們每臺機器里都備有一份域名到IP地址的映射,這個倒是能解決一部分問題,但是如果域名對應的IP發生變化了又該怎么辦呢?于是我們有了DNS這個東西。我們只需要訪問一個大家熟知的(known)的點,它就會告訴你這個域名對應的IP是什么。在我們的應用中也會存在很多這類問題,特別是在我們的服務特別多的時候,如果我們在本地保存服務的地址的時候將非常不方便,但是如果我們只需要訪問一個大家都熟知的訪問點,這里提供統一的入口,那么維護起來將方便得多了。

分布式鎖

其實在第一篇文章中已經介紹了Zookeeper是一個分布式協調服務。這樣我們就可以利用Zookeeper來協調多個分布式進程之間的活動。比如在一個分布式環境中,為了提高可靠性,我們的集群的每臺服務器上都部署著同樣的服務。但是,一件事情如果集群中的每個服務器都進行的話,那相互之間就要協調,編程起來將非常復雜。而如果我們只讓一個服務進行操作,那又存在單點。通常還有一種做法就是使用分布式鎖,在某個時刻只讓一個服務去干活,當這臺服務出問題的時候鎖釋放,立即fail over到另外的服務。這在很多分布式系統中都是這么做,這種設計有一個更好聽的名字叫Leader Election(leader選舉)。比如HBase的Master就是采用這種機制。但要注意的是分布式鎖跟同一個進程的鎖還是有區別的,所以使用的時候要比同一個進程里的鎖更謹慎的使用。

集群管理

在分布式的集群中,經常會由于各種原因,比如硬件故障,軟件故障,網絡問題,有些節點會進進出出。有新的節點加入進來,也有老的節點退出集群。這個時候,集群中其他機器需要感知到這種變化,然后根據這種變化做出對應的決策。比如我們是一個分布式存儲系統,有一個中央控制節點負責存儲的分配,當有新的存儲進來的時候我們要根據現在集群目前的狀態來分配存儲節點。這個時候我們就需要動態感知到集群目前的狀態。還有,比如一個分布式的SOA架構中,服務是一個集群提供的,當消費者訪問某個服務時,就需要采用某種機制發現現在有哪些節點可以提供該服務(這也稱之為服務發現,比如Alibaba開源的SOA框架Dubbo就采用了Zookeeper作為服務發現的底層機制)。還有開源的Kafka隊列就采用了Zookeeper作為Cosnumer的上下線管理。

437.什么是Znode?

在Zookeeper中,znode是一個跟Unix文件系統路徑相似的節點,可以往這個節點存儲或獲取數據。

Zookeeper底層是一套數據結構。這個存儲結構是一個樹形結構,其上的每一個節點,我們稱之為“znode”

zookeeper中的數據是按照“樹”結構進行存儲的。而且znode節點還分為4中不同的類型。

每一個znode默認能夠存儲1MB的數據(對于記錄狀態性質的數據來說,夠了)

可以使用zkCli命令,登錄到zookeeper上,并通過ls、create、delete、get、set等命令操作這些znode節點

438.Znode節點類型有哪些?

答:(1)PERSISTENT 持久化節點: 所謂持久節點,是指在節點創建后,就一直存在,直到有刪除操作來主動清除這個節點。否則不會因為創建該節點的客戶端會話失效而消失。

(2)PERSISTENT_SEQUENTIAL 持久順序節點:這類節點的基本特性和上面的節點類型是一致的。額外的特性是,在ZK中,每個父節點會為他的第一級子節點維護一份時序,會記錄每個子節點創建的先后順序?;谶@個特性,在創建子節點的時候,可以設置這個屬性,那么在創建節點過程中,ZK會自動為給定節點名加上一個數字后綴,作為新的節點名。這個數字后綴的范圍是整型的最大值。?在創建節點的時候只需要傳入節點 “/test_”,這樣之后,zookeeper自動會給”test_”后面補充數字。

(3)EPHEMERAL 臨時節點:和持久節點不同的是,臨時節點的生命周期和客戶端會 話綁定。也就是說,如果客戶端會話失效,那么這個節點就會自動被清除掉。注意,這里提到的是會話失效,而非連接斷開。另外,在臨時節點下面不能創建子節點。?

這里還要注意一件事,就是當你客戶端會話失效后,所產生的節點也不是一下子就消失了,也要過一段時間,大概是10秒以內,可以試一下,本機操作生成節點,在服務器端用命令來查看當前的節點數目,你會發現客戶端已經stop,但是產生的節點還在。

EPHEMERAL_SEQUENTIAL 臨時自動編號節點:此節點是屬于臨時節點,不過帶有順序,客戶端會話結束節點就消失。

439.什么是Dubbo?

Dubbo是阿里巴巴公司開源的一個高性能優秀的服務框架,使得應用可通過高性能的 RPC 實現服務的輸出和輸入功能,可以和Spring框架無縫集成。Dubbo框架,是基于容器運行的.。容器是Spring。

其核心部分包含:

1. 遠程通訊: 提供對多種基于長連接的NIO框架抽象封裝,包括多種線程模型,序列化,以及“請求-響應”模式的信息交換方式。

2. 集群容錯: 提供基于接口方法的透明遠程過程調用,包括多協議支持,以及軟負載均衡,失敗容錯,地址路由,動態配置等集群支持。

3. 自動發現: 基于注冊中心目錄服務,使服務消費方能動態的查找服務提供方,使地址透明,使服務提供方可以平滑增加或減少機器。

Dubbo能做什么?

1.透明化的遠程方法調用,就像調用本地方法一樣調用遠程方法,只需簡單配置,沒有任何API侵入。 ? ? ?

2.軟負載均衡及容錯機制,可在內網替代F5等硬件負載均衡器,降低成本,減少單點。

3. 服務自動注冊與發現,不再需要寫死服務提供方地址,注冊中心基于接口名查詢服務提供者的IP地址,并且能夠平滑添加或刪除服務提供者。

Dubbo的存在簡單來說就是要減小service層的壓力。

440.什么是RPC遠程過程調用?

遠程過程調用協議,它是一種通過網絡從遠程計算機程序上請求服務,而不需要了解底層網絡技術的協議。RPC協議假定某些傳輸協議的存在,如TCP或UDP,為通信程序之間攜帶信息數據。在OSI網絡通信模型中,RPC跨越了傳輸層和應用層。RPC使得開發包括網絡分布式多程序在內的應用程序更加容易。

441.Dubbo中有哪些角色?

registry

注冊中心. 是用于發布和訂閱服務的一個平臺.用于替代SOA結構體系框架中的ESB服務總線的。

發布

開發服務端代碼完畢后, 將服務信息發布出去. 實現一個服務的公開.

訂閱

客戶端程序,從注冊中心下載服務內容 這個過程是訂閱.

訂閱服務的時候, 會將發布的服務所有信息,一次性下載到客戶端.

客戶端也可以自定義, 修改部分服務配置信息. 如: 超時的時長, 調用的重試次數等.

Consumer

服務的消費者, 就是服務的客戶端.

消費者必須使用Dubbo技術開發部分代碼. 基本上都是配置文件定義.

provider

服務的提供者, 就是服務端.

服務端必須使用Dubbo技術開發部分代碼. 以配置文件為主.

container

容器. Dubbo技術的服務端(Provider), 在啟動執行的時候, 必須依賴容器才能正常啟動.

默認依賴的就是spring容器. 且Dubbo技術不能脫離spring框架.

在2.5.3版本的dubbo中, 默認依賴的是spring2.5版本技術. 可以選用spring4.5以下版本.

在2.5.7版本的dubbo中, 默認依賴的是spring4.3.10版本技術. 可以選擇任意的spring版本.

monitor

監控中心. 是Dubbo提供的一個jar工程.

主要功能是監控服務端(Provider)和消費端(Consumer)的使用數據的. 如: 服務端是什么,有多少接口,多少方法, 調用次數, 壓力信息等. 客戶端有多少, 調用過哪些服務端, 調用了多少次等.

442.Dubbo執行流程什么是?

0 start: 啟動Spring容器時,自動啟動Dubbo的Provider

1、register: Dubbo的Provider在啟動后自動會去注冊中心注冊內容.注冊的內容包括:

1.1 Provider的 IP

1.2 Provider 的端口.

1.3 Provider 對外提供的接口列表.哪些方法.哪些接口類

1.4 Dubbo 的版本.

1.5 訪問Provider的協議.

2、subscribe: 訂閱.當Consumer啟動時,自動去Registry獲取到所已注冊的服務的信息.

3、notify: 通知.當Provider的信息發生變化時, 自動由Registry向Consumer推送通知.

4、invoke: 調用. Consumer 調用Provider中方法

4.1 同步請求.消耗一定性能.但是必須是同步請求,因為需要接收調用方法后的結果.

5、count:次數. 每隔2分鐘,provoider和consumer自動向Monitor發送訪問次數.Monitor進行統計.

443.說說Dubbo支持的協議有哪些?

1、Dubbo協議(官方推薦協議)

優點:

采用NIO復用單一長連接,并使用線程池并發處理請求,減少握手和加大并發效率,性能較好(推薦使用)

缺點:

大文件上傳時,可能出現問題(不使用Dubbo文件上傳)

2、RMI(Remote Method Invocation)協議

優點:

JDK自帶的能力??膳c原生RMI互操作,基于TCP協議

缺點:

偶爾連接失敗.

3、Hessian協議

優點:

可與原生Hessian互操作,基于HTTP協議

缺點:

需hessian.jar支持,http短連接的開銷大

444.Dubbo支持的注冊中心有哪些?

1、Zookeeper(官方推薦)

優點:支持分布式.很多周邊產品.

缺點: 受限于Zookeeper軟件的穩定性.Zookeeper專門分布式輔助軟件,穩定較優

2、Multicast

優點:去中心化,不需要單獨安裝軟件.

缺點:Provider和Consumer和Registry不能跨機房(路由)

3、Redis

優點:支持集群,性能高

缺點:要求服務器時間同步.否則可能出現集群失敗問題.

4、Simple

優點: 標準RPC服務.沒有兼容問題

缺點: 不支持集群.

445.SessionFactory是線程安全的嗎?Session是線程安全的嗎,兩個線程能夠共享同一個Session嗎?

答:SessionFactory對應Hibernate的一個數據存儲的概念,它是線程安全的,可以被多個線程并發訪問。SessionFactory一般只會在啟動的時候構建。對于應用程序,最好將SessionFactory通過單例的模式進行封裝以便于訪問。Session是一個輕量級非線程安全的對象(線程間不能共享session),它表示與數據庫進行交互的一個工作單元。Session是由SessionFactory創建的,在任務完成之后它會被關閉。Session是持久層服務對外提供的主要接口。Session會延遲獲取數據庫連接(也就是在需要的時候才會獲?。?。為了避免創建太多的session,可以使用ThreadLocal來取得當前的session,無論你調用多少次getCurrentSession()方法,返回的都是同一個session。

446.Session的load和get方法的區別是什么?

答:主要有以下三項區別:

1)如果沒有找到符合條件的記錄, get方法返回null,load方法拋出異常

2)get方法直接返回實體類對象, load方法返回實體類對象的代理

3)在Hibernate 3之前,get方法只在一級緩存(內部緩存)中進行數據查找, 如果沒有找到對應的數據則越過二級緩存, 直接發出SQL語句完成數據讀取; load方法則可以充分利用二級緩存中的現有數據;當然從Hibernate 3開始,get方法不再是對二級緩存只寫不讀,它也是可以訪問二級緩存的

簡單的說,對于load()方法Hibernate認為該數據在數據庫中一定存在可以放心的使用代理來實現延遲加載,如果沒有數據就拋出異常,而通過get()方法去取的數據可以不存在。

447.Session的save()、update()、merge()、lock()、saveOrUpdate()和persist()方法有什么區別?

答:Hibernate的對象有三種狀態:瞬態、持久態和游離態。游離狀態的實例可以通過調用save()、persist()或者saveOrUpdate()方法進行持久化;脫管狀態的實例可以通過調用 update()、0saveOrUpdate()、lock()或者replicate()進行持久化。save()和persist()將會引發SQL的INSERT語句,而update()或merge()會引發UPDATE語句。save()和update()的區別在于一個是將瞬態對象變成持久態,一個是將游離態對象變為持久態。merge方法可以完成save()和update()方法的功能,它的意圖是將新的狀態合并到已有的持久化對象上或創建新的持久化對象。按照官方文檔的說明:(1)persist()方法把一個瞬態的實例持久化,但是并"不保證"標識符被立刻填入到持久化實例中,標識符的填入可能被推遲到flush的時間;(2) persist"保證",當它在一個事務外部被調用的時候并不觸發一個Insert語句,當需要封裝一個長會話流程的時候,一個persist這樣的函數是需要的。(3)save"不保證"第2條,它要返回標識符,所以它會立即執行Insert語句,不管是不是在事務內部還是外部。update()方法是把一個已經更改過的脫管狀態的對象變成持久狀態;lock()方法是把一個沒有更改過的脫管狀態的對象變成持久狀態。

448.什么是VSFTPD?

vsftpd 是“very secure FTP daemon”的縮寫,安全性是它的一個最大的特點。vsftpd 是一個 UNIX 類操作系統上運行的服務器的名字,它可以運行在諸如 Linux、BSD、Solaris、 HP-UNIX等系統上面,是一個完全免費的、開放源代碼的ftp服務器軟件,支持很多其他的 FTP 服務器所不支持的特征。

449.什么是Nginx?

Nginx?(engine x) 是一個高性能的HTTP和反向代理服務。Nginx是由伊戈爾·賽索耶夫為俄羅斯訪問量第二的Rambler.ru站點(俄文:Рамблер)開發的,第一個公開版本0.1.0發布于2004年10月4日。

Nginx 是一個很強大的高性能Web和反向代理服務,它具有很多非常優越的特性:在連接高并發的情況下,Nginx是Apache服務不錯的替代品:Nginx在美國是做虛擬主機生意的老板們經常選擇的軟件平臺之一。

450.Nginx有哪些作用?

答:http協議代理

搭建虛擬主機

服務的反向代理

在反向代理中配置集群的負載均衡

451.什么是正向代理?

正向代理,意思是一個位于客戶端和原始服務器(origin server)之間的服務器,為了從原始服務器取得內容,客戶端向代理發送一個請求并指定目標(原始服務器),然后代理向原始服務器轉交請求并將獲得的內容返回給客戶端??蛻舳瞬拍苁褂谜虼?。

452.什么是反向代理?

反向代理(Reverse Proxy)方式是指以代理服務器來接受internet上的連接請求,然后將請求轉發給內部網絡上的服務器,并將從服務器上得到的結果返回給internet上請求連接的客戶端,此時代理服務器對外就表現為一個反向代理服務器。

453.什么是Redis?

答:Remote Dictionary Server(Redis)是一個開源的使用ANSI?C語言編寫、支持網絡、可基于內存亦可持久化的日志型、Key-Value數據庫,并提供多種語言的API。

它通常被稱為數據結構服務器,因為值(value)可以是 字符串(String), 哈希(Map), 列表(list), 集合(sets) 和 有序集合(sorted sets)等類型。

454.Redis的特點什么是?

1. 支持多種數據結構,如 string(字符串)、 list(雙向鏈表)、dict(hash表)、set(集合)、zset(排序set)、hyperloglog(基數估算)

2. 支持持久化操作,可以進行aof及rdb數據持久化到磁盤,從而進行數據備份或數據恢復等操作,較好的防止數據丟失的手段。

3. 支持通過Replication進行數據復制,通過master-slave機制,可以實時進行數據的同步復制,支持多級復制和增量復制,master-slave機制是Redis進行HA的重要手段。

單進程請求,所有命令串行執行,并發情況下不需要考慮數據一致性問題。

455.Redis數據類型有哪些?

答:String(字符串)

Hash(hash表)

List(鏈表)

Set(集合)

SortedSet(有序集合zset)

456.Redis中的常用命令哪些?

incr 讓當前鍵值以1的數量遞增,并返回遞增后的值

incrby 可以指定參數一次增加的數值,并返回遞增后的值

incrby 可以指定參數一次增加的數值,并返回遞增后的值

decrby 可以指定參數一次遞減的數值,并返回遞減后的值

incrbyfloat 可以遞增一個雙精度浮點數

append 作用是向鍵值的末尾追加value。如果鍵不存在則將該鍵的值設置為value。返回值是追加后字符串的總長度。

mget/mset 作用與get/set相似,不過mget/mset可以同時獲得/設置多個鍵的鍵值

del 根據key來刪除value

flushdb 清除當前庫的所有數據

hset 存儲一個哈希鍵值對的集合

hget獲取一個哈希鍵的值

hmset 存儲一個或多個哈希是鍵值對的集合

hmget 獲取多個指定的鍵的值

hexists 判斷哈希表中的字段名是否存在 如果存在返回1 否則返回0

hdel 刪除一個或多個字段

hgetall 獲取一個哈希是鍵值對的集合

hvals 只返回字段值

hkeys 只返回字段名

hlen 返回key的hash的元素個數

lpush key value向鏈表左側添加

rpush key value向鏈表右側添加

lpop key 從左邊移出一個元素

rpop key 從右邊移出一個元素

llen key 返回鏈表中元素的個數 相當于關系型數據庫中 select count(*)

lrange key start end lrange命令將返回索引從start到stop之間的所有元素。Redis的列表起始索引為0。

lrange也支持負索引 lrange nn -2 -1 如 -1表示最右邊第一個元素 -2表示最右邊第二個元素,依次類推。

lindex key indexnumber 如果要將列表類型當做數組來用,lindex命令是必不可少的。lindex命令用來返回指定索引的元素,索引從0開始

如果是負數表示從右邊開始計算的索引,最右邊元素的索引是-1。

Lset key indexnumber value 是另一個通過索引操作列表的命令,它會將索引為index的元素賦值為value。

sadd?key value?添加一個string元素到,key對應的set集合中,成功返回1,如果元素已經在集合中返回0

scard?key?返回set的元素個數,如果set是空或者key不存在返回0

smembers?key?返回key對應set的所有元素,結果是無序的

sismember?key value?判斷value 是否在set中,存在返回1,0表示不存在或者key不存在

srem key value 從key對應set中移除給定元素,成功返回1,如果value 在集合中不存在或者key不存在返回0

zadd key score value 將一個或多個value及其socre加入到set中

zrange key start end 0和-1表示從索引為0的元素到最后一個元素(同LRANGE命令相似)

zrange key 0 -1 withscores 也可以連同score一塊輸出,使用WITHSCORES參數

zremrangebyscore key start end 可用于范圍刪除操作

ping 測試redis是否鏈接 如果已鏈接返回 PONG

echo value測試redis是否鏈接 如果已鏈接返回 echo命令后給定的值

keys * 返回所有的key 可以加*通配

exists key判斷string類型一個key是否存在 如果存在返回1 否則返回0

expire key time(s) 設置一個key的過期時間 單位秒。時間到達后會刪除key及value

ttl key 查詢已設置過期時間的key的剩余時間 如果返回-2表示該鍵值對已經被刪除

persist 移除給定key的過期時間

select dbindex 選擇數據庫(0-15)

move key dbIndex 將當前數據庫中的key轉移到其他數據庫中

dbsize 返回當前數據庫中的key的數目

info 獲取服務器的信息和統計

flushdb 刪除當前選擇的數據庫中的key

flushall 刪除所有數據庫中的所有key

quit 退出連接

457.Redis的配置以及持久化方案有幾種?

答:以下兩種

RDB方式

AOF方式

458.什么是RDB方式?

答:是RDB是對內存中數據庫狀態進行快照

RDB方式:將Redis在內存中的數據庫狀態保存到磁盤里面,RDB文件是一個經過壓縮的二進制文件,通過該文件可以還原生成RDB文件時的數據庫狀態(默認下,持久化到dump.rdb文件,并且在redis重啟后,自動讀取其中文件,據悉,通常情況下一千萬的字符串類型鍵,1GB的快照文件,同步到內存中的 時間是20-30秒)

RDB的生成方式:

 1、執行命令手動生成

有兩個Redis命令可以用于生成RDB文件,一個是SAVE,另一個是BGSAVE SAVE命令會阻塞Redis服務器進程,直到RDB文件創建完畢為止,在服務器進程阻塞期間,服務器不能處理任何命令請求,BGSAVE命令會派生出一個子進程,然后由子進程負責創建RDB文件,服務器進程(父進程)繼續處理命令請求,創建RDB文件結束之前,客戶端發送的BGSAVE和SAVE命令會被服務器拒絕

2、通過配置自動生成

可以設置服務器配置的save選項,讓服務器每隔一段時間自動執行一次BGSAVE命令,可以通過save選項設置多個保存條件,但只要其中任意一個條件被滿足,服務器就會執行BGSAVE命令

例如:

save 900 1

save 300 10

save 60 10000

那么只要滿足以下三個條件中的任意一個,BGSAVE命令就會被執行

服務器在900秒之內,對數據庫進行了至少1次修改

服務器在300秒之內,對數據庫進行了至少10次修改

服務器在60秒之內,對數據庫進行了至少10000次修改

459.什么是AOF方式?

AOF持久化方式在redis中默認是關閉的,需要修改配置文件開啟該方式。

AOF:把每條命令都寫入文件,類似mysql的binlog日志

AOF方式:是通過保存Redis服務器所執行的寫命令來記錄數據庫狀態的文件。

AOF文件刷新的方式,有三種:

appendfsync always - 每提交一個修改命令都調用fsync刷新到AOF文件,非常非常慢,但也非常安全

appendfsync everysec - 每秒鐘都調用fsync刷新到AOF文件,很快,但可能會丟失一秒以內的數據

appendfsync no - 依靠OS進行刷新,redis不主動刷新AOF,這樣最快,但安全性就差

默認并推薦每秒刷新,這樣在速度和安全上都做到了兼顧

AOF數據恢復方式

服務器在啟動時,通過載入和執行AOF文件中保存的命令來還原服務器關閉之前的數據庫狀態,具體過程:

載入AOF文件

創建模擬客戶端

從AOF文件中讀取一條命令

使用模擬客戶端執行命令

循環讀取并執行命令,直到全部完成

如果同時啟用了RDB和AOF方式,AOF優先,啟動時只加載AOF文件恢復數據

460.什么是全文檢索?

答:什么叫做全文檢索呢?這要從我們生活中的數據說起。

我們生活中的數據總體分為兩種:結構化數據和非結構化數據。

1)結構化數據:指具有固定格式或有限長度的數據,如數據庫,元數據等。

2)非結構化數據:指不定長或無固定格式的數據,如郵件,word文檔等。

非結構化數據又一種叫法叫全文數據。

?按照數據的分類,搜索也分為兩種:

1)對結構化數據的搜索:如對數據庫的搜索,用SQL語句。

2)對非結構化數據的搜索:如利用windows的搜索也可以搜索文件內容,

全文檢索: 就是一種將文件中所有文本與檢索項匹配的文字資料檢索方法。全文檢索首先將要查詢的目標文檔中的詞提取出來,組成索引,通過查詢索引達到搜索目標文檔的目的。這種先建立索引,再對索引進行搜索的過程就叫全文檢索(Full-text Search)。

461.什么是Lucene?

Lucene是一個高效的,基于Java的全文檢索庫。

Lucene是apache軟件基金會4 jakarta項目組的一個子項目,是一個開放源代碼的全文檢索引擎工具包,但它不是一個完整的全文檢索引擎,而是一個全文檢索引擎的架構,Lucene的目的是為軟件開發人員提供一個簡單易用的工具包,以方便的在目標系統中實現全文檢索的功能,或者是以此為基礎建立起完整的全文檢索引擎。Lucene是一套用于全文檢索和搜尋的開源程序庫,由Apache軟件基金會支持和提供。Lucene提供了一個簡單卻強大的應用程序接口,能夠做全文索引和搜尋。在Java開發環境里Lucene是一個成熟的免費開源工具。就其本身而言,Lucene是當前以及最近幾年最受歡迎的免費Java信息檢索程序庫。

462.什么是Solr?

答:Solr是一個獨立的企業級搜索應用服務器,它對外提供類似于Web-service的API接口。

Solr是一個高性能,采用Java開發,基于Lucene的全文搜索服務器。同時對其進行了擴展,提供了比Lucene更為豐富的查詢語言,同時實現了可配置、可擴展并對查詢性能進行了優化,并且提供了一個完善的功能管理界面,是一款非常優秀的全文檢索引擎。

文檔通過Http利用XML 加到一個搜索集合中。查詢該集合也是通過http收到一個XML/JSON響應來實現。它的主要特性包括:高效、靈活的緩存功能,垂直搜索功能,高亮顯示搜索結果,通過索引復制來提高可用性,提供一套強大Data Schema來定義字段,類型和設置文本分析,提供基于Web的管理界面等。

463.Solr是由哪兩個部分構成?

答:如下兩個部分

Solr的web服務

Solr的索引庫

464.什么是正排索引?

正排索引是以文檔的ID為關鍵字,索引文檔中每個字的位置信息,查找時掃描索引中每個文檔中字的信息直到找出所有包含查詢關鍵字的文檔。

但是在查詢的時候需對所有的文檔進行掃描以確保沒有遺漏,這樣就使得檢索時間大大延長,檢索效率低下。 ? ??

盡管正排索引的工作原理非常的簡單,但是由于其檢索效率太低,除非在特定情況下,否則實用性價值不大。

465.什么是倒排索引?

對數據進行分析,抽取出數據中的詞條,以詞條作為key,對應數據的存儲位置作為value,實現索引的存儲。這種索引稱為倒排索引。

當solr存儲文檔時,solr會首先對文檔數據進行分詞,創建索引庫和文檔數據庫。所謂的分詞是指:將一段字符文本按照一定的規則分成若干個單詞。

466.什么是ActiveMQ?

ActiveMQ是一種開源的,實現了JMS1.1規范的,面向消息(MOM)的中間件,為應用程序提供高效的、可擴展的、穩定的和安全的企業級消息通信。ActiveMQ使用Apache提供的授權,任何人都可以對其實現代碼進行修改。

ActiveMQ的設計目標是提供標準的,面向消息的,能夠跨越多語言和多系統的應用集成消息通信中間件。

ActiveMQ實現了JMS標準并提供了很多附加的特性。這些附加的特性包括,JMX管理(java Management Extensions,即java管理擴展),主從管理(master/salve,這是集群模式的一種,主要體現在可靠性方面,當主中介(代理)出現故障,那么從代理會替代主代理的位置,不至于使消息系統癱瘓)、消息組通信(同一組的消息,僅會提交給一個客戶進行處理)、有序消息管理(確保消息能夠按照發送的次序被接受者接收)。消息優先級(優先級高的消息先被投遞和處理)、訂閱消息的延遲接收(訂閱消息在發布時,如果訂閱者沒有開啟連接,那么當訂閱者開啟連接時,消息中介將會向其提交之前的,其未處理的消息)、接收者處理過慢(可以使用動態負載平衡,將多數消息提交到處理快的接收者,這主要是對PTP消息所說)、虛擬接收者(降低與中介的連接數目)、成熟的消息持久化技術(部分消息需要持久化到數據庫或文件系統中,當中介崩潰時,信息不會丟失)、支持游標操作(可以處理大消息)、支持消息的轉換、通過使用Apache的Camel可以支持EIP、使用鏡像隊列的形式輕松的對消息隊列進行監控等。

467.消息服務的應用場景有哪些?

答:如下3個場景都可以使用消息服務

1、異步處理

2、應用的解耦

3、流量的削峰

468.什么是JMS?

JMS(Java Messaging Service)是Java平臺上有關面向消息中間件的技術規范,它便于消息系統中的Java應用程序進行消息交換,并且通過提供標準的產生、發送、接收消息的接口,簡化企業應用的開發。

469.JMS有哪些模型?

答:JMS消息機制主要分為兩種模型:PTP模型和Pub/Sub模型。

1、PTP模型:(Point? to Point 對點模型) 每一個消息傳遞給一個消息消費者,保證消息傳遞給消息消費者,且消息不會同時被多個消費者接收。如果消息消費者暫時不在連接范圍內,JMS會自動保證消息不會丟失,直到消息消費者進入連接,消息將自動送達。因此,JMS需要將消息保存到永久性介質上,例如數據庫或者文件。

2、Pub-Sub模型:(publish-subscription 發布者訂閱者模型)每個主題可以擁有多個訂閱者。JMS系統負責將消息的副本傳給該主題的每個訂閱者。

如果希望每一條消息都能夠被處理,那么應該使用PTP消息模型。如果并不要求消息都必須被消息消費者接收到的情況下,可使用pub-sub消息模型。Pub-Sub模型可以在一對多的消息廣播時使用。

470.什么是JsonP?

Jsonp(JSON with Padding) 是 json 的一種"使用模式",可以讓網頁從別的域名(網站)那獲取資料,即跨域讀取數據。

471.什么是跨域?

跨域是指一個域(網站)下的文檔或腳本試圖去請求另一個域(網站)下的資源。

472.什么是同源策略?

同源策略/SOP(Same origin policy)是一種約定,由Netscape公司1995年引入瀏覽器,它是瀏覽器最核心也最基本的安全功能,現在所有支持JavaScript 的瀏覽器都會使用這個策略。如果缺少了同源策略,瀏覽器很容易受到XSS、CSFR等攻擊。所謂同源是指"協議+域名+端口"三者相同,即便兩個不同的域名指向同一個ip地址,也非同源

473.什么是MyCat?

MyCat是目前最流行的基于java語言編寫的數據庫中間件,是一個實現了MySQL協議的服務器,前端用戶可以把它看作是一個數據庫代理,用MySQL客戶端工具和命令行訪問,而其后端可以用MySQL原生協議與多個MySQL服務器通信,也可以用JDBC協議與大多數主流數據庫服務器通信,其核心功能是分庫分表。配合數據庫的主從模式還可實現讀寫分離。

MyCat是基于阿里開源的Cobar產品而研發,Cobar的穩定性、可靠性、優秀的架構和性能以及眾多成熟的使用案例使得MyCat變得非常的強大。

MyCat發展到目前的版本,已經不是一個單純的MySQL代理了,它的后端可以支持MySQL、SQL Server、Oracle、DB2、PostgreSQL等主流數據庫,也支持MongoDB這種新型NoSQL方式的存儲,未來還會支持更多類型的存儲。而在最終用戶看來,無論是那種存儲方式,在MyCat里,都是一個傳統的數據庫表,支持標準的SQL語句進行數據的操作,這樣一來,對前端業務系統來說,可以大幅降低開發難度,提升開發速度。

474.什么是縱向切分/垂直切分?

就是把原本存儲于一個庫的數據存儲到多個庫上。

由于對數據庫的讀寫都是對同一個庫進行操作,所以單庫并不能解決大規模并發寫入的問題。

例如,我們會建立定義數據庫workDB、商品數據庫payDB、用戶數據庫userDB、日志數據庫logDB等,分別用于存儲項目數據定義表、商品定義表、用戶數據表、日志數據表等。

優點

1)減少增量數據寫入時的鎖對查詢的影響。

2)由于單表數量下降,常見的查詢操作由于減少了需要掃描的記錄,使得單表單次查詢所需的檢索行數變少,減少了磁盤IO,時延變短。

缺點:

無法解決單表數據量太大的問題。

橫向切分/水平切分

把原本存儲于一個表的數據分塊存儲到多個表上。當一個表中的數據量過大時,我們可以把該表的數據按照某種規則,進行劃分,然后存儲到多個結構相同的表,和不同的庫上。

例如,我們userDB中的userTable中數據量很大,那么可以把userDB切分為結構相同的多個userDB:part0DB、part1DB等,再將userDB上的userTable,切分為很多userTable:userTable0、userTable1等,然后將這些表按照一定的規則存儲到多個userDB上。

優點:

1)單表的并發能力提高了,磁盤I/O性能也提高了。

2)如果出現高并發的話,總表可以根據不同的查詢,將并發壓力分到不同的小表里面。

缺點:無法實現表連接查詢。

475.簡述Tomcat,Apache,JBoss和WebLogic的區別和聯系

答:Apache:全球應用最廣泛的http服務器,免費,出自apache基金組織?

Tomcat:應用也算非常廣泛的web 服務器,支持部分j2ee,免費,出自 apache基金組織?

JBoss:開源的應用服務器,比較受人喜愛,免費(文檔要收費)?

weblogic:應該說算是業界第一的app server,全部支持j2ee1.4(收費)

JBoss也支持j2ee

JBoss和WebLogic都含有Jsp和Servlet容器,也就可以做web容器,?

JBoss和WebLogic也包含EJB容器,是完整的J2EE應用服務器

tomcat 只能做jsp和servlet的container

476.以下可以實現負載均衡的是()
A. nagios
B. Jenkins
C. nginx
D. docker
分析:答案: C Nginx是一款輕量級的Web?服務器/反向代理服務器及電子郵件(IMAP/POP3)代理服務器,并在一個BSD-like 協議下發行。其特點是占有內存少,并發能力強,事實上nginx的并發能力確實在同類型的網頁服務器中表現較好,中國大陸使用nginx網站用戶有:百度、京東、新浪、網易、騰訊、淘寶等
477.Tomcat/ WebSphere/WebLogic的作用和特點

作用:

Tomcat:目前應用非常廣泛的免費web服務器,支持部分j2ee。

WebSphere:是IBM集成軟件平臺??勺鰓eb服務器,WebSphere提供了可靠、靈活和健壯的集成軟件。

Weblogic:是美國bea公司出品的一個基于j2ee架構的中間件。BEA WebLogic是用于開發、集成、部署和管理大型分布式Web應用、網絡應用和數據庫應用的Java應用服務器。

特點(區別):

1)價位不同:Tomcat的是免費的;WebLogic與WebSphere是收費的,而且價格不菲。

2) 開源性不同:Tomcat的是完全開源的,而其他兩個不是。WebLogic與WebSphere都是對業內多種標準的全面支持,包括JSB、JMS、JDBC、XML和WML,使Web應用系統實施更簡單,且保護投資,同時也使基于標準的解決方案的開發更加簡便。

3) 擴展性的不同:WebLogic和WebSphere都是以其高擴展的架構體系聞名于業內,包括客戶機連接的共享、資源 pooling以及動態網頁。

4)應用范圍的區別:Tomcat 是一個小型的輕量級應用服務器,在中小型系統和并發訪問用戶不是很多的場合下被普遍使用,是開發和調試JSP 程序的首選。WebLogic和WebSphere是商業軟件,功能齊全強大,主要應用于大型企業的大型項目。

5)安全性問題區別:因為Tomcat是開源的,所以它們的安全性相對來說比較低,萬一應用服務器本身有什么漏洞,你是沒辦法向Apache索賠的。而WebLogic和WebSphere其容錯、系統管理和安全性能已經在全球數以千記的關鍵任務環境中得以驗證。

478.B/S和C/S的含義及其區別

C/S結構,即Client/Server(客戶機/服務器)結構,通過將任務合理分配到Client端和Server端,降低了系統的通訊開銷,可充分利用兩端硬件環境優勢。早期軟件系統多以此作為首選設計標準。

B/S結構,即Browser/Server(瀏覽器/服務器)結構,是隨著Internet技術的興起,對C/S結構的一種變化或者改進的結構。在這種結構下,用戶界面完全通過WWW瀏覽器實現,一部分事務邏輯在前端實現,但是主要事務邏輯在服務器端實現,節約了開發成本,便于軟件維護。

區別

1、C/S是建立在局域網的基礎上的。B/S是建立在廣域網的基礎上的,但并不是說B/S結構不能在局域網上使用。

2、B/S業務擴展簡單方便,通過增加頁面即可增加服務器功能。C/S的客戶端還需要安裝專用的客戶端軟件,不利于擴展。

3、B/S維護簡單方便。開發、維護等幾乎所有工作也都集中在服務器端,當企業對網絡應用進行升級時,只需更新服務器端的軟件就可以,這減輕了異地用戶系統維護與升級的成本

4、B/S響應速度不及C/S;

5、B/S用戶體驗效果不是很理想

479.說說你對容器的理解

容器也是 java 程序,它的主要作用是為應用程序提供運行環境。容器用來接管安全性、并發性、事務處理、交換到輔助存儲器和其它服務的責任

以tomcat為例:Tomcat是一個后臺服務進程,其它的servlet(相當于DLL)是在Tomcat容器內運行,Broswer只與Tomcat通迅; Tomcat接受browser的請求,經過一系列動作(如果是靜態網頁,那么裝載,按http協議形成響應流;如果是動態的如JSP,那就要調用JDK 中的servlet.jsp接口,解釋形成靜態網頁,按http協議生成響應流發送回browser)后,形成靜態網頁,返回響應。

480.為什么要使用連接池?

?傳統的數據庫連接方式

一個連接對象對應一個物理連接

每次操作都打開一個物理連接,

使用完都關閉連接,造成系統性能低下。

?連接池技術

客戶程序得到的連接對象是連接池中物理連接的一個句柄,調用連接對象的close()方法,物理連接并沒有關閉,數據源的實現只是刪除了客戶程序中的連接對象和池中的連接對象之間的聯系.

?數據庫連接的建立及關閉是耗費系統資源的操作,在大型應用中對系統的性能影響尤為明顯。為了能重復利用數據庫連接對象,縮短請求的響應時間和提高服務器的性能,支持更多的客戶,應采用連接池技術.

481.數據庫連接池的原理

數據庫連接池的原理

傳統連接方式:

首先調用Class.forName()方法加載數據庫驅動,

然后調用DriverManager.getConnection()方法建立連接.

連接池技術:

連接池解決方案是在應用程序啟動時就預先建立多個數據庫連接對象,然后將連接對象保存到連接池中。

當客戶請求到來時,從池中取出一個連接對象為客戶服務。

當請求完成時,客戶程序調用close()方法,將連接對象放回池中.

對于多于連接池中連接數的請求,排隊等待。

應用程序還可根據連接池中連接的使用率,動態增加或減少池中的連接數。

482.MVC模式及其優缺點

一、MVC原理

MVC是一種程序開發設計模式,它實現了顯示模塊與功能模塊的分離。提高了程序的可維護性、可移植性、可擴展性與可重用性,降低了程序的開發難度。它主要分模型、視圖、控制器三層。

1、模型(model)它是應用程序的主體部分,主要包括業務邏輯模塊和數據模塊。模型與數據格式無關,這樣一個模型能為多個視圖提供數據。由于應用于模型的代碼只需寫一次就可以被多個視圖重用,所以減少了代碼的重復性

2、視圖(view) 用戶與之交互的界面、在web中視圖一般由jsp,html組成

3、控制器(controller)接收來自界面的請求 并交給模型進行處理 在這個過程中控制器不做任何處理只是起到了一個連接的作用

二、MVC的優點

1、降低代碼耦合性。在MVC模式中,三個層各施其職,所以如果一旦哪一層的需求發生了變化,就只需要更改相應的層中的代碼而不會影響到其他層中的代碼。

2、有利于分工合作。在MVC模式中,由于按層把系統分開,那么就能更好的實現開發中的分工。網頁設計人員可進行開發視圖層中的JSP,而對業務熟悉的人員可開發業務層,而其他開發人員可開發控制層。

3、有利于組件的重用。如控制層可獨立成一個能用的組件,表示層也可做成通用的操作界面??梢詾橐粋€模型在運行時同時建立和使用多個視圖。

三、MVC的不足之處

1、增加了系統結構和實現的復雜性。對于簡單的界面,嚴格遵循MVC,使模型、視圖與控制器分離,會增加結構的復雜性,并可能產生過多的更新操作,降低運行效率。

2、視圖與控制器間的過于緊密的連接。視圖與控制器是相互分離,但確實聯系緊密的部件,視圖沒有控制器的存在,其應用是很有限的,反之亦然,這樣就妨礙了他們的獨立重用。

3、視圖對模型數據的低效率訪問。依據模型操作接口的不同,視圖可能需要多次調用才能獲得足夠的顯示數據。對未變化數據的不必要的頻繁訪問,也將損害操作性能。

4、目前,一般高級的界面工具或構造器不支持模式。改造這些工具以適應MVC需要和建立分離的部件的代價是很高的,從而造成MVC使用的困難。

483.MVC模式完成分頁功能的基本思路是什么?

1)頁面提交頁碼(第幾頁)到Servlet中

2)Servlet接收到頁碼后,將頁碼傳遞給分頁工具類(PageBean)

3)Servlet中調用Service層傳入PageBean對象

4)Service層調用DAO層傳入PageBean對象

5)Servlet中得到查詢出來的數據,并setAttrivute保存

6)在頁面中得到(getAttribute)數據,遍歷輸出

484.常用的Web容器

答: Unix和Linux平臺下使用最廣泛的免費HTTP服務器是Apache服務器,而Windows平臺的服務器通常使用IIS作為Web服務器。選擇Web服務器應考慮的因素有:性能、安全性、日志和統計、虛擬主機、代理服務器、緩沖服務和集成應用程序等。下面是對常用服務器的簡介:

IIS:Microsoft的Web服務器產品為Internet Information Services。IIS 是允許在公共Intranet或Internet上發布信息的Web服務器。IIS是目前最流行的Web服務器產品之一,很多著名的網站都是建立在IIS的平臺上。IIS提供了一個圖形界面的管理工具,稱為Internet服務管理器,可用于監視配置和控制Internet服務。IIS是一種Web服務組件,其中包括Web服務器、FTP服務器、NNTP服務器和SMTP服務器,分別用于網頁瀏覽、文件傳輸、新聞服務和郵件發送等方面,它使得在網絡(包括互聯網和局域網)上發布信息成了一件很容易的事。它提供ISAPI(Intranet Server API)作為擴展Web服務器功能的編程接口;同時,它還提供一個Internet數據庫連接器,可以實現對數據庫的查詢和更新。

Kangle:Kangle Web服務器是一款跨平臺、功能強大、安全穩定、易操作的高性能Web服務器和反向代理服務器軟件。此外,Kangle也是一款專為做虛擬主機研發的Web服務器。實現虛擬主機獨立進程、獨立身份運行。用戶之間安全隔離,一個用戶出問題不影響其他用戶。支持PHP、ASP、ASP.NET、Java、Ruby等多種動態開發語言。

WebSphere:WebSphere Application Server是功能完善、開放的Web應用程序服務器,是IBM電子商務計劃的核心部分,它是基于Java的應用環境,用于建立、部署和管理Internet和Intranet Web應用程序,適應各種Web應用程序服務器的需要,范圍從簡單到高級直到企業級。

WebLogic:BEA WebLogic Server是一種多功能、基于標準的Web應用服務器,為企業構建自己的應用提供了堅實的基礎。各種應用開發、部署所有關鍵性的任務,無論是集成各種系統和數據庫,還是提交服務、跨Internet協作,Weblogic都提供了相應的支持。由于它具有全面的功能、對開放標準的遵從性、多層架構、支持基于組件的開發,基于Internet的企業都選擇它來開發、部署最佳的應用。BEA WebLogic Server在使應用服務器成為企業應用架構的基礎方面一直處于領先地位,為構建集成化的企業級應用提供了穩固的基礎,它們以 Internet的容量和速度,在連網的企業之間共享信息、提交服務,實現協作自動化。

Apache:目前Apache仍然是世界上用得最多的Web服務器,市場占有率約為60%左右。世界上很多著名的網站都是Apache的產物,它的成功之處主要在于它的源代碼開放、有一支強大的開發團隊、支持跨平臺的應用(可以運行在幾乎所有的Unix、Windows、Linux系統平臺上)以及它的可移植性等方面。

Tomcat:Tomcat是一個開放源代碼、運行Servlet和JSP的容器。TomcatServer實現了Servlet和JSP規范。此外,Tomcat還實現了Apache-Jakarta規范而且比絕大多數商業應用軟件服務器要好,因此目前也有不少的Web服務器都選擇了Tomcat。

Nginx:讀作"engine x",是一個高性能的HTTP和反向代理服務器,也是一個IMAP/POP3/SMTP代理服務器。 Nginx是由Igor Sysoev為俄羅斯訪問量第二的 Rambler.ru站點開發的,第一個公開版本0.1.0發布于2004年10月4日。其將源代碼以類BSD許可證的形式發布,因它的穩定性、豐富的功能集、示例配置文件和低系統資源的消耗而聞名。

485.Java Web開發的Model 1和Model 2分別指的是什么?

答:Model 1是以頁面為中心的Java Web開發,只適合非常小型的應用程序,Model 2是基于MVC架構模式的應用,這一點在前文的面試題中已經詳細講解過了。

486.說說什么是框架:

框架(framework)是一個框子--》指約束性,也是一個架子--》指支撐性IT語境中的框架,特指為解決一個開放性問題而設計的具有一定約束性的支撐結構,在此結構上可以根據具體問題擴展、按插更多的組成部分,從而更迅速和方便地架構完整的解決問題的方案。

1)框架本身一般不完整到可以解決特定問題,但是可以幫助您快速解決特定問題:

沒有框架所有的工作都從零開始做,有了框架,為我們提供了一定的功能。我們就可以在框架的基礎上開發,極大的解決了生產力。

不同的框架,是為了解決不同領域的問題,一定要為了解決問題才去學習框架。

2)框架天生就是為了擴展而設計的

3)框架里面可以為后續的組件提供很多輔助性、支撐性的方便易用的實用工具(utilities),也就是框架時常配套一些幫組解決某類問題的庫(libraries)或工具(tools).

在java中就是一系列的jar包,其本質就是對jdk功能的擴展。

487.簡單說一下MVC框架?

是為了解決傳統MVC模式(jsp+servlet+javabean)一些問題而出現的框架

傳統MVC模式模式問題:

1) 所有的Servlet和Servlet映射都要配置在web.xml中,如果項目太大,web.xml就太龐大并且不能實現模塊化管理。

2)Servlet的主要功能就是接受參數、調用邏輯、跳轉頁面,比如像其他字符編碼、文件上傳等功能也要寫在Servlet中,不能讓Servlet主要功能而需要做處理一些特例。

3)接受參數比較麻煩

(String name = request.getParameter(“name”)),不能通過model接受,只能單個接收,接收完成后轉換封裝model。

4)跳轉頁面方式比較單一(forward,redirect),并且當我們的頁面名稱發生改變時需要改變Servlet源代碼。

現在比較常用的MVC框架:

webwork

Struts

Struts2

SpringMVC

488.簡單講一下struts2的執行流程

?一個請求在struts2框架中處理大概分為一下幾個步驟:

1)客戶瀏覽器發送一個指向Servlet容器(例如Tomcat)的請求

2)這個請求經過一系列的過濾器(Filter)(這些過濾器中有一個叫做ActionContextCleanUp的可選過濾器,這個過濾器對于Struts2和其他框架的集成很有幫助,例如:SiteMesh Plugin)

3)接著FilterDispatcher(StrutsPrepareAndExecuteFilter)被調用,FilterDispatcher詢問ActionMapper來決定這個請是否需要調用某個Action

4)如果ActionMapper決定需要調用某個Action,FilterDispatcher把請求的處理交給ActionProxy

5)ActionProxy通過Configuration Manager詢問框架的配置文件,找到需要調用的Action類

6)ActionProxy創建一個ActionInvocation的實例。

7)ActionInvocation實例使用命名模式來調用,在調用Action的過程前后,涉及到相關攔截器(Intercepter)的調用。

8)一旦Action執行完畢,ActionInvocation負責根據struts.xml中的配置找到對應的返回結果。返回結果通常是(但不總是,也 可 能是另外的一個Action鏈)一個需要被表示的JSP或者FreeMarker的模版。在表示的過程中可以使用Struts2 框架中繼承的標簽。在這個過程中需要涉及到ActionMapper

489.Struts2中的攔截器,你都用它干什么?

java里的攔截器是動態攔截Action調用的對象,它提供了一種機制可以使開發者定義一個action執行的前后執行的代碼,也可以在一個action執行前阻止其執行,同時也提供了一種可以提取action中可重用部分的方式。

在AOP(Aspect Oriented Programming)中攔截器用于在某個方法或字段被訪問之前,進行攔截后在之前或之后加入某些操作

1)struts2中的功能(參數處理、文件上傳、字符編碼等)都是通過系統攔截器實現的

2)當然我們也可以自定義攔截器,進行可插拔配置,可以執行Action的方法前后,加入相關邏輯完成業務。

使用場景:

1)用戶登錄判斷,在執行action的前面判斷是否已經登錄,如果沒有登錄的就跳轉登錄頁面。

2)用戶權限判斷,在執行action的前面判斷是否具有,如果沒有權限就給出提示信息。

3)操作日志...

490.簡單講一下SpringMVC的執行流程?

1)用戶向服務器發送請求,請求被Spring 前端控制Servelt DispatcherServlet捕獲;

2)DispatcherServlet 對請求URL進行解析,得到請求資源標識符(URI)。然后根據該URI,調用HandlerMapping獲得該Handler配置的所有相關的對象 (包括Handler對象以及Handler對象對應的攔截器),最后以HandlerExecutionChain對象的形式返回;

3)DispatcherServlet 根據獲得的Handler,選擇一個合適的HandlerAdapter。(附注:如果成功獲得HandlerAdapter后,此時將開始執行攔截器的preHandler(...)方法)

4) 提取Request中的模型數據,填充Handler入參,開始執行Handler(Controller)。 在填充Handler的入參過程中,根據你的配置,Spring將幫你做一些額外的工作:

HttpMessageConveter: 將請求消息(如Json、xml等數據)轉換成一個對象,將對象轉換為指定的響應信息

數據轉換:對請求消息進行數據轉換。如String轉換成Integer、Double等

數據根式化:對請求消息進行數據格式化。 如將字符串轉換成格式化數字或格式化日期等

數據驗證: 驗證數據的有效性(長度、格式等),驗證結果存儲到BindingResult或Error中

5)Handler執行完成后,向DispatcherServlet?返回一個ModelAndView對象;

6)根據返回的ModelAndView,選擇一個適合的ViewResolver(必須是已經注冊到Spring容器中的ViewResolver)返回給DispatcherServlet?;

7)ViewResolver 結合Model和View,來渲染視圖

8)將渲染結果返回給客戶端。

快速記憶:

核心控制器捕獲請求,查找Hander,執行Handler,選擇ViewResolver,通過ViewResoler渲染視圖并返回

491.簡單說一下struts2和springMVC有什么不同

目前企業中使用SpringMvc的比例已經遠遠超過Struts2,那么兩者到底有什么區別,是很多初學者比較關注的問題,下面我們就來對SpringMvc和Struts2進行各方面的比較:

1)核心控制器(前端控制器、預處理控制器):對于使用過mvc框架的人來說這個詞應該不會陌生,核心控制器的主要用途是處理所有的請求,然后對那些特殊的請求 (控制器)統一的進行處理(字符編碼、文件上傳、參數接受、異常處理等等),spring mvc核心控制器是Servlet,而Struts2是Filter。

2)控制器實例:Spring Mvc會比Struts快一些(理論上)。Spring Mvc是基于方法設計,而Sturts是基于對象,每次發一次請求都會實例一個action,每個action都會被注入??屬性,而Spring更像Servlet一樣,只有一個實例,每次請求執行對應的方法即可(注意:由于是單例實例,所以應當避免全局變量的修改,這樣會產生線程安全問題 )

3)管理方式:大部分的公司的核心架構中,就會使用到spring,而spring mvc又是spring中的一個模塊,所以spring對于spring mvc的控制器管理更加簡單方便,而且提供了全 注解方式進行管理,各種功能的注解都比較全面,使用簡單,而struts2需要采用XML很多的配置參數來管理(雖然也可以采用注解,但是幾乎沒有公司那 樣使用)

4)參數傳遞:Struts2中自身提供多種參數接受,其實都是通過(ValueStack)進行傳遞和賦值,而SpringMvc是通過方法的參數進行接收。

5)學習難度:Struts更加很多新的技術點,比如攔截器、值棧及OGNL表達式,學習成本較高,springmvc 比較簡單,很較少的時間都能上手。

6)intercepter 的實現機制:struts有以自己的interceptor機制,spring mvc用的是獨立的AOP方式。這樣導致struts的配置文件量還是比spring mvc大,雖然struts的配置能繼承,所以我覺得論使用上來講,spring mvc使用更加簡潔,開發效率Spring MVC確實比struts2高。spring mvc是方法級別的攔截,一個方法對應一個request上下文,而方法同時又跟一個url對應,所以說從架構本身上spring3 mvc就容易實現restful url。struts2是類級別的攔截,一個類對應一個request上下文;實現restful url要費勁,因為struts2 action的一個方法可以對應一個url;而其類屬性卻被所有方法共享,這也就無法用注解或其他方式標識其所屬方法了。spring3 mvc的方法之間基本上獨立的,獨享request response數據,請求數據通過參數獲取,處理結果通過ModelMap交回給框架方法之間不共享變量,而struts2搞的就比較亂,雖然方法之間 也是獨立的,但其所有Action變量是共享的,這不會影響程序運行,卻給我們編碼,讀程序時帶來麻煩。

7)spring mvc處理ajax請求,直接通過返回數據,方法中使用注解@ResponseBody,spring mvc自動幫我們對象轉換為JSON數據。而struts2是通過插件的方式來處理。

在springMVC流行起來之前,struts2在MVC框架中占核心地位,隨著SpringMVC的出現,SpringMVC慢慢的取代了struts2,但是很多的企業原來搭建的框架都是使用struts2。

492.說一下Spring中的兩大核心

Spring是什么?

Spring是J2EE應用程序框架,是輕量級的IOC和AOP的容器框架,主要針對JavaBean的生命周期進行管理的輕量級容器,可以單獨使用,也可以和struts框架,ibatis框架等組合使用。

1)IOC(Inversion of Control)

ioc控制反轉,又稱為“依賴注入”;

IOC的基本概念是:不創建對象,但是描述創建它們的方式。在代碼中不直接與對象和服務連接,但在配置文件中描述哪一個組件需要哪一項服務。容器負責將這些聯系在一起。   

其原理是基于OO設計原則的The Hollywood Principle:Don't call us, we'll call you(別找我,我會來找你的)。也就是說,所有的組件都是被動的(Passive),所有的組件初始化和調用都由容器負責。組件處在一個容器當中,由容 器負責管理。   

簡單的來講,就是由容器控制程序之間的關系,而非傳統實現中,由程序代碼直接操控。這也就是所謂“控制反轉”的概念所在:控制權由應用代碼中轉到了外部容器,控制權的轉移,是所謂反轉。

2)AOP 面向切面編程

核心原理:使用動態代理的設計模式在執行方法前后或出現異常常做加入相關邏輯

我們使用AOP來做:

1)事務處理:執行方法前開啟事務,執行完成后關閉事務,出現異常后回滾事務

2)權限判斷:在執行方法前,判斷是否具有權限

3)日志:在執行前進行日志處理

493.講一下Spring的事務的傳播特性

多個事物存在是怎么處理的策略

1)PROPAGATION_REQUIRED:如果存在一個事務,則支持當前事務,如果當前沒有事務,就新建一個事務。這是最常見的選擇。

2)PROPAGATION_SUPPORTS:如果存在一個事務,支持當前事務,如果當前沒有事務,就以非事務方式執行。

3)PROPAGATION_MANDATORY:如果存在一個事務,支持當前事務,如果當前沒有事務,就拋出異常。

4)PROPAGATION_REQUIRES_NEW:新建事務,如果當前存在事務,把當前事務掛起。

5)PROPAGATION_NOT_SUPPORTED:以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。

6)PROPAGATION_NEVER:以非事務方式執行,如果當前存在事務,則拋出異常。

7)PROPAGATION_NESTED:支持當前事務,新增Savepoint點,與當前事務同步提交或回滾。

494.什么是ORM

對象關系映射(Object Relation Mapping,簡稱ORM)模式是一種為了解決面向對象與關系數據庫存在的互不匹配的現象的技術,簡單的說,ORM是通過使用描述對象和數據庫之間映射的元數據,將程序中的對象自動持久化到關系數據庫中,那么到底如何實現持久化呢?一種簡單的方案時采用硬編碼方式(jdbc操作sql方式),為每一種可能的數據庫訪問操作提供單獨的方法。

這種方案存在以下不足:

1. 持久化層缺乏彈性,一旦出現業務需求變更,就必須修改持久化層的接口

2. 持久化層同時與域模型與關系數據庫模型綁定,不管域模型還是關系數據庫模型發生變化,都要修改持久化層的相關程序代碼,增加軟件的維護難度。

ORM提供了實現持久化層的另一種模式,它采用映射元數據來描述對象關系的映射,使得ORM中間件能在任何一個應用的業務邏輯層和數據庫層之間充當橋梁,Java典型的ORM框架有:Hibernate,ibatis(mybtis),speedframework。

ORM框架的方法論基于三個核心原則:

簡單:以最基本的形式建模數據

傳達性:數據庫結構被任何人都能理解的語言文檔化

精確性:基于數據模型創建正確標準化了結構

對象關系映射(Object Relation Mapping,簡稱ORM)模式是一種為了解決面向對象與關系數據庫存在的互不匹配的現象的技術,可以簡單的方案采用硬編碼方式(jdbc操作sql方式),為每一種可能的數據庫訪問操作提供單獨的方法,這種方法存在很多缺陷,使用ORM框架(為了解決面向對象與關系數據庫存在互不匹配的現象的框架)來解決。

495.Hibernate對象的狀態

臨時狀態/瞬時狀態(transient):剛剛用new語句創建,沒有被持久化,無id

不處于session中(沒有使用session的方法去操作臨時對象),該對象成為臨時對象

持久化狀態,托管狀態(persistent):已經被持久化,加入session的緩存中,session是沒有關閉

該狀態的對象為持久化對象。

游離狀態,脫管狀態(detached):已經被持久化,但不處于session中,該狀態的對象為游離對象。

刪除狀態(removed):對象有關聯的id,并且在session管理下,但是已經被計劃(事務提交的時候,commit)刪除,如果沒有事務就不能刪除

相互轉換

496.介紹一下Hibernate的緩存

答:一、why(為什么要用Hibernate緩存?)

Hibernate是一種持久化層框架,經常訪問物理數據庫。

為了降低應用程序對物理數據源訪問的頻次,從而提高應用程序的運行性能

緩存內的數據是對物理數據源中的數據的復制,應用程序在運行時從緩存讀寫數據,在特定的時刻或事件會同步緩存和物理數據源的數據。

為了提高訪問速度,把磁盤或者數據庫訪問變成內存訪問

二、what(Hibernate緩存原理是怎樣的?)Hibernate緩存包括兩大類:Hibernate 一級緩存和Hibernate二級緩存

1. Hibernate一級緩存又稱為”session的緩存”。

session緩存內置不能被卸載,session的緩存是事務范圍的緩存(session對象的生命周期通常對應一個數據庫事務或者一個應用事務)。

一級緩存中,持久化類的每個實例都具有唯一的OID

2. Hibernate的二級緩存又稱為”sessionFactory的緩存”。

由于sessionFactory對象的生命周期和應用程序的整個過程對應,因此Hibernate二級緩存是進程范圍或者集群范圍的緩存,有可能出現并發問題,因此需要采用適當的并發訪問策略,該策略為被緩存的數據提供了事務隔離級別。

第二級緩存是可選的,是一個可配置的插件,默認下sessionFactory不會啟用這個插件。

什么樣的數據適合存放到二級緩存中?

1) 很少被修改的數據 (帖子的最后回復時間)

2) 經常被查詢的數據 (電商的地點)

3) 不是很重要的數據,允許出現偶爾并發的數據

4) 不會被并發訪問的數據

5) 常量數據

擴展:Hibernate的二級緩存默認是不支持分布式緩存的,使用memcache,redis等中央緩存來代替二級緩存。

497.簡單講一下webservice使用的場景

webservice是一個SOA(面向服務的編程)的架構,它是不依賴于語言,不依賴于平臺,可以實現不同的語言間的相互調用,通過Internet進行基于http協議的網絡應用間的交互。

1、異構系統(不同的開發語言)的整合

2、不同客戶端的整合 (瀏覽器、手機端(android\ios)、微信)

3、實實在在的例子:

天氣預報:可以通過實現webservice客戶端調用遠程天氣服務實現的

4、單點登錄:一個服務實現所有系統的登錄

498.簡單介紹一下activity?

Activity是一個業務流程管理(BPM)和工作流系統,適用于開發人員和系統管理員,其核心是超快速,穩定的BPMN2的流程引擎,它易于與Spring集成使用。

主要用在OA中,把線下流程放在線上,把現實生活中一些流程固話定義到系統中,然后通過輸入表單數據完成業務。

他可以用在OA系統的流程管理中

請假流程(小于三天,一級主管審批,大于三天二級主管審批)

報銷流程(價格區間)

499.什么是MyBatis?

答:MyBatis是一個可以自定義SQL、存儲過程和高級映射的持久層框架。

500.Mybatis是如何進行分頁的?分頁插件的原理是什么?

答:1)Mybatis使用RowBounds對象進行分頁,也可以直接編寫sql實現分頁,也可以使用Mybatis的分頁插件。

2)分頁插件的原理:實現Mybatis提供的接口,實現自定義插件,在插件的攔截方法內攔截待執行的sql,然后重寫sql。

舉例:select * from student,攔截sql后重寫為:select t.* from (select * from student)t limit 0,10

501.MyBatis與Hibernate有哪些不同?

答:1)Mybatis和hibernate不同,它不完全是一個ORM框架,因為MyBatis需要程序員自己編寫Sql語句,不過mybatis可以通過XML或注解方式靈活配置要運行的sql語句,并將java對象和sql語句映射生成最終執行的sql,最后將sql執行的結果再映射生成java對象。

2)Mybatis學習門檻低,簡單易學,程序員直接編寫原生態sql,可嚴格控制sql執行性能,靈活度高,非常適合對關系數據模型要求不高的軟件開發,例如互聯網軟件、企業運營類軟件等,因為這類軟件需求變化頻繁,一但需求變化要求成果輸出迅速。但是靈活的前提是mybatis無法做到數據庫無關性,如果需要實現支持多種數據庫的軟件則需要自定義多套sql映射文件,工作量大。

3)Hibernate對象/關系映射能力強,數據庫無關性好,對于關系模型要求高的軟件(例如需求固定的定制化軟件)如果用hibernate開發可以節省很多代碼,提高效率。但是Hibernate的缺點是學習門檻高,要精通門檻更高,而且怎么設計O/R映射,在性能和對象模型之間如何權衡,以及怎樣用好Hibernate需要具有很強的經驗和能力才行。

總之,按照用戶的需求在有限的資源環境下只要能做出維護性、擴展性良好的軟件架構都是好架構,所以框架只有適合才是最好。

502.簡述Mybatis的Xml映射文件和Mybatis內部數據結構之間的映射關系?

答: Mybatis將所有Xml配置信息都封裝到All-In-One重量級對象Configuration內部。在Xml映射文件中,< parameterMap>標簽會被解析為ParameterMap對象,其每個子元素會被解析為ParameterMapping對象。< resultMap>標簽會被解析為ResultMap對象,其每個子元素會被解析為ResultMapping對象。每一個< select>、< insert>、< update>、< delete>標簽均會被解析為MappedStatement對象,標簽內的sql會被解析為BoundSql對象。

503.什么是MyBatis的接口綁定,有什么好處?

答:接口映射就是在MyBatis中任意定義接口,然后把接口里面的方法和SQL語句綁定,我們直接調用接口方法就可以,這樣比起原來了SqlSession提供的方法我們可以有更加靈活的選擇和設置.

504.Mybatis能執行一對一、一對多的關聯查詢嗎?都有哪些實現方式,以及它們之間的區別?

答:能,Mybatis不僅可以執行一對一、一對多的關聯查詢,還可以執行多對一,多對多的關聯查詢,多對一查詢,其實就是一對一查詢,只需要把selectOne()修改為selectList()即可;多對多查詢,其實就是一對多查詢,只需要把selectOne()修改為selectList()即可。

關聯對象查詢,有兩種實現方式,一種是單獨發送一個sql去查詢關聯對象,賦給主對象,然后返回主對象。另一種是使用嵌套查詢,嵌套查詢的含義為使用join查詢,一部分列是A對象的屬性值,另外一部分列是關聯對象B的屬性值,好處是只發一個sql查詢,就可以把主對象和其關聯對象查出來。

505.MyBatis里面的動態Sql是怎么設定的?用什么語法?

答:MyBatis里面的動態Sql一般是通過if節點來實現,通過OGNL語法來實現,但是如果要寫的完整,必須配合where,trim節點,where節點是判斷包含節點有內容就插入where,否則不插入,trim節點是用來判斷如果動態語句是以and 或or開始,那么會自動把這個and或者or取掉。

506.使用MyBatis的mapper接口調用時有哪些要求?

答:1)Mapper接口方法名和mapper.xml中定義的每個sql的id相同

2)Mapper接口方法的輸入參數類型和mapper.xml中定義的每個sql 的parameterType的類型相同

3)Mapper接口方法的輸出參數類型和mapper.xml中定義的每個sql的resultType的類型相同

4)Mapper.xml文件中的namespace即是mapper接口的類路徑。

507.Mybatis是如何將sql執行結果封裝為目標對象并返回的?都有哪些映射形式?

答:第一種是使用< resultMap>標簽,逐一定義列名和對象屬性名之間的映射關系。

第二種是使用sql列的別名功能,將列別名書寫為對象屬性名,比如T_NAME AS NAME,對象屬性名一般是name,小寫,但是列名不區分大小寫,Mybatis會忽略列名大小寫,智能找到與之對應對象屬性名,你甚至可以寫成T_NAME AS NaMe,Mybatis一樣可以正常工作。

有了列名與屬性名的映射關系后,Mybatis通過反射創建對象,同時使用反射給對象的屬性逐一賦值并返回,那些找不到映射關系的屬性,是無法完成賦值的。

508.MyBatis接口綁定有幾種實現方式,分別是怎么實現的?

答:接口綁定有兩種實現方式,一種是通過注解綁定,就是在接口的方法上面加上@Select@Update等注解里面包含Sql語句來綁定,另外一種就是通過xml里面寫SQL來綁定,在這種情況下,要指定xml映射文件里面的namespace必須為接口的全路徑名.

509.MyBatis實現一對一有幾種方式?具體怎么操作的?

答:有聯合查詢和嵌套查詢,聯合查詢是幾個表聯合查詢,只查詢一次,通過在resultMap里面配置association節點配置一對一的類就可以完成;嵌套查詢是先查一個表,根據這個表里面的結果的外鍵id,去再另外一個表里面查詢數據,也是通過association配置,但另外一個表的查詢通過select屬性配置。

510.什么情況下用注解綁定,什么情況下用xml綁定?

答:當Sql語句比較簡單時候,用注解綁定;當SQL語句比較復雜時候,用xml綁定,一般用xml綁定的比較多

511.MyBatis的好處是什么?

答:1) MyBatis把sql語句從Java源程序中獨立出來, 放在單獨的XML文件中編寫,給程序的維護帶來了很大便利。

2) MyBatis封裝了底層JDBC API的調用細節,并能自動將結果集轉換成Java Bean對象,大大簡化了Java數據庫編程的重復工作。

3) 因為MyBatis需要程序員自己去編寫sql語句,程序員可以結合數據庫自身的特點靈活控制sql語句, 因此能夠實現比Hibernate等全自動orm框架更高的查詢效率,能夠完成復雜查詢。

微服務框架

512.Spring Boot有哪些優點?

答:Spring Boot的優點有:

減少開發,測試時間和努力。

使用JavaConfig有助于避免使用XML。

避免大量的Maven導入和各種版本沖突。

提供意見發展方法。

通過提供默認值快速開始開發。

沒有單獨的Web服務器需要。這意味著你不再需要啟動Tomcat,Glassfish或其他任何東西。

需要更少的配置 因為沒有web.xml文件。只需添加用@ Configuration注釋的類,然后添加用@Bean注釋的方法,Spring將自動加載對象并像以前一樣對其進行管理。您甚至可以將@Autowired添加到bean方法中,以使Spring自動裝入需要的依賴關系中。

基于環境的配置 使用這些屬性,您可以將您正在使用的環境傳遞到應用程序:-Dspring.profiles.active = {enviornment}。在加載主應用程序屬性文件后,Spring將在(application{environment} .properties)中加載后續的應用程序屬性文件。

513.如何重新加載Spring Boot上的更改,而無需重新啟動服務器?

答:這可以使用DEV工具來實現。通過這種依賴關系,您可以節省任何更改,嵌入式tomcat將重新啟動。Spring Boot有一個開發工具(DevTools)模塊,它有助于提高開發人員的生產力。Java開發人員面臨的一個主要挑戰是將文件更改自動部署到服務器并自動重啟服務器。開發人員可以重新加載Spring Boot上的更改,而無需重新啟動服務器。這將消除每次手動部署更改的需要。Spring Boot在發布它的第一個版本時沒有這個功能。這是開發人員最需要的功能。DevTools模塊完全滿足開發人員的需求。該模塊將在生產環境中被禁用。它還提供H2數據庫控制臺以更好地測試應用程序。

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
514.常見的系統架構風格有哪些?各有什么優缺點?

1、單體架構

單體架構也稱之為單體系統或者是單體應用。就是一種把系統中所有的功能、模塊耦合在一個應用中的架構方式。

單體架構特點:打包成一個獨立的單元(導成一個唯一的jar包或者是war包),會一個進程的方式來運行。

單體架構的優點、缺點

優點:

項目易于管理

部署簡單

缺點:

測試成本高

可伸縮性差

可靠性差

迭代困難

跨語言程度差

團隊協作難

2、MVC架構

MVC架構特點:

MVC是模型(Model)、視圖(View)、控制器(Controller)3個單詞的縮寫。 下面我們從這3個方面來講解MVC中的三個要素。

Model是指數據模型,是對客觀事物的抽象。 如一篇博客文章,我們可能會以一個Post類來表示,那么,這個Post類就是數據對象。 同時,博客文章還有一些業務邏輯,如發布、回收、評論等,這一般表現為類的方法,這也是model的內容和范疇。 對于Model,主要是數據、業務邏輯和業務規則。相對而言,這是MVC中比較穩定的部分,一般成品后不會改變。 開發初期的最重要任務,主要也是實現Model的部分。這一部分寫得好,后面就可以改得少,開發起來就快。

View是指視圖,也就是呈現給用戶的一個界面,是model的具體表現形式,也是收集用戶輸入的地方。 如你在某個博客上看到的某一篇文章,就是某個Post類的表現形式。 View的目的在于提供與用戶交互的界面。換句話說,對于用戶而言,只有View是可見的、可操作的。 事實上也是如此,你不會讓用戶看到Model,更不會讓他直接操作Model。 你只會讓用戶看到你想讓他看的內容。 這就是View要做的事,他往往是MVC中變化頻繁的部分,也是客戶經常要求改來改去的地方。 今天你可能會以一種形式來展示你的博文,明天可能就變成別的表現形式了。

Contorller指的是控制器,主要負責與model和view打交道。 換句話說,model和view之間一般不直接打交道,他們老死不相往來。view中不會對model作任何操作, model不會輸出任何用于表現的東西,如HTML代碼等。這倆甩手不干了,那總得有人來干吧,只能Controller上了。 Contorller用于決定使用哪些Model,對Model執行什么操作,為視圖準備哪些數據,是MVC中溝通的橋梁。

MVC架構優缺點

優點:

各施其職,互不干涉。

在MVC模式中,三個層各施其職,所以如果一旦哪一層的需求發生了變化,就只需要更改相應的層中的代碼而不會影響到其它層中的代碼。

有利于開發中的分工。

在MVC模式中,由于按層把系統分開,那么就能更好的實現開發中的分工。網頁設計人員可以進行開發視圖層中的JSP,對業務熟悉的開發人員可開發業務層,而其它開發人員可開發控制層。

有利于組件的重用。

分層后更有利于組件的重用。如控制層可獨立成一個能用的組件,視圖層也可做成通用的操作界面。

缺點:

增加了系統結構和實現的復雜性。

視圖與控制器間的過于緊密的連接。

視圖對模型數據的低效率訪問。

3、面向服務架構(SOA)

面向服務的架構(SOA)是一個組件模型,它將應用程序拆分成不同功能單元(稱為服務)通過這些服務之間定義良好的接口和契約聯系起來。接口是采用中立的方式進行定義的,它應該獨立于實現服務的硬件平臺、操作系統和編程語言。這使得構建在各種各樣的系統中的服務可以以一種統一和通用的方式進行交互。

面向服務架構特點:

系統是由多個服務構成

每個服務可以單獨獨立部署

每個服務之間是松耦合的。服務內部是高內聚的,外部是低耦合的。高內聚就是每個服務只關注完成一個功能。

服務的優點、缺點

優點:

測試容易

可伸縮性強

可靠性強

跨語言程度會更加靈活

團隊協作容易

系統迭代容易

缺點:

運維成本過高,部署數量較多

接口兼容多版本

分布式系統的復雜性

分布式事務

515.什么是AKF拆分原則?

業界對于可擴展的系統架構設計有一個樸素的理念,就是:通過加機器就可以解決容量和可用性問題。(如果一臺不行那就兩臺)。

我是個段子:(世界上沒有什么事是一頓燒烤不能解決的。如果有,那就兩頓。)

這一理念在“云計算”概念瘋狂流行的今天,得到了廣泛的認可!對于一個規模迅速增長的系統而言,容量和性能問題當然是首當其沖的。但是隨著時間的向前,系統規模的增長,除了面對性能與容量的問題外,還需要面對功能與模塊數量上的增長帶來的系統復雜性問題以及業務的變化帶來的提供差異化服務問題。而許多系統,在架構設計時并未充分考慮到這些問題,導致系統的重構成為常態,從而影響業務交付能力,還浪費人力財力!對此,《可擴展的藝術》一書提出了一個更加系統的可擴展模型——?AKF可擴展立方?(Scalability Cube) 。這個立方體中沿著三個坐標軸設置分別為:X、Y、Z。

Y軸擴展會將龐大的整體應用拆分為多個服務。每個服務實現一組相關的功能,如訂單管理、客戶管理等。在工程上常見的方案是?服務化架構(SOA)?。比如對于一個電子商務平臺,我們可以拆分成不同的服務

X軸擴展與我們前面樸素理念是一致的,通過絕對平等地復制服務與數據,以解決容量和可用性的問題。其實就是將微服務運行多個實例,做集群加負載均衡的模式。

Z軸擴展通常是指基于請求者或用戶獨特的需求,進行系統劃分,并使得劃分出來的子系統是相互隔離但又是完整的。以生產汽車的工廠來舉例:福特公司為了發展在中國的業務,或者利用中國的廉價勞動力,在中國建立一個完整的子工廠,與美國工廠一樣,負責完整的汽車生產。這就是一種Z軸擴展。

516.什么是Spring Cloud?

Spring Cloud是一個微服務框架,相比Dubbo等RPC框架,?Spring Cloud提供的全套的分布式系統解決方案。

Spring Cloud對微服務基礎框架Netflix的多個開源組件進行了封裝,同時又實現了和云端平臺以及和Spring Boot開發框架的集成。

Spring Cloud為微服務架構開發涉及的配置管理,服務治理,熔斷機制,智能路由,微代理,控制總線,一次性token,全局一致性鎖,leader選舉,分布式session,集群狀態管理等操作提供了一種簡單的開發方式。

Spring Cloud 為開發者提供了快速構建分布式系統的工具,開發者可以快速的啟動服務或構建應用、同時能夠快速和云平臺資源進行對接

517.Spring Cloud與Dubbo的區別是什么?
518.什么是Eureka注冊中心?

Eureka是Netflix開發的服務發現組件,本身是一個基于REST的服務。Spring Cloud將它集成在其子項目spring-cloud-netflix中,以實現Spring Cloud的服務注冊于發現,同時還提供了負載均衡、故障轉移等能力。

519.簡單談一下Eureka中的三種角色分別是什么?

1、Eureka Server

通過Register、Get、Renew等接口提供服務的注冊和發現。

2、Application Service (Service Provider)

服務提供方

把自身的服務實例注冊到Eureka Server中

3、Application Client (Service Consumer)

服務調用方

通過Eureka Server 獲取服務列表,消費服務。

520.什么是Ribbon

1.Ribbon 是一個基于Http和TCP的客服端負載均衡工具,它是基于Netflix Ribbon實現的。

2.它不像spring cloud服務注冊中心、配置中心、API網關那樣獨立部署,但是它幾乎存在于每個spring cloud 微服務中。包括feign提供的聲明式服務調用也是基于該Ribbon實現的。

3.ribbon默認提供很多種負載均衡算法,例如 輪詢、隨機 等等。甚至包含自定義的負載均衡算法。

521.集中式與進程內負載均衡的區別

目前業界主流的負載均衡方案可分成兩類:

第一類:集中式負載均衡, 即在consumer和provider之間使用獨立的負載均衡設施(可以是硬件,如F5, 也可以是軟件,如nginx), 由該設施負責把 訪問請求 通過某種策略轉發至provider;

第二類:進程內負載均衡,將負載均衡邏輯集成到consumer,consumer從服務注冊中心獲知有哪些地址可用,然后自己再從這些地址中選擇出一個合適的provider。

Ribbon就屬于后者,它只是一個類庫,集成于consumer進程,consumer通過它來獲取到provider的地址。

522.Ribbon的常見負載均衡策略有哪些?
id 策略名稱 策略對應的類名 實現原理
1 輪詢策略(默認) RoundRobinRule 輪詢策略表示每次都順序取下一個provider,比如一共有5個provider,第1次取第1個,第2次取第2個,第3次取第3個,以此類推
2 權重輪詢策略 WeightedResponseTimeRule 1.根據每個provider的響應時間分配一個權重,響應時間越長,權重越小,被選中的可能性越低。 2.原理:一開始為輪詢策略,并開啟一個計時器,每30秒收集一次每個provider的平均響應時間,當信息足夠時,給每個provider附上一個權重,并按權重隨機選擇provider,高權越重的provider會被高概率選中。
3 隨機策略 RandomRule 從provider列表中隨機選擇一個provider
4 最少并發數策略 BestAvailableRule 選擇正在請求中的并發數最小的provider,除非這個provider在熔斷中。
5 在“選定的負載均衡策略”基礎上進行重試機制 RetryRule 1.“選定的負載均衡策略”這個策略是輪詢策略RoundRobinRule 2.該重試策略先設定一個閾值時間段,如果在這個閾值時間段內當選擇provider不成功,則一直嘗試采用“選定的負載均衡策略:輪詢策略”最后選擇一個可用的provider
6 可用性敏感策略 AvailabilityFilteringRule 過濾性能差的provider,有2種: 第一種:過濾掉在eureka中處于一直連接失敗provider 第二種:過濾掉高并發的provider
7 區域敏感性策略 ZoneAvoidanceRule 1.以一個區域為單位考察可用性,對于不可用的區域整個丟棄,從剩下區域中選可用的provider 2.如果這個ip區域內有一個或多個實例不可達或響應變慢,都會降低該ip區域內其他ip被選中的權重。
523.簡單說說什么是Feign?

Feign是一種聲明式、模板化的HTTP客戶端技術(僅在consumer中使用)。

524.什么是聲明式,有什么作用,解決什么問題?

聲明式調用就像調用本地方法一樣調用遠程方法;無感知遠程http請求。

1、Spring Cloud的聲明式調用, 可以做到使用 HTTP請求遠程服務時能就像調用本地方法一樣的體驗,開發者完全感知不到這是遠程方法,更感知不到這是個HTTP請求。

2、它像Dubbo一樣,consumer直接調用接口方法調用provider,而不需要通過常規的Http Client構造請求再解析返回數據。

3、它解決了讓開發者調用遠程接口就跟調用本地方法一樣,無需關注與遠程的交互細節,更無需關注分布式環境開發。

525.什么是服務的災難性的雪崩效應?

在微服務架構中,一個請求需要調用多個服務是非常常見的。如客戶端訪問A服務,而A服務需要調用B服務,B服務需要調用C服務,由于網絡原因或者自身的原因,如果B服務或者C服務不能及時響應,A服務將處于阻塞狀態,直到B服務C服務響應。此時若有大量的請求涌入,容器的線程資源會被消耗完畢,導致服務癱瘓。服務與服務之間的依賴性,故障會傳播,造成連鎖反應,會對整個微服務系統造成災難性的嚴重后果,這就是服務故障的“雪崩”效應

526.如何解決災難性雪崩效應?

降級

超時降級、資源不足時(線程或信號量)降級,降級后可以配合降級接口返回托底數據。實現一個fallback方法, 當請求后端服務出現異常的時候, 可以使用fallback方法返回的值.

隔離(線程池隔離和信號量隔離)

限制調用分布式服務的資源使用,某一個調用的服務出現問題不會影響其他服務調用。

熔斷

當失敗率(如因網絡故障/超時造成的失敗率高)達到閥值自動觸發降級,熔斷器觸發的快速失敗會進行快速恢復。

緩存

提供了請求緩存。

請求合并

提供請求合并。

527.線程池隔離和信號量隔離的區別
528.請回答微服務架構的六種常用設計模式是什么?

答:如下這六種
代理設計模式
聚合設計模式
鏈條設計模式
聚合鏈條設計模式
數據共享設計模式
異步消息設計模式

529.什么是網關服務?

答:網關服務,通常是外部訪問服務的唯一接口,訪問內部的所有服務都必須先經過網關服務。網關服務的主要功能是消息解析過濾,路由,轉發等。

530.網關服務中,路由器的4種路由規則方法是什么?

答:采用URL指定路由方式

采用服務名稱指定路由方式

路由的排除方法

路由的添加前綴方法

531.為什么要使用spring cloud config 配置中心?它解決了什么問題?
532.什么是Spring Cloud Bus
533.消息驅動Stream解決了什么問題?
534.為什么要使用微服務跟蹤?它解決了什么問題?
535.什么是ELK(ElasticSearch, Logstash, Kibana)

ELK是三個工具的集合,Elasticsearch + Logstash + Kibana,這三個工具組合形成了一套實用、易用的監控架構,很多公司利用它來搭建可視化的海量日志分析平臺。

1. ElasticSearch

ElasticSearch是一個基于Lucene的搜索服務器。它提供了一個分布式多用戶能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java開發的,并作為Apache許可條款下的開放源碼發布,是當前流行的企業級搜索引擎。設計用于云計算中,能夠達到實時搜索,穩定,可靠,快速,安裝使用方便。

2. Logstash

Logstash是一個用于管理日志和事件的工具,你可以用它去收集日志、轉換日志、解析日志并將他們作為數據提供給其它模塊調用,例如搜索、存儲等。

3. Kibana

Kibana是一個優秀的前端日志展示框架,它可以非常詳細的將日志轉化為各種圖表,為用戶提供強大的數據可視化支持。

536.為什么要用ELK,它解決了什么問題?
537.什么是分布式跟蹤?:?Zipki?

數據庫

538.下列屬于關系型數據庫的是()(選擇兩項)
A. Oracle
B. MySql
C. IMS
D. MongoDB
答案:AB分析: IMS 是IP Mulitimedia Subsystem的縮寫,是IP多媒體系統 MongoDB分布式文檔存儲數據庫
539.請列出Java常見的開源數據連接池,并對參數做出簡單的說明

答:在Java中開源的常用的數據庫連接池有以下幾種 :

(1)DBCP

DBCP是一個依賴Jakarta commons-pool對象池機制的數據庫連接池.DBCP可以直接的在應用程序中使用,Tomcat的數據源使用的就是DBCP。

(2)c3p0

c3p0是一個開放源代碼的JDBC連接池,它在lib目錄中與Hibernate一起發布,包括了實現jdbc3和jdbc2擴展規范說明的Connection 和Statement 池的DataSources 對象。

(3)Druid

阿里出品,淘寶和支付寶專用數據庫連接池,但它不僅僅是一個數據庫連接池,它還包含一個ProxyDriver,一系列內置的JDBC組件庫,一個SQL Parser。支持所有JDBC兼容的數據庫,包括Oracle、MySql、Derby、Postgresql、SQL Server、H2等等。

540.儲蓄所有多個儲戶,儲戶在多個儲戶所存取款,儲蓄所與儲戶之間是()
A. 一對一的聯系
B. 多對一的聯系
C. 一對多的聯系
D. 多對多的聯系
答案:D
541.視圖是一個“虛表”,視圖的構造基于()
A. 基本表或視圖
B. 視圖
C. 數據字典
D. 基本表
答案:A
542.設有關系R(A,B,C,D)及其上的函數相關性集合F={B→A,BC→D},那么關系R最高是()
A. 第一范式的
B. 第二范式的
C. 第三范式的
D. BCNF范式的
答案:A
分析: 根據數據庫三大范式的依賴性要求,從B,BC函數確定A和D這一點上,明顯看出B,BC都有可能是主碼. 若B是主碼的話,仔細看會發現,F中竟然沒有誰去函數確定C,這顯然是說不通的,(因為C至少會被B這個主碼函數確定); 若BC是主碼,那么F中存在非主屬性對候選碼的部分依賴,不滿足第二范式的要求,故為第一范式.
543.什么是DAO模式?

答:DAO(DataAccess Object)顧名思義是一個為數據庫或其他持久化機制提供了抽象接口的對象,在不暴露數據庫實現細節的前提下提供了各種數據操作。為了建立一個健壯的Java EE應用,應該將所有對數據源的訪問操作進行抽象化后封裝在一個公共API中。用程序設計語言來說,就是建立一個接口,接口中定義了此應用程序中將會用到的所有事務方法。在這個應用程序中,當需要和數據源進行交互的時候則使用這個接口,并且編寫一個單獨的類來實現這個接口,在邏輯上該類對應一個特定的數據存儲。DAO模式實際上包含了兩個模式,一是Data Accessor(數據訪問器),二是Data Object(數據對象),前者要解決如何訪問數據的問題,而后者要解決的是如何用對象封裝數據。

544.數據庫MySQL,Oracle,SqlServer分頁時用的語句

Mysql:使用limit關鍵字

Select * from 表名 where 條件 limit 開始位置,結束位置。通過動態的改變開始和結束位置的值來實現分頁。

Oracle:通過rownum來實現

select * from ( select rownum rn,t.* from addressbook where rownum<= 20 ) where rownum > 10

Sqlserver:

select top 20 * from addressbook where id not in (select top 10 id from addressbook)

545.Oracle完成分頁功能的三層子查詢語句及其含義?

如:select * from (select t.*,rownum r from (select * from A) t where rownum < 10) where r >5

select * from A:要查詢的數據

select t.*,rownum r from (select * from A) t where rownum < 10:取前10行

select * from (select t.*,rownum r from (select * from A) t where rownum < 10) where r >5:取5-10行

546.問SQL怎么優化執行效率更高

答: 1. SQL優化的原則是:將一次操作需要讀取的BLOCK數減到最低,即在最短的時間達到最大的數據吞吐量。

調整不良SQL通??梢詮囊韵聨c切入:

1) 檢查不良的SQL,考慮其寫法是否還有可優化內容

2) 檢查子查詢 考慮SQL子查詢是否可以用簡單連接的方式進行重新書寫

3) 檢查優化索引的使用

4) 考慮數據庫的優化器

2. 避免出現SELECT * FROM table 語句,要明確查出的字段。

3. 在一個SQL語句中,如果一個where條件過濾的數據庫記錄越多,定位越準確,則該where條件越應該前移。

4. 查詢時盡可能使用索引覆蓋。即對SELECT的字段建立復合索引,這樣查詢時只進行索引掃描,不讀取數據塊。

5. 在判斷有無符合條件的記錄時建議不要用SELECT COUNT (*)和select top 1 語句。

6. 使用內層限定原則,在拼寫SQL語句時,將查詢條件分解、分類,并盡量在SQL語句的最里層進行限定,以減少數據的處理量。

7. 應絕對避免在order by子句中使用表達式。

9. 小心使用 IN 和 OR,需要注意In集合中的數據量。建議集合中的數據不超過200個。

10. <> 用 < 、 > 代替,>用>=代替, < 用< =代替,這樣可以有效的利用索引。

11. 在查詢時盡量減少對多余數據的讀取包括多余的列與多余的行。

12. 對于復合索引要注意,例如在建立復合索引時列的順序是F1,F2,F3,則在where或order by子句中這些字段出現的順序要與建立索引時的字段順序一致,且必須包含第一列。只能是F1或F1,F2或F1,F2,F3。否則不會用到該索引。

547.談談數據庫去空格的情況

一、表中字符串帶空格的原因

1、空格就是空格。

2、控制符 顯示為 空格。

二、解決方法

第一種情況,去空格的處理的比較簡單,Replace(column,' ','') 就可以解決。
第二種情況,解決方法就比較麻煩點:需要先查出相應的ASCII碼,再用Replace(column,char(ascii碼),'')解決,以下舉個栗子:
CREATE TABLE #temp
(NAME NVARCHAR(50))
INSERT INTO #temp SELECT '明天就是國慶了'+CHAR(10) --換行符
SELECT * FROM #temp --末尾顯示為空格
SELECT REPLACE(NAME,' ','') FROM #temp --去不掉這個空格
SELECT REPLACE(NAME,CHAR(10),'') FROM #temp --去掉空格
SELECT REPLACE(NAME,CHAR(ASCII(RIGHT(NAME,1))),'') FROM #temp --在不知道是最后一位是什么字符導致空格的情況下,先轉ASCII碼,在替換
DROP TABLE #temp
----下面是查詢結果:
--'明天就是國慶了 '
--'明天就是國慶了 '
--'明天就是國慶了'
--'明天就是國慶了'

548.根據你以往的經驗簡單敘述一下MYSQL的優化

答:
1.數據庫的設計
盡量把數據庫設計的更小的占磁盤空間.
1).盡可能使用更小的整數類型.(mediumint就比int更合適).
2).盡可能的定義字段為not null,除非這個字段需要null.
3).如果沒有用到變長字段的話比如varchar,那就采用固定大小的紀錄格式比如char.
4).表的主索引應該盡可能的短.這樣的話每條紀錄都有名字標志且更高效.
5).只創建確實需要的索引。索引有利于檢索記錄,但是不利于快速保存記錄。如果總是要在表的組合字段上做搜索,那么就在這些字段上創建索引。索引的第一部分必須是最常使用的字段.如果總是需要用到很多字段,首先就應該多復制這些字段,使索引更好的壓縮。
6).所有數據都得在保存到數據庫前進行處理。
7).所有字段都得有默認值。
8).在某些情況下,把一個頻繁掃描的表分成兩個速度會快好多。在對動態格式表掃描以取得相關記錄時,它可能使用更小的靜態格式表的情況下更是如此。
2.系統的用途
1).盡量使用長連接.
2).explain 復雜的SQL語句。
3).如果兩個關聯表要做比較話,做比較的字段必須類型和長度都一致.
4).LIMIT語句盡量要跟order by或者 distinct.這樣可以避免做一次full table scan.
5).如果想要清空表的所有記錄,建議用truncate table tablename而不是delete from tablename.
6).能使用STORE PROCEDURE 或者 USER FUNCTION的時候.
7).在一條insert語句中采用多重紀錄插入格式.而且使用load data infile來導入大量數據,這比單純的indert快好多.
8).經常OPTIMIZE TABLE 來整理碎片.
9).還有就是date 類型的數據如果頻繁要做比較的話盡量保存在unsigned int 類型比較快。
3.系統的瓶頸
1).磁盤搜索.
并行搜索,把數據分開存放到多個磁盤中,這樣能加快搜索時間.
2).磁盤讀寫(IO)
可以從多個媒介中并行的讀取數據。
3).CPU周期
數據存放在主內存中.這樣就得增加CPU的個數來處理這些數據。
4).內存帶寬
當CPU要將更多的數據存放到CPU的緩存中來的話,內存的帶寬就成了瓶頸.

549.以Oracle11R為例簡述數據庫集群部署

命令行工具
–crsctl管理集群相關的操作:
-啟動和關閉Oracle集群
-啟用和禁用Oracle集群后臺進程
-注冊集群資源
-srvctl 管理Oracle 資源相關操作
-啟動和關閉數據庫實例和服務
在Oracle Grid安裝的home路徑下的命令行工具crsctl和srvctl用來管理Oracle集群。使用crsctl可以監控和管理任何集群節點的集群組件和資源。srvctl工具提供了類似的功能,來監控和管理Oracle相關的資源,例如數據庫實例和數據庫服務。crsctl命令只能是集群管理者來運行,srvctl命令可以是其他用戶,例如數據庫管理員來使用。

550.說一下數據庫的存儲過程?

一、存儲過程與函數的區別:

1.一般來說,存儲過程實現的功能要復雜一點,而函數的實現的功能針對性比較強。

2.對于存儲過程來說可以返回參數(output),而函數只能返回值或者表對象。

3.存儲過程一般是作為一個獨立的部分來執行,而函數可以作為查詢語句的一個部分來調用,由于函數可以返回一個表對象,因此它可以在查詢語句中位于FROM關鍵字的后面。

二、存儲過程的優點:

1.執行速度更快 – 在數據庫中保存的存儲過程語句都是編譯過的

2.允許模塊化程序設計 – 類似方法的復用

3.提高系統安全性 – 防止SQL注入

4.減少網絡流通量 – 只要傳輸存儲過程的名稱

系統存儲過程一般以sp開頭,用戶自定義的存儲過程一般以usp開頭

551.數據庫創建索引的缺點?

缺點:

第一,創建索引和維護索引要耗費時間,這種時間隨著數據量的增加而增加。

第二,索引需要占物理空間,除了數據表占數據空間之外,每一個索引還要占一定的物理空間,如果要建立聚簇索引,那么需要的空間就會更大。

第三,當對表中的數據進行增加、刪除和修改的時候,索引也要動態的維護,這樣就降低了數據的維護速度。

552.有兩張表;請用SQL查詢,所有的客戶訂單日期最新的前五條訂單記錄。(分別注明MySQL. Oracle寫法)

客戶信息表(c CUSTOM)有以下字段:

id、name、mobile

客戶訂單表(C_ORDER)有以下字段:

id、custom_id、commodity、count、order _date

Mysql:

Select * from c_order order by order_date desc limit 0,5;

Oracle:

Select o.*,rownum n

from c_order order by order_date desc where n<6;

553.關于HQL與SQL,以下哪些說法正確?()
A. HQL與SQL沒什么差別
B. HQL面向對象,而SQL操縱關系數據庫
C. 在 HQL 與 SQL 中,都包含 select,insert,update,delete 語句
D. HQL僅用于査詢數據,不支持insert,update和delete語句
答案:BC
554.下面是學生表(student)的結構說明
字段名稱 字段解釋 字段類型 字段長度 約束
s_id 學號 字符 10 PK
s_name 學生姓名 字符 50 Not null
s_age 學生年齡 數值 3 Not null
s-sex 學生性別 字符(男:1女:0) 1 Not null

下面是教師表(Teacher )的結構說明

字段名稱 字段解釋 字段類型 字段長度 約束
t_id 教師編號 字符 10 PK
t_name 教師名字 字符 50 Not null

下面是課程表(Course)的結構說明

字段名稱 字段解釋 字段類型 字段長度 約束
c_id 課程編號 字符 10 PK
c_name 課程名字 字符 50 Not null
t_id 教師編號 字符 10 Not null

下面是成績表(SC)的結構說明

字段名稱 字段解釋 字段類型 字段長度 約束
s_id 學號 字符 10 PK
c_id 課程編號 字符 10 Not null
score 成績 數值 3 Not null

1、查詢“001”課程比“002”課程成績高的所有學生的學號;

select a.s_id from (select s_id,score from SC where C_ID='001') a,(select s_id,score
from SC where C_ID='002') b
where a.score>b.score and a.s_id=b.s_id;

2、查詢平均成績大于60分的同學的學號和平均成績;

select S_ID,avg(score)
from sc
group by S_ID having avg(score) >60;

3、查詢所有同學的學號、姓名、選課數、總成績;

select Student.S_ID,Student.Sname,count(SC.C_ID),sum(score)
from Student left Outer join SC on Student.S_ID=SC.S_ID
group by Student.S_ID,Sname

4、查詢姓“李”的老師的個數;

select count(distinct(Tname))
from Teacher
where Tname like '李%';

5、查詢沒學過“葉平”老師課的同學的學號、姓名;

select Student.S_ID,Student.Sname
from Student
where S_ID not in (select distinct( SC.S_ID) from SC,Course,Teacher where SC.C_ID=Course.C_ID and Teacher.T#=Course.T# and Teacher.Tname='葉平');

6、查詢學過“001”并且也學過編號“002”課程的同學的學號、姓名;

elect Student.S_ID,Student.Sname from Student,SC where Student.S_ID=SC.S_ID and SC.C_ID='001'and exists( Select * from SC as SC_2 where SC_2.S_ID=SC.S_ID and SC_2.C_ID='002');

7、查詢學過“葉平”老師所教的所有課的同學的學號、姓名;

select S_ID,Sname
from Student
where S_ID in (select S_ID from SC ,Course ,Teacher where SC.C_ID=Course.C_ID and Teacher.T#=Course.T# and Teacher.Tname='葉平' group by S_ID having count(SC.C_ID)=(select count(C_ID) from Course,Teacher where Teacher.T#=Course.T# and Tname='葉平'));

8、查詢課程編號“002”的成績比課程編號“001”課程低的所有同學的學號、姓名;

Select S_ID,Sname from (select Student.S_ID,Student.Sname,score ,(select score from SC SC_2 where SC_2.S_ID=Student.S_ID and SC_2.C_ID='002') score2
from Student,SC where Student.S_ID=SC.S_ID and C_ID='001') S_2 where score2 < score;

9、查詢所有課程成績小于60分的同學的學號、姓名;

select S_ID,Sname
from Student
where S_ID not in (select S.S_ID from Student AS S,SC where S.S_ID=SC.S_ID and score>60);

10、查詢沒有學全所有課的同學的學號、姓名;

select Student.S_ID,Student.Sname
from Student,SC
where Student.S_ID=SC.S_ID group by Student.S_ID,Student.Sname having count(C_ID) <(select count(C_ID) from Course);

11、查詢至少有一門課與學號為“1001”的同學所學相同的同學的學號和姓名;

select distinct S_ID,Sname from Student,SC where?Student.S_ID=SC.S_ID and SC.C_ID in (select C_ID from SC where S_ID='1001');

12、查詢至少學過學號為“001”同學所有一門課的其他同學學號和姓名;

select distinct SC.S_ID,Sname
from Student,SC
where Student.S_ID=SC.S_ID and C_ID in (select C_ID from SC where S_ID='001');

555.為管理崗位業務培訓信息,有如下3個表:

S(S#,SN,SD,SA),其中S#,SN,SD,SA分別代表學號、學員姓名、所屬單位、學員年齡。 C (C#,CN ),其中C#,CN分別代表課程編號、課程名稱
SC(S#,C#,G),其中S#,C#,G分別代表學號、所選修的課程編號、學習成績
請使用2種標準SQL語句査洵選修課程名稱為“稅收基礎”的學員學號和姓名,并說明其優缺點 。

SQL92標準:

SELECT SN,SD FROM S
WHERE [S#] IN(
SELECT [S#] FROM C,SC
WHERE C.[C#]=SC.[C#]
AND CN=N'稅收基礎')

SQL99標準:

elect s.s#,s.sn from s
join sc on s.s#=sc.s#
join c on sc.c#=c.c#
where c.cn='稅收基礎'

優點:

SQL99將連接條件和過濾條件分開,顯得代碼清晰。
SQL92書寫簡單易于理解。

缺點:

SQL92連接條件和過濾條件都寫在一起,不利于查看。
SQL99書寫相對麻煩不易于理解。

556.用Java怎么實現有每天有1億條記錄的DB儲存?MySQL上億記錄數據量的數據庫如何設計?

1.這么大數據量首先建議 使用大數據的DB,可以用spring batch 來做類似這樣的處理。定量向DB存儲數據。如果需要定時,可以考慮 quartz。

Mysql數據庫設計:

1.讀寫分離;

2.縱向橫向拆分庫、表。

MySQL的基本功能中包括replication(復制)功能。所謂replication,就是確定master以及與之同步的slave服務器,再加上slave將master中寫入的內容polling過來更新自身內容的功能。這樣slave就是master的replica(復制品)。這樣就可以準備多臺內容相同的服務器。

通過master和salve的replication,準備好多臺服務器之后,讓應用程序服務器通過負載均衡器去處理查詢slave。這樣就能將查詢分散到多臺服務器上。

應用程序實現上應該只把select等讀取之類的查詢發送給負載均衡器,而更新應當直接發送給master。要是在slave上執行更新操作,slave和master的內容就無法同步。MySQL會檢測到master和slave之間內容差異,并停止replication,這回導致系統故障。Slave可以采用LVS(linux系統自帶的負載均衡器)實現查詢的負載均衡。

使用MySQL的replication是利用的冗余化,實現冗余化需要實現的最小服務器數量是4臺,三臺slave和一臺master,slave為什么是需要三臺呢,比如一臺slave死機了,現在需要修復再次上線,那么意味著你必須停止一臺slave來復制MySQL的數據,如果只有兩臺slave,一臺壞了,你就必須停止服務,如果有三臺,壞了一臺,你復制數據時停止一臺,還有一臺可以運維。

對于數據的處理是能放入到內存中就盡量放入到內存中如果不能放入到內存中,可以利用MySQL的Partitioning。

Partitioning就是表分割也就是講A表和B表放在不同的服務器上。簡單來說,Partitioning就是充分利用局部性進行分割,提高緩存利用效率,從而實現Partitioning的效果。其中最重要的一點就是以Partitioning為前提設計的系統將表分割開,用RDBMS的方式的話,對于一對多的關系經常使用JOIN查詢將兩張表連接起來。但是如果將表分割開了之后,也就是兩張表不在同一個數據庫,不在同一個服務器上怎樣使用JOIN操作,這里需要注意的是如果是用where in操作不是省了一些麻煩了嘛。

557.Mysql的引擎有哪些?支持事物么?DB儲存引擎有哪些?

MySQL有多種存儲引擎,每種存儲引擎有各自的優缺點,可以擇優選擇使用:

MyISAM、InnoDB、MERGE、MEMORY(HEAP)、BDB(BerkeleyDB)、EXAMPLE、FEDERATED、ARCHIVE、CSV、BLACKHOLE。

MySQL支持數個存儲引擎作為對不同表的類型的處理器。MySQL存儲引擎包括處理事務安全表的引擎和處理非事務安全表的引擎。

· MyISAM管理非事務表。它提供高速存儲和檢索,以及全文搜索能力。MyISAM在所有MySQL配置里被支持,它是默認的存儲引擎,除非你配置MySQL默認使用另外一個引擎。

· MEMORY存儲引擎提供“內存中”表。MERGE存儲引擎允許集合將被處理同樣的MyISAM表作為一個單獨的表。就像MyISAM一樣,MEMORY和MERGE存儲引擎處理非事務表,這兩個引擎也都被默認包含在MySQL中。

注釋:MEMORY存儲引擎正式地被確定為HEAP引擎。

· InnoDB和BDB存儲引擎提供事務安全表。BDB被包含在為支持它的操作系統發布的MySQL-Max二進制分發版里。InnoDB也默認被包括在所 有MySQL 5.1二進制分發版里,你可以按照喜好通過配置MySQL來允許或禁止任一引擎。

· EXAMPLE存儲引擎是一個“存根”引擎,它不做什么。你可以用這個引擎創建表,但沒有數據被存儲于其中或從其中檢索。這個引擎的目的是服務,在 MySQL源代碼中的一個例子,它演示說明如何開始編寫新存儲引擎。同樣,它的主要興趣是對開發者。

· NDB Cluster是被MySQL Cluster用來實現分割到多臺計算機上的表的存儲引擎。它在MySQL-Max 5.1二進制分發版里提供。這個存儲引擎當前只被Linux, Solaris, 和Mac OS X 支持。在未來的MySQL分發版中,我們想要添加其它平臺對這個引擎的支持,包括Windows。

· ARCHIVE存儲引擎被用來無索引地,非常小地覆蓋存儲的大量數據。

· CSV存儲引擎把數據以逗號分隔的格式存儲在文本文件中。

· BLACKHOLE存儲引擎接受但不存儲數據,并且檢索總是返回一個空集。

· FEDERATED存儲引擎把數據存在遠程數據庫中。在MySQL 5.1中,它只和MySQL一起工作,使用MySQL C Client API。在未來的分發版中,我們想要讓它使用其它驅動器或客戶端連接方法連接到另外的數據源。

558.以下是學生考試結果表
fname kecheng fenshu
張三 語文 81
張三 數學 65
李四 語文 76
李四 數學 90
王五 語文 61
王五 數學 100
王五 英語 90

1.請用一條sql語句從t_result表中查詢出每門課都大于75分的學生姓名;

select b.fname from
(select fname,count(kecheng) c from t_result group by fname)a,
(Select fname,kecheng,count(fname) c from t_result where fenshu >75 group by fname)b
where a.fname = b.fname and a.c = b.c

2.請用一條sql寫出總分排名前三的學生姓名,總分,平均分

select fname,sum(fenshu),avg(fenshu) from t_result GROUP By fname order by SUM(fenshu) desc;

559.庫中已經存在雇用表表名:

org_employee;表中字段:雇員編號(emp_id),雇員姓名(em_name),雇員年齡(emp_age),雇員部門(depart_name);請寫出執行以下操作的sql語句:

1)向表中增加一條數據:雇員編號(1001),雇員姓名(張三),雇員年齡(24),雇員部門(研發部);

INSERT INTO org_employee

VALUES(‘1001’,’張三’,’24’,’研發部’);

2)查詢雇員年齡在55(包含)至60(不包含)歲之間的雇員數據

SELECT * FROM org_employee

WHERE emp_age>=55 and emp_age <60;

3)分部門查詢各個部門的雇員數量

SELECT COUNT(*),depart_name group by depart_name;

4)刪除姓名為張三的雇員數據

Delete from org_employee where em_name =’張三’;

5)在表中增加一個日期類型的字段雇員出生日期,字段為emp_brithday

Alter table org_employee add(emp_brithday date);

6)將表org_employee刪除

drop org_employee;

560.如下表1中的數據,表名為:t_test,記錄某場比賽的結果。

請用sql語句實現表2的查詢結果

表1

ID matchdate result
1 2015-02-04
2 2015-02-04
3 2015-02-04
4 2015-04-07
5 2015-04-07
6 2015-04-07

表2

比賽日期
2015-02-04 2 1
2015-04-07 1 2

SQL語句:

create table t_second(
 matchdate date,
  win varchar(3),
  lose varchar(3)
);

insert into t_second (matchdate,win) select matchdate,count(result) from t_test where result ='勝' GROUP BY matchdate;

update t_second,(select matchdate,count(result) as lose from t_test where result ='負' GROUP BY matchdate)s set t_second.lose = s.lose where t_second.matchdate = s.matchdate;
561.請將如下數據庫語句進行優化,使其執行效率更高(提示:…不需要更改)
SELECT…
FROM EMP
WHERE DEPT_NO NOT IN (SELECT DEPT_NO
FROM DEPT
WHERE DEPT_CAT=’A’);
SELECT…
FROM EMP
WHERE DEPT_NO NOT EXISTS(SELECT DEPT_NO
FROM DEPT
WHERE DEPT_CAT=’A’);

優化的理由:not in 和not exists

如果查詢語句使用了not in 那么內外表都進行全表掃描,沒有用到索引;

而not extsts 的子查詢依然能用到表上的索引。所以無論那個表大,用not exists 都比not in 要快。

562.請簡述如何將Oracle中的數據庫轉至DB2中,需要保證表結構和數據不變

使用ETL工具,如infomatic,datastage,kettle等,可以完成異構數據庫的遷移

以kettle為例

表輸入選擇 oracle庫

表輸出選擇DB庫

循環執行可以進行全庫遷移

563.學生成績表
姓名:name 課程:subject 分數:score 學號:stuid
張三 數學 89 1
張三 語文 80 1
張三 英語 70 1
李四 數學 90 2
李四 語文 70 2
李四 英語 80 2

1.計算每個人的總成績并排名(要求顯示字段:姓名,總成績)

select name,sum(score) s from t_stu GROUP BY name;

2.列出各門課程成績最好的學生(要求顯示字段:學號,姓名,科目,成績)

select t1.stuid,t1.name,t1.subject,t1.score from t_stu t1,

(select subject,MAX(score) as maxscore from t_stu group by subject)t2

where t1.subject = t2.subject and t1.score = t2.maxscore;

3.列出各個課程的平均成績(要求顯示字段;課程,平均成績)

select subject,AVG(score)平均成績 from t_stu

group by subject;

564.Oracl數據庫中有兩張表Stu(學生表)和Grade(分數表),如下圖所示:

Stu表

sid(學生ID) sname(姓名) sage(年齡)
1 張三 23
2 李四 25
3 王五 24

Grade表

gid(分數主鍵) cid(課程ID) sid(學生主鍵) grade(分數)
1 2 3 86
2 2 2 79
3 1 2 80
4 1 1 81
5 1 3 70
6 2 1 78

請寫sql統計出有兩門以上的課的分數在80分以上的學生的姓名和年齡?

Select sname,sage from Stu where Stu.sid in (

Select sid from Grade where grade >80

)

565.下面是學生表(Student)的結構說明:
字段名稱 字段解釋 字段類型 字段長度 約束
s_id 學號 字符 10 PK
s_name 學生姓名 字符 50 Not null
s_age 學生年齡 數值 3 Not null
s-sex 學生性別 字符(男:1女:0) 1 Not null

下面是教師表(Teacher )的結構說明

字段名稱 字段解釋 字段類型 字段長度 約束
t_id 教師編號 字符 10 PK
t_name 教師名字 字符 50 Not null

下面是課程表(Course)的結構說明

字段名稱 字段解釋 字段類型 字段長度 約束
c_id 課程編號 字符 10 PK
c_name 課程名字 字符 50 Not null
t_id 教師編號 字符 10 Not null

下面是成績表(SC)的結構說明

字段名稱 字段解釋 字段類型 字段長度 約束
s_id 學號 字符 10 PK
c_id 課程編號 字符 10 Not null
score 成績 數值 3 Not null

查詢同名同姓學生名單,并統計同名人數

select 姓名,count(學號) as num

from 學生表

group by 姓名

having count(學號)>1 --保證查找到的都是存在2個以上(包括2)的同名同姓的姓名及人數。

查詢平均成績大于60分的學生的學號和平均成績;

Select s_id,avg(score) from sc groupby s_id having avg(score)>60

查詢姓“李”的老師的個數;

Select count(*),teacher.t_name from teacher where teacher.t_name like '李%'

566.取出sql表中低31到40的記錄(以自動增長ID為主鍵)

Sql server方案:

select top 10 * from t where id not in

(select top 30 id from t order by id ) orde by id

Mysql方案:select * from t order by id limit 30,10

Oracle方案:

select rownum num,tid from (select rownum num,tid from t_test) where num>=30 and num<=41;

567.下列兩個表,需要用一條sql語句把b表中的ID和NAME 字段的數值復制到A表中

A表

ID NAME

B表

ID NAME OTHER
1 Aaa Ddd
2 Bbb Eee

insert into a select id,name from b;

568.什么是基本表,什么是視圖,兩者的區別和聯系是什么?

它是從一個或幾個基本表中導出的 表,是從現有基本表中抽取若干子集組成用戶的“專用表”。

基本表:基本表的定義指建立基本關系模式,
而變更則是指對數據庫中已存在的基本表進行刪除與修改。
區別:
1、視圖是已經編譯好的sql語句。而表不是
2、視圖沒有實際的物理記錄。而表有。
3、表是內容,視圖是窗口
4、表只用物理空間而視圖不占用物理空間,
視圖只是邏輯概念的存在,表可以及時對它進行修改,
但視圖只能有創建的語句來修改
5、表是內模式,試圖是外模式
6、視圖是查看數據表的一種方法,
可以查詢數據表中某些字段構成的數據,
只是一些SQL語句的集合。從安全的角度說,
視圖可以不給用戶接觸數據表,從而不知道表結構。
7、表屬于全局模式中的表,是實表;視圖屬于局部模式的表,
是虛表。
8、視圖的建立和刪除只影響視圖本身,不影響對應的基本表。
聯系:視圖(view)是在基本表之上建立的表,它的結構(
即所定義的列)和內容(即所有數據行)都來自基本表,
它依據基本表存在而存在。一個視圖可以對應一個基本表,
也可以對應多個基本表。
視圖是基本表的抽象和在邏輯意義上建立的新關系

569.什么是事務?什么是鎖?

事務與鎖是不同的。事務具有ACID(原子性、一致性、隔離性和持久性),鎖是用于解決隔離性的一種機制。事務的隔離級別通過鎖的機制來實現。另外鎖有不同的粒度,同時事務也是有不同的隔離級別的(一般有四種:讀未提交Read uncommitted,
讀已提交Read committed,
可重復讀Repeatable read,
可串行化Serializable)。
在具體的程序設計中,開啟事務其實是要數據庫支持才行的,如果數據庫本身不支持事務,那么仍然無法確保你在程序中使用的事務是有效的。
鎖可以分為樂觀鎖和悲觀鎖:
悲觀鎖:認為在修改數據庫數據的這段時間里存在著也想修改此數據的事務;
樂觀鎖:認為在短暫的時間里不會有事務來修改此數據庫的數據;
我們一般意義上講的鎖其實是指悲觀鎖,在數據處理過程中,將數據置于鎖定狀態(由數據庫實現)
如果開啟了事務,在事務沒提交之前,別人是無法修改該數據的;如果rollback,你在本次事務中的修改將撤消(不是別人修改的會沒有,因為別人此時無法修改)。當然,前提是你使用的數據庫支持事務。還有一個要注意的是,部分數據庫支持自定義SQL鎖覆蓋事務隔離級別默認的鎖機制,如果使用了自定義的鎖,那就另當別論。
重點:一般事務使用的是悲觀鎖(具有排他性)

570.Student學生表(學號,姓名、性別、年齡、組織部門),Course 課程表(編號,課程名稱),Sc選課表(學號,課程編號,成績)

寫一個SQL語句,查詢選修了計算機原理的學生學號和姓名
select 學號,姓名 from Student where 學號 in
(select 學號 from Sc where 課程編號 in
(Select 課程編號 from Course where 課程名稱 = ‘計算機原理’))
寫一個SQL語句,查詢“周星馳”同學選修了的課程名字
select 課程名稱 from Course where 編號 in (
select Sc.課程編號 from Student,Sc where Student.姓名=’周星馳’ and Student.學號 = Sc.學號)
寫一個SQL語句,查詢選修了5門課程的學生學號和姓名
Select 學號,姓名 from Student where 學號 in (
Select 學號,count(課程編號) from Sc group by 學號 having count(課程編號)>=5)

571.sql查詢

Student(S#,Sname,Sage,Ssex)學生表
S#:學號
Sname:學生姓名
Sage:學生年齡
Ssex: 學生性別
Course(C#,Cname,T#)課程表
C#,課程編號;
Cname:課程名字;
T#:教師編號;
SC(S#,C#,score)成績表
S#:學號;
C#,課程編號;
Score:成績;
Teacher(T#,Tname)教師表
T#:教師編號;
Tname:教師名字
查詢“001”課程比“002”課程成績高的所有學生學號
select SC1.S#
from SC SC1 JOIN SC SC2 ON SC1.S#=SC2.S#
WHERE SC1.C#='001' AND SC2.C#='002' AND SC1.score>SC2.score
查詢平均成績大于60分的同學的學號和平均成績
select S#,AVG(score) 平均成績
from SC
group by S#
having AVG(score)>60
查詢所有同學的學號、姓名、選課數、總成績
select Student.S#,Sname,COUNT(*) 選課數,SUM(score) 總成績
from Student JOIN SC on Student.S#=SC.S#
group by Student.S#,Sname
查詢姓“李”的老師的個數
Select count(*) from Teacher where Tname like ‘李%’;
查詢沒學過“葉平”老師課的同學的學號、姓名
SELECT stu2.s#,stu2.stuname FROM Student stu2 WHERE stu2.s# NOT IN
(SELECT DISTINCT stu.s# FROM student stu, course c,teacher tea,score score
WHERE stu.s#= score.s# AND course.c#= score.c#
AND tea.t#= course.t#AND tea.tname= '葉平' )

JVM

572.簡述Java內存管理機制,以及垃圾回收的原理和使用過Java調優工具

內存管理的職責為分配內存,回收內存。 沒有自動內存管理的語言/平臺容易發生錯誤。

典型的問題包括懸掛指針問題,一個指針引用了一個已經被回收的內存地址,導致程序的運行完全不可知。

另一個典型問題為內存泄露,內存已經分配,但是已經沒有了指向該內存的指針,導致內存泄露。 程序員要花費大量時間在調試該類問題上。

573.描述JVM加載class文件的原理機制

JVM中類的裝載是由類加載器(ClassLoader)和它的子類來實現的,Java中的類加載器是一個重要的Java運行時系統組件,它負責在運行時查找和裝入類文件中的類。

由于Java的跨平臺性,經過編譯的Java源程序并不是一個可執行程序,而是一個或多個類文件。當Java程序需要使用某個類時,JVM會確保這個類已經被加載、連接(驗證、準備和解析)和初始化。類的加載是指把類的.class文件中的數據讀入到內存中,通常是創建一個字節數組讀入.class文件,然后產生與所加載類對應的Class對象。加載完成后,Class對象還不完整,所以此時的類還不可用。當類被加載后就進入連接階段,這一階段包括驗證、準備(為靜態變量分配內存并設置默認的初始值)和解析(將符號引用替換為直接引用)三個步驟。最后JVM對類進行初始化,包括:1)如果類存在直接的父類并且這個類還沒有被初始化,那么就先初始化父類;2)如果類中存在初始化語句,就依次執行這些初始化語句。

 類的加載是由類加載器完成的,類加載器包括:根加載器(BootStrap)、擴展加載器(Extension)、系統加載器(System)和用戶自定義類加載器(java.lang.ClassLoader的子類)。從Java 2(JDK 1.2)開始,類加載過程采取了父親委托機制(PDM)。PDM更好的保證了Java平臺的安全性,在該機制中,JVM自帶的Bootstrap是根加載器,其他的加載器都有且僅有一個父類加載器。類的加載首先請求父類加載器加載,父類加載器無能為力時才由其子類加載器自行加載。JVM不會向Java程序提供對Bootstrap的引用。下面是關于幾個類加載器的說明:

Bootstrap:一般用本地代碼實現,負責加載JVM基礎核心類庫(rt.jar);

Extension:從java.ext.dirs系統屬性所指定的目錄中加載類庫,它的父加載器是Bootstrap;

System:又叫應用類加載器,其父類是Extension。它是應用最廣泛的類加載器。它從環境變量classpath或者系統屬性java.class.path所指定的目錄中記載類,是用戶自定義加載器的默認父加載器。

574.說說JVM原理?內存泄漏與溢出的區別?何時產生內存泄漏?

答:JVM原理:

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

內存泄漏與溢出的區別:

1) 內存泄漏是指分配出去的內存無法回收了。

2) 內存溢出是指程序要求的內存,超出了系統所能分配的范圍,從而發生溢出。比如用byte類型的變量存儲10000這個數據,就屬于內存溢出。

3) 內存溢出是提供的內存不夠;內存泄漏是無法再提供內存資源。

何時產生內存泄漏:

1) 靜態集合類:在使用Set、Vector、HashMap等集合類的時候需要特別注意,有可能會發生內存泄漏。當這些集合被定義成靜態的時候,由于它們的生命周期跟應用程序一樣長,這時候,就有可能會發生內存泄漏。

2) 監聽器:在Java中,我們經常會使用到監聽器,如對某個控件添加單擊監聽器addOnClickListener(),但往往釋放對象的時候會忘記刪除監聽器,這就有可能造成內存泄漏。好的方法就是,在釋放對象的時候,應該記住釋放所有監聽器,這就能避免了因為監聽器而導致的內存泄漏。

3) 各種連接:Java中的連接包括數據庫連接、網絡連接和io連接,如果沒有顯式調用其close()方法,是不會自動關閉的,這些連接就不能被GC回收而導致內存泄漏。一般情況下,在try代碼塊里創建連接,在finally里釋放連接,就能夠避免此類內存泄漏。

4) 外部模塊的引用:調用外部模塊的時候,也應該注意防止內存泄漏。如模塊A調用了外部模塊B的一個方法,如:public void register(Object o)。這個方法有可能就使得A模塊持有傳入對象的引用,這時候需要查看B模塊是否提供了去除引用的方法,如unregister()。這種情況容易忽略,而且發生了內存泄漏的話,比較難察覺,應該在編寫代碼過程中就應該注意此類問題。

5) 單例模式:使用單例模式的時候也有可能導致內存泄漏。因為單例對象初始化后將在JVM的整個生命周期內存在,如果它持有一個外部對象(生命周期比較短)的引用,那么這個外部對象就不能被回收,而導致內存泄漏。如果這個外部對象還持有其它對象的引用,那么內存泄漏會更嚴重,因此需要特別注意此類情況。這種情況就需要考慮下單例模式的設計會不會有問題,應該怎樣保證不會產生內存泄漏問題。

575.GC線程是否為守護線程?

GC線程是守護線程。線程分為守護線程和非守護線程(即用戶線程)。只要當前JVM實例中尚存在任何一個非守護線程沒有結束,守護線程就全部工作;只有當最后一個非守護線程結束時,守護線程隨著JVM一同結束工作。

576.Java的類加載器都有哪些,每個類加載器都有加載那些類,什么是雙親委派模型,是做什么的?

類加載器按照層次,從頂層到底層,分為以下三種:

(1)啟動類加載器(Bootstrap ClassLoader)

這個類加載器負責將存放在JAVA_HOME/lib下的,或者被-Xbootclasspath參數所指定的路徑中的,并且是虛擬機識別的類庫加載到虛擬機內存中。啟動類加載器無法被Java程序直接引用。

(2)擴展類加載器(Extension ClassLoader)

這個加載器負責加載JAVA_HOME/lib/ext目錄中的,或者被java.ext.dirs系統變量所指定的路徑中的所有類庫,開發者可以直接使用擴展類加載器

(3)應用程序類加載器(Application ClassLoader)

這個加載器是ClassLoader中getSystemClassLoader()方法的返回值,所以一般也稱它為系統類加載器。它負責加載用戶類路徑(Classpath)上所指定的類庫,可直接使用這個加載器,如果應用程序沒有自定義自己的類加載器,一般情況下這個就是程序中默認的類加載器

雙親委派模型:

雙親委派模型要求除了頂層的啟動類加載器外,其他的類加載器都應當有自己的父類加載器。這里類加載器之間的父子關系一般不會以繼承關系來實現,而是都使用組合關系來復用父加載器的代碼

工作過程:

如果一個類加載器收到了類加載的請求,它首先不會自己去嘗試加載這個類,而是把這個請求委派給父類加載器去完成,每一個層次的類加載器都是如此,因此所有的加載請求最終都應該傳遞到頂層的啟動類加載器中,只有當父類加載器反饋自己無法完成這個請求(它的搜索范圍中沒有找到所需的類)時,子加載器才會嘗試自己去加載。

好處:

Java類隨著它的類加載器一起具備了一種帶有優先級的層次關系。例如類Object,它放在rt.jar中,無論哪一個類加載器要加載這個類,最終都是委派給啟動類加載器進行加載,因此Object類在程序的各種類加載器環境中都是同一個類,判斷兩個類是否相同是通過classloader.class這種方式進行的,所以哪怕是同一個class文件如果被兩個classloader加載,那么他們也是不同的類。

577.垃圾回收器(GC)的基本原理是什么?垃圾回收器可以馬上回收內存嗎?如何通知虛擬機進行垃圾回收?

1、對于GC來說,當程序員創建對象時,GC就開始監控這個對象的地址、大小以及使用情況。通常,GC采用有向圖的方式記錄和管理堆(heap)中的所有對象。通過這種方式確定哪些對象是"可達的",哪些對象是"不可達的"。當GC確定一些對象為"不可達”時,GC就有責任回收這些內存空間。

2、可以。程序員可以手動執行System.gc(),通知GC運行,但是Java語言規范并不保證GC一定會執行。

3. System.gc();或者Runtime.getRuntime().gc();

578.Java 中會存在內存泄漏嗎,請簡單描述。

答:理論上Java因為有垃圾回收機制(GC)不會存在內存泄露問題(這也是Java被廣泛使用于服務器端編程的一個重要原因);然而在實際開發中,可能會存在無用但可達的對象,這些對象不能被GC回收也會發生內存泄露。一個例子就是hibernate的Session(一級緩存)中的對象屬于持久態,垃圾回收器是不會回收這些對象的,然而這些對象中可能存在無用的垃圾對象。下面的例子也展示了Java中發生內存泄露的情況:

package com.bjsxt;
import java.util.Arrays;
import java.util.EmptyStackException;

public class MyStack<T> {
    private T[] elements;
    private int size = 0;
private static final int INIT_CAPACITY = 16;
    public MyStack() {
        elements = (T[]) new Object[INIT_CAPACITY];
    }
    public void push(T elem) {
        ensureCapacity();
        elements[size++] = elem;
    }
    public T pop() {
        if(size == 0)
            throw new EmptyStackException();
        return elements[--size];
    }
    private void ensureCapacity() {
        if(elements.length == size) {
            elements = Arrays.copyOf(elements, 2 * size + 1);
        }
    }
}

上面的代碼實現了一個棧(先進后出(FILO))結構,乍看之下似乎沒有什么明顯的問題,它甚至可以通過你編寫的各種單元測試。然而其中的pop方法卻存在內存泄露的問題,當我們用pop方法彈出棧中的對象時,該對象不會被當作垃圾回收,即使使用棧的程序不再引用這些對象,因為棧內部維護著對這些對象的過期引用(obsolete reference)。在支持垃圾回收的語言中,內存泄露是很隱蔽的,這種內存泄露其實就是無意識的對象保持。如果一個對象引用被無意識的保留起來了,那么垃圾回收器不會處理這個對象,也不會處理該對象引用的其他對象,即使這樣的對象只有少數幾個,也可能會導致很多的對象被排除在垃圾回收之外,從而對性能造成重大影響,極端情況下會引發Disk Paging(物理內存與硬盤的虛擬內存交換數據),甚至造成OutOfMemoryError。?

579.GC 是什么?為什么要有GC?

答:GC是垃圾收集的意思,內存處理是編程人員容易出現問題的地方,忘記或者錯誤的內存回收會導致程序或系統的不穩定甚至崩潰,Java提供的GC功能可以自動監測對象是否超過作用域從而達到自動回收內存的目的,Java語言沒有提供釋放已分配內存的顯示操作方法。Java程序員不用擔心內存管理,因為垃圾收集器會自動進行管理。要請求垃圾收集,可以調用下面的方法之一:System.gc() 或Runtime.getRuntime().gc() ,但JVM可以屏蔽掉顯示的垃圾回收調用。

垃圾回收可以有效的防止內存泄露,有效的使用可以使用的內存。垃圾回收器通常是作為一個單獨的低優先級的線程運行,不可預知的情況下對內存堆中已經死亡的或者長時間沒有使用的對象進行清除和回收,程序員不能實時的調用垃圾回收器對某個對象或所有對象進行垃圾回收。在Java誕生初期,垃圾回收是Java最大的亮點之一,因為服務器端的編程需要有效的防止內存泄露問題,然而時過境遷,如今Java的垃圾回收機制已經成為被詬病的東西。移動智能終端用戶通常覺得iOS的系統比Android系統有更好的用戶體驗,其中一個深層次的原因就在于Android系統中垃圾回收的不可預知性。

補充:垃圾回收機制有很多種,包括:分代復制垃圾回收、標記垃圾回收、增量垃圾回收等方式。標準的Java進程既有棧又有堆。棧保存了原始型局部變量,堆保存了要創建的對象。Java平臺對堆內存回收和再利用的基本算法被稱為標記和清除,但是Java對其進行了改進,采用“分代式垃圾收集”。這種方法會跟Java對象的生命周期將堆內存劃分為不同的區域,在垃圾收集過程中,可能會將對象移動到不同區域:

伊甸園(Eden):這是對象最初誕生的區域,并且對大多數對象來說,這里是它們唯一存在過的區域。

幸存者樂園(Survivor):從伊甸園幸存下來的對象會被挪到這里。

終身頤養園(Tenured):這是足夠老的幸存對象的歸宿。年輕代收集(Minor-GC)過程是不會觸及這個地方的。當年輕代收集不能把對象放進終身頤養園時,就會觸發一次完全收集(Major-GC),這里可能還會牽扯到壓縮,以便為大對象騰出足夠的空間。

與垃圾回收相關的JVM參數:

-Xms / -Xmx --- 堆的初始大小 / 堆的最大大小

-Xmn --- 堆中年輕代的大小

-XX:-DisableExplicitGC --- 讓System.gc()不產生任何作用

-XX:+PrintGCDetail --- 打印GC的細節

-XX:+PrintGCDateStamps --- 打印GC操作的時間戳?

Linux操作

580.請寫出常用的linux指令不低于10個,請寫出linux tomcat啟動。

答:linux指令
arch 顯示機器的處理器架構(1)
uname -m 顯示機器的處理器架構(2)
shutdown -h now 關閉系統(1)
shutdown -r now 重啟(1)
cd /home 進入 '/ home' 目錄'
cd .. 返回上一級目錄
cd ../.. 返回上兩級目錄
mkdir dir1 創建一個叫做 'dir1' 的目錄'
mkdir dir1 dir2 同時創建兩個目錄
find / -name file1 從 '/' 開始進入根文件系統搜索文件和目錄
find / -user user1 搜索屬于用戶 'user1' 的文件和目錄
linuxtomcat啟動
進入tomcat下的bin目錄執行 ./catalina.sh start直接啟動即可,然后使用tail -f /usr/local/tomcat6/logs/catalina.out查看tomcat啟動日志。

581.當使用RMI技術實現遠程方法調用時,能為遠程對象生成Sub和Skeleton命令的是()
A. Mic
B. mid
C. mitegistry
D. policytool
答案:A
582.以下哪個是服務()
A. kill
B. tar
C. rsyne
D. policytool
答案:c
分析:
A:kill命令,常用于殺死進程;
B:tar命令,tar命令是Unix/Linux系統中備份文件的可靠方法,幾乎可以工作于任何環境中,它的使用權限是所有用戶
C:類unix系統下的數據鏡像備份工具
D:在終端下輸入lsof即可顯示系統打開的文件,因為 lsof 需要訪問核心內存和各種文件,所以必須以 root 用戶的身份運行它才能夠充分地發揮其功能
583.下面的網絡協議中,面向連接的的協議是: ()
A. 傳輸控制協議
B. 用戶數據報協議
C. 網際協議
D. 網際控制報文協議
答案:A
584.在/etc/fstab 文件中指定的文件系統加載參數中, () 參數一般用于CD-ROM 等移動設備。
A. defaults
B. sw
C. rw 和 ro
D. noauto
答案:D
585.Linux 文件權限一共10 位長度,分成四段,第三段表示的內容是 ()
A. 文件類型
B. 文件所有者的權限
C. 文件所有者所在組的權限
D. 其他用戶的權限
答案:C
586.終止一個前臺進程可能用到的命令和操作 ()
A. kill
B. < CTRL >;+C
C. shut down
D. halt
答案:B
587.在使用mkdir 命令創建新的目錄時,在其父目錄不存在時先創建父目錄的選項是 ()
A. -m
B. -d
C. -d
D. -p
答案:D
588.下面關于i 節點描述錯誤的是 ()
A. i 節點和文件是一一對應的(每個文件都有唯一一個索引結點號與之對應,而對于一個索引結點號,卻可以有多個文件名與之對應)
B. i 節點能描述文件占用的塊數
C. i 節點描述了文件大小和指向數據塊的指針
D. 通過i 節點實現文件的邏輯結構和物理結構的轉換
答案:A
589.一個文件名字為rr.Z,可以用來解壓縮的命令是: ()
A. tar
B. gzip
C. compress
D. uncompress
答案:D
590.具有很多C 語言的功能,又稱過濾器的是 ()
A. csh
B. tcsh
C. awk
D. sed
答案:C
591.一臺主機要實現通過局域網與另一個局域網通信,需要做的工作是 ()
A. 配置域名服務器
B. 定義一條本機指向所在網絡的路由
C. 定義一條本機指向所在網絡網關的路由
D. 定義一條本機指向目標網絡網關的路由
答案:C
592.建立動態路由需要用到的文件有 ()
A. /etc/hosts
B. /etc/HOSTNAME
C. /etc/resolv.conf
D. /etc/gateways
答案:D
593.局域網的網絡地址192.168.1.0/24,局域網絡連接其它網絡的網關地址是192.168.1.1。主機192.168.1.20 訪問172.16.1.0/24 網絡時,其路由設置正確的是 ()
A. route add –net 192.168.1.0 gw 192.168.1.1 netmask 255.255.255.0 metric 1
B. route add –net 172.16.1.0 gw 192.168.1.1 netmask 255.255.255.0 metric 1
C. route add –net 172.16.1.0 gw 172.16.1.1 netmask 255.255.255.0 metric 1
D. route add default 192.168.1.0 netmask 172.168.1.1 metric 1
答案:B
594.下列提法中,不屬于ifconfig 命令作用范圍的是 ()
A. 配置本地回環地址
B. 配置網卡的IP地址
C. 激活網絡適配器
D. 加載網卡到內核中
答案:D
595.下列關于鏈接描述,錯誤的是()
A. 硬鏈接就是讓鏈接文件的i 節點號指向被鏈接文件的i 節點
B. 硬鏈接和符號連接都是產生一個新的i 節點
C 鏈接分為硬鏈接和符號鏈接
D. 硬連接不能鏈接目錄文件
答案:B
596.在局域網絡內的某臺主機用ping 命令測試網絡連接時發現網絡內部的主機都可以連同,而不能與公網連通,問題可能是()
A. 主機IP設置有誤
B. 沒有設置連接局域網的網關
C. 局域網的網關或主機的網關設置有誤
D. 局域網DNS服務器設置有誤
答案:C
597.下列文件中,包含了主機名到IP 地址的映射關系的文件是:
A. /etc/HOSTNAME
B. /etc/hosts
C. /etc/resolv.conf
D. /etc/networks
答案:B
598.不需要編譯內核的情況是()
A. 刪除系統不用的設備驅動程序時
B. 升級內核時
C. 添加新硬件時
D. 將網卡激活
答案:D
599.在shell 中變量的賦值有四種方法,其中,采用name=12 的方法稱 ()
A. 直接賦值
B. 使用read命令
C. 使用命令行參數
D. 使用命令的輸出
答案:A
600.()命令可以從文本文件的每一行中截取指定內容的數據。
A. cp
B. dd
C. fmt
D. cut
答案:D
601.下列不是Linux 系統進程類型的是()
A. 交互進程
B. 批處理進程
C. 守護進程