來源:酷殼
還記得以前本站的那一篇“編程好難啊”嗎,那是一篇眾程式員調侃程式新手的文章,有惡搞的成分在裡面。今天要和大家說的這個事沒有一些惡搞和調侃的意思,是比較嚴肅的話題,你一定可以從中收穫一些東西。這個話題來自StackOverflow上的一個問題——Cycle
in Family Tree Software,這個程式員問了下面這個問題:
我是一個寫家族族譜軟體的程式員(我用的是C++和Qt),這個軟體基本上沒有什麼問題,真到有一天有個使用者報告了一個bug。這個問題是這樣的——我這個使用者和他女兒生了兩個孩子。
於是,我程式員的一些斷言和硬性條件導致程式報錯,因為我的程式在處理這個關係的時候,其發現X即是Y的爸爸,又是Y的爺爺,所以只能報錯。
請問,在不需要移除我的斷言和資料驗證的情況下,我怎麼才能解決這個問題?
看到這裡,請重點閱讀一下下面的兩點:
- 如果你看到這裡開始興奮了,請你為你陰暗的心理去面壁反省10分鐘,因為這是一個很技術的問題。
- 如果你開始陷入了深深的思考如何解決這個問題,那麼你絕對是一個合格的程式員,因為你已陷入技術已經很深了,有點呆了。
我在前面說過,“這個是一個嚴肅的話題,你可以從中收穫一些東西”,當然,我並不希望你來收穫亂倫的知識和心得,酷殼是一個技術部落格,應該是收穫技術方面的東西。
從技術的角度上來說,這是我們經常在設計軟體時犯的錯誤——
1)作了錯誤的假設(Assumption)
Assumption是軟體設計的重大天敵,Assumption的動詞Assume意為Ass u me – Ass you and me 。你的假設做得越多,你的設計就越不靠譜。這裡的假設是——我們以為family tree是一個tree,其實並不是tree。Assumption是魔鬼。
還有一些經典的Assumption如下所示
- 最著名的就是那個y2k臭蟲。
- 不要以為沒有2月30日,在瑞典1712年有2月30日
- 一分鐘有60秒?閏秒呢?
- 雙胞胎的生日是同一天嗎?
- 雙胞胎的父親是同一個?
- 性別只有男和女?
- 婚姻只能是異性? 關於這一點,推薦一篇強文——Gay marriage: the database engineering perspective (同性婚姻:資料庫工程)
2)沒有認真分析使用者案例(Use Case)
在設計軟體時,我們需要考慮各種各樣的使用者案例,比如如下的東西:
- 私生子的問題
- 一夫多妻或一妻多夫,同父異母,同母異父
- 就算一夫多妻制違反法律,也會有離異再婚的情況
- 同性戀的問題,雖然不能繁衍,但可以領養。
- 換妻活動
- 各種亂倫關係——這種東西那個民族都不少,尤其是古時候,比如:
- 先後嫁了兩個人其是父子關係(昭君)
- 達爾文同學和他的表妹,愛因斯坦的二婚是和他的表姐,埃及豔后嫁了她的弟弟,……
- 順治同學娶了四個老婆,這四個人還是一家人:姑姑,侄女,妹妹,女兒。(參看這裡)
- 劉邦同學的母后幹出來的事,相當變態(參看這裡)
- 中國古代的“扒灰老” (類似於樓主那個問題的Use Case)
不想再列下去了,人類真TMD噁心,有點要吐了。
——————————為了緩解一下噁心的氣氛,請允許我插入一個搞笑短文——————————
一位自殺者在他的遺書裡講述了他自殺的原因,聽起來實在讓人頭痛。遺書這樣寫道:“我和一個寡婦結了婚,她有一個已成年的女兒,我父親跟我妻子帶過來的女兒結了婚。所以我父親就成了我的女婿,女兒就成了我的後母,我管父親叫爸爸,而我父親也管我叫爸爸;我女兒管我叫爸爸,但我卻管她叫媽媽;我還得管我妻子叫姥姥,因為她是我後母的母親。不久我女兒,也就是我後母生了一個兒子,他是我同父異母的弟弟,他也得管我叫姥爺,因為他也是我的外孫。後來我妻子,也就是我姥姥生了一個兒子,他是我後母的弟弟,我是他的外甥,所以兒子管我叫爸爸,我管兒子叫舅舅。另外我是我妻子,也就是我姥姥的外孫,同時也是我姥姥的丈夫,所已我也是我的外祖父。又因為我妻子是我的外祖母,我的兒子,也就是我的舅舅是我的弟弟和我女兒的弟弟,所以我……我的天哪,這麼複雜的關係實在讓我傷透了腦筋,我只有一死才能得以解脫……”
————————————————————————插入完畢————————————————————
看完上面這個短文,不知道你是否和我一樣,覺得這麼一個簡單的程式將是如此難做啊。另外,我決定在下一次的面試中讓應聘者來設計Family Tree的程式。
我又說多了,現在還是讓我們回到技術上來。除了上面那幾個觀點,我在回複中還看到了如入一些有意思的回複:
- “我的軟體沒有bug,是你的生活有bug”——讓我想到了程式員慣用的借口
- “演算法中不應該加太多的限制,限制多了反而讓演算法不靈活。”
- “移除斷言,並不代表就不出錯,對於這種rare case,我們最好給一個Warning提醒使用者,讓使用者確認確實是這樣的。”
- “關於解決這個問題,移除那個斷言,如果顯示上會有問題的話,那就複製一下有不同關係的人就可以了”
- “你真的應該想想你的軟體的價值是什嗎?市場在哪裡?你真的要照顧這樣的使用者嗎?”
挺好的,相信你對軟體開發又學到了一些東西。