κeenのHappy Hacκing Blog | Lispエイリアンの狂想曲

独学のプログラミング

誰向けなのか分からない。多分5年後くらの初心を忘れた自分が読めば良いと思う。あるいは、独学でプログラミングを始めようとしてる人が参考にするのかもしれない。

私はプログラミングを独学で学んだ。

初めて触ったのは中学生のとき、ネットゲームのギルドのホームページを作ろうとなってHTML、CSS、JavaScriptという存在を知った。イヌでもわかるJavaScript講座を見てメモ帳で書いた20行くらいのスクリプトが当時の最高傑作だった。

それから名前の訊いたことのあったC言語を学ぼうとしたが、Vijuaru Stajioのインストールが出来なくて挫折した。CとC++とC#の違いも分ってなかった。

その後、ネットゲームもしなくなり高校の間は全くプログラミングに触れずに大学に入った。

1年夏学期の情報の授業でシェルを知った。最初は慣れなかったが次第に使えるようになって、家でもコマンドプロンプトを使うようになった。冬学期の情報科学でrubyを知った。あくまで情報科学であってプログラミングの授業ではなかったが、rubyに興味を持った。Ruby入門を見ながら覚えた。メソッド、クラス、オブジェクト指向…。カタカナ語が多くて中々頭に入らなかった。

一つ、ターニングポイントになったと思うのはRuby逆引きハンドブックを買った時だと思う。どんな本かも分からずに買った。そして最初から最後まで読んだ。これで一通りプログラミング言語で何が出来るのか分かった気がする。手札の確認というか。逆引きを買ったのが1年生の冬学期の終わりだったかな?そしてバッチファイルで書いていた処理をrubyで置き換えたりしていた。

その頃にはラップトップにCygwinが入っていた気がする。そしてEmacsをCygwin内で使っていた。いや、怪しいな。Cygwinのbinにパスを通してコマンドプロンプトからEmacsを使っていたかもしれない。

春休みにプログラミングのバイトに応募してみた。それまでは個別指導をしていたが、兄弟会社でバイトを募集していると告知されたからだ。プログラミング試験はrubyで書いて恐る恐る提出すると合格だった。面談の結果Androidチームに入った。Javaは一行も書けない。最初のミーティングまでにJavaを覚えようとしたが間に合わなかった。戦々恐々と出社したが、仕事がみんなに降ってきて、自分の出来そうな仕事をして相応の報酬を貰う制度だったのでとりあえずのところ書けなくても困らなかった。

2年生の夏学期。JavaとAndroidとEmacsを勉強していた。PC系サークルにも入った。確かこの頃Ubuntuを使い始めた。バイトはまだ一度もアサインされたことはなかったがどんな仕事はどんな人が持っていくのかはなんとなく分かってきた。Emacsの設定を触るうちにLispに興味を持ったのもこの辺じゃなかったかな。

2年生の夏休み。合宿と強化練に忙殺されていたがバイトのタスクアサインに初めて手を挙げた気がする。君にはこの仕事はまだ早いと言われ、貰えなかった。もう一つ、ここで進路の決断を迫られた。大学に入ったときは数学科に行くつもりだったが情報系も検討した。最後まで悩んだ挙句数学科を選んだ。今思えば大失敗だったが後悔先に立たず。

2年生の冬学期。学科の周りの人を見て絶望した。レベルが違い過ぎる。高校の数学が少し得意程度の人が来るべきところではなかった。数学者になる夢はここで潰えた。この時期は授業が少ないので我武者羅にプログラミング関係の情報を集めた。この頃にはRuby、Common Lisp、Javaが使えた筈。でもJavaが嫌いでAndroidアプリをJava以外で書く方法を捜してた。JRubyとRubotを試したけど遅すぎてダメだった。Clojure、Scala、Haskell、OCamlなどの名前もこの辺で知った。Clojureは少し触ってみた気がする。バイトで初めてのタスクアサインを受けたのもこの頃。プログラムを書く仕事ではなくテスターだったが。

これ以降、順調に学んでいった。QtRubyで胃に穴が空きそうになったり、どうしてもCommon Lispが気になって6月にShibuya.lispに初めて参加したり。

2つ目のターニングポイントはISUCONだった。ISUCONの案内はPC系サークルのOBから来た。学生枠を設けるから講習会を開くとの案内。その頃は腕に覚えがあったのでバリバリスコア伸ばすつもりで夏期講習に参加した。コテンパンにやられた。手も足も出なかった。Webアプリケーションがどんなものかは分かっているつもりだったがSQLも知らないしNginXの設定も3時間くらい格闘して結局出来なかった。悔しいので予選でリベンジしようと思った。懇親会に出ると同じような人が何人かいて、チームを組むことになった。予選でも手も足も出なかった。私がNginXの担当になったがチューニング方法も全く分からなかった。神風が吹いて上位の学生チームがFailして本戦に出場することになった。流石に本戦で恥かしい思いはしまいと公式ブログの解答例を二人で復習した。NginX、SQL、Capistranoなどの知識を得た。そして本戦。善戦した。他の学生チームが全てFailするというまさかのオチで学生賞をとった。

