Webエンジニア hakshuの部屋

のらりくらりと綴る

退職しました

2月末で約2年半勤めたEdTechの会社を退職したので、少し振り返っておきます。

やってきたこと

技術面

  • 新規機能開発 ×2
  • Rails v4 -> v5へのアップデート
  • jQueryやAngularのメジャーバージョンアップデート
  • EC2からECSへのインフラ移行
  • PHPからRailsへの一部機能リプレイス
  • Sidekiqの導入
  • Terraform
  • 既存機能の運用・問い合わせ対応

技術以外

  • 外部勉強会の運営お手伝い
  • 学校への訪問
  • 新人研修でのメンター
  • スクラム開発
  • 後輩のメンター

振り返ってみて

社会人人生2社目の会社となりましたが、Webエンジニアとして多くのことを経験させて頂きました。

1社目では未経験であったにも関わらず、Web開発に限らず幅広く色んなことをやらせてもらいましたが、2社目ではWeb開発と運用について深く学び、経験することができたと思います。

EdTech事業を手掛けているということもあってか教育に対して思いのある方が多く、入社直後はその熱量に感動していました。

また、技術力も人間力も高い方が多く、大変刺激を受けましたし、多くの学びを得ることができました。

少し年数を重ねたこともあり、後輩や新卒の指導にもあたりました。こちらも自分にとって得るものは大きかったです。

退職に至った経緯

自分にとっては得るものが多く、いわゆる第二新卒だった経験値も少なかった自分を拾っていただいた会社に対しては感謝しかありません。

なぜ退職するかと言うと、教育に熱量がある方々に接し、また後輩指導などに携わる中で、学校教育について専門的に学んできた自分自身が学校の内側から教師として教育をより良くしていくべきだと感じていったためです。

また、日々の業務の中で、コロナウイルスによる社会の変化や学習指導要領の改訂などで学校を取り巻く環境が大きく変わってきていること、自分が大学で学んできたことと乖離し始めていることや年齢から多少の焦りも感じ始めていました。

以上のことから、次のキャリアとして学校の中で働いていくことを考え、退職という決断に至りました。

これから

まだ決まっていないですが、少しゆっくりしてから教員免許を取得するため通信制の大学で学び直しながら子供たちに関わる仕事をしようと思っています。

一番働くことを考えている小学校の教員免許は既に持っているので、試験を受ければよいだけなんですが、せっかくなので教科の専門性を高めることを考え、中高免許を取得しようと考えています。

5年間やってきたエンジニアから離れることになりますが、趣味や何らかの形でプログラミングは続けていくと思いますので、引き続きどこかで見かけたらその時はまたよろしくお願いします。

JavaScriptのthisとは

ふと

JavaScript使ってきてるわりにthisのコンテキストが変わることについて、あんまり理解できてないなーと思ったのでMDN読みながらまとめる

developer.mozilla.org

thisとは?

JavaScriptでは式の1つで、関数の実行コンテキストを参照するものである
だが、呼び出し方やアロー関数などでもコンテキストが変わるのでややこしくなっている

use strictとそれ以外でまず異なる

  • use strict (厳格)モード
    • どのような値でも取り得る
  • 非厳格モード
    • 実行コンテキスト(グローバル、関数、eval)のプロパティで常にオブジェクトへの参照である

グローバルコンテキストの場合

グローバルコンテキスト(トップレベル)ではthisはグローバルオブジェクトを参照する

console.log(this === window); // true

関数コンテキスト

関数内のthisは関数の呼び出され方と厳格モードの有無によって異なる

非厳格モード

呼び出し時にthisの値が設定されない場合規定のグローバルオブジェクトとなる

function func() {
  return this;
}

func() === window; // true

厳格モード

呼び出し時にthisの値が設定されていない、つまり関数がオブジェクトに属していない形で呼び出されるとundefinedのままになる

function func2() {
  'use strict';
  return this;
}

console.log(func2() === window); // false
console.log(func2() === undefined); // true

関数の呼び出し時にthisの値を特定の値に設定したい場合にはcallやapplyを使用して呼び出す

