Goならわかるシステムプログラミング 第2版を読んだので,その書評を書きます.
インターンシップで出会った友人の数人を誘って,輪読会を主催し,皆で発表担当を回しながら読みました.
読むのにかかった時間は合計60時間程度でした.輪読資料の作成なども全て含んだ時間なので,かなり多くなっています.
自分の作った輪読資料はこちらに公開しています.
本書の概要
公式サイトの紹介文を引用します。
OSやメモリのこと、もう少しだけ詳しく知っておきたい!
でも何から手を付けたらいいかわからない。教科書を読んでみても、ふだん書いているコードと違いすぎていまいちピンとこない……。
そんな方々のために、アプリケーションのコードから降りていくことで俯瞰的かつ具体的に低レイヤを自分の糧にできる、たくさんのエンジニアに読まれた名著の改訂版です。
第2版では、シェルやプロセスが実行されるまでといった「経験的になんとなく知っているけど……」というトピックの解説が章単位で追加されるなど、初版よりさらにボリュームが増しています。
Goで書かれた「ふつうのアプリケーションのコード」から始めることで、「身近なコードの世界」と「メモリやCPUの世界」との間の巧妙で豊かなつながりが見えてきます!
本書は、2016年9月から2017年8月にかけてアスキーjpの「プログラミング+」コーナーで連載された大好評のWebコンテンツを、さらにわかりやすく紙版の書籍として編纂した初版を改訂したものです。
まさしく,紹介文の通りで,「ソフトウェアエンジニア」が低レイヤのことをちょっと学びたい,というニーズに応える内容になっています.
また,次の冒頭の「はじめに」の一文目が刺さる方も多いのではないでしょうか.
プログラミングの勉強にあたってよく言われるのは、「流行に左右されるような技術の尻を追いかけるよりも、土台となる技術を身につけることが大切」ということです。たとえば、ウェブブラウザで動く JavaScript を書くときは、流行しているライブラリの書き方を暗記するよりも、ブラウザがどのように CSS や HTML を解釈してスクリーンに文字や絵を描き出していく(レンダリングしていく)のかを理解することが大切です。さもないと、ライブラリの流行が変わるだけで勉強したスキルが失われてしまいかねません。データベースでも同じことがいえます。SQL の文法を学ぶことよりも、データベースがどのようにスケジューリングを行い、どのようにデータを探索していくのかを学ぶほうが、パフォーマンス・チューニングのコツなどもひらめきやすくなるでしょう。
自分もこの一文に惹かれて,読むことを決めました.
また,この本は「Goを通じてシステムプログラミングを学ぶ」というコンセプトで書かれているので,Go言語の言語仕様や標準ライブラリについても学ぶことができます.
前提
筆者について
- 情報系(数理)の大学院生だが,コンピュータサイエンスについてはあまり詳しくない
- プログラミングの経験,数理とその関連分野(グラフ理論,最適化,アルゴリズムなど)の知識はある
- 一方,ネットワーク,データベース,OS, etc.については勉強中.
- Nand to Tetrisを通じて,コンピュータの基礎を学んだ(私の書評はこちら)
- PythonやJuliaなど、いくつかのプログラミング言語を学んだことがある
- Go言語の経験は,A Tour of Goをやった後,「初めてのGo言語」を読んだ程度
- 本書を読むために,0からGoを学んだ
本書を選んだ理由
- インターン先の社員さんにおすすめされて興味を持った
- Kubernetesやコンテナ技術周りに興味があり,実際触ってみたりもしたが,その前にまずOSやネットワークなどの基礎が必要だと感じた
- Goについては全くの初心者だったが,DockerやKubernetesの開発ではGoが使われており,前々からGoに興味があったので,この本をGoを学ぶきっかけにしようと思った
感想
良かった点
OSやネットワークの広範な知識を,体系的に学ぶことができました.特に,文章を読んでいるだけではピンとこない部分も,実際に手を動かしてみることで,理解が深まったように思います.
個人的に特に面白かったのは,インターフェースのところ(第2章 低レベルアクセスへの入口1:io.Writer,第3章 低レベルアクセスへの入口2:io.Reader)と,ネットワークのところ(第6章 TCPソケットとHTTPの実装,第7章 UDPソケットを使ったマルチキャスト通信)と,並行・並列処理のところ(第14章 Go言語と並列処理,第15章 並行・並列処理の手法と設計のパターン)です.
2,3章では,io.Writer
やio.Reader
を扱っているのですが,単にI/O周りのハウツーを学ぶ章ではありません.むしろ,これらのインターフェースの具体例を通じて,Goのインターフェースという抽象化の仕組みの素晴らしさを学ぶという内容になっていて,Goという言語が持つ「シンプルさ」と「強力さ」を実感できました.
6, 7章ではUDPとTCPの通信の特性の違い(TCPはコネクション型,UDPはコネクションレス型)がGoで実装してみた時の実装の違いに現れていて,理解が深まりました.
また,以下のようなことにも触れられていて,面白かったです.
- UDPはシンプルな反面,必要な機能を自分で実装しなければならないため,扱いが難しい.しかし,QUICなどの新しいプロトコルはUDPをベースにして,うまくその辺りを解決した.
- TCPのKeepAliveをGoで実装してみる
- TCPの輻輳制御とフェアネスについて
13,14章では,並行・並列処理の基本から,GoのGoroutineの実装,並行処理のデザインパターンまで幅広く学ぶことができました.
「Goは並行処理が得意」というのはよく聞く話ですが,その理由がわかりました.
具体的には以下のようなことが面白かったです.
- まずそもそも,並行処理と並列処理の違いについて
- まずそもそも,OSのプロセスとスレッドの違いについて
- GoのGoroutineとOSのスレッドの違いについて
- GoのGoroutineの実装について
- MPGモデル
- GoのランタイムはミニOS!
- 並行処理のデザインパターン:
- スレッドプール
- Producer-Consumer
- Future-Promise
比較的,各章が独立しているので,興味のある章から読んでも良いと思います.特に,普段Goを書いているエンジニアの方なら,並列・並行処理のところだけでも読んでみる価値はあると思います.
イマイチだった点
イマイチだった点というか,個人的な問題ではありますが,正直ところどころ難しいと感じました.
例えば,
- 第5章「システムコール」は手を動かすというよりは,知識を学ぶ章であり,ピンとこない部分が多かったです.
- 第8章「高速なUnixドメインソケット」では,やや天下り的で,中身の仕組みなどには触れられておらず,しっくりこなかったです.
[試して理解]Linuxのしくみ | 技術評論社では「次に読むべき本」として挙げられていましたが,確かにそうかもしれません.
次に読みたい本
引き続きシステムプログラミングや低レイヤー周りを学びたいと思っています.特に
- [試して理解]Linuxのしくみ | 技術評論社
- Linuxのカーネルやシステムコールについて学べる本
- GoやPythonで手を動かしながら学べる
- ゼロからのOS自作入門 | マイナビブックス
- みかん本として有名な本で,とても興味がありますが,あまりにボリューミーなので,手を出すのは少し躊躇しています.
- [作って学ぶ]OSのしくみⅠ | 技術評論社
- つい最近出版された本で,やはりOS自作できます.が,Rustで書かれているので,まずはRustを学ぶ必要があります.
こんな人におすすめ
- 普段アプリケーションを作っているソフトウェアエンジニアだが,低レイヤについても学びたいと考えている人
- CS系出身の方
- Goが書ける方
逆に,ある程度のOSやネットワークの知識がないと,内容が難しく感じるかもしれないので,特に非CS系の方は注意が必要です.また,Go言語の経験がない方は,Goの基礎を学んでから読むことをおすすめします.