| @労働

今週、 YAMAP でブラウザーでコースタイム付きの地図を表示し、自由に印刷できる機能をリリースした。

地図表示・印刷機能

開発の経緯

ユーザー要望が開発の起点だった。

YAMAP には Google Maps のようにウェブブラウザー上で登山道や登山口情報などを見る機能はなく、無料でダウンロードできる画像形式の地図は提供していたが、以下の課題があった。

  • 磁北線・縮尺の欠如
  • 任意の範囲を切り取っての拡大印刷はユーザー任せ
  • 地図の更新(コースタイム、山頂データなど)には画像データの書き出しが必要(アプリ内で使う地図に比べて更新サイクルが遅れる)

切り取り拡大の課題を解決するためにサポートチームが画像編集ソフトの使い方を教えたり、サポートスタッフ自身が地図を編集・加工して渡すことがあり、非常に負荷が高かった。

Google Maps のようにブラウザーで地図を閲覧できて、任意の範囲を自由に印刷できれば問題が解決するのではないかという見通しがあった。

デモ版を作ってもらって得た気付き

API は既存のものを組み合わせて作れそうだったので、 F/E エンジニアにデモ版を作ってもらった。

デモを使ってみて、地図を印刷するための機能が、ウェブブラウザー上で山の情報を確認し、山行計画を練る際にも便利なものであることに気がついた。

ブラウザーで登山コースを確認できるサイトは他にもあるが、百名山などメジャーな山が中心で、低山や全国津々浦々の里山までカバーしているものはなかった。

YAMAP の強みはユーザーからのリクエストで地図データを更新していくところにある。紙の地図では最低でも一年待たないと更新されない情報が随時更新され、しかも他のウェブサイトや紙地図では登山者が少なすぎて地図化されないような低山の地図まである。今回の機能追加で、そのような豊富な地図がウェブブラウザー上で閲覧して印刷することもできるようになるのだった。

デリバリー

デモ版は数日で出来たが、実際にリリースするまでの道のりが長かった。

先行して磁北線関連の問い合わせてをしてきた一部のユーザーにベータ版として機能を提供して様子をうかがいつつ、エンジニア、デザイナー、カスタマーサポート、経営陣のあいだで利害を調整し、機能、デザイン、使い勝手に磨きをかけた。

エンジニアやデザイナーに、他の仕事を差し置いてなぜこの機能をいま作る必要があるのかをわかってもらうのはとても難しかった。またデモ版のラフなデザインが与える印象が非開発者にはクオリティの低いプロダクトに見えてしまい、調整が難航することもあり、デザインの大切さを実感した。

苦労してリリースにこぎつけたあと、リリースノートを書いて PR 担当に Twitter や Facebook での広報を依頼した。普段の機能リリースよりも少しだけ大きい反響を得られたようだった。

所感

3 ヶ月前にエンジニアからプロダクマネージャーに社内でジョブチェンジしたので、今回のリリースで自分は一切コードを書いていない。初めてプロダクトマネジメントのロールに徹したリリースだった。

エンジニアであれば気にすべきことは自分のことがほとんどで、調子が上がらないときは遅くまで残ってやるとか家に持ち帰ってやるとか色々帳尻を合わせる方法はあった(もちろんいいやり方ではない)。プロダクトマネージャーは自分でコードを書くのではなく、周囲の人の間でもろもろ調整したり働きかけたりが仕事になるので、マイペースでのんびりやってあとで帳尻を合わせるということができない。かといってコミュニケーションを取り過ぎてエンジニアやデザイナーの邪魔をしてもいけない。塩梅が難しい。

もともと自分自身で手を動かしてソフトウェアを作ることが仕事だったから、エディターを開いてもドキュメントしか書かず、何も作ることがない日々に不安はあった。何か機能をリリースしても自分が作ったわけではないという虚しさが訪れるのではというような心配もあった。しかしリリースノートを書き終えたときには、これまでエンジニアとして機能をリリースしてきたときとは別の達成感があった。

プロダクトマネジメントについて書いてある『 Making It Right 』という本に、「プロダクトマネージャーは八つ裂きの刑に処されているようなものだ」というフレーズがある。手足を紐で別々の馬に繋がれて、それぞれ異なる方向に引っ張られるという刑だ。ビジネスサイド、開発チーム、サポート、ユーザーといった様々な人たちの利害を調整し、なんとか落とし所を見つけて説得し、開発チームに納得してソフトウェアを作ってもらう必要がある。リリースする前までは「プロダクトマネージャーつらすぎるだろ…」と思うこともあったが、苦労した分、リリース後の達成感はひとしおだった。

まだまだプロダクトマネージャーとしては新米で至らないところが多々あるが、ユーザー、サポートチーム、開発チームに寄り添いながら、多くの登山者に喜ばれるソフトウェアを届けていきたい。加えて、プロダクトによって山登りのハードルを下げ、まだ山に登ったことはないけれど興味がある、という人達に対して山登りの楽しみを広めていけたらと思う。

| @技術/プログラミング

Hot Chocolate @ Tana Cafe & Coffee Roaster

この記事は CircleCI Advent Calendar 2018 19 日目の記事ですが間に合わず一日遅れて書いております。すんません 🙇🏻

CircleCI を使った Rails アプリのデプロイフローみたいな話を書こうかなと思ったのですが、すでに他の方が書いてる内容とかぶりそうだし、自分自身ブログに過去何回も書いた話なんで今回はエモ方面の話を書くことにします。技術的な情報はないのでそっち方面を期待している方はすんません。


いまの職場で働き始めて 1 年半なんですが、当初は CI はなく、テストコードもありませんでした。いまはそこで当たり前のように CI が回り、テストのカバレッジもまぁまぁ高く、デプロイは CircleCI 経由でじゃんじゃん行われるような状況となっております。新しく会社に入った人も GitHub の Organization に入ってもらえたらその瞬間から deploy 実行できます。具体的な話は昔書いてますのでよかったらご覧下さい。

