【エンジニアの日常】エンジニア達の人生を変えた一冊 Part2

【エンジニアの日常】エンジニア達の人生を変えた一冊 Part1では大変ご好評をいただきました。

今回はPart2としまして、弊社エンジニアの人生を変えた一冊をご紹介いたします。

ぜひ、読書の秋のお供としてご参考にしていただければ幸いです!

人生を変えた一冊

SRE サイトリライアビリティエンジニアリング
―Googleの信頼性を支えるエンジニアリングチーム

こんにちは。ファインディでSREを担当している大矢です。ファインディ一人目のSREとして入社し、SRE歴は8年目になります。

「Site Reliability Engineering -- How Google Runs Production System」の日本語訳は、多くのエンジニアに愛読されている名著です。

GoogleのSREチームの取り組みも書かれており、これからSREを目指す方はもちろん、既にSREとしてご活躍されている方も、まだ本書を読まれていないようでしたら是非一度手に取って頂きたい一冊です。

私はかつて2010年代前半から中盤まで大規模なシステムでインフラエンジニアとして働いていましたが、実際はSREに近い業務を担っていました。

同システムでは開発メンバーとのコミュニケーションは活発でモニタリングやCI/CDも導入していましたが、運用面に対して次のようなプレッシャーを感じていました。

  • システム変更に対する失敗は許容されない
  • 手作業による環境構築や運用が多い
  • 24/7でのオンコール担当

これらのプレッシャーに対する答えの1つが「SRE Book」でした。

この本ではSLIやSLO、エラーバジェット、ポストモーテム、トイルといったSREにとって重要な概念や、オンコール体制の考え方が解説されています。

例えば前述のプレッシャーに対しては次のようなアプローチをとることができます。

  • SLI/SLOを定めエラーバジェットに基づいた運用をおこないポストモーテムを活かす
  • トイルを減らすため自動化を進める
  • オンコール体制は適切な人数で適切な持ち回りを行う

上記は当たり前のことかもしれませんが、私自身の考えを整理するうえで強力な後押しをしてくれました。

ところで、ファインディではプロダクト毎にSLI/SLOを設定しエラーバジェットに基づいた振り返りを推進しています。

弊社SREチームは立ち上げから日が浅いですが、これからもこの一冊で得た知識を活かし、ファインディのサービスをより信頼性の高いものにしていきたいと考えています。

プログラマが知るべき97のこと

開発推進チームで、RubyとRustとTypeScriptを書いているバックエンドエンジニアの西村です。エンジニア歴は4年目です。

この本はエンジニアとして仕事していく中で素晴らしい知見を共有してくれるエッセイ集です。 エッセイ集であるため、タイトルが気になるエッセイから読んでいく形でも問題ないです。

どのエッセイも経験豊かなエンジニア達が執筆しています。例えば、システム設計に熟練したエンジニアやプログラミング言語のコミッタが執筆している豪華な一冊になっています。

エッセイのテーマは、リファクタリング、設計原則、エンジニアとして仕事をしていく姿勢、テスト等の様々なものがあります。

この本を読んだきっかけ

私がエンジニアとして働いて半年ほど経った頃、自分の理想の姿へ近づくために、どうすればいいのか分からなくなった時期でもありました。

そんな中、毎週通っていたジュンク堂書店池袋本店でたまたま「プログラマが知るべき」という文字が目に入って、この本を読み始めました。

次のエッセイを読んで、自分がどうすればいいのかを思いつくきっかけになりました。

当時の私を助けてくれたエッセイは次のものです。

Clint Shankさんのエッセイ「学び続ける姿勢」

このエッセイでは、自分自身で学び続けるために、書籍やインターネットを利用した学習やレベルの高い人と仕事をすることなどが推奨されています。

また、技術の進化に対応できるように、常に学び続ける重要性についても書かれています。

このエッセイを読んで、当時は次のことを毎日欠かさずやっていました。

  • 仕事でわからなかったライブラリのメソッドや仕組みをその日のうちにライブラリのドキュメントを読む
  • ライブラリの挙動を理解するためにローカルPCでコードを動かす

このエッセイにある「普段利用しているライブラリについての知識を深める」という記述を参考にしていました。

現在、数ヶ月前から新規プロダクトでRustの検証をしています。そんな中、Rustのことをもっと知りたいと思い、Osaki.rsというコミュニティを立ち上げて、勉強会を開催しています。

この勉強を立ち上げた背景のひとつに、このエッセイにある「勉強会を自ら立ち上げる」という記述を参考にしています。

このOsaki.rsは、connpassのメンバー数が40人ほどになりました。これからもRustの勉強会を続けていきます。

Karianne Bergさんのエッセイ「コードを読む」

このエッセイでは、エンジニアが他のエンジニアや自分の過去のコードを読むことの重要性について述べられています。他のエンジニアが書いた読みやすいコードを読むことで、自身の成長につながると強調されています。

また、過去に自分が書いたコードを読み返すことで、スキルの向上を確認でき、さらなるやる気が湧くとも述べられています。

このエッセイを読んで、当時は次のことを毎日欠かさずやっていました。

  • 自分が関わるプロダクトのリポジトリの全てのプルリクエストに目を通す

チームメンバーが作成したプルリクエストを読むことで、チームメンバーがどのようなコードを書いているのかを知ることができ、自分のスキルアップにつながると考えていました。

現在、Rustらしい書き方と読みやすいコードの書き方が分からない時、スター数が多いライブラリのソースコードを読んで、Rustらしい書き方を日々学んでいます。

この本から学んだこと

上記のエッセイを読んで、当時悩んでいた自分がどうすればいいのかを思いつくきっかけになりました。

ぐずぐず悩んでなにも動かないより、少しだけでもいいから知らなかったことを潰していく・挑戦していくことの大切さを学べたと思います。

キャリアやこれから何を学ぶ?と悩んだときは、今でもこの本を読み直します。 また、定期的に書店へ行って、素晴らしい書籍を探しています。

Clean Coder プロフェッショナルプログラマへの道

2024年4月にファインディへ入社して、Findy Tools の開発をしている林です。

私からは Clean Coderプロフェッショナルプログラマへの道 という本を紹介します。

私はエンジニアとして働き始めて2年目に本書を読みましたが、自身が業務の中で感じていた課題とその解決策のヒントの多くを得られました。

そして、この本の考え方が日々の業務に大きな影響を与えてくれたと考えています。

本書は、タイトルの通り「プロフェッショナルプログラマ」になるための技術的なスキルだけでなく、コミュニケーション力やエンジニアリングに対する向き合い方などのソフトスキルに焦点を当てて紹介されています。

ここでいう「プロフェッショナル」とは、「責任を取る」姿勢を持つことと定義されています。これは、エンジニアが求められた仕様を実現するためのコードを書くだけでなく、最終的にビジネスの成果を達成する責任を果たすことを意味します。

本書では、エンジニアが直面しやすい具体的な課題とその解決策が解説されています。例えば:

  • プロダクトにバグが生じる

    • テスト駆動開発(TDD)や、効果的なテスト戦略の構築が重要。
  • 無理な要求や納期に間に合わない場合

    • 明確に「ノー」と言い、仕様を交渉することがプロの姿勢。
  • 精度の高い見積もりができない

    • PERTやプランニングポーカーなどで具体的な数値を挙げ、現実的な見積もりをする。
  • チームワークの問題

    • プログラミングは一人で完結するものではなく、他者との円滑なコミュニケーションが不可欠。

