随筆 | カオスの坩堝 https://anqou.net/poc Chaos is not kaos. Mon, 15 Mar 2021 14:19:23 +0000 ja hourly 1 https://wordpress.org/?v=6.1.1 https://anqou.net/poc/wp-content/uploads/2018/02/9dc10fe231765649c0d3216056190a75-100x100.png 随筆 | カオスの坩堝 https://anqou.net/poc 32 32 大学を卒業できそうなので大学生活を振り返るやつ https://anqou.net/poc/2021/03/15/post-3438/ https://anqou.net/poc/2021/03/15/post-3438/#respond Mon, 15 Mar 2021 14:19:20 +0000 https://anqou.net/poc/?p=3438 なんか大学を卒業できそうなので大学生活を振り返るやつをします。

B1

京大は入学するとビラロードとかいうクソみたいなところを歩かされるんですが、そこをビラ 1 枚で通り抜けるなどしていました。

プログラミングの記憶はほとんど無いけど、鼻くんとかを使ってプログラムを書いていた気がします。

もしかしてカオスの坩堝はこの学年で作ったんじゃないかと思ったらやっぱりそうでしたね。もうそんなになるのか。もともとは 2017 年の AdC をやるためのブログだったんですが、いまや総記事数が 300 近いサイトになりました。

あと第二外国語でロシア語をとっていました。キリル文字が面白かったので坩堝に記事を書いたりしていました。今でもキリル文字が出てくると頑張って読もうとするけど、ロシア語自体はほとんど忘れてしまいました。

有志で蟻本を読む輪読会をしたり、Linux 講習会をやったりしていました。AtCoder で ABC/ARC とかを解いていたのも多分このころですが、解けなかった問題の解答がコンテスト後に Twitter に流れてくるのが嫌でやめました。メンタルが競プロに向いてない。

GPA ポケモンのサイトを作ったのもこのころです。

2018 年の正月には、ddの出力先を間違えてディスクを吹き飛ばしたりしていました。fsckを振り回してなんとか復旧しました。

割と A+を取れた授業が多くて GPA 4.12 とかでイキってたら、何人か友達をなくしたりしました。みんなは気をつけてください。

あと鮟鱇丼という Mastodon を立てていたのですが、サーバー操作ミスで吹き飛ばしたりしていました。

B2

5 月にセキュリティ・ミニキャンプ in 兵庫に、8 月にセキュリティキャンプ全国大会に@VTb と一緒に参加しました。全国大会の顛末は坩堝にも投稿しました(応募用紙, 開発記)。低レイヤー的なことをやったのはこれが初めてだったのですが、めちゃめちゃに楽しい経験ができました。 aqcc を書いた後に物足りなくなってAQaml というセルフホスト OCaml コンパイラを書いたりもしました。あと Kernel/VM 関西 9 回目で aqcc について発表して、ベストオブ頭おかしいをもらいました。めちゃめちゃ嬉しかったです。

この話をアカデミアのよくしらないおじさんにしたら全否定されたので、アカデミアには絶対に行かないという強い意志を持ったりしました。このあたりの話はいずれまとめて短いエッセイにしたいなぁと思っています。

ちなみにこのおじさんはこの後もちょくちょく私を惑わせています。

ミニキャンプと同時期にわくわく鮟鱇ランドという Mastodon を立てて、身内で遊び始めました。これも若干メンバーを増やしつつ現在まで続いています。ちなみにこの名前は wotto さんが考えてくれたやつです。

初めは Twitter と相補的に使っていたのですが、最近はもうほとんど Mastodon でしか活動していません。Fediverse はいいぞ。みんなも連合しよう。 Mastodon を 1 年半くらいやったときに坩堝にも記事を書きました。ちなみに B3 で本格始動する未踏のチームから参加のお誘いが来たのもこの Mastodon の DM でした。

あとニューラルネットワークの研究を書くプロジェクトに参加して論文を書いて、査読が通らなかったりしていました。

割と A+を取れた授業が多くて GPA 4.12 とかでイキってたら、何人か友達をなくしたりしました。みんなは気をつけてください。

B3

2019 年の 3 月に@VTb と@nindanaoto にいきなり準同系暗号を用いたセキュアなプロセッサ開発に誘われて、急いで応募資料を書いて未踏事業に応募したところ通ったので、B3 の間はずっとそれをやっていました。その顛末は前に坩堝にも書きました(VSP の紹介未踏体験記)。応募資料と、終わった後の成果報告書はGitHub 上で公開したので良かったら見てください。ちなみに VSP は Virtual Secure Platform の略なんですが、もともとは P は Processor で、後から「プロセッサ以外にも作るもの死ぬほどあるやんけ」といって Platform に変えたという経緯があります。

未踏期間中は、開発をしたいのに試験があったりして、ままならない思いをしていました。

それから、大学の演習で FPGA 上でプロセッサを作るというものがあったのですが、ハードウェアはつらかったのでソフトウェアの勝負に持ち込むべくコンパイラを書いて、当時流行っていた「1000 円でサイゼリヤで最大何 kcal の食事をできるか」という問題を自作プロセッサ上で解いたりしました。これもカオスの坩堝に書いたのですが、思いのほか好評で、初めてはてブにたくさんコメントがついたりしました。あとロボ太さんに言及されたり、ハードウェア実験の主担当の先生に言及されたりもしました。めちゃめちゃ嬉しかったです。

あと世界の真相を知ったりしました。

ちなみにハードウェア実験のソート速度を競うコンテストでは@VTb がぶっちぎりで優勝していました。シングルコアの性能としては歴代トップらしい。

それから応用情報技術者試験を受けて受かったりしていました。普段は自分の好きなことしか知識を得ないので、こういう資格の勉強をすると普段なら絶対に知り得ないような内容(PMBOK とか)を知ることができました。

ISUCON 9 に出て、ボーダーで予選を通過して本戦を欠席したりしていました。これも坩堝に書きました

VSP以外で作ったものとしては、mattnさんのlongcatコマンドが流行っていたので、それに便乗して「流れてくる音楽で伸びたり縮んだりするlongcat」を作ったりしていましたが、全然ウケませんでした。技術的にはSixelを知れて面白い経験でした。

あと A+を取れた授業が多くて GPA 4.11 とかでイキってたら、何人か友達をなくしたりしました。みんなは気をつけてください。

B4

実は 2020 年のまとめ記事を坩堝に投稿したので、新しく書くことはあんまりありません。

4 月に行われるはずの研究室配属がコロナで 1 ヶ月ずれ込んだりしていたので、その間にカラオケ Web アプリ Damjiroを書いたりしました。

GPA ポケモンがトレンドに載って、4 万 hit を叩き出していました。

USENIX Security っていう学会に VSP の論文が通ったので、ツイートしていいねを稼いだりしていました。

論文は理論的な側面が強くて、@nindanoto にめっちゃ負担をかけたので感謝です。

VSP まわりでいうと、@nindanaoto がセキュリティ・キャンプ 2020 で講師をしていたので、それをサポートするチューターをやったりしていました。その過程で都合 3 回目となる TFHE ライブラリを書いたりしました(aqTFHE3)。@nindanaoto の講義スライドに合わせて書かれていて、世界で一番分かりやすいTFHEライブラリだと自負しています。

ISUCON 10 に出て、学生枠で予選を通過して本戦で fail したりしていました。これは梅さんが坩堝に書いてくれました(予選本戦)。このときに aquery という Go 用の SQL スロークエリアナライザを開発したり、fgprof という既存のプロファイラのバグを取ったりしていました。

B4 の後半は F*というプログラム検証用プログラミング言語を使って、ブロックチェーン用のストレージライブラリに証明をつけていました。この F*というのが曲者で、だいぶ泣いていました。

泣いた内容をまとめて技術ブログの記事にしたりしました。これは未だにちまちま更新しています。

F#という言語を触って代読 Discord ボットを作ったりしていました。これも技術ブログの方に書きました。 F#は OCaml を.NET 用に Microsoft が改造した言語で、関数型っぽい形で.NET が触れます。個人的にはオフサイドルールが OCaml の文法とこれほどマッチするとは思いもよらなくて面白かったです。 .NET 側の事情に引っ張られて若干型推論が弱いのと、フォーマッタ(fantomas)の完成度が低いのが玉にキズです。

そのあとずっとやってみたかった Erlang/OTP と Elixir を触っていました。Erlang/OTP でalqo というアルゴを遊べる Web アプリを作ったり、 Discord の代読ボットを Elixir で書き直したりしていました。 Erlang と Elixir はかなり良い言語で、アクターモデルがよくハマる Web まわりではとても楽しくプログラミングすることができました。文法としては実は Elixir よりも Erlang のほうが好みなのですが、Elixir のほうが人気があるのでライブラリが充実していて、 Elixir でプログラミングするほうが楽そうな事情が悲しいところです。あと Dialyzer という型をつけるためのツールがあるのですが、あんまり強くないのも若干残念です。

さて今年度はコロナ禍で、大学に行ったのは年度中 5 日程度しかありませんでした。ほとんどすべてのものがリモートになったわけですが、これが意外と快適で、コロナが終わってもこのままであってほしいなぁと思うくらいでした。特に、ひどいときで 1 週間に 1 回なっていた偏頭痛が、今年度に入ってからピタッと止まったのは、リモートになったおかげで睡眠時間がちゃんと確保できたからだろうなぁと本気で思っています。

