Don't Repeat Yourself

Don't Repeat Yourself (DRY) is a principle of software development aimed at reducing repetition of all kinds. -- wikipedia

Junction Tokyo 2018 で優勝しました――技術的な話

3/23-2/25 で,Junction Tokyo というハッカソンに参加してきました.そして,Logistics 部門において見事,優勝をすることができました.3日間本当にお疲れ様でした.スタッフの皆さんもどうもありがとうございました.

Junction Tokyo は,毎年5月頃に開催されているハッカソンで,私も去年出場しました.もともとはフィンランド発のハッカソンらしく,海外からの出場者も半数以上いるような国際色豊かなハッカソンです.アナウンスなどはすべて英語で行われますし,チーム内でも普通に英語で会話します.

Junction Tokyo Hackathon

私たちのチームはいわば「宅配版Uber」のようなアイディアで,車で通勤する社会人向けのサービスを考案し発表しました.車のトランクや屋根といった空きスペースを使って荷物を運び,その運んだ状況を IoT デバイスで記録して,安全な運転を行うドライバーはより高い評価を得られるというアイディアも盛り込みました.

チームにプレゼンの神様のような方がおり,その方がまず非常によくまとまったプレゼン資料を作ってくれました.またデザイナーの方は,とてもきれいな UI のプロトタイプを作ってくれました.これら2つによって優勝することができたと言っても過言ではないです.ビジネスプランとしてはベストなものが発表できたと思います.

さて一方で,プレゼンではほとんどサーバーサイド側の話をしている余裕がありませんでした.あくまでハッカソンはアイディア勝負であり,デモも行うといえば行うのですが,あくまで注目されるのはフロントエンドです.サーバーサイドの話を盛り込むことができませんでした [*1].

しかし,一応サーバーサイドエンジニア枠で出場したので,ブログでは思いっきりサーバーサイド寄りの話をここに書いておきたいと思います.

何を作ったのか,そして中身について

上記のサービスを利用する際に使用するアプリの画面と,IoT デバイスで振動や傾きを検知するプログラムと,それらを REST を使ってやりとりするサーバーを作りました.IoT デバイスの結果を一度 Python プログラムに渡して独自のアルゴリズムで評価し,それをサーバーに送ります.サーバーはそれを受け取ると,今度は画面側のドライバーの評価用にまたオブジェクトを返す,という流れです.その他,ドライバー一覧の表示やドライバーの登録を DB に行うといったこともできるようにしました.

f:id:yuk1tyd:20180326231002j:plain
全体の構成のスケッチ

サーバーには全面的に Scala を採用しました.今回は Scala の生産性の高さに非常に助けられたように思います.ハッカソンは短い時間でプロトタイプを出す必要があるので,使い慣れていて生産性の高い言語やツールを使えるとベストだと思います *2.また,今回 Scala を使ったからか技術点を結構もらうことができ,結果的に優勝につながったという点でも Scala を採用してよかったかなと思いました.

Web フレームワークFinagleFinch を採用しました.これも第一に私が使い慣れているためです.

Finch は非常に処理を書きやすく,関数型プログラミングに特化されており,コンビネータを用いた洗練された設計になっています.処理を多少雑に書いても予想外の挙動が発生しにくいように感じます.さらに twitter-util や finagle-XXX のような強力なエコシステムをもっており,それを利用するだけで非常にすばやくアプリケーションを構築できます.DB には MySQL を採用しましたが,finagle-mysql を使って簡単に接続することができました.O/R マッパーもシンプルに実装できました.Finch の生産性の高さにもまた,とても助けられました.

JSON のパースには circe を使用しました.仕事でも使っていて大変高評価だったのですが,改めて circe は楽でした.ほとんど自動的に JSON のパースをしてくれて本当に助かりました.

github.com

画面側では Vue.js を使用しました.これは別のインドネシアの子が作ってくれました.とても優秀なエンジニアで,こちらが返す (めちゃくちゃな) JSON をきれいに画面に反映してくれました *3インドネシアの方は英語もできるし頭もきれるし,これから彼らと戦わないといけないのか…と思うと正直ゾッとしましたね (笑).

