スタンフォードのコンピュータサイエンスの授業の感想

いまのところ25単位分(マスター修了に必要な単位数の約半分)の授業を取ったので感想を時系列でちょっとまとめたい。昔のやつは記憶が曖昧になっているけど。

CS243 プログラムの解析と最適化 (2014Q4)

要するにコンパイラの最適化の授業。前半はデータフロー解析とかでかなり実用的な感じがしたが、後半は行列計算の命令の依存関係を抽出してベクトル最適化とか、ItaniumみたいにレジスタのたくさんあるCPUでループアンローリングするみたいな話で、実際に役に立つのかはよくわからなかった。

と、そのときは思ったが、巨大な行列の計算はよくあるので、興味を持てなかった僕がダメだっただけかもしれない。

とにかく難易度が高かった。かなりがんばって夜中までやっていたつもりだけどもっと真剣に取り組むべきだったかもしれない。なにせこれが最初の授業だったのでレベル感がよくわかっていなかった。教授がドラゴンブックの著者の一人なので教科書は当然ながらドラゴンブックだった。

あとこれで実感したけど、いい学校使われている教科書だからといって全部を読むわけじゃないし学生が全部を理解しているわけじゃないのね。実際にはほんの一部を拾い読みするだけだし、その部分でもよく理解している学生はほんの一部。それを勘違いしていて最初から最後まで読んでくる人っていうのは嫌いじゃないけど。

お勧め度: ⭐️⭐️⭐️

CS143 コンパイラ (2015Q2)

コンパイラ入門の授業。逆順になるのでCS243の後に取る人はいないと思うけど、面白そうな授業だなと思って。

COOLという教育用の独自のオブジェクト指向言語を実装するという授業で、ある程度できているCOOLコンパイラがあり、欠けてる部分を宿題1回ごとに完成させていく。まずレキサーをlexを使って完成させ、パーザをyaccを使って書き、ASTをトラバースして型をつけて、最後の宿題でそれをMIPSのアセンブリに出力するということをやる。かなり面白い。言語自体も継承とvtableのあるオブジェクト指向言語で、実用的な言語とまでは言えないものの、完全なオモチャというわけでもない。

この授業もかなり時間が必要だった。最後は週末では足りずに有休をとって一日中宿題をやってたりした。

座学の方ではRE、LL、LR、LALRパーザみたいな構文解析の理論とか、簡単な型の理論とか、MIPSのアセンブリとか、スタックマシンとかをやったと思う。

テストのある問題では、とあるLRパーザの構文解析表から元の文脈自由文法を復元せよ、というお題がでてビックリした。文法が与えられてLRパーザの構文解析表を作ることはわりと簡単だけど、逆は難しい。その場では気合いと勘で文法を再構成することができたけど、あれは本当はどういうふうにやるんだろう?

お勧め度: ⭐️⭐️⭐️⭐️

CS103 コンピューティングの数学の基礎 (2016Q1)

計算機科学の基礎みたいなコース。計算可能性とか濃度とかを扱って数学の証明を書く。プログラムを書く宿題はなくてひたすら数学の証明の宿題ばかり。正規表現、文脈自由文法とか、P/NP/NP完全とか、プログラムの停止性問題みたいなやつもやる。

この授業、物事を論理的に英語で説明する訓練としてもすごく役に立った。数学の証明といえど人間が読むものである以上、わけがわからない書き方だとダメで、きちんと筋道立てて説明しなければいけないわけだけど、それを何度も宿題で書いているうちに、以前よりずいぶんわかりやすい文章が書けるようになったような気がする。たとえばパッチを書いてそれを誰かに送るときには、一体なにが問題でこのパッチがなにをやろうとしているのかをきちんとわかりやすく説明しなければいけないのだけど、そういう種類の英語の文章を書くための訓練として数学は非常によいのかもしれない。

あとこの授業の講師のKeithという人はとても授業がわかりやすく生徒からの人気もあるようだった。授業のレビューのサイトでも彼は評価が高い。彼は常に情熱的に授業をやるのだが、レビューサイトで「Keithは脳を刺激するようなサブスタンスを摂取しているわけではないと思うのだけど常にアップビートでフレンドリーでハイエナジーなのはすごい」と書いてあってちょっと笑った。彼は最高の講師の部類に入ると思う。