ISUCONで学生賞を取ったのとISUCON関係でフォローした人の影響でOpsの方にも興味を持った。

そういえばこの頃、睡眠時間を気にせずIT系の情報を漁っていたら体調を酷く崩してバイトを辞めた。

思い出せばこの頃に色々と変わった。変わったというか壁を破ったというか。それまでコンスタントに参加していたShibuya.lispのLisp Meet Upで初めてLTをした。初めてのまともなOSSであるCIMを作った。プロコンに参加してみた。

そしてそれから1年、勉強会で喋ってGithubで活動してISUCONに出て若干コンピュータサイエンスに興味を持った今の私になった。4年生では数学科らしからずパタヘネとMINIX本を講究でやっている。


これで大体合ってる筈なんだが書きたかったのはこういう事じゃなかった気がする。何がきっかけで殻を破ったか、どうやって独学で身につけたか。時系列は無視して書き連ねていく。

上でも書いたように逆引きRubyが1つのターニングポイントだった。でも、どうしても書きたいものがあまりなくてソースコードを読んだ。WEBRicks。その頃はまだHTTPサーバーの仕組みを分かってなかったから理解出来なかったけど雰囲気は分かった。それとrush。今では死んだプロジェクトだけどrubyで書かれたシェルに夢を抱いてソースを読んだ。

最初の頃は何でもググってた気がする。英語はスルーしてた。Common Lispを始めた時にはマイナー言語の宿命で英語は避けて通れなかったので肚を括った。しかしドキュメントも無いプロジェクトも多数あって、結局ソースをかなり読んだ。

WEB上の情報も頼りにしてたが、やっぱり書籍が便利だった。ディスプレイが1つしか無いからブラウザとEmacsを行き来するのが面倒だったというのもあるかもしれない。今数えると50数冊持っていた。図書館で借りて読んだ本もあるから読んだ本だともうちょっと。

上には出てこなかったがFreeBSDをKVM上で動かしている。FreeBSDを触り始めた時にはマニュアルを頼りにしろ、と書いてあった。成程、便利だ。それ以来ググるより先に公式ドキュメントやmanページを先に引くようになった。特にmanを引けるようになったのは大きかった気がする。

「Lisperは一度はLisp処理系を書く」と言われて言語処理系に興味を持った。Rubyやmrubyのコードを読んで図書館でそれっぽい本(後にドラゴンブックと分かる)を手にとった。就活でプログラミング課題が出たときにJavaを書きたくなくてLispを実装してLispで解いた。初めてのLisp処理系だった。それからpicrinを見かけてpicrinにコミットし始めた。言語処理系が中で何をやっているか、そして一番GCなどのメモリ管理について理解が深まったのは大きかったと思う。

低レベルの世界はパタヘネが導いてくれた。picrinにコミットし始めてCをゴリゴリ書いたのもある。高速なコードを書こうと思った時にアセンブラやCを知っていると全然違った。どうすれば速くてどこが遅くなる原因なのか。勿論、ドラゴンブックで最適化も学んだのでどの程度は処理系がやってくれるのかも少しは分っていた。

デバッガはpicrinを開発してるときに覚えた。WEBにいくらでも資料がある。実はそれまではずっとprintfデバッグしかしたことがなかった。それからCommon Lispでも少し使うようになった。他の言語はまだ使っていない。

理論の世界はOCamlとプロコンが入口だった。プロコンは賞金が出るらしいときいてリクルートプロコンに出た。4/10問解けてそれなりに満足して、少し興味を持った。chokudaiさんの講座を受けたり蟻本を買ったりして学んだ。Common Lispで実装しようとしてたらアルゴリズムイントロダクションを勧められた。図書館で借りた本だったので逃げてしまったが道具箱のカタログには入った。 OCamlは、「数学科の主な就職先は金融」「金融では主にOCamlが使われている」と訊いて始めた。OCaml界隈を追ってると、型だとかTaPLだとかCoqだとかが聴こえてきた(主に名古屋の方面から)。少し齧った。そこから関数型言語の世界に入った。HaskellもRWHをざっと読んでモナドを知り、SML#からSMLに入って、SMLも追ってみた。主に研究に使われているらしく、面白い機能を持った処理系がいっぱいあった。型安全pickling、リージョン推論、モジュールのコンパイル時畳み込み…。だいたい論文にリンクが貼ってあって、そこから論文を読むことを覚えた。

