ボクダイモリ

Life is like a Game

2018年の振り返り、来年の抱負

今日で2018年も終わりですね。今年の出来事を思い返してみると長かったような短かったような、仕事もプライベートも程々に挑戦していたと思いますが全体的にはのんびり生きていたような気がします。 一番大きなイベントと言えば転職で 去年の11月に新卒で入社した会社を辞めて今年1月からWeb系の会社に就職しました。もうそろそろ1年経ちましたが自分のやりたいと思ってたことはだいたい出来ていて社風も合っていたのでなんとか社会人としてやれています。今はなんとか社会人っぽく生きてはいますが最近は深夜まで何かに集中していた方が幸福度が高まるということを実感してからどんどん生活がだらしなくなっていくのを感じています。実に幸せです。反省はしていない。

今回は今年の振り返りについて書きますが特に書きたいこととかあまりないのでさらっと書きます。

Golang

業務で書く機会もあったしプライベートでも好きで書いてたり。 書いたコードは適当にgithubに上げている。

https://github.com/anraku/TodoList

https://github.com/anraku/tsk

https://github.com/anraku/chat

Goは読みやすいし書き方もシンプルになるのがいいですね。
上にClean Architectureで実装したものがあるのでいずれ学んだこととか解説とか書くかもしれない。

趣味

バイオリン

最近バイオリンを趣味で始めた。今までほとんど楽器や音楽に触れてこなかったので楽器何かやりたいなーとなんとなく思ってたので。 なぜバイオリンなのかというとただ単に弾くまでの準備が簡単そうでいつでも弾けそうだったから。自分はメンドくさがりなのでセッティングが煩雑だったりするとまず続かないと思っている。バイオリンは調弦したらすぐ弾けると思ってた。 あとは自宅の近くにバイオリンの教室があったため。一人で楽器を始めるのは難易度高いと思ってたのでありがたかった。 バイオリンの音は好きだけどそこまでバイオリンに思い入れはない。もし自宅の近くのウクレレの先生がいたらたぶんウクレレ弾いてたと思う。 実際バイオリンをやってみると思った通り準備は簡単だった。ただ意外と音が大きいので騒音に気をつける必要がある。
バイオリン初めてもう5ヶ月くらいになるけども毎週先生の元で練習したり小さな発表会に参加したりなんだかんだで続いている。いつ飽きるか分からないけどもこれからも続けていく。

ゲーム

スプラトゥーンとスマブラやってます。楽しい!

読んだ本

今年もいくつか技術書を読んだので良かった本を取りあげてみる。

  • エンジニアの知的生産術

Amazon CAPTCHA

内容としてはKJ法などの知的生産のためのツールを使うための具体的な方法だけでなく、人の記憶の仕組みなどに基づいて効率的な記憶の仕方などに渡ります。学び方のコツなどを知りたいという方にはオススメ。 題名は「エンジニアの」とついているけどもエンジニアではない人も十分に役に立つと思われる。

  • エンジニアリング組織論への招待

Amazon CAPTCHA

組織論、マネジメントについての本で「エンジニアリング」することについて個人やチーム、企業というそれぞれの単位で考察されている。 エンジニアリングにおける課題を解決するための思考法やメンタリング手法、プロジェクト管理手法などを学ぶことができる。 内容としては技術書というよりはマネジメントの本だと思われるが組織に属する方であれば読むと参考になることが多いはず。

  • Clean Architecture

Amazon CAPTCHA

ソフトウェア設計について分野全体を俯瞰しながらSOLID原則やデザインパターン、オブジェクト思考について学ぶことができる。 自分はクリーンアーキテクチャについて学びたくてこの本を取ったが、上記の事も合わせて広く学べたので読んで良かった。

おわりに

このブログ見返してみるとあんまり振り返れてない気がする。まぁいいか。 来年の抱負は彼女を作ることです。

それでは来年もよろしくお願いいたします。よいお年を。

【Rails5】ユーザパスワード更新の実装パターンまとめ

こんばんは

最近業務でRailsを使った社内用のアプリケーション開発を行なっていたのでそれについて何か書いてみます。

