エンジニアの次のステップの勉強法２ - 技術の別の道への活かし方

[エンジニアの次のステップへの勉強法](https://qiita.com/newta/items/f4aff8cdd8706d5d08c5)
↑ 
こちらの記事に色々はてブコメント頂いてありがとうございます！
自分にとってこんなにはてブもらうの初めてで、足りなかった部分を書こうと考えたのでこの記事にしました。


ちなみに私が選んだ道はこちらになります。
つまりスペシャリストの道は若干外れたかなと思っています。


> どんなプログラミング言語が来ても大抵書けそうかなって

ある程度オブジェクト指向系の言語を覚えると、思ったものを大抵書けると思います。
その周辺言語は似ているので、どんな言語が来てもある程度キャッチアップして書ける自信になります。

でも、ソコをさらに超えると、自分は全然書けないやって気がつくタイミングがあるので、その手前にいる人に向けています。たとえばKotlinはオブジェクト指向ですがScalaは関数型の要素を持っています。KotlinでScalaの表現力を表現しようと思っても出来ない場面は結構あります。それはオブジェクト指向でスキルが止まっているからかもしれないです。
と言っても、オブジェクト指向と関数型指向は場合の要素の一つでしかないので、必須なわけではないです。大抵の要望には応えられると思いますし。

次のステップはあくまで次に過ぎないので、全部が必須という訳ではなく、全てがオプションだと考えておけばいいかなと思います。結局、全部一気に覚えることは出来ないので、知識を積み上げて行くしかないかなと思うのでお互い頑張って行きましょー。


> 機械学習

データサイエンティストの方々はエンジニアとは別です。サイエンティストの人もコードは書きますが、きれいなコードを書くということや複数人でメンテナンスしていくためにどのようなコード管理をするかというところに興味がある人とは別の役割です。計算をしたいからコードを書いているだけで、システムで管理したいからコードを書いているのではないのです。目的の違いなので、それ自体が悪いことではありません。
もちろん、コードの品質にも興味があり、エンジニアとして活躍できる人も居ます。そのような方は希少種です。

サイエンティストの方が書く計算式をシステムの品質として維持してコードの品質を上げれるような、その両方をつなぐことが出来るエンジニアに価値が出てくるのではないかなと言うイメージでした。AIはトレンドですしね。

## 私の技術レベル

私は全然モナディックにスピード感もってスタイリッシュに書ける気がしません。

インフラ方面もあまり得意ではないので、ミドルウェアのオプションを全て把握したり、有用な機能を全部知っておいてアプリケーションを最大効率で構成することも得意ではありません。基本機能の用途を押さえるレベルです。カーネルチューニングも出来ません。ulimitは設定しないと死ぬくらいの知識。前の記事でも書きましたが、機械学習もVisionAPIをつかったりは出来ますし、ロジスティック回帰のコードを書いたことがありますが、どの要素がどのような効果を持つかの勘所はありません。プラスアルファ部分については基礎しかないです。

なので、そういう言うのは得意で好きな人にお任せしています。
スペシャリストになるのは大変だなーと思って、今回の記事の寄りのマネジメントな人間になっています。自分個人のパフォーマンス最大化よりもチームのパフォーマンスの最大化やエンジニアのやっていることが価値にインパクトを与えることを考えるのが好きです。もともとビジネスや経済も結構好きでした。

業界的には全く使われない機能を作ってたりすることもよくあるので、不毛だなって思うこともあって、そんな環境で働くエンジニアが可哀想だと思ってしまうこともあり、せめて自分が見える範囲のエンジニアだけは価値に対して最大化したいと思っています。

そんな思いを今回は文字にしてみました。


# 本編はじめ

前回の振り返りが長くなりました。

今までエンジニアとして持った技術を活かして、エンジニアチームのパフォーマンスを最大化することに興味や喜びを感じて、エンジニアの組織マネジメントの軸を増やすための知識です。

数年前からCTOとVP of Engineeringをツートップとして、技術スペシャリストと技術組織のマネジメントを分けて、技術トップを置く会社が日本でも出てきました。前回の記事はあくまでもエンジニアがスペシャリストの道を突き進むための記事の位置づけで書きましたが、今回はエンジニア組織のパフォーマンス最大化をミッションとする役割のスキルについて書こうかなと思います。


# プロダクトマネジメント

エンジニアは下手に自分で動くものが出来てしまうので、何をつくると受け入れられるのか？を全く考えずに作ったり、リサーチをほとんどしないまま劣化版を作ってしまったり
エンジニアは作ることだけでも満足出来るので(僕も無駄なものをたくさん作りましたｗ)、それが目的ならば良いのですが、使ってもらってお金を払ってもらうレベルのものを考えるとなると、十分な知識と分析のもとで作る必要があります。開発メンバーのリソースには限界があります。

どこかに荷物を運びたい時にエンジニアはF1カーを作りたいと思いがちですが、求められているものは軽自動車かもしれません。もしかしたら、既存の線路を利用して電車を使った大量の荷物を一気に運べるものが効率的かもしれません。F1カーではなく、何をつくるべきかをリサーチして分析する力が必要です。

ちなみにこれをやっていると技術の勉強も同時にやることは時間がいくらあっても足りないので、エンジニアのメインミッションではないと考え、前の記事には入れていません。


### 市場の次の変化を想像できる知識を得る

何かのアイデアやコンセプトが出てきた時に既存の企業に無いサービスなのか、競合がある場合、分析しなければなりません。ソフトウェアの世界では、それは国内情報にとどまらずに海外の企業も競合になります。そのリサーチはなにげに大変です。

誰もやっていない！って考えた時にブルーオーシャンだ！と考えるのか、誰もやっていない理由がそこにはあるのか。そもそもすでにやっている企業があって、ちゃんと勝てる要素があるのか。

エンジニアはやってみたい思いだけで作れてしまうので、リサーチが足りないケースもよくあります。商品開発を仕事でやろうとすると、エンジニアスキルにプラスして、マネタイズ方法の手段や売上、利益をどこで確保するかの見積もりや知識が必要になります。

この知識の有り無しによって、次に必要な機能の確信度が変わってしまいます。この知識の理解はアーキテクチャの基盤の作りに影響を与える可能性があります。

### アイデアを出す、整理する

何はともあれ、アイデアです。
専業のプランナーの人は大小合わせて毎日何十ものアイデアを出すみたいです。
僕にはそんなに出来ないので、すごく大事なときだけ時間を取ってやります。

タイミングによってはチームのみんなと一緒にやるタイミングを取ります。
いくらでもやれるので、毎日やったりせずに、エンジニアのリソースを使う価値があるときだけやりましょう。

- ブレスト
- KJ法
- 曼荼羅アート
- オズボーンのチェックリスト

### プロダクトの価値を見極める

感性で出てきたアイデアの種が現実的にどのような価値を提供するのか？競合はどれほど居るのか？同一化と差別化の一覧化、バランス。何度も書いていますがリソースは限りがあるため、全ては実行できません。何を優先して実装するのかはココで決まり、売れるかどうかもこれで決まると思います。

- SWOT分析やP4や3Cなど
- マインドマップ
- リーンキャンバス
- エレベータピッチ

ここに上げたプラクティスは一部ですが、図として整理すると何を価値として、何が出来るのかが見えてきます。
そのための分析手法は多く存在すると思います。

### 価値を作り込む

- ユーザーストーリーマッピング
- バリューストームマップ
- カスタマージャーニー
- エクスペリエンスビジョン

### プロダクトの価値を伝える方法を考える (マーケティング)

いいものを作ったら売れる？それはたぶん幻想です。
口コミやソーシャルを狙うにしても、ソーシャルバズマーケティングの機能設計や口コミされやすい特徴的機能の盛り込みなどを戦略に含める必要があります。最近の食べ物でやりとりするサービスなど悪い意味で有名になってしまうサービスもありますが、法律などもチェックする必要があります。


### 事例の勉強

Webや本などで企画書や提案書が紹介されている時があります。
事例は自分の状況全てに当てはまるわけではないですが、何に気をつけて何に焦点を当てて判断をするべきかを理解しやすくしてくれます。

本だと

- シンプルに考える
- ピクサー流想像するちから
- スティーブ・ジョブズ
- Hotpepperミラクルストーリー

など


# ピープルマネジメント

結局最後は人がシステムを作ります。その個人がもっともパフォーマンスが出る状態とは何でしょうか？高いスキル？
それだけではありません。
モチベーションが100の状態の人と1の状態の人だと当然パフォーマンスは全然違います。
また、適材適所です。コード書くのがメチャ早い人にExcel業務をやらせたがる会社がありますが、コードをキレイに早くかける人はコードを書いてもらって、Excelは違う人に書いてもらうのがいいに決まっています。
また、本人の行きたいキャリアに沿った仕事はモチベーションも高いです。出来ることとやりたい事のバランスを取りながら仕事を任せましょう。

このように、個々に合わせたマネジメントをするのがピープルマネジメントです。
工程別に人間を管理するよりもっと細かくパフォーマンスを上げるための手を打っていく感じですね。

ざっくり書くと下のような技術です。

- ファシリテーション
- コーチング
- ストレングスファインダー

語りだすと、この１項目だけでも数時間語れるので割愛。
僕もすごく興味の高い部分です。


### 権限委譲、目標設定、評価

Management3.0なども出てきていますが、開発プロセスよりひとつ上のマネジメント手法がアジャイルの中でも広がりつつあります。

- デリゲーションポーカー
- ムービングモチベーターズ
- 12 Steps to Happiness
- OKR
- MBO
- 1on1

### ノウハウの組織化、仕組み化

アプリケーションシステムのデザインのように、組織も仕組み化して自動的に回るようにしなければ、いくら手があっても足りません。その時の観点や技術も多数あります。

- SECIモデル
- Google Work Rules
- ファシリテーション・グラフィック
- ヤフーの1on1
- あなたのチームは、機能してますか
- Joy Inc

など


# プロジェクトマネジメント

定義した仕事が順調に進み、実行されるようにしなければなりません。そのために必要な知識やチームへの関わり方、チーム外の関係者(ステークホルダー)の関わり方はそれだけで高いスキルを要します。それはエンジニアのスキルか？と問われれば別のスキルになります。
しかし、適正にエンジニアの課題を解決するためにはある程度の技術知識がなければ十分な解決方法を提案もできません。技術とソフトウェア開発の特性を理解しながらマネジメントするには、エンジニアがマネジメントするべきかと考えています。

### やりたい事の整理

やりたい事は無限に出てきます。
その中でやるべきものを決めるのは至難の業です。
プロダクトに於いてやるべきことはプロダクトの機能の提供だけではなく、システムのメンテナビリティなど、要件に出てこないシステムの堅牢性や柔軟性、エンジニアの気になることもあります。

スクラムでは２つのバックログが定義されていてこれを使い分けて居ます。

- プロダクトバックログ
- スプリントバックログ

私のチームのケースではやりたい事が多すぎて、全く動かないプロダクトバックログがリストを見づらくしていたため、鮮度とカテゴリによってリストを分割管理するようにしました。

- ビジネスバックログ (こうだったらいいな)
- プロダクトバックログ (機能としてこういう提供をしたい)
- スプリントバックログ (実行するべき作業タスク)
- システムバックログ (ビジネス側に交渉して作業リソースを確保する必要があるシステム課題)
- 気になっているバックログ (１日くらいの修正時間があれば改修可能なシステムの気になっているもの)
- インフラバックログ (アプリケーションエンジニアでは解決できない、専任インフラエンジニアに対応してもらう必要がある課題)

#### カテゴリの種別
- ビジネス関係 - システム関係
- 作業確定度 やることが決定しているもの - 時間があればやりたいと考えていること
- 作業専任者 アプリエンジニア - インフラエンジニア

この形がどんなチームでも正しいわけではありませんが、足りないものが多い状態で、スプリントを実行している最中でも優先度がガラッと変わってしまう、現状の開発状態だと、このようなリスト管理をしています。

### 会議運営

最初のアジェンダが重要です。そのための準備の時間も十分必要です。なにも考えずに集まっても何も生み出しません。

- 発散 (ブレスト、アイデア出し、課題の吸い上げ)
- 収束 (実行するべき優先事項、考慮するべきリスクの洗い出し、実行にかかるコスト見積もり)
- 合意 (実際に開発を実行するメンバーの理解、 目的の十分な説明)
- 共有 (情報共有を効率よく行うために一度に集めて行うもの、定期的にチェックや振り返りする会)

なんでもかんでも準備に時間を掛ければ良いものでもありません。時間リソースもあなたのリソースも限られています。会議の目的達成のためのレバレッジが効くバランスで実行する必要があります。

また、参加メンバーの選択もそれぞれの情報のフェーズごとに違います。目的とは会議の戦略です。アジェンダを立てればなんでもうまくいくものでもありません。アジェンダの粒度も目的を実行するために効率的になっているかを考えて実行する必要があります。
時間と共にチームや環境は変化していくので、会議のタイトルは同じであっても、内容や進め方は変化があるものです。続けていても不要な会議はドンドン辞めましょう。

### 参考本など

- アジャイルな見積りと計画づくり
- 職場の問題地図
- SL理論
- PMBOK
- CMMI

など

# システムマネジメント

技術的に尖った人はしばしば市場を無視した技術選択をしてしまうことがあります。
挑戦と安定はバランスが重要になります。

### 採用戦略

新しい技術を採用することは開発の効率性を向上させたり、エンジニアのモチベーションに多くの影響を与えます。しかし新しい技術ばかりを採用していては継続的なシステム運用や開発メンバーの獲得に大きな問題を抱えることもあります。

使おうとしている技術が市場でどのポジションに位置していて、チーム規模を倍にしたいときにどのような採用戦略が取れるか、単価がいくらぐらいになるか、採用できそうな期間と会社やプロダクト成長のタイミングで障害にならないような技術選定のバランスを取らなければなりません。

エンジニアの採用は１人数百万かかる高コストな仕事です。無邪気に人がほしいといっても、スーパーマンなエンジニアが現れるわけではないです。

また、魅力的なエンジニアの募集要項はエンジニアにしか書けないでしょう。
要件やキーワードだけ拾ってきて書いている募集要項の魅力では自社の魅力を十分伝えてるとはいい難いものになると思います。

### 技術的負債の受け入れと解消

技術的負債についての付き合い方は私の別記事で思いは書いてあるので、今回の文脈の箇所のみ書きます。

会社やプロジェクトの投資タイミングとシステムの成熟度はバッチリ合うことはありません。
それぞれの波を把握しながらシステムの機能を増やすタイミングとシステムの堅牢性を上げるタイミングを見極めなければなりません。

システムのリスクがどこにあるかを理解しながら、経営者やビジネスサイドに提案を行う必要があります。

プロダクトの価値を試したいだけならば最低品質でリリースを優先するべきで、もしその価値が確かめられたときにどのように行動できるかをイメージします。そこで試す価値が複数あるならば、しっかり時間を掛けて作るべきですし、１つの価値だけしか試せない機能ならば、使い捨てで作って、本格的な時に作り直す方法の方が良いかもしれません。

### 経営戦略の理解

決算書を読んだり、プロジェクトの理解をしましょう。
システムの状況と経営の状況は密接に関わります。しかしエンジニアが出来る範囲を超えています。しかし！！ビジネスの人たちもシステムを理解できていないです！

システムを作るには人が必要です。人が動くということはお金がかかります。お金がかかるということは経営を理解しなければなりません。みんなの手取りから想像できないくらいのお金が１人のエンジニアに掛かります。エンジニアが１０人くらい居れば、1000万円/月がザックリ消えていくと思ってもらうのが計算が楽で良いかと思います。そんなにズレてないと思いますし。

では、１ヶ月で1000万円の価値があるものが作れているのでしょうか？そう考えるとプロダクトマネジメントに返ってきます。効率よく作れているのでしょうか？そう考えるとプロジェクトマネジメントになってきます。やる気を持ってその人の最大のパフォーマンスで実装が進んでいるのでしょうか？そう考えるとピープルマネジメントになります。

社会や経済とエンジニアが繋がると勉強することがまた沢山出てきてしまいます。

### システムへの落とし込み

品質とリリーススピードはトレードオフです。
柔軟性や汎用性と専用性もトレードオフになります。

経営判断は１日で方向転換出来ますが、システムは作り上げるのに時間がかかります。
どのように作っておくかで市場への次の一手をどのスピードで打てるかが変わります。

ビジネスの価値を考えて、リリーススケジュールとシステム品質をトレードオフ出来るんです。
エンジニアのマネージャでなければソフトウェア品質を理解できないので、品質と何かをトレードオフすることは出来ません。
そうすると、スケジュール、スコープ(機能)、リソース(コスト)の３つのバランスだけで戦わないと行けなくなってしまいます。
もちろん４つのバランスでありながら数値化出来ないものをマネジメントするのは至難の業で、とても難しいです。でも価値を最大化しようと思ったら、やるしかないです！

- アジャイルサムライ
- RDRA
- DDD
- ICONIX

#### 継続的インテグレーション

最近ではほぼほぼ必須となっています。
それでもレベル感は存在します。dockerなどを使うにしても、ビルドのためのベースイメージなどを自作するかやよりスピードを求めてテスト並列化設定など。テストを並列化するにはテストを書く時にpersistenceな領域などの扱いなどをしっかり決めて、どのようなブロックで実行すれば並列可能になるかなど戦略が必要になります。
戦略を決めるのはCTOポジションですが、リスクを把握して周辺にアクションするのはVPofEの仕事です。完全に責任を切り分け出来るわけではないですが、それぞれのメインミッションを責任を持って果たすためにリソースをどこにかけるか計画して下さい。
ただ、なんとなくメンバーに任せると、どこまでもなんでも時間を掛けてできてしまいます。
価値にインパクトがある場所にメンバーの力を使えるようにしましょう。

#### リグレッションテスト

リスクのレベル感が分かります。ただし、インパクトがあるのは中長期的な開発に於いてなので、いつのタイミングでどれくらいのリソースを掛けるかは場合によります。
Unitテストだけをとっても、そのレベル感は数字では表せないところにあるのでコードを見てリスク判断しましょう。

- Unitテスト
- End to End (E2E) テスト
- Bot自動化テスト (ゲーム系など複雑なパターンが無限に増える時)
- 画面画像解析テスト (画面の変化をDiffとったりして、差分箇所だけレポートするなど)

SIとWebでは求められる品質の最低水準や契約におけるシステムの継続的なメンテナンス性などのポイントが違います。それらを理解してマネジメントする必要があります。これはビジネスの人ではExcelの数字しか理解出来ないですが、そういうもんじゃないと思っていて、エンジニアマネージャが必要だと常々考えています。

#### 技術ノウハウのシェア

早く作るには知っている人に任せれば良いですが、それでは組織の成長はありません。ビジネスや投資フェーズに合わせて、システム側で余裕がある時にはノウハウのシェアを実行しましょう。短期的な最速スピードばかりを求めていると中長期的な開発スピードやチームの安定性は低下します。

マネージャはただのタスクの配分機になっていたり、ただの伝言役ではありません。
短期に求められているタイミングと、中長期のシステムやチームノウハウのシェアリングは戦略的に行う必要があります。

- ペアプログラミング
- モブプログラミング
- タスクのローテーション
- SECIモデル

# まとめ

- プロジェクトマネジメント
- プロダクトマネジメント
- ピープルマネジメント
- システムマネジメント

それぞれの知識はエンジニアの技術とは別の組織のパフォーマンスを最大化するためのスキルです。
あくまでスキルであって習得にはそれなりに勉強する時間も掛かりますし、実践の中で洗練させる時間もかかります。エンジニアとしての技術力アップが王道の成長かと思いますので、前回のスキルには含めていないです。
エンジニアのスキルを勉強するだけで、正直いっぱいなのに、このエンジニアとしてのサブスキルを本気で仕事にしようとすると、これも死ぬほど時間が必要です。このあたりを雑にしか学ばずマネジメントしている環境も多くあるように感じていますが、これも明確なスキルだと考えています。

何を選ぶかは「あなたが何をしたいか」という、ただその一点に尽きると思います。
全ては学ぶことが出来ません。あなたの中で優先することは何か？を考えて、次のステップを考えてみてもらえたら良いかなと思います。

# あとがき

今回紹介した技術はエンジニアにとってメインミッションであるものか？と考えた時に少し違うなと思い、前回の記事には書きませんでした。
もちろん無いよりはあった方が良いですし、分かる範囲で沢山アイデアや意見を出してもらったり、考えたほうが良いです。しかし、本気でこれを仕事にしようと考えた時に、とてもコードを書いている時間は無いんです。今の自分の現状です(コード書くのも好きなんだけど悲しい。でも、これも楽しい)

技術を活かしつつも別の道への活かし方として、今回自分の考えを書かせてもらいました。
一つの意見として、何かのきっかけになればと思います。