プログラミング言語の入門が終わったら何の勉強をすればいいの?

JJUG CCC 2022 Fallで「Javaの入門が終わったら何の勉強をすればいいの?」という内容で発表を行いました。
基本的なものが作れるようになったけども、イマイチプログラムが組めないというときに、何を勉強すればいいかをまとめました。

入門が終わって作りたいものがあれば作っていきましょう、業務で言われたものが作って行こう、でもなんだかちゃんとしたものが作れないな、もっとちゃんとしたものを作りたい、次のステップに進みたいというときに勉強していく感じです。

資料はこちらです

とりあげた本についてまとめておきます。

フレームワークは入門でやってる前提です。Java入門書「プロになるJava」ではJavaの基本から簡単なDB操作、Spring Bootまで取り上げてます。

開発作業について

まず最初に、ユーザーは直接的にはコンピュータに載ったプログラムを動かすことでサービスを体験するので、プログラマが直接ユーザーと関わることはないし、プログラムですら直接使われるわけではありません。
そこでプログラムがどのように動いて、そしてそのプログラムをどのように作るか、そのために全体としてどういう知識が必要になるか、というイメージを持つことが大切です。

このエントリではいろいろな本を取り上げますが、どのような分野が必要になるかを把握して、本屋さんに行って自分のレベルに合う本を選ぶのがいいのではないかと思います。
何を作るにしても必要になるプログラミングの基本です。作りたいものを作ればいいとコメントがありますが、ここで取り上げている基礎を勉強すると「作りたいもの」自体のレベルもあがっていくと思います。

概要

ここで取り扱う内容はコンピュータサイエンス、計算機科学といった分野としてまとまっています。つまり、コンピュータサイエンスをまんべんなくやりましょう、という話なんですが、それっぽいタイトルの本にだいたいまとまっています。

ただ、コンピュータサイエンスというタイトルの本は細かく正しく書かれていて分厚く読みにくかったりするので、応用情報技術者試験の本が読みやすいです。ただし、受験対策ではなく内容理解のための本が大事です。しかし受験対策のほうが人気がある。
高橋麻奈さんの本がオススメなのですが、受験対策には向いていないので紙版は出なくなっていますね。Kindle Unlimitedで読めるので、サービス利用者は追加の課金なしに読めます。

プログラミング言語

資料とは順番違いますが、先にプログラミング言語を。
プログラマが直接関わるのはプログラミング言語を利用して書くソースコードです。
入門書はとにかく動かせるようになることに主眼が置かれるので、細かい条件や背景などは省略されがちです。けれども入門が終わったらもう少し突っ込んだ解説が必要になります。
Javaでは「Java本格入門」を挙げています。

ただ、もっと突っ込んだ勉強をしようとするときに、言語仕様などを読む必要が出てきますが、言語仕様を読むためには「プログラミング言語」というものがそもそも何かということを知っておく必要があります。
そこで入口として、命題論理、述語論理などの論理学から、ラムダ計算、型付ラムダ計算という流れで勉強するのもいいかと思います。

そして、型理論です。「型システム入門」という本がありますが、あまりオススメしません。型理論を本格的に勉強するには必ず読まないといけない本ですが、広く勉強する一部としては専門的すぎます。

そこで「プログラミング言語の基礎知識」をおすすめします。この本は「型システム入門」のダイジェストのような本で、たったの176ページ!ただし、3行読むのに1時間かかったりします。

先にコンパイラを作ってみるというのも手です。「ふつうのコンパイラをつくろう」ではJavaCCを使ったパーサーをもとにx86コードを出力するコンパイラを作っています。ただ、ネイティブコンパイルするものではなく、インタプリタだけ作ってもいいと思います。

アーキテクチャ

プログラミング言語がわかったら、次はプログラムを実行する環境です。
Javaであれば、JVMがどのように動くか、特にJITGCについて理解しておく必要があります。「Javaパフォーマンス」にはそのあたりがよく説明されています。チューニングの話まで進むと難しくなっていきますが、概要の説明はそんなに難しくないです。

OSもプロセスまわりは把握しておいたほうがいいけど、「入門コンピュータ科学」での説明くらいでいいかな。 読むならこのあたりを。仮想化やコンテナまで触れられてます。

プロセッサについては「プロセッサを支える技術」を挙げていたけど、より範囲の広い「コンピュータアーキテクチャ技術入門」がいいかもしれない。コンピュータの処理を理解するために、パイプラインやキャッシュといった仕組みは知っておく必要があります。

機会があれば、FPGAでハードウェアをいじくってCPUを作ったりすると、コンピュータが動くイメージの解像度がかなり高くなります。

ミドルウェア

サービスを構築するときに、いろいろな役割のサーバーが必要になります。その中でもリレーショナルデータベースは重要なので、ちゃんと勉強しましょう。
まずは正規化などのテーブル設計を確認しておきましょう。

