意識的に職位を下げる

僕はチーム join 時に、Docker は初手で剥がすし、GitHub Actions でやっているワークフローの全体像を把握するのを次に行う、というのを基本的にはやっている。これはシステム構成やデプロイ周りの全貌を把握するのが好きなのと、何かが起きたときにコレをやっているのといないのとで問題切り分けの精度に圧倒的な差があるからなんだけど、join 直後にやるのが最適解とは限らない場面もある。

チームの人員構成として、テックリード業を既に担っている人が居る場合、追加人員にはテックリード未満の「プラスの工数として数えられる戦力」となって欲しい。この戦力というのは、「目の前に積み上がった問題を一緒に解いて欲しい」という期待。問題と言うよりも、既にタスクになっているものを消化したい、という期待の方が大きいと思う。

そういう期待があるときには、ちんたら Docker を剥がしている場合ではなく、何も考えずに docker compose up の 1 コマンドで環境構築を終わらせ、テストもローカルでは実行せず CI に任せても良いので、タスクを消化した量を稼がなければいけない。今実行しているコマンドが何なのかは一旦「おまじない」で構わない。

つまり、言われたことしか作業しない兵卒プログラマとしてのロールに下げる、というのが期待されている。

この期待と行動とが一致していないと、周りからはガッカリ評価を貰うことになる。

「今この瞬間にクリティカルではない問題に時間を費やしている」 「チームが相対している目前の問題に対して、一緒に戦ってくれない」

チームの本当の問題を見つけにかかるのは、もう少し信頼を稼いでから。将校の役割を期待されるようになってからで良い。兵卒は、ブラックボックスブラックボックスのままとして扱うことも必要。

兵卒ロールとテスト

こういった兵卒ロールを保証するのが CI/CD である。

他のコードに影響を与えてしまうリスクは CI で担保されているので、変更したファイルの外の世界を全て把握している必要がない。デプロイに関する人類の叡智は YAML に落とされており、誰も具体的な 1 コマンドずつの手順を知らなかったとしても粛々と動き続けてくれる。

テストコードがある世界はすごくて、すべてのコードに「間違いなく動く自信」が無くても構わない世界に連れて行ってくれる。「自信は無いけどコンパイラは怒っていないし CI も通ってるので多分動くだろう」という曖昧な認識で作業を完了しても大丈夫なのだ。この状況を作り出すためには一定以上のテストカバレッジが必要になるが、いちど閾値を突破するとテストに信頼が置けるようになり、兵卒が兵卒として生きていられる環境が成立するようになる。

プログラマの教育では「書いた全ての行について、影響を説明できるようになれ」というのを口を酸っぱくして言ってきたが、これは実は兵卒ロールに対しては過剰な努力であって、CI さえ通ってれば気にしなくても良いのかもしれない。(というのは言い過ぎで、その気になれば追える能力を持った上で、意識的に自分で上下できるとより良いよね、ということを言いたい)

考えたきっかけ

テストコードが無い世界で、テストの導入を渋る人にどう説得するのか、テストのメリットとは何なのか、という話題を見て。

テストのメリットは手動テストの時間短縮と、考慮漏れに気づける場合があることだと思っている。時間短縮は素朴に短縮できるのでやればいいが、考慮漏れの方は、僕自身が全貌を把握しているプロジェクトでは、自分ではテストを必要としていないよなぁという感想を抱いた。逆に言うと全貌を把握していなくてもコードを書けるようになるのがメリットで、全貌を把握しないという選択肢があるし、それを要求されることもある。

実際、全貌を把握しきっていないプロジェクトだと型が欲しいしテストも助かる。型さえあれば勘でコードが書ける。*1

全貌を把握することは必要ないのかと言うと、テックリードやアーキテクトの役割なら必要だろう。意思決定をするためには、どこに問題があるのか、何に効くのかを知っていると良い。そして何をするとどこがどうなるのかをだいたい知っているなら、テストの嬉しさは少ない。つまりテストの期待は「テックリードではない誰か (数ヶ月後の TL 自身も含む) が最低限の成果を出せることを保証する」ことと言えるんじゃないか。

