20250429 IP fragmentation

項目 内容 得点 換算点
睡眠時間 5時間5分 23 3.0/13.0
起床 9:12 40 3.2/8.0
散歩 ノー 0 0.0/5.0
朝食の栄養カバレッジ 3色カバー 100 5.0/5.0
体操 ノー 0 0.0/5.0
労働 休日 100 24.0/24.0
ジム 有酸素+筋トレ 100 12.0/12.0
勉強会 ノー 0 0.0/12.0
個人開発 実施 100 7.0/7.0
あすけん - 72 6.5/9.0
総合 1日の総合評価 - 61

↑これのせいでOGPのdescriptionが意味ない内容になりがちだったのでちゃんと明示するようにしてみる。

遅く起きて朝食→ジム→ラーメン屋→買い物→帰宅→昼寝→個人開発→今

ジムで顔見知りの人と世間話をした。同じジムでも普段やることが違うといろいろ教わることがあって面白い。

なんとなく普段行かないラーメン屋に行きたくなって行ったら、定休日火曜という表示とともに中で客?と店員が和やかに談笑していて、(今日は休みで店員がまかない食べながら談笑してるのか…?)と思ったけど普通に営業してた。祝日だからかな。メニューが以前来たときから完全に変わっていて驚いた。デフォルトのトッピングがほぼ無な代わりに安いというモジュラー式電源みたいな構成になっていた。

楽しみ

休日と入っても特にやりたいことも行きたいところもないよなあ…と無気力決め込んでいたけどツイッターで友人がめちゃくちゃきれいな島の風景を上げていて俺も何かすればよかったなと少し悲しくなった。人生全部これ。段取り付けて準備してようやく得られる体験というものがあり、それをきちんと遂行できる人間と、最終的な体験は羨ましがるけど行動は起こせないで家で昼寝してる人間がいる。まあ風景が良いからなんだよとも思うが。

よく友人に付き合いが悪いとか遊ぼうとしないと言われる。人と会うのは好きなのだが、事実だ。昔から楽しむということが苦手だ。趣味もなんらかの形で自己研鑽につながるものじゃないとやる気にならない。100%enjoyの娯楽には罪の意識がある。ディズニーランドとか怖い。Dota2は対戦と上達という要素があるから楽しめるが、四川省はある程度は上達の要素もあるが結局配牌次第であり、あまりやる気が出ない。加えて初めてのことをやるのも億劫だ。まあこちらは「人生経験」「これも勉強」みたいな言い方をされれば割と簡単に乗り越えられる。ので僕に違法薬物を勧めないでください。でも誘われるのは嬉しいので何でも可。

ちなみにアニメの聖地巡礼旅行はかなり自由研究的要素があるので好きです。土地とストーリーと制作プロセスが重なって新しい発見が生まれてくるのはかなり楽しい。

最近はジメッとした内省的な話ばかりしていて嫌だね。ずっと睡眠が壊滅していてそのせいで気持ちが落ち込む。まあそれも含めての日記道だから。

IP fragmentation

パケットキャプチャの続きもやった。今日はIPパケットのfragmentationのことを考えていた。昔マスタリングTCP/IPを読んでいたときにはあまり実感していなかったけどIPパケットが下位レイヤのMTUの都合で自らを分割するのってちょっと違和感あるよね。まあこの辺りが教条的ではなく柔軟だったことがIPの広がりにプラスに働いたというのもあろうが。

IPヘッダのfragment offsetは13ビットの領域を割り当てられており、その表現は8ビット単位である。この説明はよく見られるのだが「8ビット単位って何?」という疑問が湧いた。13ビットで表現できる数値は2^13(8192)通りだ。つまりfragment offsetは8の倍数オクテットであって2^16までの数字しか表現できないということになる。そうなの?答えはYesだ。RFC791に明記されているとおり

そもそもIPデータグラムの最大長は65536オクテットなので2^16でちょうど足りる。

This format allows 2**13 = 8192 fragments of 8 octets each for a total of 65,536 octets. Note that this is consistent with the the datagram total length field (of course, the header is counted in the total length and not in the fragments).

