まつもとゆきひろさんの講演(ニコニコ動画(RC2)で公開)
Asianux Road Show in Tokyo (10/16開催)での講演のビデオです。どうぞ、お楽しみ下さい。まつもとさん、ご講演ありがとうございました。
「まつもとゆきひろはなぜプログラミング言語をつくったのだろう」もあわせて読みたい。
![]() |
|
日本OSS推進フォーラム ステアリングコミッティ委員
OSDL Board of Directorsを歴任
カーネル読書会主宰
2000年6月、ミラクル・リナックスの創業に参加。
95年~98年、米国OracleにてOracle RDBMSの開発をおこなっていた。
98年にNetscapeのソースコード公開(Mozilla)に衝撃をうけ、オープンソースの世界に飛びこみ、ついには会社も立ち上げてしまう。
2008年6月取締役CTOを退任し一プログラマとなった。
« 2007年9月 | メイン | 2007年11月 »
Asianux Road Show in Tokyo (10/16開催)での講演のビデオです。どうぞ、お楽しみ下さい。まつもとさん、ご講演ありがとうございました。
「まつもとゆきひろはなぜプログラミング言語をつくったのだろう」もあわせて読みたい。
「開発工程を別々に担当してはいけない」は思いのほか多数のブックマークを頂いた。コメントやブックマークを拝見しながらあれやこれや考えた。わたしの飛躍する思考というか雑な議論で辟易している方もいらっしゃるかとは思うがもう少しお付き合いいただければ幸いである。
わたしの経験は、このブログの読者の皆さんはご存知かもしれないが、ソフトウェア製品の開発経験に偏っている。米国系ハードウェアベンダーでコンパイラやRDBMS製品を開発していた。その後西海岸のソフトウェアベンダーに転職してそこでRDBMS製品の開発に従事した。そしてOSSの可能性を信じてミラクル・リナックスの設立に参加したのが約7年前である。顧客向けアプリケーション、例えば社内システム構築(人事、財務、購買などなど)の経験はない。
さて先の「開発工程を別々に担当してはいけない」ではいろいろな論点をごった煮風に突っ込んだものだから分かりにくくなったので、いくつか細かく分けて考えてみる。
人月のワナ。
多くの人が指摘しているようにソフトウェアの価値をかかった工数(人月)で評価するというのはまるっきりナンセンスである。熟練者が一ヶ月で作成できるものを初心者が6ヶ月かかったとすると、後者に6倍お金が払われるか、それだけの価値があるか。もちろんない。
この場合の正しくは、ある実装した価値、通常は機能で近似するかと思うのだけど、それに見合った価格が支払われるべきである。単位機能を実装する工数が少なければ少ないほど、利益があがるので、ソフトウェア開発における生産性向上のインセンティブが発生する。人がソフトウェアを作る以上、一人一人の専門性、技術を向上させることに高いインセンティブが発生する。企業にとっても、未経験者(安い人材)を雇用し、その利ざやで稼ぐのではなく、より専門性の高い人間を雇用し、その生産性の高さで利益をあげることに、そして教育やトレーニングに投資すること(生産性や品質の向上に繋がる)に合理性が発生する。
ソフトウェアである機能を実装するために、設計、プログラミング、テストという工程があったとして、それを工程ごとに分離して、それぞれを単能化することによって生産性を向上するという、古典的な工場モデルがソフトウェア生産に適用可能なのか。ひたすらネジを取り付けるだけの自動車工場なんていうのがいまどきありうるのか。ソフトウェアの設計とプログラミングそしてテストというのがそもそも分離可能な工程なのか?
わたしは、そのような工程を単純に分離することは難しいし、分離することは専門性を高めることには繋がらないと思っている。分離することによって、生産性が向上するという証拠もほとんどみたことがない。ソフトウェアを実装する能力を高めるためには、渾然一体のプロセスである、設計、プログラミング、テストを等しく経験しなければならないと考えている。その経験を積むことによって一人一人の専門性すなわち生産性が向上していくと考えている。
テストとプログラミングをするものは分けるべきだと言う議論ももちろんあるが、ここでいうテストは実装の妥当性を評価するいわゆる内部テストに相当する部分で、仕様の妥当性を検証する統合テストあるいは受け入れテストのところではない。昨今ではテスト駆動型開発という手法で広く取り入れられている方式である。
ということで、工程分離することによって生産性が向上するという可能性が少ない、むしろ悪化すると考えている。一方で機能による分離では生産性向上がみこめると考えている。
ITゼネコンうんぬんかんぬんはまた別のお話なのでいつの日か別にお話することにしたい。
Asianux Road Showで大阪に出張したとき、たまたまつけた深夜放送でNHKスペシャルの再放送をやっていた。http://www.nhk.or.jp/special/onair/071022.html
そもそもポアンカレ予想なにそれのわたしだ。ビールで酔っ払った深夜、眠い目をこすりながら見た。じっくり見た。宇宙にひもをつけたロケットを飛ばす。なんだなんだ。宇宙を一周して地球に戻ってきたときそのひもをひっぱって回収する。なんだなんだ。何の話だ。そのひもがなんのひっかかりもなく回収できたら宇宙は丸い。ひっかかったらドーナツみたいな形をしている。そーゆー話らしい。
その証明は世紀の天才達が一生をかけこの100年チャレンジしたがつい最近ロシアの数学者が解答にたどり着くまで誰も証明に成功しなかったらしい。
数学に一切縁のないわたしですらぐいぐい引き込まれたエンターテイメントに仕上がっている。すげーなNHK、いい仕事をしているなあ。
こーゆー番組を見た中学生や高校生ぐらいの少年、少女が数学に興味を持って、いろいろ調べて、そっち方面の進路につくとか、そーゆー話があったら、それはそれで凄いことである。テレビにはそのくらいの影響力はありそうだ。
よっぱらいのオジサン(わたしのこと)ですら、思わずインターネットでポアンカレ予想なんてのを検索してしまった。何人の中高生が同様なことをしたのだろう。考えただけでわくわくする。
そんでもって話は一気に飛ぶのだが、コンピュータとかプログラミングとか、そーゆーものを中高生に興味を持ってもらうために、どんなことがわたし達にできるのだろう。
プログラミングすることの楽しさ、わくわく感、そんな経験をどうにかして伝えたいと思う。
若い人たちが一人でもコンピュータとかソフトウェアとかに興味を持ってもらうためにわたし達はどのような事ができるのだろう。どうすれば、その魅力を伝えることができるのだろう。
ポアンカレ予想のテレビ番組を見ながらそんなことを思った。何かいいアイデアがあれば、コメント、トラックバックを頂きたい。
ポアンカレ予想
http://ja.wikipedia.org/wiki/%E3%83%9D%E3%82%A2%E3%83%B3%E3%82%AB%E3%83%AC%E4%BA%88%E6%83%B3
殆どの数学者がトポロジーを使ってポアンカレ予想を解こうとしたのに対し、ペレリマンは微分幾何学と物理学の手法を使って解いてみせた。そのため、解の説明を求められてアメリカの壇上に立ったペレリマンの解説を聞いた数学者達は、「まず、ポアンカレ予想を解かれた事に落胆し、それがトポロジーではなく(アメリカでは古い数学と見下されていた)微分幾何学を使って解かれた事に落胆し、そして、その解の解説が全く理解できない事に落胆した」という。(NHKスペシャル 2007年10月22日放送分 『100年の難問はなぜ解けたのか ~天才数学者 失踪の謎~』 より。)
古典的なウォータフォールモデルでは、ソフトウェア開発を要求仕様分析、概要設計、詳細設計、実装(コーディング)、内部テスト、統合テスト、運用、保守みたいな工程にわけ、通常は各工程を別々の人が担当するというような方法がよくおこなわれている。
特に、要求仕様の分析、概要設計などは上流工程などとよばれていて、詳細設計、実装とは別の人ないしは組織が担当する。実装とかテストは下流工程などとよばれている。
よくあるパターンとしては元請けが上流工程を、下請け、孫請けが実装やテストなどを担当し、人月単価も下流の方が安い。
ウォーターフォールモデルでは各工程毎に成果物(仕様書や各種ドキュメント、プログラム)が大量に生産される。各フェーズ毎に定義された成果物がそろってから次のフェーズに移行するというのが建前なので、各フェーズでのドキュメントはどうしても冗長になりがちである。
一度固定した文書は次のフェーズで変更するとなると、手戻り工数が莫大になってしまうので、通常は、前工程で決めたことは、後工程で変更はしない。後工程で変更しないという前提で文書を作るので、いろいろ長期間にわたって検討などをするのであるが、実装してみないとわからない事などもいっぱいあるので、なかなかそうは上手くいかない。
実装してみて、できたものは最終ユーザからみると使えないものでも、仕様書に明記されていたものをその通りつくっている限り実装者(製造)の責任ではない。
大量な文書を作るし、各フェーズのレビューの工数も重いので開発スピードは遅くなりがちで、当初予定していた利用環境やユーザの要求というのも時間とともに変化するので、実装が終了した時点では仕様そのものが陳腐化するという事もすくなくない。ひらたく言うと、一生懸命つくっていたのに使えないものができてしまったということである。
ユーザアプリ開発、SI(System Integration)の現場では、おおかれすくなかれ上記のようなパターンがあって、それに元請け、下請けという産業構図がはめこまれていて、元請けが大手ベンダー、下請け、孫請けが中小ベンダーという風になっていたりする。大手がゼネコンの立場になって、多くの下請け、孫請けを使って大規模システムを構築する場合、いろいろな意味あいを含めてITゼネコンといったりする。
工程を別々に担当することによって、数々の問題が発生する。
通常は上流の方が単価が高く、下流の方が単価が安いので、だれも下流をやりたがらない。下流工程は結果として単価の安い経験の浅いエンジニアをつけることになる。工程は通常、組織によってわぎりにされているので、下流工程の作業をやる人がノウハウをためて上流作業をになうという機会がない。元請けはいつまでたっても元請けだし、孫請けはいつまでたっても孫請けである。孫請けの経営者も経営者で、単価は安くても、とりあえず人の分だけ売上があがるので、大手にぶらさがっていれば食いっぱぐれない。そのため経営の緊張感はない。利益率は低いがどうにか食っていける。というような構造がある。
下流にいけばいくほど単価のたたきあいになるので経験豊富なベテランを配置することが難しくなり、若年層エンジニアを使いすてることにならざるをえない。いわゆる35歳停年説である。
業界全体としてエンジニアを使い捨てにすることには百害あって一利もない。にもかかわらず、抜本的な対策、方策がとられているようには見えない。
なぜなんだろう。
わたしには、この工程によって作業を分担するという方法が諸悪の根源であるように思えてならない。小さい会社が何十人もエンジニアを集められないので元請けになれないという事情があるというのは百歩譲ってあるとしよう。大規模な開発をするため何社かで共同作業が必要だったとしよう。その場合の分担を工程ごとに輪切りにするのではなく、機能ごとに縦に切る事を提案したい。
つまり、ある機能について、一社ないしは一人が仕様の決定から設計、実装、内部テストまで担当するのである。キモは設計者と実装者は同一人物とするのである。これを分離しない。
なんでこんなことを言うかというと、実装と設計は不可分で、実装をしてみて初めて気がつくこと、設計をしてみて初めて気がつくことなどがあり、実際の設計と実装というのはいきつもどりつのプロセスである。このいきつもどりつがない限り、いい実装などはできはしない。設計と実装を分断している限り、しょぼい設計としょぼい実装にしかならない。初めから完璧な設計などはないのである。完璧な設計でない以上、しょぼい実装しかうまれてこないのである。
工程を分離するのは悪なのである。
工程を分離するために専門性が蓄積されない。より高度な実装を作成するインセンティブも発生しない。
『「渡された仕様書を実装するサラリーマンプログラマ」の悲哀』にあるのは工程を分離されたプロジェクトの悲哀であって、サラリーマンかどうかは無関係である。
わたしはソフトウェア工場というコンセプトそのものを否定するつもりは毛頭ない。工学的なアプローチによってより品質の高い(バグ密度の低い)ソフトウェアをより少ない工数で生産するということは可能であると思う。QC活動のような方法論ですら有効な場面は少なくないと思う。
しかしXPで実践されているようなベストプラクティスの多くは工程の分離ではなく設計と実装の渾然一体となったプロセスである。
日本のソフトウェア開発の現場の国際競争力のなさというのがあるとしたら、ITゼネコンをよしとした、上流下流工程を是認したソフトウェア生産方法論にあるのではないか。そこに構造的な問題があるのではないかと思うのである。人月で工数をはかる事がやりだまにあがっているが、根本的な問題は、工程を分離して、下請けにだすというソフトウェア生産方法であると思う。
ちなみに、米国のソフトウェア製造業では(マイクロソフトもオラクルも)、設計する人がコードも書くのである。それが一般的な姿である。わたしの場合(DEC時代もオラクルの時)も、そうであった。
プログラマの仕事はプログラムを読むことである/ユメのチカラ
http://blog.miraclelinux.com/yume/2007/10/post_9db7.html
先日のAsianux Road Show (東京)は大盛況だった。参加いただいた皆さんどうもありがとうございました。(ぺこり)
大阪、福岡もまだまだ会場に余裕がありますので、ふるってご参加ください。
さて、特別講演でRubyのまつもとゆきひろさんにお話をいただいた。この講演に関しては、自分が聞きたい人にお話してもらうというカーネル読書会メソッドとも言うべきもので、まつもとさんには無理を言ってお願いした。(まつもとさんには「よしおかさんの頼みを断れなかったからだ。人脈というのはこのように活用するのね」といわれてしまった(笑))
それはともかく、弊社営業も、すごいということがよくわかりました、と感動していた。しかし技術者(プログラマ)でない人達にまつもとゆきひろの凄みを説明するのはなかなか難しい。
社内反省会(懇親会のあとの飲み会とも言う)で、その営業がわたしに「なんでプログラミング言語なんて作ったんでしょうね」と聞いてきた。一見簡単そうなこの問い。なんでなんだろう。哲学的な問いである。
なんでだろう。
ふつーだったら、プログラミング言語を新規に作ろうなんて事は思わない。わたしは高校、大学時代、ちょっとは思ったが、そーゆー人間は、そんなにはいない。30年以上前にBASICを作った大学生はいまや世界一の大金持だが、そーゆー人間はふつーいない。わたしは昔昔、BYTE magazineだったか何だったかにAPLのインタプリタが載っていて、当時パソコンなんてものは持っていなかったので、その記事を穴があくほど読んだ記憶がある。(http://www.vintage-computer.com/byte.shtmlによれば1977年8月号だったようだ)
わたし自身、言語オタクの片鱗はあったかもしれないが、プログラミング言語を新規に作った経験はもちろんない。
まつもとさんはプログラミング言語を作っただけではなく、それを10年以上コツコツ拡張し続けている。
これは驚異である。奇跡(?)である。
いまでこそまつもとさんの背中を見てプログラミング言語を作ってしまおうなどという蛮勇を持った若者が出てきているが、ふつーはそんなことは考えもしなかった。
しかし、よく考えてみるとLinusも自分でOSを作りたかったから作ったわけで、それがいつのまにかにIBMだOracleだIntelだがが勝手に注目して勝手にエンタープライズだなんだとよってたかって改良に従事しはじめたわけで、その中で、ビジネスだなんだとネクタイを締めているオトナが大挙してきた歴史があって、それと昨今のRubyにまつわるビジネスシーン(?)も似ている。
ハッカーがプログラムを作る。誰かが使う。誰かが改良する。どんどん利用者が増えてくる。どんどん開発者が増えてくる。改良の速度が加速して、ますます適用範囲が拡大する。それでビジネスをする人も増えてくる。益々適用範囲が拡大する。
凡人は、新しいプログラミング言語を作ろうなんて思わない。偉大なハッカーは、それを実装するだけではなく10年以上それを続ける。そして人々から尊敬をあつめる。
プログラミングを続ける情熱は一体どこから来るのであろう。
おおきな謎は謎としてとっておきたいと思った。
ソフトウェア開発コストのほとんどは保守のコストだと言われている。各種統計がそれを示しているわけだけど、自分の実感とも合う。
古典的なウォータフォールモデルでは保守というのが意識されないか、あっても一番下流なので、その重要性に対する認識が非常に薄い。
保守という言葉は若干大げさな響きを持つが、プログラムの不具合の修正や、ちょっとした機能変更、機能追加などなど、運用していけば、つまりそのソフトウェアが利用されていれば必ず必要なものである。保守されていないソフトウェアは早晩利用されなくなるか、既に利用されていないかである。
Unixの哲学を持ち出すまでもなく、優れたプログラマはプログラムを書くのではなく、再利用する。いかにしてプログラムを書く機会を減らすか虎視眈々としている。可能な限り再利用して、どうしても書かざるを得ない場合はリサイクルをしちゃったりする。(プログラマにとってのReduce/Reuse/Recycleってか。閑話休題)
このプログラムの保守のコストというのはプログラムの規模に比例する。大規模なソフトウェアであればあるほど保守コストの比重が高まっていく。新機能を追加するとしても、既にあるアーキテクチャにすり合わせるために、それを詳細に精密に理解する必要がある。
優れたプログラマはコードを書きっぱなしにしない。そのソフトウェアが使われている限り常にコードを読み改良していく。自分のコードであれ誰かが書いたコードであり、それを読み理解し改良する。
商用ソフトウェアの開発現場のベストプラクティスでは、コードはチームによって常にレビューされる。開発プロセスの中にしっかりレビューが組み込まれている。シニアプログラマの主な仕事はジュニアプログラマや同僚のコードをひたすらレビューすることである。書きっぱなしというのはありえない。もちろんOSSの世界では優しい独裁者の主な仕事はコードを書くことではなくレビューして、そのコードを受け入れるかリジェクトするか決定することである。
プログラマの基礎体力に対するコメントで
プログラマはプログラムを書くのが直接的な作業であって、
読む作業は、役に立つとはいえ、本業に対して間接的なものになります。
「基礎体力」のような大仰な物言いをして、直接関わりのない作業の能力を挙げられても、違和感を感じるだけです。
というのをいただいた。コメントありがとうございます。
もし、「プログラマを書くのが直接的な作業であって」と認識しているのであれば、それは、そーゆースタイルの現場というのがないとは言わないが、ベストプラクティスから程遠いと断言したい。わたしはそのようなスタイルは、古典的なウォーターフォールモデルで、要求定義、外部設計、詳細設計、コーディング、テスト、統合テスト、運用、保守、みたいな各フェーズを別々の人たちがやっているイメージをする。つまり、コーディングをするいわゆるプログラマと詳細設計、外部設計、要求定義をする人たちが見事なまでにばらばらというプロセスである。
「渡された仕様書を実装するサラリーマンプログラマ」の悲哀 にあるイメージである。優れたプログラマというのは要求定義から設計、コーディング、テストまでのプロセスに主体的に関わるのである。優れたソフトウェアはそのように作られるとわたしは思う。
プログラマとして生きて行くつもりなら、「渡された仕様書を実装するだけのサラリーマンプログラマ」よりは遥か上を目指すべき。そうでないなら、他の仕事を探した方が良い。自分のキャリアパスを見つけ出す責任を持つのは、会社でも上司でもなく、自分自身なのだから。(上述)
まあ、わたしの世界が狭いのかもしれないが、わたしの直接間接に出会った優れたプログラマは皆コードを良く読むプログラマであった。そしてコードを読むことによってどんどん成長している。
寿司職人の世界と言うものがどのような世界であるか全く知らないので勝手なことを想像で書いているわけだが、職人の世界というのは、ある種の決まり事があって、包丁の研ぎ方一つにしろ、お茶の出し方にしろ長い経験に裏打ちされた何がしがあるのではないかと思う。100年前は冷蔵庫はなかったので食材の保存の仕方は全然違うと思うが包丁の研ぎ方とか魚の切り方とかのコツは多分それほど変わっていないような気がする。大工も宮大工の世界なんかは何百年もの守るべき伝統があると思う。
中学生や高校生が漠然と職業を考えるとき、プロスポーツ選手や寿司職人のような職業はかなり具体的なイメージがつくと思うが、プログラマっていったいなんなんだろ。
意味のねえ精神論説く暇あるんだったら、技術を身につける場所と、身につけた後のビジョンを説いてくれっての http://d.hatena.ne.jp/muffdiving/20071009/1192031148
で、最近になって、下の世代に技術を伝承するのは、上の世代の役目じゃねえかと思えてきた。精神論なんざどうでもいい。大事なのは、技術を教え、習得した先に何があるのかを希望を持たせる形で伝えていけることじゃねえかと思える。そうしなきゃ、その技術はやがて枯れ、途絶えていくしね。
コンピュータが世の中をよい方向へ変えていくというリアルな実感を次の世界に伝える努力。それがこの業界には絶対必要だと思う。
どんな産業でも、その産業に未来があるように若者が思えれば若者は来るだろうし、そこに未来を見出せなければ衰退していく。
IT産業は設備産業ではなく人に依存した産業というか人そのものなのだから一人でも多くの才能ある若者にとって魅力的な未来を描かなければ、この産業に未来はない。
コンピュータによってわくわくするような世界を作る。そのビジョンを提示し、ちょっとでもコンピュータやプログラムに興味を持ってもらう。それを次の世代に伝える努力を続ける。それが我々世代の責任のような気がする。
その上での、「プログラマの基礎体力」をつけるトレーニングだ。弾さんの言う「基礎体力より基礎代謝 - 書評 - 翔、曰く」は、「人間としての基礎体力の付け方」について書いてある。そのような「人間としての基礎体力」をつけた人たちが一人でも多くプログラミングの世界に来てくれたらと思う。そのような人たちと一緒に仕事をしてみたいと思う。
そして、そのような若い人たちを発見、発掘するのもわたしたちの責任だと思う。
そもそも、プログラマの基礎体力ってなんだろう。学校でアルゴリズムの基礎を習うとか、プログラミング言語を習うとか、あるいはコンピュータの基礎を習うとかそういうことなのだろうか。
断片的な情報を獲得するのなら確かにインターネットや書籍でどうにかなる。しかし、職業プログラマとして一目置かれる存在になるための基礎体力ってなんだろう。
高校や大学などでプログラマの基礎体力は身につくのだろうか。
プログラムと言っても、ゲームのプログラムから、顧客の要求に従ったアプリケーションプログラム、組み込み機器の制御プログラム、あるいはOSやら、コンパイラやら、RDBMSやらの基盤ソフトウェアなど様々ある。
わたしの場合、子供の頃、初めてコンピュータに触る機会があって、その時のなにやら得体の知れない興奮みたいなものが結局のところコンピュータ関連の職業につくことになったのだが、知識0から鍛えるべきプログラマの基礎体力ってなんだろう。
野球少年だったら、親父とキャッチボールすることで、あるいはプロ野球を見につれてってもらうことで自然と野球に対するスタイルみたいなものが確立していく。三角ベースで放課後遊ぶのでも部活にはいるのでも、上手い下手あったとしても野球をやる基礎体力を得るためのパターンは確立されているように思う。
プログラマにとってのキャッチボールみたいなものは、いったい何なんだろう。
例えば、プログラミング言語の授業でHello Worldからというのは正しいトレーニングなんだろうか?
わたしが子供のころに比べれば今は一人一台PCを持っていて、フリー(この場合は自由というよりも無料という意味の方が近い)でソフトウェアが利用できる。知識を獲得する環境は圧倒的に今のほうがよい。よいはづなのであるが、プログラマとしての基礎体力をつける環境は整備されているのか?基礎的なトレーニング方法は確立したのか?
そこでプログラマの基礎体力をつけるためのよしおか試案である。
まづ、プログラマになりたいと思うモチベーションを与えるためにのきっかけ作り。ロールモデルの提示、コンピュータで凄いことができる、世の中を変えてしまったというようなわくわくする事例の提示。ハッカー魂をくすぐる。興味を持ってもらわなければ話にならないので非常に重要だと思う。
次に、プログラムを0から書くのではなく、動いているプログラムのコードを見せる、読ませる。ある機能を実装する時の表現方法を示すのがプログラミング言語の学習になる。先にプログラミング言語の文法を教えるのではなく、おもちゃでもいいので何かを実装するプログラムがあって、それを実装するためにこのようなシンタックスで表現するということを教える。その意味で、HTMLのようなものはいいかもしれない。
コードを書く力ではなく読む力を重視する。コードを読むことがプログラマにとってのキャッチボールになる。
教材はオープンソースソフトウェアにある。
コードの中に、配列や、リストや、ツリーや。グラフや、スタックや、その他もろもろのデータ構造があるが、それがどのように利用されていて、なぜそのようなデータ構造を利用すると嬉しいのかを解説する。同様にデータ構造をあれやこれやするアルゴリズムがある。それについても批評的に読解していく。
コードを読むことによってプログラムの構造や先人の知恵や失敗を学んでいく。
コードを読むという観点からのプログラミング言語入門書というのは面白いかと思う。
プログラマにとっての基礎体力はコードの読解力でそれを強化するのが重要であるというのが、本日のわたしの結論である。
Asianux Road Showでわたしも発表するということは、下記のブログでもご紹介したとおりだ。
Asianux Road Show、まつもとゆきひろさんの講演/ユメのチカラ
http://blog.miraclelinux.com/yume/2007/09/asianux_road_sh_e0d7.html
このブログのブックマークを見てみると下記のとおりで、トップがソースコードの読み方で次がデバッグ方法論である。
8/27 ソースコードの読み方
8/31 デバッグ方法論
このブログの読者の興味のあるところをお題拝借してセミナー形式でお話しようというチャレンジである。今まさに資料を作成中なのであるが、トラブルシューティングとコードリーディングという観点からまとめている。
トラブルシューティングの基礎あたりからはじめて、問題の再現、問題の理解、問題の解決みたいなプロセスの中で、コードを読むという行為は問題の理解のプロセスの中心的(?)な役割をになう。
コードを読む力が技術者にとってなぜ必要なのか。なんてことを語れたらいいと思うのだが、全然まとまっていない。
なかなか難しいが皆様の多数の参加と懇親会での質疑応答を楽しみにしている。奮って参加してほしい。
トラブルシューティングの第一歩は問題を正しく認識することである。そのために、問題を再現する必要がある。問題を再現するために、どのような条件でその問題が発生しているかの情報を収集しないといけない。
OSのバージョン、ハードウェアの構成からはじまって、問題を発生させているソフトウェアの構成などなどを特定する。
問題が再現できれば、トラブルシューティングの八合目まで登ったも同然である。
次にやるべきことは、問題の切り分けである。問題が起こる条件を局所化、最小化して特定する。
例えばLinux Kernelの場合は「カーネルにおけるリグレッションの特定」で紹介したような方法を使う。2.6.17では問題がなかったが、2.6.18で問題があったとすると、その間にあてた修正がなんらかの問題を発生させているとして、問題を発生させた修正を特定する作業になる。gitによれば、3399件の修正があるので、一個一個それを試していては日が暮れてしまうので、2分検索をして12回ほどの試行で問題を特定する。(すごいすごい)
同様に問題の起こっているシステムと、起こっていないシステムの差異を抽出して、問題を発生させているパラメータを特定する作業が重要である。この場合、いかに問題が起こる局所化あるいは最小化した条件を素早く見つけるかが鍵になる。ある意味、このプロセスに長けたプログラマをハッカーと呼びたい。素人は一個一個のたのたやるわけだけど、達人は目にもとまらぬ速さで再現ケースに到着している。
これには、対象となるソフトウェア依存の知識が必要なのは当然である。例えばMySQLのトラブルシューティングをしているのに、MySQLのことを全く知らなければお話にならない。とはいうもののソフトウェア固有の知識ではなくトラブルシューティング一般のパターンも存在する。
先の例でいえば、あるバージョンで問題が発生したとしたら、とりあえづ最新版でその問題が発生しないか確認するというのは、王道中の王道である。その問題が未知な問題なのか既知の問題なのかの調査の一環として試行する。仮に最新版で直っていた(現象が再現しない)のなら、2分検索をして問題が起こる個所を局所化する。
問題が起こる個所が局所化できれば、あとはソースを読むなり、ワークアラウンドを提示するなりして問題を回避すればいい。
この場合、ソースコードを読む時点では、もはや問題をかなり正しく認識しているので、コードを読まずしてほぼ正解にたどり着いているようなものである。
「コードを読むな、理解しろ」でも、紹介したように、問題を局所化できれば解決までは高速道路で一気にいっちゃうのである。
皆さん、blogのバックアップはちゃんと取っているのだろうか?転ばぬ先の杖。
万が一、なんらかのアクシデントでデータが消失してしまったらどうするか。インターネットの向こう側に聞いてみる。
Googleだったらurlに cache:http://blog.miraclelinux.com/yume/ などとしてキャッシュをゲットして、コピペする。
http://404.undo.jp/ というキャッシュを検索するサービスもあるらしい。
試しにやってみた。 http://404.undo.jp/http%3A//blog.miraclelinux.com/yume/
FC2ブログでユーザー記事消失 「Googleキャッシュのコピペで復帰を」
http://www.itmedia.co.jp/news/articles/0710/04/news056.html
例えば、2.6.17では問題ないのに、2.6.18だとなぜか問題が発生するとする。linux kernel は git というソースコード管理システムによって、全ての変更が管理されているので、その機能を利用して問題を発生させたパッチを特定する事ができる。
基本的な考え方は、コミットしたパッチを問題を発生させた組と、発生しない組にわけていって、問題を絞り込む。2分検索だ。
例えば、1000個分の変更がコミットされていたとする。これを問題が発生しない状況から一個一個順ぐりにあてていき、問題が発生したら、最後にあてたパッチが原因だということがわかる。この順ぐりにあてていく場合、最悪1000回試行錯誤しなくてはいけない。
2分検索の場合、まづ、500個分あてた状態で(gitで簡単にそのような状況をつくれる)試験をし、仮に問題が発生しなければ、残りの500個に問題があるので、さらに、その半分250個をあて(最初から見ると750個のところ)試験をする。仮に問題が発生したとしたら、最初の500個分のなかに問題を発生させるパッチがあるので、さらにその半分の地点の250個分をあてた時点で試験をする。その結果によって、さらに問題を絞りこむ。
git bisectというコマンドがそれを簡単にやってくれる。手始めにOKのバージョンとNGのバージョンを設定し、その後、テストを繰り返し、テスト結果にしたがって、もし、問題が発生したら(bad)、OKであれば(good)。
git bisect bad
ないし
git bisect good
として問題をしぼりこむ。
以下実例。
# git bisect start
# git bisect good v2.6.17
# git bisect bad v2.6.18
Bisecting: 3399 revisions left to test after this
[2a2ed2db353d949c06b6ef8b6913f65b39111eab] Merge git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild
# git bisect bad
Bisecting: 1699 revisions left to test after this
[8d3c138b77f195ca0eee6fb639ae73f5ea9edb6b] page migration: Update documentation
# git bisect good
Bisecting: 849 revisions left to test after this
[88ca8ed0b7f2f04a055ff3c389f398ba3ad3d27d] V4L/DVB (4048): Add support for the Texas Instruments TLV320AIC23B audio codec
... (中略)
# git bisect good
Bisecting: 3 revisions left to test after this
[c22ce143d15eb288543fe9873e1c5ac1c01b69a1] x86: cache pollution aware __copy_from_user_ll()
# git bisect bad
Bisecting: 1 revisions left to test after this
[f2c780c1fdbe5008c902c2d7e37242ac5e60f0b9] Au1550/1200: add missing PSC #define's, make OSS driver use the proper ones
# git bisect good
Bisecting: 0 revisions left to test after this
[7dbdf43cfa635ddc3701cc8d1eab07597cd731c0] mips: fix number of mremap arguments
# git bisect good
c22ce143d15eb288543fe9873e1c5ac1c01b69a1 is first bad commit
commit c22ce143d15eb288543fe9873e1c5ac1c01b69a1
Author: Hiro YoshiokaDate: Fri Jun 23 02:04:16 2006 -0700 [PATCH] x86: cache pollution aware __copy_from_user_ll() Use the x86 cache-bypassing copy instructions for copy_from_user(). ... Signed-off-by: Hiro Yoshioka
Signed-off-by: Andrew Morton
Signed-off-by: Linus Torvalds
:040000 040000 73b282577d95f4b69f046f715ac6a5a4694ba758 a2b88cac24b674c0519352c3f74a122ed6e46e7a M arch :040000 040000 e15615138743db3d63ba41ca2c0cf00854e601eb e1d7a032e27ab3cb0bbe6df743d1ae644bd8a999 M include :040000 040000 8361e3dcee117b08ccce5ccc9d451d84b07edfad 847b80b43154037f25781dda0e059df7e94c1ff8 M mm
ふんぎゃーー。わたしのパッチで何か問題があるらしい。
という感じになる。
今回このブログを書くきっかけは、下記のスレッドにある問題。2.6.18にしたらなぜかファイルがcorruptionした。
http://marc.info/?t=119116762100001&r=1&w=2
上記のようにbisectしてみたら、どうもcache pollution aware patchがなにやらやっているらしい。
http://marc.info/?l=linux-kernel&m=119135926624999&w=2
gitのログでわたしのメールアドレスが明記されているので、メールをCCされてしまって気がついた。
それにしても3399もあるコミットからいとも簡単に問題となるパッチを特定しちゃうんだからgitというツールはすごい。
さらに言うとLinusは何千もあるパッチのうち、当該パッチはmovntiを利用していて、キャッシュをバイパスしてデータをストアしているということを正確に理解している。
http://marc.info/?l=linux-kernel&m=119144213218621&w=2
http://marc.info/?l=linux-kernel&m=119146929402139&w=2
Linusってやっぱり神だよ。
git bisectのマニュアル
http://www.kernel.org/pub/software/scm/git/docs/git-bisect.html
Git を使ってソース・コードを管理する
http://www-06.ibm.com/jp/developerworks/linux/060809/j_l-git.shtml
Real-life kernel debugging scenario
http://kernel.org/pub/software/scm/git/docs/v1.3.3/howto/isolate-bugs-with-bisect.txt
Bisection searches/みたのブログ
http://blog.miraclelinux.com/mita/2006/06/bisection_searc.html
プログラマという職業。プログラムを作って給与を得る。が、定義かと思うけど、オープンソースを趣味で作っていてそれで所得を得ていない人は、じゃあ、プロのプログラマと言えないのか。
日本のIT産業のしょぼさは、ソフトウェア開発を人月単価でやりとりするところにあるというのが多くの人の指摘するところである。SIベンダーのエライ人が、学生の「大学では何を勉強すればいいですか」という質問に対して、「弊社では教育システムが完備していますから、大丈夫です」というような頓珍漢な答えをする。大学での専門的な勉強を期待しないということは、単に人を頭数で見ていることに他ならない。
「求人、プログラマ、未経験」を試しにぐーぐるしてみるとぞろぞろある。(求人 プログラマ 未経験 の検索結果 約 1,160,000 件中 1 - 10 件目 (0.08 秒) )
誰でもできることをやっているとしたら、それはもう単価勝負にならざるを得ない。自分の仕事がオフショアされちゃったよということになる。
それじゃあだめだろうという事である。
小説家募集、未経験者歓迎。
日本語を書けるからといって、小説が書けるとは限らない。ましてや英語の読み書きができない人が、今から英語を勉強して、英語で小説を書くということを職業としてできるかということである。そんなことがまかりとおっていていいのだろうか。
学校を卒業した瞬間は確かに未経験である。しかし仕事の場でいろいろ経験を積み技術的な幅を広げていく。そのようなキャリアパスの中にプログラマという職業はあるはづである。
オープンソースのおかげでその経験を仕事以外で積み重ねることができる。入ってきたときは未経験でも、オープンソースの世界でリスペクトされるには高度な専門性が必要である。日々研鑚である。それはもちろんプロのプログラマでも同じである。
プロのプログラマならその専門性に磨きをかけないといけない。そういう世界である。
U-20(Under 20)プログラミング・コンテストの入賞者向けのまつもとゆきひろさん、g新部さんの講演会とその後のワークショップ、そして授賞式に参加した。
ワークショップでは、受賞者の皆さんと審査員との間での質疑応答があった。まつもとさんやg新部さんはどう考えても、ふつーのプログラマではないので、若いプログラマがすぐに彼らになれるかというとなかなかそうはいかないが、それでも、野球少年とイチローや松井との対話みたいな感じにはなると思う。
若手プログラマにとっての「まつもとゆきひろ」的なロールモデルは絶対必要である。この手のワークショップはなかなかスケールしない、すなわち規模の拡大は難しいが、それでも、若い人たちに語り続けることは重要である。
IT産業を3K産業などと揶揄するむきもあるが、仮にそのような状態があるとしたら、そのような状態を作っている企業人の責任は重い。若者に希望を与えるような産業構造にする義務が我々企業人にはある。その道は遠いが一人の企業人として、自社の仕事環境から少しでも理想に近づけることをし続けなければならない。
授賞式のあとの懇親会では甘利経済産業大臣も参加してU-20の皆さんと懇談していた。
21世紀のプログラムは君たちが作る。活躍を期待している。
21世紀のプログラムは君たちが作る/ユメのチカラ
http://blog.miraclelinux.com/yume/2007/09/21_4f64.html
U-20プログラミング・コンテスト/ユメのチカラ
http://blog.miraclelinux.com/yume/2007/09/u20_927d.html
U-20プログラミング・コンテスト公式ページ
http://www.jipdec.jp/procon/
(別紙2)平成19年度 U-20プログラミング・コンテスト入選作品の表彰(PDF形式
http://www.meti.go.jp/press/20070914003/20070914003.html
なお、平成19年度情報化月間情報化促進貢献個人表彰、経済産業大臣表彰「情報化促進部門」をまつもとゆきひろさんが受賞している。おめでとうございます。
http://www.meti.go.jp/press/20070914003/01_bessi01.pdf
10月5日追記:"21世紀のプログラムを作る君たち"に伝えたかったことhttp://itpro.nikkeibp.co.jp/article/COLUMN/20071003/283741/ 日経ITPro高橋さんが素敵な記事を書いてくれた。「ネットの向こうにいる仲間を信じよう。」
Intel 64 and IA-32 Architectures Software Developer's Manuals は下記にある。
http://www.intel.com/products/processor/manuals/index.htm
どれから読んだらいいか、よく分からないということであれば、 Volume 1: Basic Architectureをざっと見て、 Volume 3A: System Programming Guideに行くというのがオーソドックスかと思う。インストラクションセットの解説( Volume 2A/2B)は辞書的に必要な命令について適宜参照するという形になる。
マイクロアーキテクチャについてざっくり知りたい場合は、Intel 64 and IA-32 Architectures Optimization Reference Manualの第2章がコンパクトにまとまっている。
最近のCoreマイクロアーキテクチャやPentium 4やXeonのNetBurstマイクロアーキテクチャについて紹介されている。
Coreマイクロアーキテクチャのところを読むと、In Orderのフロントエンドが4つの命令デコーダが、命令をμOPに変換し、Out of Orderの実行コアに送り、サイクル当たり6個のμOPを実行し、In OrderリタイアメントユニットがμOPの実行結果をサイクル当たり4つプログラム順に変換する。なんてことが書いてある。
14段のパイプライン、3つのALUなどなど。
フロントエンドには、BPU(Branch Prediction Unit)、Instruction Fetch Unit、Instruction Queue、Instruction Decoder、Stack Pointer Tracker、Micro-fusionなどの機能がある。機械語をμOPにサイクル当たり4つ変換する。
実行コアはフロントエンドから供給されるμOPをOut of Orderで実行する。renamerによって、レジスタ名を大量にあるマイクロアーキテクチャの内部レジスタ名に変換する。(いくつ内部レジスタがあるかは記されていない)。Reorder buffer (ROB)はμOP実行結果を保持する。ROBは96個のエントリを持つ。Reservation Station (RS)はμOPのすべてのソースオペランドがそろうまでキューに並べスケジュールする。RSは32個のエントリを持つ。
実行コアがサイクル当たり最大6個のμOPを同時に実行するというようなことが書いてある。その他メモリアクセスをどのように高速化しているかなど興味深いお話満載である。ぜひ原文にあたって欲しい。
最近のコメント