freeeのエンジニア（夏）インターンに参加してきた

# はじめに
2024年の夏、私はfreeeのエンジニアインターンに参加する機会を得ました。このインターンシップでは、実際のプロダクト開発に携わりながら、freeeのエンジニアリング文化や技術力の高さを肌で感じることができました。本記事では、インターンを通じて得た学びや経験、そして感じたことをまとめていきます。これからインターンを検討している方や、エンジニアとしてのキャリアを考えている方に少しでも参考になれば幸いです。

## なぜこの記事を書いたか
- 限定Tシャツがほしかったから(記事を投稿すると24年サマーインターンTシャツがもらえます)
- 自分自身、去年のインターン参加者の方の記事を読んで大いに参考にさせていただいたので、私も後に続く方々の情報源になるような記事を書きたかったから
- 改めてインターンを振り返るためのメモ的な位置付けにしたかったから


# インターンシップの概要
- インターンシップは、2024年8月19日から8月30日までの期間で実施されました。このプログラムは、主にエンジニアリングにフォーカスした内容で、参加者は実際に社内で稼働している各チームに配属され、実際の開発タスクに取り組みました
- プログラム中には中間振り返りや最終日の成果発表が行われ、最終的には懇親会も企画されていました
<br>

- **期間**:8月19日(月)〜8月30日(金) (土日休み)
- **時間**:10:00〜19:00
- **形式**: 自由（フルリモートから全日出社まで自由に選べる）

## （個人的な）背景

### なぜ参加したのか
- freee人事労務を他のインターン先でユーザーとして利用していた
- 莫大なユーザー数を抱える大規模プロダクトの開発を体験したかった
- メンテナンス性の高いコード実装をするための知見や思考を学びたかった

etc...

# 選考
選考ステップは以下になります

1. 会社説明会に参加
2. コーディングテストの受験（Atcorder[B問題]くらい、多分　& 時間は90分）
3. 面接(45分程度)
    - 志望動機
    - これまでの開発経験
    - ぶつかった課題と解決方法、工夫
4. 選考結果の通知
5. (合格したら)配属先の希望調査

# インターン内容

