華文網

10年程式設計路上的幸酸苦累,寫代碼容易,程式設計並不容易

當我的程式設計生涯開始的時候,我認為“程式設計很簡單……怎麼會需要去學校學習呢?”但經過學習和實踐,我瞭解到程式設計很難。

自我評價對我自己來說一直都很重要,因為在一天結束的時候,不管別人怎麼想,自己的想法都很重要。我會在評價中思考強項、弱項、學習、訓練和個人成長。這個過程讓我反思、理解並思考成為一個程式師究竟意味著什麼。在分享的同時我自己也推薦一個學C/C++的學習群496926338無論你是大牛還是小白,

是想轉行還是想入行都可以來瞭解一起進步一起學習!群內有很多乾貨和技術分享!

教育:編碼?程式設計?關鍵性的抨擊?

我在技術領域的第一份工作主要是通過 HTML、CSS 和 JavaScript 操作一些元素並創建視覺效果。在這段時間裡,我沒有真正想到自己是一個程式師,對於這個問題,我從來沒有想要成為一個真正的程式師。不久以後我想使用 NodeJS、PHP 和 MySQL 做更多事情,這時候我開始考慮這個問題。

把我作為程式師的所有宏偉想法加起在一起,我在第一份工作中把自己當作一個小小的“軟體工程師”,一直都在積極地制定方案。

“經驗告訴我,我會頗具氣勢地拍、打和敲擊鍵盤,但那並不是程式設計。”

程式設計需要思考和理解各種資料類型、結構,並理解程式設計語言賴以構建服務的技術。差異主要在於完成特定任務時所使用的流程。重點不在於資料類型、設計模式、演算法類型、性能或任何與代碼和應用程式品質相關的內容。

相反,它被納入了實際的工作機制和技藝之中,這往往需要耗費大量的時間,最終變成一隻難以維護的巨獸。一直運行輸出到不同地方,並積極地測試輸出,直到它非常類似於一個功能。如果有什麼事情給我一種程式設計的感覺,但我在實際操作中並沒有做到將想法付諸行動。

思考資料

資料結構是我感受到教育不足的一個方面。

資料結構背後的想法是,你有不同的方法去存儲、提取、排序和搜索資料。最初當我開始程式設計,我從來沒有想過各種資料的任務與資料類型的性能。對需要存儲、排序或遍歷的任何事物,通常預設使用陣列(包括雜湊、json、字典,以及鍵-值資料集的其他術語)。

從電腦科學的角度看,集合、堆疊和佇列對我來說是很有趣的,但在 Ruby 程式設計語言中看到一些實際操作之後,

對我來說並不那麼吸引人。在我看來,堆疊和佇列是一樣的,它們允許你從資料的末端獲取資訊,佇列的例外情況是,你只能按照它們加入的順序獲得這些項。當我開始想像這一點時,我想把東西放在一個列表中,等待處理,減少可在後臺運行的任務的開銷。事實上在高層次的程式設計語言如 Ruby 中對此付諸實踐,並沒有多大意義,因為它基本上是在往陣列中 push(後追加)或 unshift(前添加)元素。

比如,Ruby 中的棧可以像下面的代碼一樣簡單。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

class Stack

# init stack

def initialize

= Array.new()

end

# put a new item at the end of the stack

def push(x)

.push x

end

# get the last item in the stack

def grab

.pop

end

# is the set empty true false bool

def empty?

.empty?

end

end

# implemented stack

s = Stack.new

putss.grab# "c"

putss.grab# "b"

putss.grab# "a"

s.grab.inspect# nil

佇列和上面創建的資料類型基本上是一樣的,Ruby 已經有一個類了。

1

2

3

4

5

6

7

8

9

10

# ruby Queue Class

q=Queue.new

q<<'a'

q<<'b'

# Tests Examples using Queue

putsq.length# prints 2

putsq.pop# prints a

putsq.length# prints 1

putsq.pop# prints b

putsq.length#prints 0

它的簡單性是基於一個非常簡單的陣列,這本身就體現了它的美。我看到自己在命令列腳本中使用棧或佇列,但我不確定還可以在別的什麼地方使用它們。

二叉搜尋樹在處理搜索資料的時間和速度上吸引了我。我經常發現從資料中獲取資料非常容易,但在陣列中搜索需要花大量時間。這就是為什麼需要二叉搜尋樹,我非常喜歡哈佛的這段視頻。雖然我並沒有使用這些東西來做過什麼,但是非常想用它們來實現點東西,然後將之與原生 Ruby 的陣列方法進行比較,看看二叉樹比普通的陣列或雜湊快多少。我在關於二叉權勢的研究中試圖找到實際的用例,於是發現了這些有意思的文章。

可維護性

我的第一個 Web 應用在可維護性方面可笑極了。沒有編碼規範,沒有設計模式,沒有對定義的方法進行整理,沒有使用命名空間,也沒有物件和模型。如果一定要我去修復缺陷(肯定會有),與其去找實際導致缺陷的方法,還不如重寫來得快些。

