なぜ小さなチームが重要なのか?システムの品質面からの考察

システム全体の品質は、そのシステムを構成する各要素の品質の積で表現される。


photo credit: thebmag via photopin cc

システムは一つでも欠陥があると全体として欠陥があるとみなされる。なので、例えば90%の信頼性のモジュールと90%の信頼性のモジュールを組み合わせたシステムを作ると、両方において問題が発生していない確率は81%となり全体としての信頼性も81%となる。

このようなパターンはシステムとモジュールの関係だけに当てはまるわけではなく、組織やプロセスにおいても仕組み(システム)である以上同じように当てはめることができる。一人がミスをすればお客様からの信頼を失うってしまうことは、個人という構成要素が会社というシステム全体の品質を左右しているといえるし、生産工程の中で一行程で問題が発生した場合に全行程が止まってしまうことも同様である。

では、システム(仕組み)の品質を上げるためにはどうすればよいのか?

各要素の品質をあげることができれば、それに超したことはない。しかしコストと品質の関係は逓減関係にあるため、品質を60%から61%へ上げるのはそれほどコストがかからなくても、98%から99%へ上げるのにはより多くのコストがかかる。そのため、各要素の品質を上げるのは次第にコストに見合わなくなってくる。

それを打開する方法の一つが”冗長化”をすることだろう。一人がミスをしてもカバーできるようにその人の仕事をチェックする人を設けておけば事故を未然に防げるし、あるサーバが止まっても大丈夫なように複数台のサーバを事前に準備しておくことでサービス全体が止まるという事態を避けることができる。冗長化の場合、例えば90%の信頼性の部品と90%の信頼性の部品を組み合わせた場合、両方に同時に問題が発生する確率は1%なので結果として99%の信頼性を担保できるようになる。

とはいえ冗長化もコストはかかる。そのコスト次第では割にあわなくなってくる。他に解決方法はあるのだろうか。それが”構成要素を少なくする”というアプローチだ。90%の品質の要素が3つあった場合、2つに減らすことができれば、それだけでも10%近い品質向上につながる。要素が減ることにより品質を上げつつコストも減らすことができる。ただ賢明なみなさんはお分かりかと思うが、単純に構成要素を減らすと全体が成り立たなくなるため、要素が少なくても成り立つような仕組みを再デザインすることが重要となる。

普通の感覚では大きな方がよしとされがちなので「小さなチームを目指します」といってもあまりピンとこない人も多い。ただ、システムの世界においては小は大より優位性がある。小さなままでいることで品質を効率的に高めることができるため、極力小さくとどまれるように工夫をしなければならない。チームを小さく保つこと、ソフトウェアを小さく保つこと、ユーザインターフェースを小さく保つこと、なぜそういうことが大切なのかを今までうまく説明できていなかったので改めて整理をしてみた。

Ubuntu on VirtualBox ベンチマーク @ Mac OS Lion

Mac Book AirでWebの開発環境を作るときに、homebrewなどでごにょごにょするのもありなのだけど、できれば本番環境に近い環境で動かしたいし、できればデスクトップの開発環境(Ubuntu)とシームレスに利用できるようにしたいというところから、UbuntuMac OS Xの仮想環境上で動かしてそこで開発をするようにしている。この方法はバッテリーの持ちが悪くなるという難点に目をつぶれる場合はとても便利がよい。個人的には、外でも電源があるところで作業することが多いので2時間もてば十分だったり。
Linuxディストリビューションの癖を覚えるのは運用上メリットがあるが、Mac OSのそれは知っていても価値が少ないので積極的にスルーすべきかと思う。

  • Ubuntu11.10 on VirtualBox 4.1.8 環境における UnixBenchの結果