あと A+を取れた授業が多くて GPA 4.11 とかでイキってたら、何人か友達をなくしたりしました。さて今の私の友達は何人でしょう。

ちなみに、B1 のときに予言したように、彼女は 4 年間できませんでした。

感想とか

書き忘れていることもたくさんありそうですが、大きなところは大体書いたかなと思います。 4 年間あっという間だった気がするのですが、こうして並べてみると意外と色々おもしろいことができたなぁという感じです。今後もこういう生活を続けて行きたいのですが、世知辛い世の中で就活なるものをしないと餓死してしまうようなので、そうも言ってられないかなと思っています。

というわけであんまり締まらないですが終わりです。ツイートを貼りまくって終わってしまいましたが、ここまで読んで頂きありがとうございました。

]]>
https://anqou.net/poc/2021/03/15/post-3438/feed/ 0
2020年のまとめ https://anqou.net/poc/2020/12/31/post-3355/ https://anqou.net/poc/2020/12/31/post-3355/#respond Thu, 31 Dec 2020 11:21:47 +0000 https://anqou.net/poc/?p=3355 2020 年にやっていたことを雑にまとめる。

1 月

未踏で VSP の開発をしていた。KVSP の基幹部分である準同型暗号ゲートの評価エンジン Iyokan を 1 月 13 日あたりから書き始める。当時並行で、ユーザーインタフェースの kvsp コマンドも作っていた。いまの KVSP のベースは、おおよそこのあたりで形作られていく。 @nindanaoto が TFHEpp を書いたのも正月三が日だったはず。

締切が近づくにつれ VSP チームに険悪なムードが漂い始めるが、全員で Factorio マルチプレイを n 時間やり、ギリギリのところで均衡を保っていた。

あと大学の試験勉強とかしてた気がする。覚えてない。

2 月

引き続き VSP を開発した。未踏の発表会が 2 月中旬にあって、この直前にバグが見つかって直したりした。発表会が終わった後も未踏の作業期間が続いていて、Iyokan とか kvsp の改善をやっていた。カーネル/VM 探検隊@関西 10 回目で発表したのもこのころ。

2 月末から 3 月頭にかけて大学で試験があったはず。このあとコロナ禍に突入していくため、試験日を最後に大学に来なくなる。

3 月

東京に VSP の紹介発表をしに行ったりしていた。多分これが最後の東京旅行。次に行けるのはいつになるのか。

2 月末から 3 月頭にかけて未踏の成果報告書を書いたりした。全文をGitHub で公開した。未踏期間は 3 月中旬で終わった。

3 月末に VSP チームで温泉旅行の予定だったが、大阪で外出自粛令的なやつが出たので中止。結局今まで行けていない。

3 月 29 日にカオスの坩堝で2020 年春季投稿大会をやった。

4 月

大学が、4 月の講義計画を 3 月末になって白紙に戻したため、めちゃめちゃに暇になった。暇に任せて採点機能付きカラオケ Web アプリ Damjiroを作ったりしていた。

なんだかんだあって研究室配属が第一希望に決まったりした。

5 月

研究室での活動がリモートで始まった。研究会やら輪読やらは全部 Zoom 経由になった。昨年と比べて、朝早く起きる必要がないのでめちゃめちゃに楽になった。昨年までは偏頭痛に悩まされていて、ひどいときには一週間に一回死んでいたが、今年はよく眠れたおかげか、ついに一度もならなかった。

院試で必要な TOEIC がコロナ禍で中止になったりした。最終的には、今年の院試では TOEIC の結果が不要になった。

4 月終わりから 5 月にかけて、VSP を論文にまとめるため動き始めた。動き始めたといってもメインで書いていたのは@nindanaoto で、私は追加で実験をやったり、@nindanaoto の無茶振り機能追加要求に対応したり、 @VTb をせっついて新しいプロセッサを書かせたり、それを KVSP に取り込んでもう一度実験をしたりしていた。未踏期間が終わるとコードを書いてもお金が出ないんだなぁということを認識したりした。

6 月〜7 月

論文を書き上げて USENIX Security に提出した。書くべき英語が全然分からなくて、先生にめちゃめちゃにお世話になるなどしていた。

あとは院試勉強というのをしていた。始めの方は気楽にやっていたが途中から余裕がなくなってきて大変だった。とくにコードを書く時間がなくなってきた。実際 GitHub の contributions のところを見ると、6 月から 7 月にかけてぽっかり空いている。 OS の勉強をすると OS を書きたくなってくるのでつらかった

8 月

院試を受けるために大学に 2 日行った。実に半年ぶりの大学だった。寒かった京都は暑くなっていた。ちなみにネタバレすると、院試後に次に大学に行くのは 12 月末に一度だけなので、今年度は結局 3 日しか大学に行っていない。

研究室で、OCaml でなにか書かないといけないというタスクがあったので、定理検証器 Qlown を書いた。依存型ベースの、Coq の弱いバージョンみたいなものができた。一応n + m = m + n程度は証明できる。もともと Qiita の記事を参考に書き始めたのだが、雰囲気で拡張したら簡約が良くわからなくなってそのまま放置することになった。

9 月

ISUCON10 に出て、予選を学生枠で突破し、本選で fail(失格)した。どちらもチームリーダーの梅さんが坩堝で記事を書いてくれた(予選本選)。今年は本当に何もできなくて、メンバーの他二人に終始助けられた。Web は難しい。

VSP 論文の rebuttal が 9 月頭くらいにあって、なんやかんやあって minor revision になって、諸々を修正して accept された。

あと卒業研究が本格的に始まって、F*というプログラム検証用の関数型プログラミング言語をつつきはじめた。

10 月

コロナの流行が若干落ち着いていたので、VSP チームでモツ鍋を食べに行った。その折に@nindanaoto から誕生日プレゼントで Let’s Split というキーボードを貰ったが、ファームウェアの焼付がまずいか何かで片手だけキーの位置が反転していた。直し方がよく分からず、そのまま倉庫に眠っている。

セキュリティキャンプに L トラックチューターとして参加した。講師は@nindanaoto で、チューターは私と@VTb で、TFHE を教えるという内容だった。今年のセキュリティキャンプはリモートな上に 10 月から 12 月まであるという長期戦で、本当にこれで大丈夫かと思っていたが、最終的には結構うまくいったんじゃないかと思う。

11 月〜12 月

F*に苦しめられていた。なかなか思い通りの証明が書けずに苦労している様子がわくわく鮟鱇ランドの#fstarハッシュタグで確認できる。最近ようやく理解してきた。

まとめ

良いお年を。

]]>
https://anqou.net/poc/2020/12/31/post-3355/feed/ 0
ISUCON9 参加記 https://anqou.net/poc/2019/09/08/post-3057/ https://anqou.net/poc/2019/09/08/post-3057/#respond Sun, 08 Sep 2019 14:05:42 +0000 https://anqou.net/poc/?p=3057 TL; DR: 初参加にしては頑張ったので褒めてほしい。

ISUCON9に参加したので、大会前と大会中と大会後に何やったかを書く。

開催前

@_nemohem@fplwdが ISUCON9のメンバーを募集していたので「入れて入れて〜」と言って入れてもらう。まともなWebサービスの運営はほぼ経験が無いが、「知識を得ることが目的」とのことだったので、気軽に参加した。

気軽に参加したあと、本戦の開催日にはすでに予定があるので参加できないことがわかり、土下座するなどした。大変申し訳ありませんでした。

Golangを選択するということが予め決まったので“A Tour of Go”を流し読みするなどする。それから、前から気になっていた「みんなのGo言語」の第二版が出ていたので買ってベンチマークのところを読み、そこに書いてあった Profiling Go Programsを読んでpprofを知った。

あと開催の少し前に集まって練習する予定が、偏頭痛でドタキャンして土下座するなどした。その節は大変申し訳ありませんでした。二人のご厚意で、本番2日前にも集まることが出来たので顔合わせをしつつGolangの過去問を解いたりした。その時の感じから、@fplwdがインフラ、 @_nemohemと筆者がGolangアプリという担当に決定した。

開始直前

行きの電車の中で、複数台構成のためのNginxの設定を調べる。 upstreamproxy_pass を使ってよしなにすればいいらしい。ふーん。とりあえず知識だけ仕入れて現場に入る。

10:00 開始

開始。@_nemohemに鯖を立ててもらっている間にマニュアルを読む。ちんたら読みつつ /initialize のレスポンスに謎の Campaign キーが生えていることだけを把握する。このあたりで鯖が立ったので「負荷は自分で決めるらしいよー」「まじー?」という会話をしつつSSHする。 ls に色がついていなかったためキレつつ alias を設定するなどしていた。

今回は初めに動いている言語がGolangだったので、そのままベンチを回す。 2千数百点付いた気がする。過去のISUCONではGolang版は0点スタートというのも珍しくなかったので、わりと取り組みやすいのかなぁなどと考えながらとりあえずコードをgitに載せGitHubのプライベートレポジトリにつっこむ。ついでにpprofも仕込んでプロファイルをとる。 getNewCategoryItems が遅いっぽいのでコードを眺めるとN+1になっているっぽい。解消するためにSQLをゴニョゴニョし始める。

11:00 getNewCategoryItems のN+1を解消

