Kengo's blog

Technical articles about original projects, JVM, Static Analysis and TypeScript.

エコシステムにビルドツールがたくさんあるのは悪いことではない

JavaやNodeJSには多数のビルドツールがあります。ものによってはビルドツールではなくタスクランナーとかワークフローとか名前が付いてるかもしれませんが些細なことです、ここでは以下のようなツールのことをまとめてビルドツールと呼びます:

一方で言語公式のビルドツールを用意している言語もあります。これによってプロジェクトごとに異なる技術を学ぶ必要性が減りますし、一貫性のある開発体験を得ることができます。javac javadoc のような単純なコマンドしか提供しないJavaとは異なる方針を言語として持っていることは明らかでしょう。

では言語のエコシステムにビルドツールがたくさんあることはモダンではなく不便なのでしょうか?そんなことはないだろうというのが自分の考えです。もちろん欠点がないとは言いませんが、以下に私見を述べます:

プロジェクトによってビルドツールに求められる役割は異なるため、きめ細かな選択肢を選べる

例えばプログラマが若干名のプロジェクトでは、コンパイルやテストが一箇所にまとまっていてフットワーク良く改善を回せていけることが望ましいでしょう。複数リポジトリやサブプロジェクトを作る必要性もまだ薄いでしょうし、そこまで統制について考えることもありません。自分なら開発が活発でパフォーマンスも良いGradleを選択することになると思います。

一方で何百人ものプログラマが関与するプロジェクトでは、ビルドツールやワークフローについても統制を考えるケースが出てきます。 mvn test を実行したらテスト実行結果が必ずJUnitのXML形式で target/surefire-reports/TEST-*.xml に吐き出されなければならないとか、Reproducible Buildsに準拠するとか、developブランチにマージしたらSonarQubeを実行せよとか、ビルドするにはJava 8を使わなければならないとか、そういったベースとなる要求をすべてのプロジェクトに守らせることでリポジトリ横断的な品質改善に役立てたりするわけです。

今だとこういった要求もGradleで満たせそうですが、7年くらい前?に自分が似た状況にあったときは、Mavenのparent projectによる制約の中央管理とバージョン管理が非常にマッチしました。DSLがないので自由度が低く、統制側としては考慮すべきことが減るというのもあります。中央管理する以上は各リポジトリの困りごとをきちんと拾い上げる姿勢は必要になりますが、その工数を考慮してもMavenに軍配が上がることはあるでしょう。

ビルドツールの思想に種類があることを学べる

そもそもこうした違いはどこから生じるのでしょうか。モダンな技術を使って開発された新しいビルドツールは常にレガシーなものよりも優れているべきではないのでしょうか?実はそうではなく、むしろ最もレガシーなApache Antと最もモダンなGradleはかなり近い特徴があります。

Apache AntとGradleはタスクを繋いで有向非巡回グラフ(DAG)を作るという発想で作られています。テストはテストケースのコンパイルに依存し、テストケースのコンパイルは実装のコンパイルに依存し、実装のコンパイルはアノテーションを使ったコード生成に依存する……といったタスクの間の依存関係を明示することで、タスクを並列実行したり不要なタスクの準備を省いたりして高速化ができるのです:

graph LR;
  annotation-processing --> compile --> testCompile --> test --> check --> build;
  compile --> jar --> assemble --> build;

特定のタスクだけ実行する・特定のタスクだけ除外するといった操作も簡単に行なえます。プロジェクト固有のタスクや概念を導入することも容易ですが、一方でタスク実行時に必要な入力がすでに生成されているかどうかを管理するため、タスクの入出力を宣言したり、タスクが依存するタスクを明記する必要があります。DAGをメンテナンスする責任をユーザが負い、それを前提にタスクの内部実装を気にせずに済むようになっています。

Mavenはビルドライフサイクルという概念があり、すべてのプロジェクトはこのライフサイクルに従うことを期待されています。ビルドライフサイクルをゼロから作ることも可能ですが、かなり重い作業です。

ビルドライフサイクルにはフェーズが定義されており、このフェーズにプラグインのゴールを紐付けることで、どのようなプロジェクトでも同じビルドライフサイクルで臨んだ結果を得られるようにしています:

graph LR;
  subgraph compile
    compiler:compile
  end
  subgraph test-compile
    compiler:testCompile
  end
  subgraph test
    surefire:test
  end
  subgraph package
    jar:jar
  end
  compile --> test-compile --> test --> package

そのフェーズに入った時点で以前のフェーズはすべて完了していると信じられるため、ゴールの入力がすでに生成されているかを気にする必要は比較的薄いでしょう。フェーズ内で実行する処理に依存関係がある場合、 compiler:compile ゴールがアノテーションプロセッシングとコンパイルの両方を行うように、ひとつのゴールにまとめてしまうことで単純化します。

一方でやはり柔軟性には欠けます。ライフサイクルの一部だけ実行したい場合、例えばテストを再実行してレポートを生成する場合など、必要なプラグインのゴールを特定してそれを直接実行しなければなりません。逆にテスト以外のすべてを実行する場合も、プラグインの実装を理解して -DskipTests オプションを指定するといったことも必要です。依存先のゴールを自動的に推定・実行することもないためゴールの入力が不正になることも多く、昔は「とにかく mvn clean してやりなおす」ということもよくやっていました。おそらく多くのMavenプロジェクトでは、開発時の混乱を避けるためにREADME.mdCONTRIBUTING.mdにこういうときはこうするというコマンド一覧が載っていると思います。

