仙石浩明の日記

2006 : July

2006年7月29日

「ソフトウェア開発」は「モノ作り」ではない (2) hatena_b

「ソフトウェア開発」は「モノ作り」ではない」を とても多くの方々に読んで頂けた。 コメント/トラックバックを頂いた方々、 はてなブックマーク して頂いた方々に 感謝申し上げる。

これだけ多くの方々に読んで頂くと、 誤解するかたも少なくないようだ。 まあ、私の文章力が至らないのだから仕方ないが、 誤解したかたも、もう少し説明を補足すれば理解し合えるのかも知れず、 もう少し書いてみようと思う。

一番の失敗は、 日経ビジネス online の記事を引用してしまったために、 この谷島氏の記事「ITの常識は世間の非常識」の主張が、 私の主張 (の一部) と思われてしまった点だ。 谷島氏の記事では、

「そもそも情報システムと自動車を同一視することもいかがなものかと。 情報システムを何か出来合いの産業機器のように受け止めているわけですよね。 やはり、顧客の意思が反映されるソフトウエアというものをお分かりではない、 ということでは」

ということにまで言及しているが、 私が主張したかったのは「ソフトウェア開発とは何か?」ということであって、 私が言う「開発」とは狭義の開発であり、 谷島氏のメインの主張である要件定義の話まで踏み込むつもりはない。

言うまでもなく要件定義はシステム開発を請け負うにあたって 最重要なステップであり、 要件定義の良し悪しがプロジェクトの成否を分けると言っても過言ではない。 しかし、だからといって他のステップを 無視してしまっていいというわけでもないだろう。

「システムを開発する技術者は、コンサルタントを目指すべし」くらいの勢いで 主張されるかたも多いし、 日経BP 等の Web ページを見ていると、 技術者にとって必要なスキルはコミュニケーション能力だ、 という主張ばかりが目立つ。 確かにコミュニケーション能力は重要ではあるが、 技術者の本分はあくまで「技術力」であって、 それをないがしろにしていいわけがない。

なので、私が主張したいのはあくまで、 技術者がどうすれば技術力を磨くことができるか、 という点にある。 そして、技術力を磨く上で最大の障害になっていると私が感じるのが、 ソフトウェア開発が何であるか、 技術者をとりまく人たち (特に経営側) が分かっていないことが多いし、 いやそれどころか当の技術者さえ、きちんと理解できていないことがある、 という点なのである。

ソフトウェア開発が何であるかが分かっていなければ、 すなわちソフトウェア開発を「モノ作り」と考えていては、 技術者を育てようとしても、 あるいは技術者自身がスキルアップを目指していろいろ勉強しても、 本質を外して徒労に終わるリスクが高い。 せっかく勉強するなら、きちんと本質をとらえて、 「技術力」を確実に伸ばしていって欲しい。

Filed under: 技術と経営 — hiroaki_sengoku @ 07:54
2006年7月28日

「ソフトウェア開発」は「モノ作り」ではない hatena_b

いつのころからか、 ソフトウェア開発がモノ作りに喩えられるようになった。 典型的なのは、製造業(例えば自動車製造)と IT 業界とを比較して、 前者が高度にシステム化されているのに対し、 後者がまるで家内制手工業のようだ、という批判である。

日経ビジネス online の記事に次のようなくだりがあった:

「というより、何といいますか、経営トップからすると、 ITはとにかく非常識な世界だ、としか思えないのではないかなあ。 例えば大きなシステム開発プロジェクトに取り組むと、 すぐ100億円を投資する、という話になってしまう。 100億円の経常利益を出そうと思ったら本当に大変。 ところが、100億円を投じたのに、期限までに完成しない、 出来上がってきたものが当初計画と違う、 直そうとするとさらに金がかかる。 こんなことが起きるわけですから、『一体なぜなんだ』と経営トップは思うわけです」

IT業界は 100億円かけても使えるものが作れない非常識な世界、というわけである。 まあよく聞く批判で、そう言いたくなる気持ちも理解できるのであるが、 100億円が高いとする根拠がいただけない。 同じ記事中に続けてこういう話が出てくる:

「例えば、自動車を買うとします。 希望の車種と色調を言えば、その通りの車が期限通りに納車される。 万一、色が違っていればすぐ取り替えてくれるし、 その車が動かないなんてことはまずない。 欠陥があった場合、リコールがある。 しかし、コンピューターの場合、自動車ではありえないことが四六時中起きる。 経営トップとしては何とも理解し難いわけです」

つまり、ソフトウェア開発を自動車の製造と比較しているのである。 自動車は、「わずか」数百万円なのに「使える」製品が買える。 自動車と同程度に複雑なソフトウェアを開発しようと思ったら、 少なくとも数億円から数十億円はかかるだろうし、 数十億円かけたところで、 現在の工業製品としての自動車のレベルの品質は望むべくもない。

このような批判は、 「ソフトウェア」を「モノ」と同一視したためにおこる誤解が元となっている。 ソフトウェア開発という「家内制手工業」をせめて「工場制手工業」へ発展させ、 ゆくゆくは「機械制大工業」に進化させようという試みの多くも、 同様の誤解がベースになっているわけで、 「ソフトウェア開発」を「モノ作り」と見なす誤解は、 広く蔓延してしまっているのかもしれない。

問: 「ソフトウェア開発」が「モノ作り」でないなら、何なのだ?

答: 「設計」である。

自動車とソフトウェアを比較するなら、 「自動車の設計図」が、 「ソフトウェア」(より正確に言えばソースコード) に相当する。 「自動車の製造」に相当するのは、 ソフトウェアを出荷するときに行なう「ビルド」「コピー」「パッケージング」 であろう。

「自動車の製造」には例えば一台あたり百万円を超えるようなコストがかかり、 1万台生産しようとすれば 100億円を超えるコストがかかる。 大量生産すればするほど「製造コスト」が支配的になるから忘れがちであるが、 自動車の設計にも結構なコストがかかっている。 設計図を引くコストだけでなく、その前提となる研究開発も必要だし、 エンジンや制御用コンピュータなどの部品の設計も含めれば、 ゼロから一台の車を設計するコストは、かなりの額 (よく分からないが数億円で済むとはとても思えない) になるだろう。 完全「特注」の自動車を設計してもらうとしたら、 いったいどのくらいかかるのだろう?

一方、ソフトウェアの開発においては、 「製造コスト」は無視できる。 1万本生産するとしても、パッケージングコストは 1 本あたりせいぜい数百円程度だろうから、数百万円程度で済んでしまう。 ダウンロード販売なら何万本生産 (つまりコピー) しても原価は 0 円である (もちろん、ダウンロード サイトの運用などには費用がかかるが、 それは原価ではなく「販管費」である)。