*1:型がなくても勘でコードを書けるのが Rails というレールの凄いところだとも思う

使用頻度とコマンド (エイリアス) の文字数を合わせたい

1 文字エイリアスのすゝめ

1 文字エイリアスが好きで、例えば

alias s="git status -sb"

している。

入社してからの 4 年半で溜めた 53 万行の .zsh_history から集計すると、

$ history 1 | awk '{ print $2 }' | sort | uniq -c | sort -nr | head
121714 g
114128 s
57124 v
34210 cd
26095 tig
23281 rg
11382 plenv
10837 t
9647 :q
6867 ll

となった。ちなみに以下の略です。

alias g="git"
alias s="git status -sb"
function v() {vi -p ${${=*/:/ +}/:*}}
alias t="tig"
alias :q="exit"
alias ll='ls -lFG'

cdplenv は主に fzf 経由で入力しているので、おそらくこんな頻度では入力していないはず。 fzf は bindkey '^s' とかに割り振られています。

1 年前ぐらいにも似たような集計をして、よく使ってる tig に 3 文字も費やしているのは最適化できていないな、と思って alias t="tig" を追加したのでした。

github.com

t の追加後は

$ history -152000 | awk '{ print $2 }' | sort | uniq -c | sort -nr | head
40638 s
37374 g
14205 v
10817 t
8550 cd
6760 rg
3948 plenv
2491 npm
1499 ll
1023 docker

と、しっかり 1 文字が上位に食い込んでいることが分かる。なお今は ll は更に短く l 1 文字にしたし、 alias d="docker" も追加済みです。

1 文字にするだけでいいのか

alias g="git" なので、g の後にサブコマンドを打っているはずなんだ。サブコマンドも含めて集計しよう

$ history 1 | awk '{ print $2,$3 }' | sort | uniq -c | sort -nr | head -n 20
114047 s
22225 tig
20599 g a
13867 g ci
11149 plenv exec
11072 g ds
10728 g co
10686 v
9726 t
9647 :q
7681 g f
6019 ll
5969 g ap
5042 g fix
4839 com
4716 g switch
4650 g b
4279 bundle exec
4169 g r
3881 g ri

g の色んなサブコマンドが出てきている。

それぞれ

a = add
ci = commit -v
ds = diff --staged -b
co = checkout
f = fetch -p
ap = add -p
fix = commit -v --amend
b = branch
r = rebase
ri = rebase -i

なんだけど、こんなに入力しているならサブコマンドではなく、alias a="git add" にするとか、空いている 1 文字エイリアスに格上げするのが望ましいはず。

サブコマンドをどんどん登録していくと 26 文字を超えちゃうんじゃないかって心配をするかもしれないけど、大文字や記号もエイリアスに使えるという発想を忘れてはいけない。50 文字ぐらいはしれっと行けるので、柔軟にやっていきましょう。少なくとも g a より ga の方が 1 文字少ないので、2 文字には縮めたい。

alias or abbr

主に fish 派閥から、「これからは alias じゃなく abbr だ」のような言説をよく目にするが、こうして使用頻度に合わせてログから最適化しようと思うと、やっぱり alias を使っている方が望ましいのではないか。 いやこれは僕はマジでよく知らなくて、もし入力文字列も history に残ってるなら何の問題無いので、abbr を使うなと言っているわけではない。

とにかく使用頻度に合わせて最適化したい。

期待値をチューニングする

吉祥寺.pm30 で、チューニングがテーマだったので、マネージャとメンバー間で期待値をチューニングするという LT をしてきた。

トークタイトルは熊とワルツを。トム・デマルコの本です。

「管理」という言葉

「管理」と訳される単語は色々ある

