Web 開發 17 年的所見所得

發表於2017-07-10

關於 NodeConfBP

NodeConfBP 會議於 2017 年 1 月在布達佩斯召開,本次會議為期一天,只有一個演講室,由 RisingStack – the Node.js Consulting & Development Company 組織並提供贊助。

下面你將會從第一人稱視角感受到一個近乎完美的風格化的會議記錄:

認識下 Daniel Khan

DynaTrace 做過的任何和 Node 沾點兒邊兒的專案基本上我都過了個遍。另外,我還在給 Lynda 做輔導課程。我在當地大學教書,有三個女兒和一個兒子。

這次講話基本上都是我的故事,涉及到了我 17 年學到的關於 Node 的一些東西。

在我看來,世間萬物都是迴圈的,它們會反覆出現,因此我們能夠以史為鏡,避免重蹈覆轍。

Daniel Khan's First Webcam Picture

這張照片拍攝於 1997 年,是我第一張使用網路攝像頭拍攝的照片,照片上右邊的那個傢伙就是我。

我們購買這臺 silicon graphics O2 差不多花了一輛小轎車的價錢,然後這個傢伙跑過來說“現在我們正在使用網路攝像頭一起拍照”。然後 哇哦 照片就出現在網際網路上了,在那個時候這真的是一件特別炫酷的事情。

1998 年我就已經開始玩 HTML 了。

This is how the web looked like in 1998 according to Daniel Khan

當時的網站看起來和圖片上展示的差不多,而且那個時候這本書還沒寫呢。

那個時候還木有 Google,木有 Facebook,木有 GitHub,木有 Wikipedia,也木有 StackOverflow。

那個時候我們只有新聞組,我們可以在上面提問,其他人也可以回答問題。有點兒像 email,但和 email 還是有區別的。

Daniel Khan's Newsgroup Question

時間走到了 1999 年,也就是 17 年前,我在 Square 新聞組裡寫下了我的問題:

  • “我正在寫 web 資料庫,但是我們已經有桌面資料庫了呀。”

是的,Microsoft Access!

  • “我的主機支援 MySQL,但是我並不知道這是什麼意思…”

我真的不知道。

  • “我知道 query 語句是如何執行了。”

其實,我完全不知道。

那個時候,我真正學到的一點是:網路永遠不會遺忘。那時我真的是毫無頭緒。

進入 2000 年

在 2000 年我成為了一名 web 開發者,當時我在給 Austrian Job Service 教 Perl,因為在那個時候,找不到工作的人基本上都能成為一名 web 開發者,在當時這是種趨勢。

那個時候 Perl 語言非常難,但是既然我已經準備教 Perl 了,那就是說明…

我非常非常聰明,是吧?

但是,真相永遠是殘酷的:其實我一點兒都不聰明。

當我嘗試在資料庫中更新資料集時,因為我不知道如何實現才算合理,所以一開始我的做法是先刪除然後再插入。

Daniel Khan became aware of the Danning Kruger Effect

那麼問題來了:就我這種水平,我又怎麼會認為我自己還能教學呢?答案就是:達克效應。

簡單來說,達克效應就是:因為你無知,所以你不知道你自己有多無知。

What I think I know vs what I actually know graph by Daniel Khan

那條綠線是你認為你知道的東西,那條黑線才是你真正知道的。那個時候,我認為自己無所不知,直到我完成了大學學業–應該是在 2011 年–我才知道 “好吧,其實我知道的也就那點兒東西”。

然後,你就開始變得稍微謙虛一些了,因為你開始學習那些你不知道的東西,接著你就開始有點兒絕望了。現在,我認為我在那個綠點的位置。

我們去了銀行…

但是不管怎麼著,我設法找到了一家公司,然後買了一臺伺服器。這臺伺服器還是我們去銀行貸了 15,000 歐元買的。

和之前相比,現如今變化真的很大:我們有 serverless 架構,你可以一臺伺服器都不用就把整個公司建立起來。

那個時候,我們不得不把伺服器放在維也納的一個資料中心的機架上。

每當伺服器當機的時候,我就得開著車到維也納去重啟伺服器。

What the full stack means according to daniel khan

那次我學到的東西就是:你要努力理解什麼是全棧。我說的就是上面的這個全棧。

全棧,意味著你至少應該知道一點兒 web 協議、知道路由的工作原理、知道 HTTP 基本的工作機理、知道 SMTP 的工作機制。

當出現問題的時候,知道這些包是如何打包進瀏覽器的,知道這些東西是如何協調的是很有必要的。

然後夜幕降臨,迎來 2002 年

現在我們是在 2002 年,我建立了一家公司。那個時候,除了澳大利亞,網際網路在全球爆炸式瘋長。

