CA Tech Dojoで最優秀賞を頂いた話

f:id:ariku1021:20210419123129j:plain 2021年2月15日〜2021年3月5日で,CyberAgent が企画するサーバサイド向け育成型インターンシップ CA Tech Dojo に参加していました.

そこで最優秀賞を頂きました!

今回はこのインターンの振り返りをしていこうと思います.

CA Tech Dojoの内容

このインターンでは,Go 言語を用いてゲーム API を開発しながら様々なことを学んでいきます.

基礎課題と発展課題が与えられていて,基礎課題が終わった人から発展課題に取り組んでいくような形になっています.

基礎課題では,与えられた API の仕様に沿った "とりあえず動く" API を作り,発展課題では,基礎課題で作った API を改善していきます.

目標

このインターンでは以下の3つのことを目標にしていました.

保守性の高いコードを書くこと

保守性の高いコードを書くために,アーキテクチャを改善したり,ユニットテストを書いたり,CI を回したり,ログ出力を考えたりしました.

その結果,「保守してもいい」と自分自身で思えるコードを書くことができました.

わからないところを放置しないこと

わからないところがあったとき,少なくとも自分自身が納得できるまで,調べたり,メンターの方々に質問していました.

その結果,より深い知識を吸収することができました.

他の Dojo 生と知見を共有し合うこと

私が学んだことを他の Dojo 生と共有するのはもちろんのこと,他の Dojo 生が学んでいることに対して,知見を共有していただいたりしていました.

例えば,同じチームでuber-go/zapを用いてログ機能を改善している人がいたので,ライブラリの使い方や,アクセスログとアプリケーションログの使い分け,ログレベルの使い分けなどについて教えていただきました.

また,インターンがない土曜日には,他のインターン生と知見を共有する LT 会を開き,知見を共有していました.

発展課題で行ったこと

私は,最初の3日間程度で基礎課題を終わらせ,残りの時間を発展課題に費やしました. 発展課題では,以下のような様々なことを行いました. f:id:ariku1021:20210401193338p:plain この中のいくつかを紹介していこうと思います.

アーキテクチャ(Clean Architecture)

Clean Architecture の概念を理解し,それを Go 言語の package 構成に落とし込み,実装しました.

package 構成を考えるのはかなり大変でしたが,メンターさんと何度も相談し,ある程度自分の中で納得できるような package 構成を考えることができました.

詳しくは,Qiita に記事を書いているのでもしよければ参考にしてください.

qiita.com

マスタデータのキャッシュ

ガチャの排出率やアイテムデータなどのマスタデータを毎回 DB から取得していると無駄が多くなってしまいます. マスタデータは頻繁に書き換わるものではないので,あらかじめ DB から取得しておいて,オンメモリにキャッシュしておくことで高速にマスタデータにアクセスすることができます.

私は,オンメモリにマスタデータを乗せるだけではなく,マスタデータが変わったときのために定期的にキャッシュを更新するような処理も書きました.

(今回のインターンでは時間的都合により以下のような処理を書いていますが,無駄が多く,改善した方が良い部分が多いです.)

まず,マスタデータを定期的に取得し,キャッシュを更新するような処理をgoroutineで走らせます. f:id:ariku1021:20210401193004p:plain しかし,このままでは,同一キャッシュに対して同一タイミングで書き込みと読み込みを行ってしまう可能性があるため,スレッド安全性を気にする必要があります.

そこで,次のような構成を考えます. f:id:ariku1021:20210401193058p:plain キャッシュの書き込みの前後と読み込み前後にLockをかけます.このようにすることで,書き込みと読み込みが同一タイミングで行われることを防ぐことができます. しかし,次のような問題点があります.

  1. キャッシュの読み込み同士は同一タイミングで行なっても良いはずだが,それに対しても待ち時間が発生してしまう

  2. キャッシュの書き込みをしている間は,読み込みは待機しているので,書き込み時間が長ければその分だけ待ち時間が発生してしまう

そこで,次のような構成に変えることで,問題点を解決しました. f:id:ariku1021:20210401193135p:plain まず,キャッシュの読み込みに対してはRLockを使うことで,読み込み同士で待ち時間が発生してしまうことを防ぎました.

次に,キャッシュへのポインタを用意し,裏で新しいキャッシュを作成し,ポインタ先を移し替えるときだけにLockをかけます. このようにすることで,キャッシュの書き込み時間が長くてもその分だけ待ち時間が発生してしまうことはなく,ポインタ先を移し替える時間だけに抑えることができました.

Redis の sorted set を用いたランキング機能

もともと MySQL を用いて SELECT ~ ORDER BY high_score DESC;とランキング取得していたものを,Redis も用いることで高速化しました.

詳しくは,Qiita に記事を書いているのでもしよければ参考にしてください.

qiita.com

CA Tech Dojoの良さ

メンターの方々のフィードバックが手厚い

このインターンでは,PR を出してメンターの方々にレビューをしていただくのですが,かなり細かい部分までレビューをしていただきました.

例えば,Go 言語におけるコメントの書き方のルールや,わかりやすい変数名の付け方,スライスのメモリ確保など,自分だけでは気づけないようなことまで指摘していただきました.

また,PR 以外にも,1日に1時間メンターさんが必ず zoom を繋いでくれる時間があり,技術的なことだけではなく,就活の相談や CyberAgent での実務のことなど様々なことについて話をすることができました.

また,インターン終了後には,人事の方から成績表をいただけるので,自分の良かった点・悪かった点を振り返ることができました.

発展課題の自由度が高い

基礎課題では,開発内容が決まっていますが,発展課題では,各自好きなことを行うことができます.したがって,自分の興味がある技術を深めることができます.

私は,上で挙げたようなことを主に行いましたが,gRPCを導入したり,Prometheusを用いて負荷分析を行なっている人,さらには,セキュリティに興味がありパケット解析をしている人などがいました.

まとめ

強いエンジニアが多く参加している中で,エンジニアとしての実務経験がほとんどない私が最優秀賞を取れたことはとても嬉しく,今後の自信にもなりました! 3週間という間,様々なことで助けていただいたメンターの方々,人事の方々,インターンに参加していた方々,本当にありがとうございました!

他の Dojo 生のブログ

hiyoko-coder.hatenablog.com

note.com

note.com

person.hatenablog.jp