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

第一篇:面試題匯總

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

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

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

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

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

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

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

2.掃一掃,咨詢詳情:

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

Java基礎、語法:

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

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

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

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

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

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

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

2.Java的安全性

語言層次的安全性主要體現(xiàn)在:

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

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

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

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

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

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

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

字節(jié)碼校驗器 -類裝載器 -運行時內(nèi)存布局 -文件訪問限制

3.Java三大版本

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

lib:類庫??????

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

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

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

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

5.Java三種注釋類型

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

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

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

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

System.out.println("b");

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

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

/**

* 子類 Dog

* @author Administrator

**/

public class Dog extends Animal{}

6.8種基本數(shù)據(jù)類型及其字節(jié)數(shù)
數(shù)據(jù)類型 關鍵字 字節(jié)數(shù)
數(shù)值型 整數(shù)型 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是一條單獨的語句,兩者沒有任何區(qū)別

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

不同點:

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

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

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

操作數(shù)1&操作數(shù)2,操作數(shù)1&&操作數(shù)2,

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

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

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

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

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

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

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

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

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

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

|和||的區(qū)別和聯(lián)系與&和&&的區(qū)別和聯(lián)系類似

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

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

10.基本數(shù)據(jù)類型的類型轉換規(guī)則

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

自動轉換規(guī)則:容量小的數(shù)據(jù)類型可以自動轉換成容量大的數(shù)據(jù)類型,也可

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

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

如何轉換:

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

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

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

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

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

不同之處:

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

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

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

do while先執(zhí)行 后判斷,最少執(zhí)行1次。

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

13.break和continue的作用

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

break還可以退出switch語句

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

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

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

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

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

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

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

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

16.數(shù)組的特征

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

數(shù)組會在內(nèi)存中開辟一塊連續(xù)的空間,每個空間相當于之前的一個變量,稱為數(shù)組的元素element

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

索引從0開始

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

數(shù)組元素有序的,不是大小順序,是索引 的順序

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

length:數(shù)組的長度

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

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

public class TestBubbleSort {
public static void sort(int[] a) {
int temp = 0;
// 外層循環(huán),它決定一共走幾趟
for (int i = 0; i <a.length-1; ++i) {
//內(nèi)層循環(huán),它決定每趟走一次
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) {
//通過符號位可以減少無謂的比較,如果已經(jīng)有序了,就退出循環(huán)
int flag = 0;
for (int j = 0; j <a.length-1-i ; ++j) {
if (a[j + 1] < a[j]) {
temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
flag = 1;
}
}
if(flag == 0){
break;
}
}
}
}
18.請寫出選擇排序的代碼
package com.bjsxt;

public class TestSelectSort {
public static void sort(int arr[]) {
int temp = 0;
for (int i = 0; i < arr.length - 1; i++) {
// 認為目前的數(shù)就是最小的, 記錄最小數(shù)的下標
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.可變參數(shù)的作用和特點

總結1:可變參數(shù)

1.可變參數(shù)的形式 ...

2.可變參數(shù)只能是方法的形參

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

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

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

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

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

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

聯(lián)系:

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

區(qū)別:

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

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

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

21.類和對象的關系

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

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

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

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

22.面向過程和面向對象的區(qū)別

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

比喻

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

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

區(qū)別

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

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

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

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

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

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

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

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

24.static關鍵字的作用

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

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

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

1.在內(nèi)存中份數(shù)不同

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

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

2.在內(nèi)存中存放的位置不同

2.在內(nèi)存中存放的位置不同

3.訪問的方式不同

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

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

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

4.在內(nèi)存中分配空間的時間不同

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

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

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

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

25.final和abstract關鍵字的作用

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

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

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

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

package com.bjsxt;

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

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

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

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

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

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

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

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

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

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

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

垃圾回收前執(zhí)行的方法

(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權限修飾符的區(qū)別
同一個類 同一個包 子類 所有類
private *
defailt * *
protected * * *
public * * * *

類的訪問權限只有兩種

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

“==”使用情況如下:

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

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

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

equals()方法使用如下:

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

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

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

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

31.談談Java的多態(tài)

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

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

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

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

向上轉型 Student person = new Student()

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

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

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

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

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

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

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

1)程序忘記及時回收,從而導致內(nèi)存泄露,降低系統(tǒng)性能。

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

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

1)可以提高編程效率。

2)保護程序的完整性。

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

垃圾回收機制的 特點

1)垃圾回收機制回收JVM堆內(nèi)存里的對象空間,不負責回收棧內(nèi)存數(shù)據(jù)。

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

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

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

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

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

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

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

33.基本數(shù)據(jù)類型和包裝類

1) 八個基本數(shù)據(jù)類型的包裝類

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

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

2.1基本數(shù)據(jù)類型有方便之處,簡單、高效。

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

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

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

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

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

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

4) 自動裝箱和自動拆箱

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

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

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

34.Integer與int的區(qū)別

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

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

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

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

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

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

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

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

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

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

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

它的方法—戰(zhàn)斗,逃跑,吃飯,睡覺,死。

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

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

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

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

戰(zhàn)士修改成—

屬性:戰(zhàn)斗力。

方法:戰(zhàn)斗。

看上去戰(zhàn)士的資料變少了,實際上沒有,我們?nèi)匀豢梢哉{用方法—戰(zhàn)士.死。

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

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

屬性:法力值

方法:施法,泡妞。

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

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

屬性:等級,戰(zhàn)力,血量。

方法:戰(zhàn)斗,死。

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

屬性:毛色。

方法:賣萌,吃胡蘿卜。

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

答:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

52.簡述Java中如何實現(xiàn)多態(tài)

實現(xiàn)多態(tài)有三個前提條件:

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

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

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

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

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

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

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

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

不是,兩者沒有任何關聯(lián);

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

56.接口和抽象類的區(qū)別

56.接口和抽象類的區(qū)別

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

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

兩者的區(qū)別主要體現(xiàn)在兩方面:語法方面和設計理念方面

語法方面的區(qū)別是比較低層次的,非本質的,主要表現(xiàn)在:

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

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

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

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

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

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

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

57.同步代碼塊和同步方法有什么區(qū)別

相同點:

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

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

區(qū)別:

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

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

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

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

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

實例化方式不同:

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

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

59.反射的概念與作用

反射的概念:

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

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

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

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

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

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

反射的作用:

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

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

2) 獲取已裝載類的方法

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

反射的優(yōu)點:

增加程序的靈活性。

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

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

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

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

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

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

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

78.存在使i+1< i的數(shù)么?

79.接口可否繼承接口?抽象類是否可實現(xiàn)接口?抽象類是否可繼承實體類?

接口可以繼承接口,抽象類可以實現(xiàn)接口,抽象類可以繼承實體類。

80.int與Integer有什么區(qū)別?

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

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

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

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

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

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

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

83.十進制數(shù)72轉換成八進制數(shù)是多少?

答: 110

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

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

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

答: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.描述&和&&的區(qū)別。

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

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

操作數(shù)1&操作數(shù)2,操作數(shù)1&&操作數(shù)2,

操作數(shù)1&操作數(shù)2,操作數(shù)1&&操作數(shù)2,

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

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

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

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

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

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

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

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

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

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

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

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

例如:

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

\d: 匹配一個數(shù)字字符。等價于[0-9]

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

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

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

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

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

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

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

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

90.已知表達式int m[] = {0,1,2,3,4,5,6}; 下面那個表達式的值與數(shù)組的長度相等()
A m.length()
B. m.length
C. m.length()+1
D. m.length+1
答案:B
分析:數(shù)組的長度是.length
91.下面那些聲明是合法的?()
A long l = 4990
B. int i = 4L
C. float f = 1.1
D. double d = 34.4
答案:AD
分析:B int屬于整數(shù)型應該是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.下面哪個函數(shù)是public void example(){....}的重載函數(shù)?()
A private void example(int m){...}
B. public int example(){...}
C. public void example2(){...}
D. public int example(int m.float f){...}
答案:AD
分析:BC定義的是新函數(shù)
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中,無論測試條件是什么,下列()循環(huán)將至少執(zhí)行一次。
A for
B. do...while
C. while
D. while...do
答案:B
分析: ACD都不一定進行循環(huán)
98.打印結果:
package com.bjsxt;

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

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

輸出結果:2

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

打印結果:

打印結果:

zero

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

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

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

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

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

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

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

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

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

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

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

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

操作數(shù)1&操作數(shù)2 操作數(shù)1&&操作數(shù)2
表達式1&表達式2 表達式1&&表達式2

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

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

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

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

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

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

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

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

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

|和||的區(qū)別和聯(lián)系與&和&&的區(qū)別和聯(lián)系類似

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

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

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

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

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

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.請問以下代碼執(zhí)行會打印出什么?

父類:

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

執(zhí)行:C:\>java com.bjsxt.ChildClass

輸出結果:?

答:

FatherClassCreate

FatherClassCreate

ChildClass Create

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

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

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

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

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

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

A. DES
B. MD5
C. DSA
D. RSA
分析:答案:A
分析:常用的對稱加密算法有:DES、3DES、RC2、RC4、AES
常用的非對稱加密算法有:RSA、DSA、ECC
使用單向散列函數(shù)的加密算法: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代碼段會產(chǎn)生幾個對象
publicvoid test(){
String a="a";
String b="b";
String c="c";
c=a+""+b+""+c;
System.out.print(c);
}

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

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

答案: -11

分析:小數(shù)點后第一位=5

正數(shù):Math.round(11.5)=12

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

小數(shù)點后第一位<5

正數(shù):Math.round(11.46)=11

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

小數(shù)點后第一位>5

正數(shù):Math.round(11.68)=12

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

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

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

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

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

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

123.十進制數(shù)278的對應十六進制數(shù)

分析:十進制數(shù)278的對應十六進制數(shù)是116

124.Java中int.long占用的字節(jié)數(shù)分別是

分析:

1:“字節(jié)”是byte,“位”是bit ;

2: 1 byte = 8 bit ;

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

short 2個字節(jié)

int 4個字節(jié)

long 8個字節(jié)

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

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

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

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

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

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

2、調用方式不同。

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

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

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

類名調用 :Person.country

3、別名不同。

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

靜態(tài)變量稱為類變量。?

4、數(shù)據(jù)存儲位置不同。

成員變量數(shù)據(jù)存儲在堆內(nèi)存的對象中,所以也叫對象的特有數(shù)據(jù).

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

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

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

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

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

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

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

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

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

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

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

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

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

133.在二進制數(shù)據(jù)中,小數(shù)點向右移一位,則數(shù)據(jù)()
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小數(shù)點右移一位
1011 對應的十進制為 2^3*1 + 2^2*0 + 2^1*1 + 2^0*1 = 11所以是擴大到原來的2倍
134.面向對象的特征有哪些方面?

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

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

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

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

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

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

答:不正確。3.4是雙精度數(shù),將雙精度型(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中沒有使用。(根據(jù)James Gosling(Java之父)編寫的《The Java Programming Language》一書的附錄中給出了一個Java關鍵字列表,其中有goto和const,但是這兩個是目前無法使用的關鍵字,因此有些地方將其稱之為保留字,其實保留字這個詞應該有更廣泛的意義,因為熟悉C語言的程序員都知道,在系統(tǒng)類庫中使用過的有特殊意義的單詞或單詞的組合都被視為保留字)

138.int 和Integer 有什么區(qū)別?

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

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

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

包裝類型:Boolean,Character,Byte,Short,Integer,Long,F(xiàn)loat,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類的靜態(tài)方法valueOf,如果看看valueOf的源代碼就知道發(fā)生了什么。

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

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

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

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

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

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

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

        private IntegerCache() {}
}

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

139.&和&&的區(qū)別?

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

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

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

答:Math.round(11.5)的返回值是12,Math.round(-11.5)的返回值是-11。四舍五入的原理是在參數(shù)上加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次方)。

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

package com.bjsxt;

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

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

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

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

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

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

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

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

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

補充:關于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。實現(xiàn)高質量的equals方法的訣竅包括:1. 使用==操作符檢查“參數(shù)是否為這個對象的引用”;2. 使用instanceof操作符檢查“參數(shù)是否為正確的類型”;3. 對于類中的關鍵屬性,檢查參數(shù)傳入對象的屬性是否與之相匹配;4. 編寫完equals方法后,問自己它是否滿足對稱性、傳遞性、一致性;5. 重寫equals時總是要重寫hashCode;6. 不要將equals方法參數(shù)中的Object對象替換為其他的類型,在重寫時不要忘掉@Override注解。

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

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

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

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

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

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

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

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

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

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

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

}

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

Outer outer = new Outer();

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

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

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

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

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

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

Outer.Inner inner = newOuter.Inner();

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

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

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

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

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;
        }
    }
     /**
     * 發(fā)牌
     * @param index 發(fā)牌的位置
     */
    public Card deal(int index) {
        return cards[index];
    }

    /**
     * 卡片類(一張撲克)
     * [內(nèi)部類]
     * @author sxt
     */
    public class Card {
  private String suite;   // 花色
        private int face;       // 點數(shù)
  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);  // 發(fā)第一張牌
              // 對于非靜態(tài)內(nèi)部類Card
        // 只有通過其外部類Poker對象才能創(chuàng)建Card對象
        Poker.Card c2 = poker.new Card("紅心", 1);    // 自己創(chuàng)建一張牌
        System.out.println(c1);     // 洗牌后的第一張
        System.out.println(c2);     // 打印: 紅心A
    }
}
150.抽象的(abstract)方法是否可同時是靜態(tài)的(static),是否可同時是本地方法(native),是否可同時被synchronized修飾?

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

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

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

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

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

153.如何實現(xiàn)對象克???
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方法沒有任何意義
        // 這兩個基于內(nèi)存的流只要垃圾回收器清理對象就能夠釋放資源
}
}

答:有兩種方式:

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

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

下面是測試代碼:

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

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

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

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

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

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

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

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

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

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

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

答:一個內(nèi)部類對象可以訪問創(chuàng)建它的外部類對象的成員,包括私有成員。如果要訪問外部類的局部變量,此時局部變量必須使用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();
    }
}

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

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

160.說說數(shù)據(jù)類型之間的轉換:

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

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

答:

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

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

161.如何實現(xiàn)字符串的反轉及替換?

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

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秒到現(xiàn)在的毫秒數(shù)?

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

4 ) 如何格式化日期?

答:操作方法如下所示:

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

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

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反射技術主要實現(xiàn)類有哪些,作用分別是什么?

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

1)Class類:代表一個類

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

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

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

5)Array類:提供了動態(tài)創(chuàng)建數(shù)組,以及訪問數(shù)組的元素的靜態(tài)方法

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.反射的使用場合和作用、及其優(yōu)缺點

1)使用場合

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

2)主要作用

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

3)反射的優(yōu)點

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

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

5)反射的缺點

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

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

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

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

1)單一職責原則SRP

2)開閉原則OCP

3)里氏替代原則LSP

4)依賴注入原則DIP

5)接口分離原則ISP

6)迪米特原則LOD

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

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

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關鍵字創(chuàng)建了一個對象,在堆中開辟了空間,”==”比較的是對象的引用,即內(nèi)存地址,所以str1與str2兩個對象的內(nèi)存地址是不相同的
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”。字符型數(shù)組在方法調用時,將主方法中ex.ch的引用傳遞給change方法中的ch,指向是堆中的同一堆空間,所以修改ch[0]的時候,ex.ch可以看到相同的修改后的結果。
172.執(zhí)行下列代碼后,哪個結論是正確的()(選擇兩項)

String[] s=new String[10];

A. s[10]為””
B. s[9]為null
C. s[0]為未定義
D. s.length為10
答案:BD
分析: 引用數(shù)據(jù)類型的默認值均為null
s.length數(shù)組的長度
173.實現(xiàn)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";
// 將字符串中的數(shù)字全部替換為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.在“=”后填寫適當?shù)膬?nèi)容:

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修飾的類是不能被繼承的,實現(xiàn)細節(jié)不允許改變。

public final class String implements java.io.Serializable,

Comparable< String>, CharSequence

176.給定兩個字符串s和t, 寫一個函數(shù)來決定是否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”);創(chuàng)建了幾個String對象。

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

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

false

true

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

0 Hello world

1 Hello world

2 Hello world

3 Hello world

4 Hello world

5 Hello world

6 Hello world

7 Hello world

8 Hello world

9 Hello world

180.關于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.已知如下代碼:執(zhí)行結果是什么()
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.寫一個方法,實現(xiàn)字符串的反轉,如:輸入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 是最基本的數(shù)據(jù)類型嗎?

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

187.String 和StringBuilder、StringBuffer 的區(qū)別?

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

相同點:

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

不同點:

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

補充1:有一個面試題問:有沒有哪種情況用+做字符串連接比調用StringBuffer / StringBuilder對象的append方法性能更好?如果連接后得到的字符串在靜態(tài)存儲區(qū)中是早已存在的,那么用+做字符串連接是優(yōu)于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()方法,含義如下:返回字符串對象的規(guī)范化表示形式。它遵循以下規(guī)則:對于任意兩個字符串 s 和 t,當且僅當 s.equals(t) 為 true 時,s.intern()?==?t.intern() 才為 true。

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

結果如下:

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

189.String類型是基本數(shù)據(jù)類型嗎?基本數(shù)據(jù)類型有哪些

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

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

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

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

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

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

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

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

而非

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

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

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

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

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

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

192.下面這條語句一共創(chuàng)建了多少個對象: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編譯可以對字符串常量直接相加的表達式進行優(yōu)化,不必要等到運行期去進行加法運算處理,而是在編譯時去掉其中的加號,直接將其編譯成一個這些常量相連的結果。

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

寫如下兩行代碼,

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

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

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

集合:

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

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

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

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

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

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

相同點:

1)實現(xiàn)原理相同---底層都使用數(shù)組

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

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

不同點:

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

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

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

相同點:

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

不同點:

ArrayList實現(xiàn)了長度可變的數(shù)組,在內(nèi)存中分配連續(xù)空間。遍歷元素和隨機訪問元素的效率比較高;

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

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

相同點:

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

不同點:

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

2、Hashtable繼承Dictionary類,HashMap實現(xiàn)Map接口

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

3)數(shù)組容量固定且無法動態(tài)改變,集合類容量動態(tài)改變。

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

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

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

200.Collection和Collections的區(qū)別

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

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

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

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

兩者的主要區(qū)別如下

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

2、Hashtable繼承Dictionary類,HashMap實現(xiàn)Map接口

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

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

HashSet與HashMap的區(qū)別

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

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的實現(xiàn)類;HashSet和TreeSet是Set的實現(xiàn)類;LinkedHashSet是HashSet的子類。HashMap和TreeMap是Map的實現(xiàn)類;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
分析:已經(jīng)指定了長度, 所以不擴容
206.List、Set、Map哪個繼承自Collection接口,一下說法正確的是()
A. List Map
B. Set Map
C. List Set
D. List Map Set
答案:C
分析:Map接口繼承了java.lang.Object類,但沒有實現(xiàn)任何接口.
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.用遞歸方式實現(xiàn)鏈表的轉置。
/**
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.給定一個不包含相同元素的整數(shù)集合,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是以整數(shù)為元素的動態(tài)數(shù)組,而res是以數(shù)組為元素的數(shù)組,在這一步,當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
分析:
數(shù)組插入、刪除效率差,排除A
tor不是java里面的數(shù)據(jù)結構,是一種網(wǎng)絡路由技術;因此排除C
Collection 是集合的接口,不是某種數(shù)據(jù)結構;因此排除D
212.以下結構中,哪個最適合當作stack使用()
A. LinkedHashMap
B. LinkedHashSet
C. LinkedList
LinkedList
分析:
Stack是先進后出的線性結構;所以鏈表比較合適;不需要散列表的數(shù)據(jù)結構
213.Map的實現(xiàn)類中,哪些是有序的,哪些是無序的,有序的是如何保證其有序性,你覺得哪個有序性性能更高,你有沒有更好或者更高效的實現(xiàn)方式?

答:1. Map的實現(xiàn)類有HashMap,LinkedHashMap,TreeMap

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

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

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

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

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

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

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

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

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

分析:Java中的java.util.Map的實現(xiàn)類

1、HashMap

2、Hashtable

3、LinkedHashMap

4、TreeMap

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

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

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

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

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

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

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

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

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

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

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

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

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

例子1:

Student.java

package com.bjsxt;

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

Test01.java

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

class Test01 {
  public static void main(String[] args) {
        Set<Student> set = new TreeSet<>();     // Java 7的鉆石語法(構造器后面的尖括號中不需要寫類型)
        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方法的第二個參數(shù)傳入一個Comparator接口對象
        // 相當于是傳入一個比較對象大小的算法到sort方法中
        // 由于Java中沒有函數(shù)指針、仿函數(shù)、委托這樣的概念
        // 因此要將一個算法傳入一個方法中唯一的選擇就是通過接口回調
        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.下列哪個方法可用于創(chuàng)建一個可運行的類()
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和實現(xiàn)Runable接口
225.說明類java.lang.ThreadLocal的作用和原理。列舉在哪些程序中見過ThreadLocal的使用?

作用:

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

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

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

ThreadLocal的原理

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

226.說說樂觀鎖與悲觀鎖

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

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

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

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

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

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

synchronized (acct) { }

}

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

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

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

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

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

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:實現(xiàn)Java.lang.Runnable接口,并實現(xiàn)run()方法。優(yōu)勢:可繼承其它類,多線程可共享同一個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方法必須使用上鎖的對象來調用,從而持有該對象的鎖進入線程等待狀態(tài),直到使用該上鎖的對象調用notify或者notifyAll方法來喚醒之前進入等待的線程,以釋放持有的鎖。

230.Java線程的幾種狀態(tài)

答:線程是一個動態(tài)執(zhí)行的過程,它有一個從產(chǎn)生到死亡的過程,共五種狀態(tài):

新建(new Thread)

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

例如:Thread t1=new Thread();

就緒(runnable)

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

運行(running)

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

死亡(dead)

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

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

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

堵塞(blocked)

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

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

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

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

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

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

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

一、volatile的內(nèi)存語義是:

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

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

二、volatile底層的實現(xiàn)機制

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

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

2、使得本CPU的Cache寫入內(nèi)存

3、寫入動作也會引起別的CPU或者別的內(nèi)核無效化其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) 實現(xiàn)Runnable接口

public class java_thread implements Runnable{
    public static void main(String args[]) {
        new Thread(new java_thread()).start();
        System.out.println("main thread run ");
    }
    public void run() {
        System.out.println("sub thread run ");
    }
}

在Executor框架下,利用Executors的靜態(tài)方法可以創(chuàng)建三種類型的常用線程池:

1)FixedThreadPool這個線程池可以創(chuàng)建固定線程數(shù)的線程池。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

銀行賬戶類:

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);   // 模擬此業(yè)務需要一段處理時間
        }
        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());
    }
}

在沒有同步的情況下,執(zhí)行結果通常是顯示賬戶余額在10元以下,出現(xiàn)這種狀況的原因是,當一個線程A試圖存入1元的時候,另外一個線程B也能夠進入存款的方法中,線程B讀取到的賬戶余額仍然是線程A存入1元錢之前的賬戶余額,因此也是在原來的余額0上面做了加1元的操作,同理線程C也會做類似的事情,所以最后100個線程執(zhí)行結束時,本來期望賬戶余額為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);   // 模擬此業(yè)務需要一段處理時間
        }
        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顯示的鎖機制,為每個銀行賬戶創(chuàng)建一個鎖對象,在存款操作進行加鎖和解鎖的操作

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); // 模擬此業(yè)務需要一段處理時間
            }
            catch (InterruptedException ex) {
                ex.printStackTrace();
            }
            balance = newBalance;
        }
        finally {
            accountLock.unlock();
        }
    }
    /**
     * 獲得賬戶余額
     */
    public double getBalance() {
        return balance;
    }
}

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

245.編寫多線程程序有幾種實現(xiàn)方式?

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

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

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關鍵字可以將對象或者方法標記為同步,以實現(xiàn)對對象和方法的互斥訪問,可以用synchronized(對象) { … }定義同步代碼塊,或者在聲明方法時將synchronized作為方法的修飾符。在第60題的例子中已經(jīng)展示了synchronized關鍵字的用法。?

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

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

API解釋如下:

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

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

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

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

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

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

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

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

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

249.線程的基本狀態(tài)以及狀態(tài)之間的關系?

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

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

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

251.創(chuàng)建線程的兩種方式分別是什么,優(yōu)缺點是什么?

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

優(yōu)勢:編寫簡單;

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

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:實現(xiàn)Java.lang.Runnable接口,并實現(xiàn)run()方法。

優(yōu)勢:可繼承其它類,多線程可共享同一個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創(chuàng)建線程后,調用start()方法和run()的區(qū)別

兩種方法的區(qū)別

1) start方法:

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

2) run():

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

總結:調用start方法方可啟動線程,而run方法只是thread的一個普通方法調用,還是在主線程里執(zhí)行。這兩個方法應該都比較熟悉,把需要并行處理的代碼放在run()方法中,start()方法啟動線程將自動調用 run()方法,這是由jvm的內(nèi)存機制規(guī)定的。并且run()方法必須是public訪問權限,返回值類型為void。

兩種方式的比較 :

實際中往往采用實現(xiàn)Runable接口,一方面因為java只支持單繼承,繼承了Thread類就無法再繼續(xù)繼承其它類,而且Runable接口只有一個run方法;另一方面通過結果可以看出實現(xiàn)Runable接口才是真正的多線程。

253.線程的生命周期

線程是一個動態(tài)執(zhí)行的過程,它也有一個從產(chǎn)生到死亡的過程。

生命周期的五種狀態(tài)

新建(new Thread)

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

例如:Thread t1=new Thread();

就緒(runnable)

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

運行(running)

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

死亡(dead)

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

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

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

堵塞(blocked)

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

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

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

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

254.如何實現(xiàn)線程同步?

當多個線程訪問同一個數(shù)據(jù)時,容易出現(xiàn)線程安全問題,需要某種方式來確保資源在某一時刻只被一個線程使用。需要讓線程同步,保證數(shù)據(jù)安全

線程同步的實現(xiàn)方案:

1)同步代碼塊,使用synchronized關鍵字

同步代碼塊:

synchronized (同步鎖) {
授課代碼;
}

同步方法:

public synchronized void makeWithdrawal(int amt) { }

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

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

注意: 同步代碼塊,所使用的同步鎖可以是三種,

1、this 2、 共享資源 3、 字節(jié)碼文件對象

同步方法所使用的同步鎖,默認的是this

255.說說關于同步鎖的更多細節(jié)

答:Java中每個對象都有一個內(nèi)置鎖。

當程序運行到非靜態(tài)的synchronized同步方法上時,自動獲得與正在執(zhí)行代碼類的當前實例(this實例)有關的鎖。獲得一個對象的鎖也稱為獲取鎖、鎖定對象、在對象上鎖定或在對象上同步。

當程序運行到synchronized同步方法或代碼塊時才該對象鎖才起作用。

一個對象只有一個鎖。所以,如果一個線程獲得該鎖,就沒有其他線程可以獲得鎖,直到第一個線程釋放(或返回)鎖。這也意味著任何其他線程都不能進入該對象上的synchronized方法或代碼塊,直到該鎖被釋放。

釋放鎖是指持鎖線程退出了synchronized同步方法或代碼塊。

關于鎖和同步,有一下幾個要點:

1)只能同步方法,而不能同步變量和類;

2)每個對象只有一個鎖;當提到同步時,應該清楚在什么上同步?也就是說,在哪個對象上同步?

3)不必同步類中所有的方法,類可以同時擁有同步和非同步方法。

4)如果兩個線程要執(zhí)行一個類中的synchronized方法,并且兩個線程使用相同的實例來調用方法,那么一次只能有一個線程能夠執(zhí)行方法,另一個需要等待,直到鎖被釋放。也就是說:如果一個線程在對象上獲得一個鎖,就沒有任何其他線程可以進入(該對象的)類中的任何一個同步方法。

5)如果線程擁有同步和非同步方法,則非同步方法可以被多個線程自由訪問而不受鎖的限制。

6)線程睡眠時,它所持的任何鎖都不會釋放。

7)線程可以獲得多個鎖。比如,在一個對象的同步方法里面調用另外一個對象的同步方法,則獲取了兩個對象的同步鎖。

8)同步損害并發(fā)性,應該盡可能縮小同步范圍。同步不但可以同步整個方法,還可以同步方法中一部分代碼塊。

9)在使用同步代碼塊時候,應該指定在哪個對象上同步,也就是說要獲取哪個對象的鎖。

256.Java中實現(xiàn)線程通信的三個方法的作用是什么?

Java提供了3個方法解決線程之間的通信問題,均是java.lang.Object類的方法,都只能在同步方法或者同步代碼塊中使用,否則會拋出異常。

方法名 作 用
final void wait() 表示線程一直等待,直到其它線程通知
void wait(long timeout) 線程等待指定毫秒?yún)?shù)的時間
final void wait(long timeout,int nanos) 線程等待指定毫秒、微妙的時間
final void notify() 喚醒一個處于等待狀態(tài)的線程。注意的是在調用此方法的時候,并不能確切的喚醒某一個等待狀態(tài)的線程,而是由JVM確定喚醒哪個線程,而且不是按優(yōu)先級。
final void notifyAll() 喚醒同一個對象上所有調用wait()方法的線程,注意并不是給所有喚醒線程一個對象的鎖,而是讓它們競爭
IO流:
257.下面哪個流類屬于面向字符的輸入流()選擇一項)
A. BufferedWriter
B. FileInputStream
C. ObjectInputStream
D. InputStreamReader
答案:D
分析:A:字符輸出的緩沖流
B:字節(jié)輸入流
C:對象輸入流

258.要從文件”file.dat”文件中讀出第10個字節(jié)到變量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指的是要跳過的字節(jié)數(shù)
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類的參數(shù)只能是Reader類型的,不能是InputStream類型。
260.下面哪個流是面向字符的輸入流()
A. BufferedWriter
B. FileInputStream
C. ObjectInputStream
D. InputStreamReader
答案:D
以InputStream(輸入流)/OutputStream(輸出流)為后綴的是字節(jié)流;
以Reader(輸入流)/Writer(輸出流)為后綴的是字符流。
261.Java類庫中,將信息寫入內(nèi)存的類是()
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中如何實現(xiàn)序列化,有什么意義?

答:序列化就是一種用來處理對象流的機制,所謂對象流也就是將對象的內(nèi)容進行流化??梢詫α骰蟮膶ο筮M行讀寫操作,也可將流化后的對象傳輸于網(wǎng)絡之間。序列化是為了解決對象流讀寫操作時可能引發(fā)的問題(如果不進行序列化可能會存在數(shù)據(jù)亂序的問題)。

要實現(xiàn)序列化,需要讓一個類實現(xiàn)Serializable接口,該接口是一個標識性接口,標注該類對象是可被序列化的,然后使用一個輸出流來構造一個對象輸出流并通過writeObject(Object obj)方法就可以將實現(xiàn)對象寫出(即保存其狀態(tài));如果需要反序列化則可以用一個輸入流建立對象輸入流,然后通過readObject方法從流中讀取對象。序列化除了能夠實現(xiàn)對象的持久化之外,還能夠用于對象的深度克?。▍⒁奐ava面試題集1-29題)?

265.Java 中有幾種類型的流?

答:兩種流分別是字節(jié)流,字符流。

字節(jié)流繼承于InputStream、OutputStream,字符流繼承于Reader、Writer。在java.io 包中還有許多其他的流,主要是為了提高性能和使用方便。

補充:關于Java的IO需要注意的有兩點:一是兩種對稱性(輸入和輸出的對稱性,字節(jié)和字符的對稱性);二是兩種設計模式(適配器模式和裝潢模式)。另外Java中的流不同于C#的是它只有一個維度一個方向。

補充:下面用IO和NIO兩種方式實現(xiàn)文件拷貝,這個題目在面試的時候是經(jīng)常被問到的。

package com.bjsxt;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class MyUtil {
  private MyUtil() {
        throw new AssertionError();
    }

    public static void fileCopy(String source, String target) throws IOException {
        try (InputStream in = new FileInputStream(source)) {
            try (OutputStream out = new FileOutputStream(target)) {
                byte[] buffer = new byte[4096];
                int bytesToRead;
                while((bytesToRead = in.read(buffer)) != -1) {
                    out.write(buffer, 0, bytesToRead);
                }
            }
        }
    }

    public static void fileCopyNIO(String source, String target) throws IOException {
        try (FileInputStream in = new FileInputStream(source)) {
            try (FileOutputStream out = new FileOutputStream(target)) {
                FileChannel inChannel = in.getChannel();
                FileChannel outChannel = out.getChannel();
                ByteBuffer buffer = ByteBuffer.allocate(4096);
                while(inChannel.read(buffer) != -1) {
                    buffer.flip();
                    outChannel.write(buffer);
                    buffer.clear();
                 }
            }
        }
    }
}

注意:上面用到Java 7的TWR,使用TWR后可以不用在finally中釋放外部資源 ,從而讓代碼更加優(yōu)雅。

266.寫一個方法,輸入一個文件名和一個字符串,統(tǒng)計這個字符串在這個文件中出現(xiàn)的次數(shù)。

答:代碼如下:

package com.bjsxt;
import java.io.BufferedReader;
import java.io.FileReader;

public class Account {
    // 工具類中的方法都是靜態(tài)方式訪問的因此將構造器私有不允許創(chuàng)建對象(絕對好習慣)
    private Account() {
        throw new AssertionError();
    }
    /**
     * 統(tǒng)計給定文件中給定字符串的出現(xiàn)次數(shù)
     * @param filename  文件名
     * @param word 字符串
     * @return 字符串在文件中出現(xiàn)的次數(shù)
     */
    public static int countWordInFile(String filename, String word) {
        int counter = 0;
        try (FileReader fr = new FileReader(filename)) {
            try (BufferedReader br = new BufferedReader(fr)) {
                String line = null;
                while ((line = br.readLine()) != null) {
                    int index = -1;
                    while (line.length() >= word.length() && (index = line.indexOf(word)) >= 0) {
                        counter++;
                        line = line.substring(index + word.length());
                    }
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return counter;
    }
}
267.輸入流和輸出流聯(lián)系和區(qū)別,節(jié)點流和處理流聯(lián)系和區(qū)別

首先,你要明白什么是“流”。直觀地講,流就像管道一樣,在程序和文件之間,輸入輸出的方向是針對程序而言,向程序中讀入東西,就是輸入流,從程序中向外讀東西,就是輸出流。

輸入流是得到數(shù)據(jù),輸出流是輸出數(shù)據(jù),而節(jié)點流,處理流是流的另一種劃分,按照功能不同進行的劃分。節(jié)點流,可以從或向一個特定的地方(節(jié)點)讀寫數(shù)據(jù)。處理流是對一個已存在的流的連接和封裝,通過所封裝的流的功能調用實現(xiàn)數(shù)據(jù)讀寫。如BufferedReader。處理流的構造方法總是要帶一個其他的流對象做參數(shù)。一個流對象經(jīng)過其他流的多次包裝,稱為流的鏈接。

268.字符流字節(jié)流聯(lián)系區(qū)別;什么時候使用字節(jié)流和字符流?

字符流和字節(jié)流是流的一種劃分,按處理照流的數(shù)據(jù)單位進行的劃分。兩類都分為輸入和輸出操作。在字節(jié)流中輸出數(shù)據(jù)主要是使用OutputStream完成,輸入使的是InputStream,在字符流中輸出主要是使用Writer類完成,輸入流主要使用Reader類完成。這四個都是抽象類。

字符流處理的單元為2個字節(jié)的Unicode字符,分別操作字符、字符數(shù)組或字符串,而字節(jié)流處理單元為1個字節(jié),操作字節(jié)和字節(jié)數(shù)組。字節(jié)流是最基本的,所有的InputStrem和OutputStream的子類都是,主要用在處理二進制數(shù)據(jù),它是按字節(jié)來處理的 但實際中很多的數(shù)據(jù)是文本,又提出了字符流的概念,它是按虛擬機的編碼來處理,也就是要進行字符集的轉化 這兩個之間通過 InputStreamReader,OutputStreamWriter來關聯(lián),實際上是通過byte[]和String來關聯(lián)的。

269.列舉常用字節(jié)輸入流和輸出流并說明其特點,至少5對。

FileInputStream 從文件系統(tǒng)中的某個文件中獲得輸入字節(jié)。

FileOutputStream 從程序當中的數(shù)據(jù),寫入到指定文件。

ObjectInputStream 對以前使用 ObjectOutputStream 寫入的基本數(shù)據(jù)和對象進行反序列化。 ObjectOutputStream 和ObjectInputStream 分別與FileOutputStream 和 FileInputStream 一起使用時,可以為應用程序提供對對象圖形的持久存儲。ObjectInputStream 用于恢復那些以前序列化的對象。其他用途包括使用套接字流在主機之間傳遞對象,或者用于編組和解組遠程通信系統(tǒng)中的實參和形參。

ByteArrayInputStream 包含一個內(nèi)部緩沖區(qū),該緩沖區(qū)包含從流中讀取的字節(jié)。內(nèi)部計數(shù)器跟蹤 read 方法要提供的下一個字節(jié)。

FilterInputStream 包含其他一些輸入流,它將這些流用作其基本數(shù)據(jù)源,它可以直接傳輸數(shù)據(jù)或提供一些額外的功能。FilterInputStream 類本身只是簡單地重寫那些將所有請求傳遞給所包含輸入流的 InputStream 的所有方法。FilterInputStream 的子類可進一步重寫這些方法中的一些方法,并且還可以提供一些額外的方法和字段。

StringBufferInputStream此類允許應用程序創(chuàng)建輸入流,在該流中讀取的字節(jié)由字符串內(nèi)容提供。應用程序還可以使用ByteArrayInputStream 從 byte 數(shù)組中讀取字節(jié)。 只有字符串中每個字符的低八位可以由此類使用。

ByteArrayOutputStream此類實現(xiàn)了一個輸出流,其中的數(shù)據(jù)被寫入一個 byte 數(shù)組。緩沖區(qū)會隨著數(shù)據(jù)的不斷寫入而自動增長??墒褂?toByteArray() 和 toString() 獲取數(shù)據(jù)。

FileOutputStream文件輸出流是用于將數(shù)據(jù)寫入 File 或FileDescriptor 的輸出流。文件是否可用或能否可以被創(chuàng)建取決于基礎平臺。特別是某些平臺一次只允許一個 FileOutputStream(或其他文件寫入對象)打開文件進行寫入。在這種情況下,如果所涉及的文件已經(jīng)打開,則此類中的構造方法將失敗。

FilterOutputStream類是過濾輸出流的所有類的超類。這些流位于已存在的輸出流(基礎 輸出流)之上,它們將已存在的輸出流作為其基本數(shù)據(jù)接收器,但可能直接傳輸數(shù)據(jù)或提供一些額外的功能。 FilterOutputStream 類本身只是簡單地重寫那些將所有請求傳遞給所包含輸出流的 OutputStream 的所有方法。FilterOutputStream 的子類可進一步地重寫這些方法中的一些方法,并且還可以提供一些額外的方法和字段。

ObjectOutputStream 將 Java 對象的基本數(shù)據(jù)類型和圖形寫入 OutputStream??梢允褂?ObjectInputStream 讀?。ㄖ貥嫞ο?。通過在流中使用文件可以實現(xiàn)對象的持久存儲。如果流是網(wǎng)絡套接字流,則可以在另一臺主機上或另一個進程中重構對象。

PipedOutputStream可以將管道輸出流連接到管道輸入流來創(chuàng)建通信管道。管道輸出流是管道的發(fā)送端。通常,數(shù)據(jù)由某個線程寫入 PipedOutputStream 對象,并由其他線程從連接的 PipedInputStream 讀取。不建議對這兩個對象嘗試使用單個線程,因為這樣可能會造成該線程死鎖。如果某個線程正從連接的管道輸入流中讀取數(shù)據(jù)字節(jié),但該線程不再處于活動狀態(tài),則該管道被視為處于毀壞狀態(tài)。

270.說明緩沖流的優(yōu)點和原理

不帶緩沖的流的工作原理:

它讀取到一個字節(jié)/字符,就向用戶指定的路徑寫出去,讀一個寫一個,所以就慢了。

帶緩沖的流的工作原理:

讀取到一個字節(jié)/字符,先不輸出,等湊足了緩沖的最大容量后一次性寫出去,從而提高了工作效率

優(yōu)點:減少對硬盤的讀取次數(shù),降低對硬盤的損耗。

271.序列化的定義、實現(xiàn)和注意事項

想把一個對象寫在硬盤上或者網(wǎng)絡上,對其進行序列化,把他序列化成為一個字節(jié)流。

實現(xiàn)和注意事項:

1)實現(xiàn)接口Serializable Serializable接口中沒有任何的方法,實現(xiàn)該接口的類不需要實現(xiàn)額外的方法。

2)如果對象中的某個屬性是對象類型,必須也實現(xiàn)Serializable接口才可以,序列化對靜態(tài)變量無效

3)如果不希望某個屬性參與序列化,不是將其static,而是transient串行化保存的只是變量的值,對于變量的任何修飾符,都不能保存序列化版本不兼容

272.使用IO流完成文件夾復制

(結合遞歸)

package com.bjsxt;

import java.io.*;
/**
 * CopyDocJob定義了實際執(zhí)行的任務,即
 * 從源目錄拷貝文件到目標目錄
*/
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));
            // 緩沖數(shù)組
            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;
     }
     //檢查目標目錄,如不存在則創(chuàng)建
     File fTargetDir = new File(targetDir);
     if(!fTargetDir.exists()){
      fTargetDir.mkdirs();
     }
        // 遍歷源目錄下的文件或目錄
        File[] file = fSourceDir.listFiles();
        for (int i = 0; i < file.length; i++) {
            if (file[i].isFile()) {
                // 源文件
                File sourceFile = file[i];
                // 目標文件
                File targetFile = new File(fTargetDir, file[i].getName());
                copyFile(sourceFile, targetFile);
            }
            //遞歸復制子目錄
            if (file[i].isDirectory()) {
                // 準備復制的源文件夾
                String subSourceDir = sourceDir + File.separator + file[i].getName();
                // 準備復制的目標文件夾
                String subTargetDir = targetDir + File.separator + file[i].getName();
                // 復制子目錄
                copyDirectiory(subSourceDir, subTargetDir);
            }
        }
    }
}
273.說說BIO、NIO和AIO的區(qū)別

Java BIO: 同步并阻塞,服務器實現(xiàn)模式為一個連接一個線程,即客戶端有連接請求時服務器端就需要啟動一個線程進行處理,如果這個連接不做任何事情會造成不必要的線程開銷,當然可以通過線程池機制改善。

Java NIO: 同步非阻塞,服務器實現(xiàn)模式為一個請求一個線程,即客戶端發(fā)送的連接請求都會注冊到多路復用器上,多路復用器輪詢到連接有I/O請求時才啟動一個線程進行處理。

Java AIO: 異步非阻塞,服務器實現(xiàn)模式為一個有效請求一個線程,客戶端的I/O請求都是由OS先完成了再通知服務器應用去啟動線程進行處理。

NIO比BIO的改善之處是把一些無效的連接擋在了啟動線程之前,減少了這部分資源的浪費(因為我們都知道每創(chuàng)建一個線程,就要為這個線程分配一定的內(nèi)存空間)

AIO比NIO的進一步改善之處是將一些暫時可能無效的請求擋在了啟動線程之前,比如在NIO的處理方式中,當一個請求來的話,開啟線程進行處理,但這個請求所需要的資源還沒有就緒,此時必須等待后端的應用資源,這時線程就被阻塞了。

適用場景分析:

BIO方式適用于連接數(shù)目比較小且固定的架構,這種方式對服務器資源要求比較高,并發(fā)局限于應用中,JDK1.4以前的唯一選擇,但程序直觀簡單易理解,如之前在Apache中使用。

NIO方式適用于連接數(shù)目多且連接比較短(輕操作)的架構,比如聊天服務器,并發(fā)局限于應用中,編程比較復雜,JDK1.4開始支持,如在 Nginx,Netty中使用。

AIO方式使用于連接數(shù)目多且連接比較長(重操作)的架構,比如相冊服務器,充分調用OS參與并發(fā)操作,編程比較復雜,JDK7開始支持,在成長中,Netty曾經(jīng)使用過,后來放棄。

網(wǎng)絡編程:

274.IP地址和端口號

1)IP地址

用來標志網(wǎng)絡中的一個通信實體的地址。通信實體可以是計算機,路由器等。

2)IP地址分類

IPV4:32位地址,以點分十進制表示,如192.168.0.1

IPV6:128位(16個字節(jié))寫成8個16位的無符號整數(shù),每個整數(shù)用四個十六進制位表示,數(shù)之間用冒號(:)分開,如:3ffe:3201:1401:1280:c8ff:fe4d:db39:1984

3)特殊的IP地址

127.0.0.1 本機地址

192.168.0.0--192.168.255.255私有地址,屬于非注冊地址,專門為組織機構內(nèi)部使用。

4)端口:port

IP地址用來標志一臺計算機,但是一臺計算機上可能提供多種應用程序,使用端口來區(qū)分這些應用程序。 端口是虛擬的概念,并不是說在主機上真的有若干個端口。通過端口,可以在一個主機上運行多個網(wǎng)絡應用程序。 端口范圍0---65535,16位整數(shù)

5)端口分類

公認端口 0—1023 比如80端口分配給WWW,21端口分配給FTP,22端口分配給SSH,23端口分配給telnet,25端口分配給smtp

注冊端口 1024—49151 分配給用戶進程或應用程序

動態(tài)/私有端口 49152--65535

6)理解IP和端口的關系

IP地址好比每個人的地址(門牌號),端口好比是房間號。必須同時指定IP地址和端口號才能夠正確的發(fā)送數(shù)據(jù)

IP地址好比為電話號碼,而端口號就好比為分機號。

275.介紹OSI七層模型和TCP/IP模型

OSI(Open System Interconnection),開放式系統(tǒng)互聯(lián)參考模型 。是一個邏輯上的定義,一個規(guī)范,它把網(wǎng)絡協(xié)議從邏輯上分為了7層。每一層都有相關、相對應的物理設備,比如常規(guī)的路由器是三層交換設備,常規(guī)的交換機是二層交換設備。OSI七層模型是一種框架性的設計方法,建立七層模型的主要目的是為解決異種網(wǎng)絡互連時所遇到的兼容性問題,其最主要的功能就是幫助不同類型的主機實現(xiàn)數(shù)據(jù)傳輸。它的最大優(yōu)點是將服務、接口和協(xié)議這三個概念明確地區(qū)分開來,通過七個層次化的結構模型使不同的系統(tǒng)不同的網(wǎng)絡之間實現(xiàn)可靠的通訊。

TCP/IP協(xié)議是Internet最基本的協(xié)議、Internet國際互聯(lián)網(wǎng)絡的基礎,主要由網(wǎng)絡層的IP協(xié)議和傳輸層的TCP協(xié)議組成。TCP/IP 定義了電子設備如何連入因特網(wǎng),以及數(shù)據(jù)如何在它們之間傳輸?shù)臉藴?。協(xié)議采用了4層的層級結構,每一層都呼叫它的下一層所提供的協(xié)議來完成自己的需求。

ISO制定的OSI參考模型的過于龐大、復雜招致了許多批評。伴隨著互聯(lián)網(wǎng)的流行,其本身所采用的TCP/IP協(xié)議棧獲得了更為廣泛的應用和認可。在TCP/IP參考模型中,去掉了OSI參考模型中的會話層和表示層(這兩層的功能被合并到應用層實現(xiàn))。同時將OSI參考模型中的數(shù)據(jù)鏈路層和物理層合并為主機到網(wǎng)絡層。

276.TCP協(xié)議和UDP協(xié)議的比較

TCP和UDP是TCP/IP協(xié)議棧中傳輸層的兩個協(xié)議,它們使用IP路由功能把數(shù)據(jù)包發(fā)送到目的地,從而為應用程序及應用層協(xié)議(包括:HTTP、SMTP、SNMP、FTP和Telnet)提供網(wǎng)絡服務。

TCP的server和client之間通信就好比兩個人打電話,需要互相知道對方的電話號碼,然后開始對話。所以在兩者的連接過程中間需要指定端口和地址。

UDP的server和client之間的通信就像兩個人互相發(fā)信。我只需要知道對方的地址,然后就發(fā)信過去。對方是否收到我不知道,也不需要專門對口令似的來建立連接。具體區(qū)別如下:

1)TCP是面向連接的傳輸。UDP是無連接的傳輸

2)TCP有流量控制、擁塞控制,檢驗數(shù)據(jù)數(shù)據(jù)按序到達,而UDP則相反。

3)TCP的路由選擇只發(fā)生在建立連接的時候,而UDP的每個報文都要進行路由選擇

4)TCP是可靠性傳輸,他的可靠性是由超時重發(fā)機制實現(xiàn)的,而UDP則是不可靠傳輸

5)UDP因為少了很多控制信息,所以傳輸速度比TCP速度快

6)TCP適合用于傳輸大量數(shù)據(jù),UDP適合用于傳輸小量數(shù)據(jù)

277.什么是Socket編程

Socket編程的定義如下:

所謂socket通常也稱作"套接字",用于描述IP地址和端口,是一個通信鏈的句柄。應用程序通常通過"套接字"向網(wǎng)絡發(fā)出請求或者應答網(wǎng)絡請求。

我們開發(fā)的網(wǎng)絡應用程序位于應用層,TCP和UDP屬于傳輸層協(xié)議,在應用層如何使用傳輸層的服務呢?在應用層和傳輸層之間,則是使用套接字來進行分離。

套接字就像是傳輸層為應用層開的一個小口,應用程序通過這個小口向遠程發(fā)送數(shù)據(jù),或者接收遠程發(fā)來的數(shù)據(jù);而這個小口以內(nèi),也就是數(shù)據(jù)進入這個口之后,或者數(shù)據(jù)從這個口出來之前,是不知道也不需要知道的,也不會關心它如何傳輸,這屬于網(wǎng)絡其它層次的工作。

Socket實際是傳輸層供給應用層的編程接口。傳輸層則在網(wǎng)絡層的基礎上提供進程到進程問的邏輯通道,而應用層的進程則利用傳輸層向另一臺主機的某一進程通信。Socket就是應用層與傳輸層之間的橋梁

使用Socket編程可以開發(fā)客戶機和服務器應用程序,可以在本地網(wǎng)絡上進行通信,也可通過Internet在全球范圍內(nèi)通信。

生活案例1如果你想寫封郵件發(fā)給遠方的朋友,如何寫信、將信打包,屬于應用層。信怎么寫,怎么打包完全由我們做主;而當我們將信投入郵筒時,郵筒的那個口就是套接字,在進入套接字之后,就是傳輸層、網(wǎng)絡層等(郵局、公路交管或者航線等)其它層次的工作了。我們從來不會去關心信是如何從西安發(fā)往北京的,我們只知道寫好了投入郵筒就OK了。

生活案例2:可以把Socket比作是一個港口碼頭,應用程序只要將數(shù)據(jù)交給Socket,就算完成了數(shù)據(jù)的發(fā)送,具體細節(jié)由Socket來完成,細節(jié)不必了解。同理,對于接收方,應用程序也要創(chuàng)建一個碼頭,等待數(shù)據(jù)的到達,并獲取數(shù)據(jù)。

278.簡述基于TCP和UDP的Socket編程的主要步驟

Java分別為TCP和UDP 兩種通信協(xié)議提供了相應的Socket編程類,這些類存放在java.net包中。與TCP對應的是服務器的ServerSocket和客戶端的Socket,與UDP對應的是DatagramSocket。

基于TCP創(chuàng)建的套接字可以叫做流套接字,服務器端相當于一個監(jiān)聽器,用來監(jiān)聽端口。?服務器與客服端之間的通訊都是輸入輸出流來實現(xiàn)的?;赨DP的套接字就是數(shù)據(jù)報套接字,?? 兩個都要先構造好相應的數(shù)據(jù)包。

基于TCP協(xié)議的Socket編程的主要步驟

服務器端(server):

1. 構建一個ServerSocket實例,指定本地的端口。這個socket就是用來監(jiān)聽指定端口的連接請求的。

2. 重復如下幾個步驟:

a. 調用socket的accept()方法來獲得下面客戶端的連接請求。通過accept()方法返回的socket實例,建立了一個和客戶端的新連接。

b. 通過這個返回的socket實例獲取InputStream和OutputStream,可以通過這兩個stream來分別讀和寫數(shù)據(jù)。

c. 結束的時候調用socket實例的close()方法關閉socket連接。

客戶端(client):

1.構建Socket實例,通過指定的遠程服務器地址和端口來建立連接。

2.通過Socket實例包含的InputStream和OutputStream來進行數(shù)據(jù)的讀寫。

3.操作結束后調用socket實例的close方法,關閉。

UDP

服務器端(server):

1. 構造DatagramSocket實例,指定本地端口。

2. 通過DatagramSocket實例的receive方法接收DatagramPacket.DatagramPacket中間就包含了通信的內(nèi)容。

3. 通過DatagramSocket的send和receive方法來收和發(fā)DatagramPacket.

客戶端(client):

1. 構造DatagramSocket實例。

2. 通過DatagramSocket實例的send和receive方法發(fā)送DatagramPacket報文。

3. 結束后,調用DatagramSocket的close方法關閉。

異常處理:

279.下列哪種異常是檢查型異常,需要在編寫程序時聲明()
A. NullPointerException
B. ClassCastException
C. FileNotFoundException
D. IndexOutOfBoundsException
答案:C
分析:NullPointerException空指針異常
ClassCastException類型轉換異常
IndexOutOfBoundsException索引超出邊界的異常
以上這些異常都是程序在運行時發(fā)生的異常,所以不需要在編寫程序時聲明
280.Java出現(xiàn)OutOf MemoryError(OOM 錯誤)的原因有哪些?出現(xiàn)OOM錯誤后,怎么解決?

答:OutOf MemoryError這種錯誤可以細分為多種不同的錯誤,每種錯誤都有自身的原因和解決辦法,如下所示:

java.lang.OutOfMemoryError: Java heap space

錯誤原因:此OOM是由于JVM中heap的最大值不滿足需要。

解決方法:1) 調高heap的最大值,即-Xmx的值調大。2) 如果你的程序存在內(nèi)存泄漏,一味的增加heap空間也只是推遲該錯誤出現(xiàn)的時間而已,所以要檢查程序是否存在內(nèi)存泄漏。

java.lang.OutOfMemoryError: GC overhead limit exceeded

錯誤原因:此OOM是由于JVM在GC時,對象過多,導致內(nèi)存溢出,建議調整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運行較長一段時間而不是剛啟動后溢出的話,很有可能是由于運行時有類被動態(tài)加載進來,此時建議用CMS策略中的類卸載配置。如:-XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled。

java.lang.OutOfMemoryError: unable to create new native thread

錯誤原因:當JVM向OS請求創(chuàng)建一個新線程時,而OS卻由于內(nèi)存不足無法創(chuàng)建新的native線程。

解決方法:如果JVM內(nèi)存調的過大或者可利用率小于20%,可以建議將heap及perm的最大值下調,并將線程棧調小,即-Xss調小,如:-Xss128k。

java.lang.OutOfMemoryError: Requested array size exceeds VM limit

錯誤原因:此類信息表明應用程序(或者被應用程序調用的APIs)試圖分配一個大于堆大小的數(shù)組。例如,如果應用程序new一個數(shù)組對象,大小為512M,但是最大堆大小為256M,因此OutOfMemoryError會拋出,因為數(shù)組的大小超過虛擬機的限制。

解決方法:1) 首先檢查heap的-Xmx是不是設置的過小。2) 如果heap的-Xmx已經(jīng)足夠大,那么請檢查應用程序是不是存在bug,例如:應用程序可能在計算數(shù)組的大小時,存在算法錯誤,導致數(shù)組的size很大,從而導致巨大的數(shù)組被分配。

java.lang.OutOfMemoryError: request < size> bytes for < reason>. Out of swap space

錯誤原因:拋出這類錯誤,是由于從native堆中分配內(nèi)存失敗,并且堆內(nèi)存可能接近耗盡。這類錯誤可能跟應用程序沒有關系,例如下面兩種原因也會導致錯誤的發(fā)生:1) 操作系統(tǒng)配置了較小的交換區(qū)。2)系統(tǒng)的另外一個進程正在消耗所有的內(nèi)存。

解決辦法:1) 檢查os的swap是不是沒有設置或者設置的過小。2) 檢查是否有其他進程在消耗大量的內(nèi)存,從而導致當前的JVM內(nèi)存不夠分配。

注意:雖然有時< reason>部分顯示導致OOM的原因,但大多數(shù)情況下,< reason>顯示的是提示分配失敗的源模塊的名稱,所以有必要查看日志文件,如crash時的hs文件。

281.列舉常見的運行時異常

答:ClassCastException(類轉換異常)

比如 Object obj=new Object(); String s=(String)obj;?

IndexOutOfBoundsException(下標越界異常)

NullPointerException(空指針異常)

ArrayStoreException(數(shù)據(jù)存儲異常,操作數(shù)組時類型不一致)

BufferOverflowException(IO操作時出現(xiàn)的緩沖區(qū)上溢異常)

InputMismatchException(輸入類型不匹配異常)

ArithmeticException(算術異常)

注意:運行時異常都是RuntimeException子類異常。

282.下面關于 Java.lang.Exception類的說法正確的是()
A. 繼承自 Throwable
B. 不支持Serializable
C. 繼承自 AbstractSet
D. 繼承自FitelnputStream
答案:A
分析:Throwable是Exception和Error的父類,Exception雖然沒有實現(xiàn)Serializable接口,但是其父類Throwable已經(jīng)實現(xiàn)了該接口,因此Exception也支持Serializable。
283.Unsupported major.minor version 52是什么異常,怎么造成的,如何解決?

答:問題的根本原因是工程中某個jar包的版本(jar包編譯時的所用的jdk版本)高于工程build path中jdk的版本,這個是不兼容的! 編程中遇到此異常Unsupported major.minor version 52.0(根據(jù)版本號,這里可以為其他數(shù)值,52是1.8jdk jar包與 1.8以下低版本jdk不匹配),在將build path中jdk的版本調整與jar包匹配后,解決異常。

284.try{}里有一個return語句,那么緊跟在這個try后的finally{}里的code會不會被執(zhí)行,什么時候被執(zhí)行,在return前還是后?

答:會執(zhí)行,在方法返回調用者前執(zhí)行。Java允許在finally中改變返回值的做法是不好的,因為如果存在finally代碼塊,try中的return語句不會立馬返回調用者,而是記錄下返回值待finally代碼塊執(zhí)行完畢之后再向調用者返回其值,然后如果在finally中修改了返回值,這會對程序造成很大的困擾,C#中就從語法上規(guī)定不能做這樣的事。?

(也許你的答案是在return之前,但往更細地說,我的答案是在return中間執(zhí)行,請看下面程序代碼的運行結果:

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

}

執(zhí)行結果

運行結果是1,為什么呢?主函數(shù)調用子函數(shù)并得到結果的過程,好比主函數(shù)準備一個空罐子,當子函數(shù)要返回結果時,先把結果放在罐子里,然后再將程序邏輯返回到主函數(shù)。所謂返回,就是子函數(shù)說,我不運行了,你主函數(shù)繼續(xù)運行吧,這沒什么結果可言,結果是在說這話之前放進罐子里的。

285.Java 語言如何進行異常處理,關鍵字:throws、throw、try、catch、finally分別如何使用?

答:Java 通過面向對象的方法進行異常處理,把各種不同的異常進行分類,并提供了良好的接口。在Java 中,每個異常都是一個對象,它是Throwable 類或其子類的實例。當一個方法出現(xiàn)異常后便拋出一個異常對象,該對象中包含有異常信息,調用這個對象的方法可以捕獲到這個異常并進行處理。Java 的異常處理是通過5 個關鍵詞來實現(xiàn)的:try、catch、throw、throws和finally。一般情況下是用try來執(zhí)行一段程序,如果出現(xiàn)異常,系統(tǒng)會拋出(throw)一個異常,這時候你可以通過它的類型來捕捉(catch)它,或最后(finally)由缺省處理器來處理;try用來指定一塊預防所有“異?!钡某绦?;catch 子句緊跟在try塊后面,用來指定你想要捕捉的“異常”的類型;throw 語句用來明確地拋出一個“異?!保籺hrows用來標明一個成員函數(shù)可能拋出的各種“異?!保籪inally 為確保一段代碼不管發(fā)生什么“異?!倍急粓?zhí)行一段代碼;可以在一個成員函數(shù)調用的外面寫一個try語句,在這個成員函數(shù)內(nèi)部寫另一個try語句保護其他代碼。每當遇到一個try 語句,“異?!钡目蚣芫头诺綏I厦?,直到所有的try語句都完成。如果下一級的try語句沒有對某種“異?!边M行處理,棧就會展開,直到遇到有處理這種“異?!钡膖ry 語句。?

286.運行時異常與受檢異常有何異同?

答:異常表示程序運行過程中可能出現(xiàn)的非正常狀態(tài),運行時異常表示虛擬機的通常操作中可能遇到的異常,是一種常見運行錯誤,只要程序設計得沒有問題通常就不會發(fā)生。受檢異常跟程序運行的上下文環(huán)境有關,即使程序設計無誤,仍然可能因使用的問題而引發(fā)。Java編譯器要求方法必須聲明拋出可能發(fā)生的受檢異常,但是并不要求必須聲明拋出未被捕獲的運行時異常。異常和繼承一樣,是面向對象程序設計中經(jīng)常被濫用的東西,神作《Effective Java》中對異常的使用給出了以下指導原則:

不要將異常處理用于正常的控制流(設計良好的API不應該強迫它的調用者為了正常的控制流而使用異常)

對可以恢復的情況使用受檢異常,對編程錯誤使用運行時異常

避免不必要的使用受檢異常(可以通過一些狀態(tài)檢測手段來避免異常發(fā)生)

優(yōu)先使用標準的異常

每個方法拋出的異常都要有文檔

保持異常的原子性

不要在catch中忽略掉捕獲到的異常?

(異常表示程序運行過程中可能出現(xiàn)的非正常狀態(tài),運行時異常表示虛擬機的通常操作中可能遇到的異常,是一種常見運行錯誤。java編譯器要求方法必須聲明拋出可能發(fā)生的非運行時異常,但是并不要求必須聲明拋出未被捕獲的運行時異常。)

287.類ExampleA 繼承Exception,類ExampleB 繼承ExampleA

有如下代碼片斷:

try{
throw new ExampleB("b")
}catch(ExampleA e){
System.out.println("ExampleA");
}catch(Exception e){
System.out.println("Exception");
}
 }

請問執(zhí)行此段代碼的輸出是什么?

答:輸出:ExampleA。(根據(jù)里氏代換原則[能使用父類型的地方一定能使用子類型],抓取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的區(qū)別

Error類,表示僅靠程序本身無法恢復的嚴重錯誤,比如說內(nèi)存溢出、動態(tài)鏈接異常、虛擬機錯誤。應用程序不應該拋出這種類型的對象。假如出現(xiàn)這種錯誤,除了盡力使程序安全退出外,在其他方面是無能為力的。所以在進行程序設計時,應該更關注Exception類。

Exception類,由Java應用程序拋出和處理的非嚴重錯誤,比如所需文件沒有找到、零作除數(shù),數(shù)組下標越界等。它的各種不同子類分別對應不同類型異常。可分為兩類:Checked異常和Runtime異常

289.Java異常處理try-catch-finally的執(zhí)行過程

try-catch-finally程序塊的執(zhí)行流程以及執(zhí)行結果比較復雜。

基本執(zhí)行過程如下:

1)程序首先執(zhí)行可能發(fā)生異常的try語句塊。

2)如果try語句沒有出現(xiàn)異常則執(zhí)行完后跳至finally語句塊執(zhí)行;

3)如果try語句出現(xiàn)異常,則中斷執(zhí)行并根據(jù)發(fā)生的異常類型跳至相應的catch語句塊執(zhí)行處理。

4)catch語句塊可以有多個,分別捕獲不同類型的異常。

5)catch語句塊執(zhí)行完后程序會繼續(xù)執(zhí)行finally語句塊。

finally語句是可選的,如果有的話,則不管是否發(fā)生異常,finally語句都會被執(zhí)行。需要注意的是即使try和catch塊中存在return語句,finally語句也會執(zhí)行,是在執(zhí)行完finally語句后再通過return退出。

290.異常處理中throws和throw的區(qū)別

1)作用不同:

throw用于程序員自行產(chǎn)生并拋出異常;

throws用于聲明在該方法內(nèi)拋出了異常

2) 使用的位置不同:

throw位于方法體內(nèi)部,可以作為單獨語句使用;

throws必須跟在方法參數(shù)列表的后面,不能單獨使用。

3)內(nèi)容不同:

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的的相同點和區(qū)別點。

區(qū)別:

JSP是在HTML代碼里寫JAVA代碼,框架是HTML;而Servlet是在JAVA代碼中寫HTML代碼,本身是個JAVA類。

JSP使人們把顯示和邏輯分隔成為可能,這意味著兩者的開發(fā)可并行進行;而Servlet并沒有把兩者分開。

Servlet獨立地處理靜態(tài)表示邏輯與動態(tài)業(yè)務邏輯.這樣,任何文件的變動都需要對此服務程序重新編譯;JSP允許用特殊標簽直接嵌入到HTML頁面, HTML內(nèi)容與JAVA內(nèi)容也可放在單獨文件中,HTML內(nèi)容的任何變動會自動編譯裝入到服務程序.

Servlet需要在web.xml中配置,而JSP無需配置。

目前JSP主要用在視圖層,負責顯示,而Servlet主要用在控制層,負責調度

聯(lián)系:

都是Sun公司推出的動態(tài)網(wǎng)頁技術。

先有Servlet,針對Servlet缺點推出JSP。JSP是Servlet的一種特殊形式,每個JSP頁面就是一個Servlet實例——JSP頁面由系統(tǒng)翻譯成Servlet,Servlet再負責響應用戶請求。

294.請簡單描述下幾個您熟悉JavaScript庫,它們有哪些作用和特點?

JavaScript 高級程序設計(特別是對瀏覽器差異的復雜處理),通常很困難也很耗時。為了應對這些調整,許多的 JavaScript庫應運而生。這些 JavaScript 庫常被稱為 JavaScript 框架。

jQuery:

Ext JS - 可定制的 widget,用于構建富因特網(wǎng)應用程序(rich Internet applications)。

Prototype

MooTools。

YUI - Yahoo! User Interface Framework,涵蓋大量函數(shù)的大型庫,從簡單的 JavaScript 功能到完整的 internet widget。

295.簡單描述HTML,CSS,Javascript在Web開發(fā)中分別起什么作用?

1、什么是HTML(超文本標記語言 Hyper Text Markup Language),HTML 是用來描述網(wǎng)頁的一種語言。

2、CSS(層疊樣式表 Cascading Style Sheets),樣式定義如何顯示 HTML 元素,語法為:selector {property:value} (選擇符 {屬性:值})

3、JavaScript是一種腳本語言,其源代碼在發(fā)往客戶端運行之前不需經(jīng)過編譯,而是將文本格式的字符代碼發(fā)送給瀏覽器由瀏覽器解釋運行

對于一個網(wǎng)頁,HTML定義網(wǎng)頁的結構,CSS描述網(wǎng)頁的樣子,JavaScript設置一個很經(jīng)典的例子是說HTML就像 一個人的骨骼、器官,而CSS就是人的皮膚,有了這兩樣也就構成了一個植物人了,加上javascript這個植物人就可以對外界刺激做出反應,可以思 考、運動、可以給自己整容化妝(改變CSS)等等,成為一個活生生的人。

如果說HTML是肉身、CSS就是皮相、Javascript就是靈魂。沒有Javascript,HTML+CSS是植物人,沒有Javascript、CSS是個毀容的植物人。

如果說HTML是建筑師,CSS就是干裝修的,Javascript是魔術師。

296.當DOM加載完成后要執(zhí)行的函數(shù),下面哪個是正確的()
A. JQuery(expression, [context])
B. JQuery(html, [ownerDocument])
C. JQuery(callback)
答案:C
297.舉例說明JAVA中如何解析xml,不同方式有和優(yōu)缺點?

答:1. DOM(Document Object Model)

DOM是用與平臺和語言無關的方式表示XML文檔的官方W3C標準。DOM是以層次結構組織的節(jié)點或信息片斷的集合。這個層次結構允許開發(fā)人員在樹中尋找特定信息。分析該結構通常需要加載整個文檔和構造層次結構,然后才能做任何工作。由于它是基于信息層次的,因而DOM被認為是基于樹或基于對象的。

【優(yōu)點】

①允許應用程序對數(shù)據(jù)和結構做出更改。

②訪問是雙向的,可以在任何時候在樹中上下導航,獲取和操作任意部分的數(shù)據(jù)。

【缺點】

①通常需要加載整個XML文檔來構造層次結構,消耗資源大。

2. SAX(Simple API for XML)

SAX處理的優(yōu)點非常類似于流媒體的優(yōu)點。分析能夠立即開始,而不是等待所有的數(shù)據(jù)被處理。而且,由于應用程序只是在讀取數(shù)據(jù)時檢查數(shù)據(jù),因此不需要將數(shù)據(jù)存儲在內(nèi)存中。這對于大型文檔來說是個巨大的優(yōu)點。事實上,應用程序甚至不必解析整個文檔;它可以在某個條件得到滿足時停止解析。一般來說,SAX還比它的替代者DOM快許多。

選擇DOM還是選擇SAX? 對于需要自己編寫代碼來處理XML文檔的開發(fā)人員來說, 選擇DOM還是SAX解析模型是一個非常重要的設計決策。 DOM采用建立樹形結構的方式訪問XML文檔,而SAX采用的是事件模型。

DOM解析器把XML文檔轉化為一個包含其內(nèi)容的樹,并可以對樹進行遍歷。用DOM解析模型的優(yōu)點是編程容易,開發(fā)人員只需要調用建樹的指令,然后利用navigation APIs訪問所需的樹節(jié)點來完成任務??梢院苋菀椎奶砑雍托薷臉渲械脑亍H欢捎谑褂肈OM解析器的時候需要處理整個XML文檔,所以對性能和內(nèi)存的要求比較高,尤其是遇到很大的XML文件的時候。由于它的遍歷能力,DOM解析器常用于XML文檔需要頻繁的改變的服務中。

SAX解析器采用了基于事件的模型,它在解析XML文檔的時候可以觸發(fā)一系列的事件,當發(fā)現(xiàn)給定的tag的時候,它可以激活一個回調方法,告訴該方法制定的標簽已經(jīng)找到。SAX對內(nèi)存的要求通常會比較低,因為它讓開發(fā)人員自己來決定所要處理的tag.特別是當開發(fā)人員只需要處理文檔中所包含的部分數(shù)據(jù)時,SAX這種擴展能力得到了更好的體現(xiàn)。但用SAX解析器的時候編碼工作會比較困難,而且很難同時訪問同一個文檔中的多處不同數(shù)據(jù)。

【優(yōu)勢】

①不需要等待所有數(shù)據(jù)都被處理,分析就能立即開始。

②只在讀取數(shù)據(jù)時檢查數(shù)據(jù),不需要保存在內(nèi)存中。

③可以在某個條件得到滿足時停止解析,不必解析整個文檔。

④效率和性能較高,能解析大于系統(tǒng)內(nèi)存的文檔。

【缺點】

①需要應用程序自己負責TAG的處理邏輯(例如維護父/子關系等),文檔越復雜程序就越復雜。

②單向導航,無法定位文檔層次,很難同時訪問同一文檔的不同部分數(shù)據(jù),不支持XPath。

3. JDOM(Java-based Document Object Model)

JDOM的目的是成為Java特定文檔模型,它簡化與XML的交互并且比使用DOM實現(xiàn)更快。由于是第一個Java特定模型,JDOM一直得到大力推廣和促進。正在考慮通過“Java規(guī)范請求JSR-102”將它最終用作“Java標準擴展”。從2000年初就已經(jīng)開始了JDOM開發(fā)。

JDOM與DOM主要有兩方面不同。首先,JDOM僅使用具體類而不使用接口。這在某些方面簡化了API,但是也限制了靈活性。第二,API大量使用了Collections類,簡化了那些已經(jīng)熟悉這些類的Java開發(fā)者的使用。

JDOM文檔聲明其目的是“使用20%(或更少)的精力解決80%(或更多)Java/XML問題”(根據(jù)學習曲線假定為20%)。JDOM對于大多數(shù)Java/XML應用程序來說當然是有用的,并且大多數(shù)開發(fā)者發(fā)現(xiàn)API比DOM容易理解得多。JDOM還包括對程序行為的相當廣泛檢查以防止用戶做任何在XML中無意義的事。然而,它仍需要您充分理解XML以便做一些超出基本的工作(或者甚至理解某些情況下的錯誤)。這也許是比學習DOM或JDOM接口都更有意義的工作。

JDOM自身不包含解析器。它通常使用SAX2解析器來解析和驗證輸入XML文檔(盡管它還可以將以前構造的DOM表示作為輸入)。它包含一些轉換器以將JDOM表示輸出成SAX2事件流、DOM模型或XML文本文檔。JDOM是在Apache許可證變體下發(fā)布的開放源碼。

【優(yōu)點】

①使用具體類而不是接口,簡化了DOM的API。

②大量使用了Java集合類,方便了Java開發(fā)人員。

【缺點】

①沒有較好的靈活性。

②性能較差。

4. DOM4J(Document Object Model for Java)

雖然DOM4J代表了完全獨立的開發(fā)結果,但最初,它是JDOM的一種智能分支。它合并了許多超出基本XML文檔表示的功能,包括集成的XPath支持、XML Schema支持以及用于大文檔或流化文檔的基于事件的處理。它還提供了構建文檔表示的選項,它通過DOM4J API和標準DOM接口具有并行訪問功能。從2000下半年開始,它就一直處于開發(fā)之中。

為支持所有這些功能,DOM4J使用接口和抽象基本類方法。DOM4J大量使用了API中的Collections類,但是在許多情況下,它還提供一些替代方法以允許更好的性能或更直接的編碼方法。直接好處是,雖然DOM4J付出了更復雜的API的代價,但是它提供了比JDOM大得多的靈活性。

在添加靈活性、XPath集成和對大文檔處理的目標時,DOM4J的目標與JDOM是一樣的:針對Java開發(fā)者的易用性和直觀操作。它還致力于成為比JDOM更完整的解決方案,實現(xiàn)在本質上處理所有Java/XML問題的目標。在完成該目標時,它比JDOM更少強調防止不正確的應用程序行為。

DOM4J是一個非常非常優(yōu)秀的Java XML API,具有性能優(yōu)異、功能強大和極端易用使用的特點,同時它也是一個開放源代碼的軟件。如今你可以看到越來越多的Java軟件都在使用DOM4J來讀寫XML,特別值得一提的是連Sun的JAXM也在用DOM4J.

【優(yōu)點】

①大量使用了Java集合類,方便Java開發(fā)人員,同時提供一些提高性能的替代方法。

②支持XPath。

③有很好的性能。

【缺點】

①大量使用了接口,API較為復雜。

二、比較

1. DOM4J性能最好,連Sun的JAXM也在用DOM4J。目前許多開源項目中大量采用DOM4J,例如大名鼎鼎的Hibernate也用DOM4J來讀取XML配置文件。如果不考慮可移植性,那就采用DOM4J.

2. JDOM和DOM在性能測試時表現(xiàn)不佳,在測試10M文檔時內(nèi)存溢出,但可移植。在小文檔情況下還值得考慮使用DOM和JDOM.雖然JDOM的開發(fā)者已經(jīng)說明他們期望在正式發(fā)行版前專注性能問題,但是從性能觀點來看,它確實沒有值得推薦之處。另外,DOM仍是一個非常好的選擇。DOM實現(xiàn)廣泛應用于多種編程語言。它還是許多其它與XML相關的標準的基礎,因為它正式獲得W3C推薦(與基于非標準的Java模型相對),所以在某些類型的項目中可能也需要它(如在JavaScript中使用DOM)。

3. SAX表現(xiàn)較好,這要依賴于它特定的解析方式-事件驅動。一個SAX檢測即將到來的XML流,但并沒有載入到內(nèi)存(當然當XML流被讀入時,會有部分文檔暫時隱藏在內(nèi)存中)。

我的看法:如果XML文檔較大且不考慮移植性問題建議采用DOM4J;如果XML文檔較小則建議采用JDOM;如果需要及時處理而不需要保存數(shù)據(jù)則考慮SAX。但無論如何,還是那句話:適合自己的才是最好的,如果時間允許,建議大家講這四種方法都嘗試一遍然后選擇一種適合自己的即可。

298.char型變量中能不能存儲一個中文漢字?

答:1.java采用unicode編碼,2個字節(jié)(16位)來表示一個字符, 無論是漢字還是數(shù)字,字母,或其他語言都可以存儲。

2.char 在java中是2個字節(jié),所以可以存儲中文

299.一個類可以實現(xiàn)多個接口,但只能繼承一個抽象類。

下面接著再說說兩者在應用上的區(qū)別:

接口更多的是在系統(tǒng)架構設計方法發(fā)揮作用,主要用于定義模塊之間的通信契約。而抽象類在代碼實現(xiàn)方面發(fā)揮作用,可以實現(xiàn)代碼的重用,例如,模板方法設計模式是抽象類的一個典型應用,假設某個項目的所有Servlet類都要用相同的方式進行權限判斷、記錄訪問日志和處理異常,那么就可以定義一個抽象的基類,讓所有的Servlet都繼承這個抽象基類,在抽象基類的service方法中完成權限判斷、記錄訪問日志和處理異常的代碼,在各個子類中只是完成各自的業(yè)務邏輯代碼,偽代碼如下:

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,顯得既專業(yè),又嚴謹,因為它是專門給子類用的
}

public class MyServlet1 extendsBaseServlet
{
protected voiddoService(HttpServletRequest request, HttpServletResponse response) throwsIOExcetion,ServletException
        {
               本Servlet只處理的具體業(yè)務邏輯代碼
        }

}

父類方法中間的某段代碼不確定,留給子類干,就用模板方法設計模式。

備注:這道題的思路是先從總體解釋抽象類和接口的基本概念,然后再比較兩者的語法細節(jié),最后再說兩者的應用區(qū)別。比較兩者語法細節(jié)區(qū)別的條理是:先從一個類中的構造方法、普通成員變量和方法(包括抽象方法),靜態(tài)變量和方法,繼承性等6個方面逐一去比較回答,接著從第三者繼承的角度的回答,特別是最后用了一個典型的例子來展現(xiàn)自己深厚的技術功底。

300.比較一下Java 和JavaSciprt

答:JavaScript 與Java是兩個公司開發(fā)的不同的兩個產(chǎn)品。Java 是原Sun 公司推出的面向對象的程序設計語言,特別適合于互聯(lián)網(wǎng)應用程序開發(fā);而JavaScript是Netscape公司的產(chǎn)品,為了擴展Netscape瀏覽器的功能而開發(fā)的一種可以嵌入Web頁面中運行的基于對象和事件驅動的解釋性語言,它的前身是LiveScript;而Java 的前身是Oak語言。

下面對兩種語言間的異同作如下比較:

1)基于對象和面向對象:Java是一種真正的面向對象的語言,即使是開發(fā)簡單的程序,必須設計對象;JavaScript是種腳本語言,它可以用來制作與網(wǎng)絡無關的,與用戶交互作用的復雜軟件。它是一種基于對象(Object-Based)和事件驅動(Event-Driven)的編程語言。因而它本身提供了非常豐富的內(nèi)部對象供設計人員使用;

2)解釋和編譯:Java 的源代碼在執(zhí)行之前,必須經(jīng)過編譯;JavaScript 是一種解釋性編程語言,其源代碼不需經(jīng)過編譯,由瀏覽器解釋執(zhí)行;

3)強類型變量和類型弱變量:Java采用強類型變量檢查,即所有變量在編譯之前必須作聲明;JavaScript中變量聲明,采用其弱類型。即變量在使用前不需作聲明,而是解釋器在運行時檢查其數(shù)據(jù)類型;

4)代碼格式不一樣。

補充:上面列出的四點是原來所謂的標準答案中給出的。其實Java和JavaScript最重要的區(qū)別是一個是靜態(tài)語言,一個是動態(tài)語言。目前的編程語言的發(fā)展趨勢是函數(shù)式語言和動態(tài)語言。在Java中類(class)是一等公民,而JavaScript中函數(shù)(function)是一等公民。對于這種問題,在面試時還是用自己的語言回答會更加靠譜。?

301.什么時候用assert?

答:assertion(斷言)在軟件開發(fā)中是一種常用的調試方式,很多開發(fā)語言中都支持這種機制。一般來說,assertion用于保證程序最基本、關鍵的正確性。assertion檢查通常在開發(fā)和測試時開啟。為了提高性能,在軟件發(fā)布后, assertion檢查通常是關閉的。在實現(xiàn)中,斷言是一個包含布爾表達式的語句,在執(zhí)行這個語句時假定該表達式為true;如果表達式計算為false,那么系統(tǒng)會報告一個AssertionError。

斷言用于調試目的:

assert(a > 0); // throws an AssertionError if a <= 0

斷言可以有兩種形式:

assert Expression1;

assert Expression1 : Expression2 ;

Expression1 應該總是產(chǎn)生一個布爾值。

Expression2 可以是得出一個值的任意表達式;這個值用于生成顯示更多調試信息的字符串消息。

斷言在默認情況下是禁用的,要在編譯時啟用斷言,需使用source 1.4 標記:

javac -source 1.4 Test.java

要在運行時啟用斷言,可使用-enableassertions 或者-ea 標記。

要在運行時選擇禁用斷言,可使用-da 或者-disableassertions 標記。

要在系統(tǒng)類中啟用斷言,可使用-esa 或者-dsa 標記。還可以在包的基礎上啟用或者禁用斷言??梢栽陬A計正常情況下不會到達的任何位置上放置斷言。斷言可以用于驗證傳遞給私有方法的參數(shù)。不過,斷言不應該用于驗證傳遞給公有方法的參數(shù),因為不管是否啟用了斷言,公有方法都必須檢查其參數(shù)。不過,既可以在公有方法中,也可以在非公有方法中利用斷言測試后置條件。另外,斷言不應該以任何方式改變程序的狀態(tài)。?

302.UML是什么?UML中有哪些圖?

答:UML是統(tǒng)一建模語言(Unified Modeling Language)的縮寫,它發(fā)表于1997年,綜合了當時已經(jīng)存在的面向對象的建模語言、方法和過程,是一個支持模型化和軟件系統(tǒng)開發(fā)的圖形化語言,為軟件開發(fā)的所有階段提供模型化和可視化支持。使用UML可以幫助溝通與交流,輔助應用設計和文檔的生成,還能夠闡釋系統(tǒng)的結構和行為。UML定義了多種圖形化的符號來描述軟件系統(tǒng)部分或全部的靜態(tài)結構和動態(tài)結構,包括:用例圖(use case diagram)、類圖(class diagram)、時序圖(sequence diagram)、協(xié)作圖(collaboration diagram)、狀態(tài)圖(statechart diagram)、活動圖(activity diagram)、構件圖(component diagram)、部署圖(deployment diagram)等。在這些圖形化符號中,有三種圖最為重要,分別是:用例圖(用來捕獲需求,描述系統(tǒng)的功能,通過該圖可以迅速的了解系統(tǒng)的功能模塊及其關系)、類圖(描述類以及類與類之間的關系,通過該圖可以快速了解系統(tǒng))、時序圖(描述執(zhí)行特定任務時對象之間的交互關系以及執(zhí)行順序,通過該圖可以了解對象能接收的消息也就是說對象能夠向外界提供的服務)。

用例圖:

303.XML 文檔定義有幾種形式?它們之間有何本質區(qū)別?解析XML 文檔有哪幾種方式?

答: XML文檔定義分為DTD和Schema兩種形式;其本質區(qū)別在于Schema本身也是一個XML文件,可以被XML解析器解析。對XML的解析主要有DOM(文檔對象模型)、SAX、StAX(JDK 1.6中引入的新的解析XML的方式,Streaming API for XML) 等,其中DOM處理大型文件時其性能下降的非常厲害,這個問題是由DOM 的樹結構所造成的,這種結構占用的內(nèi)存較多,而且DOM 必須在解析文件之前把整個文檔裝入內(nèi)存,適合對XML 的隨機訪問(典型的用空間換取時間的策略);SAX是事件驅動型的XML解析方式,它順序讀取XML文件,不需要一次全部裝載整個文件。當遇到像文件開頭,文檔結束,或者標簽開頭與標簽結束時,它會觸發(fā)一個事件,用戶通過在其回調事件中寫入處理代碼來處理XML文件,適合對XML 的順序訪問;如其名稱所暗示的那樣,StAX把重點放在流上。實際上,StAX與其他方法的區(qū)別就在于應用程序能夠把XML作為一個事件流來處理。將XML作為一組事件來處理的想法并不新穎(事實上 SAX 已經(jīng)提出來了),但不同之處在于StAX允許應用程序代碼把這些事件逐個拉出來,而不用提供在解析器方便時從解析器中接收事件的處理程序。?

304.你在項目中哪些地方用到了XML?

答: XML的主要作用有兩個方面:數(shù)據(jù)交換(曾經(jīng)被稱為業(yè)界數(shù)據(jù)交換的事實標準,現(xiàn)在此項功能在很多時候都被JSON取代)和信息配置。在做數(shù)據(jù)交換時,XML將數(shù)據(jù)用標簽組裝成起來,然后壓縮打包加密后通過網(wǎng)絡傳送給接收者,接收解密與解壓縮后再從XML文件中還原相關信息進行處理。目前很多軟件都使用XML來存儲配置信息,很多項目中我們通常也會將作為配置的硬代碼(hard code)寫在XML文件中,Java的很多框架也是這么做的。?

305.用JavaScript實現(xiàn)用正則表達式驗證,某個字符串是合法的6位數(shù)字的郵編的函數(shù)
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函數(shù),設置其async屬性來表明是異步還是同步,如下:

$.ajax({
async:true//表示異步,false表示同步
})

308.說出3條以上firefox和IE的瀏覽器兼容問題?

答案:兼容firefox的 outerHTML,F(xiàn)F中沒有outerHtml的方法

IE下,可以使用()或[]獲取集合類對象;Firefox下,只能使用[]獲取集合類對象.解決方法:統(tǒng)一使用[]獲取集合類對象.

IE下,可以使用獲取常規(guī)屬性的方法來獲取自定義屬性,也可以使用getAttribute()獲取自定義屬性;Firefox下,只能使用getAttribute()獲取自定義屬性.解決方法:統(tǒng)一通過getAttribute()獲取自定義屬性

309.請用Jquery語言寫出ajax請求或者post請求代碼
$.post(“show”,{uname=”張三”,pwd=”123”},function(data){
  alert(data)
})
310.body中的onload ()函數(shù)和jQuery中document.ready()有什么區(qū)別?

答案:ready 事件的觸發(fā),表示文檔結構已經(jīng)加載完成(不包含圖片等非文字媒體文件)

onload 事件的觸發(fā),表示頁面包含圖片等文件在內(nèi)的所有元素都加載完成。

311.jQuery中有哪幾種類型的選擇器?

答案:

基本選擇器

層次選擇器

基本過濾選擇器

內(nèi)容過濾選擇器

可見性過濾選擇器

屬性過濾選擇器

子元素過濾選擇器

表單選擇器

表單過濾選擇器

312.EasyUI中datagrid刷新當前數(shù)據(jù)的方法?

答案:使用reload()即可

313.分別寫出一個div居中和其中的內(nèi)容居中的css屬性設置

Div居中:

margin:auto 0px;

內(nèi)容居中:

text-align:center;

314.概述一下session與cookie的區(qū)別

答案:

存儲角度:

Session是服務器端的數(shù)據(jù)存儲技術,cookie是客戶端的數(shù)據(jù)存儲技術

解決問題角度:

Session解決的是一個用戶不同請求的數(shù)據(jù)共享問題,cookie解決的是不同請求的請求數(shù)據(jù)的共享問題

生命周期角度:

Session的id是依賴于cookie來進行存儲的,瀏覽器關閉id就會失效

Cookie可以單獨的設置其在瀏覽器的存儲時間。

315.JavaScript 中 null和 undefined 是否有區(qū)別?有哪些區(qū)別?

答案:

賦值角度說明:

null 表示此處沒有值,undefined表示此處定義了但是沒有賦值

從數(shù)據(jù)轉換角度:

Null在做數(shù)值轉換時會被轉換為0,undefined會被轉換為NaN

316.Servlet中的doPost和doGet方法有什么區(qū)別?它們在傳遞和獲取參數(shù)上有什么區(qū)別?

答案:

區(qū)別:doPost用來處理post請求,doGet用來處理get請求,獲取參數(shù):獲取的參數(shù)是相同的都是HttpServletRequest \HttpServletResponse

317.請寫出一段jQuery代碼,實現(xiàn)把當前頁面中所有的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()’的區(qū)別

eq返回的是一個jquery對象 get返回的是一個html對象

320.如何給weblogic定內(nèi)存的大小?

在啟動Weblogic的腳本中(位于所在Domian對應服務器目錄下的startServerName),增加set MEM_ARGS=-Xms32m -Xmx200m,可以調整最小內(nèi)存為32M,最大200M

321.TCP為何采用三次握手來建立連接,若釆用二次握手可以嗎,請說明理由?

三次握手是為了防止已失效的連接請求再次傳送到服務器端。 二次握手不可行,因為:如果由于網(wǎng)絡不穩(wěn)定,雖然客戶端以前發(fā)送的連接請求以到達服務方,但服務方的同意連接的應答未能到達客戶端。則客戶方要重新發(fā)送連接請求,若采用二次握手,服務方收到重傳的請求連接后,會以為是新的請求,就會發(fā)送同意連接報文,并新開進程提供服務,這樣會造成服務方資源的無謂浪費

322.以下HTTP相應狀態(tài)碼的含義描述正確的是()
A. 200ok表示請求成功
B. 400不良請求表示服務器未發(fā)現(xiàn)與請求URL匹配內(nèi)容
C. 404未發(fā)現(xiàn)表示由于語法錯誤兒導致服務器無法理解請求信息
D. 500內(nèi)部服務器錯誤,無法處理請求
答案:D
分析:
A 200ok 表示的意思是一切正常。一般用于相應GET和POST請求。這個狀態(tài)碼對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請求。這個狀態(tài)碼對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九大內(nèi)置對象

答案:1、request對象

request 對象是 javax.servlet.httpServletRequest類型的對象。 該對象代表了客戶端的請求信息,主要用于接受通過HTTP協(xié)議傳送到服務器的數(shù)據(jù)。(包括頭信息、系統(tǒng)信息、請求方式以及請求參數(shù)等)。request對象的作用域為一次請求。

2、response對象

response 代表的是對客戶端的響應,主要是將JSP容器處理過的對象傳回到客戶端。response對象也具有作用域,它只在JSP頁面內(nèi)有效。

3、session對象

session 對象是由服務器自動創(chuàng)建的與用戶請求相關的對象。服務器為每個用戶都生成一個session對象,用于保存該用戶的信息,跟蹤用戶的操作狀態(tài)。session對象內(nèi)部使用Map類來保存數(shù)據(jù),因此保存數(shù)據(jù)的格式為 “Key/value”。 session對象的value可以使復雜的對象類型,而不僅僅局限于字符串類型。

4、application對象

?application 對象可將信息保存在服務器中,直到服務器關閉,否則application對象中保存的信息會在整個應用中都有效。與session對象相比,application對象生命周期更長,類似于系統(tǒng)的“全局變量”。

5、out 對象

out 對象用于在Web瀏覽器內(nèi)輸出信息,并且管理應用服務器上的輸出緩沖區(qū)。在使用 out 對象輸出數(shù)據(jù)時,可以對數(shù)據(jù)緩沖區(qū)進行操作,及時清除緩沖區(qū)中的殘余數(shù)據(jù),為其他的輸出讓出緩沖空間。待數(shù)據(jù)輸出完畢后,要及時關閉輸出流。

6、pageContext 對象

pageContext 對象的作用是取得任何范圍的參數(shù),通過它可以獲取 JSP頁面的out、request、reponse、session、application 等對象。pageContext對象的創(chuàng)建和初始化都是由容器來完成的,在JSP頁面中可以直接使用 pageContext對象。

7、config 對象

config 對象的主要作用是取得服務器的配置信息。通過 pageConext對象的 getServletConfig() 方法可以獲取一個config對象。當一個Servlet 初始化時,容器把某些信息通過 config對象傳遞給這個 Servlet。 開發(fā)者可以在web.xml 文件中為應用程序環(huán)境中的Servlet程序和JSP頁面提供初始化參數(shù)。

8、page 對象

page 對象代表JSP本身,只有在JSP頁面內(nèi)才是合法的。 page隱含對象本質上包含當前 Servlet接口引用的變量,類似于Java編程中的 this 指針。

9、exception 對象

exception 對象的作用是顯示異常信息,只有在包含 isErrorPage="true" 的頁面中才可以被使用,在一般的JSP頁面中使用該對象將無法編譯JSP文件。excepation對象和Java的所有對象一樣,都具有系統(tǒng)提供的繼承結構。exception 對象幾乎定義了所有異常情況。在Java程序中,可以使用try/catch關鍵字來處理異常情況; 如果在JSP頁面中出現(xiàn)沒有捕獲到的異常,就會生成 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,如何定義含有數(shù)值1至8的數(shù)組?

答: var arr=[1,2,3,4,5,6,7,8]

329.以下JavaScipt語句會產(chǎn)生運行錯誤的是_()
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 超文本標記語言,是一種用來制作“網(wǎng)頁”的簡單標記語言;用HTML編寫的超文本文檔稱為HTML文檔,HTML文檔的擴展名是html或者htm

版本變化:

HTML1.0——在1993年6月作為IETF工作草案發(fā)布(并非標準)

HTML 2.0——1995年11月作為RFC 1866發(fā)布

HTML 3.2——1997年1月14日,W3C推薦標準

HTML 4.0——1997年12月18日,W3C推薦標準

HTML 4.01(微小改進)——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到頁面的某個位置,適用于頁面內(nèi)容較多,超過一屏的場合 。分為頁面內(nèi)的錨鏈接和頁面間的錨鏈接 。

例如:1F2F

跳轉到2F標記位置

說明:

1.在標記位置利用a標簽的name屬性設置標記。

2.在導航位置通過a標簽的href屬性用#開頭加name屬性值即可跳轉錨點位置。

333.HTML字符實體的作用及其常用字符實體

有些字符,比如說“<”字符,在HTML中有特殊的含義,因此不能在文本中使用。想要在HTML中顯示一個小于號“<”,需要用到字符實體:<或者<

字符實體擁有三個部分:一個and符號(&),一個實體名或者一個實體號,最后是一個分號(;)

常用字符實體:

顯示結果 描述 實體 實體號
空格    
< 小于 < <
> 大于 > &#
& and符號 & &
' 單引號 ' (IE不支持) '
" 引號 " "
英鎊 £ £
人民幣元 ¥ ¥
§ 章節(jié) ¥ ¥
? 版權 © ©
334.HTML表單的作用和常用表單項類型

表單的作用:

利用表單可以收集客戶端提交的有關信息。

常用表單項類型:

input標簽
type屬性
功能 input標簽
type屬性
功能
text 單行本框 reset 重置按鈕
password 密碼框 submit 提交按鈕
radio 單選按鈕 textarea 文本域
checkbox 復選框 select 下拉框
button 普通按鈕 hidden 隱藏域

335.表格、框架、div三種HTML布局方式的特點

優(yōu)點 缺點 應用場合
表格 方便排列有規(guī)律、結構均勻的內(nèi)容或數(shù)據(jù) 產(chǎn)生垃圾代碼、影響頁面下載時間、靈活性不大難于修改 內(nèi)容或數(shù)據(jù)整齊的頁面
框架 支持滾動條、方便導航 節(jié)省頁面下載時間等 兼容性不好,保存時不方便、應用范圍有限 小型商業(yè)網(wǎng)站、論壇后臺管理
Div 代碼精簡、提高頁面下載速度、表現(xiàn)和內(nèi)容分離 比較靈活、難于控制 復雜的不規(guī)則頁面、業(yè)務種類較多的大型商業(yè)網(wǎng)站

336.form中input設置為readonly和disabled的區(qū)別

readonly disabled
有效對象 .只針對type為text/password有效 對所有表單元素有效
表單提交 當表單元素設置readonly后,表單提交能將該表單元素的值傳遞出去。 當表單元素設置disabled后,表單提交不能將該表單元素的值傳遞出去。

337.CSS的定義和作用

CSS的定義:CSS是Cascading Style Sheets(層疊樣式表)的簡稱。

CSS是一系列格式規(guī)則,它們控制網(wǎng)頁內(nèi)容的外觀。CSS簡單來說就是用來美化網(wǎng)頁用的。

CSS的具體作用包括:

使網(wǎng)頁豐富多彩,易于控制。

頁面的精確控制,實現(xiàn)精美、復雜頁面 。

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.引入樣式的三種方式及其優(yōu)先級別

三種引用方式:

1. 外部樣式表(存放.css文件中)

不需要style標簽

< link rel=”stylesheet” href=”引用文件地址” />

2. 嵌入式樣式表

< style type=“text/css”>

p{color:red;}

< /style>

3.內(nèi)聯(lián)樣式

標簽屬性名為style

< p style=“color:red;”>< /p>

優(yōu)先級級別:內(nèi)聯(lián)定義最高、內(nèi)部CSS次之、外部CSS優(yōu)先級最低。。

340.盒子模型

盒子模型類似于生活中的盒子,具有4個屬性,外邊距,內(nèi)邊距,邊框,內(nèi)容。

外邊距:margin,用于設置元素和其他元素之間的距離。

內(nèi)邊距:padding,用于設置元素內(nèi)容和邊框之間的距離。

邊框:border,用于設置元素邊框粗細,顏色,線型。

內(nèi)容:width,height,用于設置元素內(nèi)容顯示的大小。

例如:

<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++等,它是一種解釋性的程序語言,它的源代碼不需要經(jīng)過編譯,而直接在瀏覽器中運行時被解釋。

基于對象:?JavaScript是一種基于對象的語言。這意味著它能運用自己已經(jīng)創(chuàng)建的對象。因此,許多功能可以來自于腳本環(huán)境中對象的方法與腳本的相互作用。

事件驅動: JavaScript可以直接對用戶或客戶輸入做出響應,無須經(jīng)過Web服務程序。它對用戶的響應,是以事件驅動的方式進行的。所謂事件驅動,就是指在主頁中執(zhí)行了某種操作所產(chǎn)生的動作,此動作稱為“事件”。比如按下鼠標、移動窗口、選擇菜單等都可以視為事件。當事件發(fā)生后,可能會引起相應的事件響應。

跨平臺:JavaScript依賴于瀏覽器本身,與操作環(huán)境無關,只要能運行瀏覽器的計算機,并支持JavaScript的瀏覽器就可正確執(zhí)行。

342.JavaScript常用數(shù)據(jù)類型有哪些

1、數(shù)值型(Number):整數(shù)和浮點數(shù)統(tǒng)稱為數(shù)值。例如85或3.1415926等。

2、字符串型(String):由0個,1個或多個字符組成的序列。在JavaScript中,用雙引號或單引號括起來表示,如“您好”、‘學習JavaScript’等。 不區(qū)分單引號、雙引號。

3、邏輯(布爾)型(Boolean):用true或false來表示。

4、空(null)值(Null):表示沒有值,用于定義空的或不存在的引用。

要注意,空值不等同于空字符串""或0。

5、未定義(Undefined)值:它也是一個保留字。表示變量雖然已經(jīng)聲明,但卻沒有賦值。

除了以上五種基本的數(shù)據(jù)類型之外,JavaScript還支持復合數(shù)據(jù)類型,包括對象和數(shù)組兩種。

343.html語法中哪條命令用于使一行文本折行,而不是插入一個新的段落? (B)

A. < TD>
B. < BR>
C. < P>
D. < H1>
分析:
A < td>定義標準表格
C < p>表示文本一個段落
D < h1>表示對文本標題進行強調的一種標簽

344.Ajax的優(yōu)點和缺點

優(yōu)點:減輕服務器的負擔,按需取數(shù)據(jù),最大程度的減少冗余請求,局部刷新頁面,減少用戶心理和實際的等待時間,帶來更好的用戶體驗,基于xml標準化,并被廣泛支持,不需安裝插件等,進一步促進頁面和數(shù)據(jù)的分離

缺點: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()方法之間的區(qū)別是什么?

JQuery.ajax()是對原生的javaScript的ajax的封裝,簡化了ajax的步驟,用戶可用JQuery.ajax()發(fā)送get或者post方式請求,Jquery.get()是對ajax的get方式的封裝,只能發(fā)送get方式的請求。

347.Jquery里的緩存問題如何解決?例如($.ajax()以及$.get())

$.ajax()請求時候加上cache:false的參數(shù),如:

$.ajax({
    type : "get",
    url : "XX",
    dataType : "json",
    cache:false,
    success : function(json) {
    }
});

$.get()請求時候加上時間,如:

$.get("url","data"+new Date(),function(data){});

348.Javascript是面向對象的,怎么體現(xiàn)Javascript的繼承關系?

Javascript里面沒有像java那樣的繼承,javascript中的繼承機制僅僅是靠模擬的,可以使用prototype原型來實現(xiàn)

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獲取(獲取的是數(shù)組對象)

var varname = document.getElementsByName("sex");

//1.3 -- 元素獲取(獲取的是數(shù)組對象)

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:下一個節(jié)點 previousSibling:上一個節(jié)點

351.Servlet API中forward() 與redirect()的區(qū)別?

答:為實現(xiàn)程序的模塊化,就需要保證在不同的Servlet之間可以相互跳轉,而Servlet中主要有兩種實現(xiàn)跳轉的方式:FORWARD方式與redirect方式。?

Forward() : 是服務器內(nèi)部的重定向,服務器直接訪問目標地址的URL,把那個URL的響應內(nèi)容讀取出來,而客戶端并不知道,因此在客戶端瀏覽器的地址欄里不會顯示跳轉后的地址,還是原來的地址。由于在整個定向的過程中用的是同一個Request,因此FORWARD會將Request的信息帶到被定向的JSP或Servlet中使用。

Redirect():則是客戶端的重定向,是完全的跳轉,即客戶端瀏覽器會獲取跳轉后的地址,然后重新發(fā)送請求,因此瀏覽器中會顯示跳轉后的地址。同時,由于這種方式比FORWARD方式多了一次網(wǎng)絡請求,因此其效率低于FORWARD方式,需要注意到的是,客戶端的重定向可以通過設置特定的HTTP 頭或寫JavaScript腳本來實現(xiàn)。

鑒于以上的區(qū)別,一般當FORWARD方式可以滿足需求時,盡可能的使用FORWARD方式。但在有些情況下,例如,需要跳轉到一個其他服務器上的資源時,則必須使用redirect 方式。

352.Session域和request域什么區(qū)別?

作用域:存放數(shù)據(jù),獲取數(shù)據(jù)(傳遞數(shù)據(jù))

有效的作用域:生命周期,作用范圍

httpServeltRequest:

生命周期:一次請求之間

作用范圍:所有被請求轉發(fā)過的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位數(shù)字的正則表達式

^[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中動態(tài)INCLUDE與靜態(tài)INCLUDE的區(qū)別?

動態(tài)導入

1、會將多個jsp頁面分別再編寫成java文件,編譯成class文件

2、jsp文件中允許有相同的變量名,每個頁面互不影響

3、當java代碼比較多優(yōu)先選用動態(tài)導入

4、效率相對較低,耦合性低

靜態(tài)導入

1、會將多個jsp頁面合成一個jsp頁面,再編寫成java文件,編譯成class文件

2、jsp文件中不允許有相同的變量名

3、當java代碼比較少或者沒有java代碼是優(yōu)先選用靜態(tài)導入

4、效率相對較高,耦合性高

359.列舉JSP的內(nèi)置對象及方法

request表示HttpServletRequest對象。它包含了有關瀏覽器請求的信息,并且提供了幾個用于獲取cookie,?header,?和session數(shù)據(jù)的有用的方法。?

response表示HttpServletResponse對象,并提供了幾個用于設置送回?瀏覽器的響應的方法(如cookies,頭信息等)?

out對象是javax.jsp.JspWriter的一個實例,提供了幾個方法使你能用于向瀏覽器回送輸出結果

pageContext表示一個javax.servlejt.sp.PageContext對象。它是用于方便存取各種范圍的名字空間、servlet相關的對象的API,并且包裝了通用的servlet相關功能的方法。?

session表示一個請求的javax.servlet.http.HttpSession對象。Session可以存貯用戶的狀態(tài)信息

applicaton?表示一個javax.servle.ServletContext對象。這有助于查找有關servlet引擎和servlet環(huán)境的信息?

config表示一個javax.servlet.ServletConfig對象。該對象用于存取servlet實例的初始化參數(shù)。?

page表示從該頁面產(chǎn)生的一個servlet實例

Exception異常

360.列舉jsp的四大作用域

page、request、session、application

361.html和xhtml的區(qū)別是什么?

HTML與XHTML之間的差別,粗略可以分為兩大類比較:一個是功能上的差別,另外是書寫習慣的差別。關于功能上的差別,主要是XHTML可兼容各大瀏覽器、手機以及PDA,并且瀏覽器也能快速正確地編譯網(wǎng)頁。

因為XHTML的語法較為嚴謹, 所以如果你是習慣松散結構的HTML編寫者,那需要特別注意XHTML的規(guī)則。但也不必太過擔心,因為XHTML的規(guī)則并不太難。下面列出了幾條容易犯的錯誤,供大家引用。

1:所有標簽都必須小寫

在XHTML中,所有的標簽都必須小寫,不能大小寫穿插其中,也不能全部都是大寫。看一個例子。

錯誤:< Head>< /Head>< Body>< /Body>

正確:< head>< /head>< body>< /body>

2:標簽必須成雙成對

像是< p>...< /p>、< a>...< /a>、< div>...< /div>標簽等,當出現(xiàn)一個標簽時,必須要有對應的結束標簽,缺一不可,就像在任何程序語言中的括號一樣。

錯誤:大家好< p>我是muki

正確:< p>大家好< /p>< p>我是muki< /p>

3:標簽順序必須正確

標簽由外到內(nèi),一層層包覆著,所以假設你先寫div后寫h1,結尾就要先寫h1后寫div。只要記住一個原則“先進后出”,先彈出的標簽要后結尾。

錯誤:< div>< h1>大家好< /div>< /h1>

正確:< div>< h1>大家好< /h1>< /div>

4:所有屬性都必須使用雙引號

在XHTML 1.0中規(guī)定連單引號也不能使用,所以全程都得用雙引號。

錯誤:< div style=font-size:11px>hello< /div>

正確:< div style="font-size:11px">hello< /div

5:不允許使用target="_blank"

從XHTML 1.1開始全面禁止target屬性,如果想要有開新窗口的功能,就必須改寫為rel="external",并搭配JavaScript實現(xiàn)此效果。

錯誤:< a target="_blank">MUKI space< /a>

正確:< a rel="external">MUKI space< /a>

362.你做的頁面用哪些瀏覽器測試過?這些測試的內(nèi)核分別是什么?

1、Trident內(nèi)核代表產(chǎn)品Internet Explorer,又稱其為IE內(nèi)核。?Trident(又稱為MSHTML),是微軟開發(fā)的一種排版引擎。使用Trident渲染引擎的瀏覽器包括:IE、傲游、世界之窗瀏覽器、Avant、騰訊TT、Netscape 8、NetCaptor、Sleipnir、GOSURF、GreenBrowser和KKman等。?

2、Gecko內(nèi)核代表作品Mozilla?,FirefoxGecko是一套開放源代碼的、以C++編寫的網(wǎng)頁排版引擎。Gecko是最流行的排版引擎之一,僅次于Trident。使用它的最著名瀏覽器有Firefox、Netscape6至9

3、WebKit內(nèi)核代表作品Safari、Chromewebkit?, 是一個開源項目,包含了來自KDE項目和蘋果公司的一些組件,主要用于Mac OS系統(tǒng),它的特點在于源碼結構清晰、渲染速度極快。缺點是對網(wǎng)頁代碼的兼容性不高,導致一些編寫不標準的網(wǎng)頁無法正常顯示。主要代表作品有Safari和Google的瀏覽器Chrome。?

4、Presto內(nèi)核代表作品OperaPresto,?是由Opera Software開發(fā)的瀏覽器排版引擎,供Opera 7.0及以上使用。它取代了舊版Opera 4至6版本使用的Elektra排版引擎,包括加入動態(tài)功能,例如網(wǎng)頁或其部分可隨著DOM及Script語法的事件而重新排版。

363.你遇到了哪些瀏覽器的兼容性問題?怎么解決的?

答:因為不同的瀏覽器對同一段代碼有不同的解析,造成頁面顯示效果不統(tǒng)一的情況;這是我們常見的兼容性問題。

解決方法:

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

繪制簡單的柱狀圖,曲線圖,蛛網(wǎng)圖,環(huán)形圖,餅圖等完全夠用,用法比較簡單。

3.D3.js

功能太強大了,看首頁就知道了,感覺沒有什么圖d3繪不出來的。

4.Rx.js

很好的解決了異步和事件組合的問題。

5.lodash.js

365.Js中的三種彈出式消息提醒(警告窗口、確認窗口、信息輸入窗口)的命令是什么?

alter(),confirm(),prompt()

366.談談js的閉包

答:閉包無處不在,比如:jQuery、zepto的核心代碼都包含在一個大的閉包中,所以下面我先寫一個最簡單最原始的閉包,以便讓你在大腦里產(chǎn)生閉包的畫面:

function A(){
function B(){
console.log("Hello Closure!");
}
return B;
}
var C = A();
C();//Hello Closure!

這是最簡單的閉包。

有了初步認識后,我們簡單分析一下它和普通函數(shù)有什么不同,上面代碼翻譯成自然語言如下:

(1)定義普通函數(shù) A

(2)在 A 中定義普通函數(shù) B

(3)在 A 中返回 B

(4)執(zhí)行 A, 并把 A 的返回結果賦值給變量 C

(5)執(zhí)行 C

把這5步操作總結成一句話就是:

函數(shù)A的內(nèi)部函數(shù)B被函數(shù)A外的一個變量 c 引用。

把這句話再加工一下就變成了閉包的定義:

當一個內(nèi)部函數(shù)被其外部函數(shù)之外的變量引用時,就形成了一個閉包。

因此,當你執(zhí)行上述5步操作時,就已經(jīng)定義了一個閉包!

這就是閉包。

367.寫一段js,遍歷所有的li,將每個li的內(nèi)容逐個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(){
//獲取復選框對象--數(shù)組對象
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 :請求的參數(shù)(json/String)
//cache:true(走緩存 )  false(不走緩存)
//result:當ajax發(fā)送成功后會調用success后面的函數(shù),result:相當于形參,返回的數(shù)據(jù)
//async:是否為異步請求 默認true異步 , false同步
$.ajax({
url:"TestJqAjax",
type:"get",
/* data:"uname=zhangsan&realname=張三豐", */
data:{uname:"zhangsan",realname:"張三豐"},
cache:false,
async:false,
success:function(result){
alert(result);
}
});
}

//ajax的get方式的請求
function jqAjaxGet(){
//url,[data],[callback](當ajax發(fā)送成功后調用的函數(shù))
$.get("TestJqAjax",{uname:"zhangsan",realname:"張三豐"},function(result){
alert(result);
});

}

function  jqAjaxPost() {
//url,[data],[callback](當ajax發(fā)送成功后調用的函數(shù))
$.post("TestJqAjax",{uname:"zhangsan",realname:"張三豐"},function(result){
alert(result);
});
}
</script>

370.Js截取字符串a(chǎn)bcdefg的efg

function test2(){
var str = "abcdefg";
var substr = str.substring(4);
alert(substr);
}

371.http的請求頭信息包含了什么?

請求行(請求方式,資源路徑,協(xié)議和協(xié)議版本號)

若干請求頭

請求實體內(nèi)容

372.http的響應碼200,404,302,500表示的含義分別是?

200 - 確定??蛻舳苏埱笠殉晒?/p>

302 - 臨時移動轉移,請求的內(nèi)容已臨時移動新的位置

404 - 未找到文件或目錄

500 - 服務器內(nèi)部錯誤

373.Servlet中request對象的方法有?

/獲取網(wǎng)絡信息
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());

}

//獲取實體內(nèi)容
private void getContent(HttpServletRequest req, HttpServletResponse resp) {
//獲取單條信息
String uname = req.getParameter("uname");
//獲取多條信息,數(shù)組格式
String[] favs = req.getParameterValues("fav");
//遍歷數(shù)組
//判斷
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(協(xié)議):"+req.getScheme());
System.out.println("TestHttpRequest.getLines(協(xié)議的版本號):"+req.getProtocol());
System.out.println("TestHttpRequest.getLines(獲取參數(shù)信息):"+req.getQueryString());
System.out.println("TestHttpRequest.getLines(項目名稱***):"+req.getContextPath());
}

374.Javascript的常用對象有哪些

常用對象包括日期對象Date,字符串對象String,數(shù)組對象Array

//獲取并顯示系統(tǒng)當前時間

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

//遍歷數(shù)組信息

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文檔內(nèi)容與結構的標準方法。

關系:

–BOM描述了與瀏覽器進行交互的方法和接口

–DOM描述了處理網(wǎng)頁內(nèi)容的方法和接口

–DOM屬于BOM的一個屬性

376.JavaScript中獲取某個元素的三種方式JavaScript中的三種彈出式消息提醒命令是什么?

window.alert() 顯示一個提示信息

window.confirm() 顯示一個帶有提示信息、確定和取消按鈕的對話框

window.prompt() 顯示可提示用戶輸入的對話框

setTimeout與setInterval 的區(qū)別

setTimeout和setInterval的語法相同。它們都有兩個參數(shù),一個是將要執(zhí)行的代碼字符串,還有一個是以毫秒為單位的時間間隔,當過了那個時間段之后就將執(zhí)行那段代碼。

不過這兩個函數(shù)還是有區(qū)別的,setInterval在執(zhí)行完一次代碼之后,經(jīng)過了那個固定的時間間隔,它還會自動重復執(zhí)行代碼,而setTimeout只執(zhí)行一次那段代碼。

window.setTimeout("function",time);//設置一個超時對象,只執(zhí)行一次,無周期

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.靜態(tài)網(wǎng)頁和動態(tài)網(wǎng)頁的聯(lián)系和區(qū)別

聯(lián)系:

1)靜態(tài)網(wǎng)頁是網(wǎng)站建設的基礎,靜態(tài)網(wǎng)頁和動態(tài)網(wǎng)頁都要使用到HTMl語言。

2)靜態(tài)網(wǎng)頁是相對于動態(tài)網(wǎng)頁而言,指沒有后臺數(shù)據(jù)庫、不含程序和不可交互的網(wǎng)頁、是標準的HTML文件,它的文件擴展名是.htm或.html。你編的是什么它顯示的就是什么、不會有任何改變。

3)靜態(tài)網(wǎng)頁和動態(tài)網(wǎng)頁之間并不矛盾,為了網(wǎng)站適應搜索引擎檢索的需要,動態(tài)網(wǎng)站可以采用靜動結合的原則,適合采用動態(tài)網(wǎng)頁的地方用動態(tài)網(wǎng)頁,如果必要使用靜態(tài)網(wǎng)頁,則可以考慮用靜態(tài)網(wǎng)頁的方法來實現(xiàn),在同一個網(wǎng)站上,動態(tài)網(wǎng)頁內(nèi)容和靜態(tài)網(wǎng)頁內(nèi)容同時存在也是很常見的事情。

區(qū)別:

1)程序是否在服務器端運行,是重要標志。在服務器端運行的程序、網(wǎng)頁、組件,屬于動態(tài)網(wǎng)頁,它們會隨不同客戶、不同時間,返回不同的網(wǎng)頁,例如ASP、PHP、JSP、ASP.net、CGI等。運行于客戶端的程序、網(wǎng)頁、插件、組件,屬于靜態(tài)網(wǎng)頁,例如html頁、Flash、javascript、VBscript等等,它們是永遠不變的。

2)編程技術不同。靜態(tài)網(wǎng)頁和動態(tài)網(wǎng)頁主要根據(jù)網(wǎng)頁制作的語言來區(qū)分。靜態(tài)網(wǎng)頁使用語言:HTML。 動態(tài)網(wǎng)頁使用語言:HTML+ASP 或 HTML+PHP 或 HTML+JSP 等其它網(wǎng)站動態(tài)語言。

3)被搜索引擎收錄情況不同。由于編程技術不容,靜態(tài)網(wǎng)頁是純粹HTML格式的網(wǎng)頁,頁面內(nèi)容穩(wěn)定,不論是網(wǎng)頁是否被訪問,頁面都被保存在網(wǎng)站服務器上,很容易被搜索引擎收錄。而動態(tài)網(wǎng)頁的內(nèi)容是當用戶點擊請求時才從數(shù)據(jù)庫中調出返回給用戶一個網(wǎng)頁的內(nèi)容,并不是存放在服務器上的獨立文件,相比較于靜態(tài)網(wǎng)頁而言,動態(tài)網(wǎng)頁很難被搜索引擎收錄。

4)用戶訪問速度不同。用戶訪問動態(tài)網(wǎng)頁時,網(wǎng)頁在獲得搜索指令后經(jīng)過數(shù)據(jù)庫的調查匹配,再將與指令相符的內(nèi)容傳遞給服務器,通過服務器的編譯將網(wǎng)頁編譯成標準的HTML代碼,從而傳遞給用戶瀏覽器,多個讀取過程大大降低了用戶的訪問速度。而靜態(tài)網(wǎng)頁不同,由于網(wǎng)頁內(nèi)容直接存取在服務器上,省去了服務器的編譯過程,用戶訪問網(wǎng)頁速度很快。

5)制作和后期維護工作量不同。動態(tài)網(wǎng)頁的設計以數(shù)據(jù)庫技術為基礎,可以實現(xiàn)多種功能,降低了網(wǎng)站維護的工作量。而靜態(tài)網(wǎng)頁由于沒有數(shù)據(jù)庫的支持,網(wǎng)頁內(nèi)容更改時需要直接修改代碼,在網(wǎng)站內(nèi)容制作和維護中,所需的工作量更大。動態(tài)網(wǎng)頁與靜態(tài)網(wǎng)頁各有特點,網(wǎng)站設計師在網(wǎng)頁設計時,主要根據(jù)網(wǎng)站的功能需求和網(wǎng)站內(nèi)容多少選擇不同網(wǎng)頁。如,網(wǎng)站包含信息量太大時,就需要選擇動態(tài)網(wǎng)頁,反之,則選擇靜態(tài)網(wǎng)頁。

379.JSP/ASP/PHP的比較

ASP(Active Server Pages),JSP(JavaServer Pages),PHP(Hypertext Preprocessor)是目前主流的三種動態(tài)網(wǎng)頁語言。

ASP是微軟(Microsoft)所開發(fā)的一種后臺腳本語言,它的語法和Visual BASIC類似,可以像SSI(Server Side Include)那樣把后臺腳本代碼內(nèi)嵌到HTML頁面中。雖然ASP簡單易用,但是它自身存在著許多缺陷,最重要的就是安全性問題。

PHP是一種跨平臺的服務器端的嵌入式腳本語言。它大量地借用C,Java和Perl語言的語法, 并耦合PHP自己的特性,使WEB開發(fā)者能夠快速地寫出動態(tài)產(chǎn)生頁面。它支持目前絕大多數(shù)數(shù)據(jù)庫。

JSP是一個簡化的Servlet,它是由Sun公司倡導、許多公司參與一起建立的一種動態(tài)網(wǎng)頁技術標準。JSP技術有點類似ASP技術,它是在傳統(tǒng)的網(wǎng)頁HTML中插入Java程序段和JSP標記(tag),從而形成JSP文件,后綴名為(*.jsp)。 用JSP開發(fā)的Web應用是跨平臺的,既能在Linux下運行,也能在其他操作系統(tǒng)上運行。

ASP優(yōu)點: 無需編譯、易于生成、獨立于瀏覽器、面向對象、與任何ActiveX scripting 語言兼容、源程序碼不會外漏。

缺點:

1)Windows本身的所有問題都會一成不變的也累加到了它的身上。安全性、穩(wěn)定性、跨平臺性都會因為與NT的捆綁而顯現(xiàn)出來。

2)ASP由于使用了COM組件所以它會變的十分強大,但是這樣的強大由于Windows NT系統(tǒng)最初的設計問題而會引發(fā)大量的安全問題。只要在這樣的組件或是操作中一不注意,那么外部攻擊就可以取得相當高的權限而導致網(wǎng)站癱瘓或者數(shù)據(jù)丟失。

3)還無法完全實現(xiàn)一些企業(yè)級的功能:完全的集群、負載均橫。

PHP優(yōu)點:

1)一種能快速學習、跨平臺、有良好數(shù)據(jù)庫交互能力的開發(fā)語言。

2)簡單輕便,易學易用。

3 ) 與Apache及其它擴展庫結合緊密。

缺點:

1 ) 數(shù)據(jù)庫支持的極大變化。

2 ) 不適合應用于大型電子商務站點。

JSP優(yōu)點:

1 ) 一處編寫隨處運行。

2 ) 系統(tǒng)的多臺平支持。

3 ) 強大的的可伸縮性。

4 ) 多樣化和功能強大的開發(fā)工具支持。

缺點:

1) 與ASP一樣,Java的一些優(yōu)勢正是它致命的問題所在。

2 ) 開發(fā)速度慢

380.CGI/Servlet/JSP的比較

CGI(Common Gateway Interface),通用網(wǎng)關接口,是一種根據(jù)請求信息動態(tài)產(chǎn)生回應內(nèi)容的技術。

通過CGI,Web 服務器可以將根據(jù)請求不同啟動不同的外部程序,并將請求內(nèi)容轉發(fā)給該程序,在程序執(zhí)行結束后,將執(zhí)行結果作為回應返回給客戶端。也就是說,對于每個請求,都要產(chǎn)生一個新的進程進行處理。

Servlet 是在服務器上運行的小程序。在實際運行的時候Java Servlet與Web服務器會融為一體。與CGI不同的是,Servlet對每個請求都是單獨啟動一個線程,而不是進程。這種處理方式大幅度地降低了系統(tǒng)里的進程數(shù)量,提高了系統(tǒng)的并發(fā)處理能力。

比較:

1) JSP從本質上說就是Servlet。JSP技術產(chǎn)生于Servlet之后,兩者分工協(xié)作,Servlet側重于解決運算和業(yè)務邏輯問題,JSP則側重于解決展示問題。

2 ) 與CGI相比,Servlet效率更高。Servlet處于服務器進程中,它通過多線程方式運行其service方法,一個實例可以服務于多個請求,并且其實例一般不會銷毀。而CGI對每個請求都產(chǎn)生新的進程,服務完成后就銷毀,所以效率上低于Servlet 。

3)與CGI相比,Servlet更容易使用,功能更強大,具有更好的可移植性,更節(jié)省投資。在未來的技術發(fā)展過程中,Servlet有可能徹底取代CGI。

381.HTTP協(xié)議工作原理及其特點

超文本傳輸協(xié)議(HTTP:Hypertext Transport Protocol)是萬維網(wǎng)應用層的協(xié)議,它通過兩個程序實現(xiàn):一個是客戶端程序(各種瀏覽器),另一個是服務器 (常稱Web服務器) 。這兩個通常運行在不同的主機上,通過交換報文來完成網(wǎng)頁請求和響應,報文可簡單分為請求報文和響應報文。

工作原理(流程):

客戶機與服務器建立連接后,瀏覽器可以向web服務器發(fā)送請求并顯示收到的網(wǎng)頁,當用戶在瀏覽器地址欄中輸入一個URL或點擊一個超連接時,瀏覽器就向服務器發(fā)出了HTTP請求,請求方式的格式為:統(tǒng)一資源標識符、協(xié)議版本號,后邊是MIME(Multipurpose Internet Mail Extensions)信息包括請求修飾符、客戶機信息和可能的內(nèi)容。該請求被送往由URL指定的WEB服務器,WEB服務器接收到請求后,進行相應反映,其格式為:一個狀態(tài)行包括信息的協(xié)議版本號、一個成功或錯誤的代碼,后邊服務器信息、實體信息和可能的內(nèi)容。即以HTTP規(guī)定的格式送回所要求的文件或其他相關信息,再由用戶計算機上的瀏覽器負責解釋和顯示。

特點:

1)支持客戶/服務器模式。

2)簡單快速:客戶向服務器請求服務時,只需傳送請求方法和路徑。請求方法常用的有GET、HEAD、POST。每種方法規(guī)定了客戶與服務器聯(lián)系的類型不同。由于HTTP協(xié)議簡單,使得HTTP服務器的程序規(guī)模小,因而通信速度很快。

3)靈活:HTTP允許傳輸任意類型的數(shù)據(jù)對象。正在傳輸?shù)念愋陀蒀ontent-Type加以標記。

4)無連接:無連接的含義是限制每次連接只處理一個請求。服務器處理完客戶的請求,并收到客戶的應答后,即斷開連接。采用這種方式可以節(jié)省傳輸時間。

5)無狀態(tài):HTTP協(xié)議是無狀態(tài)協(xié)議。無狀態(tài)是指協(xié)議對于事務處理沒有記憶能力。缺少狀態(tài)意味著如果后續(xù)處理需要前面的信息,則它必須重傳,這樣可能導致每次連接傳送的數(shù)據(jù)量增大。另一方面,在服務器不需要先前信息時它的應答就較快。

382.get和post的區(qū)別

1. Get是不安全的,因為在傳輸過程,數(shù)據(jù)被放在請求的URL中;Post的所有操作對用戶來說都是不可見的。

2. Get傳送的數(shù)據(jù)量較小,這主要是因為受URL長度限制;Post傳送的數(shù)據(jù)量較大,一般被默認為不受限制。

3. Get限制Form表單的數(shù)據(jù)集的值必須為ASCII字符;而Post支持整個ISO10646字符集。

4. Get執(zhí)行效率卻比Post方法好。Get是form提交的默認方法。

383.如何解決表單提交的中文亂碼問題

1)設置頁面編碼,若是jsp頁面,需編寫代碼

<%@page language="java" pageEncoding="UTF-8" contentType="text/html;charset=UTF-8" %>

若是html頁面,在網(wǎng)頁頭部(< head>< /head>)中添加下面這段代碼

< meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

2)將form表單提交方式變?yōu)閜ost方式,即添加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增加內(nèi)容:

URIEncoding="utf-8"

384.絕對路徑、根路徑、相對路徑的含義及其區(qū)別

絕對路徑指對站點的根目錄而言某文件的位置,相對路徑指以當前文件所處目錄而言某文件的位置,相對路徑-以引用文件之網(wǎng)頁所在位置為參考基礎,而建立出的目錄路徑。絕對路徑-以Web站點根目錄為參考基礎的目錄路徑。

先給出一個網(wǎng)站結構圖做實例加深理解,A網(wǎng)站(域名為http://www.a.com):/include/a-test.html,/img/a-next.jpg;B網(wǎng)站(域名為http://www.b.com):/include/b-test.html,/img/b-next.jpg。

相對路徑是從引用的網(wǎng)頁文件本身開始構建的,如果在A網(wǎng)站中的a-test.html中要插入圖片a-next.jpg,可以這樣做:< img src="../img/a-next.jpg" />,重點是img前面的../,表示從html處于的include開始起步,輸入一個../表示回到上面一級父文件夾下,然后再接著img/表示又從父級文件夾下的img文件開始了,最后定位img下面的next.jpg。

根路徑是從網(wǎng)站的最底層開始起,一般的網(wǎng)站的根目錄就是域名下對應的文件夾,就如D盤是一個網(wǎng)站,雙擊D盤進入到D盤看到的就是網(wǎng)站的根目錄,這種路徑的鏈接樣式是這樣的:如果在A網(wǎng)站中的a-test.html中要插入圖片a-next.jpg,可以這樣做:< img src="/img/a-next.jpg" >,以/開頭表示從網(wǎng)站根目錄算起,找到根目錄下面的img文件夾下的next.jpg。

絕對路徑就很好理解了,這種路徑一般帶有網(wǎng)站的域名,如果在A網(wǎng)站中的a-test.html中要插入圖片a-next.jpg,需要這樣這樣寫:< img src="http://www.a.com/img/a-next.jpg" >,將圖片路徑上帶有了域名信息,再打個比方:如果在A網(wǎng)站中的a-test.html中要插入B網(wǎng)站的圖片b-next.jpg,就需要這樣寫:< img src="http://www.b.com/img/b-next.jpg" >,這種方法適用與在不同網(wǎng)站之間插入外部網(wǎng)站的圖片。

385.如實現(xiàn)servlet的單線程模式

實現(xiàn)servlet的單線程的jsp命令是: <%@ page isThreadSafe=”false”%>。默認isThreadSafe值為true。

屬性isThreadSafe=false模式表示它是以Singleton模式運行,該模式implements了接口SingleThreadMode, 該模式同一時刻只有一個實例,不會出現(xiàn)信息同步與否的概念。若多個用戶同時訪問一個這種模式的頁面,那么先訪問者完全執(zhí)行完該頁面后,后訪問者才開始執(zhí)行。

屬性isThreadSafe=true模式表示它以多線程方式運行。該模式的信息同步,需訪問同步方法(用synchronized標記的)來實現(xiàn)。 一般格式如下:

 public synchronized void syncmethod(...){
      while(...) {
        this.wait();
      }
      this.notifyAll();
 }

386.Servlet的生命周期

1、加載:在下列時刻加載 Servlet:(1)如果已配置自動加載選項,則在啟動服務器時自動

2、加載 (web.xml中設置< load-on-start>);(2)在服務器啟動后,客戶機首次向 Servlet 發(fā)出請求時;(3)重新加載 Servlet 時(只執(zhí)行一次)

3、實例化:加載 Servlet 后,服務器創(chuàng)建一個 Servlet 實例。(只執(zhí)行一次)

4、初始化:調用 Servlet 的 init() 方法。在初始化階段,Servlet 初始化參數(shù)被傳遞給 Servlet 配置對象ServletConfig。 (只執(zhí)行一次)

5、請求處理:對于到達服務器的客戶機請求,服務器創(chuàng)建針對此次請求的一個“請求”對象和一個“響應”對象。服務器調用 Servlet 的 service() 方法,該方法用于傳遞“請求”和“響應”對象。service() 方法從“請求”對象獲得請求信息、處理該請求并用“響應”對象的方法以將響應傳回客戶機。service() 方法可以調用其它方法來處理請求,例如 doGet()、doPost() 或其它的方法。(每次請求都執(zhí)行該步驟)

6、銷毀:當服務器不再需要 Servlet, 或重新裝入 Servlet 的新實例時,服務器會調用 Servlet 的 destroy() 方法。(只執(zhí)行一次)

387.轉發(fā)和重定向的區(qū)別

轉發(fā)是在服務端直接做的事情,是對客戶端的同一個request進行傳遞,瀏覽器并不知道。重定向是由瀏覽器來做的事情。重定向時,服務端返回一個response,里面包含了跳轉的地址,由瀏覽器獲得后,自動發(fā)送一個新request。轉發(fā)像呼叫轉移或者110報警中心,重定向似114查號臺。

a) 區(qū)別1:跳轉效率的不同

轉發(fā)效率相對高;重定向效率相對低

b) 區(qū)別2:實現(xiàn)語句不同

轉發(fā) request.getRequestDispatcher("xxxx").forward(request,response) ;

重定向 response.sendRedirect("xxxx")

c) 區(qū)別3:是否共有同一個request的數(shù)據(jù)

轉發(fā)源組件與目標組件共有同一個request數(shù)據(jù)

重定向源組件與目標組件不共有同一個request數(shù)據(jù)(可使用session共有數(shù)據(jù))

d) 區(qū)別4:瀏覽器URL地址的不同

轉發(fā)后瀏覽器URL地址保持不變(源組件地址)

重定向后瀏覽器URL地址改變?yōu)橹囟ㄏ蚝蟮牡刂罚繕私M件地址)

e) 區(qū)別5:"/"路徑的含義不同

轉發(fā)時"/"代表當前項目的根路徑 ;重定向時"/"代表當前服務器的根路徑

f) 區(qū)別6:跳轉范圍的不同

只能轉發(fā)到同一應用中的URL(默認) ;可以重定向任何服務器、任何應用的URL

g) 區(qū)別7:刷新是否導致重復提交

轉發(fā)會導致重復提交(可以通過同步令牌解決);重定向不會導致重復提交

h) 區(qū)別8:是否經(jīng)過過濾器

轉發(fā)不經(jīng)過過濾器(默認情況);重定向經(jīng)過過濾器

388.JSP的執(zhí)行過程

在JSP運行過程中,首先由客戶端發(fā)出請求,Web服務器接收到請求后,如果是第一次訪問某個jsp頁面,Web服務器對它進行以下3個操作。

1)翻譯:由.jsp變?yōu)?java,由JSP引擎實現(xiàn)。

2)編譯:由.java變?yōu)?class,由 Java編譯器實現(xiàn)。

3)執(zhí)行:由.class變?yōu)?html,用Java虛擬機執(zhí)行編譯文件,然后將執(zhí)行結果返回給Web服務器,并最終返回給客戶端

如果不是第一次訪問某個JSP頁面,則只執(zhí)行第三步。所以第一次訪問JSP較慢。

389.JSP動作有哪些,簡述作用?

jsp:include:在頁面被請求的時候引入一個文件。

jsp:useBean:尋找或者實例化一個JavaBean。 jsp:setProperty:設置JavaBean的屬性。

jsp:getProperty:輸出某個JavaBean的屬性。

jsp:forward:把請求轉到一個新的頁面。 jsp:plugin:根據(jù)瀏覽器類型為Java插件生成OBJECT或EMBED標記。

390.page/request/session/application作用域區(qū)別

page:當前頁面范圍

request:當前頁面范圍+轉發(fā)頁面(forward)+包含頁面(include)

session:當前會話:session在以下幾種情況下失效

1)銷毀session:Session.invalidate();

2)超過最大非活動間隔時間

3)手動關閉瀏覽器(session并沒有立刻失效,因為服務器端session仍舊存在,超過最大非活動間隔時間后真正失效)

application:當前應用;服務器重新啟動前一直有效

391.JSP和Servlet的區(qū)別和聯(lián)系

區(qū)別:

1)JSP是在HTML代碼里寫JAVA代碼,框架是HTML;而Servlet是在JAVA代碼中寫HTML代碼,本身是個JAVA類。

2)JSP使人們把顯示和邏輯分隔成為可能,這意味著兩者的開發(fā)可并行進行;而Servlet并沒有把兩者分開。

3)Servlet獨立地處理靜態(tài)表示邏輯與動態(tài)業(yè)務邏輯.這樣,任何文件的變動都需要對此服務程序重新編譯;JSP允許用特殊標簽直接嵌入到HTML頁面, HTML內(nèi)容與JAVA內(nèi)容也可放在單獨文件中,HTML內(nèi)容的任何變動會自動編譯裝入到服務程序.

4)Servlet需要在web.xml中配置,而JSP無需配置。

5)目前JSP主要用在視圖層,負責顯示,而Servlet主要用在控制層,負責調度

聯(lián)系:

1)都是Sun公司推出的動態(tài)網(wǎng)頁技術。

2)先有Servlet,針對Servlet缺點推出JSP。JSP是Servlet的一種特殊形式,每個JSP頁面就是一個Servlet實例——JSP頁面由系統(tǒng)翻譯成Servlet,Servlet再負責響應用戶請求。

392.談談過濾器原理及其作用?

原理:

?過濾器是運行在服務器端的一個攔截作用的web組件,一個請求來到時,web容器會判斷是否有過濾器與該信息資源相關聯(lián),如果有則交給過濾器處理,然后再交給目標資源,響應的時候則以相反的順序交給過濾器處理,最后再返回給用戶瀏覽器

?一般用于日志記錄、性能、安全、權限管理等公共模塊。

過濾器開發(fā):

?過濾器是一個實現(xiàn)了javax.servlet.Filter接口的java類

?主要業(yè)務代碼放在doFilter方法中

?業(yè)務代碼完成后要將請求向后傳遞,即調用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>

談談監(jiān)聽器作用及其分類?

監(jiān)聽器也叫Listener,是一個實現(xiàn)特定接口的java類,使用時需要在web.xml中配置,它是web服務器端的一個組件,它們用于監(jiān)聽的事件源分別為SerlvetConext,HttpSession和ServletRequest這三個域對象

主要有以下三種操作:

–監(jiān)聽三個域對象創(chuàng)建和銷毀的事件監(jiān)聽器

–監(jiān)聽域對象中屬性的增加和刪除的事件監(jiān)聽器

–監(jiān)聽綁定到HttpSession域中的某個對象的狀態(tài)的時間監(jiān)聽器

接口分類:

–ServletContextListener

HttpSessionListener

–ServletRequestListener

–ServletContextAttributeListener

–HttpSessionAttributeListener

ServletRequestAttributeListener

–HttpSessionBindingListener(不需要配置)

–HttpSessionActivationListener(不需要配置)

配置:

< listener>< listener-class>實現(xiàn)以上任意接口的java類全名< /listener-class>< /listener>

393.jQuery相比JavaScript的優(yōu)勢在哪里

jQuery的語法更加簡單。

jQuery消除了JavaScript跨平臺兼容問題。

相比其他JavaScript和JavaScript庫,jQuery更容易使用。

jQuery有一個龐大的庫/函數(shù)。

jQuery有良好的文檔和幫助手冊。

jQuery支持AJAX

394.DOM對象和jQuery對象的區(qū)別及其轉換

DOM對象,是我們用傳統(tǒng)的方法(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)$用作選擇器

例如:根據(jù)id獲得頁面元素$("#元素ID")

2)$相當于window.onload 和 $(document).ready(...)

例如:$(function(){...}); function(){...}會在DOM樹加載完畢之后執(zhí)行。

3)$用作JQuery的工具函數(shù)的前綴

例如: var str = ' Welcome to shanghai.com ';

str = $.trim(str);去掉空格

4)$(element):把DOM節(jié)點轉化成jQuery節(jié)點

例如:var cr=document.getElementById("cr"); //dom對象

var $cr = $(cr); //轉換成jquery對象

5)$(html):使用HTML字符串創(chuàng)建jQuery節(jié)點

例如:var obj = $("< div>尚學堂,實戰(zhàn)化教學第一品牌< /div>")

396.Ajax含義及其主要技術

Ajax (Asynchronous JavaScript and XML 阿賈克斯)不是一個新的技術,事實上,它是一些舊有的成熟的技術以一種全新的更加強大的方式整合在一起。

Ajax的關鍵技術:

1)使用CSS構建用戶界面樣式,負責頁面排版和美工

2)使用DOM進行動態(tài)顯示和交互,對頁面進行局部修改

3)使用XMLHttpRequest異步獲取數(shù)據(jù)

4)使用JavaScript將所有元素綁定在一起

397.Ajax的工作原理

Ajax的原理簡單來說通過XmlHttpRequest對象來向服務器發(fā)異步請求,從服務器獲得數(shù)據(jù),然后用javascript來操作DOM而更新頁面。這其中最關鍵的一步就是從服務器獲得請求數(shù)據(jù)。要清楚這個過程和原理,我們必須對 XMLHttpRequest有所了解。

XMLHttpRequest是ajax的核心機制,它是在IE5中首先引入的,是一種支持異步請求的技術。簡單的說,也就是javascript可以及時向服務器提出請求和處理響應,而不阻塞用戶。達到無刷新的效果。

398.JSON及其作用

JSON(JavaScript Object Notation) 是一種輕量級的數(shù)據(jù)交換格式,采用完全獨立于語言的文本格式,是理想的數(shù)據(jù)交換格式。同時,JSON是 JavaScript 原生格式,這意味著在 JavaScript 中處理 JSON數(shù)據(jù)不須要任何特殊的 API 或工具包。

在JSON中,有兩種結構:對象和數(shù)組。

?{} 對象

?[] 數(shù)組

?, 分隔屬性

: 左邊為屬性名,右邊為屬性值?

屬性名可用可不用引號括起,屬性值為字符串一定要用引號括起

舉例:

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:磁盤文件工廠類,設置上傳文件保存的磁盤目錄,緩沖區(qū)大小。

ServletFileUpload:上傳處理類,此類真正讀取客戶上傳的文件,同時可以設置最大接收大小。

FileItem:上傳的文件對象,可以是多個文件,每個上傳的文件都是一個單獨的FileItem對象。

400.說出Servlet的生命周期,并說出Servlet和CGI的區(qū)別?

答:Web容器加載Servlet并將其實例化后,Servlet生命周期開始,容器運行其init()方法進行Servlet的初始化;請求到達時調用Servlet的service方法,service方法會調用與請求對應的doGet或doPost等方法;當服務器關閉會項目被卸載時服務器會將Servlet實例銷毀,此時會調用Servlet的destroy方法。Servlet與CGI的區(qū)別在于Servlet處于服務器進程中,它通過多線程方式運行其service方法,一個實例可以服務于多個請求,并且其實例一般不會銷毀,而CGI 對每個請求都產(chǎn)生新的進程,服務完成后就銷毀,所以效率上低于Servlet。

【補充1】SUN公司在1996年發(fā)布Servlet技術就是為了和CGI進行競爭,Servlet是一個特殊的Java程序,一個基于Java的Web應用通常包含一個或多個Servlet類。 Servlet不能夠自行創(chuàng)建并執(zhí)行,它是在Servlet容器中運行的,容器將用戶的請求傳遞給Servlet程序,此外將Servlet的響應回傳給用戶。通常一個Servlet會關聯(lián)一個或多個JSP頁面。以前CGI經(jīng)常因為性能開銷上的問題被詬病,然而Fast CGI早就已經(jīng)解決了CGI效率上的問題,所以面試的時候大可不必詬病CGI,騰訊的網(wǎng)站就使用了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 有有什么關系?

答:其實這個問題在上面已經(jīng)闡述過了,Servlet是一個特殊的Java程序,它運行于服務器的JVM中,能夠依靠服務器的支持向瀏覽器提供顯示內(nèi)容。JSP本質上是Servlet的一種簡易形式, JSP會被服務器處理成一個類似于Servlet的Java程序,可以簡化頁面內(nèi)容的生成。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客戶機發(fā)出的一個請求相關的對象和屬性。一個請求可能跨越多個頁面,涉及多個Web 組件;需要在頁面顯示的臨時數(shù)據(jù)可以置于此作用域

③session代表與某個用戶與服務器建立的一次會話相關的對象和屬性。跟某個用戶相關的數(shù)據(jù)應該放在用戶自己的session中

④application代表與整個Web應用程序相關的對象和屬性,它實質上是跨越整個Web應用程序,包括多個頁面、請求和會話的一個全局作用域。

403.如何實現(xiàn)JSP或Servlet的單線程模式?

<%@page isThreadSafe=”false”%>

【補充】Servlet默認的工作模式是單實例多線程,如果Servlet實現(xiàn)了標識接口SingleThreadModel又或是JSP頁面通過page指令設置isThreadSafe屬性為false,那么它們生成的Java代碼會以單線程多實例方式工作。顯然,這樣做會導致每個請求創(chuàng)建一個Servlet實例,這種實踐將導致嚴重的性能問題。

404.實現(xiàn)會話跟蹤的技術有哪些?

答:由于HTTP協(xié)議本身是無狀態(tài)的,服務器為了區(qū)分不同的用戶,就需要對用戶會話進行跟蹤,簡單的說就是為用戶進行登記,為用戶分配唯一的ID,下一次用戶在請求中包含此ID,服務器據(jù)此判斷到底是哪一個用戶。

①URL 重寫:在URL中添加用戶會話的信息作為請求的參數(shù),或者將唯一的會話ID添加到URL結尾以標識一個會話。

②設置表單隱藏域:將和會話跟蹤相關的字段添加到隱式表單域中,這些信息不會在瀏覽器中顯示但是提交表單時會提交給服務器。

這兩種方式很難處理跨越多個頁面的信息傳遞,因為如果每次都要修改URL或在頁面中添加隱式表單域來存儲用戶會話相關信息,事情將變得非常麻煩。

③cookie:cookie有兩種,一種是基于窗口的,瀏覽器窗口關閉后,cookie就沒有了;另一種是將信息存儲在一個臨時文件中,并設置存在的時間。當用戶通過瀏覽器和服務器建立一次會話后,會話ID就會隨響應信息返回存儲在基于窗口的cookie中,那就意味著只要瀏覽器沒有關閉,會話沒有超時,下一次請求時這個會話ID又會提交給服務器讓服務器識別用戶身份。會話中可以為用戶保存信息。會話對象是在服務器內(nèi)存中的,而基于窗口的cookie是在客戶端內(nèi)存中的。如果瀏覽器禁用了cookie,那么就需要通過下面兩種方式進行會話跟蹤。當然,在使用cookie時要注意幾點:首先不要在cookie中存放敏感信息;其次cookie存儲的數(shù)據(jù)量有限(4k),不能將過多的內(nèi)容存儲cookie中;再者瀏覽器通常只允許一個站點最多存放20個cookie。當然,和用戶會話相關的其他信息(除了會話ID)也可以存在cookie方便進行會話跟蹤。

④HttpSession:在所有會話跟蹤技術中,HttpSession對象是最強大也是功能最多的。當一個用戶第一次訪問某個網(wǎng)站時會自動創(chuàng)建HttpSession,每個用戶可以訪問他自己的HttpSession。可以通過HttpServletRequest對象的getSession方法獲得HttpSession,通過HttpSession的setAttribute方法可以將一個值放在HttpSession中,通過調用HttpSession對象的getAttribute方法,同時傳入屬性名就可以獲取保存在HttpSession中的對象。與上面三種方式不同的是,HttpSession放在服務器的內(nèi)存中,因此不要將過大的對象放在里面,即使目前的Servlet容器可以在內(nèi)存將滿時將HttpSession中的對象移到其他存儲設備中,但是這樣勢必影響性能。添加到HttpSession中的值可以是任意Java對象,這個對象最好實現(xiàn)了Serializable接口,這樣Servlet容器在必要的時候可以將其序列化到文件中,否則在序列化時就會出現(xiàn)異常。

405.過濾器有哪些作用和用法?

答: Java Web開發(fā)中的過濾器(filter)是從Servlet 2.3規(guī)范開始增加的功能,并在Servlet 2.4規(guī)范中得到增強。對Web應用來說,過濾器是一個駐留在服務器端的Web組件,它可以截取客戶端和服務器之間的請求與響應信息,并對這些信息進行過濾。當Web容器接受到一個對資源的請求時,它將判斷是否有過濾器與這個資源相關聯(lián)。如果有,那么容器將把請求交給過濾器進行處理。在過濾器中,你可以改變請求的內(nèi)容,或者重新設置請求的報頭信息,然后再將請求發(fā)送給目標資源。當目標資源對請求作出響應時候,容器同樣會將響應先轉發(fā)給過濾器,再過濾器中,你可以對響應的內(nèi)容進行轉換,然后再將響應發(fā)送到客戶端。

常見的過濾器用途主要包括:對用戶請求進行統(tǒng)一認證、對用戶的訪問請求進行記錄和審核、對用戶發(fā)送的數(shù)據(jù)進行過濾或替換、轉換圖象格式、對響應內(nèi)容進行壓縮以減少傳輸量、對請求或響應進行加解密處理、觸發(fā)資源訪問事件、對XML的輸出應用XSLT等。

和過濾器相關的接口主要有:Filter、FilterConfig、FilterChain

406.監(jiān)聽器有哪些作用和用法?

答:Java Web開發(fā)中的監(jiān)聽器(listener)就是application、session、request三個對象創(chuàng)建、銷毀或者往其中添加修改刪除屬性時自動執(zhí)行代碼的功能組件,如下所示:

①ServletContextListener:對Servlet上下文的創(chuàng)建和銷毀進行監(jiān)聽。

②ServletContextAttributeListener:監(jiān)聽Servlet上下文屬性的添加、刪除和替換。

③HttpSessionListener:對Session的創(chuàng)建和銷毀進行監(jiān)聽。

補充:session的銷毀有兩種情況:1session超時(可以在web.xml中通過< session-config>/< session-timeout>標簽配置超時時間);2通過調用session對象的invalidate()方法使session失效。

④HttpSessionAttributeListener:對Session對象中屬性的添加、刪除和替換進行監(jiān)聽。

⑤ServletRequestListener:對請求對象的初始化和銷毀進行監(jiān)聽。

⑥ServletRequestAttributeListener:對請求對象屬性的添加、刪除和替換進行監(jiān)聽。

407.你的項目中使用過哪些JSTL標簽?

答:項目中主要使用了JSTL的核心標簽庫,包括< c:if>、< c:choose>、< c: when>、< c: otherwise>、< c:forEach>等,主要用于構造循環(huán)和分支結構以控制顯示邏輯。

【說明】雖然JSTL標簽庫提供了core、sql、fmt、xml等標簽庫,但是實際開發(fā)中建議只使用核心標簽庫(core),而且最好只使用分支和循環(huán)標簽并輔以表達式語言(EL),這樣才能真正做到數(shù)據(jù)顯示和業(yè)務邏輯的分離,這才是最佳實踐。

408.使用標簽庫有什么好處?如何自定義JSP標簽?

答:使用標簽庫的好處包括以下幾個方面:

分離JSP頁面的內(nèi)容和邏輯,簡化了Web開發(fā);

開發(fā)者可以創(chuàng)建自定義標簽來封裝業(yè)務邏輯和顯示邏輯;

標簽具有很好的可移植性、可維護性和可重用性;

避免了對Scriptlet(小腳本)的使用(很多公司的項目開發(fā)都不允許在JSP中書寫小腳本)

自定義JSP標簽包括以下幾個步驟:

編寫一個Java類實現(xiàn)實現(xiàn)Tag/BodyTag/IterationTag接口(通常不直接實現(xiàn)這些接口而是繼承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>

運行結果

【注意】如果要將自定義的標簽庫發(fā)布成JAR文件,需要將標簽庫描述文件(tld文件)放在JAR文件的META-INF目錄下,可以JDK自帶的jar工具完成JAR文件的生成。

409.表達式語言(EL)的隱式對象及其作用?

答: pageContext、initParam(訪問上下文參數(shù))、param(訪問請求參數(shù))、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標識符命名規(guī)則,例如上面的accept-language就不是一個有效的Java標識符,那么這時候就只能用[]運算符而不能使用.獲取它的值

410.表達式語言(EL)支持哪些運算符?

答:除了.和[]運算符,EL還提供了:

算術運算符:+、-、*、/或div、%或mod

關系運算符:==或eq、!=或ne、>或gt、>=或ge、< 或lt、< =或le

邏輯運算符:&&或and、||或or、!或not

條件運算符:${statement? A : B}(跟Java的條件運算符類似)

empty運算符:檢查一個值是否為null或者空(數(shù)組長度為0或集合中沒有元素也返回true)

411.Servlet 3中的異步處理指的是什么?

答:在Servlet 3中引入了一項新的技術可以讓Servlet異步處理請求。有人可能會質疑,既然都有多線程了,還需要異步處理請求嗎?答案是肯定的,因為如果一個任務處理時間相當長,那么Servlet或Filter會一直占用著請求處理線程直到任務結束,隨著并發(fā)用戶的增加,容器將會遭遇線程超出的風險,這這種情況下很多的請求將會被堆積起來而后續(xù)的請求可能會遭遇拒絕服務,直到有資源可以處理請求為止。異步特性可以幫助應用節(jié)省容器中的線程,特別適合執(zhí)行時間長而且用戶需要得到結果的任務,如果用戶不需要得到結果則直接將一個Runnable對象交給Executor(如果不清楚請查看前文關于多線程和線程池的部分)并立即返回即可。

【補充】多線程在Java誕生初期無疑是一個亮點,而Servlet單實例多線程的工作方式也曾為其贏得美名,然而技術的發(fā)展往往會顛覆我們很多的認知,就如同當年愛因斯坦的相對論顛覆了牛頓的經(jīng)典力學一般。事實上,異步處理絕不是Serlvet 3首創(chuàng),如果你了解Node.js的話,對Servlet 3的這個重要改進就不以為奇了。

412.如何在基于Java的Web項目中實現(xiàn)文件上傳和下載?

答:(稍后呈現(xiàn),我準備用HTML5寫一個帶進度條的客戶端,然后再用Servlet 3提供的文件上傳支持來做一個多文件上傳的例子)

413.簡述值棧(Value-Stack)的原理和生命周期

答: Value-Stack貫穿整個 Action 的生命周期,保存在request作用域中,所以它和request的生命周期一樣。當Struts 2接受一個請求時,會創(chuàng)建ActionContext、Value-Stack和Action對象,然后把Action存放進Value-Stack,所以Action的實例變量可以通過OGNL訪問。由于Action是多實例的,和使用單例的Servlet不同, 每個Action都有一個對應的Value-Stack,Value-Stack存放的數(shù)據(jù)類型是該Action的實例,以及該Action中的實例變量,Action對象默認保存在棧頂。

414.闡述Session加載實體對象的過程。

答:Session加載實體對象的步驟是:

① Session在調用數(shù)據(jù)庫查詢功能之前, 首先會在緩存中進行查詢, 在一級緩存中, 通過實體類型和主鍵進行查找, 如果一級緩存查找命中且數(shù)據(jù)狀態(tài)合法, 則直接返回

② 如果一級緩存沒有命中, 接下來Session會在當前NonExists記錄(相當于一個查詢黑名單, 如果出現(xiàn)重復的無效查詢可以迅速判斷, 從而提升性能)中進行查找, 如果NonExists中存在同樣的查詢條件,則返回null

③ 對于load方法, 如果一級緩存查詢失敗則查詢二級緩存, 如果二級緩存命中則直接返回

④ 如果之前的查詢都未命中, 則發(fā)出SQL語句, 如果查詢未發(fā)現(xiàn)對應記錄則將此次查詢添加到Session的NonExists中加以記錄, 并返回null

⑤ 根據(jù)映射配置和SQL語句得到ResultSet,并創(chuàng)建對應的實體對象

⑥ 將對象納入Session(一級緩存)管理

⑦ 執(zhí)行攔截器的onLoad方法(如果有對應的攔截器)

⑧ 將數(shù)據(jù)對象納入二級緩存

⑨ 返回數(shù)據(jù)對象

415.怎么防止重復提交

1.禁掉提交按鈕。表單提交后使用Javascript使提交按鈕disable。這種方法防止心急的用戶多次點擊按鈕。但有個問題,如果客戶端把Javascript給禁止掉,這種方法就無效了。

2.Post/Redirect/Get模式。在提交后執(zhí)行頁面重定向,這就是所謂的Post-Redirect-Get (PRG)模式。簡言之,當用戶提交了表單后,你去執(zhí)行一個客戶端的重定向,轉到提交成功信息頁面。

這能避免用戶按F5導致的重復提交,而其也不會出現(xiàn)瀏覽器表單重復提交的警告,也能消除按瀏覽器前進和后退按導致的同樣問題。

3.在session中存放一個特殊標志。當表單頁面被請求時,生成一個特殊的字符標志串,存在session中,同時放在表單的隱藏域里。接受處理表單數(shù)據(jù)時,檢查標識字串是否存在,并立即從session中刪除它,然后正常處理數(shù)據(jù)。

如果發(fā)現(xiàn)表單提交里沒有有效的標志串,這說明表單已經(jīng)被提交過了,忽略這次提交。

4.在數(shù)據(jù)庫里添加約束。在數(shù)據(jù)庫里添加唯一約束或創(chuàng)建唯一索引,防止出現(xiàn)重復數(shù)據(jù)。這是最有效的防止重復提交數(shù)據(jù)的方法。

416.$(document).ready(function(){}) jQuery(document).ready(function(){}); 有什么區(qū)別?

window.jQuery = window.$ = jQuery;

這兩者可以互換使用。一般建議優(yōu)先使用$

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項目從瀏覽器發(fā)起交易響應緩慢,請簡述從哪些方面如數(shù)分析

從前端后端分別取考慮,后臺是不是數(shù)據(jù)庫死鎖等。

前臺看看是不是js 錯誤,或者圖片過大,dom 渲染dom樹,畫面優(yōu)化。cmd amd 規(guī)范等

設計模式
419.請寫出您熟悉的幾種設計模式,并做簡單介紹。

答:工廠設計模式:程序在接口和子類之間加入了一個過渡端,通過此過渡端可以動態(tài)取得實現(xiàn)了共同接口的子類實例化對象。

代理設計模式:指由一個代理主題來操作真實主題,真實主題執(zhí)行具體的業(yè)務操作,而代理主題負責其他相關業(yè)務的處理。比如生活中的通過代理訪問網(wǎng)絡,客戶通過網(wǎng)絡代理連接網(wǎng)絡(具體業(yè)務),由代理服務器完成用戶權限和訪問限制等與上網(wǎng)相關的其他操作(相關業(yè)務)

適配器模式:如果一個類要實現(xiàn)一個具有很多抽象方法的接口,但是本身只需要實現(xiàn)接口中的部分方法便可以達成目的,所以此時就需要一個中間的過渡類,但此過渡類又不希望直接使用,所以將此類定義為抽象類最為合適,再讓以后的子類直接繼承該抽象類便可選擇性的覆寫所需要的方法,而此抽象類便是適配器類。

420.寫出你用過的設計模式,并至少寫出2種模式的類圖或關鍵代碼。

工廠設計模式:

思路說明:由一個工廠類根據(jù)傳入的參數(shù)(一般是字符串參數(shù)),動態(tài)決定應該創(chuàng)建哪一個產(chǎn)品子類(這些產(chǎn)品子類繼承自同一個父類或接口)的實例,并以父類形式返回

優(yōu)點:客戶端不負責對象的創(chuàng)建,而是由專門的工廠類完成;客戶端只負責對象的調用,實現(xiàn)了創(chuàng)建和調用的分離,降低了客戶端代碼的難度;

缺點:如果增加和減少產(chǎn)品子類,需要修改簡單工廠類,違背了開閉原則;如果產(chǎn)品子類過多,會導致工廠類非常的龐大,違反了高內(nèi)聚原則,不利于后期維護。

public class SimpleFactory {
public static Product createProduct(String pname){
Product product=null;
if("p1".equals(pname)){
product = new Product1();
}else if("p2".equals(pname)){
product = new Product2();
}else if("pn".equals(pname)){
product = new ProductN();
}
return product;
}
}

單例模式

/**
 * 餓漢式的單例模式
 * 在類加載的時候創(chuàng)建單例實例,而不是等到第一次請求實例的時候的時候創(chuàng)建
* 1、私有 的無參數(shù)構造方法Singleton(),避免外部創(chuàng)建實例
 * 2、私有靜態(tài)屬性instance
 * 3、公有靜態(tài)方法getInstance()
 */
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton(){ }
public static Singleton getInstance(){
return instance;
}
}
/**
 * 懶漢式的單例模式
 *在類加載的時候不創(chuàng)建單例實例,只有在第一次請求實例的時候的時候創(chuàng)建
*/
public class Singleton {
private static Singleton instance;
private Singleton(){ }
/**
 * 多線程情況的單例模式,避免創(chuàng)建多個對象
*/
public static Singleton getInstance(){
if(instance ==null){//避免每次加鎖,只有第一次沒有創(chuàng)建對象時才加鎖
synchronized(Singleton.class){//加鎖,只允許一個線程進入
if(instance==null){ //只創(chuàng)建一次對象
instance = new Singleton();
}
}
}
return instance;
}}
421.列出除Singleton外的常用的3種設計模式,并簡單描述

答:工廠模式:工廠模式是 Java 中最常用的設計模式之一。這種類型的設計模式屬于創(chuàng)建型模式,它提供了一種創(chuàng)建對象的最佳方式。在工廠模式中,我們在創(chuàng)建對象時不會對客戶端暴露創(chuàng)建邏輯,并且是通過使用一個共同的接口來指向新創(chuàng)建的對象。

適配器模式:適配器模式是作為兩個不兼容的接口之間的橋梁。這種類型的設計模式屬于結構型模式,它結合了兩個獨立接口的功能。這種模式涉及到一個單一的類,該類負責加入獨立的或不兼容的接口功能。

模板模式:在模板模式中,一個抽象類公開定義了執(zhí)行它的方法的方式/模板。它的子類可以按需要重寫方法實現(xiàn),但調用將以抽象類中定義的方式進行。

422.Action是單實例還是多實例,為什么?

答:struts2中action是多例的,即一個session產(chǎn)生一個action

背景:

1) Struts2會對每一個請求,產(chǎn)生一個Action的實例來處理.

2) Spring的Ioc容器管理的bean默認是單實例的.

首先從數(shù)據(jù)安全性的問題上考慮,我們的Action應該保證是多例的,這樣才不會出現(xiàn)數(shù)據(jù)問題。但是如果有的action比如只有admin才能操作,或者某些action,全站公用一個來提高性能,這樣的話,就可以使用單例模式。

不過幸好,Spring的bean可以針對每一個設置它的scope,所以,上面的問題就不是問題了。如果用單例,就在spring的action bean配置的時候設置scope=”prototype”

如果是單例的話,若出現(xiàn)兩個用戶都修改一個對象的屬性值,則會因為用戶修改時間不同,兩個用戶訪問得到的屬性不一樣,操作得出的結果不一樣.

舉個例子:有一塊布長度300cm,能做一件上衣(用掉100cm)和一件褲子(用掉200cm);甲和乙同時訪問得到的長度都是300cm,

甲想做上衣和褲子,他先截取100cm去做上衣,等上衣做完再去做褲子,而乙這時正好也拿100cm去做上衣,那好,等甲做完上衣再做褲子的時候發(fā)現(xiàn)剩下的布(100cm)已經(jīng)不夠做褲子了…..這就是影響系統(tǒng)的性能,解決的辦法就是給甲和乙一人一塊300cm的布,就不會出現(xiàn)布被別人偷用的事情,也是就單實例和多實例的區(qū)別

如果設置成單例,那么多個線程會共享一個ActionContext和ValueStack,這樣并發(fā)訪問的時候就會出現(xiàn)問題了

struts 2的Action是多實例的并非單例,也就是每次請求產(chǎn)生一個Action的對象。原因是:struts 2的Action中包含數(shù)據(jù),例如你在頁面填寫的數(shù)據(jù)就會包含在Action的成員變量里面。如果Action是單實例的話,這些數(shù)據(jù)在多線程的環(huán)境下就會相互影響,例如造成別人填寫的數(shù)據(jù)被你看到了。所以Struts2的Action是多例模式的。

問題出現(xiàn)了,可以讓Struts2的action變成單例模式么?

Struts2中,可以使用注解開發(fā),在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;
    }
}

單例的特點:外界無法通過構造器來創(chuàng)建對象,該類必須提供一個靜態(tài)方法向外界提供該類的唯一實例。

【補充】用Java進行服務器端編程時,使用單例模式的機會還是很多的,服務器上的資源都是很寶貴的,對于那些無狀態(tài)的對象其實都可以單例化或者靜態(tài)化(在內(nèi)存中僅有唯一拷貝),如果使用了spring這樣的框架來進行對象托管,Spring的IoC容器在默認情況下對所有托管對象都是進行了單例化處理的。?

424.說說你所熟悉或聽說過的設計模式以及你對設計模式的看法

答:在GoF的《Design Patterns: Elements of Reusable Object-Oriented Software》中給出了三類(創(chuàng)建型[對類的實例化過程的抽象化]、結構型[描述如何將類或對象結合在一起形成更大的結構]、行為型[對在不同的對象之間劃分責任和算法的抽象化])共23種設計模式,包括:Abstract Factory(抽象工廠模式),Builder(建造者模式),F(xiàn)actory Method(工廠方法模式),Prototype(原始模型模式),Singleton(單例模式);Facade(門面模式),Adapter(適配器模式),Bridge(橋梁模式),Composite(合成模式),Decorator(裝飾模式),F(xiàn)lyweight(享元模式),Proxy(代理模式);Command(命令模式),Interpreter(解釋器模式),Visitor(訪問者模式),Iterator(迭代子模式),Mediator(調停者模式),Memento(備忘錄模式),Observer(觀察者模式),State(狀態(tài)模式),Strategy(策略模式),Template Method(模板方法模式), Chain Of Responsibility(責任鏈模式)。

所謂設計模式,就是一套被反復使用的代碼設計經(jīng)驗的總結(情境中一個問題經(jīng)過證實的一個解決方案)。使用設計模式是為了可重用代碼、讓代碼更容易被他人理解、保證代碼可靠性。設計模式使人們可以更加簡單方便的復用成功的設計和體系結構。將已證實的技術表述成設計模式也會使新系統(tǒng)開發(fā)者更加容易理解其設計思路。

【補充】設計模式并不是像某些地方吹噓的那樣是遙不可及的編程理念,說白了設計模式就是對面向對象的編程原則的實踐,面向對象的編程原則包括:

單一職責原則:一個類只做它該做的事情。(單一職責原則想表達的就是“高內(nèi)聚”,寫代碼最終極的原則只有六個字“高內(nèi)聚、低耦合”,就如同葵花寶典或辟邪劍譜的中心思想就八個字“欲練此功必先自宮”,所謂的高內(nèi)聚就是一個代碼模塊只完成一項功能,在面向對象中,如果只讓一個類完成它該做的事,而不涉及與它無關的領域就是踐行了高內(nèi)聚的原則,這個類就只有單一職責。我們都知道一句話叫“因為專注,所以專業(yè)”,一個對象如果承擔太多的職責,那么注定它什么都做不好。這個世界上任何好的東西都有兩個特征,一個是功能單一,好的相機絕對不是電視購物里面賣的那種一個機器有一百多種功能的,它基本上只能照相;另一個是模塊化,好的自行車是組裝車,從減震叉、剎車到變速器,所有的部件都是可以拆卸和重新組裝的,好的乒乓球拍也不是成品拍,一定是底板和膠皮可以拆分和自行組裝的,一個好的軟件系統(tǒng),它里面的每個功能模塊也應該是可以輕易的拿到其他系統(tǒng)中使用的,這樣才能實現(xiàn)軟件復用的目標。)

開閉原則:軟件實體應當對擴展開放,對修改關閉。(在理想的狀態(tài)下,當我們需要為一個軟件系統(tǒng)增加新功能時,只需要從原來的系統(tǒng)派生出一些新類就可以,不需要修改原來的任何一行代碼。要做到開閉有兩個要點:①抽象是關鍵,一個系統(tǒng)中如果沒有抽象類或接口系統(tǒng)就沒有擴展點;②封裝可變性,將系統(tǒng)中的各種可變因素封裝到一個繼承結構中,如果多個可變因素混雜在一起,系統(tǒng)將變得復雜而換亂,如果不清楚如何封裝可變性,可以參考《設計模式精解》一書中對橋梁模式的講解的章節(jié)。)

依賴倒轉原則:面向接口編程。(該原則說得直白和具體一些就是聲明方法的參數(shù)類型、方法的返回類型、變量的引用類型時,盡可能使用抽象類型而不用具體類型,因為抽象類型可以被它的任何一個子類型所替代,請參考下面的里氏替換原則。)

里氏替換原則:任何時候都可以用子類型替換掉父類型。(關于里氏替換原則的描述,Barbara Liskov女士的描述比這個要復雜得多,但簡單的說就是能用父類型的地方就一定能使用子類型。里氏替換原則可以檢查繼承關系是否合理,如果一個繼承關系違背了里氏替換原則,那么這個繼承關系一定是錯誤的,需要對代碼進行重構。例如讓貓繼承狗,或者狗繼承貓,又或者讓正方形繼承長方形都是錯誤的繼承關系,因為你很容易找到違反里氏替換原則的場景。需要注意的是:子類一定是增加父類的能力而不是減少父類的能力,因為子類比父類的能力更多,把能力多的對象當成能力少的對象來用當然沒有任何問題。)

接口隔離原則:接口要小而專,絕不能大而全。(臃腫的接口是對接口的污染,既然接口表示能力,那么一個接口只應該描述一種能力,接口也應該是高度內(nèi)聚的。例如,琴棋書畫就應該分別設計為四個接口,而不應設計成一個接口中的四個方法,因為如果設計成一個接口中的四個方法,那么這個接口很難用,畢竟琴棋書畫四樣都精通的人還是少數(shù),而如果設計成四個接口,會幾項就實現(xiàn)幾個接口,這樣的話每個接口被復用的可能性是很高的。Java中的接口代表能力、代表約定、代表角色,能否正確的使用接口一定是編程水平高低的重要標識。)

合成聚合復用原則:優(yōu)先使用聚合或合成關系復用代碼。(通過繼承來復用代碼是面向對象程序設計中被濫用得最多的東西,因為所有的教科書都無一例外的對繼承進行了鼓吹從而誤導了初學者,類與類之間簡單的說有三種關系,IS-A關系、HAS-A關系、USE-A關系,分別代表繼承、關聯(lián)和依賴。其中,關聯(lián)關系根據(jù)其關聯(lián)的強度又可以進一步劃分為關聯(lián)、聚合和合成,但說白了都是HAS-A關系,合成聚合復用原則想表達的是優(yōu)先考慮HAS-A關系而不是IS-A關系復用代碼,原因嘛可以自己從百度上找到一萬個理由,需要說明的是,即使在Java的API中也有不少濫用繼承的例子,例如Properties類繼承了Hashtable類,Stack類繼承了Vector類,這些繼承明顯就是錯誤的,更好的做法是在Properties類中放置一個Hashtable類型的成員并且將其鍵和值都設置為字符串來存儲數(shù)據(jù),而Stack類的設計也應該是在Stack類中放一個Vector對象來存儲數(shù)據(jù)。記?。喝魏螘r候都不要繼承工具類,工具是可以擁有并可以使用的(HAS/USE),而不是拿來繼承的。)

迪米特法則:迪米特法則又叫最少知識原則,一個對象應當對其他對象有盡可能少的了解。(迪米特法則簡單的說就是如何做到“低耦合”,門面模式和調停者模式就是對迪米特法則的踐行。對于門面模式可以舉一個簡單的例子,你去一家公司洽談業(yè)務,你不需要了解這個公司內(nèi)部是如何運作的,你甚至可以對這個公司一無所知,去的時候只需要找到公司入口處的前臺美女,告訴她們你要做什么,她們會找到合適的人跟你接洽,前臺的美女就是公司這個系統(tǒng)的門面。再復雜的系統(tǒng)都可以為用戶提供一個簡單的門面,Java Web開發(fā)中作為前端控制器的Servlet或Filter不就是一個門面嗎,瀏覽器對服務器的運作方式一無所知,但是通過前端控制器就能夠根據(jù)你的請求得到相應的服務。調停者模式也可以舉一個簡單的例子來說明,例如一臺計算機,CPU、內(nèi)存、硬盤、顯卡、聲卡各種設備需要相互配合才能很好的工作,但是如果這些東西都直接連接到一起,計算機的布線將異常復雜,在這種情況下,主板作為一個調停者的身份出現(xiàn),它將各個設備連接在一起而不需要每個設備之間直接交換數(shù)據(jù),這樣就減小了系統(tǒng)的耦合度和復雜度。迪米特法則用通俗的話來將就是不要和陌生人打交道,如果真的需要,找一個自己的朋友,讓他替你和陌生人打交道。)

425.Java企業(yè)級開發(fā)中常用的設計模式有哪些?

答: 按照分層開發(fā)的觀點,可以將應用劃分為:表示層、業(yè)務邏輯層和持久層,每一層都有屬于自己類別的設計模式。

表示層設計模式:

1) Interceptor Filter:攔截過濾器,提供請求預處理和后處理的方案,可以對請求和響應進行過濾。/p>

2) Front Controller:通過中央控制器提供請求管理和處理,管理內(nèi)容讀取、安全性、視圖管理和導航等功能。Struts 2中的StrutsPrepareAndExecuteFilter、Spring MVC中的DispatcherServlet都是前端控制器,后者如下圖所示:

3) View Helper:視圖幫助器,負責將顯示邏輯和業(yè)務邏輯分開。顯示的部分放在視圖組件中,業(yè)務邏輯代碼放在幫助器中,典型的功能是內(nèi)容讀取、驗證與適配。

4) Composite View:復合視圖。

業(yè)務邏輯層設計模式:

1) Business Delegate:業(yè)務委托,減少表示層和業(yè)務邏輯層之間的耦合。

2) Value Object:值對象,解決層之間交換數(shù)據(jù)的開銷問題。

3) Session Fa?ade:會話門面,隱藏業(yè)務邏輯組件的細節(jié),集中工作流程。

4) Value Object Assembler:靈活的組裝不同的值對象

5) Value List Handler:提供執(zhí)行查詢和處理結果的解決方案,還可以緩存查詢結果,從而達到提升性能的目的。

6) Service Locator:服務定位器,可以查找、創(chuàng)建和定位服務工廠,封裝其實現(xiàn)細節(jié),減少復雜性,提供單個控制點,通過緩存提高性能。

持久層設計模式:

Data Access Object:數(shù)據(jù)訪問對象,以面向對象的方式完成對數(shù)據(jù)的增刪改查。

【補充】如果想深入的了解Java企業(yè)級應用的設計模式和架構模式,可以參考這些書籍:?《Pro Java EE Spring Patterns》、《POJO in Action》、《Patterns of Enterprise Application Architecture》。

426.你在開發(fā)中都用到了那些設計模式?用在什么場合?

答:面試被問到關于設計模式的知識時,可以揀最常用的作答,例如:

1) 工廠模式:工廠類可以根據(jù)條件生成不同的子類實例,這些子類有一個公共的抽象父類并且實現(xiàn)了相同的方法,但是這些方法針對不同的數(shù)據(jù)進行了不同的操作(多態(tài)方法)。當?shù)玫阶宇惖膶嵗?,開發(fā)人員可以調用基類中的方法而不必考慮到底返回的是哪一個子類的實例。

2) 代理模式:給一個對象提供一個代理對象,并由代理對象控制原對象的引用。實際開發(fā)中,按照使用目的的不同,代理可以分為:遠程代理、虛擬代理、保護代理、Cache代理、防火墻代理、同步化代理、智能引用代理。

3) 適配器模式:把一個類的接口變換成客戶端所期待的另一種接口,從而使原本因接口不匹配而無法在一起使用的類能夠一起工作。

4) 模板方法模式:提供一個抽象類,將部分邏輯以具體方法或構造器的形式實現(xiàn),然后聲明一些抽象方法來迫使子類實現(xiàn)剩余的邏輯。不同的子類可以以不同的方式實現(xiàn)這些抽象方法(多態(tài)實現(xiàn)),從而實現(xiàn)不同的業(yè)務邏輯。

除此之外,還可以講講上面提到的門面模式、橋梁模式、單例模式、裝潢模式(Collections工具類里面的synchronizedXXX方法把一個線程不安全的容器變成線程安全容器就是對裝潢模式的應用,而Java IO里面的過濾流(有的翻譯成處理流)也是應用裝潢模式的經(jīng)典例子)等,反正原則就是揀自己最熟悉的用得最多的作答,以免言多必失。?

427.什么是設計模式,設計模式的作用。

設計模式是一套被反復使用的、多數(shù)人知曉、經(jīng)過分類編目的優(yōu)秀代碼設計經(jīng)驗的總結。特定環(huán)境下特定問題的處理方法。

1)重用設計和代碼 重用設計比重用代碼更有意義,自動帶來代碼重用

2)提高擴展性 大量使用面向接口編程,預留擴展插槽,新的功能或特性很容易加入到系統(tǒng)中來

3)提高靈活性 通過組合提高靈活性,可允許代碼修改平穩(wěn)發(fā)生,對一處修改不會波及到其他模塊

4) 提高開發(fā)效率 正確使用設計模式,可以節(jié)省大量的時間

428.23種經(jīng)典設計模式都有哪些,如何分類。
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;
}
}

基本原理:由一個工廠類根據(jù)傳入的參數(shù)(一般是字符串參數(shù)),動態(tài)決定應該創(chuàng)建哪一個產(chǎn)品子類(這些產(chǎn)品子類繼承自同一個父類或接口)的實例,并以父類形式返回

優(yōu)點:客戶端不負責對象的創(chuàng)建,而是由專門的工廠類完成;客戶端只負責對象的調用,實現(xiàn)了創(chuàng)建和調用的分離,降低了客戶端代碼的難度;

缺點:如果增加和減少產(chǎn)品子類,需要修改簡單工廠類,違背了開閉原則;如果產(chǎn)品子類過多,會導致工廠類非常的龐大,違反了高內(nèi)聚原則,不利于后期維護

430.請對你所熟悉的一個設計模式進行介紹

分析:建議挑選有一定技術難度,并且在實際開發(fā)中應用較多的設計模式。可以挑選裝飾模式和動態(tài)代理模式。此處挑選動態(tài)代理設計模式。

講解思路:生活案例引入、技術講解、優(yōu)缺點分析、典型應用。

1、生活案例引入:送生日蛋糕:

MM們要過生日了,怎么也得表示下吧。最起碼先送個蛋糕。蛋糕多種多樣了。巧克力,冰淇淋,奶油等等。這都是基本的了,再加點額外的裝飾,如蛋糕里放點花、放賀卡、放點干果吃著更香等等。

分析:

方案1:如果采用繼承會造成大量的蛋糕子類

方案2:蛋糕作為主體,花,賀卡,果仁等是裝飾者,需要時加到蛋糕上。要啥我就加啥。

技術講解

裝飾模式(別名Wrapper)是在不必改變原類文件和使用繼承的情況下,動態(tài)的擴展一個對象的功能。它通過創(chuàng)建一個包裝對象,也就是裝飾來包裹真實對象,提供了比繼承更具彈性的代替方案。

裝飾模式一般涉及到的角色

抽象構建角色(Component):給出一個抽象的接口,以規(guī)范準備接受附加責任的對象。

具體的構建角色(ConcreteComponent):定義一個將要接受附加責任的類。

抽象的裝飾角色 (Decorator):持有一個抽象構建(Component)角色的引用,并定義一個與抽象構件一致的接口。

具體的裝飾角色(ConcreteDecorator):負責給構建對象“貼上”附加的責任。

3、優(yōu)缺點分析

優(yōu)點

1)Decorator模式與繼承關系的目的都是要擴展對象的功能,但是Decorato更多的靈活性。

2)把類中的裝飾功能從類中搬移出去,這樣可以簡化原有的類。有效地把類的核心功能和裝飾功能區(qū)分開了。

3)通過使用不同的具體裝飾類以及這些裝飾類的排列組合,可創(chuàng)造出很多不同行為的組合。

缺點

這種比繼承更加靈活機動的特性,也同時意味著更加多的復雜性。

裝飾模式會導致設計中出現(xiàn)許多小類,如果過度使用,會使程序變得很復雜。

符合的設計原則:

多用組合,少用繼承。利用繼承設計子類的行為是在編譯時靜態(tài)決定的,且所有的子類都會繼承到相同的行為。如能夠利用組合擴展對象的行為,就可在運行時動態(tài)進行擴展。

類應設計的對擴展開放,對修改關閉。

4、典型應用

java IO中需要完成對不同輸入輸出源的操作,如果單純的使用繼承這一方式,無疑需要很多的類。比如說,我們操作文件需要一個類,實現(xiàn)文件的字節(jié)讀取需要一個類,實現(xiàn)文件的字符讀取又需要一個類....一次類推每個特定的操作都需要一個特定的類。這無疑會導致大量的IO繼承類的出現(xiàn)。顯然對于編程是很不利的。而是用裝飾模式則可以很好的解決這一問題,在裝飾模式中:節(jié)點流(如FileInputStream)直接與輸入源交互,之后通過過濾流(FilterInputStream)進行裝飾,這樣獲得的io對象便具有某幾個的功能,很好的拓展了IO的功能。

高級框架

431.什么是Maven?

Maven使用項目對象模型(POM)的概念,可以通過一小段描述信息來管理項目的構建,報告和文檔的軟件項目管理工具。

Maven 除了以程序構建能力為特色之外,還提供高級項目管理工具。由于 Maven 的缺省構建規(guī)則有較高的可重用性,所以常常用兩三行 Maven 構建腳本就可以構建簡單的項目。由于 Maven 的面向項目的方法,許多 Apache Jakarta 項目發(fā)布時使用 Maven,而且公司項目采用 Maven 的比例在持續(xù)增長。

Maven的出現(xiàn),解決了開發(fā)過程中的jar包升級及依賴的難題。它可以對項目依賴的jar包進行管理,可以讓你的項目保持基本的依賴,排除冗余jar包,并且可以讓你非常輕松的對依賴的jar包進行版本升級。而這些僅僅是Maven最基本的功能,它可以在這基礎上對項目進行清理、編譯、測試、打包、發(fā)布等等構建項目的工作。?

可以說,Maven是現(xiàn)在Java社區(qū)中最強大的項目管理和項目構建工具,而更加值得慶幸的是,這樣一個強大的工具,它的使用也是非常簡單的。

現(xiàn)在,JavaEE項目使用的開源軟件都可以通過Maven來獲取,并且,越來越多的公司也開始使用Maven來管理構建項目了。

432.Maven和ANT的區(qū)別

1.maven&ant同屬apach是流行的構建工具。

都是為了簡化軟件開發(fā)而存在的。但是maven因為自身管理一個項目對象模型(project object model),這個模型其實就是抽象了一個項目的開發(fā)流程,它包含了一個項目的生命周期的各個階段,并將這個周期固定下來,這也就是約定大于配置。約定大于配置的意思就是,我maven將項目開發(fā)的各個階段固定起來了,每個文件的存放位置,每個階段要生成什么文件、保存為什么格式并且要把它放在什么位置,我都固定好了。我知道一個軟件是怎么開發(fā)出來,如果一個項目要使用maven,可以,但你要遵循我的規(guī)則,文件目錄不要亂建亂放,只有這樣maven才會將源碼用起來。這就是約定大于配置,因為maven已經(jīng)將流程固定下來了,只要遵守約定,就不需要自己手動去配置了,這將大大地提高開發(fā)效率。就像是開車一樣,只要知道點火、油門、方向、剎車,就可以將車子開東起來(當然出于安全和法律考慮,還是要考駕照的。),關于車子內(nèi)部的傳動原理,電氣原理,工程原理,普通人并不需要了解多少,日常夠用就好了。這也是約定大于配置的一個例子。配置就是自己造一輛車去開,有必要,有能力,有時間嗎?

2.maven的中央倉庫和pom.xml文件。中央倉庫統(tǒng)一存放了開發(fā)用到的各種jar包,要用時只需要添加依賴到pom文件中,maven就會自動下載,當然為了方便一般會在本地建一個倉庫,減少下載時間。pom文件是maven的配置文件,maven就是通過管理pom文件和一些核心插件來管理項目。當然我前面將maven擬人化了,其實maven是沒有智力的,一切都是封裝好的流程,只是maven將很多操作隱藏起來了。

3.ant的build.xml文件。build文件是ant的配置文件,ant依靠它來執(zhí)行操作,與maven不同的是ant沒有固定一條程序鏈。你想要執(zhí)行什么操作以及操作之間的順序和依賴關系,都需要手動添加到build文件中,一點一滴都要寫清楚,否則ant就不會執(zhí)行。

4.maven和ant區(qū)別

Maven 擁有約定,只要遵守約定,它就知道你的源代碼在哪里。Maven 是聲明式的。你需要做的只是創(chuàng)建一個 pom.xml 文件然后將源代碼放到默認的目錄。Maven 會幫你處理其它的事情。Maven 有一個生命周期,當你運行 mvn install 的時候被調用。這條命令告訴 Maven 執(zhí)行一系列的有序的步驟,直到到達你指定的生命周期。缺點是運行許多默認目標。

而ant沒有約定,項目生命周期,它是命令式的。所有操作都要手動去創(chuàng)建、布置。甚至連build.xml文件都需要手動創(chuàng)建。

433.Maven倉庫是什么

Maven倉庫是基于簡單文件系統(tǒng)存儲的,集中化管理Java API資源(構件)的一個服務。倉庫中的任何一個構件都有其唯一的坐標,根據(jù)這個坐標可以定義其在倉庫中的唯一存儲路徑。得益于 Maven 的坐標機制,任何 Maven項目使用任何一個構件的方式都是完全相同的,Maven 可以在某個位置統(tǒng)一存儲所有的 Maven 項目共享的構件,這個統(tǒng)一的位置就是倉庫,項目構建完畢后生成的構件也可以安裝或者部署到倉庫中,供其它項目使用。

對于Maven來說,倉庫分為兩類:本地倉庫和遠程倉庫。

434.Maven的工程類型有哪些?

POM工程

POM工程是邏輯工程。用在父級工程或聚合工程中。用來做jar包的版本控制。

JAR工程

將會打包成jar用作jar包使用。即常見的本地工程 - Java Project。

WAR工程

將會打包成war,發(fā)布在服務器上的工程。如網(wǎng)站或服務。即常見的網(wǎng)絡工程 - 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的作用是什么?

配置管理

在我們的應用中除了代碼外,還有一些就是各種配置。比如數(shù)據(jù)庫連接等。一般我們都是使用配置文件的方式,在代碼中引入這些配置文件。當我們只有一種配置,只有一臺服務器,并且不經(jīng)常修改的時候,使用配置文件是一個很好的做法,但是如果我們配置非常多,有很多服務器都需要這個配置,這時使用配置文件就不是個好主意了。這個時候往往需要尋找一種集中管理配置的方法,我們在這個集中的地方修改了配置,所有對這個配置感興趣的都可以獲得變更。Zookeeper就是這種服務,它使用Zab這種一致性協(xié)議來提供一致性?,F(xiàn)在有很多開源項目使用Zookeeper來維護配置,比如在HBase中,客戶端就是連接一個Zookeeper,獲得必要的HBase集群的配置信息,然后才可以進一步操作。還有在開源的消息隊列Kafka中,也使用Zookeeper來維護broker的信息。在Alibaba開源的SOA框架Dubbo中也廣泛的使用Zookeeper管理一些配置來實現(xiàn)服務治理。

名字服務

名字服務這個就很好理解了。比如為了通過網(wǎng)絡訪問一個系統(tǒng),我們得知道對方的IP地址,但是IP地址對人非常不友好,這個時候我們就需要使用域名來訪問。但是計算機是不能是域名的。怎么辦呢?如果我們每臺機器里都備有一份域名到IP地址的映射,這個倒是能解決一部分問題,但是如果域名對應的IP發(fā)生變化了又該怎么辦呢?于是我們有了DNS這個東西。我們只需要訪問一個大家熟知的(known)的點,它就會告訴你這個域名對應的IP是什么。在我們的應用中也會存在很多這類問題,特別是在我們的服務特別多的時候,如果我們在本地保存服務的地址的時候將非常不方便,但是如果我們只需要訪問一個大家都熟知的訪問點,這里提供統(tǒng)一的入口,那么維護起來將方便得多了。

分布式鎖

其實在第一篇文章中已經(jīng)介紹了Zookeeper是一個分布式協(xié)調服務。這樣我們就可以利用Zookeeper來協(xié)調多個分布式進程之間的活動。比如在一個分布式環(huán)境中,為了提高可靠性,我們的集群的每臺服務器上都部署著同樣的服務。但是,一件事情如果集群中的每個服務器都進行的話,那相互之間就要協(xié)調,編程起來將非常復雜。而如果我們只讓一個服務進行操作,那又存在單點。通常還有一種做法就是使用分布式鎖,在某個時刻只讓一個服務去干活,當這臺服務出問題的時候鎖釋放,立即fail over到另外的服務。這在很多分布式系統(tǒng)中都是這么做,這種設計有一個更好聽的名字叫Leader Election(leader選舉)。比如HBase的Master就是采用這種機制。但要注意的是分布式鎖跟同一個進程的鎖還是有區(qū)別的,所以使用的時候要比同一個進程里的鎖更謹慎的使用。

集群管理

在分布式的集群中,經(jīng)常會由于各種原因,比如硬件故障,軟件故障,網(wǎng)絡問題,有些節(jié)點會進進出出。有新的節(jié)點加入進來,也有老的節(jié)點退出集群。這個時候,集群中其他機器需要感知到這種變化,然后根據(jù)這種變化做出對應的決策。比如我們是一個分布式存儲系統(tǒng),有一個中央控制節(jié)點負責存儲的分配,當有新的存儲進來的時候我們要根據(jù)現(xiàn)在集群目前的狀態(tài)來分配存儲節(jié)點。這個時候我們就需要動態(tài)感知到集群目前的狀態(tài)。還有,比如一個分布式的SOA架構中,服務是一個集群提供的,當消費者訪問某個服務時,就需要采用某種機制發(fā)現(xiàn)現(xiàn)在有哪些節(jié)點可以提供該服務(這也稱之為服務發(fā)現(xiàn),比如Alibaba開源的SOA框架Dubbo就采用了Zookeeper作為服務發(fā)現(xiàn)的底層機制)。還有開源的Kafka隊列就采用了Zookeeper作為Cosnumer的上下線管理。

437.什么是Znode?

在Zookeeper中,znode是一個跟Unix文件系統(tǒng)路徑相似的節(jié)點,可以往這個節(jié)點存儲或獲取數(shù)據(jù)。

Zookeeper底層是一套數(shù)據(jù)結構。這個存儲結構是一個樹形結構,其上的每一個節(jié)點,我們稱之為“znode”

zookeeper中的數(shù)據(jù)是按照“樹”結構進行存儲的。而且znode節(jié)點還分為4中不同的類型。

每一個znode默認能夠存儲1MB的數(shù)據(jù)(對于記錄狀態(tài)性質的數(shù)據(jù)來說,夠了)

可以使用zkCli命令,登錄到zookeeper上,并通過ls、create、delete、get、set等命令操作這些znode節(jié)點

438.Znode節(jié)點類型有哪些?

答:(1)PERSISTENT 持久化節(jié)點: 所謂持久節(jié)點,是指在節(jié)點創(chuàng)建后,就一直存在,直到有刪除操作來主動清除這個節(jié)點。否則不會因為創(chuàng)建該節(jié)點的客戶端會話失效而消失。

(2)PERSISTENT_SEQUENTIAL 持久順序節(jié)點:這類節(jié)點的基本特性和上面的節(jié)點類型是一致的。額外的特性是,在ZK中,每個父節(jié)點會為他的第一級子節(jié)點維護一份時序,會記錄每個子節(jié)點創(chuàng)建的先后順序?;谶@個特性,在創(chuàng)建子節(jié)點的時候,可以設置這個屬性,那么在創(chuàng)建節(jié)點過程中,ZK會自動為給定節(jié)點名加上一個數(shù)字后綴,作為新的節(jié)點名。這個數(shù)字后綴的范圍是整型的最大值。?在創(chuàng)建節(jié)點的時候只需要傳入節(jié)點 “/test_”,這樣之后,zookeeper自動會給”test_”后面補充數(shù)字。

(3)EPHEMERAL 臨時節(jié)點:和持久節(jié)點不同的是,臨時節(jié)點的生命周期和客戶端會 話綁定。也就是說,如果客戶端會話失效,那么這個節(jié)點就會自動被清除掉。注意,這里提到的是會話失效,而非連接斷開。另外,在臨時節(jié)點下面不能創(chuàng)建子節(jié)點。?

這里還要注意一件事,就是當你客戶端會話失效后,所產(chǎn)生的節(jié)點也不是一下子就消失了,也要過一段時間,大概是10秒以內(nèi),可以試一下,本機操作生成節(jié)點,在服務器端用命令來查看當前的節(jié)點數(shù)目,你會發(fā)現(xiàn)客戶端已經(jīng)stop,但是產(chǎn)生的節(jié)點還在。

EPHEMERAL_SEQUENTIAL 臨時自動編號節(jié)點:此節(jié)點是屬于臨時節(jié)點,不過帶有順序,客戶端會話結束節(jié)點就消失。

439.什么是Dubbo?

Dubbo是阿里巴巴公司開源的一個高性能優(yōu)秀的服務框架,使得應用可通過高性能的 RPC 實現(xiàn)服務的輸出和輸入功能,可以和Spring框架無縫集成。Dubbo框架,是基于容器運行的.。容器是Spring。

其核心部分包含:

1. 遠程通訊: 提供對多種基于長連接的NIO框架抽象封裝,包括多種線程模型,序列化,以及“請求-響應”模式的信息交換方式。

2. 集群容錯: 提供基于接口方法的透明遠程過程調用,包括多協(xié)議支持,以及軟負載均衡,失敗容錯,地址路由,動態(tài)配置等集群支持。

3. 自動發(fā)現(xiàn): 基于注冊中心目錄服務,使服務消費方能動態(tài)的查找服務提供方,使地址透明,使服務提供方可以平滑增加或減少機器。

Dubbo能做什么?

1.透明化的遠程方法調用,就像調用本地方法一樣調用遠程方法,只需簡單配置,沒有任何API侵入。 ? ? ?

2.軟負載均衡及容錯機制,可在內(nèi)網(wǎng)替代F5等硬件負載均衡器,降低成本,減少單點。

3. 服務自動注冊與發(fā)現(xiàn),不再需要寫死服務提供方地址,注冊中心基于接口名查詢服務提供者的IP地址,并且能夠平滑添加或刪除服務提供者。

Dubbo的存在簡單來說就是要減小service層的壓力。

440.什么是RPC遠程過程調用?

遠程過程調用協(xié)議,它是一種通過網(wǎng)絡從遠程計算機程序上請求服務,而不需要了解底層網(wǎng)絡技術的協(xié)議。RPC協(xié)議假定某些傳輸協(xié)議的存在,如TCP或UDP,為通信程序之間攜帶信息數(shù)據(jù)。在OSI網(wǎng)絡通信模型中,RPC跨越了傳輸層和應用層。RPC使得開發(fā)包括網(wǎng)絡分布式多程序在內(nèi)的應用程序更加容易。

441.Dubbo中有哪些角色?

registry

注冊中心. 是用于發(fā)布和訂閱服務的一個平臺.用于替代SOA結構體系框架中的ESB服務總線的。

發(fā)布

開發(fā)服務端代碼完畢后, 將服務信息發(fā)布出去. 實現(xiàn)一個服務的公開.

訂閱

客戶端程序,從注冊中心下載服務內(nèi)容 這個過程是訂閱.

訂閱服務的時候, 會將發(fā)布的服務所有信息,一次性下載到客戶端.

客戶端也可以自定義, 修改部分服務配置信息. 如: 超時的時長, 調用的重試次數(shù)等.

Consumer

服務的消費者, 就是服務的客戶端.

消費者必須使用Dubbo技術開發(fā)部分代碼. 基本上都是配置文件定義.

provider

服務的提供者, 就是服務端.

服務端必須使用Dubbo技術開發(fā)部分代碼. 以配置文件為主.

container

容器. Dubbo技術的服務端(Provider), 在啟動執(zhí)行的時候, 必須依賴容器才能正常啟動.

默認依賴的就是spring容器. 且Dubbo技術不能脫離spring框架.

在2.5.3版本的dubbo中, 默認依賴的是spring2.5版本技術. 可以選用spring4.5以下版本.

在2.5.7版本的dubbo中, 默認依賴的是spring4.3.10版本技術. 可以選擇任意的spring版本.

monitor

監(jiān)控中心. 是Dubbo提供的一個jar工程.

主要功能是監(jiān)控服務端(Provider)和消費端(Consumer)的使用數(shù)據(jù)的. 如: 服務端是什么,有多少接口,多少方法, 調用次數(shù), 壓力信息等. 客戶端有多少, 調用過哪些服務端, 調用了多少次等.

442.Dubbo執(zhí)行流程什么是?

0 start: 啟動Spring容器時,自動啟動Dubbo的Provider

1、register: Dubbo的Provider在啟動后自動會去注冊中心注冊內(nèi)容.注冊的內(nèi)容包括:

1.1 Provider的 IP

1.2 Provider 的端口.

1.3 Provider 對外提供的接口列表.哪些方法.哪些接口類

1.4 Dubbo 的版本.

1.5 訪問Provider的協(xié)議.

2、subscribe: 訂閱.當Consumer啟動時,自動去Registry獲取到所已注冊的服務的信息.

3、notify: 通知.當Provider的信息發(fā)生變化時, 自動由Registry向Consumer推送通知.

4、invoke: 調用. Consumer 調用Provider中方法

4.1 同步請求.消耗一定性能.但是必須是同步請求,因為需要接收調用方法后的結果.

5、count:次數(shù). 每隔2分鐘,provoider和consumer自動向Monitor發(fā)送訪問次數(shù).Monitor進行統(tǒng)計.

443.說說Dubbo支持的協(xié)議有哪些?

1、Dubbo協(xié)議(官方推薦協(xié)議)

優(yōu)點:

采用NIO復用單一長連接,并使用線程池并發(fā)處理請求,減少握手和加大并發(fā)效率,性能較好(推薦使用)

缺點:

大文件上傳時,可能出現(xiàn)問題(不使用Dubbo文件上傳)

2、RMI(Remote Method Invocation)協(xié)議

優(yōu)點:

JDK自帶的能力??膳c原生RMI互操作,基于TCP協(xié)議

缺點:

偶爾連接失敗.

3、Hessian協(xié)議

優(yōu)點:

可與原生Hessian互操作,基于HTTP協(xié)議

缺點:

需hessian.jar支持,http短連接的開銷大

444.Dubbo支持的注冊中心有哪些?

1、Zookeeper(官方推薦)

優(yōu)點:支持分布式.很多周邊產(chǎn)品.

缺點: 受限于Zookeeper軟件的穩(wěn)定性.Zookeeper專門分布式輔助軟件,穩(wěn)定較優(yōu)

2、Multicast

優(yōu)點:去中心化,不需要單獨安裝軟件.

缺點:Provider和Consumer和Registry不能跨機房(路由)

3、Redis

優(yōu)點:支持集群,性能高

缺點:要求服務器時間同步.否則可能出現(xiàn)集群失敗問題.

4、Simple

優(yōu)點: 標準RPC服務.沒有兼容問題

缺點: 不支持集群.

445.SessionFactory是線程安全的嗎?Session是線程安全的嗎,兩個線程能夠共享同一個Session嗎?

答:SessionFactory對應Hibernate的一個數(shù)據(jù)存儲的概念,它是線程安全的,可以被多個線程并發(fā)訪問。SessionFactory一般只會在啟動的時候構建。對于應用程序,最好將SessionFactory通過單例的模式進行封裝以便于訪問。Session是一個輕量級非線程安全的對象(線程間不能共享session),它表示與數(shù)據(jù)庫進行交互的一個工作單元。Session是由SessionFactory創(chuàng)建的,在任務完成之后它會被關閉。Session是持久層服務對外提供的主要接口。Session會延遲獲取數(shù)據(jù)庫連接(也就是在需要的時候才會獲?。榱吮苊鈩?chuàng)建太多的session,可以使用ThreadLocal來取得當前的session,無論你調用多少次getCurrentSession()方法,返回的都是同一個session。

446.Session的load和get方法的區(qū)別是什么?

答:主要有以下三項區(qū)別:

1)如果沒有找到符合條件的記錄, get方法返回null,load方法拋出異常

2)get方法直接返回實體類對象, load方法返回實體類對象的代理

3)在Hibernate 3之前,get方法只在一級緩存(內(nèi)部緩存)中進行數(shù)據(jù)查找, 如果沒有找到對應的數(shù)據(jù)則越過二級緩存, 直接發(fā)出SQL語句完成數(shù)據(jù)讀取; load方法則可以充分利用二級緩存中的現(xiàn)有數(shù)據(jù);當然從Hibernate 3開始,get方法不再是對二級緩存只寫不讀,它也是可以訪問二級緩存的

簡單的說,對于load()方法Hibernate認為該數(shù)據(jù)在數(shù)據(jù)庫中一定存在可以放心的使用代理來實現(xiàn)延遲加載,如果沒有數(shù)據(jù)就拋出異常,而通過get()方法去取的數(shù)據(jù)可以不存在。

447.Session的save()、update()、merge()、lock()、saveOrUpdate()和persist()方法有什么區(qū)別?

答:Hibernate的對象有三種狀態(tài):瞬態(tài)、持久態(tài)和游離態(tài)。游離狀態(tài)的實例可以通過調用save()、persist()或者saveOrUpdate()方法進行持久化;脫管狀態(tài)的實例可以通過調用 update()、0saveOrUpdate()、lock()或者replicate()進行持久化。save()和persist()將會引發(fā)SQL的INSERT語句,而update()或merge()會引發(fā)UPDATE語句。save()和update()的區(qū)別在于一個是將瞬態(tài)對象變成持久態(tài),一個是將游離態(tài)對象變?yōu)槌志脩B(tài)。merge方法可以完成save()和update()方法的功能,它的意圖是將新的狀態(tài)合并到已有的持久化對象上或創(chuàng)建新的持久化對象。按照官方文檔的說明:(1)persist()方法把一個瞬態(tài)的實例持久化,但是并"不保證"標識符被立刻填入到持久化實例中,標識符的填入可能被推遲到flush的時間;(2) persist"保證",當它在一個事務外部被調用的時候并不觸發(fā)一個Insert語句,當需要封裝一個長會話流程的時候,一個persist這樣的函數(shù)是需要的。(3)save"不保證"第2條,它要返回標識符,所以它會立即執(zhí)行Insert語句,不管是不是在事務內(nèi)部還是外部。update()方法是把一個已經(jīng)更改過的脫管狀態(tài)的對象變成持久狀態(tài);lock()方法是把一個沒有更改過的脫管狀態(tài)的對象變成持久狀態(tài)。

448.什么是VSFTPD?

vsftpd 是“very secure FTP daemon”的縮寫,安全性是它的一個最大的特點。vsftpd 是一個 UNIX 類操作系統(tǒng)上運行的服務器的名字,它可以運行在諸如 Linux、BSD、Solaris、 HP-UNIX等系統(tǒng)上面,是一個完全免費的、開放源代碼的ftp服務器軟件,支持很多其他的 FTP 服務器所不支持的特征。

449.什么是Nginx?

Nginx?(engine x) 是一個高性能的HTTP和反向代理服務。Nginx是由伊戈爾·賽索耶夫為俄羅斯訪問量第二的Rambler.ru站點(俄文:Рамблер)開發(fā)的,第一個公開版本0.1.0發(fā)布于2004年10月4日。

Nginx 是一個很強大的高性能Web和反向代理服務,它具有很多非常優(yōu)越的特性:在連接高并發(fā)的情況下,Nginx是Apache服務不錯的替代品:Nginx在美國是做虛擬主機生意的老板們經(jīng)常選擇的軟件平臺之一。

450.Nginx有哪些作用?

答:http協(xié)議代理

搭建虛擬主機

服務的反向代理

在反向代理中配置集群的負載均衡

451.什么是正向代理?

正向代理,意思是一個位于客戶端和原始服務器(origin server)之間的服務器,為了從原始服務器取得內(nèi)容,客戶端向代理發(fā)送一個請求并指定目標(原始服務器),然后代理向原始服務器轉交請求并將獲得的內(nèi)容返回給客戶端??蛻舳瞬拍苁褂谜虼怼?/p>

452.什么是反向代理?

反向代理(Reverse Proxy)方式是指以代理服務器來接受internet上的連接請求,然后將請求轉發(fā)給內(nèi)部網(wǎng)絡上的服務器,并將從服務器上得到的結果返回給internet上請求連接的客戶端,此時代理服務器對外就表現(xiàn)為一個反向代理服務器。

453.什么是Redis?

答:Remote Dictionary Server(Redis)是一個開源的使用ANSI?C語言編寫、支持網(wǎng)絡、可基于內(nèi)存亦可持久化的日志型、Key-Value數(shù)據(jù)庫,并提供多種語言的API。

它通常被稱為數(shù)據(jù)結構服務器,因為值(value)可以是 字符串(String), 哈希(Map), 列表(list), 集合(sets) 和 有序集合(sorted sets)等類型。

454.Redis的特點什么是?

1. 支持多種數(shù)據(jù)結構,如 string(字符串)、 list(雙向鏈表)、dict(hash表)、set(集合)、zset(排序set)、hyperloglog(基數(shù)估算)

2. 支持持久化操作,可以進行aof及rdb數(shù)據(jù)持久化到磁盤,從而進行數(shù)據(jù)備份或數(shù)據(jù)恢復等操作,較好的防止數(shù)據(jù)丟失的手段。

3. 支持通過Replication進行數(shù)據(jù)復制,通過master-slave機制,可以實時進行數(shù)據(jù)的同步復制,支持多級復制和增量復制,master-slave機制是Redis進行HA的重要手段。

單進程請求,所有命令串行執(zhí)行,并發(fā)情況下不需要考慮數(shù)據(jù)一致性問題。

455.Redis數(shù)據(jù)類型有哪些?

答:String(字符串)

Hash(hash表)

List(鏈表)

Set(集合)

SortedSet(有序集合zset)

456.Redis中的常用命令哪些?

incr 讓當前鍵值以1的數(shù)量遞增,并返回遞增后的值

incrby 可以指定參數(shù)一次增加的數(shù)值,并返回遞增后的值

incrby 可以指定參數(shù)一次增加的數(shù)值,并返回遞增后的值

decrby 可以指定參數(shù)一次遞減的數(shù)值,并返回遞減后的值

incrbyfloat 可以遞增一個雙精度浮點數(shù)

append 作用是向鍵值的末尾追加value。如果鍵不存在則將該鍵的值設置為value。返回值是追加后字符串的總長度。

mget/mset 作用與get/set相似,不過mget/mset可以同時獲得/設置多個鍵的鍵值

del 根據(jù)key來刪除value

flushdb 清除當前庫的所有數(shù)據(jù)

hset 存儲一個哈希鍵值對的集合

hget獲取一個哈希鍵的值

hmset 存儲一個或多個哈希是鍵值對的集合

hmget 獲取多個指定的鍵的值

hexists 判斷哈希表中的字段名是否存在 如果存在返回1 否則返回0

hdel 刪除一個或多個字段

hgetall 獲取一個哈希是鍵值對的集合

hvals 只返回字段值

hkeys 只返回字段名

hlen 返回key的hash的元素個數(shù)

lpush key value向鏈表左側添加

rpush key value向鏈表右側添加

lpop key 從左邊移出一個元素

rpop key 從右邊移出一個元素

llen key 返回鏈表中元素的個數(shù) 相當于關系型數(shù)據(jù)庫中 select count(*)

lrange key start end lrange命令將返回索引從start到stop之間的所有元素。Redis的列表起始索引為0。

lrange也支持負索引 lrange nn -2 -1 如 -1表示最右邊第一個元素 -2表示最右邊第二個元素,依次類推。

lindex key indexnumber 如果要將列表類型當做數(shù)組來用,lindex命令是必不可少的。lindex命令用來返回指定索引的元素,索引從0開始

如果是負數(shù)表示從右邊開始計算的索引,最右邊元素的索引是-1。

Lset key indexnumber value 是另一個通過索引操作列表的命令,它會將索引為index的元素賦值為value。

sadd?key value?添加一個string元素到,key對應的set集合中,成功返回1,如果元素已經(jīng)在集合中返回0

scard?key?返回set的元素個數(shù),如果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參數(shù)

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表示該鍵值對已經(jīng)被刪除

persist 移除給定key的過期時間

select dbindex 選擇數(shù)據(jù)庫(0-15)

move key dbIndex 將當前數(shù)據(jù)庫中的key轉移到其他數(shù)據(jù)庫中

dbsize 返回當前數(shù)據(jù)庫中的key的數(shù)目

info 獲取服務器的信息和統(tǒng)計

flushdb 刪除當前選擇的數(shù)據(jù)庫中的key

flushall 刪除所有數(shù)據(jù)庫中的所有key

quit 退出連接

457.Redis的配置以及持久化方案有幾種?

答:以下兩種

RDB方式

AOF方式

458.什么是RDB方式?

答:是RDB是對內(nèi)存中數(shù)據(jù)庫狀態(tài)進行快照

RDB方式:將Redis在內(nèi)存中的數(shù)據(jù)庫狀態(tài)保存到磁盤里面,RDB文件是一個經(jīng)過壓縮的二進制文件,通過該文件可以還原生成RDB文件時的數(shù)據(jù)庫狀態(tài)(默認下,持久化到dump.rdb文件,并且在redis重啟后,自動讀取其中文件,據(jù)悉,通常情況下一千萬的字符串類型鍵,1GB的快照文件,同步到內(nèi)存中的 時間是20-30秒)

RDB的生成方式:

 1、執(zhí)行命令手動生成

有兩個Redis命令可以用于生成RDB文件,一個是SAVE,另一個是BGSAVE SAVE命令會阻塞Redis服務器進程,直到RDB文件創(chuàng)建完畢為止,在服務器進程阻塞期間,服務器不能處理任何命令請求,BGSAVE命令會派生出一個子進程,然后由子進程負責創(chuàng)建RDB文件,服務器進程(父進程)繼續(xù)處理命令請求,創(chuàng)建RDB文件結束之前,客戶端發(fā)送的BGSAVE和SAVE命令會被服務器拒絕

2、通過配置自動生成

可以設置服務器配置的save選項,讓服務器每隔一段時間自動執(zhí)行一次BGSAVE命令,可以通過save選項設置多個保存條件,但只要其中任意一個條件被滿足,服務器就會執(zhí)行BGSAVE命令

例如:

save 900 1

save 300 10

save 60 10000

那么只要滿足以下三個條件中的任意一個,BGSAVE命令就會被執(zhí)行

服務器在900秒之內(nèi),對數(shù)據(jù)庫進行了至少1次修改

服務器在300秒之內(nèi),對數(shù)據(jù)庫進行了至少10次修改

服務器在60秒之內(nèi),對數(shù)據(jù)庫進行了至少10000次修改

459.什么是AOF方式?

AOF持久化方式在redis中默認是關閉的,需要修改配置文件開啟該方式。

AOF:把每條命令都寫入文件,類似mysql的binlog日志

AOF方式:是通過保存Redis服務器所執(zhí)行的寫命令來記錄數(shù)據(jù)庫狀態(tài)的文件。

AOF文件刷新的方式,有三種:

appendfsync always - 每提交一個修改命令都調用fsync刷新到AOF文件,非常非常慢,但也非常安全

appendfsync everysec - 每秒鐘都調用fsync刷新到AOF文件,很快,但可能會丟失一秒以內(nèi)的數(shù)據(jù)

appendfsync no - 依靠OS進行刷新,redis不主動刷新AOF,這樣最快,但安全性就差

默認并推薦每秒刷新,這樣在速度和安全上都做到了兼顧

AOF數(shù)據(jù)恢復方式

服務器在啟動時,通過載入和執(zhí)行AOF文件中保存的命令來還原服務器關閉之前的數(shù)據(jù)庫狀態(tài),具體過程:

載入AOF文件

創(chuàng)建模擬客戶端

從AOF文件中讀取一條命令

使用模擬客戶端執(zhí)行命令

循環(huán)讀取并執(zhí)行命令,直到全部完成

如果同時啟用了RDB和AOF方式,AOF優(yōu)先,啟動時只加載AOF文件恢復數(shù)據(jù)

460.什么是全文檢索?

答:什么叫做全文檢索呢?這要從我們生活中的數(shù)據(jù)說起。

我們生活中的數(shù)據(jù)總體分為兩種:結構化數(shù)據(jù)和非結構化數(shù)據(jù)。

1)結構化數(shù)據(jù):指具有固定格式或有限長度的數(shù)據(jù),如數(shù)據(jù)庫,元數(shù)據(jù)等。

2)非結構化數(shù)據(jù):指不定長或無固定格式的數(shù)據(jù),如郵件,word文檔等。

非結構化數(shù)據(jù)又一種叫法叫全文數(shù)據(jù)。

?按照數(shù)據(jù)的分類,搜索也分為兩種:

1)對結構化數(shù)據(jù)的搜索:如對數(shù)據(jù)庫的搜索,用SQL語句。

2)對非結構化數(shù)據(jù)的搜索:如利用windows的搜索也可以搜索文件內(nèi)容,

全文檢索: 就是一種將文件中所有文本與檢索項匹配的文字資料檢索方法。全文檢索首先將要查詢的目標文檔中的詞提取出來,組成索引,通過查詢索引達到搜索目標文檔的目的。這種先建立索引,再對索引進行搜索的過程就叫全文檢索(Full-text Search)。

461.什么是Lucene?

Lucene是一個高效的,基于Java的全文檢索庫。

Lucene是apache軟件基金會4 jakarta項目組的一個子項目,是一個開放源代碼的全文檢索引擎工具包,但它不是一個完整的全文檢索引擎,而是一個全文檢索引擎的架構,Lucene的目的是為軟件開發(fā)人員提供一個簡單易用的工具包,以方便的在目標系統(tǒng)中實現(xiàn)全文檢索的功能,或者是以此為基礎建立起完整的全文檢索引擎。Lucene是一套用于全文檢索和搜尋的開源程序庫,由Apache軟件基金會支持和提供。Lucene提供了一個簡單卻強大的應用程序接口,能夠做全文索引和搜尋。在Java開發(fā)環(huán)境里Lucene是一個成熟的免費開源工具。就其本身而言,Lucene是當前以及最近幾年最受歡迎的免費Java信息檢索程序庫。

462.什么是Solr?

答:Solr是一個獨立的企業(yè)級搜索應用服務器,它對外提供類似于Web-service的API接口。

Solr是一個高性能,采用Java開發(fā),基于Lucene的全文搜索服務器。同時對其進行了擴展,提供了比Lucene更為豐富的查詢語言,同時實現(xiàn)了可配置、可擴展并對查詢性能進行了優(yōu)化,并且提供了一個完善的功能管理界面,是一款非常優(yōu)秀的全文檢索引擎。

文檔通過Http利用XML 加到一個搜索集合中。查詢該集合也是通過http收到一個XML/JSON響應來實現(xiàn)。它的主要特性包括:高效、靈活的緩存功能,垂直搜索功能,高亮顯示搜索結果,通過索引復制來提高可用性,提供一套強大Data Schema來定義字段,類型和設置文本分析,提供基于Web的管理界面等。

463.Solr是由哪兩個部分構成?

答:如下兩個部分

Solr的web服務

Solr的索引庫

464.什么是正排索引?

正排索引是以文檔的ID為關鍵字,索引文檔中每個字的位置信息,查找時掃描索引中每個文檔中字的信息直到找出所有包含查詢關鍵字的文檔。

但是在查詢的時候需對所有的文檔進行掃描以確保沒有遺漏,這樣就使得檢索時間大大延長,檢索效率低下。 ? ??

盡管正排索引的工作原理非常的簡單,但是由于其檢索效率太低,除非在特定情況下,否則實用性價值不大。

465.什么是倒排索引?

對數(shù)據(jù)進行分析,抽取出數(shù)據(jù)中的詞條,以詞條作為key,對應數(shù)據(jù)的存儲位置作為value,實現(xiàn)索引的存儲。這種索引稱為倒排索引。

當solr存儲文檔時,solr會首先對文檔數(shù)據(jù)進行分詞,創(chuàng)建索引庫和文檔數(shù)據(jù)庫。所謂的分詞是指:將一段字符文本按照一定的規(guī)則分成若干個單詞。

466.什么是ActiveMQ?

ActiveMQ是一種開源的,實現(xiàn)了JMS1.1規(guī)范的,面向消息(MOM)的中間件,為應用程序提供高效的、可擴展的、穩(wěn)定的和安全的企業(yè)級消息通信。ActiveMQ使用Apache提供的授權,任何人都可以對其實現(xiàn)代碼進行修改。

ActiveMQ的設計目標是提供標準的,面向消息的,能夠跨越多語言和多系統(tǒng)的應用集成消息通信中間件。

ActiveMQ實現(xiàn)了JMS標準并提供了很多附加的特性。這些附加的特性包括,JMX管理(java Management Extensions,即java管理擴展),主從管理(master/salve,這是集群模式的一種,主要體現(xiàn)在可靠性方面,當主中介(代理)出現(xiàn)故障,那么從代理會替代主代理的位置,不至于使消息系統(tǒng)癱瘓)、消息組通信(同一組的消息,僅會提交給一個客戶進行處理)、有序消息管理(確保消息能夠按照發(fā)送的次序被接受者接收)。消息優(yōu)先級(優(yōu)先級高的消息先被投遞和處理)、訂閱消息的延遲接收(訂閱消息在發(fā)布時,如果訂閱者沒有開啟連接,那么當訂閱者開啟連接時,消息中介將會向其提交之前的,其未處理的消息)、接收者處理過慢(可以使用動態(tài)負載平衡,將多數(shù)消息提交到處理快的接收者,這主要是對PTP消息所說)、虛擬接收者(降低與中介的連接數(shù)目)、成熟的消息持久化技術(部分消息需要持久化到數(shù)據(jù)庫或文件系統(tǒng)中,當中介崩潰時,信息不會丟失)、支持游標操作(可以處理大消息)、支持消息的轉換、通過使用Apache的Camel可以支持EIP、使用鏡像隊列的形式輕松的對消息隊列進行監(jiān)控等。

467.消息服務的應用場景有哪些?

答:如下3個場景都可以使用消息服務

1、異步處理

2、應用的解耦

3、流量的削峰

468.什么是JMS?

JMS(Java Messaging Service)是Java平臺上有關面向消息中間件的技術規(guī)范,它便于消息系統(tǒng)中的Java應用程序進行消息交換,并且通過提供標準的產(chǎn)生、發(fā)送、接收消息的接口,簡化企業(yè)應用的開發(fā)。

469.JMS有哪些模型?

答:JMS消息機制主要分為兩種模型:PTP模型和Pub/Sub模型。

1、PTP模型:(Point? to Point 對點模型) 每一個消息傳遞給一個消息消費者,保證消息傳遞給消息消費者,且消息不會同時被多個消費者接收。如果消息消費者暫時不在連接范圍內(nèi),JMS會自動保證消息不會丟失,直到消息消費者進入連接,消息將自動送達。因此,JMS需要將消息保存到永久性介質上,例如數(shù)據(jù)庫或者文件。

2、Pub-Sub模型:(publish-subscription 發(fā)布者訂閱者模型)每個主題可以擁有多個訂閱者。JMS系統(tǒng)負責將消息的副本傳給該主題的每個訂閱者。

如果希望每一條消息都能夠被處理,那么應該使用PTP消息模型。如果并不要求消息都必須被消息消費者接收到的情況下,可使用pub-sub消息模型。Pub-Sub模型可以在一對多的消息廣播時使用。

470.什么是JsonP?

Jsonp(JSON with Padding) 是 json 的一種"使用模式",可以讓網(wǎng)頁從別的域名(網(wǎng)站)那獲取資料,即跨域讀取數(shù)據(jù)。

471.什么是跨域?

跨域是指一個域(網(wǎng)站)下的文檔或腳本試圖去請求另一個域(網(wǎng)站)下的資源。

472.什么是同源策略?

同源策略/SOP(Same origin policy)是一種約定,由Netscape公司1995年引入瀏覽器,它是瀏覽器最核心也最基本的安全功能,現(xiàn)在所有支持JavaScript 的瀏覽器都會使用這個策略。如果缺少了同源策略,瀏覽器很容易受到XSS、CSFR等攻擊。所謂同源是指"協(xié)議+域名+端口"三者相同,即便兩個不同的域名指向同一個ip地址,也非同源

473.什么是MyCat?

MyCat是目前最流行的基于java語言編寫的數(shù)據(jù)庫中間件,是一個實現(xiàn)了MySQL協(xié)議的服務器,前端用戶可以把它看作是一個數(shù)據(jù)庫代理,用MySQL客戶端工具和命令行訪問,而其后端可以用MySQL原生協(xié)議與多個MySQL服務器通信,也可以用JDBC協(xié)議與大多數(shù)主流數(shù)據(jù)庫服務器通信,其核心功能是分庫分表。配合數(shù)據(jù)庫的主從模式還可實現(xiàn)讀寫分離。

MyCat是基于阿里開源的Cobar產(chǎn)品而研發(fā),Cobar的穩(wěn)定性、可靠性、優(yōu)秀的架構和性能以及眾多成熟的使用案例使得MyCat變得非常的強大。

MyCat發(fā)展到目前的版本,已經(jīng)不是一個單純的MySQL代理了,它的后端可以支持MySQL、SQL Server、Oracle、DB2、PostgreSQL等主流數(shù)據(jù)庫,也支持MongoDB這種新型NoSQL方式的存儲,未來還會支持更多類型的存儲。而在最終用戶看來,無論是那種存儲方式,在MyCat里,都是一個傳統(tǒng)的數(shù)據(jù)庫表,支持標準的SQL語句進行數(shù)據(jù)的操作,這樣一來,對前端業(yè)務系統(tǒng)來說,可以大幅降低開發(fā)難度,提升開發(fā)速度。

474.什么是縱向切分/垂直切分?

就是把原本存儲于一個庫的數(shù)據(jù)存儲到多個庫上。

由于對數(shù)據(jù)庫的讀寫都是對同一個庫進行操作,所以單庫并不能解決大規(guī)模并發(fā)寫入的問題。

例如,我們會建立定義數(shù)據(jù)庫workDB、商品數(shù)據(jù)庫payDB、用戶數(shù)據(jù)庫userDB、日志數(shù)據(jù)庫logDB等,分別用于存儲項目數(shù)據(jù)定義表、商品定義表、用戶數(shù)據(jù)表、日志數(shù)據(jù)表等。

優(yōu)點

1)減少增量數(shù)據(jù)寫入時的鎖對查詢的影響。

2)由于單表數(shù)量下降,常見的查詢操作由于減少了需要掃描的記錄,使得單表單次查詢所需的檢索行數(shù)變少,減少了磁盤IO,時延變短。

缺點:

無法解決單表數(shù)據(jù)量太大的問題。

橫向切分/水平切分

把原本存儲于一個表的數(shù)據(jù)分塊存儲到多個表上。當一個表中的數(shù)據(jù)量過大時,我們可以把該表的數(shù)據(jù)按照某種規(guī)則,進行劃分,然后存儲到多個結構相同的表,和不同的庫上。

例如,我們userDB中的userTable中數(shù)據(jù)量很大,那么可以把userDB切分為結構相同的多個userDB:part0DB、part1DB等,再將userDB上的userTable,切分為很多userTable:userTable0、userTable1等,然后將這些表按照一定的規(guī)則存儲到多個userDB上。

優(yōu)點:

1)單表的并發(fā)能力提高了,磁盤I/O性能也提高了。

2)如果出現(xiàn)高并發(fā)的話,總表可以根據(jù)不同的查詢,將并發(fā)壓力分到不同的小表里面。

缺點:無法實現(xiàn)表連接查詢。

475.簡述Tomcat,Apache,JBoss和WebLogic的區(qū)別和聯(lián)系

答:Apache:全球應用最廣泛的http服務器,免費,出自apache基金組織?

Tomcat:應用也算非常廣泛的web 服務器,支持部分j2ee,免費,出自 apache基金組織?

JBoss:開源的應用服務器,比較受人喜愛,免費(文檔要收費)?

weblogic:應該說算是業(yè)界第一的app server,全部支持j2ee1.4(收費)

JBoss也支持j2ee

JBoss和WebLogic都含有Jsp和Servlet容器,也就可以做web容器,?

JBoss和WebLogic也包含EJB容器,是完整的J2EE應用服務器

tomcat 只能做jsp和servlet的container

476.以下可以實現(xiàn)負載均衡的是()
A. nagios
B. Jenkins
C. nginx
D. docker
分析:答案: C Nginx是一款輕量級的Web?服務器/反向代理服務器及電子郵件(IMAP/POP3)代理服務器,并在一個BSD-like 協(xié)議下發(fā)行。其特點是占有內(nèi)存少,并發(fā)能力強,事實上nginx的并發(fā)能力確實在同類型的網(wǎng)頁服務器中表現(xiàn)較好,中國大陸使用nginx網(wǎng)站用戶有:百度、京東、新浪、網(wǎng)易、騰訊、淘寶等
477.Tomcat/ WebSphere/WebLogic的作用和特點

作用:

Tomcat:目前應用非常廣泛的免費web服務器,支持部分j2ee。

WebSphere:是IBM集成軟件平臺??勺鰓eb服務器,WebSphere提供了可靠、靈活和健壯的集成軟件。

Weblogic:是美國bea公司出品的一個基于j2ee架構的中間件。BEA WebLogic是用于開發(fā)、集成、部署和管理大型分布式Web應用、網(wǎng)絡應用和數(shù)據(jù)庫應用的Java應用服務器。

特點(區(qū)別):

1)價位不同:Tomcat的是免費的;WebLogic與WebSphere是收費的,而且價格不菲。

2) 開源性不同:Tomcat的是完全開源的,而其他兩個不是。WebLogic與WebSphere都是對業(yè)內(nèi)多種標準的全面支持,包括JSB、JMS、JDBC、XML和WML,使Web應用系統(tǒng)實施更簡單,且保護投資,同時也使基于標準的解決方案的開發(fā)更加簡便。

3) 擴展性的不同:WebLogic和WebSphere都是以其高擴展的架構體系聞名于業(yè)內(nèi),包括客戶機連接的共享、資源 pooling以及動態(tài)網(wǎng)頁。

4)應用范圍的區(qū)別:Tomcat 是一個小型的輕量級應用服務器,在中小型系統(tǒng)和并發(fā)訪問用戶不是很多的場合下被普遍使用,是開發(fā)和調試JSP 程序的首選。WebLogic和WebSphere是商業(yè)軟件,功能齊全強大,主要應用于大型企業(yè)的大型項目。

5)安全性問題區(qū)別:因為Tomcat是開源的,所以它們的安全性相對來說比較低,萬一應用服務器本身有什么漏洞,你是沒辦法向Apache索賠的。而WebLogic和WebSphere其容錯、系統(tǒng)管理和安全性能已經(jīng)在全球數(shù)以千記的關鍵任務環(huán)境中得以驗證。

478.B/S和C/S的含義及其區(qū)別

C/S結構,即Client/Server(客戶機/服務器)結構,通過將任務合理分配到Client端和Server端,降低了系統(tǒng)的通訊開銷,可充分利用兩端硬件環(huán)境優(yōu)勢。早期軟件系統(tǒng)多以此作為首選設計標準。

B/S結構,即Browser/Server(瀏覽器/服務器)結構,是隨著Internet技術的興起,對C/S結構的一種變化或者改進的結構。在這種結構下,用戶界面完全通過WWW瀏覽器實現(xiàn),一部分事務邏輯在前端實現(xiàn),但是主要事務邏輯在服務器端實現(xiàn),節(jié)約了開發(fā)成本,便于軟件維護。

區(qū)別

1、C/S是建立在局域網(wǎng)的基礎上的。B/S是建立在廣域網(wǎng)的基礎上的,但并不是說B/S結構不能在局域網(wǎng)上使用。

2、B/S業(yè)務擴展簡單方便,通過增加頁面即可增加服務器功能。C/S的客戶端還需要安裝專用的客戶端軟件,不利于擴展。

3、B/S維護簡單方便。開發(fā)、維護等幾乎所有工作也都集中在服務器端,當企業(yè)對網(wǎng)絡應用進行升級時,只需更新服務器端的軟件就可以,這減輕了異地用戶系統(tǒng)維護與升級的成本

4、B/S響應速度不及C/S;

5、B/S用戶體驗效果不是很理想

479.說說你對容器的理解

容器也是 java 程序,它的主要作用是為應用程序提供運行環(huán)境。容器用來接管安全性、并發(fā)性、事務處理、交換到輔助存儲器和其它服務的責任

以tomcat為例:Tomcat是一個后臺服務進程,其它的servlet(相當于DLL)是在Tomcat容器內(nèi)運行,Broswer只與Tomcat通迅; Tomcat接受browser的請求,經(jīng)過一系列動作(如果是靜態(tài)網(wǎng)頁,那么裝載,按http協(xié)議形成響應流;如果是動態(tài)的如JSP,那就要調用JDK 中的servlet.jsp接口,解釋形成靜態(tài)網(wǎng)頁,按http協(xié)議生成響應流發(fā)送回browser)后,形成靜態(tài)網(wǎng)頁,返回響應。

480.為什么要使用連接池?

?傳統(tǒng)的數(shù)據(jù)庫連接方式

一個連接對象對應一個物理連接

每次操作都打開一個物理連接,

使用完都關閉連接,造成系統(tǒng)性能低下。

?連接池技術

客戶程序得到的連接對象是連接池中物理連接的一個句柄,調用連接對象的close()方法,物理連接并沒有關閉,數(shù)據(jù)源的實現(xiàn)只是刪除了客戶程序中的連接對象和池中的連接對象之間的聯(lián)系.

?數(shù)據(jù)庫連接的建立及關閉是耗費系統(tǒng)資源的操作,在大型應用中對系統(tǒng)的性能影響尤為明顯。為了能重復利用數(shù)據(jù)庫連接對象,縮短請求的響應時間和提高服務器的性能,支持更多的客戶,應采用連接池技術.

481.數(shù)據(jù)庫連接池的原理

數(shù)據(jù)庫連接池的原理

傳統(tǒng)連接方式:

首先調用Class.forName()方法加載數(shù)據(jù)庫驅動,

然后調用DriverManager.getConnection()方法建立連接.

連接池技術:

連接池解決方案是在應用程序啟動時就預先建立多個數(shù)據(jù)庫連接對象,然后將連接對象保存到連接池中。

當客戶請求到來時,從池中取出一個連接對象為客戶服務。

當請求完成時,客戶程序調用close()方法,將連接對象放回池中.

對于多于連接池中連接數(shù)的請求,排隊等待。

應用程序還可根據(jù)連接池中連接的使用率,動態(tài)增加或減少池中的連接數(shù)。

482.MVC模式及其優(yōu)缺點

一、MVC原理

MVC是一種程序開發(fā)設計模式,它實現(xiàn)了顯示模塊與功能模塊的分離。提高了程序的可維護性、可移植性、可擴展性與可重用性,降低了程序的開發(fā)難度。它主要分模型、視圖、控制器三層。

1、模型(model)它是應用程序的主體部分,主要包括業(yè)務邏輯模塊和數(shù)據(jù)模塊。模型與數(shù)據(jù)格式無關,這樣一個模型能為多個視圖提供數(shù)據(jù)。由于應用于模型的代碼只需寫一次就可以被多個視圖重用,所以減少了代碼的重復性

2、視圖(view) 用戶與之交互的界面、在web中視圖一般由jsp,html組成

3、控制器(controller)接收來自界面的請求 并交給模型進行處理 在這個過程中控制器不做任何處理只是起到了一個連接的作用

二、MVC的優(yōu)點

1、降低代碼耦合性。在MVC模式中,三個層各施其職,所以如果一旦哪一層的需求發(fā)生了變化,就只需要更改相應的層中的代碼而不會影響到其他層中的代碼。

2、有利于分工合作。在MVC模式中,由于按層把系統(tǒng)分開,那么就能更好的實現(xiàn)開發(fā)中的分工。網(wǎng)頁設計人員可進行開發(fā)視圖層中的JSP,而對業(yè)務熟悉的人員可開發(fā)業(yè)務層,而其他開發(fā)人員可開發(fā)控制層。

3、有利于組件的重用。如控制層可獨立成一個能用的組件,表示層也可做成通用的操作界面??梢詾橐粋€模型在運行時同時建立和使用多個視圖。

三、MVC的不足之處

1、增加了系統(tǒng)結構和實現(xiàn)的復雜性。對于簡單的界面,嚴格遵循MVC,使模型、視圖與控制器分離,會增加結構的復雜性,并可能產(chǎn)生過多的更新操作,降低運行效率。

2、視圖與控制器間的過于緊密的連接。視圖與控制器是相互分離,但確實聯(lián)系緊密的部件,視圖沒有控制器的存在,其應用是很有限的,反之亦然,這樣就妨礙了他們的獨立重用。

3、視圖對模型數(shù)據(jù)的低效率訪問。依據(jù)模型操作接口的不同,視圖可能需要多次調用才能獲得足夠的顯示數(shù)據(jù)。對未變化數(shù)據(jù)的不必要的頻繁訪問,也將損害操作性能。

4、目前,一般高級的界面工具或構造器不支持模式。改造這些工具以適應MVC需要和建立分離的部件的代價是很高的,從而造成MVC使用的困難。

483.MVC模式完成分頁功能的基本思路是什么?

1)頁面提交頁碼(第幾頁)到Servlet中

2)Servlet接收到頁碼后,將頁碼傳遞給分頁工具類(PageBean)

3)Servlet中調用Service層傳入PageBean對象

4)Service層調用DAO層傳入PageBean對象

5)Servlet中得到查詢出來的數(shù)據(jù),并setAttrivute保存

6)在頁面中得到(getAttribute)數(shù)據(jù),遍歷輸出

484.常用的Web容器

答: Unix和Linux平臺下使用最廣泛的免費HTTP服務器是Apache服務器,而Windows平臺的服務器通常使用IIS作為Web服務器。選擇Web服務器應考慮的因素有:性能、安全性、日志和統(tǒng)計、虛擬主機、代理服務器、緩沖服務和集成應用程序等。下面是對常用服務器的簡介:

IIS:Microsoft的Web服務器產(chǎn)品為Internet Information Services。IIS 是允許在公共Intranet或Internet上發(fā)布信息的Web服務器。IIS是目前最流行的Web服務器產(chǎn)品之一,很多著名的網(wǎng)站都是建立在IIS的平臺上。IIS提供了一個圖形界面的管理工具,稱為Internet服務管理器,可用于監(jiān)視配置和控制Internet服務。IIS是一種Web服務組件,其中包括Web服務器、FTP服務器、NNTP服務器和SMTP服務器,分別用于網(wǎng)頁瀏覽、文件傳輸、新聞服務和郵件發(fā)送等方面,它使得在網(wǎng)絡(包括互聯(lián)網(wǎng)和局域網(wǎng))上發(fā)布信息成了一件很容易的事。它提供ISAPI(Intranet Server API)作為擴展Web服務器功能的編程接口;同時,它還提供一個Internet數(shù)據(jù)庫連接器,可以實現(xiàn)對數(shù)據(jù)庫的查詢和更新。

Kangle:Kangle Web服務器是一款跨平臺、功能強大、安全穩(wěn)定、易操作的高性能Web服務器和反向代理服務器軟件。此外,Kangle也是一款專為做虛擬主機研發(fā)的Web服務器。實現(xiàn)虛擬主機獨立進程、獨立身份運行。用戶之間安全隔離,一個用戶出問題不影響其他用戶。支持PHP、ASP、ASP.NET、Java、Ruby等多種動態(tài)開發(fā)語言。

WebSphere:WebSphere Application Server是功能完善、開放的Web應用程序服務器,是IBM電子商務計劃的核心部分,它是基于Java的應用環(huán)境,用于建立、部署和管理Internet和Intranet Web應用程序,適應各種Web應用程序服務器的需要,范圍從簡單到高級直到企業(yè)級。

WebLogic:BEA WebLogic Server是一種多功能、基于標準的Web應用服務器,為企業(yè)構建自己的應用提供了堅實的基礎。各種應用開發(fā)、部署所有關鍵性的任務,無論是集成各種系統(tǒng)和數(shù)據(jù)庫,還是提交服務、跨Internet協(xié)作,Weblogic都提供了相應的支持。由于它具有全面的功能、對開放標準的遵從性、多層架構、支持基于組件的開發(fā),基于Internet的企業(yè)都選擇它來開發(fā)、部署最佳的應用。BEA WebLogic Server在使應用服務器成為企業(yè)應用架構的基礎方面一直處于領先地位,為構建集成化的企業(yè)級應用提供了穩(wěn)固的基礎,它們以 Internet的容量和速度,在連網(wǎng)的企業(yè)之間共享信息、提交服務,實現(xiàn)協(xié)作自動化。

Apache:目前Apache仍然是世界上用得最多的Web服務器,市場占有率約為60%左右。世界上很多著名的網(wǎng)站都是Apache的產(chǎn)物,它的成功之處主要在于它的源代碼開放、有一支強大的開發(fā)團隊、支持跨平臺的應用(可以運行在幾乎所有的Unix、Windows、Linux系統(tǒng)平臺上)以及它的可移植性等方面。

Tomcat:Tomcat是一個開放源代碼、運行Servlet和JSP的容器。TomcatServer實現(xiàn)了Servlet和JSP規(guī)范。此外,Tomcat還實現(xiàn)了Apache-Jakarta規(guī)范而且比絕大多數(shù)商業(yè)應用軟件服務器要好,因此目前也有不少的Web服務器都選擇了Tomcat。

Nginx:讀作"engine x",是一個高性能的HTTP和反向代理服務器,也是一個IMAP/POP3/SMTP代理服務器。 Nginx是由Igor Sysoev為俄羅斯訪問量第二的 Rambler.ru站點開發(fā)的,第一個公開版本0.1.0發(fā)布于2004年10月4日。其將源代碼以類BSD許可證的形式發(fā)布,因它的穩(wěn)定性、豐富的功能集、示例配置文件和低系統(tǒng)資源的消耗而聞名。

485.Java Web開發(fā)的Model 1和Model 2分別指的是什么?

答:Model 1是以頁面為中心的Java Web開發(fā),只適合非常小型的應用程序,Model 2是基于MVC架構模式的應用,這一點在前文的面試題中已經(jīng)詳細講解過了。

486.說說什么是框架:

框架(framework)是一個框子--》指約束性,也是一個架子--》指支撐性IT語境中的框架,特指為解決一個開放性問題而設計的具有一定約束性的支撐結構,在此結構上可以根據(jù)具體問題擴展、按插更多的組成部分,從而更迅速和方便地架構完整的解決問題的方案。

1)框架本身一般不完整到可以解決特定問題,但是可以幫助您快速解決特定問題:

沒有框架所有的工作都從零開始做,有了框架,為我們提供了一定的功能。我們就可以在框架的基礎上開發(fā),極大的解決了生產(chǎn)力。

不同的框架,是為了解決不同領域的問題,一定要為了解決問題才去學習框架。

2)框架天生就是為了擴展而設計的

3)框架里面可以為后續(xù)的組件提供很多輔助性、支撐性的方便易用的實用工具(utilities),也就是框架時常配套一些幫組解決某類問題的庫(libraries)或工具(tools).

在java中就是一系列的jar包,其本質就是對jdk功能的擴展。

487.簡單說一下MVC框架?

是為了解決傳統(tǒng)MVC模式(jsp+servlet+javabean)一些問題而出現(xiàn)的框架

傳統(tǒng)MVC模式模式問題:

1) 所有的Servlet和Servlet映射都要配置在web.xml中,如果項目太大,web.xml就太龐大并且不能實現(xiàn)模塊化管理。

2)Servlet的主要功能就是接受參數(shù)、調用邏輯、跳轉頁面,比如像其他字符編碼、文件上傳等功能也要寫在Servlet中,不能讓Servlet主要功能而需要做處理一些特例。

3)接受參數(shù)比較麻煩

(String name = request.getParameter(“name”)),不能通過model接受,只能單個接收,接收完成后轉換封裝model。

4)跳轉頁面方式比較單一(forward,redirect),并且當我們的頁面名稱發(fā)生改變時需要改變Servlet源代碼。

現(xiàn)在比較常用的MVC框架:

webwork

Struts

Struts2

SpringMVC

488.簡單講一下struts2的執(zhí)行流程

?一個請求在struts2框架中處理大概分為一下幾個步驟:

1)客戶瀏覽器發(fā)送一個指向Servlet容器(例如Tomcat)的請求

2)這個請求經(jīng)過一系列的過濾器(Filter)(這些過濾器中有一個叫做ActionContextCleanUp的可選過濾器,這個過濾器對于Struts2和其他框架的集成很有幫助,例如:SiteMesh Plugin)

3)接著FilterDispatcher(StrutsPrepareAndExecuteFilter)被調用,F(xiàn)ilterDispatcher詢問ActionMapper來決定這個請是否需要調用某個Action

4)如果ActionMapper決定需要調用某個Action,F(xiàn)ilterDispatcher把請求的處理交給ActionProxy

5)ActionProxy通過Configuration Manager詢問框架的配置文件,找到需要調用的Action類

6)ActionProxy創(chuàng)建一個ActionInvocation的實例。

7)ActionInvocation實例使用命名模式來調用,在調用Action的過程前后,涉及到相關攔截器(Intercepter)的調用。

8)一旦Action執(zhí)行完畢,ActionInvocation負責根據(jù)struts.xml中的配置找到對應的返回結果。返回結果通常是(但不總是,也 可 能是另外的一個Action鏈)一個需要被表示的JSP或者FreeMarker的模版。在表示的過程中可以使用Struts2 框架中繼承的標簽。在這個過程中需要涉及到ActionMapper

489.Struts2中的攔截器,你都用它干什么?

java里的攔截器是動態(tài)攔截Action調用的對象,它提供了一種機制可以使開發(fā)者定義一個action執(zhí)行的前后執(zhí)行的代碼,也可以在一個action執(zhí)行前阻止其執(zhí)行,同時也提供了一種可以提取action中可重用部分的方式。

在AOP(Aspect Oriented Programming)中攔截器用于在某個方法或字段被訪問之前,進行攔截后在之前或之后加入某些操作

1)struts2中的功能(參數(shù)處理、文件上傳、字符編碼等)都是通過系統(tǒng)攔截器實現(xiàn)的

2)當然我們也可以自定義攔截器,進行可插拔配置,可以執(zhí)行Action的方法前后,加入相關邏輯完成業(yè)務。

使用場景:

1)用戶登錄判斷,在執(zhí)行action的前面判斷是否已經(jīng)登錄,如果沒有登錄的就跳轉登錄頁面。

2)用戶權限判斷,在執(zhí)行action的前面判斷是否具有,如果沒有權限就給出提示信息。

3)操作日志...

490.簡單講一下SpringMVC的執(zhí)行流程?

1)用戶向服務器發(fā)送請求,請求被Spring 前端控制Servelt DispatcherServlet捕獲;

2)DispatcherServlet 對請求URL進行解析,得到請求資源標識符(URI)。然后根據(jù)該URI,調用HandlerMapping獲得該Handler配置的所有相關的對象 (包括Handler對象以及Handler對象對應的攔截器),最后以HandlerExecutionChain對象的形式返回;

3)DispatcherServlet 根據(jù)獲得的Handler,選擇一個合適的HandlerAdapter。(附注:如果成功獲得HandlerAdapter后,此時將開始執(zhí)行攔截器的preHandler(...)方法)

4) 提取Request中的模型數(shù)據(jù),填充Handler入?yún)?,開始執(zhí)行Handler(Controller)。 在填充Handler的入?yún)⑦^程中,根據(jù)你的配置,Spring將幫你做一些額外的工作:

HttpMessageConveter: 將請求消息(如Json、xml等數(shù)據(jù))轉換成一個對象,將對象轉換為指定的響應信息

數(shù)據(jù)轉換:對請求消息進行數(shù)據(jù)轉換。如String轉換成Integer、Double等

數(shù)據(jù)根式化:對請求消息進行數(shù)據(jù)格式化。 如將字符串轉換成格式化數(shù)字或格式化日期等

數(shù)據(jù)驗證: 驗證數(shù)據(jù)的有效性(長度、格式等),驗證結果存儲到BindingResult或Error中

5)Handler執(zhí)行完成后,向DispatcherServlet?返回一個ModelAndView對象;

6)根據(jù)返回的ModelAndView,選擇一個適合的ViewResolver(必須是已經(jīng)注冊到Spring容器中的ViewResolver)返回給DispatcherServlet?;

7)ViewResolver 結合Model和View,來渲染視圖

8)將渲染結果返回給客戶端。

快速記憶:

核心控制器捕獲請求,查找Hander,執(zhí)行Handler,選擇ViewResolver,通過ViewResoler渲染視圖并返回

491.簡單說一下struts2和springMVC有什么不同

目前企業(yè)中使用SpringMvc的比例已經(jīng)遠遠超過Struts2,那么兩者到底有什么區(qū)別,是很多初學者比較關注的問題,下面我們就來對SpringMvc和Struts2進行各方面的比較:

1)核心控制器(前端控制器、預處理控制器):對于使用過mvc框架的人來說這個詞應該不會陌生,核心控制器的主要用途是處理所有的請求,然后對那些特殊的請求 (控制器)統(tǒng)一的進行處理(字符編碼、文件上傳、參數(shù)接受、異常處理等等),spring mvc核心控制器是Servlet,而Struts2是Filter。

2)控制器實例:Spring Mvc會比Struts快一些(理論上)。Spring Mvc是基于方法設計,而Sturts是基于對象,每次發(fā)一次請求都會實例一個action,每個action都會被注入??屬性,而Spring更像Servlet一樣,只有一個實例,每次請求執(zhí)行對應的方法即可(注意:由于是單例實例,所以應當避免全局變量的修改,這樣會產(chǎn)生線程安全問題 )

3)管理方式:大部分的公司的核心架構中,就會使用到spring,而spring mvc又是spring中的一個模塊,所以spring對于spring mvc的控制器管理更加簡單方便,而且提供了全 注解方式進行管理,各種功能的注解都比較全面,使用簡單,而struts2需要采用XML很多的配置參數(shù)來管理(雖然也可以采用注解,但是幾乎沒有公司那 樣使用)

4)參數(shù)傳遞:Struts2中自身提供多種參數(shù)接受,其實都是通過(ValueStack)進行傳遞和賦值,而SpringMvc是通過方法的參數(shù)進行接收。

5)學習難度:Struts更加很多新的技術點,比如攔截器、值棧及OGNL表達式,學習成本較高,springmvc 比較簡單,很較少的時間都能上手。

6)intercepter 的實現(xiàn)機制:struts有以自己的interceptor機制,spring mvc用的是獨立的AOP方式。這樣導致struts的配置文件量還是比spring mvc大,雖然struts的配置能繼承,所以我覺得論使用上來講,spring mvc使用更加簡潔,開發(fā)效率Spring MVC確實比struts2高。spring mvc是方法級別的攔截,一個方法對應一個request上下文,而方法同時又跟一個url對應,所以說從架構本身上spring3 mvc就容易實現(xiàn)restful url。struts2是類級別的攔截,一個類對應一個request上下文;實現(xiàn)restful url要費勁,因為struts2 action的一個方法可以對應一個url;而其類屬性卻被所有方法共享,這也就無法用注解或其他方式標識其所屬方法了。spring3 mvc的方法之間基本上獨立的,獨享request response數(shù)據(jù),請求數(shù)據(jù)通過參數(shù)獲取,處理結果通過ModelMap交回給框架方法之間不共享變量,而struts2搞的就比較亂,雖然方法之間 也是獨立的,但其所有Action變量是共享的,這不會影響程序運行,卻給我們編碼,讀程序時帶來麻煩。

7)spring mvc處理ajax請求,直接通過返回數(shù)據(jù),方法中使用注解@ResponseBody,spring mvc自動幫我們對象轉換為JSON數(shù)據(jù)。而struts2是通過插件的方式來處理。

在springMVC流行起來之前,struts2在MVC框架中占核心地位,隨著SpringMVC的出現(xiàn),SpringMVC慢慢的取代了struts2,但是很多的企業(yè)原來搭建的框架都是使用struts2。

492.說一下Spring中的兩大核心

Spring是什么?

Spring是J2EE應用程序框架,是輕量級的IOC和AOP的容器框架,主要針對JavaBean的生命周期進行管理的輕量級容器,可以單獨使用,也可以和struts框架,ibatis框架等組合使用。

1)IOC(Inversion of Control)

ioc控制反轉,又稱為“依賴注入”;

IOC的基本概念是:不創(chuàng)建對象,但是描述創(chuàng)建它們的方式。在代碼中不直接與對象和服務連接,但在配置文件中描述哪一個組件需要哪一項服務。容器負責將這些聯(lián)系在一起。   

其原理是基于OO設計原則的The Hollywood Principle:Don't call us, we'll call you(別找我,我會來找你的)。也就是說,所有的組件都是被動的(Passive),所有的組件初始化和調用都由容器負責。組件處在一個容器當中,由容 器負責管理。   

簡單的來講,就是由容器控制程序之間的關系,而非傳統(tǒng)實現(xiàn)中,由程序代碼直接操控。這也就是所謂“控制反轉”的概念所在:控制權由應用代碼中轉到了外部容器,控制權的轉移,是所謂反轉。

2)AOP 面向切面編程

核心原理:使用動態(tài)代理的設計模式在執(zhí)行方法前后或出現(xiàn)異常常做加入相關邏輯

我們使用AOP來做:

1)事務處理:執(zhí)行方法前開啟事務,執(zhí)行完成后關閉事務,出現(xiàn)異常后回滾事務

2)權限判斷:在執(zhí)行方法前,判斷是否具有權限

3)日志:在執(zhí)行前進行日志處理

493.講一下Spring的事務的傳播特性

多個事物存在是怎么處理的策略

1)PROPAGATION_REQUIRED:如果存在一個事務,則支持當前事務,如果當前沒有事務,就新建一個事務。這是最常見的選擇。

2)PROPAGATION_SUPPORTS:如果存在一個事務,支持當前事務,如果當前沒有事務,就以非事務方式執(zhí)行。

3)PROPAGATION_MANDATORY:如果存在一個事務,支持當前事務,如果當前沒有事務,就拋出異常。

4)PROPAGATION_REQUIRES_NEW:新建事務,如果當前存在事務,把當前事務掛起。

5)PROPAGATION_NOT_SUPPORTED:以非事務方式執(zhí)行操作,如果當前存在事務,就把當前事務掛起。

6)PROPAGATION_NEVER:以非事務方式執(zhí)行,如果當前存在事務,則拋出異常。

7)PROPAGATION_NESTED:支持當前事務,新增Savepoint點,與當前事務同步提交或回滾。

494.什么是ORM

對象關系映射(Object Relation Mapping,簡稱ORM)模式是一種為了解決面向對象與關系數(shù)據(jù)庫存在的互不匹配的現(xiàn)象的技術,簡單的說,ORM是通過使用描述對象和數(shù)據(jù)庫之間映射的元數(shù)據(jù),將程序中的對象自動持久化到關系數(shù)據(jù)庫中,那么到底如何實現(xiàn)持久化呢?一種簡單的方案時采用硬編碼方式(jdbc操作sql方式),為每一種可能的數(shù)據(jù)庫訪問操作提供單獨的方法。

這種方案存在以下不足:

1. 持久化層缺乏彈性,一旦出現(xiàn)業(yè)務需求變更,就必須修改持久化層的接口

2. 持久化層同時與域模型與關系數(shù)據(jù)庫模型綁定,不管域模型還是關系數(shù)據(jù)庫模型發(fā)生變化,都要修改持久化層的相關程序代碼,增加軟件的維護難度。

ORM提供了實現(xiàn)持久化層的另一種模式,它采用映射元數(shù)據(jù)來描述對象關系的映射,使得ORM中間件能在任何一個應用的業(yè)務邏輯層和數(shù)據(jù)庫層之間充當橋梁,Java典型的ORM框架有:Hibernate,ibatis(mybtis),speedframework。

ORM框架的方法論基于三個核心原則:

簡單:以最基本的形式建模數(shù)據(jù)

傳達性:數(shù)據(jù)庫結構被任何人都能理解的語言文檔化

精確性:基于數(shù)據(jù)模型創(chuàng)建正確標準化了結構

對象關系映射(Object Relation Mapping,簡稱ORM)模式是一種為了解決面向對象與關系數(shù)據(jù)庫存在的互不匹配的現(xiàn)象的技術,可以簡單的方案采用硬編碼方式(jdbc操作sql方式),為每一種可能的數(shù)據(jù)庫訪問操作提供單獨的方法,這種方法存在很多缺陷,使用ORM框架(為了解決面向對象與關系數(shù)據(jù)庫存在互不匹配的現(xiàn)象的框架)來解決。

495.Hibernate對象的狀態(tài)

臨時狀態(tài)/瞬時狀態(tài)(transient):剛剛用new語句創(chuàng)建,沒有被持久化,無id

不處于session中(沒有使用session的方法去操作臨時對象),該對象成為臨時對象

持久化狀態(tài),托管狀態(tài)(persistent):已經(jīng)被持久化,加入session的緩存中,session是沒有關閉

該狀態(tài)的對象為持久化對象。

游離狀態(tài),脫管狀態(tài)(detached):已經(jīng)被持久化,但不處于session中,該狀態(tài)的對象為游離對象。

刪除狀態(tài)(removed):對象有關聯(lián)的id,并且在session管理下,但是已經(jīng)被計劃(事務提交的時候,commit)刪除,如果沒有事務就不能刪除

相互轉換

496.介紹一下Hibernate的緩存

答:一、why(為什么要用Hibernate緩存?)

Hibernate是一種持久化層框架,經(jīng)常訪問物理數(shù)據(jù)庫。

為了降低應用程序對物理數(shù)據(jù)源訪問的頻次,從而提高應用程序的運行性能

緩存內(nèi)的數(shù)據(jù)是對物理數(shù)據(jù)源中的數(shù)據(jù)的復制,應用程序在運行時從緩存讀寫數(shù)據(jù),在特定的時刻或事件會同步緩存和物理數(shù)據(jù)源的數(shù)據(jù)。

為了提高訪問速度,把磁盤或者數(shù)據(jù)庫訪問變成內(nèi)存訪問

二、what(Hibernate緩存原理是怎樣的?)Hibernate緩存包括兩大類:Hibernate 一級緩存和Hibernate二級緩存

1. Hibernate一級緩存又稱為”session的緩存”。

session緩存內(nèi)置不能被卸載,session的緩存是事務范圍的緩存(session對象的生命周期通常對應一個數(shù)據(jù)庫事務或者一個應用事務)。

一級緩存中,持久化類的每個實例都具有唯一的OID

2. Hibernate的二級緩存又稱為”sessionFactory的緩存”。

由于sessionFactory對象的生命周期和應用程序的整個過程對應,因此Hibernate二級緩存是進程范圍或者集群范圍的緩存,有可能出現(xiàn)并發(fā)問題,因此需要采用適當?shù)牟l(fā)訪問策略,該策略為被緩存的數(shù)據(jù)提供了事務隔離級別。

第二級緩存是可選的,是一個可配置的插件,默認下sessionFactory不會啟用這個插件。

什么樣的數(shù)據(jù)適合存放到二級緩存中?

1) 很少被修改的數(shù)據(jù) (帖子的最后回復時間)

2) 經(jīng)常被查詢的數(shù)據(jù) (電商的地點)

3) 不是很重要的數(shù)據(jù),允許出現(xiàn)偶爾并發(fā)的數(shù)據(jù)

4) 不會被并發(fā)訪問的數(shù)據(jù)

5) 常量數(shù)據(jù)

擴展:Hibernate的二級緩存默認是不支持分布式緩存的,使用memcache,redis等中央緩存來代替二級緩存。

497.簡單講一下webservice使用的場景

webservice是一個SOA(面向服務的編程)的架構,它是不依賴于語言,不依賴于平臺,可以實現(xiàn)不同的語言間的相互調用,通過Internet進行基于http協(xié)議的網(wǎng)絡應用間的交互。

1、異構系統(tǒng)(不同的開發(fā)語言)的整合

2、不同客戶端的整合 (瀏覽器、手機端(android\ios)、微信)

3、實實在在的例子:

天氣預報:可以通過實現(xiàn)webservice客戶端調用遠程天氣服務實現(xiàn)的

4、單點登錄:一個服務實現(xiàn)所有系統(tǒng)的登錄

498.簡單介紹一下activity?

Activity是一個業(yè)務流程管理(BPM)和工作流系統(tǒng),適用于開發(fā)人員和系統(tǒng)管理員,其核心是超快速,穩(wěn)定的BPMN2的流程引擎,它易于與Spring集成使用。

主要用在OA中,把線下流程放在線上,把現(xiàn)實生活中一些流程固話定義到系統(tǒng)中,然后通過輸入表單數(shù)據(jù)完成業(yè)務。

他可以用在OA系統(tǒng)的流程管理中

請假流程(小于三天,一級主管審批,大于三天二級主管審批)

報銷流程(價格區(qū)間)

499.什么是MyBatis?

答:MyBatis是一個可以自定義SQL、存儲過程和高級映射的持久層框架。

500.Mybatis是如何進行分頁的?分頁插件的原理是什么?

答:1)Mybatis使用RowBounds對象進行分頁,也可以直接編寫sql實現(xiàn)分頁,也可以使用Mybatis的分頁插件。

2)分頁插件的原理:實現(xiàn)Mybatis提供的接口,實現(xiàn)自定義插件,在插件的攔截方法內(nèi)攔截待執(zhí)行的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語句映射生成最終執(zhí)行的sql,最后將sql執(zhí)行的結果再映射生成java對象。

2)Mybatis學習門檻低,簡單易學,程序員直接編寫原生態(tài)sql,可嚴格控制sql執(zhí)行性能,靈活度高,非常適合對關系數(shù)據(jù)模型要求不高的軟件開發(fā),例如互聯(lián)網(wǎng)軟件、企業(yè)運營類軟件等,因為這類軟件需求變化頻繁,一但需求變化要求成果輸出迅速。但是靈活的前提是mybatis無法做到數(shù)據(jù)庫無關性,如果需要實現(xiàn)支持多種數(shù)據(jù)庫的軟件則需要自定義多套sql映射文件,工作量大。

3)Hibernate對象/關系映射能力強,數(shù)據(jù)庫無關性好,對于關系模型要求高的軟件(例如需求固定的定制化軟件)如果用hibernate開發(fā)可以節(jié)省很多代碼,提高效率。但是Hibernate的缺點是學習門檻高,要精通門檻更高,而且怎么設計O/R映射,在性能和對象模型之間如何權衡,以及怎樣用好Hibernate需要具有很強的經(jīng)驗和能力才行。

總之,按照用戶的需求在有限的資源環(huán)境下只要能做出維護性、擴展性良好的軟件架構都是好架構,所以框架只有適合才是最好。

502.簡述Mybatis的Xml映射文件和Mybatis內(nèi)部數(shù)據(jù)結構之間的映射關系?

答: Mybatis將所有Xml配置信息都封裝到All-In-One重量級對象Configuration內(nèi)部。在Xml映射文件中,< parameterMap>標簽會被解析為ParameterMap對象,其每個子元素會被解析為ParameterMapping對象。< resultMap>標簽會被解析為ResultMap對象,其每個子元素會被解析為ResultMapping對象。每一個< select>、< insert>、< update>、< delete>標簽均會被解析為MappedStatement對象,標簽內(nèi)的sql會被解析為BoundSql對象。

503.什么是MyBatis的接口綁定,有什么好處?

答:接口映射就是在MyBatis中任意定義接口,然后把接口里面的方法和SQL語句綁定,我們直接調用接口方法就可以,這樣比起原來了SqlSession提供的方法我們可以有更加靈活的選擇和設置.

504.Mybatis能執(zhí)行一對一、一對多的關聯(lián)查詢嗎?都有哪些實現(xiàn)方式,以及它們之間的區(qū)別?

答:能,Mybatis不僅可以執(zhí)行一對一、一對多的關聯(lián)查詢,還可以執(zhí)行多對一,多對多的關聯(lián)查詢,多對一查詢,其實就是一對一查詢,只需要把selectOne()修改為selectList()即可;多對多查詢,其實就是一對多查詢,只需要把selectOne()修改為selectList()即可。

關聯(lián)對象查詢,有兩種實現(xiàn)方式,一種是單獨發(fā)送一個sql去查詢關聯(lián)對象,賦給主對象,然后返回主對象。另一種是使用嵌套查詢,嵌套查詢的含義為使用join查詢,一部分列是A對象的屬性值,另外一部分列是關聯(lián)對象B的屬性值,好處是只發(fā)一個sql查詢,就可以把主對象和其關聯(lián)對象查出來。

505.MyBatis里面的動態(tài)Sql是怎么設定的?用什么語法?

答:MyBatis里面的動態(tài)Sql一般是通過if節(jié)點來實現(xiàn),通過OGNL語法來實現(xiàn),但是如果要寫的完整,必須配合where,trim節(jié)點,where節(jié)點是判斷包含節(jié)點有內(nèi)容就插入where,否則不插入,trim節(jié)點是用來判斷如果動態(tài)語句是以and 或or開始,那么會自動把這個and或者or取掉。

506.使用MyBatis的mapper接口調用時有哪些要求?

答:1)Mapper接口方法名和mapper.xml中定義的每個sql的id相同

2)Mapper接口方法的輸入?yún)?shù)類型和mapper.xml中定義的每個sql 的parameterType的類型相同

3)Mapper接口方法的輸出參數(shù)類型和mapper.xml中定義的每個sql的resultType的類型相同

4)Mapper.xml文件中的namespace即是mapper接口的類路徑。

507.Mybatis是如何將sql執(zhí)行結果封裝為目標對象并返回的?都有哪些映射形式?

答:第一種是使用< resultMap>標簽,逐一定義列名和對象屬性名之間的映射關系。

第二種是使用sql列的別名功能,將列別名書寫為對象屬性名,比如T_NAME AS NAME,對象屬性名一般是name,小寫,但是列名不區(qū)分大小寫,Mybatis會忽略列名大小寫,智能找到與之對應對象屬性名,你甚至可以寫成T_NAME AS NaMe,Mybatis一樣可以正常工作。

有了列名與屬性名的映射關系后,Mybatis通過反射創(chuàng)建對象,同時使用反射給對象的屬性逐一賦值并返回,那些找不到映射關系的屬性,是無法完成賦值的。

508.MyBatis接口綁定有幾種實現(xiàn)方式,分別是怎么實現(xiàn)的?

答:接口綁定有兩種實現(xiàn)方式,一種是通過注解綁定,就是在接口的方法上面加上@Select@Update等注解里面包含Sql語句來綁定,另外一種就是通過xml里面寫SQL來綁定,在這種情況下,要指定xml映射文件里面的namespace必須為接口的全路徑名.

509.MyBatis實現(xiàn)一對一有幾種方式?具體怎么操作的?

答:有聯(lián)合查詢和嵌套查詢,聯(lián)合查詢是幾個表聯(lián)合查詢,只查詢一次,通過在resultMap里面配置association節(jié)點配置一對一的類就可以完成;嵌套查詢是先查一個表,根據(jù)這個表里面的結果的外鍵id,去再另外一個表里面查詢數(shù)據(jù),也是通過association配置,但另外一個表的查詢通過select屬性配置。

510.什么情況下用注解綁定,什么情況下用xml綁定?

答:當Sql語句比較簡單時候,用注解綁定;當SQL語句比較復雜時候,用xml綁定,一般用xml綁定的比較多

511.MyBatis的好處是什么?

答:1) MyBatis把sql語句從Java源程序中獨立出來, 放在單獨的XML文件中編寫,給程序的維護帶來了很大便利。

2) MyBatis封裝了底層JDBC API的調用細節(jié),并能自動將結果集轉換成Java Bean對象,大大簡化了Java數(shù)據(jù)庫編程的重復工作。

3) 因為MyBatis需要程序員自己去編寫sql語句,程序員可以結合數(shù)據(jù)庫自身的特點靈活控制sql語句, 因此能夠實現(xiàn)比Hibernate等全自動orm框架更高的查詢效率,能夠完成復雜查詢。

微服務框架

512.Spring Boot有哪些優(yōu)點?

答:Spring Boot的優(yōu)點有:

減少開發(fā),測試時間和努力。

使用JavaConfig有助于避免使用XML。

避免大量的Maven導入和各種版本沖突。

提供意見發(fā)展方法。

通過提供默認值快速開始開發(fā)。

沒有單獨的Web服務器需要。這意味著你不再需要啟動Tomcat,Glassfish或其他任何東西。

需要更少的配置 因為沒有web.xml文件。只需添加用@ Configuration注釋的類,然后添加用@Bean注釋的方法,Spring將自動加載對象并像以前一樣對其進行管理。您甚至可以將@Autowired添加到bean方法中,以使Spring自動裝入需要的依賴關系中。

基于環(huán)境的配置 使用這些屬性,您可以將您正在使用的環(huán)境傳遞到應用程序:-Dspring.profiles.active = {enviornment}。在加載主應用程序屬性文件后,Spring將在(application{environment} .properties)中加載后續(xù)的應用程序屬性文件。

513.如何重新加載Spring Boot上的更改,而無需重新啟動服務器?

答:這可以使用DEV工具來實現(xiàn)。通過這種依賴關系,您可以節(jié)省任何更改,嵌入式tomcat將重新啟動。Spring Boot有一個開發(fā)工具(DevTools)模塊,它有助于提高開發(fā)人員的生產(chǎn)力。Java開發(fā)人員面臨的一個主要挑戰(zhàn)是將文件更改自動部署到服務器并自動重啟服務器。開發(fā)人員可以重新加載Spring Boot上的更改,而無需重新啟動服務器。這將消除每次手動部署更改的需要。Spring Boot在發(fā)布它的第一個版本時沒有這個功能。這是開發(fā)人員最需要的功能。DevTools模塊完全滿足開發(fā)人員的需求。該模塊將在生產(chǎn)環(huán)境中被禁用。它還提供H2數(shù)據(jù)庫控制臺以更好地測試應用程序。

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
514.常見的系統(tǒng)架構風格有哪些?各有什么優(yōu)缺點?

1、單體架構

單體架構也稱之為單體系統(tǒng)或者是單體應用。就是一種把系統(tǒng)中所有的功能、模塊耦合在一個應用中的架構方式。

單體架構特點:打包成一個獨立的單元(導成一個唯一的jar包或者是war包),會一個進程的方式來運行。

單體架構的優(yōu)點、缺點

優(yōu)點:

項目易于管理

部署簡單

缺點:

測試成本高

可伸縮性差

可靠性差

迭代困難

跨語言程度差

團隊協(xié)作難

2、MVC架構

MVC架構特點:

MVC是模型(Model)、視圖(View)、控制器(Controller)3個單詞的縮寫。 下面我們從這3個方面來講解MVC中的三個要素。

Model是指數(shù)據(jù)模型,是對客觀事物的抽象。 如一篇博客文章,我們可能會以一個Post類來表示,那么,這個Post類就是數(shù)據(jù)對象。 同時,博客文章還有一些業(yè)務邏輯,如發(fā)布、回收、評論等,這一般表現(xiàn)為類的方法,這也是model的內(nèi)容和范疇。 對于Model,主要是數(shù)據(jù)、業(yè)務邏輯和業(yè)務規(guī)則。相對而言,這是MVC中比較穩(wěn)定的部分,一般成品后不會改變。 開發(fā)初期的最重要任務,主要也是實現(xiàn)Model的部分。這一部分寫得好,后面就可以改得少,開發(fā)起來就快。

View是指視圖,也就是呈現(xiàn)給用戶的一個界面,是model的具體表現(xiàn)形式,也是收集用戶輸入的地方。 如你在某個博客上看到的某一篇文章,就是某個Post類的表現(xiàn)形式。 View的目的在于提供與用戶交互的界面。換句話說,對于用戶而言,只有View是可見的、可操作的。 事實上也是如此,你不會讓用戶看到Model,更不會讓他直接操作Model。 你只會讓用戶看到你想讓他看的內(nèi)容。 這就是View要做的事,他往往是MVC中變化頻繁的部分,也是客戶經(jīng)常要求改來改去的地方。 今天你可能會以一種形式來展示你的博文,明天可能就變成別的表現(xiàn)形式了。

Contorller指的是控制器,主要負責與model和view打交道。 換句話說,model和view之間一般不直接打交道,他們老死不相往來。view中不會對model作任何操作, model不會輸出任何用于表現(xiàn)的東西,如HTML代碼等。這倆甩手不干了,那總得有人來干吧,只能Controller上了。 Contorller用于決定使用哪些Model,對Model執(zhí)行什么操作,為視圖準備哪些數(shù)據(jù),是MVC中溝通的橋梁。

MVC架構優(yōu)缺點

優(yōu)點:

各施其職,互不干涉。

在MVC模式中,三個層各施其職,所以如果一旦哪一層的需求發(fā)生了變化,就只需要更改相應的層中的代碼而不會影響到其它層中的代碼。

有利于開發(fā)中的分工。

在MVC模式中,由于按層把系統(tǒng)分開,那么就能更好的實現(xiàn)開發(fā)中的分工。網(wǎng)頁設計人員可以進行開發(fā)視圖層中的JSP,對業(yè)務熟悉的開發(fā)人員可開發(fā)業(yè)務層,而其它開發(fā)人員可開發(fā)控制層。

有利于組件的重用。

分層后更有利于組件的重用。如控制層可獨立成一個能用的組件,視圖層也可做成通用的操作界面。

缺點:

增加了系統(tǒng)結構和實現(xiàn)的復雜性。

視圖與控制器間的過于緊密的連接。

視圖對模型數(shù)據(jù)的低效率訪問。

3、面向服務架構(SOA)

面向服務的架構(SOA)是一個組件模型,它將應用程序拆分成不同功能單元(稱為服務)通過這些服務之間定義良好的接口和契約聯(lián)系起來。接口是采用中立的方式進行定義的,它應該獨立于實現(xiàn)服務的硬件平臺、操作系統(tǒng)和編程語言。這使得構建在各種各樣的系統(tǒng)中的服務可以以一種統(tǒng)一和通用的方式進行交互。

面向服務架構特點:

系統(tǒng)是由多個服務構成

每個服務可以單獨獨立部署

每個服務之間是松耦合的。服務內(nèi)部是高內(nèi)聚的,外部是低耦合的。高內(nèi)聚就是每個服務只關注完成一個功能。

服務的優(yōu)點、缺點

優(yōu)點:

測試容易

可伸縮性強

可靠性強

跨語言程度會更加靈活

團隊協(xié)作容易

系統(tǒng)迭代容易

缺點:

運維成本過高,部署數(shù)量較多

接口兼容多版本

分布式系統(tǒng)的復雜性

分布式事務

515.什么是AKF拆分原則?

業(yè)界對于可擴展的系統(tǒng)架構設計有一個樸素的理念,就是:通過加機器就可以解決容量和可用性問題。(如果一臺不行那就兩臺)。

我是個段子:(世界上沒有什么事是一頓燒烤不能解決的。如果有,那就兩頓。)

這一理念在“云計算”概念瘋狂流行的今天,得到了廣泛的認可!對于一個規(guī)模迅速增長的系統(tǒng)而言,容量和性能問題當然是首當其沖的。但是隨著時間的向前,系統(tǒng)規(guī)模的增長,除了面對性能與容量的問題外,還需要面對功能與模塊數(shù)量上的增長帶來的系統(tǒng)復雜性問題以及業(yè)務的變化帶來的提供差異化服務問題。而許多系統(tǒng),在架構設計時并未充分考慮到這些問題,導致系統(tǒng)的重構成為常態(tài),從而影響業(yè)務交付能力,還浪費人力財力!對此,《可擴展的藝術》一書提出了一個更加系統(tǒng)的可擴展模型——?AKF可擴展立方?(Scalability Cube) 。這個立方體中沿著三個坐標軸設置分別為:X、Y、Z。

Y軸擴展會將龐大的整體應用拆分為多個服務。每個服務實現(xiàn)一組相關的功能,如訂單管理、客戶管理等。在工程上常見的方案是?服務化架構(SOA)?。比如對于一個電子商務平臺,我們可以拆分成不同的服務

X軸擴展與我們前面樸素理念是一致的,通過絕對平等地復制服務與數(shù)據(jù),以解決容量和可用性的問題。其實就是將微服務運行多個實例,做集群加負載均衡的模式。

Z軸擴展通常是指基于請求者或用戶獨特的需求,進行系統(tǒng)劃分,并使得劃分出來的子系統(tǒng)是相互隔離但又是完整的。以生產(chǎn)汽車的工廠來舉例:福特公司為了發(fā)展在中國的業(yè)務,或者利用中國的廉價勞動力,在中國建立一個完整的子工廠,與美國工廠一樣,負責完整的汽車生產(chǎn)。這就是一種Z軸擴展。

516.什么是Spring Cloud?

Spring Cloud是一個微服務框架,相比Dubbo等RPC框架,?Spring Cloud提供的全套的分布式系統(tǒng)解決方案。

Spring Cloud對微服務基礎框架Netflix的多個開源組件進行了封裝,同時又實現(xiàn)了和云端平臺以及和Spring Boot開發(fā)框架的集成。

Spring Cloud為微服務架構開發(fā)涉及的配置管理,服務治理,熔斷機制,智能路由,微代理,控制總線,一次性token,全局一致性鎖,leader選舉,分布式session,集群狀態(tài)管理等操作提供了一種簡單的開發(fā)方式。

Spring Cloud 為開發(fā)者提供了快速構建分布式系統(tǒng)的工具,開發(fā)者可以快速的啟動服務或構建應用、同時能夠快速和云平臺資源進行對接

517.Spring Cloud與Dubbo的區(qū)別是什么?
518.什么是Eureka注冊中心?

Eureka是Netflix開發(fā)的服務發(fā)現(xiàn)組件,本身是一個基于REST的服務。Spring Cloud將它集成在其子項目spring-cloud-netflix中,以實現(xiàn)Spring Cloud的服務注冊于發(fā)現(xiàn),同時還提供了負載均衡、故障轉移等能力。

519.簡單談一下Eureka中的三種角色分別是什么?

1、Eureka Server

通過Register、Get、Renew等接口提供服務的注冊和發(fā)現(xiàn)。

2、Application Service (Service Provider)

服務提供方

把自身的服務實例注冊到Eureka Server中

3、Application Client (Service Consumer)

服務調用方

通過Eureka Server 獲取服務列表,消費服務。

520.什么是Ribbon

1.Ribbon 是一個基于Http和TCP的客服端負載均衡工具,它是基于Netflix Ribbon實現(xiàn)的。

2.它不像spring cloud服務注冊中心、配置中心、API網(wǎng)關那樣獨立部署,但是它幾乎存在于每個spring cloud 微服務中。包括feign提供的聲明式服務調用也是基于該Ribbon實現(xiàn)的。

3.ribbon默認提供很多種負載均衡算法,例如 輪詢、隨機 等等。甚至包含自定義的負載均衡算法。

521.集中式與進程內(nèi)負載均衡的區(qū)別

目前業(yè)界主流的負載均衡方案可分成兩類:

第一類:集中式負載均衡, 即在consumer和provider之間使用獨立的負載均衡設施(可以是硬件,如F5, 也可以是軟件,如nginx), 由該設施負責把 訪問請求 通過某種策略轉發(fā)至provider;

第二類:進程內(nèi)負載均衡,將負載均衡邏輯集成到consumer,consumer從服務注冊中心獲知有哪些地址可用,然后自己再從這些地址中選擇出一個合適的provider。

Ribbon就屬于后者,它只是一個類庫,集成于consumer進程,consumer通過它來獲取到provider的地址。

522.Ribbon的常見負載均衡策略有哪些?
id 策略名稱 策略對應的類名 實現(xiàn)原理
1 輪詢策略(默認) RoundRobinRule 輪詢策略表示每次都順序取下一個provider,比如一共有5個provider,第1次取第1個,第2次取第2個,第3次取第3個,以此類推
2 權重輪詢策略 WeightedResponseTimeRule 1.根據(jù)每個provider的響應時間分配一個權重,響應時間越長,權重越小,被選中的可能性越低。 2.原理:一開始為輪詢策略,并開啟一個計時器,每30秒收集一次每個provider的平均響應時間,當信息足夠時,給每個provider附上一個權重,并按權重隨機選擇provider,高權越重的provider會被高概率選中。
3 隨機策略 RandomRule 從provider列表中隨機選擇一個provider
4 最少并發(fā)數(shù)策略 BestAvailableRule 選擇正在請求中的并發(fā)數(shù)最小的provider,除非這個provider在熔斷中。
5 在“選定的負載均衡策略”基礎上進行重試機制 RetryRule 1.“選定的負載均衡策略”這個策略是輪詢策略RoundRobinRule 2.該重試策略先設定一個閾值時間段,如果在這個閾值時間段內(nèi)當選擇provider不成功,則一直嘗試采用“選定的負載均衡策略:輪詢策略”最后選擇一個可用的provider
6 可用性敏感策略 AvailabilityFilteringRule 過濾性能差的provider,有2種: 第一種:過濾掉在eureka中處于一直連接失敗provider 第二種:過濾掉高并發(fā)的provider
7 區(qū)域敏感性策略 ZoneAvoidanceRule 1.以一個區(qū)域為單位考察可用性,對于不可用的區(qū)域整個丟棄,從剩下區(qū)域中選可用的provider 2.如果這個ip區(qū)域內(nèi)有一個或多個實例不可達或響應變慢,都會降低該ip區(qū)域內(nèi)其他ip被選中的權重。
523.簡單說說什么是Feign?

Feign是一種聲明式、模板化的HTTP客戶端技術(僅在consumer中使用)。

524.什么是聲明式,有什么作用,解決什么問題?

聲明式調用就像調用本地方法一樣調用遠程方法;無感知遠程http請求。

1、Spring Cloud的聲明式調用, 可以做到使用 HTTP請求遠程服務時能就像調用本地方法一樣的體驗,開發(fā)者完全感知不到這是遠程方法,更感知不到這是個HTTP請求。

2、它像Dubbo一樣,consumer直接調用接口方法調用provider,而不需要通過常規(guī)的Http Client構造請求再解析返回數(shù)據(jù)。

3、它解決了讓開發(fā)者調用遠程接口就跟調用本地方法一樣,無需關注與遠程的交互細節(jié),更無需關注分布式環(huán)境開發(fā)。

525.什么是服務的災難性的雪崩效應?

在微服務架構中,一個請求需要調用多個服務是非常常見的。如客戶端訪問A服務,而A服務需要調用B服務,B服務需要調用C服務,由于網(wǎng)絡原因或者自身的原因,如果B服務或者C服務不能及時響應,A服務將處于阻塞狀態(tài),直到B服務C服務響應。此時若有大量的請求涌入,容器的線程資源會被消耗完畢,導致服務癱瘓。服務與服務之間的依賴性,故障會傳播,造成連鎖反應,會對整個微服務系統(tǒng)造成災難性的嚴重后果,這就是服務故障的“雪崩”效應

526.如何解決災難性雪崩效應?

降級

超時降級、資源不足時(線程或信號量)降級,降級后可以配合降級接口返回托底數(shù)據(jù)。實現(xiàn)一個fallback方法, 當請求后端服務出現(xiàn)異常的時候, 可以使用fallback方法返回的值.

隔離(線程池隔離和信號量隔離)

限制調用分布式服務的資源使用,某一個調用的服務出現(xiàn)問題不會影響其他服務調用。

熔斷

當失敗率(如因網(wǎng)絡故障/超時造成的失敗率高)達到閥值自動觸發(fā)降級,熔斷器觸發(fā)的快速失敗會進行快速恢復。

緩存

提供了請求緩存。

請求合并

提供請求合并。

527.線程池隔離和信號量隔離的區(qū)別
528.請回答微服務架構的六種常用設計模式是什么?

答:如下這六種
代理設計模式
聚合設計模式
鏈條設計模式
聚合鏈條設計模式
數(shù)據(jù)共享設計模式
異步消息設計模式

529.什么是網(wǎng)關服務?

答:網(wǎng)關服務,通常是外部訪問服務的唯一接口,訪問內(nèi)部的所有服務都必須先經(jīng)過網(wǎng)關服務。網(wǎng)關服務的主要功能是消息解析過濾,路由,轉發(fā)等。

530.網(wǎng)關服務中,路由器的4種路由規(guī)則方法是什么?

答:采用URL指定路由方式

采用服務名稱指定路由方式

路由的排除方法

路由的添加前綴方法

531.為什么要使用spring cloud config 配置中心?它解決了什么問題?
532.什么是Spring Cloud Bus
533.消息驅動Stream解決了什么問題?
534.為什么要使用微服務跟蹤?它解決了什么問題?
535.什么是ELK(ElasticSearch, Logstash, Kibana)

ELK是三個工具的集合,Elasticsearch + Logstash + Kibana,這三個工具組合形成了一套實用、易用的監(jiān)控架構,很多公司利用它來搭建可視化的海量日志分析平臺。

1. ElasticSearch

ElasticSearch是一個基于Lucene的搜索服務器。它提供了一個分布式多用戶能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java開發(fā)的,并作為Apache許可條款下的開放源碼發(fā)布,是當前流行的企業(yè)級搜索引擎。設計用于云計算中,能夠達到實時搜索,穩(wěn)定,可靠,快速,安裝使用方便。

2. Logstash

Logstash是一個用于管理日志和事件的工具,你可以用它去收集日志、轉換日志、解析日志并將他們作為數(shù)據(jù)提供給其它模塊調用,例如搜索、存儲等。

3. Kibana

Kibana是一個優(yōu)秀的前端日志展示框架,它可以非常詳細的將日志轉化為各種圖表,為用戶提供強大的數(shù)據(jù)可視化支持。

536.為什么要用ELK,它解決了什么問題?
537.什么是分布式跟蹤?:?Zipki?

數(shù)據(jù)庫

538.下列屬于關系型數(shù)據(jù)庫的是()(選擇兩項)
A. Oracle
B. MySql
C. IMS
D. MongoDB
答案:AB分析: IMS 是IP Mulitimedia Subsystem的縮寫,是IP多媒體系統(tǒng) MongoDB分布式文檔存儲數(shù)據(jù)庫
539.請列出Java常見的開源數(shù)據(jù)連接池,并對參數(shù)做出簡單的說明

答:在Java中開源的常用的數(shù)據(jù)庫連接池有以下幾種 :

(1)DBCP

DBCP是一個依賴Jakarta commons-pool對象池機制的數(shù)據(jù)庫連接池.DBCP可以直接的在應用程序中使用,Tomcat的數(shù)據(jù)源使用的就是DBCP。

(2)c3p0

c3p0是一個開放源代碼的JDBC連接池,它在lib目錄中與Hibernate一起發(fā)布,包括了實現(xiàn)jdbc3和jdbc2擴展規(guī)范說明的Connection 和Statement 池的DataSources 對象。

(3)Druid

阿里出品,淘寶和支付寶專用數(shù)據(jù)庫連接池,但它不僅僅是一個數(shù)據(jù)庫連接池,它還包含一個ProxyDriver,一系列內(nèi)置的JDBC組件庫,一個SQL Parser。支持所有JDBC兼容的數(shù)據(jù)庫,包括Oracle、MySql、Derby、Postgresql、SQL Server、H2等等。

540.儲蓄所有多個儲戶,儲戶在多個儲戶所存取款,儲蓄所與儲戶之間是()
A. 一對一的聯(lián)系
B. 多對一的聯(lián)系
C. 一對多的聯(lián)系
D. 多對多的聯(lián)系
答案:D
541.視圖是一個“虛表”,視圖的構造基于()
A. 基本表或視圖
B. 視圖
C. 數(shù)據(jù)字典
D. 基本表
答案:A
542.設有關系R(A,B,C,D)及其上的函數(shù)相關性集合F={B→A,BC→D},那么關系R最高是()
A. 第一范式的
B. 第二范式的
C. 第三范式的
D. BCNF范式的
答案:A
分析: 根據(jù)數(shù)據(jù)庫三大范式的依賴性要求,從B,BC函數(shù)確定A和D這一點上,明顯看出B,BC都有可能是主碼. 若B是主碼的話,仔細看會發(fā)現(xiàn),F中竟然沒有誰去函數(shù)確定C,這顯然是說不通的,(因為C至少會被B這個主碼函數(shù)確定); 若BC是主碼,那么F中存在非主屬性對候選碼的部分依賴,不滿足第二范式的要求,故為第一范式.
543.什么是DAO模式?

答:DAO(DataAccess Object)顧名思義是一個為數(shù)據(jù)庫或其他持久化機制提供了抽象接口的對象,在不暴露數(shù)據(jù)庫實現(xiàn)細節(jié)的前提下提供了各種數(shù)據(jù)操作。為了建立一個健壯的Java EE應用,應該將所有對數(shù)據(jù)源的訪問操作進行抽象化后封裝在一個公共API中。用程序設計語言來說,就是建立一個接口,接口中定義了此應用程序中將會用到的所有事務方法。在這個應用程序中,當需要和數(shù)據(jù)源進行交互的時候則使用這個接口,并且編寫一個單獨的類來實現(xiàn)這個接口,在邏輯上該類對應一個特定的數(shù)據(jù)存儲。DAO模式實際上包含了兩個模式,一是Data Accessor(數(shù)據(jù)訪問器),二是Data Object(數(shù)據(jù)對象),前者要解決如何訪問數(shù)據(jù)的問題,而后者要解決的是如何用對象封裝數(shù)據(jù)。

544.數(shù)據(jù)庫MySQL,Oracle,SqlServer分頁時用的語句

Mysql:使用limit關鍵字

Select * from 表名 where 條件 limit 開始位置,結束位置。通過動態(tài)的改變開始和結束位置的值來實現(xiàn)分頁。

Oracle:通過rownum來實現(xiàn)

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:要查詢的數(shù)據(jù)

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怎么優(yōu)化執(zhí)行效率更高

答: 1. SQL優(yōu)化的原則是:將一次操作需要讀取的BLOCK數(shù)減到最低,即在最短的時間達到最大的數(shù)據(jù)吞吐量。

調整不良SQL通常可以從以下幾點切入:

1) 檢查不良的SQL,考慮其寫法是否還有可優(yōu)化內(nèi)容

2) 檢查子查詢 考慮SQL子查詢是否可以用簡單連接的方式進行重新書寫

3) 檢查優(yōu)化索引的使用

4) 考慮數(shù)據(jù)庫的優(yōu)化器

2. 避免出現(xiàn)SELECT * FROM table 語句,要明確查出的字段。

3. 在一個SQL語句中,如果一個where條件過濾的數(shù)據(jù)庫記錄越多,定位越準確,則該where條件越應該前移。

4. 查詢時盡可能使用索引覆蓋。即對SELECT的字段建立復合索引,這樣查詢時只進行索引掃描,不讀取數(shù)據(jù)塊。

5. 在判斷有無符合條件的記錄時建議不要用SELECT COUNT (*)和select top 1 語句。

6. 使用內(nèi)層限定原則,在拼寫SQL語句時,將查詢條件分解、分類,并盡量在SQL語句的最里層進行限定,以減少數(shù)據(jù)的處理量。

7. 應絕對避免在order by子句中使用表達式。

9. 小心使用 IN 和 OR,需要注意In集合中的數(shù)據(jù)量。建議集合中的數(shù)據(jù)不超過200個。

10. <> 用 < 、 > 代替,>用>=代替, < 用< =代替,這樣可以有效的利用索引。

11. 在查詢時盡量減少對多余數(shù)據(jù)的讀取包括多余的列與多余的行。

12. 對于復合索引要注意,例如在建立復合索引時列的順序是F1,F(xiàn)2,F(xiàn)3,則在where或order by子句中這些字段出現(xiàn)的順序要與建立索引時的字段順序一致,且必須包含第一列。只能是F1或F1,F(xiàn)2或F1,F(xiàn)2,F(xiàn)3。否則不會用到該索引。

547.談談數(shù)據(jù)庫去空格的情況

一、表中字符串帶空格的原因

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.根據(jù)你以往的經(jīng)驗簡單敘述一下MYSQL的優(yōu)化

答:
1.數(shù)據(jù)庫的設計
盡量把數(shù)據(jù)庫設計的更小的占磁盤空間.
1).盡可能使用更小的整數(shù)類型.(mediumint就比int更合適).
2).盡可能的定義字段為not null,除非這個字段需要null.
3).如果沒有用到變長字段的話比如varchar,那就采用固定大小的紀錄格式比如char.
4).表的主索引應該盡可能的短.這樣的話每條紀錄都有名字標志且更高效.
5).只創(chuàng)建確實需要的索引。索引有利于檢索記錄,但是不利于快速保存記錄。如果總是要在表的組合字段上做搜索,那么就在這些字段上創(chuàng)建索引。索引的第一部分必須是最常使用的字段.如果總是需要用到很多字段,首先就應該多復制這些字段,使索引更好的壓縮。
6).所有數(shù)據(jù)都得在保存到數(shù)據(jù)庫前進行處理。
7).所有字段都得有默認值。
8).在某些情況下,把一個頻繁掃描的表分成兩個速度會快好多。在對動態(tài)格式表掃描以取得相關記錄時,它可能使用更小的靜態(tài)格式表的情況下更是如此。
2.系統(tǒng)的用途
1).盡量使用長連接.
2).explain 復雜的SQL語句。
3).如果兩個關聯(lián)表要做比較話,做比較的字段必須類型和長度都一致.
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來導入大量數(shù)據(jù),這比單純的indert快好多.
8).經(jīng)常OPTIMIZE TABLE 來整理碎片.
9).還有就是date 類型的數(shù)據(jù)如果頻繁要做比較的話盡量保存在unsigned int 類型比較快。
3.系統(tǒng)的瓶頸
1).磁盤搜索.
并行搜索,把數(shù)據(jù)分開存放到多個磁盤中,這樣能加快搜索時間.
2).磁盤讀寫(IO)
可以從多個媒介中并行的讀取數(shù)據(jù)。
3).CPU周期
數(shù)據(jù)存放在主內(nèi)存中.這樣就得增加CPU的個數(shù)來處理這些數(shù)據(jù)。
4).內(nèi)存帶寬
當CPU要將更多的數(shù)據(jù)存放到CPU的緩存中來的話,內(nèi)存的帶寬就成了瓶頸.

549.以Oracle11R為例簡述數(shù)據(jù)庫集群部署

命令行工具
–crsctl管理集群相關的操作:
-啟動和關閉Oracle集群
-啟用和禁用Oracle集群后臺進程
-注冊集群資源
-srvctl 管理Oracle 資源相關操作
-啟動和關閉數(shù)據(jù)庫實例和服務
在Oracle Grid安裝的home路徑下的命令行工具crsctl和srvctl用來管理Oracle集群。使用crsctl可以監(jiān)控和管理任何集群節(jié)點的集群組件和資源。srvctl工具提供了類似的功能,來監(jiān)控和管理Oracle相關的資源,例如數(shù)據(jù)庫實例和數(shù)據(jù)庫服務。crsctl命令只能是集群管理者來運行,srvctl命令可以是其他用戶,例如數(shù)據(jù)庫管理員來使用。

550.說一下數(shù)據(jù)庫的存儲過程?

一、存儲過程與函數(shù)的區(qū)別:

1.一般來說,存儲過程實現(xiàn)的功能要復雜一點,而函數(shù)的實現(xiàn)的功能針對性比較強。

2.對于存儲過程來說可以返回參數(shù)(output),而函數(shù)只能返回值或者表對象。

3.存儲過程一般是作為一個獨立的部分來執(zhí)行,而函數(shù)可以作為查詢語句的一個部分來調用,由于函數(shù)可以返回一個表對象,因此它可以在查詢語句中位于FROM關鍵字的后面。

二、存儲過程的優(yōu)點:

1.執(zhí)行速度更快 – 在數(shù)據(jù)庫中保存的存儲過程語句都是編譯過的

2.允許模塊化程序設計 – 類似方法的復用

3.提高系統(tǒng)安全性 – 防止SQL注入

4.減少網(wǎng)絡流通量 – 只要傳輸存儲過程的名稱

系統(tǒng)存儲過程一般以sp開頭,用戶自定義的存儲過程一般以usp開頭

551.數(shù)據(jù)庫創(chuàng)建索引的缺點?

缺點:

第一,創(chuàng)建索引和維護索引要耗費時間,這種時間隨著數(shù)據(jù)量的增加而增加。

第二,索引需要占物理空間,除了數(shù)據(jù)表占數(shù)據(jù)空間之外,每一個索引還要占一定的物理空間,如果要建立聚簇索引,那么需要的空間就會更大。

第三,當對表中的數(shù)據(jù)進行增加、刪除和修改的時候,索引也要動態(tài)的維護,這樣就降低了數(shù)據(jù)的維護速度。

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操縱關系數(shù)據(jù)庫
C. 在 HQL 與 SQL 中,都包含 select,insert,update,delete 語句
D. HQL僅用于査詢數(shù)據(jù),不支持insert,update和delete語句
答案:BC
554.下面是學生表(student)的結構說明
字段名稱 字段解釋 字段類型 字段長度 約束
s_id 學號 字符 10 PK
s_name 學生姓名 字符 50 Not null
s_age 學生年齡 數(shù)值 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 成績 數(shù)值 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、查詢所有同學的學號、姓名、選課數(shù)、總成績;

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、查詢姓“李”的老師的個數(shù);

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.為管理崗位業(yè)務培訓信息,有如下3個表:

S(S#,SN,SD,SA),其中S#,SN,SD,SA分別代表學號、學員姓名、所屬單位、學員年齡。 C (C#,CN ),其中C#,CN分別代表課程編號、課程名稱
SC(S#,C#,G),其中S#,C#,G分別代表學號、所選修的課程編號、學習成績
請使用2種標準SQL語句査洵選修課程名稱為“稅收基礎”的學員學號和姓名,并說明其優(yōu)缺點 。

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='稅收基礎'

優(yōu)點:

SQL99將連接條件和過濾條件分開,顯得代碼清晰。
SQL92書寫簡單易于理解。

缺點:

SQL92連接條件和過濾條件都寫在一起,不利于查看。
SQL99書寫相對麻煩不易于理解。

556.用Java怎么實現(xiàn)有每天有1億條記錄的DB儲存?MySQL上億記錄數(shù)據(jù)量的數(shù)據(jù)庫如何設計?

1.這么大數(shù)據(jù)量首先建議 使用大數(shù)據(jù)的DB,可以用spring batch 來做類似這樣的處理。定量向DB存儲數(shù)據(jù)。如果需要定時,可以考慮 quartz。

Mysql數(shù)據(jù)庫設計:

1.讀寫分離;

2.縱向橫向拆分庫、表。

MySQL的基本功能中包括replication(復制)功能。所謂replication,就是確定master以及與之同步的slave服務器,再加上slave將master中寫入的內(nèi)容polling過來更新自身內(nèi)容的功能。這樣slave就是master的replica(復制品)。這樣就可以準備多臺內(nèi)容相同的服務器。

通過master和salve的replication,準備好多臺服務器之后,讓應用程序服務器通過負載均衡器去處理查詢slave。這樣就能將查詢分散到多臺服務器上。

應用程序實現(xiàn)上應該只把select等讀取之類的查詢發(fā)送給負載均衡器,而更新應當直接發(fā)送給master。要是在slave上執(zhí)行更新操作,slave和master的內(nèi)容就無法同步。MySQL會檢測到master和slave之間內(nèi)容差異,并停止replication,這回導致系統(tǒng)故障。Slave可以采用LVS(linux系統(tǒng)自帶的負載均衡器)實現(xiàn)查詢的負載均衡。

使用MySQL的replication是利用的冗余化,實現(xiàn)冗余化需要實現(xiàn)的最小服務器數(shù)量是4臺,三臺slave和一臺master,slave為什么是需要三臺呢,比如一臺slave死機了,現(xiàn)在需要修復再次上線,那么意味著你必須停止一臺slave來復制MySQL的數(shù)據(jù),如果只有兩臺slave,一臺壞了,你就必須停止服務,如果有三臺,壞了一臺,你復制數(shù)據(jù)時停止一臺,還有一臺可以運維。

對于數(shù)據(jù)的處理是能放入到內(nèi)存中就盡量放入到內(nèi)存中如果不能放入到內(nèi)存中,可以利用MySQL的Partitioning。

Partitioning就是表分割也就是講A表和B表放在不同的服務器上。簡單來說,Partitioning就是充分利用局部性進行分割,提高緩存利用效率,從而實現(xiàn)Partitioning的效果。其中最重要的一點就是以Partitioning為前提設計的系統(tǒng)將表分割開,用RDBMS的方式的話,對于一對多的關系經(jīng)常使用JOIN查詢將兩張表連接起來。但是如果將表分割開了之后,也就是兩張表不在同一個數(shù)據(jù)庫,不在同一個服務器上怎樣使用JOIN操作,這里需要注意的是如果是用where in操作不是省了一些麻煩了嘛。

557.Mysql的引擎有哪些?支持事物么?DB儲存引擎有哪些?

MySQL有多種存儲引擎,每種存儲引擎有各自的優(yōu)缺點,可以擇優(yōu)選擇使用:

MyISAM、InnoDB、MERGE、MEMORY(HEAP)、BDB(BerkeleyDB)、EXAMPLE、FEDERATED、ARCHIVE、CSV、BLACKHOLE。

MySQL支持數(shù)個存儲引擎作為對不同表的類型的處理器。MySQL存儲引擎包括處理事務安全表的引擎和處理非事務安全表的引擎。

· MyISAM管理非事務表。它提供高速存儲和檢索,以及全文搜索能力。MyISAM在所有MySQL配置里被支持,它是默認的存儲引擎,除非你配置MySQL默認使用另外一個引擎。

· MEMORY存儲引擎提供“內(nèi)存中”表。MERGE存儲引擎允許集合將被處理同樣的MyISAM表作為一個單獨的表。就像MyISAM一樣,MEMORY和MERGE存儲引擎處理非事務表,這兩個引擎也都被默認包含在MySQL中。

注釋:MEMORY存儲引擎正式地被確定為HEAP引擎。

· InnoDB和BDB存儲引擎提供事務安全表。BDB被包含在為支持它的操作系統(tǒng)發(fā)布的MySQL-Max二進制分發(fā)版里。InnoDB也默認被包括在所 有MySQL 5.1二進制分發(fā)版里,你可以按照喜好通過配置MySQL來允許或禁止任一引擎。

· EXAMPLE存儲引擎是一個“存根”引擎,它不做什么。你可以用這個引擎創(chuàng)建表,但沒有數(shù)據(jù)被存儲于其中或從其中檢索。這個引擎的目的是服務,在 MySQL源代碼中的一個例子,它演示說明如何開始編寫新存儲引擎。同樣,它的主要興趣是對開發(fā)者。

· NDB Cluster是被MySQL Cluster用來實現(xiàn)分割到多臺計算機上的表的存儲引擎。它在MySQL-Max 5.1二進制分發(fā)版里提供。這個存儲引擎當前只被Linux, Solaris, 和Mac OS X 支持。在未來的MySQL分發(fā)版中,我們想要添加其它平臺對這個引擎的支持,包括Windows。

· ARCHIVE存儲引擎被用來無索引地,非常小地覆蓋存儲的大量數(shù)據(jù)。

· CSV存儲引擎把數(shù)據(jù)以逗號分隔的格式存儲在文本文件中。

· BLACKHOLE存儲引擎接受但不存儲數(shù)據(jù),并且檢索總是返回一個空集。

· FEDERATED存儲引擎把數(shù)據(jù)存在遠程數(shù)據(jù)庫中。在MySQL 5.1中,它只和MySQL一起工作,使用MySQL C Client API。在未來的分發(fā)版中,我們想要讓它使用其它驅動器或客戶端連接方法連接到另外的數(shù)據(jù)源。

558.以下是學生考試結果表
fname kecheng fenshu
張三 語文 81
張三 數(shù)學 65
李四 語文 76
李四 數(shù)學 90
王五 語文 61
王五 數(shù)學 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.庫中已經(jīng)存在雇用表表名:

org_employee;表中字段:雇員編號(emp_id),雇員姓名(em_name),雇員年齡(emp_age),雇員部門(depart_name);請寫出執(zhí)行以下操作的sql語句:

1)向表中增加一條數(shù)據(jù):雇員編號(1001),雇員姓名(張三),雇員年齡(24),雇員部門(研發(fā)部);

INSERT INTO org_employee

VALUES(‘1001’,’張三’,’24’,’研發(fā)部’);

2)查詢雇員年齡在55(包含)至60(不包含)歲之間的雇員數(shù)據(jù)

SELECT * FROM org_employee

WHERE emp_age>=55 and emp_age <60;

3)分部門查詢各個部門的雇員數(shù)量

SELECT COUNT(*),depart_name group by depart_name;

4)刪除姓名為張三的雇員數(shù)據(jù)

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中的數(shù)據(jù),表名為:t_test,記錄某場比賽的結果。

請用sql語句實現(xiàn)表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.請將如下數(shù)據(jù)庫語句進行優(yōu)化,使其執(zhí)行效率更高(提示:…不需要更改)
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’);

優(yōu)化的理由:not in 和not exists

如果查詢語句使用了not in 那么內(nèi)外表都進行全表掃描,沒有用到索引;

而not extsts 的子查詢依然能用到表上的索引。所以無論那個表大,用not exists 都比not in 要快。

562.請簡述如何將Oracle中的數(shù)據(jù)庫轉至DB2中,需要保證表結構和數(shù)據(jù)不變

使用ETL工具,如infomatic,datastage,kettle等,可以完成異構數(shù)據(jù)庫的遷移

以kettle為例

表輸入選擇 oracle庫

表輸出選擇DB庫

循環(huán)執(zhí)行可以進行全庫遷移

563.學生成績表
姓名:name 課程:subject 分數(shù):score 學號:stuid
張三 數(shù)學 89 1
張三 語文 80 1
張三 英語 70 1
李四 數(shù)學 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數(shù)據(jù)庫中有兩張表Stu(學生表)和Grade(分數(shù)表),如下圖所示:

Stu表

sid(學生ID) sname(姓名) sage(年齡)
1 張三 23
2 李四 25
3 王五 24

Grade表

gid(分數(shù)主鍵) cid(課程ID) sid(學生主鍵) grade(分數(shù))
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統(tǒng)計出有兩門以上的課的分數(shù)在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 學生年齡 數(shù)值 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 成績 數(shù)值 3 Not null

查詢同名同姓學生名單,并統(tǒng)計同名人數(shù)

select 姓名,count(學號) as num

from 學生表

group by 姓名

having count(學號)>1 --保證查找到的都是存在2個以上(包括2)的同名同姓的姓名及人數(shù)。

查詢平均成績大于60分的學生的學號和平均成績;

Select s_id,avg(score) from sc groupby s_id having avg(score)>60

查詢姓“李”的老師的個數(shù);

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 字段的數(shù)值復制到A表中

A表

ID NAME

B表

ID NAME OTHER
1 Aaa Ddd
2 Bbb Eee

insert into a select id,name from b;

568.什么是基本表,什么是視圖,兩者的區(qū)別和聯(lián)系是什么?

它是從一個或幾個基本表中導出的 表,是從現(xiàn)有基本表中抽取若干子集組成用戶的“專用表”。

基本表:基本表的定義指建立基本關系模式,
而變更則是指對數(shù)據(jù)庫中已存在的基本表進行刪除與修改。
區(qū)別:
1、視圖是已經(jīng)編譯好的sql語句。而表不是
2、視圖沒有實際的物理記錄。而表有。
3、表是內(nèi)容,視圖是窗口
4、表只用物理空間而視圖不占用物理空間,
視圖只是邏輯概念的存在,表可以及時對它進行修改,
但視圖只能有創(chuàng)建的語句來修改
5、表是內(nèi)模式,試圖是外模式
6、視圖是查看數(shù)據(jù)表的一種方法,
可以查詢數(shù)據(jù)表中某些字段構成的數(shù)據(jù),
只是一些SQL語句的集合。從安全的角度說,
視圖可以不給用戶接觸數(shù)據(jù)表,從而不知道表結構。
7、表屬于全局模式中的表,是實表;視圖屬于局部模式的表,
是虛表。
8、視圖的建立和刪除只影響視圖本身,不影響對應的基本表。
聯(lián)系:視圖(view)是在基本表之上建立的表,它的結構(
即所定義的列)和內(nèi)容(即所有數(shù)據(jù)行)都來自基本表,
它依據(jù)基本表存在而存在。一個視圖可以對應一個基本表,
也可以對應多個基本表。
視圖是基本表的抽象和在邏輯意義上建立的新關系

569.什么是事務?什么是鎖?

事務與鎖是不同的。事務具有ACID(原子性、一致性、隔離性和持久性),鎖是用于解決隔離性的一種機制。事務的隔離級別通過鎖的機制來實現(xiàn)。另外鎖有不同的粒度,同時事務也是有不同的隔離級別的(一般有四種:讀未提交Read uncommitted,
讀已提交Read committed,
可重復讀Repeatable read,
可串行化Serializable)。
在具體的程序設計中,開啟事務其實是要數(shù)據(jù)庫支持才行的,如果數(shù)據(jù)庫本身不支持事務,那么仍然無法確保你在程序中使用的事務是有效的。
鎖可以分為樂觀鎖和悲觀鎖:
悲觀鎖:認為在修改數(shù)據(jù)庫數(shù)據(jù)的這段時間里存在著也想修改此數(shù)據(jù)的事務;
樂觀鎖:認為在短暫的時間里不會有事務來修改此數(shù)據(jù)庫的數(shù)據(jù);
我們一般意義上講的鎖其實是指悲觀鎖,在數(shù)據(jù)處理過程中,將數(shù)據(jù)置于鎖定狀態(tài)(由數(shù)據(jù)庫實現(xiàn))
如果開啟了事務,在事務沒提交之前,別人是無法修改該數(shù)據(jù)的;如果rollback,你在本次事務中的修改將撤消(不是別人修改的會沒有,因為別人此時無法修改)。當然,前提是你使用的數(shù)據(jù)庫支持事務。還有一個要注意的是,部分數(shù)據(jù)庫支持自定義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
查詢所有同學的學號、姓名、選課數(shù)、總成績
select Student.S#,Sname,COUNT(*) 選課數(shù),SUM(score) 總成績
from Student JOIN SC on Student.S#=SC.S#
group by Student.S#,Sname
查詢姓“李”的老師的個數(shù)
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內(nèi)存管理機制,以及垃圾回收的原理和使用過Java調優(yōu)工具

內(nèi)存管理的職責為分配內(nèi)存,回收內(nèi)存。 沒有自動內(nèi)存管理的語言/平臺容易發(fā)生錯誤。

典型的問題包括懸掛指針問題,一個指針引用了一個已經(jīng)被回收的內(nèi)存地址,導致程序的運行完全不可知。

另一個典型問題為內(nèi)存泄露,內(nèi)存已經(jīng)分配,但是已經(jīng)沒有了指向該內(nèi)存的指針,導致內(nèi)存泄露。 程序員要花費大量時間在調試該類問題上。

573.描述JVM加載class文件的原理機制

JVM中類的裝載是由類加載器(ClassLoader)和它的子類來實現(xiàn)的,Java中的類加載器是一個重要的Java運行時系統(tǒng)組件,它負責在運行時查找和裝入類文件中的類。

由于Java的跨平臺性,經(jīng)過編譯的Java源程序并不是一個可執(zhí)行程序,而是一個或多個類文件。當Java程序需要使用某個類時,JVM會確保這個類已經(jīng)被加載、連接(驗證、準備和解析)和初始化。類的加載是指把類的.class文件中的數(shù)據(jù)讀入到內(nèi)存中,通常是創(chuàng)建一個字節(jié)數(shù)組讀入.class文件,然后產(chǎn)生與所加載類對應的Class對象。加載完成后,Class對象還不完整,所以此時的類還不可用。當類被加載后就進入連接階段,這一階段包括驗證、準備(為靜態(tài)變量分配內(nèi)存并設置默認的初始值)和解析(將符號引用替換為直接引用)三個步驟。最后JVM對類進行初始化,包括:1)如果類存在直接的父類并且這個類還沒有被初始化,那么就先初始化父類;2)如果類中存在初始化語句,就依次執(zhí)行這些初始化語句。

 類的加載是由類加載器完成的,類加載器包括:根加載器(BootStrap)、擴展加載器(Extension)、系統(tǒng)加載器(System)和用戶自定義類加載器(java.lang.ClassLoader的子類)。從Java 2(JDK 1.2)開始,類加載過程采取了父親委托機制(PDM)。PDM更好的保證了Java平臺的安全性,在該機制中,JVM自帶的Bootstrap是根加載器,其他的加載器都有且僅有一個父類加載器。類的加載首先請求父類加載器加載,父類加載器無能為力時才由其子類加載器自行加載。JVM不會向Java程序提供對Bootstrap的引用。下面是關于幾個類加載器的說明:

Bootstrap:一般用本地代碼實現(xiàn),負責加載JVM基礎核心類庫(rt.jar);

Extension:從java.ext.dirs系統(tǒng)屬性所指定的目錄中加載類庫,它的父加載器是Bootstrap;

System:又叫應用類加載器,其父類是Extension。它是應用最廣泛的類加載器。它從環(huán)境變量classpath或者系統(tǒng)屬性java.class.path所指定的目錄中記載類,是用戶自定義加載器的默認父加載器。

574.說說JVM原理?內(nèi)存泄漏與溢出的區(qū)別?何時產(chǎn)生內(nèi)存泄漏?

答:JVM原理:

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

內(nèi)存泄漏與溢出的區(qū)別:

1) 內(nèi)存泄漏是指分配出去的內(nèi)存無法回收了。

2) 內(nèi)存溢出是指程序要求的內(nèi)存,超出了系統(tǒng)所能分配的范圍,從而發(fā)生溢出。比如用byte類型的變量存儲10000這個數(shù)據(jù),就屬于內(nèi)存溢出。

3) 內(nèi)存溢出是提供的內(nèi)存不夠;內(nèi)存泄漏是無法再提供內(nèi)存資源。

何時產(chǎn)生內(nèi)存泄漏:

1) 靜態(tài)集合類:在使用Set、Vector、HashMap等集合類的時候需要特別注意,有可能會發(fā)生內(nèi)存泄漏。當這些集合被定義成靜態(tài)的時候,由于它們的生命周期跟應用程序一樣長,這時候,就有可能會發(fā)生內(nèi)存泄漏。

2) 監(jiān)聽器:在Java中,我們經(jīng)常會使用到監(jiān)聽器,如對某個控件添加單擊監(jiān)聽器addOnClickListener(),但往往釋放對象的時候會忘記刪除監(jiān)聽器,這就有可能造成內(nèi)存泄漏。好的方法就是,在釋放對象的時候,應該記住釋放所有監(jiān)聽器,這就能避免了因為監(jiān)聽器而導致的內(nèi)存泄漏。

3) 各種連接:Java中的連接包括數(shù)據(jù)庫連接、網(wǎng)絡連接和io連接,如果沒有顯式調用其close()方法,是不會自動關閉的,這些連接就不能被GC回收而導致內(nèi)存泄漏。一般情況下,在try代碼塊里創(chuàng)建連接,在finally里釋放連接,就能夠避免此類內(nèi)存泄漏。

4) 外部模塊的引用:調用外部模塊的時候,也應該注意防止內(nèi)存泄漏。如模塊A調用了外部模塊B的一個方法,如:public void register(Object o)。這個方法有可能就使得A模塊持有傳入對象的引用,這時候需要查看B模塊是否提供了去除引用的方法,如unregister()。這種情況容易忽略,而且發(fā)生了內(nèi)存泄漏的話,比較難察覺,應該在編寫代碼過程中就應該注意此類問題。

5) 單例模式:使用單例模式的時候也有可能導致內(nèi)存泄漏。因為單例對象初始化后將在JVM的整個生命周期內(nèi)存在,如果它持有一個外部對象(生命周期比較短)的引用,那么這個外部對象就不能被回收,而導致內(nèi)存泄漏。如果這個外部對象還持有其它對象的引用,那么內(nèi)存泄漏會更嚴重,因此需要特別注意此類情況。這種情況就需要考慮下單例模式的設計會不會有問題,應該怎樣保證不會產(chǎn)生內(nèi)存泄漏問題。

575.GC線程是否為守護線程?

GC線程是守護線程。線程分為守護線程和非守護線程(即用戶線程)。只要當前JVM實例中尚存在任何一個非守護線程沒有結束,守護線程就全部工作;只有當最后一個非守護線程結束時,守護線程隨著JVM一同結束工作。

576.Java的類加載器都有哪些,每個類加載器都有加載那些類,什么是雙親委派模型,是做什么的?

類加載器按照層次,從頂層到底層,分為以下三種:

(1)啟動類加載器(Bootstrap ClassLoader)

這個類加載器負責將存放在JAVA_HOME/lib下的,或者被-Xbootclasspath參數(shù)所指定的路徑中的,并且是虛擬機識別的類庫加載到虛擬機內(nèi)存中。啟動類加載器無法被Java程序直接引用。

(2)擴展類加載器(Extension ClassLoader)

這個加載器負責加載JAVA_HOME/lib/ext目錄中的,或者被java.ext.dirs系統(tǒng)變量所指定的路徑中的所有類庫,開發(fā)者可以直接使用擴展類加載器

(3)應用程序類加載器(Application ClassLoader)

這個加載器是ClassLoader中getSystemClassLoader()方法的返回值,所以一般也稱它為系統(tǒng)類加載器。它負責加載用戶類路徑(Classpath)上所指定的類庫,可直接使用這個加載器,如果應用程序沒有自定義自己的類加載器,一般情況下這個就是程序中默認的類加載器

雙親委派模型:

雙親委派模型要求除了頂層的啟動類加載器外,其他的類加載器都應當有自己的父類加載器。這里類加載器之間的父子關系一般不會以繼承關系來實現(xiàn),而是都使用組合關系來復用父加載器的代碼

工作過程:

如果一個類加載器收到了類加載的請求,它首先不會自己去嘗試加載這個類,而是把這個請求委派給父類加載器去完成,每一個層次的類加載器都是如此,因此所有的加載請求最終都應該傳遞到頂層的啟動類加載器中,只有當父類加載器反饋自己無法完成這個請求(它的搜索范圍中沒有找到所需的類)時,子加載器才會嘗試自己去加載。

好處:

Java類隨著它的類加載器一起具備了一種帶有優(yōu)先級的層次關系。例如類Object,它放在rt.jar中,無論哪一個類加載器要加載這個類,最終都是委派給啟動類加載器進行加載,因此Object類在程序的各種類加載器環(huán)境中都是同一個類,判斷兩個類是否相同是通過classloader.class這種方式進行的,所以哪怕是同一個class文件如果被兩個classloader加載,那么他們也是不同的類。

577.垃圾回收器(GC)的基本原理是什么?垃圾回收器可以馬上回收內(nèi)存嗎?如何通知虛擬機進行垃圾回收?

1、對于GC來說,當程序員創(chuàng)建對象時,GC就開始監(jiān)控這個對象的地址、大小以及使用情況。通常,GC采用有向圖的方式記錄和管理堆(heap)中的所有對象。通過這種方式確定哪些對象是"可達的",哪些對象是"不可達的"。當GC確定一些對象為"不可達”時,GC就有責任回收這些內(nèi)存空間。

2、可以。程序員可以手動執(zhí)行System.gc(),通知GC運行,但是Java語言規(guī)范并不保證GC一定會執(zhí)行。

3. System.gc();或者Runtime.getRuntime().gc();

578.Java 中會存在內(nèi)存泄漏嗎,請簡單描述。

答:理論上Java因為有垃圾回收機制(GC)不會存在內(nèi)存泄露問題(這也是Java被廣泛使用于服務器端編程的一個重要原因);然而在實際開發(fā)中,可能會存在無用但可達的對象,這些對象不能被GC回收也會發(fā)生內(nèi)存泄露。一個例子就是hibernate的Session(一級緩存)中的對象屬于持久態(tài),垃圾回收器是不會回收這些對象的,然而這些對象中可能存在無用的垃圾對象。下面的例子也展示了Java中發(fā)生內(nèi)存泄露的情況:

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

上面的代碼實現(xiàn)了一個棧(先進后出(FILO))結構,乍看之下似乎沒有什么明顯的問題,它甚至可以通過你編寫的各種單元測試。然而其中的pop方法卻存在內(nèi)存泄露的問題,當我們用pop方法彈出棧中的對象時,該對象不會被當作垃圾回收,即使使用棧的程序不再引用這些對象,因為棧內(nèi)部維護著對這些對象的過期引用(obsolete reference)。在支持垃圾回收的語言中,內(nèi)存泄露是很隱蔽的,這種內(nèi)存泄露其實就是無意識的對象保持。如果一個對象引用被無意識的保留起來了,那么垃圾回收器不會處理這個對象,也不會處理該對象引用的其他對象,即使這樣的對象只有少數(shù)幾個,也可能會導致很多的對象被排除在垃圾回收之外,從而對性能造成重大影響,極端情況下會引發(fā)Disk Paging(物理內(nèi)存與硬盤的虛擬內(nèi)存交換數(shù)據(jù)),甚至造成OutOfMemoryError。?

579.GC 是什么?為什么要有GC?

答:GC是垃圾收集的意思,內(nèi)存處理是編程人員容易出現(xiàn)問題的地方,忘記或者錯誤的內(nèi)存回收會導致程序或系統(tǒng)的不穩(wěn)定甚至崩潰,Java提供的GC功能可以自動監(jiān)測對象是否超過作用域從而達到自動回收內(nèi)存的目的,Java語言沒有提供釋放已分配內(nèi)存的顯示操作方法。Java程序員不用擔心內(nèi)存管理,因為垃圾收集器會自動進行管理。要請求垃圾收集,可以調用下面的方法之一:System.gc() 或Runtime.getRuntime().gc() ,但JVM可以屏蔽掉顯示的垃圾回收調用。

垃圾回收可以有效的防止內(nèi)存泄露,有效的使用可以使用的內(nèi)存。垃圾回收器通常是作為一個單獨的低優(yōu)先級的線程運行,不可預知的情況下對內(nèi)存堆中已經(jīng)死亡的或者長時間沒有使用的對象進行清除和回收,程序員不能實時的調用垃圾回收器對某個對象或所有對象進行垃圾回收。在Java誕生初期,垃圾回收是Java最大的亮點之一,因為服務器端的編程需要有效的防止內(nèi)存泄露問題,然而時過境遷,如今Java的垃圾回收機制已經(jīng)成為被詬病的東西。移動智能終端用戶通常覺得iOS的系統(tǒng)比Android系統(tǒng)有更好的用戶體驗,其中一個深層次的原因就在于Android系統(tǒng)中垃圾回收的不可預知性。

補充:垃圾回收機制有很多種,包括:分代復制垃圾回收、標記垃圾回收、增量垃圾回收等方式。標準的Java進程既有棧又有堆。棧保存了原始型局部變量,堆保存了要創(chuàng)建的對象。Java平臺對堆內(nèi)存回收和再利用的基本算法被稱為標記和清除,但是Java對其進行了改進,采用“分代式垃圾收集”。這種方法會跟Java對象的生命周期將堆內(nèi)存劃分為不同的區(qū)域,在垃圾收集過程中,可能會將對象移動到不同區(qū)域:

伊甸園(Eden):這是對象最初誕生的區(qū)域,并且對大多數(shù)對象來說,這里是它們唯一存在過的區(qū)域。

幸存者樂園(Survivor):從伊甸園幸存下來的對象會被挪到這里。

終身頤養(yǎng)園(Tenured):這是足夠老的幸存對象的歸宿。年輕代收集(Minor-GC)過程是不會觸及這個地方的。當年輕代收集不能把對象放進終身頤養(yǎng)園時,就會觸發(fā)一次完全收集(Major-GC),這里可能還會牽扯到壓縮,以便為大對象騰出足夠的空間。

與垃圾回收相關的JVM參數(shù):

-Xms / -Xmx --- 堆的初始大小 / 堆的最大大小

-Xmn --- 堆中年輕代的大小

-XX:-DisableExplicitGC --- 讓System.gc()不產(chǎn)生任何作用

-XX:+PrintGCDetail --- 打印GC的細節(jié)

-XX:+PrintGCDateStamps --- 打印GC操作的時間戳?

Linux操作

580.請寫出常用的linux指令不低于10個,請寫出linux tomcat啟動。

答:linux指令
arch 顯示機器的處理器架構(1)
uname -m 顯示機器的處理器架構(2)
shutdown -h now 關閉系統(tǒng)(1)
shutdown -r now 重啟(1)
cd /home 進入 '/ home' 目錄'
cd .. 返回上一級目錄
cd ../.. 返回上兩級目錄
mkdir dir1 創(chuàng)建一個叫做 'dir1' 的目錄'
mkdir dir1 dir2 同時創(chuàng)建兩個目錄
find / -name file1 從 '/' 開始進入根文件系統(tǒng)搜索文件和目錄
find / -user user1 搜索屬于用戶 'user1' 的文件和目錄
linuxtomcat啟動
進入tomcat下的bin目錄執(zhí)行 ./catalina.sh start直接啟動即可,然后使用tail -f /usr/local/tomcat6/logs/catalina.out查看tomcat啟動日志。

581.當使用RMI技術實現(xiàn)遠程方法調用時,能為遠程對象生成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系統(tǒng)中備份文件的可靠方法,幾乎可以工作于任何環(huán)境中,它的使用權限是所有用戶
C:類unix系統(tǒng)下的數(shù)據(jù)鏡像備份工具
D:在終端下輸入lsof即可顯示系統(tǒng)打開的文件,因為 lsof 需要訪問核心內(nèi)存和各種文件,所以必須以 root 用戶的身份運行它才能夠充分地發(fā)揮其功能
583.下面的網(wǎng)絡協(xié)議中,面向連接的的協(xié)議是: ()
A. 傳輸控制協(xié)議
B. 用戶數(shù)據(jù)報協(xié)議
C. 網(wǎng)際協(xié)議
D. 網(wǎng)際控制報文協(xié)議
答案:A
584.在/etc/fstab 文件中指定的文件系統(tǒng)加載參數(shù)中, () 參數(shù)一般用于CD-ROM 等移動設備。
A. defaults
B. sw
C. rw 和 ro
D. noauto
答案:D
585.Linux 文件權限一共10 位長度,分成四段,第三段表示的內(nèi)容是 ()
A. 文件類型
B. 文件所有者的權限
C. 文件所有者所在組的權限
D. 其他用戶的權限
答案:C
586.終止一個前臺進程可能用到的命令和操作 ()
A. kill
B. < CTRL >;+C
C. shut down
D. halt
答案:B
587.在使用mkdir 命令創(chuàng)建新的目錄時,在其父目錄不存在時先創(chuàng)建父目錄的選項是 ()
A. -m
B. -d
C. -d
D. -p
答案:D
588.下面關于i 節(jié)點描述錯誤的是 ()
A. i 節(jié)點和文件是一一對應的(每個文件都有唯一一個索引結點號與之對應,而對于一個索引結點號,卻可以有多個文件名與之對應)
B. i 節(jié)點能描述文件占用的塊數(shù)
C. i 節(jié)點描述了文件大小和指向數(shù)據(jù)塊的指針
D. 通過i 節(jié)點實現(xiàn)文件的邏輯結構和物理結構的轉換
答案: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.一臺主機要實現(xiàn)通過局域網(wǎng)與另一個局域網(wǎng)通信,需要做的工作是 ()
A. 配置域名服務器
B. 定義一條本機指向所在網(wǎng)絡的路由
C. 定義一條本機指向所在網(wǎng)絡網(wǎng)關的路由
D. 定義一條本機指向目標網(wǎng)絡網(wǎng)關的路由
答案:C
592.建立動態(tài)路由需要用到的文件有 ()
A. /etc/hosts
B. /etc/HOSTNAME
C. /etc/resolv.conf
D. /etc/gateways
答案:D
593.局域網(wǎng)的網(wǎng)絡地址192.168.1.0/24,局域網(wǎng)絡連接其它網(wǎng)絡的網(wǎng)關地址是192.168.1.1。主機192.168.1.20 訪問172.16.1.0/24 網(wǎng)絡時,其路由設置正確的是 ()
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. 配置本地回環(huán)地址
B. 配置網(wǎng)卡的IP地址
C. 激活網(wǎng)絡適配器
D. 加載網(wǎng)卡到內(nèi)核中
答案:D
595.下列關于鏈接描述,錯誤的是()
A. 硬鏈接就是讓鏈接文件的i 節(jié)點號指向被鏈接文件的i 節(jié)點
B. 硬鏈接和符號連接都是產(chǎn)生一個新的i 節(jié)點
C 鏈接分為硬鏈接和符號鏈接
D. 硬連接不能鏈接目錄文件
答案:B
596.在局域網(wǎng)絡內(nèi)的某臺主機用ping 命令測試網(wǎng)絡連接時發(fā)現(xiàn)網(wǎng)絡內(nèi)部的主機都可以連同,而不能與公網(wǎng)連通,問題可能是()
A. 主機IP設置有誤
B. 沒有設置連接局域網(wǎng)的網(wǎng)關
C. 局域網(wǎng)的網(wǎng)關或主機的網(wǎng)關設置有誤
D. 局域網(wǎng)DNS服務器設置有誤
答案:C
597.下列文件中,包含了主機名到IP 地址的映射關系的文件是:
A. /etc/HOSTNAME
B. /etc/hosts
C. /etc/resolv.conf
D. /etc/networks
答案:B
598.不需要編譯內(nèi)核的情況是()
A. 刪除系統(tǒng)不用的設備驅動程序時
B. 升級內(nèi)核時
C. 添加新硬件時
D. 將網(wǎng)卡激活
答案:D
599.在shell 中變量的賦值有四種方法,其中,采用name=12 的方法稱 ()
A. 直接賦值
B. 使用read命令
C. 使用命令行參數(shù)
D. 使用命令的輸出
答案:A
600.()命令可以從文本文件的每一行中截取指定內(nèi)容的數(shù)據(jù)。
A. cp
B. dd
C. fmt
D. cut
答案:D
601.下列不是Linux 系統(tǒng)進程類型的是()
A. 交互進程
B. 批處理進程
C. 守護進程
D. 就緒進程
答案:D
602.在日常管理中,通常CPU 會影響系統(tǒng)性能的情況是: ()
A. CPU 已滿負荷地運轉
B. CPU 的運行效率為30%
C. CPU 的運行效率為50%
D. CPU 的運行效率為80%
答案:A
603.若一臺計算機的內(nèi)存為128MB,則交換分區(qū)的大小通常是
A. 64MB
B. 128MB
C. 256MB
D. 512MB
答案:C
604.在安裝Linux 的過程中的第五步是讓用戶選擇安裝方式,如果用戶希望安裝部分組件(軟件程序),并在選擇好后讓系統(tǒng)自動安裝,應該選擇的選項是()
A. full
B. expert
C. newbie
D. menu
答案:D
605.Linux 有三個查看文件的命令,若希望在查看文件內(nèi)容過程中可以用光標上下移動來查看文件內(nèi)容,應使用()命令
A. cat
B. more
C. less
D. menu
答案:C
606.下列信息是某系統(tǒng)用ps –ef 命令列出的正在運行的進程 ()進程是運行Internet 超級服務器,它負責監(jiān)聽Internet sockets 上的連接,并調用合適的服務器來處理接收的信息。
A. root 1 4.0 0.0 344 204? S 17:09 0:00 init
B. root 2 0.0 0.1 2916 1520? S 17:09 0:00 /sbin/getty
C. root 3 0.0 0.2 1364 632? S 17:09 0:00 /usr/sbin/syslogd
D. root 4 0.0 1344 1204? S 17:09 0:10 /usr/sbin/inetd
答案:D
607.在TCP/IP 模型中,應用層包含了所有的高層協(xié)議,在下列的一些應用協(xié)議中, ()是能夠實現(xiàn)本地與遠程主機之間的文件傳輸工作
A. telnet
B. FTP
C. SNMP
D. NFS
答案:B
608.當我們與某遠程網(wǎng)絡連接不上時,就需要跟蹤路由查看,以便了解在網(wǎng)絡的什么位置出現(xiàn)了問題,滿足該目的的命令是()
A. ping
B. ifconfig
C. traceroute
D. netstat
答案:C
609.對名為fido 的文件用chmod 551 fido 進行了修改,則它的許可權是()
A. -rwxr-xr-x
B. -rwxr--r--
C. -r--r--r--
D. -r-xr-x—x
答案:C
610.用ls –al 命令列出下面的文件列表,()文件是符號連接文件
A. -rw-rw-rw- 2 hel-s users 56 Sep 09 11:05 hello
B. -rwxrwxrwx 2 hel-s users 56 Sep 09 11:05 goodbey
C. drwxr--r-- 1 hel users 1024 Sep 10 08:10 zhang
D. lrwxr--r-- 1 hel users 2024 Sep 12 08:12 cheng
答案:D
611.DNS 域名系統(tǒng)主要負責主機名和()之間的解析。
A. IP地址
B. MAC地址
C. 網(wǎng)絡地址
D. 主機別名
答案:A
612.WWW 服務器是在Internet 上使用最為廣泛,它采用的是()結構
A. 服務器/工作站
B. B/S
C. 集中式
D. 分布式
答案:B
613.Linux 系統(tǒng)通過()命令給其他用戶發(fā)消息。
A. less
B. mesg
C. write
D. echo to
答案:C
614.NFS 是()系統(tǒng)。
A. 文件
B. 磁盤
C. 網(wǎng)絡文件
D. 操作
答案:C
615.()命令可以在Linux 的安全系統(tǒng)中完成文件向磁帶備份的工作
A. cp
B. tr
C. dir
D. cpio
答案:D
616.Linux 文件系統(tǒng)的文件都按其作用分門別類地放在相關的目錄中,對于外部設備文件,一般應將其放在()目錄中
A. /bin
B. /etc
C. /dev
D. /lib
答案:C
617.在重新啟動Linux 系統(tǒng)的同時把內(nèi)存中的信息寫入硬盤,應使用()命令實現(xiàn)
A. # reboot
B. # halt
C. # reboot
D. # shutdown –r now
答案:D
618.網(wǎng)絡管理具備以下幾大功能:配置管理、()、性能管理、安全管理和計費管理等
A. 故障管理
B. 日常備份管理
C. 升級管理
D. 發(fā)送
答案:A
619.關閉linux 系統(tǒng)(不重新啟動)可使用命令()
A. Ctrl+Alt+Del
B. halt
C. shutdown -r now
D. reboot
答案:B
620.實現(xiàn)從IP 地址到以太網(wǎng)MAC 地址轉換的命令為: ()
A. ping
B. ifconfig
C. arp
D. traceroute
答案:C
621.在vi 編輯器中的命令模式下,鍵入()可在光標當前所在行下添加一新行
A. < a>;
B. < o>;
C. < I>;
D. A
答案:B
622.在vi 編輯器中的命令模式下,刪除當前光標處的字符使用()命令
A. < x>;
B. < d>;< w>;
C. < D>;
D. < d>;< d>;
答案:A
623.在vi 編輯器中的命令模式下,重復上一次對編輯的文本進行的操作,可使用()命令
A. 上箭頭
B. 下箭頭
C. < .>;
D. < *>;
答案:C
624.刪除文件命令為: ()
A. mkdir
B. rmdir
C. mv
D. traceroute
答案:D
625.退出交互模式的shell,應鍵入()
A. < Esc>;
B. ^q
C. exit
D. quit__
答案:C

算法分析及手寫代碼

626.判斷身份證:要么是15位,要么是18位,最后一位可以為字母,并寫出程序提出其中年月日。要求:

寫出合格的身份證的正則表達式,

^(\d{15}|\d{17}[\dx])$

寫程序提取身份證中的年月日

public class IdCard
{
    private String idCard;//私有變量
    public IdCard(){}//構造方法
   //構造方法
   public IdCard(String idCard){
       this.idCard=idCard;
     }

    public void setIdCard(String idCard)
    {
        this.idCard=idCard;
    }

    public String getIdCard()
    {
        return idCard;
    }

    //從身份證號碼中截取生日
    public String getBirthday()
    {
      return this.getIdCard().substring(6, 14);
    }

    public static void main(String args[])
    {
        ShenFenZheng sfz = new ShenFenZheng("420154199908157841");
         //調用getBirthday()方法獲取生日
        System.out.println("生日:" + sfz.getBirthday());
    }
}
627.對于一個字符串,請設計一個高效算法,找到第一次重復出現(xiàn)的字符保證字符串中有重復的字符,字符串的長度小于等于500.
package com.bjsxt;
import java.util.ArrayList;
import java.util.List;
public class FirstRepeat {

public static void main(String[] args) {
System.out.println(findFirstRepeat("pmedmitjtckhxwhvpwemznhmhzhpueainchqrftkmbjlradhmjekcqzansyzkvqhwnrdgzdbzewdmxkzrscikdaugbvygntrifnolehdtrqjlasofuvzeijbmzehkxknmjekcxswqldknysfsxrqaqzp",152));
}
//返回:y
    public static char findFirstRepeat(String A, int n) {
     String[] str=A.split("");
     for(int x=0;x<n;x++){
      int index=0;
      int num=0;
      //對于每一個值,都需要從前開始遍歷
      while(index<=x){
       if(str[index].equals(str[x])){
        num++;
       }
       index++;
      }
      //該值出現(xiàn)了兩次,說明重復了
      if(num>1){
       char flag='x';
       flag=str[x].toCharArray()[0];
       return flag;
      }
     }
     //返回該值說明已經(jīng)沒有重復的
     return 'p';
    }
}
628.寫一個完整函數(shù),實現(xiàn)拷貝數(shù)組
public class test {

public static void main(String[] args) {
int [] arr1 = {10,20,30,40,50};
int [] arr2 = CopyArray(arr1);

System.out.println(Arrays.toString(arr2));
}

private static int[] CopyArray(int[] arr) {
int [] arr2 = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
arr2[i] = arr[i];
}
return null;
}
}
629.寫一排序算法,輸入10個數(shù)字,以逗號分開,可根據(jù)參數(shù)選擇升序或者降序排序,須注明是何種排序算法。
package cn.bjsxt.demo;

import java.util.Scanner;

public class SortDemo {
/**
 * 給定的字符串使用,號分隔
 * @param strNumber
 * @return
 */
public static String [] split(String strNumber){
String [] strSplit=strNumber.split(",");
return strSplit;
}
/**
 * 將String類型的數(shù)組轉換成int類型的數(shù)組
 * @param strSplit
 * @return
 */
public static int [] getInt(String [] strSplit){
int arr[]=new int[strSplit.length];
for (int i = 0; i < strSplit.length; i++) {
arr[i]=Integer.parseInt(strSplit[i]);
}
return arr;
}
/**
 * 冒泡排序
 * @param arr
 */
public static void sort(int [] arr){
for (int i = 0; i < arr.length-1; i++) {
for (int j = 0; j < arr.length-1-i; j++) {
if (arr[j]>arr[j+1]) {
change(arr,j,j+1);
}
}
}
}
/**
 * 兩數(shù)交換的方法
 * @param arr 數(shù)組
 * @param x 數(shù)組中元素的下標
 * @param y 數(shù)組中元素的下標
 */
public static void change(int [] arr,int x,int y){
int temp=arr[x];
arr[x]=arr[y];
arr[y]=temp;
}
/**
 * 測試類
 * @param args
 */
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
System.out.println("請輸入一個數(shù)字串,每個數(shù)字以逗號分隔");
String str=input.next();

//調用方法
String [] s=split(str);//使用逗號分隔
int [] arr=getInt(s);//調有獲得整型數(shù)組的方法
sort(arr);//調用排序的方法
for (int i : arr) {
System.out.print(i+"\t");
}
}
}
630.判斷字符串是否是這樣的組成的,第一個字母,后面可以是字母、數(shù)字、下劃線、總長度為5-20。
package cn.bjsxt.demo;

import java.util.Scanner;

public class StringDemo {
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
System.out.println("請輸入一個字符串,第一個字符必須是字母:");
String str=input.next();
if (str.length()<5||str.length()>20) {
System.out.println("對不起,字符串的長度必須在5-20之間!");
}else{
char []ch=str.toCharArray();
if (Character.isLetter(ch[0])) {//判斷第一個字符是否是字母
for (int i = 1; i < ch.length; i++) {
if (!Character.isLetterOrDigit(ch[i])&&ch[i]!='_') {
System.out.println("字符串不符合要求");
break;
}
}
}
}
}
}
631.已排好序的數(shù)組A,一般來說可用二分查找可以很快找到,現(xiàn)有一特殊數(shù)組A,它是循環(huán)遞增的,如a[]={17, 19 ,20, 25, 1, 4, 7, 9},在這樣的數(shù)組中找一元素,看看是否存在。請寫出你的算法,必要時可寫偽代碼,并分析其空間,時間復雜度。

思路說明:循環(huán)遞增數(shù)組有這么一個性質:以數(shù)組中間元素將循環(huán)遞增數(shù)組劃分為兩部分,則一部分為一個嚴格遞增數(shù)組,而另一部分為一個更小的循環(huán)遞增數(shù)組。當中間元素大于首元素時,前半部分為嚴格遞增數(shù)組,后半部分為循環(huán)遞增數(shù)組;當中間元素小于首元素時,前半部分為循環(huán)遞增數(shù)組;后半部分為嚴格遞增數(shù)組。

記要檢索的元素為e,數(shù)組的首元素為a[low],中間元素為a[mid],末尾元素為a[high]。則當e等于a[mid] 時,直接返回mid的值即可;當e不等于a[mid] 時:

1) a[mid] > a[low],即數(shù)組前半部分為嚴格遞增數(shù)組,后半部分為循環(huán)遞增數(shù)組時,若key小于a[mid]并且不小于a[low]時,則key落在數(shù)組前半部分;否則,key落在數(shù)組后半部分。

2) a[mid] < a[high],即數(shù)組前半部分為循環(huán)遞增數(shù)組,后半部分為嚴格遞增數(shù)組時,若key大于a[mid]并且不大于a[high]時,則key落在數(shù)組后半部分;否則,key落在數(shù)組前半部分。

這種方式的時間復雜度為:O(log(n)),空間復雜度為O(1)。

public class TestBinarySearch {
public static void main(String[] args) {
// 定義數(shù)組
int[] a = { 17, 19, 20, 21, 25, 1, 4, 7 };
// 調用改進后的二分查找法求索引
int pos = search(a, 7);
System.out.println("要查找的元素的索引為:" + pos);
}

/** 改進后的二分查找法:e為要查找的元素 */
public static int search(int[] a, int e) {
int low = 0;
int high = a.length - 1;
int mid = 0;
int pos = -1; // 返回-1,表示查找失敗
// 如果low < high,說明循環(huán)查找結束,直接返回-1;否則循環(huán)查找
while (low <= high) {
// mid為中間值索引
mid = (low + high) / 2;
// 如果中間值剛好是e,則查找成功,終止查找,e的索引為mid
if (a[mid] == e) {
pos = mid;
break;
}
// 如果a[low] <= a[mid],說明原數(shù)組的前半部分是嚴格遞增的,后半部分是一個更小的循環(huán)遞增數(shù)組
if (a[low] <= a[mid]) {
// 如果要查找的元素e小于a[mid]并且不小于a[low]時,則說明e落在數(shù)組前半部分
if (a[low] <= e && e < a[mid]) {
high = mid - 1;
} else {// 否則的話,需要在數(shù)組的后半部分繼續(xù)查找
low = mid + 1;
}
} else {// 否則,后半部分是嚴格遞增的,前半部分是一個更小的循環(huán)遞增數(shù)組
// 如果要查找的元素e大于a[mid]并且不大于a[high]時,則說明e落在數(shù)組后半部分
if (a[mid] < e && e <= a[high]) {
low = mid + 1;
} else {// 否則的話,需要在數(shù)組的前半部分繼續(xù)查找
high = mid - 1;
}
}
}
return pos;
}
}
632.請編寫一個完整的程序,實現(xiàn)如下功能:從鍵盤輸入數(shù)字n,程序自動計算n!并輸出。(注1:n!=1*2*3...*n, 注2:請使用遞歸實現(xiàn))

思路說明:因為n! = (n-1)! * n,所以要求n!首先要求出(n-1)!,而(n-1)! = (n-1-1)! * (n-1),以此類推,直到n = 1為止。

import java.util.Scanner;
public class TestFactorial {
public static void main(String[] args) {
System.out.print("請輸入一個整數(shù):");
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
System.out.println(n + "的階乘是:" + factorial(n));
}
/**求階乘的方法*/
public static int factorial(int n) {
if(n == 1){
return 1;
}
return factorial(n - 1) * n;
}
}
633.請用遞歸的方法計算斐波那契數(shù)列的同項F(n),已知F0=0,F1=1,F(n)=F(n-1)+F(n-2)(n>=2,n∈N*).

思路說明:斐波那契數(shù)列的排列是:0,1,1,2,3,5,8,13,21,34,55,89,144……,特別指出的是0不是第一項而是第0項;因為F(n)=F(n-1)+F(n-2),所以要求F(n)首先要求出F(n-1)和F(n-2),而F(n-1)=F(n-1-1)+F(n-1-2),以此類推,直到,F(2)=F(1)+F(0)為止,已知F(1) = 1,F(xiàn)(0) = 0。

import java.util.Scanner;
public class TestFibo {
public static void main(String[] args) {
System.out.print("請輸要求斐波那契數(shù)列的第幾項:");
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
System.out.println("斐波那契數(shù)列的第"+ n + "是:" + fibo(n));
}
public static int fibo(int n) {
if(n == 0){
return 0;
} else if(n == 1){
return 1;
}
return fibo(n -1) + fibo(n - 2);
}
}
634.現(xiàn)在有整數(shù)數(shù)組{11,66,22,0,55,32},請任意選擇一種排序算法,用Java程序實現(xiàn)

冒泡思路說明:
(1) 最開始將數(shù)組看做一個無序數(shù)列(個數(shù)是數(shù)組的長度)與一個有序數(shù)列(0個)的組合;
(2) 每一趟比較完后, 找到了無序數(shù)列的最大值, 將其放到有序數(shù)列中(有序數(shù)列個數(shù)+1);
(3) N個數(shù), 比較N-1趟;
(4) 每一趟挨個進行比較:從數(shù)組的第一個元素開始, 到無序數(shù)列的最后一個為止;
(5) 如果前邊一個大于后邊一個, 那么交換位置;
(6) 每趟比較的次數(shù)與趟數(shù)有關;
(7) 根據(jù)每趟比較是否發(fā)生了交換判斷數(shù)據(jù)是否已經(jīng)有序,從而進行優(yōu)化。

public class TestSort {
public static void main(String[] args) {
int[] arr = {11, 66, 22, 0, 55, 32};
// 調用排序方法
sort(arr);
// 輸出排除后的數(shù)組
for (int num : arr) {
System.out.print(num + "\t");
}
}

public static void sort(int[] arr) {
// 定義標記
boolean flag = false;
int temp;
// 排序
// 外層循環(huán)控制的是比較的趟數(shù)
for (int i = 0; i < arr.length - 1; i++) {
// 每一趟比較之前初始化, 否則會保留上一堂比較的結果
flag = false;
// 內(nèi)層循環(huán)控制的是每趟比較的次數(shù)
for (int j = 0; j < arr.length - 1 - i; j++) {
// 挨個進行比較: 從數(shù)組的第一個元素開始, 到無序數(shù)列的最后一個
if (arr[j] > arr[j + 1]) {
// 交換
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
//如果發(fā)生交換,改變flag的值
flag = true;
}
}
if (!flag) {
break;
}
}
}
}
635.請根據(jù)注釋,編碼實現(xiàn)下面類的方法
// 這個類用于存取一組權限,每個權限用非負整數(shù)表示的.這組枳限存儲在
// righiString屬性中。如果權限N權限存在,rightString第N個字符為“1”,否則, 為空格。
class RightStore {
public String righString = "";

// 如果傳入的權限r(nóng)ight存在,該方法返回true.否期,為false.,
// right為傳入的權限的整數(shù)值.
public boolean getRight(int right) {

return true;
}

// 該方法存儲或消除傳入的權限.如果value為true,存儲傳入的權限,
// 否則淸除該權限.
// right為傳入的權限的整數(shù)值.
public void setRight(int right, boolean value) {
}
}

思路說明:我們首先要讀懂這道題的意思:righString這個字符串是用來存儲一系列權限的,并且權限的取值只有兩種:有和沒有;在righString中使用字符‘1’表示有權限,字符空格‘ ’表示沒有權限。舉個例子:如果righString的長度為3,第一位表示對訂單系統(tǒng)是否有權限,第二位表示對人員管理系統(tǒng)是否有權限,第三位表示對庫存系統(tǒng)是否有權限。而方法中的int right參數(shù)則表示的是字符串的第幾位。

上邊這些搞明白之后,方法的編寫就簡單多了。

public class RightStore {
public String righString = "";

public boolean getRight(int right) {
//先求得第right個字符
char ch = righString.charAt(right - 1);
//如果ch為'1',返回true,否則返回false
return ch == '1';
}

public void setRight(int right, boolean value) {
//如果value為true,存儲傳入的權限,否則消除權限(改為空格)
righString.replace(righString.charAt(right - 1), value ? '1' : ' ');
}
}
636.二分法查詢(遞歸實現(xiàn))

思路說明:假設在一個已經(jīng)排好序的有序序列(N個元素,升序排列),首先讓序列中的中間的元素與需要查找的關鍵字進行比較,如果相等,則查找成功,否則利用中間位置將序列分成兩個子序列,如果待查找的關鍵字小于中間的元素,則在前一個子序列中同樣的方法進一步查找,如果待查找的關鍵字大于中間的元素,則在后一個子序列中同樣的方法進一步查找,重復以上過程一直到查找結束!

import java.util.Scanner;
public class TestBinarySearchRecursion {
public static void main(String[] args) {
int[] a = { 1, 3, 5, 7, 9, 11, 13 };
System.out.print("請輸入要查找的元素:");
int e = new Scanner(System.in).nextInt();
int index = binarySearch(a, 0, a.length - 1, e);
System.out.println(index != -1 ? "元素索引為" + index : "沒有該元素");
}

private static int binarySearch(int[] a, int low, int high, int e) {
int mid = 0;
if (low <= high) {
mid = (low + high) / 2;
if (a[mid] == e) {
return mid;
} else if (a[mid] > e) {
return binarySearch(a, low, mid - 1, e);
} else {
return binarySearch(a, mid + 1, high, e);
}
}
return -1;
}
}
637.編寫一段Java程序,把一句英語中的每個單詞中的字母次序倒轉,單詞次序保持不變,例入輸入為“There is a dog.”,輸出結果應該是“erehT si a god.”要求不使用Java的庫函數(shù),例如String類的split,reverse方法。

函數(shù)形如:

public static String reverseWords(String input) {
String str = "";

return str;
}

思路說明:將字符串轉化成字符數(shù)組,然后根據(jù)數(shù)組中空格的位置判斷每個單詞所占的索引范圍,根據(jù)得到的索引將數(shù)組中的每個單詞逆序后拼接到新的字符串中。

public class TestStringReverse{
public static void main(String[] args) {
String input = "There is a dog";
System.out.println("逆轉后的字符串為:" + reverseWords(input));
}
public static String reverseWords(String input) {
String str = "";
//將字符串轉化成字符數(shù)組
char[] arr = input.toCharArray();
//index用來記錄每個單詞的起始索引
int index = 0;
//遍歷字符數(shù)組,將空格前邊的單詞挨個拼接到str中
for (int i = 0; i < arr.length; i++) {
if(arr[i] == ' '){
//根據(jù)空格的位置將空格前邊一個單詞密續(xù)追加到str中
for(int j = i - 1; j >= index; j--){
str += arr[j];
}
//單詞拼接完成后,拼接一個空格
str += ' ';
//讓index指向下一個單詞的起始位置
index = i + 1;
}
}
//將最后一個單詞拼接上
for(int i = arr.length - 1; i >= index; i--){
str += arr[i];
}
return str;
}
}
638.手寫9x9乘法表,冒泡排序

9x9乘法表:

class Demo {
    public static void main(String[] args) {
        for(int x = 0;x <= 9; x++) {
            for(int y = 1;y <= x; y++) {
                System.out.print(y+"*"+x+"="+x*y+"\t");
            }
            System.out.println();
        }
    }
}

冒泡排序:

public class BubbleSort{
     public static void main(String[] args){
         int score[] = {67, 69, 75, 87, 89, 90, 99, 100};
         for (int i = 0; i < score.length -1; i++){//最多做n-1趟排序
             for(int j = 0 ;j < score.length - i - 1; j++){//對當前無序區(qū)間score[0......length-i-1]進行排序(j的范圍很關鍵,這個范圍是在逐步縮小的)
                 if(score[j] < score[j + 1]){ //把小的值交換到后面
                     int temp = score[j];
                     score[j] = score[j + 1];
                     score[j + 1] = temp;
                 }
             }
             System.out.print("第" + (i + 1) + "次排序結果:");
             for(int a = 0; a < score.length; a++){
                 System.out.print(score[a] + "\t");
             }
             System.out.println("");
         }
         System.out.print("最終排序結果:");
         for(int a = 0; a < score.length; a++){
             System.out.print(score[a] + "\t");
         }
}
}
639.題目: 給定一個整數(shù)數(shù)組,找到是否該數(shù)組包含任何重復數(shù)字。你的函數(shù)應該返回true只要有任何數(shù)字 在該數(shù)組中重復出現(xiàn),否則返回false。
public class Solution {
    public boolean containsDuplicate(int[] nums) {
        Set<Integer> numSet = new HashSet<Integer>();
        for(int i=0;i<nums.length;i++){·
            if(numSet.contains(nums[i]))
                return true;
            else
                numSet.add(nums[i]);
        }
        return false;
    }
}
640.給定一個數(shù)組nums, 寫一個函數(shù)來移動所有0元素到數(shù)組末尾,同時維持數(shù)組中非0元素的相對順序不變。要求不能申請額外的內(nèi)存空間,并且最小化操作次數(shù)。
public void moveZeroes(int[] nums) {
        int size = nums.length;
        int startIndex = 0;
// 0元素開始的位置
        int endIndex = 0;
// 0元素結束的位置
        int currentNum;
        int i= 0;
        // 第一步:找到第一個0元素開始的位置
        // 并將第一個0元素的游標賦值給startIndex&endIndex
        while(i < size){
            currentNum = nums[i];
            if (currentNum == 0) {
                startIndex = i;
                endIndex = i;
                break;
            }
            ++i;
        }
        // 如果當前數(shù)組中沒有找到0元素,則推出
        if (nums[endIndex] != 0)
            return;

        // 將當前i的值加1;直接從剛才0元素位置的后一位置開始循環(huán)
        ++i;
        while (i < size) {
            currentNum = nums[i];
            if (currentNum == 0){//如果當前元素等于0,則將i值賦值給endIndex
                    endIndex = i;
            } else {
                // 如果不為0
                //則將當前元素賦值給nums[startIndex]
                // 并將當前位置的元素賦值為0
                // startIndex和endIndex都加1;
                nums[startIndex] = currentNum;
                nums[i] = 0;
                ++startIndex;
                ++endIndex;
            }
            ++i;
        }
    }
641.給定一顆二叉樹,返回節(jié)點值得先序遍歷,請使用迭代(非遞歸)方式實現(xiàn)。
public class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<Integer>();
        if(root == null)
            return result;
        Stack<TreeNode> stack = new Stack<TreeNode>();
        stack.push(root);
        while(!stack.isEmpty()) {
            TreeNode node = stack.pop();
            result.add(node.val);
            if(node.right != null)
                stack.push(node.right);
            if(node.left != null)
                stack.push(node.left);
        }
        return result;
    }
}
642.驗證一棵樹是否為有效的二叉搜索樹BST
public class Solution {
    private static int lastVisit = Integer.MIN_VALUE;
public boolean isValidBST(TreeNode root) {
    if(root == null) return true;
        boolean judgeLeft = isValidBST(root.left); // 先判斷左子樹

        if(root.data >= lastVisit && judgeLeft) { // 當前節(jié)點比上次訪問的數(shù)值要大
            lastVisit = root.data;
        } else {
            return false;
        }
        boolean judgeRight = isValidBST(root.right); // 后判斷右子樹
        return judgeRight;
}
}
643.從一個鏈表中刪除節(jié)點

題目: 寫一個函數(shù)用于在一個單向鏈表中刪除一個節(jié)點(?非尾節(jié)點),前提是僅僅能夠訪問要刪除的那個節(jié)點。

比如給定鏈表1 -> 3 -> 5 -> 7 -> 9 -> 16,給定你值為3的那個節(jié)點, 調?用你的函數(shù)后,鏈表變?yōu)?/p>

1 -> 5 -> 7 -> 9 -> 16。

/**
Definition for singly-linked list.
public class ListNode {
int val;
ListNode next;
ListNode(int x) { val = x; }
* }
*/
public class Solution {
public void deleteNode(ListNode node) {
if(node==null||node.next==null) {
System.out.println("節(jié)點不存在或者是尾節(jié)點");

}else{
node.val=node.next.val;
node.next=node.next.next;
}
}
}
644.二叉搜索樹BST中第Kth小的元素 題目:給定?個BST,寫一個函數(shù)kthSmallest來找到第kth小的元素
/**
Definition for a binary tree node.
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
* }
*/
public class Solution2  {
public int kthSmallest(TreeNode root, int k) {
    Stack<TreeNode> store = new Stack<TreeNode>();
    if (root == null) {
        return -1;
    }
    store.push(root);
    while (root.left != null) {
        store.push(root.left);
        root = root.left;
    }
    while (!store.empty()) {
        TreeNode cur = store.pop();
        k--;
        if (k == 0) {
            return cur.val;
        }
        if (cur.right != null) {
            root = cur.right;// let cur.right be the current node
            store.push(root);
            while (root.left != null) {
                store.push(root.left);
                root = root.left;
            }
        }
    }
    return -1;
}
}
645.題目:給定含有n個整數(shù)的數(shù)組S,S中是否存在三個元素a,b,c使得a + b + c = 0? 找到所有這樣的三元 組,并且結果集中不包含重復的三元組。

比如,
S = [-1, 0, 1, 2, -1, -4],,
結果集為: [
[-1, 0, 1],
[-1, -1, 2]
]

/**
 * 給定一個n個元素的數(shù)組,是否存在a,b,c三個元素,使用得a+b+c=0,找出所有符合這個條件的三元組
 * 注意: - 三元組中的元素必須是非遞減的  - 結果不能包含重復元素
 */
public class Solution {

    public static void main(String[] args) {
        int[] S = {-1, 0, 1, 2, -1, -4,-3,-4,4,3};
        new Solution().get3Sum(S);
    }

    public Set<String> get3Sum(int[] S){

        if(S.length<3 || S==null){
            return null;
        }

        //接收拼接的字符串
        StringBuffer sb = new StringBuffer();
        for(int i=0; i<S.length; i++){
            for(int j=0; j<S.length; j++){
                for(int z=0; z<S.length; z++){
                    //篩選出不是遞減的一組元素
                    if(S[i]<=S[j] && S[j]<=S[z]){
                        int sum = S[i] + S[j] + S[z];
                        if(sum==0){
                            String str = "("+S[i]+","+S[j]+","+S[z]+")";
                            sb.append(str+";");
                        }
                    }
                }
            }
        }

        String s = sb.toString();
        s = s.substring(0, sb.length()-1);
        String[] arr = s.split(";");

        Set<String> set = new HashSet<String>();
        //將所篩選出來的元素放入Set集合中,去重
        for (int k = 0; k < arr.length; k++) {
            set.add(arr[k]);
        }
        System.out.println(set);
        return set;
    }

    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> result = new LinkedList<>();

        if (nums != null && nums.length > 2) {
            // 先對數(shù)組進行排序
            Arrays.sort(nums);
            // i表示假設取第i個數(shù)作為結果
            for (int i = 0; i < nums.length - 2; ) {
                // 第二個數(shù)可能的起始位置
                int j = i + 1;
                // 第三個數(shù)可能是結束位置
                int k = nums.length - 1;
                while (j < k) {
                    // 如果找到滿足條件的解
                    if (nums[j] + nums[k] == -nums[i]) {
                        // 將結果添加到結果含集中
                        List<Integer> list = new ArrayList<>(3);
                        list.add(nums[i]);
                        list.add(nums[j]);
                        list.add(nums[k]);
                        result.add(list);
                        // 移動到下一個位置,找下一組解
                        k--;
                        j++;

                        // 從左向右找第一個與之前處理的數(shù)不同的數(shù)的下標
                        while (j < k && nums[j] == nums[j - 1]) {
                            j++;
                        }
                        // 從右向左找第一個與之前處理的數(shù)不同的數(shù)的下標
                        while (j < k && nums[k] == nums[k + 1]) {
                            k--;
                        }
                    }
                    // 和大于0
                    else if (nums[j] + nums[k] > -nums[i]) {
                        k--;
                        // 從右向左找第一個與之前處理的數(shù)不同的數(shù)的下標
                        while (j < k && nums[k] == nums[k + 1]) {
                            k--;
                        }
                    }
                    // 和小于0
                    else {
                        j++;
                        // 從左向右找第一個與之前處理的數(shù)不同的數(shù)的下標
                        while (j < k && nums[j] == nums[j - 1]) {
                            j++;
                        }
                    }
                }
                // 指向下一個要處理的數(shù)
                i++;
                // 從左向右找第一個與之前處理的數(shù)不同的數(shù)的下標
                while (i < nums.length - 2 && nums[i] == nums[i - 1]) {
                    i++;
                }
            }
        }
 return result;
    }
}
646.子集問題

題目: 給定一個不包含相同元素的整數(shù)集合,nums,返回所有可能的子集集合。解答中集合不能包含重 復的子集。
比如,
nums = [1, 2, 3], ?一種解答為:
[
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2], []
]

/**
 * 不重復集合求子集
解答采用的是深度優(yōu)先遍歷,先取原數(shù)組一個元素,再構造包括這個元素的兩個,三個……n個元素的集合。dfs中的start就指向這個元素的,它在不斷地后移(i+1)。
 * @param S: A set of numbers.
 * @return: A list of lists. All valid subsets.
 */
public class Solution1 {
    public static void main(String[] args) {
        int[] first = new int[]{1, 2, 3};
        ArrayList<ArrayList<Integer>> res = subsets(first);
        for(int i = 0; i < res.size(); i ++){
            System.out.println(res.get(i));
        }
    }
    public static ArrayList<ArrayList<Integer>> subsets(int[] nums) {
        ArrayList<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer>>();
        ArrayList<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, ArrayList<Integer>item, ArrayList<ArrayList<Integer>>res){
        for(int i = start; i < nums.length; i ++){
            item.add(nums[i]);
            //item是以整數(shù)為元素的動態(tài)數(shù)組,而res是以數(shù)組為元素的數(shù)組,在這一步,當item增加完元素后,item所有元素構成一個完整的子串,再由res納入
            res.add(new ArrayList<Integer>(item));
            dfs(nums, i + 1, item, res);
            item.remove(item.size() - 1);
        }
    }
}
647.迭代方法實現(xiàn)二叉樹的先序遍歷:題目: 給定一顆?叉樹,返回節(jié)點值得先序遍歷,請使用迭代(非遞歸)方式實現(xiàn)。

比如, 給定二叉樹{1,#,2,3}, 返回 [1,2,3]

/**
Definition for a binary tree node.
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
* }
*/
public class Solution {

    List<Integer> result = new ArrayList<Integer>();

    /**
     * 迭代實現(xiàn),維護一個棧,因為入棧順序按照根右左進行入棧,因此首先將根出棧,然后出棧左子節(jié)點,
     * 最后出棧右子節(jié)點。
     * @param root
     * @return
     */
    public List<Integer> preorderTraversal(TreeNode root) {
        if(root == null)
            return result;
        Stack<TreeNode> stack = new Stack<TreeNode>();
        stack.push(root);
        while(!stack.isEmpty()) {
            TreeNode node = stack.pop();
            result.add(node.val);
            if(node.right != null)
                stack.push(node.right);
            if(node.left != null)
                stack.push(node.left);
        }
        return result;
    }
}
648.驗證二叉搜索樹BST:題目: 驗證一棵樹是否為有效的二叉搜索樹BST比如,二叉樹[2, 1, 3],返回true二叉樹[1, 2, 3], 返回false
class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
TreeNode(int x) { val = x; }
}
public class BSTChecker {
    private static int lastVisit = Integer.MIN_VALUE;

    public static boolean isBST(TreeNode root) {
        if(root == null) return true;

        boolean judgeLeft = isBST(root.left); // 先判斷左子樹

        if(root.val >= lastVisit && judgeLeft) { // 當前節(jié)點比上次訪問的數(shù)值要大
            lastVisit = root.val;
        } else {
            return false;
        }

        boolean judgeRight = isBST(root.right); // 后判斷右子樹

        return judgeRight;
    }
}
649.編輯距離題目: 給定兩個單詞word1和word2,找到最小的操作步驟使得word1轉換成word2,每次操作算作一 步。你可以對單詞進行以下三種操作:1)插入一個字符2)刪除一個字符3)替換一個字符

參考地址:http://www.cnblogs.com/masterlibin/p/5785092.html

650.買賣股票問題:題目: 你有一個數(shù)組,第i個元素表示第i天某個股票的價格,設計一個算法找到最大的利潤,并且你只能最多完成兩次交易。

參考地址:沒有完全理解的

http://www.mamicode.com/info-detail-1087177.html

http://www.mamicode.com/info-detail-1087177.html

/**
 * 解題思路:
 * 比如給定一組數(shù)組,[1,2,3,6,9,3,10]
 * 最多可以2次去獲取最大的利益,可以用2分的思想,分成2部分,
 * 從0元素開始遍歷分別求出左右2邊的最大利益,求出的左右2邊最大的利益即為解
 */
class Solution {

    public static int maxProfit(int[] prices) {
        // write your code here
        if(null==prices||0==prices.length) return 0;
         int sumProfit = 0;
         for(int i=1;i<prices.length;i++){
              int tmpsum = maxProfit(prices, 0, i)
                + maxProfit(prices, i+1, prices.length-1);
              sumProfit = Math.max(sumProfit, tmpsum);
         }
         return sumProfit;
    }
    public static int maxProfit(int[] prices,int s,int e){
         if(e<=s) return 0;
         int min = prices[s];
         int maxProfit = 0;
         for(int i=s+1;i<=e;i++){
              maxProfit = Math.max(maxProfit, prices[i]-min);
              min = Math.min(min, prices[i]);
         }
         return maxProfit;
    }
    public static void main(String[] args) {
     int arr [] =  {4,4,6,1,1,4,2,5};
     System.out.println(maxProfit(arr));
}
}
651.[編程]任給n個整數(shù)和一個整數(shù)x。請計算n個整數(shù)中有多少對整數(shù)之和等于x。
public class Test8 {
public static void main(String[] args) {
//輸入n個整數(shù)和一個整數(shù)
Scanner input = new Scanner(System.in);
System.out.println("請輸入n個整數(shù),數(shù)量任意,以逗號分隔");
String str = input.next();
System.out.println("請輸入一個整數(shù):");
int x = input.nextInt();
//將n個整數(shù)的字符串轉換為數(shù)組
String arr1[] = str.split(",");
int [] arr2 = new int[arr1.length];
for(int i=0;i<arr1.length;i++){
arr2[i] = Integer.parseInt(arr1[i]);
}
System.out.println(Arrays.toString(arr2));
//判斷并輸出n個整數(shù)中有幾對的和等于x
int count = 0;
for(int i=0;i<arr2.length-1;i++){
for(int j = i+1;j<arr2.length;j++){
if(arr2[i]+arr2[j]==x){
count++;
}
}
}
System.out.println(count);
}
}
652.[編程]請說明快速排序算法的設計思想和時間復雜度,并用高級語言寫出對整數(shù)數(shù)組進行一趟快排的函數(shù)實現(xiàn)。

快速排序由C. A. R. Hoare在1962年提出。它的基本思想是:通過一趟排序將要排序的數(shù)據(jù)分割成獨立的兩部分,其中一部分的所有數(shù)據(jù)都比另外一部分的所有數(shù)據(jù)都要小,然后再按此方法對這兩部分數(shù)據(jù)分別進行快速排序,整個排序過程可以遞歸進行,以此達到整個數(shù)據(jù)變成有序序列。

設要排序的數(shù)組是A[0]……A[N-1],首先任意選取一個數(shù)據(jù)(通常選用數(shù)組的第一個數(shù))作為關鍵數(shù)據(jù),然后將所有比它小的數(shù)都放到它前面,所有比它大的數(shù)都放到它后面,這個過程稱為一趟快速排序。值得注意的是,快速排序不是一種穩(wěn)定的排序算法,也就是說,多個相同的值的相對位置也許會在算法結束時產(chǎn)生變動。

一趟快速排序的算法是:
1、設置兩個變量i、j,排序開始的時候:i=0,j=N-1;
2、以第一個數(shù)組元素作為關鍵數(shù)據(jù),賦值給key,即key=A[0];
3、從j開始向前搜索,即由后開始向前搜索(j--),找到第一個小于key的值A[j],將A[j]和A[i]互換;
4、從i開始向后搜索,即由前開始向后搜索(i++),找到第一個大于key的A[i],將A[i]和A[j]互換;
5、重復第3、4步,直到i=j; (3,4步中,沒找到符合條件的值,即3中A[j]不小于key,4中A[i]不大于key的時候改變j、i的值,使得j=j-1,i=i+1,直至找到為止。找到符合條件的值,進行交換的時候i, j指針位置不變。另外,i==j這一過程一定正好是i+或j-完成的時候,此時令循環(huán)結束)。

public class Quick {
public static void main(String[] args) {
int arr [] = {90,60,70,50,40,80,20,100,10};
sort(arr,0,arr.length-1);
System.out.println(Arrays.toString(arr));
}
public static void sort(int arr[], int low, int high) {
//設置兩個變量l、h,排序開始的時候:l=0,h=N-1
int l = low;
int h = high;
//以第一個數(shù)組元素作為關鍵數(shù)據(jù),賦值給key,即key=A[0]
int key = arr[low];
//重復操作,直到i=j
while (l < h) {
//從h開始向前搜索,即由后開始向前搜索(h--),找到第一個小于key的值arr[h],將arr[h]和arr[l]互換
while (l < h && arr[h] >= key)
h--;
if (l < h) {
int temp = arr[h];
arr[h] = arr[l];
arr[l] = temp;
l++;
}
//從l開始向后搜索,即由前開始向后搜索(l++),找到第一個大于key的arr[l],將arr[l]和arr[h]互換;
while (l < h && arr[l] <= key)
l++;

if (l < h) {
int temp = arr[h];
arr[h] = arr[l];
arr[l] = temp;
h--;
}
}
//對前一部分進行快速排序
if (l > low)
sort(arr, low, l - 1);
//對前一部分進行快速排序
if (h < high)
sort(arr, l + 1, high);
}
}
653.對于一段形如:1,-1~3,1~15×3的輸入

輸入會依照以下規(guī)則:
1、所有輸入為整數(shù)、
2、“,”為分隔符
3、“~”表示一個區(qū)間,比如“-1~3”表示-1到3總共5個整數(shù),同時“~”前的數(shù)小于“~”后的數(shù):
4、“x”表示步長,“x3”指每3個整數(shù)一個,比如“1~15×3”表示1,4,7,10,13;
根據(jù)以上得到的結果進行打印,打印的規(guī)則為:
1、所有得到的整數(shù)按從小到大排列,以“,”分隔,不計重復;
2、每行最多顯示3個整數(shù);
3、如果兩個整數(shù)是連續(xù)的,可以放在同一行,否則自動換行。
例如對于輸入“1,-1~3,1~15×3”的輸出結果為:
-1,0,1,
2,3,4,
7,
10,
13

public class Test {
public static void main(String[] args) {
Map<Integer, Integer> map = new TreeMap<Integer, Integer>();
String str = "5~20x3,1,-1~3,1~15x3";
String[] s = str.split(",");
for (int i = 0; i < s.length; i++) {
if (s[i].contains("~")) {
String ss[] = s[i].split("~");
int first = Integer.parseInt(ss[0]);
if (s[i].contains("x")) {
String sss[] = ss[1].split("x");
int end = Integer.parseInt(sss[0]);
int l = Integer.parseInt(sss[1]);
for (int j = first; j < end;) {
map.put(j, j);
j += l;
}
} else {
int end = Integer.parseInt(ss[ss.length - 1]);
for (int j = first; j <= end; j++) {
map.put(j, j);
}
}
} else {
int j = Integer.parseInt(s[i]);
map.put(j, j);
}
}
List<Integer> list = new ArrayList<Integer>();
Set<Integer> set = map.keySet();
Iterator<Integer> ite = set.iterator();
while (ite.hasNext()) {
int key = ite.next();
int value = map.get(key);
list.add(value);
System.out.println("v :" + value);
}
System.out.println("=================");
for (int i = 0; i < list.size();) {
int value = list.get(i);
List<Integer> co = new ArrayList<Integer>();
co.add(value + 1);
co.add(value + 2);
if (list.containsAll(co)) {
System.out.println(value + "," + (value + 1) + ","
+ (value + 2));
i += 3;
} else {
System.out.println(value);
i++;
}
}
}
}
654.有兩個字符串:目標串S=“s1s2.......sn”,模式串T="t1t2.......tm"。若存在T的每個字符一次和S中的一個連續(xù)字符序列相等,則匹配成功,返回T中第一個字符在S中的位置。否則匹配不成功,返回0。寫出你的算法,要求線性時間復雜度

答:
字符串匹配操作定義:
目標串S="S0S1S2...Sn-1" , 模式串T=“T0T1T2...Tm-1”
對合法位置 0<= i <= n-m (i稱為位移)依次將目標串的字串 S[i ... i+m-1] 和模式串T[0 ... m-1] 進行比較,若:
1、S[i ... i+m-1] = T[0 ... m-1] , 則從位置i開始匹配成功,稱模式串 T 在目標串 S 中出現(xiàn)。
2、S[i ... i+m-1] != T[0 ... m-1] ,則從位置i開始匹配失敗。
字符串匹配算法 —— Brute-Force 算法
字符串匹配過程中,對于位移i (i在目標串中的某個位置),當?shù)谝淮?Sk != Tj 時,i 向后移動1位 , 及 i = i+1,此時k退回到i+1位置 ;模式串要退回到第一個字符。該算法時間復雜度O(M*N),但是實際情況中時間復雜度接近于O(M + N),以下為Brute-Force算法的Java實現(xiàn)版本:

public static int bruteForce(String target, String pattern, int pos) {
        if (target == null || pattern == null) {
            return -1;
        }
        int k = pos - 1, j = 0, tLen = target.length(), pLen = pattern.length();
        while (k < tLen && j < pLen) {
            if (target.charAt(k) == pattern.charAt(j)) {
                j++;
                k++;
            } else {
                k = k - j + 1;
                j = 0;
            }
        }
        if (j == pLen) {
            return k - j + 1;
        }
        return -1;
    }
655.如何生成一個0-100的隨機整數(shù)?
public class Test {
public static void main(String[] args) {
int num=(int)(Math.random()*101);
System.out.println(num);
}
}
656.請編寫一段Java程序將兩個有序數(shù)組合并成一個有序數(shù)組
import java.util.Arrays;

publicclass Demo1 {

publicstaticvoid main(String[] args) {

int[] a = { 1, 2, 3, 4, 5, 7, 8, 9, 10 };
int[] b = { 3, 5, 7, 9, 10 };
int[] target = newint[a.length + b.length];

for (inti = 0; i<a.length; i++)
target[i] = a[i];
for (intj = 0; j<b.length; j++)
target[a.length + j] = b[j];

Arrays.sort(target);
for (inti = 0; i<target.length; i++)
System.out.println(target[i]);

}
}
657.在最佳情況下,以下哪個時間復雜度最高(D)
A. 直接插入排序
B. 直接選擇排序
C. 冒泡排序
D. 歸并排序
分析:答案: D
排序方法 最壞時間復雜度 最好時間復雜度 平均時間復雜度
直接插入 O(n2) O(n) O(n2)
簡單選擇 O(n2) O(n2) O(n2)
冒泡排序 O(n2) O(n) O(n2)
快速排序 O(n2) O(nlog2n) O(nlog2n)
堆排序 O(nlog2n) O(nlog2n) O(nlog2n)
歸并排序 O(nlog2n) O(nlog2n) O(nlog2n)
658.一個數(shù)組,元素為從0到m的整數(shù),判斷其中是否有重復元素,使用java語言編寫一個方法
publicstaticboolean demo(int[] arr){
for (inti = 0; i<arr.length; i++) {
for (intj = i + 1; j<arr.length; j++) {
if (arr[i] == arr[j]) {
returntrue;
}
}
}
returnfalse;
}
659.某二叉樹的先序遍歷是12453,中序遍歷是42513,那么其后序遍歷是(A)
A. 45231
B. 42351
C. 12345
D. 54321
660.設一顆二叉樹中有3個葉子節(jié)點,有八個度為1的節(jié)點,則該二叉樹中總的節(jié)點數(shù)為()
A. 12
B. 13
C. 14
D. 15
分析:選b 子葉節(jié)點是度為零的節(jié)點,而二叉樹的性質可知,度是0的節(jié)點比度是2的節(jié)點數(shù)多1個,所以度是2的節(jié)點為2個,所以共有3+8+2=13
661.給出下面的二叉樹先序、中序、后序遍歷的序列?

答:先序序列:ABDEGHCF;中序序列:DBGEHACF;后序序列:DGHEBFCA。

補充:二叉樹也稱為二分樹,它是樹形結構的一種,其特點是每個結點至多有二棵子樹,并且二叉樹的子樹有左右之分,其次序不能任意顛倒。二叉樹的遍歷序列按照訪問根節(jié)點的順序分為先序(先訪問根節(jié)點,接下來先序訪問左子樹,再先序訪問右子樹)、中序(先中序訪問左子樹,然后訪問根節(jié)點,最后中序訪問右子樹)和后序(先后序訪問左子樹,再后序訪問右子樹,最后訪問根節(jié)點)。如果知道一棵二叉樹的先序和中序序列或者中序和后序序列,那么也可以還原出該二叉樹。

例如,已知二叉樹的先序序列為:xefdzmhqsk,中序序列為:fezdmxqhks,那么還原出該二叉樹應該如下圖所示:

662.你知道的排序算法都哪些?用Java寫一個排序系統(tǒng)

答:穩(wěn)定的排序算法有:插入排序、選擇排序、冒泡排序、雞尾酒排序、歸并排序、二叉樹排序、基數(shù)排序等;不穩(wěn)定排序算法包括:希爾排序、堆排序、快速排序等。

下面是關于排序算法的一個列表:

下面按照策略模式給出一個排序系統(tǒng),實現(xiàn)了冒泡、歸并和快速排序。

package com.bjsxt;

import java.util.Comparator;

/**
 * 排序器接口(策略模式: 將算法封裝到具有共同接口的獨立的類中使得它們可以相互替換)
 * @author SXT李端陽
 *
 */
public interface Sorter {

   /**
    * 排序
    * @param list 待排序的數(shù)組
    */
   public <T extends Comparable<T>> void sort(T[] list);

   /**
    * 排序
    * @param list 待排序的數(shù)組
    * @param comp 比較兩個對象的比較器
    */
   public <T> void sort(T[] list, Comparator<T> comp);
}

BubbleSorter.java

package com.bjsxt;

import java.util.Comparator;

/**
 * 冒泡排序
 * @author SXT李端陽
 *
 */
public class BubbleSorter implements Sorter {

   @Override
   public <T extends Comparable<T>> void sort(T[] list) {
      boolean swapped = true;
      for(int i = 1; i < list.length && swapped;i++) {
        swapped= false;
        for(int j = 0; j < list.length - i; j++) {
           if(list[j].compareTo(list[j+ 1]) > 0 ) {
              T temp = list[j];
              list[j]= list[j + 1];
              list[j+ 1] = temp;
              swapped= true;
           }
        }
      }
   }

   public <T> void sort(T[] list,Comparator<T> comp) {
      boolean swapped = true;
      for(int i = 1; i < list.length && swapped; i++) {
        swapped = false;
        for(int j = 0; j < list.length - i; j++) {
           if(comp.compare(list[j], list[j + 1]) > 0 ) {
              T temp = list[j];
              list[j]= list[j + 1];
              list[j+ 1] = temp;
              swapped= true;
           }
        }
      }
   }
}
package com.bjsxt;

import java.util.Comparator;
/**
 * 歸并排序
 * 歸并排序是建立在歸并操作上的一種有效的排序算法。
 * 該算法是采用分治法(divide-and-conquer)的一個非常典型的應用,
 * 先將待排序的序列劃分成一個一個的元素,再進行兩兩歸并,
 * 在歸并的過程中保持歸并之后的序列仍然有序。
 * @author SXT李端陽
 *
 */
public class MergeSorter implements Sorter {

   @Override
   public <T extends Comparable<T>> void sort(T[] list) {
      T[] temp = (T[]) new Comparable[list.length];
      mSort(list,temp, 0, list.length- 1);
   }

   private <T extends Comparable<T>> void mSort(T[] list, T[] temp, int low, int high) {
      if(low == high) {
        return ;
      }
      else {
        int mid = low + ((high -low) >> 1);
        mSort(list,temp, low, mid);
        mSort(list,temp, mid + 1, high);
        merge(list,temp, low, mid + 1, high);
      }
   }

   private <T extends Comparable<T>> void merge(T[] list, T[] temp, int left, int right, int last) {
        int j = 0;
        int lowIndex = left;
        int mid = right - 1;
        int n = last - lowIndex + 1;
        while (left <= mid && right <= last){
            if (list[left].compareTo(list[right]) < 0){
                temp[j++] = list[left++];
            } else {
                temp[j++] = list[right++];
            }
        }
        while (left <= mid) {
            temp[j++] = list[left++];
        }
        while (right <= last) {
            temp[j++] = list[right++];
        }
        for (j = 0; j < n; j++) {
            list[lowIndex + j] = temp[j];
        }
   }

   @Override
   public <T> void sort(T[] list, Comparator<T> comp) {
      T[]temp = (T[])new Comparable[list.length];
      mSort(list,temp, 0, list.length- 1, comp);
   }

   private <T> void mSort(T[] list, T[] temp, int low, int high, Comparator<T> comp) {
      if(low == high) {
        return ;
      }
      else {
        int mid = low + ((high -low) >> 1);
        mSort(list,temp, low, mid, comp);
        mSort(list,temp, mid + 1, high, comp);
        merge(list,temp, low, mid + 1, high, comp);
      }
   }

   private <T> void merge(T[] list, T[]temp, int left, int right, int last, Comparator<T> comp) {
        int j = 0;
        int lowIndex = left;
        int mid = right - 1;
        int n = last - lowIndex + 1;
        while (left <= mid && right <= last){
            if (comp.compare(list[left], list[right]) <0) {
                temp[j++] = list[left++];
            } else {
                temp[j++] = list[right++];
            }
        }
        while (left <= mid) {
            temp[j++] = list[left++];
        }
        while (right <= last) {
            temp[j++] = list[right++];
        }
        for (j = 0; j < n; j++) {
            list[lowIndex + j] = temp[j];
        }
   }

}

QuickSorter.java

package com.bjsxt;

import java.util.Comparator;

/**
 * 快速排序
 * 快速排序是使用分治法(divide-and-conquer)依選定的樞軸
 * 將待排序序列劃分成兩個子序列,其中一個子序列的元素都小于樞軸,
 * 另一個子序列的元素都大于或等于樞軸,然后對子序列重復上面的方法,
 * 直到子序列中只有一個元素為止
 * @author Hao
 *
 */
public class QuickSorter implements Sorter {

   @Override
   public <T extends Comparable<T>> void sort(T[] list) {
      quickSort(list, 0, list.length- 1);
   }

   @Override
   public <T> void sort(T[] list, Comparator<T> comp) {
      quickSort(list, 0, list.length- 1, comp);
   }

   private <T extends Comparable<T>> void quickSort(T[] list, int first, int last) {
      if (last > first) {
        int pivotIndex = partition(list, first, last);
        quickSort(list, first, pivotIndex - 1);
        quickSort(list, pivotIndex, last);
      }
   }

   private <T> void quickSort(T[] list, int first, int last,Comparator<T> comp) {
      if (last > first) {
        int pivotIndex = partition(list, first, last, comp);
        quickSort(list, first, pivotIndex - 1, comp);
        quickSort(list, pivotIndex, last, comp);
      }
   }

   private <T extends Comparable<T>> int partition(T[] list, int first, int last) {
      T pivot = list[first];
      int low = first + 1;
      int high = last;

      while (high > low) {
        while (low <= high && list[low].compareTo(pivot) <= 0) {
           low++;
        }
        while (low <= high && list[high].compareTo(pivot) >= 0) {
           high--;
        }
        if (high > low) {
           T temp = list[high];
           list[high]= list[low];
           list[low]= temp;
        }
      }

      while (high > first&& list[high].compareTo(pivot) >= 0) {
        high--;
      }
      if (pivot.compareTo(list[high])> 0) {
        list[first]= list[high];
        list[high]= pivot;
        return high;
      }
      else {
        return low;
      }
   }

   private <T> int partition(T[] list, int first, int last, Comparator<T> comp) {
      T pivot = list[first];
      int low = first + 1;
      int high = last;

      while (high > low) {
        while (low <= high&& comp.compare(list[low], pivot) <= 0) {
           low++;
        }
        while (low <= high&& comp.compare(list[high], pivot) >= 0) {
           high--;
        }
        if (high > low) {
           T temp = list[high];
           list[high] = list[low];
           list[low]= temp;
        }
      }

      while (high > first&& comp.compare(list[high], pivot) >= 0) {
        high--;
      }
      if (comp.compare(pivot,list[high]) > 0) {
        list[first]= list[high];
        list[high]= pivot;
        return high;
      }
      else {
        return low;
      }
   }

}
663.寫一個二分查找(折半搜索)的算法。

答:折半搜索,也稱二分查找算法、二分搜索,是一種在有序數(shù)組中查找某一特定元素的搜索算法。搜素過程從數(shù)組的中間元素開始,如果中間元素正好是要查找的元素,則搜素過程結束;如果某一特定元素大于或者小于中間元素,則在數(shù)組大于或小于中間元素的那一半中查找,而且跟開始一樣從中間元素開始比較。如果在某一步驟數(shù)組為空,則代表找不到。這種搜索算法每一次比較都使搜索范圍縮小一半。

package com.bjsxt;
import java.util.Comparator;

public class MyUtil1 {

   public static <T extends Comparable<T>> int binarySearch(T[] x, T key) {
      return binarySearch(x, 0, x.length- 1, key);
   }

   public static <T> int binarySearch(T[] x, T key, Comparator<T> comp) {
      int low = 0;
      int high = x.length - 1;
      while (low <= high) {
          int mid = (low + high) >>> 1;
          int cmp = comp.compare(x[mid], key);
          if (cmp < 0) {
            low = mid + 1;
          }
          else if (cmp > 0) {
            high = mid - 1;
          }
          else {
            return mid;
          }
      }
      return -1;
   }

   private static <T extends Comparable<T>> int binarySearch(T[] x, int low, int high, T key) {
      if(low <= high) {
          int mid = low + ((high -low) >> 1);
          if(key.compareTo(x[mid]) == 0) {
              return mid;
          }
          else if(key.compareTo(x[mid])< 0) {
              return binarySearch(x,low, mid - 1, key);
          }
          else {
              return binarySearch(x, mid + 1, high, key);
          }
      }
      return -1;
   }
}

說明:兩個版本一個用遞歸實現(xiàn),一個用循環(huán)實現(xiàn)。需要注意的是計算中間位置時不應該使用(high+ low) / 2的方式,因為加法運算可能導致整數(shù)越界,這里應該使用一下三種方式之一:low+ (high – low) / 2或low + (high – low) >> 1或(low + high) >>> 1(注:>>>是邏輯右移,不帶符號位的右移)

664.統(tǒng)計一篇英文文章單詞個數(shù)。
package com.bjsxt;

import java.io.FileReader;

public class WordCounting {
   public static void main(String[] args) {
     try(FileReader fr = new FileReader("a.txt")) {
        int counter = 0;
        boolean state = false;
        int currentChar;
        while((currentChar= fr.read()) != -1) {
          if(currentChar== ' ' || currentChar == '\n'
             || currentChar == '\t' || currentChar == '\r') {
             state = false;
          }
          else if(!state) {
             state = true;
             counter++;
          }
        }
        System.out.println(counter);
     }
     catch(Exception e) {
        e.printStackTrace();
     }
   }
}

補充:這個程序可能有很多種寫法,這里選擇的是Dennis M. Ritchie和Brian W. Kernighan老師在他們不朽的著作《The C Programming Language》中給出的代碼,向兩位老師致敬。下面的代碼也是如此。

665.輸入年月日,計算該日期是這一年的第幾天。
package com.bjsxt;

import java.util.Scanner;

public class DayCounting {

   public static void main(String[] args) {
      int[][] data = {
           {31,28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
           {31,29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
      };
      Scanner sc = new Scanner(System.in);
      System.out.print("請輸入年月日(1980 11 28): ");
      int year = sc.nextInt();
      int month = sc.nextInt();
      int date = sc.nextInt();
      int[] daysOfMonth = data[(year % 4 == 0 && year % 100 != 0 || year % 400 == 0)?1 : 0];
      int sum = 0;
      for(int i = 0; i < month -1; i++) {
        sum += daysOfMonth[i];
      }
      sum += date;
      System.out.println(sum);
      sc.close();
  }
}
666.回文素數(shù):所謂回文數(shù)就是順著讀和倒著讀一樣的數(shù)(例如:11,121,1991…),回文素數(shù)就是既是回文數(shù)又是素數(shù)(只能被1和自身整除的數(shù))的數(shù)。編程找出11~9999之間的回文素數(shù)。
package com.bjsxt;

public class PalindromicPrimeNumber {

   public static void main(String[] args) {
      for(int i = 11; i <= 9999; i++) {
        if(isPrime(i) && isPalindromic(i)) {
           System.out.println(i);
        }
      }
   }

   public static boolean isPrime(int n) {
      for(int i = 2; i <= Math.sqrt(n); i++) {
         if(n % i == 0) {
           return false;
        }
      }
      return true;
   }

   public static boolean isPalindromic(int n) {
      int temp = n;
      int sum = 0;
      while(temp > 0) {
        sum= sum * 10 + temp % 10;
        temp/= 10;
      }
      return sum == n;
   }
}
667.全排列:給出五個數(shù)字12345的所有排列。
package com.bjsxt;

public class FullPermutation {

   public static void perm(int[] list) {
      perm(list,0);
   }

   private static void perm(int[] list, int k) {
      if (k == list.length) {
        for (int i = 0; i < list.length; i++) {
           System.out.print(list[i]);
        }
         System.out.println();
      }else{
        for (int i = k; i < list.length; i++) {
           swap(list, k, i);
           perm(list, k + 1);
           swap(list, k, i);
        }
      }
   }

   private static void swap(int[] list, int pos1, int pos2) {
      int temp = list[pos1];
      list[pos1] = list[pos2];
      list[pos2] = temp;
   }

   public static void main(String[] args) {
      int[] x = {1, 2, 3, 4, 5};
      perm(x);
   }
}
668.對于一個有N個整數(shù)元素的一維數(shù)組,找出它的子數(shù)組(數(shù)組中下標連續(xù)的元素組成的數(shù)組)之和的最大值。

答:下面給出幾個例子(最大子數(shù)組用粗體表示):
數(shù)組:{ 1, -2,?3,5, -3, 2 },結果是:8
2)?數(shù)組:{ 0, -2,?3,?5,?-1,?2?},結果是:9
3)?數(shù)組:{ -9,?-2,-3, -5, -3 },結果是:-2
可以使用動態(tài)規(guī)劃的思想求解:

package com.bjsxt;

public class MaxSum {

   private static int max(int x, int y) {
      return x > y? x: y;
   }

   public static int maxSum(int[] array) {
      int n = array.length;
      int[] start = new int[n];
      int[] all = new int[n];
      all[n - 1] = start[n - 1] = array[n - 1];
      for(int i = n - 2; i >= 0;i--) {
        start[i] = max(array[i], array[i] + start[i + 1]);
        all[i] = max(start[i], all[i + 1]);
      }
      return all[0];
   }

   public static void main(String[] args) {
      int[] x1 = { 1, -2, 3, 5,-3, 2 };
      int[] x2 = { 0, -2, 3, 5,-1, 2 };
      int[] x3 = { -9, -2, -3,-5, -3 };
      System.out.println(maxSum(x1));   // 8
      System.out.println(maxSum(x2));   // 9
      System.out.println(maxSum(x3));   //-2
   }
}
669.用遞歸實現(xiàn)字符串倒轉
package com.bjsxt;

public class StringReverse {

   public static String reverse(String originStr) {
      if(originStr == null || originStr.length()== 1) {
          return originStr;
      }
      return reverse(originStr.substring(1))+ originStr.charAt(0);
   }

   public static void main(String[] args) {
      System.out.println(reverse("hello"));
   }
}
670.輸入一個正整數(shù),將其分解為素數(shù)的乘積。
package com.bjsxt;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class DecomposeInteger {

   private static List<Integer> list = new ArrayList<Integer>();

   public static void main(String[] args) {
       System.out.print("請輸入一個數(shù): ");
       Scanner sc = new Scanner(System.in);
       int n = sc.nextInt();
       decomposeNumber(n);
       System.out.print(n + " = ");
       for(int i = 0; i < list.size() - 1; i++) {
           System.out.print(list.get(i) + " * ");
       }
      System.out.println(list.get(list.size() - 1));
   }

   public static void decomposeNumber(int n) {
      if(isPrime(n)) {
        list.add(n);
        list.add(1);
      }
      else {
        doIt(n, (int)Math.sqrt(n));
      }
   }

   public static void doIt(int n, int div) {
      if(isPrime(div) && n % div == 0) {
        list.add(div);
        decomposeNumber(n / div);
      }
      else {
        doIt(n, div - 1);
      }
   }

   public static boolean isPrime(int n) {
      for(int i = 2; i <= Math.sqrt(n);i++) {
        if(n % i == 0) {
           return false;
        }
      }
      return true;
   }
}
一個有n級的臺階,一次可以走1級、2級或3級,問走完n級臺階有多少種走法。
package com.bjsxt;

public class GoSteps {

   public static int countWays(int n) {
        if(n < 0) {
            return 0;
        }
        else if(n == 0) {
            return 1;
        }
        else {
            return countWays(n - 1) + countWays(n - 2) + countWays(n -3);
        }
   }

   public static void main(String[] args) {
        System.out.println(countWays(5));   // 13
   }
}
672.寫一個算法判斷一個英文單詞的所有字母是否全都不同(不區(qū)分大小寫)
package com.bjsxt;

public class AllNotTheSame {

   public static boolean judge(String str) {
      String temp = str.toLowerCase();
      int[] letterCounter = new int[26];
      for(int i = 0; i <temp.length(); i++) {
        int index = temp.charAt(i)- 'a';
        letterCounter[index]++;
        if(letterCounter[index] > 1) {
           return false;
        }
      }
      return true;
   }

   public static void main(String[] args) {
      System.out.println(judge("hello"));
      System.out.print(judge("smile"));
   }
}
673.有一個已經(jīng)排好序的整數(shù)數(shù)組,其中存在重復元素,請將重復元素刪除掉,例如,A= [1, 1, 2, 2, 3],處理之后的數(shù)組應當為A= [1, 2, 3]。
package com.bjsxt;

import java.util.Arrays;

public class RemoveDuplication {

   public static int[] removeDuplicates(int a[]) {
        if(a.length <= 1) {
            return a;
        }
        int index = 0;
        for(int i = 1; i < a.length; i++) {
            if(a[index] != a[i]) {
                a[++index] = a[i];
            }
        }
        int[] b = new int[index + 1];
        System.arraycopy(a, 0, b, 0, b.length);
        return b;
   }

   public static void main(String[] args) {
        int[] a = {1, 1, 2, 2, 3};
        a = removeDuplicates(a);
        System.out.println(Arrays.toString(a));
   }
}
674.給一個數(shù)組,其中有一個重復元素占半數(shù)以上,找出這個元素。
package com.bjsxt;

public class FindMost {

   public static <T> T find(T[] x){
      T temp = null;
      for(int i = 0, nTimes = 0; i< x.length;i++) {
          if(nTimes == 0) {
              temp= x[i];
              nTimes= 1;
          }
          else {
              if(x[i].equals(temp)) {
                  nTimes++;
              }
              else {
                  nTimes--;
              }
          }
      }
      return temp;
   }

   public static void main(String[] args) {
      String[]strs = {"hello","kiss","hello","hello","maybe"};
      System.out.println(find(strs));
   }
}
675.編寫一個方法求一個字符串的字節(jié)長度?
 public int getWordCount(String s)
    {
        int length = 0;
        for(int i = 0; i < s.length(); i++)
        {
            int ascii = Character.codePointAt(s, i);
            if(ascii >= 0 && ascii <=255)
                length++;
            else
                length += 2;

        }
        return length;
    }
第二篇:就業(yè)實戰(zhàn)

一:招聘程序員的內(nèi)幕

1.面試和相親

面試其實本質上是一個交流的過程,它跟你去相親本質完全一樣。那么,把握面試官的心理狀態(tài),從面試官的角度出發(fā)思考問題,將是你可以順利收到offer的關鍵。

如果你知道面試官的動機,就可以建立共通點,很容易就能恰當?shù)鼗貞獑栴}。從而為你的面試加分、添彩。

相親時,你期望碰到美女的渴望和美女期望碰到白馬王子的渴望,二者的“渴望程度”完全是一樣的。 那么,你如果是男方,你需要做的事情就是“包裝”自己,讓自己顯得比實際上“更高,更富,更帥”,接近女方的心中白馬王子的高度,越接近越容易成功。這個過程也存在“心理博弈”的過程,雙方聊過去、聊現(xiàn)在、聊未來。 有輝煌過去的喜歡聊過去來證明自己的未來;現(xiàn)在就輝煌的就喜歡聊當下;過去不行,現(xiàn)在不行的就喜歡聊未來,展現(xiàn)自己的雄心。

同上面相親的案例,面試中,面試官需要人才的熱烈程度等于你求職的熱烈程度。 我們首先要明白面試官需要什么樣的人才,然后展示自己,告訴他,我就是這樣的人才!

明白上面的道理,我們就需要針對整個招聘的過程進行詳細的分析,讓大家心里更有底,更容易把握面試官的心理狀態(tài)。

2.為什么要招聘程序員?為什么絕大部分總能找到工作?

一般公司招聘員工有三大類原因:

1.公司計劃性擴張

2.特定項目

3.有員工離職

因此,招聘者也是“求賢若渴”,他也面臨公司給他的績效壓力。 如何能盡快、低成本的招聘到合適的人到崗,而不耽誤業(yè)務的進展,這是招聘者最大的工作。

通常如果受到高層壓力,感覺招聘進度已經(jīng)限制了公司業(yè)務的發(fā)展、已經(jīng)阻礙了業(yè)務推廣的時間,招聘者就會變“急”。 就跟開發(fā)人員迫于項目時間的壓力,湊合完成一段不合格的代碼一樣。招聘者也會由于這些壓力,有可能降低招聘的崗位標準(這種降低不是明面上通知降低標準,而是各個環(huán)節(jié)把控較松)。 這也就是為什么很多人技術并不太好,也能找到工作的原因。 公司最大的成本有時候不是金錢、而是時間。 這也就像很多優(yōu)秀的男生女生30歲之后,迫于時間壓力,降低標準找對象的道理一樣。

雖然學習編程的人員很多,但是各行各業(yè)都需要信息化,人員需求也非常巨大,缺口仍然很大。 如果某個公司招聘并不順利,連續(xù)面試很多人都不合格,那么可能就在面試你的時候降低“標準”。 這也是為什么很多技術很水的人也能找到工作的原因。 對于招聘者來說,如果你心態(tài)好,很踏實,即使現(xiàn)在技術不行,花一點時間培養(yǎng)你,也沒什么大不了。

當然,這不能成為你不好好學習技術的理由?!奔夹g強、心態(tài)好、踏實”將會讓你面臨更多的人生機會。

3.為什么有人會找不到工作?

任何一個行業(yè)都有失敗者,這就是規(guī)律。 就像婚姻、戀愛市場,總會有打光棍的問題(100%是男同胞,男女比例嚴重失調啊)。 為什么會有人找不到工作?為什么會有人找不到老婆?這是個大課題。想明白了,你將會走向人生巔峰。

我們先以婚姻、戀愛市場為例。研究研究為什么會有人找不到老婆? 有人說,打光棍是因為這個人沒錢。 但你總會發(fā)現(xiàn)比他還沒錢的人娶了老婆,有的還很漂亮。老婆還很賢惠,出去打工養(yǎng)老公。 有人說,打光棍是因為這個人沒能力。 但你總會發(fā)現(xiàn)很多沒能力的人也娶了老婆,有的也很漂亮。 這時候,你只能仰天長嘆,“好白菜都讓豬拱了”。有人說,打光棍是因為這個人長得丑,個子矮、家里窮等等。但你總會找到層出不窮的反例。這時候,你可能就會迷茫了。 到底什么才是關鍵、才是問題的核心?

好吧,我告訴你, 是心態(tài)!心態(tài)!心態(tài)!重要的問題說三遍! 心態(tài)積極,勤奮努力什么事情都能干成。 心態(tài)消極,懶惰不努力,什么條件都沒戲! 很多“懶屌絲”寧愿天天宅在家里睡懶覺、玩游戲,也不愿意走出去。寧愿窩在家里練習右手臂力,也不愿意出去多跟異性接觸。 這些人,不管什么條件都將被淘汰。

大家如果看過電影《夏洛特煩惱》,里面的“大傻”,智商低,但是人實在。就是靠死纏爛打硬泡的方式,竟然也追上了自己的女神。 追女神也是概率問題,努力去追,提高成功率,女神總有空虛、心理沒底的時候,這時候可能就會有機會了。 某天,女神忽然微信呼你:“忙嗎?”,這時候機會就來了。 但是,如果你不努力,你連女神的候選名單都上不去,怎么可能有機會?

在招聘市場,應聘者面臨的是同樣的問題。 即使你技術水平差,只要多面試、多總結、多努力,沒有不成功的。 你想想,面試是個概率事件,技術差你的成功率即使只有1%,面試100家也上去了。 技術好你的成功率是10%,不去面試,面試的少,你可能也沒戲。 因此,我們要千方百計提高自己“面試的機會”,至少可以讓自己進入企業(yè)“眼里”,一旦有機會,即可成功。

我們曾經(jīng)碰到一個學員,大學學的是文科,學歷是???, 畢業(yè)后做了一名“光榮的水手”,環(huán)球航行了兩年,決定回歸陸地。 開始學習編程,學了1個多月后,仍然在糾結什么是變量的問題。 但是,這個同學心態(tài)好,積極向上,畢業(yè)后,積極主動的去面試,結果很快搞定了工作,剛開始工資并不高。 工作兩年后,成了項目經(jīng)理,年薪30萬。風風光光的回尚學堂招聘學弟學妹了。 積極努力,一天當兩天用,起點再低也會成功。

我們也碰到過一個奇葩的學員,在尚學堂學完后,就糾結于你們不是“推薦就業(yè)”嗎?窩在宿舍等著。 企業(yè)來了,老師通知也不來參加面試,偶爾來了,結果窩在宿舍根本沒有鍛煉出能力,也無法面試成功,這是極其個別的案例。即使你是千里馬,不出去跑,天天窩在家里,消極等待,最終你也會成為一匹“廢馬”。

所以,無論你是什么條件,高富帥還是矮矬窮,心態(tài)不對,戀愛和工作都不可能成功。 希望大家積極起來,大著膽子沖向社會,千方百計進入企業(yè)招聘環(huán)節(jié),即使不成功,就當做一次鍛煉機會,鍛煉多了,一旦機會來了,是不是成功率就大大提高了? 做“屌絲”可以,自嘲一下也不錯,但千萬不要做“懶屌絲”,那樣你就完蛋了。

4. 公司最喜歡什么樣的程序員?

公司喜歡什么樣的程序員?特別簡單,三個特點:

第一、態(tài)度好

態(tài)度永遠是第一要素,面試者通常都是你以后的直接上級。如果跟你交流順暢,看你態(tài)度也不錯,這樣對他來說,領導起來就容易一些。 因此,態(tài)度通常是面試官看人的第一要素。 態(tài)度不端正,一切免談。能力強我也駕馭不了,要你何用? 能力差態(tài)度好也勉強能接受,能力差態(tài)度還差那就分分鐘被滅掉。

如果你知道面試官的動機,就可以建立共通點,很容易就能恰當?shù)鼗貞獑栴}。從而為你的面試加分、添彩。

第二、技術能力較強

企業(yè)招聘人員畢竟是來做事的,技術能力是考察的重點。技術能力能勝任目前的工作,是面試官主要看重的。

第三、熱愛技術工作,學習能力強

通過跟面試官的交流,能讓別人覺得你熱愛技術工作,會讓你具備極大的優(yōu)勢。即使感覺你現(xiàn)在水平較差,也沒有關系。興趣是最好的老師,喜歡技術,把加班當成玩游戲一樣的態(tài)度,面試官顯然會大大的給你點個贊。

PS:這里順便給個技巧,可以讓你身價立刻增加30%以上(本來你值8000,可以拿到1萬,一下子讓你一年多掙3萬),那就是學習本專業(yè)的一些新的技術、高級一點的技術。不需要多么精通,了解即可。可以在面試的時候說出來。這樣就會令面試官對你刮目相看,薪水標準也會立刻增加。因為你說的這些技術,可能是面試官也不會的,這種對你的好感度和驚詫的眼神立刻就會讓你身價暴增。 很多java學員學完后再學大數(shù)據(jù)或者架構師班,都有這樣的誤解,覺得一定要學到多么多么好。其實,沒必要,了解大數(shù)據(jù)或者架構師班某些技術能交流即可,面試時優(yōu)勢已經(jīng)極大了; 而且,即使上了班,用到這些技術,查查資料加加班能弄出來就OK了。

如上三點決定了你是否能被錄用。大家掌握這三點,也可以互相補充。比如,你技術差,可以通過展現(xiàn)態(tài)度好,愛技術,愛學習來獲得加分。 當然,如果技術好,也要通過展現(xiàn)態(tài)度好,愛技術,愛學習獲得更多的分。

面試官經(jīng)常會碰到技術非常合適,但是態(tài)度較差,計較是否加班的面試者,基本都被pass。畢竟,技術再強也不是地球上只有你會,對不對? 如果態(tài)度差,加入團隊變成團隊的負能量,那就損失大了。

5.我到底值多少錢?

第一、態(tài)度好

“我是誰?”這是人生最大的命題,找工作最大的命題是什么呢?顯然,就是“我到底值多少錢?”。給自己確定了合適的定位,才能找到合適的工作。 如果你能力只值5000,一定要找3萬的工作,那怎么可能找得到?

一般情況,面試官評價你的薪資標準通常從下面幾項:

1.個人素質和口才(占比:20%)

這其實是個印象分,所以要被別人認可的其實就是上一個話題《公司最喜歡什么樣的程序員》中表示的第一特點:“態(tài)度好”。

如果你向面試官充分表達了良好的個人素質、對工作積極的態(tài)度,整個面試過程中讓面試官都覺得非常的順暢、很投緣,即使你技術較差,也可以讓你順利拿到offer。

“個人素質和口才”是你拿到offer的最關鍵因素。

2.基礎技術(占比:40%)

基礎編程能力、理論知識是否扎實、知識體系是否系統(tǒng)是面試官比較看重的。老師講課過程中的基本知識點要盡力吃透,良好的知識體系對于后期面試極其有利。

如果面試官感覺你項目經(jīng)驗不豐富,但是基礎扎實,也可以完全的彌補項目經(jīng)驗欠缺的問題。這也是很多應屆畢業(yè)生能順利就業(yè)的法寶。 當然,如果項目經(jīng)驗欠缺的話,高薪的概率就降低了, 需要降低薪資要求,保持較普通的薪水來實現(xiàn)就業(yè)。

“基礎技術”是你能否就業(yè)的基礎因素。

3.項目經(jīng)驗(占比:40%)

項目經(jīng)驗顯然是面試官極其看重的一項。從項目經(jīng)驗的描述中可以體現(xiàn)你的個人素質、基礎技術等等。盡量多的積累項目案例,盡量多的敲代碼,可以完成基本的項目模塊,會成為你以后面試的殺手锏。

在培訓期間,老師講的項目案例大家要學會舉一反三,畢竟這些案例對著幾十人、幾百人講過,你在面試時直接寫到簡歷上并不是特別好的做法。最好的做法是,做一個有心人,多留意和查找適合自己的項目案例。

項目案例是你的,里面的項目流程和開發(fā)中遇到的問題是老師課上講過的。說白了,就是將你的項目案例換了個衣服,“換湯不換藥”,這樣就可以在面試中起到更好的效果。

“項目經(jīng)驗”是你能否實現(xiàn)高薪的關鍵因素。

4.最新和高級技術了解程度(額外,增值30%--50%)前面3項如果做好了就可以完全保證就業(yè)了。“最新和高級技術了解度”是能否爭取到合理范圍內(nèi)更高薪水的關鍵,也就是讓你實現(xiàn)更高“溢價”,“超額把你自己賣出去“。

面試官通常由于平時工作忙,無暇學習新的技術和知識,除非是項目用到的技術。但是,作為一個“技術控“,通常會關注最新技術的信息,擁有學習這些技術的渴望,但是沒有時間和精力。 這個時候,應聘者簡歷上寫的新技術、面試時聊的新技術,都會成為讓”面試官欣賞你的理由“。

但是,注意千萬不要有心理負擔,這種”欣賞的眼神“是上級發(fā)現(xiàn)一個得力下屬的”喜歡的眼神“,而不是好基友。 面試官也知道你基礎一般、項目經(jīng)驗一般,但是這些新技術你都在學,證明你是個”技術好胚子“,很像曾經(jīng)的”他自己“而已。

如果前三項決定了你的薪水是8000,那么有了第四項,你的薪水標準通常會提高至少30%,最高50%。也就是實現(xiàn)了”你的溢價”, 每個月可以多賺:4000元左右。 而且,你會發(fā)現(xiàn)拿8000和溢價拿1萬,1萬2, 最后干的活其實差別不大。

這里有個經(jīng)過我們統(tǒng)計的”1.5倍定律”: 就是經(jīng)過”最新和高級技術”的助力,你的薪水會在原定值上增加50%,薪水是原來的1.5倍。

6.找工作最重要的是什么?薪水?機會?

什么最重要,因人而異。一般分為如下幾類:

這種情況,我也不多說。缺錢就看薪水,不缺就看機會。個人建議,看機會。

第二種情況:offer少,沒得挑

這種情況,當然,就是”別挑了。先進入行業(yè),再尋找機會”。時間浪費不起,如果因為薪水糾結,兩個月不上班,損失兩個月薪水不說,還浪費了兩個月時間。

第三種情況:沒offer

這種情況,就是降低標準,千方百計就業(yè),不管什么企業(yè),先進去再說。進去行業(yè)后,再學習,再進步,再找更大的機會。

我們始終強調”機會成本”,差不多的前提下,盡快就業(yè),不要糾結于薪水多500少1000的問題,進入行業(yè)后,還需要再學習再提高。 現(xiàn)在就業(yè)不是你的終點,而是你的起點。

7.學習很多技術,現(xiàn)在的公司不用,不是虧了嗎?

很多朋友還是跟小孩一樣, 感覺學習了東西后如果考試不考,公司暫時不用就沒有價值,不想學習。 感覺學習好累啊,是給老師學的,給尚學堂交了學費,是給尚學堂學的。別不承認,很多人潛意識里面就是這種”應試教育”思維。

多學東西到底是為什么?其實,很簡單。掌握更多的技術,意味著更多的機會,有更多選擇的機會。 人和人之間本質的差距就是“選擇權“的差距。 農(nóng)民自家種蔬菜、養(yǎng)豬吃,很干凈很有機;千萬富翁可能還要吃著普通的豬肉和蔬菜;他們之間的差距在于:千萬富翁可以隨便選擇,可以隨時過農(nóng)民的生活;而農(nóng)民卻沒有選擇過千萬富翁生活的權利。 多學技術,就意味著有更多選擇的機會,發(fā)展的機會,就會造成工作和生活的差距。

同時,在IT行業(yè)多學東西,除了這些“機會和選擇權“之外,更直接的就是能帶來金錢的收益。 舉例來說,同樣招聘一個java程序員。小A只會java已經(jīng)合格了。 小B除了會java,還會一點大數(shù)據(jù)和架構知識,要價比小A高20%。 關鍵是,我們公司現(xiàn)在也不需要大數(shù)據(jù)和架構技術,小A和小B來了以后還是寫java代碼。 你猜,面試官會選擇小A還是小B? 絕大多數(shù)面試官會選擇小B。 有了小B,一旦后期有大數(shù)據(jù)和架構的需求,技術經(jīng)理就多了一個選擇。 而且,小B顯然更好學,成長性更好,雖然薪水高20%,但是幾個月時間就能把這20%的薪水賺回來。

掌握或了解更多的技術知識,拋開企業(yè)用和不用的角度,單純看應聘者就是一個態(tài)度的問題、成長潛力的問題。 面試官顯然會要態(tài)度更好、成長力更大的員工。

另外,你的企業(yè)現(xiàn)在不用,以后可能會用呀,這個時候你可能就具備強大的話語權和機會了。 我們一個大數(shù)據(jù)的學員畢業(yè)后,他還是應屆生,去了一家公司做java開發(fā),沒多久老板成立大數(shù)據(jù)業(yè)務的公司,結果公司就他會,直接就被任命為大數(shù)據(jù)業(yè)務的技術負責人。 你可以說,這個學員還年輕,技術不行什么的,但是他有這個技術負責人的平臺,還要學習和提高,現(xiàn)在不行,一年后呢?

多學習,意味著更多的機會和選擇;更多的機會,意味著完全不同的人生。

二:找工作前需要準備的殺手锏

高考前,我們要練兵考試和集訓?!迸R陣磨槍不快也光 ”,找工作前,我們也必須要花很多精力去完成一些必要的準備。 “不打無準備之仗”, 精心準備和訓練會對你有相當正面的作用。

有人認為“找工作要靠能力”。這話沒錯,我要說的是,“臨陣磨槍準備的內(nèi)容也是能力的一部分”。 找工作其實是結果導向的一個事情,而不是過程導向。

小A和小B技術實力差不多, 小A經(jīng)過精心的準備和策劃,獲得的機會顯然要遠遠多于小B。也許一個機會,就能完全將小A的命運改變了。

1.職場的十大基本素質

大家進入職場前,非常有必要明白職場的一些基本要領。其實,道理都非常簡單,甚至可以說是常識, 關鍵是我們能否執(zhí)行下去。很多人不明白這些基本的道理,幾年下來,壞的行為固化成習慣,習慣進一步融入到命運,最后很悲慘的成為人人鄙視的loser。所以,我希望大家從看到這篇文章起,就遵守這樣的行為準則,你將會在職場中很快迎來自己的好運。

①著裝整潔、個人衛(wèi)生合格

這個都不能算作職場素質,應該是做人的素質。每天逢頭垢面出門、指甲里面都是污垢、身體有異味,如何讓別人覺得你是個靠譜的人?千萬不要跟我說,你不拘小節(jié)。不拘小節(jié)是謙詞,別人可以給你面子這么說你,但你不能這么說自己。每天出門前,男士花十分鐘打理一下自己,穿一身干凈的衣服。你可以沒有阿瑪尼,穿地攤貨都可以,關鍵是干凈整潔。干凈整潔、形象良好,馬上可以讓人對你的印象提高N個檔次。

記得幾年前,一個學員過來找我,說:“老師,我面試了好多家了。為什么都是幾分鐘就被人打發(fā)了”。我極其驚訝地看著他,N天沒有洗澡,亂糟糟的頭發(fā),滿臉油膩,“逢頭垢面”就是形容他的。那時候是夏天,估計N天沒洗澡,一股異味。基本上我可以斷定,這個哥們的處境。第一、沒朋友,無論男女。沒有人會愿意跟他呆的距離在1米以內(nèi),那真是一種折磨。第二、沒前途。不知道哪個瞎眼的面試官會要他?于是,我很殘忍的告訴他現(xiàn)在的處境。

我問他:“你個人衛(wèi)生是不是太差了。這個儀表,人家跟你說十分鐘都是給你天大的面子了”。他說:“我知道衛(wèi)生有點差。但我覺得別人不會那么庸俗的,應該更多的關注我的技術和我的人品”。

我說:”大家時間都很有限,都很忙。第一、跟你技術水平相當?shù)娜硕嗟檬?,沒必要花時間透過你這個外表去琢磨你的內(nèi)在。第二、你太自我為中心了。別人應該關注你的內(nèi)在,你怎么不說,你應該改改你的外在?連基本外在衛(wèi)生都沒有,你還能做什么?“。

他仍然固執(zhí):”講衛(wèi)生很簡單,我每天花點時間整理一下就行了。但是…“。

我打斷他的話:”先回去洗個澡,換身干凈的衣服。你這樣的儀表,第一、不尊重你自己。第二。不尊重別人。不說工作了,你這樣怎么找女朋友?想改變你的處境,先改變你的儀表,改變你的行為。以后,每天早上花十分鐘整理一下自己,不然,你完蛋了“

后來,就沒再來找我。一年后,我收到一個短信:“高老師,感謝你的醍醐灌頂。以前,太自以為是,以為世界都是圍繞我的。那天回去后,我就真的“洗心革面”了,每天早上整理一下外表,都不用十分鐘,五分鐘就夠了。后來,我再面試只花了一周時間就上班了。這一年里,收獲很大,也有了女朋友,也有了很多男性朋友,整個人生都感覺改變了。再次謝謝您的直言不諱”。

②有正常的交流習慣

一個正常的交流習慣也是及其重要的。正常的交流習慣有如下五點:

1.不打斷對方說話

這是對別人最基本的尊重,把話讓別人講完,也是最基本的禮貌。

2. 說話時,盯著對方的眼睛。眼神堅定,不飄忽

眼睛是心靈的窗戶。跟人交流時,千萬不要邊說話,眼睛邊四處看。要緊盯著對方的眼睛,如果你實在不好意思,可以盯著鼻梁看。盯著鼻梁,在對方看來也是盯著眼睛的,效果差不多。

3. 說話時,語氣不拖拉。

說話語氣肯定,有自信,千萬不要嗯嗯啊啊。

4. 沒有小動作,但可以適當增加手勢

抖腿、搓手、動手碰別人這都是不禮貌的習慣。交流時,不要有這些不良動作,但是可以適當增加手勢,讓你的交流更順暢。

5. 表情放松,多一些微笑

不要將跟別人的交流搞得太過正式,放松一些,多一些微笑。

③準時,不遲到

一個沒有時間觀念的人,怎么可能做好事情?因此,面試不遲到、約會不遲到,這都是最基本的禮儀。而且,所有的面試、約會最好保證提前十分鐘到達。

但是,萬一發(fā)生了遲到的狀況,怎么辦?萬一由于堵車等原因遲到,要立刻打電話聯(lián)系對方,告知對方原因,并表示抱歉。

領導不下班,你也不走

對于初入職場的你來說,非常有必要讓領導看到你的工作態(tài)度。你可以工作做的慢,但是態(tài)度必須端正,至少要讓領導覺得你是可造之材而不是爛泥。

如果你的直接上級仍然在加班工作,你非常有必要保持同步。如果能幫上忙,可以上前問問有沒有需要你做的事情。如果暫時幫不上忙,可以坐在電腦前學習一些專業(yè)性的知識。能做到這一點的人,其實真的不多。做到了,也基本就可以奠定你工作認真、愿意付出的形象,為以后創(chuàng)造更多的機會打下基礎。

⑤和周圍的同事打成一片

多跟同事交流、打成一片,是職場最基本的規(guī)矩。這在平時工作和休息時,一定要多注意不能落單。最典型的:中午午餐時間,一定跟同事們一起吃飯,不要落單。

⑥有困難,就馬上尋求幫助

工作中遇到問題,自己通過查資料無法解決。立刻尋求同事幫忙,千萬不要因為不好意思開口而耽誤工作時間,影響公司整體的工作進度。

⑦有責任心、事情到我這里結束

基本的責任心及其重要!千萬不要以分工清楚、不是我的事情作為推脫的借口。在大公司,分工過細是事實,但是你也經(jīng)常需要參與工作之外的事情。在中小企業(yè)就更不用說了。事情到你這里,你能把他解決掉,本身就是能力的鍛煉和提升,是讓自己升值的機會。如果,你把它推脫開,不僅喪失了鍛煉的機會,也讓別人看到了你的態(tài)度,看清了你的前途。

以前遇到過一個“搬椅子”的小事情。一次開會,會議室少五把椅子,老板已經(jīng)坐下,說:“多了5個人,少5把椅子”。負責安排會議的人竟然問:“讓我去搬嗎?”他也許是想說,我是個女孩哎,搬不動。也許是想說,我是個經(jīng)理哎,讓我去搬椅子,多沒面子??傊f了這5個字。老板一臉錯愕,沒說什么。一周后,這個女孩辭職走人。

工作中,你碰到了就是你的事情。解決的事情越多,你得到的鍛煉機會越多,你的能力就越強,還怕沒有升職和發(fā)展的機會嗎?

很遺憾的是,工作中很大一部分都是責任心缺失的人。這也很幸運,這些無責任心的人會讓出很多的機會給你。一定要相信,你有沒有責任心,你的上級、你的女朋友一定能第一時間知道。

⑧學習的心態(tài)對待同事和上級、包容的心態(tài)對待同事和下級

“懂得配合才能有領導力、才能有協(xié)作力”,對待你的上級一定要抱著學習的態(tài)度。他能做到這個位置,肯定有過人之處、肯定有比你強的地方。把他這些優(yōu)點學習到位,再進行改進,青出于藍,你不就有機會了嗎?

工作中,很多同事都會私下議論上級,覺得這個決定好傻、那個決定好呆。往往是由于下級和上級看問題的角度不一樣導致的,“屁股決定腦袋”。那么,為什么不嘗試配合一下領導的決定看看到底行不行呢?或者,你覺得確實有問題,完全可以私下跟領導說說你的感想。在企業(yè)中的人事關系要比政府關系簡單的多,你私下有禮貌的提出來你的意見,往往還能博得上級的好感。

⑨忠誠

如果你不忠于你的公司,私下貪污公款、私下為其他公司牟利。一旦有這些行為,基本上你就為人所不齒了。在公司你肯定不會有好的前途,其他公司看你這樣,無非就是利用一下你,但絕對不可能重用你。

永遠不要以自己的小聰明耍弄你的上級和你的同事,這個世界,智商都差不多,誰比誰笨呀?你可以蒙他一次,兩次,不可能蒙他三次、四次。就像你考試作弊一樣,自以為很聰明,但如果你坐在講臺上監(jiān)考,你就明白,下面的動作一覽無余,更多的時候,只是老師不愿意去把你拎出來而已。

所以,職場上,忠誠是人的最基本的素養(yǎng)。

⑩辦法總比問題多,積極的心態(tài)面對問題

工作中遇到問題,不要害怕。工作就是解決一個個問題呀!既然是問題,就有應對的辦法。想盡辦法,總能解決。不要遇到問題就牢騷滿腹:“完蛋了。這絕對不能解決”。發(fā)牢騷的人,在公司里面不僅毫無價值,而且是負價值。

2.公司調研

對于你即將要面試的公司,一定要做到“知己知彼”,在面試前做充分的調研。這樣既能讓你在面試的時候與HR有充分的互動機會,也可以避免很多無良公司的“坑”。

做公司調研需要做到如下幾個關鍵點:

1. 公司發(fā)展的歷程

2. 公司的產(chǎn)品或者項目以及周期

3. 公司下一步的發(fā)展規(guī)劃

4. 公司開發(fā)使用的技術架構

5. 公司跟開發(fā)有關的組織結構(開發(fā)部、測試部、運維部、產(chǎn)品部等)

3.項目調研

對于企業(yè)來說,會關注你大學期間成績單呢,還是關注你的項目經(jīng)驗?答案顯然是:項目經(jīng)驗。甚至在很多研究生復試時候,導師看到你的簡歷上寫了很多項目經(jīng)驗,也會極大的增加你的分數(shù)。五年前,我的一個學生在尚學堂培訓時的項目寫在研究生復試簡歷上,被導師問了又問,最終被中科院計算所錄取。這就是項目的力量。

因此,前期的項目準備會讓你的簡歷更加豐富,贏得更多的機會。一個小小的機會也許就能完全改變你的命運。

對于項目調研,大家要避免誤區(qū)。不是說,一定要將項目的商業(yè)源碼搞到手,通讀一遍才算是完成調研;也不是說,一定要把這個項目代碼寫一遍;其實,項目調研的本質是讓你開闊眼界,增加和“面試官”的談資。

項目調研最重要目的是要讓你明白某個項目開發(fā)的流程、某個項目的內(nèi)在邏輯,此類項目常見的問題,開闊眼界,最終真正理解項目開發(fā)的整體流程。

項目調研關鍵是要做到有心!現(xiàn)代互聯(lián)網(wǎng)這么發(fā)達,任何資料都可以在網(wǎng)絡上找到。我可以給大家提供各種項目調研的思路:

A. 打開各種網(wǎng)站,其實就是一個個項目。

B. 打開相關軟件公司,下載他們軟件的試用版,就可以去研究他的內(nèi)在邏輯。

C. 下載各種app,也是一個個完整的項目。

D. 各種開源網(wǎng)站下載的項目,也可以作為研究的對象。

E. 大膽出去,參加一些創(chuàng)業(yè)、創(chuàng)意相關的活動。比如:中關村創(chuàng)業(yè)一條街的各種會議。

4.基礎技術準備

就業(yè)前,大家需要將自己平時培訓期間學習的技術捋一遍,全面復習一遍。臨陣磨槍仍然是最重要的應急手段,面試前的準備就像高考前一樣,越充分越好。

但是,需要記住如下兩點:

1. 對于一些常見的面試和筆試問題,一定要反復練習,最好能背下來。

2. 對于一些工作和面試不常見的問題,記住結論即可,不要糾結。不要因為一些小概率的問題而浪費太多的時間。畢竟,任何人都沒有必要有能力可以應對所有的問題,只要能應對常見的問題足以實現(xiàn)就業(yè)。

5.熱門技術準備

軟件行業(yè)技術更新較快,經(jīng)常會出現(xiàn)新的技術。但是,這些技術通常不會馬上應用于企業(yè)中,企業(yè)一般都會使用穩(wěn)定和大眾化的技術。所以,企業(yè)應用技術通常都有2-3年的滯后期。

身處軟件開發(fā)第一線的人往往對新技術學習也會滯后,畢竟企業(yè)不用,大家還是不愿意多花時間和精力去學習。但是,作為程序猿往往對這些技術保留了極大的好奇心。絕大部分程序猿會心想:“等我有時間,我一定要學習一下”。

這種滯后性,就是剛進入軟件行業(yè)的新人的機會。如果你是做IOS開發(fā)的,簡歷上寫明會使用swift語言開發(fā),就會引起一直使用Object-C開發(fā)項目的面試官極大的興趣。如果你是做JAVA開發(fā)的,會使用微服務架構,了解大數(shù)據(jù)相關的技術,也會引起面試官較大的興趣。而且,更有意思的是,你不需要精通這些新技術,只要了解即可。就能很快的引起面試官的興趣,畢竟“好奇心”是程序猿最大的特點。

對于熱門新技術的了解,可以明明白白的告訴對方,你就是一個喜歡技術、喜歡鉆研的典型的程序猿。這會給你起到加薪加分的效果。” 1.5倍薪水定律”就會起到作用。

6.更高端技術準備

技術行業(yè)是一個非常干凈的行業(yè),付出和得到基本是正比關系,你不需要靠關系靠背景。作為程序猿,學習就是本能,學習跟你的薪水是成正比的!學習越多,薪水越高。作為一個專業(yè)的程序猿,必須做好進一步提升的準備。千萬不能有已經(jīng)到頭的想法!一個二三十歲,剛入行的年輕人,如果產(chǎn)生了已經(jīng)學夠的想法,那說明你的前途也到盡頭了!”觀念決定行動,最終決定命運”。

對于本專業(yè)更加高端的技術,一定要保持學習的心態(tài)。即使,這些技術暫時用不到。對于開闊眼界,提高思維境界,應對面試都是極好的。掌握或了解本專業(yè)更高端的技術,加薪加分效果也很明顯?!?.5倍薪水定律”效用也非常明顯。

7.本專業(yè)之外的技術準備

很多人會以:“專業(yè)貴精不貴多”,“一招鮮吃遍天”,作為不學習其他技術的借口。這些話沒有錯,我也贊成這些話。但是,這些話不能作為不學習的理由。

一個學習安卓、IOS開發(fā)的程序猿當然最重要的就是掌握本專業(yè)的開發(fā)技能,但是如果你還了解后臺服務器程序的開發(fā),這就是你不同于普通程序猿的優(yōu)勢。

一個學習JAVAEE開發(fā)的程序猿,學好JAVAEE是最重要的,再了解大數(shù)據(jù)開發(fā)的知識、人工智能開發(fā)的知識, 也可以觸類旁通, 讓自己獲得更多技巧。同時,在面試JAVAEE的時候,你竟然也懂大數(shù)據(jù)、懂人工智能(也許只是皮毛)?但也一定可以給你的面試加分。

知識面寬往往意味著好學,潛力巨大。經(jīng)過兩三年的磨練后,熟悉各種技術的你,必將迎來一次發(fā)展的機遇。為什么機遇一定會給你?顯然,一般人是做不到這一點的。

我們有一個學員學完JAVAEE后,又學習了大數(shù)據(jù)開發(fā),很多人說他:“好傻,你去公司只是做一份工作。學那么多干什么?“。但是,這些嘲笑他的人錯了。這位學員三個月后,就成了公司項目的負責人,很簡單,就是因為他JAVAEE會,大數(shù)據(jù)也會,公司正好需要兩方面都懂的人。

“如果因為學習,別人說你傻”,我們只能回應:“別人笑我太瘋癲,我笑他人看不穿”。這個社會,如果不能跟別人拼爹,那就只能跟別人拼頭腦拼血汗了。

8.共同話題準備

面試你的人基本都是程序員,或者程序員出身,因此你們在對話中都可以找到很多共同話題。那么,為了讓我們的面試充滿各種“亮點”,對于共同話題的準備就相當有必要了。“用心去準備的面試,連面試官都會被你認真的態(tài)度打動;反過來說,如果連面試都不重視的人,我怎么相信你會對工作更有責任?”。

我們可以準備以下這些問題:

1. 是否曾經(jīng)耗費幾個小時甚至幾天的時間來追蹤一個頑固的bug?

2. 你有沒有因為某個問題加班到半夜的經(jīng)歷?

3. 你喜歡某種編程語言的哪一點?

4. 經(jīng)常訪問哪個程序員的網(wǎng)站?

5. 你最喜歡看的編程類的書籍是什么?

6. 關于IDE,什么事最讓你抓狂?

7. 精心準備幾個能說明你技術能力的專業(yè)問題,在面試時盡量發(fā)揮出來。

9.自我模擬面試和對練

開始投遞簡歷前,可以五人一組互相對練,進行角色扮演。分組練習的好處非常明顯,可以讓我們在非常短的時間里得到提升。分組練習的角色有:面試官、應聘者、旁觀者。

分組練習的好處有:

1. 面試官面試別人可以體會如何設問,對方回答是否得體

2. 應聘者可以身臨其境體驗被面的過程。

3. 旁觀者可以清晰的看到面試官的優(yōu)缺點、應聘者的優(yōu)缺點。加強學習,避免自己發(fā)生這些問題。

但是,也不能過多的訓練。以每人各扮演兩次角色(兩次面試官、兩次應聘者)為宜。然后,馬上投遞簡歷,開始實戰(zhàn)!!

三:面試準備

1. 簡歷的作用

一份格式規(guī)范、要點突出的簡歷是你找工作的“敲門磚”,值得你花上一周、甚至兩周時間精心打磨。這樣你會獲得更多的機會。當然,簡歷僅僅是敲門磚,任何一個面試官都不可能僅憑簡歷就雇傭一個人。

2.簡歷兩個靈魂

第一要點:必須自己親自寫簡歷。

簡歷必須每個字都自己寫,絕對不能抄!自己親自寫一次簡歷,相當于把技術復習一遍,把項目捋一遍,對于其中的關鍵點可以做到心中有數(shù)。 面試中的很多問題都是根據(jù)簡歷問出來的,只有自己親自寫一遍才能靈活應對。

第二要點:簡歷要突出自己的核心競爭力。

一個職位會有幾十、幾百份簡歷的投遞!投遞簡歷顯然是存在競爭關系的,一定要對簡歷作出適當?shù)陌b,就像去相親要化妝一樣。 不包裝的簡歷如同沒有穿衣服逛街一樣,雖然顯得本真,但是也很神經(jīng)病,很傻。在面試官看來,沒有包裝的簡歷會顯得你這個人不識時務,不靈活,而不會覺得你這個人本真(其實就是天真)。 處在世俗社會里面,我們要隨“社會大流”,別人化妝我們也要跟進,不求占別人便宜,但是也不能吃虧。但是,包裝不能欺騙企業(yè),掌握好“度”。

3.一份完美的簡歷(6大要素)

1.囊括相關技術關鍵詞,注意上下文

公司每天會收到幾十份簡歷,篩選這些簡歷往往是不懂技術的招聘人員,因此盡量寫上你會的技術的關鍵詞。

2.文筆要好,要點突出,簡明扼要

如果你不知道如何組織文字,可以先嘗試將想表達的內(nèi)容講給朋友聽,這非常有效。第一、可以起到互動、交流的作用,讓你的朋友給你指正。第二、可以捋思路。第三、為面試時的回答打下堅實基礎。

3.對工作經(jīng)驗、項目經(jīng)驗、實習經(jīng)驗作出解釋

如果你聲稱具備某種工作經(jīng)驗、項目經(jīng)驗,那么就必須說明是如何獲得的。如果簡歷上寫了“3年java開發(fā)經(jīng)驗”、“3年ios開發(fā)經(jīng)驗”,不進行進一步的說明,就顯得太虛假了。 不說明倒也沒關系,但是面試官收到的簡歷可不止你這一份,畢竟還是有很多人進行了詳細的說明。你不說明就意味著白白丟失了很多機會。 就像去相親見面,但是你不化妝、不打扮,穿著拖鞋去了,那我想你太吃虧了。 我們不想占別人便宜,但絕不能吃虧。

4.工作經(jīng)歷不要留有情況不明的空白期

簡歷中,不要留下特別長的空白期,這會讓人覺得你心中有鬼。

5.個人愛好和特殊證書

很多人會寫上自己的個人愛好:“卡拉ok,聽音樂,看電影”。這些不能體現(xiàn)個人素質的內(nèi)容不如不寫。但是,如果你是籃球校隊、乒乒球學校冠軍、廚藝大賽冠軍這些倒是可以寫在自己的簡歷上。

6.簡歷結構明了,條理清晰

簡歷結構一定要清晰明了,便于招聘者快速閱讀。不過,現(xiàn)在的招聘網(wǎng)站都有標準的模板,應聘者往里填數(shù)據(jù)即可。

如下是一份比較規(guī)范的簡歷,該學員當時年薪為30萬(稅前,北京)。 大家可以作為奮斗的參考。當然,寫簡歷簡單,掌握簡歷上的內(nèi)容難??梢哉f,簡歷上的每個字都代表“一段血淚史”。

4.簡歷的常見錯誤

“千里之堤,潰于蟻穴”, 簡歷可以讓招聘者對你形成第一印象。如果簡歷中存在細小的錯誤,也會被視為不認真的體現(xiàn),可能會讓你失去很多機會。

通常有如下錯誤:

1.手機號、qq號錯誤、電子郵箱格式不正確

真的有傻瓜竟然會把自己手機號碼寫錯,或者寫了已經(jīng)停機的舊手機號碼。然后,坐等招聘電話。 這些基本聯(lián)系方式,一定要核準無誤。

2.技術詞匯拼寫錯誤

這也是常見的錯誤,技術詞匯單詞錯誤、大小寫不對等等,這會直接降低你的第一印象。連自己的簡歷都不認真,還能做什么? 就像出門不洗臉的人,還能期望他做什么?

3.排版混亂

排版必須清晰,大方,結構整齊。

4.抄襲別人的簡歷

這是對自己和他人最大的不負責任。想找工作連個簡歷都懶得寫,這種態(tài)度如何處人處事?面試中,針對簡歷提出的問題,你如何能回答?

所以,抄簡歷,一定是死路一條。

5.注冊招聘網(wǎng)站和簡歷投遞

簡歷準備好以后,必須盡快的進入投遞環(huán)節(jié)。不要等待,不要老琢磨“我要把各個環(huán)節(jié)搞明白再投簡歷和面試”,這是錯誤的想法。我們必須在戰(zhàn)場中提高自己,實戰(zhàn)中提高自己是最快的。

首先,注冊著名招聘網(wǎng)站或者地方類招聘網(wǎng)站,并在這些網(wǎng)站上完善簡歷。智聯(lián)招聘、51job、中華英才、拉勾網(wǎng)等這些網(wǎng)站是必須要注冊的,一個都不能少。如果在地方城市找工作,地方類招聘網(wǎng)站也可以注冊,比如:長沙的芙蓉人才網(wǎng)、太原人才網(wǎng)等。

簡歷投遞一般采用海投的方式,并且要隔兩三天海投一次。 海投會給企業(yè)招聘者帶來一定的麻煩,但是對于應聘者是最高效的方式。對于應聘者來說,時間很寶貴。千萬不要把時間花在一個個篩選企業(yè)上面,對于剛入行的新人,還沒有資格篩選企業(yè)。至于有善良的應聘者害怕企業(yè)的HR麻煩,我只能說: “你想多了”。

一份合格的簡歷海投完后,你就會接到一些面試電話。下面就應該學習怎么應對面試電話了。

6.接面試電話如何應對

接到面試電話的時候,一些基本的電話禮儀你需要知道。通過如下的場景模擬,讓你對接電話后的流程有一個基本的了解。

流程如下:

1. 接聽電話第一句通常是: “喂(二聲),你好”。

2. 對方通常會說:“我是xxx公司,我們這里收到你的簡歷。你明天上午10點有時間來我公司面試嗎?”

3. 你通常會說:“可以,沒有問題。貴公司的地址在哪里?”。注意,如果時間上不允許,比如跟你已經(jīng)約好的一家公司沖突了。你也可以大方的告訴別人,明天上午有面試了,能不能換一個時間。

4. 對方會說: “我們公司在海淀區(qū)xx大廈12層1201”。

5. 你可以說: “那我到了以后,跟您聯(lián)系嗎?您怎么稱呼?”

6. 對方會說: “我姓高。到了,你跟前臺說找高七七就行”。

7. 如果你對自己查詢交通路線不太放心,可以問一下對方,如何到他們公司。如果有信心,就不用問了。

8. 最后,你一定要這樣說,“好的。謝謝你。我跟您確認一下。您的公司名字是:xxx公司。明天上午10點,在海淀區(qū)xx大廈12層1201。對嗎?”

9. 對方回答: “是的。沒有問題。還有其他問題嗎?”

10.你回答: “沒有了。謝謝。我明天準時到貴公司”。

11.對方回答: “好的。再見”。

12.你回答:“OK。再見”。等對方掛掉電話后,你再掛掉電話。即可結束本次電話邀約。通過一次交流,將公司名稱、地址、面試時間、聯(lián)系人問清楚即可。

然后,立刻馬上,使用手機或者電腦查詢這個公司相關的信息,越詳細越好。直到能夠回答如下問題為止:

1. 公司發(fā)展的歷程

2. 公司的產(chǎn)品或者項目(該公司同類型公司的產(chǎn)品和項目,各自的優(yōu)劣勢分析)

3. 公司下一步的發(fā)展規(guī)劃

這些問題,將會讓你在后續(xù)的面試中獲得意向不到的收獲。

7.去公司之前的準備

去公司面試前,做到如下五點:

1. 查詢和調研該公司的基本情況

2. 個人衛(wèi)生整潔,著裝干凈

3. 提前10-15分鐘到達,不遲到(萬一遲到,一定電話通知對方,告知實情)

4. 將以前面試遇到的問題再預演一遍

5. 將筆試題再復習一遍

8.筆試

去企業(yè)筆試,通常都會做一份該企業(yè)的筆試題目,作為基本的考核。通常,企業(yè)筆試題目都大同小異,都是一些常見工作問題,不會出現(xiàn)偏題難題怪題。如果你之前,已經(jīng)做過常見筆試題目,絕大部分題目都可以囊括。所以,只要好好準備,筆試不會構成特別大的問題。筆試過后,通常都會帶你進入面試環(huán)節(jié)。面試官通常都是你以后的直接上級,這時候就需要你好好表現(xiàn)了。

四: 面試

1.面試時,為什么沒必要緊張?

第一、從心態(tài)上你要把這次面試看做一次練習,成敗都可。畢竟,說實話,面試成功是小概率事件,按照一個人面試十家公司成功一家來看,每家成功的概率只有10%。所以,完全沒有必要緊張。

第二、面試官在跟你交流的時候,并不會將你說的每個字都記在心里。畢竟,他也有工作壓力,他可能在想:“下午開會,怎么跟老板交代的問題”。面試官多數(shù)時候,是處于一個完全放松的狀態(tài),聽你回答只是聽個流程和大概,并不會全身心投入。所以,你盡可以放輕松的交流。你的若干小問題,對方通常都不會注意到。

第三、面試完你以后,面試官還要再面試N個人。最后留到腦子里的就是你當時表現(xiàn)的打分結果,不會對你們這些應聘者每個都留下特別多的回憶。如果你覺得你說的做的每個細節(jié),面試官都看到了。通常,是你想多了。

第四、失敗又有何懼?此地不留爺,自有留爺處!天下公司那么多,只要我多面試,多總結問題。即使只有1%的機會,面試100家不是也能面上嗎?

當然,上面是給大家做“失敗并不可怕的心態(tài)調整”,并不意味著你就可以浪費大把面試機會而不珍惜。

2.面試中的禮儀

面試中,遵循正常的職場禮儀即可。這是“最基本要求”,如果你有任何一點問題,都可以讓你的成功率立馬降低50%以上。

所以,一定要遵守基本原則:

1. 微笑、禮貌、大方

2. 有正常的交流習慣,沒有小動作(抖腿、搓手等)

3. 絕對不能爭論

4. 衛(wèi)生干凈,衣冠整潔即可(沒必要西裝領帶)

面試開始時:

1.面試官進入、求職者從座位起立,微笑說:“你好”。

2.如果對方是男士,可以主動伸手握手。如果是女士,不要主動,看對方示意即可。

面試結束時:

1.結束時,一定要對面試官表示感謝。

2.將座位放回原位,幫助收拾一下桌面衛(wèi)生,所有物品物歸原位。

3.常見技術面試場景分析

無論面試官是否是技術人員出身,我們一定要給出充分準備的回答,發(fā)音準確的技術名稱,不要有所保留,盡可能仔細地回答問題。一定要在面試前,準備本專業(yè)至少20個常見的專業(yè)技術問題,能對答如流,可以變成自己的話說出來。當然,再完美的準備也會碰到不會的問題,那么如何應對呢?

1. 面試官提出的某個技術,你不會。

第一,絕對不能就說“不會”兩個字。太傻,太二,無法繼續(xù)交流,典型直男癌。

第二,態(tài)度上正視差距,如實回答?!斑@個技術我確實不會。之前的項目沒用到,只是用了xxx技術。面試完后,我也想學習一下”。

這樣,既說明了實際情況和自己的學習態(tài)度,也引向了你會的xxx技術,從而可能會小小的帶一波節(jié)奏。

2. 你對這個技術有一定的認知,但沒有把握。

對策:可以告訴面試官去年項目不太忙的時候,我學習過幾天,后來項目忙了就沒繼續(xù)看。然后,簡單說說對這個技術的理解。最后,問一下,我們公司是否在使用這個技術?我也正想撿起來再學習一下。

3. 面試官提出尖銳的問題,質疑你的簡歷或者技術能力。

面試官:“我在你的簡歷中沒有看到對我們有用的項目經(jīng)驗,你的技術能力也不符合我們的要求。”

面試者:“可能是我的經(jīng)歷還是太淺。對咱們公司這塊業(yè)務確實沒涉及過。您這塊還有什么技術要求,我可以推薦我的朋友過來試試”。

當碰到直接質疑的情況,面試成功的概率就非常低了。但也不能緊張,天下公司這么多,此處不留人,自有留我處。但要盡量多的跟面試官交流,獲得更多的行業(yè)知識,為下一次面試做準備。

4. 問到自己特別了解的技術

好吧,發(fā)揮吧,少年!還不眉飛色舞好好表現(xiàn)表現(xiàn)。

4.十大非技術面試問題及策略

社會競爭很殘酷、面試其實就是一場表演,企業(yè)永遠喜歡可以隨機應變、聰明的求職者。而不喜歡看似老實、實則笨拙不懂變通的求職者。所以,大家也要按套路出牌,出面試官喜歡的牌才能有更多的勝算。

面試官也知道求職者肯定是經(jīng)過精心準備的表演,但是仍然會認可。如果你連面試都懶得用心準備、你肯定也不會為了工作而用心。這是面試官內(nèi)在的邏輯。

1.自我介紹

這個問題是面試的時候最常被問到的問題。很多人回答這些問題會陷入一個誤區(qū),以為簡單介紹一下自己的名字、多少歲、哪里工作過、什么大學什么專業(yè)、有什么愛好就好了。如果這樣回答,你的自我介紹只能算是30分。

“面試官最想聽他想知道的內(nèi)容”,換位思考一下,假如你是面試官最想知道什么?顯然,就是”應聘者能不能勝任現(xiàn)在的崗位”。所以,應聘者應該更多的從這個角度出發(fā)思考問題。

所以,我們一般建議應聘者在自我介紹中側重于自己“實戰(zhàn)經(jīng)驗”的介紹。比如:在xxx公司從事過什么工作、做過什么項目、我為什么可以勝任貴公司的崗位。這些才是面試官最想聽到的內(nèi)容。

好的自我介紹應該分如下幾個部分:

a.實戰(zhàn)經(jīng)驗描述

實戰(zhàn)經(jīng)驗可以是在公司的工作經(jīng)驗、實習經(jīng)驗、甚至是參與大學老師的項目都可以。你需要告訴面試官實戰(zhàn)經(jīng)驗的公司名稱、時間多長、做了什么項目、有什么收獲。說到此處,你這個問題就可以拿到60分了。

b.為什么來應聘貴公司

根據(jù)自己網(wǎng)上查到的該公司的基本信息,可以說一下對公司的了解情況:看好公司未來發(fā)展前景、想進來以后多多學習。說到此處,你這個問題可以拿到80分。

c.我可以勝任貴公司這個崗位的原因

前面兩點說完后。結合自己的實戰(zhàn)經(jīng)歷和應聘公司的情況,告訴面試官我可以勝任目前的崗位、并且有決心干好。說到此處,你這個問題可以拿到100分。靜等面試官欣賞的、色瞇瞇的眼神吧。

2.你的優(yōu)點是什么?

優(yōu)缺點的描述是想看看應聘者對自己的了解程度。求職者關于優(yōu)點的描述一定要跟工作相關,并且有具體的案例描述你的優(yōu)點。

面試官通常喜歡具備如下優(yōu)點的程序猿:

1. 態(tài)度好

2. 技術實力強

3. 熱愛技術、學習能力強

大家描述的自己的優(yōu)點可以圍繞這三點展開??梢詤⒖迹骸豆鞠矚g什么樣的程序猿》。

3.你的缺點是什么?

求職者面對這個問題一定要把握一個原則:“缺點不能跟工作相關”。你不能說“我的缺點就是不喜歡技術、不喜歡加班”,那你完蛋了。缺點盡量不跟工作相關。比如:我覺得我的缺點是比較內(nèi)向、比較宅。周末我可以一個人在家悶頭鉆研技術、但是就是不想走出去跟別人去玩。這方面我覺得應該改一改。

缺點也不能說的太假。比如:我覺得我的缺點就是工作太拼命了,不注意身體。這么一說,面試官立馬就噴了。

4.對我們公司了解嗎?

我一直強調,面試前一定要查詢該公司相關的信息。所以,這個問題是必須要回答的。如果面試官沒問你這個問題。你也要在其他問題中說出你對他們公司的了解。

5.為什么從上一家公司離職?

公司都希望穩(wěn)定、有培養(yǎng)價值的員工。因此,都會特別關注你的離職理由。離職理由盡量正能量、客觀,絕對不能表示對上一家公司和上級的不滿。比如:我覺得上一個公司太摳了,加班還沒有加班費。好了,你這么負能量的回答,等于判了自己死刑。哪個公司都是摳門的、IT行業(yè)加班普遍是沒有加班費的。

6.如何看待加班?

面試官問這個問題顯然是他們公司經(jīng)常加班的。如果你確實接受不了也可以說出來。但是,對于剛入行的年輕人一定要了解,加班是非常正常的一件事。

回答這個問題,一定要客觀的說。你說你喜歡加班,這有點太扯了。你可以說:“項目緊的時候,加班也很正常?,F(xiàn)在行業(yè)情況就是這樣的,沒有問題。而且,我還年輕,能扛的住”。

7.如何看待出差?

出差在有的人眼里看是辛苦,在有的人眼里看是經(jīng)歷。有的年輕人就特喜歡出差,感覺可以去不同的城市、有不同的體驗。對于求職者來說,可以根據(jù)自己實際情況說出自己的真實感受。如果你確實無法接受、也可以明確拒絕。

8.你的職業(yè)規(guī)劃是什么?

這個問題是想了解求職者的規(guī)劃能力、對于自己是否有規(guī)劃?求職者可以根據(jù)自己的情況正常的說出自己的職業(yè)規(guī)劃,不能太低人一等、也不能好高騖遠。

一般較好的回答如下:

“這三年,我還是想腳踏實地的鉆研技術。希望通過三年的努力成為我們這個行業(yè)比較牛的人。三年后,我想學著做管理。再用兩年時間,一共五年,最終可以獨當一面”。

三年鉆研技術、顯得你很踏實。五年進入管理,這是一個有心人的正常的晉升流程。

9.你對跳槽怎么看?

公司非常不喜歡頻繁跳槽的人,所以你對這個問題的回答一定要謹慎對待。

經(jīng)典回答如下:

“現(xiàn)在這個行業(yè)大家都很浮躁,跳槽頻繁。但是,我并不喜歡頻繁的換環(huán)境。我想,我只要在一個公司扎扎實實做下去,不可能沒有機會。做好了,薪水不可能比跳槽的低”。

10.你還有什么問題要問我嗎?

這是通常面試要結束的時候的問題。求職者一定不能說:“我沒有問題”。一下子就把你搞得很low,最后一定要問一個問題問回去,即使面試官沒有這個問題。結束時,也一定要問個問題。

求職者也不能太過于急功近利的問:“今天我能面試上嗎?你能給我多少錢?”。雖然你很想知道,但這么一問,你的檔次立馬降低。通常的問題應該是跟工作相關。

技術人員可以這樣問:

1. 今天我們聊到的某個技術,我想回去好好研究一下,您這里有什么資料嗎?

2. XX新技術,您怎么看他的發(fā)展?我想趁這幾天時間寬裕,學習一下。

3. XXX技術,我感覺您好像有比較深的研究。我也想學學,您能推薦些資料嗎?

類似這樣的問題,可以讓你喜愛技術的特點,立馬暴露的一覽無余。本來面試70分的你,立刻加到80分。而你,只是問了個問題而已,回答的竟然是面試官。這么好的無本生意,不做是不是有點可惜?

5.面試后一定要總結

很多人面試后,就開始等公司的消息,焦躁不安,這絕對是錯誤的做法。面試后,大局已定,戰(zhàn)爭已經(jīng)打完了,還需要再糾結嗎?我們應該做的事是為下一場面試做準備,立刻做面試的總結,沒有總結就沒有進步。

必須總結如下內(nèi)容:

1. 列出問了哪些問題?

2. 列出自己回答較好的問題

3. 列出自己回答交差的問題,并進行改進

心態(tài)上不要等待,”謀事在人,成事在天”,成了好,不成也無所謂,就當面試失敗了。立刻,投入緊張的復習和下一次面試中。

第三篇:熱門專業(yè)學習之路

一:JAVA學習知識點明細以及配套視頻

這是JAVA工程師的完整學習路徑,我們也會公布大部分的學習視頻,這些視頻來自于我們的線下培訓課程,大多數(shù)直接錄制于課堂,歡迎大家下載或者在線觀看。

我們每個月都會更新相應的視頻,大家可以持續(xù)關注下載地址:

http://www.thehomosexualagenda.com/javashipin.html (java視頻的拼音,方便記憶)

1.JAVASE

首先要學JavaSE,這是毋庸置疑的。與此同時,和JavaSE的學習同步,建議大家研究一下數(shù)據(jù)結構與算法。

在JavaSE完成之后,可以試著完成一些小項目,同時關注一下設計模式的內(nèi)容,不必強求自己能夠完全掌握各種細節(jié),往前走吧。

掌握一種編程工具,比如說Eclipse。當然,工具掌握很簡單,大約只需要30分鐘。

建議大家讀北京尚學堂的《實戰(zhàn)JAVA程序設計》,同時可以配合《java300集視頻教程》(好吧,書是我寫的,視頻也是我錄的。個人認為還是很不錯的)。這里有JAVASE講解、有項目實戰(zhàn)、有數(shù)據(jù)結構、有算法、有JDK源碼解讀、有底層內(nèi)存分析、有設計模式,從一開始就植入了“高手思維和高手習慣”, 可以說是非常適合大學生和入門學習的人使用。

學習列表和學習說明如下:

  • 知識塊
  • 1.JAVA入門
  • 2.面向對象基礎
  • 3.飛機小項目(前兩個階段練習)
  • 4.面向對象深入
  • 5.常用類
  • 6.異常機制
  • 7.容器和數(shù)據(jù)結構
  • 8.IO流技術
  • 9.多線程
  • 10.網(wǎng)絡編程
  • 11.手寫服務器(java基礎集大成者)
  • 12.注解、反射機制、字節(jié)碼
  • 13.GOF23種設計模式
  • 14.正則表達式和文本操作
  • 15.JDBC數(shù)據(jù)庫操作(可在學完數(shù)據(jù)庫后學習)
  • 16.手寫SORM框架(學有余力的同學學習)

對于基礎的同學,建議大家學習一下預科階段(大約2小時)。對于整個行業(yè)、JAVA技術體系、就業(yè)流程、職業(yè)發(fā)展都會有個基本的認識和了解。

2.數(shù)據(jù)庫

數(shù)據(jù)庫是程序員必學的技術,大家可以選擇Oracle或者MySQL開始。學數(shù)據(jù)庫時,重點掌握SQL語言、熟悉各種查詢、數(shù)據(jù)庫設計范式。這也是以后工作中常用、面試和筆試中??嫉膬?nèi)容

再學習JDBC技術,這樣就可以用Java操作數(shù)據(jù)庫了。

大家可以按照如下順序學習:

  • 知識塊
  • 1.Oracle數(shù)據(jù)庫安裝和配置、客戶端使用
  • 2.Mysql數(shù)據(jù)庫的安裝和配置、客戶端使用
  • 3.SQL語言
  • 4.SQL語言強化(查詢深入)
  • 5.數(shù)據(jù)庫設計范式
  • 6.項目數(shù)據(jù)庫表設計核心
  • 7.PL/SQL

3.網(wǎng)頁設計和開發(fā)

互聯(lián)網(wǎng)時代,不學習網(wǎng)頁知識的程序員不是好司機。HTML、CSS、JavaScript、ajax,這些東西是做web項目必需內(nèi)容。當然,作為java程序員不需要學的很深入,熟悉即可。畢竟,前端工程師也是一個需要學習4-5個月的專門崗位。

4.Servlet/ JSP和企業(yè)級項目開發(fā)

Servlet/JSP是JAVAEE的核心內(nèi)容,必須作為重點掌握。學完基本知識后,做一些項目吧。比如:BBS、留言系統(tǒng)、學籍管理、商城、客戶關系管理等。剛開始找一些業(yè)務邏輯比較簡單的做一做。只有通過開發(fā)項目、調試項目才能真正的掌握學到的知識,真正的開啟自己的“JAVA騰飛之路”。

5.SSM框架(Spring、Spring MVC、Mybatis)

Spring 是java程序員必須掌握的一個框架,已經(jīng)形成了事實上的行業(yè)標準。 剛開始學習一下“IOC + AOP”。 依賴注入 + 面向切面,嗯,完善的旅程

Spring MVC是典型的MVC框架,企業(yè)非常流行。已經(jīng)超過struts2成為行業(yè)第一。

Mybatis是經(jīng)典的ORM框架,讓我們可以用面向對象的方式從容操作數(shù)據(jù)庫。已經(jīng)超過Hibernate成為第一的ORM框架。

學完三個經(jīng)典框架后,整合他們吧。然后,開始做一些商業(yè)項目加深自己的功力。這里可以找一些相對復雜的商業(yè)項目,加上復雜的業(yè)務邏輯。這樣,才能在你的簡歷中加入濃重的一筆。

6.各種JAVA新技術和大型項目的整合

其他一些工作中可能會用到的技術,也需要大家學習: Maven、Shiro、Nginx、Lucene、Solr、Redis、Dubbo、Zookeeper 等。

這些技術的學習,不需要特別深入,畢竟一個企業(yè)并不是使用所有的技術。但是,為了搭建“java技術體系”,必須學習這些內(nèi)容。這樣,你就形成了完完整整的“系統(tǒng)”。工作中,就可以從容應對各種各樣的問題。

記?。捍罱w系,要比鉆研某個知識點的細節(jié)重要的多。不要因為某個細節(jié)而耽誤搭建體系!不要因為看不懂某個單詞就停止閱讀整篇文章!

7.微服務架構

企業(yè)和服務提供商正在尋找更好的方法將應用程序部署在云環(huán)境中,微服務被認為是未來的方向。通過將應用和服務分解成更小的、松散耦合的組件,它們可以更加容易升級和擴展。

目前,越來越流行的微服務技術是需要大家重視的。SpringBoot、SpringData、Springcloud相關的技能已經(jīng)成為JAVA程序員必備的技能了。在后面的面試中也越來越重要,企業(yè)用的也越來越多。

8.一定要做一個大項目!

學了這么多,也做了一些小項目。最后,一定要做一個大的項目整合一下自己的所學。就像高考時候的綜合題一樣,這才是拉開差距的關鍵。

經(jīng)歷一個大項目的錘煉,就能“百煉成鋼”??梢詫讉€月所有的知識成體系的應用起來,這是成為“高手”的起步!也是你騰飛的起點。

二:JAVA基礎如何學習,才能又快又穩(wěn)?

學java編程,一般有兩種情況。一種是已經(jīng)掌握了其他語言,那學習java比較簡單,語言只是工具,編程能力才是根本。另一種是基礎,對于編程未入門或者懵懵懂懂。本文針對第二種情況。

作為初學者,在一開始學習就要培養(yǎng)良好的習慣和思維方式。因此,在入門的時候除了學著寫代碼,更重要的是這種習慣的培養(yǎng)。

企業(yè)要求:程序員既有實戰(zhàn)技能可以快速上手,也內(nèi)功扎實熟悉底層原理后勁十足。因此,在筆試和面試考察時候也是結合 “底層原理、數(shù)據(jù)結構、實戰(zhàn)應用、設計思維” 四方面進行考察。

因此,作為初學者,需要掌握下面五個核心:

1.JAVA本身內(nèi)容的應用。比如:一些類的字面用法。

2.需要掌握面向對象的思維模式。

3.掌握程序基于內(nèi)存底層的運行方式。這可以讓你對于編程理解的更加深刻。

4.掌握基本的數(shù)據(jù)結構和算法。

5.開始會寫項目,將學到的知識融會貫通。

所以我們可以根據(jù)上面的理論,開始JAVA基礎課程的學習了。

第一步:學習JAVA的開發(fā)環(huán)境配置、開發(fā)第一個Java程序。也建議大家開始使用eclipse等IDE,不必糾結是不是一定要從記事本開始。

第二步:學習數(shù)據(jù)類型、運算符、變量。這是編程的基礎,是程序的“磚塊”。這些內(nèi)容大多數(shù)編程語言都有,而且非常類似。

第三步:學習控制語句。這是編程的基礎,是程序的“混凝土”。有了控制語句+變量,理論上你就可以寫任意的程序了。因此,這是進入程序的門檻,需要大量的練習。

第四步:學習面向對象基礎。通過類、對象、包等基本概念講解。學習的時候,一定要在此處介入內(nèi)存分析,這樣可以對于對象等知識有非常深刻的理解。

第五步:繼續(xù)面向對象,主要包含三大特征:繼承、封裝,以及接口、抽象類、內(nèi)部類等概念。這些概念需要掌握。但是對于初學者來說,先熟悉語法。通過后面的學習再深入。不要期待初學時候就能深刻領會這些概念。

第六步:異常機制。Java程序的安全需要異常機制,這是必學內(nèi)容。當然,也非常簡單。學習過程中,先不要揪著什么自定義異常不放,學會基本用法即可。

第七步:數(shù)組和算法。學習數(shù)組時,注重結合循環(huán)管理數(shù)組。也要從底層內(nèi)存理解數(shù)組,這既是學數(shù)組也是復習面向對象;再結合一些算法,比如排序和搜索算法,既練習數(shù)組的用法,也學習了算法知識,為應對企業(yè)筆試和面試做好準備。

第八步:常用類和JDK源碼閱讀。學習常用類的用法:包裝類、字符串相關類、實踐類、Math類、File類等。學習過程中,只學怎么用這些API就及格了。要優(yōu)秀,要培養(yǎng)高手思維,一定要結合JDK源碼,一開始就培養(yǎng)閱讀源碼的習慣(雖然,可能大多數(shù)看不懂)。

第九步:容器和數(shù)據(jù)結構。容器有:List、Set、Map。學習這三種容器用法只需要一兩個小時。但,此時你要結合數(shù)據(jù)結構,再結合JDK源碼講解。這就是“高手習慣”,讓大家既學習容器,也學習了數(shù)據(jù)結構,打深了內(nèi)功,應對企業(yè)面試綽綽有余。

第十步:IO流技術。學會各種常用流即可,掌握一些工具類的用法,比如:Apache IOUtil這樣會讓你在以后使用時效率大增。

第十一步:多線程技術。這也是筆試和面試中常見的內(nèi)容。我們要學習多線程基本使用、生命周期、狀態(tài)轉化。如果學有余力,學習一下生產(chǎn)者消費者模式,讓你一開始就具備架構的思維;既然學,就按照“高標準”要求自己。

第十二步:網(wǎng)絡編程。工作中直接用到的不多,而且socket編程范式差不多,了解即可。畢竟直接讓你編寫基于socket底層代碼的情況比較少見。

第十三步:做個項目吧。 學了這么多,不做個東西怎么對得起自己?不管是小游戲項目也好,還是基于swing的項目,還是其他控制臺項目。

大家也可以下載我錄制的《尚學堂JAVA300集視頻教程》,已經(jīng)上百萬人在學習了?;旧县灤┝宋疑厦娴乃枷?,有知識、有底層、有數(shù)據(jù)結構、有算法、還有項目,從一開始就培養(yǎng)你的“高手思維”。

三:Python學習知識點以及配套視頻

這是Python工程師的完整學習路徑,我們會公布大部分的學習視頻,這些視頻來自于我們線下培訓課程,大多數(shù)直接錄制于課堂,歡迎大家免費下載或者在線觀看。

我們每個月都會更新相應的視頻,大家可以持續(xù)關注下載地址:

http://www.thehomosexualagenda.com/pythonshipin.html (python視頻的拼音)

1.Python基礎

“人生苦短,我用Python”, 隨著人工智能的發(fā)展,Python無疑是現(xiàn)在熱度最高的語言。從“小白”到成為一個合格的Python程序員首先要先邁過Python基礎這個門檻。

第一步:需要學習編程最基本的知識:變量、數(shù)據(jù)類型、控制語句、容器、函數(shù)和文件操作。同時,我們也深入數(shù)組結構的組織,打扎實大家的基本功。

第二步:學習python的面向對象機制,并學習一些常用的設計模式,這些都是成為Python編程高手必經(jīng)的磨練。并通過一個項目實際體會面向對象開發(fā)的優(yōu)勢。

第三步:還需要了解python是如何管理內(nèi)存的以及很多高級特性;學習內(nèi)存管理會讓我們更深入掌握python的運行機制; 很多函數(shù)式編程的特性,比如閉包、裝飾器和生成器,這些都是一些比較難掌握的概念,但面試和工作中會經(jīng)常遇到,所以大家也必須掌握。

第四步: 網(wǎng)絡編程中的高并發(fā)問題是大型互聯(lián)網(wǎng)企業(yè)必須面對的核心問題,解決高并發(fā)可以用多進程、多線程,python中還有協(xié)程。高并發(fā)和網(wǎng)絡是相關的,最后我們會利用學到的并發(fā)編程的知識來編寫不同的服務器模型。

上面四大塊學習完后,你已經(jīng)具備了比較強的python基礎,但是離工作要求還有差距。還需要繼續(xù)學習其他內(nèi)容。

2.Linux環(huán)境編程基礎

現(xiàn)在企業(yè)中不管是Web項目,還是數(shù)據(jù)庫,以及部署的爬蟲,更不要說大數(shù)據(jù)處理,甚至是人工智能,絕大多數(shù)都運行在Linux系統(tǒng)內(nèi),所以打好一個Linux基礎可謂是必備技能。

我們將學習如何在虛擬機中安裝Linux系統(tǒng),在Linux系統(tǒng)中安裝各種常用的軟件。學習如何配置Linux系統(tǒng)的網(wǎng)絡。學習使用Linux系統(tǒng)的常用基本命令。最后成為一個Linux系統(tǒng)的熟練管理員。

當然,我們的目標是會用Linux,熟悉相關常用命令即可。不需要掌握很多運維方面的知識,畢竟運維也是一個專業(yè)的崗位。

3.數(shù)據(jù)庫編程基礎

任何企業(yè)級項目都離不開數(shù)據(jù)庫,數(shù)據(jù)庫知識是程序員的必備技能。大家主要學習現(xiàn)在各大互聯(lián)網(wǎng)公司最常用的數(shù)據(jù)庫:Mysql

當然,不管學習哪一個數(shù)據(jù)庫。SQL語言是必須要深入掌握的,包含:數(shù)據(jù)庫設計思想、三大范式以及SQL語言實現(xiàn)增、刪、改、查最基本的操作。然后,也需要掌握Mysql一些基本的操作。

4.網(wǎng)頁編程基礎

目前軟件行業(yè)大多數(shù)的項目都是基于B/S架構,即在瀏覽器端實現(xiàn)效果展示。網(wǎng)頁編程也是每個程序員必懂的技能

本階段課程主要講解Web開發(fā)的三大基礎:HTML5、CSS3和JavaScript語言,并學習前端項目中經(jīng)常使用的Jquery和Ajax。

對于python程序員來說,不需要像前端程序員那樣精通這部分內(nèi)容,但是也需要做到熟悉。

5.Django Web開發(fā)框架

python也越來越多的被用在開發(fā)WEB應用上,這得益于Django這個強大的WEB框架。

學習Django的使用,要深入了解Django中MVT的開發(fā)模式,掌握模型的設計、視圖路由的設置和模板。并在最后帶領大家用Django開發(fā)一個博客項目,貫穿所有Django的常用特性。

python在WEB應用開發(fā)方向的需求在近段時間逐步增長, 薪水范圍在10k-25k之間,是大家學完python后的一個重要就業(yè)方向。

6.做一個項目

學完Django,必須做一個項目。將前面學習的Python基礎、數(shù)據(jù)庫、網(wǎng)頁開發(fā)等等技能整合起來,這樣才能學以致用。讓自己快速成長起來。

7.Tornado 異步編程框架

Tornado也是一個常用的python WEB開發(fā)框架,但Tornado更強大的地方是它的異步IO處理能力。在真正的項目中,經(jīng)常會混合使用Django和Torndao這兩大框架,充分利用Django的方便快捷和Tornado的高負載來解決項目中的實際問題。

8.Python爬蟲開發(fā)

由于近年大數(shù)據(jù)分析、人工智能都需要大量的數(shù)據(jù)做支持,所以爬蟲工程師的需求量也越來越多,有經(jīng)驗的爬蟲工程師經(jīng)常能拿到15k-25k的工資,有興趣的同學可以向這個方向發(fā)展。

首先,大家要理解網(wǎng)絡爬蟲編寫的基本套路,了解網(wǎng)絡爬蟲編寫的各種坑,能夠應對一些常用的反爬蟲技術,能夠應對動態(tài)網(wǎng)站爬取,能夠應對帶有驗證碼的網(wǎng)站。我們還要學習一些做爬蟲的常用框架:request,bs4,scrapy等。并利用scrapy結合redis實現(xiàn)分布式爬蟲的開發(fā)。

學習了這些技術,我們就可以在互聯(lián)網(wǎng)的汪洋大海中獲取到任何想要的數(shù)據(jù)。

四:人工智能學習知識點和配套視頻

人工智能成為了IT行業(yè)未來幾十年極其重要的學科。尚學堂·百戰(zhàn)程序員開設了完整的人工智能課程,由從歐美留學歸國的陳博老師領銜主講。

為了讓更多人受益, 我們會陸續(xù)公布大部分的學習視頻,這些視頻來自于我們線下培訓精品課程,大多數(shù)直接錄制于課堂,歡迎大家免費下載或者在線觀看。

我們每個月都會更新相應的視頻,大家可以關注下載地址(人工智能視頻的拼音):

http://www.thehomosexualagenda.com/rengongzhinengshipin.html

1. 機器學習

首先要學習機器學習算法,這是人工智能的核心,也是重中之重。

在學習機器學習算法理論同時,建議大家使用scikit-learn這個python機器學習的庫,試著完成一些小項目。同時關注一下能否各種算法結合使用來提高預測結果準確率。在學習的過程中不必強求自己能夠完全掌握各種算法推導,抓住重點理解算法,然后把算法用起來才是王道。

掌握一種編程工具,比如說PyCharm或者Jupyter Notebook,當然工具掌握不難,大約只需要30分鐘。

建議大家不要盲目的去看各種市面上的書籍和博客,有的對于大家來說過于理論,推導太多還有些跳步顯得過于深奧,有的又太浮于表面了不涉及算法原理細節(jié),還是以北京尚學堂的視頻作為學習材料,這里有算法的理解,算法的推導,算法的應用,非常適合大學生和入門學習的人使用,從一開始就即有算法的逐步深入,又有算法的實戰(zhàn)。給自己成為一個數(shù)據(jù)挖掘工程師,算法工程師打好基礎。

上面提到的機器學習算法譬如有監(jiān)督學習回歸算法中多元線性回歸,Lasso回歸,嶺回歸。分類算法中邏輯回歸,支持向量機,決策樹,隨機森林,GBDT,Adaboost,XGBOOST。無監(jiān)督學習聚類算法中K均值聚類,密度聚類,譜聚類。降維算法中PCA降維,F(xiàn)M因式分解,SVD奇異值分解。推薦算法中協(xié)調過濾,ALS交替最小二乘。還有機器學習里面的大招多層感知機,神經(jīng)網(wǎng)絡。關聯(lián)分析的算法Apriori,F(xiàn)P-Growth。最后研究樸素貝葉斯,貝葉斯網(wǎng)絡,隱含馬爾科夫模型,條件隨機場。

對于人工智能專業(yè)不了解的同學,建議大家學習一下預科階段,對于整個行業(yè),技術體系,就業(yè)方向,未來職業(yè)發(fā)展都會有個基本的認識和了解。

2.深度學習

深度學習是當今非常熱門的一個領域,是機器學習算法神經(jīng)網(wǎng)絡的延申,是把機器學習的擬人更加發(fā)揚光大的領域。深度學習工程師也是各大公司需要的人才。

學習深度學習可以從Google開源的tensorflow框架開始學習如何完成DNN(深度神經(jīng)網(wǎng)絡)的構建以及應用。然后還是使用tensorflow框架來學習如何完成CNN(卷積神經(jīng)網(wǎng)絡)的構建以及應用。最后來使用tensorflow框架來學習如何完成RNN(循環(huán)神經(jīng)網(wǎng)絡)的構建以及應用。

學習建議:大家在學習過程中可以試著利用構建的DNN來完成機器學習算法做的分類和回歸的案例,對比看看結果是否有提升,從而體會深度學習的奧妙。也可以利用CNN來完成一些圖像識別任務,和利用RNN來完成一些NLP(自然語言處理)任務。CNN和RNN不僅限于這兩個領域,但是目前來看它們在這兩個領域各有優(yōu)勢。

Tensorflow框架是深度學習框架之一,但不是唯一,Keras框架也是一個非常優(yōu)秀的框架,大家有興趣也可繼續(xù)學習Keras框架。代碼量會比TensorFlow更少一些,更適合去做一些實驗。

3.Python數(shù)據(jù)分析模塊

Python當今作為數(shù)據(jù)科學的第一語言,熟練掌握numpy、scipy、pandas、matplotlib等數(shù)據(jù)分析的模塊不光是作為數(shù)據(jù)分析師必須的,也是作為人工智能工程師所必須的, 如果大家認為自己的python語言掌握的不夠熟練,可以從學習這些基礎的模塊開始,來鍛煉自己。因為scikit-learn機器學習算法庫是基于numpy、scipy、matplotlib開發(fā)的,所以大家掌握好了這些基礎庫,對于分析別人封裝的算法源代碼,甚至日后自己開發(fā)一些算法也有了可能性。

學習建議:在學習這些數(shù)據(jù)分析模塊的同時,可以補補python語言的基礎語法,重復一遍基礎語法即可,不要跑偏到python其他比如什么web開發(fā),爬蟲等領域里面去。

4.Spark MLlib機器學習庫

如果說當今有什么是算法工程師的加分項,那么分布式計算框架Spark中算法庫MLlib就是一個,如果想掌握Spark MLlib,首先需要會使用spark計算框架,建議大家還是使用python語言通過pyspark來學習,在掌握了前面的機器學習部分后,這里再來學習里面的算法使用將變得異常容易。

學習建議:大家要抓住重點,千萬不要鉆到集群搭建里面,甚至是大數(shù)據(jù)各種框架里面,因為對于我們來說,spark計算框架只是一個工具,幫助我們來更好的做數(shù)據(jù)預處理,和幫助我們將算法使用分布式集群來完成海量數(shù)據(jù)場景下結果的計算。在公司里面,有運維的人員管理集群,在一些大公司,有專門給算法工程師配備數(shù)據(jù)預處理的工程師。

5.做一個人工智能項目

學了這么多,也做了一些小項目,最后一定要做一些個大項目整合一下自己的知識。做一些個人工智能領域的譬如醫(yī)療圖像識別、人臉識別、自動聊天機器人、推薦系統(tǒng)、用戶畫像等的大項目才是企業(yè)很需要的經(jīng)驗??梢詫⒗碚摻Y合實際的運用也是成為高手的必經(jīng)之路,也是在企業(yè)工作所需要的能力。

6.數(shù)學

數(shù)學是一個誤區(qū),很多人說自己的數(shù)學不夠好,是不是做不了算法工程師?面對這樣的問題,公司里面的算法工程師誰又敢說自己的數(shù)學真的好?數(shù)學是在學習機器學習階段算法推導用的到的,但是這里的推導你又不需要非要一步步扣數(shù)學計算過程,舉個例子,2+2=4,那么數(shù)據(jù)基礎是1+1=2,但是咱們需要證明1+1=2嗎?不需要,對吧,所以在機器學習階段算法推導這里更重要的還是理解算法證明的思想,能夠把講的算法推導理清楚足夠了,而這在講的過程中如何有好的引導,又何須非自己沒頭緒的補數(shù)學然后走那個彎路呢?

學習建議:很多數(shù)學符號只是一種表達而已,在學習過程中稍微補一下即可,不需要花大量時間前期準備數(shù)學知識,最重要的是,企業(yè)中人工智能工程師沒人天天抱著數(shù)學公式推導。所以同學們在大學期間數(shù)學學的不錯的同學恭喜你,你在機器學習算法學習時會稍微輕松一些,相反,在大學期間數(shù)學學的不行的同學也恭喜你,因為數(shù)學不是決定能否成為一個企業(yè)所需算法工程師的鴻溝!

五:H5前端和移動APP開發(fā)知識點和配套視頻

隨著互聯(lián)網(wǎng)、移動互聯(lián)網(wǎng)的發(fā)展,HTML5成為了客戶端軟件開發(fā)的主流技術,HTML5實際上是由:HTML5語言、CSS3、JAVASCRIPT語言組成。

尚學堂的HTML5前端課程由國內(nèi)知名技術專家劉興宇老師領銜,已經(jīng)培訓就業(yè)數(shù)千人,取得了非常好的社會影響。

為了讓更多人受益, 我們會陸續(xù)公布大部分的學習視頻,這些視頻來自于我們線下培訓精品課程,大多數(shù)直接錄制于課堂,歡迎大家免費下載或者在線觀看。

我們每個月都會更新相應的視頻,大家可以持續(xù)關注下載地址(前端視頻的拼音):

http://www.thehomosexualagenda.com/qianduanshipin.html

1.WEB前端快速入門

在本階段,我們需要掌握HTML與CSS基礎,當然,也包含H5和C3的新特性。這個部分內(nèi)容非常簡單,而且非常容易掌握。相信你也更愿意學習這個部分,畢竟他可以讓你最直觀的感受到前端的魅力。為了鍛煉大家寫代碼,可以根據(jù)你喜歡的站點去實現(xiàn)效果。

這一階段是非常重要的基礎階段,所謂基礎就是可能這個階段我們的學習的內(nèi)容,可以讓我們開發(fā)出來絢麗網(wǎng)站站點,但是功能豐富卻暫時做不到。 為了完成更絢麗的站點,我們需要掌握常見特效的實現(xiàn),利用css3和h5的新特性實現(xiàn)動畫,布局,雪碧圖,滑動門,tab切換等特效。并且掌握基礎的站點優(yōu)化內(nèi)容。例如sprite等。雖然我們還不能完成更多交互內(nèi)容,但是我們會學習到很多的知識模型和理論,而這些知識模型和理論是我們后期工作和學習的基石。扎實的基礎有了,我們才能走的更穩(wěn)更快。

注:本階段不涉及到編程,主要是熟悉HTML5各種標簽用法、CSS3各種屬性的用法。

2.JavaScript基礎與深入解析

JavaScript語言非常重要,可以說學習前端本質就是學習“JavaScript”編程。后面學的很多高級技術,全部都是基于JavaScript的。

JavaScript語言可以讓網(wǎng)頁元素具備動態(tài)效果,讓體驗度更加流暢。這在目前流行的B/S架構體系下,是極端重要的事情。這也是為什么前端工程師大行其道,被廣泛需求的根本原因。

在本階段中,我們主要學習基礎JavaScript語法與深入解析JavaScript,包含DOM操作同時也涵蓋了面向對象和設計模式,課程也涵蓋了兼容性處理和數(shù)據(jù)解析。希望大家在本階段可以熟練掌握這些知識點。

3.jQuery應用與項目開發(fā)

jQuery是一個快速、簡潔的JavaScript框架,jQuery設計的宗旨是“write Less,Do More”,即倡導寫更少的代碼,做更多的事情。它封裝JavaScript常用的功能代碼,提供一種簡便的JavaScript設計模式,優(yōu)化HTML文檔操作、事件處理、動畫設計和Ajax交互。在本階段,我們注重講解如何更好的應用jQuery以及他的設計方式,同時也包含jQuery擴展內(nèi)容。

4.PHP、數(shù)據(jù)庫編程與設計

后端服務器工程師需要了解前端的基本知識,同樣,前端工程師也必須了解服務器端編程的基本內(nèi)容。我們可以不精通,但必須知道整體的流程。

作為一名前端開發(fā)工程師,會一門后端語言是必然的。在我們的課程中,為您選擇的是PHP,因為PHP環(huán)境搭建簡單,語言與JavaScript相似性比較大,并且容易上手,連接數(shù)據(jù)庫也非常方便。希望本階段的內(nèi)容能幫助你快速掌握前后端交互數(shù)據(jù)。

通過學習PHP,前端工程師也能稱為“全棧工程師”。既能做前端開發(fā),也能做后端服務器開發(fā)。

5. Http服務于Ajax編程

Ajax真的是一個非常古老的技術了,但是到現(xiàn)在為止,這門技術仍然被大量使用,可以看出來,他是多么的優(yōu)秀。在本階段,我們將帶你了解Ajax,并且掌握它的應用。也包含了解Http相關的知識。對于站點來說,除了頁面效果能看到的就是數(shù)據(jù)了。所以,數(shù)據(jù)的獲取合理適配尤為重要。與Ajax相關的也包含跨域處理,希望大家可以掌握這些核心知識點。

6. 做一個階段項目

本階段為純項目實戰(zhàn),可以將前面學到的知識融會貫通,不實戰(zhàn)就相當于沒有學習;主要練習網(wǎng)絡請求、站點布局、網(wǎng)站優(yōu)化等內(nèi)容,同時我們需要對項目有一定的而了解。 所以,在老師的帶領下,可以更快的了解項目如何搭建,如何更優(yōu)雅的實現(xiàn)代碼。老師會將整個項目的開發(fā)流程完整的羅列出來。本階段也鍛煉BootStrap的應用,也包含一些常用的第三方插件。在實戰(zhàn)中展示具體應用。

7. H5新特性與移動端開發(fā)

H5新特性在現(xiàn)在來說已經(jīng)不再是新內(nèi)容了,項目中隨處可見,畢竟移動端不會存在兼容性問題,而且這些新特性在移動端的體現(xiàn)也是非常好的。例如定位,語義化等。利用Canvas實現(xiàn)更多的效果等。

在移動端中,我們主要注重移動端布局和資源加載,布局方向,我們主要講解百分比、flex、REM、柵格系統(tǒng)來實現(xiàn)。資源加載采用(SPA)單頁面加載,也是目前比較火的形式。在頁面跳轉時可以非常節(jié)省資源?;旌祥_發(fā)也同樣是移動端的一大特點,在我們的課程中都會詳細講解。

8.高級框架

隨著項目的需求越來越多。傳統(tǒng)的開發(fā)方式已經(jīng)不能滿足我們的需求了,所以我們需要更多的支持。在本階段中,我們講解模塊化,將程序分解為模塊化開發(fā)。我們需要Nodejs做支撐,無論是作為構建工具中的服務器存在,還是為我們提供數(shù)據(jù)模擬測試,都是必不可少的。

隨著ES5開發(fā)者體會在開發(fā)中的難言之隱,ES6的到來解決了各種頭痛的問題。也是我們必須要掌握的一個重點。還有更多,例如多人協(xié)同開發(fā)(git或者svn),利用Less和Sass完成更好的CSS的編寫

接下來我們介紹一下目前前端三大框架:

Angular:Angular是一個開發(fā)平臺,他能幫我們輕松的構建Web應用,我們將在這部分課程中講解Angular的聲明式模板,依賴注入,端到端的工具和一些最佳實踐于一身。我們通過完整項目配合實例講解課程,以便于大家更容易去理解Angular的應用。

React:作為前端三大框架之一,React擁有聲明式和組件化兩大特點,React可以輕松創(chuàng)建交互式用戶界面。為應用程序中的每個狀態(tài)設計簡單的視圖,當數(shù)據(jù)更改時,React將高效地更新和正確的渲染組件。聲明式視圖使您的代碼更具可預測性,更易于調試。創(chuàng)建好擁有各自State(狀態(tài)) 的組件,再將其組合構成更加復雜的UI界面。由于組件邏輯是用JavaScript而不是模板編寫的,因此可以通過應用程序輕松傳遞豐富的數(shù)據(jù),并將State(狀態(tài)) 保留在DOM之外。我們將會從零開發(fā)講解,講解過程中個,我們也帶領大家從環(huán)境的構建開始學習,這樣可以讓你更好更快的對接企業(yè)級項目的環(huán)境架構。

VUE:在借鑒了Angular和React兩個優(yōu)秀框架的基礎上,Vue無疑是非常受歡迎的,它使用簡單,強大的生態(tài)系統(tǒng),高效的運行速度也是我們在開發(fā)中的選擇之一。Vue是一套用于構建用戶界面的漸進式框架。與其它大型框架不同的是,Vue被設計為可以自底向上逐層應用。Vue的核心庫只關注視圖層,不僅易于上手,還便于與第三方庫或既有項目整合。

另一方面,當與現(xiàn)代化的工具鏈以及各種支持類庫結合使用時,Vue也完全能夠為復雜的單頁應用提供驅動。在學習真?zhèn)€Vue的過程中,我們會通過兩個企業(yè)級項目來講解他的使用,以便于大家更好的掌握使用Vue熟練開發(fā)。

9.微信小程序

作為微信推出的一種新的項目展示形式,微信小程序必然是非常受到人們重視的,而且,目前為止,大部分推廣為主的公司都存在了微信小程序,也催生了一個崗位,微信小程序開發(fā)工程師??上攵?,微信小程序是非常火的。我們課程是在小程序正式發(fā)布后就已經(jīng)加入到課程了,通過近1年的實戰(zhàn)演練,在我們的課程中,通過項目直接入手,在項目中掌握API知識點的應用。這樣可以更快適應項目開發(fā)。

六:大數(shù)據(jù)和云計算學習知識點和配套視頻

IT時代,最重要的特征就是:“數(shù)據(jù)越來越多”。每天產(chǎn)生的數(shù)據(jù)源源不斷,成為了現(xiàn)代社會的“石油”。大數(shù)據(jù)的存儲、分析都成了非常重要的技術。

尚學堂從2014年國內(nèi)第一批開設大數(shù)據(jù)專業(yè),由國內(nèi)知名專家夏中云、肖斌、周智雷創(chuàng)建。我們培訓的大數(shù)據(jù)學員絕大多數(shù)成為了目前各大數(shù)據(jù)企業(yè)的骨干,深刻的影響了國內(nèi)大數(shù)據(jù)行業(yè)。

為了讓更多人受益, 我們會陸續(xù)公布大部分的大數(shù)據(jù)課程視頻,這些視頻來自于我們線下培訓精品課程,大多數(shù)直接錄制于課堂,歡迎大家免費下載或者在線觀看。

我們每個月都會更新相應的視頻,大家可以持續(xù)關注下載地址(大數(shù)據(jù)視頻的拼音):

http://www.thehomosexualagenda.com/dashujushipin.html

1.大數(shù)據(jù)學習之前“必看”

大數(shù)據(jù)是現(xiàn)在這個時代非常流行的概念,并且隨著人工智能的崛起,大數(shù)據(jù)也越來越有價值。人工智能算法其實在三十年前就有了,但是沒有用。原因是:第一、計算機不夠快;第二、數(shù)據(jù)量不夠大,訓練出來的模型太差。

IT時代,其實也是大數(shù)據(jù)時代。我們產(chǎn)生的數(shù)據(jù)越來越多,這些數(shù)據(jù)反過來就像“石油”一樣,為我們提供了進一步的價值。人工智能等算法就像“吞食數(shù)據(jù)的怪獸”,數(shù)據(jù)越多人工智能也越強大。

因此,在學習大數(shù)據(jù)之前,一定要先搞明白幾個問題:

1.什么大數(shù)據(jù)?

2.什么是云計算?

3.什么是數(shù)據(jù)挖掘?

4.什么是人工智能?

5.什么條件才能學習大數(shù)據(jù)?

了解之后你才能有的放矢,以及想一想自己是否適合學習。同時,也至少不會被人騙,因為了解這些問題之后,一看課程大綱里面有“遙控機器人技術,android技術”等。這些技術肯定和大數(shù)據(jù)是沒有關系的。

由于篇幅的問題,這個幾個問題的解答已經(jīng)錄制成一套視頻。視頻列表如下:

  • 知識塊
  • 1、什么大數(shù)據(jù)?
  • 2、什么是人工智能?
  • 3、什么是機器學習和深度學習?
  • 4、數(shù)據(jù)挖掘到底挖什么?
  • 5、大數(shù)據(jù)技術體系介紹
  • 6、基礎可以學習大數(shù)據(jù)嗎?
  • 7、大數(shù)據(jù)工作職務多嗎?薪水怎么樣?
  • 8、大數(shù)據(jù)簡歷怎么寫?
  • 9、大數(shù)據(jù)的學習方法
  • 10、哪些技術才是大數(shù)據(jù)的重點內(nèi)容?

建議:在學習大數(shù)據(jù)之前最好花2個小時,認真看一下,所有人都能看懂。就算不想學習大數(shù)據(jù),也可以增加大家的知識面。

2.Hadoop框架

Hadoop的框架最核心的設計就是:HDFS和MapReduce。HDFS為海量的數(shù)據(jù)提供了存儲,則MapReduce為海量的數(shù)據(jù)提供了計算。

HDFS是一個高度容錯性的系統(tǒng),適合部署在廉價的機器上。HDFS能提供高吞吐量的數(shù)據(jù)訪問,非常適合大規(guī)模數(shù)據(jù)集上的程序計算。HDFS技術是整個大數(shù)據(jù)的“入門”。只要從事大數(shù)據(jù)方面工作的程序員,不管你后面用什么樣的分析技術都必須要學會HDFS。

MapReduce是用于大規(guī)模數(shù)據(jù)集(大于1TB)的并行運算。它極大地方便了編程人員在不會分布式并行編程的情況下,將自己的程序運行在分布式系統(tǒng)上。因為只有分布式計算才能解決“海量數(shù)據(jù)”的分析問題。

學好HDFS,就能知道為什么它可以存儲海量數(shù)據(jù),知道“百度網(wǎng)盤”本身是什么?能否自己也能實現(xiàn)一個網(wǎng)盤。讓大家一開始就進入大數(shù)據(jù)實戰(zhàn)狀態(tài)。

Hadoop是大數(shù)據(jù)中必學的一個技術,也是大數(shù)據(jù)職位要求必有的一個技術。Hadoop也是后面其他技術的基礎,學好了Hadoop才能更好的學好Hive,Hbase,Spark,Storm等。

3.數(shù)據(jù)倉庫技術

大數(shù)據(jù)的數(shù)據(jù)倉庫技術主要包括:Hive,Hbase,Sqoop,F(xiàn)lume等。其中Hive在企業(yè)中使用最為廣泛。對于同學們來說,Hive最容易入門,因為不用寫代碼;只需要有sql基礎就能很好的學習Hive。

Hbase是一個分布式、列式數(shù)據(jù)庫。它解決的問題是:在海量數(shù)據(jù)的情況下還能做到秒級的增、刪、改、查操作。

4.Spark內(nèi)存計算框架

Spark是當前最為流行的基于內(nèi)存計算的分布式框架,在Spark的生態(tài)圈中的框架幾乎能夠解決所有的大數(shù)據(jù)的應用場景,如果基于內(nèi)存計算,計算速度比Hadoop生態(tài)圈中的MapReduce快100倍,如果是基于磁盤的計算,那么速度快10倍以上,所以Spark是當前大數(shù)據(jù)開發(fā)人員必備的。

Spark是有Scala語言開發(fā)的,包括:Spark-Core(離線計算)、Spark-SQL、Spark-Streaming(流式計算)、Spark-MLlib(機器學習)。

Spark是整個大數(shù)據(jù)技術中的“重中之重”。因為在面試過程中,筆試題和面試題有60%的可能性會涉及到Spark知識點。所以,Spark的學習要求是:了解Spark源碼,能夠優(yōu)化Spark、能夠用Java,Scala,Python三種計算機語言開發(fā)任何的Spark程序。

5.機器學習和數(shù)據(jù)挖掘

機器學習(Machine Learning, ML)是一門多領域交叉學科,涉及概率論、統(tǒng)計學、逼近論、凸分析、算法復雜度理論等多門學科。專門研究計算機怎樣模擬或實現(xiàn)人類的學習行為,以獲取新的知識或技能,重新組織已有的知識結構使之不斷改善自身的性能。它是人工智能的核心,是使計算機具有智能的根本途徑,其應用遍及人工智能的各個領域。

在公司項目應用過程中,重點強調的分布式的機器學習,因為基于海量的數(shù)據(jù)必須采用分布式的機器學習庫。否則根本就是“扯淡”。所以根據(jù)企業(yè)的需求,同學們也要分辨出哪些是分布式的機器學習庫,比如:M ahout,Spark-Mllib等。

6.Storm流式計算框架

目前有兩種比較流行的計算方式:離線計算和流式計算。

流計算方式:它可以很好地對大規(guī)模流動數(shù)據(jù)在不斷變化的運動過程中實時地進行分析,捕捉到可能有用的信息,并把結果發(fā)送到下一計算節(jié)點。

Storm是流式計算中的技術之一,Storm集群由一個主節(jié)點和多個工作節(jié)點組成。主節(jié)點運行了一個名為“Nimbus”的守護進程,用于分配代碼、布置任務及故障檢測。每個工作節(jié) 點都運行了一個名為“Supervisor”的守護進程,用于監(jiān)聽工作,開始并終止工作進程。Nimbus和Supervisor都能快速失敗,而且是無 狀態(tài)的,這樣一來它們就變得十分健壯。

一般來說只要用到了流式計算,還得用到Kafka。所以大數(shù)據(jù)里面需要掌握一套Kafka+Storm流式解決方案。

7.云計算之Openstack和docker

云計算從服務角度分為三層:

同學們需要重點掌握:Iaas層的云計算技術。目前比較流行的云平臺都是基于Iaas層的云計算,包括:阿里云(https://www.aliyun.com/)、騰訊云、百度云等。 而Openstack 和Docker就是屬于Iaas層的云計算技術。

Openstack和Docker在找工作的過程中,對應的職位比較少,但是有很好的發(fā)展前景。建議大家先在入個門。等工作之后或者有剩余的時間再深入研究。

8.做一個大數(shù)據(jù)項目

“實戰(zhàn)學習,最重要的就是參與項目”。大數(shù)據(jù)的技術學完之后,需要參與一個企業(yè)級的大項目,這樣才能真正的出山,拿到高薪、獲得更多的好機會。

七:區(qū)塊鏈學習知識點和配套視頻

區(qū)塊鏈已經(jīng)成為近年非常熱門的技術,并且正在飛速的發(fā)展。各大公司都成立了區(qū)塊鏈相關部門, 大量職位空缺等待區(qū)塊鏈專業(yè)人才加入,而目前區(qū)塊鏈專業(yè)人才少之又少,所以抓住機會就是成功了一大步。

區(qū)塊鏈中涉及的面比較廣,技術又相對”底層”,學好區(qū)塊鏈后我們可以很快學習其他方向,因為區(qū)塊鏈可以給學習者打下很牢固的基礎。

在尚學堂的區(qū)塊鏈課程中,囊括了目前企業(yè)絕大多數(shù)區(qū)塊鏈相關知識,又配套大量企業(yè)級項目,可以說是廣且深。

區(qū)塊鏈課程適用于各種人群,即使是行業(yè)小白,也可以在由淺入深的課程中逐漸學會區(qū)塊鏈。技術不是遙不可及的,都是扎扎實實學出來的。不要對某個技術有過度崇拜的沖動,一層窗戶紙而已,大膽捅破它。

我們將公布區(qū)塊鏈課程中的大部分視頻,大家可以通過下面網(wǎng)址免費下載或者在線觀看:

http://www.thehomosexualagenda.com/qukuanlianshipin.html (區(qū)塊鏈視頻的拼音)

1.區(qū)塊鏈行業(yè)介紹

本階段主要是為了讓學習者對區(qū)塊鏈有總體的認識,從宏觀角度闡述了區(qū)塊鏈相關內(nèi)容.本階段是一個純理論階段,不需要編程, 所以學習本階段重點在聽而不是寫。區(qū)塊鏈也將作為像人工智能那樣的一個基礎技術,改造現(xiàn)在的很多行業(yè)。讓很多行業(yè)去中心化,極大的提升行業(yè)效率。

2.Golang從入門到高級

本階段主要是為了讓學習者對區(qū)塊鏈有總體的認識,從宏觀角度闡述了區(qū)塊鏈相關內(nèi)容.本階段是一個純理論階段,不需要編程, 所以學習本階段重點在聽而不是寫。區(qū)塊鏈也將作為像人工智能那樣的一個基礎技術,改造現(xiàn)在的很多行業(yè)。讓很多行業(yè)去中心化,極大的提升行業(yè)效率

3.數(shù)據(jù)庫操作和Golang Web

Go語言可以當作服務端語言,使用Go語言可以完成Web項目開發(fā)。本階段需要Go語言的數(shù)據(jù)庫操作和網(wǎng)絡操作,其中數(shù)據(jù)庫操作是以MySQL舉例。學習完本階段后就可以使用Go開發(fā)項目了。如果以后是找Go語言相關工作,這階段也很重要。

4. Golang 實戰(zhàn)項目

在學習完前幾個階段后,本階段是要對前面幾個階段的實際應用。單獨學習每個語法可能都不難,但是要把學習的內(nèi)容融入到實際項目中就需要一個轉化的過程。這個階段重點在敲代碼, 一定要按照視頻中順序把每個功能都認真完成。

密碼學

密碼學是區(qū)塊鏈中幾個核心部分之一,是實現(xiàn)數(shù)據(jù)按照的重要手段。在本階段中介紹了大部分區(qū)塊鏈成名項目中應用頻率比較高的密碼學知識。每個密碼學都有單獨的講解,這部分要重點學習,是后面學習比特幣、以太坊、超級賬本源碼的基礎。

6. 共識算法

所謂“共識機制”,是通過特殊節(jié)點的投票,在很短的時間內(nèi)完成對交易的驗證和確認;對一筆交易,如果利益不相干的若干個節(jié)點能夠達成共識,我們就可以認為全網(wǎng)對此也能夠達成共識。再通俗一點來講,如果中國一名微博大V、美國一名虛擬幣玩家、一名非洲留學生和一名歐洲旅行者互不相識,但他們都一致認為你是個好人,那么基本上就可以斷定你這人還不壞。

區(qū)塊鏈作為一種按時間順序存儲數(shù)據(jù)的數(shù)據(jù)結構,可支持不同的共識機制。共識機制是區(qū)塊鏈技術的重要組件。

共識算法和密碼學都是區(qū)塊鏈核心部分, 學習完共識后就可以準備開始學習具體的區(qū)塊鏈項目了。

7. Solidity

Solidity是以太坊中專門描述智能合約的語言,學習Solidity的同時也在講述什么是智能合約。 學習完Solidity就可以學習以太坊相關內(nèi)容.所以本段內(nèi)容是專門給以太坊打基礎。

8. 以太坊原理

以太坊和比特幣都是學習區(qū)塊鏈中經(jīng)典的例子。 這個階段,包含了以太坊原理架構流程和一些區(qū)塊鏈中專業(yè)概念。這一階段講解比較全面,重點學習后就可以對區(qū)塊鏈有了較深的認識。

9.以太坊客戶端

本階段繼續(xù)學習以太坊,主要講解以太坊客戶端配置和原理。為后面講解以太坊DApp打基礎。主要講解:geth客戶端配置和運行、geth源代碼解讀。

10.去中心換拍賣系統(tǒng)DApp

本階段是對以太坊的鞏固學習,屬于一個編碼階段,所有編碼階段的重點都是在動手,實戰(zhàn)。所有內(nèi)容都編寫完成后就完成了對區(qū)塊第一次完整認識。

最終我們可以利用:區(qū)塊鏈、星際文件系統(tǒng)、Node.js、MongoDB構建一個“去中心化”革命性的電商平臺。

11.超級賬本和DApp實戰(zhàn)

超級賬本是一個大體系。 在這個階段中會使用Linux的一些命令和使用,同時這一階段中使用Go作為源碼語言。學習完這個階段后會更加加深對區(qū)塊鏈的認識。

12.C++編程快速入門

C++語言是比特幣項目的編寫語言, 學習C++主要目的是為了讀懂比特幣中關鍵代碼。所以這階段不是非常詳細的把C++所有知識點都講解到,只是一個快速入門,能夠讀懂比特幣的核心代碼即可。

大家沒有必要對C++做過分深入的研究,畢竟應用范圍越來越小了。

13.比特幣

比特幣作為區(qū)塊鏈的起源,也是區(qū)塊鏈行業(yè)中的標桿。學習區(qū)塊鏈,也一定要學習比特幣相關內(nèi)容。 之前已經(jīng)學習了區(qū)塊鏈的兩大部分,這階段學習起來將會比較輕松。

14.EOS

除了幾個經(jīng)典的比特幣項目以外,在本套課程引入了其他的項目講解,目前講解的是EOS,在以后的課程中還會陸續(xù)引入小蟻、星云、量子等其他項目。

EOS:可以理解為Enterprise Operation System,即為商用分布式應用設計的一款區(qū)塊鏈操作系統(tǒng)。EOS是引入的一種新的區(qū)塊鏈架構,旨在實現(xiàn)分布式應用的性能擴展。注意,它并不是像比特幣和以太坊那樣的貨幣,而是基于EOS軟件項目之上發(fā)布的代幣,被稱為區(qū)塊鏈3.0。

EOS有點類似于微軟的windows平臺,通過創(chuàng)建一個對開發(fā)者友好的區(qū)塊鏈底層平臺,支持多個應用同時運行,為開發(fā)dAPP提供底層的模板。

當你擁有了EOS的話,就相當于擁有了計算機資源,隨著DAPP的開發(fā),你可以將手里的EOS租賃給別人使用,單從這一點來說EOS也具有廣泛的價值。簡單來說,就是你擁有了EOS,就相當于擁有了一套房租給別人收房租,或者說擁有了一塊地租給別人建房。

八:100套畢業(yè)設計和課程設計項目案例和配套視頻

本套100個完整項目源碼是由【北京尚學堂·百戰(zhàn)程序員】學員做畢設時提供,老師提供了相應的畢設輔導服務。

一共分為5季,每季約20套項目,希望大家持續(xù)關注。

很多大四同學苦于沒有參考的畢設資料,或者下載的資料不全、代碼有問題、數(shù)據(jù)有問題等等,造成畢設出現(xiàn)問題影響大學畢業(yè)?,F(xiàn)在,我們提供了經(jīng)過審核的100個項目源碼和對應的輔導視頻,讓大家在短時間內(nèi)可以完成自己的畢業(yè)設計。

同時,我們也錄制了更多的項目視頻,2018年計劃100套,后續(xù)將會有更多。大家可以到www.itbaizhan.cn在線觀看和學習,也可以到北京尚學堂官網(wǎng)免費下載。

關于版權的聲明,源碼由北京尚學堂學員做項目時提供,非北京尚學堂原創(chuàng)。北京尚學堂講師只提供了項目的部署和使用說明的視頻,如果侵犯了原作者的版權,請聯(lián)系我們。

未來,我們將發(fā)布H5前端畢設項目、Python畢設項目、大數(shù)據(jù)畢設項目、人工智能畢設項目等。讓我們的大學生朋友再也不用為畢設發(fā)愁。請大家隨時關注尚學堂bjsxt.com或者百戰(zhàn)程序員(itbaizhan.cn)的官網(wǎng)。

大家可以在:

http://www.thehomosexualagenda.com/biyeshejishipin.html (畢業(yè)視頻視頻的拼音)

1.關于各種開發(fā)軟件的使用說明和配套視頻

由于很多大學生對于開發(fā)軟件不是很熟悉,我們將常見的開發(fā)軟件使用方式集中進行了錄制。大家項目中用到哪些軟件,自行對比學習即可。

為了方便大家的學習,我們提供了常用開發(fā)軟件的安裝包,大家可以根據(jù)需要直接從網(wǎng)盤下載:

軟件的使用方式都特別簡單,大家不要有畏懼心理,這里講解了軟件在開發(fā)中最常用的使用方式。包含了常見數(shù)據(jù)庫軟件的使用(oracle、mysql、sqlserver)、數(shù)據(jù)庫客戶端操作軟件、eclipse、Myeclipse、Tomcat服務器等的使用。包含如下視頻:

1.Eclipse的使用1_開發(fā)環(huán)境使用原因

2.Eclipse的使用2_下載樓基本選擇和使用

3.Eclipse的使用3_建立JAVA項目_項目的結構說明

4.Eclipse的使用4_開發(fā)和運行JAVA程序

5.Eclipse(JEE)的使用_Tomcat整合_項目部署

6.JDK安裝1_下載和安裝_JDK目錄介紹

7.JDK安裝2_環(huán)境變量PATH設置_classpath問題

8.JDK安裝3_控制臺測試JDK安裝和配置成功

9.Myeclipse2014的安裝和使用_web項目創(chuàng)建和發(fā)布

10.Myeclipse和Tomcat整合_web項目部署

11.Mysql數(shù)據(jù)庫1_安裝和配置_命令行簡單使用

12.Mysql數(shù)據(jù)庫2_navicat客戶端軟件的使用_加載SQL文件到庫

13.Oracle數(shù)據(jù)庫1_安裝

14.Oracle數(shù)據(jù)庫2_客戶端plsql安裝并連接

15.SqlServer數(shù)據(jù)庫1_安裝

16.SqlServer數(shù)據(jù)庫2_連接并回復數(shù)據(jù)庫

17.SqlServer數(shù)據(jù)庫3_客戶端操作

18.SqlServer數(shù)據(jù)庫4_卸載

19.Tomcat服務器安裝_使用介紹

2.第一季20套項目源代碼和配套視頻

第一季20套源代碼覆蓋范圍較廣,有比較基礎的JAVA初級項目,也有比較大的WEB項目。每個項目我們都提供了完整的內(nèi)容,涵蓋:論文、PPT、源代碼、數(shù)據(jù)庫文件、配套講解視頻。我們以“土地局檔案管理系統(tǒng)”為例:

打開“論文等資料”文件夾,就發(fā)現(xiàn)有完整的論文和答辯內(nèi)容,供大家參考:

打開“項目輔導視頻”,就發(fā)現(xiàn)有詳細的項目講解視頻,幫助大家解決項目部署、項目模塊講解的問題:

為了快速查看這個項目是否符合你的需求,可以打開“項目截圖”文件夾:

報表圖.png

捕獲.png

檔案修改.png

登錄.png

功能.png

注冊.png

第一季視頻涵蓋如下圖所示項目,范圍比較廣泛。有電子政務項目、也有醫(yī)療項目、也有供應鏈管理項目、互聯(lián)網(wǎng)項目也有若干。同時,也有幾個java基礎項目,大家可以用于做JAVA的課程設計。

九:7U職場軟實力課程和配套視頻

1.職場軟實力是什么?

“每一個人都要訓練軟實力”。成功職場和成功人生不僅需要硬實力,更需要軟實力。兩種實力就像人的雙腿,缺一即“殘”。中國傳媒大學老師王雪和北京尚學堂總裁高淇發(fā)明了7U軟實力理論,讓人的軟實力有可測量的七種維度和提升的標準。已經(jīng)有上百位學員受益,短時間極速提升自己的軟實力,讓自己的工作、愛情、生活都極大受益。

程序員往往關注“編碼能力”等硬實力的提升,而忽視了“口才”、“溝通”等軟實力的提升,造成發(fā)展的困境、職位升遷的困境、甚至戀愛婚姻的困境。所以,對于軟實力不太好的朋友,非常有必要學習軟實力。

更重要的是,軟實力是一個相對的概念。而且大多數(shù)人對認為“軟實力”是天生的,無法通過訓練改變。而實際上,軟實力可以通過訓練快速提升。大家都不學習的情況下,你是很容易脫穎而出的。

職場軟實力不等于技能,但可以讓你的技能得到更好的發(fā)揮。它是你個人發(fā)展的“催化劑”,可以讓你發(fā)展更快、走的更穩(wěn)。

2.形象氣質和社交禮儀

好的形象氣質和職場禮儀是你成功的“助跑器”。除了你父母,沒有人有義務通過你邋遢的外表和不專業(yè)的禮儀深入了解你的內(nèi)在。

本階段將詳細介紹在各種場合的實用技巧。包括:服裝搭配、言談舉止、社交禮儀、生活禮儀、宴會禮儀。

讓你完全掌握職場上的基本禮儀,商務接待和談判的禮儀;掌握生活中待人接物的禮儀,成為一個落落大方的人;掌握宴會禮儀,明白如何講話,如何根據(jù)自己的身份說恰當?shù)脑捫g。

3.聲音素質

聲音不是天生的,可以通過專業(yè)的發(fā)聲技巧來改變。如果聲音不好聽,在人際交往中的效果就要大打折扣。本階段旨在培養(yǎng)大家如何在溝通中發(fā)出好聽的聲音,讓我們的聲音更有磁性,更有力量,更有感染力。

學會掌握自己的聲音,在卡拉OK的場合,再也不懼了。在公眾發(fā)言的場合,心里也會更加有底氣。

聲音是人的第二張名片。我們可以通過掌握胸腹式聯(lián)合呼吸法、共鳴訓練,正確的用氣技巧,很快就能成為一個再也不懼“發(fā)言”場合的人。

4.情商

人際關系有多重要,情商就有多重要。情商是我們所有軟實力的基礎,也是最后的一個升華,所以掌握情商能夠讓我們的人際關系更加的和諧,同時在處理困難挫折的時候又不至于焦頭爛額。本階段將告訴大家我們緊張的原因以及克服的技巧,從微表情中看出對方?jīng)]有用語言表達出來的想法,學會如何面對各種“失意”的情緒,以及在朋友圈中,在職場中如何利用情商處理人際關系。

通過學習情緒控制的基本原理:緊張的原理、條件反射原理。讓自己明白,情商的基礎物理知識。再進一步學習,微表情、自身情商的激勵,成為一個“高情商”的人。

再進一步學習,“朋友中的情商”讓自己成為一個善解人意的人;學習“職場情商”,讓自己成為一個懂領導、懂同事、懂下屬的“高情商”的合作伙伴;

5.溝通力

好的溝通力是人際交往的基礎,可以極大降低生活和工作成本。壞的溝通力能把好事也辦成壞事。本階段將詳細介紹如何更好的打開對方的心扉快速對接,以及贊美和批評的20多種技巧,還會講到如何講好故事,方便我們的溝通,以及酒宴場合的一些應對技巧。

我們需要學習:

1.如何介紹自己、商務場合介紹他人、八卦場合介紹他人

2.人性的特點

3.如何尋找合適的話題

4.掌握贊美的藝術

5.掌握批評他人的技巧

6.各種酒宴場合的演講技巧

7.掌握講好一件事的技術

6.說服力

生活是由一個個說服和被說服構成的,不是被別人說服,就是在說服別人。說服力是職場成功的關鍵。本階段講解提升說服力的技巧方法,讓我們快速的說服領導、同事以及家人。

好的說服力,在你談戀愛、找工作中能發(fā)揮極致作用。我們需要學習如下內(nèi)容:

1.如何破冰,破冰的八大策略

2.如何增加籌碼說服別人

3.十大說服技巧

4.條理公式(說服需要條理和邏輯)

7.說服力之銷售

不管你的職業(yè)是什么,每個人都是銷售。有人銷售產(chǎn)品,有人銷售思想,有人銷售自己。本階段主要針對銷售的技巧進行提升,對于沒有經(jīng)驗的學員能夠快速提升銷售技巧,對于有經(jīng)驗的銷售人員極大提高轉化效率。

做任何職業(yè),掌握銷售技巧都是非常有幫助的。畢竟,本質上“人人都是銷售員”。我們需要學習如下內(nèi)容:

成功銷售三部曲(問、聽、看)

銷售十大步驟

絕對成交七個技巧

8.演講力

“能面對多少人講話,就能有多大的成就”。本階段從演講的三個關鍵點入手,進行細節(jié)分析和技巧把握,以及如何應對演講過程中的尷尬,如何在舞臺上進行即興演講,讓我們站在舞臺上更加從容。

我們需要學習演講訓練的如下關鍵點:

1.如何寫出漂亮的演講稿

2.如何克服恐懼

3.演講自我介紹和互動技巧

4.萬能開場白

5.把握演講節(jié)奏和內(nèi)容

6.眼神、形體、語氣如何運用

7.演講的小策略

①.如何營造互動氛圍

②.如何贏取掌聲

③.忘詞怎么辦

④.如何面對刁鉆古怪的問題

9.領導力

“不想當將軍的士兵不是好士兵”,領導力培養(yǎng)需要從娃娃抓起,是先有領導力才能成為領導,而不是成為領導再鍛煉領導力(除非有個好爸爸給你大量練手機會)。本階段圍繞領導力的的九種特質及快速提升領導力的方法,以及怎樣創(chuàng)建一個優(yōu)秀的適合企業(yè)發(fā)展的團隊。

學好領導力,需要學習如下課程,并開始實戰(zhàn)訓練:

1.理解領導力的九大特質

2.領導的創(chuàng)新心態(tài)調整

組織管理的核心秘訣

4.如何制定合理的戰(zhàn)略決策

5.正確的溝通協(xié)調下屬方式

就業(yè)班
1.JAVA專業(yè),1000課 3.大數(shù)據(jù)專業(yè),500課
2.Python專業(yè),500課    4.人工智能專業(yè),500課

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

2.掃一掃,咨詢詳情:

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