<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>
"); //-->

博客專(zhuān)欄

EEPW首頁(yè) > 博客 > 12 年的祖傳“屎山”代碼,年收入竟超 1.4 億元?程序員勸“接盤(pán)俠”:趕緊退退退!

12 年的祖傳“屎山”代碼,年收入竟超 1.4 億元?程序員勸“接盤(pán)俠”:趕緊退退退!

發(fā)布人:AI科技大本營(yíng) 時(shí)間:2022-10-20 來(lái)源:工程師 發(fā)布文章
整理 | 鄭麗媛

出品 | CSDN(ID:CSDNnews)

講道理,許多做過(guò)代碼屆“接盤(pán)俠”的程序員們,某種程度上可能十分理解電影中執著(zhù)于毀滅世界的反派:“與其在現有基礎上修改,還不如直接把這堆祖傳代碼毀滅再重建!”

祖傳代碼,從字面意思來(lái)看,就是一代代老程序員們留下來(lái)的“寶藏”代碼——這些長(cháng)年累月的代碼中存有很多隱患,后來(lái)的“接盤(pán)俠”們要么無(wú)從下手,要么一改就崩,幾乎可以說(shuō)是程序員們的“終極噩夢(mèng)”,因此也被稱(chēng)作“屎山代碼”。

這不,最近又有一個(gè)“倒霉蛋”火上了 HN 熱榜:“我繼承了我見(jiàn)過(guò)的最差的代碼和技術(shù)團隊,該怎么辦?”

圖片


圖片

擁有 12 年歷史、沒(méi)有版本控制的“祖傳代碼”


從這位“接盤(pán)俠” @whattodochange 闡述的現狀來(lái)看,他這次繼承的代碼歷史長(cháng)達 12 年,是沒(méi)有版本控制的 PHP 代碼,居然每年還能產(chǎn)生超過(guò) 2000 萬(wàn)美元(約人民幣 1.4 億元)的收入:

  • 這些代碼每年能產(chǎn)生超過(guò) 2000 萬(wàn)美元的收入。

  • 運行在 PHP 上。

  • 已經(jīng)在生產(chǎn)環(huán)境直接開(kāi)發(fā)了 12 年,沒(méi)有源代碼控制(都是像 index-new_2021-test-john_v2.php 這種)。

  • 沒(méi)有使用 composer 或任何依賴(lài)管理,都是 require_once。

  • 沒(méi)使用任何框架。

  • 路由管理完全是在 NGInX 中重寫(xiě)的(NGInX 的配置大約是 10000 行)。

  • 這些年只在不斷往上堆代碼,沒(méi)刪除任何代碼(我推測這是因為代碼是直接在生產(chǎn)環(huán)境開(kāi)發(fā)的,刪東西太危險了)。

  • 數據庫結構也是一片混亂,沒(méi)有遷移等等。要添加一個(gè)列時(shí),由于數據量大,他們一般會(huì )建一個(gè)新表,然后用 join。

  • JS 和 CSS 也是如此。jQuery 的不同版本互相打架,具體取決于你在哪個(gè)頁(yè)面,有時(shí)甚至同一個(gè)頁(yè)面也會(huì )有。

  • 當然沒(méi)有 MVC 模式或其他模式什么的,沒(méi)有模板庫。這是 PHP 2003 的樣式。

  • 在很多地方,我看到像是 Controller 一樣的文件,向它自己的 rest API 發(fā)出 curl 請求(通過(guò)域名而非 localhost)進(jìn)行 oauth 授權等…然后只是為了獲取菜單項或產(chǎn)品列表。

  • 沒(méi)有緩存(但有 memcached ,但只用于 Session…)。

  • 團隊只有 3 個(gè)很年輕的人,一個(gè)后端,一個(gè)前端,一個(gè) iOS/android ,他們對代碼變革非常抵觸。

  • 生產(chǎn)力很差,這可以理解——亂七八糟的東西實(shí)在是太多了,根本沒(méi)辦法做新東西。

以上就是 @whattodochange 目前所接盤(pán)的代碼和團隊現狀,他頭疼道:“我必須要找到一個(gè)策略來(lái)修復這個(gè)開(kāi)發(fā)團隊?!?/span>

面對這個(gè)“爛攤子”,@whattodochange 想到的解決辦法是完全重寫(xiě),但由于公司管理層和總部對這些阻礙因素并沒(méi)有真正了解,業(yè)務(wù)部門(mén)對這個(gè)項目有非常積極的規劃路線(xiàn),且疫情之下公司的預算很緊張,導致 @whattodochange 根本無(wú)法推進(jìn)。

因此,@whattodochange 發(fā)帖求助:“我知道完全重寫(xiě)是必要的,但要如何平衡?”


圖片

逐一改動(dòng) or 擺爛跑路?


對于 @whattodochange 的遭遇,不少有經(jīng)驗的程序員深有同感,也提出了一些應對“祖傳代碼”的具體建議。

“完全重寫(xiě)不是必需的,甚至可能是最糟糕的方法??梢砸淮巫鲆患?,最終你會(huì )重寫(xiě)所有代碼,但永遠不會(huì )陷入‘完全重寫(xiě)’的陷阱中。

不過(guò)在重寫(xiě)一行代碼之前,記得要做大量的測試。如果有端到端測試,這些測試運行在客戶(hù)群當前使用的每個(gè)功能中,那么您就有一個(gè)基線(xiàn)來(lái)安全地進(jìn)行更改。只要測試通過(guò),就可以刪除代碼。

