初心者エンジニアインターンのための学習速度を引き上げる11個のTips

# 自己紹介
2年前にインターンとして入社した会社で、0からプログラミングを始めた文系大学生です。
当初はhtmlとcssしか書けませんでしたが、
今はPHPエンジニアとして業務系システムの追加開発をやったり、
要件定義・仕様作成・設計などの実装以外の仕事もやったりしています。
個人で受託開発を請け負ったり、Unityでゲームを作ったりもしています。

# 期待する読者
これからエンジニアになるためにインターンを始める、もしくは始めている人たち

# なぜこの記事を書いたのか
僕は元々ものづくりに関心が強く、小学校のころから大学へ足を運び自立駆動型のロボットを作ったり、
ツールを使って携帯ゲームのソフトに改修を加えて遊んだりしていました。
あいにく自分のパソコンは持っていませんでしたが、将来なりたい職業はエンジニアと卒業文集に書いていました。

しかし、プログラミングの勉強について過去3度挑戦し、**2度挫折した経験**があります。
1度目は高校生のとき、どうやって勉強すればいいのかよくわからず、つまらなくなってやめたということ。
2度目は大学に入学した後の最初のインターン先での経験。難易度が高すぎてついていけず、しんどくなってやめたという理由です。
そして、3度目にしてようやく、プログラミングに対して楽しさを覚え、仕事としてできるようになっています。

3度目にしてプログラミングをできた理由は、

* 丁寧に教えてくれるメンターがいたこと
* 自分より頭のいい人の勉強法を参考にして実践し、学習速度の向上が実感できたこと

です。

さらに最近初心者の方向けに勉強会を開く機会が増えてきたので、
技術に関心があり、2度挫折したにも関わらずどうやってできるようになったのか
という観点で過去を振り返り、やってよかったなと思うことをTipsとしてまとめてみました。

あまり網羅的ではないかもしれませんが、この記事が少しでも多くの方の参考になれば幸いです。

# 学習速度を引き上げるためのTips
## 今自分にメンターがいるのか
冒頭でも書いた通り、学習においてメンターはものすごく重要です。
中には独学で成り上がった人もいますが、**独学に拘るのは時間がもったいない**です。
特に初心者はトラブルシューティングでハマりやすく、
脱却するには**語彙や知識がなさすぎる**ため、それを補う役割としてメンターは重要です。

また、メンターには直近の仕事の話ではなく、**今後のキャリアなどの長期的な目標や悩みについても話してみる**と良いです。
自身への足りない要素が何であるのかをフィードバックしてもらえるきっかけになるだけでなく、
悩みをオープンにすることで、教える側からすると信頼してもらえた感覚があり、
よりサポートしてあげようという心理が働くために、**以前よりも良好な関係を築ける**ことがあります。
自分の悩みを吐露するのは少し気が引けるかもしれませんが、思い切って相談してみると良いと思います。

## 1つの言語の習得に絞ること
かつてプログラミングの勉強をやり始めたときに、今の僕の先生に「どの言語から勉強すればいいんですか？」と聞いたことがあります。
その時は、「言語はなんでもいいよ。」と言われましたが、本当にそのとおりだと思っています。
特に**複数の言語を平行して触り始めるのはかえって効率が悪い**です。

例えば、「自転車に乗って家から3km離れたデパートへ一人で買い物できるようにする」という目的がある場合に、
ママチャリとロードバイクを買って、両方乗れるようにするような感じです。
自転車としてのパフォーマンスの得意不得意や利用用途は違いますが、**どちらでも目的達成は可能**です。

プログラミング言語も同様、基本的には機械へ命令して、やりたいことを叶えるためのツールです。

さらに、1つの言語で得たノウハウは他の言語を学ぶ際も役立ちます。
言語にどんな機能があることを知るよりも、なぜこのデザインパターンが存在するのか、
なぜこんな機能を持っているのかを知っておくと、別の言語ではどうなっているんだろうと考えることができ、
それらの積み重ねが新しい言語を学習する際の手がかりとなります。

なので、まずは**1つの言語の習得に絞る**のが良いです。

## フルコミットしてみる
僕はかつて1年以上休学して勉強させてもらいました。
フルコミットと週2回会社に来るのとでは、成長速度は全く違います。特に、**挑戦できる仕事のレベルが段違い**です。

