1.抽象和封裝的不同點
抽象和封裝是互補的概念。一方面,抽象關注對象的行為。另一方面,封裝關注對象行為的細節。一般是通過隱藏對象內部狀態信息做到封裝,因此,封裝可以看成是用來提供抽象的一種策略。
2.重載和重寫的區別
重載: 發生在同一個類中,方法名必須相同,參數類型不同、個數不同、順序不同,方法返回值和訪問修飾符可以不同,發生在編譯時。
重寫: 發生在父子類中,方法名、參數列表必須相同,返回值范圍小于等于父類,拋出的異常范圍小于等于父類,訪問修飾符范圍大于等于父類;如果父類方法訪問修飾符為private則子類就不能重寫該方法。
3.字符型常量和字符串常量的區別
字符常量是單引號引起的一個字符 字符串常量是雙引號引起的若干個字符字符常量相當于一個整形值(ASCII值),可以參加表達式運算 字符串常量代表一個地址值(該字符串在內存中存放位置)字符常量只占一個字節 字符串常量占若干個字節(至少一個字符結束標志)4.成員變量與局部變量的區別有那些?
從語法形式上,看成員變量是屬于類的,而局部變量是在方法中定義的變量或是方法的參數;成員變量可以被public,private,static等修飾符所修飾,而局部變量不能被訪問控制修飾符及static所修飾;但是,成員變量和局部變量都能被final所修飾;從變量在內存中的存儲方式來看,成員變量是對象的一部分,而對象存在于堆內存,局部變量存在于棧內存從變量在內存中的生存時間上看,成員變量是對象的一部分,它隨著對象的創建而存在,而局部變量隨著方法的調用而自動消失。成員變量如果沒有被賦初值,則會自動以類型的默認值而賦值(一種情況例外被final修飾但沒有被static修飾的成員變量必須顯示地賦值);而局部變量則不會自動賦值。5.講講對static的理解?Java中是否可以覆蓋一個private或者是static的方法?
如果一個類的變量或者方法前面有static修飾,那么表明這個方法或者變量屬于這個類,也就是說可以在不創建對象的情況下直接使用
當父類的方法被private修飾時,表明該方法為父類私有,對其他任何類都是不可見的,因此如果子類定了一個與父類一樣的方法,這對于子類來說相當于是一個新的私有方法,且如果要進行向上轉型,然后去調用該“覆蓋方法”,會產生編譯錯誤
static方法時編譯時靜態綁定的,屬于類,而覆蓋是運行時動態綁定的(動態綁定的多態),因此不能覆蓋.
6.是否可以在static環境中訪問非static變量?
static變量在Java中是屬于類的,它在所有的實例中的值是一樣的。
當類被Java虛擬機載入的時候,會對static變量進行初始化。
如果代碼嘗試不用實例來訪問非static的變量,編譯器會報錯,因為這些變量還沒有被創建出來,還沒有跟任何實例關聯上。
7.Java支持的基本數據類型有哪些?
java支持的基本數據類型有以下9種:byte,shot,int,long,float,double,char,boolean,void.
8.怎么理解JAVA的自動拆箱裝箱?
所謂自動裝箱就是將基本數據類型自動的轉換為對應的對象包裝類型,而拆箱就是將對象包裝類型轉換為基本數據類型。
java中的自動拆裝箱通常發生在變量賦值的過程中,如:把int轉化成Integer,double轉化成double就是自動裝箱,反之就是自動拆箱
在實際中,應該注意自動拆裝箱,因為有時可能因為java自動裝箱機制,而導致創建了許多對象,對于內存小的平臺會造成壓力。
9. 重寫和重載是什么?
重寫:發生在子類與父類之間,表示子類中的方法可以與父類中的某個方法的名稱和參數完全相同,通過子類創建的實例對象調用這個方法時,將調用子類中的定義方法,這相當于把父類中定義的那個完全相同的方法給覆蓋了,這也是面向對象編程的多態性的一種表現。重載:是指在一個類中,可以有多個相同名稱的方法,但是他們的參數列表的個數或類型不同,當調用該方法時,根據傳遞的參數類型調用對應參數列表的方法。當參數列表相同但返回值不同時,將會出現編譯錯誤,這并不是重載,因為jvm無法根據返回值類型來判斷應該調用哪個方法。10.Java支持多繼承么?如果不支持,如何實現?
不支持,Java不支持多繼承。每個類都只能繼承一個類,但是可以實現多個接口。
在java中是單繼承的,也就是說一個類只能繼承一個父類。
java中實現多繼承有兩種方式,一是接口,而是內部類.
11.什么是值傳遞和引用傳遞?Java中是值傳遞還是引用傳遞,還是都有?
值傳遞:就是在方法調用的時候,實參是將自己的一份拷貝賦給形參,在方法內,對該參數值的修改不影響原來實參。引用傳遞:是在方法調用的時候,實參將自己的地址傳遞給形參,此時方法內對該參數值的改變,就是對該實參的實際操作。在java中只有一種傳遞方式,那就是值傳遞.可能比較讓人迷惑的就是java中的對象傳遞時,對形參的改變依然會影響到該對象的內容。
12.接口和抽象類的區別是什么?
接口中所有的方法隱含的都是抽象的。而抽象類則可以同時包含抽象和非抽象的方法。類可以實現很多個接口,但是只能繼承一個抽象類類如果要實現一個接口,它必須要實現接口聲明的所有方法。但是,類可以不實現抽象類聲明的所有方法,當然,在這種情況下,類也必須得聲明成是抽象的。抽象類可以在不提供接口方法實現的情況下實現接口。Java 接口中聲明的變量默認都是 final 的。抽象類可以包含非 final 的變量。Java 接口中的成員函數默認是 public 的。抽象類的成員函數可以是 private,protected 或者是 public 。接口是絕對抽象的,不可以被實例化(java 8已支持在接口中實現默認的方法)。抽象類也不可以被實例化,但是,如果它包含 main 方法的話是可以被調用的。13.構造器(constructor)是否可被重寫(override)?
構造方法是不能被子類重寫的,但是構造方法可以重載
簡單的講,就是說一個類可以有多個構造方法。
14. String, StringBuffer StringBuilder的區別
String 的長度是不可變的;StringBuffer的長度是可變的,線程安全;如果對一個字符串要經常改變的話,就一定不要用String,否則會創建許多無用的對象出來.15.HashMap的工作原理是什么?
HashMap內部是通過一個數組實現的,只是這個數組比較特殊,數組里存儲的元素是一個Entry實體(在JAVA8中為Node),這個Entry實體主要包含key、value以及一個指向自身的next指針。
HashMap是基于hashing實現的,當進行put操作時,根據傳遞的key值得到它的hashcode,然后再用這個hashcode與數組的長度進行模運算,得到一個int值,就是Entry要存儲在數組的位置(下標);當通過get方法獲取指定key的值時,會根據這個key算出它的hash值(數組下標),根據這個hash值獲取數組下標對應的Entry,然后判斷Entry里的key,hash值或者通過equals()比較是否與要查找的相同,如果相同,返回value,否則的話,遍歷該鏈表(有可能就只有一個Entry,此時直接返回null),直到找到為止,否則返回null。
HashMap之所以在每個數組元素存儲的是一個鏈表,是為了解決hash沖突問題,當兩個對象的hash值相等時,那么一個位置肯定是放不下兩個值的,于是hashmap采用鏈表來解決這種沖突,hash值相等的兩個元素會形成一個鏈表。
16.HashMap與Hashtable的區別是什么?
Hashtable基于Dictionary類,而HashMap是基于AbstractMap。Dictionary是任何可將鍵映射到相應值的類的抽象父類,而AbstractMap是基于Map接口的實現,它以最大限度地減少實現此接口所需的工作。HashMap和Hashtable都實現了Map接口,Hashtable基于Dictionary類,而HashMap是基于AbstractMap。Dictionary是任何可將鍵映射到相應值的類的抽象父類,而AbstractMap是基于Map接口的實現,它以最大限度地減少實現此接口所需的工作。HashMap允許鍵和值是null,而Hashtable不允許鍵或者值是null。Hashtable是同步(線程安全)的,而HashMap不是同步(非線程安全)。因此,HashMap更適合于單線程環境,而Hashtable適合于多線程環境。HashMap提供了可供應用迭代的鍵的集合,因此,HashMap是快速失敗的。另一方面,Hashtable提供了對鍵的列舉(Enumeration)。17.CorrentHashMap的工作原理
ConcurrenHashMap說是HashMap的升級版
ConcurrentHashMap是線程安全的,但是與Hashtable相比,實現線程安全的方式不同。
Hashtable是通過對hash表結構進行鎖定,是阻塞式的,當一個線程占有這個鎖時,其他線程必須阻塞等待其釋放鎖。
ConcurrentHashMap是采用分離鎖的方式,它并沒有對整個hash表進行鎖定,而是局部鎖定,也就是說當一個線程占有這個局部鎖時,不影響其他線程對hash表其他地方的訪問。
ConcurrentHashMap內部有一個Segment<K,V>數組,該Segment對象可以充當鎖。Segment對象內部有一個HashEntry<K,V>數組,于是每個Segment可以守護若干個桶(HashEntry),每個桶又有可能是一個HashEntry連接起來的鏈表,存儲發生碰撞的元素。
每個ConcurrentHashMap在默認并發級下會創建包含16個Segment對象的數組,每個數組有若干個桶,當進行put方法時,通過hash方法對key進行計算,得到hash值,找到對應的segment,然后對該segment進行加鎖,然后調用segment的put方法進行存儲操作,此時其他線程就不能訪問當前的segment,但可以訪問其他的segment對象,不會發生阻塞等待。
在Java8中,ConcurrentHashMap不再使用Segment分離鎖,而是采用一種樂觀鎖CAS算法來實現同步問題,但其底層還是“數組+鏈表->紅黑樹”的實現。
18.Array和ArrayList有什么區別?
Array可以容納基本類型和對象,而ArrayList只能容納對象。Array是指定大小的,而ArrayList大小是固定的Array可以包含基本類型和對象類型,ArrayList只能包含對象類型。Array大小是固定的,ArrayList的大小是動態變化的。19.ArrayList和LinkedList有什么區別?
ArrayList和LinkedList都實現了List接口ArrayList是基于數組實現,它的底層是數組。它可以以O(1)時間復雜度對元素進行隨機訪問。LinkedList是基于鏈表實現,每一個元素都和它的前一個和后一個元素鏈接在一起,在這種情況下,查找某個元素的時間復雜度是O(n)。ArrayList在查找時速度快LinkedList的插入,添加,刪除操作速度更快,因為當元素被添加到集合任意位置的時候,不需要像數組那樣重新計算大小或者是更新索引。LinkedList比ArrayList更占內存,因為LinkedList為每一個節點存儲了兩個引用,一個指向前一個元素,一個指向下一個元素。20.哪些集合類提供對元素的隨機訪問?
ArrayList、HashMap、TreeMap和HashTable類提供對元素的隨機訪問。
21.HashSet的底層實現是什么?
HashSet的實現是依賴于HashMap的,HashSet的值都是存儲在HashMap中的。
在HashSet的構造法中會初始化一個HashMap對象,HashSet不允許值重復。
因此,HashSet的值是作為HashMap的key存儲在HashMap中的,當存儲的值已經存在時返回false。
22.Comparable和Comparator接口的區別。
Comparable接口只包含一個compareTo()方法。這個方法可以個給兩個對象排序。具體來說,它返回負數,0,正數來表明輸入對象小于,等于,大于已經存在的對象。Comparator接口包含compare()和equals()兩個方法。compare()方法用來給兩個輸入參數排序,返回負數,0,正數表明第一個參數是小于,等于,大于第二個參數。
equals()方法需要一個對象作為參數,它用來決定輸入參數是否和comparator相等。只有當輸入參數也是一個comparator并且輸入參數和當前comparator的排序結果是相同的時候,這個方法才返回true。
23.HashSet和TreeSet有什么區別?
HashSet是由一個hash表來實現的,因此,它的元素是無序的。add(),remove(),contains()方法的時間復雜度是O(1)。TreeSet是由一個樹形的結構來實現的,它里面的元素是有序的。因此,add(),remove(),contains()方法的時間復雜度是O(logn)。24. Java中==與equals的區別
"==" 的作用是判斷兩個對象的地址是不是相等。即判斷兩個對象是不是同一個對象。(基本數據類型==比較的是值,引用數據類型==比較的是內存地址)equals() : 它的作用也是判斷兩個對象是否相等。但它一般有兩種使用情況:類沒有覆蓋equals()方法。則通過equals()比較該類的兩個對象時,等價于通過“==”比較這兩個對象。類覆蓋了equals()方法。一般,我們都覆蓋equals()方法來兩個對象的內容相等;若它們的內容相等,則返回true(即,認為這兩個對象相等)。25.你重寫過 hashcode 和 equals 么,為什么重寫equals時必須重寫hashCode方法?
hashCode() 的作用是獲取哈希碼,也稱為散列碼;它實際上是返回一個int整數。這個哈希碼的作用是確定該對象在哈希表中的索引位置。如果兩個對象相等,則hashcode一定也是相同的如果兩個對象相等,對兩個對象分別調用equals方法都返回true如果兩個對象有相同的hashcode值,它們也不一定是相等的因此,equals方法被覆蓋過,則hashCode方法也必須被覆蓋
hashCode()的默認行為是對堆上的對象產生獨特值。如果沒有重寫hashCode(),則該class的兩個對象無論如何都不會相等(即使這兩個對象指向相同的數據)
26.Java的四種引用,強弱軟虛,用到的場景
強引用:如果一個對象具有強引用,它就不會被垃圾回收器回收。即使當前內存空間不足,JVM也不會回收它,而是拋出 OutOfMemoryError 錯誤,使程序異常終止。如果想中斷強引用和某個對象之間的關聯,可以顯式地將引用賦值為null,這樣一來的話,JVM在合適的時間就會回收該對象軟引用:在使用軟引用時,如果內存的空間足夠,軟引用就能繼續被使用,而不會被垃圾回收器回收,只有在內存不足時,軟引用才會被垃圾回收器回收。弱引用:具有弱引用的對象擁有的生命周期更短暫。因為當 JVM 進行垃圾回收,一旦發現弱引用對象,無論當前內存空間是否充足,都會將弱引用回收。不過由于垃圾回收器是一個優先級較低的線程,所以并不一定能迅速發現弱引用對象虛引用:顧名思義,就是形同虛設,如果一個對象僅持有虛引用,那么它相當于沒有引用,在任何時候都可能被垃圾回收器回收。