はじめまして、大阪大学基礎工学部情報科学科の三年生のspeed(@strayer_13)です。
私がパソコンを初めて手にしたのは大学一年生でした。大学で情報科学を専攻している私は、情報科学という広大な世界に対してどのように勉強を進めていけばわからず、その道は一直線ではありませんでした。
本書では、stray sheep(迷える子羊)だった大学一年生の私に向けて、どのように情報科学を学ぶのが良いか、ブラウザの仕組みをボトムアップに説明していく過程で各論の良書をリストアップしながら「知の高速道路」を提供します。
目次
本書が対象とするのは、大学一年生の頃の私のような、web ブラウザやスマホなど、IT技術によって生み出された製品を使ってはいるが、
です。
すでに情報科学全般を理解している方は対象としていません。
💡 Attention これは私なりの「知の高速道路」であり、万人に適したものではないかもしれません。
なお、情報科学を学び始めて三年しか経っていない私が選んだ本の選定基準も信頼性に欠けるかもしれません。身もふたもない話ですが、本には人それぞれ相性があります。
ただ、私が知る限り本書で挙げるものは定評のある本ばかりです。
ご指摘やご感想等ありましたらコメントにてぜひお願い致します。
巷には「わかりやすい」本がたくさんあります。それらは図を用いたり複雑で込み入った難しい部分を省いているため、サクサク読めてわかった気になります。
しかし、今後ITシステムを作る側の人間となる情報科学科一年生の私に対して望んでいるのは、現在動いているITシステムがある日突然消滅した時、再構築できるレベルの「分かる」です。
その点、巷にある「わかりやすい」本ではそのレベルに達することができません。
もちろん、そのような本はとっかかりとしてとても重要であり、批判しているわけではありません。
情報科学の世界という広大な世界を説明する本書も、各論はどうしても浅くなってしまいました。そこで、良書をリストアップすることで、詳細を理解していただきたいと考えています。
本書は情報科学という広大な世界を学ぼうとする人に向けて「知の高速道路」を提供するものです。理解を容易にするため、本書では多くの人にとって馴染み深いであろうブラウザが動く仕組みをボトムアップに(通信のような抽象度の低いレイヤから、ブラウザのような抽象度の高いレイヤまで段階的に)情報科学の世界を説明していきます。
ただし、本書のような短い文章で提供できることは、情報科学の大枠を掴むことに限られています。
そのため、本書では、各領域に出会う度、なるべく信頼性の高い本を各章でリストアップしていきます。本書を読み終えた後の学習に繋げていただきたいです。
本を選ぶことの重要さ
本を選ぶというのは非常に重要です。というのも、巷には大量の本が出版されており、それらは玉石混交です。
私自身、大学一年生の頃情報科学を学ぶために情報科学の本をたくさん読んでいましたが、本の入手先であった地元の図書館は大学の図書館と比べて小さく、いわゆる「名著」があまりありませんでした。そのため、本を読んでも得られる情報が少なく、効率の悪いものとなっていました。
例えば以下のような簡単な本が多くおいてあり、それらを手に取っていたのですが、「わかりやすく」するために細かな仕組みは省いているため、余計わかりにくくなっていました。
ここでは情報量が多くかつ信頼性の高い本をリストアップし、より効率的に学んでいただきたいと考えています。
本編に入る前に、頭に入れておくべき情報科学における以下の三つの重要な概念を挙げておきます。
以下詳しく見ていきます。
世にあるITシステムは非常に複雑です。
CPUの写真を見たことはありますでしょうか。CPUは非常に多数のゲートから成り立っています。パソコンやスマホはそのような複雑なハードウェアが組み合わさってできています。ITシステムは大量の電子機器が有線のケーブルや電磁波によってつながって成り立っています。
このように複雑なシステムを構築するのは複雑な問題です。
この複雑な問題に対処するための方法論として古くから用いられてきたのが、「困難は分割せよ」です。複雑な問題を小さく(比較的)簡単な問題に落とし込んで一つ一つ解決し、それらを組み合わせて全体の問題を解決するのです。
このようなことは当たり前のように思われるかもしれませんが、情報科学を学んでいると頻繁に出てきます。
例えばプログラミングにおけるモジュール化、アルゴリズムにおける分割統治法、デジタル回路における部品の組み立て方、などです。
「困難を分割せよ」を意識していると、複雑な問題に出会ったときも、問題に取り組む勇気が湧いてきます。
これは科学全般に通ずることですが、情報技術は技術の積み上げによって成り立っています。
技術はすでにうまくいっている既存技術を積み上げてできています。
「困難は分割せよ」のステップで分割した問題を、一つ一つ解いて、それらをうまく組み合わせて新しい技術を生み出すのです。
技術の積み上げを意識する例として、通信プロトコルのレイヤ構造や、ハードウェアの構成があります。
今までは科学全般に通ずる概念でしたが、仕様と標準化という概念は情報技術特有の概念かもしれません。
情報技術は物理のように自然から導かれるわけではなく(もちろんハードウェアの性能の限界などはそうですが)、人間が仕様を決めて、それを前提としてシステムを構築していきます。
そして、仕様を多数の人々で一本化させる行為である標準化は、世の中のITシステムを効率的に運用、発明していくために非常に重要です。
仕様と標準化が重要となってくる例として、通信プロトコルや、ハードウェアとソフトウェアのインターフェースとしてのOSがあります。
人間の在るところ、標準化あり、デス。
ここであげた3つの概念は、複雑で込み入った問題に対処するためには欠かせないものだと考えています。
もちろん他にも重要な概念はたくさんあります。
📕 UNIXという考え方―その設計思想と哲学, Mike Gancarz
UNIXは、現在普及している多くのOSの源流となったOSです。
本書では、UNIXの核となる考え方を紹介しており、多くの人に長く使われるソフトウェアとはどのようなものか考えるきっかけを与えてくれます。
いよいよ本編です。
本編では、ブラウザが動く仕組みをボトムアップに説明していく中で情報技術の世界を丸ごと説明します。「わかりやすい」本のようにならないよう、仕組みを詳しく解説していくつもりです。
ただ、分量や筆者の力量の都合上、込み入った内容には立ち入らず、立ち入る寸前でおすすめの本を紹介し、次に進むような形式とします。
まず、ブラウザとは何かご存知でしょうか?
ズバリ、それはあなたが今使っているソフトウェアのことです。
より詳しくいうと、webサイトのデータの送受信やレンダリング(ページを表示する)などを行うソフトウェアです。
ブラウザの代表的なものとして、Safari、Google Chrome、Firefox、今は亡きInternet Explorerなどがあります。
では本書ではなぜ情報技術を学ぶためのテーマとしてブラウザを取り上げるのでしょうか?
それは、ブラウザを成り立たせるためには、通信、計算機、OS、プログラムなどなど情報科学の主要技術のほとんどを必要とするからです。
さらには先に挙げた情報技術で重要な概念3つ、特に仕様について理解を深めることができます。
それに皆さんにとっても馴染み深いものですよね。
以下では通信、計算機、OS、プログラム、ブラウザの順にボトムアップに情報科学の技術を見ていきます。
Let’s deep dive!
まずは通信の仕組みについて見ていきましょう。
この世界には電流がケーブルを通ったり、電磁波が飛び交ったりして情報が伝達しています。
そこでは、私たちが会話している時に用いている数字や文字が飛び交っているわけではありません。その代わりに、電圧のオンオフのような物理的な信号によって情報が伝わります。
ではなぜ0と1なのでしょうか。実は、0と1である必要は必ずしもありません。3つ以上の状態を表せるような媒体であれば、0, 1, 2であっても構いません。
しかし、情報の最小単位である0と1という2状態kに制限することで、より安定性が生まれます。
例えば、電圧の値が5Vから0Vを連続的にとるとしましょう。その時、電圧の値を3分割した場合と2分割した場合では、後者の方がより安定です。というのも、実世界においては連続量をとる物理的なものには宇宙線や温度などのノイズが入り込み、安定していません。
そのため、状態を明確に区切るためには、状態と状態の間の距離を大きく取る必要があるのです。
情報が0と1で表されることがわかりました。では、0と1でなぜ情報が伝わるのでしょうか。
それは、情報の「符号化」がなされるからです。
私たちが普段使う数字や文字はそれぞれ「0」,「1」,..や「a」など, それぞれを区別するために別々の記号によって表現されています。
これらは実際のところその記号で表す必然性はありません。
例えば、有名な文字コードのASCIIコードでは、「A」は0x41(2進数では、 01000001)という数字で表されます。ここに「仕様と標準化」という概念が立ち現れてきます。
あらかじめ0と1でどのように記号を表すか仕様として決めておけば、各記号を符号化して0と1で表せてしまうのです。
0と1でさまざまな記号を表せることがわかりました。しかし、それをコンピュータでどのように伝達するかはまだわかりません。
例えば、私は高校生の頃、1と0が電圧のオンオフに対応すると知った時、ではどのタイミングで区切りをつけ、どこを通信の開始とし、どこを終了とするのか決めないと全く通信ができないのではないかと考えていました。
そしてそれは実際にその通りで、それを解決するために「仕様と標準化」が定まっていたのです。
例えば、どこで0001が送られた時、どのタイミングで0, 0, 0, 1と区切るかが送受信同士の間で決まっていたり、他にはマンチェスター符号のようにして工夫する方法などがあります。通信の開始も、DNNの開始コドンの如く、何らかの記号を割り当てれば良いのです。
ここに「仕様」の重要さを垣間みることができます。
情報をどのように効率的に符号化するか、ノイズなどで安定性がない場合、どのように符号化・復号かするのかといったことを研究する領域が情報理論です。
情報理論の面白い応用先としてQRコードがあります。
情報理論については紹介程度にしておき、以下にあげる本に託します。
📕 情報理論, 甘利
情報理論の本質を授業のように優しい言葉で展開する本。
文庫本であるため非常にお安くなっております。
数式を多く使いつつ、丁寧に意味を解説してくれる理論書はこちら。
ここまでで、0と1をうまいこと送受信できることはわかりました。
しかし、通信においては、誰がどこに送信するかといったルーティングを行わなければなりません。
というのも、実世界では、すべてのデバイス同士がケーブルや無線で1対1に繋がっているわけではなく、網のように繋がったネットワーク上で、他のデバイスを辿っていくことでつながることができます。
よって、情報を送信するデバイス、受信するデバイスだけでなく、情報をルーティングするデバイス(ルータなど)、宛先を見つける人(DNSサーバなど)などが必要となってきます。
さらには、情報自体に、伝えたい情報の内容だけでなく、送信者、受信者といった通信のために必要な情報を付加しなくてはいけません。
それらは適当につけるのではなく、「標準化」によって定められた「仕様」(またはプロトコル)に従ってつけなければなりません。
そのような仕様はただ単に仕様を加えていくのでは複雑化してしまいます。
そこで、レイヤに分けて「困難を分割」しています。
プロトコルのレイヤの分け方として代表なモデルがOSI参照モデルです。
ただ、これは現在使われていません。
現在はTCP/ IPモデルが広く使われています。そして、これがブラウザの仕組みに大きく関わってきます。
TCP/ IPモデル、さらには通信全般について詳しく載っています。
本書を読めば通信の基礎を仕組みからしっかりと理解できます。
ここまでで通信の仕組みを理解しました。
では、通信によって得られた情報を、コンピュータはどのように処理していくのでしょうか。
そこで、ここではコンピュータがどのように計算しているのかを説明していきます。
コンピュータはいくつかのコンポーネントが組み合わさってできています。
そのうち代表的なものが以下のものです。
CPUはデータを演算・移動・一時的な保存といった情報処理をするハードウェアです。
そのため、情報処理をするコンピュータの最も重要なハードウェアです。
CPUはコンピュータをコンピュータたらしめているものと言っても良いかもしれません。
プログラムなどのデータを保存するハードウェア。
メモリにも、物理的媒体によって揮発性・不揮発性やアクセス速度、容量が異なります。
そして、現在のコンピュータは種類の異なるメモリを階層に分けるなどの工夫をして速度、容量といった性能を向上しています。
入出力装置としては、ディスプレイやキーボード、通信を送受信するための機器などがあります。
これらのハードウェアによって得られたデータが、CPUを通して演算処理を加えられたりメモリに保存されたりします。
コンピュータは先にあげたコンポーネントを用いていくつかのことができます。
それらを組み合わせてより大きなことをしていきます。まさに「技術の積み上げ」ですね。
まず、コンピュータはデータの移動ができます。
移動とは何とちっぽけな、と思われるかもしれませんが、これは情報処理の本質とも言える重要な操作です。
実際、高級言語プログラム(C言語などを用いたプログラム)がアセンブリ言語(x86などによる、機械がより読み取りやすい形式のプログラム)にコンパイル(変換)されたコードを見てみると、mov命令というデータの移動をする命令が大部分を占めていることがわかります。
加減乗除やシフト、論理演算といった基本操作ができます。
データの比較を行うことによって、処理を分岐できます。
ジャンプによってループや比較操作が可能となります。
繰り返しや分岐といった処理は、人間よりコンピュータの方が得意なものとして挙げられるものですから、3, 4はとても重要です。
他にもさまざまな処理ができますが、基本的には以上のような基本的な処理を用いて計算を進めていきます。
コンピュータにできることは意外と少ないですね。なのに、これらを組み合わせてすごいことができるのです!
それを可能にするのがプログラミングです。プログラミングはとてもcreativeな行為だということがわかりますね。
詳細は以下の本に任せることとします。
📕 コンピュータの構成と設計 MIPS Edition 第6版 上(通称パタヘネ), パターソン&ヘネシー
ソフトウェアとハードウェアのインターフェースについて詳しく書かれています。
具体的には、CPUの設計や命令セット(ISA)などについて書かれています。
現著者はこの分野を牽引する偉大な方々です。
📕 ディジタル回路設計とコンピュータアーキテクチャ 第2版(通称ハリス本), Harris+
扱っている内容はパタヘネ本に似ていますが、より低レイヤのゲートレベルからcpuを構築するまでを解説しています。 本書の特徴として、ハードウェア記述言語(HDL)の実装例が豊富に載っています。
以上で、コンピュータができる基本的なことを見ていきました。
しかしここまでのことは基本操作であり、これらの道具をソフトウェアがふんだんに活用してさらにリッチなことをしていきます。
そこで重要となってくるのがOS(Operating System)です。
OSはwindowsやLinux, Mac OS, iOSというような、パソコンやスマホを支えるソフトウェアです。
どのようなアプリであっても、計算処理をするためにメモリの確保やファイル操作、ハードウェアの管理、通信の管理といった基本的な操作を必要とします。
それらを包括的に行うソフトウェアがOSです。
ハードウェアが正しく動くことを前提とし、それらを用いてOSでハードウェアを管理するのです。まさに「技術の積み上げ」ですね。
ただ、OSはその役割からして非常に幅広い上、低レイヤであり、仕組みを詳細に説明することは限られた紙面の中では困難です。
よって、詳細は以下にあげる本に譲ります。(とても少ない記述で申し訳ないです…)
Go言語というモダンな言語を用いて、OSが行っていることや、OSを用いて行える操作についての説明がなされている。
非常に分厚いが、説明がとても丁寧だからこそ分厚い系の本。
OSを1から作っちゃおうという本。
ファインマンがいうように、これでOSが「わかる」
ここまでで通信、計算機、OSについて理解しました。
ここでは、これらを用いて実際のアプリケーションを作成するために必要となるプログラムがどのようなものか説明します。(すでに出てきたOSもプログラムですが改めて)
chatGPTに作成してもらったfibonacci数を求めるpythonによるプログラムが以下です。
def fibonacci(n):
# 基本条件
if n <= 1:
return n
# 再帰的な手続き
else:
return fibonacci(n - 1) + fibonacci(n - 2)
# フィボナッチ数列の 10 番目の数を求める
print(fibonacci(10))
このように、プログラムは「変数」や「関数」を用いて、計算を行っていくものです。
実際にはこのようなプログラムがインタープリターで解釈・実行されます。
または、コンパイラというソフトウェアによってアセンブリ言語や機械語に変換されて実行されます。
プログラムにおいて重要なのは、アルゴリズムとデータ構造です。
wikipediaによれば 、アルゴリズムとは
解が定まっている「計算可能」問題に対して、その解を正しく求める手続きをさす
とのことです。よって、プログラムは、アルゴリズムという抽象的なものをコードに落とし込んだものと言えます。
さらに、問題を解決するためには、データ構造という概念も欠かせません。
wikipediaによれば、データ構造とは
格納された各データの参照や修正といった管理を容易にするための構成である
とのことです。対象のデータの性質にあったデータ構造を用いることで、問題を対処しやすくできるのです。
詳細は以下の本に譲ります。
📕 問題解決力を鍛える!アルゴリズムとデータ構造 (KS情報科学専門書), 大槻
また、データ構造とアルゴリズムを学ぶ上で、プログラムを実際に書くことも重要です。
そのために競技プログラミングコンテストなどを用いると楽しみながら学べて良いでしょう。
日本で代表的な競プロコンテストサイトとしてはAtCoderが有名です。
アルゴ式というサイトもさまざまな分野の学習教材が揃っておりおすすめです。
個人的に、プログラム開発は問題の分割と抽象化の世界だと思っています。
大規模なプログラム開発となると、行数が何千万となるほどになります。このように大規模なプログラムを開発するためには、「困難は分割せよ」という考えと、抽象化して再利用しやすくする、という考えが重要となってきます。
その点、プログラミングは情報科学のエッセンスが詰まったものだと思います。
ここまで話した中で、プログラムとOS、計算機との接続がどのようになっているか疑問に思った読者も多いことでしょう。
私もプログラムを始めて学んだ時、インタープリターとコンパイラの違いや、0と1を解釈する計算機に対して、プログラムがなぜ実行できるのかがわからず混乱していました。
そこで、プログラムがなぜ動くのかを知る上で重要なテーマがコンパイラです。
以前のところで計算機ができる操作について解説しました。それは実際にはx86などの命令セット(ISA)によって仕様が決まっており、c言語などの高級言語がx86などのアセンブラ言語に変換することで計算機が実行できるようになるのです。
コンパイラは情報科学のエッセンスが詰まっています。特に、理論が実装に大きく貢献している点がとても面白いです。
そこで以下をおすすめします。
📕 低レイヤを知りたい人のためのCコンパイラ作成入門, Rui Ueyama
個人的に大学で読んだ本の中で最も影響を受けた本(Webサイト)です。
情報技術を学ぶ上で最も身につくのはやはり実際にプログラムを書いて自作することだと思います。
本書では、実際にCコンパイラをC言語で作成します。本書では、 常にコンパイラが動く状態になるようにインクリメンタルに(少しずつ)作成していくため楽しみが継続されやすいです。さらに、本書では大規模ソフトウェアを開発するための技法やツールについても書かれており、今後の開発に大変参考になります。
比較的薄い本でありながら、コンパイラの基礎を網羅的に学べます。
📕 コンパイラ―原理・技法・ツール (Information & Computing), エイホ+
コンパイラのより詳しい本はこちら。分厚いですが、多くのトピックを取り扱っています。はじめは辞書のように使うのがいいかもしれません。
ついにブラウザがなぜ動くのか説明する時に来ました。
私たちは通信、計算機、OS、プログラムについて学んできました。
あとはそれらを組み合わせてブラウザを作るのみです!
まず、ブラウザを成り立たせるために必要なものは何でしょうか。それは、例えばwebページを表示するためのデザインや文章、画像などといったリソースです。
このリソースを得るには、webサーバに「リソースをください」と言うリクエストが必要になります。このリクエストを送信するために、リクエスト文の仕様を決めたり、OSや計算機や通信を活用する必要があります。まさに「技術の積み上げ」ですね。
そしてリクエストを受け取ったサーバは要求されたリソースを送り返します。
それを受け取ったブラウザは、リソースをもとにディスプレイにページを表示します。ここでは表示のためのプログラムが必要となります。
また、ブラウザはjavascriptの実行エンジンを備え、ページごとに様々なデータの送受信や処理を行います。
より詳細な仕組みは以下の書籍やサイトに譲りますが、ブラウザは多くの技術を活用して実現していることが理解いただけたと思います。
静的コンテンツを記述するHTML/ CSSや、それをレンダリングするエンジンの仕組みなどまで詳しく載っています。
Rustによるブラウザ実装のrepository
ブラウザのレンダリングをRustを用いて実装するブログ
情報化社会を牽引してきたブラウザは学習・開発する上でやはり強力な武器となります。
しかし、その莫大な情報は玉石混交であり、取捨選択するのが非常に難しいという欠点があります。
そこで重要なのが検索能力です。自分の知りたい情報を検索するのはかなりスキルの必要な技術です。その検索能力を向上するためのファクターとして重要なのが検索対象の基礎力です。
私も大学一年生の頃は基礎力がなく検索するのに非常に苦労しました。まず検索すれば欲しい情報が得られることを理解しておらず、ブラウザを有効に利用することができていませんでした。
しかし実際は検索力次第で多大な情報を得ることができます。
まずは良書を用いて基礎力を高めていくのがいいでしょう。
現在に至るまでに感じていることは公式ドキュメントの重要性です。IT系だと特にドキュメントが英語だったりして日本語のブログなどを参照しがちですが、ブログにあることはだいたい公式ドキュメントに書いてあります。そして、急がば回れ的なことがよくあるのです。
意識的に公式ドキュメントを見ましょう。
プログラミングのエラーにであったらブラウザで検索することが多いでしょう。
そして公式ドキュメントやQiitaやstack overflowなどのサイトを見ることが多いでしょう。
しかし、知らない人(一年の頃の私)があまり探索しなかったが良さげなリソースとしてGithubのissueがあります。
Githubのissueは以前に同じ問題に出会った人が投稿し、その問題にかなり詳しいであろうメンテナや同じ問題に出くわした人がこぞって回答してくれます。
そのため比較的信頼性が高いです。
すでに何度も言及してますが、良書は良書なだけあって良いです。
基礎力がないと、ブラウザを用いて勉強しようと思っても検索力がなく効率的に勉強できないことが多々あります。
大学の図書館をフルに活用して良書を活用するのがいいと思います。
世の中には、情報技術の専門の学生や社会人、研究者が多く集まるイベントいくつもあります。
それらに参加することで、モチベーションや技術力の向上、交流に伴う興味の広がりといった機会を得ることができます。
以下に有名なイベントを上げます。
こちらは私も実際に参加して、参加者や講師の方々から多くの刺激を受けました。ぜひ応募してみてください。
他にも
などがあるようです。ぜひ調べてみてください。
どんなことにも言えますが、質問は大切です。質問によって得られる知見自体も大事ですが、質問を考えようとする過程で、思考を巡らせたり、理解しているところとしていないところを知ることができます。
私が大学一年生の頃後悔していることは、読書を通して理解を深めるばかりでコードをあまり書いていなかったことです。
コードを書くことは初めは難しいかもしれませんが、わかってくると自由度が高くとても面白いものです。
コードを書くことで理解もより一層深まります。実装において試行錯誤を繰り返すと、コーナーケースなど細かいことまで注意が行き届きます。
ファインマンの言う通りですね。
コードを書く、にも通ずるところですが、アウトプットは大事だと思いました。
一年の頃はほとんどがインプットで本当に理解しているのかわからず不安になっていることが多々ありました。
プログラミングをすることで実際にプログラムが正しく動いていることを確認できたり、
自身の理解をまとめた記事を読み返すことで、各時点での自分の理解の程度を知ることができます。
以上で「知の高速道路」の敷設を終わります。
今から「知の高速道路」を走っていくのはあなた自身です。新しい技術が次々と生まれる情報科学の世界において、基盤となる技術を身につけておくととても力になります。
それでは、Let’s deep dive!