8 年くらい前の自分はどうやったら CI だとか自動デプロイだとかできるようになるのか皆目見当が付きませんでした。いま 8 年前の自分と同じような状況にいる人(回りにテストを書く習慣を持つ人がいない人、 CI 動かすためにどうすればよいかわからない人)に何か言いたいと思い筆をとりました。

まずは何はなくとも頑張って一つテストケースを書いてみましょう。最初からカバレッジ 100% とか目指さなくてもよいです。どれか一つ、テストが書きやすそうなコードを見つけてテストを書き、ローカルで実行してテストがパスするのを確認しましょう。テストファーストとかも最初から目指さなくてよいです。

手元でテストが通ることを確認したら、 CI 環境でもテストを実行できるようにしましょう。

昔は Jenkins しか選択肢がなく、 Jenkins が動く環境をセットアップする(サーバーを調達する、 VPS を借りてもらう、などなど)に社内調整が必要でしたが、 CircleCI ならプライベートリポジトリでも 1 プロセスなら無料で使えますので社内調整が非常に楽です(外部にコード出してはダメな職場だと厳しいですね…)。

最初にプロジェクトを追加して言語を選ぶと設定ファイルが自動生成されるので、それをコピペして .circleci/config.yml として保存し、リポジトリにコミットするだけでとりあえずビルドが実行されるようになります。

昔は難しかった CI 環境構築のうち、お金の問題、設定の難しさの問題を CircleCI は解決してくれます。あとはあなたが頑張るだけです。

CircleCI ならビルド終了ごとに結果を Slack などチャットシステムに通知させることができます。まずはテストケースが一つでもよいのでリポジトリへの push をトリガーにビルドが実行されたら結果を Slack に通知してみましょう。

CircleCI Slack Notification

CircleCI Slack Notification

リポジトリに GitHub を使っているなら Pull Request にビルド結果が表示されるようになるはずです。

CircleCI GitHub Build status

これらで「なんかようわからんけどやっとる感」を出していきましょう。

そして過去のコードのことは一旦無視して、あなたが新しく追加する部分に関してはテストコードをセットで書くようにしていきましょう。あなたがコードレビューを依頼するときには必ずテストがグリーンな状態で依頼するようにするのです。

そうこうしているうちに他の人が出した Pull Request でテストが失敗するケースが発生します。 Slack の #circleci チャンネルに赤色の Failure 通知が届き社内が騒然とするかもしれません。しかしこれはチャンスです。

「よかった、これでバグが未然に防げましたね」

あなたのこの一言でテストや CI がもたらす開発効率の向上がチームの皆さんに伝わるはずです。こうなったらもう一押しです。あなたがテストと CI の伝道師になりましょう。テストを書くことが当たり前になってきたら、 CircleCI からの deploy や定型処理を CircleCI でやらせるような使い方にチャレンジしていきましょう。どんどん周囲を巻き込んで、 CI 文化を定着させていって下さい。

何はともあれ、最初は一つのテストコードを書くことから始まります。変更に強いコードを書いてじゃんじゃん deploy し、じゃんじゃん Money making していきましょう🤑

| @登山/ランニング

DSC_6447.jpg

北アルプスから帰ってきたあと「二丈岳に行ったけど物足りなかった」とぼやいていたところ同僚に福吉駅から十坊山、浮嶽、女岳、二丈岳を経て深江駅までの四座縦走をやってのけられ、これに触発されて一ヶ月ほど前に計画したものの雨天や家用でなかなか実現できなかったやつをやった。開始地点を浜崎駅に移して浜玉側からスタートするルートは YAMAP で検索しても活動日記が投稿されておらず四座踏破できたら達成感があるだろうと思ったが、スタートが遅れたこと(朝から風呂で Netflix 見てた。 House of Cards が面白すぎるのが悪い)、途中道迷いで小一時間ほどロストしたことにより最後の二丈岳は断念して十坊山、浮嶽、女岳の三座のみとなった。とはいえ浮嶽も女岳も未踏だったので行けて良かった。天気が最高だったこと、初めて 20km を超える縦走(しかも一人)をやったこと、浮嶽で話した唐津のおじさん(若い頃には北アルプスを踏破し久住も 100 回以上登っておられるとのこと)から浮嶽の絶景スポットや初日の出情報を教えてもらい実りの多い秋の糸島縦走だった。

計画

浜玉側から十坊山に登るのはかつて子連れでやろうとして挫折していて、そのリベンジをかねて四座縦走してみることにした。 9 月の初旬に計画したものの天気が悪かったり家用があったりでなかなか実行に移せず 10 月になってしまった。

出発

週の頭に今週末行けたらいいなとぼんやりと思って天気予報をにらんでいたところ、木曜くらいから曇りのち晴れが晴れに変わり、これは行くしかないと、金曜の昼に会社近くのスーパーでカップラーメンや行動食を買い込む。いつもダラダラ居残ってしまうが、早めに仕事を切り上げ帰宅。朝目が覚めると 4 時半で、これは行けそうだと思ったが、前夜風呂に入らずに寝てしまったため風呂につかってうっかり Netflix で House of Cards を見始めたところ面白すぎて 6 時半を過ぎた頃にようやく我に返る。計画では始発列車で移動する予定だったのにこれではもう間に合わない。風呂から上がり、ささっと準備を整えて最寄り駅まで向かう。

格好

長ズボンにするか短パンにするか迷ったが、まぁ大丈夫だろうということで普段もはいている山と道の短パンをはいていくことに。上は icebreaker のメリノウール T シャツにしたが、朝はやはりまだ寒く YATTEIKI FM のパーカーを羽織る。靴はいつもの Montrail 。つま先のソールが剥がれ始めているのでそろそろ買い替え時かもしれない💸。アルプス遠征の反省を踏まえ荷物は少なめにしたつもりだがやはり一眼レフがかさばる。使わないときはカメラバッグはリュックに収納し、なるべく身軽な状態にする。今回初めてサコッシュを山に持っていったがやはり便利だった。自撮り棒、モバイルバッテリー、 Kindle 、行動食を入れて歩いた。