========================================================================
   BYTE UNIX Benchmarks (Version 5.1.3)

   System: vbox-VirtualBox: GNU/Linux
   OS: GNU/Linux -- 3.0.0-12-generic -- #20-Ubuntu SMP Fri Oct 7 14:56:25 UTC 2011
   Machine: x86_64 (x86_64)
   Language: en_US.utf8 (charmap="UTF-8", collate="UTF-8")
   CPU 0: Intel(R) Core(TM)2 Duo CPU U9600 @ 1.60GHz (1309.8 bogomips)
          x86-64, MMX, Physical Address Ext, SYSENTER/SYSEXIT, SYSCALL/SYSRET
   22:41:02 up  2:02,  1 user,  load average: 0.87, 0.51, 0.27; runlevel 2

------------------------------------------------------------------------
Benchmark Run: Thu Feb 09 2012 22:41:02 - 23:09:10
1 CPU in system; running 1 parallel copy of tests

Dhrystone 2 using register variables       14299760.9 lps   (10.0 s, 7 samples)
Double-Precision Whetstone                     1754.3 MWIPS (10.0 s, 7 samples)
Execl Throughput                                218.7 lps   (29.9 s, 2 samples)
File Copy 1024 bufsize 2000 maxblocks        427812.6 KBps  (30.0 s, 2 samples)
File Copy 256 bufsize 500 maxblocks          153084.6 KBps  (30.0 s, 2 samples)
File Copy 4096 bufsize 8000 maxblocks        780663.8 KBps  (30.0 s, 2 samples)
Pipe Throughput                              963042.6 lps   (10.0 s, 7 samples)
Pipe-based Context Switching                  26066.5 lps   (10.0 s, 7 samples)
Process Creation                                447.6 lps   (30.0 s, 2 samples)
Shell Scripts (1 concurrent)                    536.5 lpm   (60.1 s, 2 samples)
Shell Scripts (8 concurrent)                     67.3 lpm   (60.6 s, 2 samples)
System Call Overhead                        1397670.5 lps   (10.0 s, 7 samples)

System Benchmarks Index Values               BASELINE       RESULT    INDEX
Dhrystone 2 using register variables         116700.0   14299760.9   1225.3
Double-Precision Whetstone                       55.0       1754.3    319.0
Execl Throughput                                 43.0        218.7     50.9
File Copy 1024 bufsize 2000 maxblocks          3960.0     427812.6   1080.3
File Copy 256 bufsize 500 maxblocks            1655.0     153084.6    925.0
File Copy 4096 bufsize 8000 maxblocks          5800.0     780663.8   1346.0
Pipe Throughput                               12440.0     963042.6    774.1
Pipe-based Context Switching                   4000.0      26066.5     65.2
Process Creation                                126.0        447.6     35.5
Shell Scripts (1 concurrent)                     42.4        536.5    126.5
Shell Scripts (8 concurrent)                      6.0         67.3    112.2
System Call Overhead                          15000.0    1397670.5    931.8
                                                                   ========
System Benchmarks Index Score                                         304.4

Amazon EC2のMicroインスタンスのIndexが100弱らしい。普段使っていて不便は感じない程度の性能は出ています。

視点を変えるだけで生産性を数倍にできる「複利の仕事術」

今回は仕事の生産性について書いてみました。20〜30代の若手の社会人の方向けのエントリーです。仕事の生産性を上げたいとき皆さんはどうされています?今日は生産性を上げるために、自分が意識していることを紹介したいと思います。


photo credit: hawkexpress via photopin cc

複利の仕事を意識しよう

結論から言うと、普通の人の数倍の生産性を上げたいのであれば、仕事にコミットする時間や集中力に加えて、何に取り組むかを正しく選ばなければなりません。そして仕事を選ぶときは、それが複利の仕事であるかどうかを考えて選んでください。

複利の仕事とは何でしょうか?複利というのは、銀行の金利を説明する際によく使われるとおり利子(得られたリターン)が次の元本に含まれるようになることです。単利と複利とでは1、2年ではそれほど差がつきません。しかし数年と時が経つにつれて差が開いてきます。例えば同じ年率20%の効用があるとした場合、単利と複利では以下のような違いが出てきます。

