不騙你,給女友看的超級精華Java問題總結!

當時在網上彙總了不知多少面試和基礎題,弄了個精華總結。java

一、一個".java"源文件中是否能夠包括多個類(不是內部類)?有什麼限制?程序員

能夠有多個類,但只能有一個public的類,而且public的類名必須與文件名相一致。面試

二、short s1= 1; s1= s1+1; 有沒有錯?編程

s1+1運算時會自動提高類型,結果是int,賦值給s1時,將報告須要強轉類型的錯誤。數組

三、short s1= 1; s1 += 1;有沒有錯?緩存

+=是java規定的運算符,編譯器會對它進行特殊處理,所以能夠正確編譯。markdown

四、使用final關鍵字修飾一個變量時,引用的內容必定不能變?多線程

使用final修飾變量時,是引用變量(也就是地址)不能變,引用變量所指向的對象中的內容仍是能夠改變的併發

五、是否能夠從static方法內對非static方法調用?爲何?jvm

不能夠。由於非static方法是與對象關聯的,必須建立一個對象,才能夠在該對象上進行方法調用(對象.方法)。而static方法調用時不須要建立對象,能夠直接調用。若是從一個static方法中發出對非static方法的調用,那個非static方法是關聯到哪一個對象上的呢?這個邏輯沒法成立。

六、Overload和Override的區別?

重載Overload表示同一個類中能夠有多個名稱相同的方法,但這些方法的參數列表各不相同(即參數個數或類型不一樣)。

重寫Override表示子類中的方法能夠與父類中的方法的名稱和參數徹底相同,子類對象調用這個方法時,將調用子類中的定義方法,這就把父類中的方法覆蓋了,這也是面向對象編程的多態性的一種表現。

七、Overloaded的方法是否能夠改變返回值的類型?

若是幾個重載Overloaded的方法的參數列表不同,它們的返回者類型固然也能夠不同。

若是兩個方法的參數列表徹底同樣,無論返回值是否相同,都不容許。由於沒法肯定編程者倒底是想調用哪一個方法了,由於他們被調用時看起來徹底相同。

八、接口是否可繼承接口?抽象類是否可實現(implements)接口?抽象類是否可繼承具體類(concreteclass)?抽象類中是否能夠有靜態的main方法?

接口能夠繼承接口。抽象類能夠實現(implements)接口,抽象類能夠繼承具體類。抽象類中能夠有靜態的main方法。

記住抽象類與普通類的惟一區別就是不能建立實例對象和容許有abstract方法。

九、Java中實現多態的機制是什麼?

靠的是父類(或接口定義)的引用變量能夠指向子類(或具體實現類)的實例對象。

而程序調用的方法在運行期才動態綁定,就是引用變量所指向的具體實例對象的方法,而不是引用變量的類型中定義的方法。

十、abstractclass和interface有什麼區別?

抽象類能夠有構造方法,接口中不能有構造方法。

抽象類中能夠有普通成員變量,接口中沒有普通成員變量

抽象類中能夠包含非抽象的普通方法,接口中的全部方法必須都是抽象的,不能有非抽象的普通方法。

抽象類中的抽象方法類型能夠是public,protected,接口中的抽象方法只能是public類型的,而且默認爲public abstract。

7. 一個類能夠實現多個接口,但只能繼承一個抽象類。

十一、String s = "Hello";s = s + "world!";執行後,原始的String對象中的內容變了沒有?

沒有。由於String被設計成不可變類,因此它的全部對象都是不可變對象。只是s再也不指向舊的對象了。

十二、下面這條語句一共建立了多少個對象:String s="a"+"b"+"c"+"d";

javac編譯能夠對字符串常量直接相加的表達式進行優化直接得出答案,沒必要要等到運行期再去進行加法運算處理

這行代碼被編譯器在編譯時優化後,至關於直接定義了一個」abcd」的字符串,因此,上面的代碼應該只建立了一個String對象。

1三、final, finally, finalize的區別。

final 用於聲明屬性,方法和類,分別表示屬性不可變,方法不可覆蓋,類不可繼承。

finally是異常處理語句結構的一部分,表示老是執行。

finalize是Object類的一個方法,在垃圾收集器執行的時候會調用被回收對象的此方法.

1四、error和exception有什麼區別?

error 表示恢復不是不可能但很困難的狀況下的一種嚴重問題。好比說內存溢出。不可能期望程序能處理這樣的狀況。 exception表示程序還可以克服和恢復的問題

1五、Java 中堆和棧區別?

棧經常使用於保存方法幀和局部變量,而對象老是在堆上分配。

棧一般都比堆小,也不會在多個線程之間共享,而堆被整個 JVM 的全部線程共享。

棧:在函數中定義的一些基本類型的變量和對象的引用變量都是在函數的棧內存中分配,當在一段代碼塊定義一個變量時,Java 就在棧中爲這個變量分配內存空間,當超過變量的做用域後,Java 會自動釋放掉爲該變量分配的內存空間,該內存空間能夠當即被另做它用。

