読者です 読者をやめる 読者になる 読者になる

あすたぴのブログ

astap(あすたぴ)のブログ

転職して1年がたったので振り返ります。

一応退職エントリ(のつもり)です。

だれですか

@astapi (あすたぴ)といいます。

IT系の受託開発の会社で新卒から9年働いていました。

顧客は割りと大きめの会社で、内容は言えないのですが結構面白い仕事もやらせてもらっていました。

2015年11月1日にSupership株式会社に入社し、1年が経ったのでこの1年でやったことを振り返ってみようと思います。

転職をしたいと思った理由

転職をしたいと思った理由としては3つあります。

1つ目が一番大きな理由ですが、エンジニアとして働きたかったです。

9年も働いていると自然と管理職になり、自然とコードが書く量が減っていきました。 そういう仕事ではなく、ちゃんと自分の手でコードを書きたかったです。

2つ目は開発の環境です。

受託開発である以上、顧客から開発環境(言語、サーバー)等を指定されることも多いです。 且つ、昔から続いている、保守案件も多かった為、アーキテクチャ的には古いものが多くありました。

3つ目は、自分がサービスを作ってる感がほしかったです。

受託開発のため、自分がこれを作っている。 このサービスをやっている。というのはなかなか言えません。 もっと、自分がこれを作っているんだ。いいものを作って世に出したい。 という思いを持って、開発がしたかったです。

転職してからやったこと - 勉強編

自分に実力が足りないことはわかっていたので必死に学びました。具体的には、

  • 基礎を学ぶ
  • スキルを深める
  • エンジニアとしての活動の幅を広げる

の3つです。

基礎を学ぶ

自分は専門学校卒できちんとしたコンピューター・サイエンスを学んでいません。 なので、コンピュータ、プログラミングの基礎、歴史からしっかり学ぼうと思ってこれらを読んでいました。

どんな技術でも、最終的にはコンピュータに命令を行うことになります。 その際に使用している、システムコールを意識することはたまにはあるかもしれません。 自分の使っている言語、ライブラリなどが最終的にコンピュータに対してどのような命令を行っているのか、明確に見なくてもイメージすることは、その技術を正しく使うにあたって重要だと思います。

歴史を知ることはいまの技術の理解につながります。 技術は、日々時代と共に、進歩を続けてきていますが、古い技術はもう使えないということはなく、 新しい技術でも古くからの伝統的な素晴らしい考えに沿っているものがほとんどです。 歴史を知ることはいまの技術の理解につながります。

読み終わっていないものも多いので、絶対にちゃんと読みますw

スキルを深める

現在、サーバーサイドエンジニアとして、APIを作っています。 サーバーサイドといっても、アプリのコードを書くだけではなく、 意味合い的にはフロント以外のすべてをやる。という意味です。 それに必要な技術を深掘りしようとしました。

インフラ

プロジェクトはオンプレではなく全AWSなので、AWSでも通じる知識、AWSではどうするのか。 itamae, packer, terraform, cosul等のインフラ構築ツールを学びました。 基盤こそ、インフラエンジニアの方が作ったものですが、いまは、私がサービスのインフラ改修も行っています。

インフラは全部コード化されていて、AWSのコンソールから直接構築することはありません。 AMIのイメージはpackerで構築しています。 とはいっても、AMIの作り直しは言語のversionが上がったり、した時くらいです。 AWS環境の構築はterraformで行われています。 AWS上のインスタンス間はconsulでクラスタ化されていて、 deploy時はconsulのリーダーからクラスタのメンバーへ通知を行ってます。

サーバーサイド

プロジェクトでElixirを使ってるので、ErlangとElixirをやりまくってました。 Elixirは、ErlangVM上で生成される軽量プロセスを大量に利用した、 並行、並列処理が得意で、非同期処理を頻繁に使いたいシステムと親和性が高いです。

Rubyは、プロジェクトで使っているのもあり、しっかりと学ぼうとしました。

