sql短視頻教程,過(guò)年后想轉(zhuǎn)行做java?
去B站看視頻吧。光有sql基礎(chǔ),你想轉(zhuǎn)行不是那么容易的。而且現(xiàn)在行業(yè)基本飽和了。公司都要熟手,新手估計(jì)懸。畢竟公司不想用太多時(shí)間培養(yǎng)新人。所以轉(zhuǎn)行入java還需慎重考慮
有什么網(wǎng)站可以有題讓我練習(xí)呢?
如果是想找高質(zhì)量面試題的話不妨看看動(dòng)力節(jié)點(diǎn)官網(wǎng)上面試題也是非常全面新鮮的!
Java面試題及答案
1、String類(lèi)可以被繼承嗎?
String類(lèi)在聲明時(shí)使用final關(guān)鍵字修飾,被final關(guān)鍵字修飾的類(lèi)無(wú)法被繼承。
接下來(lái)我們可以看一下String類(lèi)的源代碼片段:
publicfinalclassStringimplementsjava.io.Serializable,Comparable<String>,CharSequence{/Thevalueisusedforcharacterstorage./privatefinalcharvalue[];/Cachethehashcodeforthestring/privateinthash;//Defaultto0/useserialVersionUIDfromJDK1.0.2forinteroperability/privatestaticfinallongserialVersionUID=-6849794470754667710L;
●為什么Java語(yǔ)言的開(kāi)發(fā)者,把String類(lèi)定義為final的呢?
因?yàn)橹挥挟?dāng)字符串是不可變的,字符串池才有可能實(shí)現(xiàn)。字符串池的實(shí)現(xiàn)可以在運(yùn)行時(shí)節(jié)約很多heap空間,因?yàn)椴煌淖址兞慷贾赶虺刂械耐粋€(gè)字符串。但如果字符串是可變的,那么Stringinterning將不能實(shí)現(xiàn),因?yàn)檫@樣的話,如果變量改變了它的值,那么其它指向這個(gè)值的變量的值也會(huì)一起改變。如果字符串是可變的,那么會(huì)引起很?chē)?yán)重的安全問(wèn)題。譬如,數(shù)據(jù)庫(kù)的用戶名、密碼都是以字符串的形式傳入來(lái)獲得數(shù)據(jù)庫(kù)的連接,或者在socket編程中,主機(jī)名和端口都是以字符串的形式傳入。因?yàn)樽址遣豢勺兊?,所以它的值是不可改變的,否則黑客們可以鉆到空子,改變字符串指向的對(duì)象的值,造成安全漏洞。
因?yàn)樽址遣豢勺兊?,所以是多線程安全的,同一個(gè)字符串實(shí)例可以被多個(gè)線程共享。這樣便不用因?yàn)榫€程安全問(wèn)題而使用同步。字符串自己便是線程安全的。
因?yàn)樽址遣豢勺兊模栽谒鼊?chuàng)建的時(shí)候HashCode就被緩存了,不需要重新計(jì)算。這就使得字符串很適合作為Map中的鍵,字符串的處理速度要快過(guò)其它的鍵對(duì)象。這就是HashMap中的鍵往往都使用字符串。
●final關(guān)鍵字除了修飾類(lèi)之外,還有哪些用法呢?
final修飾的變量,一旦賦值,不可重新賦值;
final修飾的方法無(wú)法被覆蓋;
final修飾的實(shí)例變量,必須手動(dòng)賦值,不能采用系統(tǒng)默認(rèn)值;
final修飾的實(shí)例變量,一般和static聯(lián)用,用來(lái)聲明常量;
注意:final不能和abstract關(guān)鍵字聯(lián)合使用。
final表示最終的、不可變的。
2、&和&&的區(qū)別?
●&運(yùn)算符是:邏輯與;&&運(yùn)算符是:短路與。
●&和&&在程序中最終的運(yùn)算結(jié)果是完全一致的,只不過(guò)&&存在短路現(xiàn)象,當(dāng)&&運(yùn)算符左邊的表達(dá)式結(jié)果為false的時(shí)候,右邊的表達(dá)式不執(zhí)行,此時(shí)就發(fā)生了短路現(xiàn)象。如果是&運(yùn)算符,那么不管左邊的表達(dá)式是true還是false,右邊表達(dá)式是一定會(huì)執(zhí)行的。這就是他們倆的本質(zhì)區(qū)別。
●當(dāng)然,&運(yùn)算符還可以使用在二進(jìn)制位運(yùn)算上,例如按位與操作。
3、兩個(gè)對(duì)象值相同equals結(jié)果為true,但卻可有不同的hashCode,這句話對(duì)不對(duì)?
不對(duì),如果兩個(gè)對(duì)象x和y滿足x.equals(y)==true,它們的哈希值(hashCode)應(yīng)當(dāng)相同。Java對(duì)于equals方法和hashCode方法是這樣規(guī)定的:
(1)如果兩個(gè)對(duì)象相同(equals方法返回true),那么它們的hashCode值一定要相同;
(2)如果兩個(gè)對(duì)象的hashCode相同,它們并不一定相同。當(dāng)然,你未必按照要求去做,但是如果你違背了上述原則就會(huì)發(fā)現(xiàn)在使用集合時(shí),相同的對(duì)象可以出現(xiàn)在Set集合中,同時(shí)增加新元素的效率會(huì)大大降低(對(duì)于使用哈希存儲(chǔ)的系統(tǒng),如果哈希碼頻繁的沖突將會(huì)造成存取性能急劇下降)。
關(guān)于equals和hashCode方法,很多Java程序員都知道,但很多人也就是僅僅了解而已,在JoshuaBloch的大作《EffectiveJava》(《EffectiveJava》在很多公司,是Java程序員必看書(shū)籍,如果你還沒(méi)看過(guò),那就趕緊去買(mǎi)一本吧)中是這樣介紹equals方法的:
首先equals方法必須滿足自反性(x.equals(x)必須返回true)、對(duì)稱(chēng)性(x.equals(y)返回true時(shí),y.equals(x)也必須返回true)、傳遞性(x.equals(y)和y.equals(z)都返回true時(shí),x.equals(z)也必須返回true)和一致性(當(dāng)x和y引用的對(duì)象信息沒(méi)有被修改時(shí),多次調(diào)用x.equals(y)應(yīng)該得到同樣的返回值),而且對(duì)于任何非null值的引用x,x.equals(null)必須返回false。實(shí)現(xiàn)高質(zhì)量的equals方法的訣竅包括:
使用==操作符檢查"參數(shù)是否為這個(gè)對(duì)象的引用";
使用instanceof操作符檢查"參數(shù)是否為正確的類(lèi)型";
對(duì)于類(lèi)中的關(guān)鍵屬性,檢查參數(shù)傳入對(duì)象的屬性是否與之相匹配;
編寫(xiě)完equals方法后,問(wèn)自己它是否滿足對(duì)稱(chēng)性、傳遞性、一致性;
重寫(xiě)equals時(shí)總是要重寫(xiě)hashCode;
不要將equals方法參數(shù)中的Object對(duì)象替換為其他的類(lèi)型,在重寫(xiě)時(shí)不要忘掉@Override注解。
4、在Java中,如何跳出當(dāng)前的多重嵌套循環(huán)?
在最外層循環(huán)前加一個(gè)標(biāo)記如outfor,然后用breakoutfor;可以跳出多重循環(huán)。例如以下代碼:
publicclassTestBreak{
publicstaticvoidmain(String[]args){
outfor:for(inti=0;i<10;i++){
for(intj=0;j<10;j++){
if(j==5){
breakoutfor;
}
System.out.println("j="+j);
}
}
}
}
運(yùn)行結(jié)果如下所示:
j=0
j=1
j=2
j=3
j=4
5、重載(overload)和重寫(xiě)(override)的區(qū)別?重載的方法能否根據(jù)返回類(lèi)型進(jìn)行區(qū)分?
方法的重載和重寫(xiě)都是實(shí)現(xiàn)多態(tài)的方式,區(qū)別在于前者實(shí)現(xiàn)的是編譯時(shí)的多態(tài)性,而后者實(shí)現(xiàn)的是運(yùn)行時(shí)的多態(tài)性。
重載發(fā)生在一個(gè)類(lèi)中,同名的方法如果有不同的參數(shù)列表(類(lèi)型不同、個(gè)數(shù)不同、順序不同)則視為重載。
重寫(xiě)發(fā)生在子類(lèi)與父類(lèi)之間,重寫(xiě)要求子類(lèi)重寫(xiě)之后的方法與父類(lèi)被重寫(xiě)方法有相同的返回類(lèi)型,比父類(lèi)被重寫(xiě)方法更好訪問(wèn),不能比父類(lèi)被重寫(xiě)方法聲明更多的異常(里氏代換原則)。重載對(duì)返回類(lèi)型沒(méi)有特殊的要求。
●方法重載的規(guī)則:
方法名一致,參數(shù)列表中參數(shù)的順序,類(lèi)型,個(gè)數(shù)不同。
重載與方法的返回值無(wú)關(guān),存在于父類(lèi)和子類(lèi),同類(lèi)中。
可以拋出不同的異常,可以有不同修飾符。
●方法重寫(xiě)的規(guī)則:
參數(shù)列表、方法名、返回值類(lèi)型必須完全一致;
構(gòu)造方法不能被重寫(xiě);
聲明為final的方法不能被重寫(xiě);
聲明為static的方法不存在重寫(xiě)(重寫(xiě)和多態(tài)聯(lián)合才有意義);
訪問(wèn)權(quán)限不能比父類(lèi)更低;
重寫(xiě)之后的方法不能拋出更寬泛的異常;
6、當(dāng)一個(gè)對(duì)象被當(dāng)作參數(shù)傳遞到一個(gè)方法后,此方法可改變這個(gè)對(duì)象的屬性,并可返回變化后的結(jié)果,那么這里是值傳遞還是引用傳遞?
是值傳遞。Java語(yǔ)言的方法調(diào)用只支持參數(shù)的值傳遞。當(dāng)一個(gè)對(duì)象實(shí)例作為一個(gè)參數(shù)被傳遞到方法中時(shí),參數(shù)的值就是對(duì)該對(duì)象的內(nèi)存地址。這個(gè)值(內(nèi)存地址)被傳遞后,同一個(gè)內(nèi)存地址指向堆內(nèi)存當(dāng)中的同一個(gè)對(duì)象,所以通過(guò)哪個(gè)引用去操作這個(gè)對(duì)象,對(duì)象的屬性都是改變的。
7、為什么方法不能根據(jù)返回類(lèi)型來(lái)區(qū)分重載?
我們來(lái)看以下的代碼:
publicvoidtestMethod(){
doSome();
}
publicvoiddoSome(){
}
publicintdoSome(){
return1;
}
在Java語(yǔ)言中,調(diào)用一個(gè)方法,即使這個(gè)方法有返回值,我們也可以不接收這個(gè)返回值,例如以上兩個(gè)方法doSome(),在testMethod()中調(diào)用的時(shí)候,Java編譯器無(wú)法區(qū)分調(diào)用的具體是哪個(gè)方法。所以對(duì)于編譯器來(lái)說(shuō),doSome()方法不是重載而是重復(fù)了,編譯器報(bào)錯(cuò)。所以區(qū)分這兩個(gè)方法不能依靠方法的返回值類(lèi)型。
8、抽象類(lèi)(abstractclass)和接口(interface)有什么異同?
不同點(diǎn):
●抽象類(lèi)中可以定義構(gòu)造器,接口不能;
●抽象類(lèi)可以有抽象方法和具體方法,接口不能有具體方法;
●接口中的成員全都是public的,抽象類(lèi)中的成員可以使用private、public、protected、默認(rèn)等修飾;
●抽象類(lèi)中可以定義成員變量,接口中只能是常量;
●有抽象方法的類(lèi)必須被聲明為抽象類(lèi),而抽象類(lèi)未必要有抽象方法;
●抽象類(lèi)中可以包含靜態(tài)方法,接口中不能有靜態(tài)方法;
●一個(gè)類(lèi)只能繼承一個(gè)抽象類(lèi),一個(gè)類(lèi)可以實(shí)現(xiàn)多個(gè)接口;
相同點(diǎn):
●不能夠?qū)嵗?/p>
●可以將抽象類(lèi)和接口類(lèi)型作為引用類(lèi)型;
●一個(gè)類(lèi)如果繼承了某個(gè)抽象類(lèi)或者實(shí)現(xiàn)了某個(gè)接口都需要對(duì)其中的抽象方法全部進(jìn)行實(shí)現(xiàn),否則該類(lèi)仍然需要被聲明為抽象類(lèi);
9、char型變量中能不能存儲(chǔ)一個(gè)中文漢字,為什么?
char類(lèi)型可以存儲(chǔ)一個(gè)中文漢字,因?yàn)镴ava中使用的編碼是Unicode(不選擇任何特定的編碼,直接使用字符在字符集中的編號(hào),這是統(tǒng)一的唯一方法),一個(gè)char類(lèi)型占2個(gè)字節(jié)(16比特),所以放一個(gè)中文是沒(méi)問(wèn)題的。
補(bǔ)充:使用Unicode意味著字符在JVM內(nèi)部和外部有不同的表現(xiàn)形式,在JVM內(nèi)部都是Unicode,當(dāng)這個(gè)字符被從JVM內(nèi)部轉(zhuǎn)移到外部時(shí)(例如存入文件系統(tǒng)中),需要進(jìn)行編碼轉(zhuǎn)換。所以Java中有字節(jié)流和字符流,以及在字符流和字節(jié)流之間進(jìn)行轉(zhuǎn)換的轉(zhuǎn)換流,如InputStreamReader和OutputStreamReader,這兩個(gè)類(lèi)是字節(jié)流和字符流之間的適配器類(lèi),承擔(dān)了編碼轉(zhuǎn)換的任務(wù)。
10、抽象的(abstract)方法是否可同時(shí)是靜態(tài)的(static),是否可同時(shí)是本地方法(native),是否可同時(shí)被synchronized?
都不能。
●抽象方法需要子類(lèi)重寫(xiě),而靜態(tài)的方法是無(wú)法被重寫(xiě)的,因此二者是矛盾的。
●本地方法是由本地代碼(如C++代碼)實(shí)現(xiàn)的方法,而抽象方法是沒(méi)有實(shí)現(xiàn)的,也是矛盾的。
●synchronized和方法的實(shí)現(xiàn)細(xì)節(jié)有關(guān),抽象方法不涉及實(shí)現(xiàn)細(xì)節(jié),因此也是相互矛盾的。
Java面向?qū)ο竺嬖囶}
1、面向?qū)ο蟀男┨匦裕趺蠢斫獾模?/p>
(1)封裝:通常認(rèn)為封裝是把數(shù)據(jù)和操作數(shù)據(jù)的方法綁定起來(lái),對(duì)數(shù)據(jù)的訪問(wèn)只能通過(guò)已定義的接口。面向?qū)ο蟮谋举|(zhì)就是將現(xiàn)實(shí)世界描繪成一系列完全自治、封閉的對(duì)象。我們?cè)陬?lèi)中編寫(xiě)的方法就是對(duì)實(shí)現(xiàn)細(xì)節(jié)的一種封裝;我們編寫(xiě)一個(gè)類(lèi)就是對(duì)數(shù)據(jù)和數(shù)據(jù)操作的封裝??梢哉f(shuō),封裝就是隱藏一切可隱藏的東西,只向外界提供最簡(jiǎn)單的編程接口。
(2)繼承:繼承是從已有類(lèi)得到繼承信息創(chuàng)建新類(lèi)的過(guò)程。提供繼承信息的類(lèi)被稱(chēng)為父類(lèi)(超類(lèi)、基類(lèi));得到繼承信息的類(lèi)被稱(chēng)為子類(lèi)(派生類(lèi))。繼承讓變化中的軟件系統(tǒng)有了一定的延續(xù)性,同時(shí)繼承也是封裝程序中可變因素的重要手段。
(3)多態(tài):多態(tài)性是指允許不同子類(lèi)型的對(duì)象對(duì)同一消息作出不同的響應(yīng)。簡(jiǎn)單的說(shuō)就是用同樣的對(duì)象引用調(diào)用同樣的方法但是做了不同的事情。多態(tài)性分為編譯時(shí)的多態(tài)性和運(yùn)行時(shí)的多態(tài)性。如果將對(duì)象的方法視為對(duì)象向外界提供的服務(wù),那么運(yùn)行時(shí)的多態(tài)性可以解釋為:當(dāng)A系統(tǒng)訪問(wèn)B系統(tǒng)提供的服務(wù)時(shí),B系統(tǒng)有多種提供服務(wù)的方式,但一切對(duì)A系統(tǒng)來(lái)說(shuō)都是透明的。方法重載(overload)實(shí)現(xiàn)的是編譯時(shí)的多態(tài)性(也稱(chēng)為前綁定),而方法重寫(xiě)(override)實(shí)現(xiàn)的是運(yùn)行時(shí)的多態(tài)性(也稱(chēng)為后綁定)。運(yùn)行時(shí)的多態(tài)是面向?qū)ο笞罹璧臇|西,要實(shí)現(xiàn)多態(tài)需要做兩件事:
第一:方法重寫(xiě)(子類(lèi)繼承父類(lèi)并重寫(xiě)父類(lèi)中已有的或抽象的方法);
第二:對(duì)象造型(用父類(lèi)型引用指向子類(lèi)型對(duì)象,這樣同樣的引用調(diào)用同樣的方法就會(huì)根據(jù)子類(lèi)對(duì)象的不同而表現(xiàn)出不同的行為)。
(4)抽象:抽象是將一類(lèi)對(duì)象的共同特征出來(lái)構(gòu)造類(lèi)的過(guò)程,包括數(shù)據(jù)抽象和行為抽象兩方面。抽象只關(guān)注對(duì)象有哪些屬性和行為,并不關(guān)注這些行為的細(xì)節(jié)是什么。
2、訪問(wèn)權(quán)限修飾符public、private、protected,以及不寫(xiě)(默認(rèn))時(shí)的區(qū)別?
修飾符
當(dāng)前類(lèi)
同包
子類(lèi)
其他包
public
√
√
√
√
protected
√
√
√
×
默認(rèn)(缺省)
√
√
×
×
private
√
×
×
×
3、Java中為什么要用clone?
在實(shí)際編程過(guò)程中,我們常常要遇到這種情況:有一個(gè)對(duì)象A,在某一時(shí)刻A中已經(jīng)包含了一些有效值,此時(shí)可能會(huì)需要一個(gè)和A完全相同新對(duì)象B,并且此后對(duì)B任何改動(dòng)都不會(huì)影響到A中的值,也就是說(shuō),A與B是兩個(gè)獨(dú)立的對(duì)象,但B的初始值是由A對(duì)象確定的。在Java語(yǔ)言中,用簡(jiǎn)單的賦值語(yǔ)句是不能滿足這種需求的。要滿足這種需求雖然有很多途徑,但clone()方法是其中最簡(jiǎn)單,也是最高效的手段。
●說(shuō)到對(duì)象的克隆,涉及到深克隆和淺克隆?
淺克隆:創(chuàng)建一個(gè)新對(duì)象,新對(duì)象的屬性和原來(lái)對(duì)象完全相同,對(duì)于非基本類(lèi)型屬性,仍指向原有屬性所指向的對(duì)象的內(nèi)存地址。
深克?。簞?chuàng)建一個(gè)新對(duì)象,屬性中引用的其他對(duì)象也會(huì)被克隆,不再指向原有對(duì)象地址。
4、new一個(gè)對(duì)象的過(guò)程和clone一個(gè)對(duì)象的區(qū)別?
new操作符的本意是分配內(nèi)存。程序執(zhí)行到new操作符時(shí),首先去看new操作符后面的類(lèi)型,因?yàn)橹懒祟?lèi)型,才能知道要分配多大的內(nèi)存空間。分配完內(nèi)存之后,再調(diào)用構(gòu)造函數(shù),填充對(duì)象的各個(gè)域,這一步叫做對(duì)象的初始化,構(gòu)造方法返回后,一個(gè)對(duì)象創(chuàng)建完畢,可以把他的引用(地址)發(fā)布到外部,在外部就能使用這個(gè)引用操縱這個(gè)對(duì)象。
clone在第一步是和new相似的,都是分配內(nèi)存,調(diào)用clone方法時(shí),分配的內(nèi)存和原對(duì)象(即調(diào)用clone方法的對(duì)象)相同,然后再使用原對(duì)象中對(duì)應(yīng)的各個(gè)域,填充新對(duì)象的域,填充完成之后,clone方法返回,一個(gè)新的相同的對(duì)象被創(chuàng)建,同樣可以把這個(gè)新對(duì)象的引用發(fā)布到外部。
5、Java中實(shí)現(xiàn)多態(tài)的機(jī)制是什么?
Java中的多態(tài)靠的是父類(lèi)或接口定義的引用變量可以指向子類(lèi)或具體實(shí)現(xiàn)類(lèi)的實(shí)例對(duì)象,而程序調(diào)用的方法在運(yùn)行期才動(dòng)態(tài)綁定,就是引用變量所指向的具體實(shí)例對(duì)象的方法,也就是內(nèi)存里正在運(yùn)行的那個(gè)對(duì)象的方法,而不是引用變量的類(lèi)型中定義的方法。
6、談?wù)勀銓?duì)多態(tài)的理解?
多態(tài)就是指程序中定義的引用變量所指向的具體類(lèi)型和通過(guò)該引用變量發(fā)出的方法調(diào)用在編程時(shí)并不確定,而是在程序運(yùn)行期間才確定,即一個(gè)引用變量到底會(huì)指向哪個(gè)類(lèi)的實(shí)例對(duì)象,該引用變量發(fā)出的方法調(diào)用到底是哪個(gè)類(lèi)中實(shí)現(xiàn)的方法,必須在程序運(yùn)行期間才能決定。因?yàn)樵诔绦蜻\(yùn)行時(shí)才確定具體的類(lèi),這樣,不用修改源代碼,就能讓引用變量綁定到各種不同的對(duì)象上,從而導(dǎo)致該引用調(diào)用的具體方法隨之改變,即不修改程序代碼就能改變程序運(yùn)行時(shí)所綁定的具體代碼,讓程序可以選擇多個(gè)運(yùn)行狀態(tài),這就是多態(tài)性。
7、談?wù)勀銓?duì)面向?qū)ο蟮睦斫猓?/p>
所謂對(duì)象就是由一組數(shù)據(jù)結(jié)構(gòu)和處理它們的方法組成的,重點(diǎn)“數(shù)據(jù)”包括對(duì)象的特性、狀態(tài)等的靜態(tài)信息;“方法”也就是行為,包括該對(duì)象的對(duì)數(shù)據(jù)的操作、功能等能動(dòng)信息。把相同行為的對(duì)象歸納為類(lèi),類(lèi)是一個(gè)抽象的概念,對(duì)象是類(lèi)的具體。簡(jiǎn)單點(diǎn)說(shuō):對(duì)象就是類(lèi)的實(shí)例。例如:小品演員就是一個(gè)類(lèi),趙本山就是一個(gè)對(duì)象。
面向?qū)ο蟮哪康模航鉀Q軟件系統(tǒng)的可擴(kuò)展性,可維護(hù)性和可重用性。
●面向?qū)ο蟮娜筇匦裕悍庋b、多態(tài)和繼承:
(1)封裝(對(duì)應(yīng)可擴(kuò)展性):隱藏對(duì)象的屬性和實(shí)現(xiàn)細(xì)節(jié),僅對(duì)外公開(kāi)接口,控制在程序中屬性的讀和修改的訪問(wèn)級(jí)別。封裝是通過(guò)訪問(wèn)控制符(publicprotectedprivate)來(lái)實(shí)現(xiàn)。一個(gè)類(lèi)就可看成一個(gè)封裝。
(2)繼承(重用性和擴(kuò)展性):子類(lèi)繼承父類(lèi),可以繼承父類(lèi)的方法和屬性??梢詫?duì)父類(lèi)方向進(jìn)行覆蓋(實(shí)現(xiàn)了多態(tài))。但是繼承破壞了封裝,因?yàn)樗菍?duì)子類(lèi)開(kāi)放的,修改父類(lèi)會(huì)導(dǎo)致所有子類(lèi)的改變,因此繼承一定程度上又破壞了系統(tǒng)的可擴(kuò)展性,只有明確的IS-A關(guān)系才能使用。繼承要慎用,盡量?jī)?yōu)先使用組合。
(3)多態(tài)(可維護(hù)性和可擴(kuò)展性):接口的不同實(shí)現(xiàn)方式即為多態(tài)。接口是對(duì)行為的抽象,剛才在封裝提到,找到變化部分并封裝起來(lái),但是封裝起來(lái)后,怎么適應(yīng)接下來(lái)的變化?這正是接口的作用,接口的主要目的是為不相關(guān)的類(lèi)提供通用的處理服務(wù),我們可以想象一下。比如鳥(niǎo)會(huì)飛,但是超人也會(huì)飛,通過(guò)飛這個(gè)接口,我們可以讓鳥(niǎo)和超人,都實(shí)現(xiàn)這個(gè)接口。
面向?qū)ο缶幊蹋∣OP)其實(shí)就是一種設(shè)計(jì)思想,在程序設(shè)計(jì)過(guò)程中把每一部分都盡量當(dāng)成一個(gè)對(duì)象來(lái)考慮,以實(shí)現(xiàn)軟件系統(tǒng)的可擴(kuò)展性,可維護(hù)性和可重用性。
Java異常處理面試題
1、final、finally、finalize的區(qū)別?
●final:用于聲明屬性,方法和類(lèi),分別表示屬性不可變,方法不可覆蓋,被其修飾的類(lèi)不可繼承。
●finally:異常處理語(yǔ)句結(jié)構(gòu)的一部分,表示總是執(zhí)行。
●finalize:Object類(lèi)的一個(gè)方法,所以Java對(duì)象都有這個(gè)方法,當(dāng)某Java對(duì)象沒(méi)有更多的引用指向的時(shí)候,會(huì)被垃圾回收器回收,該對(duì)象被回收之前,由垃圾回收器來(lái)負(fù)責(zé)調(diào)用此方法,通常在該方法中進(jìn)行回收前的準(zhǔn)備工作。該方法更像是一個(gè)對(duì)象生命周期的臨終方法,當(dāng)該方法被系統(tǒng)調(diào)用則代表該對(duì)象即將“死亡”,但是需要注意的是,我們主動(dòng)行為上去調(diào)用該方法并不會(huì)導(dǎo)致該對(duì)象“死亡”,這是一個(gè)被動(dòng)的方法(其實(shí)就是回調(diào)方法),不需要我們調(diào)用。
2、Java中異常分為哪些種類(lèi)?
按照異常需要處理的時(shí)機(jī)分為編譯時(shí)異常(也叫受控異常)也叫CheckedException和運(yùn)行時(shí)異常(也叫非受控異常)也叫UnCheckedException。Java認(rèn)為Checked異常都是可以被處理的異常,所以Java程序必須顯式處理Checked異常。如果程序沒(méi)有處理Checked異常,該程序在編譯時(shí)就會(huì)發(fā)生錯(cuò)誤無(wú)法編譯。這體現(xiàn)了Java的設(shè)計(jì)哲學(xué):沒(méi)有完善錯(cuò)誤處理的代碼根本沒(méi)有機(jī)會(huì)被執(zhí)行。對(duì)Checked異常處理方法有兩種:
●第一種:當(dāng)前方法知道如何處理該異常,則用try...catch塊來(lái)處理該異常。
●第二種:當(dāng)前方法不知道如何處理,則在定義該方法時(shí)聲明拋出該異常。
運(yùn)行時(shí)異常只有當(dāng)代碼在運(yùn)行時(shí)才發(fā)行的異常,編譯的時(shí)候不需要try…catch。Runtime如除數(shù)是0和數(shù)組下標(biāo)越界等,其產(chǎn)生頻繁,處理麻煩,若顯示申明或者捕獲將會(huì)對(duì)程序的可讀性和運(yùn)行效率影響很大。所以由系統(tǒng)自動(dòng)檢測(cè)并將它們交給缺省的異常處理程序。當(dāng)然如果你有處理要求也可以顯示捕獲它們。
3、error和exception的區(qū)別?
Error類(lèi)和Exception類(lèi)的父類(lèi)都是Throwable類(lèi),他們的區(qū)別如下:
●Error類(lèi)一般是指與虛擬機(jī)相關(guān)的問(wèn)題,如系統(tǒng)崩潰,虛擬機(jī)錯(cuò)誤,內(nèi)存空間不足,方法調(diào)用棧溢出等。對(duì)于這類(lèi)錯(cuò)誤的導(dǎo)致的應(yīng)用程序中斷,僅靠程序本身無(wú)法恢復(fù)和預(yù)防,遇到這樣的錯(cuò)誤,建議讓程序終止。
●Exception類(lèi)表示程序可以處理的異常,可以捕獲且可能恢復(fù)。遇到這類(lèi)異常,應(yīng)該盡可能處理異常,使程序恢復(fù)運(yùn)行,而不應(yīng)該隨意終止異常。
●Exception類(lèi)又分為未檢查異常(UnCheckedException)和受檢查的異常(CheckedException)。運(yùn)行時(shí)異常ArithmeticException,IllegalArgumentException編譯能通過(guò),但是一運(yùn)行就終止了,程序不會(huì)處理運(yùn)行時(shí)異常,出現(xiàn)這類(lèi)異常,程序會(huì)終止。而受檢查的異常,要么用try…catch捕獲,要么用throws字句聲明拋出,交給它的父類(lèi)處理,否則編譯不會(huì)通過(guò)。
4、調(diào)用下面的方法,得到的返回值是什么?
1.publicintgetNum(){
2.try{
3.inta=1/0;
4.return1;
5.}catch(Exceptione){
6.return2;
7.}finally{
8.return3;
9.}
10.}
代碼走到第3行的時(shí)候遇到了一個(gè)MathException,這時(shí)第4行的代碼就不會(huì)執(zhí)行了,代碼直接跳轉(zhuǎn)到catch語(yǔ)句中,走到第6行的時(shí)候,異常機(jī)制有一個(gè)原則:如果在catch中遇到了return或者異常等能使該函數(shù)終止的話那么有finally就必須先執(zhí)行完finally代碼塊里面的代碼然后再返回值。因此代碼又跳到第8行,可惜第8行是一個(gè)return語(yǔ)句,那么這個(gè)時(shí)候方法就結(jié)束了,因此第6行的返回結(jié)果就無(wú)法被真正返回。如果finally僅僅是處理了一個(gè)釋放資源的操作,那么該道題最終返回的結(jié)果就是2。因此上面返回值是3。
5、Java異常處理機(jī)制的理解?
Java對(duì)異常進(jìn)行了分類(lèi),不同類(lèi)型的異常分別用不同的Java類(lèi)表示,所有異常的根類(lèi)為java.lang.Throwable,Throwable下面又派生了兩個(gè)子類(lèi):Error和Exception。
Error表示應(yīng)用程序本身無(wú)法克服和恢復(fù)的一種嚴(yán)重問(wèn)題。
Exception表示程序還能夠克服和恢復(fù)的問(wèn)題,其中又分為系統(tǒng)異常和普通異常。
系統(tǒng)異常是軟件本身缺陷所導(dǎo)致的問(wèn)題,也就是軟件開(kāi)發(fā)人員考慮不周所導(dǎo)致的問(wèn)題,軟件使用者無(wú)法克服和恢復(fù)這種問(wèn)題,但在這種問(wèn)題下還可以讓軟件系統(tǒng)繼續(xù)運(yùn)行或者讓軟件死掉,例如,數(shù)組下標(biāo)越界(ArrayIndexOutOfBoundsException),空指針異常(NullPointerException)、類(lèi)轉(zhuǎn)換異常(ClassCastException)。
普通異常是運(yùn)行環(huán)境的變化或異常所導(dǎo)致的問(wèn)題,是用戶能夠克服的問(wèn)題,例如,網(wǎng)絡(luò)斷線,硬盤(pán)空間不夠,發(fā)生這樣的異常后,程序不應(yīng)該死掉。
Java為系統(tǒng)異常和普通異常提供了不同的解決方案,編譯器強(qiáng)制普通異常必須try..catch處理或用throws聲明繼續(xù)拋給上層調(diào)用方法處理,所以普通異常也稱(chēng)為checked異常,而系統(tǒng)異常可以處理也可以不處理,所以編譯器不強(qiáng)制用try..catch處理或用throws聲明,所以系統(tǒng)異常也稱(chēng)為unchecked異常。
6、說(shuō)出最常見(jiàn)的5個(gè)RuntimeException?
●java.lang.NullPointerException空指針異常;出現(xiàn)原因:調(diào)用了未經(jīng)初始化的對(duì)象或者是不存在的對(duì)象。
●java.lang.ClassNotFoundException指定的類(lèi)找不到;出現(xiàn)原因:類(lèi)的名稱(chēng)和路徑加載錯(cuò)誤;通常都是程序試圖通過(guò)字符串來(lái)加載某個(gè)類(lèi)時(shí)可能引發(fā)異常。
●java.lang.NumberFormatException字符串轉(zhuǎn)換為數(shù)字異常;出現(xiàn)原因:字符型數(shù)據(jù)中包含非數(shù)字型字符。
●java.lang.IndexOutOfBoundsException數(shù)組角標(biāo)越界異常,常見(jiàn)于操作數(shù)組對(duì)象時(shí)發(fā)生。
●java.lang.IllegalArgumentException方法傳遞參數(shù)錯(cuò)誤。
●java.lang.ClassCastException數(shù)據(jù)類(lèi)型轉(zhuǎn)換異常。
●java.lang.NoClassDefFoundException未找到類(lèi)定義錯(cuò)誤。
●SQLExceptionSQL異常,常見(jiàn)于操作數(shù)據(jù)庫(kù)時(shí)的SQL語(yǔ)句錯(cuò)誤。
●java.lang.InstantiationException實(shí)例化異常。
●java.lang.NoSuchMethodException方法不存在異常。
7、throw和throws的區(qū)別?
●throw:
throw語(yǔ)句用在方法體內(nèi),表示拋出異常,由方法體內(nèi)的語(yǔ)句處理。
throw是具體向外拋出異常的動(dòng)作,所以它拋出的是一個(gè)異常實(shí)例,執(zhí)行throw一定是拋出了某種異常。
●throws:
throws語(yǔ)句是用在方法聲明后面,表示如果拋出異常,由該方法的調(diào)用者來(lái)進(jìn)行異常的處理。
throws主要是聲明這個(gè)方法會(huì)拋出某種類(lèi)型的異常,讓它的使用者要知道需要捕獲的異常的類(lèi)型。
●throws表示出現(xiàn)異常的一種可能性,并不一定會(huì)發(fā)生這種異常。
現(xiàn)在軟件行業(yè)還像幾年前那么火嗎?
感謝邀請(qǐng)!
作為一名資深非專(zhuān)業(yè)程序員,做軟件開(kāi)發(fā)已經(jīng)十多年了。以前從事軟件行業(yè)吃香,是因?yàn)榛ヂ?lián)網(wǎng)才起步,人才少,但是需求量很大?,F(xiàn)在互聯(lián)網(wǎng)繁榮了,各行各業(yè)都爭(zhēng)先恐后的加入到互聯(lián)網(wǎng)中,需求仍然很大,但是人才輸出比起十幾年前要大得多了,與其說(shuō)有沒(méi)有以前火,不如說(shuō)現(xiàn)在是供需接近飽和了。
培訓(xùn)機(jī)構(gòu)沖擊市場(chǎng)
隨著市場(chǎng)對(duì)軟件行業(yè)人才需求日益旺盛,培訓(xùn)機(jī)構(gòu)也開(kāi)始繁榮昌盛,中低端軟件人才大量輸出,導(dǎo)致就業(yè)市場(chǎng)競(jìng)爭(zhēng)異常激烈。
我記得還在上大學(xué)的時(shí)候,有一家計(jì)算機(jī)培訓(xùn)機(jī)構(gòu)就直接開(kāi)在了學(xué)校旁邊。打出的口號(hào)就是沒(méi)考上大學(xué)不要緊,落榜了不要緊,來(lái)我們這里培訓(xùn)吧,包分配!
大數(shù)據(jù)、人工智能時(shí)代
隨著計(jì)算機(jī)科學(xué)技術(shù)的發(fā)展,軟件行業(yè)對(duì)高端人才的需求越來(lái)越大?,F(xiàn)在各大知名的科技企業(yè),都已經(jīng)在行動(dòng),例如阿里的達(dá)摩院,小米的未來(lái)星計(jì)劃,騰訊的犀牛鳥(niǎo)精英人才計(jì)劃等等。
21實(shí)際最缺的,是人才!在未來(lái)的時(shí)代,是大數(shù)據(jù)、人工智能的時(shí)代。
大數(shù)據(jù)的特點(diǎn)是數(shù)據(jù)量大、類(lèi)型眾多,要從事大數(shù)據(jù)分析,還要求分析效率以及體現(xiàn)有效價(jià)值。
人工智能可以對(duì)人的意識(shí)、思維的信息過(guò)程進(jìn)行模擬,大家都知道,人的意識(shí)和思維是一種復(fù)雜網(wǎng)絡(luò),而復(fù)雜網(wǎng)絡(luò)算法就是人工智能深度學(xué)習(xí)的基礎(chǔ)。
所以在未來(lái),軟件行業(yè)依舊會(huì)很火,只是軟件行業(yè)對(duì)人才的需求從數(shù)量變?yōu)榱速|(zhì)量!
我是程序員愛(ài)編程,一個(gè)資深非專(zhuān)業(yè)碼農(nóng),科技領(lǐng)域段子手!如本回答能夠討得您的歡心,勞請(qǐng)點(diǎn)贊、轉(zhuǎn)發(fā)、關(guān)注我,如有不同看法可以在評(píng)論區(qū)留言,謝謝!
我是程序員愛(ài)編程,一個(gè)資深非專(zhuān)業(yè)碼農(nóng),科技領(lǐng)域段子手!如本回答能夠討得您的歡心,勞請(qǐng)點(diǎn)贊、轉(zhuǎn)發(fā)、關(guān)注我,如有不同看法可以在評(píng)論區(qū)留言,謝謝!
大數(shù)據(jù)主要學(xué)習(xí)什么內(nèi)容?
要從事計(jì)算機(jī)行業(yè)的工作,不管是什么工作,開(kāi)發(fā)、測(cè)試、還是算法等,都是要有一門(mén)自己比較熟練的編程語(yǔ)言,編程語(yǔ)言可以是C語(yǔ)言、Java、C++等,只要是和你后續(xù)工作所相關(guān)的就能(后續(xù)用到其他語(yǔ)言的話,你有一門(mén)語(yǔ)言基礎(chǔ)了,學(xué)起來(lái)就快了)。一般初學(xué)者入門(mén)語(yǔ)言大多都會(huì)選擇Java、C語(yǔ)言、C++或者Python,而且現(xiàn)在網(wǎng)上有很多好的視頻,可以供初學(xué)者學(xué)習(xí)使用。關(guān)于學(xué)習(xí)視頻或者資料的選擇,知乎或者百度等都有很多講解了,也可以跟師兄師姐咨詢,這樣可以少走很多彎路,當(dāng)然,有人說(shuō),走一些彎路總是有好處的,但是我這里說(shuō)的彎路不是說(shuō)不犯錯(cuò)誤,不調(diào)bug,而是指學(xué)習(xí)資料以及一些知識(shí)點(diǎn)的偏重點(diǎn),這樣可以盡量節(jié)約一部分時(shí)間,剛開(kāi)始時(shí),總會(huì)有點(diǎn)迷,而且當(dāng)你真正投入進(jìn)去學(xué)習(xí)時(shí),會(huì)發(fā)現(xiàn)時(shí)間總是不夠用。
我前面是做的Java后端,后續(xù)才轉(zhuǎn)的大數(shù)據(jù),所以一些Java開(kāi)發(fā)所需要的東西自己也有學(xué)習(xí)過(guò),也都是按照正常的路線走的,JavaSE階段,然后數(shù)據(jù)庫(kù),SSM框架,接著做了一些網(wǎng)上找的項(xiàng)目,之后發(fā)現(xiàn)對(duì)大數(shù)據(jù)比較感興趣,就開(kāi)始找大數(shù)據(jù)相關(guān)的資料學(xué)習(xí),看視頻,看博客,敲代碼,前期大概花了3-4個(gè)月吧(公眾號(hào)的這些資料就是我當(dāng)時(shí)看過(guò)的),也是一步步艱難走過(guò)來(lái)的,剛剛開(kāi)始接觸大數(shù)據(jù)相關(guān)的東西時(shí),一度懷疑這么多東西自己能否學(xué)得完,是不是能用得到,學(xué)完又忘了,忘了又回頭看,不過(guò)還好,堅(jiān)持過(guò)來(lái)了,還好沒(méi)有放棄,工作也還ok,找的大數(shù)據(jù)開(kāi)發(fā)崗,待遇也還不錯(cuò)吧。
下面就說(shuō)一下我自己從Java開(kāi)發(fā)到大數(shù)據(jù)開(kāi)發(fā)的曲折學(xué)習(xí)之路(狗頭保命.jpg)。因?yàn)槲椰F(xiàn)在是做大數(shù)據(jù)相關(guān)的工作了,所以Java后端涉及到的一些SSM框架等知識(shí)點(diǎn)我就不介紹了,畢竟后續(xù)一段時(shí)間也沒(méi)有做了。自己看過(guò)的大數(shù)據(jù)學(xué)習(xí)相關(guān)的視頻+資料大概是200G-300G吧,從Linux->Hadoop->。。。->Spark->項(xiàng)目,還有就是一些面試文檔,面經(jīng)等。一些視頻看了兩遍或者更多,跟著學(xué),跟著敲代碼,做項(xiàng)目,準(zhǔn)備面試。涉及到需要學(xué)習(xí)的東西包括:JavaSE,數(shù)據(jù)結(jié)構(gòu)與算法(計(jì)算機(jī)行業(yè)必備),MySQL,Redis,ES(數(shù)據(jù)庫(kù)這些可以看項(xiàng)目,也可以自己熟練一兩個(gè)),Linux,Shell(這個(gè)可以后期補(bǔ)),Hadoop,Zookeeper,Hive,F(xiàn)lume,Kafka,HBase,Scala(Spark是Scala寫(xiě)的,會(huì)Scala做相關(guān)的項(xiàng)目會(huì)更容易入手),Spark,F(xiàn)link(這個(gè)是找工作時(shí)有面試官問(wèn)過(guò)幾次liao不liao解,所以找完工作才開(kāi)始接觸學(xué)習(xí)),相關(guān)項(xiàng)目。
編程語(yǔ)言階段學(xué)習(xí)
?如果是零基礎(chǔ)的話,建議還是從視頻開(kāi)始入門(mén)比較好,畢竟一上來(lái)就看教材,這樣有些代碼的來(lái)龍去脈可能不是很了解。如果是有一些編程語(yǔ)言基礎(chǔ)的話,從視頻開(kāi)始也會(huì)更簡(jiǎn)單,一些for、while循環(huán)你都知道了,學(xué)起來(lái)也會(huì)快很多。?JavaSE我是選擇的某馬劉意的為主,因?yàn)閯倓傞_(kāi)始學(xué)Java看過(guò)一本從《Java從入門(mén)到精通》,沒(méi)什么感覺(jué),后續(xù)又在看了某課網(wǎng)的Java初級(jí)視頻,還是沒(méi)感覺(jué)出來(lái)啥(當(dāng)時(shí)就有點(diǎn)懷疑自己了。。。),可能有點(diǎn)沒(méi)進(jìn)入狀態(tài)。?還好后續(xù)找了某馬劉意老師的JavaSE視頻(我是看的2015年版本,那時(shí)候19版還沒(méi)出),覺(jué)得他講的真的是很好很詳細(xì),每個(gè)知識(shí)點(diǎn)都會(huì)有例子,也都會(huì)帶你敲代碼,做測(cè)試,可能前面有C語(yǔ)言基礎(chǔ),然后也看過(guò)Java的一些語(yǔ)法,所以學(xué)起來(lái)還是比較順利,后面的IO流、多線程等知識(shí)點(diǎn)時(shí),也有看書(shū)看博客,或者看看其他老師的課程,講解的可能自己比較容易接受就能,反正都是多嘗試(下面會(huì)給出視頻鏈接),盡量懂一些,后續(xù)可以回頭來(lái)復(fù)習(xí)。JavaSE相關(guān)的視頻,先看一遍,后續(xù)有時(shí)間建議再看一遍,而且這些經(jīng)典的視頻,看兩遍真的是享受。?如果有一定基礎(chǔ)了的,JavaSE前面七八天的視頻可以加速看,但是不懂的一定要停下開(kāi)仔細(xì)想想,零基礎(chǔ)的還是盡量不要加速吧,慢慢來(lái)穩(wěn)些。后面的視頻建議還是跟著視頻來(lái),盡量不要加速,代碼盡量都敲一敲,第一遍基本上一個(gè)月到一個(gè)半月可以結(jié)束。?JavaSE可以說(shuō)是很基礎(chǔ)也很重要的東西,主要重點(diǎn)包括面向?qū)ο蟆⒓希↙ist、Map等),IO流,String/StringBuilder/StringBuffer、反射、多線程,這些最好是都要熟悉一些,面試也是重點(diǎn)。?JavaSE之后,如果你是要走前端或后端開(kāi)發(fā)路線的話,可以跟著一些網(wǎng)上的視頻繼續(xù)學(xué)習(xí),這里我就不多做介紹了。
===========分割線,Scala可以后續(xù)Spark階段再接觸學(xué)習(xí)=============
?Scala的學(xué)習(xí),Scala是一門(mén)多范式(multi-paradigm)的編程語(yǔ)言,Scala支持面向?qū)ο蠛秃瘮?shù)式編程,最主要的是后續(xù)Spark的內(nèi)容需要用到Scala,所以前面學(xué)習(xí)了JavaSE,到Spark學(xué)習(xí)之前,再把Scala學(xué)習(xí)一波,美滋滋,而且Scala可以和Java進(jìn)行無(wú)縫對(duì)接,混合使用,更是爽歪歪。后續(xù)Spark學(xué)習(xí)時(shí)基本都是用的Scala,也可能是和Java結(jié)合使用,所以Spark之前建議還是先學(xué)一波Scala,而且Scala用起來(lái)真是很舒服(wordcount一行代碼搞定),適合迭代式計(jì)算,對(duì)數(shù)據(jù)處理有很大幫助,不過(guò)Scala看代碼很容易看懂,但是學(xué)起來(lái)還是挺難的,比如樣例類(lèi)(caseclass)用起來(lái)真是nice,但是隱式轉(zhuǎn)換學(xué)起來(lái)就相對(duì)比較難。學(xué)習(xí)Scala的建議:1.學(xué)習(xí)scala特有的語(yǔ)法,2.搞清楚scala和java區(qū)別,3.了解如何規(guī)范的使用scala。Scala對(duì)學(xué)習(xí)Spark是很重要的(后面Flink也是要用),雖然現(xiàn)在很多公司還是用Java開(kāi)發(fā)比較多,而且Spark是Scala寫(xiě)的,如果要讀源碼,會(huì)Scala還是很重要的(至少要看得懂代碼)。?Scala主要重點(diǎn)包括:隱式轉(zhuǎn)換和隱式參數(shù)、模式匹配、函數(shù)式編程。這里我看的是某硅谷韓老師的Scala視頻,韓老師講的真的很不錯(cuò),五星推薦,哈哈。?也許有人會(huì)覺(jué)得Python也是需要的,但是學(xué)習(xí)階段,可能用Java還是比較多,面試也基本都是問(wèn)Java相關(guān)的內(nèi)容,所以Python后續(xù)工作會(huì)用到的話,再看看Python的內(nèi)容吧。
大數(shù)據(jù)框架階段學(xué)習(xí)
?大數(shù)據(jù)這方面的知識(shí)點(diǎn)自己可以說(shuō)真的是從零開(kāi)始的,剛剛開(kāi)始學(xué)那會(huì)Linux基本都沒(méi)用過(guò),心里那個(gè)虛啊,而且時(shí)間也緊迫,想起來(lái)都是一把辛酸淚。?剛剛開(kāi)始學(xué)的時(shí)候,看了廈門(mén)大學(xué)林子雨的《大數(shù)據(jù)技術(shù)原理與應(yīng)用》課程,可能這個(gè)課程是面對(duì)上課的,所以看了一些,感覺(jué)對(duì)自己幫助不是很大(并不是說(shuō)課程不好,可能不太適合自己,如果是要了解理論知識(shí),很透徹,但是俺時(shí)間緊迫啊),所以就繼續(xù)在網(wǎng)上找視頻,然后發(fā)現(xiàn)某硅谷的培訓(xùn)視頻很多人去參加,而且知識(shí)點(diǎn)也很齊全,大數(shù)據(jù)相關(guān)組件都有講課,還有一些項(xiàng)目比較好,所以就找了它相關(guān)的視頻,當(dāng)時(shí)看的是2018年的,所以視頻不算舊。?來(lái)一張推薦系統(tǒng)架構(gòu)的圖,先看看
?一般來(lái)說(shuō),F(xiàn)lume+Kafka對(duì)數(shù)據(jù)進(jìn)行采集聚合傳輸,一方面Spark對(duì)實(shí)時(shí)數(shù)據(jù)進(jìn)行處理,傳輸給相應(yīng)的數(shù)據(jù)處理模塊(比如實(shí)時(shí)數(shù)據(jù)處理的算法模塊,Spark也有提供常見(jiàn)的機(jī)器學(xué)習(xí)算法的程序庫(kù)),另一方面采集的數(shù)據(jù)也可以放入數(shù)據(jù)庫(kù)(HBase、MongoDB等)中,后續(xù)MapReduce對(duì)離線數(shù)據(jù)進(jìn)行離線處理,數(shù)據(jù)處理完畢用于后續(xù)的使用,數(shù)據(jù)采集處理的流程大概就是這樣。如果是推薦系統(tǒng),實(shí)時(shí)推薦會(huì)給用戶產(chǎn)生實(shí)時(shí)的推薦結(jié)果,讓用戶進(jìn)行查閱選擇,比如你在界面瀏覽了或者看了新的物品,然后刷新下界面,可能給你展示的東西就有一些變成跟你剛剛瀏覽的相關(guān)了。離線推薦的話主要是對(duì)離線數(shù)據(jù)進(jìn)行處理,為物品或種類(lèi)做出相似的推薦,如果后續(xù)用戶搜索相應(yīng)的物品時(shí),給用戶展示相應(yīng)的產(chǎn)品。
?大數(shù)據(jù)學(xué)習(xí)路線:Linux->Hadoop->Zookeeper->Hive->Flume->Kafka->HBase->Scala->Spark->項(xiàng)目->Flink(如果需要學(xué)習(xí)Storm,在Spark前面學(xué)習(xí))
一、Linux(基本操作)
?一般我們使用的都是虛擬機(jī)來(lái)進(jìn)行操作,所以要安裝VM(VirtualMachine),我使用的是CentOS,所以VM和CentOS都要跟著安裝好,跟著視頻操作,一定要?jiǎng)邮謱?shí)踐,將一些Linux基本命令熟練掌握,一些VIM編輯器的命令也要會(huì)用,做相應(yīng)的一些配置,使用SecureCRT來(lái)做遠(yuǎn)程登錄操作(也可以使用其他的,自己順手就行)。再?gòu)?qiáng)調(diào)一遍,基本操作命令盡量熟練一點(diǎn),如果一下記不住,打印一些常用的,自己看看,多用多實(shí)踐,慢慢就會(huì)用了。還有一些軟件包的下載安裝卸載等,跟著操作一遍,熟悉下,后續(xù)都會(huì)使用,Shell編程可以后續(xù)補(bǔ)。
二、Hadoop(重點(diǎn)中的重點(diǎn))
?Hadoop是一個(gè)分布式系統(tǒng)基礎(chǔ)框架,用于主要解決海量數(shù)據(jù)的存儲(chǔ)和海量數(shù)據(jù)的分析計(jì)算問(wèn)題,也可以說(shuō)Hadoop是后續(xù)整個(gè)集群環(huán)境的基礎(chǔ),很多框架的使用都是會(huì)依賴(lài)于Hadoop。主要是由HDFS、MapReduce、YARN組成。這個(gè)部分安裝Hadoop,Hadoop的三個(gè)主要組成部分是重點(diǎn),對(duì)他們的概念要理解出來(lái),知道他們是做什么的,搭建集群環(huán)境,偽分布式模式和完全分布式模式的搭建,重要的是完全分布式的搭建,這些部分一定要自己動(dòng)手實(shí)踐,自己搭建集群,仔細(xì)仔細(xì)再仔細(xì),Hadoop的NameNode,DataNode,YARN的啟動(dòng)關(guān)閉命令一定要知道,以及他們的啟動(dòng)關(guān)閉順序要記住,不要搞混。后續(xù)視頻會(huì)有一些案例操作,跟著寫(xiě)代碼,做測(cè)試,把基本環(huán)境都配置好,后續(xù)這個(gè)集群(完全分布式需要三臺(tái)虛擬機(jī))要一直使用。
三、Zookeeper
?Zookeeper是一個(gè)開(kāi)源的分布式的,為分布式應(yīng)用提供協(xié)調(diào)服務(wù)的Apache項(xiàng)目。分布式安裝ZK,對(duì)ZK有一定的了解就能了,了解它的應(yīng)用場(chǎng)景,以及內(nèi)部原理,跟著做一些操作,基本上有一些了解即可。
四、Hive(重點(diǎn))
?Hive是基于Hadoop的數(shù)據(jù)倉(cāng)庫(kù)工具,可以將結(jié)構(gòu)化的數(shù)據(jù)文件映射為一張表,并提供類(lèi)SQL查詢功能。Hive的安裝,它的數(shù)據(jù)類(lèi)型,以及它的數(shù)據(jù)定義、數(shù)據(jù)操作有較好的了解,怎么操作表(創(chuàng)建表、刪除表,創(chuàng)建什么類(lèi)型的表,他們有什么不同),怎么操作數(shù)據(jù)(加載數(shù)據(jù),下載數(shù)據(jù),對(duì)不同的表進(jìn)行數(shù)據(jù)操作),對(duì)數(shù)據(jù)的查詢一定要進(jìn)行實(shí)踐操作,以及對(duì)壓縮方式和存儲(chǔ)格式要有一些了解,用到時(shí)不懂也可以去查,最好是能理解清楚。這部分有什么面試可能會(huì)問(wèn),所以視頻后續(xù)的面試講解可以看看,理解清楚。
五、Flume
?Flume是一個(gè)高可用的,高可靠的,分布式的海量日志采集、聚合和傳輸?shù)南到y(tǒng)。對(duì)于Flume,對(duì)它的組成架構(gòu),以及對(duì)FlumeAgent的內(nèi)部原理要理解清楚,Source、Channel、Sink一定要知道它們的各種類(lèi)型以及作用,有哪些拓?fù)浣Y(jié)構(gòu)是常見(jiàn)常用的,例如一對(duì)一,單Source、多Channel、多Sink等,它們有什么作用,要理解清楚。還有一個(gè)重點(diǎn),就是對(duì)Flume的配置文件一定要了解清楚,不懂的可以上官網(wǎng)查看案例,對(duì)于不同的情況,它的配置文件要做相應(yīng)的修改,才能對(duì)數(shù)據(jù)進(jìn)行采集處理,視頻中的實(shí)踐案例一定要跟著做。
六、Kafka(重點(diǎn))
?Kafka是一個(gè)分布式消息隊(duì)列,用來(lái)緩存數(shù)據(jù)的。比如說(shuō)實(shí)時(shí)計(jì)算中可以通過(guò)Flume+Kafka對(duì)數(shù)據(jù)進(jìn)行采集處理之后,SparkStreaming再使用Kafka相應(yīng)的Topic中的數(shù)據(jù),用于后續(xù)的計(jì)算使用。對(duì)于Kafka,要理解Kafka的架構(gòu),什么是Kafka,為什么需要Kafka,應(yīng)用場(chǎng)景?;镜拿钚胁僮饕莆?,比如怎么創(chuàng)建刪除Topic,怎么通過(guò)生產(chǎn)者生成數(shù)據(jù),消費(fèi)者怎么消費(fèi)數(shù)據(jù)等基本操作,官網(wǎng)也是有一些案例可以查閱的。
七、HBase(重點(diǎn))
?HBase是一個(gè)分布式的、基于列存儲(chǔ)的開(kāi)源數(shù)據(jù)庫(kù)。HBase適合存儲(chǔ)PB級(jí)別的海量數(shù)據(jù),也可以說(shuō)HBase是很適合大數(shù)據(jù)的存儲(chǔ)的,它是基于列式存儲(chǔ)數(shù)據(jù)的,列族下面可以有非常多的列,列族在創(chuàng)建表的時(shí)候就必須指定。所以對(duì)HBase的數(shù)據(jù)結(jié)構(gòu)要有一定的理解,特別是RowKey的設(shè)計(jì)部分(因?yàn)槊嬖嚤粏?wèn)到過(guò),咳咳,所以點(diǎn)一下),對(duì)于它的原理要了解,一些基本操作也要都會(huì),比如創(chuàng)建表,對(duì)表的操作,基本的API使用等。
八、Spark(重點(diǎn)中的重點(diǎn))
?Spark是快速、易用、通用的大數(shù)據(jù)分析引擎。一說(shuō)到Spark,就有一種哪哪都是重點(diǎn)感覺(jué),哈哈。?Spark的組成可以看下圖
?Spark是基于內(nèi)存計(jì)算的,對(duì)于數(shù)據(jù)的處理速度要比MapReduce快很多很多,而且數(shù)據(jù)挖掘這些都是要對(duì)數(shù)據(jù)做迭代式計(jì)算,MapReduce對(duì)數(shù)據(jù)的處理方式也不適合,而Spark是可以進(jìn)行迭代式計(jì)算,很適合數(shù)據(jù)挖掘等場(chǎng)景。Spark的SparkSQL能夠?qū)Y(jié)構(gòu)化數(shù)據(jù)進(jìn)行處理,SparkSQL的DataFrame或DataSet可以作為分布式SQL查詢引擎的作用,可以直接使用Hive上的表,對(duì)數(shù)據(jù)進(jìn)行處理。SparkStreaming主要用于對(duì)應(yīng)用場(chǎng)景中的實(shí)時(shí)流數(shù)據(jù)進(jìn)行處理,支持多種數(shù)據(jù)源,DStream是SparkStreaming的基礎(chǔ)抽象,由一系列RDD組成,每個(gè)RDD中存放著一定時(shí)間段的數(shù)據(jù),再對(duì)數(shù)據(jù)進(jìn)行處理,而且是基于內(nèi)存計(jì)算,速度快,所以很適合實(shí)時(shí)數(shù)據(jù)的處理。SparkMLlib提供常見(jiàn)的機(jī)器學(xué)習(xí)(ML)功能的程序庫(kù)。包括分類(lèi)、回歸、聚類(lèi)、協(xié)同過(guò)濾等,還提供了模型評(píng)估、數(shù)據(jù)導(dǎo)入等額外的支持功能。對(duì)Spark的核心組件、部署模式(主要是Standalone模式和YARN模式)、通訊架構(gòu)、任務(wù)調(diào)度要有一定了解(面試問(wèn)到了可以說(shuō)一波),SparkShuffle要好好理解,還有內(nèi)存管理要知道,對(duì)Spark的內(nèi)核原理一定要好好理解,不僅面試可能要用,以后工作也是有幫助的。
九、Flink(重點(diǎn)中的重點(diǎn))
?Flink是一個(gè)框架和分布式處理引擎,用于對(duì)無(wú)界(有開(kāi)始無(wú)結(jié)束)和有界(有開(kāi)始有結(jié)束)數(shù)據(jù)流進(jìn)行有狀態(tài)計(jì)算?,F(xiàn)在主要是阿里系公司使用的比較多,很多公司使用的還是Spark居多,而且Flink基本上都是和Spark很多功能大體上一樣的,但是以后Flink和Spark孰強(qiáng)孰弱還有待時(shí)間的考驗(yàn),不過(guò)Flink近幾年越來(lái)越火了這是事實(shí),所以如果有時(shí)間有精力的話,可以學(xué)一學(xué)Flink相關(guān)的內(nèi)容也是很不錯(cuò)的。Spark和Flink主要都是在數(shù)據(jù)處理方面應(yīng)用,在數(shù)據(jù)處理方面的話,離線數(shù)據(jù)處理:Flink暫時(shí)比不上Spark,SparkSQL優(yōu)點(diǎn)在于可以和Hive進(jìn)行無(wú)縫連接,SparkSQL可以直接使用Hive中的表;Flink暫時(shí)做不到這一步,因?yàn)楣俜讲恢С诌@一操作,F(xiàn)link只能將數(shù)據(jù)讀取成自己的表,不能直接使用Hive中的表。對(duì)于實(shí)時(shí)數(shù)據(jù)的處理:Flink和Spark可以說(shuō)是平分秋吧,而且Flink是以事件為驅(qū)動(dòng)對(duì)數(shù)據(jù)進(jìn)行處理,而Spark是以時(shí)間為驅(qū)動(dòng)對(duì)數(shù)據(jù)進(jìn)行處理,在一些應(yīng)用場(chǎng)景中,也許Flink的效果比Spark的效果還要好些,因?yàn)镕link對(duì)數(shù)據(jù)更加的敏感。比如一秒鐘如果觸發(fā)了成千上萬(wàn)個(gè)事件,那么時(shí)間驅(qū)動(dòng)型就很難對(duì)數(shù)據(jù)做細(xì)致的計(jì)算,而事件驅(qū)動(dòng)型可以以事件為單位,一個(gè)個(gè)事件進(jìn)行處理,相比而言延遲更低,處理效果更好?,F(xiàn)在使用Flink的公司越來(lái)越多,有時(shí)間學(xué)習(xí)下,也算是有個(gè)準(zhǔn)備。
項(xiàng)目階段
?其實(shí)某硅谷的視頻里面有很多大數(shù)據(jù)相關(guān)的項(xiàng)目,而且都是文檔配代碼的,B站上也有視頻,學(xué)習(xí)期間可以跟著視頻做兩到三個(gè)項(xiàng)目,自己理清思路,把項(xiàng)目理解透徹,還是可以學(xué)到很多東西的。?根據(jù)自己情況,選擇兩到三個(gè)項(xiàng)目重點(diǎn)跟著做,理解透徹一點(diǎn)
大數(shù)據(jù)項(xiàng)目實(shí)戰(zhàn)
?某硅谷的視頻里面有很多大數(shù)據(jù)相關(guān)的項(xiàng)目,而且都是文檔配代碼的,學(xué)習(xí)期間可以跟著視頻做兩到三個(gè)項(xiàng)目,自己理清思路,把項(xiàng)目理解透徹,還是可以學(xué)到很多東西的。根據(jù)自己情況,選擇兩到三個(gè)項(xiàng)目重點(diǎn)跟著做,理解透徹一點(diǎn)。相關(guān)項(xiàng)目文檔資料我已經(jīng)放到網(wǎng)盤(pán),GongZhongHao回復(fù)相應(yīng)關(guān)鍵字獲取領(lǐng)取方式。?相關(guān)項(xiàng)目、涉及技術(shù)框架及其B站鏈接(B站鏈接主要是為了有些小伙伴網(wǎng)盤(pán)速度限制,這樣就下載文檔資料即可)
書(shū)籍
?書(shū)籍部分直接云盤(pán)鏈接保存即可,這里我放兩張Java開(kāi)發(fā)和大數(shù)據(jù)開(kāi)發(fā)我自己的書(shū)單(很多,路漫漫,吾將上下而求索~)?Java后端書(shū)架:
?大數(shù)據(jù)書(shū)架:
?大概就這些,看完就需要很久了,大部分我也是需要的時(shí)候看相應(yīng)的部分,所以有時(shí)間可以好好看下,不然就需要哪一部分看哪一部分,有助于學(xué)習(xí)即可。
最后
?大數(shù)據(jù)開(kāi)發(fā)也是需要編程基礎(chǔ)的,并不是學(xué)會(huì)使用這些框架怎么樣就能了,所以對(duì)于編程語(yǔ)言,數(shù)據(jù)結(jié)構(gòu)與算法,計(jì)算機(jī)網(wǎng)絡(luò)這些基礎(chǔ)也是要的,這些基礎(chǔ)知識(shí)也有助于自己以后的發(fā)展,如果是應(yīng)屆生校招的話,面試基本上都是JavaSE和數(shù)據(jù)結(jié)構(gòu)與算法等的知識(shí)點(diǎn),還有大數(shù)據(jù)組件相關(guān)的知識(shí)點(diǎn),以及對(duì)項(xiàng)目的理解,這些都是要自己面試前準(zhǔn)備好的,多看面經(jīng),多找面試題看,面幾次,心里有譜了,后續(xù)面試就好了。?不管是從事什么樣的計(jì)算機(jī)相關(guān)的崗位,編程都是很重要的,數(shù)據(jù)結(jié)構(gòu)與算法特別重要,還有就是leetcode等編程網(wǎng)站刷題,提升自己的編程思維,后續(xù)筆試面試都要要的。?要將一行行代碼看做一疊疊rmb,但是一行行代碼能不能轉(zhuǎn)換成一疊疊rmb,自己就一定要:堅(jiān)持,多敲代碼;多敲代碼,堅(jiān)持;堅(jiān)持。?
零基礎(chǔ)學(xué)習(xí)SQL怎么起步?
首先不知道你是在校學(xué)生還是工作了轉(zhuǎn)行要學(xué)習(xí)SQL這方面的知識(shí)。
如果是在校學(xué)生的話,就先根據(jù)課堂上老師的講的內(nèi)容和書(shū)本的上的知識(shí)慢慢學(xué)吧,畢竟這方面內(nèi)容說(shuō)多也不多,說(shuō)難也不難。
如果你是轉(zhuǎn)行學(xué)習(xí)SQL的話,建議先不要看書(shū),看書(shū)的話,文字比較多,很多內(nèi)容可能對(duì)你來(lái)說(shuō)比較晦澀難懂。建議先找個(gè)教學(xué)視頻看看,網(wǎng)上很多教學(xué)視頻,基本上都是選擇重要知識(shí)點(diǎn)去講,這樣你理解起來(lái)也很快。后面可以根據(jù)自己需要在看書(shū)吧!
希望我的回答對(duì)你有所幫助,謝謝。
抖匯吧»sql短視頻教程_過(guò)年后想轉(zhuǎn)行做java