多開發(fā)者認(rèn)為,編程的難度依然非常大,但是這些困難與編程語言無關(guān),本篇主要介紹了軟件開發(fā)的難點(diǎn),通過發(fā)現(xiàn)這些問題,來及時(shí)找到自己的問題。
有的人認(rèn)為,一款好的編程語言可以減輕軟件開發(fā)者身上的負(fù)擔(dān),且能夠相應(yīng)地提高他們的效率。
毫無疑問,這一點(diǎn)在很久前的匯編與 Fortran 時(shí)代確實(shí)如此。
然而,如今編程語言已經(jīng)足夠好了,我們?nèi)匀幻媾R著一些其他方面的困難與挑戰(zhàn)。時(shí)下,很多開發(fā)者認(rèn)為,編程的難度依然非常大,但是這些困難與編程語言無關(guān),原因有以下幾點(diǎn)。
阿姆達(dá)爾定律
在需要執(zhí)行一系列的任務(wù)時(shí),我們就會(huì)想起阿姆達(dá)爾定律。這條定律告訴我們,僅通過加速某一項(xiàng)任務(wù)而獲得的整體速度提升有硬性限制。
假設(shè)把水燒開需要10分鐘,然后煮面條也需要10分鐘。即便你找到一種方法加快燒開水的速度,做飯的時(shí)間也不會(huì)少于10分鐘。任憑爐子再旺,也不可能將做飯的速度提高到兩倍。
該定律的數(shù)學(xué)公式為:假設(shè)某件事的總時(shí)間比為p,則你永遠(yuǎn)無法獲得大于1/(1 – p)的加速比。假設(shè)這部分工作占用了90%的時(shí)間,即p = 0.90,在優(yōu)化的過程中,如果將這部分的時(shí)間降至0,則整體的工作速度將提高1/(1 – 0.90) = 10倍。
阿姆達(dá)爾定律的關(guān)鍵在于,你能夠獲取的最大速度提升受限于優(yōu)化的工作所占的比例。
造成編程工作難度非常大的原因有很多。簡單來說,我們可以認(rèn)為這是由于我們需要處理的工作必須按照一定的順序完成。畢竟人類不是很擅長同時(shí)處理多項(xiàng)任務(wù)。
在某個(gè)時(shí)間點(diǎn),你可能在使用構(gòu)建工具、閱讀文檔、編寫代碼或參加會(huì)議。當(dāng)然你也有可能在開會(huì)的時(shí)候忘我地寫代碼,但你只能做一樣工作,無法同時(shí)兼顧寫代碼和開會(huì)。因此,我們可以應(yīng)用阿姆達(dá)爾定律,假設(shè)你能設(shè)法將構(gòu)建時(shí)間降至0,但項(xiàng)目的整體速度也只能加快一點(diǎn)點(diǎn)。你的工作效率仍然會(huì)受到其他因素的限制。
曾經(jīng),將程序轉(zhuǎn)化成計(jì)算機(jī)可以運(yùn)行的代碼非常困難。很久以前,我們甚至需要將程序轉(zhuǎn)換成1和0,然后不厭其煩地將其輸入到計(jì)算機(jī)。我不知道這中間需要花費(fèi)多少時(shí)間,但我們可以假設(shè)這項(xiàng)工作占據(jù)了90%的編程時(shí)間。
這意味著,如果我們能找到一種更好的辦法(比如Python)告訴計(jì)算機(jī)干什么,就可以將編程效率提高10倍之多。
然而,如今我們的編程語言越來越好了,告訴計(jì)算機(jī)干什么的時(shí)間也越來越少了,將程序轉(zhuǎn)化成代碼也不需要花費(fèi)90%的時(shí)間了。假設(shè)現(xiàn)在我們只需要10%的時(shí)間。這意味著,如今即便將這部分工作的時(shí)間降至0,也只能提高1.11倍的效率。效率提升比以前減少了81倍。
這是因?yàn)槠溆?/span>90%的軟件開發(fā)工作都是非常艱巨的任務(wù),即便編程語言再好也無法(直接)減輕我們的負(fù)擔(dān)。
為什么編程的工作還是這么難?
傳達(dá)需求
這里我所說的編程工作很難,實(shí)際上與編程語言毫無關(guān)系。為了找出其中的原因,暫時(shí)假設(shè)我們完全不使用計(jì)算機(jī)。你無需告訴計(jì)算機(jī)做什么,但你需要告訴你的朋友該做什么。別作弊,也不能告訴你的朋友自己看著辦,你必須為他們做所有的決定。
你會(huì)發(fā)現(xiàn),你需要花費(fèi)大量時(shí)間才能解釋清楚關(guān)鍵的背景信息。你的朋友需要了解程序需要處理的現(xiàn)實(shí)問題,以及你認(rèn)為該程序應(yīng)該提供哪些功能。你必須解釋清楚所有的縮寫字母和術(shù)語,而且還需要討論各種外部因素。
你的朋友需要知道所有可能出現(xiàn)的情況,需要處理的細(xì)節(jié)非常多。
同時(shí),你還需要考慮不同功能的狀態(tài)兩兩組合,用戶可能會(huì)嘗試的各種動(dòng)作,以及所有可能出現(xiàn)的事件,你需要與朋友討論大量的極端情況。
向你的朋友解釋清楚這一切的難點(diǎn)有好幾個(gè)。首先,你必須掌握所有的實(shí)際細(xì)節(jié);其次,你必須了解程序在每種情況下應(yīng)該執(zhí)行的操作;再者,你必須通過朋友能夠理解的方式來傳達(dá)所有的信息。這意味著你必須有條理地組織這些信息,以確保便于理解。
請注意,到目前為止,我們甚至還沒有提及計(jì)算機(jī),當(dāng)然也沒有提及編程語言。理解需求,掌握程序應(yīng)該做什么以及組織表達(dá)方式,這些都是非常艱巨的任務(wù)。
描述與規(guī)格
我們很容易搞混描述與規(guī)格之間的區(qū)別,這是一個(gè)我們經(jīng)常會(huì)踏入的思維陷阱。如果你只有一段描述(“紅色汽車”),則你可以測試實(shí)際情況是否符合該描述(“是紅色,但不是汽車”),但是這段描述并不足以傳達(dá)如何制造一輛汽車。而這就是規(guī)范的用途。
創(chuàng)造事物需要做出很多決定。如果記錄下每個(gè)決策的結(jié)果,就會(huì)得到一份(雜亂無章的)規(guī)范。編寫程序的時(shí)候,你需要做出這樣的決定,因此僅憑描述還不行,你需要一份規(guī)范。在看到一段描述(“列出文件”)時(shí),我們很容易認(rèn)為這是一個(gè)規(guī)范,因此我們覺得應(yīng)該能夠告訴計(jì)算機(jī)執(zhí)行該動(dòng)作。但實(shí)際上,這中間有大量的決定需要考慮(“文件應(yīng)以什么順序列出?每個(gè)文件一行嗎?”)
在編寫程序的時(shí)候,你拿到的規(guī)范常常只是一段描述。計(jì)算機(jī)無法“繪制矩形”,它必須知道這個(gè)矩形的顯示位置、大小以及顏色。在編寫這段代碼的時(shí)候,你會(huì)發(fā)現(xiàn)很多尚未做出的決定。做這些決定需要付出很多努力。我們經(jīng)常會(huì)弄錯(cuò)引發(fā)這些工作的緣由,將其歸咎于編程語言,但其實(shí)這只是因?yàn)槲覀兒茈y根據(jù)一段描述創(chuàng)建規(guī)范。
計(jì)算機(jī)本身
下面,說回計(jì)算機(jī)。開發(fā)軟件不僅僅是了解軟件應(yīng)該做什么,并將各種想法轉(zhuǎn)變成代碼。計(jì)算機(jī)本身也有很多程序必須解決的問題。你的程序必須在硬件和網(wǎng)絡(luò)上快速地運(yùn)行。程序需要處理機(jī)器故障。而工具和協(xié)議的復(fù)雜性導(dǎo)致該領(lǐng)域所要面對的問題更多。這些困難都不是由向計(jì)算機(jī)解釋做什么的過程引起的,它們也是需要解釋的事情。
另外,你需要在腦海中運(yùn)行某些程序。有時(shí)邏輯很容易理解,但有時(shí)你無法將一系列的事件和狀態(tài)盡數(shù)塞入腦海中。為了正確理解程序的詳細(xì)信息,在出現(xiàn)錯(cuò)誤的情況下修復(fù)程序,你需要了解各種情況下程序本身的狀態(tài)。
編寫代碼的過程,可以讓你清楚地掌握程序的工作方式。然而,程序永遠(yuǎn)不會(huì)停止變化。你會(huì)發(fā)現(xiàn)錯(cuò)誤、添加新功能或修改現(xiàn)有的行為。即便程序最初的組織方式非常有效,但也不意味著它的結(jié)構(gòu)永遠(yuǎn)正確。你需要花費(fèi)時(shí)間組合各種情況,考慮未來的需求,并在出現(xiàn)意外的時(shí)候收拾爛攤子。
人員合作
很多時(shí)候,我們需要與其他人合作編寫程序,而這也會(huì)帶來挑戰(zhàn)。
所有的團(tuán)隊(duì)成員都必須各司其職。為了他們之間不互相妨礙工作,你必須進(jìn)行分工。為了建立合理的分工,首先你需要了解程序的結(jié)構(gòu)(請參見康威定律)。
如果你有多個(gè)團(tuán)隊(duì),則情況會(huì)更復(fù)雜。每個(gè)團(tuán)隊(duì)都有不同的目標(biāo),因此你必須權(quán)衡各個(gè)方面。有時(shí),某個(gè)決定非常利于其他團(tuán)隊(duì),但會(huì)阻礙你的工作。設(shè)身處地為他人著想,并找到合理的妥協(xié)方案是非常艱難的工作,但必須完成。
在大型項(xiàng)目中,沒有任何一個(gè)團(tuán)隊(duì)能夠了解整個(gè)系統(tǒng),更不用說一個(gè)人了。但是,你依然需要弄清楚系統(tǒng)的各個(gè)部分是如何設(shè)計(jì)的,又是如何組織到一起的。這比你自己承擔(dān)起整個(gè)設(shè)計(jì)還要難。
雖然與人打交道并不是真正意義上的編寫代碼,但也是開發(fā)軟件中非常重要的一部分。
如何解決軟件開發(fā)的外在難題?
我們可以尋找一些不受阿姆達(dá)爾定律限制的方法。如果各個(gè)任務(wù)的速度不是完全獨(dú)立的(比如優(yōu)化一個(gè)任務(wù)能夠加快另一個(gè)任務(wù)的速度),我們就有希望通過技術(shù)解決方案改善這個(gè)問題。
我們需要更好的語言和開發(fā)環(huán)境。如果我們可以用更少的人編寫程序(比如兩個(gè)人能代替整個(gè)團(tuán)隊(duì),或者一個(gè)團(tuán)隊(duì)代替一個(gè)部門),則可以大大削減組織規(guī)模。如果由同一個(gè)人來編寫接口的前后臺(tái),就不需要開會(huì)討論了。生產(chǎn)率的提升不僅可以降低編寫代碼的成本,而且還會(huì)改變工作的方式,從而降低其他工作的成本。雖說如此,但這種方式也有局限性,因?yàn)槌绦騿T無法將所有業(yè)務(wù)都納入他們的腦海中。
迭代速度是另一個(gè)杠桿。為了編寫程序,你需要了解領(lǐng)域知識(shí)以及需要做出的決定。為此,你需要了解所有細(xì)節(jié),然后建立一種思維模型。雖然這種方法可行,但可能不是最有效的方法。還有一種方法,根據(jù)一些顯而易見的細(xì)節(jié),構(gòu)建一個(gè)小型的思維模型。
然后,根據(jù)這個(gè)模型創(chuàng)建一個(gè)小程序,并實(shí)際驗(yàn)證這個(gè)思維模型。然后根據(jù)得到的反饋進(jìn)行迭代,這樣每次創(chuàng)建的模型就會(huì)越來越豐富,越來越準(zhǔn)確。這種方法似乎更好,因?yàn)樗先藗儗W(xué)習(xí)的過程。為了保證這種方法的有效性,你需要快速測試并獲得反饋。理想狀態(tài)是在輸入完代碼后,新的代碼就立即開始運(yùn)行。改變開發(fā)環(huán)境,實(shí)現(xiàn)更快的迭代周期,可以讓開發(fā)人員從第一種方法轉(zhuǎn)變成第二種,從而幫助他們理解問題。
更具表現(xiàn)力的編程語言是否能夠顯著地提高生產(chǎn)力?我并不是很樂觀。然而,我認(rèn)為仍然有可能出現(xiàn)更好的開發(fā)環(huán)境。如果我們能通過更好的工具來理解現(xiàn)有代碼,實(shí)現(xiàn)更快的開發(fā)迭代周期,并減少繁瑣的“體力”勞動(dòng),就有可能改變軟件開發(fā)的方式,并從多方面改善我們的工作。
文章來源:網(wǎng)絡(luò) 版權(quán)歸原作者所有
上文內(nèi)容不用于商業(yè)目的,如涉及知識(shí)產(chǎn)權(quán)問題,請權(quán)利人聯(lián)系小編,我們將立即處理
聯(lián)系客服