goo 和英辞書 によると

  • 〔経営〕management
  • 〔経営,運営〕administration
  • 〔統制〕control
  • 〔監督〕supervision

英辞郎 on the WEB によると

  • administration〔【略】admin. ; adm.〕
  • caretaking(建物・土地などの)
  • caretaking〈英〉(学校などの公共施設の)
  • charge
  • conduct(業務などの)
  • control
  • custody(大事な物の)
  • direction
  • governance(学校・企業などの)
  • government(組織などの)〔不可算〕
  • hand〔通例、hands〕
  • intendance
  • management(会社などの)
  • oversight〔【同】supervision〕
  • stewardship(他人から預かった資産などの)
  • superintendence〔【動】superintend〕
  • supervision

こういうのは英英辞典を引くとニュアンスの違いを読み取れるのでロングマンで調べていく。

https://www.ldoceonline.com/jp/dictionary/administration

し、ググるといくつも出てくる。

ざっくり言うと

  • administration
    • management の上位概念
    • 方針や目標を設定する
    • 政権
  • control
    • 制御する
    • 定常業務
    • 大きな変化を伴わないものを安定動作させる
  • management
    • administration で決まった方針を具体化する
    • (暴れ馬を) 乗りこなす

みたいなイメージがあるっぽい。

特に control と management の違いは面白くて、例えば車の運転は management じゃなくて control であろう。management はもっと変化をする (しなければいけない状況である) のを期待されている。

今プロジェクトに必要なのは、決まった型から外れないように control する人なのか、暴れ馬を乗りこなす人なのか。自分はどちらを求められているのか、というのを認識したり、上長と握ったりしておくと、期待に合った変化を持ち込めそう。

だいたいこういうのは職位によって期待が決まっていて、定型的、典型的なものは少しジュニアな人に、より上位の人には、典型的な要件を越えて、または典型的な要件の中で筋よく発揮することを期待している。守破離ですね。まずは教科書通りに control する成果を、慣れてきたら教科書から外れたものでもなんとかする、自分の方法論を新たな教科書としてまとめていくような成果を出して欲しい。

リスクマネジメント

リスクマネジメントプロセスは ISO 31000 に書かれていて、このプロセスのループを回していくことで安定的にプロジェクトを進めたい。

リスクマネジメントと現場の気づきの重要性 | オージス総研 より

このループは、ジュニアなうちは判定業務と言える。

  • 事前に決まっている判定基準に照らし合わせて、アラートを上げるべきと判定する
  • 事前に決まっているプランBに切り替えるかどうかを問い合わせる
  • 決まっていたプランBを遂行する

より上位になると、リスクの掌握そのものを行って欲しい。

  • リスクを特定するための観点をまとめるとか、観点からリスク一覧を作るとか
  • リスクの評価関数を定めるとか
  • リスクへの対応手段を決定しておくとか

整えられた状況で達成できる、ではなく、どんな状況でも達成できる、を期待されていると言える。

どんな状況でも達成するためには、リスクを洗い出しておいて、リスクごとに対応方法を決めておく。リスクが高まってきたら「最悪松竹梅の梅に切り替えれば良い」ぐらいの精度が初期状態として、梅を実際にタスク分割して見積もっていくような動きを取っていくことになる。

理想として松プラン、普通の成果としても竹プランに着地させるプロジェクトマネジメントを期待しているが、ダメだったときに梅プランには着地させる。梅にすら着地できないは、避けたい。

松竹梅を出すとか、今のままじゃダメそうかどうかをどう判定するかとか、どのプランに着地させるかを決めるとか、着地させるためにどう動くかとかを、自分で決めることを期待されているのか、それともそこまでは期待が無くて方針は上の方で決まっているのかは、administration や management、control の差なのではないか。

委譲

Management 3.0 (今年、邦訳が出るらしい?) で紹介されているツールに Delegation Board というものがある。

アカツキさんの例 とか CyberAgentさんの例 とかを見ると感覚が掴めると思う。

