valid,invalid

関心を持てる事柄について

now = ohbarye.hired_at.since 2.years

「転職が成功か失敗か決まるのは(退職|転職)エントリを書いた時じゃない、入社から半年経ってからだ」とうそぶきつつ大した振り返りもせず早2年…

というわけで Quipper に転職してちょうど2年が経過したので自身のことを中心に振り返ってみる。

2年前

思えばよく採用されたな…と思う、タイミングが良かった。現在は採用のハードルが上がっているので今の Quipper に2年前の俺が応募したら不採用になるだろうなと思う。これはチームの成長の証左でもあるので良いことだ。

転職まで

当時の俺はSIer (システムインテグレーター) に勤務する新卒3年目の SE (システムエンジニア) で、1年目はちょっとした Java の研修というトンネルを抜けるとそこはテスト仕様書と人力テストの国…。技術力を高めたいと主張して色々仕事を振ってもらってもコードを書く時間は半分も無かった。日曜プログラマとしてたまにコードは書いていたが自分の業務を少し助けるものか、ちょっとしたおもちゃを作ってばかりだった。原点…と呼べるかすら危ういこの環境、とても狭い世界で、小さなプログラムと大量の仕様書を書いていた。

学校という環境設計の中で生きていけないという諦念とともに教員の道を辞した人生をどこかで清算したいと思っており、こうした信念と実にマッチした Quipper と比肩する候補はその時は存在しなかった。今も存在しないかもしれない。

採用が決まってから

これまでの自分のスキルが全く通用しない世界に飛び込むのだと思ってとにかく焦った。

あまりに焦ったので「入社までに何を勉強すれば良いでしょうか」と正直に聞いた。その時に刺身さんが返してくれた内容は「これは報いないといけない」という思いともによく覚えている。

2015年の8月は業務をさっさと終わらせて家に帰ってはアドバイスに従って Quipper で使う予定のテクノロジーと英語をほぼ毎日勉強し、何かしら形にしておきたいとブログを書いていた。完全に忘れていたが2015夏タグが付けてあったので今でも読み返せる。

転職直後

絶対プルリクキメ太郎と気張っていった初日、"予習"の甲斐あってかなんとかキメられた。最初のpull requestが"要らなくなった機能の削除"だったのは不思議な気持ちだった。それまでコードをちゃんと消すチームでの開発をほとんどしてこなかったのだ。

このとき、GitHub flow も pull request ベースの開発もCIも staging app も何もかもが新しかった。

詳細は割愛するが入社してから暫くは受験サプリというプロダクトを Quipper のコードベース上に migrate する大掛かりな移行プロジェクトをやった。日本の web engineer は当時5人のみで、終わるかどうかとてもあやしい量のタスクがあった。2015年末頃には振り返れば炎上と言って差し支えないほど働いていた。

前職のデスマーチ案件よりは稼働時間は少なかったのと、とにかくコードを書くことだけに集中できたので当時はそれほど苦に感じなかった。土日に出勤してテスト項目をひたすら消化していた頃に比べれば何もかもが遥かに良かった。ただ、もう一度やれと言われたらやりたくはない。

このプロジェクトが終わってからは一度も休日出勤はしていない(はず)。

それから

あっさり2年が経ってしまった。

チームは数倍の大きさになり、その中で俺は今年度は Engineering Manager という役割を担うことになった。Quipper の Engineering Manager は世間一般でいうテックリードとも(プロジェクト|プロダクト)マネージャーとも違うところにあって、卓越した技術力とかずば抜けたマネジメント能力が求められるものではないと考えている。組織やプロダクトといった大きい主語の実存に対して物言いたい人が集まっている立場の気がする。

そう、Engineering Manager という役割につき、チームに貢献するメンバーとして一人前の自覚はありながらも、いちエンジニアとして俺はどんな奴なんだ?どうありたいんだ?と今でも問い続けている。

先月にメキシコの Engineering Manager が日本に訪れた際に俺のキャリアについて聞かれることがあった。その時に「実のところ俺が “real engineer” としてのキャリアをスタートしたのは Quipper に入ってから。つまりまだほんの2年前なんだ」という話をした。

いったい何が “real engineer” なのかは言った俺にもわからないのだが、確かに言えるのは前職の俺は “SE” であってエンジニア*1ではなかったということだ。今は自分が信じるエンジニア像に少しは近づいた…はず。

