猫Rails

ねこー🐈

リーンでアジャイルでモフモフなTwitterBot開発

はじめに

先月からお世話になっているmofmofさんの研修で、顔を変えて遊ぶTwitterBotを開発しました。

この記事は開発したTwitterBotの紹介と、mofmofさんで学んだ研修内容のまとめです。

顔変えるBotの紹介

「顔変えるBot」は、AIが生み出した実在しない人物の顔を、AIによる顔合成技術でユーザーの顔に合成して、顔を変えて遊ぶTwitterBotです。

こんな感じで顔変えるBot@kaokaeru_bot)に人物画像をメンションすると、顔を変えた画像をリプライしてくれます。

「アイドルにして!」、「髭面にして!」のように、なりたい顔を指定することもできます。

昔こんな感じの「リアルバーチャルYoutuber」 という顔を匿名化するWebサービスを個人開発したのですが、こちらがアイデアのベースになっています。

mofmofさんの研修

自分はフリーランスとしてmofmofさんにお世話になっているのですが、まだまだ経験が浅いこともあってmofmofさんの研修を受けさせていただくことができました!

mofmofさんではリーン/アジャイルに関する10程度の研修を、社長のはらぱんさんによる講義/ワークショップの形式で受けることができます。そして研修で学んだことの実践の場として、メンターさんの指導を受けながら一人でプロダクト開発を行います。顔変えるBotはそこで開発したプロダクトです。(通常は1ヶ月かけてRailsアプリの開発を行うそうですが、自分の場合はRailsアプリ開発の経験があったのと他の仕事であまり時間が取れなそうだったので、TwitterBotの開発をさせていただきました。)

ここからは研修で学んだことを自分なりにまとめていきます。

リーン開発の概要

リーン開発には「全ては仮説である」という前提があります。

プロダクト開発を始める際にリーンキャンバス(後述)などのツールを使って、ターゲットとする顧客や解決したい課題を明確にしていきます。しかしそこで想定している顧客や課題はただの仮説です。自分がどれだけ良いプロダクトだと思っても、実際にはそんなものを欲しがっている人はどこにも存在しないかもしれません。そのため実際に使ってもらえるプロダクトを開発するためには、この仮説が正しいかどうかをまず検証する必要があります。

リーン開発では仮説を検証するためにMVP(Minimum Viable Product)を開発します。MVPとは最小限の機能だけを備えた、仮説を検証するためのプロダクトです。MVPを作って、実際にユーザーに使ってもらってフィードバックを受け取り、そこから学んだことをチームで学習し、MVPを修正します。このBuild(構築) -> Measure(測定) -> Learn(学習)のループを繰り返すことで、仮説検証を行っていきます。常にユーザーから学び修正していくので、MVPが最終的にどういう形になるかは予想がつきません。

MVPを作る際には以下のことに気をつけます。

  • 機能を最小限にする。機能を作りすぎてしまうと無駄なコストをかけてしまうし、コア機能がぼやけてしまう。仮説検証を行うためには機能は最小限でよい。Must-haveだけ作るようにしてNice-to-haveはスケール時に必要になってから作ればよい。
  • 仮説検証に注力する。そのため顧客との対話を重視する。リーンではマーケティングも含めて、全ては検証による学びを得るために行う行為になる。顧客と課題の検証は最優先事項。
  • 最小限のコストで作る。リソースは有限なのでリソースが尽きる前に仮説検証する必要がある。そのためには仮説検証ループは素早く回す。
  • アーリーアダプタに向けて作る。全員に向けて作ると誰も欲しくないものができてしまう。全員に好まれるものではなく、一部に熱狂的に愛されるものを作る。
  • まずは課題の質を上げる。ソリューションの質を上げるのはその後でないと無意味。課題が間違っていたら作り直しになる。

MVPはプロダクトではなくハリボテを作る場合もあります。有名なところではDropboxのデモ動画等がありますが、mofmofさんの場合は実際に触れるプロダクトを作ります。

参考: リーン・スタートアップとMVP/lean-startup-mvp - Speaker Deck

本だとリーン・スタートアップの青本が有名ですが、実践方法について詳しく書いてなくて自分には難しかったです。企業の科学が読みやすくてよかったです。 あと正確にはリーンと違うかもしれませんが、BasecampのGetting Real小さなチーム、大きな仕事Railsエンジニアには馴染みがあっておすすめです。

イデア出し

イデア出しの基本

一番初めは、どんなプロダクトを作るのかアイデア出しを行います。

イデア出しでは連想が基本になります。人はなにもないところからアイデアを出すことはできません。必ず何かしらの手がかりを元にして発想を行います。

うまくアイデア出しをするためにはこの手がかりを何らかの形で自分に与える必要があります。例えば「タウンウォッチング法」という発想法があります。街中に出て人やものを観察して、観察したものをメモしておきます。そして街中を歩いた際の記憶やメモを元に新しいアイデアを発想します。ここでとるメモはテキストに限定されません。手がかりになればよいのでイラストでもOKです。

具体的なアイデア出しの方法についてはこちらの「発想する技術」をおすすめされました。30の発想法が網羅的に書いてあります。

欠点列挙法でアイデア出し

自分の場合は以前作った「リアルバーチャルYoutuber」を改善したいという思いがあったので、プロダクトの改善案を発想する「欠点列挙法」という方法を参考にしました。まずプロダクトの欠点を列挙していき、そこから改善案を発想していく発想法です。

「リアルバーチャルYoutuber」は動画をアップロードすると架空の人物の顔に変換してくれるWebサービスです。こちらの欠点を列挙していきます。

欠点としては

  • 動画にサイズ制限/時間制限があるため使いにくい
  • 動画の顔変換に時間がかかる
  • サインアップ、動画作成で離脱してしまう人が多い
  • 変換した動画を共有する手段がない

改善案としては

  • 動画ではなく画像にすれば、サイズ/時間制限はなくなる
  • 動画ではなく画像にすれば、短時間で学習できる
  • WebサービスではなくTwitterBotにすれば、離脱ポイントが減る
  • WebサービスではなくTwitterBotにすれば、そのまま共有できる

こんな感じで「リアルバーチャルYoutuber」のTwitterBot版を作って、動画の代わりに画像を変換すればもっと使ってもらえるようになるのでは?と発想していきました。

良いアイデアのポイント

リーン開発において良いアイデアには以下のようなポイントがあります。できるだけこれらもおさえておきます。

  • 一言で表せるアイデアが良いアイデアインパクトを与えるためには、一言で表せないといけない。
  • 現実の課題を解決するアイデアが良いアイデア。架空の課題を解決しても誰も使ってくれない。
  • 自分の課題を解決するアイデアが良いアイデア。顧客 = 自分になるので、課題を深く理解できる。
  • 技術ドリブンではなく課題ドリブンなアイデアが良いアイデア(場合による?)

顔変えるbotはどちらかというと課題ありきではなく技術ありきの技術ドリブンなのですが、個人開発とか場合によってはこういうやり方もアリなようです。

リーンキャンバス作成

リーンキャンバスの基本

イデア出しが終わったら、そのアイデアをリーンキャンバスにまとめます。アイデア出しが発散で、リーンキャンバス作成が収束です。発散と収束は分けて行います。

リーンキャンバスではこんな感じでキャンバスが用意されるので、9つの項目を埋めていきます。

f:id:nekorails:20200103105828p:plain

項目を埋めていくことでビジネスモデルを整理できて、実際に開発する価値があるかどうかを分析できます。

リーンキャンバスの良い点は以下のとおりです。

  • ビジネスモデルを整理できる。ビジネスアイデアをピッチできるようになる
  • ビジネスモデルを分析できる。どこに弱点があるかわかる。
  • 簡単に作れる。事業計画書は作るの大変だけど、リーンキャンバスなら10分で作れる。

参考: リーンキャンバスの作り方/how-to-make-lean-canvas - Speaker Deck

リーンキャンバス作成

顔変えるbotのリーンキャンバスはこんな感じになりました。

f:id:nekorails:20200103105918p:plain

見にくい場合はこちら -> https://www.mof-canvas.com/canvases/41

この中でも特に重要な項目が課題と顧客セグメントです。しかし今回の顔変えるbotは課題と顧客セグメントがなかなか固まりませんでした。というのも顔変えるbotは、自分の顔を変えてそれをシェアして楽しんでもらうことを想定しています。「楽しむ」とか「遊ぶ」というのをどうやって課題にすればいいのわかりませんでした。メンターさんに相談したところ、例えば女子高生をターゲットにするなら暇を潰したいのかもしれないし、インフルエンサーをターゲットとするならその人達はフォロワーを増やしたいかもしれない。きちんと深堀りすれば出てくることもあるよーとアドバイス頂きました。

これ以外にもハイレベルコンセプトは1つに絞ったほうが良さそうとか、チャネルとしてインフルエンサーさんに使ってもらうのもいいかもねとか、フィードバックをもらいつつさらにブラッシュアップしていきました。

リーンキャンバス作成にはmof-canvasというサービスを使いました。こちらはmofmofの社員さんが研修で作成したサービスになります。使いやすいし、作成から公開まで簡単にできるのでおすすめです。

インセプションデッキ作成

インセプションデッキの基本

インセプションデッキは、10の質問に答えることでプロジェクトの全体像を明確にして、プロジェクトの目的をチームメンバー間で合意するためのドキュメントです。

