都是一些非常非辰闳基礎的題航背,是我最近參加各大IT公司筆試后靠記憶記下來的,經過整理獻給與我一樣參加各大IT校園招聘的同學們巫击,純考Java基礎功底禀晓,老手們就不用進來了,免得笑話我們這些未出校門的孩紙們坝锰,但是IT公司就喜歡考這些基礎的東西粹懒,所以為了能進大公司就當復習期末考吧∏昙叮花了不少時間整理凫乖,在整理過程中也學到了很多東西,請大家認真對待每一題~~
下面都是我自己的答案非官方弓颈,僅供參考帽芽,如果有疑問或錯誤請一定要提出來,大家一起進步啦~~~
- 下面哪些是Thread類的方法()
A start() B run() C exit() D getPriority()
答案:ABD
解析:看Java API docs吧:http://docs.oracle.com/javase/7/docs/api/翔冀,exit()是System類的方法导街,如System.exit(0)。
- 下面關于java.lang.Exception類的說法正確的是()
A 繼承自Throwable B Serialable CD 不記得纤子,反正不正確
答案:A
解析:Java異常的基類為java.lang.Throwable菊匿,java.lang.Error和java.lang.Exception繼承 Throwable付呕,RuntimeException和其它的Exception等繼承Exception,具體的RuntimeException繼承RuntimeException跌捆。
擴展:錯誤和異常的區(qū)別(Error vs Exception)
java.lang.Error: Throwable的子類徽职,用于標記嚴重錯誤。合理的應用程序不應該去try/catch這種錯誤佩厚。絕大多數的錯誤都是非正常的,就根本不該出現(xiàn)的潮瓶。
java.lang.Exception: Throwable的子類,用于指示一種合理的程序想去catch的條件煞额。即它僅僅是一種程序運行條件胀莹,而非嚴重錯誤婚温,并且鼓勵用戶程序去catch它荆秦。Error和RuntimeException 及其子類都是未檢查的異常(unchecked exceptions),而所有其他的Exception類都是檢查了的異常(checked exceptions).
checked exceptions: 通常是從一個可以恢復的程序中拋出來的搪哪,并且最好能夠從這種異常中使用程序恢復。比如FileNotFoundException, ParseException等漓概。檢查了的異常發(fā)生在編譯階段胃珍,必須要使用try…catch(或者throws)否則編譯不通過觅彰。
unchecked exceptions: 通常是如果一切正常的話本不該發(fā)生的異常烛芬,但是的確發(fā)生了赘娄。發(fā)生在運行期遣臼,具有不確定性揍堰,主要是由于程序的邏輯問題所引起的。比如ArrayIndexOutOfBoundException, ClassCastException等西采。從語言本身的角度講械馆,程序不該去catch這類異常,雖然能夠從諸如RuntimeException這樣的異常中catch并恢復尾菇,但是并不鼓勵終端程序員這么做派诬,因為完全沒要必要默赂。因為這類錯誤本身就是bug缆八,應該被修復奈辰,出現(xiàn)此類錯誤時程序就應該立即停止執(zhí)行底哥。 因此趾徽,面對Errors和unchecked exceptions應該讓程序自動終止執(zhí)行,程序員不該做諸如try/catch這樣的事情了袁,而是應該查明原因载绿,修改代碼邏輯。
RuntimeException:RuntimeException體系包括錯誤的類型轉換怕享、數組越界訪問和試圖訪問空指針等等。
處理RuntimeException的原則是:如果出現(xiàn) RuntimeException跌帐,那么一定是程序員的錯誤。例如即舌,可以通過檢查數組下標和數組邊界來避免數組越界訪問異常肥惭。其他(IOException等等)checked異常一般是外部錯誤,例如試圖從文件尾后讀取數據等牵囤,這并不是程序本身的錯誤揭鳞,而是在應用環(huán)境中出現(xiàn)的外部錯誤野崇。
- 下面程序的運行結果是()
String str1 = "hello";
String str2 = "he" + new String("llo");
System.err.println(str1 == str2);
答案:false
解析:因為str2中的llo是新申請的內存塊乓梨,而==判斷的是對象的地址而非值,所以不一樣臭觉。如果是String str2 = str1,那么就是true了菱肖。
- 下列說法正確的有()
A. class中的constructor不可省略
B. constructor必須與class同名旭从,但方法不能與class同名
C. constructor在一個對象被new時執(zhí)行
D.一個class只能定義一個constructor
答案:C
解析:這里可能會有誤區(qū)稳强,其實普通的類方法是可以和類名同名的,和構造方法唯一的區(qū)分就是和悦,構造方法沒有返回值退疫。
- 具體選項不記得,但用到的知識如下:
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
- 下面程序的運行結果:()
public static void main(String args[]) {
Thread t = new Thread() {
public void run() {
pong();
}
};
t.run();
System.out.print("ping");
}
static void pong() {
System.out.print("pong");
}
A pingpong B pongping C pingpong和pongping都有可能 D 都不輸出
答案:
B
解析:這里考的是Thread類中start()和run()方法的區(qū)別了鸽素。start()用來啟動一個線程褒繁,當調用start方法后,系統(tǒng)才會開啟一個新的線程,進而調用run()方法來執(zhí)行任務磨澡,而單獨的調用run()就跟調用普通方法是一樣的尉共,已經失去線程的特性了剧蚣。因此在啟動一個線程的時候一定要使用start()而不是run()。
7. 下列屬于關系型數據庫的是()
A. Oracle B MySql C IMS D MongoDB
答案:
AB
解答:IMS(Information Management System )數據庫是IBM公司開發(fā)的兩種數據庫類型之一;
一種是關系數據庫洞拨,典型代表產品:DB2启泣;
另一種則是層次數據庫芭梯,代表產品:IMS層次數據庫累奈。
非關系型數據庫有MongoDB请敦、
memcachedb桥滨、Redis等
邀杏。
8. GC線程是否為守護線程小泉?()
答案:是
解析:線程分為守護線程和非守護線程(即用戶線程)。
只要當前JVM實例中尚存在任何一個非守護線程沒有結束,守護線程就全部工作;只有當最后一個非守護線程結束時喳瓣,守護線程隨著JVM一同結束工作仿滔。
守護線程最典型的應用就是 GC (垃圾回收器)
9. volatile關鍵字是否能保證線程安全惠毁?()
答案:不能
解析:volatile關鍵字用在多線程同步中,
可保證讀取的可見性,JVM只是保證從主內存加載到線程工作內存的值是最新的讀取值驴一,而非cache中洒嗤。但
多個線程對
volatile的寫操作跃洛,無法保證線程安全率触。
例如假如線程1,線程2 在進行read,load 操作中汇竭,發(fā)現(xiàn)主內存中count的值都是5葱蝗,那么都會加載這個最新的值,在線程1堆count進行修改之后细燎,會write到主內存中两曼,主內存中的count變量就會變?yōu)?;線程2由于已經進行read,load操作玻驻,在進行運算之后合愈,也會更新主內存count的變量值為6;導致兩個線程及時用volatile關鍵字修改之后,還是會存在并發(fā)的情況佛析。
10. 下列說法正確的是()
A LinkedList繼承自List
B AbstractSet繼承自Set
C HashSet繼承自AbstractSet
D WeakMap繼承自HashMap
答案:AC
解析:
下面是一張下載的Java中的集合類型的繼承關系圖益老,一目了然。
11. 存在使i + 1 < i的數嗎()
答案:存在
解析:如果i為int型寸莫,那么當i為int能表示的最大整數時捺萌,i+1就溢出變成負數了,此時不就<i了嗎膘茎。
擴展:存在使i > j || i <= j不成立的數嗎()
答案:存在
解析:比如Double.NaN或Float.NaN
12. 0.6332的數據類型是()
A float B double C Float D Double
答案:B
解析:默認為double型桃纯,如果為float型需要加上f顯示說明,即0.6332f
13. 下面哪個流類屬于面向字符的輸入流( )
A BufferedWriter
B FileInputStream
C ObjectInputStream
D InputStreamReader
答案:D
解析:Java的IO操作中有面向字節(jié)(Byte)和面向字符(Character)兩種方式披坏。
面向字節(jié)的操作為以8位為單位對二進制的數據進行操作态坦,對數據不進行轉換,這些類都是InputStream和OutputStream的子類棒拂。
面向字符的操作為以字符為單位對數據進行操作伞梯,在讀的時候將二進制數據轉為字符,在寫的時候將字符轉為二進制數據帚屉,這些類都是Reader和Writer的子類谜诫。
總結:以InputStream(輸入)/OutputStream(輸出)為后綴的是字節(jié)流; 以Reader(輸入)/Writer(輸出)為后綴的是字符流攻旦。
擴展:Java流類圖結構喻旷,一目了然,解決大部分選擇題:
14. Java接口的修飾符可以為()
A private B protected C final D abstract
答案:CD
解析:接口很重要牢屋,為了說明情況且预,這里稍微啰嗦點:
(1)接口用于描述系統(tǒng)對外提供的所有服務,因此接口中的成員常量和方法都必須是公開(public)類型的,確保外部使用者能訪問它們;
(2)接口僅僅描述系統(tǒng)能做什么,但不指明如何去做,所以接口中的方法都是抽象(abstract)方法烙无;
(3)接口不涉及和任何具體實例相關的細節(jié),因此接口沒有構造方法,不能被實例化,沒有實例變量辣之,只有靜態(tài)(static)變量;
(4)
接口的中的變量是所有實現(xiàn)類共有的皱炉,既然共有怀估,肯定是不變的東西,因為變化的東西也不能夠算共有合搅。所以變量是不可變(final)類型多搀,也就是常量了。
(5)
接口中不可以定義變量灾部?如果接口可以定義變量康铭,但是接口中的方法又都是抽象的,在接口中無法通過行為來修改屬性赌髓。有的人會說了从藤,沒有關系催跪,可以通過 實現(xiàn)接口的對象的行為來修改接口中的屬性。這當然沒有問題夷野,但是考慮這樣的情況懊蒸。如果接口 A 中有一個public 訪問權限的靜態(tài)變量 a。按照 Java 的語義悯搔,我們可以不通過實現(xiàn)接口的對象來訪問變量 a骑丸,通過 A.a = xxx; 就可以改變接口中的變量 a 的值了。正如抽象類中是可以這樣做的妒貌,那么實現(xiàn)接口 A 的所有對象也都會自動擁有這一改變后的 a 的值了通危,也就是說一個地方改變了 a,所有這些對象中 a 的值也都跟著變了灌曙。這和抽象類有什么區(qū)別呢菊碟,怎么體現(xiàn)接口更高的抽象級別呢,怎么體現(xiàn)接口提供的統(tǒng)一的協(xié)議呢在刺,那還要接口這種抽象來做什么呢逆害?所以接口中 不能出現(xiàn)變量,如果有變量增炭,就和接口提供的統(tǒng)一的抽象這種思想是抵觸的。所以接口中的屬性必然是常量拧晕,只能讀不能改隙姿,這樣才能為實現(xiàn)接口的對象提供一個統(tǒng) 一的屬性。
通俗的講厂捞,你認為是要變化的東西输玷,就放在你自己的實現(xiàn)中,不能放在接口中去靡馁,接口只是對一類事物的屬性和行為更高層次的抽象欲鹏。對修改關閉,對擴展(不同的實現(xiàn) implements)開放臭墨,接口是對開閉原則的一種體現(xiàn)赔嚎。
所以:
接口的方法默認是public abstract;
接口中不可以定義變量即只能定義常量(加上final修飾就會變成常量)胧弛。
所以接口的屬性默認是public static final 常量尤误,且必須賦初值
。
注意:final和abstract不能同時出現(xiàn)结缚。
15. 不通過構造函數也能創(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)都會明確的顯式的調用構造函數 最冰;(3)是在內存上對已有對象的影印瘦棋,所以不會調用構造函數 ;(4)是從文件中還原類的對象锌奴,也不會調用構造函數兽狭。java學習群669823128
16. ArrayList list = new ArrayList(20);中的list擴充幾次()
A 0 B 1 C 2 D 3
答案:A
解析:這里有點迷惑人,大家都知道默認ArrayList的長度是10個鹿蜀,所以如果你要往list里添加20個元素肯定要擴充一次(擴充為原來的1.5倍)箕慧,但是這里顯示指明了需要多少空間,所以就一次性為你分配這么多空間茴恰,也就是不需要擴充了颠焦。
17. 下面哪些是對稱加密算法()
A DES B AES C DSA D RSA
答案:AB
解析:常用的對稱加密算法有:
DES、3DES往枣、RC2伐庭、RC4、AES
常用的非對稱加密算法有:RSA分冈、DSA圾另、ECC
使用單向散列函數的加密算法:MD5、SHA
18.新建一個流對象雕沉,下面哪個選項的代碼是錯誤的集乔?()
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
解析:請記得13題的那個圖嗎坡椒?Reader只能用FileReader進行實例化。
19. 下面程序能正常運行嗎()
public class NULL {
public static void haha(){
System.out.println("haha");
}
public static void main(String[] args) {
((NULL)null).haha();
}
}
答案:
能正常運行
解析:輸出為haha汗唱,因為null值可以強制轉換為任何java類類型,(String)null也是合法的。但null強制轉換后是無效對象丈攒,其返回值還是為null,而static方法的調用是和類名綁定的巡验,不借助對象進行訪問所以能正確輸出。反過來深碱,沒有static修飾就只能用對象進行訪問腹鹉,使用null調用對象肯定會報空指針錯了敷硅。這里和C++很類似愉阎。
20. 下面程序的運行結果是什么()
class HelloA {
public HelloA() {
System.out.println("HelloA");
}
{ System.out.println("I'm A class"); }
static { System.out.println("static A"); }
}
public class HelloB extends HelloA {
public HelloB() {
System.out.println("HelloB");
}
{ System.out.println("I'm B class"); }
static { System.out.println("static B"); }
public static void main(String[] args) {
new HelloB();
}
}
答案:
static A
static B
I'm A class
HelloA
I'm B class
HelloB
解析:說實話我覺得這題很好榜旦,考查靜態(tài)語句塊景殷、構造語句塊(就是只有大括號的那塊)以及構造函數的執(zhí)行順序。
對象的初始化順序:(1)類加載之后咐旧,按從上到下(從父類到子類)執(zhí)行被static修飾的語句铣墨;(2)當static語句執(zhí)行完之后,再執(zhí)行main方法办绝;(3)如果有語句new了自身的對象孕蝉,將從上到下執(zhí)行構造代碼塊、構造器(兩者可以說綁定在一起)超埋。
下面稍微修改下上面的代碼骤肛,以便更清晰的說明情況:
class HelloA {
**java學習群669823128**
public HelloA() {
System.out.println("HelloA");
}
{ System.out.println("I'm A class"); }
static { System.out.println("static A"); }
}
public class HelloB extends HelloA {
public HelloB() {
System.out.println("HelloB");
}
{ System.out.println("I'm B class"); }
static { System.out.println("static B"); }
public static void main(String[] args) {
System.out.println("-------main start-------");
new HelloB();
new HelloB();
System.out.println("-------main end-------");
}
}
此時輸出結果為:
static A
static B
-------main start-------
I'm A class
HelloA
I'm B class
HelloB
I'm A class
HelloA
I'm B class
HelloB
-------main end-------
- getCustomerInfo()方法如下窍蓝,try中可以捕獲三種類型的異常,如果在該方法運行中產生了一個IOException淑玫,將會輸出什么結果()
public void getCustomerInfo() {
try {
// do something that may cause an Exception
} catch (java.io.FileNotFoundException ex) {
System.out.print("FileNotFoundException!");
} catch (java.io.IOException ex) {
System.out.print("IOException!");
} catch (java.lang.Exception ex) {
System.out.print("Exception!");
}
}
A IOException!
BIOException!Exception!
CFileNotFoundException!IOException!
DFileNotFoundException!IOException!Exception!
答案:A
解析:考察多個catch語句塊的執(zhí)行順序絮蒿。當用多個catch語句時叁鉴,catch語句塊在次序上有先后之分幌墓。從最前面的catch語句塊依次先后進行異常類型匹配冀泻,這樣如果父異常在子異常類之前弹渔,那么首先匹配的將是父異常類溯祸,子異常類將不會獲得匹配的機會焦辅,也即子異常類型所在的catch語句塊將是不可到達的語句。所以欧募,一般將父類異常類即Exception老大放在catch語句塊的最后一個跟继。
- 下面代碼的運行結果為:()
import java.io.*;
import java.util.*;
public class foo{
public static void main (String[] args){
String s;
System.out.println("s=" + s);
}
}
A 代碼得到編譯镣丑,并輸出“s=”
B 代碼得到編譯莺匠,并輸出“s=null”
C 由于String s沒有初始化,代碼不能編譯通過
D 代碼得到編譯摇庙,但捕獲到 NullPointException異常
答案:C
解析:開始以為會輸出null什么的卫袒,運行后才發(fā)現(xiàn)Java中所有定義的基本類型或對象都必須初始化才能輸出值单匣。
- System.out.println("5" + 2);的輸出結果應該是()户秤。
A 52 B7 C2 D5
答案:A
解析:沒啥好說的,Java會自動將2轉換為字符串转砖。
- 指出下列程序運行的結果 ()
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府蔗、 good and abc
B礁竞、 good and gbc
C、 test ok and abc
D捶朵、 test ok and gbc
答案:B
解析:大家可能以為Java中String和數組都是對象所以肯定是對象引用综看,然后就會選D岖食,其實這是個很大的誤區(qū):因為在java里沒有引用傳遞泡垃,只有值傳遞
這個值指的是實參的地址的拷貝,得到這個拷貝地址后忠寻,你可以通過它修改這個地址的內容(引用不變)存和,因為此時這個內容的地址和原地址是同一地址捐腿,
但是你不能改變這個地址本身使其重新引用其它的對象茄袖,也就是值傳遞,可能說的不是很清楚寺鸥,下面給出一個完整的能說明情況的例子吧:
package test;
/**
* @description Java中沒有引用傳遞只有值傳遞
*
* @author Alexia
* @date 2013-10-16
*
*/
class Person {
private String name;
private String sex;
public Person(String x, String y) {
this.name = x;
this.sex = y;
}
// 重寫toString()方法席吴,方便輸出
public String toString() {
return name + " " + sex;
}
// 交換對象引用
public static void swapObject(Person p1, Person p2) {
Person tmp = p1;
p1 = p2;
p2 = tmp;
}
// 交換基本類型
public static void swapInt(int a, int b) {
int tmp = a;
a = b;
b = tmp;
}
// 交換對象數組
public static void swapObjectArray(Person[] p1, Person[] p2) {
Person[] tmp = p1;
p1 = p2;
p2 = tmp;
}
// 交換基本類型數組
public static void swapIntArray(int[] x, int[] y) {
int[] tmp = x;
x = y;
y = tmp;
}
// 改變對象數組中的內容
public static void changeObjectArray(Person[] p1, Person[] p2) {
Person tmp = p1[1];
p1[1] = p2[1];
p2[1] = tmp;
// 再將p1[1]修改
Person p = new Person("wjl", "male");
p1[1] = p;
}
// 改變基本類型數組中的內容
public static void changeIntArray(int[] x, int[] y) {
int tmp = x[1];
x[1] = y[1];
y[1] = tmp;
x[1] = 5;
}
}
public class ByValueTest {
public static void main(String[] args) {
// 建立并構造兩個對象
Person p1 = new Person("Alexia", "female");
Person p2 = new Person("Edward", "male");
System.out.println("對象交換前:p1 = " + p1.toString());
System.out.println("對象交換前:p2 = " + p2.toString());
// 交換p1對象和p2對象
Person.swapObject(p1, p2);
// 從交換結果中看出唆缴,實際對象并未交換
System.out.println("\n對象交換后:p1 = " + p1.toString());
System.out.println("對象交換后:p2 = " + p2.toString());
// 建立兩個對象數組
Person[] arraya = new Person[2];
Person[] arrayb = new Person[2];
// 分別構造數組對象
arraya[0] = new Person("Alexia", "female");
arraya[1] = new Person("Edward", "male");
arrayb[0] = new Person("jmwang", "female");
arrayb[1] = new Person("hwu", "male");
System.out.println('\n' + "對象數組交換前:arraya[0] = "
+ arraya[0].toString() + ", arraya[1] = "
+ arraya[1].toString());
System.out.println("對象數組交換前:arrayb[0] = "
+ arrayb[0].toString() + ", arrayb[1] = "
+ arrayb[1].toString());
// 交換這兩個對象數組
Person.swapObjectArray(arraya, arrayb);
System.out.println('\n' + "對象數組交換后:arraya[0] = "
+ arraya[0].toString() + ", arraya[1] = "
+ arraya[1].toString());
System.out.println("對象數組交換后:arrayb[0] = "
+ arrayb[0].toString() + ", arrayb[1] = "
+ arrayb[1].toString());
// 建立兩個普通數組
int[] a = new int[2];
int[] b = new int[2];
// 給數組個元素賦值
for (int i = 0; i < a.length; i++) {
a[i] = i;
b[i] = i + 1;
}
System.out.println('\n' + "基本類型數組交換前:a[0] = " + a[0] + ", a[1] = " + a[1]);
System.out.println("基本類型數組交換前:b[0] = " + b[0] + ", b[1] = " + b[1]);
// 交換兩個基本類型數組
Person.swapIntArray(a, b);
System.out.println('\n' + "基本類型數組交換后:a[0] = " + a[0] + ", a[1] = " + a[1]);
System.out.println("基本類型數組交換后:b[0] = " + b[0] + ", b[1] = " + b[1]);
// 改變對象數組的內容
Person.changeObjectArray(arraya, arrayb);
System.out.println('\n' + "對象數組內容交換并改變后:arraya[1] = " + arraya[1].toString());
System.out.println("對象數組內容交換并改變后:arrayb[1] = " + arrayb[1].toString());
// 改變基本類型數組的內容
Person.changeIntArray(a, b);
System.out.println('\n' + "基本類型數組內容交換并改變后:a[1] = " + a[1]);
System.out.println("基本類型數組內容交換并改變后:b[1] = " + b[1]);
}
}
程序有些啰嗦,但能反映問題复罐,該程序運行結果為:
對象交換前:p1 = Alexia female
對象交換前:p2 = Edward male
對象交換后:p1 = Alexia female
對象交換后:p2 = Edward male
對象數組交換前:arraya[0] = Alexia female, arraya[1] = Edward male
對象數組交換前:arrayb[0] = jmwang female, arrayb[1] = hwu male
對象數組交換后:arraya[0] = Alexia female, arraya[1] = Edward male
對象數組交換后:arrayb[0] = jmwang female, arrayb[1] = hwu male
基本類型數組交換前:a[0] = 0, a[1] = 1
基本類型數組交換前:b[0] = 1, b[1] = 2
基本類型數組交換后:a[0] = 0, a[1] = 1
基本類型數組交換后:b[0] = 1, b[1] = 2
對象數組內容交換并改變后:arraya[1] = wjl male
對象數組內容交換并改變后:arrayb[1] = Edward male
基本類型數組內容交換并改變后:a[1] = 5
基本類型數組內容交換并改變后:b[1] = 1
說明:不管是對象效诅、基本類型還是對象數組乱投、基本類型數組,在函數中都不能改變其實際地址但能改變其中的內容剑刑。
- 要從文件"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(9); int c=in.readByte();
答案:A?D?
解析:long skip(long n)作用是跳過n個字節(jié)不讀施掏,主要用在包裝流中的其监,因為一般流(如FileInputStream)只能順序一個一個的讀不能跳躍讀限匣,但是包裝流可以用skip方法跳躍讀取米死。那么什么是包裝流呢?各種字節(jié)節(jié)點流類究西,它們都只具有讀寫字節(jié)內容的方法物喷,以FileInputStream與FileOutputStream為例峦失,它們只能在文件中讀取或者向文件中寫入字節(jié)尉辑,在實際應用中我們往往需要在文件中讀取或者寫入各種類型的數據,就必須先將其他類型的數據轉換成字節(jié)數組后寫入文件卓练,或者從文件中讀取到的字節(jié)數組轉換成其他數據類型,想想都很麻煩V雒础拱撵!因此想通過FileOutputStream將一個浮點小數寫入到文件中或將一個整數寫入到文件時是非常困難的表蝙。這時就需要包裝類DataInputStream/DataOutputStream府蛇,它提供了往各種輸入輸出流對象中讀入或寫入各種類型的數據的方法汇跨。
DataInputStream/DataOutputStream并沒有對應到任何具體的流設備,一定要給它傳遞一個對應具體流設備的輸入或輸出流對象函匕,完成類似 DataInputStream/DataOutputStream功能的類就是一個包裝類蚪黑,也叫過濾流類或處理流類。它對InputOutStream/OutputStream流類進行了包裝抒寂,使編程人員使用起來更方便掠剑。其中DataInputStream包裝類的構造函數語法:public DataInputStream(InputStream in)朴译。包裝類也可以包裝另外一個包裝類眠寿。
首先BC肯定 是錯的,那A正確嗎姆另?按上面的解析應該也不對迹辐,但我試了下甚侣,發(fā)現(xiàn)A也是正確的殷费,與網上解析的資料有些出入
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileStreamTest {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
FileOutputStream out = new FileOutputStream("file.dat");
byte[] b = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
out.write(b);
out.close();
FileInputStream in = new FileInputStream("file.dat");
in.skip(9); // 跳過前面的9個字節(jié)
int c = in.read();
System.out.println(c); // 輸出為10
in.close();
}
}
那么D呢详羡,RandomAccessFile是IO包的類,但是其自成一派水泉,從Object直接繼承而來草则】缓幔可以對文件進行讀取和寫入葡粒。支持文件的隨機訪問嗽交,即可以隨機讀取文件中的某個位置內容,這么說RandomAccessFile肯定可以達到題目的要求腔寡,但是選項有些錯誤放前,比如RandomAccessFile的初始化是兩個參數而非一個參數糯彬,采用的跳躍讀取方法是skipBytes()而非skip()撩扒,即正確的寫法是:
RandomAccessFile in = new RandomAccessFile("file.dat", "r");
in.skipBytes(9);
int c = in.readByte();
這樣也能讀到第十個字節(jié),也就是A和D都能讀到第十個字節(jié)豪墅,那么到底該選哪個呢黔寇?A和D有啥不同嗎缝裤?求大神解答~~~
- 下列哪種異常是檢查型異常憋飞,需要在編寫程序時聲明 ()
ANullPointerException BClassCastException CFileNotFoundException D IndexOutOfBoundsException
答案:C
解析:看第2題的解析。
- 下面的方法叨粘,當輸入為2的時候返回值是多少?()
public static int getValue(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;
}
A0 B2 C4 D10
答案:D
解析:注意這里case后面沒有加break升敲,所以從case 2開始一直往下運行驴党。
- 選項中哪一行代碼可以替換題目中//add code here而不產生編譯錯誤获茬?()
public abstract class MyClass {
public int constInt = 5;
//add code here
public void method() {
}
}
Apublic abstract void method(int a);
B constInt = constInt + 5;
C public int method();
D public abstract void anotherMethod() {}
答案:A
解析:考察抽象類的使用恕曲。
抽象類遵循的原則:
(1)abstract關鍵字只能修飾類和方法佩谣,不能修飾字段茸俭。
(2)抽象類不能被實例化(無法使用new關鍵字創(chuàng)建對象實例),只能被繼承艇炎。
(3)抽象類可以包含屬性缀踪,方法,構造方法奏候,初始化塊鼻由,內部類厚棵,枚舉類婆硬,和普通類一樣彬犯,普通方法一定要實現(xiàn)查吊,變量可以初始化或不初始化但不能初始化后在抽象類中重新賦值或操作該變量(只能在子類中改變該變量)逻卖。
(4)抽象類中的抽象方法(加了abstract關鍵字的方法)不能實現(xiàn)评也。
(5)含有抽象方法的類必須定義成抽象類。
擴展:抽象類和接口的區(qū)別坤邪,做個總結吧:
(1)接口是公開的艇纺,里面不能有私有的方法或變量喂饥,是用于讓別人使用的员帮,而抽象類是可以有私有方法或私有變量的导饲。
(2)abstract class 在 Java 語言中表示的是一種繼承關系,一個類只能使用一次繼承關系氢哮。但是冗尤,一個類卻可以實現(xiàn)多個interface胀溺,實現(xiàn)多重繼承仓坞。接口還有標識(里面沒有任何方法无埃,如Remote接口)和數據共享(里面的變量全是常量)的作用嫉称。
(3)在abstract class 中可以有自己的數據成員,也可以有非abstarct的成員方法壳繁,而在interface中氮趋,只能夠有靜態(tài)的不能被修改的數據成員(也就是必須是 static final的剩胁,不過在 interface中一般不定義數據成員)祥国,所有的成員方法默認都是 public abstract 類型的舌稀。
(4)abstract class和interface所反映出的設計理念不同壁查。其實abstract class表示的是"is-a"關系睡腿,interface表示的是"has-a"關系。
(5)實現(xiàn)接口的一定要實現(xiàn)接口里定義的所有方法纤控,而實現(xiàn)抽象類可以有選擇地重寫需要用到的方法船万,一般的應用里骨田,最頂級的是接口盛撑,然后是抽象類實現(xiàn)接口抵卫,最后才到具體類實現(xiàn)介粘。抽象類中可以有非抽象方法晚树。接口中則不能有實現(xiàn)方法爵憎。
(6)接口中定義的變量默認是public static final 型宝鼓,且必須給其初值愚铡,所以實現(xiàn)類中不能重新定義沥寥,也不能改變其值。抽象類中的變量默認是 friendly 型片橡,其值可以在子類中重新定義捧书,也可以在子類中重新賦值鳄厌。
- 閱讀Shape和Circle兩個類的定義荞胡。在序列化一個Circle的對象circle到文件時,下面哪個字段會被保存到文件中了嚎? ( )
class Shape {
public String name;
}
class Circle extends Shape implements Serializable{
**java學習群669823128**
private float radius;
transient int color;
public static String type = "Circle";
}
Aname
B radius
C color
D type
答案:B
30.下面是People和Child類的定義和構造方法泪漂,每個構造方法都輸出編號。在執(zhí)行new Child("mike")的時候都有哪些構造方法被順序調用歪泳?請選擇輸出結果 ( )
class People {
String name;
public People() {
System.out.print(1);
}
public People(String name) {
System.out.print(2);
this.name = name;
}
}
class Child extends People {
People father;
public Child(String name) {
System.out.print(3);
this.name = name;
father = new People(name + ":F");
}
public Child() {
System.out.print(4);
}
}
A312 B 32 C 432 D 132
答案:D
解析:考察的又是父類與子類的構造函數調用次序萝勤。在Java中,子類的構造過程中必須調用其父類的構造函數呐伞,是因為有繼承關系存在時,子類要把父類的內容繼承下來伶氢。但如果父類有多個構造函數時趟径,該如何選擇調用呢?
第一個規(guī)則:子類的構造過程中癣防,必須調用其父類的構造方法蜗巧。一個類,如果我們不寫構造方法蕾盯,那么編譯器會幫我們加上一個默認的構造方法(就是沒有參數的構造方法)幕屹,但是如果你自己寫了構造方法,那么編譯器就不會給你添加了级遭,所以有時候當你new一個子類對象的時候望拖,肯定調用了子類的構造方法,但是如果在子類構造方法中我們并沒有顯示的調用基類的構造方法挫鸽,如:super(); 這樣就會調用父類沒有參數的構造方法说敏。
第二個規(guī)則:如果子類的構造方法中既沒有顯示的調用基類構造方法,而基類中又沒有無參的構造方法掠兄,則編譯出錯像云,所以,通常我們需要顯示的:super(參數列表)蚂夕,來調用父類有參數的構造函數迅诬,此時無參的構造函數就不會被調用。
總之婿牍,一句話:子類沒有顯示調用父類構造函數侈贷,不管子類構造函數是否帶參數都默認調用父類無參的構造函數,若父類沒有則編譯出錯。
最后俏蛮,給大家出個思考題:下面程序的運行結果是什么撑蚌?
public class Dervied extends Base {
private String name = "dervied";
public Dervied() {
tellName();
printName();
}
public void tellName() {
System.out.println("Dervied tell name: " + name);
}
public void printName() {
System.out.println("Dervied print name: " + name);
}
public static void main(String[] args){
new Dervied();
}
}
class Base {
private String name = "base";
public Base() {
tellName();
printName();
}
public void tellName() {
System.out.println("Base tell name: " + name);
}
public void printName() {
System.out.println("Base print name: " + name);
}
}
java學習群669823128