エンジニアとしてどう変わったか

この2年間は、かつて担当していた小さな業務システムでは深く考えなくてもそれなりにやれていたことを何回も何倍も真剣に見つめ直したし、数え切れないほど新しいことも獲得した。例えば…

チーム開発の基礎。GitHub flow とレビュー。レビューしてもらいやすい pull request とそうでないものの差異。誰かと一緒にあるいはチームでコードを書くということ。コードレビュー会。可読性。リファレンスの貼り方。Excel方眼紙ではないドキュメンテーション

パフォーマンスのこと。N + 1 クエリがサービスに及ぼす影響、防ぐ方法、万一混入した場合でも見つけられるようなパフォーマンスモニタリング。データベースの特性とそれに応じた実装。富豪的計算をしすぎない。

キャッシュ。強いキャッシュと弱いキャッシュ、それぞれの実現方法。データの更新頻度、転送量の削減。

Single Page Applicationのこと。Backbone.js + Marionette.js に始まってReact.jsへの変化・移行。メリットとデメリット、選ぶべきときとそうでないとき。

デザイン。ユーザー目線とは。ビジュアルではなく体験にこだわること。どうやってデザイナーと協業するか。

API設計。SPAのバックエンドとして見た時の、REST・RPCそれぞれのメリット、デメリット。ステートレス。ページング。あるいはネイティブアプリのバックエンドAPI設計。後方互換性。

外部システムとの連携インタフェース設計。冪等性とリトライのこと。大量データの捌き方。

テスト。ユニットテストやフィーチャーテストがいかに開発に安心感を与えるか。E2Eテストの重要性と難しさ。テストは実装の最初の再利用、つまりテストが書きにくければ設計が悪いということ。

リリース。小さく繰り返すことの重要性。ユーザーの驚きを減らす。バグはすぐ直す。でかすぎる feature branch は作らない。コードの変更なしに feature toggle できると理想的。

データ分析。BigQuery や TreasureData のこと。イベント設計に失敗すると分析が活きない。イベントトラッキングの発火タイミングのコントロールに気をつける。データがあって初めて見えるユーザー像もある。A/Bテストの設計と実装、振り返り。

アーキテクチャ。複数アプリケーション、複数データベースがいかに複雑か。アプリケーション間の依存関係の整理がいかに大事か。web サーバとアプリケーションサーバでできること・できないこと。

採用のこと。自分たちのことをよく知らないとできない。短時間で候補者のことを最もよく知るための質問とは。コードテストの評価の仕方。

グローバル。英語。相変わらず今でも手こずっている。ハチャメチャでもひどい発音でも通じるが、それは相手の善意によってコミュニケーションが成り立っているから。リモートだからこそ気にすべきコミュニケーションのやりかた。マーケットの特性。localization、internationalization。

カスタマーサポート。日々ユーザーと直に接しているメンバーからプロダクトへのフィードバック。使いづらい機能やバグをリリースしてしまったときのゴメンナサイ感。

受託ではなく自社のプロダクトをやっていくということ。ユーザーフィードバックのありがたさとつらさ。競合への意識。

思いつきで書きなぐっただけでもこれだけのことを2年前の自分はほとんど知らなかった。

生活の変化

裁量労働制になり10時どころか11時出社も危うい体となってしまったがライフスタイルを自由に構築できるので、妻と京橋でランチしたり早く帰ってジムに行ったり銭湯に行ったり出社前に家で英会話レッスンを受けたり走ったり自宅近くでランチしたりできる。

福利厚生・給与

書籍購入やカンファレンス参加費を社費でまかなってもらえる。それぐらい当たり前、という風潮があるが前職ではまったくもって当たり前でなかったのでありがたい。

ダメ元で頼んだら会社に懸垂台と卓球台を置いてもらえたのもありがたい。

給与は転職時の1.8倍ぐらいになったのであまり不満はないが良ければもう一度1.8倍してほしい。

これから

勤続年数でいえば今のチームでは相対的に古株ぽくなってしまった。もろもろ聞かれたり答えたりするのは全然構わないのだが、ドメイン知識以外のところでもっと勝負したいとかいう気持ちがある。1つの技術や言語に精通している感覚が未だ持てていないことに強い課題意識を感じる。