ソフトウェアの設計というと、 要件定義、外部仕様、詳細仕様、等々を作ることを指すことが多いのでややこしいが、 製造業においても、図面を引く前には仕様を詳細につめているはずなので、 自動車の設計図を書く工程を「設計」と呼ぶのであれば、 ソフトウェアのコーディングも「設計」と見なすべきだろう。 コーディングの「家内制手工業」ぶりを批判したいのであれば、 比較対象は設計図を書く工程であるべきであって、 組み立て工程ではない。 ソフトウェア開発の近代化は重要な課題であるが、 そのお手本を「機械制大工業」における「製造工程」に求めてしまっては、 大きく道を誤る。

(つづく)

Filed under: 技術と経営 — hiroaki_sengoku @ 08:22
2006年7月25日

イントラの「ファイル共有」を社外からアクセスする方法 (VPN-Warp 応用編 3) hatena_b

だいぶ間があいてしまいました (^^;) が、 VPN-Warp の応用例の第二回目を、お送りします。 前回は、「盗まれたノートPC を外部から操作する方法」という、 やや特殊な例だったので、 今回は、とてもオーソドックスに、 イントラの Windows マシンの「ファイル共有」を、 社外から利用できるようにする方法の紹介です。

その前に... そもそも Windows のファイル共有とは何なのか?を、 おさえておく必要があります。 といっても「Microsoft ネットワーク」は 仕様が完全に公開されているわけではありませんし、 過去のしがらみで無暗に複雑になってしまっているプロトコルなので、 深入りはしません (^^;)。 詳しく知りたい方は、

アンドキュメンテッドMicrosoftネットワーク
誰も知らなかった「ネットワークコンピュータ」の秘密
高橋基信 著, 翔泳社 (2002/06)

などを参照してください。

CIFS (Common Internet File System)

当初は TCP/IP とは似ても似つかない独自プロトコルとして始まった Microsoft ネットワークも、 TCP/IP がネットワークの事実上の標準になるに従って、 しだいに TCP/IP に適合するように変化してきました。 まず NetBIOS が TCP/IP の上で動くようになり (NetBIOS over TCP/IP, 略して NBT と呼ばれる)、 さらに TCP/IP に馴染まない点を整理して、 フツーの TCP/IP 上のプロトコルっぽくなったのが CIFS (Common Internet File System) です。

CIFS は NetBIOS名でコンピュータが指定できるなど、 TCP/IP の世界とは相容れない点がまだ残っているものの、 NetBIOS名を使わずに 「ホスト名」や「IP アドレス」でコンピュータを 指定することもできるので、だいぶ使いやすくなりました。 「ネットワーク コンピュータ」でコンピュータ名が表示されない (ブラウズ リストに含まれていない) コンピュータでも、 「\\192.168.1.1」などと指定してアクセスすることができるように なったわけです。

NetBIOS名の名前解決 (つまり、コンピュータ名からマシンを特定する方法ですね) には UDP/TCP 137番および UDP/TCP 138番が使われますが、 これを省略して、ファイル共有サーバの TCP 139番ポートへアクセスするだけでも、 ファイル共有を行なうことができます。 この TCP 139番ポートへのアクセスは、 SMB (Server Message Block) セッションと呼ばれます。

VPN-Warp 入門編 (3)」で説明したのと全く同様の方法で、 ローカルホストの 139番ポートを、 リモートホストの 139番ポートへ転送するようにしておけば、 ローカルホストの 139番ポートへ接続するだけで、 リモートホストへ SMB セッションを確立することができて、 ファイル共有が可能になる、というわけです。

ローカルホスト         リレー           リモートホスト
    stone ─────→ サーバ ←──── relayagent─→ ネットワーク アダプタ
   139番ポート …………………………………………………→ 139番ポート

転送先の「ネットワーク アダプタ」は、 ファイル共有サービスを行なっている IP アドレスを指定します。 後述するように 139番ポートのサービスは、 アダプタごとに有効/無効を指定できるので、 有効になっているアダプタを指定する必要があります。

Direct Hosting of SMB (Server Message Block)

Windows 2000 以降だと、 NetBIOS 名の解決を行なわない 「Direct Hosting of SMB」 というプロトコルも使えます。 TCP/IP で名前解決 (つまり、ホスト名から IPアドレスを求める方法) を行ない、 ファイル共有サーバの TCP 445番ポートへ接続して 即 SMB セッションを確立します。

「Microsoft ネットワーク」が理解しにくいプロトコルであった一因は NetBIOS と SMB が一体化していたことにあったわけで、 NetBIOS を必要としない SMB の登場は、 SMB が何であったかを明確化する意味も持っていたように思います。

話が脱線しますが、ふつう何かの複雑なシステムを作るときは、 単純なものから始めて、それらを一般化して標準技術として確立した上で、 それらを組合わせて複雑なシステムを構築していくものだと思いますし、 インターネットはそのようにして発展してきました。 「Microsoft ネットワーク」は逆の方向に発展 (つまり退化? ;) したのでしょうか? このような最初に唐突に複雑なものが登場する傾向は、 Windows に限らず他のプロプライエタリなソフトウェアに共通してみられる 傾向のようにも思われます。

「NetBIOS over TCP/IP を無効にする」設定

Windows XP 等で、 「ネットワーク接続」の各アダプタのプロパティの中の、 「インターネット プロトコル (TCP/IP)」のプロパティにて、 「詳細設定」を選択すると、 WINS タブの中に、 この「NetBIOS over TCP/IP を無効にする」という設定があります。

この設定 (以下、「NBT を無効にする」と略記) はどういう意味でしょうか? 実は、 「このアダプタにおいて『NetBIOS 付 SMB』サービスを行なわない」 という意味です。 「NetBIOS over TCP/IP」という表現で「SMBサービス」を指すのは 分かりにくいと思うのですが、それはサテオキ この設定を行なうと、 「NetBIOS 付 SMB」すなわち 137, 138番ポートと TCP 139番ポートを 使用しなくなります (つまり listen しなくなる)。

VPN-Warp で 139番ポートを転送するには、 139番ポートを空けておかねばなりませんから、 いずれかのアダプタでこの「NBTを無効にする」設定を行なう必要があります。 ファイル共有サービスを外部へ提供しない PC (ノートPC などでは安全のためにも共有サービスは提供すべきではないでしょう) ならば、 どのアダプタの NBTを無効にしても問題なさそうに見えますが、 「メイン」のアダプタ (正確に言えばデフォルトルートになっているアダプタ) の NBT を無効にすると、 SMB サービスへアクセスするクライアント機能まで無効にされてしまうので 注意が必要です。

「Microsoft ネットワーク」が分かりにくい理由の一つに、 「クライアント」と「サーバ」の機能がきちんと区別されていない、 という点もあるのではないかと思います。 「NBTを無効にする」という表現では、 SMB サービスを利用するクライアント機能を無効にするのか、 SMB サービスを提供するサーバ機能を無効にするのか判然としませんよね? 実際には「クライアント機能」も「サーバ機能」も 同時に無効にされてしまうので、 確かに表現としては間違いではないのですが...