プロダクト開発をする際、顧客自身が必要なものを的確に表現できるわけではありません。顧客に言われたものをただ作るだけだと、だれも欲しくないものを作ってしまうかもしれません。あるいは全く見当違いなものを作ってしまうかもしれません。顧客に言われたものをなんとなく想像で作るのではなく、顧客が望む価値を実現することが大切です。価値を実現するためには、開発を始める前にそもそもプロジェクトの目的が何なのかを明確にして、それを合意しておく必要があります。インセプションデッキはそのためのドキュメントです。

インセプションデッキ作成時のポイント

  • 合意のプロセスが大切。なんとなく合意するのではなく、ちゃんとメンバー間で議論をして合意する。
  • 最終的には自分でプロダクトの価値を説明できるようにする。
  • 本来はプロダクトオーナーが作るもの。実際には開発者も作って主体となって進めるほうが上手くいく。
  • 一度作って終わりではなく、ことある毎に見返して更新していく。

参考: インセプションデッキの作り方/how-to-make-inception-deck - Speaker Deck

インセプションデッキ作成

本来は11枚のスライドを埋めますが、今回は特に大切な4枚を埋めました。

f:id:nekorails:20200103110019p:plain

f:id:nekorails:20200103110104p:plain

f:id:nekorails:20200103110116p:plain

f:id:nekorails:20200103110138p:plain

トレードオフ・スライダーでは通常はスコープ/予算/時間/品質の4つのスライダーを使います。ただ「品質」は定義が曖昧になりがちです。保守性の高さを指すのか?見た目の綺麗さを指すのか?バグの少なさを指すのか?、「品質」が何を指すかは自明ではありません。そこで今回は品質の項目は外しました。

研修期間は決まっているので時間はMAXにして、予算に大きな縛りがないのでほぼMINにしています。

インセプションデッキでは合意のプロセスが大切になります。今回は変則的になりますがメンターさんにPOとしてインセプションデッキを作ってもらい、それを議論しながら合意してこの形にしていきました。例えば最初は「たくさんの顔モデルを用意する」というのがやるリストに入っていたのですが、これはMVPには必須ではないのでは?ということでやらないことリストに移したりしました。

ストーリー出し

ストーリー出し

インセプションデッキの作成が終わったら、ユーザーストーリー出しを行います。

ユーザーストーリーとはユーザーが実現したいことを簡潔にまとめた文章です。ユーザーストーリーを作る際は以下のポイントに気をつけます。

  • ユーザーにとっての価値に重きを置くために、ユーザー目線で書く
  • INVESTを満たしている
    • Independent: 各ストーリーが他のストーリーに依存せず単体で機能する
    • Negotiable: かっちり仕様をきめずに、実装方式について交渉可能である
    • Valuable: 価値を提供できる
    • Estimable: 見積もり可能である
    • Sized appropriately: 適切なサイズである
    • Testable: テスト可能である(受け入れ条件がある)

参考: ユーザーストーリーとは?

実際のストーリー出しではメンターさんと一緒に付箋にストーリーを書き出していきました。一通りストーリーを出し切ったら、ストーリーに抜けがないか確認した後にPivotal Trackerにバックログアイテムとして登録していきます。

f:id:nekorails:20200103110237p:plain
今は全てDoneになっていますが、こんな感じのストーリーを出しました。

見積もり

次に登録したストーリーを見積もります。

見積もりとしてストーリーにストーリーポイントを付けていきます。mofmofさんでは「Railsでテーブルに1つカラムを追加して、ビュー等も合わせて変更する」を基準サイズの1としているので、それと比べた相対的なポイントを各ストーリーに付けていきます。理想日のような絶対サイズを使うケースもあるそうですが、ストーリーポイントのような相対サイズを使うほうが主流のようです。

注意すべき点として見積もりはあくまでも見積もりでしかありません。確実な予測ではありませんし、コミットメントでもありません。

参考: 見積もり/agile-estimation - Speaker Deck

実際の見積もりではメンターさんとフィボナッチ数列を用いてプランニングポーカーを行い見積もりました。

参考: プランニングポーカーのやりかた – Ryuzee.com

スコープ削り

見積もりが終わると開発にどれくらいの期間かかりそうかが見えてきます。ベロシティはプロジェクトが進めば計算できるようになるのですが、プロジェクト開始時点だとわからないので今回は経験則的に適当な数字を利用しています。小さなプロダクトなのでストーリーは5つ程度とかなり少なめだったのですが、それでもリリース日(研修の最終日)には間に合わない感じでした。

ここからリリース日に間に合うようにスコープを削っていきます。このプロジェクトは研修期間が決まっているため、トレードオフスライダーの時間はMAXに設定されています。リリース日はずらせません。予算を増やして開発速度を上げられるプロジェクトでもないのでスコープを削るしかありません。

最初は自分には全ての機能が必須に思えたので、削るのは無理なんじゃないかと思いました。しかしメンターさんのアドバイスを元に精査していくと「ユーザーは顔を変換できる」というストーリーはもっと細かく分解できることがわかってきます。ストーリーを細かく分解していくうちに、分解されてできた「ユーザーはなりたい顔を指定できる」というストーリーが実はMVPに必須ではないことが判明します。MPVは実用最小限のプロダクトです。このプロダクトが提供する価値は「顔が変わって、それをみんなと楽しむ」なので、「なりたい顔を指定できる」というストーリーは必ずしも必須ではありません。ただなにかに顔が変わるだけでも目的は達成できます。

こんな感じで必須に見えるけど実際には必須ではないストーリーをスコープ外にしていって、ぎりぎりリリース日に間に合うようにスコープを削れました。(結局最後時間が余ったので、その時にスコープ外にしたストーリーのいくつかは実装したのですが。それはそれでよいのかなーと思います。)

MVP開発

ここまでで開発の準備は整ったので、ここから実際にMVPとなるプロダクトを開発していきます。

今回作成するプログラムはざっくり2つに分けられます。1つはTwitterAPIを利用してメンションから画像を取得してリプライを返すBot側のプログラム。もう1つは画像の顔を変換するAI側のプログラムです。

Bot側のプログラム作成

TwitterAPIを使うためにAPI申請をします。最近申請が厳しくなったと聞いていたので、実はここが一番不安でした。でもこの記事を参考に申請してみると、すんなり審査は通りました。

申請したTwitterAPIを使ってBot側のプログラムを書いていきます。顔変えるBotではメンションされた画像を加工するため、メンションを監視する必要があります。Account Activity APIというのを使えばWebhookで通知を受け取れるらしいのですが、別途申請が必要だったり結構面倒なことが多いそうです。なので単純にRubyプロセスを常駐させて、メンションが来ていないか確認するためにREST APIをポーリングする形にしました。

Bot側のプログラムは特に難しいこともなく順調に進みました。

AI側のプログラム作成

顔画像を変換するのにディープラーニングを利用するのでGPUサーバーが必要です。クラウドを使うと数万円/月かかってしまうので自前のGPUサーバーを利用します。(ただのゲーミングPCに電源やGPUを追加しただけですが。)久しぶりにPCを触ったら画面が付かなくて焦りました。結局はマザボに電源を供給するケーブルが劣化していただけだったのですが、これを解決するのに1~2日もってかれてなかなか辛い感じでした...💦

AI側のプログラムは「リアルバーチャルYoutuber」で作ったプログラムを流用しています。AIで顔変換する部分とWebサービスが密結合になっていたので、そこだけ修正して独立した形で使えるようにしました。学習モデルはそのまま流用できる感じだったので流用しています。

GPUサーバーのセットアップ(物理)にかなりてこずりましたが、なんとかリリースまでに完成できました。

完成したプロダクトで社員さんの顔を変えて遊んでいたら、結構喜んでもらえました。よかったよかった🐈

KPTでふりかえり

KPTの基本

最後に研修全体をKPTでふりかえります。

KPT(Keep/Problem/Try)とはシンプルで強力なふりかえりの手法です。

3つの要素に分けて現状分析を行います。

  • Keep: 良かったこと(今後も続けること)
  • Problem: 悪かったこと(今後はやめること)
  • Try: 次に挑戦すること(Problemの改善策、Keepでさらに改善すること)

ふりかえりを円滑にすすめるために、以下のグラウンドルールが用意されています。

  • 積極的に話し、参加する
    • 当事者意識を持つ
  • 1人で話しすぎない
    • 発言をさえぎらない
    • 話してない人にも思いあり
  • 原因追求をする。個人の責任追求をしない
    • 罪を憎んで人を憎まず
    • 「人 vs 人」ではなく、「チーム vs 問題」の構図を意識する
    • だから自己弁護も不要

参考: 振り返り/agile-looking-back - Speaker Deck

KPTでふりかえり

まず自分とメンターさんと社長でそれぞれKeepとProblemを付箋に書き出して、その後Problemに対するTryを出し合っていきました。

こんな感じです。

f:id:nekorails:20200103110421j:plain
左がKeep、右がProblem/Try

  • Keep
    • 期日通りリリースできた
    • 研修で学んだことをプロダクト開発を通じて一通り実践できた
    • スコープ削りができた
  • Problem -> Try
    • GPUサーバーのセットアップに苦戦して期限危うかった -> 必須でリスクが高いストーリーは先に見通しをたてておく
    • コードレビューできなかった -> 詳細設計とか話し合っておけばその時にできた
    • 研修で学んだことをもう忘れそう -> 研修で学んだことをブログにまとめれば思い出す

まず期日通りリリースできたのが何よりでした。あとは講義で学んだことを実際のプロダクト開発を通じて一通りできたのは良い経験になりました。こういうのは実際にやってみないとわからないことも多いし、身につかないものだと思うので。正直これだけだとまだ基礎を抑えただけなので今後実務で経験を積んでいかなければならないのですが、フリーランスの研修としては十分すぎるほど時間を使わせてもらえて良い経験を積むことができました。

