プログラミングのサイドプロジェクトを始めたいきさつ

image
(ソフトについて問い合わせがあったので記入しておきます。Sublime Text 3にMaterializeの”Spacegray Light”を適用、フォントはUbuntu Mono Boldです。)

UC San Diegoでの学生時代は、コンピュータサイエンス(CS)プログラムを専攻する他の学生と同じく、数年間は何となく講義を受けていただけでした。出来は可もなく不可もなしといった感じで、成績の評価点(GPA)も至って普通でした。プログラミングの授業ではやりがいのある課題を楽しんでいましたが、微積分はそれほど楽しくはありませんでした。

今回のブログの投稿ではそれほど技術的な内容は扱わず(気分転換ですね)、私自身のオープンソースプロジェクトの経験について、その経緯を振り返ってみようと思います。これらのプロジェクトがきっかけとなり、私は後にインターンの機会を得ることができました(その中にはAmazonも含まれ、結果的にフルタイムでの就職につながります)。

これを読んでいる方の中には現役の、あるいは将来的なCSの学生もいると思いますが、そういう方たちにとって何らかの刺激を与えることができたらなと思います。

追記:いくつかのsubredditでシェアしてみると、この投稿はとても支持を受けました。おもしろいフォローアップの議論が/r/compsci/r/cscareerquestions、または/r/programmingで展開されているので、興味のある方はぜひどうぞ。

この投稿が気に入った方はぜひ私のTwitterをフォローしてください。

実践的な経験への思い

大学に入ってから3年目に、ソフトウェア開発と実践的なプログラミング、そしてCSの間に乖離がある1ことに私は気付きました。これについては以前の投稿で触れています。

時を経ると共に私が感じたのは、CSのコースに実践的なプログラミングの授業が足りていないということです。私はWebデザインやモバイルアプリ開発などを学ぶ機会をじっと待っていました。自分が簡単なアイデアでさえもソフトウェアスタックとして思い描けないことで、全体的に消化不良な気分だったのです。

ちなみに、上記に関するいくつかの議論を/r/cscareerquestionsで目にしたことで、大学に実践的なCSのコースが少ないと感じている同じような学生が他にも多くいるということを知りました。一方で、もっとあとになってから、大学の授業はプログラミング言語やソフトウェアアーキテクチャを中心に展開しているわけではなく、問題点とその解決法を軸にして考えるよう構成されているということにも気付きました。

当時の私は、ペットプロジェクト(長年暖めてきた計画、企画)がどれだけ就職の可能性を広げてくれるかということを完全には理解していませんでしたが、キャンパスでの様々なテックトークや雇用者による公開討論会などから、サイドプロジェクトが実際に仕事探しに役立ちそうだということを知るに至ります。学生の間では「サイドプロジェクトのポートフォリオがあれば、好成績を取る必要はない」とまで言われていましたが、私自身、これには少し懐疑的でした。

足掛かり

事が動き始めたのは2年生の夏休みで、その頃から私はオープンソースソフトウェアの世界へと足を踏み入れました。依然として、より多くのプログラミング言語を習得することの方に重きを置いてはいましたが、その考えも時間と共に変わっていきましたし、それ自体は悪いことではありません。いずれにしても、それまでにコースの課題プロジェクトでJavaやC、C++言語を使っており、それ以前にはCodecademyや簡単なReddit botプロジェクトで多少Pythonをかじってもいました。

とにかく夏休みを利用してもっとプログラミング言語を習得し、履歴書に箔を付けようとしたのです。

重点的に取り組んだのはJavaScriptとPythonで、PHPにも手を出しました。自分の目標に枠組みができたのはよかったと思います。小さなプロジェクトに着手し、Safariの機能で自分か欲しかったsafcatx-posterRecoverTabsの拡張機能を完成させました。RecoverTabsはGitHubで好評を得た私の最初のプロジェクトで、SafariにCmd+Shift+Tの機能を追加するものです。この機能は他のブラウザには元々備わっているものですが、Safariに関しては不完全と言わざるを得ません。

そのあと少し考えてからWebデザインを学び始め、ゼロから自分のWebサイト(このサイトではありません)を立ち上げました。当時はBootstrapのようなUIフレームワークがあることすら知らなかったので、Webの世界に頭から飛び込み、何もない状態から作り上げたような形です。そのことは最終的に大きな満足感をもたらしてくれました。

これはあとになって分かったことですが、Webデザインを経験したことはバックエンドエンジニアとしても非常に有益でした。フロントエンドについて他の誰もが手を出さない中、自分1人がその知識を持っているというのは素晴らしいことです。そして結果的に、私はモバイルアプリの開発や他のことではなく、専門的そして副業的にWeb(バックエンド)開発の道へと歩み始めることになりました。

それ以降、どんどん知識は身に付きましたが、Webデザインへの愛着は変わっていませんし、それ自体とてもリラックスできる作業です。

ちなみに私の意見では、サイドプロジェクトのポートフォリオを作成しようとしている学生にとって、Web開発は取り組みやすい選択肢の1つだと思います。なぜなら、他に基礎的なことを学びながらモバイルアプリのUIデザインを学習することに比べると、デザインのコンポーネントがはるかにシンプルだからです。Webデザインは作業をすればすぐにフィードバックが得られるので、その点も初心者には大きな励みになるかと思います。

プロジェクトの年

夏休みが終わっても、私はペットプロジェクトを続けました。

フロントエンドのスキルを向上させたあとに重点的に取り組んだのがExpress.jsやFlaskなどのバックエンド用のフレームワーク(補足:両方ともWebアプリを始めるには最適です)です。何かアイデアが浮かべば、他の人に頼らずともUIをデザインできる自信がありましたし、実際に完成までこぎ着けました。

ここまで来たら止まりません。作業はより衝動的になり、Node.jsのAPI wrapperNW.jsを使ったデスクトップユーティリティ、はたまた私が管理するsubreddit用のCSSテーマまで続々と作っていきました。

大学3年生の間は、何時間もぶっ通しでサイドプロジェクトに身を投じることが多くなりました。それが純粋に楽しかったからです。これによりゲームの時間のみならず講義のための勉強時間さえも削られることがありましたが、今、当時を振り返ってみても後悔は全くありません。

自分のプロジェクトから得た経験は貴重な財産です。大学のどんな授業だってそれに取って代わることはできません。

こうして私の輝かしい(そして増殖を続ける)ポートフォリオがGitHubにでき、Learning Equalityでのインターンが認められました。Learning Equalityとは、UC San Diegoのキャンパスをベースに活動する非営利のソフトウェアチームです。そしてこのインターンを通じて、私は初めてソフトウェア開発の”リアルな現場”を味わったのです。短い面接の中で、面接官が私のことを”有力な人材”と言ってくれたことを今でも覚えています。

ちょうどこの頃、私は夏のインターンシップの募集に片っ端から応募していました。ただ、GPAが2.96で優秀とは言えなかったため、引き受け手が見つからないのではという不安も感じてはいました。複数社との電話やオンラインでの適性検査のあと、キャンパス内で開かれるAmazonの面接に誘われたので、さほどの期待もせずに了承し、実際に面接を受けましたが、結果は何と採用でした。

卒業後、このAmazonでのインターンはフルタイムでの就職につながります(最終的なGPAは3.07でした)。本当に天にも昇る気持ちでしたね。

Amazonでのインターンが決まったあともプロジェクトは続けていました。中でも特筆すべきなのがQuibblerです。

豊かなポートフォリオは後に大きな力となってくれます。

初心者の落とし穴

ここで、初心者が自分のプロジェクトを進めるに当たって犯しがちなミスを前提に話を進めたいと思います。中には反対意見が出るものもあると思いますが、これらは私が経験し直接、目にしてきた物事をベースにしたただの意見です。私の経験はすべての人に当てはまるものではありませんから、話半分に聞いていただいて構いません。

オープンソースで設計する

プロジェクトのアイデアが思い浮かんだ時、私は以下の項目を含むプランを事前に立てるようにしています。

  1. 選択した言語/フレームワークにとって最善の実践方法を見つける。
  2. そのジョブにとって適切なスタックを選ぶ。
  3. デプロイとアップデートメカニズムの構想を練る。

プログラミングには、プログラミング以上のことが常につきまといます。しかし授業でソフトウェアのデプロイや配布、アップデートを通じたその後のメンテナンスが重点的に扱われることは少ないでしょう。

プロジェクトに取り組む際には、これらについて事前に計画を立てるのが得策です。サーバ上で自分のWebアプリがどのように動くのか、あるいはデスクトップ用のアプリにどうやってアップデートを送り、アプリ側はどうやってそれを受け取るのかなどについてきちんと考えておきましょう。これらのことは実装する時にも役立ちます。別に時間に追われているわけではないので、時間を掛けて最善と思われるすべての実践手順を必ず踏まなければなりません。技術的な負債を負うという選択肢はありません。

それから、オープンソースで設計するということは、以下の項目に気を配りながらコードを書くことを意味します。

  1. 十分なドキュメンテーションと共にWeb上のリポジトリに提示できるようにする。
  2. 他のプログラマによって解読、解釈、改善可能なものにする。
  3. Webに上げることをためらわない。

これを守ることは、いいコーディングの習慣を身に付ける1つの方法だと思います。単にプログラミングをするだけでなく、ソフトウェアを実践的に開発する訓練をしましょう。

また、雇用主になるかもしれない人に対して自分のコードをアピールすることも忘れずに

まずは小規模で

プロジェクトが小さくて取るに足りないものでも気にせずに、とにかくポートフォリオに加えましょう。

実際のところ、私は小規模なプロジェクトを意図的に選ぶことをお薦めしています。プロジェクトが小さいほど、完成させるのも維持していくのも容易だからです。必要なスキルを身に付けるには特定のものに集中した方が近道です。逆に、新たな巨大ソーシャルネットワークの構築や、完璧な勉強仲間検索アプリなどに手を付けるのは止めた方がいいでしょう。実際にやってみると大変だったということが少なくありません。

JavaScriptを始めるなら、まずはブラウザの拡張機能から始めてみましょう。Pythonを身に付けたい時は、小規模なコマンドラインユーティリティを作って公開してみるといいと思います。時には、デプロイそのものだってチャレンジを要することもあるのです。

初心者なら特に、小規模のプロジェクトでポートフォリオを埋めていった方がいいでしょう。遅かれ早かれ(息切れせずに)何が達成できて、何ができないかがつかめてくるはずです。

一匹狼であるよう心掛ける

共同作業をする相手が見つからないと言って、プロジェクトの着手を先延ばしにしてはいけません。

もちろんサイドプロジェクトを誰かと共同で行うことで得るものもあるかもしれませんが、私自身はこれまで自分1人で何とかやってきました。ソフトウェアアーキテクチャの設計やデバッグ、問題点の解決などを自分だけでこなすのは非常に有益です。

もしパートナーを選ぶのであれば、スキルやモチベーションを考慮に入れましょう。相手があなたと同じベクトルに位置していれば組んでもいいと思いますが、そうでない場合、出口の見えない無限ループに入り込んでしまうかもしれません。サイドプロジェクトはそもそもからして余分な作業です。軌道に乗せるのは大変なことで、負荷の多い作業は誰かに押し付けたくもなります。他の人の作業完了を待つ時間も増えるでしょう。また、経験を積んだメンバーがいる場合、彼らにとっては遅れを余儀なくされることも多くなり、時間の無駄にもつながります。

一方、単独作業の場合は自分で作業時間を確保できますし、他に作業を頼める人はいないので、すべての段階を学ぶこともできます。もちろん多くの困難にも直面し、行き詰まることもあるでしょうが、それを乗り越えることが成長するということではないでしょうか。

いずれにしても、いつかは自分の力で何かを作るよう努力すべきというのが私の意見です。

ソフトウェアのメンテナンスを理解する

オープンソースコミュニティに向けての設計には責任も伴います。時間が経てば、あなた自身も(きっと)オープンソースの文化について分かってくるはずです。ここで覚えておかなければならないのは、Webにアップしたオープンソースプロジェクトのオーナー、そして保守管理者はあなた自身であるということです。第三者があなたのプロジェクトに興味を持てば、彼らはプロジェクトに接触し、提案を与えてくれたり変更をもたらしてくれたりするでしょう。あなたはそれを適切に受容することを期待されています。ですので、バージョン1.0.0でプロジェクトを放置するようなことはしないでください。

一般的にはどんなソフトウェアでも積極的に保守管理することが求められています。それがオープンソースでなくても、ユーザがたくさんいれば古いままにしておくのは賢明ではありません。ユーザは折に触れて新機能を期待するものです。

メンテナンス作業はそれだけにとどまりません。プロジェクトが完成したあとも、生じうるコストには気を配ってください。例えばiOSのアプリを作成してApp Storeで配布するには、年間99米ドルのApple Developer Programメンバーシップ料金が掛かります。私のようにWebデザインの世界に足を踏み入れた場合には、潜在的な雇用主に見えるようプロジェクトを運用状態で維持するために、サーバの時間に対して料金を支払う必要が生じるかもしれません(ポートフォリオのデッドリンクを見たい人はいないですよね)。また、Amazon Web Servicesを試してみようと計画している場合、コストは必ず事前に見積もってください。Amazonのサービスは無料か最低限のコストで使えるものもありますが、一部は使用規模が大きくならないと費用対効果が出ないものもあります。

杓子定規的な教科書のプロジェクトにはノーと言う

これは個人的な好みの問題でもあるのですが、私自身は教科書でプログラミングを学ぶのは好きではありません。教科書向けに作られた演習のプログラミングを完全に否定しています。教科書やオンラインのチュートリアルなどは一部の人にとって、言語やフレームワークを学び始めるいいスターティングポイントになるかもしれませんが(私もCodecademyには、かなりお世話になりました)、単純に何かが欠落しているように感じるのです。

  1. 記載された技術が実際に開発でどのように使われているかが説明されていない。
  2. 実際に直面するような問題や課題が含まれていない。

私の経験則では、役に立つものを実際に作った方がよりよく学習できます。もちろん、オリジナルのアイデアをひねり出すことは簡単なことではありませんが、それについては誰でも同じです。その点を差し引いても、それがプロジェクトに対してモチベーションを維持し続ける最善の方法だと思います。

総じて、私は以前に誰も作ったことがないものだけを作ります。私にとっては新しいアイデアか否かということが重要なのです。

イライラしない

プロジェクトで壁にぶつかりイライラしてしまうことはよくあります。これが講義の課題であれば、大学であれ専門学校であれ、講師やTAがいてその壁を乗り越える手助けをしてくれるでしょう。しかし個人のプロジェクトの場合、そんな贅沢なサポートはありません。

だからと言って、壁も天下無双で立ちはだかっているわけではないのです。幸い、あなたには時間があり、オンラインで解決策を探すことができます。助けを求めることを恥じることはありません。

行き詰まる度に、貴重な経験ができます。時には依存ベースの問題にぶつかり、自分では全く力が及ばずにプロジェクトが座礁することもあるでしょうが、これだって立派な経験です。

ちなみに、プロジェクトに着手する時にも、コードの書き方について助けてくれる講師はいないということは覚えておいてください。

いずれにしても仮にプロジェクトが毎回、失敗に終わっても、その落胆の回数分、メンタルは鍛えられるはずですよ。

プロジェクトを完成する

最後に、すべてのプロジェクトで完成を目指して、少なくとも1回は安定したバージョンをアップできるようにしましょう。GitHubのポートフォリオが、20種類のフォークと行き場のない細切れのアイデアだけで埋まることのないようにしてください。何と言っても見た目がよくありません。雇用主は、プロジェクトを出荷できる自信に満ちあふれた有能なあなたのポートフォリオを見たいはずです。アプリやWebアプリ、そしてWebサービスを適切にパッケージ化して配布し、保守管理しながらアップデートするのは容易ならざる事で、それもスキルの一部と言えます。

おまけ:プロジェクトを目立たせる

あなたの記事にはとても説得力がありました。UC San Diegoの学生がCSについてディスカッションしているのを目にできてとてもうれしく思います。
記事の中の個人プロジェクトについては私も全く同感です。学生の履歴書について、私は彼らによくこんなアドバイスをします。
* プロジェクトを履歴書の上の方に記入すること。
* 専門的な経験がないのであれば、個人プロジェクトを増やすこと。
言うまでもなく、優れたソフトウェアエンジニアを目指すのであれば練習は必要でしょう。そして自分のコード内で何度も失敗をすることが、一番の学習方法です。

Redditユーザの/u/k3q3が、この投稿へのコメントで重要な指摘をしてくれました。プロジェクトは、特に仕事の経験がない場合は、履歴書の一番上に書き込んで間違いなく目立つようにしてください。関連性の高い仕事の経験を除けば、これは履歴書のトップを飾る項目になるはずです。そして雇用する側にとっては、これこそが他の何よりも(専攻コース、成績、GPA)採用の決め手となるものかと思います。

どうやってアイデアを得るのか

ここまでをまとめると、私は共同作業をせず、教科書の演習ではプログラミングせず、新しくてオリジナルのソフトウェアしか作らないということを述べてきましたが、どうやってこれらのアイデアを得るに至ったのでしょうか。

私のプロジェクトに目を通してみると、そのほとんどは革新的という言葉からはかけ離れていますよね。でもそれで大丈夫です。プロジェクトが世界を変えるようなものである必要は全くないのです。それに新しいアイデアを生み出すのは簡単とは言えないので、難しい時には他の人から刺激をもらえばいいと思います。

そんなわけで私は以下に挙げた項目が(すべては私の経験に沿ったものです)、大学や専門学校に通う経験の浅いプログラマの皆さんに刺激を与えられるかもしれないと考えています。

  • 自分のポートフォリオ用Webサイトを作ってみる(例:このサイト)。
  • 生活をシンプルにするようなブラウザのエクステンションを作ってみる()。
  • 自分で決めた言語を使ってAPI wrapperライブラリを作ってみる。API wrapperが増えて困るようなことはありません()。
  • 生活をシンプルにするようなコマンドラインユーティリティを作ってみる()。
  • 他の人がその上に自分のプロジェクトを構築できるような何らかのフレームワーク(デザイン、またはその他)を設計してみる()。
  • Raspberry Piを入手し、Arch Linuxをセットアップする。そしてSSH経由でWebにアクセスできるようにし、センサを接続して部屋の温度などをモニタする。プログラミングの出番はさほどありませんが、学ぶことは多いと思います。
  • Reddit botを作ってみる。/r/RequestABotで誰かのリクエストを実行し、/r/botwatchでhelpとinspirationを見る。

重要なのはとにかくやり始めることです。ソフトウェアプロジェクトを進めるに従って、あなたを刺激するような発見がGitHub上に必ずあると思います。また、他の人がやっていることに注意を払い、自分のプロジェクトに取り入れてみてください。私はWebデザインの愛好家として、パンくずナビやシングルページWebアプリケーション、そしてUX要素などに常に目を光らせています。もしあなたの好みがモバイルアプリの設計であれば、アプリのストアをブラウズするだけでも刺激になるはずです。GitHubで言語や技術などを検索し、最新情報にも目を向けるようにするといいでしょう。

それから、プロジェクトの途中で見つけた他のデベロッパたちと交流してみてください。他の人の仕事を補完するソフトウェアを作ってみてもいいと思います。

お互い頑張りましょう!

Twitterでぜひ交流しましょう。私のプロジェクトについてはGitHubで閲覧できます。