1. 程式人生 > >java常見面試基礎問題整理

java常見面試基礎問題整理

1、short s1 = 1; s1 = s1 + 1;有錯嗎?short s1 = 1; s1 += 1;有錯嗎?

答案:s1 = s1+1 ; 會提示“cannot convert from int to short”,1本身是int型別,而s1是短整型,所以他們二者運算結果是int型別,要想使表示式成立,需要將結果強制轉換成short型別
s1+=1;相當於s1 = (short)(s1 + 1);其中有隱含的強制型別轉換。所以編譯不會有問題。

2、int和Integer的區別?

答案:8大資料型別:(在棧中可以直接分配記憶體的資料是基本資料型別)

        整型:char、short、int、long

        浮點型:float、double

        邏輯型:boolean

        字元型:char

        基本資料型別和引用資料型別:

        基本資料型別:在棧中可以直接分配記憶體的資料是基本資料型別。

        引用資料型別:資料的引用在棧中,但是它的物件在堆中。

        對應位元組數:

        boolean:1/8個(一個位元組有8bit(位)boolean只有true和false兩個邏輯值,在編譯後的值是用0和1來表示,他們在記憶體中按位來計算,只需要一位就能表示)

        byte:1個(位元組型)

        char:2個(字元型,一個char只能儲存一個漢字)

        short:2個(短整型)

        int:4個(整數型別)

        long:8個(長整型)

        float:4個(浮點型)

        double:8個(雙精度型別 )

        java中預設的整數型別是int型,如果要定義成float型,需要在後面加上l或者L

        java中預設的浮點型是double,如果要定義成float型,需要在後面加上f或者F

        小可轉大,大轉小會丟失精度。

        對應的封裝類:

        boolean→Boolean        

        char→Character

        byte→Byte

        short→Short

        int→Integer

        long→Long

        float→Float

        double→Double

        正題:int和Integer的區別?

        (1)Integer是int提供的封裝類。int是基本資料型別中的一種。

        (2)Integer的預設值是null。int的預設值是0 。

        (3)Integer是一個物件,需要一個引用來指向這個物件,int是基本資料型別, 直接儲存在記憶體中。

        (4)宣告為Integer的變數需要例項化,宣告為int的變數不需要例項化。

3、java中的堆和棧?

java中把記憶體分為兩種,一種是堆記憶體,一種是棧記憶體。

靜態儲存分配:是指在編譯時就能確定每個資料目標在執行時的儲存空間需求,即在編譯時就能對應的給它分配對應的固定的記憶體空間。

棧式儲存分配:可稱為動態儲存分配,是由一個類似於堆疊的執行棧來實現的。和靜態儲存分配相反,在棧式儲存方案中,程式對在編譯時候需要的記憶體空間都是未知的,只有執行的時候才能根據所需的資料區大小分配對應的記憶體空間。(棧式記憶體按照先進後出的原則分配。)

通俗一點說堆和棧的區別:堆主要用來存放物件的,棧主要用來執行程式的。

java中在函式中定義的一些基本型別的變數和物件的引用變數都在函式的棧記憶體中分配。當在一段程式碼塊定義一個變數時,Java就在棧中為這個變數分配記憶體空間,當超過變數的作用域後,Java會自動釋放掉為該變數所分配的記憶體空間,該記憶體空間可以立即被另作他用。

堆記憶體用來存放由new建立的物件和陣列。 在堆中分配的記憶體,由Java虛擬機器的自動垃圾回收器來管理。 在堆中產生了一個數組或物件後,還可以在棧中定義一個特殊的變數,讓棧中這個變數的取值等於陣列或物件在堆記憶體中的首地址,棧中的這個變數就成了陣列或物件的引用變數。

引用變數就相當於是為陣列或物件起的一個名稱,以後就可以在程式中使用棧中的引用變數來訪問堆中的陣列或物件。

總結:

棧和堆都是java用來在記憶體中存放資料的地方,(與c++不同的是java自動管理棧和堆,程式設計師不能直接地設定棧和堆)

堆:(物件)

java的堆是一個執行時資料區,堆是由垃圾回收來負責的,堆的優勢是可以動態地分配記憶體大小,生存期也不必事先告訴編譯器,因為它是在執行時動態分配記憶體的,java的垃圾收集器會自動收走這些不再使用的資料。但缺點是,由於要在執行時動態分配記憶體,存取速度比較慢。

棧:(基本資料)

棧的優勢是,存取速度要比堆快,棧資料可以共享。但是缺點是,存在棧中的資料大小與生存期必須是確定的,缺乏靈活性。棧中主要存放一些基本型別的變數。
這裡寫圖片描述