委譲は 0/1 ではなく 7 段階のグラデーションがあり、どの段階と考えているかをお互いに認識を揃えよう、そして理想の委譲段階にしていくために情報や判断をしっかり渡していこう、というツール。

  1. 指示する :管理者として意思決定を行う
  2. 売り込む :意思決定についての人々を納得させる
  3. 相談する :決定する前に、チームからの意見を得る
  4. 同意する :チームと一緒に決定を下す
  5. アドバイスする :チームによる意思決定に影響を及ぼす
  6. 問い合わせる :チームの決定後のフィードバックを求める
  7. 移譲する :特に影響を及ぼさずチームに任せる

似たようなツールに RACI 図がある。

asana.com

これはタスクごとに

  • Responsible (実行責任者)
  • Accountable (説明責任者)
  • Consulted (意見を述べる人)
  • Informed (報告を受ける人)

をハッキリさせておこうというツール。

この RACI と Delegation Board の各委譲レベルを対応させると、以下のようになるのではないか。

Delegation Level mamager member
1(指示する) A,R
2(売り込む) A,R I
3(相談する) A,R C
4(同意する) A,R R
5(アドバイスする) A R
6(問い合わせる) I A,R
7(移譲する) A,R

という話が アカツキさんのブログ にあります。

「4. 同意する」のところでは実行責任が同列にある、「6. 問い合わせる」では Accountability もマネージャ側のものではなくなっている、「7. 委譲する」だと報告されることもない、とかがより分かりやすくなって、非常に面白い。

まとめ

  • 管理にも色々ある
  • management を求められているのか、control を求められているのか
  • 委譲度合いも認識を合わせて上手くやろう

先回りするコツとミカドメソッドという手法

実装を進める上で障害になりそうなところを先回りして直してるように見えるけど、一体どうやって検知しているかという話題。

結論から言うと「慣れです」なんだけど、こういう考え方があるよというのを紹介しておく。

mikadomethod.info

ちょうど10年ぐらい前に話題になった手法だけど、考え方としてはまだまだ現役です。

概要は本家なりこの辺のリンク先なりを見て貰って。

僕の理解は

  • 1 ループ目
    • やりたいことを実現するコードを書く
    • ギャップが無ければサクッと実装して終わり
    • ギャップがあれば、それを「課題」としてマークする
    • 最初のコードを捨てる
  • 2 ループ目
    • 課題を実現するコードを書く
    • ギャップが無ければサクッと実装して終わり
    • ギャップがあれば、それを「課題」としてマークする
    • 最初のコードを捨てる
  • 以下課題がなくなるまで繰り返す

と繰り返すとゴールを達成できる、です。

いわゆる「ヤク刈り」を、1 つずつ、いつでも引き返せる形で行える、というのがポイントなのだろう。

似たような養成ギプスに、 test && commit || revert や TDD があります。

medium.com

test && commit || revert は、本気でこれをやろうと思うと依存関係の端から作業しないといけないので、ミカドメソッドと同じことを実現しなければいけません。 また、設計技法としての TDD は、テストを書きながら絶対必要になるパーツを実装し、パーツを組み上げて完成させる。これも依存関係を構築していくイメージですね。

最初に思いついた簡単な方法で実現できると爆速で生産性 MAX になるが、様々な理由でそう上手くはいかない。 爆速な理想と、目の前のコードベースとのギャップを実感しながら日々暮らしていくと、要件を言われたときに「絶対ココが問題になるので直しておきましょう」と言えるようになっていく。

依存関係を思い浮かべられる、問題になると自信を持って言える、というのが、必然なのだけど、端から見ると先回りに見えるのだろう。

なぜ依存関係が思い浮かぶのか、に対しては「毎日のヤク刈りの結果、コードベースが頭に入っているから」 なぜ問題になると自信を持って言えるのか、に対しては「毎日のヤク刈りの結果、罠っぽいところに鼻がきくようになっているから」