1年 2年 3年 4年 5年 6年 7年 8年 9年 10年
単利 1.20 1.40 1.60 1.80 2.00 2.20 2.40 2.60 2.80 3.00
複利 1.20 1.44 1.73 2.07 2.49 2.99 3.58 4.30 5.16 6.19

10年経つと大きく差が開きます。もし「え、10年も長い時間をかけて3.00と6.19って、これだけしか違わないの?」と思った方もいるかもしれません。分かりやすく収入におきかえてみましょう。入社当初年収が200万の人が、単利の仕事のみをしたとき10年後には生産性は3倍になっています。つまり年収は600万となります。一方で複利の仕事をした人の年収はどうでしょう。この計算では年収は1240万になるということです(そして更にその先は大きく差がついていきます)。

単利と複利の違いで恐ろしいのは、1、2年ではそれほど差が見えないということです。自分の仕事が単利なのか複利なのかを見分けることができなければ、10年後になって初めてその違いを実感するということになってしまいます。

さらに恐いことに仕事は単利の仕事と複利の仕事以外に、消費の仕事というものがあります。それは利率0%の仕事です。仕事の効果がワンタイムで消費されてしまうようなルーティンワークは利率0%の仕事です。その場合生産性はずっと1.00のままで、収入は増えません。世の中は、消費の仕事であふれています。意識をせずに仕事をしていると単利すら得られない状態になるので注意をしましょう。

では複利の仕事を見つけるにはどうすればいいのでしょうか。それは複利の原則に戻って、「得られたリターンが次の元本に含まれるような仕事」を探せばよいのです。そして、複利の仕事には2種類あります。一つは効果を指数的にのばす仕事、もう一つは指数的にのびるコストを押さえる仕事です。

効果を指数的にのばす仕事とは

効果といっても、それは売上のように見えやすいものだけではありません。例えば、人に教えることで周りの人の生産性があがり、その人々が更に周りの人に対して教えることで生産性があがる連鎖を生むことができれば、それは複利の仕事だと言えます。

しかし、複利かどうかは自分がしっかりシビアに判断しなければなりません。周りの人に仕事を教えるだけでは、それは単利の仕事です。なぜなら教わった人が周りに教えるとは限らないからです。複利の仕事というのは、仕事を教えるだけにとどまらず、周りの人を教える方法を教えるところまでやって初めて複利の仕事になります。同じ教えるという行為でも、そのぐらい意識をするかしないかで単利の仕事になるか、複利の仕事になるか変わります。日々行っている仕事の中でも取り組み次第で複利の仕事にできるということです。

指数的にのびるコストを押さえる仕事とは

これはイメージがつきにくいかもしれません。例をあげると、ソフトウェアのコストが良い例かと思います。ソフトウェアのコストは人数が増えるたびに、またコードベースが大きくなるにつれて指数的にコストが伸びていきます。システム規模が大きいと、小さな修正を行うだけでも既存の巨大なシステムとの依存関係を意識した検証を行わなければなりません。修正の規模に関係なくリリースをするコストが増えていきます。例えばそのようなコスト構造を、システムの規模に関係なく修正ができるような仕組みを提供できれば、それは複利の仕事といえます。

複利の仕事の見分け方は伝わりましたでしょうか?先述の通り、単利と複利では最初それほど違いが出てこないので本当に合っているのかどうか不安に思うかもしれません。しかし継続すれば生み出せる成果は大きく変わってきます。ぜひ自分が携わっている仕事が消費の仕事なのか、単利の仕事なのか、複利の仕事なのかを意識して取り組んでみてください。

デザイン思考とソフトウェアデザイン

デザイン思考と聞くと、ビジュアルデザインに関することを想像しがちですが、プロダクトデザインやサービス開発にも用いられるイノベーションの技法です。デザインコンサルティングファームのIDEO社がデザインプロセスが注目されてから、次第にこの言葉を聞くようになってきました。


photo credit: Neil via photopin cc