アプリケーションにユーザ管理機能を実装する際は、deviseというrubyのgemを使うことで簡単にユーザ管理に必要な機能を実装できます。 ユーザ情報への入力パラメータに対してバリデーションなどを簡単に実現できますが、独自に実装を加えたりする必要も場合によってはあります。 今回はdeviseを使ったユーザ管理を実装していく中で学んだこと、特にパスワードの更新周りで調べた点をまとめてみます。

rubyと各gemのバージョン

  • ruby 2.5.1p57
  • rails (5.2.1.1)
  • devise (4.5.0)

パスワード更新のパターン

  • ユーザ更新時にパスワードを更新しない
  • ユーザ更新時に特定の条件でパスワードの検証をしない
  • ユーザ更新時にパスワードフォームの値が空でない場合にパスワードを更新する

ユーザ更新時にパスワードを更新しない

ユーザ更新時にパスワードを更新したくない場合、strong parameterに:passwordを含めない方法が簡単です。

params(:user).permit(:first_name, :last_name, :address)

上記は独自のコントローラー内でupdateを行う場合になりますが、Devise::RegistrationsControllerを実装したコントローラーに実装する場合は下記のようになります。 update_resourceをoverrideして中でupdate_resourceをresource.update_without_passwordを呼ぶように実装を変更します。

# app/controllers/registrations_controller.rb
class RegistrationsController < Devise::RegistrationsController

  protected

  def update_resource(resource, params)
    resource.update_without_password(params)
  end
end

ユーザ更新時に特定の条件でパスワードの検証をしない

deviseのvalidatableを実装することでupdate時にパスワードの検証を行うことができます。

class User < ApplicationRecord
    devise :validatable
end

validatableのパスワード検証のロジックはpassword_required内で定義されています。

      def password_required?
        !persisted? || !password.nil? || !password_confirmation.nil?
      end

このメソッドをoverrideすることで任意の条件でパスワード検証を行うことができます。

      def password_required?
          if do_validate # パスワード検証を行う条件
              !persisted? || !password.nil? || !password_confirmation.nil?
          else
              false
          end
      end

ユーザ更新時にパスワードの値が空だった場合、パスワードを更新しない

これは同僚から聞いて知ったのですが、controller内で参照できるparamsに含まれるパラメータは全てvalidationの対象となるようです。 なのでupdateメソッド内にパスワードが空だった場合、userをupdateする前にparams[:user].delete(:password)を実行することで validationを回避することができます。

  def update
    if params[:user][:password].blank?
      params[:user].delete("password")
    end
    if @user.update(user_params)
  end

おわりに

それぞれ簡単にですがdevise利用を踏まえてのパスワード更新周りについてまとめました。 deviseは便利な機能が多いので使う場合はどんな機能があるのかをざっと確認しておくと良いです。 機能の全体像を把握する上で下記の記事が参考になりました。

[*Rails*] deviseの使い方(rails5版) - Qiita

参考リンク

How To: Allow users to edit their account without providing a password · plataformatec/devise Wiki · GitHub

easyramble.com

yoshitsugufujii.github.io

rails: devise update user without password - CODE Q&A Solved

[*Rails*] deviseの使い方(rails5版) - Qiita

awkのprintでピリオドを出力したいが出来なかった

追記

結論、できた。ピリオドをダブルクォテーションで括ればよかったようです。

echo "1.2.3" | awk -F. '{print $1"."$2"."($3 + 1)}'

問題

下のようにawkのprintを使って演算した結果をピリオド付きで出力をしたかったが出来なかった

$ cat awk_test.sh
#!/bin/bash
echo "1.2.3" | awk -F. '{print $1.$2.($3 + 1)}'

$ sh awk_test.sh
124

\でピリオドをエスケープすればできる?と思ったけどもsyntax errorが出てしまう。

解決策

最初に加工した結果をスペース区切りで出力させて、そのあとsedでピリオドに置き換えた

$ cat awk_test.sh
#!/bin/bash
echo "1.2.3" | awk -F. '{print $1,$2,($3 + 1)}' | sed 's/ /./g'