設計拙劣導致亂糟糟的代碼。

我難以處理的問題之一是條件嵌套和迴圈嵌套。這些迴圈中存在大量的 if 語句和驗證,但這個問題本身來源於一個系統性的問題,即不清楚怎樣恰當地組織和拆分程式的不同部分。我曾嘗試著在一個巨大的方法中處理所有事情,不關心哪些代碼可以重用,也沒創建一個模組來擴展物件和方法的功能。為了節省篇幅,下面的代碼截取自真實的代碼。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

print"

Display Weekdays:

";

// Looping in a view ... should have been factored diff

foreach($imageRecords["display"]as$=>$displayRecords){

// WTF is this a nested foreach

foreach($displayRecords as$value=>$dispRecord){

$tempWeekdayValuesArray=array();

if($value==="weekdays"&&!isnull($dispRecord)){

// 3rd nested foreach WTF!

foreach($dispRecord as$weekday=>$weekbool){

// :( condition foreach day ::SHAME::

if($weekday=="monday"&&$weekbool==1){

// logic removed

}

}

}

}

}

我不會把責任推到別人身上,這段壞代碼是我寫的,我會承認這一點,然而其中一些本來可以通過代碼導師、或者通過代碼審查和“拉”請求來加以緩解。回顧這段代碼,我感到慚愧,但這是一件好事,因為它表明了我作為一個開發人員的成長程度。自由在某些意義上是一個問題,但不是在其他方面。例如,對這個項目我被限制於使用 LAMP 技術棧,這是不容協商的,但與此同時,這真的是唯一的限制。我沒有使用設計模式,遵循任何風格指南, 使用代碼分析器,或遵循代碼公約的任何政策。這就創建了一個系統,你可以自由地使用自己的設備,並且如果你還沒有瞭解應用程式的長期性和錯誤修復,那麼它會損害你的最終結果。

我已經真正體會到了文字編輯器的好處,在你編寫代碼時它會給出提示(指出潛在的錯誤)從而為你節省很多時間,同時我也開始欣賞與程式設計相關的一些美好細節。一個寫得很好的代碼庫,會遵循文檔標準、清晰的約定和風格指南,閱讀起來就像一封電子郵件或一篇網文那樣流暢。(當然,有時候使用的程式設計語言本身就更好)總地來說,我也發現我很喜歡這本書中的許多原則, Robert C。 Martin 和其他作者的《敏捷軟體匠人的整潔代碼手冊》 。

測試驅動開發

在我看來,測試驅動開發的好處足以證明其優點,但我明白,並不是每個人都同意測試為代碼庫提供任何價值。我不會爭論測試的有效性,但我確實想分享它如何幫到我。在實際創建代碼之前,為代碼編寫集成測試和單元測試已經在很多方面幫到我。它幫助我編寫更整潔的代碼,高效地編寫代碼,並幫助我解決了我遇到麻煩的問題。

編寫更整潔、更高效的代碼與程式設計中的許多事情有交叉。可讀性、性能和編碼時間是 TDD 幫到我的主要方面。我發現我能編寫代碼,不必重構(多次)使其可以上生產線或進入版本控制庫。它不僅幫助我減少了 bug,而且幫助我減少了跟蹤和修復 bug 所花費的時間。修復 bug 時,我發現我可以接受預期的輸入或輸出,編寫一個與之匹配的測試,然後努力使該測試和所有其他測試通過。這樣可以消除 bug,並確保代碼實現其預期的目的。

在分享的同時我自己也推薦一個學C/C++的學習群496926338無論你是大牛還是小白,是想轉行還是想入行都可以來瞭解一起進步一起學習!群內有很多乾貨和技術分享!

在開始編寫實際的方法或物件之前,TDD 可以説明我組織思路。在更複雜的功能中,它可以幫助我將功能分解成其需要正常工作的集。也就是說,邊界條件就是邊界條件,並且在最初創建代碼時往往更難於考慮到邊界情況。最終我覺得測試驅動開發有助於使我成為更好的程式師。

比如,Ruby 中的棧可以像下面的代碼一樣簡單。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

class Stack

# init stack

def initialize

= Array.new()

end

# put a new item at the end of the stack

def push(x)

.push x

end

# get the last item in the stack

def grab

.pop

end

# is the set empty true false bool

def empty?

.empty?

end

end

# implemented stack

s = Stack.new

putss.grab# "c"

putss.grab# "b"

putss.grab# "a"

s.grab.inspect# nil

佇列和上面創建的資料類型基本上是一樣的,Ruby 已經有一個類了。

1

2

3

4

5

6

7

8

9

10

# ruby Queue Class

q=Queue.new

q<<'a'

q<<'b'

# Tests Examples using Queue

putsq.length# prints 2

putsq.pop# prints a

putsq.length# prints 1

putsq.pop# prints b

putsq.length#prints 0

它的簡單性是基於一個非常簡單的陣列,這本身就體現了它的美。我看到自己在命令列腳本中使用棧或佇列,但我不確定還可以在別的什麼地方使用它們。

