「コンピューターはなぜ動くのか」振り返り

# 「コンピューターはなぜ動くのか」を読んだので振り返り
プログラムはなぜ動くのかが面白かったので、
こちらも読んでみました。
一部理解しきれていない箇所があるが、
一旦まとめて不明点を明確にしたい。

## コンピューターの３大原則
コンピューターの絶対的な基礎は３つある。
1.ハードウェアの基礎は入力、演算、出力。
2.ソフトウェアは命令とデータの集まり。
3.コンピューターの都合は人間とは異なる。

とくにすべてのデータを２進数で扱う点が、
人間とは異なるといわれる所以。
２進数で扱うのは電極のON、OFFでデータを扱っているから。

## コンピューターを作ってみる
### ハードウェアの基本要素
CPU、メモリー、I/Oから成る。
それぞれの役割は、
CPU：プログラムの解釈と実行
メモリ：プログラムの記憶（データ＋命令）
I/O：データの入出力

## ハンドアセンブル
### マシン語
数値だけで表されたプログラム言語。
CPUが直接解釈し、実行することができる。
なお、CPUの種類によってマシン語も変わる。

### クロック周波数
カチカチと一定の周期でクロックジェネレーターからCPUに送られる電気信号のこと。
周波数によってプログラムの実行速度に影響がある。

### アドレス空間
データや命令が格納されたメモリーの場所のこと。
１つの番地に８ビットまで記録できる。

### アセンブリ言語
マシン語を英語でわかりやすくしたものをニーモニックと呼び、
そのニーモニックを使用したプログラム言語のこと。
英語の命令文と同じ語順で記載する。
「Give 　　　　　　me money　　　　」
「命令（オペコード）　目的語（オペランド）　」

### レジスタ
CPUにある記憶装置のこと。
データの記憶だけでなく、演算も可能。
各レジスタごとに名前がついていて、役割も異なる。（アキュムレーターなど）


## 川の流れのようにプログラムは流れる
プログラムの流れは３つしかない。
順次実行、条件分岐、繰り返しである。

ジャンプ命令を使わずに、上記の３つだけで言語を記載することを
構造化プログラミングという。

条件分岐、繰り返しは内部的には、
PCレジスタにジャンプ先のアドレスが設定されることで実現している。

## アルゴリズム
問題の処理手順のこと。
問題を解く手順が明確で有限回である必要がある。

「最大公約数を求める」はアルゴリズムではない。（明確ではない）
「最大公約数を求められた二つの数字の大小を比較し、
　低い方の数値を大きい方の数値から引いていき、大小を比較する。
　同数となった場合、その数が最大公約数となる。」
は明確で有限回のため、アルゴリズムとなる（ユークリッド互除法）

コンピューターのスピードを利用しつつも、
スピードアップのための工夫は必要。
また、基本的なアルゴリズムは勉強し、
応用できるようにする必要がある。

アルゴリズムの工夫の代表例として「番兵」がある。
これは線形探索などで利用されることが多いもので、
番兵を利用しない探索では、
目的の値の判定のあと、毎回Nが指定の検索範囲を超えていないかをチェックする必要がある。
番兵として検索範囲の最後のあとに目的の値を挿入することで、
毎回Nの判定をしなくても、目的の値が見つかったタイミングで
検索範囲を超えているかどうかをチェックすればよくなる。
（目的の値は番兵によって必ず見つかるので、
　検索範囲を超えている→見つかったのは番兵なので、検索結果なし
　検索範囲を超えていない→見つかったのは番兵ではないので、検索結果あり
　となる）

結局アルゴリズムを考えるのは自分自身のため、
基本的なアルゴリズムに縛られないよう注意する。

## データ構造
アルゴリズムと切っても切り離せない関係にあるのが、
データ構造。
プログラムで変数を宣言すると、
その変数用のメモリー領域が確保され、
上記の変数名として扱うことができる。

