一名程序員的自白:其實(shí)我并不是一位天賦卓越的編程大師
時間:2022-05-25 21:42:01 | 來源:網(wǎng)絡(luò)營銷
時間:2022-05-25 21:42:01 來源:網(wǎng)絡(luò)營銷
我是一名程序員,雖然有著相當(dāng)不錯的基本技能,但我還是得承認(rèn)自己只不過是水平一般的程序員,這花了我很長一段時間,我不再感覺有必要去抓住那些我并不了解的觀點(diǎn),當(dāng)人們發(fā)現(xiàn)我對某樣?xùn)|西不了解時,我也不再感到害怕,你可能對此不以為然,但是我曾經(jīng)自詡為編程大師。
直到我犯了足夠多的錯誤才明白為什么那些被稱為錯誤,我很清楚我還需要了解更多東西,最重要的是,我知道那些東西大概是什么,并且我正在努力而積極地提升自己。
這種對自己能力的不正確的評估,很大程度歸因于我在一個相對封閉的環(huán)境中學(xué)習(xí)技能,在過去那些日子里,有電腦就已經(jīng)很特別了,更不用說知道如何使用了。
在我自己看來,我當(dāng)時是一個知識淵博并且經(jīng)驗(yàn)豐富的程序員,在我不到20歲的時候我已經(jīng)用C++、Pascal、C#、JavaScript寫過程序,當(dāng)然我最引以為傲的是,曾經(jīng)徒手用PHP編了一個電子商務(wù)平臺。
接下來這個故事就是講我如何產(chǎn)生自己很厲害的幻覺,并自詡為天賦卓越的編程大師!
1、天才的起源 當(dāng)我九歲的時候,我的一個朋友家里有衛(wèi)星電視,而在我們家里,我們只能收到四個頻道(你能想象第五頻道出現(xiàn)之前的日子嗎?),我熱切地盼望有一臺普通的電視機(jī),我們所需要的只是那些“衛(wèi)星盤子”,或者我稱為“衛(wèi)星”的東西——那樣我就隨時可以看QVC臺或者Eurosport臺。
由于隱約意識到自己的某種天分,我開始搭建自己的衛(wèi)星!我的設(shè)計(jì)包括了一把打開的傘和一條銅質(zhì)音頻線,一段接在傘的金屬柄上,另一端接在電視機(jī)天線上。必須承認(rèn)我的設(shè)計(jì)有一些缺陷,并直接導(dǎo)致我沒有得到想要的結(jié)果,但是這個小故事僅僅想表達(dá)我童年和青少年時期對技術(shù)的渴望,我認(rèn)識的人中從沒人想過制造“衛(wèi)星”。
幾年后,當(dāng)我父親的辦公室得到一個14.4k的貓時,我成為了最早一批網(wǎng)民一員。我能回憶起花了整個星期六下午的時間等待這個火焰漫畫圖標(biāo)被加載,每個幀的動畫大概要過一分鐘才顯示。
我甚至用Netscape搭建了我自己的網(wǎng)站,由于不知道互聯(lián)網(wǎng)的架構(gòu),我把所有的HTML文件存放在本地,并且期待有一天他們會出現(xiàn)在互聯(lián)網(wǎng)上,然而這些細(xì)節(jié)并沒有削弱一個事實(shí):我認(rèn)識的人中沒有一個制作了他們自己的網(wǎng)站。
在我十多歲的時候,我發(fā)現(xiàn)了自己天才中的黑暗面,在裝備了Jolly Rogers的食譜后,我和一群小伙伴們準(zhǔn)備動搖整個九十年代英格蘭的技術(shù)和道德根基,破解電話系統(tǒng)是我們的專長,我們用手提式聲音耦合器和公用電話,給我們在ICQ上認(rèn)識的美國姑娘們打免費(fèi)國際電話,以及在私人交換機(jī)上設(shè)立語音信箱。
最終學(xué)業(yè)和滑板阻止了我們在這條路上越走越遠(yuǎn),如果沒有這些干擾,我們無疑已經(jīng)在制造凝固汽油,黑進(jìn)政府網(wǎng)站并且徒手殺人了,盡管我們沒有把自己的能力發(fā)揮到極致,但事實(shí)是除了我們沒有其他人哪怕?lián)碛新曇赳詈掀鳌?br>
盡管到那個時候我已經(jīng)經(jīng)歷了一些冒險和失敗,我還是缺少一些東西,我的想法總是要超前我自身能力好幾步,正如在“衛(wèi)星”一節(jié)里體現(xiàn)出來的,我需要一種把我腦海中想法表達(dá)出來的方式,我需要一個直接的介于我想象和現(xiàn)實(shí)之間的接口。
2、Fuck生成器 真正的轉(zhuǎn)機(jī)出現(xiàn)在我十四歲的時候,我購買了一份PC Plus雜志,其中附贈了帶有完整版Borland C++編譯器的CD。我安裝了,并且認(rèn)真學(xué)習(xí)了雜志上的“hello world”教程。
就這樣,一個嶄新的世界在我面前打開了,物質(zhì)世界對于我想象力的限制消失了,我的創(chuàng)造力被解放了,我腦海中的大教堂要成為現(xiàn)實(shí)了!我該把這個新工具用于怎樣崇高的事業(yè)呢?很顯然,F(xiàn)uck生成器。
簡單而優(yōu)雅的Fuck生成器是一個命令行程序,也是我即“hello world”之后第一個里程碑。
程序開始運(yùn)行后會提示用戶輸入一個數(shù)字n,然后它會輸出字符串“fuck”,n次,最后用戶被提示可以重復(fù)以上過程或是退出。盡管功能有限,我還是沉醉于我所品嘗到的成就。
這是任何程序員都能享受到的一種快感,即看著機(jī)器執(zhí)行你的命令,不管這個任務(wù)有多簡單,它在運(yùn)行了,并且你知道為什么它能夠運(yùn)行,它除了在那里運(yùn)行不會做任何別的事。
過了些時日,另一期的PC Plus附贈了一個完整版的Borland Delphi。有了這個,我把程序升級為帶有窗口界面并且可以隨機(jī)生成彩色的4種不同的臟話。當(dāng)別的孩子在玩PlayStation的時候,我正在投身于一項(xiàng)更有意義和創(chuàng)造性的事業(yè),我在生成很多fuck。
到那時,一切都預(yù)示著我是注定要成大事的,我要向世人展示我真正可以做的事情。
3、我的巨著 在90年代晚期,我為一家小型并且擴(kuò)張迅速的郵件訂購零售商創(chuàng)建了一個網(wǎng)站。一開始,這個站點(diǎn)只包含一些靜態(tài)的頁面——關(guān)于商品的小冊子,一個導(dǎo)航菜單和一個訪問數(shù)量計(jì)數(shù)器。
當(dāng)我們的訪問量越來越大時,我們決定加入電子商務(wù)功能,我們遍歷了一些現(xiàn)成的工具包,它們的質(zhì)量從差到極差不等,我印象中第一個版本大部分建立在擺弄cgi腳本以及怪異地把<select>元素用于幾乎所有的用戶交互部分之上。
之后的一個版本是充斥著framesets和Javascript的怪物(具體可查看億企邦的《JavaScript是什么?JavaScript功能有哪些》相關(guān)介紹),遠(yuǎn)在Javascript成為舉世皆準(zhǔn)的構(gòu)建應(yīng)用功能的方式之前。另一個版本是由微軟的Access數(shù)據(jù)庫驅(qū)動的。
不久后我們意識到,如果我們想要一個真正可用的甚至體面的在線商店,我們需要一個自定義解決方案。我想到了我過去的成功經(jīng)驗(yàn):fuck生成器系列,以及截至那時我所編寫的優(yōu)秀網(wǎng)站,這其中:我的Manic Street Preachers吉他譜收藏網(wǎng)站非常具有權(quán)威性,我認(rèn)為是時候看看我能真正做些什么的時候了,我要自己從頭開始干。
從頭開始?即使那個時候開源框架已經(jīng)存在,我也不會知道他們,我有自己的計(jì)劃,我買了一本關(guān)于PHP和MySQL的書,一邊學(xué)習(xí)一邊著手搭建新的網(wǎng)站(其實(shí)可以編程網(wǎng)頁的語言還有很多,具體可通過億企邦的《12種最常用的網(wǎng)頁編程語言簡介》相關(guān)介紹來詳細(xì)的了解)。
幸運(yùn)的是,這本書把一個非常簡單的購物網(wǎng)站作為它的核心例子。所有的部分都在那兒:“category.php”會列出一個目錄中的所有物品;“product.php”會顯示商品信息以及把該商品加入購物車的按鈕;以及最重要的“cart.php”,它是所有奇跡發(fā)生的所在,這就是我想要的東西!
我孜孜不倦地學(xué)習(xí)這個例子,充滿自信地實(shí)現(xiàn)所有巧妙的而且毫無疑問也是最新潮的技術(shù),那些方便的“mysql_”函數(shù);用于建立查詢的字符串連接函數(shù);把不同的函數(shù)放進(jìn)“functions.php”文件;通過加入“header.php”和“footer.php”來維護(hù)整個網(wǎng)站的一致性;為了代碼的快速運(yùn)行而回避了笨重的面向?qū)ο蟮脑O(shè)計(jì)方式(管它是什么玩意),我的技能在飛速成長。
像一個人的王國一樣,我建造了高塔和迷宮般的地道,我每添加一個特性,就好像整個結(jié)構(gòu)在向天空伸展同時也向地下蔓延。顧客帳戶、商品評價、購買歷史、優(yōu)惠點(diǎn)數(shù)、帳單號、特殊優(yōu)惠、日志、 A/B測試、支付信息加密,等等,一個蔓延的迷宮,一整個星系的函數(shù),大的小的,緩緩圍繞一個不變的核心:“cart.php”。
經(jīng)過八個月的激情工作,我終于完成了,它成功運(yùn)行了。
4、最糟的設(shè)計(jì) 盡管我現(xiàn)在把這當(dāng)作我最糟的設(shè)計(jì),但是這個東西確確實(shí)是能夠運(yùn)行,它在每一個糟糕的教程,每一個反php的帖子里都能找到,攪成一團(tuán)的代碼?是的。不一致的數(shù)據(jù)和方法名稱?是的。介紹和業(yè)務(wù)邏輯混在一起?是的。魔幻數(shù)和全局變量?是的。
對我而言,面向?qū)ο蟮脑O(shè)計(jì)只是一堆不必要的開銷和公式化的代碼,并且有很多片面的理論支持我的觀點(diǎn)。我知道有關(guān)測試的所有,點(diǎn)擊一些你設(shè)計(jì)的特性,看上去不錯,上傳運(yùn)行,我不太知道別的架構(gòu),但是據(jù)我所知,我所采用的是最明智的方法。
一些事實(shí)能“證明”我所做的都是正確的:我從零開始,白手起家,用智慧創(chuàng)造了一個功能齊全的電子商務(wù)站點(diǎn),更重要的,它運(yùn)行完好并且還在擴(kuò)張。
在我的眼里,我和那些寫了亞馬遜的程序員們沒什么太大區(qū)別。當(dāng)然亞馬遜要大一些,但是我沒有看到任何我的網(wǎng)站不能擴(kuò)張成那樣的理由,尤其考慮到我采用的高速運(yùn)行的架構(gòu)。
那時,我認(rèn)為我的技術(shù)水平已經(jīng)到了巔峰了,并不是說我對學(xué)習(xí)新技術(shù)不感興趣了,我只是不再對此感到緊迫,畢竟我創(chuàng)造了一些不錯的產(chǎn)品,任何在此之上的東西只是附加獎勵,是蛋糕頂端的櫻桃而已。
5、回到地表 我很遺憾,我在這種心態(tài)下生活了好幾年,我只是將一小部分時間用在這個網(wǎng)站上,而把主要時間用在完全不同的領(lǐng)域,在之后多年的維護(hù)和偶爾添加特性的過程中,我確實(shí)意識到了之前做的一些選擇是有問題的,我意識到有時候要花很長時間才能找到我要找的文件,有時候當(dāng)我做一個改動時,一些看上去毫無關(guān)聯(lián)的地方會出現(xiàn)bug。
我的學(xué)習(xí)沒有停止,但它確實(shí)進(jìn)展緩慢,我意識到我曾經(jīng)寫的mysql函數(shù)是有風(fēng)險的,因?yàn)楹竺姘姹镜腜HP減少了對它們的支持。
在一段時間里,我克服對此的恐懼的方法是堅(jiān)信我的無懈可擊的設(shè)計(jì)可以彌補(bǔ)這些風(fēng)險,畢竟我嘗試了所有形式的我能找到的SQL注入,一切看起來都沒有問題。
去年的一天我接到了一個緊急電話,網(wǎng)站掛了,所有的請求都得到500錯誤,在工程師們重新啟動并且分析了事故原因后,這被證實(shí)是一起來自國外的sql注入攻擊,是我從來沒見過的一種。
好吧,我想,這也許是我該轉(zhuǎn)向PDO(PHP Data Object)的時候了。
PDO(PHP Data Object)是PHP5新加入的一個重大功能,因?yàn)樵赑HP5以前的php4/php3都是一堆的數(shù)據(jù)庫擴(kuò)展來跟各個數(shù)據(jù)庫的連接和處理,什么php_mysql.dll、php_pgsql.dll、php_mssql.dll、php_sqlite.dll等等擴(kuò)展來連接MySQL、PostgreSQL、MS SQL Server、SQLite,同樣的,我們必須借助ADOdb、PEAR::DB、PHPlib::DB之類的數(shù)據(jù)庫抽象類來幫助我們,無比煩瑣和低效,畢竟,php代碼的效率怎么能夠我們直接用C/C++寫的擴(kuò)展斜率高?所以嘛,PDO的出現(xiàn)是必然的,大家要平靜學(xué)習(xí)的心態(tài)去接受使用,也許你會發(fā)現(xiàn)能夠減少你不少功夫哦。
我實(shí)現(xiàn)了PDO(PHP Data Object),同時開始第一次使用PHPUnit,我決不想嘗試通過單元測試去改造那樣的代碼。
現(xiàn)在我有意識地迫使自己無論何時都盡量去學(xué)習(xí),我正在讀一些每個程序員都應(yīng)該讀的書,我在關(guān)注別人的博客,比如億企邦,我在收聽播客,我會看會議視頻,我正在參加一些當(dāng)?shù)氐纳鐖F(tuán)并且在其中做演講,我在做副業(yè)并且挑戰(zhàn)自己學(xué)習(xí)新的技術(shù),我在學(xué)習(xí)用正確的方法做事。
對你們所有獻(xiàn)身于這項(xiàng)事業(yè)中的人來說,有一個對我們很重要的有利條件,即編程是這樣一個完全抽象的活動,任何其他領(lǐng)域都會受到的現(xiàn)實(shí)世界中的限制在這里不存在,在這里,你的極限是你自己。
6、覺悟 當(dāng)我坐下來準(zhǔn)備重寫所有的數(shù)據(jù)存取方法時,我意識到了一些深層次的問題,我意識到這將會很困難,而且我知道為什么它會這么困難。
因?yàn)檫@些方法散落在所有地方;因?yàn)槲覠o法知道是否會不經(jīng)意地破壞一些東西;因?yàn)榇a是如此不一致以至于我要小心地研究不同對象的細(xì)微差別;因?yàn)楹芏啻a和別的部分緊密相連,這也會導(dǎo)致我會不小心造成破壞。
簡單地說,這將會很困難,不僅因?yàn)樗羞@些壞的實(shí)現(xiàn)方法,還因?yàn)槲覍λ鼈兯鶎⒃斐傻暮蠊狈︻A(yù)見。
所有的辯護(hù),借口,逃避都無法繼續(xù)下去了,我錯了,我不是那個幻想中的天賦卓越的程序員,這么多年來,我一直都沒有認(rèn)清這一點(diǎn)。
我的愚蠢已經(jīng)顯而易見,盡管這對我的自尊心是極大的打擊,但這也是很寶貴的一個教訓(xùn),也給初學(xué)者一個真實(shí)的忠告(有興趣的朋友可以看下億企邦的《老程序員給初學(xué)者的一些建議和忠告》相關(guān)介紹)。
我通過親身經(jīng)歷(而且是非常痛苦的),學(xué)到了為什么做一件事的方法有對錯之分,這不僅僅關(guān)系到品味或者時尚,這不是比誰的方法更聰明,正確的方法可以在現(xiàn)實(shí)生活中找到,并且能讓你和那些使用你代碼的人的生活更好。
錯誤的方法讓人沮喪,浪費(fèi)時間,我在這里不想說明哪些東西是組成“正確方法”的要素,只要說不是我做的那些就夠了。
億企邦點(diǎn)評: 作為一個初學(xué)者或者進(jìn)階者,這并沒有什么錯,當(dāng)一個有能力的程序員而不是領(lǐng)導(dǎo)者,這也沒有什么錯,真正的錯誤是,當(dāng)你知道應(yīng)該如何去提高時仍然選擇做一名初學(xué)者。