一.什么是全棧工程師?
簡(jiǎn)單概括就是全能型的人才;比如說(shuō)你一個(gè)人能夠把服務(wù)器搭建起來(lái)、能夠把數(shù)據(jù)庫(kù)建好、能夠?qū)慦eb程序連接數(shù)據(jù)庫(kù),不管是用JAVA還是PHP或者別的語(yǔ)言。如java使用JDBC、PHP使用PDO、Node.js使用Node.js的MySQL擴(kuò)展等。不管用什么方式把服務(wù)器搭好、服務(wù)器數(shù)據(jù)庫(kù)連接好、寫(xiě)Web程序、包括我們的網(wǎng)頁(yè)客戶端+ios客戶端和Android客戶端,一個(gè)人能夠把一個(gè)APP做起來(lái)做上線,那么你就可以認(rèn)為自己是一個(gè)全棧工程師了。
棧是什么?
堆棧的棧。堆棧:比如說(shuō)你把一摞書(shū)摞在桌子上,那么在內(nèi)存中表現(xiàn)的數(shù)據(jù)結(jié)構(gòu)我們稱它為一個(gè)棧,再把一本新的書(shū)放上去就會(huì)越摞越高,越后面放的書(shū)越在上面,越早放的書(shū)越在下面,這就叫棧。如果要拿出從上面拿起,越后放的書(shū)反而越先拿;所以棧這種數(shù)據(jù)結(jié)構(gòu)的特點(diǎn)就是先進(jìn)后出,后進(jìn)先出。
混合APP開(kāi)發(fā)模式
??與用戶交互的前端技術(shù)分為兩類:一類是客戶端程序,另一類是網(wǎng)頁(yè)端程序;如果寫(xiě)網(wǎng)頁(yè)端程序就要學(xué)習(xí)HTML、CSS和JS;如果要寫(xiě)客戶端程序就要學(xué)習(xí)ios和Android;把這兩者結(jié)合起來(lái)就是混合APP開(kāi)發(fā)模式。
全棧工程師的特點(diǎn)是通往架構(gòu)師之路,我們知道做技術(shù)的最高端,站在金字塔頂端的人是架構(gòu)師。如果要做架構(gòu)師全棧工程師就是起點(diǎn),因?yàn)槿珬9こ處熕械募夹g(shù)環(huán)節(jié)都知道。
二.編程語(yǔ)言的發(fā)展歷史
??編程語(yǔ)言的特點(diǎn):可以控制我們的指令、進(jìn)行內(nèi)存的分配、可以執(zhí)行我們的程序邏輯。(HTML和CSS沒(méi)有這個(gè)能力所以不算編程語(yǔ)言,能夠承載邏輯的才是編程語(yǔ)言)
機(jī)器語(yǔ)言
??最原始、最底層的編程語(yǔ)言就是機(jī)器語(yǔ)言,機(jī)器語(yǔ)言是直接跟硬件電路相關(guān)的,比如說(shuō)CPU有很多幀口數(shù),我們通過(guò)電路指令給它每個(gè)幀口數(shù)通電是高電位還是低電位(是1還是0),它會(huì)給我們返回運(yùn)算結(jié)果。CPU就是通過(guò)這種硬件電路來(lái)工作的,這種硬件電路就是近機(jī)器語(yǔ)言(0101二進(jìn)制這種類型)。這種就屬于硬件編程,也屬于機(jī)器語(yǔ)言編程。
匯編語(yǔ)言
比機(jī)器語(yǔ)言高級(jí)點(diǎn)就是匯編語(yǔ)言,匯編語(yǔ)言是直接通過(guò)我們的英文單詞給我們的機(jī)器下指令,匯編語(yǔ)言會(huì)經(jīng)過(guò)編譯器解析之后直接生成機(jī)器碼。
高級(jí)語(yǔ)言
比匯編語(yǔ)言更高級(jí)的語(yǔ)言我們統(tǒng)稱為高級(jí)語(yǔ)言,高級(jí)語(yǔ)言是從C語(yǔ)言開(kāi)始起步的,C、C++、Java包括現(xiàn)在的JS、Ruby、Python、go等。
??高級(jí)語(yǔ)言又有分類,一般編程語(yǔ)言在10年至20年之間都會(huì)有一次大的變革。比如說(shuō)從1946年第一臺(tái)計(jì)算機(jī)的硬件編碼到50年代末期的匯編語(yǔ)言才流行起來(lái),到60年代末期C語(yǔ)言就誕生了,我們都知道C語(yǔ)言和UNIX操作系統(tǒng)同時(shí)誕生的,C語(yǔ)言和匯編語(yǔ)言比起來(lái)就屬于高級(jí)語(yǔ)言了,因?yàn)榇a有復(fù)用性了,寫(xiě)好的代碼可以在很多臺(tái)機(jī)器上面都可以編譯。而匯編是不可以的,匯編針對(duì)每一臺(tái)機(jī)器CPU指令都不同,都要重新寫(xiě)。但是C語(yǔ)言就可以一處編寫(xiě),到處編譯。在不同的機(jī)器上編譯就會(huì)翻譯成不同的機(jī)器碼以供使用。C語(yǔ)言稱之為結(jié)構(gòu)化的編程語(yǔ)言,就是因?yàn)镃語(yǔ)言有了函數(shù),函數(shù)可以調(diào)用函數(shù),函數(shù)之間可以傳遞參數(shù)有返回值,這樣的話代碼看起來(lái)更清晰能夠有模塊化了。其中最重要的一點(diǎn)就是可以抽象,可以把一個(gè)大型的項(xiàng)目切得很小對(duì)項(xiàng)目進(jìn)行劃分。然后隨著項(xiàng)目越來(lái)越大,C語(yǔ)言的抽象程度還是不夠,因此比C語(yǔ)言更加抽象的面向?qū)ο笳Z(yǔ)言C++出現(xiàn)了。所以面向?qū)ο笫潜菴語(yǔ)言更高級(jí)的抽象。面向?qū)ο蟮暮诵木褪浅橄蟆?br> ??面向?qū)ο蟮恼Z(yǔ)言從80年代末期到90年代初期很火,尤其在1993年Java語(yǔ)言誕生后面向?qū)ο蠓浅7浅;?,一直持續(xù)到2005年左右?,F(xiàn)在我們知道面向?qū)ο笳Z(yǔ)言也慢慢被淘汰了。面向?qū)ο笠脖憩F(xiàn)了很多弊端,比如說(shuō)在Java編程語(yǔ)言里面很多東西都要求標(biāo)準(zhǔn)化、規(guī)范化要寫(xiě)接口。
Java打敗C++
同樣是面向?qū)ο笳Z(yǔ)言我們知道很長(zhǎng)一段時(shí)間Java打敗了當(dāng)時(shí)最強(qiáng)的語(yǔ)言C++,因?yàn)镃語(yǔ)言和C++有個(gè)很大的弊端就是它有指針,指針需要人為去管理還要管理內(nèi)存的分配和釋放,這樣很容易出BUG,指針操作不當(dāng)會(huì)產(chǎn)生很嚴(yán)重的后果,還可能產(chǎn)生內(nèi)存泄漏。而Java有了JVM實(shí)現(xiàn)了真正意義上的跨平臺(tái)(一處編譯,到處運(yùn)行),還通過(guò)內(nèi)存回收機(jī)制,通過(guò)一定基數(shù)來(lái)幫我們管理內(nèi)存,這樣程序員不用手動(dòng)去管理內(nèi)存程序員的工作量和犯錯(cuò)的幾率就減少了。Java就是精簡(jiǎn)版的C++,而且不用人為去管理內(nèi)存和指針了,這就是Java打敗C++的原因。
??隨著時(shí)代的發(fā)展,面向?qū)ο蟮恼Z(yǔ)言后來(lái)被曝出了很多毛病,比如說(shuō)Java很長(zhǎng)一段時(shí)間差點(diǎn)被淘汰了,如果不是Android使用Java的話,Java可能之前就已經(jīng)走向末路了。原因是Java這樣的面向?qū)ο蟮恼Z(yǔ)言在做大型軟件工程的時(shí)候Java可以幫助我們高度抽象,抽象理論上說(shuō)是由好處的,但是由于Java為我們提供了很多的規(guī)范,而編程的時(shí)候我們都去遵守這些規(guī)范,而且有大量的配置文件我們要去配置,所以大家覺(jué)得很不方便。因?yàn)镴ava希望我們所有程序員寫(xiě)的代碼都是一致的,希望我們都按照一個(gè)標(biāo)準(zhǔn)規(guī)范來(lái)走,這種思想是好的但是這樣導(dǎo)致了一個(gè)結(jié)果,就是在大的項(xiàng)目架構(gòu)設(shè)計(jì)的時(shí)候我們要預(yù)先設(shè)計(jì)好所有的接口,然后讓所有的程序員去實(shí)現(xiàn)這些接口,程序員去實(shí)現(xiàn)這些接口自然程序就能對(duì)接,多人合作就能很順利,這是好事情同時(shí)又造成一個(gè)弊端,很多Java的反對(duì)者認(rèn)為Java是反人類的。因?yàn)檐浖歼€沒(méi)做出來(lái),你怎么可能知道我需要哪些接口、需要定義哪些抽象類、抽象層方法呢?這不是反人類的嗎?(因?yàn)橐粋€(gè)全新的、之前沒(méi)有人做過(guò)的開(kāi)發(fā)項(xiàng)目,不可能實(shí)現(xiàn)在項(xiàng)目開(kāi)始之前就能定義好這個(gè)項(xiàng)目有哪些數(shù)據(jù)結(jié)構(gòu)、表要留哪些字段、要留哪些接口、定義好哪些基類和抽象類等然后再給其他程序員去用,除非同樣的系統(tǒng)之前做過(guò)很多遍,才有可能實(shí)現(xiàn))
PHP打敗Java
我們知道很長(zhǎng)一段時(shí)間Java被PHP打敗了,到現(xiàn)在為止全球有80%的網(wǎng)站是用PHP寫(xiě)的。那么Java之前那么強(qiáng)還很安全,還給程序員省了很多力,為什么會(huì)被PHP打敗呢?原因就是Java過(guò)度標(biāo)準(zhǔn)化,要求大量的預(yù)先設(shè)計(jì)(導(dǎo)致項(xiàng)目還沒(méi)有開(kāi)始、需求都還不確定但是要設(shè)計(jì)好所有的接口和規(guī)范、基類和抽象類、建好數(shù)據(jù)庫(kù)、布置好模板等這種是很不實(shí)際的事情)。PHP不要求為預(yù)先設(shè)計(jì)非常靈活,可以面向?qū)ο缶幊桃部梢圆幻嫦驅(qū)ο缶幊蹋热缯f(shuō)前期開(kāi)發(fā)的時(shí)候哪怕是過(guò)程化的寫(xiě)法,只是代碼不好看,后期可以再把面向過(guò)程的代碼變成面向?qū)ο?,還可以把多個(gè)PHP文件整合成一個(gè)單入口, 代碼完成后發(fā)現(xiàn)有幾個(gè)類都有共同的方法,可以再寫(xiě)一個(gè)接口讓這些類同時(shí)再實(shí)現(xiàn)這個(gè)接口,這就是一個(gè)不斷開(kāi)發(fā)重構(gòu)、開(kāi)發(fā)重構(gòu)過(guò)程,重構(gòu)的時(shí)候代碼就越來(lái)越漂亮越來(lái)越完善,這樣重構(gòu)到最后Java是完全部面向?qū)ο?,PHP也可以會(huì)是完全面向?qū)ο?,Java是MVC,PHP也可以是MVC。只不過(guò)在開(kāi)發(fā)的過(guò)程中PHP會(huì)很靈活。開(kāi)發(fā)了之后確定了最后的需求再來(lái)一步一步的完善。這就是為什么PHP做項(xiàng)目很快很靈活的原因,也是現(xiàn)在很多創(chuàng)業(yè)型項(xiàng)目IOS和Android的APP服務(wù)器端都是用PHP做的。
三.函數(shù)式編程語(yǔ)言
我們說(shuō)編程語(yǔ)言10~20年都會(huì)有一個(gè)大的變革,那么PHP其實(shí)也是一門面向?qū)ο蟮恼Z(yǔ)言,JS是基于對(duì)象的語(yǔ)言。而現(xiàn)在最流行的編程語(yǔ)言就是函數(shù)式編程語(yǔ)言,從2006年以后Ruby是日本人開(kāi)發(fā)的,在美國(guó)發(fā)揚(yáng)光大以后,把所有的傳統(tǒng)編程語(yǔ)言都打敗了,因?yàn)樵诜?wù)器開(kāi)發(fā)領(lǐng)域的話函數(shù)式編程語(yǔ)言的優(yōu)勢(shì)非常大,函數(shù)式編程語(yǔ)言就是解決了面向?qū)ο缶幊陶Z(yǔ)言的弊端(之前提到的預(yù)先設(shè)計(jì)、Java的反人類做法)。函數(shù)式編程語(yǔ)言有很多,比如現(xiàn)在谷歌最新的編程語(yǔ)言go語(yǔ)言,Java8、PHP7等都支持函數(shù)式編程語(yǔ)言的一部分特性(其中Java8已經(jīng)支持函數(shù)式編程語(yǔ)言的80%了)。函數(shù)式編程語(yǔ)言是現(xiàn)在的主流,它不需要我們提前設(shè)計(jì)好接口、設(shè)計(jì)好基類。因?yàn)楹瘮?shù)式編程如果兩個(gè)類中都有一個(gè)共同的方法,它會(huì)自動(dòng)生成這個(gè)方法的接口。
編程語(yǔ)言的動(dòng)態(tài)類型、靜態(tài)類型、強(qiáng)類型和弱類型的區(qū)分
強(qiáng)類型通常就是靜態(tài)類型,但是動(dòng)態(tài)類型不一定就是弱類型。強(qiáng)類型就是存儲(chǔ)在內(nèi)存中的數(shù)據(jù)類型是限定的,不同地方使用時(shí)需要進(jìn)行強(qiáng)制數(shù)據(jù)類型轉(zhuǎn)換,動(dòng)態(tài)類型就是在聲明一個(gè)變量時(shí)不需要使用特定的關(guān)鍵字進(jìn)行數(shù)據(jù)類型限定,比如將一個(gè)數(shù)字類型和一個(gè)字符串類型的數(shù)據(jù)進(jìn)行運(yùn)算時(shí),如果有需要進(jìn)行數(shù)據(jù)類型轉(zhuǎn)換后才能進(jìn)行運(yùn)算的就是強(qiáng)類型,如果不需要轉(zhuǎn)換就能直接進(jìn)行運(yùn)算的就是弱類型,所以PHP就是弱類型編程語(yǔ)言,而JS在嚴(yán)格意義上來(lái)說(shuō)是動(dòng)態(tài)類型的強(qiáng)類型編程語(yǔ)言。
指令式編程語(yǔ)言與函數(shù)式語(yǔ)言的區(qū)別
之前所有的傳統(tǒng)編程語(yǔ)言都是指令式編程語(yǔ)言,因?yàn)槲覀儗?xiě)的代碼是怎么樣執(zhí)行完全按照我們程序員編寫(xiě)的指令來(lái)執(zhí)行。但是函數(shù)式編程不是這樣執(zhí)行的,函數(shù)式編程代碼的執(zhí)行順序不是按照程序的先后順序執(zhí)行的,它是理解了程序員的用意后進(jìn)行執(zhí)行,比如要讓計(jì)算機(jī)畫(huà)一棵樹(shù),它就會(huì)畫(huà)一顆樹(shù),但是具體畫(huà)樹(shù)的方法是由它來(lái)畫(huà)的,并不像之前按照程序員的的程序一步一步的去畫(huà),相對(duì)函數(shù)式編程環(huán)境承擔(dān)的東西更多了,跟接近于人腦的思維方式在編程,所以學(xué)習(xí)函數(shù)式編程更簡(jiǎn)單了,不需要學(xué)程序邏輯都可以做函數(shù)式編程。所以在函數(shù)式編程領(lǐng)域像計(jì)算機(jī)一樣去思考不是必須的。