そして分割は8オクテット単位でせねばならないと定められている。

The data of the long datagram is divided into two portions on a 8 octet (64 bit) boundary (the second portion might not be an integral multiple of 8 octets, but the first must be).

そう言えばもう一つ、Identificationも他の送信元と被ったら混線しない?と思ったんだけど、これは送信者IP・宛先IP・プロトコルも含めてユニークになるようにassembleせよと定められてたね。

To assemble the fragments of an internet datagram, an internet protocol module (for example at a destination host) combines internet datagrams that all have the same value for the four fields: identification, source, destination, and protocol.

Ethernetの仕様書は7000ページあった一方でIPは随分読みやすい。

20250427 逆算と積み上げ

項目 内容 得点 換算点
睡眠時間 4時間34分 3 0.4/13.0
起床 8:33 72 5.8/8.0
散歩 ノー 0 0.0/5.0
朝食の栄養カバレッジ 3色カバー 100 5.0/5.0
体操 ノー 0 0.0/5.0
労働 休日 100 24.0/24.0
ジム 有酸素 100 12.0/12.0
勉強会 ノー 0 0.0/12.0
個人開発 ノー 0 0.0/7.0
あすけん - 59 5.3/9.0
総合 1日の総合評価 - 52

人生、ゴールを決めてそこから逆算して日々のノルマを決めるのか、それとも自分のキャパシティと相談して毎日捻出できるリソースを決めてそれを積み上げていくのか。これは難しい問題だ。前者の方が達成度を厳密に管理しやすいが、ゴールと達成度という最初に決めた一本道の目標に囚われて寄り道が難しくなるという欠点もある。スマホのアプリアイコンを整頓した。これは特定のゴールを設定していないが、日々の改善活動によって今後の生活が遅滞することを防ぐタスクに分類される。人生も開発も同じなんだよな。全てが僕というレンズを通せば同じになるから、僕は文章を書いている。

久々に王将の餃子定食を食べた。やはりどこかのチェーンと違って餃子がちゃんと美味い。しかし高い!

なんとなく物欲しい気分だったのでお菓子を大量に買ってきて食べた。娯楽は何かを犠牲にするものだが、僕の場合栄養スロットには余裕がありがちなのでこの手に限る。

あまり気持ちがハァーサッパリサッパリしない。これじゃ日記じゃなくてチラ裏だよ。それはやっぱり違うものだから。ネマシュ

20250426 EtherType

項目 内容 得点 換算点
睡眠時間 7時間35分 100 13.0/13.0
起床 9:51 8 0.6/8.0
散歩 ノー 0 0.0/5.0
朝食の栄養カバレッジ 3色カバー 100 5.0/5.0
体操 ノー 0 0.0/5.0
労働 休日 100 24.0/24.0
ジム 有酸素+筋トレ 100 12.0/12.0
勉強会 ノー 0 0.0/12.0
個人開発 実施 100 7.0/7.0
あすけん - 72 6.5/9.0
総合 1日の総合評価 - 68

論理午前中にジム。帰宅して昼寝。昼寝が習慣づくと就寝が下手になる疑惑もあるが…。今日は寒かったね。雨も降ったし。

個人開発はパケットキャプチャ。タイプをパースできるようにした。そろそろwikipediaじゃなくてIEEEの仕様書読むかと思ってダウンロードした。最初は200ページで意外と少ねえな?と思ったらそれは追加分で、実際は7000ページあった。

Rustのモジュールシステムはまだ奇怪な印象が拭えない。#[derive(Debug, PartialEq)] とかは便利だな。テストはまずビルトインなのが嬉しい。as がマジのキャストなのはTypeScriptと感覚が違う。というかこれはTSの方が変なんだろうけど。

自宅のネットワークをパケットキャプチャして見てみると色々発見がある。ときどき送られてくるベンダ不明のMACからのフレームはスマホとPCを連携させるKDEConnectのpingだったし、ときどき送っているIPv6のマルチキャストは近隣探索のようだった。

nanacoをアプリ上で作ってみたがチャージに使えるクレジットカードが専用のやつだけでまたこのパターンかよ…と幻滅。また嫌いになりました。