さいごに

メンターとして開発に付き合ってくださった @sssgggiiiさん、@harada4atsushi さん、お二人のおかげでなんとか完成させることができました。本当にありがとうござました🙇

自分の中ではこの記事の公開がプロダクトの正式リリースのつもりなのですが、なんとか形になってほっとした気持ちです。

リーン開発としてはBuild -> Measure -> Learnループの最初のBuildが終わっただけで、ここからが本番な感じです。今後は実際に使ってもらってフィードバックループを回していけたらなーと思います。(ただしすでにやる気が消えかけてます 。個人開発で一度リリースするとやる気が消える問題、いい加減どうにかしたいです・・・😇)

よわよわRailsエンジニアのジレンマ

こんにちは。よわよわRailsエンジニア愛知代表のshitaです。

最近フィヨルドさんやmofmofさんのミートアップで、駆け出しエンジニアの方達に就職の相談をいただくことがありました。

自分は未だによわよわなのですが、駆け出しエンジニアの頃は今よりもっとよわよわでした。その時にRails友達と話していた悩みを思い出したのでここで共有させてください。

よわよわRailsエンジニアのジレンマ

よわよわRailsエンジニアはよわよわな現場にしか入れず技術力が上がらないので、ずっとよわよわな現場から脱出できない。

  1. つよつよな現場はつよつよRailsエンジニアを求めるため、よわよわRailsエンジニアはよわよわな現場に入るしかない
  2. しかしよわよわな現場では技術力を上げるのが難しい
  3. 技術力が上がらないので、よわよわエンジニアはつよつよな現場に入ることができず、ずっとよわよわな現場から脱出できない

そしてよわよわな現場はお賃金が低くブラックなことが多いため、徐々に精神的に追い込まれていきます。

『よわよわな現場では技術力を上げるのが難しい』というのがポイントです。

(ここで言うつよつよな現場は、いわゆる『ふつうの』Railsアプリケーション開発 をやっている現場を指します。Rails開発で当たり前とされていることができている現場です。テストが書かれているかどうかが1つ分かれ目かと思います。まともなテストを書くにはまともな設計が必要なので、よわよわな現場はテストを書けません。)

よわよわな現場では技術力を上げるのが難しい

よわよわな現場でも技術力を上げることは不可能ではないですが、実際にはなかなか難しいのが現実です。理由は以下のとおりです。

つよつよなコードに触れられない

つよつよな現場にはつよつよなコードがあります。ちゃんとDB設計/クラス設計/URL設計等が行われていて、Ruby/Railsの流儀に則っていて、Fatコントローラー/Fatモデルではない、メンテナブルでリーダブルなコードがあります。毎日つよつよなコードに触れるのは、毎日Railsのベストプラクティスを学んでいるようなものです。ただコードに触れているだけで、自然と良い書き方が身についていきます。

一方よわよわな現場にはよわよわなコードがあります。テストコードはなく、Restfulではなく、ドメインロジックはモデルに書かれず、コントローラーは1000行を超えます。駆け出しエンジニアの場合は経験が浅いので、Railsはこんな感じなのかと思ってしまいます。毎日よわよわなコードに触れるのは、毎日Railsのバッドプラクティスを正しい書き方として学んでいるようなものです。ただコードに触れているだけで、自然と悪い書き方が身についていきます。

コードレビューを受けられない

つよつよな現場ではコードレビューが受けられます。コードレビューはスキルアップの場でもあります。良くないコードを書いてしまった場合でもコードレビューで指摘してもらえるので、コードレビューのたびに新しい学びを得られます。

一方よわよわな現場にはコードレビューはありません。良くないコードを書いても、それが良くないコードだと気づくことはありません。

モダンな技術に触れられない

つよつよな現場はモダンな技術を採用しています。つよつよな現場には技術好きな人達が集まるため、新しい技術についての知見も共有され、プロジェクトにマッチするようなら自然と採用されていきます。

一方よわよわな現場はレガシーな技術が使われ続けます。選択の結果あえてレガシーな技術を採用したのなら良いのですが、よわよわな現場はそもそもモダンな技術を知らないし関心がありません。CoffeeScriptjQueryを使い続けます。その結果、つよつよな現場で求められるスキルセットと自分のスキルセットの間でズレが生じてきてます。

勉強時間を確保できない

つよつよな現場はホワイトです。つよつよな現場はつよつよなRailsエンジニアを採用するために働きやすい環境づくりに力を入れています。今までお世話になったつよつよな現場では当たり前のように残業はありませんでした。仕事は早々に終わるので、業務後に自己研鑽に時間を使えます。というか、つよつよな現場では業務時間中にも勉強できます。昔お世話になった会社では業務時間中に普通に勉強会が開かれてて、目ん玉飛び出るくらいびっくりしたのを覚えています。当時の自分は勉強は業務時間外にやるものだと思っていたのですが、どうもつよつよな現場ではあたりまえのことのようです。

一方よわよわな現場はブラックです。当たり前のように残業があるため、新しい技術の勉強にはなかなか時間が割けません。結果、更新されないままの手持ちの知識でなんとかしようとするため無理のある設計/実装になっていきます。メンテナンス性は考慮されず、コードはさらに地獄と化していき、プロジェクトは炎上し、さらに勉強時間を確保するのが難しくなっていきます。あとこちらがより深刻なのですが、ブラックなので精神的に摩耗してしまい、家に帰っても勉強する気力が残っていません。

よわよわな現場を脱出するには?

よわよわな現場を脱出するにはつよつよな現場で経験を積むのが一番です。すでに述べたとおり普通にはつよつよな現場には入れませんが、こんな感じで一工夫すれば可能性が出てくるのかなーと思います。

つよつよな現場にアルバイトで入る

これは自分がとった方法です。

会社としては正社員を採用するよりアルバイトを採用するほうが敷居が低いです。そのため、とりあえずアルバイトとしてつよつよな現場に入って経験を積むのはありだと思います。開発経験としては正社員と遜色のない経験を積めますし、そのまま正社員に誘われることもあります。

フィヨルドブートキャンプに参加する

これも自分がとった方法です。

フィヨルドブートキャンプはプログラミングスクールです。ただ、他のプログラミングスクールとはだいぶ違っていて、単純なRailsの知識を教えるのではなく実際につよつよな現場で働けるだけの現場力を身につけてもらうことにフォーカスしています。

昔記事を書いたので、詳しくはこちらをどうぞ。

nekorails.hatenablog.com

メンターの@komagataさん@machidaさん達と一緒にOSSRailsアプリケーションを開発をするのですが、これはつよつよな現場そのものです。がっつりつよつよな現場の経験を積めます。

駆け出しエンジニアを募集しているつよつよな会社を探す

つよつよな会社は、新卒を除いてあんまり未経験者を募集していません。

しかし、つよつよな会社でも駆け出しエンジニアを積極的に募集している場合があります。そういう会社は研修もしっかりしていて、まだまだよわよわな駆け出しエンジニアを受け入れる体制ができているのかなーと想像します。

例えば自分がフリーランスとしてお世話になっているmofmofさんは、実務未経験/実務経験が浅いRailsエンジニアの方達に向けて定期的にミートアップを開いています。

www.wantedly.com

その会社がつよつよかどうかは、実際に現場で働いているエンジニアさん達に聞くのが良いと思います。知り合いのエンジニアに聞くか、勉強会の懇親会などで聞けば教えてもらえるかなーと思います。

他の方法

あとはOSS活動も良いと思うのですが、OSS活動できる時点で既によわよわではないかなーと。

勉強会に行くのはつよつよな現場のつよつよな知見を得られて良いと思います。ただよわよわな現場だと基本炎上しているので、その時間と体力を捻出するのがけっこう難しかったりします。

まとめ

最近はプログラミングスクールが増えて駆け出しエンジニアが大量に増えたため、パイの奪い合いが激しくなって、駆け出しエンジニアの就活がより厳しくなったと聞きます。そのため仕方なくよわよわな現場に入る方達が増えて、その方達がこのジレンマから抜け出せなくなってしまうのではないかと心配です。

優秀な人であればよわよわな現場に行ったとしても勝手に成長しますし、むしろ現場を改善していけるんだろうと思います。しかし、自分も含めて多くの駆け出しエンジニアはまだまだよわよわです。それはとても難しいことです。

駆け出しにエンジニアとってよわよわな現場を避けることはとても大切なことだと思います。よわよわな現場に入ってしまい、心をやられてしまったという話をいくつか聞いたことがあります。せっかく勉強してきた結果がそれでは悲しすぎます。

駆け出しエンジニアのみなさんの就職が上手くいくことを心より願います🐈

Sendagaya.rbさんに初参加させていただきました!

先日お仕事のために東京に引っ越したのですが、未だにベッドが届かず床に寝ています。引っ越し作業大変すぎて、仕事開始までに終わるか心配になってきました・・・。

昨日Sendagaya.rb #295に参加させていただきました!

ずっと田舎に引きこもっていて勉強会に参加させていただくのは久しぶりだったので緊張しましたー。

流れとしてはこんな感じでした。

  1. @s4naさんの技術的な相談をみんなで考える
  2. 自己紹介
  3. 軽い懇親会(のはずでしたがお店がギリギリ閉まってしまった)

@s4naさんの技術的な相談をみんなで考える

RubyにはWebMockというHTTPリクエストをモックするgemがあるのですが、それがうまく機能しないという相談でした。モックしているはずなのにリクエストが飛んでしまう。

提示されたコードはこんな感じでしたー

WebMock.enable!
WebMock.stub_request(:get, url).to_return(response)

いろんな意見が出しましたが、以下覚えている部分だけ箇条書きでー。

  • モックするコードの直後にブレークポイント仕掛けて試行錯誤してみると良いかも
  • HTTPメソッドやURLがマッチしていない可能性がありそう
    • 問題を切り分けるために、:any*を使ってそもそもリクエストがモックできるのか調べてみよう -> モックできなかった。モックするコードではなく、他の部分に問題がありそう
  • 特定の条件でモックがdisabledになってしまう可能性がありそう
  • 何か見落としがありそう。そもそも論として処理のフローはどんな感じ?
    • 検索ボタンを押す -> ブラウザからサーバーに/tweets.json(クエリパラメータ) -> サーバーがtwitter gemを使って、ツイートを取得 -> サーバーがJSONでブラウザに情報を返す
    • テストコードではCapybaraのvisitメソッドを使ってAPIにアクセスしている。ここをモックしたい。 -> あれ?visitってモックできるんだっけ?
  • Webmockはどの部分をモックする?
    • おそらくNet::HTTP等のRubyの主要なHTTPライブラリのリクエスト部分をモックしているはず
    • visitはブラウザアクセスなのでモックできないのでは? -> これが原因だった

ということで、Web APIvisitでブラウザアクセスしていたのでモックできないということでしたー。

この後もここから派生して色々な学びがありました。

  • ブラウザアクセスをWebmockでモックできるgemがあるよ -> puffing-billy
  • リクエスト情報をダンプするgemがあるよ。めっちゃ便利そう -> http-dump
  • コントローラーにTwitterAPIへのアクセス処理をベタ書きしてしまっている。これだとFatコントローラーなので、Twitterへのアクセス部分だけPOROに切り出すと良さそう
    • 外部APIへのアクセスは結構変更があったりするので、切り出しておくと修正しやすくなる
    • モックが簡単になる。リクエストをモックするというより、リクエストの処理をインスタンスメソッドに閉じ込めて、そこを丸ごとモックするのが良さそう
    • この場合、POROはmodels配下に置く。libに置いたりgemにしたりする人もいる(けどちょっとやり過ぎかも)
  • 上記のインスタンスメソッドは、どうやって単体テストをすればよい?
    • 外部APIをテストすることになってしまうので、テストは結構難しい
    • 毎回リクエストするのはまずいし、VCRを使ってキャッシュしておくと実質的にはテストにならない
    • リクエストの形式はテストできそう。ちゃんとした引数が渡っているか程度のテストでいいかなー
    • あとテストとは別で外部APIの動作をチェックするCIを用意する、っていうのは可能。例えば外部サイトの画面をスクレイピングして情報をとってくるような場合は、画面は変わりやすいのでチェックは必須になりそう。

感想

WebMockでモックできない件はあらためて考えてみると簡単なことなのですが、自分でPCを操作できない等の制約がある中で解決にまで至るのはなかなか大変でした。自分は見当違いなことを言ったり、そもそも問題を正しく理解できていなかったり、結構迷惑かけてしまいました。でも皆さんは1つずつ問題を切り分けたり、そもそもフレーム外の所に問題があるのでは?と気づいたりしていて、すごいなーと感心しっぱなしでした。どういう流れで解決まで至るか、@tkawaさん、@fukajunさん、@sanfrecce_osakaさん達、強い人達の思考の過程を生で見れたのはめちゃ勉強になりました!

あと今回は主催者の@tkawaさんと@fukajunさん以外、参加者の4人全員フィヨルドブートキャンプ生(卒業生含む)という奇跡が起きました✨自分はフルリモートでフィヨルドブートキャンプを卒業して、他の生徒さんと会うのは初めてだったので、なかなか緊張しました。でも3人とも優しい方だったので安心しました。よかったー。特に@NMPさんとはお互い上京したばかりで、初勉強会参加ということで意気投合しました。

そして主催者の@tkawaさんと@fukajunさんおふたりともとても優しい方で、本当リスペクトでした。Rubyコミュニティの方たちは、皆さん本当に優しいですよね。感動です✨

あと会場のランチェスターさんが凄くきれいでした。

久しぶりの勉強会で緊張しましたが、楽しいし勉強になるし最高の勉強会でした!主催者の皆さん、参加者の皆さん、会場提供してくださったランチェスターさん、ありがとうございましたー!  

プログラミングスクールの理想と現実。あとフィヨルドブートキャンプについて

Railsのプログラミングスクールについての話です。あと自分はフィヨルドブートキャンプの卒業生で、バイアスかかってるかもなので差し引いてお読みください。)

プログラミングスクールについてあまりいい話を聞きません。

炎上系のプログラミングスクールだけでなく、その他のプログラミングスクールについてもネガティブな話を結構聞きます。

正直自分もプログラミングスクール業界には良いイメージはないのですが、とはいえちゃんと探せば良いプログラミングスクールも(少しだけ)存在します。この記事はそんなお話です。

プログラミングスクールの理想と現実

プログラミングスクールの問題点は明確で、プログラミングスクールを卒業しても現場で働けるだけの実力がつかないということです。

こんなイメージです。

f:id:nekorails:20191022004905j:plain
プログラミングスクールの理想と現実(字が下手すぎてすみません🙇)

プログラミングスクールではRails周りの基礎を一通り勉強して、Webサービスを個人開発して卒業のところが多いかなーと思います。でもこれだと現場で働けるレベルまで届かないです。図の現場力に相当する能力が不足しています。具体的には

これらの能力を身につけるには技術書を読むだけだと足りません。実際に優秀なRailsプログラマと一緒に開発したり、コードをレビューしてもらったり、ペアプロしたりしながら、実践とフィードバックを繰り返すことで日々少しずつ成長していきます。

フィヨルドブートキャンプのメンターの @komagata さんが、詳しく書いているのでこちらおすすめですー。 -> Railsエンジニアとして就職できるレベルとは - komagataのブログ

現場で働けるだけの実力がつかないので、就職もなかなか難しいです。フィヨルド以外のプログラミングスクールの方とお話させてもらう機会がありましたが、みなさん就職に苦戦されてるようでした。

プログラミングスクールは良いメンターを雇えない問題

現場力を鍛えるためにはプログラミングスクールは優秀なメンターを雇う必要があるのですが、それはとても難しいです。優秀なメンターは優秀なプログラマなので、高すぎるし引く手あまたなのです。優秀なメンターを雇えないので、プログラミングスクールを卒業したばかりの現場未経験の方をメンターとして雇うような事態が起きてしまいます。(そのレベルでも基礎であれば教えられるので必ずしも悪いことではないと思います。ただし現場レベルのフィードバックは得られませんし、現場力を鍛えるにはそれがとても大切です。)

フィヨルドブートキャンプなら、現場力を身に付けられるよ

フィヨルドブートキャンプは上記の問題を解決しています。

実際に現役のエンジニア/デザイナーである @komagata さんと @machida さんの二人が直接メンターになってくれます。Rubyコミュニティで有名な二人なので知っている方も多いと思います。お二人は他の仕事もしながら、フィヨルドの会社経営もしながら、メンターもしてくれます。どう時間を作っているの?スーパーマンです。

フィヨルドブートキャンプではBootcampという学習状況や日報を管理する独自のRails製サービスを利用しています。基礎の学習が一通り終わると、このサービスを二人と一緒に開発していくことになります。実際に今まで自分が使っていたサービスを開発する形になるので、スムーズに開発に入れます。この開発の中でスクラムを組んだり、ペアプロしたり、Github上でレビューしてもらったりすることで、現場力を鍛えて行くことが出来ます。

レビューしてもらえるのはコードだけではないです。Webサービスの個人開発のプラクティスでは、エレベーターピッチやペーパープロトタイプ、Webサービスのデザインなんかもレビューして貰えます。こちらはデザイナーの @machida さんが主にレビューしてくれます。この記事を読んでもらえればどんな感じでレビューしてもらえるか、雰囲気がわかると思います。 -> プログラミングスクールで、「リアルバーチャルYoutuber」というWebサービスを作りました - 猫Rails

あと、例えばフィヨルドブートキャンプには「lsコマンドをRubyで作ってください」という課題があります。これはただ動くだけでは駄目で、Rubyのコードとしてリーダブルでメンテナンスしやすいコードを書く必要があります。この問題に答えはありません。そこで生徒さん達は、参考図書のオブジェクト指向設計実践ガイドを読んだり、@komagataさんに何度もレビューしてもらったり、(課題クリア後に)他の生徒さんのコードを読んだりしながら、少しづつRubyオブジェクト指向について学んでいきます。こういった答えがない問題を自分で調査したり考えたりしながら解決していくことでも現場力が鍛えられていきます。

フィヨルドブートキャンプの良いところ

上記の「強いメンターにより、現場力が鍛えられる」というのが一番の魅力です。他にも色々良い所があるので列挙しておきます。

  • 3万円/月で良心的。しかもフィヨルドさんの紹介で就職すると全額キャッシュバック。卒業生の多くはフィヨルドさんの紹介で就職してるっぽい
  • 卒業生は皆さん有名な会社に就職されてる(それくらい鍛えられる、というのと二人の人脈が広いというのもあるかも)
  • リモートでできる(自分は田舎に住んでいるので、完全にリモートのみで卒業しました)
  • ローカルでもできる(可能ならフィヨルドさんのオフィスに行ったほうが良いと思います。Slackで質問するより直で聞くほうが便利だし、他の生徒さんもいてやる気も出ます)
  • 特に強制がなく、自分のペースで進められる(人によってはデメリットかも)
  • 日報や学習時間の草など、学習を継続するよう促す仕組みがある