4、Math.round()的原理?
Math.round(11.5)取值結果是12,
Math.round(11.4)取值結果是11,
Math.round(11.6)取值結果是12
Math.round(-11.5)取值結果是-11
Math.round(-11.4)取值結果是-11
Math.round(-11.6)取值結果是-12
原理就是在給要求的值加0.5然後向下取整。
5、String、StringBuffer、StringBuilder的區別?
他們都可以操作和儲存字串。
String是隻讀字串,string引用的字串內容是不能被改變的。
StringBuffer和StringBuilder類表示的字串物件可以直接進行修改。
StringBuilder是java5之後引入的,與StringBuffer的區別是StringBuilder它是在單執行緒環境下使用的,所以效率要比StringBuffer高。
6、過載(overload)和重寫(override)的區別。過載的方法能否根據返回型別進行區分?
過載和重寫都是多型的體現,二者的區別是:
過載說的是:編譯時的多型性。它發生在同一個類中,指的是在一個類中,同名的方法如果引數型別不同或者引數個數不同或者引數型別和個數都不同。注:過載對返回型別沒有特殊的要求。
重寫說的是:執行時的多型性。它發生在父類和子類之間,當子類繼承父類且子類中的方法和父類中的方法它們的方法名、引數個數和引數型別都相同,返回型別也相同(不過這一點在java5之後返回型別可以不同,但是必須是父類的返回值的子類,假如父類返回Object類,子類的返回值可以是String等)
7、&和&&的區別?
&:按位與,將左右兩邊先轉換成二進位制,然後再進行與的運算。
&&:邏輯與,左右兩邊表示式都是true才返回true,有一方false則結果false
8、抽象類和介面的區別?
什麼時候用抽象類,什麼時候用介面?
如果你擁有一些方法並且想讓它們中的一些有預設實現,則可以使用抽象類。
如果你想實現多重繼承,則需要使用介面(java不支援多繼承,子類不能繼承多個類,但是可以實現多個介面)

介面是對動作的抽象,抽象類是對根源的抽象。
抽象類表示的是,這個物件是什麼,介面表示的是這個物件能做什麼。
舉例說:人是一個抽象類,豬也是一個抽象類,人有吃喝拉撒睡的動作,豬也有吃喝拉撒睡的動作,那麼就可以把吃喝拉撒睡這些動作做成一個介面,然後分別去具體實現它們。

使用抽象類的目的:提高程式碼的複用性。可以重寫抽象類中的方法來達到自己需要的目的。
使用介面的目的:體現多型性,讓實現介面的物件可以以不同方式來實現同一個方法。

抽象方法:抽象方法必須用abstract關鍵字來修飾。如果一個類中存在抽象方法,那麼這個類一定是抽象類,抽象類必須在類前用abstract關鍵字修飾。因為抽象類中含有沒有具體實現的方法, 所以不能用抽象類建立物件。(注意:如果一個類中不包含抽象方法,只是用abstract修飾的話也是抽象類。即抽象類不一定必須含有抽象方法。)

抽象類存在的意義就是為了繼承。如果定義了一個抽象類,卻不去繼承它。那麼就等於白白建立了這個抽象類。

包含抽象方法的類是抽象類,但並不是說抽象類中只能有抽象方法,它和普通類一樣,同樣可以擁有成員變數和普通的成員方法。

抽象類和普通類的主要區別:
(1)抽象方法必須為public或者protected,預設為public,因為private無法被繼承。
(2)抽象類不能用來建立物件。
(3)如果一個類繼承於一個抽象類,則子類必須實現父類的抽象方法。如果子類沒有實現父類的抽象方法,則必須將子類也定義為抽象類。

介面中可以含有變數和方法。實際上介面中的變數會被隱式地指定為public static final 變數(只能是)方法也會被隱式的指定為public abstract方法且只能是public abstract方法。
區別:
(1)介面可以多繼承,抽象類只能單繼承,抽象類可以實現多個介面。
(2)介面中所有的方法都是抽象的(預設public abstract修飾),不能有具體的實現。抽象類中可以有普通方法,也可以有抽象方法,也可以定義靜態方法。
(3)介面中成員變數只能是public static final (靜態變數),抽象類中的變數可以是各種型別。
(4)介面中沒有建構函式,抽象類中有建構函式,但是這裡的建構函式不能用於new物件,他的作用主要用來初始化抽象類的操作。

舉例:
有一個警報的介面。有一個門的抽象類。那麼要寫一個防盜門的類的話只需要繼承門這個抽象類,實現警報這個介面即可。

介面可以繼承介面,而且介面可以繼承多個介面,抽象類可以實現介面,而且可以實現多個介面,抽象類可以繼承具體類。

