小printf的故事:什么是真正的程序員?
英文原文:The Little Printf(PDF電子書)
第一章
(推薦看完整篇文章,再回過頭看一遍第一章)
我非常幸運出生在一個電腦和電子游戲還沒有普遍的時代。所以我可以和我的小伙伴們一起玩耍,同時發明屬于我們的游戲。
我們十分會玩:用樹枝做成弓箭。我們可以用樹枝做出任何東西,除’回旋鏢’。因為你把樹枝扔出去,你需要自己撿回來。(作者這個故事是活躍氣氛嗎?😓)
當我們長大了,上面說的游戲變得很幼稚。你不能把一個松塔當成一個手榴彈;假裝擁有神奇的魔法;當其他孩子覺得作為一個成年人很酷。你最終會迫于壓力而長大。不過總的來說這也是一個非常幸運的童年。
偶然的一次機會我接觸了電子游戲和電腦。你可能想沉浸在這個虛擬的世界,這會毀了你。
大多數電子游戲:你不能創造,只能反應,浪費你的時間。我在十多歲的時候,參加過’即興表演’。在那里我可以發揮我的創造性。
我大學的專業是’多媒體’,但是我最終卻從事’編程’工作。我覺得編程is amazing!我可以發揮我的創造性,同時又可以掙錢!之后我做了我的第一個游戲。
“這不是一個真正的電子游戲。”別人跟我說:“它只是一個html的表單,而且代碼需要簡化。”
這席話使我有一些沮喪,它花費了很多心思和時間。但是,我意識到如果我想做出被人們認可的東西的話,我還需要學習更多知識。
我需要學習真正的編程。從GUI工具里的js,轉到更好的語言:像PHP。所以我先學習了js,后來又去學習PHP,但是一切并不是很順利,其他人給我的建議去試試python。最后,我學習的是python(🎊我也是這樣走上python之路的🍻)。
但是python中高深一些的東西:’lambdas’和’面向對象編程’,讓我云里霧里的。后來別人建議我去讀一下《計算機程序的構造和解釋》,因為它是編程的基礎入門圣經。
就這樣,我知道了Scheme,后來我又去學習C語言。因為大多數的程序員都會C,同時我旁聽了我們學校的計算機課程,跟著他們一起學習。因為,真正的程序員都知道數據結構和數學,但是這些我只略懂皮毛。我開始讀技術文章和書,因為程序員的知識更新太快。
經過一段時間,我掌握了Erlang,從而開始了我的職業生涯。(這篇文章的作者寫了一本Erlang入門書)。十分奇怪的是,我這個沒有用Erlang做過任何生產級別開發的人,卻得到了一份教Erlang的工作。
第二章
所以我忙于到世界各地演講,教別人(夸夸其談)。但是,大家似乎都相信我是一個真正的程序員。因為,我講的這些事情大多都和編程無關。
一天,我結束了一個會議回家,飛機晚點。我憤怒的敲擊著鍵盤,一個柔弱的聲音打斷了我:
“你好,能請你給我設計一個系統嗎?”
我:”什么?”
“給我設計一個系統!”
我對這個請求很驚訝。我環視四周,發現一個渴望成為開發者的孩子。他叫’printf’(主角閃亮登場)。我覺得這個名字很傻。“我還不是很了解計算機,但是你好像是計算機方面的專家。我希望寫一個blog程序,人們可以使用和訪問它。求求你幫我設計一個系統!”
這是個令人驚訝的請求,并且我已經二十多個小時沒睡了。我不是完全理解他所說的。我告訴他,做一個系統十分困難。我不知道他想要做什么:需要支持多少訪問者;在哪里部署;所以我無法根據他提供的少量信息,設計一個合適的系統。
“沒有關系,給我設計一個系統吧。”
所以我做了下面這幅結構圖:
他看了之后說:”不,這個系統還不夠好。請給我再設計一個別的。”
所以我又做了下面這個:
然后我給他講解這個系統的工作原理。
我的新朋友(printf)十分禮貌的說:”這不是我想要的,它又太復雜而且好多東西都是我不需要的。”
我感到十分不爽,我設計的這個系統考慮到了:冗余、監控、備份、緩存、負載、支付、故障轉移、部署簡單等等。我設計的這個系統都已經可以獲得一份可觀的咨詢費用了!我已經失去耐心了,所以我就畫了這個:
我又告訴他:”這是你設計的系統,你要的系統在這個黑盒子里。”我希望這個滑稽的答案,可以打發他。但是他的回復讓我十分驚訝:
“這正是我想要的!”
這就是我和小printf相識的過程。
第三章
過了一段時間,我知道了這個小鬼的編程水平。在他的代碼倉庫只有些小程序、網站的小demo、瑣碎的程序片段。都是些不值得一提的東西。
之后他開始著手做一個需要很多模塊的大型程序。這個程序需要socket、磁盤讀寫、用到真正的數據庫。當它第一次跑起來的時候,小printf十分興奮。但是,這個程序還不夠好。
這個程序需要重構、更好的測試、文檔、分析。它只運行了一段時間就崩潰了。然后一次又一次的崩潰!
程序的設置是錯誤的,日志不工作、磁盤速度不穩定、網絡卡頓、有bug、編碼混亂、數據庫需要清理、證書過期、沒有異常處理導致問題找不到根源。
真的像面條一樣一團糟。
小printf跟我說:”通過這件事,我發現自己簡直是一無所知!這個程序本來是根據我的需要寫的。我原來的想法太天真了,后來我修復bug的時間和這個程序給我帶來的便利根本不成正比!最后,變得跟我原來想的一點都不一樣。雖然這樣,我仍然認為這件事情讓我收獲了很多。”
一天早上,他決定離開我這里。“再見。”小printf跟我做了最后的道別。他想要出去看看世界,看看其他人寫的程序。
小printf寫的應用,最后因為不斷增加的日志,導致硬盤沒有空間,徹底的崩潰了。
第四章
小printf走進了一個辦公樓,想尋找有經驗的程序員取經,獲得一些建議和幫助。
他遇到一個驕傲的高級程序員,而且自我感覺良好。
傲慢的高級程序員說:”哎,過來新手!歡迎來到我所擅長的領域,在這個領域我是專家!”
“專家?”小printf問到:”專家的意思是:可以編寫任何程序嗎?”
“是的!”傲慢的高級程序員回答道,接著他又說:”準確的說,應該是大多數程序。因為我只編寫有價值的程序,我不會浪費我的時間在沒有意義的小程序上。很多程序我都沒有寫過,但是它們都難不倒我!”
“額,所以你可以幫我完善我的程序?”小print問到,之后他開始闡述他的網站系統,但是傲慢的高級程序員打斷了他:
“對不起,我覺得你的網站系統沒有一點價值。”
小printf:”為什么?”
“經驗!我擅長編寫我開發的東西,我也只做我擅長的領域的開發。我需要確保我在我的領域的永遠有價值。這叫做工作保障,也叫做適者生存。但這就是我的風格。我只專注于我的領域!”
小printf:”那你為什么不幫我呢?”
“花費我的時間去幫助你,意味著我需要花費精力去幫助別人,而不是提高自己——這對我來說不是一個好的主意。我的建議是:自己多努力,自己弄懂。還可以塑造你自己的心性”
小printf:”你說的方法,好想不是很高效。。。”
“你可以到學校去學,或者自學。事實上這種方法可以淘汰那些懶惰、只喜歡簡單的事情的人。真正渴望知識的人才能成功!”
小printf:”你認為合作和同事不能幫助你嗎?”
“不,我并不是這個意思。我最好的工作狀態是:獨立空間,沒有讓我分心的事。每次我和同事合作的時候,都是一次不好的經歷。以往的經驗:最好的辦法是——把他們的代碼拿過來重寫。然后就可以了!”
小printf對這個不喜歡幫助別人的專家感到十分驚訝,不僅如此,他還因認為別人的技術不行而惱火。這個專家眼界是狹隘的,他只關心自己擅長的領域。活在自己的世界里。
小printf:“我明白了,我想我很慶幸你沒有幫助我。”
“你什么意思?”傲慢的專家問到,貌似他的權威受到了威脅:”你不認可我,你是在質疑我嗎?”
小printf:“并不是這樣,就像你覺得我是一個累贅,令人惱怒的一樣。我是來尋找幫助的,而不是來找罵的。”
說完之后,小printf飛快的跑出了傲慢專家的辦公室。當小printf離開后,這個專家又重新找回了他所擅長領域的權威,同時自我感覺良好。
第五章
然后,小printf又走進了另外一個辦公室。里面有一個男士,他的座位周圍都是精裝厚厚的書籍(例如《代碼大全》這種書)。
小printf:“先生,你有好多書啊!”
“是的,我想這些都是程序員必看的書籍,如果你沒看過這些,你很難成為大牛。”
小printf:“我想我現在還是很菜,請問這些書里面你最喜歡哪本?”
“哦,是這樣的,這些書大多數我還沒有讀過。”
小printf:“那你現在是個大牛嗎?”
“不,我還不是。”這個程序員很驕傲的說:“我其實是一個很垃圾的程序員。”
小printf:”這太丟人了,我正在努力變強。”
“你聽過‘達克效應’嗎?”
小printf:”那是什么?”
“簡單的說就是:能力強的人總是低估自己,能力弱的人總是高估自己。”
小printf:”也就是說,如果我覺得自己在變強,其實我并沒有變強。”
“是的,你說的非常正確。你很可能在原地踏步。另一方面,我宣揚我是一個很糟糕的程序員,但根據‘達克效應’,我是低估了我自己,所以我是一個好的程序員,你怎么看?”
小printf:”我。。。額”
“這就是為什么程序員都喜歡自嘲(稱自己是碼農也算吧?)。當你認為你足夠好了,你就放松了,也就沒有前進的動力。”(這句話我還是很贊同的👍)
小printf:”你的意思是:一旦自我感覺良好,也就是正在走向失敗,應該時刻覺得自己還不夠好。”
“是的,但是用著這種方式應對所有的事很危險,如果你還沒有拿到offer。這種方式會讓你顯的聰明,但是沒有任何實際用途,別人不會因為你顯的聰明就雇傭你。”
小printf:”你的意思是?”
“比方說,我在網上看到一個我不喜歡的項目。我留言說項目一無是處,但是不明確的指出哪里不好。最后,你還可以說這個項目的作者是笨蛋,也沒有人管你。”
小printf:“但是這樣做有什么好處呢?”
“我想讓他們知道他們走上歧途了,卻又不明確的指出來。這表現的我比他們厲害。然而他們毫無頭緒,像霧里看花。沒有人能明白我的意思。哇咔咔”
小printf:“當別人請教你的問題,你不會的時候,你會怎么辦?”
“這種情況下你就說到處都是問題,還有很多的不完善的事情要做,總之就是轉移話題。然后他們感覺絕望,最后還是要他們自己解決。”
小printf:“所以這就是你的立場?這是你的一貫作風?你會的問題裝作對此無能為力,使得真正無法解決這個問題的人抓狂;當你遇到不會的問題時,你裝作很了解,使得別人根據你的建議改善其它的地方,而與真理相行漸遠,浪費時間”
“很多情況下,才能不是最重要的,但口碑很重要。人們雇傭朋友,不被喜歡的人和無關緊要的人會被第一個被炒魷魚(😤MLGB)。要不就改變環境,改不了就要適應,適應不了就被淘汰。這就是‘社會’。企業中就是這樣,學術屆沒準也是如此。做這行,你認識誰,學會推銷自己,建立自己的聲望。這樣你才能在企業里站住腳。”
小printf:“如果在企業中工作是這么惡心,要給別人‘使絆’。那么我真不想在這種環境下工作!(黑暗的辦公室政治,還好我還沒有遇到🙊)”
第六章
到了吃午飯的時間,小printf打斷了一個貌似忘記吃午飯的人。他桌子上的三明治已經涼了,但是他還是坐在桌子前面盯著他的屏幕。
他好像十分的忙,但是沒人知道他在做什么。
小printf:“如果主數據庫掛掉了,從數據庫也會掛掉嗎?”(創建主從數據庫是為了減少DOWN機時間,讓數據庫可以一直處于工作狀態中)
“你運行的所有東西,或早或晚都會掛掉。”
小printf:“你以往的經歷告訴你這一切都會失敗?”
“是的,不僅如此。所有的大系統,都會在特定的時間出現問題。”(就像千年蟲問題?🤔)
小printf:“那么,做一個可靠的系統,都需要做什么?”
那個人忙于他自己的事情,沒有理會小printf。
小printf又問了一次:“做一個可靠的系統,都需要做什么?”
那個人正在嘗試解決產品中的一個問題,但是小printf還一直問個不停,同時他還沒有吃午飯。
所以他不耐煩甚至粗魯的吼道:“這根本不可能,編程就是shit💩。”
小printf倒吸了一口氣,半天說不出一句話。
小printf💢憤怒的回擊道:“我不相信你說的。程序是脆弱的沒錯,但是程序員可以改善這一點,同時做出更好和有用的東西”
那個人沒有任何回答,他在查閱文檔,嘗試重新啟動一個新的集群,但是情況卻越來越糟糕。
小printf:“并且你應該相信有好的可靠的程。。”
“不可能”,那個人打斷了小printf,接著說道:“我不相信有可靠或者好的程序!根本不可能!這是我的第一個感覺,因為我正在處理一個垃圾的系統。你沒看見我在想法設法地讓這個東西跑起來嗎?事實如此!”
小printf很震驚的看著他說道:“事實如此?說的好像自己是個專家!是你自己把一切都搞的很糟糕。這世界上有上百萬的久經考驗的程序,它們也有bug,也崩潰。但是人們還是需要它們,使用它們。據我所知,很多程序是沒有問題的。出現問題的原因大多是因為電腦的環境配置問題,或者一個錯誤的操作造成的。你不認為這才是問題的所在嗎?”
那個人聽完啞口無言。
第七章
小printf來到了第四個地方,遇到了一個人,他的電腦幾乎被便簽蓋滿了,沒有人知道他在干什么。
“motor-mvc, quadrangular JS, GoQuery, cometeor, some japanese soundy thing, …”
小printf打斷了他的自言自語說道:“你好,你在干什么?”
“alchemist, bongodb, mochascript, walktime.js, portasql, …”,那個男士繼續自言自語。
小printf提高了音量又問了一次:“你在干什么?”
“哦,我正在嘗試新的框架,工具和語言。”
小printf:“哇,你接觸的東西好新鮮啊!大多數人還都沒有聽說過這些。”
“是的,這個行業跟新很快!”,他看了一眼他的手機接著又說到:“看,http://cardboard.io框架又推出了3.5版本,它宣布不兼容3.4了。與此同時,社區中已經有4個衍生版本了。我必須從他們之中挑一個。”
小printf:“你這么做為了什么?”
“我是最早的嘗鮮者,如果你不保持更新技能樹,還是用老掉牙的COBOL或者MUMPS(兩門老掉牙的編程語言🤖)。你還想抓住成功的契機,搶占先機,乘勢而起?”
小printf:“你成功的預測過以后的熱門技術嗎?”
“是的!我發現Rails的時候它還很小,我學會Node.js的時候它還沒有流行。我是redis、mongodb和riak的內測用戶。我是第一批試用vagrant的用戶,然后我轉去使用docker,但是現在我全身心的關注unikernels。。。”
小printf:“太酷了!你是第一批試用這些技術的人,你從中得到了什么回報?”
“額,并沒有。當Rails壯大的時候,我就去關注另外的新鮮東西了。同樣的,其他的幾門技術我也是這樣的(他不獨寵一個,而是雨露均沾🙈)。我現在把希望寄托在unikernels上。”
小printf沉思了一會說到:“你用這些框架和工具都解決了什么問題?”
“我每次都確保不使用不成熟的東西,因為不能用公司做賭注。這一點十分重要,因為如果你使用最新的技術,你就可能招不到人,而不關注新的技術,有可能脫離時代的步伐。所以我們鼓勵學習新的技術。”
小printf:“這非常有趣。”
“在這個飛速發展的世界中,如果你想參與這場游戲,你需要有先進的技術。否則你就會被時代淘汰,沒有人想被時代淘汰。”
小printf:“不,你誤解我的意思了,我的意思是:好的工具是為了解決問題而被制造出來的。但是你卻盲目追求新的技術,而不是為了什么實際的目的。”
聽完這些話,哪個人呆住了,小printf跳躍著離開了這個房間。
第八章
小printf來到了下一個辦公室,這里有一個疲憊的女員工。桌子上雜亂無章,整個人無精打采,瘋狂的打字。
小printf:“你好。”
這個女士沒有停下了她的手頭工作,繼續瘋狂的打字。
小printf又打了一遍招呼:“你好?”
女士這次停下了,拿起一瓶咖啡猛灌了一口。
“我有一份十分糟糕的工作。”,她說:“我是devops(開發,運維,測試于一體的職位)。剛開始的時候還好,原來我大多數時間進行開發,然后抽出一些時間修復bug。但是,情況變的越來越糟糕,bug開始接連不斷。為了擺脫這種情況,同時在規定時間內完成。我不得不使用一些奇技淫巧。”
小printf:“你為什么不雇人來幫你?”
“我很擅長做這些事情。我已經習慣這一切都在我的的掌控之下。還有因為他們已經習慣我可以hold一切,如果我提出我自己無法繼續掌控全局,他們很容易認為我在偷懶。”
小printf:“這真是叫人悲傷的故事。”
“事實就是這樣子。因為你是最熟悉這些問題(bug🔥)的人,你只能變的越來越累,直到你的boss招了一個人頂替你原來的工作,這是唯一的出路。但如果你擔心其他人修改你寫的東西時候遇到問題,你只能幫助別人改一個又一個的bug,當然這些都是你討厭的事情。直到你對這一切感到麻木。”
小printf:“你真不幸。”
這位女士又被叫去工作了。
小printf自言自語道:“這個女人會被我原來遇到的那些人嘲笑的——那個高級專家(只專注于自己擅長的領域),搖滾開發者(過分追求新技術的人),故做高深的程序員(那個周圍都是大頭書的裝X程序員)。盡管他是這些人里面唯一樂于助人的。或許是因為,她認為一切事情還是親力親為的好。”
第九章
小printf發現在這棟大樓里發現了一個有著巨大落地窗并且寬敞的辦公室。這里坐著一個德國老頭,他面前堆了一堆的文件。
“啊!來了一個開發者。”,德國老頭驚呼道同時招呼小printf說:“快進來!”
小printf環視四周的窗戶,發現上面寫滿了東西。上面畫了各種圓圈,箭頭,圓柱和云彩(就是圖片中玻璃上的圖形)。真是搞不懂這個老頭畫這些東西有什么用。
小printf:“窗戶上的都是些什么?”
“哦,這些?這是我們的線上系統!”,那個老頭隨口說到:“我是一個軟件架構師。”
小printf:“什么是軟件架構師?”
“總的來說,就是知道如何構建大型系統并且讓系統中的每個部分都非常穩定的人。架構師還會數據庫,編程語言,框架,編寫程序,協議,封裝和降低耦合等知識。”
小printf:“聽起來都叫人興奮!終于有人能回答我的所有問題了!”,小printf瞥了一眼玻璃上的結構圖說到:”你們的系統真大,他跑的快嗎?”
“我沒法告訴你。”,架構師說;”應該會很快吧。”
小printf:“那它的代碼怎么樣呢?”
“我沒法告訴你。”
小printf:“用戶喜歡這個系統嗎?”
“這個我恐怕也沒法告訴你。”
小printf:“但是你是軟件架構師啊!”
“我的確是架構師,但是我不是開發者。架構師不做——例如功能模塊、類、整合lib等——這種工作的。架構師最重要的不是寫代碼。他是指引程序員和開發者的人。如果遇到棘手的,無法解決的問題,架構師才會接手。”
小printf:“這是為什么呢?”
“因為我們經驗十足。我們了解系統并且能解決它的一切問題。開發者可以根據我們的經驗和指導,開發出好的系統。”
小printf:“但是你不寫不看代碼怎么知道這將是個好的系統?”
“我們相信開發者。”
小printf:“所以,所你們相信開發者們可以正確的實現你們的想法,但是開發者們沒有機會提出他們自己的想法?”
這個軟件架構師明顯的愣了一下:”我想。。。”,他最終承認了:“你剛才提出的這個問題,其實工作中很多的提議是沒有被證實或者實驗的。。。”,他停頓,并沉思了一下說道:“有些時候軟件架構師看起來既不是軟件工程師,也不是架構師(是老師?)。”
小printf離開了這個房間,結束了他的旅行。走出了這棟樓。
第十章
小printf走到外邊,發現了一個為慈善機構募集錢的男士。
“你好”,那個男士說道:“你覺得幫助一些需要幫助的人的感覺怎么樣?”
小printf:“那樣可能會讓我感覺更好,我在那棟建筑(遇到了各種各樣的程序員的大樓)呆了一整天,尋求幫助。但是現在,我感覺比以前更加迷惑了。”
“嗯,我幫你分析下:那些人都是開發者,他們并沒有真正幫到你是嗎?他們喜歡說‘程序員改變世界’,實際也是這樣的。”
小printf:“那為什么我卻毫無收獲呢?”
“是這樣的,他們最擅長做的事情是幫助把人們的工作變成程序,使人們變的輕松。軟件正在吞噬整個世界,使世界改革換面。但是事實上這還是個舊的世界。因為以這種方式的改變,并不意味著事情變好。我們還是有些根深蒂固的問題(例如:思想的問題,或是缺乏創造性。)。”
小printf焦急的說:“怎么做才能讓我感覺更好?”
那個男士深思了一會,最后提出讓小printf幫助他,為需要幫助的人募捐。因為這個男士認為這種方式可以讓他感覺更好。用一下午的時間,小printf把他的問題和他的經歷都告訴了這位男士。
這個男士沉思了很長時間說道:“在個游戲中,他們從解決復雜的問題而得到的快樂以及他們看重的名聲和身份,這種快樂是片刻的。因為最終,如果你解決的問題沒有實際價值(為了解決問題而解決問題),忽略了‘以人為本’。那么你永遠不會得到真正的滿足!”(說的真好!)
他接著又說:“隨著你的成長,可能找到一家比之前更好的單位。可能是錢多,或者是因為這個工作更有趣,這都很正常。只要你知道你自己想要的是什么!”
他最后補充道:“最后,當你解決了人們真正面臨的問題的時候,你會覺得真正的滿足!有的時候根本不需要計算機。”
“你花費了大量的時間在你的系統上。最重要的是:你忘記當初為什么創建這個系統,反而花費時間在優化系統上面,那么它就變成了一場炫耀的游戲。這才是最可悲的。”
“開發者經常忘記最開始的初衷(真正有意義的事情)。如果你失去做這件事意義,而是為了解決系統的問題,才花時間在這上面。這就是問題的所在(如果你只是為了做好的系統,而不是解決實際問題,那你就應該自我反思了)”
小printf不斷重復這句話,想要印在腦子里:“只有在解決人們真正面對的問題的時候,才能獲得真正的滿足!”
第十一章
小printf坐在我的前面,和他聊天讓我開始認真思考:我為什么走上編程的道路。小printf之前遇到的每個人,仿佛我將來的某一天會成為他們中的一員(這真是個悲傷的情景)。我被這樣的人(小printf之前遇到的那些程序員)鼓勵成為像他們一樣的程序員。
我也被拖進,小printf不喜歡的那個,成為“真正程序員”的游戲中。小printf曾說過:相比于“真正的程序員”,我更想成為能夠為人們解決真正需要解決的問題的程序員(解決真正問題的程序員,而不是解決編程問題的程序員)。
今天我呆坐在這里,回顧我的整個編程生涯,我想弄清:成為解決真正問題的程序員,還是一切都只是完成工作。這兩者是完全不同的。
不管怎么樣,小printf認為他不需要成為一個真正的程序員。我現在,也是這樣認為的!