### チーム配属
- freee人事労務（勤怠チーム） [詳細](https://www.freee.co.jp/time-tracking-plus/)
    
- エンジニアのメンターさんが３名ついてくださりました

### 業務内容
- インターン生（私のチームは3人）同士でチームを組み、実際にサービス内の機能を改修、追加するタスクを2つ渡され、2週間の中で取り組んでいく
- 要件定義書をもとに**議論->設計書の作成-> 開発　-> テスト -> デプロイ**　まで（その過程でのタスク分担等の業務も含め） 様々な工程の業務に挑戦
- インターン期間中はfreeeの社員同然に扱われ、オンボーディング資料をはじめとする様々なドキュメントを閲覧しながら環境構築から始めり二週間でぎゅっと頑張る

<br>

**＜個人的に嬉しかったポイント＞**
- 2週間を通してやることやらないことは本当に自分次第（めちゃめちゃ自由度が高い）
    - 所謂、上流工程の会議への参加
    - 業務時間内でのエンジニア/非エンジニアの方々（私の場合は、人事の方や配属部署の部長）との1on1は自己申告すれば快く引き受けてもらえる
    - 1on1では業務内の相談事項に限らず、キャリアについての相談やfreeeについての詳細を聞くことができる
- 共有された設計書やチームビルディングについての資料等読み漁ることができるので得られる知見はとても多い（業務との両立は当事者の技量が試される）


### スケジュール

私たちのチームでは以下の項目を基本とし、日々の業務を行なっていきました。
- 基本的に業務中はGoogle Meetを繋ぐ（コミュニケーションがとりやすい）
- 質問や詰まったポイントは随時Slackで共有
- 10分考えて無理ならヘルプを呼ぶ
- 朝会、夕会は一日一回ずつ(15~30分)やる
- チームのエンジニアの方々との1on1の実施

#### 1~3日目
- 初日はインターン全体の説明と支給PCの環境構築
- 2,3日目はプロダクトの理解と開発環境の構築

とにかく環境構築が重かった（新品のMacを使わせてもらってたので、複数のプロダクトを連携させたりするための開発環境を整えるために多くの時間を費やしました。）

#### 4~5日目

- タスク1（人事労務（勤怠）のUI改善）に着手 
- 中間報告 (自チームのプロダクト、タスク、気づきなどを共有)

本格的な開発業務に入れたのは、インターンが始まって4日目以降でした。
具体的にやったこととしては、
1. タスクの切り分け
1. 実装箇所の把握
1. [Feature Flag](https://zenn.dev/ascend/articles/feature-flag)の設置
1. レビュー
1. 実装 (Feature Flagにとる場合分けを含む)
1. テスト (ここがめちゃめちゃ落ちる)
1. レビュー(え、そんな綺麗な書き方あるの！？の気づき)
1. デプロイのための作業（ステージング環境での確認、本番環境への反映）

そうです。一つのミニマムな機能追加だったとしてもこれだけの手順を踏む必要があります。

数百万単位のユーザーを抱えるプロダクトの実装に関わるという貴重な経験を通じて、freeeが行っている安全な開発運用を行うための徹底した作業工程の統一やCI/CDを活用したテスト運用を目の当たりにしました。

同時に、これまで私が関わってきたプロジェクトでは体験することができなかった便利ツールの存在や保守性の高いコード実装についても、現場エンジニアの方のレビュー等を通じて知ることができました。

なお、タスク1に関しては、他のチームメンバーが中心になってタスクを行ってくれました。その過程でタスクの進捗状況はこまめに同期（共有）できていたし、実装過程で詰まったポイントを記録していってくれていたので、タスク共通のステップ（Feature Flagの設置やPRの書き方）は以降のタスクではとてもスムーズに行っていくことができました。（ありがとう！(届け)）

#### 6~7日目

- スケジュールと目標の再確認
- タスク2（人事労務（勤怠）の機能改善）に着手
    -  企画提案書, PRDの読み合わせ 
    - Design Doc の作成
- (個人)エンジニア採用担当の方と1on1

インターンの後半戦が始まり、前週までの業務からある程度の工数感と苦戦しそうなポイントが明らかになったので、改めてチーム内のミーティングで「タスク2までは完遂しよう」という共通目標を立てました。

タスク2では、タスク1にはなかった工程を体験することができました。

1. 企画提案書, PRDの読み合わせ (with PM / Eng /QA )
1. Design Docの作成
1. DesignDoc読み合わせ
1. セキュリティチームによる確認
~ 以降はTask1と同様 ~


エンジニアに限らず色々な役割の社員さんたちと共に、ユーザにとっての本質的な価値を見据えて協議し、ドキュメントの作成を行いました。
実装に入る前の工程について、個人的には初めての体験であり、「大きな会社のエンジニアっぽいヽ(*＾ω＾*)ﾉ」貴重な経験をさせていただきました。

会社で定められているリスク基準や要件を満たすための変更点の洗い出しなど、様々な点に気を配りながら最終的な資料として社員さん方との読み合わせ会にて共有し、何点かフィードバックをもらい、適宜修正しながら、ドキュメントの完成度を高めていきました。


メンバー全員初めての作業だっただけに、なかなか難易度の高い業務でしたが、Design Doc の作成を取りまとめてくれていたメンバーが疑問に思った点を都度社員さんに質問し、共有してくれていたので、その場で学びながら話し合いや関連業務を進めることができました。（ありがとう！(届け)2）

また、6日目にはエンジニア採用担当の方にお願いして、1on1を実施していただきました。1on1では、主に「インターン期間でさらに成長するためには？」と「キャリアパスの選び方」についてのお話をさせていただきました。
細かい内容は割愛させていただきますが、インターン前に立てていた個人目標とインターンで経験できそうな内容に少しズレがあるように感じていたので、このインターン内でできることの中で自身の成長を最大化するために、どんな動きができるかの選択肢を提供していただきました。また、モヤモヤしている部分の言語化、視座を高めるための相談の場として、ある部署の部長(freeeでは「船長」)をつとめていらっしゃる方との1on1もセッティングしてくださりました。
(親身になって相談に乗ってくださりありがとうございました!(届け)3)



#### 8~9日目
- タスク2（人事労務（勤怠）の機能改善）
    - Feature Flag の設置
    - 実装(機能/テスト)
    - 適宜レビューの依頼と修正
- タスク3(+aのタスク)のDesignDoc作成
- チームメンバーの方々とのランチ会 (チャーシュー丼(小ネギ/味玉トッピング)美味しかった~)
- (個人)船長との1on1 & ランチ (詳細後述)



タスク2は私がメインになって実装させていただきました。詳細は避けますが、新規の汎用的な知識として、
- [OpenAPI](https://swagger.io/specification/) / [Swagger](https://editor.swagger.io/)
- [active_model_serializers](active_model_serializers)
というものを初めて知りました。（後者についてはインターン期間中に簡単に勉強して[記事](https://qiita.com/Hayato-7812/items/1e1479df6c32093bdf8d)を作成しました）

などを得ることができました。 チームのTech Leadの方によるコードレビューが本当に惚れ惚れする内容で、頭の中をのぞいてみたくなりました。レビュー後の1on1でも普段からどんなことをこころがけているのか伺うことができ、さっそく実践しています。（ありがとうございました!(届け)4）

**<苦戦したことと>**
- 適切な変更箇所の把握
    - プロダクト内で記述やディレクトリ構成（役割的な側面）に多少のばらつきが見られ、変更箇所はどこになるか、どこに記述を追加するのかを決定するのに時間がかかった
    - これらの負債は解消にも工数がかかるし、利用頻度が少ないコードのリファクタリングはコスパが悪いのでやるところ、やらないところを選択する必要があるよねという話をメンターさんとしました
- DBデータの役割や依存関係の整理
    - 人事労務関連のドメイン知識が不足しており、テーブル/カラム名からそのデータが持つ情報が何なのかを即座に見分けることができなかった
- 型定義の変更と追加した制約の解決
    - 変更の中に構造体へのフィールドの追加が含まれており、単純な変更だけでなく、変更によって影響が出た箇所の解決(ここははじめの段階でできるだけ周囲に影響が出ないように実装することが望ましいが、プロダクトの初期フェーズで先々の実装変更や追加まで考慮するには限界があるので難しいところだな...と感じました。スーパーエンジニアの人たちは何をどこまで考えて新規機能の実装をしているんだろう、今度聞いてみよう) 


**<乗り越え（ようとし）方>**
- 変更箇所の把握
    - 開発者ツールの Network>Fetch/XHRでAPIから送られてくる情報やパスを発見 (New!)
    - UIで見られる文字列を使ったファイル全検索
    - break point の設置
    - 経験による勘(<- メンターさんと話していて「一定以上のドメイン知識とプロダクトに携わった経験が必要である」思いました。実際にプロジェクトにアサインされたときは、これをつけるための動きを意識してみてもいいかもしれないという気づきです。）

- DBデータの役割や依存関係の整理
    - (schemaファイルを観察する)
    - メンターさんに聞く（インターン期間の短さを考慮するとやむを得ない）
     


(3,)8,9日目は実際にオフィスに出社させてもらいました。
まずは綺麗！ビルの18F~21Fがfreeeのオフィスとなっており、ユニークな会議室や魅力的なスペース（図書館や集会場）が設置されており、「こんなオフィスならたくさん行きたくなっちゃうな〜」と思いました。
残念だったこととしては、事前に試聴していたオフィス紹介動画にはあった、キャンプ場スペースや砂浜スペースが綺麗に埋め立てられ、デスクが並ぶ正当なオフィススペースに変貌していたことです。

(以下出典：[freee、楽しさの多様性と働きやすさを追求したオフィスを公開 出社率は80%超、社員が自ら考えた楽しい会議室でさらに成長を加速させる | プレスリリース | corp.freee.co.jp](https://corp.freee.co.jp/news/20220920freee_office.html))

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1071957/353bce64-0e3c-fd2c-d0b4-ee880736d046.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1071957/f2642c87-cf83-9661-047d-dea0cebd0c12.png)


そして、8,9日目はそれぞれ30分の1on1&お昼ご飯で船長とお話しする時間をとっていただきました。 （1インターン生に対してとてつもない時間と労力を割いてくださりました(涙)ありがとうございました！(届け)5）
私のやりたいことをベースにどのあたりの役職が向いていそうか、様々なフェーズの会社の強み/弱み（実体験に基づく）、freeeではどんなことができるのか etc etc etc ...
拙い質問や、言語化しきれていない部分も汲み取ったうえで、就活軸がまた一つ具体的で強固になるような対話をしてくださりました。
めちゃ美味しいランチをご馳走になりました。（お店とfreeeは全く関係ない）

<img width="300" alt="IMG_3894 2.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1071957/dd04b097-fb14-ac8d-ec5c-a48550432daf.jpeg">


#### 10日目

- タスク2のステージング環境確認
- タスク3のFeature Flag設置
- 振り返り(個人、チーム、メンターさんからのFB)
- 最終発表資料作成
- 最終発表
- 懇親会

最終日は、業務の追い込みと、2週間の振り返りを行いました。
振り返りでは、「もう少し上手くできたな」と思うところも多々ありましたが、チームメンバーやメンターの方からの第三者目線のコメントから「ここは自分の中でも武器にできそう」のような気づきがあり、とても濃密な時間でした。
また、最終発表では別の配属先で2週間走っていたインターン参加者の方々からの成果発表を見ました。
配属先によって使用技術や文化にも色があり、freeeが社内で行なっている業務の種類（基盤~サービスまで）の多さを感じました。

懇親会では、他のチームの方々と、就活全体の話や普段大学でやっている研究の話など有意義な会話を楽しむことができました。

いやぁ〜、楽しかった。


## まとめ

半分勢いで雑多に書き上げてしまいましたが、改めて学びの多い2週間でした。
冷静に書き直すと、下記のような学び（一部）がありました。

:::note warn
反省
- **工数の見積もりが甘かった**
    - 粒度をもっと細かくするべきだった([参考](https://qiita.com/taku-0728/items/7a2f0919ce375bbb48f7))
    - ドメイン知識がない状態での工数設定に時間を浪費しない(->同じことを繰り返さない工夫をする)
- **周辺技術の深いところを吸収しに行く時間をあまり取れなかった**
    - 知識習得が業務で必要になる部分にとどまることが多かった
    - 明示的な時間の確保、日々の習慣
:::


:::note info
学んだこと
- **ユーザーにとっての本質的な価値を考える文化**（freeeでは「マジ価値」と呼ばれています）
- **堅牢で安心なプロダクトを届けるための開発工程、コードとの向き合い方**（まだまだ学ぶことは多い）
- **多職種の方々との協働(会議/質問)では**
    - 誰に向けて何を伝えたいのかを意識する
    - 前提や目的は事前に共有しておく、可視化しておく
- **自分を曝け出すことの重要性**
    - コミュニケーションのハードルを下げる効果
    - 個人での振り返りには限界があるため、重要になる「他者からのFB」の質が向上することは期待できる
- **自身の成長に対して謙虚であることの重要性**
    - FBを受容する
    - 自身を認知し、次の課題に取り組むこと
- **技術知見の深みは、自分でプロデュースできる**
    - 仕組み化されているものを深掘りに行くことで得られるものは大きい
    - 習慣的の技術知識をとりに行く
- **全てを倒して本番環境にデプロイされた時の達成感**
- **50万事業所以上に利用されているプロダクトに自分が実装した機能が載るということの高揚感**
:::

今回のサマーインターンを通じて、技術的なスキルだけでなく、チームでの協働やプロダクト開発のプロセスを深く学ぶことができました。特に、問題解決のアプローチやコードの品質向上に対する意識の変化は、今後のキャリアにおいて大きな財産となると感じています。また、インターン先のメンバーとの交流を通じて、さまざまな視点や技術トレンドにも触れ、自分自身の成長の幅を広げることができました。

これからもこの経験を糧にし、さらなる挑戦を続けていきたいと思います。最後に、この貴重な機会を提供してくださった企業や社員の皆様に感謝いたします。