目次
- ご挨拶
- テーマ
- 注意点
- 前提条件
- 本読むだけじゃダメ
- 自学の意味
- 直近で必要ないもの
- 知識体系
- 各領域
- システム開発全工程
- まとめ
ご挨拶
この記事をご覧になってくださった皆様、ありがとうございます。
石川 聖(ヒジリ)と申します。
先週に続いて、駆け出しエンジニア向けにエンジニアに必要とされる知識体系と学習方法を開設していきます。
(また、1つ目の投稿「自己紹介&ポートフォリオ作成」も宜しければご覧になってください。
https://qiita.com/ishikawahijiri/items/233f353b274a8a514350
)
テーマ
この投稿では、
- インターンでエンジニアとして働きたい学生
- エンジニアとして就職・転職したい
- ポテンシャル採用でエンジニアになったがスキルアップの方法が分からない
といった方に向けての学習ロードマップを解説します。
僕自身は25/4からSIerに勤務する駆け出しエンジニアですが、一応、
- 大学で情報工学専攻
- インターン, ハッカソン, 企業実習などでのシステム開発
- 個人でweb系開発
などの経験があり、10段階で言えば3程度のスキルはあります。(主観)
そのため、上記の方々に向けた適切なアドバイス、道筋の提示はできると思います。
注意点
前提条件
このロードマップは既に基本的なプログラミングはできる人を対象としています。
完全にプログラミング未経験の人は、学びたい言語の入門本を一通りやるか、progateなどのオンラインサービスを利用して学んでください。(案件数の多い言語をやれば良いと思います。ex. java, java script, python)
そこから、
- インターンで働きたい
- エンジニアとして就職・転職をしたい
- 効率的にスキルアップしていきたい
といった方々が欲しい情報をまとめました。
また、既にエンジニアになった方向けに、その先のスキル習得の道筋も解説します。
(また、僕がweb系フルスタックを目指しているので、それを加味したロードマップになっていますが、どの領域の方でも参考になると思います。)
本読むだけじゃダメ
エンジニアにとって、最も重要なのは実務経験です。
就職や転職の際には、実務経験こそがスキルや実績を証明する最も確実な手段となり、
駆け出しのエンジニアにとっては、実際の現場に入り、経験豊富なエンジニアから直接学ぶことが最も効率的に成長できる方法です。
そのため、できるだけ早く実務経験を積むことが重要です。
もちろん、右も左もわからない初心者にとっては、
- 技術書の内容をなぞって実装すること
- 資格を取得すること
等の明確なゴールがあるものは、効率よくスキルを身につけるための有効な手段となります。また、発展的な内容を学ぶ際も書籍を読むことが有効です。
しかし、いくら本を読んだり資格を取ったりしても、それが実務で通用することを他人に証明するのは難しいという現実があります。
その手段として、自らのスキルを示すアウトプット、つまりポートフォリオを作ることが必要になります。これは、特に学生や他業種からの未経験転職者にとっては必須のステップです。
まずは、知識やポートフォリオのクオリティを最低限のレベルまで引き上げその状態で面接を受けます。運よく通過できればラッキーですが、もし不合格だった場合は、知識とポートフォリオの質を少し向上させ、再び面接に挑む。この繰り返しが、エンジニアとしてのキャリアを始める最高効率の方法です。
そのため、学習はアウトプットを重視し、必要な部分だけを学ぶのがベストです(完璧主義にならない)。駆け出しの頃は、長期休暇などのタイミングで腰を据えて基礎固めをするくらいで十分でしょう。
(また、技術的なスキル(ハードスキル)と同じくらい、コミュニケーション能力やチームでの立ち回り(ソフトスキル)も重要です。現場では、先輩エンジニアに可愛がられることが成長への近道になります。)
自学の意味
実務経験が重要であることはご理解頂けたと思いますが、現場に入るためには最低限の知識やスキルが必要です。
多くの企業の入社試験では、コーディング試験としてデータ処理のアルゴリズムの問題が出題されたり、技術面接で「ブラウザにurlを打ち込んでからコンテンツが表示されるまでの流れを説明しろ」といった基礎知識を問われることがあります。これらの対策は、ある程度はしておく必要があります。
また、新卒のポテンシャル採用で入社できたとしても、「パソコンの電源の付け方は?」といったレベルの知識しかないとさすがに周囲に呆れられてしまいます。そのため、最低限の基礎知識は自分で身につけたうえで、実務に即したより発展的な内容や経験則を先輩から学ぶという形が最も効率的な成長方法となります。
これは、進学校の生徒が予習をしているからこそ、より高度な授業が展開でき、結果として学力が伸びるのと同じ原理です。
事前に自分で基礎を固めておくことで、現場に入った際に吸収できる知識の質と量が大きく向上します。
直近で必要ないもの
開発エンジニアを目指す場合、インフラ関連の知識は直近ではあまり必要になりません。
具体的には、物理インフラやクラウドなどの実行環境については基本的に専門のエンジニアが担当するため、新人が触れる機会はほとんどないのが現実です。
そのため、無理にインフラの深い知識を学ぶよりも、まずは開発に必要なツールや環境に慣れることを優先すべきです。具体的には、CLI(コマンドラインインターフェース)の基本操作、IDEの使い方、コンテナ技術(Dockerなど)、そしてGitのバージョン管理に慣れることが重要です。
これらのスキルは実際の開発現場で即戦力となるため、まずはここに注力すると良いでしょう。
知識体系
システム開発の工程を以下に示します。
- 要件定義
- 基本設計
- 詳細設計
- 実装
- テスト
- デプロイ
- 保守運用
次の章で、優先度順に、具体的に求められる知識を解説していきます。
各領域
(Amazonのアソシエイトとして適格販売により収入を得ています。)
プログラミング(パラダイム, コード設計, コーディングルール, etc)
(ここから先は、基礎的なプログラミングと簡単なポートフォリオ作成が完了した人、既にエンジニア職に就いた人が対象です。)
「三日後の自分は他人」という言葉があります。数日空くだけで過去の自分のコードが一体、どんな処理をしているのかがわからなくなるということの比喩です。他人が書いたものなら尚更です。そのため、自分にとっても、それを将来的に保守することになる他人のためにも、万人にとって読みやすく理解しやすいコーディングを心がける必要があります。
初心者向けに分かりやすいものだと、こちらになります。
有名どころではこちらですね。前述のものよりやや難しいですが、既にある程度プログラミングができるならこちらがおすすめです。
プログラミング言語には様々なパラダイム(考え方, 価値観, 規範)があります。それらを理解することで、より高い可読性, 保守性, パフォーマンスを持ったコードを実装できます。
現在、メジャーなパラダイムはオブジェクト指向言語(object-oriented programming language, OOP)ですので、それだけを簡単に学んでおくと良いです。
ここで圧倒的におすすめの書籍があります。実務に入る前に全員読んだほうが良いと断言できるレベルのものです。命名規則やネストを浅くするといった基本的な手法に加え、オブジェクト指向向けの優れた設計原則や、テスト・リファクタリング手法、後述するドメイン駆動設計の知識までを網羅的に扱っています。
それを、悪いコードの例から段々と良いコードへと改善していく(リファクタリング)過程を平易な文章で説明することで、大変理解しやすい形にまとめた良書の中の良書と呼べる本です。是非とも読んでいただきたいです。
(この本の18章 「さらにステップアップするための設計技術書紹介」がありますが、そこで紹介されているものは
- リーダブルコード(Dustion Boswell)
- リファクタリング(Martin Fowler)
- Clean Code(Robert C.Martin)
- エリック・エヴァンスのドメイン駆動設計(Eric Evans)
- テスト駆動開発(Kent Beck)
- etc
など名だたる名著が並んでいます。これらの様々な優れた開発手法の知識を凝縮した本書を、是非、手に取ってみて下さい。
もし私が他の人よりも遠くを見渡せたのだとすれば、それは巨人の肩の上に立っていたからだ - アイザック・ニュートン -
巨人の肩とは、知識が少しずつ積み重ねられていく様子を表す比喩です。彼は、人々が過去の知識を活かしてさらに新しい知識を得ることを「巨人の肩の上に立つ」ことで、より遠くを見ることができると表現しました。書籍で言えば、その質は引用で決まるといっても過言ではなありません。)
オブジェクト指向自体はプログラミングだけでなく、上流工程にも適応できる概念であり、
カプセル化, ポリモーフィズム, 継承といったOOPの基本概念がコード付きで分かりやすく解説されています。
また、機械語, アセンブリ, 手続型からOOPが誕生するまでの経緯や次世代パラダイム 関数型との違い、オブジェクト指向の考えを上流工程へと適応した業務モデリング・UML・アジャイルなどの解説まで含む、オブジェクト指向の全体観を掴むのに最適の1冊になっています。
オブジェクト指向はクラスという、データ(属性)と動作(メソッド)をまとめたものを実装します。(普段何気なく使っている、string.split()や.replace()がまさしくそれです。)
そのクラスにも、優れた設計手法、逆にバッドパターンが存在し、それを専門に扱った書籍があります。より高い保守性、再利用性を求める人、後述のクリーンアーキテクチャやドメイン駆動設計を学びたい人は前提知識として必要ですので、時間があれば勉強しましょう。(ここまでの知識を持った中級者以上向け)
こちらは、オブジェクト指向において古典的な23個のデザインパターンを、Java言語で書かれた短いサンプルプログラムで、初心者向けにわかりやすく解説した技術書です。
また、これもオブジェクト指向の設計で有名なリファレンス的書籍です。
また、こちらはデザインパターンで有名な入門書です。
(また、こちらはオブジェクト指向でUIを実装するという書籍です。今度、買って読もうと思っています。
(また、オブジェクト指向に次ぐパラダイムとして関数型プログラミング言語があります。関数を第一級の要素として扱い、副作用を最小限に抑えた純粋な関数(純粋関数)の組み合わせでプログラムを構築するというパラダイムのことです。(関数自体を変数に代入・引数として渡し、戻り値として返すことが可能。pythonなどで似たようなことができますね
配列から偶数を取り出す操作 filter( lambda x: x % 2 == 0, list))
気になった方は一緒に勉強しましょう。
(また、こちらのデータ指向プログラミングも気になっており読む予定です。
テスト
プログラマーは実装したプログラムに対して対価を得ます。バグのあるプログラムを納品することは、不良品を売りつけるようなものです。
また、将来の変更に備えて、リファクタリングを行い品質を高める努力が必要であり、それらにテストの知識は必須となります。
適切にテストを行うことで、バグの早期発見, 品質の向上, 開発効率の向上が望めます。
初心者におすすめの書籍を2つ挙げます。どちらか1つを見れば大丈夫です。
扱っている内容はほぼ同じで、
- ホワイトボックス/ブラックボックステスト
- 境界値/同値分割テスト
- ディシジョンテーブル
- 状態遷移テスト
- 組み合わせテスト
これらを知っていれば当面、問題ないです。
さらに発展的な内容としてテスト駆動開発があります。これは、
- まずテストを書く(実装前に仕様を明確化)
- テストを通すために最小限のコードを書く(余計な実装を避ける)
- コードをリファクタリングする(設計を改善しながら保守性を向上)
というサイクルを繰り返す開発手法です。メリットとして、
- 設計が明確になる(テストを書くことで必要な機能・仕様を整理できる)
- バグを早期に防げる(実装前にテストするため不具合の混入が減る)
- リファクタリングしやすい(コードの仕様が明確なので安心してコード改善ができる)
- 開発の効率化(後からバグ修正や仕様変更に強いコードを書ける)
があります。すぐに必要になる知識ではありませんが、より良いコード品質を目指すには良い学びがあると思います。おすすめの書籍は、テスト駆動開発の考案者自身が書かれたこちらです。
リファクタリング
ここまででも少し取り上げましたが、リファクタリングとは、外部から見た動作を変えずに、コードの内部構造を改善することです。これにより、可読性・保守性・拡張性を向上させ、技術的負債を減らすことができます。先述の「良いコード/悪いコードで学ぶ設計入門」で紹介されたものにはこれらがあります。
リファクタリングの代表的な解説書、ガイドブックです。こちらは第2版でjava scriptで書かれています(第1版はjavaです)。
こちらもリファクタリングがテーマの書籍です。テストコードがなく、仕様が不明なレガシーコードをどのように分析し、改善していくかに焦点を当てた実践的なものになっています。
また、この書籍では、上記の書籍で言及されていない粗悪なコードパターンがカタログ化されています。
ここまでの知識でミクロな設計技法(コード設計、クラス・関数設計レベル)を取得できると思います。続いてマクロな設計技法(アーキテクチャレベル)を見ていきましょう。
上流工程
(ここから先は、既にエンジニアやIT関連職種に就くことが決まった人向けです。)
ここから上流工程に入っていきます。一通り実装ができるようになったプログラマ志望の方や、コンサルや技術営業の方が学ぶと良い内容になります。(プログラマーであれば後述の詳細設計から見ても良いと思います。)
上流工程は、大まかに分類すると、
- 要件定義
- 基本設計
- 詳細設計(一応、上流に含めます)
となります。それぞれについて、必要になる具体的な知識に分解して解説します。
ドキュメンテーション
いきなりドミュメンテーション??何で??と思われるかもしれませんが、実際の業務を見ると、
- 要件定義
- 顧客のヒアリング
- 議事録の作成→ドキュメンテーション
- 要件定義書の作成→ドキュメンテーション
- 契約書の作成→ドキュメンテーション
- 顧客のヒアリング
- 設計
- 各種設計書の作成→ドキュメンテーション
となっており、すべての工程で資料作成のスキルが必要になります。
開発エンジニアについても、上流工程で作成された資料をもとに実装してきます。書類の作り方を知ることでこれらの理解が容易になり、上流工程に進みやすくなります。
大学生で受託開発をしていた優秀な友人からのおすすめの書籍がこちらです。これ1冊で初心者~上級者までカバーでき、運用手順書などのエンジニア向けドキュメントだけでなくあらゆる資料作成に役立ったそうです。僕も読もうと思います。
要件定義
要件定義ですが、分解すると
- 業務の分析
- モデリング, 図表に起こす
- システム化する範囲を決める
に分かれると思います。
初心者向けの書籍ですが、これ以上の入門書はないと思います。
これらで、
- 要件定義の目的
- 作成すべき成果物
- 業務分析
- モデリング
などをざっくりと理解できます。
2については、UMLやER図を活用してドメインモデリングを行うことです。僕もまだ理解が甘いため勉強していきます。
ER図に関しては、先ほどの「始めよう!シリーズ」の著者のものがあります。後半には、架空の帳票からモデリングを行う実習があり、理論から実践へとステップを進めることができます。
UMLは以下の書籍を購入して学びました。
UML入門書としては、こちらが最も分かりやすいと思います。具体例の記載も多く、リファレンスとしても使えます。
また、こちらも入門書として分かりやすいです。
この書籍では、RDRA2.0(ラドラ)という要件のモデル表現と、モデル間・モデル要素間のつながりを表現する手法の解説をしています。
これで実習を行いました。
マーチン・ファウラー著のものです。こちらもリファレンス的に使えます。
これらの工程によって、システムが持つべき機能を漏れなく把握し、UML等を活用して要件を具体化することを目指します。
(また、こちらは、最小限のUMLのコアサブセットと、ユースケースからオブジェクト指向ソフトウェア設計を導出するための思考プロセス(両者はまとめてICONIXと呼ばれています)を学べる書籍です。
ある架空のプロジェクトで、上流の分析ではロバネスト図を活用した「ロバネスト分析」、下流ではSpringFramework(java)を用いた開発を行なっていく実践的な内容になっています。
https://amzn.to/4jkrsoe
)
アーキテクチャ概要
(ここで基本設計, 詳細設計をまとめて簡単に説明します。)
システム開発において「設計」は非常に重要なフェーズです。特に駆け出しエンジニアにとっては、設計フェーズでどんなことを考えればいいのか、どういう順番で設計を進めていけばいいのか、イメージが湧きづらいことも多いと思います。
この記事では、そんな方に向けて、システム設計全体の流れを「アーキテクチャ」という視点から俯瞰しつつ、「これは基本設計に該当するな」「これは詳細設計に該当するな」といった位置づけも整理して解説していきます。
複雑な専門領域(例:クラウドやDBチューニングなど)には深入りせず、一般的なWebアプリケーションを前提にした設計の全体像を掴める内容にしています。
アーキテクチャとは、ざっくり言えば「要件を満たすためのシステム構成を考えること」です。
そして、それを設計する役割の人を「アーキテクト」と呼びます。大規模なプロジェクトであれば専任のアーキテクトがいることもありますが、小規模なプロジェクトではエンジニア自身がアーキテクチャの設計を担当する場面も少なくありません。
「設計」という言葉は非常に広い意味を持っていますが、その中でもアーキテクチャは特に抽象度の高い設計を指します。
たとえば、以下のような設計層があるとしましょう:
-
アーキテクチャスタイル(設計原則・設計テンプレート)
例:レイヤードアーキテクチャ、クリーンアーキテクチャ、ヘキサゴナルなど
→ システム全体の設計方針を示すもので、設計の思想に近い
→ 基本設計に含まれる
-
アーキテクチャパターン・システム構成
例:モノリス、マイクロサービス、サーバーレスなど
→ システムの物理的な構成(どのように分割・配置するか)
→ 基本設計に含まれる
-
モジュール・コンポーネント設計
→ どんな責務を持つ部品をどのように分けて開発するか
→ 詳細設計に含まれる
-
クラス設計・関数設計
→ コードレベルでの設計
→ 詳細設計に含まれる
つまり、「アーキテクチャ」と一口に言っても、抽象度の違う複数の層から構成されており、それぞれ基本設計〜詳細設計の中に位置づけられています。
設計の各層で大切になるのが「責務の分離」と「疎結合・高凝集」です。この観点をもとに、以降のセクションでは、各フェーズでどのようなアーキテクチャ的思考が求められるのかを見ていきます。
こちらの有名な入門書で、アーキテクチャの全体像が把握できます。
また、こちらでアーキテクトと呼ばれる人たちの業務内容を知ることができます。現代ビジネスを支えるITアーキテクトの役割や必要とされる能力を学ぶことができます。
また、システムの設計方法にドメイン駆動設計(Domain Driven Desgn, DDD)というものがあります。これは、簡単にいうと、「オブジェクト指向の延長で、ビジネスの本質(ドメイン)を深く理解し、それをシステム設計に反映するためのアプローチ」のことです(これを読んでピンときていないならまだ読まなくても良いです)。
余裕があれば、こちらの入門本で全体をざっと理解しておきましょう。タイトル通り、実際のコードの実装例からボトムアップでドメイン駆動設計のイメージを掴むことができます。オブジェクト指向プログラミングの経験があれば理解できるとも思います。
DDDの原典はこちらです。上記のものが面白かった方はぜひ読んでみてください。
ただし、前提知識として、一通りのシステム開発経験、オブジェクト指向・クラス設計の知識、要件定義・UML、後述のアーキテクチャなどの知識が必要であり、かつ、かなり抽象的な内容になっています。
こちらは、javaを使ってDDDの実装をするという内容です。
基本設計(外部設計)
ここでは、システム全体の大まかな構成を決めていきます。このフェーズでは以下のようなことを決めることが中心になります
- システムの構成方針(例:モノリス or マイクロサービス)
- アーキテクチャスタイルの選定(例:レイヤード、クリーンアーキテクチャなど)
- 技術スタックやミドルウェアの選定
- 非機能要件(可用性、拡張性、セキュリティなど)の洗い出しと対応方針
- 外部システムやユーザーとのインターフェイス設計
- 画面・API・データ(DB)設計の大枠
ここでは、設計の思想(スタイル)と構成(パターン)を組み合わせて、要件を実現するシステム像を作ることが目的になります。
この入門書も先ほどと同じシリーズから出ているのでおすすめです。これで設計フェーズの業務内容、成果物などを理解できます。
先ほどの「ソフトウェアアーキテクチャの基礎」の続編にあたる書籍です。ロールプレイ形式で架空のシステムの設計を進めていくという内容です。タイトル通り、マイクロサービスの設計に関する内容です。
余談ですが、web APIの入門書はこちらが最適だと思います。オライリーにしてはとても読みやすい内容になっています。
ここでいうデータ設計は、テーブル単位の設計です(データの保存先, テーブル間のリレーション, 正規化の判断など)。これまでに紹介したものやデータモデリングに関する書籍を読んでください。
また、非機能要件として、セキュリティ要件, パフォーマンス要件, 運用・保守設計などがあります。これまでに説明した知識を網羅的に持っていないと難しいです。頑張りましょう。
詳細設計(内部設計)
上流工程はこれで最後になります。
詳細設計(内部設計)では、基本設計で決めたアーキテクチャや構成をもとに、より具体的に実装に落とし込める設計を行っていきます。
「コードが書けるくらい具体的になっているか?」がこのフェーズの目安です。
具体的には、
- モジュール・コンポーネント設計
- データベース詳細設計(テーブル詳細設計, SQLの設計)
- API/インターフェイスの詳細設計
- クラス・関数の詳細設計
- (webの場合)フロントエンド詳細設計
- テスト詳細設計
- パフォーマンス・運用設計
などがあります。この中で2つに絞って解説します。
- モジュール・コンポーネント設計
この工程では、システムを意味のある責務単位に分割し、それぞれの役割・責任範囲・依存関係を明確にしていきます。
目的としては、
- システム全体の見通しやすさ・再利用性・保守性を高める
- 責務の分離(Separation of Concerns)
- 疎結合・高凝集の実現
があります。
具体的には、
「認証モジュール、ユーザー管理モジュール、商品管理モジュールなどの各コンポーネント」が、「それぞれどんな責務を持ち、どの層に属するか?」(例:ドメイン層の中のユースケースサービス、インフラ層のリポジトリなど)などを設計していきます。
おすすめの書籍としては、こちらが有名です。技術的負債を回避するための設計原則や手法がまとめられています。先述のDDDと一緒に学ぶと良いです。
こちらは、上記の「クリーンアーキテクチャ」の概念に沿って、実際のwebアプリを実装しコードに落とし込む方法を学ぶことができます。
- クラス・関数の詳細設計
ここでは、各モジュール・コンポーネントを実際のクラス・関数でどう表現するかを設計します。具体的には、
- オブジェクト指向設計における責務分割の明確化
- 適切なクラス図・シーケンス図による構造の可視化
- 実装の一貫性・テスタビリティの確保
を決めていきます。
この部分は、書籍を読みながら実際に書いてみて試行錯誤するのが一番です。命名規則やデザインパターン、コーディングルール、SOLID原則や設計パターン(Factory, Strategy, etc)もこの段階で活きてきます。
ここでは、プログラムの具体的な設計を行います。(オブジェクト指向を用いる場合は、)「どのクラスがどの責務を持つか?」「メソッドは何を受け取って何を返すか?」といったことを定め適切な設計をします。これまで紹介した書籍でおおよそ学べます。
他は要件定義・基本設計で行ったことの具体度を増していく作業です。勉強が必要になった際に先輩から良い書籍を教えてもらってくださいw
お疲れ様です。以上がエンジニアの知識体系でした。
解説しておいてなんですが、僕もこれら全てを完全に理解したわけではありませんw
20代の下積み的な時代の過ごし方を整理したかったこと、悩める同世代たちに道筋を示したい気持ちから執筆いたしました。
下積みを脱したつよつよな先輩からのダメ出しをお待ちしております。
まとめ
ここまでご覧になってくださった皆様、誠にありがとうございます。
このアカウントは週1回の投稿を目指しております。
また、月に1冊は技術書を読破し、その紹介記事を書くことで学びを皆様に共有することも目標としています。
次の投稿は「新卒エンジニアが読むべき本1選!?(この記事で超絶おすすめした本の紹介記事)」か、「オブジェクト指向って何だよ?」(オブジェクト指向の概要, 上流工程を学ぶまでの準備)を予定しております。
それでは皆様、また来週。