2015年2月15日

Making Software を読んだ

O'Reillyから出版されている Making Software を読みました。 ソフトウェア工学研究者たちのエッセイ集になっており、Beautiful Code: Leading Programmers Explain How They Think のような書籍です。 内容はソースコードの書き方の話ではなく、プロジェクトマネジメント寄りの話題と言えます。 即効性は期待できませんが、知っておくと見通しがよくなることが多い印象です。 具体的にどの指標を参考にするかは、本書を読んで自分のプロジェクトのコンテキストに合わせて調整すると良いでしょう。

推測や思いつきではなく、現場における実際のデータや実験によるデータに基づいて、実証的にソフトウェア開発のあり方を改良しようとする立場に立ったソフトウェア工学のことを実証的ソフトウェア工学(empirical software engineering)と呼びます。 ソフトウェア開発の現場で感覚的に語られていることに対して、できる限りのデータを収集して定量的に分析している点が特徴です。 例えば、ソースコード管理システムに巨大なコミットがあるとレビューが大変ですが、具体的に何行を越えると不具合の可能性が高まるのかを各種の統計量を用いて調査しています。 すべてのエビデンスが万人受けすることはありませんので、結果を提示する人はそのときの想定読者に合わせて内容を調整します。 研究者と読み手のコンテキストの共有が不十分だと「でも一体、それの何が良いの?」となりますので、観測したものを法則として認識し、それを説明する理論を構築できるかどうかが、この分野での挑戦となります。 詳細は A Handbook of Software and Systems Engineering: Empirical Observations, Laws and Theories を参照してください。

書籍は2部構成で、最初は一般的な原理、次に個別の話題を扱います。 各部とも割と独立した章から構成されますので、目次と図表をパラパラと眺めて興味を持てそうなところを読むと良いと思いました。


第 Ⅰ 部 エビデンスの探求と利用に関する一般的原理

コンテキストをうまく共有するためには、信頼性(Credibility)と妥当性(Relevance)という概念を理解すると良さそうです。 特に、信頼性のためには、高い妥当性があるということに加え、よい報告がなされていて、読み手がその調査をいつ、どのように応用すべきか分かるということが必要です。(19ページ)

  • 信頼性:提示されたエビデンスとそれについての主張を、あなたがどれくらい信じようとするかの度合い
  • 適合性:あなたがエビデンスとその内容に興味を持つ度合い

読み手としては、測定を中心とした「量的調査」と、記述や分類に関係する「質的調査」を区別することが肝要です。 どちらが優れているということではなく、両方の要素が連続的に含まれていることが大事です。 ソフトウェア工学は社会的なコンテキストやプロセスを扱いますので、アルゴリズムの性能調査とは異なる探求が必要なためです。 様々なエビデンスを統合する上では「システマティック・レビュー(Systematic Review)」の活動が奨励されています。 元はイギリスの国民保健サービスから始まったものですが、ソフトウェア工学でも徐々に使われるようになってきているそうです。 関連研究の偏りを減らしたりリサーチクエッションを規定するようなアカデミックな話題が多いですが、コスト見積もり調査にも SR が使われます。 予算と期限の妥当性を評価するには多様な視点が要求されますが、PBR (Perspective Based Reading), AHR (Ad Hoc Reading), CBR (Checklist Based Reading) などを意識してドキュメントやソースコードを読むと論点がはっきりすると思いました。 リーディング技法・インスペクション手法に関しては以下の記事が分かりやすいです。

一般的なプロセス改善の課題として、たとえ何もしなかったとしても同様の成果が達成されたかもしれない、という主張があります。 ソフトウェア開発においても、新しい手法を身につけなくてもコストとスケジュールを守って製品を完成できるかもしれない、と言い換えられます。 このため、経験に関するモデルを開発するには製品開発とは独立なものとして表立ってサポートしないとその活動自体が生じず、開発プロセスの質の向上は難しいと言えます。 データ収集そのものを目標駆動として認識できるかは組織の文化にも依存しますが、NASAソフトウェア工学研究所での数十年の経験が語られている点が本書の良いところでしょう。 「すでに大きくなったソフトウェア開発組織の中堅を変えることはできない」というブログ記事もありますが、経験モデルの構築に組織的に取り組めるかどうかで技術移転の進めやすさ、学習プロセスのスピードは変わってくるように感じます。

組織的な取り組みよりも、生産性は個人に強く依存する場合もあります。 その個人の生産性を測るもしくは向上させるには何をすべきかも議論になりがちです。 ひとつの事例集としては Robert L. Glass の以下の記事が有名だと思います。