我們靜靜地等待著網際網路的繁榮有朝一日能夠降臨到我們身上,然後一切都結束了。

boo.com

我認為這一切都是從 boo.com 開始的,這是一家運營時尚服飾的初創公司。

在那時,每個人都花大把大把的時間去投資和新經濟、新媒體相關的專案,所以整個行業開始繁榮增長。

在兩個月內,公司從 10 個人漲到了 100 個人。然後,boo.com 破產了。

我認為那年的網際網路危機和他們有關。所有的投資者差不多都退出了,因為他們意識到新經濟公司終將會失敗。

The technology Bubble by Daniel Khan

這是納斯達克的資料。我們當時在這個繁榮階段,緊接著一切都奔潰了。這裡是 9/11,一切都隨風而逝…

我在 Google 上搜尋了一下,這是那個時候矽谷人的想法,你們感受下。

Dotcom bubble in the Silicon Valley

我找到了一個哥們兒這樣寫到:

“噢,我的天吶,這簡直是致命的打擊。作為一個年輕的初創公司,我知道的每個人都受到了影響。我知道的大多數人都失去了工作。不久之後,我知道的大部分人都搬走了。”

在這裡他寫到:

“泡沫時代的對比是史詩級的。開放式的酒吧活動和神話般的釋出會都已經一去不復返了。工作和公司也都沒有了。不久之後,絕大多數企業家沒有了安全保障–很多人回到家裡重新組團。”

聽著有些熟悉,是吧?

如果今天你去矽谷,看到的也是這個樣子。一切都是新興的。工作在那裡的人都是這樣的:

“什麼?他們公司沒有自助早餐?

他們沒有這種桌式足球?

噢,我不想在那兒工作了–我想買架飛機。”

homeless programmer

這種事情隨時都會重現。不過那個時候,我們看到的更多一些。

儘管如果現在我說就算這種事情發生了也不會有什麼問題,但是真的當這種事情發生了的時候,就真有問題了。

趁熱打鐵,抓緊機會!

我從中學到的一件事是:一定要趁熱打鐵,抓緊機會!我現在並沒有高談闊論地去談錢。

我正在談論的是通過投資於你的技能和知識來隨時應對不好的時代。

拒絕平庸,對吧?!

程式語言太多了,我認為程式設計並不是說一定要成為一名 JavaScript 開發者或者 Node 開發者。程式設計是一種概念、一種思想。就比如,當你在用 JavaScript 寫例項的時候,可以嘗試一下 Scala 函數語言程式設計的一些東西。

最開始我在 Lynda 和 Coursera 工作,這讓我真正的理解了 JavaScript,理解了我使用 underscorejs 的原因,理解了怎樣才能讓需要的東西更好的融合起來。

所以我想鼓勵你們的是:不要把你自己當成一個 JavaScript 開發者或者 Node 開發者,要把你自己當成一個工程師。

要學習思想、學習如何使用不同的語言去解決問題。你的視野決定你的世界,掌握知識面越廣我們對問題的思考就會越靈活。

The Scala course Daniel Khan took

這是我這次學習的課程。這真的很難,但是這是發明 Scala 的 Martin Odersky 做的,所以他知道他在做什麼,這真的很有趣。

所有的這些資源在網際網路上都是免費的,所以如果你有時間的話,可以投入一些時間和精力培養一下你的技能。

為未來的你寫程式碼

然後,在 2002 年到 2012 年之間我做了許多專案,大部分都是 web 專案,許多是基於 PHP 的,不管你相不相信,其中的一些專案到現在仍然線上上執行著,比如下面這個:

Daniel Khan's Walking Dead App

它們今天還在困擾著我。因為這些應用是我在 2002 年或 2004 年或其他的什麼年份完成的,我從來沒有想過,在 2015年、2016年、2017年,我還能再次看到他們。

但是之後一通電話打過來了:”這個網站掛了,你能不能幫我們搞搞?”–儘管我早已經不是這個公司的員工了。

然後一萬隻草泥馬在奔騰:

“哎呦,我去,這程式碼是哪個傻逼寫的,寫得太爛了。”

…恩,我知道這個傻逼就是我。

在我看來,寫出未來的你能夠理解並引以為豪的程式碼是很重要的!當你做一件事情的時候,要麼不做,要做就把它做好。

程式碼的破窗效應

我最喜歡的一個理論是破窗效應–這個理論也可以應用到程式碼上。

想象一下,你身處一座城市,站在一座高樓面前,周圍的一切都很美好。然後突然一個哥們兒跑過來打破了一扇窗戶。