Be the worst の精神を忘れたくない、技術系のコミュニティから刺激を受けたいという思いもある。直近では勉強会やカンファレンスでの登壇や週1~2での副業を積極的にやってみるというのも卑近な方法だろうか。

今年度になるまではサービスの基盤を作るためにやらなければならない山積みの仕事を終えた今、ようやくエンジニアとしてやりたいことを提案したり挑戦したりするフェーズが来ているなと感じている。だからこそインプットとアウトプットにこれまで貪欲になろうとしているのかもしれない。

中期的には日本国外に居住したり、教育以外の事業領域も体験してみたい。だが、最終的にはやはり最強の教育サービスを作ってみたい。

結論

冒頭で"転職が成功か失敗か"という表現をしたけれども、実際にはその2択ではなく「成功ぽい」「失敗ぽい」というようなグレーゾーンが大半を占めるはず。

俺にとってはどうだったのか諸々考えてみたけれど、2年前に戻ってやり直せるとしても同じ転職を選ぶんじゃないかなぁ…。これは限りなく成功に近い転職と言えるだろうか?

*1:ここでは"エンジニアリングに関する専門的な技術を持った実践者"という意味

"kill N + 1 queries" Tシャツ作った

絶対に殺すという強く熱い"想い"を"カタチ"に。

仕上がり予想図

f:id:ohbarye:20170910153032p:plain

ロゴ

白黒両方作って試してみた。

f:id:ohbarye:20170910153028p:plain

反転していると見づらい。

f:id:ohbarye:20170910153035p:plain


加工代や送料込みで4,000円弱かかった。前は2,000円ぐらいで作れた気がしたのだが気のせいか?

(追記) 9/16に届いた。

automaildoc gem でメール一覧と文面を自動生成する

RSpec からメール一覧を自動生成する gem を書いてみた。

github.com

使い方

gem を install したのちコマンドラインから AUTOMAILDOC=1 rspec を走らせるとメールを一覧表示するHTMLを生成する。

https://user-images.githubusercontent.com/1811616/29994112-c6dacbc6-9002-11e7-812f-a346d415d6c4.gif

名前も設計もほとんど autodoc を参考にしている。

背景・課題

「法務・ブランドチェックが入るのでメールを確認したい」

「新たに送信するメールの文面考えるので類似メールの文面見られますか?」

「この前もらったメール文面のプレミアムユーザー版だとどうなりますか?」

プロダクトマネージャーやビジネスサイド、カスタマーサポートなどのステークホルダーからのこうした問合せには、開発者がコードや I18n の翻訳ファイルを見たりしつつ都度回答してきた。

しかしA/BテストやCS要望のために少なくない頻度で内容がアップデートされたり、日々の開発で気づかないうちにメールが増えたり減ったりするし、同じメールでもコンテキストに応じて変わる内容を追従できていなかったりと諸々問題がありそうだった。

この課題に対する解決策として同僚の yuya-takeyama さんが autodoc みたいに RSpec から自動生成したら便利なのではというアイディアを出し、tanaka51 さんが 20 percent policy 的な時間でプロトタイプを作ってくれていた。7月に tanaka51 さんが退職されて以降この課題が放置されていたのだが再度「メール一覧見たい」という要望を受けた際にこれを思い出してガッと gem 化してみた。

HTMLメールがきちんと表示されない問題があるが近日中に直す。version 0.1.3 で表示されるようにした。

現状

会社のレポジトリに automaildoc を突っ込んで「こんなのできますがどうですかね」と [RFC] ラベル付き pull request を投げてみたところ「やってみましょう」と即マージされた。ありがたい。

課題

生成されたHTMLをどう共有するか

秘匿性の高いものはまた別のやり方が必要だが、/doc/mails/toc.htmlGitHub pages で公開するのが最も簡単そう。

定期的に更新する仕組み

全部コマンドラインで完結するので Jenkins などで定期的に生成して pull request を自動で push すると良さそう。

個々の開発をフックにするなら Git hook が使えそう。pre-commit hook で変更されたファイルをチェックし、 mail spec や翻訳ファイルに変更があれば rspec を走らせてドキュメントを自動生成する…と書いていて思ったが結構面倒くさそう。

mail ごとの rspec を書かないといけない

ツールに合わせた開発はしたくない。が、request spec と違って mail spec 自体に込み入ったロジックや fixture を用意するケースはほとんどなく、もともとさらっと書いてあれば導入の費用対効果は悪く無さそう。