本書では、プログラマーの優劣に性格が関係するのか、知能指数や一般知的能力 (GMA; General Mental Ability - g factor (psychometrics)) の影響はあるのか、専門性とは何でありどのようにそれを高めるのか、といったことに言及しています。 これらの問いに対する唯一の解はありませんが、Reflective practice、要するに、日々の活動を自省してよりよい方法の発展を模索すべき理由が見えてくると思います。 重要度と緊急度でマトリクスを構成したときに、「重要/非緊急」な計画・発展象限に目を向けるきっかけになるかもしれません。

ある程度の期間に渡ってソフトウェアを開発すると、だんだんとソースコードが複雑になってくることが多いはずです。 しかし、一概に複雑と言っても計測手法は無数に存在します。 ソースコード行数が多いのか関数が多いのか、循環複雑度が高いのかオペレーターが多くて難しさが高いのか、参照するメトリクスに依存することも多いでしょう。 そこで、これらのメトリクスを統計的に分析した試みが8章にあります。 実際の開発現場でも SonarQube™ (Sonar から名称変更) などで簡単にメトリクスを算出できるはずですので、本章の結論と実際の計測値を比較してみると興味深いはずです。 CLOC -- Count Lines of Code を使うとファイル数、行数、コメント行数などを簡単に確認できます。 プロジェクトの進捗に合わせてどの数値がどのように変化するかを追いかけるだけでも、実装スピードの目安を定義できるようになるでしょう。

最近はトラッキングシステムの Web サービスを使うチームも増えてきているはずです。 規模の異なる複数のチームが同じサービスを使うことで、サービスプロバイダーには多様なデータが蓄積されます。 こうしたデータの分析結果を公開してくれている事例もありますので、参考にしてみると良いと思います。


第 Ⅱ 部 ソフトウェア工学における個別の話題

第 Ⅱ 部は章ごとの独立性が高くなっています。 企業かオープンソースを問わず、具体的なソフトウェアのことを題材にしているためです。

9章では AT&T のソースコード行数が30〜50万行の6つのシステムを対象に分析しています。 数十万行のシステムではバグ管理が難しい課題になります。 そもそもどこを重点的にテストすべきなのか、どのバグから改修すべきなのか、次回のリリースに間に合うのか、といったことを判断しなければなりません。 このため、体系的な欠陥報告、変更管理、バージョンコントロールが極めて重要です。 この章では、バグが強い非対称性を持ってコード内に存在しているエビデンスを提示し、欠陥を含んだファイルから予測モデルを構築することで、次回リリース時に欠陥のありそうな上位20%に対して特別な注意を払ったことを説明してくれます。 当然ながらバグ混入率はシステムによって異なりますが、仮にバグがパレート分布のように存在しているならば、上位20%に対処するだけで全体の80%を特定できるかもしれません。

10章はバリー・ベームが書いています。この人の功績やそれを取り巻く状況は ICSE 2007 のパネルディスカッションが分かりやすく、このときの様子は以下の記事に記載されています。

プロジェクトには要求、設計、開発、受け入れなどのライフサイクルがありますが、初期段階での投資とその後のフェーズにおける修正コストの関係性をテーマにしています。 基本的には、大規模ソフトウェア開発で時間経過に対する変更コストの増加率を見積もることをテーマとしており、納品後のソフトウェアに対する変更は要求フェーズにおける変更の何倍のコストがかかるのか? という疑問に対して複数のエビデンスを提示します。 COCOMO® IICMM; Capability Maturity Model を検討もしくは導入したことがあると、ふむふむという感じかもしれません。


11章はコンウェイの法則に関する内容です。 「システムを設計する組織は、その構造をそっくりまねた構造の設計を生み出してしまう」という主張の証明は難しいですが、その誤りを証明しようとして失敗するたびにその理論に関する確信が高まるという、実証哲学の視点で記述されます。 対象とするデータも興味深く、Windows Vista 開発時の Microsoft 社における技術者の人数、元技術者の人数、編集の頻度、主所有の深さ (DMO; Depth of Master Owership)、開発に寄与する組織の割合、組織上のコード所有レベル、組織上の所有権、組織の交差因子を扱っています。 開発者が数千人にも及ぶと、あるバイナリのバグ改修に誰を割り当てるかだけでも大変だと思いますので、コーディネーションが全体の生産性に与える影響は絶大と言えそうです。 本章では伽藍とバザールの関係も意識して、オープンソースの開発者たちの技術的構造とコミュニティ構造も分析しています。 社会構造と技術構造は別々に議論されることも多いと思いますが、開発物の規模によっては考え直しても良さそうです。