とりあえずitemとuserとcategoryを INNER JOIN すればええやろとばかりにSQLを書き始めるが、 sqlx を知らなかったため、解読とコーディングに時間がかかった。ついでにcategoryは親カテゴリー名を取得するために再帰的なコードが書かれており、 SQLに落とせない。最終的にsqlxをsqlっぽく使う初心者丸出しコードで itemとuserのinner joinだけを書き上げ、投入してベンチを走らせるがSQLが間違っている。ぐだぐだのまま12時台へ。

12:00 N+1の解決と500エラー

結局1時間以上使ってなんとか動かしたが、謎の500エラーが /buy/sell に出て思ったよりもスコアが伸びない。負荷が足りないのかと Campaign1 にセットするがやっぱり伸びない。ついでにToo many connectionsのエラーが出たので@fplwdに対応してもらうなどした。

あとから聞いた話によると、DBのロックのかけかたがまずくデッドロックが起こっていたらしい(?)。結局これには最後まで気づかなかった。

何度かベンチを走らせても伸びないので、諦めてご飯を食べに行く。店に入るほどの余裕はなかったのでローソンで冷やし中華を買って食べた。麺がゴムっぽかったが、お腹も減っていたのでまあまあ美味しかった。タレで味がついていれば大抵の物は食えるんだなぁ。みつを。

13:00 カテゴリをメモリに乗せる

getNewCategoryItems のN+1を解決するためにはcategoryをよしなにしなければいけない。メンバーがcategoryテーブルに変更が加わらない(初期データの呼出しのみ)ことを見つけてくれたので、DBを叩いてcategoryテーブルの中身をダンプし、「categoryのidを与えると必要な情報を出してくれる関数のGolangコード」を出力するスクリプトをRubyで書く。これを使ってようやくN+1を解決した。長かった……。

14:00 遅いbcryptと6000点

このあたりでbcryptがアホ遅いことに気づく。以前Railsのチュートリアルをやったときに「動作時間で情報がもれないように、ハッシュ化されたパスワードの比較はどんな場合でも一定時間で終わるようになっている(≒わざと遅くなっている)」と読んだことを思い出し、これを通常の等号比較で行えないか検討する。しかし「ユーザにしてほしくないことは行いにくくする」というライブラリ作成の原則が bcryptに一貫されていて、脆弱性を仕込むことはできないようになっていた。仕方がないので「この部分は仕方がないんじゃなーい?」などと言いつつ諦める。

ちなみにレギュレーション上は「平分のままDBに保存しないこと」のみが規定されていたため、例えばbcryptのcostを下げるなどすれば対応可能だったようだ。残念。

さてpprofを見ると getUseSimpleID が重いらしいので SELECT 時に取ってくるカラムの数を減らす。またcategoryを全部取ってくる SELECT が遅いらしいので、またまたDBをダンプして関数に変換したりなどした。ベンチをとると、このあたりで6000点を越えた。

わくわくしつつnginxのキャッシュやらgz圧縮などを設定すると 3000点に落ちたり5000点に浮上したりと安定しない。仕方がないのでキャッシュとgz圧縮はなくして、複数台構成にシフトすることで点数を稼ぐことにした。

15:00 複数台でバグる

ベンチがアクセスしてくるサーバ(フロントエンド)で静的ファイルを配信し、 Golangが動く必要がある場合はバックエンド1台目に投げ、さらにDBを動かす必要があればバックエンド2台目に投げる構成に決定する。さっそくNginxを設定するが、そもそもNginxで複数台構成を(練習を含め)経験した人間がチームに一人もいないことに気づく。Golang側のボトルネックがほとんど解消していると感じていたこともあり、朝に upstream を知った筆者が設定することになる。

フロントエンドとバックエンド1台目はわりとすぐに動いてくれたが、バックエンド2台目の設定で詰まる。バックエンド2台目で動いているリバースプロキシ用の NginxとMySQL間の通信がうまくいかない。3人で頭を突き合わせてあーでもないこーでもないと言っているうちに1時間経過する。

16:00 複数台で動く

MySQLはunix domain socketで接続を待ち受けるらしい。知らなかったよね。これに気づいてからは早かった。ベンチを回すと6000点か7000点くらい出た気がする。やったぜ。

top を見るとバックエンド1台目がCPUを使い切ってることが分かったので、フロントエンドにも処理を肩代わりしてもらうことにする。これは upstream127.0.0.1 を追加するだけではだめで、フロントエンドとバックエンド1台目のどちらかにアップロードされる画像ファイルに、これらの両方からアクセスできるようにする必要がある。 ISUCON7のfujiwara組が同様の問題を upload/01/upload/02/ に画像を振り分けた上で Nginxでスイッチすることで解消していたのでこれを真似る。fujiwara組の nginx.conf は公開されていなかったのだけど、Google検索し続けたらどうにかなった。

「残り30分でも動かなかったら単一構成に戻す」などと言っていたのが杞憂に終わってよかった。

17:00 ラストスパート

残り時間が1時間を切ったのでランキングが見えなくなった。このあたりでベンチを回して9000点台が出た。うれし〜〜。

初めの方に有効化してバグったキャッシュとかgz圧縮とかを復活させる?という話をしていたが、下手にいじって壊すのが怖い。結局ここで最適化は打ち止めにして、ログの出力やプロファイルのコードを消してベンチを回し続けることにした。なぜかベンチが二回に一回failするのでドキドキしながらベンチを回していた。ついでに再起動試験をし忘れていたことに気づいたので慌ててやった。

最終的に17:45に9670点が出て、ここで打ち切りにした。 17:50あたりからポータルサイトが不安定になっていたので、「ここで止めて正解やったなぁ」などと話しながら、夕飯の場所を決めた。

終了後

無事終了。公式が立てた感想戦のDiscordを眺めながら「デッドロックとか起こってたんかへー」「非同期APIはさっさと返してええんやなへー」「bcryptはやっぱり手を入れるべきやったんかへー」などと喋っていた。ついでにボーダー予想もしつつ「ボーダーは1万2千点くらいかなぁ」「いやもうちょっと高くて1万5千点くらいじゃないー?」などと喋っていた。

適当なところで切り上げてモダン焼きを食べに行った。美味しかった。

食べている途中で結果が発表された。残念ながら予選敗退だったが、ボーダーが意外と低くて 1万点くらいだったので「非同期APIに気づいてればなー」「デッドロックに気づいてればなー」「bcryptに手を入れてればなー」などとほざいていた。

ISUCON9 オンライン予選 全てのチームのスコア(参考値)が発表され、予選をボーダーで通過したチームのすぐ下に点差210点で自分のチームが付けていたことを知り泣いています。

感想、あるいは来年への備忘録

始まる前に思っていたよりもいいところにつけた(全参加者の上位5.1%)ので個人的には満足した。Webアプリについて実戦経験が無くても、意外と付け焼き刃でできることはいろいろあるのだなぁと実感した。

Golang側の改善がほとんどpprof一本槍だったので、もう少しいろいろなツールを利用すればデッドロックに気づけたのかなぁと思ったり思わなかったり。あとNginxの知識とかDBの知識とか、諸々のWeb周りの知識が欠けているというのも実感としてあるので、どうにかしていきたいですね(ふんわりとした問題意識)。

大変楽しかったので、できれば来年も出たいなぁと思いつつ。

お疲れ様でした。

]]>
https://anqou.net/poc/2019/09/08/post-3057/feed/ 0
隙あらば自分語り(2) https://anqou.net/poc/2019/02/23/post-2745/ https://anqou.net/poc/2019/02/23/post-2745/#comments Sat, 23 Feb 2019 07:38:09 +0000 https://anqou.net/poc/?p=2745 2月の頭に大学が事実上の春休みに入ってから、起きている時はほとんどずっとパソコンに向かっている。わたしが主に使っているパソコンは2台あるけれど、どちらもDropboxで同期されているから、やっていることは似たようなものだ。画面にはターミナルとエディタとブラウザ。わたしのパソコンを覗き込むことがある人には知っておいてほしいのだけど、こういう画面になっているとき、わたしは大抵プログラムを書いている。話しかけてもロクな返事が返ってこないので要注意だ。

2月前半はおおよそMioのことで頭がいっぱいだった。 MioはイントロクイズゲームができるWebアプリである。「イントロ」と銘打っているが、実は曲の途中からでもランダムに再生ができるので「中トロ」か「ラントロ」のほうが実態には合っている。出題者が居て、問題にする曲をアップロードし、回答者はそれを聞いてクイズの答えを送信する。出題者が各参加者からの解答の正誤を入力すると、自動的に正誤数がカウントされるようになっている。シンプルなゲームだ。行ったことがないけれど、きっとハッカソンとかだと1日で完成するんじゃないかな。わたしは3週間かかったけど。

Mioでは「サーバ」と呼ばれる中枢のコンピュータを用意して、出題者と回答者側――「クライアント」という ――がサーバと協調して動作することにより、イントロクイズを行っている。さっきの仕組みと合わせると、まず出題者が問題の曲をサーバに対してアップロードする。サーバはそれを受け取って、クライアント ――この場合は回答者だ――に送信する。回答者が答えを入力すると、これもまたサーバを経由して出題者に送信される。きょうび、他人と一緒に遊ぶタイプのゲームやツールは、おおよそこの仕組みで動いている。

この手のアプリケーションは作るのが難しい、と思う。大抵なんでも「協調して動く」というのが難しいのは、国際社会を見ていればよく分かる(ここは笑うところ)。プログラムだって例外ではない。途中で回答者が居なくなったらどうするか。出題者が居なくなったらどうするか。そもそもサーバが不具合で止まってしまったらどうするか。回答者が悪巧みをして、サーバに攻撃を仕掛けてくるかもしれない。そうなったときサーバはどのように動くのが良いのか――考え出せばキリがない。