$ sh awk_test.sh
1.2.4

Vue.js + Golangでタスクリスト作ってみた

Vue.jsとgolangを使って何か作ってみたかったので試しにタスクリストを作ってみました。

github.com

Vue.jsの書き方やgolangAPI実装はmattnさんのブログを大いに参考にさせて頂きました。

mattn.kaoriya.net

見た目はこんな感じです。

f:id:anrakusan:20180625070806p:plain

WebアプリケーションフレームワークはEcho、ORMにgormを利用しています。 また、Dockerの勉強も兼ねてフロントエンドとバックエンドの環境を立ち上げられるよう設定ファイルも書いてみました。

バージョン確認

$ go version
go version go1.10 darwin/amd64

$ node -v
v9.8.0

$ npm -v
5.8.0

なお、環境構築の手順は割愛します。

フロントエンドの実装

タスクリストの機能は次の通りです。 - タスクの一覧表示 - タスク作成 - タスクの完了、及び残タスクに戻す

上記の処理はsrc/components/Todo.vueにあります。 下のコードはjsが動く部分です。

<script>
import axios from 'axios'
export default {
  name: 'Todo',
  data () {
    return {
      newTask: '',
      todos: []
    }
  },
  created: function () {
    axios.get('http://localhost:1323/tasks')
      .then((response) => {
        console.log(response)
        this.todos = response.data.items || []
      })
      .catch((error) => {
        console.log(error)
      })
  },
  methods: {
    addTask: function (todo) {
      let params = new URLSearchParams()
      params.append('text', this.newTask)
      params.append('done', false)
      axios.post('http://localhost:1323/tasks', params)
        .then((response) => {
          this.todos.unshift(response.data)
          this.newTask = ''
        })
        .catch((error) => {
          console.log(error)
        })
    },
    updateTask: function (todo) {
      let params = new URLSearchParams()
      params.append('done', !todo.done)
      axios.put('http://localhost:1323/tasks/' + todo.id, params)
        .then((response) => {
          todo.done = !todo.done
          console.log(response)
        })
        .catch((error) => {
          console.log(error)
        })
    }
  }
}
</script>

created()はページをロードした時だけ実行されます。

また、データのやり取りはすべてAjaxAPIを実行して結果を取得するようにしています。

axios使いやすいです。

バックエンドの実装

バックエンドのAPIGolang + Echo + Gormで実装しています。

ミドルウェアやルーティングの設定はmain.goでして実処理はhandler.goに書いてます。

model/にはタスクのデータ定義やデータアクセスの処理を定義していて、ビジネスロジックは書かずシンプルにしています。

func (m *Model) FindAll() (tasks []model.Task, err error) {
    err = m.DB.Table(table).Find(&tasks).Error
    return
}

func (m *Model) Create(task model.Task) (t model.Task, err error) {
    t = task
    err = m.DB.Table(table).Create(&t).Error
    return
}

func (m *Model) Update(task model.Task) (t model.Task, err error) {
    t = task
    err = m.DB.Table(table).Where("id = ?", task.ID).Update("done", task.Done).Error
    return
}

実際のデータベース接続処理とも切り離していて、接続処理はdatabase/に定義しています。

func Connect() (*gorm.DB, error) {
    db, err := gorm.Open("mysql", "root:password@tcp(mysql:3306)/app?charset=utf8&parseTime=True&loc=Local")
    if err != nil {
        return nil, err
    }
    return db, nil
}

また、tasksのテーブル定義はinfra/mysql/sqls/1_init.sqlに記載してます。

環境構築

今回紹介したアプリはなるべくdocker-composeで再現できるようにしていますが、APIのビルドは事前に実行する必要があります。本当はそこもMakefile使う等で自動化したい。。

cd TodoList/backend/service
GOOS=linux go build -o api main.go handler.go

基本必要な記述はできるだけ個々のDockerfileではなくdocker-compose.ymlに寄せてます。

