Mobile Factory Tech Blog

技術好きな方へ!モバイルファクトリーのエンジニアたちが楽しい技術話をお届けします!

チーム横断の技術研修とは別で「プロダクト技術研修」をする

駅奪取チームエンジニアの id:dorapon2000 です。

弊社の今年の技術研修についての記事が何点か投稿されています。

tech.mobilefactory.jp tech.mobilefactory.jp

プロダクトで利用されているプログラミング言語、ライブラリ、RDBMSなどの技術研修を行っても、プロダクト開発を円滑に行うことは難しいです。プロダクトの仕様の理解が浅く、各機能のコードがどこにあるか把握できていないことが一因です。他にも、口頭伝承になりがちで毎年のコストになっていたことや、新機能開発に取り組んでも、プロダクト理解が浅ければ出るべき提案も出てこない問題もあります。

私達のチームでは、こういった問題を解決するため、チーム横断の技術研修とは別に「プロダクト技術研修」を4年前から実施しています。本記事では、そのプロダクト技術研修の紹介と実施にあたり大切にしていることを書きたいと思います。

何をしているのか

新人にプロダクトに関する課題を与えて解いてもらいます。課題の回答をメンター(私)がレビューし、設問の目的を達成できていれば次の課題を、達成できていなければその理由を説明し新人に修正してもらいます。後述しますが、課題文通りの回答になっているかではなく、お互いに目的を達成できていると納得した状態を目指します。

実際に用意している課題には3種類の設問があります。順に説明します。

  • 【遊び方】遊んでスクショを撮る
  • 【仕様理解】フローチャート・状態遷移図を書く
  • 【コードを追う】該当処理のコードがどこにあるのか追う

【遊び方】遊んでスクショを撮る

プロダクトを操作しながら指定されたスクリーンショットを撮ってもらいます。 私のチームで扱うプロダクトは、駅奪取という位置情報を使った駅の陣取りゲームですが、例えば、下記のスクリーンショットのように駅の路線を制覇(路線に属するすべての駅で位置登録)したときの達成画面をスクリーンショットしてもらっています。

工夫のポイントは、ユーザーが主要機能の内容をゲーム内のどこで把握できるのか、ドキュメントとしてはどこにまとまっているのか、併せて理解してもらうことです。そうすることで、課題で扱わなかった機能についても理解したいとき、同じ要領で自ら探せます。

【仕様理解】フローチャート・状態遷移図を書く

主要機能について、ユーザーからは見えないコードレベルで細かい仕様の理解をするために、コードを読み、フローチャート・状態遷移図に落とし込んでもらいます。【遊び方】の発展と言えます。

下記は「1週間以内に20km移動せよ」といった指令機能の状態遷移図です。素朴に考えると、ユーザが取りうる状態は、指令を達成しているか否かだけと考えがちですが、それ以外にも期限切れなどの状態があることを、状態遷移図を通して理解してもらいます。

工夫している点は、手間はかかりますが、自分の手でフローチャートを書いてもらっていることです。すでにあるフローチャートを読むだけでは、プロダクトのコードとフローを紐付けて理解することが難しいと感じています。

【コードを追う】該当処理のコードがどこにあるのか追う

指定した処理のコードがどこにあるのか、練習用のブランチ上でコメントしてもらいます。

この設問の目的は2つです。

  1. アーキテクチャ・実装の理解
  2. 自分が探している処理をソースコード上から見つけられるようになること

偶然見つけられたでは後者の目的を達成できていません。達成するために、実際にユーザーから見えるフロントエンドのコードから順に追っていき、目的のバックエンド側の処理を探してもらいます。課題文中では「トレース的に」と説明します。

例えば、ガチャの確率を決定するメソッドを探してほしい場合、ガチャを引くボタンを押して、リクエストが飛ぶエンドポイントを探し、そこからバックエンド側のメソッドの奥へ奥へと探索しながら該当コードを見つけられると目的達成です。以下は回答例です。

# 1. ここにガチャ抽選のHTTPリクエストがくる
sub dispatch_draw_gacha {

  # 2. ガチャの抽選処理
  my $result = Service::Gacha->draw($user, $gacha);
  ...
}

sub Service::Gacha::draw($self, $user, $gacha) {

   # 3. ガチャに入っているアイテム
   my $items = $self->select_gacha_items($gacha);

   # 4. ガチャの確率を決定する箇所【ここが課題の箇所】
   my $max_rate = sum0 { $_->weight } @$items;
   my $rate = Sub::Rate->new( max_rate => $max_rate );
   $rate->add( $_->weight => sub { $_ } ) for @$items;

   # 5. 抽選
   my $item = $rate->genereate();
   ...
}

実際の業務では、ユーザーからお問い合わせで不具合の報告があったとき、実際の処理がどうなっているのかコードレベルでの理解が要求されます。あるいは、既存の機能の拡張を行う際も、既存の機能を十分に理解する必要があります。そのための練習です。

何を目指しているのか

課題全体の目的は2つあります。これら2つの目的を達成することで、定常業務や新規機能開発にスムーズに参加できるようになることを期待しています。

  • 基本的な遊び方、仕様を理解すること
  • 各機能、処理のコードがどこにあるか自分で追えるようになること

1つ目はその通りで、自分は2つ目を大切にしています。

プロダクトの技術研修を終えた後もまだまだ未知の機能やコードがあります。それらをメンターや先輩、上司に積極的に質問して解決できることは嬉しいことではありますが、チーム全体のリソースを考えると自己解決できることも同じように大事です。2つ目の目的は課題の中で自己解決のノウハウを学んでもらうためにあります。【遊び方】で機能を理解できる場所を示したり、【コードを追う】でトレース的にコードをたどってもらったのもそのような意図でした。

内容は毎年アップデートしていく

基本機能はプロダクトの新規機能開発に伴って増えていきます。そのため、課題の内容にもアップデートが欠かせません。

しかし、内容のアップデートだけなく、課題文を洗練していくことも大切です。プロダクトに慣れているせいで初心者の視点が抜け落ちた不親切な課題文になってしまっていたり、曖昧な課題文で回答が1つに定まらない場合があります。新人が目的とはずれた場所で時間を浪費しないために、時間を浪費して自分自身を責めてしまわないように、課題文はアップデートをしていきます。

個人的に気をつけていること

去年と今年の2回、プロダクトの技術研修の担当をしました。この研修を活かすために意識していたことがあります。

まず、新人にプロダクトの技術研修の目的を知ってもらうことです。

  • 課題が解ければいいのではないこと
  • ユーザーからお問い合わせがあったとき、ドキュメントになっていない細かい仕様をコードを追いながら説明できるようになってほしいこと
  • 課題的には不要だったフローチャートも目的と合致しているから残しておいていいこと
  • インフラ起因のエラーに悩むことは目的と合致していないからすぐヘルプを出してほしいこと

そして新人が質問してきたこと・躓いたところを忘れないうちにメモしておきます。それらは来年の課題のアップデートの際に必要な材料になります。

最後に

プロダクトの技術研修としてプロダクト用の課題を準備していることについて紹介しました。

初回の準備は大変ですが、一度実施できれば、その課題を翌年以降にも引き続くことができます。準備された課題はチームの新人学習に対するノウハウでもあります。研修担当者が変わったとしても、同じ質で研修を実施できるでしょう。

見てくださった方の参考になれば幸いです。