堆:堆內存用來存放由 new 建立的對象和數組,在堆中分配的內存,由 Java 虛擬機的自動垃圾回收器來管理。

1六、能將 int 強制轉換爲 byte 類型的變量嗎?(引伸到全部大類型轉小類型)

實際中,咱們能夠作強制轉換,不會報錯。

可是存在大類型轉小類型的通病: int 是 32 位的,而 byte 是 8 位的,若是強制轉化,int 類型的高 24 位將會被丟棄,因此儘可能不要這樣作。

1七、hashCode有什麼用?與 a.equals(b) 有什麼關係?

hashCode方法對應對象的 hash 值。它經常使用於基於 hash 的集合類,如 Hashtable、HashMap、LinkedHashMap等等。根 據 Java 規範,兩個使用 equal() 方法來判斷相等的對象,必須具備相同的 hash code。

1八、垃圾回收的優勢和原理。

垃圾回收能夠有效的防止內存泄露,有效的使用可使用的內存。垃圾回收器一般是做爲一個單獨的低級別的線程運行,不可預知的狀況下對內存堆中已經死亡的或者長時間沒有使用的對象進行清除和回收,程序員不能實時的調用垃圾回收器對某個對象或全部對象進行垃圾回收。回收機制有分代複製垃圾回收和標記垃圾回收,增量垃圾回收。

原理:能夠給對象添加一個被引用的計數器,就能夠判斷是否已是無引用對象。可是難以解決循環引用問題。

若是不下當心直接把 Obj1-reference 和 Obj2-reference 置 null。則在 Java 堆當中的兩塊內存依然保持着互相引用沒法回收。

可達性分析法:經過一系列的 ‘GC Roots’ 的對象做爲起始點,從這些節點出發所走過的路徑稱爲引用鏈。當一個對象到 GC Roots 沒有任何引用鏈相連的時候說明對象不可用。

19,java中會存在內存泄漏嗎

內存泄漏:指一個再也不被程序使用的對象或變量一直被佔據在內存中。java中有垃圾回收機制,它能夠保證當對象再也不被引用的時候,對象將自動被垃圾回收器從內存中清除掉。

因爲Java使用有向圖的方式進行垃圾回收管理,能夠消除引用循環的問題,例若有兩個對象,相互引用,只要它們和根進程不可達,那麼GC也是能夠回收它們的。

java中的內存泄露的狀況:長生命週期的對象持有短生命週期對象的引用就極可能發生內存泄露.

儘管短生命週期對象已經再也不須要,可是由於長生命週期對象持有它的引用而致使不能被回收,這就是java中內存泄露的發生場景。通俗地說,就是程序員可能建立了一個對象,之後一直再也不使用這個對象,這個對象卻一直被引用,即這個對象無用可是卻沒法被垃圾回收器回收的,這就是java中可能出現內存泄露的狀況,例如,緩存系統,咱們加載了一個對象放在緩存中(例如放在一個全局map對象中),而後一直再也不使用它,這個對象一直被緩存引用,但卻再也不被使用。

2一、線程和進程有什麼區別?

進程是操做系統資源分配的基本單位,而線程是任務調度和執行的基本單位

線程是進程的子集,一個進程能夠有不少線程,每條線程並行執行不一樣的任務。

不一樣的進程使用不一樣的內存空間,而全部的線程共享一片相同的內存空間。

2二、如何在Java中實現線程?

繼承Thread類
class Handler extends Thread{
    public void run(){
       //方法重寫
    }
    public static void main(String[] args){
        Thread thread = new Handler();//建立線程對象
        thread.start();//啓動線程
    }
}





實現Runnable接口
class Handler implements Runnable{
    public void run(){
       //方法實現
    }
    public static void main(String[] args){
        Handler handler = new Handler();
        Thread thread = new Thread(handler);//建立線程對象
        thread.start();//啓動線程
    }
}2三、Java 關鍵字volatile 與 synchronized 做用與區別?
複製代碼

1,volatile

它所修飾的變量不保留拷貝,直接訪問主內存中的。

在Java內存模型中,有main memory,每一個線程也有本身的memory (例如寄存器)。

爲了性能,一個線程會在本身的memory中保持要訪問的變量的副本。這樣就會出現同一個變 量在某個瞬間,在一個線程的memory中的值可能與另一個線程memory中的值,或者main memory中的值不一致的狀況。

一個變量聲明爲volatile,就意味着這個變量是隨時會被其餘線程修改的,所以不能將它cache在線程memory中。

2,synchronized

當它用來修飾一個方法或者一個代碼塊的時候,可以保證在同一時刻最多隻有一個線程執行該段代碼。

1、當兩個併發線程訪問同一個對象object中的這個synchronized(this)同步代碼塊時,一個時間內只能有一個線程獲得執行。

2、當一個線程訪問object的一個synchronized(this)同步代碼塊時,另外一個線程仍然能夠訪問該object中的非synchronized(this)同步代碼塊。

