開發(fā)出好程序要做的功課
接著前一篇,原則設(shè)定好了,接下來還需要能夠?qū)嵺`,否則就只是空談,而實(shí)踐就得依賴開發(fā)人員的素質(zhì)。要提升開發(fā)人員的素質(zhì),有三個(gè)重點(diǎn), “基礎(chǔ)、基礎(chǔ)、基礎(chǔ)” 。沒錯(cuò)!想要提升素質(zhì)其實(shí)沒有速成的方法,就像功夫電影都會(huì)有強(qiáng)調(diào)扎馬的橋段,腳力是提供一切招式力道的根源,而再凌厲的招式也可能因?yàn)橹匦牟环€(wěn)而失去了威力。開發(fā)的領(lǐng)域中,愈充實(shí)的基礎(chǔ)知識(shí)在遇到狀況時(shí)愈能有效的解決問題,甚至是提早預(yù)防。因?yàn)樵谥烙心男┈F(xiàn)成選項(xiàng)可以運(yùn)用,也就不需要重新打造一個(gè)輪子,而是站在巨人的肩膀上。
心酸的業(yè)界生態(tài)
身為開發(fā)者必須要很清楚自己設(shè)計(jì)的每一個(gè)環(huán)節(jié)會(huì)產(chǎn)生的效果或可能的問題、限制,才能夠貼切地符合需求的內(nèi)容。這是需要具備一定的經(jīng)驗(yàn)和知識(shí),尤其是隨著時(shí)間的累進(jìn)、程序愈來愈精致化,開發(fā)程序時(shí)不論是編程語言或是作業(yè)平臺(tái)都伴隨著龐大的內(nèi)容、大量的資訊,需要時(shí)間來消化、理解。
入行的條件不再高不可攀
也許是現(xiàn)代開發(fā)工具的強(qiáng)大與坊間的教育機(jī)構(gòu)的普及,很多人經(jīng)過簡單的訓(xùn)練就以 “會(huì)把網(wǎng)絡(luò)上搜尋來的程序片斷兜起來、可以正常運(yùn)行” 當(dāng)成是寫程序的全部。但是科班出身的就充滿著光芒嗎?我也看過不少人,不是在課堂上虛擲光陰,就是沒有將所學(xué)融會(huì)貫通,展現(xiàn)出來的工作水準(zhǔn)也只是一般般。
現(xiàn)在寫程序的模式除了有現(xiàn)成的框架、庫可以選用,網(wǎng)絡(luò)資訊的發(fā)達(dá)讓形形色色的源代碼片段都可以搜尋得到,很多時(shí)候只要選好框架、把網(wǎng)絡(luò)上的源代碼片段組合起來,就可以有一個(gè)能夠運(yùn)行的程序。當(dāng)然沒事就沒事,但不幸出事了要算是誰的責(zé)任?
在過去的工作經(jīng)驗(yàn)里就曾經(jīng)遇過當(dāng)程序發(fā)生問題,我問負(fù)責(zé)的人出問題的源代碼在做什么事,他回答我: “不知道,從網(wǎng)絡(luò)上貼來的!” 如果你是老板,遇到這種情況會(huì)不會(huì)想:“那我應(yīng)該付錢給原作者?還是負(fù)責(zé)貼上的人?”
當(dāng)你不了解程序運(yùn)行的內(nèi)容,怎么能保證你的程序能夠穩(wěn)定地運(yùn)行、沒有安全上的疑慮?的確,在實(shí)作上有很多時(shí)候需要進(jìn)階一點(diǎn)的演算法,像是壓縮、圖形運(yùn)算,非科班出身、沒有數(shù)學(xué)基礎(chǔ)的還真沒有辦法理解。有點(diǎn)職業(yè)道德的人會(huì)盡可能地做好測試,就算不知道內(nèi)容,但最少確認(rèn)運(yùn)行的結(jié)果是自己要的。而不是交差后就當(dāng)沒事,默默祈求程序不要出問題!
這個(gè)情況,讓人聯(lián)想到食安事件。有一部份餐飲業(yè)者沒有具備烹飪的基本功夫,所以很多材料必須要靠外購,對食材的特性也沒有足夠的掌握能力。但在成本的考量下,黑心一點(diǎn)就選擇明知有問題、來路不明但成本低廉的食材。像是用的油出了事、用到了地溝油,就只能推說: “我也是受害者,是那些做地溝油的廠商該死,應(yīng)該要向地溝油的廠商求償,與我無關(guān)?!?/p>
當(dāng)然,也有負(fù)責(zé)任的店家并不是用成本低廉的食材但也遭到波及。第一時(shí)間會(huì)覺得這些人真的很無辜,但進(jìn)一步想想,要從事餐飲業(yè)是你的選擇,你的客人是信任你的烹飪技巧、口味的掌控、食材挑選能力等等的質(zhì)量要素,而不是信任你的進(jìn)貨廠商。出了問題,要說你完全沒有責(zé)任并不合理!對消費(fèi)者來說,合理方式應(yīng)該是先賠償給消費(fèi)者,至于和進(jìn)貨廠商的賠償問題是店家內(nèi)部的事,這樣對我們這些末端的消費(fèi)者才公平不是嗎?而且,規(guī)模大的商家更應(yīng)該要有資源、能力與責(zé)任承擔(dān)起這樣的標(biāo)準(zhǔn)。
寫程序不再是閉門造車
反觀我們自己理所當(dāng)然地把別人寫好的東西拿來用,卻鮮少深究內(nèi)部運(yùn)作的邏輯,是不是也是一樣的缺乏商業(yè)道德?說起來還挺心虛的,批評地義正嚴(yán)詞、擲地有聲,原來比起食品產(chǎn)業(yè)我們高尚不到哪去!用 “我們” 似乎太過一竿子打翻船人,所以我招認(rèn)最少我自己是。
在社會(huì)分工細(xì)致化、講求效率的年代,工作當(dāng)中使用自己不了解的產(chǎn)品成了必要之惡,就像是要求店家所有的食材全部自制一樣,是一種奢求。再加上訊息科技雖然發(fā)展沒幾年,但是已經(jīng)形成了一個(gè)很龐大的知識(shí)體系。不一而足的操作系統(tǒng)平臺(tái)、程序語言,多如繁星的框架、SDK、庫,各行各業(yè)的領(lǐng)域知識(shí)、商業(yè)邏輯,每一個(gè)區(qū)塊都形成了一個(gè)有高度的門檻和學(xué)習(xí)障礙。在開發(fā)程序時(shí),如果要完全以自制的模式來進(jìn)行,不是成本高得嚇人,就是時(shí)間長得不能接受,以致于難以實(shí)行。
知名廠商的庫、開源的框架比較不可能會(huì)是問題的來源,畢竟這些程序都是以一般化的用途為出發(fā)點(diǎn)、能夠適用于大多數(shù)的情況之下,并且經(jīng)過重重的檢驗(yàn)、測試。知名的公司也不可能自毀招牌,放任產(chǎn)品中有明顯的瑕疪或安全問題。但由網(wǎng)絡(luò)上搜尋到的源代碼往往是示范性質(zhì)或?qū)榻鉀Q特定問題,不見得與程序的需求百分之百的契合,如果一字不改或是對運(yùn)行的內(nèi)容一知半解的情況下編入程序內(nèi),這樣的做法和之前舉的食安例子中使用來路不明食材的店家有何差別?
那有些小公司或不明來源編譯好的庫豈不是問題潛在的制造者?會(huì)不會(huì)內(nèi)藏惡意的源代碼?這個(gè)問題對于管理者來說會(huì)是一個(gè)取決于風(fēng)險(xiǎn)與成本的困難抉擇。端看你的程序?qū)τ诎踩囊蟪潭龋瞧髽I(yè)內(nèi)部敏感數(shù)據(jù)的系統(tǒng)?還是給一般人使用的系統(tǒng)?打算付出多少的成本?沒有打算付出太多的成本,只能承受較高的風(fēng)險(xiǎn);不能承受風(fēng)險(xiǎn)的,就得要付出較多的成本,像是有制度一點(diǎn)的應(yīng)該要成立專職的安全小組對程序做必要的檢測。
如果要問我,所開發(fā)的軟件遇到像食安風(fēng)暴的情況,會(huì)不會(huì)采用和那些店家一樣的態(tài)度?我會(huì),同時(shí)還會(huì)用投名狀中龐青云的語氣說 “裝死無敵!這是規(guī)矩!” 。但這是問題發(fā)生了的假設(shè),在發(fā)生問題之前我會(huì)想要盡可能地避免,畢竟程序是自己寫的,光嘴巴上喊沒責(zé)任就可以置身事外也不太可能。
追求質(zhì)量的價(jià)值在哪里?
要把這個(gè)想法做好,首先會(huì)遇到的就是被海量信息淹沒的無助。這是這行從業(yè)人員普遍會(huì)有的心酸,要學(xué)習(xí)的東西愈出愈快、愈來愈多。先不看是不是有足夠的時(shí)間吸收,光信息量就已經(jīng)超出一般人大腦能夠承載的極限。餐飲界里隨處可見幾十年的老味道,能夠傳承好幾代的手藝。反觀軟件界,當(dāng)年縱橫 COBOL 和 Fortran 語言的系統(tǒng),試問如今安在?姑且不看這種由時(shí)代浪潮所帶來的興衰,同一家公司的技術(shù)總會(huì)一脈相傳、延續(xù)演進(jìn)吧?過去靠微軟的技術(shù)混過飯吃的那段日子,有過不少次被微軟打臉的經(jīng)驗(yàn),那頭才在研討會(huì)上大張旗鼓地?zé)崃彝其N,回頭卻是悄悄收攤,不再發(fā)展、更新。收兵尚且要鳴金,有的時(shí)候是連鳴金都省了!我的青春、我的人生,就在不斷地用新技術(shù)翻修舊系統(tǒng)的循環(huán)中渡過。
信息技術(shù)的更替如過江之鯽的現(xiàn)象,再加上公司高層多以利字為先,造就了不少開發(fā)人員速成的心態(tài)。對使用的技術(shù)一知半解、得過且過,源代碼能用就好、不求甚解,反正用沒多久又要換一種寫法,復(fù)制貼上的時(shí)間已經(jīng)比自己打字的時(shí)間還多。而衍生出來的問題是遇到了技術(shù)上的狀況,常常磨了很久得到的答案是不可能解決、沒辦法處理。但等到換一個(gè)對技術(shù)比較自我要求的人去試時(shí)卻又不是這么回事,有時(shí)解決的方案還直接到不行,可是原本負(fù)責(zé)的人找答案時(shí)又認(rèn)真到你分不清楚是否是該歸類成偷懶的借口!這樣的情況我遇到的并不是個(gè)案,也不是單一個(gè)人才有,甚至習(xí)以為常到不忍去苛責(zé)這個(gè)大環(huán)境所形成的共業(yè)。就管理者的角度,迫于專業(yè)分工下的現(xiàn)實(shí),只能盡可能讓開發(fā)人員針對自己擅長的領(lǐng)域做專精,用團(tuán)隊(duì)的力量來截長補(bǔ)短。
既然業(yè)界風(fēng)氣如此,那一昧的追求開發(fā)人員的素質(zhì)是否太過矯情?還是個(gè)人完美主義在作崇?組合網(wǎng)絡(luò)上的源代碼所產(chǎn)出的程序真得有這么不堪、有這么嚴(yán)重嗎?就如同做吃的這件事,沒有高超的烹飪技巧、專業(yè)級(jí)的食材挑選眼光,就不能煮東西給別人吃了嗎?那這樣豈不是所有家庭的爸爸、媽媽都不能下廚,都只能外食?如果我有一道拿手的菜就不能分享給親戚好友、街坊鄰居?
我個(gè)人認(rèn)為,程序本來就是解決問題的工具,如果寫的人快樂、用的人也快樂,是否得這么吹毛求疪地一定要設(shè)定什么門檻或標(biāo)準(zhǔn)?我想并不是這樣的,業(yè)界常常有一句話:“沒有最佳的解決方案,只有最適合的解決方案”。所以在這里完全沒有要貶低不是接受傳統(tǒng)制式訓(xùn)練的從業(yè)人員,或是對于愿意投入熱情從事程序開發(fā)工作的人有任何不敬的意思。相反地,能夠用程序解決生活中或是專業(yè)領(lǐng)域上遇到的問題,是很值得敬佩的一件事。最少人家有第二專長,而我只能靠人家的第二專長糊口,光這一點(diǎn)就沒什么資格對人說三道四的。
不過,這文章怎么好像愈寫愈沒立場,那還談什么素質(zhì)的提升?先來看看 Uber 和 Airbnb 的所帶來的爭議,這二個(gè)平臺(tái)所使用的模式很類似,都是共享經(jīng)濟(jì)的實(shí)踐者,分享私人閑置的資產(chǎn)來對大眾提供服務(wù)。像是如果我有閑置的車子我可以開著它去載客;如果我有閑置的房間我可以提供給短期需求的人來住宿。聽起來很美好,不但是各取所需,還可以有效利用資源、落實(shí)環(huán)保的概念。
但為什么有人要出來反對、抗議,而政府也介入干預(yù)?是政府狗拿耗子?那些既得利益者眼紅?如果是眼紅,那出租車司機(jī)為什么不叫車隊(duì)也搞一個(gè)類似的平臺(tái)來競爭就好?我用自己的車載朋友也要證照?加入 Uber 載人違法,自己載朋友不違法,差別在哪?是因?yàn)闆]有從中獲利?朋友請吃飯當(dāng)謝禮算不算從中得利?我使用的是全新車,車款高級(jí)、內(nèi)裝豪華,載客時(shí)也是西裝革履,開車時(shí)戰(zhàn)戰(zhàn)競競,車上還有額外的飲水服務(wù),哪一點(diǎn)比出租車差?明明雙方都是你情我愿,又沒礙著別人,這樣也要抗議?那有廚師證的為什么不出來抗議滿街沒證照的街邊小吃?開店做生意的店家為什么不出來抗議擺在路旁的地?cái)偅?/p>
上面是延伸前一段的立場只呈現(xiàn)單一面的意見,而實(shí)際上兩造的論點(diǎn)各據(jù)一詞、沒有太大的交集。但可以看到一個(gè)現(xiàn)象,都是提供服務(wù)的二方在爭議,購買服務(wù)的第三方卻沒聽到很大的負(fù)面評價(jià)。我想那是因?yàn)檫€沒有遇到危害切身利益的情況,以服務(wù)提供者的角度來看,重點(diǎn)還是那句話:沒事就沒事,但不幸出事了要算是誰的責(zé)任?一但牽扯到利益,問題就會(huì)變得異常的復(fù)雜,不管你是爭議的哪一方、有沒有政府背書的證書、或是你從哪個(gè)名校畢業(yè)的。面對的若是親朋好友,可能會(huì)看你的情面,不用你開口,就主動(dòng)放棄權(quán)利,也許幫忙出個(gè)必要的費(fèi)用就當(dāng)沒事。但如果是你不認(rèn)識(shí)的人,你有把握可以說服苦主讓你輕松過關(guān)嗎?爛客人事件在新聞中屢見不鮮,當(dāng)你碰上了一個(gè)要跟你走法律程序的對象,你真的有時(shí)間、心神應(yīng)付?
所以,如果你對于寫出好程序還有一點(diǎn)期待,不管你是完美心態(tài)作崇、還是想要明哲保身,提升質(zhì)量是一項(xiàng)看得見回報(bào)的投資,所謂一分耕耘一分收獲,端看你想要先甘后苦還是先苦后甘。也就是說,看你想要先花時(shí)間避免未來的損害?還是你想要把時(shí)間用在出問題后擦屁股這件事情上?
基礎(chǔ)、基礎(chǔ)、基礎(chǔ)
能做的努力大概就是一開始提到的:基礎(chǔ),多一分了解才多一分的機(jī)會(huì)知道怎么逃避責(zé)任... 我是說保護(hù)自己,就像法律通常都是保護(hù)懂法律的人。當(dāng)然在軟件的工作領(lǐng)域中,很多是商業(yè)機(jī)密、只能用不能看,在沒有授權(quán)的情況下太 “深入” 是會(huì)有觸犯法律的風(fēng)險(xiǎn)。所以這里指的努力,當(dāng)然就是針對公開的部份,像是文件、開源碼,至少讓自己不是在一知半解的情況下做出錯(cuò)誤的抉擇。
具備關(guān)鍵的知識(shí)
基礎(chǔ)中的基礎(chǔ)不外就是在學(xué)校中教授的那些課程,像是計(jì)算機(jī)概論、操作系統(tǒng)、數(shù)據(jù)結(jié)構(gòu)、工程數(shù)學(xué)等等。不過,這些內(nèi)容卻也是在實(shí)際從事程序開發(fā)時(shí)最不具存在感的內(nèi)容?,F(xiàn)在的程序設(shè)計(jì)都架構(gòu)在層層的堆疊與包裝之上,很多底層的問題都被隱藏、處理掉了。像是很多的語言都有提供垃圾回收(GC)的機(jī)制,所以 Memory Leak 問題變得不需要花時(shí)間處理,原本課堂上學(xué)的 Memory Leak 注意事項(xiàng)也無用武之地。
但這些設(shè)計(jì)上的問題仍然實(shí)際存在著,有一些仍然是要靠開發(fā)人員素養(yǎng)來做出適當(dāng)?shù)木駬瘛T谶x擇變量類型來儲(chǔ)存數(shù)字?jǐn)?shù)據(jù)時(shí),有些人會(huì)想容量應(yīng)該是愈大愈好,以免數(shù)字不小心超過上限而讓程序出現(xiàn)問題。在沒有接觸過相關(guān)的知識(shí)會(huì)根本沒想到,變量的型別會(huì)對運(yùn)作的效能上產(chǎn)生影響。而造成效能影響的原因,來自變量型別與記憶體長度的關(guān)系,是底層一個(gè)意想不到的運(yùn)作規(guī)則。
還有像是之前提到的多線程在設(shè)計(jì)時(shí)會(huì)遇到諸多的問題,如果具有相關(guān)的知識(shí)就會(huì)了解系統(tǒng)底層的工作原理、多線程的管理方式、對應(yīng)處理的機(jī)制。數(shù)據(jù)結(jié)構(gòu)可以協(xié)助設(shè)計(jì)有效率的數(shù)據(jù)處理模式,像是如果要進(jìn)行排序會(huì)有許多的排序演算法可用運(yùn)用,每一種都有其特性和適用的時(shí)機(jī),并且有一套學(xué)術(shù)上的方法可以預(yù)估處理模式在效率上是否符合需求。同時(shí)也會(huì)知道遞歸很好用,但呼叫階層數(shù)太多程序是會(huì)當(dāng)?shù)舻?。如果要?jì)算 1 加到 N 的總合,第一直覺是使用遞歸來寫,寫出來的程序卻有個(gè)致命的缺點(diǎn),N 有上限、超過程序會(huì)當(dāng)?shù)???墒歉挠锰菪蚊娣e公式,程序只要一行、運(yùn)行時(shí)間天差地別,N 也可以理論上達(dá)到無限大,最少可以達(dá)到變量能儲(chǔ)存總合的最大值。
這些相關(guān)的機(jī)制大多會(huì)被實(shí)作在編程語言所搭配的 SDK 上,技術(shù)文件中也許只會(huì)提到使用的規(guī)格,而不會(huì)有詳細(xì)的說明來解釋背后的原理。當(dāng)你擁有相關(guān)的背景知識(shí)就可以適切的運(yùn)用這些功能,而不是靠著猜測與試驗(yàn)來決定要選擇哪一種方案。這些選擇對程序的穩(wěn)定性與運(yùn)行效率都會(huì)有舉足輕重的影響,也決定著程序一但出現(xiàn)問題時(shí)初步處理的策略,發(fā)現(xiàn)及解決問題所要耗去的時(shí)間。
數(shù)學(xué)更是這一些基礎(chǔ)知識(shí)最不起眼的,就像我過去在企業(yè) IT 部門服務(wù)的經(jīng)驗(yàn)里,高階的數(shù)學(xué)知識(shí)完全束之高閤,大多數(shù)的程序只是單純地要求數(shù)據(jù)庫的 CRUD,數(shù)據(jù)處理的運(yùn)算需求也頂多是加減乘除。不過,數(shù)學(xué)基本上可以訓(xùn)練邏輯推演、協(xié)助思考,如果能夠融會(huì)貫通是有機(jī)會(huì)可以讓自己增加薪資條件、進(jìn)入特定的專精領(lǐng)域,像是圖學(xué)里的演算多是靠矩陣、向量等運(yùn)算來進(jìn)行,這是在影像處理、游戲、3D 應(yīng)用中必須的。
同時(shí),沒有明顯的助益并不代表就是多余的。這些知識(shí)會(huì)成為基礎(chǔ)是有其道理,所有的人造物都不會(huì)是跳躍式地一下就以復(fù)雜的結(jié)構(gòu)出現(xiàn),都會(huì)是由簡單的規(guī)則組合并堆砌所演化出來的。這個(gè)理論套用在軟件產(chǎn)業(yè)中一樣適用,基于相同底層所發(fā)展出來的系統(tǒng)都會(huì)具有一定的相似度。所以吸收的這些知識(shí)會(huì)內(nèi)化成為你的工作能力,例如增加技術(shù)的敏銳度,提升學(xué)習(xí)的效率,更容易接納新的技術(shù)、縮短上手時(shí)間。這就好像如果你有富爸爸,做起事來一定是事半功倍;但反過來如果是白手起家,遇到困難就是只能一步一腳印地走出來了。
掌握編程語言
再接下來的這項(xiàng)基礎(chǔ)效果就會(huì)比較明顯一點(diǎn),那就是編程語言。編程語言是程序開發(fā)的核心,用來編譯成 CPU 可運(yùn)行機(jī)械語言的依據(jù)。而編程語言靠的是保留字來跟編譯器溝通,透過保留字設(shè)定好的意義來轉(zhuǎn)換成機(jī)械語言或字節(jié)碼。
編程語言是所有人接觸程序的切入點(diǎn),學(xué)習(xí)編程語言的脈絡(luò)不外是變量宣告、運(yùn)算符、陳述、流程控制,進(jìn)階的還有面向?qū)ο蟪绦蛟O(shè)計(jì),但有不少人對于編程語言的學(xué)習(xí)也就僅此而已。隨著時(shí)間的推演,不少的新概念被導(dǎo)入既有的編程語言之中,像是現(xiàn)在最新的是大家都流行要 Lambda 一下,再早一點(diǎn)是使用 Attribute 來提供源代碼在運(yùn)行時(shí)期的附屬資訊,或是利用保留字來簡化多線程環(huán)境的數(shù)據(jù)同步問題。
這些編程語言的新語法如果不會(huì)對寫程序造成改變,通常也都不會(huì)、畢竟還是要考慮到相容性,很多人的選擇都是視而不見。就算是以喜新厭舊聞名的信息產(chǎn)業(yè),仍存在著為數(shù)不少的堅(jiān)持不輕易改變的從業(yè)人員。姑且不看新的語法所帶來的撰寫上的彈性、工作效率的增加、運(yùn)行效能的提升等優(yōu)勢,就算是只安于剪下貼上的工作模式,當(dāng)網(wǎng)絡(luò)上搜到的示范源代碼愈來愈多是以新語法撰寫時(shí),打算如何銜接到所負(fù)責(zé)的源代碼內(nèi)?或是有一個(gè)對新技術(shù)高度狂熱的同事寫的源代碼要讓你接手,這時(shí)還能夠以不變應(yīng)萬變嗎?
只有新玩意才不被人重視?泛型就不是個(gè)新玩意,但沒聽過、不知道如何使用還大有人在,不然就是只會(huì)依樣畫葫蘆地呼叫以泛型寫的功能,自己要設(shè)計(jì)卻無從下手、也不了解別人含有泛型設(shè)計(jì)的源代碼。所以對編程語言不夠了解會(huì)導(dǎo)致的下埸就是看不懂別人寫的源代碼,能被分配的工作就只能是只寫不改,可能嗎?
雖說看得懂別人寫的源代碼,是發(fā)現(xiàn)邏輯錯(cuò)誤或語法問題的第一步,看懂了卻忽略細(xì)節(jié)一樣也可能對錯(cuò)誤視而不見。有一個(gè)很古老的案例,以下有一個(gè)在 VB 還沒有進(jìn)入 .NET 的時(shí)代的源代碼范例:
Dim A, B, C As Integer
我遇到很多人都以為三個(gè)變量全部是以整數(shù)類型儲(chǔ)存在記憶體中,但實(shí)際上卻是只有 C 是整數(shù)類型,另外二個(gè)是以 Variant 的型別來運(yùn)作。這個(gè)問題嚴(yán)重嗎?就 VB 的語言特性來說,平常不會(huì)出現(xiàn)什么異樣。只是當(dāng)問題出在 Variant 上,源代碼的差異一下沒看出來,要確認(rèn)問題發(fā)生的原因還是挺累人的。
還有一個(gè)很基本卻是不少人忽略的細(xì)節(jié),那就是變量的生存周期、作用域的議題??此撇唤?jīng)意的變量聲明動(dòng)作,影響所及是程序會(huì)不會(huì)虛耗寶貴的記憶體空間、占著毛坑不拉屎;也有可能變量的內(nèi)容在沒有料想到的惰況下被更改,讓程序時(shí)不時(shí)地出現(xiàn)莫名其妙的反應(yīng),卻又遍尋不著發(fā)生問題的原因。
善用開發(fā)的工具
要開發(fā)程序,絕大多數(shù)的人大概已經(jīng)脫離不了對 IDE 的依賴,一個(gè)整合好開發(fā)所需環(huán)境的工具。從單純的打字、編譯、調(diào)試等基本的開發(fā)功能,到源代碼提示、即時(shí)語法檢查、源代碼重構(gòu)、版本控管、源代碼復(fù)雜度檢查、效能檢測、測試報(bào)告等跟團(tuán)隊(duì)與質(zhì)量相關(guān)的功能。能做的事愈來愈多,但我們在進(jìn)行開發(fā)工作時(shí)對 IDE 提供的功能中能夠掌握運(yùn)用的比例有多少?
很多跟 Application Lifecycle Management 相關(guān)的功能也許不是負(fù)責(zé)開發(fā)工作的人說要用就用得上,但還有不少是和工作效率習(xí)習(xí)相關(guān)的可以快速發(fā)現(xiàn)問題、縮減開發(fā)工作負(fù)擔(dān)的功能。曾經(jīng)就有遇過有人在調(diào)試時(shí),仍在使用最基本的左右逼近法,完全不知道有條件斷點(diǎn)可以用。很難想像在遇到大型循環(huán)時(shí),怎么有辦法耐得住性子,一次又一次地按著單步運(yùn)行的按鈕,直到期望的條件出現(xiàn);又或者是在很多階層的遞歸之間,是如何保持清醒、很明確地知道現(xiàn)在程序走到了第幾層的呼叫?
“工欲善其事,必先利其器” 大家都知道,很多人也羨慕 MacGyver 可以用一把瑞士軍刀就可以解決很多問題,但卻在自己拿到瑞士軍刀時(shí),只知道使用其中一項(xiàng)工具來解決所有問題。有的時(shí)候,功能的使用是需要有一點(diǎn)創(chuàng)意才能找到符合自己習(xí)慣的模式,但最少應(yīng)該要先點(diǎn)開來把玩看看,才能借由熟悉找到最合適的使用情境。
熟悉程序運(yùn)作的環(huán)境
這里的環(huán)境指的是由操作系統(tǒng)內(nèi)建函式、官方 SDK、各式框架、第三方庫所組成,用來提供程序運(yùn)行時(shí)期一切運(yùn)作的基礎(chǔ)。既然是基礎(chǔ),就是在提升開發(fā)人員素質(zhì)里所要討論的范圍內(nèi)。
這個(gè)部份還真的是知易行難的典范,跟學(xué)校教授的課程相比變遷劇烈、跟編程語言的內(nèi)容相比更加龐雜無邊、跟開發(fā)工具的功能組合相比更是繁復(fù)多變。隨便挑一小區(qū)塊的資訊都可能看到成了過去式還看不完,是很心酸,但無奈之余最少應(yīng)該要對工作所需要的領(lǐng)域有 “基本的認(rèn)識(shí)” 。
過去有接觸過不少有所謂的 “開發(fā) Android 程序” 經(jīng)驗(yàn)的人,對談之后發(fā)現(xiàn)這些人對 Intent, Service, Content Provider, Broadcast Receiver 等等基礎(chǔ)的控件完全沒有概念,不要說沒有使用的經(jīng)驗(yàn),甚至連這些名詞都一無所悉。還有的根本不知道自己寫程序用來控制畫面的控件叫 Activity,當(dāng)然也不用提進(jìn)階一點(diǎn)的 PendingIntent 或 IntentService。這應(yīng)該已經(jīng)不是專不專業(yè),而是合不合格的問題了!
再來看一個(gè)架構(gòu)大一點(diǎn)的例子,在因應(yīng) RESTFul 輕量化需求而誕生的 ASP.NET Web API 之前,WCF 一直占據(jù)著微軟遠(yuǎn)程過程調(diào)用的主要舞臺(tái)。WCF 借著簡化的開發(fā)過程、彈性的設(shè)定檔調(diào)整,讓不具底層知識(shí)的開發(fā)人員也可以輕易的建立跨電腦傳遞的功能,成為了企業(yè)內(nèi)架構(gòu)分散式系統(tǒng)的好選擇。但隨著移動(dòng)平臺(tái)的堀起,移動(dòng)裝置要被納入分散式系統(tǒng)成了熱門的需求。這時(shí),不知 HTTP 規(guī)格是何物的開發(fā)人員就踢到了鐵板!要讓沒有 WCF 的移動(dòng)平臺(tái)可以呼叫的情況下,限制服務(wù)端只能用 HTTP 通訊是必然的。然而安全性是 WCF 主打的特色之一,服務(wù)端一定設(shè)計(jì)了相當(dāng)程度的安全驗(yàn)證,沒有 WCF 怎么通過驗(yàn)證?
該想到的情況 WCF 都想到了,沒想到的也保留了接口可以擴(kuò)充,調(diào)整設(shè)定參數(shù)就可以完成準(zhǔn)備。移動(dòng)裝置要如何送出驗(yàn)證信息卻是尚待解決的問題,如果送不了,是不是把服務(wù)端的安全機(jī)制撤下來?有資安這種單位在,這個(gè)想法是不可能的!為了移動(dòng)平臺(tái)再重新打造一組服務(wù)?如果有閃電俠在可以考慮一下!這時(shí)如果對 HTTP 的規(guī)格有一定的了解、研究過 WCF 設(shè)定細(xì)節(jié),就可以知道 WCF 要進(jìn)行何種設(shè)定,并且在移動(dòng)平臺(tái)送出要求時(shí)要附上什么樣的驗(yàn)證資訊,以最低的成本來達(dá)成任務(wù)。
對于所謂 “基本認(rèn)識(shí)” 的作法,每個(gè)人天賦不同、做法也因人而異,也許有神人能夠把所有的資訊記憶在腦海之中。我的習(xí)慣是最少先瀏覽一遍文件的目錄或大綱讓腦海中有一個(gè)印象,然后期望體內(nèi)的小宇宙能在遇到障礙時(shí),提醒我排除的方法可能存在于文件的某一處。有的時(shí)候的確會(huì)很神奇的靈光一閃、小有幫助,多數(shù)的時(shí)候還是得靠 Google 大神,有道是團(tuán)結(jié)才是力量嘛!只是就算 Google 再神,也得要知道怎么問、下什么關(guān)鍵字,這就要看平常閱讀的功夫下得有多深了,也就是一開頭提到的 “基礎(chǔ)、基礎(chǔ)、基礎(chǔ)”。
最后
總算,文章的篇幅很長,大多是過去工作遇到狀況的縮影。叨叨絮絮地打了很多,是希望能讓剛接觸這個(gè)行業(yè)的人多些參考。感謝能夠這么耐心地看到最后的各位!