20250425 チーズバーガー丼

項目 内容 得点 換算点
睡眠時間 3時間30分 0 0.0/13.0
起床 8:31 74 5.9/8.0
散歩 ノー 0 0.0/5.0
朝食の栄養カバレッジ 0色カバー 0 0.0/5.0
体操 ノー 0 0.0/5.0
労働 passion: 70点, discipline: 70点 70 16.8/24.0
ジム 休養日 100 12.0/12.0
勉強会 ノー 0 0.0/12.0
個人開発 ノー 0 0.0/7.0
あすけん - 45 4.0/9.0
総合 1日の総合評価 - 39

↑結構いろいろ改修した(させた)。今回はGemini2.5Pro。小規模アプリケーションだとめっちゃ賢いよ。ちゃんと.clinerulesに従うしpackage.jsonのコマンドも読める。まあコスト的にはハイエンド側だからね。コメントが過剰気味なのは変わってない。そう言えばYouTubeのある英語話者がジェミナイって読んでたけど、本人(?)に聞いたら発音はジェミニって言ってたな。


(世代がバレる)

夜眠れず、眠れないことにイラついて開き直って5時頃まで起きてた。健康も精神も全てが破滅している。

友人からのタレコミで松屋の新メニューチーズバーガー丼を食べた。美味いかまずいか以前に「普通にパンでバーガーにすれば良いのでは…?」という疑問が湧くほどには単にチーズバーガー。味の評価は米に酸味を合わせることをどう思うか次第。僕は若干懐疑(しかし改めて考えてみると酢飯・ケチャップライス・ケバブ・ドリア等は違和感なく食べてはいるな…)。シンプルに肉がデカいのは満足感がある。

休みが多い期間に入る。と言ってもカレンダー通りだが、憂鬱だ。休みは退屈で、休みを退屈にしてしまう自分の至らなさを思い知るのは辛いからだ。

基本的に僕はポイントカードアンチなのだが、ここに住み始めて結構長く、そろそろ近所のスーパーで使えるカードなら作ってもいいかなという気分になってきた。しかし僕は基本的にデジタル国粋主義者なので、GAFAにピンハネさせないでポイントカードを活用するためにはどういう方法がいいかなと考えている。

20250423 MicroStar International

項目 内容 得点
睡眠時間 5時間9分 26
起床 6:41 100
散歩 実施・ゴミ拾いなし・犬遭遇0匹 100
朝食の栄養カバレッジ 3色カバー 100
体操 実施 100
労働 した・passion: 80点, discipline: 60点 70
ジム 有酸素+筋トレ 100
勉強会 参加 100
個人開発 実施 100
あすけん - 72
総合 1日の総合評価 81

犬遭遇で荒稼ぎ、ズルいので廃止します。

眠りはあまり良くない。早期覚醒が早起きとして点数化されるのはバグっぽいけど睡眠時間の方が重みがかなり大きいので許して。昼間もあまり調子は良くなかった。春の雨、若干寒いような、でも油断すると蒸し暑いような気温だ。

ジムで腹筋をやっていたら鋭い痛みが走った。くしゃみをするととても痛い。笑わせないでください。

個人開発はパケットキャプチャ。MACアドレスをパースして表示できるようになり、ベンダーを調べて遊んでいた。マザボ側がMicro-Star(MSIってMicroStar Internationalだったゆんか!?)、ルータ(イーサネットのレイヤーはルータって言わないのかも?マサカリ回避)側はHUMAX。JCOMのやつ。

この前のprismaでgroupByに対してサブクエリで良くない?と友人に言われ、なるほどな〜と思った。ちなみに現状は2つのクエリに分けてサブクエリと同等のことをしている。サブクエリ化するとトランザクションになるしオーバーヘッドが小さくなるが、メモリの使用量が増える。あとテーブル名が単数形なのは気持ち悪いとも言われたが、それは後の祭りだ。

米を炊いて冷凍した。カブのサラダ(切っただけ)もまだ大量にある。春なのでカブ。

20250422 フロントエンドDDDの記事を読んで思うこと