二叉搜尋樹在處理搜索資料的時間和速度上吸引了我。我經常發現從資料中獲取資料非常容易,但在陣列中搜索需要花大量時間。這就是為什麼需要二叉搜尋樹,我非常喜歡哈佛的這段視頻。雖然我並沒有使用這些東西來做過什麼,但是非常想用它們來實現點東西,然後將之與原生 Ruby 的陣列方法進行比較,看看二叉樹比普通的陣列或雜湊快多少。我在關於二叉權勢的研究中試圖找到實際的用例,於是發現了這些有意思的文章。

可維護性

我的第一個 Web 應用在可維護性方面可笑極了。沒有編碼規範,沒有設計模式,沒有對定義的方法進行整理,沒有使用命名空間,也沒有物件和模型。如果一定要我去修復缺陷(肯定會有),與其去找實際導致缺陷的方法,還不如重寫來得快些。

設計拙劣導致亂糟糟的代碼。

我難以處理的問題之一是條件嵌套和迴圈嵌套。這些迴圈中存在大量的 if 語句和驗證,但這個問題本身來源於一個系統性的問題,即不清楚怎樣恰當地組織和拆分程式的不同部分。我曾嘗試著在一個巨大的方法中處理所有事情,不關心哪些代碼可以重用,也沒創建一個模組來擴展物件和方法的功能。為了節省篇幅,下面的代碼截取自真實的代碼。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

print"

Display Weekdays:

";

// Looping in a view ... should have been factored diff

foreach($imageRecords["display"]as$=>$displayRecords){

// WTF is this a nested foreach

foreach($displayRecords as$value=>$dispRecord){

$tempWeekdayValuesArray=array();

if($value==="weekdays"&&!isnull($dispRecord)){

// 3rd nested foreach WTF!

foreach($dispRecord as$weekday=>$weekbool){

// :( condition foreach day ::SHAME::

if($weekday=="monday"&&$weekbool==1){

// logic removed

}

}

}

}

}

我不會把責任推到別人身上,這段壞代碼是我寫的,我會承認這一點,然而其中一些本來可以通過代碼導師、或者通過代碼審查和“拉”請求來加以緩解。回顧這段代碼,我感到慚愧,但這是一件好事,因為它表明了我作為一個開發人員的成長程度。自由在某些意義上是一個問題,但不是在其他方面。例如,對這個項目我被限制於使用 LAMP 技術棧,這是不容協商的,但與此同時,這真的是唯一的限制。我沒有使用設計模式,遵循任何風格指南, 使用代碼分析器,或遵循代碼公約的任何政策。這就創建了一個系統,你可以自由地使用自己的設備,並且如果你還沒有瞭解應用程式的長期性和錯誤修復,那麼它會損害你的最終結果。

我已經真正體會到了文字編輯器的好處,在你編寫代碼時它會給出提示(指出潛在的錯誤)從而為你節省很多時間,同時我也開始欣賞與程式設計相關的一些美好細節。一個寫得很好的代碼庫,會遵循文檔標準、清晰的約定和風格指南,閱讀起來就像一封電子郵件或一篇網文那樣流暢。(當然,有時候使用的程式設計語言本身就更好)總地來說,我也發現我很喜歡這本書中的許多原則, Robert C。 Martin 和其他作者的《敏捷軟體匠人的整潔代碼手冊》 。

測試驅動開發

在我看來,測試驅動開發的好處足以證明其優點,但我明白,並不是每個人都同意測試為代碼庫提供任何價值。我不會爭論測試的有效性,但我確實想分享它如何幫到我。在實際創建代碼之前,為代碼編寫集成測試和單元測試已經在很多方面幫到我。它幫助我編寫更整潔的代碼,高效地編寫代碼,並幫助我解決了我遇到麻煩的問題。

編寫更整潔、更高效的代碼與程式設計中的許多事情有交叉。可讀性、性能和編碼時間是 TDD 幫到我的主要方面。我發現我能編寫代碼,不必重構(多次)使其可以上生產線或進入版本控制庫。它不僅幫助我減少了 bug,而且幫助我減少了跟蹤和修復 bug 所花費的時間。修復 bug 時,我發現我可以接受預期的輸入或輸出,編寫一個與之匹配的測試,然後努力使該測試和所有其他測試通過。這樣可以消除 bug,並確保代碼實現其預期的目的。

在分享的同時我自己也推薦一個學C/C++的學習群496926338無論你是大牛還是小白,是想轉行還是想入行都可以來瞭解一起進步一起學習!群內有很多乾貨和技術分享!

在開始編寫實際的方法或物件之前,TDD 可以説明我組織思路。在更複雜的功能中,它可以幫助我將功能分解成其需要正常工作的集。也就是說,邊界條件就是邊界條件,並且在最初創建代碼時往往更難於考慮到邊界情況。最終我覺得測試驅動開發有助於使我成為更好的程式師。