クライアント機能まで無効にされては、 なんのために VPN-Warp で 139番をポートフォワードするのか分からなくなるので、 NBT を無効にする専用のアダプタを (メインのアダプタとは別に) 追加するのがよいでしょう。

まず 「コントロールパネル」から「ハードウェアの追加」を選び、 「新しいハードウェア デバイスの追加」をクリックして、 「一覧から選択したハードウェアをインストール」を選びます。

そして「ネットワーク アダプタ」の中から、 「Microsoft Loopback Adapter」を追加インストールします。 インストールした Loopback Adapter の「TCP/IP 詳細設定」を開くと、 「IP アドレスを自動的に取得する」がデフォルトになっていますが、 ループバックに DHCP サーバを走らせても仕方がないので、 「次の IP アドレスを使う」を選択して、 適当な IP アドレス、例えば「192.168.168.1」を設定します。 そしてもちろん、 WINS タブの中の「NetBIOS over TCP/IP を無効にする」を設定します。

「NetBios over Tcpip」ドライバを使わない設定

前述したように「NetBIOS 付 SMB」はアダプタごとに 無効にすることができるのですが、 「Direct Hosting of SMB」すなわち「NetBIOS 無し SMB」は 全てのアダプタをまとめて無効にすることしかできません。 しかも Microsoft 流 (?) に、 クライアント機能とサーバ機能の区別がついてませんから、 サーバ機能だけ無効にするということができないようです。

「コンピュータの管理」の「デバイス マネージャ」で、 「プラグ アンド プレイではないドライバ」 (「表示」メニューにて「非表示のデバイスの表示」を選択すると表示されます) の中から「NetBios over Tcpip」を選んで 「このデバイスを使わない(無効)」設定にすれば、 「NetBIOS 無し SMB」を無効にできますが、 これを設定してしまうと SMB に関する全ての機能が利用できなくなってしまうので 現実的ではありません。

繰り返しになりますが (くどい? ^^;)、 「NetBIOS 無し SMB」を有効/無効するための設定が、 「NetBios over Tcpip」ドライバを使う/使わない、という名称なのは、 なんとかならないのでしょうかねぇ? なんだかわざと分かりにくくしようとしているんじゃないかと 勘繰りたくなります。

したがって、 Windows PC の 445番ポートを転送させることは現実的ではありません。 私は Windows なノート PC 上で coLinux を走らせているので、 この Linux 上の 445番ポートを VPN-Warp でポートフォワードしたりしていますが、 まあそこまでやらなくても、139番をポートフォワードするほうがよいでしょうね。

VPN-Warp の設定

長々と Microsoft ネットワークについて説明してしまいましたが、 要約すれば Windows PC の Loopback Adapter の 139番ポートを VPN-Warp を使ってファイル共有サーバの 139番ポートへ転送すればよい、 ということになります。

そして (いままでの説明が長かったこととは裏腹に ;-)、 VPN-Warp 自体の設定はとても簡単です。 まずファイル共有サーバ側で走らせる relayagent の設定は次の通りです:

-c "C:/Program Files/KLab Security/VPNワープ relayエージェント/user.pem"
-k "C:/Program Files/KLab Security/VPNワープ relayエージェント/user.pem"
-n
relay.klab.org:443 192.168.1.129:139

フォワード先が 192.168.1.129 (この IP アドレスは私の PC の場合の例です) の 139番ポートになっている他は、 前回の「盗まれたノートPC を外部から操作する方法」と同様ですね。 「192.168.1.129」は、 「NetBIOS 付 SMB」サービスを行なっているアダプタの IP アドレスで 読み替えてください。 一般的には「ローカル エリア接続」などの名称になっているアダプタでしょう。

次に、ローカルホスト側、 つまりファイル共有サーバを利用するクライアント側 (ノートPC など) は、 stone を以下の設定で動かすだけです:

-q cert=user.pem
-q key=user.pem
relay.klab.org:443/ssl,http 192.168.168.1:139 "GET / HTTP/1.1"

これも、前回と異なるのは転送元の指定である「192.168.168.1:139」の 部分だけですね。 Loopback Adapter の IP アドレス (この例では 192.168.168.1) と、 139番ポートを指定します。

Filed under: システム構築・運用 — hiroaki_sengoku @ 06:49
2006年7月24日

生活水準の「中流」と能力の「中流」 hatena_b

昨日放送された NHK スペシャル (21:00~):

「ワーキングプアー・働いても働いても豊かになれない」
低所得者層の拡大
定職につけない“住所不定無職”の若者
基幹産業の不振ほか

で、「働いても豊かになれない」若者が、 自分だって普通の人と同じくらい、「中の上」くらいの能力はある、 と言っていたのが妙に印象的だった。

ソフトウェアの開発業界では、 「中の上」の人 10人より、 「上」の人 1人のほうが力になる、 というのが常識として浸透しつつあると思う。 「人員を投入すればするほど、かえって工期は長引く」とか、 「少数のプログラマで開発する方が短期間で品質の高いものが作れる」 とかの事例は広く知られるようになった。 しかし世間一般では、 まだまだ「大勢の普通の人」の方が 「少数の優秀な人」より役に立つ、 という感覚なのかも知れない。

高度成長期のころ、能力の「中流」は、生活水準の「中流」につながった。 情報革命が進行しつつある現在、 「中流」の能力を持つ労働者に「中流」の待遇を提供できないのを、 企業の責任と言いきってしまって良いのだろうか? 「中流」の能力が以前ほど重要視されない原因を、 「規制緩和」に求めるべきなのだろうか?

Filed under: 技術と経営 — hiroaki_sengoku @ 09:11
2006年7月17日

理容SENGOKU(千石) たまプラーザ店

日記の更新が滞ってしまっています (_O_)。 いろいろ考えていることはあるのですが、 考えがまとまるまでは個人の日記の ほうへ書くということにしていたら、 こちらの日記の更新が止まってしまいました (^^;)。 二つの日記を書き分けるというのは、なかなか難しいものですね。

この三連休は、どーせ梅雨で雨だろうと思っていて 特にどこへも行く予定を立てていなかったので、 家でのんびりしております。 時間を持て余し気味だったので、 連休の中日に散髪に行ってきました。

自宅の近くにいくらでも散髪屋があるのに、 私はわざわざ電車に乗って、 たまプラーザ駅(東急田園都市線)の近くの散髪屋へ行っています。 なぜ、たまプラーザかといえば、以前その近くに住んでいたからで、 引越ししてもう 6年以上にもなるのに同じ散髪屋に行き続けています。 いつも同じ担当者に散髪してもらえれば、 いちいち髪型を指定する必要もなく楽だから、 ずーっと同じ散髪屋、同じ担当者に散髪してもらっている、というわけです。 そういう人って多いと思うのですが、 引越しして生活圏が変わってもわざわざ以前の店に通い続ける、 というのは少数派かも知れませんね。

