最近受朋友之託,幫別人調一個程式,據說是畢業論文。這個論文是本科還是碩士的,我也不清楚,反正是一個對指紋進行增強題目。離開學校那麼多年了,很多理論知識快忘乾淨了,比如什麼偏導數、內積、卷積……第一眼看這個論文的時候,腦子裡面蹦出來的是“好複雜啊”,對科學產生了一種肅然起敬的心情!
不過看到那個程式之後,心情就變了個徹底。別的不說,先看看一個代碼片斷:
for(i=0;i<298;i++)
{
for(j=0;j<298;j++)
{
n1=n2=0;
for(m2=0;m2<3;m2++) //*****賦值*****
{
for(m1=0;m1<3;m1++)
{
u[n1][n2]=tr1[i][j];
n2++;
j++;
}
n2=n2-3;
j=j-3;
n1++;
i++;
}
n1=n1-3;
i=i-3;
a=i+1;
b=j+1;
xx[a][b]=timesx(u,i,j);
yy[a][b]=timesy(u,i,j);
}
}
還好,這還不是我見過最差勁的校園畢業論文程式,至少還有對齊,也不會一堆的代碼寫在一行裡面。但是,光看這對東西也感覺夠怪異的,為什麼要修改迴圈變數j和i?看了半天才明白,其實是想把矩陣中的某一塊複製到一個臨時數組之中。事實上這樣的複製完全沒有必要,後來我花了幾個小時的時間對這個簡單的程式做了一次巨大的重構。其間不斷的發現極其重複的代碼,甚至有些重複的代碼還出現了不一致(即其中某些複製過的代碼被修改了,而且還改錯了)。我們再來看看這樣的代碼:
if (((s[1][1]-s[0][0]+sqrt((s[0][0]-s[1][1])*(s[0][0]-s[1][1])+4*s[0][1]*s[0][1]))*(s[1][1]-s[0][0]+sqrt((s[0][0]-s[1][1])*(s[0][0]-s[1][1])+4*s[0][1]*s[0][1]))+4*s[0][1]*s[0][1])<0.0)
{
{
w1[0][0]=w1[1][0]=w2[0][0]=w2[1][0]=e1=e2=0.0;
}
else
if(sqrt((s[1][1]-s[0][0]+sqrt((s[0][0]-s[1][1])*(s[0][0]-s[1][1])+4*s[0][1]*s[0][1]))*(s[1][1]-s[0][0]+sqrt((s[0][0]-s[1][1])*(s[0][0]-s[1][1])+4*s[0][1]*s[0][1]))+4*s[0][1]*s[0][1])==0.0)
{w1[0][0]=w1[1][0]=w2[0][0]=w2[1][0]=e1=e2=0.0;}
else
{
w1[0][0]=(2*s[0][1])/sqrt((s[1][1]-s[0][0]+sqrt((s[0][0]-s[1][1])*(s[0][0]-s[1][1])+4*s[0][1]*s[0][1]))*(s[1][1]-s[0][0]+sqrt((s[0][0]-s[1][1])*(s[0][0]-s[1][1])+4*s[0][1]*s[0][1]))+4*s[0][1]*s[0][1]);
w1[1][0]=(s[1][1]-s[0][0]+sqrt((s[0][0]-s[1][1])*(s[0][0]-s[1][1])+4*s[0][1]*s[0][1]))/sqrt((s[1][1]-s[0][0]+sqrt((s[0][0]-s[1][1])*(s[0][0]-s[1][1])+4*s[0][1]*s[0][1]))*(s[1][1]-s[0][0]+sqrt((s[0][0]-s[1][1])*(s[0][0]-s[1][1])+4*s[0][1]*s[0][1]))+4*s[0][1]*s[0][1]);
w2[0][0]=(2*s[0][1])/sqrt((s[1][1]-s[0][0]+sqrt((s[0][0]-s[1][1])*(s[0][0]-s[1][1])+4*s[0][1]*s[0][1]))*(s[1][1]-s[0][0]+sqrt((s[0][0]-s[1][1])*(s[0][0]-s[1][1])+4*s[0][1]*s[0][1]))+4*s[0][1]*s[0][1]);
w2[1][0]=(s[1][1]-s[0][0]-sqrt((s[0][0]-s[1][1])*(s[0][0]-s[1][1])+4*s[0][1]*s[0][1]))/sqrt((s[1][1]-s[0][0]+sqrt((s[0][0]-s[1][1])*(s[0][0]-s[1][1])+4*s[0][1]*s[0][1]))*(s[1][1]-s[0][0]+sqrt((s[0][0]-s[1][1])*(s[0][0]-s[1][1])+4*s[0][1]*s[0][1]))+4*s[0][1]*s[0][1]);
//***求特徵值***
e1=(s[0][0]+s[1][1]+sqrt((s[0][0]-s[1][1])*(s[0][0]-s[1][1])+4*s[0][1]*s[0][1]))/2.0;
e2=(s[0][0]+s[1][1]-sqrt((s[0][0]-s[1][1])*(s[0][0]-s[1][1])+4*s[0][1]*s[0][1]))/2.0;
}
媽媽米婭!感覺進入了Matrix電影裡面去了,滿眼的0和1。
還好,最後總算順利的給拆卸並重新組裝了。其實根本就沒有顯示的那麼複雜,裡面有很多是屬於重複計算。並且由於沒有引入一些必要的中間變數,才會出現這麼複雜的代碼。
說實話,我是非常佩服寫這樣代碼的人,在寫這樣代碼的時候能夠想得清楚的。不過最後我還是在這段代碼裡面找到了一些錯誤——與論文中的公式不符。其實寫這樣的代碼,就很難避免一個不小心看走眼的問題。我認為問題不在於寫這樣代碼的同學身上,問題在於高校!
如果高校的論文需要寫一個複雜程度為A的程式,就應該給學生們傳授能夠寫出複雜程度為A的程式的基本功。說實話,這個程式從編程的角度並不算多難,難的地方在理論公式上面。但是就是這樣一個難度,現在的學生也不具備正確寫出程式的必要能力。與此相對應的一個情境是,要求在IEEE上面發表外語論文。最難的確實是理論上面的事情,但是如果你的英語能力只是good good study day day up,那麼要求發表外語論文根本就是瞎掰!對於這種問題,如果教育部認為發表外語論文是必須的,那麼就應該加強學生在外語方面的訓練;如果認為無法解決外語能力方面的訓練,那就不應該要求發表外語論文。可是就是這麼簡單的一個問題,教育部就是解決不了,至少在我看來就是不誠心,或者沒有儘力。
我們還是回到寫程式上面。我真想質問一下這個學校的校長,或者該系的系主任:現在都什麼年代了,教出來的學生連代碼風格都沒有及格,他們是怎麼畢業的?我也不指望本科生在設計模式上面有什麼造詣,但是這一連串的s[0][0]-s[0][1]+sqrt(...)還有那些毫無道理的修改迴圈變數的代碼,教他們電腦的老師看著不覺得慚愧嗎?要是我教的學生在畢業論文裡面寫出這樣的代碼,我就乾脆辭職算了——沒臉見人!
我也知道,現在的大學在電腦編程上面投入的課時太少,大學新生在電腦方面的基礎差距也很大,有各種各樣的客觀障礙。要是這樣就不要拉牛上樹趕鴨上架啊,別讓他們選一個編程解決指紋增強畢業論文題目啊!明知不可為而為之的結果,就是一個字“混”。
我原來以為這個程式是托我解決問題的同學寫的,我也不好意思寫出來,怕打擊人家自尊。後來跟他一聊才知道,原來這個程式是他的導師給他的,作者是上一屆的畢業生。那我就不客氣了,反正打擊的也是原來的作者。唉,我感覺這個問題已經是一種常態了,當年我女朋友讀研的時候,這種事情我也聽得多見的多了。好多人都是拿著導師給的、上一屆寫出來的、狗屁不通的、執行結果錯誤的、甚至乾脆無法編譯的程式,修修改改、胡亂調整幾個參數、加幾個其實根本沒有被調用的方法,最後和他的已經畢業了的師兄師姐一樣混畢業了。他們改完之後變得更糟糕的程式還會被流傳下去,千秋萬代,遺臭萬年。試問這樣的結果是教育部想要的嗎?反正我相信這樣的水平絕對不是一個商業軟體公司所能夠接受的!
我女朋友說我又在抱怨了,是,我就是在抱怨!前兩天還有一位同志在我這裡評論道“奇怪奇怪真奇怪……設計模式是提高效能”云云,其實當時我心裡是挺鬱悶的。我所說的那些情況其實並不算是嚴重的了,如果你跟我今天舉的例子比較起來。這些人畢業進了公司,你指望他能夠懂設計模式?他們不把你寫的好好的代碼,設計的好好的架構,應用的好好的第三方工具弄個亂七八糟千瘡百孔烏煙瘴氣,你就該念“阿彌陀佛(此處刪去萬餘字,免得有侮辱宗教之嫌)”了。再好的設計模式,也經不起胡亂的copy&paste的。更不要說5層迴圈嵌套,外加內迴圈修改外迴圈的迴圈變數,外加if語句裡面一長串的調用,外加完全無畏的重複調用。
我也不想抱怨更多了,最後再抱怨一個:
各大高校,拜託再也不要為了教同學們c語言的關鍵字,就不使用c++的文法了,看了讓人笑話!我在看這個程式的時候就覺得鬱悶,為什麼每個函數前面都有一長串的變數聲明,哪怕是最後面才會用到。最後才發現原來這是一個c檔案,而不是cpp檔案!我以前還遇到的其它代碼類似如下:
int func1(a, b)
int a;
float b;
{
return (a+b);
}
不知道大家是不是和我一樣,看到了化石?不要“用c比c++效能更好,寫底層的代碼應該用c而不是c++”這樣的理由跟我爭論,我相信寫出這麼爛的代碼的同學之所以選用c而不是c++標準,絕對不是因為這個原因。首先因為這樣的程式的效率問題是用c編譯器也無法挽救的,其次因為我相信他們更笨不知道還有這樣一個理由。
不說了,開另外一篇寫點別的。
P.S.:
@dudu:貌似如果你開一個抱怨區,我會灌很多文章進去,哢哢!