ところで「プログラミングには数学が必要だ」というのは(プログラマの間では)よく話題にのぼるトピックだけれども、わたしはむしろ「プログラミングには論理が必要だ」のほうが正確に物事を捉えていると思う。実際(命令的な)プログラムは「まずこれをして、この場合には次にこれをして、そのあと これこれという条件になるまではこれをして、それが終わったら始めに戻る」みたいなものだから、これを正しく書くには論理の力がプログラマに無いとダメだというのはある意味当然だろう。Mioのようなプログラムをつらつら考えていると、まるでプログラミングが論理パズルのように思えてくる。「もしここで回答者の接続が切れていて、出題者も接続が切れていて、しかしゲームは続行中という状況がありえるだろうか?」

数学とか論理パズルとか、実はあまり好きではない。少なくとも熱狂的な支持者ではない。できれば避けて生活したい。大学というのは、そういう意味では不便な場所で、「単位」という名のもとに数学の授業を受けなければならない。無駄に負けず嫌いだから、試験があるなら勉強しなくては気がすまない。つくづく損な性分だと思うが、それでGPA芸人ができているから、損ばかりでもない。試験期間には呪詛の念を吐きながら数学の授業ノートに向かっている。こんなところからおおよそ予想がつくかもしれないが、勉強した数学の知識の8割くらいは試験が終わると頭から抜け落ちてしまう。「ラプラシアンってなんだっけ?」つまり学期の9割くらいは数学ができない。数学ができないということは、まぁ、論理の力もあんまり無いということである。

こう考えてくると、自分はどうにもプログラマには向いて無さそうだなと感じることになる。実際、数学や論理をフル回転させる競技プログラミングは、性に合わなくてやめてしまった。勘違いをしてプログラムにバグを埋め込んだり、論理的に考えれば絶対にできないことを可能だと思いこんだりしたことは数え切れない。そのたびに「賢い人はこんなことで悩まないんだろうな」などとぼんやり考える。どうしてこんな物を好きになったんだろう。

現代には集合知たるWWWが存在する。要するにGoogleである。最近はプログラミングを嗜む人が増えてきたこともあって、自分が悩んでいることを「ググれ」ば、解決法が見つかることも多くなった。それから、足掛け9年もプログラミングをやっていれば、頻出する論理――この場合アルゴリズムともいう―― は否が応でも覚えることになる。結局やっていることは「コピペプログラマ」みたいなものだ。ここまで「論理が大事!」と書いておいてひどい話だけれど、こうやってずっとプログラムを組んできたのだろうし、いまも組んでいるし、これからも組んでいくのだろう。

何かプログラミングで作品を作っていると、おおよそ一日中そのことを考えている。プログラミングが好きだからだ、というのも一つあるけれど、そこまで考えないと良いプログラムを書けないから、というのも大きい。これは割合に負担が大きくて、作品が一応の完成を見た次の日に偏頭痛で吐いたりするのはこの習慣のせいだろうと思わなくもない。ずっとこれを「まぁプログラム書くのが好きだし、ちかたないね」で済ませてきたのだが、学部生活も残り少なくなってきて、ふと就職のことが気になった。 Twitterでよく見る「適当に手を抜かないと自分が体を壊す」言説にピタリと一致している。職業プログラマには向いていないなと、こんなところでも感じる。

ところで、このあいだMioを(とりあえず)作り終わって、暇になった。こんなこともあろうかと、ブックマークの「あとで読む」フォルダを見ると “Learn You Some Erlang for Great Good!”が入っていたので、一昨日から読み始めた。英文だが、げらげら笑いながら楽しく読んでいる。やっぱり技術文書はこうじゃなきゃなぁ。自分もこういう文章を書きたいものだ、などと思いつつ特段オチのない鬱記事を終わる。

]]>
https://anqou.net/poc/2019/02/23/post-2745/feed/ 1
私とプログラミングとおっぱい https://anqou.net/poc/2019/01/07/post-2682/ https://anqou.net/poc/2019/01/07/post-2682/#comments Sun, 06 Jan 2019 16:17:13 +0000 https://anqou.net/poc/?p=2682 最近スマホのブラウザに「おすすめ記事」が表示されるようになった。どうやら、私が普段見ているサイトから推測して表示されるらしい。私がスマホのブラウザで見るものなど、プログラミングに関するものか、おっぱいと相場が決まっている。いつ親にブラウザの履歴を見られても問題ないように、おっぱいはシークレットブラウザで見ているから、結局プログラミングの記事ばかりが並ぶことになる。

「おすすめ記事」にはプログラミング言語の紹介サイトがよく現れる。有り体に言えば「今年学ぶべきプログラミング言語5選!」のようなものである。開いてみると、有名なプログラミング言語が薄っぺらい説明とともに数種類載っている。私なんかはひねくれているから、「お前がそう思うんならそうなんだろう お前ん中ではな」などと口走りつつページを閉じるのである。そしておっぱいを見る。

ところで、私が中学2年か3年のときに、和田裕介さんの『Webサービスのつくり方 〜「新しい」を生み出すための33のエッセイ』という本を本屋で立ち読みした。Amazonのサイトに行くとこの本の目次が読めるのであるが、その第4章に「いかにして大量のおっぱい画像をダウンロードするか」という項目がある。中学生の私は大いに興奮しながらそのページを読んだ。記憶が確かなら、そこにはプログラミングを使っておっぱい画像をダウンロードしてくる話が書いてあったのである。この話は和田さんの(あるいは「ゆーすけべー」さんの)ブログにも公開されていて、これを行うためのプログラムを入手することができる。このプログラムはPerlというプログラミング言語で書かれていた。こうして私はPerlという言語を知った。今から考えるとひどい出会い方である。

さてそんなおっぱい言語、もとい病的折衷主義のがらくた出力機、もとい実用データ取得レポート作成言語Perlで書かれた画像ダウンロードプログラムを、中学生の鮟鱇少年はわくわくしながら改造するのである。「まともな」(婉曲表現)おっぱい画像を集めるためにクエリをいじってみたり、より多くののおっぱいを集めるべく取得件数を多くしてみたり。そのためにはPerlのことを知らなければならないから、俗に言う「ラクダ本」を図書館から借りてきて読みふけったし、あるいは画像検索のAPIの仕様をネットで調べたりもした。心底楽しかったのを覚えている。その後わたしはRubyと出会って、おっぱいプログラムをRubyで書き直したりもするのだが、それは別の話。

プログラミングを学ぶって畢竟こういうことなんじゃないだろうか。自分がやりたいことがあって、それを達成するための道具としてプログラミングをやる。中学生の私には、たまたまそれがPerlであったわけで、それがPerlであったことそのものが重要だったわけではない。もちろん職としてプログラミングをやるならある程度「トレンド」のようなものがあるのかもしれないけれど、趣味としてやるなら「どのプログラミング言語を選べばよいか」よりもむしろ「プログラミングで何をやりたいか」のほうが重要なのだろうと思う。

中学の頃から足掛け9年ほどプログラミングをやってきた経験からいえば、メジャーなプログラミング言語を1つ知っていれば、他のものでもある程度検討がつく。薄く広く知っていれば、自分がやりたいことをどのようにやればいいかも自然と分かることが多い。少なくとも趣味としてはこれで十分なんだろうなと、おっぱいを見ながら思うのである。

]]>
https://anqou.net/poc/2019/01/07/post-2682/feed/ 2
できる! コンパイラ作成の資料まとめ https://anqou.net/poc/2019/01/03/post-2650/ https://anqou.net/poc/2019/01/03/post-2650/#respond Thu, 03 Jan 2019 04:49:47 +0000 https://anqou.net/poc/?p=2650 あけましておめでとうございます。今年もよろしくおねがいします。艮鮟鱇です。

さてつい先程、友人から「冬休みに言語処理系ちょっと書いてみたいんだけどいい資料ない?」(意訳)と言われました。新しい年も始まりましたし、これを機にコンパイラ・インタプリタを書き始める人も少なくないこともないかもしれません。

ということで私が把握している言語処理系開発のための資料を以下に一覧します。上から順に見ていって、自分に合うものを探して頂ければと思います。私がよく知っているものを並べたので、全体的にCコンパイラよりです。「自分が開発するときに見るやつが載ってない!」という方は是非コメントをくださるか、 Twitterで雑にリプライをお願いします。

低レイヤを知りたい人のためのCコンパイラ作成入門

セキュキャン2018 Cコンパイラ開発ゼミの講師の一人、Rui UeyamaさんのCコンパイラ作成入門資料です。タイトルでGoogle検索すると、この資料を読んで実際にコンパイラを開発している方のブログなども見ることができます。

この資料はセキュキャン2018をもとに書かれたものですが1 そのときの様子はCコンパイラゼミ講師のRuiさんのnote (「Cコンパイラ制作の夏期集中コースが思っていた以上にうまくいった話」)や同じく講師のhikaliumさんのスライド(3(0)日でできる!Cコンパイラ自作入門)などから参照できます。

(1/3 追記)講師のRuiさん・hikaliumさんが開発した/しているCコンパイラは次から参照できます:

Cコンパイラ開発ゼミ参加者の感想などは次から参照できます:

簡単なプログラミング言語を作るライブコーディング