12章はテスト駆動開発の効果を述べています。 最近では TDD is dead. Long live testing. (DHH) というブログ記事も話題になり、TDD に関して決定的なエビデンスはありません。 本章が興味深いのは、TDD を架空の医薬品に見立てて SR (Systematic Review; 前述) を実施している点です。 病気に対して薬を飲むことは難しい問題で、服用する頻度や量、他の薬との飲み合わせやジェネリック医薬品での違いなど、治療効果のほどは一概に判断できません。 確実に効果のある薬を飲んでいるはずなのに生活習慣が悪くて症状が改善されないこともあるでしょう。 また、治験のように外的要因をどこまで制御できるかも悩ましい問題です。 こうしたことをソフトウェア開発に照らし合わせて有効性を検証してみると、感情に流されない議論ができるかもしれません。 なお、TDD が全てを解決できるわけではないとは Kent Beck も認めています。Kent Beck's answer to Does Kent Beck use TDD at Facebook? How? - Quora

13章は「コンピュータサイエンスに女性が増えない理由」です。 本章冒頭で紹介される、1985年はCS (Computer Science) の学士号の37%は女性に与えられていた、という統計データは興味深いと思います。 個人的には、元々男性しかおらず徐々に増えて10〜20%くらいになった、と勝手に思っていたのですが、CS 専攻に興味を持つ女性が減っているそうです。 アメリカでの統計ですから日本では事情が異なるでしょうが、思い込みで脳の機能やホルモンの要因、社会的・文化的な理由を論じてはいけないなと思いました。 能力に関する話題、経済面での切り口、国別比較など、いくつかのエビデンスが提示されていますが、最終的な目標は CS 職の質と有効性と進歩である、と締められている点が、いかにも研究と言える内容だと感じました。

14章では、特定の探索アルゴリズムに特化したプログラムとSNSのようなWebアプリを複数のプログラミング言語で実装し、その性能や頑健性、変更容易性などを比較する研究です。 アドホックな会話の場合、成果物の違いはプログラミング言語が影響するのかそのプログラマの力量が影響するのか、という点が欠落してしまうこともありますが、本章ではできるだけ一貫性を保ってデータを収集したとのことです。 「有能なプロの人が使う場合、PHP は評判以上にかなり良好です」(242ページ) という記述には苦笑を禁じ得ませんが、定量的に比較するときの指標などは参考になると思います。

15章は OS のソースコードを分析しています。 分析対象は FreeBSD, Linux, OpenSolaris, Windows Research Kernel (WRK) の4つです。 具体的に何の指標をどのように比較しているかは本章を読んで頂くとして、現実世界で広く利用されているソフトウェアは要求もより高度になりがちなので、 それに合ったプロセスであれば結果は似てくる、つまり形態は機能に従う、とのことです。 ソフトウェアのソースコードをどういった人が読むかによってコメント量やプリプロセッサの使い方に特徴はあるようですが、 超大規模になるとオープンかクローズドかというプロセスの影響は小さいようです。


16章はプログラマーの時間の使い方に関する研究です。 1年分の日記調査と1週間分の観察調査を実施し、誰と何について話し、どのようにソースコードを書いているかを分析しています。 頭脳労働の生産性を考えることは難しいですが、つまづくパターンが明らかになれば予防策を講じることもできるでしょう。 特に、開発中のどのタイミングで何のドキュメントを書くかの認識を合わせられると、コミュニケーションの効率が良くなりそうです。 効率的にエラーに対処することで中心となるタスクに割り当てられる時間は増加するでしょうから、チーム内での情報の整理方法は定期的に見直した方が良いでしょう。

17章はペアプログラミングに関する内容です。 実践方法に慣れるまでに 2, 3 日 (およそ 8 〜 12 時間) ほどを必要とする (296ページ)、とあるように、最初の学習時間を考慮できるかどうかが導入の成否にも影響すると思いました。 特に参考になったのが「チームは、気が向いた時など構造化せずにペアプログラミングを実施したときよりも、たとえばペアプログラミングの時間を正式に設けたり、ミーティングで毎日ペアを割り当てるなど、ペアプログラミングに対して構造化・組織化されたアプローチを採用したときの方がうまく行きました」(297ページ) という部分で、明示的に意識付けすることでモチベーションも変わるように感じます。 プロジェクトの中でも高難易度の課題に関しては、共通に使う時間を設定して取り組む効果は大きいのかもしれません。

