為什麼有些網際網路公司體量大,技術差?

演算法與數學之美發表於2018-09-17

今年年初,到一家網際網路公司實習,該公司是國內行業龍頭。不過技術和管理方面,卻弱爆了。


那裡的程式設計師,每天都在看郵件,查問題工單。這些問題,多半是他們設計不當,造成的。


程式碼寫的一團糟,全是複製貼上,連作者都沒改,大家普遍不寫註釋,也不格式化,程式碼歪歪扭扭。


一個專案裡,httpclient竟然出現了四種。


  • 一種是該公司研發部寫的,

  • 一種是老版本的開源專案,

  • 一種是新版本的開源專案,

  • 一種是開發人員造的輪子。


打介面請求響應日誌,竟然不知道用攔截器。打錯誤日誌竟然不打上下文資訊,每個人一種日誌風格,千奇百怪。許多重要的中間流程,居然不打日誌。


idea、eclipse、myeclipse的配置檔案竟然全部傳到專案裡去了。


該公司混了兩年的程式設計師,跟快遞公司做查詢介面,竟然不知道加密運單號。


所有服務間通訊,都沒有設requestId,導致跟蹤會話很困難。


一個沒什麼qps的邊緣介面,居然做消費者生產者+阻塞佇列的非同步模式。

顯得你技術少是不是。


不知道非同步會增加維護成本,提高測試難度嗎?


而且,任務隊裡沒有考慮持久化,趕上釋出,丟了好多工。


讀取一個小小的xml和exc配置檔案,居然用流式解析,沒見過這麼二逼的,真是醉了。


做優化全靠拍腦門拍大腿,難道不會用excel分析日誌,用jprofile掃專案?


一個100以內的常數集合遍歷,他也要寫個優化演算法進去,演算法跟業務還攪在一起,一團亂麻。


每個人都在嚷嚷效能、演算法、分散式計算……


幾乎沒有文件,全靠從程式碼反推邏輯。


有列舉他不用,非要在每個頁面上,把列舉值挨個兒寫死,知道後面改程式碼多麼費勁嗎?


欺騙性的變數名,裡面儲存的是AES加密的,變數名字尾卻寫成了DES;裡面存的是小寫字母,卻寫成upperStr。


一個方法十幾個引數,有三分之一是極其簡略的縮寫,註釋肯定也沒有的。一個類寫到三四千行是常事。


開發自測,居然要把程式碼全丟到公共機器上,而且都是走svn,他們把svn當ftp用。


svn裡面大量的無意義提交,一多半的提交連都編譯不過去。


我看到有個應屆生,改了兩句話,馬上提交,說是怕程式碼丟失。


一個執行了兩年的專案,spring的包掃描明顯配錯了,有些bean根本掃不進來,居然沒有人發現。


一半的bean在spring管理下,另一半的bean他們自己寫單例模式來例項化。


他們用mysql來做審計系統,出報表,有個報表要跑8分鐘。


原來是有人用字串來存多值(逗號分隔),sql裡寫了like,導致沒有利用到索引。

為什麼不用pg,pg在sql程式設計方面,功能更豐富,更適合做統計,它本身就支援陣列。


程式設計師們都是得過且過的態度,怎麼把程式碼灌進去,跑的通測試,就算交差了。


為什麼大型網際網路公司,技術和管理這麼差勁,是怎麼形成的?


新手經常會有這樣的想法——「這程式碼怎麼這麼爛?寫的人幹什麼吃的?怎麼能這樣?為什麼不按照書上說的做?」,這很正常,大家都年輕過,經歷過這種階段,我懂你心裡的想法,所以也願意詳細地向你解釋,


這一切發生的原因是什麼?


有人會說


不過技術和管理方面,卻弱爆了。

那裡的程式設計師,每天都在看郵件,查問題工單。

這些問題,多半是他們設計不當,造成的。


你真的覺得『國內行業老大的網際網路公司』會是技術和管理弱爆了的樣子嗎?


你以為團隊應該像永動機,但現實永遠有各種摩擦、輻射、損耗。


內燃機的能量轉化率,通常只有 30% – 50%,但是它卻是驅動全世界運轉的核心引擎,順豐京東的快遞小車、聯通全國的高鐵動車綠皮、瞬時直達的飛機……

機器尚不能 100% 效率運轉,何況是人呢?


你說我們的程式設計師每天都在檢視郵件、問題工單,你說這些問題多半是我們設計不當造成的,請問你有試過統計資料嗎?你大概只是『感覺』如此吧?