移動

IMG_6232

最寄り駅のセブンイレブンでおにぎりを二つとコーヒーを買う。筑肥線に乗り浜崎へと向かう。平日の朝はたくさんの人が電車を待つ駅だが、土曜の朝だと人影はまばら。筑前前原駅で唐津行きに乗り換え、浜崎まで 50 分弱で到着した。

DSC_6334

十坊山へ

IMG_6236

浜崎駅から登山口のある谷口集落まで歩く。 YAMAP のルートではだいぶ大回りするように書かれているが、あちらのルートは農道で農業用車両の通行が多いので今回通っている集落を抜けるルートがおススメ。

DSC_6342

DSC_6352

コースマップのルートに合流し歩き続けるが、分岐に遭遇する。駅から止まらずに歩いていたのでリュックを下ろし水を飲んでおにぎりを一つ食べながら考える。ずっと舗装路を歩いてきたので山道らしい舗装されていない方に行ってみることにした。

DSC_6368

しばらく行くといきなり選択を誤ったかと思えるような光景に出くわす。水害の影響か、道が崩落している。注意しながら踏み外さないように通り抜けて先に進む。

DSC_6369

再び舗装路になるが、しばらく行くとどうも様子がおかしい。やたら蜘蛛の巣が多くなり、雑草が背高く生い茂っている。道の荒れ具合が人通りがないことを物語っている。短パンで来たことを少し後悔する。

DSC_6375

毒々しい色をした大きな蜘蛛の巣をくぐりながら進んだところでふと YAMAP を開くとルートから外れていることに気がつく。地図を見ると強引に先に進めばルートに合流しないこともなさそう。戻るべきか進むべきか。しばし迷ったがヤマケイ新書の遭難本に書いてあったことを思い出し、来た道を引き返すことにする。

DSC_6384

DSC_6385

人間、これまで登ってきた道を戻ることには抵抗があるのだろう、戻る前は随分進んでしまっていたように感じたが、いざ戻ってみるとルートを外れた地点まではすぐだった。しかし肝心の分岐しているはずの正規ルートが見つからない。なんと、先ほど見かけた崩落地点で分岐しており、脇の方にある舗装路ではない野道の方が正解だったのだ。これは分かりにくい。

DSC_6386

気を取り直し、野道の方を進む。野道だが人の通りがあるのか先ほどの道のように蜘蛛の巣地獄ではなく、草の背丈も程々で非常に歩きやすい。しばらく進むと視界がひらけ、湿地のような場所に出た。また道が舗装路になり快調に歩いた。

十坊山には川はないかと思っていたが、今回歩いた道は途中で沢の横を通り川の音を聞くことができた。この道は林道のようで、あたりはぎっしりと杉が植えられている。杉に覆い尽くされ昼間でも真っ暗になっている場所があり、阿蘇山の登山道を思い出す。蜘蛛が三つに並んで巣を作っていてタバコの煙をプカプカさせているようで面白かったので写真に撮った。

DSC_6412

暗いあたりを過ぎると明るくなる。東屋と芝生が見えたので公園でもあるのかと思ったがゴルフ場の敷地で外からは入れなくなっている。

しばらく進んで漸く十坊山の南登山口に到着した。ここからやっと山登りらしい道になる。十坊山にこちらから登る人は少ないようで登山道は荒れている。杉の葉が大量に落ちておりカラフルな絨毯のようだった。

森の中を淡々と進むと程なく白木峠からのルートと合流した。ここからかなり角度が急な坂を登る。あっという間に山頂に着く。時刻は 11 時半過ぎで、山頂には家族連れや女性二人グループなど先客がいた。当初の予定では浮嶽で昼食を取る予定だったが、すでに昼近くだったのでここで昼食をとる。山頂ではすすきが穂を垂れ始めており秋の気配が強まっていた。坊主岩に登って著者近影をキメてそそくさと退散し浮嶽へ向かう。

浮嶽へ

十坊山から白木峠の方に下る。下りには何組かの小さい子ども連れの家族とすれ違った。下りはすぐだった。白木峠から浮嶽への登り口は十坊山の登り口と道路を挟んで向かい側にある。土留めコンクリートに小さく看板があるだけなので少しわかりにくい。

白木峠から浮嶽へのルートは単調だった。ゴルフ場の脇を通るルートで、時々ゴルフに興じている人たちの絶叫や叫び声が聞こえて変な気持ちになる。一旦 360m まで下って 800m まで登るので 400m 超を駆け上がるが、山頂まではずっと同じような道が続き疲労感が募る。森の中で景色に変化がないので写真を撮ることもなく、一眼レフを胸にくくりつけてるのがアホらしくなってきてカメラバッグに収納しカメラバッグごとリュックサックの中に納めた。

浮嶽では数人とすれ違ったが、挨拶をしたのに返してもらえなかった。聞こえなかったのかなと思って思わず二度挨拶しそうになった。糸島の山は挨拶しない主義の登山者が多いのかもしれない。一人の中高年男性ほど挨拶を返してくれない傾向にあると思う。

そうこうしている間に浮嶽に着いた。浮嶽山頂は立派な杉の木が植えられており、神社もあって厳かな雰囲気がある。写真を撮り、リュックサックを下ろして休憩していると長靴に作業着で軽装の地元の人とおぼしき人がやってきて神社にお参りしていた。こんにちはと挨拶すると、縦走かと聞かれてしばし話し込んだ。この方は唐津の農家で、若い頃北アルプスを踏破し、久住にも 100 回以上登っておられるとのことだった。いまは農業が忙しく遠出ができないためこうして近所の浮嶽に仕事の合間に登りに来ているのだそう。自分が今夏北アルプスに行った話をすると話が弾み、浮嶽の絶景スポットや初日の出が見えるスポットを教えてもらった。

