2008年12月7日

google のボットは javascript 生成コンテキストを追跡できないのだろうか??

fjの教祖様 の蔵書/既読書@GeoCities というページを持っている。

ここのインデックス部分を、全てのページで static に保持すると物凄くディスク容量を喰う(全体の 3/4 がインデックスだった事が判明している)上に、同じデータを何度も何度もクライアントに転送するのは重たい。さらに言うと、インデックスに何か追加されるたびに全体が再構成、サーバへも再uploadするため耐え難い…というので、ここをどうにかして client side include (CSI)できないかと考え… javascript で生成する事にした。Javascriptならば <script src="xxxx"> と記載すれば別途読み込める。

読み込んだ関数はすごく馬鹿みたいで、document.write() を使って本来そこにあるべきインデックスを現す html 命令をひたすら書き出しているだけだ。すごく簡単だが、結構強力。なによりビルドの相互依存性や再構築範囲の大幅な減少はありがたかった。

ありがたかったのだが、しばらく運用して判った事として、Google のエンジンがこの javascript による URL 展開結果を追跡できないらしい。この変更以降に作られたページが全くでてこないし、それ以前からあるページも古いイメージ分しか検索されない。新しく登録した本とかが出てこないのだ。

うーむ。検索性が下がるのは、それはそれで困るなぁ。だからといって、転送量が増えるのはオリジナル→サーバも、サーバ→クライアントも、困る。

何かいい手を考えなくてはいけないなぁ。

2008年11月11日

shell は奥が深い…

/.J の記事の話。

(便利で)くだらないUnix技は?」の「Re:びっくりマーク」に対するコメントから始まる一連。

いやー失敗。

よく知っているパターンとして
% ^aaa^bbb                             が「最初の aaa を bbb に置き換える」
と言うのがあったので、それと空目していました。
% ^aaa^bbb^
そう。まさか最後にもう一つ「^」がついていたとは。

確かに「最初の2つの aaa を bbb に入れ替えたい」場合は

%^aaa^bbb^:&

がよさそうです。

ちなみに、
以外で呼んだ事が無いのですが、全部確実に置換したければ

%!!:gs/aaa/bbb/

とやるのだそうです。また、: の後ろに置換コマンドを書くことが出来るそうです。例えば、

%!!:gs/aaa/bbb/:gs/ccc/ddd/

とかの感じですね。

知っていればもっと楽になった事が多々あったのにぃ~~~

2008年10月26日

聘珍樓


Amazonのサイトに食い物系が追加されたと聞いてみていたら、なんと「聘珍樓」の商品を扱っていた。
おぉう。聘珍樓と言うとアレだな。新宿三井ビル54階にある中華料理屋。
55階をEMCのマシンルームに取られる、という屈辱を味わっている。つーかEMC、明らかに立地間違えてるだろうが。なんで本来展望ルームかレストランがあるべきところにマシンルームなんだよ。

というわけで。とりあえず美味そうなものを選んでぐるぐるウィジェットにしてみました。
誰かおごってください (^o-)。

東大合格生のノートには汚いものもある

『東大合格生のノートはかならず美しい』
えー??! うっそだー!?
それがタイトルを聴いた瞬間の感想。だって自分のものでこそ無いが、東大生のノートなら知ってる。家族にいるからだが。綺麗でもなければまとまってもいないぞ。

東工大生のノートも知ってるし、早稲田・慶応の理工学部合格者のノートも知っている(これは全部自分)。東大生に輪を掛けて汚い。

と言うわけで。何を勘違いしているんだろう??! と思い立って本を買ってみてみました。一瞬で納得。著者である「太田あや」はノートには3種類もある事を知らないらしい。知らなかったら、そりゃ勘違いするわ。

と言うわけで、せっかくの受験シーズン突入期。ノートの種類と共通する特徴についてちょっと書いて見ましょう。


まず、ノートの種類から。ノートには大雑把に3種類あります。

  1. 資料的ノート

  2. 答案用紙的ノート

  3. メモ


資料的ノート


『資料的ノート』というのが、『東大合格生のノートはかならず美しい』という本で集めているノートです。自前の参考書のようなものですね。確かにこの手のノートは長く保存するものですし、丁寧に作るでしょう。もしあなたがこの手のノートを作るタイプならば

そう、本質的に資料を作らない人のほうが多いんです。だってそんなのは参考書でいくらでも代替が利く。適切な参考書をいかに最初に吟味して選ぶか、そこをちゃんとやっていればこの手の資料は作らなくてもいい。

逆にこの手の資料を作るタイプの人は「資料を作る過程で」物事を覚えていく。なのでこのタイプのノートを読み返しているとき、その人は実際には
「そのノートを作っている自分をリフレインする形で記憶を更新している」
のであって、そのノートに書かれていることそのものを覚え直しているのではない、と言うことも念頭に置いた方がよいでしょう。

答案用紙的ノート


『答案用紙的ノート』は問題集を解くためのノート。問題集を解く時に使うノートです。これは単に問題を解くために使うのではありません。自分がどのようにして問題を解いたのかを分析するためにも使います。

答案用紙的ノートを普段のノートと分けていない人は意外と多い。しかし考えて見れば『資料的ノート』の中に、問題集を解いた結果が混ざっているのは読みにくい。『答案用紙的ノート』の中に『資料的ノート』が挟まっているのも(いろいろカンニングが出来て)都合が悪い。なので、ノートとしてこれは独立させる必要があるのです。

メモ


『メモ』は、授業などで使うノートです。授業中と言うのは授業の流れに応じて先生の説明を記録したり、与えられた問題を解いたり、暇になったら落書きしたり…と実に無茶苦茶な使われ方をするものです。なのでメモ用ノートは『資料的ノート』『答案用紙的ノート』のいずれとも分けなくてはいけません。




さて。殆どの人は『メモ』タイプのノートしか持っていないのではないでしょうか?
これに対して、『東大合格生のノートはかならず美しい』で集めているのは資料的ノート。そりゃこの2つを比較したら「東大に合格する奴のノートは違うんだなぁ」と勘違いするでしょう。

でも実際には「別のノートを見せられている」から違うに決まっています。投入する力が違うんですから見てくれからして違うに決まっている。

「なるほど。じゃぁ全く参考にならないのか」

そんな事はありません。資料的ノートとして見るならば十分参考になるでしょう。あと全体でなるべく共有するべき特徴があります。

  1. 余白を十分に取る

  2. 区切りを大事にする

  3. 丁寧に書く

  4. バインダーを使わない(メモは「なるべく」。残り2つは「絶対」)


最初の3つは『東大合格生のノートはかならず美しい』でも述べられていますね。


余白を十分に取る


余白はノートの表面を眼が流れていくときに、自分にとって重要な情報がどこに書かれているのかを知る重要な手がかりです。無駄に文字を密集させたノートは読みづらく、故に読むのに時間がかかります。「資料」「メモ」の2種類についてこの性質が重要なのは言うまでもありません。

「答案用紙」タイプでもこの性質は重要だ、と言うのを知らない人が多いのが問題です。問題を解く場合、特に大学受験の数学は、条件分岐と部分証明の繰り返しが頻発します。極めて煩雑な作業で、途中で気が遠くなる。このときに見通しの悪い回答だと、証明するべき内容を1つ2つすっ飛ばしてしまう、などのミスが発生します。ほんの数分未来の自分がミスをしないようにするために、視認性の高い回答を書く必要があるのです。

あと、もう1つ。「答案用紙」タイプは問題を解くだけでなく、自分がどのように問題を解いたのか、その分析にも使います。このため分析段階で特徴などを見つけ出し情報を記載する空間もなくてはいけません。このためにも余白は十二分に取る必要があるのです。

私の場合、「答案用紙」の場合、キャンパスノートタイプにし、右半分しか使いません。左半分はメモ用。バインダーにしないのは「左右でワンセット」だからです。

区切りを大事にする


東大合格生のノートはかならず美しい』では、見開き単位での区切りについて述べていますが、ノートそのものの区切りと言うものも同じように大切にしているはずです。どのジャンルでもサブジャンルと言うものがありますが、それらの単位でノートはまとまっているでしょう。

ようするに「この内容を知りたければどのノートを見ればいいのか」という段階で混ざらないようにしてあるわけです。

なので、ノートのページ数は少ない目に、冊数は多い目に、というのがノートを買う段階でのコツになります。

答案用紙タイプの場合、答の区切り、と言うものも大事になります。特に数学の証明問題は、
1) 問題の分割
2) 各部分問題の解
3) 全体をまとめ直して問題全体に対する解にする
という3段階に分割できるものです。1,2,3がそれぞれどこからどこまでなのか、2は各部分解がどこからどこまでなのか、判るように記載するべきです。これには「余白」も大事になりますし、「丁寧に書く」事も大事になりますが、同じぐらい「区切り」単位で証明等を離して書く、などの対処にも繋がります。


他に面白い『区切り』として、物理の力学と数学を混ぜるというのもあります。

ご存知の人はご存知の通り、微積分とベクトル・行列はそもそもニュートン力学を表現する上で必須の知識です。逆の言い方をすると、微積分と線形代数を先に、ニュートン力学を後に勉強すると苦労が大幅に減る。この場合、力学と数学を別々に勉強してしまうと逆に苦労が増える。なのでこの2つはわざと「物理・数学のように区切らずに」ノートを作る。

丁寧に書く


メモは比較的走り書きにするでしょう。資料は丁寧に書くのは(後で見直すことを考えれば)当然です。
答案用紙も実は丁寧に書くべきです。これは最終的に他の人に見せ、それによって採点を受ける答案を書くための練習台だからです。字が汚くて☓というのがうれしい人は、そうそういないと思います。

丁寧に書いていれば綺麗かどうかはともかく「読み易い字」を早く書くことができるようになりますしね。その意味では「丸文字」等の変形文字は使わないことも重要です。

バインダーは使わない


「余白」の部分ですでに説明しましたし、『東大合格生のノートはかならず美しい』にもありますが、資料・答案用紙型のノートは「見開き単位で」埋めていくものです。

しかるにバインダー型ノートは「紙単位」で管理するもの。見開きの左右がばらばらになってしまう危険性があるので、資料・答案用紙についてはバインダーを使わないほうがよいのです。

一方でメモは片面単位で使うことも出来ますし、1枚単位で追加削除できる方が利便性が高まります。なのでこちらはバインダーでも構いません。ただし、ノートはバルクで買うとどんどん安くなるので…気分転換以外の理由でバインダー型を併用するメリットはあまりありません。




というわけで。以上の条件をちゃんと満たしていればOK。インデックスなんて無くても構いません。文頭が揃ってなくてもOK。全く問題はありません。

ちなみに。
この本は「コクヨ」の CAMPASノートのニューバージョンの広告を兼ねています。が、私に言わせれば、ドットを打つよりもプロジェクトペーパー(7mmぐらいの方眼用紙)でノートを作ってもらった方が、よほど使いやすいと思いますね。これを2x2を1枡として使っていく。そのほうが快適なノートが作れます。

2008年10月11日

た…正しい、正しすぎる…

そもそも「止まってはいけない」「RCA」と叫ぶばかりで運用と言う概念が無い会社が多すぎるのが悪い

/.J のメインフレーム技術者不足、問題にという議論より。

そもそも、労働者の供給市場としてメインフレーム技術者が需要過剰になる、と言うことは2通りしかありえない。需要が急激に増えて供給が追いつかないか、世界的・汎業界的なトレンドに反している特殊需要者がいるか、のどちらか。そしてこの場合は後者に決まっている。

そもそも日本の客はオープンソースにメインフレーム並みのサービスや機能を要求するなど、非常識極まりない。「あるものを使う」のではなく「欲しいものを述べてふんぞり返る」事しかしないのだ。その結果、金払いはいいが、コストが掛かりすぎるので利益が圧倒的に少ない、という状態に陥る。受注する側にすれば迷惑な存在でしかないのだ。そのことが判らない、売上げばかりに目が行って純利益を考えない経営者が多すぎる、と言うのも問題だが。

良い機会だ。放置してしまえばよい。誰も対応しないのが一番だ。売上げはたくさん立つだろうがどうせ儲からないのだから。

2008年9月28日

日本の湿気った空気には、水冷が良い

日本の夏は蒸し暑い。これは日本人ならば誰でも知っていると思う。

日中最高気温は35度以上になり、40度だって当たり前。
なのに湿度が60%を下回る事はない。恒温動物にとって地獄のような環境である。

さて、一方その頃(え?)。

飽和水蒸気量という単語をご存知だろうか? Wikipediaへのリンクをくっつけてあるが、ようするに 1m3の空間中に存在できる水蒸気の質量をgで現したもの、だそうだ。当然、これは100%のときの質量であって、たとえば湿度が60%の場合、存在している湿度の量はその60%になる。