version: '2'
services:
  web:
    container_name: 'web'
    build:
      context: ../front/
      dockerfile: Dockerfile
    volumes:
      - ../front:/app
    networks:
      - front
    ports:
      - 8080:8080

  api:
    container_name: 'api'
    build:
      context: ../backend/service/
      dockerfile: Dockerfile
    networks:
      - front
      - datastore
    ports:
      - 1323:1323

  mysql:
    container_name: 'db'
    build:
      context: ./mysql/
      dockerfile: Dockerfile
    volumes:
      - ./mysql/mysql_data:/var/lib/mysql # データの永続化
      - ./mysql/sqls:/docker-entrypoint-initdb.d # 初期データ投入
    environment:
      - MYSQL_ROOT_PASSWORD=password #rootパスワードの設定
    networks:
      - datastore
    ports:
      - 3306:3306

networks:
    front:
    datastore:

webのDockerコンテナは起動時にnpm installとnpm runしてます。 apiコンテナは事前にlinux用にビルドされたバイナリを配置して起動しているだけです。 DBのテーブル定義などはコンテナ構築時に初期データを読み込むようにしています。

      - ./mysql/sqls:/docker-entrypoint-initdb.d # 初期データ投入

感想

なんだかんだで今回一番時間かかったのはdockerを使った環境構築。。。

Vue.jsを使ってみたくてアプリを作ってみましたが、ファイル分割しやすいしstyleとhtmlとjsをコンポーネント毎に分けられるので処理を理解しやすい。axiosなどの使いやすいライブラリもあるので開発するならVue.jsでいい感じ。レイアウトのデザインを作るためのライブラリも充実していてElementやVuetifyがあります。Vuetifyは簡単にマテリアルデザインが作れる感じなので使ってみたい。

【Flutter入門】Flutterでメモ帳アプリ作ってみた

そろそろ何かアプリを作ってみたいと思ったので簡単にマルチプラットフォームなアプリを作れるFlutterというフレームワークを触ってみました。 今回は勉強の一環として作成した簡単なメモ帳アプリを公開、解説します。 作成したアプリはGithubにアップしています。

github.com

コードの解説の前にFlutterについてですが、Flutterとはハイブリットアプリを開発するためのフレームワークDartという言語で実装されています。 Flutterの公式にも書いてありますが簡単にMaterial UIを持ったネイティブアプリを開発することができます。 flutter.io

書いててとても便利だったのがホットリロード機能で、コード修正→UI確認が秒速で完了します。

実際にアプリ開発に入る前に公式のチュートリアルは一度やってみた方がいいでしょう。 flutter.io

なお、アプリ開発のための環境構築方法については割愛します。

アプリの機能

今回実装したアプリの機能は次の通りです。

  • メモの一覧表示

  • メモの新規作成

  • メモの編集

  • メモの削除

main.dart(Home画面)

アプリのホーム画面でメモの一覧を表示させています。

アプリの全体はmain.dartに記述されており、下記のように定義しています。

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Note App',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new Home(title: 'Note List'),
    );
  }
}

class Home extends StatefulWidget {
  Home({Key key, this.title}) : super(key: key);
  final String title;

  @override
  _HomeState createState() => new _HomeState();
}

アプリののタイトルと_HomeStateというWidgetを定義しています。 このWidgetはStatefulでメモ帳のデータを持たせています。

class _HomeState extends State<Home> {
  List<Memo> memos = new List<Memo>();

...

Home画面のUIは次のコードで定義されています。

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text(widget.title),
      ),
      body: _list(),
      floatingActionButton: new FloatingActionButton(
        tooltip: 'add note',
        child: new Icon(Icons.add),
        onPressed: () {
          Memo newMemo = new Memo('','');
          memos.add(newMemo);
          Navigator.push(context, new MaterialPageRoute<Null>(
              settings: const RouteSettings(name: "/create"),
              builder: (BuildContext context) => new Create(newMemo)
          ));
        }
      ),
    );
  }

ScaffoldというクラスでUIを構成する各コンポーネントを定義します。 それぞれのコンポーネントについて説明します。

  • appBar

アプリのナビゲーションバーに表示するタイトルです。

  • body