項目 内容 得点
睡眠時間 6時間39分 86
起床 7:47 100
散歩 実施・ゴミ拾いなし・犬遭遇3匹(プープーパピ?) 130
朝食の栄養カバレッジ 3色カバー 100
体操 実施 100
労働 した・passion: 75点, discipline: 85点 80
ジム 休養日 100
勉強会 参加 100
個人開発 実施 100
あすけん - 22
総合 1日の総合評価 88

今日はよく眠れた。そのせいか労働は特に気合が入っていたというわけでもないが自然体でスムーズによく進んだ。そうそう、これが僕の本当の能力よ。

いい気分になったのでお菓子を大量に食べてしまった。すまん、あすけん女。

イーサネットフレーム

個人開発ではパケットキャプチャを進めた。久々にRustのBoxやdynのことを思い出していた。Rustはコンパイル時にあらゆるデータのサイズが決まらなくてはいけないので、関数の返り値としてトレイトを返すことは原則できない。なぜならトレイトはその実装ごとに型とサイズが違うからだ。しかしその返り値への参照を返すという作りにすれば参照のサイズは固定だから問題なく、その方法を使ってトレイトを返り値にするときに dyn traitname と書くのだ。

まあなんか書くときの感覚よりもメモリ管理のルールが優先されるのはいかにもRustだよね。

今日は生のイーサネットフレームを得るところまで成功した。 u8[] で得られたのでそのままGeminiに放り込んでみたら普通にパースできてすごい。

フロントエンドDDDの記事を読んで思うこと

そう言えば今日は フロントエンドDDD という記事を読んだ。クラスなりなんなりで豊かなデータ構造を作ってそこにドメインロジックを集約するという考え方はとても良く、業界でも重厚なフロント作っている方だと自認している私としてもぜひ見習いたい考え方だと思った。

一方でこの記事が改めて注目を集めるほどに珍しいのは、フロントエンドの世界はどうしてもバックエンドからの通信でシリアライズされてメソッドが消えたり、Reactベースの世界観になるとクラスの差分検出がめんどいというところもあったりする。『コア価値であるロジックがフロントエンドの技術変遷の影響を受けすぎない』で述べられていることを裏返せば、通信やフレームワークの事情先行で作っていくとプリミティブ中心に薄く薄く…ということになりがち。そういうところを上手く分離して丁寧に構築する作り方をしてもなおメリットが上回るような重いものを作っていて、難なくそれを扱えるチームの熟練度があってこそかなあと思う。

関連記事: https://panda-program.com/posts/clean-architecture-and-frontend

『生成AIの作業領域との分離』という切り口は考えたことがなかったが確かにその通りだ。賢い。

20250421 もう一人のボク

項目 内容 得点
睡眠時間 5時間0分 20
起床 6:30 100
散歩 ノー 0
朝食の栄養カバレッジ 3色カバー 100
体操 ノー 0
労働 した・passion: 75点, discipline: 80点 78
ジム 有酸素 100
勉強会 ノー 0
個人開発 実施 100
あすけん - 64
総合 1日の総合評価 59

入眠困難・眠い浅い・悪夢の三重苦。一応早起きした(してしまった)がその後も半覚醒でボーッとしていたのでゴミを捨てそこねた。

昼食は日高屋のW餃子定食。いつもながらあんまり美味しくない。なんならいつもあんまり美味しくなさすぎて思ったより美味しいまである。あすけんに入力するときキムチか唐揚げか選べるようにしてほしい。

神の気温。むしろ適温に近すぎるせいで日に当たると暑いし風が吹くと寒い。フィードバック処理なら平滑化を入れないと高速で服を着たり脱いだりし始めて他の行動ができなくなる。

最近は睡眠の不調を反映してか頭の動きが悪い。とっさに単語が出てこなかったり、複雑な仕組みをイメージするのに時間がかかったりする。元気もあまりない。年齢もあるだろうが、それよりも体調による短期的変動のほうがずっと大きい。

ふと思い立って自分の全ツイートと全日記をNotebookLMに突っ込んでみた。全然面白くなくて、あれこれ質問しても自分がもう知ってることを自分よりも曖昧で不正確な文章で返答してくるだけだった。