荒谷峠までおじさんの車で乗せて行こうかと言われたが、せっかくなので歩こうと思って辞退し、歩いて荒谷峠へ向かった。荒谷峠へは山道と舗装路の二つがあるが、併走しているので最終的には同じところに辿り着く。自分はコースタイムが短かった舗装路の方を選んだ。歩きながら見えた浮嶽の姿は非常に立派だった。唐津のおじさんに教えてもらった絶景ポイントも最高で、標高が高いため十坊山よりも二丈岳よりも景色が良いかもしれない。また来たいと思った。行動食のトレイルミックスを食べながら優雅に舗装路を下った。

女岳へ

荒谷峠に着いて、女岳に登るかスキップして真名子まで行き二丈岳に登るか迷った。すでにこのとき時間は 15 時半を回っており、四座踏破は無理だろうなと思っていた。女岳は眺望もないと聞いていたし、登る価値がないかもしれないと思っていたが、二丈岳には何度も登ったことがあるしそもそも真名子まで女岳を経由してもしなくても所要時間は変わらない、それなら女岳に登って二丈岳をスキップし、深江に降りる予定を大入に降りようと考えを改めた。真名子からゆらりんこ橋へのルートは過去に通ったことがあるし、日が落ちてしまっても何とかなるだろうと考えた。

女岳にはすぐに着いた。登山道は杉林ではなく雑木林で鬱蒼感が多少ましで好きな雰囲気だった。 16 時前に着いたが山頂は誰もおらず、温度計を見ると気温は 10 ℃だった。立ち止まると体が冷える。ナイロンパーカーを羽織って寒さを凌ぐ。数枚写真を撮って足早に下山した。

もう体力が尽きかけていたのか、女岳ではリュックサックから一眼レフを取り出して写真を撮る気力が沸かなかった。眺望が悪いときいていたものの、自撮り棒を使って高い位置から海の写真を撮ることができた。

真名子方向におり始めてすぐにとても大きな石を見た。白馬岳ルートの天狗が原で見たやつよりも大きく感じられた。カメラで写真を撮るべきだろうなぁとは思ったが、疲労と寒さが勝り先を急いだ。

真名子へ

女岳の下りから北アルプス遠征で痛めた左膝が痛み始めた。普段の生活では痛まないが、山登りの下りで痛むようだった。どうもこれは持病になってしまったみたいだ。自分はもう死ぬまでこの痛みと付き合っていかなければならないのかもしれない。もうアルプスのような高い山にも登れないのかも知れないと思うと悲しい気持ちになった。

真名子への下りでは誰とも出会わなかった。途中、車道に出ることが何度かあって、そのとき脇を車が通り過ぎていった。キャンプ場に向かう人やアウトドアテーマパークから帰る人たちだった。どうせ二丈岳には登らないのだからこのまま車で帰りたい、親切な人が乗せてくれないかななどと思いながらも歯を食いしばって歩いた。このあたりでは疲れてほとんど写真を撮っていない。

だいぶ下って舗装路に出て、見慣れた真名子の研修棟のところに着いた。二丈岳への登山口はスルーして賀茂神社に向かう。飲み水が少なくなっていたので水場で補給させてもらう。

ゆらりんこ橋へは慣れた道だったが左膝が痛み、ほとんど一人で絶叫しながら降りて行った。

ゆらりんこ橋から大入へ

何とか日が残っているうちにゆらりんこ橋に着いた。ただここからまだ大入まで 4km 弱ある。最後の力を振り絞って歩く。 YAMAP の活動距離を見ると 17km ほどになっていた。こんなに歩いたのは初めてで、大入まで行くと 20km を超えるだろうと思った。

大入駅の前にコンビニがあったはずだからコンビニでビールを買って飲むことを楽しみに歩き続けた。車ではなく電車で来て縦走しているのでそういうことができる。

大入駅手前まで来たところで夕焼けがとても綺麗だったので再び一眼レフを取り出して何枚か写真を撮った。パタゴニアのロゴみたいな色の空が撮れた。

DSC_6492

何とか大入駅に辿り着いたが、駅前のコンビニは閉店してしまっておりビールを買うという夢は打ち砕かれた。荷物を軽くしようと賀茂神社でくんだ水は途中で捨ててしまっていたので飲むものがなくどっと疲れが出た。加えて電車を待つホームを間違えてしまい、下りホームにいたところを親切な人に「そっち上り電車来ませんよ」と教えてもらって慌てて階段を駆け上がって反対側に移動し、何とか帰りの電車に載ることができた。筑肥線の筑前前原以西は電車の本数が減るので、ホームを間違っていることに気づかずこれを逃していたら帰宅が一時間くらい遅れていたかもしれない。最後に散々な思いをしながら放心状態で自宅最寄り駅まで電車に揺られ帰り着くことができた。

所感

初めて一人で縦走をし、 20km 以上も歩いた。低山だと侮っていた糸島の山も立て続けに三座登ると足がぱんぱんになり、非常に達成感があった。

一方でやはりまだまだ自分は初心者で、ゆっくり目に引いてある YAMAP のコースタイムよりも遅いペースでしか歩けないことがよく分かった。出発が 2 時間近く遅れたものの、飛ばせばそのうち挽回できて二丈岳にも回れるだろうと思っていたが全くそんなことはなく、四座目の二丈岳を断念しなければならないのは残念だった。なかなか一人で一日使って登山できることはないので貴重な機会を逃してしまったのもしれない。

もしまた実行できるチャンスがあれば、深江側から二丈岳、女岳、浮嶽、十坊山を縦走して浜玉側に降りるやつをやってみたい。そのときは是非ビールを買って帰りの筑肥線で海を見ながら飲みたい。

| @労働

Twitter で DHH が共有していた記事が面白かったので著者の許可を得て翻訳します。

ジュニアを採用しない連中はシニアに値しない、というもの。

※なお本文中で「エンジニア」はソフトウェアエンジニアのことを指して使っています。


とても成功した企業がとてつもない愚かな決定をした話をさせてほしい。