長くなりましたが、すべての状況にマッチするツールが存在しないのは、ツールの根底にある思想によって適した現場がそれぞれ異なるからだと考えられます。これらの思想そのものは20年以上変化していない時代の荒波に揉まれたものですので、一長一短はあれど使い所が合えば価値の高いものだと言えます。ビルドツールの多様性は、それすなわち言語の活用幅の広さだということなのでしょう。

単に歴史が長いのでビルドツールが数多く生まれてきた

特にJavaは言語としての歴史が長いので、多くのビルドツールが作成され検討されてきたという側面はあると思います。例えばApache Antを使っているfb-contribは2005年からあります。当時からJavaのビルドツールが成長せず、Antだけでここまで来れたかというと、ちょっと考えられませんね。最近(と言っても8年前ですが)Java Moduleにネイティブで対応するビルドツールも提案されていたりして、今でも新しい形が模索されています。

それで言うと今はひとつしかビルドツールを備えていない言語も、もしかしたら今後はビルドツールが2つ3つと増えてくるかもしれませんね。どんなニーズにもひとつのツールチェインで応えようとすると収集つかないこともありそうなので。

とはいえ新しいツールに乗り換えたほうがいいこともある

古いビルドツールをずっと使い続けると技術革新の恩恵を得にくいみたいなところはありますので、ビルドツールをモダンなものに変えていく努力はしたほうが良いことはあります。これからも活発に変更を入れていくプロジェクトであれば特に、更新が活発なビルドツールに移行したほうが良いでしょう、私もFindBugsをSpotBugsにforkするときはAntとMavenを使っていたプロジェクトをGradleで書き換えるという経験をしました

異なる思想を持つツールに移行する場合は両方のツールに詳しくないと思わぬところで失敗するなんてこともあるので、一時的に有識者に手伝ってもらうことも検討しましょう。私もビルドツール移行の副業を受け付けております(唐突な宣伝):

youtrust.jp

まとめ

エコシステムにビルドツールがたくさんあることは悪いことではありません。キャッチアップが大変とか、コミュニティの知見が分散してしまうとかはもちろんあるのですが、コミュニティの抱えるプロジェクトの多様性を担保し、歴史あるプロジェクトと新鋭気鋭なプロジェクトとが同居する上でとても重要な貢献をしています。

キャッチアップコストが気になる場合はREADMEを整備するとか情報の多い新しめのツールに乗り換えるとか、自衛策を取ることもできます。最初からビルドツールがひとつだったら払わなくて済むコストでは確かにあるのですが、言語の歴史と実績に思いを馳せていただければと思います。

組織という仕組みで解決することの難しさ、あるいはマネジメントに超人を求めるのは間違っているだろうか

そりゃ間違ってるんだけど、ではどうするべきなのかが見えてないなぁという話です。

事業が大きくなると組織という仕組みの重要性が上がる

同僚が何千人といたメガベンチャーから社員数20数人のスタートアップに転職してから1.5年経ちました。ここまでに自分が貢献した内容にはSREや医療情報技師としてのものも当然あるのですが、マネジメント経験のあるIndividual Contributorという立場から組織の成長や組織における連携について補足や関連情報を提供するということも意外とありました。例えば社内ブログや社内勉強会で触れたものには以下のようなものがあります:

こうした知識や観点を個々人が持つことは、ボトムアップと呼ばれる自発的な行動を支援する意味では大きな意味があります。そして少ない人数で尖った成果を出すことが求められるスタートアップ立ち上げ時には、これで充分でもあると思います。

一方で事業と組織が急成長していくフェーズでは、これでは足りないというのも事実です。もちろん個人の知識や観点を伸ばしていくことは引き続き大切ですが、人数が増えたことによるコミュニケーションの混乱や事業拡大による着眼点の増大についていくためには、底上げ的な施策や目標の明確化、すなわち組織をマネジメントするための動きが必要になります。トップダウンが必要だということではなく、ボトムアップを続けるためには最も情報を多く持つトップがきちんと情報や要求を棚卸しして、従業員に共有し続けなければならないということです。

事業目標の明示と共有に、トップの演説。
燃え尽き症候群対策に、ピープルマネジメント。
従業員の成長支援に、教育とコーチング。
従業員エンゲージメントの向上に、定期的な面談や人事施策などの実施と評価。
従業員の常識を合わせるための、定期的な従業員教育や統制。

このような「組織をマネジメントするための動き」をトップがやっていたら事業成長に時間を使えなくなりますし、専門家を採用して任せようということになります。こうしてスタートアップは組織化され、専門家が進み、より質の高い課題解決をお客様に提供できるようになっていきます。

組織化はチームマネジメントの負担を高める

しかし人事部があればそれでオッケーかというと、そういうことにはなりません。各部署やチームごとに働き方や求められる専門性、扱う情報などは異なりますし、職場に求めるものは個人レベルで異なります。そうした異なるニーズに対して人事部がケアしきることは事実上不可能です。