function func3() {
  'use strict';
  return this;
}

console.log(func3.call(window) === window); // true
console.log(func3.apply(window) === window); // true

また、bindで永続的に設定した関数を生成できる

const newFunc = func3.bind(window);
console.log(newFunc() === window); // true

Arrow Functionの場合

Arrow Functionの場合のthisは実行時ではなく関数の定義時に決まる
そのthisは自身の外側のスコープに定義されたもっとも近い関数のthisの値を指す
注意点としてArrow Functionはcall, apply, bindでthisを設定することはできない

const arrowFn = () => {
  // この時外側には関数は存在しないためトップレベルのthis、つまりwindowを指す
  return this;
};

console.log(arrowFn() === window); // true
console.log(arrowFn.call({ a: 1 })); // Window {...}

クラスコンテキスト

基本クラスの場合thisはそのクラスを指す また、クラス内の非staticなメソッドはthisのプロトタイプに追加される

class Foo {
  constructor() {
    console.log(this); // Foo {}
    const proto = Object.getPrototypeOf(this);
    console.log(Object.getOwnPropertyNames(proto)); // ['constructor', 'bar']
  }
  bar() {}
  static hoge() {}
}

new Foo();

子孫クラス

継承先の子孫クラスではthisバインディングはなく、super()を呼び出すとコンストラクタ内にthisバインディングが作成される
このthisはsuperを呼び出したクラス自身を指す

class Base {
  base() {}
}
class Child extends Base {
  constructor() {
    super();
    console.log(this); // Child
  }
}
new Child();

オブジェクトのメソッドの場合

オブジェクトのメソッドとして呼び出されるときはthisはメソッドの所属オブジェクトになる

const obj = {
  count: 10,
  currentCount: function() {
    return this.count;
  }
};

console.log(obj.currentCount()); // 10

まとめ

  • 基本的にはthisは呼び出し時の所属オブジェクトを指す
  • Arrow Functionのthisは呼び出し時ではなく定義時の外側のスコープに定義されたもっとも近い関数のthisを指す
  • 関数コンテキストでは厳格モードと非厳格でthisが異なる

JavaScript Primerにもコールバックなどさらに詳しい情報が載っているのでこちらも読んでみようと思います jsprimer.net

npmからyarn(v1)に移行する方法

最近仕事で、古めのサービスでnpmからyarn(v1)に移行する機会があったが、結構簡単だったので備忘録がてら残しておく   基本的には以下公式のマイグレーションガイドに沿えば移行できる

Migrating from npm | Yarn

やることは一つで、package-lock.jsonがあるディレクトリ直下で

yarn import

を実行するだけ

これにより、package-lock.jsonをベースにyarn.lockを自動生成してくれる
最後に rm package-lock.json をしてyarn.lockだけを残せば基本的にはOK
後はCIやnpm scripts内でnpmを使っている箇所をyarnに置き換えるだけだった。

自分がnpm scriptsを使う理由

普段よく使っていますが、改めて自分がなぜ好んで使うのか自分の備忘的な意味も込めて書いておきます

概要

package.json の scripts プロパティに定義しているスクリプトをnpm scriptsと呼びます docs.npmjs.com

例えば以下のようにpackage.jsonに書いている場合は

{
  "name": "npm-scripts-sample",
  "version": "1.0.0",
  "scripts": {
    "build": "webpack",
    "start": "webpack-dev-server --open"
  }
  ...
}

コマンドラインで以下のようにスクリプトを実行できます

$ npm run build

# yarn の場合
# run は省略可能
$ yarn (run) build

# 実行結果
# yarn run v1.22.4
# $ webpack
# Hash: 26a04d64a2da6e6f2c09
# Version: webpack 4.43.0
# Time: 2846ms...

メリット

  • cli をグローバルにインストールする必要がない
    • 開発環境だけでなく、Dockerfile、CIなどでも
  • node_modules にインストールされているライブラリを使うので、個々人でのバージョンの差異が出ない
  • gulp などタスクランナーを導入しなくてもよい
  • 長いコマンドでも簡潔なエイリアスを使って npm or yarn で実行できる