近くの初めての店に行くか、遠くのなじみの店に行くか、 みなさんならどちらを選ぶでしょうか? どのくらい「なじみ」になるかにもよると思いますが、 顧客ロイヤリティをいかに高めるかがとても重要な業種の一つであることは まちがいなさそうです。

私が行き付けのこのお店、 最初の頃 (今から 14年ほど前になるでしょうか) は、 顧客管理を担当者の記憶だけに頼っていたようですが、 そのうち顧客一人一人の好みの髪型や留意点を書き留めた カルテを管理するようになり、 そして最近ついに、 Web ページを公開しました。 スタッフのブログまであるようです (せっかくの機会なのでトラックバックを打ってみます)。 昔からワン・トゥ・ワン・マーケティングを実践してきたお店が、 今後どのようにインターネットを活用していくのか、 とても興味深いところです。

ちなみに、私がそもそもこのお店に行くようになったきっかけは、 大学を卒業して東京に出てきたとき、 街をうろうろしていたら、 たまたま私の名前 (SENGOKU) と同じ名前の散髪屋を見つけて、 「何かの縁」と思って入ってみた、という単純なものです (「センゴク」といっても地名の「千石」のようですが)。 こういう「気まぐれ」で入ってきたお客をいかに固定化するか、 そのノウハウは非常に重要なものなのでしょうね。

Filed under: その他 — hiroaki_sengoku @ 10:08
2006年7月14日

stone 2.3b のバグ

