右上↗

プログラミングに関するメモをのこしていきます

我を通すことと全体最適を一致させる

2024年が終わる。実は今年のテーマは「意志を持って仕事をすること」だった。自分の強みはカバー範囲が広いことにあると思っていて、結果として穴埋めに走りやすく、大きな成果を生めていないという2023の反省からきたテーマだった。

ふりかえると、まぁなんだかんだでかなり流されたかなと思う。

何で流されたんだろうなと考えた時に、自分の中で「全体最適であること」の優先度がかなり高いということを改めて感じた。意志を持ってこうするぞと思っていても、全体最適のための動きと乖離してきたらそっちに流れてしまう。

全体最適でいいじゃんとも思ったのだけど、やっぱりそれは諦めているというか、逃げの消極的な結論だなとも思った。やっぱり意志を持って仕事した方がパフォーマンスもあがるし、能力も上がるし、成果も出ると信じている。

と、ここまで考えて、そもそもなぜか意志を通そうとすると全体最適でなくなってしまうという前提に立って考えていることに気がついた。

そんなはずはなくて、全体最適にするためにはこうするべきだという意志で動けばいいだけではないか。

つまり、今年の僕の問題は、意志のレベルが低かったことなんじゃないか、と思った。もっと高いレベルで考えて練られた意志をもっていれば、途中でふらふらと流される必要はなくて、貫けた行動もあったと思う。また、前提条件が大きく変動するなどして当初描いていた構想から離れていくときも、流されるのではなく、その状況に応じて考えぬいた自分の意思を持つことはできたはずだ。

ようするにまだまだ受動的、ないしは判断が弱かった・遅かったということかなと思う。2025こそ頑張りたい。

簡単そうな小粒の開発が連打する機能こそ難しい

長くサービス開発をしていると、機能領域ごとに開発する内容に特色が見えてくる。ある領域は深く難しい開発が求められ、ある領域は簡単な変更を大量にやる開発が求められる。

前者の方が分かりやすく難しいので注目を集めやすいが、実は後者の方が本当は難しいのではないかと思うようになった。

深く難しいところは、たしかに難しいのだが、結局のところ1人でその時ベストな設計をすればよい。規模にやるが、そういうのはできるエンジニアが1人でえいっとやってしまって終われることも多い。1人で作ればいいのであれば、設計的な難易度はかなり下がると思う。

一方、軽微な修正・仕様変更が連打されるものは、時間軸的に長期化することも多く、そうなると関わる開発者が1人では収まらなくなる。時間が長く、関係者が多くなると、設計意図は簡単に失われる。設計意図が失われると、アドホックな変更を積み重ねてしまい、俯瞰して見た時に何が何だかわからない魔境が簡単に出来上がってしまう。

これのタチが悪いところは、実際それである程度問題が解決してしまうところだ。ここにif文を入れる、このときはこの変数に本来の設計意図とちょっと違う意味の値を入れる、このときはあっちでこう計算しているのでこっちで帳尻合わせをする。それでその場の問題は解決してしまうが、先に述べたような修正方法は明らかに全体設計が破綻していくシグナルだ。質とスピードそのものという感じの話だが、あっという間に損益分岐点を超えてしまう。

解決方法としては、そういう場所にこそ全体設計を俯瞰できるハイスキルで背景をよく知っているエンジニアをアサインするとか、設計意図が失われないように強い輝きや制約を持つ良いカードを書くとかだろうか。特に前者は真逆のことをやってしまいがちなので、注意したい。一見簡単そうで、Good first issueに見えてしまうが、歴史的経緯などを踏まえた割と高度な判断が求められるので、新メンバーに任せっきりにするのは酷で、手厚くフォローするようにしたい。

他人の仕事への許容度はどうあるべきか

人と仕事をすると、自分の思ってた感じじゃないやり方や成果物が出てくることがある。そういう時にどこまでを許容するか。いろんな観点があると思うので考えてみたい。