20250420 モアイ回し

項目 内容 得点
睡眠時間 5時間37分 45
起床 8:38 68
散歩 ノー 0
朝食の栄養カバレッジ 3色カバー 100
体操 ノー 0
労働 休日 100
ジム 有酸素+筋トレ 100
勉強会 ノー 0
個人開発 実施 100
あすけん - 72
総合 1日の総合評価 66

睡眠時間を追加した。

朝食。2時間おいてジム。風呂上がりに扇風機の風を浴びるおじさん、脱衣所あるあるだと思うんだけど今日は2台の扇風機で2人のおじさんが同じポーズで浴びてて面白かった。モアイ回し(ああ、僕が小学生の頃に遊んだブラウザゲームたちは今どこにいるのだろう)。帰りに『爽 とろける濃厚完熟マンゴー』を買って食べてみた。うん、確かにマンゴーらしい風味はあるけど、そもそも爽があんまり好きじゃないんだよね。シャリシャリ系なので。

↑の点数計算アプリケーションをGPT-4.1-miniでvibe codingしていた。いじるファイルが3つくらいで行数も少ないのでこのAIでもかなりいい具合に動く。激安だし。やってる最中にちょっと面白い発見があって技術ブログも書けた。AIもフロントエンドのツールチェインの複雑さには勝てないようだな。

逆にもっと複雑なwatch-duty-managerはAIに任せるのはかなり難しい。AIが何をしているのか俺にはよくわからないし、AIも俺が何をしているのかよくわかってない。相当上手く操縦しないといけないがそんなことするなら自分でやったほうが早い。.clinerulesを当然のように無視してくるのでこちらがノウハウを積み重ねられないんだよな。

気候がとても丁度いい。26度で湿度50%。自室で服を脱いでいて、暑くもなく寒くもない。蒸しもせず乾燥もしない。布団を被っても気持ちいいし蹴飛ばしても気持ちいい。

import typeならallowImportingTsExtensionsは不要

import { foo } from "./foo.ts";

のように .ts を付けてimportするためにはtsconfig.jsonでallowImportingTsExtensionsがtrueになっている必要がある。しかしこのオプションはnoEmitも同時にtrueにしなければならない。その理由はuhyo氏が解説している。トランスパイルしたら.tsファイルじゃなくなるのでimportできなくなって意味ない(そこの辻褄合わせまでtscはやりません)のでトランスパイルしないでくださいということ。

https://zenn.dev/uhyo/articles/rewrite-relative-import-extensions-read-before-use#--allowimportingtsextensions-%E3%82%AA%E3%83%97%E3%82%B7%E3%83%A7%E3%83%B3

じゃあトランスパイル後に消えていいimport、つまりimport typeならよくね?と思って調べたら、実際そうだった。

// allowImportingTsExtensionsがfalseでもエラーにならない
import type { foo } from "./foo.ts";

https://github.com/microsoft/TypeScript/pull/54746

これに気づいたのは、vibe codingで軽めに作っているアプリケーションにテストを追加しようとしたときだ。現状nodeのビルトインテストフレームワークと--experimental-strip-typesを使うとjestやらvitestやらがなくてもそれっぽいテストが作れる(jestのためにトランスパイルとか、結構複雑だったよね)。

https://blog.koh.dev/2024-10-23-nodejs-builtin-test-typescript/

しかしnodeとして実行するならimportには拡張子が必要であり

https://zenn.dev/mizchi/articles/experimental-node-typescript#%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB%E8%A7%A3%E6%B1%BA

拡張子をつけると今度は「allowImportingTsExtensionsをtrueに旋回!」と怒られる。うーん、このルールの意図を考えればimport typeにすれば通るんじゃね?と思ったら通ったという次第。import typeにできる箇所で良かった。というかそうでなければそもそもtscだけではビルドできなかったんだけどな。

nodeのドキュメントにもimport typeはstripすると読める説明が書いてあった。

https://nodejs.org/api/typescript.html#importing-types-without-type-keyword