事實上,經過十幾年的發展,我們內部的『效率改進團隊』已經非常高效成熟,每月、每週、甚至每天都會有新的改進,現在的業務處理方式,不說全世界,我可以自豪地說在全國我們是領先的,甚至是遙遙領先,不然憑啥坐到了全國龍頭老大的位置呢?


所以啊,你只看到了程式設計師花在業務上的時間,沒看到我們內部的『效率改進團隊』為程式設計師們省掉的時間,我覺得我有必要站出來為默默付出的『效率改進團隊』說幾句。


當然,樓主作為實習生,不知道這些事情進而產生了這些疑問,也暴露了我們的不足。我已經在『團隊建設委員會』裡提出了這個問題,大家一致通過了決議,以後我們會對新員工——包括實習生加強企業文化、歷史培訓,確保我們的新夥伴們不僅知道要去哪兒,也要清楚我們從哪裡來,長路漫漫,我們一同前行。


有人會覺得


程式碼寫的一團糟,全是複製貼上,連作者都沒改,大家普遍不寫註釋,也不格式化,程式碼歪歪扭扭。


當初公司起步的時候,整個專案都是幾個初創程式設計師加班加點熬出來的,我知道你看過《程式碼大全》、《程式設計師修煉之道》、《Unix 程式設計藝術》,你對上面的準則信手拈來,你可否翻開床頭櫃上的這幾本書,看看它們的出版時間呢?


是的,公司起步的時候,這幾本書根本還沒有出版,彼時中國網際網路方興未艾,大家都是摸著石頭過河。現在你遇到問題,你可以問朋友、問導師、用谷歌、用棧溢位、用知乎,我們寫程式那個年代,看的是譚浩強、嚴蔚敏,用的是 52k 撥號上網,語言只有 C,編輯器是沒有語法高亮和實時編譯的,編譯器是沒有智慧準確的報錯的,沒有現在這麼多知識、也沒有這麼多規範和好資源、好工具。不過我們還是把專案做出來了,把公司一步步推到了現在的位置。


不過這個問題是客觀存在的問題,誰也不否認,但是你知道為什麼你被分配到了一個『程式碼看上去一團糟也不夠規範』的專案嗎?我們需要新鮮血液來重構一些老程式碼,所以你會被分配到艱苦的崗位上。我們希望你是勇於戰鬥的戰士,我們更希望你能成長為經驗豐富的老兵,而把你放到這種崗位,是對你來說成長最快的方式。


有人會認為


一個專案裡,httpclient竟然出現了四種。

一種是該公司研發部寫的,

一種是老版本的開源專案,

一種是新版本的開源專案,

還有一種是開發人員造的輪子。


你不知道的是,我們最初用了開源軟體(也就是你所說的『老版本』),它構成了我們早期專案的基石,隨著業務複雜性增加,我們改進並最終切換到新版本。

這個軟體跑老業務非常成熟,但是在一些新業務上有不可調和的矛盾,所以在痛苦的適配後,研發部的同事們自告奮勇用 20% 的時間寫了新業務的元件——是的你沒看錯我們也有 20% 時間,我們鼓勵工程師的創新。


至於你說的開發人員造的輪子——這說起來可真有趣,它其實是前年來的一個清華大學實習生寫的。


當時他來了之後,針對他接手業務的需求,向我抱怨說現有的 3 種都不好,要寫一個新的來『統一天下』,這話是他的原話,我記得非常清楚,因為以我多年經驗來看這樣的做法是不可取的,但是本著鍛鍊年輕人的心態(加上他的確是不可多得的天才),我同意了他的請求,於是我用自己的業餘時間接管了他的大部分工作,全力支援他寫一個新的元件,幫他擋住了所有上面的壓力,後來的故事就是你看到的這樣。


是的,他後來越深入、就越來越感到業務的複雜,不斷推翻重構、拆東牆補西牆,但始終發現和自己想的根本完全不一樣,受不了了就走了,留下來這個。


我們明年的規劃中,就包括剔除這個元件的 codebase,因為它實在是太糟糕了。


又有人會說


打介面請求響應日誌,竟然不知道用攔截器。

打錯誤日誌竟然不打上下文資訊,每個人一種日誌風格,千奇百怪。

許多重要的中間流程,居然不打日誌。

idea、eclipse、myeclipse的配置檔案竟然全部傳到專案裡去了。

該公司混了兩年的程式設計師,跟快遞公司做查詢介面,竟然不知道加密運單號。

所有服務間通訊,都沒有設requestId,導致跟蹤會話很困難。


攔截器並不如你所想的那班美好,也許你在自己的電腦上寫過一些玩具程式碼,覺得這樣很方便、酷炫,但是真正到了戰場,你會發現沒什麼才是必須的、好的,只有適合的才是對的。