18章はコードレビューに関する内容です。 GitHub の Pull Request などで仕組みを導入する敷居は著しく下がったと思います。 では、何人くらいでどれくらいの時間を費やすのが良いのでしょうか? という疑問に対するエビデンスが本章であると言えます。 集中して長時間のレビューを続けると疲れて欠陥発見能力が落ちますし、速く読むと細かい点を見落とします。 レビューミーティングを開催すると目が増えて指摘の質が向上しそうな気もしますが、時間に見合った価値があるかは断言できません。 本章で紹介されているような、レビューごとの欠陥発見密度は良い指標と言えそうですので、参考になりました。

19章はオフィス空間のレイアウトに関する内容です。 書籍ピープルウエア - Amazon では、高い能率を発揮する人と作業場の環境には、相関関係はあるものの因果関係は見いだせないことが記載されています。 しかし、個人の作業効率とチームの作業効率は必ずしも一致しません。 プロジェクトの性質や規模、進捗状況により異なる作業パターンがあり、それぞれに要求されるコミュニケーションも異なるものです。 粛々と作業を進めるべきこともあるでしょうし、メンバーと何度も議論を重ねることもあるでしょう。 また、情報やタスクの流れが双方向か片方向かの違いもあります。 こうしたことを踏まえて、個室を用意すべきか大部屋にすべきかを判断すべきであり、パーティションで区切るのは中途半端なので避けるべきだそうです。 最近でも「仕切りのないオフィスが職場を破壊する | スラッシュドット・ジャパン」という投稿もあり、議論の続くトピックと言えます。

20章はグローバルなソフトウェア開発におけるコーディネーションに関する内容です。 技術的な要素と社会組織的な要素の二軸で生産性に及ぼす影響を議論しています。 実際、タスク追跡システムが記録した開発タスク間のオーバーラップ度合いが高い場合、開発されたソフトウェアの品質も低いことが分かった (340ページ) そうです。 また、プロジェクトの境界をまたがった依存関係がある場合、ソフトウェアの品質レベルが低下する傾向があるそうです。 確かに、外部インターフェイスが曖昧なシステムと統合するときは大変なので、個人の直感にもマッチすると思います。 複数の研究でこうした直感が定量的に裏付けられてくると、具体的な対応策も練りやすくなるのではないでしょうか。


21章はモジュール化の効果に関する内容です。 1つの修正に対して変更するコードは1つのモジュールに限定されていることが望ましいでしょうが、現実にはそうもいかないこともあります。 本章では Evolution, Firefox, Mylyn のソースコードを分析し、いくつかの分割パターンに整理しています。 変更するときに、余分なモジュールを多数調べてしまう開発者の大半は経験の少ない開発者 (365ページ) だそうです。 複数の分割方法があることを認識した上で、アスペクト指向プログラミング - Wikipedia を導入したり、類似の変更で以前に調べたモジュール群を眺められると、変更に要する時間が少なくなるかもしれません。

22章はデザインパターンに関する内容です。 やはりという感じの内容ですが、コメントなどにパターンが明記されていると複数のオブジェクトや相互作用を連想できるので、ドキュメント無しに比べて理解が進むそうです。 しかし、どのパターンでも一律の効果かと言えばそうでもなく、パターンを知らなくても理解や変更が容易なこともありますし、パターンによって保守にキャッチアップできることもあります。 開発時の有意性は実証されていませんが、保守の場面での品質と生産性の改善は期待して良いと言えます。

23章はエラー予測に関する内容です。 Microsoft 社の Windows Vista および Windows Server 2003 での事例研究が題材となっています。 メトリクスは1)コードカバレッジ、2)コード変更量、3)コード複雑度、4)コード依存度、5)人々と組織に関するメトリクス、6)統合 / 組み合わせによるアプローチの6種類です。 どれか一つ以上を計測している組織は多いかもしれませんが、これらを総合して分析している点が Microsoft 社ならではだと思います。 コード変更量や組織に関する指標は細分化して記述されていますので、自分のプロジェクトでも計測を開始する前には目を通しておくと良いでしょう。

24章はバグレポート収集に関する内容です。 報告者と開発者の間にある情報のミスマッチについて、具体的な項目ごとに調査結果を分析しています。 開発者にとって有用な情報が多く読みやすいバグレポートほど修正が早く行われる、というのは感覚的にも合致します。 報告者にスタックトレースの追加を促すのが一番ではありますが、Style and Diction - GNU Project のようなもので「ドキュメントの書き方に関する表層的な特徴を分析」するのも効果があるそうです。 取っ掛かりに悩む場合は、まずは Mozilla のバグレポート指針 (Bug writing guidelines | MDN) をプロジェクトメンバーで共有するのが良いと思います。