デメリット

  • 複雑なタスクはやりづらい

基本的には npm scripts で事足りる印象ですが、複雑なタスク実行などは gulp 等で補ってもよさそうです

個人的には先程挙げた以下のメリットを強く感じるので、npm scripts を活用しています

  • cliをグローバルにインストールする必要がない
  • node_modulesにインストールされているライブラリを使うので、個々人でのバージョンの差異が出ない

参考

npm scriptsの活用方法などはこちらがわかりやすいと思います ics.media

今さらだけどCircleCI2.1について学んだよ

CircleCI2.1について業務でまとめたので、載せておく

そもそもCircleCIとは

そもそもCI/CDとは

  • CI: 継続的インテグレーション
    • ビルド、テストまでを自動化して、小さなサイクルで繰り返すことで、統合されたソフトウェアを迅速に開発する
  • CD: 継続的デリバリー
    • CIを含めたリリースプロセス全体の自動化を行い、素早くソフトウェアに反映し、ユーザーに価値を届ける

CircleCI用語

参考: https://circleci.com/docs/ja/2.0/concepts/#section=getting-started

  • プロジェクト
  • ステップ
    • ジョブを実行するために行うアクション。基本はコマンドの集まり
  • イメージ
    • 実行コンテナを作成するためのパッケージ
    • CircleCIが提供しているimageリスト
  • ジョブ
    • ステップの集まり
    • ジョブにはExecutor(実行環境)を宣言する必要あり
  • キャッシュ
    • ビルドを高速化するために依存関係やソースをキャッシュできる
  • ワークフロー
    • ジョブのリストと実行順序。ジョブを並列/順次/スケジュール/承認ジョブでの手動での実行 など実行方法を設定できる
  • ワークスペース
    • ワークフローに対応したストレージ
    • ジョブ固有のデータを保存して、同じワークフロー内の他のjobで使えるようにしている
  • アーティファクト
    • ワークフローが完了した後もデータを維持するストレージ  

CircleCI2.1に乗り換えたい場合

  • config.ymlのversion指定を2.1にするだけ
version: 2.1

CircleCI2.1の新機能

参考・引用: https://discuss.circleci.com/t/circleci-2-1-config-overview/26057

commands

  • 一連のstepをcommandとして定義できる
  • jobのstepで利用する
version: 2.1

commands:
  my-command:
    steps:
      - run: echo "a command is a collection of steps"
      - run: echo "this command has two steps"

jobs:
  my-job:
    steps:
      - my-command

executors

executorに指定する実行環境を定義しておける

version: 2.1

executors:
  my-executor:
    docker:
      - image: python
  my-other-executor:
    docker:
      - image: ruby

jobs:
  my-job:
    executor: my-executor
    steps:
      - run: echo "i'm using my-executor"
  my-job2:
    executor: my-other-executor
    steps:
      - run: echo "i'm using my-other-executor"

parameters

  • commands、executors、jobsで使えるパラメータを定義する。使える型は以下
    • string
    • boolean
    • steps
    • enum
  • << parameters.param-name >> で展開する
commands:
  copy-markdown:
    parameters:
      destination:
        description: destination directory
        type: string
        default: docs
    steps:
      - cp *.md << parameters.destination >>

orbs

  • jobs, executors, commandsなどをまとめる
  • orbはパッケージとして公開されているので、インポートして利用できる https://circleci.com/orbs/registry/
orbs:
  codecov: circleci/codecov-clojure@0.0.4
  my-orb:
    executors:
      default:
        docker:
          - image: circleci/ruby:1.4.2
    commands:
      dospecialthings:
        steps:
          - run: echo "We will now do special things"
    jobs:
      myjob:
        executor: default
        steps:
          - dospecialthings
          - codecov/upload:
              path: ~/tmp/results.xml

workflows:
  main:
    jobs:
      - my-orb/myjob

conditional steps

when と unless という条件分岐のためのkeyが追加