f:id:nekorails:20191022011707p:plain
この草を絶やさないようにしてたら、3ヶ月休みなく継続できた🐈

フィヨルドブートキャンプの悪いところ

正直ほとんどないのですが、公平性のために悪いところもあげておきます。

「基礎を手取り足取り教えてもらえない」、というところは人によっては辛いかもです。

たぶんこれは「現場力が鍛えられる」の裏返しです。現場力を鍛えるためには、未知の問題に出会った時に自分で解決する能力を鍛えていく必要があります。そのためフィヨルドブートキャンプの課題は、自分で調査して考えることを要求する、答えのない課題が多いです。なのでWebを調べたり、他の生徒さんの日報を調べたりしながら、自分の頭で考えて解決していきます。この調査・思考自体が大事な訓練なのですが、未経験者の場合は手取り足取り教えて欲しいという方もいると思います。そういう方にはあんまり向いていないかもーと思います。

かなりハードなカリキュラムになりますし、実際フィヨルドブートキャンプを卒業できる人は少ないです。(だからこそ卒業生は皆さん優秀だし、有名な会社さんに就職できるのですが。)

個人的には基礎は独学で済ませて、プログラミングスクールでは現場力を鍛えるべきだと思うので、このやり方は正しいと思います。プログラマとしての適正を早めに判断できるという利点もあります。とはいえ早めに脱落してしまう人が結構多いので、未経験者にはもうちょっとサポートがあってもいいのかなーとも思います。

これは悪いところというより思想の問題かもしれないです。

プログラミング未経験でフィヨルドブートキャンプに参加される方は、Progateやドットインストール等で先に基礎を勉強しておくか、並行して勉強していくのをおすすめします。ただカリキュラム的には未経験でも進められるように必要なプラクティスを網羅しているので、やる気がある方ならフィヨルドブートキャンプだけでも問題ないです。

フィヨルドブートキャンプに向いている人

「最低限のプログラミングの基礎知識があって、現場力を鍛えたい方」です。具体的には

  • Progateやドットインストール等で基礎を独学済みの方
  • 他のプログラミングスクールを卒業したけど就職できなかった方
  • SIerからWeb系に転職したい方
  • 現役プログラマで、Ruby/Railsをがっつり勉強したい方

意外かもですが、現役のプログラマが参加するのはめっちゃ有りだと思っています。自分はRailsの実務経験3~4年で参加しましたが、それでも学ぶことが大量にありました。(自分のRails力が低いというのもありそうです 😹)。経験者の場合は不要なプラクティスは飛ばしつつ、自分が強化したい分野を重点的にやります。自分の場合は苦手意識があったテストとモダンフロントエンドを重点的にやりました。

たしか3日間以内だったら無料で辞められたはずなので、一度入ってみて合わなそうなら辞めてみるのもいいと思いますー。

その他の良いプログラミングスクールの探し方

実際現場で働いている現役プログラマさんに聞くのが一番です。知り合いのプログラマに聞いたり、勉強会に参加して懇親会などで聞いてみるのがいいのかなーと思います。採用に関わっている方も多いですし、ネットには出てこないリアルな話が聞けると思います。

検索で評判調べるのはイマイチかもです。SEOがハックされているので、有益な情報を拾うのが難しいです。例えば「プログラミングスクール 評判」で検索すると、現役プログラマからの悪評が多いプログラミングスクールが書いた記事が出てきて、自分で自分をおすすめしてます。検索を使う場合は、個人ブログのリアルな声を参考にするとよさそうです。

大学院もいいよ

あと、プログラミングスクール以外の選択肢として専門職大学院に行くのもオススメですー。

自分は文系大学からプログラミング未経験で産業技術大学院大学(AIIT)という専門職大学院に行きました。公立なので安いですし、社会人が通えるように平日夜と土曜日に開講しているし、未経験でも(ギリギリ)ついていけるようにカリキュラが作られています。

入試は応用情報技術者試験の午前相当の問題で、対策も立てやすくそれほど難しくありません。ただし入試に比べて生徒や教員のレベルは高いので、入学後はなかなか大変です。

カリキュラムとしてはCSの基礎から、デザイン、マネジメント、経営まで広く学べます。自分はCS関係の講義をとるだけで手一杯でしたが。あと2年目はPBLという形で実務相当の経験をつめますし、かなり実務に即した学びが可能です。

2年かけてじっくり学べますし、こちらもかなりおすすめです。

aiit.ac.jp

ただRailsスペシャリストが教えてくれるわけではないので、Railsをやると決めているならやはりフィヨルドブートキャンプが一番おすすめですー。Ruby/Railsの教育に関しては、それくらいフィヨルドさんは良いです 🐈

bootcamp.fjord.jp

mofmof inc.さんについて調べましたー🐈

f:id:nekorails:20191008234848j:plain

以前会社体験会に参加させていただいたmofmofさんに面談していただけることになりましたー。

自分は新卒時は大学院の友人の会社に就職して、フリーランス時代も繋がりでお仕事をもらってきたので、こういうまともな面談みたいなのはしたことがありません。なのでだいぶ緊張します。

面談の前準備として、その会社を知るために企業研究をやっておくといいそうです。mofmofさんは有名な会社なのでだいたいどんな会社かは知っていましたが、今回はより詳しく調べてみました。

お世話になっているフィヨルドブートキャンプさんに企業研究というプラクティスがあり、そちらを参考にしています。

(あくまで自分用にまとめたメモです。おそらく自分の勘違いなども結構混じっていると思いますので、正確な情報についてはmofmofさんのHPや企業ブログを御覧ください。)

代表

ミッション・ビジョン・バリュー

ミッション

  • 新しいテクノロジーを使って新しい価値を創造し、より一般的なものに変えること
  • 「技術が目的、ビジネスは手段」という価値観。技術好きが伝わってきます。すてき。

ビジョン

  • つくって人をしあわせにする

バリュー

  • 根性に頼らず、思考して工夫する
  • うまくいかないときは「人」ではなく「仕組み」に着目すること
  • 感情的にならないこと
  • 自己研鑽すること
  • 会社のためではなく自分のために働くこと

参考

メンバー構成

  • 20名程度
  • 社員さんとフリーランスさん半々くらい
  • 20代と30代が半々くらい
  • 8割がエンジニア
  • 強いエンジニアが多い
  • デザイナさんはいない

働く環境

  • 正社員/業務委託
  • 副業や時短をサポート
  • 火曜日はリモートワーク
  • ガチで残業0
  • ベンチャー企業にありがちなピリピリした雰囲気はなく、エンジニアにとって居心地が良い環境。イヤホン着用可で作業に没頭しやすい
  • メンバーはReact.js勉強会や、初心者向け機械学習勉強会、Vue.js勉強会など、社内外向けに勉強会を積極的に開催
  • 1人で2案件持つことも。その場合は20時間/週を2つ持つ感じになる。午前/午後で分けてもいいし、日にちで分けても良いし、その辺は自由。
  • クライアント(プロダクトオーナー)を含めて2〜6名くらいの小規模チームで開発
  • フリーランスさんでも社員さんでも2.5日/週から入れる。フリーランスの場合は基本的には2.5日/週からスタートらしい
  • 受託でも客先常駐はなく、社内で開発
  • お昼休みはみんなゲームしてる

参考

プログラミング

  • コードレビューは必須
  • テストコードは可能な限り書く
  • TDD推奨

利用している技術

サーバサイド

インフラ

  • Heroku or AWS(基本、これ以外は受注していない)

フロントエント

  • Vue.jsがメイン。Nuxt.jsも使ってるっぽい。
  • React.jsも。
  • jQueryはもう使ってないらしい

ツールなど

  • GitHub
  • Pivotal Tracker
  • Slack
  • Circle CI
  • Wercker
  • Google Hangouts
  • Firebase
  • Docker

原則常に最新バージョンにアップグレードする

事業内容

受託開発

月額制受託開発「開発チームレンタル」

  • (おそらく)メインとなる受託サービス
  • 昔ながらのウォーターフォール型の作って終わりの受託ではなく、月額制アジャイル型の受託
    • 請負契約ではなく、準委任契約
    • 客先常駐ではなく、社内で開発
    • 成果物の実現ではなく、価値の実現
    • クライアントとは受注者・発注者の対立の関係ではなく、1つのチームとしての関係
    • まずはMVPを作り、3ヶ月以内にサービスイン
  • 新規事業に特化
  • 流れは、開発相談 -> 契約 -> 開発 -> リリース -> 保守
  • アプリ開発もするがWeb開発がメイン
  • 営業はしてなくてpullのみ(と聞いた気がするが勘違いかも)。それでもエンジニアが足りなくなるほど多数の依頼が来ている。
  • 現在は20程度の案件が走っている
  • 価格
    • 60万/月から(古い資料なので変わってそう)
    • 保守・運用フェーズは3万/月からの別プランがある。脆弱性対応やチャット対応等。
  • 過去の事例

参考

いきなりMVP

  • 3日の開発合宿でMVPを作りきる
  • 軽井沢とか行くらしい。ブログで皆さん楽しそう
  • このあと開発チームレンタルに繋がるのかな
  • 250万円から

参考

いきなりシェアリングエコノミー

My-ope office

  • 社内問い合わせ対応専用のAIチャットボット
  • 社内からの問い合わせにさくコストを減らせる

