なりたいエンジニア像

3年後になりたいエンジニア像

エンジニアとしての土台(英語+低レイヤーの知識)を固め、大規模サービスに携わり、バックエンド領域の専門性を高め、バックエンド領域において他の誰よりも深い知識を持つプロフェッショナルになりたい。

実現のために残りの学生生活〜3年目は下記に取り組みます。

  • 英語力の向上
    • 定性的な目標 : 英語の技術書、動画、記事、ドキュメントを翻訳無しで理解できる。
  • 低レイヤーの知識の習得
    • 定性的な目標 : OS、CPU、データ構造、アルゴリズム、ネットワーク、ハードウェアなどのコンピューターの仕組みを自分の言葉で説明できる。
  • バックエンド領域の専門性を高める
    • 大規模サービスに携わり、データベース(設計、インデックス、大規模データの取り扱い、データの一貫性など)、パフォーマンス(ボトルネックの特定、キャッシュの利用など)、セキュリティなどのバックエンド領域における幅広い経験を積む。
    • Backend Developer Roadmapの理解が浅い部分を深める。
    • カンファレンスやイベントで登壇し、知識を体系的に整理し、他のエンジニアからフィードバックを得る。

5年後になりたいエンジニア像

小規模サービスに携わり、バックエンド領域以外の知見を広げ、システムの全体像を理解し、チームを技術面でリードし、マネジメントできるエンジニアになりたい。

実現のために4年目〜5年目は下記に取り組みます。

  • バックエンド領域以外の知見を広げる
    • 小規模サービスに携わり、バックエンド領域に軸足を置きつつ、サービス開発における幅広い経験を積む。
  • マネジメント力の向上 
    • チームメンバーや他のステークホルダーと積極的なコミュニケーションを心がけ、コミュニケーション力を上げる。
    • エンジニアの生産性を重視し、適切なサポートやリソースを提供するために、チームメンバーと議論を繰り返し、エンジニアの働きやすい環境を整える提案を行う。
    • 他エンジニアのリソースや進捗にも目を配り、プロジェクト全体の管理能力を磨く。
    • 質の高いコードレビューを通して、システム全体の品質を上げる。

10年後になりたいエンジニア像

エンジニアリングの専門知識と経験を活かしつつ、ビジネスの要件や戦略を理解し、ビジネス面と技術面の両面で事業の成長に貢献し続けられるエンジニアになりたい。

実現のために6年目〜10年目は下記に取り組みます。

  • 新規事業立ち上げ
    • ユーザーに真摯に向き合い、人々が欲しがるプロダクトを作る。
    • 適切な意思決定(技術選定、アーキテクチャ設計、システムの導入など)を行うために、常に最新の技術を追いかけ、継続的に学習に取り組む。
    • ビジネスの要件や戦略を理解し、事業の成長に貢献するために、ビジネス領域(マーケティング、財務など)の知識を補強する。
    • ビジネスサイドとのコミュニケーションを増やし、ビジネスの視点やニーズをより深く理解し、技術的戦略の提案を行う。

3年後/5年後/10年後のキャリアプラン

3年後 : バックエンドエンジニア

5年後 : テックリード

10年後 : CTO

なぜ1つの技術領域(バックエンド領域)を極めたいと考えているのか

  • RubyKaigi 2023で他の技術者と差別化を図るため+プロフェッショナルとして生き残るために、特定の技術領域において他の誰よりも深い知識を持つという武器を身につける必要があることを学んだから。
  • バックエンド領域に興味があるから。

なぜバックエンドエンジニアなのか

  • 裏側のロジックを構築することが楽しいと感じるから。
  • システムの基盤を担当することに魅力を感じるから。

なぜテックリードなのか

CTOというキャリアパスを考えているため、チームを技術面でリードしていく経験を積みたいから。

なぜCTOなのか

技術で貢献していきたいのと事業を作ることに興味があるから。

なぜ最初に大規模サービスなのか