特に印象に残ったのは、本書の第2章にある無理な要求に対して「ノー」と言うことの重要性です。

私は本書を読む前、プロフェッショナルなエンジニアとは、どんな要求にも対応する技術力を持つべきだと考えていました。

しかし、本書を読んで、「できないことは断る」ということもプロフェッショナルの責務であることに気づかされました。

さらに、「試しにやってみる」という曖昧な言葉も問題視されています。

このフレーズは、調査の時間を指しているのか、あるいは実装を試すことを意味しているのかが不明瞭で、誤解を招きかねません。

私自身、何気なく使っていた言葉なのでより明確に何が問題で何をするのかを具体的に言うようにしました。

本書の内容は一朝一夕で身につくものではありませんが、私は業務で困ったときに何度も読み返しています。

特に、最近エンジニアになった方や「プロフェッショナルとは何か?」と漠然としている方にとって、強い指針となる一冊です。ぜひ手に取ってみてください。

まとめ

いかがでしたでしょうか?

ファインディでは一緒に会社を盛り上げてくれるメンバーを募集中です。興味を持っていただいた方はこちらのページからご応募お願いします。

herp.careers

Findyのエンジニア爆速成長の事例 2024年夏

こんにちは。こんばんは。 開発生産性の可視化・分析をサポートする Findy Team+ 開発のフロントエンド リードをしている @shoota です。

先日、END【フルスタックエンジニアへの道!】React と TypeScript の修行をした話 というタイトルで、フルスタックエンジニアを目指すためのフロントエンドの修行の記事を投稿いたしました。 こちらの記事では React / TypeScript において個人学習程度のレベルにあった END が、機能開発を自走可能になるまでの内容が書かれています。

そこで本記事では、END の成長と挑戦をサポートし、実際に指導にあたった私がメンター視点での話をいたします。

育成のはじまり

Findy Team+の開発メンバーはバックエンド・フロントエンドにそれぞれ主軸を置きつつ、多くのメンバーがその垣根を超えた貢献ができることを目指しています。 そのなかでバックエンドを主軸としていた END がフロントエンド領域に集中して挑戦したいという話が持ち上がりました。

フロントエンドメンバーの比率が少なく、「片手間ではなく集中して挑戦する」という決意もあり、自分としても前向きに指導担当をさせてもらいました。

下準備

ゴール設定

急に育成をするとなっても何となく始めてしまうとちゃんと成長できているのか、育成をサポートできているのかどうかがわからなくなります。 まずはじめに私がしたのは、エンジニアリングマネージャー(EM) とのすり合わせでした。

具体的には次のような質問から「どのくらいの時間でどこまでできるようになるのか?」をある程度の幅で決めていきました。

  • メンティーが目指すゴールはどのレベルか?
  • EM の期待するゴールはどのレベルか?
  • どれくらいの育成期間をとるか?

ゴールのレベルもざっくりと 3 段階を想定しました。

  1. 基本はバックエンドを主軸としつつも、状況にあわせてフロントエンドも書けるようになりたい
  2. バックエンド・フロントエンドに分け隔てなく両輪で活動できるようになりたい
  3. フロントエンド主軸に移りたい

結果 2 番目のレベルをイメージしながら、「フルスタックな動きをキャリアの目標として想定しつつ、まずはフロントエンドを自走できるレベル」「とりあえず 3 ヶ月」で目指してみようとなりました。

助走をしてもらう

もともと個人で React は書いたことがあるといっても、Team+の膨大なコードの前に立つとなかなかどこから手を付けたらよいかと不安になるものです。 なのでまずはメンティーの心の準備体操として、フロントエンドの考え方をまとめた読み物を書きました。

読み物

MVC アーキテクチャやオブジェクト指向といった馴染みの概念と照らしながら、どんなパラダイム・シフトが待っているのかをブログのように書いておきました。 このほか、これまでにもフロントエンドの設計や React の思想などに関する社内記事を書いていたので、それらも合わせて共有しておきました。

実践

育成の方針と実践

自分で調べたり考えたりしたことがいちばん身につくので、基本的には寄り添い過ぎず、私のなかでいくつかのゲートを設けて見守ることを計画しました。

私はこれまでもジュニア層のフロントエンドエンジニアの育成経験があったので、これらのゲートが多くの人がぶつかる壁であることを知っており、これをクリアできてそうかをみながらサポートの強弱をつけていく算段です。

成長ステップ

  1. React に Props を渡して単純な HTML を出力するコンポーネントを書ける
  2. コンポーネントを組み合わせた大きなコンポーネントを型を含めて書ける
  3. ユーザーインタラクションのハンドラーを純粋な関数として書ける
  4. バックエンド API との通信インターフェースを理解し、コード生成ができる
  5. データとコンポーネント間を TypeScript をつかって型安全かつ整合してつなぐことができる

多くの場合に Step. 3 と Step. 5 がよく詰まるポイントで、ここを乗り切るための知識や理解のための伏線を張っていくように、ドキュメントなどをプルリクエストや Slack でどんどん渡していきました。 特に Step. 5 がジュニア層の鬼門で、それまでの React Component の積み上げと API の型定義を同時に整理しなければならないため、データとビジュアルの責務分離、そのための関数と型の設計などで苦戦します。

渡した資料の中で、誤読しやすいものや前提知識が多く必要なものは口頭で補足するなどしながら、これまでの理解度を測って次のステップに必要なものを選んでいくようにしました。 こうして Step. 5 を乗り越えるための理解が積み上がるように進路補正をしていきました。

トレードオフ

このように挑戦するメンティー側にはいろいろな壁を超えるための頑張りが必要になってきますが、一方でサポートするメンター側も、自分のパフォーマンスを維持し続けるのが難しくなってきます。 どれくらいの厚みのサポートが必要かは個々人によって違いますが、少なくともメンターの 20%くらいはサポートに力を注ぎたいものです。

Findy では Findy Team+ を使って自分のパフォーマンスを計測する習慣がありますが、私は育成に際してこの数値がある程度は落ち込むことを覚悟の上で、その落ち込み幅をできるだけ小さくすることにも挑戦していました。

私のマネージャーにもこの想定の落ち込み幅のすり合わせをし、育成と自己パフォーマンスのバランスをとっていることを 1on1 などで話しています。

パフォーマンスを可視化することで数値の変動にきちんと理由付けをできるのが Findy Team+ を使っていく最大の利点です。

3 ヶ月の成果と分析

プルリクエストの可視化

実際には想定よりも成長速度が安定していたので最初の 2 ヶ月弱で設定したゴールに到達しそうでしたが、とりあえずはそのまま 3 ヶ月間みっちりと進めてみました。

難易度が高すぎないタスクを中心に実施してもらってはいたものの、最終的にフロントエンドへのプルリクエスト数は私とほぼ同等かそれ以上が出せるようになっていました。

Team+のグラフで可視化してみると次のようになりました。

青が私、オレンジがEND

メンティーの分析

先ほどのメンター(私)とメンティー(END)の両方の PR 作成数でした。これをメンティー(END)だけに絞ると、中盤に数値の谷があります。 実はこれが狙い通りで、前述の想定した Step と期間を照らし合わせることで成長の過程が見えてくるようになります。

