精選牛客網鄙視題&詳解(二)【Java部分】

精選牛客網鄙視題&詳解(二)

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修飾
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章