新しい技術を学ぶときは、既存の技術には何か問題があり、 問題を解決するために新しい技術を作っている人がいる。 どんな問題をどう解決しようとしているのか? を考えると、その技術の使い所、使い方を見えやすくなるのでおすすめです。

エンジニアとしての幅を広げる

他、業務とは関係ないですが以下のようなこともやりました。 上司との1on1で、こういうことをやりたいんです。って言ったら、 じゃあやってみよう。って背中を押してもらったのでやりました。

オープンソースへの関与など

  • ライブラリを作った。
  • OSS開発
    • てきとうにgithubで探したライブラリにpull requestを送った。
    • 感謝されたけど、取り込まれはしなかった。
    • やり取りが暖かくて嬉しかった。(英語)

勉強会での登壇や運営への参加

Elixirの勉強会 tokyo.ex にて、LTと、パネルトークをしました。

Elixirを本番で導入しているという観点から、多少は話せたのかな・・・。

ご縁があり、運営としても参加させてもらっています。 (積極的に手伝えておらず、申し訳ないです。)

転職してからやったこと - 仕事編

非常に楽しく仕事ができました。

楽しく仕事ができる環境を用意してもらい、本当にありがとうございます。 一番良かったことは、任せてもらい、失敗をさせてもらえたことです。(勝手に失敗して勝手に直してる)

自分で設計して、自分で導入して、自分で失敗に気づいて、自分で改善策を調べて自分で直しました。

1つのサービスで、機能追加や改修のたびに、 (自分で書いた)良くない部分を直しつつ、進めてきました。 これが非常に、よかったです。

デザインパターンや、コードの設計に関することが非常に苦手で、 どこに適用すればいいのか、適用したらどうなるのかがいまいちイメージが出来ていませんでした。 自分が失敗したと、思ったことをパターンに当てはめて、 改善することで初めて、使えるようになったと思っています。

振り返り

プライベートの学習を振り返ってみると、 これだけしかやっていないのかと思いました。

自分的には、なんとなく1年前に比べたらかなり成長したなぁ。

という感覚があったのですが、 まとめてみると、あっさりしている気がします。

昔はアウトプットを意識していたのですが、 この1年はインプットの割合が多すぎました。 これからは、学んだことをしっかりと自分のためにも残していこうと思います。

終わりに

最近読んだ中で好きなマンガで、BlueGiant、ベイビーステップがあります。

この2つの本に共通しているのは、 最初から強い、何か特別な能力を持っているわけではない主人公が、 地道に地道に1つ1つを積み重ねて成長していく。というところです。

自分は、そんなに頭が良いわけでもなく、 理解が早いわけでもないので、 この本の主人公たちのように1つ1つを積み重ねていかないとダメだと思っています。

これからも、いまよりがんばって積み重ねていきたいと思っています。 ここまで読んでくれてありがとうございました!!!

おまけ

Supership株式会社ではエンジニアを募集しています。

興味がある方はSupership HP,wantedllyから応募するか、

私にお声がけください。

個人の開発環境について

プライベートではなく、仕事で開発をする際に、

他のところは、どのような開発環境を構築しているのだろうか。

技術的な環境と、仕組み的な環境にわけられると思うが、

技術的な環境

  • ローカルのWindowsMacに構築する。
  • vagrant等のVM環境をローカルに乗せてその上に構築する。
  • docker等のコンテナを用いて、その上に構築する。
  • AWS,GCPインスタンスを立てて構築する。

仕組み的な環境

  • 全員が同じ環境になるようにしている。chef等のプロビジョニングツールで用いて容易に構築が可能。
  • 手順だけ決まっていて、それぞれで構築する。
  • 各自適当に構築している。

技術的な環境で言うと、割りとバラけてるような気がする。

最近ではdockerが多くなってきているのかな?

仕組み的な環境で言うと、そこそこしっかりしたところはプロビジョニングツールを使ってるだろうな。

自分の話し

これ。

  • vagrant等のVM環境をローカルに乗せてその上に構築する。
  • 各自適当に構築している。

あんまりよくないですね。

