非科班出身程序員比較容易缺乏哪些技能?用什麼方法彌補比較好?
最大的缺點就是:
不知道自己不知道什麼。所有稱得上稱職的程序員通常都有非常高的自學能力及慾望,我將題目理解為「非科班出身程序員比較容易缺乏哪些技能」。
沒有系統學習過計算機科學知識的程序員通常是興趣驅動的,這往往意味著他們以解決問題為出發點,所缺乏的技能通常在理論和基本功方面,比如各類基本演算法和數據結構。彌補這一點只需要讀兩本書,做一些習題即可。
此外他們通常從一種技術起家,有可能對其「母語」的語法、範式、庫、社區等等帶有強烈的感情,可能會對於「敵對陣營」的技術,或者新鮮事物,產生排斥和輕視,影響到技術遷移和對新概念的掌握。不過這是個性問題,在科班出身的程序員之中也不少見。基本上沒法彌補。
第三他們可能會缺乏一些基本的計算機文化常識或曰「鄉謠(Lore)」,比如 foo bar 後面的第三個佔位符是什麼、這些佔位符什麼來歷、Dijkstra 是誰之類,科班出身基本上都知道的事情。這個也是看書就能補的。
再就是英語可能會比較爛,不過也不乏知名英語兼成功學教師學過兩行 HTML 就開始 bitching 國內程序員界如何扶不起。請注意我鄙視的不是 HTML。
Update:
補一個書單,僅供參考。
- Introduction to algorithms,作者首字母縮寫 CLRS ,講演算法的。
- Structure and Interpretation of Computer Programs, 簡稱 SICP,一本有些被神化的書,不過的確值得一讀。多數人初讀此書,兩章後會有眼前豁然開朗的感覺。雖然這書已經不再是教材了。封面是魔術師和 lamda 。什麼是經典,這就是經典。
- Computer architecture: a quantitative approach,此書我還沒看,因為我自己也不是科班出身,而且此前對硬體毫無興趣(Dijkstra 說過 computer science is no more about computers than astronomy is about telescopes),不過據說講計算機架構的書里這本很好。
- Concrete Mathematics: A Foundation for Computer Science,高德納出品,講述與計算機相關的數學知識。如果數學書只想看一本,這個應該差不多夠了。
- Computer Networks,作者Tanenbaum。
- 一本講數字電路基礎的書……可以省略,不過還是挺有趣的。
- TAOCP,若能看下去就看吧,看不下去也沒啥,科班的都未必看得去。
- The Art of UNIX Programming,The Cathedral and the Bazaar,這兩本是傳道書,有些內容現在看來已經是常識了,不過仍舊值得一讀。
- Code Complete (2nd Ed) by Steve McConnell,比較系統的軟體工業流程認知和編程常識讀本。
- The Pragmatic Programmer, 這本書講授編程實作中的基本套路,過一遍有助於掃清盲點。
- 《人月神話》(The Mythical Man-Month),中文版還不錯。
- 《最後期限》(The Deadline),中文版也還不錯。
- Refactoring: Improving the Design of Existing Code,「重構」理論的集大成者。
- Design Patterns,「設計模式」的集大成者,作者四人幫,封面是埃舍爾的畫。什麼是經典,這就是經典。
- Programming Pearls,《編程珠璣》,茶餘飯後的鑒賞小品,雖然說不定哪天就用到了。
……待續。如果不脫產,這些書夠讀兩三年的。所以科班出身最大的優勢,可能就是有四年的時間可以讀這些書,和同樣讀這些書的人交流,並且不用為別的事情煩惱。
我只想說,作為一個科班出身的人,看到題主的問題,與目前排名靠前的幾個答案。心裡真的好虛。
其實,科班出身的,數學方面也幾乎沒啥基礎。而演算法,如果不是搞過ACM之類競賽的,也都是一塌糊塗,頂多是略懂略懂。像演算法導論那樣的長篇著作,更只是浮光掠影的掃過幾眼而已。
不知道其他科班的學生是否和我感受一樣。
上基礎課程的時候,我在想的是,能夠用編程解決什麼問題,然後感興趣的恰恰是一些奇技淫巧,如怎麼寫個小遊戲、怎麼搞個黑客工具之類的。而網路發達的如今,這樣的小東西比比皆是,很容易就找到一種莫名的成就感。於是,就會感覺諸如數學、線性代數、演算法、計算機體系結構,都好無聊啊。
而學校少數幾個能夠動手的課程,偏硬體的也許在搗鼓單片機,偏軟體工程的,幾乎清一色的Java EE,為啥,這東西最容易搞出一些理論來,好教。諸如分個組模擬一下做項目的感覺,寫個需求分析、概要設計、詳細設計之類。可那時我真的還比較懵懂,Java也僅限於知道一點語法而已。如何架構一個後台系統,真的跨度比較大。所以一直到課程設計,幾乎都在琢磨類似SSH這樣的成熟框架的使用。而這時,隱約感覺到,基礎不牢,地動山搖了。為啥,因為很多東西不明白,看了很多介紹的書,就是看不明白。老師能教的也有限,大三之後,幾乎就只在意成果,不在意你到底理不理解了。然後,這時學習的課程,幾乎都是諸如設計模式、重構等艱深話題,由於根本沒什麼實踐經驗,所以各種被打臉。
所以我可以總結說,大部分時候,由於作業、考試、實驗報告的壓力。很多方面都是死記硬背下來的。真的沒有理解透。甚至,很多當時覺得理解了的東西,回頭髮現,其實理解偏了。
直到實習切實應用、考研全面複習基礎知識。才感覺自己的知識體系慢慢成型。
——————
以上就是我作為一個科班出身的人,真實的經歷。工作有年頭之後,才多次深感基礎的薄弱,技能的缺乏,回頭又看書,卻比較容易理解了。但,真的很少有精力、有時間去看了。
有時候,就是這麼無奈、悲哀。
科班出身的程序員也容易有技能缺失,前面的答案略有提及。如腳本語言(python, ruby, lua等),很多科班出身的就很少接觸。如果有,都是自學的。而大部分,都僅限於主流編程語言(C,C++,Java等)。而且,多數因為連這些語言都很難掌握精通,很少有勇氣去自學腳本語言的。
所以,我覺得,無論是科班的、非科班,都會缺失一些技能。真正牛逼的,就是那些練童子功的吧,或者ACMer了吧。其他人,多數都很平庸。
我有時假設,我重新念一次大學,會不會把技能點點的更全一點。多次推演的結果是:不會。估計我還是會這樣走過,也許偏重不同,可能會更注重數學知識、演算法等。
也許最好的彌補措施,不是全面撒網去補缺,而是遇河過河、遇山翻山。從你現在的工作出發,遇到哪裡不懂,由點及面的去讀書、去研究。效果會好一點。
列書單,往往是一種心靈的慰藉。除了學生、能去啃得下大部頭的人,寥寥無幾。而學生,又往往不懂這些看似無趣之書的價值所在。最終啃下來的,都是人中龍鳳。
人類歷史上,龍鳳總是少的。
以上。
——
PS:本人211大學的計算機科學與技術專業(07級),不能代表一流大學的情況,但應該可以代表中流那一部分。以我來說,編程和計算機架構主要是中學時自學的,而演算法在大學裡上過兩門課。但我的本科是認知科學,缺少了一些計算機科學必修課,例如編譯原理。另外,數學比較不足,所以近兩年自修一些抽象代數、拓撲、微分幾何等,將來準備再學一些微分方程和數值分析。
現在也有很多公開課,只要英文可以,是一種很好的進修途徑。
補充濤吳書單:
Computer Systems: A Programmer"s Perspective
Modern Operating Systems
冒號課堂
另外最好學一門腳本 包括但不限於bash/perl/python
因為計算機相關的課程,科班出身基本都學過,但是自學過腳本語言的人才是真正愛這行的人
數學太差. 底層知識不牢靠. 沒看過幾篇論文.
以上我在說我自己.
如果讓我推薦, 我能想到的好書不多. 大約這個比較值得推薦:
&
http://www.akkadia.org/drepper/cpumemory.pdf
==
點評一下有人推薦的書單.
樓上有人推薦SICP, 書當然是好書. 然而非科班學生入門的話, 看SICP之前最好先看看&<小陰謀家&> ... HtDP也是個SICP的前導書, 不過進度太慢, 我沒耐心看完.
CSAPP比較枯燥. 如果為了速成, 應該是很多人沒興趣讀完的. 所以我更推薦薄一些, 更有意思一些的&
TAOCP很多人推薦, 沒幾個人讀過... 所以我總覺得推薦這書的人並不靠譜... 為了找工作, 還是去刷leetcode吧... 學東西一定要選最快的方法, 因為肚子很快就會餓. &<- 基於這個理由, 我不推薦TAOCP. 事實上我總是更願意推薦初學者去看"薄"的書. 快速入門, 想深入有的是機會. 但是入門時就被枯燥乏味的口水給嚇走了還談啥深入不深入...
1.缺少計算機行業的世界觀,科班出身的對整個軟體體系了解更多些,在簡單點說就是對行業的見識和認知少了。
2.缺少這些並不可怕,在前期接觸的時候入門會慢點。但是這些都不是問題,心態上「激情+熱愛」,行動上「多問多聽多看多研究」。
3.編程這玩意,我總覺得跟佛家說的「醍醐灌頂」有些相似。在開始你很難入門,總覺得比科班的少些東西,也很努力,但就是不如意。但是不斷積累積累。某一天突然開竅了,再從頭回顧以前的項目,豁然開朗。
4.當初自動化畢業,每天跟強電打交道,只會點彙編和C語言,冒然闖入軟體業。每天像聽天書一樣,身邊人嘴邊的關鍵詞一個都不懂。開始做項目被經理K的最多,自己都懷疑自己能否走下去。但無數個加班的晚上熬過之後,某個晚上突然悟了。回頭看看,原來如此。
高等數學,線性代數,概率與統計,離散數學,演算法和數據結構,操作系統,網路協議,計算機組成原理,編譯原理,圖形學,人工智慧,資料庫系統等等等等。每門課程一般都只安排一個學期,平均也只能學個大概,考試不掛的程度。更不會教你有問題先google,對待新技術要持空杯心態這些。科班出身的平均水平不高的
個人比較認可 @Milo Yip的答案。
我自己高中畢業後做銷售,後來做coder,現在在一家中型互聯網公司做基層Leader,面過很多科班出身(大部分都是211、985畢業,公司要求比較高)的coder,這一方面還是比較有感觸的。
先說說一定會缺乏的技能:
0. Algorithm、Math
1. Data Structure
線性、樹狀等結構
2. 編譯原理
3. 計算機結構體系
這一點在底層以及基礎系統、中間件開發方面比較重要。
4. 編碼能力
大學裡面寫過10萬行C/C++的人,在編碼功底上確實優勢很大。反應到工作就是,開發效率以及Bug數量。
個人是我結合自己以及公司成員(大部分來自BAT、網易等公司)的出來的。
彌補措施:
0. 這個不好說,我在這一塊進度比較緩慢, @Milo Yip的方法應該不錯,也是我想實踐的。
1. 相關數據一本,用C實現大部分結構,應該問題不大,我就是這麼做的。現在基本上常用的都不會有問題,且很清晰每一個結構的優劣以及內部實現。
2. 不知道
3.讀過一本書《深入理解計算機系統》,可以補上不少知識。
4.大量的寫吧
個人的一點經驗,僅供參考。
Ps:感覺Coder對軟性能力要求更高,比如系統設計,解決問題能力等等。作為程序員的話,非科班並不比科班缺少什麼「技能」。科班和非科班的不同,我覺得對於程序員工作基本毫無影響,區別只在一些屠龍之技上,舉個栗子:
我常上某BBS的求職版面,前幾天有人問了一道程序員面試題(好像說是Google家電面題),我第一反應覺得似乎是NP-Hard的,仔細想了一會兒後發現確實是可以從圖的最小支配集問題歸約而來,很高興地把我的思路貼了上去。後來發現只有一個人和我討論,其餘人都在紛紛貼代碼和互相找bug,用BFS的,用剪枝搜索的,用(錯誤的)貪心的,等等。
我知道如果我去面試的話也是要寫代碼的,實在忍不住想扯些NPC之類的話也要看面試官臉色,遇見不耐煩的面試官沒準兒要被鄙視。所以科班出身真的是毫無用處啊。同意匿名用戶說的,其實純學計算機的話,個人沒有太濃厚的興趣的話,演算法這一塊能力很弱是很正常的。理解了剝掉演算法的數據結構之後(難度還沒高中數學高)利用現成的庫實際上甚至足夠應付大部分的中高級工作了(注意不是底層工作)。
計算機從科學角度上其實是很淺的,任何工科,土木啦,機械啦,生物,甚至於金融工程的對演算法和數學的需求都碾壓學計算機的。
我個人從計算機專業出來的感覺,專業和非專業的主要區別,一個是軟體工程的打底,一個是計算機原理和編譯原理構造的對整個體系的理解。
前者沒有解決任何問題,但提出了一個軟體工程是可控的空想烏托邦,於是我在十幾年編碼生涯中,永遠無法在(痛苦不堪的)寫完模塊之後停止思考和質疑,這個習慣大大強化了腦海里各種組織,結構,抽象概念的培養,而不是停留在某個具體語言的某個具體框架的某個具體哲學(宗教)上;後者會讓我寫完一行代碼的時候能直接想像出來代碼會變怎樣變成編解碼,編解碼會怎樣變成電平信號在cpu和內存里把東西倒騰來倒騰去,最終變成屏幕上的像素點的過程,這個過程起到的作用,除了能輕易理解多線程和優化性能之外,還可以強化我們碼農的刨根問底的強迫症傾向,我們強迫症無法接受已經掌握的這個巨大的白盒子裡面混進一個黑盒子進來,理論上一切都必須弄成是透明的。(所以程序員不可能去問熟悉領域的問題,白盒裡怎麼會有問題,這是完全情緒化的下意識反應,結果碰到盲點,其實真有問題的時候就砸了)
最終達到什麼效果呢?舉個例子,職業小說家永遠不是按照故事發展想出故事進程寫在紙上就夠了,他們腦子裡能同時想出這一段故事的20種發展模式,整個故事完全在他們的掌控之下,整個故事的一切其他發展的可能性也完全在他們的掌控之下,他們就是故事世界觀里的神,寫出來的故事只是千萬個平行宇宙里一個偶然而已。
而程序員成精之後,就會變成他們所寫的模塊的神,他們不是寫一個模塊把功能實現,而是知道用無數種結構,無數種語言,無數種未來的功能拓展可能性下這個模塊的寫法;也知道這個模塊將來一切的可能的功能擴展的時候需要如何修改的寫法;同時知道這個模塊永遠寫不到哪種程度的寫法。我自己腦海里就有「任何語言都實現不了」的一些遺憾,任何新語言,新框架出來的時候都會興沖沖的跑去審視一遍看看是否有所突破,然後悻悻的關上網頁。缺的不是技能,是一種理念吧。比如:編程時,寫一段代碼,科班出身的能夠把這段代碼從編譯到執行這個過程在大腦里顯現出來,有哪些步驟,代碼如何在計算機整個系統中運行,如何在網路中傳播。也就是說,在他們腦海里對整個計算機系統,互聯網,有一個從局部到整體的認識和把握(這些東西在工作中一般體現不出來,但不是每個科班出身的都能完全理解到這個程度的),而當遇到相關聯的知識也知道可以到哪裡去尋找解決方案,其實科班出身的也就是學的基礎理論知識比較多一點,更加系統一點。彌補的話,只能多看上面推薦的書(如果沒有極大的興趣,真的很難看進去的,特別是基礎理論的書)不過僅僅是為了工作需要的話,很多基礎理論並不需要,因為大學裡面教的那些理論是為了科學研究做準備的,目的不僅僅是為了提供軟體開發人員。所以非科班的人員反而會因為更專註於某一項技術的深入研究而比科班人員更出色的勝任軟體開發,這也是業內所說的科班出身的水平比較低的一個原因吧。術業有專攻,社會分工越來越細,非科班的不必要為此苦惱,除非想在計算機領域有更高的成就才需要去學習更多的基礎理論知識!(個人短見,僅供參考)
反對@Chaos的答案。
聲明:我並不是來優越似的表達科班出身的程序員比非科班出身的要高明、優秀多少,而是以一個在讀的未來的程序員的身份探討一下系統地、有層次性地學習更加事半功倍。
我假設@Chaos通過自學,大量地敲寫、堆砌代碼(事實上,他肯定也會有思考,看書學習的過程,但是他的答案展現的是無盡的寫代碼才是正道)成為水平不俗的程序員。
為什麼很多人認為科班出身的程序員會比非科班出身的程序員優秀呢?其實程序員作為理性的一群人,大家並沒有這麼武斷,他們這麼認為的原因在我看來應該是,科班出身,那麼學習編程更加的系統,有層次,循序漸進,這樣的學習出來的人基礎更加雄厚,理論比較紮實,日後工作時學各種招式都很快。當然,很多科班出身的人也很菜,比不上某些非科班出身的,就像chaos說的某些非科班的秒殺80%985/211的學生不在話下,其實原因也不是科班不科班,而是很多科班出身的人並沒有認真去學習,循序漸進的學習,而這些非科班的卻相反。
《演算法導論》公開課的那位教授說過,你可以編寫10年代碼成為大牛,也可以選擇學習一門優秀的演算法課,然後編寫2年代碼成為大牛。這裡是強調演算法的重要性。但我們也可以容易的看出,系統地學好演算法,將會對你的編程水平的提升有著莫大的助益。
正所謂磨刀不但不誤砍柴工,而將對砍柴大有裨益。
回到這裡,我的看法是,無論你是不是科班出身,系統地、循序漸進的學習才是王道,才是成為優秀程序員的康庄大道。
通過不斷地堆砌代碼,編寫代碼成為可不可能成為大牛呢?當然可能!但是這並不能說明這是成為優秀程序員的康庄大道,雖然必要的練習是必不可少的。我不斷朝著東走一樣最終能達到西藏,但你不能說,朝西走更遠,甚至行不通,更不能宣揚說去西藏最近的路是是一直朝東走。
如果一開始就能夠系統、循序漸進地學習,再加上多年踩坑的經驗以及對於編程的興趣或者毅力,我相信不管是否科班都會成為優秀的程序員的。
我並不以所謂科班不科班看待程序員,但是我絲毫不贊成Chaos的言論,他所說的確實會有人因為那樣成為牛人,但是他的方法並不可取,最重要的是在那裡宣揚這種方法,很有可能給初學者造成誤導,容易急功近利,誤入歧途。
條條大路通羅馬,那為什麼我們不選擇康庄大道,而去選擇荊棘小路呢?身為高中學歷非科班吊絲程序員表示目前感覺最缺的是數學和英語。
謝邀,除了把微積分,線性代數,離散數學,計算機導論,計算機組成原理,彙編,數據結構,演算法導論,編譯原理等基礎知識過一遍之外,剩下就一天500行以上的敲代碼
演算法、數據結構、設計模式、編譯原理
非電類的可能還對於彙編、計算機結構沒什麼了解
科班出身表示讀了太多書也不見得會寫多少代碼,不過倒是覺得寫書的人很有意思,谷歌他們的代碼,論文,著作,遂豁然開朗。
關於怎麼彌補,不要執著於項目和進度,一定要抽時間出來保持學習熱情就行。沒差, 只有適合與不適合之分.
有的科班出身的人一樣不適合做程序員, 於是那些人要麼轉行, 要麼墊底了.
私以為搞程序開發最大的要求就是興趣~當年擺在我面前的兩條路, 一條是研發月薪2500, 一條是測試月薪4500. 我用腳想了一下, 毅然決然的踏上了研發之路~
奮鬥至今, 我現在掌握的東西基本上都是自學的. 包括我正在做項目所用到的語言.
最後也是最重要的一點, 邏輯能力....私以為跟智商有點關係, 吾從不認為所有人的聰明程度都一樣, 邏輯能力高的人在寫程序的時候得心應手, 演算法信手拈來. 學得也快. 這是天分問題.. 當然不排除一些苦大仇深的通過瘋狂後天訓練,量變來產生質變, 但那種就像碰撞演算法, 很累...而且最終會變成測試.
部分非科班出身的程序員,最缺少的技能就是不知道自己不會什麼。結果是不知道自己的長期學習方向。
像牛頓(是他吧)畫的圓,圓越大,圓周接觸外圍的邊緣也越大,科班出身的同學由於在大學被各類基礎課老師給玩過,於是有的知道自己的彙編語言那個爛,所以對硬體體系留存一份敬畏,有的知道自己的演算法能力在班裡只能是倒數,所以工作中遇到演算法高人的戰友頓感幸福,有的知道自己連個像樣的表達式解析器都搞不定,所以從不亂評一門語言的好壞。
非科班出身也有不少心若虛谷之人。。。但這二十年下來,我聽到下面這樣的表達:
「我幹嘛要知道位元組和字元的區別?(java環境下),我幹嘛要關心字元串「123456」和數字123456誰佔用內存大?都用字元串表達,比較,是多麼方便的事呀。我幹嘛要知道浮點數與字元串轉換的代價。。"
"演算法真的有用?我寫程序也5年了,從來沒有什麼需要用到我不會的演算法呀,不也工資過萬? 說難聽點演算法就是一些人拿來賣弄的。他的程序是用了比我好的演算法,也確實比我快一倍,但用戶設備那麼好,有必要搞這麼複雜嗎?"
「這門語言(比如golang或某腳本語言)語法格式就一瞎整,居然把類型放在變數後面。。。反人類呀。 」
這些表達沒有精細統計,但通常5個中有4個是非科班的。儘管他們當中好多都是幹活的好手。
解決方法,應該多買基礎理論的書閑時翻翻。
高三的時候我也是收到過一個做科學可視化的公司的面試邀請的,不過後來人家發現我是高三就罷了。所以我也算當過一把非科班出身的程序員吧。後來讀了軟體工程,就變成科班的了。
想想讀計算機前後到底有什麼區別?無非就是好好的搞了一把演算法導論,學會怎麼做測試,怎麼組織軟體生產勞動了,做一個優秀的項目經理(跟產品狗是不一樣的)了。這些也不是只能在大學才能學會,你只要進了一個靠譜的公司,耳濡目染,也是可以很快學會的。
只是靠譜的公司多半要求比較高,非科班出身因為沒受過訓練的進去略難,這算是一個良性循環了。不過只要你肯好好補上這些功課,還是沒問題的。
推薦閱讀: