2015年9月9日水曜日

良いプログラマになるための5つのコツ

先日「プログラマの履歴書」という記事で「コンピューターを使って世の中をほんの少し便利にすようとする」ことが良いプログラマになるきっかけと書きました。先日「どうしたらプログラミングができるようなるか」という質問を受けたので、参考になればと思いもう少し掘り下げてみることにします。

1. 「どの言語を学べば良いか」という問いから離れる

ノーベル賞はこうして決まる」という本には、セレンディピティ(serendipity: 偶然から生まれる偉大なる発見)という言葉が頻繁に登場します。ノーベル賞は狙って取るものではなく、科学への貢献に邁進するなかで生まれてくるものだと。

その一方、「Serendipity favors the prepared mind (偉大な発見は、準備ができている頭脳を好む)」とも言われます。プログラミングを始めるにあたってどんな言語を学べば良いかという問いに対しては「何が将来役に立つかはわからない」というのが正直な答えで、何も学ばなければ偶然による成果も生まれません。今は亡きスティーブジョブスがたまたまCalligraphyのコースを大学時代にとっていたおかげで、現在のMac OSの美しいフォントの誕生につながったという例もあります。

したがって「どの言語を学べば良いか」という問いは本来「どの言語が効率的に◯◯を実現できるか」という形であるべきで、この◯◯に当たるプログラミングでできることを知る為には、プログラミングを学ばなくてはいけない、という鶏と卵の関係にあります。問題に適したコードを書くには、それまで慣れ親しんだ言語を元に考えることになるので「準備」が必須です。

将来どんなことがプログラミングで実現できるかを予想するのは難しく、学び始めたばかりのころは動機付けが十分ではありません。そのためプログラミングを勉強するというのはあまり楽しい作業ではないはずです。一度1つのプログラミング言語を学んでからは比較対象ができるので他の言語を学ぶのは容易になってきます。Scala, Python, Rubyなど比較的新しい言語は、昔の言語の悪い面を改善しているので使いやすいのですが、C++を学ぶと、なぜこれらの新しい言語がよくできているのかより一層わかってくるという具合です。

2.「プログラミングをする環境に身を置く」

プログラミングを学ぶには、コンピューターサイエンスのカリキュラムを持つ大学に行くのが確実です。例えば、東大理学部情報科学科のパンフレットではどのようなことを学ぶかが詳しく紹介されています。それ以外の専攻や、大学を既に卒業された方でも、MITのオンラインで学べるcousewareCouseraなどを利用する、オライリーの本を読む、GitHubで他人の書いたコードを読むなど学ぶ資料には事欠かないはずです。一人で学ぶことももちろんできますが、動機付けや新しい知識を仕入れる面で効率が悪いので、一緒に学んでいる仲間がいる環境に飛び込むことが大切です。たとえば、Emacs, vimなどのエディタのどれが良いか、効率的な使い方などを周りの様子から知ることができます。大学で皆が集まって学ぶ意義はまさにそういった環境をつくる点にありますし、いろいろな知識を持った人と触れることでセレンディピティにつながる確率が上がります。会社がそのような環境であると幸せですね。

3. 「プログラミング以外の世界に触れる」

コンピューターサイエンスの知識を持った人が必ずしも世の中を便利にする製品を作れるとは限りません。今では、コンピューターを効率的に使うための研究をするコンピューターのためのサイエンスの世界は少し狭くなってきたと言えます。一方、ゲノムサイエンスのように、コンピューターを活用できる、あるいは活用しないと対応できないような世界はますます広がっています。「プログラミングの知識」かつ「他分野の知識を持ち、コンピューターで解決できそうな問題に気付く」この組み合わせを持った人が、今までコンピューターサイエンティストが想像もできなかったようなアプローチで世の中にインパクトを与えることができます。また、その過程でプログラミングがしやすくなるようなツールも生まれてきたりします。

4. 「人と協力する術を身につける」

