新卒エンジニアがGoでサーバーサイドを学んだ話【研修振り返りレポート】

by Hyu Ogawa | November 11, 2021
new-graduates | #new-graduates #golang

こんにちは。2021 年新卒エンジニアの小川です。

今年の DeNA の新卒エンジニア研修は 4 月中旬から 6 月末までの 2 ヶ月半という長い期間で行われました。本記事ではサーバーサイドの学習に焦点を当てて、具体的にどのような研修を行なっていたのか、その概要と私が何を感じたかをお伝え致します。

ある程度今まで Go もサーバーサイドも経験があり、ある程度は分かっているつもりでしたが、想像以上に広範で、コーディングスキルだけでなくエンジニアとしてのスキルを全体的に鍛え上げられた非常に楽しい期間でした。

Go とは

新卒エンジニア研修のサーバーサイドの実装では Go というプログラミング言語を用いました。Go は新卒エンジニア研修のアプリ開発で利用した Flutter と同様 Google にて設計された言語で、静的型付けを行いながらも動的型付け言語のようにコーディングが容易であるという特徴があります。学習コストの低さだけでなく、幅広い用途で求められる要件を満たす汎用性も備えることから、エンジニア研修で取り扱うにあたって適切なプログラミング言語であったと思われます。

研修の概要

厳密にこれに従っている訳ではありませんが、主な研修の内容は以下の通りです。ただし、Go の研修と同時に Dart/Flutter を用いたフロントエンドの研修も行っており、主に午前中に Go の研修が行われておりました。特に最初は同じ内容を Go と Dart で書くことが多かったので、Dart 側に焦点を合わせた他の方が書いた記事も読んでいただけると幸いです。

  • 1週目:Go の基礎文法・基本的なデータ構造・プログラムが動く原理
  • 2週目:HTTP
  • 3週目:Driving Questions・SQL・認証
  • 4週目:SQL・redis、nginx・クリーンアーキテクチャ
  • 5週目:クリーンアーキテクチャ・テスト

1週目

Go の基礎文法

勿論新卒メンバーの中には今まで Go を扱ったことがない人もいるため、Go がどのような言語であるかを講義+演習形式で行いました。講義ではあまり多くのことの説明は行わず、演習の際に分からないことを調べて学びながらやる形です。2 日目以降では Go らしいコード・綺麗なコード を意識するよう、実際に演習で同期が提出したコードを見比べて「どういうコードが望ましいか」と議論も講義中に行っていました。

演習ではコーディングテスト等で出題されるような非常にシンプルな課題を Go で実装しました。2人1組での ペアプログラミング(以下、ペアプロ)での形式でコーディングを行いました。以降もペアプロ、もしくは 3 人以上で行う モブプログラミング(以下、モブプロ)での演習が続きますので、これについては後述します。

基本的なデータ構造

Go の基礎文法を学ぶと同時に、基本的なアルゴリズムとデータ構造についても講義、演習がありました。講義で連結リスト・ハッシュテーブルの概念について学習した後に、ペアプロ形式でそれを実装する、といった形でした。

Go の基本実装・基本的なデータ構造では演習に Replit というサービスを活用していました。活用していて以下の点で非常に優れていると思われます。

  • エンジニア研修自体が全体研修終了直後から始まっており、人によっては環境構築がまだ出来ていない。ローカル環境を整えるための時間稼ぎになる。
  • 実装に関して必要な環境が一通り揃った状態でコーディングを行い、提出まで可能。
  • 複数人での同時編集やコメント機能に対応しており、ペアプロや研修中サポートをしてくださる先輩、講師からの review を受け取ることが出来る。

プログラムが動く原理

Go の領域ではありませんが、とても大切な概念である点、講義の時間が Go の時間を利用して行われていた点から取り上げさせていただきます。ここではトランジスタを組み合わせて出来る AND/OR/NOT ゲートからどのようにして各種演算がハードウェア的に実装され、CPU にて計算が行われているのかを学びました。

コンピュータサイエンスの領域で大学でも学ぶことがある領域ですが、突然「全加算機を実装してください」と言われると考え込むものです。アセンブリ言語も少し扱って CPU 命令実行サイクルについて学ぶなど、知っている人には復習になり、知らない人にはとても新鮮な世界を垣間見ることができたと思います。

