初心者からの我流プログラミング学習8選

期せずしてITを生業とするようになってしまいました。
今でこそITプロダクトのPMをやっているけれども、当初は「未経験」ながらもあらゆることをキャッチアップせねばなりませんでした。

「文系/未経験」が技術を理解し身につけていくファーストステップは、開発案件にアサインされてフィードバックを得ていくパターンが王道かと思います。
自分の場合は、周囲に頼れる人/情報が多くなかったため試行錯誤の末プログラミングを身に着け、今に至ります。
本記事は、そんなかなり我流のプログラミング学習を振り返ることで、なんらかの参考になれば幸いです。

ちなみに、自分は仕事ではJavaを使い、プライベートではKotlin、JavaScriptを使うことが多いです。
以下、断りがなければJavaのことを暗に言っているんだと思ってください。

記事の最後に学習に使用した書籍やサイトのリファレンスをまとめたので、よろしければそちらもご覧ください。

# 学習履歴から
挙げたらきりがないくらい、なにかを作ったり教材、リファレンスにあたってきましたがその中でも特に学習効果が高かったと感じるものを8つ、挙げてみました。
1. 簡単なウェブアプリを決めて制作する
2. Google Tech Dev Guide
3. 壮大な「趣味の開発」と派生プロジェクト
4. 開発パートナーのソースコード読み漁る
5. 数学
6. C言語
7. プログラミング言語の標準APIを掘る
8. AWS環境の構築

なお、私もはじめはProgateなどとっかかりは別でこなしてはおりまして、そこからのステップアップの方法が主題となります。

## 1. 簡単なウェブアプリを決めて制作する
超最初期の学習法。
「プログラミングスクールやオンライン教材で文法は理解できたけど次どうしよう」のステップでは、自分で作りたいものを決めて開発するのがとてもいいと思います。
結構どんなのを作ってもいいんですが、1.のエッセンスは「成果物から逆算して必要な概念やロジックを理解する」ことです。

たとえば、LINE Bot開発は超初期の「初心者」レベルでなにかを作ってみたいときはめちゃくちゃおすすめしたいです。
これは単純に、「LINEから入力を受け取って処理をするスクリプトを作ってみる」。

