有哪些新手程序員不知道的小技巧?

相關問題:

有哪些新手程序猿不知道的大殺技?


我有一個學習的小技巧,就是學習新技術的時候,多看看「官方文檔」。


多年來的學習和工作經歷,讓我比較深刻認識到一點:看「官方文檔」非常重要


我們很多的問題和技術細節,其實,只要我們認真將官方文檔過一遍,會發覺大部分的問題和認識模糊的地方都消失了。甚至,你還能發現自己之前通過搜索獲得的到一些資料,可能是不準確或者已經過時的。官方文檔是真正的好東西,因為編寫文檔的人群,通常就是這些技術或者軟體的開發者,他們才是對這些東西最了解的人,因此,他們寫的文檔質量是很高的,通常也是最新的。

官方文檔的不足的地方,大概是中文版本不多,看起來可能會比較吃力。不過,請相信我,下載一個翻譯輔助軟體,慢慢看還是可以的。另一方面,就是這些文檔編寫者,通常是技術界大牛,他們編寫文檔有時候是基於他們自己的技術認知水平,跳過了很多基礎概念,也增加了閱讀難度。不過,這個我們也可以通過多查資料,慢慢看來解決,並且通常會帶來額外的學習收穫。


老鳥和新手的一個很大區別來自於debug的能力。其中最主要又可以從兩方面看出來:
1. 從高層往底層找錯。
2. 科學方法。

很多新手遇到程序執行結果不對(尤其是圖形程序員),先認為是機器毛病(浮點精度、硬體故障),然後認為是驅動有錯,再認為是系統有錯,最後才開始排查自己的程序。其實99%的情況下是自己程序有錯,然後那1%裡面的99%是系統有bug,再接著那1%里的99%是驅動有bug,最後到硬體問題,已經微乎其微了。應該從高層往底層查,而不是反過來。

debug一般來說是知道現象,但原因未知。這一點和很多自然科學的情況一樣,所以完全也可以用科學的方法來:提假說-&>根據假說做出預言-&>做實驗肯定或否定預言。對應於debug,那就是假設是某個地方有問題,那麼推斷它一定會導致除了你看到的現象之外的其他現象,運行程序看你的推斷是否成立。掌握這個方法後debug不在變成瞎找瞎試,而是有跡可循有系統可依賴的方法。


@叛逆者 的debug技能說的非常好。針對其中「科學方法」一部分補充一下。原答案見此:為什麼 C++ 只比 VBA 快 4倍? - grapeot 的回答
當時遇到的問題是一段C++程序速度非常慢。對於這樣的情況,我們需要用科學的方法和適當的工具來找到問題的原因,而不是亂猜問題在哪裡,隨便改。具體地說,我們用了以下的方法:

我首先在VS2013, Release模式下面跑了一下C++代碼,時間是208ms。基本重現了C++部分的結果。這個速度的確不能算快。在我們推測具體原因以前,一定一定要先profile,看看每一行所花費的時間是多少(不成熟的優化是萬惡之源)。在VS里這個非常簡單(要求VS Ultimate,但一般訂閱了MSDN AA的學校都有免費的VS Ultimate)。只要點一個按鈕就好了,如下圖所示。

出來的結果類似:

我們可以看到,如 @姚冬 所說,rand()佔用了56.3%的時間,是性能的瓶頸。此外,整數的減法也佔用了33.4%的時間。

知道了原因以後就好辦了。第一步,放狗搜索c++ slow rand。出來一大坨結果。其中一個是
Need a fast random generator for c++
裡面提供了一個快速的rand()實現。把代碼粘進去。

unsigned int g_seed = 0;
unsigned int fastrand() {
g_seed = (214013 * g_seed + 2531011);
return (g_seed &>&> 16) 0x7FFF;
}

瞬間提速1倍到了99ms,結果不變。再profile得到:

一個詭異的地方是這是個整數運算應該極其快,而且不應該有類型轉換在裡面。但是profiler說50%的時間都在float到long的類型轉換上面(注意圖片右上角)。進一步檢查發現,rand_max怎麼是double。改成int,結果不變,時間變成43ms,進一步提速2倍。再profile得到:

這時候我們可以看到時間非常平均,也沒有明顯瓶頸了。優化結束。
考慮到我們機器的不同,我的43ms大約相當於你的機器的31ms,相比於vba的570ms有了18倍的性能差異,感覺還是比較合理的。

幾點討論:

  • 其實在這個回答里,核心並不是程序優化的具體技巧,而是拿到一個問題如何思考和利用工具的通用方法。比如即使我們不知道profiler這個東西,通過搜索"代碼 每一行 時間"也可以很快知道有這樣的工具叫做profiler,並且學會怎麼使用。即使不知道rand這個函數怎麼加速,通過搜索引擎也可以找到別人寫好的現成代碼。另一方面是發現瓶頸之後也不要著急自己修復,如果不是特別一目了然的話,先看看別人是怎麼做的。站在巨人的肩膀上,事半功倍。所以關鍵在於時刻知道自己想要的是什麼,和分析-調研-實驗的思維習慣。
  • 具體關於程序優化,我們絕大多數人沒有 @姚冬 那麼牛的經驗,一眼就能看出問題在哪裡。所以遇到性能問題,第一反應應當是用profiler看看瓶頸到底在哪。而且一個經驗是這個瓶頸往往是很難猜的——比如這個例子直接看代碼第一反應往往是用代數和工程方法去優化算半徑的那部分。但就算這部分做到極致,rand速度提不上去,最多也只能把時間降到原來的一半,事倍功半。以前我寫代碼也會在寫的時候用各種奇技淫巧提升速度,但後來發現總體上程序的速度並沒有得到提升。因為程序80%的時間其實花在20%的代碼里,剩下80%的代碼就算花個兩個月優化到速度無窮快,也還是白瞎。所以一個兼顧開發和運行效率的方法是,先怎麼方便開發怎麼寫,然後用profiler找到瓶頸再有針對性地優化。
  • 前兩點不僅可以節省時間,可能更重要的是,如果你面對的不僅是一個工程,而且是老闆,你要說服老闆你這麼做的原因。這些profile的結果、別人的討論、你自己的實驗結果,都會1) 說服老闆你這麼做是對的,2) 給老闆留下深刻印象:你幹了很多事,腦子清楚。以後升遷啥的都有幫助。
  • 不懂的問題上知乎問!這也是非常重要的一部分。
  • 上面用的是Windows平台的VS,方便好用但也非常貴。如果是Linux平台下可以用gprof(不曉得有沒有GUI版本的,望指教)。Mac下可以用XCode。但基本思路都是一樣的。