2週目

この週から Go を用いたサーバーサイドの勉強の側面が強くなっていきます。また、この週から演習について Replit を用いた環境からローカル環境に環境を移し、提出も GitHub 上で行うようになりました。ペアプロの際には Visual Studio Code の Live Share 機能を用いているところが大半だったと思います。

HTTP

HTML の木構造や Cookie を用いたセッション、Representational State Transfer についても簡単に学ぶなど、HTTP について学びました。完成済みの API サーバーをローカルで動かし、Postman を用いてその API サーバーと通信を行うことでセッションの挙動について理解をした上で、簡単なセッションを用いたサーバーを実装してみる、といったことを行いました。

最後にはログイン・ログアウトに加えて何かしら自由にエンドポイントを追加し、セッションを用いた簡易的なゲームのAPIサーバーを作りました。

3週目

Driving Questions

Driving Questions(DQ) も Go やサーバーサイドに直結する内容ではないですが、とても重要な概念であるため、取り上げさせていただきます。

Driving Questions とはエンジニアが問い続けるべき問題で、講義中では以下の 3 つに対して焦点を当てていました。

  • より成長・より良いキャリアを歩むエンジニアは何をして上手くいっているのか。
  • 高品質なシステムを作るにはどうすれば良いか。
  • チームとして効率良く開発をするにはどうすれば良いか。

これに対してはある程度講師の方が答えを用意していたのですが、講義中に「その答えは正しいのか・必ずしも当てはまる訳でもなく、他の正解があるのではないのか」という意見が出るなど、議論が白熱しました。

逆に「これは大事だよね」と共感出来る箇所も多い講義でした。個人的な意見ですが、「大事だよね」と共感するのは大事ですが、それは「自身が普段意識してそれを考えているか」を伴うことで初めて実現できることであり、それが出来ていない以上忘れてしまっており、無意味なことです。「大事だよね」と共感すると同時に、「それを意識していよう」と注意を向けることが出来た、という意味でも非常に有意義な時間でした。

SQL とそれを用いた認証機能

データベースとは何なのか、その種類、SQL と NoSQL の比較やトランザクションが満たすべき ACID についても学びました。実際に PostgreSQL を利用してさらにインデックスによるパフォーマンスチューニングの重要性を体感したり、基本的なクエリを用いた 100 本ノック(実際は 10 問程度です)も行いました。

さらに、実戦での活用例として 1 週間前に行ったセッション管理を利用し、とあるサービスの認証機能の実装も行いました。この際に ID を連番にすべきか UUID/ULID を活用すべきか、他に良いものは無いかの議論が起こるなど、この時期にはペア内・チーム内での小さな疑問から全体で議論を行う良い風潮が出来ていたと思います。

また、SQL においては PARTITION BYCOALESCE 等、普段あまり使わないような構文も積極的に学ぶ姿勢を取ることで見えてくるなど、多くのことを学ぶことが出来ました。

4週目

Redis・NGINX を利用したサービスの高速・堅牢化と docker による構築の簡易化

認証含めとあるサービスの API サーバーの一部分を作成していたのですが、これに Redis・NGINX を加えてより堅牢・高速なサービスを作成しようというものです。Redis が key-value store である事を踏まえてサービスに追加実装をし、NGINX を用いてリバースプロキシ、ロードバランサーを設置して負荷分散を行いました。

これらの実装手法のような形で docker を利用しました。既に今までの研修で docker 自体は利用していたのですが、ここでちゃんと学び直し、そもそも docker がどのような技術であるかを理解することが出来ました。

クリーンアーキテクチャ

クリーンアーキテクチャの概念を学び、実際に既存サービスをクリーンアーキテクチャに従ったものに直してみる、といったことをしました。実際にコーディングをする際にあたり、可読性のある構造でコーディングを行う構造化の方法の 1 つとしてクリーンアーキテクチャを学び、実際に触ってみてそのメリット・デメリットを知りました。

5週目

テスト

