独学プログラミング初心者が「エンジニア職」を始めるためにした7つの習慣

この記事は [Akatsuki Advent Calendar 2016](http://qiita.com/advent-calendar/2016/aktsk) の16日目です。
## 自己紹介
Qiitaで初投稿になります。 @nk16です。
スマホのゲームアプリ等を開発する会社で、今年新卒のエンジニアとして働いております。

結構同期のエンジニア方などは中学生の頃からC言語などに触れてたりと…すごくガチな方が多いのですが、僕はというと高校生の頃にブログのデザインをいじったりするためにHTMLやCSS、ならびにJavaScriptも少し覚えた！で喜んでたりするどうしょうもない人でした。

さらに当時の僕は配列が理解できなかったため、複数の要素に同じ計算をさせたい時に、
```
var a1 = 1;
var a2 = 2;
var b1 = a1 * 10;
var b2 = a2 * 10;
```
…といった形で変数増やしてコピペする超絶クソコードを書いてた黒歴史の持ち主です。

大学（一応情報工学科…）に入ってからも、

- サーバー側で処理する言語に興味を持ちPHPを勉強するも、XSS対策というものを知らず、URLのパラメータをエスケープせずにSQL文を組み立てるコードを書いてた。もし悪意のある人に見られたら大変なことになってた。
- PHPが多少書けるようになった頃、Webアプリ開発のバイトに応募して受かるも、小規模な新規事業で体制が全然整わずしまいには他のメンバーが卒業して一人でサーバー側のコードを書いてサーバー側の設定もするようになった。
  - 色々自分で調べて作り上げるもスキル的には実質独学の趣味開発に近い状態に。
- その後自分一人で大体出来ると間違った自信をもってしまった僕は時給に惹かれてWebアプリ開発の別のバイトに応募。PHPが書けたりWebアプリを一人で作れることから採用されるも、gitやbundler、migration、RESTなどWebアプリ開発で常識のように使われてる内容をココで初めて知り、あまりの違いにすぐにはついて行けず1ヶ月でクビに。
- その後反省し、モダンな開発で採り入れられてるものを趣味で作っているものに少しずつ採り入れて自信を取り戻す。しかし就活の時にこのような経験を面接で喋って技術的な経験ありますアピールをしたら、「データベースのレプリケーションについて分かりますか？」「TCPについて説明して下さい」と反撃され全く答えられなかった。（もちろん落ちた）

というエンジニア志望としては恥ずかしい失敗談を相変わらず生み続けておりました。

そんな僕でしたが、今では周囲の助けもあり日々コードを書きつつ学びつつ「エンジニア」として働いております。

そこで、今回は失敗談から得た学びや、今の会社の研修や業務での経験をもとに、僭越ながら未経験もしくは趣味もしくは一人でしかプログラム書いてなかった方々が「エンジニア」としてのキャリアを積み始めたい時に実践した習慣について書きたいと思います。

## 趣味プログラマーとエンジニア職の違いは、プログラムを書く「以外」の「面倒なこと」の多さ
自己紹介が長くなってしまいました。ここでは7つの習慣を書く前に、そもそもエンジニアの「業務」に求められることについて書きたいと思います。

趣味・独学でプログラムを書くとプログラミング言語の本やドキュメントを読むなり、自分で工夫して処理を考えるなり、人によってはググってコピペしたり…いずれにせよ「プログラムを書く」ということをだけを考えていてもある程度動くものが作れます。

しかし「エンジニア」の「業務」として必要なことは単に「プログラムを書いて動くものを作る」ということだけではありません。
私の現場の開発で単に「プログラムを書く」以外にエンジニアが考えてること・やることの例を挙げるとこんな感じになります…もちろん下記の内容は「趣味でやってる時も考慮してるわ！」と思う方も多いでしょうが、全部には対応してなかったり、特に一度も業務を経験しない場合はそもそも気付いてなかった点もあったりすると思います。
独学や学業でプログラミングをやり始めた時の僕はほぼ気付いてませんでました。

### プログラムを書く「以外」の「面倒なこと」の例
#### 計画をする
- 業務では期限を決めて間に合うように開発するのが最優先。どんなタスクが必要か洗い出して見積もり、計画をする。
- 遅れそうかどうか確認を逐次行い、遅れそうなら他の方に一部タスクをお願いするなど対策を考える。

#### チームの方々と一緒に開発出来るようにする
- gitやbundler等を使い、皆のPCやサーバーでなるべく同じ環境を簡単に再現できるようにする。
- 他のメンバーが見ても分かるコードにする。他のメンバーが変更点を確認しやすいよう、gitを操作してコミットを整理する。
- エンジニアだけでなくディレクターなど様々な職種の方が作業しやすいようにするため、ツールを作る。

### お客様からお金を頂ける品質のサービスにする
- 課金したのにエラーで反映されない、いつの間にかデータが消し飛んだ、突然遊べなくなったなどの不具合は当然NG！
  - 当たり前でもそれを「99.9%」でなく「100%」起きないように対応するのは意外と難しい。
- 確実に動作する質の高いシステムにするため、2回ボタンを押したりはもちろん、途中で通信が止まった、途中でアプリを強制終了させた、不正を企んだ…などいろんな条件を考えてコードやテストを追加修正する。
- レビューとよばれる設計やプログラムの内容の確認作業をエンジニア同士で行う。問題になりそうな箇所が見つかれば指摘し、修正する。
- ネット上からソースコードをコピペする、信憑性のない情報を参考にするのは著作権的に問題なくてもなるべく避ける。採り入れるにしても自分で内容を確認して理解できていることが条件。

#### サービスをリリースしてからのことを考える
- 低スペックな端末でも動くように、利用者が殺到してもサーバーが止まらないように、プログラムを修正してチェックする。
- 利用者が殺到しても大丈夫かつトラブルやデータ消失リスクの低い、複数台のサーバー構成を考えて設定をする。さらに、設定や機能の追加・変更の適用（デプロイ）を簡単に出来る仕組みを作る。
- サーバー代を削減できるよう、サーバーの設定やコードを見直す。あるいは必要な分だけサーバーを動かせるよう、柔軟に変更可能な構成・仕組みにする。
- お客様からの問い合わせの事実確認とトラブルシューティング、もしくは利用状況の分析をするために、ログを保存して簡単に参照できる仕組みを作る。

……などなど、「エンジニア」の仕事はプログラムを書く「**以外**」の「**面倒なこと**」が大半です（笑）。

実際欲しい機能がざっくり動くだけのプログラムを書く（プロトタイプを作る）作業よりも、**上記のことを考えてリリースする作業のほうがはるかに時間がかかります**し、さらにリリース後に都度時間を割いて改善していくこともしばしばあります。

ですので、「アマのプログラマ」と「プロのエンジニア」の差は**業務の大半**を占めるこのような「**面倒なこと**」に対応する・できるかどうか、だと思いました。

## プログラムを書く「以外」の「面倒なこと」を出来るようにするためにやりたい7つの習慣
ではここから本題です。上記のような「面倒なこと」には、単に「プログラムを書く」ことだけを考えていたら対応できるわけではありません。
特に趣味から始めて動くだけのプログラムを書いてきた人が、その後いきなり即戦力で業務のコードを書こうとした場合、相当必死にやらないとついていけないと思います。（僕はバイト時代についていけなかった経験がありました…）

その後反省して趣味の開発で下記の習慣の一部を始めた結果、現職の新卒技術者研修にだいぶついて行きやすくなりました。
また研修を通じて学んだ習慣を足しながら新しいことを学んでいくことで、第一線の現場での技術業務にも入りやすくなりました。

最初のうちは結構しんどいですが、慣れると新しいことにも簡単に対応できるようになり、段々と開発がより捗るようになります。正直業務でも毎日全部実践すると仕事が終わらなくなるくらいハードな内容なので（笑）、しんどければ負担を減らして少しずつ‥でも続けば効果的だと思います。（最初はgitを学習する時だけは…次はログイン機能を作る時だけは試してみよう、など）

### 1.（特にWebサーバ系では）面倒でもチュートリアルをやる
弊社の新卒サーバーエンジニアでも、1ヶ月いたバイト先でもまず出された課題といえば、まずネットで公開されてる（Railsなどの）チュートリアルをやることでした。
RailsTutorialなどチュートリアルって結構長くて面倒くさい…なんて感じますし、実際愚直にやれば1〜2週間フルタイムでかかりますが、プログラムを書くだけでなくエンジニア業務をする上で結構重要なエッセンスが詰まってました。

- 複数人開発では欠かせない、gitの使い方について
- サーバーへの攻撃（XSS、CSRF、パラメータ改ざんなど）から守る方法について
- 万一データ漏えいが起きてもユーザーのパスワードが流出しない、ログイン認証方法（パスワードのハッシュ化）
- 効率的なデータベースの設計方法について（正規化、インデックスなど）

…などなど、Railsでのプログラムの書き方**以外**の情報のほうが詰まっているのではないかというくらいの中身でした。
でもそれはRailsを使って**エンジニア**として仕事するためには欠かせない内容ばかりでした。

特に初めてアプリを作りたくて何が必要なのか分からないときこそ、面倒だからといって適当にサンプルコードを組み立てる横着をせずに読んでおくべきだったと反省しております。

### 2.面倒でも分からない単語は調べる
公式の文献などを読んでいるとわからない単語に出会うことも多いです。
例えば、URLに応じて表示内容を変える仕組みを作りたくてルーティングの設定方法について調べていくと、RESTとは何かGET・POST・PUTとは何か、さらに安全なメソッド、冪等とは何か…など掘り下げていくうちにキリが無くて全然進まなくて面倒なことになったりすると思います。

たしかにルーティングの設定方法さえ知っていれば動くものを作れますが、他の関連ワードにはエンジニア達での"決め事"や"基本的な考え方・パターン"が詰まっています。これらについて調べていくことはエンジニア方の話についていったり、的外れなことをされてると思われないためにも大切です。またこれらの決め事やパターンは、過去のエンジニア達がこうしたほうが合理的・効率的と考えた結果だったりもしますので、効率的な開発に役立ってくれます。

特にRailsTutorialで散りばめられている、プログラミングとは直接関係ないワードについても根気よく調べると、Webエンジニアとして知ってほしい内容をある程度網羅できそうです。

### 3.面倒でも信頼できるソースを極力使う。
結構公式ドキュメントなどの信頼できるソースは、よく分からない割りに使い方のサンプルが少なくてつらい、もし☓☓をしたい時はどうすればいいの…なんて最初のうちは結構思ってしまいました。

もちろんQiitaやStackOverFlowのTipsなどを通じて作業やトラブルシューティングすることもありますが、間違いや誤解された情報を信じて作業をすると、後戻りが大きく発生してしまうもの。間違いや誤解を確認して気づけるようにするためにも、特に学び始めのものに関しては信頼できるソースを読んで理解を深めるのが理想です。

### 面倒と思っても日本語のソースが無ければ英語を読む
新しい、もしくはマイナーなツールのドキュメントや、メジャーでも深い部分の内容は英語しかないことが往々にしてあります。
結構理科系の大学に進学した方だと最新の情報や深い情報を知るために英語の文献を読んだ方も多いと思いますが、それと同じ理由でエンジニアも英語の文献を読んだりします。

ただ文法が難しいよりかは専門の単語が分からなかったりすることが多いと思います。また専門用語は日本語と英語でカタカナかアルファベットの違いしか無いことが多いので、次項に述べる「面倒でも分からない単語は調べる」に近いものがあります。英語を勉強しなきゃ…と身構える必要はあまりありません。

### 4.面倒でもエラーの解決策より原因を先に考える。
プログラミング中やツールを触る時に、途中でエラーは必ずといっていいほど出てしまうもの。
早く解決したいと焦る気持ちはわかりますが、エラーの文章でググってStackOverflowで出た解決策を適当に試す…だと上手く行かないことが多いです。なぜなら返って来るエラーの**結果**は同じでも**原因は場合によって様々**だからです
従ってエラーが起こる原因が何だったかを考えないと、見当違いの変更を繰り返して結局意味がわからないことになってしまいます。

前項で述べた分からない単語の意味を調べて知識を増やすのは、実はエラーの原因を特定する力を上げる効果もあります。
パソコンのトラブルで例えると「パソコンの調子が悪くて動きが鈍い。」としか言えなかったのが「CPUとメモリ、HDDの使用率に問題はないか。またそれらの使用率が高いプロセスが無いか、タスクマネージャーで調べよう」…と考えられるになれる、といった感じです。

### 5.面倒と思ってもきれいにコードを書く
#### 面倒と思っても変数名は丁寧に
結構私は変数名の付け方で悩んで時間を食ってしまうことが多いですが、他の方に聞いてもちゃんと和英辞典で調べたり、それでも悩んだりしているそうですｗ

曖昧さが無く（例えばclearだと消去なのか（ゲームの）クリアなのか分からなくなるから☓）、かつ長すぎず…また他の箇所との統一感を考えたら…なんて考えていくとどんどん悩ましくなります。

趣味でプログラム書いてる頃は考える時間がもったいないから適当に思いつきで、とかeach操作はとりあえずkey、valueでといった具合に書いてましたが、業務でそれは許されることではありません。

しかし適当な変数名で書き殴った久々に自分のコードを触れると、思い返すのにだいぶ時間がかかってしまい、改修しようにも面倒だから乗り気になれない、あるいはやるなら丸っと書き換えなきゃ…と思っているうちにプログラムに手を付ける気力がなくなってしまいますｗ

実は相手のためだけでなく自分のためにもなる大事な作業だったんだなと感じております。

#### 面倒と思ってもコーディング規約に従う
チーム開発ではコードの書き方のルールが細かくて面倒…とは感じつつも、美意識の高いエンジニアは結構多いようで、そこそこ重く見られてしまいます。カッコは改行して書く、ココは1行空ける、でもメソッドは20行以内、一行は80字…など、プロジェクトによりますがルールは様々。動くプログラムが書ければ…と思ってた僕が書き方のルールに慣れるまでにはやや時間がかかりました。

#### コーディング規約チェックツールを使う
rubyだとrubocop、phpならPHP_CodeSnifferなど、書き方が"ルールに従ってて綺麗"かどうかチェックしてくれるツールがあったりもします。間違っている箇所があったら目で追って探さずともちゃんと都度指摘してくれるので便利ですし、これを使って指摘されないコードを書くことで楽に慣れられます。
またルール定義を記述して共有することで、各プロジェクト毎に"ローカルルール"を決めて、それを適用させることも出来て便利です。

### 6.面倒と思ってもツールを色々入れて覚える
結構初心者にとって開発に使うツールを入れるというのは一苦労だったりすると思います。私も最初はうまく扱えませんでした。

例えばgitだとコミットのやり方をミスった時に修正しようとすると時々訳の分からないことになるし、bundlerもmigrationも最初は時々よく分からないエラー吐くし面倒…なんて思いつつ、チーム開発のためにしぶしぶ使っていました。

#### 面倒と思ってもツールの使い方はなんとなくで済まさずちゃんと理解する。
でもうまく扱えない時に理解が足りてないままだと、結局ずっと躓いたままになってしまいます。

例えばgitでセーブしたいときがcommitで元に戻したいときがresetでコミットまとめる時がrebase -i だっけ…といった**適当な理解のままで居るとうまく扱えないままになります**…面倒でもどの操作をするとブランチがどのコミットの位置に動くのか、ファイルの内容は書き換わるのかどうか、どの変更がステージングないしはコミットされてどの変更がされないのか…などの挙動を地道に理解できるようになると結構強い味方になってくれます。

### 7.面倒と思っても良いライブラリがあれば使う。
僕が初心者の時に陥ってしまった悪いやり方として、ライブラリというのを知らず基本的なログイン機能でも自分で考えて実装したりネットのソースコードをコピペして参考にしてしまっていました。

ライブラリは最初は使い方を読んでも分かりづらったり覚えるのが大変だったり、ちょっと複雑なことをしたいときに痒いところに手が届かない…でもライブラリのソースコードを変えるのは難しくてかなりの手間になるから意外と使いづらかったりすることも多い…経験もあると思います。

が、良いライブラリはいろんなケースで使われていくうちに気付いたバグを修正してくれたり、関連するライブラリやツールのバージョンアップデートに対応してくれたり…と、業務で作る品質の高いシステムを作る上で役立ってくれます！ネット上のソースコードをコピペしてカスタム…というやり方の場合、これらの恩恵が受けられなくなるので禁物ですし、自分で書くと自分でこれも修正対応しなければならないですので後々厄介になってしまいます。

## おわりに：最初は面倒でも後々楽になる。
最初はプログラムを書いたり手っ取り早く何か作りたいのに、あれもこれも色々あってもう面倒だーという感想になる方が多いと思います。私も開発スタイルを改めた時は最初は慣れずに作業が逆に遅くなることが多いですが、段々と覚えていくうちに効率も上がって、後戻りが少なくなったりエラーにぶち当たってもすぐ自己解決できたり…と自分のプログラミングに対しての効果にも還ってきます。そしてなにより開発がより楽しく出来るようになるので、やって損はないと思います。

### さいごに
面倒でも最後まで読んでくれた方々ありがとうございました。

もしガチなエンジニアや面接官がこれを読まれてましたら、「独学で作った」だけの実績を見て即戦力採用の判断をした場合に、上記のような理由から必要なスキルが足りず上手く行かない場合があることを知っていただけると幸いです。昔バズった「某R社を5日でクビになった話」もこれと似たような原因ではないかなと推察します。

もし非技術者の方がこれを読まれてましたら、「なんで動くプロトタイプはすぐ作れるのにリリースまでの見積もりがこんなに長いんだろう」という理由を理解していただけたり、「何を頼んでも動くアウトプットが早く出て来るからこの人すごい、技術力ある」と判断するのは危険なことを知っていただけると嬉しいです。早い場合、見えづらいけど本当は必要なものを見落としてる/要件に合わせて抜かしてるだけの可能性があります。

もし新卒で就活中の方がこれを読まれてましたら…（学生バイトは別ですが）新卒採用は即戦力採用ではないので、ほとんどの場合は上記のようなスキルを実際に磨くのは後で間に合うようです。それよりも今のうちは基礎的な人間力を磨くほうが大事かもしれないです…（経験談）