<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>blog.kyu08.com</title>
    <link>https://blog.kyu08.com/</link>
    <description>Recent content 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/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>『プログラミング言語C 第2版』を読んだ</title>
      <link>https://blog.kyu08.com/posts/k_and_r/</link>
      <pubDate>Sun, 12 Apr 2026 17:48:08 +0900</pubDate>
      
      <guid>https://blog.kyu08.com/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/posts/how-networks-work/</link>
      <pubDate>Sat, 04 Apr 2026 16:45:52 +0900</pubDate>
      
      <guid>https://blog.kyu08.com/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>Go Conference mini in Sendai 2026に参加した</title>
      <link>https://blog.kyu08.com/posts/go-con-mini-in-sendai-2026/</link>
      <pubDate>Sun, 01 Mar 2026 09:00:32 +0900</pubDate>
      
      <guid>https://blog.kyu08.com/posts/go-con-mini-in-sendai-2026/</guid>
      <description>2026/02/21(土)に仙台で行われたGo Conference mini in Sendai 2026に参加したのでその内容をまとめる。 Go Conference mini in Sendai 20262026年2月21日（土）</description>
      <content>&lt;p&gt;&lt;img src=&#34;closing-slide.webp&#34; alt=&#34;&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;2026/02/21(土)に仙台で行われたGo Conference mini in Sendai 2026に参加したのでその内容をまとめる。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://sendaigo.jp/&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://sendaigo.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://sendaigo.jp/ogp.png&#34; alt=&#34;Go Conference mini in Sendai 2026&#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 Conference mini in Sendai 2026&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;2026年2月21日（土）開催 - Go Forward Together - 東北から広がるGoコミュニティ&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://sendaigo.jp/&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;h2 id=&#34;keynote静的解析からみるgoの過去と未来&#34;&gt;【KeyNote】静的解析からみるGoの過去と未来&lt;/h2&gt;
&lt;p&gt;tenntennさんによるキーノート。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;embed-container google-slides&#34;&gt;
      &lt;iframe src=&#34;https://docs.google.com/presentation/d/14e9PiaKbyqcZTu5mYCKBqa9MokJhxmT0WePHxwPzCmg/embed?start=false&amp;loop=false&amp;delayms=3000&#34; frameborder=&#34;0&#34; width=&#34;960&#34; height=&#34;569&#34; allowfullscreen=&#34;true&#34; mozallowfullscreen=&#34;true&#34; webkitallowfullscreen=&#34;true&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;&lt;/p&gt;
&lt;p&gt;最後に紹介されていたGo1.27のアノテーションで静的解析をできるようにする機能は今まさに自分が欲している機能&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;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;//line a.go:1&lt;/code&gt;のような記法は知らなかった。
&lt;ul&gt;
&lt;li&gt;調べてみたところ&lt;code&gt;line directive&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;/li&gt;
&lt;li&gt;こんな感じでコンパイラが出力するエラーメッセージなどが上書きされる。
&lt;ul&gt;
&lt;li&gt;&lt;img src=&#34;line-directive.webp&#34; alt=&#34;&#34; loading=&#34;lazy&#34; /&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://go.dev/play/p/Thvs9U8Twvj&#34; target=&#34;_blank&#34; &gt;https://go.dev/play/p/Thvs9U8Twvj&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;自動生成されたコードのエラーを元のコードの行番号で表示したいときなどに使われるらしい。(例えば自動生成されたGoファイルでのエラーに対してprotoファイルの行番号をエラーに表示したいケースなど)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;go test -cover&lt;/code&gt;を実行すると裏側では&lt;code&gt;go tool cover&lt;/code&gt;が実行され、計測用のコードが挿入される&lt;/li&gt;
&lt;li&gt;Goがセルフホスティングされるようになったのは2015年（Go1.5）（それまではC）
&lt;ul&gt;
&lt;li&gt;(まだ10年しかたってないんだなー)&lt;/li&gt;
&lt;li&gt;ここからコンパイラのコードが既存標準パッケージと共通化されたりするようになった&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;2019
&lt;ul&gt;
&lt;li&gt;goplsが登場&lt;/li&gt;
&lt;li&gt;最初はgolspだったがしれっと名前が変わったらしいw&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Go 1.27
&lt;ul&gt;
&lt;li&gt;アノテーションによる静的解析
&lt;ul&gt;
&lt;li&gt;一点もののlinterを作らなくてよくなる。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;//go:fix inline&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://go.dev/doc/go1.26#go-command&#34; target=&#34;_blank&#34; &gt;https://go.dev/doc/go1.26#go-command&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;xxしたあとにyyする、みたいな制約をアノテーションで表現できるようになる（らしい。が一次情報は見つけられていない）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;ai時代のgo開発2026-爆速開発のためのガードレール&#34;&gt;AI時代のGo開発2026 爆速開発のためのガードレール&lt;/h2&gt;
&lt;p&gt;UPSIDERのRyo MimuraさんによるAI時代の開発生産性を保つにあたっての課題と対策についてのセッション。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;embed-container docswell&#34;&gt;
      &lt;div class=&#34;docswell-placeholder&#34; data-src=&#34;https://www.docswell.com/s/r4mimu/ZQXGNY-2026-02-21-102435?slide=1&#34; style=&#34;width:100%;height:569px;background:#f0f0f0;display:flex;align-items:center;justify-content:center;color:#666;&#34;&gt;Loading...&lt;/div&gt;
    &lt;/div&gt;&lt;/p&gt;
&lt;p&gt;最近PRレビューをする機会が増えてレビュワーとPR作成者双方の負担を減らす方法を考えていたのでとても参考になった。&lt;/p&gt;
&lt;p&gt;以下メモ。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;AIの予期せぬ変更はRules / Skillsでもある程度は防げるがあくまで挙動は非決定的なためすり抜けてしまう可能性がある。そのためハード制約（決定的な処理による制約）を設けることが重要。&lt;/li&gt;
&lt;li&gt;ハード制約の例
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;internal&lt;/code&gt; packageで予期せぬ外部参照から保護する&lt;/li&gt;
&lt;li&gt;&lt;code&gt;depguard&lt;/code&gt;による依存性ルールの強制&lt;/li&gt;
&lt;li&gt;Package by Featureで凝集性を向上させることでコンテキストをうまく制御する&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Fuzzing Test, Mutation Testingなどのテスト手法を活用してコード品質を保つ&lt;/li&gt;
&lt;li&gt;開発者体験 = エージェント体験
&lt;ul&gt;
&lt;li&gt;両者は同じもの。&lt;/li&gt;
&lt;li&gt;環境構築、テストとフィードバック、可観測性等開発者体験が悪ければAI Agentもうまく開発を進めることはできなくなる。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;go-での並列処理-最初の一歩から次の一歩へ&#34;&gt;Go での並列処理 「最初の一歩」から「次の一歩」へ&lt;/h2&gt;
&lt;p&gt;TakasagoさんによるGoでの並行処理についてのセッション。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;embed-container google-slides&#34;&gt;
      &lt;iframe src=&#34;https://docs.google.com/presentation/d/1SpK9Pxsh2QOOXwIirNe3YiN6U5ujAxiottt4ZNPdBkg/embed?start=false&amp;loop=false&amp;delayms=3000&#34; frameborder=&#34;0&#34; width=&#34;960&#34; height=&#34;569&#34; allowfullscreen=&#34;true&#34; mozallowfullscreen=&#34;true&#34; webkitallowfullscreen=&#34;true&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;&lt;/p&gt;
&lt;p&gt;並行処理の原理だけでなく、パターンを身につけておくといざ実装するとなったときに役に立ちそうだと思った。（なかなか毎月書くような機会がないのであまり定着してない&amp;hellip;）&lt;/p&gt;
&lt;p&gt;以下メモ。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Goは同期で書いておいて高速化したい箇所だけ並列化する、という書き方がやりやすいのが特徴。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;go126のruntimemetricsが便利そうな件&#34;&gt;Go.1.26のruntime/metricsが便利そうな件（？）&lt;/h2&gt;
&lt;p&gt;o_ga09さんによる発表。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;embed-container google-slides&#34;&gt;
      &lt;iframe src=&#34;https://docs.google.com/presentation/d/1mamepeOir5fiEh3ZcGuRM9kkEvQohCcKeZIsKwZ6_L4/embed?start=false&amp;loop=false&amp;delayms=3000&#34; frameborder=&#34;0&#34; width=&#34;960&#34; height=&#34;569&#34; allowfullscreen=&#34;true&#34; mozallowfullscreen=&#34;true&#34; webkitallowfullscreen=&#34;true&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;&lt;/p&gt;
&lt;p&gt;goroutineリークをリアルタイムに検出できるの便利そう。&lt;/p&gt;
&lt;h2 id=&#34;モジュラモノリスにおける境界をgoのinternalパッケージで守る&#34;&gt;モジュラモノリスにおける境界をGoのinternalパッケージで守る&lt;/h2&gt;
&lt;p&gt;SODA inc.のmagavelさんによる発表。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;embed-container speakerdeck&#34;&gt;
        &lt;iframe src=&#34;https://speakerdeck.com/player/52cdc21278874c8dafb7a21812d6bd81&#34; allowfullscreen=&#34;true&#34; mozallowfullscreen=&#34;true&#34; webkitallowfullscreen=&#34;true&#34;&gt;&lt;/iframe&gt;
      &lt;/div&gt;&lt;/p&gt;
&lt;p&gt;メモ:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;「結合はむしろ、忘れてはならない設計ツールだ。」&lt;/li&gt;
&lt;li&gt;&lt;code&gt;bounded_context&lt;/code&gt;ディレクトリを切っているのが印象的だった&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;お話したこと:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ディレクトリ構成について
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;bounded_context&lt;/code&gt;ディレクトリの同階層には&lt;code&gt;monolish&lt;/code&gt;ディレクトリがある
&lt;ul&gt;
&lt;li&gt;これらは現状ワンバイナリになっている&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;bounded_context&lt;/code&gt;ディレクトリの中には購入、xxx、yyyなどの境界づけられたコンテキストが並ぶ。&lt;/li&gt;
&lt;li&gt;たとえば購入コンテキストの中には購入モジュール、決済モジュールなどがある。&lt;/li&gt;
&lt;li&gt;購入モジュールからは決済モジュールの公開されたIFを呼び出すようになっている。&lt;/li&gt;
&lt;li&gt;公開したくないパッケージはすべてinternal配下に置くことで予期しない依存を防いでいる。&lt;/li&gt;
&lt;li&gt;他にも&lt;code&gt;depguard&lt;/code&gt;を使って依存関係を制御している。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;go設計思想の深掘り&#34;&gt;Go設計思想の深掘り&lt;/h2&gt;
&lt;p&gt;k_program510さんによる発表。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;embed-container speakerdeck&#34;&gt;
        &lt;iframe src=&#34;https://speakerdeck.com/player/bf88016d5fe349edb4eee19de56f94c2&#34; allowfullscreen=&#34;true&#34; mozallowfullscreen=&#34;true&#34; webkitallowfullscreen=&#34;true&#34;&gt;&lt;/iframe&gt;
      &lt;/div&gt;&lt;/p&gt;
&lt;p&gt;メモ:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;発表者の方がオブジェクト指向言語に慣れていてGoにクラスがないことに驚いてGo誕生の背景を深ぼろうと思った、という自分の疑問に向き合う姿勢がとても素敵だと思った。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;設計思想は「どこで使うべきか」を教えてくれる&lt;/code&gt;いい言葉だ。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;databasesqldriverを理解してカスタムデータベースドライバーを作る&#34;&gt;database/sql/driverを理解してカスタムデータベースドライバーを作る&lt;/h2&gt;
&lt;p&gt;replu5さんによる発表。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;embed-container speakerdeck&#34;&gt;
        &lt;iframe src=&#34;https://speakerdeck.com/player/71c311a482f14af59e5808230f22dae3&#34; allowfullscreen=&#34;true&#34; mozallowfullscreen=&#34;true&#34; webkitallowfullscreen=&#34;true&#34;&gt;&lt;/iframe&gt;
      &lt;/div&gt;&lt;/p&gt;
&lt;p&gt;メモ:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;カスタムデータベースドライバーを作る理由
&lt;ul&gt;
&lt;li&gt;ログをだしたい&lt;/li&gt;
&lt;li&gt;リクエストをDBのwriteインスタンスとreadインスタンスに振り分けたい&lt;/li&gt;
&lt;li&gt;sqlcを使っているが、sqlcが生成したコードに手を加えていくのは避けたい&lt;/li&gt;
&lt;li&gt;本体をforkしてしまうと本体に追従するのが大変なので既存のドライバーをラップしたドライバーを作成することにした&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;お話したこと&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;sqlcだと引数に応じてwhere句を一部変更することができないと思うがどうやっているのか。
&lt;ul&gt;
&lt;li&gt;そういうケースでは複数パターンのクエリを（愚直に）repository層に書いている。&lt;/li&gt;
&lt;li&gt;そもそも巨大で複雑なクエリにはsqlcは適していないので使うべきではないかもしれない。
&lt;ul&gt;
&lt;li&gt;（技術の思想や特徴を理解し適切な場所で使うべき、という姿勢は↑のk_program510さんの『Go設計思想の深掘り』とも通じることがあると感じた。）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;nilとは何か-言語仕様と設計者の葛藤から理解する&#34;&gt;nilとは何か 〜言語仕様と設計者の葛藤から理解する〜&lt;/h2&gt;
&lt;p&gt;株式会社サイバーエージェント kurodaさんによる発表。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;embed-container speakerdeck&#34;&gt;
        &lt;iframe src=&#34;https://speakerdeck.com/player/a0086a4f622f413b83f12560bf8fb2a2&#34; allowfullscreen=&#34;true&#34; mozallowfullscreen=&#34;true&#34; webkitallowfullscreen=&#34;true&#34;&gt;&lt;/iframe&gt;
      &lt;/div&gt;&lt;/p&gt;
&lt;p&gt;以下メモ。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Goで定義されているキーワード数を即答している人が数人いてすごかったw（25個らしい）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;nil&lt;/code&gt;はキーワードではない。&lt;code&gt;true&lt;/code&gt;, &lt;code&gt;false&lt;/code&gt;, &lt;code&gt;iota&lt;/code&gt;と同じpredeclared identifier(事前宣言された識別子)である。&lt;/li&gt;
&lt;li&gt;predeclared identifierのなかでデフォルト型を持たないのは&lt;code&gt;nil&lt;/code&gt;だけ。&lt;/li&gt;
&lt;li&gt;（ちょいちょいクイズが挟まっていて参加者を飽きさせない工夫があって発表の仕方が参考になった）&lt;/li&gt;
&lt;li&gt;interfaceが==nilになるのは型情報もデータも両方ゼロのときのみ。
&lt;ul&gt;
&lt;li&gt;なのでtyped nilは==nilにならない。
&lt;ul&gt;
&lt;li&gt;-&amp;gt; &lt;code&gt;var err *MyError = nil&lt;/code&gt;のように初期化した値は==nilにならないのでnilをreturnしたい場合は明示的にnilを返す必要がある。（全然知らなかった）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;nilに関する問題をどう解決するかの議論がなかなか前に進んでいないことを説明してからの&lt;code&gt;errors.AsType&lt;/code&gt;をセマンティクスを変えずにうまく問題を解決した例として説明する流れがめっちゃ綺麗だった。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;who-tests-the-tests-&#34;&gt;Who tests the &lt;code&gt;Tests&lt;/code&gt; ?&lt;/h2&gt;
&lt;p&gt;sivchariさんの発表。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;embed-container google-slides&#34;&gt;
      &lt;iframe src=&#34;https://docs.google.com/presentation/d/1we1bAhUH-_hCEZTYFy2DOyFjWN0fp7VWBkWBha8nwk4/embed?start=false&amp;loop=false&amp;delayms=3000&#34; frameborder=&#34;0&#34; width=&#34;960&#34; height=&#34;569&#34; allowfullscreen=&#34;true&#34; mozallowfullscreen=&#34;true&#34; webkitallowfullscreen=&#34;true&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;&lt;/p&gt;
&lt;p&gt;メモ:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;AI時代になってCIの重要性が増している。&lt;/li&gt;
&lt;li&gt;カバレッジだけを追っていくと本質的でないテストコードが増えてしまう。&lt;/li&gt;
&lt;li&gt;テストコードのテストとしてMutation Testingという手法を紹介する。&lt;/li&gt;
&lt;li&gt;Mutation Testing
&lt;ul&gt;
&lt;li&gt;プログラムの一部を意図的に書き換え、生成したミュータントに対してテストを実行し、失敗するかどうかを検証する手法。
&lt;ul&gt;
&lt;li&gt;演算子の変更、&lt;code&gt;else&lt;/code&gt;ブロックの削除など&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;失敗することを期待するテスト(&lt;code&gt;KILLED&lt;/code&gt;: テスト失敗 == 期待した挙動、&lt;code&gt;SURVIVED&lt;/code&gt;: テスト成功 == 期待した挙動ではない)&lt;/li&gt;
&lt;li&gt;どれくらい失敗したかを指標にする。&lt;/li&gt;
&lt;li&gt;ただこれは銀の弾丸ではない。実行時間とのトレードオフになる。
&lt;ul&gt;
&lt;li&gt;100% &lt;code&gt;KILLED&lt;/code&gt;を目指すべきではない。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Mutation Testingをどう実装するか
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/sivchari/gomu&#34; target=&#34;_blank&#34; &gt;sivchari/gomu&lt;/a&gt;というMutation Testingライブラリを作成した。&lt;/li&gt;
&lt;li&gt;overlayを使うと実際のファイルを仮想的に変更して実行できる
&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;p&gt;感想:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;overlayすごそう&lt;/li&gt;
&lt;li&gt;気になったこと
&lt;ul&gt;
&lt;li&gt;mutation testingの使い所について
&lt;ul&gt;
&lt;li&gt;実際のプロダクションに導入するならある程度テストが整備されたあとにやるのが優先順位としてよい？（Mutation Testingがちゃんと動作することの前提としてある程度のカバレッジが必要そう）&lt;/li&gt;
&lt;li&gt;あとは不慣れな巨大コードと向き合うときにmutation testを実行してみてテスト品質を把握する、というのもいいかもしれない。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;mutation testing以外のテスト品質保証手法について
&lt;ul&gt;
&lt;li&gt;あまりテストの品質を定量的、機械的に保証する方法をカバレッジ以外に考えたことがなかった。&lt;/li&gt;
&lt;li&gt;mutation testing以外ではどのようにテストコードの品質や正当性を保証するのがよさそう？&lt;/li&gt;
&lt;li&gt;たとえばk8sの内部実装などではどのように品質担保しているのか気になった（気になっただけで調べられてはいない）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;goから学ぶgcの仕組みとgreen-tea-gcによる次世代最適化&#34;&gt;Goから学ぶGCの仕組みとGreen Tea GCによる次世代最適化&lt;/h2&gt;
&lt;p&gt;go_poron10さんによる発表。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;embed-container speakerdeck&#34;&gt;
        &lt;iframe src=&#34;https://speakerdeck.com/player/17dc2bf5b4ed4a1d8c289ad77f26cd8c&#34; allowfullscreen=&#34;true&#34; mozallowfullscreen=&#34;true&#34; webkitallowfullscreen=&#34;true&#34;&gt;&lt;/iframe&gt;
      &lt;/div&gt;&lt;/p&gt;
&lt;p&gt;とても内容が高度で途中でついていけなくなってしまったのでいつかリベンジしたい。&lt;/p&gt;
&lt;h2 id=&#34;実装公開goで実現する堅牢なアーキテクチャdddgrpc-connectそしてai協調開発の実践&#34;&gt;【実装公開】Goで実現する堅牢なアーキテクチャ：DDD、gRPC-connect、そしてAI協調開発の実践&lt;/h2&gt;
&lt;p&gt;株式会社テレシーのDaisuke Sasakiさんによる発表。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;embed-container speakerdeck&#34;&gt;
        &lt;iframe src=&#34;https://speakerdeck.com/player/0592dd9c358e4ea9b74adf758ddb546a&#34; allowfullscreen=&#34;true&#34; mozallowfullscreen=&#34;true&#34; webkitallowfullscreen=&#34;true&#34;&gt;&lt;/iframe&gt;
      &lt;/div&gt;&lt;/p&gt;
&lt;p&gt;お話したこと:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;application層のQuery Serviceからdomain packageへの依存はOKにしている？それとも独自のreturn typeをQuery serviceで定義している？
&lt;ul&gt;
&lt;li&gt;依存OKにしている。&lt;/li&gt;
&lt;li&gt;domain層に以下の2種類があり、それぞれ別パッケージに定義している。
&lt;ul&gt;
&lt;li&gt;commandとqueryの両方から参照される型(tier1)&lt;/li&gt;
&lt;li&gt;queryからのみ参照される型(tier2)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;スポンサーブースで話したこと一部抜粋&#34;&gt;スポンサーブースで話したこと（一部抜粋）&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ANDPAD
&lt;ul&gt;
&lt;li&gt;意外にもGo関連の勉強会でスポンサーブースを出すのは初とのこと。
&lt;ul&gt;
&lt;li&gt;スポンサーブースが抽選なので出展の機会を得るのは簡単ではないらしい。&lt;/li&gt;
&lt;li&gt;個人的にはGoに力を入れている会社のイメージを2年くらい前から持っていたので意外だった。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;SODA
&lt;ul&gt;
&lt;li&gt;CodeRabbitでレビュー負荷を下げている&lt;/li&gt;
&lt;li&gt;PRレビューはチーム全員で分担して特定の誰かに負担が偏らないようにしている&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;感想&#34;&gt;感想&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ソロ参加だったがセッションの合間や懇親会でたくさんの人と交流できてとても楽しかった。
&lt;ul&gt;
&lt;li&gt;社外のエンジニアと話せるとかなり刺激&amp;amp;学びになるので今後も機会を見つけていろんな勉強会に参加してみようと思った。&lt;/li&gt;
&lt;li&gt;勉強会に参加している人は自分の時間を使って勉強会に参加するくらいなのでモチベが高い（あるいは技術が好きな）人が多いというのはあるかもしれない。（考えてみれば当たり前だが実際に行ってみてそのことを実感できた）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;今年はCSの勉強&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;と並行してGoのインプット &amp;amp; アウトプットを頑張っていこうと思っているのでモチベがいい感じに上がった。
&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;h2 id=&#34;振り返り&#34;&gt;振り返り&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;セッションの合間は発表者の方に質問するためにウロウロしている時間が長かったのもあり、全スポンサーブースを回れなかった。もうちょっといい感じに時間を使えるとよさそう。（スポンサーブースで各社の方とお話するのは楽しいので全部回りたい気持ち）&lt;/li&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;/ul&gt;
&lt;h2 id=&#34;おまけ&#34;&gt;おまけ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;土日に仙台でKing Gnuのライブがあった影響か、土曜は仙台駅付近のホテルがめっちゃ高かったので福島まで移動して宿泊してgot aことなきした。（ありがとうアパホテル）&lt;/li&gt;
&lt;li&gt;福島で食べたお寿司が美味しかった。観光までする（体力的）余裕がなかったのが残念。
&lt;ul&gt;
&lt;li&gt;&lt;img src=&#34;sushi.webp&#34; alt=&#34;&#34; loading=&#34;lazy&#34; /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;なんか新幹線が長かった。
&lt;ul&gt;
&lt;li&gt;&lt;img src=&#34;long-shinkansen.webp&#34; alt=&#34;&#34; loading=&#34;lazy&#34; /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;大AI時代になりPRレビュー負担が肥大化しているのでCIで機械的にコード品質を担保するためにLinterを増やそうと思っているため。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://pkg.go.dev/cmd/compile#hdr-Line_Directives&#34; target=&#34;_blank&#34; &gt;https://pkg.go.dev/cmd/compile#hdr-Line_Directives&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;今は（今更ながら）『ネットワークはなぜつながるのか』を読んでいる。&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;話しかけるときは普通に「お疲れ様です〜」とかでいいんだなという学びを得た。&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</content>
    </item>
    
    <item>
      <title>開発環境現状確認 2026</title>
      <link>https://blog.kyu08.com/posts/development-environment-2026/</link>
      <pubDate>Sun, 15 Feb 2026 00:00:08 +0900</pubDate>
      
      <guid>https://blog.kyu08.com/posts/development-environment-2026/</guid>
      <description>2026年年始に複数の方（や会社）が開発環境について書いていたので2026年時点のスナップショットも兼ねて自分も流行りに乗って書いてみる。 開</description>
      <content>&lt;p&gt;2026年年始に複数の方（や会社）が開発環境について書いていたので2026年時点のスナップショットも兼ねて自分も流行りに乗って書いてみる。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://blog-dry.com/entry/2026/01/02/145952&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://blog-dry.com/entry/2026/01/02/145952&#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://ogimage.blog.st-hatena.com/8599973812298536260/17179246901338085482/1768574867&#34; alt=&#34;開発環境現状確認（2026年） - Don&amp;#39;t Repeat Yourself&#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;開発環境現状確認（2026年） - Don&amp;#39;t Repeat Yourself&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;覚えてたのでやります。 blog-dry.com 前提として、macOSです。 エディタ Neovimを使っています。仕事ではKotlinを使用しています。KotlinのLanguage Serverは登場しましたが、相変わらずまだ安定的に使える状態にはないのでKotlinを書くときだけ仕方なくIntelliJを使っています。ちなみに別にIntelliJに強い不満があるわけではなく、がんばってlazygitをfloating windowで開かせてそれっぽい動作をさせるなどの涙ぐましいカスタマイズをしています。 なお今年は一瞬Rustのコードレビューなどをする時間を仕事で得たのですが、Neov…&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://blog-dry.com/entry/2026/01/02/145952&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://k0kubun.hatenablog.com/entry/development-environment-2026&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://k0kubun.hatenablog.com/entry/development-environment-2026&#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://cdn.image.st-hatena.com/image/scale/9f7e3bf4789f918b60a5c29199c495e03354b3f6/backend=imagemagick;version=1;width=1300/https%3A%2F%2Fcdn-ak.f.st-hatena.com%2Fimages%2Ffotolife%2Fk%2Fk0kubun%2F20260114%2F20260114221351.jpg&#34; alt=&#34;開発環境現状確認 2026 - k0kubun&amp;#39;s blog&#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;開発環境現状確認 2026 - k0kubun&amp;#39;s blog&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;@helloyuki_ さんと @giginet さんがやってて、自分との違いを眺めるのも面白いかと思ったので書いてみる*1。僕の以前の環境は 後悔しているがやめられない開発効率向上術、Neovimを一瞬でVSCode並みに便利にする、自作PC2023: Ryzenをやめた あたりで書いた。 OS Linux、macOS、Windows の3つを、この順に多く使用している。使っている環境が多いほど面倒毎が増えるので、本当なら3つも使わない方が良い。 LinuxはUbuntu 24.04を使っている。よく使うDockerイメージやGitHub Actions環境と同じパッケージ名が使えたり、デス…&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://k0kubun.hatenablog.com/entry/development-environment-2026&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://tech.pepabo.com/2026/01/23/development-environment-2026/&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://tech.pepabo.com/2026/01/23/development-environment-2026/&#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://tech.pepabo.com/blog/2026/01/23/development-environment-2026/images/pepabo-development-environment-2026.png&#34; alt=&#34;ペパボパートナーの開発環境現状確認 2026 - Pepabo Tech Portal&#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;ペパボパートナーの開発環境現状確認 2026 - Pepabo Tech Portal&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;「開発環境現状確認2026」に寄せて、ペパボパートナーの有志の開発環境を紹介します！@名前の環境詳細をみる をクリックして、各メンバーの詳細な環境を確認してみてください。&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://tech.pepabo.com/2026/01/23/development-environment-2026/&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&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;/p&gt;
&lt;h2 id=&#34;os&#34;&gt;OS&lt;/h2&gt;
&lt;p&gt;大学生くらいからmacOSを使っている。あまり不満がなくて好き。（仕事用端末もmacOS）&lt;/p&gt;
&lt;p&gt;唯一あるとしたらゲームがあんまりできないのでこれがちょっとだけ気になっている。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://store.steampowered.com/sale/steammachine&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://store.steampowered.com/sale/steammachine&#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://clan.fastly.steamstatic.com/images/45479024/d2ce7e96bb0ab51817ba37cf61e3ca919d6f7209.jpg&#34; alt=&#34;Steam Machine&#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;Steam Machine&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;Your games on the big screen&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://store.steampowered.com/sale/steammachine&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;5年くらい前に買ったM1 MacBook Air(16GB RAM)の物持ちが良すぎて新しいMacを買うタイミングがなかなか来ない。新しいMacを買うのは楽しいので買いたい気持ちもありつついかんせん困ってないのでなあ&amp;hellip;の気持ち。&lt;/p&gt;
&lt;h2 id=&#34;エディタ&#34;&gt;エディタ&lt;/h2&gt;
&lt;p&gt;（就職した）2021年くらいからNeovimを使っている。厳密には2022年ごろまではJetBrains系のエディタと併用していたが、そこからはNeovimのみを使っている。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;neovim.webp&#34; alt=&#34;&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;キーボードだけで操作しやすいのと起動が早いのとカスタマイズしやすいのが好きでつかっている。（もちろんvimの操作性も気に入っている）&lt;/p&gt;
&lt;p&gt;最近はこんな感じで&lt;a href=&#34;https://github.com/sindrets/diffview.nvim&#34; target=&#34;_blank&#34; &gt;diffview.nvim&lt;/a&gt;を使ってPRのdiffはすべてNeovim上で見るようにしている。コードをレビューしていると周辺の実装も含めて確認したいことがよくあるので、エディタ上でレビューしているとすぐに該当ファイルに飛べて便利。（&lt;a href=&#34;https://github.com/pwntester/octo.nvim&#34; target=&#34;_blank&#34; &gt;octo.nvim&lt;/a&gt;にコメント周りのバグがあったのでレビューコメントの書き込みはGitHubのWebUIから行っている。）&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;neovim-pr-review.webp&#34; alt=&#34;&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://github.com/sindrets/diffview.nvim&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://github.com/sindrets/diffview.nvim&#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/25191950b2cb7462c7f1cc4e494445fb712741740f320073014779957dc0fdab/sindrets/diffview.nvim&#34; alt=&#34;GitHub - sindrets/diffview.nvim: Single tabpage interface for easily cycling through diffs for all modified files for any git rev.&#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 - sindrets/diffview.nvim: Single tabpage interface for easily cycling through diffs for all modified files for any git rev.&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;Single tabpage interface for easily cycling through diffs for all modified files for any git rev. - sindrets/diffview.nvim&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://github.com/sindrets/diffview.nvim&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;今はGo/TypeScript/Rustあたりしか書いてないので特に困ってないが、JVM系をNeovimで書こうとすると若干辛みがあるかもしれない。（ちょっとだけJava/ScalaをNeovimで書いたことがあるが重かったり不安定だったりして辛かった）&lt;/p&gt;
&lt;p&gt;AI時代になって設定を自分好みにするコストが格段に減ったのでNeovimのカスタマイズが捗っており嬉しい。最近はPRレビュー効率化のための色々をClaude Codeにやってもらっている。（Luaの書き方を覚える前にAI時代が来てしまった&amp;hellip;）&lt;/p&gt;
&lt;p&gt;久々に起動時間を測ってみたら60msくらいになっていたので気が向いたらもうちょっとチューニングしてもいいかもしれない。（たぶん30msくらいまではいけるはず）&lt;/p&gt;
&lt;p&gt;一時期cursorも頑張って設定ファイルを作り込んだうえで慣れようとしてみたが、どうもVSCode系エディタとは思想が合わなかったので結局数日で戻ってきてしまった。&lt;/p&gt;
&lt;h2 id=&#34;aiツール&#34;&gt;AIツール&lt;/h2&gt;
&lt;p&gt;ClaudeとDevin、GitHub Copilotを使っている。&lt;/p&gt;
&lt;p&gt;ClaudeはDesktop App経由で壁打ちや検索用途で使ったり、Claude Codeでコードを書いてもらったりしている。&lt;/p&gt;
&lt;p&gt;Claude Codeを使うときはNeovim plugin等ではなくtmuxのpaneを切ってそこで直接動かしている。&lt;/p&gt;
&lt;p&gt;Devinは主にAsk Devinを使ってコードベースの調査などに使っている。レスポンスがめっちゃ早くてありがたい。&lt;/p&gt;
&lt;p&gt;GitHub Copilotはエディタのインライン補完で使ったり、GitHubのWebUI上でタスクを依頼したりするときに使っている。特にこのブログの機能開発ではよく使っている。（issueさえ書けばそのままWebUIからタスクを依頼できて便利）&lt;/p&gt;
&lt;h2 id=&#34;ターミナルエミュレータ&#34;&gt;ターミナルエミュレータ&lt;/h2&gt;
&lt;p&gt;Alacrittyを使っている。ターミナルにはタブ機能がない方が&lt;code&gt;cmd+w&lt;/code&gt;等を誤爆したりとかが起きないので好きで使っている。（iTerm2を使っていたときはたまに誤爆してシェルが消えて悲しくなっていた。）&lt;/p&gt;
&lt;p&gt;正直早いかどうかはあまりわかってないが特に不満もない。（少し前に日本語入力もいい感じになったし）&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://github.com/alacritty/alacritty&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://github.com/alacritty/alacritty&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail&#34;&gt;
      &lt;img src=&#34;https://repository-images.githubusercontent.com/51980455/c6857780-448b-11ea-95ed-00fdbc59eb0b&#34; alt=&#34;GitHub - alacritty/alacritty: A cross-platform, OpenGL terminal emulator.&#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 - alacritty/alacritty: A cross-platform, OpenGL terminal emulator.&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;A cross-platform, OpenGL terminal emulator. Contribute to alacritty/alacritty development by creating an account on GitHub.&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://github.com/alacritty/alacritty&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;tmuxを使っている。1セッションに好きなだけウィンドウを開く運用で使っている。&lt;/p&gt;
&lt;p&gt;tmux-fzfでのwindow切り替えがとても便利で気に入って使っている。&lt;/p&gt;
&lt;figure class=&#34;video&#34;&gt;
  &lt;video controls preload=&#34;metadata&#34;   &gt;
    &lt;source src=&#34;https://blog.kyu08.com/posts/development-environment-2026/tmux.mp4&#34; type=&#34;video/mp4&#34;&gt;
  &lt;/video&gt;
  &lt;/figure&gt;

&lt;p&gt;設定手順は過去にこちらに書いた。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://blog.kyu08.com/posts/tmux-fzf-window/&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://blog.kyu08.com/posts/tmux-fzf-window/&#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/tmux-fzf-window/cover.png&#34; alt=&#34;tmux-fzfを使ってwindow切り替えをできるようにする手順&#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;tmux-fzfを使ってwindow切り替えをできるようにする手順&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;これはなに こんな感じでtmuxでwindowをfzfで切り替えられるようにするための設定方法 手順 .tmux.confに以下を追記 set -g @plugin &amp;amp;#39;tmux-plugins/tpm&amp;amp;#39; # す&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://blog.kyu08.com/posts/tmux-fzf-window/&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;前述の通りalacrittyとの相性がいい感じなのでよほどのことがない限りこの組み合わせは変えなさそう。&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;Status Lineはこんな感じで画面下側にwindow名と現在時刻を表示している。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;tmux.webp&#34; alt=&#34;&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;詳しくは後述するが、&lt;a href=&#34;https://github.com/nvim-orgmode/orgmode&#34; target=&#34;_blank&#34; &gt;nvim-orgmode/orgmode&lt;/a&gt;でClock In(時間計測)しているタスクがあるときはそのタスク名と経過時間をStatus Lineに表示するようにしている。1つのタスクに集中できて割と作業が捗っている。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;tmux-org-task.webp&#34; alt=&#34;&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;その他のtmuxの設定とか工夫を紹介する記事は別で書きたい。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/zellij-org/zellij&#34; target=&#34;_blank&#34; &gt;Zellij&lt;/a&gt;も試したことはあるが、自分の環境だとなぜか表示が崩れてしまったので使っていない。&lt;/p&gt;
&lt;h2 id=&#34;シェル&#34;&gt;シェル&lt;/h2&gt;
&lt;p&gt;zshを使っている。&lt;/p&gt;
&lt;p&gt;元々はネットに落ちているshellのコードが（fishよりも）動きやすいから、という理由で使っていたのを惰性で使い続けている。&lt;/p&gt;
&lt;p&gt;少し前にこの記事を参考にして起動を高速化したりした。（最近は測ってないが多分今も数10msくらいで起動するはず）&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://zenn.dev/fuzmare/articles/zsh-plugin-manager-cache&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://zenn.dev/fuzmare/articles/zsh-plugin-manager-cache&#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://res.cloudinary.com/zenn/image/upload/s--kunWWsQu--/c_fit%2Cg_north_west%2Cl_text:notosansjp-medium.otf_55:%25E7%25A9%25B6%25E6%25A5%25B5%25E3%2581%25AEzsh%25E3%2583%2597%25E3%2583%25A9%25E3%2582%25B0%25E3%2582%25A4%25E3%2583%25B3%25E8%25AA%25AD%25E3%2581%25BF%25E8%25BE%25BC%25E3%2581%25BF%25E9%25AB%2598%25E9%2580%259F%25E5%258C%2596%253A%2520%25E3%2583%2597%25E3%2583%25A9%25E3%2582%25B0%25E3%2582%25A4%25E3%2583%25B3%25E3%2583%259E%25E3%2583%258D%25E3%2583%25BC%25E3%2582%25B8%25E3%2583%25A3%25E3%2583%25BC%25E3%2581%25AE%25E9%2599%2590%25E7%2595%258C%25E3%2582%2592%25E8%25B6%258A%25E3%2581%2588%25E3%2582%258D%25E3%2580%2590%25E8%25B5%25B7%25E5%258B%2595%25E6%2599%2582%25E9%2596%259314.6ms%25E3%2580%2591%2Cw_1010%2Cx_90%2Cy_100/g_south_west%2Cl_text:notosansjp-medium.otf_37:fuzmare%2Cx_203%2Cy_121/g_south_west%2Ch_90%2Cl_fetch:aHR0cHM6Ly9saDMuZ29vZ2xldXNlcmNvbnRlbnQuY29tL2EtL0FPaDE0R2hXeXNFR1h2VTVUX0ZodzJHYnNQX3M2Z3A5YXpjWWVDanVBaENkcmc9czk2LWM=%2Cr_max%2Cw_90%2Cx_87%2Cy_95/v1627283836/default/og-base-w1200-v2.png?_a=BACAGSGT&#34; alt=&#34;究極のzshプラグイン読み込み高速化: プラグインマネージャーの限界を越えろ【起動時間14.6ms】&#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;究極のzshプラグイン読み込み高速化: プラグインマネージャーの限界を越えろ【起動時間14.6ms】&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://zenn.dev/fuzmare/articles/zsh-plugin-manager-cache&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;2024/4頃から&lt;a href=&#34;https://github.com/yuki-yano/zeno.zsh&#34; target=&#34;_blank&#34; &gt;zeno.zsh&lt;/a&gt;を使っていてよく使うコマンドの実行がかなり効率化できている。snippetがいい感じに展開されるのは言わずもがな嬉しいが、&lt;code&gt;zeno-insert-snippet&lt;/code&gt;でzenoに登録したsnippetをfzfで選択&amp;amp;挿入できるのがとても便利。設定ファイルはまだyaml形式で書いている。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://github.com/yuki-yano/zeno.zsh&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://github.com/yuki-yano/zeno.zsh&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail&#34;&gt;
      &lt;img src=&#34;https://repository-images.githubusercontent.com/360002009/f2a1e442-d89a-40ad-99ab-c3bb3e2d45bc&#34; alt=&#34;GitHub - yuki-yano/zeno.zsh: zsh fuzzy completion and utility plugin with Deno.&#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 - yuki-yano/zeno.zsh: zsh fuzzy completion and utility plugin with Deno.&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;zsh fuzzy completion and utility plugin with Deno. - yuki-yano/zeno.zsh&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://github.com/yuki-yano/zeno.zsh&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;プロンプト表示にはstarshipを使っている。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://github.com/starship/starship&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://github.com/starship/starship&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail&#34;&gt;
      &lt;img src=&#34;https://repository-images.githubusercontent.com/178991158/17096280-8d4d-11e9-97e9-7fed5f61d6bf&#34; alt=&#34;GitHub - starship/starship: ☄🌌️  The minimal, blazing-fast, and infinitely customizable prompt for any shell!&#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 - starship/starship: ☄🌌️  The minimal, blazing-fast, and infinitely customizable prompt for any shell!&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;☄🌌️  The minimal, blazing-fast, and infinitely customizable prompt for any shell! - starship/starship&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://github.com/starship/starship&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;こんな感じでk8sのcontextとnamespaceを表示するようにしている。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;zsh.webp&#34; alt=&#34;&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;誤ってprod環境を壊すことがないようにこんな感じでcontextに&lt;code&gt;prod&lt;/code&gt;という文字列が含まれていたら目立つようにしている。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;zsh-k8s.webp&#34; alt=&#34;&#34; loading=&#34;lazy&#34; /&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-toml&#34; data-lang=&#34;toml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[&lt;span style=&#34;color:#a6e22e&#34;&gt;kubernetes&lt;/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;format&lt;/span&gt; = &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;[[$symbol]($style)\[ctx\]$context \[ns\]$namespace]($style) &amp;#39;&lt;/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;disabled&lt;/span&gt; = &lt;span style=&#34;color:#66d9ef&#34;&gt;false&lt;/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;contexts&lt;/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;context_pattern&lt;/span&gt; = &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;.*dev.*&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;style&lt;/span&gt; = &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;blue&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;symbol&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 style=&#34;color:#a6e22e&#34;&gt;context_pattern&lt;/span&gt; = &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;.*prod.*&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;style&lt;/span&gt; = &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;bold red&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;symbol&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;その他の設定とか便利スクリプトを紹介する記事は別で書きたい。&lt;/p&gt;
&lt;h2 id=&#34;ランチャー&#34;&gt;ランチャー&lt;/h2&gt;
&lt;p&gt;AlfredとRaycastを併用している。&lt;/p&gt;
&lt;p&gt;基本的に不満がないかつ操作性がRaycastよりも好みなので基本的にはAlfredを使っている。&lt;/p&gt;
&lt;p&gt;使い道は至って普通でスニペットやweb検索、ローカルのファイル検索などに使っている。&lt;/p&gt;
&lt;p&gt;あとはWorkflowを利用してよく使うアプリを以下のようなキーバインドで呼び出せるように設定している。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Alacritty: &lt;code&gt;opt + space&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Brave: &lt;code&gt;cmd + esc&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Slack: &lt;code&gt;opt + opt&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Notion: &lt;code&gt;opt + n&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Claude: &lt;code&gt;opt + x&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;TickTick: &lt;code&gt;opt + t&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Spotify: &lt;code&gt;ctrl + esc&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;今は治ってるかもしれないが、一時期Alfredのクリップボードの動作がとてつもなく重くなってしまったのでそこだけRaycastを使っている。&lt;/p&gt;
&lt;h2 id=&#34;ウィンドウマネージャー&#34;&gt;ウィンドウマネージャー&lt;/h2&gt;
&lt;p&gt;yabaiとskhdを使っている。設定をコード管理できるのが嬉しい。たまに動作が不安定になるのでそのたびに&lt;code&gt;yabai --restart-service &amp;amp;&amp;amp; skhd --restart-service&lt;/code&gt;を実行している。とはいえ特に不満もない。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://github.com/asmvik/yabai&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://github.com/asmvik/yabai&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail&#34;&gt;
      &lt;img src=&#34;https://repository-images.githubusercontent.com/184909163/d2ae7e00-d558-11e9-8468-33ce04888bac&#34; alt=&#34;GitHub - asmvik/yabai: A tiling window manager for macOS based on binary space partitioning&#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 - asmvik/yabai: A tiling window manager for macOS based on binary space partitioning&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;A tiling window manager for macOS based on binary space partitioning - asmvik/yabai&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://github.com/asmvik/yabai&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://github.com/asmvik/skhd&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://github.com/asmvik/skhd&#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/aa4145926f55661b08174cbf129ebbdd62108dcfc5d658b4c37f00812bf61d25/asmvik/skhd&#34; alt=&#34;GitHub - asmvik/skhd: Simple hotkey daemon for macOS&#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 - asmvik/skhd: Simple hotkey daemon for macOS&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;Simple hotkey daemon for macOS. Contribute to asmvik/skhd development by creating an account on GitHub.&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://github.com/asmvik/skhd&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;めっちゃ雑に書くとよく使うのはこの辺のやつ。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;windowを右半分に表示&lt;/li&gt;
&lt;li&gt;windowを左半分に表示&lt;/li&gt;
&lt;li&gt;windowを左上に表示&lt;/li&gt;
&lt;li&gt;windowを左下に表示&lt;/li&gt;
&lt;li&gt;windowを右3/4に表示&lt;/li&gt;
&lt;li&gt;windowを左1/4に表示&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;フォント&#34;&gt;フォント&lt;/h2&gt;
&lt;p&gt;M+1Code Nerd Font Monoを使っている。まるっとしていて好き。nerd fontも入っているのでNeovimを使っていても豆腐が出ず嬉しい。（あまり原理はわかってないがCicaなどの他のnerd font対応フォントよりも豆腐が出なくてありがたい）&lt;/p&gt;
&lt;h2 id=&#34;タスク管理&#34;&gt;タスク管理&lt;/h2&gt;
&lt;p&gt;ここ1年くらいは&lt;a href=&#34;https://github.com/nvim-orgmode/orgmode&#34; target=&#34;_blank&#34; &gt;nvim-orgmode/orgmode&lt;/a&gt;を使っている。emacsのorg-modeライクな機能をNeovimで使えるようにしたプラグイン。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://github.com/nvim-orgmode/orgmode&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://github.com/nvim-orgmode/orgmode&#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/bf4256a31866e947ec66e92605e2963c21d3bec42091a8b95e34a4f2db36e5ef/nvim-orgmode/orgmode&#34; alt=&#34;GitHub - nvim-orgmode/orgmode: Orgmode clone written in Lua for Neovim 0.11.0&amp;#43;.&#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 - nvim-orgmode/orgmode: Orgmode clone written in Lua for Neovim 0.11.0&amp;#43;.&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;Orgmode clone written in Lua for Neovim 0.11.0&amp;#43;. Contribute to nvim-orgmode/orgmode development by creating an account on GitHub.&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://github.com/nvim-orgmode/orgmode&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&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-markdown&#34; data-lang=&#34;markdown&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;## TODO
&lt;/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;-&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;## 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:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;-&lt;/span&gt; コードレビュー
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Neovimでタスク管理できるのとタスクに優先度、期日を設定してそれをいい感じにソートして表示してくれるのがかなり肌にあっていて気に入っている。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;nvim-orgmode.webp&#34; alt=&#34;&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;最近は時間の使い方を振り返る目的でClock In的な機能を使ってタスクごとの所要時間も管理してみている。&lt;/p&gt;
&lt;p&gt;これに関してはそのうち別の記事として詳しく書きたい。&lt;/p&gt;
&lt;h2 id=&#34;ブラウザ&#34;&gt;ブラウザ&lt;/h2&gt;
&lt;p&gt;数年前からBraveを使っている。広告をブロックしてくれつつChrome拡張も使えるので便利。一時期Arcも使っていたが肌に合わない挙動があったので使うのをやめてしまった。（具体的には覚えていない）&lt;/p&gt;
&lt;p&gt;よく使うChrome拡張は少し前にこの記事に書いた。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://blog.kyu08.com/posts/chrome-extensions-for-dev-2024/&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://blog.kyu08.com/posts/chrome-extensions-for-dev-2024/&#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/chrome-extensions-for-dev-2024/cover.png&#34; alt=&#34;ソフトウェアエンジニア目線で使ってみて便利だったChrome拡張を紹介する&#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;ソフトウェアエンジニア目線で使ってみて便利だったChrome拡張を紹介する&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;本記事はUnipos Advent Calendar 2024の13日目の記事です。 本記事では使ってみて便利だったChrome拡張を紹介します。 Stylus Stylus ユーザー定義のCSSを&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://blog.kyu08.com/posts/chrome-extensions-for-dev-2024/&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;h2 id=&#34;ime&#34;&gt;IME&lt;/h2&gt;
&lt;p&gt;Google日本語入力を使っている。&lt;/p&gt;
&lt;p&gt;たまーにひらがなの変換がおかしいのが気になっているが全体的には割と満足している。&lt;/p&gt;
&lt;p&gt;azooKeyも試したが辞書登録した単語の優先度が低いのが使いづらくて使うのをやめてしまった。（ライブ変換はとても便利だった。）&lt;/p&gt;
&lt;p&gt;ならissueを立てんかい&amp;hellip;という話ではあるがちょっとこのところ忙しくそこまではできていない。&lt;/p&gt;
&lt;h2 id=&#34;clituiツール&#34;&gt;CLI/TUIツール&lt;/h2&gt;
&lt;p&gt;よく使っているCLI/TUIツールはこのあたり。&lt;/p&gt;
&lt;h3 id=&#34;fzf&#34;&gt;fzf&lt;/h3&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://github.com/junegunn/fzf&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://github.com/junegunn/fzf&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail&#34;&gt;
      &lt;img src=&#34;https://repository-images.githubusercontent.com/13807606/b261cfc9-ec9c-4842-a7dd-366e6674cb50&#34; alt=&#34;GitHub - junegunn/fzf: :cherry_blossom: A command-line fuzzy finder&#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 - junegunn/fzf: :cherry_blossom: A command-line fuzzy finder&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;:cherry_blossom: A command-line fuzzy finder. Contribute to junegunn/fzf development by creating an account on GitHub.&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://github.com/junegunn/fzf&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&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;lazygit&#34;&gt;lazygit&lt;/h3&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://github.com/jesseduffield/lazygit&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://github.com/jesseduffield/lazygit&#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/d2896804693595df8f89ef1047e17c57f1da3702622b4710dd2032efea7b3518/jesseduffield/lazygit&#34; alt=&#34;GitHub - jesseduffield/lazygit: simple terminal UI for git commands&#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 - jesseduffield/lazygit: simple terminal UI for git commands&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;simple terminal UI for git commands. Contribute to jesseduffield/lazygit development by creating an account on GitHub.&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://github.com/jesseduffield/lazygit&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;

&lt;img src=&#34;lazygit.webp&#34; alt=&#34;&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;gitのTUIクライアント。&lt;/li&gt;
&lt;li&gt;gitの操作はすべてlazygitでやっている。&lt;/li&gt;
&lt;li&gt;add commit push pullなどの日常の操作やブランチ操作などをかなり少ないキー入力で行えるのがとても便利。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git rebase -i&lt;/code&gt;相当のことができたり、commitの一部だけstagingに戻したりと細かいこともできる。&lt;/li&gt;
&lt;li&gt;ここ2年くらいで細々とPRを送っており、去年末頃に9番目にcommitが多い人になることができた。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&#34;lazygit-contibutors.webp&#34; alt=&#34;&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;k9s&#34;&gt;k9s&lt;/h3&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://github.com/derailed/k9s&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://github.com/derailed/k9s&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail&#34;&gt;
      &lt;img src=&#34;https://repository-images.githubusercontent.com/167596393/6dd20780-5c0e-11ea-8e26-7754ad171192&#34; alt=&#34;GitHub - derailed/k9s: 🐶 Kubernetes CLI To Manage Your Clusters In Style!&#34; loading=&#34;lazy&#34;&gt;
    &lt;/div&gt;&lt;div class=&#34;blogcard-content&#34;&gt;
      &lt;div class=&#34;blogcard-title&#34;&gt;GitHub - derailed/k9s: 🐶 Kubernetes CLI To Manage Your Clusters In Style!&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;🐶 Kubernetes CLI To Manage Your Clusters In Style! - derailed/k9s&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://github.com/derailed/k9s&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;

&lt;img src=&#34;k9s.webp&#34; alt=&#34;&#34; loading=&#34;lazy&#34; /&gt;
&lt;img src=&#34;k9s-pulse.webp&#34; alt=&#34;&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GKEのリソースを見たり操作したりするときに使っている。とても便利。（画像はサンプル用にkindでローカル起動したクラスタのもの）&lt;/li&gt;
&lt;li&gt;ログはあまり使いこなせてないので普段の開発ではDatadogやCloud Loggingを見ていることが多い。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;&amp;lt;PRここから&amp;gt;&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&#34;fzf-make&#34;&gt;fzf-make&lt;/h3&gt;
&lt;p&gt;fzf-makeというmake targetをfuzzy finder形式で選択、実行できるTUIを開発している。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;fzf-make.gif&#34; alt=&#34;&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;コマンド名やその内容を覚えずとも楽に実行できたり、履歴機能があるのが特徴。&lt;/p&gt;
&lt;p&gt;現在は&lt;code&gt;Makefile&lt;/code&gt;に定義されたmake target以外にも以下のようなコマンドに対応している。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;package.json&lt;/code&gt;の&lt;code&gt;scripts&lt;/code&gt;に定義されたコマンド(pnpm, yarn, npmに対応)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;justfile&lt;/code&gt;に定義されたrecipe&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Taskfile.yml&lt;/code&gt;に定義されたtask&lt;/li&gt;
&lt;/ul&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-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;brew install fzf-make
&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-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cargo +1.90.0 install --locked fzf-make
&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;div class=&#34;blogcard&#34; data-url=&#34;https://github.com/kyu08/fzf-make&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://github.com/kyu08/fzf-make&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail&#34;&gt;
      &lt;img src=&#34;https://repository-images.githubusercontent.com/611369838/a30cf798-2e08-47a5-9443-978329275d2c&#34; alt=&#34;GitHub - kyu08/fzf-make: A command line tool that executes commands using fuzzy finder with preview window for make, npm, pnpm, yarn, just and task.&#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/fzf-make: A command line tool that executes commands using fuzzy finder with preview window for make, npm, pnpm, yarn, just and task.&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;A command line tool that executes commands using fuzzy finder with preview window for make, npm, pnpm, yarn, just and task. - kyu08/fzf-make&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://github.com/kyu08/fzf-make&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&amp;lt;/PRここまで&amp;gt;&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;キーリマッパー&#34;&gt;キーリマッパー&lt;/h2&gt;
&lt;p&gt;Karabiner-Elementsを使っている。&lt;/p&gt;
&lt;p&gt;vimmerなのでAの左側のキーを&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;単押しでesc&lt;/li&gt;
&lt;li&gt;長押しでctrl&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;となるように設定している。&lt;/p&gt;
&lt;p&gt;あとはよくある左cmdを英数、右cmdをかなにリマップする設定とか、ctrl+shift+hjklで←↓↑→が入力する設定とかを入れている。&lt;/p&gt;
&lt;h2 id=&#34;キーボード&#34;&gt;キーボード&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;7sPro
&lt;img src=&#34;7spro.webp&#34; alt=&#34;&#34; loading=&#34;lazy&#34; /&gt;
&lt;ul&gt;
&lt;li&gt;2021/8から使っている。今は家でメインのキーボードとして使っている。&lt;/li&gt;
&lt;li&gt;キースイッチは&lt;a href=&#34;https://shop.yushakobo.jp/products/5659&#34; target=&#34;_blank&#34; &gt;Yushakobo Fairy Silent Linear Switch&lt;/a&gt;を使用。&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://shop.yushakobo.jp/products/7spro&#34; target=&#34;_blank&#34; &gt;https://shop.yushakobo.jp/products/7spro&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;EPOMAKER SPLIT70
&lt;ul&gt;
&lt;li&gt;2026/1に買って職場で使っている。分割キーボードかつガスケットマウントでとても打鍵感が良い。&lt;/li&gt;
&lt;li&gt;キースイッチは同じく&lt;a href=&#34;https://shop.yushakobo.jp/products/5659&#34; target=&#34;_blank&#34; &gt;Yushakobo Fairy Silent Linear Switch&lt;/a&gt;を使用。&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://epomaker.jp/products/epomaker-split70&#34; target=&#34;_blank&#34; &gt;https://epomaker.jp/products/epomaker-split70&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;その他&#34;&gt;その他&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;fuwari
&lt;ul&gt;
&lt;li&gt;スクリーンショットを付箋のように画面上に貼り付けておけるmacアプリ。画面に表示されている何かをちょっとメモ的に見たいときにとても便利&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kentya6/Fuwari&#34; target=&#34;_blank&#34; &gt;https://github.com/kentya6/Fuwari&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;こんな感じで動く
&lt;figure class=&#34;video&#34;&gt;
          &lt;video controls preload=&#34;metadata&#34;   &gt;
            &lt;source src=&#34;https://blog.kyu08.com/posts/development-environment-2026/fuwari.mp4&#34; type=&#34;video/mp4&#34;&gt;
          &lt;/video&gt;
          &lt;/figure&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;まとめ&#34;&gt;まとめ&lt;/h2&gt;
&lt;p&gt;ここ数年で主要な使用ツール（Neovim, tmux, zsh）が変わっていないので安定して自分好みのカスタマイズが進められている。&lt;/p&gt;
&lt;p&gt;AIツールの実装力がかなり上がったのもあり、Neovimやtmuxのカスタマイズも今まで以上にかなり捗るようになっている。&lt;/p&gt;
&lt;p&gt;好みの環境で作業ができると作業自体が楽しくなって仕事や趣味のモチベーションも上がるので2026年もやっていき。&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;これ系の記事でNeovimの使用率が1位になってるの初めて見た。Neovimユーザーとしては嬉しい。&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;画面内の文字を検索するのにcmd+fをよく使うのでGhosttyは自分には合わなかった。&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</content>
    </item>
    
    <item>
      <title>『解像度を上げる』を読んだ</title>
      <link>https://blog.kyu08.com/posts/kaizodo-wo-ageru/</link>
      <pubDate>Wed, 11 Feb 2026 13:00:41 +0900</pubDate>
      
      <guid>https://blog.kyu08.com/posts/kaizodo-wo-ageru/</guid>
      <description>おすすめしていただいて気になっていた『解像度を上げる――曖昧な思考を明晰にする「深さ・広さ・構造・時間」の４視点と行動法』を読んだ。 起業家に</description>
      <content>&lt;p&gt;おすすめしていただいて気になっていた&lt;a href=&#34;https://eijipress.co.jp/products/2318&#34; target=&#34;_blank&#34; &gt;『解像度を上げる――曖昧な思考を明晰にする「深さ・広さ・構造・時間」の４視点と行動法』&lt;/a&gt;を読んだ。&lt;/p&gt;
&lt;p&gt;起業家に向けて書かれている記述が多かったが、いちソフトウェアエンジニアとしても非常に参考になる部分が多かったので自分に刺さったポイントを書いていく。&lt;/p&gt;
&lt;p&gt;なお、引用は特別に断りがない限りすべて同書からのものです。&lt;/p&gt;
&lt;h2 id=&#34;解像度の構成要素&#34;&gt;「解像度」の構成要素&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;解像度の高さが何によって構成されているかを考えたときに見えてきたのが、「深さ」「広さ」「構造」「時間」の４つの視点です。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;解像度の構成要素を「深さ」「広さ」「構造」「時間」の4つと整理する視点&lt;/strong&gt;を得られたのが本書を読んで一番良かったポイントかもしれない。&lt;/p&gt;
&lt;p&gt;この視点があると「なんか解像度が低いぞ&amp;hellip;」となったときにどの要素が足りていないかを考えることで効率的に再現性高く解像度を上げることができそう。他の人のアウトプットへのFBにもかなり便利に使えそう。&lt;/p&gt;
&lt;p&gt;4要素は以下のように理解した。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;深さ:&lt;/strong&gt; 具体性を上げたり、因果関係を深堀りしたりする&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;広さ:&lt;/strong&gt; 網羅性（幅広さ）を上げる&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;構造:&lt;/strong&gt; 「深さ」と「広さ」のステップで出した各要素を構造化する（要素を分解したり整理したりする）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;時間:&lt;/strong&gt; 「過去」「現在」「未来」のような時間軸の観点を盛り込む&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;情報をツリー構造で整理する&#34;&gt;情報をツリー構造で整理する&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;ここまで、深さ、広さ、構造、時間の４つの視点で解像度をチェックしてきました。こうしたチェックをやりやすくする一つの方法としてお勧めなのが、一度自分の理解をツリー構造で整理してみることです。 　&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;本書でも幾度となくツリー構造で分析を整理した図が紹介されていた。&lt;/p&gt;
&lt;p&gt;ツリー構造で書いていくと色々なメリットがあって良さそうので取り入れてみようと思う。&lt;/p&gt;
&lt;p&gt;たとえば思考の現在地が把握しやすくなることでかなり効率よく思考を深めやすくなる気がする。（今自分は仮説1の解決策2について考えているんだな〜みたいなのが一目でわかるので狭くなりがちな思考を広げられたり、他の要素と行ったり来たりしながら思考を深めやすそう。）&lt;/p&gt;
&lt;p&gt;あとは目的意識なく深さと広さを広げすぎるとノイズが増えそうなので構造化するのを忘れないことも大事そう。（このあたりは実際にやってみて調節するのがよさそう）&lt;/p&gt;
&lt;h2 id=&#34;解像度を上げる対象&#34;&gt;解像度を上げる対象&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;上げるべきは、課題と解決策の解像度&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;ビジネスの文脈では特に&lt;strong&gt;課題&lt;/strong&gt;と&lt;strong&gt;解決策&lt;/strong&gt;の解像度を上げることが重要。&lt;/p&gt;
&lt;p&gt;（文字にするとそれはそうという感じにはなってしまうが）「解像度が足りない」と感じたときに足りないのが&lt;strong&gt;課題の解像度&lt;/strong&gt;なのか&lt;strong&gt;解決策の解像度&lt;/strong&gt;なのか両方なのかを分けて考えられるとよりスムーズに成果に繋がりそう。&lt;/p&gt;
&lt;p&gt;（直感的には課題の解像度が上がらないと解決策の精度や解像度は上がらなそうに思えるので前者が前提になりそう。）&lt;/p&gt;
&lt;h2 id=&#34;課題の選び方&#34;&gt;課題の選び方&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;このように課題や問いが重要視される理由は、良い課題を選べるかどうかで生み出される価値がほぼ決まると言っても過言ではないからです。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;『イシューからはじめよ』でもイシュー度が高い課題を解くことの重要性が説かれていたのを思い出した。&lt;/p&gt;
&lt;p&gt;そういう意味でもまずは課題の解像度を上げることが重要かもしれない。（緊急度が高く重要度が低い課題とかはぱっと解決して早く次に行きたい種類の課題なので例外かもしれないが）&lt;/p&gt;
&lt;h2 id=&#34;書くことで考える&#34;&gt;書くことで考える&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;まず取り組んでほしいのは、「今、何が最も重要な課題だと思っているのか、それはなぜなのか」を仮説で良いから最初に書くことです。&lt;/p&gt;
&lt;p&gt;考え抜いた「結果」を書くのではありません。書くことは思考の「過程」です。書くことで私たちは考えることができます。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;ブログに記事を書いたり（まさにこの記事とかがそう）チームで何か意思決定をする際に会議資料を書いたりすることで自分が考えていることがクリアになったり、思考が深まったりすることがよくあるので最後の2文にはすごく共感した。&lt;/p&gt;
&lt;p&gt;文字にすることの効果はかなり感じているので今後も悩んだら（というか何かを考えたいときは）書くことで思考を深めていこうと思った。&lt;/p&gt;
&lt;h2 id=&#34;書くときの留意点&#34;&gt;書くときの留意点&lt;/h2&gt;
&lt;p&gt;課題の解像度を「深さ」の視点で上げるための方法として「現時点での自分の課題認識を書き出す」という方法が紹介されていた。&lt;/p&gt;
&lt;p&gt;その際のポイントとして以下のような点が挙げられていた。&lt;/p&gt;
&lt;p&gt;（他の人に読んでもらうための）わかりやすい文章を書くという観点でも非常に参考になりそうだったので一部を引用して紹介する。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;最初の書き出しは箇条書きでも構いません。ただし、より詳細に課題を検討するときには、文章として長文で書くことをお勧めします。箇条書きを使うと、論理の飛躍や矛盾などに気づきづらいからです。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;箇条書きだと論理的にわかりやすい文書になるかはかなり書き手に依存すると思っているので頷けた。（自分は箇条書き自体がダメだとは思ってないが注意深く使わないと読み手の解釈が一意にならないので気をつけて使おうと思っている派）&lt;/p&gt;
&lt;p&gt;よくあるパターンでいうと以下のようなケースがあると思う。&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;（「なので」「とはいえ」「しかし」などの接続詞が省略されることが多く、）論理的なつながりがわかりづらい&lt;/li&gt;
&lt;li&gt;列挙された項目がシーケンスなのか選択肢なのか、AndなのかOrなのかがわかりづらい&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Amazonでも会議資料に箇条書きだけで構成されたスライドを使うのは禁止らしい。&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;（さすがに社員全員が同一のルールを実践してるとは限らないと思うが）&lt;/p&gt;
&lt;p&gt;なんにせよ読み手が疑問を感じたり2パターン以上の解釈ができてしまうような文章を書かないことを心がけるのがよさそう。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;主語が明確な文にする　&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;これも抜けがちだがクリティカルな齟齬につながりやすいので気をつけたい。（自分の場合はどちらかというと口頭で話してるときに抜けがちかも）&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;動詞を入れる　──　体言止めではなく、動詞を入れるようにしましょう。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;体言止めも読み手に解釈の余地を与えがちなので注意したい。&lt;/p&gt;
&lt;p&gt;たとえば「データ移行の切り戻しは手動。」とドキュメントに書かれていた場合、「手動で行う予定」なのか「手動でしか行えない」（制約の共有）なのか「手動で行った」（完了報告）なのかが明確ではなかったりする。&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;スタートアップに関するエッセイで有名なポール・グレアムも、エッセイを公開する前には必ず声に出して読み上げて、友達に話すような言い回しになっているかを確認しているそうです（４）。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;普段会議資料を書くときに最後は声に出して読んでみて詰まるポイントがないかチェックしているのでこの点も共感できた。うまく話せないところは論理が飛躍していたり変な結論になっていたりするのことが多いので、仕上げとして声に出して読むのは大事そう。&lt;/p&gt;
&lt;p&gt;ことこのブログに関しては書いた後に声に出して読んだりはしていないが良さそうなので試してみようと思った。&lt;/p&gt;
&lt;h2 id=&#34;深める&#34;&gt;深める&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;事例のサーベイが十分できているかどうかの閾値は、関連事例を「１００」程度知っているか&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;（起業ではなく）ソフトウェアエンジニアリングの場面では必ずしも100個必要とは限らないが、他社の事例を知っておくと引き出しが増えるので、知っておくに越したことはないと思う。&lt;/p&gt;
&lt;p&gt;たとえばソフトウェアアーキテクチャのパターンやディレクトリ構成などは書籍やテックブログ、登壇資料で数多く紹介されているのでそういったアウトプットから学べるとよさそう。普段自分が仕事で関わっている領域ではゼロから何も見ずに自分で考えることに価値があるというよりは、効果的な施策や判断に価値があることが多いので重要な意思決定をする際には適切な情報収集をできるとよさそう。&lt;/p&gt;
&lt;p&gt;また、そうしたネット上の資料は無料で公開されていることが多く、そうした環境にかなりお世話になっている自覚があるので自分もアウトプットを続けて少しでも業界、エコシステムに恩返しをしていければなと思う。&lt;/p&gt;
&lt;h2 id=&#34;不慣れな分野のキャッチアップ&#34;&gt;不慣れな分野のキャッチアップ&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;本屋に行って、端から端まで本を買う 　事例のサーベイがある程度終わったら、次は大きめの書店に行き、自分の課題に関連する業界の本を端から端まで買うことをお勧めします。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;著者によって異なる視点から同じ物事を見ることができますし、重複しているのなら、その情報は誰の目から見ても重要だということが分かります。そうして業界の構造やトレンドを深掘りしていくのです。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;特に不慣れな分野に飛び込むときにはこのような方法は効果的そう。&lt;/p&gt;
&lt;p&gt;同じような内容の書籍は1冊読めばいいのでは？と思っていたが複数の著者で共通した内容がある場合はその内容の重要性が担保されるという観点はなるほどと思った。&lt;/p&gt;
&lt;h2 id=&#34;教える&#34;&gt;教える&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;教える 　対話や質問のさらに一歩先の言語化として、教えるがあります。今考えている課題について、よく知らない人に教えるつもりで話してみましょう。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;自分がブログを書いている理由の1つ。あまり人に教えられるような書き方まではできていないが、先の引用でもあったように書くことを通して理解や思考を深められている。社内外の勉強会での登壇などもこれにあたりそう。&lt;/p&gt;
&lt;h2 id=&#34;コミュニティに参加する&#34;&gt;コミュニティに参加する&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;コミュニティに参加すると、深く考えるためのヒントや、情報をもらえます。それに、誰かが近くにいることで、必然的に言語化や壁打ちの機会が生まれます。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;これまであまりコミュニティには参加してこなかったが、今年はGoの知識を深めたいのでチャレンジしてみようと思った。（さっそく2/21のGo Conference mini in Sendai 2026に行ってみることにした）&lt;/p&gt;
&lt;h2 id=&#34;まとめ&#34;&gt;まとめ&lt;/h2&gt;
&lt;p&gt;主に起業家や起業家を志す人に向けて書かれているように感じたが、いちソフトウェアエンジニアとしても参考になる部分が非常に多く、読んでよかった。&lt;/p&gt;
&lt;p&gt;解像度を上げるための4つの視点「深さ」「広さ」「構造」「時間」は非常に有用なフレームワークだと感じたのでしばらくは意識的に使ってみようと思う。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;この箇条書き複数パターンの例示であることが伝わっている&amp;hellip;と信じたい。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://forbesjapan.com/articles/detail/38119&#34; target=&#34;_blank&#34; &gt;https://forbesjapan.com/articles/detail/38119&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;文脈を読めばわかるだろという意見もあるかもしれないが、可能な限りローコンテキストに記述することで読み手の認知負荷低減に繋がり、結果としてコミュニケーションコストを下げられると考えています。&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</content>
    </item>
    
    <item>
      <title>『CQRS Documents by Greg Young』を読んだ</title>
      <link>https://blog.kyu08.com/posts/cqrs-documents-by-greg-young/</link>
      <pubDate>Mon, 12 Jan 2026 00:27:58 +0900</pubDate>
      
      <guid>https://blog.kyu08.com/posts/cqrs-documents-by-greg-young/</guid>
      <description>CQRSに興味があったのでGreg Young氏のCQRS Documentsを読んでみた。 https://cqrs.wordpress.com/wp-content/uploads/2010/11/cqrs_documents.pdfhttps://cqrs.wordpress.com/wp-content/uploads/2010/11/cqrs_documents.pdf CQRSに興味を持ったきっかけ ドメイン層のメンテナ</description>
      <content>&lt;p&gt;CQRSに興味があったのでGreg Young氏の&lt;a href=&#34;https://cqrs.wordpress.com/wp-content/uploads/2010/11/cqrs_documents.pdf&#34; target=&#34;_blank&#34; &gt;CQRS Documents&lt;/a&gt;を読んでみた。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://cqrs.wordpress.com/wp-content/uploads/2010/11/cqrs_documents.pdf&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://cqrs.wordpress.com/wp-content/uploads/2010/11/cqrs_documents.pdf&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail blogcard-thumbnail-placeholder&#34;&gt;
      &lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 24 24&#34; fill=&#34;none&#34; stroke=&#34;currentColor&#34; stroke-width=&#34;2&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34;&gt;
        &lt;path d=&#34;M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71&#34;&gt;&lt;/path&gt;
        &lt;path d=&#34;M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71&#34;&gt;&lt;/path&gt;
      &lt;/svg&gt;
    &lt;/div&gt;&lt;div class=&#34;blogcard-content&#34;&gt;
      &lt;div class=&#34;blogcard-title&#34;&gt;https://cqrs.wordpress.com/wp-content/uploads/2010/11/cqrs_documents.pdf&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://cqrs.wordpress.com/wp-content/uploads/2010/11/cqrs_documents.pdf&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;h2 id=&#34;cqrsに興味を持ったきっかけ&#34;&gt;CQRSに興味を持ったきっかけ&lt;/h2&gt;
&lt;p&gt;ドメイン層のメンテナビリティの重要性を感じる中で、ドメイン層は書き込み系の振る舞いだけを担い、読み取り系の責務は別のモジュールに移譲してしまった方がドメイン層をシンプルに保てて良いのではないかと考えるようになった。&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;それってCQRSってやつじゃね？と思ったのでまずは原典に近いドキュメントを読んでみることにした。&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;ここからは&lt;a href=&#34;https://cqrs.wordpress.com/wp-content/uploads/2010/11/cqrs_documents.pdf&#34; target=&#34;_blank&#34; &gt;CQRS Documents&lt;/a&gt;の内容をまとめていく。&lt;/p&gt;
&lt;h2 id=&#34;a-stereotypical-architecture-典型的なアーキテクチャ&#34;&gt;&amp;ldquo;A Stereotypical Architecture&amp;rdquo;: 典型的なアーキテクチャ&lt;/h2&gt;
&lt;p&gt;&amp;ldquo;A Stereotypical Architecture&amp;quot;として、典型的なアーキテクチャが紹介されている。CQRS Documentsではこのアーキテクチャに対して段階的にCQRSを導入していく形で説明が進んでいく。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;a-stereotypical-architecture.webp&#34; alt=&#34;a-stereotypical-architecture.webp&#34; loading=&#34;lazy&#34; /&gt;
CQRS Documents by Greg Young P2より引用&lt;/p&gt;
&lt;p&gt;このアーキテクチャではシステムはCRUDのみの機能を持ち、クライアントとは&lt;strong&gt;常にDTOを介して通信する。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;おそらくクライアントが&lt;code&gt;UpdateUserName&lt;/code&gt;のようなエンドポイントに更新後のユーザーネームだけを渡すのではなく&lt;code&gt;/user&lt;/code&gt;に更新後のDTOを丸ごと渡す、というようなことだと思われる。&lt;/p&gt;
&lt;p&gt;サーバー側では受け取ったDTOをドメインオブジェクトに詰め替えてバリデーションを行い、永続化する。&lt;/p&gt;
&lt;p&gt;このような設計ではアプリケーションサービスの責務はDTOとドメインオブジェクトの詰め替えに終始し、ドメイン層はバリデーションを主な責務として受け持つ。データの更新方法はクライアントに委ねられてしまうため、ドメイン知識の一部がクライアント側に漏れ出してしまう。&lt;/p&gt;
&lt;p&gt;このようなアーキテクチャでは簡潔性によってオンボーディングコストが低くなるメリットがある代わりに、次のような課題が存在する。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;スケーリング:&lt;/strong&gt; 一般的なシステムでは読み取り操作は書き込み操作よりも2桁以上多い。読み取り操作から見ると非正規化されたデータ構造が適しているが、書き込み操作から見ると正規化されたデータ構造が適している。これらを単一のDBで扱おうとすると垂直スケーリングが必要になるが、垂直スケーリングには非常に高額なコストがかかる。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DDD適用の困難さ:&lt;/strong&gt; この設計ではAPIがデータ指向のインターフェースを持つため、システム全体がCRUDの4つの動詞に縛られる。（データの更新方法がクライアントまたはユーザー側に漏れ出ておりドメイン知識をソフトウェアで表現することが難しいため）&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;ここまでの感想&#34;&gt;ここまでの感想&lt;/h3&gt;
&lt;p&gt;さすがにこういったアーキテクチャのシステムは見たことがないので極端な例では&amp;hellip;?とは思いつつ時代や場所によってはこういった設計のシステムも存在するのかもしれない。&lt;/p&gt;
&lt;h2 id=&#34;cqrsとは&#34;&gt;CQRSとは&lt;/h2&gt;
&lt;p&gt;CQRSはBertrand Meyerが提唱した&lt;a href=&#34;https://en.wikipedia.org/wiki/Command%E2%80%93query_separation&#34; target=&#34;_blank&#34; &gt;『Command and Query Separation Principle』&lt;/a&gt;にその起源を持つ。Wikipediaではこの原則を次のように説明している。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;It states that every method should either be a command that performs an action, or a query that returns data to the caller, but not both.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Command%E2%80%93query_separation&#34; target=&#34;_blank&#34; &gt;Command–query separation - Wikipedia&lt;/a&gt; より引用&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;とあり、すべてのメソッドはCommandかQueryのいずれかであるべきであり、両方を兼ねるべきではないと説明されている。&lt;/p&gt;
&lt;p&gt;これに対し、Martin Fowlerは以下のようにPopのような操作はCommandでありQueryでもあり、必ずしも上記の原則を厳密に守らなくてもいいのではないか、ということを述べている。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Meyer likes to use command-query separation absolutely, but there are exceptions. Popping a stack is a good example of a modifier that modifies state. Meyer correctly says that you can avoid having this method, but it is a useful idiom. So I prefer to follow this principle when I can, but I&amp;rsquo;m prepared to break it to get my pop. (Fowler)&lt;/p&gt;
&lt;p&gt;CQRS Documents by Greg Young P17より引用&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;ここまでの感想-1&#34;&gt;ここまでの感想&lt;/h3&gt;
&lt;p&gt;実際にWebサービスを開発していてもたとえばユーザー作成メソッドが作成したユーザーのIDを返すような処理は普通に書くし、自分もどちらかというと定義ほどは厳密に運用しなくても十分恩恵を受けられるのではないかという立場。&lt;/p&gt;
&lt;h2 id=&#34;a-stereotypical-architectureにcqrsを導入する&#34;&gt;&amp;ldquo;A Stereotypical Architecture&amp;quot;にCQRSを導入する&lt;/h2&gt;
&lt;p&gt;&amp;ldquo;A Stereotypical Architecture&amp;quot;として最初に紹介されたアーキテクチャでは、ドメインモデルがCommandとQueryの両方に使用されていた。このアプリケーションにCQRSを適用するとQuery側とCommand側はそれぞれ次のようになる。&lt;/p&gt;
&lt;h3 id=&#34;query&#34;&gt;Query&lt;/h3&gt;
&lt;p&gt;Query処理側にはデータ取得のためのメソッドのみが含まれる。&lt;/p&gt;
&lt;p&gt;元のアーキテクチャではドメインモデルを生成し、それをDTOにマッピングしたうえでクライアントに返却していた。多くの場合でドメインモデルとDTOは異なるモデルであるため、以下のような課題があるがこれがCQRSの適用によって解決される。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;複数集約から1つのDTOを生成する場合、複数回DBにアクセスする必要がありパフォーマンスが低下する。また、集約の境界が曖昧になる。&lt;/li&gt;
&lt;li&gt;ドメイン層にQueryの責務が多く含まれている（e.g. repositoryのinterfaceにQuery系のメソッドが多く含まれ、ページングやソート情報が含まれている）&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;After CQRS has been applied there is a natural boundary. Separate paths have been made explicit. It makes a lot of sense now to not use the domain to project DTOs. Instead it is possible to introduce a new way of projecting DTOs.&lt;/p&gt;
&lt;p&gt;CQRS Documents by Greg Young P20より引用&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;とあるように、CQRSを適用することでCommandとQueryの処理経路が明確に分離される。この段階ではドメインモデルをDTOの生成に使用しない方が合理的である。&lt;/p&gt;
&lt;p&gt;その代わりに&amp;quot;Thin Read Layer&amp;quot;という方法でDTOを生成することができる。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;thin-read-layer.webp&#34; alt=&#34;thin-read-layer.webp&#34; loading=&#34;lazy&#34; /&gt;
CQRS Documents by Greg Young P21より引用&lt;/p&gt;
&lt;p&gt;この層はDBから直接データを読み取り（ドメインモデルを迂回し）DTOを生成する。&lt;/p&gt;
&lt;p&gt;こうすることで、&lt;strong&gt;ドメイン層からQueryの責務を切り離すことができ、ドメイン層の純度を上げることができる。&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&#34;command&#34;&gt;Command&lt;/h3&gt;
&lt;p&gt;CQRSを適用するとCommand側のアーキテクチャは以下のようになる。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;the-command-site.webp&#34; alt=&#34;the-command-site.webp&#34; loading=&#34;lazy&#34; /&gt;
CQRS Documents by Greg Young P22より引用&lt;/p&gt;
&lt;p&gt;元のアーキテクチャでは書き込み系の処理をする際もDTOをクライアントから受け取っていたが、CQRS適用後はデータ中心ではなく振る舞い中心の契約を採用している点と読み取り処理が分離されている点が大きな違い。（元のアーキテクチャでは書き込み時にクライアントからDTOを渡していたが、ここではメッセージが渡されるようになっている）&lt;/p&gt;
&lt;p&gt;また、元のアーキテクチャでドメイン層に存在していた次のような課題が解決されている。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;リポジトリに大量の読み取りメソッドが存在する&lt;/li&gt;
&lt;li&gt;DTO構築のためにドメインオブジェクトの内部状態を公開するゲッターメソッドが存在する&lt;/li&gt;
&lt;li&gt;DTO構築のために複数の集約オブジェクトをそれぞれ読み込むことで、非効率なクエリが実行される&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;ドメインイベントイベントソーシング&#34;&gt;ドメインイベント、イベントソーシング&lt;/h3&gt;
&lt;p&gt;本文にはドメインイベント、イベントソーシングについても記載があり読んだがここでは割愛。&lt;/p&gt;
&lt;h3 id=&#34;ここまでの感想-2&#34;&gt;ここまでの感想&lt;/h3&gt;
&lt;p&gt;ドメイン層からQuery系の責務を切り離すことでメンテナビリティが向上する、というのが自分が（直近）CQRSに興味を持っていた一番の理由だったのでそうだよなーと思いながら読んだ。&lt;/p&gt;
&lt;p&gt;また（書いてあるとおりだが）読み取り単位を必ずしもドメインモデル単位にする必要がないためパフォーマンスの最適化が行いやすい点も大きなメリットだといえそう。&lt;/p&gt;
&lt;p&gt;結局CommandとQueryはまったく別の責務なことが多いので両者を分離することでメリットを得られるケースは多そう。&lt;/p&gt;
&lt;h2 id=&#34;作業習慣の違い&#34;&gt;作業習慣の違い&lt;/h2&gt;
&lt;p&gt;CQRS Documentsを読むまでは意識していなかったが、CQRSを採用することで&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;ドメイン層&lt;/li&gt;
&lt;li&gt;リードモデル&lt;/li&gt;
&lt;li&gt;クライアント&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;の3つの要素に分解して作業を進めることができるため、プロジェクトに関わる開発者数をより効果的に増やすことができる。（サーバーとクライアントの作業分担をできるのはCQRSかどうかにかかわらないが、重要なのは1つのサーバーアプリケーションを2並列で安全に進めやすいという点だろう。）&lt;/p&gt;
&lt;p&gt;また、開発者には次のような観点の差異が存在する。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;技術的熟練度&lt;/li&gt;
&lt;li&gt;ビジネスドメインに関する知識&lt;/li&gt;
&lt;li&gt;コスト&lt;/li&gt;
&lt;li&gt;ソフトスキル&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;ドメイン層の実装には4つすべての項目が秀でた人材が最適である一方、リードモデルの実装にはそれらの開発者要件は必ずしも当てはまるとは限らない。&lt;/p&gt;
&lt;h3 id=&#34;ここまでの感想-3&#34;&gt;ここまでの感想&lt;/h3&gt;
&lt;p&gt;開発効率の観点は持ってなかったが、たしかにCQRSを採用することで（1つのアプリケーションが2つのモジュールに分離されるので）コンフリクトせずに開発を進めやすそう。（モジュール設計はプロジェクトによるので厳密には2つのモジュールとは限らないが）&lt;/p&gt;
&lt;h2 id=&#34;感想&#34;&gt;感想&lt;/h2&gt;
&lt;p&gt;事前のイメージ通り、CQRSを適用することで開発効率を高められそうなイメージが持てた。&lt;/p&gt;
&lt;p&gt;CQRS Documents内でも触れられていたが、結局CQRSにしろイベントソーシングにしろ一定のオーバーヘッドはあるので、システムやビジネスの課題や要件、今後の見通しを元に必要性を検討するのが（いつだって）重要そう。&lt;/p&gt;
&lt;p&gt;というのはありつつ、ドメイン層のメンテナビリティを高めるためにCQRSを採用するのはかなり有効な選択肢の1つだとも感じているので、ひとまず個人のプロジェクトで検証してみたいと思う。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;もちろんアプリケーションの状況にもよるが&amp;hellip;。repositoryのRead系メソッドの返り値がドメインモデルと一致&lt;strong&gt;しない&lt;/strong&gt;ケースが多くなるような場合では特にCQRSのメリットが効果を発揮しやすいような気がしている。状況にかかわらずCQRSをやったほうがいいのかどうかはまだあまりわかっていない。ちなみにここでのCQRSは基本的には&lt;strong&gt;同一DB&lt;/strong&gt;でCのアプリケーションコードとQのアプリケーションコードが分離されている、くらいの方法をざっくり想定して書いている。（CとQでDBを分けるパターンは流石にtoo muchなケースが多そうなので）&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;厳密にこのドキュメントが原典であることを確認したわけではない。正確な情報をお持ちの方がいたら教えて下さい。&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</content>
    </item>
    
    <item>
      <title>2025年を振り返る</title>
      <link>https://blog.kyu08.com/posts/looking-back-on-2025/</link>
      <pubDate>Tue, 30 Dec 2025 12:00:00 +0900</pubDate>
      
      <guid>https://blog.kyu08.com/posts/looking-back-on-2025/</guid>
      <description>年の瀬なので1年を振り返る。 OSS PR GitHubとGerritで55件のPR1を作成し49件のPRがマージされた。(GitHub2 Gerrit) 去年の数字が</description>
      <content>&lt;p&gt;年の瀬なので1年を振り返る。&lt;/p&gt;
&lt;h2 id=&#34;oss&#34;&gt;OSS&lt;/h2&gt;
&lt;h3 id=&#34;pr&#34;&gt;PR&lt;/h3&gt;
&lt;p&gt;GitHubとGerritで55件のPR&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;を作成し49件のPRがマージされた。(&lt;a href=&#34;https://github.com/pulls?q=is%3Apr&amp;#43;archived%3Afalse&amp;#43;is%3Aclosed&amp;#43;author%3Akyu08&amp;#43;is%3Apublic&amp;#43;-user%3Akyu08&amp;#43;created%3A2025-01-01..2025-12-31&amp;#43;&#34; target=&#34;_blank&#34; &gt;GitHub&lt;/a&gt;&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; &lt;a href=&#34;https://go-review.googlesource.com/q/owner:kyu.subsub@gmail.com&#34; target=&#34;_blank&#34; &gt;Gerrit&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;去年の数字が以下だったのでPR作成数、マージされたPR数ともに微増した。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;49件のPRを作成し43件のPRがマージされた。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;PR一覧は以下のような感じ。&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h4 id=&#34;機能追加&#34;&gt;機能追加&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/jesseduffield/lazygit/pull/4810&#34; target=&#34;_blank&#34; &gt;jesseduffield/lazygit - Add &amp;ldquo;CopyToClipboard&amp;rdquo; command to ConfirmationController&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/jesseduffield/lazygit/pull/4728&#34; target=&#34;_blank&#34; &gt;jesseduffield/lazygit - Add new command &amp;ldquo;Checkout previous branch&amp;rdquo;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/nabekou29/pair-lens.nvim/pull/2&#34; target=&#34;_blank&#34; &gt;nabekou29/pair-lens.nvim - feat: add Go expression_switch_statement and type_switch_statement support&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;ドキュメント関連&#34;&gt;ドキュメント関連&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/Homebrew/homebrew-cask/pull/200288&#34; target=&#34;_blank&#34; &gt;Homebrew/homebrew-cask - cursor: update homepage link&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/rust-lang/this-week-in-rust/pull/7158&#34; target=&#34;_blank&#34; &gt;rust-lang/this-week-in-rust - Add project update: &amp;ldquo;fzf-make v0.65.0&amp;rdquo;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/ratatui/.github/pull/2&#34; target=&#34;_blank&#34; &gt;ratatui/.github - Fix typo Javascript -&amp;gt; JavaScript&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/genkit-ai/docsite/pull/158&#34; target=&#34;_blank&#34; &gt;genkit-ai/docsite - Fix incorrect field name in express authentication example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/humanlayer/12-factor-agents/pull/73&#34; target=&#34;_blank&#34; &gt;humanlayer/12-factor-agents - Fix typo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/humanlayer/12-factor-agents/pull/72&#34; target=&#34;_blank&#34; &gt;humanlayer/12-factor-agents - Delete unnecessary ]&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/go-task/task/pull/2394&#34; target=&#34;_blank&#34; &gt;go-task/task - chore: delete unnecessary whitespace&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/go-task/task/pull/2393&#34; target=&#34;_blank&#34; &gt;go-task/task - docs: add fzf-make to &amp;ldquo;Community Integrations&amp;rdquo;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/jesseduffield/lazygit/pull/4807&#34; target=&#34;_blank&#34; &gt;jesseduffield/lazygit - Update the badges of golangci-lint and homebrew in README.md&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/jesseduffield/lazygit/pull/4806&#34; target=&#34;_blank&#34; &gt;jesseduffield/lazygit - Update CONTRIBUTING.md to clarify translation contribution process&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/nvim-orgmode/orgmode/pull/985&#34; target=&#34;_blank&#34; &gt;nvim-orgmode/orgmode - docs: fix absences of line break&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/bnjbvr/cargo-machete/pull/168&#34; target=&#34;_blank&#34; &gt;bnjbvr/cargo-machete - doc: rename job name in example workflow&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/rust-lang/cargo/pull/15511&#34; target=&#34;_blank&#34; &gt;rust-lang/cargo - docs: update version notice for deprecation removal&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/geek-rabb1t/geek-rabb1t.github.io/pull/1&#34; target=&#34;_blank&#34; &gt;geek-rabb1t/geek-rabb1t.github.io - typoを修正&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/h3pei/trace-pr.nvim/pull/4&#34; target=&#34;_blank&#34; &gt;h3pei/trace-pr.nvim - docs: describe the default value of trace_by_commit_hash_when_pr_not_found explicitly in README.md&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/golangci/golangci-lint/pull/5697&#34; target=&#34;_blank&#34; &gt;golangci/golangci-lint - docs: explicitly describe that the migrate command automatically migrate linters.presets&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/catppuccin/lazygit/pull/53&#34; target=&#34;_blank&#34; &gt;catppuccin/lazygit - doc: remove deprecated selectedRangeBgColor key from example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/yykamei/block-merge-based-on-time/pull/2192&#34; target=&#34;_blank&#34; &gt;yykamei/block-merge-based-on-time - Add ready_for_review as the workflow trigger to the example in README.md&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/yuki-yano/zeno.zsh/pull/81&#34; target=&#34;_blank&#34; &gt;yuki-yano/zeno.zsh - docs(readme): replace exa with eza&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/nand2tetris/web-ide/pull/559&#34; target=&#34;_blank&#34; &gt;nand2tetris/web-ide - Fix typo in projects/src/project_08/21_nested_call.ts(initliazes -&amp;gt; initializes)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/cloudspannerecosystem/yo/pull/147&#34; target=&#34;_blank&#34; &gt;cloudspannerecosystem/yo - Add installation method for Go 1.16+&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://go-review.googlesource.com/c/wiki/&amp;#43;/703735&#34; target=&#34;_blank&#34; &gt;golang - 703735: GoUsers: add Canary Inc.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://go-review.googlesource.com/c/wiki/&amp;#43;/703736&#34; target=&#34;_blank&#34; &gt;golang - 703736: GoUsers: fix the position of CloudSign&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;バグ修正&#34;&gt;バグ修正&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/derailed/k9s/pull/3699&#34; target=&#34;_blank&#34; &gt;derailed/k9s - feat(pulse): map hjkl to navigate as help shows&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;ci開発環境等の変更&#34;&gt;CI、開発環境等の変更&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/jesseduffield/lazygit/pull/4974&#34; target=&#34;_blank&#34; &gt;jesseduffield/lazygit - Add synchronize event to the hooks of &amp;ldquo;Check Required Labels&amp;rdquo;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/jesseduffield/lazygit/pull/4936&#34; target=&#34;_blank&#34; &gt;jesseduffield/lazygit - Use ignore directive to ignore test files not to be passes to gofumpt&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/jesseduffield/lazygit/pull/4844&#34; target=&#34;_blank&#34; &gt;jesseduffield/lazygit - Update go to 1.25&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/jesseduffield/lazygit/pull/4830&#34; target=&#34;_blank&#34; &gt;jesseduffield/lazygit - Run label check workflow only on label events and open pr event&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/jesseduffield/lazygit/pull/4829&#34; target=&#34;_blank&#34; &gt;jesseduffield/lazygit - Enhance PR/Issue templates readability&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/jesseduffield/lazygit/pull/4809&#34; target=&#34;_blank&#34; &gt;jesseduffield/lazygit - Pass only Git-tracked Go files to gofumpt&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;翻訳&#34;&gt;翻訳&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/rust-lang/surveys/pull/329&#34; target=&#34;_blank&#34; &gt;rust-lang/surveys - [Japanese] replace &amp;ldquo;prioritising work&amp;rdquo; with &amp;ldquo;problems to productivity&amp;rdquo; in 2024 survey&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;自作ツールのbrew-release関連&#34;&gt;自作ツールのbrew release関連&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/Homebrew/homebrew-core/pull/260001&#34; target=&#34;_blank&#34; &gt;Homebrew/homebrew-core - fzf-make 0.66.0&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/Homebrew/homebrew-core/pull/249550&#34; target=&#34;_blank&#34; &gt;Homebrew/homebrew-core - fzf-make 0.65.0&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/Homebrew/homebrew-core/pull/249255&#34; target=&#34;_blank&#34; &gt;Homebrew/homebrew-core - fzf-make 0.64.0&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/Homebrew/homebrew-core/pull/248909&#34; target=&#34;_blank&#34; &gt;Homebrew/homebrew-core - fzf-make 0.63.0&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/Homebrew/homebrew-core/pull/246767&#34; target=&#34;_blank&#34; &gt;Homebrew/homebrew-core - fzf-make 0.62.0&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/Homebrew/homebrew-core/pull/242247&#34; target=&#34;_blank&#34; &gt;Homebrew/homebrew-core - fzf-make 0.61.0&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/Homebrew/homebrew-core/pull/234337&#34; target=&#34;_blank&#34; &gt;Homebrew/homebrew-core - fzf-make: add task to available runner in description&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/Homebrew/homebrew-core/pull/233946&#34; target=&#34;_blank&#34; &gt;Homebrew/homebrew-core - fzf-make 0.60.0&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/Homebrew/homebrew-core/pull/223065&#34; target=&#34;_blank&#34; &gt;Homebrew/homebrew-core - fzf-make: update desc&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/Homebrew/homebrew-core/pull/223063&#34; target=&#34;_blank&#34; &gt;Homebrew/homebrew-core - fzf-make 0.59.0&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/Homebrew/homebrew-core/pull/222737&#34; target=&#34;_blank&#34; &gt;Homebrew/homebrew-core - fzf-make 0.58.0&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/Homebrew/homebrew-core/pull/222421&#34; target=&#34;_blank&#34; &gt;Homebrew/homebrew-core - fzf-make 0.57.0&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/Homebrew/homebrew-core/pull/205485&#34; target=&#34;_blank&#34; &gt;Homebrew/homebrew-core - fzf-make 0.56.0&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/Homebrew/homebrew-core/pull/203296&#34; target=&#34;_blank&#34; &gt;Homebrew/homebrew-core - fzf-make 0.55.0&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/Homebrew/homebrew-core/pull/203265&#34; target=&#34;_blank&#34; &gt;Homebrew/homebrew-core - fzf-make 0.54.0&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;寄付&#34;&gt;寄付&lt;/h3&gt;
&lt;p&gt;この記事を書いたときから継続して&lt;a href=&#34;https://github.com/sponsors/neovim&#34; target=&#34;_blank&#34; &gt;Neovim&lt;/a&gt;と&lt;a href=&#34;https://github.com/sponsors/ratatui&#34; target=&#34;_blank&#34; &gt;ratatui&lt;/a&gt;に5$/monthずつ寄付し続けている。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://blog.kyu08.com/posts/renew-oss-sponsoring/&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://blog.kyu08.com/posts/renew-oss-sponsoring/&#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/renew-oss-sponsoring/cover.png&#34; alt=&#34;GitHub Sponsorsの寄付先にratatuiを追加した&#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 Sponsorsの寄付先にratatuiを追加した&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;OSSへの寄付の月予算を$10にした - laiso こちらの記事で寄付するOSSプロジェクトの選び方として次のような基準が紹介されていた。 寄付するプロジ&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://blog.kyu08.com/posts/renew-oss-sponsoring/&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;だいたい累計$150くらい寄付したことになる。少しでも長く持続してくれると嬉しいのでこれからも続けていく。&lt;/p&gt;
&lt;h3 id=&#34;振り返り&#34;&gt;振り返り&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;去年と同じくらいのペースでPRを送ることができた。（平均約4.5件/月ペース）&lt;/li&gt;
&lt;li&gt;LazygitのトップページのContributors一覧に表示されるようになった。
&lt;img src=&#34;lazygit-contibutors.webp&#34; alt=&#34;lazygit-contibutors.webp&#34; loading=&#34;lazy&#34; /&gt;
&lt;ul&gt;
&lt;li&gt;GitHubではcommit数が多い順に12人目くらいまでのアイコンがContributorsに表示される。&lt;/li&gt;
&lt;li&gt;細々とcontributionを続けたところの9番目にcommitが多い人になれた。（2025/12/23現在）&lt;/li&gt;
&lt;li&gt;しばらくはこれを目標にlazygitへのcontributionを続けていたので嬉しい。&lt;/li&gt;
&lt;li&gt;CIの修正やGoのバージョンアップなど、地味めなPRがメインだったがいくつか機能追加PRもマージしてもらえた。（&lt;a href=&#34;https://github.com/jesseduffield/lazygit/pull/4728&#34; target=&#34;_blank&#34; &gt;branchパネルで&lt;code&gt;-&lt;/code&gt;を押すと&lt;code&gt;git checkout -&lt;/code&gt;相当のことができる機能&lt;/a&gt;と&lt;a href=&#34;https://github.com/jesseduffield/lazygit/pull/4810&#34; target=&#34;_blank&#34; &gt;エラー内容をクリップボードにコピーできるようにする機能&lt;/a&gt;）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;GoWikiへのcontributionに際してGerritを初めてつかった。
&lt;ul&gt;
&lt;li&gt;GitHubとかなかなかメンタルモデルが違う感じだったので結構手間取った。&lt;/li&gt;
&lt;li&gt;参考になったリソースなどをいつか記事にしたい。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;OSSメンテナに感謝されるのは嬉しいし、見つけた問題を自分の手で解決するのも楽しいので引き続きやっていきたい。&lt;/p&gt;
&lt;p&gt;社内でもOSSは楽しいぞーという話を何回かしたところ、それをきっかけにしてOSS貢献にトライしてくれる方が何名かいたのも嬉しかった。&lt;/p&gt;
&lt;h2 id=&#34;個人開発&#34;&gt;個人開発&lt;/h2&gt;
&lt;h3 id=&#34;fzf-make&#34;&gt;fzf-make&lt;/h3&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://github.com/kyu08/fzf-make&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://github.com/kyu08/fzf-make&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail&#34;&gt;
      &lt;img src=&#34;https://repository-images.githubusercontent.com/611369838/a30cf798-2e08-47a5-9443-978329275d2c&#34; alt=&#34;GitHub - kyu08/fzf-make: A command line tool that executes commands using fuzzy finder with preview window for make, npm, pnpm, yarn, just and task.&#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/fzf-make: A command line tool that executes commands using fuzzy finder with preview window for make, npm, pnpm, yarn, just and task.&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;A command line tool that executes commands using fuzzy finder with preview window for make, npm, pnpm, yarn, just and task. - kyu08/fzf-make&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://github.com/kyu08/fzf-make&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;タスクランナー側で定義したコマンドをfuzzy finder形式で選択できるCLIツールを趣味でRustで開発している。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;fzf-make-demo.gif&#34; alt=&#34;fzf-make-demo.gif&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;現在は以下のタスクランナーに対応している。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;make&lt;/li&gt;
&lt;li&gt;pnpm&lt;/li&gt;
&lt;li&gt;yarn&lt;/li&gt;
&lt;li&gt;just&lt;/li&gt;
&lt;li&gt;task&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;gifを見てもらえれば分かる通り、プレビューウィンドウでコマンド内容を確認しながらコマンドを選択できるのが特徴の一つ。&lt;/p&gt;
&lt;h4 id=&#34;スター数&#34;&gt;スター数&lt;/h4&gt;
&lt;p&gt;2025/12/23現在では245スターを獲得している。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;fzf-make-star.webp&#34; alt=&#34;fzf-make-star.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.star-history.com/#kyu08/fzf-make&amp;amp;type=date&amp;amp;legend=top-left&#34; target=&#34;_blank&#34; &gt;Star History&lt;/a&gt;によると2024/12/19時点では129スターだったので1年で大体倍くらいになった。🎉&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;fzf-make-star-history-20251223-last-year.webp&#34; alt=&#34;fzf-make-star-history-20251223-last-year.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;来年も適度なペースで細々とメンテしていきます。(npm対応は早めにやりたい&amp;hellip;！)&lt;/p&gt;
&lt;h4 id=&#34;今年の変更点&#34;&gt;今年の変更点&lt;/h4&gt;
&lt;p&gt;2025年は&lt;a href=&#34;https://github.com/pulls?q=is%3Apr&amp;#43;archived%3Afalse&amp;#43;author%3Akyu08&amp;#43;is%3Apublic&amp;#43;repo%3Akyu08%2Ffzf-make&amp;#43;created%3A2025-01-01..2025-12-31&amp;#43;is%3Amerged&amp;#43;&#34; target=&#34;_blank&#34; &gt;筆者が74件のPRを作成&amp;amp;マージし&lt;/a&gt;、&lt;a href=&#34;https://github.com/kyu08/fzf-make/compare/v0.54.0...v0.65.0&#34; target=&#34;_blank&#34; &gt;12個のバージョンがリリースされ、筆者とrenovateを含めて5人の貢献者により102のcommitが追加された。&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;TUIツールを個人開発をしているとなかなかユーザーの存在を感じづらいので昨年に引き続きissueを立てたりPRを送ってくれたりTwitterで言及してくれる方がいてとても嬉しい。🙏&lt;/p&gt;
&lt;p&gt;もちろん使ってるよー！と言ってもらえるだけでも大変うれしいです！ぜひ&lt;a href=&#34;https://github.com/kyu08/fzf-make&#34; target=&#34;_blank&#34; &gt;スター&lt;/a&gt;もお願いします！&lt;/p&gt;
&lt;p&gt;今年行った主要な機能追加は以下の通り。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;コマンドに引数を渡せるようにする&lt;a href=&#34;https://github.com/kyu08/fzf-make/releases/tag/v0.58.0&#34; target=&#34;_blank&#34; &gt;&lt;code&gt;@v0.58.0&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;go-task/taskをサポート&lt;a href=&#34;https://github.com/kyu08/fzf-make/releases/tag/v0.60.0&#34; target=&#34;_blank&#34; &gt;&lt;code&gt;@v0.60.0&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;コマンドのコピー機能を追加&lt;a href=&#34;https://github.com/kyu08/fzf-make/releases/tag/v0.66.0&#34; target=&#34;_blank&#34; &gt;&lt;code&gt;@v0.66.0&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;来年こそはnpm対応を入れたい。（npm対応のPRを送ってくれている方がいるので早ければ年始くらいにはリリースできるかもしれない）&lt;/p&gt;
&lt;h3 id=&#34;sunaba&#34;&gt;sunaba&lt;/h3&gt;
&lt;p&gt;これまで素振り用のrepositoryはトピックごと（触りたいライブラリや読んでいる本など）ごとに作成していたが、まとめて管理したくなったので素振りごった煮repositoryを作成した。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://github.com/kyu08/sunaba&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://github.com/kyu08/sunaba&#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/0da536ef9b42550c4e820b6c64f41c28d20102ddd47cf7540ac7f7c0afd9ae69/kyu08/sunaba&#34; alt=&#34;GitHub - kyu08/sunaba: Personal sandbox&#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/sunaba: Personal sandbox&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&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;今までは都度repositoryを作成していたが、ディレクトリを作成するだけでよくなったので若干楽になった。&lt;/p&gt;
&lt;h2 id=&#34;ブログ&#34;&gt;ブログ&lt;/h2&gt;
&lt;h3 id=&#34;書いた記事&#34;&gt;書いた記事&lt;/h3&gt;
&lt;p&gt;今年は14本の記事を書いた。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.kyu08.com/posts/magi65/&#34; target=&#34;_blank&#34; &gt;IQUNIX Magi65を買った&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.kyu08.com/posts/nand2tetris/&#34; target=&#34;_blank&#34; &gt;『コンピュータシステムの理論と実装 第2版』を読んだ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.kyu08.com/posts/oblivion-keycaps/&#34; target=&#34;_blank&#34; &gt;傾斜付きロープロファイルキーキャップNuPhy Oblivionを買った&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.kyu08.com/posts/manage-cargo-dependencies/&#34; target=&#34;_blank&#34; &gt;cargoプロジェクトで依存関係を継続的に管理する&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.kyu08.com/posts/fp-matsuri-2025/&#34; target=&#34;_blank&#34; &gt;関数型まつり2025に参加した&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.kyu08.com/posts/keychron-v4-max/&#34; target=&#34;_blank&#34; &gt;Keychron V4 Max を買った&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.kyu08.com/posts/second-keychron-v4-max/&#34; target=&#34;_blank&#34; &gt;追いKeychron V4 Max&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.kyu08.com/posts/tidy-first/&#34; target=&#34;_blank&#34; &gt;『Tidy First?』を読んだ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.kyu08.com/posts/vim-conf-2025/&#34; target=&#34;_blank&#34; &gt;VimConf 2025 Smallに参加した&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.kyu08.com/posts/the-deadline/&#34; target=&#34;_blank&#34; &gt;『デッドライン』を読んだ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.kyu08.com/posts/bbf_kubernetes/&#34; target=&#34;_blank&#34; &gt;『つくって、壊して、直して学ぶ Kubernetes入門』を読んだ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.kyu08.com/posts/understanding-rust-from-concepts/&#34; target=&#34;_blank&#34; &gt;『コンセプトから理解するRust』を読んだ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.kyu08.com/posts/rust-web-app-book/&#34; target=&#34;_blank&#34; &gt;『RustによるWebアプリケーション開発 設計からリリース・運用まで』を読んだ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.kyu08.com/posts/gerrit-find-cls-you-created/&#34; target=&#34;_blank&#34; &gt;Gerritで自分が作成したCL一覧を確認する方法&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;本を読んで記事を書くことで理解や記憶への定着が捗っている気がするので来年も適度にやっていきたい。&lt;/p&gt;
&lt;h3 id=&#34;ブログの変更&#34;&gt;ブログの変更&lt;/h3&gt;
&lt;p&gt;今年はブログのデザインや仕組みについてもいくつか変更を加えた。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;OGPを動的生成するようにした&lt;/li&gt;
&lt;li&gt;Heading要素のデザインを変えた&lt;/li&gt;
&lt;li&gt;プレビュー環境を整えた&lt;/li&gt;
&lt;li&gt;ブログカードの表示&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;ogpの自動生成&#34;&gt;OGPの自動生成&lt;/h3&gt;
&lt;p&gt;CIで記事のタイトルを読み取ってOGP画像を自動生成 + commitするようにした。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://github.com/kyu08/blog/pull/239&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://github.com/kyu08/blog/pull/239&#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/fe74384e326179034c16e82687271d21dc5b84b20e1c849b6f4ac4daebf2f6c8/kyu08/blog/pull/239&#34; alt=&#34;Add dynamic OGP image generation by kyu08 · Pull Request #239 · kyu08/blog&#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;Add dynamic OGP image generation by kyu08 · Pull Request #239 · kyu08/blog&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;close #238, close #120

Add satori and @resvg/resvg-js for OGP image generation
Create OGP generation script that reads post metadata and generates images
Add OGP template with dark theme design (b...&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://github.com/kyu08/blog/pull/239&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;img src=&#34;cover.png&#34; alt=&#34;cover.png&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;Twitterで投稿したときに追加されるタイトル要素とOGPのメタ情報が被らないようになっているのが地味なこだわりポイント。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;twitter-caption.webp&#34; alt=&#34;twitter-caption.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;ついでにこんな感じでPRにコメントとして表示されるようにしたので投稿前に確認できる。（日本語だとたまーに特定の記号などが豆腐になってしまうのチェックしておきたい）&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;ogp-pr-comment.webp&#34; alt=&#34;ogp-pr-comment.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;heading要素のデザインを変えた&#34;&gt;Heading要素のデザインを変えた&lt;/h3&gt;
&lt;p&gt;これまではレベルの異なるHeading要素の区別が付きづらかったので&lt;code&gt;## OSS&lt;/code&gt;のようにHeading要素のレベルに合わせて&lt;code&gt;#&lt;/code&gt;が表示されるデザインにした。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;BEFORE&lt;/th&gt;
&lt;th&gt;&lt;img src=&#34;heading-before.webp&#34; alt=&#34;heading-before.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AFTER&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src=&#34;heading-after.webp&#34; alt=&#34;heading-after.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;a href=&#34;https://x.com/voluntas&#34; target=&#34;_blank&#34; &gt;@voluntas&lt;/a&gt;さんの&lt;a href=&#34;https://x.com/voluntas/status/1981896805672501760&#34; target=&#34;_blank&#34; &gt;このツイート&lt;/a&gt;をみていいなーと思ったので真似してみた。&lt;/p&gt;
&lt;h3 id=&#34;プレビュー環境を整えた&#34;&gt;プレビュー環境を整えた&lt;/h3&gt;
&lt;p&gt;PRコメントにプレビュー環境のリンクが投稿されるようにした。出先などでも記事の推敲がしやすくなった。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://github.com/kyu08/blog/pull/235&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://github.com/kyu08/blog/pull/235&#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/32ce461bebea477e1df3aa07888eac4e710be1aef3ba882c0cf49f2b9b765539/kyu08/blog/pull/235&#34; alt=&#34;PRごとにPreview環境を作成する by kyu08 · Pull Request #235 · kyu08/blog&#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;PRごとにPreview環境を作成する by kyu08 · Pull Request #235 · kyu08/blog&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;A blog powered by hugo. Contribute to kyu08/blog development by creating an account on GitHub.&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://github.com/kyu08/blog/pull/235&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;h3 id=&#34;ブログカードの表示&#34;&gt;ブログカードの表示&lt;/h3&gt;
&lt;p&gt;こんな感じでリンク先の情報を表示するようにした。便利。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;blog-card.webp&#34; alt=&#34;blog-card.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://github.com/kyu08/blog/pull/246&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://github.com/kyu08/blog/pull/246&#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/eb445efdb9b6351b5b509ccdfd909411c138798d6e689ba8c4fa3ef3c235b314/kyu08/blog/pull/246&#34; alt=&#34;Implement blog card link preview feature by kyu08 · Pull Request #246 · kyu08/blog&#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;Implement blog card link preview feature by kyu08 · Pull Request #246 · kyu08/blog&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;Implemented a blog card shortcode that displays rich link previews with:

Automatic OGP metadata fetching (title, description, image)
Manual parameter specification support
Responsive design with d...&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://github.com/kyu08/blog/pull/246&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;a href=&#34;https://www.oreilly.co.jp/books/9784814400874/&#34; target=&#34;_blank&#34; &gt;コンピュータシステムの理論と実装 第2版&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.oreilly.co.jp/books/9784814400911/&#34; target=&#34;_blank&#34; &gt;Tidy First?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://bookplus.nikkei.com/atcl/catalog/99/140252/&#34; target=&#34;_blank&#34; &gt;デッドライン&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.shoeisha.co.jp/book/detail/9784798183961&#34; target=&#34;_blank&#34; &gt;つくって、壊して、直して学ぶ Kubernetes入門&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gihyo.jp/book/2022/978-4-297-12562-2&#34; target=&#34;_blank&#34; &gt;コンセプトから理解するRust&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.kodansha.co.jp/book/products/0000398182&#34; target=&#34;_blank&#34; &gt;RustによるWebアプリケーション開発 設計からリリース・運用まで&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://tatsu-zine.com/books/clean-architecture&#34; target=&#34;_blank&#34; &gt;Clean Architecture 達人に学ぶソフトウェアの構造と設計&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;読みかけのものは割愛。&lt;/p&gt;
&lt;p&gt;タイトルからも分かる通りComputer Science、 プロマネ、Kubernetes、Rustが今年の興味領域の中心だった。長期的に役立ちそう系と仕事ですぐ使える系とただ単に興味がある系をバランスよく摂取できた気がする。&lt;/p&gt;
&lt;p&gt;特に『コンピュータシステムの理論と実装』は本当に読んでよかった。&lt;/p&gt;
&lt;p&gt;CSを体系的に学んできていない自分にとっては論理回路を始めとしたハードウェアや、アセンブラ、コンパイラ、OSなどのソフトウェアの解像度を上げられたという意味で貴重な経験だった。（手を動かす分時間はかかったが）&lt;/p&gt;
&lt;p&gt;ひとまずRust欲が落ち着いたので来年はComputer Science系をやりつつ、Goの深堀りにも時間を使っていきたい。Computer Scienceに関してはネットワークと並行プログラミング周りを深掘ろうと思っている。&lt;/p&gt;
&lt;h2 id=&#34;勉強会&#34;&gt;勉強会&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;関数型まつり2025&lt;/li&gt;
&lt;li&gt;VimConf 2025 Small&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;に参加した。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://blog.kyu08.com/posts/fp-matsuri-2025/&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://blog.kyu08.com/posts/fp-matsuri-2025/&#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/fp-matsuri-2025/cover.png&#34; alt=&#34;関数型まつり2025に参加した&#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;関数型まつり2025に参加した&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;2025/06/14(土)、2025/06/15(日)に中野セントラルパークで行われた関数型まつり2025に参加した。 筆者はElmやRust&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://blog.kyu08.com/posts/fp-matsuri-2025/&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://blog.kyu08.com/posts/vim-conf-2025/&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://blog.kyu08.com/posts/vim-conf-2025/&#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/vim-conf-2025/cover.png&#34; alt=&#34;VimConf 2025 Smallに参加した&#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;VimConf 2025 Smallに参加した&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;2025年11月2日（日）にアキバプラザ・アキバホールで開催されたVimConf 2025 Smallに参加した。 こちらはノベルティ。食器とかお箸はた&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://blog.kyu08.com/posts/vim-conf-2025/&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;勉強になったり刺激を得られたりしてよかった。来年はGoの勉強会にも参加してみようと思う。&lt;/p&gt;
&lt;h2 id=&#34;生活&#34;&gt;生活&lt;/h2&gt;
&lt;h3 id=&#34;ジム&#34;&gt;ジム&lt;/h3&gt;
&lt;p&gt;8月からジムに通い始めた。腰が痛くなりやすいので腰痛防止が主な目的。&lt;/p&gt;
&lt;p&gt;無事に腰痛とはお別れでき、筋肉も4ヶ月で4kg増やすことができているので引き続きやっていき。活動できる量も増えるしやはり筋肉は正義なのだと実感した。&lt;/p&gt;
&lt;h3 id=&#34;睡眠&#34;&gt;睡眠&lt;/h3&gt;
&lt;p&gt;今年の春くらいから就寝時間が0時半くらいになった。それまでは2時とかに寝て次の日なんかボーッとするなーということが多かったのでいい感じになってよかった。&lt;/p&gt;
&lt;p&gt;朝散歩で日の光にあたったり運動や出社で体力を使うようにしたのが自分の睡眠にはいい影響があった気がする。（たぶん）&lt;/p&gt;
&lt;h3 id=&#34;食事&#34;&gt;食事&lt;/h3&gt;
&lt;p&gt;これまではリモートで働いているとよく17時前後に集中力が皆無になってしまい、ちょっとゴロゴロしてから空腹を感じてご飯を食べる、というようなことをしていた。&lt;/p&gt;
&lt;p&gt;ある日お昼ご飯をお腹いっぱい食べたところ夕方の集中力低下タイムがなくなったことに気づいた。シンプルに夕方に血糖値的なものが下がりすぎて集中力が落ちていた模様。地味に生産性が落ちていたので改善できて良かった。&lt;/p&gt;
&lt;h3 id=&#34;舌下治療&#34;&gt;舌下治療&lt;/h3&gt;
&lt;p&gt;去年の秋頃始めた舌下治療の結果がでて今年の春の花粉シーズンは例年よりも楽だった。&lt;/p&gt;
&lt;p&gt;来年はもっと楽になることを期待。&lt;/p&gt;
&lt;h3 id=&#34;サッカー&#34;&gt;サッカー&lt;/h3&gt;
&lt;p&gt;今年からJリーグ（カップ戦も含む）観戦にいくようになった。&lt;/p&gt;
&lt;p&gt;非日常でめっちゃ楽しい。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;soccer.webp&#34; alt=&#34;soccer.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;仕事&#34;&gt;仕事&lt;/h2&gt;
&lt;p&gt;転職し、2/1から新しい職場で働きはじめた。&lt;/p&gt;
&lt;p&gt;プロダクトがたくさんのお客様に価値提供をできている実感があり、モチベーション高く働けている。&lt;/p&gt;
&lt;p&gt;また、上期に関わったプロジェクトがうまくいき、MVPを受賞することができた。&lt;/p&gt;
&lt;p&gt;会社全体としても好調なのでより一層事業成長に貢献していけるように全方面で頑張っていきたい。&lt;/p&gt;
&lt;p&gt;技術的には引き続きGo、Google Cloud、Spannerなどを触っている。&lt;/p&gt;
&lt;p&gt;このブログではあまり会社について詳しく話せていませんが、エンジニア採用を強化中ですので少しでも興味を持ってくれた方はTwitterのDMとかで連絡をください。ご飯やカジュアル面談などの調整をさせていただきます。（もちろんDMで聞きたいことを聞いていただいても大丈夫です）&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://recruit.canary-app.jp/engineer-entrance-book&#34; target=&#34;_blank&#34; &gt;Engineer Entrance Book&lt;/a&gt;にもかなり詳しく情報がまとまっているのでぜひご覧ください。🙇&lt;/p&gt;
&lt;h2 id=&#34;2026年の抱負&#34;&gt;2026年の抱負&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;事業成長により貢献する&lt;/li&gt;
&lt;li&gt;GoとComputer Scienceの理解を深める&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;おわりに&#34;&gt;おわりに&lt;/h2&gt;
&lt;p&gt;2026年もやっていき。&lt;/p&gt;
&lt;p&gt;過去の振り返り記事はこちら。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.kyu08.com/posts/looking-back-on-2024/&#34; &gt;2024年を振り返る&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.kyu08.com/posts/looking-back-on-2023/&#34; &gt;2023年を振り返る&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.kyu08.com/posts/20201231-review-of-2020/&#34; &gt;2020年をかんたんに振り返る&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;便宜的にPRと表記しているが、GerritではCL(たしかChange List)と呼ばれる。&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;Ownerが自分以外のPublic Repositoryを対象に集計。&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://gist.github.com/kyu08/138f8d15c2badc8243ca2e126545ca36&#34; target=&#34;_blank&#34; &gt;https://gist.github.com/kyu08/138f8d15c2badc8243ca2e126545ca36&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>Gerritで自分が作成したCL一覧を確認する方法</title>
      <link>https://blog.kyu08.com/posts/gerrit-find-cls-you-created/</link>
      <pubDate>Thu, 25 Dec 2025 00:17:02 +0900</pubDate>
      
      <guid>https://blog.kyu08.com/posts/gerrit-find-cls-you-created/</guid>
      <description>年末の振り返りを書いていて自分が作成したCL一覧が見たくなったときに地味に迷ったのでメモしておく。 tl;dr 以下にアクセスする。 &amp;lt;repo-url&amp;gt;/q/owner:&amp;lt;your-email&amp;gt; こんな感じで表示さ</description>
      <content>&lt;p&gt;年末の振り返りを書いていて自分が作成したCL一覧が見たくなったときに地味に迷ったのでメモしておく。&lt;/p&gt;
&lt;h2 id=&#34;tldr&#34;&gt;tl;dr&lt;/h2&gt;
&lt;p&gt;以下にアクセスする。&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;repo-url&amp;gt;/q/owner:&amp;lt;your-email&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;こんな感じで表示される。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;result.webp&#34; alt=&#34;result.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;たとえばgoのrepositoryだったら&lt;code&gt;https://go-review.googlesource.com/q/owner:&amp;lt;your-email&amp;gt;&lt;/code&gt;のような感じ。&lt;/p&gt;
&lt;p&gt;以降はおまけ。&lt;/p&gt;
&lt;h2 id=&#34;経緯&#34;&gt;経緯&lt;/h2&gt;
&lt;p&gt;ここから行けるか&amp;hellip;?とか思ったが&amp;hellip;
&lt;img src=&#34;menu.webp&#34; alt=&#34;menu.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;マージ済みが表示されそうな項目はRecently closedしかないが、これだと最近のCLしか見れなさそうだった。
&lt;img src=&#34;dashboard.webp&#34; alt=&#34;dashboard.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;検索ボックスに打ち込むクエリを試行錯誤したところ冒頭の指定方法を見つけた。&lt;/p&gt;
&lt;p&gt;GitHubと違ってrepository横断で検索できないっぽいので複数のGerrit repositoryから活動を集計するのは大変そう。（調べてないだけでやり方はあるのかもだが）&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;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;GitHubと違ってrepositoryごとにそれぞれでホスティングされてそうな雰囲気を感じるので直感的には難しそうではある。&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>
    
    <item>
      <title>『RustによるWebアプリケーション開発 設計からリリース・運用まで』を読んだ</title>
      <link>https://blog.kyu08.com/posts/rust-web-app-book/</link>
      <pubDate>Mon, 22 Dec 2025 00:13:06 +0900</pubDate>
      
      <guid>https://blog.kyu08.com/posts/rust-web-app-book/</guid>
      <description>『RustによるWebアプリケーション開発 設計からリリース・運用まで』を読んだので感じたことをメモしておく。 『ＲｕｓｔによるＷｅｂアプリケー</description>
      <content>&lt;p&gt;『RustによるWebアプリケーション開発 設計からリリース・運用まで』を読んだので感じたことをメモしておく。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://www.kodansha.co.jp/book/products/0000398182&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://www.kodansha.co.jp/book/products/0000398182&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail&#34;&gt;
      &lt;img src=&#34;https://dvs-cover.kodansha.co.jp/0000398182/qlwQ4BgoUFJKQBFNNIbAbFmXHhhSS0R338o5wVij.jpg&#34; alt=&#34;『ＲｕｓｔによるＷｅｂアプリケーション開発　設計からリリース・運用まで』（豊田　優貴,松本　健太郎,吉川　哲史）　製品詳細　講談社&#34; loading=&#34;lazy&#34;&gt;
    &lt;/div&gt;&lt;div class=&#34;blogcard-content&#34;&gt;
      &lt;div class=&#34;blogcard-title&#34;&gt;『ＲｕｓｔによるＷｅｂアプリケーション開発　設計からリリース・運用まで』（豊田　優貴,松本　健太郎,吉川　哲史）　製品詳細　講談社&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;★Rustによるアプリケーション開発のベストプラクティス！ 　Rustを現場で使うときがきた！ Rust経験豊富な筆者が、貴重な知識とテクニックを惜しみなく伝授。 「蔵書管理アプリケーション」の実装を通じて、Rustによる設計、開発、保守、運用までをハンズオンで学ぶ！ コードも丁寧に解説。 【目次】 第1章　本書で開発するもの 第2章　開発環境の構築 第3章　最小構成アプリケーションの実装 第4章　蔵書管理サーバーアプリケーションの設計 第5章　蔵書管理サーバーの実装 第6章　システムの結合とテスト 第7章　アプリケーションの運用 第8章　エコシステムの紹介&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://www.kodansha.co.jp/book/products/0000398182&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;h2 id=&#34;モチベーション&#34;&gt;モチベーション&lt;/h2&gt;
&lt;p&gt;Rustという言語の開発体験がかなり好きでRustでサーバーサイドを書くのがどんな感じなのか純粋に気になっていたので読んでみた。（筆者がサーバーサイドの開発でガッツリ書いたことがあるのはほぼGoのみで、RustはCLIやTUIの開発にしか使ったことがないというバックグラウンド）&lt;/p&gt;
&lt;h2 id=&#34;本書の概要&#34;&gt;本書の概要&lt;/h2&gt;
&lt;p&gt;本書はRustで蔵書管理アプリケーションのサーバーサイドを実装しながらRustでのWebアプリケーション開発の仕方を学ぶことができる本。&lt;/p&gt;
&lt;p&gt;ただ動くものを作る、というよりは業務の実際のサーバーサイドの開発でよく出くわす課題をRustではどう実装するのかが豊富に紹介されている。(DIやエラーハンドリングなど)&lt;/p&gt;
&lt;p&gt;設計面ではレイヤードアーキテクチャを採用しており、レイヤー間の責務などが考慮された設計になっている。その意味でも実務での開発に近い内容になっていると言える。&lt;/p&gt;
&lt;p&gt;あとはステップごとのコード差分が丁寧に書かれているので、本書に従って実装を進めるとWeb Serverの実装が出来上がる（はず）。&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h2 id=&#34;学び&#34;&gt;学び&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;コンパイル時間短縮の工夫
&lt;ul&gt;
&lt;li&gt;アプリケーションを複数のクレートに分割することで変更があったクレートだけ再コンパイルすればよくなるためコンパイル時間が短縮できる。&lt;/li&gt;
&lt;li&gt;たとえば本書ではレイヤードアーキテクチャのレイヤーごとにクレートを分割していた。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Web開発で有用なクレート
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://crates.io/crates/derive-new&#34; target=&#34;_blank&#34; &gt;&lt;code&gt;derive_new&lt;/code&gt;&lt;/a&gt;: &lt;code&gt;new&lt;/code&gt;関数を実装してくれる。デフォルト値の設定などもできる模様。&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://crates.io/crates/serde&#34; target=&#34;_blank&#34; &gt;&lt;code&gt;serde&lt;/code&gt;&lt;/a&gt;: 言わずと知れたシリアライズ/デシリアライズのためのクレート。&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://crates.io/crates/sqlx&#34; target=&#34;_blank&#34; &gt;&lt;code&gt;sqlx&lt;/code&gt;&lt;/a&gt;: SQLを型安全に扱うことができる。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;エラーハンドリングの方法
&lt;ul&gt;
&lt;li&gt;クライアントに返すエラーはthiserrorで定義し、それ以外のエラーはanyhowを使って表現する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;RustでどうDIを実装すべきか
&lt;ul&gt;
&lt;li&gt;ジェネリクスを用いてDIするパターン（静的ディスパッチ）
&lt;ul&gt;
&lt;li&gt;動的ディスパッチと比較すると記述量が増える&lt;/li&gt;
&lt;li&gt;動的ディスパッチと比較するとパフォーマンスが高い&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;トレイトオブジェクト（&lt;code&gt;dyn &amp;lt;トレイト名&amp;gt;&lt;/code&gt;）を利用するパターン（動的ディスパッチ）
&lt;ul&gt;
&lt;li&gt;静的ディスパッチと比較すると記述量が減る&lt;/li&gt;
&lt;li&gt;静的ディスパッチと比較するとパフォーマンス面で不利&lt;/li&gt;
&lt;li&gt;本書ではWeb開発において動的ディスパッチのコストが問題になることは少ないことを理由にこちらを採用していた。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;実際にrustでweb-serverを書いてみた感想主にgoとの比較&#34;&gt;実際にRustでWeb Serverを書いてみた感想（主にGoとの比較）&lt;/h2&gt;
&lt;p&gt;※なお、筆者のRustスキルは趣味レベルなのでRustを深く理解したうえでの感想ではありません。間違っている点や他の重要な観点などがある可能性があります。また、主には個人的な考えのスナップショットを自分用に残す目的で書いているので説明を端折っている箇所がある可能性があります。&lt;/p&gt;
&lt;h3 id=&#34;ポジ&#34;&gt;ポジ&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;enumやパターンマッチ等を使って仕様をスマートに書ける。&lt;/li&gt;
&lt;li&gt;null安全なので他の言語のnull相当の概念を型安全に扱うことができる。&lt;/li&gt;
&lt;li&gt;if式を始めとした関数型ライクな言語機能のおかげで開発体験が良い。&lt;/li&gt;
&lt;li&gt;変数がデフォルトでimmutableなので、mutableな変数を目立たせやすいし、自然とimmutableなコードが書きやすい。&lt;/li&gt;
&lt;li&gt;あらゆるシンボルがデフォルトでprivateなのでカプセル化するようなコードが若干書きやすい。（意識的に&lt;code&gt;pub&lt;/code&gt;を付けなければprivateになってくれる点で強い理由がなければprivateになりやすくなる、と考えている）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;ネガ&#34;&gt;ネガ&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;コンパイル時間が長い。&lt;/li&gt;
&lt;li&gt;コンパイル時間短縮のためにcrate分割が推奨されているが、依存関係の増減があるたびに&lt;code&gt;Cargo.toml&lt;/code&gt;を手書きで編集しないといけないのが若干面倒。
&lt;ul&gt;
&lt;li&gt;もしかしたらコードアクション等、エディタの支援が得られるのかもしれないがそこまで調べられていない。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Goに慣れているとRustのマクロやアトリビュートが若干黒魔術的に感じる。これらに慣れるまでは認知負荷が高そう。例えば以下。（『RustによるWebアプリケーション開発 設計からリリース・運用まで』より引用）
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#[derive(Error, Debug)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;pub&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;enum&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;AppError&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;#[error(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;{0}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    UnprocessableEntity(String),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;#[error(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;{0}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    EntityNotFound(String),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;#[error(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;{0}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ValidationError(&lt;span style=&#34;color:#75715e&#34;&gt;#[from]&lt;/span&gt; garde::Report),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;#[error(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;トランザクションを実行できませんでした。&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    TransactionError(&lt;span style=&#34;color:#75715e&#34;&gt;#[source]&lt;/span&gt; sqlx::Error),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;#[error(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;データベース処理実行中にエラーが発生しました。&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    SpecificOperationError(&lt;span style=&#34;color:#75715e&#34;&gt;#[source]&lt;/span&gt; sqlx::Error),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;#[error(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;No rows affected: {0}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    NoRowsAffectedError(String),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;#[error(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;{0}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    KeyValueStoreError(&lt;span style=&#34;color:#75715e&#34;&gt;#[from]&lt;/span&gt; redis::RedisError),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;#[error(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;{0}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    BcryptError(&lt;span style=&#34;color:#75715e&#34;&gt;#[from]&lt;/span&gt; bcrypt::BcryptError),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;#[error(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;{0}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ConvertToUuidError(&lt;span style=&#34;color:#75715e&#34;&gt;#[from]&lt;/span&gt; uuid::Error),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;#[error(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;ログインに失敗しました&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    UnauthenticatedError,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;#[error(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;認可情報が誤っています&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    UnauthorizedError,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;#[error(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;許可されていない操作です&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ForbiddenOperation,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;#[error(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;{0}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ConversionEntityError(String),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;DIが若干複雑
&lt;ul&gt;
&lt;li&gt;Goならinterface使うだけなので考えることが少なくて済む。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;非同期処理
&lt;ul&gt;
&lt;li&gt;これもRustの非同期処理の仕組みへの理解&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;が大変浅いのであまり具体的に書けないが、自分の現状のRustスキルだとGoに比べて意図通りに動く非同期処理を書くのに数倍時間がかかる。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;まとめ&#34;&gt;まとめ&lt;/h2&gt;
&lt;p&gt;本書を読むまではRustがWebサーバーサイド開発の銀の弾丸、とまでは言わないもののかなりいい選択肢の1つのように思えていた。主に型の表現力のおかげでドメインがうまく表現できたり、所有権などの言語機能や発達したリンターによって内部品質を高く保つことができ、その結果開発生産性が高まると考えていた。&lt;/p&gt;
&lt;p&gt;しかし実際に本書でRustでサーバーを書いてみると上記のメリットはありつつも意外とRustでの実装でも手間や複雑なポイントがあり、Goのシンプルさや手軽さの良さを改めて認識した。&lt;/p&gt;
&lt;p&gt;結果はともあれ実際にRustでサーバーを書くのがどんな感じなのかを知ることが本書を読んだ目的だったので解像度を高めることができてよかった。&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;5章の途中までしかやっていないので「はず」と書いている。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;あるいは単にコンピュータの仕組みへの理解が浅いとも言えるのかもしれない。&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;もちろんもっとDeep Diveしたら違う感想を持つかも知れないが、あくまで今時点の自分の感想としては上記のような感じ。&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</content>
    </item>
    
    <item>
      <title>『コンセプトから理解するRust』を読んだ</title>
      <link>https://blog.kyu08.com/posts/understanding-rust-from-concepts/</link>
      <pubDate>Mon, 15 Dec 2025 19:21:35 +0900</pubDate>
      
      <guid>https://blog.kyu08.com/posts/understanding-rust-from-concepts/</guid>
      <description>Rustのことをもっと理解りたくて『コンセプトから理解するRust』を読んだ。 コンセプトから理解するRust | 技術評論社Rustはメモリ安全</description>
      <content>&lt;p&gt;&lt;img src=&#34;./book.webp&#34; alt=&#34;book&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;Rustのことをもっと理解りたくて『コンセプトから理解するRust』を読んだ。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://gihyo.jp/book/2022/978-4-297-12562-2&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://gihyo.jp/book/2022/978-4-297-12562-2&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail&#34;&gt;
      &lt;img src=&#34;https://gihyo.jp/assets/images/ogp/2022/9784297125622.jpg&#34; alt=&#34;コンセプトから理解するRust | 技術評論社&#34; loading=&#34;lazy&#34;&gt;
    &lt;/div&gt;&lt;div class=&#34;blogcard-content&#34;&gt;
      &lt;div class=&#34;blogcard-title&#34;&gt;コンセプトから理解するRust | 技術評論社&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;Rustはメモリ安全、スレッド安全を保ちつつ、高パフォーマンスなプログラムを開発できるプログラミング言語です。また、手続き型、オブジェクト指向型、関数型でのプログラミングに対応できるマルチパラダイムの言語でもあります。ただ、そういったRustのポテンシャルを引き出すには、所有権やライフタイム、ジェネリクスやトレイトといった特徴的な仕様の理解が求められ、これらは初学者の壁にもなっています。本書ではそれら難解な仕様をピックアップし、他のプログラミング言語とコードレベルで比較しながら、「なぜそのような仕様になっているか」という言語のコンセプトからRustの理解を試みます。加えて、Rustのこまやかなエラーメッセージを読みつつ、Rustをうまく書くための知識もお伝えします。&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://gihyo.jp/book/2022/978-4-297-12562-2&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;h2 id=&#34;前提&#34;&gt;前提&lt;/h2&gt;
&lt;p&gt;筆者のRustの知識は&lt;a href=&#34;https://tourofrust.com/00_ja.html&#34; target=&#34;_blank&#34; &gt;Tour of Rust&lt;/a&gt;や&lt;a href=&#34;https://doc.rust-jp.rs/book-ja/&#34; target=&#34;_blank&#34; &gt;The Rust Programming Language&lt;/a&gt;を読んだり簡単なツール&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;を作ったことがある程度で、非同期処理をスラスラ書けたり、スムーズに人に教えたりできるレベルではない。&lt;/p&gt;
&lt;p&gt;過去に&lt;a href=&#34;https://doc.rust-jp.rs/book-ja/&#34; target=&#34;_blank&#34; &gt;The Rust Programming Language&lt;/a&gt;を読んだときもスマートポインターまわりなどは飛ばしつつ読んでいたので本書での学びは多かった。&lt;/p&gt;
&lt;h2 id=&#34;学び&#34;&gt;学び&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Box&lt;/code&gt;について理解した。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Rc&lt;/code&gt;, &lt;code&gt;RefCell&lt;/code&gt;, &lt;code&gt;Weak&lt;/code&gt;周りをなんとなく理解した。たぶん空では書けないが、エラーになったら調べて解決できるくらいの理解にはなったはず。&lt;/li&gt;
&lt;li&gt;トレイト境界についてちょっとわかった。&lt;/li&gt;
&lt;li&gt;クロージャ, &lt;code&gt;Fn&lt;/code&gt;, &lt;code&gt;FnMut&lt;/code&gt;, &lt;code&gt;FnOnce&lt;/code&gt;について理解できた。&lt;/li&gt;
&lt;li&gt;簡単な非同期処理の仕組みがわかった。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;今まで全然わかっていなかったこれらの概念が少しだけわかった。やはりコードを書き散らかすだけでなく体系的なインプットも大事&amp;hellip;。（それはそう）&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;おそらく今後Rustを書いたりコンパイラと対話したりしていくともう少し深く理解していけると思う。&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;全体を通してコード例が豊富だったので手元で動かしながら理解しやすくてとてもありがたかった。&lt;/p&gt;
&lt;h2 id=&#34;まとめ&#34;&gt;まとめ&lt;/h2&gt;
&lt;p&gt;Rustの力がまた少しついた。&lt;/p&gt;
&lt;p&gt;Rustを学ぶとRust自体への理解が深まるだけでなく、少なからずコンピュータの仕組みに近い低レイヤな部分の理解も一緒に深まるので勉強になる感覚があって楽しめた。&lt;/p&gt;
&lt;p&gt;非同期処理周りはあまりちゃんと勉強したことがないので次はこの本を読んでみようと思う。（サンプルコードが主にRustで書かれているらしいのでこの本での学びも活かせそう）&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://www.oreilly.co.jp/books/9784873119595/&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://www.oreilly.co.jp/books/9784873119595/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail&#34;&gt;
      &lt;img src=&#34;https://www.oreilly.co.jp/books/images/picture_large978-4-87311-959-5.jpeg&#34; alt=&#34;並行プログラミング入門&#34; loading=&#34;lazy&#34;&gt;
    &lt;/div&gt;&lt;div class=&#34;blogcard-content&#34;&gt;
      &lt;div class=&#34;blogcard-title&#34;&gt;並行プログラミング入門&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;複数のプログラムを同時に実行する「並行プログラミング」は、処理速度を飛躍的に向上させる手法で、タスク管理、プロセス管理、スレッド管理をはじめ、複雑な仕組みについての幅広い知識とテクニックが必要となります。本書はRustとアセンブリ、そして一部Cを用い、CPUのアトミック命令、グリーンスレッド、アクターモデル、π計算、ソフトウェア・トランザクショナルメモリ、async/awaitなど、並行プログラミングに関する理論的な背景から実装までをカバー。さらに、アセンブリ実装の理解を深めるため、AArch64とx86-64アーキテクチャの説明も付録として収録。一歩一歩、着実に理解できるように、その仕組みから順を追って詳しく説明します。GitHub上で公開されているソースコードを実際に動かしながら、並行プログラミングの知識と理解を深めることができます。&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://www.oreilly.co.jp/books/9784873119595/&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;h2 id=&#34;おまけ&#34;&gt;おまけ&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;The name &amp;ldquo;Tokio&amp;rdquo; is derived from Tokyo and mio, and the Tokio logo vaguely resembles the city emblem of Tokyo.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Tokio_%28software%29&#34; target=&#34;_blank&#34; &gt;https://en.wikipedia.org/wiki/Tokio_(software)&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Rustの非同期ランタイムのtokioの名前の由来の一部は東京らしい。&lt;/p&gt;
&lt;p&gt;あとロゴも東京都の紋章を彷彿とさせるデザインになっているらしい。（実際調べてみたら似ているというかほぼ同じだったw）&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/kyu08/fzf-make&#34; target=&#34;_blank&#34; &gt;fzf-make&lt;/a&gt;というTUIツールを書いている。あとそういえば&lt;a href=&#34;https://github.com/kyu08/sunaba/tree/main/rust/nand2tetris&#34; target=&#34;_blank&#34; &gt;nand2tetris&lt;/a&gt;もRustで書いていた。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;趣味のプログラミングなのでRustを覚え始めた頃は楽しさ優先でまあ動けばOKという気持ちで書いていたが最近になってちゃんと理解したくなってきたので学んでいる。&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;あるいは各種概念を自作するという選択肢もあるかもしれない。Arcとか非同期ランタイムとか&amp;hellip;。&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;他には&lt;a href=&#34;https://www.oreilly.co.jp/books/9784814400515/&#34; target=&#34;_blank&#34; &gt;詳解 Rustアトミック操作とロック&lt;/a&gt;、&lt;a href=&#34;https://www.oreilly.co.jp/books/9784814401185/&#34; target=&#34;_blank&#34; &gt;Async Rust
&lt;/a&gt;、&lt;a href=&#34;https://www.kodansha.co.jp/book/products/0000398182&#34; target=&#34;_blank&#34; &gt;RustによるWebアプリケーション開発　設計からリリース・運用まで
&lt;/a&gt;あたりもとても気になっている。&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</content>
    </item>
    
    <item>
      <title>『つくって、壊して、直して学ぶ Kubernetes入門』を読んだ</title>
      <link>https://blog.kyu08.com/posts/bbf_kubernetes/</link>
      <pubDate>Wed, 10 Dec 2025 00:04:41 +0900</pubDate>
      
      <guid>https://blog.kyu08.com/posts/bbf_kubernetes/</guid>
      <description>0からKubernetesのキャッチアップがしたくて、高橋 あおいさん著の『つくって、壊して、直して学ぶ Kubernetes入門』を読んだ。 つ</description>
      <content>&lt;p&gt;&lt;img src=&#34;./book.webp&#34; alt=&#34;book&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;0からKubernetesのキャッチアップがしたくて、高橋 あおいさん著の『つくって、壊して、直して学ぶ Kubernetes入門』を読んだ。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://www.shoeisha.co.jp/book/detail/9784798183961&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://www.shoeisha.co.jp/book/detail/9784798183961&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail&#34;&gt;
      &lt;img src=&#34;https://www.shoeisha.co.jp/static/book/og_image/9784798183961.jpg&#34; alt=&#34;つくって、壊して、直して学ぶ Kubernetes入門 | 翔泳社&#34; loading=&#34;lazy&#34;&gt;
    &lt;/div&gt;&lt;div class=&#34;blogcard-content&#34;&gt;
      &lt;div class=&#34;blogcard-title&#34;&gt;つくって、壊して、直して学ぶ Kubernetes入門 | 翔泳社&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;動かなくっても、もう怖くない！

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


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


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



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



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



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

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


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


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



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



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



Part 1：つくってみようKubernetes
Chapter 1　Dockerコンテナをつくってみる
Chapter 2　Kubernetesクラスタをつくってみる
Chapter 3　全体像の説明
Chapter 4　アプリケーションをKubernetesクラスタ上につくる
Part 2：アプリケーションを壊して学ぶKubernetes
Chapter 5　トラブルシューティングガイドとkubectlコマンドの使い方
Chapter 6　Kubernetes リソースをつくって壊そう
Chapter 7　安全なステートレス・アプリケーションをつくるために
Chapter 8　総復習：アプリケーションを直そう
Part 3：壊れても動くKubernetes
Chapter 9　Kubernetesの仕組み、アーキテクチャーを理解しよう
Chapter 10　Kubernetesの開発ワークフローを理解しよう
Chapter 11　オブザーバビリティとモニタリングに触れてみよう
Chapter 12　この先の歩み方&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://www.shoeisha.co.jp/book/detail/9784798183961&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://www.sbcr.jp/product/4815618599/&#34; target=&#34;_blank&#34; &gt;https://www.sbcr.jp/product/4815618599/&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</content>
    </item>
    
    <item>
      <title>VimConf 2025 Smallに参加した</title>
      <link>https://blog.kyu08.com/posts/vim-conf-2025/</link>
      <pubDate>Sun, 02 Nov 2025 01:07:08 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/posts/vim-conf-2025/</guid>
      <description>2025年11月2日（日）にアキバプラザ・アキバホールで開催されたVimConf 2025 Smallに参加した。 こちらはノベルティ。食器とかお箸はた</description>
      <content>&lt;p&gt;2025年11月2日（日）にアキバプラザ・アキバホールで開催された&lt;a href=&#34;https://vimconf.org/2025/ja/&#34; target=&#34;_blank&#34; &gt;VimConf 2025 Small&lt;/a&gt;に参加した。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;vim-conf-2025.webp&#34; alt=&#34;vim-conf-2025.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;こちらはノベルティ。食器とかお箸はたくさんあっても困らないのでありがたい。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;お茶碗&lt;/li&gt;
&lt;li&gt;お箸&lt;/li&gt;
&lt;li&gt;コースター&lt;/li&gt;
&lt;li&gt;巾着&lt;/li&gt;
&lt;li&gt;お茶&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&#34;vim-conf-novelty.webp&#34; alt=&#34;vim-conf-novelty.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;nvim-cmp-retrospective-exploring-completion-and-facing-foss-challenges&#34;&gt;nvim-cmp retrospective: Exploring Completion and Facing FOSS Challenges&lt;/h2&gt;
&lt;p&gt;hrsh7thさんによる発表。&lt;/p&gt;
&lt;h3 id=&#34;explore-completion&#34;&gt;Explore Completion&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;nvim-cmpのcmpって「シーエムピー」って読むんだ（「コンプ」って読んでた）&lt;/li&gt;
&lt;li&gt;補完プラグインってめちゃめちゃいろんなケースを考慮して作られているんだな&amp;hellip;（全然詳しくないので薄い感想しか出てこない）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;foss-challenges&#34;&gt;FOSS Challenges&lt;/h3&gt;
&lt;p&gt;大きなOSSプロジェクトをメンテすることになったことでの学びの共有。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;もともとはユーザーが求めるものと自分のやりたいことが合致していた。自分がやりたいことをやることで感謝してもらえていた。
&lt;ul&gt;
&lt;li&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;ユーザーが求めること
&lt;ul&gt;
&lt;li&gt;安定した動作&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;結果モチベが下がった&lt;/li&gt;
&lt;li&gt;予期せずプロジェクトが大きくなって責任が芽生えた&lt;/li&gt;
&lt;li&gt;モチベが低いならコミュニティ主導にすればいいのでは？という意見も見るが&amp;hellip;
&lt;ul&gt;
&lt;li&gt;直接話したこともない人をrepositoryに招待するのは危険だと感じた（ユーザー数も多いのでサプライチェーンアタックが怖い）
&lt;ul&gt;
&lt;li&gt;実際にhrsh7thさんが作ったプラグインのコピープラグインがリリース1週間後にできて、そこにマルウェアが含まれていたことがあるらしい（怖すぎる）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;新メンテナのオンボーディングをサポートするのも大変&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;とはいえOSS開発は楽しい
&lt;ul&gt;
&lt;li&gt;nvim-cmpを公開して「これめっちゃ便利だね！」といってもらえたのはとても印象に残っている&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;p&gt;たくさんのユーザーを抱えるOSSのメンテ目線のリアルな心境を聞けてよかった。&lt;/p&gt;
&lt;p&gt;大規模OSSのメンテナに憧れる気持ちもあるが、楽しいこともあればその分大変なこともあるんだろうな〜などと思った。（それはそう）&lt;/p&gt;
&lt;p&gt;とはいえたくさんの開発者、プロジェクトに寄与するような大規模OSSメンテナへの憧れはあるのでコミットしたいOSSが見つかったら挑戦してみようと思う。&lt;/p&gt;
&lt;h2 id=&#34;and-yet-vim-survived-thinking-and-seeing-in-the-age-of-code-you-dont-write&#34;&gt;And Yet, Vim Survived: Thinking and Seeing in the Age of Code You Don&amp;rsquo;t Write&lt;/h2&gt;
&lt;p&gt;Λlisueさんによるコードリーディングに関する発表。&lt;/p&gt;
&lt;p&gt;以下の3stepに分けてコードを読む。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Where - Seeing the flow&lt;/li&gt;
&lt;li&gt;What - Seeing the structure&lt;/li&gt;
&lt;li&gt;Why - Seeing the Reasoning&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;where---seeing-the-flow&#34;&gt;Where - Seeing the Flow&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;File Jumps
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;gf&lt;/code&gt; / &lt;code&gt;gF&lt;/code&gt; - open file under cursor&lt;/li&gt;
&lt;li&gt;これ知らなかった。&lt;code&gt;go test&lt;/code&gt;の結果を見て失敗しているファイルに飛ぶときとかに便利そう。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Search Jumps
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/&lt;/code&gt;や&lt;code&gt;?&lt;/code&gt;で検索し&lt;code&gt;n&lt;/code&gt;でジャンプ&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;fall.nvim(fuzzy finder)
&lt;ul&gt;
&lt;li&gt;検索して&lt;code&gt;n&lt;/code&gt;で飛ぶのに比べて&lt;code&gt;&amp;lt;c-o&amp;gt;&lt;/code&gt;で直前の位置に戻れるので便利&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Quickfix
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;]q&lt;/code&gt; / &lt;code&gt;[q&lt;/code&gt;でジャンプできる&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;what---seeing-the-structure&#34;&gt;What - Seeing the structure&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Window management
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;c-w&amp;gt;&lt;/code&gt; + &lt;code&gt;s&lt;/code&gt;/&lt;code&gt;v&lt;/code&gt;/&lt;code&gt;h&lt;/code&gt;/&lt;code&gt;j&lt;/code&gt;/&lt;code&gt;k&lt;/code&gt;/&lt;code&gt;l&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;c-w&amp;gt;&lt;/code&gt; + &lt;code&gt;o&lt;/code&gt;: （複数ウィンドウを開いているときに実行すると）現在のウィンドウのみを表示する
&lt;ul&gt;
&lt;li&gt;nativeだと元の状態に戻れない&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;goyo.vim&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;code&gt;&amp;lt;c-w&amp;gt;&lt;/code&gt; + &lt;code&gt;o&lt;/code&gt;をもう一度実行するともとのウィンドウの状態に戻れる。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;file treeは知らないファイルを探すために使う&lt;/li&gt;
&lt;li&gt;fuzzy finderは知っているファイルを開くために使う&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;why---seeing-the-reasoning&#34;&gt;Why - Seeing the Reasoning&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;git blameを活用してコードの背景を理解しながらコードを読む&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;感想-1&#34;&gt;感想&lt;/h3&gt;
&lt;p&gt;ありすえさんが発表がうますぎてその点でも勉強になった。特にこのあたりのポイントが勉強になった。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;論理構造が自然で理解しやすかった&lt;/li&gt;
&lt;li&gt;話す速度、スライドの情報量が多すぎなかったのでついていきやすかった&lt;/li&gt;
&lt;li&gt;ユーモアを交えていて楽しく聞けた&lt;/li&gt;
&lt;li&gt;シンプルに滑舌が良かった（わかんないけどマイクの使い方とかも違うんだろうか。なんかとにかく声が明瞭で聞き取りやすかった）&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;beyond-syntax-highlighting-unlocking-the-power-of-tree-sitter-in-neovim&#34;&gt;Beyond Syntax Highlighting: Unlocking the Power of Tree-sitter in Neovim&lt;/h2&gt;
&lt;p&gt;atusyさんによるtree-sitterに関する発表。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://github.com/atusy/treemonkey.nvim&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://github.com/atusy/treemonkey.nvim&#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/804219f33da8a500a826d1d11eba82298c6ccc5bb6beaa63485762164a54cbbf/atusy/treemonkey.nvim&#34; alt=&#34;GitHub - atusy/treemonkey.nvim&#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 - atusy/treemonkey.nvim&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;Contribute to atusy/treemonkey.nvim development by creating an account on GitHub.&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://github.com/atusy/treemonkey.nvim&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
 便利そう&lt;/p&gt;
&lt;p&gt;tree-sitterをもっと深く理解したくなった（&lt;a href=&#34;https://github.com/kyu08/fzf-make&#34; target=&#34;_blank&#34; &gt;趣味のプロジェクト&lt;/a&gt;で&lt;a href=&#34;https://github.com/IndianBoy42/tree-sitter-just&#34; target=&#34;_blank&#34; &gt;IndianBoy42/tree-sitter-just&lt;/a&gt;に依存しているので自分もメンテに参加できるようになりたい）&lt;/p&gt;
&lt;h2 id=&#34;designing-repeatable-edits-the-architecture-of--in-vim&#34;&gt;Designing Repeatable Edits: The Architecture of . in Vim&lt;/h2&gt;
&lt;p&gt;Satoru Kitaguchiさんによるドットリピートの解説。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;.&lt;/code&gt;でリピートできる操作
&lt;ul&gt;
&lt;li&gt;ノーマルモードから始まってバッファを編集し、ノーマルモードに戻ってくる&lt;/li&gt;
&lt;li&gt;undoツリー上のlast-change nodeを再実行している = 直前の編集チャンクを再適用する&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;daw&lt;/code&gt;, &lt;code&gt;ci&amp;quot;&lt;/code&gt;などはリピートできる&lt;/li&gt;
&lt;li&gt;Visual modeを含んだ操作などはリピートできない
&lt;ul&gt;
&lt;li&gt;Visual modeでは内部的には選択された文字数や行数しか保持されないため&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;さらっとVimの内部動作を解説していてかっこよすぎた。Vimのコードを読んだのか、Vimの内部構造を解説しているsomethingがどこかに存在するのかちょっと気になった。かなり周到に調査されてスライドを作られてそうな印象を受けた。&lt;/p&gt;
&lt;p&gt;便利なプラグインの情報を集めるのも楽しいが、たまにはちゃんとVim自体の機能を学んだ方がかえって効率よく日々の操作を効率化できそうだな〜と思った。&lt;/p&gt;
&lt;p&gt;実践Vimを読みたい気持ちが芽生えた。（n回目）&lt;/p&gt;
&lt;h2 id=&#34;lt&#34;&gt;LT&lt;/h2&gt;
&lt;p&gt;ryoppippiさんの &lt;a href=&#34;https://github.com/ryoppippi/nvim-in-the-loop&#34; target=&#34;_blank&#34; &gt;https://github.com/ryoppippi/nvim-in-the-loop&lt;/a&gt; がかなり便利そう。&lt;/p&gt;
&lt;p&gt;自分のVimの操作履歴を記録し、AIにどのようなキーマップを登録すると無駄な操作を減らせるかを分析させるというものらしい。すごい。&lt;/p&gt;
&lt;h2 id=&#34;まとめ&#34;&gt;まとめ&lt;/h2&gt;
&lt;p&gt;学びや刺激を得られたので行って良かった。&lt;/p&gt;
&lt;p&gt;発表内容もさることながらプレゼンが上手な方がいたり、（おそらく日本の方だけど）英語が超上手な方がいたりして、その意味でも刺激を得られた。&lt;/p&gt;
&lt;p&gt;今回初参加なので他の回との比較はできないが全然Smallな感じがせず、満足感が高かった。（もしやSmallじゃない回は2トラックとかあったりする&amp;hellip;?）&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/junegunn/goyo.vim&#34; target=&#34;_blank&#34; &gt;https://github.com/junegunn/goyo.vim&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>
    
    <item>
      <title>『Tidy First?』を読んだ</title>
      <link>https://blog.kyu08.com/posts/tidy-first/</link>
      <pubDate>Sat, 04 Oct 2025 08:21:10 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/posts/tidy-first/</guid>
      <description>『Tidy First?』を読んだ。 勉強になったところをまとめる。 「整頓」という概念 整頓はリファクタリングのサブセットだ。整頓は可愛くてふわふ</description>
      <content>&lt;p&gt;『&lt;a href=&#34;https://www.oreilly.co.jp/books/9784814400911/&#34; target=&#34;_blank&#34; &gt;Tidy First?&lt;/a&gt;』を読んだ。&lt;/p&gt;
&lt;p&gt;勉強になったところをまとめる。&lt;/p&gt;
&lt;h2 id=&#34;整頓という概念&#34;&gt;「整頓」という概念&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;整頓はリファクタリングのサブセットだ。整頓は可愛くてふわふわした小さなリファクタリングなので、誰も嫌いになれないはずだ。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;リファクタリングほど大掛かりなものではなく、数十分でできるような小さな改善を本書では「整頓」と呼んでいる。&lt;/p&gt;
&lt;p&gt;具体的にはコードコメントを追加したり適切な位置に空行を配置したり適切な変数名に変更したりすることなどを指している。&lt;/p&gt;
&lt;p&gt;この「整頓」という概念を知ることができたのが本書を読んで得られた最大の収穫だった。今までそのような行為に名前をつけたことがなかったが名前をつけることで使い所や意義が明確になり意識的に実践できるようになりそう。&lt;/p&gt;
&lt;p&gt;なお本書では「整頓」と「振る舞いの変更」の順番やタイミング、粒度や意義について様々な角度から書かれているので気になる方はぜひ手にとってみてほしい。&lt;/p&gt;
&lt;h2 id=&#34;第11章-ステートメントを小分けにする&#34;&gt;第11章 ステートメントを小分けにする&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;大きなコードのチャンクを読んでいると、「ああ、ここは&lt;strong&gt;これ&lt;/strong&gt;をしていて、あそこで&lt;strong&gt;あれ&lt;/strong&gt;をしているのか」とわかる。そのあいだに空行を入れよう。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;長めの関数を読むとき、空行がまったくないことは少ないが空行の位置を改善できそうだと感じることがたまにある。&lt;/p&gt;
&lt;p&gt;処理の塊ごとに適切に改行されているだけでそこそこ可読性が上がる実感があるのでやってみようと思う。（空行の追加/削除のみのPRであればレビュワーの負担もかなり少ないはず）&lt;/p&gt;
&lt;h2 id=&#34;第13章-ひとかたまり&#34;&gt;第13章 ひとかたまり&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;細かく分割されているがゆえに、かえって理解を妨げているようなコードに出会うことはないだろうか。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;超巨大な関数はテストしづらく可読性も低いので避けたいが、逆にすべての処理を関数として切り出してしまうと毎回定義ジャンプしないと処理の内容がわからないのでかえって読みづらくなってしまう。&lt;/p&gt;
&lt;p&gt;テストが書きやすい程度に細かくかつ可読性が落ちない程度には大きく関数を切り出すのがよさそうで、いい塩梅を探るには複数のパターンを実際に書いてみて読みやすいかどうかを判断するのがよさそう。（実際に複数パターンを書いてみると意外とすぐに書けることが多いし、しかも実際に書いてみると事前の想定とは印象が違うことが多いように思う）&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;小さな部品に分けようとするのは、コードを少しずつ理解できるようにしたいからだ。だが、ときには、このプロセスが間違った方向に進むことがある。小さな部品のやりとりの仕方によっては、コードが&lt;strong&gt;理解しにくくなる&lt;/strong&gt;のだ。明確さを取り戻すには、まずはコードを1箇所に集めて、それから改めて、簡単に理解できる部品を抽出する。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;1000行の関数でこれをやるとさすがに辛そうだが、100行前後くらいであればひとまず1つにまとめてから再構成するのはたしかに良さそう。&lt;/p&gt;
&lt;h2 id=&#34;第14章-説明コメント&#34;&gt;第14章 説明コメント&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;コードを読んでいて「なるほど、それで&lt;strong&gt;こう&lt;/strong&gt;なっているのか」と声が出ることがある。これは貴重な瞬間だ。記録しよう。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;コードリーディングの結果、必要なコメントが欠けていることに気づくことがある。&lt;/p&gt;
&lt;p&gt;そういった場面でこれまであまりPRを作ったりはしてこなかったが、説明コメントの追加も立派な整頓であり将来の読者（当然将来の自分を含む）の時間を節約することに繋がるのでやっていきたい。&lt;/p&gt;
&lt;p&gt;説明コメントの追加PRはレビュワーの負荷が少ない割にレビュイーとレビュワーのコード理解を深められる点で比較的コスパの良い取り組みな気がした。（正確な説明コメントを書くための調査が大変、とかはあるかもだが）&lt;/p&gt;
&lt;h2 id=&#34;第19章-リズム&#34;&gt;第19章 リズム&lt;/h2&gt;
&lt;p&gt;1つの整頓にかける時間はここでは1時間くらいまでが許容範囲とされており、それを大幅に超過するようであれば変更の単位が大きすぎる兆候らしい。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;こんな話を聞いたことはないだろうか。ある大学がたくさんの建物を造った。計画者は、それを結ぶ歩道をどこに造るか考えていた。だが、そこで経験にもとづいて注意深く推測するのではなく、建物のあいだのエリアに芝生を植えたのだ。
数か月後、学生の歩いた跡によって芝生に道ができた。計画者は芝生がなくなったところを舗装した。&lt;/p&gt;
&lt;p&gt;コードにおいて、振る舞いの変更は一部に集中する傾向にある。パレートの法則にあるように、80%の変更は20%のファイルで起こる。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;（計画者天才すぎワロタ&amp;hellip;）&lt;/p&gt;
&lt;p&gt;変更の前に整頓することを続けていくと頻繁に変更される20%のコードがどんどん綺麗になっていく、ということを言っているのだと解釈した。&lt;/p&gt;
&lt;p&gt;そうした取り組みを続けていくとコードの大部分は手直ししてないにもかかわらず整頓していないコードに出会うことは稀になる。逆に言うと仮にコードの50%を頑張って綺麗にしたところで、その50%に変更がまったく入らないのであれば投資対効果が高いとはいえないかもしれない。（当然、コード全体が複雑に絡み合っていて一部だけ再設計することが難しい場合や全体的に変更しないと一貫性がなくなる場合などはその限りではないと思う）&lt;/p&gt;
&lt;p&gt;なのでコードを修正する際は単純にある時点のコードベースだけを見てコード品質に改善点が見つかったというだけの理由で修正する、というよりは修正すべき合理的な理由（e.g. 内部品質が課題で問題が起きている、よく変更が入る箇所が変更しづらくなっているなど）がある箇所から対応していくのがよさそう。&lt;/p&gt;
&lt;h2 id=&#34;第21章-先に整頓あとに整頓改めて整頓整頓しない&#34;&gt;第21章 先に整頓、あとに整頓、改めて整頓、整頓しない&lt;/h2&gt;
&lt;p&gt;整頓を変更の前にやるか、あとにやるか、将来時間がとれたときにやるか、あるいはまったくやらないかについて論じた章。&lt;/p&gt;
&lt;p&gt;章のまとめにもあるように結局はビジネスにとって合理的なタイミングでやるのがよい、ということなのだと思った。（言葉にするとそれはそうという感じではあるが）&lt;/p&gt;
&lt;p&gt;「改めて整頓する」と「あとに整頓する」の区別はあまり考えたことがなかったが、整頓が完了するまでの必要工数が
大きいケース以外は「あとに整頓する」に寄せるのが良さそうに感じた。&lt;/p&gt;
&lt;h2 id=&#34;第25章-明日の1ドルより今日の1ドル&#34;&gt;第25章 明日の1ドルより今日の1ドル&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;お金を生む振る舞いの変更を今すぐ実装して、あとから整頓できるなら、すぐにお金が手に入り、あとでお金を使うことになる(前述のとおり、ときには先に整頓してから振る舞いを変更するほうが整頓せずに変更するよりも安価なこともある。そんな場合は常に先に整頓する)。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;ビジネス的なメリットがあるならば整頓を後回しにすることが合理的になるのは十分にありえる。(e.g. 12/1までにリリースできれば大企業A社の受注に繋がるが、それを超過してしまうと競合他社と契約されてしまい、A社と契約できるチャンスが消滅してしまう)&lt;/p&gt;
&lt;p&gt;逆に、先に整頓したほうが変更が楽になるならそうする。コードベースへの理解、ビジネスへの関心と理解（デッドラインは最終的なものなのか、調整可能なのか）、一定の設計スキルなどがあるとこの判断の練度を上げることに繋がりそう。&lt;/p&gt;
&lt;!-- 逆に、先に整頓したほうが変更が楽になるならそうする。じゃあメリデメを整理していい感じに判断すればいいじゃん、という話になるがこの判断を正確にするためにはコードベースへの理解、ビジネスへの関心と理解（デッドラインは最終的なものなのか、調整可能なのか）、一定の設計スキルなどが必要そう。 --&gt;
&lt;h2 id=&#34;第26章-オプション&#34;&gt;第26章 オプション&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;「次にどのような振る舞いを実装できるか」は、実装する前から、それ自体に価値がある。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;これはあまり考えたことがなかった。「プログラムの変更容易性は将来の実装工数を削減するために重要である」というアイディアと本質的には近いことを言ってそうだが、「価値」という切り口で捉え直すとたしかに変更容易性は価値と等価ともいえそう。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;（これが最重要なのだが）価値予測の不確実性が&lt;strong&gt;高い&lt;/strong&gt;ほど、オプションの価値は&lt;strong&gt;高い&lt;/strong&gt;（今すぐ実装するのと比べて）。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;価値予測の不確実性と変更容易性の価値についてもあまり考えたことがなかったが納得感があった。たとえばよくあるSaaSモデルのプロダクトであれば探索しながら市場の反応を見たり変化に対応したりすることが必要で、そのためには変更容易性が必要なのでその価値がより高まる、ということだと理解した。&lt;/p&gt;
&lt;h2 id=&#34;第32章-凝集&#34;&gt;第32章 凝集&lt;/h2&gt;
&lt;p&gt;凝集性が低いモジュールの改善方法についての章だが、どちらかというと章の後半に書かれていた下記の記述が参考になった。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;次の人のために少しだけコードを整頓しておこう。全員がこのボーイスカウトルール(「来たときよりも美しく」)に従えば、そのうちにより扱いやすいコードになっていくだろう。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;これまではボーイスカウトルールというと「触ったコードの負債をできるだけ&lt;strong&gt;リファクタリングして綺麗にすべし&lt;/strong&gt;」のような考え方だと認識していた（これ自体は間違いではないと思う）。&lt;/p&gt;
&lt;p&gt;本格的なリファクタリングまではいかなくとも、本書で「整頓」として紹介されている「コードコメントの追加」や「空行の調整」なども十分ボーイスカウト的な行為なのだなと考え直して少しハードルが下がる感覚を得た。&lt;/p&gt;
&lt;h2 id=&#34;第33章-結論&#34;&gt;第33章 結論&lt;/h2&gt;
&lt;p&gt;本書のタイトルにもなっている、どんなときに先に整頓すべきかについてのまとめの章。&lt;/p&gt;
&lt;p&gt;以下の4つの観点で整理して決断するとよい、と書かれている。次に判断に迷った際には参考にしてみたい。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;コスト&lt;/li&gt;
&lt;li&gt;収益&lt;/li&gt;
&lt;li&gt;結合&lt;/li&gt;
&lt;li&gt;凝集&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- &gt; だが、いちばん重要なのはあなただ。整頓はあなたのプログラミングに平穏と満足、喜びをもたらしてくれるだろうか? 多少はありそうだ。これは重要だ。なぜなら、あなたが最高の自分でいれば、より良いプログラマーでいられるからだ。いつも急いでいて、変更に痛みを伴うコードの変更をしているなら、最高の自分ではいられない。 --&gt;
&lt;!----&gt;
&lt;!-- この部分に関してはちょっと諸説ありそうだと思った。 --&gt;
&lt;!----&gt;
&lt;!-- プログラマ的にはクリーンなコードを書いたり、コードをクリーンにする作業自体が楽しかったり、そこから学びを得ることができるというのは当然理解できる。 --&gt;
&lt;!----&gt;
&lt;!-- ただ業務であまりそこを重視しすぎるとビジネス的な都合を無視する考えに繋がるのでは...と思った。（著者はそこまで言ってないかもだが）一般的にはビジネスがうまくいかないと売上が上がらないことに起因してモチベーションが下がったり報酬が思ったように上がらなかったり、働く環境が悪化したりすることもあるため難しい。 --&gt;
&lt;!----&gt;
&lt;!-- いちメンバーの視点だとビジネス都合とソフトウェアの状況を勘案して総合的に判断するのがよさそうな気がした。 --&gt;
&lt;!----&gt;
&lt;!-- マネジメント側の立場だとメンバーのパフォーマンスを高めることも重要な責務なのでうまくバランスを取るのが重要そう。 --&gt;
&lt;h2 id=&#34;まとめ&#34;&gt;まとめ&lt;/h2&gt;
&lt;p&gt;164ページと全体がコンパクトにまとまっているのと、簡潔に書かれている（かつ、翻訳もとても読みやすい）ので短時間で読みやすかった。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;「整頓」&lt;/strong&gt; という概念を知れたのが最大の収穫だった。今後は意識的に実践していきたいと思う。&lt;/p&gt;
&lt;p&gt;次回作の構想もあるようなので楽しみ。&lt;/p&gt;
</content>
    </item>
    
    <item>
      <title>追いKeychron V4 Max</title>
      <link>https://blog.kyu08.com/posts/second-keychron-v4-max/</link>
      <pubDate>Thu, 28 Aug 2025 14:24:39 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/posts/second-keychron-v4-max/</guid>
      <description>Keychron V4 Max を買ったで紹介したV4 MAXはオフィス用のV4 MAXになった。あまりにも使い心地がいいので家用のV4 MAXを買い足した。 前回はキーキャ</description>
      <content>&lt;p&gt;&lt;img src=&#34;box.webp&#34; alt=&#34;box.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;v4-max.webp&#34; alt=&#34;v4-max.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.kyu08.com/posts/keychron-v4-max&#34; &gt;Keychron V4 Max を買った&lt;/a&gt;で紹介したV4 MAXはオフィス用のV4 MAXになった。あまりにも使い心地がいいので家用のV4 MAXを買い足した。&lt;/p&gt;
&lt;p&gt;前回はキーキャップとスイッチが家に余ってたのでベアボーンを買ったが、もう在庫はないし20$足せばキーキャップがついてくるので今回はフルセットの方を買った。（どうせ赤軸は苦手だからどのみちキースイッチは買うつもりだった）&lt;/p&gt;
&lt;p&gt;送料込みで$112.99(¥17,400 JPY)だった。&lt;/p&gt;
&lt;p&gt;8/24に発送連絡がきて8/28に届いた。中国からの発送なのに早くてすごい。&lt;/p&gt;
&lt;p&gt;開封してちょっと触ってみたがやはり赤軸は苦手な感じだったのでオフィスにおいてあるV4 MAXと同じくKailh Box Silent Pink軸をAmazonで買った。&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;60%で本体重量が軽めで打鍵感が良さげな既製品キーボードが意外と少ないのでディスコンになる前に買えてよかったー。&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;ディスコンらしいけどなんとかまだ在庫があって助かった〜&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;たしかこのモデルも発売から2,3年経ってた気がするので買えてラッキー&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>Keychron V4 Max を買った</title>
      <link>https://blog.kyu08.com/posts/keychron-v4-max/</link>
      <pubDate>Thu, 19 Jun 2025 14:38:21 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/posts/keychron-v4-max/</guid>
      <description>持ち運び用に軽めの60%メカニカルキーボードが欲しくなり、いくつか検討した結果、Keychron V4 Max(Barebone)を買った。 候補 持</description>
      <content>&lt;p&gt;持ち運び用に軽めの60%メカニカルキーボードが欲しくなり、いくつか検討した結果、&lt;a href=&#34;https://www.keychron.com/products/keychron-v4-max-qmk-via-wireless-custom-mechanical-keyboard?variant=41285926682713&#34; target=&#34;_blank&#34; &gt;Keychron V4 Max(Barebone)&lt;/a&gt;を買った。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;with-keycaps.webp&#34; alt=&#34;with-keycaps&#34; loading=&#34;lazy&#34; /&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;ul&gt;
&lt;li&gt;ロープロファイルよりノーマルな方が好みなため&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;重量が軽め(600g前後)
&lt;ul&gt;
&lt;li&gt;Magi65は900gくらいあり若干重い(あと結構打鍵音がでかい)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;打鍵音が大きくなさそう(スイッチにも大きく依存するが)
&lt;ul&gt;
&lt;li&gt;オフィスでも使いたいので&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ホットスワップ対応&lt;/li&gt;
&lt;li&gt;おおよそ2万円以内&lt;/li&gt;
&lt;li&gt;60%&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;最初は候補として5つのキーボードが挙がっていたが、冷静になった結果NiZとREALFORCEは価格が高かったのでやめ、CIDOO QK61 V2は重量が重めだったのでこちらも候補から外した。&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;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;Keychron V4 Max&lt;/td&gt;
&lt;td&gt;650g&lt;/td&gt;
&lt;td&gt;対応&lt;/td&gt;
&lt;td&gt;$84.99&lt;/td&gt;
&lt;td&gt;対応&lt;/td&gt;
&lt;td&gt;ガスケットマウントで打鍵感&amp;amp;打鍵音がよさそう&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;EPOMAKER Hack59&lt;/td&gt;
&lt;td&gt;630g&lt;/td&gt;
&lt;td&gt;対応&lt;/td&gt;
&lt;td&gt;¥10,700&lt;/td&gt;
&lt;td&gt;対応&lt;/td&gt;
&lt;td&gt;ガスケットマウントで打鍵感&amp;amp;打鍵音がよさそう&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NiZ Atom66&lt;/td&gt;
&lt;td&gt;?&lt;/td&gt;
&lt;td&gt;おそらく非対応&lt;/td&gt;
&lt;td&gt;¥32,000&lt;/td&gt;
&lt;td&gt;?&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;REALFORCE RC1&lt;/td&gt;
&lt;td&gt;600g&lt;/td&gt;
&lt;td&gt;おそらく非対応&lt;/td&gt;
&lt;td&gt;¥35,860&lt;/td&gt;
&lt;td&gt;調べてないがさすがに対応してそう&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CIDOO QK61 V2&lt;/td&gt;
&lt;td&gt;880g&lt;/td&gt;
&lt;td&gt;おそらく対応&lt;/td&gt;
&lt;td&gt;¥11,000&lt;/td&gt;
&lt;td&gt;?&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;最終的にはKeychron V4 MaxとEPOMAKER Hack59で迷ったが打鍵音がより静かそうなKeychron V4 Maxを選んだ。&lt;/p&gt;
&lt;h2 id=&#34;keychron-v4-max&#34;&gt;Keychron V4 Max&lt;/h2&gt;
&lt;p&gt;KeychronのWebサイトを見ると2つのオプションがあった。&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;Barebone&lt;/td&gt;
&lt;td&gt;$84.99&lt;/td&gt;
&lt;td&gt;キーボード本体のみ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fully Assembled&lt;/td&gt;
&lt;td&gt;$104.99&lt;/td&gt;
&lt;td&gt;キーボード本体 + キーキャップ + キースイッチ&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;+$20でキーキャップとキースイッチがつくのでコスパでいえばFully Assembledの方がいいが、ちょうど家にキーキャップとキースイッチが1セットずつ余っていたのでBareboneにした。&lt;/p&gt;
&lt;p&gt;価格は送料込みで$92.99(¥14,093)だった。注文から5日後に届いた。（意外と早かった）&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;box.webp&#34; alt=&#34;box&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;ベアボーンな様子。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;barebone.webp&#34; alt=&#34;barebone&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;キースイッチキーキャップ&#34;&gt;キースイッチ、キーキャップ&lt;/h2&gt;
&lt;p&gt;キースイッチはもともと使っていたKailh Box Silent Pinkを装着した。（今は廃盤らしい&amp;hellip;）&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;with-switches.webp&#34; alt=&#34;with-switches&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;普段7sProに装着して使っている&lt;a href=&#34;https://shop.yushakobo.jp/products/5659&#34; target=&#34;_blank&#34; &gt;Yushakobo Fairy Silent Linear Switch&lt;/a&gt;より若干重くて押してる感じが適度にあってよい。&lt;/p&gt;
&lt;p&gt;キーキャップは家にあった&lt;a href=&#34;https://sanyollc.com/products/%E4%BA%88%E7%B4%84%E8%B2%A9%E5%A3%B2-the-old-seaside-abs-cherry-profile-keycaps&#34; target=&#34;_blank&#34; &gt;Keyreative The Old Seaside ABS Cherry Profile&lt;/a&gt;を装着した。
&lt;img src=&#34;with-keycaps.webp&#34; alt=&#34;with-keycaps&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;なぜか光る。
&lt;img src=&#34;gaaaaaaming.webp&#34; alt=&#34;gaaaaaaming&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;使ってみた感想&#34;&gt;使ってみた感想&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ガスケットマウントのおかげか打鍵感もよいし音もうるさくないので大満足。&lt;/li&gt;
&lt;li&gt;普段HHKB配列の分割キーボード&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;を使っているので右シフトがデカくてfnキーがないのは気になっていた。が、自分の使い方だと右シフトは&lt;code&gt;?&lt;/code&gt;を入力するときにたまに使っていたくらいだったので、思い切って右シフトをfnキーにすることで事なきを得た。&lt;/li&gt;
&lt;li&gt;軽いが使っていて位置がずれたりすることもなく、よい。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;あとちゃんと技適申請が通っていて、かつ技適マークも表示されていて嬉しい。
&lt;img src=&#34;giteki.webp&#34; alt=&#34;giteki&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;おわりに&#34;&gt;おわりに&lt;/h2&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://shop.yushakobo.jp/products/7spro&#34; target=&#34;_blank&#34; &gt;7sPro&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>
    
    <item>
      <title>関数型まつり2025に参加した</title>
      <link>https://blog.kyu08.com/posts/fp-matsuri-2025/</link>
      <pubDate>Sun, 15 Jun 2025 05:00:00 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/posts/fp-matsuri-2025/</guid>
      <description>2025/06/14(土)、2025/06/15(日)に中野セントラルパークで行われた関数型まつり2025に参加した。 筆者はElmやRust</description>
      <content>&lt;p&gt;2025/06/14(土)、2025/06/15(日)に中野セントラルパークで行われた関数型まつり2025に参加した。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;nakano-central-park.webp&#34; alt=&#34;nakano-central-park&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;pop.webp&#34; alt=&#34;pop&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;筆者はElmやRustの開発体験を気に入っており、Webアプリケーションのサーバーサイドを関数型言語で書くことに興味があったので参加してみた。&lt;/p&gt;
&lt;h2 id=&#34;関数型言語テイスティング-haskell-scala-clojure-elixirを比べて味わう関数型プログラミングの旨さ---lagénorhynqueカマイルカさん&#34;&gt;関数型言語テイスティング: Haskell, Scala, Clojure, Elixirを比べて味わう関数型プログラミングの旨さ - lagénorhynque/カマイルカさん&lt;/h2&gt;
&lt;p&gt;lagénorhynque/カマイルカさんによるHaskell, Scala, Clojure, Elixirの紹介と比較を行う発表。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;embed-container docswell&#34;&gt;
      &lt;div class=&#34;docswell-placeholder&#34; data-src=&#34;https://www.docswell.com/s/lagenorhynque/Z6VX6E-functional-language-tasting-haskell-scala-clojure-elixir?slide=1&#34; style=&#34;width:100%;height:569px;background:#f0f0f0;display:flex;align-items:center;justify-content:center;color:#666;&#34;&gt;Loading...&lt;/div&gt;
    &lt;/div&gt;&lt;/p&gt;
&lt;p&gt;部分適用や関数合成やパイプ演算子などElmで便利だった言語機能を思い出しながら聞いていた。&lt;/p&gt;
&lt;p&gt;文法を見ていると、Elmの文法はかなりHaskellに近いようだった。(ML系と呼ばれるらしい)&lt;/p&gt;
&lt;p&gt;あとは関数型かつ動的型付け言語の実際のアプリケーション開発での書き味が全然想像がつかないのでちょっとElixirやClojureを書いてみたくなった。質疑応答でも触れられていたが、実際にML系の言語とlispなどの動的型付け言語の関数型言語ではメンタルモデルが違うらしい。&lt;/p&gt;
&lt;p&gt;発表の最後に関数型プログラマのメンタルモデルとして以下のようなことを紹介されていて、自分が関数型言語から得た学びと重なる部分が多かった。&lt;/p&gt;
&lt;ul&gt;
&lt;li&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;/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;関数型言語を採用し維持し継続する---松澤-有さん&#34;&gt;関数型言語を採用し、維持し、継続する - 松澤 有さん&lt;/h2&gt;
&lt;p&gt;Siiibo証券株式会社のCTOである松澤さんによる自社プロダクトのフロントエンド、バックエンドの開発言語として関数型言語(Elm, Elixir)をなぜ採用したのか、そしていかにして維持し、継続しているかについての発表。実は主にこの発表を聞くために関数型まつりに参加したので良い発表を聞けてよかった。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://zenn.dev/siiibo_tech/articles/adopting-fp-languages&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://zenn.dev/siiibo_tech/articles/adopting-fp-languages&#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://res.cloudinary.com/zenn/image/upload/s--264zsvWh--/c_fit%2Cg_north_west%2Cl_text:notosansjp-medium.otf_55:%25E9%2596%25A2%25E6%2595%25B0%25E5%259E%258B%25E8%25A8%2580%25E8%25AA%259E%25E3%2582%2592%25E6%258E%25A1%25E7%2594%25A8%25E3%2581%2597%25E3%2580%2581%25E7%25B6%25AD%25E6%258C%2581%25E3%2581%2597%25E3%2580%2581%25E7%25B6%2599%25E7%25B6%259A%25E3%2581%2599%25E3%2582%258B%2Cw_1010%2Cx_90%2Cy_100/g_south_west%2Cl_text:notosansjp-medium.otf_34:Yu%2520Matsuzawa%2Cx_220%2Cy_108/bo_3px_solid_rgb:d6e3ed%2Cg_south_west%2Ch_90%2Cl_fetch:aHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL3plbm4tdXNlci11cGxvYWQvYXZhdGFyLzBmMzgxMmZkZWEuanBlZw==%2Cr_20%2Cw_90%2Cx_92%2Cy_102/co_rgb:6e7b85%2Cg_south_west%2Cl_text:notosansjp-medium.otf_30:Siiibo%25E3%2583%2586%25E3%2583%2583%25E3%2582%25AF%25E3%2583%2596%25E3%2583%25AD%25E3%2582%25B0%2Cx_220%2Cy_160/bo_4px_solid_white%2Cg_south_west%2Ch_50%2Cl_fetch:aHR0cHM6Ly9saDMuZ29vZ2xldXNlcmNvbnRlbnQuY29tL2EtL0FPaDE0R2dwd3pXbm9hSUl4bEVZcUtBSnRicVVheWljRmlJVExYVGZNN0EyPXMyNTAtYw==%2Cr_max%2Cw_50%2Cx_139%2Cy_84/v1627283836/default/og-base-w1200-v2.png?_a=BACAGSGT&#34; alt=&#34;関数型言語を採用し、維持し、継続する&#34; loading=&#34;lazy&#34;&gt;
    &lt;/div&gt;&lt;div class=&#34;blogcard-content&#34;&gt;
      &lt;div class=&#34;blogcard-title&#34;&gt;関数型言語を採用し、維持し、継続する&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://zenn.dev/siiibo_tech/articles/adopting-fp-languages&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;結局はラストマンシップを持って自分がなんとかするという気概が重要だという話が一番印象的だった。これは関数型言語を業務で書いているわけではない自分にも大いに参考になる話だと思っていて、結局どんな技術を採用したかやCTOかメンバーかなどにかかわらず、このラストマンシップを持っているエンジニアが多ければ多いほど開発組織は強固になるんだろうなと思った。&lt;/p&gt;
&lt;p&gt;また「アウトリーチを怠らなければ意外と世の中にちゃんと仲間はいる」ということをおっしゃっていて、使用言語がメインストリームであろうとなかろうと外部発信を通してコミュニティに貢献したり認知を獲得することの重要性を改めて感じた。やっていき。&lt;/p&gt;
&lt;p&gt;総じて松澤さんのエンジニアとしてのマインドセット的な部分がとても参考になった。&lt;/p&gt;
&lt;p&gt;技術的な内容に関しては、コードレビューの話とUpkeepの話が参考になった。&lt;/p&gt;
&lt;p&gt;コードレビューに関しては以下のようなことをおっしゃっていて、とても参考になった。特に2番目に関しては、前提としてコード品質を重要視するマインドがチームに装備されている必要があると思っていて、それをどう実現しているのか気になった。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;自分がいいと思う技術であっても、それを伝道できなければあとが続かない&lt;/li&gt;
&lt;li&gt;チームにとって良いコードとはどのようなものか、ということを感覚、信念として共有できる状態に持っていくことを目指している&lt;/li&gt;
&lt;li&gt;人は忘れるし、一度言っただけで身につくことは誰であれないので繰り返し伝えていくことが重要&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Upkeepとは維持費の意味で、ここでは依存ライブラリや言語自体のバージョンアップなどのことを指す。こまめにバージョンアップ作業をやっておくことでいざというときに言語やライブラリの新機能をすぐ取り込めたり、巨大なバージョンアップのせいでデグレするリスクを低減できたりと良いこと尽くめだと改めて感じた。（もちろん簡単ではないが）&lt;/p&gt;
&lt;p&gt;あとはバージョンを最新に保つという行為に名前をつけたことがなかったのでUpkeepという語で表現するのはいいなーと思った。&lt;/p&gt;
&lt;p&gt;以下発表を聞きながら取ったメモ。(発表を聞きつつスライドを見ながら書いたメモなので誤りが含まれる場合があります🙇)&lt;/p&gt;
&lt;h3 id=&#34;技術選定の方針&#34;&gt;技術選定の方針&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;CTO, Founding Engineerが技術構成を選ぶにあたっての観点
&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;（上記2点を説得材料として）カネを集められるか&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;ElixirやElmはメインストリームと目されているとは言えず、モノ・ヒト・カネの要素を自信を持って揃えるには弱い&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;/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;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;&lt;strong&gt;一度言っただけで身につくことは誰であれ、ない&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;upkeep&#34;&gt;Upkeep&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Upkeepとは維持費の意味で、ここでは依存ライブラリや言語自体のバージョンアップなどのことを指す。&lt;/li&gt;
&lt;li&gt;Upkeep恐怖症にならずにこまめにやれる環境をつくる。&lt;/li&gt;
&lt;li&gt;(バージョンアップ作業がやりやすいのは言語の大きな加点項目)&lt;/li&gt;
&lt;li&gt;Elixirで静的型検査の導入が2022年に発表された
&lt;ul&gt;
&lt;li&gt;Upkeepしておくと、こういった新機能もすぐに取り込める&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;言語公式フォーラム, ML, Slack, Discordのウォッチ
&lt;ul&gt;
&lt;li&gt;そもそもコミュニティがデカすぎないので最新動向をすべて追うのがそこまで大変ではない&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;コンパイラ、主要ライブラリのissue trackerも購読する
&lt;ul&gt;
&lt;li&gt;チーム内で抱えてる課題と似たような話題も出たりする&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Twitter&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;小さいコミュニティなので自分が第一人者、Front Runnerである可能性もある&lt;/li&gt;
&lt;/ul&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;/ul&gt;
&lt;h3 id=&#34;続けていく気概&#34;&gt;続けていく気概&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;結局大事なのは言いだしっぺがケツを持つ気概があるかどうか&lt;/li&gt;
&lt;li&gt;アウトリーチを怠らなければ意外と世の中にちゃんと仲間はいる&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;産業機械をelixirで制御する---菊池-豊さん&#34;&gt;産業機械をElixirで制御する - 菊池 豊さん&lt;/h2&gt;
&lt;p&gt;菊池 豊さんによる複数の水力発電の制御ソフトウェアをElixirで書いた経験を紹介する発表。&lt;/p&gt;
&lt;p&gt;Elixirは書きやすく、コミュニティも盛り上がっているという話を聞いてちょっと書いてみたくなった。&lt;/p&gt;
&lt;p&gt;以下メモ。&lt;/p&gt;
&lt;h3 id=&#34;課題&#34;&gt;課題&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Python
&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, Rust, Haskell, Erlang, Elm
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://qiita.com/kikuyuta/items/96c3f91a850e9274b0e9&#34; target=&#34;_blank&#34; &gt;Elixir を使うようになった経緯 〜電力システム制御の現場から〜&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;why-elixir&#34;&gt;Why Elixir&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;並行性
&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;
&lt;/ul&gt;
&lt;h3 id=&#34;elixirにないもの&#34;&gt;Elixirにないもの&lt;/h3&gt;
&lt;ul&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;lean言語は新世代の純粋関数型言語になれるか---井上亜星さん&#34;&gt;Lean言語は新世代の純粋関数型言語になれるか？ - 井上亜星さん&lt;/h2&gt;
&lt;p&gt;井上亜星さんによるLean言語の紹介の発表。&lt;/p&gt;
&lt;p&gt;この発表でLean言語という言語の存在を知った。純粋関数型言語でありながらforループやwhileループを書けるのはユニークだなーと思った。&lt;/p&gt;
&lt;h2 id=&#34;what-i-have-learned-from-15-years-of-functional-programming---scott-wlaschinさん&#34;&gt;What I have learned from 15 years of functional programming - Scott Wlaschinさん&lt;/h2&gt;
&lt;p&gt;Scott Wlaschinさんによる関数型プログラミングでの学びを共有する発表。&lt;/p&gt;
&lt;p&gt;「直和型とレコード型を駆使しドメインモデリングを正確に表現することで保守性が向上するだけでなく動作可能なドキュメントとしても機能する」という話が印象に残った。&lt;/p&gt;
&lt;p&gt;前者のメリットは以前から感じていたが、後者の観点はなかったので面白かった。（言われてみればそれはそうという感じだが）&lt;/p&gt;
&lt;p&gt;以下メモ。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;パイプライン指向で書くことで保守性の高いコードを書くことができる
&lt;ul&gt;
&lt;li&gt;以前はSOLID原則を満たすことを意識しすぎてしまいうまくいかなかったが、パイプライン的な志向でコードを書くことで自然と綺麗なコードを書くことができ、SOLID原則も自然と満たすことができるようになったとのこと&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&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;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Railway Oriented Programmingを使うことでエラー処理を伴う処理を保守性高く書くことができる&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;/ul&gt;
&lt;h2 id=&#34;fの設計と妥協点---net上で実現する関数型パラダイム---猪股-健太郎さん&#34;&gt;F#の設計と妥協点 - .NET上で実現する関数型パラダイム - 猪股 健太郎さん&lt;/h2&gt;
&lt;p&gt;猪股 健太郎さんによるF#の言語設計の特徴、設計意図を紹介する発表。&lt;/p&gt;
&lt;p&gt;純粋関数型言語なのかと思っていたが、命令形っぽい書き方もできることは知らなかった。他の.NET言語との相互運用性があるのも便利そう。&lt;/p&gt;
&lt;p&gt;以下メモ。&lt;/p&gt;
&lt;h3 id=&#34;概要&#34;&gt;概要&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;OCamlに大きな影響を受けている&lt;/li&gt;
&lt;li&gt;金融工学、データサイエンス、科学計算、Webアプリなどで活用されている&lt;/li&gt;
&lt;li&gt;F#をJavaScriptにトランスパイルするコンパイラもあり、フロントエンドも書ける&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;fの特徴&#34;&gt;F#の特徴&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;静的型付けの非純粋関数型言語である。
&lt;ul&gt;
&lt;li&gt;デフォルトはイミュータブルだがmutableにもできる&lt;/li&gt;
&lt;li&gt;.NETランタイムは仮想マシン型
&lt;ul&gt;
&lt;li&gt;C#, F#など複数言語を.NETランタイム上で動かす前提で設計されており共通中間言語、共通型システム、共通言語仕様を備える&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ホスト環境との相互運用性
&lt;ul&gt;
&lt;li&gt;F#で書かれたコードは他の.NET言語から自然かつ安全に利用可能&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;/ul&gt;
&lt;h3 id=&#34;言語設計の意図&#34;&gt;言語設計の意図&lt;/h3&gt;
&lt;p&gt;プログラマーが命令的なコーディングから関数型のコーディングへ移行する際のハードルを下げることを意識した設計になっているらしい。&lt;/p&gt;
&lt;h2 id=&#34;マイクロサービス内で動くapiをfで書いている---ayato-pさん&#34;&gt;マイクロサービス内で動くAPIをF#で書いている - ayato-pさん&lt;/h2&gt;
&lt;p&gt;ayato-pさんによるマイクロサービスの1サービスをF#で書く際の設計や悩みどころを紹介する発表。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;embed-container speakerdeck&#34;&gt;
        &lt;iframe src=&#34;https://speakerdeck.com/player/9efe648f23514385a48f5c5608d5f1c3&#34; allowfullscreen=&#34;true&#34; mozallowfullscreen=&#34;true&#34; webkitallowfullscreen=&#34;true&#34;&gt;&lt;/iframe&gt;
      &lt;/div&gt;&lt;/p&gt;
&lt;p&gt;ドメイン設計の際に容易にOptionを使わずにenumの別のvariantとして表現する、という考え方はRustなどでも活かせそうだと思った。別の概念であれば別の型として表現するのが大事そう。&lt;/p&gt;
&lt;p&gt;以下メモ。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;どんなチームで採用したのか
&lt;ul&gt;
&lt;li&gt;ペアプログラミングを中心に100人超の組織で開発している&lt;/li&gt;
&lt;li&gt;モノリス -&amp;gt; マイクロサービスの移行をやっている&lt;/li&gt;
&lt;li&gt;マイクロサービスの各APIは多種多様な言語で書かれている&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;F#導入以前のプロダクトチーム
&lt;ul&gt;
&lt;li&gt;JVM系、Elixir, Go, Rust, OCaml, Haskellなども採用&lt;/li&gt;
&lt;li&gt;.NET系の言語は採用されていなかった&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;どう導入したのか
&lt;ul&gt;
&lt;li&gt;システムのコアにいきなり採用するのはリスキーだったのでなにかあってもまずは影響が少ないサブシステムで採用&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;なぜF#か
&lt;ul&gt;
&lt;li&gt;静的型付け&lt;/li&gt;
&lt;li&gt;シンタックスが簡素&lt;/li&gt;
&lt;li&gt;.NETの資産を活用できる&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;F#らしさを活かした設計
&lt;ul&gt;
&lt;li&gt;Optionなどを入れずに判別共用体を使って設計する&lt;/li&gt;
&lt;li&gt;e.g. 上場企業と非上場企業を表現するときに&lt;code&gt;isListed: bool&lt;/code&gt;, &lt;code&gt;listedAt: Option&amp;lt;DateTime&amp;gt;&lt;/code&gt;のように表現するのではなく&amp;hellip;
&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-fsharp&#34; data-lang=&#34;fsharp&#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;Company&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; id&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; CompanyId
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    name&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;    isListed&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;bool&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    listedAt&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; Option&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;DateTime&lt;span style=&#34;color:#f92672&#34;&gt;&amp;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;そもそも別のvariantとして表現する
&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-fsharp&#34; data-lang=&#34;fsharp&#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;Listed&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; Listed &lt;span style=&#34;color:#66d9ef&#34;&gt;of&lt;/span&gt; listedAt&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; DateTime
&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;type&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;CompanyProfile&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; id&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; CompanyId
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    name&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 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:#f92672&#34;&gt;[&amp;lt;&lt;/span&gt;RequireQualifiedAccess&lt;span style=&#34;color:#f92672&#34;&gt;&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:#66d9ef&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Company&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; Listed &lt;span style=&#34;color:#66d9ef&#34;&gt;of&lt;/span&gt; CompanyProfile &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; Listed
&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; UnListed &lt;span style=&#34;color:#66d9ef&#34;&gt;of&lt;/span&gt; CompanyProfile
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;スポンサーブース&#34;&gt;スポンサーブース&lt;/h2&gt;
&lt;p&gt;Jane Streetのエンジニアの方にお聞きしたがJane StreetではフロントエンドとサーバーサイドをOCamlで書いているらしい（！）ブースでお話した方も関数型言語が書きたくて入社したそうで、関数型言語への愛を感じた。&lt;/p&gt;
&lt;p&gt;ブースでいただいたノベルティのTシャツもめっちゃOCamlだった。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;jane-street.webp&#34; alt=&#34;jane-street&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;ノベルティ&#34;&gt;ノベルティ&lt;/h2&gt;
&lt;p&gt;入場時にロゴ入りのトートバッグがもらえた。
&lt;img src=&#34;bag.webp&#34; alt=&#34;bag&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;Nulabさんのノベルティのマイクロファイバークロス。実用的でありがたい。
&lt;img src=&#34;nulab.webp&#34; alt=&#34;nulab&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;まとめ&#34;&gt;まとめ&lt;/h2&gt;
&lt;p&gt;今は業務で関数型言語を使うことはないが、関数型言語の考え方を取り入れることで非関数型言語でもより良いコードを書けるようになると改めて感じた。&lt;/p&gt;
&lt;p&gt;個人で初めてオフラインの勉強会/カンファレンスに参加したが普通に楽しかったのでまた行ってみようと思う。&lt;/p&gt;
&lt;h2 id=&#34;つけ麺情報&#34;&gt;つけ麺情報&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://tabelog.com/tokyo/A1319/A131902/13115487&#34; target=&#34;_blank&#34; &gt;二代目えん寺&lt;/a&gt;がとても美味しかった。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;tsukemen.webp&#34; alt=&#34;tsukemen&#34; loading=&#34;lazy&#34; /&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://sporto.github.io/elm-patterns/advanced/railway.html&#34; target=&#34;_blank&#34; &gt;Elm Patternsでも紹介されていた&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>
    
    <item>
      <title>cargoプロジェクトで依存関係を継続的に管理する</title>
      <link>https://blog.kyu08.com/posts/manage-cargo-dependencies/</link>
      <pubDate>Tue, 20 May 2025 15:00:00 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/posts/manage-cargo-dependencies/</guid>
      <description>OSSに依存するプロジェクトでは依存しているライブラリのライセンス表記が必要になることがある。（体感的にはほとんどのライブラリはライセンス表</description>
      <content>&lt;p&gt;OSSに依存するプロジェクトでは依存しているライブラリのライセンス表記が必要になることがある。（体感的にはほとんどのライブラリはライセンス表記を求めているように思う）&lt;/p&gt;
&lt;p&gt;そのため、依存ライブラリが増えた場合にはライセンス表記を更新する必要があるが、依存ライブラリの依存ライブラリに対しても再帰的にライセンス表記を見に行って自リポジトリの依存ライセンス表記ファイルを更新して&amp;hellip;という作業を行うのは現実的ではない。&lt;/p&gt;
&lt;p&gt;他にもうっかりコピーレフトなライブラリに依存してしまうとプロジェクトのライセンスを変更しなければならなかったりと案外注意すべきポイントが多い。&lt;/p&gt;
&lt;p&gt;cargoプロジェクトにおいてこれらの労力を削減してくれるツールがいくつか存在している。&lt;/p&gt;
&lt;p&gt;筆者は趣味プロジェクトとして&lt;code&gt;fzf-make&lt;/code&gt;というmake targetやpnpm script, yarn script, just recipeをfuzzy finder形式で選択、実行できるCLIツール&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;をRustで開発しており、このプロジェクトで最近それらのツールを導入したので使い方とともに紹介する。&lt;/p&gt;
&lt;h2 id=&#34;tldr&#34;&gt;tl;dr&lt;/h2&gt;
&lt;p&gt;以下のチェックをCIで実行することでcargoプロジェクトの依存関係を継続的に省力で管理できる。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/bnjbvr/cargo-machete&#34; target=&#34;_blank&#34; &gt;&lt;code&gt;cargo-machete&lt;/code&gt;&lt;/a&gt;: 不要な依存関係がないか&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/EmbarkStudios/cargo-deny&#34; target=&#34;_blank&#34; &gt;&lt;code&gt;cargo-deny&lt;/code&gt;&lt;/a&gt;: 依存ライブラリに許容しないライセンスが含まれていないか&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/EmbarkStudios/cargo-about&#34; target=&#34;_blank&#34; &gt;&lt;code&gt;cargo-about&lt;/code&gt;&lt;/a&gt;: リポジトリのライセンス表記ファイルに更新漏れがないか&lt;/li&gt;
&lt;/ul&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;ローカル&lt;/td&gt;
&lt;td&gt;make&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CI&lt;/td&gt;
&lt;td&gt;GitHub Actions&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;cargo-macheteで不要な依存関係を検出する&#34;&gt;&lt;code&gt;cargo-machete&lt;/code&gt;で不要な依存関係を検出する&lt;/h2&gt;
&lt;h3 id=&#34;why&#34;&gt;why&lt;/h3&gt;
&lt;p&gt;ある程度の期間開発を続けていると以前追加した依存関係が不要になったことに気付かずに&lt;code&gt;cargo.toml&lt;/code&gt;の&lt;code&gt;dependencies&lt;/code&gt;や&lt;code&gt;dev-dependencies&lt;/code&gt;に残ったままになることがある。
不要な依存関係が残ったままになっているとrenovateやdependabotによるバージョン更新の手間が不必要に増えてしまうのでPRの時点で気付けるようにしたい。&lt;/p&gt;
&lt;h3 id=&#34;what&#34;&gt;what&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/bnjbvr/cargo-machete&#34; target=&#34;_blank&#34; &gt;cargo-machete&lt;/a&gt;を使って&lt;code&gt;cargo.toml&lt;/code&gt;に記述されている依存関係のうち、プロジェクトが実際には依存していない依存関係を検出する。&lt;/p&gt;
&lt;h3 id=&#34;howローカル&#34;&gt;how(ローカル)&lt;/h3&gt;
&lt;p&gt;以下のようなmake targetを定義しておくと&lt;code&gt;make detect-unused-dependencies&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-makefile&#34; data-lang=&#34;makefile&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;.PHONY&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; tool-detect-unused-dependencies
&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;tool-detect-unused-dependencies&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;	@if ! which cargo-machete &amp;gt; /dev/null; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#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:#ae81ff&#34;&gt;&lt;/span&gt;		cargo install --locked cargo-machete; &lt;span style=&#34;color:#ae81ff&#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:#ae81ff&#34;&gt;&lt;/span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;fi&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;.PHONY&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; detect-unused-dependencies
&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;detect-unused-dependencies&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; tool-detect-unused-dependencies
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	cargo machete
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;以下は不必要な依存関係として&lt;code&gt;tempfile&lt;/code&gt;が検出されている様子。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;cargo-machete.webp&#34; alt=&#34;cargo-machete&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;howci&#34;&gt;how(CI)&lt;/h3&gt;
&lt;p&gt;以下のようなyamlを定義しておくと不要な依存関係がある場合にCIが落ちてくれる。&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-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;name&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;Detect unused dependencies&lt;/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;on&lt;/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;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:#f92672&#34;&gt;branches&lt;/span&gt;: [ &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;main&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:#f92672&#34;&gt;pull_request&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;jobs&lt;/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;detect-unused-dependencies&lt;/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;runs-on&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;ubuntu-latest&lt;/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;steps&lt;/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;name&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;Checkout&lt;/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;uses&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;actions/checkout@v4&lt;/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;name&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;Machete&lt;/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;uses&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;bnjbvr/cargo-machete@v0.8.0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;cargo-denyで依存ライブラリに許容しないライセンスが含まれていないか検証する&#34;&gt;&lt;code&gt;cargo-deny&lt;/code&gt;で依存ライブラリに許容しないライセンスが含まれていないか検証する&lt;/h2&gt;
&lt;h3 id=&#34;why-1&#34;&gt;why&lt;/h3&gt;
&lt;p&gt;筆者は&lt;code&gt;fzf-make&lt;/code&gt;をより自由に利用してほしいと考えているためMITライセンスでプロジェクトを公開したい。
コピーレフトのライセンスに依存してしまうとライセンス変更を余儀なくされるため、コピーレフトのライブラリに依存することを避けたい。&lt;/p&gt;
&lt;h3 id=&#34;what-1&#34;&gt;what&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/EmbarkStudios/cargo-deny&#34; target=&#34;_blank&#34; &gt;cargo-deny&lt;/a&gt;は依存関係のlint機能を提供する。&lt;code&gt;fzf-make&lt;/code&gt;では、&lt;code&gt;cargo deny check licenses&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-toml&#34; data-lang=&#34;toml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# deny.toml&lt;/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;licenses&lt;/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;allow&lt;/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;MIT&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;ISC&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;Apache-2.0&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;MPL-2.0&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;BSD-2-Clause&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;BSD-3-Clause&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;Unicode-DFS-2016&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;OpenSSL&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;confidence-threshold&lt;/span&gt; = &lt;span style=&#34;color:#ae81ff&#34;&gt;0.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;exceptions&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;licenses&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;clarify&lt;/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;name&lt;/span&gt; = &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;ring&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;expression&lt;/span&gt; = &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;MIT AND ISC AND OpenSSL&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;license-files&lt;/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;path&lt;/span&gt; = &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;LICENSE&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;hash&lt;/span&gt; = &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;xbd0eed23&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;h3 id=&#34;howローカル-1&#34;&gt;how(ローカル)&lt;/h3&gt;
&lt;p&gt;以下のようなmake targetを定義しておくと&lt;code&gt;make check-licenses&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-makefile&#34; data-lang=&#34;makefile&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;.PHONY&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; tool-check-licenses
&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;tool-check-licenses&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;	@if ! which cargo-deny &amp;gt; /dev/null; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#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:#ae81ff&#34;&gt;&lt;/span&gt;		cargo install --locked cargo-deny; &lt;span style=&#34;color:#ae81ff&#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:#ae81ff&#34;&gt;&lt;/span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;fi&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;.PHONY&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; check-licenses
&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;check-licenses&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; tool-check-licenses
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	cargo deny check licenses
&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;img src=&#34;cargo-deny.webp&#34; alt=&#34;cargo-deny.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;howci-1&#34;&gt;how(CI)&lt;/h3&gt;
&lt;p&gt;以下のようなyamlを定義しておくと不要な依存関係があるとCIが落ちてくれる。&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-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;name&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;Check licenses&lt;/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;on&lt;/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;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:#f92672&#34;&gt;branches&lt;/span&gt;: [ &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;main&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:#f92672&#34;&gt;pull_request&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;jobs&lt;/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;check-licenses&lt;/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;runs-on&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;ubuntu-latest&lt;/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;steps&lt;/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;uses&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;actions/checkout@v4&lt;/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;uses&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;EmbarkStudios/cargo-deny-action@v2&lt;/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;with&lt;/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;command&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;check licenses&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;cargo-aboutでリポジトリのライセンス表記が最新か検証する&#34;&gt;&lt;code&gt;cargo-about&lt;/code&gt;でリポジトリのライセンス表記が最新か検証する&lt;/h2&gt;
&lt;h3 id=&#34;why-2&#34;&gt;why&lt;/h3&gt;
&lt;p&gt;冒頭でも触れた通り、多くのOSSでは依存ライブラリのライセンス表記を求めている。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;fzf-make&lt;/code&gt;では&lt;code&gt;CREDITS.html&lt;/code&gt;というファイルを用意しておりそこに依存ライブラリのライセンス表記を記載している。&lt;/p&gt;
&lt;p&gt;これまでは依存ライブラリを追加/削除した際に手作業でライセンス表記ファイルを更新していたが、漏れがちになっていた。&lt;/p&gt;
&lt;p&gt;また、本来は依存ライブラリの依存ライブラリを再帰的にチェックしてすべてのライセンス表記をすべきなのだと思うが、手作業でそれをする気にはなれなかったので直接依存しているライブラリのライセンスしか表記できていなかった。&lt;/p&gt;
&lt;p&gt;これらの課題を&lt;code&gt;cargo-about&lt;/code&gt;を用いることで解決できそうだったので導入してみた。&lt;/p&gt;
&lt;h3 id=&#34;what-2&#34;&gt;what&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/EmbarkStudios/cargo-about&#34; target=&#34;_blank&#34; &gt;cargo-about&lt;/a&gt;は依存ライブラリのライセンス表記ファイルを自動生成する機能を提供する。&lt;/p&gt;
&lt;p&gt;以下のようなテンプレートを用意し、&lt;code&gt;cargo about generate about.hbs &amp;gt; CREDITS.html&lt;/code&gt;を実行すると&lt;code&gt;CREDITS.html&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-html&#34; data-lang=&#34;html&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;html&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;head&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;style&lt;/span&gt;&amp;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;media&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;prefers-color-scheme&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;dark&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;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:#66d9ef&#34;&gt;background&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;#333&lt;/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;color&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;white&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;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:#66d9ef&#34;&gt;color&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;skyblue&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;container&lt;/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;font-family&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;sans-serif&lt;/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;max-width&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;800&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;px&lt;/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;margin&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;auto&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;intro&lt;/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;text-align&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;center&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;licenses-list&lt;/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;list-style-type&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;none&lt;/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;margin&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:#66d9ef&#34;&gt;padding&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:#a6e22e&#34;&gt;license-used-by&lt;/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;margin-top&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;-10&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;px&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;license-text&lt;/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;max-height&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;200&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;px&lt;/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;overflow-y&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;scroll&lt;/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;white-space&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;pre-wrap&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;        &amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;style&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;head&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;body&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;main&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;container&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;div&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;intro&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;h1&lt;/span&gt;&amp;gt;Third Party Licenses&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;h1&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;p&lt;/span&gt;&amp;gt;This page lists the licenses of the projects used in fzf-make.&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;p&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;div&lt;/span&gt;&amp;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;            &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;h2&lt;/span&gt;&amp;gt;Overview of licenses:&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;h2&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;ul&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;licenses-overview&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                {{#each overview}}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;li&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;a&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;href&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;#{{id}}&amp;#34;&lt;/span&gt;&amp;gt;{{name}}&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;a&lt;/span&gt;&amp;gt; ({{count}})&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;li&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                {{/each}}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;ul&lt;/span&gt;&amp;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;            &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;h2&lt;/span&gt;&amp;gt;All license text:&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;h2&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;ul&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;licenses-list&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                {{#each licenses}}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;li&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;license&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;h3&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;id&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;{{id}}&amp;#34;&lt;/span&gt;&amp;gt;{{name}}&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;h3&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;h4&lt;/span&gt;&amp;gt;Used by:&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;h4&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;ul&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;license-used-by&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        {{#each used_by}}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;li&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;a&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;href&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;{{#if crate.repository}} {{crate.repository}} {{else}} https://crates.io/crates/{{crate.name}} {{/if}}&amp;#34;&lt;/span&gt;&amp;gt;{{crate.name}} {{crate.version}}&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;a&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;li&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        {{/each}}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;ul&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;pre&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;license-text&amp;#34;&lt;/span&gt;&amp;gt;{{text}}&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;pre&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;li&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                {{/each}}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;ul&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;main&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;body&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;html&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;howローカル-2&#34;&gt;how(ローカル)&lt;/h3&gt;
&lt;p&gt;以下のようなmake targetを定義しておくと&lt;code&gt;make update-license-file&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-makefile&#34; data-lang=&#34;makefile&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;.PHONY&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; tool-update-license-file
&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;tool-update-license-file&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;	@if ! which cargo-about &amp;gt; /dev/null; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#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:#ae81ff&#34;&gt;&lt;/span&gt;		cargo install --locked cargo-about; &lt;span style=&#34;color:#ae81ff&#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:#ae81ff&#34;&gt;&lt;/span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;fi&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;.PHONY&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; update-license-file
&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;update-license-file&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; tool-update-license-file
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	cargo about generate about.hbs &amp;gt; CREDITS.html
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;howci-2&#34;&gt;how(CI)&lt;/h3&gt;
&lt;p&gt;以下のようなyamlを定義しておくと依存ライブラリのライセンス表記が最新でないとCIが落ちてくれる。&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-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;name&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;Check license file&lt;/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;on&lt;/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;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:#f92672&#34;&gt;branches&lt;/span&gt;: [ &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;main&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:#f92672&#34;&gt;pull_request&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;jobs&lt;/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;check-license-file&lt;/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;runs-on&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;ubuntu-latest&lt;/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;steps&lt;/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;name&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;Checkout&lt;/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;uses&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;actions/checkout@v4&lt;/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;name&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;Check&lt;/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;run&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;make update-license-file&lt;/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;name&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;Check diff&lt;/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;run&lt;/span&gt;: |&lt;span style=&#34;color:#e6db74&#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:#e6db74&#34;&gt;          git 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:#e6db74&#34;&gt;          git diff --cached --exit-code&lt;/span&gt;          
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;なお、デフォルトだと以下の部分の&lt;code&gt;This page...fzf-make&lt;/code&gt;の部分が&lt;code&gt;This page lists the licenses of the projects used in cargo-about.&lt;/code&gt;として出力される。そのため、そのまま利用すると「&lt;code&gt;cargo-about&lt;/code&gt;プロジェクトでは以下のライセンスに依存しています」という意味の表示になってしまうためユーザーが忘れずに&lt;code&gt;cargo-about&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;/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-html&#34; data-lang=&#34;html&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;div&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;intro&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;h1&lt;/span&gt;&amp;gt;Third Party Licenses&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;h1&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;p&lt;/span&gt;&amp;gt;This page lists the licenses of the projects used in fzf-make.&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;p&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;div&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;これに関しては以下のissueを立ててみたので&lt;code&gt;cargo-about&lt;/code&gt;側と意見が一致したら修正するPRを送ってみようと思う。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/EmbarkStudios/cargo-about/issues/281&#34; target=&#34;_blank&#34; &gt;[Feature request] change &lt;code&gt;cargo about init&lt;/code&gt; to generate the statement including user&amp;rsquo;s project name.&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;おわりに&#34;&gt;おわりに&lt;/h2&gt;
&lt;p&gt;繰り返しの定型タスクをCIに任せることができたので開発により集中できるようになった。（趣味開発だと数ヶ月ぶりにコミットするとかもザラにあり、開発に必要なタスクを忘れがちなのでそういった意味でも自動化の範囲を増やすことができてよかった）&lt;/p&gt;
&lt;p&gt;便利ツールをOSSとして公開してくれている人/企業に感謝しつつ利用するだけでなく自分にできる貢献はやっていきたい。&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;code&gt;fzf-make&lt;/code&gt;の紹介記事: &lt;a href=&#34;https://zenn.dev/kyu08/articles/974fd8bc25c303&#34; target=&#34;_blank&#34; &gt;[make,pnpm,yarn,justに対応]コマンドをfuzzy finder形式で選択できるCLIツール fzf-makeの紹介&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;a href=&#34;https://github.com/search?q=%22This&amp;#43;page&amp;#43;lists&amp;#43;the&amp;#43;licenses&amp;#43;of&amp;#43;the&amp;#43;projects&amp;#43;used&amp;#43;in&amp;#43;cargo-about.%22&amp;amp;type=code&#34; target=&#34;_blank&#34; &gt;90件近くのプロジェクトで&lt;code&gt;cargo-about&lt;/code&gt;のままになっている。&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</content>
    </item>
    
    <item>
      <title>傾斜付きロープロファイルキーキャップNuPhy Oblivionを買った</title>
      <link>https://blog.kyu08.com/posts/oblivion-keycaps/</link>
      <pubDate>Wed, 30 Apr 2025 13:49:03 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/posts/oblivion-keycaps/</guid>
      <description>傾斜付きロープロファイルキーキャップであるNuPhy Oblivionを買った。 OblivionEmerges from the structured chaos of programming, where logic dances with creativity and every line of code tells a story. Inspired by the stark elegance of terminal interfaces and the rhythmic</description>
      <content>&lt;p&gt;&lt;img src=&#34;lets-unbox.webp&#34; alt=&#34;lets-unbox&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;傾斜付きロープロファイルキーキャップであるNuPhy Oblivionを買った。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://nuphy.com/collections/keycaps/products/oblivion&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://nuphy.com/collections/keycaps/products/oblivion&#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://nuphy.com/cdn/shop/files/Mechanical_keyboard_keycaps_on_a_gray_background_with_Oblivion_branding..jpg?v=1758089460&#34; alt=&#34;Oblivion&#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;Oblivion&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;Emerges from the structured chaos of programming, where logic dances with creativity and every line of code tells a story. Inspired by the stark elegance of terminal interfaces and the rhythmic flow of syntax highlighting, its deep gray foundation is illuminated by vibrant accents of green, blue, and orange—a palette that feels as timeless as the tools of a coder’s trade.&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://nuphy.com/collections/keycaps/products/oblivion&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;価格は送料込みで$53.98(8,000円)だった。注文から6日後に届いた。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.kyu08.com/posts/magi65&#34; &gt;IQUNIX Magi65を買った&lt;/a&gt;でも書いていた通りロープロファイルでも傾斜付きのキーキャップがないかな〜と思っていたところ突如としてOblivionのリリース情報がTwitterで流れてきたので買ってMagi65に装着してみた。&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;with-magi65.webp&#34; alt=&#34;with-magi65.web&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;良かった点&#34;&gt;良かった点&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;傾斜があって打ちやすい&lt;/li&gt;
&lt;li&gt;(NuPhy Halo65のキーキャップと比べて)打鍵音が少し静かになった&lt;/li&gt;
&lt;li&gt;ロープロファイル用なだけあって干渉せずに問題なく使える&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;手前の白いのがオリジナルのフラットなキーキャップ。
&lt;img src=&#34;original.webp&#34; alt=&#34;original.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;これが今回購入したoblivionのキーキャップ。Cherry Profileに近い形状で傾斜がついている。
&lt;img src=&#34;oblivion.webp&#34; alt=&#34;oblivion.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;気になった点&#34;&gt;気になった点&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ホーミングキーの凹凸(よくFキーとJキーについてるアレです)が結構低いので若干わかりづらい。が、慣れればそんなに問題なさそう&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&#34;homing-key.webp&#34; alt=&#34;homing-key.webp&#34; loading=&#34;lazy&#34; /&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;HHKBっぽく使いたい都合で普段使わないキーを間違って押さないようにあえてキーキャップを交換していない。&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>
    
    <item>
      <title>『コンピュータシステムの理論と実装 第2版』を読んだ</title>
      <link>https://blog.kyu08.com/posts/nand2tetris/</link>
      <pubDate>Tue, 29 Apr 2025 15:00:00 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/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>IQUNIX Magi65を買った</title>
      <link>https://blog.kyu08.com/posts/magi65/</link>
      <pubDate>Sun, 06 Apr 2025 09:50:34 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/posts/magi65/</guid>
      <description>ある日YouTube Shortsで流れてきて打鍵感と打鍵音がよさそうで気になっていたIQUNIX Magi65を買ってみた。 画像は公式サイトよ</description>
      <content>&lt;p&gt;ある日YouTube Shortsで流れてきて打鍵感と打鍵音がよさそうで気になっていた&lt;a href=&#34;https://iqunix.com/products/magi65&#34; target=&#34;_blank&#34; &gt;IQUNIX Magi65&lt;/a&gt;を買ってみた。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;iqunix-magi65-official.webp&#34; alt=&#34;iqunix-magi65-official.webp&#34; loading=&#34;lazy&#34; /&gt;
画像は公式サイトより引用: &lt;a href=&#34;https://iqunix.com/products/magi65&#34; target=&#34;_blank&#34; &gt;Magi65 Aluminum Low Profile Mechanical Keyboard&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;価格は送料込みで$128(20,169円)だった。注文から14日後に届いた。中国から送られてきたので妥当そう。（？）&lt;/p&gt;
&lt;p&gt;Magi65はコトコト系の打鍵音 &amp;amp; いい感じの打鍵感なので普段使っている7sPro&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://www.youtube.com/watch?v=EClom7Y_hO0&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://www.youtube.com/watch?v=EClom7Y_hO0&#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;- YouTube&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;Enjoy the videos and music you love, upload original content, and share it all with friends, family, and the world on YouTube.&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://www.youtube.com/watch?v=EClom7Y_hO0&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;重さも900gと適度にあるので安定感がありつつも持ち運びもそこまで辛くない。&lt;/p&gt;
&lt;p&gt;ロープロファイルのキーボードには傾斜がないキーキャップが使われていることが多いがMagi65も例に漏れず傾斜のないタイプのキーキャップが採用されていた。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;flat-keycaps.webp&#34; alt=&#34;flat-keycaps&#34; loading=&#34;lazy&#34; /&gt;
画像は公式サイトより引用: &lt;a href=&#34;https://iqunix.com/products/magi65&#34; target=&#34;_blank&#34; &gt;Magi65 Aluminum Low Profile Mechanical Keyboard&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;傾斜があったほうが打ちやすい派なのでNuPhy Halo65のキーキャップが使えたらいいなーと思いおもむろに装着してみたところなぜか普通に使えてしまったのでそのまま使ってみている。（色味が合ってないのが若干アレではあるが打ちやすさには代えられないのでよしとした&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;magi65-with-nuphy-keycaps.webp&#34; alt=&#34;magi65-with-nuphy-keycaps&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;あと通常プロファイルのキーボードよりも高さがないので尊師スタイルでも使っても手が疲れにくいのも嬉しいポイント。&lt;/p&gt;
&lt;p&gt;[追記]その後&lt;a href=&#34;../oblivion-keycaps/&#34; &gt;傾斜付きロープロファイルキーキャップNuPhy Oblivionを買った&lt;/a&gt;ので記事を書いた。&lt;/p&gt;
&lt;p&gt;欲を言えばスペースキーが3つくらいに割れていて傾斜のあるキーキャップの選択肢が多いと嬉しい。（ハイパー高望み）&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://shop.yushakobo.jp/products/5659&#34; target=&#34;_blank&#34; &gt;Yushakobo Fairy Silent Linear Switch&lt;/a&gt;を使っている。Magi65と比べるとより静音で打鍵感も軽いので疲れなくてこれはこれで良い。&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;Cherry Profileのキーキャップも装着してみたがそちらは高さが合わなかったのか、R2の列のキーキャップの戻りが悪くなってしまい使えなかった&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>2024年を振り返る</title>
      <link>https://blog.kyu08.com/posts/looking-back-on-2024/</link>
      <pubDate>Sun, 29 Dec 2024 02:03:53 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/posts/looking-back-on-2024/</guid>
      <description>年の瀬なので今年を振り返る。 OSS PRでの貢献 49件のPRを作成1し43件のPRがマージされた。(4件がclosedで2件がopenのまま) 簡単</description>
      <content>&lt;p&gt;年の瀬なので今年を振り返る。&lt;/p&gt;
&lt;h2 id=&#34;oss&#34;&gt;OSS&lt;/h2&gt;
&lt;h3 id=&#34;prでの貢献&#34;&gt;PRでの貢献&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/pulls?q=is%3Apr&amp;#43;archived%3Afalse&amp;#43;is%3Aclosed&amp;#43;author%3Akyu08&amp;#43;is%3Apublic&amp;#43;-user%3Akyu08&amp;#43;created%3A2024-01-01..2024-12-31&amp;#43;&#34; target=&#34;_blank&#34; &gt;49件のPRを作成&lt;/a&gt;&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;し43件のPRがマージされた。(4件がclosedで2件がopenのまま)&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;ul&gt;
&lt;li&gt;バグ修正: 3件&lt;/li&gt;
&lt;li&gt;ドキュメントの修正: 11件&lt;/li&gt;
&lt;li&gt;lint系の修正: 4件&lt;/li&gt;
&lt;li&gt;typo修正: 9件&lt;/li&gt;
&lt;li&gt;機能追加: 7件&lt;/li&gt;
&lt;li&gt;CIのバージョンアップ: 5件&lt;/li&gt;
&lt;li&gt;自作TUIのbrew release関連: 3件&lt;/li&gt;
&lt;li&gt;その他: 1件&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;今年の抱負の1つとしてこう書いていたがこれは達成できたといってよさそう。嬉しい。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;OSS貢献を続ける。何らかのOSSのアプリケーションコードにも貢献する。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.kyu08.com/posts/looking-back-on-2023/#2024%E5%B9%B4%E3%81%AE%E6%8A%B1%E8%B2%A0&#34; target=&#34;_blank&#34; &gt;https://blog.kyu08.com/posts/looking-back-on-2023/#2024%E5%B9%B4%E3%81%AE%E6%8A%B1%E8%B2%A0&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;基本的には仕事中や趣味開発中にバグを見つけたり、追加したほうがよさそうな機能を思いついたり、ドキュメントの誤りに気付いたタイミングでPRを送っていた。&lt;/p&gt;
&lt;p&gt;振り返るとOSS貢献を通して次のような成長を得られた。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;馴染みのないプロジェクトのコードを読むのに慣れてきた。困ったり疑問があったらとりあえずドキュメントを読んだりissueやPRを検索したりcloneしてコードを読む、というのを自然とできるようになってきた。
&lt;ul&gt;
&lt;li&gt;以前はとりあえず日本語のブログを探したりAIに聞いたりしていたが上記の動きができるようになってから困りの解消速度が上がった感触がある。&lt;/li&gt;
&lt;li&gt;特にRustで個人開発をしていると使いたいライブラリにドキュメントやexampleが存在しておらずそうするしかなかったというのもあるが、そのおかげで結果的に情報収集力が上がったように思う。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;(OSSプロジェクトでは基本的に英語でコミュニケーションを行うので)英語でのやりとりに対する抵抗がなくなった。DeepLに頼ることも多々あるので来年はその割合を減らしていけると英語力の向上に繋がっていいかもしれない。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;OSS貢献を始める前は「自分がissueを立てたりPRを送ったりしなくても世界中にはたくさんの優秀なエンジニアがいるので自分が貢献する余地はないだろう」などど考えていたが、意外と自分のような普通の開発者でも貢献の余地があることを実感できた。&lt;/p&gt;
&lt;p&gt;具体的には、ある程度利用者がいるOSSプロジェクトであっても意外と自分が思いついた改善のアイディアが採用されたり、超有名なOSSでもドキュメントに間違いがあったりする。&lt;/p&gt;
&lt;p&gt;機能追加の例を挙げると&lt;a href=&#34;https://github.com/dlvhdr/gh-dash&#34; target=&#34;_blank&#34; &gt;dlvhdr/gh-dash&lt;/a&gt;に対する以下のPRではローディング中に&lt;code&gt;No PRs were found ...&lt;/code&gt;のようなメッセージが表示されていたのでローディング状態を表すスピナーを表示するようにした。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/dlvhdr/gh-dash/pull/364&#34; target=&#34;_blank&#34; &gt;feat: showing a loading message #364 - dlvhdr/gh-dash&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;gh-dashは2024/12/30現在で7.4kスターを獲得しているOSSプロジェクトでスター数から類推するにそれなりに利用者もいると思われるが機能追加で貢献できたのは当時の自分からすると意外だった。(有名なプロジェクトなので自分が貢献する余地はないだろう、という先入観があった)&lt;/p&gt;
&lt;p&gt;また、ドキュメント修正の例だと&lt;a href=&#34;https://github.com/grpc/grpc.io/pull/1343&#34; target=&#34;_blank&#34; &gt;Add missing version specifications for go install #1343 - grpc/grpc.io&lt;/a&gt;でgRPCのプラグインのインストールコマンドを修正したり&lt;a href=&#34;https://github.com/zed-industries/zed/pull/10416&#34; target=&#34;_blank&#34; &gt;docs: Fix installation command via Homebrew #10416 - zed-industries/zed&lt;/a&gt;でzedのインストールコマンドの不備を修正する変更が受け入れられた。&lt;/p&gt;
&lt;p&gt;このように大規模な有名OSSであっても意外と自分が貢献する余地があると感じられたのはよかった。2025年も「自分なんかができることはないだろう」と自分の可能性を狭めずに積極的に貢献していきたい。&lt;/p&gt;
&lt;p&gt;また、OSS貢献はメンテナや利用者に感謝してもらえるし熱量が高い人と議論したり協力したりできるのでとても楽しい。これからも楽しみながら貢献を続けていこうと思う。&lt;/p&gt;
&lt;h3 id=&#34;寄付&#34;&gt;寄付&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.kyu08.com/posts/renew-oss-sponsoring/&#34; target=&#34;_blank&#34; &gt;GitHub Sponsorsの寄付先にratatuiを追加した&lt;/a&gt;でも書いた通り毎月&lt;a href=&#34;https://github.com/ratatui/ratatui&#34; target=&#34;_blank&#34; &gt;ratatui&lt;/a&gt;と&lt;a href=&#34;https://github.com/neovim/neovim&#34; target=&#34;_blank&#34; &gt;neovim&lt;/a&gt;に5$ずつ寄付しはじめた。&lt;/p&gt;
&lt;p&gt;また、自分がソフトウェアエンジニアを目指して就活をしている際に&lt;a href=&#34;https://jsprimer.net/&#34; target=&#34;_blank&#34; &gt;JavaScript Primer&lt;/a&gt;に大いに助けていただいたことをふとしたときに思い出したので&lt;a href=&#34;https://github.com/sponsors/azu&#34; target=&#34;_blank&#34; &gt;azu&lt;/a&gt;さんにoneshotで10$寄付させていただいた。非情報系の大学/大学院に進んでいた自分にとってはとてもありがたい存在だった。&lt;/p&gt;
&lt;h2 id=&#34;個人開発&#34;&gt;個人開発&lt;/h2&gt;
&lt;p&gt;サマリ:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;fzf-makeのstar数が100を突破した&lt;/li&gt;
&lt;li&gt;fzf-makeがhomebrew-coreに取り込まれた&lt;/li&gt;
&lt;li&gt;goでWeb APIサーバを作る際のパッケージ構成について検討した&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;fzf-make&#34;&gt;fzf-make&lt;/h3&gt;
&lt;p&gt;個人開発に関して言うと2024年はひたすらfzf-makeの改善を続けていた。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/kyu08/fzf-make&#34; target=&#34;_blank&#34; &gt;fzf-make&lt;/a&gt;とはタスクランナー側で定義したコマンドをfuzzy finder形式で選択できるCLIツールで、現在は以下のタスクランナーに対応している。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;make&lt;/li&gt;
&lt;li&gt;pnpm&lt;/li&gt;
&lt;li&gt;yarn&lt;/li&gt;
&lt;li&gt;just&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&#34;fzf-make-pnpm.gif&#34; alt=&#34;fzf-make-pnpm&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;プレビューウィンドウが表示されるのでコマンドの内容を確認しながら選択できるのが特徴。履歴機能もあるので前回実行したコマンドを簡単に再実行することもできる。(&lt;code&gt;fzf-make repeat&lt;/code&gt;)&lt;/p&gt;
&lt;p&gt;2024年は&lt;a href=&#34;https://github.com/pulls?q=is%3Apr&amp;#43;archived%3Afalse&amp;#43;author%3Akyu08&amp;#43;is%3Apublic&amp;#43;repo%3Akyu08%2Ffzf-make&amp;#43;created%3A2024-01-01..2024-12-31&amp;#43;is%3Amerged&#34; target=&#34;_blank&#34; &gt;筆者が108件のPRを作成&amp;amp;マージし、&lt;/a&gt;41個のバージョンがリリースされ、&lt;a href=&#34;https://github.com/kyu08/fzf-make/compare/v0.13.0...v0.53.0&#34; target=&#34;_blank&#34; &gt;筆者とrenovateを含めて8人の貢献者により184のcommitが追加された。&lt;/a&gt;時折issueを立ててくれたりPRを送ってくれる方もいて大変ありがたい限り&amp;hellip;！🙏&lt;/p&gt;
&lt;p&gt;自分や自分の身の回りのエンジニアに使ってもらえてるのでFBをもらいやすいこと、Rustを書くのが楽しいことが要因で熱量高く取り組めている。&lt;/p&gt;
&lt;p&gt;行った主要な機能追加は以下の通り。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;コマンドの実行履歴機能の追加&lt;a href=&#34;https://github.com/kyu08/fzf-make/releases/tag/v0.19.0&#34; target=&#34;_blank&#34; &gt;&lt;code&gt;@v0.19.0&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;pnpm scriptsのサポート&lt;a href=&#34;https://github.com/kyu08/fzf-make/releases/tag/v0.39.0&#34; target=&#34;_blank&#34; &gt;&lt;code&gt;@v0.39.0&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;yarn scriptsのサポート&lt;a href=&#34;https://github.com/kyu08/fzf-make/releases/tag/v0.43.0&#34; target=&#34;_blank&#34; &gt;&lt;code&gt;@v0.43.0&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;利用中のバージョンよりも新しいバージョンが存在する場合の通知機能&lt;a href=&#34;https://github.com/kyu08/fzf-make/releases/tag/v0.48.0&#34; target=&#34;_blank&#34; &gt;&lt;code&gt;@v0.48.0&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;プレビューウィンドウのためにbatコマンドを実行する方式からsyntectを利用してsyntax highlightを行うように変更(パフォーマンスが向上した)&lt;a href=&#34;https://github.com/kyu08/fzf-make/releases/tag/v0.50.0&#34; target=&#34;_blank&#34; &gt;&lt;code&gt;@v0.50.0&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;justのサポート&lt;a href=&#34;https://github.com/kyu08/fzf-make/releases/tag/v0.52.0&#34; target=&#34;_blank&#34; &gt;&lt;code&gt;@v0.52.0&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;来年はnpm、taskfileのサポートやaptでの配信などにも着手しようと画策中。&lt;/p&gt;
&lt;p&gt;また、ある程度機能が揃ってきたタイミングでユーザー数を増やすアクションをしようと思い、zenn、Reddit, Hacker Newsに記事を投稿した。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Zenn: &lt;a href=&#34;https://zenn.dev/kyu08/articles/974fd8bc25c303&#34; target=&#34;_blank&#34; &gt;[make,pnpm,yarn,justに対応]コマンドをfuzzy finder形式で選択できるCLIツール fzf-makeの紹介&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Reddit: &lt;a href=&#34;https://www.reddit.com/r/commandline/comments/1h7btkl/fzfmake_a_command_runner_with_fuzzy_finder_and/&#34; target=&#34;_blank&#34; &gt;fzf-make - A command runner with fuzzy finder and preview window for make, pnpm - reddit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Hacker News: &lt;a href=&#34;https://news.ycombinator.com/item?id=42357587&#34; target=&#34;_blank&#34; &gt;Show HN: fzf-make – a command runner with a fuzzy finder for make, pnpm and yarn - Hacker News&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;広報活動の甲斐もあってかGitHubのstar数が100を突破した。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;star-history-20241230.webp&#34; alt=&#34;star-history-20241230&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;記事へのリアクションはHacker News &amp;lt; Zenn &amp;lt; Redditの順で多かったが、流入数が一番多かったのはHacker Newsだった。おそらくアクティブユーザーのケタが違いそう。&lt;/p&gt;
&lt;p&gt;さらには夢の1つだった自分のツールがhomebrew-coreに取り込まれるということも達成できた。実は本家homebrewに取り込まれるためには&lt;a href=&#34;https://docs.brew.sh/Acceptable-Formulae#niche-or-self-submitted-stuff&#34; target=&#34;_blank&#34; &gt;ある程度有名でユーザー数が多いこと、などの基準がある&lt;/a&gt;ためいつかfzf-makeがある程度有名になったといえるタイミングでPRを送ろうと&lt;a href=&#34;https://github.com/kyu08/fzf-make/issues/195&#34; target=&#34;_blank&#34; &gt;考えていた。&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;が、あるときたまたまhomebrewのメンテナによって&lt;a href=&#34;https://github.com/Homebrew/homebrew-core/pull/200454&#34; target=&#34;_blank&#34; &gt;fzf-makeがhomebrew/homebrew-coreに追加されるPR&lt;/a&gt;を発見しfzf-makeがhomebrewに取り込まれたことを知ることとなった。自分としては思わぬ早めのクリスマスプレゼントのような感じで本当に嬉しかった。&lt;/p&gt;
&lt;p&gt;その喜びと感謝を伝えたところメンテナの方からこんなコメントをもらった。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In addition to maintaining Homebrew, I search for awesome software that we don&amp;rsquo;t currently ship so that I can add it for distribution. Was happy to find fzf-make and ship it! おめでとう〜！&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/kyu08/fzf-make/issues/195#issuecomment-2533563544&#34; target=&#34;_blank&#34; &gt;https://github.com/kyu08/fzf-make/issues/195#issuecomment-2533563544&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;自分がつくったソフトウェアがhomebrewメンテナの方に必要だと思ってもらえて純粋に嬉しかったし、たった一言でもわざわざ日本語で祝福してくれたのも大変心に響いた。&lt;/p&gt;
&lt;h3 id=&#34;goでweb-apiサーバを作る際のパッケージ構成について検討した&#34;&gt;GoでWeb APIサーバを作る際のパッケージ構成について検討した&lt;/h3&gt;
&lt;p&gt;業務のWeb APIサーバーの実装の課題と改善策を考えているときにふと「現時点での自分の理想のGo APIサーバーのアーキテクチャ」のぼんやりとした像はあれど実装したことがないことに気付いたので書いてみることにした。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://github.com/kyu08/go-api-server-playground&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://github.com/kyu08/go-api-server-playground&#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/d0ea62f045cb885011d1728784f87461591c5dd0f1781bcbdaa5c543ebb040fd/kyu08/go-api-server-playground&#34; alt=&#34;GitHub - kyu08/go-api-server-playground: GoでAPI Serverを書くときのもろもろを検証するレポ&#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-api-server-playground: GoでAPI Serverを書くときのもろもろを検証するレポ&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;GoでAPI Serverを書くときのもろもろを検証するレポ. Contribute to kyu08/go-api-server-playground development by creating an account on GitHub.&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://github.com/kyu08/go-api-server-playground&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;Twitterのクローンアプリを題材にした。主にレイヤー分けの方法に注力しつつ次のような技術キャッチアップも兼ねて作った。(その他の使用技術は&lt;a href=&#34;https://github.com/kyu08/go-api-server-playground&#34; target=&#34;_blank&#34; &gt;README&lt;/a&gt;参照)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;gRPC&lt;/li&gt;
&lt;li&gt;構造化ログ&lt;/li&gt;
&lt;li&gt;runnを使ったE2Eテスト&lt;/li&gt;
&lt;li&gt;docker composeを自分でイチから書く&lt;/li&gt;
&lt;li&gt;sqlcを使ってsqlからコード生成&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;なんとなく形になりかけたところで忙しくなり中途半端になってしまったので来年どこかで再開したい。&lt;/p&gt;
&lt;h2 id=&#34;ブログ&#34;&gt;ブログ&lt;/h2&gt;
&lt;p&gt;サマリ:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;17本の記事を書いた&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.kyu08.com/posts/better-programmer/&#34; target=&#34;_blank&#34; &gt;『ベタープログラマ』 を読んだ&lt;/a&gt;がはてぶのトップページに載った&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kyu08/blog/pull/186&#34; target=&#34;_blank&#34; &gt;こんな感じ&lt;/a&gt;でデザインを変更した。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;3月に書いた&lt;a href=&#34;https://blog.kyu08.com/posts/better-programmer/&#34; target=&#34;_blank&#34; &gt;『ベタープログラマ』 を読んだ&lt;/a&gt;がたくさんの人の読んでいただけて、はてぶのトップページに掲載された。&lt;/p&gt;
&lt;p&gt;優秀なエンジニアの振る舞いについて様々な角度から考察されていて大変参考になった。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;better-programmer-hatebu.webp&#34; alt=&#34;better-programmer-hatebu&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;他に印象に残っている記事は以下。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.kyu08.com/posts/cs50-jp/&#34; target=&#34;_blank&#34; &gt;CS50.jpでCSに入門した&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.kyu08.com/posts/learn-about-spanner/&#34; target=&#34;_blank&#34; &gt;Cloud Spanner について知らなかったことを書く&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.kyu08.com/posts/go-system-programming/&#34; target=&#34;_blank&#34; &gt;『Goならわかるシステムプログラミング 第2版』を読んだ&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ブログでのアウトプットを通して自分の学びを整理したり、記憶に定着させることができている実感があるので来年も続けていく。&lt;/p&gt;
&lt;h2 id=&#34;読書など&#34;&gt;読書など&lt;/h2&gt;
&lt;p&gt;読んだ本や受講した講座:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CS50&lt;/li&gt;
&lt;li&gt;ベタープログラマ&lt;/li&gt;
&lt;li&gt;いちばんやさしいアジャイルの開発の教本&lt;/li&gt;
&lt;li&gt;読み手につたわる文章 - テクニカルライティング&lt;/li&gt;
&lt;li&gt;Goならわかるシステムプログラミング第2版&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;CS50を受講し、『Goならわかるシステムプログラミング第2版』を読んだことでCSの基礎的な部分を学ぶことができた。両方とも手を動かしながら学べる形式だったので楽しく理解を深めることができた。&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;そこで得た学びをもとに、次は『コンピュータシステムの理論と実装第2版』をやっていく。その次はネットワーク系にも手を出したい。&lt;/p&gt;
&lt;h2 id=&#34;生活&#34;&gt;生活&lt;/h2&gt;
&lt;h3 id=&#34;運動と早寝早起き&#34;&gt;運動と早寝早起き&lt;/h3&gt;
&lt;p&gt;運動と早寝早起きによって頭がスッキリしてパフォーマンスが上がる感覚があったので今年の春くらいから意識的に取り組んだ。&lt;/p&gt;
&lt;p&gt;リングフィットは運動のハードルを下げられるし楽しく運動できて良い反面、有酸素運動をするのであれば普通にランニングした方が運動強度を高めやすくて良さそう。（が、冬の時期は着替えが面倒だし寒いのでなかなか走りに行けなかった）&lt;/p&gt;
&lt;p&gt;あとは早めに風呂に入ると早めに眠くなるので早寝早起きしやすい、という当たり前すぎることを感じた。&lt;/p&gt;
&lt;h3 id=&#34;舌下治療をはじめた&#34;&gt;舌下治療をはじめた&lt;/h3&gt;
&lt;p&gt;11月中旬から開始した。来年の2月ごろには効果が出るらしいので楽しみ。&lt;/p&gt;
&lt;h2 id=&#34;買ってよかったもの&#34;&gt;買ってよかったもの&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;スタンディングデスク(FlexispotのE7)&lt;/li&gt;
&lt;li&gt;MX Ergo S
&lt;ul&gt;
&lt;li&gt;MX Ergoから乗り換えたが静かでボタンの押し心地も良くなっていて満足。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;LogicoolのWebカメラ(C980GR)&lt;/li&gt;
&lt;li&gt;デスク用の足元パネルヒーター&lt;/li&gt;
&lt;li&gt;脱衣所に置く小型セラミックヒーター&lt;/li&gt;
&lt;li&gt;THE NORTH FACEのダウン&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;仕事&#34;&gt;仕事&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;チーム内のコミュニケーションやドキュメンテーションなどチーム改善にコミットする時間が去年までよりも長かった。チームを変えることの難しさやうまくいったときの達成感を感じることができてよかった。&lt;/li&gt;
&lt;li&gt;これまでよりも不確実性と向き合った。目的不確実性がある中でのプロジェクトの進め方、アサインやタスクの着手順などについて考えることが多かったのがいい経験だった。改めて『エンジニアリング組織論への招待』を読み返そうと思う。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;2025年の抱負&#34;&gt;2025年の抱負&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;仕事関係で大きめの変化があるのでしっかりとバリューを出して事業貢献できるように頑張っていきたい。&lt;/li&gt;
&lt;li&gt;CSの勉強を続けてソフトウェアエンジニアの土台となるような知識を固めていきたい。来年はこのあたりに注力する予定。
&lt;ul&gt;
&lt;li&gt;OS&lt;/li&gt;
&lt;li&gt;ネットワーク&lt;/li&gt;
&lt;li&gt;コンテナ技術(というかk8s)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;おわりに&#34;&gt;おわりに&lt;/h2&gt;
&lt;p&gt;振り返ると結構いろいろやれた。来年もやっていき。&lt;/p&gt;
&lt;p&gt;去年の振り返り: &lt;a href=&#34;https://blog.kyu08.com/posts/looking-back-on-2023/&#34; target=&#34;_blank&#34; &gt;2023年を振り返る&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;Ownerが自分以外のPublic Repositoryを対象に集計。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;別記事を書くときのための自分用のメモ &lt;a href=&#34;https://gist.github.com/kyu08/29f27ea93e8566759c89db001c47b3cb&#34; target=&#34;_blank&#34; &gt;https://gist.github.com/kyu08/29f27ea93e8566759c89db001c47b3cb&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;CS50の課題でC言語の大変さを学べたのもいい思い出。&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>RFC 2606: Reserved Top Level DNS Namesを読んで知らなかったことを書く</title>
      <link>https://blog.kyu08.com/posts/reserved-top-level-dns-names-rfc-2606/</link>
      <pubDate>Sun, 15 Dec 2024 15:00:00 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/posts/reserved-top-level-dns-names-rfc-2606/</guid>
      <description>本記事はUnipos Advent Calendar 2024の16日目の記事です。 ふいに見かけたRFC 2606: Reserved Top Level DNS Namesを読んでみたところ発見があったのでその内容をま</description>
      <content>&lt;p&gt;本記事は&lt;a href=&#34;https://qiita.com/advent-calendar/2024/unipos&#34; target=&#34;_blank&#34; &gt;Unipos Advent Calendar 2024&lt;/a&gt;の16日目の記事です。&lt;/p&gt;
&lt;p&gt;ふいに見かけた&lt;a href=&#34;https://datatracker.ietf.org/doc/html/rfc2606&#34; target=&#34;_blank&#34; &gt;RFC 2606: Reserved Top Level DNS Names&lt;/a&gt;を読んでみたところ発見があったのでその内容をまとめてみようと思います。&lt;/p&gt;
&lt;h2 id=&#34;rfc-2606の概要&#34;&gt;RFC 2606の概要&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Abstract&lt;/p&gt;
&lt;p&gt;To reduce the likelihood of conflict and confusion, a few top level
domain names are reserved for use in private testing, as examples in
documentation, and the like.  In addition, a few second level domain
names reserved for use as examples are documented.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;対立や混乱を減らす目的でいくつかのTLD名が予約されている。用途はプライベートなテスト用、ドキュメントでの例示用など。&lt;/li&gt;
&lt;li&gt;上記に加えて例示用にいくつかのSecond Level Domain Namesが予約されている。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;予約されたtop-level-domain-names&#34;&gt;予約されたTop Level Domain Names&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;There is a need for top level domain (TLD) names that can be used for
creating names which, without fear of conflicts with current or
future actual TLD names in the global DNS, can be used for private
testing of existing DNS related code, examples in documentation, DNS
related experimentation, invalid DNS names, or other similar uses.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;DNSのプライベートテスト用やドキュメントなどの目的で使用できるTLD名が必要であるとのこと。（DNSへの解像度がとても低いので具体的にどんなテストが行われるのかの想像はついていない&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;blockquote&gt;
&lt;p&gt;To safely satisfy these needs, four domain names are reserved as
listed and described below.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;            .test
         .example
         .invalid
       .localhost
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;ldquo;.test&amp;rdquo; is recommended for use in testing of current or new DNS
related code.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;.example&amp;rdquo; is recommended for use in documentation or as examples.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;.invalid&amp;rdquo; is intended for use in online construction of domain
names that are sure to be invalid and which it is obvious at a
glance are invalid.&lt;/p&gt;
&lt;p&gt;The &amp;ldquo;.localhost&amp;rdquo; TLD has traditionally been statically defined in
host DNS implementations as having an A record pointing to the
loop back IP address and is reserved for such use.  Any other use
would conflict with widely deployed code which assumes this use.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;上記のニーズを満たすために、次の4つのTLD名が予約されている。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;.test&lt;/code&gt;: 既存のまたは新規のDNS関連コードのテストに使用することが推奨されている。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.example&lt;/code&gt;: ドキュメントや例示として使用することが推奨されている。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.invalid&lt;/code&gt;: 無効であることが確実で一目で無効であることが明らかなドメイン名をオンラインで構築する際に使用することを目的としている。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.localhost&lt;/code&gt;: 伝統的にホストDNS実装においてループバックIPアドレスを指すAレコードを持つものとして静的に定義されておりこのような使用のために予約されている。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;.invalid&lt;/code&gt;の説明がわからなかったのでWikipadiaを参照してみたところ次のような記述があった。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This top-level domain is sometimes used as a pseudo domain name in Uniform Resource Identifiers (URIs) to convey either an error condition or in use of privacy protection.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/.invalid&#34; target=&#34;_blank&#34; &gt;https://en.wikipedia.org/wiki/.invalid&lt;/a&gt; より引用&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;要はエラーケースのテストのためやプライバシー保護の目的で擬似ドメイン名として利用されることがある、と理解した。(このあたりの深い理解は別途時間をとりたい)&lt;/p&gt;
&lt;p&gt;これらのTLD名は見たことはあったがRFCとして明示されていることは知らなかった。&lt;/p&gt;
&lt;h2 id=&#34;予約されたsecond-level-domain-names&#34;&gt;予約されたSecond Level Domain Names&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;3 Reserved Example Second Level Domain Names&lt;/p&gt;
&lt;p&gt;The Internet Assigned Numbers Authority (IANA) also currently has the
following second level domain names reserved which can be used as
examples.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; example.com
 example.net
 example.org
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;example.com&lt;/code&gt;以外にも&lt;code&gt;example.net&lt;/code&gt;と&lt;code&gt;example.org&lt;/code&gt;が予約されていることは知らなかった。&lt;/p&gt;
&lt;p&gt;また、&lt;code&gt;4. IANA Considerations&lt;/code&gt;にも記述があるが、本文章で示されたTLD名およびSecond Level Domain名はInternet Assigned Numbers Authority(IANA)によって予約される。&lt;/p&gt;
&lt;h2 id=&#34;著作権表示&#34;&gt;著作権表示&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Copyright (C) The Internet Society (1999).  All Rights Reserved.&lt;/p&gt;
&lt;p&gt;This document and translations of it may be copied and furnished to
others, and derivative works that comment on or otherwise explain it
or assist in its implementation may be prepared, copied, published
and distributed, in whole or in part, without restriction of any
kind, provided that the above copyright notice and this paragraph are
included on all such copies and derivative works.  However, this
document itself may not be modified in any way, such as by removing
the copyright notice or references to the Internet Society or other
Internet organizations, except as needed for the purpose of
developing Internet standards in which case the procedures for
copyrights defined in the Internet Standards process must be
followed, or as required to translate it into languages other than
English.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;感想&#34;&gt;感想&lt;/h2&gt;
&lt;p&gt;はじめてRFCを読んだ。部分的に馴染みのある内容だったし文量としても多くなかったのでスムーズに読めた。&lt;/p&gt;
&lt;p&gt;これまでは「誰かがテスト用ドメインとして&lt;code&gt;example.com&lt;/code&gt;を抑えてくれているのでテスト用に使ってOK」という程度の理解だったが、いくつかのDomain名がテスト、例示目的で予約されることがRFCで明示されておりIANAが実際にそれらを予約していることでテスト用ドメインが利用できているということを知ることができた。&lt;/p&gt;
&lt;p&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;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://www.amazon.co.jp/Linux%E3%81%A7%E5%8B%95%E3%81%8B%E3%81%97%E3%81%AA%E3%81%8C%E3%82%89%E5%AD%A6%E3%81%B6TCP-IP%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E5%85%A5%E9%96%80-%E3%82%82%E3%81%BF%E3%81%98%E3%81%82%E3%82%81-ebook/dp/B085BG8CH5&#34; target=&#34;_blank&#34; &gt;Linuxで動かしながら学ぶTCP/IPネットワーク入門&lt;/a&gt;や&lt;a href=&#34;https://www.sbcr.jp/product/4815618599/&#34; target=&#34;_blank&#34; &gt;体験しながら学ぶ ネットワーク技術入門&lt;/a&gt;あたりで腰を据えてネットワーク周りを学びたい&amp;hellip;。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;が、次は&lt;a href=&#34;https://www.oreilly.co.jp/books/9784814400874/&#34; target=&#34;_blank&#34; &gt;コンピュータシステムの理論と実装 第2版&lt;/a&gt;をやると決めているのでやるとしたらその次かな&amp;hellip;。&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;ちなみに、他のRFCを眺めていたら&lt;code&gt;SHOULD&lt;/code&gt;, &lt;code&gt;MUST&lt;/code&gt;のようなキーワードが大文字で強調されていたが、それらのキーワードの解釈については&lt;a href=&#34;https://datatracker.ietf.org/doc/html/rfc2119&#34; target=&#34;_blank&#34; &gt;RFC 2119: Key words for use in RFCs to Indicate Requirement Levels&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>ソフトウェアエンジニア目線で使ってみて便利だったChrome拡張を紹介する</title>
      <link>https://blog.kyu08.com/posts/chrome-extensions-for-dev-2024/</link>
      <pubDate>Thu, 12 Dec 2024 15:00:00 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/posts/chrome-extensions-for-dev-2024/</guid>
      <description>本記事はUnipos Advent Calendar 2024の13日目の記事です。 本記事では使ってみて便利だったChrome拡張を紹介します。 Stylus Stylus ユーザー定義のCSSを</description>
      <content>&lt;p&gt;本記事は&lt;a href=&#34;https://qiita.com/advent-calendar/2024/unipos&#34; target=&#34;_blank&#34; &gt;Unipos Advent Calendar 2024&lt;/a&gt;の13日目の記事です。&lt;/p&gt;
&lt;p&gt;本記事では使ってみて便利だったChrome拡張を紹介します。&lt;/p&gt;
&lt;h2 id=&#34;stylus&#34;&gt;Stylus&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://chromewebstore.google.com/detail/stylus/clngdbkpkpeebahjckkjfobafhncgmne?hl=ja&#34; target=&#34;_blank&#34; &gt;Stylus&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;ユーザー定義のCSSを手軽に適用できるChrome拡張です。&lt;/p&gt;
&lt;p&gt;筆者の使い方としては&lt;a href=&#34;https://blog.kyu08.com/posts/refine-notion-gantt-chart/&#34; target=&#34;_blank&#34; &gt;Notionのガントチャートを見やすくしたり&lt;/a&gt;、GitHubのUIの幅を大きくしたりしています。PR上で実行計画を見る際などにスクロールしなくてよくなり便利になりました。&lt;/p&gt;
&lt;h2 id=&#34;google-search-results-shortcuts&#34;&gt;Google search results shortcuts&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://chromewebstore.google.com/detail/google%E6%A4%9C%E7%B4%A2%E3%82%AD%E3%83%BC%E3%83%9C%E3%83%BC%E3%83%89%E3%82%B7%E3%83%A7%E3%83%BC%E3%83%88%E3%82%AB%E3%83%83%E3%83%88/dchaandmcifgjemlhiekookpgjmkcelg&#34; target=&#34;_blank&#34; &gt;Google search results shortcuts&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Google検索結果のページでキーボードショートカットを使えるようにするChrome拡張です。&lt;/p&gt;
&lt;p&gt;筆者がよく使うのは以下です。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;↑: 1つ上の検索結果に移動&lt;/li&gt;
&lt;li&gt;↓: 1つ下の検索結果に移動&lt;/li&gt;
&lt;li&gt;Enter: 選択中の検索結果を開く&lt;/li&gt;
&lt;/ul&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;google-search-results-shortcuts.gif&#34; alt=&#34;google-search-results-shortcuts.gif&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;vimium&#34;&gt;Vimium&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://chromewebstore.google.com/detail/vimium/dbepggeogbaibhgnhhndojpepiihcmeb?hl=ja&#34; target=&#34;_blank&#34; &gt;Vimium&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;言わずと知れたvimのような操作感でChromeを操作できるChrome拡張です。&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;基本的な操作方法についてはたくさんの情報があると思いますのでここでは筆者のキーマップや最近知った機能について紹介します。&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-vim&#34; data-lang=&#34;vim&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;map&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;q&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;goBack&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#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;map&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;d&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;goForward&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#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;map&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;s&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;scrollPageUp&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#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;map&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;a&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;scrollPageDown&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#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;map&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;w&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;scrollDown&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#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;map&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;e&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;scrollUp&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;また、最近知ったvimiumの機能についても紹介したいと思います。ふと&lt;a href=&#34;https://github.com/philc/vimium&#34; target=&#34;_blank&#34; &gt;README&lt;/a&gt;を眺めていたら&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;gi      focus the first (or n-th) text input box on the page. Use &amp;lt;tab&amp;gt; to cycle through options.
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;という記述を見つけました。&lt;/p&gt;
&lt;p&gt;フォーカスできるテキストボックスが1つの場合はその要素にフォーカスが当たり、複数の場合はタブで切り替えることができます。
これまではマウスを使ってフォーカスを当てていましたがこれを知ってからマウスへの依存をより下げることができました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;vimium-gi.gif&#34; alt=&#34;vimium-gi.gif&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;gcp-console-colorize&#34;&gt;GCP console colorize&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://chromewebstore.google.com/detail/gcp-console-colorize/higjahjicmccalicmgfpokdmooopdhej?hl=ja&#34; target=&#34;_blank&#34; &gt;GCP console colorize&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Google Cloudのプロジェクトごとにヘッダーの色を変更するChrome拡張です。&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;project-a&lt;/td&gt;
&lt;td&gt;&lt;img src=&#34;gcp-console-colorize-red.webp&#34; alt=&#34;gcp-console-colorize-red.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;project-b&lt;/td&gt;
&lt;td&gt;&lt;img src=&#34;gcp-console-colorize-yellow.webp&#34; alt=&#34;gcp-console-colorize-yellow.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;lttm&#34;&gt;LTTM&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://chromewebstore.google.com/detail/lttm/jdidcgkdggndpodjbipodfefnpgjooeh&#34; target=&#34;_blank&#34; &gt;LTTM&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;PRレビューの際にいい感じの画像を手早く貼ることができるChrome拡張です。&lt;/p&gt;
&lt;p&gt;PR上でのコミュニケーションが捗っています。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;lttm.webp&#34; alt=&#34;lttm.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;find--regex-find-in-page-tool&#34;&gt;find+ | Regex Find-in-Page Tool&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://chromewebstore.google.com/detail/find&amp;#43;-regex-find-in-page/fddffkdncgkkdjobemgbpojjeffmmofb&#34; target=&#34;_blank&#34; &gt;find+ | Regex Find-in-Page Tool&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;正規表現を使ってページ内を検索できるChrome拡張です。&lt;/p&gt;
&lt;p&gt;便利です。&lt;/p&gt;
&lt;h2 id=&#34;notion-sidebar-tamer&#34;&gt;Notion Sidebar Tamer&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://chromewebstore.google.com/detail/notion-sidebar-tamer/kkjflddbknmcnjodgeobojmdacilodlb?hl=ja&#34; target=&#34;_blank&#34; &gt;Notion Sidebar Tamer&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Notionのサイドバーにマウスカーソルが近づいたときにサイドバーが表示されるのを防ぐChrome拡張です。&lt;/p&gt;
&lt;p&gt;1日に1回はこの挙動にストレスを感じていたのでQOLが上がりました。&lt;/p&gt;
&lt;p&gt;たとえば次のようなNotionページの赤枠部分をコピーしたいとします。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;notion-sidebar-tamer.webp&#34; alt=&#34;notion-sidebar-tamer.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;コピーするには赤枠の左あたりにカーソルを持っていく必要がある&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;のですが判定が結構厳しいので意図せずサイドバーが表示されてしまうことがよくあります。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;notion-sidebar-tamer-before.gif&#34; alt=&#34;notion-sidebar-tamer-before.gif&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;そこでNotion Sidebar Tamerを使うとカーソルをサイドバー付近に移動してもサイドバーが表示されなくなります。やったね！&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;notion-sidebar-tamer-after.gif&#34; alt=&#34;notion-sidebar-tamer-after.gif&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;おわりに&#34;&gt;おわりに&lt;/h2&gt;
&lt;p&gt;Chrome拡張開発者のみなさんに圧倒的感謝&amp;hellip;！&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://chromewebstore.google.com/detail/tabby-cat/mefhakmgclhhfbdadeojlkbllmecialg?hl=ja&amp;amp;utm_source=chrome-ntp-launcherhttps://chrome.google.com/webstore/detail/mabl-trainer/npfildagndinaoofhecikgcfcohfapeo?hl%3Dja&#34; target=&#34;_blank&#34; &gt;Tabby Cat&lt;/a&gt;の機能です。&lt;code&gt;cmd + T&lt;/code&gt;で新しいタブを開くと可愛い動物たちとchillな時間を過ごすことができます。&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;早くNotionとSlackがキーボードだけで操作できるようになってほしいです。あわよくば誰か完璧なTUIクライアントを作ってください。&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;このケースだとカーソルを右側に持っていってコピーすることもできますが普段は左側に持っていかないとコピーが難しいケースが多いためこのように書いています。具体的なケースが思い出せたら記事を修正しようと思います。&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</content>
    </item>
    
    <item>
      <title>Notionのダークモードのガントチャートが見づらいのをChrome拡張で修正する方法</title>
      <link>https://blog.kyu08.com/posts/refine-notion-gantt-chart/</link>
      <pubDate>Fri, 08 Nov 2024 14:34:37 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/posts/refine-notion-gantt-chart/</guid>
      <description>できること Notionのガントチャートが見づらいのをなんとかするスクリプト Before After 前提条件 NotionをChromium系のブラウザで利用してい</description>
      <content>&lt;h2 id=&#34;できること&#34;&gt;できること&lt;/h2&gt;
&lt;p&gt;Notionのガントチャートが見づらいのをなんとかするスクリプト&lt;/p&gt;
&lt;h3 id=&#34;before&#34;&gt;Before&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;before.webp&#34; alt=&#34;before.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;after&#34;&gt;After&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;after.webp&#34; alt=&#34;after.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;前提条件&#34;&gt;前提条件&lt;/h2&gt;
&lt;p&gt;NotionをChromium系のブラウザで利用していること&lt;/p&gt;
&lt;h2 id=&#34;やり方&#34;&gt;やり方&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;下記のリンクからStylusをインストール
&lt;a href=&#34;https://chromewebstore.google.com/detail/stylus/clngdbkpkpeebahjckkjfobafhncgmne?hl=ja&#34; target=&#34;_blank&#34; &gt;https://chromewebstore.google.com/detail/stylus/clngdbkpkpeebahjckkjfobafhncgmne?hl=ja&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Manageをクリックして管理画面を開く
&lt;img src=&#34;open-management-window.webp&#34; alt=&#34;open-management-window.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/li&gt;
&lt;li&gt;Write new styleをクリック
&lt;img src=&#34;click-write-new-style.webp&#34; alt=&#34;click-write-new-style.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/li&gt;
&lt;li&gt;次のCSSを入力しURLのブロックに&lt;code&gt;URLs starting with: https://www.notion.so/&lt;/code&gt;を指定しSaveをクリック
&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-css&#34; data-lang=&#34;css&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;notion-selectable&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;notion-page-block&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;notion-timeline-item&lt;/span&gt; &lt;span style=&#34;color:#f92672&#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:#66d9ef&#34;&gt;background&lt;/span&gt;: rgba(&lt;span style=&#34;color:#ae81ff&#34;&gt;255&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;255&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;255&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0.15&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;img src=&#34;set-configs.webp&#34; alt=&#34;set-configs.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/li&gt;
&lt;li&gt;みやすくなる
&lt;img src=&#34;after.webp&#34; alt=&#34;after.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/li&gt;
&lt;/ol&gt;
</content>
    </item>
    
    <item>
      <title>『Goならわかるシステムプログラミング 第2版』を読んだ</title>
      <link>https://blog.kyu08.com/posts/go-system-programming/</link>
      <pubDate>Sun, 03 Nov 2024 12:42:30 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/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>GitHub Sponsorsの寄付先にratatuiを追加した</title>
      <link>https://blog.kyu08.com/posts/renew-oss-sponsoring/</link>
      <pubDate>Mon, 23 Sep 2024 15:02:46 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/posts/renew-oss-sponsoring/</guid>
      <description>OSSへの寄付の月予算を$10にした - laiso こちらの記事で寄付するOSSプロジェクトの選び方として次のような基準が紹介されていた。 寄付するプロジ</description>
      <content>&lt;p&gt;&lt;a href=&#34;https://laiso.hatenablog.com/entry/2022/02/25/gihutown&#34; target=&#34;_blank&#34; &gt;OSSへの寄付の月予算を$10にした - laiso&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;こちらの記事で寄付するOSSプロジェクトの選び方として次のような基準が紹介されていた。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;寄付するプロジェクトはこういう基準で選んでる&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;自分が使っていてなくなったら困る&lt;/li&gt;
&lt;li&gt;マイナーであまり寄付されていない&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;今まで前者の基準に則って&lt;a href=&#34;https://github.com/sponsors/neovim&#34; target=&#34;_blank&#34; &gt;neovim&lt;/a&gt;に寄付していたが、後者の観点を持てていなかったことに気付いた。そこで自分もOSSへの寄付を見直してみようと思った。&lt;/p&gt;
&lt;h2 id=&#34;というわけで&#34;&gt;というわけで&lt;/h2&gt;
&lt;p&gt;タイトルの通りだが、GitHub Sponsorsの寄付先に&lt;a href=&#34;https://github.com/sponsors/ratatui&#34; target=&#34;_blank&#34; &gt;ratatui&lt;/a&gt;を追加した。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/ratatui/ratatui&#34; target=&#34;_blank&#34; &gt;ratatui&lt;/a&gt;とは、手軽にTUIアプリケーションを作成できるRust用のライブラリで、筆者が個人開発しているOSSである&lt;a href=&#34;https://github.com/kyu08/fzf-make&#34; target=&#34;_blank&#34; &gt;fzf-make&lt;/a&gt;でも利用している。&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://raw.githubusercontent.com/kyu08/fzf-make/main/static/demo.gif&#34; alt=&#34;fzf-make-demo.gif&#34; loading=&#34;lazy&#34; /&gt;
&lt;a href=&#34;https://github.com/ratatui/ratatui&#34; target=&#34;_blank&#34; &gt;ratatui&lt;/a&gt;のおかげでこんな感じのUIを手軽に実装できている。&lt;/p&gt;
&lt;!-- textlint-disable ja-technical-writing/ja-no-weak-phrase --&gt;
&lt;p&gt;Rust製のTUIツールでは非常に幅広く利用されている印象だが、現在のスポンサー数が9人と少なかったので少しでも力になれればということで寄付先に追加した。長期間メンテされる状態が続いてくれると嬉しい。自分にもできそうなバグ修正があれば挑戦してみようと思う。&lt;/p&gt;
&lt;!-- textlint-disable ja-technical-writing/ja-no-weak-phrase --&gt;
&lt;p&gt;&lt;img src=&#34;ratatuis-10th-sponsor.webp&#34; alt=&#34;ratatuis-10th-sponsor.webp&#34; loading=&#34;lazy&#34; /&gt;
10番目のスポンサーになった様子。&lt;/p&gt;
&lt;p&gt;これで現在の寄付額は$10/月で、&lt;a href=&#34;https://github.com/sponsors/neovim&#34; target=&#34;_blank&#34; &gt;neovim&lt;/a&gt;と&lt;a href=&#34;https://github.com/sponsors/ratatui&#34; target=&#34;_blank&#34; &gt;ratatui&lt;/a&gt;にそれぞれ$5ずつ寄付していることになる。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;github-sponsors-logos.webp&#34; alt=&#34;github-sponsors-logos.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;他にも寄付したいプロジェクトは山ほどあるので山ほど稼いでいきたい。(あと円高頼む&amp;hellip;)&lt;/p&gt;
&lt;h2 id=&#34;まとめ&#34;&gt;まとめ&lt;/h2&gt;
&lt;p&gt;今後ともOSSコミュニティの持続可能性を高めていきたい。&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;make targetをプレビューウィンドウ付きであいまい検索によって選択&amp;amp;実行できるツール。brewやcargoでインストールできるのでぜひ。 &lt;div class=&#34;blogcard&#34; data-url=&#34;https://github.com/kyu08/fzf-make&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://github.com/kyu08/fzf-make&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail&#34;&gt;
      &lt;img src=&#34;https://repository-images.githubusercontent.com/611369838/a30cf798-2e08-47a5-9443-978329275d2c&#34; alt=&#34;GitHub - kyu08/fzf-make: A command line tool that executes commands using fuzzy finder with preview window for make, npm, pnpm, yarn, just and task.&#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/fzf-make: A command line tool that executes commands using fuzzy finder with preview window for make, npm, pnpm, yarn, just and task.&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;A command line tool that executes commands using fuzzy finder with preview window for make, npm, pnpm, yarn, just and task. - kyu08/fzf-make&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://github.com/kyu08/fzf-make&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&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>
    
    <item>
      <title>Cloud Spanner について知らなかったことを書く</title>
      <link>https://blog.kyu08.com/posts/learn-about-spanner/</link>
      <pubDate>Mon, 23 Sep 2024 01:44:54 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/posts/learn-about-spanner/</guid>
      <description>普段業務でCloud Spannerを使っているが、雰囲気で使っている自覚が大いにあるのでドキュメントやブログを読んで知らなかったことを自分用</description>
      <content>&lt;p&gt;普段業務でCloud Spannerを使っているが、雰囲気で使っている自覚が大いにあるのでドキュメントやブログを読んで知らなかったことを自分用のメモとしてまとめてみる。&lt;/p&gt;
&lt;h2 id=&#34;spanner-のスキーマ設計の最適化--google-cloud&#34;&gt;Spanner のスキーマ設計の最適化  |  Google Cloud&lt;/h2&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://cloud.google.com/spanner/docs/whitepapers/optimizing-schema-design?hl=ja&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://cloud.google.com/spanner/docs/whitepapers/optimizing-schema-design?hl=ja&#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://docs.cloud.google.com/_static/cloud/images/social-icon-google-cloud-1200-630.png?hl=ja&#34; alt=&#34;Spanner のスキーマ設計の最適化  |  Google Cloud Documentation&#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;Spanner のスキーマ設計の最適化  |  Google Cloud Documentation&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://cloud.google.com/spanner/docs/whitepapers/optimizing-schema-design?hl=ja&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;キー定義とインターリーブの2つはスケーラビリティに大きな影響を与える&lt;/li&gt;
&lt;li&gt;Spannerにはルートテーブルとインターリーブされたテーブルの2種類のテーブルがある。&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;/ul&gt;
&lt;h3 id=&#34;テーブルレイアウト&#34;&gt;テーブルレイアウト&lt;/h3&gt;
&lt;p&gt;Spannerテーブルの行は&lt;code&gt;PRIMARY_KEY&lt;/code&gt;によって辞書順に並べかえられる。したがって以下の特性を示す。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;辞書順のテーブルスキャンは効率的&lt;/li&gt;
&lt;li&gt;十分に近い行は同じディスクブロックに格納され、一緒に読み込まれてキャッシュされる&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;各Spannerレプリカ内のデータは&lt;code&gt;スプリット&lt;/code&gt;と&lt;code&gt;ブロック&lt;/code&gt;という2つの物理階層レベルで編成される。&lt;/p&gt;
&lt;h3 id=&#34;インターリーブ&#34;&gt;インターリーブ&lt;/h3&gt;
&lt;p&gt;ルートテーブルの各行をルート行と呼び、インターリーブされたテーブルの各行を子行と呼ぶ。ルート行とそのすべての子孫のコレクションは行ツリーと呼ばれる。&lt;/p&gt;
&lt;!-- textlint-disable ja-technical-writing/no-doubled-joshi --&gt;
&lt;p&gt;行ツリー内のオペレーションは他のスプリットとの通信を必要としないケースが多いため基本的には効率性が高い。ただし子行にホットスポットがある場合Spannerはホットスポットの行とそれ以降の子行を分離するためにスプリット境界を追加しようとする。そのため必ずしも効率性が高いという保証はない。&lt;/p&gt;
&lt;!-- textlint-disable ja-technical-writing/no-doubled-joshi --&gt;
&lt;h3 id=&#34;局所性のトレードオフ&#34;&gt;局所性のトレードオフ&lt;/h3&gt;
&lt;p&gt;以下の理由で局所性を高めることが重要。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;通信するサーバが多いほど一時的にビジー状態のサーバに遭遇する可能性が高くなり、レイテンシの増加につながる。&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;分散DBである以上、一定レベルの二層コミットや非ローカルデータオペレーションは避けられない。&lt;/li&gt;
&lt;li&gt;すべてのオペレーションの局所性を完璧にするのではなく最も重要なルートエンティティと最も一般的なアクセスパターンについて必要な局所性を実現することが重要。その他のオペレーションについてはそのままにすることを推奨。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;インデックスのオプション&#34;&gt;インデックスのオプション&lt;/h3&gt;
&lt;!-- textlint-disable ja-technical-writing/ja-no-redundant-expression --&gt;
&lt;ul&gt;
&lt;li&gt;デフォルトではインターリーブされていないインデックスを作成されるが、インターリーブされたインデックスを作成することもできる。
&lt;ul&gt;
&lt;li&gt;インターリーブされたインデックスはインターリーブされたテーブルにデータを格納する。そのためデータとインデックスが強制的に同じ行ツリーに格納され、データとインデックスの結合効率が高くなる。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- textlint-disable ja-technical-writing/ja-no-redundant-expression --&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Spannerはテーブルと同じ方法でインデックスデータを格納する。&lt;/strong&gt; 換言すると、インターリーブされていないインデックスはルートテーブルにデータを格納する。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;そのため以下が推奨される。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;検索範囲が単一のエンティティのときは&lt;strong&gt;常に&lt;/strong&gt;インターリーブされたインデックスを使用する。&lt;/li&gt;
&lt;li&gt;逆にデータベース内のどこからでも行を検索する必要がある場合はインターリーブされていないインデックスを使用する。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;storing&#34;&gt;STORING&lt;/h3&gt;
&lt;p&gt;要求されたすべてのデータがインデックス自体に含まれる場合、&lt;code&gt;STORING&lt;/code&gt;句を使用してインデックスを作成することができる。これによりベーステーブルと結合することなくクエリを完了できるためより効率的に結果を取得することができる。&lt;/p&gt;
&lt;p&gt;現在はインデックスキーは16個、合計サイズが6KiBまでに制限されているため、&lt;code&gt;STORING&lt;/code&gt;句を使用することで任意のインデックスに対してデータを格納することができる。&lt;/p&gt;
&lt;p&gt;つまり&lt;code&gt;STORING&lt;/code&gt;を使用すると&lt;strong&gt;WRITEコストおよびストレージコストの上昇&lt;/strong&gt;と引き換えに&lt;strong&gt;READコストを削減&lt;/strong&gt;できる。&lt;/p&gt;
&lt;p&gt;また、ドキュメントでは&lt;code&gt;STORING&lt;/code&gt;の便利な応用例として&lt;code&gt;NULL_FILTERED&lt;/code&gt;インデックスとの併用を紹介している。それについてはこちらの記事が大変詳しいので参照されたい。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://zenn.dev/facengineer/articles/15e7a68fcc2fad&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://zenn.dev/facengineer/articles/15e7a68fcc2fad&#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://res.cloudinary.com/zenn/image/upload/s--zSlZX7Xu--/c_fit%2Cg_north_west%2Cl_text:notosansjp-medium.otf_55:Cloud%2520Spanner%25E3%2581%25AENull%2520Filtered%2520INDEX%25E3%2581%25AE%25E7%2594%25A8%25E9%2580%2594%25E3%2582%2592%25E8%2580%2583%25E5%25AF%259F%25E3%2581%2599%25E3%2582%258B%2520%25E3%2580%259C%25E3%2582%25B5%25E3%2583%2596%25E3%2582%25BF%25E3%2582%25A4%25E3%2583%2597%25E5%25AE%259F%25E8%25A3%2585%25E3%2580%259C%2Cw_1010%2Cx_90%2Cy_100/g_south_west%2Cl_text:notosansjp-medium.otf_37:kngnr%2Cx_203%2Cy_121/g_south_west%2Ch_90%2Cl_fetch:aHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL3plbm4tdXNlci11cGxvYWQvYXZhdGFyLzc3YmY1NTZjODYuanBlZw==%2Cr_max%2Cw_90%2Cx_87%2Cy_95/v1627283836/default/og-base-w1200-v2.png?_a=BACAGSGT&#34; alt=&#34;Cloud SpannerのNull Filtered INDEXの用途を考察する 〜サブタイプ実装〜&#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;Cloud SpannerのNull Filtered INDEXの用途を考察する 〜サブタイプ実装〜&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://zenn.dev/facengineer/articles/15e7a68fcc2fad&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&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;ol&gt;
&lt;li&gt;他のルートテーブルの1つにインターリーブする（ただし各ルートへの書き込みレートが十分低くなるようにする）&lt;/li&gt;
&lt;li&gt;シャーディングを使用して時系列的に連続したデータを複数のスプリットに分散する&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;この例ではPKに&lt;code&gt;ShardId&lt;/code&gt;(0~N-1)を追加する方法を紹介している。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;spanner-sharding.webp&#34; alt=&#34;spanner-sharding.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;スキーマ設計のベスト-プラクティス--spanner--google-cloud&#34;&gt;スキーマ設計のベスト プラクティス  |  Spanner  |  Google Cloud&lt;/h2&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://cloud.google.com/spanner/docs/schema-design?hl=ja&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://cloud.google.com/spanner/docs/schema-design?hl=ja&#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://docs.cloud.google.com/_static/cloud/images/social-icon-google-cloud-1200-630.png?hl=ja&#34; alt=&#34;スキーマ設計のベスト プラクティス  |  Spanner  |  Google Cloud Documentation&#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;スキーマ設計のベスト プラクティス  |  Spanner  |  Google Cloud Documentation&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://cloud.google.com/spanner/docs/schema-design?hl=ja&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;次のような場合はキー列をタイムスタンプ降順に格納することでホットスポットを回避する。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;最新の履歴を読み取る際、履歴にインターリーブ テーブルを使用しており、親行を読み取る場合&lt;/li&gt;
&lt;li&gt;連続したエントリを日付の新しい順に読み込む場合に、いつまで日付をさかのぼるか不明なとき&lt;/li&gt;
&lt;/ul&gt;
&lt;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-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;CREATE&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;TABLE&lt;/span&gt; UserAccessLog (
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;UserId     INT64 &lt;span style=&#34;color:#66d9ef&#34;&gt;NOT&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;NULL&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;LastAccess &lt;span style=&#34;color:#66d9ef&#34;&gt;TIMESTAMP&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;NOT&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;NULL&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;PRIMARY&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;KEY&lt;/span&gt; (UserId, LastAccess &lt;span style=&#34;color:#66d9ef&#34;&gt;DESC&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;筆者はこれまでこのようなケースでは&lt;code&gt;UserAccessLog&lt;/code&gt;テーブルにUUIDを付与し&lt;code&gt;LastAccess&lt;/code&gt;降順なインデックスを作成することで対応することが多かった。この方法は選択肢として持てていなかったので必要になったら思い出せるとよさそう。&lt;/p&gt;
&lt;p&gt;このケースはアクセスログなのでWRITE頻度が高いテーブルを想定していると思われる。インデックスで対応する方式と比較するとWRITEコストを下げることができる点でメリットがありそう。&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;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-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;CREATE&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;TABLE&lt;/span&gt; Users (
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;UserId     INT64 &lt;span style=&#34;color:#66d9ef&#34;&gt;NOT&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;NULL&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;LastAccess &lt;span style=&#34;color:#66d9ef&#34;&gt;TIMESTAMP&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;PRIMARY&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;KEY&lt;/span&gt; (UserId);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;!-- textlint-disable ja-technical-writing/sentence-length --&gt;
&lt;p&gt;このテーブルに対して次のような(インターリーブされていない &amp;amp;&amp;amp; 最初のキーが単調増加する)インデックスを作成した場合、&lt;code&gt;LastAccess&lt;/code&gt;は単調増加する値なので最後のスプリットに書き込みが集中し、ホットスポットが発生してしまう。&lt;/p&gt;
&lt;!-- textlint-disable ja-technical-writing/sentence-length --&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-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;CREATE&lt;/span&gt; NULL_FILTERED &lt;span style=&#34;color:#66d9ef&#34;&gt;INDEX&lt;/span&gt; UsersByLastAccess &lt;span style=&#34;color:#66d9ef&#34;&gt;ON&lt;/span&gt; Users(LastAccess);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;このようなケースでは次のような対処が考えられる。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;インデックスに&lt;code&gt;ShardId&lt;/code&gt;を追加する&lt;/li&gt;
&lt;li&gt;（そもそも）インデックスをインターリーブする&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;セカンダリ-インデックス--spanner--google-cloud&#34;&gt;セカンダリ インデックス  |  Spanner  |  Google Cloud&lt;/h2&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://cloud.google.com/spanner/docs/secondary-indexes?hl=ja&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://cloud.google.com/spanner/docs/secondary-indexes?hl=ja&#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://docs.cloud.google.com/_static/cloud/images/social-icon-google-cloud-1200-630.png?hl=ja&#34; alt=&#34;セカンダリ インデックス  |  Spanner  |  Google Cloud Documentation&#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;セカンダリ インデックス  |  Spanner  |  Google Cloud Documentation&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://cloud.google.com/spanner/docs/secondary-indexes?hl=ja&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Spannerではセカンダリインデックスに次のデータが格納される。
&lt;ul&gt;
&lt;li&gt;ベーステーブルのすべてのキー列&lt;/li&gt;
&lt;li&gt;インデックスに含まれるすべての列&lt;/li&gt;
&lt;li&gt;&lt;code&gt;STORING&lt;/code&gt;句で指定されたすべての列&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;null値の並び替え順&#34;&gt;NULL値の並び替え順&lt;/h3&gt;
&lt;p&gt;Spannerでは&lt;code&gt;NULL&lt;/code&gt;を最小値として扱う。そのため昇順の場合は&lt;code&gt;NULL&lt;/code&gt;が先頭に、降順の場合は末尾に並ぶ。&lt;/p&gt;
&lt;h3 id=&#34;末尾のレコードの取得&#34;&gt;末尾のレコードの取得&lt;/h3&gt;
&lt;p&gt;次のようなクエリを実行する場合は結果をすばやく取得することができる。これはSpannerがテーブルの行を&lt;code&gt;PRIMARY_KEY&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-sql&#34; data-lang=&#34;sql&#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 style=&#34;color:#66d9ef&#34;&gt;CREATE&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;TABLE&lt;/span&gt; Songs (
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    SongId INT64 &lt;span style=&#34;color:#66d9ef&#34;&gt;NOT&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;NULL&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;PRIMARY&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;KEY&lt;/span&gt; (SongId);
&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:#66d9ef&#34;&gt;SELECT&lt;/span&gt; SongId &lt;span style=&#34;color:#66d9ef&#34;&gt;FROM&lt;/span&gt; Songs &lt;span style=&#34;color:#66d9ef&#34;&gt;LIMIT&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;しかしSpannerではテーブル全体をスキャンしないと列の最大値を取得することができないため次のようなクエリはすばやく結果を返さない。&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-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;SELECT&lt;/span&gt; SongId &lt;span style=&#34;color:#66d9ef&#34;&gt;FROM&lt;/span&gt; Songs &lt;span style=&#34;color:#66d9ef&#34;&gt;ORDER&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;BY&lt;/span&gt; SongId &lt;span style=&#34;color:#66d9ef&#34;&gt;DESC&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;LIMIT&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;このようなケースでは次のようにPK降順のインデックスを明示的に作成することで読み取りパフォーマンスを向上させることができる。&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-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;CREATE&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;INDEX&lt;/span&gt; SongIdDesc &lt;span style=&#34;color:#66d9ef&#34;&gt;On&lt;/span&gt; Songs(SongId &lt;span style=&#34;color:#66d9ef&#34;&gt;DESC&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;sharding-of-timestamp-ordered-data-in-cloud-spanner---googblogscom&#34;&gt;Sharding of timestamp-ordered data in Cloud Spanner - googblogs.com&lt;/h2&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://www.googblogs.com/sharding-of-timestamp-ordered-data-in-cloud-spanner/&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://www.googblogs.com/sharding-of-timestamp-ordered-data-in-cloud-spanner/&#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;Sharding of timestamp-ordered data in Cloud Spanner - googblogs.com&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;By Karthi Thyagarajan, Solutions Architect Cloud Spanner was designed from the ground up to offer horizontal scalability and a developer-friendly SQL interface. As a managed service, Google Cloud handles most database management tasks, but it’s up to you to ensure that there are no hotspots, as described in Schema Design Best Practices and Optimizing Schema Design for Cloud Spanner. In this article, we’ll look at how to efficiently insert and retrieve records with timestamp ordering. We’ll start with the high-level guidance provided in Anti-pattern: timestamp ordering and explore the scenario in more detail with a concrete example. Scenario Let’s say we’re building an app that logs user activity along with timestamps and also allows users to query this activity by user id and time range. A good primary key for the table storing user activity (let’s call it LogEntries) is (UserId, Timestamp), as this gives us a uniform distribution of activity logs. Cloud Spanner inserts log entries sequentially, but they’re naturally sharded by UserId, resulting in uniform key distribution. Table LogEntries UserId (PK) Timestamp (PK) LogEntry 15b7bd1f-8473 2018-05-01T15:16:03.386257Z Here’s a sample query to retrieve a list of log entries by user and time range:SELECT UserId, Timestamp, LogEntry FROM LogEntries WHERE UserID = &amp;#39;15b7bd1f-8473&amp;#39; AND Timestamp BETWEEN &amp;#39;2018-05-01T15:14:10.386257Z&amp;#39; AND &amp;#39;2018-05-01T15:16:10.386257Z&amp;#39;; This query takes advantage of the primary key and thus performs well. Now let’s make things more interesting. What if we wanted to group users by the company they work for so we can segment reports by company? This is a fairly common use case for Cloud Spanner, especially with multi-tenant SaaS applications. To support this, we create a table with the following schema.Table LogEntries CompanyId (PK) UserId (PK) Timestamp (PK) LogEntry Acme 15b7bd1f-8473 2018-05-01T15:16:03.386257Z And here’s the corresponding query to retrieve the log entries: SELECT CompanyId, UserId, Timestamp, LogEntry FROM LogEntries WHERE CompanyID = &amp;#39;Acme&amp;#39; AND UserID = &amp;#39;15b7bd1f-8473&amp;#39; AND Timestamp BETWEEN &amp;#39;2018-05-01T15:14:10.386257Z&amp;#39; AND &amp;#39;2018-05-01T15:16:10.386257Z&amp;#39;; Here’s the query to retrieve log entries by CompanyId and time range (user field not specified):SELECT CompanyId, UserId, Timestamp, LogEntry FROM LogEntries WHERE CompanyID = &amp;#39;Acme&amp;#39; AND Timestamp BETWEEN &amp;#39;2018-05-01T15:14:10.386257Z&amp;#39; AND &amp;#39;2018-05-01T15:16:10.386257Z&amp;#39;; To support the above query, we add a separate, secondary index. Initially, we include just two columns:CREATE INDEX LogEntriesByCompany ON UserActivity(CompanyId, Timestamp) Challenge: hotspots during inserts The challenge here is that some companies may have a lot more (orders of magnitude more) users than others, resulting in a very skewed distribution of log entries. The challenge is particularly acute during inserts as described in the opening paragraph above. And even if Cloud Spanner helps out by creating additional splits, nodes that service new splits become hotspots due to uneven key distribution. The above diagram depicts a scenario where Company B has three times more users than Company A or Company C. Therefore, log entries corresponding to Company B grow at a higher rate, resulting in the hotspotting of nodes that service the splits where Company B’s log entries are being inserted. Hotspot mitigation There are multiple aspects to our hotspot mitigation strategy: schema design, index design and querying. Let’s look at each of these below. Schema and index design  As described in Anti-pattern: timestamp ordering, we’ll use application-level sharding to distribute data evenly. Let’s look at one particular approach for our scenario: instead of (CompanyId, UserId, Timestamp), we’ll use (UserId, CompanyId, Timestamp).Table LogEntries (reorder columns CompanyId and UserId in Primary Key) UserId (PK) CompanyId (PK) Timestamp (PK) LogEntry 15b7bd1f-8473 Acme 2018-05-01T15:16:03.386257Z By placing UserId before CompanyId in the primary key, we can mitigate the hotspots caused by the non-uniform distribution of log entries across companies. Now let’s look at the secondary index on CompanyId and timestamp. Since this index is meant to support queries that specify just CompanyId and timestamp, we cannot address the distribution problem by simply incorporating UserId. Keep in mind that indexes are also susceptible to hotspots and we need to design them so that their distribution is uniform. To address this, we’ll add a new column, EntryShardId, where (in pseudo-code): entryShardId = hash(CompanyId &amp;#43; timestamp) % num_shards The hash function here could be a simple crc32 operation. Here’s a python snippet illustrating how to calculate this hash function before a log entry is inserted:... import datetime import zlib ... timestamp = datetime.datetime.utcnow() companyId = &amp;#39;Acme&amp;#39; entryShardId = (zlib.crc32(companyId &amp;#43; timestamp.isoformat()) &amp;amp; 0xffffffff) % 10 ... In this case, num_shards = 10. You can adjust this value based on the characteristics of your workload. For instance, if one company in our scenario generates 100 times more log entries on average than the other companies, then we would pick 100 for num_shards in order to achieve a uniform distribution across entries from all companies. This hashing approach essentially takes the sequential, timestamp-ordered LogEntriesByCompany index entries for a particular company and distributes them across multiple application (or logical) shards. In this case, we have 10 such shards per company, resulting from the crc32 and modulo operations shown above.Table LogEntries (with EntryShardId added) CompanyId (PK) UserId (PK) Timestamp (PK) EntryShardId LogEntry ‘Acme’ 1 2018-05-01T15:16:03.386257Z 8 And the index: CREATE INDEX LogEntriesByCompany ON LogEntries(EntryShardId, CompanyId, Timestamp) Querying Evenly distributing data using a sharding approach is great for inserts but how does it affect retrieval? Application-level sharding is no good to us if we cannot retrieve the data efficiently. Let’s look at how we would query for a list of log entries by CompanyId and time range, but without UserId:SELECT CompanyId, UserId, Timestamp, LogEntry FROM LogEntries@{FORCE_INDEX=LogEntriesbyCompany} WHERE CompanyId = &amp;#39;Acme&amp;#39; AND ShardedEntryId BETWEEN 0 AND 9 AND Timestamp &amp;gt; &amp;#39;2018-05-01T15:14:10.386257Z&amp;#39; AND Timestamp The above query illustrates how to perform a timestamp range retrieval while taking sharding into account. By including the ShardedEntryId in the query above, we tell Spanner to ‘look’ in all 10 logical shards to retrieve the timestamp entries for CompanyId ‘Acme’ for a particular range. Cloud Spanner is a full-featured relational database service that relieves you of most—but not all—database management tasks. For more information on Cloud Spanner management best practices, check out the recommended reading.Anti-pattern: timestamp orderingOptimizing Schema Design for Cloud SpannerBest Practices for Schema Design&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://www.googblogs.com/sharding-of-timestamp-ordered-data-in-cloud-spanner/&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;タイムスタンプ順に並んだレコードをいかに効率よく挿入、取得するかについての解説記事。&lt;/p&gt;
&lt;h3 id=&#34;レコードの挿入時&#34;&gt;レコードの挿入時&lt;/h3&gt;
&lt;p&gt;次のようにCompanyID、UserID、Timestampの3つのキーを持つログテーブルがあるとする。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;CompanyId(PK)&lt;/th&gt;
&lt;th&gt;UserId(PK)&lt;/th&gt;
&lt;th&gt;Timestamp(PK)&lt;/th&gt;
&lt;th&gt;LogEntry&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Acme&lt;/td&gt;
&lt;td&gt;15b7bd1f-8473&lt;/td&gt;
&lt;td&gt;2018-05-01T15:16:03.386257Z&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;このスキーマにしたがって単純にデータを挿入していくとユーザー数が多い企業があるとホットスポットが発生してしまう。&lt;/p&gt;
&lt;p&gt;そのための次のような疑似コードで表現できる&lt;code&gt;EntryShardId&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-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;entryShardId &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; hash(CompanyId &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; timestamp) &lt;span style=&#34;color:#f92672&#34;&gt;%&lt;/span&gt; num_shards
&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;次のようなインデックスを追加する。&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-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;CREATE&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;INDEX&lt;/span&gt; LogEntriesByCompany &lt;span style=&#34;color:#66d9ef&#34;&gt;ON&lt;/span&gt; LogEntries(EntryShardId, CompanyId, &lt;span style=&#34;color:#66d9ef&#34;&gt;Timestamp&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-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;SELECT&lt;/span&gt; CompanyId, UserId, &lt;span style=&#34;color:#66d9ef&#34;&gt;Timestamp&lt;/span&gt;, LogEntry
&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;FROM&lt;/span&gt; LogEntries&lt;span style=&#34;color:#f92672&#34;&gt;@&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;{&lt;/span&gt;FORCE_INDEX&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;LogEntriesByCompany&lt;span style=&#34;color:#960050;background-color:#1e0010&#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;WHERE&lt;/span&gt; CompanyId &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;Acme&amp;#39;&lt;/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;AND&lt;/span&gt; EntryShardId &lt;span style=&#34;color:#66d9ef&#34;&gt;BETWEEN&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;AND&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;9&lt;/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;AND&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Timestamp&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;2018-05-01T15:14:10.386257Z&amp;#39;&lt;/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;AND&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Timestamp&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;2018-05-01T15:16:10.386257Z&amp;#39;&lt;/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;ORDER&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;BY&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Timestamp&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;DESC&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;こうすることでインデックスを使って10個の論理シャードから条件にあったレコードを効率よく取得することができる。&lt;/p&gt;
&lt;h3 id=&#34;余談&#34;&gt;余談&lt;/h3&gt;
&lt;p&gt;前章のクエリのWHERE句内で以下のように&lt;code&gt;CompanyId, EntryShardId&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-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   &lt;span style=&#34;color:#66d9ef&#34;&gt;WHERE&lt;/span&gt; CompanyId &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;Acme&amp;#39;&lt;/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;AND&lt;/span&gt; EntryShardId &lt;span style=&#34;color:#66d9ef&#34;&gt;BETWEEN&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;AND&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;9&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;任意のGoogle CloudプロジェクトでSpannerインスタンスを作成し、以下のDDLを実行してテーブルとインデックスを作成する。&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-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;CREATE&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;TABLE&lt;/span&gt; LogEntries (
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  CompanyId STRING(&lt;span style=&#34;color:#ae81ff&#34;&gt;36&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;NOT&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;NULL&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  UserId STRING(&lt;span style=&#34;color:#ae81ff&#34;&gt;36&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;NOT&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;NULL&lt;/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;Timestamp&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;TIMESTAMP&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;NOT&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;NULL&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  EntryShardId INT64 &lt;span style=&#34;color:#66d9ef&#34;&gt;NOT&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;NULL&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  LogEntry STRING(&lt;span style=&#34;color:#66d9ef&#34;&gt;MAX&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;NOT&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;NULL&lt;/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;PRIMARY&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;KEY&lt;/span&gt; (CompanyId, UserId, &lt;span style=&#34;color:#66d9ef&#34;&gt;Timestamp&lt;/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;CREATE&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;INDEX&lt;/span&gt; LogEntriesByCompany &lt;span style=&#34;color:#66d9ef&#34;&gt;ON&lt;/span&gt; LogEntries(EntryShardId, CompanyId, &lt;span style=&#34;color:#66d9ef&#34;&gt;Timestamp&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;次にテストデータをINSERTする。&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;シャード数&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Companyの数&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;従業員数&lt;/td&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;上記の条件で合計1000レコードを挿入するINSERT文を作成した。（スクリプトは&lt;a href=&#34;https://gist.github.com/kyu08/a751344fd76d4e50208164378a822dc1&#34; target=&#34;_blank&#34; &gt;こちら&lt;/a&gt;）&lt;/p&gt;
&lt;h4 id=&#34;クエリの実行&#34;&gt;クエリの実行&lt;/h4&gt;
&lt;p&gt;これに対して次の2つのクエリを実行し、実行計画を確認した。&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-sql&#34; data-lang=&#34;sql&#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 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;  CompanyId,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  UserId,
&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;Timestamp&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  LogEntry
&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;FROM&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  LogEntries&lt;span style=&#34;color:#f92672&#34;&gt;@&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;{&lt;/span&gt;FORCE_INDEX&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;LogEntriesByCompany&lt;span style=&#34;color:#960050;background-color:#1e0010&#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;WHERE&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  CompanyId &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;amazon&amp;#39;&lt;/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;AND&lt;/span&gt; EntryShardId &lt;span style=&#34;color:#66d9ef&#34;&gt;BETWEEN&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;AND&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;9&lt;/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;AND&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Timestamp&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;2023-01-01T00:00:00.386257Z&amp;#39;&lt;/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;AND&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Timestamp&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;2023-01-01T00:00:05.386257Z&amp;#39;&lt;/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;ORDER&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;BY&lt;/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;Timestamp&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;DESC&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-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- CompanyId, EntryShardIdの順番を逆にしてみたクエリ
&lt;/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;SELECT&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  CompanyId,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  UserId,
&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;Timestamp&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  LogEntry
&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;FROM&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  LogEntries&lt;span style=&#34;color:#f92672&#34;&gt;@&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;{&lt;/span&gt;FORCE_INDEX&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;LogEntriesByCompany&lt;span style=&#34;color:#960050;background-color:#1e0010&#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;WHERE&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  EntryShardId &lt;span style=&#34;color:#66d9ef&#34;&gt;BETWEEN&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;AND&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;9&lt;/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;AND&lt;/span&gt; CompanyId &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;amazon&amp;#39;&lt;/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;AND&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Timestamp&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;2023-01-01T00:00:00.386257Z&amp;#39;&lt;/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;AND&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Timestamp&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;2023-01-01T00:00:05.386257Z&amp;#39;&lt;/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;ORDER&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;BY&lt;/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;Timestamp&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;DESC&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;結論からいうとどちらのクエリでも同様にインデックスを利用できていた。おそらくSpannerのオプティマイザがいい感じに判断してくれていると思われる。以下が実際の実行計画。&lt;/p&gt;
&lt;p&gt;記事で紹介されていたクエリ
&lt;img src=&#34;original.webp&#34; alt=&#34;original.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;CompanyId, EntryShardIdの順番を逆にしてみたクエリ
&lt;img src=&#34;swap.webp&#34; alt=&#34;swap.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;cloud-spanner-におけるトランザクションのロックについて&#34;&gt;Cloud Spanner におけるトランザクションのロックについて&lt;/h2&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://cloud.google.com/blog/ja/products/databases/transaction-locking-in-cloud-spanner&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://cloud.google.com/blog/ja/products/databases/transaction-locking-in-cloud-spanner&#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://storage.googleapis.com/gweb-cloudblog-publish/images/10_-_Databases.max-2600x2600.jpg&#34; alt=&#34;Cloud Spanner におけるトランザクションのロックについて | Google Cloud 公式ブログ&#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;Cloud Spanner におけるトランザクションのロックについて | Google Cloud 公式ブログ&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://cloud.google.com/blog/ja/products/databases/transaction-locking-in-cloud-spanner&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Spanner におけるトランザクションのロックの粒度は、セル、つまり行と列の交点となります。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;なのでREAD, WRITEの範囲(行および列)を最小限にすることでロック範囲を最小限にすることができる。結果として他のトランザクションに与えるパフォーマンス影響を最小限にすることができる。&lt;/p&gt;
&lt;p&gt;他には複数のトランザクションが同時に実行された際の優先度について詳しく解説してあった。&lt;/p&gt;
&lt;h2 id=&#34;spanner-の読み取りと書き込みのライフサイクル--google-cloud&#34;&gt;Spanner の読み取りと書き込みのライフサイクル  |  Google Cloud&lt;/h2&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://cloud.google.com/spanner/docs/whitepapers/life-of-reads-and-writes?hl=ja&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://cloud.google.com/spanner/docs/whitepapers/life-of-reads-and-writes?hl=ja&#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://docs.cloud.google.com/_static/cloud/images/social-icon-google-cloud-1200-630.png?hl=ja&#34; alt=&#34;Spanner の読み取りと書き込みの有効期間  |  Google Cloud Documentation&#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;Spanner の読み取りと書き込みの有効期間  |  Google Cloud Documentation&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://cloud.google.com/spanner/docs/whitepapers/life-of-reads-and-writes?hl=ja&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;Spannerのレプリカセットの構成については次の記事が非常にわかりやすい。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://zenn.dev/facengineer/articles/bca8790087b0e4&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://zenn.dev/facengineer/articles/bca8790087b0e4&#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://res.cloudinary.com/zenn/image/upload/s--_d0bBcdy--/c_fit%2Cg_north_west%2Cl_text:notosansjp-medium.otf_55:Cloud%2520Spanner%25E3%2581%25AE%25E3%2582%25B9%25E3%2583%2597%25E3%2583%25AA%25E3%2583%2583%25E3%2583%2588%25E5%2588%2586%25E6%2595%25A3%25E3%2582%2592%25E3%2582%258F%25E3%2581%258B%25E3%2581%25A3%25E3%2581%259F%25E6%25B0%2597%25E3%2581%25AB%25E3%2581%25AA%25E3%2582%258B%2Cw_1010%2Cx_90%2Cy_100/g_south_west%2Cl_text:notosansjp-medium.otf_37:kngnr%2Cx_203%2Cy_121/g_south_west%2Ch_90%2Cl_fetch:aHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL3plbm4tdXNlci11cGxvYWQvYXZhdGFyLzc3YmY1NTZjODYuanBlZw==%2Cr_max%2Cw_90%2Cx_87%2Cy_95/v1627283836/default/og-base-w1200-v2.png?_a=BACAGSGT&#34; alt=&#34;Cloud Spannerのスプリット分散をわかった気になる&#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;Cloud Spannerのスプリット分散をわかった気になる&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://zenn.dev/facengineer/articles/bca8790087b0e4&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;読み込みおよび書き込み時のロックの取り方について詳しく解説されていた。&lt;/p&gt;
&lt;h3 id=&#34;読み取り専用トランザクション&#34;&gt;読み取り専用トランザクション&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ロックを取得せずに実行できるため高速&lt;/li&gt;
&lt;li&gt;ステイル読み込みを使用できる場合はより高速にすることができる（他のオペレーションに与えるパフォーマンス影響も抑えることができる）
&lt;ul&gt;
&lt;li&gt;Spannerはレプリカへの同期を10秒ごとに行っているため、10秒以上前のデータをステイル読み込みできる場合は読み取りのスループットをさらに高めることができる。&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;書き込む行に対して排他ロックを取得する&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ちなみに複数のトランザクションが同時に実行された場合の挙動については次の記事が詳しかった。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://cloud.google.com/blog/ja/products/databases/transaction-locking-in-cloud-spanner&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://cloud.google.com/blog/ja/products/databases/transaction-locking-in-cloud-spanner&#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://storage.googleapis.com/gweb-cloudblog-publish/images/10_-_Databases.max-2600x2600.jpg&#34; alt=&#34;Cloud Spanner におけるトランザクションのロックについて | Google Cloud 公式ブログ&#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;Cloud Spanner におけるトランザクションのロックについて | Google Cloud 公式ブログ&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://cloud.google.com/blog/ja/products/databases/transaction-locking-in-cloud-spanner&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;h2 id=&#34;sql-のベスト-プラクティス--spanner--google-cloud&#34;&gt;SQL のベスト プラクティス  |  Spanner  |  Google Cloud&lt;/h2&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://cloud.google.com/spanner/docs/sql-best-practices?hl=ja&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://cloud.google.com/spanner/docs/sql-best-practices?hl=ja&#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://docs.cloud.google.com/_static/cloud/images/social-icon-google-cloud-1200-630.png?hl=ja&#34; alt=&#34;SQL のベスト プラクティス  |  Spanner  |  Google Cloud Documentation&#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;SQL のベスト プラクティス  |  Spanner  |  Google Cloud Documentation&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://cloud.google.com/spanner/docs/sql-best-practices?hl=ja&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;h3 id=&#34;クエリパラメータの使用&#34;&gt;クエリパラメータの使用&lt;/h3&gt;
&lt;p&gt;クエリパラメータを使用することで次のメリットがある。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;キャッシュが容易になるためクエリのパフォーマンスが向上する&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;文字列の値をエスケープする必要がないため構文エラーのリスクが減る&lt;/li&gt;
&lt;li&gt;SQLインジェクションを防ぐことができる&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;範囲キーのルックアップを最適化する&#34;&gt;範囲キーのルックアップを最適化する&lt;/h3&gt;
&lt;p&gt;キーのリストが短く、連続していない場合は次のように&lt;code&gt;IN UNNEST&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-sql&#34; data-lang=&#34;sql&#34;&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 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;FROM&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Table&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;AS&lt;/span&gt; t
&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;WHERE&lt;/span&gt; t.&lt;span style=&#34;color:#66d9ef&#34;&gt;Key&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;IN&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;UNNEST&lt;/span&gt; (&lt;span style=&#34;color:#f92672&#34;&gt;@&lt;/span&gt;KeyList)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;キーのリストが連続して範囲内である場合には次のように下限と上限を設定する。&lt;code&gt;[@min, @max]&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-sql&#34; data-lang=&#34;sql&#34;&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 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;FROM&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Table&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;AS&lt;/span&gt; t
&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;WHERE&lt;/span&gt; t.&lt;span style=&#34;color:#66d9ef&#34;&gt;Key&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;BETWEEN&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;@&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;min&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;AND&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;@&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;max&lt;/span&gt;
&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;h4 id=&#34;可能な限りインターリーブされたテーブルのデータを主キーによって結合する&#34;&gt;可能な限りインターリーブされたテーブルのデータを主キーによって結合する&lt;/h4&gt;
&lt;p&gt;インターリーブされた子行とそのルート行は基本的に同じスプリットに格納されるためローカルで結合することができ、効率的に結合できるため。&lt;/p&gt;
&lt;h4 id=&#34;結合の順序を強制する&#34;&gt;結合の順序を強制する&lt;/h4&gt;
&lt;p&gt;Spanner側の最適化によって結合順序が変更され（この場合は&lt;code&gt;Singers JOIN Albums&lt;/code&gt;と記述したが&lt;code&gt;Albums JOIN Singers&lt;/code&gt;の順序に変更されたケース）パフォーマンスが低下した場合などは&lt;code&gt;FORCE_JOIN_ORDER&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-sql&#34; data-lang=&#34;sql&#34;&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 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;FROM&lt;/span&gt; Singers &lt;span style=&#34;color:#66d9ef&#34;&gt;AS&lt;/span&gt; s &lt;span style=&#34;color:#66d9ef&#34;&gt;JOIN&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;@&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;{&lt;/span&gt;FORCE_JOIN_ORDER&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;TRUE&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;}&lt;/span&gt; Albums &lt;span style=&#34;color:#66d9ef&#34;&gt;AS&lt;/span&gt; a
&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;ON&lt;/span&gt; s.SingerId &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; a.Singerid
&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;WHERE&lt;/span&gt; s.LastName &lt;span style=&#34;color:#66d9ef&#34;&gt;LIKE&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;%x%&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;AND&lt;/span&gt; a.AlbumTitle &lt;span style=&#34;color:#66d9ef&#34;&gt;LIKE&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;%love%&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;joinアルゴリズムを指定する&#34;&gt;JOINアルゴリズムを指定する&lt;/h4&gt;
&lt;p&gt;次のように&lt;code&gt;JOIN_METHOD&lt;/code&gt;ヒントを使用することでJOINアルゴリズムを指定することができる。&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-sql&#34; data-lang=&#34;sql&#34;&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 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;FROM&lt;/span&gt; Singers s &lt;span style=&#34;color:#66d9ef&#34;&gt;JOIN&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;@&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;{&lt;/span&gt;JOIN_METHOD&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;HASH_JOIN&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;}&lt;/span&gt; Albums &lt;span style=&#34;color:#66d9ef&#34;&gt;AS&lt;/span&gt; a
&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;ON&lt;/span&gt; a.SingerId &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; a.SingerId
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;JOINアルゴリズムについては次の記事が詳しい。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://zenn.dev/facengineer/articles/cc0cab5c7e9a1c#join%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://zenn.dev/facengineer/articles/cc0cab5c7e9a1c#join%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0&#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://res.cloudinary.com/zenn/image/upload/s--0QeUHHkH--/c_fit%2Cg_north_west%2Cl_text:notosansjp-medium.otf_55:Cloud%2520Spanner%25E3%2581%25AE%25E3%2583%2591%25E3%2583%2595%25E3%2582%25A9%25E3%2583%25BC%25E3%2583%259E%25E3%2583%25B3%25E3%2582%25B9%25E3%2583%2581%25E3%2583%25A5%25E3%2583%25BC%25E3%2583%258B%25E3%2583%25B3%25E3%2582%25B0%25E3%2581%25AE%25E5%258B%2598%25E6%2589%2580%2Cw_1010%2Cx_90%2Cy_100/g_south_west%2Cl_text:notosansjp-medium.otf_37:kngnr%2Cx_203%2Cy_121/g_south_west%2Ch_90%2Cl_fetch:aHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL3plbm4tdXNlci11cGxvYWQvYXZhdGFyLzc3YmY1NTZjODYuanBlZw==%2Cr_max%2Cw_90%2Cx_87%2Cy_95/v1627283836/default/og-base-w1200-v2.png?_a=BACAGSGT&#34; alt=&#34;Cloud Spannerのパフォーマンスチューニングの勘所&#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;Cloud Spannerのパフォーマンスチューニングの勘所&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://zenn.dev/facengineer/articles/cc0cab5c7e9a1c#join%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;h3 id=&#34;likeの代わりにstarts_withを使用する&#34;&gt;&lt;code&gt;LIKE&lt;/code&gt;の代わりに&lt;code&gt;STARTS_WITH&lt;/code&gt;を使用する&lt;/h3&gt;
&lt;p&gt;Spannerはパラメータ化された&lt;code&gt;LIKE&lt;/code&gt;パターンを実行時まで評価しないのですべての行を読み取ったうえで&lt;code&gt;LIKE&lt;/code&gt;式で評価し、一致しない行を除外するためパフォーマンスが悪い。&lt;/p&gt;
&lt;p&gt;適切なインデックスが作成されている場合は&lt;code&gt;LIKE&lt;/code&gt;の代わりに&lt;code&gt;STARTS_WITH&lt;/code&gt;を使用するとSpannerはクエリ実行プランをより効率的に最適化することができる。&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-sql&#34; data-lang=&#34;sql&#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 style=&#34;color:#66d9ef&#34;&gt;SELECT&lt;/span&gt; a.AlbumTitle &lt;span style=&#34;color:#66d9ef&#34;&gt;FROM&lt;/span&gt; Albums a
&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;WHERE&lt;/span&gt; a.AlbumTitle &lt;span style=&#34;color:#66d9ef&#34;&gt;LIKE&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;@&lt;/span&gt;like_clause;
&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:#66d9ef&#34;&gt;SELECT&lt;/span&gt; a.AlbumTitle &lt;span style=&#34;color:#66d9ef&#34;&gt;FROM&lt;/span&gt; Albums a
&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;WHERE&lt;/span&gt; STARTS_WITH(a.AlbumTitle, &lt;span style=&#34;color:#f92672&#34;&gt;@&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;prefix&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;クエリ実行プラン--spanner--google-cloud&#34;&gt;クエリ実行プラン  |  Spanner  |  Google Cloud&lt;/h2&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://cloud.google.com/spanner/docs/query-execution-plans?hl=ja&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://cloud.google.com/spanner/docs/query-execution-plans?hl=ja&#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://docs.cloud.google.com/_static/cloud/images/social-icon-google-cloud-1200-630.png?hl=ja&#34; alt=&#34;クエリ実行プラン  |  Spanner  |  Google Cloud Documentation&#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;クエリ実行プラン  |  Spanner  |  Google Cloud Documentation&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://cloud.google.com/spanner/docs/query-execution-plans?hl=ja&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;CPUの消費量が多いクエリの場合、実行計画は30日間保存されている。&lt;/p&gt;
&lt;p&gt;確認方法は以下。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://cloud.google.com/spanner/docs/tune-query-with-visualizer?hl=ja#view-sampled-queries&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://cloud.google.com/spanner/docs/tune-query-with-visualizer?hl=ja#view-sampled-queries&#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://docs.cloud.google.com/_static/cloud/images/social-icon-google-cloud-1200-630.png?hl=ja&#34; alt=&#34;クエリプラン ビジュアライザーを使用したクエリのチューニング  |  Spanner  |  Google Cloud Documentation&#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;クエリプラン ビジュアライザーを使用したクエリのチューニング  |  Spanner  |  Google Cloud Documentation&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://cloud.google.com/spanner/docs/tune-query-with-visualizer?hl=ja#view-sampled-queries&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;まとめ&#34;&gt;まとめ&lt;/h2&gt;
&lt;p&gt;Spannerの気持ちが少しわかった。すごく強引にまとめると以下のようなポイントが重要そう。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ホットスポットに注意する&lt;/li&gt;
&lt;li&gt;結合コストを最小限にする&lt;/li&gt;
&lt;li&gt;スキャン行数を最小限にする&lt;/li&gt;
&lt;li&gt;ロック範囲を最小限にする&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これまで漫然とドキュメントを読んで頭に入らなかったり記憶が定着しなかったりしたが、ブログにアウトプットしながら読むと理解度も定着度も（モチベーションも）上がるのでやってよかった。&lt;/p&gt;
&lt;p&gt;次はCloud Runとも仲良くなりたい。&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;①ルートテーブル②インターリーブされたテーブル③インターリーブの子を持たない通常のテーブルの3種類だと思い込んでいたが③は①として扱われるようだ。&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>
    
    <item>
      <title>forkしたrepositoryのremoteを最新化しつつローカルにpullするスクリプトを書いた</title>
      <link>https://blog.kyu08.com/posts/gh-sync-remote-and-pull/</link>
      <pubDate>Mon, 02 Sep 2024 15:54:12 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/posts/gh-sync-remote-and-pull/</guid>
      <description>前提 ghコマンドがインストールされていること デフォルトブランチにいること tl;dr # forkしたrepositoryのremoteを更新しつつpul</description>
      <content>&lt;h2 id=&#34;前提&#34;&gt;前提&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;gh&lt;/code&gt;コマンドがインストールされていること&lt;/li&gt;
&lt;li&gt;デフォルトブランチにいること&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;tldr&#34;&gt;tl;dr&lt;/h2&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# forkしたrepositoryのremoteを更新しつつpullする&lt;/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;function&lt;/span&gt; git-sync&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;    REPO&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;git remote get-url origin | sed -E &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;s%.+github.com/(.*).git$%\1%&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;🔄 Syncing &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;REPO&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;...\\n&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    gh repo sync &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;REPO&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; git pull
&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;alias gsy&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;git-sync
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;嬉しさ&#34;&gt;嬉しさ&lt;/h2&gt;
&lt;p&gt;もともとは以下の2ステップだったが前述のスクリプトを使うと1ステップにまとめることができる。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;ブラウザで&lt;code&gt;Sync fork &amp;gt; Update branch&lt;/code&gt;をクリック&lt;/li&gt;
&lt;li&gt;ローカルで&lt;code&gt;git pull&lt;/code&gt;を実行&lt;/li&gt;
&lt;/ol&gt;
</content>
    </item>
    
    <item>
      <title>ブラウザからforkすると遅いのでCLIからfork &amp; cloneするスクリプトを書いた</title>
      <link>https://blog.kyu08.com/posts/gh-repo-fork-script/</link>
      <pubDate>Sun, 18 Aug 2024 06:52:01 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/posts/gh-repo-fork-script/</guid>
      <description>モチベーション GitHubにホストされているOSSにPRを出す時にforkしてからローカルにcloneするが、ブラウザのforkボタンを使っ</description>
      <content>&lt;h2 id=&#34;モチベーション&#34;&gt;モチベーション&lt;/h2&gt;
&lt;!-- textlint-disable ja-technical-writing/no-doubled-joshi --&gt;
&lt;p&gt;GitHubにホストされているOSSにPRを出す時にforkしてからローカルにcloneするが、ブラウザのforkボタンを使ってforkすると時間がかかることが多くストレスに感じていた。&lt;/p&gt;
&lt;!-- textlint-enable ja-technical-writing/no-doubled-joshi --&gt;
&lt;p&gt;そのためCLI上でforkとcloneを行うスクリプトを書いた。&lt;/p&gt;
&lt;p&gt;これまでの手順は以下のような手順が必要だった。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;ブラウザでforkボタンを押す&lt;/li&gt;
&lt;li&gt;forkの完了を待つ&lt;/li&gt;
&lt;li&gt;ブラウザに表示されるcloneコマンドをコピー(&lt;code&gt;gh repo clone owner/repo&lt;/code&gt;みたいなやつ)&lt;/li&gt;
&lt;li&gt;ターミナルでコマンドを実行してforkしたリポジトリをcloneする&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;これを以下のステップでできるようにした。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;リポジトリのURLまたは&lt;code&gt;OWNER/REPO&lt;/code&gt;形式の文字列をコピー&lt;/li&gt;
&lt;li&gt;コマンドに1. で取得した文字列を渡して実行&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;つくったスクリプト&#34;&gt;つくったスクリプト&lt;/h2&gt;
&lt;p&gt;以下を&lt;code&gt;.zshrc&lt;/code&gt;などに追加すると使えるようになる。&lt;code&gt;alias&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;/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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt; git-fork-clone&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:#75715e&#34;&gt;# 入力からowner/repoを取り出す。owner/repoのような形式でもURLでもOK&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    REPO&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;echo $1 | sed -E &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;s@.+github.com/([^/]+)/([^/]+).*@\1/\2@&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;🐙 &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;REPO&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt; will be forked and cloned.\\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:#75715e&#34;&gt;# -- 以降のオプションはgit cloneに渡される&lt;/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;# See: https://cli.github.com/manual/gh_repo_fork&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    gh repo fork &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;REPO&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt; --default-branch-only --clone&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;true -- --filter&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;blob:none
&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;alias gf&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;git-fork-clone
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;前提&#34;&gt;前提&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;gh&lt;/code&gt;コマンドがインストールされていること。&lt;/p&gt;
&lt;h2 id=&#34;使い方&#34;&gt;使い方&lt;/h2&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ git-fork-clone https://github.com/cli/cli
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;上記を実行すると以下のような出力が表示され、リポジトリのforkとcloneが行われる。&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;🐙 cli/cli will be forked and cloned.
&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;✓ Created fork kyu08/cli
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Cloning into &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;cli&amp;#39;&lt;/span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;remote: Enumerating objects: 31, &lt;span style=&#34;color:#66d9ef&#34;&gt;done&lt;/span&gt;.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;remote: Counting objects: 100% &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;31/31&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;done&lt;/span&gt;.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;remote: Compressing objects: 100% &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;30/30&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;done&lt;/span&gt;.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;remote: Total &lt;span style=&#34;color:#ae81ff&#34;&gt;31&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;delta 0&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;, reused &lt;span style=&#34;color:#ae81ff&#34;&gt;10&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;delta 0&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;, pack-reused &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;from 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;Receiving objects: 100% &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;31/31&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;, 20.41 KiB | 10.20 MiB/s, &lt;span style=&#34;color:#66d9ef&#34;&gt;done&lt;/span&gt;.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;From github.com:cli/cli
&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;new branch&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;      main       -&amp;gt; upstream/main
&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;new tag&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;         v1.0.1     -&amp;gt; v1.0.1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;✓ Cloned fork
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;以下のような形式でも動く。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;git-fork-clone https://github.com/cli/cli/pulls&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git-fork-clone cli/cli&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;まとめ&#34;&gt;まとめ&lt;/h2&gt;
&lt;p&gt;また人類のOSS貢献力を加速させてしまいました。&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;code&gt;REPO=...&lt;/code&gt;の部分は &lt;a href=&#34;https://www.tutorialspoint.com/execute_bash_online.php&#34; target=&#34;_blank&#34; &gt;https://www.tutorialspoint.com/execute_bash_online.php&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>
    
    <item>
      <title>『読み手につたわる文章 - テクニカルライティング』を読んだ</title>
      <link>https://blog.kyu08.com/posts/technical-writing-book/</link>
      <pubDate>Wed, 05 Jun 2024 15:21:05 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/posts/technical-writing-book/</guid>
      <description>技術書典で購入した『読み手につたわる文章 - テクニカルライティング』を読んだので学びになったトピックについて書く。 1.2 「知らない」と書けない（P</description>
      <content>&lt;p&gt;技術書典で購入した『読み手につたわる文章 - テクニカルライティング』を読んだので学びになったトピックについて書く。&lt;/p&gt;
&lt;h2 id=&#34;12-知らないと書けないp14&#34;&gt;1.2 「知らない」と書けない（P14）&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;そして自分が対象物を思っていたより「知らない」ということに、我々は気付いていないことが多いのです。上手な絵は、対象物のことを知らないと描けません。それと同じように、分かりやすい実用文は、文章力のあるなし以前に &lt;strong&gt;対象物をよく知らないと書けない&lt;/strong&gt; のです。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;文字にすると当たり前のことのように感じるが、ブログを書いているとよく実感する。&lt;/p&gt;
&lt;!-- textlint-disable ja-technical-writing/no-doubled-joshi --&gt;
&lt;!-- textlint-disable ja-technical-writing/ja-no-weak-phrase --&gt;
&lt;p&gt;技術的な内容であれば、当然対象を理解していないと書けないし、自分の考えでさえもいざ言語化しようと思うとなかなか筆が進まないことが多い。&lt;/p&gt;
&lt;!-- textlint-enable ja-technical-writing/ja-no-weak-phrase --&gt;
&lt;!-- textlint-enable ja-technical-writing/no-doubled-joshi --&gt;
&lt;p&gt;そうした場合にはまず自分が何を言いたいのかを整理して理解するようにしている。&lt;/p&gt;
&lt;h2 id=&#34;214-いつまでに何をしてほしいのか書こうp25&#34;&gt;2.1.4 いつまでに何をしてほしいのか書こう（P25）&lt;/h2&gt;
&lt;!-- textlint-disable ja-technical-writing/ja-no-successive-word --&gt;
&lt;blockquote&gt;
&lt;p&gt;何の食べ物だか言わずにいきなり「食べて! ほら食べて!」とスプーンを差し出されると、「え、怖い。なになになに?」となって、とても素直に口を開く気にはなれませんし、食べたところで猜疑心で味もよく分かりません。そんなときは「初めて作ったプリンが思いのほか美味しくできたので一口食べて感想を教えてほしい」というように、どういう意図で読み手に何をして欲しいと思っているのかを先に説明してあげる必要があります。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;!-- textlint-enable ja-technical-writing/ja-no-successive-word --&gt;
&lt;p&gt;引用部分の前に書かれていた例示のエピソードがわかりすぎて無限に頷いてしまった。認知負荷が高い文章を読むにはエネルギーを要する。&lt;/p&gt;
&lt;p&gt;報告なのでただ把握だけしておいて欲しいのか相談がしたいので意見を求めているのかなど、読み手に求めるアクションを明示すると読み手の認知負荷が低くて良さそう。&lt;/p&gt;
&lt;p&gt;結局伝えたいことが伝わらないことには意味がないので書いて満足、ではなくドキュメントを書くことの目的を見失わないようにしていきたい。&lt;/p&gt;
&lt;h2 id=&#34;22-文書構造や文章量が適切だと分かりやすい&#34;&gt;2.2 文書構造や文章量が適切だと分かりやすい&lt;/h2&gt;
&lt;h3 id=&#34;221-大枠から始めてだんだん細かくしていこうp26&#34;&gt;2.2.1 大枠から始めてだんだん細かくしていこう（P26）&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;文章で何かを説明するときには、先に大枠を理解してもらい、それから段々細かい 内容にしていくという順番を意識しましょう。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;以前上司にレビューで指摘してもらって以来意識するようになった。&lt;/p&gt;
&lt;p&gt;コンテキストを共有していない人とコミュニケーションを取る時は特に重要だと感じている。自分と相手が持っている情報の差分を埋めるように情報を提示できるとスムーズにコミュニケーションを取れる印象がある。&lt;/p&gt;
&lt;h3 id=&#34;223-既知から未知に繋ごうp28&#34;&gt;2.2.3 既知から未知に繋ごう（P28）&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;文章を書くとき、「大枠から詳細へ」の他に意識すべきもう1つの順番は「既知から未知へ」です。
技術ドキュメントを読んでいても、最初から知らない単語や知らない概念ばかりが次から次へと出てくると、「知らないことについて説明してくれているけど、その説明がまず分からない」という状態になります。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;あまり意識したことがなかった。&lt;/p&gt;
&lt;p&gt;一度にまとまった情報量を記述したい時にはこのあたりまで意識して書くと認知負荷が減ってよさそう。&lt;/p&gt;
&lt;h2 id=&#34;24-再利用しやすい文章にする&#34;&gt;2.4 再利用しやすい文章にする&lt;/h2&gt;
&lt;h3 id=&#34;242-並列はナカグロで書かないp34&#34;&gt;2.4.2 並列はナカグロ（・）で書かない（P34）&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;文章の中で並列を表そうとして「ホーム・検索・マイページ・ヘルプのタブは非表示にできません」のようにナカグロ(・)を使っていると、再利用されて箇条書きになったときに、次のような見た目になることがあります。&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;着せかえの設定時、以下の機能は非表示にしたり、見た目を変更したりできません。
・ホーム・検索・マイページ・ヘルプのタブ
・トレンドワード機能
・ID連携機能
&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;対策として、最初から箇条書きにしておくか、読点を使うといいとのこと。&lt;/p&gt;
&lt;!-- textlint-disable --&gt;
&lt;p&gt;いつもどう書くか迷っていたが&lt;code&gt;・&lt;/code&gt;で並列関係を表現すると上記のデメリットがあるので読点を使うようにしてみようと思う。&lt;/p&gt;
&lt;!-- textlint-enable --&gt;
&lt;h3 id=&#34;244-リンクテキストをこちらにしないp35&#34;&gt;2.4.4 リンクテキストを「こちら」にしない（P35）&lt;/h3&gt;
&lt;p&gt;リンク切れになったときやテキストだけコピーされたときにリンク先がどこを指しているのかわからなくなるため、以下のようにどういったページなのかも含めて書くのがいいとのこと。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;また「詳しくは&lt;a href=&#34;https://blog.kyu08.com/BankCodeAPI/reference/&#34; &gt;Shops APIのAPIリファレンス&lt;/a&gt;をご覧ください」&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;また、読み手としてもリンクを踏む前にどんなページへ飛ばされるのかわかるというメリットも紹介されていた。&lt;/p&gt;
&lt;h2 id=&#34;まとめ&#34;&gt;まとめ&lt;/h2&gt;
&lt;p&gt;具体的な知見が理由とセットで書いてあってとても勉強になった。&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;チームで仕事をする上で認知負荷を下げる工夫の重要性を日々感じるのでこれから意識的に実践していきたい。&lt;/p&gt;
&lt;p&gt;紹介したトピック以外にもたくさんの知見が紹介されていたので気になった方はこちらからぜひ購入してみてください。 &lt;a href=&#34;https://techbookfest.org/product/3t8AGqtB65jsPtPhx6m5fr&#34; target=&#34;_blank&#34; &gt;こちら&lt;/a&gt; &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;余談だがちゃんと理由まで書かれているとスムーズに理解できるのでちゃんと背景や理由を説明するのは重要だと感じた。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;冗談です。リンクテキストにはリンクの内容がわかるようなものにしましょう。購入はこちらから。 &lt;a href=&#34;https://techbookfest.org/product/3t8AGqtB65jsPtPhx6m5fr&#34; target=&#34;_blank&#34; &gt;読み手につたわる文章 - テクニカルライティング - 技術書典マーケット&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</content>
    </item>
    
    <item>
      <title>『いちばんやさしいアジャイル開発の教本』 を読んだ</title>
      <link>https://blog.kyu08.com/posts/ichiban-yasashii-agile-no-kyouhon/</link>
      <pubDate>Sat, 25 May 2024 15:48:56 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/posts/ichiban-yasashii-agile-no-kyouhon/</guid>
      <description>2024/4からチーム異動してスクラムを実践しているチームに移ったのでアジャイル・スクラムのインプットをしたいと思い、『いちばんやさしいアジ</description>
      <content>&lt;p&gt;2024/4からチーム異動してスクラムを実践しているチームに移ったのでアジャイル・スクラムのインプットをしたいと思い、『いちばんやさしいアジャイル開発の教本』を読んだ。&lt;/p&gt;
&lt;p&gt;本書を読んで自分なりに勉強になったことをLessonごとに書いていく。（カッコ内の&lt;code&gt;Pxx&lt;/code&gt;はページを表す）&lt;/p&gt;
&lt;h2 id=&#34;lesson6-アジャイル開発とは何かp28-31&#34;&gt;Lesson6. アジャイル開発とは何か（P28-31）&lt;/h2&gt;
&lt;p&gt;「継続的に改善することが前提」なので逆にいえば作りたいものが決まっているならばアジャイル開発を採用するメリットは薄いかもしれない。&lt;/p&gt;
&lt;h2 id=&#34;lesson7-カイゼンp32&#34;&gt;Lesson7. カイゼン（P32）&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;世界で通じる日本語、&amp;ldquo;Kaizen&amp;rdquo;。このKaizenという言葉は日本においてもカタカナで &lt;strong&gt;「カイゼン」&lt;/strong&gt; と表現されており、「改善」という単語とはあえて区別されています。&lt;/p&gt;
&lt;p&gt;もともと改善という表現は「誤りや欠陥を正し、よりよいものにする」という意味があります。カイゼンは &lt;strong&gt;「いまあるものをよりよいものにしていく」&lt;/strong&gt; という精神に基づいており、より前向きで積極的なものだということがわかります。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;「カイゼン」という表記を見たことはあったが、文脈によっては「改善」とは別の単語として使われているというこれは知らなかった。&lt;/p&gt;
&lt;h2 id=&#34;lesson14-アジャイル開発の構造p56&#34;&gt;Lesson14. アジャイル開発の構造（P56）&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;マインドセット：&lt;/strong&gt; アジャイルソフトウェア開発宣言&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;マインドセットを実現するための原則：&lt;/strong&gt; アジャイル宣言の背後にある原則&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;現場での実践：&lt;/strong&gt; スクラム・XP・FDD・カンバン・モブプロなど&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;lesson17-個人と対話p66&#34;&gt;Lesson17. 個人と対話（P66）&lt;/h2&gt;
&lt;p&gt;アジャイルソフトウェア開発宣言の &lt;strong&gt;「プロセスやツールよりも個人と対話を」&lt;/strong&gt; について書いた章。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;対話と議論の違いは何でしょうか。ざっくり説明すると、議論は自分自身の目線から主張を展開するものですが、対話は相手の価値観を尊重し、ともに考えていくものです。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;プロダクト開発では不確実性が高いため、必ずしも正解がなく、あらゆる角度から課題を見つめることでより良い解決策を探っていくことが重要で、そのための有効な手段として「対話」があると解釈した。&lt;/p&gt;
&lt;p&gt;また、対話を繰り返すなかで互いの認識のズレや齟齬を発見し解消していくことで、議論の前提にズレが生まれることが減り、よりスピーディーに問題解決を行うことができるようになりそう。（これはアジャイルに限らないが）&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;このように個人を尊重し、対話をしながらチームの課題と全員で向き合うことで相互理解が進み、それぞれが異なる立場からの視点を得ることができます。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;盲目的にプロセスやツールに従うのではなく、個人との対話をして相互理解を深めることでチームが強くなる。そのようなチームでは信頼関係があり情報共有が活発に行われるため問題が起きても迅速にリカバリーできる。&lt;/p&gt;
&lt;h2 id=&#34;lesson18-動くソフトウェアp68&#34;&gt;Lesson.18 動くソフトウェア（P68）&lt;/h2&gt;
&lt;p&gt;アジャイルソフトウェア開発宣言の &lt;strong&gt;「包括的なドキュメントよりも動くソフトウェアを」&lt;/strong&gt; について書いた章。&lt;/p&gt;
&lt;p&gt;ソフトウェア開発においては課題とその解決方法を仮説として立て、実際にリリースして検証するという流れで開発を進めることが多い。&lt;/p&gt;
&lt;p&gt;細かくリリースするのではなく、機能を全て作り込んでからリリースした場合、仮説と解決策の確らしさを検証できるのが遅くなってしまう。&lt;/p&gt;
&lt;p&gt;なので、仮説を検証するために最低限必要な機能が備わっているプロダクト（MVP）を提供して仮説の検証を行うことでより素早く検証のループを回すことができる。&lt;/p&gt;
&lt;p&gt;また、いくら社内で話し合ったところで実際の顧客の反応がわかるわけではないので、一定仮説を煮詰めたらリリースして実際の反応をみることが重要そう。&lt;/p&gt;
&lt;h2 id=&#34;lesson19-顧客との協調p70&#34;&gt;Lesson.19 顧客との協調（P70）&lt;/h2&gt;
&lt;p&gt;アジャイルソフトウェア開発宣言の &lt;strong&gt;「契約交渉よりも顧客との協調を」&lt;/strong&gt; について書いた章。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;自社開発の場合はこの契約交渉はどのような形となって現れてくるのでしょうか。たとえば、顧客からのフィードバックに対して「それは仕様が悪い」「仕様通りの挙動です」というようにいまのソフトウェアの挙動が正しいことを前提として判断してしまう、といった保守的な行動として現れます。&lt;/p&gt;
&lt;p&gt;&amp;hellip;(中略)&amp;hellip;&lt;/p&gt;
&lt;p&gt;ユーザーボイスを尊重しながら、そのままいわれたとおりに開発するのではなく、その声の裏側にある本当に要望を見極めていきましょう。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;社内外からのフィードバックをフラットに受け取ってフィードバックの裏側の要求を見極めることでよりよいプロダクトを作っていけそう。&lt;/p&gt;
&lt;h2 id=&#34;lesson20-変化への対応p72&#34;&gt;Lesson.20 変化への対応（P72）&lt;/h2&gt;
&lt;p&gt;アジャイルソフトウェア開発宣言の &lt;strong&gt;「計画に従うことよりも変化への対応を」&lt;/strong&gt; について書いた章。&lt;/p&gt;
&lt;p&gt;プロダクト開発においては常に最新の情報を基に仮説をアップデートすることが重要なので事前に決めた計画通りに進めることよりも、都度変化に適用することが重要そう。(それはそうという感じだが)&lt;/p&gt;
&lt;h2 id=&#34;lesson22-自己組織化チームとリーダーシップp76&#34;&gt;Lesson.22 自己組織化チームとリーダーシップ（P76）&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;図表22-2&lt;/code&gt;が示すように自己組織化チームとはひとことでいうと「自走できるチーム」です。自分たちがなぜここにいるのかを理解し、またお互いの得意分野がわかっているため自分たちで最適なフォーメーションを組みながらビジョンへと向かっていきます。リーダーの意思決定を待つことなく自己修復的に課題を解決していく。それが自己組織化チームの底力です。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&#34;self-organizing-team.webp&#34; alt=&#34;self-organizing-team.webp&#34; loading=&#34;lazy&#34; /&gt;
『いちばんやさしいアジャイル開発の教本』P76より引用&lt;/p&gt;
&lt;p&gt;チームの振り返りなんかでも、「どうすれば自己組織化チームに近付けるか」という観点で考えてみてもいいかもしれない。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;自己組織化チームにおいて情報共有は重要な要素&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;よく透明性が大事、と聞くけどそれも個々人が自律的に行動するために情報は不可欠だからなんだろうなーと思った。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;理想的な自己組織化チームとは？&lt;/p&gt;
&lt;p&gt;(中略)
自己組織化し、それぞれのメンバーがリーダーシップを発揮できるようになると、 &lt;strong&gt;外からチームを見た際にはもはや誰がリーダーと呼ばれる役割なのかわからなくなるでしょう。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;これは自己組織化されたチームの見え方の1つとして良さそうだとおもったので心に留めておきたい。&lt;/p&gt;
&lt;h2 id=&#34;まとめ&#34;&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;まずは「自己組織化チーム」を目指していきたい。&lt;/li&gt;
&lt;li&gt;実際にアジャイルの入門書を1冊読んでみて、とはいえまずはスクラムガイドをしっかり理解した方がよさそうだと思ったので次はスクラムガイドを読み込んでいこうと思う。&lt;/li&gt;
&lt;/ul&gt;
</content>
    </item>
    
    <item>
      <title>`Process failed to start: too many open files: &#34;/opt/homebrew/bin/git&#34;`というエラーが出てNeovimのプラグインが動作しなくなる問題の回避策</title>
      <link>https://blog.kyu08.com/posts/mac-too-many-open-files/</link>
      <pubDate>Mon, 13 May 2024 04:11:01 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/posts/mac-too-many-open-files/</guid>
      <description>問題 ここ数日Neovimを使っていると、Process failed to start: too many open files: &amp;quot;/opt/homebrew/bin/git&amp;quot;といっ</description>
      <content>&lt;h2 id=&#34;問題&#34;&gt;問題&lt;/h2&gt;
&lt;p&gt;ここ数日Neovimを使っていると、&lt;code&gt;Process failed to start: too many open files: &amp;quot;/opt/homebrew/bin/git&amp;quot;&lt;/code&gt;といったエラーとともにプラグインが動作しなくなることがあり困っていた。&lt;/p&gt;
&lt;p&gt;記憶にある範囲だと&lt;a href=&#34;https://github.com/nvim-telescope/telescope.nvim&#34; target=&#34;_blank&#34; &gt;nvim-telescope/telescope.nvim&lt;/a&gt;や&lt;a href=&#34;https://github.com/akinsho/toggleterm.nvim&#34; target=&#34;_blank&#34; &gt;akinsho/toggleterm.nvim&lt;/a&gt;を使っているときにこのエラーが起きることが多かった印象。&lt;/p&gt;
&lt;h2 id=&#34;筆者の環境&#34;&gt;筆者の環境&lt;/h2&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;$ nvim --version
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;NVIM v0.9.5
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Build type: Release
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;LuaJIT 2.1.1703358377
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;利用しているプラグインは後述。&lt;/p&gt;
&lt;h2 id=&#34;回避策&#34;&gt;回避策&lt;/h2&gt;
&lt;p&gt;この記事にしたがってファイルを作成したところエラーが出なくなった。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://qiita.com/sou_lab/items/1ca051a1f3b906a23dc8&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://qiita.com/sou_lab/items/1ca051a1f3b906a23dc8&#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://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-user-contents.imgix.net%2Fhttps%253A%252F%252Fcdn.qiita.com%252Fassets%252Fpublic%252Farticle-ogp-background-afbab5eb44e0b055cce1258705637a91.png%3Fixlib%3Drb-4.0.0%26w%3D1200%26blend64%3DaHR0cHM6Ly9xaWl0YS11c2VyLXByb2ZpbGUtaW1hZ2VzLmltZ2l4Lm5ldC9odHRwcyUzQSUyRiUyRnFpaXRhLWltYWdlLXN0b3JlLnMzLmFtYXpvbmF3cy5jb20lMkYwJTJGMTY1NDglMkZwcm9maWxlLWltYWdlcyUyRjE0NzM2ODE4OTE_aXhsaWI9cmItNC4wLjAmYXI9MSUzQTEmZml0PWNyb3AmbWFzaz1lbGxpcHNlJmJnPUZGRkZGRiZmbT1wbmczMiZzPTI1MWJiNGI5MDdkYWI1ZDQyYTNhYzllOTRmZGUwNzgw%26blend-x%3D120%26blend-y%3D462%26blend-w%3D90%26blend-h%3D90%26blend-mode%3Dnormal%26mark64%3DaHR0cHM6Ly9xaWl0YS1vcmdhbml6YXRpb24taW1hZ2VzLmltZ2l4Lm5ldC9odHRwcyUzQSUyRiUyRnMzLWFwLW5vcnRoZWFzdC0xLmFtYXpvbmF3cy5jb20lMkZxaWl0YS1vcmdhbml6YXRpb24taW1hZ2UlMkY2MTQxMmE3YjhlYjUzOWJjNDhjOGMyMDVjYjBlY2RlNGIzN2Q5ZTZhJTJGb3JpZ2luYWwuanBnJTNGMTU2Mzc3MTYzNT9peGxpYj1yYi00LjAuMCZ3PTQ0Jmg9NDQmZml0PWNyb3AmbWFzaz1jb3JuZXJzJmNvcm5lci1yYWRpdXM9OCZiZz1GRkZGRkYmYm9yZGVyPTIlMkNGRkZGRkYmZm09cG5nMzImcz01NDM1N2FlYzZkODY1MDg2MzhhMTcxMGU5Y2ZkNzE2Zg%26mark-x%3D186%26mark-y%3D515%26mark-w%3D40%26mark-h%3D40%26s%3Db61af12191ef888837427d5dd76a2325?ixlib=rb-4.0.0&amp;amp;w=1200&amp;amp;fm=jpg&amp;amp;mark64=aHR0cHM6Ly9xaWl0YS11c2VyLWNvbnRlbnRzLmltZ2l4Lm5ldC9-dGV4dD9peGxpYj1yYi00LjAuMCZ3PTk2MCZoPTMyNCZ0eHQ9TWFjJUUzJTgxJUFFJUUzJTgwJThDVG9vJTIwbWFueSUyMG9wZW4lMjBmaWxlcyVFMyU4MCU4RCVFMyU4MiVBOCVFMyU4MyVBOSVFMyU4MyVCQyVFMyU4MiU5MiVFOCVBNyVBMyVFNiVCNiU4OCZ0eHQtYWxpZ249bGVmdCUyQ3RvcCZ0eHQtY29sb3I9JTIzMUUyMTIxJnR4dC1mb250PUhpcmFnaW5vJTIwU2FucyUyMFc2JnR4dC1zaXplPTU2JnR4dC1wYWQ9MCZzPWVkMzhmZWEwOTIyMWQxYzIxMGYzNDA5NWYzOTM5MTc4&amp;amp;mark-x=120&amp;amp;mark-y=112&amp;amp;blend64=aHR0cHM6Ly9xaWl0YS11c2VyLWNvbnRlbnRzLmltZ2l4Lm5ldC9-dGV4dD9peGxpYj1yYi00LjAuMCZ3PTgzOCZoPTU4JnR4dD0lNDBzb3VfbGFiJnR4dC1jb2xvcj0lMjMxRTIxMjEmdHh0LWZvbnQ9SGlyYWdpbm8lMjBTYW5zJTIwVzYmdHh0LXNpemU9MzYmdHh0LXBhZD0wJnM9MGE5YWVlODU1ODVmMDAyZjRhNzQ2ZDlhNDIxMjUzM2Q&amp;amp;blend-x=242&amp;amp;blend-y=454&amp;amp;blend-w=838&amp;amp;blend-h=46&amp;amp;blend-fit=crop&amp;amp;blend-crop=left%2Cbottom&amp;amp;blend-mode=normal&amp;amp;txt64=5qCq5byP5Lya56S-R2FqaS1MYWJv&amp;amp;txt-x=242&amp;amp;txt-y=539&amp;amp;txt-width=838&amp;amp;txt-clip=end%2Cellipsis&amp;amp;txt-color=%231E2121&amp;amp;txt-font=Hiragino%20Sans%20W6&amp;amp;txt-size=28&amp;amp;s=2b4e151676316b1328695062166862ef&#34; alt=&#34;Macの「Too many open files」エラーを解消 - Qiita&#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;Macの「Too many open files」エラーを解消 - Qiita&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;「Too many open files」と出てで、ファイルが保存できないことがあった。 Railsを起動して、Gulpも起動してほげほげしてるとよく起こる。 Sublime Textでこのエラーが出ると設定も何もかも保存されないし、HotExitも効かないし、ファイルは開...&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://qiita.com/sou_lab/items/1ca051a1f3b906a23dc8&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;以下記事より引用。&lt;/p&gt;
&lt;blockquote&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;sudo vi /Library/LaunchDaemons/limit.maxfiles.plist
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;viでもnanoでもcodeでもお好きなエディタのコマンドで下記コードをコピペ。&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-xml&#34; data-lang=&#34;xml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;?xml version=&amp;#34;1.0&amp;#34; encoding=&amp;#34;UTF-8&amp;#34;?&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:#75715e&#34;&gt;&amp;lt;!DOCTYPE plist PUBLIC &amp;#34;-//Apple//DTD PLIST 1.0//EN&amp;#34; &amp;#34;http://www.apple.com/DTDs/PropertyList-1.0.dtd&amp;#34;&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;plist&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;version=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;1.0&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&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;dict&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;key&amp;gt;&lt;/span&gt;Label&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/key&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;string&amp;gt;&lt;/span&gt;limit.maxfiles&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/string&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;key&amp;gt;&lt;/span&gt;ProgramArguments&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/key&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;array&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;string&amp;gt;&lt;/span&gt;launchctl&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/string&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;string&amp;gt;&lt;/span&gt;limit&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/string&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;string&amp;gt;&lt;/span&gt;maxfiles&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/string&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;string&amp;gt;&lt;/span&gt;524288&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/string&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;string&amp;gt;&lt;/span&gt;524288&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/string&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;/array&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;key&amp;gt;&lt;/span&gt;RunAtLoad&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/key&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;true/&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;key&amp;gt;&lt;/span&gt;ServiceIPC&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/key&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;false/&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;/dict&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;/plist&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/blockquote&gt;
&lt;h2 id=&#34;参考&#34;&gt;参考&lt;/h2&gt;
&lt;p&gt;同時に開くことができるファイル数の上限に引っかかってしまっている模様。&lt;/p&gt;
&lt;p&gt;もしかしたら一部のNeovimプラグインの特定のバージョンに原因があるのかもしれない。&lt;/p&gt;
&lt;p&gt;もしかしたらこれをみた人の参考になるかもしれないので&lt;code&gt;lazy-lock.json&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-json&#34; data-lang=&#34;json&#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;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;Comment.nvim&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;master&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;0236521ea582747b58869cb72f70ccfa967d2e89&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:#f92672&#34;&gt;&amp;#34;alpha-nvim&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;main&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;41283fb402713fc8b327e60907f74e46166f4cfd&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:#f92672&#34;&gt;&amp;#34;barbecue&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;main&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;cd7e7da622d68136e13721865b4d919efd6325ed&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:#f92672&#34;&gt;&amp;#34;bufferline.nvim&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;main&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;73540cb95f8d95aa1af3ed57713c6720c78af915&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:#f92672&#34;&gt;&amp;#34;cmp-buffer&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;main&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;3022dbc9166796b644a841a02de8dd1cc1d311fa&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:#f92672&#34;&gt;&amp;#34;cmp-look&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;master&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;971e65a6be0e75c3438fe7b176d4fc020cb89d7b&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:#f92672&#34;&gt;&amp;#34;cmp-nvim-lsp&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;main&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;5af77f54de1b16c34b23cba810150689a3a90312&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:#f92672&#34;&gt;&amp;#34;cmp-nvim-lsp-signature-help&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;main&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;3d8912ebeb56e5ae08ef0906e3a54de1c66b92f1&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:#f92672&#34;&gt;&amp;#34;cmp-nvim-lua&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;main&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;f12408bdb54c39c23e67cab726264c10db33ada8&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:#f92672&#34;&gt;&amp;#34;cmp-path&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;main&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;91ff86cd9c29299a64f968ebb45846c485725f23&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:#f92672&#34;&gt;&amp;#34;cmp-vsnip&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;main&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;989a8a73c44e926199bfd05fa7a516d51f2d2752&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:#f92672&#34;&gt;&amp;#34;copilot.vim&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;release&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;b603990a639bb4b8651d054ef8d5a8fe5db56e0c&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:#f92672&#34;&gt;&amp;#34;dial.nvim&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;master&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;27eb570085db2ef44bff4f620d3806039184651c&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:#f92672&#34;&gt;&amp;#34;fzf&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;master&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;24ff66d4a9d6889988e4d7e373f33f4098870b9e&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:#f92672&#34;&gt;&amp;#34;gitsigns.nvim&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;main&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;bc933d24a669608968ff4791b14d2d9554813a65&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:#f92672&#34;&gt;&amp;#34;gotests-vim&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;master&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;42abccb59e9889cd1ce427b11b2ffbb36f2a46a6&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:#f92672&#34;&gt;&amp;#34;gruvbox.nvim&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;main&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;dd0ab08b17d2ead7bdb4838b48e1d08034ead0f0&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:#f92672&#34;&gt;&amp;#34;harpoon&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;harpoon2&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;0378a6c428a0bed6a2781d459d7943843f374bce&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:#f92672&#34;&gt;&amp;#34;indent-blankline.nvim&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;master&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;3d08501caef2329aba5121b753e903904088f7e6&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:#f92672&#34;&gt;&amp;#34;lasterisk.nvim&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;main&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;bbcfcaeca50f686e338a03386e41645fc3305f44&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:#f92672&#34;&gt;&amp;#34;lazy.nvim&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;main&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;ebdd0499551765e6a7aba220cc8ae4e0cdb6be69&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:#f92672&#34;&gt;&amp;#34;lazygit.nvim&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;main&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;0ada6c6e7e138df92f5009b6952f4ac41248305a&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:#f92672&#34;&gt;&amp;#34;lsp-lens.nvim&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;main&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;48bb1a7e271424c15f3d588d54adc9b7c319d977&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:#f92672&#34;&gt;&amp;#34;lsp_signature.nvim&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;master&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;c6aeb2f1d2538bbdfdaab1664d9d4c3c75aa9db8&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:#f92672&#34;&gt;&amp;#34;lspkind.nvim&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;master&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;1735dd5a5054c1fb7feaf8e8658dbab925f4f0cf&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:#f92672&#34;&gt;&amp;#34;lspsaga.nvim&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;main&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;052234296f13e2705d5d290c7bd5a36d3dd81fde&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:#f92672&#34;&gt;&amp;#34;lualine.nvim&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;master&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;0a5a66803c7407767b799067986b4dc3036e1983&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:#f92672&#34;&gt;&amp;#34;mason-lspconfig.nvim&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;main&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;05744f0f1967b5757bd05c08df4271ab8ec990aa&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:#f92672&#34;&gt;&amp;#34;mason.nvim&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;main&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;751b1fcbf3d3b783fcf8d48865264a9bcd8f9b10&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:#f92672&#34;&gt;&amp;#34;neo-tree.nvim&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;v2.x&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;80dc74d081823649809f78370fa5b204aa9a853a&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:#f92672&#34;&gt;&amp;#34;noice.nvim&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;main&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;f4decbc7a80229ccc9f86026b74bdcf0c39e38a7&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:#f92672&#34;&gt;&amp;#34;nui.nvim&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;main&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;274fa89a9b4bed746647c2917091902f882509ec&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:#f92672&#34;&gt;&amp;#34;nvim-autopairs&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;master&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;14e97371b2aab6ee70054c1070a123dfaa3e217e&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:#f92672&#34;&gt;&amp;#34;nvim-bqf&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;main&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;52703d7adc3be3f7c09eea9a80c5b8caa615fb25&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:#f92672&#34;&gt;&amp;#34;nvim-cmp&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;main&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;8f3c541407e691af6163e2447f3af1bd6e17f9a3&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:#f92672&#34;&gt;&amp;#34;nvim-hlslens&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;main&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;3e8fceb2b030100857ee72741a8f48c9a1d8595e&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:#f92672&#34;&gt;&amp;#34;nvim-jdtls&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;master&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;8eb5f0dbe6e126b392ddcaf45893358619893e45&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:#f92672&#34;&gt;&amp;#34;nvim-lspconfig&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;master&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;ee450e6a9364fc740236166dd57aaca1ec7cdb48&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:#f92672&#34;&gt;&amp;#34;nvim-metals&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;main&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;c6268555d0b471262af78818f11a086ddf30688b&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:#f92672&#34;&gt;&amp;#34;nvim-navic&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;master&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;8649f694d3e76ee10c19255dece6411c29206a54&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:#f92672&#34;&gt;&amp;#34;nvim-scrollbar&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;main&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;35f99d559041c7c0eff3a41f9093581ceea534e8&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:#f92672&#34;&gt;&amp;#34;nvim-treesitter&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;master&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;4b70dde72753a179333b4bba02518d234a30510e&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:#f92672&#34;&gt;&amp;#34;nvim-ts-context-commentstring&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;main&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;a6382f744f584bbf71d0a563af789af7190aabda&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:#f92672&#34;&gt;&amp;#34;nvim-web-devicons&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;master&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;475fbcfcb6ee7c35aa33a6b6207ebd4032791d87&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:#f92672&#34;&gt;&amp;#34;plenary.nvim&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;master&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;08e301982b9a057110ede7a735dd1b5285eb341f&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:#f92672&#34;&gt;&amp;#34;pounce.nvim&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;master&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;0c044cad69571d57d8f64a41cca95332859b6abc&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:#f92672&#34;&gt;&amp;#34;sqlite.lua&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;master&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;d0ffd703b56d090d213b497ed4eb840495f14a11&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:#f92672&#34;&gt;&amp;#34;telescope-egrepify.nvim&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;master&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;728dc1b7f31297876c3a3254fc6108108b6a9e9d&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:#f92672&#34;&gt;&amp;#34;telescope-frecency.nvim&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;master&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;6b6565e6584c86ca501bdac485cbdc2ca64556e4&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:#f92672&#34;&gt;&amp;#34;telescope-fzf-native.nvim&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;main&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;9ef21b2e6bb6ebeaf349a0781745549bbb870d27&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:#f92672&#34;&gt;&amp;#34;telescope.nvim&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;master&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;fac83a556e7b710dc31433dec727361ca062dbe9&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:#f92672&#34;&gt;&amp;#34;todo-comments.nvim&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;main&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;a7e39ae9e74f2c8c6dc4eea6d40c3971ae84752d&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:#f92672&#34;&gt;&amp;#34;toggleterm.nvim&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;main&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;066cccf48a43553a80a210eb3be89a15d789d6e6&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:#f92672&#34;&gt;&amp;#34;translate.nvim&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;main&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;30cc9e9f339b61e7bd40bc1ba7af73ea193bf589&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:#f92672&#34;&gt;&amp;#34;vim-illuminate&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;master&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;e522e0dd742a83506db0a72e1ced68c9c130f185&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:#f92672&#34;&gt;&amp;#34;vim-test&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;master&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;eb5bd18d58a859e7d55d732d37e4e2b94fa50275&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:#f92672&#34;&gt;&amp;#34;vim-to-github&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;master&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;9ea9c75b6cd48bd42823a39c56a05a2ff8161536&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:#f92672&#34;&gt;&amp;#34;vim-vsnip&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;master&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;02a8e79295c9733434aab4e0e2b8c4b7cea9f3a9&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:#f92672&#34;&gt;&amp;#34;vim-vsnip-integ&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;master&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;1914e72cf3de70df7f5dde476cd299aba2440aef&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:#f92672&#34;&gt;&amp;#34;yode-nvim&amp;#34;&lt;/span&gt;: { &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;develop&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;eaf3141b919c143ebf174d7ad180abd9c032b38c&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;</content>
    </item>
    
    <item>
      <title>CS50.jpでCSに入門した</title>
      <link>https://blog.kyu08.com/posts/cs50-jp/</link>
      <pubDate>Sun, 12 May 2024 06:32:42 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/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>
    
    <item>
      <title>tmux-fzfを使ってwindow切り替えをできるようにする手順</title>
      <link>https://blog.kyu08.com/posts/tmux-fzf-window/</link>
      <pubDate>Wed, 10 Apr 2024 14:12:22 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/posts/tmux-fzf-window/</guid>
      <description>これはなに こんな感じでtmuxでwindowをfzfで切り替えられるようにするための設定方法 手順 .tmux.confに以下を追記 set -g @plugin &amp;#39;tmux-plugins/tpm&amp;#39; # す</description>
      <content>&lt;h2 id=&#34;これはなに&#34;&gt;これはなに&lt;/h2&gt;
&lt;p&gt;こんな感じでtmuxでwindowをfzfで切り替えられるようにするための設定方法&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.kyu08.com/posts/my-dev-setup-terminal/tmux-fzf.gif&#34; alt=&#34;https://blog.kyu08.com/posts/my-dev-setup-terminal/tmux-fzf.gif&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;手順&#34;&gt;手順&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;.tmux.conf&lt;/code&gt;に以下を追記&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-tmux&#34; data-lang=&#34;tmux&#34;&gt;set -g @plugin &amp;#39;tmux-plugins/tpm&amp;#39; # すでにある場合は不要
set -g @plugin &amp;#39;sainnhe/tmux-fzf&amp;#39;
bind-key &amp;#34;space&amp;#34; run-shell -b &amp;#34;${HOME}/.tmux/plugins/tmux-fzf/scripts/window.sh switch&amp;#34; # `prefix + space`で起動

run &amp;#39;~/.tmux/plugins/tpm/tpm&amp;#39; # すでにある場合は不要
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;prefix + I&lt;/code&gt;でtpm経由でプラグインをインストール(&lt;code&gt;prefix + i&lt;/code&gt;ではないので注意)&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
</content>
    </item>
    
    <item>
      <title>クラムシェルでMacを使っているとき用のマイクとしてEarPodsを買った</title>
      <link>https://blog.kyu08.com/posts/mac-clamshell-mode-best-mic-earpods/</link>
      <pubDate>Sat, 30 Mar 2024 15:00:38 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/posts/mac-clamshell-mode-best-mic-earpods/</guid>
      <description>前提 社でバーチャルオフィスツールとしてGatherを使っており、就業中は基本的にずっとログインしているため急に話しかけられることがある 普段は</description>
      <content>&lt;h2 id=&#34;前提&#34;&gt;前提&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;社でバーチャルオフィスツールとしてGatherを使っており、就業中は基本的にずっとログインしているため急に話しかけられることがある
&lt;ul&gt;
&lt;li&gt;普段はマイクをオフにしておき、話しかけられた時だけONにしている&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;机ができるだけスッキリするのが好きなので画像のようにMacをクラムシェルモードで使っている
&lt;ul&gt;
&lt;li&gt;Macのマイクは使えないのでAirPods Proをマイクとして使っている&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&#34;desk-without-earpods.webp&#34; alt=&#34;desk-without-earpods.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;課題&#34;&gt;課題&lt;/h2&gt;
&lt;p&gt;同僚に話しかけられた時には&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;AirPods Proを装着&lt;/li&gt;
&lt;li&gt;BluetoothでMacに接続されるのを待つ&lt;/li&gt;
&lt;li&gt;GatherのマイクをONにする&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;という手順が必要なのだが、AirPods Proの接続を待つ必要があるので話かけられた相手を待たせてしまう。(話しかけられてから話せるようになるまでだいたい5秒くらい)&lt;/p&gt;
&lt;h2 id=&#34;解決策&#34;&gt;解決策&lt;/h2&gt;
&lt;p&gt;EarPods(AirPodsではなく)を買ってMacに常時接続しておくことで話しかけられたらGatherのマイクをONにするだけで話せるようにした。&lt;/p&gt;
&lt;p&gt;これにより話しかけられてから1秒弱くらいで話せる状態にできるようになった。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;desk-with-earpods.webp&#34; alt=&#34;desk-with-earpods.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;特に音質が悪かったり声が聞きづらいみたいなFBはもらっていないので今のところ特に問題はなさそう。&lt;/p&gt;
</content>
    </item>
    
    <item>
      <title>GitHub Issuesをサイトのコメント欄として活用できるutterancesを導入した</title>
      <link>https://blog.kyu08.com/posts/add-comment-section-to-this-blog/</link>
      <pubDate>Sun, 17 Mar 2024 13:06:40 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/posts/add-comment-section-to-this-blog/</guid>
      <description>このブログにコメント欄を設置した。 utterance/utterancesというGitHubのIssuesへのコメントを記事のコメント欄とし</description>
      <content>&lt;p&gt;このブログにコメント欄を設置した。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/utterance/utterances&#34; target=&#34;_blank&#34; &gt;utterance/utterances&lt;/a&gt;というGitHubのIssuesへのコメントを記事のコメント欄として使えるようにしてくれるOSSのツールを使っている。&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;/p&gt;
&lt;ol&gt;
&lt;li&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;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://utteranc.es/&#34; target=&#34;_blank&#34; &gt;https://utteranc.es/&lt;/a&gt;でscriptタグを生成&lt;/li&gt;
&lt;li&gt;生成したタグをブログに埋め込む&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;だけだったので10分くらいでできて大変お手軽だった。&lt;/p&gt;
&lt;p&gt;(自分はこのブログのリポジトリのissueをコメント用に使いたくなかったのでそれ用のリポジトリを作成したが、もし既存のリポジトリを使う場合は&lt;code&gt;1.&lt;/code&gt;は不要)&lt;/p&gt;
&lt;p&gt;ぜひご自由にコメントを残していってください。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.orhun.dev/&#34; target=&#34;_blank&#34; &gt;https://blog.orhun.dev/&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;a href=&#34;https://github.com/kyu08/blog-comments&#34; target=&#34;_blank&#34; &gt;https://github.com/kyu08/blog-comments&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</content>
    </item>
    
    <item>
      <title>『ベタープログラマ』 を読んだ</title>
      <link>https://blog.kyu08.com/posts/better-programmer/</link>
      <pubDate>Wed, 06 Mar 2024 15:27:45 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/posts/better-programmer/</guid>
      <description>『ベタープログラマ』を読んだので自分的に刺さった点をまとめる。 6章 航路を航行する 新たなメンバーが開発チームに参加する際にどのようにすれば速や</description>
      <content>&lt;p&gt;『ベタープログラマ』を読んだので自分的に刺さった点をまとめる。&lt;/p&gt;
&lt;h2 id=&#34;6章-航路を航行する&#34;&gt;6章 航路を航行する&lt;/h2&gt;
&lt;p&gt;新たなメンバーが開発チームに参加する際にどのようにすれば速やかに生産的になることができるかについての章。&lt;/p&gt;
&lt;p&gt;最善な策はすでにプロジェクトへの理解があるメンバーに導いてもらうこと。もしそれができなければ次のようなことを調べるとよい。&lt;/p&gt;
&lt;h4 id=&#34;ソースの取得の容易さ&#34;&gt;ソースの取得の容易さ&lt;/h4&gt;
&lt;p&gt;ソースの取得がどれだけ簡単か。健全なプログラムはコードベース全体を得るための単一のチェックアウトのみを必要とする。&lt;/p&gt;
&lt;h4 id=&#34;コードのビルドの容易さ&#34;&gt;コードのビルドの容易さ&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;一般的でないツールにビルドが依存していないか&lt;/li&gt;
&lt;li&gt;コード自身に適切で簡単なドキュメンテーションがあるか&lt;/li&gt;
&lt;li&gt;手作業なしで1つのコマンドでビルドを行うことができか&lt;/li&gt;
&lt;li&gt;コードの一部に取り組んでいるときにその部分だけをビルドできるか&lt;/li&gt;
&lt;li&gt;ビルド中に潜在的な問題を曖昧にしているかもしれない無数の警告が出ていないか&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;テスト&#34;&gt;テスト&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;単体テスト・インテグレーションテスト・システム全体のテストがどの程度揃っているか&lt;/li&gt;
&lt;li&gt;テストは自動で実行されるか。あるいは追加のビルドステップを必要とするか&lt;/li&gt;
&lt;li&gt;テストはどれだけ頻繁に実行されているか&lt;/li&gt;
&lt;li&gt;カバレッジはどの程度か&lt;/li&gt;
&lt;li&gt;テストは適切できちんと作成されているか&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;コードとテストには普遍的な関連性がある。優れたテストが存在するコードはたいていきちんとリファクタリングされ、きちんと考え尽くされている。&lt;/p&gt;
&lt;h4 id=&#34;ファイルの構造&#34;&gt;ファイルの構造&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;ディレクトリの構造が領域・サブシステム・コードの階層を明確に表しているか&lt;/li&gt;
&lt;li&gt;ディレクトリの構造が整っているか&lt;/li&gt;
&lt;li&gt;サードパーティのライブラリはプロジェクトのコードからきちんと分離されているか&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;ドキュメンテーション&#34;&gt;ドキュメンテーション&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;ドキュメンテーションは存在するか。わかりやすく、かつメンテナンスされているか&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;要件&#34;&gt;要件&lt;/h4&gt;
&lt;p&gt;プロジェクトの要件文書あるいは機能仕様書があるか。&lt;/p&gt;
&lt;h4 id=&#34;プロジェクトの依存物&#34;&gt;プロジェクトの依存物&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;コードは特定のFWやライブラリを使っているか。それらについてどの程度学ぶ必要があるか&lt;/li&gt;
&lt;li&gt;コードが言語の標準ライブラリをうまく利用しているか&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;コードの品質&#34;&gt;コードの品質&lt;/h4&gt;
&lt;p&gt;品質の感触を得るためにざっと目を通す。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;コードのコメントの量と質はどうか&lt;/li&gt;
&lt;li&gt;多くのデッドコードがあるか&lt;/li&gt;
&lt;li&gt;コーディングのスタイルは全体にわたって首尾一貫しているか&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;アーキテクチャ&#34;&gt;アーキテクチャ&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;ここまでの項目を通して主となる階層群を特定できるか&lt;/li&gt;
&lt;li&gt;それらの階層がきれいに分離されているか&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;上記を実施すれば素早くプロジェクトについて把握できる。
では実際にプロジェクトに取り組む際にはどのようにすればいいか。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;やってみて学ぶ
&lt;ul&gt;
&lt;li&gt;コードを読むことは読むことにすぎない。実際に取り組んでみて、間違いを犯すことによってのみコードベースを学ぶことができる&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;何か単純で小さな修正から着手する&lt;/li&gt;
&lt;li&gt;コードを点検する
&lt;ul&gt;
&lt;li&gt;コード検査ツールをコードベースに対して実行してみる&lt;/li&gt;
&lt;li&gt;コンパイルの警告が無効にされいないか調べる。無効にされていれば有効にして警告が表示されないようにコードを修正する。それによってコードベースの構造と品質の理解を深めることができる&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;調査、そして行動
&lt;ul&gt;
&lt;li&gt;コードの小さな部分を調べ、批評してみる。弱点がないか調べ、容赦なくリファクタリングする。正しい命名に修正したり、長いコードを小さくて適正な命名をもつ関数に切り出す&lt;/li&gt;
&lt;li&gt;このような作業を数回行うことで、コードにどれだけの柔軟性があり修正や変更に対してどれだけ従順であるかの感触を得ることができる&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;維持管理
&lt;ul&gt;
&lt;li&gt;ソースファイルを整頓したりディレクトリ階層を正しくしたりする&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;わかったことを文書化する
&lt;ul&gt;
&lt;li&gt;コードに取り組み始める方法を説明しているトップレベルのREADMEは存在するか。しなければ作成してこれまでに学んだことを書く&lt;/li&gt;
&lt;li&gt;そのドキュメンテーションを経験のあるプログラマにレビューしてもらう&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;新たなコードベースに取り組むほど、新たなコードを効果的に学ぶことができる。&lt;/p&gt;
&lt;p&gt;この章はプロジェクトのキャッチアップに必要な観点が多く記述されていてとても参考になった。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;新しくプロジェクトに参加した際(業務・OSS関わらず)&lt;/li&gt;
&lt;li&gt;既存のプロジェクトの課題点を整理する際&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;などのタイミングで特に参考にできそう。&lt;/p&gt;
&lt;h2 id=&#34;14章-ソフトウェア開発とは&#34;&gt;14章 ソフトウェア開発とは&lt;/h2&gt;
&lt;blockquote&gt;
&lt;h3 id=&#34;ソフトウェア開発は退屈な仕事&#34;&gt;ソフトウェア開発は退屈な仕事&lt;/h3&gt;
&lt;p&gt;ソフトウェア開発の仕事の多くは、楽しくありません。魅力的でもありません。(中略)有能なプログラマであるためには、退屈な仕事を恐れてはいけません。(中略)時には、私達はソフトウェアの清掃員にならなければならず、次のことが求められます。&amp;hellip;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;自分が学生のときには想像できていなかったソフトウェアエンジニアの現実、という感じがする。学生のときには毎日コードを書けるなんて夢みたいだ！と思っていたけれど、実際には楽しくない仕事もあるしコードを書かない日もある。ただ、自分が見てきた優秀なエンジニアたちはそういった仕事であっても着実に丁寧に素早くこなしていた印象がある。&lt;/p&gt;
&lt;p&gt;あと、このところは&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;チームとして成果を出すためにはどうすればいいか&lt;/li&gt;
&lt;li&gt;身の回りの人から信頼される振る舞いとはどのようなものだろう&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;を意識して行動するようにしていて、自分にとってタスクが楽しいかや成長に繋がるかということをいい意味で意識せずに仕事ができている。この意識を持つようにしてから仕事が楽しく感じられるようになったので自分にとってもかなりいい変化だった思う。&lt;/p&gt;
&lt;h2 id=&#34;15章-規則に従って競技する&#34;&gt;15章 規則に従って競技する&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;自分達で決めた&lt;/strong&gt;規則が必要です。私達が所有権を持つ規則です。特定のチームにおける文化、およびうまく開発できる方法を定めている規則です。これらは、大きくて、扱いにくい厳しい規則である必要はありません。新たなチームメンバーがすぐに一緒に開発できるように、単純なものでよいです。つまり、それらは単なる方法やプロセスよりも詳しく何かを記述している規則であったり、コーディング文化を記述している規則だったりします。すなわち、&lt;strong&gt;チームで優れた選手になるための方法を記述している規則です。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;この &lt;strong&gt;「チームで優れた選手になるための方法を記述している規則です。」&lt;/strong&gt; という部分が特にいいなと思った。チームメンバーとして活躍する方法が言語化されていることで、新しいメンバーが素早く立ち上がることができるだけでなく、すでにチームに所属しているメンバーもことあるごとに立ち返ることができて、方向性がずれかけてもうまく軌道修正できるなどのメリットがありそう。&lt;/p&gt;
&lt;p&gt;個人的にチームで共通理解を持つことでチームの方向性がうまく揃い、軌道修正もしやすかった経験を部活のときにしたのでこの章の内容はとても腹落ちした。&lt;/p&gt;
&lt;h2 id=&#34;18章-変わらないものはない&#34;&gt;18章 変わらないものはない&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;コードのどの領域も、誰にも「所有」されていません。どの領域でも、誰もが変更を行うことが許されています。コードを所有するといった制度は避けてください。それは、変更を抑制します。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;サーバーサイドの開発チームに初めて異動したときは「自分よりもサーバーサイドも経験が長いエンジニアたちが書いたコードだからどの部位も意図があり、設計も練られた上で今の実装になってるに違いない&amp;hellip;！だから強い理由がないとなかなか変更を加えるべきではないのではないか」という思い込みがあったが、何ヶ月かサーバーサイドの開発の経験を積んで「なんか全然自分でも修正できそうなところあるぞ・・・！」と感じられるようになった。&lt;/p&gt;
&lt;p&gt;いい意味でフラットな目線でコードベースに触れる意識を持てるとよさそう。&lt;/p&gt;
&lt;h2 id=&#34;28章-倫理的なプログラマ&#34;&gt;28章 倫理的なプログラマ&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;プログラミングのキャリアの中で、最も頻繁に出会う人々は、チームメイトです。彼らは、毎日一緒に働くプログラマやテスターなどです。倫理的なプログラマは、彼ら全員と一緒に誠実に働き、各チームメンバーに敬意を払って、できる限り最善の結果を達成することに注意を払っています。&lt;/p&gt;
&lt;p&gt;どれだけ成熟しているとか経験を積んでいるとかに関係なく、誰もが貢献できる価値を持っていることを常に信じてください。&lt;/p&gt;
&lt;p&gt;誠実で信頼されるようになってください。誰にでも誠意を持って接してください。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;大事。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;倫理的なプログラマは、燃え尽きるような働き方をしません。それは、個人的に不都合であるだけではなく、チーム全体に対しても悪い影響を与えます。毎週、何十時間も残業すれば、疲れ切ったプログラマになり、必ず不注意な間違いを生み出し、悪い結果となります。驚くほど熱心に働く英雄のように思われるのは素晴らしいですが、倫理的なプログラマは、非現実的な期待に応えようとして、自身が燃え尽きてしまうのは悪い考えであることを理解しています。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;直感では理解できるが、プロジェクトの種類によっては残業の量が成果に直結することもあり難しい。残業を最後の手段にしつつ必要なときはやる、くらいの感覚がいいのだろうか。(残業前提でスケジュールを組み出すと工夫をする発想がなくなり、効率が上がらず長期的には損だと思う。もちろん燃え尽きリスクが高まるという面でもそう。)&lt;/p&gt;
&lt;p&gt;あとは現実的にビジネス的に絶対に守りたい締切があることはあると思う。現場レイヤー目線だと踏ん張りどこは頑張って、乗り切ったら少し休むようにし、マネジメントレイヤー目線だとそうならないように人員計画をいい感じにするとかがいいのだろうか（？）&lt;/p&gt;
&lt;p&gt;ただ、チームをマネジメントする立場からみると長期間安定して働いてくれることも一定嬉しいとは思うので無理をしすぎないことも重要そう。&lt;/p&gt;
&lt;h2 id=&#34;結び&#34;&gt;結び&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;ひどいプログラマと優れたプログラマを区別しているものは、態度です。それが、単なる適当なプログラマと並外れたプログラマを区別するものです。&lt;/p&gt;
&lt;p&gt;態度は、技術スキルに勝ります。プログラミング言語の複雑な知識は、保守可能なコードを保証しません。プログラミングのモデルを多く理解したからといって、必ずしも優れた設計を生み出すとは限りません。あなたのコードが優れているかどうかと、あなたと一緒に働くのが楽しいのかどうかを決めるのは、あなたの態度なのです。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;この記述がこの本を通して特に刺さった。シンプルだがとても重要なことだと思う。「何ができるか」も重要だが、それ以上に「どうしたいか」や「どこを目指しているのか」がより重要なのだろうと思った。ついついハードスキルばかりに目がいってしまうがそういった志向性を持つことにも同様に気を配りたい。&lt;/p&gt;
&lt;p&gt;自分が見てきた優秀なエンジニアはこれを体現している人ばかりだったように思う。&lt;/p&gt;
&lt;p&gt;最悪技術力の不足はレビューなどで他のエンジニアの力を借りて補うことができても、オーナーシップや主体性に限っては自分自身で持つしかない。&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;そういった意味でもどのようにすれば良い態度を保ち続けられるか、はふりかえりや環境選びの重要な観点になるように思える。&lt;/p&gt;
&lt;h2 id=&#34;感想&#34;&gt;感想&lt;/h2&gt;
&lt;p&gt;「優秀なエンジニアはどう振る舞うか」を主題に数多くのトピックが書かれていてとても参考になった。自分がこれまで接してきた優秀なエンジニアの振る舞いとも重なるところが多かった。 優秀なエンジニアがなぜ優秀かをあらゆる角度から言語化していて理解を深めることができたし、自分も真似できそうなことが多くあったので実践していきたい。&lt;/p&gt;
&lt;p&gt;次は久々に技術寄りの本を読みたくなったので次はRust関連の本を読んでみたいと思う。&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;あとは「プログラマー脳」も気になるのでいずれ読みたい。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;もちろん日々研鑽して自分の技術力を高めることも当然重要だと思っている。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;「コンセプトから理解するRust」でRustの理解を深めて「詳解Rustプログラミング」でRustで低レイヤーを学んでいこうと思っている。&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</content>
    </item>
    
    <item>
      <title>2023年を振り返る</title>
      <link>https://blog.kyu08.com/posts/looking-back-on-2023/</link>
      <pubDate>Fri, 29 Dec 2023 15:03:17 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/posts/looking-back-on-2023/</guid>
      <description>趣味 OSS貢献 今年は初めてOSS貢献1をできた年でもあった。2023年に行った貢献を種類ごとにリポジトリごとでまとめたものが以下。2 ドキュメ</description>
      <content>&lt;h2 id=&#34;趣味&#34;&gt;趣味&lt;/h2&gt;
&lt;h3 id=&#34;oss貢献&#34;&gt;OSS貢献&lt;/h3&gt;
&lt;p&gt;今年は初めてOSS貢献&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;をできた年でもあった。2023年に行った貢献を種類ごとにリポジトリごとでまとめたものが以下。&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;h4 id=&#34;ドキュメント関連&#34;&gt;ドキュメント関連&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;ratatui-org/website
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/ratatui-org/website/pull/272&#34; target=&#34;_blank&#34; &gt;chore(docs): fix broken link to showcase/apps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/ratatui-org/website/pull/271&#34; target=&#34;_blank&#34; &gt;chore(docs): fix typo in showcase/third-party-widgets&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/ratatui-org/website/pull/203&#34; target=&#34;_blank&#34; &gt;docs: Add fzf-make to showcase&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/ratatui-org/website/pull/169&#34; target=&#34;_blank&#34; &gt;docs: fix a broken link 🐛&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/ratatui-org/website/pull/136&#34; target=&#34;_blank&#34; &gt;docs: Add demo gif to tutorial/json-editor 📚&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;a-kenji/tui-term
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/a-kenji/tui-term/pull/109&#34; target=&#34;_blank&#34; &gt;chore(doc): fix typo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/a-kenji/tui-term/pull/108&#34; target=&#34;_blank&#34; &gt;chore(doc): fix typo&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;orhun/PKGBUILDs
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/orhun/PKGBUILDs/pull/10&#34; target=&#34;_blank&#34; &gt;Update fzf-make description&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;neovim/neovim
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/neovim/neovim/pull/25138&#34; target=&#34;_blank&#34; &gt;docs: replace screen.c for undo.c in src/nvim/README.md&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Homebrew/brew.sh
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/Homebrew/brew.sh/pull/971&#34; target=&#34;_blank&#34; &gt;Update Japanese translation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;cicd関連&#34;&gt;CI/CD関連&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;hashicorp/terraform
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/hashicorp/terraform/pull/34357&#34; target=&#34;_blank&#34; &gt;chore(GitHub Actions): fix inputs of Lock Threads, and bump version&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;jesseduffield/lazygit
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/jesseduffield/lazygit/pull/2952&#34; target=&#34;_blank&#34; &gt;fix Generate Sponsors README&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/jesseduffield/lazygit/pull/2950&#34; target=&#34;_blank&#34; &gt;fix GitHub Actions warnings&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;その他&#34;&gt;その他&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;rust-lang/rust-playground
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/rust-lang/rust-playground/pull/992&#34; target=&#34;_blank&#34; &gt;Update outdated links&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;biomejs/biome
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/biomejs/biome/pull/224&#34; target=&#34;_blank&#34; &gt;chore: rename rome_js_transform and rome_js_parser to biome_*&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/biomejs/biome/pull/205&#34; target=&#34;_blank&#34; &gt;chore: rename rome_js_unicode_table to biome_js_unicode_table biomejs#88&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/biomejs/biome/pull/170&#34; target=&#34;_blank&#34; &gt;chore: rename rome_flags to biome_flags, rome_aria_metadata tobiome_aria_metadata and rome_aria tobiome_aria biomejs#88&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;jesseduffield/lazygit
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/jesseduffield/lazygit/pull/2937&#34; target=&#34;_blank&#34; &gt;Add Makefile&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;mislav/bump-homebrew-formula-action
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/mislav/bump-homebrew-formula-action/pull/57&#34; target=&#34;_blank&#34; &gt;(docs): use environment files instead of set-output&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;2023年8月以降で20個のPRをマージしてもらうことができた！ほとんどが簡単なPRだったとはいえ感謝してもらえることも多かったので単純に嬉しかった。&lt;/p&gt;
&lt;p&gt;一定数OSSに貢献できたのは嬉しいが、ドキュメントやCIの修正など比較的ハードルが低めの貢献が多かったのも事実。&lt;/p&gt;
&lt;p&gt;流石にOSSにPRを出すことには慣れてきたので2024年は上記のような貢献もしつつ何らかのOSSのアプリケーションコードへの貢献もしていきたい。&lt;/p&gt;
&lt;p&gt;OSSメンテナ観点では、どのプロジェクトのメンテナも非常に紳士的で優しく接してくれる方が多かったので自分も見習っていきたい。特にRustコミュニティは初心者を歓迎する雰囲気があり、PRを送った際の体験がとてもよかったので真似したい。&lt;/p&gt;
&lt;h3 id=&#34;rustを書き始めた&#34;&gt;Rustを書き始めた&lt;/h3&gt;
&lt;p&gt;2023年2月&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;ごろからRustを書き始めた。きっかけはkenkooooさんのこのスライドを読んで「Elmに似てて開発者体験がよさそう」と感じたので触ってみることにした。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://speakerdeck.com/estie/man-wochi-siteshi-merurust&#34; target=&#34;_blank&#34; &gt;満を持して始める Rust&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;入門に際して以下のようなことをやった。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&#34;https://tourofrust.com/00_ja.html&#34; target=&#34;_blank&#34; &gt;Tour of Rust&lt;/a&gt;を読んでなんとなく雰囲気をつかむ&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://doc.rust-jp.rs/book-ja/&#34; target=&#34;_blank&#34; &gt;The Rust Programming Language&lt;/a&gt;を手を動かしつつ(わからないところはいったん飛ばしつつ)一通り読む&lt;/li&gt;
&lt;li&gt;RustでCLIアプリを作る&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;code&gt;3.&lt;/code&gt; で作ったアプリをOSSとして公開した。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/kyu08/fzf-make&#34; target=&#34;_blank&#34; &gt;kyu08/fzf-make&lt;/a&gt;&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h3 id=&#34;fzf-makeを公開した&#34;&gt;fzf-makeを公開した&lt;/h3&gt;
&lt;p&gt;こんな感じでMakefileに定義したtargetを曖昧検索で絞り込んで実行できるツールを作った。プレビューウィンドウがあるのが地味に便利なポイントでtargetの内容を確認しつつ実行できる。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;fzf-make-demo.gif&#34; alt=&#34;fzf-make-demo.gif&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;Rustの理解を深めるのと自分の普段の作業を効率化したくて作ったがその両方が割と達成できているので満足している。特に所有権やスマートポインタに関しては&lt;a href=&#34;https://doc.rust-jp.rs/book-ja/&#34; target=&#34;_blank&#34; &gt;The Rust Programming Language&lt;/a&gt;を読んだときにはイマイチ理解できなかったが実際に自分でコードを書いてコンパイラに指摘されてコードを修正することで理解を深めることができた。&lt;sup id=&#34;fnref: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;p&gt;最初は身近な人に紹介して使ってもらったりしていたが、ある日面識のない日本人の開発者の方がバグ報告issue&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;を立ててくれて、インターネットの向こう側の人に自分のアイディアが届いて気に入ってもらえて、しかもわざわざバグ報告をしてくれたという事実がとても嬉しかった。&lt;/p&gt;
&lt;p&gt;当然個人の趣味開発なので副業などとは違い時給を得て開発しているわけではないが、ものづくりを通して他者に喜んでもらうということが自分にとって最高の喜びだとわかっただけでも非常に良い経験だった。自分がOSSコミュニティに貢献したいと考えているのも究極は「人に喜んで欲しいから」なのかもしれない。&lt;/p&gt;
&lt;p&gt;その後も何人かの人がstarしてくれたりTwitter(現X)で言及してくれたり&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;、issueを立ててくれたり、時にはPRを送ってくれたりして自分が書いたツールを通して海外のエンジニアとも交流できたのは自分にとって非常に刺激的だった。&lt;/p&gt;
&lt;p&gt;これから開発したい機能や修正したいバグはまだまだあるので来年以降も引き続き開発を続けていきたい。Homebrewをはじめ、いくつかのパッケージマネージャでインストールできるのでぜひ使ってみてください。あとスターくれると大変嬉しいです！よろしくお願いします！&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/kyu08/fzf-make&#34; target=&#34;_blank&#34; &gt;kyu08/fzf-make&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;neovimへの寄付&#34;&gt;Neovimへの寄付&lt;/h3&gt;
&lt;p&gt;筆者はNeovimには仕事・趣味のプロジェクトなど自分が行うすべての開発に収まらずちょっとしたタスク管理やブログ執筆などあらゆる場面でとにかくお世話になっている。&lt;/p&gt;
&lt;p&gt;Neovim自体はOSSなので無償で利用できるわけだが、あるときNeovimコミュニティの成果にフリーライドに近い状態&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;になっている自分に気付いてからNeovimをはじめとしたOSSへの自分の関わり方に対し違和感を感じるようになったのでまずは経済的な支援でNeovimに貢献してみようと思い、GitHub Sponsorsを通じてNeovimに対して5$/Monthの寄付を開始した。&lt;sup id=&#34;fnref:9&#34;&gt;&lt;a href=&#34;#fn:9&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;9&lt;/a&gt;&lt;/sup&gt;&lt;sup id=&#34;fnref:10&#34;&gt;&lt;a href=&#34;#fn:10&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;10&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;冗談抜きにNeovimのメンテナあっての自分の開発生活なのでこれは来年も続けたい。(本当のところはもっと稼いでもっと寄付したい)&lt;/p&gt;
&lt;h3 id=&#34;ブログ&#34;&gt;ブログ&lt;/h3&gt;
&lt;p&gt;2023年は20個の記事を書いた。たまに「あの記事読んだよ！」的な反応をもらうことがあって嬉しかった。Twitterで話しかけたり感想を伝えてくれたりするのは嬉しいのでお待ちしています。&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;h3 id=&#34;fzf-bookmark-openerを公開した&#34;&gt;fzf-bookmark-openerを公開した&lt;/h3&gt;
&lt;p&gt;ブックマークをfzfで絞り込んで開くことができるCLIツール。自分が欲しかったので作った。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/kyu08/fzf-bookmark-opener&#34; target=&#34;_blank&#34; &gt;kyu08/fzf-bookmark-opener&lt;/a&gt;&lt;sup id=&#34;fnref:11&#34;&gt;&lt;a href=&#34;#fn:11&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;11&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;fzf-bookmark-opener-demo.gif&#34; alt=&#34;fzf-bookmark-opener-demo.gif&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;同時期に書いた&lt;a href=&#34;https://github.com/kyu08/gcp-url-generator&#34; target=&#34;_blank&#34; &gt;kyu08/gcp-url-generator&lt;/a&gt;と組み合わせて業務でよく使っている。特定のGCPプロジェクトの特定のGCPサービスのコンソールをターミナルから開きたいことが多いので重宝している。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/ktr0731/go-fuzzyfinder&#34; target=&#34;_blank&#34; &gt;ktr0731/go-fuzzyfinder&lt;/a&gt;のおかげで100行程度のコードでやりたいことが実現できて大変助かった。&lt;/p&gt;
&lt;h3 id=&#34;買ってよかったもの&#34;&gt;買ってよかったもの&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Nuphy Air60 v2&lt;/li&gt;
&lt;li&gt;klack&lt;/li&gt;
&lt;li&gt;コアラマットレスのマットレス&lt;/li&gt;
&lt;li&gt;オーダーメイド枕&lt;/li&gt;
&lt;li&gt;Salomon XT-6&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://md-holdings.com/product/list5/4977856205339.html&#34; target=&#34;_blank&#34; &gt;なすの天ぷら&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;大晦日に元気があったら記事として書きます。&lt;/p&gt;
&lt;h2 id=&#34;仕事&#34;&gt;仕事&lt;/h2&gt;
&lt;h3 id=&#34;やったこと&#34;&gt;やったこと&lt;/h3&gt;
&lt;p&gt;SaaSプロダクトのバックエンドエンジニアとして主に負債解消プロジェクトに取り組んでいた。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Scalaで書かれたアプリケーションのGoへの移行&lt;/li&gt;
&lt;li&gt;DatastoreからCloud Spannerへの移行&lt;/li&gt;
&lt;li&gt;E2Eテストの整備&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;などを行った。マイクロサービス何もわからないのでオライリーのマイクロサービス本あたりを読んで勉強したい。&lt;/p&gt;
&lt;h3 id=&#34;学びなど&#34;&gt;学びなど&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;12月ごろからこれまでよりは大きめのプロジェクトを任せてもらっている。これまで担当したプロジェクトよりは自分で考える幅が広いのもありかなり楽しく働けている。引き続きより大きな信頼を勝ち取って自分の仕事の幅を広げていけるように頑張っていきたい。&lt;/li&gt;
&lt;li&gt;ローカルでテストできる環境が整っていると開発速度が爆上がりすることを実感した。多少整備に時間がかかったとしてペイすることが多いと思うので他のプロジェクトでもうまいこと時間を確保して整備していけるとよさそう。&lt;/li&gt;
&lt;li&gt;DBに関連する色々を雰囲気でやってしまっていると自覚があるので年末年始はRDBの基礎的な原理&lt;sup id=&#34;fnref:12&#34;&gt;&lt;a href=&#34;#fn:12&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;12&lt;/a&gt;&lt;/sup&gt;や業務でメインで使っているDBであるCloud Spanner&lt;sup id=&#34;fnref:13&#34;&gt;&lt;a href=&#34;#fn:13&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;13&lt;/a&gt;&lt;/sup&gt;の理解を深めていきたい。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;2024年の抱負&#34;&gt;2024年の抱負&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;引き続き仕事をモリモリがんばる。&lt;/li&gt;
&lt;li&gt;OSS貢献を続ける。何らかのOSSのアプリケーションコードにも貢献する。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;まとめ&#34;&gt;まとめ&lt;/h2&gt;
&lt;p&gt;最後まで読んでくれてありがとうございました！良いお年を〜&lt;/p&gt;
&lt;p&gt;2024年もがんばるぞー&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;初めてOSS貢献したときの記事はこちら。 &lt;a href=&#34;../my-first-oss-contribution&#34; &gt;OSSに初めてPRを送ってマージされた話&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;a href=&#34;https://gist.github.com/kyu08/138f8d15c2badc8243ca2e126545ca36&#34; target=&#34;_blank&#34; &gt;GitHubで自分がOSSに送ってマージされたPRを集計するやつ.md&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;a href=&#34;https://github.com/kyu08/tour-of-rust&#34; target=&#34;_blank&#34; &gt;tour-of-rustのメモリポジトリ&lt;/a&gt;が2023/2頃にできていたのできっとこの頃から書き始めたはず。そういえばkeenさんのこのメモリの記事がすごくわかりやすかった。&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: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;モチベーションになるのでスターください！拡散もしてくれると泣いて喜びます！&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;そういえば&lt;a href=&#34;https://github.com/rust-lang/rustlings&#34; target=&#34;_blank&#34; &gt;rust-lang/rustlings&lt;/a&gt;というコンパイルエラーを修正していくことでRustの理解を深めるというコンセプトのリポジトリがあるので作りたいものはないがRustの理解を深めたい人にはおすすめかもしれない。（筆者はREADMEを読んだだけで触ったことはない）&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;&lt;a href=&#34;https://github.com/kyu08/fzf-make/issues/21&#34; target=&#34;_blank&#34; &gt;https://github.com/kyu08/fzf-make/issues/21&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://twitter.com/orhunp_/status/1692511841270841502&#34; target=&#34;_blank&#34; &gt;https://twitter.com/orhunp_/status/1692511841270841502&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;&lt;a href=&#34;https://twitter.com/songmu/status/897317241909157888&#34; target=&#34;_blank&#34; &gt;songmuさんも言っている&lt;/a&gt;ようにOSSを使っていることを公言することもOSSプロジェクトにとってはプラスになるとは思うが、それぐらいでは済まないくらいNeovimに自分の開発人生を豊かにしてもらっている自覚がある。&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;li id=&#34;fn:9&#34;&gt;
&lt;p&gt;初めてNeovimに寄付をしたときの話はこちら。&lt;a href=&#34;../sponsored-neovim&#34; &gt;GitHub Sponsorsを通してNeovimに寄付をした&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:9&#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:10&#34;&gt;
&lt;p&gt;ちなみにNeovimへの寄付の使途はopen collective上で公開されている。 &lt;a href=&#34;https://opencollective.com/neovim&#34; target=&#34;_blank&#34; &gt;https://opencollective.com/neovim&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:10&#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:11&#34;&gt;
&lt;p&gt;紹介記事はこちら&lt;a href=&#34;../fzf-bookmark-opener&#34; &gt;yamlに定義したbookmarkをfzfで選択してブラウザで開くCLIツールをGoで作った&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:11&#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:12&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://use-the-index-luke.com/ja&#34; target=&#34;_blank&#34; &gt;SQLのインデックスとそのチューニングについてのオンラインブック&lt;/a&gt;や &lt;a href=&#34;https://zenn.dev/suzuki_hoge/books/2022-12-database-index-9520da88d02c4f&#34; target=&#34;_blank&#34; &gt;図解 DB インデックス&lt;/a&gt;あたりを読んでみようと思っている。&amp;#160;&lt;a href=&#34;#fnref:12&#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:13&#34;&gt;
&lt;p&gt;地道に&lt;a href=&#34;https://cloud.google.com/spanner/docs/create-query-database-console?hl=ja&#34; target=&#34;_blank&#34; &gt;公式ドキュメント&lt;/a&gt;を読んでいくつもり&amp;#160;&lt;a href=&#34;#fnref:13&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</content>
    </item>
    
    <item>
      <title>『世界一流エンジニアの思考法』 を読んだ</title>
      <link>https://blog.kyu08.com/posts/how-world-class-engineers-think/</link>
      <pubDate>Sun, 19 Nov 2023 01:41:50 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/posts/how-world-class-engineers-think/</guid>
      <description>Microsoftのエンジニアとしてアメリカで働いている牛尾剛さんが優秀な同僚から学んだ思考法について書いた著書『世界一流エンジニアの思考法</description>
      <content>&lt;p&gt;&lt;img src=&#34;./book.webp&#34; alt=&#34;book&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;Microsoftのエンジニアとしてアメリカで働いている牛尾剛さんが優秀な同僚から学んだ思考法について書いた著書『世界一流エンジニアの思考法』を読んだので学びになったトピックについて簡単に書こうと思う。&lt;/p&gt;
&lt;h2 id=&#34;頭がよくても理解には時間がかかる&#34;&gt;頭がよくても「理解」には時間がかかる&lt;/h2&gt;
&lt;p&gt;ある若くて優秀な同僚が新しいプロジェクトに参加するときにアーキテクチャの説明ビデオを「難しいので何回も見直している」と言っていたのに対して著者が衝撃を受けたというエピソードが紹介されていた。&lt;/p&gt;
&lt;p&gt;なかなか他人の作業過程を観察する機会もないのでついつい「優秀な人は複雑な物事でも一瞬で理解してしまうのだろう」と想像してしまいがちだが、&lt;strong&gt;Microsoftの凄腕エンジニアでも理解に時間がかかることがある&lt;/strong&gt;という実例を知り、何だかとても励まされた気分になった。&lt;/p&gt;
&lt;p&gt;新しい技術や概念の理解に時間がかかるとついつい仮想上の優秀な人と自分を比べて「はやくインプットしてはやくアウトプットを出さなければ」と焦るのをたまにやってしまうが「&lt;strong&gt;優秀な人でも物事を正確に理解するには時間がかかることもある&lt;/strong&gt;」という心持ちでいるだけで焦らず着実にインプットしていけそうだと感じた。&lt;/p&gt;
&lt;p&gt;そうして「正確に理解している概念」が増えていくほど新しい概念を理解する速度も向上するはずなので焦らず地道に理解することに努めたい。（もちろん時間的制約があるケースもあるので一概には言えないが）&lt;/p&gt;
&lt;p&gt;このトピックに関しては以下の記事にもあるのでもし気になったら読んでみて欲しい。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://note.com/simplearchitect/n/n388201603a28&#34; target=&#34;_blank&#34; &gt;プログラミングというより物事が出来るようになる思考法｜牛尾　剛&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;完全に余談だが、優秀な人をリスペクトしすぎると「自分とあの人は違うしな・・・」と自分にはそういった人のような素晴らしいアウトプットは出せないという思い込みを持ってしまいがちなので自分を卑下せずかといって奢りもせずフラットな気持ちで自分を励ましまくっていきたい。&lt;/p&gt;
&lt;h2 id=&#34;be-lazy怠惰であれ&#34;&gt;Be Lazy(怠惰であれ)&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;より少ない時間で価値を最大化する&lt;/strong&gt;という考え方。これを体現するために習慣として次が紹介されていた。&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;望んでいる結果を達成するために、最低限の努力をする。&lt;/li&gt;
&lt;li&gt;不必要なものや付加価値のない仕事（過剰準備含む）をなくす。&lt;/li&gt;
&lt;li&gt;簡潔さを目指す。&lt;/li&gt;
&lt;li&gt;優先順位をつける。&lt;/li&gt;
&lt;li&gt;時間や費やした努力より、アウトプットと生産性に重点を置く。&lt;/li&gt;
&lt;li&gt;長時間労働しないように推奨する。&lt;/li&gt;
&lt;li&gt;会議は会議の時間内で効率的かつ生産的に価値を提供する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;自分なりに抽象化すると&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;成果にフォーカスする&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;より効率的に成果が出るように工夫する&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ということなのかなと思った。&lt;/p&gt;
&lt;p&gt;とくに自分は成果を安定的に出せているかと言われると全然そんなことはないので、まずは「成果を出すこと」次に「より効率的に成果を出すこと」というステップで意識していくと良さそうだと思った。（あまり残業しないことばかりに意識を向けると結局期待される成果がでずに会社も自分も不幸せ、という状況に陥ってしまいそう）&lt;/p&gt;
&lt;p&gt;ただ、成果を出す手段として長時間労働を第一の選択肢にしてしまうとさまざまな弊害があるとは思うのでそこは気をつけたい。&lt;/p&gt;
&lt;p&gt;長期的な生産性を高めるためには&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;振り返りをして改善し自分 / 自チームの生産性を高めること&lt;/li&gt;
&lt;li&gt;振り返りを通して得た気付きを共有して組織の生産性を高めること&lt;/li&gt;
&lt;li&gt;自分のスキルアップに一定時間を投資すること&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;あたりは大事かなと思うのでやっていきたい。&lt;/p&gt;
&lt;h2 id=&#34;タイムボックス制&#34;&gt;タイムボックス制&lt;/h2&gt;
&lt;p&gt;以下のように紹介されていた。&lt;/p&gt;
&lt;blockquote&gt;
&lt;h2 id=&#34;タイムボックス制で学習の時間を確保する&#34;&gt;タイムボックス制で、学習の時間を確保する&lt;/h2&gt;
&lt;p&gt;今までは、時短を試みても「アウトカム」重視派だったので、切りのいいところまでやろうと考えて、結局寝る直前までかかってしまうことが頻繁にあった。(中略)ソリューションは簡単だった。「タイムボックス」制だ。
例えば、5時になったら仕事が途中でも、どんなに切りが悪くても、すぐに仕事をやめる。いつの間にか時間が過ぎてしまわないよう、5時きっかりにアラームをセットして。&lt;/p&gt;
&lt;p&gt;絶対に時間をオーバーすることはないよう、しばらく無理矢理にでも「タイムボックス」で生活してみたらどうなったか？ まず、5時に強制終了するようにすると、就業後にランニングできるようになった。頭がすっきりとリフレッシュするのがわかるし、夜に本を読んだり、ギターを弾いたり、ゲームしたりする余裕が生まれた。以前はそうした時間にすごく罪悪感を感じたが、一番イケてる人たちの意見をじることにしたのだ。 タイムボックス導入と同時に朝型の生活にシフトして、必ず夜10時には寝るスタイルにしてみた。&lt;/p&gt;
&lt;p&gt;すると1週間もしないうちに、というか翌日から頭が冴えて生産性が上がった。 正直マジかよ！と思ったが、今までどれだけ働きすぎて頭の切れが鈍くなっていたかを痛感した。運動をしなければ、動物として何かがおかしくなるのも当然だし、深夜まで起きて作業したって、ろくに頭が働いていなかったのだ。人間は週40時間労働が一番生産性が上がるという説もあるし、確かに時間を区切ったほうが合理的だ。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;仕事に使える時間を定めることで「たくさん残業して気合いで解決する」みたいな解決方法が第一の選択肢となることを防ぎ、工夫や改善によって生産性を上げることに繋がり持続可能な形で開発生産性を上げる文化に繋がりそうだと思った。&lt;/p&gt;
&lt;p&gt;成果が出るならばより少ない時間でその成果が得られる方がいいのはそれはそうなので少し自分なりにアレンジして取り入れたい。具体的には「残業しすぎないように気をつける」くらいのマイルドな感じで取り入れてみようと思う。&lt;/p&gt;
&lt;p&gt;ここでの示唆は、業務だけに自分の時間を使ってしまうと&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;学習によって自分の生産性を向上させることがしずらい&lt;/li&gt;
&lt;li&gt;残業前提で成果を出すため再現性が低い&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ということだと思う。残業しすぎないことで学習の時間を確保したり、開発プロセスの改善やスコープの調整によってうまく成果を出せるようにできていることが重要なのだと思う。&lt;/p&gt;
&lt;p&gt;ときには多少残業をしないと厳しいこともあると思うし個人としても残業を1秒もしたくないというほどでもないのでこういう取り入れ方にしてみようと思った。&lt;/p&gt;
&lt;h2 id=&#34;まとめ&#34;&gt;まとめ&lt;/h2&gt;
&lt;p&gt;というわけでマインドセットだけでなく具体的なプラクティスの面でも大いに参考になる内容が多かったのでとても勉強になったので折に触れてまた読み返したい。気になった方はぜひ読んでみてください。&lt;/p&gt;
</content>
    </item>
    
    <item>
      <title>ThePrimeagen/harpoon を使ってみた</title>
      <link>https://blog.kyu08.com/posts/harpoon-review/</link>
      <pubDate>Fri, 17 Nov 2023 15:20:13 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/posts/harpoon-review/</guid>
      <description>ThePrimeagen/harpoonというNeovimプラグインを使ってみたので気になっている人の参考になればと思い感想を書いてみる。 で</description>
      <content>&lt;p&gt;&lt;a href=&#34;https://github.com/ThePrimeagen/harpoon&#34; target=&#34;_blank&#34; &gt;ThePrimeagen/harpoon&lt;/a&gt;というNeovimプラグインを使ってみたので気になっている人の参考になればと思い感想を書いてみる。&lt;/p&gt;
&lt;h2 id=&#34;できること&#34;&gt;できること&lt;/h2&gt;
&lt;p&gt;ファイルをマークしてquick_menu(マークしたファイルの一覧)からファイルを開くことができる。操作している様子は以下の通り。&lt;/p&gt;
&lt;h3 id=&#34;1-ファイルをマークして&#34;&gt;1. ファイルをマークして&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;:lua require(&amp;quot;harpoon.mark&amp;quot;).add_file()&lt;/code&gt;を実行してファイルをマーク&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;add-file.gif&#34; alt=&#34;add-file&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;2-quick_menuからファイルを開く&#34;&gt;2. quick_menuからファイルを開く&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;:lua require(&amp;quot;harpoon.ui&amp;quot;).toggle_quick_menu()&lt;/code&gt;を実行してマークしたファイル一覧からファイルを開く&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;toggle-quick-menu.gif&#34; alt=&#34;toggle-quick-menu&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;機能は他にもありそう&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;だが筆者はこの機能しか使ってないので割愛。&lt;/p&gt;
&lt;h2 id=&#34;嬉しさ&#34;&gt;嬉しさ&lt;/h2&gt;
&lt;p&gt;個人開発などファイル数が少ないプロジェクトだとそこまで効果を感じないが業務では(当然だが)一定数のファイルがあり、かつ定義ジャンプを繰り返しているとバッファにはたくさんファイルが存在しているのでtelescopeなどのfuzzy-finderプラグインを使ったとしてもファイルの行き来には多少時間がかかってしまっていた。&lt;/p&gt;
&lt;p&gt;harpoonの導入によってファイルの行き来が爆速になってかなり作業効率が爆上がりした。&lt;/p&gt;
&lt;h2 id=&#34;推しポイント&#34;&gt;推しポイント&lt;/h2&gt;
&lt;h3 id=&#34;1-マークしたファイルが一度エディタを閉じても保持される&#34;&gt;1. マークしたファイルが一度エディタを閉じても保持される&lt;/h3&gt;
&lt;p&gt;LSPが不調だったりしてNeovimを再起動することがたまにあるので地味に便利。&lt;/p&gt;
&lt;p&gt;(一度Neovimを閉じてもマークしたファイルが保持されている様子。)
&lt;img src=&#34;saved-quick-menu.gif&#34; alt=&#34;saved-quick-menu&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;2-自由に編集できる-quick_menu&#34;&gt;2. 自由に編集できる quick_menu&lt;/h3&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;quick_menuは純粋なテキストなので自由に編集できる。&lt;/p&gt;
&lt;p&gt;つまりこんな感じで&lt;code&gt;dd&lt;/code&gt; -&amp;gt; &lt;code&gt;y&lt;/code&gt;のようなコマンドで自由に順番を入れ替えたり削除したりできる。普段のvimの操作感で扱えるのでとても直感的で使いやすくて嬉しい。&lt;/p&gt;
&lt;p&gt;quick_menuを自由に編集している様子&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;img src=&#34;editable-quick-menu.gif&#34; alt=&#34;editable-quick-menu&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;まとめ&#34;&gt;まとめ&lt;/h2&gt;
&lt;p&gt;気になった方はぜひ試してみてください。&lt;/p&gt;
&lt;p&gt;インストール方法はこちら&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://github.com/ThePrimeagen/harpoon?tab=readme-ov-file#-installation&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://github.com/ThePrimeagen/harpoon?tab=readme-ov-file#-installation&#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/5e01e04da74278bcb0a94c1c59b12eeca6ef3660ecfa6576770d497bc6135bbc/ThePrimeagen/harpoon&#34; alt=&#34;GitHub - ThePrimeagen/harpoon&#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 - ThePrimeagen/harpoon&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;Contribute to ThePrimeagen/harpoon development by creating an account on GitHub.&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://github.com/ThePrimeagen/harpoon?tab=readme-ov-file#-installation&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;h4 id=&#34;余談&#34;&gt;余談&lt;/h4&gt;
&lt;p&gt;そういえばThePrimeagenの好きな動画があるので貼っておく。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://www.youtube.com/watch?v=nMHxdz-N7EU&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://www.youtube.com/watch?v=nMHxdz-N7EU&#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;- YouTube&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;Enjoy the videos and music you love, upload original content, and share it all with friends, family, and the world on YouTube.&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://www.youtube.com/watch?v=nMHxdz-N7EU&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&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/ThePrimeagen/harpoon?tab=readme-ov-file#terminal-navigation&#34; target=&#34;_blank&#34; &gt;ターミナルを開く機能&lt;/a&gt;とか&lt;a href=&#34;https://github.com/ThePrimeagen/harpoon?tab=readme-ov-file#telescope-support&#34; target=&#34;_blank&#34; &gt;telescope&lt;/a&gt;や&lt;a href=&#34;https://github.com/ThePrimeagen/harpoon?tab=readme-ov-file#tmux-support&#34; target=&#34;_blank&#34; &gt;tmux&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;a href=&#34;https://github.com/ThePrimeagen/harpoon/issues/205#issuecomment-1241921113&#34; target=&#34;_blank&#34; &gt;https://github.com/ThePrimeagen/harpoon/issues/205#issuecomment-1241921113&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;ちなみにdemoで使っているcolorschemeは&lt;a href=&#34;https://github.com/catppuccin/nvim&#34; target=&#34;_blank&#34; &gt;catppuccin-mocha&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>『採用基準 地頭より論理的思考力より大切なもの』 を読んだ</title>
      <link>https://blog.kyu08.com/posts/saiyo-kijun/</link>
      <pubDate>Sun, 22 Oct 2023 11:00:41 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/posts/saiyo-kijun/</guid>
      <description>概要 McKinsey &amp;amp; Company出身の伊賀泰代さんがリーダーシップについて書いた『採用基準地頭より論理的思考力より大切なもの』を読んだ。ちょうど「リー</description>
      <content>&lt;h2 id=&#34;概要&#34;&gt;概要&lt;/h2&gt;
&lt;p&gt;McKinsey &amp;amp; Company出身の伊賀泰代さんがリーダーシップについて書いた『採用基準地頭より論理的思考力より大切なもの』を読んだ。ちょうど「リーダーシップとは」みたいなことが気になっていたので読んでみた。&lt;/p&gt;
&lt;p&gt;コンサルティングファームでの出来事を中心に書かれているが、ITベンチャーでエンジニアとして働く自分にも参考になる点が多かったように思う。&lt;/p&gt;
&lt;h2 id=&#34;学び&#34;&gt;学び&lt;/h2&gt;
&lt;h3 id=&#34;思考力とは&#34;&gt;思考力とは&lt;/h3&gt;
&lt;p&gt;思考力とは以下の3つの要素からなる。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;思考スキル&lt;/li&gt;
&lt;li&gt;思考意欲&lt;/li&gt;
&lt;li&gt;思考体力&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;このうち思考スキルはトレーニングなどで向上させることができるが、思考意欲と思考体力は一朝一夕で身につけることが難しいため筆者は面接時によく見ているらしい。&lt;/p&gt;
&lt;p&gt;この部分を読むまで思考力といえば思考スキルや思考体力が主だと思っていたので思考意欲という概念は自分には目新しかった。&lt;/p&gt;
&lt;h3 id=&#34;リーダーシップが全員に必要な理由&#34;&gt;リーダーシップが全員に必要な理由&lt;/h3&gt;
&lt;p&gt;多くの欧米企業が社員全員にリーダーシップを求める理由が書かれていたので引用する。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;マッキンゼーをはじめとする外資系企業の多くでは、すべての社員に高いレベルのリーダーシップを求めます。アメリカの場合は、大学や大学院の入学判定に使われる小論文でも、過去のリーダーシップ体験は常に問われる最重要項目です。(中略)全員がリーダーシップをもつ組織は、一部の人だけがリーダーシップをもつ組織より、圧倒的に高い成果を出しやすいのです。だから学校も企業も、欧米では（もしくは外資系企業では）全員にリーダーシップ体験を求めるのです。(中略)リーダーシップのある人は、「成果を出すこと」を「自説が採用されること」よりも優先します。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;「全員がリーダーシップを持つ組織」と聞くと「全員自分の意見ばかり主張していては物事が前に進まないのでは&amp;hellip;?」と考えてしまいがちだが、ここではリーダーシップを「チームの使命を達成するために、必要なことをやる人」と定義している。&lt;/p&gt;
&lt;p&gt;たしかにそう聞くと多角的な視点からよりよい意思決定ができそうな気がしてくる。チーム・組織の全員がリーダーシップを体現できれば指示待ちが起こらず、生産性が高まりそうだなと感じた。&lt;/p&gt;
&lt;h3 id=&#34;バリューを出す&#34;&gt;バリューを出す&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;まずは自分自身が期待されている(あるいは期待以上の)バリューを出すことでリーダーが最もこだわるべき成果の重要性を理解したりやそれにこだわる姿勢を身につけることができる。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;ポジションをとる&#34;&gt;ポジションをとる&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;自分はどう思うのか。情報を揃えて周りに判断を仰いでばかりではいつまでも指示待ち人間を脱することはできない。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;自分の仕事のリーダーは自分&#34;&gt;自分の仕事のリーダーは自分&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;組織図を考える時に上司が上、メンバーが下というように考えるよりは自分を中心に捉えてその周りに他のメンバーや上司やその上司などが放射状に位置していると考える。&lt;/li&gt;
&lt;li&gt;上司に決めて貰えばいいと考えるのではなく周りの人をどううまく使って自分の仕事を進めるかを考えることが大切。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;まとめ&#34;&gt;まとめ&lt;/h2&gt;
&lt;p&gt;組織の全員がリーダーシップを体現することの嬉しさを知れたのが自分にとっては大きな収穫だった。&lt;/p&gt;
&lt;p&gt;成果を意識してやっていく。&lt;/p&gt;
</content>
    </item>
    
    <item>
      <title>GitHubで自分がOSSに送ったPR一覧を表示するやつ</title>
      <link>https://blog.kyu08.com/posts/github-pr-list/</link>
      <pubDate>Sun, 22 Oct 2023 10:26:39 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/posts/github-pr-list/</guid>
      <description>稀に自分がOSSに送ったPR一覧を見たくなるのでメモ代わりに書く。 (正確には「自分所有でないpublic repositoryに送ってマージさ</description>
      <content>&lt;p&gt;稀に自分がOSSに送ったPR一覧を見たくなるのでメモ代わりに書く。 (正確には「自分所有でないpublic repositoryに送ってマージされたPR一覧」を表示する方法)&lt;/p&gt;
&lt;h2 id=&#34;tldr&#34;&gt;tl;dr&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/pulls&#34; target=&#34;_blank&#34; &gt;https://github.com/pulls&lt;/a&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-shell&#34; data-lang=&#34;shell&#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;is:pr archived:false is:closed author:@me is:public -user:@me created:2024-01-01..2024-12-31 
&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;img src=&#34;pulls.webp&#34; alt=&#34;pulls&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;余談&#34;&gt;余談&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;orgを所属組織とかに絞って検索すれば仕事の振り返りとかにも使えそう。&lt;/li&gt;
&lt;li&gt;他にも &lt;a href=&#34;https://github.com/pulls/review-requested&#34; target=&#34;_blank&#34; &gt;https://github.com/pulls/review-requested&lt;/a&gt; にいくと自分がレビュワーとしてアサインされているPR一覧が見れて便利だったりする。ターミナル上で同じようなことをやりたい人は &lt;a href=&#34;https://github.com/dlvhdr/gh-dash&#34; target=&#34;_blank&#34; &gt;dlvhdr/gh-dash&lt;/a&gt; とかもオススメかもしれない。&lt;/li&gt;
&lt;/ul&gt;
</content>
    </item>
    
    <item>
      <title>go/src/cmdでLSPが動作するようにするメモ</title>
      <link>https://blog.kyu08.com/posts/develop-go-runtime-using-1.21/</link>
      <pubDate>Mon, 11 Sep 2023 15:12:17 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/posts/develop-go-runtime-using-1.21/</guid>
      <description>gc(go compiler)のコード（具体的にはgo/src/cmd/compile配下）を読むために必要な手順があったのでメモ代わりに書いておく。</description>
      <content>&lt;p&gt;gc(go compiler)のコード（具体的には&lt;a href=&#34;https://github.com/golang/go/tree/master/src/cmd/compile&#34; target=&#34;_blank&#34; &gt;&lt;code&gt;go/src/cmd/compile&lt;/code&gt;&lt;/a&gt;配下）を読むために必要な手順があったのでメモ代わりに書いておく。neovimでしか確認していないが他のエディタでもきっと同じような感じなはず。&lt;/p&gt;
&lt;h2 id=&#34;packagesload-error-err-exit-status-2-stderr-panic-runtime-error-index-out-of-range--1--goroutine-1-running-cmdgointernallistcollectdepserrors&#34;&gt;&lt;code&gt;packages.Load error: err: exit status 2: stderr: panic: runtime error: index out of range [-1]  goroutine 1 [running]: cmd/go/internal/list.collectDepsErrors...&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;というエラーを出力してLSPが停止する。go1.21.0のバグだった模様。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://github.com/golang/go/issues/61816&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://github.com/golang/go/issues/61816&#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/9647cb688b3d9d6ab029f32776ee5c4694abad4a3321a44235fe3234173cb10d/golang/go/issues/61816&#34; alt=&#34;cmd/go: panic: runtime error: index out of range [-1] in collectDepsErrors · Issue #61816 · golang/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;cmd/go: panic: runtime error: index out of range [-1] in collectDepsErrors · Issue #61816 · golang/go&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;Related: #59905. Just observed this panic while looking into golang/vscode-go#2923: From the root directory of https://github.com/yaklang/yaklang: &amp;gt; go list -e -compiled -test ./... panic: runtime ...&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://github.com/golang/go/issues/61816&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;ローカルのgoをgo1.21.1に上げることでエラーが解決した。&lt;/p&gt;
&lt;h2 id=&#34;error-loading-workspace-folders-expected-1-got-0-failed-to-load-view-for-filepathtorepogosrccmd-err-exit-status-1-stderr-go-downloading-go122-darwinarm64-go-download-go122-for-darwinarm64-toolchain-not-available&#34;&gt;&lt;code&gt;Error loading workspace folders (expected 1, got 0) failed to load view for file:///path/to/repo/go/src/cmd: err: exit status 1: stderr: go: downloading go1.22 (darwin/arm64) go: download go1.22 for darwin/arm64: toolchain not available&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;src/cmd/go.mod&lt;/code&gt; の &lt;code&gt;go 1.22&lt;/code&gt;を&lt;code&gt;go 1.21.0&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-diff&#34; data-lang=&#34;diff&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;diff --git a/src/cmd/go.mod b/src/cmd/go.mod
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;index 1eaad916ff..da12b2adff 100644
&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;--- a/src/cmd/go.mod
&lt;/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 style=&#34;color:#a6e22e&#34;&gt;+++ b/src/cmd/go.mod
&lt;/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;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;@@ -1,6 +1,6 @@
&lt;/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; module cmd
&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;-go 1.22
&lt;/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 style=&#34;color:#a6e22e&#34;&gt;+go 1.21.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:#a6e22e&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; require (
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  github.com/google/pprof v0.0.0-20230811205829-9131a7e9cc17
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;this-file-is-within-module--which-is-not-included-in-your-workspace-to-fix-this-problem-you-can-add-a-gowork-file-that-uses-this-directory-see-the-documentation-for-more-information-on-setting-up-your-workspace-httpsgithubcomgolangtoolsblobmastergoplsdocworkspacemd&#34;&gt;&lt;code&gt;This file is within module &amp;quot;.&amp;quot;, which is not included in your workspace. To fix this problem, you can add a go.work file that uses this directory. See the documentation for more information on setting up your workspace: https://github.com/golang/tools/blob/master/gopls/doc/workspace.md.&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;リンク先のドキュメントの手順に従って&lt;code&gt;go.work&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;// src/cmd ディレクトリで
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;go work init
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;go work use ./compile
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;ということで&#34;&gt;ということで&lt;/h2&gt;
&lt;p&gt;無事LSPを動作させることができた。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;running-lsp-on-go-runtime-repository.webp&#34; alt=&#34;running-lsp-on-go-runtime-repository.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;これでgo本体のコードがサクサク読めるぞー。&lt;/p&gt;
</content>
    </item>
    
    <item>
      <title>GitHub Sponsorsを通してNeovimに寄付をした</title>
      <link>https://blog.kyu08.com/posts/sponsored-neovim/</link>
      <pubDate>Thu, 10 Aug 2023 16:35:48 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/posts/sponsored-neovim/</guid>
      <description>Neovimに対してGitHub Sponsorsを通してOne-time1の寄付をしたという話。 Neovimには仕事・趣味のプロジェクトなど</description>
      <content>&lt;p&gt;Neovimに対してGitHub Sponsorsを通してOne-time&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;Neovimには仕事・趣味のプロジェクトなど自分が行うすべての開発に収まらずちょっとしたタスク管理やブログ執筆などあらゆる場面でとにかくお世話になっている。&lt;/p&gt;
&lt;p&gt;なんでもカスタマイズしたくなってしまうこだわりの強い自分には非常にあっていて数多のプラグインを使って快適に開発を行っている。&lt;/p&gt;
&lt;p&gt;大変お世話になっているOSSプロジェクトなのでいつかPRで貢献したいな〜と思いつつ何の気なしにNeovimのリポジトリを眺めていたら「そういえばGitHub Sponsorsでの金銭的な支援も立派なcontributionじゃん！」と思ったのでとりあえず寄付することにした。&lt;/p&gt;
&lt;h2 id=&#34;案外あっさりできた&#34;&gt;案外あっさりできた&lt;/h2&gt;
&lt;p&gt;今回はひとまずOne-timeで20$だけ寄付してみることにした。&lt;/p&gt;
&lt;p&gt;初めてGitHub Sponsorsを使ってみたが必要なのは&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;請求先住所の入力&lt;/li&gt;
&lt;li&gt;クレジットカード情報の入力&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;くらいだったので5分もかからずにできた。&lt;/p&gt;
&lt;p&gt;手続きが完了するとこんな感じでSponsorsに自分のアイコンが表示される。(嬉しい)&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;sponsors.webp&#34; alt=&#34;sponsors.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;さらには自分のプロフィール画面にNeovimのアイコンが表示される。組織の一員感がでて地味にいいですねこれ。(結構嬉しい)&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;github-profile.webp&#34; alt=&#34;github-profile.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;日頃から「OSSにお世話になっている分コードを書いて恩返ししたい&amp;hellip;。けどなかなかすぐに解決できそうなissueも見当たらない&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;」みたいなことを思っていたのでまずは寄付という形でOSSに貢献できてよかった。&lt;/p&gt;
&lt;p&gt;今後はPRでもOSSコミュニティに貢献していくぞという気持ちになった。&lt;/p&gt;
&lt;h2 id=&#34;と思っていた矢先&#34;&gt;と思っていた矢先&lt;/h2&gt;
&lt;p&gt;個人開発のプロジェクトで使えそうなGitHub Actionsを物色していたところ早速自分でも修正できそうな箇所があったのでOSSに初めてPRを送ってみた。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://github.com/mislav/bump-homebrew-formula-action/pull/57&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://github.com/mislav/bump-homebrew-formula-action/pull/57&#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/2c79a32ddf4056ec77079b10cd390168cd17879da5f4b729832b88192b140a3e/mislav/bump-homebrew-formula-action/pull/57&#34; alt=&#34;(docs): use environment files instead of set-output by kyu08 · Pull Request #57 · mislav/bump-homebrew-formula-action&#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;(docs): use environment files instead of set-output by kyu08 · Pull Request #57 · mislav/bump-homebrew-formula-action&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;Thanks for creating a great workflow!
What this PR changes
This PR changes usage example in the README.md to use environment files instead of set-output because set-output is deprecated.
close #56
...&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://github.com/mislav/bump-homebrew-formula-action/pull/57&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;その時の記事はこちら。 &lt;a href=&#34;../my-first-oss-contribution&#34; &gt;OSSに初めてPRを送ってマージされた話&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;今後&#34;&gt;今後&lt;/h2&gt;
&lt;p&gt;Neovimの話に戻るが冷静にもし自分がJetBrainsのIDEユーザーだったら毎年ライセンスを購入するのは厭わないだろうにNeovimを使い倒させてもらっている自分が今回のOne-timeの寄付だけじゃ全然足りなくね？という気持ちになった。&lt;/p&gt;
&lt;p&gt;なのでこれからはJetBrainsのライセンスと同じくらいの額(10$/monthくらい？)はmonthlyで寄付していこうと思う。&lt;/p&gt;
&lt;p&gt;いずれはPRでもNeovimに貢献していきたいが、直近のPRを軽くみた感じluaやCが書けた方がよさそうだった。&lt;/p&gt;
&lt;p&gt;自分が今一番書ける言語はGoなので何かGoを使ったOSSに貢献できないかな〜と思っていたところ自分がよく使っているTUIのgit clientであるLazygit&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;がGo製でかつドキュメントも整っていた&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;のでまずはコードリーディングからチャレンジしてみようと思う。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;定期的な寄付ではなく、一度きりの寄付&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;一時期Good First Issueを漁りまくったりしてみたが、typo修正やUT追加などの一部を除いてはプロジェクトについての理解が浅い状態で貢献できそうなissueはあまり見当たらなかった。やはり全体のアーキテクチャや実際の動作を理解した上でなんらかのissueに取り組むのがいいんだろうなと思ったので腰を据えて特定のプロジェクトへのcontributionを狙っていこうと考えを改めた。&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://github.com/jesseduffield/lazygit&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://github.com/jesseduffield/lazygit&#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/d2896804693595df8f89ef1047e17c57f1da3702622b4710dd2032efea7b3518/jesseduffield/lazygit&#34; alt=&#34;GitHub - jesseduffield/lazygit: simple terminal UI for git commands&#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 - jesseduffield/lazygit: simple terminal UI for git commands&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;simple terminal UI for git commands. Contribute to jesseduffield/lazygit development by creating an account on GitHub.&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://github.com/jesseduffield/lazygit&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/jesseduffield/lazygit/blob/master/CONTRIBUTING.md&#34; target=&#34;_blank&#34; &gt;CONTRIBUTING.md&lt;/a&gt;のようなドキュメントが整備されているだけでなく、authorのjesseさんが実際にLazygitに機能を追加する様子を収めた動画も公開されていたりと貢献に対してかなりオープンな印象&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</content>
    </item>
    
    <item>
      <title>OSSに初めてPRを送ってマージされた話</title>
      <link>https://blog.kyu08.com/posts/my-first-oss-contribution/</link>
      <pubDate>Thu, 10 Aug 2023 16:32:27 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/posts/my-first-oss-contribution/</guid>
      <description>個人開発のプロジェクトで使えそうなGitHub Actionsを物色していたところちょうど自分でも修正できそうな箇所があったのでPRを送ってみ</description>
      <content>&lt;p&gt;個人開発のプロジェクトで使えそうなGitHub Actionsを物色していたところちょうど自分でも修正できそうな箇所があったのでPRを送ってみたところ無事にマージしてもらうことができた。&lt;/p&gt;
&lt;p&gt;実際にマージされたPRはこちら。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://github.com/mislav/bump-homebrew-formula-action/pull/57&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://github.com/mislav/bump-homebrew-formula-action/pull/57&#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/2c79a32ddf4056ec77079b10cd390168cd17879da5f4b729832b88192b140a3e/mislav/bump-homebrew-formula-action/pull/57&#34; alt=&#34;(docs): use environment files instead of set-output by kyu08 · Pull Request #57 · mislav/bump-homebrew-formula-action&#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;(docs): use environment files instead of set-output by kyu08 · Pull Request #57 · mislav/bump-homebrew-formula-action&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;Thanks for creating a great workflow!
What this PR changes
This PR changes usage example in the README.md to use environment files instead of set-output because set-output is deprecated.
close #56
...&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://github.com/mislav/bump-homebrew-formula-action/pull/57&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;h2 id=&#34;prの作成&#34;&gt;PRの作成&lt;/h2&gt;
&lt;p&gt;修正内容としては非推奨となった&lt;code&gt;set-output&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;をenvironment filesに置き換えるという簡単なもの。
ちょうど業務で同様の修正を行っていたので特に詰まることなく修正できた。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;diff.webp&#34; alt=&#34;diff.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;修正内容はたった1行だったが、非同期だし時差もあるしでコミュニケーションの往復が増えることはお互い避けたいはずなのでできるだけ一発でマージしてもらえるように丁寧に背景や動作確認のログを書いた。(自分としても早くマージしてもらえた方が嬉しいし)&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;pr.webp&#34; alt=&#34;pr.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;若干ソワソワしながら過ごしていると&#34;&gt;若干ソワソワしながら過ごしていると&lt;/h2&gt;
&lt;p&gt;PRを送った1日後には見事マージしてもらえた。念願の初OSS contribution！やったね！&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;approve.webp&#34; alt=&#34;approve.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;2.2kものrepositoryで使われてるworkflowのcontributorsに自分のアイコンが載るのは結構嬉しい。(自分のプロジェクト&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;でも利用し始めたタイミングだったのでちゃっかりUsed byにもアイコンが載っているｗ)&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;contributors.webp&#34; alt=&#34;contributors.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;commit logに載っている様子。嬉しい。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;commit-log.webp&#34; alt=&#34;commit-log.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;ということで&#34;&gt;ということで&lt;/h2&gt;
&lt;p&gt;これからもOSSコミュニティへの貢献やっていくぞ〜！&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.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/&#34; target=&#34;_blank&#34; &gt;https://github.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/&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;div class=&#34;blogcard&#34; data-url=&#34;https://github.com/kyu08/fzf-make&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://github.com/kyu08/fzf-make&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail&#34;&gt;
      &lt;img src=&#34;https://repository-images.githubusercontent.com/611369838/a30cf798-2e08-47a5-9443-978329275d2c&#34; alt=&#34;GitHub - kyu08/fzf-make: A command line tool that executes commands using fuzzy finder with preview window for make, npm, pnpm, yarn, just and task.&#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/fzf-make: A command line tool that executes commands using fuzzy finder with preview window for make, npm, pnpm, yarn, just and task.&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;A command line tool that executes commands using fuzzy finder with preview window for make, npm, pnpm, yarn, just and task. - kyu08/fzf-make&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://github.com/kyu08/fzf-make&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</content>
    </item>
    
    <item>
      <title>Goの静的解析に入門した</title>
      <link>https://blog.kyu08.com/posts/hello-go-static-analisys/</link>
      <pubDate>Mon, 17 Jul 2023 05:21:29 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/posts/hello-go-static-analisys/</guid>
      <description>tenntenn Conference 2023 にスポンサーし、Goの静的解析を完全に理解した話 を読んでから静的解析が気になっていたのでこれをやってみた。 静的解析をはじめよう - Gop</description>
      <content>&lt;p&gt;&lt;a href=&#34;https://zenn.dev/team_soda/articles/8e61219eab0fc8&#34; target=&#34;_blank&#34; &gt;tenntenn Conference 2023 にスポンサーし、Goの静的解析を完全に理解した話&lt;/a&gt; を読んでから静的解析が気になっていたのでこれをやってみた。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://golangtokyo.github.io/codelab/find-gophers/?index=codelab#0&#34; target=&#34;_blank&#34; &gt;静的解析をはじめよう - Gopherをさがせ！&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;以下のようなソースコードから&lt;code&gt;Gopher&lt;/code&gt;型を探し出す簡単な解析スクリプトを通してGoでの静的解析の流れやASTの探索方法、型チェックを用いたより詳細な解析方法などを学べた。&lt;/p&gt;
&lt;blockquote&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;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&gt;&lt;/span&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;Gopher&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&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;Gopher&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;string&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;`json:&amp;#34;gopher&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:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;gopher&lt;/span&gt; = &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;GOPHER&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;gogopher&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;GOPHER&lt;/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;gogopher&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Gopher&lt;/span&gt; = &lt;span style=&#34;color:#a6e22e&#34;&gt;gopher&lt;/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;gogopher&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;GOPHER&lt;/span&gt;() (&lt;span style=&#34;color:#a6e22e&#34;&gt;gopher&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Gopher&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;gopher&lt;/span&gt; = &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;Gopher&lt;/span&gt;{&lt;span style=&#34;color:#a6e22e&#34;&gt;Gopher&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;gopher&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&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;a href=&#34;https://golangtokyo.github.io/codelab/find-gophers/?index=codelab#2&#34; target=&#34;_blank&#34; &gt;https://golangtokyo.github.io/codelab/find-gophers/?index=codelab#2&lt;/a&gt; より&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;解説がかなり丁寧でわかりやすかったので静的解析初心者にはかなりありがたかった。&lt;/p&gt;
&lt;p&gt;静的解析を使えば単なる&lt;code&gt;grep&lt;/code&gt;ではできないことができるイメージが実際に掴めたので早速linterを作ってみようと思う。&lt;/p&gt;
</content>
    </item>
    
    <item>
      <title>『ちょうぜつソフトウェア設計入門 PHPで理解するオブジェクト指向の活用』を読んだ</title>
      <link>https://blog.kyu08.com/posts/chozetsu-bon/</link>
      <pubDate>Sat, 15 Jul 2023 15:00:00 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/posts/chozetsu-bon/</guid>
      <description>田中ひさてるさんの『ちょうぜつソフトウェア設計入門――PHPで理解するオブジェクト指向の活用』が話題になっていたので読んでみた。 全体を通して</description>
      <content>&lt;p&gt;田中ひさてるさんの『ちょうぜつソフトウェア設計入門――PHPで理解するオブジェクト指向の活用』が話題になっていたので読んでみた。&lt;/p&gt;
&lt;p&gt;全体を通して平易な日本語で書かれていたのとコード例が豊富だったので理解しやすくてよかった。&lt;/p&gt;
&lt;p&gt;以下学びを簡単にまとめていく。&lt;/p&gt;
&lt;h2 id=&#34;第2章-パッケージ原則&#34;&gt;第2章 パッケージ原則&lt;/h2&gt;
&lt;p&gt;より変更に強いパッケージ設計にするために注意すべき点として&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;パッケージの凝集性を高める&lt;/li&gt;
&lt;li&gt;より安定度が高い(=抽象度が高い)パッケージに依存する&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;などがある。&lt;/p&gt;
&lt;p&gt;また、&lt;strong&gt;凝集性の低さを表すシグナル&lt;/strong&gt;として&lt;strong&gt;そのパッケージが変更される理由が複数あること&lt;/strong&gt;・&lt;strong&gt;1つの変更の際に変更対象となるパッケージが複数あること&lt;/strong&gt;(それぞれ同じ?)が挙げられる。&lt;/p&gt;
&lt;p&gt;「抽象」については以下のように説明されていた。&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;抽象クラスやインターフェイスなど実装詳細を自身から排除したもの&lt;/li&gt;
&lt;li&gt;上記のような詳細を持たないものだけに依存するロジック&lt;/li&gt;
&lt;li&gt;固有の業務にも特定技術にも関係しない時刻や配列などの汎用概念とその操作&lt;/li&gt;
&lt;li&gt;プログラミング言語そのものや言語標準ライブラリと同等レベルの業界標準&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;第3章-オブジェクト指向&#34;&gt;第3章 オブジェクト指向&lt;/h2&gt;
&lt;h3 id=&#34;いい抽象を見つけるには&#34;&gt;いい抽象を見つけるには&lt;/h3&gt;
&lt;p&gt;具体的な例を分析してそれらから抽象を見つけることで期待値の高い抽象を発見できる。&lt;/p&gt;
&lt;p&gt;逆に先に&lt;strong&gt;ひとりよがりの哲学をこねくり回して現実をかえりみない抽象化を先行させた&lt;/strong&gt;場合は、&lt;strong&gt;役に立たない概念に縛られる無駄が起きやすくなる。&lt;/strong&gt;（ペットショップのシステムなのに「Catには野良猫もいるかもしれない。必ずしもPetではないかも&amp;hellip;…」みたいなことを考えてしまうのは明らかに無駄）（抽象化においてもYAGNIが重要っぽい）&lt;/p&gt;
&lt;p&gt;無限の可能性に向かって発散してしまわず、いかに可能性を削ぎ落として最小サイズで実際に起こりうるバリエーションをカバーできるかが汎化のポイント。&lt;/p&gt;
&lt;p&gt;そういう意味でもドメインやビジネスの状況を理解しておくことはプロダクトの将来を考慮しながら設計するために必要なんだろうなと思った。&lt;/p&gt;
&lt;h3 id=&#34;多態性がなくても役立つ&#34;&gt;「多」態性がなくても役立つ&lt;/h3&gt;
&lt;p&gt;抽象と具象は必ずしも1対多の関係である必要はない。&lt;/p&gt;
&lt;p&gt;具象と抽象に分けておくことで先に大枠を安定させることができるため、設計の見通しがつきやすくなる。&lt;/p&gt;
&lt;p&gt;また、具象の数が複数になったときに対応しやすいというメリットもある。&lt;/p&gt;
&lt;p&gt;これまで「抽象と具象が1対1対応なケースはわざわざDIする必要はないのでは」と思っていたが上記のメリットがあるので積極的にDIしていこうと思った。&lt;/p&gt;
&lt;h2 id=&#34;第5章-オブジェクト指向原則-solid&#34;&gt;第5章 オブジェクト指向原則 SOLID&lt;/h2&gt;
&lt;h3 id=&#34;5-2-単一責任原則single-responsibility-principlesrp&#34;&gt;5-2 単一責任原則(Single Responsibility Principle(SRP))&lt;/h3&gt;
&lt;p&gt;クラスと責務は1対1対応すべき、という指針。&lt;/p&gt;
&lt;h4 id=&#34;単一の責務のみつけかた&#34;&gt;単一の責務のみつけかた&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;クラスの利用者がどんなときに別のクラスや新しいバージョンに交換したいと思うかを想像する。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;実際に起こりそうな交換要求への想像が責務(= クラスのカバー範囲)を見極めるヒントになる。&lt;/p&gt;
&lt;p&gt;たとえば記事クラスが存在し記事の入稿および購読というユースケースがある例では以下のように考えることができる。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;ニュース記事を書く人の事情が変わったけれど、購読ユーザーには従来どおりのサービスを提供したい。逆に、入稿はそのまま、購読ユーザーへのサービスを拡張したい。そんなニーズが起きるのは容易に想像できます。入稿と購読のそれぞれを互いに影響を与えない独立したクラスとしておき、いつでも気兼ねなく別の実装に交換できる単位としておく方が、後で便利に決まっています。なので、ニュース記事管理の場合は、「入稿」と「購読」が、それぞれひとつの責務になります。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;5-3-開放閉鎖原則open-close-principle&#34;&gt;5-3 開放閉鎖原則(Open Close Principle)&lt;/h3&gt;
&lt;p&gt;拡張に対してオープン、変更にたいしてクローズドであるべき、という指針。&lt;/p&gt;
&lt;p&gt;これは書籍内で紹介されていたコード例がわかりやすかった。&lt;/p&gt;
&lt;p&gt;あとはどこが変化する仕様なのかを考えるために一度要件を抽象化してみる方法が紹介されていた。こちらもコード例が示されていたのでイメージが湧きやすかった。&lt;/p&gt;
&lt;h2 id=&#34;第7章-依存性注入&#34;&gt;第7章 依存性注入&lt;/h2&gt;
&lt;p&gt;オブジェクトが使う機能の実体を得る際その解決を自力で行わず、常に外部から与えるようにすべき、という設計方針。&lt;/p&gt;
&lt;p&gt;依存性注入を行うメリットの1つは生成の責務と使用の責務を分けられる点がある。&lt;/p&gt;
&lt;p&gt;また、テスト容易性とDIについては以下のような記述があった。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;単体テストしやすいクラスであることと、DI可能なクラスであるということには、正の相関があります。DIを単に「単体テストのためにやること」といった目的観で考えるのは視野狭窄ではあるのですが、単体テストがアーキテクチャへの気づきの手段として、とても有用なのは間違いありません。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;テストが書きずらかったら設計を疑ってみるのも1つの手かもしれない。&lt;/p&gt;
&lt;h2 id=&#34;まとめ&#34;&gt;まとめ&lt;/h2&gt;
&lt;p&gt;よく聞くSOLID原則もやっとちゃんと理解できたし依存性注入に対する理解も深まったので今後に活かしていきたい。&lt;/p&gt;
</content>
    </item>
    
    <item>
      <title>NuPhy Air60を買った</title>
      <link>https://blog.kyu08.com/posts/nuphy-air60/</link>
      <pubDate>Sun, 11 Jun 2023 14:27:54 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/posts/nuphy-air60/</guid>
      <description>NuPhy Air60を買ったので簡単にレビューする 買った理由 普段は7sProを使っているが出社のときに持っていくのが大変だったり尊師スタイルで作業し</description>
      <content>&lt;p&gt;NuPhy Air60を買ったので簡単にレビューする&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;nuphy-air60.webp&#34; alt=&#34;nuphy-air60.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;買った理由&#34;&gt;買った理由&lt;/h2&gt;
&lt;p&gt;普段は7sProを使っているが出社のときに持っていくのが大変だったり尊師スタイルで作業したりしずらかったりするので出社用・家での尊師スタイル用にキーボードを探していた。&lt;/p&gt;
&lt;p&gt;コンパクトなキーボードが好みなので60%で探したいたところNuPhy Air60を見つけ、社の先輩がAir75を使っていたので少し触らせてもらったところ打鍵感がいい感じだったので購入を決めた。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;sonshi.webp&#34; alt=&#34;sonshi.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;nuphy-air60のいいところ&#34;&gt;NuPhy Air60のいいところ&lt;/h2&gt;
&lt;h3 id=&#34;macのキーボードと比べて打ちやすい&#34;&gt;(macのキーボードと比べて)打ちやすい&lt;/h3&gt;
&lt;p&gt;macの付属キーボードのような薄いタイプよりもメカニカルキーボードなどのようなキーストロークが深めなキーボードが好きなので(ロープロファイルとはいえ)比較的打ちやすい。&lt;/p&gt;
&lt;h3 id=&#34;打鍵感--打鍵音がいい&#34;&gt;打鍵感 &amp;amp; 打鍵音がいい&lt;/h3&gt;
&lt;p&gt;コトコト系で心地よい感じ。 以前Keychron K6を一瞬だけ使っていたときは底打ち感があって指が痛くなりやすかったがそういうことも現状ない。&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;img src=&#34;nuphy-air60-2.webp&#34; alt=&#34;nuphy-air60-2.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;コンパクト&#34;&gt;コンパクト&lt;/h3&gt;
&lt;p&gt;60%なのでそれはそうという感じだがコンパクトで使いやすい。(65%のキーボードは一番右の列を間違って押してしまいがちなのでつらい)&lt;/p&gt;
&lt;p&gt;ちなみに持ち歩く際はバード電子から発売されている &lt;a href=&#34;https://www.pfu.ricoh.com/direct/hhkb/hhkb-option/detail_smartcase2.html&#34; target=&#34;_blank&#34; &gt;HHKBスマートケース2&lt;/a&gt; に入れて持ち運んでいる。ぴったりフィットしている。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;with-cover.webp&#34; alt=&#34;with-cover.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;気になったポイント&#34;&gt;気になったポイント&lt;/h2&gt;
&lt;p&gt;唯一惜しいと思ったのはキーキャップがフラットで傾斜がついてないこと（軽く調べた感じロープロファイルだと傾斜がついてないのがスタンダードっぽいのでNuPhy Air60特有の微妙なところかと言われると微妙ではある）&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;を7sProに装着して使っているのでなかなか慣れない &amp;amp; 若干手が疲れる。(とはいえmacのキーボードよりははるかに打ちやすい)&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;keycaps.webp&#34; alt=&#34;keycaps.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;まとめ&#34;&gt;まとめ&lt;/h2&gt;
&lt;p&gt;NuPhy Air60は打鍵感がよく持ち運びもしやすくてとても気に入っている。&lt;/p&gt;
&lt;p&gt;あとは家で作業しているときもキーボードを変えると気分転換になることを発見したのでときどき意味もなくキーボードを入れ替えてみている。&lt;/p&gt;
&lt;p&gt;NuPhyが気になった方は方はこちらのリンクを踏むと10%オフのクーポンが発行されるみたいなのでぜひ。(2023/6/18まで有効) &lt;div class=&#34;blogcard&#34; data-url=&#34;http://nuphy.refr.cc/kyusubsub&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;http://nuphy.refr.cc/kyusubsub&#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://client-assets.referralcandy.com/tf8IcClKVX-qiv7AQJHWv_%25E5%25BE%25AE%25E4%25BF%25A1%25E5%259B%25BE%25E7%2589%2587_20230707181614.jpg&#34; alt=&#34;I can get you a discount at NUPHY®&#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;I can get you a discount at NUPHY®&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;Hey, if you&amp;#39;re ever looking for NUPHY® products, let me know and I can get you a discount at NUPHY®. Here&amp;#39;s a coupon if you need one now:&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;http://nuphy.refr.cc/kyusubsub&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&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://buildersbox.corp-sansan.com/entry/2019/08/16/110000&#34; target=&#34;_blank&#34; &gt;https://buildersbox.corp-sansan.com/entry/2019/08/16/110000&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>
    
    <item>
      <title>GitHub Pagesでデプロイのたびにカスタムドメインの設定が消える問題の解決方法</title>
      <link>https://blog.kyu08.com/posts/github-pages-custom-domain/</link>
      <pubDate>Sat, 10 Jun 2023 14:14:42 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/posts/github-pages-custom-domain/</guid>
      <description>困っていたこと GitHub Actions経由でGitHub Pagesにデプロイするたびにカスタムドメインの設定が消えてしまい、デプロイ先がカスタムドメ</description>
      <content>&lt;h2 id=&#34;困っていたこと&#34;&gt;困っていたこと&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;GitHub Actions経由でGitHub Pagesにデプロイするたびにカスタムドメインの設定が消えてしまい、デプロイ先がカスタムドメインから&lt;code&gt;https://&amp;lt;username&amp;gt;.github.io/&amp;lt;repository&amp;gt;&lt;/code&gt;に戻ってしまう&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;解決方法&#34;&gt;解決方法&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/peaceiris/actions-gh-pages#%EF%B8%8F-add-cname-file-cname&#34; target=&#34;_blank&#34; &gt;ドキュメント&lt;/a&gt;にある通り、&lt;code&gt;cname&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-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;name&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;deploy&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;on&lt;/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;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:#f92672&#34;&gt;branches&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - &lt;span style=&#34;color:#ae81ff&#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;jobs&lt;/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;deploy&lt;/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;runs-on&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;ubuntu-22.04&lt;/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;steps&lt;/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;uses&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;actions/checkout@v2&lt;/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;with&lt;/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;submodules&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/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;fetch-depth&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:#f92672&#34;&gt;name&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;Setup Hugo&lt;/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;uses&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;peaceiris/actions-hugo@v2&lt;/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;with&lt;/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;hugo-version&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;0.112.5&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:#f92672&#34;&gt;extended&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;true&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;name&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;Build&lt;/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;run&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;hugo&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;name&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;Deploy&lt;/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;uses&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;peaceiris/actions-gh-pages@v3&lt;/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;with&lt;/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;github_token&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;${{ secrets.GITHUB_TOKEN }}&lt;/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;publish_dir&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;./public&lt;/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:#f92672&#34;&gt;cname&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;blog.kyu08.com&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;まとめ&#34;&gt;まとめ&lt;/h2&gt;
&lt;p&gt;ドキュメントちゃんと読むの大事&lt;/p&gt;
</content>
    </item>
    
    <item>
      <title>hugo-theme-terminal でOGPに任意の画像を設定する方法</title>
      <link>https://blog.kyu08.com/posts/hugo-theme-terminal-ogp-config/</link>
      <pubDate>Fri, 09 Jun 2023 17:02:33 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/posts/hugo-theme-terminal-ogp-config/</guid>
      <description>hugo-theme-terminal でOGPの設定に少し詰まったのでやったことを書いておく。 前提 hugo version: hugo v0.112.5+extended darwin/arm64 困り 筆者はカバー画像を記事一覧・記事詳細画面に表示したくない、かつO</description>
      <content>&lt;p&gt;&lt;a href=&#34;https://github.com/panr/hugo-theme-terminal&#34; target=&#34;_blank&#34; &gt;hugo-theme-terminal&lt;/a&gt; でOGPの設定に少し詰まったのでやったことを書いておく。&lt;/p&gt;
&lt;h2 id=&#34;前提&#34;&gt;前提&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;hugo version: &lt;code&gt;hugo v0.112.5+extended darwin/arm64&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;困り&#34;&gt;困り&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;筆者はカバー画像を記事一覧・記事詳細画面に表示したくない、かつOGPは全共通の画像を使いたい&lt;/li&gt;
&lt;li&gt;hugo-theme-terminalでは任意の画像をOGPだけに設定できない。（カバー画像をOGPとすることはできる）&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;やったこと&#34;&gt;やったこと&lt;/h2&gt;
&lt;p&gt;多少ハッキーな方法ではあるが以下の方法で実現した。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;各記事のFront Matterに&lt;code&gt;cover: &amp;quot;${OGP_URL}&amp;quot;&lt;/code&gt;指定(&lt;code&gt;archetypes&lt;/code&gt;にテンプレートとして書いておくと便利)&lt;/li&gt;
&lt;li&gt;以下のCSSを追加&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-css&#34; data-lang=&#34;css&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;post-cover&lt;/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;display&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;none&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;</content>
    </item>
    
    <item>
      <title>ブログ用にGifでキャプチャを作る時にやっていること</title>
      <link>https://blog.kyu08.com/posts/create-gif/</link>
      <pubDate>Fri, 09 Jun 2023 16:26:52 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/posts/create-gif/</guid>
      <description>ブログ用によくGifをつくるので自分用の備忘録代わりに手順を記しておく。 追記(2023/11/29) 下記の方法だと生成後のgifに格子模様の</description>
      <content>&lt;p&gt;ブログ用によくGifをつくるので自分用の備忘録代わりに手順を記しておく。&lt;/p&gt;
&lt;h2 id=&#34;追記20231129&#34;&gt;追記(2023/11/29)&lt;/h2&gt;
&lt;p&gt;下記の方法だと生成後のgifに格子模様のようなものが入ってしまうので以下の記事で紹介されているffmpegを使った方法を使うようにしたところ綺麗なgifが生成できるようになった。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://qiita.com/takasp/items/65d1d0d90073bcfc4873&#34; target=&#34;_blank&#34; &gt;Mac で GIF 画像を作る技術 - Qiita&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&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-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ffmpeg -i input.mov -vf &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;palettegen&amp;#34;&lt;/span&gt; -y palette.png
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;GIF 画像を出力します。
サンプルでは、-r オプションでフレームレートを 24 に設定しています。&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;ffmpeg -i input.mov -i palette.png -r &lt;span style=&#34;color:#ae81ff&#34;&gt;24&lt;/span&gt; -y output.gif
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;追記ここまで&lt;/p&gt;
&lt;h2 id=&#34;前提&#34;&gt;前提&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;macOS&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://getkap.co/&#34; target=&#34;_blank&#34; &gt;Kap&lt;/a&gt;がインストールされていること&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/keycastr/keycastr&#34; target=&#34;_blank&#34; &gt;Keycastr&lt;/a&gt;がインストールされていること&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;手順&#34;&gt;手順&lt;/h2&gt;
&lt;h3 id=&#34;1-keycastrを起動&#34;&gt;1. Keycastrを起動&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;keycastr.gif&#34; alt=&#34;keycastr.gif&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;2-kapでいい感じに範囲を選んで録画開始ボタンを押す&#34;&gt;2. Kapでいい感じに範囲を選んで録画開始ボタンを押す&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;select-window.webp&#34; alt=&#34;select-window.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;3-いい感じのサイズで保存重要&#34;&gt;3. いい感じのサイズで保存(重要)&lt;/h3&gt;
&lt;p&gt;(あとから圧縮しようとすると思いのほか大変なのでサイズを小さくしたい場合はいい感じのサイズにするのを忘れない)
&lt;img src=&#34;select-size.webp&#34; alt=&#34;select-size.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;おわりに&#34;&gt;おわりに&lt;/h2&gt;
&lt;p&gt;(いざ書いてみると書くほどでもなかった)&lt;/p&gt;
</content>
    </item>
    
    <item>
      <title>このブログをhugoで作り直した</title>
      <link>https://blog.kyu08.com/posts/hello-hugo/</link>
      <pubDate>Wed, 07 Jun 2023 13:25:41 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/posts/hello-hugo/</guid>
      <description>もともとこのブログはNext.js + Vercelの構成で作られていたが色々と辛くなってしまったのでお手軽にブログが作れそうなhugo + GitHub Pa</description>
      <content>&lt;p&gt;もともとこのブログはNext.js + Vercelの構成で作られていたが色々と辛くなってしまったのでお手軽にブログが作れそうなhugo + GitHub Pagesの構成に移行した。&lt;/p&gt;
&lt;h2 id=&#34;動機&#34;&gt;動機&lt;/h2&gt;
&lt;p&gt;もともとNext.jsを触ってみたかったのでNext.jsで書いたでブログを運営していた。&lt;/p&gt;
&lt;p&gt;このときのディレクトリ構成が以下のような感じになっていて、画像はrepositoryにアップロードして(PRのコメント欄とかに画像を貼って取得した&lt;code&gt;https://user-images.githubusercontent.com/xxxxx&lt;/code&gt;のようなURLを使って)それをマークダウンから呼び出していた。&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;root/
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ├ posts/
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  │　├ post1.md
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  │　├ post2.md
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  │　└ post3.md
&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;ところがGitHubのrepositoryにアップした画像まわりの仕様が変わり&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;、それ以降private repositoryにアップした画像は認証付きになったため画像のホスト方法の変更が必要になった。&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-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;root/
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ├ posts/
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  │  ├ post1.md/
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  │  │  ├ index.md
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  │  │  └ image.png
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  │  ├ post2.md/
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  │  │  ├ index.md
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  │  │  └ image.png
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  │  └ post3.md/
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  │     ├ index.md
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  │     └ image.png
&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;で、それをやろうとしたがどうにもうまく画像を読み込むことができなかった。(当然悪いのはNext.jsではなく1000億%自分の技術力のNASAです)&lt;/p&gt;
&lt;p&gt;ちゃんとNext.js(やJSのツールチェイン周り)のお勉強をすればNextでもできたと思うが当面JS関連の技術を触る予定もないしブログの管理にそこまで時間をかけたい気持ちもなかったので諦めてhugoに移行することにした。&lt;/p&gt;
&lt;h2 id=&#34;やったこと&#34;&gt;やったこと&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;テーマ選定(&lt;a href=&#34;https://github.com/panr/hugo-theme-terminal&#34; target=&#34;_blank&#34; &gt;panr/hugo-theme-terminal&lt;/a&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;GA4導入&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;以下部分的に補足する。&lt;/p&gt;
&lt;h3 id=&#34;デプロイの自動化&#34;&gt;デプロイの自動化&lt;/h3&gt;
&lt;p&gt;以下のようなyamlを&lt;code&gt;.github/workflows/deploy.yaml&lt;/code&gt;として配置するとmainへのpush時に自動でデプロイが行われる。&lt;/p&gt;
&lt;p&gt;カスタムドメインに指定したい場合は&lt;code&gt;cname&lt;/code&gt;を指定しないとデプロイのたびにカスタムドメインが404になってしまうので注意。&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-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;name&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;deploy&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;on&lt;/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;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:#f92672&#34;&gt;branches&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - &lt;span style=&#34;color:#ae81ff&#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;jobs&lt;/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;deploy&lt;/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;runs-on&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;ubuntu-latest&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;# サポートされていないバージョンを指定するとGitHub Actionsがずっとrunningになるので注意&lt;/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;steps&lt;/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;uses&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;actions/checkout@v2&lt;/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;with&lt;/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;submodules&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/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;fetch-depth&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:#f92672&#34;&gt;name&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;Setup Hugo&lt;/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;uses&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;peaceiris/actions-hugo@v2&lt;/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;with&lt;/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;hugo-version&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;0.112.5&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:#f92672&#34;&gt;extended&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;true&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;name&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;Build&lt;/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;run&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;hugo&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;name&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;Deploy&lt;/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;uses&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;peaceiris/actions-gh-pages@v3&lt;/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;with&lt;/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;github_token&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;${{ secrets.GITHUB_TOKEN }}&lt;/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;publish_dir&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;./public&lt;/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;cname&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;blog.kyu08.com&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;# カスタムドメインの設定をしていない場合は不要&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;ga4の導入&#34;&gt;GA4の導入&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://maku77.github.io/p/zxk6pat/&#34; target=&#34;_blank&#34; &gt;こちらの記事&lt;/a&gt;を参考に進めたらできた。&lt;/p&gt;
&lt;p&gt;1点だけ注意が必要なのはpartialsの扱いがthemeによって異なる(っぽい)こと。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/panr/hugo-theme-terminal&#34; target=&#34;_blank&#34; &gt;panr/hugo-theme-terminal&lt;/a&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-html&#34; data-lang=&#34;html&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;!--
&lt;/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;To add an extended head section, please create
&lt;/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;`layouts/partials/extended_head.html` in your Hugo directory.
&lt;/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;--&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&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;code&gt;layouts/partials/extended_head.html&lt;/code&gt;にタグの設定を記述した。&lt;/p&gt;
&lt;h2 id=&#34;着手--公開まででかかった時間&#34;&gt;着手 ~ 公開まででかかった時間&lt;/h2&gt;
&lt;p&gt;たぶん6hくらい。&lt;/p&gt;
&lt;p&gt;数箇所詰まったがドキュメントや先人のブログのおかげですぐに解決できた。&lt;/p&gt;
&lt;p&gt;おそらくミニマムな状態(カスタムドメイン設定なし, テーマのデザインをそのまま利用, GA4なしなどなど)なら1hもかからずに公開までできると思う。&lt;/p&gt;
&lt;h2 id=&#34;hugoのいいところ&#34;&gt;hugoのいいところ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;既存のテーマを利用すると手軽に色々できる(TOC, シンタックスハイライト, 脚注などなど)。とにかくお手軽なのが最高。基本的にはテーマを選んで記事を書いてデプロイすればブログが公開できてしまうのですごい。&lt;/li&gt;
&lt;li&gt;ドキュメント・themeのソースコードを読めば大抵解決する&lt;/li&gt;
&lt;li&gt;&lt;code&gt;watch&lt;/code&gt;オプションがあるので&lt;code&gt;hugo serve -w&lt;/code&gt;を実行するとホットリロードが有効になるので捗る&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;ハマったところ&#34;&gt;ハマったところ&lt;/h2&gt;
&lt;p&gt;&lt;del&gt;長くなりそうなので別途記事にする予定&lt;/del&gt;&lt;/p&gt;
&lt;p&gt;それぞれ記事にした。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.kyu08.com/posts/hugo-theme-terminal-ogp-config&#34; &gt;hugo-theme-terminal でOGPに任意の画像を設定する方法&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.kyu08.com/posts/github-pages-custom-domain&#34; &gt;GitHub Pagesでデプロイのたびにカスタムドメインの設定が消える問題の解決方法&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;実際の運用はこんな感じ&#34;&gt;実際の運用はこんな感じ&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;記事作成用のブランチを作成&lt;/li&gt;
&lt;li&gt;記事を作成&lt;/li&gt;
&lt;li&gt;PRを作成してmainにマージ&lt;/li&gt;
&lt;li&gt;GitHub Actionsでビルド・デプロイが走る&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;code&gt;2.記事を作成&lt;/code&gt;だけ軽く補足すると、Makefileに以下のようなターゲットを定義したので&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-Makefile&#34; data-lang=&#34;Makefile&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;.PHONY&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; new
&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;new&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;	@read -p &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;post id: &amp;#34;&lt;/span&gt; id; &lt;span style=&#34;color:#ae81ff&#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:#ae81ff&#34;&gt;&lt;/span&gt;	hugo new &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;posts/&lt;/span&gt;$$&lt;span style=&#34;color:#e6db74&#34;&gt;{id}/index.md&amp;#34;&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;img src=&#34;make-new.gif&#34; alt=&#34;make-new.gif&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;ちなみにデプロイは1分くらいで完了するのでサクサク反映できて嬉しい。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;deploy.webp&#34; alt=&#34;deploy.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;おわりに&#34;&gt;おわりに&lt;/h2&gt;
&lt;p&gt;色々追加したい機能はあるけどとりあえず最低限の機能はできたのでヨシ！とする。&lt;/p&gt;
&lt;p&gt;ブログたくさん書くぞ〜&lt;/p&gt;
&lt;p&gt;感想はtwitterとかで呟いたりリプしてくれたりすると跳んで喜びます。&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.blog/changelog/2023-05-09-more-secure-private-attachments/&#34; target=&#34;_blank&#34; &gt;https://github.blog/changelog/2023-05-09-more-secure-private-attachments/&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;a href=&#34;https://github.com/panr/hugo-theme-terminal/blob/9726b8d80658c6cf3c092c21484548aba6f64a68/layouts/partials/extended_head.html&#34; target=&#34;_blank&#34; &gt;https://github.com/panr/hugo-theme-terminal/blob/9726b8d80658c6cf3c092c21484548aba6f64a68/layouts/partials/extended_head.html&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</content>
    </item>
    
    <item>
      <title>About Me</title>
      <link>https://blog.kyu08.com/about/</link>
      <pubDate>Tue, 06 Jun 2023 01:15:48 +0900</pubDate>
      
      <guid>https://blog.kyu08.com/about/</guid>
      <description>Go Elm TypeScript Neovim tmux Rust CLIが好きな6年目ソフトウェアエンジニアです。ご連絡はTwitterまで。 site account GitHub kyu08 Twitter @kyu08_ Bluesky @kyu08.bsky.social misskey @kyu08 ブログの誤字や誤情報については こ</description>
      <content>&lt;p&gt;Go Elm TypeScript Neovim tmux Rust CLIが好きな6年目ソフトウェアエンジニアです。ご連絡はTwitterまで。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;site&lt;/th&gt;
&lt;th&gt;account&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;GitHub&lt;/td&gt;
&lt;td&gt;&lt;a href=&#34;https://github.com/kyu08&#34; target=&#34;_blank&#34; &gt;kyu08&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Twitter&lt;/td&gt;
&lt;td&gt;&lt;a href=&#34;https://twitter.com/kyu08_&#34; target=&#34;_blank&#34; &gt;@kyu08_&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bluesky&lt;/td&gt;
&lt;td&gt;&lt;a href=&#34;https://bsky.app/profile/kyu08.bsky.social&#34; target=&#34;_blank&#34; &gt;@kyu08.bsky.social&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;misskey&lt;/td&gt;
&lt;td&gt;&lt;a href=&#34;https://misskey.io/@kyu08&#34; target=&#34;_blank&#34; &gt;@kyu08&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;ブログの誤字や誤情報については &lt;a href=&#34;https://github.com/kyu08/blog/issues&#34; target=&#34;_blank&#34; &gt;このブログのリポジトリ&lt;/a&gt; でも受け付けています。&lt;/p&gt;
</content>
    </item>
    
    <item>
      <title>Makefileに定義されたtargetをfzfで選択して実行するCLIツールをRustでつくった</title>
      <link>https://blog.kyu08.com/posts/fzf-make/</link>
      <pubDate>Fri, 31 Mar 2023 01:15:48 +0900</pubDate>
      
      <guid>https://blog.kyu08.com/posts/fzf-make/</guid>
      <description>(2024/12/14追記) 内容を更新した紹介記事をZennに投稿しました。 [make,pnpm,yarnに対応]タスクランナーのコマンドを</description>
      <content>&lt;blockquote&gt;
&lt;h1 id=&#34;20241214追記-内容を更新した紹介記事をzennに投稿しました&#34;&gt;(2024/12/14追記) 内容を更新した紹介記事をZennに投稿しました。&lt;/h1&gt;
&lt;p&gt;&lt;a href=&#34;https://zenn.dev/kyu08/articles/974fd8bc25c303&#34; target=&#34;_blank&#34; &gt;[make,pnpm,yarnに対応]タスクランナーのコマンドをfuzzy finder形式で選択できるCLIツール fzf-makeの紹介&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Makefileに定義されたtargetをfzfで選択して実行するCLIツールをRustでつくった。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://github.com/kyu08/fzf-make&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://github.com/kyu08/fzf-make&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail&#34;&gt;
      &lt;img src=&#34;https://repository-images.githubusercontent.com/611369838/a30cf798-2e08-47a5-9443-978329275d2c&#34; alt=&#34;GitHub - kyu08/fzf-make: A command line tool that executes commands using fuzzy finder with preview window for make, npm, pnpm, yarn, just and task.&#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/fzf-make: A command line tool that executes commands using fuzzy finder with preview window for make, npm, pnpm, yarn, just and task.&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;A command line tool that executes commands using fuzzy finder with preview window for make, npm, pnpm, yarn, just and task. - kyu08/fzf-make&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://github.com/kyu08/fzf-make&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;img src=&#34;fzf-make-demo.gif&#34; alt=&#34;fzf-make-demo&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;fzf-makeがやっていること&#34;&gt;fzf-makeがやっていること&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;Makefile&lt;/code&gt;からtargetを正規表現で抜き出す&lt;/li&gt;
&lt;li&gt;&lt;code&gt;skim&lt;/code&gt;(※)に実行オプションとtargetたちを渡す&lt;/li&gt;
&lt;li&gt;&lt;code&gt;skim&lt;/code&gt;がプレビューウィンドウ付きのfuzzy-finderを表示&lt;/li&gt;
&lt;li&gt;&lt;code&gt;skim&lt;/code&gt;から選択されたtargetが返ってくるので&lt;code&gt;make ${target}&lt;/code&gt;を実行&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;基本的な動作はすべて&lt;code&gt;skim&lt;/code&gt;任せになっていてRust側でやっているのは&lt;code&gt;skim&lt;/code&gt;とのやりとりくらいになっている。&lt;/p&gt;
&lt;p&gt;※&lt;a href=&#34;https://github.com/lotabout/skim&#34; target=&#34;_blank&#34; &gt;lotabout/skim&lt;/a&gt;&amp;hellip;Rust製のfuzzy-finder。Rustのライブラリとして利用することもできる。&lt;/p&gt;
&lt;p&gt;(makeの文法が思ったより多彩っぽかったので自分が必要とするごく簡単なユースケース以外をカバーするのは&lt;a href=&#34;https://twitter.com/kyu08_/status/1639986936407531525&#34; target=&#34;_blank&#34; &gt;早々に諦めた。&lt;/a&gt;(makeで1冊本が書けるぐらいだしそれはそうという感じではある))&lt;/p&gt;
&lt;p&gt;brewコマンドでインストールできるので気になる方はぜひ。&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;brew tap kyu08/tap
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;brew install kyu08/tap/fzf-make
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;ソースも公開しているので、「こう書くといいよ」とかバグとかありましたらぜひissueやPRで教えてください。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://github.com/kyu08/fzf-make&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://github.com/kyu08/fzf-make&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail&#34;&gt;
      &lt;img src=&#34;https://repository-images.githubusercontent.com/611369838/a30cf798-2e08-47a5-9443-978329275d2c&#34; alt=&#34;GitHub - kyu08/fzf-make: A command line tool that executes commands using fuzzy finder with preview window for make, npm, pnpm, yarn, just and task.&#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/fzf-make: A command line tool that executes commands using fuzzy finder with preview window for make, npm, pnpm, yarn, just and task.&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;A command line tool that executes commands using fuzzy finder with preview window for make, npm, pnpm, yarn, just and task. - kyu08/fzf-make&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://github.com/kyu08/fzf-make&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;上述の通り処理の大部分はskim任せになっている。(書いたコードはテストを含めても200行程度)&lt;/p&gt;
&lt;p&gt;ただskimをライブラリとして利用する実装サンプルがあまりなかったのがちょっと大変だった。特にプレビューウィンドウの表示にfzfの候補文字列を変数としたシェルコマンドの形で渡すことができることに気づくまでに時間がかかった&lt;/p&gt;
&lt;p&gt;↓の&lt;code&gt;{}&lt;/code&gt;にtarget名が入るイメージ。&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:#66d9ef&#34;&gt;let&lt;/span&gt; preview_command &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;r&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;line=$(bat Makefile | grep -nE &amp;#39;^{}\s*:&amp;#39; | sed -e &amp;#39;s/:.*//g&amp;#39;); bat --style=numbers --color=always --line-range $line: --highlight-line $line Makefile&amp;#34;&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/kyu08/fzf-make/blob/3a627d0a1aa75b1bf1ff87f3443f63393afbcf10/src/misc.rs#L18&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://github.com/kyu08/fzf-make/blob/3a627d0a1aa75b1bf1ff87f3443f63393afbcf10/src/misc.rs#L18&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail&#34;&gt;
      &lt;img src=&#34;https://repository-images.githubusercontent.com/611369838/a30cf798-2e08-47a5-9443-978329275d2c&#34; alt=&#34;fzf-make/src/misc.rs at 3a627d0a1aa75b1bf1ff87f3443f63393afbcf10 · kyu08/fzf-make&#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;fzf-make/src/misc.rs at 3a627d0a1aa75b1bf1ff87f3443f63393afbcf10 · kyu08/fzf-make&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;A command line tool that executes commands using fuzzy finder with preview window for make, npm, pnpm, yarn, just and task. - kyu08/fzf-make&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://github.com/kyu08/fzf-make/blob/3a627d0a1aa75b1bf1ff87f3443f63393afbcf10/src/misc.rs#L18&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;あとはgoでいつもやっている感じでテーブル駆動テストっぽくテストを書いてみた。可読性も保守性も高いので割と気に入っている。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://github.com/kyu08/fzf-make/blob/3a627d0a1aa75b1bf1ff87f3443f63393afbcf10/src/misc.rs#L145&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://github.com/kyu08/fzf-make/blob/3a627d0a1aa75b1bf1ff87f3443f63393afbcf10/src/misc.rs#L145&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail&#34;&gt;
      &lt;img src=&#34;https://repository-images.githubusercontent.com/611369838/a30cf798-2e08-47a5-9443-978329275d2c&#34; alt=&#34;fzf-make/src/misc.rs at 3a627d0a1aa75b1bf1ff87f3443f63393afbcf10 · kyu08/fzf-make&#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;fzf-make/src/misc.rs at 3a627d0a1aa75b1bf1ff87f3443f63393afbcf10 · kyu08/fzf-make&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;A command line tool that executes commands using fuzzy finder with preview window for make, npm, pnpm, yarn, just and task. - kyu08/fzf-make&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://github.com/kyu08/fzf-make/blob/3a627d0a1aa75b1bf1ff87f3443f63393afbcf10/src/misc.rs#L145&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;Rustが書きたかった。(以上)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;最近Rustのやっていきが高まっており、&lt;a href=&#34;https://doc.rust-jp.rs/book-ja/&#34; target=&#34;_blank&#34; &gt;The Rust Programming Language&lt;/a&gt; を1周したので何か作ってみるぞーという機運とMakefileのターゲットをfuzzy-finderで絞り込めたら便利そうだなーという気持ちが重なったのでRustでfzf-makeを作ってみた。 (あとはskimの存在を知っていたのも大きい。)&lt;/p&gt;
&lt;p&gt;自分が欲しいCLIツールを手に入れつつRustの経験が積めたのでよかった。&lt;/p&gt;
&lt;p&gt;ちなみにRustに入門した直接的(?)なきっかけとしてはこのスライドを目にして、「Elmっぽい！楽しそう！」と思ったのが発端だった。Rustに興味を持っている人はぜひ読んでみて欲しい。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://speakerdeck.com/estie/man-wochi-siteshi-merurust&#34; target=&#34;_blank&#34; &gt;満を持して始める Rust&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;rustを触ってみて感じたこと&#34;&gt;Rustを触ってみて感じたこと&lt;/h2&gt;
&lt;p&gt;Rustを触る前に持っていた印象は「コンパイルが通りずらく、安全性が高い」「関数型っぽい」という感じだった。&lt;/p&gt;
&lt;p&gt;実際に学んでみた印象は次のような感じ。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;関数型っぽい書き心地
&lt;ul&gt;
&lt;li&gt;特にenumとパターンマッチング,Option型 ,Result型, 式指向な考え方などの関数型っぽい言語機能や極力データをイミュータブルに扱う思想などが心地よかった。筆者が大好きな言語であるElm(ウェブブラウザベースのGUIを作成するための純粋関数型)の好きな部分をほとんど含んでたのでElmに近い感覚で書くことができた。(もちろん慣れてないこともあってElmよりも全然難しかったけど)&lt;/li&gt;
&lt;li&gt;(Elmが気になる方は&lt;a href=&#34;https://guide.elm-lang.jp/&#34; target=&#34;_blank&#34; &gt;Elm Guide&lt;/a&gt;がおすすめです)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;↑に近いがNull安全なことに加えて所有権などの概念のおかげでコンパイルが通りさえすればちゃんと動いてくれるという安心感がある。
&lt;ul&gt;
&lt;li&gt;リファクタもやりやすそう。(enumにバリアントを追加したとき、パターンマッチの全箇所を修正しないとコンパイルが通らなかったりすると思うので)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;開発体験が良い
&lt;ul&gt;
&lt;li&gt;エラーメッセージがとても丁寧。「ここがこう悪いで〜」とか「ここをこう直すとええで〜」みたいなことまでエラーメッセージに書いてくれてあるホスピタリティに感動した。こういったところもRustが生産性が高いと言われる所以なのかもしれない。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;コミュニティの初学者をサポートする姿勢がすごい
&lt;ul&gt;
&lt;li&gt;RustのOSSプロジェクトへのcontributionについては &lt;a href=&#34;https://zenn.dev/fraternite/articles/4e11063bf05aac&#34; target=&#34;_blank&#34; &gt;rust-lang/rustへのcode contributionをはじめからていねいに&lt;/a&gt; が詳しいが、Rust製のOSSプロジェクトには&lt;code&gt;E-mentor&lt;/code&gt;というタグがありissueを進めるに当たってメンターが指針を記してくれているらしい。（&lt;a href=&#34;https://github.com/rust-lang/rust/issues/109099&#34; target=&#34;_blank&#34; &gt;https://github.com/rust-lang/rust/issues/109099&lt;/a&gt; これとかすごい。）&lt;/li&gt;
&lt;li&gt;いつかRustのOSSプロジェクトにもcontributionしてみたい&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;他の言語と比べて動くものをつくるまでに必要な学習コストは高いとは思うがRustをちゃんと書けるようになれば生産性高く安全なコードが書けると思うので必ずしも学習コストが高いとは言えないのかもしれない。（他の言語でも安全なコードを書くためには一定の学習や経験が必要だろうし）（※想像で喋っています）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;総じて開発体験は良かったのでこれからもゆるゆるとRustの学習は続けていきたい。&lt;/p&gt;
&lt;h2 id=&#34;余談&#34;&gt;余談&lt;/h2&gt;
&lt;p&gt;テスト実行に &lt;a href=&#34;nextest-rs/nextest&#34; &gt;https://github.com/nextest-rs/nextest&lt;/a&gt; を使ってみたがテスト結果が見やすくて便利だった。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;cargo run&lt;/code&gt;の結果
&lt;img src=&#34;cargo-run.webp&#34; alt=&#34;cargo run&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;cargo nextest run&lt;/code&gt;の結果
&lt;img src=&#34;nextest-run.webp&#34; alt=&#34;cargo nextest run&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;カラフルで見やすい。&lt;/p&gt;
</content>
    </item>
    
    <item>
      <title>yamlに定義したbookmarkをfzfで選択してブラウザで開くCLIツールをGoで作った</title>
      <link>https://blog.kyu08.com/posts/fzf-bookmark-opener/</link>
      <pubDate>Wed, 22 Feb 2023 16:15:48 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/posts/fzf-bookmark-opener/</guid>
      <description>つくったもの yamlに定義しておいたbookmarkをfzfで選択してブラウザで開くCLIツールをGoで作った。 GitHub - kyu08/fzf-bookmark-opener: A command line tool that opens bookmark using fzf.A command line</description>
      <content>&lt;h2 id=&#34;つくったもの&#34;&gt;つくったもの&lt;/h2&gt;
&lt;p&gt;yamlに定義しておいたbookmarkをfzfで選択してブラウザで開くCLIツールをGoで作った。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://github.com/kyu08/fzf-bookmark-opener&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://github.com/kyu08/fzf-bookmark-opener&#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/d139e419d52297633132631fea0101b20a871eb91b1cb56c2a1ffb7780b41a17/kyu08/fzf-bookmark-opener&#34; alt=&#34;GitHub - kyu08/fzf-bookmark-opener: A command line tool that opens bookmark using fzf.&#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/fzf-bookmark-opener: A command line tool that opens bookmark using fzf.&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;A command line tool that opens bookmark using fzf. - kyu08/fzf-bookmark-opener&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://github.com/kyu08/fzf-bookmark-opener&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;img src=&#34;https://user-images.githubusercontent.com/49891479/218272272-e693c10d-c810-458a-bf46-9c3a4a2fe45a.gif&#34; alt=&#34;demo&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;コードの話&#34;&gt;コードの話&lt;/h2&gt;
&lt;p&gt;コード自体は大変シンプルで&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;設定ファイルがなければ&lt;code&gt;~/.config/fzf-bookmark-opener/config.yaml&lt;/code&gt;に作成&lt;/li&gt;
&lt;li&gt;設定ファイルの読み込み&lt;/li&gt;
&lt;li&gt;fzfで選択&lt;/li&gt;
&lt;li&gt;選択されたブックマークをブラウザで開く&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;ということをやっているだけである。(&lt;code&gt;main.go&lt;/code&gt;に120行弱だけという素朴なコード量)&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/kyu08/fzf-bookmark-opener/blob/69313bf187dcfd6127efcf75e172a34fb9b8e05a/main.go#L38-L60&#34; target=&#34;_blank&#34; &gt;fzf-bookmark-opener/main.go at main · kyu08/fzf-bookmark-opener&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;この記述量で作れたのは間違いなくktr0731/go-fuzzyfinderのおかげでした。このライブラリのおかげでgoのコードからfzfを簡単に呼び出すことができました。というかなんならこのライブラリの存在を知ったので使ってみたくなってfzf-bookmark-openerを作ったみたいなとこもあります。ありがとうございます。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/ktr0731/go-fuzzyfinder&#34; target=&#34;_blank&#34; &gt;ktr0731/go-fuzzyfinder&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;ちゃっかりbrewでも公開してみた&#34;&gt;ちゃっかりbrewでも公開してみた&lt;/h2&gt;
&lt;p&gt;brewでインストールできるに越したことはないだろうってことで、brewでも公開してみたが思いのほか簡単だった。&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;brew tap kyu08/tap
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;brew install kyu08/tap/fzf-bookmark-opener
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;これだけでインストールできるので気になった方もそうでない方もぜひ。issueやPRもお待ちしています。(&lt;code&gt;go install&lt;/code&gt;でインストールしたい方はこちら(&lt;code&gt;go install github.com/kyu08/fzf-bookmark-opener@latest&lt;/code&gt;))&lt;/p&gt;
&lt;p&gt;brew公開に関してはこちらのブログを参考にしたら30分弱でサクッと公開できた(想像より簡単だった)&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://www.rasukarusan.com/entry/2019/11/03/211338&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://www.rasukarusan.com/entry/2019/11/03/211338&#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://cdn.image.st-hatena.com/image/scale/887da0d267a399928f4f3e7a0eb22ea2278d9656/backend=imagemagick;version=1;width=1300/https%3A%2F%2Fcdn-ak.f.st-hatena.com%2Fimages%2Ffotolife%2Fr%2Frasukarusan%2F20191103%2F20191103211239.png&#34; alt=&#34;【備忘録】Homebrewで自作ツールを配布する - ハイパーマッスルエンジニア&#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;【備忘録】Homebrewで自作ツールを配布する - ハイパーマッスルエンジニア&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;Homebrewでの配布は簡単だが毎回忘れる Goでバイナリ作ったり、ShellScript書いて配布したいなと思ったときにHomebrew使うことが割とある。 が、その都度毎回調べてやり方を思い出しながらするのが億劫だったので、一回まとめてみる。 ざっくり手順 Homebrew配布用のリポジトリを作る tagをpushしてReleaseノートを作る Formulaファイルを作ってpush 1. Homebrew配布用のリポジトリを作る 自作ツールのインストールファイルを置くためのリポジトリを作る。このリポジトリにバイナリとかの成果物を置くわけではない。置くのはインストールファイルである.rb…&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://www.rasukarusan.com/entry/2019/11/03/211338&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;詳細は↑の記事を読んでいただければわかるが、リリースにバイナリを含めて配布用のrepositoryを作るだけなので本当に簡単だったのでツールを配布したい人はぜひ。&lt;/p&gt;
&lt;h2 id=&#34;ちゃっかりヘルパースクリプトも公開した&#34;&gt;ちゃっかりヘルパースクリプトも公開した&lt;/h2&gt;
&lt;p&gt;現在お仕事ではGCPを使っているんですが、GCPのコンソールをプロジェクト、サービスを指定して直接開きたいことが多いのでプロジェクトのリストを渡すとGCPの主要なサービス(主観)のURL一覧をfzf-bookmark-openerの設定ファイルの形式で吐いてくれるスクリプトも公開した。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/kyu08/gcp-url-generator&#34; target=&#34;_blank&#34; &gt;kyu08/gcp-url-generator&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;project名のリストとregionを渡すとこういう文字列を吐いてくれるイメージ。(以下は出力の一部)(この例だとregionは関係ない)&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-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  - &lt;span style=&#34;color:#f92672&#34;&gt;title&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;Home stg&amp;#39;&lt;/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;url&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;https://console.cloud.google.com/home/dashboard?project=stg&amp;#39;&lt;/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;title&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;Home dev&amp;#39;&lt;/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;url&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;https://console.cloud.google.com/home/dashboard?project=dev&amp;#39;&lt;/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;title&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;Home prod&amp;#39;&lt;/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;url&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;https://console.cloud.google.com/home/dashboard?project=prod&amp;#39;&lt;/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;title&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;Datastore stg&amp;#39;&lt;/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;url&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;https://console.cloud.google.com/datastore/entities?project=stg&amp;#39;&lt;/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;title&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;Datastore dev&amp;#39;&lt;/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;url&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;https://console.cloud.google.com/datastore/entities?project=dev&amp;#39;&lt;/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;title&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;Datastore prod&amp;#39;&lt;/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;url&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;https://console.cloud.google.com/datastore/entities?project=prod&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;現在の対応サービスは以下で、Cloud Runに関してはサービス名の配列を渡すとプロジェクト*サービスの全組み合わせのURLを吐く。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Dashboard&lt;/li&gt;
&lt;li&gt;Datastore&lt;/li&gt;
&lt;li&gt;App Engine&lt;/li&gt;
&lt;li&gt;Artifact Registry&lt;/li&gt;
&lt;li&gt;Cloud Storage&lt;/li&gt;
&lt;li&gt;Spanner&lt;/li&gt;
&lt;li&gt;BigQuery&lt;/li&gt;
&lt;li&gt;Cloud Scheduler&lt;/li&gt;
&lt;li&gt;PubSub&lt;/li&gt;
&lt;li&gt;Dataflow&lt;/li&gt;
&lt;li&gt;Cloud Build&lt;/li&gt;
&lt;li&gt;Cloud Tasks&lt;/li&gt;
&lt;li&gt;Cloud Run&lt;/li&gt;
&lt;li&gt;Cloud SQL&lt;/li&gt;
&lt;li&gt;Cloud Functions&lt;/li&gt;
&lt;li&gt;IAM&lt;/li&gt;
&lt;li&gt;Secret Manager&lt;/li&gt;
&lt;li&gt;AI Platform&lt;/li&gt;
&lt;li&gt;Compute Engine&lt;/li&gt;
&lt;li&gt;Logging&lt;/li&gt;
&lt;li&gt;Monitoring&lt;/li&gt;
&lt;li&gt;Workflows&lt;/li&gt;
&lt;li&gt;Firebase Realtime Database (DB)&lt;/li&gt;
&lt;li&gt;Firebase Hosting&lt;/li&gt;
&lt;li&gt;Firebase Remote Config&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これで生成したURLをfzf-bookmark-openerに食わせるとお使いのGCPプロジェクトの特定のサービスがコマンドラインからサクッと開くことができる。(詳しくは&lt;a href=&#34;https://github.com/kyu08/gcp-url-generator&#34; target=&#34;_blank&#34; &gt;kyu08/gcp-url-generatorのREADME&lt;/a&gt;を参照)
こちらもissueやPRお待ちしてます。&lt;/p&gt;
&lt;h2 id=&#34;余談1&#34;&gt;余談1&lt;/h2&gt;
&lt;p&gt;Rustだとlotabout/skimを使うとktr0731/go-fuzzyfinderと同じようなことができるらしい。最近Rust熱が高まりに高まっている(Tour of Rustやり中)ので次に何かCLIでfzfなツールをつくるときは使ってみようと思う。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/lotabout/skim&#34; target=&#34;_blank&#34; &gt;lotabout/skim&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[追記]
Makefileに定義されたtargetをfzfで選択して実行するCLIツールをRustでつくった。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/kyu08/fzf-make&#34; target=&#34;_blank&#34; &gt;kyu08/fzf-make&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;余談2&#34;&gt;余談2&lt;/h2&gt;
&lt;p&gt;ふと気になってktr0731/go-fuzzyfinderをはじめとする依存ライブラリのライセンス表示はどうすればいいか気になって調べてみたところリポジトリに&lt;code&gt;NOTICES&lt;/code&gt;とか&lt;code&gt;CREDITS&lt;/code&gt;とか&lt;code&gt;ThirdPartyNotices&lt;/code&gt;みたいなファイルを置いてそこに依存ライブラリの著作権・ライセンス表示をするのが一般的なようだった。&lt;/p&gt;
&lt;p&gt;手作業でやるのは辛いので自動生成ツールを探したところGoだとこれが使いやすそうだったので使ってみたけど簡単でとてもよかった。ありがたや&amp;hellip;。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://github.com/Songmu/gocredits&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://github.com/Songmu/gocredits&#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/e988441e6034bc06ec50b0ad38ca1afba52744179f5c59d77afbb6cbb6764640/Songmu/gocredits&#34; alt=&#34;GitHub - Songmu/gocredits: creates CREDITS file from LICENSE files of dependencies&#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 - Songmu/gocredits: creates CREDITS file from LICENSE files of dependencies&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;creates CREDITS file from LICENSE files of dependencies - Songmu/gocredits&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://github.com/Songmu/gocredits&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;ktr0731/go-fuzzyfinderはいいぞ〜&lt;/p&gt;
</content>
    </item>
    
    <item>
      <title>Tmux&#43;NeovimでJetBrains IDEのScratchみたいな機能を実現している話</title>
      <link>https://blog.kyu08.com/posts/tmux-neovim-scratch/</link>
      <pubDate>Sat, 04 Feb 2023 16:15:48 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/posts/tmux-neovim-scratch/</guid>
      <description>任意の構成のSandbox的な環境をTmuxのwindowとして用意するようにしたところターミナルから出ずにサクっと動作検証とかが行えてハッ</description>
      <content>&lt;p&gt;任意の構成のSandbox的な環境をTmuxのwindowとして用意するようにしたところターミナルから出ずにサクっと動作検証とかが行えてハッピーになったよ、という記事。ここではvanillaなGoのプロジェクトの例を紹介しますが、お好みの構成でSandbox環境を作ってみてください。&lt;/p&gt;
&lt;p&gt;全然大したことをやっているわけではないですがTmux, Neovimやそれらのプラグインの普及活動になれば嬉しいので書いてみます。&lt;/p&gt;
&lt;h2 id=&#34;動作イメージ&#34;&gt;動作イメージ&lt;/h2&gt;
&lt;p&gt;こんな感じでvanillaのGoプロジェクトをTmuxのwindowに開いておいて、確認したくなったときにすぐwindowを切り替えてコードを書いて実行結果を確認できるようにしている。(Gifの例はGoの書式指定子&lt;code&gt;%+v&lt;/code&gt;の動作を忘れて試してみているところ)&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;go-playground.gif&#34; alt=&#34;go-playground&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;Gifでやっていることは以下&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;GoのSandbox環境を開いたNeovimが起動しているwindowに切り替え&lt;/li&gt;
&lt;li&gt;コードを書く&lt;/li&gt;
&lt;li&gt;Neovim上でターミナルを表示&lt;/li&gt;
&lt;li&gt;&lt;code&gt;make run&lt;/code&gt;を実行してコード実行&lt;/li&gt;
&lt;li&gt;結果を確認&lt;/li&gt;
&lt;li&gt;元いたwindowに戻る&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;tmux-fzfなど筆者のターミナル環境については以下参照&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.kyu08.com/posts/my-dev-setup-terminal&#34; target=&#34;_blank&#34; &gt;開発の効率化のためにやっていること ターミナル編&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;筆者はGoの動作を確認したいことがほとんどなのでこういった構成にしているが、必要に応じてよく使うFWをセットアップした環境を作っておくと便利そう。&lt;/p&gt;
&lt;h2 id=&#34;プロジェクトの内容&#34;&gt;プロジェクトの内容&lt;/h2&gt;
&lt;p&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├── .git
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├── .gitignore
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├── go.mod
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├── go.sum
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├── main.go
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├── main.go.sample
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├── main_test.go
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;└── Makefile
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;基本的に&lt;code&gt;main.go&lt;/code&gt;の中身を編集して、&lt;code&gt;go run .&lt;/code&gt;で実行して実行結果を確認するということをしている。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Makefile&lt;/code&gt;の中身は以下のような感じになっていて、&lt;code&gt;make run&lt;/code&gt;でコード実行、&lt;code&gt;make clear&lt;/code&gt;で&lt;code&gt;main.go&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-Makefile&#34; data-lang=&#34;Makefile&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;.PHONY&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; run clear
&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;run&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;  @go run .
&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;clear&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;  @cp ./main.go.sample ./main.go
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;main.go.sample&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:#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&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;あとはよく見返したくなるコードは&lt;code&gt;main.go&lt;/code&gt;以外のファイル名で保存したり、commitしておくと後からでもさっと確認できてよさそう。(筆者はそこまでやってない)&lt;/p&gt;
&lt;h2 id=&#34;感想&#34;&gt;感想&lt;/h2&gt;
&lt;p&gt;ターミナルから出ずに作業が完結できてうれしい。&lt;/p&gt;
&lt;p&gt;同様のことはGoの場合はブラウザからThe Go Playground(※)を開いても行えるが筆者は何でもターミナルでできると嬉しい人なのでできるようにしてみた。&lt;/p&gt;
&lt;p&gt;※ブラウザ上で実行できるGoのエディタ + 実行環境がセットになったやつ。&lt;div class=&#34;blogcard&#34; data-url=&#34;https://go.dev/play/&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://go.dev/play/&#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://go.dev/doc/gopher/gopher5logo.jpg&#34; alt=&#34;Go Playground - The Go Programming Language&#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 Playground - The Go Programming Language&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://go.dev/play/&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;あとやるとしたらThe Go PlaygroundにあるURL発行機能とかを実現できると他の人への共有も楽になっていいのかもしれない。(今のところあんまり他の人に共有する機会がないので困っていない)&lt;/p&gt;
&lt;h2 id=&#34;補足&#34;&gt;補足&lt;/h2&gt;
&lt;p&gt;最後に補足としてGif内で使っているNeovimのプラグインを紹介します。&lt;/p&gt;
&lt;h3 id=&#34;ターミナル表示&#34;&gt;ターミナル表示&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/voldikss/vim-floaterm&#34; target=&#34;_blank&#34; &gt;voldikss/vim-floaterm&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;floaterm.gif&#34; alt=&#34;floaterm&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;GoのSandbox環境の&lt;code&gt;main.go&lt;/code&gt;に書いたスクリプトを実行するために、Neovimからターミナルを表示するシーンで使っている。&lt;/p&gt;
&lt;p&gt;コード編集してサクっと動作確認したいときなどに便利。(といいつつ最近動作の重さが目立ってきたので&lt;code&gt;&amp;lt;C-z&amp;gt;&lt;/code&gt;でNeovimの起動元に戻ってターミナルを操作することが多い)&lt;/p&gt;
&lt;h3 id=&#34;カーソル移動&#34;&gt;カーソル移動&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/yuki-yano/fuzzy-motion.vim&#34; target=&#34;_blank&#34; &gt;yuki-yano/fuzzy-motion.vim&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;fmt.Printf(&amp;quot;u: %v\n&amp;quot;, u)&lt;/code&gt;の&lt;code&gt;u&lt;/code&gt;から&lt;code&gt;%v&lt;/code&gt;の位置にカーソル移動する際に使っているプラグイン。&lt;/p&gt;
&lt;p&gt;動作のイメージはこんな感じ。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;fuzzy-motion.gif&#34; alt=&#34;fuzzy-motion&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;起動すると文字がグレーアウトするのでジャンプしたい文字列を入力するとその文字にジャンプするためのキーワードを表示してくれるというプラグイン。&lt;/p&gt;
&lt;p&gt;同様の機能をもつプラグインとしてはeasy-motionなどのプラグインが有名だが、fuzzy-motionはジャンプしたい文字列をfuzzy-finder形式で絞り込んでくれるのが大きな特徴。(詳しくはリポジトリのREADME参照)&lt;/p&gt;
&lt;p&gt;筆者はノーマルモードで&lt;code&gt;f&lt;/code&gt;キーを押下するとプラグインが起動するように設定している。&lt;/p&gt;
&lt;p&gt;カーソル移動の効率がよすぎて正直もうこれなしでは開発したくない。&lt;/p&gt;
&lt;h3 id=&#34;lsp-server&#34;&gt;LSP Server&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/neoclide/coc.nvim&#34; target=&#34;_blank&#34; &gt;neoclide/coc.nvim&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Language Serverをホストするためのプラグイン。&lt;/p&gt;
&lt;p&gt;すごく簡単にいうと補完や関数定義を表示したり定義ジャンプできるようにしたりしてくれる。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;coc-nvim.gif&#34; alt=&#34;coc-nvim&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;以上です。ここまで読んでくれてありがとうございました。&lt;/p&gt;
</content>
    </item>
    
    <item>
      <title>デザインパターンをひととおり眺めた感想</title>
      <link>https://blog.kyu08.com/posts/learn-design-pattern/</link>
      <pubDate>Wed, 01 Feb 2023 16:15:48 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/posts/learn-design-pattern/</guid>
      <description>ずっと気になってはいたが2つ~3つくらいしか知らなかったデザインパターンをやっと勉強する気になったのでこのサイトを一通り眺めてみた。 デザイン</description>
      <content>&lt;p&gt;ずっと気になってはいたが2つ~3つくらいしか知らなかったデザインパターンをやっと勉強する気になったのでこのサイトを一通り眺めてみた。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://refactoring.guru/ja/design-patterns&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://refactoring.guru/ja/design-patterns&#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://refactoring.guru/ja/images/refactoring/social/facebook-share-preview.png?id=dbf9e98269595be86eb668f365be6868&#34; alt=&#34;デザインパターン&#34; loading=&#34;lazy&#34;&gt;
    &lt;/div&gt;&lt;div class=&#34;blogcard-content&#34;&gt;
      &lt;div class=&#34;blogcard-title&#34;&gt;デザインパターン&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;デザインパターンは、ソフトウェア設計でよく起きる問題に対する典型的な解決方法です。これらは、事前に用意された、問題解決のための設計図で、適宜変更して、自分のコードにおける特定の設計上の問題の解決に使えます。&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://refactoring.guru/ja/design-patterns&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;こちらのサイトは平易な文章とわかりやすい例で説明がされていて、各言語でのサンプルコードも載せてくれていたのでかなりサクサクと理解できてとてもよかった。(各パターンをC#, C++, Go, Java, php, Python, Ruby, Rust, Swift, TypeScriptで実装した例が紹介されていた)(すごい)&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;li&gt;暗記までする必要はなくて設計のときの参考程度にするとよさそう&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;みたいなことを言っているのをよく聞くのですべてを自分のものにするというよりは軽く雰囲気を理解するくらいのテンションでサイトを眺めてみた。&lt;/p&gt;
&lt;h2 id=&#34;感想&#34;&gt;感想&lt;/h2&gt;
&lt;p&gt;一通り眺めてみて、以下のようなことが重要なんだろうなと感じた。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;interfaceをうまく使って抽象に依存する&lt;/li&gt;
&lt;li&gt;データと振る舞いを分離する&lt;/li&gt;
&lt;li&gt;依存の方向に気を付ける&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;いろんなところで言われていることだが、やはり責務の分離や単一責任の法則を意識することで変更しやすいコードにしていくことがよりよい設計に繋がることを再確認できた。&lt;/p&gt;
&lt;p&gt;いいコードを書けるようになるにはこれらのことを意識しながら実際にコードを書いて実践していくことが重要だと思うのでたくさん試行錯誤していい感じのコード書き力を身につけていきたい。(とても経験豊富な先輩エンジニアも結局自分でサービスを運用して設計の失敗の痛みを感じるのが一番成長できる、というようなことを言っていた)&lt;/p&gt;
&lt;p&gt;設計関連だと &lt;a href=&#34;https://www.amazon.co.jp/dp/4297127830&#34; target=&#34;_blank&#34; &gt;良いコード/悪いコードで学ぶ設計入門 ―保守しやすい 成長し続けるコードの書き方&lt;/a&gt; とか &lt;a href=&#34;https://www.amazon.co.jp/Clean-Architecture-%E9%81%94%E4%BA%BA%E3%81%AB%E5%AD%A6%E3%81%B6%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E3%81%AE%E6%A7%8B%E9%80%A0%E3%81%A8%E8%A8%AD%E8%A8%88-Robert-C-Martin/dp/4048930656&#34; target=&#34;_blank&#34; &gt;Clean Architecture&lt;/a&gt; とかも気になってるので読みたい。&lt;/p&gt;
</content>
    </item>
    
    <item>
      <title>開発の効率化のためにやっていることターミナル編</title>
      <link>https://blog.kyu08.com/posts/my-dev-setup-terminal/</link>
      <pubDate>Wed, 14 Dec 2022 16:15:48 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/posts/my-dev-setup-terminal/</guid>
      <description>【この記事はUnipos Advent Calendar 2022の記事です】 この記事では筆者が開発の効率化のために行っている工夫や使っているツールなどについて紹介します</description>
      <content>&lt;p&gt;【この記事は&lt;a href=&#34;https://qiita.com/advent-calendar/2022/unipos&#34; target=&#34;_blank&#34; &gt;Unipos Advent Calendar 2022&lt;/a&gt;の記事です】&lt;/p&gt;
&lt;p&gt;この記事では筆者が開発の効率化のために行っている工夫や使っているツールなどについて紹介します。
「他にもこんなツールあるよ！」「こんな設定おすすめだよ！」などなどありましたらtwitterとかで教えてもらえると助かります。&lt;/p&gt;
&lt;p&gt;今回はターミナル編です！&lt;/p&gt;
&lt;h2 id=&#34;シェル&#34;&gt;シェル&lt;/h2&gt;
&lt;p&gt;シェルはzshを使っています。 一時期fishも使っていましたが、環境移行のコストが低かったりPOSIX準拠だったりするメリットに旨味を感じてzshに乗り換えました。&lt;/p&gt;
&lt;h3 id=&#34;よく使うalias&#34;&gt;よく使うalias&lt;/h3&gt;
&lt;p&gt;zshでは&lt;code&gt;alias hoge=&#39;echo hoge&#39;&lt;/code&gt;のように記述することでaliasを定義できます。&lt;/p&gt;
&lt;p&gt;ここでは筆者がよく使うaliasをいくつか紹介します。&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-zsh&#34; data-lang=&#34;zsh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;alias m&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;MEMODIR=~/code/memo; cd $MEMODIR; FILE=$MEMODIR/$(date +%Y%m%d).md; if [ ! -e $FILE ]; then echo &amp;#34;# todo \n\n# done\n&amp;#34; &amp;gt;&amp;gt; $FILE; fi; nvim $FILE&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;日毎に&lt;code&gt;yyyymmdd.md&lt;/code&gt;形式の名前のファイルを作成してvimで開く。
ファイルが存在していなければ&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-md&#34; data-lang=&#34;md&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# todo
&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;# done
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;をファイルに書き込んだうえでvimで開く、という内容のワンライナーです。&lt;/p&gt;
&lt;p&gt;実際に呼び出すとこんな感じです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;memo.gif&#34; alt=&#34;memo&#34; loading=&#34;lazy&#34; /&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-md&#34; data-lang=&#34;md&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# todo
&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;-&lt;/span&gt; タスクA
&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;-&lt;/span&gt; 子タスクa
&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;-&lt;/span&gt; 子タスクb
&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;-&lt;/span&gt; タスクB
&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;# done
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;のような感じでタスクを書いていき、完了したら以下のように&lt;code&gt;done&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-md&#34; data-lang=&#34;md&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# todo
&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;-&lt;/span&gt; タスクB
&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;# done
&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;-&lt;/span&gt; タスクA
&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;-&lt;/span&gt; 子タスクa
&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;-&lt;/span&gt; 子タスクb
&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-zsh&#34; data-lang=&#34;zsh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;alias ghw&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;gh repo view -w&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;gh&lt;/code&gt;コマンドを利用して現在いるリポジトリをブラウザでGitHubで開くコマンド&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;ghw.gif&#34; alt=&#34;ghw&#34; loading=&#34;lazy&#34; /&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-zsh&#34; data-lang=&#34;zsh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;alias pbc&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;pbcopy &amp;amp;&amp;amp; pbpaste&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;make test | pbc&lt;/code&gt;のように出力をパイプで&lt;code&gt;pbc&lt;/code&gt;に渡すとクリップボードにコピーしつつ標準出力に出力してくれる。&lt;/p&gt;
&lt;p&gt;コマンドの出力をコピーしたいけど出力内容もその場で確認したいときに便利。&lt;/p&gt;
&lt;p&gt;こちらの記事で紹介されていた。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://takuya-1st.hatenablog.jp/entry/2017/05/30/093000&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://takuya-1st.hatenablog.jp/entry/2017/05/30/093000&#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://ogimage.blog.st-hatena.com/12704830469097614513/10328749687248132970/1496127744&#34; alt=&#34;pbcopy で標準出力の内容をecho表示を維持しつつコピーしたい - それマグで！&#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;pbcopy で標準出力の内容をecho表示を維持しつつコピーしたい - それマグで！&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;pbcopy コマンドはクリップボードのコピーが出来て便利。 pbcopy コマンドを使うと、ターミナルの出力内容をコピーが出来る。便利なコマンド でも困ったことが有る。クリップボードにコピーされた内容を見れない。 takuya@~$ ls / Applications Network Users bin dev home lost&amp;#43;found net private tmp var Library System Volumes cores etc installer.failurerequests mnt opt sbin usr takuya@~$ ls / | pbcopy コピーされる…&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://takuya-1st.hatenablog.jp/entry/2017/05/30/093000&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&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-zsh&#34; data-lang=&#34;zsh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;alias finder&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;open -a Finder ./&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;現在いるディレクトをfinderで開くコマンド&lt;/p&gt;
&lt;p&gt;ごく稀に使う。&lt;/p&gt;
&lt;h3 id=&#34;ディレクトリ移動&#34;&gt;ディレクトリ移動&lt;/h3&gt;
&lt;p&gt;zshにはcdrという、移動したことがあるディレクトリを自動的に保持してくれる機能があります。&lt;/p&gt;
&lt;p&gt;これをいい感じにファジーファインダーから呼び出すスクリプトを公開して下さっている方がいたのでありがたく使わせてもらっています。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://www.rasukarusan.com/entry/2018/08/14/083000&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://www.rasukarusan.com/entry/2018/08/14/083000&#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://cdn.image.st-hatena.com/image/scale/9b31fbd938705281a7c2b0ea30268e113c6e1f95/backend=imagemagick;version=1;width=1300/https%3A%2F%2Fcdn-ak.f.st-hatena.com%2Fimages%2Ffotolife%2Fr%2Frasukarusan%2F20180812%2F20180812205449.gif&#34; alt=&#34;fzfで捗る自作コマンド一覧(zsh) - ハイパーマッスルエンジニア&#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;fzfで捗る自作コマンド一覧(zsh) - ハイパーマッスルエンジニア&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;みんな大好きfzf fzfは結果をインタラクティブに絞り込むだけのコマンドだが、組み合わせ次第でかなり使えるコマンドだ。日本ではpecoの方が有名だが海外ではfzfの方が人気らしい。 github.com 筆者が思うpecoと比較したときのfzfのメリットを述べる。 画面クリアがなく目に優しい fuzzy search(曖昧検索)が可能 絞り込んだものをパイプつなぎでコマンドを適用でき、結果をpreviewとして画面に表示できる カスタマイズが豊富 特にfuzzy searchとpreviewできる点が素晴らしい。またfzfの絞り込み結果の画面サイズを指定できたりとカスタマイズ性が高いのもGO…&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://www.rasukarusan.com/entry/2018/08/14/083000&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;fzfをインストールした上で以下のスクリプトを&lt;code&gt;.zshrc&lt;/code&gt;に記述すると&lt;code&gt;c&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-zsh&#34; data-lang=&#34;zsh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# fzf-cdr &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;alias c&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;fzf-cdr&amp;#39;&lt;/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;function&lt;/span&gt; fzf-cdr&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;    target_dir&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;`&lt;/span&gt;cdr -l | sed &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;s/^[^ ][^ ]*  *//&amp;#39;&lt;/span&gt; | fzf&lt;span style=&#34;color:#e6db74&#34;&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    target_dir&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;`&lt;/span&gt;echo &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;target_dir/&lt;span style=&#34;color:#ae81ff&#34;&gt;\~&lt;/span&gt;/$HOME&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#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;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt; -n &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$target_dir&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        cd $target_dir
&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;fi&lt;/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:#75715e&#34;&gt;# cdrの設定&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;autoload -Uz is-at-least
&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; is-at-least 4.3.11
&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;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  autoload -Uz chpwd_recent_dirs cdr add-zsh-hook
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  add-zsh-hook chpwd chpwd_recent_dirs
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  zstyle &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;:chpwd:*&amp;#39;&lt;/span&gt;      recent-dirs-max &lt;span style=&#34;color:#ae81ff&#34;&gt;500&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  zstyle &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;:chpwd:*&amp;#39;&lt;/span&gt;      recent-dirs-default yes
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  zstyle &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;:completion:*&amp;#39;&lt;/span&gt; recent-dirs-insert both
&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;fi&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;# fzfの設定&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;export FZF_DEFAULT_OPTS&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;--color=fg+:11 --height 70% --reverse --exit-0 --multi&amp;#39;&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;img src=&#34;fzf-cdr.gif&#34; alt=&#34;cdr&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;やっていることは以下です。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;.zshrc&lt;/code&gt;に定義したfzf-cdrを実行&lt;/li&gt;
&lt;li&gt;移動したいディレクトリのパスの一部を入力&lt;/li&gt;
&lt;li&gt;候補から移動したいディレクトリを選択する&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;コマンド履歴検索&#34;&gt;コマンド履歴検索&lt;/h3&gt;
&lt;p&gt;実行したコマンドの履歴についてもfzfを使って絞り込みを行うようにしています。&lt;/p&gt;
&lt;p&gt;これもスクリプトを公開して下さっている方がいたのでありがたく使わせてもらっています。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://techblog.sgr-ksmt.dev/2016/12/10/smart_fzf_history/&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://techblog.sgr-ksmt.dev/2016/12/10/smart_fzf_history/&#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://tech-blog.sgr-ksmt.org/avatar.jpg&#34; alt=&#34;fzfを使ってzshのコマンド履歴検索をスマートに&#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;fzfを使ってzshのコマンド履歴検索をスマートに&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://techblog.sgr-ksmt.dev/2016/12/10/smart_fzf_history/&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;以下のスクリプトを&lt;code&gt;.zshrc&lt;/code&gt;に記述すると、&lt;code&gt;ctrl + r&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-zsh&#34; data-lang=&#34;zsh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt;-history&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;  BUFFER&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;history -n -r &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; | fzf --no-sort +m --query &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$LBUFFER&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; --prompt&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;History &amp;gt; &amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  CURSOR&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;$#BUFFER
&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;zle -N &lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt;-history
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;bindkey &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;^r&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt;-history
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;img src=&#34;command-history.gif&#34; alt=&#34;command-history&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;git操作&#34;&gt;Git操作&lt;/h2&gt;
&lt;p&gt;Git操作のほとんどはGitのTUIクライアントであるLazygitを使っています。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://github.com/jesseduffield/lazygit&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://github.com/jesseduffield/lazygit&#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/d2896804693595df8f89ef1047e17c57f1da3702622b4710dd2032efea7b3518/jesseduffield/lazygit&#34; alt=&#34;GitHub - jesseduffield/lazygit: simple terminal UI for git commands&#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 - jesseduffield/lazygit: simple terminal UI for git commands&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;simple terminal UI for git commands. Contribute to jesseduffield/lazygit development by creating an account on GitHub.&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://github.com/jesseduffield/lazygit&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;Lazygitはターミナル上で動作するリッチなGitクライアントでGitに関する大抵のことを行うことができます。(機能が豊富すぎて何ができて何ができないのかを正確に把握できていない)&lt;/p&gt;
&lt;p&gt;以下はLazygitを使って変更をaddしてcommitしてpushする例です。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;lazygit-push.gif&#34; alt=&#34;lazygit-push&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;見やすいですし、&lt;strong&gt;少ないタイプ数で操作できる&lt;/strong&gt;点でおすすめです。他にも基本的なブランチ操作はもちろんのこと、&lt;code&gt;git rebase -i&lt;/code&gt;相当のこともスピーディーにできるのでよく使っています。&lt;/p&gt;
&lt;p&gt;ちなみに筆者はkdheepak/lazygit.nvimというプラグインを使ってNeovim上からLazygitを呼び出しています。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://github.com/kdheepak/lazygit.nvim&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://github.com/kdheepak/lazygit.nvim&#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/f747a1925f1a95560347d0452451542ec9da819063a2f3f0e10568d443dc2249/kdheepak/lazygit.nvim&#34; alt=&#34;GitHub - kdheepak/lazygit.nvim: Plugin for calling lazygit from within neovim.&#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 - kdheepak/lazygit.nvim: Plugin for calling lazygit from within neovim.&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;Plugin for calling lazygit from within neovim. Contribute to kdheepak/lazygit.nvim development by creating an account on GitHub.&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://github.com/kdheepak/lazygit.nvim&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;筆者はターミナルエミュレータ(以下ターミナル)としてAlacrittyを使っています。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://github.com/alacritty/alacritty&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://github.com/alacritty/alacritty&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail&#34;&gt;
      &lt;img src=&#34;https://repository-images.githubusercontent.com/51980455/c6857780-448b-11ea-95ed-00fdbc59eb0b&#34; alt=&#34;GitHub - alacritty/alacritty: A cross-platform, OpenGL terminal emulator.&#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 - alacritty/alacritty: A cross-platform, OpenGL terminal emulator.&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;A cross-platform, OpenGL terminal emulator. Contribute to alacritty/alacritty development by creating an account on GitHub.&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://github.com/alacritty/alacritty&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;筆者は普段開発にNeovimを利用しているのですが、以前からプロジェクトの全文検索に時間がかかってしまう点が気になっていました。
動作が高速なターミナルを探していたところRust製のターミナルであるAlacrittyにたどり着きました。&lt;/p&gt;
&lt;p&gt;iTerm2からの乗り換えでしたが満足できるだけの速度になりました。&lt;strong&gt;ターミナルの速度を早くしたい人にはオススメ&lt;/strong&gt;です。あとは&lt;strong&gt;設定をyamlで記述できる&lt;/strong&gt;のも好みなポイントです。&lt;/p&gt;
&lt;p&gt;カラースキームはTokyo Nightを利用しています。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://github.com/zatchheems/tokyo-night-alacritty-theme&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://github.com/zatchheems/tokyo-night-alacritty-theme&#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/a9d2942739260f0c7dbd81ae838b71cf8fc8f5b9f16c8cdce820926b1c7fde4c/zatchheems/tokyo-night-alacritty-theme&#34; alt=&#34;GitHub - zatchheems/tokyo-night-alacritty-theme: A slick dark theme for Alacritty based on the Tokyo Night VS Code theme and ported from the Vim theme of the same name.&#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 - zatchheems/tokyo-night-alacritty-theme: A slick dark theme for Alacritty based on the Tokyo Night VS Code theme and ported from the Vim theme of the same name.&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;A slick dark theme for Alacritty based on the Tokyo Night VS Code theme and ported from the Vim theme of the same name. - zatchheems/tokyo-night-alacritty-theme&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://github.com/zatchheems/tokyo-night-alacritty-theme&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;tokyonight.webp&#34; alt=&#34;tokyonight&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;Alacrittyにはタブ機能がなくタブ的な機能を実現するためにはtmuxなどのターミナルマルチプレクサを利用する必要があるため筆者はtmuxを利用しています。
設定・プラグインなどは後述しますが、tmuxの操作感も好みなので割と満足しています。&lt;/p&gt;
&lt;p&gt;他にもRust製のターミナルとしてWarp, Weztermなどがありますが筆者の環境ではWarpはNeovimのcolorschemeの反映がうまくできず、Weztermは画面の再描画まわりの不具合が多少あったため、採用しませんでした。(Warp便利そうだしみやすいので使いたかった)&lt;/p&gt;
&lt;h2 id=&#34;ターミナルのタブ管理&#34;&gt;ターミナルのタブ管理&lt;/h2&gt;
&lt;p&gt;前述の通りAlacrittyにはタブ機能がないため、tmuxを使ってターミナルのタブ管理を行っています。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://github.com/tmux/tmux&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://github.com/tmux/tmux&#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/71fd2cba28fec19272d3ad5aba36b0c8e03bcd24d55a2a9ebad2517c96317849/tmux/tmux&#34; alt=&#34;GitHub - tmux/tmux: tmux source code&#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 - tmux/tmux: tmux source code&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;tmux source code. Contribute to tmux/tmux development by creating an account on GitHub.&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://github.com/tmux/tmux&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;h3 id=&#34;ステータスラインの表示&#34;&gt;ステータスラインの表示&lt;/h3&gt;
&lt;p&gt;ステータスラインは比較的シンプルにしていて、&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ウィンドウ一覧&lt;/li&gt;
&lt;li&gt;現在時刻&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;を表示するようにしています。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;tmux-status-line.webp&#34; alt=&#34;tmux-status-line&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;普段の開発ではプロジェクトごとにウィンドウを開き、必要に応じて切り替える運用にしています。&lt;/p&gt;
&lt;h3 id=&#34;ウィンドウの切り替え&#34;&gt;ウィンドウの切り替え&lt;/h3&gt;
&lt;p&gt;筆者はふだんプロジェクトごとのウィンドウに加えてmemo用のウィンドウ・dotfiles用のウィンドウなども開いており、常時ウィンドウが15前後あります。筆者は簡単なタスク管理もmemo用ウィンドウに立ち上げたNeovim内で行っているため、ウィンドウの切り替えを頻繁に行います。&lt;/p&gt;
&lt;p&gt;以前まではウィンドウ切り替えを&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;prefix + w&lt;/code&gt; でウィンドウの一覧を表示&lt;/li&gt;
&lt;li&gt;目的のウィンドウの位置を確認&lt;/li&gt;
&lt;li&gt;目的のウィンドウまで &lt;code&gt;ctrl + n&lt;/code&gt;, &lt;code&gt;ctrl + p&lt;/code&gt; で移動&lt;/li&gt;
&lt;li&gt;選択する&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;という手順で行っていましたがウィンドウが増えてくると地味にウィンドウ移動が大変になっていきました。以下は従来のウィンドウ切り替えの様子です。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;tmux-window.gif&#34; alt=&#34;tmux-window&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;どうにかもう少し楽にウィンドウ切り替えをできないかと探していたところsainnhe/tmux-fzfに出会いました。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://github.com/sainnhe/tmux-fzf&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://github.com/sainnhe/tmux-fzf&#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/402a4a1d7416da13fdb8297946d8dc1650593bdee43d8257a4dd707d67ac85cf/sainnhe/tmux-fzf&#34; alt=&#34;GitHub - sainnhe/tmux-fzf: Use fzf to manage your tmux work environment!&#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 - sainnhe/tmux-fzf: Use fzf to manage your tmux work environment!&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;Use fzf to manage your tmux work environment! Contribute to sainnhe/tmux-fzf development by creating an account on GitHub.&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://github.com/sainnhe/tmux-fzf&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;sainnhe/tmux-fzfはファジーファインダーで効率的にtmuxを操作するためのプラグインです。&lt;/p&gt;
&lt;p&gt;詳しくはリポジトリのREADMEに譲りますが、&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;セッション管理&lt;/li&gt;
&lt;li&gt;ウィンドウ管理&lt;/li&gt;
&lt;li&gt;ペイン管理&lt;/li&gt;
&lt;li&gt;コマンドの検索&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;などが可能です。&lt;/p&gt;
&lt;p&gt;筆者はウィンドウ管理機能の中のウィンドウの切り替え機能を使っています。
sainnhe/tmux-fzfを使うようにしたことでウィンドウ切り替えを&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;prefix&lt;/code&gt; + &lt;code&gt;prefix&lt;/code&gt;  でtmux-fzfのウィンドウ一覧を表示&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;img src=&#34;tmux-fzf.gif&#34; alt=&#34;tmux-fzf&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;おわりに&#34;&gt;おわりに&lt;/h2&gt;
&lt;p&gt;ここまで読んでくださってありがとうございました。&lt;/p&gt;
&lt;p&gt;需要がありそうだったら&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Neovim編&lt;/li&gt;
&lt;li&gt;alfred編&lt;/li&gt;
&lt;li&gt;chrome拡張機能編&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;なども書こうと思います。&lt;/p&gt;
</content>
    </item>
    
    <item>
      <title>『コンサル一年目が学ぶこと』を読んだ</title>
      <link>https://blog.kyu08.com/posts/consultant/</link>
      <pubDate>Sat, 25 Dec 2021 16:15:48 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/posts/consultant/</guid>
      <description>コンサル一年目が学ぶこと を読んだ。 何を期待して読んだのか これまで技術の勉強はしたことがあったが、社会人として普遍的なスキルである 問題解決能力</description>
      <content>&lt;p&gt;&lt;a href=&#34;https://www.amazon.co.jp/%E3%82%B3%E3%83%B3%E3%82%B5%E3%83%AB%E4%B8%80%E5%B9%B4%E7%9B%AE%E3%81%8C%E5%AD%A6%E3%81%B6%E3%81%93%E3%81%A8-%E5%A4%A7%E7%9F%B3%E5%93%B2%E4%B9%8B-ebook/dp/B00MA671WW/ref=sr_1_5?adgrpid=89884031168&amp;amp;gclid=CjwKCAiAhreNBhAYEiwAFGGKPLfeLxQ_KIeJv22itv63KSRBjnAb3p0hH0Q0JvgN6FzTeD2J6dcsQBoCs3QQAvD_BwE&amp;amp;hvadid=553974437471&amp;amp;hvdev=c&amp;amp;hvlocphy=1009307&amp;amp;hvnetw=g&amp;amp;hvqmt=e&amp;amp;hvrand=17984675329684059400&amp;amp;hvtargid=kwd-416077613251&amp;amp;hydadcr=27493_14478962&amp;amp;jp-ad-ap=0&amp;amp;keywords=%E3%82%B3%E3%83%B3%E3%82%B5%E3%83%AB&amp;#43;%E4%B8%80&amp;#43;%E5%B9%B4&amp;#43;%E7%9B%AE&amp;#43;%E3%81%8C&amp;#43;%E5%AD%A6%E3%81%B6&amp;#43;%E3%81%93%E3%81%A8&amp;amp;qid=1638793971&amp;amp;sr=8-5&#34; target=&#34;_blank&#34; &gt;コンサル一年目が学ぶこと&lt;/a&gt; を読んだ。&lt;/p&gt;
&lt;h2 id=&#34;何を期待して読んだのか&#34;&gt;何を期待して読んだのか&lt;/h2&gt;
&lt;p&gt;これまで技術の勉強はしたことがあったが、社会人として普遍的なスキルである&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;問題解決能力&lt;/li&gt;
&lt;li&gt;仕事を円滑に進めるためのコミュニケーションの取り方&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;あたりをちゃんと学んだことがなく、一度入門書的なものに触れたいと思っていたので読んでみた。&lt;/p&gt;
&lt;h2 id=&#34;学び&#34;&gt;学び&lt;/h2&gt;
&lt;p&gt;印象に残っているのは以下。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;端的に話す&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;仮説を持って行動する&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;重要なことに時間を使う&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;期待値のすり合わせを怠らない&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Quick and Dirty&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;それぞれ簡単に補足していく。&lt;/p&gt;
&lt;h3 id=&#34;端的に話すtalk-straight&#34;&gt;端的に話す(Talk Straight)&lt;/h3&gt;
&lt;p&gt;聞かれたことに対してストレートに答える。具体的には&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;端的に喋る&lt;/li&gt;
&lt;li&gt;素直に話す&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ことが重要。&lt;/p&gt;
&lt;p&gt;これは相手の立場に立ってみれば当然で、質問をしたのにその答えがなかなか返ってこないと「結局何がいいたいんだ？」となってしまう。&lt;/p&gt;
&lt;p&gt;とは言いつつも、自分自身も自分の思考が整理できていない時は特にだらだらと喋ってしまいがちなので、そういう時はいいチャンスだと思って一旦思考を整理するようにしたい。&lt;/p&gt;
&lt;h3 id=&#34;仮説を持って行動する&#34;&gt;仮説を持って行動する&lt;/h3&gt;
&lt;p&gt;1から10まで調査しきっていては時間が足りない。最低限の調査をして仮説を立てたら、検証 -&amp;gt; 仮説の修正のループを高速で回していくことで限られた時間で精度の高い結論を導くことができる。&lt;/p&gt;
&lt;p&gt;仮説思考を身につける第1歩として、仮説を持つクセをつけるためにあらゆる事象に対して「自分はどう思うのか」「なぜそう思うのか」というスタンスを持つことを心がけたい。&lt;/p&gt;
&lt;h3 id=&#34;重要なことに時間を使う&#34;&gt;重要なことに時間を使う&lt;/h3&gt;
&lt;p&gt;使える時間は限られているので費用対効果を常に意識して時間の使い方を決める。&lt;/p&gt;
&lt;p&gt;仮説思考の話とも繋がるが優先順位を設定して重要な課題から手をつけていきたい。&lt;/p&gt;
&lt;p&gt;自分に振ってきたタスクどうしの優先順位だけでなく、もう一段上の視座で自分/自チームが今本当に取り組むべきことは何なのか、という思考を心がけたい。&lt;/p&gt;
&lt;h3 id=&#34;期待値のすり合わせを怠らない&#34;&gt;期待値のすり合わせを怠らない&lt;/h3&gt;
&lt;p&gt;求められていないことに時間を使っても成果には繋がらない。まずは自分が何を期待されているかを正確に把握することが重要。&lt;/p&gt;
&lt;p&gt;自分の認識がズレていて後になって手戻りが発生することが稀によくあるので、タスクを振られた際などにその場で&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;そのタスクの目的&lt;/li&gt;
&lt;li&gt;求められているアウトプット&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;を明確にするように心がけたい。&lt;/p&gt;
&lt;h3 id=&#34;quick-and-dirty&#34;&gt;Quick and Dirty&lt;/h3&gt;
&lt;p&gt;3日間かけて100% のアウトプットを出すのではなく、まずは3時間で30% のアウトプットをだすべき。&lt;/p&gt;
&lt;p&gt;こまめにアウトプットを行ってフィードバックを得ることができれば間違った方向に進んでしまって時間を浪費する前に軌道修正できる。&lt;/p&gt;
&lt;h2 id=&#34;まとめ&#34;&gt;まとめ&lt;/h2&gt;
&lt;p&gt;この本を読んだことの収穫としては、自分の中でぼんやりと課題感としてあった&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ただがむしゃらに取り組むのではなく効率よく問題を解決するにはどうすればいいのか&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;というイシューへの回答の1つである、&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;重要思考・仮説思考を用いる&lt;/li&gt;
&lt;li&gt;Quick and Dirty&lt;/li&gt;
&lt;li&gt;期待値のすり合わせを怠らない&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;という考え方に出会えたことが挙げられると思う。&lt;/p&gt;
&lt;p&gt;また、コンサルタントのプロフェッショナリズムに触れて自分も周囲の期待を越え続ける存在でありたいと思った。&lt;/p&gt;
&lt;h3 id=&#34;おまけ&#34;&gt;おまけ&lt;/h3&gt;
&lt;p&gt;「仮説思考をやっていこうと思いました」(意訳) という話を上長にしたところ『イシューからはじめよ』をおすすめされたのでこちらも読んでみようと思う。&lt;/p&gt;
</content>
    </item>
    
    <item>
      <title>Elmで固定長配列が扱えるライブラリelm-static-arrayを触ってみた</title>
      <link>https://blog.kyu08.com/posts/2021121217-elm-static-array/</link>
      <pubDate>Thu, 16 Dec 2021 16:15:48 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/posts/2021121217-elm-static-array/</guid>
      <description>Elmで固定長配列を扱うためのライブラリelm-static-arrayを触ってみたので感じたことを書いていきます。 elm-static-array とは elm-static-array はElmで固定長</description>
      <content>&lt;p&gt;Elmで固定長配列を扱うためのライブラリelm-static-arrayを触ってみたので感じたことを書いていきます。&lt;/p&gt;
&lt;h2 id=&#34;elm-static-array-とは&#34;&gt;elm-static-array とは&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://package.elm-lang.org/packages/Orasund/elm-static-array/latest/&#34; target=&#34;_blank&#34; &gt;elm-static-array&lt;/a&gt; はElmで固定長配列を扱うためのライブラリです。&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-elm&#34; data-lang=&#34;elm&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- StaticArray&lt;/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;-- 長さ 4 の配列&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;arrayLength&lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;StaticArray&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Index&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;Four&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:#75715e&#34;&gt;-- 通常の Array&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ordinaryArray &lt;span style=&#34;color:#a6e22e&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Array&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;String&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;どんな場面で使ったか&#34;&gt;どんな場面で使ったか&lt;/h2&gt;
&lt;p&gt;趣味で開発している麻雀の点数集計アプリで使いました。&lt;/p&gt;
&lt;p&gt;各プレイヤーの試合毎のスコアを記録して合計を表示するだけの簡単なアプリケーションです。(※実際には順位点やトビ賞の計算などもやっていますがここでは割愛)&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;jan-log-demo.webp&#34; alt=&#34;jan-log-demo.web&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;ここで &lt;strong&gt;参加者の名前&lt;/strong&gt; および &lt;strong&gt;その試合のスコア&lt;/strong&gt; を &lt;code&gt;Array String&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-elm&#34; data-lang=&#34;elm&#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:#66d9ef&#34;&gt;alias&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Players&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Array&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;type&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;alias&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Points&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Array&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;String&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;これではあらゆる長さの配列をとることができてしまいますが、仕様上どちらも長さ4もしくは5の配列しかとることはありません。
そこでelm-static-arrayを使って配列の長さの情報を型で表現しました。&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-elm&#34; data-lang=&#34;elm&#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:#66d9ef&#34;&gt;Players&lt;/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;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Players4&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;StaticArray&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Index&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;Four&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Player&lt;/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;|&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Players5&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;StaticArray&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Index&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;Five&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Player&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;type&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Points&lt;/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;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Points4&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;StaticArray&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Index&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;Four&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Point&lt;/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;|&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Points5&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;StaticArray&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Index&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;Five&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Point&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;h2 id=&#34;elm-static-array-を使うことで得られるメリット&#34;&gt;elm-static-array を使うことで得られるメリット&lt;/h2&gt;
&lt;h3 id=&#34;メリット仕様を型で表現しやすい&#34;&gt;メリット①：仕様を型で表現しやすい&lt;/h3&gt;
&lt;p&gt;上でも触れましたが、長さが4もしく5の &lt;code&gt;Point&lt;/code&gt; の配列はelm-static-arrayを使うと以下のように定義できます。&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-elm&#34; data-lang=&#34;elm&#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:#66d9ef&#34;&gt;Points&lt;/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;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Points4&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;StaticArray&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Index&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;Four&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Point&lt;/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;|&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Points5&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;StaticArray&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Index&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;Five&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Point&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;elm-static-arrayを使うことで型に配列の長さの情報を持たせることができるため、&lt;strong&gt;仕様を型で表現しやすくなり&lt;/strong&gt;コードの可読性向上に繋がります。&lt;/p&gt;
&lt;!-- 注釈で動画リンクを貼りたい --&gt;
&lt;!-- 仕様上ありえない状態を表現できないようなコードを書くべきである、という指針 --&gt;
&lt;p&gt;また、それにともなって &lt;strong&gt;仕様上ありえない状態が存在できないコードを書きやすくなる&lt;/strong&gt;ため&lt;strong&gt;バグの可能性を減らす&lt;/strong&gt; ことができます。&lt;/p&gt;
&lt;p&gt;たとえば以下の &lt;code&gt;isDefaultRound&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-elm&#34; data-lang=&#34;elm&#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:#66d9ef&#34;&gt;Round&lt;/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;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Round4&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Round4Value&lt;/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;|&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Round5&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Round5Value&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;type&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;alias&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Round4Value&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#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;-- 長さが 4 の StaticArray&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    { points &lt;span style=&#34;color:#a6e22e&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;StaticArray&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Index&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;Four&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Point&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    , seatingOrder &lt;span style=&#34;color:#a6e22e&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Maybe&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;SeatingOrder&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    , tobisho &lt;span style=&#34;color:#a6e22e&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;StaticArray&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Index&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;Four&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Point&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&gt;&lt;/span&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:#66d9ef&#34;&gt;alias&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Round5Value&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#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;-- 長さが 5 の StaticArray&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    { points &lt;span style=&#34;color:#a6e22e&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;StaticArray&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Index&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;Five&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Point&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    , seatingOrder &lt;span style=&#34;color:#a6e22e&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Maybe&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;SeatingOrder&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    , tobisho &lt;span style=&#34;color:#a6e22e&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;StaticArray&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Index&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;Five&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Point&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;isDefaultRound &lt;span style=&#34;color:#a6e22e&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Round&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Bool&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;isDefaultRound round &lt;span style=&#34;color:#a6e22e&#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;case&lt;/span&gt; round &lt;span style=&#34;color:#66d9ef&#34;&gt;of&lt;/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;Round4&lt;/span&gt; _ &lt;span style=&#34;color:#a6e22e&#34;&gt;-&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            round &lt;span style=&#34;color:#a6e22e&#34;&gt;==&lt;/span&gt; initRound&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;
&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;Round5&lt;/span&gt; _ &lt;span style=&#34;color:#a6e22e&#34;&gt;-&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            round &lt;span style=&#34;color:#a6e22e&#34;&gt;==&lt;/span&gt; initRound&lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;仕様上 &lt;code&gt;Points&lt;/code&gt; の長さは4もしくは5になるのですが、elm-static-arrayを使って書くと &lt;code&gt;isDefaultRound&lt;/code&gt;関数のパターンマッチの中では仕様上ありえる値の分岐だけを扱えばいいことがわかると思います。&lt;/p&gt;
&lt;p&gt;これをelm-static-arrayを使わずに書いた場合は以下のように仕様上ありえないパターンを扱う必要があります。&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-elm&#34; data-lang=&#34;elm&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;isDefaultRound &lt;span style=&#34;color:#a6e22e&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Round&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Bool&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;isDefaultRound round &lt;span style=&#34;color:#a6e22e&#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;case&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Array&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;.&lt;/span&gt;length round&lt;span style=&#34;color:#a6e22e&#34;&gt;.&lt;/span&gt;points &lt;span style=&#34;color:#66d9ef&#34;&gt;of&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;-&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            round &lt;span style=&#34;color:#a6e22e&#34;&gt;==&lt;/span&gt; initRound&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;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;-&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            round &lt;span style=&#34;color:#a6e22e&#34;&gt;==&lt;/span&gt; initRound&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&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        _ &lt;span style=&#34;color:#a6e22e&#34;&gt;-&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:#66d9ef&#34;&gt;False&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;elm-static-arrayを使うことで仕様上ありえないパターンを扱う必要がなくなりバグの可能性を減らすことができます。&lt;/p&gt;
&lt;h3 id=&#34;メリット配列の要素を取得する際に-maybe-をハンドリングする必要がない&#34;&gt;メリット②：配列の要素を取得する際に &lt;code&gt;Maybe&lt;/code&gt; をハンドリングする必要がない&lt;/h3&gt;
&lt;p&gt;配列の要素を取得する際も通常のArrayとの違いを感じることができます。&lt;/p&gt;
&lt;p&gt;以下は配列の要素を取得する &lt;code&gt;get&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-elm&#34; data-lang=&#34;elm&#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;get &lt;span style=&#34;color:#a6e22e&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Int&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Array&lt;/span&gt; a &lt;span style=&#34;color:#a6e22e&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Maybe&lt;/span&gt; a
&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;-- StaticArray&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;get &lt;span style=&#34;color:#a6e22e&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Index&lt;/span&gt; n &lt;span style=&#34;color:#a6e22e&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;StaticArray&lt;/span&gt; n a &lt;span style=&#34;color:#a6e22e&#34;&gt;-&amp;gt;&lt;/span&gt; a
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;注目すべきは &lt;strong&gt;返り値の型&lt;/strong&gt; です。&lt;/p&gt;
&lt;p&gt;通常の配列では要素の型が &lt;code&gt;a&lt;/code&gt; である配列の要素を取得する際の返り値の型が &lt;code&gt;Maybe a&lt;/code&gt; になりますが、 elm-static-arrayでは返り値の型が &lt;code&gt;a&lt;/code&gt; になります。
これにより &lt;strong&gt;&lt;code&gt;Maybe&lt;/code&gt; をハンドリングする必要がなくなるためよりシンプルに記述できます。&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;懸念点&#34;&gt;懸念点&lt;/h2&gt;
&lt;p&gt;逆に懸念だと感じたのは以下の2つです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Arrayに定義されているすべての関数が定義されているわけではない&lt;/li&gt;
&lt;li&gt;elm-static-arrayの書き方に慣れるまでは時間がかかる&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;それぞれ補足していきます。&lt;/p&gt;
&lt;h3 id=&#34;懸念array-に定義されているすべての関数が定義されているわけではない&#34;&gt;懸念①：Array に定義されているすべての関数が定義されているわけではない&lt;/h3&gt;
&lt;p&gt;Arrayに生えている関数がStaticArrayには生えてなかったりするので、都度Arrayに変換して処理をした上で再度StaticArrayに変換する、というような工程が必要になる場面がありました。StaticArrayには最小限の関数しか定義されていないので例えば &lt;code&gt;filter&lt;/code&gt; や &lt;code&gt;foldl(foldr)&lt;/code&gt; などは一度Arrayなどに変換し、処理してから再度StaticArrayに変換しなおす必要がありました。&lt;/p&gt;
&lt;p&gt;以下はStaticArrayをArrayに変換してfilterしてStaticArrayに戻すコード例です。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;StaticArray.fromList&lt;/code&gt; がheadとtailを引数に取るため若干コード量が増えてしまいます。&lt;/p&gt;
&lt;p&gt;headの要素を取り出す際にNothingをハンドリングしなければならないのがちょっと億劫ですね。(もちろんコンパイラはStaticArrayから変換されたArrayであることなど知るよしもないので仕方ないのですが)&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-elm&#34; data-lang=&#34;elm&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;filterStaticArray &lt;span style=&#34;color:#a6e22e&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;StaticArray&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Index&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;Four&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;String&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;StaticArray&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Index&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;Four&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;filterStaticArray staticArray &lt;span style=&#34;color:#a6e22e&#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;let&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        filteredArray &lt;span style=&#34;color:#a6e22e&#34;&gt;=&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            staticArray
&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;|&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;StaticArray&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;.&lt;/span&gt;toArray
&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;|&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Array&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;.&lt;/span&gt;filter (&lt;span style=&#34;color:#a6e22e&#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;        head &lt;span style=&#34;color:#a6e22e&#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;Maybe&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;.&lt;/span&gt;withDefault &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;undefined&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;&amp;lt;|&lt;/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;Array&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;.&lt;/span&gt;get
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#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;                    filteredArray
&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;        tail &lt;span style=&#34;color:#a6e22e&#34;&gt;=&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            filteredArray
&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;|&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Array&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;.&lt;/span&gt;slice &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;Array&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;.&lt;/span&gt;length filteredArray)
&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;|&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Array&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;.&lt;/span&gt;toList
&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;in&lt;/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;StaticArray&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;.&lt;/span&gt;fromList
&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;Length&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;.&lt;/span&gt;four
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        head
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        tail
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;懸念staticarray-の書き方に慣れるまでは時間がかかる&#34;&gt;懸念②：StaticArray の書き方に慣れるまでは時間がかかる&lt;/h3&gt;
&lt;p&gt;たとえばインデックスを指定してStaticArrayの要素を取得するget関数を使おうと&lt;a href=&#34;https://package.elm-lang.org/packages/Orasund/elm-static-array/latest/StaticArray#get&#34; target=&#34;_blank&#34; &gt;ドキュメント&lt;/a&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-elm&#34; data-lang=&#34;elm&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- Gets an element of the array. Note that it only possible if the index is in bound. Therefore eliminating Off-by-one errors.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;get &lt;span style=&#34;color:#a6e22e&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Index&lt;/span&gt; n &lt;span style=&#34;color:#a6e22e&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;StaticArray&lt;/span&gt; n a &lt;span style=&#34;color:#a6e22e&#34;&gt;-&amp;gt;&lt;/span&gt; a
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;自分のElm力の乏しさのせいではありますがドキュメントに具体的なコード例が示されていないこともあり、動かすまでにそれなりの試行錯誤が必要でした。(当時はGitHubで検索しても引っ掛からずに絶望していましたが、検索の仕方が悪かっただけだということに執筆時に気付きました。)
実際には以下のような使い方をする必要があります。ちゃんと動くコードを書くのに1hくらい費やしてしまいました。&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-elm&#34; data-lang=&#34;elm&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;head &lt;span style=&#34;color:#a6e22e&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Element&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;head &lt;span style=&#34;color:#a6e22e&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;StaticArray&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;.&lt;/span&gt;get (&lt;span style=&#34;color:#66d9ef&#34;&gt;Index&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;.&lt;/span&gt;fromModBy &lt;span style=&#34;color:#66d9ef&#34;&gt;Length&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;.&lt;/span&gt;four &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;) someStaticArray
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;まとめると、 &lt;strong&gt;多少の手間が必要になる&lt;/strong&gt; ということかなと思います。
このあたりがelm-static-arrayの作者が &lt;a href=&#34;https://package.elm-lang.org/packages/Orasund/elm-static-array/latest/&#34; target=&#34;_blank&#34; &gt;README&lt;/a&gt; の中で以下のように言っている所以かなと感じました。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Construction is a bit slower (should be neglectable for most cases).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;ただ逆に言えばネガティブに感じたのは上記のそれくらいで、基本的にはメリットの方が大きく感じたためこれからも必要であれば使っていきたいと思っています。&lt;/p&gt;
&lt;h2 id=&#34;まとめ&#34;&gt;まとめ&lt;/h2&gt;
&lt;p&gt;Elmで固定長配列を扱うためのライブラリelm-static-arrayを触った感想を書いてみました。&lt;/p&gt;
&lt;p&gt;仕様を型で表現しやすくなるという点に魅力を感じたので今後も必要なケースでは積極的に使っていきたいと思います。&lt;/p&gt;
&lt;p&gt;また、ひさびさに個人開発をして、なかなか時間が取れずコードの意図や全体像をよく忘れたりするので個人開発においても可読性が高かったり意図の伝わりやすいコードを書くことの重要性が身に染みました。&lt;/p&gt;
&lt;p&gt;時間がなかなかとれないからこそ質の高いコードを意識的に書いていきたいなと思います。&lt;/p&gt;
</content>
    </item>
    
    <item>
      <title>自己紹介</title>
      <link>https://blog.kyu08.com/posts/20211203-introduce/</link>
      <pubDate>Fri, 03 Dec 2021 01:15:48 +0900</pubDate>
      
      <guid>https://blog.kyu08.com/posts/20211203-introduce/</guid>
      <description>今年の2月ごろから下書きを放置していて書いてなかったことに気付いてしまったので書きます。 都内でエンジニアをしています。 Neovim, Elm, TypeScript, 麻雀, ガジェット</description>
      <content>&lt;p&gt;今年の2月ごろから下書きを放置していて書いてなかったことに気付いてしまったので書きます。&lt;/p&gt;
&lt;p&gt;都内でエンジニアをしています。&lt;/p&gt;
&lt;p&gt;Neovim, Elm, TypeScript, 麻雀, ガジェットがすきです。&lt;/p&gt;
&lt;p&gt;今月はブログたくさんかくぞ〜〜&lt;/p&gt;
&lt;p&gt;おわり&lt;/p&gt;
</content>
    </item>
    
    <item>
      <title>2020年をかんたんに振り返る</title>
      <link>https://blog.kyu08.com/posts/20201231-review-of-2020/</link>
      <pubDate>Wed, 30 Dec 2020 16:15:48 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/posts/20201231-review-of-2020/</guid>
      <description>このブログを作った動機でもある今年の振り返りを書いていきます。 今年はいろいろ大変な一年でしたが家にいる時間が増えた分たくさんやりたいことがで</description>
      <content>&lt;p&gt;このブログを作った動機でもある今年の振り返りを書いていきます。&lt;/p&gt;
&lt;p&gt;今年はいろいろ大変な一年でしたが家にいる時間が増えた分たくさんやりたいことができた一年でもありました。&lt;/p&gt;
&lt;p&gt;静的型付け言語デビューしたり(TypeScript, Scala)、内定先の選考インターンで課題だと感じた設計関連のインプット・アウトプットをたくさんできたのがよかったです。&lt;/p&gt;
&lt;p&gt;あとはいくつか作りたいものをつくれて充実感があってよかったです。では振り返っていきます。&lt;/p&gt;
&lt;h2 id=&#34;1月2月&#34;&gt;1月~2月&lt;/h2&gt;
&lt;p&gt;のちに内定先となる第一志望の企業の本選考インターン(の続き)をやっていました。いちおう詳細は伏せますが、メンターの方々に助けていただきながらがんばりました。Slackでやりとりをしていたのですが、年末年始も反応していただきとっても助かりました。&lt;/p&gt;
&lt;p&gt;使った技術はReactです。&lt;/p&gt;
&lt;p&gt;無事内定は頂けたものの、モデルはどういう基準で定めたの?という質問に対して全然うまく説明できず、設計関連の知識の足りなさを強く感じました。&lt;/p&gt;
&lt;h2 id=&#34;3月&#34;&gt;3月&lt;/h2&gt;
&lt;p&gt;N予備校の&amp;quot;サーバーサイドプログラミング入門&amp;quot;と&amp;quot;実践サーバーサイドプログラミング&amp;quot;をやりました。&lt;/p&gt;
&lt;p&gt;はじめて仮想環境をつかってssh接続しながら開発しました。&lt;/p&gt;
&lt;p&gt;動くコードが載ってるだけでなく割と詳しめに背景となる知識を解説してあってかなりわかりやすかったです。自分も書いたコードの背景や実装の根拠をしっかりと語れるようになりたい&amp;hellip;。&lt;/p&gt;
&lt;h2 id=&#34;4月&#34;&gt;4月&lt;/h2&gt;
&lt;p&gt;本選考インターンでつくったWebAppのリファクタリングをしました。
あとはTypeScriptの勉強をはじめました。やったことは&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.typescriptlang.org/docs/handbook/intro.html&#34; target=&#34;_blank&#34; &gt;TypeScript HANDBOOK&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://typescript-jp.gitbook.io/deep-dive/&#34; target=&#34;_blank&#34; &gt;TypeScript DeepDive&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;あたりです。始めて静的型付けの言語に触れて表現力の豊かさを感じました。わかりやすさと堅牢さが得られそう&amp;hellip;、エディタがいろいろ教えてくれるので開発効率も上がりそう&amp;hellip;などと感じました。&lt;/p&gt;
&lt;h2 id=&#34;5月&#34;&gt;5月&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;CLIのtodoアプリをNode.js(TypeScript) でつくった&lt;/li&gt;
&lt;li&gt;読みかけだったリーダブルコードをよんだ&lt;/li&gt;
&lt;li&gt;Repositoryパターンを実装してみた&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;CLIのtodoアプリはCLIでTODOを確認したくなったのとTypeScriptで何か作ってみたくなったので作って &lt;a href=&#34;https://www.npmjs.com/package/great-todo-cli&#34; target=&#34;_blank&#34; &gt;npm で公開しました。&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;責務の分離を意識して書いたので今までよりは見通しの良いコードを書けたと思っています。&lt;/p&gt;
&lt;p&gt;あとははじめてWebpackの設定を書いて、&lt;code&gt;create-react-app&lt;/code&gt; の便利さを感じました。(今まで&lt;code&gt;create-react-app&lt;/code&gt;が何をしてくれているのかわかってなかった&amp;hellip;)&lt;/p&gt;
&lt;h2 id=&#34;6月&#34;&gt;6月&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.amazon.co.jp/dp/B01L8SEVYI/ref=dp-kindle-redirect?_encoding=UTF8&amp;amp;btkr=1&#34; target=&#34;_blank&#34; &gt;オブジェクト指向設計実践ガイド　～Rubyでわかる 進化しつづける柔軟なアプリケーションの育て方&lt;/a&gt;
をよんだ&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.amazon.co.jp/dp/B073GSDBGT/ref=dp-kindle-redirect?_encoding=UTF8&amp;amp;btkr=1&#34; target=&#34;_blank&#34; &gt;現場で役立つシステム設計の原則 〜変更を楽で安全にするオブジェクト指向の実践技法&lt;/a&gt;
をよんだ&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.amazon.co.jp/dp/B082WXZVPC/ref=dp-kindle-redirect?_encoding=UTF8&amp;amp;btkr=1&#34; target=&#34;_blank&#34; &gt;ドメイン駆動設計入門 ボトムアップでわかる！ドメイン駆動設計の基本&lt;/a&gt;
をよんだ&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;6月はたくさん本を読みました。毎日作業を始める前に1時間本を読むスタイルが自分にあっている感じでした。&lt;/p&gt;
&lt;p&gt;RubyのOOP本は&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;そのあと読んだ現場で役立つ~は&amp;quot;ドメインモデルとは&amp;quot;みたいな話が書いてあって今まで自分の中で整理できてなかったことが言語化してあってとてもスッキリしました。&lt;/p&gt;
&lt;p&gt;↑の2冊を読んだ上で成瀬さんのDDD本を読んだのでスムーズに理解できました。我ながら結構いい感じの流れでDDD(の入り)を学んでいけた感じがしています。(あと成瀬さんの本がわかりやすすぎた&amp;hellip;。とてもおすすめです！)&lt;/p&gt;
&lt;h2 id=&#34;7月&#34;&gt;7月&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Twitterのクローンアプリの設計 &amp;amp; フロントエンドの実装開始&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.amazon.co.jp/Web%E3%82%92%E6%94%AF%E3%81%88%E3%82%8B%E6%8A%80%E8%A1%93-HTTP%E3%80%81URI%E3%80%81HTML%E3%80%81%E3%81%9D%E3%81%97%E3%81%A6REST-WEB-PRESS-plus/dp/4774142042&#34; target=&#34;_blank&#34; &gt;Webを支える技術&lt;/a&gt;
をよんだ&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;設計のアウトプットをしたかったんですが特にアプリのアイディアとかもなかったのでTwitterのクローンアプリを作りました。&lt;/p&gt;
&lt;p&gt;事前に&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;要件定義&lt;/li&gt;
&lt;li&gt;スケジュール&lt;/li&gt;
&lt;li&gt;設計&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;をしてから開発に入ったので大きな手戻りなく開発できました。と同時になかなかコードを書き始められなくてもどかしく感じました&amp;hellip;。&lt;/p&gt;
&lt;p&gt;クローンアプリのことについてはまた別の記事で詳しく書きたいと思います。&lt;/p&gt;
&lt;h2 id=&#34;8月&#34;&gt;8月&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;応用情報の勉強をはじめた&lt;/li&gt;
&lt;li&gt;Twitterのクローンアプリのバックエンドの実装&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;大学・大学院で情報系を学んでいる&amp;amp;学んできた人たちに少しでも追いつきたいと思い応用情報を受けることにしました。(資格がとれるからというより試験があって合否があった方が頑張れるので&amp;hellip;)&lt;/p&gt;
&lt;p&gt;友達と毎日1時間くらいUdemyの動画をみる形で応用情報の勉強をやっていきました。(動画自体は40時間くらい)&lt;/p&gt;
&lt;p&gt;Udemyで試験範囲を一通り学んだあとは、試験前2週間程度で過去問10回分を3周くらいしました。&lt;/p&gt;
&lt;p&gt;午前問題はわりとはやくから安定して7割以上とれてたのでよかったんですが午後問題が6割前後しか解けなくてずっと不安でした&amp;hellip;。&lt;/p&gt;
&lt;h2 id=&#34;9月&#34;&gt;9月&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Scalaの勉強をはじめた&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&#34;https://scala-text.github.io/scala_text/&#34; target=&#34;_blank&#34; &gt;scala-text&lt;/a&gt;
や
&lt;a href=&#34;https://github.com/kyu08/tour-of-scala&#34; target=&#34;_blank&#34; &gt;tour of scala&lt;/a&gt;
とかをやりました。&lt;/p&gt;
&lt;p&gt;TypeScriptと比較して、型まわりの機能が多かったり(共変、非変のあたりとか)ビルトインのメソッドが多かったりして、学習コストはあるけどちゃんと学んだら堅牢で表現力豊かなコードがかけそうだな〜という印象。&lt;/p&gt;
&lt;p&gt;コップ本も買いましたが途中まで読んで積んじゃってます。再開したい。&lt;/p&gt;
&lt;h2 id=&#34;10月&#34;&gt;10月&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.amazon.co.jp/dp/B00GRKD6XU/ref=dp-kindle-redirect?_encoding=UTF8&amp;amp;btkr=1&#34; target=&#34;_blank&#34; &gt;Evans本&lt;/a&gt;
をよんだ&lt;/li&gt;
&lt;li&gt;Vimに入門したけど2日で心がおれた&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Evans本を読みました。成瀬さんのDDD本を読んでから望んだので前半はわりと理解できましたが後半はサッパリでした&amp;hellip;。🤔&lt;/p&gt;
&lt;p&gt;IntelliJちょっと重いなあ&amp;hellip;ということでNeoVimに入門してみましたがPluginがなかなかうまく動かなかったりしてIntelliJでやってることができる状態にするのめっちゃ大変やん&amp;hellip;となり挫折しました。&lt;/p&gt;
&lt;h2 id=&#34;11月&#34;&gt;11月&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Scala x PlayFrameworkで簡単なAPIサーバをつくった&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;学会準備のためあまり勉強できず、、&lt;/p&gt;
&lt;p&gt;ScalikeJDBCの使い方が難しくて詰まった。あとScalaの&lt;code&gt;implicit&lt;/code&gt;がむずい。&lt;/p&gt;
&lt;h2 id=&#34;12月&#34;&gt;12月&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;応用情報受かった&lt;/li&gt;
&lt;li&gt;このブログをNext.jsでつくった&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;応用情報受かりました！🎉&lt;/p&gt;
&lt;p&gt;午後が結構不安だったのでめちゃめちゃ嬉しかったです。(午前78%, 午後62.5%だった)&lt;/p&gt;
&lt;p&gt;わりと広く浅く学べたのでこれからがっつり学ぶ必要が出てきたときの土台となってくれれば&amp;hellip;と期待しています。。&lt;/p&gt;
&lt;p&gt;Next.jsに入門しました。今までcomponentが増えてくると辛みが増していましたがcomponentを&lt;code&gt;/pages&lt;/code&gt;と&lt;code&gt;/component&lt;/code&gt;に配置するやり方が読みやすさ的にも書きやすさ的にもいいなと感じました。&lt;/p&gt;
&lt;p&gt;あとはVercelへのデプロイが簡単すぎて感動しました。&lt;/p&gt;
&lt;p&gt;詳しくは&lt;a href=&#34;https://blog.kyu08.com/posts/constructed-blog&#34; target=&#34;_blank&#34; &gt;こちら&lt;/a&gt;をご覧ください。&lt;/p&gt;
&lt;h2 id=&#34;まとめ&#34;&gt;まとめ&lt;/h2&gt;
&lt;p&gt;最後まで読んでくださりありがとうございます。&lt;/p&gt;
&lt;p&gt;あと4ヶ月でエンジニアとしてのキャリアがスタートするのでそこまで頑張って力を高めていちはやく技術力で会社に貢献できるようになりたいです。&lt;/p&gt;
&lt;p&gt;2021年もがんばります。&lt;/p&gt;
</content>
    </item>
    
    <item>
      <title>Next.js VercelでBlogをつくった</title>
      <link>https://blog.kyu08.com/posts/20201227-built-blog/</link>
      <pubDate>Sat, 26 Dec 2020 16:15:48 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/posts/20201227-built-blog/</guid>
      <description>急にブログが書きたくなったのでつくった。 使った技術 Next.js TypeScript Vercel 感想 Vercelめっちゃ楽 Syntax Highlightできてうれしい const age: number = 1 // こんなかんじ</description>
      <content>&lt;p&gt;急にブログが書きたくなったのでつくった。&lt;/p&gt;
&lt;h2 id=&#34;使った技術&#34;&gt;使った技術&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Next.js&lt;/li&gt;
&lt;li&gt;TypeScript&lt;/li&gt;
&lt;li&gt;Vercel&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;感想&#34;&gt;感想&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Vercelめっちゃ楽&lt;/li&gt;
&lt;li&gt;Syntax Highlightできてうれしい&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-typescript&#34; data-lang=&#34;typescript&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;age&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;number&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 style=&#34;color:#75715e&#34;&gt;// こんなかんじ
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;これからやりたいこと&#34;&gt;これからやりたいこと&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;header footerつくる&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;各種SNSへのリンク&lt;/li&gt;
&lt;li&gt;存在しないリンクへアクセスされたら記事一覧に戻す&lt;/li&gt;
&lt;/ul&gt;
</content>
    </item>
    
  </channel>
</rss>
