Chatworkサマーインターンに行ってきた2022 バックエンド（Scala）コース

2022年8月15日~2022年9月2日であったChatworkのサマーインターンのバックエンドコース（Scala）に行ってきました！ めちゃめちゃ学びになったので、アウトプットとして体験記みたいなものを書いていきます。

https://recruit.chatwork.com/internship/2022/engineer.html

## 応募する前の経歴
現在、理学部で物理を勉強している学部3年生です。学部2年生の頃からWeb開発を本格的に学び始めて、ハッカソンなどでチームでWebアプリを開発したり、アルバイトでバックエンド開発をしたりしていました。アルバイトではドメイン駆動設計（DDD）やアーキテクチャに則った開発を行なっていました。Chatworkのインターンに興味を持ったのもドメイン駆動設計がきっかけです。

## 選考について

自分はホームページ経由からの選考だったので、以下のフローでした。

- 書類選考
- コーディングテスト
- 人事面接、技術面接

他社に比べて、選考内容がユニークでした。
特にコーディングテストがびっくりでしたね。内容は話せないので、受けてみてからのお楽しみです！

Scalaの経験が全くなかったので、合格は難しいかなと考えていましたが、なんとか合格をいただけました（応募前はScalaどころか、静的型付け言語でのアプリ開発の経験はほぼ皆無でした...）。インターン始まってからわかったことですが、どうやら他の参加者の方もScala経験がない方がほとんどでした。

ビビらず受けてみてよかった！！

## インターンの概要

講義パートが１週間、実践パートが２週間の計３週間で、全てオンラインでした。実技パートはオフラインの予定だったのですが、某感染症の影響でオンラインになってしまいました。オフィス行きたかった...（先日、念願のオフィスツアー行ってきました！）

**講義パートで学んだ内容を実践パートでアウトプットすることで学びを自分のものにする**みたいな構成になっていました。

インターン参加前に本が二冊支給されたので、前もって予習できる形でした。（本もらえるの嬉しい）

https://gihyo.jp/book/2017/978-4-7741-9087-7

https://gihyo.jp/book/2018/978-4-297-10141-1

