當前位置: 華文問答 > 數位

編程真的能改變人的思維方式嗎?

2016-12-12數位

與其說「編程改變人的思維方式」,不如說是「思維方式合適的人在這個行業更能如魚得水」;然後再被工作環境以及團隊中的同類反復強化,越發顯示出其獨特性來。

程式設計師思維第一個,也是最顯著最根源的特征是: 一切程式設計師都是還原論者

沒錯,你完全可以說,「等等!我是程式設計師,但還原論是啥啊?」

嗯,你可以不知道什麽是還原論,但你仍然是個還原論者。

所謂還原論,指的是「世界一切復雜事物都可以約分到一系列較為簡單的子系統、再由簡單子系統約分到很少幾個簡單原理上」,並且「透過很簡單的幾條原理、若幹子系統的組合和交互作用,就可以分毫不差的精確模擬一個復雜系統」這樣一種信念。持有這種信念的,就叫還原論者。

很顯然,能夠計算一切可計算物的圖靈機就是最最典型的還原論機器。

如果你身為程式設計師卻不相信還原論、沒有拆分復雜事物的能力,那麽你一定會在這個行業活的非常非常的痛苦。

舉例來說,熟練掌握還原論,學習知識你可以只學核心邏輯;一旦學會後,隨便什麽新技術什麽新架構新原理,在你看來都是新瓶裝舊酒:程式設計師基礎掌握得好學新東西真的就快麽?

類似的,熟練掌握還原論,那麽一個外人看來非常非常麻煩的需求,在你看來就是一組核心計演算法則(比如傳統資料庫的核心就是關系代數)的一系列組合而已。於是在別人看來得喀喀喀喀出苦力敲出無數行程式碼的東西,在你看來,只需設定很少幾條「生成規則」,然後讓電腦執行這些規則,一切功能便自然湧現。

典型如生命遊戲(Game of Life)有哪些圖形? ,簡單的幾條規則就能得到無窮無盡的動態花樣。

當然,生命遊戲只是個最簡單最容易理解的例子,所以看起來毫無用處。我想說明的只是「其實程式設計師的工作中,需要的各種功能也可以用類似方式自動引出」——典型如現在如日中天的AI背後的神經網路。

顯然,如果一個人不相信、不理解還原論,甚至連個八音盒的原理他都理解不了,那麽他一定學的慢、寫程式碼出呆力、還老是弄出一大堆bug。這種人實際上是做不了程式設計師的。

這個特征會在程式設計師和普通人的交流中造成什麽影響呢?

喏,我的親身經歷:是不是真的有不適合編程的人?

普通人一般不會把「邏輯推理」當成「常規武器」使用,和程式設計師離開邏輯就沒法說話完全不同——還原論的還原可不是「背誦很簡單的幾句口訣」,而是「用這幾句口訣還原整個世界」。那麽這邏輯推理對他們,就必須吃飯喝水一樣自然。

於是,程式設計師和普通人說話時,很容易出現這種場景:

程式設計師:我都說這麽明白了你還不懂嗎?

普通人:這家夥為什麽非要把那麽簡單一句話翻來覆去說那麽多遍?!我早懂了能不能別說了咱換下個話題好不好?

比如我提到的那名女生,她很明顯就對「電腦會把你寫在文本裏的指令按從上到下的順序一條條執行一遍」毫無感覺。這句話太淺,所以呢?下一個需要我記憶的知識點是什麽?

但對程式設計師來說,這句話等於開天辟地懂嗎!

最簡單的,你們班有50個人,要把他們的名字每人一行的打印出來;而putchar一次只能打印一個字元,怎麽辦?

簡單,按順序putchar("李")然後putchar("四")再putchar一個回車,這不就是「一行一個名字」嗎?

對每個人名,重復這個動作50次,這不就是「五十個人的名字每人一行的打印出來」嗎?