重大なバグが発見されない限り正式リリースとする予定だった stone 2.3b であるが、 あいにくバグが発見されてしまった。 SSL 接続が確立する前に TCP 接続が切れてしまうと、 まれに busy loop が発生する。 某環境では、health check と称して ;-( ごく短い時間でポートのオープン/クローズを繰り返しているので、 何日か走らせると load average が無駄に 1 増えてしまっていた。 逆に言うと、かなり無茶な使い方をしない限り、この現象は起きないと思われる。

なぜ busy loop が起きるかと言えば、 doReadWrite() select loop において、 close 予定のソケットについて書込み待ち FD_SET して select(2) を行なうケースがあったからだ。 close 予定のソケットだから、書込み可能でも何も書込まない。 だから select(2) は待ち時間 0 で常に書込み可能を返す。 これが延々繰り返される。

この現象を回避するには、 close 予定のソケットについては FD_SET しなければよい。 ただし SSL_shutdown(3) が書込み待ちでブロックすることがあるので、 この場合、すなわち sf_sb_on_w (SSL flag: shutdown blocked on write) が セットされているときは、 close 予定であっても FD_SET する。 stone.c 2.2.3.6 で修正済み。 なお、busy loop は select 版でのみ確認したが、 epoll 版でも発生する可能性があると思われる。 今回の修正で epoll 版でも busy loop を防ぐことができると思われる。

ついでに、busy loop が起きたときにそれを検知するコードも追加した。 doReadWrite() select loop において busy loop が発生すると、 「<sd> TCP <sd>: doReadWrite Can't happen spin occured」 というエラーログを出力する。 stone が出力するログで「Can't happen」から始まるものは、 想定外の事象が起きたことを示す。 つまりバグである。 stone の最新版において、このようなログに遭遇したかたは、 ご連絡頂けると大変ありがたい。

Filed under: stone 開発日記 — hiroaki_sengoku @ 12:04
2006年7月12日

判断の理由 ~成功は失敗の元~

人は様々な判断をする。 経営上の決断だったり、 設計方針の決定だったり、 あるいはキャリアパスの選択だったりする。

あらゆる「判断」には、 その判断をするという「結果」をもたらした「原因」がある。 理詰めで行なった判断であれば、 どのような思考過程でそのような結論に至ったか、 明確にすることは比較的容易かも知れない。

しかし全ての思考過程が白日の下にさらされることは稀だろう。 理詰めの判断だと思っていても、 その一部が直感に頼っている場合もあるかもしれないし、 思い込みに捕らわれた論理の飛躍があるかもしれない。

直感といっても天から降ってくるはずはなく、 無意識の思考の結果だろう。 常にその思考の源泉があるはずである。 無意識の思考をかきわけ、 その直感がもたらされた真の原因を突き止めるべきだと思う。 無意識の思考をたどっていくうちに、 演繹の連鎖の中に、 思い込みや嗜好が関係していることがあるかもしれない。

もっとも危険なのは、 無意識のうちに過去の成功体験の事例を踏襲してしまっているケースだろう。 成功事例は、その前提条件が現在も成り立つときに限り有効であり、 前提条件を無視して無理矢理過去の事例を適用しようとすれば、 成功は失敗の元となる。

しかも、変化の早い現代においては、 以前の前提がそのまま成り立つことは、ほとんど有り得ない。 過去のやり方を真似ようとするときは、よりいっそう慎重にならなければならない。

過去と現在との条件の違いを明確にした上で、 過去の経験を活かすのであればよい。 過去の経験は資産になるだろう。

しかし、 無意識の思考で過去の経験を採用してしまうと、 本当にその前提条件が成り立つのか「意識」することなく 無意識に思考が進んでしまいかねない。 「判断」という結果を出すまでに、 その誤謬を正すことができるだろうか?

無意識の思考で発生した前提条件の齟齬が、 アラートとして意識に上ってくる場合もあるだろう。 上がってこない場合は、無意識の思考の過程を洗い出さなければならない。 無意識の思考は意識で想像するより深く入り組んでいる場合もある。 何が判断に影響を与えたのか、 常日頃から思考を遡って無意識の思考を監視する習慣が大切だろう。

その一つのきっかけとなりうるのが、 判断が結果的に間違っていたと思ったときに行なう反省、 すなわち「失敗から学ぶ」ことである。 失敗は、無意識の思考からアラートが上がってこない場合に、 外部から与えられるアラートである。

無意識の思考のアラートを次回こそは機能させるためにも、 失敗の原因をとことん追求すべきである。 ゆめゆめ失敗の原因を外部要因に転嫁して、 自己の思考を正当化してしまうことのないようにしたい。 そんなことをすれば、 追求が途中で頓挫してしまい、 失敗が次に活かされない。 「思い込み」が放置され、 無意識の思考に対する監視機能が働かないままになる。

そもそも言い訳など無意味である。 思考は全て自分のものであるのだから、 間違った思考の責任は全て自分にある。 自分自身に言い訳をして、 自分自身を欺くことの無いようにしたい。

Filed under: 技術と経営 — hiroaki_sengoku @ 09:31
2006年7月10日

一つのIPアドレスで djbdns (tinydns, dnscache) を走らせる (3) dnscache で別ポートを使う

前回は、tinydns を IP アドレス指定せずに起動したいケースについて述べた。 前々回で述べたように、 djbdns はネームサーバ tinydns と、 キャッシュサーバ dnscache が完全に分離した独立のプログラムになっていることが 大きな特徴であるが、 tinydns を IP アドレス指定せずに起動しようとすると、 同じポート番号を使う dnscache を起動することができなくなってしまう。

そもそも論で言えば、 ネームサーバとキャッシュサーバは全く異なるサービスを行なうサーバなのだから、 同じポート番号を使うこと自体が間違っているのである。 もしキャッシュサーバが 53番以外のポートを使うのであれば、 tinydns も dnscache も IP アドレスを指定せずに同じマシンで起動できるし、 これ以上シンプルな解決策はないであろう。

ならば dnscache を 53番とは異なるポートで起動しよう。 ただし、dnscache は 53番ポートを bind(2) するように ハードコーディングされているので、 若干パッチをあてる必要がある。

--- dnscache.c.org        Mon Feb 12 06:11:45 2001
+++ dnscache.c        Sun Jul  9 06:43:23 2006
@@ -390,6 +390,7 @@
 {
   char *x;
   unsigned long cachesize;
+  unsigned long port;
 
   x = env_get("IP");
   if (!x)
@@ -397,16 +398,19 @@
   if (!ip4_scan(x,myipincoming))
     strerr_die3x(111,FATAL,"unable to parse IP address ",x);
 
+  x = env_get("PORT");
+  if (x) scan_ulong(x,&port); else port = 53;
+
   udp53 = socket_udp();
   if (udp53 == -1)
     strerr_die2sys(111,FATAL,"unable to create UDP socket: ");
-  if (socket_bind4_reuse(udp53,myipincoming,53) == -1)
+  if (socket_bind4_reuse(udp53,myipincoming,port) == -1)
     strerr_die2sys(111,FATAL,"unable to bind UDP socket: ");
 
   tcp53 = socket_tcp();
   if (tcp53 == -1)
     strerr_die2sys(111,FATAL,"unable to create TCP socket: ");
-  if (socket_bind4_reuse(tcp53,myipincoming,53) == -1)
+  if (socket_bind4_reuse(tcp53,myipincoming,port) == -1)
     strerr_die2sys(111,FATAL,"unable to bind TCP socket: ");
 
   droproot(FATAL);

すなわち、環境変数「PORT」にポート番号を設定した場合は、 53番ポート番号の代わりに設定されたポート番号を使えるようにする。 例えば 2053番ポートで dnscache を起動する。 もちろんリゾルバは、こんな事情はお構い無しに 53番ポートへ問合わせるので、 それを 2053番ポートへ振り向ける (リダイレクトさせる) 必要がある。

Linux には、 パケット フィルタリング フレームワーク があって、 ネットワーク アドレス変換を自在に行なうことができる。 だから、53番ポートへのアクセスを 2053番ポートへリダイレクトする、 などということは iptables コマンドを実行するだけで手軽に実現できる。

例えば、dnscache と同じマシン上のリゾルバから 53番ポートへの接続を、 2053番ポートへリダイレクトするなら、

iptables -t nat -A OUTPUT -j REDIRECT -p udp --dport 53 --to-port 2053 \
        -s 127.0.0.1 -d 127.0.0.1

などと iptables を実行するだけである。 「-p udp --dport 53」の部分で、 UDP 53番ポートへのアクセスが対象であることを指定し、 「--to-port 2053」の部分で、 リダイレクト先が 2053番ポートであることを指定している。

また、「-s 127.0.0.1 -d 127.0.0.1」の部分が、 接続元 (つまりリゾルバ) と接続先 (つまり dnscache) の IP アドレスの指定である。 接続元が LAN 内の他のマシンの場合も許可するなら、 この部分を例えば「-s 192.168.1.0/24 -d 192.168.1.1」に変更し、 「OUTPUT」の代わりに「PREROUTING」チェインを指定して iptables を実行すればよい (後述)。

さて、これだけだと実は問題がある。 dnscache は当然のことながら自ドメインのホスト名を解決するには 同じマシン上の tinydns へアクセスする必要があるのだが、 上記のように iptables を実行すると、 この dnscache から tinydns へのアクセスまでリダイレクトしてしまう。 すなわち dnscache が localhost の 53番ポートへ、 自ドメインに関する問合わせを行なうと、 それが 2053番ポートへリダイレクトされ、 結果 dnscache (つまり自分自身) に届いてしまう。 これでは自ドメインのホスト名の解決ができない。

したがって、dnscache からのアクセスの場合だけは、 リダイレクトが行なわれないようにしなければならない。 これを実現するには、 iptables のパラメータに「-m owner ! --uid-owner Gdnscache」 を追加すればよい。 これは、アクセス元のユーザが「Gdnscache」ならばリダイレクトを行なわない、 という指定であり、 Gdnscache は dnscache を実行しているユーザID である。

以上をまとめると、 次のような sh スクリプトになる。 これをマシンのブート時に実行すればよい。

#!/bin/sh
PATH=/sbin:/usr/sbin:/bin:/usr/bin
nsredirect="-t nat -j REDIRECT --dport 53 --to-port 2053"
iptables -p udp $nsredirect -A OUTPUT -s 127.0.0.1 -d 127.0.0.1 \
        -m owner ! --uid-owner Gdnscache
iptables -p tcp $nsredirect -A OUTPUT -s 127.0.0.1 -d 127.0.0.1
if [ -n "$INNER_NETWORK" -a -n "$INNER_DNSCACHE" ]; then
        nsredirect="$nsredirect -A PREROUTING \
                -s $INNER_NETWORK/$INNER_NETMASK -d $INNER_DNSCACHE"
        iptables -p udp $nsredirect
        iptables -p tcp $nsredirect
fi

$INNER_NETWORK」と「$INNER_NETMASK」に、 LAN のネットワークアドレス (例えば 192.168.1.0) とサブネットマスクを それぞれ指定する。 また、「$INNER_DNSCACHE」は キャッシュサーバ (つまりこのマシン) の IPアドレスである。

なお、Linux のパケット フィルタリングでは、
接続元が同一ホストの場合は OUTPUT チェインが使われるので、
-s 127.0.0.1」を指定するときは「-A OUTPUT」を指定して OUTPUT チェインへ追加し、
接続元が LAN 内の他のマシンの場合は PREROUTING チェインが使われるので、
-s $INNER_NETWORK/$INNER_NETMASK」を指定するときは 「-A PREROUTING」を指定して PREROUTING チェインへ追加している。

Filed under: システム構築・運用 — hiroaki_sengoku @ 06:43
2006年7月9日

一つのIPアドレスで djbdns (tinydns, dnscache) を走らせる (2) IPアドレス指定しないサービス起動

前回は djbdns の特徴について述べた。 djbdns の大きな特徴は、 キャッシュサーバ (dnscache) とネームサーバ (tinydns) が分離している、 という点であり、 ネームサーバだけを不特定多数に対して公開することにより、 BIND など他のネームサーバがかかえている潜在的リスクを完全に回避している。

dnscache と tinydns を走らせるための、 固定的な IP が確保できるのであれば話は簡単なのであるが、 複数の (固定的な) IP アドレスを使いにくいマシン環境もある。

例えばノートPC は、移動中など、スタンドアロンで動かすこともあり、 この場合、IP アドレスは 127.0.0.1 の一つだけである。 LAN に接続したり、あるいはダイアルアップ接続すると、 もう一つ IP アドレスを持つことになるが、 この IP アドレスは固定ではなく、 接続のたびに動的に割当てられることが多いだろう。 仮に毎回同じ IP アドレスが割当てられるのだとしても、 スタンドアロン状態の時は、 その IP アドレスが利用できないという点で、 固定的な IP アドレスが利用できるとは言いがたい。

Linux 等では alias IP アドレスを設定することによって 固定的に IP を割当てておくこともできる。 例えば loopback インタフェース lo に対して

onohara:/root # ifconfig lo:0 127.0.0.2

などと別の IP アドレスを追加することができる。 マシン内部で利用するサービスならこれでもいいが、 外部に対して公開するサービスではこの方法は使えない (ノートPC で外部にサービスしてどうするん?という突っ込みは言わないお約束 ;)。

ノートPC 以外でも、 例えば小規模サイト (家庭LAN など) における ゲートウェイマシンなどにおいても、 昨今だとインターネットへの接続は PPPoE を使うことが多いだろう。 グローバル IP アドレスは接続時のみ割当てられる。 サイト外に公開するネームサーバは、 このグローバル IP アドレスで動かすのが自然であるが、 PPPoE 接続が切れている場合にどうするか考えておく必要がある。

ノートPC にしろゲートウェイマシンにしろ、 外部に対して接続しているときのみ割当てられる IP アドレスを利用しようとすると、 接続時のみ tinydns を起動する、 という方法を採らざるを得ない。 たとえば接続が成功したときに実行されるスクリプト (/etc/ppp/ip-up など) で tinydns を起動し、 接続が切れたときに実行されるスクリプト (/etc/ppp/ip-down など) で tinydns を終了させる、 という方法が一般的だろう。

しかしながらこの方法だと、 接続が切れているときは tinydns も動いていないわけで、 サイト内に対して別途 tinydns を立ち上げる必要がある。 また、 接続のたびにサーバプログラムを起動するということは、 それだけトラブルの可能性が高まるということであり、 できればもっとシンプルにしたい。 対外サービスを行なうサーバプログラムには、 常に安定して動いていてほしいわけで、 起動・停止を繰り返す運用よりは、 ずーっと立ち上げっぱなしの方が好ましいだろう。

UNIX の場合、 動的に IP アドレスを割当てられたときに、 サーバプログラムで IP アドレスを bind(2) しなおさないで済む方法というと 一つしかない。 つまり IP アドレスを指定せず (INADDR_ANY) に bind(2) する方法である。

senri:/root # netstat -nap
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address      Foreign Address    State      PID/Program name
        ...
udp        0      0 :::53              :::*                          1240/tinydns
tcp        0      0 0.0.0.0:53         0.0.0.0:*          LISTEN     1242/tcpserver
        ...

「Local Address」に「:::53」とか「0.0.0.0:53」と出ているのが、 IP アドレスを指定せずに走らせているサーバプログラムである。 このようなサーバプログラムは、 マシンに割当てられているどの IPアドレスに対する接続も受け付けることができる。 つまり新たに動的に IPアドレスが追加されても、 サーバプログラムを立ち上げ直す必要がない。

だから tinydns は IPアドレスを指定せずに、 つまり環境変数 IP に 0.0.0.0 (INADDR_ANY) を設定して立ち上げることが望ましい。

ところが、このようにしてしまうと、当然のことながら 同じ 53番ポートを使う dnscache を同じマシンで立ち上げることが できなくなってしまう。

そもそも、キャッシュサーバ (dnscache) とネームサーバ (tinydns) では 目的が違うのにもかかわらず、 同じポート番号 53番を使うのが問題なのである。 最初から別のポート番号を割当てておけば、 このような問題で悩まなかったものを... RFC 883 が悪い~
と言っても始まらない (^^;) ので、 なんとか tinydns と dnscache を IP アドレスを指定せずに立ち上げる方法を 考えてみたい。

続きは次回に...

Filed under: システム構築・運用 — hiroaki_sengoku @ 07:10
2006年7月8日

一つのIPアドレスで djbdns (tinydns, dnscache) を走らせる (1) djbdns の特徴

djbdns は、 とてもシンプルなネームサーバなので、 動作が予測しやすいという特徴を持っている。 複雑なプログラムにありがちな、 謎な現象とも無縁。 ネームサーバというと BINDが有名だが、 BIND はとても巨大なプログラムで、 特に高負荷時に理解しがたい挙動をする。 私は 3年半ほど前に BIND の異常動作 (高負荷環境下だとサービス起動に異常に時間がかかる) で徹夜する羽目に陥って以来、 BIND を捨てて djbdns を使うようになった。

djbdns の大きな特徴の一つに、 キャッシュサーバ (dnscache) とネームサーバ (tinydns) が分離している、 という点がある。 キャッシュサーバ、すなわちリゾルバからの問合わせを受けて、 他のネームサーバに再帰的に問合わせを行なうサーバは、 不特定多数からの問合わせを受付けるべきではない。 なぜなら、キャッシュサーバはその仕組み上、 攻撃に対して脆弱であり、 不特定多数に対してオープンにするのであれば、 嘘のレコードを覚え込まされてしまう 恐怖に怯え続けなければならない。

一方、ネームサーバは本来的に不特定多数に対してサービスすべきものである。 他ドメインからの問合わせ (主に他ドメインのキャッシュサーバからの問合わせ) に対して答えなければ役目を果たせない。 つまり、

  • キャッシュサーバは自ドメインのユーザからの問合わせに答えるサーバ
  • ネームサーバは他ドメインからの問合わせに答えるサーバ

であって、全く異なる役目のサーバである。 両機能を (BIND のように) 一つのプログラムで実現することは 大変なリスクをともなう。

私も djbdns に乗り換える前は BIND を使っていたのだが、 キャッシュサーバとネームサーバを分離し、 セキュリティを向上させるために様々な工夫をした。 この辺りの顛末は、 日経Linux に書いた連載の中でも紹介している:

2000年 5月号 第2回 「ネーム・サーバ (前編)」 pp143-148 (HTML 版)
2000年 6月号 第3回 「ネーム・サーバ (後編)」 pp133-140 (HTML 版)

djbdns だと、この連載で書いたような工夫をしなくても、 同等以上のセキュリティをデフォルトで実現できるので、 とても楽である。

キャッシュサーバとネームサーバそれぞれを別のマシンで動かすのであれば、 素直に djbdns を動かすだけで完璧なのであるが、 一台のマシンで両者のサーバを動かそうとすると、 少々工夫が必要である。 もし、そのマシンが複数の NIC (ネットワーク インタフェース カード) を 持っていて、 各 NIC に固定的に IP アドレスを割当てているなら、 話は簡単である。 異なる NIC それぞれに、 キャッシュサーバないしネームサーバをそれぞれ立ち上げればよい。 ところが IP アドレスが固定でない場合は少しやっかいである。

続きは次回に...

Filed under: システム構築・運用 — hiroaki_sengoku @ 08:34
2006年7月6日

ロングテール戦略が格差社会を生む: 必要は発明の母 hatena_b

仮説: ロングテール戦略が格差社会を生む の検証の二回目 (全七回を予定)。

必要は発明の母

格差が広がりつつあることの根拠として、 親の資金力が子供にかけられる教育費に影響を与え、 子供の知能に影響する、という点があげられることがあるが、 果たしてそうだろうか? 確かに、お金に糸目をつけなければ いくらでも(授業料が)高い教育を受けさせることができる。 いくらデキの悪い子でも、 教えたぶんくらいは学力が上がるだろう。 しかしながら学力と知能は違う。 知能とは考える力であり、 いい学校にいけば身につけられる、 というものでもない。

学びて思わざれば則ち罔し

教わるだけで考えなければダメ、とは 論語以来くり返し言われ続けてきていることであるが、 考える訓練を学校で行なっているかと言えば、 なかなか心もとないものがある。 少なくとも私の経験だと、 考える習慣というのは学校とは関係のないところで身につけたような気がする。

どういうときに考える習慣が身についたかと言えば、 それは何か不足しているときである。 何か不便なことがある、 あるいは何かやりたいことがあるのだけどできない。 様々な制約をどうやって乗り越えようかと思案しているときに、 ついつい深く考え込む。

私が子供の頃というと高度成長期が終わった頃なので、 世の中にモノは溢れていた。 だから「不足」というとおこがましいのであるが、 当時は大量生産の時代なので、 少数のニーズは切り捨てられていた。 また、一億総白痴化の道具と言われたテレビも、 視聴率至上主義で少数のニーズには見向きもしていなかった。 つまり、 モノが溢れていると言っても画一的な製品ばかりだったし、 テレビなどのマスメディアが提供するサービスも画一的だった。 子供心にも、テレビはつまらない番組ばかりという印象を持った。

だから、好奇心旺盛な子供にとって工夫の余地はいたるところにあった。 買うより作った方が早い、そういう時代だったし、 小学生が電子工作に夢中になるのも珍しいことではなかった。 小学生でもいろいろ考えれば、 大人が驚くような成果を誇示することが可能だった。

「知」に対する渇望

プログラマを目指すのに適した時代、適していない時代」で書いたように、 私がプログラミングを学ぼうとした時代は制約や不足だらけだった。 そもそも入門書が無い。 少なくとも街の本屋にはコンピュータ関係の本は皆無だったし、 大阪梅田の 紀伊國屋書店旭屋書店でさえ、 コンピュータ関連書籍のコーナと言えば、せいぜい本棚一つくらいのものだった。 そんな希有な本棚を見つけ出せたとしても、 現在みたいに手取り足取り教えてくれる入門書なんてあるわけがなく、 大学の専門課程の学生向けの専門書を、 わずかな手がかりをもとに当時中学生だった私が読み解いていくのである。 まさに「読書百遍、意自ら通ず」の世界である。

そんな私が、初めて 八重洲ブックセンターを 訪れたときの感慨を理解して頂けるだろうか? 大げさに聞こえるだろうが、まさに砂漠で一杯の水を見つけたような気分だった。 一日中ここですごしたいと思ったものだ。

そうやってあちこちを探しまわって なんとか入手した 6502 のデータシートに記載されていた ニーモニック表を手がかりに、 まるで暗号解読をするように一命令づつその動作を想像し、 ついにはハンドアセンブルできるようになった時の達成感、 そしてハンドアセンブルして作ったバイナリコードを PET 2001 に打ち込んで実行し、 BASIC とはケタ違いのスピード ──まさに一瞬だった── を 目の当たりにしたときの感動は、 今でもありありと思い出すことができる。

「知」に対する渇望があるからこそ、 人は学び考えるのだろうと思う。 渇望するより先に与えられてしまったとしたら、 果たしてそれを学び考えようとするだろうか? 少なくとも若かった頃の私にそれができたかというと、 はなはだ自信がない。 いつでも学べると思うと、 「時間ができたら勉強したい」と 後回しにしてしまいそうな気がするのである。

不足(ニーズ)あるところに商機あり

多品種少量生産の時代になって久しい。 どんなニッチなニーズでも、 それを満たす製品ないしサービスがたちどころに開発されて提供される。 しかも IT技術によって全国津々浦々、どこにいてもその恩恵を受けられる。 やっとの思いで上京して八重洲ブックセンターに行く必要はないのである。 かゆいところに手が届くサービスが湯水のように提供されているのに、 どうして不足を感じることができるだろうか。 まして「渇望」とは無縁であろう。 世の中これだけ便利になってしまうと、 どうやって工夫すればいいのだろう? テレビが成し得なかった「一億総白痴化」を IT技術が達成してしまうのだろうか。

いや、そんなことはない、 インターネットの時代では、 消費者は単に消費するだけでなく、 自ら情報を発信していく、 生産者的かつプロフェッショナルな消費者 つまりプロシューマだ、 という人がいるかも知れない。 それはその通りだろう。 一部の消費者は「消費者」の枠に留まらず、 どんどん活躍の場を広げていくことだろう。 しかし、 そういった活躍をするのにも知能は必要である。 身近なところで考える訓練を積むことなく、 いきなりインターネットの世界に晒されては、 情報発信以前に、 あっと言う間に魑魅魍魎の餌食になるだろう。

Filed under: 自己啓発 — hiroaki_sengoku @ 06:29
2006年7月1日

プログラマを目指すのに適した時代、適していない時代 hatena_b

プログラマの道を目指すのに適した時代、適していない時代、 というのがあるように思う。 もちろんプログラマに限らず、あらゆる職種、それぞれについて、 適した時代というのがありそうだ。 最初に断っておくが、 適していない時代だからといって、その職種を目指すな、と言っているわけではない。 ただ単に、適していない時代であることを意識し、 適していないことを覚悟して ;-)、その道を目指すべきだ、という意味である。

現代は、プログラマを目指すのには適していない時代だとつくづく思う。

そんな馬鹿な、インターネットの普及によって、何でも簡単に調べられて、 その気さえあればいくらでも高度な勉強ができて、 いくらでもプログラマとしてのスキルアップができるではないか、

という反論が聞こえてきそうであるが、 もうしばらく黙って私の話を聞いて欲しい。

自分なりに体系化するセンス」で、長久氏曰く:

「仙石浩明の日記」版「断片的な知識と体系的な知識」を見ると、 こういう学生時代を過ごして来た人って、 私の知人を見る限り 「未踏」級なんですよね。 で、やっぱり1回目の未踏に採択されています。 また、学習指導要領的には、 私の1世代前で、最も勉強が難しかった世代です。 今と違って、誰でもプログラマーになれた時代でもありません。 恐らく、仙石氏の同世代で普通のプログラマーって、 私の世代の普通のプログラマーより、 はるかにパフォーマンスが高いはずです。 更に世代を下がって、今の20代前半の普通のプログラマーって、 仙石氏の世代から見て、ありえない人たちに見えるのではないかと思います。
あまり議論されているのを見たことないのですが、 世代の違いって、すごく大きい気がします。 ソフトウェア技術者って、 仕事でハンマーとか使わないから(?)、 後輩に優しかったり、 職場に同じ年代が集まりやすいので、 世代を超えて積極的に交わろうとしなかったり、 世代間の断絶みたいなものがある気がするのです。 なので、私は、プロレスのように、積極的に世代闘争するべきだと思うんですよね。

「未踏」というのは、 「天才プログラマー/スーパークリエータ」を発掘支援することを目的に IPA が実施している 事業で あるが、 採択された他の方がどうだかはよく分からないが、 少なくとも私自身はとても「天才」とか「スーパー」とか呼ばれるようなレベルでは 全然ないと思う。 これは決して謙遜というわけではなくて、 自身がそういうレベルではないと思うからこそ、 プログラミングのみに集中するのではなく、 「取締役CTO」みたいなことをやったり、 マーケティングをかじってみたりと、 プログラマとしては道を踏み外したことを専らやっているわけだ。

そんな私が、いやしくも IPA のような権威に認めてもらえるように なってしまったのは、 ひとえに私がプログラミングを始めた時代が、 プログラマを目指すのに適した時代だった、 という幸運に恵まれたためだったからと思う。 私が初めてプログラムを書いたのは、 今から 30年近く前、中学1年生の時である。 1978年当時は、まさに長久氏がおっしゃる通り、 今と違って、誰でもプログラマーになれた時代ではなかった。

そもそもコンピュータ自体がまだまだ珍しい存在で、 私自身、もし中学校に「マイコン部」が無かったら、 コンピュータに出会うのはもっと後になってからだったとは思う。 コンピュータに出会う確率が低かった、 という意味で誰でもプログラマーになれるわけではなかったわけであるが、 それ以上に、当時の「マイコン」には少なくとも普通の人にとっては、 なんの魅力も感じられない代物だった、というのが重要な点である。

今と違い当時の「マイコン」は、大したことはできなかった。 高々 20Kバイトの BASIC インタープリタに、 最大 8Kバイトの RAM に記憶させた BASIC プログラムを実行させて、 40x25 キャラクタディスプレイ (つまりビデオRAM はわずかに 1Kバイト! もちろん表示できるのは半角文字だけである) に 表示させてできることなぞタカが知れている。 慣れない BASIC言語でプログラム書いてはバグに悩まされ、 散々苦しんだ挙げ句に得られる見返りは、あまりに少なかった。 自分で言うのもアレだが、 こんな何の役にも立たないものが好きになるのは、 よっぽどの物好きだけだったろう。

実際、私の同級生の中には、 プログラミングに興味を持って BASIC 言語を学ぼうとした人も沢山いたが、 大多数の人は何をすき好んでこんな七面倒くさい「言語」を学ぶのか、 到底理解できず、すぐ興味が別のものへ移っていった。 中学を卒業する頃、まわりを見渡してみると、 BASIC 言語を使いこなすレベルまで到達したのは私だけだったと記憶している。 私以外の同級生が BASIC 言語も使えないくらい低能だった、 というわけでは決してない。 それどころか私より明らかに頭がいい人も沢山いた。 それでも BASIC 言語一つ覚えられなかったのは、 単にプログラミングをするということに意義を見いだせなかっただけに過ぎない。 彼らが現在の中学生だったなら、 余裕で Web 2.0 時代のプログラミングをバリバリこなしていただろう。

つまり、誰でもプログラマーになれた時代ではなかったというよりは、 誰もプログラマーになろうとは思いもしなかった時代だった。 しかし、逆説的ではあるが、 苦労に見合うリターンが全く得られないからこそ、 自分がプログラミングが好きだということを確認できたという点で、 当時は「プログラマを目指すのに適した時代」だったと思う。

それに比べ、 現在のように少しでもプログラミングができれば給料までもらえてしまう、 ある意味プログラマが必要以上に優遇されている世の中では、 好きだからプログラミングをするのか、 それとも単に食うために(仕方無しに)プログラミングするのか、 曖昧になってしまうわけで、 「プログラマを目指すのには適していない時代」なのだと思う。

長久氏がおっしゃるように、 「仙石氏の同世代で普通のプログラマーって、 私の世代の普通のプログラマーより、 はるかにパフォーマンスが高いはず」というのは (実際に統計をとったわけではないが実感としては) 正しくて、 その原因は、 当時の「普通」のプログラマは、 みな例外無くプログラミングが三度の飯より好きだったし、 プログラミングに向いている人だけがプログラミングをやっていた、 ということにあるのだろうと思う。

昔話に終始していては、現在の若い人たちの参考にならないだろうから、 この話を現在に適用すれば、次のようになるだろう:

今の時代は、 プログラミングをすれば充分すぎる見返りが得られるが故に、 自分がプログラミングに向いているのか、 あるいは単に見返りのためにプログラミングをしているのか見極めるのが、 とても困難な時代である。 プログラマを目指すのもいいが、 向いていないことを後になって自覚して 「35歳で定年を迎える」ことにはなってほしくない。 現在は明らかにプログラマを目指すのには適していない時代である。 では何を目指すのに適した時代だろうか? 1978年当時の「マイコン」に相当するものが、 今の時代にもきっとあるはずである。 若い感性でそれを見つけ出し、 誰もが目指さないからこそチャンスがあるんだと信じて、 自分に向いていることをどこまでも追い求めて欲しい。

Filed under: 技術者の成長 — hiroaki_sengoku @ 08:41