本來只是分享幾條看法,沒想到會有這麼多人喜歡。我再補充一些,希望能對進階中的程序朋友有幫助。手機敲得,比較凌亂。作為個人意見僅供參考。

1.重構是程序員的主力技能。

2.工作日誌能提升腦容量。

3.先用profiler調查,才有臉談優化。

4.注釋貴精不貴多。杜絕大姨媽般的「例注」。漫山遍野的碎碎念注釋,實際就是背景噪音。

5.普通程序員+google=超級程序員。

6.單元測試總是合算的。

7.不要先寫框架再寫實現。最好反過來,從原型中提煉框架。

8.代碼結構清晰,其它問題都不算事兒。

9.好的項目作風硬派,一鍵測試,一鍵發布,一鍵部署; 爛的項目生性猥瑣,口口相傳,不立文字,神神秘秘。

10.編碼不要畏懼變化,要擁抱變化。

11.常充電。程序員只有一種死法:土死的。

12. 編程之事,隔離是方向,起名是關鍵,測試是主角,調試是補充,版本控制是後悔葯。

13. 一行代碼一個兵。形成建制才能有戰鬥力。單位規模不宜過大,千人班,萬人排易成萬人坑。

14. 重構/優化/修復Bug,同時只能作一件。

15. 簡單模塊注意封裝,複雜模塊注意分層。

16. 人腦性能有限,整潔勝於雜亂。讀不懂的代碼,嘗試整理下格式; 不好用的介面,嘗試重新封裝下。

17. 迭代速度決定工作強度。想多快好省,就從簡化開發流程,加快迭代速度開始。

18. 忘掉優化寫代碼。過早優化等同惡意破壞;忘掉代碼作優化。優化要基於性能測試,而不是糾結於字裡行間。

19. 最好的工具是紙筆;其次好的是markdown。

20. leader問任務時間,若答不上來,可能是任務拆分還不夠細。

21. 寧可多算一周,不可少估一天。過於「樂觀」容易讓boss受驚嚇。

22. 最有用的語言是English。其次的可能是Python。

23. 百聞不如一見。畫出結果,一目了然。調試耗時將大大縮短。

24. 資源、代碼應一道受版本管理。資源匹配錯誤遠比代碼匹配錯誤更難排查。

25. 不要基於想像開發, 要基於原型開發。原型的價值是快速驗證想法,幫大家節省時間。

26. 序列化首選明文文本 。諸如二進位、混淆、加密、壓縮等等有需要時再加。

27. 編譯器永遠比你懂微觀優化。只能向它不擅長的方向努力。

28. 不要定過大、過遠、過細的計劃。即使定了也沒有用。

29. 至少半數時間將花在集成上。時間,時間,時間總是不夠。

30. 與主流意見/方法/風格/習慣相悖時,先檢討自己最可靠。

31. 出現bug主動查,不管是不是你的。這能讓你業務能力猛漲、個人形象飆升; 如果你的bug被別人揪出來.....呵呵,那你會很被動~≧﹏≦

32. 不知怎麼選技術書時就挑薄的。起碼不會太貴,且你能看完。

33. git是最棒的。簡單,可靠,免費。

34. 僅對「可預測的非理性」拋斷言。

35. Log要寫時間與分類。並且要能重定向輸出。

36. 注釋是稍差的文檔。更好的是清晰的命名。讓代碼講自己的故事。

37. 造輪子是很好的鍛煉方法。前提是你見過別的輪子。

38. code review最好以小組/結對的形式。對業務有一定了解,建議會更有價值(但不絕對)。而且不會成為負擔。管理員個人review則很容易成team的瓶頸。

39. 提問前先做調研。問不到點上既被鄙視,又浪費自己的時間。

40. 永遠別小看程序媛(╯3╰)


1. 東西交付之前偷偷測試一遍;
2. 問別人之前偷偷谷歌一下;
3. 版本發布之前反覆檢查七八遍,用check-list,多想想老婆孩子,恩;
4. 用谷歌,用英文搜索;
5. 做十件事不如做好一件事,奪取話語權只有一條路徑,就是超出別人的預期;
6. 心要皮實,但話語和臉皮要柔軟,記住有句老話叫,伸手不打笑臉人。
7. 先假裝你就是專家,慢慢為了裝得像,不得不去學,假的就成真了。

更多精彩內容,歡迎關注微信公眾號「極客思享」(codingcoffee)


說點其他的。
當你面對一個新的功能或者需求的時候,80%的可能人家已經做過。50%的可能有人開源。90%的可能不好用,缺少文檔。代碼有問題。或者不適合。所以你需要的是要看懂源碼,能對其代碼做出評估。即這代碼自己能不能改。問題能不能解決。才能決定用不用開源項目

有人說官方文檔很重要。比官方文檔更重要的是源代碼。看源代碼:
一:意味著你可以看到以及學習優秀的代碼。
二:意味著即使源代碼有坑,你也會提前在大腦有迴路更容易找到問題所在。

看不懂源碼意味著不同的幾點:
1.你對這個庫或者代碼的功能不熟悉
(知道某段源碼的功能及特點)。
2.你不會用Debug。
3.你的演算法基礎薄弱
4.源碼太過混亂。

你需要反思自己屬於哪一項。針對其中某一類下藥


上來直接從頭看源碼學東西一般是不可行的。
你需要從上層入侵到下層。先用這段代碼才能看懂源碼。而不是在上層都不熟悉的基礎上開始。

任何重複的代碼/重複的類似代碼。意味著你框架設計有問題,或者開發語言的表達能力不夠。Java的固定設計模式就是Java本身表達能力不夠的表現。

流程意味著生命周期,即你不僅需要抽象已知的流程。還需要在未提及的點留下一個坑(函數/介面/鉤子)。往往這些坑在以後的需求變更和項目擴展和維護中是救命的點。