バージョン管理システムは.emacsの管理をsvnで始めたのが最初だった。バイト先が最初svnだったから。DropBoxにsvnサーバを置いてちまちま使っていた。init.elだけはRCSで管理してた時期もあった気がする。バイト先がgitになってから手元もgitに以降した。gitbreakに.emacsを置いた。この時点ではまだGithuはソース読もうと思ったら良く出てくるダウンロードUIが最悪なサイトだった。しかししょっちゅう出てくるので義務感に刈られてアカウントを作った。Shibuya.lispでLTするにあたり、サンプルコードを置くのに初めてpushした。いや、Octopressのブログが先だったか?いずれにせよ3年生の9月あたりからコミットを始めた。gitは経験とWEBで覚えた。今はgit helpを参照している。

OSについてはLinuxディストリを試して回ったときに学んだ。最初はUSBに焼くことしか知らず、同じUSBに何度も色々なディストリを焼いた。Ubuntuの次はArch、Gentoo、FreeBSD、 OpenSUSE。Gentooはブートローダやパーティションについて知る良い機会だった。PCを何度も再起動するのが耐えられなくて回避策を捜したらKVMが出てきた。三つ子の魂なんとやら、今でもコマンドラインからkvmコマンドで仮想マシンを起動している。そして今はMINIX本でもうちょっと詳しくOSについて学んでいる。

AIはLispをやってると自然と行きつく。WEBを参考にしながらオセロのAIを作った。そのとき初めてSchemeを触った。なんでSchemeを選んだのかは覚えてない。SICPの影響だったかPC系サークルで部誌を書くにあたりSchemeのチュートリアルがあってそれに乗っかって選んだのか。ほぼGaucheのマニュアルだけでやりきった。魔法のように見えたAIが人工無能であることを理解した。探索、MiniMax、αβ法なんかも理解した。将棋のAI、碁のAIの本も買った。そこで機械学習を知った。

データ解析はビッグデータの流れから本を捜して学んだ。R。正直そんなに身に入ってないが心には留めている。

機械学習はAIの流れとデータ解析の流れの合流地点だった。WEB、データ解析の本、AIの本などで断片的に知識を仕入れた。これもあまり身に入ってないがディープラーニングや画像処理の話題についていける程度にはなった。

画像処理はAIの流れだった。五目並べに似たConnect 6というドマイナーなゲームのAIを作ろうとした。棋譜を打ち込むのが面倒だから画像処理でやろうとした。結局処理は出来なかったけど画像処理が裏で何をやっているのか、OpenCVで何が出来るのか、機械学習がどう使われるのかなどが分かった。公式マニュアルとWEBとオライリーのOpenCVも図書館で借りた気がする。道具箱に入った。

ネットワークは自宅サーバを立てようとしてルータをいじった時に少し覚えた。WEBで情報を得た。OSをインストールするときにも最初に設定が必要になる。正直まだまだ知識が足りてない。TCP/IPの本を流し読みしたけど覚え切れなかった。

UnicodeやエンコードはpicrinをUnicode対応させようとしたときに調べた。WEBだとどうしても表面しか書いてない記事が多くて欲しい情報を探しきれなかったので本を買った。

上に書いたことだと、勉強会はShibuya.lispが暖かく受け入れてくれたことから始まった。怖がらないことが大事。そしてLTを録画してくれるので見直して喋り方やスライドも改善した。

OpsはISUCONがきっかけだった。Twitterで流れてくる情報を追った。運用に興味を持った。でも、自分で運用しているサービスなんてない。サーバもない。多分だから早くエンジニアになりたいと思ってるんだと思う。

データベースもISUCONがきっかけだった。SQLも然り。そこからNoSQLに行って7つのDB7つの世界を読んだ。道具箱のカタログの中身が増えた。データベースの実装が気になって少しRDBを作ってみた。トランザクションとかバックアップとかクラスタリングとかはまだどう実装するのか理解していない。

Linuxプログラミングは自然に覚えた。シェルが内側で何をやっているか、高速なWEBサーバの背後にあるのは何か。データベースを効率的に実装するには何が必要か。picrinに機能を追加する時に最終的に何を使うのか。

ここで上に書いたものを改めて見てみる。何が必要で何が必要でないか分からない。全然足りない気がする。CPU作ったこともコンパイラ書いたこともデバイスドライバ書いたこともない。同年代の情報系の人は何を学んでいるのか。情報科学科と情報工学科でどれくらいの違いがあるのか。エンジニアに必要なスキルは何なのか。やっぱり見えない敵と戦っている。

文系からエンジニアになったという人を見掛けた。見てると、大学に入り直して情報科学を体系的に学びたいと言っていた。彼女も多分見えない敵と戦ってるんだと思う。

何だろう。大学を出るまであと3~4ヶ月。あと何を勉強しておけば良いのかな。

Written by κeen