大前提だが、そもそも共同で仕事をする上で、やりかたや成果物についての期待値を揃える努力は惜しまない方がいい。ただすりあわせればこういう摩擦がなくなるかというと、そんなことはない。そのまですり合わせたら、それはもうペアプロだ。たとえば、外部仕様や設計レベルで期待値を揃えていても、詳細な実装部分で思ってたのと違う感じになる、なんてことはよくある話だと思う。

許容度が低いというのはつまり、自分の思う正解・やり方以外をあまり認めないという意味だ。許容度が高いというのはその逆で、思ってたのと違っても受け入れるという意味。

こう書くと許容度が低いことはあまりいいことじゃないようにも見えるが、自分はそうでもないと思う。ソフトウェアエンジニアリングにおいては、PRレビューがしっかりしている人をイメージすれば、そんなに悪いことじゃないと思える人は多いのではないか。自分はレビューが粗い自覚があるので、そこまでこだわって質の高いものを作ろうと意識できている人を尊敬している。

とはいえ、許容度が低すぎるのも良くない。まず第一に、自分の思う正解が本当に正解かどうかはわからない。そもそもどちらも正解である場合すらある。常に自分の思う正解が絶対である限り、自分より高いレベルの成果物は生み出せないが、複数人で良いところを持ち寄ることで昇華できるものは多い。

自分の想像とズレた時に、そこには実際にやってみた人なりの洞察・考察があるはずで、きちんとそこをすり合わせることが大切だ。

そしてそのためには、普段から度量があると思ってもらうことも大切だと思う。受け入れてくれる可能性がないと思ってしまったら、もうそこに健全な議論は成立しないから。

また、マイクロマネジメント的にやり方を規定されることで、パフォーマンスが落ちることもよくある。モチベーションは大事にした方がいい。

とはいえ、先に書いた通り、こだわりを持って成果物に向き合う職人性は、エンジニアならある程度は持っているほうがいいのだろうと思う。こだわれるのは、それだけ問題に向き合って考え抜いている証拠でもある。理想的には、こだわるべきだと思う場所をきちんと判断し、譲れないポイントを明らかにした上で合意する。それ以上のことは任せる。というのがいいだろうなと思う。

そもそもどっちでも良いような話はゴロゴロしているので、そういうのは任せつつ、チームで規約を作るなどして整える活動を別でやると良さそうだ。

 

 

プレイングできるマネージャーだからこそできる攻め方がある

と思うのだけど、どうだろうか。

プレイングマネージャーってあんまり認められないというか、基本的には良くないこととされていると思う。

自分は、別にいいんじゃないかなと思っているので、なんでそう思っているのか書いてみたい。
 
まず前提として、マネジメントをおろそかにするプレイングマネージャーは違うよねというのはわかる。
自己批判として、マネジメントの技量不足や向き合い不足をプレイングで無理やり誤魔化していないかを問う、というのは正しいと思う。
 
一方で、そもそもあらゆる職種において、完璧な正解があるわけでもないし、正解らしきなにかがあったとして、そのために必要な能力を完璧に備えている人なんてほとんどいないと思う。
だからこそみんな試行錯誤をして、足りないスキルをどう補うかを考えて、どうにかして成果を出す。
そのための手段としてプレイングをすることってそんなに悪いことなんだろうか、と思う。
 
もちろんある程度自覚的である必要はあるし、プレイングすることでマネジメントに悪影響が出るなら本末転倒だとは思う。
たとえばマネジメントに向き合う時間が足りなくなったり、メンバーに対して良くないシグナルにつながってしまったり。
 
でもむしろ、プレイヤーとしての価値を出せるというカードを持っているからこそできる攻め方というのがあるんじゃないか、というのも考えてみたい。
 
自分は一プレイヤーとして、やっぱり現実の問題を解決してくれないマネジメントにはちょっと距離を感じてしまう。
一緒に泥をかぶってほしいとまでは言わないが、一人の力で抜けないカブがあるときに、自分の力を貸してくれる人のほうが信頼してしまう。
自分が子どもなのかもしれないが、みんなそんなもんじゃないだろうか。
マネージャーが一人手を貸したところで抜けないようなカブを、多くの人や金を動かして抜くのがマネージャーだろ、というのはもちろんある。直面している問題のサイズとか種類次第だけど、一人手を貸してくれればうまくいくってときに手を貸せるっていうのは大事だと思う。
 