我々はジュニアなエンジニアやインターンは雇わないことにしてるんだ…子犬を飼わなければ糞の片付けをせずに済む。

Netflix

社畜連中が子犬をよくないものと見なしていること、またみんながそれを受け入れていることに唖然とした。子犬とは地球上で最もピュアな存在だ。文字通り遊びの時間とふわふわの毛でできている。孤独なこの世界の救いだ。話が脱線してしまった。

多くの企業が "経験者のみ" という採用戦略をとっている。理由を聞かれると以下のように答える。

  • ジュニアエンジニアを雇うには時間もリソースも足りないから。我々は急いでるんだ。
  • 会社にシニアエンジニアを雇う余裕があるからジュニアな人を雇う必要がない。
  • 我々はいま間違いをおかすわけにはいかないんだ。ジュニアエンジニアを雇うのはリスクが大きすぎる。
  • 我々は従業員に自律的に働いてもらってる。ジュニアエンジニアが必要とするような手取り足取りの支援をすることはできない。
  • 未経験者を雇う前にプロダクトの基盤を固めておきたい。

ジュニアエンジニアを雇うことは企業が義務感から行うもの、あるいは会社の予算に悪影響を及ぼすものという認識で、ジュニアエンジニアは負債のようなものだと言っているに等しい。慈善活動をする余裕があって補助作業要員を置けるような大企業が雇えば良いと言ってるようにもとれるが、そんなやり方はできない。

アメリカには 10 万を超えるテック企業があるけど、どこの CEO も「ミスは大した問題にならない」とか「持ってる金はじゃぶじゃぶ使いたいね」なんて言わない。だから結局「経験者のみ」と言って近道をしたつもりになっていたとしても、それはアドバンテージにはならない。会社がきちんと運営されてないことを露呈するだけだ。

ジュニアエンジニアを雇うかどうかは組織、開発体制、企業文化の健全性の物差しになる。熟練の開発者はそのことを知っている1。もしこの主張が聞き入れられなかったとしても、ジュニアエンジニアをバランス良く採用することは会社の財務を安定させる2ことは確かだ。

Preventing messes

ジュニアエンジニアは混乱を引き起こすから雇いたくないと拒否しているのであれば、それは会社に「ミスを許さない」文化があることを意図せず表明している。我が社はサーバーがダウンするたびに原因を作ったエンジニアをクビにしています、と言っているようなものだ。どんなに給料が高くてもすぐクビになる会社で働きたくないし、ミスをしないように開発者を脅すような文化はメンタルヘルスとプロダクティビティを阻害する。

こういう脅しの文化が自動化されたテストや QA 、フェイルオーバー、アクセス制限、バージョンコントロールなどを根付かせるんだとあなた言うかもしれない。しかし逆で、会社がフェイルセーフ技術を推奨し時間やリソースを与えるのであれば、「間違いを許さない」文化は不要で無価値だ。なぜならほとんどの不具合は production にリリースされる前に見つかって修正されるからだ。ジュニアエンジニアもシニアエンジニアも堅強な開発プロセスに守られてのびのび仕事ができる。

ジュニアエンジニアを雇い入れることは、過去に講じた不具合の予防策が機能しているか確認することができるまたとない機会ともいえる。彼らはシニアエンジニアよりもそういう罠にはまりがちだ。少しでも経験のあるエンジニアならみなそう言うように、ミス予防策の動作検証をしないということはあり得ないはずで、今やるかあとでやるかくらいしか選択肢がない。不具合が起こる可能性が残されているとき、ほとんどすぐにその不具合は起こる。どんなに経験があってもヒューマンエラーを完全に予防することはできない。

つまるところ少しのシニアエンジニアがいて開発基盤を固めてもらい、エラーに強い開発サイクルを構築すればよい。誰もジュニアエンジニアだけ雇えと言っているのではない。本当にミスをケアする職場であれば、ジュニアエンジニアもちゃんとフィットするし、シニアエンジニアも含めてみんなの満足度が高くなるはずだ。障害による炎上の火消しばかりやらなくて済むし、夜や週末はゆっくり休むことができる。

Saving money

Indeed.com によると、ジュニアエンジニアの給料の平均は $55,394 でシニアエンジニアの方は $117,374 だ。シニアエンジニアの給料は未熟な人の二倍以上だ。

コストには常に理由が必要だ。シニアエンジニアはジュニアな開発者よりも生産的であることが求められる。そんなに単純な話ではないが、ビジネスにかかるコストを無視するのは怠慢だし不利益を招く。

すべてのコードを書くのに長年の経験が必要なわけではない。良いコードを書く場合にだって必要ない。すべてのプログラムには、ありふれたやり方で入力と出力を結びつける「にかわのようなコード」が存在する。こういうのは誰が書いたって大差ない。時給 $28 の人に頼んでも時給 $59 の人に頼んでも結果は同じだ。もし熟練エンジニアしか雇わないのなら、そういった軽い仕事に余分なお金を払っているということになる。

コードは作るアプリケーションごとに結構変わるもので、慣れが生産性に大きく関わることがある。大抵のケースで、 6 ヶ月チームで仕事しているジュニアエンジニアと入ったばかりのシニアエンジニアでは、アプリケーションのドメインに詳しいという理由だけで前者の方が生産性が高かったりする。

先に述べた「にかわコード」とドメイン特化のコードを書くことは少なくとも開発業務の半分くらいを占める。その残りの部分で初めて熟練したシニアエンジニアの利点を活かせる。そしてたとえジュニアエンジニアであったとしても、十分な教材やベテランのメンターが付くことで難しい分野でもとても良い働きをしてくれることがある。

従ってジュニアとシニアのエンジニアでペアを組ませると二人のシニアエンジニアと同じだけの価値を発揮すると言える。しかもコストはシニア二人の場合の 75% しかかからない。もしあなたのゴールが最小の費用で最大の生産性を発揮することだとしたら、組織の中でジュニアとシニアの組み合わせを分子レベルでの最小単位とすべきだ。

