はじめに
初めまして。2021年4月に新卒で入社いたしました教育事業本部サービス開発部バックエンドセクションの len です。
今回は教育事業本部の新卒メンバーとして join してから1年で取り組んできた研修についてお話しします。 メンターにサポートいただきながら研修を進めて参りました。メンター視点の記事はこちらになります。
全社エンジニア新入社員研修
入社してすぐ全業種に向けたビジネスマナー研修や事業説明があり半月経ったあたりでエンジニア向けの研修が6月末まで行われました。 この研修では基本的な技術の取得や学んだ技術を使って個人やチームなどでアプリを作成するといった内容でした。
こちらの研修の1つである基礎研修では、N予備校の教材を使い、web に関する基礎的な技術を学びました。
それと同時に読書会もあり、読んだ技術書の内容をN予備校で復習できる点がよかったです。
具体的な流れや目的等はエンジニア新入社員研修の担当である青木さんの記事をご覧ください。
N予備校キャッチアップ
6月末で全社エンジニア新入社員研修が終わり、教育事業本部に配属となった私はまずN予備校やそれを支える各マイクロサービスのキャッチアップを行いました。 N予備校のマイクロサービスについてはこちらの記事をご覧ください。
キャッチアップでは最初にN予備校の一通りの機能(教材の閲覧やフォーラム投稿など)を体験しました。 次に、各マイクロサービスの説明や使用している開発ツールの説明を読み込み、API Gateway である tenjin の ローカル環境構築をしました。
N予備校のマイクロサービスでは Ruby が使われており、もともと Ruby は学生時代にふれていたこともあり比較的読みやすかったです。
このあたりの資料はすべて社内資料共有ツールである Confluence にまとまっていたのでリモート環境化でも迷わず進めることができました。
メンターとの面談の中でスキルマップを提示いただき、自分が足りない部分や苦手意識がある分野を洗い出してその分野を勉強するという時間もいただきました。 私の場合はマイクロサービスのコンテナ管理をする Kubernetes についての知識がなかったので研修内で勉強する時間をいただき、その内容を部内で発表会という形でアウトプットしました。
発表会ではバックエンドセクションに限らず、フロントエンドや品証の方もお見えになり、緊張はしましたが demo でコンテナを構成したりして学んだ成果を発表できました。
また、メンターと一日30分程度の 1on1 や slack の質問チャンネルなどわからない部分を気軽に質問できる環境があったことも嬉しかったです。
社内ツールの改善
約2週間のキャッチアップが終わった後、セクション内で研修課題がありました。
それが kannushi 改善です。
kannushi とは、N予備校を支える各マイクロサービスの開発環境の管理状況を可視化する Web ツールです。 N予備校の開発では、本番環境へリリースする前に開発環境のデプロイすることでリリース予定のコードの動作を社内で確認できます。 その開発環境の占有するために Slack で声かけ運用していたものをツール化したものになります。
今回の研修課題ではこの kannushi の改善点を洗い出して、開発からリリースまでの一通りの開発手順を約3ヶ月弱で学びました。
kannushi の環境構築
キャッチアップと同じくこちらも環境構築から始めました。
この環境構築がうまくいかず、ビルドしようとすると mimemagic (0.3.5)
という gem が rubygems.org に存在しないというエラーが発生していました。
この原因を突き止めるところからスタートしました。
mimemagic について調べてみると、ライセンス問題1のため v0.3.5以下のバージョンが rubygems.org からなくなっていたのが原因でした。
現在は依存元である Rails のバージョンをあげれば解決するとの記述があったため、 Rails のバージョンアップ(今回は6.0.3.1 → 6.0.3.6にアップデートした)をしました。
この調査で特に大事だなと思った部分は、一次ソースの情報をみることです。
エラー文だったりライブラリ名で検索をすると多くの記事が出てきますが、きちんと説明がされていなかったり解決方法だけが書いてあったりして根本的な解決にならない場合が多いです。 ですので、一次ソースである公式ドキュメントや GitHub を見ることで本質情報が手に入ることが多かったです。ほとんど英語なので気力は必要ですが。
改善点の洗い出し
kannushi の一通りの動作やコードを眺めて、ここがイケていないなと感じる部分をまとめました。 それを費用対効果別で優先度を算出して重要な部分のみ改善していくという流れで洗い出していきました。
この箇所を改善したらどう嬉しいのかをユーザー(社内ツールなので同じ部署の先輩方)にヒアリングして情報収集をしました。 自分が考えた優先度とヒアリングした結果を反映した優先度では違うものが多くあり、現場の声の重要さを感じることができました。
開発
上記で洗い出した改善点を優先度順で開発を進めて行きました。 今回は以下の内容について改善しました。
- 予約機能の搭載
- Faraday のインスタンス作成処理の共通化
- HTTP client を作成し、エラーハンドリングを共通化する
1つ目は機能の改善、2,3つ目はコードの改善になります。
1つピックアップして予約機能の搭載について得たことを共有します。
今までの kannushi では、当日の占有しかできず、未来の占有ができない状態でしたので、日付選択を可能にすることによって予約機能を実装しました。
開発の流れとしては、 DB 設計→ Controller 実装→画面作成→テストコード作成といった流れでした。 個人的に悩んだポイントとしては、予約しようとしている時間帯にすでに占有がされていないかを判定するロジックが複雑だったことです。
ロジックとしては予約時間帯に重なっていない条件式を割り出しその否定をとり重なる条件式を取得します。 その重なる条件式を予約テーブルの中から探してなければ占有できるという流れになります。
重なっていないパターンは、下図のAB2つになります。
この2つの条件を式で表すと以下のようになります。
(終了時間 <= 予約開始時間) OR (予約終了時間 <= 開始時間)
次に、この条件式の否定をとります。(ド・モルガンの法則を使います)
NOT((終了時間 <= 予約開始時間) OR (予約終了時間 <= 開始時間)) ↓ NOT(終了時間 <= 予約開始時間) AND NOT(予約終了時間 <= 開始時間) ↓ (終了時間 > 予約開始時間) AND (予約終了時間 > 開始時間)
そうすると下図のパターンが取得できるようになります。
RailsのActiveRecordでは、not という便利なメソッドが用意されていますので、重なっていないパターンをnotメソッドに記載すれば期待しているレコードが取れそうです。
最終的には下記のような形で書くことができました。(started_atは予約開始時間、expired_atは予約終了時間です。)
Reservation.where.not(id: id).where.not('? <= started_at or expired_at <= ?', expired_at, started_at)
そのままコードに書こうとすると複数条件式を頭の中で整理しながら書くことになり時間がかかってしまいました。 一度落ち着いて条件式を文章で洗い出してから考えるとコードに落とし込みやすくなりました。
このように複雑な判定処理をいかにみやすくコードに落とし込むかを考え、学ぶことができました。
リリース
改善した機能を開発環境にデプロイするのを体験しました。 N予備校ではデプロイ時 Jenkins で自動化されており、ボタンひとつで開発環境にデプロイできました。
ボタンひとつでうまくいくと思いきや、デプロイ後に migration のエラーが発生してしまいました。 この時点でかなり焦ってしまったのですがデプロイする前に作成したリリースチケットがありました。 その中には rollback 手順を記載しメンターにも承認をいただいていたので、なにもわからないという状態にはならず、スムーズに手戻りし原因調査に時間を割くことができました。
原因として今回の改善で予約開始時刻である started_at というカラムを null: false で追加しました。 しかしすでに存在したデータが開発環境にはあったため migration により null: false な started_at が競合してしまいエラーが発生していました。
この経験から焦らず原因調査することとリリース時の流れを掴むことができました。
ペアプロ
こちらは上記の研修課題と同時期に行ったもので、 Kubernetes の勉強が一区切りついたあとに認証認可について学ぼうという話になりました。 そこで簡単なアプリを作ってみようとのことでメンターとペアプロをして開発していくことになりました。 使用する言語も新しく学ぼうと言うことで TypeScript を採用し、Express.js を使って認可フローの仕組みを実装していきました。
このペアプロからは TypeScript の知識取得や OAuth2 の仕組みの理解につながりました。 その他に、メンターがどのように考えてコードを書いているかや、自分がコードを書いているときの説明がきちんと文章化できているかなどが確認でき、目的以上に学ぶことが多くありました。 意外と説明できなかったことや知らなかったコードの書き方などを知れたので、継続してやっていきたいと考えています。
OJT
研修課題が終わり10月から1月末まで部内の案件に参画しました。
ドワンゴ社内の通知基盤をN予備校でも利用しており、大規模な改修があるとのことでN予備校としても修正が必要なものだったので案件が生まれました。 具体的には通知基盤が REST API から gRPC 通信になったことによる送信方法の修正でした。 この案件では自分以外にも中途入社で参画されたメンバーがおり、2人で分担して作業していくスタイルでした。
参画の前に gRPC やN予備校の通知基盤のキャッチアップを行い、どこを修正するのか調査をしチケット化を行っての開発になります。
今回は gRPC のクライアントから作成し新しいファイルを作ることが多かったのですが、メンターやメンバーの方のたくさんのレビューのおかげでわからないところをつぶしながら進めていくことができました。 自分もレビューに参加することもあったのですが、誤字の修正などの軽微なものが多く、ロジックに関してのレビューをできなかったのが心残りです。
通知基盤のv2移行が終わり、複数回に渡ってリリース作業を行いました。 v1とv2を混在したリリース、v2に移行するリリース、コードのリファクタリングをしたリリースの合計3回です。 私は2,3回目を担当しました。
2回目のリリースの際、手順通りにリリースを終え動作確認をしたら通知設定画面が開かなくなってしまいました。 kannushi 改善の際にも rollback の経験をしたので今度は比較的焦らず元の状態に戻し原因調査の時間をとることができました。
焦らずすぐに戻すことで本番での影響範囲を最小限にできました。
おわりに
約半年の研修から、多くのツールや技術に触れたり、一次ソースの重要性や説明できるまで知識を入れることなどたくさんの経験や考え方を学ぶことができました。 リモート環境での勤務だったので最初のうちはなかなか Slack で相談しずらかったり先輩方と話す機会が少なくて不安だったのですが、質問できる場や機会をおおく設けて下さったことで安心へつながりました。
毎日出勤の日々に戻る、なんてことは当分なさそうですが、 ドワンゴのオフィスはすごい綺麗でやっぱりモチベも上がるのでたまには行きたいですね。(電車がつらいので行きたいときに行けるぐらいがちょうどいいのですが)
また、個人的にはセクション内で技術の話題ではなく、趣味やプライベートな出来事で雑談したりできたのがよかったです。
リモート環境での勉強や勤務漬けで一息できる時間がないため、何も考えずにみなさんと雑談できることでリフレッシュできました。
この雑談でメンターにサウナをおすすめされ、すっかりハマってしまい今ではサウナなしでは生きられなくなってしまいました(笑)
現在はN予備校のさらなる改善に向けて、新たな教材の入稿管理ツールを作成する案件に参画しています。 自分のモチベーションの1つであるいろんな技術を吸収したいという考えを飲み込んでくださり、React.js を使ったフロントエンドサイドでの開発に従事しています。
自分は同期のメンバーに比べて技術力もなく、まだまだ足りない部分もたくさんあるのですが、恵まれた環境を最大限に生かして、今後の開発に貢献していきたいと考えています。
We are hiring!
株式会社ドワンゴの教育事業では、一緒に未来の当たり前の教育をつくるメンバーを募集しています。 カジュアル面談も行っています。 お気軽にご連絡ください!
開発チームの取り組み、教育事業の今後については、他の記事や採用資料をご覧ください。
脚注
-
MITライセンスで公開されていたのにGPLライセンスのファイルが含まれていた↩