新規事業

  • 「技術が目的、ビジネスは手段」の言葉通り、AR/VR/AIなどの新しい技術を使った事業が多い

meshiqoo

  • ARで飲食店を検索
  • ダウンロードして使ってみたが、愛知県の田舎に飲食店なんてなかった😢東京行ったら使おう

VR酒屋

  • VR内でお酒を買える

Toriders

  • AIによる振り込み業務自動化サービス

採用基準

  • 主に技術力/人間性/コミュニケーション能力の3つ

人間性

  • mofmofのビジョンやミッションに共感できる人
  • 技術好きな人。WEBサービスやプロダクトを作るのが好きな人。
  • 学習を続けられる人。学習を楽しめる人。自ら学べる人。
  • 感情的にならない人。波風を立てない人
  • ただ作るのではなく、クライアントに対してちゃんと価値を提供できる人
  • 自律的に行動できる人
  • 反省し改善し続ける人
  • 最高の仲間!的な暑苦しい人はちょっと違うらしい

参考

コミュニケーション能力

  • 素早く適切に他者と意思疎通し合意する能力
  • 会話や振る舞いによって他者に好感を与える能力

参考

福利厚生

  • 出張マッサージ
  • 書籍リクエス
  • GPU手当クラウドや自費購入のグラボの費用の一部を会社で負担。AI使った自作サービス作る際にGPU高くて苦労したので、これは嬉しい人多そう
  • HerokuのDyno手当
  • もふもふ手当。もふもふ関係で貰える。

同業他社さんと比べた際の特徴

  • Railsによるアジャイル開発で、単に作って終わりではなくクライアントへの価値提供を重視する
  • 新規事業に特化していて0->1を経験できる
  • クライアント(プロダクトオーナー)を含めて2〜6名くらいの小規模チーム
  • フリーランスさんが多い。社員さんしかいない所もあるので
  • 受託開発と新規事業の両輪
  • 2.5日/週から入れる、週1リモートワーク等の働きやすさ
  • 「技術が目的、ビジネスが手段」等のユニークな価値観
  • mofmof感。HRT、穏やかさ、優秀さ、技術好き、ものづくり好き、動物好き的な。(ブログから受ける印象です)

企業研究してみた感想

単純に企業ブログや社長の原田さんのブログが勉強になりました✨

原田さんのブログは以前から読ませてもらっていて、自分が自作アプリを作った際にもエレベーターピッチを作る時に エレベーターピッチの作り方 - シンプルな言葉でプロダクトを表現する方法 - 毎日がもふもふ を参考にさせて頂いてました。他の記事も美味しい情報が詰まっているので、mofmof志望じゃない方にもおすすめです。技術系の記事は普段から読むのですが、ビジネス寄りの記事はあまり読んでこなかったので知見の塊でした。かなり情報量が多く全然消化できてないので、何度も読み返すことになりそうです。

あと、企業研究してみてやはりmofmofさんは調べれば調べるほどいい会社だなーと思いました。優秀で、技術が好きで、ものづくりが好きで、優しい会社さんです。実際に社員の方達とお話させていただいた際も同じこと思いました。(ただブログだとゆるふわな雰囲気ですが、実際にはガチで強いエンジニアさん達ばかりだと聞きます。)

「技術が目的、ビジネスが手段」や、「根性に頼らず、思考して工夫する」等、他の会社にはないユニークな価値観が多くあります。原田さんがSIer -> フリーランスという経験をされているエンジニアなので、エンジニアが価値を実現しながら楽しみ成長していくにはどうすればいいのか?っていう発想が根っこにあるのかなーと想像します。そういった価値観は「mofmof」という会社名に現れてる気がします。

募集が多くて競争率が高いというお話も聞くので正直自分の実力では難しい気もしますが、マッチしたらいいなーと思います🐑

参考

mofmofさんの会社体験会に参加したら、みんな虜になったよ🐑

f:id:nekorails:20190920172909j:plain

先日mofmof inc.さんでmofmofさんのアジャイル開発を体験できるイベントが開催されたので、愛知県から新幹線で参加させていただきましたー!

www.wantedly.com

このイベントはmofmofさんに興味があるエンジニア見習いさんに、mofmofさんがどんなところかを知ってもらうために開かれたもので、これ以外にも定期的に開催されているそうです。

イベントは以下の流れで進みましたー。

  1. mofmofさんの会社紹介
  2. 社員さん、参加者さんの自己紹介
  3. KPTワークショップ
  4. 社員さんに質問する会

mofmofさんの会社紹介

(おそらく)こちらのスライドで紹介してくださいました。

speakerdeck.com

社員さん、参加者さんの自己紹介

社員さんは4名。
参加者は9名で、プログラミングスクールの生徒さん、独学でプログラミングを学習されている方、現在プログラマーで転職を考えている方などが参加されていました。

KPTワークショップ

KPT(Keep/Problem/Try)とはシンプルで強力なふりかえりの手法です。

(社員さんがすごくわかりやすいスライドでKPTの説明してくださったのですが、そのスライドを見つけられず😹・・・うろ覚えですがこんな感じだった気がします💦)

下記のような3つの要素に分けて現状分析を行います。

  • Keep: 良かったこと(今後も続けること)
  • Problem: 悪かったこと(今後はやめること)
  • Try: 次に挑戦すること(Problemの改善策、Keepでさらに改善すること)

ふりかえりを円滑にすすめるために、以下のグラウンドルールが用意されています。

  • 積極的に話し、参加する
    • 当事者意識を持つ
  • 1人で話しすぎない
    • 発言をさえぎらない
    • 話してない人にも思いあり
  • 原因追求をする。個人の責任追求をしない
    • 罪を憎んで人を憎まず
    • 「人 vs 人」ではなく、「チーム vs 問題」の構図を意識する
    • だから自己弁護も不要

このワークショップでは、最初に「砂漠で遭難したときにどうするか」というコンセンサスゲームを行い、それをKPTで振り返るということをしました。

答えを知っているとゲームがつまらなくなってしまうそうなので、詳細は割愛します🙇

最後は「ふりかえりのふりかえり」としてKPT自体をふりかえります。
自分達のチームはTryが抽象的だったので、具体的な行動に落とし込むといいよと社員さんにアドバイスいただきました。(「時間配分を意識する」だと抽象的なので、「xxさんが、タイムキーパーをやる」まで落とし込む)

社員さんも参加者の方も皆さん優しくて、楽しい上にめちゃ勉強になるという最高の体験でした。

社員さんに質問する会

結構際どい質問にも答えていただきました。書ける範囲で。
(結構失礼なことも聞いてしまった気がします・・・。申し訳ありませんでした🙇)

案件はどれくらい走ってますか?

20程度。一人で2案件掛け持ちすることも。その場合コンテキストスイッチが大変だけど、時間配分は個人の裁量に任されていて柔軟に対応できるようにしている。

デザイナーさんはいますか?

いない。お客さんにデザイナーさんを用意していただくとか、簡単なものならBootstrapとかのCSSフレームワークを使ってプログラマが作ることもある。デザインが得意なプログラマもいる。

社員さん、フリーランスさんの割合はどれくらいですか?

10名ずつ程度。フリーランスの場合は基本2.5日/週から。社員でも2.5日/週を選べる。

参考: 新しい働き方 | 月額制受託開発の株式会社mofmof

コードレビューはしていただけますか?

基本全てコードレビューする。想像以上にやる。研修時には50とかコメント付くこともある。

参考

フロントエンドの技術はなんですか?

Vue.jsがメイン。フロントはSPAでRailsAPIサーバーに徹する案件も。Reactも得意な人いる。jQueryは使ってない。

モダンフロントエンドの知識ない場合、入社してからの勉強でも大丈夫ですか?

ES6の知識なかったが入社してから勉強した。Railsも(事前に勉強したが、)実務未経験で入社した。ただ手取り足取り教えてもらえるわけではないので、自分で学んでいく姿勢が大事。

採用で重視するポイントはなんですか?

技術力/コミュニケーション力/人間性。技術力が高くてもmofmofの価値観と合わないと難しいかも。

参考: 採用面談で失敗してしまいがちな3パターンをまとめた - 毎日がもふもふ

3日でプロダクトを作るなんて可能なのですか?

フル機能を作るわけでなくMVPを作るので可能。MVP(Minimum Viable Product)と呼ばれる実用最小限の製品を作り、ユーザーに価値を提供できているか仮説検証を行う。DropboxのMVPはデモ動画だった。

参考: イキナリ!MVP

(結構思い込みで補完してしまっている気がします・・・💦ミートアップが定期的に開かれているそうなので、正確な情報はその時に聞いていただけると幸いです🙇)

感想

めちゃ楽しかったです!

mofmofさんは企業ブログや社長さんのブログ等、アクセスできる情報が充実しているのでだいたいどんな会社なのかイメージできていたのですが、イメージそのままでした。
技術が好きで、ものづくりが好きで、優しい会社さんです。
社員さん皆さんから優秀さと優しさが滲み出てました。

帰り道で他の参加者の方達と本音トークさせていただきました。
「めっちゃ良い」、「絶対行きたい」、「うちの会社とぜんぜん違う」等、自分も含めてみんなmofmofさんの虜になってる感じでした。

mofmofさん、参加者の皆さん、楽しいイベントをありがとうございました!

プログラミングスクールで、「リアルバーチャルYoutuber」というWebサービスを作りました

f:id:nekorails:20190910041229p:plain

はじめに

(まだまだRails勉強中の身で、至らない点も多いと思います💦よろしくお願いします🙇)