加えて、シニアエンジニアばかり集めるとアルゴリズムやマイクロ秒単位の最適化、コーディングスタイルなど些細な事柄で延々議論をしてしまう傾向があることを考慮しなければならない。もし会社がシニアエンジニアだらけで、チームに堅実な意思決定プロセスが存在しなければ、数百時間分の人件費が議論のために失われることだろう。ジュニアエンジニアであればほとんどこういう問題を起こすことはない。

Building careers

ジュニアエンジニアを採用しないことによるもう一つのメッセージは、キャリア構築に対する無理解の表明だ。

これは会社の世間体とかテックコミュニティでの役割の話をしているのではない。あなたの会社をより働きやすくし、多くのエンジニアが入社し長く働いて会社に貢献してくれるようにするためのものだ。

数人のエンジニアが「やっと職位を変えることができたよ。もう職位を変えるのは嫌だ。一生シニアエンジニアでいたいね」と話しているのを聞いたことがある。しかし「給料なんて上がんなくていいよ。新しいことを学びたくもないし金輪際達成したことを評価されたくもないね」なんて言う人はいない。それに面倒なことに、向上心旺盛な野心家を引き留めるために必要なものは、無欲だが情熱的なシニアエンジニアを引き留めるのに必要なものとほとんど同じだ。仕事の成果を図るための評価軸と十分な研修用の教材、そして様々な種類の新旧のプロジェクトが必要だ。昇進を望まない少数の人に対しても、進歩や成長の意識を植え付ける必要がある。

しかしそういう連中に手をこまねかないでほしい。彼らは少数派だ。テック業界にいるエンジニアのほとんどが 40 年間もシニアエンジニアでいたいなんて思っていない。みんなソフトウェアアーキテクトだとか、チームリーダーだとか、 CTO だとか創業者になりたいと思っている。キャリア開発に関して無関心な企業は潜在的な従業員から働き先の最終候補にしか見てもらえない。

エンジニアが面接を受けに来てもっとも感銘をうける言葉の一つはこういうものだ。「やぁ、僕はチームリーダーでこの会社に入って 8 年になる。最初はインターンだったんだ」。印象に残るがとても稀だ。こういう人は会社にとって非常に貴重だ。これまでの製品ラインの変遷を知っているし、半径 100 ヤード以内の各プロジェクトのコードを見てきている。組織の中の一人一人と一緒に仕事をした経験もある。他に誰もできないようなやり方で内側から会社を変革してくれるだろう。会社はこういう人の仕事で予測不可能なほどの利益を得るだろう。なぜなら社員を 8 年間(人生の 1/10 の時間に相当する)も同じ会社にとどまらせる方法を明らかにしたからだ。これは会社の文化醸成がうまくいっていることの証だ。職場のモラルは高く、良い仕事が評価され、社内の至る所で面白いプロジェクトが待ち受けていることを示す。

「ジュニアを雇わない」は、あなたの会社が誰かのキャリアの一部になる準備ができていないことを示している。会社が停滞していると公言しているのと同じだ。「我が社は経験豊富で能力の高いエンジニアを求めていて、金さえ払えば際限なく仕事をやってくれることを期待しています」。こういう求人に応募する人もいるだろうが、彼らは最善の仕事はしてくれないだろう。

もしあなたの会社がキャリア開発に真剣に取り組んでいるならば、ジュニアお断りポリシーは採用のパイプラインをしぼませ、従業員の在職期間を短くするだけだろう。

Making great software

ジュニアエンジニアにはシニア連中が普通失ってしまったようなユニークな特徴がある。その一つが盲目的な楽観思考だ。他に喜んで指示に従うというのもある。でも最も価値が高い特徴は、ジュニアは手ぶらであるということだ。シニアエンジニアの連中はこれまで技術の盛衰や失敗したプロジェクト、崩壊したチーム、その他の開発周りの罠を見てきている。彼らはその経験から強い意見を言い、時にそれは過度に一般化され、特定チームやプロジェクトでうまく行った(あるいは行かなかった)事柄を他のプロジェクトにも当てはまると思い込む。問題から新しい学びを得ることを避けるだろうことが明白だ。

「あれがそこで使えなかったってことは知らなかったよ。でもここではうまく行くさ」と言うことがしばしばプロジェクトマネージャーの仕事になることがある。そのときジュニアエンジニアがその主張の裏付け役としてうってつけの存在になる。シニアエンジニアが長年かけて培った偏見なしに実証のためのプロトタイプを作ることができる。僕はジュニアエンジニアだったときによくこういう仕事をした。新しいツールや技術を試し、全く違うやり方で作り直したり、他の人が手を出すには早すぎると言ったことを実証試験したりしてきた。大抵僕はよりよい方法を見つけて、結果として会社のソフトウェアはかなり良くなった。ページ読み込みが遅かったところで一桁速度を改善したこともあるし、複数ページにまたがっていたものを一つにまとめ、将来のメンテナンスにかかる数週間分の工数を節約したし、時間を浪費する可能性があった不適切な技術を除外することもできた。技術的背景がまっさらでフレッシュな視点の有効性は無視できないものであることがわかる。

多くの会社が一束のシニアエンジニアを部屋に集めて問題解決方法について合意を得るための討論をさせている。しかし人件費の安い数名のジュニアエンジニアを加えるだけで一回きりの作業や野心的な取り組みに手を出しやすくなり、プロダクトに驚くべき成果をもたらすことができる。

ソフトウェアの品質に関しても、ジュニアエンジニアが感謝こそされないが重要な影響をもたらすことがある。彼らはシニアの連中が書きたがる頭でっかちでオーバーエンジニアリングなコードを書かない。

上のツイートで "凡人" と書かれているところを "ジュニア" に置き換えてみればこれがどういうことか分かるだろう。コードベースとはコードを書いている人々が重要だと思ったことが抽象化されて記録されているものだ。ジュニアエンジニアとシニアエンジニアの割合が健全であればコードはシンプルになり将来の改修も楽になる。