上の資料と同様にRui Ueyamaさんの、言語処理系ライブコーディングの動画。最終的にフィボナッチ数列を計算できるインタプリタが、約30分で完成します。

この動画にインスパイアされて似たようなインタプリタを作った私のスライドがこちらです(宣伝):「10ステップで作るお手軽インタプリタ開発」

プログラミング言語を作る

本にもなっている言語処理系作成ページ。インタプリタcrowbarと、バイトコードにコンパイルして実行するDiksamを開発されています。クロージャ・GC・VMなどが実装されています。 Cコンパイラ開発ゼミでは使用しなかったlex/yaccの使い方やLALRの説明2なども記載されています。

Compiler Explorer

Cコンパイラ開発者御用達。入力したCプログラムがgccやclangでどのようにアセンブリに変換されるかを見ることができます。自分で gcc -S hoge.c などするよりも楽なのでよく使います。

Intel SDM

Intel CPUのSDM (Software Developer’s Manuals)。 IntelのCPUにおいて、どんなアセンブリをかけばどんな挙動をするのかが一覧されています。章ごとにダウンロードするのがおすすめです(Four-Volume Set of Intel® 64 and IA-32 Architectures Software Developer’s Manuals)。とくにINSTRUCTION SET REFERENCEが載っているVolume 2を多用します。

Intel SDMは文書量が膨大かつ記述言語が英語なので、全部読むのはいろいろとつらいところがあります。例えば「x86-64プロセッサでGNU assemblerを使う」「x86-64プロセッサのスタックを理解する」などのまとめページを読むと、全体的な(簡易の)理解を得られます。

(PDF注意) System V Application Binary Interface AMD64 Architecture Processor Supplement

AMD64のABI(のドラフト)。Cの型のサイズや、関数引数の渡し方などが一覧されています。 va_startva_argの実装方法などが記載されており、 Cコンパイラで可変長引数関数に対応する時に重宝します。

C言語仕様書

いろいろあります。とりあえずC11の仕様(のドラフト)(PDF注意)を参照すれば大抵うまくいきます。英語が苦手な人はC99ベースのJIS規格を参照してください。

Annex AにBNFがあります。これを見ながら再帰下降するとパーサが書けます。ただしJIS規格ではAnnexが省略されているので注意です。

ドラゴンブック

正式名称は「コンパイラ―原理・技法・ツール (Information & Computing)」。コンパイラ作成の伝統的な名著――という噂です。筆者は買いましたがちゃんと読んでいません。

べらぼうに値段が高い書籍3ですが、原著(英語)でよければ、名前で検索するとPDFが落ちていたりいなかったりします。というかこれはライセンス的にどうなんだろう……。

同じような書籍で「タイガーブック」もありますが、こちらは持ってすら居ないので割愛4

その他

より体系的な入門記事は「低レイヤーの歩き方 – るくすの日記 ~ Out_Of_Range ~」が有名です。言語処理系についても記載があります。

他には、Rui UeyamaさんによるポッドキャストTuring Complete FMでも Cコンパイラ開発ゼミの話や言語処理系の話がされています。


  1. もともとはCコンパイラ開発ゼミの内部資料だったものを、ほぼ全面改定し公開されたものです。↩
  2. 本文中に明記されてないけど多分LALRのはず。あれ、LRだっけ?↩
  3. でも専門性の高い大学の教科書は大体このくらいしますけど。↩
  4. これを「難しい本なんて読まなくてもコンパイラは書ける」と捉えるか、「しょせん深海魚はその程度か」と捉えるかはあなた次第() どちらの考え方も半分正しくて半分間違ってるような気がしますけど。↩
]]>
https://anqou.net/poc/2019/01/03/post-2650/feed/ 0
seccamp2018とKernel/VM@関西と「やるだけ」 https://anqou.net/poc/2018/12/25/post-2547/ https://anqou.net/poc/2018/12/25/post-2547/#respond Mon, 24 Dec 2018 15:33:26 +0000 https://anqou.net/poc/?p=2547 この記事は2018年の10月くらいに投稿しようと思いながらも結局投稿しなかった記事原案を、適当に編集したものです。

セキュリティキャンプ全国大会2018とKernel/VM@関西 9回目とちょっとだけ話題になった「やるだけ」の話をします。

お久しぶりです。艮鮟鱇です。一行目はTwitterのカードに出るので2行目で挨拶です。 Twitter対策大事ですね。あんまりTwitterやらないけど。わくわく鮟鱇ランドはいいぞ。

さて今日は夏休みに圧倒的成長をした話をします。嘘です。でもちょっとくらいは成長した話をします。もっと素朴に言えば、セキュリティキャンプとKernel/VMの話です。夏休みの総仕上げでもあります。予定が立て込んで夏休み中に書けなかったのが少し心残りです。仕方がないので、9月32日の気分で書きます。

セキュリティキャンプ全国大会2018

先日も書きましたが、8月の中旬にセキュリティキャンプ全国大会2018に行って、 Ruiさんとhikaliumさんのご指導の元、セルフホストCコンパイラを作ってきました。1

セキュリティキャンプの全般的な話はいろんな体験記に上がっているので省略することにして2、自分が面白かった話をいくつか書きたいと思います。

プログラミングは孤独な作業です。パソコンに向かってキーボードをカタカタ。特に私はいままで開かれたコミュニティに参加することも無かったため、自分が書いたコードの良し悪し、あるいはコードが綺麗とか汚いといった判断をする人は自分しか居ませんでした。 3

それに対して、セキュリティキャンプでは自分のコードについてRuiさんやhikaliumさんから助言や意見を頂くことができました。この部分のロジックを変えたほうがいいといった指摘から、変数名の英語がおかしいといった細かい問題まで、自分のコードを読んで、コメントしてもらえるというのはとても新鮮で、貴重な経験でした。自分の書いたコードの悪いところ・良いところを客観的に知ることができ、最終的に自分が書いたコードに自信を持つことができました。4

さて、Cコンパイラを作ろうゼミでは、一貫して「インクリメンタルな開発」というものを志向しました。これはつまり、全てを一気に作ろうとするのではなくて、スモールステップで動くものを作るということ。例えばCコンパイラなら、まず整数値を1つ読み込んで、それを返すようなアセンブリを出力する「コンパイラ」から始めます。実際のコードがここから読めますが、たった14行、本質的なところは5行しかありません。これを「コンパイラ」と果たして呼んでいいのか甚だ疑問ですが、しかし全てはここから始まります。そこから演算子+を足し、-を足し、と開発が進みます。重要なことは「動いている」ということです。同時に「テスト」と呼ばれるものを書いて、 Cコンパイラが正しく動いているかを常にチェックします。どのコミットでもこのテストを通っているようにすることで、自分が加えた変更が正しいものであることを保証できます。

つまり金太郎飴みたいなものです。どのコミットを見ても、それがある意味での「完成形」になっていて、限定的な機能しかないかもしれないけれど、ちゃんと動くようになっています。

やっぱりプログラムは動かないと楽しくありません。動くとモチベーションも維持できますし、どれだけ自分が進んだかを実感することもできます。結果として、開発を気分よく進めることができます。

こういった「インクリメンタルな開発」や「テスト」といったものを、耳にすることはあっても実際に自分の開発で意識して使ってみることはありませんでした。セキュリティキャンプによって今後自分がどういったコードを好んで書いていけばいいか、一つの指針が出来たような気がしています。

ところで、セキュリティキャンプでは最後に「成果発表」という時間があります。これは、各人がセキュリティキャンプ中にどのようなことをしたのか、他の参加者に向けて発表する場です。ここでした私の発表がめっちゃ受けました。楽しかったです。発表は面白くてなんぼですね。まぁ多分いちばん感動を呼んだのはuint256_tさんのものなんですが。あれはやばかった。

Kernel/VM@関西 9回目

さてセキュリティキャンプの帰路、TwitterのTLでKernel/VMの話が出たので反応したところ、おるみんさんからすぐにリプライが飛んで来た結果、 Kernel/VM@関西 9回目という勉強会で成果発表のスライドを持って登壇することになりました。

Kernel/VMは低レイヤープログラミングのエキスパートの方々が集まる勉強会だというのはTwitterでちらほら見ていました。ということは、きっとCコンパイラを実際に作ったことはなくても、その作り方は知っているだろうというのも容易に想像がつきます。そこで発表の方針としては、コンパイラの作り方をくどくど説明するようなものではなく、実際にCコンパイラを作ってみてつらかったところや面白かったところを中心に伝えようと考えました。「実際にやってみた」ってやつですね。これなら知識のない自分にもできそうです。

ところがここで問題が浮上しました。セキュリティキャンプの成果発表は7分でした。つまり手元には7分の長さのスライドしかありません。対してKernel/VMは15分〜20分です。なんとかしてこの資料をかさ増しする必要がありますが、生半可なことを書いても面白くありません。

そこで、新しくアセンブラを書くことにしました。これなら、途中で失敗しても「バグった!」というスライドを作れば受けます。どちらに転んでも面白い発表ができそうです。

まずアセンブラが何をやっているか調べなければなりません。コンパイラを書いたときは気軽に質問を投げることができましたが、今回は一人です。まず既存の実装を見てみようと思い、GNU assemblerのソースコード見てみると、大変年季の入ったコードで、3分少々で読むのを諦めました。仕方がないのでGNU assemblerの出力を解読するところから始めました。バイナリをodで16進数に直して、ELFの資料をお供にひたすら読み進めました。アセンブラがやっていることがわかれば、次は実装です。