となってしまって、つまり「慣れ」です。

「慣れ」ではあるんだけど、普段どれだけ意識しながら目の前のコードを読んでいるかでもある。 ヤク刈りをしているときに、今私はヤク刈りをしています、と認識しながらやっていると、分解したタスクのそれぞれの重さについて、勘所が磨かれていくのではないか。

3 月に 2 本登壇していた

もう 5 月も終わりですね。つい書くのが億劫で。

www.slideshare.net

YAPC::Japan::Online 2022 で登壇したもの。

Description には

僕らはインターネット上で開発の知見を得ることによってサービスを開発・運営できているので、インターネットに還元したい。そんな気持ちから、会社でもアウトプット (登壇や技術ブログ、執筆、OSS 活動等) が推奨されています。 社としての技術ブログも存在しますが、スタッフ個人のブログを通じて発信するのも同じように推奨していきたい。エンジニアの個人ブランディングも大事だと考えているし、自分の場所の方が書きやすいというのも感じているからです。 その上で、社内外の色んなサービスに散らばった技術 Tips を上手くまとめて再放流することで、手軽に情報を摂取し、技術的好奇心を満たし、成長し続けられる環境を用意したい。 そんな、個人の集合体としての技術コミュニティを運営する方法と、そのために開発したアプリケーションについて紹介します。

と書いておいたんですが、まさにそういう話をしました。

内容はほぼ以下の記事なんですが、社で行われている色々なアクティビティが同じ方向を向いている様子を表現できた、良い発表だったと思う。情報を放流して定期的にまとめることで定着を狙う。ただ放流するだけでは文化にならない (主にフォロワーが生まれづらい) と考えています。コメント力を付けるとかして、もっと上手くまとめていきたい。

onk.hatenablog.jp

www.slideshare.net

Hatena Engineer Seminar #19 カクヨム編 - connpass で登壇したもの。

リモートワーク主体になって、(特に技術的) 雑談が減って困っていませんか。誰が何をやりたいか、誰がどこに不満を持っているかを把握しておかないと、どんどん判断が難しくなる。意思決定のために雑談は必要なんです。そしてこの毛繕い行為には「社会的グルーミング」という名前が付いていて、チーム人数に応じた適切な時間がある。

チーム内のボケやツッコミ、かぶせといった役割を想像できる。こう言ったらこう返ってくる、拾ってくれるだろうと思える状態が心理的安全性です。という話をしました。

1on1 も割と似た捉え方をしているかもしれない。自己開示しつつ信頼関係を構築するだけの時間を過ごして、相手の価値観を知り、反応を見ながら伝え方を考える。というのを、チームで仕事をする上でずっとやってる気がします。

コードの話が少ないけど、今月は今のところチーム内 merge 数 1 位です。この調子で楽しく開発できるチームとコードベースでやっていこうな。

$ git shortlog -sn --merges --since=2022.05.01 | head -1
    58  Takafumi ONAKA

株式会社はてなに入社しました

株式会社はてなに入社しました

株式会社はてなに入社しました - hitode909の日記

5 年目になりました。所属は引き続き弊社です。

Podcastに出た!聞いてください!

developer.hatenastaff.com

タイトルは前回のゲストの id:hitode909 に合わせた。

blog.sushi.money

自分の声を聞き返すのが苦手なので、自分では Amazon Transcribe で読み返しました。

f:id:onk:20220320004548p:plain
誰の台詞かの判定もできる

読み返してみたんですが、

みたいな、情報ジャンキーとしての話が目立ってますね。そこそこ得意技です。

異動を計画するに当たって気にしていることとか、技術ブログをレビューするときに気にしていることみたいなのは、それぞれ別にまとめておきたいな。

そんな話をしました。よければ聞いてください。

developer.hatenastaff.com

似た話をファインディさんとのイベントで話す気がするので、一緒に宣伝しておきます。こちらも日中にラジオ感覚でどうぞ。

findy.connpass.com