この問題に対する解決策でよくあるのが、人事部はルールやツールの整備をし、実行の多くをチームマネジメントが担う方式です。つまり部長や課長に相当する中間管理職に対して、その部下への「組織をマネジメントするための動き」を期待する方式です。部長や課長であればそのチームがどのような働き方をしているのか把握していますし、部下それぞれの個性もわかっていますし、面談を通じてコーチングすることもできます。よってチームマネジメントが「組織をマネジメントをする動き」をすることは合理的であり、組織としてスケーラブルな施策であるとも言えます。

しかし待ってください、チームマネジメントにはもともと他の役割を期待していなかったでしょうか。それはプロダクトマネジメントかもしれないですし、プロジェクトマネジメントかもしれないですし、コードレビューや渉外かもしれないですが、とにかくチームを結成してここに代表者を置いた時点で何らかの機能を持たせていたはずです。チームマネジメントはその道の専門家であって、ピープルマネジメントだ従業員エンゲージメントだ統制だとあとから役割を増やすことにはいくつかの問題があります:

  1. その人には「組織をマネジメントするための動き」に対する知識や関心がないかもしれない。チームを率いるものとして組織に全く関心がないということはないかもしれませんが、そんなの人事でやってくれという声を聞くことは珍しくないのでは。
  2. その人の「組織をマネジメントするための動き」を評価してフィードバックすることが難しい。前提の整理やゴール設定を中央管理的にできないからチームマネジメントにお鉢が回ってきているわけで、そのチームマネジメントがきちんとできているかを外部から評価することは意外と難しい。

言い換えるならば、組織化はチームマネジメントに対して多彩な要件をつきつけます。経営者が経営に必要なすべてを担い、スクラムマスターがスクラムの運用に必要なすべてを担うように、組織化はチームマネジメントにチームが機能するために必要な全てを背負わせます。そして事業の成長とともにチームとそのメンバーに対する期待値も高まり、チームマネジメントへの負担も向上します。

これは組織を運営する我々が、チームマネジメントに超人であることを求めていると言えないでしょうか。チームにおける単一障害点(SPOF)であるチームマネジメントにここまで高い負荷をかけることは、組織運営上正しいことなのでしょうか。

求められるのは「組織をマネジメントする動き」の専門家か、それとも「組織をマネジメントするための動き」のコモディティ化か

浮上した課題に対して組織化によって対応したこと自体は、大きな間違いではないと思います。two pizza teamを作ってこれをまとめることで事業と組織を大きくすることは、今やシステム開発におけるベストプラクティスのひとつだと言っていいでしょう。となると「中央管理を諦める」か「分散実施をチームマネジメントによって実現する」のどちらかに課題があると思われます。

ただ中央管理にこだわるのは、事業成長のどこかで破綻するのではないかと考えています。もちろん人事部はミッション・ビジョン・バリュー(MVV)を整理して全従業員が共通言語で話しあい評価しあう組織を志向するべきですし、そのレベルでは中央管理もするべきです。しかし前述のとおり、チームや従業員ごとの個性に対する配慮なしには「組織をマネジメントするための動き」は実現できないため、どこかで破綻するだろうというのが自分の考えです。

よって解決は「分散実施をチームマネジメント以外の仕組みで実現する」になるでしょう。しかし、具体的にはどうすればいいのでしょう?

ひとつのアイデアは組織をマネジメントする動きを提供する専門のチームを作ることです。部下からは専門性(チーム)の上長と、人事的メンタル的な上長を持つ形になります。 これはちょっと難しいかなと思っていて、というのも専門性の上長と人事的メンタル的な上長の間のパワーバランスってどうなるんだろうという。メンター制度によってある程度はメンタルのケアや教育の実施を上長から外すことを実現できている事例は聞くのですが、完全な代替にはなっていなさそうです。

もうひとつのアイデアはチームマネジメントだけではなく従業員全員が「組織をマネジメントする動き」をすることです。上長によるトップダウンではなく、チーム内での相互作用によって組織をマネジメントしていくことです。 これはある意味で理想的なんですが、事業成長において必要な(比較的に)大量の人材を採用するときのハードルとなってしまいます。「組織をマネジメントする動き」には合う合わないもありますし、単純に習熟と時間を必要とするからです。それこそ新卒採用なんて無理じゃねって感じですね。またこの手のアプローチには再現性がまだなさそうだなと思っているということは、「ティール組織わからん、を掘り下げる」にもまとめています。

組織という仕組みで解決することの難しさ、あるいはマネジメントに超人を求めるのは間違っているだろうか

事業拡大における組織化の重要性と、その際にチームマネジメントの負荷向上という問題について書いてきました。組織化は重要だけど組織という「仕組みで解決」する過程でどうしても個人に依存しちゃうねという。正直まだいい解決は見つかっていないと思っていて、チームマネジメントに高い負荷をかける今までのやり方をチームマネジメントの様子を見ながらやっていくのが現実解かなぁと思っています。その点で、人事部が真にやるべきなのはチームマネジメントに対する教育とコーチングなんでしょう。

