Webエンジニア1年目が終了しました

# 入社前の状態

## 入社前のレベル

入社前は以下のようなレベルでした。

### フロントエンド

* HTMLのdata-attributeを知らない
* jQueryという単語しか知らない、Javascriptの知識はなし
* CSSはBootstrapのグリッドしか使いこなせず、marginとpaddingすら理解していない
* Chrome検証ツールを使いこなせていなかった
* Javascriptの非同期の概念を勘違いしていた

### サーバサイド

* AjaxはRailsのヘルパーメソッドである `remote: true` しか使ったことがない
* Rubyのテンプレートエンジンはerbしかないと思っていた
* Railsのレスポンスに搭載されているJBuilderは何のために用意されているか知らない
* exception.logの存在を知らず、サーバのログのみでエラーを解決しようとしていた
* `Collection.all` の戻り値はArrayのオブジェクトだと思っていた
* Railsのモデルにインスタンスメソッドを定義したことがない
* ブロックがわからない

### インフラ

* MacのFinderばかり使っていたので、mvコマンドやcpコマンドを打ったことがない
* シンボリックリンクを知らない
* DNSという単語は知っていたが、切り替えたりレコードを操作したことがない
* AWSのサービスはEC2とS3以外知らない
* 本番サーバに入ったことがない (当然scpコマンドやsshログインをしたことがない)
* インフラに関する単語をほぼ知らない
* Ansibleのような自動サーバ構築ツールを知らない

# こなした業務

自分は以下の業務をこなしました。

## 機能開発

* 一覧画面にてドラッグ&ドロップで並び替え
* 顧客の年齢を表示するロジックの実装
* Ransack 改行区切りで検索できるようにする
* 外部決済のAPIを叩くためのXMLの追加
* 処理が失敗した時にSlackに通知するように
* LP購入フォームにて、規格を用いて複数のSKUを選択できるように
* クーポン機能の実装
* 閏年や存在しない日 (4/31) を考慮した生年月日のプルダウン実装
* Sidekiqを用いた一括更新機能の実装
* ショップのマイページにて定期受注に紐付く支払方法を変更できるように
* ショップのマイページにて定期受注に紐付く商品を変更できるように
* バナー画像を登録できるように
* 配送予定日「指定なし」で検索できるよう受注管理検索条件に追加 (change)
* 管理者に対してグループを設定できるように
* 管理画面における検索条件の保存機能
* 集計用のテーブルを作成し、1時間に1回顧客のアクセス履歴を集計することで、データ取得の時間を削減
* S3のファイルが1万ほど存在しているショップでも1秒以内にレスポンスが返却されるように実装

## その他

* 本番環境にSSHログインし、実行者や日時を特定
* 設定値の切り替えをコードベースまたはデータパッチをして対応
* 本番環境にてRailsコンソールを叩き、データ修正
* Ansibleを使ってVPCの構築
* AWSのRoute53を利用してDNSの切り替え/運用
* カートシステムに関するFAQのシステムをテーブル設計から実装、動作確認
* ショップデザインの案件を5つ担当
* 未経験者3人をエンジニアの卵までに育成

# 入社後の変化

## フロントエンド

今までJavascriptを全くやってこなかったので、先入観で難しい言語と認識していました（実際難しいですが）。
最初はAjaxやJSONという言葉を聞いただけでアレルギーが出ていました。
しかし開発していく中で以下のポイントを抑えると開発スピードが上がったことを実感しました。

### シングルスレッド

Javascriptはシングルスレッドなので、並列処理ができません。
したがって `非同期` という概念は `後回し` という意味に近いです。
Backbone.jsにはAjaxを実現するためのfunctionとして `fetch` が挙げられますが、Ajax通信にて取得した値を使って何かをしたいのであれば、 `fetchの後に処理する` という定義をする必要があります。

```coffee
model = Model.fetch()
model.get('name')
```

```coffee
model = Model.fetch().then ->
  model.get('name')
```

### renderという言葉

自分は最初、renderはHTMLを `返却` することを指していると勘違いしていました。
しかし実際は `生成` するという感覚に近いことを理解しました。
Backbone.jsにもrenderというfunctionがありますが、上記を理解してからBackbone.jsを1段階使いこなせるようになりました。

### JSONの必要性

