1. 程式人生 > >JAVA基礎面試題 三

JAVA基礎面試題 三

用最有效率的方法計算2乘以8?

  • 2 << 3(左移3位相當於乘以2的3次方,右移3位相當於除以2的3次方)。
public static void main(String[] args) {
    int a = 2;
    int b = 32;
System.out.println("2 * 8 " + (a << 3));
System.out.println("32 / 8" + (b >> 3));
}

----結果輸出---

2 * 8 :16
32 / 8:4
Process finished with exit code 0

陣列有沒有length()方法?String有沒有length()方法?

  • 陣列沒有length()方法,有length 的屬性
  • String 有length()方法
  • JavaScript中,獲得字串的長度是通過length屬性得到的,這一點容易和Java混淆。
public class UserTest {
    public static void main(String[] args) {
        String[] strings = new String[3];
System.out.println(strings.length);
System.out.println("123".length());
}

-------JavaScript 寫法如下----

$(function () {
    var str = new String("123");
var arr = new Array(5);
console.log("str.length"+str.length);
console.log("arr.length"+arr.length);

在Java中,如何跳出當前的多重巢狀迴圈?

設定迴圈條件

public static void main(String[] args) {
    /**迴圈標識*/
boolean flag = true;
    for (int i = 0; i < 10 && flag; i++) {
        for 
(int j = 0; j < 10; j++) { System.out.print(i + "" + j + " "); /**i=2j=2時退出迴圈*/ if (i == 2 && j == 2) { flag = false; break; } } } }

--------結果輸出---

00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 

Process finished with exit code 0

break + lable

public static void main(String[] args) {
    /**迴圈外邊設定標記"out:",記得帶冒號*/
out:for (int i = 0; i < 10; i++) {
        for (int j = 0; j < 10; j++) {
            System.out.print(i + "" + j +" ");
/**i=2j=3時跳出到迴圈外面的"out"
             * 跳出了就不會再進來*/
if (i == 2 && j == 3) {
                break out;
}
        }
    }
}

-------結果輸出-----------

00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 

Process finished with exit code 0

封裝成方法

public static void main(String[] args) {
    forEach();
}
public static void forEach() {
    for (int i = 0; i < 10; i++) {
        for (int j = 0; j < 10; j++) {
            System.out.print(i + "" + j + " ");
/**i=2j=4時直接方法返回,從而達到退出迴圈的目的*/
if (i == 2 && j == 4) {
                return;
}
        }
    }
}

---------結果輸出---------

00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 
Process finished with exit code 0

構造器(constructor)是否可被重寫(override)?

  • 構造器不能被繼承,因此不能被重寫,但可以被過載。
  • 構造器的方法名是必須與類名一致的

兩個物件值相同(x.equals(y) == true),但卻可有不同的hash code,這句話對不對?

  • 不對,如果兩個物件x和y滿足x.equals(y) == true,它們的雜湊碼(hash code)應當相同。
  • Java對於eqauls方法和hashCode方法是這樣規定的:(1)如果兩個物件相同(equals方法返回true),那麼它們的hashCode值一定要相同;(2)如果兩個物件的hashCode相同,它們並不一定相同。
public static void main(String[] args) {
    String str1 = new String("張無忌");
String str2 = "張無忌";
System.out.println("str1.equals(str2):"+str1.equals(str2));
System.out.println("str1.hashCode():"+str1.hashCode());
System.out.println("str2.hashCode():"+str2.hashCode());
}

----輸出結果---

str1.equals(str2):true
str1.hashCode():24235276
str2.hashCode():24235276
Process finished with exit code 0

是否可以繼承String類?

  • String 類是final類,不可以被繼承。
public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {

當一個物件被當作引數傳遞到一個方法後,此方法可改變這個物件的屬性,並可返回變化後的結果,那麼這裡到底是值傳遞還是引用傳遞?

  • 是值傳遞。Java語言的方法呼叫只支援引數的值傳遞。
  • 當一個物件例項作為一個引數被傳遞到方法中時,引數的值就是對該物件的引用。物件的屬性可以在被呼叫過程中被改變,但對物件引用的改變是不會影響到呼叫者的。

String和StringBuilder、StringBuffer的區別?

  • Java平臺提供了兩種型別的字串:String和StringBuffer/StringBuilder,它們可以儲存和操作字串。
  • String是隻讀字串,String引用的字串內容是不能被改變的
  • StringBuffer/StringBuilder類表示的字串物件可以直接進行修改。
  • StringBuilder是Java 5中引入的,它和StringBuffer的方法基本相同,區別在於它是在單執行緒環境下使用的,因為它的所有方法都沒有被synchronized修飾,因此它的效率也比StringBuffer要高。

String

  • String只適合固定不變的字串,如果需要動態修改值的不建議使用String。
public static void main(String[] args) {
    String str1 = new String("張無忌");
Long startTime = System.currentTimeMillis();
    for (int i = 0; i < 100000; i++) {
        str1 += i;
}
    Long endTime = System.currentTimeMillis();
System.out.println((endTime - startTime)+"毫秒");
}

------輸出結果-----這樣做效率是最低的-------要避免使用----

14855毫秒

Process finished with exit code 0

StringBuffer

  • 同樣的操作,StringBuffer將String的15秒縮短到了13毫米
  • StringBuffer所有的方法採用了synchronized修飾,加了物件鎖,更適合多執行緒操作
public static void main(String[] args) {
    StringBuffer str1 = new StringBuffer("張無忌");
Long startTime = System.currentTimeMillis();
    for (int i = 0; i < 100000; i++) {
        str1.append(i);
}
    Long endTime = System.currentTimeMillis();
System.out.println((endTime - startTime)+"毫秒");
}

------輸出結果----------推薦方式一--------

13毫秒
Process finished with exit code 0

StringBuilder

  • StringBuilder與StringBuffer基本一致,只是StringBuilder的方法沒有用synchronized修飾,效率更高
public static void main(String[] args) {
    StringBuilder str1 = new StringBuilder("張無忌");
Long startTime = System.currentTimeMillis();
    for (int i = 0; i < 100000; i++) {
        str1.append(i);
}
    Long endTime = System.currentTimeMillis();
System.out.println((endTime - startTime)+"毫秒");
}

------輸出結果-----推薦方式-------------

12毫秒

Process finished with exit code 0

過載(Overload)和重寫(Override)的區別。過載的方法能否根據返回型別進行區分?

Overloading 

  • 同一個類中,同名的方法如果引數列表各不相同(個數、型別、順序不同)被視為過載
  • 不能通過訪問許可權synchronized、返回值型別、丟擲異常等進行過載
  • 構造器就是典型的過載
public void show(){
    System.out.println("show()");
}

public void show(String show){
    System.out.println(show);
}
public String show(Integer showId){
    return String.valueOf(showId);
}

Overriding

  • 子類繼承父類,對父類方法的重新編寫叫方法重寫
  • 重寫方法的方法名與引數列表(引數型別、個數、順序)以及返回值型別都應該與父類相同
  • 子類的重寫方法不能丟擲比父類更多的異常,只能丟擲相同或是更少的異常,或者丟擲父類異常的子異常(因為子類的方法重寫是用來解決父類中的問題的,而不是增加問題)
  • 子類重寫方法的訪問許可權只能與父類的相同或者更大,不能縮小(必須遵循訪問更加友好的原則)
  • 父類中private修飾的方法,子類不能繼承,所以更加無法重寫
  • 父類final修飾的方法,子類可以繼承,卻不能重寫