現職はまだこういう悩みとは無関係なのですが、自分が統制をかけていく側のロールなのでうまいやり方を見つけていきたいんですよね。このへん読むといいよって感じの推薦図書とか講演動画とか、もしあればTwitterやはてブ、本記事へのコメントなどで教えていただけると嬉しいです。

オープンソースソフトウェアのユーザに知っておいてほしいひとつのこと

あけましておめでとうございます。新年早々オープンソースソフトウェア関係でやねうら王さんの記事が流れてきました。同じオープンソースソフトウェアを手掛ける開発者として記載内容の大部分には賛同できないのですが、枝葉は置いといて主幹だと私が思う主張については共感する部分があり、それについて書いてみます。

yaneuraou.yaneu.com

ユーザには無償であること以上に、オープンであることに着目してほしい

さて、そのような経緯でやねうら王はOSSとして公開してきました。やねうら王は、「無償でいいからどうか使ってくれ」ではないのです。まして、「俺はプロ棋士のファンだからプロの先生に使ってもらえたらとても嬉しい」でもないのです。(そういう考えの開発者の方も確かにいらっしゃいます。私はそうではないというだけです。)

繰り返しになりますが、OSSとは、単なる無料のソフトウェア以上の意味を持ちます。

この件については、ちょっとした補助線となるストーリーがあるので紹介します。私が学生だった頃は、この手のソフトウェアをフリーソフトウェアと呼んでいました。例えば当時のフリーソフトウェア配布場所最大手のひとつであるベクターさんでも、オープンソースソフトウェアではなくてフリーソフトウェアという形で説明しています:

www.vector.co.jp

このフリー(Free)には自由という意味を持たせていました。ところがフリーには無償という意味もあり、ソフトウェアの自由を保証すること以上に、無償で手に入るソフトウェアだということが前面に出る使われ方をされるようになります。そりゃそうですよね、命名が良くない。

そこで自由であることを強調するために*1、Free/Libre and Open Source Software(FLOSS)であるとか、単にOpen Source Software(OSS)などと呼ぶようになりました。こうした経緯、すなわち無償ソフトウェア扱いされてきた体験があって、オープンソースソフトウェアを開発・公開している人は「無償ではないんだ」ということを大切にしている人が一定数いらっしゃると私は考えています。

このあたりが気になる方は、詳しいサイトがあるのでこちらの一読をおすすめします:

www.kogures.com

のでオープンソースソフトウェアを使う場合は、無償であることよりも公開されていることや始めやすいことを特徴として捉えていただけると良いかなとは思います。

オープンソースソフトウェアにはだいたい「動作の保証はしないよ」と書いてある

私は、将棋ファンに向けて「将棋ソフトを無料で公開するから是非将棋ファンの皆さん、遊んでください」と考えているような篤志家などではなく、どちらかと言えばOSSの開発にコミットメントしてくれない人たちは、 (引用者略) 有償ならともかく無償ではそういう人たちのサポートをしたくありません。

このあとに書かれているように、大抵のオープンソースソフトウェアはサポートにも手厚い傾向は実際あります。ただすべてのプロジェクトがそうではなく、そうしたプロジェクトはサポートを手厚くすることで貢献のハードルを下げるとかシェアを奪うとかの狙いがあるからそうしている、あるいは成功体験があって無意識にそうしている場合が多いはずです。ですからオープンソースソフトウェア開発者ならユーザを大切にせよというのは、少なくとも違うと思います。

これはオープンソースソフトウェアには必ず含まれている文書にも明記されています。オープンソースソフトウェアはOSSライセンスによって利用者に対してライセンスされますが、このライセンスにはだいたい、以下のような表記を頒布物に含めることを求めています:

このプログラムは有用であることを願って頒布されますが、全くの無保証 です。商業可能性の保証や特定の目的への適合性は、言外に示されたものも含め全く存在しません。詳しくはGNU 一般公衆利用許諾契約書をご覧ください。

GNU 一般公衆利用許諾契約書バージョン2でライセンスされるソフトウェアに同梱される文書


適用される法律または書面での同意によって命じられない限り、本ライセンスに基づいて頒布されるソフトウェアは、明示黙示を問わず、いかなる保証も条件もなしに「現状のまま」頒布されます。

Apache License v2でライセンスされるソフトウェアに同梱される文書


本ソフトウェアは、著作権者およびコントリビューターによって「現状のまま」提供されており、明示黙示を問わず、商業的な使用可能性、および特定の目的に対する適合性に関する暗黙の保証も含め、またそれに限定されない、いかなる保証もありません。

3条項BSDライセンスでライセンスされるソフトウェアに同梱される文書

英語で記載されていることもありますが、内容は一緒です。保証はないので自己責任で使ってくださいということです。オープンソースソフトウェアだけど保証がほしいなという場合は、サポートを提供してくれるベンダーを探すことになるかなと思います。

オープンソースソフトウェアを開発している開発者に求めるのは、間違いではないかもしれませんが機能しないことがあることは念頭に置いていただければと思います。このへんは本当にプロジェクトによる感じです。

配布されている無償ソフトウェアがオープンソースかどうかわからなくても、同梱資料を読めばオッケー