Railsアプリケーションを開発するときに `XXX.json.jbuilder` というビューファイルを今まで一度も使ったことがなかったので、必要性を感じませんでした。
しかし実際は様々な箇所でAjax通信を行なっており、 `XXX.json.jbuilder` が引っ張りだこでした。
JSはRailsのアソシエーションのようにメソッドチェーンの融通がそこまで効かないので、 `XXX.json.jbuilder` が頑張らないといけないという感覚も身につきました。

### thisが指すもの

thisが何を指しているかを理解することで、コードリーディングが格段に速くなりました。


## サーバサイド

### 大規模アプリケーション慣れる

最初に弊社のカートシステムのコードを共有してもらった時に、Railsアプリケーションのappディレクトリ配下のファイル数に驚きを隠せませんでした。
半年くらい経ってようやく規模の大きさに慣れました。
免疫をつけることは意外と大事ということに気づきました。

### コールバックを考慮

大規模アプリケーションを開発する上で一番意識したのは `コールバック` です。
どこが連動してどこが連動してはいけないのかを追うのが大変でした。
Railsコンソールからデータパッチを行う際も `update` または `update_column` のどちらを使うかなど、影響範囲をチェックする必要があるため気をつかう場面が多かったです。

### SQLへの意識

大規模アプリケーションは発行されるSQLの量も多かったです。
したがってどのようなSQLが発行されるかについて、より意識するようになりました。
データ移行の際に使用した `activerecord-import` というgemが印象的で、１つのINSERT文で一気にデータを保存できることも学びました。

### エンジニアとしての勘所

自分は前職のインターンでプログラミング教育に携わっていたため、それを生かしてRubyエンジニアの育成をしました。
育成していく中で、欠けてはいけない要素を見つけました。
まず１つ目は `Railsコンソールをノンストレスで叩ける` ことです。
RailsコンソールはActiveRecordを介したDB操作はもちろん、Rubyの記述確認やpryデバックを用いて変数やメソッドの確認をすることができます。
さらにリクエストを発生させてステータスコードを返却することもできます。

```
app.get '/blogs'
=> 200
```

Ruby以外の言語でもコンソールを叩いたり、Chromeの検証ツールを使いこなせることは必須スキルと言えるでしょう。

２つ目は `オブジェクト操作 (クラス/インスタンス/メソッド) を完全に理解している` ことです。

```
Model.none
=> []

Array.new
=> []
```

例えば上記は同じ空の配列に見えますが、以下のように全く所属の違うオブジェクトということがわかります。

```
Model.none.class
=> ActiveRecord_Relation

Array.new.class
=> Array
```

自分自身も、どのクラスに所属したオブジェクトかを理解することで開発スピードが一気に上がることを体感しました。
デザインパターンまでは理解していなくても、オブジェクト操作を理解していないとRailsのモデルに何かメソッドを定義したり、メソッドチェーンで値を取得したりすることができず、上っ面の開発 (Railsのビューの改善など) に留まってしまいます。
したがってオブジェクト操作ができることも必須スキルと言えるでしょう。

このように実務を経験したことでエンジニアとして業務をするための勘所を抑えることができました。

## インフラ

### AWSのサービスを使ったインフラ運用

前述の通り、自分はインフラの知識がゼロに等しかったので、実務をしながら覚えるスタイルでインフラを徐々に理解していきました。
AWSのサービス (Route53/Cloud Formation/IAM/RDS/Certificate Manager/ALB) を使ったインフラ運用を行いました。
DNSに関して、最初はAレコードしか分かりませんでしたが、AWS特有のALASレコードを含め、ほとんどのレコードの役割と仕組みを理解しました。
インフラ運用を行ったことでWebアプリケーションの全体像がはっきりし、エラーが起きた時に何が原因なのかが掴めてきました。
実務レベルのインフラ運用に携われる環境はなかなかないので、強化できて良かったと思っています。

### 本番での作業

自分は本番環境での作業をしたことがなかったので、本番環境での作業をする上でどんなスキルが必要なのかが分かっていませんでした。
いざSSHログインしてみると、権限やメモリ使用率の見方、ファイル操作ができずにいました。
最近ではAtomやRubyMineなど便利なテキストエディタが揃っていますが、本番サーバでテキストエディタは使えないので、最低限必要なVim操作が出来てからテキストエディタを使った方が良いと感じました。

# 今年度

決済システムの開発と運用を頑張ります。