デザイン思考はそれほど真新しい話ではありません。振り返ってみるとガイアックスで「スクールガーディアン」という世界初の学校裏サイトサービスを企画した時は、まさにデザイン思考的なプロセスで行っていたのだなと感じます。システム、オペレーション、マーケティングと機能が異なる部署のメンバーが集まって、試行錯誤しながらプロトタイプとなるサービスを企画し、協力して頂けるファーストユーザを探してサービスを提供しました。最初は全くシステム化されてもいませんでしたし、効率の悪いオペレーションとなっていましたが、ユーザのニーズに応えられるか否かを見極めて、フィードバックをもらうことは十分にできました。そういったフィードバックを受けて改善を行い今の形になって次第に近づいていったのです。学校裏サイト問題が2007年の7月に社会問題化してから、社内の有志数名で集まり、他の仕事も掛け持ちしながらも11月にローンチできたのは、フォーカスをプロトタイプに絞ったからではないかと思います。

一方で、ソフトウェアデザインにデザイン思考的なプロセスを持ち込むのはオペレーショナルなサービスデザインに比べて一段ハードルが高いと感じています。その要因はシステムの変更の難しさにあります。システムとはつまり体系のことです。プロトタイプを提供したところ、システムが目指していたコンセプトレベルで変更が必要となった時には、体系自体を変えなければならないためシステムを大幅に作り直す必要があります(時には0から作り直すこともあります)。つまりシステムデザインの世界に、デザイン思考を持ち込むためには、変化に強いシステムを作ることが前提条件となっているのです。

システムの業界では、変化に強いソフトウェアの制作方法として、アジャイル開発プロセスが確立されてきました。スタンドアップミーティング、イテレーション開発、自動テスト、リファクタリング、ストーリーポイント見積もり、継続的インテグレーション(CI)などのプラクティスはアジャイル開発の中から出てきたものです。

アジャイル宣言の一節に

我々は、
プロセスやツールよりも個人と対話を、
包括的なドキュメントよりも動くソフトウェアを、
契約交渉よりも顧客との協調を、
計画に従うことよりも変化への対応を、
価値とする。

とあります。
動くソフトウェアというのはプロトタイプ、顧客との協調というのはユーザ中心設計、変化への対応はフィードバックに基づいたプロトタイプの修正、といったようにデザイン思考とアジャイル開発は根底の思想でつながっているところがあるように見えます。

制作プロセスにおいても、デザインとテクノロジーの融合が重要で、デザイン思考とアジャイル開発の相補的な関係が良いプロダクトを作る土壌になるのではないかと考えています。

2011年を振り返って

今年は大きな動きがあった一年でしたね。年の瀬に、2011年最も印象に残ったことをテーマ別に振り返ってみたいと思います。

衝撃を受けた社会的変化

東日本大震災原発問題。今年はこれ以外は考えられないです。記憶が風化しないよう、来年も再来年も自分たちの問題として考え続けていかなければならないなと思います。

お会いした中で最も印象的だった方

大川加世子さん。Interop Tokyo 2011のパネルディスカッションでご一緒させて頂いたコンピュータおばあちゃんの会の代表の方。80才を超えて元気に活動されているのも驚きでしたが、お会いできてシニア世代のITとの関わりに持っていた固定観念をなくすことができました。

気になったテクノロジートレンド

JavaScriptの躍進。HTML5、Node.js、PhoneGapの広がりを見るとUIをJavaScriptで作る流れは決定的になってきていると思います。JavaScriptはしがらみが多い技術にもかかわらず、既存のベースを活かしつつマーケットに合わせて進化してきているのは素晴らしいですね。

新たに取り組んだこと

ハーフマラソン(27km)。これは完全プライベートですが、河口湖マラソンに初めて参加しました。途中膝の痛みでだいぶしんどかったですが、自分に甘えずに走りきることができたのはよかったなと思います。富士山のふもとで天気もよく、素晴らしい景色でした。