Home画面に表示するコンポーネントの本体。_list()でメモ帳の一覧を表示するためのリストが返されます。

  • floatingActionButton

右下に丸いボタンを出すことができます。押すとメモ帳の新規作成画面に遷移します。

        onPressed: () {
          Memo newMemo = new Memo('','');
          memos.add(newMemo);
          Navigator.push(context, new MaterialPageRoute<Null>(
              settings: const RouteSettings(name: "/create"),
              builder: (BuildContext context) => new Create(newMemo)
          ));

Navigator.pushで遷移先を指定します。また、遷移する際に新しいメモデータを配列に追加しています。 また、メモ帳のデータはMemo型を自作して配列にして保存するようにしています。 Memo型はentity/memo.dartで定義しています。

そしてメモ帳のリストを作成している箇所が次の通り。

  Widget _list() {
    return new ListView.builder(
        padding: const EdgeInsets.all(16.0),
        itemCount: memos.length,
        itemBuilder: (context, i) {
          final item = memos[i];
          return new Dismissible(
            key: new Key(item.title),
            onDismissed: (direction) {
              memos.removeAt(i);

              Scaffold.of(context).showSnackBar(
                  new SnackBar(content: new Text("Memo dismissed")));
            },
            // Show a red background as the item is swiped away
            background: new Container(color: Colors.red),
            child: new ListTile(
              title: new Text(
                item.title,
                maxLines: 1,
                style: _biggerFont,
              ),
              onTap: () {
                Navigator.push(context, new MaterialPageRoute<Null>(
                    settings: const RouteSettings(name: "/detail"),
                    builder: (BuildContext context) => new Detail(item)
                ));
              },
            ),
          );
        },
    );
  }

ListView.builderを使ってメモ帳のデータをListViewに表示させています。

メモ帳の要素を元にListTileを一つずつ作っています。

ListView内のListTileをタップしたらメモ帳の編集が行えるようにしたいのでonTapというイベントハンドラーを定義して、 押された時に編集画面に遷移するようにしてます。

また、親要素にDismissibleクラスを定義していますがこれはListViewのTileにスワイプ→削除のようなモーションを実装するのに必要になります。onDismissedがメモ帳削除のイベントハンドラーです。

create.dart(メモ帳の新規作成)

前述したメモ帳の新規作成画面はHome画面の右下に出てくる丸いボタンを押すと遷移します。 新規作成画面にはテキストフィールドとボタンを置いています。

@override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('Create new note'),
      ),
      body: new ListView(children: <Widget>[
        new TextField(
            decoration: new InputDecoration(
                hintText:"Write title."
            ),
            controller: new TextEditingController(text: _memo.title),
            onChanged: (String newTitle) {
              _memo.title = newTitle;
            }
        ),
        new TextField(
            maxLines: 10,
            decoration: new InputDecoration(
                hintText:"Write memo."
            ),
            controller: new TextEditingController(text: _memo.body),
            onChanged: (String newBody) {
              _memo.body = newBody;
            }
        ),
        Center(
          child: new Container(
            margin: const EdgeInsets.all(10.0),
            height: 75.0,
            width: 150.0,

            child: new FlatButton(
              child: new Text('save memo'),
              color: Colors.lightBlue,
              textColor: Colors.white,
              onPressed: () {
                Navigator.pop(context);
              }
            )
          )
        )
      ])
    );
  }

2つのテキストフィールドはonChangedを実装していて、変更を行ったタイミングでメモ帳の内容を上書きしています。 また、ボタンを押した時のイベントは単に元の画面(Home画面)に戻っているだけです。

detail.dart(メモ帳の編集)

メモ帳の詳細画面は新規作成とほとんど変わらないです。Home画面に戻るためのボタンがないだけ。

メモ帳の削除

メモ帳の削除については前述した通り、main.dartでonDismissedというイベントハンドラーで実装しています。

            onDismissed: (direction) {
              memos.removeAt(i);

              Scaffold.of(context).showSnackBar(
                  new SnackBar(content: new Text("Memo dismissed")));
            },

