『仕組みと使い方がわかる Docker&Kubernetes のきほんのきほん』でようやく Docker の基本を理解する

仕組みと使い方がわかる Docker&Kubernetes のきほんのきほん は Docker の入門書です. イラストやハンズオンが豊富で, サーバや Linux の知識が豊富ではない人にも Docker の基本が分かるように書かれた本です. ネット上のコマンドを見様見真似でなんとなく Docker を使うことは難しくありませんが, 結局そのコマンドはどういう意味なのか, どういう仕組みで Docker が成り立っているのかを知らないと応用できません. これまで docker run や docker-compose up などのコマンドを使ってきたのに, その実何が起きているのか理解していなかったのですが, 本書の説明でようやく基本が理解できました. Docker コマンドのフォーマット Docker コマンドを使う上で最も重要だと感じたのがコマンドのフォーマットです. 1 docker <上位コマンド> <下位コマンド> [オプション] <上位コマンド> は基本的に操作対象を, <下位コマンド> は操作を表しています. 例えば docker container start だと, コンテナを開始するという意味です. これがなぜ重要なのかと言うと, 操作対象を明確に意識できるからです. 自分が操作しようとしているのはコンテナなのかイメージなのかはっきりと分かります. これまで, Docker には, 隔離されたプログラムの実行環境であるコンテナと, コンテナの設計図であるイメージがあるというような説明を目にしたことがあったにも拘らず, それを各コマンドと結び付けられていなかったのですが, このフォーマットを知ることで疑問が氷解しました. コンテナ, イメージ, ネットワーク, ボリュームなど, 扱いたい対象が上位コマンドに来るというただそれだけなのです. 混乱の原因となっていたのは, 上位コマンドは省略可能な場合があることです. 例えば docker ps はコンテナの状態を表示するコマンドですが container の文字がありません. 実はこれは docker container ps と同じ意味なのですが, 歴史的な経緯により ps でも container ps と同じことができます....

May 6, 2023 · 4 min

『達人に学ぶ DB 設計 徹底指南書』でデータベース設計の論理と物理を考える

『達人に学ぶ DB 設計 徹底指南書』 はリレーショナルデータベース (RDB) の設計についての解説書です. 『達人に学ぶ SQL 徹底指南書』 の続編という位置づけのようなので, 本書に登場する SQL が難しいと思ったり, より SQL のことを学びたいと思ったら前作を読むと良いでしょう. 本書ではデータベースの設計を, エンティティの定義や正規化などを行う論理設計と, データ格納の方法や場所を考える物理設計の二段階に分けて説明します. 設計についての基本的な考え方や知識を抑えつつ, やってしまいがちなバッドノウハウや, 論理設計と物理設計のトレードオフと言った実践的な内容にも踏み込みます. 正規化 データベース設計は大きく論理設計と物理設計という二段階に分かれる. 最初に行う論理設計では, 特定の DBMS(Database Management System) や SQL のことは考えずに, プログラムが扱う対象となる物事の属性や物事同士の関係をモデル化する. 論理設計をするに当たって役に立つのが, データの冗長性や非一貫性を排除するための正規化という方法だ. 正規化を理解するには正規化されていないデータを題材にすると分かりやすい. 例えば以下のテーブルは, 都道府県, 市町村, 市町村の規模を表している. このように分割しておけば先に挙げた問題は起きない. 1 2 3 4 5 6 7 8 9 10 +-----------+-----------+-----------+-----------+-----------+--------+ | pref_code | pref | city_code | city | area_code | area | +-----------+-----------+-----------+-----------+-----------+--------+ | 01 | Aomori | 01 | Hirosaki | 01 | Large | | 01 | Aomori | 02 | Hatinohe | 01 | Large | | 01 | Aomori | 03 | Misawa | 03 | Small | | 02 | Yamaguchi | 04 | Ube | 01 | Large | | 02 | Yamaguchi | 05 | Kudamatsu | 02 | Middle | | 02 | Yamaguchi | 06 | Mine | 03 | Small | +-----------+-----------+-----------+-----------+-----------+--------+ このテーブルには 01 Aomori のように何度も登場するデータがあって冗長だ....

May 5, 2023 · 5 min

キャリア 3 年目の振り返り