他にも、このブログを始めたり、海外採用へチャレンジしたり、YAPC::AsiaでLT発表したり、福岡の開発拠点立ち上げ準備したり、いろいろと取り組んだ一年だったなと思います。

どれも家族や周りの方からの支援があってこそのことだと思います。今年も一年ありがとうございました。

エンジニアのツボ

エンジニアでない方から、「エンジニアって何を楽しいと感じて、何を楽しくないと思うのか分からない」とよく言われます(^^;

この件については、Eric S. Raymondの How To Become A Hacker の 「III. ハッカー的心構え」が、うまく表現できていると思うので紹介します。

1. この世界は解決を待っている魅力的な問題でいっぱいだ
2. 同じ問題を二度解くような無駄はいやだ
3. 退屈と単純作業は悪
4. 自由は善
5. 心構えは技能の代用にはならない

エンジニアといえどいろんなタイプがいますが、上のような気質を持っている人が多いのではないかと思います。この5カ条を見て分かるのは、いわゆる”お仕事”と相反していることが多いということ。なので、私は一緒に仕事をする時にはその点を考慮して、そもそも仕事の内容から工夫するようにしています。

チェックリストとして表現すると以下のような感じとなります。

  1. 解決する問題のテーマを面白いと思えるか
  2. 解決策が既に世の中で提供されていないか
  3. ルーティンワークやただ作るだけの仕事ではないか
  4. 自分の裁量は大きいか
  5. 仕事の姿勢でなく、スキルや成果で評価されているか

すべてを満たしている必要はないですが、こういった点を意識して仕事が楽しく、スムーズに行くといいですね!

私の構造的学習法<番外編>

実は構造的学習法に関連して理解しておいた方がよいことがあるので、今回は番外編ということで軽めのエントリーを書きたいと思います。

理解の罠

前編で出てきた概念ネットワークの本質は、概念の分割を行うことだという話をしていました。しかし、この概念を”分ける”という行為には、本質的にリスクが伴います。それは何でしょうか?

それは、概念を分ける行為は過度な一般化を伴うため、概念ネットワークはともすると固定観念の塊になりえるということです。

例えば、日本人とアメリカ人という概念を整理するとしましょう。きっとみなさんは二つの違いを思い浮かべると思います。国籍の違い、見た目の違い、言語の違い、考え方の違い、さまざまな角度から違いを洗い出していますよね。しかし、その違いってよく考えるとステレオタイプになっていたりしませんか?アメリカ国籍の人でも自分は日本人だと思っている人もいるでしょうし、日本語をしゃべるアメリカ人だっています。このように分けるという行為は一般化をすることが前提となっているため、固定観念化というリスクを伴っているものなのです。

私もそういった弊害が起きないように気をつけているつもりですが、それでも歳を追うごとに概念ネットワークが固くなって固定観念化が進んでいることを自分自身感じています。個人的には、願わくば目の前の現実に合わせて常に概念ネットワークを0から再構築できるぐらいの柔軟な人で居たいですね。

コミュニケーションの問題

誰ひとりとして同じ概念ネットワークを持っている人はいません。私たちが言葉を使う時、話し手と聞き手はそれぞれの概念ネットワークの中でその意味を解釈しています。その結果、話し手と聞き手の解釈が厳密に一致することはありません。

コミュニケーションの問題の原因は、すべてこのことを起因として起きています。

コミュニケーションというのは、概念ネットワーク間の通信とみなすことができます。自分の概念ネットワークに他の人の概念ネットワークの一部を取り込んだり、逆に自分の概念ネットワークの一部を他の人の概念ネットワークへ移植したりする活動がコミュニケーションです。

さびしい話ですが、私たちは実は一人一人が全く違う世界に生きていると言っても過言ではありません。そのことを受け入れて、そもそも各々考えが違うことを前提として話をすることが、コミュニケーションの問題を解決する一歩となります。コミュニケーションの目的は、発信者と受信者の考え方の違いをなくすことではなく、そもそもお互い何が違うのかを理解することにあるということを忘れないようにしましょう。