配列も同様で、配列分のメモリー領域が確保される。
現在、ひとえに配列と呼ばれているものもいくつかの種類がある。

### スタック
LIFO（Last In First Out）型の配列。
最後に格納されたものが最初に取り出される。

なお、最初に配列の要素数を定義する必要がある。
また、すでにある要素の間に要素を追加すると、
追加した後の要素すべてのアドレスを変更する必要がある。
プッシュ関数とポップ関数で格納と取り出しを行う。

### キュー
FIFO（First In First Out）型の配列。
最初に格納されたものが最初に取り出される。
（順番待ちと同じ）

なお、最初に配列の要素数を定義する必要がある。
また、すでにある要素の間に要素を追加すると、
追加した後の要素すべてのアドレスを変更する必要がある。
エンキューとデキューで格納と取り出しを行う。

### リスト型
値の保持方法がスタックとキューと若干異なり、
次の値のアドレスの箇所も保存している。
そのため、間に要素を追加するとしても、
次の値のアドレスの箇所を修正するだけで済むので、
高速に対応できる。

### 二分木型
リスト型の応用で、要素に子要素２つのアドレスの値を保有している。

## オブジェクト指向
ものをベースに考えられたプログラムのこと。
プログラムの保守を容易にする目的がある。
様々な意見があるようで一部抜粋。

オブジェクト指向プログラミングには、
継承、カプセル化、多態性が必要。

### 継承
オブジェクト指向プログラミングでは、
ものの振る舞い、属性をクラスで定義する。
そのクラスは他のクラスへ継承することができ、
継承されたクラスは親クラスの振る舞い、属性を同様に扱うことができる。
→親クラスを変更すれば、子クラスの振る舞い、属性も同時に修正ができるため、保守性が高い

### カプセル化
不必要なものは見せない様にすることで、
クラスを使う側に使いやすくする。

### 多態性
同じメッセージに対して、オブジェクトが異なる操作(処理)をすること。



その他にも、
・大規模の開発に適した手法
・世の中の事象を部品ごとに考え、構成する手法
など様々な意見がある。

## データベース
データベースはデータの基地。
データ・ファイル、DBMS、アプリケーションを１台のPC上に設置することを
「スタンドアロン型」という。※小規模システム
データ・ファイルとDBMS、アプリケーションの２つを別々のPCに設置することを
「ファイル共有型」という。
データ・ファイル、DBMSをまとめ、それを別PCのアプリケーションから利用することを
「クライアント/サーバー型」という。※大規模システム

カード型のデータベースでは、
同じ情報をなんども登録する必要があり手間がかかるのと、
修正が大変になる。
そこでリレーショナルデータベースでは、
テーブルごとに情報をわけ、
IDによって各テーブルを紐づける形としている。
これによって情報の入力、修正が楽になる。

そのため、リレーショナルデータベースに登録される情報は、
重複する情報があってはならないし、
同じものを入力ミスなので異なるものと認識されないようテーブルを分割する必要がある。

#### インデックス
インデックスとは、フィールドの値とレコードの場所を対応つけたもの。
読み込むフィールドの数が少ないため、
高速にデータを扱うことができる。
ただし、登録を行った場合、インデックスの登録も必要になるため、
かえって時間がかかる。
登録と検索（並べ替え）どちらが多いかでインデックスの有無を判断する必要がある。
むやみやたらとインデックスをつけるべきではない。

#### DB操作とインターフェイス
DBの操作は基本的にCRUDとなる。
Create,Read,Update,Delete
そのため、ユーザーインターフェイスにも最低限上記の
４機能は搭載する必要がある。

## TCP/IP
### LAN
Local Area Networkの略。
企業内や家庭内などの限られたネットワーク。
LANでは、ネットワークカードというものに登録された一意な数値である
MACアドレスで各PCを識別し、情報をやりとりしている。
なお、ネットワークカードで通信の仕様が決まるが、
現在はほぼイーサネット一択。
電気信号の形式が同一になるため、異なるハードウェア間の通信も可能になる。