育成方針とパフォーマンスの谷

はじめは単純な HTML 合成のための Component 作成(Step. 1, 2)で伸びていく数値が、ユーザーインタラクションの実装 (Step. 3) が始まると徐々に鈍化していきます。

インタラクションの実装に慣れてくるとバックエンド API との連動 (Step. 4) のイメージもつきやすきなってきますが、いざこれらをつなごうとすると考慮することが一気に増えるため、数値が下がっています。 そしてこの鬼門を乗り越えると、またぐんぐんと順調に伸びていく事がわかります。

メンターの分析

次に自分がメンターをしている期間にどれくらいのパフォーマンス影響があったかを見てみます。 同じ期間での私の PR 作成数をグラフにすると、何ともつまらないくらいに変化が少ないグラフになりました。

メンターのPR作成数

しかしこれには秘密があります。

まずメンターを始めてからメンティーのプルリクエストはすべてレビューしており、すぐに自分のパフォーマンスに対する影響を感じていました。 具体的には次のようなことを、プルリクエストがあがるごとに都度実施していたためです。

  • 設計意図を汲み取りにくい構造になっている部分を読み解く
  • 厳密でない型定義によって型チェックをすり抜けている箇所がないかチェックする
  • 指摘内容とともに実装サンプルを書いたり、その理由を示すリファレンスを探して提示する。

そこでマネージャーと相談して、自身のプルリクエスト作成数が 4 以下にならないように水準を維持していくことを宣言し、レビューの濃度を調整していったのです。 (それまでの私の平均プルリクエスト作成数は 5.6〜5.8 程度でした)

「そこまで狙い通りにプルリクエスト数を調整できるものか?」と思われるかもしれません。

しかし自分のパフォーマンスを落としては開発が進まず、また一方でメンバーの成長にも投資しなければ全体の生産性が高まりません。この実績と投資のバランスを自分の数値を軸にすることで全体最適を図っていったのです。

もっと自分がプルリクエストを書ける状況でもその分は育成への投資に使いました。こうしてマネージャーと合意したパフォーマンスを維持しながら、最大限の育成を進めるのは意外と難しくありません。

所感とまとめ

今回の育成期間の全体を通して、おおむね計画どおりに進めることができました。もちろんメンティーのポテンシャルの高さやメンターの経験もあってのことですが、次のような点が成功への道しるべになったと思います。

  • メンティーのゴール設定を 技術リードとエンジニアリングマネージャーの両者 で合意してから開始したこと
  • 適切なステップとぶつかる壁を用意したこと
    • 成長のための「適度なストレス」を感じ続けられるようにすることで、モチベーションを維持
    • 最も大きな谷を超えるための準備としてサポートを意識した
  • メンターのパフォーマンスへの影響とその保証ラインも適切に設定し、そのパフォーマンスラインを指標として サポートの厚みを可変できるようにしたこと

これらによって、開始時に設定したゴールを超えて爆速で成長してもらえました。

卒業の様子

最後に、「メンティーの分析」であげた END のプルリクエスト作成数グラフをもう一度みてみると、非常にゆるやかなダニングクルーガー曲線になっており、非常に興味深いなと思いました。

成長したいエンジニアを探しています!!

バックエンド主軸のあなたでもフロントエンド開発を自走できるレベルまで成長することが出来ます。

もちろんフロントエンドが大好きなあなたも、リードエンジニアを目指してスキルアップできることでしょう!