前提として、最初は1つの技術領域(バックエンド領域)を極めたいと考えています。

  • 大規模サービスでは、大量のリクエストや大量のデータを処理し、安定した運用が求められるので、単に動作するコードを書くだけでなく、パフォーマンスの最適化や適切なデータ構造やアルゴリズムの選択など、バックエンドに関する深い知識を磨くことができるから。
  • 大規模サービスでは、チーム内の分業化が進んでおり、バックエンドエンジニアはバックエンドの領域に特化しているので、バックエンドに関する深い知識を磨くことができるから。
  • 1つの技術領域に精通することで、他の技術の習得も容易になるから。

なりたいエンジニア像のその先に何を成し遂げたいのか

なりたいエンジニア像のその先は、人生のビジョンである「何かを残す人生にしたい」を体現する「自分が居なくなった後も多くの人の役に立つようなプロダクト」を作っていきたいと考えています。

なぜ何かを残す人生にしたいと思うようになったのか

大学1年生の時に⽣まれて初めて⾝近な⼈が亡くなり、遺体から遺⾻になるまでの過程を⾒たので「⾃分もいつか死ぬんだ」と強く実感しました。そこから「どんなに⼤切な物があろうとも、死んだら何も持っていくことはできない。でも残していくことはできる。この残したものこそ⼈⽣の集⼤成なのではないか?それなら何かを残す人生にしたい」と思うようになった。

なぜ事業を作っていきたいのか

IVS2021 NASU*1にスタッフとして参加させていただいて、事業家たちの熱い想いに触れて自分もいつか事業を作っていきたいと思ったから。

*1:日本最大級のスタートアップ企業経営幹部が集まるカンファレンス&コミュニティ

ユーザー間のコードレビューサービス「Duet Code」をリリースしました

サービスの概要

Duet Codeは、①プライベートで書いたコードをレビューしたり、されたりする機会が無い問題②他の人が書いたコードを読んだり、自分の書いたコードに意見を貰うことで、技術力を上げたいニーズを解決するサービスです。レビューしてほしいプルリクエストを投稿し、レビュアーを募集することができます。ログインすることでレビュイーにもレビュアーにもなることができます。

開発理由

プライベートで書いたコードをレビューしたり、されたりする機会が無い問題を解決したかったからです。現状、プライベートだとコードをレビューする機会が無く、プライベートで書いたコードをレビューしてもらえるサービスはMENTAくらいしか無く、契約制(有料)ということもあり、ハードルが高く、もっと手軽にコードレビューが出来たらいいなと思い開発しました。

使用技術

バックエンド

フロントエンド

API関連のコードOpenAPI Generator TypeScript Axiosで自動生成しています。

インフラ

テスト

CI/CD

Lefthookを使用してコミット前にESLintPrettierRuboCopを実行し、コードの品質を保っています。

環境構築

外部サービス

技術選定

Ruby on Rails

他選択肢 : Laravel, Django

選定理由 : 

Next.js

他選択肢 : React, Angular, Nuxt.js
選定理由 :

  • CtoCサービスなのでSEOを意識する必要があり、Pre-renderingをサポートしているから。(React単体ではPre-renderingをサポートしていない)
  • 実務でReactを使用しているので、Angular, Nuxt.jsに比べて少ない学習コストで習得できると思ったから。

TypeScript

他選択肢 : JavaScript, Flow
選定理由 :

  • 型を付与することでプログラムの可読性が向上したり、エディターの補完機能が効いたり、タイポやバグの早期発見が可能だから。
  • Googleトレンドで定常的にFlowよりTypeScriptが優位だから。

Tailwind CSS

他選択肢 : Bootstrap, Chakra UI, styled-components
選定理由 :

  • デザインに可能な限り合わせたかったから。
  • インラインで疑似クラスやレスポンシブ対応できるから。
  • クラス名を考える必要がないから。

MUI

他選択肢 : Bootstrap, Chakra UI
選定理由 :

Fly.io