日誌非常重要,日誌環境也非常重要,debug是基礎技能,對應的是開發狀態。日誌則對應穩定的線上狀態。 而不能重現的bug占整個開發的非常多的時間。所以錯誤日誌記錄詳細的環境意味著你可以更快的重現這個錯誤。

不要習慣於固定的工具和固定的語言和固定的解決辦法。
團隊的架構師或者lead其中很大一部分不是因為代碼寫的好和規範。而是因為:
1.確保團隊能完成開發。
2.在所有的技術中找到最適合團隊使用的。
這兩點要求你使用過很多框架,工具和技術。意味著你可以從眾多的可選項中找到最優的解。

技術崇拜是個很LOW的行為。技術和人是分開的。唯一有關聯的是高手可以很快掌握新技術。而不是我使用了新技術我就是高手。抱團是不對的。

Stackoverflow解決不了的需要自己去Github提Issue。Issue沒人理或者項目需要用郵件列表或者Irc的時候,那就只能自求多福了。


說點程序外的:
你們需要理解和抽象這個世界。所以才能抽象需求和項目。然後才能抽象到代碼。
這意味著。
不僅僅是數學。數學是構造這個世界。而歷史或者哲學是抽象這個世界。
沒有不變的需求意味著沒有不變的社會。項目的設計和框架的搭建也同樣意味著你看到的這個世界的脈絡。
(這部分是玄學。需要自己體會。)


版本管理工具是你最好的拐杖。代碼要早提交,勤提交,越勤越好,只要改進一點點(哪怕只是改了一行代碼,甚至只是改了注釋中的拼寫錯誤),測試通過了,立馬提交。沒有提交的代碼就等於沒寫。

調試的要點在於代碼孤立和隔離——每次只修改一處代碼;因為如果同時改動多處代碼,你不知道到底是哪個改動造成了關鍵性的變化。勤提交可以幫你很好地做代碼隔離。老手的做法是改一點,不成功,立即在版本管理里放棄當前改動,回滾到上一個提交的版本,然後再改;但新手會在本地版本里改,不提交,不行了再手動改回來。但靠記憶手動改回常常有問題,比如新聲明的變數忘了去掉,或者改錯了,或者偷懶乾脆不改回,繼續改其他部分。這樣改動越積越多,越搞越沒頭緒,最後往往得整個放棄從頭再來(如果之前的新功能代碼也沒有提交的話,可能會一起搞砸,效率更低)。還有一種情況是瞎貓碰到死老鼠,改七改八能運行了,但之後發現其它工作的部分又出問題了,於是再去拆東牆補西牆。其實解決方案很簡單:勤提交。一旦不行,立即回滾。

勤提交的好處除了回滾方便以外,還有利於快速自我代碼審查——在提交之前瞟一眼diff,勤提交改動小,許多顯而易見的錯誤,或者一些垃圾改動,比如增加了空白行,沒有用到的聲明變數等等容易被看到,此時就可以把這些改動放棄,有利於避免代碼質量劣化。

----

P.S. 關於提交的頻率,新功能/BUG修復的提交單位是branch而不是commit。對應的,團隊代碼審核(如果有的話)的基本單位也是branch PULL request而不是單個commit。那些認為只有完成了一個新功能或者修復了一整個bug才能commit的,本座建議你重新審視一下自己作為程序員的基本素養。 Git Workflows and Tutorials

----

Q:公司還在用SVN怎麼辦?
A:趕快換到GIT。

Q:想用GIT但做不了主怎麼辦?
A:忍著。

Q:GIT本地完整拷貝太大了,硬碟裝不下怎麼辦?
A:買2T的硬碟。
Q:買不起怎麼辦?
A:500塊的硬碟都買不起你做毛的開發?


1. devops中任何一個環節,無論是別人如何告訴你可行,都需要自己真實驗證過,至少需要在開發環境和測試環境全部跑通過,這是新手易犯的第一個問題,過於信任上下游。
2. 測試告訴你測過的時候,最好去review下測試過程,如果是自動化測試,必須看看代碼(我現在會選擇自己來完成一部分自動化測試代碼),有時候你會發現測試沒理解需求寫錯了測試場景,而你又沒自測,這是新手易犯的第二個錯,過於信任合作夥伴。
3. 性能監控和異常行為監控,往往新人對這個都完全沒概念,無論系統寫的有多健壯,異常是不能避免的,新人的程序總是要等待用戶反饋來發現異常,這是新手易犯的第三個錯誤,對自己的程序過於自信。
4. 缺乏對全局的看法,被上下游牽著鼻子走,在需求交流溝通會陷入被動,去做一些不符合全局利益,但是可以讓上下游獲得好處的需求,最後讓自己的架構失去兼容性,背上沉重的歷史包袱,這是新手易犯的錯誤之四

解決的技巧也很多:
1. 不符合kpi的需求不接,一個資深碼農是懂得刷選需求的
2. 一定要搞好監控和異常主動發現,監控不是那種讓sa看看的花架子,資深碼農懂得如何刷選監控中的有效信息並指導bug主動修復
3. 對上下游做到代碼級別掌握,這樣在甩鍋上可以立於不敗之地,再牛逼點的,可以做到指導上下游開發的方向,讓上下游來配合自己完成開發目標
4. 搞好自動化測試和集成測試,很多老鳥的自動化測試寫的非常有才,場景覆蓋全,業務分析清晰,看一份牛逼的代碼,推薦從集成測試和自動測試入手


本文只提供給新手程序員閱讀。

多年前的一個 IBM 的老鳥曾經教過我一個 5 分鐘上手的思維習慣,當我聽到以後,醍醐灌頂,驚人天人,一改日常的編碼風格。到現在,它還持續保持在我的日常的編碼習慣當中。

我不知道應該怎麼稱呼這種思維習慣的名字,top-down,自頂而下,或者分治?不管怎麼樣,它的核心是非常清晰的:編碼的時候只思考同一個思維層次的邏輯,在這層完成之後再思考下一層。

它基於這麼一個事實:我們每個人智力是有限的,同一個時間只能思考有限內容的東西,我們都不是天才。由於這個事實的存在,所以程序 bug 就會存在(廢話)。因此,思考問題的時候(編碼)不要跨抽象層級思考,在我們有限的智力裡面現保證這個層級的邏輯正確,再思考下一個。什麼叫跨抽象層級思考,什麼叫同一個抽象層級的思考。我們通過一個例子來看看,假設現在我要編寫程序打車去上班。