ここまで読んだ方は、なんだオープンソースソフトウェアってなんかめんどくさいんだな、とお考えかもしれません。でも実際ユーザが使うときは、ソフトウェアがオープンソースソフトウェアかどうかなんて気にしていないことがほとんどですよね。そこで、使おうとしているのが"めんどくさい"ソフトウェアであることに気づき、扱いを間違えないためのコツをお教えしましょう。それは、配布物に同梱された資料に目を通すことです。

あなたが入手したソフトウェアには十中八九、READMEとかLICENSEとかNOTICEとか、あるいはライセンス通知やエンドユーザーライセンス契約(EULA)などと名前のついたファイルが同梱されているはずです。インストーラが表示してくれる場合もあるかもしれませんね。

これらのファイルにはソフトウェアを利用する上で何に合意する必要があるか、このソフトウェアを利用するということは何を作者に許諾する必要があるか、などが書かれています。ユーザサポートについてはもちろん、商用利用時の可否についても書かれています。仮にオープンソースソフトウェアではなかったとしても、作者があなたの端末からどのような情報を得るか(!)などが書かれていることもありますので、目を通すに越したことはありません。

本当はオープンソースソフトウェアは決してめんどくさいソフトウェアではなく、ソフトウェアの自由と発展を考えて作られてきた運用であり文化だというのも伝えたいことではありますが、それは別の機会に譲ります。

まとめ

オープンソースソフトウェアのユーザには、とりあえず同梱の資料には目を通しましょうということを知っていただきたいです。そこにはユーザが知るべきこと、作者が伝えたいこと、双方の権利を守るための重要な通知が含まれています。

また無償であることを前面に出すことは、ソフトウェアの自由と発展を考えて作られてきたオープンソースソフトウェアの歴史、あるいは開発者個人の経験から、オープンソースソフトウェア作者にはあまり良い印象がないかもしれません。公開されていることや始めやすいことに感謝し、ブログで紹介するとか感想を伝えるとかの形で貢献(還元)することもご検討いただければと思います。

とはいえオープンソースソフトウェアとひとくくりに議論するには、この世のプロジェクトは多すぎます。つまり、私が書いたことを気にしない、あるいは他のことを大切にしている開発者も多くいるでしょう。ソフトウェアの向こう側にはその作者やメンテナーがいるのだとご理解いただき、その人がどんな人かに関心を持っていただくことが、そのソフトウェアを真の意味で大切にする行為なのかもしれません。

*1:コピーレフトの件もあるけど割愛

はたらく人には自己成長と健康のためにコーチングがおすすめ

人の一生は重荷を負うて遠き道を行くがごとし、とは徳川家康の言葉らしいですね。この記事では人生という旅路を振り返ること無く歩んでしまうと自己成長と健康に良くないので、ちょいちょい振り返りをするといいですよ、そのためにはコーチングというものを知っておくと捗りますよ。という話をします。

エンジニアにとって振り返りというとポストモーテムのイメージがあるかもしれませんが、今回対象にしているのは個人の活動に対する組織的な振り返りのことで、人材育成の文脈でフィードバックと呼ばれるものです。目標管理(MBO-S)とかOKRとかもこれに含まれます。

読み手としてはマネジメントも想定しますが、どちらかと言えば新社会人ないし組織運営の観点を補強したい方に向けています。コーチングは「コーチングのしかた」という技法も重要ですが「コーチングというものがあるのだ」という認知もまた自己成長と健康に役立つと考えています。よってコーチングを受ける側の新社会人の方にも役立つでしょう。

フィードバックとは教えることと答えを出す助けをすること

まずフィードバックを定義しましょう。私は中原先生の定義が好きでよく使っています。「Feedback = Teaching + Coaching」というもので、明確な答えがあることを教えるティーチングと、自ら答えを見出すことを助けるコーチングをあわせてフィードバックと呼ぶわけです。

ティーチングは学習機会を提供することで、例えば業務や事業領域についての知識を伝えることを指します。例えばJavaの書き方とか、サイバーセキュリティ教育とか、PRレビューのやり方とか、社史であるとか、こうした学習機会の提供は多くの職場でやっていると思います。特にオンボーディング(入社時教育)で頻出のイメージがあります。ティーチングは答えがあるものを扱うため、理解度を試験で確認することができます。

コーチングは逆に、答えのないものを扱います。前述の書籍から説明を引用します:

コーチングを最も簡潔に要約してしまえば「他者の目的達成を支援する技術」です。それは、育成する相手に「現状」と「めざすべきゴール」のギャップを、第三者からの「問いかけ」によって意識化させ、振り返り(リフレクション/内省)を促し、「今後、何を為していくべきか」の行動指針や行動計画をともに作っていく技術です。

(フィードバック入門 耳の痛いことを伝えて部下と職場を立て直す技術 第一章)

問いかけを受けて足を止め後ろを振り返ることが、旅路には有効に作用することも多いんですね。これ単体でも掘り下げて話せるような深い話題ですが、今回は話に具体性を持たせるため、メジャーなコーチングの場である1on1に絞って話していきます。すなわち職場において部下が、上司や同僚による「現状と目指すべきゴールのギャップ」についての問いかけを受けて振り返りを行い、今後の行動指針や行動計画をともに作っていく場面を想定します。目標管理やOKRの現場ではよくある姿ですね。