9、抽象的(abstract)方法是否可同時是靜態的(static),是否可同時是本地方法?是否可同時被synchronized修飾?
答案:抽象方法將來是要被重寫的,而靜態方法是不能重寫的,所以這個是錯誤的。本地方法是由原生代碼實現的,而抽象方法是沒有實現的,所以這個也是錯誤的。
synchronized作用主要體現在具體的方法實現上,同樣抽象方法是沒有實現額,所以這個也是錯誤的。
10、final關鍵字的用法?
答案:
(1)修飾類:表示該類不能被繼承。
(2)修飾方法:表示該方法不能被重寫。
(3)修飾變數:表示該變數賦值後值不能被修改,常量。
11、物件構造器的呼叫順序?
先初始化靜態成員變數—>然後呼叫父類構造器–》再初始化非靜態成員變數–>最後呼叫自己構造器
12、是否可以從一個靜態(static)方法內部發出對非靜態方法的呼叫?
答案:不可以,靜態方法只能訪問靜態成員,非靜態方法的呼叫要先建立物件。
13、關於GC?
答案:GC是垃圾回收的意思,java的GC功能可以自動檢測物件是否超過作用域從而達到自動回收記憶體的目的。
有效的防止記憶體洩漏,GC相當於一個單獨的低優先順序的執行緒執行,對記憶體堆中長時間沒有使用的物件進行清除和回收。
14、資料型別之間的轉換?
將字串轉換成基本資料型別:
呼叫基本資料型別對應的封裝類的parseXXX()
將基本資料型別裝換成字串:
呼叫String.valueOf(xxx) 方法;
15、如何實現字串的反轉和轉換?
答案:

    public static String reverse(String a) {

        String newStr = ""; 
          if(a == null || a.length() <= 1) {
              return a;
          }else{
              newStr=reverse(a.substring(1))+a.charAt(0); 
              return newStr ;
          }
      }

16、java常見異常處理關鍵字“throws”、“throw”、“try”、“catch”、“finally”?
答案:java中每個異常都是一個物件,都是Throwable類或其子類的例項。當一個方法出現異常後便丟擲一個異常物件,該物件中包含有異常資訊,呼叫這個物件的方法可以捕獲異常,並對異常作出處理。
throw:就是我們在開發的時候知道會出現什麼異常,明確的丟擲該異常。
throws:用來宣告一個方法可能丟擲的各種異常。
try:用來指定一個段或者說一塊需要預防異常的程式,如果有異常物件,可通過它的型別來catch它或者通過總是執行程式碼塊(finally)來處理。
17、常見的執行時異常?
ArithmeticException(算術異常)
ClassCastException(類轉換異常)
IllegalArgumentException(非法引數異常)
IndexOutOfBoundsException(下表越界異常)
NullPointerException(空指標異常)
SecurityException(安全異常)
18、final、finally、finalize的區別?
final:修飾符(關鍵字)有三種用法:
如果一個類被宣告為final,意味著它不能再派生出新的子類,即不能被繼承,因此它和abstract是反義詞,
將變數宣告為final,可以保證它們在使用中不被改變,被宣告為final的變數必須在宣告時給定初值,而在以後的引用中只能讀取不可修改。
如果方法被final修飾也同樣只能使用,不能在子類中被重寫。

finally:通常放在try……catch的後面構造總是執行程式碼塊,這就意味著程式無論正常執行還是發生異常,這裡的程式碼都是會被執行的。

finalize:Object類中定義的方法,Java中允許使用finalize()方法在垃圾收集器將物件從記憶體中清除出去之前做必要的清理工作。這個方法是由垃圾收集器在銷燬物件時呼叫的,通過重寫finalize()方法可以整理系統資源或者執行其他清理工作。

19、List,Set,Map的用法和區別?
list,set都繼承於Collection介面,map不是。

list(列表):元素以線性方式儲存,可以存放重複元素。

list主要實現類:
ArrayList():長度可以改變的陣列,插入和刪除元素效率較慢。檢索效率快。
LinkedList():連結串列資料結構儲存,插入和刪除元素效率快,檢索訪問效率慢。
set(集合):元素沒有特定的排列順序,存放的是物件引用,沒有重複元素。

set主要實現類:
HashSet:按照雜湊演算法來存取集合中的物件,存取速度較快。
TreeSet:實現了SortedSet介面,能夠對集合中的物件進行排序。

map(對映):鍵物件和值物件對映的集合,每一個元素都有對應的鍵(key)和值(value)物件,從map中檢索元素時候,只需要給出鍵物件就能返回對應的值物件。
一個map中不能包含相同的key,每個key只能對映一個value

主要實現類:
hashMap:底層使用資料+連結串列實現,同一個鍵可以放多個值,但取出的是最後一個值。(非同步)允許放空值空鍵。
hashTable:hashTable和hashMap一樣,唯一的不同就是,它是執行緒安全的,put和get等操作都加鎖,且不允許空值和空鍵。
LinkedHashMap和LinkedArrayList原理相似,可以放空值空鍵。(非同步)相比hashMap是一個單向連結串列來講, 它是雙向連結串列。(缺點是會保留原值)