成果と価値 この一年で, 成果を出すことと仕事の価値を理解することの重要性を学んだ. まず, 営利を目的とする会社組織の一員である以上は成果を出すことが最も重要な役目であることは間違いない. 利益を上げることが目的なのだとすると, 成果は売上の増大かコストの削減に大別される. そのどちらか, あるいは両方に強いインパクトを与える仕事をすることが成果を出すことだ. 成果が重要であると認識しつつ, 大した成果に結びつかない仕事ばかりしてしまうことがある. むしろ, 注意しなければ日々の雑事に埋没するのは簡単なことだ. そうならないようにするためには, 仕事に優先順位を付けて重要なこと, とりわけ重要だが緊急ではないことに取り組む時間を意識的に確保する必要がある. ある仕事が重要かどうか判断するためには, その仕事の価値を理解しなければならない. 仕事の価値は, プロダクトへの理解, ひいては会社が営むビジネスへの理解と考察によって判断できる. 実は, 必ずしも仕事の価値を理解しなくとも成果を出すことはできる. 他人から与えられた仕事をこなすだけなら, 与えられた仕事の重要性を認識している必要はない. しかしそこから先, つまり仕事が所与のものである状態から, 仕事を自発的に見つけ, 他人へ割り振ることができる段階に行くために仕事の価値の理解が必要なのだ. 何をするか自分で決めるのであれば, 自分で仕事の価値を判断しなければならない. そして, 一人で働いているのでなければ周囲にその価値を説明することも必要だ. 価値を説明することで人々も成果を認識できる. プロダクトを理解する, 仕事の価値を判断する, 仕事を提案する. 仕事を完了させ, その価値を説明する. そうやって成果を出す. プロダクトへの理解があって初めて価値判断が可能になり, 価値判断できることでインパクトの大きな成果を狙えるようになる. ミニマリズム, 英語, OSS 最近ミニマリズムにハマっている. と言っても家中の物を処分してがらんとした部屋で暮らしているわけではない. 無駄を排除して重要なものに集中するという考えが気に入っている. それは私生活にも仕事にも活かされていて, 殆どのことは無駄なんじゃないかとか, 今一番大事なことは何だろうかと言うようなことをよく考えるようになった. AI の隆盛と逆を行っているのかもしれないが, やはり英語は重要だと思う. 勉強のために TOEFL を受けたりもした. OSS にコントリビュートしたときもやり取りは英語だったし, そういえば原著で技術書を読んだこともあった. 次の一年 この一年でコンピュータ・アーキテクチャ, 並列処理, SQL を主に学んだ. 引き続き基礎を固める勉強を続けるのだが, それだけでなく何かの分野を深めていく勉強もしたい. 例えばデータベースなら SQL の書き方やテーブル設計はある程度分かってきたので, さらにデータベース内部の仕組みについて勉強すると言ったようなことをイメージしている....

April 10, 2023 · 1 min

Apache Bench でベンチマークできるミニマルな C 言語製 HTTP サーバ

ab コマンド, つまり Apache HTTP server benchmarking tool をつかってベンチマークできる状態の HTTP サーバを C 言語で作る. なるべくシンプルに必要最小限の要素のみを持ったコードを目指す. 手堅いエンジニアは高速化のために, いきなりコードを書いたりしない. 計測できる環境を整えておかないと, 高速化をしてもその効果を測ることができない. このサーバを出発点として手を加えて (例えばマルチスレッド化したり IO 多重化をしたりして) サーバのパフォーマンスがどのように変化するかを確かめるために使うことを想定している. ソースコード全体は https://github.com/momori256/cs2 にある. ソケット ab を使うには HTTP を解すサーバでなければならないため, まずは TCP での通信を実装する. ソケットプログラミングはお決まりのコードなので説明は省く. いつもお決まりを忘れてしまうので, man getaddrinfo の EXAMPLE をいつも参照している. socket, bind, listen をして accept できるソケットを作成する部分は以下の関数だ. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 int sock_create(const char* const port, int backlog) { typedef struct addrinfo addrinfo; addrinfo hints = {0}; { hints....

February 24, 2023 · 4 min

『Linux と pthreads による マルチスレッドプログラミング入門』で pthreads を実践する