LAN内では宛先のMACアドレスを指定して、
ブロードキャストで通信を行う。
各コンピューターは自分宛の通信であればその通信を受け取り、
自分宛ではない場合はその通信を棄却する。

### WAN
インターネットのような大規模なネットワークのことをWANという（Wide Area Network）。
LANとWANはルーターによって結ばれる。


### IPアドレス
MACアドレスはメーカ名＋商品番号で規定されるため、
企業ごとなどのグルーピングが不可能になる。
そこでIPアドレスが登場する。
IPアドレスは上位階層から地域、プロバイダーなどのグループごとに割り当てられる
一意な数値である。
このグルーピングによって宛先までの道のりがスムーズになる。

また、グループを示すネットワーク部と、
各PCを示すホスト部があり、
サブネットマスクで表示される。

ちなみにIPアドレスが付加されたコンピューターのことをホストという。

### DHCP
動的にIPアドレスとサブネットマスクを割り当てるもの。
DHCPがあることによって、ネットワーク利用者はまだ使われていないIPアドレスを調べたり、
管理することなくIPアドレスを取得することができる。
※コンピューター起動時にまだ使用されていないIPアドレスが割り当てられる。

### ルーター
ルーターは宛先IPアドレスのネットワーク部を調べ、
そLAN内のIPアドレスではない場合、
WANへデータを転送する。
なお、どのルーターへ送るかはルーティングテーブル内に記載がされている。

### DNSサーバー
IPアドレスは人間にとっては覚えにくいので、
文字列で管理できるようにしている。
その際、文字列をIPアドレスに変換できるようにしたものがDNSサーバーと呼ばれる。
なお、文字列といっても一意である必要があり、
ルーターのドメイン名、コンピューターのホスト名から決められる。※所謂URL

また、文字列→IPアドレスへの変換を名前解決といい、
各ルーター内にあるDNSサーバーがこの名前解決を行っている。
もし、ルーターないのDNSサーバーで名前解決ができなかった場合は、
別のルーターへ問い合わせを行う。

### ARP
IPアドレスをMACアドレスに変換する。
LAN内にブロードキャストでこのIPアドレスの人は
MACアドレスを教えてください的な通信を行う。

### TCP
ハンドシェイクでデータを通信する。
TCPではデータをパケットに分割し、データを送信する。

## 暗号化
### 公開鍵暗号方式
暗号化の鍵と復号化の鍵を異なる値とし、
暗号化の鍵を公開鍵、
復号化の鍵を秘密鍵とする。

データを送る際は公開鍵を使ってデータを暗号化する。
送られた側は秘密鍵を使って復号化を行う。

### 電子署名
送信するメッセージからメッセージダイジェストを作成し秘密鍵で暗号化、
送付された側はメッセージダイジェストを公開鍵で復号化し、
同様にメッセージからメッセージダイジェストを作成。
上記のメッセージダイジェストが合致すればOK。

上記によって、
・送信者がメッセージの内容を承認していること
・送信者が確かに本人であること
の２つを確認することができる。

## XML
拡張可能なマークアップ言語のこと。
マークアップ言語のメタ言語である。
ある程度決められたタグの作成手順に従って自由にタグを生成することができるため、
HTMLなど本来はタグに意味を持たない者に対して、
意味を持たせることができるようになる。

つまり、レイアウトやデザインと分離し、データ構造を定義することができる。


## その他
・コンピューターを作ってみるの箇所、XMLの箇所はまだふわふわしているので、
　再度読んだ方が良さそう。
・徐々にアルゴリズムとかデータ構造とか、RubyやPythonだけやっていても、
　なかなかイメージつかない部分があったが、イメージが掴めてきた。
　C言語にチャレンジすればより理解が深まる気がする。