<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>読書ログ on blog.kyu08.com</title>
    <link>https://blog.kyu08.com/pr-344/tags/%E8%AA%AD%E6%9B%B8%E3%83%AD%E3%82%B0/</link>
    <description>Recent content in 読書ログ on blog.kyu08.com</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>ja</language>
    <copyright>blog.kyu08.com</copyright>
    <lastBuildDate>Sun, 21 Jun 2026 23:32:15 +0900</lastBuildDate><atom:link href="https://blog.kyu08.com/pr-344/tags/%E8%AA%AD%E6%9B%B8%E3%83%AD%E3%82%B0/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>『エンジニアのための時間管理術』を読んだ</title>
      <link>https://blog.kyu08.com/pr-344/posts/time-management-for-system-administrators/</link>
      <pubDate>Sun, 21 Jun 2026 23:32:15 +0900</pubDate>
      
      <guid>https://blog.kyu08.com/pr-344/posts/time-management-for-system-administrators/</guid>
      <description>エンジニアのための時間管理術を読んだので参考になったところをまとめておく。 表紙はクズリというイタチ科の動物らしい 読もうと思ったきっかけ まとめ</description>
      <content>&lt;p&gt;&lt;a href=&#34;https://www.oreilly.co.jp/books/9784873113074/&#34; target=&#34;_blank&#34; &gt;エンジニアのための時間管理術&lt;/a&gt;を読んだので参考になったところをまとめておく。&lt;/p&gt;
&lt;p&gt;&lt;figure class=&#34;image-with-caption&#34;&gt;
    &lt;img src=&#34;book.webp&#34; alt=&#34;book.webp&#34; loading=&#34;lazy&#34; /&gt;
    &lt;figcaption&gt;表紙はクズリというイタチ科の動物らしい&lt;/figcaption&gt;
  &lt;/figure&gt;&lt;/p&gt;
&lt;h2 id=&#34;読もうと思ったきっかけ&#34;&gt;読もうと思ったきっかけ&lt;/h2&gt;
&lt;!-- TODO: 書けそうなら書く。仕事の時間管理がイマイチな感じがしたので参考になる点があるといいなと思って読んでみた。 --&gt;
&lt;h2 id=&#34;まとめ&#34;&gt;まとめ&lt;/h2&gt;
</content>
    </item>
    
    <item>
      <title>『プログラミング言語C 第2版』を読んだ</title>
      <link>https://blog.kyu08.com/pr-344/posts/k_and_r/</link>
      <pubDate>Sun, 12 Apr 2026 17:48:08 +0900</pubDate>
      
      <guid>https://blog.kyu08.com/pr-344/posts/k_and_r/</guid>
      <description>Operating Systems: Three Easy Pieces(以下、OSTEP)に取り組むにあたって、C言語の知識があるとスムーズそうだったので読んだ。 プログラミング言語C - 共立出</description>
      <content>&lt;p&gt;&lt;img src=&#34;./book.webp&#34; alt=&#34;book&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://pages.cs.wisc.edu/~remzi/OSTEP/&#34; target=&#34;_blank&#34; &gt;Operating Systems: Three Easy Pieces&lt;/a&gt;(以下、&lt;a href=&#34;https://pages.cs.wisc.edu/~remzi/OSTEP/&#34; target=&#34;_blank&#34; &gt;OSTEP&lt;/a&gt;)に取り組むにあたって、C言語の知識があるとスムーズそうだったので読んだ。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://www.kyoritsu-pub.co.jp/book/b10011596.html&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://www.kyoritsu-pub.co.jp/book/b10011596.html&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail&#34;&gt;
      &lt;img src=&#34;https://hondana-image.s3.amazonaws.com/book/image/10011596/fd17bee4-f762-49a3-b1ee-d888d2ac90ca.jpg&#34; alt=&#34;プログラミング言語C - 共立出版&#34; loading=&#34;lazy&#34;&gt;
    &lt;/div&gt;&lt;div class=&#34;blogcard-content&#34;&gt;
      &lt;div class=&#34;blogcard-title&#34;&gt;プログラミング言語C - 共立出版&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;Brian W.カーニハン 著&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://www.kyoritsu-pub.co.jp/book/b10011596.html&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;Cに関してはCS50で基本的な文法を学んだ程度であまり体系的には学んでいなかったので、CS50の内容を補完するような感じで読んだ。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://blog.kyu08.com/posts/cs50-jp/&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://blog.kyu08.com/posts/cs50-jp/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail&#34;&gt;
      &lt;img src=&#34;https://blog.kyu08.com/posts/cs50-jp/cover.png&#34; alt=&#34;CS50.jpでCSに入門した&#34; loading=&#34;lazy&#34;&gt;
    &lt;/div&gt;&lt;div class=&#34;blogcard-content&#34;&gt;
      &lt;div class=&#34;blogcard-title&#34;&gt;CS50.jpでCSに入門した&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;CS50.jpの気になっていたトピックを学んでみたので振り返っておく。 CS50.jpとは CS50.jpの説明はサイトから引用する。 このページ&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://blog.kyu08.com/posts/cs50-jp/&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;h2 id=&#34;どんな本か&#34;&gt;どんな本か&lt;/h2&gt;
&lt;p&gt;C言語の開発者であるB.W.カーニハンとD.M.リッチーによるC言語の解説書。&lt;/p&gt;
&lt;p&gt;1989/06/15発売と、約40年前の本だが入門書としての評価が未だに高いようだったので買ってみた。(結果的にも普通に勉強になったので良かった)&lt;/p&gt;
&lt;p&gt;二人のイニシャルをとってK&amp;amp;Rと呼ばれることもあるらしい。&lt;/p&gt;
&lt;p&gt;ちなみに、&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;1.1 Getting Started に、例として掲載されている&amp;quot;hello, world&amp;quot;プログラムは、あらゆる「プログラミングの最初の例題」として定番となった。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://ja.wikipedia.org/wiki/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E8%A8%80%E8%AA%9EC&#34; target=&#34;_blank&#34; &gt;https://ja.wikipedia.org/wiki/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E8%A8%80%E8%AA%9EC&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;とあるように、&lt;code&gt;hello, world&lt;/code&gt;の生みの親としても有名らしい。（！）&lt;/p&gt;
&lt;p&gt;各章に演習問題が豊富に用意されているので手を動かしながら学びやすかった。&lt;/p&gt;
&lt;p&gt;また、付録を除くと231ページと比較的コンパクトなので、Cの全体像をざっと把握するのにちょうどいいボリューム感だった。&lt;/p&gt;
&lt;h2 id=&#34;読み方&#34;&gt;読み方&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;1,2章は演習問題をやりつつ読み、他の章は演習問題をスキップして本文だけ読んだ。
&lt;ul&gt;
&lt;li&gt;Cを完全理解したり人に教えられるレベルになりたい、というよりは&lt;a href=&#34;https://pages.cs.wisc.edu/~remzi/OSTEP/&#34; target=&#34;_blank&#34; &gt;OSTEP&lt;/a&gt;での実装がスムーズになれば嬉しいなーくらいの温度感だったのと、手を動かすのは&lt;a href=&#34;https://pages.cs.wisc.edu/~remzi/OSTEP/&#34; target=&#34;_blank&#34; &gt;OSTEP&lt;/a&gt;でできそうだったので知らない文法や仕組みを軽く頭に入れておくくらいの感じで読んだ。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;#include&lt;/code&gt;なしでboolが使えると多少楽そうだったのでC23で動かした。
&lt;ul&gt;
&lt;li&gt;演習問題を解いた実装はこちら。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://github.com/kyu08/sunaba/tree/d15fb4fa20d3e478cc0f5ac6f9e89e7d0c668b21/c/k_and_r&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://github.com/kyu08/sunaba/tree/d15fb4fa20d3e478cc0f5ac6f9e89e7d0c668b21/c/k_and_r&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail&#34;&gt;
      &lt;img src=&#34;https://opengraph.githubassets.com/903bd6d6dd437fe6ffdcd00ef3a9bd8fa1acb8191443eed7373f3f2a5d7c9de1/kyu08/sunaba&#34; alt=&#34;sunaba/c/k_and_r at d15fb4fa20d3e478cc0f5ac6f9e89e7d0c668b21 · kyu08/sunaba&#34; loading=&#34;lazy&#34;&gt;
    &lt;/div&gt;&lt;div class=&#34;blogcard-content&#34;&gt;
      &lt;div class=&#34;blogcard-title&#34;&gt;sunaba/c/k_and_r at d15fb4fa20d3e478cc0f5ac6f9e89e7d0c668b21 · kyu08/sunaba&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;Personal sandbox. Contribute to kyu08/sunaba development by creating an account on GitHub.&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://github.com/kyu08/sunaba/tree/d15fb4fa20d3e478cc0f5ac6f9e89e7d0c668b21/c/k_and_r&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;h2 id=&#34;学び&#34;&gt;学び&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;変数、関数の可視性の制御方法(&lt;code&gt;static&lt;/code&gt;、&lt;code&gt;extern&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;#include&lt;/code&gt;の機能(&lt;code&gt;&amp;quot;foo.h&amp;quot;&lt;/code&gt;と&lt;code&gt;&amp;lt;foo.h&amp;gt;&lt;/code&gt;の違いなど)&lt;/li&gt;
&lt;li&gt;aが配列のとき&lt;code&gt;a[i]&lt;/code&gt;と&lt;code&gt;*(a + i)&lt;/code&gt;は同じ&lt;/li&gt;
&lt;li&gt;共用体
&lt;ul&gt;
&lt;li&gt;結構使うのが難しそうなので相当パフォーマンスを重視したいときにしか使わないかも&amp;hellip;?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;関数ポインタ&lt;/li&gt;
&lt;li&gt;マクロの基礎&lt;/li&gt;
&lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;まとめ&#34;&gt;まとめ&lt;/h2&gt;
&lt;p&gt;(すべての演習問題をやったわけではないのもあって)1週間ちょっとでCについて一通り簡単に学べて、ちょうどいいボリューム感だった。&lt;/p&gt;
&lt;p&gt;ということで&lt;a href=&#34;https://pages.cs.wisc.edu/~remzi/OSTEP/&#34; target=&#34;_blank&#34; &gt;OSTEP&lt;/a&gt;に取り組む準備ができたので次は実際に着手していこうと思う。&lt;/p&gt;
</content>
    </item>
    
    <item>
      <title>『ネットワークはなぜつながるのか』を読んだ</title>
      <link>https://blog.kyu08.com/pr-344/posts/how-networks-work/</link>
      <pubDate>Sat, 04 Apr 2026 16:45:52 +0900</pubDate>
      
      <guid>https://blog.kyu08.com/pr-344/posts/how-networks-work/</guid>
      <description>ネットワークはなぜつながるのか 第2版を読んだので感想などをまとめる。 どんな本か ブラウザにURLを入力してからサーバーから返ってきたレスポンス</description>
      <content>&lt;p&gt;&lt;img src=&#34;./book.webp&#34; alt=&#34;book&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://bookplus.nikkei.com/atcl/catalog/07/P83110/&#34; target=&#34;_blank&#34; &gt;ネットワークはなぜつながるのか 第2版&lt;/a&gt;を読んだので感想などをまとめる。&lt;/p&gt;
&lt;h2 id=&#34;どんな本か&#34;&gt;どんな本か&lt;/h2&gt;
&lt;p&gt;ブラウザにURLを入力してからサーバーから返ってきたレスポンスをブラウザで表示するまでの間に起きることを順を追って説明してくれる本。&lt;/p&gt;
&lt;p&gt;章の構成は以下。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Chapter Number&lt;/th&gt;
&lt;th&gt;Title&lt;/th&gt;
&lt;th&gt;Summary&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;第1章&lt;/td&gt;
&lt;td&gt;Webブラウザがメッセージを作る―ブラウザ内部を探検&lt;/td&gt;
&lt;td&gt;ブラウザにURLを入力してからブラウザがIPアドレスを解決し、HTTPメッセージを作成してプロトコルスタックに渡すまでに行うこと&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;第2章&lt;/td&gt;
&lt;td&gt;TCP/IPのデータを電気信号にして送る―プロトコル・スタックとLANアダプタを探検&lt;/td&gt;
&lt;td&gt;ブラウザから依頼を受けたプロトコルスタックがソケットを作成してから通信を終えてソケットを抹消するまでの流れ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;第3章&lt;/td&gt;
&lt;td&gt;ケーブルの先はLAN機器だった―ハブとスイッチ、ルーターを探検&lt;/td&gt;
&lt;td&gt;LANケーブルへと送り出されたパケットがリピータハブ、スイッチングハブ、ルーターなどの機器を経由してインターネットに向かって進んでいく流れ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;第4章&lt;/td&gt;
&lt;td&gt;アクセス回線を通ってインターネットの内部へ―アクセス回線とプロバイダを探検&lt;/td&gt;
&lt;td&gt;パケットがインターネット接続用ルーターを経由してインターネットの中に入って進んでいく様子&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;第5章&lt;/td&gt;
&lt;td&gt;サーバー側のLANには何がある&lt;/td&gt;
&lt;td&gt;サーバー側のPOPに入ったパケットがサーバーの手前にあるファイアウォール、キャッシュサーバー、負荷分散装置などを通過する様子&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;第6章&lt;/td&gt;
&lt;td&gt;Webサーバーに到着し、応答データがWebブラウザに戻る―わずか数秒の「長い旅」の終わり&lt;/td&gt;
&lt;td&gt;サーバーがリクエストを受信してからクライアント側のブラウザが結果を表示するまでの流れ&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;特に&lt;strong&gt;第1章 ~ 第3章の内容が普段のWeb開発と関わりが大きいかつ自分の知識が浅い領域だったのでとても面白かった。&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;なぜ読んだか&#34;&gt;なぜ読んだか&lt;/h2&gt;
&lt;p&gt;そもそも自分はコンピューターサイエンスをこれまで(大学などで)体系的に学んできていないのもあり、以下の目的でコンピューターサイエンスの勉強を隙間時間に進めている。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ソフトウェアエンジニアリング文脈の問題解決やスキル獲得の速度を上げたい&lt;/li&gt;
&lt;li&gt;知的好奇心を満たしたい&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;去年は&lt;a href=&#34;https://www.oreilly.co.jp/books/9784814400874/&#34; target=&#34;_blank&#34; &gt;コンピュータシステムの理論と実装&lt;/a&gt;を読んでコンピューターについて広く浅く理解することができたので次はネットワーク周りを強化しようと思い、読んでみた。(他にはセキュリティ、データ構造とアルゴリズム、データベース、プロトコルスタック、シェルなどが気になっている)&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://blog.kyu08.com/posts/nand2tetris/&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://blog.kyu08.com/posts/nand2tetris/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail&#34;&gt;
      &lt;img src=&#34;https://blog.kyu08.com/posts/nand2tetris/cover.png&#34; alt=&#34;『コンピュータシステムの理論と実装 第2版』を読んだ&#34; loading=&#34;lazy&#34;&gt;
    &lt;/div&gt;&lt;div class=&#34;blogcard-content&#34;&gt;
      &lt;div class=&#34;blogcard-title&#34;&gt;『コンピュータシステムの理論と実装 第2版』を読んだ&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;『コンピュータシステムの理論と実装 第2版』を読んだので感想を書く。割と長いので得られた学びだけ読みたい方は## 学び、得た経験までジャンプして&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://blog.kyu08.com/posts/nand2tetris/&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;h2 id=&#34;学びや気付き&#34;&gt;学びや気付き&lt;/h2&gt;
&lt;p&gt;「ブラウザにURLを打ち込んでエンターキーを押すと何が起こるか」という質問に暗記ではなく理解をもとに答えられるようになった。(はず) 特に以下に関しては今までより詳しく理解できた。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;ブラウザが何をしているか&lt;/li&gt;
&lt;li&gt;DNSが何をしているか&lt;/li&gt;
&lt;li&gt;TCP接続においてプロトコルスタックが何をしているか&lt;/li&gt;
&lt;li&gt;IPが何をしているか&lt;/li&gt;
&lt;li&gt;イーサネットとは何か&lt;/li&gt;
&lt;li&gt;インターネットとは何か&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;ネットワークの基礎を学んだことで今後の問題解決や技術理解の助けにもなってくれそう。&lt;/p&gt;
&lt;p&gt;それぞれ現時点での自分の理解を書いてみる。&lt;/p&gt;
&lt;h3 id=&#34;1-ブラウザが何をしているか&#34;&gt;1. ブラウザが何をしているか&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;FQDNをもとにDNSにIPアドレスを問い合わせて解決する&lt;/li&gt;
&lt;li&gt;HTTPリクエストを作成する&lt;/li&gt;
&lt;li&gt;ソケットを作成する&lt;/li&gt;
&lt;li&gt;プロトコルスタックにTCPコネクションの確立を依頼する&lt;/li&gt;
&lt;li&gt;プロトコルスタックにリクエストの送信を依頼する&lt;/li&gt;
&lt;li&gt;通信が終わったらソケットを抹消する&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;どんなシステムコールを呼ぶ必要があるのか気になったのでCで簡単なHTTP Clientを書いてみた。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://github.com/kyu08/sunaba/blob/ea1ba354678e5c1616ea13a62ddcdb04ed34859f/network/how_networks_work/myhttpclient-c/main.c&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://github.com/kyu08/sunaba/blob/ea1ba354678e5c1616ea13a62ddcdb04ed34859f/network/how_networks_work/myhttpclient-c/main.c&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail&#34;&gt;
      &lt;img src=&#34;https://opengraph.githubassets.com/82a16aa8925c3f1388909b52c7915e23f6e885acaad0a645b25119d749296664/kyu08/sunaba&#34; alt=&#34;sunaba/network/how_networks_work/myhttpclient-c/main.c at ea1ba354678e5c1616ea13a62ddcdb04ed34859f · kyu08/sunaba&#34; loading=&#34;lazy&#34;&gt;
    &lt;/div&gt;&lt;div class=&#34;blogcard-content&#34;&gt;
      &lt;div class=&#34;blogcard-title&#34;&gt;sunaba/network/how_networks_work/myhttpclient-c/main.c at ea1ba354678e5c1616ea13a62ddcdb04ed34859f · kyu08/sunaba&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;Personal sandbox. Contribute to kyu08/sunaba development by creating an account on GitHub.&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://github.com/kyu08/sunaba/blob/ea1ba354678e5c1616ea13a62ddcdb04ed34859f/network/how_networks_work/myhttpclient-c/main.c&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;今回自分が実装したHTTP Clientでは以下のような流れでシステムコールや関数が呼ばれる。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&#34;https://man7.org/linux/man-pages/man3/getaddrinfo.3.html&#34; target=&#34;_blank&#34; &gt;&lt;code&gt;getaddrinfo(3)&lt;/code&gt;&lt;/a&gt; を使ってドメイン名に合致するIPアドレス(の配列)を取得&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://man7.org/linux/man-pages/man2/socket.2.html&#34; target=&#34;_blank&#34; &gt;&lt;code&gt;socket(2)&lt;/code&gt;&lt;/a&gt;でソケットを作成しソケットへのファイルディスクリプタを取得する&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://man7.org/linux/man-pages/man2/connect.2.html&#34; target=&#34;_blank&#34; &gt;&lt;code&gt;connect(2)&lt;/code&gt;&lt;/a&gt;サーバーへの接続を確立する&lt;/li&gt;
&lt;li&gt;&lt;code&gt;2.&lt;/code&gt;で取得したファイルディスクリプタに対して&lt;a href=&#34;https://man7.org/linux/man-pages/man2/write.2.html&#34; target=&#34;_blank&#34; &gt;&lt;code&gt;write(2)&lt;/code&gt;&lt;/a&gt; でリクエストを書き込む&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://man7.org/linux/man-pages/man2/read.2.html&#34; target=&#34;_blank&#34; &gt;&lt;code&gt;read(2)&lt;/code&gt;&lt;/a&gt; でレスポンスを読み込む&lt;/li&gt;
&lt;li&gt;サーバー側がソケットをクローズしたらクライアント側でも&lt;a href=&#34;https://man7.org/linux/man-pages/man2/close.2.html&#34; target=&#34;_blank&#34; &gt;&lt;code&gt;close(2)&lt;/code&gt;&lt;/a&gt;を使ってソケットをクローズする&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;なお、実装は&lt;code&gt;getaddrinfo(3)&lt;/code&gt;の&lt;code&gt;EXAMPLES&lt;/code&gt;を参考にしたらほとんど完成してしまった。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://man7.org/linux/man-pages/man3/getaddrinfo.3.html#EXAMPLES&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://man7.org/linux/man-pages/man3/getaddrinfo.3.html#EXAMPLES&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail blogcard-thumbnail-placeholder&#34;&gt;
      &lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 24 24&#34; fill=&#34;none&#34; stroke=&#34;currentColor&#34; stroke-width=&#34;2&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;&gt;
        &lt;path d=&#34;M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71&#34;&gt;&lt;/path&gt;
        &lt;path d=&#34;M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71&#34;&gt;&lt;/path&gt;
      &lt;/svg&gt;
    &lt;/div&gt;&lt;div class=&#34;blogcard-content&#34;&gt;
      &lt;div class=&#34;blogcard-title&#34;&gt;getaddrinfo(3) - Linux manual page&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://man7.org/linux/man-pages/man3/getaddrinfo.3.html#EXAMPLES&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;比較のためにGoでも&lt;code&gt;syscall&lt;/code&gt;パッケージを使って書いてみた。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://github.com/kyu08/sunaba/blob/ea1ba354678e5c1616ea13a62ddcdb04ed34859f/network/how_networks_work/myhttpclient-go/main.go#L1&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://github.com/kyu08/sunaba/blob/ea1ba354678e5c1616ea13a62ddcdb04ed34859f/network/how_networks_work/myhttpclient-go/main.go#L1&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail&#34;&gt;
      &lt;img src=&#34;https://opengraph.githubassets.com/82a16aa8925c3f1388909b52c7915e23f6e885acaad0a645b25119d749296664/kyu08/sunaba&#34; alt=&#34;sunaba/network/how_networks_work/myhttpclient-go/main.go at ea1ba354678e5c1616ea13a62ddcdb04ed34859f · kyu08/sunaba&#34; loading=&#34;lazy&#34;&gt;
    &lt;/div&gt;&lt;div class=&#34;blogcard-content&#34;&gt;
      &lt;div class=&#34;blogcard-title&#34;&gt;sunaba/network/how_networks_work/myhttpclient-go/main.go at ea1ba354678e5c1616ea13a62ddcdb04ed34859f · kyu08/sunaba&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;Personal sandbox. Contribute to kyu08/sunaba development by creating an account on GitHub.&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://github.com/kyu08/sunaba/blob/ea1ba354678e5c1616ea13a62ddcdb04ed34859f/network/how_networks_work/myhttpclient-go/main.go#L1&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;h3 id=&#34;2-dnsが何をしているか&#34;&gt;2. DNSが何をしているか&lt;/h3&gt;
&lt;h4 id=&#34;dnsサーバーに格納されているデータ&#34;&gt;DNSサーバーに格納されているデータ&lt;/h4&gt;
&lt;p&gt;DNSサーバーには以下のようなデータが格納されている。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;名前
&lt;ul&gt;
&lt;li&gt;サーバーやメール配送先の名前&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;クラス
&lt;ul&gt;
&lt;li&gt;常に&lt;code&gt;IN&lt;/code&gt;が格納される。&lt;/li&gt;
&lt;li&gt;DNSができた当初はインターネット以外のネットワークでも利用も検討されていたが、現在はインターネット以外のネットワークが消滅したので&lt;code&gt;IN&lt;/code&gt;しか入らない。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;タイプ
&lt;ul&gt;
&lt;li&gt;名前にどのようなタイプの情報が対応付けられているかを表現した値。&lt;/li&gt;
&lt;li&gt;具体例
&lt;ul&gt;
&lt;li&gt;A
&lt;ul&gt;
&lt;li&gt;IPアドレス(AddressのA&lt;a href=&#34;https://www.cloudflare.com/learning/dns/dns-records/dns-a-record/&#34; target=&#34;_blank&#34; &gt;らしい&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;MX
&lt;ul&gt;
&lt;li&gt;メール配送先&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CNAME
&lt;ul&gt;
&lt;li&gt;名前にエイリアスを設定する&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;以下はDNSレコードの例。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;名前&lt;/th&gt;
&lt;th&gt;クラス&lt;/th&gt;
&lt;th&gt;タイプ&lt;/th&gt;
&lt;th&gt;クライアントに返答する項目&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;example.com&lt;/td&gt;
&lt;td&gt;IN&lt;/td&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;192.0.2.226&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;example.test&lt;/td&gt;
&lt;td&gt;IN&lt;/td&gt;
&lt;td&gt;MX&lt;/td&gt;
&lt;td&gt;10 mail.example.test&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mail.example.test&lt;/td&gt;
&lt;td&gt;IN&lt;/td&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;192.0.2.227&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id=&#34;世界中のdnsサーバーが協調する仕組み&#34;&gt;世界中のDNSサーバーが協調する仕組み&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;blog.example.com&lt;/code&gt;というドメインのIPアドレス解決を例に考える&lt;/li&gt;
&lt;li&gt;DNSサーバは階層構造でレコードを分散管理しており、以下のように階層ごとに別々のDNSサーバーに格納されている(同じになることもあるが)
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ルートドメイン&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.com&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;example.com&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;blog.example.com&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;問い合わせはルートドメインから順番にたどるので以下のような流れになる
&lt;ol&gt;
&lt;li&gt;最寄りのDNSサーバが&lt;code&gt;ルートドメイン&lt;/code&gt;のDNSサーバに&lt;code&gt;blog.example.com&lt;/code&gt; のIPアドレスを問い合わせる
&lt;ul&gt;
&lt;li&gt;レコードのIPアドレスはわからないが、&lt;code&gt;com&lt;/code&gt;ドメインのDNSサーバのIPアドレスはわかるからそっちに聞いてくれ、と&lt;code&gt;com&lt;/code&gt;ドメインのDNSサーバのIPアドレスが返ってくる&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;最寄りのDNSサーバが&lt;code&gt;com&lt;/code&gt;ドメインのDNSサーバに&lt;code&gt;blog.example.com&lt;/code&gt; のIPアドレスを問い合わせる
&lt;ul&gt;
&lt;li&gt;同じ要領で &lt;code&gt;example.com&lt;/code&gt; のDNSサーバのIPアドレスが返ってくる&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;最寄りのDNSサーバが&lt;code&gt;example.com&lt;/code&gt;ドメインのDNSサーバに&lt;code&gt;blog.example.com&lt;/code&gt; のIPアドレスを問い合わせる
&lt;ul&gt;
&lt;li&gt;同じ要領で &lt;code&gt;blog.example.com&lt;/code&gt; のDNSサーバのIPアドレスが返ってくる&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;最寄りのDNSサーバが&lt;code&gt;blog.example.com&lt;/code&gt;ドメインのDNSサーバに&lt;code&gt;blog.example.com&lt;/code&gt; のIPアドレスを問い合わせる
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://blog.example.com/&#34; target=&#34;_blank&#34; &gt;&lt;code&gt;blog.example.com&lt;/code&gt;&lt;/a&gt; のIPアドレスが返ってくる&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;DNSサーバにはキャッシュ機能があるので必ずしも毎回このようなステップになるとは限らない。
&lt;ul&gt;
&lt;li&gt;当然TTLも存在するので最新のデータが返ってくるとも限らない。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;3-tcpでの接続の場合にプロトコルスタックが何をしているか&#34;&gt;3. TCPでの接続の場合にプロトコルスタックが何をしているか&lt;/h3&gt;
&lt;p&gt;プロトコルスタックとは&lt;strong&gt;プロトコル(e.g. TCP, UDP, IP, etc.)を役割ごとに階層化して積み重ねたソフトウェア群&lt;/strong&gt;を指す。ネットワークの文脈では主にSocketライブラリとLANドライバの橋渡しの役割を担う。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   +---------------------------------------------------+
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Application Layer-&amp;gt;|  +---------------------------------------------+  |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   |  | Network Applications                        |  |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   |  | (Web Browser, Mailer, Web Server, etc.)     |  |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   |  +----------------------------+----------------+  |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   |  | Socket Library             | Resolver       |  |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   |  +----------------------------+----------------+  |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   +---------------------------------------------------+
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;OS Layer----------&amp;gt;| Protocol Stack                                    |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   |  +----------------------+  +--------------------+ |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   |  | TCP                  |  | UDP                | |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   |  | (Connection-based)   |  | (Connectionless)   | |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   |  +----------------------+  +--------------------+ |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   |  +---------------------------------------------+  |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   |  | IP (Route &amp;amp; Forward)                        |  |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   |  |  +------------+              +------------+ |  |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   |  |  | ICMP       |              | ARP        | |  |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   |  |  +------------+              +------------+ |  |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   |  +---------------------------------------------+  |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   +---------------------------------------------------+
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Driver Layer------&amp;gt;|  +---------------------------------------------+  |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   |  | LAN Driver (Controls LAN Adapter)           |  |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   |  +---------------------------------------------+  |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   +---------------------------------------------------+
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Hardware Layer----&amp;gt;|  +---------------------------------------------+  | 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   |  | LAN Adapter                                 |  |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   |  +---------------------------------------------+  |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                   +---------------------------------------------------+
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;『ネットワークはなぜつながるのか 第2版』P96 図2.1 をもとに再構成&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&#34;https://man7.org/linux/man-pages/man3/getaddrinfo.3.html&#34; target=&#34;_blank&#34; &gt;&lt;code&gt;getaddrinfo(3)&lt;/code&gt;&lt;/a&gt; を使ってドメイン名に合致するIPアドレス(の配列)を取得
&lt;ol&gt;
&lt;li&gt;UDP担当部分にDNSサーバーへの問い合わせを依頼する&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://man7.org/linux/man-pages/man2/socket.2.html&#34; target=&#34;_blank&#34; &gt;&lt;code&gt;socket(2)&lt;/code&gt;&lt;/a&gt;でソケットを作成しソケットへのファイルディスクリプタ(以下fd)を取得する
&lt;ol&gt;
&lt;li&gt;ソケット1つ分のメモリを確保しそこに初期状態であることを記録して&lt;/li&gt;
&lt;li&gt;アプリケーションにfdを返す。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://man7.org/linux/man-pages/man2/connect.2.html&#34; target=&#34;_blank&#34; &gt;&lt;code&gt;connect(2)&lt;/code&gt;&lt;/a&gt;サーバーへの接続を確立する
&lt;ol&gt;
&lt;li&gt;アプリケーションからsocketのfdとサーバー側のIPアドレスとポート番号を受け取る&lt;/li&gt;
&lt;li&gt;以下の手順で3ウェイハンドシェイクを行う
&lt;ol&gt;
&lt;li&gt;(クライアント側)送信元と宛先のポート番号やコントロールビット(&lt;code&gt;SYN=1&lt;/code&gt;, &lt;code&gt;ACK=0&lt;/code&gt;)を含んだTCPヘッダーを作成する&lt;/li&gt;
&lt;li&gt;(クライアント側)IP担当部分に送信を依頼する&lt;/li&gt;
&lt;li&gt;(サーバー側)IP担当部分がパケットを受け取ってTCP担当部分に渡す&lt;/li&gt;
&lt;li&gt;(サーバー側)TCP担当部分がTCPヘッダーを調べてそこに記載されている宛先ポート番号に相当するソケットを探し出す&lt;/li&gt;
&lt;li&gt;(サーバー側)該当するソケットに必要な情報を記録して、接続動作が進行中だという状態にする&lt;/li&gt;
&lt;li&gt;(サーバー側)送信元と宛先のポート番号やコントロールビット(&lt;code&gt;SYN=1&lt;/code&gt;, &lt;code&gt;ACK=1&lt;/code&gt;)を含んだTCPヘッダーを作成する&lt;/li&gt;
&lt;li&gt;(サーバー側)IP担当部分に送信を依頼する&lt;/li&gt;
&lt;li&gt;(クライアント側)IP担当部分がパケットを受け取ってTCP担当部分に渡す&lt;/li&gt;
&lt;li&gt;(クライアント側)TCP担当部分がTCPヘッダーを調べてサーバー側の接続動作が成功なら(&lt;code&gt;SYN=1&lt;/code&gt;, &lt;code&gt;ACK=1&lt;/code&gt;)「サーバーのIPアドレスやポート番号」と「接続完了を示す制御情報」等をソケットに記録する&lt;/li&gt;
&lt;li&gt;(クライアント側)サーバー側に接続成功を示すTCPヘッダー(&lt;code&gt;SYN=0&lt;/code&gt;, &lt;code&gt;ACK=1&lt;/code&gt;)を送り返す&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;2.&lt;/code&gt;で取得したfdに対して&lt;a href=&#34;https://man7.org/linux/man-pages/man2/write.2.html&#34; target=&#34;_blank&#34; &gt;&lt;code&gt;write(2)&lt;/code&gt;&lt;/a&gt; でリクエストを書き込む
&lt;ol&gt;
&lt;li&gt;送信データを受け取ったプロトコルスタックはデータを相手に送る
&lt;ol&gt;
&lt;li&gt;データが大きいときは分割して送る&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ウィンドウ制御方式(ACK番号の到着を待たず、複数のパケットを連続して送る方式)&lt;/strong&gt; で効率化を図る。ウィンドウの大きさは受信側のバッファの空き容量をもとに調整される。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;送信するすべてのパケットにシーケンス番号(何バイト目か)を付与し、受信側はACK番号(受け取ったシーケンス番号の中でその時点で最大のものに1を足した数値)を返し、「ここまでは受け取ったのでこの番号のパケットを送ってください」というメッセージを伝える&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;送信側はACK番号を見て必要に応じてパケットを再送する&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;データを受信した場合、受信したデータ断片とTCPヘッダーを途中でデータが抜けていないか検査し、問題なければACK番号を送り返す&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://man7.org/linux/man-pages/man2/read.2.html&#34; target=&#34;_blank&#34; &gt;&lt;code&gt;read(2)&lt;/code&gt;&lt;/a&gt; でレスポンスを読み込む
&lt;ol&gt;
&lt;li&gt;受信バッファに積まれたデータをアプリケーションに渡す&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;サーバー側がソケットをクローズしたらクライアント側でも&lt;a href=&#34;https://man7.org/linux/man-pages/man2/close.2.html&#34; target=&#34;_blank&#34; &gt;&lt;code&gt;close(2)&lt;/code&gt;&lt;/a&gt;を使ってソケットをクローズする(なお、クライアントが先にソケットをクローズすることもあり、どちらになるかはアプリケーション次第になる。)
&lt;ol&gt;
&lt;li&gt;(サーバー側)がcloseを呼び出す&lt;/li&gt;
&lt;li&gt;(サーバー側)プロトコルスタックがコントロールビットの&lt;code&gt;FIN&lt;/code&gt;を&lt;code&gt;1&lt;/code&gt;にセットしたTCPヘッダーを作成し、IP担当部分に送信を依頼する&lt;/li&gt;
&lt;li&gt;(クライアント側)&lt;code&gt;FIN=1&lt;/code&gt;であるTCPヘッダーが届いたのを確認して、自分のソケットにサーバー側が接続動作に入ったことを記録する&lt;/li&gt;
&lt;li&gt;(クライアント側)&lt;code&gt;FIN=1&lt;/code&gt;であるパケットを受け取ったことをサーバー側に知らせるためにACK番号をサーバー側に送り返す&lt;/li&gt;
&lt;li&gt;(クライアント側)サーバーからすべてのデータを受け取ったことをアプリケーション側に知らせる&lt;/li&gt;
&lt;li&gt;(クライアント側)コントロールビットの&lt;code&gt;FIN&lt;/code&gt;を&lt;code&gt;1&lt;/code&gt;にセットしたTCPヘッダーを作成し、IP担当部分に依頼してサーバーに送ってもらう&lt;/li&gt;
&lt;li&gt;(サーバー側)クライアント側から&lt;code&gt;FIN=1&lt;/code&gt;なパケットを受け取ったらACK番号を返す&lt;/li&gt;
&lt;li&gt;(クライアント側)サーバーからACK番号が返ってきたことを確認し、サーバーとのやり取りを終了する&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;4-ipが何をしているか&#34;&gt;4. IPが何をしているか&lt;/h3&gt;
&lt;p&gt;IPの主な役割は&lt;strong&gt;宛先IPアドレスをもとにパケットの転送先を決定し、次のホップへ届けること。&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;IPヘッダー、MACヘッダーの作成
&lt;ul&gt;
&lt;li&gt;送信元・宛先IPアドレス、TTL(Time To Live)などを含むIPヘッダーをTCPパケットに付与する
&lt;ul&gt;
&lt;li&gt;TTLはルーターを経由するたびに1減らされ、0になったらパケットは破棄される(ループ防止)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;IPヘッダーの前にMACヘッダーを付与する
&lt;ul&gt;
&lt;li&gt;MACヘッダーには宛先MACアドレスと送信元MACアドレスが含まれる&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;MACアドレスの解決にはARPを使う
&lt;ul&gt;
&lt;li&gt;ARPとは、IPアドレスからMACアドレスを解決するためにLAN内でブロードキャストを行い、対象IPアドレスのMACアドレスを特定するためのプロトコルである&lt;/li&gt;
&lt;li&gt;キャッシュ機能もあるので毎回ブロードキャストするわけではない&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ルーティング
&lt;ul&gt;
&lt;li&gt;ルーティングテーブルを参照して「次にどのルーターにパケットを渡すか」を決定する&lt;/li&gt;
&lt;li&gt;宛先IPアドレスとルーティングテーブルのエントリを比較し、最長プレフィックスマッチで転送先を選ぶ&lt;/li&gt;
&lt;li&gt;宛先が同一LAN内であればそのままL2で届けられる&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;あくまでIPは「どこに届けるか」を決める仕組みで、実際の転送はイーサネットを用いて行うためMACアドレスが必要になる&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;IPはベストエフォートの転送のみを担い、信頼性の保証はしない(それはTCPの責務)&lt;/p&gt;
&lt;p&gt;ICMPとARPはIPの動作を補助する形で動く。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ICMP: エラー通知(宛先到達不能など)や疎通確認(ping)に使われる&lt;/li&gt;
&lt;li&gt;ARP: IPアドレスからMACアドレスを解決するためにLAN内でブロードキャストされる&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;5-イーサネットとは何か&#34;&gt;5. イーサネットとは何か&lt;/h3&gt;
&lt;p&gt;イーサネットは&lt;strong&gt;LAN内の機器間でデータをやり取りするための規格。IPがネットワーク間の転送を担うのに対し、イーサネットは同一LAN内の転送を担う。&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;アドレス体系
&lt;ul&gt;
&lt;li&gt;MACアドレス(48ビット)を使って送受信先を識別する&lt;/li&gt;
&lt;li&gt;MACアドレスは原則的にはNICに割り当てられた固有の識別子&lt;/li&gt;
&lt;li&gt;IPアドレスが「建物の住所」なら、MACアドレスは「人の名前」に相当する&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;フレーム
&lt;ul&gt;
&lt;li&gt;イーサネットではデータを「フレーム」という単位で送受信する&lt;/li&gt;
&lt;li&gt;フレームには送信元MACアドレス、宛先MACアドレス、データ、エラー検出用のFCSが含まれる&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;スイッチングハブ
&lt;ul&gt;
&lt;li&gt;MACアドレスと接続ポートの対応表(MACアドレステーブル)を持ち、宛先MACアドレスに対応するポートにだけフレームを転送する&lt;/li&gt;
&lt;li&gt;最初は対応表が空なのでブロードキャストし、応答を受け取ることでテーブルを学習していく&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;6-インターネットとは何か&#34;&gt;6. インターネットとは何か&lt;/h3&gt;
&lt;p&gt;なお「インターネット」は広範な意味を持つ言葉だが、ここでは本書のスコープ(ISP・POP・IXあたりの話)に限定して整理する。&lt;/p&gt;
&lt;p&gt;インターネットとは、世界中のISP(インターネットサービスプロバイダ)のネットワークが相互接続された巨大なネットワークの集合体。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ISPとPOP
&lt;ul&gt;
&lt;li&gt;ISP(Internet Service Provider)はインターネット接続サービスを提供する事業者&lt;/li&gt;
&lt;li&gt;POP(Point of Presence)はISPの設備が置かれた接続拠点。&lt;strong&gt;ユーザーのパケットはまずここに届く&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;POP内にはルーターが置かれており、パケットを次の拠点に転送する&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;NOC
&lt;ul&gt;
&lt;li&gt;POPから入ってきたパケットが集まる&lt;/li&gt;
&lt;li&gt;プロバイダの中核となる設備&lt;/li&gt;
&lt;li&gt;データ転送能力が数テラビット/秒を超えるルーターが使われることもある&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;IX(Internet eXchange)
&lt;ul&gt;
&lt;li&gt;複数のISPが相互に接続するための中立的な施設&lt;/li&gt;
&lt;li&gt;IXを介することでISP間のパケットのやり取りが効率化される&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;パケットの経路
&lt;ul&gt;
&lt;li&gt;ユーザーのパケットはISPのPOP → ISPバックボーン → IX → 相手ISP → サーバーという流れで届く&lt;/li&gt;
&lt;li&gt;経路上のルーターがBGP(Border Gateway Protocol)で経路情報を交換し合うことでインターネット全体のルーティングが成立している&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;qaメモ&#34;&gt;Q&amp;amp;Aメモ&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://x.com/ihtesham2005/status/2030214970353602806&#34; target=&#34;_blank&#34; &gt;こちらのポスト&lt;/a&gt;を参考にしてClaudeに質問を作成してもらい、都度Claudeに相談しながら回答を考えてみた。&lt;/p&gt;
&lt;p&gt;あくまで「この質問に対しては暗記ではなく理解をもとに答えられるようになった」ということをメモしておくための自分用学習メモです。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;No&lt;/th&gt;
&lt;th&gt;質問&lt;/th&gt;
&lt;th&gt;回答&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;TCPの3ウェイハンドシェイクはなぜ「2ウェイ」ではダメなのか&lt;/td&gt;
&lt;td&gt;サーバーからクライアントへの経路が機能しているかどうかをサーバーが確認できないため。&lt;br&gt;双方向の疎通を双方が確認するには3メッセージ必要になる。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;DNSキャッシュのTTLを短くするデメリットは何か&lt;/td&gt;
&lt;td&gt;キャッシュDNSサーバーから権威DNSサーバーへのリクエスト数が増加する。その結果以下が発生する。 &lt;br&gt;  • 権威DNSサーバーが処理しなければならないリクエストの量が増えるため、権威DNSサーバーのレイテンシが増加する &lt;br&gt;  • キャッシュDNSサーバーがキャッシュを返す割合が減るため権威DNSサーバーへのリクエスト分のレイテンシが増加する&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;NATがエンドツーエンド通信に何をしているか図で説明せよ&lt;/td&gt;
&lt;td&gt;送信時はプライベートIPとポート番号をルーターのグローバルIP+任意のポート番号に変換し、受信時はその逆の変換を行う。 &lt;br&gt;結果として通信相手はNATを意識することなく、単一のグローバルIP+ポート番号とやりとりをしているように見える。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;TCPとUDPの使い分けを「信頼性」以外の観点で説明せよ&lt;/td&gt;
&lt;td&gt;前提として、UDPは接続確立や再送のオーバーヘッドがなく、輻輳制御も行わないため高速に通信を行うことができる。&lt;br&gt;信頼性を多少犠牲にしてでも高速性を重視したい場面ではUDPの利用が有効なケースがある。 &lt;br&gt;たとえば遠隔運転システムでは、一瞬映像が途切れたとしてもリアルタイムに映像が表示され続けることが重要になるためUDPのメリットを享受しやすいと考えられる。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;ルーティングテーブルの「最長プレフィックスマッチ」とは何か、なぜその方式か&lt;/td&gt;
&lt;td&gt;ルーティングの際にルーティングテーブルの中から宛先IPアドレスとマッチする範囲が一番長いレコードにあるネットワークを次のルーティング先とする方式。 &lt;br&gt; &lt;br&gt;&lt;code&gt;10.0.0.0/8&lt;/code&gt;に向けるデフォルト経路と&lt;code&gt;10.1.2.0/24&lt;/code&gt;に向ける特定経路が存在する場合は後者を優先しないと意図したルーティングにならないため。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;HTTPSでサーバー証明書が必要な理由を、鍵交換から説明せよ&lt;/td&gt;
&lt;td&gt;MITMへの対策のため。 &lt;br&gt;証明書がないと鍵の交換相手が本物のサーバーなのか攻撃者なのかわからないため必要になる。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;パケットロスが0%でもアプリが遅い理由を説明せよ&lt;/td&gt;
&lt;td&gt;ここでは「アプリが遅い」 == 「クライアント側で見ているWebアプリの動作が想定よりも遅い」と仮定する。 &lt;br&gt; &lt;br&gt;• DNSサーバーのレイテンシが大きい &lt;br&gt;  • クライアントのマシンの動作が遅く、リクエスト送信までに時間がかかっている &lt;br&gt;  • アクセス回線にADSLが含まれるなどがそもそも低速な回線がボトルネックになっている &lt;br&gt;  • クライアントとサーバーが地理的に離れており、そもそも通信に時間がかかる &lt;br&gt;  • 経路上のネットワーク機器が古く、非効率な通信を行っている &lt;br&gt;  • サーバーの負荷が高く、CPUがスロットリングした結果、サーバーの処理全体が遅くなっている &lt;br&gt;  • マイクロサービス構成になっておりそもそも必要なネットワークIOの数が多い&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;サブネットマスクはなぜ必要か、IPアドレスだけでは何が足りないか&lt;/td&gt;
&lt;td&gt;IPアドレスのうち、どこまでがネットワーク部でどこからがホスト部なのかがわからなくなるため。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;ARPはなぜIPレイヤーではなくL2に属するのか&lt;/td&gt;
&lt;td&gt;ARPはIPアドレスをMACアドレスに解決するプロトコルだが、L2のフレームで直接ブロードキャストし、IPルーティングを経由しない。 &lt;br&gt;つまりL3の仕組みに依存せずに動作する必要があるためL2に属する。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;ping が通るのにHTTPが失敗するとき、最初に何を疑うか&lt;/td&gt;
&lt;td&gt;ファイアウォールによるポートのブロックを疑う。 &lt;br&gt;pingはICMPプロトコルを利用しており、そもそもポート番号を指定する必要がない。一方でHTTPはポート番号を指定する必要があるため。 &lt;br&gt;他にはサーバー側でサーバープログラムが起動していない可能性やTLSの証明書エラーの可能性も考えられる。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;まとめ&#34;&gt;まとめ&lt;/h2&gt;
&lt;p&gt;読む前の期待以上にネットワークの解像度を上げられたので読んでよかった。&lt;/p&gt;
&lt;p&gt;次は&lt;a href=&#34;https://pages.cs.wisc.edu/~remzi/OSTEP/&#34; target=&#34;_blank&#34; &gt;Operating Systems: Three Easy Pieces&lt;/a&gt;でOS周りの深堀りをしていこうと思っている。メモリ管理やプロセス、スレッド周りの解像度を上げたい。あと課題でCを書く必要があるのも若干良さそうに感じたポイントでもある。(Cを書くのは辛いが、その分頑張りが身になる感覚があり&amp;hellip;)&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://pages.cs.wisc.edu/~remzi/OSTEP/&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://pages.cs.wisc.edu/~remzi/OSTEP/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail blogcard-thumbnail-placeholder&#34;&gt;
      &lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 24 24&#34; fill=&#34;none&#34; stroke=&#34;currentColor&#34; stroke-width=&#34;2&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;&gt;
        &lt;path d=&#34;M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71&#34;&gt;&lt;/path&gt;
        &lt;path d=&#34;M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71&#34;&gt;&lt;/path&gt;
      &lt;/svg&gt;
    &lt;/div&gt;&lt;div class=&#34;blogcard-content&#34;&gt;
      &lt;div class=&#34;blogcard-title&#34;&gt;Operating Systems: Three Easy Pieces&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://pages.cs.wisc.edu/~remzi/OSTEP/&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;軽く読んだ感じ、英語ではあるもののかなり平易に書いてくれているので読みやすそうだった。やっていく。&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;(C言語は&lt;a href=&#34;../cs50-jp&#34; &gt;CS50&lt;/a&gt;で軽くさらった程度なのでせっかくなので&lt;a href=&#34;https://www.kyoritsu-pub.co.jp/book/b10011596.html&#34; target=&#34;_blank&#34; &gt;『プログラミング言語C 第2版』&lt;/a&gt;あたりの入門書を一冊読むのもいいかもしれない)&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;&amp;ldquo;you will also learn the practical, including how an operating system does things like schedule the CPU, manage memory, and store files persistently.&amp;rdquo; とのこと。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;なお、内容は無料でWebで公開されているので無課金で学習することも可能。自分は移動時間に読んだり書き込んだりしたかったので&lt;a href=&#34;https://remzi.gumroad.com/l/exGpf&#34; target=&#34;_blank&#34; &gt;PDF&lt;/a&gt;を購入した。(それでも$10という破格)&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</content>
    </item>
    
    <item>
      <title>『解像度を上げる』を読んだ</title>
      <link>https://blog.kyu08.com/pr-344/posts/kaizodo-wo-ageru/</link>
      <pubDate>Wed, 11 Feb 2026 13:00:41 +0900</pubDate>
      
      <guid>https://blog.kyu08.com/pr-344/posts/kaizodo-wo-ageru/</guid>
      <description>おすすめしていただいて気になっていた『解像度を上げる――曖昧な思考を明晰にする「深さ・広さ・構造・時間」の４視点と行動法』を読んだ。 起業家に</description>
      <content>&lt;p&gt;おすすめしていただいて気になっていた&lt;a href=&#34;https://eijipress.co.jp/products/2318&#34; target=&#34;_blank&#34; &gt;『解像度を上げる――曖昧な思考を明晰にする「深さ・広さ・構造・時間」の４視点と行動法』&lt;/a&gt;を読んだ。&lt;/p&gt;
&lt;p&gt;起業家に向けて書かれている記述が多かったが、いちソフトウェアエンジニアとしても非常に参考になる部分が多かったので自分に刺さったポイントを書いていく。&lt;/p&gt;
&lt;p&gt;なお、引用は特別に断りがない限りすべて同書からのものです。&lt;/p&gt;
&lt;h2 id=&#34;解像度の構成要素&#34;&gt;「解像度」の構成要素&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;解像度の高さが何によって構成されているかを考えたときに見えてきたのが、「深さ」「広さ」「構造」「時間」の４つの視点です。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;解像度の構成要素を「深さ」「広さ」「構造」「時間」の4つと整理する視点&lt;/strong&gt;を得られたのが本書を読んで一番良かったポイントかもしれない。&lt;/p&gt;
&lt;p&gt;この視点があると「なんか解像度が低いぞ&amp;hellip;」となったときにどの要素が足りていないかを考えることで効率的に再現性高く解像度を上げることができそう。他の人のアウトプットへのFBにもかなり便利に使えそう。&lt;/p&gt;
&lt;p&gt;4要素は以下のように理解した。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;深さ:&lt;/strong&gt; 具体性を上げたり、因果関係を深堀りしたりする&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;広さ:&lt;/strong&gt; 網羅性（幅広さ）を上げる&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;構造:&lt;/strong&gt; 「深さ」と「広さ」のステップで出した各要素を構造化する（要素を分解したり整理したりする）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;時間:&lt;/strong&gt; 「過去」「現在」「未来」のような時間軸の観点を盛り込む&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;情報をツリー構造で整理する&#34;&gt;情報をツリー構造で整理する&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;ここまで、深さ、広さ、構造、時間の４つの視点で解像度をチェックしてきました。こうしたチェックをやりやすくする一つの方法としてお勧めなのが、一度自分の理解をツリー構造で整理してみることです。 　&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;本書でも幾度となくツリー構造で分析を整理した図が紹介されていた。&lt;/p&gt;
&lt;p&gt;ツリー構造で書いていくと色々なメリットがあって良さそうので取り入れてみようと思う。&lt;/p&gt;
&lt;p&gt;たとえば思考の現在地が把握しやすくなることでかなり効率よく思考を深めやすくなる気がする。（今自分は仮説1の解決策2について考えているんだな〜みたいなのが一目でわかるので狭くなりがちな思考を広げられたり、他の要素と行ったり来たりしながら思考を深めやすそう。）&lt;/p&gt;
&lt;p&gt;あとは目的意識なく深さと広さを広げすぎるとノイズが増えそうなので構造化するのを忘れないことも大事そう。（このあたりは実際にやってみて調節するのがよさそう）&lt;/p&gt;
&lt;h2 id=&#34;解像度を上げる対象&#34;&gt;解像度を上げる対象&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;上げるべきは、課題と解決策の解像度&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;ビジネスの文脈では特に&lt;strong&gt;課題&lt;/strong&gt;と&lt;strong&gt;解決策&lt;/strong&gt;の解像度を上げることが重要。&lt;/p&gt;
&lt;p&gt;（文字にするとそれはそうという感じにはなってしまうが）「解像度が足りない」と感じたときに足りないのが&lt;strong&gt;課題の解像度&lt;/strong&gt;なのか&lt;strong&gt;解決策の解像度&lt;/strong&gt;なのか両方なのかを分けて考えられるとよりスムーズに成果に繋がりそう。&lt;/p&gt;
&lt;p&gt;（直感的には課題の解像度が上がらないと解決策の精度や解像度は上がらなそうに思えるので前者が前提になりそう。）&lt;/p&gt;
&lt;h2 id=&#34;課題の選び方&#34;&gt;課題の選び方&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;このように課題や問いが重要視される理由は、良い課題を選べるかどうかで生み出される価値がほぼ決まると言っても過言ではないからです。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;『イシューからはじめよ』でもイシュー度が高い課題を解くことの重要性が説かれていたのを思い出した。&lt;/p&gt;
&lt;p&gt;そういう意味でもまずは課題の解像度を上げることが重要かもしれない。（緊急度が高く重要度が低い課題とかはぱっと解決して早く次に行きたい種類の課題なので例外かもしれないが）&lt;/p&gt;
&lt;h2 id=&#34;書くことで考える&#34;&gt;書くことで考える&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;まず取り組んでほしいのは、「今、何が最も重要な課題だと思っているのか、それはなぜなのか」を仮説で良いから最初に書くことです。&lt;/p&gt;
&lt;p&gt;考え抜いた「結果」を書くのではありません。書くことは思考の「過程」です。書くことで私たちは考えることができます。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;ブログに記事を書いたり（まさにこの記事とかがそう）チームで何か意思決定をする際に会議資料を書いたりすることで自分が考えていることがクリアになったり、思考が深まったりすることがよくあるので最後の2文にはすごく共感した。&lt;/p&gt;
&lt;p&gt;文字にすることの効果はかなり感じているので今後も悩んだら（というか何かを考えたいときは）書くことで思考を深めていこうと思った。&lt;/p&gt;
&lt;h2 id=&#34;書くときの留意点&#34;&gt;書くときの留意点&lt;/h2&gt;
&lt;p&gt;課題の解像度を「深さ」の視点で上げるための方法として「現時点での自分の課題認識を書き出す」という方法が紹介されていた。&lt;/p&gt;
&lt;p&gt;その際のポイントとして以下のような点が挙げられていた。&lt;/p&gt;
&lt;p&gt;（他の人に読んでもらうための）わかりやすい文章を書くという観点でも非常に参考になりそうだったので一部を引用して紹介する。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;最初の書き出しは箇条書きでも構いません。ただし、より詳細に課題を検討するときには、文章として長文で書くことをお勧めします。箇条書きを使うと、論理の飛躍や矛盾などに気づきづらいからです。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;箇条書きだと論理的にわかりやすい文書になるかはかなり書き手に依存すると思っているので頷けた。（自分は箇条書き自体がダメだとは思ってないが注意深く使わないと読み手の解釈が一意にならないので気をつけて使おうと思っている派）&lt;/p&gt;
&lt;p&gt;よくあるパターンでいうと以下のようなケースがあると思う。&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;（「なので」「とはいえ」「しかし」などの接続詞が省略されることが多く、）論理的なつながりがわかりづらい&lt;/li&gt;
&lt;li&gt;列挙された項目がシーケンスなのか選択肢なのか、AndなのかOrなのかがわかりづらい&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Amazonでも会議資料に箇条書きだけで構成されたスライドを使うのは禁止らしい。&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;（さすがに社員全員が同一のルールを実践してるとは限らないと思うが）&lt;/p&gt;
&lt;p&gt;なんにせよ読み手が疑問を感じたり2パターン以上の解釈ができてしまうような文章を書かないことを心がけるのがよさそう。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;主語が明確な文にする　&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;これも抜けがちだがクリティカルな齟齬につながりやすいので気をつけたい。（自分の場合はどちらかというと口頭で話してるときに抜けがちかも）&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;動詞を入れる　──　体言止めではなく、動詞を入れるようにしましょう。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;体言止めも読み手に解釈の余地を与えがちなので注意したい。&lt;/p&gt;
&lt;p&gt;たとえば「データ移行の切り戻しは手動。」とドキュメントに書かれていた場合、「手動で行う予定」なのか「手動でしか行えない」（制約の共有）なのか「手動で行った」（完了報告）なのかが明確ではなかったりする。&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;スタートアップに関するエッセイで有名なポール・グレアムも、エッセイを公開する前には必ず声に出して読み上げて、友達に話すような言い回しになっているかを確認しているそうです（４）。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;普段会議資料を書くときに最後は声に出して読んでみて詰まるポイントがないかチェックしているのでこの点も共感できた。うまく話せないところは論理が飛躍していたり変な結論になっていたりするのことが多いので、仕上げとして声に出して読むのは大事そう。&lt;/p&gt;
&lt;p&gt;ことこのブログに関しては書いた後に声に出して読んだりはしていないが良さそうなので試してみようと思った。&lt;/p&gt;
&lt;h2 id=&#34;深める&#34;&gt;深める&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;事例のサーベイが十分できているかどうかの閾値は、関連事例を「１００」程度知っているか&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;（起業ではなく）ソフトウェアエンジニアリングの場面では必ずしも100個必要とは限らないが、他社の事例を知っておくと引き出しが増えるので、知っておくに越したことはないと思う。&lt;/p&gt;
&lt;p&gt;たとえばソフトウェアアーキテクチャのパターンやディレクトリ構成などは書籍やテックブログ、登壇資料で数多く紹介されているのでそういったアウトプットから学べるとよさそう。普段自分が仕事で関わっている領域ではゼロから何も見ずに自分で考えることに価値があるというよりは、効果的な施策や判断に価値があることが多いので重要な意思決定をする際には適切な情報収集をできるとよさそう。&lt;/p&gt;
&lt;p&gt;また、そうしたネット上の資料は無料で公開されていることが多く、そうした環境にかなりお世話になっている自覚があるので自分もアウトプットを続けて少しでも業界、エコシステムに恩返しをしていければなと思う。&lt;/p&gt;
&lt;h2 id=&#34;不慣れな分野のキャッチアップ&#34;&gt;不慣れな分野のキャッチアップ&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;本屋に行って、端から端まで本を買う 　事例のサーベイがある程度終わったら、次は大きめの書店に行き、自分の課題に関連する業界の本を端から端まで買うことをお勧めします。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;著者によって異なる視点から同じ物事を見ることができますし、重複しているのなら、その情報は誰の目から見ても重要だということが分かります。そうして業界の構造やトレンドを深掘りしていくのです。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;特に不慣れな分野に飛び込むときにはこのような方法は効果的そう。&lt;/p&gt;
&lt;p&gt;同じような内容の書籍は1冊読めばいいのでは？と思っていたが複数の著者で共通した内容がある場合はその内容の重要性が担保されるという観点はなるほどと思った。&lt;/p&gt;
&lt;h2 id=&#34;教える&#34;&gt;教える&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;教える 　対話や質問のさらに一歩先の言語化として、教えるがあります。今考えている課題について、よく知らない人に教えるつもりで話してみましょう。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;自分がブログを書いている理由の1つ。あまり人に教えられるような書き方まではできていないが、先の引用でもあったように書くことを通して理解や思考を深められている。社内外の勉強会での登壇などもこれにあたりそう。&lt;/p&gt;
&lt;h2 id=&#34;コミュニティに参加する&#34;&gt;コミュニティに参加する&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;コミュニティに参加すると、深く考えるためのヒントや、情報をもらえます。それに、誰かが近くにいることで、必然的に言語化や壁打ちの機会が生まれます。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;これまであまりコミュニティには参加してこなかったが、今年はGoの知識を深めたいのでチャレンジしてみようと思った。（さっそく2/21のGo Conference mini in Sendai 2026に行ってみることにした）&lt;/p&gt;
&lt;h2 id=&#34;まとめ&#34;&gt;まとめ&lt;/h2&gt;
&lt;p&gt;主に起業家や起業家を志す人に向けて書かれているように感じたが、いちソフトウェアエンジニアとしても参考になる部分が非常に多く、読んでよかった。&lt;/p&gt;
&lt;p&gt;解像度を上げるための4つの視点「深さ」「広さ」「構造」「時間」は非常に有用なフレームワークだと感じたのでしばらくは意識的に使ってみようと思う。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;この箇条書き複数パターンの例示であることが伝わっている&amp;hellip;と信じたい。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://forbesjapan.com/articles/detail/38119&#34; target=&#34;_blank&#34; &gt;https://forbesjapan.com/articles/detail/38119&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;文脈を読めばわかるだろという意見もあるかもしれないが、可能な限りローコンテキストに記述することで読み手の認知負荷低減に繋がり、結果としてコミュニケーションコストを下げられると考えています。&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</content>
    </item>
    
    <item>
      <title>『CQRS Documents by Greg Young』を読んだ</title>
      <link>https://blog.kyu08.com/pr-344/posts/cqrs-documents-by-greg-young/</link>
      <pubDate>Mon, 12 Jan 2026 00:27:58 +0900</pubDate>
      
      <guid>https://blog.kyu08.com/pr-344/posts/cqrs-documents-by-greg-young/</guid>
      <description>CQRSに興味があったのでGreg Young氏のCQRS Documentsを読んでみた。 https://cqrs.wordpress.com/wp-content/uploads/2010/11/cqrs_documents.pdfhttps://cqrs.wordpress.com/wp-content/uploads/2010/11/cqrs_documents.pdf CQRSに興味を持ったきっかけ ドメイン層のメンテナ</description>
      <content>&lt;p&gt;CQRSに興味があったのでGreg Young氏の&lt;a href=&#34;https://cqrs.wordpress.com/wp-content/uploads/2010/11/cqrs_documents.pdf&#34; target=&#34;_blank&#34; &gt;CQRS Documents&lt;/a&gt;を読んでみた。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://cqrs.wordpress.com/wp-content/uploads/2010/11/cqrs_documents.pdf&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://cqrs.wordpress.com/wp-content/uploads/2010/11/cqrs_documents.pdf&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail blogcard-thumbnail-placeholder&#34;&gt;
      &lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 24 24&#34; fill=&#34;none&#34; stroke=&#34;currentColor&#34; stroke-width=&#34;2&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;&gt;
        &lt;path d=&#34;M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71&#34;&gt;&lt;/path&gt;
        &lt;path d=&#34;M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71&#34;&gt;&lt;/path&gt;
      &lt;/svg&gt;
    &lt;/div&gt;&lt;div class=&#34;blogcard-content&#34;&gt;
      &lt;div class=&#34;blogcard-title&#34;&gt;https://cqrs.wordpress.com/wp-content/uploads/2010/11/cqrs_documents.pdf&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://cqrs.wordpress.com/wp-content/uploads/2010/11/cqrs_documents.pdf&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;h2 id=&#34;cqrsに興味を持ったきっかけ&#34;&gt;CQRSに興味を持ったきっかけ&lt;/h2&gt;
&lt;p&gt;ドメイン層のメンテナビリティの重要性を感じる中で、ドメイン層は書き込み系の振る舞いだけを担い、読み取り系の責務は別のモジュールに移譲してしまった方がドメイン層をシンプルに保てて良いのではないかと考えるようになった。&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;それってCQRSってやつじゃね？と思ったのでまずは原典に近いドキュメントを読んでみることにした。&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;ここからは&lt;a href=&#34;https://cqrs.wordpress.com/wp-content/uploads/2010/11/cqrs_documents.pdf&#34; target=&#34;_blank&#34; &gt;CQRS Documents&lt;/a&gt;の内容をまとめていく。&lt;/p&gt;
&lt;h2 id=&#34;a-stereotypical-architecture-典型的なアーキテクチャ&#34;&gt;&amp;ldquo;A Stereotypical Architecture&amp;rdquo;: 典型的なアーキテクチャ&lt;/h2&gt;
&lt;p&gt;&amp;ldquo;A Stereotypical Architecture&amp;quot;として、典型的なアーキテクチャが紹介されている。CQRS Documentsではこのアーキテクチャに対して段階的にCQRSを導入していく形で説明が進んでいく。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;a-stereotypical-architecture.webp&#34; alt=&#34;a-stereotypical-architecture.webp&#34; loading=&#34;lazy&#34; /&gt;
CQRS Documents by Greg Young P2より引用&lt;/p&gt;
&lt;p&gt;このアーキテクチャではシステムはCRUDのみの機能を持ち、クライアントとは&lt;strong&gt;常にDTOを介して通信する。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;おそらくクライアントが&lt;code&gt;UpdateUserName&lt;/code&gt;のようなエンドポイントに更新後のユーザーネームだけを渡すのではなく&lt;code&gt;/user&lt;/code&gt;に更新後のDTOを丸ごと渡す、というようなことだと思われる。&lt;/p&gt;
&lt;p&gt;サーバー側では受け取ったDTOをドメインオブジェクトに詰め替えてバリデーションを行い、永続化する。&lt;/p&gt;
&lt;p&gt;このような設計ではアプリケーションサービスの責務はDTOとドメインオブジェクトの詰め替えに終始し、ドメイン層はバリデーションを主な責務として受け持つ。データの更新方法はクライアントに委ねられてしまうため、ドメイン知識の一部がクライアント側に漏れ出してしまう。&lt;/p&gt;
&lt;p&gt;このようなアーキテクチャでは簡潔性によってオンボーディングコストが低くなるメリットがある代わりに、次のような課題が存在する。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;スケーリング:&lt;/strong&gt; 一般的なシステムでは読み取り操作は書き込み操作よりも2桁以上多い。読み取り操作から見ると非正規化されたデータ構造が適しているが、書き込み操作から見ると正規化されたデータ構造が適している。これらを単一のDBで扱おうとすると垂直スケーリングが必要になるが、垂直スケーリングには非常に高額なコストがかかる。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DDD適用の困難さ:&lt;/strong&gt; この設計ではAPIがデータ指向のインターフェースを持つため、システム全体がCRUDの4つの動詞に縛られる。（データの更新方法がクライアントまたはユーザー側に漏れ出ておりドメイン知識をソフトウェアで表現することが難しいため）&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;ここまでの感想&#34;&gt;ここまでの感想&lt;/h3&gt;
&lt;p&gt;さすがにこういったアーキテクチャのシステムは見たことがないので極端な例では&amp;hellip;?とは思いつつ時代や場所によってはこういった設計のシステムも存在するのかもしれない。&lt;/p&gt;
&lt;h2 id=&#34;cqrsとは&#34;&gt;CQRSとは&lt;/h2&gt;
&lt;p&gt;CQRSはBertrand Meyerが提唱した&lt;a href=&#34;https://en.wikipedia.org/wiki/Command%E2%80%93query_separation&#34; target=&#34;_blank&#34; &gt;『Command and Query Separation Principle』&lt;/a&gt;にその起源を持つ。Wikipediaではこの原則を次のように説明している。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;It states that every method should either be a command that performs an action, or a query that returns data to the caller, but not both.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Command%E2%80%93query_separation&#34; target=&#34;_blank&#34; &gt;Command–query separation - Wikipedia&lt;/a&gt; より引用&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;とあり、すべてのメソッドはCommandかQueryのいずれかであるべきであり、両方を兼ねるべきではないと説明されている。&lt;/p&gt;
&lt;p&gt;これに対し、Martin Fowlerは以下のようにPopのような操作はCommandでありQueryでもあり、必ずしも上記の原則を厳密に守らなくてもいいのではないか、ということを述べている。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Meyer likes to use command-query separation absolutely, but there are exceptions. Popping a stack is a good example of a modifier that modifies state. Meyer correctly says that you can avoid having this method, but it is a useful idiom. So I prefer to follow this principle when I can, but I&amp;rsquo;m prepared to break it to get my pop. (Fowler)&lt;/p&gt;
&lt;p&gt;CQRS Documents by Greg Young P17より引用&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;ここまでの感想-1&#34;&gt;ここまでの感想&lt;/h3&gt;
&lt;p&gt;実際にWebサービスを開発していてもたとえばユーザー作成メソッドが作成したユーザーのIDを返すような処理は普通に書くし、自分もどちらかというと定義ほどは厳密に運用しなくても十分恩恵を受けられるのではないかという立場。&lt;/p&gt;
&lt;h2 id=&#34;a-stereotypical-architectureにcqrsを導入する&#34;&gt;&amp;ldquo;A Stereotypical Architecture&amp;quot;にCQRSを導入する&lt;/h2&gt;
&lt;p&gt;&amp;ldquo;A Stereotypical Architecture&amp;quot;として最初に紹介されたアーキテクチャでは、ドメインモデルがCommandとQueryの両方に使用されていた。このアプリケーションにCQRSを適用するとQuery側とCommand側はそれぞれ次のようになる。&lt;/p&gt;
&lt;h3 id=&#34;query&#34;&gt;Query&lt;/h3&gt;
&lt;p&gt;Query処理側にはデータ取得のためのメソッドのみが含まれる。&lt;/p&gt;
&lt;p&gt;元のアーキテクチャではドメインモデルを生成し、それをDTOにマッピングしたうえでクライアントに返却していた。多くの場合でドメインモデルとDTOは異なるモデルであるため、以下のような課題があるがこれがCQRSの適用によって解決される。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;複数集約から1つのDTOを生成する場合、複数回DBにアクセスする必要がありパフォーマンスが低下する。また、集約の境界が曖昧になる。&lt;/li&gt;
&lt;li&gt;ドメイン層にQueryの責務が多く含まれている（e.g. repositoryのinterfaceにQuery系のメソッドが多く含まれ、ページングやソート情報が含まれている）&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;After CQRS has been applied there is a natural boundary. Separate paths have been made explicit. It makes a lot of sense now to not use the domain to project DTOs. Instead it is possible to introduce a new way of projecting DTOs.&lt;/p&gt;
&lt;p&gt;CQRS Documents by Greg Young P20より引用&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;とあるように、CQRSを適用することでCommandとQueryの処理経路が明確に分離される。この段階ではドメインモデルをDTOの生成に使用しない方が合理的である。&lt;/p&gt;
&lt;p&gt;その代わりに&amp;quot;Thin Read Layer&amp;quot;という方法でDTOを生成することができる。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;thin-read-layer.webp&#34; alt=&#34;thin-read-layer.webp&#34; loading=&#34;lazy&#34; /&gt;
CQRS Documents by Greg Young P21より引用&lt;/p&gt;
&lt;p&gt;この層はDBから直接データを読み取り（ドメインモデルを迂回し）DTOを生成する。&lt;/p&gt;
&lt;p&gt;こうすることで、&lt;strong&gt;ドメイン層からQueryの責務を切り離すことができ、ドメイン層の純度を上げることができる。&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&#34;command&#34;&gt;Command&lt;/h3&gt;
&lt;p&gt;CQRSを適用するとCommand側のアーキテクチャは以下のようになる。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;the-command-site.webp&#34; alt=&#34;the-command-site.webp&#34; loading=&#34;lazy&#34; /&gt;
CQRS Documents by Greg Young P22より引用&lt;/p&gt;
&lt;p&gt;元のアーキテクチャでは書き込み系の処理をする際もDTOをクライアントから受け取っていたが、CQRS適用後はデータ中心ではなく振る舞い中心の契約を採用している点と読み取り処理が分離されている点が大きな違い。（元のアーキテクチャでは書き込み時にクライアントからDTOを渡していたが、ここではメッセージが渡されるようになっている）&lt;/p&gt;
&lt;p&gt;また、元のアーキテクチャでドメイン層に存在していた次のような課題が解決されている。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;リポジトリに大量の読み取りメソッドが存在する&lt;/li&gt;
&lt;li&gt;DTO構築のためにドメインオブジェクトの内部状態を公開するゲッターメソッドが存在する&lt;/li&gt;
&lt;li&gt;DTO構築のために複数の集約オブジェクトをそれぞれ読み込むことで、非効率なクエリが実行される&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;ドメインイベントイベントソーシング&#34;&gt;ドメインイベント、イベントソーシング&lt;/h3&gt;
&lt;p&gt;本文にはドメインイベント、イベントソーシングについても記載があり読んだがここでは割愛。&lt;/p&gt;
&lt;h3 id=&#34;ここまでの感想-2&#34;&gt;ここまでの感想&lt;/h3&gt;
&lt;p&gt;ドメイン層からQuery系の責務を切り離すことでメンテナビリティが向上する、というのが自分が（直近）CQRSに興味を持っていた一番の理由だったのでそうだよなーと思いながら読んだ。&lt;/p&gt;
&lt;p&gt;また（書いてあるとおりだが）読み取り単位を必ずしもドメインモデル単位にする必要がないためパフォーマンスの最適化が行いやすい点も大きなメリットだといえそう。&lt;/p&gt;
&lt;p&gt;結局CommandとQueryはまったく別の責務なことが多いので両者を分離することでメリットを得られるケースは多そう。&lt;/p&gt;
&lt;h2 id=&#34;作業習慣の違い&#34;&gt;作業習慣の違い&lt;/h2&gt;
&lt;p&gt;CQRS Documentsを読むまでは意識していなかったが、CQRSを採用することで&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;ドメイン層&lt;/li&gt;
&lt;li&gt;リードモデル&lt;/li&gt;
&lt;li&gt;クライアント&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;の3つの要素に分解して作業を進めることができるため、プロジェクトに関わる開発者数をより効果的に増やすことができる。（サーバーとクライアントの作業分担をできるのはCQRSかどうかにかかわらないが、重要なのは1つのサーバーアプリケーションを2並列で安全に進めやすいという点だろう。）&lt;/p&gt;
&lt;p&gt;また、開発者には次のような観点の差異が存在する。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;技術的熟練度&lt;/li&gt;
&lt;li&gt;ビジネスドメインに関する知識&lt;/li&gt;
&lt;li&gt;コスト&lt;/li&gt;
&lt;li&gt;ソフトスキル&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;ドメイン層の実装には4つすべての項目が秀でた人材が最適である一方、リードモデルの実装にはそれらの開発者要件は必ずしも当てはまるとは限らない。&lt;/p&gt;
&lt;h3 id=&#34;ここまでの感想-3&#34;&gt;ここまでの感想&lt;/h3&gt;
&lt;p&gt;開発効率の観点は持ってなかったが、たしかにCQRSを採用することで（1つのアプリケーションが2つのモジュールに分離されるので）コンフリクトせずに開発を進めやすそう。（モジュール設計はプロジェクトによるので厳密には2つのモジュールとは限らないが）&lt;/p&gt;
&lt;h2 id=&#34;感想&#34;&gt;感想&lt;/h2&gt;
&lt;p&gt;事前のイメージ通り、CQRSを適用することで開発効率を高められそうなイメージが持てた。&lt;/p&gt;
&lt;p&gt;CQRS Documents内でも触れられていたが、結局CQRSにしろイベントソーシングにしろ一定のオーバーヘッドはあるので、システムやビジネスの課題や要件、今後の見通しを元に必要性を検討するのが（いつだって）重要そう。&lt;/p&gt;
&lt;p&gt;というのはありつつ、ドメイン層のメンテナビリティを高めるためにCQRSを採用するのはかなり有効な選択肢の1つだとも感じているので、ひとまず個人のプロジェクトで検証してみたいと思う。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;もちろんアプリケーションの状況にもよるが&amp;hellip;。repositoryのRead系メソッドの返り値がドメインモデルと一致&lt;strong&gt;しない&lt;/strong&gt;ケースが多くなるような場合では特にCQRSのメリットが効果を発揮しやすいような気がしている。状況にかかわらずCQRSをやったほうがいいのかどうかはまだあまりわかっていない。ちなみにここでのCQRSは基本的には&lt;strong&gt;同一DB&lt;/strong&gt;でCのアプリケーションコードとQのアプリケーションコードが分離されている、くらいの方法をざっくり想定して書いている。（CとQでDBを分けるパターンは流石にtoo muchなケースが多そうなので）&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;厳密にこのドキュメントが原典であることを確認したわけではない。正確な情報をお持ちの方がいたら教えて下さい。&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</content>
    </item>
    
    <item>
      <title>『RustによるWebアプリケーション開発 設計からリリース・運用まで』を読んだ</title>
      <link>https://blog.kyu08.com/pr-344/posts/rust-web-app-book/</link>
      <pubDate>Mon, 22 Dec 2025 00:13:06 +0900</pubDate>
      
      <guid>https://blog.kyu08.com/pr-344/posts/rust-web-app-book/</guid>
      <description>『RustによるWebアプリケーション開発 設計からリリース・運用まで』を読んだので感じたことをメモしておく。 『ＲｕｓｔによるＷｅｂアプリケー</description>
      <content>&lt;p&gt;『RustによるWebアプリケーション開発 設計からリリース・運用まで』を読んだので感じたことをメモしておく。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://www.kodansha.co.jp/book/products/0000398182&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://www.kodansha.co.jp/book/products/0000398182&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail&#34;&gt;
      &lt;img src=&#34;https://dvs-cover.kodansha.co.jp/0000398182/qlwQ4BgoUFJKQBFNNIbAbFmXHhhSS0R338o5wVij.jpg&#34; alt=&#34;『ＲｕｓｔによるＷｅｂアプリケーション開発　設計からリリース・運用まで』（豊田　優貴,松本　健太郎,吉川　哲史）　製品詳細　講談社&#34; loading=&#34;lazy&#34;&gt;
    &lt;/div&gt;&lt;div class=&#34;blogcard-content&#34;&gt;
      &lt;div class=&#34;blogcard-title&#34;&gt;『ＲｕｓｔによるＷｅｂアプリケーション開発　設計からリリース・運用まで』（豊田　優貴,松本　健太郎,吉川　哲史）　製品詳細　講談社&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;★Rustによるアプリケーション開発のベストプラクティス！ 　Rustを現場で使うときがきた！ Rust経験豊富な筆者が、貴重な知識とテクニックを惜しみなく伝授。 「蔵書管理アプリケーション」の実装を通じて、Rustによる設計、開発、保守、運用までをハンズオンで学ぶ！ コードも丁寧に解説。 【目次】 第1章　本書で開発するもの 第2章　開発環境の構築 第3章　最小構成アプリケーションの実装 第4章　蔵書管理サーバーアプリケーションの設計 第5章　蔵書管理サーバーの実装 第6章　システムの結合とテスト 第7章　アプリケーションの運用 第8章　エコシステムの紹介&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://www.kodansha.co.jp/book/products/0000398182&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;h2 id=&#34;モチベーション&#34;&gt;モチベーション&lt;/h2&gt;
&lt;p&gt;Rustという言語の開発体験がかなり好きでRustでサーバーサイドを書くのがどんな感じなのか純粋に気になっていたので読んでみた。（筆者がサーバーサイドの開発でガッツリ書いたことがあるのはほぼGoのみで、RustはCLIやTUIの開発にしか使ったことがないというバックグラウンド）&lt;/p&gt;
&lt;h2 id=&#34;本書の概要&#34;&gt;本書の概要&lt;/h2&gt;
&lt;p&gt;本書はRustで蔵書管理アプリケーションのサーバーサイドを実装しながらRustでのWebアプリケーション開発の仕方を学ぶことができる本。&lt;/p&gt;
&lt;p&gt;ただ動くものを作る、というよりは業務の実際のサーバーサイドの開発でよく出くわす課題をRustではどう実装するのかが豊富に紹介されている。(DIやエラーハンドリングなど)&lt;/p&gt;
&lt;p&gt;設計面ではレイヤードアーキテクチャを採用しており、レイヤー間の責務などが考慮された設計になっている。その意味でも実務での開発に近い内容になっていると言える。&lt;/p&gt;
&lt;p&gt;あとはステップごとのコード差分が丁寧に書かれているので、本書に従って実装を進めるとWeb Serverの実装が出来上がる（はず）。&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h2 id=&#34;学び&#34;&gt;学び&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;コンパイル時間短縮の工夫
&lt;ul&gt;
&lt;li&gt;アプリケーションを複数のクレートに分割することで変更があったクレートだけ再コンパイルすればよくなるためコンパイル時間が短縮できる。&lt;/li&gt;
&lt;li&gt;たとえば本書ではレイヤードアーキテクチャのレイヤーごとにクレートを分割していた。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Web開発で有用なクレート
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://crates.io/crates/derive-new&#34; target=&#34;_blank&#34; &gt;&lt;code&gt;derive_new&lt;/code&gt;&lt;/a&gt;: &lt;code&gt;new&lt;/code&gt;関数を実装してくれる。デフォルト値の設定などもできる模様。&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://crates.io/crates/serde&#34; target=&#34;_blank&#34; &gt;&lt;code&gt;serde&lt;/code&gt;&lt;/a&gt;: 言わずと知れたシリアライズ/デシリアライズのためのクレート。&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://crates.io/crates/sqlx&#34; target=&#34;_blank&#34; &gt;&lt;code&gt;sqlx&lt;/code&gt;&lt;/a&gt;: SQLを型安全に扱うことができる。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;エラーハンドリングの方法
&lt;ul&gt;
&lt;li&gt;クライアントに返すエラーはthiserrorで定義し、それ以外のエラーはanyhowを使って表現する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;RustでどうDIを実装すべきか
&lt;ul&gt;
&lt;li&gt;ジェネリクスを用いてDIするパターン（静的ディスパッチ）
&lt;ul&gt;
&lt;li&gt;動的ディスパッチと比較すると記述量が増える&lt;/li&gt;
&lt;li&gt;動的ディスパッチと比較するとパフォーマンスが高い&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;トレイトオブジェクト（&lt;code&gt;dyn &amp;lt;トレイト名&amp;gt;&lt;/code&gt;）を利用するパターン（動的ディスパッチ）
&lt;ul&gt;
&lt;li&gt;静的ディスパッチと比較すると記述量が減る&lt;/li&gt;
&lt;li&gt;静的ディスパッチと比較するとパフォーマンス面で不利&lt;/li&gt;
&lt;li&gt;本書ではWeb開発において動的ディスパッチのコストが問題になることは少ないことを理由にこちらを採用していた。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;実際にrustでweb-serverを書いてみた感想主にgoとの比較&#34;&gt;実際にRustでWeb Serverを書いてみた感想（主にGoとの比較）&lt;/h2&gt;
&lt;p&gt;※なお、筆者のRustスキルは趣味レベルなのでRustを深く理解したうえでの感想ではありません。間違っている点や他の重要な観点などがある可能性があります。また、主には個人的な考えのスナップショットを自分用に残す目的で書いているので説明を端折っている箇所がある可能性があります。&lt;/p&gt;
&lt;h3 id=&#34;ポジ&#34;&gt;ポジ&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;enumやパターンマッチ等を使って仕様をスマートに書ける。&lt;/li&gt;
&lt;li&gt;null安全なので他の言語のnull相当の概念を型安全に扱うことができる。&lt;/li&gt;
&lt;li&gt;if式を始めとした関数型ライクな言語機能のおかげで開発体験が良い。&lt;/li&gt;
&lt;li&gt;変数がデフォルトでimmutableなので、mutableな変数を目立たせやすいし、自然とimmutableなコードが書きやすい。&lt;/li&gt;
&lt;li&gt;あらゆるシンボルがデフォルトでprivateなのでカプセル化するようなコードが若干書きやすい。（意識的に&lt;code&gt;pub&lt;/code&gt;を付けなければprivateになってくれる点で強い理由がなければprivateになりやすくなる、と考えている）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;ネガ&#34;&gt;ネガ&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;コンパイル時間が長い。&lt;/li&gt;
&lt;li&gt;コンパイル時間短縮のためにcrate分割が推奨されているが、依存関係の増減があるたびに&lt;code&gt;Cargo.toml&lt;/code&gt;を手書きで編集しないといけないのが若干面倒。
&lt;ul&gt;
&lt;li&gt;もしかしたらコードアクション等、エディタの支援が得られるのかもしれないがそこまで調べられていない。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Goに慣れているとRustのマクロやアトリビュートが若干黒魔術的に感じる。これらに慣れるまでは認知負荷が高そう。例えば以下。（『RustによるWebアプリケーション開発 設計からリリース・運用まで』より引用）
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#[derive(Error, Debug)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;pub&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;enum&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;AppError&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;#[error(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;{0}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    UnprocessableEntity(String),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;#[error(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;{0}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    EntityNotFound(String),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;#[error(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;{0}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ValidationError(&lt;span style=&#34;color:#75715e&#34;&gt;#[from]&lt;/span&gt; garde::Report),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;#[error(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;トランザクションを実行できませんでした。&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    TransactionError(&lt;span style=&#34;color:#75715e&#34;&gt;#[source]&lt;/span&gt; sqlx::Error),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;#[error(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;データベース処理実行中にエラーが発生しました。&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    SpecificOperationError(&lt;span style=&#34;color:#75715e&#34;&gt;#[source]&lt;/span&gt; sqlx::Error),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;#[error(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;No rows affected: {0}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    NoRowsAffectedError(String),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;#[error(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;{0}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    KeyValueStoreError(&lt;span style=&#34;color:#75715e&#34;&gt;#[from]&lt;/span&gt; redis::RedisError),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;#[error(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;{0}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    BcryptError(&lt;span style=&#34;color:#75715e&#34;&gt;#[from]&lt;/span&gt; bcrypt::BcryptError),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;#[error(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;{0}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ConvertToUuidError(&lt;span style=&#34;color:#75715e&#34;&gt;#[from]&lt;/span&gt; uuid::Error),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;#[error(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;ログインに失敗しました&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    UnauthenticatedError,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;#[error(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;認可情報が誤っています&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    UnauthorizedError,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;#[error(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;許可されていない操作です&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ForbiddenOperation,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;#[error(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;{0}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ConversionEntityError(String),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;DIが若干複雑
&lt;ul&gt;
&lt;li&gt;Goならinterface使うだけなので考えることが少なくて済む。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;非同期処理
&lt;ul&gt;
&lt;li&gt;これもRustの非同期処理の仕組みへの理解&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;が大変浅いのであまり具体的に書けないが、自分の現状のRustスキルだとGoに比べて意図通りに動く非同期処理を書くのに数倍時間がかかる。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;まとめ&#34;&gt;まとめ&lt;/h2&gt;
&lt;p&gt;本書を読むまではRustがWebサーバーサイド開発の銀の弾丸、とまでは言わないもののかなりいい選択肢の1つのように思えていた。主に型の表現力のおかげでドメインがうまく表現できたり、所有権などの言語機能や発達したリンターによって内部品質を高く保つことができ、その結果開発生産性が高まると考えていた。&lt;/p&gt;
&lt;p&gt;しかし実際に本書でRustでサーバーを書いてみると上記のメリットはありつつも意外とRustでの実装でも手間や複雑なポイントがあり、Goのシンプルさや手軽さの良さを改めて認識した。&lt;/p&gt;
&lt;p&gt;結果はともあれ実際にRustでサーバーを書くのがどんな感じなのかを知ることが本書を読んだ目的だったので解像度を高めることができてよかった。&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;5章の途中までしかやっていないので「はず」と書いている。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;あるいは単にコンピュータの仕組みへの理解が浅いとも言えるのかもしれない。&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;もちろんもっとDeep Diveしたら違う感想を持つかも知れないが、あくまで今時点の自分の感想としては上記のような感じ。&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</content>
    </item>
    
    <item>
      <title>『コンセプトから理解するRust』を読んだ</title>
      <link>https://blog.kyu08.com/pr-344/posts/understanding-rust-from-concepts/</link>
      <pubDate>Mon, 15 Dec 2025 19:21:35 +0900</pubDate>
      
      <guid>https://blog.kyu08.com/pr-344/posts/understanding-rust-from-concepts/</guid>
      <description>Rustのことをもっと理解りたくて『コンセプトから理解するRust』を読んだ。 コンセプトから理解するRust | 技術評論社Rustはメモリ安全</description>
      <content>&lt;p&gt;&lt;img src=&#34;./book.webp&#34; alt=&#34;book&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;Rustのことをもっと理解りたくて『コンセプトから理解するRust』を読んだ。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://gihyo.jp/book/2022/978-4-297-12562-2&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://gihyo.jp/book/2022/978-4-297-12562-2&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail&#34;&gt;
      &lt;img src=&#34;https://gihyo.jp/assets/images/ogp/2022/9784297125622.jpg&#34; alt=&#34;コンセプトから理解するRust | 技術評論社&#34; loading=&#34;lazy&#34;&gt;
    &lt;/div&gt;&lt;div class=&#34;blogcard-content&#34;&gt;
      &lt;div class=&#34;blogcard-title&#34;&gt;コンセプトから理解するRust | 技術評論社&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;Rustはメモリ安全、スレッド安全を保ちつつ、高パフォーマンスなプログラムを開発できるプログラミング言語です。また、手続き型、オブジェクト指向型、関数型でのプログラミングに対応できるマルチパラダイムの言語でもあります。ただ、そういったRustのポテンシャルを引き出すには、所有権やライフタイム、ジェネリクスやトレイトといった特徴的な仕様の理解が求められ、これらは初学者の壁にもなっています。本書ではそれら難解な仕様をピックアップし、他のプログラミング言語とコードレベルで比較しながら、「なぜそのような仕様になっているか」という言語のコンセプトからRustの理解を試みます。加えて、Rustのこまやかなエラーメッセージを読みつつ、Rustをうまく書くための知識もお伝えします。&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://gihyo.jp/book/2022/978-4-297-12562-2&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;h2 id=&#34;前提&#34;&gt;前提&lt;/h2&gt;
&lt;p&gt;筆者のRustの知識は&lt;a href=&#34;https://tourofrust.com/00_ja.html&#34; target=&#34;_blank&#34; &gt;Tour of Rust&lt;/a&gt;や&lt;a href=&#34;https://doc.rust-jp.rs/book-ja/&#34; target=&#34;_blank&#34; &gt;The Rust Programming Language&lt;/a&gt;を読んだり簡単なツール&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;を作ったことがある程度で、非同期処理をスラスラ書けたり、スムーズに人に教えたりできるレベルではない。&lt;/p&gt;
&lt;p&gt;過去に&lt;a href=&#34;https://doc.rust-jp.rs/book-ja/&#34; target=&#34;_blank&#34; &gt;The Rust Programming Language&lt;/a&gt;を読んだときもスマートポインターまわりなどは飛ばしつつ読んでいたので本書での学びは多かった。&lt;/p&gt;
&lt;h2 id=&#34;学び&#34;&gt;学び&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Box&lt;/code&gt;について理解した。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Rc&lt;/code&gt;, &lt;code&gt;RefCell&lt;/code&gt;, &lt;code&gt;Weak&lt;/code&gt;周りをなんとなく理解した。たぶん空では書けないが、エラーになったら調べて解決できるくらいの理解にはなったはず。&lt;/li&gt;
&lt;li&gt;トレイト境界についてちょっとわかった。&lt;/li&gt;
&lt;li&gt;クロージャ, &lt;code&gt;Fn&lt;/code&gt;, &lt;code&gt;FnMut&lt;/code&gt;, &lt;code&gt;FnOnce&lt;/code&gt;について理解できた。&lt;/li&gt;
&lt;li&gt;簡単な非同期処理の仕組みがわかった。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;今まで全然わかっていなかったこれらの概念が少しだけわかった。やはりコードを書き散らかすだけでなく体系的なインプットも大事&amp;hellip;。（それはそう）&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;おそらく今後Rustを書いたりコンパイラと対話したりしていくともう少し深く理解していけると思う。&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;全体を通してコード例が豊富だったので手元で動かしながら理解しやすくてとてもありがたかった。&lt;/p&gt;
&lt;h2 id=&#34;まとめ&#34;&gt;まとめ&lt;/h2&gt;
&lt;p&gt;Rustの力がまた少しついた。&lt;/p&gt;
&lt;p&gt;Rustを学ぶとRust自体への理解が深まるだけでなく、少なからずコンピュータの仕組みに近い低レイヤな部分の理解も一緒に深まるので勉強になる感覚があって楽しめた。&lt;/p&gt;
&lt;p&gt;非同期処理周りはあまりちゃんと勉強したことがないので次はこの本を読んでみようと思う。（サンプルコードが主にRustで書かれているらしいのでこの本での学びも活かせそう）&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://www.oreilly.co.jp/books/9784873119595/&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://www.oreilly.co.jp/books/9784873119595/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail&#34;&gt;
      &lt;img src=&#34;https://www.oreilly.co.jp/books/images/picture_large978-4-87311-959-5.jpeg&#34; alt=&#34;並行プログラミング入門&#34; loading=&#34;lazy&#34;&gt;
    &lt;/div&gt;&lt;div class=&#34;blogcard-content&#34;&gt;
      &lt;div class=&#34;blogcard-title&#34;&gt;並行プログラミング入門&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;複数のプログラムを同時に実行する「並行プログラミング」は、処理速度を飛躍的に向上させる手法で、タスク管理、プロセス管理、スレッド管理をはじめ、複雑な仕組みについての幅広い知識とテクニックが必要となります。本書はRustとアセンブリ、そして一部Cを用い、CPUのアトミック命令、グリーンスレッド、アクターモデル、π計算、ソフトウェア・トランザクショナルメモリ、async/awaitなど、並行プログラミングに関する理論的な背景から実装までをカバー。さらに、アセンブリ実装の理解を深めるため、AArch64とx86-64アーキテクチャの説明も付録として収録。一歩一歩、着実に理解できるように、その仕組みから順を追って詳しく説明します。GitHub上で公開されているソースコードを実際に動かしながら、並行プログラミングの知識と理解を深めることができます。&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://www.oreilly.co.jp/books/9784873119595/&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;h2 id=&#34;おまけ&#34;&gt;おまけ&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;The name &amp;ldquo;Tokio&amp;rdquo; is derived from Tokyo and mio, and the Tokio logo vaguely resembles the city emblem of Tokyo.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Tokio_%28software%29&#34; target=&#34;_blank&#34; &gt;https://en.wikipedia.org/wiki/Tokio_(software)&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Rustの非同期ランタイムのtokioの名前の由来の一部は東京らしい。&lt;/p&gt;
&lt;p&gt;あとロゴも東京都の紋章を彷彿とさせるデザインになっているらしい。（実際調べてみたら似ているというかほぼ同じだったw）&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/kyu08/fzf-make&#34; target=&#34;_blank&#34; &gt;fzf-make&lt;/a&gt;というTUIツールを書いている。あとそういえば&lt;a href=&#34;https://github.com/kyu08/sunaba/tree/main/rust/nand2tetris&#34; target=&#34;_blank&#34; &gt;nand2tetris&lt;/a&gt;もRustで書いていた。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;趣味のプログラミングなのでRustを覚え始めた頃は楽しさ優先でまあ動けばOKという気持ちで書いていたが最近になってちゃんと理解したくなってきたので学んでいる。&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;あるいは各種概念を自作するという選択肢もあるかもしれない。Arcとか非同期ランタイムとか&amp;hellip;。&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;他には&lt;a href=&#34;https://www.oreilly.co.jp/books/9784814400515/&#34; target=&#34;_blank&#34; &gt;詳解 Rustアトミック操作とロック&lt;/a&gt;、&lt;a href=&#34;https://www.oreilly.co.jp/books/9784814401185/&#34; target=&#34;_blank&#34; &gt;Async Rust
&lt;/a&gt;、&lt;a href=&#34;https://www.kodansha.co.jp/book/products/0000398182&#34; target=&#34;_blank&#34; &gt;RustによるWebアプリケーション開発　設計からリリース・運用まで
&lt;/a&gt;あたりもとても気になっている。&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</content>
    </item>
    
    <item>
      <title>『つくって、壊して、直して学ぶ Kubernetes入門』を読んだ</title>
      <link>https://blog.kyu08.com/pr-344/posts/bbf_kubernetes/</link>
      <pubDate>Wed, 10 Dec 2025 00:04:41 +0900</pubDate>
      
      <guid>https://blog.kyu08.com/pr-344/posts/bbf_kubernetes/</guid>
      <description>0からKubernetesのキャッチアップがしたくて、高橋 あおいさん著の『つくって、壊して、直して学ぶ Kubernetes入門』を読んだ。 つ</description>
      <content>&lt;p&gt;&lt;img src=&#34;./book.webp&#34; alt=&#34;book&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;0からKubernetesのキャッチアップがしたくて、高橋 あおいさん著の『つくって、壊して、直して学ぶ Kubernetes入門』を読んだ。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://www.shoeisha.co.jp/book/detail/9784798183961&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://www.shoeisha.co.jp/book/detail/9784798183961&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail&#34;&gt;
      &lt;img src=&#34;https://www.shoeisha.co.jp/static/book/og_image/9784798183961.jpg&#34; alt=&#34;つくって、壊して、直して学ぶ Kubernetes入門 | 翔泳社&#34; loading=&#34;lazy&#34;&gt;
    &lt;/div&gt;&lt;div class=&#34;blogcard-content&#34;&gt;
      &lt;div class=&#34;blogcard-title&#34;&gt;つくって、壊して、直して学ぶ Kubernetes入門 | 翔泳社&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;動かなくっても、もう怖くない！

トラブルシューティングを体験しながら学ぶ、実践的入門書。


本書は、Kubernetesの実践的な知識をハンズオン形式で解説する書籍です。本書の特徴は、壊れにくいKubernetesをあえて壊しながら学ぶことで、初心者が挫折しやすいトラブルシューティングの知識や対応力が身に付けられることです。初心者でも、経験者でも、今度こそKubernetesがわかる！
マンガや図解を多く掲載しているため視覚的に理解したい方にもおすすめです。


・つくって、壊して、直して学ぶ
- DockerfileからDockerコンテナをつくる
- Kubernetesクラスタ上にアプリケーションをつくって、壊す
- Serviceを壊す
- kubectlでデバッグする
- OutOfMemoryを発生させて、直す　...



・Kubernetesの構築、運用だけでなくオブザーバビリティも解説
トラブル解決にむけてより多くの情報を得るための「オブザーバビリティ」、そしてトラブルを検知するための「モニタリング」についても説明します。



・豊富なイラストとマンガで見てわかる
章ごと、ハンズオンごとに導入マンガを掲載し、視覚的にも学習内容を理解できるようにしています。むずかしい概念もイラストで丁寧に図解してあります。



Part 1：つくってみようKubernetes
Chapter 1　Dockerコンテナをつくってみる
Chapter 2　Kubernetesクラスタをつくってみる
Chapter 3　全体像の説明
Chapter 4　アプリケーションをKubernetesクラスタ上につくる
Part 2：アプリケーションを壊して学ぶKubernetes
Chapter 5　トラブルシューティングガイドとkubectlコマンドの使い方
Chapter 6　Kubernetes リソースをつくって壊そう
Chapter 7　安全なステートレス・アプリケーションをつくるために
Chapter 8　総復習：アプリケーションを直そう
Part 3：壊れても動くKubernetes
Chapter 9　Kubernetesの仕組み、アーキテクチャーを理解しよう
Chapter 10　Kubernetesの開発ワークフローを理解しよう
Chapter 11　オブザーバビリティとモニタリングに触れてみよう
Chapter 12　この先の歩み方&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://www.shoeisha.co.jp/book/detail/9784798183961&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;h2 id=&#34;そもそものモチベーション&#34;&gt;そもそものモチベーション&lt;/h2&gt;
&lt;p&gt;今年の2月から仕事でKubernetesを使い始めたが、普段はk9sを使ってデプロイが完了したかどうかを確認するくらいでそれ以上高度なことは全然できていなかった。&lt;/p&gt;
&lt;p&gt;そんな状態なのでトラブルシューティングや運用を独力で全然できないことに課題感を感じていた。&lt;/p&gt;
&lt;p&gt;新しい技術を学ぶときは手を動かしながら学ぶのが好きなのでこの本を手に取ってみた。&lt;/p&gt;
&lt;h2 id=&#34;特徴&#34;&gt;特徴&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;本書は、Kubernetesの実践的な知識をハンズオン形式で解説する書籍です。本書の特徴は、壊れにくいKubernetesをあえて壊しながら学ぶことで、初心者が挫折しやすいトラブルシューティングの知識や対応力が身に付けられることです。初心者でも、経験者でも、今度こそKubernetesがわかる！&lt;/p&gt;
&lt;p&gt;マンガや図解を多く掲載しているため視覚的に理解したい方にもおすすめです。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;という書籍説明の通り、ハンズオン形式でKubernetesを学ぶことができる。&lt;/p&gt;
&lt;p&gt;また、&lt;a href=&#34;https://github.com/kubernetes-sigs/kind&#34; target=&#34;_blank&#34; &gt;Kind&lt;/a&gt;というツールを使ってローカルでKubernetesクラスタを構築するのでクラウドの登録や課金を気にする必要がないのも手軽でよかった。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://github.com/kubernetes-sigs/kind&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://github.com/kubernetes-sigs/kind&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail&#34;&gt;
      &lt;img src=&#34;https://opengraph.githubassets.com/e5385189a4eed3dc941cdea81786f9bc35ee61e7d561ac65491e3e21916d3adb/kubernetes-sigs/kind&#34; alt=&#34;GitHub - kubernetes-sigs/kind: Kubernetes IN Docker - local clusters for testing Kubernetes&#34; loading=&#34;lazy&#34;&gt;
    &lt;/div&gt;&lt;div class=&#34;blogcard-content&#34;&gt;
      &lt;div class=&#34;blogcard-title&#34;&gt;GitHub - kubernetes-sigs/kind: Kubernetes IN Docker - local clusters for testing Kubernetes&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;Kubernetes IN Docker - local clusters for testing Kubernetes - kubernetes-sigs/kind&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://github.com/kubernetes-sigs/kind&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;1つ1つの解説はそこまで文量がないので結構サクサク進めることができる。なので本書でKubernetesの全体感を本書で学び、深く学ぶのは別のリソースで補うのがよさそうだと感じた。&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;誤解のないように書いておくと、自分のようなKubernetes初心者にとっては各リソースの説明の文量が多すぎないお陰で短期間で全体感を把握できてとてもよかった。(気になったところは別途公式ドキュメントやLLMを使って深堀ったりした)&lt;/p&gt;
&lt;p&gt;こんな雰囲気。漫画があって文量も多すぎず読みやすい。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;manga.webp&#34; alt=&#34;manga.webp&#34; loading=&#34;lazy&#34; /&gt;
&lt;a href=&#34;https://www.shoeisha.co.jp/book/detail/9784798183961&#34; target=&#34;_blank&#34; &gt;商品ページ&lt;/a&gt;より引用&lt;/p&gt;
&lt;p&gt;以下の画像のように実行すべきコマンドとその結果がどうなるかが書いてあるのでKubernetesの経験が少なくても進めやすい。（実際自分もほぼ知識0で臨んだ）&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;command.webp&#34; alt=&#34;command.webp&#34; loading=&#34;lazy&#34; /&gt;
&lt;a href=&#34;https://www.shoeisha.co.jp/book/detail/9784798183961&#34; target=&#34;_blank&#34; &gt;商品ページ&lt;/a&gt;より引用&lt;/p&gt;
&lt;p&gt;こんな感じでk9sを常時起動しながらコマンドを実行するスタイルで進めたところリアルタイムでPodの変化が見れて理解が捗った。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;k9s.webp&#34; alt=&#34;k9s.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://github.com/derailed/k9s/&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://github.com/derailed/k9s/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail&#34;&gt;
      &lt;img src=&#34;https://repository-images.githubusercontent.com/167596393/6dd20780-5c0e-11ea-8e26-7754ad171192&#34; alt=&#34;GitHub - derailed/k9s: 🐶 Kubernetes CLI To Manage Your Clusters In Style!&#34; loading=&#34;lazy&#34;&gt;
    &lt;/div&gt;&lt;div class=&#34;blogcard-content&#34;&gt;
      &lt;div class=&#34;blogcard-title&#34;&gt;GitHub - derailed/k9s: 🐶 Kubernetes CLI To Manage Your Clusters In Style!&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;🐶 Kubernetes CLI To Manage Your Clusters In Style! - derailed/k9s&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://github.com/derailed/k9s/&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;h2 id=&#34;学び&#34;&gt;学び&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;kubectlの使い方&lt;/li&gt;
&lt;li&gt;Pod、Service、Deploymentなどの基本的なリソースの性質や動かし方&lt;/li&gt;
&lt;li&gt;Readiness probe, Liveness probe, Startup probeの特徴や使い方&lt;/li&gt;
&lt;li&gt;Resource Requests/Limits, HPA, Affinity, HPA, VPAなどの性能やスケールなどに関する機能の使い方&lt;/li&gt;
&lt;li&gt;Kubernetes自体のアーキテクチャ&lt;/li&gt;
&lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;感想&#34;&gt;感想&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;0からKubernetesの基礎を学ぶことができてとても良い本だった。&lt;/li&gt;
&lt;li&gt;ちょうど仕事でmanifestを書くタイミングがあったので本書で学んだことがダイレクトに活きてとても助かった。物事の解像度が上がるのはいつだって楽しいな〜と再確認した。&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;次はしばらく積んでしまっていた&lt;a href=&#34;https://www.sbcr.jp/product/4815618599/&#34; target=&#34;_blank&#34; &gt;『体験しながら学ぶ ネットワーク技術入門』&lt;/a&gt;をやっていく。&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;本書後半でも紹介されているが本で詳しく学ぶなら&lt;a href=&#34;https://book.impress.co.jp/books/1119101148&#34; target=&#34;_blank&#34; &gt;Kubernetes完全ガイド 第2版&lt;/a&gt;がいいらしい。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;たとえばリクエストが全然きてないマイクロサービスのPod数が一瞬2倍になっているグラフをみて、&lt;code&gt;maxSurge: 100%&lt;/code&gt;でRollingUpdateしてるな〜と思えたりとか。&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</content>
    </item>
    
    <item>
      <title>『デッドライン』を読んだ</title>
      <link>https://blog.kyu08.com/pr-344/posts/the-deadline/</link>
      <pubDate>Sun, 23 Nov 2025 10:43:53 +0900</pubDate>
      
      <guid>https://blog.kyu08.com/pr-344/posts/the-deadline/</guid>
      <description>少し前にTwitterで紹介されていて気になっていた1トム デマルコの『デッドライン』を読んだ。新品で売ってるところが見つからなかったのでAm</description>
      <content>&lt;p&gt;&lt;img src=&#34;the-deadline.webp&#34; alt=&#34;the-deadline.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;少し前にTwitterで紹介されていて気になっていた&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;トム デマルコの『デッドライン』を読んだ。新品で売ってるところが見つからなかったのでAmazonで中古を購入した。&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;プロジェクトマネジメントをするたびにその難しさを痛感しているので知見が得られたり思考が整理できたりすることを期待して読んだ。&lt;/p&gt;
&lt;p&gt;同著者の本だと『ピープルウエア』が有名だがそちらは未読。『ゆとりの法則』とかも面白そうなのでいつか読みたい。&lt;/p&gt;
&lt;p&gt;というわけで参考になったところを紹介していく。（なお&lt;code&gt;(P84)&lt;/code&gt;のような数字はページ数を示す。）&lt;/p&gt;
&lt;h2 id=&#34;生産性の向上p84&#34;&gt;生産性の向上(P84)&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;短期的に生産性を高める方法などない。生産性は、長期的な投資によって向上する。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;（本筋ではないが）まずこれを読んだときに手作業の自動化のためのCI/CDを整備したら短期的に生産性はあがるのでは？と思った。&lt;/p&gt;
&lt;p&gt;が、ここでの生産性は「期間あたりのアウトプット」のことを指していて、「期間あたりのアウトカム」を指しているわけではないのかもしれないと解釈してひとまず納得した。（そもそもそんなに細かい話はしていない、またはCI/CDのような比較的すぐにできて明らかに生産性に寄与する施策はすでに実施済み、という前提はあるのかもしれない。）&lt;/p&gt;
&lt;p&gt;なので「生産性を大きく向上させるためには長期的な投資が重要なことが多い」くらいに捉えてみる。&lt;/p&gt;
&lt;p&gt;たしかに長期目線でチームの生産性を大きく向上させるにはチームとしての練度を向上させたり、リアーキテクティングをはじめとした技術的負債を解消したり、スキルアップを図ったりといったことが必要になることが多いように思うのでその意味では同意できる文だった。&lt;/p&gt;
&lt;p&gt;スタートアップではリソースが限られる中で短期的にマストでやらなければいけないことをこなす必要があったりするので長期的な施策への投資バランスが本当に難しい。（とはいえ少しでも時間を見つけて長期的な施策を少しずつでも進めていくしかないか）&lt;/p&gt;
&lt;h2 id=&#34;リスク管理p84&#34;&gt;リスク管理(P84)&lt;/h2&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;リスクを管理することによってプロジェクトを管理せよ。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;それぞれのリスクの実現する確率と予想コストを評価せよ&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;プロジェクトマネジメントをしていると「どう不確実性を取り扱うか」というのが難しく、かつ一番重要度が高いように感じる。&lt;/p&gt;
&lt;p&gt;プロジェクト（以下PJと表記）を進めていると様々な不確実性によってスケジュール遅延が発生し、品質が落ちたり、計画を変更してPJ期間を延ばしたり、スコープを削ったり、あるいは人員を追加したりというアクションが必要になる。（場合によっては残業が増えたりもする）&lt;/p&gt;
&lt;p&gt;そして何より、当初の見積もりを超過するとエンジニア当人が感じるプレッシャーが増えたりモチベーションが下がったりする。（自分だけかもしれないが）&lt;/p&gt;
&lt;p&gt;なので可能な限り見積もりからのズレを減らしたくなる。（見積もりのズレが減って悲しい人はいないはず）&lt;/p&gt;
&lt;p&gt;今のところは可能な限り見積もりからのズレを減らすためにはこのあたりのことを意識してみている。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;見積もりがズレたらその原因を分析して次回以降に活かす&lt;/li&gt;
&lt;li&gt;そもそも見積もりという行為自体が不確実性をはらんでいることを理解する&lt;/li&gt;
&lt;li&gt;不確実性を早期に削減することでPJ後半に手戻りや遅延が発生する確率を下げる&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;code&gt;1.&lt;/code&gt;に関しては組織、人によってまちまちだと思うが最近自分が発見したズレの要因はこのあたり。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;（プロマネと実装を兼任する場合に）プロマネタスクのための時間を確保し忘れていた&lt;/li&gt;
&lt;li&gt;設計をチームに共有するための資料等の準備時間やレビュワーからもらったフィードバックを反映する時間を見積もりに含めていなかった&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;特にプロマネと実装者を兼務している場合、状況が変わった際のスケジュールの組み直し、タスク実行順をどうするかの検討、ステークホルダーへの報告や相談などのプロマネタスクに意外と時間がかかることを直近のPJで学んだ。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;2.&lt;/code&gt;への対策としては2点見積もり、3点見積もりのような手法を用いたり、見積もりをレンジで表現したりすることが考えられそう。（e.g. 「7月1日にリリースできそうです」と伝えるのではなく「7月前半にリリースできそうです」のように範囲で伝える。）&lt;/p&gt;
&lt;p&gt;PJが進むに連れて不確実性が下がっていき、見積もりの精度も上がっていくはずなので徐々にレンジも狭くなっていくはず。なのでステークホルダーに一度伝えて終わり、というよりはチェックポイントごとに最新の見積もりを伝えるのが良さそうに思う。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;3.&lt;/code&gt;については不確実性コーンに従って不確実性が下がっていくようにPJ初期の要件定義や設計の段階で大きな不確実性を潰しておくことが重要そう。&lt;/p&gt;
&lt;h2 id=&#34;人材管理の智将p94&#34;&gt;人材管理の智将(P94)&lt;/h2&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;プロジェクトの初期にむだにする一日も、末期にむだにする一日も等しく打撃になる。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;一日をむだにする方法はいくらでもある…しかし、一日を取り戻す方法は一つもない。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;真理みがある。真理過ぎてあまり書くことがない。&lt;/p&gt;
&lt;p&gt;これを見て小学校のころのサッカーのコーチの「そのリフティングの1回はもう帰ってこないよ（だから集中して取り組もう）」という言葉を思い出した。&lt;/p&gt;
&lt;h2 id=&#34;プレッシャーの効果p200&#34;&gt;プレッシャーの効果(P200)&lt;/h2&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;プレッシャーをかけても思考は速くならない。&lt;/li&gt;
&lt;li&gt;一時的なプレッシャーや残業は、人びとの焦点を定め、その仕事が重要であるという認識を高めるには有効な方法かもしれないが、プレッシャーをかけすぎると、かならず失敗する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;自分もプレッシャーが大きすぎるとパフォーマンスが落ちるタイプなのでとてもわかりみがあった。&lt;/p&gt;
&lt;p&gt;振り返ってみると特に明示的でないプレッシャーがあるとパフォーマンスが落ちやすい気がした。「xx月yy日までにリリースしたい」のようなものではなく「なんか上司から圧を感じる。今のままだとダメな気がする&amp;hellip;」みたいな状態。要求（の理解）が明瞭ではないので目標が定まらず、辛い感じになりがち。（今思えば上司とコミュニケーションをとって明確にするのがよさそうではある）&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;残業時間を増やすのは、生産性を落とす方法である。&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;残業が常態化し「あとで残業すればいっか〜」というマインドになってしまうと結局日中の生産性は落ちてしまい無駄が増えてしまうので気をつけたい。&lt;/p&gt;
&lt;p&gt;一方で昼夜問わず猛烈にコミットして成果を出しまくっている人も身の回りに複数いるので必ずしも残業が悪とまではいえない気持ちにもなっている。（あくまで今の自分がそう感じるというだけ人/時期によっては残業しないことの重要度が高まることは普通にあるとは思う）&lt;/p&gt;
&lt;p&gt;そういえば残業の話は『世界一流エンジニアの思考法』にも書いてあったなーと思い出した。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;ここでの示唆は、業務だけに自分の時間を使ってしまうと&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;学習によって自分の生産性を向上させることがしずらい&lt;/li&gt;
&lt;li&gt;残業前提で成果を出すため再現性が低い&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ということだと思う。残業しすぎないことで学習の時間を確保したり、開発プロセスの改善やスコープの調整によってうまく成果を出せるようにできていることが重要なのだと思う。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.kyu08.com/posts/how-world-class-engineers-think/#%E3%82%BF%E3%82%A4%E3%83%A0%E3%83%9C%E3%83%83%E3%82%AF%E3%82%B9%E5%88%B6&#34; target=&#34;_blank&#34; &gt;https://blog.kyu08.com/posts/how-world-class-engineers-think/#%E3%82%BF%E3%82%A4%E3%83%A0%E3%83%9C%E3%83%83%E3%82%AF%E3%82%B9%E5%88%B6&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;スタッフの人数p259&#34;&gt;スタッフの人数(P259)&lt;/h2&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;初期に人数が多すぎると、プロジェクトは重要な設計作業を省略せざるをえない（全員に仕事を与えるため）。設計が完成する前に大勢に仕事を割り当てると、人や作業グループの間のインタフェースを最小化できない。&lt;/li&gt;
&lt;li&gt;このため、相互依存性が高まり、会議が増え、やり直しが増え、フラストレーションがたまる。&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;チームの人数が多すぎる場合、設計段階で全員にタスクをふろうとすると対象ソフトウェアへの理解が不十分な段階で人為的にソフトウェアを部分に切り分けて担当をアサインすることになる。&lt;/p&gt;
&lt;p&gt;そのため人と人とのインターフェースが無駄に複雑化してしまい、コミュニケーションコストが増大する、ということを言っていると理解した。&lt;/p&gt;
&lt;p&gt;そのため設計段階までは少人数で進めてタスクを切り分けられる段階まできたら人数も増やしてもよいのではないか、ということが書かれていた。&lt;/p&gt;
&lt;p&gt;ここで得られる示唆としては&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;対象ソフトウェアへの理解が曖昧な状態では正しく切り分けることができない（マイクロサービス化にもいえそう）&lt;/li&gt;
&lt;li&gt;チームの人数をいたずらに増やすべきではない&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;というようなことかなと思った。（生産性以外にも様々な事情があるケースもあるとは思うので一概には言えないが）&lt;/p&gt;
&lt;h2 id=&#34;まとめ&#34;&gt;まとめ&lt;/h2&gt;
&lt;p&gt;プロジェクトマネジメントについていろいろと示唆を得られてよかった。&lt;/p&gt;
&lt;p&gt;物語調だったので隙間時間にサクサク読みやすかった。&lt;/p&gt;
&lt;p&gt;数冊の積読があるので年内に消化できるようにやっていきたい&amp;hellip;。（k8s本&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;とかネットワークの本&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;とか）&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://x.com/voluntas/status/1957427884848820578&#34; target=&#34;_blank&#34; &gt;https://x.com/voluntas/status/1957427884848820578&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;ここ数年は物理本派でやらせてもらっているので&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://www.shoeisha.co.jp/book/detail/9784798183961&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://www.shoeisha.co.jp/book/detail/9784798183961&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail&#34;&gt;
      &lt;img src=&#34;https://www.shoeisha.co.jp/static/book/og_image/9784798183961.jpg&#34; alt=&#34;つくって、壊して、直して学ぶ Kubernetes入門 | 翔泳社&#34; loading=&#34;lazy&#34;&gt;
    &lt;/div&gt;&lt;div class=&#34;blogcard-content&#34;&gt;
      &lt;div class=&#34;blogcard-title&#34;&gt;つくって、壊して、直して学ぶ Kubernetes入門 | 翔泳社&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;動かなくっても、もう怖くない！

トラブルシューティングを体験しながら学ぶ、実践的入門書。


本書は、Kubernetesの実践的な知識をハンズオン形式で解説する書籍です。本書の特徴は、壊れにくいKubernetesをあえて壊しながら学ぶことで、初心者が挫折しやすいトラブルシューティングの知識や対応力が身に付けられることです。初心者でも、経験者でも、今度こそKubernetesがわかる！
マンガや図解を多く掲載しているため視覚的に理解したい方にもおすすめです。


・つくって、壊して、直して学ぶ
- DockerfileからDockerコンテナをつくる
- Kubernetesクラスタ上にアプリケーションをつくって、壊す
- Serviceを壊す
- kubectlでデバッグする
- OutOfMemoryを発生させて、直す　...



・Kubernetesの構築、運用だけでなくオブザーバビリティも解説
トラブル解決にむけてより多くの情報を得るための「オブザーバビリティ」、そしてトラブルを検知するための「モニタリング」についても説明します。



・豊富なイラストとマンガで見てわかる
章ごと、ハンズオンごとに導入マンガを掲載し、視覚的にも学習内容を理解できるようにしています。むずかしい概念もイラストで丁寧に図解してあります。



Part 1：つくってみようKubernetes
Chapter 1　Dockerコンテナをつくってみる
Chapter 2　Kubernetesクラスタをつくってみる
Chapter 3　全体像の説明
Chapter 4　アプリケーションをKubernetesクラスタ上につくる
Part 2：アプリケーションを壊して学ぶKubernetes
Chapter 5　トラブルシューティングガイドとkubectlコマンドの使い方
Chapter 6　Kubernetes リソースをつくって壊そう
Chapter 7　安全なステートレス・アプリケーションをつくるために
Chapter 8　総復習：アプリケーションを直そう
Part 3：壊れても動くKubernetes
Chapter 9　Kubernetesの仕組み、アーキテクチャーを理解しよう
Chapter 10　Kubernetesの開発ワークフローを理解しよう
Chapter 11　オブザーバビリティとモニタリングに触れてみよう
Chapter 12　この先の歩み方&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://www.shoeisha.co.jp/book/detail/9784798183961&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://www.sbcr.jp/product/4815618599/&#34; target=&#34;_blank&#34; &gt;https://www.sbcr.jp/product/4815618599/&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</content>
    </item>
    
    <item>
      <title>『Tidy First?』を読んだ</title>
      <link>https://blog.kyu08.com/pr-344/posts/tidy-first/</link>
      <pubDate>Sat, 04 Oct 2025 08:21:10 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/pr-344/posts/tidy-first/</guid>
      <description>『Tidy First?』を読んだ。 勉強になったところをまとめる。 「整頓」という概念 整頓はリファクタリングのサブセットだ。整頓は可愛くてふわふ</description>
      <content>&lt;p&gt;『&lt;a href=&#34;https://www.oreilly.co.jp/books/9784814400911/&#34; target=&#34;_blank&#34; &gt;Tidy First?&lt;/a&gt;』を読んだ。&lt;/p&gt;
&lt;p&gt;勉強になったところをまとめる。&lt;/p&gt;
&lt;h2 id=&#34;整頓という概念&#34;&gt;「整頓」という概念&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;整頓はリファクタリングのサブセットだ。整頓は可愛くてふわふわした小さなリファクタリングなので、誰も嫌いになれないはずだ。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;リファクタリングほど大掛かりなものではなく、数十分でできるような小さな改善を本書では「整頓」と呼んでいる。&lt;/p&gt;
&lt;p&gt;具体的にはコードコメントを追加したり適切な位置に空行を配置したり適切な変数名に変更したりすることなどを指している。&lt;/p&gt;
&lt;p&gt;この「整頓」という概念を知ることができたのが本書を読んで得られた最大の収穫だった。今までそのような行為に名前をつけたことがなかったが名前をつけることで使い所や意義が明確になり意識的に実践できるようになりそう。&lt;/p&gt;
&lt;p&gt;なお本書では「整頓」と「振る舞いの変更」の順番やタイミング、粒度や意義について様々な角度から書かれているので気になる方はぜひ手にとってみてほしい。&lt;/p&gt;
&lt;h2 id=&#34;第11章-ステートメントを小分けにする&#34;&gt;第11章 ステートメントを小分けにする&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;大きなコードのチャンクを読んでいると、「ああ、ここは&lt;strong&gt;これ&lt;/strong&gt;をしていて、あそこで&lt;strong&gt;あれ&lt;/strong&gt;をしているのか」とわかる。そのあいだに空行を入れよう。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;長めの関数を読むとき、空行がまったくないことは少ないが空行の位置を改善できそうだと感じることがたまにある。&lt;/p&gt;
&lt;p&gt;処理の塊ごとに適切に改行されているだけでそこそこ可読性が上がる実感があるのでやってみようと思う。（空行の追加/削除のみのPRであればレビュワーの負担もかなり少ないはず）&lt;/p&gt;
&lt;h2 id=&#34;第13章-ひとかたまり&#34;&gt;第13章 ひとかたまり&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;細かく分割されているがゆえに、かえって理解を妨げているようなコードに出会うことはないだろうか。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;超巨大な関数はテストしづらく可読性も低いので避けたいが、逆にすべての処理を関数として切り出してしまうと毎回定義ジャンプしないと処理の内容がわからないのでかえって読みづらくなってしまう。&lt;/p&gt;
&lt;p&gt;テストが書きやすい程度に細かくかつ可読性が落ちない程度には大きく関数を切り出すのがよさそうで、いい塩梅を探るには複数のパターンを実際に書いてみて読みやすいかどうかを判断するのがよさそう。（実際に複数パターンを書いてみると意外とすぐに書けることが多いし、しかも実際に書いてみると事前の想定とは印象が違うことが多いように思う）&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;小さな部品に分けようとするのは、コードを少しずつ理解できるようにしたいからだ。だが、ときには、このプロセスが間違った方向に進むことがある。小さな部品のやりとりの仕方によっては、コードが&lt;strong&gt;理解しにくくなる&lt;/strong&gt;のだ。明確さを取り戻すには、まずはコードを1箇所に集めて、それから改めて、簡単に理解できる部品を抽出する。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;1000行の関数でこれをやるとさすがに辛そうだが、100行前後くらいであればひとまず1つにまとめてから再構成するのはたしかに良さそう。&lt;/p&gt;
&lt;h2 id=&#34;第14章-説明コメント&#34;&gt;第14章 説明コメント&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;コードを読んでいて「なるほど、それで&lt;strong&gt;こう&lt;/strong&gt;なっているのか」と声が出ることがある。これは貴重な瞬間だ。記録しよう。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;コードリーディングの結果、必要なコメントが欠けていることに気づくことがある。&lt;/p&gt;
&lt;p&gt;そういった場面でこれまであまりPRを作ったりはしてこなかったが、説明コメントの追加も立派な整頓であり将来の読者（当然将来の自分を含む）の時間を節約することに繋がるのでやっていきたい。&lt;/p&gt;
&lt;p&gt;説明コメントの追加PRはレビュワーの負荷が少ない割にレビュイーとレビュワーのコード理解を深められる点で比較的コスパの良い取り組みな気がした。（正確な説明コメントを書くための調査が大変、とかはあるかもだが）&lt;/p&gt;
&lt;h2 id=&#34;第19章-リズム&#34;&gt;第19章 リズム&lt;/h2&gt;
&lt;p&gt;1つの整頓にかける時間はここでは1時間くらいまでが許容範囲とされており、それを大幅に超過するようであれば変更の単位が大きすぎる兆候らしい。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;こんな話を聞いたことはないだろうか。ある大学がたくさんの建物を造った。計画者は、それを結ぶ歩道をどこに造るか考えていた。だが、そこで経験にもとづいて注意深く推測するのではなく、建物のあいだのエリアに芝生を植えたのだ。
数か月後、学生の歩いた跡によって芝生に道ができた。計画者は芝生がなくなったところを舗装した。&lt;/p&gt;
&lt;p&gt;コードにおいて、振る舞いの変更は一部に集中する傾向にある。パレートの法則にあるように、80%の変更は20%のファイルで起こる。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;（計画者天才すぎワロタ&amp;hellip;）&lt;/p&gt;
&lt;p&gt;変更の前に整頓することを続けていくと頻繁に変更される20%のコードがどんどん綺麗になっていく、ということを言っているのだと解釈した。&lt;/p&gt;
&lt;p&gt;そうした取り組みを続けていくとコードの大部分は手直ししてないにもかかわらず整頓していないコードに出会うことは稀になる。逆に言うと仮にコードの50%を頑張って綺麗にしたところで、その50%に変更がまったく入らないのであれば投資対効果が高いとはいえないかもしれない。（当然、コード全体が複雑に絡み合っていて一部だけ再設計することが難しい場合や全体的に変更しないと一貫性がなくなる場合などはその限りではないと思う）&lt;/p&gt;
&lt;p&gt;なのでコードを修正する際は単純にある時点のコードベースだけを見てコード品質に改善点が見つかったというだけの理由で修正する、というよりは修正すべき合理的な理由（e.g. 内部品質が課題で問題が起きている、よく変更が入る箇所が変更しづらくなっているなど）がある箇所から対応していくのがよさそう。&lt;/p&gt;
&lt;h2 id=&#34;第21章-先に整頓あとに整頓改めて整頓整頓しない&#34;&gt;第21章 先に整頓、あとに整頓、改めて整頓、整頓しない&lt;/h2&gt;
&lt;p&gt;整頓を変更の前にやるか、あとにやるか、将来時間がとれたときにやるか、あるいはまったくやらないかについて論じた章。&lt;/p&gt;
&lt;p&gt;章のまとめにもあるように結局はビジネスにとって合理的なタイミングでやるのがよい、ということなのだと思った。（言葉にするとそれはそうという感じではあるが）&lt;/p&gt;
&lt;p&gt;「改めて整頓する」と「あとに整頓する」の区別はあまり考えたことがなかったが、整頓が完了するまでの必要工数が
大きいケース以外は「あとに整頓する」に寄せるのが良さそうに感じた。&lt;/p&gt;
&lt;h2 id=&#34;第25章-明日の1ドルより今日の1ドル&#34;&gt;第25章 明日の1ドルより今日の1ドル&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;お金を生む振る舞いの変更を今すぐ実装して、あとから整頓できるなら、すぐにお金が手に入り、あとでお金を使うことになる(前述のとおり、ときには先に整頓してから振る舞いを変更するほうが整頓せずに変更するよりも安価なこともある。そんな場合は常に先に整頓する)。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;ビジネス的なメリットがあるならば整頓を後回しにすることが合理的になるのは十分にありえる。(e.g. 12/1までにリリースできれば大企業A社の受注に繋がるが、それを超過してしまうと競合他社と契約されてしまい、A社と契約できるチャンスが消滅してしまう)&lt;/p&gt;
&lt;p&gt;逆に、先に整頓したほうが変更が楽になるならそうする。コードベースへの理解、ビジネスへの関心と理解（デッドラインは最終的なものなのか、調整可能なのか）、一定の設計スキルなどがあるとこの判断の練度を上げることに繋がりそう。&lt;/p&gt;
&lt;!-- 逆に、先に整頓したほうが変更が楽になるならそうする。じゃあメリデメを整理していい感じに判断すればいいじゃん、という話になるがこの判断を正確にするためにはコードベースへの理解、ビジネスへの関心と理解（デッドラインは最終的なものなのか、調整可能なのか）、一定の設計スキルなどが必要そう。 --&gt;
&lt;h2 id=&#34;第26章-オプション&#34;&gt;第26章 オプション&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;「次にどのような振る舞いを実装できるか」は、実装する前から、それ自体に価値がある。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;これはあまり考えたことがなかった。「プログラムの変更容易性は将来の実装工数を削減するために重要である」というアイディアと本質的には近いことを言ってそうだが、「価値」という切り口で捉え直すとたしかに変更容易性は価値と等価ともいえそう。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;（これが最重要なのだが）価値予測の不確実性が&lt;strong&gt;高い&lt;/strong&gt;ほど、オプションの価値は&lt;strong&gt;高い&lt;/strong&gt;（今すぐ実装するのと比べて）。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;価値予測の不確実性と変更容易性の価値についてもあまり考えたことがなかったが納得感があった。たとえばよくあるSaaSモデルのプロダクトであれば探索しながら市場の反応を見たり変化に対応したりすることが必要で、そのためには変更容易性が必要なのでその価値がより高まる、ということだと理解した。&lt;/p&gt;
&lt;h2 id=&#34;第32章-凝集&#34;&gt;第32章 凝集&lt;/h2&gt;
&lt;p&gt;凝集性が低いモジュールの改善方法についての章だが、どちらかというと章の後半に書かれていた下記の記述が参考になった。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;次の人のために少しだけコードを整頓しておこう。全員がこのボーイスカウトルール(「来たときよりも美しく」)に従えば、そのうちにより扱いやすいコードになっていくだろう。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;これまではボーイスカウトルールというと「触ったコードの負債をできるだけ&lt;strong&gt;リファクタリングして綺麗にすべし&lt;/strong&gt;」のような考え方だと認識していた（これ自体は間違いではないと思う）。&lt;/p&gt;
&lt;p&gt;本格的なリファクタリングまではいかなくとも、本書で「整頓」として紹介されている「コードコメントの追加」や「空行の調整」なども十分ボーイスカウト的な行為なのだなと考え直して少しハードルが下がる感覚を得た。&lt;/p&gt;
&lt;h2 id=&#34;第33章-結論&#34;&gt;第33章 結論&lt;/h2&gt;
&lt;p&gt;本書のタイトルにもなっている、どんなときに先に整頓すべきかについてのまとめの章。&lt;/p&gt;
&lt;p&gt;以下の4つの観点で整理して決断するとよい、と書かれている。次に判断に迷った際には参考にしてみたい。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;コスト&lt;/li&gt;
&lt;li&gt;収益&lt;/li&gt;
&lt;li&gt;結合&lt;/li&gt;
&lt;li&gt;凝集&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- &gt; だが、いちばん重要なのはあなただ。整頓はあなたのプログラミングに平穏と満足、喜びをもたらしてくれるだろうか? 多少はありそうだ。これは重要だ。なぜなら、あなたが最高の自分でいれば、より良いプログラマーでいられるからだ。いつも急いでいて、変更に痛みを伴うコードの変更をしているなら、最高の自分ではいられない。 --&gt;
&lt;!----&gt;
&lt;!-- この部分に関してはちょっと諸説ありそうだと思った。 --&gt;
&lt;!----&gt;
&lt;!-- プログラマ的にはクリーンなコードを書いたり、コードをクリーンにする作業自体が楽しかったり、そこから学びを得ることができるというのは当然理解できる。 --&gt;
&lt;!----&gt;
&lt;!-- ただ業務であまりそこを重視しすぎるとビジネス的な都合を無視する考えに繋がるのでは...と思った。（著者はそこまで言ってないかもだが）一般的にはビジネスがうまくいかないと売上が上がらないことに起因してモチベーションが下がったり報酬が思ったように上がらなかったり、働く環境が悪化したりすることもあるため難しい。 --&gt;
&lt;!----&gt;
&lt;!-- いちメンバーの視点だとビジネス都合とソフトウェアの状況を勘案して総合的に判断するのがよさそうな気がした。 --&gt;
&lt;!----&gt;
&lt;!-- マネジメント側の立場だとメンバーのパフォーマンスを高めることも重要な責務なのでうまくバランスを取るのが重要そう。 --&gt;
&lt;h2 id=&#34;まとめ&#34;&gt;まとめ&lt;/h2&gt;
&lt;p&gt;164ページと全体がコンパクトにまとまっているのと、簡潔に書かれている（かつ、翻訳もとても読みやすい）ので短時間で読みやすかった。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;「整頓」&lt;/strong&gt; という概念を知れたのが最大の収穫だった。今後は意識的に実践していきたいと思う。&lt;/p&gt;
&lt;p&gt;次回作の構想もあるようなので楽しみ。&lt;/p&gt;
</content>
    </item>
    
    <item>
      <title>『コンピュータシステムの理論と実装 第2版』を読んだ</title>
      <link>https://blog.kyu08.com/pr-344/posts/nand2tetris/</link>
      <pubDate>Tue, 29 Apr 2025 15:00:00 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/pr-344/posts/nand2tetris/</guid>
      <description>『コンピュータシステムの理論と実装 第2版』を読んだので感想を書く。割と長いので得られた学びだけ読みたい方は## 学び、得た経験までジャンプして</description>
      <content>&lt;p&gt;&lt;img src=&#34;./book.webp&#34; alt=&#34;book&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;『コンピュータシステムの理論と実装 第2版』を読んだので感想を書く。割と長いので得られた学びだけ読みたい方は&lt;a href=&#34;#%e5%ad%a6%e3%81%b3%e5%be%97%e3%81%9f%e7%b5%8c%e9%a8%93&#34; &gt;## 学び、得た経験&lt;/a&gt;までジャンプしてください。&lt;/p&gt;
&lt;h2 id=&#34;本書の構成&#34;&gt;本書の構成&lt;/h2&gt;
&lt;p&gt;本書はnand2tetrisという通称の通り、NANDゲートからスタートして、CPUやコンパイラやOSなどを実装し、最終的にはそのプラットフォーム上でテトリス(のようなアプリケーション)&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;が動くところまで実装するという内容のコースになっている。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;roadmap.webp&#34; alt=&#34;roadmap&#34; loading=&#34;lazy&#34; /&gt;
&lt;div class=&#34;blogcard&#34; data-url=&#34;https://drive.google.com/file/d/1BPmhMLu_4QTcte0I5bK4QBHI8SACnQSt/view&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://drive.google.com/file/d/1BPmhMLu_4QTcte0I5bK4QBHI8SACnQSt/view&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail blogcard-thumbnail-placeholder&#34;&gt;
      &lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 24 24&#34; fill=&#34;none&#34; stroke=&#34;currentColor&#34; stroke-width=&#34;2&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;&gt;
        &lt;path d=&#34;M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71&#34;&gt;&lt;/path&gt;
        &lt;path d=&#34;M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71&#34;&gt;&lt;/path&gt;
      &lt;/svg&gt;
    &lt;/div&gt;&lt;div class=&#34;blogcard-content&#34;&gt;
      &lt;div class=&#34;blogcard-title&#34;&gt;lecture 7.pdf&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://drive.google.com/file/d/1BPmhMLu_4QTcte0I5bK4QBHI8SACnQSt/view&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
 P3より引用&lt;/p&gt;
&lt;p&gt;上図のとおりだが、大まかな流れとしては以下。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;NANDゲートを使ってnot, and, orなどの基本的なチップを実装&lt;/li&gt;
&lt;li&gt;加算機やALUを実装&lt;/li&gt;
&lt;li&gt;レジスタ、RAM、Program Counterを実装&lt;/li&gt;
&lt;li&gt;Memory、CPU、Computerを実装&lt;/li&gt;
&lt;li&gt;アセンブラを実装(機械語の記号表現をバイナリ表現に変換する)&lt;/li&gt;
&lt;li&gt;仮想マシンを実装&lt;/li&gt;
&lt;li&gt;コンパイラを実装&lt;/li&gt;
&lt;li&gt;OSを実装&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;各章末に課題とそれをパスしたことを確認するテストがある。基本的にはテストコードを使って動作確認ができるようになっているため、自分の実装が合ってるかを機械的に確認できるようになっており、手を動かしながら理解を深めやすいようになっている。&lt;/p&gt;
&lt;p&gt;参考までに各章の実装に用いる言語を記しておく。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;章&lt;/th&gt;
&lt;th&gt;実装言語&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;第1章 ブール論理&lt;/td&gt;
&lt;td&gt;HDL(Hardware Description Languageの略で論理回路の構造を記述できる言語)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;第2章 ブール算術&lt;/td&gt;
&lt;td&gt;HDL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;第3章 メモリ&lt;/td&gt;
&lt;td&gt;HDL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;第4章 機械語&lt;/td&gt;
&lt;td&gt;アセンブリ言語(Hackプラットフォーム独自の仕様)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;第5章 コンピュータアーキテクチャ&lt;/td&gt;
&lt;td&gt;HDL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;第6章 アセンブラ&lt;/td&gt;
&lt;td&gt;任意の言語&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;第7章 仮想マシンI：処理&lt;/td&gt;
&lt;td&gt;任意の言語&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;第8章 仮想マシンII：制御&lt;/td&gt;
&lt;td&gt;任意の言語&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;第9章 高水準言語&lt;/td&gt;
&lt;td&gt;Jack言語(本書で実装するJavaライクな独自言語)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;第10章 コンパイラI：構文解析&lt;/td&gt;
&lt;td&gt;任意の言語&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;第11章 コンパイラII：コード生成&lt;/td&gt;
&lt;td&gt;任意の言語&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;第12章 OS&lt;/td&gt;
&lt;td&gt;Jack言語&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;第6章 ~ 第8章と第10章 ~ 第11章は決められた入出力を持つCLIツールを書けばいいので任意の言語で書くことができる。筆者はRustで実装した。特にEnumとパターンマッチのおかげで構文解析関連の処理が書きやすかった。&lt;/p&gt;
&lt;p&gt;ここからは各章の学びを簡単に書いていく。&lt;/p&gt;
&lt;h2 id=&#34;第1章-ブール論理&#34;&gt;第1章 ブール論理&lt;/h2&gt;
&lt;p&gt;NANDを使って以下の論理回路をHDLを使って実装した。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;not&lt;/li&gt;
&lt;li&gt;and&lt;/li&gt;
&lt;li&gt;or&lt;/li&gt;
&lt;li&gt;xor&lt;/li&gt;
&lt;li&gt;マルチプレクサ&lt;/li&gt;
&lt;li&gt;デマルチプレクサ&lt;/li&gt;
&lt;li&gt;not(16bit)&lt;/li&gt;
&lt;li&gt;and(16bit)&lt;/li&gt;
&lt;li&gt;or(16bit)&lt;/li&gt;
&lt;li&gt;マルチプレクサ(16bit)&lt;/li&gt;
&lt;li&gt;8入力or&lt;/li&gt;
&lt;li&gt;4入力マルチプレクサ(16bit)&lt;/li&gt;
&lt;li&gt;8入力マルチプレクサ(16bit)&lt;/li&gt;
&lt;li&gt;4入力デマルチプレクサ&lt;/li&gt;
&lt;li&gt;8入力デマルチプレクサ&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;マルチプレクサの実装に悩んだがいい感じの実装を思いついたときの爽快感がすごかった。&lt;/p&gt;
&lt;p&gt;真理値表を丁寧めに書きながら進めた結果マルチプレクサの実装以外はそこまで悩まなかった。&lt;/p&gt;
&lt;h2 id=&#34;第2章-ブール算術&#34;&gt;第2章 ブール算術&lt;/h2&gt;
&lt;p&gt;以下の論理回路を作成した。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;半加算器&lt;/li&gt;
&lt;li&gt;全加算器&lt;/li&gt;
&lt;li&gt;16bit同士の加算&lt;/li&gt;
&lt;li&gt;16bitの入力に1をインクリメントする回路&lt;/li&gt;
&lt;li&gt;ALU(Arithmetic Logic Unit: 算術論理演算装置)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;学び:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;内部ピンにインデックスアクセスするには次のように書く必要がある。
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-hdl&#34; data-lang=&#34;hdl&#34;&gt;Mux16(a=calculateResult, b=notCalculateResult, sel=no, out=out, out[0..7]=out0To7, out[8..15]=out8To15, out[15]=ng);
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;愚直な実装をしている箇所があったが、Mux16でスマートに書き直せることを知って感動した。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;第3章-メモリ&#34;&gt;第3章 メモリ&lt;/h2&gt;
&lt;p&gt;この章では、DFF(Data Flip-Flop)を用いて1-bit registerを作成し、それを組み合わせて16-bit registerを作成し、さらにそれを組み合わせてRAMを作成した。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;from-dff-to-ram.webp&#34; alt=&#34;from-dff-to-ram.webp&#34; loading=&#34;lazy&#34; /&gt;
&lt;div class=&#34;blogcard&#34; data-url=&#34;https://drive.google.com/file/d/1boFooygPrxMX-AxzogFYIZ-8QsZiDz96/view&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://drive.google.com/file/d/1boFooygPrxMX-AxzogFYIZ-8QsZiDz96/view&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail blogcard-thumbnail-placeholder&#34;&gt;
      &lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 24 24&#34; fill=&#34;none&#34; stroke=&#34;currentColor&#34; stroke-width=&#34;2&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;&gt;
        &lt;path d=&#34;M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71&#34;&gt;&lt;/path&gt;
        &lt;path d=&#34;M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71&#34;&gt;&lt;/path&gt;
      &lt;/svg&gt;
    &lt;/div&gt;&lt;div class=&#34;blogcard-content&#34;&gt;
      &lt;div class=&#34;blogcard-title&#34;&gt;lecture 3.pdf&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://drive.google.com/file/d/1boFooygPrxMX-AxzogFYIZ-8QsZiDz96/view&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
 P47より引用&lt;/p&gt;
&lt;p&gt;読み書き可能なメモリを作成したことで、コンピュータを作っている感が強まってきた。&lt;/p&gt;
&lt;p&gt;作成した回路は具体的には以下。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Register(1bit)&lt;/li&gt;
&lt;li&gt;Register(16bit)&lt;/li&gt;
&lt;li&gt;RAM(8bit)&lt;/li&gt;
&lt;li&gt;RAM(64bit)&lt;/li&gt;
&lt;li&gt;ProgramCounter&lt;/li&gt;
&lt;li&gt;RAM(512bit)&lt;/li&gt;
&lt;li&gt;RAM(4K-bit)&lt;/li&gt;
&lt;li&gt;RAM(16K-bit)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;学びメモ&#34;&gt;学びメモ&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;第2章までは時間に依存しない回路のみを扱っていたがこの章では過去の状態を保持する回路を作成した。&lt;/li&gt;
&lt;li&gt;ここでは時間をクロックという単位で区切って扱う。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;非同期チップ(組み合わせチップ)&lt;/strong&gt;: 入力値の組み合わせのみに反応し時間の進行には影響を受けない&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;同期チップ(順序チップ)&lt;/strong&gt;: 以前の時間単位での変化に対応する用に設計されたチップ&lt;/li&gt;
&lt;li&gt;同期チップを利用することでシステム内のチップ間で信号が伝播するのにかかる時間を無視できる。&lt;/li&gt;
&lt;li&gt;ただしクロックサイクルは「システム内のチップ間で信号が伝播するのにかかる時間の最大値」と「1チップ内で最も処理時間がかかる演算を完了するのにかかる時間」の合計値よりも大きく設定する必要がある。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;DFFは&lt;code&gt;out(t+1) = in(t)&lt;/code&gt;で表される出力を持つ。DFFを用いることで過去の状態を論理回路上で表現できる。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;dff.webp&#34; alt=&#34;dff.webp&#34; loading=&#34;lazy&#34; /&gt;
&lt;div class=&#34;blogcard&#34; data-url=&#34;https://drive.google.com/file/d/1boFooygPrxMX-AxzogFYIZ-8QsZiDz96/view&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://drive.google.com/file/d/1boFooygPrxMX-AxzogFYIZ-8QsZiDz96/view&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail blogcard-thumbnail-placeholder&#34;&gt;
      &lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 24 24&#34; fill=&#34;none&#34; stroke=&#34;currentColor&#34; stroke-width=&#34;2&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;&gt;
        &lt;path d=&#34;M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71&#34;&gt;&lt;/path&gt;
        &lt;path d=&#34;M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71&#34;&gt;&lt;/path&gt;
      &lt;/svg&gt;
    &lt;/div&gt;&lt;div class=&#34;blogcard-content&#34;&gt;
      &lt;div class=&#34;blogcard-title&#34;&gt;lecture 3.pdf&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://drive.google.com/file/d/1boFooygPrxMX-AxzogFYIZ-8QsZiDz96/view&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
 P41より引用&lt;/p&gt;
&lt;p&gt;次のようにマルチプレクサとDFFを組み合わせることで1-bit registerを作成できる。&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-hdl&#34; data-lang=&#34;hdl&#34;&gt;CHIP Bit {
    IN in, load;
    OUT out;

    PARTS:
    Mux(a=dffOut, b=in, sel=load, out=mux);
    DFF(in=mux, out=out, out=dffOut);
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;1-bit registerは時刻&lt;code&gt;t&lt;/code&gt;において&lt;code&gt;load&lt;/code&gt;ビットがアサートされると&lt;code&gt;out(t+1)&lt;/code&gt;が&lt;code&gt;in(t)&lt;/code&gt;の値になり、アサートされていない場合は&lt;code&gt;out(t+1)&lt;/code&gt;は&lt;code&gt;out(t)&lt;/code&gt;の値になる。換言するとレジスタを利用することで過去の状態を保持できる。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;1-bit-register.webp&#34; alt=&#34;1-bit-register.webp&#34; loading=&#34;lazy&#34; /&gt;
&lt;div class=&#34;blogcard&#34; data-url=&#34;https://drive.google.com/file/d/1boFooygPrxMX-AxzogFYIZ-8QsZiDz96/view&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://drive.google.com/file/d/1boFooygPrxMX-AxzogFYIZ-8QsZiDz96/view&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail blogcard-thumbnail-placeholder&#34;&gt;
      &lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 24 24&#34; fill=&#34;none&#34; stroke=&#34;currentColor&#34; stroke-width=&#34;2&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;&gt;
        &lt;path d=&#34;M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71&#34;&gt;&lt;/path&gt;
        &lt;path d=&#34;M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71&#34;&gt;&lt;/path&gt;
      &lt;/svg&gt;
    &lt;/div&gt;&lt;div class=&#34;blogcard-content&#34;&gt;
      &lt;div class=&#34;blogcard-title&#34;&gt;lecture 3.pdf&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://drive.google.com/file/d/1boFooygPrxMX-AxzogFYIZ-8QsZiDz96/view&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
 P25より引用&lt;/p&gt;
&lt;h2 id=&#34;第4章-機械語&#34;&gt;第4章 機械語&lt;/h2&gt;
&lt;p&gt;第4章では以下のプログラムを機械語で書いた。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;掛け算を行うプログラム&lt;/li&gt;
&lt;li&gt;キーボードが押されているときだけ画面を黒くするプログラム&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;機械語&#34;&gt;機械語&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ハードウェアプラットフォームが実行するように設計されている基本的な命令セット&lt;/li&gt;
&lt;li&gt;高水準言語は表現力やプラットフォーム間の互換性を目標に設計される一方で機械語は特定のハードウェアで直接実行され、そのハードウェアを完全に制御できるように設計されている。&lt;/li&gt;
&lt;li&gt;機械語は決められた形式に従い&lt;strong&gt;プロセッサ&lt;/strong&gt;と&lt;strong&gt;レジスタ&lt;/strong&gt;を用いて&lt;strong&gt;メモリ&lt;/strong&gt;を操作するように設計されている。&lt;/li&gt;
&lt;li&gt;バイナリ形式、記号形式の2パターンで記述できる。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;メモリ&#34;&gt;メモリ&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;データや命令を保存するハードウェアデバイス。各セルは&lt;strong&gt;メモリ位置&lt;/strong&gt;や&lt;strong&gt;メモリレジスタ&lt;/strong&gt;と呼ばれ、それぞれ固有の&lt;strong&gt;アドレス&lt;/strong&gt;を持つ。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;プロセッサ&#34;&gt;プロセッサ&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;プロセッサは&lt;strong&gt;中央演算装置(CPU)&lt;/strong&gt; と呼ばれ、あらかじめ決められた基本的な命令セットを実行できる。&lt;/li&gt;
&lt;li&gt;プロセッサは選択されたレジスタとメモリ位置からデータを取り出し、選択されたレジスタとメモリ位置に出力を書き込む。&lt;/li&gt;
&lt;li&gt;プロセッサは&lt;strong&gt;ALU&lt;/strong&gt;と&lt;strong&gt;レジスタ&lt;/strong&gt;、&lt;strong&gt;バイナリ命令の解析と実行を可能にする論理ゲート&lt;/strong&gt;によって構成される。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;レジスタ&#34;&gt;レジスタ&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;プロセッサとメモリはそれぞれ独立したチップとして実装されており一方から他方へデータを移すには比較的時間がかかる。そのためほとんどのプロセッサにはいくつかのレジスタが備わっており、高速なローカルメモリとして機能する。&lt;/li&gt;
&lt;li&gt;CPUに存在するレジスタは2つのタイプに分類される。
&lt;ul&gt;
&lt;li&gt;データを保持する&lt;strong&gt;データレジスタ(Dレジスタ)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;アドレスを保持する&lt;strong&gt;アドレスレジスタ(Aレジスタ)&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;hackコンピュータのアーキテクチャ&#34;&gt;Hackコンピュータのアーキテクチャ&lt;/h3&gt;
&lt;p&gt;Hackコンピュータは以下のようなアーキテクチャを持つ。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;hack-computer-architecture.webp&#34; alt=&#34;hack-computer-architecture.webp&#34; loading=&#34;lazy&#34; /&gt;
&lt;div class=&#34;blogcard&#34; data-url=&#34;https://drive.google.com/file/d/1HxjPmIZkFHl-BVW3qoz8eD9dqEuEyuBI/view&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://drive.google.com/file/d/1HxjPmIZkFHl-BVW3qoz8eD9dqEuEyuBI/view&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail blogcard-thumbnail-placeholder&#34;&gt;
      &lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 24 24&#34; fill=&#34;none&#34; stroke=&#34;currentColor&#34; stroke-width=&#34;2&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;&gt;
        &lt;path d=&#34;M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71&#34;&gt;&lt;/path&gt;
        &lt;path d=&#34;M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71&#34;&gt;&lt;/path&gt;
      &lt;/svg&gt;
    &lt;/div&gt;&lt;div class=&#34;blogcard-content&#34;&gt;
      &lt;div class=&#34;blogcard-title&#34;&gt;lecture 4.pdf&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://drive.google.com/file/d/1HxjPmIZkFHl-BVW3qoz8eD9dqEuEyuBI/view&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
 P23より引用&lt;/p&gt;
&lt;h3 id=&#34;アセンブラの役割&#34;&gt;アセンブラの役割&lt;/h3&gt;
&lt;p&gt;機械語はバイナリ形式、記号形式の2パターンで記述できると書いたが、記号形式で&lt;code&gt;@x&lt;/code&gt;のように変数を宣言した場合にその変数を実際のメモリのどこに置くかを知るのが&lt;strong&gt;アセンブラ&lt;/strong&gt;である。アセンブラのおかげで記号形式のプログラム側は実装詳細を意識することなく変数を初期化、利用できる。&lt;/p&gt;
&lt;h3 id=&#34;命令タイプ&#34;&gt;命令タイプ&lt;/h3&gt;
&lt;p&gt;Hack言語には2つの命令タイプがある。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;A命令&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;A命令はAレジスタに15ビットの値を設定する。&lt;/li&gt;
&lt;li&gt;A命令は1ビットのオペコード + 15ビットの値で構成される。(Hack機械語ではA命令のオペコードは&lt;code&gt;0&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;A命令は3つの目的で使用される。
&lt;ul&gt;
&lt;li&gt;プログラムによってコンピュータに定数を入力する&lt;/li&gt;
&lt;li&gt;Aレジスタのアドレスを設定することでその次のC命令でRAMレジスタを操作できる&lt;/li&gt;
&lt;li&gt;Aレジスタにジャンプ先のアドレスを設定することでその次のC命令でジャンプを実行できる&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C命令&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;C命令では次の3つを指定する。
&lt;ul&gt;
&lt;li&gt;どういう計算をするか(comp)&lt;/li&gt;
&lt;li&gt;計算された値をどこに保存するか(dest)&lt;/li&gt;
&lt;li&gt;次に何をするか(jump)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Hack機械語では一番左端の1ビットが1&lt;/li&gt;
&lt;li&gt;C命令は次のような形式で構成される。&lt;code&gt;111accccccdddjjj&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;111: 先頭の1がオペコードで、左から2,3ビット目は使用されないが慣例として&lt;code&gt;1&lt;/code&gt;が設定されている。&lt;/li&gt;
&lt;li&gt;a: ALUへの入力がAレジスタからの値化Mからの値か決定する(1ビット)&lt;/li&gt;
&lt;li&gt;c: compフィールド。(6ビット)ALUに対して計算内容を指定する。&lt;/li&gt;
&lt;li&gt;d: destフィールド。(3ビット)計算結果の値をどこに保存するかを表現する。左から順にDレジスタ、Aレジスタ、&lt;code&gt;RAM[A]&lt;/code&gt;に値を保存するかを表現する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&#34;the-hack-language-specification.webp&#34; alt=&#34;the-hack-language-specification&#34; loading=&#34;lazy&#34; /&gt;
&lt;div class=&#34;blogcard&#34; data-url=&#34;https://drive.google.com/file/d/1HxjPmIZkFHl-BVW3qoz8eD9dqEuEyuBI/view&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://drive.google.com/file/d/1HxjPmIZkFHl-BVW3qoz8eD9dqEuEyuBI/view&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail blogcard-thumbnail-placeholder&#34;&gt;
      &lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 24 24&#34; fill=&#34;none&#34; stroke=&#34;currentColor&#34; stroke-width=&#34;2&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;&gt;
        &lt;path d=&#34;M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71&#34;&gt;&lt;/path&gt;
        &lt;path d=&#34;M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71&#34;&gt;&lt;/path&gt;
      &lt;/svg&gt;
    &lt;/div&gt;&lt;div class=&#34;blogcard-content&#34;&gt;
      &lt;div class=&#34;blogcard-title&#34;&gt;lecture 4.pdf&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://drive.google.com/file/d/1HxjPmIZkFHl-BVW3qoz8eD9dqEuEyuBI/view&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
 P129より引用&lt;/p&gt;
&lt;h3 id=&#34;外部デバイス&#34;&gt;外部デバイス&lt;/h3&gt;
&lt;p&gt;Hackのハードウェアプラットフォームでは画面とキーボードの2つの外部デバイスに接続できる。どちらのデバイスも&lt;strong&gt;メモリマップ&lt;/strong&gt;を通してコンピュータと会話する。(メモリの中に画面とキーボード用のメモリ領域があり、そこに画面の各ピクセルの値や押下されているキーのキーコードが格納される。)&lt;/p&gt;
&lt;h3 id=&#34;hackプログラムの例&#34;&gt;Hackプログラムの例&lt;/h3&gt;
&lt;p&gt;以下は掛け算を行うHackプログラムのソースコード。(Hackアーキテクチャで動作する機械語で書かれている) ハードウェアの構成要素を理解しながら手続き型チックに記述する必要があるため難しかったが理解が進んだ。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-asm&#34; data-lang=&#34;asm&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// 0に対して(R0-1)回R1を足すことで掛け算を実現する
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;// n = 0
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;@&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;n&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;M&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;// R2 = 0
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;@&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;R2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;M&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;LOOP&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;// if n == R0 then goto END
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;@&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;n&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;D&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;M&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;@&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;R0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;D&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;D-M&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;@&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;END&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;D&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;;JEQ
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;// R2 += R1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;@&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;R2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;D&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;M&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;@&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;R1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;D&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;D&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;+&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;M&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;// R2 = D
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;@&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;R2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;M&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;D&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;// n++
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;@&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;n&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;M&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;M&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;+&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;// go to LOOP
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;@&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;LOOP&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;;JMP
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;END&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;@&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;END&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;;JMP
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;第5章-コンピュータアーキテクチャ&#34;&gt;第5章 コンピュータアーキテクチャ&lt;/h2&gt;
&lt;p&gt;第5章では、これまでの章で作成した論理回路を組み合わせてついに1つの汎用コンピュータを作成する。このコンピュータは第4章に登場した機械語のプログラムを実行できる。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ノイマン型アーキテクチャ&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;CPUがメモリデバイスと相互作用する。&lt;/li&gt;
&lt;li&gt;入力デバイスからデータを受け取り出力デバイスへデータを送信する。&lt;/li&gt;
&lt;li&gt;コンピュータのメモリに保存されるデータはコンピュータが計算したデータだけではなくコンピュータに何を行うべきかを指示する「命令」も含まれる。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;メモリ&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;物理的にはアドレス指定可能な固定サイズの&lt;strong&gt;レジスタ&lt;/strong&gt;の並びで、それぞれが固有のアドレスを持つ。&lt;/li&gt;
&lt;li&gt;概念的にはアドレス空間はデータと命令の保存という2つの役割を果たす。&lt;/li&gt;
&lt;li&gt;ランダムに選択されたメモリレジスタに瞬時に到達できるという要件からRandom Access Memoryと呼ばれている。
&lt;ul&gt;
&lt;li&gt;たしかにRAMはレジスタの木構造になっていたのである程度大きいRAMでも少ないホップ数で指定したレジスタにアクセスできそうだ。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;データ専用のメモリ領域を&lt;strong&gt;データメモリ&lt;/strong&gt;、命令専用のメモリ領域を&lt;strong&gt;命令メモリ&lt;/strong&gt;と呼ぶ。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CPU&lt;/strong&gt;:
  &lt;!-- textlint-disable ja-technical-writing/ja-no-redundant-expression --&gt;
&lt;ul&gt;
&lt;li&gt;CPUは現在読み込まれているプログラムの命令を実行する。&lt;/li&gt;
&lt;li&gt;各命令はCPUに対して以下を指示する。
&lt;ul&gt;
&lt;li&gt;どの計算を実行するか&lt;/li&gt;
&lt;li&gt;どのレジスタにアクセスするか&lt;/li&gt;
&lt;li&gt;次のどの命令をフェッチして実行するか&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CPUはこれらのタスクを&lt;strong&gt;ALU&lt;/strong&gt;、&lt;strong&gt;レジスタ&lt;/strong&gt;、&lt;strong&gt;制御ユニット&lt;/strong&gt;を使って実行する。&lt;/li&gt;
&lt;/ul&gt;
  &lt;!-- textlint-disable ja-technical-writing/ja-no-redundant-expression --&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;第5章の課題ではこれまでの章で作成した論理回路を組み合わせて以下を作成した。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Memory&lt;/li&gt;
&lt;li&gt;CPU&lt;/li&gt;
&lt;li&gt;Computer&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;正直CPUの実装、デバッグがはかなり大変だったが公式が提供してくれているテストツールとデバッガのおかげで効率的にバグを見つけることができた。&lt;/p&gt;
&lt;p&gt;こんな感じで各ピンの出力や期待する結果とのdiffを比較的見やすい形式で表示してくれるのでありがたかった。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;cpu-debug.webp&#34; alt=&#34;cpu-debug.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;ここで作成したCPUの回路は次のようなもの。ここではヒントとして大まかな回路設計が与えられておりそれを参考にしつつ足りない部分を埋めていく形で実装を進めた。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;cpu-implementation.webp&#34; alt=&#34;cpu-implementation.webp&#34; loading=&#34;lazy&#34; /&gt;
&lt;div class=&#34;blogcard&#34; data-url=&#34;https://drive.google.com/file/d/1Z_fxYmmRNXTkAzmZ6YMoX9NXZIRVCKiw/view&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://drive.google.com/file/d/1Z_fxYmmRNXTkAzmZ6YMoX9NXZIRVCKiw/view&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail blogcard-thumbnail-placeholder&#34;&gt;
      &lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 24 24&#34; fill=&#34;none&#34; stroke=&#34;currentColor&#34; stroke-width=&#34;2&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;&gt;
        &lt;path d=&#34;M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71&#34;&gt;&lt;/path&gt;
        &lt;path d=&#34;M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71&#34;&gt;&lt;/path&gt;
      &lt;/svg&gt;
    &lt;/div&gt;&lt;div class=&#34;blogcard-content&#34;&gt;
      &lt;div class=&#34;blogcard-title&#34;&gt;lecture 5.pdf&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://drive.google.com/file/d/1Z_fxYmmRNXTkAzmZ6YMoX9NXZIRVCKiw/view&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
 P31より引用&lt;/p&gt;
&lt;h2 id=&#34;第6章-アセンブラ&#34;&gt;第6章 アセンブラ&lt;/h2&gt;
&lt;p&gt;第6章では第5章で書いた機械語の記号表現をバイナリ表現に変換するアセンブラを開発する。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;変数やラベルのアドレス管理を行うために&lt;strong&gt;シンボルテーブル&lt;/strong&gt;を利用する。シンボルテーブルには以下のような情報が格納される。
&lt;ul&gt;
&lt;li&gt;ラベルの位置 e.g. &lt;code&gt;(LOOP)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;変数のアドレス e.g. &lt;code&gt;@i&lt;/code&gt;(Hack機械語では変数は16以降のアドレスに順に割り当てられる)&lt;/li&gt;
&lt;li&gt;定義済みシンボルのアドレス e.g. &lt;code&gt;@SCREEN&lt;/code&gt;, &lt;code&gt;@KBD&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;シンボル処理&#34;&gt;シンボル処理&lt;/h3&gt;
&lt;p&gt;アセンブリプログラムではシンボルが定義される前にシンボルラベルを使用できる。(goto命令の行き先を指定するのに利用する)&lt;/p&gt;
&lt;p&gt;この挙動も考慮しつつバイナリを生成するには&lt;strong&gt;2パス・アセンブラ&lt;/strong&gt;と呼ばれる手法を用いる。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;第1パス: シンボルテーブルを作成しすべてのラベルシンボルをテーブルに追加する。&lt;/li&gt;
&lt;li&gt;第2パス: 変数シンボルを処理し、シンボルテーブルを使用してバイナリコードを生成する。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;第6章からは好きな言語で実装できるのでRustで実装した。構文解析系はenumがある言語だと書きやすくて良い。&lt;/p&gt;
&lt;h2 id=&#34;第7章-仮想マシンi処理&#34;&gt;第7章 仮想マシンI：処理&lt;/h2&gt;
&lt;p&gt;第7章ではVM変換器の一部を実装した。第8章で残りの部分を実装してVM変換器が完成する。ここまでの課題の中では一番大変で丸3日かかった。&lt;/p&gt;
&lt;h3 id=&#34;hackプラットフォームのvmアーキテクチャとその利点&#34;&gt;HackプラットフォームのVMアーキテクチャとその利点&lt;/h3&gt;
&lt;p&gt;Hackプラットフォームにおいて、Hackプログラムは2段階コンパイルによって機械語に変換される。(更にその後アセンブラが機械語(記号表現)を機械語(バイナリ表現)に変換する)&lt;/p&gt;

&lt;pre class=&#34;mermaid&#34;&gt;    graph LR
    A[Jackコード&lt;br&gt;e.g. Foo.jack] --&gt;|コンパイラが変換| B[&#34;VMコード(中間コード)&lt;br&gt;e.g. Foo.vm&#34;]
    B --&gt;|VM変換器が変換| C[&#34;機械語(記号表現)&lt;br&gt;e.g. Foo.asm&#34;]
    C --&gt;|アセンブラが変換| D[&#34;機械語(バイナリ表現)&lt;br&gt;e.g. Foo.hack&#34;]
&lt;/pre&gt;

&lt;p&gt;中間コードは&lt;strong&gt;仮想マシン(Virtual Machine; VM)&lt;/strong&gt; と呼ばれる抽象化されたコンピュータ上で実行されるように設計されている。&lt;/p&gt;
&lt;p&gt;高水準言語のプログラムを直接機械語に変換する方式だとハードウェアプラットフォームごとにコンパイラを作成する必要がある。この場合、コンパイラはソース言語(高水準言語)とターゲット言語(機械語)の両方に依存するためそれぞれの変更に追従する必要がある。&lt;/p&gt;
&lt;p&gt;2段階でコンパイルする方式を採用するとコンパイラはソース言語の詳細に、VM変換器はターゲット言語の詳細にのみ依存するため&lt;strong&gt;変更への追従コストを下げることができる。&lt;/strong&gt;
この方式ではコンパイラはハードウェアプラットフォームによらず利用することができ、ハードウェアごとにVM変換器さえ実装すればよい。そのため&lt;strong&gt;クロスプラットフォーム対応が比較的容易になる&lt;/strong&gt;という利点がある。&lt;/p&gt;
&lt;p&gt;VMフレームワークは上記の利点の代償として&lt;strong&gt;効率性が低下する&lt;/strong&gt;という欠点がある。2段階の変換プロセスで生成するコードは直接コンパイルで生成するコードよりも冗長なことが多く、効率性が落ちる。&lt;/p&gt;
&lt;h3 id=&#34;vm言語の設計&#34;&gt;VM言語の設計&lt;/h3&gt;
&lt;p&gt;VM言語の設計にはバランスが重要で以下の要求を同時に満たす必要がある。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;高水準側からの要求: 高水準言語のコードを表現できるだけの表現力と構造性を持たなければならない&lt;/li&gt;
&lt;li&gt;低水準側からの要求: VMコードから生成される機械語がコンパクトで効率的になるようにVMコードは十分に低水準でなければならない&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;このような一見矛盾するような要件を&lt;strong&gt;スタックマシン&lt;/strong&gt;が解決する。スタックマシンに基づく中間のVM言語を用いることで&lt;strong&gt;高水準言語の表現力&lt;/strong&gt;と&lt;strong&gt;低水準言語の効率性&lt;/strong&gt;という相反する要求を満たすことができる。&lt;/p&gt;
&lt;h3 id=&#34;スタックマシンの挙動&#34;&gt;スタックマシンの挙動&lt;/h3&gt;
&lt;p&gt;スタックマシンの中心は&lt;strong&gt;スタック&lt;/strong&gt;と呼ばれるLIFOのデータ構造にある。ここではいくつかの操作について説明する。(ここではスタックは下方向に成長するように記述する)&lt;/p&gt;
&lt;h4 id=&#34;push操作の例&#34;&gt;push操作の例&lt;/h4&gt;

&lt;pre class=&#34;mermaid&#34;&gt;graph LR
    A[Stack: empty] --&gt;|push 10| B[Stack:&lt;br&gt;10]
&lt;/pre&gt;

&lt;p&gt;pushを行うとスタックの先頭に値が追加される。スタックでは&lt;strong&gt;SP(スタックポインタ)&lt;/strong&gt; という値を使ってスタックの先頭位置を保持している。SPはpush操作を行う際に値を追加する領域を指し示している。スタックのメモリアドレスが&lt;code&gt;0&lt;/code&gt;からスタートすると仮定すると今回の例ではアドレス&lt;code&gt;0&lt;/code&gt;に値がpushされたときにSPの値が&lt;code&gt;0&lt;/code&gt;から&lt;code&gt;1&lt;/code&gt;になる。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;アドレス&lt;/th&gt;
&lt;th&gt;値&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;pre class=&#34;mermaid&#34;&gt;graph LR
    A[Stack: empty] --&gt;|push 10| B[Stack:&lt;br&gt;10]
    B --&gt;|push 20| C[Stack:&lt;br&gt;10&lt;br&gt;20]
&lt;/pre&gt;

&lt;p&gt;push操作を行うとスタックの先頭に値が追加される。このときSPの値は&lt;code&gt;1&lt;/code&gt;から&lt;code&gt;2&lt;/code&gt;になる。(補足:ここではSPは0-originとする)&lt;/p&gt;
&lt;h4 id=&#34;pop操作の例&#34;&gt;pop操作の例&lt;/h4&gt;

&lt;pre class=&#34;mermaid&#34;&gt;graph LR
    A[Stack:&lt;br&gt;42] --&gt;|pop local 0| B[&#34;Stack: empty&lt;br&gt;local[0] = 42&#34;]
&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;pop segment_name index&lt;/code&gt;と記述するとスタックの先頭の値を取り除き、指定したメモリセグメント、インデックスの位置に値を書き込む。&lt;/p&gt;
&lt;p&gt;pop操作はスタックの先頭の値を取り除く。&lt;/p&gt;
&lt;h4 id=&#34;算術演算addの例&#34;&gt;算術演算(add)の例&lt;/h4&gt;

&lt;pre class=&#34;mermaid&#34;&gt;graph LR
    A[Stack: empty] --&gt;|push 10| B[Stack:&lt;br&gt;10]
    B --&gt;|push 20| C[Stack:&lt;br&gt;10&lt;br&gt;20]
    C --&gt;|add| D[Stack:&lt;br&gt;30]
&lt;/pre&gt;

&lt;p&gt;算術演算の例として&lt;code&gt;x+y&lt;/code&gt;を行うケースを考える。&lt;/p&gt;
&lt;p&gt;この処理は次のような流れで行われる。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;スタックからオペランド&lt;code&gt;x&lt;/code&gt;, &lt;code&gt;y&lt;/code&gt;をpopする&lt;/li&gt;
&lt;li&gt;&lt;code&gt;x+y&lt;/code&gt;を計算する&lt;/li&gt;
&lt;li&gt;計算結果をスタックにpushする&lt;/li&gt;
&lt;/ol&gt;

&lt;pre class=&#34;mermaid&#34;&gt;graph LR
    A[Stack:&lt;br&gt;10&lt;br&gt;20] --&gt;|pop y=20| B[Stack:&lt;br&gt;10]
    B --&gt;|pop x=10| C[Stack: empty]
    C --&gt;|push x+y=30| D[Stack:&lt;br&gt;30]
&lt;/pre&gt;

&lt;p&gt;この方法を拡張することで一般的な算術演算をスタックマシンで評価できる。&lt;/p&gt;
&lt;p&gt;第7章では、以下の演算子を実装した。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;push&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;pop&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;算術演算子
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;add&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sub&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;neg&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;eq&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gt&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;lt&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;and&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;or&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;not&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;仮想メモリセグメント&#34;&gt;仮想メモリセグメント&lt;/h3&gt;
&lt;p&gt;ここで実装するVMにはシンボル変数は存在しない。そのかわりに変数は&lt;code&gt;static&lt;/code&gt;, &lt;code&gt;local&lt;/code&gt;, &lt;code&gt;argument&lt;/code&gt;, &lt;code&gt;this&lt;/code&gt;, &lt;code&gt;that&lt;/code&gt;, &lt;code&gt;pointer&lt;/code&gt;, &lt;code&gt;temp&lt;/code&gt;のような名前を持つ&lt;strong&gt;仮想セグメント&lt;/strong&gt;の要素として表現される。たとえばコンパイラは高水準言語プログラムで見つかった最初のスタティック変数を&lt;code&gt;static 0&lt;/code&gt;に、その次に見つかったスタティック変数を&lt;code&gt;static 1&lt;/code&gt;に、というように変換する。&lt;/p&gt;
&lt;p&gt;ここでのVM実装では以下のような仮想メモリセグメントを持つ。&lt;/p&gt;
&lt;blockquote&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;名前&lt;/th&gt;
&lt;th&gt;場所&lt;/th&gt;
&lt;th&gt;使用法&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;SP&lt;/td&gt;
&lt;td&gt;RAM[0]&lt;/td&gt;
&lt;td&gt;スタックポインタ：スタック最上位の次のメモリアドレス&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LCL&lt;/td&gt;
&lt;td&gt;RAM[1]&lt;/td&gt;
&lt;td&gt;localセグメントのベースアドレス&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ARG&lt;/td&gt;
&lt;td&gt;RAM[2]&lt;/td&gt;
&lt;td&gt;argumentセグメントのベースアドレス&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;THIS&lt;/td&gt;
&lt;td&gt;RAM[3]&lt;/td&gt;
&lt;td&gt;thisセグメントのベースアドレス&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;THAT&lt;/td&gt;
&lt;td&gt;RAM[4]&lt;/td&gt;
&lt;td&gt;thatセグメントのベースアドレス&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TEMP&lt;/td&gt;
&lt;td&gt;RAM[5-12]&lt;/td&gt;
&lt;td&gt;tempセグメントを保持&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;R13, R14, R15&lt;/td&gt;
&lt;td&gt;RAM[13-15]&lt;/td&gt;
&lt;td&gt;VM変換器が生成するアセンブリコードに変数が必要な場合、これらのレジスタを使用可能&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;P175より引用&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;LCL&lt;/code&gt;, &lt;code&gt;ARG&lt;/code&gt;, &lt;code&gt;THIS&lt;/code&gt;, &lt;code&gt;THAT&lt;/code&gt;には各セグメントのベースアドレスが格納されている。たとえば次のように指定されていた場合、&lt;code&gt;pop this 2&lt;/code&gt;はスタックの先頭の値を&lt;code&gt;RAM[2202]&lt;/code&gt;に書き込む。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;アドレス&lt;/th&gt;
&lt;th&gt;値&lt;/th&gt;
&lt;th&gt;備考&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;256&lt;/td&gt;
&lt;td&gt;SP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;2000&lt;/td&gt;
&lt;td&gt;LCL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;2100&lt;/td&gt;
&lt;td&gt;ARG&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;2200&lt;/td&gt;
&lt;td&gt;THIS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;2300&lt;/td&gt;
&lt;td&gt;THAT&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;vm変換器の動作例&#34;&gt;VM変換器の動作例&lt;/h3&gt;
&lt;p&gt;例として実際の変換例を示す。&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-vm&#34; data-lang=&#34;vm&#34;&gt;push constant 7
push constant 8
add
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;今回作成した実装では上記のvmコードは次のようなアセンブリコードに変換される。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-asm&#34; data-lang=&#34;asm&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// init
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;@256&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;D&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;A&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;@&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;SP&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;M&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;D&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// body
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// push
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;@7&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;D&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;A&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;@&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;SP&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;A&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;M&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;M&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;D&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;@&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;SP&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;M&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;M&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;+&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// push
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;@8&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;D&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;A&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;@&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;SP&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;A&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;M&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;M&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;D&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;@&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;SP&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;M&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;M&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;+&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// add
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;@&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;SP&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;A&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;M&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;A&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;A-1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;A&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;A-1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;D&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;M&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;@&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;SP&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;A&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;M&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;A&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;A-1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;D&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;D&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;+&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;M&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;@&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;SP&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;A&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;M&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;A&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;A-1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;A&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;A-1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;M&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;@&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;SP&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;A&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;M&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;A&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;A-1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;M&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;@&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;SP&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;M&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;M-1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;M&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;M-1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;@&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;SP&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;A&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;M&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;M&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;D&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;@&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;SP&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;M&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;M&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;+&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// end
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;END&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;@&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;END&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;;JMP
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;VM変換器の実装はハードウェアの構造を意識しながらだいぶ手続き的なコードを書く必要があるので大変だった。(記述量も多いしミスるポイントも多い。)&lt;/p&gt;
&lt;p&gt;現代のおいては低レイヤを隠蔽してくれる便利な仕組みがあるおかげでソフトウェアエンジニアが少ない記述量でアプリケーションを動かすことができていることを実感した。&lt;/p&gt;
&lt;p&gt;ただ、隠蔽されているからこそ自主的に潜っていかないと構造の理解を深めるのが難しかったりするので引き続きやっていきたい。&lt;/p&gt;
&lt;h2 id=&#34;第8章-仮想マシンii制御&#34;&gt;第8章 仮想マシンII：制御&lt;/h2&gt;
&lt;p&gt;第7章では&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;push&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;pop&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;算術演算子
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;add&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sub&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;neg&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;eq&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gt&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;lt&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;and&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;or&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;not&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;以下の演算子を実装したが、第8章では以下の演算子を実装し、VM変換器を完成させた。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;label&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;goTo&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ifGoTo&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;call&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;function&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;return&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これを実装することで次の操作が可能になりよりプログラムっぽい処理を行えるようになる。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;任意のラベル位置へのジャンプ&lt;/li&gt;
&lt;li&gt;if分岐&lt;/li&gt;
&lt;li&gt;関数の宣言と呼び出し&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;関数の呼び出しcall&#34;&gt;関数の呼び出し(&lt;code&gt;call&lt;/code&gt;)&lt;/h3&gt;
&lt;p&gt;Hackプラットフォームにおいては&lt;code&gt;call {function_name}&lt;/code&gt;コマンドを使って関数呼び出しを行う。&lt;/p&gt;
&lt;p&gt;スタックを利用することで関数の呼び出しと戻り値の取得をシンプルに行うことができる。&lt;/p&gt;
&lt;p&gt;ここでは&lt;code&gt;func_a&lt;/code&gt;から&lt;code&gt;func_b&lt;/code&gt;を呼び出すシナリオを例に関数呼び出しをスタックで実現する際の操作を説明する。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;(&lt;code&gt;func_a&lt;/code&gt;から&lt;code&gt;func_b&lt;/code&gt;を呼び出す)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;func_a&lt;/code&gt;の以下の呼び出し側の情報をスタックにpush(これらの情報は&lt;strong&gt;フレーム&lt;/strong&gt;と呼ばれる)(画像の灰色の部分)
&lt;ol&gt;
&lt;li&gt;リターンアドレス(: &lt;code&gt;func_b&lt;/code&gt;の呼び出しが完了して&lt;code&gt;return&lt;/code&gt;する際に戻るアドレス)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;func_a&lt;/code&gt;のLCLセグメントのベースアドレス&lt;/li&gt;
&lt;li&gt;&lt;code&gt;func_a&lt;/code&gt;のARGセグメントのベースアドレス&lt;/li&gt;
&lt;li&gt;&lt;code&gt;func_a&lt;/code&gt;のTHISセグメントのベースアドレス&lt;/li&gt;
&lt;li&gt;&lt;code&gt;func_a&lt;/code&gt;のTHATセグメントのベースアドレス&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;ARG, LCLセグメントの値を更新&lt;/li&gt;
&lt;li&gt;&lt;code&gt;func_b&lt;/code&gt;のコマンドが定義されているアドレスにジャンプ&lt;/li&gt;
&lt;li&gt;リターンアドレスラベルをコードに挿入&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&#34;call.webp&#34; alt=&#34;call.webp&#34; loading=&#34;lazy&#34; /&gt;
&lt;div class=&#34;blogcard&#34; data-url=&#34;https://drive.google.com/file/d/1BexrNmdqYhKPkqD_Y81qNAUeyfzl-ZtO/view&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://drive.google.com/file/d/1BexrNmdqYhKPkqD_Y81qNAUeyfzl-ZtO/view&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail blogcard-thumbnail-placeholder&#34;&gt;
      &lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 24 24&#34; fill=&#34;none&#34; stroke=&#34;currentColor&#34; stroke-width=&#34;2&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;&gt;
        &lt;path d=&#34;M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71&#34;&gt;&lt;/path&gt;
        &lt;path d=&#34;M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71&#34;&gt;&lt;/path&gt;
      &lt;/svg&gt;
    &lt;/div&gt;&lt;div class=&#34;blogcard-content&#34;&gt;
      &lt;div class=&#34;blogcard-title&#34;&gt;lecture 8.pdf&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://drive.google.com/file/d/1BexrNmdqYhKPkqD_Y81qNAUeyfzl-ZtO/view&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
 P58より引用&lt;/p&gt;
&lt;h3 id=&#34;関数からのreturnreturn&#34;&gt;関数からのreturn(&lt;code&gt;return&lt;/code&gt;)&lt;/h3&gt;
&lt;p&gt;呼び出された関数の終了は&lt;code&gt;return&lt;/code&gt;コマンドで行う。このコマンドが呼ばれることで呼び出し側に処理が戻る。&lt;/p&gt;
&lt;p&gt;ここでは&lt;code&gt;func_a&lt;/code&gt;から&lt;code&gt;func_b&lt;/code&gt;を呼び出した際に&lt;code&gt;func_b&lt;/code&gt;から&lt;code&gt;func_a&lt;/code&gt;に戻るシナリオを例にスタックの操作を説明する。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;frameのアドレスを一時変数に格納&lt;/li&gt;
&lt;li&gt;リターンアドレスを一時変数に格納&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ARG&lt;/code&gt;に返り値を格納&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SP&lt;/code&gt;を&lt;code&gt;ARG+1&lt;/code&gt;に設定&lt;/li&gt;
&lt;li&gt;&lt;code&gt;THAT&lt;/code&gt;, &lt;code&gt;THIS&lt;/code&gt;, &lt;code&gt;ARG&lt;/code&gt;, &lt;code&gt;LCL&lt;/code&gt;を復元&lt;/li&gt;
&lt;li&gt;リターンアドレスにジャンプ&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&#34;return.webp&#34; alt=&#34;return.webp&#34; loading=&#34;lazy&#34; /&gt;
&lt;div class=&#34;blogcard&#34; data-url=&#34;https://drive.google.com/file/d/1BexrNmdqYhKPkqD_Y81qNAUeyfzl-ZtO/view&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://drive.google.com/file/d/1BexrNmdqYhKPkqD_Y81qNAUeyfzl-ZtO/view&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail blogcard-thumbnail-placeholder&#34;&gt;
      &lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 24 24&#34; fill=&#34;none&#34; stroke=&#34;currentColor&#34; stroke-width=&#34;2&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;&gt;
        &lt;path d=&#34;M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71&#34;&gt;&lt;/path&gt;
        &lt;path d=&#34;M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71&#34;&gt;&lt;/path&gt;
      &lt;/svg&gt;
    &lt;/div&gt;&lt;div class=&#34;blogcard-content&#34;&gt;
      &lt;div class=&#34;blogcard-title&#34;&gt;lecture 8.pdf&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://drive.google.com/file/d/1BexrNmdqYhKPkqD_Y81qNAUeyfzl-ZtO/view&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
 P73より引用&lt;/p&gt;
&lt;h2 id=&#34;第9章-高水準言語&#34;&gt;第9章 高水準言語&lt;/h2&gt;
&lt;p&gt;第10章、第11章でコンパイラを実装するJackの言語仕様を解説した章。&lt;/p&gt;
&lt;p&gt;Javaに近い感じの文法。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Main&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   function &lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;main&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      var Array a&lt;span style=&#34;color:#f92672&#34;&gt;;&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      var &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; length&lt;span style=&#34;color:#f92672&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      var &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; i&lt;span style=&#34;color:#f92672&#34;&gt;,&lt;/span&gt; sum&lt;span style=&#34;color:#f92672&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      let length &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; Keyboard&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;readInt&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;How many numbers? &amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      let a &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; Array&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;new&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;length&lt;span style=&#34;color:#f92672&#34;&gt;);&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;// constructs the array
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;     
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      let i &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;while&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;i &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; length&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         let a&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;i&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; Keyboard&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;readInt&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Enter a number: &amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         let sum &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; sum &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; a&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;i&lt;span style=&#34;color:#f92672&#34;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         let i &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; i &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;do&lt;/span&gt; Output&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;printString&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;The average is &amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;do&lt;/span&gt; Output&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;printInt&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;sum &lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt; length&lt;span style=&#34;color:#f92672&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   &lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;第10章-コンパイラi構文解析&#34;&gt;第10章 コンパイラI：構文解析&lt;/h2&gt;
&lt;p&gt;第10章の内容に入る前にJackのソースコードが実行可能な形式になるまでの流れをおさらいしておく。&lt;/p&gt;

&lt;pre class=&#34;mermaid&#34;&gt;    graph LR
    A[Jackコード&lt;br&gt;e.g. Foo.jack] --&gt;|コンパイラが変換| B[&#34;VMコード(中間コード)&lt;br&gt;e.g. Foo.vm&#34;]
    B --&gt;|VM変換器が変換| C[&#34;機械語(記号表現)&lt;br&gt;e.g. Foo.asm&#34;]
    C --&gt;|アセンブラが変換| D[&#34;機械語(バイナリ表現)&lt;br&gt;e.g. Foo.hack&#34;]
&lt;/pre&gt;

&lt;p&gt;Jackコンパイラは構文解析器とコード生成器からなり構文解析器はトークナイザとパーサ&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;からなる。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;compiler-roadmap.webp&#34; alt=&#34;compiler-roadmap&#34; loading=&#34;lazy&#34; /&gt;
&lt;div class=&#34;blogcard&#34; data-url=&#34;https://drive.google.com/file/d/1CM_w6cxQpYnYHcP-OhNkNU6oD5rMnjzv/view&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://drive.google.com/file/d/1CM_w6cxQpYnYHcP-OhNkNU6oD5rMnjzv/view&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail blogcard-thumbnail-placeholder&#34;&gt;
      &lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 24 24&#34; fill=&#34;none&#34; stroke=&#34;currentColor&#34; stroke-width=&#34;2&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;&gt;
        &lt;path d=&#34;M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71&#34;&gt;&lt;/path&gt;
        &lt;path d=&#34;M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71&#34;&gt;&lt;/path&gt;
      &lt;/svg&gt;
    &lt;/div&gt;&lt;div class=&#34;blogcard-content&#34;&gt;
      &lt;div class=&#34;blogcard-title&#34;&gt;lecture 10.pdf&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://drive.google.com/file/d/1CM_w6cxQpYnYHcP-OhNkNU6oD5rMnjzv/view&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
 P4より引用&lt;/p&gt;
&lt;p&gt;トークナイザはソースコードをトークンと呼ばれる「プログラムにおいて意味を持つコードの最小単位」に変換する処理を担う。&lt;/p&gt;
&lt;p&gt;トークンのような表現に変換してからパースを行うことでプログラムの複雑性を軽減することができる。&lt;/p&gt;
&lt;p&gt;例として以下のJack言語のコードのトークン列をXMLで表記すると以下のようになる。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Main&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;static&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;boolean&lt;/span&gt; test&lt;span style=&#34;color:#f92672&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    function &lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;main&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;do&lt;/span&gt; Output&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;printString&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Hello world!&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-xml&#34; data-lang=&#34;xml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;class&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;keyword&amp;gt;&lt;/span&gt; class &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/keyword&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;identifier&amp;gt;&lt;/span&gt; Main &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/identifier&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;symbol&amp;gt;&lt;/span&gt; { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/symbol&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;classVarDec&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;keyword&amp;gt;&lt;/span&gt; static &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/keyword&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;keyword&amp;gt;&lt;/span&gt; boolean &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/keyword&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;identifier&amp;gt;&lt;/span&gt; test &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/identifier&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;symbol&amp;gt;&lt;/span&gt; ; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/symbol&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/classVarDec&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;subroutineDec&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;keyword&amp;gt;&lt;/span&gt; function &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/keyword&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;keyword&amp;gt;&lt;/span&gt; void &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/keyword&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;identifier&amp;gt;&lt;/span&gt; main &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/identifier&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;symbol&amp;gt;&lt;/span&gt; ( &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/symbol&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;parameterList&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/parameterList&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;symbol&amp;gt;&lt;/span&gt; ) &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/symbol&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;subroutineBody&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;symbol&amp;gt;&lt;/span&gt; { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/symbol&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;statements&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;doStatement&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;keyword&amp;gt;&lt;/span&gt; do &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/keyword&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;identifier&amp;gt;&lt;/span&gt; Output &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/identifier&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;symbol&amp;gt;&lt;/span&gt; . &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/symbol&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;identifier&amp;gt;&lt;/span&gt; printString &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/identifier&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;symbol&amp;gt;&lt;/span&gt; ( &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/symbol&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;expressionList&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;expression&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;term&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;stringConstant&amp;gt;&lt;/span&gt; Hello world! &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/stringConstant&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/term&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/expression&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/expressionList&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;symbol&amp;gt;&lt;/span&gt; ) &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/symbol&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;symbol&amp;gt;&lt;/span&gt; ; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/symbol&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/doStatement&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;returnStatement&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;keyword&amp;gt;&lt;/span&gt; return &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/keyword&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;symbol&amp;gt;&lt;/span&gt; ; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/symbol&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/returnStatement&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/statements&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;symbol&amp;gt;&lt;/span&gt; } &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/symbol&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/subroutineBody&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/subroutineDec&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;symbol&amp;gt;&lt;/span&gt; } &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/symbol&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/class&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;パーサはトークン列を言語の構文ルールに照らし合わせその構造を構文上の要素に変換する処理を担う。&lt;/p&gt;
&lt;p&gt;ここでは再帰下降構文解析というアルゴリズムを使って構文解析を行った。&lt;/p&gt;
&lt;p&gt;ちなみに、Jack言語の構文は次のように定義されている。簡単な部類の言語とはいえ実装量はこれまでの課題と比べると多めだった。趣味でCコンパイラを書く人をたまにTwitterで見かけたりするがすごいなぁという気持ちになった。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;jack-grammer.webp&#34; alt=&#34;jack-grammer&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;第11章-コンパイラiiコード生成&#34;&gt;第11章 コンパイラII：コード生成&lt;/h2&gt;
&lt;p&gt;第11章では、コード生成器を実装する。具体的には構文解析した結果をもとにVMコードを生成する。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;compiler-roadmap.webp&#34; alt=&#34;compiler-roadmap&#34; loading=&#34;lazy&#34; /&gt;
&lt;div class=&#34;blogcard&#34; data-url=&#34;https://drive.google.com/file/d/1CM_w6cxQpYnYHcP-OhNkNU6oD5rMnjzv/view&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://drive.google.com/file/d/1CM_w6cxQpYnYHcP-OhNkNU6oD5rMnjzv/view&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail blogcard-thumbnail-placeholder&#34;&gt;
      &lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 24 24&#34; fill=&#34;none&#34; stroke=&#34;currentColor&#34; stroke-width=&#34;2&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;&gt;
        &lt;path d=&#34;M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71&#34;&gt;&lt;/path&gt;
        &lt;path d=&#34;M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71&#34;&gt;&lt;/path&gt;
      &lt;/svg&gt;
    &lt;/div&gt;&lt;div class=&#34;blogcard-content&#34;&gt;
      &lt;div class=&#34;blogcard-title&#34;&gt;lecture 10.pdf&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://drive.google.com/file/d/1CM_w6cxQpYnYHcP-OhNkNU6oD5rMnjzv/view&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
 P4より引用&lt;/p&gt;
&lt;p&gt;一般的には&lt;strong&gt;ソースコードをVMコードに変換する層をフロントエンド&lt;/strong&gt;、&lt;strong&gt;VMコードを機械語に変換する層をバックエンド&lt;/strong&gt;と呼ぶらしい。本書では第10章と第11章の内容がフロントエンドに、第6章~第8章の内容がバックエンドに該当する、と言えそう。&lt;/p&gt;
&lt;h3 id=&#34;シンボルテーブル&#34;&gt;シンボルテーブル&lt;/h3&gt;
&lt;p&gt;コンパイラが&lt;code&gt;let y = foo(x);&lt;/code&gt;のような文に遭遇するたびに&lt;code&gt;x&lt;/code&gt;, &lt;code&gt;y&lt;/code&gt;が何を表しているのかを知る必要がある。&lt;/p&gt;
&lt;p&gt;Jackではクラススコープとサブルーチンスコープの2つのスコープがある。クラススコープの変数にはフィールド変数、スタティック変数の2種類があり、サブルーチンスコープの変数にはローカル変数、引数の2種類がある。&lt;/p&gt;
&lt;p&gt;ここではこれらの変数の情報は&lt;strong&gt;シンボルテーブル&lt;/strong&gt;と呼ばれるデータ構造に格納することで管理する手法が紹介されていた。シンボルテーブルは変数の名前、型、スコープ、種類、インデックスを保持する。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;symbol-table.webp&#34; alt=&#34;symbol-table&#34; loading=&#34;lazy&#34; /&gt;
&lt;div class=&#34;blogcard&#34; data-url=&#34;https://drive.google.com/file/d/1CYOcXKxfAwRHaOERvoyuNKSwdlxMo_e3/view&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://drive.google.com/file/d/1CYOcXKxfAwRHaOERvoyuNKSwdlxMo_e3/view&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail blogcard-thumbnail-placeholder&#34;&gt;
      &lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 24 24&#34; fill=&#34;none&#34; stroke=&#34;currentColor&#34; stroke-width=&#34;2&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;&gt;
        &lt;path d=&#34;M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71&#34;&gt;&lt;/path&gt;
        &lt;path d=&#34;M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71&#34;&gt;&lt;/path&gt;
      &lt;/svg&gt;
    &lt;/div&gt;&lt;div class=&#34;blogcard-content&#34;&gt;
      &lt;div class=&#34;blogcard-title&#34;&gt;lecture 11.pdf&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://drive.google.com/file/d/1CYOcXKxfAwRHaOERvoyuNKSwdlxMo_e3/view&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
 P6より引用&lt;/p&gt;
&lt;p&gt;Jackではクラススコープとサブルーチンスコープの2つのスコープがあるのでそれぞれ別のシンボルテーブルを保持する必要がある。Jackでは内側のスコープが外側のスコープよりも優先されるため、コンパイラは&lt;code&gt;x&lt;/code&gt;という変数に出会ったときにまずサブルーチンスコープのシンボルテーブルを検索し、見つからなければクラススコープのシンボルテーブルを検索する。&lt;/p&gt;
&lt;h3 id=&#34;コンストラクタのコンパイル&#34;&gt;コンストラクタのコンパイル&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;特定のクラス型の変数を宣言する。e.g. &lt;code&gt;var Point p&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;クラスのコンストラクタを呼び出して実際にインスタンス化する。 e.g. &lt;code&gt;let p = Point.new(2, 3)&lt;/code&gt;
&lt;ol&gt;
&lt;li&gt;新しい&lt;code&gt;Point&lt;/code&gt;インスタンスを表現するために必要な2ワード分のメモリブロックをヒープ上に確保する&lt;/li&gt;
&lt;li&gt;確保された2ワードがコンストラクタの引数として与えられた&lt;code&gt;2&lt;/code&gt;と&lt;code&gt;3&lt;/code&gt;で初期化される&lt;/li&gt;
&lt;li&gt;pに新しく確保したメモリブロックのベースアドレスを割り当てる&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;実装自体が難しいというケースは少なかったが、純粋にVM変換器の仕様を忘れて思い出すのに時間がかかったりしたので可能な方は時間を開けずにやると思い出しにかかるコストを減らせておすすめです。&lt;/p&gt;
&lt;h2 id=&#34;第12章-os&#34;&gt;第12章 OS&lt;/h2&gt;
&lt;p&gt;第12章では最小限のOSを実装した。&lt;/p&gt;
&lt;p&gt;ここではOSは以下の役割を果たす。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ハードウェア操作の抽象化&lt;/li&gt;
&lt;li&gt;Jack言語でよく使われる処理を関数/メソッドとして提供&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;それぞれ具体的には次のようなクラスによって実現されている。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ハードウェア操作の抽象化
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Output&lt;/code&gt;クラス: &lt;code&gt;printString&lt;/code&gt;, &lt;code&gt;println&lt;/code&gt;などのスクリーンへのテキストの書き込み処理を提供&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Screen&lt;/code&gt;クラス: &lt;code&gt;drawLine&lt;/code&gt;, &lt;code&gt;drawCircle&lt;/code&gt;などのスクリーンへの図形の書き込みを処理を提供&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Keyboard&lt;/code&gt;クラス: &lt;code&gt;keyPressed&lt;/code&gt;, &lt;code&gt;readLine&lt;/code&gt;などのキーボードからの入力の読み取り処理を提供&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Memory&lt;/code&gt;クラス: &lt;code&gt;alloc&lt;/code&gt;, &lt;code&gt;deAlloc&lt;/code&gt;, &lt;code&gt;peek&lt;/code&gt;, &lt;code&gt;poke&lt;/code&gt;などのメモリアクセス処理を提供&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Sys&lt;/code&gt;クラス: プログラム実行に必要な処理の提供&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Jack言語でよく使われる処理を関数/メソッドとして提供
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Math&lt;/code&gt;クラス: &lt;code&gt;abs&lt;/code&gt;, &lt;code&gt;devide&lt;/code&gt;などの基本的な算術演算を提供&lt;/li&gt;
&lt;li&gt;&lt;code&gt;String&lt;/code&gt;クラス: 文字列データ型と&lt;code&gt;length&lt;/code&gt;, &lt;code&gt;setCharAt&lt;/code&gt;などの関連処理を提供&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Array&lt;/code&gt;クラス: 配列の初期化とメモリの解放を行う機能を提供&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;この章ではこれまでまったく意識したことがなかったメモリ操作によってハードウェアを制御するという経験が得られた。クラスインスタンスの初期化のためにメモリから任意の大きさの空き領域を探して確保する処理や、2点の座標が与えられたときにそれらを結ぶ直線をスクリーン上に描画する処理など。想像に難くない通り、基本的にかなり泥臭い実装が多かったがその泥臭さを吸収するための層でもあるので仕方ないとは思う。&lt;/p&gt;
&lt;p&gt;その過程でメモリ操作やビットを扱う処理に少し慣れられたのは大きな収穫の1つだった。普段のWeb開発ではbit演算やメモリ操作をする機会はなかなかないので貴重な経験だった。&lt;/p&gt;
&lt;p&gt;軽く調べた感じでは、現実世界では(Linuxでは)システムコールやデバイスドライバがそれらを担っているらしい。&lt;/p&gt;
&lt;p&gt;実装に関しては整数型のオーバーフローが原因で数時間費やしてしまった。&lt;a href=&#34;https://blog.kyu08.com/posts/cs50-jp/#%E5%AD%A6%E3%81%B3%E3%82%84%E5%BE%97%E3%81%9F%E3%82%82%E3%81%AE&#34; target=&#34;_blank&#34; &gt;CS50でC言語で課題を解いていたときも同様のハマり&lt;/a&gt;があったのであるあるかもしれない。普段書いている言語は簡単にオーバーフローしなかったり場合によっては静的解析で指摘してくれたりするのでなかなか気付くことができなかった。&lt;/p&gt;
&lt;h2 id=&#34;学び得た経験&#34;&gt;学び、得た経験&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;普段はWebアプリケーションばかり触っているので、それよりも数段下のレイヤーの解像度を上げることができた。今後新しい知識の習得やトラブルシューティングがスムーズになるといいなと思う。
&lt;ul&gt;
&lt;li&gt;あとは普段触っているソフトウェア、ハードウェアの仕組みを知ることができて純粋に楽しかった。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;難しい概念に出会ったときに「順を追って理解を整理したり、労を惜しまずに手を動かしていけばきっと体得できるはず」という感覚を持てるようになった。
&lt;ul&gt;
&lt;li&gt;自分のコンピュータサイエンスの知識と経験が薄いのもあり、本書を通して未知の概念とのたくさんの出会いがあった。&lt;/li&gt;
&lt;li&gt;まったく知らない概念でも、順を追って理解を進めて手を動かすことで知識を自分のものにすることができた。その過程で未知の技術に対する恐れや及び腰になる感覚が減った。&lt;/li&gt;
&lt;li&gt;余談だが、大学受験のときにセンター試験の数2Bで一見すると難しそうな問題が出ることが多いように感じていて「いけるいける難しくない落ち着いて考えればわかる」と何回も念じながら問題文を読んでいたのを思い出した。「難しそう」と考えるよりも「わかりそう」とか「なんかいけそう」みたいな方向性のマインドを持っていたほうがパフォーマンスも高くなるなーと改めて思うなどした。&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;難しい課題も小さい部分に分割して段階的に進めるとうまくいくことを実感できた。
&lt;ul&gt;
&lt;li&gt;0からコンパイラを実装するのは気が引けるが、仕組みを理解していくつかの部品に分解して進めることで、複雑なソフトウェアを着実に構築する経験を得ることができた。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;コンパイラやアセンブラの実装で泥臭い処理をたくさん書いたおかげで泥臭さへの耐性が多少ついた。そもそも複雑なものは実装も複雑になりうるのでそういうケースでは特に実装力が大事だなーと思うなどした。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;おわりに&#34;&gt;おわりに&lt;/h2&gt;
&lt;p&gt;『Goならわかるシステムプログラミング』を読んでからかなり気になっていた本だったので無事完走できてよかった。&lt;/p&gt;
&lt;p&gt;最近のテーマであるCS力の強化をまた一歩進めることができた。&lt;/p&gt;
&lt;p&gt;次は&lt;a href=&#34;https://www.sbcr.jp/product/4815618599/&#34; target=&#34;_blank&#34; &gt;『体験しながら学ぶ ネットワーク技術入門』&lt;/a&gt;でネットワークの理解を深めていこうかなと思う。&lt;/p&gt;
&lt;p&gt;あとはソフトスキル系でいうと&lt;a href=&#34;https://www.oreilly.co.jp/books/9784814401116/&#34; target=&#34;_blank&#34; &gt;『エンジニアリングチームのリード術-―Googleに学ぶインディビジュアルコントリビューターとマネージャーのための実践ガイド』&lt;/a&gt;も良さそうなので読んでみようと思う。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;実際はテトリスではなく別のブロック崩しのようなゲームではある&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;Twitterを見ているとパーザと表記する流派も存在する模様&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;近い話が&lt;a href=&#34;https://blog.3qe.us/entry/2025/01/15/194843&#34; target=&#34;_blank&#34; &gt;何かがそれほど得意でなくても、世の中の平均よりは得意だと思っておいたほうがよい - Lambdaカクテル&lt;/a&gt;で綺麗に言語化されている。&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</content>
    </item>
    
    <item>
      <title>『Goならわかるシステムプログラミング 第2版』を読んだ</title>
      <link>https://blog.kyu08.com/pr-344/posts/go-system-programming/</link>
      <pubDate>Sun, 03 Nov 2024 12:42:30 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/pr-344/posts/go-system-programming/</guid>
      <description>『Goならわかるシステムプログラミング第2版』をサンプルコードを手元で実行しつつ一通り読んだ。(期間としては2024/6/8 ~ 2024/11</description>
      <content>&lt;p&gt;&lt;img src=&#34;./book.webp&#34; alt=&#34;book&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;『Goならわかるシステムプログラミング第2版』をサンプルコードを手元で実行しつつ一通り読んだ。(期間としては2024/6/8 ~ 2024/11/4でコミットした日数としてはおおよそ24日ほどだった。)&lt;/p&gt;
&lt;p&gt;筆者は情報系の学部を出ておらず、CSなどの基礎知識があまりないので大変勉強になった。また、サンプルコードが豊富なので実際に自分のマシン上で動かしながら学ぶことができ解像度を上げながら理解を深めることができた。&lt;/p&gt;
&lt;p&gt;低レイヤ、コンピューターサイエンスの学習に興味がある方にはとてもおすすめなのでぜひ買って読んでみてください。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://www.lambdanote.com/products/go-2&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://www.lambdanote.com/products/go-2&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail&#34;&gt;
      &lt;img src=&#34;http://www.lambdanote.com/cdn/shop/products/web-asset-1_1024x1024.jpg?v=1647933491&#34; alt=&#34;Goならわかるシステムプログラミング 第2版&#34; loading=&#34;lazy&#34;&gt;
    &lt;/div&gt;&lt;div class=&#34;blogcard-content&#34;&gt;
      &lt;div class=&#34;blogcard-title&#34;&gt;Goならわかるシステムプログラミング 第2版&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;Go言語による新時代のコンピュータシステム入門 渋川よしき 著 424ページ A5判 ISBN：978-4-908686-12-2 2022年3月23日 第2版第1刷 発行 いつも開発に使っている言語やライブラリの裏側は、いったいどうなっ&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://www.lambdanote.com/products/go-2&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;手元で実行したコードは以下のリポジトリにまとめた。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://github.com/kyu08/go-system-programming&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://github.com/kyu08/go-system-programming&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail&#34;&gt;
      &lt;img src=&#34;https://opengraph.githubassets.com/355ab1c4f0743bcf245b84b5a33ead3e075d2b755c79cbdc43e5e554867af726/kyu08/go-system-programming&#34; alt=&#34;GitHub - kyu08/go-system-programming: 『Goならわかるシステムプログラミング』の写経リポジトリ&#34; loading=&#34;lazy&#34;&gt;
    &lt;/div&gt;&lt;div class=&#34;blogcard-content&#34;&gt;
      &lt;div class=&#34;blogcard-title&#34;&gt;GitHub - kyu08/go-system-programming: 『Goならわかるシステムプログラミング』の写経リポジトリ&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;『Goならわかるシステムプログラミング』の写経リポジトリ. Contribute to kyu08/go-system-programming development by creating an account on GitHub.&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://github.com/kyu08/go-system-programming&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;以下読書メモ。&lt;/p&gt;
&lt;h2 id=&#34;第1章-go言語で覗くシステムプログラミングの世界&#34;&gt;第1章 Go言語で覗くシステムプログラミングの世界&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;デバッガを使って&lt;code&gt;fmt.Println&lt;/code&gt;の動作をシステムコールまで追った。&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;当然だがデバッガを使うと変数の中身に何が入ってるかがわかって便利。&lt;/li&gt;
&lt;li&gt;デバッガを使ってみて別パッケージのprivate変数の中身を見ることができるのはプリントデバッグにはないデバッガの利点だと気づいた。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;第2章-低レベルアクセスへの入口1iowriter&#34;&gt;第2章 低レベルアクセスへの入口1：io.Writer&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;io.Writer&lt;/code&gt;はOSが持つファイルのシステムコールの相似形&lt;/li&gt;
&lt;li&gt;OSでは、システムコールを&lt;strong&gt;ファイルディスクリプタ&lt;/strong&gt;と呼ばれるものに対して呼ぶ。&lt;/li&gt;
&lt;li&gt;ファイルディスクリプタ(file descriptor)は一種の識別子（数値）で、この数値を指定してシステムコールを呼び出すと、数値に対応するモノへとアクセスできる。&lt;/li&gt;
&lt;li&gt;ファイルディスクリプタはOSがカーネルのレイヤーで用意している抽象化の仕組み。&lt;/li&gt;
&lt;li&gt;OSのカーネル内部のデータベースに、プロセスごとに実体が用意される。&lt;/li&gt;
&lt;li&gt;OSはプロセスが起動されるとまず3つの擬似ファイルを作成し、それぞれにファイルディスクリプタを割り当てる。
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0&lt;/code&gt;が標準入力、&lt;code&gt;1&lt;/code&gt;が標準出力、&lt;code&gt;2&lt;/code&gt;が標準エラー出力。&lt;/li&gt;
&lt;li&gt;以降はそのプロセスでファイルをオープンしたりソケットをオープンしたりするたびに1ずつ大きな数値が割り当てられていく。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;複数のファイル&lt;code&gt;f1&lt;/code&gt;, &lt;code&gt;f2&lt;/code&gt;を&lt;code&gt;os.Create()&lt;/code&gt;する処理をデバッガーで追ってみたところ、それぞれファイルディスクリプタの値が&lt;code&gt;3&lt;/code&gt;, &lt;code&gt;4&lt;/code&gt;&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;となっておりファイルディスクリプタの値が&lt;code&gt;3&lt;/code&gt;からインクリメントされる様子を確認できた。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;delve-neovim.webp&#34; alt=&#34;delve-neovim.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;第3章-低レベルアクセスへの入口1ioreader&#34;&gt;第3章 低レベルアクセスへの入口1：io.Reader&lt;/h2&gt;
&lt;h3 id=&#34;エンディアン変換&#34;&gt;エンディアン変換&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;リトルエンディアンでは、10000という数値(&lt;code&gt;0x2710&lt;/code&gt;)をメモリに格納するとき下位バイトから順に格納する。&lt;/li&gt;
&lt;li&gt;ビッグエンディアンでは、上位バイトから順に格納する。&lt;/li&gt;
&lt;li&gt;現在主流のCPUではリトルエンディアンが採用されている。&lt;/li&gt;
&lt;li&gt;ネットワーク上で転送されるデータの多くはビッグエンディアンが用いられている。&lt;/li&gt;
&lt;li&gt;そのため多くの環境ではネットワークで受け取ったデータをリトルエンディアンに変換する必要がある。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;ioパッケージのいくつかの関数--構造体--インターフェースの使い方&#34;&gt;&lt;code&gt;io&lt;/code&gt;パッケージのいくつかの関数 / 構造体 / インターフェースの使い方&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;io.Pipe&lt;/code&gt;&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;io.LimitReader&lt;/code&gt;: 先頭の&lt;code&gt;n&lt;/code&gt;バイトだけ読み込む&lt;/li&gt;
&lt;li&gt;&lt;code&gt;io.MultiReader&lt;/code&gt;: 複数の&lt;code&gt;io.Reader&lt;/code&gt;を1つの&lt;code&gt;io.Reader&lt;/code&gt;にまとめる&lt;/li&gt;
&lt;li&gt;&lt;code&gt;io.SectionReader&lt;/code&gt;: &lt;code&gt;offset&lt;/code&gt;と&lt;code&gt;n&lt;/code&gt;を指定して一部のデータだけ読み込む&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;第4章-チャネル&#34;&gt;第4章 チャネル&lt;/h2&gt;
&lt;p&gt;普段goroutineを全然使わないので忘れていることが多かった。以下学んだことメモ。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;バッファなしチャネルでは、受け取り側が受信しないと、送信側もブロックされる。&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;for task := range tasks // tasksは任意のch&lt;/code&gt;のように書くと、チャネルに値が入るたびにループが回り、チャネルがクローズされるまでループが回る。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;第5章-システムコール&#34;&gt;第5章 システムコール&lt;/h2&gt;
&lt;p&gt;システムコールとは特権モードでOSの機能を呼ぶこと。&lt;/p&gt;
&lt;h3 id=&#34;cpuの動作モード&#34;&gt;CPUの動作モード&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;OSの仕事は以下の2つ
&lt;ul&gt;
&lt;li&gt;各種資源（メモリ、CPU時間、ストレージなど）の管理&lt;/li&gt;
&lt;li&gt;外部入出力機能の提供（ネットワーク、ファイル読み書き、プロセス間通信）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;動作モード
&lt;ul&gt;
&lt;li&gt;実行してよいハードウェアとしての機能がソフトウェアの種類に応じて制限されている&lt;/li&gt;
&lt;li&gt;OSが動作する特権モード&lt;/li&gt;
&lt;li&gt;一般的なアプリケーションが動作するユーザーモード&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;システムコールが必要な理由&#34;&gt;システムコールが必要な理由&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;通常のアプリケーションでメモリ割り当てやファイル入出力、インターネット通信などの機能を使うために必要なのがシステムコール&lt;/li&gt;
&lt;li&gt;システムコールがなくてもCPUの命令そのものはほとんど使うことができる&lt;/li&gt;
&lt;li&gt;しかし、ユーザーモードでは計算した結果を画面に出力したり、ファイルに保存したり外部のWebサービスに送信したりできない。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;dtruss&lt;/code&gt;コマンドを使ってシステムコールの呼び出しを確認しようとしたがmacOSのセキュリティの設定上何も表示されなかったのでDocker上でLinuxを起動して確認してみることにした。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker run -it --name stracetest golang:1.22.4-alpine3.19
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;apk add strace
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;go mod init kyu08/stracetest
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 任意のgoファイルを作成&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;go build ./...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;strace -o strace.log ./実行ファイル
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;less strace.log
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;今回は&lt;code&gt;f, _ := os.Create(&amp;quot;test_file.txt&amp;quot;)&lt;/code&gt;と&lt;code&gt;defer f.Close()&lt;/code&gt;を実行するだけのgoプログラムを実行したときのシステムコールのログを確認した。以下はその一部。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;rt_sigaction&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;SIGRT_32, &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;sa_handler&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;0x70d90, sa_mask&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;~&lt;span style=&#34;color:#f92672&#34;&gt;[]&lt;/span&gt;, sa_flags&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;SA_ONSTACK|SA_RESTART|SA_SIGINFO&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;, NULL, 8&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;rt_sigprocmask&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;SIG_SETMASK, ~&lt;span style=&#34;color:#f92672&#34;&gt;[]&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;[]&lt;/span&gt;, 8&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;clone&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;child_stack&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;0x400001c000, flags&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;890&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;rt_sigprocmask&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;SIG_SETMASK, &lt;span style=&#34;color:#f92672&#34;&gt;[]&lt;/span&gt;, NULL, 8&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;--- SIGURG &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;si_signo&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;SIGURG, si_code&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;SI_TKILL, si_pid&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;889, si_uid&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;0&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt; ---
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;rt_sigreturn&lt;span style=&#34;color:#f92672&#34;&gt;({&lt;/span&gt;mask&lt;span style=&#34;color:#f92672&#34;&gt;=[]})&lt;/span&gt;                 &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1139696&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;rt_sigprocmask&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;SIG_SETMASK, ~&lt;span style=&#34;color:#f92672&#34;&gt;[]&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;[]&lt;/span&gt;, 8&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;clone&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;child_stack&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;0x4000062000, flags&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;891&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;rt_sigprocmask&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;SIG_SETMASK, &lt;span style=&#34;color:#f92672&#34;&gt;[]&lt;/span&gt;, NULL, 8&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;futex&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;0x4000080148, FUTEX_WAKE_PRIVATE, 1&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;futex&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;0x4000048948, FUTEX_WAKE_PRIVATE, 1&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;prlimit64&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;0, RLIMIT_NOFILE, NULL, &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;rlim_cur&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;1024*1024, rlim_max&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;1024*1024&lt;span style=&#34;color:#f92672&#34;&gt;})&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;fcntl&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;0, F_GETFL&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;                       &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; 0x20002 &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;flags O_RDWR|O_LARGEFILE&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;futex&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;0x4000049148, FUTEX_WAKE_PRIVATE, 1&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;fcntl&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;1, F_GETFL&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;                       &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; 0x20002 &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;flags O_RDWR|O_LARGEFILE&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;fcntl&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;2, F_GETFL&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;                       &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; 0x20002 &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;flags O_RDWR|O_LARGEFILE&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;openat&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;AT_FDCWD, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;test_file.txt&amp;#34;&lt;/span&gt;, O_RDWR|O_CREAT|O_TRUNC|O_CLOEXEC, 0666&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;futex&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;0x115ea0, FUTEX_WAKE_PRIVATE, 1&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;futex&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;0x115db8, FUTEX_WAKE_PRIVATE, 1&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;fcntl&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;3, F_GETFL&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;                       &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; 0x20002 &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;flags O_RDWR|O_LARGEFILE&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;fcntl&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;3, F_SETFL, O_RDWR|O_NONBLOCK|O_LARGEFILE&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;epoll_create1&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;EPOLL_CLOEXEC&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;            &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;pipe2&lt;span style=&#34;color:#f92672&#34;&gt;([&lt;/span&gt;5, 6&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;, O_NONBLOCK|O_CLOEXEC&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;     &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;epoll_ctl&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;4, EPOLL_CTL_ADD, 5, &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;events&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;EPOLLIN, data&lt;span style=&#34;color:#f92672&#34;&gt;={&lt;/span&gt;u32&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;1549912, u64&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;1549912&lt;span style=&#34;color:#f92672&#34;&gt;}})&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;epoll_ctl&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;4, EPOLL_CTL_ADD, 3, &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;events&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;EPOLLIN|EPOLLOUT|EPOLLRDHUP|EPOLLET, data&lt;span style=&#34;color:#f92672&#34;&gt;={&lt;/span&gt;u32&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;3997171713, u64&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;18446585726557487105&lt;span style=&#34;color:#f92672&#34;&gt;}})&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; -1 EPERM &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;Operation not permitted&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;fcntl&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;3, F_GETFL&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;                       &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; 0x20802 &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;flags O_RDWR|O_NONBLOCK|O_LARGEFILE&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;fcntl&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;3, F_SETFL, O_RDWR|O_LARGEFILE&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;   &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;close&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;3&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;                                &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;exit_group&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;0&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;                           &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; ?
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;+++ exited with &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; +++
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;openat(AT_FDCWD, &amp;quot;test_file.txt&amp;quot;, O_RDWR|O_CREAT|O_TRUNC|O_CLOEXEC, 0666) = 3&lt;/code&gt;の部分でファイルが作成され、ファイルディスクリプタに&lt;code&gt;3&lt;/code&gt;が割り当ている&lt;/li&gt;
&lt;li&gt;&lt;code&gt;close(3)                                = 0&lt;/code&gt;の部分で&lt;code&gt;defer f.Close()&lt;/code&gt;に相当する処理が行われている&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ということを確認できた。&lt;/p&gt;
&lt;h2 id=&#34;第6章-tcpソケットとhttpの実装&#34;&gt;第6章 TCPソケットとHTTPの実装&lt;/h2&gt;
&lt;h3 id=&#34;ソケットとは&#34;&gt;ソケットとは&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ほとんどのOSではアプリケーション層からトランスポート層のプロトコルを利用するときのAPIとして&lt;strong&gt;ソケット&lt;/strong&gt;という仕組みを利用している&lt;/li&gt;
&lt;li&gt;HTTP/1.0と1.1はこのソケットのバイトストリーム上に作られたテキストを使ったプロトコル&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;ソケットの種類本書で説明するもののみ&#34;&gt;ソケットの種類（本書で説明するもののみ）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;TCP：一番使われている。安定性が高い。&lt;/li&gt;
&lt;li&gt;UDP：通信開始が早い。相手に一方的に送りつける。&lt;/li&gt;
&lt;li&gt;Unixドメインソケット：ローカル通信でしか使えないが最速。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;ソケット通信の基本構造&#34;&gt;ソケット通信の基本構造&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;どんなソケット通信も基本となる構成は次のような形態
&lt;ul&gt;
&lt;li&gt;サーバー：ソケットを開いて待ち受ける&lt;/li&gt;
&lt;li&gt;クライアント：開いているソケットに接続し、通信する&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;GoではTCP通信が確立されると、送信側、受信側の両方に相手との通信する&lt;code&gt;net.Conn&lt;/code&gt;インタフェースを満たすオブジェクトが渡ってくる&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;goに組み込まれているtcpの機能netconnだけを使ってhttpによる通信を実現する&#34;&gt;Goに組み込まれているTCPの機能（&lt;code&gt;net.Conn&lt;/code&gt;）だけを使ってHTTPによる通信を実現する&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;net.Conn&lt;/code&gt;だけを使ってTCPソケットの初期化や通信の確立などの普段なら&lt;code&gt;net/http&lt;/code&gt;がやってくれている部分を実装した。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;http.ListenAndServe()&lt;/code&gt;のコードを読んでみたら、&lt;a href=&#34;https://github.com/golang/go/blob/c83b1a7013784098c2061ae7be832b2ab7241424/src/net/http/server.go#L3258&#34; target=&#34;_blank&#34; &gt;golang/go/src/net/http/server.go#L3258&lt;/a&gt;で本書のハンズオンと同じようにTCPソケットの初期化を行っていることを確認できた。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;素朴な実装の速度改善&#34;&gt;素朴な実装の速度改善&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;①Keep-Aliveへの対応
&lt;ul&gt;
&lt;li&gt;HTTP/1.1から入った規格&lt;/li&gt;
&lt;li&gt;HTTP/1.0ではセットの通信が終わるたびにTCPコネクションが切れる仕様になっていたが、Keep-Aliveを使うことで、しばらくの間はTCP接続のコネクションを維持して使い回すことができる。&lt;/li&gt;
&lt;li&gt;TCP接続の通信には一定のオーバーヘッドがあるが、Keep-Aliveを使うことでそのオーバーヘッドを削減できる。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;②レスポンスの圧縮
&lt;ul&gt;
&lt;li&gt;レスポンスを圧縮することで、通信量を削減でき速度向上につながる。&lt;/li&gt;
&lt;li&gt;レスポンスヘッダーは圧縮されないため、少量のデータを通信する場合は効率が悪くなる。そのため実際のデータ量に応じて圧縮するかどうかを判断する必要がありそう。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;③チャンク形式のボディー送信
&lt;ul&gt;
&lt;li&gt;動画など大きいデータを送信する場合、データを分割して送信することでデータの送信が完了する前に受信側でデータを処理できるようになる。また、すべてのデータをメモリに展開する必要もなくなるのでメモリの使用量を抑えることができるというメリットもある。&lt;/li&gt;
&lt;li&gt;チャンク形式ではヘッダーに送信データのサイズを書かないかわりに&lt;code&gt;Transfer-Encoding: chunked&lt;/code&gt;というヘッダーを付与する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;④パイプライニング
&lt;ul&gt;
&lt;li&gt;送受信を非同期化する方法&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;第7章-udpソケットを使ったマルチキャスト通信&#34;&gt;第7章 UDPソケットを使ったマルチキャスト通信&lt;/h2&gt;
&lt;h3 id=&#34;udpとtcpの用途の違い&#34;&gt;UDPとTCPの用途の違い&lt;/h3&gt;
&lt;p&gt;UDPはTCPと同じトランスポート層のプロトコルで以下のような特徴がある。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;誰と繋がっているか管理しない&lt;/li&gt;
&lt;li&gt;データロスの検知をすることも通信速度の制限をすることもしない&lt;/li&gt;
&lt;li&gt;パケットの到着順序も管理しない&lt;/li&gt;
&lt;li&gt;複数のコンピュータに同時にメッセージを送ることが可能な「マルチキャスト」と「ブロードキャスト」をサポートしている。（TCPにはない機能）&lt;/li&gt;
&lt;li&gt;UDPの利用例としてはDNSやNTP, WebRTCなどがある。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;udpのマルチキャストの実装例&#34;&gt;UDPのマルチキャストの実装例&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;マルチキャストはリクエスト側の負担を増やすことなく多くのクライアントに同時にデータを送信できる仕組み。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;udpとtcpの機能面の違い&#34;&gt;UDPとTCPの機能面の違い&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;TCPには再送処理とフロー処理がある。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;再送処理&#34;&gt;再送処理&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;TCPでは送信するメッセージに&lt;strong&gt;シーケンス番号&lt;/strong&gt;が入っているので、受信側ではこの数値をみることでパケットの順序を管理できる。&lt;/li&gt;
&lt;li&gt;受信側はメッセージを受け取ると、受信したデータの&lt;strong&gt;シーケンス番号&lt;/strong&gt;と&lt;strong&gt;ペイロードサイズの合計&lt;/strong&gt;を確認応答番号として返信する。&lt;/li&gt;
&lt;li&gt;送信側はこの応答確認番号が受け取れなかった場合に再送処理を行う。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;フロー処理&#34;&gt;フロー処理&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;受信側がリソースを用意できていない状態で送信リクエストが集中して通信内容が失われるのを防ぐための仕組みを&lt;strong&gt;ウィンドウ制御&lt;/strong&gt;という。
&lt;ul&gt;
&lt;li&gt;具体的には、受信用のバッファ（ウィンドウ）をあらかじめ決めておき送信側ではそのサイズまでは受信側からの受信確認を待たずにデータを送信できる。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;受信側のデータの読み込みが間に合わない場合には、受信できるウィンドウサイズを受信側から送信側に伝えて通信量を制御できる。これを&lt;strong&gt;フロー制御&lt;/strong&gt;という。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;フレームサイズ&#34;&gt;フレームサイズ&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;UDPレイヤーで取り扱えるデータは約64キロバイトまで。&lt;/li&gt;
&lt;li&gt;UDPではデータの分割などはアプリケーションで面倒を見る必要がある。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;輻輳制御とフェアネス&#34;&gt;輻輳制御とフェアネス&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;輻輳制御&lt;/strong&gt;とは、ネットワークの輻輳（渋滞）を避けるように流量を調整し、そのネットワークの最大効率で通信できるようにするとともに複数の通信をお互いに&lt;strong&gt;フェアに行う&lt;/strong&gt;ための仕組み。&lt;/li&gt;
&lt;li&gt;TCPには輻輳制御が備わっており、そのアルゴリズムにはさまざまな種類がある。&lt;/li&gt;
&lt;li&gt;UDPにはTCPのような輻輳制御の仕組みはなく、流量の制御はUDPを利用する各プログラムに委ねられている。そのため、UDPとTCPを利用するアプリケーションがそれぞれあって、UDPを利用するアプリケーションでフェアネスが考慮されていない場合には、&lt;strong&gt;両方の通信が重なった時に遠慮する機能が組み込まれたTCPの通信速度だけが極端に落ち込む&lt;/strong&gt;こともある。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;第8章-高速なunixドメインソケット&#34;&gt;第8章 高速なUnixドメインソケット&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;UnixドメインソケットはPOSIX系OSで提供されている機能で、コンピュータ内部でしか使えない代わりに高速な通信が可能。&lt;/li&gt;
&lt;li&gt;Unixドメインソケットには、TCP型（ストリーム型）とUDP型（データグラム型）の両方の使い方ができる。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;unixドメインソケットの基本&#34;&gt;Unixドメインソケットの基本&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;TCPとUDPによるソケット通信が外部のネットワークにつながるインターフェースに接続するのに対し、Unixドメインソケットはカーネル内部で完結する高速なネットワークインターフェースを作成する。&lt;/li&gt;
&lt;li&gt;Unixドメインソケットを使うことで、ウェブサーバーとNGINXなどのリバースプロキシとの間、あるいはウェブサーバーとデーターベースとの間の接続を高速にできる場合がある。&lt;/li&gt;
&lt;li&gt;Unixドメインソケットを開くには、ファイルシステムのパスを指定する。サーバープロセスを起動するとファイルシステム上の指定したパスにソケットファイルが作成される。&lt;/li&gt;
&lt;li&gt;Unixドメインソケットで作成されるのはソケットファイルと呼ばれる特殊なファイルであり、通常のファイルのような実体を持たない。あくまでもプロセス間の高速な通信としてファイルというインターフェースを利用するだけ。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;以下はソケットファイルが作成されている様子。ソケットファイルは先頭が&amp;quot;s&amp;quot;で始まる。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;socket-file.webp&#34; alt=&#34;socket-file.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;unixドメインソケットとtcpのベンチマーク&#34;&gt;UnixドメインソケットとTCPのベンチマーク&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Unixドメインソケットを使った実装とTCPを経由した実装のベンチマークの比較をすると筆者の環境だとUnixドメインソケットの方が10倍ほど高速だった。&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ go test -bench . -benchmem
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;goos: darwin
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;goarch: arm64
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;pkg: github.com/kyu08/go-system-programming/bench
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;BenchmarkTCPServer-8                &lt;span style=&#34;color:#ae81ff&#34;&gt;4165&lt;/span&gt;            &lt;span style=&#34;color:#ae81ff&#34;&gt;327038&lt;/span&gt; ns/op           &lt;span style=&#34;color:#ae81ff&#34;&gt;52175&lt;/span&gt; B/op        &lt;span style=&#34;color:#ae81ff&#34;&gt;110&lt;/span&gt; allocs/op
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;BenchmarkUDSStreamServer-8         &lt;span style=&#34;color:#ae81ff&#34;&gt;42742&lt;/span&gt;             &lt;span style=&#34;color:#ae81ff&#34;&gt;27837&lt;/span&gt; ns/op           &lt;span style=&#34;color:#ae81ff&#34;&gt;16762&lt;/span&gt; B/op         &lt;span style=&#34;color:#ae81ff&#34;&gt;59&lt;/span&gt; allocs/op
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;PASS
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ok      github.com/kyu08/go-system-programming/bench    4.788s
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;第9章-ファイルシステムの基礎とgo言語の標準パッケージ&#34;&gt;第9章 ファイルシステムの基礎とGo言語の標準パッケージ&lt;/h2&gt;
&lt;p&gt;この章では&lt;code&gt;os&lt;/code&gt;パッケージと&lt;code&gt;path/filepath&lt;/code&gt;パッケージの主要な関数の使い方が紹介されていた。&lt;/p&gt;
&lt;h3 id=&#34;ファイルディレクトリを扱うgo言語の関数たち&#34;&gt;ファイル/ディレクトリを扱うGo言語の関数たち&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;2つのファイルの同一性の判定: &lt;code&gt;os.Samefile()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;ファイルのパーミッション、オーナー、タイムスタンプの変更: &lt;code&gt;os.Chmod()&lt;/code&gt;, &lt;code&gt;os.Chown&lt;/code&gt;, &lt;code&gt;os.Chtimes()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;ハードリンク、シンボリックリンクの作成: &lt;code&gt;os.Link&lt;/code&gt;, &lt;code&gt;os.Symlink()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;ファイル一覧の取得: &lt;code&gt;dir, _ := os.Open(path)&lt;/code&gt; -&amp;gt; &lt;code&gt;dir.Readdir()&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;os内部におけるファイル操作の高速化&#34;&gt;OS内部におけるファイル操作の高速化&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;CPUにとってディスクの読み書きはとても遅い処理であり、なるべく最後までやらないようにしたい。LinuxではVFSの内部に設けられているバッファを利用することでディスクに対する操作をなるべく回避している。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;pathfilepathパッケージの関数たち&#34;&gt;&lt;code&gt;path/filepath&lt;/code&gt;パッケージの関数たち&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;パスの最後の要素を返す: &lt;code&gt;filepath.Base()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;パスのディレクトリ部分を返す: &lt;code&gt;filepath.Dir()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;パスをディレクトリとパス名に分割する: &lt;code&gt;filepath.Split()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;ファイルの拡張子を返す: &lt;code&gt;filepath.Ext()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/some/../path&lt;/code&gt;や&lt;code&gt;another//path&lt;/code&gt;のような形式のパスを整える: &lt;code&gt;filepath.Clean()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;パターンにマッチするファイルの判定: &lt;code&gt;filepath.Match()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;ディレクトリのトラバース: &lt;code&gt;filepath.Walk()&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;想像よりも標準パッケージでいろんなことができるのでこの辺りの操作をしたくなったら自作関数を書く前に標準パッケージを探してみるのが良さそうだと思った。&lt;/p&gt;
&lt;h2 id=&#34;第10章-ファイルシステムの最深部を扱うgo言語の関数&#34;&gt;第10章 ファイルシステムの最深部を扱うGo言語の関数&lt;/h2&gt;
&lt;h3 id=&#34;ファイルの変更監視syscallinotify&#34;&gt;ファイルの変更監視（&lt;code&gt;syscall.Inotify&lt;/code&gt;）&lt;/h3&gt;
&lt;p&gt;プログラムでファイルを監視する方法には次の2種類がある。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;監視したいファイルをOS側に通知しておいて、変更があったら教えてもらう（パッシブな）方式&lt;/li&gt;
&lt;li&gt;タイマーなどで定期的にフォルダを走査し、&lt;code&gt;os.Stat()&lt;/code&gt;などを使って変更を探しに行く（アクティブな）方式&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;アクティブな方式の方がコード量は少ないが監視対象が増えるとCPU負荷やIO負荷が増える。&lt;/p&gt;
&lt;p&gt;パッシブな方式はファイルの変更検知が各OSでシステムコールやAPUIとして提供されている一方で環境ごとのコード差は大きくなる。&lt;/p&gt;
&lt;p&gt;ここでは &lt;a href=&#34;https://github.com/fsnotify/fsnotify&#34; target=&#34;_blank&#34; &gt;fsnotify/fsnotify.v1&lt;/a&gt;を用いてファイルの変更検知プログラムを作成した。&lt;/p&gt;
&lt;p&gt;fsnotify.v1では、Linuxの場合はinotify系APIが、BSD系OSの場合はkqueueが使われている。&lt;/p&gt;
&lt;h3 id=&#34;ファイルのメモリへのマッピングsyscallmmap&#34;&gt;ファイルのメモリへのマッピング（&lt;code&gt;syscall.Mmap()&lt;/code&gt;）&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;syscall.Mmap()&lt;/code&gt;を使うことでファイルの中身をそのままメモリ上に展開したり、メモリ上で書き換えた内容をそのままファイルに書き込むことができる。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/edsrzf/mmap-go&#34; target=&#34;_blank&#34; &gt;edsrzf/mmap-go&lt;/a&gt;では&lt;code&gt;mmap.Map()&lt;/code&gt;を使うことでファイルをメモリに展開できる。&lt;code&gt;mmap.Map()&lt;/code&gt;は次のようなシグネチャを持つ。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Map&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;f&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;os&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;File&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;prot&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;flags&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt;) (&lt;span style=&#34;color:#a6e22e&#34;&gt;MMap&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;error&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;2つ目の引数に次のような値を指定することでメモリ領域に対して許可する操作を設定できる。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;mmap.RDONLY&lt;/code&gt;: 読み込み専用&lt;/li&gt;
&lt;li&gt;&lt;code&gt;mmap.RDWR&lt;/code&gt;: 読み書き可能&lt;/li&gt;
&lt;li&gt;&lt;code&gt;mmap.EXEC&lt;/code&gt;: 実行可能にする&lt;/li&gt;
&lt;li&gt;&lt;code&gt;mmap.COPY&lt;/code&gt;: コピーオンライト&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;コピーオンライトが指定されると、複数のプロセスが同じファイルをマッピングしているときに、カーネル上は1つ分のみメモリ領域が使用され、それ以上のメモリを消費しない。&lt;/p&gt;
&lt;p&gt;しかし、その領域内でメモリ書き換えが発生すると、その領域がまるごとコピーされる。このようにすることでメモリ消費量をうまく節約できる。&lt;/p&gt;
&lt;h3 id=&#34;同期非同期--ブロッキングノンブロッキング&#34;&gt;同期・非同期 / ブロッキング・ノンブロッキング&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;同期処理: OSにI/Oタスクを投げて、入出力の準備ができたらアプリケーションに処理が返ってくる&lt;/li&gt;
&lt;li&gt;非同期処理: OSにI/Oタスクを投げて、入出力の準備ができたら通知をもらう&lt;/li&gt;
&lt;li&gt;ブロッキング処理: お願いしたI/Oタスクの結果の準備ができるまで待つ（自分は停止）&lt;/li&gt;
&lt;li&gt;ノンブロッキング処理: お願いしたI/Oタスクの結果の準備ができるのを待たない（自分は停止しない）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;select属のシステムコールによるio多重化&#34;&gt;select属のシステムコールによるI/O多重化&lt;/h3&gt;
&lt;p&gt;非同期・ブロッキングは1スレッドでたくさんの入出力を効率よく扱うための手法でありI/O多重化とも呼ばれる。それを効率よく実現するAPIのことを本書では&lt;strong&gt;select属&lt;/strong&gt;と総称する。&lt;/p&gt;
&lt;p&gt;並行処理を使うことで小さい規模のI/Oの効率化は十分に行えるが、select属はC10K問題と呼ばれる、万の単位の入出力を効率よく扱うための手法として有効。&lt;/p&gt;
&lt;h3 id=&#34;第11章-コマンドシェル101&#34;&gt;第11章 コマンドシェル101&lt;/h3&gt;
&lt;p&gt;シェルとは、ユーザーがコンピューターを操作するために使う接点となるシステムにおいてコンピューターシステムの殻（shell）となるプログラムのこと。&lt;/p&gt;
&lt;h4 id=&#34;シェルがないシステム&#34;&gt;シェルがないシステム&lt;/h4&gt;
&lt;p&gt;Distrolessと呼ばれるコンテナイメージはシェルがないため、セキュリティホールをついてシステムに侵入されることがない。&lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt;（当然攻撃の脅威がゼロになるわけではない）&lt;/p&gt;
&lt;h4 id=&#34;シェルがコマンドを起動するまで&#34;&gt;シェルがコマンドを起動するまで&lt;/h4&gt;
&lt;p&gt;シェルがコマンドを起動するまでには次のようなことを行っている。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;ユーザーの入力を受け付ける&lt;/li&gt;
&lt;li&gt;入力されたテキストの分解&lt;/li&gt;
&lt;li&gt;コマンドと引数の前処理&lt;/li&gt;
&lt;li&gt;実行ファイルの探索&lt;/li&gt;
&lt;li&gt;ワイルドカードの展開&lt;/li&gt;
&lt;li&gt;プロセスの起動&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;「11.5.3コマンドと引数の前処理」で紹介されていたが、&lt;code&gt;$(which nvim)&lt;/code&gt;と同様に&lt;code&gt;`which nvim`&lt;/code&gt;でもコマンドの実行結果を変数に代入できるのは知らなかった。&lt;/p&gt;
&lt;h2 id=&#34;第12章-プロセスの役割とgo言語による操作&#34;&gt;第12章 プロセスの役割とGo言語による操作&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;OSが実行ファイルを読み込んで実行するには、そのためのリソース（CPU、メモリ）を用意する必要がある。そのようなリソースをまとめたプログラムの実行単位のことを&lt;strong&gt;プロセス&lt;/strong&gt;と呼ぶ。プロセスはOSが実行ファイルを読み込んで実行するときに新しく作られる。&lt;/li&gt;
&lt;li&gt;プロセスにはプロセスごとにユニークな識別子がある。（&lt;strong&gt;プロセスID&lt;/strong&gt;）。Go言語では&lt;code&gt;os.Getpid()&lt;/code&gt;で取得できる。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;プロセスの入出力&#34;&gt;プロセスの入出力&lt;/h3&gt;
&lt;p&gt;すべてのプロセスは少なくとも次の3つの入出力データを持っている。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;入力：コマンドライン引数&lt;/li&gt;
&lt;li&gt;入力：環境変数&lt;/li&gt;
&lt;li&gt;出力：終了コード&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;osから見たプロセス&#34;&gt;OSから見たプロセス&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;OSの仕事はたくさんあるプロセスに効率よく仕事をさせること&lt;/li&gt;
&lt;li&gt;Linuxではプロセスごとに&lt;code&gt;task_struct&lt;/code&gt;型の&lt;strong&gt;プロセスディスクリプタ&lt;/strong&gt;と呼ばれる構造体を持っている。
&lt;ul&gt;
&lt;li&gt;基本的にはプロセスから見た各種情報と同じ内容だが、そこには含まれていない要素もいくつか存在する。&lt;/li&gt;
&lt;li&gt;例えば、&lt;strong&gt;どこからどこまでが自分のメモリ領域かというメモリブロックの情報&lt;/strong&gt;や&lt;strong&gt;スタック領域がどこにありプログラムが静的に確保するデータや動的に確保するデータがどのようにレイアウトされるか&lt;/strong&gt;もOSが持つプロセスの情報の中にある。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;プロセスの出力に色づけをする&#34;&gt;プロセスの出力に色づけをする&lt;/h3&gt;
&lt;p&gt;プロセスの出力に色をつけたい場合には&lt;strong&gt;ANSIエスケープシーケンス&lt;/strong&gt;を使うことができる。&lt;/p&gt;
&lt;p&gt;自分が利用したことある&lt;sup id=&#34;fnref:6&#34;&gt;&lt;a href=&#34;#fn:6&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;6&lt;/a&gt;&lt;/sup&gt;Rustの&lt;a href=&#34;https://crates.io/crates/colored&#34; target=&#34;_blank&#34; &gt;&lt;code&gt;colored&lt;/code&gt;&lt;/a&gt;クレートも確認したところ実際にANSIエスケープシーケンスを使ってターミナルに色をつけていた。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;#[cfg_attr(feature = &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;no-color&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;, ignore)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;#[test]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;fn&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;compute_style_simple_fg_blue&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;let&lt;/span&gt; blue &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\x1B&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;[34m&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        assert_eq!(blue, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;.blue().compute_style());
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://github.com/colored-rs/colored/blob/775ec9f19f099a987a604b85dc72ca83784f4e38/src/lib.rs#L805-L811&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://github.com/colored-rs/colored/blob/775ec9f19f099a987a604b85dc72ca83784f4e38/src/lib.rs#L805-L811&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail&#34;&gt;
      &lt;img src=&#34;https://opengraph.githubassets.com/1072123a6eb5d0eb1781edd6afa28fd10244f3ba273a0bc5e3f5e1c1801ffba9/colored-rs/colored&#34; alt=&#34;colored/src/lib.rs at 775ec9f19f099a987a604b85dc72ca83784f4e38 · colored-rs/colored&#34; loading=&#34;lazy&#34;&gt;
    &lt;/div&gt;&lt;div class=&#34;blogcard-content&#34;&gt;
      &lt;div class=&#34;blogcard-title&#34;&gt;colored/src/lib.rs at 775ec9f19f099a987a604b85dc72ca83784f4e38 · colored-rs/colored&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;(Rust) Coloring terminal so simple you already know how to do it ! - colored-rs/colored&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://github.com/colored-rs/colored/blob/775ec9f19f099a987a604b85dc72ca83784f4e38/src/lib.rs#L805-L811&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
 より&lt;/p&gt;
&lt;p&gt;調べてみたところ&lt;code&gt;\x1B&lt;/code&gt;でも&lt;code&gt;\e&lt;/code&gt;でもエスケープシーケンスを表現できるらしい。&lt;sup id=&#34;fnref:7&#34;&gt;&lt;a href=&#34;#fn:7&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;7&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h3 id=&#34;外部プロセスに対して自分が擬似端末だと詐称する&#34;&gt;外部プロセスに対して自分が擬似端末だと詐称する&lt;/h3&gt;
&lt;p&gt;ライブラリによっては、自分が繋がっている先が擬似端末かどうかでエスケープシーケンスを出力するかどうかを決定している。&lt;/p&gt;
&lt;p&gt;子プロセスの出力を色づけするためには、親を擬似端末だと詐称することでエスケープシーケンスを出力させることができる。&lt;/p&gt;
&lt;h3 id=&#34;デーモン化&#34;&gt;デーモン化&lt;/h3&gt;
&lt;p&gt;普通のプログラムはシェルのプロセスの子になってしまうので、ログアウトしたりシェルを閉じたりするだけで終了してしまう。&lt;/p&gt;
&lt;p&gt;そのような場合でも終了しないように下記のような特別な細工が施されたプロセスが&lt;strong&gt;デーモン&lt;/strong&gt;である。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;セッションID、グループIDを新しいものにして既存のセッションとグループから独立&lt;/li&gt;
&lt;li&gt;カレントのディレクトリはルートに移動&lt;/li&gt;
&lt;li&gt;フォークしてからブートプロセスのinitを親に設定し、実際の親はすぐに終了&lt;/li&gt;
&lt;li&gt;標準入出力も起動時のものから切り離される(通常は&lt;code&gt;dev/null&lt;/code&gt;に設定される)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;第13章-シグナルによるプロセス間の通信&#34;&gt;第13章 シグナルによるプロセス間の通信&lt;/h2&gt;
&lt;p&gt;シグナルには主に2つの用途がある。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;プロセス間通信&lt;/strong&gt;: カーネルが仲介してあるプロセスから別のプロセスへとシグナルを送るケース。自分自身にシグナルを送ることもできる。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ソフトウェア割り込み&lt;/strong&gt;: システムで発生したイベントがシグナルとしてプロセスに送られる。シグナルを受け取ったプロセスは現在置くなっているタスクを中断してあらかじめ登録しておいた処理を実行する。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;システムコールはユーザー空間で動作しているプロセスからカーネル空間にはたらきかけるためのインターフェースだが、その逆方向がシグナルだと考えることができる。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;システムコールでは最大7つほどの引数を指定できるのに対し、ソフトウェア割り込みとしてのシグナルで送信できるのはその種類のみ。&lt;/li&gt;
&lt;li&gt;プロセスは受け取ったシグナルを無視するか補足して処理する。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;シグナルのハンドラを書く&#34;&gt;シグナルのハンドラを書く&lt;/h3&gt;
&lt;p&gt;Goでは次のように&lt;code&gt;signal.NotifyContext()&lt;/code&gt;を使ってシグナルを受け取ることができる。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;package&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;main&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;context&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;fmt&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;os/signal&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;syscall&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;time&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;main&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#a6e22e&#34;&gt;ctx&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;context&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Background&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#a6e22e&#34;&gt;sigctx&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;cancel&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;signal&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;NotifyContext&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;ctx&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;syscall&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;SIGINT&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;syscall&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;SIGTERM&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;defer&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;cancel&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#a6e22e&#34;&gt;toctx&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;cancel2&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;context&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;WithTimeout&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;ctx&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;time&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Second&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;defer&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;cancel2&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;case&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;-&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;sigctx&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Done&lt;/span&gt;():
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#a6e22e&#34;&gt;fmt&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Println&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;signal&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;case&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;-&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;toctx&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Done&lt;/span&gt;():
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#a6e22e&#34;&gt;fmt&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Println&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;timeout&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;KubernetesやDockerでは外からタスクを終了させるとき、まずSIGTERMをアプリケーションに対して送信する。(SIGTERM: &lt;code&gt;kill()&lt;/code&gt;システムコールや&lt;code&gt;kill&lt;/code&gt;コマンドがデフォルトで送信するシグナル。プロセスを終了させるもの)&lt;/p&gt;
&lt;p&gt;(GoアプリケーションのGraceful Shutdownの実装例でSIGTERMをハンドリングするのをよく見るのはだからか、と納得した。)&lt;/p&gt;
&lt;h2 id=&#34;第14章-go言語と並列処理&#34;&gt;第14章 Go言語と並列処理&lt;/h2&gt;
&lt;h3 id=&#34;並行処理と並列処理の違い&#34;&gt;並行処理と並列処理の違い&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;並行処理: 1つのコアで複数のタスクを素早く切り替えながら処理すること&lt;/li&gt;
&lt;li&gt;並列処理: 複数のコアを使って複数のタスクを同時に処理すること&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;チャネル&#34;&gt;チャネル&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Go言語で簡単に並列処理を書くための道具としてgoroutineとチャネルがある。&lt;/li&gt;
&lt;li&gt;チャネルを使うことでデータの入出力を&lt;strong&gt;直列化できる。&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;スレッドとgoroutineの違い&#34;&gt;スレッドとgoroutineの違い&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;スレッドとはプログラムを実行するためのものであり、OSによって手配される。&lt;/li&gt;
&lt;li&gt;プログラムからみたスレッドは「&lt;strong&gt;時間が凍結されたプログラムの実行状態&lt;/strong&gt;」で、CPUが演算に使ったり計算結果や状態を保持したりする&lt;strong&gt;レジスタ&lt;/strong&gt;と呼ばれるメモリと&lt;strong&gt;スタックメモリ&lt;/strong&gt;が含まれる。&lt;/li&gt;
&lt;li&gt;OSは凍結状態のプログラムの実行状態を復元して各スレッドに短時間ずつ処理をさせる。実行予定のスレッドは&lt;strong&gt;ランキュー&lt;/strong&gt;と呼ばれるリストに入っている。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;スレッドがCPUコアに対してマッピングされる&lt;/strong&gt;のに対し、&lt;strong&gt;gouroutineはOSのスレッドにマッピングされる&lt;/strong&gt;点が通常のスレッドとgoroutineとの最大の違い。
&lt;ul&gt;
&lt;li&gt;goroutineはOSスレッドの1~2MBと比べると初期スタックメモリのサイズが小さい(2KB)ため起動処理が軽い。&lt;/li&gt;
&lt;li&gt;また、gouroutineはOSに処理を渡さずに作成できるのでカーネルとのタスク切り替えのコストも小さい。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;goroutineのメリット&#34;&gt;goroutineのメリット&lt;/h3&gt;
&lt;p&gt;大量のクライアントからのリクエストを効率よく捌きたいとき（いわゆるC10K）に、クライアントごとに1つのgoroutineを割り当てたとしても少ないメモリ消費量で処理できる（前述の通りgoroutineは起動時の初期スタックメモリのサイズが小さいため）&lt;/p&gt;
&lt;h2 id=&#34;第15章-並行並列処理の手法と設計のパターン&#34;&gt;第15章 並行・並列処理の手法と設計のパターン&lt;/h2&gt;
&lt;h3 id=&#34;代表的な並行並列処理の手法&#34;&gt;代表的な並行・並列処理の手法&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;マルチプロセス&lt;/li&gt;
&lt;li&gt;イベント駆動&lt;/li&gt;
&lt;li&gt;マルチスレッド&lt;/li&gt;
&lt;li&gt;ストリーミング・プロセッシング&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;イベント駆動&#34;&gt;イベント駆動&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;主に並列化ではなく並行処理のために使われる。&lt;/li&gt;
&lt;li&gt;I/Oバウンドなプログラムで用いられる。&lt;/li&gt;
&lt;li&gt;OSに依頼したデータ受信の仕事が終わるたびにコールバックが返ってくる仕組み。&lt;/li&gt;
&lt;li&gt;単体ではCPUを使いこなしにくい点が欠点。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;マルチスレッド&#34;&gt;マルチスレッド&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;同じメモリ空間内で多くのCPUが同時に実行するための仕組み
&lt;ul&gt;
&lt;li&gt;Linuxではプロセスもスレッドもカーネル上は同じ構造体として表現されている。親のプロセスとメモリ空間を共有していなければプロセス、共有していればスレッド。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;利点はCPUのパフォーマンスを引き出すことができる点。&lt;/li&gt;
&lt;li&gt;欠点はプロセスほどではないが、OSのスレッドの場合は比較的大きなスタックメモリ（1~2MB）を必要とし、起動時間もややかかる。そのためスレッドプールを作っておき、必要になったらすぐ使えるようにする、ということが行なわれている。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;goにおける並行並列処理のパターン集&#34;&gt;Goにおける並行・並列処理のパターン集&lt;/h3&gt;
&lt;p&gt;アムダールの法則: 並列化を導入するとどれだけ効率が改善するかを表す数式&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;S(N) = 1 / ((1 - P) + P/N)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;ここで&lt;code&gt;P&lt;/code&gt;は並列化できる仕事の割合、&lt;code&gt;N&lt;/code&gt;は並列数である。&lt;/p&gt;
&lt;p&gt;P = 0.5, N = ∞のとき、S(N) = 2倍になり、P = 0.9, N = ∞のとき、S(N) = 10倍になる。このことからもわかるように、並列数よりも並列化できるタスクの割合が支配的になる。&lt;/p&gt;
&lt;p&gt;Pを改善するためのアイディアとして次のような手法が考えられる。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;同期処理を非同期にする&lt;/li&gt;
&lt;li&gt;非同期にしたものを同期化する&lt;/li&gt;
&lt;li&gt;タスク生成と処理を分ける（Producer-Consumerパターン）&lt;/li&gt;
&lt;li&gt;開始した順で処理する（チャネルのチャネル）&lt;/li&gt;
&lt;li&gt;タスク処理が詰まったら待機（バックプレッシャー）&lt;/li&gt;
&lt;li&gt;並列なForループ&lt;/li&gt;
&lt;li&gt;決まった数のgoroutineでタスクを消化する（ワーカープール）&lt;/li&gt;
&lt;li&gt;依存関係のあるタスクを表現する（Future/Promise）&lt;/li&gt;
&lt;li&gt;イベントの流れを定義する（ReactiveX）&lt;/li&gt;
&lt;li&gt;自立した複数のシステムで協調動作（アクターモデル）&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;同期---非同期化&#34;&gt;同期 -&amp;gt; 非同期化&lt;/h4&gt;
&lt;p&gt;I/O処理などの重いタスクを非同期化する&lt;/p&gt;
&lt;h4 id=&#34;非同期---同期化&#34;&gt;非同期 -&amp;gt; 同期化&lt;/h4&gt;
&lt;p&gt;非同期化したタスクはどこかで同期化する必要がある。そのための一番簡単な手法がチャネル。&lt;/p&gt;
&lt;h4 id=&#34;タスク生成と処理を分けるproducer-consumerパターン&#34;&gt;タスク生成と処理を分ける（Producer-Consumerパターン）&lt;/h4&gt;
&lt;p&gt;GoではチャネルでProducerとConsumerを接続することで簡単に実現できる。&lt;/p&gt;
&lt;h4 id=&#34;開始した順で処理するチャネルのチャネル&#34;&gt;開始した順で処理する（チャネルのチャネル）&lt;/h4&gt;
&lt;p&gt;チャネルを用いると複数の処理を終了した順に取り出すことができる。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// 終了した順に書き出し
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// チャネルに結果が投入された順に処理される
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;writeToConn&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;responses&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;chan&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;http&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Response&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;conn&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;net&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Conn&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;defer&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;conn&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Close&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#75715e&#34;&gt;// 順番に取り出す
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;response&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;range&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;responses&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#a6e22e&#34;&gt;response&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Write&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;conn&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;チャネルのチャネルを使うと処理を開始した順で処理をできる。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// 開始した順に書き出し
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// チャネルにチャネルを入れた(開始した)順に処理される
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;writeToConn&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;sessionResponses&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;chan&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;chan&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;http&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Response&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;conn&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;net&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Conn&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;defer&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;conn&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Close&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#75715e&#34;&gt;// 順番に取り出す
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;sessionResponse&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;range&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;sessionResponses&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#75715e&#34;&gt;// 選択された仕事が終わるまで待つ
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;        &lt;span style=&#34;color:#a6e22e&#34;&gt;response&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;-&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;sessionResponse&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;response&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Write&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;conn&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;タスク処理が詰まったら待機バックプレッシャー&#34;&gt;タスク処理が詰まったら待機（バックプレッシャー）&lt;/h4&gt;
&lt;p&gt;以下のようなバッファ付きチャネルを使うことで実現できる。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;tasks&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; make(&lt;span style=&#34;color:#66d9ef&#34;&gt;chan&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;string&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;10&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;並列forループ&#34;&gt;並列Forループ&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;forループ内の処理をgoroutineで実行することでループ処理を並列化できる。&lt;/li&gt;
&lt;li&gt;ループ内部の処理が小さすぎるとオーバーヘッドのほうが大きくなり効率が上がらないことがあるので注意が必要。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;決まった数のgoroutineでタスクを消化するワーカープール&#34;&gt;決まった数のgoroutineでタスクを消化する（ワーカープール）&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;特にCPUバウンドな処理ではCPUのコア数以上にgoroutineを作ってもスループットは上がらないため、CPUコア数分のワーカーを作成してタスクを消化するのが効果的な場合がある。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;依存関係のあるタスクを表現するfuturepromise&#34;&gt;依存関係のあるタスクを表現する（Future/Promise）&lt;/h4&gt;
&lt;p&gt;Futureをチャネルで表現すると、必要なデータが揃ったらタスクを逐次実行できる。&lt;/p&gt;
&lt;p&gt;後続の処理に結果を引き継ぎたいが、処理自体は可能な限り非同期で実行したい場合に有効そう。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;readFile&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;path&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;string&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;chan&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;string&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#75715e&#34;&gt;// ファイルを読み込み、その結果を返すFutureを返す
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;	&lt;span style=&#34;color:#a6e22e&#34;&gt;promise&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; make(&lt;span style=&#34;color:#66d9ef&#34;&gt;chan&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;string&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;go&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#a6e22e&#34;&gt;content&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;os&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;ReadFile&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;path&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;nil&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			&lt;span style=&#34;color:#a6e22e&#34;&gt;fmt&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Printf&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;read error %s\n&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;err&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Error&lt;/span&gt;())
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			close(&lt;span style=&#34;color:#a6e22e&#34;&gt;promise&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		} &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			&lt;span style=&#34;color:#75715e&#34;&gt;// 約束を果たした
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;			&lt;span style=&#34;color:#a6e22e&#34;&gt;promise&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;-&lt;/span&gt; string(&lt;span style=&#34;color:#a6e22e&#34;&gt;content&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	}()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;promise&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;printFunc&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;futureSource&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;chan&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;string&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;chan&lt;/span&gt; []&lt;span style=&#34;color:#66d9ef&#34;&gt;string&lt;/span&gt; { 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;// 文字列中の関数一覧を返すFutureを返す
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;	&lt;span style=&#34;color:#a6e22e&#34;&gt;promise&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; make(&lt;span style=&#34;color:#66d9ef&#34;&gt;chan&lt;/span&gt; []&lt;span style=&#34;color:#66d9ef&#34;&gt;string&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;go&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#66d9ef&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;result&lt;/span&gt; []&lt;span style=&#34;color:#66d9ef&#34;&gt;string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#75715e&#34;&gt;// futureが解決するまで待って実行
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;		&lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;_&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;line&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;range&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;strings&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Split&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;-&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;futureSource&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;\n&amp;#34;&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;strings&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;HasPrefix&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;line&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;func &amp;#34;&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;				&lt;span style=&#34;color:#a6e22e&#34;&gt;result&lt;/span&gt; = append(&lt;span style=&#34;color:#a6e22e&#34;&gt;result&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;line&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#75715e&#34;&gt;// 約束を果たした
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;		&lt;span style=&#34;color:#a6e22e&#34;&gt;promise&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;result&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	}()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;promise&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;main&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#a6e22e&#34;&gt;futureSource&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;readFile&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;main.go&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#a6e22e&#34;&gt;futureFuncs&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;printFunc&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;futureSource&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#a6e22e&#34;&gt;fmt&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Println&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;strings&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Join&lt;/span&gt;(&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;-&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;futureFuncs&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;\n&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;また、次のような構造体を定義することで上記のFutureの値を複数回読み取ることができる。（上記の実装ではバッファなしチャネルを使っているので複数回受信してしまうと処理がブロックされてしまう）&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;StringFuture&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#a6e22e&#34;&gt;receiver&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;chan&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#a6e22e&#34;&gt;cache&lt;/span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;NewStringFuture&lt;/span&gt;() (&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;StringFuture&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;chan&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;string&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#a6e22e&#34;&gt;f&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;StringFuture&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#a6e22e&#34;&gt;receiver&lt;/span&gt;: make(&lt;span style=&#34;color:#66d9ef&#34;&gt;chan&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;string&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;f&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;f&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;receiver&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;f&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;StringFuture&lt;/span&gt;) &lt;span style=&#34;color:#a6e22e&#34;&gt;Get&lt;/span&gt;() &lt;span style=&#34;color:#66d9ef&#34;&gt;string&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#a6e22e&#34;&gt;r&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;ok&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;-&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;f&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;receiver&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;ok&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		close(&lt;span style=&#34;color:#a6e22e&#34;&gt;f&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;receiver&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#a6e22e&#34;&gt;f&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;cache&lt;/span&gt; = &lt;span style=&#34;color:#a6e22e&#34;&gt;r&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;f&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;cache&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;f&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;StringFuture&lt;/span&gt;) &lt;span style=&#34;color:#a6e22e&#34;&gt;Close&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	close(&lt;span style=&#34;color:#a6e22e&#34;&gt;f&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;receiver&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;イベントの流れを定義するreactivex&#34;&gt;イベントの流れを定義する：ReactiveX&lt;/h4&gt;
&lt;p&gt;ここでは&lt;a href=&#34;https://github.com/ReactiveX/RxGo&#34; target=&#34;_blank&#34; &gt;RxGo&lt;/a&gt;を使ってイベントの流れを定義する方法が紹介されていた。
まずこのようにwatcherを定義する。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;watcher&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;observer&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Observer&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;NextHandler&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;item&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;any&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#a6e22e&#34;&gt;line&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;item&lt;/span&gt;.(&lt;span style=&#34;color:#66d9ef&#34;&gt;string&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;strings&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;HasPrefix&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;line&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;func &amp;#34;&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#a6e22e&#34;&gt;fmt&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Println&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;line&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;ErrHandler&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;error&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#a6e22e&#34;&gt;fmt&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Printf&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Encountered error: %v\n&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;err&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;DoneHandler&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#a6e22e&#34;&gt;fmt&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Println&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Done!&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;以下のようにすると&lt;code&gt;NextHandler&lt;/code&gt;に登録された関数に&lt;code&gt;line&lt;/code&gt;が渡される。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;emitter&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;line&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;そして次のようにすると&lt;code&gt;ErrHandler&lt;/code&gt;に登録された関数が呼ばれる。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;emitter&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;err&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;渡ってきた値に応じて処理を分岐させたく、かつ何度も同一のイベントが発生するケースではこの方法を使うと良さそう。&lt;/p&gt;
&lt;h4 id=&#34;自律した複数のシステムで協調動作アクターモデル&#34;&gt;自律した複数のシステムで協調動作：アクターモデル&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;アクターと呼ばれる自律した多数のコンピューターが協調して動作するというモデル。&lt;/li&gt;
&lt;li&gt;各アクターは別のアクターから送られてくるメッセージを受け取る&lt;strong&gt;メッセージボックス&lt;/strong&gt;を持つ。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;第16章-go言語のメモリ管理&#34;&gt;第16章 Go言語のメモリ管理&lt;/h2&gt;
&lt;h3 id=&#34;仮想メモリ&#34;&gt;仮想メモリ&lt;/h3&gt;
&lt;p&gt;現代のOSではプロセスはメモリを読み書きするのに物理的なアドレスを直接扱うのではなく、プロセスごとに仮想的なメモリアドレス空間があり、それを使ってメモリにアクセスしている。この仮想的なメモリアドレス空間のことを&lt;strong&gt;仮想メモリ&lt;/strong&gt;という。&lt;/p&gt;
&lt;p&gt;仮想メモリのアドレスから実際の物理メモリにアクセスするために&lt;strong&gt;ページテーブル&lt;/strong&gt;というデータ構造が使われる。&lt;strong&gt;ページ&lt;/strong&gt;とはメモリを管理する単位のこと。&lt;/p&gt;
&lt;p&gt;仮想メモリのおかげで実際の保存領域が飛び飛びになっていたとしてもプロセスからはフラットなメモリ領域が確保されているように見える。&lt;/p&gt;
&lt;p&gt;仮想メモリは物理メモリのアドレスと1対1対応しているわけではなく、物理メモリのあるアドレスが複数の仮想メモリから参照されることもある。こうすることで共有ライブラリなどを複数のプロセスで利用でき省メモリになる。&lt;/p&gt;
&lt;h3 id=&#34;osカーネルがプロセスのメモリを確保するまで&#34;&gt;OSカーネルがプロセスのメモリを確保するまで&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;プロセスは起動時にOSからメモリをもらう。OSはプロセスごとに仮想メモリの領域を確保する。&lt;/li&gt;
&lt;li&gt;ユーザーのメモリ空間は大きく3つの連続したメモリ領域に分かれる。3つの領域の間の空きスペース分はメモリの確保が行われない。
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;| ①プログラム + 静的データ | ヒープとして使われる領域 | ②共有ライブラリ |      | ③スタックなど |
小さいアドレス                                                                大きいアドレス -&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;スタック&#34;&gt;スタック&lt;/h3&gt;
&lt;p&gt;関数を呼ぶとリターンアドレスや新しい関数のための作業メモリ領域として&lt;strong&gt;スタックフレーム&lt;/strong&gt;と呼ばれるメモリ領域が確保される。&lt;/p&gt;
&lt;p&gt;スタックフレームはスレッドごとにあらかじめ確保されているメモリブロックに対して順番に追加したり削除されたりされるだけなので割当のコストはほぼゼロ。&lt;/p&gt;
&lt;h3 id=&#34;go言語でのスタックとヒープの使い分け&#34;&gt;Go言語でのスタックとヒープの使い分け&lt;/h3&gt;
&lt;p&gt;Go言語では変数のデータをヒープに置くかスタックに置くかはコンパイラが自動的に判断する。以下はその一部。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;new&lt;/code&gt;で初期化してもその関数内でしか利用されなければスタックに確保される。&lt;/li&gt;
&lt;li&gt;ローカル変数として宣言してもそのポインタを他の関数に渡したり、関数の返り値として返すような場合にはヒープに確保される。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Go言語でメモリがスタックとヒープのどちらに確保されるかを知りたい場合にはビルド時に&lt;code&gt;-gcflags -m&lt;/code&gt;を渡すことで確認できる。&lt;/p&gt;
&lt;p&gt;ということで次のコードを使って上記の挙動を確認してみる。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;package&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;main&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;fmt&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;main&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#a6e22e&#34;&gt;strValue&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Hello, World!&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;// スタックに確保される(関数内でしか利用されていないため)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;	&lt;span style=&#34;color:#a6e22e&#34;&gt;_&lt;/span&gt; = &lt;span style=&#34;color:#a6e22e&#34;&gt;strValue&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#a6e22e&#34;&gt;strPtr&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; new(&lt;span style=&#34;color:#66d9ef&#34;&gt;string&lt;/span&gt;) &lt;span style=&#34;color:#75715e&#34;&gt;// スタックに確保される(関数内でしか利用されていないため)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;	&lt;span style=&#34;color:#a6e22e&#34;&gt;_&lt;/span&gt; = &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;strPtr&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#a6e22e&#34;&gt;strPtr2&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; new(&lt;span style=&#34;color:#66d9ef&#34;&gt;string&lt;/span&gt;) &lt;span style=&#34;color:#75715e&#34;&gt;// ヒープに確保される(他の関数に渡されているため)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;	&lt;span style=&#34;color:#a6e22e&#34;&gt;receiveStrPtr&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;strPtr2&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#a6e22e&#34;&gt;strPtrFromFunc&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;returnStrPtr&lt;/span&gt;() &lt;span style=&#34;color:#75715e&#34;&gt;// スタックに確保される(関数内でしか利用されていないため)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;	&lt;span style=&#34;color:#a6e22e&#34;&gt;_&lt;/span&gt; = &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;strPtrFromFunc&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;receiveStrPtr&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;argStrPtr&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;string&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#a6e22e&#34;&gt;fmt&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Printf&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;argStrPtr: %v\n&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;argStrPtr&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;returnStrPtr&lt;/span&gt;() &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;string&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#a6e22e&#34;&gt;str&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Hello, World!&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;// ヒープに確保される(関数の返り値として返されているため)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;str&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;-gcflags -m&lt;/code&gt;をつけてビルドしてみると次のようになりコードコメント通り、&lt;code&gt;strPtr2&lt;/code&gt;と&lt;code&gt;str&lt;/code&gt;がヒープに確保されていることがわかった。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ go build -gcflags -m main.go
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# command-line-arguments&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;./main.go:19:6: can inline receiveStrPtr
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;./main.go:23:6: can inline returnStrPtr
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;./main.go:13:15: inlining call to receiveStrPtr
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;./main.go:15:32: inlining call to returnStrPtr
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;./main.go:13:15: inlining call to fmt.Printf
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;./main.go:20:12: inlining call to fmt.Printf
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;./main.go:7:15: strValue + &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt; does not escape
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;./main.go:9:15: new&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;string&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; does not escape
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;./main.go:10:14: *strPtr + &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt; does not escape
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;./main.go:12:16: new&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;string&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; escapes to heap
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;./main.go:13:15: ... argument does not escape
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;./main.go:16:22: *strPtrFromFunc + &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt; does not escape
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;./main.go:19:20: leaking param: argStrPtr
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;./main.go:20:12: ... argument does not escape
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;./main.go:24:2: moved to heap: str
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;ガベージコレクタ&#34;&gt;ガベージコレクタ&lt;/h3&gt;
&lt;p&gt;Goをはじめとして多くの言語ではマークアンドスイープという方式が採用されている。&lt;/p&gt;
&lt;p&gt;マークアンドスイープ方式では、まずメモリの領域をスキャンして必要なデータか否かをマークしていき、次のフェーズで不要なものを削除する。&lt;/p&gt;
&lt;p&gt;マークアンドスイープ方式では、不要なメモリを削除する間にプログラム全体を停止する必要がある。（これをストップザワールドと呼ぶ）&lt;/p&gt;
&lt;p&gt;Goではバージョンを重ねる事にストップザワールドの時間の短縮化が進んでいる。&lt;/p&gt;
&lt;h2 id=&#34;第17章-実行ファイルが起動するまで&#34;&gt;第17章 実行ファイルが起動するまで&lt;/h2&gt;
&lt;p&gt;最終的にCPUで実行されるバイナリはメモリ空間に単に命令が並んだもので、そこにはブロックのような概念は存在しない（Goでいうと&lt;code&gt;{&lt;/code&gt;と&lt;code&gt;}&lt;/code&gt;で囲まれた処理の塊）。&lt;/p&gt;
&lt;p&gt;アセンブリ言語には関数のブロックのような概念はないが、その代わりにラベルという概念がある。&lt;/p&gt;
&lt;h3 id=&#34;ランタイムの役割&#34;&gt;ランタイムの役割&lt;/h3&gt;
&lt;p&gt;Goに限らずC言語でもRustでも何かしらのプログラミング言語で生成したアプリケーションは「ランタイム」と呼ばれるライブラリを利用したプログラムになるのが一般的。&lt;/p&gt;
&lt;p&gt;ラインタイムライブラリが最終的にはOSのカーネルにシステムコールを発行して仕事を依頼し、メモリ管理やファイルやネットワークアクセスを実現する役割を担う。&lt;/p&gt;
&lt;p&gt;ラインタイムライブラリがなければ、OSに仕事を依頼するところも自分で作成する必要がある。&lt;/p&gt;
&lt;h3 id=&#34;リンカーの役割&#34;&gt;リンカーの役割&lt;/h3&gt;
&lt;p&gt;以下はWikipediaによるリンカーの説明。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;a computer program that takes one or more object files generated by a compiler or generated by an assembler and links them with libraries, generating an executable program or shared library&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Linker&#34; target=&#34;_blank&#34; &gt;Linker - Wikipedia&lt;/a&gt; から引用&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;上記を翻訳すると「コンパイラまたはアセンブラによって生成された1つ以上のオブジェクトファイルをライブラリと結合し実行可能ファイルまたは共有ライブラリを生成するプログラム」といった感じだろうか。&lt;/p&gt;
&lt;p&gt;OSはリンカーが生成した実行ファイルがシェルから起動されると、実行ファイルの内容をメモリに配置する。&lt;/p&gt;
&lt;p&gt;ロードが終わったら決め打ちされた「特定のアドレス」からCPUが命令を読み込んで実行が開始される。&lt;/p&gt;
&lt;p&gt;実行中に発生する関数呼び出しはすでにリンカーによってアドレスが解決されているので示されたアドレスにジャンプするだけで高速に実行される。&lt;/p&gt;
&lt;h3 id=&#34;実行ファイルのメモリ配置&#34;&gt;実行ファイルのメモリ配置&lt;/h3&gt;
&lt;p&gt;OSがアプリケーションの実行ファイルを最初にロードしてくる部分についての解説。&lt;/p&gt;
&lt;p&gt;まず、実行ファイルのフォーマットはOSによって異なる。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;LinuxなどのPOSIX系OS: ELF形式&lt;/li&gt;
&lt;li&gt;Windows: PE(Portable Executable)形式&lt;/li&gt;
&lt;li&gt;macOS: Mach-O形式&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;また、実行ファイルには次のようなデータが格納されている。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;この実行ファイルが対象としているCPUアーキテクチャの種類&lt;/li&gt;
&lt;li&gt;実行ファイル中に含まれるセクションをどのメモリアドレスに配置するか、そのときのセクション名と実行権限&lt;/li&gt;
&lt;li&gt;プログラム起動時に最初に呼び出す命令が格納されているアドレス&lt;/li&gt;
&lt;li&gt;実行ファイルの実行に必要な共有ライブラリの情報&lt;/li&gt;
&lt;li&gt;実行コードのセクション&lt;/li&gt;
&lt;li&gt;静的に初期化された変数のセクション&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;セクションは実行ファイルフォーマットを構成するバイナリデータのブロックのことで以下のようなものがある。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;TEXT&lt;/code&gt;: 機械語の実行コードが格納されるセクション&lt;/li&gt;
&lt;li&gt;&lt;code&gt;DATA&lt;/code&gt;: 実行コードを含まない静的に確保された初期化済み（データがすでに入っている）のメモリ領域&lt;/li&gt;
&lt;li&gt;&lt;code&gt;BSS&lt;/code&gt;: 変数が置かれる領域で初期化されていない（すべてゼロ）メモリ領域&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;OSはこの実行ファイルフォーマットに従って実行ファイルに含まれるセクションを適切なアドレスに配置していく。&lt;sup id=&#34;fnref:8&#34;&gt;&lt;a href=&#34;#fn:8&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;8&lt;/a&gt;&lt;/sup&gt;その後実行ファイルフォーマットに書かれた初期実行アドレスを実行することでアプリケーションが起動する。&lt;/p&gt;
&lt;h3 id=&#34;goのプログラムの起動&#34;&gt;Goのプログラムの起動&lt;/h3&gt;
&lt;p&gt;Goで書かれたソースコードが実行されるまでの流れは以下。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Goで書かれたアプリケーションをコンパイルすると実行ファイルが作成される&lt;/li&gt;
&lt;li&gt;コンパイル済みのGoプログラムを実行すると実行環境のランタイムにある&lt;code&gt;$GOROOT/src/runtime/asm_(ARCH名).s&lt;/code&gt;というファイルのなかにある&lt;code&gt;_rt0_(ARCH名)&lt;/code&gt;という関数が呼ばれる。このプロシージャの中では以下のような処理が実行される。
&lt;ol&gt;
&lt;li&gt;最初のgoroutineの初期化&lt;/li&gt;
&lt;li&gt;OSから渡されるコマンドライン引数&lt;code&gt;os.Args&lt;/code&gt;のパース&lt;/li&gt;
&lt;li&gt;コンピュターで利用可能なCPUコア数の取得&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$GOROOT/src/runtime/proc.go&lt;/code&gt;の&lt;code&gt;schedinit()&lt;/code&gt;関数の中で以下のような処理が実行される。
&lt;ul&gt;
&lt;li&gt;スタックを初期化&lt;/li&gt;
&lt;li&gt;メモリマネージャを初期化し、Mを初期化&lt;/li&gt;
&lt;li&gt;mapの内部で使われるハッシュアルゴリズムの初期化&lt;/li&gt;
&lt;li&gt;モジュール機能向けのモジュール情報や型情報の取得&lt;/li&gt;
&lt;li&gt;シグナルハンドラの初期化&lt;/li&gt;
&lt;li&gt;コマンドライン引数と環境変数の初期化&lt;/li&gt;
&lt;li&gt;ガベージコレクタの初期化&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;次に新しいgoroutineを作って&lt;code&gt;$GOROOT/src/runtime/proc.go&lt;/code&gt;の&lt;code&gt;main()&lt;/code&gt;関数が呼び出される。そこでは以下のような流れで処理が進む。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;runtime.lockOSThread()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;(ランタイムの)&lt;code&gt;init()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;main・init()&lt;/code&gt;(アプリケーションのmainパッケージの&lt;code&gt;init()&lt;/code&gt;関数)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;runtime.unlockOSThread()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;main・main()&lt;/code&gt;(アプリケーションのmainパッケージの&lt;code&gt;main()&lt;/code&gt;関数)&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;まとめ&#34;&gt;まとめ&lt;/h2&gt;
&lt;p&gt;ここまでの理解をもとにいくつかの質問に対する答えを書いてみる。&lt;/p&gt;
&lt;h3 id=&#34;プロセスとスレッドの違いは何か&#34;&gt;プロセスとスレッドの違いは何か&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;プロセスはプログラムの実行単位であり他のプロセスとはメモリを共有していない。&lt;/li&gt;
&lt;li&gt;プロセスは起動時に仮想メモリが割り当てられるためスレッドに比べて起動コストが高い&lt;/li&gt;
&lt;li&gt;スレッドはプロセス内で実行される軽量な実行単位でプロセス内のメモリ空間やリソースを共有する。&lt;/li&gt;
&lt;li&gt;複数のスレッドが同じメモリを操作する可能性があるためデータ競合を防ぐ必要がある。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;プログラムはどのような流れで実行されるか&#34;&gt;プログラムはどのような流れで実行されるか&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;コンパイラがソースコードをコンパイルする&lt;/li&gt;
&lt;li&gt;リンカーがコンパイル済みのオブジェクトファイルをリンクし実行可能ファイルを生成する&lt;/li&gt;
&lt;li&gt;ユーザーが実行可能ファイルを実行する(e.g. ターミナルから呼び出す)&lt;/li&gt;
&lt;li&gt;OSがプロセスを生成し、プロセスの実行に必要な仮想メモリ空間を割り当てる&lt;/li&gt;
&lt;li&gt;OSが実行ファイルの内容をディスクからメモリに読み込み、仮想アドレス空間に適切に配置する&lt;/li&gt;
&lt;li&gt;メインスレッドでプログラムが実行される(プロセスが生成されると自動的にメインスレッドが作成される)&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;感想&#34;&gt;感想&lt;/h3&gt;
&lt;p&gt;冒頭にも書いた通りCSを体系的に学んだ経験がない自分にとってはとても勉強になった。&lt;/p&gt;
&lt;p&gt;次はこのあたりの書籍を読んでみようとおもう。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;コンピュータシステムの理論と実装&lt;/li&gt;
&lt;li&gt;Go言語による並行処理&lt;/li&gt;
&lt;li&gt;つくって、壊して、直して学ぶ Kubernetes入門&lt;/li&gt;
&lt;li&gt;Linuxで動かしながら学ぶTCP/IPネットワーク入門&lt;/li&gt;
&lt;li&gt;体系的に学ぶ 安全なWebアプリケーションの作り方&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;あるいは、 &lt;a href=&#34;https://blog.ojisan.io/server-architecture-2023/#%E3%83%97%E3%83%AD%E3%82%BB%E3%82%B9-vs-%E3%82%B9%E3%83%AC%E3%83%83%E3%83%89&#34; target=&#34;_blank&#34; &gt;Webサーバーアーキテクチャ進化論2023 - blog.ojisan.io&lt;/a&gt;を参考に学習ロードマップを立ててみるのもいいかもしれない。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;Neovimでのデバッガの環境構築は &lt;a href=&#34;https://zenn.dev/saito9/articles/32c57f776dc369&#34; target=&#34;_blank&#34; &gt;nvim-dapでGolangのデバッグ環境構築&lt;/a&gt; を参考にした&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;&lt;code&gt;Sysfd&lt;/code&gt;の定義はgolang/go/src/internal/poll/fd_unix.go#L23(&lt;a href=&#34;https://github.com/golang/go/blob/c83b1a7013784098c2061ae7be832b2ab7241424/src/internal/poll/fd_unix.go#L23&#34; target=&#34;_blank&#34; &gt;https://github.com/golang/go/blob/c83b1a7013784098c2061ae7be832b2ab7241424/src/internal/poll/fd_unix.go#L23&lt;/a&gt;) にある。&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;&lt;code&gt;io.Pipe&lt;/code&gt;の使いどころに関しては &lt;a href=&#34;https://medium.com/eureka-engineering/file-uploads-in-go-with-io-pipe-75519dfa647b&#34; target=&#34;_blank&#34; &gt;Go言語のio.Pipeでファイルを効率よくアップロードする方法&lt;/a&gt; が大変参考になった。&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;cf. &lt;a href=&#34;https://github.com/kyu08/go-system-programming/blob/b9da4a0ce759b2df4ce884ab61248fb893b60bef/4-channel/unbufferedchannel/main.go#L8&#34; target=&#34;_blank&#34; &gt;kyu08/go-system-programming/4-channel/unbufferedchannel/main.go#L8&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:5&#34;&gt;
&lt;p&gt;Distrolessに対して「コンテナイメージが軽量になる」以外のメリットを感じていなかったが書かれている通りセキュリティ面でもメリットがあると気付いた。&amp;#160;&lt;a href=&#34;#fnref:5&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:6&#34;&gt;
&lt;p&gt;fzf-makeの出力の一部に色を付けるために使っている。 &lt;a href=&#34;https://github.com/kyu08/fzf-make/blob/12789acd19bc24daa60ba7eb84973dab18fe7a52/src/usecase/execute_make_command.rs#L5&#34; target=&#34;_blank&#34; &gt;https://github.com/kyu08/fzf-make/blob/12789acd19bc24daa60ba7eb84973dab18fe7a52/src/usecase/execute_make_command.rs#L5&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:6&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:7&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://ufcpp.net/blog/2023/12/escape-escape/&#34; target=&#34;_blank&#34; &gt;https://ufcpp.net/blog/2023/12/escape-escape/&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:7&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:8&#34;&gt;
&lt;p&gt;仮想メモリ空間についてはκeenさんのこちらの記事がとてもわかりやすかった。&lt;a href=&#34;https://keens.github.io/blog/2017/04/30/memoritosutakkutohi_puto/&#34; target=&#34;_blank&#34; &gt;メモリとスタックとヒープとプログラミング言語&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:8&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</content>
    </item>
    
    <item>
      <title>『読み手につたわる文章 - テクニカルライティング』を読んだ</title>
      <link>https://blog.kyu08.com/pr-344/posts/technical-writing-book/</link>
      <pubDate>Wed, 05 Jun 2024 15:21:05 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/pr-344/posts/technical-writing-book/</guid>
      <description>技術書典で購入した『読み手につたわる文章 - テクニカルライティング』を読んだので学びになったトピックについて書く。 1.2 「知らない」と書けない（P</description>
      <content>&lt;p&gt;技術書典で購入した『読み手につたわる文章 - テクニカルライティング』を読んだので学びになったトピックについて書く。&lt;/p&gt;
&lt;h2 id=&#34;12-知らないと書けないp14&#34;&gt;1.2 「知らない」と書けない（P14）&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;そして自分が対象物を思っていたより「知らない」ということに、我々は気付いていないことが多いのです。上手な絵は、対象物のことを知らないと描けません。それと同じように、分かりやすい実用文は、文章力のあるなし以前に &lt;strong&gt;対象物をよく知らないと書けない&lt;/strong&gt; のです。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;文字にすると当たり前のことのように感じるが、ブログを書いているとよく実感する。&lt;/p&gt;
&lt;!-- textlint-disable ja-technical-writing/no-doubled-joshi --&gt;
&lt;!-- textlint-disable ja-technical-writing/ja-no-weak-phrase --&gt;
&lt;p&gt;技術的な内容であれば、当然対象を理解していないと書けないし、自分の考えでさえもいざ言語化しようと思うとなかなか筆が進まないことが多い。&lt;/p&gt;
&lt;!-- textlint-enable ja-technical-writing/ja-no-weak-phrase --&gt;
&lt;!-- textlint-enable ja-technical-writing/no-doubled-joshi --&gt;
&lt;p&gt;そうした場合にはまず自分が何を言いたいのかを整理して理解するようにしている。&lt;/p&gt;
&lt;h2 id=&#34;214-いつまでに何をしてほしいのか書こうp25&#34;&gt;2.1.4 いつまでに何をしてほしいのか書こう（P25）&lt;/h2&gt;
&lt;!-- textlint-disable ja-technical-writing/ja-no-successive-word --&gt;
&lt;blockquote&gt;
&lt;p&gt;何の食べ物だか言わずにいきなり「食べて! ほら食べて!」とスプーンを差し出されると、「え、怖い。なになになに?」となって、とても素直に口を開く気にはなれませんし、食べたところで猜疑心で味もよく分かりません。そんなときは「初めて作ったプリンが思いのほか美味しくできたので一口食べて感想を教えてほしい」というように、どういう意図で読み手に何をして欲しいと思っているのかを先に説明してあげる必要があります。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;!-- textlint-enable ja-technical-writing/ja-no-successive-word --&gt;
&lt;p&gt;引用部分の前に書かれていた例示のエピソードがわかりすぎて無限に頷いてしまった。認知負荷が高い文章を読むにはエネルギーを要する。&lt;/p&gt;
&lt;p&gt;報告なのでただ把握だけしておいて欲しいのか相談がしたいので意見を求めているのかなど、読み手に求めるアクションを明示すると読み手の認知負荷が低くて良さそう。&lt;/p&gt;
&lt;p&gt;結局伝えたいことが伝わらないことには意味がないので書いて満足、ではなくドキュメントを書くことの目的を見失わないようにしていきたい。&lt;/p&gt;
&lt;h2 id=&#34;22-文書構造や文章量が適切だと分かりやすい&#34;&gt;2.2 文書構造や文章量が適切だと分かりやすい&lt;/h2&gt;
&lt;h3 id=&#34;221-大枠から始めてだんだん細かくしていこうp26&#34;&gt;2.2.1 大枠から始めてだんだん細かくしていこう（P26）&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;文章で何かを説明するときには、先に大枠を理解してもらい、それから段々細かい 内容にしていくという順番を意識しましょう。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;以前上司にレビューで指摘してもらって以来意識するようになった。&lt;/p&gt;
&lt;p&gt;コンテキストを共有していない人とコミュニケーションを取る時は特に重要だと感じている。自分と相手が持っている情報の差分を埋めるように情報を提示できるとスムーズにコミュニケーションを取れる印象がある。&lt;/p&gt;
&lt;h3 id=&#34;223-既知から未知に繋ごうp28&#34;&gt;2.2.3 既知から未知に繋ごう（P28）&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;文章を書くとき、「大枠から詳細へ」の他に意識すべきもう1つの順番は「既知から未知へ」です。
技術ドキュメントを読んでいても、最初から知らない単語や知らない概念ばかりが次から次へと出てくると、「知らないことについて説明してくれているけど、その説明がまず分からない」という状態になります。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;あまり意識したことがなかった。&lt;/p&gt;
&lt;p&gt;一度にまとまった情報量を記述したい時にはこのあたりまで意識して書くと認知負荷が減ってよさそう。&lt;/p&gt;
&lt;h2 id=&#34;24-再利用しやすい文章にする&#34;&gt;2.4 再利用しやすい文章にする&lt;/h2&gt;
&lt;h3 id=&#34;242-並列はナカグロで書かないp34&#34;&gt;2.4.2 並列はナカグロ（・）で書かない（P34）&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;文章の中で並列を表そうとして「ホーム・検索・マイページ・ヘルプのタブは非表示にできません」のようにナカグロ(・)を使っていると、再利用されて箇条書きになったときに、次のような見た目になることがあります。&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;着せかえの設定時、以下の機能は非表示にしたり、見た目を変更したりできません。
・ホーム・検索・マイページ・ヘルプのタブ
・トレンドワード機能
・ID連携機能
&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;対策として、最初から箇条書きにしておくか、読点を使うといいとのこと。&lt;/p&gt;
&lt;!-- textlint-disable --&gt;
&lt;p&gt;いつもどう書くか迷っていたが&lt;code&gt;・&lt;/code&gt;で並列関係を表現すると上記のデメリットがあるので読点を使うようにしてみようと思う。&lt;/p&gt;
&lt;!-- textlint-enable --&gt;
&lt;h3 id=&#34;244-リンクテキストをこちらにしないp35&#34;&gt;2.4.4 リンクテキストを「こちら」にしない（P35）&lt;/h3&gt;
&lt;p&gt;リンク切れになったときやテキストだけコピーされたときにリンク先がどこを指しているのかわからなくなるため、以下のようにどういったページなのかも含めて書くのがいいとのこと。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;また「詳しくは&lt;a href=&#34;https://blog.kyu08.com/pr-344/BankCodeAPI/reference/&#34; &gt;Shops APIのAPIリファレンス&lt;/a&gt;をご覧ください」&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;また、読み手としてもリンクを踏む前にどんなページへ飛ばされるのかわかるというメリットも紹介されていた。&lt;/p&gt;
&lt;h2 id=&#34;まとめ&#34;&gt;まとめ&lt;/h2&gt;
&lt;p&gt;具体的な知見が理由とセットで書いてあってとても勉強になった。&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;チームで仕事をする上で認知負荷を下げる工夫の重要性を日々感じるのでこれから意識的に実践していきたい。&lt;/p&gt;
&lt;p&gt;紹介したトピック以外にもたくさんの知見が紹介されていたので気になった方はこちらからぜひ購入してみてください。 &lt;a href=&#34;https://techbookfest.org/product/3t8AGqtB65jsPtPhx6m5fr&#34; target=&#34;_blank&#34; &gt;こちら&lt;/a&gt; &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;余談だがちゃんと理由まで書かれているとスムーズに理解できるのでちゃんと背景や理由を説明するのは重要だと感じた。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;冗談です。リンクテキストにはリンクの内容がわかるようなものにしましょう。購入はこちらから。 &lt;a href=&#34;https://techbookfest.org/product/3t8AGqtB65jsPtPhx6m5fr&#34; target=&#34;_blank&#34; &gt;読み手につたわる文章 - テクニカルライティング - 技術書典マーケット&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</content>
    </item>
    
    <item>
      <title>『いちばんやさしいアジャイル開発の教本』 を読んだ</title>
      <link>https://blog.kyu08.com/pr-344/posts/ichiban-yasashii-agile-no-kyouhon/</link>
      <pubDate>Sat, 25 May 2024 15:48:56 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/pr-344/posts/ichiban-yasashii-agile-no-kyouhon/</guid>
      <description>2024/4からチーム異動してスクラムを実践しているチームに移ったのでアジャイル・スクラムのインプットをしたいと思い、『いちばんやさしいアジ</description>
      <content>&lt;p&gt;2024/4からチーム異動してスクラムを実践しているチームに移ったのでアジャイル・スクラムのインプットをしたいと思い、『いちばんやさしいアジャイル開発の教本』を読んだ。&lt;/p&gt;
&lt;p&gt;本書を読んで自分なりに勉強になったことをLessonごとに書いていく。（カッコ内の&lt;code&gt;Pxx&lt;/code&gt;はページを表す）&lt;/p&gt;
&lt;h2 id=&#34;lesson6-アジャイル開発とは何かp28-31&#34;&gt;Lesson6. アジャイル開発とは何か（P28-31）&lt;/h2&gt;
&lt;p&gt;「継続的に改善することが前提」なので逆にいえば作りたいものが決まっているならばアジャイル開発を採用するメリットは薄いかもしれない。&lt;/p&gt;
&lt;h2 id=&#34;lesson7-カイゼンp32&#34;&gt;Lesson7. カイゼン（P32）&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;世界で通じる日本語、&amp;ldquo;Kaizen&amp;rdquo;。このKaizenという言葉は日本においてもカタカナで &lt;strong&gt;「カイゼン」&lt;/strong&gt; と表現されており、「改善」という単語とはあえて区別されています。&lt;/p&gt;
&lt;p&gt;もともと改善という表現は「誤りや欠陥を正し、よりよいものにする」という意味があります。カイゼンは &lt;strong&gt;「いまあるものをよりよいものにしていく」&lt;/strong&gt; という精神に基づいており、より前向きで積極的なものだということがわかります。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;「カイゼン」という表記を見たことはあったが、文脈によっては「改善」とは別の単語として使われているというこれは知らなかった。&lt;/p&gt;
&lt;h2 id=&#34;lesson14-アジャイル開発の構造p56&#34;&gt;Lesson14. アジャイル開発の構造（P56）&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;マインドセット：&lt;/strong&gt; アジャイルソフトウェア開発宣言&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;マインドセットを実現するための原則：&lt;/strong&gt; アジャイル宣言の背後にある原則&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;現場での実践：&lt;/strong&gt; スクラム・XP・FDD・カンバン・モブプロなど&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;lesson17-個人と対話p66&#34;&gt;Lesson17. 個人と対話（P66）&lt;/h2&gt;
&lt;p&gt;アジャイルソフトウェア開発宣言の &lt;strong&gt;「プロセスやツールよりも個人と対話を」&lt;/strong&gt; について書いた章。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;対話と議論の違いは何でしょうか。ざっくり説明すると、議論は自分自身の目線から主張を展開するものですが、対話は相手の価値観を尊重し、ともに考えていくものです。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;プロダクト開発では不確実性が高いため、必ずしも正解がなく、あらゆる角度から課題を見つめることでより良い解決策を探っていくことが重要で、そのための有効な手段として「対話」があると解釈した。&lt;/p&gt;
&lt;p&gt;また、対話を繰り返すなかで互いの認識のズレや齟齬を発見し解消していくことで、議論の前提にズレが生まれることが減り、よりスピーディーに問題解決を行うことができるようになりそう。（これはアジャイルに限らないが）&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;このように個人を尊重し、対話をしながらチームの課題と全員で向き合うことで相互理解が進み、それぞれが異なる立場からの視点を得ることができます。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;盲目的にプロセスやツールに従うのではなく、個人との対話をして相互理解を深めることでチームが強くなる。そのようなチームでは信頼関係があり情報共有が活発に行われるため問題が起きても迅速にリカバリーできる。&lt;/p&gt;
&lt;h2 id=&#34;lesson18-動くソフトウェアp68&#34;&gt;Lesson.18 動くソフトウェア（P68）&lt;/h2&gt;
&lt;p&gt;アジャイルソフトウェア開発宣言の &lt;strong&gt;「包括的なドキュメントよりも動くソフトウェアを」&lt;/strong&gt; について書いた章。&lt;/p&gt;
&lt;p&gt;ソフトウェア開発においては課題とその解決方法を仮説として立て、実際にリリースして検証するという流れで開発を進めることが多い。&lt;/p&gt;
&lt;p&gt;細かくリリースするのではなく、機能を全て作り込んでからリリースした場合、仮説と解決策の確らしさを検証できるのが遅くなってしまう。&lt;/p&gt;
&lt;p&gt;なので、仮説を検証するために最低限必要な機能が備わっているプロダクト（MVP）を提供して仮説の検証を行うことでより素早く検証のループを回すことができる。&lt;/p&gt;
&lt;p&gt;また、いくら社内で話し合ったところで実際の顧客の反応がわかるわけではないので、一定仮説を煮詰めたらリリースして実際の反応をみることが重要そう。&lt;/p&gt;
&lt;h2 id=&#34;lesson19-顧客との協調p70&#34;&gt;Lesson.19 顧客との協調（P70）&lt;/h2&gt;
&lt;p&gt;アジャイルソフトウェア開発宣言の &lt;strong&gt;「契約交渉よりも顧客との協調を」&lt;/strong&gt; について書いた章。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;自社開発の場合はこの契約交渉はどのような形となって現れてくるのでしょうか。たとえば、顧客からのフィードバックに対して「それは仕様が悪い」「仕様通りの挙動です」というようにいまのソフトウェアの挙動が正しいことを前提として判断してしまう、といった保守的な行動として現れます。&lt;/p&gt;
&lt;p&gt;&amp;hellip;(中略)&amp;hellip;&lt;/p&gt;
&lt;p&gt;ユーザーボイスを尊重しながら、そのままいわれたとおりに開発するのではなく、その声の裏側にある本当に要望を見極めていきましょう。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;社内外からのフィードバックをフラットに受け取ってフィードバックの裏側の要求を見極めることでよりよいプロダクトを作っていけそう。&lt;/p&gt;
&lt;h2 id=&#34;lesson20-変化への対応p72&#34;&gt;Lesson.20 変化への対応（P72）&lt;/h2&gt;
&lt;p&gt;アジャイルソフトウェア開発宣言の &lt;strong&gt;「計画に従うことよりも変化への対応を」&lt;/strong&gt; について書いた章。&lt;/p&gt;
&lt;p&gt;プロダクト開発においては常に最新の情報を基に仮説をアップデートすることが重要なので事前に決めた計画通りに進めることよりも、都度変化に適用することが重要そう。(それはそうという感じだが)&lt;/p&gt;
&lt;h2 id=&#34;lesson22-自己組織化チームとリーダーシップp76&#34;&gt;Lesson.22 自己組織化チームとリーダーシップ（P76）&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;図表22-2&lt;/code&gt;が示すように自己組織化チームとはひとことでいうと「自走できるチーム」です。自分たちがなぜここにいるのかを理解し、またお互いの得意分野がわかっているため自分たちで最適なフォーメーションを組みながらビジョンへと向かっていきます。リーダーの意思決定を待つことなく自己修復的に課題を解決していく。それが自己組織化チームの底力です。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&#34;self-organizing-team.webp&#34; alt=&#34;self-organizing-team.webp&#34; loading=&#34;lazy&#34; /&gt;
『いちばんやさしいアジャイル開発の教本』P76より引用&lt;/p&gt;
&lt;p&gt;チームの振り返りなんかでも、「どうすれば自己組織化チームに近付けるか」という観点で考えてみてもいいかもしれない。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;自己組織化チームにおいて情報共有は重要な要素&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;よく透明性が大事、と聞くけどそれも個々人が自律的に行動するために情報は不可欠だからなんだろうなーと思った。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;理想的な自己組織化チームとは？&lt;/p&gt;
&lt;p&gt;(中略)
自己組織化し、それぞれのメンバーがリーダーシップを発揮できるようになると、 &lt;strong&gt;外からチームを見た際にはもはや誰がリーダーと呼ばれる役割なのかわからなくなるでしょう。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;これは自己組織化されたチームの見え方の1つとして良さそうだとおもったので心に留めておきたい。&lt;/p&gt;
&lt;h2 id=&#34;まとめ&#34;&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;まずは「自己組織化チーム」を目指していきたい。&lt;/li&gt;
&lt;li&gt;実際にアジャイルの入門書を1冊読んでみて、とはいえまずはスクラムガイドをしっかり理解した方がよさそうだと思ったので次はスクラムガイドを読み込んでいこうと思う。&lt;/li&gt;
&lt;/ul&gt;
</content>
    </item>
    
    <item>
      <title>『ベタープログラマ』 を読んだ</title>
      <link>https://blog.kyu08.com/pr-344/posts/better-programmer/</link>
      <pubDate>Wed, 06 Mar 2024 15:27:45 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/pr-344/posts/better-programmer/</guid>
      <description>『ベタープログラマ』を読んだので自分的に刺さった点をまとめる。 6章 航路を航行する 新たなメンバーが開発チームに参加する際にどのようにすれば速や</description>
      <content>&lt;p&gt;『ベタープログラマ』を読んだので自分的に刺さった点をまとめる。&lt;/p&gt;
&lt;h2 id=&#34;6章-航路を航行する&#34;&gt;6章 航路を航行する&lt;/h2&gt;
&lt;p&gt;新たなメンバーが開発チームに参加する際にどのようにすれば速やかに生産的になることができるかについての章。&lt;/p&gt;
&lt;p&gt;最善な策はすでにプロジェクトへの理解があるメンバーに導いてもらうこと。もしそれができなければ次のようなことを調べるとよい。&lt;/p&gt;
&lt;h4 id=&#34;ソースの取得の容易さ&#34;&gt;ソースの取得の容易さ&lt;/h4&gt;
&lt;p&gt;ソースの取得がどれだけ簡単か。健全なプログラムはコードベース全体を得るための単一のチェックアウトのみを必要とする。&lt;/p&gt;
&lt;h4 id=&#34;コードのビルドの容易さ&#34;&gt;コードのビルドの容易さ&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;一般的でないツールにビルドが依存していないか&lt;/li&gt;
&lt;li&gt;コード自身に適切で簡単なドキュメンテーションがあるか&lt;/li&gt;
&lt;li&gt;手作業なしで1つのコマンドでビルドを行うことができか&lt;/li&gt;
&lt;li&gt;コードの一部に取り組んでいるときにその部分だけをビルドできるか&lt;/li&gt;
&lt;li&gt;ビルド中に潜在的な問題を曖昧にしているかもしれない無数の警告が出ていないか&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;テスト&#34;&gt;テスト&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;単体テスト・インテグレーションテスト・システム全体のテストがどの程度揃っているか&lt;/li&gt;
&lt;li&gt;テストは自動で実行されるか。あるいは追加のビルドステップを必要とするか&lt;/li&gt;
&lt;li&gt;テストはどれだけ頻繁に実行されているか&lt;/li&gt;
&lt;li&gt;カバレッジはどの程度か&lt;/li&gt;
&lt;li&gt;テストは適切できちんと作成されているか&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;コードとテストには普遍的な関連性がある。優れたテストが存在するコードはたいていきちんとリファクタリングされ、きちんと考え尽くされている。&lt;/p&gt;
&lt;h4 id=&#34;ファイルの構造&#34;&gt;ファイルの構造&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;ディレクトリの構造が領域・サブシステム・コードの階層を明確に表しているか&lt;/li&gt;
&lt;li&gt;ディレクトリの構造が整っているか&lt;/li&gt;
&lt;li&gt;サードパーティのライブラリはプロジェクトのコードからきちんと分離されているか&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;ドキュメンテーション&#34;&gt;ドキュメンテーション&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;ドキュメンテーションは存在するか。わかりやすく、かつメンテナンスされているか&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;要件&#34;&gt;要件&lt;/h4&gt;
&lt;p&gt;プロジェクトの要件文書あるいは機能仕様書があるか。&lt;/p&gt;
&lt;h4 id=&#34;プロジェクトの依存物&#34;&gt;プロジェクトの依存物&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;コードは特定のFWやライブラリを使っているか。それらについてどの程度学ぶ必要があるか&lt;/li&gt;
&lt;li&gt;コードが言語の標準ライブラリをうまく利用しているか&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;コードの品質&#34;&gt;コードの品質&lt;/h4&gt;
&lt;p&gt;品質の感触を得るためにざっと目を通す。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;コードのコメントの量と質はどうか&lt;/li&gt;
&lt;li&gt;多くのデッドコードがあるか&lt;/li&gt;
&lt;li&gt;コーディングのスタイルは全体にわたって首尾一貫しているか&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;アーキテクチャ&#34;&gt;アーキテクチャ&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;ここまでの項目を通して主となる階層群を特定できるか&lt;/li&gt;
&lt;li&gt;それらの階層がきれいに分離されているか&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;上記を実施すれば素早くプロジェクトについて把握できる。
では実際にプロジェクトに取り組む際にはどのようにすればいいか。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;やってみて学ぶ
&lt;ul&gt;
&lt;li&gt;コードを読むことは読むことにすぎない。実際に取り組んでみて、間違いを犯すことによってのみコードベースを学ぶことができる&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;何か単純で小さな修正から着手する&lt;/li&gt;
&lt;li&gt;コードを点検する
&lt;ul&gt;
&lt;li&gt;コード検査ツールをコードベースに対して実行してみる&lt;/li&gt;
&lt;li&gt;コンパイルの警告が無効にされいないか調べる。無効にされていれば有効にして警告が表示されないようにコードを修正する。それによってコードベースの構造と品質の理解を深めることができる&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;調査、そして行動
&lt;ul&gt;
&lt;li&gt;コードの小さな部分を調べ、批評してみる。弱点がないか調べ、容赦なくリファクタリングする。正しい命名に修正したり、長いコードを小さくて適正な命名をもつ関数に切り出す&lt;/li&gt;
&lt;li&gt;このような作業を数回行うことで、コードにどれだけの柔軟性があり修正や変更に対してどれだけ従順であるかの感触を得ることができる&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;維持管理
&lt;ul&gt;
&lt;li&gt;ソースファイルを整頓したりディレクトリ階層を正しくしたりする&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;わかったことを文書化する
&lt;ul&gt;
&lt;li&gt;コードに取り組み始める方法を説明しているトップレベルのREADMEは存在するか。しなければ作成してこれまでに学んだことを書く&lt;/li&gt;
&lt;li&gt;そのドキュメンテーションを経験のあるプログラマにレビューしてもらう&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;新たなコードベースに取り組むほど、新たなコードを効果的に学ぶことができる。&lt;/p&gt;
&lt;p&gt;この章はプロジェクトのキャッチアップに必要な観点が多く記述されていてとても参考になった。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;新しくプロジェクトに参加した際(業務・OSS関わらず)&lt;/li&gt;
&lt;li&gt;既存のプロジェクトの課題点を整理する際&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;などのタイミングで特に参考にできそう。&lt;/p&gt;
&lt;h2 id=&#34;14章-ソフトウェア開発とは&#34;&gt;14章 ソフトウェア開発とは&lt;/h2&gt;
&lt;blockquote&gt;
&lt;h3 id=&#34;ソフトウェア開発は退屈な仕事&#34;&gt;ソフトウェア開発は退屈な仕事&lt;/h3&gt;
&lt;p&gt;ソフトウェア開発の仕事の多くは、楽しくありません。魅力的でもありません。(中略)有能なプログラマであるためには、退屈な仕事を恐れてはいけません。(中略)時には、私達はソフトウェアの清掃員にならなければならず、次のことが求められます。&amp;hellip;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;自分が学生のときには想像できていなかったソフトウェアエンジニアの現実、という感じがする。学生のときには毎日コードを書けるなんて夢みたいだ！と思っていたけれど、実際には楽しくない仕事もあるしコードを書かない日もある。ただ、自分が見てきた優秀なエンジニアたちはそういった仕事であっても着実に丁寧に素早くこなしていた印象がある。&lt;/p&gt;
&lt;p&gt;あと、このところは&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;チームとして成果を出すためにはどうすればいいか&lt;/li&gt;
&lt;li&gt;身の回りの人から信頼される振る舞いとはどのようなものだろう&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;を意識して行動するようにしていて、自分にとってタスクが楽しいかや成長に繋がるかということをいい意味で意識せずに仕事ができている。この意識を持つようにしてから仕事が楽しく感じられるようになったので自分にとってもかなりいい変化だった思う。&lt;/p&gt;
&lt;h2 id=&#34;15章-規則に従って競技する&#34;&gt;15章 規則に従って競技する&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;自分達で決めた&lt;/strong&gt;規則が必要です。私達が所有権を持つ規則です。特定のチームにおける文化、およびうまく開発できる方法を定めている規則です。これらは、大きくて、扱いにくい厳しい規則である必要はありません。新たなチームメンバーがすぐに一緒に開発できるように、単純なものでよいです。つまり、それらは単なる方法やプロセスよりも詳しく何かを記述している規則であったり、コーディング文化を記述している規則だったりします。すなわち、&lt;strong&gt;チームで優れた選手になるための方法を記述している規則です。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;この &lt;strong&gt;「チームで優れた選手になるための方法を記述している規則です。」&lt;/strong&gt; という部分が特にいいなと思った。チームメンバーとして活躍する方法が言語化されていることで、新しいメンバーが素早く立ち上がることができるだけでなく、すでにチームに所属しているメンバーもことあるごとに立ち返ることができて、方向性がずれかけてもうまく軌道修正できるなどのメリットがありそう。&lt;/p&gt;
&lt;p&gt;個人的にチームで共通理解を持つことでチームの方向性がうまく揃い、軌道修正もしやすかった経験を部活のときにしたのでこの章の内容はとても腹落ちした。&lt;/p&gt;
&lt;h2 id=&#34;18章-変わらないものはない&#34;&gt;18章 変わらないものはない&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;コードのどの領域も、誰にも「所有」されていません。どの領域でも、誰もが変更を行うことが許されています。コードを所有するといった制度は避けてください。それは、変更を抑制します。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;サーバーサイドの開発チームに初めて異動したときは「自分よりもサーバーサイドも経験が長いエンジニアたちが書いたコードだからどの部位も意図があり、設計も練られた上で今の実装になってるに違いない&amp;hellip;！だから強い理由がないとなかなか変更を加えるべきではないのではないか」という思い込みがあったが、何ヶ月かサーバーサイドの開発の経験を積んで「なんか全然自分でも修正できそうなところあるぞ・・・！」と感じられるようになった。&lt;/p&gt;
&lt;p&gt;いい意味でフラットな目線でコードベースに触れる意識を持てるとよさそう。&lt;/p&gt;
&lt;h2 id=&#34;28章-倫理的なプログラマ&#34;&gt;28章 倫理的なプログラマ&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;プログラミングのキャリアの中で、最も頻繁に出会う人々は、チームメイトです。彼らは、毎日一緒に働くプログラマやテスターなどです。倫理的なプログラマは、彼ら全員と一緒に誠実に働き、各チームメンバーに敬意を払って、できる限り最善の結果を達成することに注意を払っています。&lt;/p&gt;
&lt;p&gt;どれだけ成熟しているとか経験を積んでいるとかに関係なく、誰もが貢献できる価値を持っていることを常に信じてください。&lt;/p&gt;
&lt;p&gt;誠実で信頼されるようになってください。誰にでも誠意を持って接してください。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;大事。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;倫理的なプログラマは、燃え尽きるような働き方をしません。それは、個人的に不都合であるだけではなく、チーム全体に対しても悪い影響を与えます。毎週、何十時間も残業すれば、疲れ切ったプログラマになり、必ず不注意な間違いを生み出し、悪い結果となります。驚くほど熱心に働く英雄のように思われるのは素晴らしいですが、倫理的なプログラマは、非現実的な期待に応えようとして、自身が燃え尽きてしまうのは悪い考えであることを理解しています。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;直感では理解できるが、プロジェクトの種類によっては残業の量が成果に直結することもあり難しい。残業を最後の手段にしつつ必要なときはやる、くらいの感覚がいいのだろうか。(残業前提でスケジュールを組み出すと工夫をする発想がなくなり、効率が上がらず長期的には損だと思う。もちろん燃え尽きリスクが高まるという面でもそう。)&lt;/p&gt;
&lt;p&gt;あとは現実的にビジネス的に絶対に守りたい締切があることはあると思う。現場レイヤー目線だと踏ん張りどこは頑張って、乗り切ったら少し休むようにし、マネジメントレイヤー目線だとそうならないように人員計画をいい感じにするとかがいいのだろうか（？）&lt;/p&gt;
&lt;p&gt;ただ、チームをマネジメントする立場からみると長期間安定して働いてくれることも一定嬉しいとは思うので無理をしすぎないことも重要そう。&lt;/p&gt;
&lt;h2 id=&#34;結び&#34;&gt;結び&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;ひどいプログラマと優れたプログラマを区別しているものは、態度です。それが、単なる適当なプログラマと並外れたプログラマを区別するものです。&lt;/p&gt;
&lt;p&gt;態度は、技術スキルに勝ります。プログラミング言語の複雑な知識は、保守可能なコードを保証しません。プログラミングのモデルを多く理解したからといって、必ずしも優れた設計を生み出すとは限りません。あなたのコードが優れているかどうかと、あなたと一緒に働くのが楽しいのかどうかを決めるのは、あなたの態度なのです。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;この記述がこの本を通して特に刺さった。シンプルだがとても重要なことだと思う。「何ができるか」も重要だが、それ以上に「どうしたいか」や「どこを目指しているのか」がより重要なのだろうと思った。ついついハードスキルばかりに目がいってしまうがそういった志向性を持つことにも同様に気を配りたい。&lt;/p&gt;
&lt;p&gt;自分が見てきた優秀なエンジニアはこれを体現している人ばかりだったように思う。&lt;/p&gt;
&lt;p&gt;最悪技術力の不足はレビューなどで他のエンジニアの力を借りて補うことができても、オーナーシップや主体性に限っては自分自身で持つしかない。&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;そういった意味でもどのようにすれば良い態度を保ち続けられるか、はふりかえりや環境選びの重要な観点になるように思える。&lt;/p&gt;
&lt;h2 id=&#34;感想&#34;&gt;感想&lt;/h2&gt;
&lt;p&gt;「優秀なエンジニアはどう振る舞うか」を主題に数多くのトピックが書かれていてとても参考になった。自分がこれまで接してきた優秀なエンジニアの振る舞いとも重なるところが多かった。 優秀なエンジニアがなぜ優秀かをあらゆる角度から言語化していて理解を深めることができたし、自分も真似できそうなことが多くあったので実践していきたい。&lt;/p&gt;
&lt;p&gt;次は久々に技術寄りの本を読みたくなったので次はRust関連の本を読んでみたいと思う。&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;あとは「プログラマー脳」も気になるのでいずれ読みたい。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;もちろん日々研鑽して自分の技術力を高めることも当然重要だと思っている。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;「コンセプトから理解するRust」でRustの理解を深めて「詳解Rustプログラミング」でRustで低レイヤーを学んでいこうと思っている。&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</content>
    </item>
    
    <item>
      <title>『世界一流エンジニアの思考法』 を読んだ</title>
      <link>https://blog.kyu08.com/pr-344/posts/how-world-class-engineers-think/</link>
      <pubDate>Sun, 19 Nov 2023 01:41:50 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/pr-344/posts/how-world-class-engineers-think/</guid>
      <description>Microsoftのエンジニアとしてアメリカで働いている牛尾剛さんが優秀な同僚から学んだ思考法について書いた著書『世界一流エンジニアの思考法</description>
      <content>&lt;p&gt;&lt;img src=&#34;./book.webp&#34; alt=&#34;book&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;Microsoftのエンジニアとしてアメリカで働いている牛尾剛さんが優秀な同僚から学んだ思考法について書いた著書『世界一流エンジニアの思考法』を読んだので学びになったトピックについて簡単に書こうと思う。&lt;/p&gt;
&lt;h2 id=&#34;頭がよくても理解には時間がかかる&#34;&gt;頭がよくても「理解」には時間がかかる&lt;/h2&gt;
&lt;p&gt;ある若くて優秀な同僚が新しいプロジェクトに参加するときにアーキテクチャの説明ビデオを「難しいので何回も見直している」と言っていたのに対して著者が衝撃を受けたというエピソードが紹介されていた。&lt;/p&gt;
&lt;p&gt;なかなか他人の作業過程を観察する機会もないのでついつい「優秀な人は複雑な物事でも一瞬で理解してしまうのだろう」と想像してしまいがちだが、&lt;strong&gt;Microsoftの凄腕エンジニアでも理解に時間がかかることがある&lt;/strong&gt;という実例を知り、何だかとても励まされた気分になった。&lt;/p&gt;
&lt;p&gt;新しい技術や概念の理解に時間がかかるとついつい仮想上の優秀な人と自分を比べて「はやくインプットしてはやくアウトプットを出さなければ」と焦るのをたまにやってしまうが「&lt;strong&gt;優秀な人でも物事を正確に理解するには時間がかかることもある&lt;/strong&gt;」という心持ちでいるだけで焦らず着実にインプットしていけそうだと感じた。&lt;/p&gt;
&lt;p&gt;そうして「正確に理解している概念」が増えていくほど新しい概念を理解する速度も向上するはずなので焦らず地道に理解することに努めたい。（もちろん時間的制約があるケースもあるので一概には言えないが）&lt;/p&gt;
&lt;p&gt;このトピックに関しては以下の記事にもあるのでもし気になったら読んでみて欲しい。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://note.com/simplearchitect/n/n388201603a28&#34; target=&#34;_blank&#34; &gt;プログラミングというより物事が出来るようになる思考法｜牛尾　剛&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;完全に余談だが、優秀な人をリスペクトしすぎると「自分とあの人は違うしな・・・」と自分にはそういった人のような素晴らしいアウトプットは出せないという思い込みを持ってしまいがちなので自分を卑下せずかといって奢りもせずフラットな気持ちで自分を励ましまくっていきたい。&lt;/p&gt;
&lt;h2 id=&#34;be-lazy怠惰であれ&#34;&gt;Be Lazy(怠惰であれ)&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;より少ない時間で価値を最大化する&lt;/strong&gt;という考え方。これを体現するために習慣として次が紹介されていた。&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;望んでいる結果を達成するために、最低限の努力をする。&lt;/li&gt;
&lt;li&gt;不必要なものや付加価値のない仕事（過剰準備含む）をなくす。&lt;/li&gt;
&lt;li&gt;簡潔さを目指す。&lt;/li&gt;
&lt;li&gt;優先順位をつける。&lt;/li&gt;
&lt;li&gt;時間や費やした努力より、アウトプットと生産性に重点を置く。&lt;/li&gt;
&lt;li&gt;長時間労働しないように推奨する。&lt;/li&gt;
&lt;li&gt;会議は会議の時間内で効率的かつ生産的に価値を提供する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;自分なりに抽象化すると&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;成果にフォーカスする&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;より効率的に成果が出るように工夫する&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ということなのかなと思った。&lt;/p&gt;
&lt;p&gt;とくに自分は成果を安定的に出せているかと言われると全然そんなことはないので、まずは「成果を出すこと」次に「より効率的に成果を出すこと」というステップで意識していくと良さそうだと思った。（あまり残業しないことばかりに意識を向けると結局期待される成果がでずに会社も自分も不幸せ、という状況に陥ってしまいそう）&lt;/p&gt;
&lt;p&gt;ただ、成果を出す手段として長時間労働を第一の選択肢にしてしまうとさまざまな弊害があるとは思うのでそこは気をつけたい。&lt;/p&gt;
&lt;p&gt;長期的な生産性を高めるためには&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;振り返りをして改善し自分 / 自チームの生産性を高めること&lt;/li&gt;
&lt;li&gt;振り返りを通して得た気付きを共有して組織の生産性を高めること&lt;/li&gt;
&lt;li&gt;自分のスキルアップに一定時間を投資すること&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;あたりは大事かなと思うのでやっていきたい。&lt;/p&gt;
&lt;h2 id=&#34;タイムボックス制&#34;&gt;タイムボックス制&lt;/h2&gt;
&lt;p&gt;以下のように紹介されていた。&lt;/p&gt;
&lt;blockquote&gt;
&lt;h2 id=&#34;タイムボックス制で学習の時間を確保する&#34;&gt;タイムボックス制で、学習の時間を確保する&lt;/h2&gt;
&lt;p&gt;今までは、時短を試みても「アウトカム」重視派だったので、切りのいいところまでやろうと考えて、結局寝る直前までかかってしまうことが頻繁にあった。(中略)ソリューションは簡単だった。「タイムボックス」制だ。
例えば、5時になったら仕事が途中でも、どんなに切りが悪くても、すぐに仕事をやめる。いつの間にか時間が過ぎてしまわないよう、5時きっかりにアラームをセットして。&lt;/p&gt;
&lt;p&gt;絶対に時間をオーバーすることはないよう、しばらく無理矢理にでも「タイムボックス」で生活してみたらどうなったか？ まず、5時に強制終了するようにすると、就業後にランニングできるようになった。頭がすっきりとリフレッシュするのがわかるし、夜に本を読んだり、ギターを弾いたり、ゲームしたりする余裕が生まれた。以前はそうした時間にすごく罪悪感を感じたが、一番イケてる人たちの意見をじることにしたのだ。 タイムボックス導入と同時に朝型の生活にシフトして、必ず夜10時には寝るスタイルにしてみた。&lt;/p&gt;
&lt;p&gt;すると1週間もしないうちに、というか翌日から頭が冴えて生産性が上がった。 正直マジかよ！と思ったが、今までどれだけ働きすぎて頭の切れが鈍くなっていたかを痛感した。運動をしなければ、動物として何かがおかしくなるのも当然だし、深夜まで起きて作業したって、ろくに頭が働いていなかったのだ。人間は週40時間労働が一番生産性が上がるという説もあるし、確かに時間を区切ったほうが合理的だ。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;仕事に使える時間を定めることで「たくさん残業して気合いで解決する」みたいな解決方法が第一の選択肢となることを防ぎ、工夫や改善によって生産性を上げることに繋がり持続可能な形で開発生産性を上げる文化に繋がりそうだと思った。&lt;/p&gt;
&lt;p&gt;成果が出るならばより少ない時間でその成果が得られる方がいいのはそれはそうなので少し自分なりにアレンジして取り入れたい。具体的には「残業しすぎないように気をつける」くらいのマイルドな感じで取り入れてみようと思う。&lt;/p&gt;
&lt;p&gt;ここでの示唆は、業務だけに自分の時間を使ってしまうと&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;学習によって自分の生産性を向上させることがしずらい&lt;/li&gt;
&lt;li&gt;残業前提で成果を出すため再現性が低い&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ということだと思う。残業しすぎないことで学習の時間を確保したり、開発プロセスの改善やスコープの調整によってうまく成果を出せるようにできていることが重要なのだと思う。&lt;/p&gt;
&lt;p&gt;ときには多少残業をしないと厳しいこともあると思うし個人としても残業を1秒もしたくないというほどでもないのでこういう取り入れ方にしてみようと思った。&lt;/p&gt;
&lt;h2 id=&#34;まとめ&#34;&gt;まとめ&lt;/h2&gt;
&lt;p&gt;というわけでマインドセットだけでなく具体的なプラクティスの面でも大いに参考になる内容が多かったのでとても勉強になったので折に触れてまた読み返したい。気になった方はぜひ読んでみてください。&lt;/p&gt;
</content>
    </item>
    
    <item>
      <title>『採用基準 地頭より論理的思考力より大切なもの』 を読んだ</title>
      <link>https://blog.kyu08.com/pr-344/posts/saiyo-kijun/</link>
      <pubDate>Sun, 22 Oct 2023 11:00:41 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/pr-344/posts/saiyo-kijun/</guid>
      <description>概要 McKinsey &amp;amp; Company出身の伊賀泰代さんがリーダーシップについて書いた『採用基準地頭より論理的思考力より大切なもの』を読んだ。ちょうど「リー</description>
      <content>&lt;h2 id=&#34;概要&#34;&gt;概要&lt;/h2&gt;
&lt;p&gt;McKinsey &amp;amp; Company出身の伊賀泰代さんがリーダーシップについて書いた『採用基準地頭より論理的思考力より大切なもの』を読んだ。ちょうど「リーダーシップとは」みたいなことが気になっていたので読んでみた。&lt;/p&gt;
&lt;p&gt;コンサルティングファームでの出来事を中心に書かれているが、ITベンチャーでエンジニアとして働く自分にも参考になる点が多かったように思う。&lt;/p&gt;
&lt;h2 id=&#34;学び&#34;&gt;学び&lt;/h2&gt;
&lt;h3 id=&#34;思考力とは&#34;&gt;思考力とは&lt;/h3&gt;
&lt;p&gt;思考力とは以下の3つの要素からなる。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;思考スキル&lt;/li&gt;
&lt;li&gt;思考意欲&lt;/li&gt;
&lt;li&gt;思考体力&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;このうち思考スキルはトレーニングなどで向上させることができるが、思考意欲と思考体力は一朝一夕で身につけることが難しいため筆者は面接時によく見ているらしい。&lt;/p&gt;
&lt;p&gt;この部分を読むまで思考力といえば思考スキルや思考体力が主だと思っていたので思考意欲という概念は自分には目新しかった。&lt;/p&gt;
&lt;h3 id=&#34;リーダーシップが全員に必要な理由&#34;&gt;リーダーシップが全員に必要な理由&lt;/h3&gt;
&lt;p&gt;多くの欧米企業が社員全員にリーダーシップを求める理由が書かれていたので引用する。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;マッキンゼーをはじめとする外資系企業の多くでは、すべての社員に高いレベルのリーダーシップを求めます。アメリカの場合は、大学や大学院の入学判定に使われる小論文でも、過去のリーダーシップ体験は常に問われる最重要項目です。(中略)全員がリーダーシップをもつ組織は、一部の人だけがリーダーシップをもつ組織より、圧倒的に高い成果を出しやすいのです。だから学校も企業も、欧米では（もしくは外資系企業では）全員にリーダーシップ体験を求めるのです。(中略)リーダーシップのある人は、「成果を出すこと」を「自説が採用されること」よりも優先します。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;「全員がリーダーシップを持つ組織」と聞くと「全員自分の意見ばかり主張していては物事が前に進まないのでは&amp;hellip;?」と考えてしまいがちだが、ここではリーダーシップを「チームの使命を達成するために、必要なことをやる人」と定義している。&lt;/p&gt;
&lt;p&gt;たしかにそう聞くと多角的な視点からよりよい意思決定ができそうな気がしてくる。チーム・組織の全員がリーダーシップを体現できれば指示待ちが起こらず、生産性が高まりそうだなと感じた。&lt;/p&gt;
&lt;h3 id=&#34;バリューを出す&#34;&gt;バリューを出す&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;まずは自分自身が期待されている(あるいは期待以上の)バリューを出すことでリーダーが最もこだわるべき成果の重要性を理解したりやそれにこだわる姿勢を身につけることができる。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;ポジションをとる&#34;&gt;ポジションをとる&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;自分はどう思うのか。情報を揃えて周りに判断を仰いでばかりではいつまでも指示待ち人間を脱することはできない。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;自分の仕事のリーダーは自分&#34;&gt;自分の仕事のリーダーは自分&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;組織図を考える時に上司が上、メンバーが下というように考えるよりは自分を中心に捉えてその周りに他のメンバーや上司やその上司などが放射状に位置していると考える。&lt;/li&gt;
&lt;li&gt;上司に決めて貰えばいいと考えるのではなく周りの人をどううまく使って自分の仕事を進めるかを考えることが大切。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;まとめ&#34;&gt;まとめ&lt;/h2&gt;
&lt;p&gt;組織の全員がリーダーシップを体現することの嬉しさを知れたのが自分にとっては大きな収穫だった。&lt;/p&gt;
&lt;p&gt;成果を意識してやっていく。&lt;/p&gt;
</content>
    </item>
    
    <item>
      <title>『ちょうぜつソフトウェア設計入門 PHPで理解するオブジェクト指向の活用』を読んだ</title>
      <link>https://blog.kyu08.com/pr-344/posts/chozetsu-bon/</link>
      <pubDate>Sat, 15 Jul 2023 15:00:00 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/pr-344/posts/chozetsu-bon/</guid>
      <description>田中ひさてるさんの『ちょうぜつソフトウェア設計入門――PHPで理解するオブジェクト指向の活用』が話題になっていたので読んでみた。 全体を通して</description>
      <content>&lt;p&gt;田中ひさてるさんの『ちょうぜつソフトウェア設計入門――PHPで理解するオブジェクト指向の活用』が話題になっていたので読んでみた。&lt;/p&gt;
&lt;p&gt;全体を通して平易な日本語で書かれていたのとコード例が豊富だったので理解しやすくてよかった。&lt;/p&gt;
&lt;p&gt;以下学びを簡単にまとめていく。&lt;/p&gt;
&lt;h2 id=&#34;第2章-パッケージ原則&#34;&gt;第2章 パッケージ原則&lt;/h2&gt;
&lt;p&gt;より変更に強いパッケージ設計にするために注意すべき点として&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;パッケージの凝集性を高める&lt;/li&gt;
&lt;li&gt;より安定度が高い(=抽象度が高い)パッケージに依存する&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;などがある。&lt;/p&gt;
&lt;p&gt;また、&lt;strong&gt;凝集性の低さを表すシグナル&lt;/strong&gt;として&lt;strong&gt;そのパッケージが変更される理由が複数あること&lt;/strong&gt;・&lt;strong&gt;1つの変更の際に変更対象となるパッケージが複数あること&lt;/strong&gt;(それぞれ同じ?)が挙げられる。&lt;/p&gt;
&lt;p&gt;「抽象」については以下のように説明されていた。&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;抽象クラスやインターフェイスなど実装詳細を自身から排除したもの&lt;/li&gt;
&lt;li&gt;上記のような詳細を持たないものだけに依存するロジック&lt;/li&gt;
&lt;li&gt;固有の業務にも特定技術にも関係しない時刻や配列などの汎用概念とその操作&lt;/li&gt;
&lt;li&gt;プログラミング言語そのものや言語標準ライブラリと同等レベルの業界標準&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;第3章-オブジェクト指向&#34;&gt;第3章 オブジェクト指向&lt;/h2&gt;
&lt;h3 id=&#34;いい抽象を見つけるには&#34;&gt;いい抽象を見つけるには&lt;/h3&gt;
&lt;p&gt;具体的な例を分析してそれらから抽象を見つけることで期待値の高い抽象を発見できる。&lt;/p&gt;
&lt;p&gt;逆に先に&lt;strong&gt;ひとりよがりの哲学をこねくり回して現実をかえりみない抽象化を先行させた&lt;/strong&gt;場合は、&lt;strong&gt;役に立たない概念に縛られる無駄が起きやすくなる。&lt;/strong&gt;（ペットショップのシステムなのに「Catには野良猫もいるかもしれない。必ずしもPetではないかも&amp;hellip;…」みたいなことを考えてしまうのは明らかに無駄）（抽象化においてもYAGNIが重要っぽい）&lt;/p&gt;
&lt;p&gt;無限の可能性に向かって発散してしまわず、いかに可能性を削ぎ落として最小サイズで実際に起こりうるバリエーションをカバーできるかが汎化のポイント。&lt;/p&gt;
&lt;p&gt;そういう意味でもドメインやビジネスの状況を理解しておくことはプロダクトの将来を考慮しながら設計するために必要なんだろうなと思った。&lt;/p&gt;
&lt;h3 id=&#34;多態性がなくても役立つ&#34;&gt;「多」態性がなくても役立つ&lt;/h3&gt;
&lt;p&gt;抽象と具象は必ずしも1対多の関係である必要はない。&lt;/p&gt;
&lt;p&gt;具象と抽象に分けておくことで先に大枠を安定させることができるため、設計の見通しがつきやすくなる。&lt;/p&gt;
&lt;p&gt;また、具象の数が複数になったときに対応しやすいというメリットもある。&lt;/p&gt;
&lt;p&gt;これまで「抽象と具象が1対1対応なケースはわざわざDIする必要はないのでは」と思っていたが上記のメリットがあるので積極的にDIしていこうと思った。&lt;/p&gt;
&lt;h2 id=&#34;第5章-オブジェクト指向原則-solid&#34;&gt;第5章 オブジェクト指向原則 SOLID&lt;/h2&gt;
&lt;h3 id=&#34;5-2-単一責任原則single-responsibility-principlesrp&#34;&gt;5-2 単一責任原則(Single Responsibility Principle(SRP))&lt;/h3&gt;
&lt;p&gt;クラスと責務は1対1対応すべき、という指針。&lt;/p&gt;
&lt;h4 id=&#34;単一の責務のみつけかた&#34;&gt;単一の責務のみつけかた&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;クラスの利用者がどんなときに別のクラスや新しいバージョンに交換したいと思うかを想像する。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;実際に起こりそうな交換要求への想像が責務(= クラスのカバー範囲)を見極めるヒントになる。&lt;/p&gt;
&lt;p&gt;たとえば記事クラスが存在し記事の入稿および購読というユースケースがある例では以下のように考えることができる。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;ニュース記事を書く人の事情が変わったけれど、購読ユーザーには従来どおりのサービスを提供したい。逆に、入稿はそのまま、購読ユーザーへのサービスを拡張したい。そんなニーズが起きるのは容易に想像できます。入稿と購読のそれぞれを互いに影響を与えない独立したクラスとしておき、いつでも気兼ねなく別の実装に交換できる単位としておく方が、後で便利に決まっています。なので、ニュース記事管理の場合は、「入稿」と「購読」が、それぞれひとつの責務になります。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;5-3-開放閉鎖原則open-close-principle&#34;&gt;5-3 開放閉鎖原則(Open Close Principle)&lt;/h3&gt;
&lt;p&gt;拡張に対してオープン、変更にたいしてクローズドであるべき、という指針。&lt;/p&gt;
&lt;p&gt;これは書籍内で紹介されていたコード例がわかりやすかった。&lt;/p&gt;
&lt;p&gt;あとはどこが変化する仕様なのかを考えるために一度要件を抽象化してみる方法が紹介されていた。こちらもコード例が示されていたのでイメージが湧きやすかった。&lt;/p&gt;
&lt;h2 id=&#34;第7章-依存性注入&#34;&gt;第7章 依存性注入&lt;/h2&gt;
&lt;p&gt;オブジェクトが使う機能の実体を得る際その解決を自力で行わず、常に外部から与えるようにすべき、という設計方針。&lt;/p&gt;
&lt;p&gt;依存性注入を行うメリットの1つは生成の責務と使用の責務を分けられる点がある。&lt;/p&gt;
&lt;p&gt;また、テスト容易性とDIについては以下のような記述があった。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;単体テストしやすいクラスであることと、DI可能なクラスであるということには、正の相関があります。DIを単に「単体テストのためにやること」といった目的観で考えるのは視野狭窄ではあるのですが、単体テストがアーキテクチャへの気づきの手段として、とても有用なのは間違いありません。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;テストが書きずらかったら設計を疑ってみるのも1つの手かもしれない。&lt;/p&gt;
&lt;h2 id=&#34;まとめ&#34;&gt;まとめ&lt;/h2&gt;
&lt;p&gt;よく聞くSOLID原則もやっとちゃんと理解できたし依存性注入に対する理解も深まったので今後に活かしていきたい。&lt;/p&gt;
</content>
    </item>
    
    <item>
      <title>『コンサル一年目が学ぶこと』を読んだ</title>
      <link>https://blog.kyu08.com/pr-344/posts/consultant/</link>
      <pubDate>Sat, 25 Dec 2021 16:15:48 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/pr-344/posts/consultant/</guid>
      <description>コンサル一年目が学ぶこと を読んだ。 何を期待して読んだのか これまで技術の勉強はしたことがあったが、社会人として普遍的なスキルである 問題解決能力</description>
      <content>&lt;p&gt;&lt;a href=&#34;https://www.amazon.co.jp/%E3%82%B3%E3%83%B3%E3%82%B5%E3%83%AB%E4%B8%80%E5%B9%B4%E7%9B%AE%E3%81%8C%E5%AD%A6%E3%81%B6%E3%81%93%E3%81%A8-%E5%A4%A7%E7%9F%B3%E5%93%B2%E4%B9%8B-ebook/dp/B00MA671WW/ref=sr_1_5?adgrpid=89884031168&amp;amp;gclid=CjwKCAiAhreNBhAYEiwAFGGKPLfeLxQ_KIeJv22itv63KSRBjnAb3p0hH0Q0JvgN6FzTeD2J6dcsQBoCs3QQAvD_BwE&amp;amp;hvadid=553974437471&amp;amp;hvdev=c&amp;amp;hvlocphy=1009307&amp;amp;hvnetw=g&amp;amp;hvqmt=e&amp;amp;hvrand=17984675329684059400&amp;amp;hvtargid=kwd-416077613251&amp;amp;hydadcr=27493_14478962&amp;amp;jp-ad-ap=0&amp;amp;keywords=%E3%82%B3%E3%83%B3%E3%82%B5%E3%83%AB&amp;#43;%E4%B8%80&amp;#43;%E5%B9%B4&amp;#43;%E7%9B%AE&amp;#43;%E3%81%8C&amp;#43;%E5%AD%A6%E3%81%B6&amp;#43;%E3%81%93%E3%81%A8&amp;amp;qid=1638793971&amp;amp;sr=8-5&#34; target=&#34;_blank&#34; &gt;コンサル一年目が学ぶこと&lt;/a&gt; を読んだ。&lt;/p&gt;
&lt;h2 id=&#34;何を期待して読んだのか&#34;&gt;何を期待して読んだのか&lt;/h2&gt;
&lt;p&gt;これまで技術の勉強はしたことがあったが、社会人として普遍的なスキルである&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;問題解決能力&lt;/li&gt;
&lt;li&gt;仕事を円滑に進めるためのコミュニケーションの取り方&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;あたりをちゃんと学んだことがなく、一度入門書的なものに触れたいと思っていたので読んでみた。&lt;/p&gt;
&lt;h2 id=&#34;学び&#34;&gt;学び&lt;/h2&gt;
&lt;p&gt;印象に残っているのは以下。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;端的に話す&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;仮説を持って行動する&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;重要なことに時間を使う&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;期待値のすり合わせを怠らない&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Quick and Dirty&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;それぞれ簡単に補足していく。&lt;/p&gt;
&lt;h3 id=&#34;端的に話すtalk-straight&#34;&gt;端的に話す(Talk Straight)&lt;/h3&gt;
&lt;p&gt;聞かれたことに対してストレートに答える。具体的には&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;端的に喋る&lt;/li&gt;
&lt;li&gt;素直に話す&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ことが重要。&lt;/p&gt;
&lt;p&gt;これは相手の立場に立ってみれば当然で、質問をしたのにその答えがなかなか返ってこないと「結局何がいいたいんだ？」となってしまう。&lt;/p&gt;
&lt;p&gt;とは言いつつも、自分自身も自分の思考が整理できていない時は特にだらだらと喋ってしまいがちなので、そういう時はいいチャンスだと思って一旦思考を整理するようにしたい。&lt;/p&gt;
&lt;h3 id=&#34;仮説を持って行動する&#34;&gt;仮説を持って行動する&lt;/h3&gt;
&lt;p&gt;1から10まで調査しきっていては時間が足りない。最低限の調査をして仮説を立てたら、検証 -&amp;gt; 仮説の修正のループを高速で回していくことで限られた時間で精度の高い結論を導くことができる。&lt;/p&gt;
&lt;p&gt;仮説思考を身につける第1歩として、仮説を持つクセをつけるためにあらゆる事象に対して「自分はどう思うのか」「なぜそう思うのか」というスタンスを持つことを心がけたい。&lt;/p&gt;
&lt;h3 id=&#34;重要なことに時間を使う&#34;&gt;重要なことに時間を使う&lt;/h3&gt;
&lt;p&gt;使える時間は限られているので費用対効果を常に意識して時間の使い方を決める。&lt;/p&gt;
&lt;p&gt;仮説思考の話とも繋がるが優先順位を設定して重要な課題から手をつけていきたい。&lt;/p&gt;
&lt;p&gt;自分に振ってきたタスクどうしの優先順位だけでなく、もう一段上の視座で自分/自チームが今本当に取り組むべきことは何なのか、という思考を心がけたい。&lt;/p&gt;
&lt;h3 id=&#34;期待値のすり合わせを怠らない&#34;&gt;期待値のすり合わせを怠らない&lt;/h3&gt;
&lt;p&gt;求められていないことに時間を使っても成果には繋がらない。まずは自分が何を期待されているかを正確に把握することが重要。&lt;/p&gt;
&lt;p&gt;自分の認識がズレていて後になって手戻りが発生することが稀によくあるので、タスクを振られた際などにその場で&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;そのタスクの目的&lt;/li&gt;
&lt;li&gt;求められているアウトプット&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;を明確にするように心がけたい。&lt;/p&gt;
&lt;h3 id=&#34;quick-and-dirty&#34;&gt;Quick and Dirty&lt;/h3&gt;
&lt;p&gt;3日間かけて100% のアウトプットを出すのではなく、まずは3時間で30% のアウトプットをだすべき。&lt;/p&gt;
&lt;p&gt;こまめにアウトプットを行ってフィードバックを得ることができれば間違った方向に進んでしまって時間を浪費する前に軌道修正できる。&lt;/p&gt;
&lt;h2 id=&#34;まとめ&#34;&gt;まとめ&lt;/h2&gt;
&lt;p&gt;この本を読んだことの収穫としては、自分の中でぼんやりと課題感としてあった&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ただがむしゃらに取り組むのではなく効率よく問題を解決するにはどうすればいいのか&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;というイシューへの回答の1つである、&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;重要思考・仮説思考を用いる&lt;/li&gt;
&lt;li&gt;Quick and Dirty&lt;/li&gt;
&lt;li&gt;期待値のすり合わせを怠らない&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;という考え方に出会えたことが挙げられると思う。&lt;/p&gt;
&lt;p&gt;また、コンサルタントのプロフェッショナリズムに触れて自分も周囲の期待を越え続ける存在でありたいと思った。&lt;/p&gt;
&lt;h3 id=&#34;おまけ&#34;&gt;おまけ&lt;/h3&gt;
&lt;p&gt;「仮説思考をやっていこうと思いました」(意訳) という話を上長にしたところ『イシューからはじめよ』をおすすめされたのでこちらも読んでみようと思う。&lt;/p&gt;
</content>
    </item>
    
  </channel>
</rss>
