java上机题四取三排列_Java练习题
Java的問答題。
一、 基本
1.一個".java"源文件中是否可以包括多個類(不是內部類)?有什么限制?
可以,限制:一個文件中只能有一個public類,并且此public類必須與文件名相同
2.在 JAVA 中如何跳出當前的多重嵌套循環?
使用break,讓外層的循環條件表達式的結果可以受到里層循環體代碼的控制
3.用最有效率的方法算出2乘以8等於幾?
2<<3
4.簡述邏輯操作(&,|,^)與條件操作(&&,||)的區別。
區別主要答兩點: a.條件操作只能操作布爾型的,而邏輯操作不僅可以操作布爾型,而且可以操作數值型 b.邏輯操作不會產生短路
5.char型變量中能不能存貯一個中文漢字?為什么?
可以,因為Java中使用的編碼是Unicode,一個char類型占2個字節(16比特),所以放一個中文是沒問題的。
6.請說出作用域public,private,protected,以及不寫時的區別?
作用域 當前類 同一package 子孫類 其他package public √ √ √ √ protected √ √ √ × friendly √ √ × × private √ × × ×
7.使用final關鍵字修飾一個變量時,是引用不能變,還是引用的對象不能變?
使用final關鍵字修飾一個變量時,是指引用變量不能變,引用變量所指向的對象中的內容還是可以改變的。
8.Math.round(11.5)等於多少? Math.round(-11.5)等於多少?
Math.round(11.5)的結果為12,Math.round(-11.5)的結果為-11
9.是否可以從一個static方法內部發出對非static方法的調用?
不可以,因為非static方法是要與對象關聯在一起的,必須創建一個對象后,才可以在該對象上進行方法調用,而static方法調用時不需要創建對象,可以 直接調用。也就是說,當一個static方法被調用時,可能還沒有創建任何實例對象,如果從一個static方法中發出對非static方法的調用,那個非static方法是關聯到哪個對象上的呢?這個邏輯無法成立,所以,一個static方法內部發出對非static方法的調用。
10."=="和 equals 方法究竟有什么區別?
“==”是看兩個對象是否是同一個對象,也就是兩個[對象引用]是否指向同一個對象(Java分配的[內存地址]一樣)當然如果用于int,long,double就不是看兩個值是否相等了 equals()是比較兩個對象的內容是否相等,一般如果用戶自己不定義針對自己的類的equals()方法,那么就會使用Object你的類的父類的這個方法。如果你的類里沒有[對象引用]的域,就不必要覆蓋equals()(注意String域也是對象)String有自己的equals()方法,它已經覆蓋了Object的該方法了。
11.Java里的傳引用和傳值的區別是什么?
在方法參數傳遞中當變量是8大基本數據類型的時候,就是傳值,在方法里被修改了這個也不會影響 當變量是Object類型的時候,就是傳引用
12.為什么Java里沒有全局變量?
Global variables(全局變量) 是指可以全局訪問的變量, Java不支持全局變量,原因如下: 1. 全局變量破壞了引用的透明性
13.如何將String類型轉化成Number類型?
第一種方法:i=Integer.parseInt(s);//直接使用靜態方法,不會產生多余的對象,但會拋出異常 第二種方法:i=Integer.valueOf(s).intValue();//Integer.valueOf(s) 相當于 new Integer(Integer.parseInt(s)),也會拋異常,但會多產生一個對象
二、 類相關
Final關鍵字有什么特點?
final:最終的意思,可以修飾類,方法和變量 它修飾的類,不能被繼承 它修飾的方法,不能被重寫 它修飾的變量,不能被改變
1.Integer與int的區別
Integer是int提供的封裝類,而int是的基本數據類型; Integer默認值是null,而int默認值是0; 聲明為Integer的變量需要實例化,而聲明為int的變量不需要實例化; Integer是對象,用一個引用指向這個對象,而int是基本類型,直接存儲數值。
2.如何將數值型字符轉換為數字( Integer , Double )
1、如何將字符串String轉化為整數int int i = Integer.parseInt(str); int i = Integer.valueOf(my_str).intValue(); 注: 字串轉成Double, Float, Long的方法大同小異。 2、如何將字符串String轉化為Integer Integer integer=Integer.valueOf(i) 3、如何將整數 int 轉換成字串 String? String s = String.valueOf(i); String s = Integer.toString(i); String s = "" + i; 注:Double, Float, Long 轉成字串的方法大同小異。
3.寫clone()方法時,通常都有一行代碼,是什么?
clone 有缺省行為,super.clone();因為首先要把父類中的成員復制到位,然后才是復制自己的成員。
4.抽象類的作用
1.通過繼承它實現多態,后期綁定,可以為將來要實現的東西做好接口,實現重用性。 2.接口就是更純粹的抽象類。
5.abstract class和interface有什么區別?
抽象類和接口的對比
Paste_Image.png
什么時候使用抽象類和接口
如果你擁有一些方法并且想讓它們中的一些有默認實現,那么使用抽象類吧。 如果你想實現多重繼承,那么你必須使用接口。由于Java不支持多繼承,子類不能夠繼承多個類,但可以實現多個接口。因此你就可以使用接口來解決它。 如果基本功能在不斷改變,那么就需要使用抽象類。如果不斷改變基本功能并且使用接口,那么就需要改變所有實現了該接口的類。
6.abstract的method是否可同時是static,是否可同時是native,是否可同時是synchronized?
都不可以,因為abstract申明的方法是要求子類去實現的,abstract只是告訴你有這樣一個接口,你要去實現,至于你的具體實現可以是native和synchronized,也可以不是,抽象方法是不關心這些事的,所以寫這兩個是沒有意義的。然后,static方法是不會被覆蓋的,而abstract方法正是要子類去覆蓋它,所以也是沒有意義的。所以,總的來說,就是java語法不允許你這樣做,事實上,也沒有意義這樣做。
7.接口是否可繼承接口? 抽象類是否可實現(implements)接口? 抽象類是否可繼承具體類(concrete class)?抽象類中是否可以有靜態的main方法?
接口可以繼承接口。抽象類可以實現(implements)接口,抽象類是可以繼承具體類。抽象類中可以有靜態的main方法。 記住抽象類與普通類的唯一區別就是不能創建實例對象和允許有abstract方法。
9.如何取小數點前兩位,并四舍五入。
BigDecimal k = new BigDecimal(25.9887);
BigDecimal j = k.setScale(2, BigDecimal.ROUND_HALF_UP);
String a= j.toString();
a = a.substring(a.length()-2);
System.out.println(a);
另一種思路:
double d = 3.1475926;
double d1 = d*100.0;
double d2 = Math.round(d1);
double d3 = d2/100.0;
System.out.println("d保留小數點2位并四舍五入的是:"+d3);
10.如何取得年月日,小時分秒?
public class DateTest {
public static void main(String[] args) throws ParseException {
Calendar now = Calendar.getInstance();
System.out.println("年: " + now.get(Calendar.YEAR));
System.out.println("月: " + (now.get(Calendar.MONTH) + 1) + "");
System.out.println("日: " + now.get(Calendar.DAY_OF_MONTH));
System.out.println("時: " + now.get(Calendar.HOUR_OF_DAY));
System.out.println("分: " + now.get(Calendar.MINUTE));
System.out.println("秒: " + now.get(Calendar.SECOND));
System.out.println("當前時間毫秒數:" + now.getTimeInMillis());
System.out.println(now.getTime());
Date d = new Date();
System.out.println(d);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dateNowStr = sdf.format(d);
System.out.println("格式化后的日期:" + dateNowStr);
String str = "2012-1-13 17:26:33"; //要跟上面sdf定義的格式一樣
Date today = sdf.parse(str);
System.out.println("字符串轉成日期:" + today);
}
}
11.如何取得從 1970 年到現在的毫秒數
public static void main(String[] args) {
// TODO Auto-generated method stub
Date dt= new Date();
Long time= dt.getTime();//這就是距離1970年1月1日0點0分0秒的毫秒數
System.out.println(System.currentTimeMillis());//與上面的相同
}
13.編碼轉換,怎樣實現將 GB2312 編碼的字符串轉換為 ISO-8859-1 編碼的字符串。
參考:https://zhidao.baidu.com/question/141886093.html
謹慎地使用getBytes(NAME_OF_CHARSET)和new String(bytes, NAME_OF_CHARSET),除非你很清楚的知道原始的字
符編碼和傳輸協議使用的編碼。
推薦使用基于服務器的配置、過濾器設置request/response的characterEncoding、content type屬性。還有就是JSP頁面的
pageEncoding屬性、HTML meta元素的content type屬性。盡量避免頻繁的在代碼中進行字符串轉碼,即降低了效率又增
加了風險。
14.String是最基本的數據類型嗎?
不是,基本數據類型包括:byte,short,int,long,float,double,boolean,char. 而String是類代表字符串,屬于引用類型,所謂引用類型包括:類,接口,數組...
15.是否可以繼承String類?
String類是final類型的,故不可以繼承。
16.String s = "Hello";s = s + " world!";這兩行代碼執行后,原始的String對象中的內容到底變了沒有?
沒有,s + " world!" 創建了一個新的對象。
17.String s = new String("xyz");創建了幾個String Object? 二者之間有什么區別?
如果JVM常量池中存在"xyz",則是創建了一個對象s,如果不存在"xyz",則是先創建一個"xyz"對象,結果為2個對象
18.下面的代碼有什么不妥之處?
if(username.equals(“zxx”)){}
直接調用equals方法可能會拋出NullPointerException異常。為了防止程序拋出異常在調用equals方法之前要先判斷一下是否為空。 if( username!=null && username.equals(“zxx”){}這樣寫才完整。
int x = 1;return x==1?true:false;
?true:false 多余了
20.String 和StringBuffer的區別
String 為不可變對象,一旦被創建,就不能修改它的值,StringBuffer是一個可變對象,當對他進行修改的時候不會像String那樣重新建立對象,所以使用StringBuffer速度會比String 快。
21.StringBuffer與StringBuilder的區別
StringBuilder:線程非安全的 StringBuffer:線程安全的
22.如何把一段逗號分割的字符串轉換成一個數組?
用正則表達式,代碼大概為:String [] result = orgStr.split(“,”);
用 StingTokenizer ,代碼為:
StringTokenizer tokener = StringTokenizer(orgStr,”,”);
String [] result = new String[tokener.countTokens()];
Int i=0;
while(tokener.hasNext(){result[i++]=toker.nextToken();}
23.數組有沒有length()這個方法? String有沒有length()這個方法?
數組中沒有length()這個方法,但是數組中有length這個屬性。用來表示數組的長度 String中有length()這個方法。用來得到字符串的長度。
24.下面這條語句一共創建了多少個對象:String s="a"+"b"+"c"+"d";
javac 編譯可以對 字符串常量直接相加的表達式進行優化, 不必要等到運行期去進行加法運算處理, 而是在編 譯時去掉其中的加號, 直接將其編譯成一個這些常量相連的結果。 題目中的第一行代碼被編譯器在編譯時優化后, 相當于直接定義了一個”abcd”的字符串, 所以, 上面的代碼應該只創建了一個 String 對象。
25.說出一些常用的類,包,接口,請各舉5個
類: BufferedReader BufferedWriter String Integer Date 包: java.lang java.io java.util java.sql spring的包 接口: List Map Set Iterable Serializable
26.能不能自己寫個類,也叫java.lang.String?
可以,但在應用的時候,需要用自己的類加載器去加載,否則,系統的類加載器永遠只是去加載jre.jar包中的那個Java.lang.String。
三、 內部類
1.什么是內部類?Static Nested Class 和 Inner Class的不同。
Inner Class(內部類)定義在類中的類。 (一般是JAVA的說法) Nested Class(嵌套類)是靜態(static)內部類。(一般是C++的說法) 靜態內部類: 1 創建一個static內部類的對象,不需要一個外部類對象 2 不能從一個static內部類的一個對象訪問一個外部類對象
2.內部類可以引用它的包含類的成員嗎?有沒有什么限制?
可以,但非靜態內部類中不能定義靜態成員(靜態對象是默認加載,那么靜態內部類應該先于外部類被加載到內存中)
3.一個房子里有椅子,椅子有腿和背,房子與椅子是什么關系,椅子與腿和背是什么關系?
has a is a
4.Anonymous Inner Class (匿名內部類) 是否可以extends(繼承)其它類,是否可以implements(實現)interface(接口)?
`
匿名內部類:
可以繼承其他類,但不能用extends。
可以實現某接口,但不能用implements。
Paste_Image.png
答案來之知乎https://www.zhihu.com/question/21285716
`
四、 繼承相關
1.super() 與 與 this() 的區別?
this是當前對象的引用,super是當前對象的父類對象的引用!
2.面向對象的特征有哪些方面
1.抽象:抽象就是忽略一個主題中與當前目標無關的那些方面,以便更充分地注意與當前目標有關的方面。抽象并不打算了解全部問題,而只是選擇其中的一部分,暫時不用部分細節。抽象包括兩個方面,一是過程抽象,二是[數據抽象]
2.繼承:繼承是一種聯結類的層次模型,并且允許和鼓勵類的重用,它提供了一種明確表述共性的方法。對象的一個新類可以從現有的類中派生,這個過程稱為類繼承。新類繼承了原始類的特性,新類稱為原始類的派生類(子類),而原始類稱為新類的基類(父類)。派生類可以從它的基類那里繼承方法和[實例變量],并且類可以修改或增加新的方法使之更適合特殊的需要。
3.封裝:封裝是把過程和數據包圍起來,對數據的訪問只能通過已定義的界面。面向對象計算始于這個基本概念,即現實世界可以被描繪成一系列完全自治、封裝的對象,這些對象通過一個受保護的接口訪問其他對象。
4.多態性:多態性是指允許不同類的對象對同一消息作出響應。多態性包括參數化多態性和包含多態性。多態性語言具有靈活、抽象、行為共享、[代碼共享]的優勢,很好的解決了應用程序函數同名問題。
3.java中實現多態的機制是什么?
java中實現多態的機制靠的是父類或者接口定義的引用變量可以指向子類或者具體的實現類的實例對象,而程序調的方法在運行期才動態綁定,就是引用變量所指向的具體實例對象的方法,也就是內存里正在運行的那個對象的方法,而不是引用變量的類型中定義的方法。
4.jdk中哪些類是不能繼承的?
final修飾的類
5.super.getClass()方法調用
getClass方法來自Object類,它返回對象在運行時的類型 如果想得到父類的名稱,應該用如下代碼: Java代碼 getClass().getSuperClass().getName()
6.搞了多個重載方法,參數分別是int ,char,和double,然后將double x = 2,傳遞進去,會選擇哪個方法?
調用參數為double的方法
7.構造器Constructor是否可被override?
其實你只需要記住一句話:構造器不是方法,那么用來修飾方法特性的所有修飾符都不能用來修飾構造器(并不等與構造器 具備這些特性,雖然不能用static修飾構造器,但它卻有靜態特性)構造器只能用 public private protected這 三個權限修飾符,且不能有返回語句。
8.Overload 和 Override 的區別。Overloaded 的方法是否可以改變返回值的類型?
方法的重寫Overriding 和重載Overloading 是Java 多態性的不同表現。重寫Overriding 是父類 與子類之間多態性的一種表現,重載Overloading 是一個類中多態性的一種表現。如果在子類中定義某 方法與其父類有相同的名稱和參數,我們說該方法被重寫(Overriding)。子類的對象使用這個方法時, 將調用子類中的定義,對它而言,父類中的定義如同被"屏蔽"了。如果在一個類中定義了多個同名的方法, 它們或有不同的參數個數或有不同的參數類型,則稱為方法的重載(Overloading)。Overloaded 的方法 是可以改變返回值的類型
五、 異常的
1.try {}里有一個return語句,那么緊跟在這個try后的finally {}里的code會不會被執行,什么時候被執行,在return前還是后?
會執行,在try語句中,在執行return語句時,要返回的結果已經準備好了,就在此時,程序轉到finally執行了在轉去之前,try中先把要返回的結果存放到不同于a的局部變量中去,執行完finally之后,在從中取出返回結果,因此,即使finally中對變量a進行了改變,但是不會影響返回結果。
2.final, finally, finalize的區別。
final --修飾符(關鍵字)。如果一個類被聲明為final,意味著它不能再派生出新的子類,不能作為父類被繼承 被final聲明過的類也可以稱為太監類(因為不能在繼承)被final聲明過的變量就變成常量了 如果加上static 就是全局常量了 finally—在異常!處理時提供 finally 塊來執行任何清除操作。如果拋出一個異常,那么相匹配的catch 子句就會執行,然后控制就會進入 finally 塊(如果有的話)。 finalize —方法名。Java 技術允許使用finalize() 方法在垃圾收集器將對象從內存中清除出去之前做必要的清理工作。一旦垃圾回收器準備好釋放對象占用的空間,將首先調用其finalize()方法,并且在下一次垃圾回收動作發生時,才會真正回收對象占用的內存。簡單的說finalize() 方法是在垃圾收集器刪除對象之前對這個對象調用的
3.運行時異常與一般異常有何異同?
運行時異常和檢查時異常。checked 異常就是經常遇到的IO異常,以及SQL異常等等,對于這種異常,編譯器強制要求我們去try/catch。而對于runtime exception,我們可以不處理,比如:我們從來沒有人去處理過NullPointerException異常,它就是運行時異常,這還是個最常見的異常之一哦。
4.error和exception有什么區別?
Error 是 Throwable 的子類,用于指示合理的應用程序不應該試圖捕獲的嚴重問題 Exception 類及其子類是 Throwable 的一種形式,它指出了合理的應用程序想要捕獲的條件
5.Java中的異常處理機制的簡單原理和應用。
如果程序在運行中 發生了不允許的情況 比如 除0,比如空指針,常見的異常 [JVM])會自動的[拋出異常]不知道的異常,需要人工拋出 和捕獲,當發生異常的時候捕獲異常會對異常進行處理
6.請寫出你最常見到的5個runtime exception。
NullPointerException、ArrayIndexOutOfBoundsException、ClassCastException。 StringIndexOutOfBoundsException WebServiceException ArithmeticException(整數除0時發生)
7.JAVA語言如何進行異常處理,關鍵字:throws,throw,try,catch,finally分別代表什么意義?在try塊中可以拋出異常嗎?
throws是獲取異常 throw是拋出異常 try是將會發生異常的語句括起來,從而進行異常的處理 catch是如果有異常就會執行他里面的語句 而finally不論是否有異常都會進行執行的語句。 throw和throws的詳細區別如下: throw是語句拋出一個異常。 語法:throw (異常對象); throw e; throws是方法可能拋出異常的聲明。(用在聲明方法時,表示該方法可能要拋出異常) 語法:[(修飾符)](返回值類型)(方法名)([參數列表])[throws(異常類)]{......} public void doA(int a) throws Exception1,Exception3{......}
舉例: 如: void doA(int a) throws Exception1,Exception3{ try{ ...... }catch(Exception1 e){ throw e; }catch(Exception2 e){ System.out.println("出錯了!"); } if(a!=b) throw new Exception3("自定義異常"); }
六、 線程的
1.同步和異步有何異同,在什么情況下分別使用他們?舉例說明。
1.同步交互:指發送一個請求,需要等待返回,然后才能夠發送下一個請求,有個等待過程 2.異步交互:指發送一個請求,不需要等待返回,隨時可以再發送下一個請求,即不需要等待。 區別:一個需要等待,一個不需要等待,在部分情況下,我們的項目開發中都會優先選擇不需要等待的異步交互方式。 哪些情況建議使用同步交互呢?比如銀行的轉賬系統,對數據庫的保存操作等等,都會使用同步交互操作,其余情況都優先使用異步交互。
2.線程的基本概念、線程的基本狀態以及狀態之間的關系
`
1.什么是線程
一個線程是進程的一個順序執行流。同類的多個線程共享一塊內存空間和一組系統資源,線程本身有一個供程序執行時的堆棧。線程在切換時負荷小,因此,線程也被稱為輕負荷進程。一個進程中可以包含多個線程。
2.進程與線程的區別
一個進程至少有一個線程。線程的劃分尺度小于進程,使得多線程程序的并發性高。另外,進程在執行過程中擁有獨立的內存單元,而多個線程共享內存,從而極大地提高了程序的運行效率。
線程在執行過程中與進程的區別在于每個獨立的線程有一個程序運行的入口、順序執行序列和程序的出口。但是線程不能夠獨立執行,必須依存在應用程序中,由應用程序提供多個線程執行控制。
從邏輯角度來看,多線程的意義在于一個應用程序中,有多個執行部分可以同時執行。但[操作系統]并沒有將多個線程看做多個獨立的應用來實現進程的調度和管理以及資源分配。
3.并發原理
多個線程或進程”同時”運行只是我們感官上的一種表現。事實上進程和線程是并發運行的,OS的線程調度機制將時間劃分為很多時間片段(時間片),盡可能均勻分配給正在運行的程序,獲取CPU時間片的線程或進程得以被執行,其他則等待。而CPU則在這些進程或線程上來回切換運行。微觀上所有進程和線程是走走停停的,宏觀上都在運行,這種都運行的現象叫并發,但是不是絕對意義上的“同時發生。
4.線程狀態
Paste_Image.png
1.新建
用new語句創建的線程對象處于新建狀態,此時它和其他[Java]對象一樣,僅被分配了內存。
2.等待
當線程在new之后,并且在調用start方法前,線程處于等待狀態。
3.就緒
當一個線程對象創建后,其他線程調用它的start()方法,該線程就進入就緒狀態。處于這個狀態的線程位于Java虛擬機的可運行池中,等待cpu的使用權。
4.運行狀態
處于這個狀態的線程占用CPU,執行程序代碼。在并發運行環境中,如果計算機只有一個CPU,那么任何時刻只會有一個線程處于這個狀態。
只有處于就緒狀態的線程才有機會轉到運行狀態。
5.阻塞狀態
阻塞狀態是指線程因為某些原因放棄CPU,暫時停止運行。當線程處于阻塞狀態時,Java虛擬機不會給線程分配CPU,直到線程重新進入就緒狀態,它才會有機會獲得運行狀態。
阻塞狀態分為三種:
1、等待阻塞:運行的線程執行wait()方法,JVM會把該線程放入等待池中。
2、同步阻塞:運行的線程在獲取對象同步鎖時,若該同步鎖被別的線程占用,則JVM會把線程放入鎖池中。
3、其他阻塞:運行的線程執行Sleep()方法,或者發出I/O請求時,JVM會把線程設為阻塞狀態。當Sleep()狀態超時、或者I/O處理完畢時,線程重新轉入就緒狀態。
6.死亡狀態
當線程執行完run()方法中的代碼,或者遇到了未捕獲的異常,就會退出run()方法,此時就進入死亡狀態,該線程結束生命周期。
`
3.啟動一個線程是用run()還是start()?
start()
4.java中有幾種方法可以實現一個線程?用什么關鍵字修飾同步方法? stop()和suspend()方法為何不推薦使用?
有兩種實現方法,分別是繼承Thread類與實現Runnable接口 用synchronized關鍵字修飾同步方法
5.sleep() 和 wait() 有什么區別?
先說wait,wait的本質是條件等待,這里涉及到了鎖的概念(也就是多線程中要保證[線程安全]的鎖)。所謂條件等待就是已經獲得了鎖的線程,由于需要滿足某種條件才能繼續執行,而當前不滿足條件,所以只能等待。所以調用wait的一個前提條件就是要先拿到鎖。拿到鎖的線程,wait之后,該線程就進入條件[等待隊列],并且釋放鎖,讓其他線程執行。當其他線程的執行使得條件滿足之后,再調用notify或者notifyAll方法,將條件[等待隊列]中的線程喚醒,這些線程再去請求鎖,拿到鎖的線程接著去執行。 sleep(long t)的意思是暫停當前線程t[毫秒],當然,其他線程就得到了時間片,sleep與線程是否獲得鎖無關。調用sleep線程進入TimeWaiting狀態。
7.多線程有幾種實現方法?同步有幾種實現方法?
多線程實現:繼承Thread類,重寫run();實現Runnable接口,重寫run(); 同步方式:synchronized修飾,wait(),notify()
8.當一個線程進入一個對象的一個synchronized方法后,其它線程是否可進入此對象的其它方法?
1.其他方法前是否加了synchronized關鍵字,如果沒加,則能。 2.如果這個方法內部調用了wait,則可以進入其他synchronized方法。 3.如果其他個方法都加了synchronized關鍵字,并且內部沒有調用wait,則不能。 如果其他方法也被static關鍵字修飾,那么這些方法使用的同步鎖(或者可以叫做監視器)是當前對象“類鎖“,而不是當前“對象鎖”(“對象”是“類”的具體實),所以用的是兩個鎖,就不能同步。
9.簡述synchronized和java.util.concurrent.locks.Lock的異同 ?
1.Lock能完成幾乎所有synchronized的功能,并有一些后者不具備的功能,如鎖投票、定時鎖等候、可中斷鎖等候等 2.synchronized 是[Java](http://lib.csdn.net/base/javase) 語言層面的,是內置的關鍵字;Lock 則是JDK 5中出現的一個包,在使用時,synchronized 同步的代碼塊可以由JVM自動釋放;Lock 需要程序員在finally塊中手工釋放,如果不釋放,可能會引起難以預料的后果(在多線程環境中)。
10.線程如何同步和通訊
多線程同步示例,來自《瘋狂java講義》。
通過synchronized,wait(),notify(),notifyAll()實現多線程同步與通信
例:
假設現在系統中有兩個線程,這兩個線程分別代表存錢者和取錢者---現在假設系統有一種特殊的要求,系統要求存款者和取錢者不斷地重復存錢、取錢動作,而且要求每當存款著將錢存入指定賬戶后,取錢者就立即取出這筆錢。不允許存款者連續兩次存錢,也不允許取錢者連續兩次取錢。
程序中,通過一個旗標flag標識,本次賬戶操作是不是存款操作,以便下次操作可以探測
1.Account賬戶類,有取錢(drawBalance)和存錢(deposit)兩個同步方法
package com.sunchp;
public class Account {
private String accountNo;
private double balance;
private boolean flag = false;
public Account(String _accountNo, double _balance) {
this.accountNo = _accountNo;
this.balance = _balance;
}
public String getAccountNo() {
return accountNo;
}
public void setAccountNo(String accountNo) {
this.accountNo = accountNo;
}
public double getBalance() {
return balance;
}
public synchronized void drawBalance(double drawBalance) {
if (flag) {
if (balance > drawBalance) {
System.out.println(Thread.currentThread().getName() + "取錢成功,正在吐鈔:" + drawBalance);
balance -= drawBalance;
flag = false;
this.notifyAll();
System.out.println(Thread.currentThread().getName() + "余額為:" + getBalance());
} else {
System.out.println(Thread.currentThread().getName() + "取錢失敗,余額不足");
}
} else {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public synchronized void deposit(double depositBalance) {
if (flag) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
System.out.println(Thread.currentThread().getName() + " 存款:" + depositBalance);
this.balance += depositBalance;
flag = true;
this.notifyAll();
System.out.println(Thread.currentThread().getName() + "余額為:" + getBalance());
}
}
}
2.取錢線程類
package com.sunchp;
public class MyThread1 implements Runnable {
private Account account;
private double drawBalance;
public Account getAccount() {
return account;
}
public void setAccount(Account account) {
this.account = account;
}
public double getDrawBalance() {
return drawBalance;
}
public void setDrawBalance(double drawBalance) {
this.drawBalance = drawBalance;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
account.drawBalance(drawBalance);
}
}
}
3.存錢線程類
package com.sunchp;
public class MyThread2 implements Runnable {
private Account account;
private double depositBalance;
public Account getAccount() {
return account;
}
public void setAccount(Account account) {
this.account = account;
}
public double getDepositBalance() {
return depositBalance;
}
public void setDepositBalance(double depositBalance) {
this.depositBalance = depositBalance;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
account.deposit(depositBalance);
}
}
}
4.測試類,main方法
package com.sunchp;
public class Test {
public static void main(String[] args) throws Exception {
Account acc = new Account("001", 1000);
MyThread1 mt1 = new MyThread1();
mt1.setAccount(acc);
mt1.setDrawBalance(20);
Thread t1 = new Thread(mt1, "取錢者1");
Thread t2 = new Thread(mt1, "取錢者2");
MyThread2 mt2 = new MyThread2();
mt2.setAccount(acc);
mt2.setDepositBalance(20);
Thread t3 = new Thread(mt2, "存錢者1");
Thread t4 = new Thread(mt2, "存錢者2");
t1.start();
t2.start();
t3.start();
t4.start();
}
}
七、 集合的
1.介紹Collection框架的結構
常用容器繼承關系圖
Paste_Image.png
Iterator不是容器,只是一個操作遍歷集合的方法
Collection和Map
Collection:
是容器繼承關系中的頂層接口。是一組對象元素組。有些容器允許重復元素有的不允許,有些有序有些無序。 JDK不直接提供對于這個接口的實現,但是提供繼承與該接口的子接口比如 List Set。
Map:
一個保存鍵值映射的對象。 映射Map中不能包含重復的key,每一個key最多對應一個value。
List和Set:
他們2個是繼承Collection的子接口,就是說他們也都是負責存儲單個元素的容器。
最大的區別如下:
List是存儲的元素容器是有個有序的可以索引到元素的容器,并且里面的元素可以重復。
Set里面和List最大的區別是Set里面的元素對象不可重復。
詳細:http://www.jianshu.com/p/46f2c704abeb
2.Collection框架中實現比較要實現什么接口
要實現 comparable 接口,把你的自定義類實現以上接口,實現 compareTo 方法
3.Collection 和 Collections的區別。
Collection是集合類的上級接口,繼承與他有關的接口主要有List和Set Collections是針對集合類的一個幫助類,他提供一系列靜態方法實現對各種集合的搜索、排序、線程安全等
4.你所知道的集合類都有哪些?主要方法?
map:Hashmap,Treemap set: Hashset Treeset list: Arraylist LinkedList 主要方法:add() clear() remove size() isEmpty() iterator()等
6.List、Map、Set三個接口,存取元素時,各有什么特點?
list是線性表,元素是你任意加進去的。 map是[key-value]二元映射表,可做索引。 set是集合表,元素不重復。
7.List 和 Map 區別?
list是對象集合,允許對象重復。 map是鍵值對的集合,不允許key重復。
8.hashCode方法的作用?
也就是說 List 是一個有序的、可重復的對象容器接口,Set是一個無序的、不可重復的對象容器接口 。后面都講了 Set 是如何實現不重復的 :為了避免多次重復的使用 equal 方法帶來的系統負擔 ,set 首先調用hashCode 方法來檢測 是否被占用 如果被占用 然后調用 equal 方法判斷被占用的是否相同
10.說出ArrayList,Vector, LinkedList的存儲性能和特性
ArrayList 采用的是數組形式來保存對象的,這種方式將對象放在連續的位置中,所以最大的缺點就是插入刪除時非常麻煩 LinkedList 采用的將對象存放在獨立的空間中,而且在每個空間中還保存下一個鏈接的索引 但是缺點就是查找非常麻煩 要叢第一個索引開始 ArrayList和Vector都是用數組方式存儲數據,此數組元素數要大于實際的存儲空間以便進行元素增加和插入操作,他們都允許直接用序號索引元素,但是插入數據元素涉及到元素移動等內存操作,所以索引數據快而插入數據慢. Vector使用了sychronized方法(線程安全),所以在性能上比ArrayList要差些. LinkedList使用雙向鏈表方式存儲數據,按序號索引數據需要前向或后向遍歷數據,所以索引數據慢,是插入數據時只需要記錄前后項即可,所以插入的速度快.
12.Set里的元素是不能重復的,那么用什么方法來區分重復與否呢? 是用==還是equals()? 它們有何區別?
==是用來判斷兩者是否是同一對象(同一事物),而equals是用來判斷是否引用同一個對象。還是對象的引用。根據Java的存儲機制可知,set里面存放的是對象的引用,所以當兩個元素只要滿足了equals()時就已經指向同一個對象,也就出現了重復元素。所以應該用equals()來判斷。
13.HashMap和Hashtable的區別
1.HashMap幾乎可以等價于Hashtable,除了HashMap是非synchronized的,并可以接受null(HashMap可以接受為null的鍵值(key)和值(value),而Hashtable則不行)。 2.HashMap是非synchronized,而Hashtable是synchronized,這意味著Hashtable是線程安全的,多個線程可以共享一個Hashtable;而如果沒有正確的同步的話,多個線程是不能共享HashMap的。Java 5提供了ConcurrentHashMap,它是HashTable的替代,比HashTable的擴展性更好。 3.另一個區別是HashMap的迭代器(Iterator)是fail-fast迭代器,而Hashtable的enumerator迭代器不是fail-fast的。所以當有其它線程改變了HashMap的結構(增加或者移除元素),將會拋出ConcurrentModificationException,但迭代器本身的remove()方法移除元素則不會拋出ConcurrentModificationException異常。但這并不是一個一定發生的行為,要看JVM。這條同樣也是Enumeration和Iterator的區別。 3.由于Hashtable是線程安全的也是synchronized,所以在單線程環境下它比HashMap要慢。如果你不需要同步,只需要單一線程,那么使用HashMap性能要好過Hashtable。 HashMap不能保證隨著時間的推移Map中的元素次序是不變的。
14.兩個對象值相同(x.equals(y) == true),但卻可有不同的hash code,這句話對不對?
不對,如果兩個對象x和y滿足x.equals(y) == true,它們的哈希碼(hash code)應當相同。Java對于eqauls方法和hashCode方法是這樣規定的:(1)如果兩個對象相同(equals方法返回true),那么它們的hashCode值一定要相同;(2)如果兩個對象的hashCode相同,它們并不一定相同。當然,你未必要按照要求去做,但是如果你違背了上述原則就會發現在使用容器時,相同的對象可以出現在Set集合中,同時增加新元素的效率會大大下降(對于使用哈希存儲的系統,如果哈希碼頻繁的沖突將會造成存取性能急劇下降)。
15.TreeSet里面放對象,如果同時放入了父類和子類的實例對象,那比較時使用的是父類的compareTo方法,還是使用的子類的compareTo方法,還是拋異常!
如果子類和父類都復寫了compareTo方法那么各自調用自己的compareTo方法 如果子類沒有復寫compareTo方法,那么調用的都是父類的compareTo方法
八、 io 的語法
1.什么是java序列化,如何實現java序列化?或者請解釋Serializable接口的作用。
將一個java對象變成字節流的形式傳出去或者從一個字節流中恢復成一個java對象,序列化是將對象狀態轉換為可保持或傳輸的格式的過程。 什么是java序列化,如何實現java序列化?或者請解釋Serializable接口的作用 將一個java對象變成字節流的形式傳出去或者從一個字節流中恢復成一個java對象 序列化是將對象狀態轉換為可保持或傳輸的格式的過程。 java中的序列化機制能夠將一個實例對象(只序列化對象的屬性值,而不會去序列化什么所謂的方法。)的狀態信息寫入到一個字節流中使其可以通過socket進行傳輸、或者持久化到存儲數據庫或文件系統中;然后在需要的時候通過字節流中的信息來重構一個相同的對象。一般而言,要使得一個類可以序列化,只需簡單實現java.io.Serializable接口即可。 序列化就是一種用來處理對象流的機制,所謂對象流也就是將對象的內容進行流化。可以對流化后的對象進行讀寫操作,也可將流化后的對象傳輸于網絡之間。序列化是為了解決在對對象流進行讀寫操作時所引發的問題。序列化的實現:將需要被序列化的類實現Serializable接口,該接口沒有需要實現的方法,implements Serializable只是為了標注該對象是可被序列化的,然后使用一個輸出流(如:FileOutputStream)來構造一個ObjectOutputStream(對象流)對象,接著,使用ObjectOutputStream對象的writeObject(Object obj)方法就可以將參數為obj的對象寫出(即保存其狀態),要恢復的話則用輸入流。
2.序列化接口的id有什么用?
序列化時為了保持版本的兼容性,即在版本升級時反序列化仍保持對象的唯一性。
3.java中有幾種類型的流?JDK為每種類型的流提供了一些抽象類以供繼承,請說出他們分別是哪些類?
IO流四大家族: InputStream:輸入字節流。 OutputStream:輸出字節流。 Reader:輸入字符流。 Writer:輸出字符流。
4.字節流與字符流的區別
https://www.zhihu.com/question/39262026 總而言之,一切都是字節流,其實沒有字符流這個東西。字符只是根據編碼集對字節流翻譯之后的產物。
九、虛擬機方面的語法
1.什么是類的反射射機制?
反射機制是在運行狀態中,對于任意一個類,都能夠知道這個類的所有屬性和方法;對于任意一個對象,都能夠調用它的任意一個方法和屬性;這種動態獲取的信息以及動態調用對象的方法的功能稱為java語言的反射機制。
2.類的反射機制中的包及核心類?
java.lang.reflect這個包下面的類 Constructor 提供關于類的單個構造方法的信息以及對它的[訪問權限] Field 提供有關類或接口的單個字段的信息,以及對它的動態[訪問權限]。 Method 提供關于類或接口上單獨某個方法(以及如何訪問該方法)的信息。 Modifier 類提供了 static 方法和常量,對類和成員訪問修飾符進行解碼。 Proxy 提供用于創建動態代理類和實例的靜態方法,它還是由這些方法創建的所有動態代理類的超類。
3.得到 Class 的三個過程是什么?
對象.getClass() 類.class或Integer.type(int) Integer.class(java.lang.Integer) Class.forName();
4.描述一下JVM加載class文件的原理機制?
JVM中類的裝載是由類加載器(ClassLoader)和它的子類來實現的,Java中的類加載器是一個重要的Java運行時系統組件,它負責在運行時查找和裝入類文件中的類。 由于Java的跨平臺性,經過編譯的Java源程序并不是一個可執行程序,而是一個或多個類文件。當Java程序需要使用某個類時,JVM會確保這個類已經被加載、連接(驗證、準備和解析)和初始化。類的加載是指把類的.class文件中的數據讀入到內存中,通常是創建一個字節數組讀入.class文件,然后產生與所加載類對應的Class對象。加載完成后,Class對象還不完整,所以此時的類還不可用。當類被加載后就進入連接階段,這一階段包括驗證、準備(為靜態變量分配內存并設置默認的初始值)和解析(將符號引用替換為直接引用)三個步驟。最后JVM對類進行初始化,包括:1)如果類存在直接的父類并且這個類還沒有被初始化,那么就先初始化父類;2)如果類中存在初始化語句,就依次執行這些初始化語句。 類的加載是由類加載器完成的,類加載器包括:根加載器(BootStrap)、擴展加載器(Extension)、系統加載器(System)和用戶自定義類加載器(java.lang.ClassLoader的子類)。 2(JDK 1.2)開始,類加載過程采取了父親委托機制(PDM)。PDM更好的保證了Java平臺的安全性,在該機制中,JVM自帶的Bootstrap是根加載器,其他的加載器都有且僅有一個父類加載器。類的加載首先請求父類加載器加載,父類加載器無能為力時才由其子類加載器自行加載。JVM不會向Java程序提供對Bootstrap的引用。下面是關于幾個類加載器的說明: Bootstrap:一般用本地代碼實現,負責加載JVM基礎核心類庫(rt.jar); Extension:從java.ext.dirs系統屬性所指定的目錄中加載類庫,它的父加載器是Bootstrap; System:又叫應用類加載器,其父類是Extension。它是應用最廣泛的類加載器。它從環境變量classpath或者系統屬性java.class.path所指定的目錄中記載類,是用戶自定義加載器的默認父加載器。
5.heap和stack有什么區別。
6.java的事件委托機制和垃圾回收機制
7.GC是什么? 為什么要有GC?
8.垃圾回收的優點和原理。并考慮2種回收機制。
9.垃圾回收器的基本原理是什么?垃圾回收器可以馬上回收內存嗎?有什么辦法主動通知虛擬機進行垃圾回收?
10.什么時候用assert。
11.java中會存在內存泄漏嗎,請簡單描述。
Java的編程練習題。
一、基礎
1.如何取小數點前兩位,并四舍五入。
2.設計出計算任意正整數的階層
3.任意數字序列“123456”之類,輸出它們所有的排列組合
4.判斷身份證:要么是15位,要么是18位,最后一位可以為字母,并寫程序提出其中的年月日。
5.現在輸入n個數字,以逗號,分開;然后可選擇升或者降序排序;按提交鍵就在另一頁面顯示按什么排序,結果為,提供reset
二、數組(排序,選擇)
1.有數組a[n],用java代碼將數組元素順序顛倒
2.排序都有哪幾種方法?請列舉。用JAVA實現一個快速排序。
3.一列數的規則如下: 1、1、2、3、5、8、13、21、34...... 求第30位數是多少, 用遞歸算法實現。
4.給定一個有序的數組,如果往該數組中存儲一個元素,并保證這個數組還是有序的,那么這個元素的存儲角標位如何獲取
5.打印出九九乘法表
6.打印出三角形
7.打印數組,元素間用逗號隔開,例:[0],[1]
8.獲取數組的最大值和最小值
9.給定數組排序,遞增,冒泡
10.1~100之間 7的倍數的個數。并打印。
11.3000米長的繩子,每天減一半。問多少天這個繩子會小于5米?不考慮小數
12.打印一個矩形
13.獲取1到10 10個數的和。
三、字符串
1.如何將數字轉換為字符?
2.如何把一段逗號分割的字符串轉換成一個數組?
3.有一個字符串,其中包含中文字符、英文字符和數字字符,請統計和打印出各個字符的個數。
4.編寫一個函數將一個十六進制數的字符串參數轉換成整數返回
5.編寫一個截取字符串的函數,輸入為一個字符串和字節數,輸出為按字節截取的字符串,但要保證漢字不被截取半個,如“我ABC”,4,應該截取“我AB”,輸入“我ABC漢DEF”,6,應該輸出“我ABC”,而不是“我ABC+漢的半個”。
6.將字符串反轉
7.獲取一個字符串在另一個字符串中出現的次數
8.給定一個字符數組。按照字典順序從小到大排序
9.一個字符串在整串中出現的次數
10.兩個字符串中最大相同的字串
11.模擬一個trim功能一致的方法
四、io
1.文件讀寫,實現一個計數器
2.寫一個程序,從文件(c:\test.txt)中查出字符串”mobnet”出現的次數?
3.編寫一個程序,將a.txt文件中的單詞與b.txt文件中的單詞交替合并到c.txt文件中,a.txt文件中的單詞用回車符分隔,b.txt文件中用回車或空格進行分隔。
4.讀入文件信息,根據分隔符,存入字符串數組words中
5.編寫一個程序,將 d: \ java 目錄下的所有.java 文件復制到d: \ jad 目錄下,并 將原來文件的擴展名從.java 改為.jad
五、集合
1.ArrayList如何實現插入的數據按自定義的方式有序存放
2.請寫出一段代碼獲取結構List>中的各個Map的鍵值,并通過System.out.pringln()打印出來。
六、線程
1.設計4個線程,其中兩個線程每次對j增加1,另外兩個線程對j每次減少1。寫出程序。
2.子線程循環10次,接著主線程循環100,接著又回到子線程循環10次,接著再回到主線程又循環100,如此循環50次,請寫出程序。
3.有類似的這樣一串"abcddeffx.asre-321"!assra.."請實現以下方法將該字符串中的各個字符串出現的次數統計出來
七、類相關
1.如何取得年月日,小時分秒?
2.如何取得從 1970 年到現在的毫秒數
3.如何格式化日期?
4.編碼轉換,怎樣實現將 GB2312 編碼的字符串轉換為 ISO-8859-1 編碼的字符串。
5.判斷第二個日期比第一個日期大
八、設計模式
1.幾種單例模式
題目補充
2.寫一段代碼獲取結構 List>中各個Map,并通過System.out.println()打印出來(15)
/**
將指定的 結構為 List>的參數 通過System.out.println()打印出來
格式:"鍵名:鍵值"
@param List>
*/
3.有類似這樣的一串字符"abcddeffx.asre-321!assra..",請實現以下方法將字符串各個字符的出現的次數統計出來
/**
將指定的 結構為 List>的參數 通過System.out.println()打印出來
格式:"鍵名:鍵值"
@param List>
@return Map
*/
public Map staticCharcnt(String str){
}
4.在一個文本文件(文件大小不超過2k)中存放了很多以空格分隔的英語單詞,請寫一段偽代碼或用文字描述來實現,已得到沒有重復的、且按字典順序排序的所有單詞(20分)
5.請用javascript語言解析如下json對象,取出對象中所有數據或將其顯示在頁面上。(15)
6.在項目中一導入jquery1.7庫,請實現用jquery查找下列表格的第二行第三列的值。(15)
7.寫一個程序,從文件(c:\test.txt)中查出字符串”mobnet”出現的次數?
8.編寫一個程序,將a.txt文件中的單詞與b.txt文件中的單詞交替合并到c.txt文件中,a.txt文件中的單詞用回車符分隔,b.txt文件中用回車或空格進行分隔。
總結
以上是生活随笔為你收集整理的java上机题四取三排列_Java练习题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python语言的实验心得体会_国产编程
- 下一篇: centos 对已有卷扩容_CentOS