1on1の真の価値、あるいはなぜ1on1に準備が必要なのか

皆さんは1on1を定期的に開催していますでしょうか?筆者としては、月1度でいいのでぜひ定期的に1on1をしてほしいと思っています。相手としては自分のロールやフィールドに詳しい人がベストですが、そうでなくとも傾聴ができて問題解決プロセスにある程度明るい方であれば良いと思います。周りに適当な方が見つからない場合は、フィードバックに興味がある同僚を見つけて相互にフィードバックしあう形が始めやすいかもしれません。

1on1のよくある失敗パターンは、進捗共有と雑談だけして終わるパターンと、「今日は話すことがないのでスキップします!」パターンです。1on1をコーチングの場として、すなわち「自分で見つけなければならない答えを見出すヒントを得るための場」として見たときに、まず必要なのが「答えのない問い」です。事前に問いを用意して失敗パターンを回避しましょう。すでに心のなかにあるならそれを持っていけばいいですが、ぱっと思いつかない場合は次のように自問自答してみます:

  • 自分の働き方や貢献に満足できていないことはあるか?
  • どのようになりたい、何をもって覚えられたいという想いに反した現状が目の前に横たわっているか?
  • 3ヶ月前、6ヶ月前、1年前の自分といまの自分を比べたときに、胸を張って成長したと言えるか?

問いが見つかればこれを分解し、自分で解決できることを除いていきます。例えば自分の貢献が足りないなと気づいて分析した結果、睡眠が足りないので朝会に遅刻することが多いという問題を見つけたとしましょう。このとき「早寝早起きする」のがすでに実行可能なのであれば、相談は必要ないでしょう。しかし「夜遅くまで業務が入ってしまう」「ストレスでなかなか寝付けない」などの事実があるなら、これは1on1に持っていく価値がありそうです。

自分で解決できない問いをいくつか用意したら、1on1が始まる前にこれを議事録に書いて相手に共有しましょう。相手は相談の内容に応じて準備するでしょうし、自分もなにが邪魔して「自分で解決できない問い」になっているのかを考える時間ができます。こうした準備がコーチングにおける傾聴と振り返りを可能にします。

コーチングが健康に効く理由

まずコーチングには承認と呼ばれる、あなたの挑戦やできていることを認めるプロセスがあります。これが自己肯定感の醸成につながるため、新しいことに挑戦していてまとまった成果が出にくい時期には特に、コーチングを受ける側のメンタルを守るすべとして期待ができます。ある程度経験を積んでいい意味で鈍感になれば、このようなフィードバックがなくても自尊心を維持できることもあるとは思いますが、特に新卒採用をするときには組織的にコーチングを行う体制が必要になるでしょう。

次に、これは人によるとは思いますが、少なくとも自分は身体の過負荷に対するサインって普通に生活してたらけっこう見逃すんですよ。ので「最近どう?元気?」と聞かれて「いやー全然ダメですね」と答えることはあまりありません。サインに自分で気づいたころにはもう戻れないところまで来ていたりします。

つまり「あっ、このまま行くとヤバいな」と気づくには才能や経験が必要なんですね。よって朝会や飲み会のような「最近どう?」ではなく、1on1という問題を意識的に俎上に載せる場が同僚の健康を守ることに繋がると考えています。

コーチングする側への手引き

もしあなたがコーチングをする側なら、ひとつルールを定めましょう。それは「進捗共有はするな!」です。進捗共有は朝会のようなチームに開かれた定例で充分に行われるべきだからです。不純物は取り除きましょう。

また1on1は業務上の問題を相談する場でもないので、「1on1が開催されるまで問題をしまっておく」ような動きが見えた場合もこれをやめてもらう必要があります。業務上の問題はリアルタイムにチーム内あるいはエスカレーションをもって相談するべきです。マネジメントが忙しそうだとなかなか報連相できない、という方は一定数いらっしゃるものなので、口を酸っぱくして「いつでも来てね!」というスタンスを伝えていく必要があります。自分は以下のルールをオフィスのキュービクルに貼っていました(とあるネットスラングの改変です)。

1. Your boss always has time to talk with you.
2. If your boss seems busy and hard to talk with, see the rule number 1. 

そして自分では解決できない問いだけが1on1の場に残ったとき、はじめて傾聴や質問、承認といったコーチングを行えるようになります。その問いはおそらくコーチングをする側であるあなたにも答えられないものでしょう。もしティーチングが有効そうならコーチングからさっと切り替えてしまってもいいですが、まずは傾聴することを勧めます。

まとめ

コーチングは自己成長と健康のために活用できるテクニックです。受ける側としてもする側としても、きっと学べることがあると思うので挑戦してみてください。特に準備の有無で体験が大きく変わりますので、1on1にマンネリを感じている方もテコ入れの一環としてコーチングを取り入れてみてほしいです。1on1をやっていないという方は、これを機に取り入れてみてはいかがでしょうか。

JVMにおけるServiceLoaderとjavaagent

本エントリーはJava Advent Calendarシリーズ2の19日目です。

qiita.com

OpenTelemetryの自動計装機能を調べていたら、 ServiceLoader とjavaagentを活用した実装になっていました。これ前知識がないと魔法に見えるやつだなって思ったのですが、 ServiceLoader はともかくjavaagentなんてなかなか使わないだろうなぁと思ったので簡単な説明を書いてみます。