アセンブラを書き始めてからおおよそ2週間後の9月上旬に、とりあえず動くものができました。安堵したのもつかの間、アセンブラのスライドを書いてみると、どうにもバランスが取れません。通常Cプログラムはコンパイラとアセンブラを経由した後にリンカを通って実行バイナリに変換されます。そう、リンカを書かなければ、スライドの都合上流れが悪いのです。

ということでリンカを書き始めました。Mastodonでsksatさんに勧められて買った『リンカ・ローダ実践開発テクニック』が大いに役に立ちました。リンカを書いている最中に言霊.inを引用するネタと「やるだけツールチェイン」のネタを思いつきました。なんとしてもそのスライドまでこぎつけなければ、死んでも死にきれない。そう思ってリンカの開発を急ぎました。

結果、9月中旬に自作リンカでaqccをセルフホストできるようになりました。そこからスライドを作って、Kernel/VMで発表したところめっちゃ受けました5 とても楽しい経験ができました。

「やるだけ」

そんな発表資料ですが、見ていただくと「やるだけ」というネタを一貫して使っていることが分かります。これは「天丼」的な効果を狙うと同時に、技術的にはやればできるが、実際にやってみるといろいろ面白いことが分かる、という意味も含んだ表現です。また、セキュキャンに参加したことで、「できそうもないこと」を「やるだけ」にすることができた、という意味も含んでいます。

Cコンパイラを書き始めた当初は、どうにも自分がCコンパイラを書けるとは思いませんでした。いってみれば、「やってもできない」感じがしていたわけです。

セキュリティキャンプに参加することによって、「やってもできない」ことを「やるだけ」――より正確に言えば「このようにすればできる」という技術と自信を得ることができました。

まとめ

もっといろいろと書くべきことがあるような気がしますが、うまく文章がまとまらないのでこのへんで筆をおくことにします。書いてる内に頓珍漢なことのように思えてくるし、文章を書くのは難しいですね。

最後になりましたが、セキュキャン講師のRuiさんhikaliumさんをはじめ、多くの方々にお世話になりました。この場を借りてお礼申し上げます。ありがとうございました。


  1. 私のセキュリティキャンプ応募内容と、 Cコンパイラ開発記は各々すでに坩堝に上がっているのでまだ読んでいない方はぜひチェックしてみて下さい。↩
  2. 講師のRuiさん、hikaliumさん視点でのセキュリティキャンプの感想はTuring Complete FMでポッドキャストとして配信されています。↩
  3. 形式上過去形になっていますが、今でも基本的にそうです。書くプログラムの多くは人目に触れない気がするし、私に限らず意外とそんなものかもしれない。↩
  4. もちろん悪い点を指摘されると少々へこむわけですが、「悪いところは直せばいい」というゼミの雰囲気があり、とても開発しやすい環境でした。その辺りの話はRuiさんがnoteに書かれています↩
  5. 発表資料はSpeakerdeckに上がっています。発表の様子はYouTubeに上がっています↩
]]>
https://anqou.net/poc/2018/12/25/post-2547/feed/ 0
すきあらば自分語り 〜鮟鱇の場合〜 https://anqou.net/poc/2018/11/23/post-2001/ https://anqou.net/poc/2018/11/23/post-2001/#comments Fri, 23 Nov 2018 14:37:47 +0000 https://anqou.net/poc/?p=2001 すきがあるので自分語りをする。

幼年期

非常に残念ながら、私には前世の記憶や母親の胎内にいたときの記憶はない。前世で徳を積まなかったのだろうか。さらに言えば、幼稚園の頃の記憶もあまりない。

などといいつつ、幼長のころ、年下の女の子に追いかけられていたことは覚えている。たぶん人生最後のモテ期である。どんな子に追いかけられたか、もう顔も覚えていない。

あとやたらと飴をねだるので「飴太郎」というあだ名がついた。つくづく安直な名前である。

少年期

小学校に入った。入ったその日に、となりの男の子に殴られて泣いていた、らしい。記憶がない。ただ低学年のうちは「子供カースト」の下の方であったのは否定しない。まぁそんなものである。

小学3年生のころに、将棋マイブームがやってきた。休み時間になっては、友人と一局指していたような覚えがある。家でも父親相手に指すこともあったが、なかなか時間が合わない。母親は将棋を指さない。これでは家で研鑽を積むことはできない。

そんな折に見つけたのがコンピュータ将棋であった。これなら家でも将棋を楽しむことができる。色々と調べてみると、フリーの将棋ソフトが見つかった。たしか柿木将棋だった気がするが今調べてみると有償のようだ。記憶がはっきりしない。

ただ小学生の鮟鱇少年には、巷のコンピュータ将棋は強すぎた。定跡書などを読み漁った覚えがあるが、とんと上達しない。将棋教室にも行ったが、結局大して強くなることもなくやめてしまった。そのうちマイブームも去り、将棋も全く指さなくなってしまった。

にもかかわらず、このマイブームは後の鮟鱇少年に大きなきっかけをもたらすことになる。すなわち、鮟鱇少年にとって「コンピュータ将棋」との出会いは、同時に「プログラミング」との出会いを意味していたからだ。

プログラミングに出会う

さて鮟鱇少年、コンピュータ将棋で勝ったり負けたり負けたり負けたりしているうちに、どうにもこの程度の(失敬!)プログラムなら作れるのではないかという酔狂な考えを抱き始めた。先に言っておくが、もちろんコンピュータ将棋のプログラムはかなり複雑な構造をしているのが普通であって、当時プログラミング経験もなかった鮟鱇少年がすぐに作れるような代物ではない。

しかしそこは世間を知らない小学生である。とりあえず検索窓に「将棋 作り方」などと打ち込んでみる。すると、なんと「将棋プログラムの作り方」という鮟鱇少年にぴったりのページが見つかるのである。このサイトはC++を用いてコンピュータ将棋をつくるページで、間違っても小学生は対象読者に入っていない。中身を読んでみると、謎の英語(コード)は出てくるし、日本語の部分もよくわからないし、まぁどうにもならない。

どうにもならないが、どうにかしたいのが鮟鱇少年である。さらにいろいろとしらべて、当時のMicrosoft Visual StudioのExpress Edition(無料版)を入れてプログラムの部分だけをコピペしてみたり(もちろん動かない)、「将棋プログラムの作り方」と同じ著者による本『コンピュータ将棋のアルゴリズム』(近年どうもHTML版が公開されているらしい)を図書館から借りてきて読んでみたり(なんだかよくわからない)とまぁいろいろやった。いろいろやって、結局どうにもならずに諦めてしまった。

しかしここで、プログラミングに興味を持ったのは事実である。次に図書館に行って『30日でできる! OS自作入門』を借りてきた。なんということはない、語り口が軽妙で、読みやすそうだったのがその理由である。厚さにして4cmもある本を、さながら二宮金次郎像のように、登校途中に歩きながら読んでいた記憶がある。

一応読み通しはしたが、結局C言語はよく分からなかったし、OSも作ろうとはしなかった。ただ、図版が豊富だったこともあって、コンピュータがどのような仕組みで動いているのかを理解するのにはおおいに役に立った。このあとC言語を本格的に学習する際に、たとえばポインタのような概念で躓くことがほぼなかったのは、この本のおかげだろうと思う。

そんなこんなで、プログラミングと少し触れ合いつつも、コードはほとんど書かずに小学生を終えた。

(またすきがあれば続く)

]]>
https://anqou.net/poc/2018/11/23/post-2001/feed/ 1
セキュキャン体験記に代えて https://anqou.net/poc/2018/08/22/post-1881/ https://anqou.net/poc/2018/08/22/post-1881/#respond Wed, 22 Aug 2018 13:04:47 +0000 https://anqou.net/poc/?p=1881 セキュキャンから帰ってきた。合宿中にあったあんなことやこんなことを家族に話していたら、そもそも私がセキュキャンで何をしてきたのかという話になった。セルフホストのCコンパイラを作ってきたんだと言ったら、納得の行かない顔をしている。どうやらCコンパイラを自作することに価値を見いだせないようだ。無理もない。技術界隈でよく話題になる「車輪の再発明」だと言われれば、少々返答に困る。

Cコンパイラは、Cというプログラミング言語で書かれたプログラムを機械語に変換する、いわば翻訳者のようなソフトウェアである。プログラミング言語は人間にとって分かりやすいが機械には読めず、機械語は機械が読めるが人間には読みにくい。いわば、人間と機械の橋渡しをするためのものだ。 C言語は生み出されてから久しいから、もちろんすでに実用的なCコンパイラが存在しており、かなり精度のいい機械語を生成してくれる。正直、既存のCコンパイラに特に不満はない。それどころか、私が手作りするようなCコンパイラでは、その速度や生成する機械語の良し悪しで太刀打ちできるはずもない。なぜそれを、一から手作りする必要があるのだろうか。一見、何の意味もない行為に思える。

コンパイラは魔法だ。自然言語のように書かれたテキストを自律的に解釈する。規約どおりに書けばちゃんと動く。しかしこの魔法が、そんじょそこらの魔法と大きく違うのは、中身を理解できるということである。理論があり、実装がある。「ホゲホゲフガフガ」と唱えたら水が出てくる、論理もへったくれもないおとぎ話とは大違いだ。