首先穿衣服,然後洗臉刷牙上廁所,然後下樓打車。

這句話就算是一個三歲的人都能說出來。上面的描述是在同一個思維層次,把「打車上班」這個事情分成了幾個符合順序和操作邏輯的模塊和動作,我的大腦能夠承載這些邏輯,這一套邏輯下來就能夠把這件事情完成。於是我把它寫下來:

function goWorkByCar () {
dressUp()
wash()
goDownstairs()
goByCar()
}

這個抽象層次的東西已經完成了,我看這個函數就知道這個操作的順序和邏輯是什麼,甚至還不用注釋。我們有四個函數都是沒有完成的,它們的具體實現就是下一個抽象層次的東西。我們現在下到下一層,看看 `dressUp`。現在我的注意力已經不在打車上班這件事情上了,這一層的邏輯已經完成了。我的注意力在怎麼穿衣服這件事情上:

從柜子里把衣服拿出來,先穿上半身,再穿下半身。

符合正常的操作,不錯:

function dressUp () {
const clothes = takeClothesFromWardrobe()
dress(clothes.up)
dress(clothes.down)
}

我們看看洗漱怎麼做:

上廁所,刷牙,洗臉

function wash () {
urine()
brushTeeth()
washFace()
}

下樓呢?

我要先出門,然後鎖門,然後坐電梯。

function goDownstairs () {
openDoorAndOut()
lockTheDoor()
takeTheLift()
}

打車呢?

用手機打車,然後坐車走人

function goByCar () {
const car = callACarByPhone()
takeTheCar(car)
}

...然後再用這種方式實現像 `brushTeeth` 和 `washFace` 具體的實現,想想它們需要什麼操作。

你會發現我們不停地在填函數,函數裡面又不停地出現新的函數需要我們去完成。每個函數體裡面的操作都和這個函數所要完成的目的相關,在一個函數裡面,我們只關心這個函數需要完成的目標所需要操作。例如「打車上班」這個任務所依託的 goWorkByCar,我們在這裡並不關心怎麼刷牙,因為它是下一層的東西,我們只關注完成「打車上班」這個目標需要哪幾步。如果我們刷牙、開門這些操作都放在這個函數裡面,那麼一開始就會陷入無限的細節當中而失去了主要目的的關注,而且大腦也無法承載如此複雜多端的細節,處理不好就很容易出現 bug

而這種思維方式可以讓我們不停地把一個大的任務在同一個層級做分解,保證這一層的步驟和邏輯正確以後,然後再下一層分解,最後其實是一個樹狀的結構,樹的葉子結點才是具體的代碼演算法實現。在編碼的時候,我只用我有限的腦力關注當前層級的任務,不關註上一層也不關注下一層的細節。

這樣的代碼寫出來不僅 bug 少,邏輯清晰而且還很輕鬆,因為你每一層思考的東西其實都很簡單,不知不覺就把代碼寫完了。為什麼很多人覺得編程很難,因為你接到一個「打車上班」的任務以後就開始腦子裡面就填滿了刷牙打車穿衣服這種不成邏輯和順序的任務,並且都把它寫到一個函數裡面去。

接到任務以後你可以像上面一樣用人類語言描述一下如果你要解決這個任務,你需要什麼步驟。這些步驟才是這一層任務的關注點。例如跟女朋友看電影:你要先看看有什麼好電影,然後再約女朋友,再買票。

UPDATE:有朋友說這裡第一步應該先找女朋友,同意!!必須同意!全身同意!每個細胞都同意!)

當你寫一行代碼的時候可以經常看看你的函數名,你這行代碼和你的函數名所代表任務的是不是同一個邏輯層次的東西,不是的話,把它分出去。

有空再寫寫。


  • 不審慎的"重用"容易成為代碼中最頭疼的"耦合"
  • 對邏輯錯誤做"容錯"會錯上加錯,低概率的不可預期的異常不如不處理直接拋出來
  • 語言或者工具的高級特性並非一定要用在自己的項目中,使用高級特性並不能使你更 senior

把覺得不靠譜的需求放到最後做。

很可能到時候需求就變了。


並不存在這樣的東西,我現在懂的東西當年從零學編程起就一直懂,幾本經典書都講爛了,怎麼可能不懂呢?

我最初學習時候的代碼風格規範和現在的代碼風格規範幾乎一致,因為第一本 c 語言書上就寫了這樣做的重要性。

我在不同時期看過 4 遍《代碼大全》,從最初的大略懂點到後來的能識別很多過時或錯誤。
但是最初看的時候,書中的要點我一直牢記於心,比如建議的變數名長度是 8 - 20 個字元(基於 60 年代的統計,當然了,本身也是很偏頗的啦……)、熬夜的是業餘玩票愛好者、注釋和文檔、測試、code review、提高見識……
很長的列表,就不一一註明了。

我最初就知道「優化」基本就是學生過家家,人命比電腦值錢、有問題再找瓶頸什麼的……

我從一開始就知道 debug 要用理智,不能發泄情緒,也不能胡亂修改,直接就應該讀代碼、找錯誤、修正、測試。

我從一開始就知道什麼是正確的、什麼是錯誤的、工具的重要性。

我從很多本不同的書上讀到了很多相似的思想和原則,其實很多本經典書裡面講的東西都大致差不多,可能是換一點點角度和解釋方式,原則是通用的。不過這也導致了我看到一些書的時候相見恨晚,因為我已經用變態的方法學會了裡面的東西了……

什麼估時間 * 5 啊、項目進度管理啊、真正的工程啊之類的,《人月神話》說得很好,我當時想了一遍,基本就接受了。當然,後來也能看出很多書上過時、錯漏的內容了。

普通人是被本能驅動的,學習、做事的時候,要是事先學習加多過腦,就不會沒事大驚小怪三天兩頭來個驚呼了……

— 記者:專家有什麼秘方是新手不知道的嗎?
— 蕭井陌:「並沒有,專家們已經寫在書上了,你所需要做的就是思考相信並遵從」