不要想著(zhù)去推動(dòng)變革,嘗試擁抱這個(gè)每年賺 2000 萬(wàn)美元的可怕代碼庫,和團隊討論討論如何在能力范圍內改進(jìn)即可?!?br />

作為這個(gè)開(kāi)發(fā)團隊的經(jīng)理,你的任務(wù)是要得到高管支持來(lái)逐漸解決這個(gè)爛攤子。你沒(méi)必要告訴高管或團隊具體要如何修復,只要有時(shí)間和空間上的支持就好。

有一種辦法是每周五集合團隊一起來(lái)測試,但可能會(huì )經(jīng)常被緊急任務(wù)擠掉;另一種辦法是讓每個(gè)更新的發(fā)布速度稍慢一些,這樣就有時(shí)間優(yōu)化每次更新所涉及到的其他代碼。例如,業(yè)務(wù)要求添加功能 X,那么你就給相關(guān)的現有功能 Y 添加一個(gè)測試,可以對團隊說(shuō)優(yōu)化 Y 是為了讓添加 X 更為方便?!?/span>

不過(guò),也有部分程序員在了解 @whattodochange 的現狀后,認為“擺爛跑路”是最優(yōu)解:

“你應該考慮辭職。雖然你知道這代碼很爛,但它確實(shí)能帶來(lái)每年 2000 萬(wàn)美元的收入,所以你的團隊不想變革,業(yè)務(wù)人員也不會(huì )關(guān)心代碼質(zhì)量。他們會(huì )認為:反正 2003 年樣式的 PHP 代碼就可以實(shí)現這個(gè)收入,那不挺好,干嘛要浪費財力和精力去重寫(xiě)?

最后,你很難說(shuō)服你的開(kāi)發(fā)團隊和業(yè)務(wù)部門(mén)同意重寫(xiě)這個(gè)決定,甚至還會(huì )招來(lái)仇視,而你自己也會(huì )討厭這樣的工作氛圍?!?/span>

“為了避免自己受傷,我勸你擺脫這種混亂的處境。我之前也一直處于類(lèi)似的情況,花了快五年的時(shí)間試圖解決,但最后還是心累地放棄了?!?/span>


圖片

血淚教訓:“人跟代碼有一個(gè)能跑就行了”


其實(shí)在現實(shí)中,幾乎所有軟件開(kāi)發(fā)公司都有各種老大難的“祖傳代碼”,像 @whattodochange 遇到這種 12 年歷史的都還算年輕的了——一般越大規模越厲害的公司,“屎山”代碼的情況越嚴重。

  • 《GTA 5》聯(lián)機版中循環(huán) 19.8 億次的 if 語(yǔ)句,被許多人稱(chēng)作游戲開(kāi)發(fā)史上最大的“屎山”代碼,存在了 7 年 R 星(游戲開(kāi)發(fā)商 RockStar)的程序員無(wú)人敢動(dòng)。最終,還是一位黑客大哥看不下去給出了解決方案,R 星這才官宣要修復 bug,并給這位黑客獎勵了 1 萬(wàn)美元。

  • 一位亞馬遜工程師也曾形容他們公司的代碼為:“一座很大的屎山,一座你見(jiàn)過(guò)的最大的山,每次你想修正一個(gè) bug,都得爬到屎山的正中央去?!?/span>

類(lèi)似地,國內也有許多程序員分享過(guò)他們遇到的各種“骨灰級”祖傳代碼:

  • “公司代碼已經(jīng) 40 年了,最早寫(xiě)代碼的人不知道是否活著(zhù),要命的是文檔沒(méi)留下,項目代碼堆在一起能有 90 多 G?!?/span>

  • “我要升級的那批代碼寫(xiě)于 2000 年前,最早的部分可能寫(xiě)于 1980 年代貝爾實(shí)驗室。第一批維護升級做需求的人早就退休了,第二批也退休了,每一行代碼動(dòng)起來(lái)都膽戰心驚?!?/span>

  • “曾經(jīng)在 Visa 工作過(guò),感覺(jué)什么 10 年 20 年的代碼簡(jiǎn)直 naive,你見(jiàn)過(guò) 1965 年的代碼嗎?第一次看到簡(jiǎn)直驚呆了,這半個(gè)世紀的代碼現在還在用還跑的好好的?”

可能對于很多剛工作的萌新程序員來(lái)說(shuō),看見(jiàn)這些各處都埋著(zhù)“地雷”的代碼第一反應就是“推倒重來(lái)”,但大多都得到了血淚教訓:“有的時(shí)候,代碼能運行就不要嘗試去改,哪怕是遇到屎山一樣的代碼”,可能還會(huì )對新人建議道:“人跟代碼有一個(gè)能跑就行了?!?/span>

那么,你是否在工作中遇見(jiàn)過(guò)令人發(fā)指的“祖傳代碼”,最長(cháng)擁有多少年歷史?你是選擇逐一改動(dòng)還是放任不管?

參考鏈接:

  • https://news.ycombinator.com/item?id=32883596

  • https://www.zhihu.com/question/272065178


*博客內容為網(wǎng)友個(gè)人發(fā)布,僅代表博主個(gè)人觀(guān)點(diǎn),如有侵權請聯(lián)系工作人員刪除。



關(guān)鍵詞: AI

相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>