ListTileをスワイプすると対応するインデックスのメモデータを削除しています。 UIも削除後に自動的に再描画されます。

この勝手に再描画してくれる点がとても楽。これが正しいやり方なのかは分からないけども。

実装してみての感想

公式ドキュメントも分かりやすく情報は十分にあるので問題なく実戦で使えると思う。 文法的な部分ではアプリのUI構造を宣言的に書けるのでその分構造を組みやすいと感じるが、階層が深くなると一覧性を損なってしまう点を強く感じた。

Widgetの記述ををメソッドやクラスを使って階層を減らすように工夫が必要そうだが、別Widgetの変数をどう参照するかとかも考えないといけない。

UIの再描画を伴うデータの更新はStatefulなWidgetがSetState()の中で行うのが正しいと思われるので、今回のようなデータのポインタを渡した先で値変更、というようなやり方は良くないのかもしれない。

このWidget同士でのデータの扱い方とかStatefulとStatelessのWidgetの使い分けは良く分かっていないので後で調べてみる。

ともあれ、やはり開発時のホットリロードはサクサク開発を進められるのですごく気持ちいいので今後もFlutterは触ってると思う。

2018年の抱負

明けましておめでとうございます。今年もよろしくお願いします。
 
昨年は印象深いイベントがいくつかあったり、世の中の先端技術の知見を浅く広く学べた年で新鮮な体験が多かったです。
とりあえず今年の振り返りと反省をKPT使ってやっていきます。

Keep

分野を問わず情報をキャッチアップし続ける
最近思ったのがアイデアを考え出すセンスとか物事の違和感に気づける洞察力というのは、今まで蓄積した知識量に依るところが多いなということ。
現に一昨年までは新しい発想を生み出すのが苦手だったのですが、流行りのサービスをよく使うようにしたりニュースアプリやSNSなどから情報収集をよくするようになってから発想するアイデアの量が大きく増えました。
他にも常に広い範囲にアンテナを張っておくことは、今後自分のどの能力に投資すればよいかの判断材料を得るのに役立ちます。自分の市場価値を高めていくために如何にして学習する分野を選択し、その分野を極めていけるかがエンジニアとして大事なことだと考えています。
 
幅広く技術要素を習得していく
去年に学んだ技術はだいたいこんな感じ
 
フロントエンド系の学習はProgateがとても役に立ちました。初心者から中級者くらいまで参考にできるいいサービスだと思います。
その他にもGolangでチャットサービスを作ってみたり、作ったサービスをサーバにデプロイするためにnginxなどのミドルウェアについても学習できました。ただ、作成したサービスについては納得できるものができていないので、広く技術を学びながら今年またチャレンジしたい。
 
勉強会の開催
会社の同僚とか元同僚の人たちと集まって仕事とかそういうのなしで勉強会とかやれたのは良かった。お互い刺激になると思うしみんなで集まって話すのめっちゃ楽しいので今後も続けていきたい。
ただ、ずっと続けているとマンネリ化してくるのか人気が少しずつなくなっているような気がしている。開催するたびにいつもどうやったら面白くなるかを模索してる感がある。もう少し求心力というか参加して楽しくなるようなコンテンツを用意できたらなーとつくづく感じます。その点は勉強会メンバーと話し合いながら考えよう。
 
運動する
仕事の都合上デスクワークが多いので運動してないと30歳あたりから腰が悪くなりそう。僕の周りで30くらいで腰壊してる人が何人かいるので気をつける:(;゙゚'ω゚'):
ぎっくり腰予防も兼ねて毎週一回テニススクールに通ってるけど最近サボりが多いので反省。

Problem

本あまり読めてない
面白いと思った本は結構買ったけど半分以上積んでしまった。本はだいたい電車で読むこと多いけどここ最近は本よりもニュース見てることの方が多くなってきた。家にいる時も動画をだらだら見てること多くなったなー、特にNetflix超面白い。画質綺麗だしホント他に何も手がつかなくなるのでオススメ。
とはいえ積み本は消化したいので以前のようにしっかり読書の時間を確保したり、インプットすべき情報は厳選する。とりあえず読んで価値があると思ったもの以外は見ないようにする。

