邏輯是個好東西

導讀:程式設計的必要知識,也是日常的基本能力。
作者:Crossin先生
來源:Crossin的程式設計教室(ID:crossincode)
“英語不好能不能學程式設計?”
“程式設計是不是對數學要求很高?”
翻譯一下就是:數學/英語是否是學程式設計先決條件?
我覺得這個問題有點像,身高不高能不能打籃球一樣。雖然對於職業籃球運動員來說,身高是非常關鍵的因素,但對於普通籃球愛好者,甚至一個籃球相關從業人員來說,這並不是非要不可的條件。放到程式設計上,數學和英語都很重要,但:
  1. 在入門階段,你完全不用在意這些,照著一本教程好好跟著模仿就行
  2. 對於大部分的日常開發來說,中學程度的數學和英語水平已經可以應付
  3. 和身高這種先天條件不同,英語和數學是可以透過學習提高的,哪裡不足補哪裡唄。網上流行一句話:“以大多數人的努力程度之低,根本輪不到拼天賦。”你能長期堅持背背單詞,看看書,就足以提升自己。總是把XX不好掛在嘴上恐怕更多是在給自己找藉口。
不過,有一項能力,確實是在學習程式設計初期就需要足夠重視的。然而這一點,很多教程不會專門強調,相關書籍也往往假定你已經掌握,以至於很多學習者並沒有意識到自己在此方面的薄弱,為之後的學習留下隱患。我要說的就是:
  • 邏輯