「重復執行動作」被電腦語言專門支持,叫迴圈語句;那麽安排好迴圈,把人名一個個「餵」給這個東西,那麽頂多十行程式碼,這個任務不就完成了嗎?

你看,還原論者說出的「簡單常識」「抽象理論」,預設是可以被展開被執行被任意組合的;如果你想不到「我自己可以展開/組合/執行他說的東西」,那麽這些話將永不能被你理解。

我帶的那名女生要做的,其實比這個更簡單。但是她沒有這種還原論思想,我最終也沒能給她引匯出這個思想。所以她學再久都學不會編程。

並不僅僅涉及編程時會出現「有無真正理解還原論」的沖突。比如談論工程談論機械、談論股市談論政策、談論歷史事件談論文學作品……一切的一切,如果有還原論方面的理解,很容易就會「找出幾條基本原則然後代入模型開始推演」——你看,還原論思維模式貫穿始終。

那麽這時候,很容易出現這種情況:普通人/整體論者談論「斯德哥爾摩症候群」的種種表現;而還原論者則力圖仿照「囚徒困境」「膽小鬼賽局」構造出一個合理的賽局場景來,把「習得性無助」、「斯德哥爾摩症候群」的成因找出來。

如果不理解還原論,那麽你很容易發現,程式設計師們總喜歡不分場合的顯擺各學科的「入門知識」或者「極為抽象的怪異概念」——他們永遠糾結在很「淺薄」很「抽象」很「無趣」的入門知識上,永遠不肯和你正面面對「現實問題」。當你要求他們「談論問題」時,他們甚至可能很生氣的告訴你「什麽都沒搞懂談什麽談」、「我們談的就是這個問題,你確定你聽懂了?」

——當然,如果你理解了我的講解,那麽你大概就會明白:哦!這就是還原論者啊!他們不喜歡那些沒有由來的「高層論斷」,從最簡單最基礎最不可能錯的「基礎知識」開始、自己主動構建/推匯出「高級話題」,這才是他們的思維模式。

程式設計師思維的第二個特點是系統論。

系統論(科學名詞)_百度百科

系統論是研究系統的結構、特點、行為、動態、原則、規律以及系統間的聯系,並對其功能進行數學描述的新興學科。系統論的基本思想是把研究和處理的物件看作一個整體系統來對待。系統論的主要任務就是以系統為物件,從整體出發來研究系統整體和組成系統整體各要素的相互關系,從本質上說明其結構、功能、行為和動態,以把握系統整體,達到最優的目標。

如果是還原論是拆解,那麽系統論就是組裝——我猜很多哲學愛好者在看到我說程式設計師都是還原論者時,已經對他們有了一個判斷……

雖然說只要不是哲學學的走火入魔了,都不會覺得「還原論者都是些只見局部不見整體的渣渣」;但其他行業的還原論者,尤其是那些更容易為公眾所知的、純科學純數學純技術的研究者,他們都很容易造成這樣一種整體印象:所謂還原論者,就是只研究眼睛中的其中一種感光細胞裏面的其中一種化學物質、其他一切他都不管的「書呆子」……

但這個判斷並不全面。

軟體工程畢竟是一個工程學科。光會拆,你永遠都不可能拆出一輛整車來;同樣的,做工程,你必須會組裝——從最最基本的概念、標準化的各種零件/元件開始,設計一個合適的架構,把它們裝配到一起,得到讓客戶滿意的產品。

因此,任何合格的程式設計師,或多或少都有點系統論基礎——模組如何劃分?你打算傳什麽給我、能做到何種程度的保證?我需要回饋給你什麽?

如果這些都理解不了……

更進一步的,怎麽透過系統各部份采集的訊號,設計出合適的正負反饋機制,使得軟體系統可以「自適應」於工作環境?

這個東西繼續發展,就是「控制論」。

控制論_百度百科

