目錄
精選牛客網鄙視題&詳解(二)
1. Java數組的使用
// 1.直接賦值
String arr[] = { "hello", "world", "DO", "You", "Love", "Me"};
// 2.通過new關鍵字
String arr1[] = new String[5];
String[] arr2 = new String[5];
// 3.初始化的同時賦值
String[] arr3 = new String[] {"hello", "world", "DO", "You", "Love", "Me"};
// 3.先定義一個數組
String[] arr4 = null;
// 賦值數組的第一個值
arr[0] = "a";
2. 原碼、反碼、補碼
-
源碼:一個正數,按照絕對值大小轉換成的二進制數;一個負數按照絕對值大小轉換成的二進制數,然後最高位補1,稱爲原碼。
-
反碼:正數的反碼與原碼相同,負數的反碼爲對該數的原碼除符號位外各位取反。
-
補碼:正數的補碼與原碼相同,負數的補碼爲對該數的原碼除符號位外各位取反,然後在最後一位加1.
補充:Java中的
>>
是無符號右移,如果該數爲正,則高位補0,若爲負數,則高位補1;
>>>
是無符號右移,也叫邏輯右移,即若該數爲正,則高位補0,而若該數爲負數,則右移後高位同樣補0。
3. 關於Java枚舉的使用
enum AccountType
{
SAVING, FIXED, CURRENT;
private AccountType()
{
System.out.println(“It is a account type”);
}
}
class EnumOne
{
public static void main(String[]args)
{
System.out.println(AccountType.FIXED);
}
}
// 執行結果
It is a account type
It is a account type
It is a account type
FIXED
/*
枚舉類有三個實例,故調用三次構造方法,打印三次It is a account type
枚舉類在後臺實現時,實際上是轉化爲一個繼承了java.lang.Enum類的實體類,原先的枚舉類型變成對應的實體類型,上例中AccountType變成了個class AccountType,並且會生成一個新的構造函數,若原來有構造函數,則在此基礎上添加兩個參數,生成新的構造函數,如上例子中:
private AccountType(){ System.out.println(“It is a account type”); }
會變成:
private AccountType(String s, int i){
super(s,i); System.out.println(“It is a account type”);
}
而在這個類中,會添加若干字段來代表具體的枚舉類型:
public static final AccountType SAVING;
public static final AccountType FIXED;
public static final AccountType CURRENT;
而且還會添加一段static代碼段:
static{
SAVING = new AccountType("SAVING", 0);
FIXED = new AccountType("FIXED", 0);
CURRENT = new AccountType("CURRENT", 0);
$VALUES = new AccountType[]{
SAVING, FIXED, CURRENT
}
}
以此來初始化枚舉中的每個具體類型。(並將所有具體類型放到一個$VALUE數組中,以便用序號訪問具體類型)
在初始化過程中new AccountType構造函數被調用了三次,所以Enum中定義的構造函數中的打印代碼被執行了3遍。
*/
4. 關於Java的垃圾回收機制
- java提供了一個系統級的線程,即垃圾回收器線程。用來對每一個分配出去的內存空間進行跟蹤。當JVM空閒時,自動回收每塊可能被回收的內存,GC是完全自動的,不能被強制執行。程序員最多隻能用System.gc()來建議執行垃圾回收器回收內存,但是具體的回收時間,是不可知的。
- 當對象的引用變量被賦值爲null,可能被當成垃圾。
5. 關於多線程是否釋放鎖資源問題
-
鄙視題
下列哪些操作會使線程釋放鎖資源? A.sleep() B.wait() C.join() D.yield() //正確答案: B C
-
sleep()方法
在指定時間內讓當前正在執行的線程暫停執行,但不會釋放“鎖標誌”。不推薦使用。
sleep()使當前線程進入阻塞狀態,在指定時間內不會執行。 -
wait()方法
在其他線程調用對象的notify或notifyAll方法前,導致當前線程等待。線程會釋放掉它所佔有的“鎖標誌”,從而使別的線程有機會搶佔該鎖。
當前線程必須擁有當前對象鎖。如果當前線程不是此鎖的擁有者,會拋出IllegalMonitorStateException異常。
喚醒當前對象鎖的等待線程使用notify或notifyAll方法,也必須擁有相同的對象鎖,否則也會拋出IllegalMonitorStateException異常。
waite()和notify()必須在synchronized函數或synchronized block中進行調用。如果在non-synchronized函數或non-synchronized block中進行調用,雖然能編譯通過,但在運行時會發生IllegalMonitorStateException的異常。 -
yield方法
暫停當前正在執行的線程對象。
yield()只是使當前線程重新回到可執行狀態,所以執行yield()的線程有可能在進入到可執行狀態後馬上又被執行。
yield()只能使同優先級或更高優先級的線程有執行的機會。 -
join方法
join()等待該線程終止。
等待調用join方法的線程結束,再繼續執行。如:t.join();//主要用於等待t線程運行結束,若無此句,main則會執行完畢,導致結果不可預測
6. 關於Java中字符串的比較
-
鄙視題
以下程序執行的結果是() public class Test { private String name = "abc"; public static void main(String[] args) { Test test = new Test(); Test testB = new Test(); String result = test.equals(testB) + ","; result += test.name.equals(testB.name) + ","; result += test.name == testB.name; System.out.println(result); } } // 執行結果 false,true,true
7. 字節流和字符流
下面的類哪些可以處理Unicode字符?
A.InputStreamReader
B.BufferedReader
C.Writer
D.PipedInputStream
//正確答案: A B C
/*
簡單地說,字符流是字節流根據字節流所要求的編碼集解析獲得的
可以理解爲字符流=字節流+編碼集
所以本題中和字符流有關的類都擁有操作編碼集(unicode)的能力。
後綴是Stream的都是字節流,其他的都是字符流。
字節流:
InputStream
|-- FileInputStream (基本文件流)
|-- BufferedInputStream
|-- DataInputStream
|-- ObjectInputStream
字符流
Reader
|-- InputStreamReader (byte->char 橋樑)
|-- BufferedReader (常用)
Writer
|-- OutputStreamWriter (char->byte 橋樑)
|-- BufferedWriter
|-- PrintWriter (常用)
*/
8. Java多線程中的wait()、notify()、notifyAll()、await()、signal()、signalAll()
以下哪幾種方式可用來實現線程間通知和喚醒:( )
A.Object.wait/notify/notifyAll
B.ReentrantLock.wait/notify/notifyAll
C.Condition.await/signal/signalAll
D.Thread.wait/notify/notifyAll
//正確答案: A C
/*
解析:
wait()、notify()和notifyAll()是 Object類 中的方法 ;
Condition是在java 1.5中才出現的,它用來替代傳統的Object的wait()、notify()實現線程間的協作,相比使用Object的wait()、 notify(),使用Condition1的await()、signal()這種方式實現線程間協作更加安全和高效。
*/
9. Java的 native 關鍵字
-
native 關鍵字是JNI的一部分
-
JNI是Java Native Interface的 縮寫。從Java 1.1開始,Java Native Interface (JNI)標準成爲java平臺的一部分,它允許Java代碼和其他語言寫的代碼進行交互。JNI一開始是爲了本地已編譯語言,尤其是C和C++而設計 的,但是它並不妨礙你使用其他語言,只要調用約定受支持就可以了。
-
使用java與本地已編譯的代碼交互,通常會喪失平臺可移植性。但是,有些情況下這樣做是可以接受的,甚至是必須的,比如,使用一些舊的庫,與硬件、操作系統進行交互,或者爲了提高程序的性能。JNI標準至少保證本地代碼能工作在任何Java 虛擬機實現下。
-
使用方法
public class HelloWorld { public native void displayHelloWorld(); static { System.loadLibrary("hello"); } public static void main(String[] args) { new HelloWorld().displayHelloWorld(); } }
-
聲明native方法:如果你想將一個方法做爲一個本地方法的話,那麼你就必須聲明改方法爲native的,並且不能實現。其中方法的參數和返回值在後面講述。
-
Load 動態庫:System.loadLibrary(“hello”);加載動態庫(我們可以這樣理解:我們的方法displayHelloWorld()沒 有實現,但是我們在下面就直接使用了,所以必須在使用之前對它進行初始化)這裏一般是以static塊進行加載的。同時需要注意的是 System.loadLibrary();的參數“hello”是動態庫的名字。
10、關於Java中 外部類、成員內部類、局部內部類的訪問修飾符問題
- 1.類指外部類,最大的類,修飾符有public(表示該類在項目所有類中可以被導入),default(該類只能在同一個package中使用),abstract,final
- 2.內部類指位於類內部但不包括位於塊、構造器、方法內,且有名稱的類,修飾符有public,private,protected訪問控制符,也可以用static,final關鍵字修飾,public和private比較簡單,一個表示所有可以被所有類訪問,一個表示只能被自身訪問,protected修飾的成員類可以被同一個包中的類和子類訪問。而default修飾的成員類只能被同一個包中的類訪問。
- 3.局部內部類指位於塊、構造器、方法內的有名稱類,最多隻能有final修飾