いかにして未経験から4年間でフルスタックエンジニアになったか

## TL; DR

- 案件ガチャで未経験分野の案件に参画し続け、使用する技術がどんどんモダンな方向に進みまくった結果としてフルスタックになることができたという話
- 未経験技術での仕事の話が来たときでも今できないからやらないという姿勢ではなく、積極的に挑戦することでスキルを身につけることができた
- フリーランスや受託の場合、フルスタックな人材であればあらゆる業務をこなすことができかなり有利だと思われる
- 新しい技術はプライベートに加えて業務中に学習して身につけるのがベスト。なぜなら週40時間もの時間をプログラミングに使うことができるから
- 未経験でもポートフォリオを自分一人で作ればフルスタックな人材になれるのではないかという話。ただし毎週20時間は必須

## はじめに
先日お邪魔させていただいた交流会にて、自分が持っている技術スタックが比較的希少なものである、ということを知らされました。
自分としてはコンピュータサイエンスの知識も薄く、まだまだ毛が生えていた程度の技術しかないと考えていましたが、未経験の方や経験年数の浅い方達からするとフロントエンドとバックエンドからクラウドまでこなし、かなりレベルの高いエンジニアとして認識していただけたようです。
一応現在の私の4年間の技術スタックを主にプログラミング言語とフレームワークに絞って簡単に並べてみると、

- フロントエンド: TypeScript, React, Next.js, Vue.js, Nuxt.js, Jest, Enzyme, JavaScript, jQuery
- バックエンド: Kotlin, Java, C#, PHP, Spring Boot, .NET MVC, CakePHP
- クラウド、その他: プライベートクラウド(AWSのEC2, RDS, Route53, S3相当), AWS S3, Consul, Prometheus, Alertmanager, Grafana, Jenkins, Ansible

といった具合ですね。
私のスキルを一言で表現すれば、
「新規開発案件あるいは既存サービスのリプレイス等において、フロントエンドとバックエンド双方の視点からアーキテクチャやインターフェースを設計するなどの、フルスタックな技術的提案および実装が可能なエンジニア」
になると考えています。
この業界には上には上がいて、自分では本気で未熟なエンジニアだと思っています。
ただ先日の交流会の参加者さんの場合を考えると、こちらでも私の話が参考になる場合もあるかと思いますので、今回の記事ではいかにして自分がこのような技術スタックを持つことができたのか、自分の技術を振り返るとともに、考察してみたいと思います。

## 言語別業務経験と学習方法および考察

### PHP時代
未経験で入社したSES企業にて、半年間自社で学習。
オライリーやハンズオン形式の書籍を用いてLAMP環境での開発方法を習得。
その後案件に参画、フレームワークを使わないネイティブのPHP案件やCakePHPを用いた案件に参画。
フロントエンドに関してもHTML,CSS,Javascriptを用いて対応し、比較レガシーな環境ではあったがいわゆる一般的なWebアプリ開発を開発した。

#### 考察
動的型付け言語であるPHPから私のキャリアは始まりました。
未経験にもかかわらず、採用していただき、半年間の学者期間を設けていただいたのが今ではかなり希少なことかもしれません(今の時代に未経験で業界に入ろうとすると、CSの学位を取得していたり、プライベートではポートフォリオを作ったりする必要があるはずですので…)。
そのためPHPではありましたが、プログラミングの習得には十分な時間を持って取り組み、業務ができるレベルには成長でき、実際業務をこなすことができました。
単純に計算すると、学習期間に使った時間としては8時間 x 20日(1ヶ月) x 6ヶ月 = 960時間で、ほぼ1000時間ですね。
プライベートでポートフォリオを作成したりする人と単純に比較するのはできないでしょうが、自分の時間を使って1000時間ほどプログラミング に取り組めば、十分な作品ができ、就職・転職に足るようなものができるのではないでしょうか。

### Java時代
PHPの案件が終了したため次の案件に移る必要があったが当時PHPの案件がなく、会社的に人員リソースを持て余すことはありえないため次にJava + Spring Bootの追加機能開発の案件を担当することに決定。
案件参画には時間的に1ヶ月ほどバッファがあったため、「スッキリわかるJava」などのJavaの書籍を読んで学習した上で業務に参画した。
学習期間の際はJavaのみを学び、フレームワークであるSpring Bootに関しては業務でのOJTという形で学習。
Thymeleafを用いた古典的なWebアプリの追加開発に携わった。
次の案件でもJavaの案件となり、次はREST APIのみのサーバーサイドの案件に参画。
こちらではJava8のラムダ式を用いた関数型ライクな記述が必須ではあったが、プライベートに簡単にだが学習していたHaskellによってある程度関数型の記述には慣れていたため、苦労はしたものの業務を遂行した。
自ら積極的な姿勢を示して働いた、コードレビュー文化の方なかった現場で直接レビューをしたり、ユニットテストの導入を行ったりした。