ユニットテストを中心にクリーンアーキテクチャの中でどのようにテストを行うかを学びつつ、今まで作成していたコードにテストを追加する、といったことをしました。先週に行ったクリーンアーキテクチャを採用したプロジェクト上ではテストが非常に行いやすいコード構造をしていることを把握した上で、適切な可読性を維持しつつテストコードを書く、といった経験をしました。

ペアプログラミングについて

研修においては、ペアプログラミング(ペアプロ)を中心に時々モブプログラミング(モブプロ)で課題に取り組む形式を取りました。一般的に 1 名がドライバとしてコーディングを行い、他のメンバーがナビゲータとして意見を発することでコードの質を高めたり、効率よくプログラミングを行うことが出来るというものです。研修中においても「互いの学習量を最大化する」という観点に重きを置いた上でペアプロ・モブプロを行っていました。また、ペアやチームによっては各自が分担してコーディングを行い、後でレビューし合う等といった形式を取るところもあり、この辺りは各自が多くの学びを得るためにどうすべきか考え、その場その場で取るべき形で行っていたと思います。

研修を通じて感じたこと

私は入社時点で

  • 独学でサーバーサイド・フロントエンドの開発を趣味レベルで行っていた
  • 過去アルバイトで Go を用いた WebSocket サーバーの開発経験がある

という状態でした。特に序盤の Go の基礎やコンピュータサイエンスで扱う内容に近い箇所を学んでいる最中ではかなり復習に感覚が近く、ペアプロを行う相手にもよりますがナビゲーターとしてドライバーにヒントを出したりこうすべきとアドバイスをすることが多かったです。

ただし、その中でも「ただひたすら課題を消化して研修を終える」という時間の過ごし方は避けたいと思い、最初から「その課題から何を得るか」については常に注意して過ごしていました。同期の間で「課題をどのように解き、その間に何を学ぶか」を最初に話すことで、既に開発経験ある人でも無い人でもそれぞれが何かしら有用なものを得ていくことは出来ていたと思います。

実際これは途中でメンターに相談したことですが、「ペアプロの際に実力差がある場合(どちら側でも)はどのようにすればお互いのためになるか」という課題があります。基本的により実力のある方が導くような動き方が取られがちですが、この際に自分は「相手がどのような学びのスタイルを取るのか」に注意する必要があると考えて行動していました。特定の専門分野に対して深く鋭く学ぶことが好きな人や、浅く広く学ぶことが好きな人がいます。相手の好みに合わせて自身の知識や経験を使って相手の学びを誘発し、逆に自分自身もその過程を通じて新しくその周りの知識や、チーム全体としての学びを最大化する経験を得ることが出来ました。

このように、私自身にとっては自分自身のコーディングスキルよりもチームとしてのアウトプットを上げていく中でどのように立ち回る必要があるのかについて考え、試行錯誤して、時によっては仲間からフィードバックを貰うことが出来た非常に重要な期間でした。

実はこの研修のゴールの一つとして「自走力」というワードが設定されており、そのせいかよくも悪くも、この研修は自由度が非常に高く設定されていたと思います。実際に私達の研修では途中で研修の進め方について議論が幾度と行われ、その形式が少し変わったりもしました。恐らく毎年研修の雰囲気も、実際各自が学んでいったことも違ったものだと思われます。以降の研修はまた未来の新卒エンジニアの手によって「どうあるべきか」議論され、彼らに合うように行われるのでしょう。

おわりに

本記事では、2021年の新卒エンジニア研修における Go を用いたサーバーサイド研修にて私達が学んだことをお伝え致しました。

DeNA の新卒エンジニア研修ではどのようなことをしているのか、その雰囲気が伝われば幸いです。2021 年の新卒エンジニア研修に関する記事は既に他にも公開されております。もし良ければ読んでいただけると幸いです。

この記事を読んで「面白かった」「学びがあった」と思っていただけた方、よろしければ Twitter や facebook、はてなブックマークにてコメントをお願いします!

また DeNA 公式 Twitter アカウント @DeNAxTech では、 Blog記事だけでなく色々な勉強会での登壇資料も発信してます。ぜひフォローして下さい!