『コーディングを支える技術』読書メモとか
大学四年生になって自分の勉強をする時間がようやく取れるようになったので、体系的な知識をつけるために技術書を読むことにしている。 ただ漫然と読んでいるとサラーッと読んでしまうので、人に説明できる程度には自分のものにしたかったので、自分用のwikiに読書メモをまとめている。 しかし、圧力がないと飽きてしまうのでとりあえずブログに公開してみることにした。
まとめ方は基本的に一つの節を一つの疑問文に直し、その答えを極力簡潔にその節の中からまとめる形。
以下自前wikiより転載。
コーディングを支える技術
コーディングを支える技術 ~成り立ちから学ぶプログラミング作法 (WEB+DB PRESS plus)
- 作者: 西尾泰和
- 出版社/メーカー: 技術評論社
- 発売日: 2013/04/24
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (34件) を見る
読むことにしたわけ
プログラミングについての知識を深める以前に、全体の俯瞰をしたかった
例外とかよく知らないなと思った
勉強法についても乗ってるっぽくて良さそうだった
読後の感想
☆5
もっと早く読むべきだったとも思うが、今読むことが出来て本当に良かった。 知ってはいるし使ってもいるが何となくも理解しきれていない技術がどのような歴史的経緯で発明されて、今後どこに向かっていきそうなのかがかなりよくまとまっていた。 オブジェクト指向の章は今まで読んだ中で一番納得感のある内容だった。
ただ、この本を読んだからと言って実装ができるようになるとは限らず、また細かいところも省略されているのであとは自分で調べる必要がありそう。
読書メモ
第1章 言語を深く効率的に学ぶには
タイトルの通り
1.1 比較から学ぶ -why?
言語ごとに共通な知識と違いを知ることが出来るから
RubyとCでtrueになるものの違い
1.2 歴史から学ぶ -why?
- なぜその機能が必要なのかを、言語設計者の視点から知ることが出来るから
1.3 まとめ
第2章 プログラミング言語を俯瞰する
どうしてプログラミング言語が生まれたか?
第3章 文法の誕生
なぜ文法が必要か?
3.1 文法って何だろう?
3.2 スタックマシンとFORTH -what
3.4 中置記法 -what
3.5 まとめ
第4章 処理の流れのコントロール
なぜ制御構造が必要か?
4.1 構造化プログラミングの誕生 -what
if
とかwhile
とかが生まれた → なぜ?
4.2 ifが生まれる前 -what
アセンブリレベルではジャンプ(=Cでの
goto
)を使っている。直感に反しており読みづらい。else
も同様。楽で読みやすい方が良い!
4.3 while ──繰り返しのifを読みやすく表現 -what
if
とgoto
だけで実現できるが、読みやすさ書きやすさが良い
4.4 for ──数値を増やしながらのwhileを読みやすく表現 -what
for
を使うとループの初期化と週条件とステップがまとまってるので意図が分かりやすい。foreach
も同様の目的。
4.5 まとめ
- 使わなくても出来るけど、制御できるおかげで分かりやすい
第5章 関数
何故関数が必要か?
5.1 関数の役割 - what?
理解のため - いくつかの行を一塊にして名前をつけることで 組織 のようになる
再利用のため - 部品としてコンパクトに再利用できる。
5.2 戻る命令 - how?
従来の goto 文だと戻ることができなかった。
戻り先を書き換える方式だと上書きされたら戻れなくなる。
戻り先をスタックに保存しておくことでネストした関数呼び出しにも対応できる。
5.3 再帰呼び出し - why?
- 入れ子構造のデータを扱うために必要。
5.4 まとめ
第6章 エラー処理
なぜ例外処理が返り値を使う方法よりもよいのか?
6.1 プログラムも失敗をする - what?
- ファイルの書き込みの失敗などは起きうるが、それを伝える必要がある。
6.2 失敗をどうやって伝える? - how?
返り値で失敗を伝える - 失敗を見落とす、エラー処理がifの中にあるのでコードが読みづらくなるなどの問題がある
失敗したらジャンプする - 失敗したときにジャンプする場所を決めておくことでコードの可読性は向上する。
6.3 失敗しそうなコードを囲む構文 - why?
- 例外の可能性を忘れる/不適切な例外処理を書くというもんだいを解決するためには、失敗しそうな処理を囲ってエラーをあとに書くという
try ~ catch
が必要。
- 例外の可能性を忘れる/不適切な例外処理を書くというもんだいを解決するためには、失敗しそうな処理を囲ってエラーをあとに書くという
6.4 出口を1つにしたい - why?
try, catch だけでなく finally も生まれた。
対になる処理(file の
lock
,unlock
など)を絶対に行う必要があるから。D言語では
scope(exit)
というスコープガードを発明。
6.5 どういうときに例外を投げるか
何が例外的状況なのかは一通りではない
筆者としては、すぐ例外を投げてくれたほうが異常事態に気づきやすいので良い(フェイルファースト)
6.6 例外の伝搬
6.7 まとめ
第7章 名前とスコープ
なぜ名前の有効範囲を制限する必要があったのか?
7.1 名前はなぜ必要だったか
メモリの番地よりも人にとってわかりやすい
名前は衝突しうるので、長い変数名をつけることとスコープを利用することが対策としてうまれた。
7.2 スコープの進化 - what?
動的スコープ - 入り口で元の値をとっておき、出口で戻す。呼び出された関数のスコープが呼び出し元と同じになってしまう。
静的スコープ - 関数ごとの名前と値の対応表を専用に持っているので、影響範囲を関数内だけに限定できる。←これが普通
7.3 静的スコープは完成形?
- ネストした関数でのスコープや、外の関数への束縛など問題は残っており、各言語が頑張って解決している
7.4 まとめ
第8章 型
8.1 型とは何か
- ビット列をどのように解釈するのかを定めた追加の情報
8.2 数値をオンとオフで表現する方法
- 0~9をランプで表現するためには、位取りや7セグメント、そろばん形式など多くの形式がある
8.3 1つの位に必要なランプはいくつか?
- 4つで良いが、2新方で表せばもっと節約できる。
8.4 実数はどうやって表現しよう
8.5 型は何のため?
- コンピュータにとってはビット列が何を表しているかわからない→言語処理系で宣言しておけばどのように処理すればよいかわかる。
8.6 型のいろいろな展開
8.7 まとめ
第9章 コンテナと文字列
「いくつものモノを入れるためのモノ」について、色々な種類がある理由とその長所と短所について。後半は特に文字列について。
9.1 いろいろな種類のコンテナがある - what?
9.2 なぜいろいろな種類のコンテナがあるのか
それぞれのコンテナに長所と短所があるから。
ex. 配列と連結リストでは、操作によって効率の優劣が違う。
9.3 辞書,ハッシュ,連想配列 - what?
「キー: 値」という組み合わせ。
万能のコンテナはない
9.4 文字とは何か
9.5 文字列とは何か
9.6 まとめ
- 文字列の実現へのアプローチにはいくつかの方法があるが、実装で解決するだけでなく標準化での解決も進んでいる。
第10章 並行処理
同時に複数の処理が実行される時何が起こっているのか。どんな問題が起こりうるのか。
10.1 並行処理とは何か
- 複数の処理を時間軸上でオーバラップして実行すること。
10.2 細かく区切って実行する -what
- 実際には、 人間が気付かないくらい短い間隔で複数の処理を切り替えながら実行している。
10.3 処理を切り替える2通りの方法 -what
どういう時に交代するのかには2つの方法がある。
協調的マルチタスク - キリの良いところで交代を宣言する。
プリエンプティブマルチタスク - 一定時間で交代する。 ← 最近のOSはこれが多い。
10.4 競合状態を防ぐには -how
10.5 ロックの問題点と解決策 -what
10.6 まとめ
第11章 オブジェクトとクラス
「オブジェクト指向という言葉がさすものは言語によって異なります。」
11.1 オブジェクト指向とは何か
11.2 変数と関数を束ねて模型を作る方法
- クラス以外の3つをまず以下で説明
11.3 方法1 モジュール,パッケージ
関連性の強い関数や変数のまとまりを表現するもの。
Perlでの例。最初はデータもモジュール(パッケージ)に含めていたが、データを外部のハッシュにし、blessでモジュールと紐付けて実現。
11.4 方法2 関数もハッシュに入れる
JSでは関数もハッシュ(Object)に入れる。
ただObjectに入れるだけだと各Objectに関数があってメモリの無駄なので、prototypeに関数を入れておくことでオブジェクト指向を実現。
11.5 方法3 クロージャ
状態を持った関数を作る。
自由変数を束縛し、関数の中に閉じ込める。
ここの説明はサラッとしてるので、オブジェクト指向なJavaScriptプログラミングのススメ(2) | ゆっくりと… を見ると良い。
11.6 方法4 クラス
言語によってクラスの主要な意味は異なるが、主に3つの意味がある。
まとまったものを作る生成器(上述の例)
どういう操作が可能かという仕様としてのユーザー定義型(C++での主目的)
継承しコードを再利用する単位
11.7 まとめ
第12章 継承によるコードの再利用
いろいろな継承の仕組みの長所と短所
12.1 継承とは
実装を自動で引き継ぐ考え方。主に3つの考え方がある。
一般化/特殊化
共通部分の抽出 - 複数のクラスの共通部分を親クラスとして抽出する
差分実装 - 変更分だけ実装していく → コードの場所がわかりづらくなるという批判あり。
リスコフの置換原則(継承はis-aの関係でなければならない)
12.2 多重継承 -what
- 現実世界では、1つのモノが複数の分類に属することがほとんど。→多重継承
12.3 多重継承の問題点──またしても衝突!
多重継承した結果複数のクラスで同じメソッドを持っていたらどうするか?
多重継承の禁止(Javaなど) - 委譲を用いてオブジェクトを持つにとどめる(依存性の注入)。インターフェースを用いる。
メソッド解決順序を工夫する(Pythonなど) - 深さ優先探索(Python2.3まで)、C3線形化(Python2.3以降)
処理を混ぜ込む:Mix-in(Rubyなど) - 再利用したい機能だけを持った小さなクラスを混ぜ込む。(衝突は解決できない)
トレイト - 再利用の単位としての役割をインスタンス生成機としての役割から分離する。Rubyのmodule同様メソッドをまとめる束だが、mix-inでの衝突時に明示的にエラーにする。トレイトを利用するクラスに必要とするメソッドを明示しておく。
12.4 まとめ