<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>CS on blog.kyu08.com</title>
    <link>https://blog.kyu08.com/pr-344/tags/cs/</link>
    <description>Recent content in CS on blog.kyu08.com</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>ja</language>
    <copyright>blog.kyu08.com</copyright>
    <lastBuildDate>Sun, 12 Apr 2026 17:48:08 +0900</lastBuildDate><atom:link href="https://blog.kyu08.com/pr-344/tags/cs/index.xml" rel="self" type="application/rss+xml" />
    <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>『コンピュータシステムの理論と実装 第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>CS50.jpでCSに入門した</title>
      <link>https://blog.kyu08.com/pr-344/posts/cs50-jp/</link>
      <pubDate>Sun, 12 May 2024 06:32:42 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/pr-344/posts/cs50-jp/</guid>
      <description>CS50.jpの気になっていたトピックを学んでみたので振り返っておく。 CS50.jpとは CS50.jpの説明はサイトから引用する。 このページ</description>
      <content>&lt;p&gt;&lt;a href=&#34;https://cs50.jp/&#34; target=&#34;_blank&#34; &gt;CS50.jp&lt;/a&gt;の気になっていたトピックを学んでみたので振り返っておく。&lt;/p&gt;
&lt;h2 id=&#34;cs50jpとは&#34;&gt;CS50.jpとは&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://cs50.jp/&#34; target=&#34;_blank&#34; &gt;CS50.jp&lt;/a&gt;の説明はサイトから引用する。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;このページは、ハーバード大学 CS50 の日本語版翻訳プロジェクトのページです。当サイトのドメインに掲載されているコンテンツは、Creative Commons ライセンスが適用されています。個人利用のほか、非営利に限って教材として利用することができます。&lt;/p&gt;
&lt;p&gt;（中略）&lt;/p&gt;
&lt;p&gt;ハーバード大学の CS50x は、コンピュータサイエンスとプログラミング技術を紹介するコースで、プログラミングの経験の有無にかかわらず、経験者と未経験者の両方を対象としています。David J. Malan が担当するエントリーレベルのコースである CS50x では、アルゴリズム的に考え、問題を効率的に解決する方法を学びます。テーマは、抽象化、アルゴリズム、データ構造、カプセル化、リソース管理、セキュリティ、ソフトウェアエンジニアリング、ウェブ開発など。言語は C、Python、SQL、JavaScript に加え、CSS と HTML を使用します。問題集は、生物学、暗号、金融、科学捜査、ゲームなどの実世界の領域からヒントを得ています。CS50x の学内版である CS50 は、ハーバード大学で最大のコースです。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;カリキュラムは次のような構成になっている。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Week0 Scratch&lt;/li&gt;
&lt;li&gt;Week1 C&lt;/li&gt;
&lt;li&gt;Week2 Arrays&lt;/li&gt;
&lt;li&gt;Week3 Algorithms&lt;/li&gt;
&lt;li&gt;Week4 Memory&lt;/li&gt;
&lt;li&gt;Week5 Data Structures&lt;/li&gt;
&lt;li&gt;Week6 Python&lt;/li&gt;
&lt;li&gt;Week7 SQL&lt;/li&gt;
&lt;li&gt;Week8 HTML, CSS, JavaScript&lt;/li&gt;
&lt;li&gt;Week9 Flask&lt;/li&gt;
&lt;li&gt;Week10 Ethics&lt;/li&gt;
&lt;li&gt;Security&lt;/li&gt;
&lt;li&gt;Artificial Intelligence&lt;/li&gt;
&lt;li&gt;Final Project&lt;/li&gt;
&lt;/ul&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;p&gt;&lt;img src=&#34;check50.webp&#34; alt=&#34;check50&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;正直にいうと日本語訳がなかったら取り組もうと思わなかったと思うのでCS50.jpの翻訳コントリビュータであるCODEGYM社には感謝してもしきれない。本当にありがとうございます。&lt;/p&gt;
&lt;h2 id=&#34;そもそもなぜcsを勉強しているか&#34;&gt;そもそもなぜCSを勉強しているか&lt;/h2&gt;
&lt;p&gt;前提として筆者について補足しておくと筆者は電気系の学部・大学院を卒業しておりコンピューターサイエンスのバックグラウンドを持っていない。（かつSaaS企業でソフトウェアエンジニアとして働き初めて現在4年目）&lt;/p&gt;
&lt;p&gt;「〜という分野に精通して自分の業務パフォーマンスを向上させる」のような明確な目的意識はないがおおむね以下のような理由でやっている。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CSの知識を習得することでソフトウェアエンジニアとして見える世界がどう変わるのか知りたい&lt;/li&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;Week6 Python以降は自分にとって大きな学びはなさそうだったのでWeek5 Data Structuresの課題（Lab &amp;amp; Problem Set）までを取り組んだ。2024/3/8~2024/5/3まで平日夜や土日の時間を使って取り組んだ。&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/cs50&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://github.com/kyu08/cs50&#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/00035094a7bc93b522fdb700816e4bfc25f62a40b9d4f3f466c0adec9dc315b5/kyu08/cs50&#34; alt=&#34;GitHub - kyu08/cs50: https://cs50.jp/&#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/cs50: https://cs50.jp/&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;https://cs50.jp/. Contribute to kyu08/cs50 development by creating an account on GitHub.&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://github.com/kyu08/cs50&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;h3 id=&#34;csの基礎&#34;&gt;CSの基礎&lt;/h3&gt;
&lt;p&gt;CSの基礎の導入部分くらいには触れることができたと思う。たとえばこのあたり。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ASCIIとは&lt;/li&gt;
&lt;li&gt;Cで記述したプログラムが実行可能になるまでの流れ&lt;/li&gt;
&lt;li&gt;アルゴリズム
&lt;ul&gt;
&lt;li&gt;O記法とΩ記法&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;/ul&gt;
&lt;p&gt;ただ、各週の講義動画は1.5hくらいのボリュームなのであくまでそれぞれのトピックの序章（または序章の導入部分）くらいの内容だとは思う。&lt;/p&gt;
&lt;h3 id=&#34;c言語の基礎&#34;&gt;C言語の基礎&lt;/h3&gt;
&lt;p&gt;あとはWeek1 ~ Week5までの課題はすべてC言語で課されたのだが、C言語の経験が得られたのは自分にとって貴重だった。(各Weekの課題が2~3問あり合計で14問の課題をC言語で解いた。)&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;C言語を触ることで現在自分がよく触っている言語であるGoやRustがいかに便利かを思い知った。&lt;/p&gt;
&lt;p&gt;あとはC言語で書かれたOSSやサンプルコードの理解を多少は深めやすくなったので今後の学習・調査の助けになってくれそう。&lt;/p&gt;
&lt;h2 id=&#34;まとめ&#34;&gt;まとめ&lt;/h2&gt;
&lt;p&gt;全体感としてはCSの勉強をやっていく上での基礎的な知識を学ぶことができ、今後の学習の足がかりになってくれそうだったので取り組んでみてよかった。あとはC言語の経験が得られてよかった。&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;テストケースは&lt;a href=&#34;https://github.com/cs50/problems&#34; target=&#34;_blank&#34; &gt;cs50/problems&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;/ol&gt;
&lt;/div&gt;
</content>
    </item>
    
  </channel>
</rss>