お勧め度: ⭐️⭐️⭐️⭐️⭐️

CS107 コンピュータの構成とシステム (2016Q2)

要するにC言語と低レイヤのプログラミングのコース。C言語でスタックがどうなっているかとか、構造体がどういう風にメモリにレイアウトされるのかとか、マシンコードとか、そういうことを学ぶ。

ある回の宿題では謎の実行ファイルが与えられて、それを逆アセンブルして改変するという課題がでた。5つのチェックポイントをクリアするたびに点数が与えられるという仕組みで、バイナリを編集してそれをクリアしていく。たとえば最初のチェックポイントでは、ある変数が1かどうかを比べてそうでなければexitするみたいなふうになっているので、バイナリを編集してあらかじめその変数に1をセットしておく、みたいなことをやる。5段階目くらいになると解析も結構難しかった。

ただこの問題、チェックポイントをクリアできないとサーバにそれが通知されて毎回1ポイントが引かれるという仕組みになっていたのが鬼であった。そんなことは知らなかったのでとりあえず実行してみると「Boom! 1ポイントが引かれました」とか表示されて、「ふーむ・・」と思って、もう一度実行してみると同じメッセージが出る。それで「あれ? これもしかして俺死んでね?」と気づいた。宿題の説明文をよく読んでみると、不用意に実行するとペナルティを食らうから注意してねと最後の方に書いてあった。そういう重要なことは最初に書いておいてよ。

最後はmallocを実装するという課題がでて、これはかなり楽しかった。ベンチマークが与えられてその数値で宿題の得点が変わってくるのだけど、素朴な実装では全然いい点にはならない。デザインを見直して何度かゼロから再実装したらやっと満点が出るようになった(実際はぶっちぎりで出るようになった)。

ペーパーテストはかなり難しい。Cで書かれた特に意味をなしてない関数が与えられて、この関数にある入力を与えたときにメモリ上のデータのレイアウトを書きなさい、みたいな問題が出る。ポインタとか整数とかが同じメモリ上のアドレスでエイリアスされまくっているので、実際に動かさずに答えるのはかなり難しい。意味のあるコードなら意図がわかるので一行一行トレースしなくても答えられるのだけど、意味がないコードなので頭の中で地道に実行してみるしかない。こういうのは大変。

お勧め度: ⭐️⭐️⭐️⭐️

CS242 プログラミング言語 (2016Q3)

Haskellとかをやる授業。この授業はいまいちだったかもなぁ。Javaの<? extends Foo>みたいなものが何なのかを学ぶことができたのはよかったとは思うけど、あまり面白い授業とは思えなかった。授業も簡単すぎたように思う。

お勧め度: ⭐️⭐️

CS140 OSとシステムプログラミング (2016Q4)

今までで一番大変だった授業。仮想メモリを実装する宿題では中1日で2回徹夜するはめになってしまった。24時間以上コードを書いてデバッグしつづけていると時間の感覚がなくなってくる。ここまで必死でコードを書くというのは久々だった。CS140はスタンフォードのコンピュータサイエンスのなかでも一番労力の必要な授業という前評判があったが、評判通りだったといっていいと思う。(その次に大変なのはCS143らしい。)

プリミティブな教育用OSがすでにあって、宿題ではそれにユーザプロセス、仮想メモリ、原始的なレベルのUnixファイルシステムなどを実装する。カーネルにはプリエンプティブなスレッドがあるのできちんとスレッドセーフなコードを書かないといけない。こういう環境でバグがあると無限に時間の必要なデバッギングに突入してしまうので非常につらい。毎日ずーっとやってもやっても終わらなくて閉口した。

テストではわりと自由回答な問題が出た。○○という前提のカーネルにおいて○○という仕組みは必要か? みたいな。たとえばシングルCPUのシステムでスピンロックは意味があるか? みたいな。メモリマップされた奇妙なデバイスを仮定するとこういう種類の質問はだいたい「はい」が答えになってしまうのだけど、それを回答に書いたら「そんなシステムはとても変だけど正しいは正しい」というので丸がもらえた。採点するTAは大変だろうけど、なかなかよいテストだと思う。

お勧め度: ⭐️⭐️⭐️⭐️

2021年の後編に続く)

この記事が気に入ったらサポートをしてみませんか?