もともとは、

  • ローカルのWindowsMacに構築する。
  • 手順だけ決まっていて、それぞれで構築する。

だったんだけど、

ローカルに構築するのが好きではないので、

勝手に自分で環境を構築した。

自分用のvagrant環境と用意して、itamaeを書いて、構築できるようにしている。

個人的な考えとしては開発環境は、 人によってやりやすさが違うと思うので、

自分で構築してトラブルが発生しても自分で解決するのであれば 自由でいいと思っている。

Activerecordのパフォーマンスチューニング

背景

仕事でactiverecordを使用していて、

複数のテーブルのデータを返す必要がある場合に、

レスポンスが一気に遅くなったために調べていた。

N+1問題を解消

まず、最初にあまり気にせずにN+1を行っていたので解消した。

解消方法としては、includes, prelaod、eager_loadがある。

今回はjoinして絞り込む必要がなく、

複数のクエリで単純にセレクトをしたかったのでpreloadをしていた。

これを行うことによって、クエリの発行数が抑えられた(もともと、大した量ではなかったけど)

ボトルネックを明確にする。

しかし、preloadを行っても性能はあまり改善が見られなかった。

ボトルネックを明確にする為に、

rack-profilerを使用し、

細かく各処理の時間を見ていたが、

どうもロジックと全体の時間が合っていない。

activerecordでセレクトし、生成されたオブジェクトのループ全体の時間と

ループ内の処理の時間を足した時間が一致しない。

ループ時のループ変数(って言葉ある?)を生成するタイミングで時間がかかっているようだった。

Object生成のコスト

N+1問題の解消の為に、予めクエリを発行し、キャッシュしていくことが解決方法であるが、

そこで予め生成するオブジェクトのコストはN+1でクエリを発行するよりも重い場合がある。

多くをpreloadしたオブジェクトを each メソッド等でループする際に、

紐づくテーブルの情報もオブジェクト生成が行われる。

結果として、1ループあたりの、ループ変数の生成に時間がかかるようになる。

つまり、N+1のクエリ発行とpreloadのオブジェクト生成の時間はトレードオフになる。

結論

レコード数や関連するテーブル、オブジェクト生成数によって

何が一番良いかが変わるため、正解がない。

今回の場合は、preloadはしておきたいものの、

preloadしたいレコード数が決まっていた。(全てを取る必要がない)

そのため、 preloadで全レコードのオブジェクト生成のコストよりN+1のコストのほうが低くなった。

tips

オブジェクトの生成が必要なく、

セレクトしてきたデータのみが必要な場合は、pluckメソッドを使用することで

オブジェクト生成せずに、データが取得できる。

User.all.pluck(:id, :name)
[
  [1, 'hoge'],
  [2, 'moge']
]

みたいなデータが取れる。

DMM Cupに感動した

www.youtube.com

一昨日行われていた、DMM Cup っていうストリートファイター5の大会の決勝動画。

決勝が19歳チーム対プロゲーマーというのが感動した・・・。

格ゲーシーンはずっと、同じ人達が活躍していて、

ギルティギアなんて、10年以上前からTOPがほぼ変わっていない。

SF4も8年以上続いていたシリーズだったので、これもやっぱり上位はずっと同じ。

今回SF5はその状況をリセットするとうたっての発売だったが、

実質的にはほぼ変わらず前シリーズの強者がそのまま居座っていた。(世界大会では一部、海外の若手で強い選手もでてきている)

そんな中、日本でも今回のように、若手の強い選手がでてきてすごく嬉しい。(もうこの感想が老害

SF5はゲーム性が変わったとはいえ、

やはり強いひとはそのまま強くて、リセットって何?みたいに言われてたけど、

SF4はシリーズが続きすぎて参入障壁が高かった。

それがSF5で全員が一度同じスタート地点に戻るというリセットであればそれは正しかったんだと思う。

今、格ゲーシーン最高に熱いです。

EVOという7月末にアメリカで行われる大会はエントリー人数が4000人を超えて過去最高。