理解ができるなら、それを応用することだって可能である。例えば機械語(ないしそれを少し簡単化したアセンブリと呼ばれるもの)の知識を、コンピュータの理解に役立てることができるだろう。Cプログラムを解析する部分の理論を、整形されたデータフォーマットの解析に使うことができるだろう。6000行規模のCプログラムを書いた経験を元に、次に書く同じような規模のプログラムの設計の見通しを立てることが出来るだろう。

結局、この「魔法」を理解してみたいというのが一番大きい動機だろうか。他にも「大きなプログラムを書いてみたい」とか「アセンブリに触れてみたい」とか、考えれば種々あるけれど、一番大きいのは「魔法を解明したい」という単純な欲求かも知れない。ちょうど、小学生がマジックのタネを知りたいような。

もちろん、こんな小難しいことを考えながら開発したわけではない。ただ、「それがぼくには楽しかったから」

 

]]>
https://anqou.net/poc/2018/08/22/post-1881/feed/ 0
セキュリティ・キャンプ全国大会2018応募用紙の話 https://anqou.net/poc/2018/06/15/post-1600/ https://anqou.net/poc/2018/06/15/post-1600/#respond Fri, 15 Jun 2018 08:24:07 +0000 https://anqou.net/poc/?p=1600 みなさんこんにちは。(はじめまして|お久しぶりです)。艮鮟鱇です。6月に入り少しずつ暑くなって参りましたが皆様御機嫌如何でしょうか。私は花粉症です。

さてこの度 セキュリティ・キャンプ全国大会2018 というものに出来心で応募したところ、なんと通ってしまいました。びっくらぽんです。このイベントは一度選考を通ってしまえば参加できる(二次面接などはない)ので、 8月の半ばぐらいに開催地である東京に行って、私の場合はC言語コンパイラを作成することになります。今からわくわくどきどき楽しみです。セキュリティ・キャンプの詳細を知りたい方は公式サイトをどうぞ。

さて、セキュリティ・キャンプに通った人はその応募内容を晒すと、ナウなヤングでバッチグーになれるそうです。ぜひ私もナウなヤングでバッチグーになりたいので以下に貼り付けようと思います。

問題

私は集中開発コースシステムプログラミングトラックの「C コンパイラを自作してみよう!」というゼミに応募しました。このゼミの問題は以下のようなものでした。

[問1] これまでのプログラミング歴(C言語に限りません)について好きなだけ語ってください。何か作ったものがあれば、それについても教えてください。

[問2] コンパイラがソースコードから実行バイナリを生成する過程について、現在知っている範囲で説明してください。ソースコードの言語については、好きなものでかまいません。

[問3] C言語のコンパイラを書く際に、最も難しいポイントはどこだと思いますか?考えたことや、これまでのプログラミング経験をもとに、具体的に教えてください。

[問4]. 何か他にアピールしたいことがあれば、自由に書いてください。この設問も含め、誤ったことを書いていても減点はしません。書いておきたいことはなんでも書いてください。

鮟鱇の回答

順に掲載します。

[問1] これまでのプログラミング歴(C言語に限りません)について好きなだけ語ってください。何か作ったものがあれば、それについても教えてください。

※ この問の一番下に、これまでに作成したプログラムの一覧の抜粋を書きました。

小学生のころにコンピュータ将棋がきっかけでプログラミングを始め、現在まで続けてきました。はじめはコンピュータ将棋のれさぴょんなどが実装されているC++に興味を持ったのですが、当時の自分には難しく、Windowsの簡単なバッチファイルを書くなど以外では、プログラミングそのものをすることはあまりありませんでした。その代わり、近くの図書館にあった『コンピュータ将棋のアルゴリズム』(池 泰弘、I・O BOOKS、2005)や、『30日でできる! OS自作入門』(川合 秀実、毎日コミュニケーションズ、2006)などを読みながら、コンピュータの動き方や内部的な構造、MinMax法・リングバッファといったアルゴリズム・データ構造を眺めていました。いま思えば、このときの経験が、自分が情報系の道に進みたいと思った大きなきっかけとなったと思っています。

中学生になって情報同好会に入り、本格的にプログラミングを始めました。C言語からはじめ、C++・Perlなどを書いていました。特にC++(というよりむしろBetter Cでしたが)とDXライブラリを使ってゲームなどを作成し、文化祭などで展示していました。そのうちDXライブラリでは、Windowsのコンポーネントを利用したツール類が作りにくいことを知り、『猫でもわかるWindowsプログラミング 第3版』(粂井 康孝、ソフトバンククリエイティブ、2008年)やインターネットの情報などを頼りに、 Win32APIを使ってソフトウェアを作成していました。

また中学三年のころから「さくらのVPS」を借り、簡単なCGI掲示板を書いて運用していました。同じサーバーでMinecraftのためのマルチサーバーなども立ち上げていましたが、これを起動・終了するためのシェルスクリプトを書いているうちにシェルスクリプトで全てを行うことに限界を感じ、 PerlやRubyで書き直したりしていました。

高校生になってからは、C++やRubyを使って簡単なツールなどを作るようになりました。高校1年のときには、クイズ研究会に頼まれて、後輩と共に得点表示ソフトウェアを作りました。高校2年のときには、文化祭でインターネットラジオを放送することになり、複数本のマイクの音声を内部でミックスし、仮想オーディオラインに流すようなソフトウェアを書きました。

また、WordPressを使用して、複数人で更新するブログの管理をやっていました。ここで使用したWordPressテンプレートがSimplicity2ですが、デフォルトのコードではどの著者が投稿したのかひと目では分からず困ったため、PHPを書き換えて表示するようにしました。

大学に入ってからは忙しくなったこともあり、大きなプログラムを書くことはあまりなくなりました。情報技術の基礎を教える授業で登場したモデルコンピュータ(アセンブリと機械語が対応していることを示すためのモデル化されたコンピュータ)の仕様から、簡単なアセンブラやエミュレータを作りました。 Ruby on Railsを使って過去問管理Webアプリケーションを作成しました。友達に誘われて競技プログラミングを始めました。現在はAtCoderで水色です。 Mastodonのセットアップの際に実行されるスクリプトにバグがあったのでPull Requestを送り、マージされました。

直近ではMaLというチュートリアルを参考にしながらLISPインタプリタを作成しました。またC++17のconstexprを使用して、ニューラルネットの学習をコンパイル時に行うプログラムを作成中です。 C++でTwitterクライアントを作成中ですが、TwitterのUserstream廃止を受けて、現在計画が宙ぶらりんになっています。 Python3と機械学習用ライブラリであるChainerを使って、ニューラルネットに関する論文の実装などを行っています。

【これまでに作成したソフトウェアの一覧の抜粋】

おおよそ時系列です。

ブロック崩し

自分で作った最初のまともなソフトウェアです。C++とDXライブラリで実装しました。下の方でユーザーが操作するバーが動き、上にあるブロックに動く玉をぶつけてこわします。文化祭で展示しました。

お絵かきソフト

ドラッグすると線が引かれます。初めはDXライブラリを使って実装しましたが、太い線が書けず、Win32APIのペンを使用して実装し直しました。

ComingBossSoon

予め指定したキーを押すと、現在開いているウィンドウを全て隠してくれるソフトウェアです。 C++とWin32APIのライブラリであるWin32++を使用して実装しました。内部的には、Win32APIのEnumWindows()とShowWindow()を使用していました。

Chess

『コンピュータ将棋のアルゴリズム』を参考にしながらチェスAIをC++で作成しました。単純なαβ法に定跡データを載せただけのものでしたが、自分より強くなってしまい、AIが負けた時のデバッグに困りました。

Ash

クイズの大会中に参加者の点数を表示するためのソフトウェアです。学校のクイズ研究部と協力して作成しました。「クイズの大会」と一口に言ってもその種類は様々で、表示すべき内容と入力仕様(つまりMVCのViewとController)が多様でした。そこで、Viewに関しては後輩がHSPを使用して作成し、私がC++で書くModel部分とはWM_COPYDATAを使用して通信を行いました。また、Luaを組み込んだ上でこれを使用してControllerを書くことで、Model側のコンパイルをせずに変更が可能なようにしました。

ソースはこちらです。

cables

インターネットラジオを文化祭で放送するに当たって作成したソフトウェアです。WindowsとLinux両対応です。 PCに接続された複数のマイクから入力を取り込み、それをミックスしてスピーカーに出力します。ここで「マイク」と「スピーカー」は、WindowsやLinuxからそう認識されるものであれば何でも良いので、音楽再生用ソフトウェアから出力される音楽を仮想オーディオラインを通じてcablesに取り込んでミックスし、ラジオのBGMとするなどの使い方をしました。また、実際の運用時にはマイクが接続されるPCとインターネットに配信するPCを別にしました。そのため、この2台のPCをLANケーブルでつなぎ、両方でcablesを起動した後、cables内部でソケット通信を行うことで音声をやりとりしました。

入力・出力は仮想化されていて、実際にそれが何をしているかを気にせずに扱うことが出来るようにしました。音声を入出力する単一のデバイスをUnitという単位で構成し、これらをSocketと呼ばれる機構でつなぎ合わせることで、全体のシステムが構築されるようにしました。Unitにはマイクから直接音声を取得するものだけではなく、リバーブフィルタなども含まれました。

全体として、音声を受け取るとスレッドが走り、予め指定したユニットを経由して、スピーカーやソケット通信路へと流すようになっていました。

ソースはこちらです。

Repka

