Lights on?

エンジニアの一日は問題解決の連続です。普段は当たり前すぎて意識していませんが、気にしてみるといかにそうであるかがわかります。

  • 落ちたサーバを復旧させる
  • 与えられた文字列を正規化するコードを書く
  • 関係者全員のスケジュールが合うようにミーティングをセッティングする

優れた解決方法を考えだすには、まず問題を正しく定義しなければいけません。

この記事では問題発見学の名著、「ライト、ついてますか」 から重要な点を引用して、どのようにすればより良い問題定義ができるかについて書きたいと思います。

注:引用が英語なのは原本しか読んでいないからです。”訳:”とあるところは自分で翻訳しただけなので日本語版の実際の言い回しとは異なります。 また今回読んだKindle版にはページ情報がなかったので、引用元はページ番号ではなくその引用があった章を代わりに書いています。

問題とは何か?

A problem is a difference between things as desired and things as perceived (3章)

訳:問題とはそうあるべき状態と今ある状態の差である

そもそも問題とはなんでしょうか?著者は問題を上記のように定義しています。 問題をこのように定義するといいことがひとつあります。それは、見方を変えることで問題が解決する可能性があることです。

とても時間のかかる処理があるとします。真っ先に思いつく解決方法は処理を早くすることです。しかし、見方を変えて 処理に時間がかかってもいいと考えたらどうでしょうか?バッチ処理にして夜中にやればどうでしょうか?このように見方を変えるだけで 問題そのものをなくすことができます。

Don’t take their solution method for a problem definition (4章)

訳:他人の解決方法を問題の定義としてはいけない

人が問題だと言っていることが本当の問題とは限りません。本に書かれている例が一番わかりやすいので要約して紹介します。

会社の購入担当者がある競売で一番有利になる競り方を考えるように命じられました。この競売にはとても複雑なルールがあり 沢山のケースを考慮しなければいけないと考え、考える限りのケース想定してその中で一番いいものを使うことにしました。

ケースの組み合わせは、4の11乗、4,000,000パターンありそのすべてをシミュレーションするようにプログラマのグループに命じました。 パターンが多いので普通にやると彼らのコンピュータでは12時間かかってしまい、それだと競売の時間までにぎりぎりです。

プログラマのグループは上司の自分たちの抱えている問題は4,000,000パターンの計算をいかにして高速化することだと言い、アドバイスを求めました。

上司は少し考え、購入担当者の部屋に言って詳しい競売のルールを聞きに行きました。

詳しいルールを理解した上司はベストな競売の方法を一瞬で導きだしました。

ルールを正しく分析すれば、4,000,000パターンの計算など必要なかったのです。

この話で学ぶことは、他人(購入担当者とプログラマ)が問題の解決方法だと信じた計算を本当の問題と考えてはいけないということです。 真の問題は4,000,000ケースの計算の高速化ではなく、競売で一番有利な方法を導きだすことなのです。

問題を解決する前に

問題がきちんと定義されれば解決することはさほど難しくありません。しかし、ちょっと待ってください。その問題はあなたの問題ですか? 本当にあなたが解決しないといけませんか?まずは、次の質問を自分に問いかけてみましょう。

Whose problem is it? (11章)

訳:誰の問題か?

本当にあなたが解決しなければいけませんか?もし、その問題が誰かの問題ならあなたが解決しようとするべきではありません。 もし、あなたの問題でなければ、頼まれないかぎり何もしないのがベストです。私たちは自分の問題解決に時間に忙しいはずですから。

Where does this problem come from? (14章)

訳:この問題はどこから来たのか?

この問いも問題が本当に自分の問題なのか調べるのに役立ちます。なぜ自分はその問題に直面しているのか?なぜこんなことになったのか? 自分に落ち度があるか?それとも、誰か他人に巻き込まれたか?

もし、問題の出所が自分であった場合は自分がしていることを正せばいいので解決は比較的簡単です。

Ignoring the problem (3章)

訳:問題を無視する

時には問題そのものを無視するのもありです。気づかないふりをしていまいましょう。問題は、あるべき状態と現在の状態の差ですが、 人間はすぐに適応する生き物です。最初はみんな問題だと感じてもいつの間にかそれが当たり前のようになるものです。

あなたが作り出したバグのワークアラウンドのために、オペレーションの人に余計な手動の作業が発生したとします。”近い内に直す”と言って、 1年も経てばワークアラウンド作業はオペレーションの業務に組み込まれて、その作業が当たり前のものになります。おめでとう! あるべき状態今ある状態 が同じになり問題そのものが消えました。

….もちろん、勧められる方法ではありませんがこれも一つの問題解決方法と言えます。

考えをやめない

あなたは問題を正しく定義して適切な解答を導き出しました。しかし、まだリラックスはできません。

Each solution is the source of the next problem (7章)

訳:あるひとつの解決方法は別の新しい問題を生む

私たちが問題を解決してもリラックスできないのは、その解決方法がまた別の問題を生み出すからです。これはエンジニアは直感的に理解していると思います。 PythonやRubyのような動的型付けなスクリプトプログラミング言語はそれまで他の言語が抱えていた問題を沢山解決しました。 インタープリタさえあればどこでも同じコードを走らせることもできるし、対話的にプログラミングすることもできます。 メタプログラミングを使うことで動的にコードを生成することでコードのDRY化をもたらしました。

しかし、今では動的片付け言語がもたらした解決方法は他の問題を生むことは広く知られています。インタープリタを挟むのでスクリプト言語の実行速度は遅く、 メタプログラミングはコードをデバックしずらくして、コードの保守性を下げてしまうことがしばしばあります。

PythonやRubyがもたらした過去の問題への解決は新たな問題を生み、今度は静的型付けの言語がそれらの問題を解決すべく注目されています。そして、この連鎖は恐らくずっと続くでしょう。

これに対してできることはそれほどないはずです。一つ言えるのは、問題への解決方法が新たな問題を生む、ということを認識して常に考えることをやめないことです。

The really important thing in dealing with problems is to know that the question is never answered, but that it doesn’t matter, as long as you keep asking (第6章)

訳:最も重要なことは問題は解決されることがないと知ることだ。しかし、考えることを止めなければは大したことではない。

無事に解決方法を見つけても、その解決方法が最も正しかったかどうかはわかりません。それどころか、問題定義がそもそも正しくなかったかもしれません。 自分の出した答えが完璧だったと信じることが一番厄介です。なぜなら、完璧な答えなどないからです。だから、私たちは常に問題を振り返って見直さなければいけないのです。