#### 考察
いわゆる案件ガチャのおかげで、動的型付け言語のPHPに加えて、静的型付け言語であるJavaの技術スタックを獲得します。
言語こそPHPからJavaというSIerよりのレガシーな言語ではありますが、技術スタック的には複数の言語を使うことができる、という強みを手に入れることができたと思いますし、異なる型付け方式の言語を学んだことで、プログラミングを抽象して考えることができるようになったと思います。

### C#時代
次の案件ではC# で.NET MVCを用いたWebアプリの作成を対応。
C#は前回利用したJavaと同様な静的型付であることを利用し、Javaを脳内で抽象化して利用、特別業務でのOJT以外にC#を学習することはほとんどなかった(ただしプチ炎上していたため業務時間は長めだった)。
フロント側は間も変わらずHTMl, CSS, JavaScript(jQuery)を用いたレガシーな環境ではあったが、Javaとは異なる言語での静的型付けの言語による経験を積み、新しい技術スタックを獲得。

#### 考察
こういうことを言うと批判されるかもしれませんが、上記の通りC#に関してはほとんど個別の学習を行うことなく、OJTで逐一業務で調査対応するうちに利用できるようになりました。
LINQのような関数型ライクな構文は苦労しましたが、それ以外はJavaの考え方を応用することで業務の遂行が可能でした。
ここから言えることは複数の言語やフレームワークの経験を持っていると、現在の技術スタックを利用して、未経験の技術に積極的に参加して経験を積んでいくいわゆる「わらしべ長者戦略」がやりやすくなる、ということでしょう。
複数言語とフレームワークを利用してきた経験から、未経験の言語でも比較的簡単に言語を習得、業務をこなすことができるようになるということを理解できた期間でした。

### Vue時代
前回の案件が終了する際にフロントエンド要員を求めているチームにジョインする話があり、そちらにジョインすることが決定。
チームの移動には１ヶ月ほど余裕があったので、余裕がある時間やプライベートを使ってVue, WebPack等を学習した。
一般ユーザ向けのサイトのためSEOを考慮する必要があったが、Vue.jsのみだとSEO的に問題があるため、SSR(Server Side Rendering)の実現のためにNuxt.jsの技術調査、および実プロジェクトへの導入も担当。
2, 3ヶ月経過した際に別のチームで同様にVueを使っているという話を聞くことができ、その際にTypeScriptを導入しているとの話も伺ったため、チーム内での協議の上TypeScriptを導入することに決定。導入まで私の方で対応。
管理サイト、一般向けサイトの両方を対応したため、SSR有りと無しの異なるアーキテクチャで複数プロジェクトを作成。
管理サイトにおいてはSpring BootとVue.jsの連携方法についての技術調査が必要だったため、自分の方で技術調査を行い、Spring Boot上でエントリーページを返却し、SPAを実現する対応を実施。

#### 考察
ここでモダンなフロントエンドとフレームワークの案件に初めて携わることになりました。
ここでも1ヶ月程度の十分な時間を取り学習を行い準備をしたため、余裕を持って対応することができたと思っています。
業務内容としてもVue.jsを始めとしてSSRであるNuxt.js, i18n、そしてTypeScriptといったモダンな技術をフルに活用できたため、経験としても大変良いものになりました。

### React時代
前回のVueでの業務経験を活かし、Reactの案件に参画。
すでに作成されているVueプロジェクトをReactへリライトしたうえで、追加機能開発を行うという業務内容であったため、既存のVueプロジェクトを参考にしながら開発を行うことができた。
また今回はReactという別フレームワークではあるが、時間的に余裕もあったことからユニットテスト、既存プロジェクトにはなかったAtomic Design、Storybookを導入し、プロジェクトの保守性や信頼性に貢献した。

#### 考察
Vue.jsの次にReactによる業務を経験し、Angularを含めた三大フレームワークのうち二つの技術スタックを保持することになりました。
サーバサイドでの経験に加えて複数のフロントエンドフレームワークの経験を身につけ、この時点で技術スタックとしてはかなりモダンで強みのあるものになったのではないかと思います。
そして結果としてVueだけでなく、React, Next.js, Redux等の技術スタックを獲得しました。
ただこの時スムーズに学習ができたかというと、Redux等の概念は最初かなり難しく、プライベートでの学習をしなければ難しかったです。
新しい技術に関してはやはり自主的な学習が無ければ習得することができないと実感する案件でもありました。

### Kotlin時代
React再構築業務もひと段落し時間的余裕が生まれてきたときに、別プロジェクトのバックエンドチームの方で人員が不足し始めたことからそちらに参画することが決定。
言語はKotlinであったが、Javaと同様のJVM言語であるため、対応可能であると判断していただくことができ、バックエンドメインに移動しREST APIの開発に従事した。
またフロントエンド側に関しても前回のVue, React, SSR, TypeScriptの知見を活かし、積極的なレビューや基盤コードの構築に貢献。
またクラウド環境でのサーバーインスタンス、DB、DNSの設定を行い、Consul, Prometheusなどの整備された環境に対し、GUI監視ツールのGrafanaを追加。
フロントエンドからバックエンド、そしてクラウドや監視環境についてのフルスタックな業務を行った。