如果你等上幾個星期再回去看,你會發現整座高樓開始腐爛,搖搖欲墜,到處都是亂七八糟的塗鴉,人們也不再 care 它了。

同樣這也適用於程式碼,那些臨時的解決方案就是高樓上的破窗,是吧?

“恩,是的,我們改天再改吧。”

然後那些臨時的程式碼片段還保留在那裡,然後等到下一個開發人員(有可能還是你噢)過來看了看這程式碼,然後說:

“好吧,這個已經很糟糕了,我們快速修復下,然後程式碼又變得糟糕了。”

所有這些醜陋的程式碼片段都充斥在你的程式碼裡。就算十年過去了,你還是得處理這些程式碼,所以你為什麼不提前和你的小夥伴商量一下?你應該這樣想:

“這是一箇舊專案了,讓我們把這個專案重寫一遍吧。”–因為這就是我們喜歡的做事的方式,對吧?

Daniel Khan advises to think twice before rewriting from scratch

我經常聽到開發者這樣說 “看,這個專案是我們兩年前寫的,整個技術棧都已經落伍了,我們把所有的東西都重寫一遍吧,很簡單的,兩週就能搞定!我們已經開搞了是吧?”

The feature gap explained by Daniel Khan

我們知道軟體都有一個飽和曲線。有時候給程式碼新增新的特性確實很困難,所以這時候重寫程式碼更換技術棧是完全沒有問題的,但是你得注意這裡的這個缺口。

當你切到一個新的技術棧時,專案就變得複雜了,從一開始就不會有相同的功能特性。

因為在整個系統中整合了很多固有的東西,所以你不能輕易重做。所以你必須意識到,如果你從頭開始做某事,那麼至少會有一個特性差距。

網站真的需要 React、需要同構 JavaScript 嗎?

好吧,那我們就重構程式碼,但是網站真的需要 React、需要同構 JavaScript 嗎?我知道,這些技術都很酷,我們也想用。但是,我們真的願意每六個星期就重寫整個前後端程式碼嗎?

新技術日新月異,尤其是 JavaScript 方面的。新技術每月都會出現,而且也有公司在推動著這些新技術。

如果某項技術是 Google 出品或 Facebook 出品,那麼它一定很酷是吧?因為 Google、Facebook 的這幫傢伙們知道他們自己在做什麼。

First Facebook prezentation about React

所以當時就去了解了下 React,還看了看他們介紹 React 和 Flux 的那次演講,會上他們基本上就說了這些:

“我們在 Facebook 上遇到了訊息通知方面的問題,當訊息被閱讀了以後,狀態並沒有更新。”

“我們的這個 MVC 專案很糟糕,因為 MVC 本身就很糟糕,所以這個專案並沒有很好地執行,所以我們發明了 Flux。”

當時,我的反應是這樣的:“我勒個去,這都可以!?”

This is not an MVC

從什麼時候箭頭可以從 View 層畫到 Model 層了?我認為這是錯誤的。

之後有一個問答環節,但是並沒有人提問。在座的每個人可能都是這樣想的,“恩恩,MVC 太遜了,我們確實需要 Flux。”

也許她是要表述一個觀點,但是這個觀點她並沒有表述清楚。

然後我往下滾動頁面,評論區有大量這樣的評論,“這不對啊,這有問題啊,這根本就不是 MVC 啊!”

the commenters agreed with daniel khan

真搞不明白髮佈會上他們都在說什麼。演講完了,每個人都感覺 “恩,MVC 是挺遜的,我們確實需要 Flux,因為 Flux 解決了我們所有的問題…”

不過,說實話,我也沒有資格譴責他們。我在會上的問答環節也沒有站起來說“這個不對”,因為我向來就比較謙虛,我總是認為別人說的都是對的。~^.^~

保持冷靜,勿信炒作

提出質疑,勿信炒作–我們早就該這樣做了。

畢竟,不管是 Facebook 還是 Google,它們也只是公司。如果 Facebook 將 React 交給社群,他們就會有這樣的議程。Angular 和 React 正在交付給新的開發者,或許並不是因為他們想給社群一些東西。

我們應該時刻保持清醒,在大多數的時代都不會平白無故地天上掉餡餅,所有的東西都是期望能夠賺錢的。

所以如果有這種炒作的話,你確實應該提出質疑。

Daniel Khan thinks you shouldn't rely on frameworks and wizardry

畢竟,所有的這些東西都僅僅是框架,是別人的程式碼!

在 JavaScript 的世界裡,我們喜歡談論不必要的依賴,因為那些由網際網路上的某個陌生人擼出來的程式碼總是完美的,對吧?

使用第三方元件真的有點兒 low,使用整個框架同樣也很 low。