jobs:
  myjob:
    parameters:
      preinstall-foo:
        type: boolean
        default: false
    machine: true
    steps:
      - run: echo "preinstall is << parameters.preinstall-foo >>"
      - when:
          condition: << parameters.preinstall-foo >>
          steps:
            - run: echo "preinstall"
      - unless:
          condition: << parameters.preinstall-foo >>
          steps:
            - run: echo "don't preinstall"

pre-steps and post-steps

名前の通りで、jobの前後に実行するstepを定義できる

version: 2.1

orbs:
  foo: somenamespace/foo@1.2
workflows:
  build:
    jobs:
      - foo/bar:
          pre-steps:
            - run:
                command: echo "install custom dependency"
          post-steps:
            - run:
                command: echo "upload artifact to s3"

所感

  • DRYにまとめられる機能が増えてconfigの見通しが良くなった
  • orbsによって、Slack連携やパブリッククラウドへのデプロイなどがやりやすくなった、GitHubActions感

2019年の振り返りと2020年やっていき

2020年、今年はとうとう東京オリンピックですね。

年が明けてから結構経ってますが去年は転職やプライベートでは結婚など色々あったので、簡単に振り返っていこうかと思います。

 

2019年こんなことあったな

ライフイベント

  • 転職

詳しくはこちらの記事に書いています。

転職前は色々と不安でしたが、改めて転職を踏み切ってよかったなと思っています。

flyhighupair.hatenablog.com

 

  • 結婚

2019年の後半に入籍と結婚式を行いました。

一つ言えるのは転職と同時にやるのはオススメできません。

自分の場合はどちらも思い立った時期が同じだったので、並行で進めることになりましたが、結婚式の準備と転職活動・転職先に慣れるのを同時にやるのはかなり大変でした。

新婚旅行は今年行く予定です。

 

初めて触ってみた・より深めた技術

言語

フレームワーク・ライブラリ

インフラ

  • AWS
  • Terraform

2019年は図らずも気になっていたRubyを前職の業務で触ることになりました。

さらに転職によって、サーバーサイドはRuby on Rails、フロントエンドはAngularでの開発が基本になりました。

少しずつ慣れてきてはいますがまだまだなので、今年はチョットワカルを目指していきたいです。

 

2020年やっていき 

今年は以下を目標にやっていこうと思っています。

エンジニア面

  • OSSにコントリビュートする
  • 2週に一回ブログかQiitaでアウトプットする
  • 毎月本を読む
  • 外部勉強会でLTする

 プライベート面

  • 舞台やライブに行くなど趣味も充実させる
  • 投資信託などの資産運用方針を明確にして、運用する(今まで何となくでやっていたので)
  • 新婚旅行に行って楽しむ

少しずつ取り組んで、今年も充実した年にしていきたいです。

今年も頑張っていくぞ!

初めての転職~夢の新天地へ~

退職者アドベントカレンダー21日目です。

adventar.org

新卒から2年半勤めた会社を8月に退職し、9月に今の会社に転職して3ヶ月が経過しました。(試用期間も明けた!)

転職に至った理由と、転職してからを振り返ります。

 

自己紹介

現在社会人3年目のWebエンジニアです。フルスタック気味です。

大学時代は教育学部で小学校教員になるため、4年生の段階で教員採用試験まで受験しましたが、教育実習などで触れたICTからこの世界に興味を持ち、未経験ながら飛び込んで、現在働いています。

 

転職を考えた理由

前職では、受託開発の会社で未経験ながら、色々と教わりながら、実践を積んできました。

開発言語についても、担当領域についてもお客さんにヒアリングやデモを行うところから画面デザイン・もちろん実装・テスト・ユーザーインタビューなど幅広くやらせていただきました。

 

ですが、受託開発はどうしても、案件ごとに求められる技術が異なり、器用貧乏になってしまうと感じたこと、数ヶ月〜1年程度で、関わったサービス・アプリから離れてしまうので、モチベーションの低下や感じた改善点を活かせないところがネックに感じていました。