ServiceLoaderはJVM標準のDI技術

ServiceLoader とはJava 1.6から提供されている仕組みです。ので現代で使われているJVMでは必ず使える機能のひとつですね。

サービスとは、既知のインタフェースおよびクラス(通常は抽象クラス)のセットです。サービス・プロバイダとは、特定のサービスの実装です。通常、プロバイダのクラスによって、サービス自体に定義されているクラスのインタフェースとサブクラスが実装されます。 https://docs.oracle.com/javase/jp/8/docs/api/java/util/ServiceLoader.html

ServiceLoader を端的に説明すると、Javaプログラマに通りのいい表現としては、DIのようなものです。このインタフェースを実装してるクラスの実装がほしいよ〜、というコードを書いておくと、それをCLASSPATHから探して渡してくれるんです。

class よくあるDI {
  @Inject
  よくあるDI(Collection<適当なインタフェース> 引数) {
    // 指定したインタフェースの実装をコンストラクタに渡してくれる
  }
}
class ServiceLoader動作イメージ {
  void method() {
    ServiceLoader serviceLoader = ServiceLoader.load(適当なインタフェース.class)
    serviceLoader.iterator() // 指定したインタフェースの実装をイテレートするIteratorを返してくれる
  }
}

なお実装のインスタンスはデフォルトコンストラクタによって作成されます。このため複雑なインスタンスを作ることはできませんが、特定の処理を開始する起点としては充分なことが多いです。

例えばログファサードライブラリであるSLF4Jでは、この機能を使ってバインディングと呼ばれるインタフェースの実装を探しています。SLF4JはLog4j2やLogbackなどのロギングライブラリに処理を委譲しますが、このときに「Log4j2が使えるのか、Logbackが使えるのか?」を判断するのにService Loaderを使っているわけです。

OpenTelemetryでは InstrumentationModule の実装を探すのに ServiceLoader を使っています。何からデータを集めたいのか(RDB、gRPC、HTTPサーバなどなど)に応じたライブラリをCLASSPATHに入れておけば、起動時に ServiceLoader がよしなに必要なコードを拾い集めて初期化してくれる、そういうコードが簡単に書けるわけです。業務ロジック側では、それらのライブラリの存在すら認識する必要はありません。

ちなみに ServiceLoader でインスタンス化される側のコードを書く場合、ほぼセットで利用するのがGoogleのAuto Serviceです。Service Loaderでインスタンス化される側のコードを書く際に「Service Loaderに実装の居場所を教えるためのファイル」を作成する必要があるのですが、これをアノテーションから自動的に生成してくれます。便利ですね。

main関数以前の処理を実現するjavaagent

次にjavaagentの話をします。皆さんがJavaプログラマであれば、 public static void main(String[] args) な関数を一度は書いたことがあるでしょう。え? public static なんて今ドキ書かないって?2023年ですね。

ところでJVMはこの main 関数を実行する前、何をしているのでしょうか。メモリの確保とか、GCの準備とか、 ClassLoader の作成とか、プロセス引数から String[] を作るとか、色々やってそうですよね。そこで自分のコードを動かせたら最高じゃないですか?例えば ClassLoader 作成に一枚噛めるということは、これは事実上JVMが利用するほぼすべてのクラスのロードに介入して改変できることを意味しています。実際OpenTelemetryではメソッドの実装に介入してメソッド実行時に引数を差し替えるなんて芸当をしています。

実際こういう実装の差し替えとかやりはじめると、考慮することが結構あって大変なんですけどね。bytecode manipilationと呼ばれる分野で、筆者の好物のひとつでもあります。

さてjavaagentの話に戻ります。javaagentは java.lang.instrument パッケージに説明があります。javaagentにはそのままズバリの premain という関数を実装すればよさそうです。なるほど、 main 関数の前に呼び出されそうな名前ですね。さらにクラス定義を差し替えるためのメソッドなども提供されていて、いかにもJVMをハックするためのAPIという感じです。

のでひとつ注意点があって、javaagentは使うとどうしてもJVM起動速度にペナルティがかかります。迅速に起動を終わらせてリクエストを受け付けられるようにしたいんだという場合、javaagentの利用を避けて手で各種初期化を行うことも検討せざるを得ない……ということもあるでしょう。

以上でざっくりした説明を終わります。OpenTelemetryは ServiceLoader とjavaagentの合わせ技で、javaagentのCLASSPATHに入っているインタフェースの実装を main 関数実行前に使うことで、 ClassLoader に手を加えて計測対象モジュールに対して自動的に初期化を行っていました。一見便利ですがjavaagentの持つ速度的なペナルティや、javaagentのCLASSPATHが大きくなりがちという問題も潜んでいます。ご利用は計画的に。

2023年に読んでよかった本

記事にしたやつ

職場でオススメされた「両利きの経営」を読んで記事にしました。「知識創造企業」もオススメされているので来年読みたい。

blog.kengo-toda.jp

医療関係