Linux と pthreads による マルチスレッドプログラミング入門 は pthreads の入門書です. 基礎から説明してあるので Linux でのマルチスレッドプログラミングを学びたい方におすすめです. pthreads は知っていましたし, ミューテックスなどのマルチスレッドプログラミングの概念もある程度知っていたのですが, 改めて pthreads で実践してみようと思いました. 必要なもの一通り スレッドの生成と破棄, ミューテックス, 条件変数など, 必要なものは一通り説明されている. 多数ある pthreads の関数から特に重要なものがピックアップされており, 説明も深入りしすぎず手短なので気負わずにさくっと読める. もっと詳しく知りたい場合は man を参照すればよい. というか実際には主だった関数に限っても引数や返り値の意味を覚えられるわけではないので, 結局 man はいつも参照するから, 詳細が省かれていても手間は対して変わらない. 確かこういう関数があったかなぁとぼんやり覚えているくらいで十分だろう. 説明をコンパクトにまとめることも大事である. スレッドプールを実装 本書の後半ではスレッドセーフなキューを実装する. そしてそのキューを使ってスレッドプールを備えた並行サーバを実装する. ミューテックスと条件変数があれば実装はそれほど難しくないだろうと思っていたが, 実際に手を動かして試してみるのは大事だと思う. 事実, ロック絡みで少しハマったりした. Linux の技術書ではソケット関連のサンプルが頻繁に登場するので随分見慣れた. ソケットのプログラムを書くたびに面倒さを感じつつお馴染みのコードを書いている. 動きのあるサンプル CLI のプログラムだとどうしても絵的には退屈になりがちだが, 本書はエンタメ性を意識しているのか面白いサンプルが使われている. 端末上をハエが飛び回るのだ. ハエの数だけスレッドがあり, 並行にハエの位置が計算されている. CLI でのグラフィカルなプログラムを作るために ncurses を使ったことがあったのだが, エスケープシーケンス (printf("\033[2J") で画面クリアなど) でもこれくらいのものが簡単にできると知って感心した. 少し見た目にこだわりたいときはちょうどよいかもしれない. 結語 マルチスレッドプログラミングは難しいと常々思っていますが, 基本的なライブラリを使うのはそれほど難しくありません. できる限りロジックをシンプルにするのが重要だと感じました. コンパクトな本書に倣って記事もコンパクトにしてみました. 本の紹介や学んだことのまとめをするのに毎回長い文章を書く必要はありませんし, 必要最小限はプログラマの美学ですし (ですよね?), たまにはこれくらい短い記事でも良いと思いました....

November 22, 2022 · 1 min

C のエレガンスが詰まった『The C Programming Language』

『The C Programming Language』 は C 言語の教科書です. 最新の第二版が出版されたのが 1988 年ですから流石に時代を感じますが, C の原点を知る歴史読み物的な価値があります. 個人的に, 配列やポインタ絡みの異常に複雑な型や typedef などの文法に疑問や不満を持っていたのですが, 本書を読み一部が解消されました. コンパクトな言語 C 言語はコンパクトな言語である. 本書はサンプルプログラムを交えつつ C の文法を解説しているが, 付録を除けば約 160 ページしかない. それでいてプログラムを書くのに必要な機能は一通り揃っているから, 小さいことは良いことであるという UNIX 哲学を体現したような言語だと思う. 本書でよく引き合いに出される Pascal や FORTRAN といった言語が当時は流行っていたのだろうが, 著者の一人である Kernighan は Why Pascal is Not My Favorite Programming Language という論文を書いていたようだし, それらの改良版言語という意味もあるのかもしれない. 今となっては一般的となった概念も, C によってもたらされたものは多いのだろう. 複雑な型の読み方 配列やポインタ絡みでやたらと型の記述が複雑になるが, その読み方を整理しよう. 型を文に翻訳する方法 まずは簡単な型を見てみる. 1 int *x x は int 型の値を指すポインタである. 1 int *x[13] x は int 型の値を指すポインタの配列 (サイズ 13) である....

November 6, 2022 · 4 min

『コンピュータの構成と設計 下』でプロセッサのこれからを考える