まとめると、テック業界で広がりを見せる「シニアのみ」の態度はジュニアエンジニアを低く評価している。これはみんな、特に未経験者の候補者を閉め出すことで採用を楽にしようという誤った考えをしている組織にとって損失でしかない。そういう会社は財務的に余裕があったとしても、無駄にしているお金と時間はとても多い。

もしあなたの会社がこういう問題に直面していたら、そしてもしあなたがジュニアエンジニアをどう雇い、どう教育すべきか知っていたら、ここで述べているベネフィットを享受することができるだろう。あなたの会社ではどんでん返しが減り、多様性が高く、競争による副作用も少なくて済むだろう。ソフトウェアは壊れにくくなり、輝きを放つようになるはずだ。もちろん、これだけがすべてではない。しかしジュニアエンジニアに対する積極的な採用方針はあらゆるレベルのエンジニアにとって働きやすさの指針になるはずだ。(翻訳ここまで)


ジュニアがいてもぶっ壊れない開発フローで思い出すのがペパボ時代のことだ。 Jenkins のセットアップがしたくて @hsbt さんがお守りをしていたプロジェクトの Jenkins 設定を参考にさせてもらってるときに、うっかりビルドを実行してしまって production へのデプロイが始まってしまった。青ざめたけど「 master からのデプロイなら全く問題ないように作ってあるので大丈夫」と言われてめっちゃカッケーなと思った。いま CI の仕組みを整えたり誰でも Hubot から簡単にデプロイしたりできるように頑張ってるののきっかけになってると思う。


  1. 訳注) だから「経験者のみ」を掲げている会社にはよい開発者がやってこないと言いたいのだと思う 

  2. 訳注) ジュニアは給料が安いから 

| @技術/プログラミング

ジョブキューイングシステムをどうするかでチームのリーダーとやりあって考えたことがあるのでまとめておく。

Rails で使うジョブキューイングシステムの技術選定で、リーダーは Amazon SQS 推し(レガシーシステムで SQS を使っている)、自分は Sidekiq 推しだった。前職時代に Sidekiq を使ってトラブルに遭遇したことはなかったし、とても簡単に使えるので Sidekiq で十分だと思っていた。 Sidekiq は GitHub でのスター数は 9000 オーバーで、 Rails の ActiveJob バックエンドとしては事実上のデファクトスタンダードだといえると思う。ググれば情報がいっぱい出てくるし、チームメンバーもリーダー以外は全員 Sidekiq の使用経験があった。

リーダーが Sidekiq に反対する理由は以下だった。

  1. キューに可視性タイムアウトの概念がない( SQS にはある)
    ワーカーがキューメッセッージを取得したあと何らかの事情で一定時間内に処理を終えられなかった(ワーカーが突然死した場合など)未処理のジョブが再度ワーカーから見えるようになるので、ジョブの実行が保証される
  2. Redis が飛んだらジョブをロストする
    ElastiCache を使っているが、たしかに稀にメンテ祭などでフェイルオーバーが発生するなど困ることがあった
  3. Ruby 以外の言語から使えない
    Redis に書き込まれる情報は Sidekiq 専用フォーマットなので他の言語からも使う場合は読み取り君を作る必要がある

一方で自分が SQS に反対した理由は以下。

  1. 依存関係をソースコードに落とし込むことができない
    Sidekiq を使う場合は Redis と Sidekiq worker が動く Docker コンテナの情報を docker-compose.yml に書くことで依存関係を(バージョンまで含めて)宣言的に記述できる。 SQS の場合はそうはいかない。
  2. アプリケーションが AWS にロックインされる

    運用環境はすでにロックインされているが、アプリケーションが SQS という AWS のプロプライエタリな技術に依存すると、ソースコードが AWS と密結合になり他の IaaS に移行するときの障壁となる
  3. ローカル開発で利用することができない

    実際にローカル環境で非同期処理の検証不足が原因で機能の実装が漏れたまま production に deploy されたことが何度かあった。 localstack という AWS の機能をローカルに再現する技術はあるが、 SQS はオープンソースではないので完全に再現されるわけではない。

このような議論を経て、結局ジョブキューイングシステムには RabbitMQ を使うことになった。 RabbitMQ はリーダーが求める三つの要件を満たすし、オープンソースなので自分が SQS に反対する理由にも抵触しない。開発環境では Docker で RabbitMQ を動かし、 production では AWS にフルマネージドの RabbitMQ サービスはないので( ActiveMQ のマネージドサービス、 Amazon MQ というのはある)、 RabbitMQ の運用に特化した SaaS を利用することにした。

SQS に対する考えを整理する上で The Twelve-Factor App を改めて読んだが非常に参考になった。特に以下の三つの部分について、 SQS は Twelve-Factor App に反しており使うべきではないと思った。

II. 依存関係

アプリケーションが将来に渡って実行され得るすべてのシステムに存在するかどうか、あるいは将来のシステムでこのアプリケーションと互換性のあるバージョンが見つかるかどうかについては何の保証もない。アプリケーションがシステムツールを必要とするならば、そのツールをアプリケーションに組み込むべきである。

IV. バックエンドサービス

Twelve-Factor Appのコードは、ローカルサービスとサードパーティサービスを区別しない。アプリケーションにとっては、どちらもアタッチされたリソースであり、設定に格納されたURLやその他のロケーター、認証情報でアクセスする。Twelve-Factor Appのデプロイは、アプリケーションのコードに変更を加えることなく、ローカルで管理されるMySQLデータベースをサードパーティに管理されるサービス(Amazon RDSなど)に切り替えることができるべきである。同様に、ローカルのSMTPサーバーも、コードを変更することなくサードパーティのSMTPサービス(Postmarkなど)に切り替えることができるべきである。どちらの場合も、変更が必要なのは設定の中のリソースハンドルのみである。

X. 開発/本番一致

Twelve-Factor Appでは、継続的デプロイしやすいよう開発環境と本番環境のギャップを小さく保つ