他選択肢 : Heroku, Railway, Render.com
選定理由 :

  • 無料枠があるから。
  • 一定時間アクセスが無くてもスリープしないから。(Render.comの無料プランだと15分間アクセスが無いとスリープする)
  • 一定期間後にデータベースが初期化されないから。(Render.comの無料プランだと90日後にデータベースが初期化される)
  • 日本語のドキュメントが充実していて、導入が簡単だから。

Vercel

選定理由 :

  • Next.jsとの相性が良く、導入が簡単だから。

Rspec

他選択肢 : minitest
選定理由 :

  • 実務でRSpecを使用しているので、minitestに比べて早く開発できるから。
  • APIテストの便利メソッドが格納されているcommittee-railsREADMEがRSpecで書かれているから。

Cypress

他選択肢 : Selenium
選定理由 :

  • Cypressをインストールするだけで導入が簡単だから。(SeleniumSelenium以外もインストールが必要で手間がかかる)
  • UIが直感的で分かりやすいから。

GitHub Actions

他選択肢 : CircleCI
選定理由 :

Docker

他選択肢 : VirtualBox
選定理由 :

  • 同じ環境を再現することが容易だから。
  • VirtualBoxはホストOS上で完全な仮想化を行い、ゲストOSを起動するためオーバーヘッドが発生し重たいですが、DockerはホストOSのカーネルを共有するため、ゲストOSを起動する必要が無く軽量だから。 

Firebase Authentication

他選択肢 : Auth0
選定理由 :

使用方法

レビュイー

①「ログイン」or「無料で始める」をクリックして、GitHub認証でログインします。

②ヘッダーの「募集する」をクリックします。

③「タイトル」「プルリクエスト」「使用言語」「プルリクエストの説明」「レビューしてほしい点」を入力して「保存する」をクリックします。(GitHub APIを使用してPublicリポジトリのプルリクエストを取得しています)

④レビュアーが「レビューする」をクリックすると通知が届きます。また、レビュアーが「レビューする」をクリックすると、GitHub APIを使用して自動でリポジトリのコラボレーターに追加され、レビュアーにレビューリクエストが届きます。

⑤レビュアーがプルクエストをApproveして、フィードバックを送信すると通知が届きます。通知をクリックし「お礼する」をクリックして、お礼を送信します。お礼を送信するとレビューは完了になります。

レビュアー

①「ログイン」or「無料で始める」をクリックして、GitHub認証でログインします。

②レビュー募集中からレビューしたい投稿を探します。レビューする場合「レビューする」をクリックします。「レビューする」をクリックすると、GitHub APIを使用して自動でリポジトリのコラボレーターに追加され、レビューリクエストが届きます。プルリクエスト上でレビューを行い、問題が無ければApproveしてください。プルリクエストをApproveしたら「フィードバックする」をクリックして、フィードバックを送信します。

③レビュイーがお礼を送信すると通知が届き、レビューは完了になります。

工夫した点

スキーマ駆動開発を導入しました

スキーマ駆動開発とは、OpenAPIの仕様書を最初に定義し、その仕様書をもとにバックエンドとフロントエンドの開発を同時に進める開発手法です。スキーマ駆動開発を導入したことでフロントエンド側、バックエンド側にメリットがありました。フロントエンド側は、openapi.ymlからAPIクライアントのコード自動生成できるので、余分なコードを書く必要が無くなったり、リクエストとレスポンスに型が付与されているので安全に開発を行えたり、モックサーバーを立てることでバックエンドの実装を待つことなく、フロントエンドの実装を進められたり、ドキュメントを見れば、どんなリクエストを送れば、どんなレスポンスが返ってくるのか分かるので、バックエンドのコードを読みに行く必要がなく楽でした。バックエンド側は、OpenAPIの仕様書を最初に定義しているので、実装すべきことが明確で迷うことなく実装できました。

GitHub APIを導入することでユーザーの手間を減らし、UI/UXを改善しました