某種角度來說,邏輯可部分算作是數學,在高中數學課本中就有相關內容。這部分內容也恰好是我們學程式設計時最需要了解的基礎。
01 布林代數
真(1)、假(0)兩種狀態,以及與(and)、或(or)、非(not)三種基本運算組成。布林代數看似簡單,卻與數位電路中開和關兩種狀態相對應,是計算機的邏輯基礎。你可能聽說過,電腦上的一切在內部都是由0和1所表示,那換句話說,計算機的所有行為,本質都是由布林邏輯所實現的。
在程式語言中,布林型別(bool)也是極為重要的存在。沒有它,我們就做不了條件判斷,也就無從控制程式的執行。Python 的 if、while 語句都必須依賴布林型別作為判斷條件。
因此,即使你不想深入學習邏輯,布林代數的基本規則也是無論如何必須瞭解的。簡單來說,就是下面這張“真值表”
p
q
not p
p and q
p or q
1
1
0
1
1
0
1
1
0
1
1
0
0
0
1
0
0
1
0
0
這些基本規則又會組合出更復雜的邏輯,比如: 
not (p or q) 等價於 (not p) and (not q)
(示例:“不是管理員或者會員”相當於“不是管理員且不是會員”)
實際開發中面臨的邏輯判斷複雜多樣,但歸根結底還是會轉化到最基本的這幾個規則上。
思考題1:如何用邏輯語言表示“透過活動註冊的新使用者或者充值超過100元的老使用者,內部人員除外”
02 命題邏輯
真值唯一的陳述句叫做命題,不能分解成更簡單的命題叫做原子命題。比如,“1+1=2”是原子命題,“所有貓都是白的”是原子命題(假命題),“存在外星人”也是原子命題(雖不能判斷真假,但結果必然唯一)。命題和邏輯運算相結合,又會產生更復雜的邏輯。
比如充分必要條件
如果命題p必然推出命題q,那麼p就是q的充分條件,q就是p的必要條件,記作 p→q。
比如漢樂府的詩句“山無稜,天地合,乃敢與君絕”,用邏輯語言表達是怎樣?
(山無稜 and 天地合) → 與君絕?
想一想是不是不大對勁?根據語義來看,“山無稜”、“天地合”是“與君絕”的必要條件,如果“與君絕”為真,那必然存在“山無稜”和“天地合”,反過來卻未必。所以正確的邏輯是:
與君絕 → (山無稜 and 天地合)
再比如三段論
①不掌握基本的邏輯知識就無法學好程式設計
②Python是一種程式語言
所以,學好Python需要掌握基本的邏輯知識
一個大前提加上一個小前提,可以推匯出一個結論。這是日常使用最多的論證形式,看似簡單,但也總有人在這上面犯糊塗。舉個錯誤的例子:
①有錢人都用 iPhone XS Max
②我用 iPhone XS Max
所以,我是有錢人
這些邏輯關係、推導過程與程式中的邏輯結構息息相關。如果你對此不能保持思路清晰,寫出的程式碼很可能與預期有出入,或是在一些特殊情況下存在漏洞。
思考題2:一個每天簽到領獎的小功能,在每天的11~13點和18~20點開放,普通使用者每天可以領取一次,會員使用者可以在每個時段分別領取一次。如何實現這段程式的邏輯結構?(我時常拿這個作為面試題,很多人都不能在短時間內給出正確的答案)
03 歸納
有時候,我們並不能透過邏輯推匯出必然的結論,但仍然可以透過一系列的經驗和已有結論,找出其中基本遵循的規律。
比如:
①X團隊歷來給所有成員都配備Dell筆記本作為工作電腦
②C老師最近剛加入X團隊
透過這兩點,我們可以推匯出,C老師很可能也使用Dell筆記本。
但你要清楚歸納的結論並不必然為真,如果遇到邏輯推理出的必然反例,即使再不符合常理,歸納的結論也會被推翻。
比如除了上述兩點,我們還知道:
③C老師簽約了蘋果公司代言
④蘋果公司的代言人不得使用其他品牌的手機和筆記本
那麼,上述“C老師使用Dell筆記本”的結論便不成立。
雖然歸納不是必然,但在解決問題時依然重要。尤其在開發中遇到錯誤需要 debug(除錯)的時候,並不是所有錯誤都可以直接從報錯資訊看出問題(比如 Python 開發時經常出現的亂碼問題),這時如果有豐富的經驗和較強的歸納能力,效率會大大提升。這也是資深程式設計師和初級程式設計師之間差距的重要體現。
現在網上的程式設計教程鋪天蓋地,不過呢,大家都喜歡寫寫怎麼編個爬蟲抓圖片、抓資料之類,卻很少有文章願意講講背後的思維過程。寫了讀者也不願意看,因為看不出什麼效果,哪有調幾個函式就出結果來得爽快。
以至於你發現,照著例子也能寫個一樣的程式碼出來,但是一旦報錯或者沒有預期的結果,就完全抓瞎了,只能把引數東改改西改改,反覆執行,期待某一次奇蹟出現。以後換個新的問題,依然不知道從何下手。
這就是因為並未理解程式背後的邏輯。我常在答疑群裡說:遇到程式出錯了不要去猜!要去做假設,再透過輸出驗證假設,最終定位問題所在。
文字只是一個引子,不可能讓你對邏輯融會貫通。但前面講的那些邏輯基礎,任何一本《離散數學》或者《邏輯學》的書上都有,而且僅僅是最開始的一小部分就很受用了。找一本來看一看。
真想好好學程式設計,不要只侷限於讀網上的教程,這些都是別人嚼爛喂到你嘴裡的。如果你只能接受這樣二次加工過的知識,而沒有自己咀嚼的過程,那麼你學習上的乳牙永遠都掉不了。
瞭解邏輯學和思維具有邏輯性並不完全等價。有人沒學過邏輯,說話做事一樣很有邏輯性,而有的人雖然學過邏輯,也不過是當做數學公式在背,整天“邏輯思維”掛嘴邊不代表做事就講邏輯。
在網路上,你經常可以看到一些邏輯謬誤,舉幾個常見的例子:
  • 以偏概全:你說用X產品遇到了Y問題。有人就反駁說,我也用X產品,我身邊人也用X產品,都沒有問題,所以你一定是故意黑。
  • 關聯當因果:某地區的人喜歡喝生牛乳,同時該地區人平均壽命高於周邊地區,所以喝生牛乳可以延年益壽。
  • 非黑即白:網上都在抨擊某個產品竊聽使用者聊天,並且之前也有發垃圾廣告的前科。你說竊聽從技術上來說不現實,目前也缺少明確證據。然後就有人認為你不一起噴,你就是水軍、洗地。
  • ……
類似的不講邏輯充斥著網路。
我們的周圍有很多偏見、歧視的觀念,還有很多喜歡爭論的“槓精”,歸根結底,你會發現這些人都有一個共同的特徵:邏輯混亂。比如,之所有有人會有性別歧視、地域歧視,就是因為以偏概全地由一些特例而對整體作出推論。而偷換概念、顛倒因果、動機揣測,更是槓精們喜歡濫用的邏輯謬誤。
不僅僅是在程式設計上,如果我們更講究邏輯,這個世界的矛盾就會少很多。即使沒經過專門的學習和訓練,只要保持謙遜,學會傾聽,以包容的心態對待不同的聲音,多去思考一下對方的觀點,從不同的角度看問題,你的邏輯就會更完備。
感謝轉發和點讚的各位~
延伸閱讀👇
延伸閱讀《因果論:模型、推理和推斷》
乾貨直達👇
更多精彩👇
在公眾號對話方塊輸入以下關鍵詞
檢視更多優質內容!
讀書 | 書單 | 乾貨|講明白|神操作 | 手把手
大資料 | 雲計算 | 資料庫 | Python | 爬蟲 | 視覺化
AI | 人工智慧 | 機器學習 | 深度學習 | NLP
5G|中臺 | 使用者畫像數學 | 演算法 數字孿生
據統計,99%的大咖都關注了這個公眾號
👇

相關文章