需求來了,切莫急著編碼;
不明確不清晰的需求不要急著寫,很可能最後不需要寫;
先搭架子,後寫實現,架子是思路,想不清細節可以先放個函數名在那裡;
疲憊或者感覺自己腦子不夠用,或者進了死胡同,就回家睡覺,不要死磕;
讀好書,垃圾書會浪費你時間;
功夫在業餘時間,業餘時間多學習;
效率不高的時候,不要死撐,出去玩,低效的努力不過是欺騙自己;
多陪孩子和家人。


不要忽略編譯器的警告內容( -?_-? )

注意文檔備份以及實時更新(? ̄? ??  ̄??)

想清楚了再做,偽代碼先行? ?(?ˉ???ˉ???)?」

該問的的一定要問???????

問過了一定要記住|?ω?`)

要做好個人筆記???( ˙ ? ˙ )???

UT和AT還是有必要的(?????????)?

每天抽出點時間學習或複習(??? ?? ???)

多了解幾種語言,對接時會輕鬆許多,視野也會寬闊?ω?

多鍛煉身體 └(o)┐

必應谷歌大法好,哪裡不會點哪裡 (??? ???)

延期不可怕可怕的是一直延期( ′?ω?)?(._.`)

看書先看目錄了解大概( ??? .? ??? )?

很多東西純靠代碼優化是不靠譜的(っ??╭╮??)っ

早點找女朋友??????u

不要老是加班,會笨的??? ?? ˙? ?? ???

不要只知道怎麼用就滿足了,要知道怎麼實現的???(?σ????? ?σ????)·??

多看看別人的代碼,從代碼能看出一個程序猿的內心呢 ∑(O_O;)

git推薦還是用命令行?(? ??)

日誌最起碼得具有方便查詢和記錄有效數據這倆吧(lll¬ω¬)

