1、運算符優先級問題,下面代碼的結果是多少?
public class Test { public static void main(String[] args) { int k = 0; int ret = ++k + k++ + ++k + k; // ret的值為多少 System.err.println(ret); } }
解答:主要考察++i和i++的區別。++在前則先自增再賦值運算,++在后則先賦值再自增運算。因此,結果為8。
2、運算符問題,下面代碼分別輸出什么?
public class Test { public static void main(String[] args) { int i1 = 10, i2 = 10; System.err.println("i1 + i2 = " + i1 + i2); System.err.println("i1 - i2 = " + i1 - i2); System.err.println("i1 * i2 = " + i1 * i2); System.err.println("i1 / i2 = " + i1 / i2); } }
解答:主要考察兩點,運算符的優先級、字符串與數字中的+為連接符號。
第一條中,都是相加,則從前到后的順序運算,字符串與數字相加,連接為一個字符串,再與后面的數字相加,再次連接為字符串,因此結果為“i1 + i2 = 1010”。
第二條編譯錯誤,字符串無法與數字用減號連接。
第三條、第四條中乘除的優先級高,會先運算,而后再與字符串連接,因此結果分別為:“i1 * i2 = 100”、“i1 * i2 = 1”。
3、下面代碼的結果是什么?
public class Test { public void myMethod(String str) { System.err.println("string"); } public void myMethod(Object obj) { System.err.println("object"); } public static void main(String[] args) { Test t = new Test(); t.myMethod(null); } }
解答:這道題考察重載方法參數具有繼承關系時的調用問題,還有對null的認識。如果是一般具有繼承關系的對象分別作為參數,看對象的引用,如:
class A { } class B extends A { } public class Test { public static void main(String[] args) { A b1 = new B(); B b2 = new B(); get(b1);// A get(b2);// B } public static void get(A a) { System.out.println("A"); } public static void get(B a) { System.out.println("B"); } }
這道題中,Object是一切類的父類,具有繼承關系,那null是指向什么呢?null是任何引用類型的初始值,String和Object的初始值都是null,但是null會優先匹配引用類型參數為String的方法,因此這道題答案是string。假設這道題中還有其他同是引用類型的重載方法呢?如:
public void myMethod(Integer obj) {
System.err.println("Integer");
}
如果是這樣的話,調用這個方法傳入參數null時會報錯,他不知道選哪個方法進行匹配調用了。
4、假設今天是9月8日,下面代碼輸出什么?
public class Test { public static void main(String[] args) { Date date = new Date(); System.err.println(date.getMonth() + " " + date.getDate()); } }
解答:這道題考察的是日期中獲取的月份是從0開始的,因此會比我們日常的月份少1,這個題答案是8 8。
5、下面代碼的輸出結果是什么?
public class Test { public static void main(String[] args) { double val = 11.5; System.err.println(Math.round(val)); System.err.println(Math.floor(val)); System.err.println(Math.ceil(val)); } }
解答:這個是在考Math取整數的三種方法。round()是四舍五入取證,floor()是舍去小數位,ceil()是向上進一位。floor是地板ceil是天花板,一個在下,則舍去,一個在上,則向上進1。那是不是結果應該為12、11、12呢?還要考慮返回值類型,round()返回值類型為long長整型,floor()和ceil()返回值的是double類型,因此正確的答案應該是12、11.0、12.0。
6、編程輸出一個目錄下的所有目錄及文件名稱,目錄之間用tab。
public class Test { public static void main(String[] args) { new Test().read("D:/test", ""); } public void read(String path, String tab) { File file = new File(path); File[] childFiles = file.listFiles(); for (int i = 0; childFiles != null && i < childFiles.length; i++) { System.err.println(tab + childFiles[i].getName()); if (childFiles[i].isDirectory()) { read(childFiles[i].getPath(), tab + "\t"); } } } }
這個主要是考察IO部分知識點了。
7、從鍵盤讀入10個整數,然后從大到小輸出。
public class Test {
public static void main(String[] args) { Scanner in = new Scanner(System.in); // 注意這里的數組,不是int的 Integer[] arr = new Integer[10]; for (int i = 0; i < 10; i++) { arr[i] = in.nextInt(); } Arrays.sort(arr, new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { if (o1 > o2) return -1; if (o1 < o2) return 1; return 0; } }); System.err.println(Arrays.toString(arr)); } }
8、下面代碼的結果是什么?
public class Test extends Base { public static void main(String[] args) { Base b = new Test(); b.method(); Test t = new Test(); t.method(); } @Override public void method() { System.err.println("test"); } } class Base { public void method() throws InterruptedException { System.err.println("base"); } }
解答:兩次調用輸出都是test。多態的情況下,盡管是父類的引用,調用方法時,還是調用子類的方法。
9、以下代碼的結果是什么?
package test; public class Test extends Base { public static void main(String[] args) { new Test().method(); } public void method() { System.err.println(super.getClass().getName()); System.err.println(this.getClass().getSuperclass().getName()); } } class Base { }
解答:第一個輸出test.Test、第二個輸出test.Base。super很容易讓人以為也是調用了父類,實際上還是本類。
10、true or false?
public class Test { public static void main(String[] args) { String str1 = new String("abc"); String str2 = new String("abc"); System.err.println(str1.equals(str2)); StringBuffer sb1 = new StringBuffer("abc"); StringBuffer sb2 = new StringBuffer("abc"); System.err.println(sb1.equals(sb2)); } }
解答:第一個true,第二個false。String重寫了Object中的equals方法,會將string拆分為字符數組,逐個比較各個字符,代碼如下:
public boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof String) { String anotherString = (String)anObject; int n = value.length; if (n == anotherString.value.length) { char v1[] = value; char v2[] = anotherString.value; int i = 0; while (n-- != 0) { if (v1[i] != v2[i]) return false; i++; } return true; } } return false; }
Object中的equests方法如下:
public boolean equals(Object obj) {
return (this == obj);
}
11、輸出的結果是什么?
public class Test { public static void main(String[] args) { System.err.println(new Test().method1()); System.err.println(new Test().method2()); } public int method1() { int x = 1; try { return x; } finally { ++x; } } public int method2() { int x = 1; try { return x; } finally { return ++x; } } }
解答:第一個返回1,第二個返回2。finally中的代碼是一定會被執行的且在try中的代碼執行完之后,因此若在其中return返回,會覆蓋掉try中的返回值。
如果這樣呢?
public class Test { public static void main(String[] args) { System.err.println(method()); } public static boolean method() { try { return true; } finally { return false; } } }
很明顯返回值應該為false。
12、方法m1和m2有區別嗎?
public class Test { public static void main(String[] args) { } public synchronized void m1() { } public static synchronized void m2() { } }
解答:這里考察的是同步方法的問題。synchronized修飾方法時鎖定的是調用該方法的對象。它並不能使調用該方法的多個對象在執行順序上互斥,靜態修飾符很有必要。因此當不適用靜態時,創建多個對象執行該方法,鎖都不一樣,還同步什么呢,因此用static修飾后才能實現想要的效果。
13、true or false?
public class Test { public static void main(String[] args) { Integer i1 = 127; Integer i2 = 127; System.err.println(i1 == i2); i1 = 128; i2 = 128; System.err.println(i1 == i2); } }
解答:第一個為true,第二個為false。這個是對Integer包裝類型中應用的享元模式的考察。
14、true or false?
public class Test { public static void main(String[] args) { String str1 = "a"; String str2 = "a"; String str3 = new String("a"); System.err.println(str1 == str2); System.err.println(str1 == str3); str3 = str3.intern(); System.err.println(str1 == str3); } }
解答:這個是對String Pool的考察。答案為true、false、true
15、true or false?
public class Test { public static void main(String[] args) { System.err.println(12 - 11.9 == 0.1); } }
解答:結果為false。這個題我只說下我的想法,12-11.9進行運算后會轉換成對象,不在是基本數據類型,因此在進行恆等判斷時,就會是false。
16、以下代碼輸出是什么?
public class Test { public static void main(String[] args) { BigInteger one = new BigInteger("1"); BigInteger two = new BigInteger("2"); BigInteger three = new BigInteger("3"); BigInteger sum = new BigInteger("0"); sum.add(one); sum.add(two); sum.add(three); System.out.println(sum.toString()); } }
解答:這個是對大整數的考察。結果是不是6呢?看起來好像沒毛病,其實不然。sum.add(one)與我們基本類型的sum+=one可不同,前者不會講結果賦值給sum對象,結果被賦值了這條語句的返回值。因此不管怎么add,sum對象的值是沒有變化的,因此結果為0。
18、如何迭代Map容器?
---------------------------法1------------------------------ Map<String, String> map = new HashMap<>(); Set<Map.Entry<String, String>> entrySet = map.entrySet(); for(Map.Entry<String, String> entry : entrySet){ String key = entry.getKey(); String value = entry.getValue(); } -----------------------法2----------------------------------- Set<String> keySet = map.keySet(); Iterator<String> it1 = keySet.iterator(); if(it1.hasNext()) System.out.println(it1.next()); -----------------------法3--------------------------------------- Collection<String> values = map.values(); Iterator<String> it2 = values.iterator(); if(it2.hasNext()){ System.out.println(it2.next());
19、以下代碼輸出的結果
public class Test { public static void main(String[] args) { System.err.println(args.length); } }
/*
A. null B. 0 C. Test
D. Exception in thread "main" java.lang.NullPointerException
*/
解答:0.
20、下面為一個單例的實現代碼,請指出代碼中有幾個錯誤或不合理之處,並改正。
public class Test { public Test instance = null; public static Test getInstance() { if (instance == null) { instance = new Test(); return instance; } } }
解答:單例模式要滿足三點:1、私有化構造方法;2、創建私有靜態對象;3、提供公有靜態方法獲取唯一實例。
因此錯誤包含,1構造函數沒有私有化,2對象非私有靜態,3獲取實例的方法中return不應包含在條件中。