プログラミングに習熟してくると、いろいろな機能を自分一人の力で実装できるようになりますが、やはり自分ひとりの力でできることには物理的な限度があります。10個のプログラミング言語でコードが書けても、同時に作業できる問題は1つか2つ。一人で知識を溜め込んでも、作れるプロダクトの種類はそう多くはありません。能力をスケールさせるためには、アイデアを他の人と共有する、文章を書いて他の人が時間を置いて理解できるようにすることが大切です。大学の論文などでは、数年、数十年後に論文の内容を理解した人が素晴らしいアプリケーションを見つけてくれるかもしれない、という気の長いものもあります。アイデアの共有には時間がかかることを覚悟します。コミュニケーションでの礼儀正しさも要求されるでしょう。オープンソース開発を支援するGitHubは他の人と共同してコーデイングするための環境を築いたという意味で、非常に大きな貢献をしています。また、英語を使わないというだけでも協力者の範囲を狭めプロジェクトの生存期間を短くします。

5. 「良く寝ること」

プログラミングの作業はどうしても目、肩、腰、脳など体に負担がかかるものです。デバッグ作業など原因の究明に試行錯誤と集中力が要求されるものもあります。毎日8時間以上コードを書き続けるというのは至難の技で、持続可能ではないでしょう。睡眠が必要なのは健康という意味だけではありません。プログラミングではパズルを解く感覚も必要になってきます。ワーキングメモリにいかにたくさんの情報があるかで、複雑に絡み合ったコンポーネント間のつながりを意識したコードを自然に書けるかどうかが決まってきます。音楽を演奏する人でも、たくさん練習をするより、楽譜を読んで寝てしまったほうが、次の日に自然に演奏できるようになるそうです。これは寝ることで記憶が再構築された状態で定着し、脳からの指令がスムーズに指に伝わるようになるという原理です。(参考:TED: The benefits of good night sleep)   睡眠もプログラミングには欠かせない要素の1つです。








2015年9月1日火曜日

プログラマの履歴書

コードを書け。それが履歴書だ」という昔の名台詞が目に留まったので、常日頃感じていることを書き出してみることに。

コードが GitHubで公開してあると、まず採用する側の視点としては非常に助かります。プロジェクトを2、3つ眺めるだけでも、この人が普段どんなことを意識してプログラミングしているのかが見えてきます。例えば、性能を重視しているとか、拡張のしやすさを意識してインターフェースをデザインしているとか。さらに本人の興味の方向性、得意な言語などがわかるが何より嬉しい。過去の経験から、自己申告でJavaができます、C++ができますなどと言うだけの人が期待したレベルでコードを書けた試しがありません。

その次にわかるのがコミュニケーションスキル。基礎的な英語力の判断材料にもなるし、チームを組んだ時のイメージがしやすい。問題を共有する能力も大事。自分一人の頭の中でたくさん難しいことを理解して解決できる天才肌タイプの人もいますが、大事なのは頭の中の問題を外に出して、自分以外の人も取り組めるようにすること。そうすることで、自分でコードをメンテナンスしなくなっても(大抵のプロジェクトは遅かれ早かれ自分の手を離れることになります)問題意識が共有されプロジェクトが成長していきます。自分一人でできることというのはたかが知れていて、自分が休んでいるときにでも物事が進んで行く様子を見られるのは非常に幸せなことです。

僕の転職活動での例を出すと、大学での研究者という立場から突然Treasure Dataというビッグデータ解析基盤を提供する会社のエンジニアになったのですが、履歴書として大事だったのはやはり自分のGitHubリポジトリでした。論文を書いていてもプログラミング能力の証明にはならないし、データベース分野の知識があるのと実装ができることはまた別の能力です。転職の相談の際にCTOの太田くんが既に僕のGitHubリポジトリを見てくれていたのでその後の話がとてもスムーズでした。

ただし、普通の研究者や、日々の仕事や子育てで忙しい人がGitHubのリポジトリを充実ささせるのは難しいのではないか、という思いもあります。僕の場合は、仕事で必要になったものをちょこちょこ外に出していたので、Treasure Data創業者の古橋くん(fluentd, MessagePack, embulkなど種々の人気オープンソース製品の開発者)ほど野心を持って出していたわけではありません。彼の凄さは、MessagePackを開発したらアルバイト先の基幹コードにそれを捻じ込んでから帰ってくるというあたり。それも複数の会社に。