また、リレーショナルデータベースがどのように動くかというのは、NoSQLデータベースにも応用ができるので、ひととおり知っておくといいです。
この本はMS SQLサーバーの仕組みですが、大枠はどのRDBMSでも同じなのと、ここまで読みやすくデータベースの仕組みを解説した本も他にないので、読んでおくといいです。
資料にあげてたRDBMS解剖学は絶版で中古も高い・・・

あとは「ソフトウェアアーキテクチャの基礎」に運用も含めて細かく解説されています。

ネットワーク

サーバーを構築して複数のコンピュータを連携させると、必ずネットワークで通信します。
「ネットワークはなぜつながるのか」には、イーサネットや光ケーブルといった物理層TCP/IPなど通信プロトコルがまとまっているので、一度読むといいです。

プロになるJava」ではソケット通信でHTTPクライアント・サーバーを構築するサンプルを載せているので、実装してみるといいと思います。

デプロイ

プログラムを動かす環境を理解して、プログラムが書けたとしても、それをコンピュータに載せなくてはユーザーは使えません。
そこで、プログラムをコンピュータ上に配置するデプロイの作業が必要になります。
いまではソースコードから実行ファイルを作成してサーバーに配備する手順は複雑化しているので、自動化が大切です。そして、作ったものをなるべく早く使ってもらってフィードバックを得る必要も出ているということで継続的インテグレーション(CI)という考え方が必要になります。

また、作ったプログラムを公開するときには、プログラムが変な動きをしないかどうか確認する必要があります。このような作業をテストといいます。ユニットテストで自動化することも大事ですが、そもそもテストというのはどういう作業かということも知っておく必要があります。

理論

「プログラミングに数学は必要か?」のような議論が起きたときに、「物理シミュレーションを組むなら微分積分必要だろうけどアプリケーションによるのでは?」のような話をする人がいますが、離散数学はコンピュータの動作の基礎でもあるため、アプリケーションによらず必要です。離散数学は、とりあえずどういう内容を扱っているかを確認しておくといいと思います。

集合や論理に関しては、「論理と計算のしくみ」で扱われているので、そちらを見てください。

論理については野矢先生の本を見ておくのもいいですね。論理はプログラミングにとどまらず全ての事柄について、正しく考えるために必要です。

また、グラフ理論も重要なのでちゃんと勉強しておくほうがいいですが、この本は物語になっていて読みやすいです。

ソート、探索といったアルゴリズム、そしてアルゴリズムの設計法も大切です。

指摘があって確認したのだけど、データ構造やグラフといった話題を扱っているこちらのほうがいいかも。

アルゴリズムに関してはトレーニングも大切なので、LeetCodeのeasy問題をひたすらやっていくとかも大事です。
https://leetcode.com/problemset/algorithms/?difficulty=EASY&page=1

計算可能性の話は、「数学ガール/乱択アルゴリズム」をおすすめします。

物語の冗長性がまだるっこしい人はこちらを。

計算理論の基礎」は絶版か・・・

あと、「プロになるJava」では、プログラムの複雑さを分解して順に練習していくというサンプルをやっています。知る限り他にはないアプローチなので、難しい処理が書けるようにならないという人は、Javaではない言語ででも書いてみるのもいいと思います。

開発手法

さて、プログラムやコンピュータの動きが把握できたとしても、ユーザーがやりたいことを実現できなければ意味がありません。
その入口になるのは、ユーザーの要件をまとめる要件定義です。「はじめよう!要件定義」は読みやすくよくまとまっていておすすめです。

要件が固まったらそれをシステムに実装できるよう詳細化を行う必要があります。そのための手法としてDDDが定番になっていますが、エリック・エヴァンスの本は「そのエピソードに2ページ要る?」みたいなのが多くて読むのがつらいので、最初はこのあたりを読むのがいいと思います。

あと、DDDは具体的な作業どうするん?というのがわかりにくいので、ICONIXというユースケースロバストネス図を基本にした分析手法を知っておくといいかもしれません。

業務システムの場合は、業務知識の概要があるといいです。
Webサービスにしても販売管理、流通管理、生産管理などは裏側で必要になることが多いです。

開発プロセス

開発プロセスとしては、いまやアジャイルが当たり前になっていますね。
カイゼンジャーニー」はひとりから始めてチームにアジャイルプロセスを浸透させていく話で、読みやすく実用的でいいです。

同じ著者たちの「いちばんやさしいアジャイル開発の教本」は、アジャイルについてもっと知りたい場合にいいと思います。

また、いまは共同作業にGitHub(or 代替サービス)が不可欠です。GitHubよくわからんな人は、よこなさん、しょぼちむさんの本を読んでおきましょう。

まとめ

勉強することが、とにかくたくさんありますが、期限が決まっているわけではなく10年15年かけて勉強していけばいいので、じっくりゆっくりやっていけばいいと思います。
最初にあげた絵を地図として、いつか全部わかるようになろうという意思をもって日々いろいろやって少しずつでも近づいていけば、そのうちいろいろわかるようになっていると思います。