問題是這樣的,你依賴別人的程式碼,當你想修改一些東西的時候,你就必須去修改他們的原始碼。

所以此時此刻,你並沒有學習使用程式語言本身來處理問題–你學習的是別人的程式碼,你除錯的也是別人的程式碼。

過去有太多這樣的案例,比如 PHP 的 Symphony 框架。你有一個生成器,然後直接執行就可以了,框架已經為你生成了你所需要的一切。但是,如果在某個時刻框架底層報錯了,那你就真的不知道到底是哪裡出問題了。

那麼問題來了:

相比於快速完成專案,不依賴其他框架自己來做不是更好嗎?

在這種情況下,當出現了問題時,你就得檢視程式碼,學習如何讓它們相互配合。

舉個栗子,在 JavaScript 程式語言中有模組化這一概念–這個概念在 React 中體現的尤為突出–程式碼被分成一個一個的模組,然後以某種方式將它們組合起來。

我嘗試著搞了一個 React 專案,但是我之後就執行 npm uninstall 解除安裝了所有的依賴,因為僅僅為了構建一個同構 React 應用竟然被安裝了這麼多的依賴。

13 dependencies are too much for Daniel Khan

上圖中顯示有 13 個依賴!13 個依賴打包出來的程式碼都上兆了。這種情況一定要謹慎處理啊。

不要輕信別人的程式碼!

對於 npm 同樣有這樣的問題。

npm

從上圖中可以看到,程式設計世界裡有 40 萬個難題,是吧?所以就對應著出現了 40 萬個解決方案。

上週我需要轉換一些 UTF-8 HTML 字元實體–來給大家看一下我搜尋出來的結果:

A lot of solution for the same problem

針對於同一個問題,有許多模組給出瞭解決方案,所以選擇正確的解決方案真的有點困難。

你必須檢視並做決定:

  • 這個包還有人在維護麼?
  • 這個包有多少個 bug?

在你用 npm 或者 yarn 來安裝包的時候應該三思而後行。

同樣,在你從 StackOverflow 上覆制貼上的時候也要三思而後行。

dont copy and paste from stackoverflow

這裡是一個轉換 HTML 字元實體的包。

在文件中有一處明顯的錯誤:首先定義了 var Entities ,然後執行了 entities = new Entities(),他們在無意中生成了一個漏洞。

在 StackOverflow 上有一個問題,回答該問題的一個同學直接從文件裡面複製貼上到了 StackOverflow。

我確信下一個同學會直接將這段程式碼複製貼上到他的程式碼裡。僅僅是因為:StackOverflow 出品,必屬精品。

沒有人站出來說這段程式碼有問題。所以不管你是從 Stackoverflow 還是其他的什麼地方複製貼上程式碼都要三思而後行。

畢竟是別人的程式碼,所以你應該理解整個程式碼,並逐行確認程式碼確實如你所想的那樣執行。

Daniel Khan 的終極 web 開發建議

恩,最後我再說幾句。對於我來說,有幾條原則至關重要。

第一條關鍵原則(注:Don’t repeat yourself):DRY!

這條原則表示-在 Node 中程式碼複用很容易-不要因為某些邏輯相同就隨處複製貼上程式碼。

你應該將 config 檔案 require 到應用中,而不是在用到 config 的地方都複製貼上。require 以後,修改 config 檔案,所有用到的地方就都同步修改了。

嘗試一次載入,減輕程式碼,然後在需要的地方將它傳遞過去。因為回撥函式的存在,所以在 Node 裡事情就顯得有些複雜。

然後,我們說說回撥函式。建立能夠處理函式返回值的函式是個好的選擇,回撥函式就是這樣的存在。

是不是有點說不通?你建立了一個函式來讀取資料庫中的某些資料,然後呼叫回撥函式,處理返回的資料庫結果,這裡最好建立一個能夠處理不同返回值的回撥,而不要一次一次的建立。

Yagni 原則(注:You ain’t gonna need it):“你不會需要它”

所以當你做事情的時候,問自己幾個問題:

  • 這個專案有 Facebook 那麼大嗎?
  • 我真的需要像那樣設定嗎?
  • 我真的需要像那樣建立嗎,還是說我僅僅是預見它以後會出現?

請一定要務實!

KISS 原則(注:Keep it simple stupid)

最後一條原則:儘量簡單

考慮到未來的自己,你的程式碼應該寫的儘量簡單、易理解。如果你喜歡我講的這些程式設計思想,可以讀讀這本書:

Book recommendation by Daniel Khan: The Pragmatic Programmer

如果你要讀書的話,請一定要讀讀這本–《程式設計師修煉之道》。書中講到的許多規則在我講的這些程式設計思想中都有所提及。

謝謝!

相關文章