InitializeComponent() の前に待っていた「奇妙な儀式」
どうも!海外の片隅で、今日もXAMLと格闘しながらC#コードを書きなぐってるITエンジニアです。専門はWPF、クライアントアプリの設計開発がメインね。
さて、いま日本でバリバリ働いてて、「いつかは海外で!」って思ってるそこのアナタ。たぶん今、めちゃくちゃ勉強してるんじゃない? async/awaitの非同期処理の極意とか、DIコンテナ(Dependency Injection)使った疎結合なアーキテクチャとか、MVVMパターンのベストプラクティスとか。
うん、素晴らしい。その知識、もちろん大事。でもね、海外で働くって決めたなら、一旦その技術書、そっと閉じてみて。
「は?何言ってんの?技術力こそがエンジニアの共通言語だろ?」
そう思ってるでしょ。僕もそうだった。マジで。日本にいた頃は、WPFのUIスレッドを止めないためにTask.Runとawaitを駆使し、複雑な画面間連携はActionデリゲートで華麗にさばき、ガチガチの設計書(Excel方眼紙!)に基づいてピクセル単位でUIを実装することに命を燃やしてた。コードが綺麗で、バグがなくて、納期を守る。それが正義。それがプロのエンジニア。そう信じて疑わなかった。
だからね、海外の会社からオファーをもらって、意気揚々と乗り込んできた初日。僕はもう、やる気満々だったわけ。「OK、最速で開発環境(Visual Studio)立ち上げて、Gitからソース落として、一発デカいプルリク(Pull Request)かましてやるぜ!」って。
PCを受け取って、自分のデスク(フリーアドレスだけど、なんとなく窓際)に陣取って。まずはWindows Update、からのVisual Studio Enterpriseのインストール、ReSharper(これないと生きていけない)のセットアップ…と、まさにInitializeComponent()、つまりは「初期化処理」を爆速で進めてたんだ。
その時だった。隣のデスクに座ってた、見るからに古株っぽいシニアエンジニア、仮に「マイク」としよう。彼が僕の肩をポンと叩いた。
「ヘイ、新人!調子どうだ? ところで、コーヒーでもどう?」
時刻は、朝の9時半。
いやいやいや。調子どうだ、じゃないでしょ。
こっちは今、PCの初期設定っていう、エンジニア人生で最も神聖な儀式の真っ最中なわけ。ネットワークは遅いし、インストールは終わらないし、ぶっちゃけ話しかけてる暇ないんですけど?
日本での僕だったら、間違いなくこう言ってた。「あ、すみません、今ちょっとセットアップが立て込んでまして。キリがいいところでご一緒します!」
これが日本の「デキる」社会人の返答だよね。タスク優先。効率第一。
でも、ここは海外。僕は精一杯の笑顔(たぶん引きつってた)を作って、「あ、はい、ぜひ!」と答えた。内心では(おいおい、大丈夫かこの会社…朝イチで雑談かよ…)って、めちゃくちゃ焦ってた。僕のタスクスケジューラは「今すぐ実行」でパンパンなのに、彼らのスレッドプールは「雑談」タスクで埋め尽くされてる感じ。
マイクに連れられて向かったのは、オフィスのど真ん中にある、やたらとデカい休憩スペース。そこには、スタバ顔負けのバカでかいエスプレッソマシンが鎮座していて、豆の種類もなんか5種類くらいある。そして、ふかふかのソファがいくつも置いてあって、すでに10人近いエンジニアたちがマグカップ片手にたむろしてたんだ。
(マジか…これ全員サボってんのか…?)
僕はもう、気が気じゃなかった。早くデスクに戻ってVisual Studioのインストールを完了させたい。Gitのcloneを始めたい。WPFアプリのあのクソ重い起動画面をなんとかしたい(それはまだ早い)。
彼らの会話に耳を傾けてみた。
「昨日のフットボールの試合見たか?あのフォワード、マジで神だったよな!」
「今週末、湖でカヤックするんだけど、誰か来る?」
「新しく出たスマートウォッチ、あれバッテリー持ちどう思う?」
………。
誰も、仕事の話をしていない。
アーキテクチャの議論も、データベースの正規化の話も、WPFのレンダリングパフォーマンスの改善策も、何一つ出てこない。
マイクが僕にコーヒーを淹れながら(これがまた、豆を挽くところからやるから時間かかるんだ!)、「日本から来たんだって?C#やってるんだ?いいね、俺も昔WPFで苦労したよ。あのXAMLのBinding、時々ワケわかんなくなるよな!」とフレンドリーに話しかけてくる。
僕は「あ、はい、BindingはElementNameよりRelativeSource派です…」とか、しどろもどろに答えるしかない。頭の中は「あと30分もすればインストール終わるかな」「Gitのcredential設定しなきゃ」でいっぱい。
この「コーヒーブレイク」という名の儀式。それは結局、20分以上続いた。
僕の貴重な20分。WAF(Windows Presentation Foundation)のUIロジックをリファクタリングできたかもしれない20分。Actionデリゲートの代わりにeventを使って疎結合にできたかもしれない20分。
デスクに戻った時、僕は心の底から思った。
「なんて非効率な職場なんだ…」と。
日本で鍛え上げられた「効率教」の信者だった僕にとって、この「一見、完全に無駄な雑談タイム」は、理解不能な「奇妙な伝統」以外の何物でもなかった。
でもね。
今だから言える。
この時、僕が「非効率だ」と切り捨てたこの儀式こそが、この会社で生き残るため、いや、むしろ「デキるエンジニア」として認められるための、最重要仕様書であり、僕が最初にパスすべき「入社試験」だったんだ。
技術書に書いてあるasync/awaitの正しい使い方なんかより、WPFのDependencyProperty(依存関係プロパティ)の仕組みなんかより、この「朝9時半のコーヒーブレイク」の作法を学ぶことの方が、100倍重要だった。
この儀式を「無駄な時間」と侮ったせいで、僕はキャリアで最大級の「ヌルリファレンス例外(NullReferenceException)」を踏み抜くことになる。そう、彼らはコードをレビューする前に、「人」をレビューしてたんだ。
まさか、あのどうでもいいフットボールの話が、数週間後の僕のWPFアプリ開発プロジェクトの仕様変更に、直結することになるなんて、この時の僕は知る由もなかったんだよね…。
NullReferenceException: 見えない「信頼」オブジェクトが参照されていません
さて、あの「非効率な儀式」こと、長ったらしいコーヒーブレイク。
初日にそれを体験した僕は、日本人エンジニアの性(さが)として、ある固い決意をした。
「OK、わかった。郷に入っては郷に従えだ。だが、俺はエンジニアだ。まずは実力で黙らせる」と。
僕の戦略はこうだ。
朝のコーヒーブレイクには顔を出す。フットボールの話には「Wow, really?」と相槌を打つ。でも、マグカップが空になった瞬間に「OK, guys, I have to go!(じゃ、俺行かなきゃ!)」と宣言し、誰よりも早くデスクに戻る。そして、誰よりもクリーンで、誰よりもパフォーマンスの高いコードを書きまくる。
これぞ「技術によるゴリ押し」作戦。Actionデリゲートでイベントを繋ぐみたいに、雑談は「顔見せ」というタスクとして処理し、本命のコーディングタスクに全リソース(CPU)を割く。完璧なプランだと思った。
僕に最初に割り当てられたのは、既存のWPFアプリケーションのパフォーマンス改善タスクだった。日本でも散々やってきた、得意分野中の得意分野だ。
起動が遅い。画面遷移がもたつく。リスト表示がカクカクする。
あー、はいはい、わかるよ。
僕はさっそくVisual Studioのプロファイラを起動し、ボトルネックを特定。
「うわ、このリスト、ListBoxをそのまま使ってるじゃん…アイテム数5000超えてるのに。そりゃ遅いわ」
速攻でItemsControlとVirtualizingStackPanelを使った仮想化対応のカスタムコントロールに差し替える。
「なんでUIスレッドでこんな重いデータI/O走らせてんだ…」
async/awaitを導入し、Task.Runでバックグラウンドスレッドに処理を逃がす。当然、処理中はプログレスバーを表示させ、UIがフリーズしないようIProgress<T>で進捗を安全に通知する。これぞWPFのお作法だ。
「この画面間のデータ連携、staticな変数でやってる…最悪だ」
設計(Architecture)としては最悪だけど、今はパフォーマンス改善が優先。とりあえず、無駄なデータコピーが走らないよう、参照渡し(ref)やキャッシュ機構をミニマムに導入。
数日間、僕は文字通り「ゾーン」に入っていた。Slackの通知はオフ。コーヒーブレイクも最短。ランチもデスクでサンドイッチをかじりながらコードを睨む。
そして、金曜の午後。僕は自信作のプルリクエスト(PR)を提出した。
変更ファイル数30。追加コード500行、削除コード300行。プロファイラの結果も添付し、「起動時間を35%改善、リスト表示のメモリ使用量を50%削減」と高らかに宣言した。
(どうだ、マイク。これが日本のエンジニアの実力だ。フットボールの話なんかしてる場合じゃねえんだよ)
僕は、Slackでメンションが飛んでくるのを誇らしい気持ちで待っていた。
…しかし。
待てど暮らせど、PRに「Approved(承認)」の緑のチェックマークがつかない。
月曜の朝。コーヒーブレイク(もちろん参加した)の席で、僕はマイクにそれとなく聞いてみた。
「あの、マイク。先週末に出したPR、時間あるときに見てもらえます?」
マイクは「ああ、見たよ!」と笑顔で言う。
「すごいじゃないか! async/awaitの使い方も完璧だし、VirtualizingStackPanelのアイデアもクールだ。技術的には、まったく問題ない(Technically perfect!)」
(…ん? 「技術的には」?)
その小さな違和感に気づかないフリをして、僕はデスクに戻った。
すると、PRにマイクからのコメントがびっしりと付いていた。
Comment 1:
「ここのリスト表示、確かに速くなったね! でも、ウチの最大のクライアントであるA社のジョーンズさん、彼はいつもこのリストを『全部一気に表示』させて、Ctrl+Fで探すのが好きなんだ。仮想化しちゃうと、まだ表示されてないアイテムは検索に引っかからないよね? 彼は怒ると思うな」
Comment 2:
「UIスレッドからI/Oを分離してくれたのは最高だ。でも、プログレスバーを出すようにしただろ? この画面のメインユーザーであるB社のオペレーターたちは、『処理中に画面が操作できなくなること』を『正常な動作(仕様)』として認識してるんだ。プログレスバーが出て操作できちゃうと、彼らは『バグだ!』って騒ぎ出すよ」
Comment 3:
「static変数のキャッシュ化、わかる。でも、**来月導入予定の新機能(例のフットボール狂のジェフがごり押ししてるやつ)**と、そのキャッシュ、たぶんコンフリクト(競合)するぜ。この話、サラ(別のエンジニア)から聞いてない?」
………は?
僕は、キーボードを打つ手が止まった。
頭が真っ白になった。
ジョーンズさんが? Ctrl+Fで?
オペレーターが? バグだと騒ぐ?
ジェフがごり押ししてる新機能? サラ? 何の話だ?
僕のコードは、C#の文法としても、WPFのベストプラクティスとしても、完璧だったはずだ。
でも、マイクのコメントは、僕が書いたコードの「外側」にある情報ばかりを指摘してくる。
仕様書(Jiraのチケット)には、そんなこと一言も書いてなかった。
僕が「パフォーマンス改善」という名の技術的迷宮に潜り込んでいる間、彼らはコーヒーを飲みながら、
「A社のジョーンズさん、また無茶な使い方しててさー」
「B社のオペレーター、いまだにIE8使ってた頃の癖が抜けないんだよな」
「ジェフのフットボールチームが勝ったから、今週は仕様変更のチャンスだぜ!」
…そんな話をしていたんだ。
僕は、急いでマイクの席に行った。
「マイク、このコメント…本当ですか? 仕様書と違いますけど」
マイクは、不思議そうな顔で僕を見た。
「え? ああ、本当だよ。仕様書? ああ、あれはただの『たたき台』さ。あんなの、書いてるそばから古くなる。本当の仕様は、いつだって『人』が持ってるんだよ」
衝撃だった。
日本での僕の仕事は、Excel方眼紙で描かれた「完璧な設計書」を、1ピクセル、1ロジックたりとも間違えずに「実装」することだった。仕様の矛盾は、実装が始まる前にすべて洗い出すのが「設計」だった。
でも、ここは違った。
仕様は流動的で、テキスト化されておらず、クライアントの「好み」や「機嫌」でさえ、最重要パラメーターになる。
あの朝9時半の「奇妙な儀式」。
あれは、サボりでも雑談でもなかった。
あれは、**テキスト化されていない、生きた仕様書を同期するための「デイリースクラム」**であり、**クライアントの機嫌という名の「環境変数」を読み込むための「コンフィグサーバー」**だったんだ。
僕は、そのミーティングに参加していながら、StreamReaderでストリームを読み飛ばすみたいに、大事な情報を全部聞き流していた。
フットボールの話? 無駄話だ。
カヤックの話? 週末の予定なんてどうでもいい。
…そうやって。
その結果、僕が自信満々で提出したプルリクエストは、技術的には完璧でも、ビジネスの文脈(Context)から見たら、完全に「見当違い」のシロモノになっていた。
C#のコードで言えば、まさにこれだ。
BusinessContext context = null;
context.ApplyMyPerfectCode(); // -> ここでクラッシュ
System.NullReferenceException: オブジェクト参照がオブジェクト インスタンスに設定されていません。
僕は、参照すべき「ビジネス文脈」という名のオブジェクトを、自らnullにしていたんだ。
どんなに優れたasync/awaitの知識も、WPFのDependencyPropertyの深い理解も、この「ヌルリファ」の前では無力だった。
僕は、コードを書く前に、Visual Studioを立ち上げる前に、まず彼らの「雑談」という名の仕様書を、真剣に読み解く必要があった。
マイクが淹れてくれた、あのやたらと時間のかかるエスプレッソを飲みながら。
new Strategy(Context context): 「雑談」をDIしてリファクタリング
さて、System.NullReferenceException。
C#エンジニアにとって、これは最も屈辱的で、最も基本的なバグだ。初期化忘れ。参照漏れ。いわば「うっかりミス」の王様。
僕は、キャリアで最大級の「うっかり」をやらかした。それも、コードの中じゃなく、現実世界(Real World)で。参照すべき「ビジネス文脈(BusinessContext)」オブジェクトを、丸ごとnullのままぶん回そうとしていたんだから。
あのマイクからのPRコメント(という名の仕様変更通知)で真っ白になった僕は、その日、珍しく定時でPCを閉じた。
(どうすりゃいいんだ…)
日本でやってきた「効率教」は、ここでは異端らしい。WPFのBindingエラーをデバッグウィンドウで睨むように、僕は自分のキャリア戦略を見直す必要があった。
技術書を読んでも答えは載ってない。
じゃあ、どうするか?
答えは、僕がずっと「非効率」と見下していた、あの場所にしかなかった。
そう、オフィスのど真ん中にある、エスプレッソマシンの前だ。
僕は、腹を括った。
「郷に入っては郷に従え」なんていう消極的な姿勢じゃない。
「郷(=この職場の文化)を、俺のC#スキルでハックしてやる」と決めた。
翌朝。
僕は、Visual Studioより先に、エスプレッソマシンを起動した。
そして、マイクやジェフ(例のフットボール狂)たちが集まってくるのを、カプチーノ(淹れるのが一番時間がかかる)を作りながら待った。
僕の戦略は変わった。
以前の僕は「技術によるゴリ押し」だった。
新しい僕は、「DI(Dependency Injection:依存性の注入)」戦略だ。
僕というエンジニア(MyEngineerClass)は、外部の「文脈(IContext)」に依存している。その事実にようやく気づいたんだ。
今までは、そのIContextを自分で勝手にnew GijutsuContext()(技術文脈)とかやって初期化してた。だからダメだった。
これからは、外部(=あの雑談)から、正しいBusinessContextを「注入」してもらう必要がある。
「よう、新人! 今日はずいぶんゆっくりしてるじゃないか!」
マイクが来た。
「ええ、昨日のPR、色々教えてもらって。いやー、ジョーンズさんの好みとか、全然知らなかったです」
僕は、正直に白旗を上げた。
マイクはニヤリと笑った。
「だろ? あいつは頑固なんだ。WPFのUIなんてどうでもよくて、とにかく『全部のデータに一瞬でアクセスできること』が彼の正義なんだよ」
そこからが、僕の「リファクタリング」の始まりだった。
僕は、あの雑談の輪の中で、ただの相槌マシン「Mr. Wow, Really?」を演じるのをやめた。
C#エンジニアとして培った「分析能力」と「設計スキル」を、フル活用し始めたんだ。
【ケース1:ジェフのフットボール狂という「仕様」】
ジェフが「昨日の試合は最悪だ! あのクソ審判!」と息巻いている。
以前の僕:
(うるせえな…WPFのレンダリングスレッドに集中させろよ…)
現在の僕:
(ふむ。ジェフのチームが負けた。彼はA機能の担当。今日はA機能に関する厄介な仕様変更の依頼(Task)をawaitさせるのはやめよう。たぶんCancelされるかExceptionが飛んでくる)
逆に、ジェフのチームが勝った月曜日。
「おい聞いたか! 昨日の逆転ゴール! マジで神!」
僕はすかさずコーヒーを片手に近づく。
「ジェフ、おめでとう! すごい試合だったね! ところでさ、A機能のことでちょっと相談したいんだけど、あのWPFのグリッドのデザイン、こっちのほうがクールじゃない?」
「おお、いいね! やっちまえ!(Go for it!)」
チョロい。いや、違う。これが「文脈を読んだ」タスクのawaitだ。
【ケース2:B社オペレーターの「愚痴」という「要求」】
サラ(インフラ担当)が「またB社のオペレーターが、DBロックさせた。あいつら、絶対Enterキー連打してる」と愚痴ってる。
以前の僕:
(ユーザーリテラシー低いな…そんなの知らんがな)
現在の僕:
(なるほど。Enterキー連打が「仕様」か。つまり、僕のWKPFアプリ側で、ボタンのClickイベントにdebounce(短期間の連続実行を間引く処理)を仕込む必要があるな。あと、try-catchだけじゃなくて、DBロックを検知したら自動でリトライ(RetryPolicy)する機構もActionデリゲートで共通化して組み込むか…)
これはもう、雑談じゃない。世界で一番リアルタイムな「要求定義ミーティング」だ。
仕様書(Jira)に「Enterキー連打に対応すること」なんて、絶対に書かれない。でも、実装しなきゃいけない。なぜなら、それが「本当の仕様」だから。
僕は、彼らの会話を「解析(Parse)」し始めた。
誰が、どのクライアントの、どの機能に「感情移入」しているか。
誰と誰が、オフィス政治的に「Binding」されているか。
どの機能が、技術的負債という「Exception」を投げたがっているか。
この「文脈のDI」戦略は、僕のコードにも劇的な変化をもたらした。
覚えているだろうか、あの「ヌルリファ」を踏んだPR。
僕は、マイクと、ジェフと、サラと、あの雑談の輪で徹底的に話し合った。
「ジョーンズさんのCtrl+F問題だけど、仮想化は維持したい。代わりに、検索ボックスをWPFウィンドウのトップに常駐させて、そこでの検索はDBに直接asyncで問い合わせる(Task.Run)ってのはどう? これならジョーンズさんもハッピーだし、メモリも食わない」
「オペレーターの『バグだ!』騒ぎは、こうしよう。プログレスバーは出す。でも、設定(config)で『レガシーモード』をオンにしたら、処理中はあえてWPFウィンドウ全体をIsEnabled="False"(操作不能)にする。これで彼らも安心だ」
「ジェフの新機能とのコンフリクト。ジェフ、あんたの機能、どうせフットボールの結果をDBから引っこ抜くだけだろ? 俺のキャッシュ(MemoryCache)とキーが被らないように、プレフィックス(接頭辞)ルール決めようぜ。ついでに、あんたのチームが勝った日だけ、俺のWPFアプリのタイトルバーの色、チームカラーに変えるイースターエッグ仕込んどいてやるよ」
「マジで!? やってくれよ!」
これが、本当の「設計」だった。
日本で僕がやっていたのは、設計書という「インターフェース(interface)」の実装(implement)だけ。
今、僕がやっているのは、「人」という名の不安定な外部要因をどうやって「抽象化(Abstraction)」し、どうやって「カプセル化(Encapsulation)」して、WPEの美しいMVVMパターンに落とし込むか、という真の「アーキテクチャ設計」だ。
あの「非効率な儀式」と馬鹿にしていたコーヒーブレイク。
あれは、InitializeComponent()(初期化)より前に実行すべき、最重要の「コンストラクタ(Constructor)」だったんだ。
そこで必要な依存関係(Dependency)をすべて注入しなきゃ、このクラス(会社)では正しくインスタンス化(=仲間として認識)すらしてもらえない。
僕は、技術力(ハードスキル)を捨てるんじゃない。
技術力を、「人」を理解し、「文脈」をハックするために使うんだ。
WPFのActionデリゲートは、フォームAからフォームBにデータを渡すためだけにあるんじゃない。
エンジニアの僕から、フットボール狂のジェフに「好意」という名の非同期メッセージをPostするために使うんだ。
そうやって、僕は「技術オタクの日本人」から、「文脈が読めるC#エンジニア」へと、自分自身をリファクタリングしていった。
そしてこの戦略が、僕のエンジニア人生で最高傑作と呼べる「ある機能」を生み出すことになる。
IDisposable.Dispose(): 「無駄」をハックしたら、未来が見えた話
さて、そんなこんなで『雑談DI戦略』をマスターした僕。
WPFのBindingよろしく、技術(C#)と人間(Culture)をがっちり双方向バインディング(TwoWay)させたわけだ。もはや僕にとって、あのコーヒーブレイクは「儀式」じゃない。「必須コンポーネント」だ。
Actionデリゲートで「今度ランチどう?」って非同期メッセージを送れば、Callbackで「あのクライアントの裏仕様」が返ってくる。try-catchで「ジェフの機嫌」という名のExceptionを捕捉し、finallyブロックで「まあ、ビールでも飲もう」と必ず処理を完結させる。
もう、僕のコードが「文脈ヌルリファ」でクラッシュすることはなくなった。
そして、この戦略が、僕のエンジニア人生で最高傑作と呼べる「ある機能」を生み出すことになる。
……それは、皮肉なことに、WPFとC#で書いた、たった100行ほどの、一見クソどうでもいいアプリだった。
きっかけは、またあの休憩室だ。
QAチームのリーダー、サラが「あー、今週もリリース前で死ぬわー」って言いながら、エスプレッソを3杯もおかわりしてるのを見た。
その横で、営業チームの連中が「今週は契約ゼロ! やばい!」と青い顔でデカフェを飲んでる。
かと思えば、ジェフが「俺のチームが勝った!」と、フットボールのユニフォームを着たまま(!)カプチーノを淹れている。
僕は、思った。
(……この休憩室、この会社全体の「生きたログ」じゃないか?)
日本にいた頃の僕なら、「うるせえな、集中させろ」で終わりだ。
でも、「文脈DI」を覚えた僕は、そこに「データ」を見た。
僕は、余ってたSurface(WPFアプリを動かすのに最適だ!)に、シンプルなアプリをぶち込んだ。
タイトルは『Coffee-Driven Development (CDD) Index』。
もちろん、ふざけた名前だ。
エスプレッソマシンの横にそいつを置いて、こう告知した。
「みんな、コーヒー淹れる時、自分の『今の気分』をタップしてってくれ! 一番疲れてるチームに、俺が金曜にピザ奢るわ!」
ボタンがいくつかある。
『俺はまだ戦える(Espresso)』
『ちょっと疲れた(Latte)』
『もうダメぽ(Decaf)』
『(ジェフ専用)俺のチーム最強!(Cappuccino)』
みんな、面白がって押してくれる。ジェフは自分のチームが勝つと『俺のチーム最強!』を連打してた(もちろん、例のdebounce処理は完璧に実装済みだ)。
日本だったら、どうだ?
「勤務実態の把握か?」
「そんなことしてないで仕事しろ」
「Excel方眼紙で稟議書出して」
……たぶん、速攻で却下されるやつだ。
でも、僕はこっそり、そのClickイベントのTimestamp(タイムスタンプ)を、プロジェクト名と部署ID(Active Directoryから引っこ抜いた)と一緒に、DBにINSERTしてたんだ。
1ヶ月後。
僕はそのログを、LINQで集計した。
そして、Jiraのバグチケットの起票日、Gitのcommitログ、営業の契約DBとマージしてみた。
……出たんだよ。
明確な、恐ろしいほどの「相関関係」が。
『”もうダメぽ(Decaf)” がQAチームによって押される回数が、月曜の朝に急増すると、その週の金曜に、必ずクリティカルなバグが本番環境で見つかる』
『”ちょっと疲れた(Latte)” が営業チームで押され始め、水曜までに”Espresso”に回復しないと、その週の契約成約率は80%低下する』
なぜか?
QAのサラたちは、バグの予兆を(本能的に)感じ取り、リリース前に週末返上でデバッグしてたんだ。彼らは「疲れた」なんてマネージャーには言わない。言えない。でも、コーヒーマシンには「正直」だったんだ。
営業チームは、週の初めの「勢い(=Espresso)」が失われると、リカバリーが効かないことを、データが示してた。
僕は、このデータを可視化するWPFのダッシュボードを爆速で作って、マネージャー陣に見せた。
「これは…未来予測か?」
そう。
これは、人間の「疲労」や「士気(モラル)」という、世界で最もテキスト化しにくい「仕様」をハックした、**バグと失注の早期警告システム(Early Warning System)**だ。
マネージャーたちは、すぐ動いた。
ダッシュボードでQAチームの”Decaf”が点滅したら、リリース日を延期し、僕ら開発チームをヘルプに回した。
営業チームの”Latte”が続いたら、ベテランがテコ入れに入った。
結果?
クリティカルバグは半減し、営業成績は安定した。
そして、僕の「お遊びアプリ」は、全社で最も重要な「経営ダッシュボード」になった。
僕らはITエンジニアだ。
C#が書ける。WPFでUIが作れる。async/awaitで非同期処理が書ける。
その技術、何のために使う?
コードのパフォーマンスを上げるため? 違う。
設計書通りにモノを作るため? 違う。
僕らの本当の仕事は、「人」が抱える「非効率」や「面倒くさい」や「言えない本音」を、テクノロジーでハックして、解決することだ。
海外で働くっていうのは、その「人」のOSが、Windows日本語版から、Linuxの謎ディストリビューションに変わるようなもんだ。
コマンド(lsとかcd)が全然違う。マニュアル(仕様書)もアテにならない。
だから、まず「manコマンド(雑談)」を打つんだ。
彼らの使い方(カルチャー)を死ぬ気で読むんだ。
あの「奇妙な儀式」と僕がバカにしたコーヒーブレイクは、最高のデバッグコンソールであり、最強のログ収集ツールだった。
これから海外で働こうとしている、そこのアナタへ。
素晴らしいC#のスキル、WPFの知識、持ってるんだろ?
だったら、現地に着いたら、まずVisual Studioを立ち上げるな。
まず、エスプレッソマシンを立ち上げろ。
Actionデリゲートで、まず「Hi, how’s it going?」というイベントをInvoke(発行)しろ。
返ってくるCallback(雑談)こそが、お前が本当に読むべき「仕様書」だ。
アナタが本当にDispose(破棄)すべきは、その技術力じゃない。
「技術さえあればなんとかなる」という、その古いContext(文脈)そのものなんだ。
それが、僕が海外で学んだ、C#コードのどこにも書いてない、最高の人生術だ。

コメント