また、関わっていた事業ドメインに興味を持てなかったこともあり、自分が大学で学んだ学校教育をターゲットとした自社サービスに関わりたいと思い、転職活動を始めました。

 

転職活動

新卒の就職活動はほぼ教員採用試験一本に絞っており、ろくに自己分析もしていなかったため、以下の本を参考に自分の目指すところや将来どうなっていきたいかを書き出しました。

www.amazon.co.jp

 

その後は、Twitterなどで広告を見かけることが多かった転職ドラフトに登録しました。

job-draft.jp

どうにか審査も通り、いざドラフトに入ったところ、その当時の年収の倍近い提示額でのオファーが来ました。こういったものは多少オファー金額がつり上がるとは思っていましたが、世間から見た自分の市場価値というのはこんな感じなのかと思いました。

そこで改めて転職意欲が高まりました。

 

追加でWantedlyにも登録し、2019年の3月ごろから本格的に転職活動を始めました。

気になったいくつかのEdTech事業やB to Cの会社にカジュアル面談を申し込み、面談・選考を受けていきました。

いくつかの企業のコーディング課題や面接などを受けて、改めて自分の現在の力量などを実感しました。

 

転職のために使ったサービスや行った勉強など

履歴書や職務経歴書はProffというサービスで作成しました。

学生の頃は手書きが当たり前だと思っていましたが、こちらで1回作成しておけば、修正も簡単ですし、PDFでダウンロードして、メール送付できるので、便利でした。

proff.io

 

エンジニアっぽさを出したいと思い、職務経歴書は以下の記事を参考にGitHubでも管理しています。

qiita.com

github.com

 

また、コーディング課題なども多かったので、プログラミングの基礎力を底上げしようと思い、競プロのようなアルゴリズム問題を解くサイトにも取り組みました。

www.codewars.com

atcoder.jp

 

その他、技術書典で出ていた完全SIer脱出マニュアルも転職にあたり、参考にしました。

jumpei-ikegami.hatenablog.com

 

面接対策

技術面接については以下の記事などを参考に回答を考えました。

blog.maximum80.me

paiza.hatenablog.com

 

毎回の転職面接で聞かれたことや質問したことはEvernoteにまとめて、振り返ることができるようにしていました。

以前話題になったブラウザの仕組みなども実際技術面接で聞かれたので、まとめておくのは大切だと思います。

 

他に面接でうまくいかないときのモチベーション管理として、知っている方も多いと思いますが、Podcastでしがないラジオを聞いていました。

実際転職してどうか、転職の時どんなことがあったかなどを聞いて、自分の参考にしていました。

shiganai.org

 

転職での資格の価値

よく資格を取った方がいいなどと言われています。

自分は、前職の会社の教育方針もあってか、応用情報技術者を始め、色々資格を取得していました。(資格勉強が仕事に結びつく面白さもありました)

資格取得は賛否両論あるとは思いますが、実際資格の多さから面接などで興味を持ってもらえることも多く、自分にとってはプラスに働いたと思いました。

 

退職にあたって

無事6月頃にどうにかご縁があって、今の会社に内定が決まりました。念願のEdTech事業を自社開発で行っている会社です。

当然転職の意思を固めたら、退職の手続きを踏むのですが、初めての転職なので、退職を上司に伝える時には凄く緊張しました。

幸い揉めることも無く、引き継ぎのスケジュールなどを決め、退職できました。

ただ、引き継ぎに追われ、有給を消化しきれなかったのは心残りではあります。

 

転職してみて

なんだかんだ前職の最終出社日にはいい会社だったと改めて感じ、新天地へ向かう不安からもわざわざ転職に踏み切らなくてもよかったのではと思いました。

ですが、今の会社は面接でも感じた通りに居心地が良く、周りの方の技術力も高く、楽しく働いています。

 

最後に

転職しようかどうか悩んでおり、行動をまだ起こせていない方も多いと思います。

ですが、迷っている方こそ、カジュアル面談などで自分の経歴ややりたいことを言語化することで自分を見つめ直す機会になると思います。

ぜひ一歩進んでみてください。今とは違う何かがそこには待っています。