実は毎日同じ場所にいるという事実が会社に与える安心感は非常に大きいです。

毎日いることはマネージメント側からすると、特定曜日しか来ないことと比べて管理が容易になるため、
難易度の高い仕事を振りやすくなります。
もちろん、大きな仕事を任されるまでの信頼を得るために、小さい仕事を繰り返しこなす必要もありますが、
**「毎日いる」ということは大きな仕事を任せてもらうために重要な変数の１つ**であることは間違いないです。
夏休みも近いですし、**手っ取り早くスキルを身に着けたい**のであれば、フルコミットしてみるのがいいでしょう。


## コードをひたすら読むこと
コードをひたすら読む目的は、**他人のコードを読むことに慣れ、そこから学習できるようにする**ためです。
基本的に何かコードを書くとき、ネット上のコードやチームの他のメンバーのコードを参考することが沢山あります。

特にフレームワーク等で開発をしていると、公式が公開しているAPIの挙動の中身や、
利用しているライブラリの中身など、実装上見る機会があるので、
普段からコードを読む習慣があると、他人のコードを読む際の抵抗感が小さくなる、調査速度が速くなるなど沢山メリットがあります。

しかし、いきなり参加したプロジェクトのコードをすべて読もうとしても、どこから読めばいいかわからないと思います。僕も過去にプロジェクトのすべてのファイルを理解しようとして、挫折したことがあります。
なので、すべてのファイルを読むのではなく、**Pull Requestに投げられているコードを読む**ことをおすすめします。

基本的にPull Requestは1機能あたり1つなので、コード量は読むには多くはありません。
また、機能と実装を結びつける良い機会になります。

特に、開発チームのリーダーやメンターの書いたコードは必ず読んで、少しでもわからなければどんどん質問しましょう。
過去のPull Request(Merge Request)を漁ってみて質問するのもいいと思います。

## 仮説を持って質問すること
初心者の場合、メンターへの質問を沢山飛ばすことになると思います。
その際、的外れでもなんでもいいので、**何かしらの仮説を持って質問してみる**と勉強になります。
「なんかエラー出てるけどよくわかんない。。。」ではなく、こじつけでも良いので仮説を立ててみましょう。

例えば以下のトラブルシューティングで、

```
Class 'UserController' not found
```

といったエラーが出た場合、「書いたコード上は問題がないから言語の方に問題があるんじゃないか」
という仮説を持った上で質問してみてもいいと思います。
実際には、名前解決ができていなかったり、ファイル名やクラス名が間違っていたりなど、
仮説が外れるケースが多々ありますが、仮説を立てることで自分の考え方のうち何が足りなかったのか、どうすれば改善できるのかなど反省し、学習することができます。

さらに仮説を持つ習慣をつけると、上記のようなトラブルシューティングの解決速度が向上したり、
「こういう理由があるから、こんな実装をしようと思っているのですが、どうでしょうか？」といった
**主体的な提案をメンターへすることができ、より良質なフィードバックがもらえる**ようになります。

なので、必ず仮説を持った上で望みましょう。


## わかってないのに、わかったって言わないことをやめる
非常に重要です。わかってないのにわかったというのは、下記の大きなリスクがあります。

**1. 学習機会を失うこと**
**2. 承認したというリスクを持つということ**

1については自分ひとりの問題で済みますが、2については他人に迷惑をかけることになります。
もしメンターに対してではなく、受託開発をしている想定でお客さんを前にした場合にこの状態に陥ると、
既に承認した自分に問題がある、ということになり、**信用を大きく失う可能性がある**ため、
わかっていないのにわかったと発言するのはやめるよう習慣づけましょう。


## おすすめされる書籍は必ず目を通すこと
書籍から学べることはたくさんあります。同じ本でもプログラミングを始めたばかりなのか、
ある程度慣れてきてからなのかで得られる知識は全く違うのですが、いずれにせよ非常に役に立ちます。

ただ、おすすめされる本は最初は難しく、**100%理解するのは不可能**なことが多いです。
ですが、全て目を通しておくことは最低限やっておいたほうがいいです。

というのも、実際にコードを書いてみると

「そう言えばあの本が参考になりそうな内容書いてあったな。。。」
といったように後々本の存在を思い出し、目的を持った上で学習し直すきっかけがうまれるので、
**中身を100%理解できずとも、目を通しておく**ことをおすすめします。