医療関係エンジニアのはしくれとしてある程度の情報収集は心がけているのですが、今年読んだ中ではこの「再考・医療費適正化」がダントツで面白かったです。医療費問題は医療の持続可能性を考える上で避けて通れないのですが、実は地域性も色濃く出る問題なのだということがよくわかりました。

医療情報技術関係の雑誌もいくつか試していますが、現時点では新医療がダントツで読みやすいです。特集もセキュリティ寄りの医療情報技師である自分の関心に近いものが多く、また連載もけっこう楽しいです。多要素認証は大切だけど、医療現場でどう運用するんだ*1みたいな疑問もきちんと掘り下げた話を載せてくれていたりします。医療情報技師なら事業者側でも医療機関側でも読んで損はないんじゃないでしょうか?

エンジニアリング

大工に縁のある人生だしマイクラみたいなゲームも好きだしエンジニアリングでご飯を食べてもいるので、建物や設計についてはちょいちょいつまみ食いをしています。今年読んだ中では「一級建築士矩子の設計思考」が面白かった!図面を書くときのワクワク感がすごい伝わるし、設計や構築の裏側にある考察や気配り、法制度なども見えてきて知識欲が満たされます。

お酒や建築関係の知識がちょいちょい出てくるのも面白く、私はこのコミックスをきっかけに最寄りの蔦屋書店で商店建築を買うなどしました。都心の呑んべぇにはまた違った価値がある本なのだろうと思います。

こっちの「船の科学」も良かった。モジュールごとに開発して最後に組み上げるとか、納品前に性能試験をするがその際のやり方が国際的に決まっているとか、こちらもソフトウェア開発に通じるところがありそう。

ソフトウェアエンジニリングの現場感というか勝ちパターンのようなものが見えてくると、こうして外の分野におけるやり方から学ぶことで変な常識を頭から外せると思っているのですよね。そういう意味でシステム開発のワークフローを作っている人には参考になると思いますし、もちろんものづくりのプロセスやその背景にある科学について興味がある方もぜひ読んでみたら良いと思います。

その他

「結婚するって本当ですか」完結おめでとうございます!ラブコメで引き込みつつも、わかりやすくデフォルメされつつも丁寧な描写で家族や愛について考えさせてくれる名作です。この家族がこれからも幸せに生活できることを願っています。

「ダンジョン飯」完結おめでとうございます!モンスターを食うという奇天烈さをもって売り込まれた第一巻でしたが、完結まで追ったら普遍的かつ本質的なテーマを地盤に持っていたのだと再発見させる内容でした。また最初から読み直したら新たな発見がありそうです。

「誰も農業を知らない」子供に何を食べさせるかを日々考える立場として、とても考えさせてくれる内容でした。遺伝子組換え作物も農薬も、こうしてきちんと論じられると有り難みがわかりますね。どちらも(自分の中では)最初の印象でだいぶ損をしていたので、こうして実態を再整理して認識しておくことは今後の生活に役立つと感じました。

そして最後、今年読んだ一番面白かった本を聞かれて答えたのがこちらの「うんち学入門」です。対話を通じて掘り下げる書き方をしていて変わっているなぁというのが第一印象でしたが、その書き方が内容にマッチしていてすごく読みやすいんです。本としての起承転結に結びつくのもそうですが、すでに学んだ内容とのつながりの指摘や新たな疑問点の提示などがキャラクターによってなされることでここまで科学的な読み物が読みやすくなるのか!というのは感動的な発見でした。

この本には組成のようなうんちそのものについてももちろん書いてあるのですが、うんちを起点とすることで生物や進化、生態系まで幅広く学べるのが特徴的です。知識欲を満たすのに最適な一冊だと思います。

*1:手袋マスク装着とか、短期契約の働き手が多いとか、固有の問題が多い

2023年のOSS活動状況まとめ

昨年のに引き続きOSS活動状況をまとめます。2022年12月16日時点の情報です。

概要:OSS活動はもっと減った

GitHubのプロファイルページによると今年は8,153 contributions、過去最多でした。ただこれはprivate repoでの活動を含む値で、これを除くと514 contributionsと昨年や一昨年よりも少ない数値になりました。 昨年以上に減りましたね。ただ昨年7月に転職していることを考えると、昨年7月以降のContributionペースはあまり変わってはないのかも(昨年の方が多いのは1〜6月の影響が大きいか)。

図1 Private Repoの貢献を含まない値
図2 Private Repoの貢献を含む値

自分でメンテナンスしているもの

だいたい絞れてきている感じです。gradle-semantic-release-plugin470リポジトリで使われていて、代表作になりつつあります。

actions-setup-docker-composedocker compose コマンドの登場を受け、今後メンテナンスモードに入れていきます。 errorprone-slf4j はもう自分では使ってないので、当該コードをerrorproneあたりに寄贈するべきなのかもしれない。

あとはいくつかの実験的実装プロジェクトを走らせていますが、あまりコミット数は無いですね。

貢献しているもの

現時点ではほぼ一点のみです。これもやっぱり自分では使ってないですが、Gradleプラグインの新しい機能や実装を試すのにちょうどいいサイズだというのと、統合テスト自動化をしっかりやったので安心して開発できるのとでしばらく手を入れていくとは思います。

できれば自分が今使っているツールのプラグインを書きたいので、引き続きアンテナを立てていければと思います。