で、大事なのはその曲線の形状だ。Wikipediaの画像をちょいと無断拝借:

飽和蒸気圧曲線

数字はどうでもいい。大事なのは形状だ。
わかるだろうか?気温10度から20度へ10度上昇した場合と、20度から30度へ10度上昇した場合とでは、後者の方が増大量が大きい。

問題はこうだ。
データセンターのようなマシンルームでは、室温20~25度、湿度0~30%になるように押さえつけなくてはいけない。内部に格納されている全てのマシンが空冷だからだ。外気温が35度、湿度50%の状態からこの状態へ空気を冷やすにはどれだけの熱量をくみ出せばいいのだろうか?当たり前だが単純に20度に冷やすだけでは湿度は100%になってしまうので、20度のときに湿度30%になるぐらいまで水を減らす必要が出る。

水が同じ温度の水蒸気になるためには気化熱が必要だ。Wikipedia の蒸発熱のページによると、40.8 kJ/mol のエネルギーが必要だ。これは0度から100度まで温度を上げる際に必要な熱量の5倍に当たると言う。逆に言うと水蒸気を水に戻すときにはこれだけのエネルギーを「気温降下とは別に」くみ出さなくてはいけない。

一方で、マシンの冷却に湿度は関係ない。湿度はマシンが錆びたり、黴たりするのを防ぐために下げるのであって『気温は下がらないけれども、湿度を下げれば…』とはならないのだ。マシンは汗をかかないから。




そこでこういう発想が出てくる。

仮に、気温を20度まで下げる代わりに30度までしか下げない事を考えよう。で、チップなど主な冷却対象に液冷装置をつける。液体の温度は30度にすることで結露を防ぐ。代わりに、液体を強制循環させてどんどん熱をくみ出す。CPUなどの表面温度は40度以上なのは空冷であっても変わらないので、30度の液体を強制循環させた場合でも十分な冷却効果は得られるはずだ。

30度までしか気温を下げないので、除湿しなくてはいけない量が圧倒的に少なくて済む。これによってデータセンターの冷却設備の能力を、マシンを冷却する事に集中させる事ができる。