また、チームとしてサバイバルモード気味になってくると、少し厳しい運営をしなければならないこともある。
こういうときに、プレイヤーとして圧倒的な馬力を出している背中を見せてくれると、頑張れるなと思う。
マネジメント側の立場で考えても、メンバーにやや厳しいコミットメントを要求するときに、泥をかぶっている方がやりやすいんじゃないか。(これも甘えるなという話かもしれないけど、でも人間そういうものじゃない?)
 
責任のとり方の一つでもある。うまくやらないと最悪なパターン(「あーあとはもうこっちで巻き取るんでいいです」みたいな)になりかねないから、注意が必要だけど、例えばペアプロで手を差し伸べたり方針をがっと整理したりするのも大切な打ち手だと思う。
プレイヤーができないのにそういう打ち手を取ろうとすると、とんちんかんな邪魔になってしまう。
一メンバーとして、うまく進まないタスクを持ち続けているという状況は、精神的負荷がかなり高いと感じるので、どういう手段であれ軽くしてくれることが一番うれしいと自分は思う。(これは本当に人と状況によると思うけど。)
 
結局そういう背中に人はついていきたくなる、と自分は思う。すくなくとも自分はそう。
マネジメントをやりだすとプレイヤーになれない、とかマネジメント嫌悪を広めるだけだし。

サーバーサイドKotlinのエコシステムって意外と多様性がないなと思った話

なんでだろうね。 お前が作るんだよって話もあると思うのだけど、それにしても極端に少ない印象を受けている。

たとえば Go や Python, TypeScript, Rust あたりは、雨後の筍のように HTTP Server を書くためのライブラリが乱立している。それぞれに特徴があって、OpenAPI との接続がいい感じになってたりミドルウェアが揃ってたりする。 このへんの言語はメジャーだから、という話に思えるかもしれないが、新興言語でも昨今は HTTP 関連ライブラリは割と乱立するイメージがある。 たとえば gleam なんかは、 https://github.com/gleam-lang/awesome-gleam?tab=readme-ov-file#http-servers を見るだけでも3つある。(まぁこれはずるいか。CGIも含んでるし、Erlang / JS がバックエンドだから。)

Kotlin にはあまりそういうのはない。HTTP Server を書こうと思ったら、Ktor か Spring という感じ。 そして Ktor にはあまりエコシステムの広がりを感じない。Ktor 公式に Plugins がいろいろ書かれているけど、Go とかと比べるとかなり貧弱な印象。 言語としての利用度合いでいえば、Kotlin もそれなりに人気のはずでは...?

いくつか理由は思いつく。 個人ユースで Kotlin を選ぶ人が少ないので、小粒なライブラリが乱立する環境でない。 Java エコシステムに乗っかれることが Kotlin を使う非常に大きな理由になっているので、逆にいえば Java エコシステムで十分。 とか。 JVM はいまから新規に小粒のアプリケーションを作るときには選択肢にあがりづらいよなと正直思う。 組織的に開発するようなエンプラよりのものでないと、積極的に選び辛い。

Ktor のうえに広がりがないのは、Ktor の独自路線感にも一因がある気がする。 Ktor での概念整理が、一般的な HTTP Server における概念整理と違うというか。 Middleware じゃなくて Plugin ってよぶんだーとか、グローバルなエラーハンドラのことを StatusPage Plugin ってよぶんだーとか。 Hono がでてきたときにドキュメントを読んでいて、概念が基本的にはよくあるやつ(Go とかでもよく見るような)だったので、ザーッと眺めてなるほどねとなれたんだが、Ktor にはそれが通じないんだよな。

ちょっと Ktor の上に Hono や Go の net/http 的な API を生やす wrapper が欲しくなってしまった。 せっかく Kotlin Native や Kotlin JS も頑張っているようなので、もう少し軽量に便利なものを作れる感じになって広まるといいなと思う。 なんか作れるものがないか考えて貢献してみたい気持ちになった。

エンジニアの個人技でチーム開発を加速する