『コンピュータの構成と設計 MIPS Edition 第 6 版 下』 はコンピュータサイエンスの教科書です. ハードウェアを知り, ソフトウェアを適合させる方法が説明されます. 上下巻に分かれていますが, 内容は完全に上巻の続きです. 各巻で相互に参照されている箇所もあるので, 両方を手元に置いて置くと理解しやすいでしょう. 下巻のメインはメモリ (キャッシュや仮想メモリなど) と並行処理で, アセンブラや論理回路についての付録も含まれています. キャッシュをどのように保存するか考える. キャッシュはメインメモリ中の値を保持するものだから, メモリアドレスに基づいてキャッシュを入れる場所を決定するのは自然だろう. アドレスによってキャッシュの場所を一箇所に定める方法をダイレクトマップ方式という. アドレスが 4bit, キャッシュのブロック数が 4 個なのであれば, アドレス上位の 2bit をインデックスとして用いる. つまりアドレス 0000, 0001, 0010, 0011 は同じインデックスが割り当てられる. 残りの下位 2bit をタグとしてデータと合わせて保持して, 現在キャッシュにあるのがどのアドレスのデータなのか特定できるようにする. もし 0000, 0010 を交互にアクセスするとどうなるだろうか. 両者とも同じインデックスに保存されているためキャッシュ位置が競合し, キャッシュミスが繰り返される. 競合を減らす柔軟な方法はないだろうか. 一つのインデックスに二つのブロックを保存できるようにすればどうだろう. そうすれば二つのブロックを持つセット二つから成るキャッシュができる. 元々 4 * 1 だった構造が 2 * 2 になったということだ. キャッシュを格納するとき, 各セットにある二つのブロックどちらを使っても良い.もちろん空きがなければ追い出すしかなく, LRU(Least Recently Used) 法などに従って捨てるキャッシュを選び, 新たにキャッシュを入れる. 一般化して, 一つのインデックスに複数のブロックを保存する方法をセット・アソシエイティブ方式という. 究極はセットが一つしかないフル・アソシエイティブ方式だ. 一セット当たりのブロック数のこと指す連想度という用語を使えば, ダイレクトマップ方式からフル・アソシエイティブ方式に向けて連想度が上がると表現できる....

October 20, 2022 · 3 min

『コンピュータの構成と設計 上』でソフトとハードを股に掛ける

『コンピュータの構成と設計 MIPS Edition 第 6 版 上』 はコンピュータ・アーキテクチャの教科書です. 2 名の著者パターソン&ヘネシーの名前を取ってパタへネという愛称で知られています. ヘネパタという紛らわしい愛称が付けられている『コンピュータ・アーキテクチャ』はより上級者向けの内容です. 本書はソフトウェアとハードウェアの境界付近についての本です. コンピュータの中核的な仕組みを説明し, プログラムを書く上でどうやってハードウェアを活用すればよいかという視点で語られます. コンピュータの中身を知りたい方におすすめです. Moore の法則の終わり プロセッサは数百ものトランジスタが搭載された集積回路によって実現されている. トランジスタを始めとする半導体素子の材料になるのはシリコンという砂に含まれている物質だ. 円柱状のシリコン結晶を 0.1mm ほどに薄くスライスしたウェハ (wafer) を格子状にカットすると, 小さなチップができる. チップ一つ当たりのトランジスタ数が 2 年で倍増するという, Intel の創始者の一人である Gordon Moore の予想「Moore の法則」は 50 年間に渡って正しかった. しかしいつまでも指数的な成長が続くわけではない. 消費電力の増加とともに発熱が増え, ついには冷却性能の限界を迎えたのだ. ここに来てプロセッサ開発者は方針転換を余儀なくされた. 一つのプロセッサの性能が頭打ちとなったので, 一つの CPU に複数のプロセッサを搭載することにしたのである. マルチコア CPU の性能を引き出すにはプログラムの努力が欠かせない. 現代は, ソフトウェアエンジニアもハードのことを考えなければならない時代なのである. MIPS について 本書で取り扱われる MIPS という命令セットは, 命令数を抑えシンプルさを重視して設計された. フォーマットが単純であれば規則性が保たれ, 回路の実装が容易となる. そして単純な回路は消費電力を抑えらる. スマートフォンの時代 (ポスト PC 時代) において, 消費電力は命令セットの良し悪しを決める鍵となった. MIPS と同様の思想を持って設計された ARMv8 や RISC-V が脚光を浴びるのは自然な流れであった....

October 5, 2022 · 2 min

『入門 UNIX シェルプログラミング』で UNIX の世界を学ぶ