研究動物(包括人類)和機器內部的控制與通訊的一般規律的學科,著重於研究過程中的數學關系。綜合研究各類系統的控制、資訊交換、反饋調節的科學,是跨及人類工程學、控制工程學、通訊工程學、電腦工程學、一般生理學、神經生理學、心理學、數學、邏輯學、社會學等眾多學科的交叉學科。 在控制論中,「控制」的定義是:為了「改善」某個或某些受控物件的功能或發展,需要獲得並使用資訊,以這種資訊為基礎而選出的、於該物件上的作用,就叫作控制。由此可見,控制的基礎是資訊,一切資訊傳遞都是為了控制,進而任何控制又都有賴於資訊反饋來實作。資訊反饋是控制論的一個極其重要的概念。通俗地說,資訊反饋就是指由控制系統把資訊輸送出去,又把其作用結果返送回來,並對資訊的再輸出發生影響,起到制約的作用,以達到預定的目的。

這個思維模式又容易帶來什麽影響呢?

1、精確清晰的描述

系統嘛,任何一個部份描述的稍有差異,都可能造成很復雜很嚴重的後果。

如果你描述遺漏了什麽,那麽系統中就會存在一個未知的「沖激」,這個「沖激」一定會引起一些莫名其妙的「響應」,甚至可能毀掉整個系統。

如果你的描述添加了什麽,那麽系統中就會存在一個不存在的「訊號」,針對這個訊號的一切準備不僅一定是無用功,還可能引入其他很多故障(或者因為依賴了這個不存在的訊號而無法完成功能)。

如果你的描述歪曲了什麽,那麽針對它設計的後續機制一定會做出錯誤的判斷、繼而引起復雜的連鎖反應……

因此,程式設計師無法容忍模棱兩可的含糊措辭(其實一切工程師都有類似的怪癖),也特別善於捕捉可能隱藏著重大問題的異常描述——畢竟每一句客戶說的吞吞吐吐的話後面,都可能藏著一大窩子驚喜。

2、根源

初入行的新人,在興高采烈的排除了舊系統的一個bug後,幾乎總是會遇到老員工的兜頭一盆冷水:「你確定找到根源了嗎?」

為什麽一定要找到根源呢?

因為軟體是一個系統。

一切bug,除了偶然的鍵入錯誤,一定是程式設計師思想認識上的錯誤造成的。這些錯誤在系統中傳遞,還會引發其他位置的異常;其他位置的異常繼續傳遞,繼續造成更多更詭異的異常……

如果你只是抓住了其中一個異常解決掉,那麽根本上的錯誤就被遮掩了,就更難抓到了。

同時,你的解決方案顯然也是基於錯誤的理解而設計的;它本身就很可能引起其它異常。

你在不相幹的地方修的越多,這個系統的健壯性就被破壞的越徹底。

除非你能證明這個修改僅僅是使得某個模組更健壯了、而且並不會隱藏上一級傳來的異常、而且沒有其他意想不到的side effect,否則寧可留著錯誤,直到你找到真正的根源。

這種思路,配合還原論,使得程式設計師在談論各種問題時,總是自覺不自覺的尋找「真正的根源」,而不是滿足於頭痛醫頭、腳痛醫腳。

不過,和普通人談論時,他會覺得你故作神秘。很簡單的事你幹嘛非要講那麽復雜?

3、隔離

基於追蹤根源、控制錯誤傳遞的思想,程式設計師會積極主動的隔離問題。

只有隔離了問題,才可以盡量在接近根源處解決問題。解決根源,才可以避免錯誤四處擴散到處破壞,把問題搞得越來越嚴重越來越不可解決。

因此,當討論系統A時,他們希望能把系統B徹底丟到一邊;而為了能夠把系統B丟到一邊,他們會把每個系統「封裝」進一個黑盒子裏,只關註它的輸入輸出。

——我們不要管系統B出錯怎麽辦,先把系統A搞好、制止錯誤的擴散;那些無法阻止的「真正的異常」可以羅列出來,將來在上層設計機制處理掉。