感想

運用やめたら「automaildoc やめた」という記事を書きます。

Gem の install / uninstall フックの使い方

Git hook を手軽に管理できる huskyRuby 版が欲しいかもと思い最近 rusky という gem を作っている。

github.com

gem install 時に Git hook スクリプトを自動生成し、uninstall 時には勝手に消してくれる感じにしたい。そんなわけで gem のインストールフックの使い方を学んだ。

知ったこと

走らせたいフックを rubygems_plugin.rb というファイルに定義する。rubygems_plugin の話は Plugins - RubyGems Guides あたりに書いてある。

# lib/rubygems_plugin.rb
require 'rubygems'

Gem.post_install do |installer|
  # whatever you want
end

Gem.pre_install do |uninstaller|
  # whatever you want
end

使えるフックは module Gem - Documentation for Ruby 2.4.0 あたりを参考にする。

これらのフックを gem_name.gemspec ファイルに書いても動くようだが、一部環境では動かないようだ。

ハマっていた問題

こんな Gemfile を書いて色々テストしていた。

# test-repo/Gemfile
source 'https://rubygems.org'

# it doesn't work
gem 'rusky'

# it works
# gem 'rusky', path: '/Users/ohbarye/.ghq/github.com/ohbarye/rusky'

# it works
# gem 'rusky', github: 'ohbarye/rusky'

同僚の松島さんに使用例を教えてもらった

見比べて何が足りないかと思えば rubygems_plugin.rb 内で require 'rubygems' していなかったのが原因らしかった。足して見たところうまく動いた。とはいえ、うーん、require しないとこのへんで定義してるメソッドが読まれない?Gem class のこととかよくわかっていない。また、なぜ path や github オプションの指定ではうまく動くのかもわかっていないので時間あるときにコードを追いたい。

現状

手元のテスト用レポジトリでは上記のどの Gemfile の書き方でもうまく動いているようだ。

8月はOSS活動をそれなりに頑張った

過去に作った kpt-bot を omoiyari.fm で紹介いただいたのをきっかけにモチベーションが上がり、8月はOSS活動を普段より頑張ってみることにした。

lean-agile.fm

目標

  • 週1で何らかの OSS プロダクトに Pull Request を投げる
  • 20 stars ぐらい集めるような"何か"を作る
  • 毎日コードを書く

進捗

Pull Requests

8月に出した Pull Requestsは8本で、数で言えば達成できたが内容はドキュメント更新ばかりでやや物足りない。普段から息を吸うように活動してる人はやはり尊敬する…。

作ったもの

github.com

ohbarye.hatenablog.jp

20 stars 届かず無念。とはいえ仕事でも役に立つものが出来てよかった。

毎日コードを書く

Write Code Every Day… とは違うルールだけどアクティビティ上は達成できたようだ。

その他

8月中に完成しなかったけどもちょっとした gem を作ってみたり。

感想

ちょっとした修正は GitHub の Web UI 上で完結するので便利だなァと今更思うなどした。

コントリビュートできないかと粗探しをした結果、副次的にライブラリのコードをよく読むようになった。

オープンソースの粗探し(?)に慣れると業務で触るコードも粗だらけに見えてきて最近は前よりボーイスカウト的な行動もするようになった…かもしれない。

最近の英語学習と、コミュニケーションについて思ったこと

会社では以前より遥かに使う機会が増えており、プレッシャーを感じる…。

リーディング / ライティング

以前は突然 Slack でダイレクトメッセージが来ると心臓が高なったりしたが、最近は流石に即興対応できるようになってきた。

GitHub issues でのやりとりはだいぶ前に慣れたが相変わらず語彙が少ない(Grammarly を有料契約しているので英作文の傾向や語彙数が週次で定量的に把握できる)。ネイティブの同僚のコメントなどから諸々の表現を盗みつつ改善していきたい。

知っているとちょっとかっこいい小手先のテクニックみたいなのは全然学んでいないし使っていない。

リスニング

相変わらず自信が持てないので、重要な 1 on 1 の会話をするときはこんな感じでしのいでいる。

  • 初めにゆっくり話すよう頼む
  • 何回も聞き返す
  • 相手の言葉をそのまま言い返して合っているか確認する