たとえ理論的にはアダプターがバックエンドサービスの違いをすべて抽象化してくれるとしても、 Twelve-Factorの開発者は、開発と本番の間で異なるバックエンドサービスを使いたくなる衝動に抵抗する。 バックエンドサービスの違いは、わずかな非互換性が顕在化し、開発環境やステージング環境では正常に動作してテストも通過するコードが本番環境でエラーを起こす事態を招くことを意味する。この種のエラーは継続的デプロイを妨げる摩擦を生む。この摩擦とそれに伴って継続的デプロイが妨げられることのコストは、アプリケーションのライフサイクルに渡ってトータルで考えると非常に高くつく。

AWS の技術がどんなに優れていたとしても、自分はオープンソースではない AWS 独自のプロプライエタリな技術に依存してアプリケーションを作りたい訳ではない。運用の煩雑さ・手間から解放されたい、スケーラビリティを提供してほしい、というのが AWS に期待するところだ。 SQS はアプリケーションのソースコードの中に入り込んでくる。開発環境ではローカルの PostgreSQL 、 production では RDS の PostgreSQL インスタンスに接続先を変えるだけ、という風にプラガブルに切り替えることができない。開発効率性や移行可能性(ほかの IaaS に移ることができるか)を考えると、運用の効率性に特化して AWS を使いたいと思った。 Redshift とか DynamoDB とか Kinesis とか AWS の技術でしか実現できないことをやりたいときに手を出すのは悪くないと思うけど、AWS が提供するものなら何でも素晴らしいからすぐに飛びつくというのは間違っていると思う。

ちなみに CircleCI との距離の取り方はうまくいってると思う。いま deploy を CircleCI から行なっているが、 CircleCI が止まると deploy できなくなるのは困るので deploy 処理自体はシェルスクリプト化してある(👺 Hubot で Slack から AWS ECS にデプロイ)。 CircleCI が死んだら手元から deploy コマンドを実行するだけでよい。 CircleCI にやってもらっているのは、人間が手でも実行できることの自動化の部分だけだ。 CircleCI というサービスが終了したとしても恐らく簡単にほかのサービスに乗り換えられる。

まとめると、 IaaS / SaaS / PaaS を使う場合は以下に気をつけるべきだと思う。

  • ソースコードの中に特定のプラットフォームのプロプライエタリな技術に依存した部分が出てこないか
  • アプリケーションをローカル環境でも動かすことができるか
  • 運用やスケーラビリティに関してのみ依存するようにする
  • 人間が手でもできることの自動化のみに利用する

| @散財

契約中のサービス

Apple Music

何度も一ヶ月だけ契約して試しては解約し、を繰り返していたけど、 Circle 2018 に行ったあとに出てた人たちの音楽をまとめて聞きたくなって契約した。全部アルバム買うと 2, 3 万になるのがファミリープランでも 1480 円/月で済むのはいい。人間は音楽を買ってもそのうち聞かなくなる。聞きたい間だけお金を払うのが正解なのかもしれない。

ただ有名ミュージシャンの曲や懐メロのオリジナル版は相変わらず Apple Music にはなくて(カバーはいっぱいある)買わないといけないので注意が必要。ゴレンジャーの曲とか聖闘士星矢の曲のオリジナル版は iTunes Store で買った。

Spotify にしない理由は macOS や iOS との統合された使い勝手を重視しているから。たまに切り替えて使ってみるのもよいかもしれない。

Netflix

深夜食堂を見たくて入ってる。その他、アメリカのドラマも時々見る。電車の中で見たいけど結構エロシーンが多くて困る。イギリスのクッキング対決番組も面白い。とはいえ元とれてる感じはしないので Rebuild で話題になるドラマなんかをさっと見て解約したい。

Amazon Prime

Amazon のクレジットカード( Master )の特典で付いてくる。様々な割引を組み合わせたカードの年会費が 3940 円でプライム年会費と同じ。 Master カードはコストコでの支払いにも使えるようになったので便利。 1% ポイント還元。

Prime ビデオに関しては割と頻繁にラインナップの見直しあってて見たいやつがなくなるので見られたらラッキーくらいのつもりで利用しないと逆にストレス溜まる。

The Old Reader

RSS リーダーの中で最安なので使ってる。検索が厳しい。たぶん全文検索エンジン使ってなくて DB から LIKE サーチしてる気配を感じる。 Inoreader に乗り換えを検討した方がよいかもしれない( Feedly は好きになれない )。

さくら VPS 2GB プラン

このブログを動かしている。まぁまぁ高いが AWS や自宅サーバーで運用するのに比べたら十分経済的。

AWS

Route 53 と S3 、 CloudFront のみ利用している。 毎月 200 〜 300 円くらい。

解約したサービス

GitHub private repo

Microsoft に買われて自分ごときの金なしおじさんが利用料を払う必要もなかろうと思い解約。大したコード上げてなかった。秘密情報的なやつは GitLab に移した。

Flickr Pro

自己顕示欲を満たすために人に写真を見せる、ということがなくなったので解約しようと思っていたが、 2 年おきの更新なのでうっかりしてて 2020 年まで自動更新されてしまった。とりあえず自動更新を停止にした。

iTunes Match

Apple Music に移行したので自動更新を停止した。

| @技術/プログラミング

ヒトデさんの以下のツイートを目にして便利そうだと思ったので fish + peco + vim でやってみることにした。

以下のような fish 関数を追加した上でショートカットキーを bind しておいた。

function peco_gitlsfiles_vim
  git ls-files | peco --query "$LBUFFER" | read selected
  if [ $selected ]
    vim $selected
  end
end
function fish_user_key_bindings
  fish_vi_key_bindings
  bind \cg\cv peco_gitlsfiles_vim
  bind -M insert \cg\cv peco_gitlsfiles_vim
end

これまで一旦 vim を閉じてしまうとファイルを開きたいときには vim . して Unite で調べててたけど、いきなり git ls-files して peco して絞り込めるようになってとても便利になった。

2018-06-20 16.48.40.gif