至於配置檔案,這麼說吧,IDE 的配置檔案傳到程式碼倉庫是我定下的規矩,『怎麼會有人定這樣的規矩?』,是的你可能從軟體工程的教科書上或者某些『知名部落格』上讀到了不能這樣做,但實際上這樣做在很多情況下是必須的。

原因何在?


這樣可以確保程式碼克隆即可用,而不是讓每個人都去設定一大堆無聊的東西,這樣不僅節省時間,也確保了每個人的環境一致性,你想想這幾年火熱的 docker,應該明白了這樣做的正確性和必要性了吧?


你可能會說即便如此、外掛也不用上傳到伺服器儲存,我告訴你這樣是不行的,你要考慮到我們這個專案前後十餘年,你覺得幾個外掛能堅挺十餘年?很可能我們早期用的軟體,現在你已經完全不可能找到了,所以儲存一份備份是非常有必要的,決不能錯誤地認為是冗餘。


教科書只會教你基本通用的原則,樹立你基本正確的觀念,但是如果只是死守教條,如何能擁抱日益複雜的變化呢?


你看的教科書,且不說時間上已經是二十多年前的了,在適用性上,也不說就是真理,IT 行業發展日新月異,幾個月就是滄海桑田,為了適應這樣的變化,認真地思考、總結、判斷才是最重要的。


有人會覺得


一個沒什麼qps的邊緣介面,居然做消費者生產者+阻塞佇列的非同步模式。

顯得你技術少是不是。

不知道非同步會增加維護成本,提高測試難度嗎?

而且,任務隊裡沒有考慮持久化,趕上釋出,丟了好多工。

讀取一個小小的xml和exc配置檔案,居然用流式解析,沒見過這麼二逼的,真是醉了。


你大概不知道,當初跑在你口中的「一個沒什麼qps的邊緣介面」上面的業務帶來了公司曾經 90% 的收入,所以我們用了複雜的設計以應對當時的需求,當然現在業務轉變,老系統不再需要處理那麼多業務了,但是更沒有理由為一個『works perfectly well』並且不再重要的業務重構程式碼吧?


所以,不是我們秀技術,而是業務需求 + 業務變更使然,年輕人還需要多學習一個。


有人會抱怨


做優化全靠拍腦門拍大腿,難道不會用excel分析日誌,用jprofile掃專案?

一個100以內的常數集合遍歷,他也要寫個優化演算法進去,演算法跟業務還攪在一起,一團亂麻。

每個人都在嚷嚷效能、演算法、分散式計算……

幾乎沒有文件,全靠從程式碼反推邏輯。

有列舉他不用,非要在每個頁面上,把列舉值挨個兒寫死,知道後面改程式碼多麼費勁嗎?

欺騙性的變數名,裡面儲存的是AES加密的,變數名字尾卻寫成了DES;裡面存的是小寫字母,卻寫成upperStr。

一個方法十幾個引數,有三分之一是極其簡略的縮寫,註釋肯定也沒有的。

一個類寫到三四千行是常事。


我再強調一次——我們是全中國同類公司中技術能力第一的,你所說的問題,當然是不存在的。


我們有專門的 Hadoop 叢集來分析日誌,當然也就用不著 Excel 了。


對於我們這種體量的公司來說,不存在什麼『常數集合』,程式碼必須用合適的資料結構——這是常識吧?


特殊的演算法和業務摻雜以增加內聚性,這是我們多年的經驗,的確,它和教科書上說的不一樣,但是我前面說了,死守教條是不行的——想必你一定知道 OSI 7 層網路模型吧?


公司的技術氛圍濃厚,是和公司的基因分不開的,我們公司最重要的原則就是——『擁抱變化』,從十幾年前的機房託管單機到現在的龐大自建叢集,技術躍遷了何止千萬裡,所以每個人都在學習新知識、每個人都沉浸在新知識的喜悅中。


你的問題,大多都是因為沒有考慮到公司的龐大體量和十幾年的技術躍遷才有的疑問,這點不再贅述,自行體會吧。


有人想的是


開發自測,居然要把程式碼全丟到公共機器上,而且都是走svn,他們把svn當ftp用。

svn裡面大量的無意義提交,一多半的提交連都編譯不過去。

我看到有個應屆生,改了兩句話,馬上提交,說是怕程式碼丟失。

一個執行了兩年的專案,spring的包掃描明顯配錯了,有些bean根本掃不進來,居然沒有人發現。

一半的bean在spring管理下,另一半的bean他們自己寫單例模式來例項化。