## 講義パート
共通講義と専門講義があり、専門講義ではフロントエンドとバックエンド分かれて別々の講義を受けました。（内容に関しては[こちら](https://recruit.chatwork.com/internship/2022/engineer_backend.html)）実はこれら以外にもインフラなど色々な講義があります。

そもそもWebサービス開発とは？みたいなところからDDDやスクラムまでかなり幅広く講義が用意されていました。技術そのものの使い方にフォーカスするのではなく、その技術が選ばれる背景や重要なポイントに絞った講義だったので、その技術のエッセンスに触れることができました。幅広い分野の講義を聞く中で、これから学習したいことや興味が増えたこともよかったことの一つかなと考えてます。

また、DDDで有名なかとじゅんさんの講義が受けられます。内容の密度と膨大な情報量に圧倒されました。講義中に質問させてもらえたのですが、質問１に対して内容が１０くらいで返ってきました。めちゃくちゃ贅沢でしたね。

ここで学んだ内容はのちの実践パートでかなり活きてきます。（特にDDDとスクラム）

## 実践パート

今回の開発チームは、フロントエンド3人、バックエンド3人の計6人の学生でした。チームにはエルダーというメンター的な役割の社員の方がついてくださったり、コードレビューや実装で困ったときに相談させてもらえるサポートレビュワーの方がいらっしゃいました。社員の方に指示を受けながら開発するのではなく、チームとして１から考えて開発し、困ったら社員の方に助けていただく、という感じでした。

今回の課題は、インターン用に開発されたチャットアプリへの機能追加でした。
要件定義から設計、テスト、実装、デプロイまで一通りを経験することができました。

今回はissueごとにブランチを切って開発するissue駆動開発で行いました。これによりPRの粒度を適切なものにできたり、作業前にやることが明確になったので採用してよかったです。

テストをしっかり書いたり、サポートレビュワーの方に手厚いPRのレビューを頂いたので、品質が保証されたコードが書けたのではないかと思っています。

スプリント（今回は１週間）ごとに成果報告会があり、各方面のプロから直接フィードバックがもらえます。たくさんの質問にも答えていただきました。ここまで豪華だと、果たして自分はこのインターンでお金をもらっていいのか？という気分になってきます。

### そもそもドメイン駆動設計とは？

誤解を恐れず、簡単に言うと、
ビジネスの専門家と開発者が同じ言語や同じモデルを使うことで、開発者もビジネス視点を踏まえたソフトウェアを作ろう
みたいな設計になります。
興味がある人は”ユビキタス言語”とか”ドメインモデル”みたいな単語でググってみてください。

### バックエンドのお話

バックエンドの既存の実装は、ScalaでDDDとCleanArchitectureに則って作られており、コードリーディングだけでもかなり勉強になりました。フロントエンドもDDDで開発されていたようです。（かなり珍しいみたい）

また、CQS（コマンド責務分離）に基づいて実装されています。副作用の有無でクラスを分けることで、自信を持ってメソッドを使うことができます。クエリの際にはリードモデルと呼ばれるクエリ専用のモデルを用意することで、さまざまなクエリに柔軟に対応しやすくなるのですが、今回は時間の都合上、エンティティで対応しました。

フロントエンドの方と仕様を決めた後、バックエンドとしては次のような手順でAPIの開発を行いました。
- ドメインモデリング
    - ひと、もの、ことに関するビジネスロジックや制約を書き出す
- ドメインオブジェクトの設計と実装、テスト
    - ドメインモデルを反映したドメインオブジェクトを設計し、実装する
- Usecase層の実装
    - ドメイン層を使って、機能を実現
- Controller層、永続化層の実装、テスト
    - 今回はController層でUsecase層の振る舞いもテストした
- application層の実装
    - 上の部品を組み合わせてアプリケーションとしての機能を提供

ドメインモデリングやドメイン層の設計に関しては、講義パートで学習した内容を復習したり、かとじゅんさんを始め、さまざまな社員の方からレビューをいただいたりしながら進めました。

## 学んだこと
DDDや設計は言わずもがななので、それ以外で言うと**レビューしてもらいやすいPRを作成する**ということです。

メンターの方から「レビュワー側としては、PRにコードという結果しかないと、設計の背景とかどこを見たらいいの？みたいなところに気を取られてレビューしにくい。良いレビューをもらうには、レビュー側もレビューしやすいPRを作る配慮をする方がいいよね」みたいな話をいただきました。
チーム内でも確かにそうだよねとなったので、以下の点をPRに書くように変更しました。

- 設計の背景や実装の経緯をきちんと書く
    - コードという”結果”では背景や経緯は伝わりにくい 
- テスト結果を載せる
    - この実装はちゃんと動くの？というレビュワーのノイズを減らせる
- PRの粒度を適切に
    - 大きすぎると、レビュワーはしんどい
- レビューしてほしいポイントを明記する
    - あえてスコープを絞ることで、見てもらいたいところにレビューがもらえる

レビューしてもらう人への配慮って大事だなと気づきましたね。
インターンが終わった後も、PRや質問などで相手の負担を減らすことをより意識するようになりました。
## 会社の雰囲気

「学んだこと」に通ずる話でもあるのですが、コミュニケーションを重要視されていると個人的には感じました。特に、サポートレビュワーの方への質問の際に、レビュワーの方が「我々の質問を違う言葉で言い直してくださる」など認識の齟齬を生まないようなコミュニケーションをしてくださったことが印象に残っています。

また、個人チャットの些細なつぶやきにも色々な反応をもらえますし、GoogleMeetなどでのチャットも本当に活発です。あったかいです。

あと、面白い方が多いです。自分のツボが浅いこともありますが、声出して笑ってました。
なんだかうまく表現できているかはわかりませんが、ほんとに良い雰囲気でした！
## 最後に
とても楽しく、学びになる３週間でした。
関わっていただいた方、本当にありがとうございました！

インターンのお給料でキーボードとか買おうかな...

最後に同じ参加者の方のブログを載せておきます！

https://ajfafg.github.io/chatwork-summer-internship-2022/

<!---

- 幅広い分野の講義が受けられる→個人で学習していると、どうしても内容に傾斜がかかる　これから学習したいことや興味が増えた エッセンスを知れた（教科書を勉強しているだけではなかなか伝わってこないようなもの）

- 実践パートで使っていくので、アウトプットができて効率がいい

レビューかなりしてもらった
PRがわかりやすいように、設計の背景やテスト結果を掲載、PRの粒度や見てほしいところを書く
テストしっかり書いた　テストの役割や責務、必要性
気づいたこと

## 個人的成長ポイント
- テストの重要性を実感できた
- レビューがもらいやすいように、PRの粒度やコミュニケーションの取り方を考えることができた
    - サポートレビュワーの方に頼むとPull Requestのレビューがもらえます。
    - PRには実装の詳細だけでなく、設計の背景やテスト実行結果を盛り込むことで、できるだけレビュワーが迷わないようにすることが良いフィードバックをもらう上で大事だということが実感できた
-->