ぜひ、ご応募お待ちしております (∩´∀ `)∩

herp.careers

Findyの爆速開発を支えるPull requestの粒度

こんにちは。

Findy で Tech Lead をやらせてもらってる戸田です。

既に皆さんも御存知かと思いますが、弊社では開発生産性の向上に対して非常に力を入れています。

以前公開した↓の記事で、弊社の高い開発生産性を支えている取り組み、技術についてお話させていただきました。

tech.findy.co.jp

ありがたいことに、この記事を多くの方に読んでいただき反響をいただいております。

そこで今回は、↑の記事でも紹介されている「Pull requestの粒度」について更に深堀りしてお話しようと思います。

Pull requestの粒度は、弊社にJOINしたら最初に必ず覚えてもらう最重要テクニックの1つです。

それでは見ていきましょう!

大きなPull request

Pull requestのレビュー依頼が飛んできて確認したら、大きなPull requestでブラウザをそっと閉じた経験がある方は少なくないと思います。

大きなPull requestにおけるデメリットは数多く存在します。

パッと思いつくデメリットを列挙してみます。心当たりがある読者の方もいるのではないでしょうか?

  • topic branchの生存期間が長くなり、結果的にbase branchとの差分が大きくなりconflictの発生確率が高くなる
  • 変更内容が多岐に渡るため、問題発生時の原因特定に時間が掛かってしまう
  • revert時に余計な内容までrevertされてしまう
  • レビューの質が落ちる
    • レビュワーが見るべき範囲が広くなるため、認知負荷が大きくなる
      • あとで見とこ、、、となりがち
        • 結果的にtopic branchの生存期間が長くなる
        • base branchとの差分が大きくなる
        • conflictの発生確率が高くなる
    • 指摘内容が増え、結果的に手戻りが増える
  • etc

このようにデメリットは数多く存在します。システム開発において大きなPull requestの存在は、円滑な開発を阻害する要因となるでしょう。

では「大きなPull request」とは具体的にどんなPull requestのことを指しているのでしょうか?

適切な粒度とは

ここでサイズと粒度の違いを説明する必要が出てきます。

そのPull requestが1つのことに注力できているかどうかが、粒度を語る上で非常に重要なポイントになります。

Pull requestのサイズとは、コードの変更行数や変更ファイル数のことを指します。

しかし、コードの行数や変更ファイル数が多かったとしても、変更内容が一意であれば問題ないはずです。

例えば、関数名を変更して一括置換した場合を例に挙げましょう。変更ファイル数は多くなりますが、変更内容は一意です。

こういったケースの場合、Pull requestの概要欄に一括置換した旨を記載しておけば、変更内容を全て確認せずとも変更後の関数名をレビューし、CIが通ればマージ出来るはずです。

一方、Pull requestの粒度とは、コードの変更内容のことを指します。

例えば、変更ファイル数が少ない一方、データ取得・データ加工・描画処理を同じPull requestで対応した場合を例に挙げて考えてみましょう。

この場合、それぞれの処理は全く異なる内容です。しかし同じPull request内で対応してしまったため、変更内容全てを一度にレビューする必要があり、レビュワーに対する認知負荷が大きくなってしまいます。

極論ですが、たとえ変更行数が1万行を超えていたとしても、変更内容が一意であれば問題は無いと考えています。

逆に変更行数が20行程度の不具合修正の中に「ついでにリファクタ」した内容が含まれていた場合、粒度が大きいと判断しPull requestを分割すべきなのです。

なぜならば、もし不具合修正に失敗していてrevertしようとした際に、ついでにリファクタした内容もrevertされてしまうからです。こういったケースの場合、リファクタをしたPull requestを別で作成します。

つまり本質はコードの変更行数や変更ファイル数ではなく、変更内容そのものにあるということを理解できたかと思います。

粒度が適切であれば、1行だけの修正でも、1万行の修正でも問題ありません。

10のプルリクを1回レビューするよりも、1のプルリクを10回レビューする方が、作成者、レビュワー共に負担が少ないのです。

適切な粒度を維持するために

タスク分解

Pull requestの粒度について完全に理解したので、これからは適切な粒度でPull requestを作るぞ!と思い立っても、すぐに実現させるのは難しいものです。

理解はしているけど、やってみるとやることがどんどん増えていき、結果的にPull requestが肥大化しがちです。

それを解決するのがタスク分解です。概要は↓のページを参照してください。

tech.findy.co.jp

タスク分解に関しても、別の機会で詳細にお話できればと思います。

迷ったら小さく

とは言え、最初のうちは粒度に対して悩むことが出てくると思います。

もっと作り込んでからレビュー依頼を出す?それとも今の段階で出す?でも修正内容が小さすぎないか?などといった葛藤は自分にも経験があります。

そういう時は、より小さい粒度の段階でレビュー依頼を出すことをオススメします。レビューのやり取りの中で粒度に対する議論を行い、そこで認識を合わせればOKです。

Pull requestを大きく作って後から分解するより、小さく作って後から修正内容を追加する方が圧倒的に楽だからです。

まずは小さすぎても良いので小さく作り、そこから肉付けしていくようなイメージでPull requestを作成していくと良いでしょう。

レビューを最優先にする

Pull requestの粒度が小さくなった場合、レビュー依頼に対して最優先で取り組む必要があります。

なぜならば、マージしないと次の修正に着手出来ない場合に、レビューがボトルネックになり結果的に開発スピードが遅くなってしまうからです。

自分の作業を一時中断して、10分程度レビューして自分の作業に戻るとコンテキストスイッチを戻すのが非常に難しいと思います。

でも心配しなくてよいです。Pull requestの粒度が適切であれば、レビュワーが確認する内容も小さくなるためレビューに掛かる時間が短縮されます。

そのため、自分の作業を一時中断することになったとしても、すぐまた自分の作業に戻ることができるようになります。

弊社では1つのPull requestのレビューに掛ける時間はほんの数分程度となっています。1分以内で終わることもあります。

粒度が適切なPull requestが当たり前となれば、レビューを最優先にする習慣、文化が組織に根付くはずです。

CI高速化

粒度が小さくなってくると、当然ながら作成されるPull requestの数が増えます。つまりCIの実行回数も比例して増えていきます。

CIの実行回数が増えた状態で実行速度が遅いと、逆に開発効率が落ちてしまいます。CIが遅いからPull requestの粒度も大きくなってしまうといったケースも見たことがあります。こうなってしまうと本末転倒です。

そこでCIの高速化も同時に進めた方が良いでしょう。詳細はこの記事では割愛しますが、↓の別記事を参考にしてみてください。

tech.findy.co.jp

feature flag運用

Pull requestの粒度は適切にしたいが、本番環境には影響を出したくない。というパターンはfeature flagを使うと良いでしょう。

ローカル環境でのみ実行されるようなコードにしておいて、その状態を維持しつつbase branchにマージし続けます。本番公開OKのタイミングでfeature flagを解除し、本番環境に反映します。

feature flagの運用方法はSaaSを使う、ライブラリを使うなどの方法がありますが、今回は一番カンタンに導入できる方法の、コード上にフラグを埋め込んで切り替える手法を紹介します。

実際にコードの例を見てみましょう。

export const SampleComponent = () => {
  const isEnabledNewLabel = process.env.FEATURE_NEW_LABEL === 'true';

  return (
    <div>
      {isEnabledNewLabel && <span>NEW</span>}
      <span>Sample</span>
    </div>
  );
};

環境変数に埋め込まれている FEATURE_NEW_LABEL の値によって、 NEW の表示を切り替える単純なcomponentです。

この仕組みにより、ローカル環境の環境変数をtrue、本番環境の環境変数をfalseにすることで、本番環境に影響を与えずに新機能の開発を進めることが可能になります。

開発が完了して本番環境に反映する際には、本番環境の環境変数をtrueにすることで新機能を公開できます。何かしらの問題が発生した場合、本番環境の環境変数をfalseに戻すことで、新機能を非公開に変更可能です。

本番環境で問題が起きなければ、環境変数のフラグとコード上の分岐を削除します。

この手法はfeature flagの管理が煩雑になったり、コード内の分岐やテストケースが増えるといったデメリットもありますが、Pull requestの粒度を適切に維持するためには非常に有効な手段です。

本番環境に影響を出さずに、Pull requestの粒度を適切に維持し続け、スピード感を持って開発する手段の1つとして活用してみてください。

topic branch運用

様々な事情によってfeature flagを使えない、使いたくない場合の手段として、topic branch運用を紹介します。

topic branch運用

base branchからtopic branchを切って、そこから更にdevelop branchを切ります。develop branchからtopic branchへのPull requestを作成し、そこで粒度を維持しつつレビューをします。

本番反映OKのタイミングでtopic branchからbase branchへのPull requestを作成し、マージします。このタイミングでのレビューは必要最低限でOKです。なぜなら、develop branchからtopic branchへのPull requestでレビューしているからです。

この手法により、base branchにはリリースのタイミングまで変更内容が反映されません。そのため本番環境への影響を与えず、Pull requestの粒度を適切に維持し続けることが可能になります。

定期的にbase branchからtopic branchへ変更をmergeしておくのがポイントです。topic branchの生存期間が長くなるので、base branchとの差分が大きくなりconflictが発生しやすくなるからです。最低でも1日1回はbase branchの修正内容を取り込んでおくと良いでしょう。

まとめ

いかがでしたでしょうか?

粒度を適切に維持することで、レビュワー、レビュイーの両者に対して優しいPull requestを作成し続けることができます。

弊社では最重要テクニックの1つとしていますが、比較的カンタンに覚えることができ、コツさえ掴めば誰でも実践できる内容です。

是非、皆さんも試してみてください。

現在、ファインディでは一緒に働くメンバーを募集中です。

興味がある方はこちらから ↓ herp.careers

【フルスタックエンジニアへの道!】ReactとTypeScriptの修行をした話

こんにちは、ファインディでFindy Team+(以下Team+)を開発しているEND(@aiandrox)です。

普段はバックエンドの開発をメインで担当しているのですが、3ヶ月間フロントエンドの開発に挑戦する機会がありました。短い期間でしたが、フロントエンドテックリードから直接指導してもらいながら実装をすることで、フロントエンドの開発を一人でできるくらいに慣れることができました。

今回は、その経験と学びについて書いていきます。

フロントエンドに挑戦する前の自分について

もともとはバックエンド(Ruby on Rails)の開発をメインでしていました。

前職では特にバックエンドとフロントエンドが分かれておらず、Rails View / CoffeeScript / FlowType / jQuery / Reactの混在したフロントエンドを触っていました。また、個人開発でReact / TypeScriptを触ったことはあったものの、あくまでも動くことを重視していたため、アーキテクチャの意識はあまりしていませんでした。

Team+のフロントエンドでは、前年に修正プルリクをいくつか出したので、アーキテクチャはなんとなく把握していました。しかし、既存の実装を踏襲したまま一部を修正する程度だったので、新規でComponentを作ったことはありませんでした。

フロントエンドに挑戦することになった経緯

もともと個人開発などもしていたので、フロントエンドへの興味もありました。将来的にはフルスタックエンジニアとしてスキルを広げたいという思いもありましたが、まずはバックエンドの技術を身に付けることを優先していました。そんな中、「フロントエンドの手が足りないんだけどやってみない?」という提案がありました。

いい機会!ということで、「やりたいです〜」「テックリードと一緒にやってもらおうと思ってます」「やったー」とトントン拍子で進んでいきました。

フロントエンドを学ぶ上で助けられたこと

フロントエンドに挑戦するにあたり、以下のサポートがあることにより、スムーズに実装を進めることができました。

フロントエンドのノウハウが溜まった記事の充実

社内記事に「フロントエンドを書くときに何を考えているか、どうしているか」というものがあり、これを参考にできました。「データ層を扱うものはデータ層の責務に閉じ込め、プレゼンテーション層は見た目に注力する。つまり、Pureな Presentational Componentは原則としてロジックを持ってはならない」といった基本的な考え方と、実際に画面を作るときの作業工程を書いていたので、とても役立ちました。

基準の考え方があったので、迷ったときにこれに立ち返ったり、「この場合はどうなのか?」と具体的に質問することができました。

開発ツールが揃っている

開発中はJavaScriptの統合テストツールWallaby.jsを使用していたので、デバッグがスムーズに進み、開発作業が非常に効率的になりました。

tech.findy.co.jp

また、CIによって一定の品質が自動的に担保されるので、レビュー前に自分で気付けることも多かったです。ESLintは実装に寄ってくれている感じがあり、hooksの依存などを自動で補完してくれるため初学者としては安心できました。

テックリードとマンツーマンでタスクをやっていく

テックリードとは同じチームなので、朝会で進捗の共有をするとき悩みポイントを共有したりしていました。また、実装方針に悩んだときは分報チャンネルに投げて拾ってもらったり、都度ペアプロなどでサポートしてもらいました。

また、自分が作成したプルリクに関してはすべて見てもらっていたので、私の理解度を把握されていました。そのため、プルリクの実装についての指摘や、理解度が浅そうなところなどがあったタイミングで呼び出していただきました。都度口頭で説明されたり自分からも「この理解で合ってます?」と壁打ちすることで、具体的な話から理解度を高めることができました。

※「体育館裏」は一見怖そうに見えるかもしれませんが、怒られたりすることはありません。コワクナイヨ

react.devの輪読会

もともと、フロントエンドをメインとするメンバーでReact公式のLearn Reactの輪読会を行っていたので、自分も途中から参加するようになりました。

書かれている文章だけだと言葉や概念が難しかったのですが、輪読会では具体的な解説があったりわからない点を質問できたりしたので、実践を理論で補強できました。これにより、プルリクで指摘された内容について「つまりそういうことなのか」と理解できるようになりました。

つまづいた点

タスク粒度を適切に分割すること

バックエンドに関しては、技術的にもドメイン的にも慣れているので、1つのクラスごとにプルリクを作成することができていました。しかし、フロントエンドに関しては、ローカルの画面で動く状態まで実装すると大きすぎるプルリクになることがありました。

これを解消するために、1つずつ実装した箇所のテストを書くことで安心してプルリクを出すことができました。バックエンドでは当然のように考えていたことでしたが、フロントエンドではつい画面でのデバッグをしようとする心が働いてしまっていたことを自覚しました。

また、最初はComponentを分割して実装するという意味をあまり理解できておらず、中途半端な状態で1プルリクにしたりもしていました。

Team+のフロントエンドの責務の考え方

フロントエンドの設計は以下のようになっています。

コンポーネント名 カスタムフック名 扱うデータ
Page Component Params Hook ブラウザURL
Container Component Facade Hook API や ストレージ等
Presentational Component Presenter Hook フォーム

Findy転職フロントエンドの開発生産性を向上させるためにやったこと - Findy Tech Blog

この思想をなんとなく頭に入れていたものの、実際に実装している途中で、「この記述はFacadeで書くべきなのか、Presenterで書くべきなのか」と迷うことがありました。

例えば、GAトラッキングの記述を最初はFacadeに書いていたのですが、「GAの実行はUIのクリックアクションをトリガーとするので、Presenterに書くのが適切」といったフィードバックを受けました。propsで渡された関数をPresenterでwrapするといったやり方が、最初は選択肢になかったので、新鮮に感じました。

また、ContainerからContainerを呼んでいる場合もあり、どのようにコンポーネントを分割するべきか迷う場面もありました。画面内のAPIを基準にFacadeを分割し、それに応じてContainerを組み立てていくとわかりやすかったです。

TypeScriptで慣れる必要があったこと

今まで書いてきたRuby / Railsと比較して、TypeScriptには型があるというのが大きな違いですが、個人的にはその堅牢さの中でJavaScriptの関数などを使いこなすのが難しかったです。

例えば、以下のような点です。

  • nullundefinedだけでなく、0もfalsyな値になる
  • 配列に対してfindを実行すると戻り値がundefinedになりうるため、必ず値が存在する場合にfindを使うと、型と実態が合わなくなってしまう

3ヶ月の挑戦の成果

この機会に、1つの新機能をテックリードと2人で分担して開発しました。私は、以下のような一覧画面と分析画面をそれぞれ2画面ずつ担当しました。

一覧画面

分析画面

また、安定してプルリクを作成することもできるようになりました。

この3ヶ月を通して、React全体やTeam+のフロントエンドでの設計思想を学び、コンポーネントの責務の分離や状態管理の方法について、実践を通して理解することができました。これにより、他のエンジニアへのレビューもある程度自信を持って行えるレベルになりました。

改めて感じたのは、ただ動けばいいのではなく、Reactで可読性・設計を考慮したコードを書くのは難しいということでした。記述方法の自由度が高い分、意図を設計として乗せる必要がある(テックリードからの受け売り)というのを実感しました。

自身の伸びしろ

今回の挑戦では表示するデータを取得するものばかりだったので、フォーム処理やデータの更新などに今後は積極的に挑戦したいです。

また、react.devの輪読会や共通コンポーネントを変更しようとしたときに、自分の実力不足を感じました。TypeScriptの知識不足や型の伝播を読み解けなかったり、既存の実装の変更対象がわかっても修正方法がわからない、概念はわかるが名称を知らない、などの伸びしろを見つけました。これに関しては、実際にやってみたり他の人のプルリクを参考に考えることを積み重ねていくことで、自身の糧にしていくつもりです。

ライブラリに関する理解もまだ浅いので、今後は開発にくわえて、フロントエンド環境のメンテナンスをできるような知識も増やしていきたいです。

おわりに

このように、ファインディではフルスタックを目指す環境で働くことができます。また、現在ファインディでは共に働く仲間を募集中です。興味のある方は、こちらのページからぜひどうぞ!

herp.careers

入社初月からさくさくアウトプット!スムーズな立ち上がりを支えるオンボーディングの具体例

こんにちは。

2024/7/1 からファインディに入社した斎藤です。

ファインディでは、Findy Team+ という、エンジニア組織の開発生産性を可視化し、開発チームやエンジニアリングメンバーのパフォーマンスを最大化するためのサービスの開発に携わっています。

今回は、私が入社初月からさくさくアウトプットできた理由についてご紹介します!

入社初月からプルリク1日4件出せました

ファインディでは1日あたり4件プルリクを作成するというのを1つの指標としています。

入社直後は慣れるまでは結構厳しい指標だなと思っていたのですが、この記事で紹介する様々な仕組みのサポートもあり気がついたら初月から達成できていました。

中途入社あるあるだと思いますが、入社直後になかなか成果が出せなくてプレッシャーを感じてしまうということがあります。

簡単なタスク中心ではありますが、初月から貢献しているという実感が持てたので心理的にもたくさんプルリクが出せて良かったなと感じています。

※1日4件という数値はあくまでアウトプット量の参考です。 闇雲にプルリクをたくさん出せばいいということではありません。アウトプットをプロダクトの成果につなげることが大切です。

入社1ヶ月目プルリク数

1日平均4.6件!!

入社1ヶ月目プルリク数

入社2ヶ月目のプルリク数

1日平均5.7件!!

入社2ヶ月目プルリク数

入社初月からさくさくアウトプットできた理由

Good First Issueの粒度が適切であったこと

新しく参画した人向けのIssueとしてGood First Issueを準備する文化がファインディにはありますが、粒度として難しすぎず簡単に終わりすぎず良い粒度で取り組めるタスクになっていました。

その中で複数箇所に同じ修正を加える作業があり、それをなるべく速く終わらせる意識で対応しました。

例:同じリファクタリングを複数ファイルに渡って対応するタスク

  • ある処理を別ファイルに移動するというリファクタリング
  • 対応すべきファイル名が列挙されていてわかりやすい

Good First Issue

スムーズな開発を支えるレビューとCI/CDがあること

入社前は開発生産性を可視化するプロダクトを開発しているくらいなので、さぞかし開発がしやすいんだろうなーと思っていましたが、 入社後はその想像を超えて開発がしやすい環境だなと感じました。

特に次のことが要因で開発をサクサク進めることができています。

  • レビューが速い!とにかく速い!
    • 1PRあたりオープンからレビューまでの平均時間:3.3h
  • プルリクの粒度を小さくして出す文化が根付いているためレビュー負荷が少ない
  • リリース作業が楽で、時間が取られない
    • リリースPR作成、e2eテストが自動化されていて基本的にマージボタンを押すだけで完了できる

この辺りは他の方の入社エントリーで詳しく紹介されているのでもしよかったら見てみてください。

メンターと密にコミュニケーション

メンターとの1on1で不慣れな点を解消しつつ、やることを明確に設定していただけたことで開発に集中できました。 1on1で印象的だったのは一度に多くの情報をインプットしないようにしていただけたことです。 入社後に必要な情報を適切なタイミングで適切な量に分けてインプットしていただけたので、ストレスなく業務に慣れることができました。

  • 適切な頻度(私の場合は週1回)でメンターとの1on1があり、そこで課題を解消できた
  • 1on1以外でも都度メンターに質問して迅速に疑問点を解消でき、開発に集中できた

ふりかえりをして日々改善が行われる

私のチームでは2週間に1回の頻度でFindy Team+の「KPTふりかえり」機能を使ってふりかえりを行っています。 そこで出た課題に対する打ち手を議論して改善に繋げる取り組みがとてもいいなと思いました。 ふりかえりで出たアクションはまずは試しにやってみましょうという感じですぐに実行されます。 アクションがすぐに実行されるというスピード感がとてもいいなと思いました。 そしてやってみたアクションについてどうだったかも合わせて次のふりかえりで確認しているので 継続的に改善が行われる仕組みになっています。

新しく参画した私が感じた課題はすでに改善のアクションが進んでいるという状態でした。 (なので課題が思いつかないという課題があります。。。)

このように現状に満足せず、より良くするにはどうしたら良いかを全員で考え行動していることが高い開発生産性に繋がっているんだろうなと感じました。

挙げられたProblemに対してTryを設定 KPT

全てのコードベースを把握していなくても既存を壊さない仕組み

またテストカバレッジが99%で、自分の改修で他へ影響があった場合にはちゃんとテストが落ちるようになっています。

このように、自分の開発に集中できる仕組みが整っているため、 最初から全てを把握していなくても、安全に開発を進めることができます。

なので、全くプロダクトの知識がない入社直後でも 自分の担当作業に集中できるので、サクサクプルリクを出すことができました。

不明点は遠慮せずにすぐに聞いたり相談できる

前述したメンターとの1on1もありますが、定例以外でも不明点はすぐにSlackのメッセージやハドルで聞くことが推奨されています。 オンボーディング資料にも「不明点は都度Slackやハドル、(出社している場合は)対面で確認しましょう!」と明記されており、みなさん快く応じてくれます!

また、ファインディではSlackでtimes(分報)チャンネルを各自持っています。 自分のtimesで疑問をつぶやくといろんな人が助けにきてくれる文化があるので助かっています!

今後の抱負

ファインディのバリューであり、自分の強みでもある「スピード」を大切に爆速で開発をやっていきたいです!

ファインディでは一緒に会社を盛り上げてくれるメンバーを募集中です。興味を持っていただいた方はこちらのページからご応募お願いします。

herp.careers

ファインディでのGitHub Actions自動化の事例

ファインディ株式会社でフロントエンドのリードをしております 新福(@puku0x)です。

GitHub Actionsは、CI/CD以外にも様々な業務の効率化に役立ちます。

この記事では、弊社で実施しているGitHub Actionsを使った自動化について紹介します。

自動化

担当者アサイン

開発フローの中では、Pull requestを作ってからレビューに出すまでにいくつかのタスクを行うことがあります。

弊社では、Pull requestの作成者がAssignee(担当者)となる場合が多いため、↓こちらのActionを用いてアサインの自動化をしています。

github.com

- uses: kentaro-m/auto-assign-action@v2.0.0
  with:
    repo-token: ${{ secrets.GITHUB_TOKEN }}
addAssignees: author
runOnDraft: true

Assigneeのみ自動化しているのは、レビューに出すタイミングをPull requestの作成者側で制御したかったためです。

レビュアーについては、GitHubの標準機能でレビュー用のGitHubチームを作ってランダムアサインするようにしています。

ラベル設定

弊社では、Pull requestをラベルを用いて管理しているチームもあります。

付与するラベルについては、セマンティックバージョニングと相性の良いものが用いられることが多いです。

GitHub - azu/github-label-setup: 📦 Setup GitHub label without configuration.

ラベル設定の自動化は、公式のActionがありますので比較的導入しやすいでしょう。

github.com

actions/labelerは、最近の更新でブランチ名を基にラベルを設定する機能が追加されました。

この例では、ブランチ名の先頭が featfix 等であった場合に対応するラベルを付与するようにしています。

'Type: Feature':
  - head-branch: ['^feat']

'Type: Bug':
  - head-branch: ['^fix', '^bug']

モノレポの場合、ファイルのパスに対応するラベルを設定すると、どのプロジェクトに影響するか判断しやすくなります。

'Scope: App1':
  - changed-files:
    - any-glob-to-any-file:
      - apps/app1/**/*
      - libs/app1/**/*

'Scope: App2':
  - changed-files:
    - any-glob-to-any-file:
      - apps/app2/**/*
      - libs/app2/**/*

actions/labelerは、Pull requestのタイトルを基にしたラベル設定には、2024年9月現在だと対応していないようです。

その場合は、手動でGitHubのAPIを呼ぶシェルを組む必要があります。

run: |
  pr_title=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \  -H "Accept: application/vnd.github.v3+json" \
  "https://api.github.com/repos/Findy/***/pulls/${{ github.event.pull_request.number }}" \  | jq -r '.title')
  if [[ $pr_title =~ ^feat ]]; then
    pr_type='Feature'
  fi
  curl -X POST -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
  -H "Accept: application/vnd.github.v3+json" -d '{"labels": ["Type: '"$pr_type"'"]}' \
  "https://api.github.com/repos/Findy/***/issues/${{ github.event.pull_request.number }}/labels"

いつか公式のActionにも欲しいですね!

リリース

手順の多いリリース作業も、弊社では自動化を取り入れて負担を減らしています。

ここではフロントエンド系のリポジトリに採用されているものを紹介します。

  1. バージョニング用ワークフローを実行
  2. バージョニング用Pull requestが自動生成される
  3. バージョニング用Pull requestをマージ
  4. バージョニング用Pull requestのマージを起点にリリース用Pull requestが自動生成される
    (プロダクトによってはここでStaging環境へのデプロイも実行されます)
  5. リリース用Pull requestをレビュー後、マージ
  6. リリース用Pull requestのマージを起点に本番デプロイ

開発者は「ワークフローの起動」と「自動生成されるPull requestのマージ×2」というシンプルな手順で本番デプロイまでできるようになります。

また、Conventional Commits に準拠したコミットメッセージを採用しており、自動バージョニングやリリースノートの自動生成といった恩恵も得られています。

デプロイ頻度はFour Keysの指標にも入っていることから、チームの健康状態を知る手掛かりになります。可能な限り高い頻度でデプロイできるよう、仕組みはしっかりと整備していきましょう💪

参考: https://dev.to/puku0x/github-actions-1mi5

QAチェック項目の抽出

リリースの際に、QA担当者がチェックすべき項目をPull requestの履歴から自動抽出しているチームもあります。

まず、.github/PULL_REQUEST_TEMPLATE.md に次のような項目を設定しておきます。

次に、リリース時に起動するGitHub Actionsから、チェック済みの項目を抽出するスクリプトを起動します。

def category_by_pull(pull)
  return :planner_qa_pr if body.include? "- [x] 企画側QA"
  return :developer_qa_pr if body.include? "- [x] 開発側QA"
  return :other_pr
end

リリース用のPull requestの本文に反映されるため、QA担当者が何を見るべきかがわかりやすくなります。

定期実行

cron が使えるのもGitHub Actionsの良いところです。

on:
  schedule:
    - cron: '30 0 * * 1-5' # 平日09:30 (JST)

休日・祝日の考慮が必要な場合は、次のように前段に判定用のジョブを仕込んで needs で繋ぎます。

check:
  outputs:
    is_holiday: ${{ steps.check_holiday.outputs.result }}
  steps:
    - run: npm install @holiday-jp/holiday_jp
    - uses: actions/github-script@v7
       id: check_holiday
       env:
         TZ: 'Asia/Tokyo' # タイムゾーン固定必須
       with:
         script: |
           const holidayJp = require('@holiday-jp/holiday_jp');
           return holidayJp.isHoliday(new Date());

some_job:
  needs: check
  if: needs.check.outputs.is_holiday == 'false'

outputsstring で返ってくるため、boolean で扱いたい場合は fromJson(needs.check.outputs.is_holiday) のように変換すると良いでしょう。

まとめ

この記事では、GitHub Actionsを使った様々な自動化の手法を紹介しました。

公式が提供するActionの他にも、世の中には有用なActionがたくさんあります。

サードパーティ製のActionの利用については、「要件を満たせるか」「セキュリティ上の懸念はないか」「継続的なメンテナンスが期待できるか」等が選定の基準となるでしょう。

前回の記事では GitHub Actions高速化の事例 を書いておりますので、合わせてご覧いただけたらと思います。

弊社の他のGitHub Actions活用事例は、次のスライドで紹介しております。

こちらの発表については、connpassのイベントページにアーカイブ動画へのリンクを載せております。皆様の参考となれば幸いです。 findy.connpass.com

ファインディでは一緒に会社を盛り上げてくれるメンバーを募集中です。興味を持っていただいた方はこちらのページからご応募お願いします。

herp.careers

GitHub Copilotの効果は本物?論文から読み解く開発生産性の真実

はじめに

こんにちは。プロセス改善・アジャイルコーチで、Tech Blog編集長の高橋(@Taka_bow)です。

皆さんは、2021年6月に生まれたGitHub Copilotを利用していますか?

この生成AIベースのコーディング支援ツールは、コードの自動補完や生成、関数の自動生成、エラー修正支援など、開発者の作業を多面的にサポートします。

ファインディでは2023年3月から導入し、開発チーム全員が日常的に活用しています。Findy Team+で効果を測定した結果、コーディングの効率化やコミュニケーションコストの削減、さらには開発者の満足度向上など、多くの利点が確認されました。

今回は、このようなソフトウェア開発における生成AIの影響を分析した最新の論文を紹介します。GitHub Copilotが開発プロセスにもたらす変化や、開発者の生産性への影響についての研究が書かれた、興味深い論文です。

生成AIが高度なスキルを要する仕事に与える影響

2024年9月5日、GitHub Copilotに関する1つの論文がプレプリントサーバーのひとつSSRN(Social Science Research Network)に公開されました。

papers.ssrn.com

直訳すると

「生成AIが高度なスキルを要する仕事に与える影響:ソフトウェア開発者を対象とした3つのフィールド実験からの証拠」

といったところでしょうか。

査読前論文なので、現在は誰でも読むことが出来ます。

この論文は、Kevin Zheyuan Cui氏(プリンストン大学)、Mert Demirer氏(マサチューセッツ工科大学)、Sonia Jaffe氏(マイクロソフト)、Leon Musolff氏(ペンシルベニア大学ウォートン校)、Sida Peng氏(マイクロソフト)、およびTobias Salz氏(マサチューセッツ工科大学)によって執筆されたもので、大規模な実験の結果を分析した科学的アプローチの成果が記されています。

実験の概要

この研究では、GitHub Copilotの効果を検証するため、大規模なランダム化比較試験が行われました。実験の舞台となったのは、Microsoft、Accenture、そして匿名のFortune 100エレクトロニクス製造会社の3社です。

驚くべきことに、この実験には実に4,867人もの開発者が参加しました。

参加者は2つのグループに分けられ、一方にはGitHub Copilotが提供され、もう一方は従来の開発手法を継続しました。この比較により、GitHub Copilotが本当に開発者の生産性を向上させるのか、客観的に検証することが目的でした。

また、各社の実験期間は次の通りです。

  1. Microsoft:2022年9月初旬から2023年5月3日まで(約7ヶ月間)
  2. Accenture:2023年7月末から2023年12月まで(約4ヶ月間)
  3. 匿名の大手企業(Fortune 100):2023年10月から2ヶ月間(段階的にロールアウト)

このような実験の設計により、異なる企業環境や期間での GitHub Copilotの効果を包括的に評価することが可能となりました。

具体的な成果

実験結果は、GitHub Copilotの効果を明確に示しています。

GitHub Copilotを使用した開発者グループでは、次のような顕著な改善が見られました。

  • タスク完了数: 平均で26.08%増加(標準誤差: 10.3%)
  • コミット数: 13.55%増加(標準誤差: 10.0%)
  • コードコンパイル回数: 38.38%増加(標準誤差: 10.0%)

これらの数字は、GitHub Copilotが開発作業全体の効率を確実に向上させていることを示しています。特筆すべきは、経験の浅いジュニア開発者への効果です。このグループでは、

  1. GitHub Copilotの採用率がより高く
  2. 生産性の向上がより顕著

であったことが報告されています。このことから、GitHub Copilotが特にキャリア初期の開発者のスキル向上と生産性増加に大きく貢献する可能性が示唆されています。

シニア開発者には控えめな効果

この研究で特に注目すべきは、GitHub Copilotがジュニア開発者とシニア開発者に与えた影響の違いです。

ジュニア開発者への影響

GitHub Copilotは、経験の浅い開発者に対して特に大きな効果を示しました。

  • 新しいコードの書き方や構文を効率よく学習
  • タスクの進捗が大幅に向上
  • プルリクエスト数が40%増加(シニア開発者は7%)

これらの結果から、GitHub Copilotはジュニア開発者にとって単なる補助ツールを超えた学習ツールとしての役割を果たしていると考えられます。

シニア開発者への影響

一方、シニア開発者に対する影響は比較的小さいものでした。これには次のような要因が考えられます。

  • すでに確立された作業スタイルがある
  • 新しいツールの採用に対する慎重さ

詳細な比較

次の表は、ジュニアとシニア開発者におけるGitHub Copilotの効果の違いを示しています。

項目 ジュニア開発者 シニア開発者
プルリクエスト増加率 40% 7%
コミット数増加率 21% 16%
ビルド数増加率 29% 13%
GitHub Copilot採用率 82.1% (±2.1pp) 76.8% (±2.1pp)
採用後1ヶ月後の継続使用率 84.3% 74.8%
GitHub Copilot提案受け入れ率 25.2% 24.7%

注:この研究では、会社での採用時の職位や在職期間に基づいて開発者を「ジュニア」と「シニア」に分類しています。具体的な基準については詳細が明らかにされていません。

ツール採用パターンの違い

実験結果から、GitHub Copilotの初期採用率は予想外に低かったことが分かりました。

Microsoftでは最初の2週間で採用率が42.5%にとどまり、リマインダー後に64%まで上昇。Accentureでは全体で約60%の採用率でした。

この結果は、新しいツールの導入には単なる提供以上のものが必要だということを示しています。適切なトレーニングやサポートが不可欠で、段階的な導入や定期的なリマインダー、効果的な使用法の教育セッションなどが有効な戦略となりそうです。

これらの知見は、GitHub Copilotに限らず、新技術の導入時に直面する一般的な課題を反映しています。単にツールを導入し、現場任せにするだけでは、効果的に活用できないでしょう。急速に進化する開発環境では、新ツールを戦略的に導入し、継続的にサポートすることが、組織の競争力を保つうえで極めて重要です。

補足:Accentureの実験初期のデータ破棄(論文付録D)

Accentureの実験には意外な展開がありました。2023年4月に同社が実施した大規模なレイオフ(19,000人の従業員削減)により、当初の実験が中断を余儀なくされたのです。

このレイオフは実験にも大きな影響を与えました。

  • 実験参加者の42%が影響を受ける
  • データの質に問題が生じる
  • GitHub Copilotの使用状況や採用データの記録が不十分に

結果として、この初期実験のデータは信頼性に欠けるものとなりました。しかし、204人の開発者に絞って行った分析では、次のような傾向が見られました。

  • プルリクエスト数: 39.18%減少 (標準誤差: 36.78%, 統計的に有意ではない)
  • コミット数: 43.04%増加 (標準誤差: 38.80%)
  • ビルド数: 12.33%増加 (標準誤差: 53.60%)

これらの結果は統計的な信頼性が低く、実験結果としては参考程度にとどめるべきでしょう。

おわりに:試されるのは「人間」

この研究から、GitHub Copilotがソフトウェア開発者の生産性向上に確かな効果をもたらすことが明らかになりました。特に、ジュニア開発者への顕著な効果は注目に値します。

一方で、シニア開発者への効果が限定的だった点も興味深い発見です。これは、経験豊富な開発者がすでに高いスキルを持ち、AIのサポートをそれほど必要としていない可能性を示唆しています。

しかし、ジュニア開発者がAIの提案を鵜呑みにするリスクも考慮する必要があります。ここで、シニア開発者によるコードレビューの重要性が一層高まると言えるでしょう。

調査会社の米ガートナーが発表した内容によると、AI コードアシスタント(生成AI)に関するマジック・クアドラントと共に、次のような予測がなされていました。

戦略的計画の仮説

  • 2027年までに、ソフトウェア開発ライフサイクル(SDLC)のあらゆるフェーズを拡張するためにAIを活用するプラットフォームエンジニアリングチームの割合は、5%から40%に増加する。
  • 2027年までに、80%の企業がAIで拡張されたテストツールをソフトウェアエンジニアリングツールチェーンに統合しており、これは2023年初頭の約15%から大幅な増加となる。
  • 2027年までに、AI生成コードに対する”ヒューマン・オーバーサイト”(人間がAIに対して動きを見たり止めたりできる)*1 が不足しているために、本番環境に流出するソフトウェア欠陥が25%に達し、2023年の1%未満から大幅に増加する。
  • 2028年までに、90%の企業のソフトウェアエンジニアがAIコードアシスタントを使用するようになり、2024年初頭の14%未満から増加する。
  • 2028年までに、生成AI(GenAI)の使用により、レガシーアプリケーションのモダナイゼーションコストが2023年の水準から30%削減される。

Figure 1: Magic Quadrant for AI Code Assistants https://www.gartner.com/resources/808000/808075/Figure_1_Magic_Quadrant_for_AI_Code_Assistants.png?reprintKey=1-2IKO4MPE

ここでも、人間側によるチェックが不足することでソフトウェア欠陥の上昇が予測されており、結局のところ、AIツールの活用と人間の経験や判断力のバランスが、質の高い開発プロセスの鍵となりそうです。

私たちに求められるのは、技術の進化を単に観察するだけでなく、それを最大限に活用しつつ、人間ならではの創造性や洞察力を発揮していくことです。この新しい時代の開発環境で、私たちはどのような価値を生み出していけるでしょうか。その答えを、皆さんと一緒に見つけていきたいと思います。

お知らせ!

現在、私と一緒にイネイブリングチームの立ち上げを行うメンバーを探しています!

イネイブリングチームは、単なる開発支援を超えた重要な役割を担います。

  • 組織全体のエンジニアリング力を向上
  • 開発スキル向上のためのトレーニングやワークショップを実施
  • プロセス改善の提案とコーチングを行い、開発生産性とDevExを向上
  • 社内外のエンジニアを対象とした活動を展開

このチームで、ファインディの成長エンジンとなりませんか?興味がある方は、ぜひこちらをクリックしてみてください↓

herp.careers

他にも、ファインディでは一緒に働くメンバーを募集中です。

herp.careers

*1:AIの文献で良く出てくる"human oversight"は適した日本語訳がなく、一旦このように訳した