其實那不是 SVN,那是我們公司自主研發的適應我們內部需求的 原始碼管理系統 和 檔案管理系統,你可以往裡面放任何東西。


你所說的「無意義提交、一多半的提交連都編譯不過去」其實只是表象,這套系統代號 TITAN,它自帶 CIDD(持續繼承、交付、部署),所以這些無法編譯的提交都是不會有機會走到下一步流程的的。


如果你工作了一年,你就會發現這個需求是很重要的,改動、尤其是大型改動,中間會有很多非可用但有需要存檔的步驟,現有的原始碼管理系統都不能很好地支援這些需求,因此你也被教育了一套適應落後工具的思想。人啊,最重要的能力是改進工具,所以用 TITAN 的時候要擁抱全新思維,不要被落後思維捆綁。


如果你工作了幾年,你可能還會問為什麼我們沒用 Jenkins、Travis 等工具,其實呀,就在 TITAN 之中呀,它凝結了公司最優秀的人才的十幾年寶貴經驗和心血。

By the way,我們最近正計劃開源它,為中國開源社群做貢獻,也希望提高業界的綜合素質。歡迎你提交 PR 哦。


最後又有人說了


他們用mysql來做審計系統,出報表,有個報表要跑8分鐘。

原來是有人用字串來存多值(逗號分隔),sql裡寫了like,導致沒有利用到索引。

為什麼不用pg,pg在sql程式設計方面,功能更豐富,更適合做統計,它本身就支援陣列。

程式設計師們都是得過且過的態度,怎麼把程式碼灌進去,跑的通測試,就算交差了。

為什麼大型網際網路公司,技術和管理這麼差勁,是怎麼形成的?


為什麼不用 pg?如果你抱著這種想法,那用了 pg 也要被噴的,到時候就就會說 —— 「為什麼不用 sqlite,輕量簡單,搞這麼複雜真的有必要嗎?」,真的有必要。。。


這只是一個很簡單的系統,做的事情也很簡單,當初做這個系統的同事更熟悉 MySQL,當然 MySQL 是不二之選了,對於簡單的東西,追求的是開發速度、使用便利性。


你覺得一個月跑一次的審計程式碼,8 分鐘有什麼問題嗎?就算是一週跑一次,當然也是沒問題的。


程式設計師的單位時間是如此寶貴,為了優化一段一個月跑一次的 8 分鐘程式碼,值得花費數天的時間來做這件事嗎?


重複一遍,你的問題,大多都是因為『沒有考慮到公司的龐大體量和十幾年的技術躍遷才有的疑問』,這點不再贅述,還請自行體會。


當然,年輕人樂於思考,這是好事,是希望,新鮮血液替換老舊部件系統才能健康發展成長,人如此、公司如此、國家也是如此。


希望你勤于思考,努力學習,有問題的話,我們公司是鼓勵同事們向 CEO、CTO 寫信的,不然也不會有 CEO、CTO 信箱了你說對嗎?


當然,這樣的技術性問題、你寫給我就好,CEO 是船長,不需要關心底層鍋爐房的細節。


另外我想補充一下我的想法,希望對你有所幫助。

 

你看你都沒說加班問題,我們公司沒加班啊,這多好,怎麼做到激烈競爭下還能不加班的?都虧了公司老領導和元老們的一手決策


所以我想補充的不是技術問題,技術問題都不是問題,年輕人可以學習、交流,技術都會很快成長,畢竟年輕人的衝勁大、頭腦靈活。


我想說的是整體觀、大局觀、大棋戰略。

 

黃金的導電性最好,為什麼電腦主機板還要用銅?

清華大學最好,為什麼有人要去普通學校?

飛機最快,為什麼還有人坐火車?


因為資源都是有限的,我們在現實生活中——而不是教科書上——必須兼顧成本和產出的平衡。

 

你問我每行程式碼都多人多層人工 review 好不好?問我支不支援?我說好,review 我怎麼能不支援呢?我今天在知乎這個公眾平臺我明確說了我支援。


但是你也應該多學習一個,這個現實畢竟是現實,我們要兼顧各種考量。


你今天在這裡渲染「大公司技術和管理這麼差勁」,是不對的、是失實的、是欠妥的、是缺乏認真思考的、是未加深入考量的。


將來輿論出了偏差,你雖然不用負責任,但是你認識到自己的錯誤的時候,會後悔、會內疚、會難過的吧?


何處烏托邦?或許……等下一代?


總結就是,生產效率才是最重要的,世間萬物最重要的是平衡。


怎樣取捨、如何妥協,這不僅是大自然的規律,也是我們前進、發展的準繩和仰仗的原則。

 