- [Messaging API](https://developers.line.biz/ja/docs/messaging-api/)

おすすめ理由は大きく3つで、 

- インプットからアウトプットまでのロジックが簡単
- Rubyのようなスクリプト言語で作れてしまう
- 簡単なわりに結構いい感じのものができて、ちょっと達成感を得られる

特に3つめが大事なのかなと。結構簡単に作れる割には達成感を得やすい。
Google Apps Script（GASと呼ばれているやつ）とLINE Botの組み合わせなんかは、ちょっとできるようになってからでも十分楽しめますよね。
ネットで検索すればいろいろな実装例が出てきます。
スプレッドシートを簡易DBに見立てて、「LINEからの入力を受けてデータを返す」みたいな構成にすると、「UI - ロジック - DB」の基盤作りもでき、多くのことを学べます。

## 2. Google Tech Dev Guide
Google Tech Dev Guideは一時期やりこんでました。

- [Google Tech Dev Guide](https://techdevguide.withgoogle.com)

自分の理解では、Google Tech Dev GuideはGoogleがキュレーションしているテーマ別のプログラミング教材サイトです。
目的やレベル別になっていて、ビギナーでも取り組みやすいです。

この教材は、1をクリアしてから挑むと難易度がちょうどいいじゃないかな。
なるほどと思えるくらいしっかりした内容なのに、ビギナーでも一定頭を使えば取り組める教材が揃っている。
ひとしきりやったら、ちょっとしたアルゴリズムを自作できるくらいにはなりました。

「1. 簡単なウェブアプリを決めて制作する」は、「なにか出来上がる楽しみ」はある反面、何を作るかを頻繁に考えないといけないデメリットがあります。2.のようにコースが決まっていると端から進めていきやすいので学習に集中しやすい側面があると考えてます。

## 3. 壮大な「趣味の開発」と、派生プロジェクト
壮大な「趣味の開発」プロジェクト。
これはもう、本当に壮大で「普通にあったら使うなっていうのをSPAで作る」ってことをやってました。

足掛け1年弱、主に土日を使ってずっと作ってた...
フロントとバックエンドを、盛大に切り離して2つのプロジェクトを同時進行させてました。
フロント側のプロジェクトとバックエンド側のプロジェクトを平行して進めたため、体感では3倍くらいのコード量になってた気がします。
フロント〜ロジック〜DBまでを一貫して設計〜リリースしたいっていうのがこのときのモチベーションで、仕事ばりに設計書を書いて（笑）、実装してテストまで一貫してやりきった。

このプロジェクトもめちゃくちゃ得ることが多かったので、まじでやってよかった。
よかったポイントを挙げていくと、

- 結構本気で書いたので、コードベースがあとあと他のところでも使い回せるくらい洗練されてた
- e2eで確かに思い描いていたものを作り上げられた
- デプロイ基盤、サーバ/ネットワーク構成も自作して、文字通り「システムを立ち上げた」
- ここで書いたソースコードを一部抜き出してちょっとしたライブラリ化できた
- いい感じのものを作り上げた達成感
- 世の中のサービスの表と裏、上から下までの構造をなんとなく想像できるようになる

などなど。他にももう少しありそう。

このプロジェクトはまあ大量のコードを生み出したので、その一部を切り出して自分のよく使うライブラリとして現在もメンテしてます。
そのような派生して生み出されたソースも資産としてのこって行くので、思い出深いです。

## 4. 開発パートナーのソースコード読み漁る
私の会社では（厳密にいうと）エンジニアのロールが存在せず、ITの実働は常駐していただいているパートナーにお願いしてます。
そして、事業で動いているソースコードはすべて社内のバージョン管理システムに置かれて、いつでも誰でも読める状態になっています。
一時期、まあ飽きることなくいろいろなプロジェクトのソースを読むことで学びを得ており、ここに挙げてみました。

この学習方法は、少しコツのいる作業かもしれないです。
人のソースコードは、読んでるだけだと全然よくわからない。本当によくわからなかった...
他人の積み上げたソースを、腰を据えて読む段階では何個か気をつけるとよい点があるので、列挙してみます。

### 気をつけたこと1　「知らないクラスを徹底的に検索する」。
びっくりするぐらい聞いたこともないようなクラスが、標準ライブラリだったり依存ライブラリでたくさん出てくる。
上からソースコードを読んで、わからないクラスは「Java 〇〇」（〇〇はクラス名）でひたすら検索してました。
ここでは、公式ドキュメントにあたり続けるのがよいですね。
公式ドキュメントは省略こそ少ないし初見ではわかりづらいこともあるけれども、過不足ない知識を提供してくれます。今後、他のなにかを始めるときに「公式ドキュメント解読力」は自分の力になります。
本当、ずっとJavadoc読んでました...

### 気をつけたこと2　「呼び出し先のクラス/メソッド/プロパティを追いかけ続ける」
これもめちゃくちゃやった...人のソース読んでも、そもそもそのコードが書かれた文脈がわからない。
ソースの積み上げられた文脈はソースからだけではあまりわからず、
「お前（知らないクラス、メソッド、プロパティ）誰だよ...」
ってよくなってました。
当時、私は「ラップされすぎてて実体がわからねえ」苦しみに悶てました...
とりあえず呼び出し先のクラスを複数回、追いかけて具体的な実装が出てくるところまで遡るとよいと思います。
体感では、「よくわからない構造」は4〜5回くらい呼び出しや実装/拡張を経ている印象です。

でも2はいまだにベストプラクティスわからないです、今でも苦労してます。

### 気をつけたこと3　「すべてが"実装例"だと理解する」
プロジェクトによっては、イケてるロジック・構造とそうじゃないところの差がすごい大きいんですよね。

ビギナーのうちは、結局どういうロジック/構造がよいのか、判断つかなくてよく混乱してました。
似たようなことをやりたいのに、ある箇所と別の箇所ではまるでロジックが違うのはよくある。

個人的な印象では、よく知られたフレームワークやライブラリの実装でもない限り「超王道」を貫いているプロジェクトは少ないと思ってまして、その意味で「すべてのソースは実装例である」くらいに理解しておくことにしてます。
本番で動いてるソースの全部が全部、王道に沿って構成されてないという（笑）

そして、そりゃそうなんすよね。そんなに全部が全部超かっこよく構成してないし（いろいろな制約があって）できない。

## 5. 数学
他の学習方法と比べても、とりわけ価値の高い情報を摂取できたのが数学の勉強でした。
「ちょっとしたウェブアプリは、調べながらできるようになってきたな」くらいで着手して、学習効率がとても高かった方法です。
列挙した8つの学習方法の中でも、とりわけ学習効果が高かったです。

情報系を卒業された方であれば数学が大事なのは当たり前すぎて論を俟たないですが、そりゃそうやんって話で、そもそも（一般的な）コンピュータそのものが離散数学のアイデアをベースに設計されていますよね。
だから、コンピュータを使って仕事していく上で数学は欠かせないのかなと思っています。

やったこととしては、座学を中心に学部生向けの情報系の学生がやるようなテキストやウェブ上の資料を何冊かこなしました。
ここでもいろいろやりましたが、何個か例をあげると

- [離散数学 (コンピュータサイエンス教科書シリーズ)](https://www.amazon.co.jp/dp/4339027154/ref=cm_sw_em_r_mt_dp_U_.CG6Eb6G4K329)
- [計算モデル論入門―チューリング機械からラムダ計算へ](https://www.amazon.co.jp/dp/4781911358/ref=cm_sw_em_r_mt_dp_U_2DG6EbXH1QCDW)
- [離散数学](https://www.hongo.wide.ad.jp/~jo2lxq/dm/)

カリキュラム、というかどの領域を学ぶか？は応用情報技術者試験の出題範囲などを参考に選定。

このときは家に帰ってから毎日何時間か、数カ月間帰ってテキスト開いて数学の問題を解く生活をやっておりました（笑）
学生時代にも線形代数や簡単な微分積分は使っていたので数学自体は苦手をあまり感じず、それはめっちゃラッキーでした。
必要性を感じて勉強をしたけど、座学そのものが純粋に面白かった。
今まで触れてこなかった領域だったので、離散数学は独特の匂いを感じられて大変興味深かったです。

私はなにを扱うにも原理が気になる性でして、プログラミングでも「それはなぜ？」を追いかけ続けたくなってしまう。
数学はプログラミングにおいて「なぜそうなのか？」を自己解決していくための超重要ツールであることを（ようやく）ここで知り、テキストをこなしてるときは毎日、興奮しっぱなしでした。
数学で扱う構造をクラスで表現しようとするとこういう構成になるんだ、ってのを一つひとつ原理的な部分から理解できた。

いっぽうで、「学校のお勉強」感満載でして、腰を据えてやらないと途中で楽しくなくなる可能性が高いかもしれません...
万人にはおすすめできないです。

## 6. C言語
王道中の王道なので、「C言語超いいですよ！」って大声で列挙するのはおかしな話なんですけど...
よく言われるようにC言語は他の多くの言語に影響を与えてきてますし、一回くらいはやってもいいかなって。

何かを作り、動くのを目的にプログラミングする場合は、他の言語やツールを使うほうが楽なケースが多いと思ってまして、だからC言語の学習は「ちゃんと定義して、ちゃんと動作させる」ことそのものを目的に学習しました。
C言語は、5の数学と前後して一緒に勉強していて「原理を知る」ことをそのものが狙いでした。
そのため、学習サイトのサンプルを見ながら軽めに書いてコンパイルして動かす程度の深さでしか触れてないです。

- [C言語](http://www.c-lang.org/)
- [一週間で身につくC言語の基本](http://c-lang.sevendays-study.com/)

あんまり深追いはできてないものの、アルゴリズム・データ構造の実装もC言語と平行してやるようにはしてました。

よく「つまづきやすい」と言われているポインタ周りは、ご多分に漏れ、ず私も「これは深いゾ？！」と途中で気づきました。
ポインタ周りだけは別途書籍で学習、オライリーのがよかったです。

- [詳説 Cポインタ (日本語)](https://www.amazon.co.jp/dp/4873116562/ref=cm_sw_em_r_mt_dp_U_JYG6EbE3FQXP4)

この本はいまだにちょくちょく参照してます。人間から見える「オモテ面」と、物理的な動作の「ウラ面」をほどよく抽象化して説明してくれている点で大変参考になりました。
メモリ管理のくだりは特にお気に入りです。

## 7. プログラミング言語の標準APIを掘る
なんらかプログラミング言語の標準APIは、都度参照していくとよいと思います。
自分の場合は、仕事ではJavaを使い、プライベートではKotlinを触ることが多いのでJDKのソースはちょくちょく読んでます。

- [OpenJDK](https://github.com/openjdk)

慣れちゃえば「標準APIとか、ライブラリのソース読むなんて当たり前じゃね」と思うようになるのかもしれないんですが、個人的な感想として「本家にあたる」のはハードルの高い作業だと感じます。

「本家のやっていることを直に見られる」意味でこれをやるといいと思ってます。逆にいえばこれ以外で得られることはは小さいかも。
なにか標準APIのクラスやメソッドを使うときに、より納得して使えるようになるし誤った用法を避けられるのも、副作用にはあるかもしれないですが。
用法はドキュメントを読めば解消できますし。

ちなみに、7.は「4. 開発パートナーのソースコード読み漁る」に近いです。
興味のある、ないしはもっと理解を深めたいクラスやメソッドを探し出してきて「これは何してるんだ？」と掘っていくだけ。
「4. 開発パートナーのソースコード読み漁る」との違いは、標準APIのほうが抽象的だったりクラス構成が重厚だったりして追いかけづらい点などでしょうか。

## 8. AWS環境の構築
アプリだけでなく「アプリ基盤も自分でこさえてみようぜ」って項目です。
AWSでなくAzureでもGCPでも、好きなIaaSを選んだらいいです。なんならIaaSじゃなくてもいいですし、「ネットワークとサーバ」を簡単に立ち上げられる環境を用意できればいいです。

昔、インフラチームとアプリチームを兼務していた時期あり、サーバを組み立ててミドル入れて、みたいな仕事をしていたので業務の補完として取り組んでました。
「3. 壮大な「趣味の開発」と、派生プロジェクト」で作った、壮大な趣味アプリをデプロイする基盤も自分で作り、運営できるところまでは構築しました。
ネットワークを構成して、その中にサーバを置いてミドル入れてアプリを配備してって。

（自分が言うことでもないけれども）AWSは、ドキュメントやチュートリアルがまー充実してるのでドキュメントを読んで組み立てるんでも十分いろいろできるかと思います。

- [アマゾン ウェブ サービス (AWS) の実践的チュートリアル](https://aws.amazon.com/jp/getting-started/hands-on/)

自分は、仕事でAWSに入ったのでチュートリアルを知らず、自分のアカウント開設してから「こんなパワフルなチュートリアルあったんか...」と驚きました。
これほんとうにすごいですよね...読んでると動かしたくなってきてしまう。
チュートリアルに出てくるテーマのうち何個かをやってみて、説明ややりたいことがわかりやすく、簡単にできて普通に楽しかったです（笑）

アプリ開発の観点では、VPCやサブネットをチュートリアルなどを見ながら自前で用意して、そのネットワーク内にサーバを立てて稼働基盤を組み立てる一連の流れを踏んでみるのが一番オススメです。

いまでもPMしながらアーキテクチャのディスカッションに入ってて、わからないところは自分のアカウントでちょっとしたデモを立ち上げて勉強するのにとても役立ってます。

# 最後に
学習方法はもちろん大事でいろいろ試行錯誤すべきと思っている反面、「好奇心」がない限りはなかなか体になじんでいかないですよね。
これを書きながらも、Howと同じかそれ以上にWhyを考えてこんでしまうか？ってのは大きな論点なんじゃないかと。
周囲の人を見ていても、普段からなんらかプログラムを作ったり勉強している人は義務感とか必要性以上に好奇心がそうさせているように感じられてならないです。
そして、私は業務でたまたま触る機会と必要性があったから触れることができたけども、ここまでのめり込めるとは思いもよらなかった。

どんなものでもよいので、興味を持てる技術を深堀りするところから始めてみてるのもよいのかもしれません。

# 参考
本文に出てきたもの、出てきてないが参考になったものです。

1.簡単なウェブアプリを決めて制作する

- [Messaging API](https://developers.line.biz/ja/docs/messaging-api/)
- [Google Apps Script](https://developers.google.com/apps-script?hl=ja)

2.Google Tech Dev Guide

- [Google Tech Dev Guide](https://techdevguide.withgoogle.com)
- [LeetCode](http://leetcode.com/)

3.壮大な「趣味の開発」と派生プロジェクト

- [リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice) (日本語)](https://www.amazon.co.jp/dp/4873115655/ref=cm_sw_em_r_mt_dp_U_IPB7EbY5GSRE0)
- [Web API: The Good Parts (日本語)](https://www.amazon.co.jp/dp/4873116864/ref=cm_sw_em_r_mt_dp_U_yWB7EbG8B69CS)

5.数学

- [離散数学 (コンピュータサイエンス教科書シリーズ)](https://www.amazon.co.jp/dp/4339027154/ref=cm_sw_em_r_mt_dp_U_.CG6Eb6G4K329)
- [計算モデル論入門―チューリング機械からラムダ計算へ](https://www.amazon.co.jp/dp/4781911358/ref=cm_sw_em_r_mt_dp_U_2DG6EbXH1QCDW)
- [離散数学](https://www.hongo.wide.ad.jp/~jo2lxq/dm/)
- [計算機システム概論―基礎から学ぶコンピュータの原理とOSの構造](https://www.amazon.co.jp/dp/4781912508/ref=cm_sw_em_r_mt_dp_U_QOB7Eb8TDTKM1)
- [プログラマの数学 第2版](https://www.amazon.co.jp/dp/4797395451/ref=cm_sw_em_r_mt_dp_U_BNB7Eb93NHXZK)

6.C言語

- [C言語](http://www.c-lang.org/)
- [一週間で身につくC言語の基本](http://c-lang.sevendays-study.com/)
- [詳説 Cポインタ (日本語)](https://www.amazon.co.jp/dp/4873116562/ref=cm_sw_em_r_mt_dp_U_JYG6EbE3FQXP4)
- [アルゴリズムイントロダクション 第3版 第1巻: 基礎・ソート・データ構造・数学 (世界標準MIT教科書)](https://www.amazon.co.jp/dp/4764904063/ref=cm_sw_em_r_mt_dp_U_t0B7EbS21MMRB)

7.プログラミング言語の標準APIを掘る

- [OpenJDK](https://github.com/openjdk)
- [JetBrains/kotlin](https://github.com/JetBrains/kotlin)

8.AWS環境の構築
 
- [アマゾン ウェブ サービス (AWS) の実践的チュートリアル](https://aws.amazon.com/jp/getting-started/hands-on/)