ひとりひとりのソフトウェアエンジニアの生産性には顕著な差があり、いわゆるスーパーハッカーはひとより100倍生産性が高いみたいな話は世にありふれている。 個人的な実感としても正直これはそうかなと思う。自分と比較して、圧倒的な生産性を発揮するソフトウェアエンジニアは実際何人か出会ってきた。(本題からそれるけど、そういう人に出会えているのラッキーだ。)

自分よりすごい人達を目の当たりにしているので、そこまで自惚れるつもりはないが、まぁ自分もそれなりには生産性が高いソフトウェアエンジニアをやれていると思っている。 結局のところは人によって得意不得意があって強みが活きるように動けているかが大事だったりするので、あまり汎用的な生産性というものを論じる意味はないのかもしれないが。

自分は個人開発者ではなく会社の一員として活動をしているので、組織として勝つことに興味がある。 ソフトウェアエンジニアが組織として勝つことに貢献する方法のもっともストレートなものは、良いプロダクトを速く作ることなので、自分もプロダクト開発に全力を注いできた。

が、最近このやり方が最適なのか疑問に思っている。 自分くらいの生産性だと、自分ひとりで組織の問題をふきとばすほどのアウトプットは出せない。そういうレベルの人も世にはいるかもしれないが。 となると、自分ひとりでのアウトプットだけで戦っていては結局組織として勝つことができない。 だけど、組織として勝つためにもっと個人として貢献できることがあるんじゃないか?そうなることを目指すべきなんじゃないのか?と思うようになった。

こういうことを考えていると出てくるのはマネジメントっぽい話かモブプログラミングみたいなチーム開発手法の話だが、自分はなんとなく即座にその二者に話がいくのは違うんじゃないかなと思っている。

マネジメントについては、ソフトウェア開発そのものにきちんとコミットするソフトウェアエンジニアでなければできないことがあると思っているので、話を飛ばし過ぎだと思ってしまう。

チーム開発については、自分の受け取り方の問題かもしれないが、なんというか人を平準化しようとしすぎていると思ってしまってあまり前向きになれないところがある。 モブプログラミングなどを通じても、ひとりひとりのメンバーが交換可能になることはなく、むしろ個々が活きるようにのびのびやれるほうがいいんじゃないかと思っている。 (モブプログラミングの目的にはいろいろあって、総論としてモブプログラミング自体にはポジティブではある。今の会社でもむしろ推進してたりする。)

ソフトウェアエンジニアはまだまだ職人技で、人と領域の組み合わせによって圧倒的に生産性に差が出る、という立場を自分は取っている。 結局は個人技で成果を上げていった先の組織的勝利なんじゃないかと、根っこでは思っている。 ソフトウェアエンジニアは個人個人のスキルがとても大切だし、結局そこが一番組織の強さを決める第一の要素だと思う。(他の職種もそうなのかもしれないけど、よく知らないので)

でもそれは、チームでの開発をないがしろにするという意味じゃない。ここが結構履き違えられがちだなと思う。 個人技を発揮するというのは、チームメンバーを気にせず自分の好きなように大技を繰り出すことではない。 というか、それも個人技なんだが、それはレベルの低い個人技だと思う。 本当にレベルの高い個人技というのは、むしろチームの生産性をあげるために辣腕を振るうみたいなものだと思う。 (まぁこれはちょっと「本当に頭のいい人ならもっとわかりやすく説明できるはずだ」論法に近いものだという自覚はある。でもソフトウェアエンジニアはそれを目指すべきだとは思うんだよな。)

勉強会とかペアプロ・モブプロとか、そういう活動ももちろん大切だし、それによって教育的な効果やチームでの認識を揃える効果を狙うのは実際にチームの生産性に寄与すると思う。 だけど、それ以上に、普通にめちゃくちゃいいコードを書いたり、みんながよく苦しんでいる部分のリファクタリングをしたり、チーム向けのライブラリ的なコードを書いたり、そういうソフトウェアエンジニアリングど真ん中の貢献をやっていきたい。 ソフトウェアエンジニアなので。

はやく開発するためにできること

ってなんだろう、というのを考えている。

プロジェクトが肥大化・遅延して、もっと早くリリースするためにできることを探しているシチュエーション。