對於這個問題,下面是一種回答:


題主你看到了很多槽點,但我認為你不能只看到槽點和大概怎麼解決。有沒有想過怎麼改進,如果是你的話你怎麼做,這些專案裡面臨的主要挑戰是什麼,次要的挑戰又是什麼?


不要只告訴我技術A弱爆了,用B就可以完爆這個專案了。你知道用B的優劣,B的適用場景以及適用B的成本嗎?對於一間公司來說,成本是很重要的。我這裡說的成本不是金錢。而是,假如你看不爽一份程式碼,你打算重構它,你覺得你需要投入多少時間,多少人力?重構之後,又要花費多少時間和人力去升級依賴這份程式碼的其他專案?不要以為開會無用,老闆就只是在天天發郵件。如果你重構了一份程式碼,不能通過溝通說服其他組去升級他們的元件,又或者你只是重構了一份雖然很醜陋,但其實並沒有多少程式依賴它的程式碼,又又或者你重構了程式碼只是讓程式碼技術含量更高了,更好看了,卻沒給公司帶來多少收入甚至KPI,那你的工作和成果就很尷尬了。


其實上述也解釋了為什麼你身邊的同事都眼睜睜地看著這些醜陋的shit存在而無動於衷。因為他們也是需要投入成本的。先不論他們個人技術水平高低,試問誰願意挑一個又艱難,又不能產生多少效益的任務去做?當然,你會說,寫好程式碼是程式設計師的節操。抱歉,節操多少錢一斤,北京三環商品房多少錢一平?


程式設計高手都有真愛,但現實就是程式設計高手鳳毛麟角。我們身邊的大部分同事可能只是希望養家餬口,他們頭上還掛著十幾個bug等著修。我們數落他們沒追求,但追求從來都不是嘴上說說,吐吐槽就能實現的。


人心如此,公司也如是。


矛盾分主次,公司的目標都是一樣的:用最少的成本投入到最能產生效益的專案中去,或者投入大成本去解決公司最需要解決的問題,這間公司才能繼續運作。


所以題主你想想,在你吐槽的個案中,有多少是公司真正關心的?有哪些是你的老闆認為可以創造最大效益的?有哪些才是主要矛盾或者挑戰需要最牛逼的人挺身而出第一時間解決?去辨別,解決這些關鍵的問題吧,騷年。必要時帶上(忽悠)一隊人馬(同事)跟你一起幹,苟富貴,勿相忘。不要像祥林嫂一樣,天天抱怨著生活,日日思考著辭職。得罪點說一句:


“淪落”到要跟這樣的人共事工作,難道自己身上就沒有原因?


這個世界有更好的公司,有更牛逼的人。如果你認為解決這間公司的這堆問題不值得,又或者同事實在太不給力,就遠走高飛吧。


我以前也跟題主一樣,看我第一份正式工作的很多技術環節都相當不爽。這份程式碼寫得醜,那個設計像大學生作品,重要的專案居然連單元測試都沒有……但是我後來反觀我自己,並沒有發現比起那些醜陋程式碼和糟糕實現強悍多少。我跟我的同事沒有質的區別。我笑話他們程式碼混亂bug不盡,我何嘗不是少處理了一個field,倒騰錯了一個片段的資料搞到要翻工重跑?在我心底裡艹了隔壁組那個“我的程式好像不能跑,你幫我debug下”的同事一千次之後,帶我做ML讓我倒騰資料並且被我的程式搞壞了幾份資料(當然後來搞好了)的T9君在會議上說:“她已經很努力了,我承認我有時候也逼得她太緊,她應該有多些時間的。”


來自:http://www.techug.com


更多精彩:

☞  哈爾莫斯:怎樣做數學研究

☞  祖克伯2017年哈佛大學畢業演講

☞  線性代數在組合數學中的應用

☞  你見過真的菲利普曲線嗎?

☞  支援向量機(SVM)的故事是這樣子的

☞  深度神經網路中的數學,對你來說會不會太難?

☞  程式設計需要知道多少數學知識?

☞  陳省身——什麼是幾何學

☞  模式識別研究的回顧與展望

☞  曲面論

☞  自然底數e的意義是什麼?

☞  如何向5歲小孩解釋什麼是支援向量機(SVM)?

☞  華裔天才數學家陶哲軒自述

☞  代數,分析,幾何與拓撲,現代數學的三大方法論

640?wx_fmt=png

演算法數學之美微信公眾號歡迎賜稿

稿件涉及數學、物理、演算法、計算機、程式設計等相關領域,經採用我們將奉上稿酬。

投稿郵箱:math_alg@163.com

相關文章