抽象類和接口的含義以及區(qū)別
抽象類
抽象類不能創(chuàng)建實(shí)例,它只能作為父類被繼承。抽象類是從多個(gè)具體類中抽象出來的父類,它具有更高層次的抽象。從多個(gè)具有相同特征的類中抽象出一個(gè)抽象類,以這個(gè)抽象類作為其子類的模板,從而避免了子類的隨意性。
(1) 抽象方法只作聲明,而不包含實(shí)現(xiàn),可以看成是沒有實(shí)現(xiàn)體的虛方法
(2) 抽象類不能被實(shí)例化
(3) 抽象類可以但不是必須有抽象屬性和抽象方法,但是一旦有了抽象方法,就一定要把這個(gè)類聲明為抽象類
(4) 具體派生類必須覆蓋基類的抽象方法
(5) 抽象派生類可以覆蓋基類的抽象方法,也可以不覆蓋。如果不覆蓋,則其具體派生類必須覆蓋它們
接口是什么:
(1) 接口不能被實(shí)例化
(2) 接口只能包含方法聲明
(3) 接口的成員包括方法、屬性、索引器、事件
(4) 接口中不能包含常量、字段(域)、構(gòu)造函數(shù)、析構(gòu)函數(shù)、靜態(tài)成員
接口和抽象類的區(qū)別:
(1)抽象類可以有構(gòu)造方法,接口中不能有構(gòu)造方法。
(2)抽象類中可以有普通成員變量,接口中沒有普通成員變量
(3)抽象類中可以包含靜態(tài)方法,接口中不能包含靜態(tài)方法
(4) 一個(gè)類可以實(shí)現(xiàn)多個(gè)接口,但只能繼承一個(gè)抽象類。
(5)接口可以被多重實(shí)現(xiàn),抽象類只能被單一繼承
(6)如果抽象類實(shí)現(xiàn)接口,則可以把接口中方法映射到抽象類中作為抽象方法而不必實(shí)現(xiàn),而在抽象類的子類中實(shí)現(xiàn)接口中方法
String、StringBuffer、StringBuilder有什么區(qū)別?
String是Java中基礎(chǔ)且重要的類,并且String也是Immutable類的典型實(shí)現(xiàn),被聲明為final class,除了hash這個(gè)屬性其它屬性都聲明為final,因?yàn)樗牟豢勺冃裕岳缙唇幼址畷r(shí)候會(huì)產(chǎn)生很多無用的中間對(duì)象,如果頻繁的進(jìn)行這樣的操作對(duì)性能有所影響。
StringBuilder是JDK1.5發(fā)布的,它和StringBuffer本質(zhì)上沒什么區(qū)別,就是去掉了保證線程安全的那部分,減少了開銷。
StringBuffer就是為了解決大量拼接字符串時(shí)產(chǎn)生很多中間對(duì)象問題而提供的一個(gè)類,
1、在字符串不經(jīng)常發(fā)生變化的業(yè)務(wù)場(chǎng)景優(yōu)先使用String(代碼更清晰簡(jiǎn)潔)。如常量的聲明,少量的字符串操作(拼接,刪除等)。
2、在單線程情況下,如有大量的字符串操作情況,應(yīng)該使用StringBuilder來操作字符串。不能使用String"+"來拼接而是使用,避免產(chǎn)生大量無用的中間對(duì)象,耗費(fèi)空間且執(zhí)行效率低下(新建對(duì)象、回收對(duì)象花費(fèi)大量時(shí)間)。如JSON的封裝等。
3、在多線程情況下,如有大量的字符串操作情況,應(yīng)該使用StringBuffer。如HTTP參數(shù)解析和封裝等。
相關(guān)網(wǎng)址:string stringbuffer stringbuilder區(qū)別
ArrayList和LinkedList的區(qū)別?(鏈表和數(shù)組的優(yōu)缺點(diǎn))
ArrayList和LinkedList都實(shí)現(xiàn)了List接口,有以下的不同點(diǎn):
1、ArrayList是基于索引的數(shù)據(jù)接口,它的底層是數(shù)組。它可以以O(shè)(1)時(shí)間復(fù)雜度對(duì)元素進(jìn)行隨機(jī)訪問。與此對(duì)應(yīng),LinkedList是以元素列表的形式存儲(chǔ)它的數(shù)據(jù),每一個(gè)元素都和它的前一個(gè)和后一個(gè)元素鏈接在一起,在這種情況下,查找某個(gè)元素的時(shí)間復(fù)雜度是O(n)。
2、LinkedList的插入,添加,刪除操作速度更快,因?yàn)楫?dāng)元素被添加到集合任意位置的時(shí)候,不需要像數(shù)組那樣重新計(jì)算大小或者是更新索引。
3、LinkedList比ArrayList更占內(nèi)存,因?yàn)長inkedList為每一個(gè)節(jié)點(diǎn)存儲(chǔ)了兩個(gè)引用,一個(gè)指向前一個(gè)元素,一個(gè)指向下一個(gè)元素。
HashMap是怎樣的結(jié)構(gòu)?工作原理是什么?退化成鏈表解決方法?
答:HashMap的本質(zhì)仍然是數(shù)組,不過數(shù)組中存儲(chǔ)的不是數(shù)據(jù),而是一個(gè)鏈表的頭節(jié)點(diǎn)。所以準(zhǔn)確的說,其實(shí)現(xiàn)就是鏈表數(shù)組。HashMap中保存的是一個(gè)鍵值對(duì),插入對(duì)象時(shí)必須提供一個(gè)鍵對(duì)象;查找對(duì)象時(shí)必須給定一個(gè)鍵對(duì)象(因此必須記住鍵)。鍵對(duì)象是不允許重復(fù)的,但是允許null空鍵的存在。
HashMap插入對(duì)象時(shí),根據(jù)給定的鍵key計(jì)算hashcode,然后再與數(shù)組長度進(jìn)行求余運(yùn)算得到數(shù)組下標(biāo)。然后與該位置上的鏈表中已存儲(chǔ)的鍵進(jìn)行比較,對(duì)于已存在的鍵,則覆蓋;對(duì)于不存在的鍵,則添加到鏈表尾。
HashMap工作原理: http://www.admin10000.com/document/3322.html
HashMap基于hashing原理,我們通過put()和get()方法儲(chǔ)存和獲取對(duì)象。當(dāng)我們將鍵值對(duì)傳遞給put()方法時(shí),它調(diào)用鍵對(duì)象的hashCode()方法來計(jì)算hashcode,然后找到bucket位置來儲(chǔ)存值對(duì)象。當(dāng)獲取對(duì)象時(shí),通過鍵對(duì)象的equals()方法找到正確的鍵值對(duì),然后返回值對(duì)象。HashMap使用LinkedList來解決碰撞問題,當(dāng)發(fā)生碰撞了,對(duì)象將會(huì)儲(chǔ)存在LinkedList的下一個(gè)節(jié)點(diǎn)中。 HashMap在每個(gè)LinkedList節(jié)點(diǎn)中儲(chǔ)存鍵值對(duì)對(duì)象。
當(dāng)兩個(gè)不同的鍵對(duì)象的hashcode相同時(shí)會(huì)發(fā)生什么? 它們會(huì)儲(chǔ)存在同一個(gè)bucket位置的LinkedList中。鍵對(duì)象的equals()方法用來找到鍵值對(duì)。
key對(duì)象相同則覆蓋,hashcode相同則添加到鏈表尾。
退化成鏈表解決方法?
JDK7中確實(shí)會(huì)有這樣的問題,因?yàn)殒湵矸ㄓ羞@樣的缺陷。但是在JDK8中,Java會(huì)在鏈表長度超過一個(gè)闕值的時(shí)候?qū)㈡湵砩?jí)為一個(gè)平衡二叉樹,使用hashcode作為樹的分支變量,較大的會(huì)插入到右子樹中;hashcode相等的情況下,HashMap希望Key對(duì)象是實(shí)現(xiàn)了Comparable接口的,這樣就可以按照順序插入。
鍵對(duì)象的選擇->選擇String對(duì)象作為鍵對(duì)象最好,因?yàn)镾tring具有不可變性
棧和隊(duì)列的區(qū)別是什么??
答:隊(duì)列允許頭出尾進(jìn),而棧只允許從棧頂進(jìn)出。簡(jiǎn)單說:吃多了拉就是隊(duì)列;吃多了吐就是棧。
排序算法相關(guān):時(shí)間復(fù)雜度、空間復(fù)雜度、穩(wěn)定性。?
答:

Java的垃圾回收機(jī)制是怎樣的?回收的是什么樣的對(duì)象?
答:Java垃圾回收器實(shí)現(xiàn)對(duì)堆內(nèi)存數(shù)據(jù)的自動(dòng)回收,無需程序員顯式地調(diào)用delete放啊。Java的垃圾自動(dòng)回收機(jī)制有效地避免了因?yàn)槌绦騿T忘記釋放內(nèi)存而造成的內(nèi)存溢出錯(cuò)誤。
Java使用被稱為垃圾收集器的技術(shù)來監(jiān)視Java程序的運(yùn)行,當(dāng)對(duì)象不再被使用時(shí),即不再被引用時(shí),就會(huì)自動(dòng)釋放對(duì)象所占用的內(nèi)存。Java使用一系列軟指針來跟蹤對(duì)象的各個(gè)引用,這些軟指針并不直接指向?qū)ο?,而是指向?qū)ο蟮囊谩Mㄟ^軟指針,Java的垃圾收集器能夠以單獨(dú)的線程在后臺(tái)運(yùn)行,并不時(shí)檢查每個(gè)對(duì)象的引用。
調(diào)用System的靜態(tài)方法gc()可以運(yùn)行垃圾收集器,但是并不能保證立即回收指定對(duì)象。(這就是建議回收,不能強(qiáng)迫回收。)
finalize()方法可以終止一個(gè)對(duì)象來釋放資源,調(diào)用之后對(duì)象不再被引用,就會(huì)被回收。
什么是堆內(nèi)存?什么是棧內(nèi)存?有什么區(qū)別??
答:Java的內(nèi)存空間分為堆內(nèi)存和棧內(nèi)存。棧內(nèi)存用于存儲(chǔ)定義的基本類型變量、函數(shù)返回值、對(duì)象的引用等,而堆內(nèi)存用于存放new出來的一切對(duì)象。
什么是進(jìn)程、什么是線程?進(jìn)程和線程有什么區(qū)別?怎樣定義線程??
答:進(jìn)程是某個(gè)程序在某個(gè)數(shù)據(jù)集上的一次活動(dòng),是系統(tǒng)資源分配的最小單位。?
線程是進(jìn)程的一個(gè)實(shí)體,是系統(tǒng)進(jìn)行調(diào)度的最小單位;線程基本不擁有資源,它與其他線程共享進(jìn)程的資源。
尾遞歸是怎樣的?與遞歸的比較?
答:尾遞歸,也即在尾部進(jìn)行遞歸的一種遞歸形式,指的是在一次遞歸執(zhí)行完畢,返回上一層之后,不在進(jìn)行任何操作,也即在回歸的過程中不做任何操作,且返回值不屬于表達(dá)式的一部分。
當(dāng)編譯器檢測(cè)到一個(gè)函數(shù)調(diào)用是尾遞歸的時(shí)候,它就覆蓋當(dāng)前的活動(dòng)記錄而不是在棧中去創(chuàng)建一個(gè)新的。編譯器可以做到這點(diǎn),因?yàn)檫f歸調(diào)用是當(dāng)前活躍期內(nèi)最后一條待執(zhí)行的語句,于是當(dāng)這個(gè)調(diào)用返回時(shí)棧幀中并沒有其他事情可做,因此也就沒有保存棧幀的必要了。通過覆蓋當(dāng)前的棧幀而不是在其之上重新添加一個(gè),這樣所使用的??臻g就大大縮減了,這使得實(shí)際的運(yùn)行效率會(huì)變得更高。
死鎖是怎么產(chǎn)生的?怎么解決死鎖的問題??
答:死鎖是多個(gè)進(jìn)程競(jìng)爭(zhēng)共享資源產(chǎn)生的,若無外力作用,這些進(jìn)程將永遠(yuǎn)無法前進(jìn)。
產(chǎn)生死鎖的四個(gè)條件:? 1、互斥? ?2、占有且等待? 3、不可搶占 4、循環(huán)等待
? ? ? ?當(dāng)以上四個(gè)條件均滿足,必然會(huì)造成死鎖,發(fā)生死鎖的進(jìn)程無法進(jìn)行下去,它們所持有的資源也無法釋放。這樣會(huì)導(dǎo)致CPU的吞吐量下降。所以死鎖情況是會(huì)浪費(fèi)系統(tǒng)資源和影響計(jì)算機(jī)的使用性能的。那么,解決死鎖問題就是相當(dāng)有必要的了。
什么是優(yōu)先級(jí)隊(duì)列??jī)?yōu)先級(jí)隊(duì)列有什么用?
答:優(yōu)先級(jí)隊(duì)列,因?yàn)橐话阌枚娑褋韺?shí)現(xiàn),因此又稱為堆。它的每一個(gè)父節(jié)點(diǎn)的值都比孩子節(jié)點(diǎn)大(或者?。?。它的工作是查找或者刪除優(yōu)先隊(duì)列中的最大值(或最小值)
什么是二叉搜索樹?
答:二叉搜索樹,是一種特殊的二叉樹,其每一個(gè)父節(jié)點(diǎn)的值都大于左孩子節(jié)點(diǎn),且小于右孩子節(jié)點(diǎn)。
重載和重寫的區(qū)別? 子類可以重載父類的方法嗎?
答:重載:指的是同名的方法擁有不同的參數(shù)列表,而系統(tǒng)調(diào)用函數(shù)是能夠根據(jù)參數(shù)列表選擇正確的方法。
重寫:指的是是對(duì)父類方法的一種覆蓋。
子類不可以重載父類的方法,只能重寫。
說說你對(duì)于static關(guān)鍵字的理解。
答:static修飾的域?qū)儆谶@個(gè)類,而不屬于具體的某一個(gè)對(duì)象。
static方法是一種不能向?qū)ο髮?shí)施操作的方法,換句話說,靜態(tài)方法不需要訪問對(duì)象的狀態(tài),所有的參數(shù)都來自于顯式的參數(shù)。
面向?qū)ο蟮娜齻€(gè)特征
封裝,繼承,多態(tài),這個(gè)應(yīng)該是人人皆知,有時(shí)候也會(huì)加上抽象。
多態(tài)的好處
允許不同類對(duì)象對(duì)同一消息做出響應(yīng),即同一消息可以根據(jù)發(fā)送對(duì)象的不同而采用多種不同的行為方式(發(fā)送消息就是函數(shù)調(diào)用)。主要有以下優(yōu)點(diǎn):
可替換性:多態(tài)對(duì)已存在代碼具有可替換性
可擴(kuò)充性:增加新的子類不影響已經(jīng)存在的類結(jié)構(gòu)
接口性:多態(tài)是超類通過方法簽名,向子類提供一個(gè)公共接口,由子類來完善或者重寫它來實(shí)現(xiàn)的。
靈活性
簡(jiǎn)化性
代碼中如何實(shí)現(xiàn)多態(tài)
實(shí)現(xiàn)多態(tài)主要有以下三種方式:
1. 接口實(shí)現(xiàn)
2. 繼承父類重寫方法
3. 同一類中進(jìn)行方法重載
虛擬機(jī)是如何實(shí)現(xiàn)多態(tài)的
????動(dòng)態(tài)綁定技術(shù)(dynamic binding),執(zhí)行期間判斷所引用對(duì)象的實(shí)際類型,根據(jù)實(shí)際類型調(diào)用對(duì)應(yīng)的方法。
接口的意義
接口的意義用三個(gè)詞就可以概括:規(guī)范,擴(kuò)展,回調(diào)。
抽象類的意義
抽象類的意義可以用三句話來概括:
????1.為其他子類提供一個(gè)公共的類型
? ? 2.封裝子類中重復(fù)定義的內(nèi)容
? ? 3.定義抽象方法,子類雖然有不同的實(shí)現(xiàn),但是定義時(shí)一致的
父類的靜態(tài)方法能否被子類重寫
不能。重寫只適用于實(shí)例方法,不能用于靜態(tài)方法,而子類當(dāng)中含有和父類相同簽名的靜態(tài)方法,我們一般稱之為隱藏。
接口和抽象類的區(qū)別
生產(chǎn)者消費(fèi)者模型?如何定義?
線程安全是什么意思?
說出final,finalize,finally的區(qū)別?
列舉你常用的幾個(gè)Java工具類。
HashMap與HashSet哪個(gè)更快?它們有什么不同?
二、設(shè)計(jì)模式?
代理模式的適用場(chǎng)景??
答:所謂代理模式,即為一個(gè)對(duì)象創(chuàng)建一個(gè)代理,以控制對(duì)這個(gè)對(duì)象的訪問。?
使用代理的兩種場(chǎng)景:?
控制訪問權(quán)限,不同用戶對(duì)同一對(duì)象擁有不同的訪問權(quán)限
某個(gè)客戶端不能直接操作到某個(gè)對(duì)象,卻又必須與其進(jìn)行交互
三、數(shù)據(jù)庫基礎(chǔ)
事務(wù)的四個(gè)特性
答:事務(wù),是應(yīng)用程序中一系列嚴(yán)密的操作,所有操作必須全部完成,否則在每個(gè)操作中的更改都會(huì)被撤銷。也就是說,一個(gè)事務(wù)中的所有操作要么全部執(zhí)行,要么全不執(zhí)行。
四個(gè)特性:ACID
A:原子性,事務(wù)是數(shù)據(jù)庫的邏輯工作單位,事務(wù)中包含的操作,要么都做,要么都不做。
C:一致性,事務(wù)執(zhí)行的結(jié)果必須是使數(shù)據(jù)庫從一個(gè)一致性狀態(tài)到另一個(gè)一致性狀態(tài)。
I :隔離性,一個(gè)事務(wù)的執(zhí)行不能干擾其他事務(wù)。
D:持續(xù)性,也即永久性,指的是一個(gè)事務(wù)執(zhí)行后對(duì)數(shù)據(jù)庫數(shù)據(jù)的更改是永久性的。
什么是索引?
四、網(wǎng)絡(luò)基礎(chǔ)?
TCP和UDP的區(qū)別?
什么是HTTP協(xié)議?
TCP和HTTP的關(guān)系?
三次握手是怎樣的過程?
TCP如何確認(rèn)對(duì)方收到了消息?
select? distinct name from table;剔除重復(fù)的名字