——好了,現在不要假設系統A壞了怎麽辦,我們把系統B搞好。自己做好自己的事,不要老拉扯別人!

盡量完成錯誤隔離,系統整體才能夠有序健康的實作我們的期望——就是真出錯了,也可以直接找到責任人,不至於來來回回踢皮球。

但這種「一個一個問題分別討論」的態度,很容易被普通人看成書呆子——哎呀它們明明是相互關聯的,你怎麽能一次只說一個?

4、混沌

只要開發維護過一些不太簡單的系統,程式設計師就會知道,「混沌」才是常態。

為了告誡新程式設計師們,避免他們把軟體工程想的太甜,業界還有一本極為著名的程式設計師必讀書叫做【人月神話】。

嗯,這本書並不是講嫦娥奔月的。

它說的是,不要以為一個計畫的進度可以用簡單的幾個人、多少月就能做完衡量,這只是個神話。

增加人手,未必能加快計畫進度;一個人兩個月能做完的,兩個人一個月未必能做完。沒有任何工具、方法可以徹底解決這個難題。

因此,對於復雜系統,一個經驗豐富的程式設計師一定不敢對你拍胸口;對於涉及大量人群的復雜事件,一個合格的程式設計師一定會想到「看似簡單的XX與XX的互動也可能衍生出很多問題」。

如果一個程式設計師看不出其中的復雜性,那麽他一定沒有做過有一定規模的系統。

需求階段的一個問題,流傳到總體設計階段就需要十倍的時間金錢精力投入才能解決;總體設計階段的一個問題,流傳到詳細設計階段,也需要十倍的時間金錢精力;詳細設計階段的問題,到了編碼階段,同樣會被放大一個數量級……

最終,需求階段的問題沒有解決,推啊推推到編碼階段,將來你就得準備千倍投入……

因此,要應付混沌問題,你必須盡量在初始階段就把事情做對——不需要多,但必須對。對了,將來才可能擴充;否則,初始階段遺留的某些問題,修復它可能比重新寫一遍的投入還大。

但和普通人談論時,他同樣會覺得你故作神秘。很簡單的事你幹嘛非要講那麽復雜?

5、控制論

面對復雜的系統,普通人會覺得一團亂麻:哎呀這怎麽可能理得清?你胡說我胡說大家都胡說而已……

但是,很多時候,控制論可以快刀斬亂麻:再復雜,歸根結底也不過是一個「沖激-響應」的問題。一個一個的把沖激輸入找出來,分別討論它的響應、分析它的因果,這不就理清楚了嗎?

「控制論」已經被很多學者用到了歷史研究等方面,它的確是一個極為犀利的武器。

混沌等於狀態遷移特別特別多、初始條件又極端敏感;但混沌並不等於不可分析。

而程式設計師的工作,恰恰就是找出任意復雜系統的關鍵點、透過幾條規則破解它。這個破解的捷徑,就是利用控制論方法理清系統每個局部的相互關系。

但這種思路則很容易被不明就裏者當作「頭腦簡單」,因為程式設計師總是只看得到一個原因;尤其搭配上「隔離」,就更顯得「簡陋」了。

問題是,「簡陋」的「隔離討論」並不是永遠隔離;分別討論完了(還原論)、再整合回去(系統論)不就把一切都說清楚了嗎?一切不都在那幾個公式/邏輯裏面嗎?綜合一下不會嗎?

嗯,說不定還真不會……

當然了,很少有人能把這些真正修煉到位。因為修煉不夠,把這些東西用成笑話的比比皆是(我就經常鬧各種笑話)。

對絕大多數人來說,只是因為這個環境的影響,從而在思想上打下了這方面的烙印而已——烙印究竟有多深刻,這當然是因人而異的。

但總的來說,程式設計師多半都受過這些思維方式的影響。這是這個職業本身的特點所決定的。