FJORD BOOT CAMP(フィヨルドブートキャンプ) というプログラミングスクールの最終課題で、自作のWebサービスを作りました。
本記事はWebサービスの紹介と開発日誌のまとめです。

作ったWebサービスの紹介

リアルバーチャルYoutuber」は、AIが生み出した実在しない人物の顔を、AIによる顔合成技術でユーザーの顔に合成することで、顔を匿名化するWebサービスです。

f:id:nekorails:20190910040516g:plain

f:id:nekorails:20190910040519g:plain

ユーザーは、ベースとなる動画をアップロードして、用意された実在しない人物の顔モデルを選ぶことで、その顔になることができます。

f:id:nekorails:20190910192547g:plain

f:id:nekorails:20190910192553g:plain

実写Youtubeをしたいけれど顔出しはしたくない、といった方達に使って頂けると嬉しいです。
Rails + Herokuで作られていて、開発期間は2週間ほどです。
利用は無料で、ソースコードOSSとして公開しています。

サービス: https://realvtuber.shita1112.com
ソースコード: https://github.com/shita1112/realvtuber

開発日誌

以下、開発時にやったことのまとめです。
フィヨルドブートキャンプ生のような、初めてWebサービスを作る方達に読んでいただけると嬉しいです。
次回Webサービスを作る時用の備忘録も兼ねているので、リンク多めです。ご了承ください🙇

Getting Realを読む

まず最初にフィヨルドブートキャンプでサービス開発の教科書としておすすめされた Getting Real を読みました。(たしか翻訳もあったはずですが、なぜか検索しても見つかりませんでした💦すみません🙇)
Rails作者のDHHさんのいる会社「BaseCamp」の社長が書いた文章です。
サービス開発する際に大切なことがたくさん書かれています。
サービス開発で悩んだ際は、この本に立ち返りつつサービス開発を進めていきました。(とはいえサービス開発の哲学が凝縮された本なので、まだ消化しきれていないことが多いのですが・・・。)

今後も何度か読むことになりそうです。

エレベーターピッチを作る

エレベーターピッチとは、投資家さんとエレベータで30秒だけ一緒にいられる場合に、短い時間でサービスの本質を伝えるための文章です。
趣味の個人開発の場合でも、エレベーターピッチを作っておくとプロダクトの「解決する課題」や「ターゲット」等を自分の中で整理でき、「本当に必要な機能」と「必要ない機能」を実装前に知ることができます。
あと、それをメンターさんたちと共有できます。

エレベーターピッチのテンプレートはいくつかパターンがあるようですが、フィヨルドブートキャンプで使っているのはこんな感じです。

サービス名 というサービスは、
解決する問題 を解決したい
このサービスを使うターゲット 向けの、
サービスのカテゴリーです。
ユーザーは このサービスでできること ができ、
競合サービス とは違って、
差別化要素 が備わっている事が特徴です。

自分の場合はいくつかぼんやりしたWebサービスのアイデアがあったのですが、自分で一人では考えをまとめられなかったので、一度エレベーターピッチにしてメンターである@komagataさんと@machidaさんのレビューを受けることにしました。

作ったエレベーターピッチは以下の4つです。

リアルバーチャルYoutuber というサービスは、
Youtubeで実写動画を作る際に、顔を出さなければいけないという問題 を解決したい
Youtubeで実写動画を公開したいけど、顔出しはしたくない人 向けの、
動画の顔の匿名化ツールです。
ユーザーはAIで生成された実在しない人物の顔を、AIによる顔転写技術を使ってユーザーの顔に転写することで、ユーザーの顔を実在しない人物の顔に置き換えることができ、
バーチャルYoutuberとは違って、
実写に使えます。

Readme翻訳 というサービスは、
Gemを利用する時に、英語が苦手なためReadmeを読まないという問題 を解決したい
英語が苦手なRailsプログラマ(=自分) 向けの、
英語技術文書のリーディング支援ツールです。
ユーザーはReadmeの隣に表示されるGoogle翻訳の結果を読み、日本語で大意を掴むことで、Readmeを読む負担を減らすことができ、
日本語に翻訳(chrome内蔵のGoogle翻訳機能)でReadmeを読む 場合とは違って、
Google翻訳を原文を読むための補助として利用します。

Tsukutte(ツクッテ) というサービスは、
技術力UPとポートフォリオ強化のためにWebサービスを作りたいが、作りたいものがないという問題 を解決したい
Webエンジニア 向けの、
マッチングサービスです。
依頼者は自分が作って欲しいWebサービスの内容をTsukutteに書き込み、開発者は書き込み内容から作りたいWebサービスを選んで開発することができ、
クラウドソーシングでWebサービスの開発を依頼/開発する場合 とは違って、
無料なので依頼者/開発者ともに気楽に使えます。

Readch(リードック) というサービスは、
英文のEPUBやPDFを読む際に、英文リーディング用のChrome拡張(Mouse Dictionary等)を使えないという問題 を解決したい
英語が苦手なRailsプログラマ(=自分) 向けの、
洋書の技術書のリーディング支援ツールです。
ユーザーが英文のEPUB/PDFをサイトにアップロードすると、HTMLに変換されてレンダリングされるので、Chrome拡張を使って読むことができ、
EPUP/PDFをHTMLに変換するWebサービス とは違って、
HTMLをダウンロードせずに、サイト上で読むことができます

フィヨルドブートキャンプからのアドバイスで、エレベーターピッチを作る際には以下の2点に気をつけました。

「自分の課題を解決するサービスにする」
自分の課題を解決するサービスだと、ターゲットが自分になり普段痛みを感じている具体的な課題から始めることが出来るので、課題の質を上げられます。
あと必ず自分は使うので、個人開発でありがちなユーザー数0という悲劇を避けられます。(このパターンは本当に多いそうです。)

CGM(Consumer Generated Media)型ではなくツール型にする」
CGMだとそもそもユーザーやユーザー投稿が集まらないと始まらないので、避けたほうがいいそうです。
ツール型なら過疎っていてもとりあえず自分は使えるので安心です。

@machidaさんや@komagataさんに相談しつつ、最終的にはツール型でポートフォリオとして面白がってもらえそうな「リアルバーチャルYoutuber」を作ることに決めました。

参考

技術検証

フェイススワップ(ディープフェイク)というDeep Learningを用いた顔転写技術とこの生成技術で今回のプロダクトを作れそうと思いましたが、自然な出来になるのか心配だったので先に検証しました。

最初の試作動画はこんな感じです。

f:id:nekorails:20190910020508g:plain

少し顔が崩れていますが、改良すればなんとかいけるかなーと判断して開発を始めました。

いくつか調整を重ねて、今はもう少し質が上がっています。

f:id:nekorails:20190910015744g:plain

ペーパープロトタイプを作る

作るもののざっくりとしたUIを書くことで、必要な機能やUIの検討ができます。

自分はこんな感じで作りました。

ログイン前の画面4つ

f:id:nekorails:20190910002337j:plain

ログイン後の画面4つ

f:id:nekorails:20190910002403j:plain

ここでもメンターさん達にレビューしていただき、そもそもログインはいるのかー?等をつめていきました。

参考

技術選定とシステム構成図の作成

技術スタックはこんな感じです。

  • バックエンド: Rails
  • フロントエンド: Vue.js + Webpack(Webpacker) + Material Design for Bootstrap 4
  • インフラ: Heroku + S3 + CloudFront + MySQL

バックエンドはちょうどRails6がリリースされたタイミングだったので、Rails6で作りました。
gemが対応できているか少し心配でしたが、特に問題なく開発できました。

フロントエンドはVue.jsの勉強をがっつりしたばかりだったので、経験を積むためにVue.jsを選びました。(でも結局JS側のコードはあんまり書きませんでした😹)
CSSフレームワークにはMaterial Design for Bootstrap 4を採用しました。

インフラはHerokuを採用しています。
CDNはHerokuのFastlyアドオンを使うと簡単にできるそうなのですが、価格面を考慮した結果CloudFrontを採用することにしました。

システム構成はこんな感じです。

f:id:nekorails:20190910002900j:plain

動画作成でDeep Learningを使うので、GPUサーバーが必要です。
しかしAWSGCPGPUサーバーを使おうと思うと、GPU1つで数万円/月もかかってしまい、とても運用できません💦
たまたま自宅にGTX 1080 Tiが4枚あったので、自宅でGPUサーバーを組んで運用することにしました。
GPUサーバーにもコードを置いて、そこでJobワーカーを動かします。

あとこの図だとassetsをS3に置いていますが、 @komagata さんにassetsはS3に置かずにHerokuから配信すればいいよーとアドバイスいただいたので、今はHerokuからassetsを配信して前段にCloudFrontを置くように変更しています。

開発の進め方を考える

タスク管理にはGithubプロジェクトを利用していました。
しかし途中から面倒になってしまい、 Emacsのorgモード で管理するようになりました。
(orgモードはMarkdown相当の機能にTODO管理とかの便利機能を色々詰め込んだ感じのものです。)

ワークフローはOSSなのでちゃんとしたほうがいいのかなと思い GitHub Flow と呼ばれるものを使っていました。
しかしこちらも途中から面倒になってしまい、結局masterに直接commitするようになりました。

$ rails new

ここまでで開発の準備ができたので、ここから実際の開発を進めていきます。
$ rails newRailsアプリを作成します。この際に--skip-xxxxオプションを使うと不要な機能を外してくれるので便利です。