#### 考察
JVM言語であり、モダンな言語であるKotlin。
この言語を業務で使い技術スタックとして獲得したことで、VueとReactというモダンなフロントエンドに加えてモダンなバックエンドの技術スタックを習得することなりました。
加えてプライベートクラウドで基礎的なサービスではありますがクラウドデビューを果たし、監視環境に関しても対応をしたため運用監視面でも経験を得ることができました。
ここまでフロントエンドこそモダンな技術を使うことができていたもののバックエンドに関してはモダンではなかった自分の技術スタックが、この業務を通して全体としてモダンになることができました。

## まとめ、人はいかにしてフルスタックになることができるか
以上が私の簡単な業務経歴で、いかにして各レイヤにおける技術を習得したかをまとめた内容となっています。
これらの内容を振り返ると、私の中で以下の点が言えると思っています。

### 勉強に時間を割きさえすれば、どんな技術でも習得でき、技術スタックを積み上げることができる
PHPでのサーバーサイドでのHTMLレンダリングから始まり、REST APIの開発、フロントエンドフレームワークによる開発、そしてクラウドや監視環境の構築など、文字通りフルスタックな業務を行って貴ました。
未経験の方やフロントやバックエンドの専任の方からすると、どうやって全てのレイヤをこなすことができるのか、と思われるかもしれませんが、業務時間に加えてプライベートの時間を使って学習すれば意外とできることが分かります。
要はインプットとアウトプットに使う時間を最大化することで、未経験の技術も習得することができるわけです。
特に私の場合は業務時間中に新しい技術を触ることができたということが大きかったと思っています。
というのも単純に計算すれば8時間 * 5日間 = 週40時間もの時間を使って新しい技術を触ることができるわけです。
業務の都合上どうしようもないこともあるでしょうが、時間さえかければ新しいスキルの習得は不可能ではない、ということを身をもって体感した4年間でした。

### 積極的に業務に携わることで他者からの評価をもらうことができ、次のチャンスに繋がる
Javaの案件に携わっている間、コードレビューやユニットテストの導入などを自発的に行っていたと述べましたが、この点がチームリーダーから評価され、後ほどモダンなWeb企業の案件に参画することができました。
コードレビューやユニットテストは今日では当然のように行われていることですが、当時の私の案件では存在しませんでした。
にも関わらずそれについて対応しようとする姿勢が評価されたのだと思います。
結果としてモダンな企業の案件に参画することができ、一気に技術スタックを積み上げることができました。
特定の技術を使う社内アプリ開発に従事している場合、この話は一般化はできませんが、フリーランスや受託，派遣の場合はフルスタックであるこということの恩恵は受けやすいと思います。
未経験でも関連する技術であれば、少し学べば業務レベルのことができるようになりますし、企業よっては「これをやったことがあるのでこれもできますよね」みたいな感じで参画することもできるはずです。
常に業務にフルパワーで取り組む必要はないと思いますが、どのようにすれば他者から評価を得ることができるかを考え、そのような行動をとることは重要だと思います。

### 未経験の方や特定レイヤ専任の方でもポートフォリオ(自作アプリ)を作ることで、フルスタックになることは可能
私は業務として様々なレイヤについて対応を行い、結果としてフルスタックになりましたが、自主的にフルスタックになることも可能だと思います。
例えば一例としてアプリケーションを自分で作る、という方法です。
というのもSNS等で未経験の方が作られているポートフォリオ を見るとフロントはVue/Reactを使ったフロントエンドフレームワークを利用し、バックエンドはRailsを用いたREST API、そしてインフラはAWS/GCPを用いたクラウドネイティブなアプリケーションといった具合に高品質なものをいくつか拝見しました。
ポートフォリオ というとこれらを全て自分一人で作るということになり、必然的にフルスタックなことを行わざるをえません。
すると何かしらのポートフォリオ を作りたいために技術を学び実践していると、必然的にフルスタックになっていくのではないでしょうか。
もちろん自分一人で作ったものだとセキュリティや品質が担保されていないという問題が起こることはありますが、一人でそれぞれのレイヤについて実装することができるという自信にはつながるはずです（そして未経験からエンジニアへの転職を考えている方にとっては、転職の有力な材料にもなるはず）。
ただこれを実現しようと思うと、プライベートの結構な時間をプログラミング に使う必要があると思うので覚悟は必要かなと思います。業務レベルで使えるようになることを目指すと、半分の時間、20時間は毎週取り組んで高品質なものを作れるくらいになるのが望ましいのではないでしょうか。

以上、経歴の部分が冗長気味になっていましたが、参考になればと思い書かせていただきました。
この記事が読者の参考になれば幸いです。