25章は欠陥が生じる開発フェーズと欠陥タイプに関する内容です。 分類方法やアンケート項目、その結果をどのように統計分析してまとめるかが具体的に説明されており、同じようなことを調査してみたい場合には参考になると思います。 興味深いのが、多様な分析の結果として、人頼みの防止策(アプリケーションウォークスルーや専門家の雇用、ガイドラインの強制など)を現在のプロセスに取り入れることが、欠陥防止に大きく役立つと言える点です。 アプリケーション全般について浅い知識しか持たないことが巨大システム構築時の重大な問題点となります (A field study of the software design process for large systems)。


26章は新卒者が組織に順応する要素に関する内容です。 大学教育ではプログラミングパラダイムなどの「固い」スキルを身につけますが、職場での実務には文書化やコミュニケーションなどの「柔らかい」スキルが必須となります。 Microsoft 社に新規雇用された8人を被験者として、タスク分析とビデオ日記での自省をまとめています。 ソフトウェア開発組織で社内研修プログラムなどを検討する上では、頭に入れておくと良い内容と言えます。

27章は自力でエビデンスをマイニングする流れを説明してくれます。 Eclipse プロジェクトを例として、ソースコード管理とバグトラッキングのデータを突き合わせて、変更とバグの分布を確認しています。 最も頻繁にバグ修正が実施されたモジュールの情報を手元に置くことで、重点的にテスト資源を集中できるようになるでしょう。 しかし、相関関係の発掘にはなりますが、因果関係を特定できるものではありません。 あくまでも決定を下すサポート情報として使いましょう。

28章はコピーペーストに関する内容です。 頭ごなしにダメとするのではなく、いくつかのパターンに分類して整理しています。 ハードウェアの違い、プラットフォームの違い、実験バージョンという3パターンは分かりやすいと思います。 抽象化のレベルやアプリケーション特性に応じて、リスクや品質を評価するのは今後の課題となります。

29章は API の使いやすさに関する内容です。 Visual Studio で作業するときに使う API のユーザビリティ改善について、当時の担当者が検討開始から問題への対処までを説明してくれます。 万人受けする API の設計と構築は難易度が高すぎるので、3つの開発者のペルソナを定義し、それぞれのシナリオに基づいて設計上の選択を考慮してきたことが分かります。

30章はプログラマの生産性に関する内容です。 著者はスティーブ・マコネルです。 生産性が10倍違う、上位20%の人がアウトプットの50%を生み出している、下位10%程度の人たちは負の生産性に寄与している、というキャッチーな導入に始まり、生産性の測定方法やばらつきをコンパクトに説明してくれます。 「組織が生産性を包み込む容れものとなり、その中でチームが能力を発揮します。非常に優れた組織で働く、平均的な能力の個人から成るチームは、二流の組織で働く、非常に優れた人材のチームよりも良い性能を発揮します。(536ページ)」ということで、個人的には最も参考になる章でした。


巻末に、エビデンスを生かしたソフトウェア開発を実施するための鼎談があります。 数年前の話にはなってしまいますが、日本の現場ではどうなんだ、という議論が展開されています。 書籍全般に渡る話題を扱っていますので、椅子のある本屋さんでザーッと読むと良いかなと思いました。

2014年10月16日

CentOS 7 と Docker のメモ

さくらインターネットの VPS で OS を CentOS 7 にしたのでメモしておきます。 VPS のデフォルトは CentOS 6 なので、手動でカスタム OS を選択しています。 ディスクのパーティション設定や管理者ユーザーの設定はインストーラーで終わっているものとします。

2014年6月22日

Python の学習資料 - 5

Python の学習資料を更新しました。

変更点:

  • Python 2.7 をベースにしていたものを Python 3.4 にしました。
  • fabric は Python 3 系に対応しきれていないので、そこは Python 2.7 のままです。
  • Django の導入みたいな記事を外しました。公式チュートリアルが充実しているためです。

多くの環境で利用されていると思われる Red Hat Enterprise Linux あるいは CentOS の新しいバージョンがリリースされます。 RHEL7 の標準は Python 2.7 なので、Python 3.x 系への移行に躊躇する人も多いと思います。 しかし、アプリケーションを動かすときに Docker のようなコンテナの利用を考えると、 Python 3.4 は移行のきっかけとして良い選択肢と言えます。 virtualenv と同等の pyvenv だけでなく、パッケージ管理の pip も標準でインストールされますので、 複数のプロジェクトを切り替えて開発する場合も安心です。