## 外部の勉強会に参加してみる
対外向けに勉強会を開いている企業は結構沢山あり、いざ足を運んでみると勉強になります。
ある程度機能の実装に慣れてきたり、語彙力が高まってくると、勉強会の内容がわかるようになるので、
**自分の理解度合いを測る**上で非常に効果的です。
「3ヶ月前にわからなかったことがわかるようになった。。。！」といった感動を得ることができるようになるだけでも、
より学習へのモチベーションに繋がります。

さらに、チームで開発をする上でどんな開発手法を取っているのか、どんなツールを採用しているのかなどのアイデアやワークフローについて、
**検証結果や実績を交えて紹介してくれている**ので、ものすごく勉強になります。


## 自分でプロダクトを作ってみる
自分でプロダクトを作ってみると、思っていたよりもコードが書けないということを自覚でき、
**何が能力として不足しているのか痛感させられます**。

また、仕事で書いているコードや開発手法に対して、
「なんでこれを採用しているんだろう。。。◯◯という理由があるからなのかな？」
といった**疑問と仮説が生まれる良い機会にもなります**。

さらに、個人での開発は〆切に追われることもなく、気軽に開発することができるので、
精神衛生上も安全でおすすめです。興味のある技術に触れてみたり、自身の復習も兼ねて、
どれだけ小さなプロダクトでも良いので取り組んでみると勉強になります。


## 一度に複数のことにチャレンジしないこと
「Laravelで機能開発はある程度できるようになったし、Dockerで環境構築してSPAチックなイケてるプロダクト作ってみよう！」
挑戦してみてもいいですが、確実にオーバーキルされると思うのでおすすめしません。
新しい技術に挑戦してみるのはものすごくいいことですが、
**一度に複数のことをやろうとすると、理解が追いつかずに失敗する**ことが往々にしてあります。

なので、新しい技術に挑戦するのであれば、**1つの技能ずつ**挑戦していくことをおすすめします。
感覚的には、やりたいことを決めた後に、
**できることを8割・今できないけど学習したいことを2割**程度にして挑戦するのがいい気がします。

例えば、先の例であれば、
「機能実装はできるけど、1からサイトを作るのは初めてだから、まずはLaravelでサイトの構築まで一人でやれるようにしよう！」
まで落としてから、徐々に取り組みたかった内容に挑戦するのがおすすめです。


## 自分で勉強会を開くこと
自分で勉強会を開くことで、技術に関する理解はものすごく深まります。
機能の仕組みが理解できていないために、いざ質問を受け付けてみると答えられなかったりします。

さらに、自分で勉強会を開く習慣がついていると、

「もしこの機能を勉強会で解説したら、いつも教えているAさんから"どうしてこんな仕組みにする必要があるの？"みたいな質問がなげられそうだ。」

といったように**自主的に深掘りをする習慣**ができます。
結果、勉強会を重ねれば重ねるほど、教えている分野についても理解を深められ、
自身が新しい分野を勉強する上でも、**理解までの速度を向上できる**ようになります。


# 最後に
エンジニアの最も大きな素養の1つとして、「やっていて好きである」という要素がありますが、
技術に強い興味・関心があったとしても、どうやって勉強すればよいのかがわからず、
成功体験が詰めなければ人は**簡単に挫折します**。
少なくとも僕は挫折を2度繰り返しました。

一方、2度の挫折を経験した僕にとってプログラミングが本当に楽しくなるようになったのは、
**親切に教えてもらえる環境**に出会え、成長実感を持てる**効果的な学習方法を選択できた**というのが要因として最も大きかったと思っています。結果、小さな成功体験を繰り返し積むことができるようになり、プログラミングが楽しくなりました。
だからこそ**環境**と**学習方法**はものすごく重要だと捉えています。

冒頭でも述べましたが、この記事がエンジニアインターンをこれから始める、もしくは挑戦し始めた人にとって、
少しでも役立てればいいなと思っています。

以上です！拙い文章でしたが、お付き合いいただきありがとうございました！

# 参考
* [2年前に独学でプログラミングを始めて成長速度が遅かった自分に後悔していることと、おすすめの勉強法と参考書](http://www.vivi-life.com/entry/2018/02/17/205006)
* [未経験からエンジニアとして働くようになるまでにやったこと、思ったこと](https://qiita.com/suy0n9/items/d1bfbd823d8b6dc562be)