IoT デバイス側は,アメリカ出身の方が作ってくれました.BOSCH の XDK を使って,主に傾きと揺れを検知し,ドライバーがどの程度安全に運転しているかの指標にしようとしました.検出はとてもうまくいき,一応適当なアルゴリズムを考えてドライバーの評価が行われ,その評価が画面上で「★」の数で表示されるというところまで作りました.

ハッカソンということで時間がなく,正直 REST のレスポンスや保存時の処理などはドライバー一覧の取得以外わりとめちゃくちゃになっています.Python 側 (IoT 側) でステータスから成功か失敗か判断する実装をつけ忘れていたことに直前に気づき,デモの直前で「保存されると音がなる」という実装をサーバー側に実装して公開するなどのやっつけ仕事もしました.が,これが意外にチームに好評でデモもスムーズにいったので,美しく実装することがすべてではないのだなとも思いました.

ハッカソンで優勝して学んだこと

今回のハッカソンで優勝して学んだことは次です.

  • 高速でプロトタイプを作る必要がある際には,技術的にこだわってはいられないということ.
  • 変更に強いアーキテクチャであること.
  • プレゼンテーションめちゃくちゃ大事.

1つ1つ見ていきましょう.

高速でプロトタイプを作る必要がある際には,技術的にこだわってはいられないということ

ハッカソンでもっとも大きく評価に影響するのはプロトタイプのできであり,アイディアを具体的なプロトタイプにして示せなかったとしたらハッカソンの意味がありません.そして,ハッカソンは時間がありません.もっとも避けなければならないのは「プロトタイプができあがらない」ことなはずです.

エンジニアである以上,そしてハッカソンという日常業務から離れられる場である以上,どうしても「これまで使ってみたいと思っていた技術を使って作ってみよう」と思うのはわからなくはないのですが,しかしハッカソンで本気で優勝を狙うのであれば,むしろ「使い慣れた技術で」「精度の高い」プロトタイプを作ることが必要不可欠かなと思います.したがって,使い慣れた技術かつやり慣れた手順でプロトタイプ制作を行うことを強くおすすめします.

私も,正直 Rust でサーバーサイドを作ってもよかったです.が,Rust の Web フレームワークはそこまで使い慣れているということはなく,「時間が余計にかかってしまってやりたいことが実現できないかもしれない」と,仕事で使い慣れている Scala を選びました.

変更に強いアーキテクチャであること

ハッカソンで工夫できることはむしろこちらなのかなと思います.とにかく時間がないので,やることの大枠が決まった時点で手を動かし始める必要があります.そして,あとからやってくる仕様変更の波に耐えきることのできるような設計を行う必要があります.ある程度抽象的な実装を行っておいて拡張しやすいようにしておく必要があるなど,エンジニアとしての熟練度を求められます.

プレゼンテーションめちゃくちゃ大事

今回,優勝できた一番の要因はこれかなと思います.プレゼンテーションはとても重要です.とくに,自分たちが何を問題と置き,世の中では現状どのようになっていて,それを解決するためのプロダクトとして何を作ったかというストーリーを,わかりやすく伝える必要があります.

また,本番の前にたくさん練習を積むことも重要だなと改めて思いました.今回はプレゼンの神様が会場のスタッフやら参加者やらいろんな人を連れてきて,合計で10回くらいリハーサルも含めて練習しました.その結果,本番で想定される質問の洗い出しや,プロダクトの実演時の問題点などをたくさん洗い出して,高速で PDCA サイクルを回すことができました.これは本当に大きかったです.

作ったプロダクトは,うるさいくらいに主張しないと周りの人に伝わりません.「いいものだったらかならず周りの人がよさをわかってくれる」ということはありません.悪いものでもアピールをするといいものとして評価される場合もあるくらいです.改めてこのことを学んだなと思います*4

最後になりましたが,非常に楽しい3日間でした.GW もまたハッカソンがあるはずなので,興味のあるものがあったらぜひ出場してみようと思います.ディープラーニング系のものがあったら出てみたいですね.

*1:私が,技術的な話はあまり必要ないと思ったので押しませんでした

*2:その点では,PlayFramework を使えたらよかったなとは思いました.

*3:circe が case class を上手に解釈してくれなくて,若干変なレスポンスになってしまい妥協してもらいました.

*4:もちろん,私たちの作ったものはとてもいいプロダクトですよ笑.