關(guān)于編程這件事我所走過的彎路
我是如何成為一個程序員的呢?
只能說是機緣巧合,命運捉弄,歪打正著,如果當(dāng)年真的僅僅是因為自己高中物理比較好就報物理專業(yè)的話,如今可能還在讀研或者已經(jīng)是個老師了吧,如今后悔成為一枚程序員嗎?只能說后悔過,我曾好多次以為自己不適合干這個,如今對于技術(shù)和編碼這件事能做到有些樂在其中可以說是走了很多彎路才到了如今的境界的。怎么說呢?雖然我不信神,但是此時卻想說,可能都是命運的安排吧。
事情的起因都是源自高三的一本志愿書,看到一個專業(yè)叫物聯(lián)網(wǎng),聽起來就感覺很有逼格,很厲害的樣子,于是沒有多想就想一心報這個專業(yè),學(xué)校呢?當(dāng)時心心念念的學(xué)校是哈工大,將來成為創(chuàng)造物聯(lián)網(wǎng)歷史的人,結(jié)果呢高考考的感覺選擇題用腳踩答題卡都估計比我想出來的好,語文12個選擇題我選錯了九個,最擅長的物理我選了3-5結(jié)果那題看似簡單其實暗藏玄機15分直接沒了,最終愿望縮水成為吉大,不過仍然作為村里數(shù)年難得一遇的985大學(xué)生,也不想頂著壓力復(fù)讀,而且吉大的大部分專業(yè)也是都有選擇的余地的,最終還是欣然接受了,最終成功錄取,當(dāng)時只是感覺挺好一切盡在掌握,只是錄取通知書的小字計算機學(xué)院我卻完全沒有注意,這將決定我未來十幾年的人生軌跡。
進了大學(xué),忽然發(fā)現(xiàn)一切和我想象的都是不一樣的,用校ACM的一個人來說就是吉大的計算機有種農(nóng)村包圍城市的感覺,這話我是服氣的,因為我就是那個農(nóng)村,別說編程了,電腦我都沒怎么碰過,我對輸入法的認知還停留在,小學(xué)的智能abc那個時代呢,打字用二指禪,看著c語言編程的書,感覺沒那么難,結(jié)果第一節(jié)實驗課,卡在VC6.0不會創(chuàng)建工程,好不容易創(chuàng)建一個,發(fā)現(xiàn)才知道輸入法標(biāo)點符號是有中英文的,而VC60這種上古級ide是不會提醒你語法錯誤的,當(dāng)時是真的連hello world都寫不出來的,更要命的是老師當(dāng)時推薦的書是譚浩強的,用如今的眼光來看那本書整本書充斥的只有“錯誤”二字,有人戲稱c語言期末考試內(nèi)容就是應(yīng)該找譚浩強的書中的錯誤,找到多少個就考多少分。而且書中的絕大部分代碼都是照著敲根本跑不起來的,比如a+++++b這種鬼代碼,寫更是嚴(yán)重打擊初學(xué)者的信心。這是實驗課,當(dāng)時就想,與我在電視中看到的程序員不一樣啊,程序員不應(yīng)該是沖著屏幕一頓亂敲,一會問題就好了嘛?結(jié)果如今就是各種各樣的error和燙燙燙燙燙燙,而且做出來的東西一點都不高大上不實用,開始懷疑人生。
再說課程,我想像的大學(xué)課程是教我們?nèi)绾螌懢W(wǎng)站,如何黑別人電腦,再不濟也要來個office ps 視頻剪輯什么的吧,結(jié)果呢?大學(xué)的課程每一門都給人一種十分魔幻的感覺。怎么說呢?就是剛開始老師講的東西你幾乎都不用思考就能懂,半個小時就開始陸續(xù)出現(xiàn)幾個陌生點,三天過去老師講的東西就連一個標(biāo)點符號都聽不懂了。你會懷疑甚至?xí)B1+1都不敢回答等于二,講的也都是一些與找工作無關(guān)的東西,什么高等數(shù)學(xué)啦,什么電路啦,甚至計組,什么c語言啦c艸啦,再往后是各種匯編,各種芯片的匯編,算法,數(shù)據(jù)結(jié)構(gòu)啦,作為一個實用主義,面對這些我腦中有無數(shù)個問號,其中最大的疑問就是它們特么有什么用,我花一個星期,讓一個電機轉(zhuǎn)起來有什么用?迷茫×2
在迷茫彷徨中,我度過了人生最迷糊的三年,雖然大學(xué)的課程很多很雜,但是我從來不敢說我哪怕學(xué)會或者掌握一丁點東西,就是聽個響,也不敢說自己做了一丁點讓自己驕傲或者感覺有意義的事情,論文啥的都是百度百科復(fù)制粘貼,不知不覺就到了找工作的時候了,真的是感覺自己是虛度了四年,別說面試官了,我自己都找不到一個讓對方要我的理由,這個不努力啥都沒干,啥都不會,還沒特長的我,好在最后被一家外包公司也就是我的上家收留了,雖然這也讓我未來的兩年很痛苦,這估計也是懲罰我吧,懲罰我無所作為無累積的三年,我無數(shù)次都在思考過,如果我報了自己更擅長的物理估計也不會這樣度過四年了,一定是個學(xué)霸,哪怕是軟件工程也比現(xiàn)在強很多,至少人家教的東西比我們更實用啊,我會什么?就一個c語言c艸,還只是連皮毛都不算的水平,不過不管怎樣大學(xué)結(jié)束了,第一批小白鼠成功出獄了。
再然后就是畢業(yè),在外包公司的兩年,怎么說呢?錢少也就算了,最不能忍的是它帶偏你,這家外包業(yè)務(wù)主要分兩類國內(nèi)和對日,我比較不幸被分到對日的部門了,這兩年怎么過的?首先是公司地點,在深山之中一座大高樓,上下班門閘必須打卡且員工卡是絕對不能借用的,然后是穿:必須穿襯衫,不讓穿牛仔褲,短褲,休閑褲,七分褲,不讓穿運動鞋,涼鞋,球鞋,板鞋,休閑鞋,帶鞋帶的鞋,然后是午休時間一個小時,然后是室內(nèi)到處都是的攝像頭,手機不允許放到辦公桌上,有的部門還會把手機鎖在門口的一個柜子里,
如果說這還算可以理解的話那:
電腦人離開的時候必須鎖屏
鎖屏密碼必須每個月?lián)Q一次且?guī)讉€月之內(nèi)不能重復(fù)
電腦不許插U盤(這點我是能理解的),
電腦不許上外網(wǎng),嗯只有局域網(wǎng),不能百度
手機不可以拍攝屏幕,
需求是日語的,什么意思要靠第六感猜,沒有百度翻譯。
要求一行代碼一行注釋,日語注釋,沒有百度翻譯,不會打日語自己去找復(fù)制粘貼。還要求每行代碼都要同步文檔。
文檔有哪些呢?表結(jié)構(gòu)字段設(shè)計書,基本設(shè)計書,詳細設(shè)計書,單元測試設(shè)計書,結(jié)合測試設(shè)計書,checklist等等等等數(shù)都數(shù)不清,要全都同步,也就起說,代碼改一處,這些東西全都要同步改,測試要重測,而設(shè)計開發(fā)測試全都是你一個人,如果不改還好,可惜客戶一個星期能改八遍。
測試文檔要求截圖+日語說明的,截圖工具也是上古級的,特別難用。截什么圖呢?挨個打斷點看每一個變量,加頁面截圖,加數(shù)據(jù)庫的數(shù)據(jù),加各個服務(wù)器的log日志,改動的位置要字體標(biāo)紅,而且紅色啦字體啦要和其它的一致,僅僅看起來差不多還不行,因此最保險的手段還是復(fù)制粘貼,順帶一提中間那些內(nèi)容少一點忘一點都是要重新測試的,覆蓋率要求呢?100%!對你沒聽錯就是百分百,甚至于跑到所有的if else以及所有可能和異常都不夠,還有各種業(yè)務(wù)的邊界條件比如時間你就要考慮,一號30號凌晨十二點凌晨零一秒等等等,有點常識都知道異常不是那么好測的,你要制造異常數(shù)據(jù),為了造這條數(shù)據(jù)你要解析這個異常前面的所有代碼,有的根本就不是很容易創(chuàng)造異常條件的比如系統(tǒng)時間相關(guān)的,有的要斷網(wǎng)絡(luò)的,只能debug打斷點改值,給java改值還好,別忘了還有存儲過程debug呢,反正都是干神仙的活,最后也都弄出來了。
如何測試呢?不是說沒有外網(wǎng)嘛!公司給了一個虛擬機終端,終端里可以訪問外網(wǎng),然后有個類似網(wǎng)盤的東西從虛擬機傳上去,再在本地下下來,那虛擬機多大內(nèi)存呢?2g,公司電腦多大性能呢?4g i3,窗口超多且卡的不行,順帶一提,虛擬機是每天都會還原的,且沒有截圖軟件,而且還不可以下外網(wǎng)的東西,因此要自己用那個網(wǎng)盤先傳一份上去安裝,更多麻煩的流程細則不多贅述,總之工作之前,需要重復(fù)的準(zhǔn)備好多好多東西。這活才能開始,然后一重啟電腦全都沒了,要測什么呢?火狐 谷歌 ie對還有ie安卓3G沒錯就是那個非智能機時代的3G。所有的測試和點點點截圖文檔斷點等,都要再重復(fù)五遍
總算聊到架構(gòu)了,代碼什么樣呢?2000行一個文件,還不是java代碼是而存儲過程,存儲過程還會調(diào)存儲過程你不知道會調(diào)多少層,java會調(diào)存儲過程,定時任務(wù)也會,shell也會調(diào),java幾百上千行調(diào)個幾十層類和ifelse也是蠻常見的,如何配置呢?用表的字段來配置,一個表幾十個字段,命名flag1 flag2一直flag20多每個都有其含義,什么含義自己去看文檔去,多少個表呢?200多個,多少個存儲過程呢?也200多個,但還不是一一對應(yīng)的,之前不是要截數(shù)據(jù)嘛,測試的時候還要把關(guān)鍵數(shù)據(jù)字段標(biāo)紅,而且那個紅也不是你選的,最保險還是復(fù)制粘貼,每個存儲過程開始都是先來幾個表的聯(lián)合查詢,這也是我為什么如此痛恨sql腳本的原因,有框架嗎?很可惜這是一個十年前的日本框架,我離職之后根本說不清楚這究竟是什么框架,非常的非主流,繼承用的滿天飛,遺留累積了十年的垃圾代碼,你想改?你想重構(gòu)?不可能!你想用新技術(shù)?不行!就日本人膽小的樣子,你寫點新技術(shù)的東西他們根本看不懂,最重要的是日語文檔注釋我根本不會寫,還沒有外網(wǎng)下東西,而且我改了幾十行的代碼就要看好幾千行代碼,調(diào)查幾十個文檔,日本方式的測試還是親自測重構(gòu)是會死人的,最重要的是他們不敢,別說新技術(shù)了,三目運算符都不讓用,代碼風(fēng)格創(chuàng)新一點都不行的,必須完全看不出來是你寫的,而且日語的代碼還有一個問題就是,他們是分全角半角的,全角的英文數(shù)字空格,我無數(shù)次被這個東西坑過。
就這樣產(chǎn)出是什么樣子呢?一個星期幾十行代碼也就差不多了,什么?少?getter setter是純手敲的,那樣的文檔那樣的架構(gòu),那樣的測試和測試環(huán)境,還是日語的需求,而且客戶說改就改哪怕只改一點全重干,還想要輸出?如今我一個星期寫幾千行都是很平常的事情,你想快就先把那些破規(guī)矩都去掉。而且盤根錯節(jié)的代碼與業(yè)務(wù)寫幾十行要調(diào)查接近無限的代碼是不可能快起來的。
期間我想過很多次離職的事情,可是我的技術(shù)在外邊根本沒有什么談資,java基礎(chǔ)還好,因為我測試的時候是挨個打斷點debug的,java的內(nèi)存模型,都用身體記住了并且瘋狂java也看了很多遍了,并且我還抽空看過shell tomcat spring這些東西,我并沒有完全按部就班的按照對日的那套走,然而即便這樣沒有項目經(jīng)歷是最傷的,人是受限于環(huán)境的,盡管我,承受著巨大的工作壓力,干著神仙才能干的活,然而真走的話卻毛線都說不出來,所以一直都不敢走,主要是不會什么主流的開源框架。就這點讓我沒有說走就走的勇氣,也是很多干對日的人不敢走的根本原因。因為你的知識體系和主流嚴(yán)重脫節(jié)。
最終復(fù)制粘貼出鼠標(biāo)手離職了,雖然還沒有準(zhǔn)備好,但是我已經(jīng)徹底看透,即便在這里干十年,也不會改變什么,工資漲不上去,技術(shù)不會漲,跳槽還會越來越難,這就是外包的本質(zhì),錢給的少點可以,但是你不能帶偏我,吐槽一下公司的領(lǐng)導(dǎo),感覺我還是涂樣啊。一邊說讓你搞技術(shù),一邊自己上線把服務(wù)器搞掛掉然后讓你來擦屁股;一邊要你全力開發(fā),一邊一天打斷你個十幾次讓你寫不了代碼;一邊說不搞傳統(tǒng)公司一套,一邊想事起來大半夜來你個電話;一邊把說著自己看不起的公司,一邊把自己看不起的一套全做一遍。我真的想不懂有些人天天想些什么。
終于開始了找工作的環(huán)節(jié),其實面了不少家,主要是其實我的基礎(chǔ)還行,主要坑在沒什么項目經(jīng)驗上,沒辦法我寫的東西根本絲毫沒有我原創(chuàng)的空間啊,說白了就是復(fù)制粘貼,你可以不復(fù)制粘貼自己寫,然而客戶領(lǐng)導(dǎo)不讓啊,有的公司面試官喜歡在你面前貶低你,跟你秀設(shè)計模式git等等等,最終到了如今這家,可能一般工作經(jīng)歷正常一點的人體會不到,沒有門閘,不管穿什么,沒有攝像頭,沒有信息安全的工作環(huán)境是多么爽,最主要的是沒有日語。
其實工作一段時間會發(fā)現(xiàn),互聯(lián)網(wǎng)公司除了架構(gòu)之外其他人的水平也沒有高的神乎其神,相反,越是高級的技術(shù)使用起來反而越簡單,然而正是因為簡單了,你才能更進一步去做一些什么,在被大量細節(jié)束縛的時候你是無心也無力去做自己的原創(chuàng)的東西的,至少我是做不到的,并且設(shè)計模式也不是絕對的好東西,絕大部分人也是if else橫飛的。框架也就會個皮毛,但是因為流程更正規(guī),分工更明確,我由原來的“偽全棧”,成為真正的服務(wù)端開發(fā)了。至此我彎彎曲曲的程序員生涯才剛剛步入正軌。過去的六年只能用慘不忍睹來形容。
然后偶然的機遇,我遇到了函數(shù)式編程,并且嘗試在實際項目中開始使用,起初只是簡單的stream foreach 再然后會了map filter 收集器和reduce 然后會了Optional容器,再然后開始會高階函數(shù),重新理解閉包的概念,再然后理解了柯里化,結(jié)合泛型設(shè)計模式重新理解函數(shù)式編程和面向?qū)ο螅缴蟼€月的組合式異步編程,現(xiàn)在開始入坑Scala 讓我的編程水平短短幾個月上升了n個級別,根本停不下來,因為更簡單更實用的東西這些年終于遇到了。如果大學(xué)學(xué)的不是c語言而是scala如今可能早已是另外一番景象了,如今的代碼是什么水平呢?我只能說這東西無法用時間來衡量是需要一點天賦的,就和過去的六年我沒有編程天賦一樣,如果硬要衡量一下的話大概是,我高中的物理有多強,如今的敲代碼能力就有多強,因為函數(shù)式編程的最基本思維方式就是映射,就是套公式,原理是如出一轍的,知道這點之后,以前的套公式技巧審題技巧就全都可以遷移到這里了,這也正是很多人感覺它很別扭的根本原因,在過程式編程浸淫的越久就越難習(xí)慣。越難理解。
至此回顧一下我所有的彎路和給新人的一些建議,首先,編程的學(xué)**要分三大門派,其一就是,先學(xué)各種數(shù)學(xué)和電路和算法數(shù)據(jù)結(jié)構(gòu)操作系統(tǒng),然后再去寫程序的,另一種是先學(xué)如何寫個網(wǎng)頁,寫個小游戲,等一些很amazing的東西,前者我們稱之為魔幻派,后者我們稱之為實用派,還有一種就是介于兩者之間混合派,我更傾向于實用派,而不幸的是大學(xué)的教育方式絕大部分都是魔幻派的,這導(dǎo)致了我整個大學(xué)都處在迷茫的階段,還有就是ide的選擇最好選擇新一些的工具和技術(shù),機器能替你做好的事情,人就不要花精力去操心了,語法檢查交給編譯器就好了,其次就是教材的選擇,譚浩強的書作為大學(xué)考試筆試應(yīng)試還是不錯的,然而真想學(xué)c建議還是c primer一本錯的教材會讓你懷疑人生的,然后就是大學(xué)教材包括業(yè)界主流都只強調(diào)面向?qū)ο蠛兔嫦蜻^程兩種編程模式,再好一點的能來個面向切面編程,而函數(shù)式編程這種與圖靈機并駕齊驅(qū)卻生不逢時的編程模式卻鮮有提及,就這么說吧函數(shù)式編程對于剛進大學(xué)入門的人來說絕對比面向?qū)ο蟾菀捉邮埽哺衔磥淼木幊讨髁鳌_€有就是不要選擇外包和測試,但凡有一點回旋的空間都不要進外包,萬劫不復(fù)啊,還有就是測試,雖然測試門檻不高,但是任何門檻不高的工作都要付出更慘重的門檻不高的代價的,如果是自動化測試還好,點點點是沒有前途的,將來做產(chǎn)品嗎?好想也行,最后就是離職這件事,我是工作兩年才跳槽,有一方面一直顧及的是一個工作忠誠度的問題,這是不對的,工作前兩年如果發(fā)現(xiàn)公司沒什么前途或是價值觀有問題就趕緊走,割肉止損,前兩年HR是能夠理解你跳槽次數(shù)多的,他會認為你在試錯,但是兩年之后再跳槽就不能那么沖動了。