VTRyo Blog

一歩ずつ前に進むブログ

コンピュータの基礎を学び直す -2024 CS50 感想-

ハーバード大学のコンピュータサイエンス入門「CS50」を完走しました。

全編オンラインで完結するコンピュータサイエンスの基礎コース、というのがわかりやすいでしょう。

私は大卒後から10年ずっとITエンジニアですが、未経験就職(いわゆるCSの学位を取ってない)だったのでこのコースは大変よい勉強になりました。

自身の経歴にコンプレックスがある方はおすすめです。

CS50のコースはWeek1から10まであり、それぞれ宿題が課されています。 最初の授業ではscratchを使って、手続きというものを学んでいきます。

youtu.be

プログラミング言語の文法とは無関係な要素を取り除くことで、本質的な部分を先に体験できるようになってるわけですね。

序盤のWeek1からWeek5まではC言語を使って基礎を学びます。
あくまでこれは2024年版です。内容は毎年テクノロジーの進化によって変わっていくものと思われます。

  • Week 0 Scratch
  • Week 1 C
  • Week 2 Arrays
  • Week 3 Algorithms
  • Week 4 Memory
  • Week 5 Data Structures
  • Week 6 Python
  • Week 6.5 Artificial Intelligence
  • Week 7 SQL
  • Week 8 HTML, CSS, JavaScript
  • Week 9 Flask
  • Week 10 Cybersecurity

文字列の気持ちになる、そんなことすらも新鮮

私は普段はGoを扱うことが多いのですが、C言語を扱うのは実は初めてでした。CはStringではなくCharとして一文字ずつ扱うことが前提だったりと、「そうかーなるほどなー」と思うことが多かったです。文字列は文字の配列だし、その文字は識別番号と対応して表現されていますよね。

ja.wikipedia.org

そういった意識してなかったものをもう一度確認しながら、一文字ずつCで扱う瞬間は新鮮でした。

結果的に、Goを書くときの勘所みたいなものが格段に良くなったと思います。

「文字列っていうのは文字の配列であって」「その配列先頭のアドレスを参照すれば、Null終端までが一つの文字列」というメンタルモデルが出来上がったので、例えばこういう実装でdisplayText += string(characters[currentMessageIndex][currentCharIndex]) みたいな所を見たときに何がしたいかすぐにピンとくる。

package main

import (
    "fmt"
    "time"
)

func main() {
    characters := []string{"this", "is", "me"}
    currentMessageIndex := 0
    currentCharIndex := 0
    displayText := ""

    for currentMessageIndex < len(characters) {
        if currentCharIndex < len(characters[currentMessageIndex]) {
         // 文字列が文字の配列であることを理解してないときはピンとこなかった
            displayText += string(characters[currentMessageIndex][currentCharIndex]) 
            currentCharIndex++
        } else {
            // Move to the next word
            currentMessageIndex++
            currentCharIndex = 0
            if currentMessageIndex < len(characters) {
                displayText += " " // Add space between words
            }
        }

        fmt.Println(displayText)
        time.Sleep(200 * time.Millisecond) // Pause for half a second
    }
}
t
th
thi
this
this 
this i
this is
this is 
this is m
this is me
this is me

Program exited.

go.dev

まじで知らなかったコト

Week5でData Structureを学ぶのですが、ここではハッシュテーブルを実装する宿題が出ます。 現代のプログラミングをしている人であれば、ハッシュテーブルと言われればすぐにピンとくると思います。

キーと値の組(エントリと呼ぶ)を複数個格納し、キーに対応する値をすばやく参照するためのデータ構造

ja.wikipedia.org

しかしこれがどうやって構造化されているかは全然考えたことがなく、おそらく最も勉強になった回です。

ハッシュテーブルがなぜキーに対応する値に対して高速アクセスできるのか。それはどういう仕組で成立しているのか。Cでどうやって実装するのか。

実際にコーディングしないことにはこれはうまく掴めなかったでしょう。

youtu.be

楽しかったコト

SQLミステリー

Week7のSQL回。さすがにSQL自体は知ってましたが、この宿題が面白かった。単にSQLを書いて練習したあと、SQL Cityという事例をベースに作成され、CS50では窃盗犯をデータベース内から特定する内容になっています。

mystery.knightlab.com

データベース内に大量のデータセットがあり、犯人の特定を当てずっぽうでやるのはまず無理。しかし愚直にクエリして条件を絞っていけば必ず到達するようにできてます。最終的には大量のネストをして犯人のidを一発で特定するクエリを書いたが、めちゃくちゃ気持ちよかったですね。

ゲーム性があるものの中でもこれは素晴らしいものでした。

Final Project

卒業課題とも言うべきプロジェクト。大学生は誰かと協力してもいいようです。私はひとりなので自力でやりました。

このプロジェクトは時間を掛けるほど作り込みができると思いますが、私は2024年が終わりかけていたのでとにかく目的が達成できる最低限の実装を目指しました。

せっかくなのでFlutterにトライして「ビール何杯飲んだ?」というビールカウントアプリを作りました。

提出するREADMEには750語以上の説明が必要であり、これが中々の分量でした。

ある程度の複雑さがないと750語到達しないかもしれない、と課題説明に書かれており、これで制作物に複雑性を担保させているようでした。

また、デモンストレーションの動画も必要です。限定公開にしているのでよかったら参考にしてください。

www.youtube.com

どれくらい時間かかったか

開始したのが2024年5月という記録が残っていたので、半年くらいかかってます。

仕事しながらなので、通勤時に1.25倍速で講義動画を見る(一回2時間程度)。それが終わったら、家で宿題をやるという流れです。 1宿題もそれなりに時間がかかったので、Week1あたり2週間以上使ってしまった気がします。もちろん取り組めない週もあったので、時間が空いたりもしてます。

結局、12月に長期休暇を取って、2週間で猛烈にWeek6からWeek10まで一気に終わらせるハメになりました。

ただし後半戦はPythonやFlaskを使ったWebプログラミングなので、割とすんなり終わってます。

おわりに

時間はかかりましたが、やはりやってよかったですね。

LinkedInを使っている人はこの修了証を載せることもできるようです。