レビュー自体はプルリクエスト上で行うことを構想していたのですが、①レビュイーがレビュアーをリポジトリのコラボレーターに追加する②レビュアーが招待を承認する③レビュイーがレビュアーにレビューリクエストを送るという手順が必要でした。これを手動で行うとレビューをするまでに数日かかってしまいます。この手間を省くためにGitHub APIを導入し、レビュアーが「レビューする」をクリックするだけで手順を自動化し、UI/UXを改善しました。

苦労した点

Firebase AuthenticationのidTokenを用いてバックエンドで検証し、UIDをDBに保存するまでのJWT認証の実装に苦労しました

フロントエンドからFirebase Authenticationに認証情報を送る②認証に成功するとidTokenが返却される③フロントエンドからidTokenをバックエンドに送り、idTokenを検証するメソッドが格納されているfirebase-auth-railsを使用して、改竄されていないか検証する④検証に成功するとpayloadが返却されるので、payloadからuidを取得してDBに保存するまでのJWT認証の流れを理解し、ミニアプリを作って試しながら、理解を深めて実装していきました。

なぜFirebase Authenticationを導入したのか

  • 様々な認証プロバイダをサポートしていて、GitHubログインを簡単に実現できるから。
  • OAuth/OpenID Connectなどの認証プロトコルをサポートしていてセキュリティの高い認証フローを実装出来るので、自前で認証を構築し、GitHubのメールアドレス、パスワードをDBに保管するより安全に管理できるから。

なぜidTokenを検証する必要があるのか

idTokenはBase64で暗号化されており、第三者でも簡単に復号できてしまうため、改竄される恐れがあるから。

なぜスキーマ駆動開発を導入したのか

使用したことのない技術を多く使用していて、実装前に技術をキャッチアップしたのですが、バックエンドの実装が完了してからフロントエンドの実装を進める手法だと、余分なキャッチアップコストが掛かってしまうと思ったので、同時並行で両方の実装を進めたかったから。

作り直したい部分

バックエンドのインフラをFly.ioからAWSGCPなどのパブリッククラウドに作り直したいです。理由は2点あります。1点目は、実務ではAWSGCPなどのパブリッククラウドが一般的に使用されているため、AWSGCPなどのパブリッククラウドに作り直すこと自体が勉強になるからです。2点目は、Fly.ioダッシュボードは見づらく、カスタマイズに制限があり、スロークエリの特定やトレースの確認、CPUの使用率、メモリの使用率、リクエスト数、レイテンシなどのアプリケーションのパフォーマンスに関する指標が把握しづらいため、サービスを運用していく上で不便に感じているからです。

自信のあるコード

routescontrollerです。DHHはどのようにRailsのコントローラを書くのかという記事を参考にデフォルトのCRUDアクションであるindex show new edit create update destroyのみを使うようにしました。

フィードバックをどう改善したのか

RubyKaigi 2018のデザインを担当されたmachidaさんにフィードバックをいただき、キャッチコピーを変更したり、デザインを改善しました。他にも面接で「パフォーマンスは推測するのではなく、計測した方がいい」というフィードバックをいただき、APMツールを導入し、パフォーマンスチューニングをしました。

どんな学びを得たのか

  • 個人開発は長期戦になるので、モチベーションを管理するのが一番難しい。最初から完璧を目指すのではなく、まずは終わらせることを意識する。
  • 記事は参考になるが誤植もあるので、一次情報を見る癖を付けた方がいい。
  • 1ヶ月前に書いたコードが何をしたいのか分からないことがあるので、出来る限りコードは綺麗に書く。
  • エラーの大半はログを見れば解決する。
  • 技術はアウトプットすることで理解が深まる。
  • 要件定義、プロトタイピング、リソース設計、DB設計、実装、テスト、リリースをやってみてサービス開発の全体像が分かった。
  • フロントエンド、バックエンド、インフラをやってみてバックエンドの開発をしている時が一番楽しいと感じることに気付いた。