Jul 29, 2014

ソフトウェアのバグを見つけたときにやってはいけないこと

ソフトウェアのバグを見つけたときの対応には、プログラマとしてのセンスがけっこうあらわれると思っている。ぼくはセンスの無い人間の代表例みたいなものだから、ここにはぼくがよくやってしまう行動を思い返して書き、「ソフトウェアのバグを見つけたときにやってはいけないこと」とした。

バグを見つけたことを周囲に吹聴してはいけない

 

ソフトウェアにバグを見つけることや、ソフトウェアのバグを踏むことは、基本的に嫌なことだ。本当にそうだろうか。

有名なソフトウェアが不可解な挙動をするのを見たとき、周囲のひとびとをデスクに呼んで、

「いやー、このソフト、マジでクソですよ。こんなバグがあるんです。ほら、ひどいでしょ」

と毒づいているとき、ぼくは口を歪めながら、ある種のよろこびを感じている。それは、他者のプレゼンに対して不備を指摘するときのよろこびにとてもよく似ている。いうなれば「鬼の首を取ってやったぞ」という気分だ。

あら探しによろこびを感じるひとは少なくない。経験上、バグを見つけた側からそのことを周囲に吹聴するようなひとには、こうした傾向がある(ぼくがそうであるように)。そんなひとびとは「見つけたバグにどう対処するか」という生産的な思考がすぐにはできず、ソフトウェアの抱える不具合という「あら」につい矛先を向けてしまう。

これが悪化するとと、一度バグを踏んだだけで、だんだんそのソフトウェアを憎たらしく思えてくるようになってくる。ソフトウェアを敵視しがちになってしまう。しまいには、「俺の仕事がうまくいかないのも、全部このソフトのせいだ」なんていう被害妄想にすら発展することもある。

バグを見つけたと思ったら、周囲に話したくなる気持ちをぐっとこらえ、深呼吸をしよう。それでも収まりがつかないなら、テディベアにでも打ち明けてみればよい。

プログラマとしてのセンスとは、ソフトウェアを敵視しないことだ。

バグをすぐ直そうとしてはいけない 

 

バグを見つけたと思ったとき、「なんだよもう」 とぼやきながらソースコードをエディタで開き、問題のありそうな箇所にあたりをつけ、デバッグ文を仕込みーー。

それが、あなたのつくっているソフトウェアであって、時間が無尽蔵にあるのならばよい。しかし、そうではないのだとしたら。納期のある中、巨大なコードベースからなる著名なソフトウェアを前にしているのだとしたら。それは最善の選択ではないし、最悪の選択となってしまうことすらあるだろう。

もちろん、それが本当にバグだとわかったのなら、バグレポートを登録するぐらいは礼儀だと思う。しかし、ソースコードの修正までいくのは早計だ。ぼくらにとってバグを直すことは本来の目的ではない。

プログラマは手を動かし続けることが好きだから、ついつい問題が与えられると、それを解こうとしてしまう。目先の Yak-shaving に夢中になってしまう。Yak-shaving がどれだけ時間を奪うか、それを嫌というほど知っているにも関わらず、気がつけば Yak-shaving のなかにいる。

プログラマとしてのセンスとは、本来の目的を見失わないことだ。

バグを見つけたと思ってはいけない

 

そもそも、それはバグではないのかもしれない。

これまで、ぼくが「ソフトウェアにバグを見つけた」と思った経験のうち、実に半分以上は見事な思い違いだった。それは仕様だったり、ドキュメントを読んでいれば回避できる問題だったりした。「あのバグ、結局どうなった?」と同僚に聞かれ、勘違いだったとは言えずに赤面しながら言葉を濁した経験は枚挙に暇がない。

そんな恥をかかないためにも、まずバグを見つけたと思ったら、 そのことを疑ってみよう。ドキュメントをもう一度読んでみよう。そのソフトウェアに詳しいひとが周囲にいれば、恥ずかしがらずに聞いてみよう。こうした行為はもうひとつの視点を与えてくれ、それによって思い込みが正されることも少なくない。

プログラマとしてのセンスとは、思い込みを排除して、常に二つ以上の視点から問題に取り組むことだ。

免責

 

ぼくは残念ながらプログラミングを生業にすることができていない。趣味で十年近くプログラムは書いてきたが、いまだ上に書いたようなことをやらかしている。そういうわけで、この題材を選んだ。これは自戒の記事を出発点とするから、ごく個人的なことを、偉そうに一般化して書いてしまったきらいはある。許してください。

Jul 12, 2014

ひとと話をするとき、ぼくらが tf-idf に従っているということ

ぼくら技術者は基本的に技術の話が大好きなものだから、技術者同士で集まれば、ついつい技術の話をしがちだ。そんな調子で技術の話をはじめたとき、横で聞いていたひとりが、