3、尤爲關鍵的是,當一個線程訪問object的一個synchronized(this)同步代碼塊時,其餘線程對object中全部synchronized(this)同步代碼塊的訪問將被阻塞。

2四、線程生命週期?

新建一個線程時,它的狀態是New。當咱們調用線程的start()方法時,狀態被改變爲Runnable。線程調度器會爲Runnable線程池中的線程分配CPU時間而且將它們的狀態改變爲Running。其餘的線程狀態還有Waiting,Blocked 和Dead。

2五、死鎖?

指多個進程在運行過程當中因爭奪資源而形成的一種僵局,當處於這種狀態時,若無外力做用,它們都將沒法再向前推動。

緣由可歸結爲兩點:競爭資源、 進程間推動順序非法

產生死鎖的必要條件:

互斥條件:在一段時間內某資源僅爲一進程所佔用。

請求和保持條件:對已得到的資源保持不放。

不剝奪條件:已得到的資源只能由本身釋放。

環路等待條件:存在一個進程--資源的環形鏈。

2六、什麼是線程池? 爲何要使用它?

建立線程要花費昂貴的資源和時間,若是任務來了才建立線程那麼響應時間會變長,並且一個進程能建立的線程數有限。

線程池實現了線程重複利用,節約了時間和資源。

// Java線程池的完整構造函數
public ThreadPoolExecutor(
  int corePoolSize, // 線程池長期維持的線程數,即便線程處於Idle狀態,也不會回收。
  int maximumPoolSize, // 線程數的上限
  long keepAliveTime, TimeUnit unit, // 超過corePoolSize的線程的idle時長,
                                     // 超過這個時間,多餘的線程會被回收。
  BlockingQueue<Runnable> workQueue, // 任務的排隊隊列
  ThreadFactory threadFactory, // 新線程的產生方式
  RejectedExecutionHandler handler) // 拒絕策略
複製代碼

2七、反射?

JAVA反射機制是在運行狀態中,對於任意一個實體類,都可以知道這個類的全部屬性和方法;對於任意一個對象,都可以調用它的任意方法和屬性;這種動態獲取信息以及動態調用對象方法的功能稱爲java語言的反射機制。

2八、JDK 、 JRE 、JVM有什麼區別和聯繫?

JVM : Java 虛擬機。可以將 class 文件中的字節碼指令進行識別並調用操做系統向上的 API 完成動做。因此說,jvm 是 Java 可以跨平臺的核心。

JRE :Java 運行時環境。包含兩個部分,jvm和 Java 的一些基本類庫。

JDK :Java 開發工具包。jdk 是整個 Java 開發的核心,它集成了 jre 和一些好用的小工具。

這三者的關係是:一層層的嵌套關係。JDK>JRE>JVM。

2九、深拷貝淺拷貝

數據類型分爲兩種基礎類型和引用類型:

基礎類型:像Number、String、Boolean等這種爲基本類型

引用類型:Object和Array

淺拷貝只是複製了對象的引用地址,兩個對象指向同一個內存地址,修改其中任意的值,另外一個值會隨之變化

深拷貝是將對象及值複製過來,兩個對象修改其中任意的值另外一個值不會改變。

30、JVM內存分爲哪幾部分?各個部分的做用是什麼?

JVM內存區域分爲五個部分,分別是堆,方法區,虛擬機棧,本地方法棧,程序計數器。

1)堆。

堆是Java對象的存儲區域,任何用new字段分配的Java對象實例和數組。

2)方法區。

它用於存儲已被虛擬機加載的類信息,常量,靜態變量,即時編譯器編譯後的代碼等數據,方法區,從JDK1.8永久代被移除。

3)虛擬機棧。

虛擬機棧中執行每一個方法的時候,都會建立一個棧幀用於存儲局部變量表,操做數棧,動態連接,方法出口等信息。

4)本地方法棧。

與虛擬機棧發揮的做用類似,相比於虛擬機棧爲Java方法服務,本地方法棧爲虛擬機使用的Native方法服務,執行每一個本地方法的時候,都會建立一個棧幀用於存儲局部變量表,操做數棧,動態連接,方法出口等信息。

5)程序計數器。

指示Java虛擬機下一條須要執行的字節碼指令。

總:其中方法區和堆被JVM中多個線程共享,好比類的靜態常量就被存放在方法區,供類對象之間共享,虛擬機棧,本地方法棧,pc寄存器是每一個線程獨立擁有的,不會與其餘線程共享。

3一、爲何會出現4.0-3.6=0.40000001這種現象?

2進制的小數沒法精確的表達10進制小數,在計算10進制小數的過程當中要先轉換爲2進制進行計算,這個過程當中出現偏差。

3二、「==」比較的是什麼?

「==」兩邊是對象,比較地址。

「==」兩邊是基本類型,比較數值。

原文連接:fantianzuo.blog.csdn.net/article/det…

相關文章
相關標籤/搜索