致青春
還記得自己那年考清華失敗,被調劑到中科大軟院,當初有幾個方向可以選,軟體設計、嵌入式、資訊保安等等,毫不猶豫地選擇了資訊保安。
為什麼選資訊保安?這四個字聽起來多牛多有感覺,我本科是學物理的,記得做一個光學實驗的時候,一個老師看我做的結果,說,學物理不是什麼人都可以的,這個是需要一點智商的。
好吧,當初其實並非對我一個人所說,但我確實感覺到受到了鄙視,同時,我沒有任何在物理上的精湛技藝可以反擊我的老師。
由於整個大學期間,我都在沉迷遊戲和小說,以至於輔導員說,現在找你都得預約。
而我的同學基本在學期開始和考試前能見到我,當時為了應付考試,我不得不學習複雜的物理公式和推導,有一門課程是鐳射原理,老師是雙博士學位,大概是很厲害的,在我考試時,過來看我的卷子,說你的”背功“很厲害。
考試時如期通過,但老師大概都對我評價不高。自然,我是感到不愉快的。
回到我的畢業論文,大概是做一個電離層特徵參量的反演,其實就是用迭代法解病態方程。
這個論文基本是沒有人選的,因為題目本身可能相對比較難,也需要程式設計實現,好吧,當時下載的是盜版的matlab,參考的是一個日本學者和我導師的論文,鏗鏗鏘鏘地寫出來了。還做了個所謂的引數優化,以使得結果看起來更平滑。
當時覺得很得意,我女朋友(現在的老婆)也很驚訝,我一個月做完了。
其實這不是第一次領略程式的魅力,在很久之前,高中時期,為了追一個女生,我做過flash,當時我就覺得拖來拖去很麻煩,但苦於沒有基礎,看不懂actionscript,所以難以深入體會程式設計的精妙,如果看到網上有一些類似雪花飄落、旋轉字等效果,都是直接拷貝修改到完工。
現在回到,為什麼選擇資訊保安上來,因為在大學時,很喜愛遊戲,尤愛單機,國情大家是清楚的,而且我沒有錢,也不知道哪裡可以買到正版,這個猥瑣了,呵呵。
仙劍、上古、火炬之光、火焰紋章,各種型別都喜歡。也很喜歡生存類遊戲。給一個單機遊戲做的exe補丁和用lua擴充的mod至今看來仍讓我懷念。
討厭網遊是因為自己沒有錢,搞不過RMB玩家,而且砸裝備總失敗。
唯獨一個,2006年時,我玩完美世界,後來玩它的SF,為了砸裝備,我第一次想到寫封包外掛,由於當時已經有一些socket、tcp/ip的概念了,雖然C++玩不轉,還是各種參考,寫hook、寫位元組轉換,同時完美當時打擊WG很厲害,遊戲基址容易變,又加了很多防除錯的功能。
但為了不手工砸裝備(SF裡的石頭幾乎免費,就是砸上去的機率太低),我慾望那個強啊,所以用OD除錯找網路傳送的函式地址, 然後C++寫程式碼hook。
程式最終工作很好,我還分享給了幾個玩友。
後面也寫過一些類似跳舞自動擊鍵的WG,主要也是為了自娛自樂,因為我真的反應不過來螢幕上瞬間出現太多的key!
與程式為伍的日子很少,但每一次接觸,似乎都是為了達到自己的一些目標。
所以凌亂的程式設計體驗,雖然不繫統,不精湛,卻讓我快樂。
再次回到為什麼選擇資訊保安上來?也許答案已經很清楚。
當時覺得虛擬機器加密太高深了,聯網解密也難搞定,所以覺得資訊保安一定是能解決我的問題的!
後來你猜到了,就是C,就是彙編,就是linux,我當時是多麼反感linux,當時還用的是ubuntu,但為了課程,實在是沒有辦法,為了考研,自己系統自學了資料結構、計算機網路、作業系統、組成原理,當時在考研論壇上還和一個清華搞計算機體系的探討問題,刷了好幾頁的帖子,現在看來,多幼稚!但,快樂也是固定在那個過程之中了。
我討厭彙編,我討厭C,我討厭linux,但他們強大,能夠滿足需求,這就夠了。
java還是 c#?
其實這不應該是我們真正的主題,而且入了行的也很少會java還是c#這麼比,但初學的,java和c#往往就代表了兩大流派,java代替了j2ee,c#代替了.net,ok,沒有關係,這麼作為title,不影響我們說事。
如果從語言的角度上來講,c#毫無疑問勝出,易用、門檻低、優雅、較為簡潔。但java和c#的語言特性是相似的。
在很多類的命名上,它們都如出一轍:
1 2 3 4 |
//java System.out.println("java比C#強!j-a-v-a!"); //C# System.Console.WriteLine("你沒看到#是4個+嗎,我比c++還強2個+,你就歇菜吧!"); |
c#出現的時間比java晚,所以自然吸收、借鑑,同時又有它的創新,比如很早就支援lamda表示式、比如event和委託,比如var,比如linq。
但如果從面向介面來講,java同樣可以做到event和listener,只不過物件引用的傳遞比較直接。
而.Net的類庫和jdk則各有千秋。
如果從應用的角度來看,javaee和.Net體系幾乎都涵蓋了主流的開發方向:
桌面、Web、服務端、資料庫、網路、移動端、中介軟體。
哪個方向,哪個更強?這個留給讀者自己體會吧。
微軟給.Net一個宇宙最強的IDE,也給了各個方向統一而平滑的程式設計體驗,不得不說,微軟的上手要容易的多。
而java則一開始就和開源分不開,多如牛毛的框架、引擎、包,blabla,用java開發,程式設計師要懂得東西更多一些。應為你大部分情況下得自己整合。但整合的好了就是很強大的,比如SSH。
在近幾年很熱的大資料和雲端計算領域,hadoop、spark、tez、leveldb、mongodb、mariadb、hive、hbase,還有oracle,都各自在自己不同的層面發力,大部分的這些都對java是極為友好的。
很多java程式設計師,都覺得搞.net開發的,就是拖拖控制元件而已,其實我可以告訴你,說出這種話的java程式設計師一般都還比較小白,如果你是搞.net的,你也可以說搞java的都是拷貝別人的開源軟體的程式碼,然後改改而已。
當然改改沒什麼問題,誰都不喜歡重複造輪子,比如,google裡面也並非全部是創新,經常”拿“別人的東西自己改吧改吧,淘寶就很不用說了,招了一些能改c、會點編譯的程式設計師,經常拿各種開源框架開刀,然後表明是自己的東西。比如雙11的那個問題。
當然不是說淘寶找的人有問題,而是這個企業的文化就是銷售和廣告文化,後來的google也如此。
回到正題,wpf和silverlight(雖然已經EOL)中最大的創新莫過於xaml技術,如果你認為wpf只是winform的簡單升級,或者說你只會在wpf中拖控制元件,說明你還是一個非常初級的.net程式設計師,不管你工資上w沒有,或者你已經是專案經理了。
xaml天生就是為mvvm模型而生,這一點,搞前端的同學,應該熟悉,即使你不懂wpf,js和html怎麼做mvvm,你也應該體會過它的好處。
wpf中在xaml中佈局控制元件,並支援INotifyPropertyChanged介面,可以非常容易的實現介面和資料分離,做出一個mvvm模型出來。
說到標記性語言,我們看看jsp的jstl、struts2的tags,還有asp.net mvc3之後的razor引擎:
jstl和aspx的標籤類似,自由、強大,可以很容易的穿插交織到html標記中;
struts的標籤就是個另類,我個人反感這種既不遵循主流標準也不簡潔的東西,雖然好多人會說好用,那是個習慣問題,我這麼說,不是說這東西難學難掌握,只是比較一下和razor引擎中的標籤語法,弱爆了。
razor,強大、簡潔、優雅。
你肯定覺得我是微軟.net的粉絲,其實我想告訴你的是,最強的標籤語言只有兩種,html和xml,穿插動態語句到服務端頁面上,然後刷出html,從來都不是好的做法,因為不只你一個人寫程式碼,後面可能會有其他人維護這個頁面,本來這是需要由web designer來做的事情,但是有了語句,他的維護成本就很高。
規範的頁面開發,程式設計師是不會染指一個css、style的,動態語言在aspx、view、jsp上面應該儘量少用。否則你不如使用php和asp。
這一點,你會在工作中會深有體會的。
青春的你,怎麼選擇?
看看現在的招聘吧,動不動就是
精通j2ee,精通struts、spring mvc、hibernate或者mybatis,對mysql、oracle有深入理解,精通webservice、精通多執行緒,能處理高併發,有的還得懂jvm,最好有hadoop等開發經驗。最後再來個211以上。
.net方面呢?
精通.Net,精通mvc3-5、精通wpf、wcf、多執行緒,mssql等等等等。
我現在處於離職狀態,所以每天收到獵聘上的一些推薦,都很鬱悶,因為沒有一項是我精通的。
但是不妨礙我在2012年實習中,就拿到了13K的月薪,比一些正式員工可能還要高。
而且,仔細想想,程式碼中經常講到要容易維護、這個設計模式、那個AOP,這個大併發,那個高效能,我個人沒有見到容易維護的程式碼。學習一個新公司的一套模式,一套老產品,比學習一門新技術需要的時間長得多,你會發現,99%的情況下,你最需要的,不是什麼程式碼,模式,而是對產品的理解、對業務的理解,很多情況下,除非太菜太小白,大家的程式碼都差不多,誰有時間重構程式碼?程式設計師又為何加班?
這是行情,一個專案接一個專案,公司需要掙錢的,這是大部分公司的現狀。
為了回答java還是c#的問題,我會從我的經歷提供一些參考,既然是我的,那就不會是全面的和準確的,你自己判斷。
還是從故事開始吧!
在科大軟院(蘇州),因為老婆想和我一起在外面過個年,我不得不去臨時找實習,當時c和彙編不行啊,所以得選個流行的,什麼流行呢,當時是web。
所以我遇到了java還是c#的問題,確切的是我遇到了j2ee還是.net的問題。
因為經常使用windows,又因為.net門檻如此低,所以毫不猶豫選擇了.net,當時是不會寫SQL的,但是卻系統學習了資料庫設計原理。
進入公司就接觸mvc3,覺得好,外企的技術確實比較新呢,比我學習.net時學的aspx優雅,那個時候開始接觸並嘗試理解mvc模式和ddd的概念。
當時,時薪25人民幣。
6個月的實習,基本能玩javascript和c#,然後sql還是不行,當時記得一個高階開發跟我說,他以前做delphi開發的時候,團隊寫sql寫的好就牛,我深以為然。
只會用Entityframework + mvc3 + javascript,開發網站的我,用理解很淺的.net的web技術體系,支撐了我和老婆在上海的生活費用,當時10年,我們租的拎包式入住公寓1500一個月,不算生活費、水電費。
再一次,通過一項技術,達到了我的目標,支撐了我的計劃,當時對技術的理解,但是偏執於.Net,對java陣營是不屑一顧的。
後來很快離開了科大軟院和蘇州,考取了中科院,到了北京,房租是1580一個月,照樣不算生活費、水電費。
沒辦法,學校發的補貼根本不夠押2付3的。
找實習,做過什麼呢?office程式設計,而且當時的老闆是從IBM下來的工程師,專案主要是java開發,jsf做頁面,招我過去,做word程式設計,還不能使用.net,你猜到了,我用的是vba。
沒做多久,公司發錢就開始拖延,兩週後,我沒有積蓄,只能被迫離職,後來加入一家公司,從4K到10k,用了8個月,在這裡,我完善了程式設計師生涯中sql能力的快速成長,並且廣泛地使用了silvelight、aspx、oracle、mssql技術。記得當時一個北郵畢業的同事,做了6個月的office文件在web展示,因為涉及到了com程式設計,所以執行非常不穩定也難於除錯,更重要的是,拉一個頁面到展示,需要20秒。
老闆是中科院軟體所的博士,架構很厲害,但對於這個技術細節並不擅長,問我有沒有辦法,我說做過vba,大概瞭解word的dom結構,我試試。那個同事說,如果你能做到穩定、快速的實現,你可以拿這個做你的畢業論文了。
我說,我試試。
臨危受命,我猥瑣地查詢資料,研究百度文庫如何實現等等,後來為了.Net環境的一致性和可維護,所以拋棄了pdf + flash。
通過大量看老外的東西,我選擇了aspose.Net框架 + 一個能把word轉為Xaml的框架 + silverlight實現,可惜這兩個框架都收歐元,公司鐵定不會出錢,所以我猥瑣地對其進行了破解,也開始接觸IL碼。
docx文件線上編輯 + 展示的功能完成,給老闆run了一下,老闆點了個贊,顯示時間縮短到5秒左右。
後來做了資料庫的靜態,顯示時間縮短為1秒內。老闆又點了個贊。
後來帶領團隊,從mssql遷移程式碼oracle,至今還記得和老闆並肩一起寫儲存過程的情形,並感嘆微軟自身的資料庫外遷還得依靠三方工具的搞笑。
時光很快,當時回想,.Net是多麼的強大,是麼?
在工作的同時,學業,為了湊夠4個整天來實習,也為了自己的未來,我選擇了資料探勘、計算機影像處理、天文資料處理、文字檢索、分散式計算、高效能運算等所有聽起來很牛的東西。
不求甚解,一段一段的程式碼和註釋,將能掌握的注入到自己的技術骨頭裡去。
還記得在學校週一開組會,同一個組的基本都是博士了,我放棄碩博連讀,因為我實在年齡大了,得養家餬口。
後來一家西二旗的距離oracle很近的公司面上了,記得最後一輪面試是小屋子壓力面,從董事長到我的小組領導都在,沒有水。
首席架構師是科大少年班的,博士在網路所讀的,問了一個問題:
你如何實現google的負載均衡?
那個問題我答的不好,其實即使不理解負載均衡的實現,也該從組成原理的匯流排仲裁知識中窺的一點參考。
所以那次又被鄙視了。但那次拿到了13K的月薪,當時的總監是漢王以前的副總裁,評價是,基礎紮實,思維靈活,實習階段就參與公司重大專案研發,值得培養。
直到現在,我,相信也還有很多程式設計師,遇到了數不清的技術,我經常會茫然,到底我該何去何從?
一些疑問:
訪問資料庫,隨便找個高效的connector或者driver就行了,一般提供資料的廠家,誰不提供connector?ORM是很必要,但是追求效能和反框架氾濫的公司不在乎ORM帶來的那點便利性,用一個jdbc + sql照樣寫穩定高效的資料訪問。
做web前端,真的需要自己寫一個框架出來?真正需要這種開發的專案有幾個呢?jQuery和d3,原生的javascript就夠了,你寫的也許不叫框架,最多就是個wrapper。
資料庫的唯一性索引、聚合索引、輔助索引都沒搞清楚,就開始搞hadoop、spark、hbase、mongodb,用人單位也一再這麼要求的,你的專案中真的有那麼大的資料量?在傳統的rdbms下解決不了?
你開始知道輪子的概念了,並且知道不要重複造輪子。可是你快不是程式設計師了,而是框架員了。
所以,回到java還是c#,這個問題,要比我遇到的技術分裂要簡單的多。
一些建議
我的意見是,忘記java或者c#的對立,如果要做一個開心、有自我追求、同時滿足就業的程式設計師,你需要重視以下方面:
- 函式呼叫棧,這個很多高階程式設計師只知其然不知其所以然。你可以不懂的彙編、函式入口、返回地址、暫存器,但你需要除錯,你得深刻理解函式呼叫棧,無論是在dev模式除錯struts開發的jsp頁面,還是debug模式除錯aspx頁面,你得看懂呼叫棧的資訊
- 基本的資料結構和演算法,資料庫中索引的組織方式,是B+樹還是Hash,還是堆,你的公司有Web、桌面、移動使用者,有社群,有產品,你可能要做個推薦什麼的,或者研究個社交圖譜什麼的,這門技術可以幫助你。
- 一門動態語言。lua、python、javascript,都可以,你需要隨時和系統進行互動,或者實現一個原型,或者用程式的方式來畫點介面、資料圖什麼,它們夠輕量、夠快捷。
- 一門重量級語言。比如java或者c#。你靠它們吃飯。
- 理解跨平臺的含義。掌握一些基本的跨平臺技術,比如xml、c、html、json。
- 重視網路程式設計的練習和理解,在你使用URLConnection或者MySqlConnection或者WebRequest的時候,你是否理解它們的生命週期和底層實現,用什麼語言無所謂,你要記住tcp/ip協議和http的基本特性。這樣不至於你寫了幾年程式,還不知道method=post是什麼原理。
- 找一個順手的IDE,我個人不是CLI控,雖然不得不CLI,一個順手的IDE真的可以提高生產效率。搞.Net推薦vs + resharper,搞java推薦intellij IDEA.
- 關注一些熱門而經典的領域,比如機器學習、影像處理、資料探勘,即使已經有了mahout,不代表你不需要了解這些領域,你可能永遠不會在工作中使用它們,但它們的思想值得你擁有,因為你選擇了做程式設計師,而不是哪個公司的程式設計師。
剩下的,就是你的解決問題的思路和你實現的硬功夫(編碼能力),我相信,很多看這篇文章的人,不能夠輕易寫出一個ftp伺服器,不能夠不參考、不聯網查詢資料寫出一個簡單的快速排序,也不能夠輕易寫出一段通用分頁SQL,但他們依然可以正常工作。
所以外面的功夫容易忘記,有網路就能拾起,內功才是入骨的東西。
架構不是學出來的,是你的理解到位了,恰好工作中有這麼個需求,你就開始整合你的已知,然後開始選擇輪子。
最重要的是,你千萬不要成為一個只會熟練使用框架的程式設計師,那樣,你會疲於奔命,你也許永遠只會使用hadoop,而寫不出一個hadoop,你只是一個hadoop程式設計師,而不是一個分散式程式設計師。
你也許永遠只會使用struts,而忘記了自己寫filter,你只是一個ssh程式設計師,而不是一個web工程師。
後記
人言三十而立,如今二十有九,反反覆覆,雖然買房買車(俗了~),依然一事無成。
結婚5年,老婆再次懷孕,她很興奮,我也很開心,由於時常加班,對她很抱歉。
目前離職,有些感觸,特撰此文。