編程小白犯過的各種錯誤(譯文)
以前只是畫網頁界面,沒想過怎麼實現;現在拿著自己畫的界面寫代碼,進展極其緩慢,這才稍微理解」為什麼他們不這麼設計「了??。
學著寫代碼能加深對網頁設計的理解,嘗試將腦海中的構想落地的過程也很棒。以前有大神隊友幫忙,代碼學的不紮實,現在想入坑好好玩。
這篇文章戳中了我不少痛點,決定花點時間用中文歸納下,也能強迫我仔細看文章。
我目前只是寫靜態網頁,能用到第三點-第六點,更多內容我沒體會,所以沒怎麼歸納,強烈建議讀原文。
鏈接:The Mistakes I Made As a Beginner Programmer
作者按特定順序總結了自己學習編程以來的一系列錯誤:
1)沒計劃就開始寫代碼
高質量的代碼遵循如下流程:思考、研究、計劃、編寫、生效、調整(Think. Research. Plan. Write. Validate. Modify. ),需要時刻提醒自己養成這個習慣。
寫獨立的小應用時可能無所謂,但沒計劃對大項目有很大的消極影響。建議你想重構(refactor)代碼前,先數十秒;如果這行代碼沒測試過,數一百秒。
編程多數情況是:讀之前的代碼、研究需求、研究需求如何適應現有系統、計劃以小而可測試的步驟實現特徵。實際花在寫代碼上的時間,大概有10%。
編程不是寫代碼,而是一個基於邏輯、需要不斷迭代成熟的創造性過程。
2)寫代碼前計劃太多
沒有完美的計劃,找一個足夠好(能開始干)的計劃就行。
你需要做的計劃是:一直設想下幾個特徵應該怎麼做。編程應該是一個不斷反饋(responsive)的過程,你需要變得敏捷(agile)。
3)不理解代碼質量的重要性
如果你只能關注代碼某一方面的質量,那就是可讀性(readability),代碼是溝通工具,告訴別人你是如何將解決方案落地的。
可讀性要從小處著手,可通過格式化工具實現,比如
- 縮進(indentation)
- 大小寫(capitalization)
- 短句子(不要超過80個字母,否則太難讀),刪除不必要的代碼
- 不要在一個函數或文件的寫太多行代碼,對函數而言,可能超過10行的就太長了(只是經驗法則,a rule of thumb)
- 不要雙重否定
- 給變數一個描述性、非歧義的名字
- 當邏輯依賴於一個固定字元串或數值時,將字元串或數值賦給一個常量,起好名字
- 不要用草率的縮寫
- 不要過多用條件邏輯(conditional logic),大部分需求其實不需要。
4)挑選第一個方案
不要拿到一個方案就直接開始做,先質疑你找到的所有方案。如果你想不到多個解決方案,這可能意味著你沒有完全理解問題。
專業程序員的職責是找到一個最簡單的問題解決方案,這意味著代碼能正確執行且足夠簡單(可讀、可理解、可維護)。
5)死守第一個方案
編程中正確的心態是「簡單而頻繁的失敗」(fail early and fail often),當你質疑手頭的解決方案時,不論你已經投入了多少,將這個方案放一邊,重新思考問題。
6)不搜索
你想解決的問題,可能前人已經試著解決過了。先搜索,節省你的時間。
搜索後,你可能發現你的問題不是問題、你需要的不是你想的。
但注意避免搜索的另一個極端:直接復用而不理解代碼,決不要用你不能理解的代碼。
7)不封裝(encapsulation)
不大能體會作者寫的內容,可能因為我現在寫的代碼太簡單了。只能放著後面補。
8)為未知做計劃
不要意淫潛在需求(it is just wrong to use as a driver for potential needs),不要寫你今天不需要的代碼,以盡量少的代碼滿足你今天的解決方案需要。
要解決邊緣個案(edge-cases)而不是邊緣特徵(edge-features)
9)不使用正確的數據結構
除了了解演算法,記得多種數據結構的優缺點也有利於開發。比如:
- 存儲記錄時,使用maps(objects)而不是list(arrays)。
- 不使用堆棧
不大懂,先記在這兒。
10)讓已有的代碼更糟糕
整理物品時,往混亂的房間里加東西只會讓房間更混亂,正確做法是先把房間清理乾淨再放東西。同理,別在混亂的代碼上加東西,先理順代碼再說。常見的問題:
- 重複代碼
- 不使用配置文件
- 使用不必要的條件語句和臨時變數。作者舉了一個例子
function isOdd(number) { if (number % 2 === 1) { return true; } else { return false; }}
其實用這個就好(默默吐槽自己……我沒看出來??)
function isOdd(number) { return (number % 2 === 1);};
11)在顯而易見的事情上寫註解
大部分註解用一個命名清晰的變數就能替代。需要用註解的情況不是」這段代碼在幹什麼「,而是」這段代碼為什麼這麼寫「。
12)不寫測試
作者提到了自動測試和TTD(testing-driven development),不大能體會,保留。
13)認為代碼能通過就對了
即便代碼能通過,仍然存在很多問題。作者舉了如下例子:
const sumOddValues = (array) => { return array.reduce((accumulator, currentNumber) => { if (currentNumber % 2 === 1) { return accumulator + currentNumber; } return accumulator; });}; console.assert( sumOddValues([1, 2, 3, 4, 5]) === 9);
這個代碼能通過,但它沒考慮輸入為空、輸入不合法的問題,也沒有測試其他可能的情況,比如:
sumOddValues([2, 1, 3, 4, 5]) // => 11
14)不質疑已經存在的代碼
15)追求最好的實踐
沒有最好只有更好,對所有建議(包括這篇文章)保持開放態度。
16)糾結於表現
如果表現不能被有效測量,別去優化它,不然浪費時間。
17)不以終端用戶體驗為目標
想辦法讓這個特徵能為用戶所用,而不是工程上好實現(我:被灌輸過N遍的概念,不容易啊……)
18)沒為工作挑選一個好工具
少有工具能滿足所有需求,你需要多探索並與工具磨合。你可能用熟了一個工具,但工具優化無止境,你需要跟進,這可以是個漸進的過程。
19)沒有意識到代碼問題會導致數據問題
這部分看起來和後端有關,我暫時不care這個事,放著。
20)重新發明輪子
除非你真需要一個非典型設計的輪子,否則別重新發明一個。
21)以消極的態度看待評論
學習是終身的,每次評論和討論都是一次學習的機會,就醬。
22、23兩點完全沒體會,保留
22)Not Using Source Control
23)Over-Using Shared State
24)對錯誤保有錯誤態度
失敗是成功之母,把握學習機會,就醬。
25)不休息
做大量的短暫的休息(take a lot of short breaks),站起來走動下,想想看下一步幹啥,休息下眼睛
這篇文章這麼長你都看完了,可以給自己獎勵一小段時間休息一下。
推薦閱讀:
※v2ex帖子 教小朋友學c++問答整理
※以鶸ice為例,手擼一個解釋器(一)明確目標
※編程入門(一):Hello World!
※編程入門(五):編程開發工具這麼多,我該如何選擇?
※0基礎學Python之二十四:異常處理(上)