ランチのようなランダムチャットは何が飛んで来るかわからないぶん仕事よりも難易度が高いのだが、自分から話題を振ることでいきなりコンテキストを掴むというスキルを手に入れた。

スピーキング

発音はアメリカ英語に近づけるよう努力している。これはかっこ良さとかでなく聞き手に楽をさせるためだ。

てきとうな例だけど sea と she の発音はアメリカ英語では明らかに違う([s][ʃ])のに sea をカタカナで「シー」と発音すると、聞き手の英語話者は「どっちのことを言っているんだろう」と思う。カタカナの「シ」だと [ʃ] に近いから she だと思うかもしれないし、相手は日本人だからこの音を区別できていないのだろうと思うかもしれない。

いずれにせよ聞き手に負担をかけたまま放置するのはコミュニケーションの悪手だと自分は考えている。伝わればいいとか何も言わないよりとにかく話すのが大事と言ってカタカナ英語を推す言説も聞くが、これはやりたくない。(無論「正しい英語」なんてものは存在しないので自分がどういう英語コミュニケーションをしたいか、というだけの話)

完璧は目指していないのでそんなに力を入れて練習してはいないが、単語の意味を調べる時についでに発音記号を見るとか、基本の発音をすべて知っておくぐらいのことはしている。基本の発音の練習はもっと必要。

この辺の考え方や練習の仕方は英語耳にだいぶ影響を受けた。

amzn.to

レビュー待ちの Pull Request 一覧を Slack に定期的に通知する

review 待ちの Pull Request 一覧を Slack に定期的に通知する仕組みを作ってみた。

完成品

以下の画像は朝11時 JST に自分のチームのレビュー待ちリストを表示している様。Slack の絵文字で「いまレビューしてますよ〜」「merged!」みたいな表現をするのはエンジニアしぐさだ。

f:id:ohbarye:20170826221056p:plain

private repo だと味気ない(かつ業務情報なのでモザイクだらけだ)が、public repo の PR だと Slack が自動的に展開してくれるのでよりファビュラスに見える。

2017-08-11 11 15 31

仕組み

3行で書くと…

  • review-waiting-list-bot という Slack bot が Heroku にデプロイされている*1
  • メンションされると GitHub API を叩いてプルリクエストを収集し、まとめて Slack に post する
  • 定期的に実行する仕組みは Slack のリマインダーを使う

review-waiting-list-bot

github.com

Node.js 製の Slack botフレームワークには前回作った KPT-bot 同様、 Botkit を使っている。

async / await を試してみたかったので Node version 8 にした。残念ながら Botkit が Promise に対応しておらずコールバックを色々書くハメになる*2のだが、GitHubAPI をコールするところはうまくまとめられる。

bot をコールする際に author, owner, repo を指定することができる。-repo のような表記で除外条件(exclusive)を指定することもできる。詳細は README#Usage を参照。

Slack Reminder

bot 側で定期的に post する仕組みも作れるのだがやらなかった。設定を持たないといけなくなる=ステートレスでなくなるし、Slack に慣れているチームなら reminder 機能を充分に使いこなしてくれるからだ。

ちなみに、毎朝11時にリマインドする場合は以下のようなコマンドになる。タイムゾーンはリマインダ作成者の設定に依存するようなので注意。

/remind #channel-name "@review-bot ls author:org/my-team owner:org -repo:design" every weekday at 11am

詳細は Set a reminder – Slack Help Center 参照。

反応

開発者間のミーティングで紹介↓した後、

f:id:ohbarye:20170826225525p:plain

社内の幾つかのチームで使ってくれているようだ。Slack で定期的に呼んでいるチームもあれば daily meeting の最後に手動で呼び出して情報を同期しているチームもある。

フィリピンの同僚から Pull Request を貰ったり、チームでなく個人の活動を拾い上げたりもした。

f:id:ohbarye:20170826224603p:plain

所感

開発者だけでなく Product Manager にも喜ばれたのが意外だった。開発の進捗を把握する一助になるとか。

なんにせよ思ったより使われて良かった*3というのと、社内にユーザーがいるとフィードバックがすぐに貰えてドーパミンが出ますね。

*1:free dyno でも worker プロセスが眠らずに働いているのでいつでもメンションに反応する

*2:https://github.com/howdyai/botkit/pull/278 で試みられたがずっと放置された末に author の心が折れたようだ

*3:前作の KPT-bot が思ったほど奮わなかったのでひとしお