さて。これでどれぐらい無駄なエネルギーを削減できるか。
うーん。面倒なので誰か代わりに計算してください(おぃ

大雑把に言っても、夏場、エアコンはもうジャブジャブと水を「生産」しています。水1molは18gしかありません。これは18ccと同じです。一合は180ccなので計量カップ一杯は10molです。
1molの水がジャブッと出るたびに40.8kJが必要なので、180ccの水が出てくるのには408kJの熱をくみ出す必要があります。

水を1mol、0度から100度にするには7.53 kJ必要です。別の言い方をすると10度下げるには0.753kJくみ出すだけでいい。乾燥空気の場合は(http://q.hatena.ne.jp/1180249482によると)0.288[kcal/m3 ℃]=1.2kJちょいですから12kJくみ出せば10度下がります。このことから考えると、ワンカップの水が冷却器から出てくるたびに、34m3の空気を冷やすのと同じ能力が消費された、と見ることが出来ます。液冷にする事で、この能力の大半を、本来のマシンを冷やす事に振り向け直す事ができるのです。




夏場、冷房装置からどれだけの水が出ているのか見てください。
家庭用のエアコンは真夏の日中に空気を20度に冷やしたりしません。なのにそれだけでるのです。

マシンルームのデザインに液冷対応を考慮するのは十分価値のある事だと思いませんか?

2008年9月6日

Process Monitorの出力をいじる

WindowsにはProcess Monitorというツールがある。多分アンカーの指している場所がダウンロードサイトの中で最も簡単に手に入れられるページだと思う(日本語で説明が書いてあるから)。

対応OSは 2000, XP, 2003, そして Vista だそうだ。

Process Monitor (procmon.exe)は、NT kernelへのシステムコール…というかリクエストキューに積まれたリクエストを記録し続ける。記録されるのは全てのプロセスのリクエストだ。unixのstraceなどと違って「このプロセスの」とか「あのプロセスだけ」という制約は無い。そのおかげでシステム全体の状態が判るが、これはセキュリティ上は結構危険な状態でもある。

procmon.exeは記録したシステムコールを表示するときにも使える。いくつかのフィルター条件を設定して望みのものだけを選び出すことが出来る。ある特定のプロセスが発行したもの、特定のスレッドが発行したもの、あるファイル(あるいはレジストリパス)に対するIO、あるシステムコールだけを選ぶ…などができる。実はシステムコールを発行した(キューに積んだ)時刻だけではなく、これが完了するまでにかかった時間も記録している。
「システムコールが終わるまでに0.1sec以上かかった」
とか
「システムコールに対する応答が無かった」
などという条件も設定できるのだ(NTのシステムコールは「キューにリクエストを積んで」「応答を待つ」形式なので、本質的に全て非同期コールだ)。

障害解析やパフォーマンス解析においてこれほど強力なツールはまず、ない。

が、世の中どんなに頑張っても
「それは俺の設定したい条件じゃない」
と言うことはあるわけで。そうなるとPerlのようなスクリプト言語の出番になる。




Perlに読めるようにするためには、procmon.exeが記録した内容を何らかのテキストの形で出力してもらわなくてはいけない。それ自体は簡単だ。

% procmon.exe /OpenLog 'filename.PML' /SaveAs 'filename.CSV'


PMLは procmonが出力するバイナリフォーマットのログ、filename.csvは「csvフォーマットでファイルを出力しろ」と言う意味だ。ちなみにこの場合、csvファイルはutf-8で出してくれる。なんとUCS2やUTF-16じゃないのだ。ありがたい。

しかし、この出力には2つ問題がある。

1つ目はファイルの先頭にBOM … Byte Order Mark …がついている点だ。確かにこれがあれば確実にUTF-8だと判るのだが、私の知る限り perl が標準入力から読み込むファイルの操作に関して、BOMを適切に処理できる、と言う話は聞かない。だから、BOM…この場合はファイル先頭の3byteなのだが…を削らなくてはいけない。

2つ目はCSVそのものにある。いや、もちろん、CSVだって悪いわけじゃない。もし1つのValueの中にカンマで分割された文字列が入っているのでなければ

perfmon.exe の記録のいくつかのフィールドが、それ自体カンマで区切った複数フィールドから成り立っているのだ。例えば Detail というフィールドなんかがそうだ。たとえば:
"User Time: 0.0781250, Kernel Time: 0.0312500, Private Bytes: 1,806,336, Working Set: 5,439,488"

とか(これは Process Profiling をやっているときの記録だな)、
"Desired Access: Read Attributes, Disposition: Open, Options: Open Reparse Point, Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a, Impersonating: S-x-x-xx-xxxxxxxxx-xxxxxxxxx-xxxxxxxxx-xxxx, OpenResult: Opened"

(これはファイルに対する IRP_MJ_CREATE のDetailだな)、このように1つのエントリ自体が複数のカンマで区切られたフィールドになっている。判ると思うが、各エレメントは " で囲まれている。

すると、単純にカンマをセパレータにして split をするとエライ目に合うわけだ。そこで、CSVをTSV… Tab Separated Values …形式にする。" で囲まれた領域に TAB は含まれていないので split をしかけるときにセパレータを /\t/ と定義すれば、あっさりと正しく split できるようになる。ファイルをこの形式にしておく事で、この後何度も統計処理や絞込みのために行う splitting rule を簡素化できるわけだ。

TSVにするフィルター自体はすごく簡単に作れる。これがコードだ:
tail --bytes=+4 input.CSV |\
sed -r -e 's/\r$//g' \
-e 's/\",\"/\"\t\"/g'\
> output.TSV


最初の tail --bytes=+4 は input.CSVの先頭3バイトを取り外す。これでBOMが無くなる。

GNU sed に与えた -r オプションは「拡張正規表現」を使えるようにする、というものだ。実際の正規表現はその次の2つの -e で始まるものになる。

's/\r$//g' は行末の 0x0d を取り外しているだけだ。ようするに改行コードを unix 形式になおしている。

's/\",\"/\"\t\"/g'は 『","』 となっている場合の , を TAB に入れ替える。ここには、procmon は「"," というフィールドデータを吐かない」という前提を使っている。少なくとも今の所、見たことは無い。多分大丈夫だろう。




ちなみに。TSVに直した後も、各エレメントは " で囲まれたままだ。で、 " で囲まれたエレメントを処理するときには「まだ」面倒な問題が残っている。

" で囲まれた中で " を表現するには『""』のように"を2回連続しなくてはいけない。

で、「そのプログラムはどのように起動したのか」を説明する「Command Line」フィールドに絶対パスが例の『Program Files』を含む場合、このようになってしまうのだ:


"""C:\Program Files\IBM\Director\websrv\dirwbs.exe"""


一番外側の " は「フィールド」を囲む " だが、その内側の "" は実際には1つの " を " で囲まれたフィールド内で表現するためのものだ。

この点だけは注意した方がよい。

2008年8月30日

何かを見つけた、その後

おっとっと、忘れてた。

仮に、問題のポイントと相関が高いカウンターが見つかったとしよう。それで終わってくれるならば特にどうと言うことは無いだろうが、普通は
「で、それは何をどうしているって??」
と言うことを確認しなくてはいけない。もし障害分析を仕事でやっている場合ならばお客様には
「r2が 0.43 なのでこいつが問題点です」
という1行よりはもう少し親切な…そう例えばグラフ化するとか…してあげなくてはいけない。

そこで、自分が「これ」と決めたカウンターに関して、Excelシートを作る事を考えよう。

もちろん、対象となるカウンターがもう決まっているのだから、relog.exe に対象カウンター一覧を食わせて TSV ファイルを作り、それをそのまま Excel に飲ませるのだってOKだ。
ただ、このやり方だと、例えば対象となる Performance Monitor のログが30個あると、30回「新しくシートを作って、そこにTSVファイルを読み込ませて」を繰り返さなくてはいけない。はっきり言おう。私は嫌だ。

と言うわけで。Excelシートを作ってくれるスクリプトだ。

toxls.pl

#!/usr/bin/perl
# Output xls file name is described as ARGV[0];
# ARGV[1] and on should contian
# ( ARGV[odd], ARGV[odd+1] ) = ( TSV filename, sheet name ).
# And at least ARGV[1] and ARGV[2] should be given in order to have something meaningful.
# Or, you'll get empty Excel file.


use Spreadsheet::WriteExcel;
use Spreadsheet::WriteExcel::Utility;

$workbookname = shift @ARGV;
if ( !defined( $workbookname ) ) {
die "Excel WorkBook name not given\n";
}

my $workbook = Spreadsheet::WriteExcel->new($workbookname);


@sheetnames = @ARGV;

while( $sheetfilename = shift @ARGV ) {
$sheetname = shift@ARGV;
if ( !defined( $sheetname )) {
die "Excel sheetname not given for TSV file name: $sheetfilename\n";
}

readsheet( $sheetname, $sheetfilename );
}

$workbook->close();
exit 0;


sub readsheet {
my ( $sheetname, $sheetfilename ) = @_;

my $worksheet = $workbook->add_worksheet( $sheetname );
open SHEETFILE, $sheetfilename or die "unable to open filename: $sheetfilename\n";


my $linenumber = 0;
my $offset = 5;
my $maxcells = 0;

while () {
chomp;

my @cells = split /\t/;

if ( $maxcells < $#cells ) {
$maxcells = $#cells;
}

if ( $linenumber == 0 ) {
$column = $linenumber;
} else {
$column = $linenumber + $offset;
}

for ( $i = 0; $i <= $#cells; $i++ ) {
$cells[$i] =~ /^\"(.+)\"/;
my $tmp = $1;
$worksheet->write( $column, $i, $tmp );
}
$linenumber++;
}

$maxlinenum = $linenumber + $offset;

for ( $row = 0; $row <= $maxcells; $row++ ) {

# Since we need to skip first element, headofdata requires to have +1.
my $headofdata = $offset+1 +1;
my $tailofdata = $maxlinenum - 1;

my $ydatatop = xl_rowcol_to_cell( $headofdata, $row );
my $ydatatail = xl_rowcol_to_cell( $tailofdata, $row );

my $xdatatop = xl_rowcol_to_cell( $headofdata, 1 );
my $xdatatail = xl_rowcol_to_cell( $tailofdata, 1 );


my $formulacol = 1;
my $formularow = $row;
if ( $row == 0 ) {
$worksheet->write_string( $formulacol, $formularow, 'R2' );
} elsif ( $row == 1 ) {
$worksheet->write_formula( $formulacol, $formularow, "=RSQ( $ydatatop:$ydatatail, $xdatatop:$xdatatail)" );
} else {
$worksheet->write_formula( $formulacol, $formularow, "=RSQ( $ydatatop:$ydatatail, $xdatatop:$xdatatail)" );
}


$formulacol = 2;
$formularow = $row;
if ( $row == 0 ) {
$worksheet->write_string( $formulacol, $formularow, 'a' );
} elsif ( $row == 1 ) {
# do nothing
} else {
$worksheet->write_formula( $formulacol, $formularow, "=SLOPE( $ydatatop:$ydatatail, $xdatatop:$xdatatail)" );
}


$formulacol = 3;
$formularow = $row;
if ( $row == 0 ) {
$worksheet->write_string( $formulacol, $formularow, 'b' );
} elsif ( $row == 1 ) {
# do nothing
} else {
$worksheet->write_formula( $formulacol, $formularow, "=INTERCEPT( $ydatatop:$ydatatail, $xdatatop:$xdatatail)" );
}


$formulacol = 4;
$formularow = $row;
my $r2 = xl_rowcol_to_cell( 1, $formularow );
if ( $row == 0 ) {
$worksheet->write_string( $formulacol, $formularow, 'High Relation' );
} elsif ( $row == 1 ) {
# do nothing
} else {
$worksheet->write_formula( $formulacol, $formularow, "=IF( $r2>=0.25,\"*\",\"\")" );
}
}

close SHEETFILE;
}


ヘルプも何もありゃしない :p 使い方としてはこんな感じ:


% toxls.pl AFO.xls A.TSV A-dayo B.TSV B-desu


するってーと AFO.xls が作られる。開くと見えるのはこんな感じだ。



タブを見ると「A-dayo」「B-desu」というのがあるのが判るだろう。それぞれ A.TSV, B.TSVの中身がシートになった状態になっている。

こいつにはもう一つおまけの機能がある。2行目から4行目がそれぞれ「r2」「y=ax+bのa」「y=ax+bのb」になっている。これらは Perlで算出したものではなく、Excelの「式」が書いてあってあなたがこのExcelシートを開いたときに値を再計算してくれた状態なのだ。

5行目には「もしr2の値が0.25より大きかったら * を、そうでなければ何も表示しない(エラーの場合を除く)」という式が埋めてある。単なる目印のようなものだが、たまに便利だったりする。

2008年8月26日

15個に分類するには

sort.pl が出してくる3つのファイルを、マシン2台分用意してAとBの邂逅の図1のように分類するのに必要なツールは、実は簡単なものでいい。

今回はcommon.plとonlyFirst.plという2つのプログラムを作り、それを使うことにしよう。
common.plは2つのファイルを受け取り、その両方に存在するカウンター名を出力する。
onlyFirst.plは同じく2つのファイルを受け取るが、最初のファイルにあって2つ目のファイルには存在しないカウンター名を出力する。

「diffコマンドじゃ駄目なのか?」
という声が聞こえてきそうだが、実は駄目だ。diffは厳密な差分を作るわけではない。あまりにも複雑な差分が出てくると、その近辺をまとめて「えいやっ」と全部違うことにしてしまう。パッチを作るのには便利だが、本当の意味で差分を知りたいときには役に立たないのだ。




おっとっと。sort.pl の出力例を示そう。

"\System\Threads"
# "-0.22995779821056035196" "0.05288058895784879381" "-0.07730117409966560384" "143.68969576542572045539"
# "-0.51157343991699204758" "0.26170738442850427247" "-0.28398973957007304341" "268.04879224402808287292"
# "-0.54019071369820630440" "0.29180600716577749228" "-0.44072471855335868898" "364.09672304650726120687"
# "-0.55452955075971981685" "0.30750302266577667691" "-0.35677693634035859957" "315.68199698065233504727"
# "-0.56238435856552132237" "0.31627616675915285595" "-0.25723384667083141975" "251.10319887283403001070"
"\System\System Up Time"
# "-0.01694272285973713476" "0.00028705585790185927" "-0.00002142521429336236" "319.75744872321046887814"
# "-0.10027028487321032493" "0.01005413002855475131" "-0.00006496869460687431" "814.02214841113016417319"
# "-0.15561543326229096847" "0.02421616306941053433" "-0.00009270518792943096" "1140.66520449120347153620"
# "0.02950515281233018273" "0.00087055404247895569" "0.00002478604557354800" "-190.27570068419384733538"
# "0.64118189188208415717" "0.41111421847748865761" "0.00006133456719050028" "-615.26230486597317302122"
"\System\System Calls/sec"
# "-0.18729246211596788708" "0.03507846636546126618" "-0.00055434531116103602" "100.21166379708057100480"
# "-0.29232961498316379384" "0.08545660379620478167" "-0.00111680437443534113" "93.05619900302319881495"
# "-0.34131479803199158732" "0.11649579135561920833" "-0.00090462856546019161" "90.75926531940870958778"
# "-0.34750948339695522578" "0.12076284105081869973" "-0.00149413414952154013" "87.55393220941927354234"
# "-0.51114894911397353620" "0.26127324818031950750" "-0.00296996323726849211" "104.08031976970305210654"


# で始まっている行はコメントだ。この行はデバッグ用に各カウンターから算出されるr, r2, a, b の4つの値を記録しているだけで、この段階では何の意味も無い。これは処理の前に grep -v で消してしまおう。


% cd $TOP
% cd $TOP/06rmComment
% cat filter.sh
#!/bin/sh

for i in ../05sort/*.{HI,BORDER,LOW}; do
o=`echo $i | sed 's/\.\.\/05sort\///g'`
echo $o
egrep -v '^#' $i | sort | uniq > $o
done
% ./filter.sh

sort はデバッグしやすくするためだが(アルファベット順に並んでいると間違ってるかどうか探しやすい)、uniq は「ついカッとなってやった」の類だ。無くても構わない。




では。まず2つのファイルに共通しているカウンター名を引っ張り出すスクリプト。

common.pl

#! /usr/bin/perl

# common.pl
# read and , line by line.
# if common lines were found regardless of it's order, output it to STDOUT.

$inAfn = $ARGV[0];
$inBfn = $ARGV[1];

open( INA, $inAfn ) or die "can't open file $inAfn as read\n";
open( INB, $inBfn ) or die "can't open file $inBfn as read\n";

while () {
chomp;
push @inAline, ( $_ );
}

while () {
chomp;
push @inBline, ( $_ );
}

close INA;
close INB;


while ( $line = pop @inAline ) {
# find same line in @inBline;
for ( $i = 0; $i <= $#inBline; $i++ ) {
if ( $inBline[$i] eq $line ) {
print "$line\n";
}
}
}

えぇ、自分で言うのもなんだが、すげぇ馬鹿コードである。共通要素を見つけた後、next で次に行かないのもどうだかと思うし、inBline から見つかった要素を消さないのもどうだかと思う。

次は片一方にしかないカウンターを見つけるスクリプト。

onlyFirst.pl

#! /usr/bin/perl

# onlyFirst.pl
# read and , line by line.
# if line from does not exist in line from then print that to STDOUT.

$inAfn = $ARGV[0];
$inBfn = $ARGV[1];

open( INA, $inAfn ) or die "can't open file $inAfn as read\n";
open( INB, $inBfn ) or die "can't open file $inBfn as read\n";

while () {
chomp;
push @inAline, ( $_ );
}

while () {
chomp;
push @inBline, ( $_ );
}

close INA;
close INB;

A_line:

while ( $line = pop @inAline ) {
# find same line in @inBline;
for ( $i = 0; $i <= $#inBline; $i++ ) {
if ( $inBline[$i] eq $line ) {
next A_line;
}
}
print "$line\n";
}

ふ。負けず劣らずこちらも馬鹿コードである orz




% cd $TOP
% cd $TOP/07common
% cat filter.sh
##############################################
# re-classify into matrix
#
# B \ A | | | |
# \ | HIGH | BORDER | LOW |
#------------+------+--------+-----+
# HIGH | HH | HB | HL |
#------------+------+--------+-----+
# BORDER | BH | BB | BL |
#------------+------+--------+-----+
# LOW | LH | LB | LL |
#------------+------+--------+-----+

./common.pl ../06rmComment/A.HI ../06rmComment/B.HI > HH
./common.pl ../06rmComment/A.HI ../06rmComment/B.BORDER > BH
./common.pl ../06rmComment/A.HI ../06rmComment/B.LOW > LH

./common.pl ../06rmComment/A.BORDER ../06rmComment/B.HI > HB
./common.pl ../06rmComment/A.BORDER ../06rmComment/B.BORDER > BB
./common.pl ../06rmComment/A.BORDER ../06rmComment/B.LOW > LB

./common.pl ../06rmComment/A.LOW ../06rmComment/B.HI > HL
./common.pl ../06rmComment/A.LOW ../06rmComment/B.BORDER > BL
./common.pl ../06rmComment/A.LOW ../06rmComment/B.LOW > LL

for i in HI BORDER LOW; do
./onlyFirst.pl ../06rmComment/A.$i ../06rmComment/B.HI > ./tmp1
./onlyFirst.pl ./tmp1 ../06rmComment/B.BORDER > ./tmp2
./onlyFirst.pl ./tmp2 ../06rmComment/B.LOW > ./onlyA.$i
done

for i in HI BORDER LOW; do
./onlyFirst.pl ../06rmComment/B.$i ../06rmComment/A.HI > ./tmp1
./onlyFirst.pl ./tmp1 ../06rmComment/A.BORDER > ./tmp2
./onlyFirst.pl ./tmp2 ../06rmComment/A.LOW > ./onlyB.$i
done

% ./filter.sh


C,Dの処理は省略した。

はっきり言ってこれでもかと言うぐらいの力押しスクリプトだ。よい子はまねをしてはいけない(ぇ…)。



というわけで、これで機械的に出来る分類は終わった。
ココから先は、人間の推理力がモノを言う。

実際、ここにある perl のスクリプトはほぼそのまま私が使っているスクリプトだ。シェルスクリプトの方は時々に応じて変更しているのでこれこのままではないが。で、今まで発見できなかった要因をいろいろ見つけることが出来ている。

性能障害問題で悩んでいるなら、きっと役に立つと思う。少なくとも同じ考え方は使えるはずだ。

2008年8月24日

AとBの邂逅

ここまでは、各マシン毎の分類だった。ここからはマシンごとの特徴を見た上での分類が必要になる。要点としては図1のように分類する事になる。

 A only HIA only BORDERA only LOW
Aマシンのカウンター
B only HIBマシンのカウンター(A,B)=(HI,HI)(A,B)=(BORDER,HI)(A,B)=(LOW,HI)
B only BORDER(A,B)=(HI,BORDER)(A,B)=(BORDER,BORDER)(A,B)=(LOW,BORDER)
B only LOW(A,B)=(HI,LOW)(A,B)=(BORDER,LOW)(A,B)=(LOW,LOW)
図1. AとBの分類


まず最も判りやすいところから説明しよう。中央の紫色の3x3=9枡目は、AとBの両方で存在した(NaNによる除去を免れた)カウンターだ。A, B それぞれにおいて、どう分類されていたのか、に応じて3x3通りが存在する。

薄い黄色で塗られた3つの枡目、「A only xxxx」とあるのは『Aには存在したがBには存在しなかった』カウンターを現す。同様に「B only xxxx」とある水色の3つの升目は『Bには存在したが、Aには存在しなかった』カウンターを現す。

生き残ったカウンターは以上15個の升目のどこかに必ず入る。まずこの分類を行う。

さて、これらの升目の内、重要視するのは図2で示した6枡である。


 A only HIA only BORDERA only LOW
Aマシンのカウンター
B only HIBマシンのカウンター(A,B)=(HI,HI)(A,B)=(BORDER,HI)(A,B)=(LOW,HI)
B only BORDER(A,B)=(HI,BORDER)(A,B)=(BORDER,BORDER)(A,B)=(LOW,BORDER)
B only LOW(A,B)=(HI,LOW)(A,B)=(BORDER,LOW)(A,B)=(LOW,LOW)
図2. 重要視するポイント


症状はAでは発生しているが、Bでは発生していない。そして問題が生じているときにはプロセッサが忙しく働いている。ならば、「AのときはIdleと強い相関があり、Bの時にはIdleとの相関が弱い」所に探すべきネタがある。

Aにしか存在しないカウンターの内、相関がLOWのもの以外の2つは、当然検討対象にしなくてはいけない。これは判ると思う。逆にBにしか存在しないカウンターは無視して構わない。

A,Bともに存在したカウンターの内、Aにおいて相関がLOWだったものは、この場合検討対象から外してよい。

Bにおいて相関がHIだったものも、この場合検討から外してよいはずだ。AもHI,BもHIならそれは「いつでも相関が高いもの」…例えば、プロセッサ消費量の内の User の割合など…であることが考えられる。また、AがHIで、BがHIではないのでは明らかに今回探している対象から外れるのは自明だ。

残った6枡の内、A,Bともに BORDERなものは特別扱いが必要になる。BORDERにあるのは計測すると相関が高かったり高く無かったりしたものだ。つまり「AもBも、相関が高いんだか低いんだかよく判らん」ものだったりする。この場合、各カウンターの内容を調べて、個別に判断する必要が出る。しかし、逆に言うとここは手間がかかるところなので、それ以外の部分で何か見つかった場合は無視して構わない、ともいえる。

と言うわけで、残り5枡を最優先で調べるべし、と言うことになる。

2008年8月16日

sort.pl の出力

先に進む前に sort.pl の出力についてもう少し説明する。

sort.pl が入力として受け付ける(前提としている)のは、calcr2.pl の出力を複数 cat でつないだもの。今回は sort もかけることで同じカウンターが近接するようにしてあるが、本質的には sort の必要は無い。結果として、このような内容が延々続くファイルになる:


"\LogicalDisk(C:)\% Disk Read Time" "-0.04062578806352645403" "0.00165045465578256851" "-0.12770872885354865610" "90.45804378385737658023"
"\LogicalDisk(C:)\% Disk Read Time" "-0.04406606083496136481" "0.00194181771751051590" "-0.17957809895894711362" "90.36202077972433047033"
"\LogicalDisk(C:)\% Disk Read Time" "-0.10162240553099880448" "0.01032711330590677641" "-0.25960115664153218127" "91.91528872471089858070"
"\LogicalDisk(C:)\% Disk Read Time" "-0.10606592840069039460" "0.01124998116750038125" "-0.50117255489344281550" "89.78700245921672272973"
"\LogicalDisk(C:)\% Disk Read Time" "-0.63225077753384162361" "0.39974104569214729193" "-0.98409431769226710436" "99.62442055641675669955"
"\LogicalDisk(C:)\% Disk Time" "-0.04336533750022928025" "0.00188055249650879188" "-0.11305679326692022027" "90.53746144831214471477"
:


r2の値を使ってこれらをソートしていくわけだが、全ての計測結果においてr2が同じ性質を持つわけではない。実はここでは4種類に分類している。出力しているファイルは3種類だが、実際には分類は4種類あるのだ。

そこで、まず個々のr2の値はどのような値をとりえるのか、考えて見よう。

r2のとる値


すでに述べたが、r2は0.0から1.0までの間の値を取る。正確には計算できる場合は、それらの間の値をとる。そう。計算できない場合、と言うのがあるのだ。

指定したカウンターに値が全く記録されていない場合がありえる。この場合、データが全くないので、回帰直線も引けない。つまり y=ax+b という形のaとbも求められない。rの値は a と b がないと計算できないのでrも求められないし、その二乗値も求められない。
この場合、r, r2, a, b は全て Not a Number (NaN) となる。

rやr2が NaN になるケースがもう一つある。a が 0.0 になった場合だ。厳密には一定の誤差の範囲内であれば NaN になってしまう。rの計算式には a による除算が含まれているのだが、ここで 0割り(0を分母とする分数の値を計算しようとした時に生じるエラー)が起こるのだ。この場合、r, r2は NaN になるが、a は 0.0 になるし、bはどんな値になるかはデータ依存だ。

以上の2つのケース以外の場合、rの値は 0.0 から 1.0 の間の値を取る。厳密には、計算誤差のせいで 1.0 を超える数字が出たり、0.0を下回る数字が出たりすることもあるが、あくまでも誤差の範囲、と捉えてもらって大丈夫だ。

r2の値による分類


さて、今回、sort.pl でカウンターを分類するにあたって次のような規則を適用した。


1) 同じカウンターに属する、全てのr2の値が NaN ならば、そのカウンターは記録しない。

データが一切ないのであれば、そのカウンターは考慮に値しない。

データがあるが a が 0.0 になる、と言うことは Processor Idle の値に全く影響を受けてない/影響を与えていない、と言うことだ。今回は影響のあるものを探しているのだから、そのカウンターについて、以降考慮する必要は無い。
Process ID のように変わるはずの無いカウンターが該当する。

2) 同じカウンターの一部だけが NaN の場合、そのNaNは無視する。

取りあえず残りのデータだけで分析しよう、と言うことだ。

3) 全ての r2が境界値以上だったらHI

4) 全ての r2が境界値未満だったらLOW

5) r2が境界値以上、未満の両方存在したら、BORDER



なので、全てNaNの場合のカウンターがこの段階で消えている。カウンターの総数は分類前と分類後では、分類後の方が少ない可能性がある、ということだ。

2008年8月12日

相関係数によってカウンターを分類する

カウンターごとに相関が求まったので、それを元にカウンターを分類する。

その前に。カウンターにくっついているマシン名がうざったい。

"\\A\Processor(_Total)\% Idle Time" "0.99999999999999558689" ....


というこの「\\A\」がうざったいのだ。と言うのは、後で「マシン同士の」相関を取る必要があるからだ。カウンター名にマシン名が含まれていては「同じカウンター同士」を判別するのが面倒になる。だからこの場で外してしまおう。

そしてついでに、同じマシンに関して、別の日付のものをあわせて1つにしてしまおう。


次に。各TSVファイルを分類する。分類するスクリプトはこれ:

sort.pl
$r2_limitation = 0.25;

open( INFILE, "$ARGV[0]" ) or die "can't open file $ARGV[0] as read\n";
open( OHI, " > $ARGV[1]" ) or die "can't open file $ARGV[1] as write\n";
open( OBO, " > $ARGV[2]" ) or die "can't open file $ARGV[2] as write\n";
open( OLO, " > $ARGV[3]" ) or die "can't open file $ARGV[3] as write\n";

while () {
chomp;
my @cells = split /\t/;
my $i, $n;

for ( $i = 0; $i <= $#cells; $i++ ) {
$cells[$i] =~ s/"(.*)".*$/\1/g;
}

$n = $cells[0];
if ( $n eq "name" ) {
next;
}
if ( $counter{$n} <= 0 ) {
push @name, $n;
}

$i = $counter{$n};
$counter{$n}++;
$r{$n}[$i] = $cells[1];
$r2{$n}[$i] = $cells[2];
$a{$n}[$i] = $cells[3];
$b{$n}[$i] = $cells[4];
}

while ( $n = pop @name ) {
my $allbig = 1;
my $allsmall = 1;
my $findNaN = 0;

for ( $i = 0; $i < $counter{$n}; $i++ ) {
if ( $r2{$n}[$i] < $r2_limitation ) {
$allbig = 0;
}
if ( $r2{$n}[$i] >= $r2_limitation ) {
$allsmall = 0;
}
if ( $r2{$n}[$i] eq "NaN" ) {
$findNaN = 1;
}
}

if (( $allbig )&&( !$allsmall )) {
print OHI "\"$n\"\n";
for ( $i = 0; $i < $counter{$n}; $i++ ) {
print OHI "# \"$r{$n}[$i]\"\t\"$r2{$n}[$i]\"\t\"$a{$n}[$i]\"\t\"$b{$n}[$i]\"\n";
}
}

if (( !$allbig )&&( $allsmall )) {
print OLO "\"$n\"\n";
for ( $i = 0; $i < $counter{$n}; $i++ ) {
print OLO "# \"$r{$n}[$i]\"\t\"$r2{$n}[$i]\"\t\"$a{$n}[$i]\"\t\"$b{$n}[$i]\"\n";
}
}

if (( !$allbig )&&( !$allsmall )) {
print OBO "\"$n\"\n";
for ( $i = 0; $i < $counter{$n}; $i++ ) {
print OBO "# \"$r{$n}[$i]\"\t\"$r2{$n}[$i]\"\t\"$a{$n}[$i]\"\t\"$b{$n}[$i]\"\n";
}
}
if (( $allbig )&&( $allsmall )) {
if ( $findNaN ) {
print STDERR "\"$n\" seems to have NaN as it's r2 value\n";
} else {
die "\"$n\" did not have any element in $ARGV[0]?!\n";
}
}
}


引数は4つ。
1つ目が入力TSVファイル名。
2つ目は $r2_limitation 以上のr2値を持っているカウンターだけを集めたTSVファイルの名前。
4つ目は $r2_limitation 未満のr2値を持っているカウンターだけを集めたTSVファイルの名前。
3つ目は r2の値が $r2_limitation 以上だったり以下だったりふらつくものを集めたTSVファイルの名前。

とりあえず $r2_limitation はSTATISTICS HACKの推奨にあわせて「強い相関」の値0.25に設定してあります。

% cd $TOP
% cd $TOP/05sort
% cat filter.sh
#!/bin/sh

onebefore="../04Colleration";
for i in A B C D; do
cat $onebefore/$i.*.tsv | sed -e 's/^"\\\\[[:upper:][:digit:]]\+\\/"\\/g' | sort > $i.lst
done

for i in A B C D; do
./sort.pl $i.lst $i.HI $i.BORDER $i.LOW
done
% bash filter.sh


これで A.HI, A.BORDER, A.LOW や B.HI, B.BORDER, B.LOW ができた。

一番計算機パワーを食うところはこれでおしまい。ここから先は人間が悩むしかない…。

2008年8月11日

じゃぁ、相関とかを求めるかね。

全部のマシン、全部の日付、全部のエントリについて、"Processor(_Total)\% Idle Time" との相関 r ならびに r2, 回帰式 y=ax+b にマップしたときの a, b を求めよう。あ、x 側が"Processor(_Total)\% Idle Time"で、yが「相関を求めるべき他のエントリ」な。

Perlにはこの手の統計処理用のモジュールが結構ある。どれを使うか迷う所だが、今回は深く考えずにMath::NumberCruncherを使ってみよう。

もし、cygwinを使っているならば、次の命令を実行し、尋ねてくる質問に真摯に答えればインストールは完了する。
% perl -MCPAN -e 'install Math::NumberCruncher'

Active Perlのときはどうするのか?とかそういう質問の答は判らないのでよろしく。

http://search.cpan.org/~sifukurt/Math-NumberCruncher-5.00/NumberCruncher.pod
に一応説明らしきものがある事になっているが、はっきり言って説明になっていない。2引数を取る場合、どちらかがxでどちらかがy…という問題を解かなきゃいけないはずだが、それもない。強引に超能力をかけることにする。多分、こういうこったろう。

$correlation = Math::NumberCruncher::Correlation(\@yarray,\@xarray);

($slope,$y_intercept ) = Math::NumberCruncher::BestFit(\@yarray,\@xarray);


ここで、$correlation は「相関係数」つまり、今まで言っていた r の事だ。$slope (傾き)と $y_intercept (y切片) は、それぞれ a と b になる。r2を直接求める関数はないので、$r2=$r*$r; で求める事になる。




入力TSVファイルは全部次のようなフォーマットになっている。
"(PDH-TSV 4.0) (Tokyo Standard Time)(-540)" "\\A\Processor(_Total)\% Idle Time" "\\A\LogicalDisk(C:)\% Disk Read Time" ........
"07/15/2008 07:59:59.810" "0.079295186091091777" "0.00050253600663232288" .......
"07/15/2008 08:00:59.809" "98.125628004019234" "0.10616734613768194" .......
........


第一行がラベルで、各ラベルは ダブルクォート(") で囲まれている。さらに、それらはタブで分割されている。第2行以降は測定結果だ。

各行の最初は「測定時刻」だ。従って、相関を求めるべき一方の「Idle」は2つ目の要素になる。

ダブルクォートの中にはタブはないので、とりあえずタブで要素を分割すればいいだろう。その後、ダブルクォートを各要素から取り除けばよい。これを2次元配列にぶちこんだあと、2つ目の要素列と3つ目以降の各要素列との相関を求める。




各要素の出力は次のような形とする。
"name" "r" "r2" "slope" "y intercept"
"\\A\Processor(_Total)\% Idle Time" "0.99999999999999558689" "0.99999999999999117378" "0.99999999999995984122" "0.00000000000341678664"
"\\A\LogicalDisk(C:)\% Disk Read Time" "-0.08658618963563029212" "0.00749716823561733062" "-0.36956562874045379176" "85.25898260145136281611"
.......

第1行は各列のラベルだ。で、2行目以降は「相関を取った列のラベル」、相関係数 "r"、rの二乗値 "r2"、傾き "a"、y切片 "b"の順になる。1行毎に相関を取る相手が変わる。

ある TSVファイルから、この出力を求める perl スクリプトは次の通りだ。

calcr2.pl

use Math::NumberCruncher;
$ref = Math::NumberCruncher->new();

my $linenumber = 0;
my $maxcells = 0;

# read data.
while () {
chomp;

my @cells = split /\t/;

if ( $maxcells < $#cells ) {
$maxcells = $#cells;
}

if ( $linenumber == 0 ) {
for ( $i = 0; $i <= $#cells; $i++ ) {
$cells[$i] =~ /^\"(.+)\"/;

my $tmp = $1;
$countername[$i] = $tmp;
}
} elsif ( $linenumber == 1 ) {
# skip this one!
# first taken data is useless.
} else {
for ( $i = 0; $i <= $#cells; $i++ ) {
$cells[$i] =~ /^\"(.+)\"/;
my $tmp = $1;

# $linenumber == 2 got to be $index == 0.
my $index = $linenumber - 2;

$num[$i][$index] = $tmp;
}
}

$linenumber++;
}

# output the result
print "\"name\"\t\"r\"\t\"r2\"\t\"slope\"\t\"y intercept\"\n";

for ( $i = 1; $i <= $maxcells; $i++ ) {

$xname = $countername[1];
$yname = $countername[$i];
@xarray = @{$num[1]};
@yarray = @{$num[$i]};

$r = Math::NumberCruncher::Correlation( \@yarray, \@xarray );
($a, $b)
= Math::NumberCruncher::BestFit( \@yarray, \@xarray );
$r2 = $r * $r;

print "\"$yname\"\t\"$r\"\t\"$r2\"\t\"$a\"\t\"$b\"\n";
}


いくつかポイントがある。

入力は標準入力。出力は標準出力だ。

データ行になって最初の行はわざと捨てている。これは、この手の記録の多くが「前回取得したデータとの差分」から求められる事が多いからだ。1つ前のデータがない、最初の一手は往々にして間違ったデータである事が多い。故にそれは取り除く。

@xarray, @yarray をコピーしているが、これは単に「配列の配列」から「配列(2つ目の方)」を持ってくる方法を完全に失念していたためだ。うまく動かない…と七転八倒するためにコピーをとったのに過ぎない。多分、ここには無駄があり、この無駄を省けば結構速くなるんじゃないかな、と思う。

こいつを、すでに作ってあるTSVファイルに対して適用する。ただし、出力結果もTSV。ややこしい事おびただしいが、作ったときは深く考えてなかった。カっとなってやった。今では反省している。

% cd $TOP
% cd $TOP/04Colleration
% cat filter.sh
for i in ../03TSV/*.tsv; do
of=`echo $i | sed 's/\.\.\/03TSV\///g'`;
echo $of
cat $i | ./calcr2.pl > $of
done


私の環境では12時間ほどかかりました。もっとメモリとプロセッサパワーが欲しいです。

2008年8月4日

一覧の出現順序をいじったら…TSV化だっ

一覧から
\\A\Processor(_Total)\% Idle Time

とかを切り出して、一番最初に出てくるようにする。

% cd $TOP
% cd $TOP/02LST
% cat filter.sh
for i in A B C D; do
cat ../01PQRlst/$i* | fgrep 'Processor(_Total)\% Idle Time' | sort | uniq > ./$i.lst
cat ../01PQRlst/$i* | fgrep -v 'Processor(_Total)\% Idle Time' | sort | uniq >> ./$i.other
done
% bash filter.sh

大事なのは Sort を掛けてある事と、各マシンについて日付をまたいでリストをマージしている事。

Sortをかけているのは、リストのエントリが「大雑把に何\細かく言うと何」という形式に従っているから、と言うのが一つ。似た項目が集まるように。もう一つは uniq をかけるため。




さて、とりあえずここまできたら、blg ファイルの中身を TSVファイルに変換しよう。
先ほど作った A.lst, B.lst を relog.exe に適用すれば、そこで指定した順番でカウンターが出力される。

% cd $TOP
% cd $TOP/03TSV
% cat filter.sh
for i in A B C D; do
for j in $TOP/native_blg/$i*.blg; do
outfile=`echo $j | sed -e 's/^.*\//g' -e 's/\.blg$/.tsv/g'`
relog.exe $j -f TSV -cf $TOP/02LST/$i.lst -o $outfile;
done
done
% bash filter.sh


これで $TOP/03TSV/ 下に欲しい順序で、各 blg ファイルの中身が TSV の形式で格納されたわけだ。ただし、3500列 480行もあるファイルが4個 x サーバ4種類の合計16個もあり、このTSVファイルを Excel に食わせようとすると、Excel側がギブアップするってぐらいのおチャメさんなファイルになったわけだが…

2008年8月3日

まずは一覧

どこか適当なディレクトリを $TOP と定義する。

$TOP/native_blg/

ディレクトリ下に、blgファイルが全部置いてある、としよう。そして、cygwin が「全部インストール」してあると仮定しよう。bash も使い放題だ。Perl もCPANモジュールが適宜インストールできる、とする。

% ls $TOP/native_blg/
A_Jul15.blg
A_Jul16.blg
A_Jul17.blg
A_Jul18.blg
B_Jul15.blg
B_Jul16.blg
B_Jul17.blg
B_Jul18.blg
:

[マシン名]_日付.blg というファイル名フォーマットらしい。

まず、最初にするべきなのは、各 blg ファイルに含まれているエントリを全部引き出す事だ。Printer情報だのProcess情報だのと、結構それぞれ異なっているはずなので、一覧を取り出して、不要なものをある程度削らなくてはいけないし、Excelに食わせられるように200個ぐらいづつに切り分けるための一覧表が必要になる。

relog.exe というプログラムが .blg ファイルを CSV や TSV (Tab Separated Values)フォーマットに変換してくれる。 これには -q というオプションがあって、このカウンタの一覧を引っ張り出してくれる:

% relog A_Jul15.blg -q -o A_Jul15.lst
% cat A_Jul15.lst
\\A\LogicalDisk(C:)\Avg. Disk Bytes/Write
\\A\LogicalDisk(E:)\Avg. Disk Bytes/Write
\\A\LogicalDisk(F:)\Avg. Disk Bytes/Write
\\A\LogicalDisk(_Total)\Avg. Disk Bytes/Write
\\A\LogicalDisk(C:)\% Idle Time
\\A\LogicalDisk(E:)\% Idle Time
\\A\LogicalDisk(F:)\% Idle Time
\\A\LogicalDisk(_Total)\% Idle Time
\\A\LogicalDisk(C:)\Disk Reads/sec
:


すでに後悔の念バリバリな分量が出てくる。うわ、必要なんだかなんだか判らないものだらけ…。中にこれが見つかるはずだ。

\\A\Processor(_Total)\% Idle Time


これがCPUがIdleになっている割合を示すカウンターだと思われる。\\A\の部分までは「マシンを指定する」ためのものなので、こいつの出力と、その他の出力とのr2を求めればいいわけだ。

とりあえず、全部のファイルについて、このカウンターリストを作る。

% cd $TOP
% mkdir 00nativelist
% pushd 00nativelist
% cat filter.sh
for i in ../native_blg/*.blg; do
j=`echo $i | sed 's/..\/native_blg\///g' | sed 's/\.blg$/.lst/g'`;
relog $i -q -o $j
done
% bash filter.sh
% popd

これで $TOP/00nativelist/ の下に、各 blg ファイルのカウンター一覧ファイルが出来た。今回は Printer Queue は関係なさそうなので、削り落とそう。

% cd $TOP
% mkdir 01PQRlst
% pushd 01PQRlst
% cat filter.sh
for i in ../00nativelst/*.lst; do
j=`echo $i | sed 's/..\/00nativelst\///g'`;
egrep -v '^\\\\\w+\\Print Queue.*\\' $i > $j;
done
% bash filter.sh
% popd


これで、不要な要素をカウンターリストから削る事ができた。

performance monitor の出力に辟易している話

Windowsには Performance Monitor と言うものがある。

システムの評価、できてますか?

身近な定量評価その2 - Windowsのperfmon.exeを使ってみる


なんかを見ると起動の仕方とか、出てくるグラフとかが判ると思う。Unixでいうtopと *stat シリーズを足して貧相なGUIを付け加えたような代物だ。基本的にシステムの異常を監視するときにはよいが、何が悪いのか知ろうというときにはあまり役に立たない

しかし、世界は広いというか物を知らない人は多いと言うか…
「システムの調子が悪いので見てください」
と言って、こいつが吐く .blg ファイルをゴッソリ送りつけてくるやからがいる。
「取りあえず何をとったらいいのか判らないので、全部とりましたから」
とか言いながら。そんな所にはヒントは無いと言うのに。

perfmonは「全部」取ったりすると 3000項目以上データを取得してくれる。1分に1回取得しても8時間分取得すると480回取得するわけだ。これだけのデータを perfmon の貧相なGUIで見て回るのははっきり言って不可能に近い。

このままではどうしようもないので、Excel にでも食わせて見るか…しかし MS-Office 2003 とかを使っていると、これもまた無理、と判る。Excel-2003は「1シート当たり、256列 65536行」しか受け付けないのだ。3000項目 × 480回のデータ取得ではどうあがいてもシートの中に納まりきらない。

そこで、だ。こういう場合にどうするか、と言うのが今回のお題。とは言っても、このままではノーヒント過ぎるのでヒントを1つもらう。

「調子が悪い、と言うのはどうやって判ったの?」
「あー、なんかCPUの利用率が天井に張り付いてるんですよ…」

なるほど。これで戦略は立った。CPUの利用率と相関が高い項目を見つけ出して、そいつらが何なのか調べればいい、と言うわけだ。

「あ、ちなみに。Aっていう場所では起こってるんですが、Bという場所では起こっていないんで…。両方とも perfmon の出力は取ってあります」

ふむ。ならば、AとBでそれぞれについてCPUの利用率との相関を取って、『Aでは相関が高いが、Bでは低いもの』を見つけ出せばいいって事になるな。



現実的には、『CPUの利用率』というのは「ユーザが利用している」場合と「kernelが利用している」場合の2通りがある。どちらが本命か判らない。こういう場合は CPUの非使用率 、つまり CPU Idle との相関を取ると良い。CPU Idle の値が低い場合に多く動くもの、あるいはリソースとして少なくなるものを見つければいい。

そういう時は R2 というものを取ればいい。あぁ、大丈夫。 R2というのは 0.0 から 1.0 の間の値を取り、『相関が高いほど値がでかくなる不思議な数字』とだけ覚えておけばいい。さらに言うと、注目するべきは 0.25 以上の値をとっているもので、なおかつ 1.0 ではないもの(1.0は直接的過ぎて、ちょっと怪しい)。

もっと詳しい事が知りたければこの本を見て欲しい。


R2 という値自体は、Excelの RSQ() という関数で求める事ができる。どうにかしてデータを Excel にぶち込み、各項目と CPU Idle 値との RSQ() 値を求め、その中から 0.25 以上の数字になっている項目を見つけ出せばいいのだ。

.....

そう。そうして問題が元に戻ってくる。perfmon の blg ファイルから、Excelに入る程度の小さなデータセットを作り出す方法、その中に必ず CPU Idle の値を入れておく方法、そしてできれば各項目との RSQ() 指定までは自動的にする方法…

なるべく苦労せず、ステップ バイ ステップで(つまりいつでも後戻りできる形で)実行するにはどうすればいいのか… その苦闘の歴史を綴ろう。

「tcpのいろは」は取りあえずあきらめますた

ちょっち出直しだ。

いや、描かなくちゃいけない図の多さに辟易しているうちに半年も経つとは…

2008年4月20日

tcpdumpのいろは(2)

ひえぇえええ、すごく間が空いてしまった。

さてさて、tcpdumpだがまずはデータを取得しなくてはいけない。そう、tcpdumpの解析は「まずダンプが取れて何ぼ」なのだ。

で、最初に一言重要な事を

tcpdumpが気楽に取れると思うな

一例を挙げよう。1Gbpsのネットワークカードが1枚あって、そいつが通信しているさまを取得したいとする。どうやるのかはともかく、どういう原理かはともかく、それができるとしよう。

すると、1Gbpsなので、全力全開でデータ通信されると、1Gbps…つまり8秒で1Gbyteのデータが取れる計算になる。もちろん、実際はネットワーク利用効率の問題とか、そもそもパケットをキャプチャするソフトがそんなに早く動作するのか、とかいろいろ要因はあってそこまでのデータ増量にはならないのだが、それでも 10-12秒で1Gbyteの量にはなるのだ。

当たり前だが、HDDもその速度に対応しなくてはいけない。PCのバス(PCI-Expressとか xPCIとか)は、NICの流量とHDDの流量の両方を流せるだけの速度が必要になる。同様にメモリだってかなりの容量がないと瞬間風速に耐えられないし、そのメモリはかなり速くなくてはいけない…。なので、普通はEthernet Switchの高いのを間に噛ませて、パケット duplication (パケットを別のポートにもべたコピーで送る機能がある、高いスイッチを使うということだ)した上で、パケットキャプチャ専用マシンを用意する。

ちゃんとしたプロは*データ取得用に Raid0 を組んだり、SSD(Solid State Disk)つまり RamDiskの化け物を用意したりする。そうしないと意味のあるデータが取れないのだ。HDDの速度に引っ張られてNICの送受信速度が変化してしまい、結果としてtcpdumpを取得しなかった場合には起こっていた現象が起こらなくなった…と言うのでは本末転倒だ。
*) 「ちゃんとしたプロは」と言うということは、「ちゃんとしていないプロ」が世の中に満ち溢れていて、全然役に立たないデータを取ってきて「さぁ、見てくれ」と言う馬鹿者が多い事をも意味する。
つまり、こういう特別な環境が無い場合、disk cache がどうにか対処できる時間程度しかパケットキャプチャはできない事を意味する。かなりリッチな環境でも5分取れたら良い方だろう。5分程度、負荷がかなり軽い環境であっても数Gbyteのデータにはなる。

高速なHDD (USB2接続なんか論外だ)を、きちんとデフラグした上で(できればファイルシステムを再フォーマットするのが望ましい)、キャプチャ専用に準備して欲しい。


今回は別件が忙しいので、とりあえずここまでっ!!

2008年2月29日

tcpdumpのいろは(1)

/.Jのokky の日記に書いたようにtcpdumpの基本についてお客様に説明するためにまとめた。結局その資料は使えなかったわけではあるが、まとめたおかげでイヤンなバグを発見する事ができた。

で、そのままだともったいないので、まとめたものについて再度まとめなおしてここに掲載してみる事にした。もしかしたら他の人の役に立つかもしれないし、最低限でも自分の役には立つから (^^;)。同じ資料を作り直す事自体はともかく、構成から考え直すのはしんどいので。それに運がよければ、ここへのポインタだけ張っておけばOKとかいう手抜きができる場合も…。

さて、この話は大きく3つに分ける事ができる。
  1. tcpdumpの物凄く大雑把な基本原理。どうやってパケットはキャプチャされているのか、どういう制限があるのか、等。ようするに基本データが持っている特性を理解するって事ですね。あと、どういう風に取るべきかとかも。
  2. tcpdumpの結果の解析方法。ただし、今は Wireshark というとても賢いソフトがあるので、そいつに押し付けられる部分は説明しません。
  3. multi sessionを利用するプロトコルを解析する上での注意点。まぁ、よく知られている例として FTP なんぞを。多分、読んでいる分には当たり前の話に聞こえると思いますが、たまに忘れるので。


もうすでに出てきたが、Wireshark程度は扱えるようになっていることを前提とする。どうもWindows版のWiresharkにはフィルターロジック周りに微妙なバグがあるんじゃないか…と思うことがあるが…同じロジックを Linux 上の Wireshark に与えたときと結果が違うし…その辺りはあまり深く突っ込むつもりは無い。細かい話は確か何冊か Wireshark の使い方に関する本が出ているので、そちらを参照する事。ただし、内容に関しては保障しない。まだ読んでいないので。

Wiresharkはものすさまじくメモリ(仮想アドレス)を消費する。Windowsの32bit版ではあまり大きなキャプチャファイルの解析はできないだろう。64bit版OS…Linuxとか…が動いている環境を用意し、その上で 64bit版バイナリの Wireshark を利用する事をお勧めする。editcapとかを使って、キャプチャファイルを一旦分割し、tshark を使ってそれぞれにフィルタをかけ、最後に mergecapを使って結合しなおす…というノウハウは説明しない。ただ、この場合も結局テキストコンソールの環境がリッチな Linux の方が便利なので(でなければ、cygwin とかね)、やはりそれ系の環境を整えておく事をお勧めはする。


Ethernetの動作原理だの、ルーティングアルゴリズムだの、そういうことは説明しない。実はパケットをキャプチャする上でこれらの知識は必須なのだが、対象があまりにも広大すぎる上に、殆どの人にとって使う知識はその中のごく一部だから。
ただし、殆どの人が使う共通の項目がある、という意味ではない。AさんとBさんはそれぞれが全体の 0.1%ぐらいしか必要としないが、重なる部分は殆ど無い、と言う意味だ。これは、必要な知識のうち大半が Cisco とその他、WAN と LAN の違い、などに起因するからで、そんな環境を個人で持っている人は、こんなドキュメントは読む必要すらないからだ。

最後に。「これはうちの話じゃないか?!」と思う人がいるかもしれないが、完全に気のせいです。ネットワーク障害と言うのは、はっきりいうとどこでも、ここでも、そこでも同じように起こるもんです。もう一つついでに言うと、機材が分散しているためでしょうか、複数の機器間で設定が破綻して通信がおかしくなる、というケアレスミス・人的ミスはその道のプロのかたがたの環境の方が頻繁に起こるぐらいです。パケット解析を必要とする状況というのはそんなものです。

では、行ってみることにしましょう。

2008年2月17日

キターーーー

きたきたきた、来ましたよ。

久しぶりの大ヒットの予感。NHKが来年受信料を払って欲しいと思うなら、今年の紅白歌合戦にJEROを出すのはもう必須でございましょう。

出せないなら、受信料を必要としなくなるレベルまで、放送を縮小していいから。つーか、教育テレビとニュースだけで十分だ、君らは。2チャンネルも占有する必要なし。ハイビジョンだの何だのと言った研究もする必要なし。結局君達が研究したアナログハイビジョンはゴミでしかない事が世界的に証明されたわけだし。税金ですでに半分以上支払ってるんだから、それだけで十分まかなえる規模になりなさい。

嫌ならこいつを紅白に出すのジャーーーーー。

2008年2月6日

桃を食べよう・辞書を引こう

そう言っていた人がいた。

明文術という本を読んだ。文章を判りやすくするという視点に立って、どう書くべきか、注意点はどこか、間違いやすいのはどういうパターンかをきちんと書いてある優れた本だ。はっきり言って、ここ3年ぐらいに読んだ「文章の書き方」本の中で No.1 だ。

この本が唯一指摘を忘れているのが辞書を引けという一点だ。

文章が下手な人にはいくつも問題点があるが、その中に
単語の意味を判っていない
と言うのがある。わかりやすく書こうと当人は努力しているつもりなのだろうが、そもそも使っている単語の意味を間違えているのでは、意味は伝わらない。それなのに「忙しい」とかそういう屁理屈をつけて、辞書を引かないのだ。お前が忙しいのは辞書を引かず、間違った意味の単語を間違って使っているせいで、お前がこちらの意図を捻じ曲げるからだと、100億年程 滝壺の底に押し込めて説教してやりたいぐらいだ。

最近こんな事例があった。

お客様の所で障害が起こった。お客様は弊社製品の性だと考えたが、tcpdump等の解析結果とswitch の設定は、お客様側のネットワーク設定の不備を示していた。そこで、条件を変えてテストをする事になった。

弊社側の技術者は
再現性のあるテストを行ってください
と繰り返し書いてきた。しかし、弊社の担当官がこれを
テストをして事象を再現させてください
と勝手に書き直していた。判る人は判るだろうが、前者と後者は言っている事が全然違う。

前者はテスト結果として障害が起こった条件と起こらなかった条件を見比べた場合に、何が主要な制御要因か判るようにしてくれ、と言う意味だ。条件の比較によって弊社製品に問題が無い事が示せるならばそれはそれでよい。逆に弊社製品に問題があると判った場合は再現テストを弊社側で行い、製品内部の何が原因なのか突き止めて障害が起こらないようにする方法を見つける事もできる。そのためにも、条件をきちんと記録し、かつその条件をなんどでもリプレイ可能なものにしてくれ、と言っているわけだ。

しかし、後者は「事象が起これば良い」だけだ。なにが原因なのか分析できる必要は無いし、条件を同時に複数変えてもかまわない。これでは、ネットワークの設定が悪かったのか、弊社製品が悪かったのかすら区別できない。このような条件で実験を繰り返しても、ただ時間を無駄に過ごすだけだし、そのための労力はすべてゴミにしかならない。参考情報が無いに等しいからだ。

「再現する」事と「再現性がある」事の違いを理解していないお客様担当が、後者を前者と勘違いして文章を書き換えた事によって、お客様がどれだけの被害をこうむったか…考えるだけでぞっとする。

意味が一意に決まるように文章を書けたとしても、それだけでは明文にはならない。オリジナルの文章があるならば、その文章が何を言っているのかをきちんと理解できなくてはいけないし、使われている単語についても自分勝手な解釈ではなく国語辞典に基づいた意味で解釈し、また記述しなくてはいけない。私文ならばともかく、お客様相手の、技術的な文章に関しては、用語が示す概念の共有を必要とするので
言葉は変化するものだ
などという寝言も却下だ。そういう寝言は正しい意味をきちんと説明できるようになってから言っていただきたい。

国語辞典では私は広辞苑をお勧めする。広辞苑は不正確だ、とかいろいろ言う人がいるが、この場合は全然構わない。そもそも国語辞典のお勧めを聞いている段階がナンセンスだからだ。

国語辞典について「これ」という意見を持っている人は、私に「お勧め」を尋ねたりはしない。お勧めを尋ねるのは、国語辞典をろくに引いた事がない人だ。そういう人は、まず広辞苑の厚みにビビッてもらう必要がある。ここで岩波国語辞典などのより薄くて軽い辞典に移動したら、その段階で論外。この人は内容ではなく「軽さ」と「薄さ」で辞典を選んだからだ。

国語辞典は「自分が知らない言葉」の意味を調べるためにある。あなたがどんな言葉を知らないのか、どうして国語辞典を引く前に判ると言うのか?? そう考えると「日常よく使う xxxx 語を厳選」など…余計なお世話である。その「厳選からもれた」単語が引きたかったらどうしろというのだ?? 2冊目、3冊目としてならばともかく、1冊目の国語辞典は量こそすべてである。この点において広辞苑は合格だ。無駄に分厚く、無駄に単語量が多い。これにビビッてはならないのだ。

あとは、入手しやすさが決定要因だ。広辞苑はほとんどすべての本屋で手に入れる事ができる。ある一軒で入手できなくても3軒以内で確実に手に入る。普段使わない単語の、枝葉末節な部分に間違いがあるなど、入手のしやすさに比べたら誤差だ。

一旦、辞典を手に入れたら、自分が知っていると思っている単語でも引いてみよう。意外と正しい意味を理解していなかった事に気がつくはずだ。その上で、この本に従って分祖hを書いてみよう。時間が掛かるかもしれないから、まずは短いものからで構わない。案外、簡単に書ける上に、その文書を使った仕事はそれまでのような突っかかりが無く、すいすいと進む事に気がつくはずだ。

それは、仕事がなかなか進まないのはあなたの文章が悪かった証拠、である。

2008年1月27日

「4合を午後6時に炊き上がるようにセットしておいて」には Leadership の全てがあるお話 -11- まとめ

まとめよう。

今後、日本は技術立国として立ち行かなくなるだろう。
コンテンツとか研究開発はごく一部の人間にしかできない発想力を必要とするので主力産業とするのは論外だ。となると残るのは「繰り返し経験をつむ事で得られる技術」でしか技術立国化できないが、これに関しては月1万円レベルの給料で働いてくれる人口が20億人もいて、この労働力供給は向こう20年ぐらい衰えそうも無い。と言う事は、日本の「新人技術者」が OJT を積む場は無い、と言う事だ。

そこで、Leader立国と言う発想が出てくる。20億の労働力と戦うのではなく、彼らを指導する立場に建ち、彼らを率いて産業を組み立てていくわけだ(悪い表現を使うと、彼らの上前をはねる、となる)。

しかし、Leadership 教育を今の学校・教師システムに期待する事はできない。昔は四書五経という「Leadershipの教科書」を読み・解説できる者の事を「先生」と呼んでいたが、今の教師は単なるエンジニア開発組織の末端部員に過ぎず、彼ら自身に Leadership に関する意見も何も、持っていないからだ。

と言うわけで、Leadership教育は家庭に任されることになる。ここで、「そんなのどうでもいいわよ」と判断を下すと、子供は Leadership Divide というものに直面する事になる。つまり、Leadership を学んだものは栄え、学ばなかったものは月1万の20億人を賃金のライバルとせざるを得なくなるのだ。

じゃぁ、家庭で Leadership 教育って何をすればいいのさ…実は、単に普通のお手伝いで十分だ、と言う事になる。ただし、ある程度「タスク達成に対する障害物」が無くてはいけないが。
その意味では、一人っ子はよくないかもしれない。「手伝いを邪魔する弟・妹」もいなければ、「手伝いを邪魔してやる兄・姉」もいないからだ。親自身が上手に「障害物」にならないと、効果がまったく無くなってしまう。
重要なのは繰り返す事で信頼関係を築く事。その意味では、お母さんと言う存在の方がこの教育には圧倒的に有利である。と、同時に、Leadership という観点からすれば、

子育てをしていると仕事に不利などというのは真っ赤な間違い

子育てにおいて Leadership について十分経験を積んだ女性は、サラリーマン生活でエンジニア・ノーメンクラーツとしての訓練しか積んでいない野郎どもよりもよほど優秀であり、その経験は大勢の人間を引っ張っていく仕事になればなるほど、有利に働くはずなのだ。

# ちゃんと Leadership を意識せずに子育てをしてきた女性はもちろん不利だろうが、
# それはろくに勉強もしてこなかったサラリーマンが役立たずなのと同じである。

2008年1月24日

「4合を午後6時に炊き上がるようにセットしておいて」には Leadership の全てがあるお話 -10- Leadership Divide

Leadership 教育が均質に行えないどころか、ほとんどの教師が Leadership 教育を行えない。一方で、日本が今後現状の反映を維持するには Leader立国を目指すしかない、というこの状態で無為無策を続けると、Leadership教育を重要視した家庭と、重要視しなかった家庭のどちらで育ったかに依存した機会の不公平が発生する。

これは、ちょうどコンピューターが自由に使える家庭で育ったかどうかでコンピューターに対する扱い能力に差が出て、それがそのまま就職や仕事の効率に影響し、最終的には大きな収入の差に繋がってその次の世代において格差がどんどん広がっていく…という Digital Divide と同じ問題が Leadership 教育に関しても起こる、と言う事だ。

この Leadership 教育の格差を

Leadership Divide

と呼ぶ事にしよう。

Leadership Divide の負け組になると悲惨だ。商売敵は1ヶ月1万円の給料で満足する連中なのだ。遠隔地である事、言語ギャップ(こちらは、Leadership Divide の勝ち組にとって言語教育は重要なキーの一つになるので、徐々に問題にならなくなるだろうが)、成果物の輸送コスト( digital 化された文書などは輸送コストはほとんどかからないが ) などを考慮しても、月3万円以上を要求するのは難しい。一方で、労働基準法があるから…ようするに日本という国からはどんどん仕事が無くなっていくだけ、と言う事だ。

「Leadership Divide の負け組に陥るのを看過するのも親の自由」とは、私は思わない。Leadership 教育は明らかに 教育の義務と権利 の一部として、子供が与えられるべき最低限の教育保障だと思う。とするならば、もう親が直接子供に教えるしかないではないか。

しかも、やるべきことは? と言えば「お手伝いをさせる」だ。どう考えても Digital Divide に対応するために親自身があわててコンピューターを使い始めるのに比べても、何億倍もやさしく、かつ投資もほとんど必要ない。

また、親として子供にお手伝いをさせる、事そのものは、親にとっても自身の Leadership 教育の一環となる。

手伝いの手順、意義などを子供が後に自立的に判断できるように、行う必要があるからだ。つまり、Leader としての親と言うものをきちんと見せる事で、後に子供が Leader になったときの手本・参考にならなくてはいけないため、親にとっても訓練の場となる。

企業などが行う社員教育にも Leadership 関係のものがあるが、上記を念頭に置くと社員教育は単にその企業に勤めている社員だけに行うべきものではなく、社員の家族も含めて行う必要がある、と言う事がわかる。昔、IBMのCEOが Thomas Watson Senior だった頃、これに近い社員教育方針が採られていた。II世になって社員同士のトラブルに巻き込まれるのを恐れ、会社と社員の間に距離を置くようになり、その方針が広く広まるようになったが、もし Leadership に優れた社員を多く必要としているのであれば、企業は社員のみならずその家族との距離ももっと縮める必要がある、と言えよう。

Leadership Divide の負け組になった社員はもちろん、負け組側に社員の子息がいるという状態も、社員の performance に強い悪影響を与える。その状態を回避するのに Leadership 教育が重要で、なおかつそれが社員自身の Leadership 向上にも役に立つのであれば(そして Leadership に優れた社員が多く存在する事を企業が望むのであれば)、社員の家族をも含めた Leadership 教育を推し進めるべきだ。

そして、似たような事は政府と文部省にも言えるが…彼らの場合はどうせ対応が間に合わない事はわかっている。やるべきことは、教育に関する無駄な規制を辞め(教師になるのに教員資格が必要だ、などというのは愚の骨頂だ)、監視役に徹する事だろう。

「4合を午後6時に炊き上がるようにセットしておいて」には Leadership の全てがあるお話 -9- 今の学校の先生にLeadershipは教えられない

今の学校の先生に Leadership が教えられない理由は何か。これを理解するには、江戸時代などの藩校などと比較すれば最も簡単にわかる。

江戸時代、文武両道を旨としていた藩校が「文」として教えていたのは、四書五経の素読と習字である。ところが、四書五経というのはそもそもが
優れた王たるもの、かくあるべし
というリーダーシップ論とそのための背景知識を説明した本だ。それを読み、意味を教えられる先生と言うのは当然、相応の Leadership論と知識の実践に関する一定の意見を持っていた(もちろん、江戸幕府が朱子学という枠を用意していたので、独自性や多様性には一定の枠がはまっていたとは思うが)。

つまりこの当時は、
Leadershipとはなんであるか
を教えられる人の事を先生と呼んでいたのだ


この定義上、当然この頃の先生は Leadership を教える事ができたのだ。

明治時代になっても、この先生Leadership との繋がりは多くの人のイメージにこびりついていたため、この頃までは「指導者として」優れた教師もまだ多かったと思う。

しかし、今の教師の中に 四書五経を読みこなしている者など皆無だろう。

学級崩壊に見られるように、40人程度の子供を導くのも容易ではない有様だ。もちろん、これは親が子供に教師を敬うよう教えないのも原因の一つだろうが、もう一つには Leadership を得るための準備・細かい繰り返しのコンタクトなどに欠けるためでもある。

しかし、さらに言うならば教師になるための教育の中に Leadership に関するものはほとんど無い。どちらかと言うとこれをメインにするべきなぐらいなのに、彼らの職場ではたった一人で40人の子供の相手をし続け、ほとんど指導者が即時指導する、などの OJT もままならない。

じゃぁ、Leadership を教育した教師を育てたらどうなるか。文部省から教育委員会、学校内のヒエラルキーという巨大なピラミッドの底辺部分に当たる教師を Leadership 豊かにしたら、ピラミッドはひっくり返ってしまう。もう一つのピラミッド、日教組など法的な強制力が無いのだから言わずもがなだ。よって、教師は
  • なりたての頃は Leadership について何も知らず
  • なってからも Leadership について何も教わらず
  • Leadership のあるものは排斥される組織構造
の中にいる事になる。これで Leadership について生徒に教えられるような教師が、全国の生徒達に教え得るだけの数存在していたら、それは奇跡と言うものだ。

このように、Leadership に関する限り、学校はまったく持ってあてにならない。それは個々の教師の問題ではなく、教育システムが技術者を大量育成する事に最適化されているからだ。この状態では、Leader を大量生産する教育システムなど絶対に作れない。

江戸時代が終わり、教育システムが変化してもしばらくの間優れた Leadership 教育者が出た事からも判るように、Leadership 教育ができない今のシステムも「今日、この場で」改善を開始したとしても入れ替わるのに40年はかかるだろう。しかるに日本には20年しか執行猶予は無い。

我々は学校・政府に頼っていたのでは間に合わない、という事態に陥っているのだ。

2008年1月21日

「4合を午後6時に炊き上がるようにセットしておいて」には Leadership の全てがあるお話 -8- Leader 立国

20世紀、日本の基本戦略は一貫して技術立国だった。

ペリーが日本に来て、強制的に開国を迫って以来、日本の戦略は一貫して
西洋に脅されない日本を作る
だった。そのために、西洋に匹敵する軍事力を持つ必要がある。軍事力を支える技術力と資金力が必要になる。そこで富国強兵というキーワードでまい進してきた。

これは第2次世界大戦後も本質的には変わっていない。軍事力は所持できなくなったが、その分を金の力でやろうとしているのに過ぎない。そして、そのために
技術立国
というキーワードが使われてきた。

おそらく、今30代以上の年齢の人たちは小学校のときに、次のように教わったのではないだろうか?

「日本には資源がありません。ですので、外国から資源を買い、それを加工して付加価値をつけて外国に売る、という形でお金をもうけ、そのお金で日本で暮らしていく上で必要な食料などを買う必要があるのです」

これはある意味正しいし、このような商売をするためには、優秀な加工技術が低価格で供給される必要があった。日本の義務教育システムは、このような人間を作るのにもってこいのシステムだったわけだ。

しかし、1ドルが360円で初任給が10万円の時代(大雑把に言うと年俸3000ドルの時代)ならば十分太刀打ちできていたかもしれないが、今は1ドルが100円で、初任給は 25万円(大雑把に年俸30000ドル)が日本の水準だ。決して「安い労働力」とはいえない。

一方で、中国には 13億人、インドには10億人、アフリカその他をあわせると35億人の「潜在的労働者」が世界中には存在する。これらの労働市場には「1ヶ月1万円で満足する基本技術労働者」を20億人規模で、20年間供給し続ける能力がある。これらの国々では食料の自給率が高いため、このような賃金でも食べていけるわけだ(日本でこのようなことは実質不可能である)。

技術力の大きな部分を占めているのが、反復訓練による技能向上である。低賃金で労働力を供給できる国に、工業的技術力は絶対移動していく。『高度な技術力』を持つ工員を一人作るには100人規模の工員が同じ仕事をし、99人が敗退していく必要があるので、日本でこのような技術者を育成し続ける事は(国策などで大赤字を大前提にでもしない限り)不可能だろう。

つまり何を言っているかと言うと、向こう20年間の内に、日本から技術力は消え去る、と言う事だ。1億の人間が食っていく戦略として技術立国はもう成り立たない

では何で食っていくか。

その候補の一つが Leadership なのだ。日本には「今は」技術力がある。その技術力を海外の安い労働力に移転し、その過程で彼らの Leader として入り込み、彼らに高い付加価値を作ってもらい、その「上前」で食べていく、と言う事だ。もう少しシビアな表現をするなら、

Leader立国としての日本ぐらいしか

この国が食べていくための方策は残っていない


他の産業は、よほどの才能を必要とするか、価格競争に曝されているか、地理的に狭い領域を相手にしているため「海外からの資源の輸入」という観点からは役に立たないか、どれかになってしまうのだ。

このためには Leadership を持った人材を多く育成する必要がある。
「あぁ、学校教育で Leadership を教えればいいじゃん」

…あいにくとそうは問屋がおろさないのだ。

2008年1月20日

「4合を午後6時に炊き上がるようにセットしておいて」には Leadership の全てがあるお話 -7- これは個人の趣味ではない

一応まとめ。
「4合を午後6時に炊き上がるようにセットしておいて」
というお手伝いをお願いしたお母さん。彼女は実はこのお手伝いを指示する段階で、次の5つの事ができている必要が有る。
1. 子供にでもできるように作業を分割してある
2. 子供を信頼して依頼する
3. 小さな約束をし、守る事で、子供に信頼してもらう
4. 結果に対してフィードバックをかける
5. 子供が依頼を遂行している間、あなたは彼らのそばにいる…も同然
で、これはよく見ると
a. 事前準備
b. 子供との相互信頼の確立
c. フィードバックによる作業改善
というLeaderがなすべき3つの要素がすべて入っている事が判る。この3つの要素がチームを一体化させ、結果として:
仲間からの信頼、
この人に任せれば大丈夫という安心感、
この人に任せてもらえたと言う形でのモチベーションの向上、
この人が言うのだからとグループ全員に同じ方向を向かせる方向性の決定能力
という4つの結果を導き出す。

かくも、「お母さん」という職業は Leadership の訓練に最適であり、故に「主婦業をやっていたから仕事ができない」などというのは大嘘なのだ。主婦業をやっていたからではなく、Leadership について考えていなかったから、であれば納得もいくが、それは普通のサラリーマンでもボーっと日々の作業をこなすだけでまったく向上心を持たなければ、だめだ、と言うのと同じ話でしかない。



と、ここまでだと、

なるほど、そういう見方もあるね。
でも、本質的にはそれは個人の自由ってものではないの?

という意見があるだろう。

で、私も「20世紀中」であればその意見に同意する。が、21世紀はその意見は間違いだ、と言おう。

なぜならば、20世紀、日本は技術立国だった。21世紀は Leader立国 でなくてはいけないからだ。と言うわけで「Leader 立国って何さ」と言う話を次にするので、この話、もう少し続く。

2008年1月15日

「4合を午後6時に炊き上がるようにセットしておいて」には Leadership の全てがあるお話 -6- 子供が依頼を遂行している間、あなたは彼らのそばにいる…も同然

5. 子供が依頼を遂行している間、あなたは彼らのそばにいる…も同然
さて、最後だ。

1-4までの事をすべてきちんと行ったとしよう。特に4の「結果に対してフィードバックをかける」をしっかりと行ったとしよう。その上で、また「ご飯を炊いておいて頂戴」というお願いをしたとする。

基本的に子供は同じような事を同じように行うだろう。
計量し、洗米し、水を張り、炊飯器にセットし、炊飯器をセットし、スイッチを入れる。

問題は、この際の子供の心境だ。特に水を張っている時。

きちんと信頼関係が作られているならば、この子供はおいしいといってもらえるようにするために、水の量を細かく加減するはずだ。もちろん、その結果が成功かどうかはともかく、そのように考えて行動するはずだ。

「ちょっと目を離すとすぐ悪さをして…」

というこの台詞は、子供を評する親からも、部下を評する上司からも聞かれるが、この両者に共通するのは、
目を離している間、(子供|部下)は(親|上司|お客様)の事を失念する
という点だ。しかし、きちんと1-4までを行っていた場合、(子供|部下)は少なくとも手伝いをしている間

・仕事をきっちり仕上げようというモチベーションが出ている
・(親|上司|お客様)がその場で監視していなくても、相手の事を考えて行動している

という2つの条件をクリアしている事になる。


「女性は子供に縛られる」と言う。しかし、このことを見れば、正しくは「子供に縛られる」のではなく、
子供に対する Leadership が取れていない
のだと言う事が判る。Leadershipが取れていないのであれば、子供は暴れ、部下は仕事をしないだろう。そこには何も違いは無い。逆に Leadership が取れていれば、たとえ親自身の目が離れていても、その間にやるべきことを与えれば、コントロールは取れるのだ。

Leadership をとるには 1-4 までのステップが重要であり…と言う事は、定期的に、小さな仕事を頼む(別に小さくなくても本当はいいのだが)事そのものが、Leadership を維持する上で不可欠だ、と言う事が判るだろう。

Leadership をとる事で仕事を頼めるようにする、と言うのは実は一面的な見方でしかない。仕事を頼む事によって Leadership が取れるようになる。


たまに「Leadership を取れるようになったら昇進させてやろう」とバカな事を言う人がいるが、

Leadership を取るには
仕事を頼める立場に立たなくてはいけないのだ


ガソリンエンジンを動かすには最初にスターターが必要なのと同様、Leadership もスターターが必要なのだ。このスターターなしで Leadership を手に入れるのは、ものすごく小さな micro start からはじめる必要がある。

権限を与えずに「Leadership を発揮して成果を出せ」と寝言をいい、その結果が出ないと「部下が無能で」と嘆く人が多いが、そのような人間には一切の同情は無用だ。部下が無能なのではない。権限を与えていないその人が無能なのだから。

2008年1月13日

「4合を午後6時に炊き上がるようにセットしておいて」には Leadership の全てがあるお話 -5- 結果に対してフィードバックをかける

ご飯が炊けたら当然それを食べる事になる。ここで大事なのが:
4. 結果に対してフィードバックをかける
というこれだ。

仕事のフィードバックはとても重要だ。よくできていたならその事を伝えるべきだし、悪いところがあったらそれを指摘しなくてはいけない。そして何よりも、
その仕事をやってくれて感謝している
事を相手に伝えなくてはいけない

これが仕事をしてくれた人たちに、「あぁ、この人のために仕事をして良かった」と言う感想を与え、次の仕事のバネとなってくれるのだ。侮ってはいけない。

と言う訳で、ちゃんと「6時に帰って来た」お母さんはご飯の準備をしながら、
「あ、ちゃんとご飯炊けてる。ありがとうね」

ご飯を食べながら、
「xx ちゃんがご飯を炊いたの。おいしいね。」
「でも、おかあさん、もう少しやわらかい方がいいなぁ。
お水をほんの少しだけ多い目にするといいのよ」

と、延々、次のお手伝いモチベーションを上げるための感謝 & スキルアップのための指導をする必要があるのだ(おかぁさんは大変だねぇ)。


この感謝 & 指導に手を抜いてはならない。手を抜かないと、実は次の回でよいことがあるのだ (^o^)。
と言う訳で、続く。

2008年1月9日

「4合を午後6時に炊き上がるようにセットしておいて」には Leadership の全てがあるお話 -4- 小さな約束をし、守る事で、子供に信頼してもらう

3. 小さな約束をし、守る事で、子供に信頼してもらう
-3- の最後で「あなた自身は相手にとって信用されたい人か?」という問いを入れた。

一般に人間は自分が信用する人から信用されたいし、信用しない人からは信用されたくない。したがって、相手に対する「あなたを信頼しています」というメッセージは、そのままでは諸刃の剣になる。

これは自分の子供が相手であっても同じだ。いくら自分の親であっても、あまりにも嘘ばかりつくのでは信用できない。そのような者から「信頼しています」というメッセージは、嘘八百である可能性があるので、当然これまた信用が置けない。何を裏でたくらんでいるのやら…


という事は。Project Leader はまず信頼されなくてはいけない。でないと、仕事を割り振る事ができないのだ。特に自分が監視し続ける事ができない仕事を頼むには、相手を信頼するだけではなく、相手からも信頼されなくてはいけないのだ。

これが難しい。

実はここで重要になるのが「小さな約束事をして、それを守る事を繰り返す」事。

大きな守るのが難しい約束を1回守ってもあまり信頼度は上がらない。偶然約束が守れた可能性がある、と考えられてしまうのだ。そうではなく、小さな約束事を毎日守ることで、信頼を積み上げ、最終的に大きな信頼を得る。これが重要になる。

まー、実際問題として。たくさんの約束をすればいくつか守りきれないときもあるけれど、小さな約束なら、信頼の失墜量も少ない、というのもあるんだけどね。


この場合、「6時に炊き上がるようにセットする」という事は、「6時頃には帰ってくる」という暗黙の約束がある、という事だ。
「お手伝いを頼むとは、必ずカウンターで暗黙の約束をしている」
のだ。「あなたのその作業を無駄にはしませんよ」という約束を。この約束をきちんと守れば、あなたは信用され、結果としてあなたのメッセージである「あなたを信用していますよ」というメッセージも信用される、というポジティブフィードバックが形成される。

よく、「社員のモチベーションが上がらない」という悩みを持っている会社や部署を見聞きする。しかし、そもそもモチベーションというのは、
  • 自分が興味を持つ事をやる
  • 相手が自分の労に足りる相手である
というどちらか最低限度でも一方、できれば両方が成立しないと上がらないものだ。「社員の」モチベーションが上がらない場合、それは「社員に」問題があるのではなく、ご褒美をちらつかせれば良くなるものでもなく、

社員から信頼されなくなるほど、
社員を裏切り続けた会社側に問題がある

あるいは上司に問題がある場合も、
そのようなものが偉くなれる、という意味において
会社側に問題がある


というこの点をまず絶対前提として受け入れなければ、問題は解決しないのだ。


ちょっと脇にそれたが。これで判ったと思うが、お手伝いはさせたほうが親に対する信頼は増すのだ。Project Leader も小さなお願いをたくさん member に行い、それをきっちり生かす運営をするのが、信頼を増す近道なのだ。

たぶん、自分でやった方が早い、という事は多々あるだろうが、それでは信頼関係が築けない。leader と member の間も、親と子の間も。

「4合を午後6時に炊き上がるようにセットしておいて」には Leadership の全てがあるお話 -3- 子供を信頼して依頼する

2番目のポイントは「子供を信頼して依頼する」だ。

これは必然的にそうならざるを得ない。依頼している自分は、子供が米を磨いでいる間も、炊飯器をセットしている間も家にいないのだ。乱暴な話、子供が何もしなかったとしてもそれを訂正するすべはない。

したがって、このような依頼をする場合は、子供を信頼するしかないのだ。

重要なのは「信頼する事そのもの」ではない。実はこの依頼は子供に
「あなたの事を信頼しているからね」
というメッセージを送っているのだ。子供に対する信頼を態度で示している、と言い換えてもいい。

一般に「信頼している」という言葉は信用されない。しかし、信頼しているという態度は信用される。これは子供に対しても、大人に対しても言える事だ。

ただしこのままだと問題が1点。
あなた自身は相手にとって信用されたい人か?

この問題を解くために、この次のポイントが重要になってくる。

2008年1月6日

「4合を午後6時に炊き上がるようにセットしておいて」には Leadership の全てがあるお話 -2- 子供にでもできるように作業を分割してある

最初の項目は『子供にでもできるように作業を分割してある』だ。正確には、作業を分割しすでに手順を教育してある事になる。

「4合を午後6時に炊き上がるようにセットする」

というこのコマンドを実施するには、最低限でも次の知識が必要だ。

a) 「4合のお米」の計測方法が判っている
b) 4合以上お米の備蓄があり、それがどこにあるか判っている
c) 必要に応じて、お米を洗う方法がわかっている。
「必要に応じて」なのは無洗米かもしれないから。
d) 一緒に入れる水の分量がわかっている
e) お米の炊飯方法がわかっている。
多くの場合、これは炊飯器の操作方法と、タイマーの設定方法がわかっている、ということだ。

しかし、実際にはこれらのほかに次の大きな障害物を考慮しなくてはいけない。

f) 兄弟姉妹の内、年長のものがこれを実施するとする。
すると弟妹がこれを邪魔する行為に出る場合が、大雑把に 1/3 の確率で発生する。
この状態でも危険な状態に陥らず、できればお米が無駄にならないように環境が整えられている

この f の条件はプロジェクトが失敗する要因のうち、予測可能なものでなおかつ発生確率の高いものについて対策を打つ事を意味するが、お母さんという立場はこのことを常に念頭に置かなくてはいけない。

例えば、今回の場合だと、
1) お米の計測を邪魔する
2) 洗米を邪魔する
3) 水を張る段階で邪魔をする
4) 炊飯中に邪魔をする
の4通りの邪魔の仕方が考えられる。台所で真に危険なものは火と刃物だ、という事を考えると、今回「刃物」は使う必要がないので火に注意すればよい事がわかる。手順で言うと 4 だ。ここだけは死守しなくてはいけない。でないと、人死にがでかねない。

このことから、電子炊飯器を使って炊飯するべきであって、ガスの炊飯器や土鍋で炊いたりしてはいけない、ということが判る。ガス式炊飯器は電気式炊飯器に比べて より悪戯に弱い という性質を持っているからだ。

これはさらに本質を考えると、小さい子供が親がいないときに行う悪事は、親がいるときに行う悪事よりも、悪質で被害が拡大しやすい事を意味する。親がいる間は悪事は自分自身に降りかかってくるが、親さえいなければ年長者のせいにしたり、後片付けをそちらに押し付けたりできるなど、
同じリスクでより派手な悪事を行える
からだ。

「4合を午後6時に炊き上がるようにセットしておいて」というこのリクエストを子供に発行するためには、以上のようなポイントをすべて考慮した上で炊飯器を選択し、米びつなどを準備してから、子供にやり方を教えなくてはいけない。また、上の子供が飯ごう炊飯などのやり方を知っており、炊飯器が壊れたからといって、土鍋で炊いておくよう頼んではいけない事を意味する(少なくとも下の子と二人だけで留守番をさせているときには)。


これは、仕事における準備と環境設営と同じ事だ。仕事の場合も、同じようなポイントについて注意しつつ(あぁ、もちろん、小さな子供がどのような悪さをするのかは、気にしなくて良いが)、仕事をするために必要な環境を整える必要がある。そのためには作業内容を分割し(あるいは Engineer に分割してもらい)、注意点を教えてもらい、対策を考慮し(あるいは Engineer に考慮してもらい)、必要なことが揃っている事を確認する必要がある。


Team で仕事をする場合 Leader に期待される事に「準備」がある。お母さんというものは、日々の生活の中でこのように「準備」の大切さに直面し続けているはずなのだ。