「お前らは技術の話をやめろ。もっと一般のひとにもわかるような話をしろ」

と、諭すようにいって、はっとした。共通する話題は他にも多いのに、なぜぼくらは技術の話を選んだか。

帰り道、電車に揺られ名前も知らないひとびとの話にぼんやりと耳をかたむけているときふと思ったのは、

「ぼくらは tf-idf に従って話題を選んでいるのではないか」

ということだった。

tf-idf は情報検索の分野でよく知られた指標で、「ある文書における、ある単語の重要度」をはかる。その単語がその文書内に登場すればするほど重要度はあがり、その単語が他の文書に登場すればするほど重要度はさがる。ふたつめの点が面白いところで、これはつまり、「ある文書にとって、他のたくさんの文書に登場するようなありふれた単語は、あまり重要ではない」ということをいっている。

tf-idf で、文書をひとに、単語を話題に、置き換えてみる。すると tf-idf は、「あるひとにとって、ほかのたくさんのひとが持っているようなありふれた話題は、あまり重要ではない」ということを意味する指標に変化する。

技術を話題にできるひとは少ない。恋愛を話題にできるひとはそれよりも多い。天気を話題にできるひとはもっと多いことだろう。全世界あわせて71億人のなかのひとりと話すとき、71億人ができる話をしようと思うだろうか。貴重な話題を共にするひとに出会ったなら、せっかくの機会を活かそうとすることだろう。ぼくらは tf-idf に従っている。

そういう話を、どこか別の場所でした。ぼくはまだ技術から抜け出せそうにない。

Apr 26, 2014

研究のうまい見せ方

研究のうまい見せ方について話した。ぼくらのやっている高速化の研究は地味ではないか、とぼくが問題提起をして、先輩と二人で話した。そこで得た気づきがよかったので、ここに記す。

速度的な優位さをうたうとき、ぼくらは「○○倍の高速化を達成」と書きがちである。こうした高速化の数値は直感的でない。これは、研究の下手な見せ方だ。うまいひとは、それを具体的なことがらに結びついた数値に置き換える。例えば「カップラーメンをつくる際、従来方式では3分かかりますが、我々の提案方式をつかうと5秒ですみます」といった具合だ。これだけで、効果がぐっと訴えかけるようになる。数値の選び方にもコツがある。なるべく、聞き手にとって身近なことがらの数値をつかうのがよい。つまり、研究の見せ方は、聞き手にあわせて変えるべきものといえる。

研究内容が実際にシステムとして動くような場合であっても、ただそれを見せればよいというわけではない。むしろ、実際に動くものこそ、その見せ方には工夫が必要である。見せ方のテクニックのひとつに「対比」がある。これはやや即物的なフレームワークかもしれないが、有効と思ったので書く。まずやることは、自身の研究の応用例を、簡単にでもよいのでシステムとして実装することである。そのとき、自身の方式をつかったものと、過去の方式をつかったものの、ふたつを用意する。システムの用意ができたら、それらを並べて、同時に走らせる。そして、その様子を見てもらう。自身の方式をつかったものと比べ、過去の方式をつかったものの挙動がおかしかったり、のろまであったり、ぎくしゃくしていたりすれば、しめたものだ。それを見ているひとは、視覚的に、直感的に、ぼくらの方式の優位さを体験することだろう。
 
ぼくはこれまで「自身の研究のよさが一般のひとびとに伝わらないのは、研究が本質的に地味であるからだ」と考えがちであった。同じ思いを抱えているひとは少なくないだろう。そんなひとに向けて、この文章を書いた。

Nov 6, 2011

メッセージキュー

データストリーム処理の概念を聞き,その中で使われる DSMS (Data Stream Management System) の存在を知ったとき,多くの人が気にするのは「DSMS におけるストリームデータの入出力はどうなっているのだろうか」ということだろう.ストリーム情報源はいかにしてデータを DSMS へ送信するのか.そして,クライアントはいかにして処理結果を DSMS より受け取るのか.

データストリーム処理に関する論文を読む限りにおいて,こうした入出力はブラックボックスとして扱われることが多い.どのような分野であれ,何かしら「理想的な存在」を用意することにより,綺麗に論理立てが行えるようになるといったことがある.データストリーム処理において,入出力はその「理想的な存在」に対応する.

さて,その理想的な存在も,いざ実装を始めようとすれば,おとなしく理想的な存在でいてくれるはずもない.この記事では,その裏にある理想的ではない部分を覗いていくことにしよう.

実験レベルの実装

良く,論文の実験レベルでやられる実装は次のようなものだ.

入力
プログラム内にデータストリームを受信する関数を設け,その関数は(必要に応じてスリープ時間を加え)あらかじめ用意されたデータを次々と返却する
出力
標準出力に結果を書き出す