Try

Webサービスを公開する
(去年もこんなこと言ってたような…)
毎回何かしら作っては途中でやる気失って放置するの繰り返しになってる気がするのでそろそろ何か公開したい。

おわりに

いきなりですが新年早々モンハンの新作出ますね!めっちゃ楽しみです。
モンハンやる方は一緒にやりましょう。

SIerを辞めてWebサービス系に転職しました

最近色々あったので状況報告がてら更新。
去年の11月末に新卒で入社し2年半ほど勤めていた会社を退職しました。今年1月からはWeb系の会社でお世話になる予定です。

 

前職は良し悪し色々ありましたが、基本的にはゆったり仕事をやらせて貰えたので新卒で入社できて良かったなーと思っています。入社当時、自分のような人間でも就職出来る事実に驚いていたのが懐かしいです。​😅​

 

12月中は無職だったので1週間セブ島に旅行に行ってみたり、1週間で平均15時間くらいゲームに没頭してみたり、コミケに行って写真撮影してみたりと普段出来なそうな事を色々やってました。あと勉強もちょいちょいやってます。
1月からまたエンジニアとして働く予定です。無職生活儚い…

 

転職の理由


将来は事業化目線でサービスを作ったりマーケティングを考えたり出来る人になりたいと考えているので、それが実現出来そうなキャリアプランと仕事内容がマッチしてそうな企業さんで働きたかったというのが大きな理由です。
その為にもエンジニアとしてのスキルアップを目指したかったので、自分のキャリアプランに合った企業さんとご縁を持つ事が出来たのは幸運でした。


個人的にはずっと同じ職場で働く事については少しリスクがあると感じていて、前職に居続けることで図らずとも会社特有の文化に同調し過ぎてしまったり、社外への意識が薄くなってしまうことを危惧してました。それに僕は前職以外の企業で働いた事が無いのでこれからもっと色々な人や環境に出会うべきだと思っているし、今後色々な知見を得ていく上で如何様にも変わっていけると感じているので若い今のうちになるべくチャレンジしていければなと思っています。

転職活動の振り返り


転職活動は11月中旬くらいから始めて12月中旬あたりで内定を頂きました。次の職場決まる前に辞めるっていうと色んな人に驚かれる…計画性が無い​😅​

 

転職活動やってみて思ったのは会社行きながら並行して面接受けたりするのすごく大変だということ。当時は有給を全て使ってしまっていたので会社終わった後に面接行ってました。もう二度とやりません。

 

受けた企業は全部で7社くらい。どれも自社サービス開発をやっている企業です。
面接等を受けて印象に残っているのが質問であまり技術の深掘りをされる事があまりなく、その企業の理念に共感出来るかだとか説明が論理的であるかだとかがよく見られていた様に感じました。年齢が26という事もありもしかしたら第二新卒のように見られていたのかもしれないです。


また、志望させて頂いた企業の殆どが内定をもらうのが難しいとエージェントの方から言われており案の定お見送りが多かったのですが、お見送り理由が総じて「スキル不足」だったのも印象的でした。技術的な質問が殆ど無かったにも関わらずこの様な評価をされていたのも気になる点でした。


後ほど内定先の人事の方に話を聞いてみたところ、経歴的なWeb開発やベンチャー企業での経験がなかった点で技術的に経験不足であると判断されたとの事でした。前職ではWebアプリケーション開発の一次受けや保守運用の仕事が主で、ゼロイチでプロダクトを作った経験やWeb系・ベンチャーでの経験がなかった点で技術的な評価が低かったのだと思います。

まとめ


約1ヶ月と短い転職活動でしたが、自分の目標とスキル的にもいいタイミングで転職が出来たのでとても満足しています。
転職先での仕事内容も自分のやりたい事とマッチしており、契約の条件も良かったので本当に良いご縁を頂けたなと思っています。


ただ転職先からはスキル不足でありつつもポテンシャルに期待、といった評価で採用を頂いているはずなので、その点は自覚を持ちながら今後は上手くやっていきたいです。