高中的時(shí)候,我覺(jué)得當(dāng)黑客很帥氣,心生向往,結(jié)果選擇了看起來(lái)能成為黑客、事實(shí)上只可能被黑客攻擊的計(jì)算機(jī)專(zhuān)業(yè)。2020年大學(xué)畢業(yè)時(shí),看到華為面對(duì)制裁很“剛”、很酷,于是不假思索地選擇了華為,來(lái)到成研,成為了一名真正的程序猿,體會(huì)到了什么是“休閑向左,成研向右”。 經(jīng)過(guò)1年半的努力,我成了數(shù)據(jù)管理產(chǎn)品部OM(操作維護(hù))開(kāi)發(fā)部的MDE(模塊設(shè)計(jì)師)和Committer,開(kāi)始了和代碼過(guò)招的日常。 “菜鳥(niǎo)”的不知所措:一天問(wèn)800遍“是這樣嗎” 時(shí)間撥回2020年的夏天,當(dāng)我還沉浸在晨練、紅白文化衫以及“物質(zhì)激勵(lì)重要還是精神激勵(lì)重要”的辯論中時(shí),突然發(fā)現(xiàn)自己成了數(shù)據(jù)存儲(chǔ)OM開(kāi)發(fā)部最年輕的開(kāi)發(fā)人員,擺在我面前的是一個(gè)完全陌生且復(fù)雜的業(yè)務(wù)領(lǐng)域。到現(xiàn)在我都能清晰地回想起來(lái),自己面對(duì)數(shù)以十萬(wàn)計(jì)的代碼以及復(fù)雜的服務(wù)之間的關(guān)系時(shí),那種不知所措、無(wú)從下手的茫然感。 我接手的第一個(gè)需求是操作系統(tǒng)切換的需求,涉及到新操作系統(tǒng)的適配以及python2、python3的兼容。現(xiàn)在看來(lái)只是不到500行的小需求,但是對(duì)一個(gè)對(duì)linux的了解只局限在cp、cd、mkdir命令的萌新、一個(gè)對(duì)所有需要改動(dòng)的python腳本功能都不了解的新員工來(lái)說(shuō),我的壓力是難以言說(shuō)的。 那段時(shí)間,我每天晚上都難以入眠,總覺(jué)得自己能力不足,難以梳理如此復(fù)雜的業(yè)務(wù),沒(méi)辦法按時(shí)高質(zhì)量地交付,無(wú)時(shí)無(wú)刻不在思考如何才能完成業(yè)務(wù)。每天走在上班的路上,我就忍不住胡思亂想:昨天的代碼在聯(lián)調(diào)中有沒(méi)有發(fā)現(xiàn)問(wèn)題?今天的工作能不能按時(shí)完成?那段時(shí)間,我每天問(wèn)自己、問(wèn)別人最多的就是:這個(gè)地方是這樣的嗎?那個(gè)地方我理解得有問(wèn)題嗎? 組內(nèi)的同事給了我無(wú)限的包容。每次遇到一個(gè)問(wèn)題,不論再忙,總有人幫我出主意,給出解決方案。隨著“為什么”一個(gè)一個(gè)地減少,需求也進(jìn)入了聯(lián)調(diào)階段。我所焦慮的問(wèn)題也從“怎么實(shí)現(xiàn)”變成了“怎么定位解決當(dāng)前遇到的問(wèn)題”。 由于這個(gè)需求是系統(tǒng)層面的適配,很多問(wèn)題要在聯(lián)調(diào)階段實(shí)際測(cè)試中發(fā)現(xiàn),加之我們模塊又是整個(gè)分布式存儲(chǔ)的入口,某種程度上我們的角色就是個(gè)“守門(mén)員”,需要了解每個(gè)問(wèn)題。因此,遇到問(wèn)題,我會(huì)先查找相關(guān)代碼,然后再跟組內(nèi)的“老人”確認(rèn),是否跟我理解得一致,確認(rèn)測(cè)試同事提出的問(wèn)題是不是真的問(wèn)題,或者將問(wèn)題轉(zhuǎn)給對(duì)應(yīng)模塊的人確認(rèn),最后記錄到筆記本中。 隨著時(shí)間的推移,需求越來(lái)越多,我定位的問(wèn)題也越來(lái)越多,盡管還是會(huì)碰到各種各樣不知道的技術(shù),偶爾也會(huì)掉進(jìn)沒(méi)有踩過(guò)的坑里,但是看著筆記中越來(lái)越多的常見(jiàn)命令、常見(jiàn)問(wèn)題,我已經(jīng)不再焦慮,反而覺(jué)得這些問(wèn)題越發(fā)可愛(ài)起來(lái),逼著我不斷成長(zhǎng)。 隨著積累越來(lái)越多,我發(fā)現(xiàn)自己可以解答不少問(wèn)題了,也能夠?yàn)樾枨蟮母哔|(zhì)量交付貢獻(xiàn)一份我的力量了。 終于有底氣說(shuō)“這個(gè)問(wèn)題我知道” 經(jīng)過(guò)半年多的“打怪升級(jí)”,我在日常問(wèn)題的處理上已經(jīng)得心應(yīng)手。但我覺(jué)得,這樣還遠(yuǎn)遠(yuǎn)不夠,我經(jīng)常打開(kāi)問(wèn)題列表,查看組內(nèi)的常見(jiàn)問(wèn)題,思考每個(gè)問(wèn)題為什么會(huì)發(fā)生,怎樣做才能避免發(fā)生這樣的問(wèn)題??吹膯?wèn)題越來(lái)越多,了解的業(yè)務(wù)越來(lái)越多,我開(kāi)始有底氣說(shuō)出“這個(gè)問(wèn)題我知道”。 一天,我正準(zhǔn)備修改一個(gè)不太復(fù)雜的安全單,突然發(fā)現(xiàn),這個(gè)發(fā)送LLDP(鏈路層發(fā)現(xiàn)協(xié)議)報(bào)文的小模塊看起來(lái)并不簡(jiǎn)單。這是一個(gè)定制化開(kāi)發(fā)的模塊,平時(shí)不會(huì)使用,也沒(méi)人關(guān)注,但卻是重點(diǎn)客戶(hù)采購(gòu)規(guī)范里“指名道姓”的功能。 當(dāng)我上手這一模塊的時(shí)候,有一種“不祥”的預(yù)感。果不其然,當(dāng)我輕車(chē)熟路地修改完安全問(wèn)題并進(jìn)行測(cè)試的時(shí)候,驚訝地發(fā)現(xiàn),這個(gè)從老版本直接同步過(guò)來(lái)的模塊,根本沒(méi)有適配切換python3之后的操作系統(tǒng),換言之,這個(gè)模塊在當(dāng)前版本軟件配套的操作系統(tǒng)上完全不能運(yùn)行。 本來(lái)2個(gè)小時(shí)的工作量突然就變成為未知。此時(shí)我還是很樂(lè)觀(guān),覺(jué)得自己應(yīng)該可以快速搞定,因?yàn)閜ython2和pyhton3之間的差異我并不陌生。但當(dāng)我根據(jù)之前的經(jīng)驗(yàn)修改完代碼,放到新的操作系統(tǒng)上調(diào)測(cè)時(shí),發(fā)現(xiàn)雖然程序已經(jīng)能夠不報(bào)錯(cuò)運(yùn)行,但是表現(xiàn)卻跟在舊的操作系統(tǒng)上面不盡相同。顯然,已有的經(jīng)驗(yàn)并沒(méi)有幫我解決這個(gè)問(wèn)題。 這是一個(gè)直接工作在鏈路層的協(xié)議,我平常很少接觸。不過(guò)不熟悉不代表我會(huì)慫,我沒(méi)有害怕,而是仔細(xì)走讀代碼,搜集相關(guān)資料。很快,我就發(fā)現(xiàn),代碼中報(bào)文生成的部分是直接使用的二進(jìn)制內(nèi)容書(shū)寫(xiě)的,而python在兩個(gè)大版本之間,在編碼方式上的確有很大的不同。于是,我根據(jù)這個(gè)思路,重點(diǎn)審視協(xié)議報(bào)文生成部分的代碼。果不其然,重新修改后,我再在python2、3的環(huán)境上分別運(yùn)行這個(gè)模塊,報(bào)文格式、內(nèi)容完全相同。這意味著問(wèn)題已經(jīng)解決了! 但是對(duì)于一個(gè)完整功能模塊來(lái)說(shuō),需要端到端的驗(yàn)證才能保證功能完全正常。對(duì)于LLDP報(bào)文發(fā)送模塊來(lái)說(shuō),這就需要在交換機(jī)上查看對(duì)應(yīng)報(bào)文才能保證功能完全正常。提著一口氣,我第一次登陸完全沒(méi)有接觸過(guò)的交換機(jī),使用剛剛搜索到的命令查看到了這個(gè)模塊LLDP報(bào)文,很快就放下心來(lái)——問(wèn)題解決了!這個(gè)“逍遙法外”許久的功能被我成功逮捕,成為了前端測(cè)試用例庫(kù)里的又一個(gè)例行執(zhí)行的用例。 “代碼質(zhì)量好,回家回得早”成了團(tuán)隊(duì)的共識(shí) 作為一個(gè)典型的程序猿,我一直都有著代碼潔癖。雖然是大學(xué)才接觸編程,但是卻很享受將想法變成一個(gè)個(gè)程序的感覺(jué)。大學(xué)期間,我開(kāi)始閱讀各式技術(shù)書(shū)籍,從《Java核心技術(shù)》到《Thinking in Java》,從《設(shè)計(jì)模式之禪》到《重構(gòu)》,每本都如數(shù)家珍。入職后,在快速熟悉業(yè)務(wù)代碼之余,我也依舊沒(méi)有放下閱讀技術(shù)書(shū)籍的習(xí)慣,并時(shí)常思考如何才能將書(shū)中的知識(shí)轉(zhuǎn)換為能力,如何才能寫(xiě)好代碼。入職6個(gè)月后,憑借著對(duì)業(yè)務(wù)的熟悉和對(duì)代碼的追求,我被任命為OM團(tuán)隊(duì)內(nèi)部最年輕的committer。 當(dāng)我第一次看到自己的名字出現(xiàn)在正式的任命文件上的時(shí)候,難免有些欣喜,但是也覺(jué)得壓力頗大。原來(lái)作為軟件工程師的我,只需要管好自己的一畝三分地,做好測(cè)試自驗(yàn)證,保證自己的代碼clean就可以了。但是作為committer,就要對(duì)組內(nèi)的代碼負(fù)責(zé),需要看護(hù)好每一個(gè)經(jīng)手的MR(合并請(qǐng)求)。再加上,我的組內(nèi)全是前輩,面對(duì)他們的MR,我應(yīng)該怎么辦呢? 一時(shí)間,巨大的壓力如同一張巨大的網(wǎng)將我包裹起來(lái),讓我不知所措。說(shuō)來(lái)也巧,當(dāng)時(shí)正要進(jìn)行安全送檢,我承擔(dān)了安全排查的工作,一下感覺(jué)找了抓手。我梳理出100多個(gè)已有腳本,發(fā)現(xiàn)了30多個(gè)問(wèn)題,總結(jié)出常見(jiàn)提取模式、命令注入等共性的安全問(wèn)題,在組內(nèi)開(kāi)展多次培訓(xùn)。與此同時(shí),在代碼檢視中,我也提出了很多關(guān)鍵問(wèn)題,將問(wèn)題攔截在最前端。 慢慢的,大家從被動(dòng)的必須讓我檢視才能合入,變成了驗(yàn)證前先找我檢視看看有沒(méi)有“踩坑”。這時(shí)候,我就知道,大家已經(jīng)認(rèn)可了我的能力。 接下來(lái),以肉眼可見(jiàn)的速度,大家代碼越來(lái)越直觀(guān)漂亮,安全問(wèn)題顯著減少。而且,大家還經(jīng)常一起討論,這個(gè)地方提到公共類(lèi)是否更加合適,那個(gè)地方多加一個(gè)換行是不是結(jié)構(gòu)更加清晰的一些“小事”。 不過(guò),這些“小事”在面對(duì)版本交付壓力的時(shí)候,突然變成了大事。在距離分布式存儲(chǔ)產(chǎn)品的最新版本發(fā)布不到兩周的時(shí)候,PL(項(xiàng)目主管)找到我,說(shuō)在超大集群規(guī)模下,版本升級(jí)必然失敗,需要緊急定位分析,解決問(wèn)題。 經(jīng)過(guò)分析,我發(fā)現(xiàn)問(wèn)題了所在。模塊里面包含一個(gè)從Excel文件讀取配置信息的功能,代碼邏輯極其復(fù)雜,以前就是一個(gè)黑盒,沒(méi)有人改動(dòng)代碼,也沒(méi)有人知道里面的功能實(shí)現(xiàn)。從模塊誕生之初,這段代碼就平穩(wěn)地在系統(tǒng)中運(yùn)行。但是隨著版本的演進(jìn),集群規(guī)模愈發(fā)擴(kuò)大,單個(gè)單元格需要承載的內(nèi)容越來(lái)越多。在新版本中,單集群需要支持超過(guò)5000個(gè)節(jié)點(diǎn),而當(dāng)Excel中單個(gè)單元格字符長(zhǎng)度超過(guò)32767時(shí),讀取Excel的三方類(lèi)就會(huì)直接報(bào)錯(cuò)。 解決這個(gè)問(wèn)題有兩個(gè)選擇,一是直接修改對(duì)應(yīng)的類(lèi),對(duì)超長(zhǎng)的單元格進(jìn)行拆分,只需要不到100行,工作量低風(fēng)險(xiǎn)低。二是重構(gòu)這部分邏輯,配置文件改為Json,并修改對(duì)應(yīng)的解析邏輯。風(fēng)險(xiǎn)高且工作量大。 當(dāng)時(shí)距離版本發(fā)布只有不到一個(gè)月的時(shí)間,PM認(rèn)為風(fēng)險(xiǎn)較高,建議先使用簡(jiǎn)化方案處理。但是在我詳細(xì)走讀代碼后發(fā)現(xiàn),該模塊的代碼已經(jīng)不適合當(dāng)前的實(shí)現(xiàn),如果繼續(xù)修改會(huì)導(dǎo)致后續(xù)維護(hù)難度更大。作為開(kāi)發(fā)者,我的代碼潔癖不允許我選擇“簡(jiǎn)化方案”,作為committer,我更需要以身作則。 所以,我堅(jiān)決地選擇了方案二,但是針對(duì)當(dāng)前修改風(fēng)險(xiǎn)大的現(xiàn)狀,跟PM和前端測(cè)試對(duì)齊,提前識(shí)別場(chǎng)景,做好用例設(shè)計(jì)并采用測(cè)試驅(qū)動(dòng)開(kāi)發(fā)的模式保證質(zhì)量。最終,將解析代碼由3K簡(jiǎn)化為0.1K,并且在一周內(nèi)完成了開(kāi)發(fā)測(cè)試上主干,高質(zhì)量零缺陷解決問(wèn)題。 由于升級(jí)業(yè)務(wù)的特殊性,我們所負(fù)責(zé)的微服務(wù)不能和產(chǎn)品包一起升級(jí),需要在節(jié)點(diǎn)上手動(dòng)調(diào)用相關(guān)腳本升級(jí)。且升級(jí)過(guò)程中需要輸入3個(gè)用戶(hù)名、5個(gè)密碼,實(shí)施時(shí)極易因?yàn)槊艽a錯(cuò)誤等原因失敗。針對(duì)這一問(wèn)題,我仔細(xì)構(gòu)思,設(shè)計(jì)并開(kāi)發(fā)了自升級(jí)界面化功能。通過(guò)復(fù)用其他服務(wù)的通道,做到了在界面上一鍵完成升級(jí),且升級(jí)時(shí)長(zhǎng)較原先縮短50%,得到一致好評(píng)。 自升級(jí)界面化交付后可以在頁(yè)面一鍵式升級(jí) 現(xiàn)在,每次不論是遇到問(wèn)題、做新需求還是設(shè)計(jì)新特性,我總是喜歡想一想,有沒(méi)有更好的方法,代碼能不能更精簡(jiǎn),可用性、可靠性能不能更高。每次看到做完需求代碼反而更少了,我覺(jué)得比交付了很多“湊工作量”的代碼更令人激動(dòng)。 隨著時(shí)間的推移,我經(jīng)手的代碼越來(lái)越多,被“挑刺”的越來(lái)越少。團(tuán)隊(duì)的代碼質(zhì)量也越來(lái)越高,花費(fèi)在修改問(wèn)題單的時(shí)間越來(lái)越少。大家也逐漸認(rèn)可了“代碼質(zhì)量好,回家回得早”的這個(gè)道理,越來(lái)越多的人開(kāi)始重視代碼里的細(xì)節(jié)。 一點(diǎn)一滴的積累,一個(gè)又一個(gè)的細(xì)節(jié)優(yōu)化,讓我們的團(tuán)隊(duì)也變得更好。 穿越黑暗與苦痛,才能破繭而出 就像牛頓頭上的那個(gè)蘋(píng)果總是會(huì)落地一樣,軟件缺陷也是無(wú)法避免的,難免會(huì)有現(xiàn)網(wǎng)的緊急問(wèn)題需要處理,尤其是我所在業(yè)務(wù)組負(fù)責(zé)的升級(jí)。為了不影響客戶(hù)使用,升級(jí)總是在深夜執(zhí)行,且有著嚴(yán)格的時(shí)間窗。現(xiàn)在,當(dāng)被深夜的電話(huà)會(huì)議驚醒的時(shí)候,我總是會(huì)條件反射般地告訴一線(xiàn)同事“稍等兩分鐘”,然后迅速起身打開(kāi)便攜,快速處理閉環(huán)問(wèn)題。這時(shí)候我才突然意識(shí)到,我已經(jīng)從那個(gè)小心翼翼地詢(xún)問(wèn)“是這樣的嗎”的萌新,成長(zhǎng)為“我馬上上來(lái)處理”的團(tuán)隊(duì)骨干。 路漫漫而修遠(yuǎn)兮,吾將上下而求索。作為一個(gè)新上崗的MDE和Committer,我還有很多的知識(shí)需要學(xué)習(xí)和積累。就像被困在繭里的毛毛蟲(chóng)一樣,只有默默積蓄力量,穿越黑暗與苦痛,才能破繭而出,見(jiàn)到更廣闊的世界,遇見(jiàn)更好的自己。和大家共勉。 |
|