実際のところ,実験レベルであれば上記の実装で十分といえる.むしろ,このようにシンプルな実装にしたほうが,ノイズが少なく,本来観察したい部分の挙動に影響を与えにくい.

一方で,上記の実装は実用的なシステムとしては最低限の要件も備えていない.さて,その要件とは何だろうか.

最低限の実装

実用的な DSMS における入出力の最低限の要件としては,次のようなものがあげられる.

入力
DSMS とは別のプロセスが(同一マシン上にあるとは限らない),データを DSMS へ送信できる.
出力
DSMS とは別のプロセス(クライアント)が,クエリを登録し,その処理結果を DSMS から受信できる.

こうした要件を満たす実装としてはどのようなものが考えられるだろうか.

一つは,ごく単純な INET のクライアント・サーバの実装を流用する,すなわち以下のような実装である.

入力
プログラムが INET サーバとなり,受信ポートを開く.データストリーム情報源は,そのポートに接続しデータストリームを次々と PUSH 的に送信する.ここで,データストリーム情報源が PUSH 的な配信機構を備えていない場合は,そのラッパーとなるプログラムが,データストリーム情報源の出力キューを定期的にチェックし,データを PULL した上で DSMS へ PUSH する.
出力
プログラムが INET サーバとなり,クエリ受付用の受信ポートを開く.クライアントはこのポートに接続し,クエリを登録する.DSMS はそのクエリを自身へ登録すると,新たなポート番号をクライアントに送信する.このポートを通じ,DSMS はクライアントへ処理結果を PUSH する.

プロトタイプシステムは,この単純な実装にとどまっていることも少なくない.一方で,このシステムを実環境へ導入すれば,容易に破綻しかねない.原因の一つは,この実装が OS のソケットバッファを,そのままキューとして使っているいうところにある.

数多くのデータストリーム情報源が DSMS とのコネクションを張り,データを次々と送り付けたらどうなるか? ソケットバッファは一杯になり,あふれ出たデータは処理されることなく消滅する.TCP を通信に使っていた場合は,パケット内のウィンドウがストリーム情報源に限界を伝え,それを聞いたストリーム情報源は送信を自重する.すると,今度は自身の送信キューが一杯となり,あふれ出たデータは DSMS へ送信されることなく消滅する.

OS のソケットバッファは,あまりにプリミティブだ.細かな挙動を変更することはできず,最大のサイズなどを変更するだけでも http://yumewaza.yumemi.co.jp/2010/07/limitsconf.html にあるように ulimit や limits.conf を使う必要がある.DSMS を真面目に実装するのであれば,もう少し高級なキューが必要だ.

メッセージキューの利用

IPC で良く使われる機構に,メッセージキュー (http://en.wikipedia.org/wiki/Message_queue) というものがある.メッセージキューの実装は様々だが,高度なものはプロセス間で非同期的にメッセージをやりとりする場合に,次のようなことを保証してくれる.

  • メッセージが必ず到達する
    • 必要に応じて再送・二次記憶へのスワップアウトなどを自前で行なう
  • メッセージの順序がバラバラにならない

この仕組みはまさに DSMS におあつらえ向きではないだろうか.

実際の DSMS が使っているメッセージキューの実装を覗いていく前に,いくつか有名なメッセージキューの実装を紹介しておこう.寡聞にして知るものは少ないが,ご勘弁いただきたい.

ActiveMQ http://activemq.apache.org/
Java Message Service のオープンソース実装.様々な機能がサポートされている.
Q4M http://q4m.github.com/
DeNA の奥一穂氏により開発されている,MySQL のストレージエンジンとして動作するメッセージキュー実装.日本語の情報は多い.

DSMS 実装

さて,世に DSMS の実装は数多い.特に,アカデミックの世界ではデータストリーム処理を研究するグループの 3 つに 1 つ,実装があると言っても過言ではないぐらいだ.そのようなわけで,実装に至っても玉石混交.ここでは,その中から「玉」,すなわちある程度の評判を得ている DSMS を選び,メッセージキューを中心にその内部実装を覗いていくことにしよう.

STREAM

TelegraphCQ

Aurola / Borealis

S4

Storm

Flume

Jubatus

Nov 5, 2011

Multicorn

Multicorn <http://multicorn.org/>というプロジェクトを Twitter 経由で知る.詳しくは調べていないが PostgreSQL の SQL/MED サポートである Foreign Data Wrapper を簡便に利用可能とするスクリプトらしい.

感心したのは,見栄えのするサイトのデザインだ.Web Fonts をうまく利用している.私もどこかで真似をさせて頂こう.

さて,本題とそれた.SQL/MED には,以前から興味があった.何でも,ストリーム的データをテーブルとして扱うこともできるとのことで,私のやっている研究ともからんでくる気がしている.ちょっと,想像はつかないが.