『入門 UNIX シェルプログラミング シェルの基礎から学ぶ UNIX の世界』 は UNIX シェルプログラミングの入門書です. 良いと思ったのは網羅的で実用的なところです. おそらく一通りの基礎的なトピックスに触れていて, 本書を読んでおけば大抵のことには対応できる土台が身に付くと感じました. 基礎だけにとどまらず, 豊富な実例を伴った解説がなされるので, 辞書やクックブックとしても使えそうです. 基本的だけど知らなかったこと 検索しづらいようなトピックスがきちんと紹介されているのが嬉しいポイントです. これまで何となく知っているけどよく分からずにいたことが分かって, 知りたいことが知れたという気分がしました. #/bin/sh とは何か シェルスクリプトの最初の行に書くシェバンというものですが, これはスクリプトを実行するのインタープリタを指定する記述です. シェバンがなければ余計な手順が掛かり, 意図したのとは異なるシェルでスクリプトが実行される可能性があります. シェルはまず exec システムコールでコマンド実行を試みますが, シェルスクリプトは実行ファイルではないので exec は失敗します. 次にファイルに実行権限があればシェルスクリプトだと判定し, 現在のシェルでスクリプトを実行します. 余計な手間を省く, 実行されるシェルを統一するという役割があるのです. そういうわけなので, スクリプトとして実行されないファイルであればシェバンは不要です. 例えば関数を定義してドットコマンド . で読み込んで使うファイルの場合です. ドットコマンド . ファイルの内容を展開するコマンドです. 例えば . abc とするとファイル abc の内容が実行されます. C 言語の #include のようなものですね. 用途としては, 関数を定義しておいたり, 環境変数を設定したりするのに便利です. こういう記号はネットでは検索しづらいので本に書いてあると助かります. 教科書的な本を読む利点だと思います. ワイルドカード ls ~/* でホームディレクトリ以下の全てのファイルが見られますが, これはワイルドカードという機能の一部です. 以下のような記号でファイルを指定できます. * : 任意の文字列 ? : 任意の 1 文字 [ABC]: A/B/C のいずれかの文字 [!...

September 7, 2022 · 3 min

『コンピュータ・システム プログラマの視点から』で知識の糸を織りあげる

『コンピュータ・システム プログラマの視点から』 はコンピュータ・サイエンスの教科書です. コードを書いて, コンパイルして, プログラムを実行する一連の流れにおいて, コンピュータの中では実際のところ何が起きているのかを知りたい人のための本です. 扱う範囲が幅広く CPU アーキテクチャ メモリ階層 リンクの仕組み 仮想メモリ 並行プログラミング など, 盛り沢山な内容となっています. 非常に分厚い本で 900 ページ近くあるのですが, これでも内容は絞られています. 副題の「プログラマの視点から」というのは大事な指針です. 多岐に渡る本書の内容は, どれも「C 言語を書くときに知っておいたほうが良いかどうか」という基準で取捨選択されています. 例えばアセンブラを学びますが, アセンブラを自力で書けるようになることは目的としていません. そうではなく, コンパイラが出力したアセンブラを読んで挙動を追ったり性能を最適化したりすることができるようになることが目的です. ほぼ全てのものが順を追って説明されるので前提となる知識は少ないです (大学のコンピュータ・サイエンス入門コースを元にした本らしい). 例えば CPU のパイプライン制御の章では「論理ゲートとは」というところから話が始まります. 個人的には, これまで学んできたことが関連付けられたり補強されたり, 知識や理解を整理する良い機会となりました. 以下印象に残った点をかいつまんでまとめます. 浮動小数点 浮動小数点はなんとなく地味な存在だと思っていて, これまであまり深く考えたことがなかったのですが, 今更ながらよく考えられたフォーマットだなと思いました. 昇順に並べた時ビットが符号なし整数と同じになる, 非正規化数から最小の正規化数まで等間隔に滑らかにつながると言う事実を知って驚きました. かつては仕様が乱立していた時代もあったそうですが, 今の形に落ち着いたのも納得です. 実用的には小数と整数の変換で誤差が出るかどうか, 丸めがどのように行われるのかといったことは把握しておくと役に立つかもしれないと思いました. アセンブリ C 言語がどのようにアセンブリに変換されるのかが説明されています. 例えば if は条件ジャンプを使って実現されることをなどを学びます. このあたりは昔 『コンピュータシステムの理論と実装』で自力で考えたことがありました が, 本書を先に読んでいれば楽だったかもしれないと思いました. 多くは既知の内容でしたが, switch については認識を改めました. これまで if-else と同じようなものだろうと思っていたのですが, アセンブリのレベルで見ると実装方法が異なります. switch はジャンプテーブルを用いて対象の case に直接ジャンプするので効率が良いです. if-else の連続だとその回数分条件式が評価されますしね....

August 14, 2022 · 2 min