保持平和心態,學會拒絕(/"≡ _ ≡)/~┴┴

別用中英混合命名,別用縮寫命名,別#define true false( ?????_????? )

過段時間就去審視一下自己以前的代碼(?( ˙??˙? )?)??????

重構要一步一步來,不要過度重載=(=`д′=)?

設計模式重點是看思想,不要生搬硬套 (?`н′?)

不要炫技,編寫面向人腦編程的便於維護的代碼(? ?д?)&<

debug很艱難,寫代碼時盡量實時人腦編譯運行ε (?&> ? &<) з

輪子雖好,請不要重複造呦o(*////▽////*)q

================昏割線==============

現在忙,等會詳細補充一些?_?


隨便寫點

  1. 一個好的頂層設計比什麼都重要,比勤奮重要,比搜github和stackoverflow的能力重要
  2. 好的頂層設計是你用一句話就能說清楚,並且沒有修改餘地和疑點的那種。有的時候它正確的就像一句廢話。
  3. 設計一個系統的時候從最困難的地方做起,而不是通過「這裡調用其他系統的API來實現」來將問題無限後推
  4. 雖然設計要一開始就想好頂層,但實現要從底層開始一層一層往上搭,底層不要跟頂層設計有關係,那是輪子。學會用和改別人的輪子或者自己設計一個適合你的輪子。
  5. 扔掉你去年的經驗去用新技術,經驗永遠是過時的,只有道理不變。
  6. 讓只會調API的人滾蛋,或者至少從參與設計的組裡滾蛋。帶著他們那些設計出來的奇怪API一起。如果你真的搞明白了你的模塊提供了什麼功能,你自然知道它應該是什麼樣的介面。
  7. 堅持你的設計,不要輕易妥協。除非你發現設計錯了。
  8. 如果你因為新需求重構了你的系統,你TM一定是沒有做好第1條。

每個程序員從員變猿的過程都足夠寫一本幾十萬字的血淚史,小慕這邊的一個講師就曾經說過:每次熬幾個通宵敲代碼的時候就覺得自己是小仙男,全靠一口仙氣吊著。等熬過了這段時間,就覺得自己像吃了十斤豬肝一樣心明眼亮,馬上就要飛升成為修仙界的大佬……嗯,聽起來還是蠻心酸的……所以小慕在這裡簡單總結兩方面的技巧分享一下,希望能夠助大家少走彎路,早日渡劫成功。

【專業技巧】

1. 規劃

新手程序員往往剛拿到需求就會開始coding,實際上這樣並不高效。當拿到需求的時候,一定要以上帝視角考慮程序的整體結構,整個系統要分成哪幾個層次,有哪些模塊,每個模塊的功能的實現,模塊之間如何銜接,甚至需要哪些函數的變數,這些都要盡量在coding之前想好。就像上帝為眾神分配任務一樣,上層分配規劃完成後再逐個施工,這樣方能事半功倍。

2. 借鑒和修改代碼

事必躬親,用到的東西都自己寫,這樣真的就是敬業嗎?實際上,直接去借鑒相應的代碼是一個非常高效的手段。現在網路上可以找到很多經典的代碼,只需要稍微修改就可以拿過來用,而且經典的代碼由於經過很多人優化,可靠性會比自己寫的更高。正所謂:高級程序員=普通程序員+Google。

3. 認真注釋

當你在寫某個程序的時候,可能自己記得很清楚,這一段是什麼機制如何實現,但是寫的程序越來越多,會導致你想不起來當初為什麼這樣寫,改動和交接也十分麻煩。而對代碼進行注釋就可以有效避免這種情況。注釋不僅可以讓人讀懂代碼,甚至能讓讀代碼的人獲取更多信息,不信你看:

(這就是公司得罪程序員的下場哼)

4. 形成自己的變數命名規則

定義變數在寫程序中非常常見,一個程序可能用到成千上萬的變數,這些變數之間又有著錯綜複雜的聯繫。很明顯狗剩、鐵蛋、二妮、i、j這些名字是遠遠不夠的,不論是內部變數還是全局變數,都要形成自己的一種命名規則,能夠一眼看明白變數的意思。

另外,還要盡量減少重名變數和容易混淆的變數名,如果變數定義出現問題,會容易讓人產生疑惑。所以只有養成良好的變數命名習慣,才能有效避免這類問題。

5. 認真對待編譯中的warning

新手程序員往往重視error忽視warning,覺得warning不影響編譯執行。當你的程序規模到了一定程度,這些warning可能就會讓你的程序出現匪夷所思的問題,到時候哭都找不到地方。所以一定不要忽略warning,對於每個warning一定要思考為什麼會出現,如何才能消滅,然後修改程序幹掉這個warning。

6. 看文檔、博客要多版本對照

看文檔和博客要注意多版本對照,很多對你有價值的信息可能就藏在一篇初看覺得很難理解的文檔中。

你:這文檔並無卵用o(╯□╰)o。

文檔:哼活該你學不到o(╯□╰)o

所以你要多看一些文檔相互印證,然後去猜作者的用意。

7. Regexper等正則表達式可視化工具

如果數據分析妹紙來找你幫忙寫正則表達式,可以用這個把正則表達式的編寫可視化……不僅是為了概率極小的「打動芳心」效果,更重要的是降低溝通成本,節約雙方時間,這將在時間緊迫的時候為程序員帶來極大便利。

8. 寫無副作用的函數

把文件讀寫和業務邏輯分開,保證業務邏輯相關的函數輸入什麼,就能得到什麼。如果得到的東西有錯誤,那麼就可以反求諸己,從輸入內容找到問題。

9. 利用代碼自動生成工具

比如java有maven插件mybatis-generator-maven-plugin……就可以直接自動生成DAO。

【職業技巧】

1. 入職前了解加不加班

2. deadline是老手的,而不是你的

老闆:「你是新來的小王吧,這裡有一個重要的任務……時間緊任務重……」這種時候,如果你忙不過來就早請示晚彙報——這個時候還會有人記得你是新手程序猿。畢竟以後就變成這樣,老闆:「你是剛來的老王吧,這裡有一個重要的任務……時間緊任務重……」

3. 教會產品經理使用搜索引擎

產品經理:你是新來的小王吧,老李讓我來問問你這個功能能不能做blabla……反正你是新手,也解釋不清楚,這個時候最好總結一下他的關鍵詞然後讓他百度。如果這是一位勤奮好學的產品經理,以後就會省掉很多麻煩。

4. 當一個企業說自己開源的東西有多好的時候……

要麼這個東西所應對的業務對你所在的小公司來說根本遙不可及,要麼就是進階版還要繼續花錢。

5. 技不如人Do not panic

技不如人Do not panic,是因為:恐慌不能解決任何問題。在承認自己和大神存在差距的同時,儘力去努力縮短它們就好,不要有太多負擔。

以上就是小慕為新手程序員整理的小技巧,當然適用與否還是要看大家自己的決定和判斷~雖然程序員在網上一直被調侃,但是其中很多人是懷抱著喜愛的態度在「高級黑」,小慕就已經在以往回答的評論中看到好多妹子喜歡程序員了呢!所以,如果你已經進入了這個行業,不妨好好利用這些小技巧,提升自己的工作能力,還是那句話,麵包和老婆都會有的~


1. 程序不等於數據結構加演算法,而等於搜索引擎加英語。
2. 技術群是萌新的搜索引擎,同時也是老鳥的效率陷阱。很奇怪,喜愛社交的手藝人技術總是不咋地。
3. 遇到匪夷所思的Bug時,不要信邪,錯誤一定出在你自己身上。要堅信,引擎、類庫以及語言本身,就像你的女友或老婆一樣,永遠正確。同樣,所謂「運行效率低」也是一樣。
4. 推薦一本技術書:《邏輯學導論》。
5. 魅力低的人能力總是被低估,團隊中不善言辭以及長得丑的人值得留意。反之也成立,「你長得真好看」,「你給人的感覺很不錯」,可以作為「你丫技術真爛」的委婉說辭。
6. 同事罵策劃或產品傻逼,自己跟著罵罵就得了,千萬別真的那麼想,否則會降低你的可合作性。可合作性是項很重要的能力。
7. 《設計模式》、《人月神話》、《人件》、《我的編程感悟》等業內知名度很高的書,其實沒什麼卵用,但依然推薦閱讀,可以用來和同行聊天時裝逼。尤其是和寫Java的程序員聊設計模式,能把人給唬跪了。但不要和用C系列語言的程序員聊這個。
8. 自動識別是IDE的標配,因此匈牙利命名法除了降低編碼效率之外沒什麼別的好處。除非你用記事本敲代碼,你長得真好看,你牛逼。
9. iOS開發真的是……非常簡單,連初中小孩都學得會。招人難只不過因為Mac電腦普及率低。推薦給不明前途的新人。
10. 新人如果面試iOS,記得花一小時把斯坦福大學的某節有關MVC的公開課看明白,面試時候使勁講。對面主程草包一點的話,沒準會覺得醍醐灌頂,終於找到了之前遇到的一些奇葩問題的根源。
11. 有一種傻逼,總是嫌棄別人造的輪子不夠圓,非要自己親手造個方輪子。這種傻逼到處都是。以現成的類庫坑多為由不用,非要自己寫,不過是避開了現有的坑,轉而親手挖坑親自跳。
12. H5真的沒什麼前途,那概念是用來忽悠傻錢的,始作俑者是李開復大大。新人可別被坑了。
13. cocos真是好啊!大家都快去用!Unity真垃圾!一大堆坑而且閉源沒法改!千萬別用!做遊戲的都快去用cocos去!觸控靠譜!cocos大法好!都別用Unity嗯。都別用才好。
14. 翻譯官方文檔是通向「業界大拿」的捷徑。
15. 以極客自居的,多為極品。
16. 語言之間的隔閡,不過是要花一周熟悉下語法。勤奮點三天就夠了。技術是技術,語言是語言,一門技術可以跨多門語言,程序員以技術分,而非以語言分。只有外行和新人才混為一談。當然有不少寫了多年程序依然停留在語法層面的老新人也分不清這個。


講一個我自己的經驗……

提高生產力的平台不應該以生產力作為唯一的維度。

這話說起來有點拗口,簡單的來說就是提高生產力的方法有很多種,但是對於平台層面的設計開發而言,不能「只」看重生產力。

原因其實很簡單,人本身是參差不齊的。隨著 team 的規模越來越大,平台所扮演的角色應該是能保證最差的那個人也能保證一定的生產力而不至於拖整個 team 的後退,產生所謂的短板效應。

換句話說,如果我的 team 各個都是1個打100個放到阿里都是P10,都是三體人思維透明,還不會跳槽我壓根連平台都不用搞,完全靠純手工操作和高效的編碼也會有很高的生產力。但事實上你根本做不到這點,別說思維行動統一了,新人入職怎麼辦,培養體系怎麼搞,一線二線甚至三線四線研發力量怎麼弄。

所以編碼的時候,雖然有些細節看上去很牛逼很爽,比如 python 經常一句話就寫完了,但只有你懂,對於你來說是提升了生產力,但對於整個 team 而言就是負反饋了。一個 team 要有 20% 人的打江山,那還要有 80% 的人能守得住哇,所以這種就是不可取的。況且你是老闆你出得起全是 20% 那種人的工錢么……

再比如在設計的時候,現在都用 docker 容器什麼的鏡像是吧,latest tag 是可以減少很多 Dockerfile 的改動,是一種偷懶的方法,對於老鳥程序員來說就是提高了生產力。但同樣的 latest 會導致新人不知道當前的這個 base 是從哪個準確的版本過來的。一味的跟著最新萬一線上出現某些 bug,或者新手經驗不足導致用法上的偏差,這時候你想 debug 排除 base 的難度就很高了。雖然看上去生產力是提高了,但相應的也提高了 team 的管理成本,這些就是需要權衡的。

當然啦,這些都是平台開發設計中的一個點而已,還有諸如穩定性,設備可靠性,要不要帶狀態,都是需要考慮的。只有能規模化生產的生產力才有意義,在此之前我覺得追求單一個方面的生產力極致並沒有什麼卵用。


阿里云云棲社區,彙集阿里技術精粹,點此關注

這40條編程小技巧和注意事項送給各位小夥伴

有哪些老鳥程序員知道而新手不知道的小技巧?自我感受-博客-雲棲社區-阿里雲

1.重構是程序員的主力技能

是的,我之前經常也提到一點,就是好多設計模式不是提前就設計出來的,而是重構出來的。很多情況是我們在做設計的時候考慮不到的,是寫代碼時也考慮不到的,只有在項目上線後,客戶使用過程中才會反應出來,這個時候就需要對項目進行擴展,版本升級,這時就體現老程序員實力的時候了,就是根據已有的情形,結合新的客戶需求,使用合適的設計模式,使得代碼能夠優雅的擴展。

2.工作日誌能提升腦容量

這個我沒有什麼體會,我平時也寫工作日誌,但是那是項目工作的需要,不是我本人的主觀意願。不過我個人覺得技術博客能夠提升腦容量才是真的。很多項目中遇到的問題,解決了,也許以後還會再次遇到,也許別人也會遇到,那麼就寫成博客,自我總結,方便以後自己或者其他程序員遇到同樣的問題。

3.先用profiler調查,才有臉談優化

是的,我之前也專門做過SQL Server的性能優化,很有體會,Profiler是第一步。如果做.net代碼的優化,也有對應的Profiler工具,這個可以幫我們快速的定位瓶頸在哪裡。找到了瓶頸才有接下來的優化工作。
4.注釋貴精不貴多。杜絕大姨媽般的「例注」。漫山遍野的碎碎念注釋,實際就是背景噪音。

我不是很同意這個說法,還有更極端的觀點是不需要注釋,命名就是注釋,好的命名就能注釋一切。我覺得好的命名那是必須的,但是在複雜的邏輯中,我們有必要在代碼中注釋我們的思路,為什麼會用這樣一種寫法。

5.普通程序員+google=超級程序員

確實,很多不懂的,解決不了的就Google吧,一般Google會告訴你,Stackoverflow知道答案。

6.單元測試總是合算的

這個觀點我贊同,也許對於很多程序員來說,單元測試就是浪費時間,但是當項目複雜了以後,真的很需要單元測試,尤其是在不斷的hotfix和版本升級的過程中。

7.不要先寫框架再寫實現。最好反過來,從原型中提煉框架

這個就是我前面第一點提到的一樣,很多框架設計好了,但是不一定適應當前這個項目,那就是畫蛇添足。

8.代碼結構清晰,其它問題都不算事兒

這個就是編碼規範的問題,代碼寫的漂亮,讓Debug沒那麼痛苦,讓別人Review你的代碼也沒那麼痛苦。

9.好的項目作風硬派,一鍵測試,一鍵發布,一鍵部署; 爛的項目生性猥瑣,口口相傳,不立文字,神神秘秘

這個也是我最近在研究的CI(持續集成),適應TeamCity可以把測試,發布,部署都自動化搞定。

10.編碼不要畏懼變化,要擁抱變化

基於介面的編程,我們只關注介面,實現嘛,隨時可以變。

11.常充電。程序員只有一種死法:土死的

好吧,程序員的命就是這樣,技術變化太快了。

12. 編程之事,隔離是方向,起名是關鍵,測試是主角,調試是補充,版本控制是後悔葯

面向介面,控制反轉與依賴注入,都是編寫複雜的軟體的必備良藥。測試,調試,沒啥可說的,必備。版本控制,那是必須的!即使是只有一個開發人員的項目,也需要版本控制。

13. 一行代碼一個兵。形成等建制才能有效指揮。單位規模不宜過大。千人班,萬人排,容易變成萬人坑

這裡說的一個關於函數的規範問題,有一種說法是一個函數的內容不應該超過7行,如果超過7行,那麼肯定是把多個Function合併到一個函數中的,應該拆分成多個函數。這個要求可能有點高,很難做到。不過上百行,上千行的函數那是不應該的,必須拆分!

14. 重構/優化/修復Bug,同時只能作一件

這個我還是有點體會的,把多個目標合併到一次修改中,那是多麼困難的事情,真的不好做。最好是分開,先重構,保證重構後的功能和原來的功能一致,然後再Fix Bug。

15. 簡單模塊注意封裝,複雜模塊注意分層

面向對象編程基本要點,封裝,企業應用架構的基礎就是分層。最經典的三層架構做企業應用的應該都知道。

16. 人腦性能有限,整潔勝於雜亂。讀不懂的代碼,嘗試整理下格式; 不好用的介面,嘗試重新封裝下

還是說到編碼規範的問題,簡潔易懂,介面要清晰。

17. 迭代速度決定工作強度。想多快好省,簡化開發流程,加快迭代速度

軟體工程中的快速迭代,敏捷開發,涉及到前面提到的持續集成。

18. 忘掉優化寫代碼,忘掉代碼作優化。因為過早優化,往往事倍功半; 不通過全局性能度量,優化也難有建樹

不是很認同,有經驗的程序員,在寫代碼時採用的就是最優的演算法,最好的查詢方式。沒有什麼忘掉優化寫代碼的事情,在寫代碼時,想到的就是最優的演算法,因為在他看來就這種演算法才是對的。

19. 最好的工具是紙筆;其次好的是markdown

紙和筆只適用於在Face 2 Face的交流過程中,交流後頂多拍照留存,根本無法建立有效的知識庫,以後想到之前的討論,怎麼檢索?怎麼修改?。寫Wiki才是王道,Markdown只是一種寫Wiki的方式罷了。

20. leader問你任務時間,你答不上來。很可能是任務拆分不夠細。細分到沒有疑問吧

應該是的,如果不知道任務時間,那麼說明要麼你根本不懂這個任務怎麼做,完全不會,要麼就是任務太大了,不好估計時間。

21. 寧可多算一周,不可少估一天。別總因為你的「樂觀」而boss受驚嚇

是啊。程序員在估計工時的時候總是太樂觀。隨便開口就是一個小時就能搞定,半天就能做完。完全沒有想到該修改對其他模塊的影響。一個修改後的單元測試,可接受測試,UAT環境測試,再到上線,很多地方都得花時間的。一旦某個測試不通過,然後又得調試,修改,再進行單元測試,可接受測試~~~~,好吧,誰能保證每次修改都是一次通過呢。

22. 最有用的語言是English。其次的可能是Python

好吧,我英語不好,Python更不懂。我不評論。

23. 百聞不如一見。畫出結果,調試耗時將急劇縮短

沒懂這裡在說什麼。

24. 資源、代碼應一道受版本管理。資源匹配錯誤遠比代碼匹配錯誤更難排查

這個應該是這樣。在項目文件夾中,有很多個子文件夾,其中一個文件夾叫src,那裡存放的才是代碼,那麼其他的文件夾呢?就可能存放相關的設計啊、測試啊、工具之類的。

25. 不要基於想像開發, 要基於原型開發。原型的價值是快速驗證想法,幫大家節省時間

恩,是啊,最好是先畫出原型。有了原型才方便討論,明確需求。

26. 序列化首選明文文本 。諸如二進位、混淆、加密、壓縮等等有需要時再加

應該是吧,比如Json是比較好的序列化選項。

27. 編譯器永遠比你懂微觀優化。只能向它不擅長的方向努力

有了好的設計和演算法,誰關係編譯器內部怎麼做的。

28. 不要定過大、過遠、過細的計劃。即使定了也沒有用

過大過遠的目標還是可以定吧,規劃一下下一個版本的Roadmap,也許還沒有開始做,但是願景可以建立。只是經常會有計劃趕不上變化的情況,所以遠期的計劃不需要太詳細,反正也會不斷變。

29. 至少半數時間將花在集成上

這得看做什麼項目了吧,很多項目就是一個完全獨立的孤島,沒啥好集成的。最近的基礎可能就是單點登錄的集成,太簡單花不了多少時間。另外常見的是HR系統的員工數據的集成還有財務系統的財務數據集成,確實很花時間。

30. 與主流意見/方法/風格/習慣相悖時,先檢討自己最可靠

沒啥說的。

31. 出現bug主動查,不管是不是你的。這能讓你業務能力猛漲、個人形象飆升; 如果你的bug被別人就出來,那你會很被動~≧﹏≦

查Bug是也很難的事情,自己做的項目,自己再支持運維一段時間,看看自己的代碼寫的有多爛,有多難修改,多難調試。真的可以讓自己能力提升很多。

32. 不知怎麼選技術書時就挑薄的。起碼不會太貴,且你能看完

我很懶,很多書都看了一半就看不下去了。

33. git是最棒的。簡單,可靠,免費

源代碼管理,必選Git,自己可以架設Git Server,也可以用GitHub。

34. 僅對「可預測的非理性」拋斷言

恩。是啊,尤其用戶輸入的時候。

35. Log要寫時間與分類。並且要能重定向輸出

這個用現成的Log組件即可。有Log4J,Log4Net,真的很好用。

36. 注釋是稍差的文檔。更好的是清晰的命名。讓代碼講自己的故事

前面已經說過了。

37. 造輪子是很好的鍛煉方法。前提是你見過別的輪子

這裡說的是程序員的自我修鍊的過程。確實,對於一個需求場景,我們應該先想想有沒有現成的開源項目可以用,然後再看能否把開源項目拿來改,最後自身足夠強大了,就自己做一個輪子。

38. code review最好以小組或結對為主。因為對業務有足夠了解建議才更有價值。而且不會成為負擔。注意,提交過程中的管理員review很容易成為瓶頸

這點我做的不好,在我這麼多年的工作中,也只有為數不多的Code Review Meeting。

39. 提問前先做調研。節約大家的時間

是啊,Google能夠直接告訴你答案的,那就不用再問別人了。

40. 永遠別小看程序媛(╯3╰)

只要是正在的碼農,在我看來是沒有區別的。所以沒有小看或者高看的意思。

以上都是我的個人感受寫給自己,看看差距,希望以後能做的更好吧。

阿里云云棲社區,彙集阿里技術精粹,點此關注

親們阿里云云棲社區已開通專欄,歡迎關注閱讀:我是程序員 - 知乎專欄


需要解決比較複雜數學問題的時候,請直接找數學專業人士,而不是自己跳坑。
比如:汽車工業界幾十年來都想消除 NURBS 曲面上的曲率突變,結果丘成桐直接從理論上證明他們是痴心妄想,後來業界就關注怎麼用里奇流來最優化突變數量了


推薦閱讀:

知乎上有哪些在前端開發領域的高質量回答?
為什麼維基百科的用戶界面設計不夠友好?
為什麼很難聘到前端工程師?

TAG:前端開發 | 程序員 | 編程 | 軟體工程 | 軟體架構師 |