競プロ勢がソフトウェア開発に向いていると考える理由

【プロフィール】kenkoooo

東京大学理学部卒業後、自宅でニートに従事。その後、国立情報学研究所、リクルート、SoundHound、Indeedにソフトウェアエンジニアとして勤務。現在はestieでデータ基盤の開発などに取り組んでいる。

はじめに

こんにちは、kenkoooo です。

estie では不動産業界向けにソフトウェアを開発していますが、日々の開発の中で「実質競プロじゃん」と思うことが多々あります。僕は AtCoder と AOJ でプログラミングを覚えてソフトウェアエンジニアになっているので、この感覚はかなり強いバイアスがかかっている気がしますが、それはそれとして、僕は競技プログラマとソフトウェア開発の親和性はかなり高いと感じています。

もちろん向き不向きはあると思いますが、アプリの仕組みなど競プロに登場しなかった要素を学び、チーム開発のフローや開発ツールなどに慣れれば、競プロで身につけた強みを活かして、開発をリードする存在になれると考えています*1

競技プログラミングとソフトウェア開発の親和性が高いと感じる事柄について、思いついた順に書いていきます。

計算量の感覚

競技プログラミングでは「計算量が O(N^{2}) のアルゴリズムは思いつくが、 O(N \log N) で実装したい……ぐぬぬ……」としている時間が結構あるかもしれません。そこが面白いところでもありますが、残念ながら estie でやっているウェブアプリ開発では、計算量を削減するために頭をひねるようなシーンはほとんどありません。ただ、自明な計算量削減を行うシーンは日常的に存在します。

例えば、「ビル一覧を取得し、各ビルに所有者情報を付加する」という関数を考えてみましょう。ビルの数を N 所有者の数を M としたとき、素朴な O(NM) のアルゴリズムは次の実装のようになります。

def find_building_owners(db: DB, params: Params):
  buildings = db.find_buildings(params)
  owners = db.find_owners(params)
  for building in buildings:
    for owner in owners:
      if owner.id == building.owner_id:
        building.set_owner(owner)

  return buildings

ここで HashMap などを使うことで計算量を O(N+M) にできます。

def find_building_owners(db: DB, params: Params):
  buildings = db.find_buildings(params)
  owners = db.find_owners(params)
  
  owner_by_id = HashMap()
  for owner in owners:
    owner_by_id[owner.id] = owner
  
  for building in buildings:
    owner = owner_by_id.get(building.owner_id)
    if owner:
      building.set_owner(owner)

  return buildings

競プロをやっている人にとってはあまりに簡単に思えるかもしれませんが、estie に限らず実際の開発の現場では、前者のような素朴な実装になっている場合がほとんどです。もちろん NM が十分に小さければ問題ありません。しかし、実際には N=2000, M=2000 のようなケースでページの表示が数秒遅れ、ユーザーに「なんとなくモッサリしたウェブサイト」という印象を植えつけていることがしばしばあります。

こういった簡単な計算量削減を、意識せずに指が勝手にやってしまうようになっていることが、ユーザーの満足度を高めるウェブサービス開発につながっていると考えています。

実装の速さ

競技プログラマの実装スピードは圧倒的です。単純にコードを書くのが速いというのもありますが、そのコードに含まれるバグが少なく、リリースまでも速いというのもあります。

コードを書く速さは、コードを書き慣れすぎているということから来ていると思います。コンテストに出れば1問あたり大体30〜50行ほどコードを書きます。仮に2000問解くと考えると、単純計算で8万行くらい書いていることになります。この8万行全てが重要な意味を持つとは思いませんが、これだけ書くと流石に身体が覚え、コードを書くこと自体に脳のリソースをほとんど割かずに、脳内にある実装を指へ出力するだけの作業になるような気がしています。競技プログラマの異常なコーディング速度は、コードを書きすぎて考えなくてもコードが書けるようになったという、マッチョな要因があると考えています。

実装したコードにバグが少ないことも根本は同じだと思います。競プロをやっている人は、3次元の DP 配列の添字が合わなかったり、二分探索が実行終了しなかったり、セグ木で配列外参照したり、とにかくとんでもない数の自分が埋めたバグと格闘した経験があると思います。競技プログラマは大量のコードを書く中で大量のバグを埋め込み、それを見つけ出して潰してきた経験があります。そうした中で、バグの痛みを身体で覚え、直感的にバグりそうな部分やエッジケースが見えるようになったというものだと思います。

このように、実装ノウハウの蓄積によるものというよりは、コーディングとバグ修正のやり過ぎで身体が覚えてしまった結果だと思いますが、競技プログラマには圧倒的な実装スピードがあり、それは高速な製品リリースに活かせると思います。

設計

実装がとんでもなく速いことによって、ソフトウェア開発で重要視されている様々なステップをショートカットできます。

ソフトウェア開発の現場では手戻りを嫌って、できるだけ実装前に不明点を洗い出し、コードを書き始める前に周到に設計を行うことが多くあります。もちろん、着手する前に不明瞭な部分を明らかにしておくことは大事ですが、やってみて初めて分かることも少なくありません。手戻り上等で見切り発車し、書いては捨てを繰り返しても、実装スピードが十分速ければトータルで見て短期間で完了できます。

また、会社の規模や業態にもよりますが、大抵のコードは数年で寿命を迎えます。必要なときにガッとリビルドできる実装力があれば、少しでも延命するように設計に工夫を凝らす必要もありません。

おわりに

実のところ「競技プログラマと一緒に働きたい!」という強い気持ちがあるわけではないのですが、一緒に働きたいソフトウェアエンジニア像を洗い出していったら、結果的に競技プログラマとかなり近くなった次第です。

現在 estie では、Whole Product 構想を掲げ、新規プロダクトを次々に立ち上げて同時に走らせています。作りたいもののアイディアは無数にあり、試行回数を増やすため、開発を加速していきたいと考えています。資金調達もしているので、あとは実装力の高いエンジニアの皆様にガンガンご入社いただき、バリバリ開発していただくだけです。

この記事を読んで自分のことだと思った方は、今すぐご入社ください。

対戦ゲームの狂気の中で身体に刻み込まれるような実装力を OJT で身につけるのは難しいと思いますが、ソフトウェア開発に必要な知識は2ヶ月もあれば最低限カバーできると思います。estie では既に先駆者たちが道を整備していますので、実装力だけご持参ください。

hrmos.co

hrmos.co

*1:ちなみに estie にも多数の競技プログラマが在籍していて、AtCoder のレート順で上から4人選ぶと色は橙、黄、黄、黄となりますが、4人ともそれぞれのチームで開発をリードしています

© 2019- estie, inc.