まず前提として、作るもののスコープを絞るというのがある。これは意識しているところが多いのではないか。 絞るのはいいけど、そのあと回収されるのか?みたいな不安や疑問への答えかたの方が難しい。

結局のところ、やりたいことが溜まっている状況では、スコープを切って順次リリースすることにしても、全部をやり切るのにかかる時間はあまり変わらない。 もちろん小さく分割された問題は不確実性が相対的に低くなるので、そういうメリットはある。 ここではもっと根本的な物量に言及しているつもり。

では次に何ができるか。採用で人を増やす。 ただし、人を増やして速くなるには、かなり良い条件が整っている必要がある。人が増えれば速くなるということは普通はない。

この条件を網羅的に言語化しきれればいいんだが、正直あんまりできる気はしない。 「並行に動かせるプロジェクトが明確にあり、人が増えれば単純に並行数が増やせる」みたいな状況は、人が増えると速くなる可能性がありそう。 ただし、並行で動かせるというのがまやかしでなく、本当に並行して独立に動かせる必要がある。 これは1プロダクト内だとそう簡単な話ではない。

そこで、多少のオーバーヘッドを許容することを考える。 手戻りなどのオーバーヘッドを許容すれば、並行で動かせるプロジェクトは増える。 オーバーヘッドが損益分岐点を下回らなければ成功だ。(ここでは人件費は一切考えていない。単に時間だけに焦点を当てている。)

オーバーヘッドといってもいろいろな種類のオーバーヘッドがある。 作ったものが想定と違って手戻りになる。一部のロールがちょっと暇になってしまう時期が発生する。最重要プロジェクトのスケジュールを後続のプロジェクトが喰い荒らしてしまう。

ここで大事なのは、自分たちの置かれている状況を鑑みて、どんなオーバーヘッドならどこまで受け入れられるのかを考えることだ。 このあたりは技術的負債と同じ考え方で、どんなコストを払ってどんな利得を得るのかに自覚的であることがまずは大切だ。

一部のロールが暇になるというオーバーヘッドは恐れる必要はなく、むしろガンガン受け入れるべきだと思っている。

というか、理想的には暇になることはオーバーヘッドですらないという世界を目指すべきだ。 開発者はみな自立してボトムアップに行動できるので、暇があれば改善をすればいい。 改善の対象は何でもいいが、典型的なのはコードの品質だろう。

これが当たり前にできる開発組織はかなり強い組織だ。暇がなければボトムアップな打ち手が実行されることは少なくなり、じわじわと首が絞まる。 自立したハイスキルな開発者で構成された開発組織においては、このオーバーヘッドは簡単に回収できるコストであり、トータルではやく開発することに直結する。

すこし話題が逸れたので戻す。 どういうフォーメーションで動き、どういうコストを払って、どう速度を稼ぐかは、チームやプロジェクトの内容によって大きく左右される。 そもそも人にはそれぞれに得意不得意があり、人数で簡単にカウントできるような仕事を我々はしていない。 大切なのは、その時々でベターな選択を、メンバーが自覚的に選択できることだ。

そのためには、プロジェクトへの深い理解とコミットメントを各メンバーがもつことが必要だ。 ひとつのプロジェクトに関わるメンバーが増えるということは、ここからやや遠ざかる力学がある。 ひとつのプロジェクトにたくさんの人を関わらせることのデメリットはここにある。 人を増やしてはやさを求めるなら、オーバーヘッドを受け入れて並行数を増やすアプローチしかないのではないか。

プロジェクトは並行させずにクリティカルなプロジェクトに集中せよというのが一般的なプラクティスで、それは正しいと思う。 もしこのプラクティスを優先した方が良いという状況になったとしたら、それが今の組織やコードベース、プロダクトの限界だと受け入れた方がいいのだと思う。 その場合、採用より内部のスケールアップに力を注いだ方がいい。リアーキテクチャとか教育とか。 これは暇を恐れない話にも繋がる。個のパワーが高く、個のパワーを阻害しない、というのが結局一番速い。

それはそれとして、採用には人を増やして開発をはやくする以上の目的があるので大切。