$ rails new realvtuber --skip-test --skip-turbolinks --skip-active-storage --skip-action-cable --skip-action-text --skip-action-mailbox --webpack=vue --database=mysql

テストはRSpecを使い、ファイルアップローダーはActiveStrageの代わりにCarrierWaveを使うのでskipしました。
あとVue.jsやMySQLを使う場合はここで指定しておくと、自分で設定する手間を省けます。

Herokuをセットアップ

PaasにはHerokuを利用しました。

参考

独自ドメイン設定 + SSL

Herokuアプリを作ると「サービス名.herokuapp.com」ドメインが割り当てられます。
これを利用してもいいのですが、せっかくなので独自ドメインお名前.com で取得して設定します。

実はこのアプリを作る前に「Readme翻訳」というサービスを開発をするために独自ドメインを取得したのですが、結局諸事情で開発が中止になってしまいドメインだけが手元に残ってしまいました。
とても悲しかったので、その教訓から作ったWebサービスが誰からも使われなくてさみしい問題を解決する(しない)意識低い方法論 を参考にさせていただいて、サブドメインで運用することにしました。

Herokuで独自ドメインSSL化するのは若干面倒でしたが、以下の記事等を参考にしてなんとかいけました。

参考

ルートドメインを設定する場合にも、PointDNSというアドオンを使えば無料でいけます。

参考

SendGridをセットアップ

メール配信にはSendGridアドオンを利用します。
無料枠が大きいので、個人開発の場合は無料枠に収まることが多そうです。

参考

S3 + CloudFrontをセットアップ

Herokuにはファイルを置けないので、ファイル置き場としてS3を用意します。
あと配信速度を上げるためにCDNとしてCloudFrontも一緒に利用します。
S3の前段にCloudFrontを置くイメージです。
CloudFront + S3 によるCDN (Cache Distribution パターン) 構築手順 を参考に設定すればいけました。
特に難しい箇所もなく、基本的にはデフォルト設定でOKです。

assetsの配信でHerokuの前段にCloudFrontを置く場合は、Rails側の設定も必要になります。
特にWebフォントを使用するためにはCORS対応が必要になり、そこでハマりました。
以下のサイトが参考になります。

Googleアナリティクスをセットアップ

アクセス解析を行うために、Googleアナリティクスを導入しておきます。

参考

Googleサーチコンソールをセットアップ

サイトの検索キーワード等を調べるために、Googleサーチコンソールの設定を行っておきます。

参考

ロゴ・ファビコンを作る

ロゴはWebで使えるデザインツールのCanvaで作りました。

f:id:nekorails:20190910004423p:plain

こんな感じでフォントを最大サイズにして、フォントパワーに全てを託します。

あとは色を反転させたものをファビコンとして使います。
ファビコンはこちらのサイトで作れます。

参考

サイトマップを自動作成

サイトマップGoogle等の検索エンジンにサイトの情報を伝えることで、インデックスを促します。
sitemap_generatorというgemを使い、リリース時にサイトマップを自動作成するようにしておきます。

参考

metaタグを設定する

SEO対策としてtitle等のmetaタグを設定できるようにします。
meta-tags というgemを利用しました。
必要な部分だけ各ページで上書きできるので、メンテしやすくてよかったです。

参考

Rubocopを設定する

Rubocopを使い、コーディング規約を強制します。
Rubocopのデフォルト設定は(Ruby Style Guide通りなのですが)ルールが厳しめで守るのが難しいので、少し緩くしたいです。
@onkさんがいい感じの設定をgemにまとめてくださっているので、そちらのonkcopというgemを利用します。

# Gemfile

group :development do
  gem "onkcop", github: "shita1112/onkcop" # onkcopがrubocop最新版に対応していないようなので、一時的にforkを使う
  gem "rubocop"
  gem "rubocop-rails"
  gem "rubocop-rspec"
end
$ bundle install

FrozenStringLiteralの設定を追加しておきます。

# .rubocop.yml

inherit_gem:
  onkcop:
    - "config/rubocop.yml"
    - "config/rails.yml"
    - "config/rspec.yml"

AllCops:
  TargetRubyVersion: 2.6
  Exclude:
    - "bin/bundle"
    - "node_modules/**/*"

Style/FrozenStringLiteralComment:
  Enabled: true

rubocopコマンドの--auto-correctを使うとルールに合わせて機械的に変換してくれるので、使っておきます。

$ rubocop --auto-correct

参考

便利Gemを導入する

開発する際に便利なGemを先に導入しておきます。

bullet

N+1の検出ができます。

letter_opener

developmentモードで簡単に送信メールの確認できます。

letter_opener_web

letter_openerのwebインターフェースです。

xray-rails

どの部分がパーシャルか、画面上に表示してくれます。

pry-rails

binding.pryブレークポイント仕込めます。

pry-byebug

binding.pryでステップ実行できます。

pry-doc

Cで書かれたRubyソースコードを表示できます。

pry-alias

binding.pryの代わりにbpでいけます。

awesome_print

pppより出力が綺麗なapが使えるようになります。

tapp

レシーバをputsしてくれるtapです。デバッグで利用します。

[1, 2, 3].tapp(&:size)
3
=> [1, 2, 3]

rack-mini-profiler

簡易的なパフォーマンス測定として、ページ左上にレンダリング時間を表示してくれます。

newrelic_rpm

パフォーマンス測定できるNew Relicというサービスを利用できます。Herokuのアドオンとして基本機能は無料で使えます。

enum_help

Rails標準機能のenumi18n機能を追加してくれます。

config

環境毎に定数管理できます。

gon

Rails側からJS側に変数を渡せます。

browser

ブラウザ/デバイスの種類を判定できます。スマホかどうか調べるのに利用します。

devise

認証。カスタマイズが難しく避けられがちですが、今回はビューの変更だけで済みそうだったので利用しました。

pundit

認可。リソース毎にファイルを作るので、cancancanより好みです。

active_decorator

デコレータ。自動的にデコレートしてくれるので、draperより好みです。関連先もデコレートしてくれるようになっていました。

carrierwave

ファイルアップローダー。たしかActiveStrageにはキャッシュとバリデーション機能がまだなかったはずなのでこちらを利用します。

Railsを日本語化

設定を変更して、タイムゾーンとlocaleを日本向けにします。

# config/application.rb

+    config.time_zone = "Tokyo"
+
+    config.i18n.default_locale = :ja

日本語のロケールファイルはこれを利用しました。

利用規約・プライバシーポリシーを作る

フッターに置く利用規約とプライバシーポリシーを作成します。
何を書けばいいのか全くわからなかったのですが、フィヨルドブートキャンプの先輩方のサービスを参考にさせていただきました🙇

あと今読んでいる途中なのですが、【改訂新版】良いウェブサービスを支える 「利用規約」の作り方 が利用規約を置く意義等が丁寧に書かれていてとても参考になります。

PageSpeed Insightsで表示速度を測定する

Railsアプリが一通りできたらPageSpeed Insightsで表示速度を測定します。
PageSpeed Insightsはサイトの表示速度を測定した上で、遅い場合には改善策を提示してくれます。

測定してみるとリアルバーチャルYoutuberはパソコンが98点、モバイルが89点でした。 f:id:nekorails:20190910005453p:plain f:id:nekorails:20190910005528p:plain

「合格した監査」を見てみると、画像を適切なサイズで配信できていることや、CSS/JSをminifyできていること等を確認できます。 f:id:nekorails:20190910014533p:plain

「改善できる項目」を見てみると、「次世代フォーマットでの画像の配信」を改善すれば速くできることがわかります。
この場合はWebp対応ブラウザにWebpを配信すれば速くできそうです。 f:id:nekorails:20190910005622p:plain

@machida さんによるデザインレビューを受ける

メンターでデザイナーの@machida さんにデザインレビューをしていただきました。

こちらがもともとのデザインです。
作成した動画をリストとして並べています。 f:id:nekorails:20190910195520p:plain

次がレビューを元に修正したデザインです。
作成した動画をカードとして並べることで、前のデザインよりスッキリして見えます。
あとh1タグはただでかい文字が置かれているだけだったのですが、別ブロックを作ることで見やすくなりました。

f:id:nekorails:20190910195443p:plain

他のページもかなり丁寧にレビューしてくださいました。

普段デザインのことはあまり考えていなかったので、デザインはとても苦労しました。
開発のかなりの時間をデザインに使ってた気がします。

なのでプロのデザイナーである@machidaさんにアドバイス頂けたのはとても助かりましたし、勉強になりました。

@komagata さんによるコードレビューを受ける

リリースを優先させてテストコードがおざなりなので、これからテスト書いてレビューしていただきます。

さいごに

謝辞

メンターとして相談にのってくださった@machidaさん、@komagataさん、毎週の進捗報告会に付き合ってくださった@matt59649858さん、@tararicoさん、@wai_doiさん、フィードバックをくださったフィヨルドブートキャンプの皆さん、唐突なお願いにも関わらず動画提供や戦略面でのアドバイスなど親身になって協力してくださったYoutuberの@fujishuuさん、@Layer_Qさん、皆さんのおかげでなんとか完成させることができました。本当にありがとうござました🙇

あとうちのお猫様には開発中も癒やされました。ありがとうございました😺 f:id:nekorails:20190910011444j:plain

(完成祝にちゅーるあげました)

Railsのお仕事探しています🙇

これでプログラミングスクールが完了になるので、これからお仕事探しを本格的に始めます。
もしRailsプログラマ探してるよーという方がいましたら、自分の経歴をまとめたのでこちらを見ていただけると嬉しいです
よろしくおねがいします🙇