大学過去問管理Webアプリケーションです。Ruby on Railsを使用して作成しました。(主に法的な)諸般の事情から運用はしていません。過去問の情報(教員・科目名・年度・ファイルへのリンクなど)を登録すると、それらの情報に対して部分一致検索をできるようになっています。 RoRの習作として作成しました。

ソースはこちらです。

鼻くんパズル

友人が作った「鼻くん」というキャラクターを使った8パズルです。C++とSFMLを使って作りました。動いているイメージがこちらにあります。

ソースはこちらです。

パチンコ

Windows XPに付属していたピンボールのようなゲームです。C++とSFMLを使って作りました。 SFMLを使用する部分は上の「鼻くんパズル」と実装が共通しています。

SVGを読み込ませると、それがそのままマップになります。汎用的な当たり判定の仕組みを作成するのに苦労した覚えがあります。 hanakunブランチにすると上の「鼻くん」がボールとして飛びます。動作イメージはこちらです。

ソースはこちらです。

MastodonへのPull Request

Mastodonサーバーを立てる際に実行されるrakeファイルにバグが有ったので、これを直すPRを送ったところ、マージされました。 1つめ 2つめ

MaL

MaLというチュートリアルに従って LISPインタプリタを作成しました。Step Aを除いて全てのテストを通しました。

ソースはこちらです。

constexpr-nn

C++17のconstexprを使用して、コンパイル時にニューラルネットの学習を行うプログラムです。現在作業中です。 C++14においてconstexprが大幅に制限緩和されたため、実行時向けに書くコードとほとんど同じように、コンパイル時に動くコードを書くことが出来ます。

ソースはこちらです。

Yellow

バイナリ一つで動くTwitterクライアントを目指してC++で書き始めましたが、TwitterがUserstreamの8月廃止を決めたため、モチベーションが下がっています。Twitterとの通信にlibcurlを使用しています。

ソースはこちらです。

Chainerを用いたニューラルネット論文の実装

Towards Understanding Generalization of Deep Learning: Perspective of Loss Landscapes という論文で登場する「訓練サンプルに対しては良い性能を示すが、テストサンプルに対しては悪い性能を示すニューラルネット」を作成するためのシステムの実装を、Python3と機械学習用ライブラリのChainerを用いて行っています。基本的な実装は終了しましたが、適切なハイパーパラメータが見つからず、調整中です。

ソースはこちらです。

[問2] コンパイラがソースコードから実行バイナリを生成する過程について、現在知っている範囲で説明してください。ソースコードの言語については、好きなものでかまいません。

C言語コンパイラについて説明します。まずソースコードを読み込んで、正規表現などを用いてトークンごとに切り分けます。正規表現は決定性有限オートマトンに変換できるため、これにマッチするかどうかで文字列の切り分けを行うことが出来ます。言語処理系のトークン切り分けのためのC言語コードを生成するソフトウェアとしてLex及びその強化版であるFlexなどがあります。

次に、それらのトークンの列を抽象構文木(AST)と呼ばれる木構造に変換します。これによって、トークンの羅列だったソースコードを、コンパイラが理解できるような形にします。例えば、「a = 1 + 2 * 3;」というプログラムは

         =
       /   \
      a     +
          /   \
         1     *
             /   \
            2     3

以上のような木に変換されます。このような変換は、文脈自由文法によって記述された規則をもとに構文解析器を作成することで行います。構文解析器は、その仕組みによってLL法・LALR法・LR法などに別れます。C言語にはLALR法の構文解析器を使用することが出来ます。言語処理系の構文解析器のC言語コードを生成するソフトウェアとしてYacc及びその強化版であるBisonなどがあります。

次に意味解析を行います。ここでは、C言語の言語仕様と照らし合わせて不正なプログラムが書かれていないかを検査すると同時に、プログラム内で使用されている識別子に関する情報を得ます。例えば int i; という文があるときには、ここでint型の変数iが宣言されることを記録すると同時に、同一スコープ内で同名の変数が宣言されていないかなどを確認し、不正な場合にはエラーを出力します。

続いて最適化を行います。例えば即値で書かれているような計算は、あらかじめコンパイラが計算した値を代わりに使用することで、最終的なバイナリの実行速度を上げることができます。また、必要のない計算を行っている部分を削除することで、バイナリのサイズを小さくすることが出来ます。

最後にコード生成を行います。上で作成した構文木や識別子の情報などを参照し、それらに対応するアセンブリ(LLVMを利用するならば中間コード)を出力します。

出力されたアセンブリはアセンブラによって機械語へと翻訳されオブジェクトファイルとなります。その後、複数の(少なくとも1つ以上の)オブジェクトファイルがリンカによってリンクされて実行バイナリとなります。

参考:『実践コンパイラ構成法』(滝本宗宏、コロナ社、2017)

[問3] C言語のコンパイラを書く際に、最も難しいポイントはどこだと思いますか?考えたことや、これまでのプログラミング経験をもとに、具体的に教えてください。

この問への答えは、どの程度の技術水準を持った人がプログラムを書くかや、Lex・Yaccなどのツールを使用するかによってかなり異なると思います。

仮にYaccを使用せずにC言語コンパイラを書くとすると、一番困難かつ煩雑なのは構文解析器を作成する部分だと思います。再帰下降型構文解析を行うことが出来るLL法は比較的実装が簡単ですが、これではC言語の構文解析は不可能なため、LR法やLALR法を用いる必要があります。私はこれらの構文解析器の実装をしたことがないので正確なところはよく分かりませんが、今回この文章を書くために『実践コンパイラ構成法』などを調べた際に、理論的に難解であるという印象を受けました。実装に落とし込むのは、より難しいだろうと思います。逆に、Yaccを使用するならば、構文解析器の作成はある程度簡単になるだろうと思います。C言語の言語仕様は、 Yaccと同じような記法で書かれているためです(C99言語仕様のAnnex A)。これを利用してYaccコードを書くことができれば、極めて容易に構文解析器を実装することが出来ると思います。

その他に困難な点として、言語仕様を理解するという点が挙げられると思います。例えばsizeof演算子の詳細な挙動や暗黙の型変換の規則など、コンパイラを作る際には把握しなければならないであろう事柄でも、 C言語のコードを書くだけなら、「なんとなく」の理解で済んでしまいます。私は、C言語の表層的な理解はしているつもりですが、言語仕様を1から読んだことはありません。 C言語コンパイラを作成する際にはこれを理解する必要があります。

そのうえで、いま作ろうとしているコンパイラの実装デザインを考える必要があります。拙速に実装を初めてしまうと、途中で大幅にコードを改変する必要が出てくることがあります。アドホックなやり方でこれを乗り切ると、最終的に誰も読めないようなソースコードが生まれてしまう可能性があります。これはバグの温床になりえるため、避けなければなりません。ただ、未来のコードを予測して現在のコードを書くことはそれほど容易ではありません。逆に想定しなくても良いコードを想定してしまったために、コードが煩雑になってしまうこともあります。例えばC++などで不用意に共通部分を継承関係でまとめてしまうと、あるクラスの特異な挙動を実装しにくくなり、結果としてdynamic_castを多用するようなコードを書いてしまうことがあります。このような状況を回避するためには、既存のC言語コンパイラの実装を参照する必要があると思いますが、他人が書いたコードを読むのは一般的に大変な作業になりがちです。

また、個人的に困難なポイントとしてコード生成があります。コンパイラは最終的にアセンブリを出力するため、コンパイラを書くためにはアセンブリを理解しておく必要があります。私はアセンブリを書いたことがほとんど無く、この点に関して1から勉強する必要があると思っています。アセンブリはハードウェアに近い部分であることから、これまで自分がやってきたプログラミングの規則とは異なる部分も多くあると予想されます。これを習得するのは簡単ではないだろうと思います。

[問4]. 何か他にアピールしたいことがあれば、自由に書いてください。この設問も含め、誤ったことを書いていても減点はしません。書いておきたいことはなんでも書いてください。

Twitterです。 GitHubです。 AtCoderです。ブログです。ブログ「カオスの坩堝」は複数人で更新しています。私は「艮 鮟鱇」名義です。私が管理・運営しています。

Linuxに関する通り一遍の知識はあるつもりです。知人向けにLinux 講習会を開催した経験があります。上に書いたブログに、この講習会の議事録があります。

プログラミングを始めた中学1年の頃からコンパイラに興味がありました。当時は何も分かりませんでしたが、そのうちASTや正規表現などを知り、一度挑戦してみようと思っている間に年月が過ぎ去っていました。これではダメだと思い、MaLを見ながらLISPインタプリタを作成しました。おかげで簡単なインタプリタの構造は理解できましたが、実用的なコンパイラに関する興味は一層高まりました。同時期にTuring Complete FMを知って聴取し、自分と同世代のハッカーがたくさん居るということを知りました。何か自分もやってみたいとちょうど思っているときに今回のセキュリティキャンプを見つけ、ぜひやりたいと思って応募しました。よろしくお願いします。

終わりに

今読み直すとかなりひどい文章だと思います。特に問2・問3をもう少し書くべきだったかもしれません。来年度以降応募される方は、あまり参考にしないことをおすすめしておきます。代わりに、といっては変ですが、この記事を編集している間に続々と公開されていた、他の参加者の応募用紙をおすすめしておきます。インターネット上で公開されている応募用紙はここにまとめられています。ぜひ参考になさってみてはいかがでしょうか。

]]>
https://anqou.net/poc/2018/06/15/post-1600/feed/ 0