小編轉註:《為什麼有些大公司技術弱爆了?》話題討論得激烈,前些天小編轉的幾個熱門回覆,是教育題主的。今天發一篇支援題主的。
知乎上看到一個熱帖,我覺得很有意思,叫做“為什麼有些大公司技術弱爆了?”。我剛看到標題的時候,先入為主和刻板偏見了一下,正如同第一個回答一樣,我皺了皺眉頭,產生了對題主的鄙視之情;但是很快,讀完帖子以後,我卻立場明確地站到題主一邊了。正如同裡面有位回答:
看題目以為是題主傻逼,看了正文發現真的是公司傻逼。
上面這種情況其實發生的概率挺低的,但是我覺得這回是真的發生了。
但是令我感到遺憾的是,各式各樣的回答裡面,大部分居然都跳出來“教育”題主,表態這個世界就不是完美的,表態要妥協要接受這樣的事實,要無奈地嚥下這個現實的苦果。這個大面積出現的觀點,太不正常了吧?
比如這樣的話:
寫好程式碼是程式設計師的節操。抱歉,節操多少錢一斤,北京三環商品房多少錢一平?
有的問題實在不是能夠三言兩語回答的,尤其是當面對整個行業的現實的時候,但是,可以很明確的是,當一個專案程式碼寫爛掉的時候,這個專案也活不久了。
好吧,還是就事論事,下面就貼過來,然後逐一分析其中的內容。說說為什麼大致上題主沒問題,有問題的是這家公司,這個專案組。
=================================
今年年初,到一家網際網路公司實習,該公司是國內行業龍頭。
不過技術和管理方面,卻弱爆了。
那裡的程式設計師,每天都在看郵件,查問題工單。
這些問題,多半是他們設計不當,造成的。
>> 這就是所謂的operation的工作,大多情況下很無趣。這通常也意味著系統複雜,負載高,問題不容易輕易定位和解決,往往是歷史遺留下來的大型系統。這並不奇怪,就像外人見到風光的AWS一樣,之後內部的工程師才知道其中有多少維護性的工作,壓力有多巨大。我記得不久前,看過一個principal talk,講oncall的折磨使他成長,我想說法不假,只是很遺憾我還到不了這個層次。題主能看到問題多半出自設計不當,不錯。而問題居然多半是因為設計不當,這個工程的初始架構人員 ,以及後來架構看護的骨幹工程師,是要挨批評的。對於一個“國內行業龍頭”,這樣的事情是不該發生的。
程式碼寫的一團糟,全是複製貼上,連作者都沒改,大家普遍不寫註釋,也不格式化,程式碼歪歪扭扭。
>> 這又是一件不該發生的事情。對於程式碼質量的追求各有說法,但是“複製貼上”、“作者都沒改”、“不寫註釋”、“不格式化”等等這樣的字眼,我不相信一般的“龍頭”公司能夠接受。這些東西就像飯要一口一口吃一樣,縱然有再大的野心,這些最最基本的細節,始終是不能忽略的。我覺得公司在招人的時候,既然是雙向選擇,就可以互亮程式碼,這樣的程式碼擺出來看到以後,大家就不用浪費時間了。
一個專案裡,httpclient竟然出現了四種。
一種是該公司研發部寫的,
一種是老版本的開源專案,
一種是新版本的開源專案,
還有一種是開發人員造的輪子。
>> 最理想的情況當然是統一成一種。遇到這樣多種實現,並且有自造輪子的情況,很多都是源於“歷史原因”。當然,都能看到程式碼簡單地“複製貼上”了,不看以往程式碼實現,按照自己的理解來寫也就並不奇怪了。當然,我可以接受因為某某特殊原因而導致一個httpclient有多於一種的實現方式(我在這裡還寫過造輪子的好處),但是居然有四種之多,我覺得凶多吉少了。
打介面請求響應日誌,竟然不知道用攔截器。
打錯誤日誌竟然不打上下文資訊,每個人一種日誌風格,千奇百怪。
許多重要的中間流程,居然不打日誌。
>> 攔截器是個好東西,簡化程式碼,避免囉嗦的日誌影響業務邏輯的閱讀。當然也有不好的地方,比如不直觀、不好除錯,以及有時候可能發生的效能問題等等。因此這個也不強求,根據專案實際情況而定。日誌風格千奇百怪的問題,多是由於缺乏專案內部的管理造成的,各就各業,缺少溝通。開發人員不怎麼樣不說,這個專案經理更是弱爆了。重要流程不打日誌,這一條只能幫助證明這群開發人員的工程意識還欠缺。
idea、eclipse、myeclipse的配置檔案竟然全部傳到專案裡去了。
>> IDE用的不一樣沒事兒,但是這些IDE的配置檔案也傳上去了?這樣的低階問題都出現……難道程式碼不用review麼?
該公司混了兩年的程式設計師,跟快遞公司做查詢介面,竟然不知道加密運單號。
>> 這樣的資訊是否要加密通常取決於呼叫兩邊的協議是怎麼規定的,但是凡是涉及到隱私等等重要資訊,都需要加密以減少資訊洩露的風險。
所有服務間通訊,都沒有設requestId,導致跟蹤會話很困難。
>> 如果只是牽涉到服務之間的通訊,而通訊又只是簡單的查詢的話,沒有requestId我覺得是可以接受的。至於會話的跟蹤,如果這裡指的是整個系統在一個request到達和處理的過程中,能夠跟蹤全部的或者重要的行為,比如呼叫了哪些介面,得到了哪些結果,做了哪些操作等等,這個功能確實是很有必要的,但是這個跟蹤是可以在服務間通訊沒有requestId做到的。比如在主系統中使用一個執行緒變數,在每次列印這些資訊的時候把執行緒變數放置在前面,後續的日誌分析工具就可以捕捉到這次會話互動的所有日誌。
一個沒什麼qps的邊緣介面,居然做消費者生產者+阻塞佇列的非同步模式。
顯得你技術少是不是。
不知道非同步會增加維護成本,提高測試難度嗎?
而且,任務隊裡沒有考慮持久化,趕上釋出,丟了好多工。
>> 沒什麼qps的邊緣介面,做成這樣的非同步模式,看起來是有點殺雞用牛刀了。但是這個事情要結合背景去分析,比如有可能是為了未來的擴充套件需要,有的介面可以預見到請求量會大幅增加。當然,結合整個上下文來看,我更傾向於是這個專案組疏於管理,然後來了一個自恃牛逼的“大拿”,整了一套高大上唬住大夥兒;或者是一個很想在專案中嘗試新東西的小哥,就拿這東西練手了。至於任務隊裡沒有持久化這個一條,依然要看具體的問題,不過通常情況下,如果要設計一個通用的任務佇列,持久化是一個必選項。當然話也不能說死,你是要搞完全不在乎任務丟失的,或者任務排程者可以不斷地重試那些掛掉的任務,於是你不在乎他們丟失的問題——不過想想好像這樣的case挺少的。
讀取一個小小的xml和exc配置檔案,居然用流式解析,沒見過這麼二逼的,真是醉了。
>> 這和上面那個殺雞用牛刀是同一個問題,已經闡述過了。
做優化全靠拍腦門拍大腿,難道不會用excel分析日誌,用jprofile掃專案?
一個100以內的常數集合遍歷,他也要寫個優化演算法進去,演算法跟業務還攪在一起,一團亂麻。
每個人都在嚷嚷效能、演算法、分散式計算……
>> 看起來這裡指的是效能方面的優化,那麼做優化至少包括兩部分,一部分是在設計階段就要分析需求層面的資料推出要“優化”到什麼程度,另一部分才是題主說的根據日誌和已有專案執行的資料“反推 ”(幾年前寫過一點這方面的東西)。當然,無論哪個,都比拍腦門和拍大腿靠譜得多。至於100以內常數集合遍歷,也要寫優化演算法,這有時未必是件壞事,比如大家都在遵循最佳實踐,不過結合上下文看(包括“演算法和業務攪在一起”),我更傾向於是屬於前面已經闡述過的問題。就這種狀況下,每個人都還嚷嚷“效能、演算法、分散式計算”就顯得有點沒抓到主要矛盾了,主要矛盾應該是把這些程式碼最基本的問題給解決了。我記得小時候練習書法的時候,老師批評過我:先不要嘗試那些技巧,先把最基本的橫平豎直給練好了。
幾乎沒有文件,全靠從程式碼反推邏輯。
>> 程式碼和文件經常是對立面,這樣的狀況並不稀奇。我覺得比較可行的做法是,有概要的文件,但是詳細文件往往不現實,即使寫了也難免過時。公司內部的文件太多太多是一坨漿糊。
有列舉他不用,非要在每個頁面上,把列舉值挨個兒寫死,知道後面改程式碼多麼費勁嗎?
>> 欠缺基本的程式設計師素質。
欺騙性的變數名,裡面儲存的是AES加密的,變數名字尾卻寫成了DES;裡面存的是小寫字母,卻寫成upperStr。
一個方法十幾個引數,有三分之一是極其簡略的縮寫,註釋肯定也沒有的。
一個類寫到三四千行是常事。
>> 看到這裡我已經產生無力吐槽的感覺了。
開發自測,居然要把程式碼全丟到公共機器上,而且都是走svn,他們把svn當ftp用。
svn裡面大量的無意義提交,一多半的提交連都編譯不過去。
我看到有個應屆生,改了兩句話,馬上提交,說是怕程式碼丟失。
>> 自測走svn其實不稀奇。就像自己開發一個新功能在git下可以cut一個新的branch,然後開發了,提交了,部署到各種機器上去。不過當ftp用顯然是不對的。“一半多編譯不過去的提交”,這個專案沒有專案管理嗎?開發機上不單元測試嗎?至於“改了兩句話,馬上提交”,沒看出有什麼不妥,只要提交前的測試、review等等通過。
一個執行了兩年的專案,spring的包掃描明顯配錯了,有些bean根本掃不進來,居然沒有人發現。
一半的bean在spring管理下,另一半的bean他們自己寫單例模式來例項化。
>> 第一條依然是專案組疏於管理的佐證。即便是主力程式設計師,也缺少對專案整體的責任感,或者是程式碼爛得讓人難以提起興致。第二條則是一個典型的不好的實踐。有時候可能會需要這樣的妥協,但是居然有一半的bean脫離Spring的管理,那最初引入Spring幹嘛?
他們用mysql來做審計系統,出報表,有個報表要跑8分鐘。
原來是有人用字串來存多值(逗號分隔),sql裡寫了like,導致沒有利用到索引。
為什麼不用pg,pg在sql程式設計方面,功能更豐富,更適合做統計,它本身就支援陣列。
>> 報表跑8分鐘很正常。Sql用字串存多值這個,沒有利用索引,還是要分析具體問題,原則上我不覺得有什麼問題。要想完美解決這個問題,還是在mysql裡面,就得把多值拆解成多行,放到一張新表裡面去。另外,也有一些NoSQL系統天然支援value多值,比如DynamoDB,不過這是題外話。至於為什麼不用pg,這涉及到最初的技術選型,後人看的時候只是說說“如果用xxx就yyy了”當然容易,但是不清楚最初是否有技術層面的考量。當然,這個專案那麼爛,也許是一開始圖方便搞了mysql的prototype就上了。無論如何,有質疑的想法總是值得鼓勵的。
程式設計師們都是得過且過的態度,怎麼把程式碼灌進去,跑的通測試,就算交差了。
為什麼大型網際網路公司,技術和管理這麼差勁,是怎麼形成的?