僕の作ったものの中ではsqlite-jdbcというSQLiteデータベース(ファイル1つでDBになるお手軽DBMS)をJavaから使えるようにしたコードがあります。最初はGoogle CodeのSubversionで管理され、次はBitBucketのMercurial、その次はGitHubと転々としていて時代を感じますが、開発のきっかけは既存のsqlite用のjdbcドライバだとインストールや設定が必要で大変だな、という点から始まりました。それならsqliteをコンパイルしたライブラリをjarファイルに埋め込んでインストールを自動化したものを配布しようとしたのがきっかけです。これがあると、ゲノムブラウザのようなWebアプリをDBを含めて1つのフォルダにまとめられて非常にポータブルに実装できます。

DBを扱っていると圧縮ライブラリも必要になり手頃なものを探していたのですが、ちょうどGoogleがSnappyという400MB/sec.を超える性能で解凍できるライブラリを公開したばかりだったので、sqlite-jdbcで培ったテクニックを利用できると思い、Snappyの公開から数日でsnappy-javaを作成しました。これはタイミングが非常に良くて、今では、Sparkなどの有名プロジェクトでも使われていたり、Maven Centralで月間10万回以上もダウンロードされています。自分以外の人が自分以上によく使ってくれているコードで、なんだか不思議な感じがします。

逆に多大な労力を割いたけれど、あまり広くは使われていないコードもあります。先に挙げたゲノムブラウザ(UTGB)のコードは、Railsの用に簡単にゲノムブラウザを立ち上げられるフレームワークになっています。これはもう少し普及活動を頑張っても良かったプロジェクトなのだけれど、大学でコードを書ける人を見つけるのに非常に苦労して、自分自身が進めないとどうしようもなくなったので停滞してしまったプロジェクトです。Silkという大規模データ処理用の分散ワークフローエンジンもありますが、これもScalaでたくさんのコードを書きましたが、まだ外のユーザーを捕まえるに至っていません。協力者を得るにも、そもそも分散計算のフレームワークを書けるプログラマはなかなか見つかるものではありません。一方、Silkの開発に必要だったので作成したsbt-pack(Scalaプロジェクトをパッケージングするプラグイン)、sbt-sonatype(ScalaプロジェクトをMaven centralにアップロードするプラグイン)などはよく使われていて、目的がはっきりしていて手軽なものほど普及するというのを実感しています。

このようなツールを作成していたのも、ゲノムサイエンスという、コードを書いてデータを分析しないと仕事が進まない分野にいたからであって、純粋にコンピューターサイエンスやデータベース分野の研究をしていたら、コードを書き続けていたかどうか自信がありません。アカデミアでキャリアを築くには、残念ながら品質の良いコードを書くことが最短ルートではないので、コンピューターサイエンスの学歴があっても、採用の時はそういう目で評価しています。(ただし、コンピューターサイエンスの素養の中には、プログラミングに重要なものも多々あって、オブジェクト指向やコードの安全性、型理論、計算量、ハードウェアのアーキテクチャなど、それを知っている人とそうでない人の書くコードには歴然の差があります。)

「コードを書け。それが履歴書だ」というのは簡単ですが、仕事であれ、日常であれ、身の回りで起こっている日々の問題を、コンピューターの力を使って解こうとすること、また、そうできる環境に身を置くことがまず必要です。そういう意味で、Treasure Dataはコードを書いて問題を解決しようとする人が集まっていて良い職場だと思います。オープンソース活動に専念しているエンジニアもいる(しかも高給!)など、興味がある方はこちら(採用情報)を参考までに。ワークフローエンジンSilkもTreasure Dataに来たおかげで、問題意識を共有する仲間も増え、リニューアルして生まれ変わりそうな雰囲気になってきました。

コンピューターを使ってこんなものを作ったら世の中をほんの少し便利にできる。そう思えること、そして自分がそれを実現できるとコードを書くことを通して自信をつけていくことが、良いプログラマとして自立していくためのきっかけになるのではと思っています。



License

Creative Commons LicenseLeo's Chronicle by Taro L. Saito is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 2.1 Japan License.