程序員在實際工作中寫的代碼和各種學生時代的競賽如ICPC NOI等寫的代碼有什麼區別?

如題,請從難度,思路等等方面分析一下


真正的程序,corner case多到爆炸,所以能寫對就已經天下第一了。其實只要你的程序的scalability是好的(完美的情況下也就是說給你N台電腦你的速度就會變成N倍),那這就把問題轉換為錢的問題,而不是演算法問題了。而錢的問題顯然是最容易解決的。如果你生命的短暫只能允許你在scalability和algorithm之間選一個,那一定要選scalability。

scalability差又是一種什麼情況呢?假設你的程序是允許多進程執行的,但是之間要同步。做一個1小時的任務,其中有10分鐘的部分是不能並行的。那麼你就算有billgates那麼多錢,你的性能也只能提高到6倍。如果你不能並行的部分只有+1s,那你就可以提高到3600倍。如果你做到了完全並行,那就真的是有多少錢就給多少速度了。

有些時候為了達到一個更好的scalability,可能會需要你做出讓單機性能更差的選擇。這個時候千萬不要猶豫(逃。如果你的程序執行1小時,不能並行的部分是1分鐘。現在為了完全去掉這個不能並行的1分鐘,你亂雞巴改把你的程序改成了10個小時。假設一台電腦是1000美元,那麼一開始你可能需要花1萬美元才能做到原本那麼快。但是不能並行的部分是1分鐘的意思也就是說,最快的極限就是1分鐘了。因此如果你花掉的錢大於60萬美元,你就獲得了比之前1小時的演算法的極限更快的速度。當你的投入終於到了6億的時候,雖然你的演算法的單機性能比以前爛了10倍,但是你的「爛」演算法在6億的加持下,性能是6億加持下的「好」演算法的1000倍。

這裡的性能的極限,指的是在任務無限、金錢也無限的情況下,「花費的人命時間/任務數量」的極限。此時不同電腦的時間是不直接相加的,同時發生的就只算一份。所以才說是人命時間,畢竟不能說你能同時操作兩台電腦,你的壽命就算成160歲。


你永遠都猜不到用戶會給你什麼輸入,然而你還需要儘可能的處理所有的可能,同時還要做到性能和可靠性。
還有後期維護,名稱衝突,擴展等等很多問題需要解決。


叫那群 ACM 選手去解析一個稍微像一點人類寫的輸入格式,就能難倒不少了……

真實世界是艸蛋的,不是準備好的數據


注釋,變數名,風格。
對輸入數據的特判。
用戶友好。
這些都是競賽不要求而現實要求的。

但是我反對那些說難倒一大片的。因為競賽學到的編程思想是很可貴的,相比之下剩下那些事都是小菜,只要稍稍提醒即可解決。實在不行寫幾個程序之後也就有經驗了。


1.業務問題。程序競賽一般解決的問題有特定的輸入和輸出,但是現實世界一般需要解決公司的特定業務問題,不同公司需要的業務知識不一樣,需要掌握一定的領域知識。程序競賽一般對智力、演算法要求比較高,公司項目往往對代碼質量和工程比較關注。

2.風格和可維護性的區別。程序競賽一般為了效率寫出來的代碼風格和可讀性稍差,但是工程代碼大部分時間是用來維護的,需要具備良好的風格和可讀性,崇尚clean code,需要良好的注釋、文檔和單元測試,甚至很多編程語言比較tricky的地方會禁止使用。你可以看看阿里最近開源的《java編程規範》,能體會到工程代碼的很多規定。或者看看google開源的代碼規範。

3.魯棒性。競賽代碼的輸入一般是確定的,但是現實世界的複雜性可能導致代碼在很多地方崩潰,需要良好的容錯能力。比如競賽代碼一般是極少需要處理異常的,以至於筆者一開始寫工程代碼的時候幾乎不會捕捉異常,導致一開始各種崩潰。

4.防禦式編程。不要信任來自外部的任何輸入,防止xss等攻擊。

5.交流和理解。公司里一般需要和設計師、產品、運維、測試工程師等各個職責的人打交道,需要具備良好的溝通能力和對業務的理解能力,很多問題有時候並不是純粹的技術問題。

6.工程管理。工程代碼一般代碼量比較大,甚至不是一個人短時間能掌控的。有些公司會把業務拆分進行服務化,需要具備一定的工程項目管理經驗。筆者每次上手新公司的代碼都需要花費一定的時間去熟悉各種文檔和代碼倉庫,每次面對比較ugly的代碼倉庫又沒啥文檔和注釋的項目,總是比較崩潰。

(答主剛入某乎,這是我web後端開發的一些經驗,想到了再更新吧)


真正的程序90%是logistic代碼,比如dump debug log的,調整輸入輸出數據類型不匹配的,還有將就各種蛋疼的庫函數的……真正的核心業務邏輯只有很少一點點。

而且如果你對其中某一行有疑問,永遠找不到人問。

而且永遠有bug。


編程五分鐘,扯淡兩小時


健壯性和可擴展性


之前在學校打過一陣子比賽,沒了興趣也就沒打了。現在在學習寫網站。

區別有這樣幾點:
1.icpc幾乎不用考慮程序的可讀性,速度才是墜吼的。這樣的代碼是很難維護的。

2.競賽其實做多了也就是各種模板各種練,大部分題分析清楚了,直接套模板就好了。實際編程裡面模板少,質量差的居多。

3.競賽大部分c/c++,java,實際編程中語言的選擇挺蛋疼的。

競賽的意義並不是在於讓你學會編程,它只是帶給你一種又一種想法,編程只是實現了這些想法而已。
打過競賽以後去編程,你會發現很多東西寫起來都比別人輕鬆。


比賽的時候,考驗你的是記憶力,以及知識的深度和廣度,以及高壓力情況下對知識的檢索能力。

工作以後,很多時候你只要具有廣度就可以了,很多時候深度的部分大腦僅作為一個cache的存在。但廣度的要求卻比比賽時還大的多。

另一個方面,比賽時候,你會感慨寫代碼容易,做演算法難。

到了工作,你會感慨能把代碼寫對就不錯了。幾乎所有的精力都花在怎麼讓代碼沒bug。


你會以為可以靠屌炸天的演算法在代碼世界裡平步青雲,然而現實只關心你的代碼有沒有Bug,完(攤手)。


謝邀

ACM應對的是一個確定的問題,所以代碼以高性能為第一要務;實際工作應對的是不確定問題,所以代碼解耦才是第一要務,性能往往是夠用就好


我歪個樓。
比賽的時候,沒有特殊情況,題目是不會變的,題量是不會增加的。
工作的時候,沒有哪個需求不在變動,手上的項目也只增不減。

這兩種情況下能一樣嘛?
當然了...有些大佬經歷的多了,西方的什麼需求都見過,那自然是能談笑風生。
但這也是有前提的,將來線上出了偏差,程序員可是要負責任的!


比賽中自己知道要做什麼,工作中不光自己不知道要做什麼,連客戶都不一定知道要做什麼


難度:競賽題一定有解,實際的項目是不一定的.這就跟學數學一樣,書上要求證明的題一定能證明真偽。實際的數學問題連真偽都不知道。比方說1+1。
範圍:競賽題是濃縮了的,最核心的難題,解出來就成功了。實際項目核心問題可能只佔1%,大部分解決的是簡單而零碎的各種小問題,比如錯誤處理,業務邏輯,任何一方面沒做好,產品就有可失敗。
時間:競賽解題時間以小時計,實際項目以一般以月甚至年計,對時間規劃要求高的多。
人:競賽一般兩三個比較熟悉的小夥伴,背景差不多。實際項目會碰到各色人等,各種有的沒的消息,溝通overhead巨大。
評判:競賽以對錯為評判標準,演算法熟,編程快,腦子好就能勝出。實際工作沒有對錯,不以單一標準論成敗。程序員編程能力強,但是到一定level因為別的因素升不上去的比比皆是。


概念車和路上跑的車的區別


acm是面向oj programing
工作是面向同事 programing


就好像花樣游泳和橫渡長江的區別


競賽的時候一切操作和環境都是最優化的,僅僅需要秀技巧即可


實際工作中根本不需要技巧,都有現成的開源包可用。千分之一的情況可能需要你實現一個特殊演算法的話,去google一下,抄一段就行了。


實際工作中主要要考慮可用性。首先運行環境不可預測,包括各種花式的環境和輸入,一個不注意就是異常或者安全漏洞。另外分解需求時業務邏輯不求優美簡潔,但要思慮慎密,但凡少考慮了一個特殊情況,就就是一個嚴重產品缺陷。還有一個是維護代碼靠經驗和良心,盡量讓別人接手的時候不罵人。


除了代碼能力外,競賽還檢驗智商。。


做演算法題最主要的好處還是在對時間空間的估算上。即使是第三方庫,一個第三方函數拍下去,n 還是log n 大概心裡就有個數了。

順便說一下,當下大量的第三方庫大大方便了麻瓜的程序開發,其實許多的優秀演算法和理念都封進去了。

做業務99%的時間用不到複雜演算法,但當真遇到需要人肉寫一個複雜演算法的時候,就是你發現為什麼同樣是coder,但是待遇有差別的時候。


推薦閱讀:

GitHub 上有哪些優秀的項目?
這次intel裁員對象大部分為40歲以上,是否說明40歲以上的程序員就基本喪失競爭力了?
你們有沒有遇到那種長的比你高和帥,能力比你強,情商還比你高的對手呀。?
程序員們是不是熱衷於站隊而非技術?
北京哪裡有面對面學 Coding?

TAG:程序員 | C編程語言 | 計算機科學 | IT行業 | ACM競賽 |