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