Due to the nature of type stripping, the type keyword is necessary to correctly strip type imports.

TypeScriptとの微妙な距離感が面白かった。

https://nodejs.org/api/typescript.html#importing-types-without-type-keyword

As in JavaScript files, file extensions are mandatory in import statements and import() expressions: import './file.ts', not import './file'.

The tsconfig.json option allowImportingTsExtensions will allow the TypeScript compiler tsc to type-check files with import specifiers that include the .ts extension.

あくまで拡張子付きのimportという文法が先にあり、それをTypeScriptが許可するかはオプション次第ですね〜というスタンスが感じられ、なるほど言語を作っている方からはそういう見方になるんだなあと思った。

20250420 回転寿司/gpt-4.1-miniの印象/prismaでgroupBy

遅めに起きて布団カバーを洗濯した。また冬が終わったので毛布類をコインランドリーで洗った。待つ間にくら寿司で豪遊(1100円)。

回転寿司

回転寿司というのは、極みである。食事の進行中に1品ずつ注文を受けてオンデマンドで調理される自由度の高さ、それを支えるweb注文とコンベヤ輸送という温かみの欠片もない高度な技術によるオペレーション、射幸心を煽るびっくらぽん。揚げ物スイーツラーメンなんでもありの無文化性。そんなに美味しくない寿司、腹に貯まる米による満腹感。誰も触らないせいで回転レーンで干からびていく寿司(そしてそのせいで一層誰も触らなくなる)。

食べる分量が空腹である入店時には決まらないという性質上食べ過ぎにくいというのはなかなか良いところだと思う。

洗いたての毛布を持ち帰って神の昼寝。起きたら友人が麻雀で大負けしていた。

gpt-4.1-miniの印象

またいろんなLLMを試しながら個人開発。これ自分じゃメンドクセぇ〜って思うところはやっぱりLLMにも任せられないね。今日の感触としてはこんな感じ。

  • gemini2.5: やたらと作業ログをコメントで残す。やめろと言ってもやめない。diffツールの使い方が下手で何度もやり直し金ばかりかかる。触るなと言ったところを触る。
  • gpt-4.1-mini: 頭も記憶力も悪いが時間をかけて誘導すれば一応仕事はできる

僕は安くてそこそこ使えるやつに興味があり、その点ではgpt-4.1-miniは良い。claudeはお高くて使いづらいんだけど優秀であるということを痛感。gemini2.5は高いし評判も良かったけど使ってみたらそれほどでもなかった。

prismaでgroupBy

具体的にやった作業はprismaのクエリいじり。アニメの作品(work)とエピソード(episode)が一対多対応であるという前提で、ある条件を満たすようなepisodeを2つ以上持つworkを抽出したい。生SQL(を使えるprisma API)だと

const works = await prisma.$queryRaw`
  SELECT w.*
  FROM work w
  JOIN episode e ON e.work_id = w.id
  WHERE e.some_condition = true
  GROUP BY w.id
  HAVING COUNT(e.id) >= 2
`;

のようにwhere→group by→havingの流れで2回絞り込みを行うことで実現するらしいのだが、これをprismaに持っていくと

const works = await prisma.episode.groupBy({
  by: ['workId'],
  where: {
    some_condition: true,
  },
  _count: {
    workId: true,
  },
  having: {
    workId: {
      _count: {
        gte: 2,
      },
    },
  },
});

となり、返り値の型が { _count: { workId: number }, workId: number } になる。つまり SELECT w.* が再現されずworkIdしか取れない。

既知のissueとしてはこの辺りが近い話に思われるが、いずれも対応される雰囲気がない。
https://github.com/prisma/prisma/issues/24816
https://github.com/prisma/prisma/discussions/6517

まあしないだろうなという感覚もわかる。prismaはそもそも様々なデータベースを隠蔽する抽象化の役割も持っており、各データベースのある程度細かい機能に逐一対応するのは無理だ。TypeScriptとの堅固な統合が持ち味であることを考えれば難易度は一層高い。

ある程度複雑なクエリ、パフォーマンスチューニングが求められるクエリは生SQLのAPIを使ってくださいよということなのだろう。