2009年12月31日木曜日

SWE637ふりかえり

今セメスターからMS Software Engineeringコースにおける必須科目となったこのコース「Software Testing」。このコースでは、ソフトウェアテスティングの道具として、今までの研究成果として見出された様々なテストカバレッジクライテリアを学びつつ、それらをどのように効果的に使用するかについてコースの後半に駆け足で学びました。その過程で感じたのは、
  1. ソフトウェアテスティングにおいて銀の弾丸はない
  2. ソフトウェアテスティングは設計・実装と同じかそれ以上に経験と知識が要求される
ということです。実際のソフトウェア開発現場では、ソフトウェアテスターが開発チームにおいて尊敬される存在であって、プロジェクトを技術的にリード・教育する、という考え方が浸透すべきだ、と学びました。講義の中で先生が示された、ソフトウェアテスターに対する面白い喩えが「スペルチェッカー」でした。英語の文章を書いているとき、スペルチェッカーがスペルをテストしてくれるだけでなく、それらのテストを通じて私達はスペルを学ぶこともできます。

クラスで成績1番でした
このコースの成績は「A+」でした。先セメスターに受講したSWE642と同じく、講師Dr. Offuttが「A+はクラスでtop gradeだった一人だけにしか与えない」という方針をおっしゃっていたので、私はtop gradeだったと思います。実際、今セメスターの終盤、講師と雑談をしているときに、宿題やクイズの成績を見て「Kojiは明らかにtop studentだ。Kojiのgradingは他の学生より厳しくしなくちゃ」と冗談ぽく言ってくださいました。今回のクラスでも、会社勤めをしながら講義を受けるパートタイムの学生が多く(約40%ぐらい?)、私より年上の人もたくさんいました。残りの40%はインド人の学生、残りの20%は中国人の学生、という感じでしょうか。このような中で良い成績をいただけたので、自信になります(というか、就職活動を考慮すると、もっと自分に自信を持たなくては、と自分に言い聞かせています)。

このコースが難しい理由
このコースでは、多くの学生が苦労しているようで、Aの成績を取る学生はクラス内でたいてい30%以下だそうです。その理由は、おそらくこのコースで学ぶ以下のTest Coverage Criteriaが離散系数学・情報科学と深く関わっているからだはないかと想像します。
  • Graph Coverage
  • Logic Coverage
  • Input Space Partitioning
  • Syntax-Based Testing
Graph Coverageではグラフ理論、Logic Coverageでは論理、Input Space Partitioningでは集合、Syntax-Based TestingではBNFや正規表現が関連しています。宿題やクイズでは、これら情報科学について理解できていないと正しく答えられないことが多かったはずで、特にクイズの平均点は概ね低い日が多かったと記憶しています。

2009年12月30日水曜日

SWE619ふりかえり

SWE619のタイトル「OO Software Specification and Construction」に含まれる”Specification"という言葉が暗示するように、このコースでは、他人に使われることが前提のソフトウェアモジュールをどのように作ればよいか、を学びました。

おかげさまで成績は「A+」でした。成績の内訳は、宿題33%、クイズ33%、期末試験34%で、宿題およびクイズは満点でしたし(そのつど結果は返されました)、期末試験でも全問正解の自信があったので、成績全体で満点に近かったと思います。

期末試験でバグ発見
期末試験は教材持込可で、問題のほとんどは、与えられたソースコードを基に設問に答える形式でした。このコースで学んだ内容を効果的に問う、とてもよく考え込まれた設問ばかりでした。その中で、与えられたコードの問題点を指摘する設問において、出題者の意図と明らかに逸脱したバグを見つけてしまい、試験中に先生に確認したところ、先生は「ボーナスポイントあげる」を苦笑いしていました。

このコースで学んだ内容
冒頭で述べたように、他人が使われることを前提にしたソフトウェアモジュール(メソッド、クラス)を作るのに必要な仕様の定義方法、考え方、同仕様に対する実装方法等を学びました。また、Effective Java第2版の内容を学びました。どれもうなるような奥深さで、毎回クラスや宿題が楽しかったです。特に印象に残っているのは(というか、学んだ内容全て体に染み付けないといけないのですが)、
  1. Substitution Principle(継承の原則?)
  2. equals()の注意点
  3. clone()の注意点
  4. Concurrencyの難しさ
1. Substitution Principle
今回のコースを通じて、継承を使うことにはいかに多くの危険性があるかを思い知りました。そして、継承の本質として、「Substitution Principle」の大事さを痛感しました。この本質を分かりやすい例で説明すると、StackクラスはVectorクラスを継承すべきではない、ということです。正直言うと今まで、読みやすい、あるいは重複のない、といったことに注意してコードを書いていましたが、それほど深く考えずに継承を使っていました。特に、他人に使われるであろうクラスを作成するときは、とても気をつける必要があります。

2. equals()の注意点
1.にも関連しますが、インスタンス化可能な親クラスを継承した瞬間、equals()を正しく実装することは不可能だ、という事実を学び、正直驚きました。

3. clone()の注意点
これまた1.にも関連しますが、自分のクラスが他人によって継承可能な場合、コンストラクタを使ってclone()を実装したらアウト、という注意点を学びました。基本的にclone()は使わず、ファクトリメソッドを提供すべきですね。

4. Concurrencyの難しさ
何年経っても、並行プログラミングの難しさには閉口させられます(だじゃれです)。まして、他人が使うことが前提とされているマルチスレッドモジュールを作成する、あるいは他人が複数のスレッドを使ってアクセスするモジュールを作成するとなれば、格段に問題は難しくなります。Effective Javaにおいて何度も参照されている「Java Concurrency in Practice」は、近いうちに読む必要がありそうです。

すでに分かっていることながら、今回改めて痛感したのは、ソフトウェアの品質は開発者の経験および知識によって大きく左右される、ということです。多くの経験と知識を持つ先人がその経験・知識をEffective Javaのような素晴らしい書籍に残してくれるのはとても素晴らしいことだと思います。私達は先人が残してくれた知識を注意深く学ぶべきだと思いました。ただ、どうしても人間は、先輩が注意してくれても自分が痛い目にあわないと十分に理解できないことが多いのではないでしょうか。私も、Javaを学び始めてしばらくしてEffective Javaの第1版を読み、内容を理解したつもりでも「ふーん」ぐらいにしか思えず、その重要さを理解できていませんでした。その後、ある程度実装経験を積んだ段階で、上記のようにそれらを学びなおしてみて「そうそう、これはかなり重要!」と感じ、脳に強く焼き付けることができました。

2009年12月21日月曜日

大雪

12月19日土曜日は、日本や欧州各地で大寒波に見舞われたようで、私が住むワシントンDC近郊もたくさん雪が降り積もりました。おかげさまで、期末テストが終わってリラックスしながら大雪を自宅の部屋から見守っていました。

次の日の日曜日は晴天になりました。下の写真は自宅アパートの駐車場の様子です。すっかり車が雪に埋もれてしまっています。子供達は大喜びで雪遊びです。今日は、次の日に備えて車が出れるよう雪かきをしました。日曜日の時点で、周辺の道路は除雪されて、ノーマルタイヤでも問題なく車が走れる状態のようで安心です。