Rust のStdinを読む

Rust で Command::new した子プロセスに対して標準入出力でやりとりをするコードを書いていて、std::io や std::fs ってどうなっているんだっけ?というのが気になったので、気合いを入れてコードを読むことにした。

Rust における入出力

Rust の入出力機能は、std::io や println マクロを用いて標準入出力するものや、std::fs を用いてファイル入出力するものが一般的である。

Rust で標準出力や標準エラー出力をやりたいだけなら println! や eprintln! で事足りるし、標準入力をするなら std::io::stdin().read_line(&mut buf) を呼ぶだけでいい。ファイル入出力もstd::fs::File を用いて開いたファイルに対して read_line を呼び出すだけで済む。

このように入出力をするだけなら簡単に済むが、その裏側はどうなっているのだろうか?

入出力に関連するトレイト

Rust は入出力の機能を次のトレイトや構造体で抽象化する。

各トレイトは library/std/src/io/mod.rs に実装されている。

BufReader は library/std/src/io/buffered/bufreader.rs に実装されている。

BufWriter は library/std/src/io/buffered/bufwriter.rs に実装されている。

  • Read
    • read() が実装されていることを要求する。バイトごとの読み込みが想定されている。
    • 実装した read() を用いて、read_to_string() などのデフォルト実装を提供する。
  • Write
    • write() と flush() が実装されていることを要求する。
    • 実装した write() や flush() を用いて、write_all などのデフォルト実装を提供する。
  • BufRead
    • Supertrait として Read を指定する。
    • 内部にバッファを持つことで、繰り返し入力する際に毎回システムコールを呼ばないようにするためのトレイト。
  • BufReader
    • Read が実装された構造体に BufRead を実装したものとして取り扱うための構造体。Read を実装した構造体 a を引数に入れて BufReader::new(a) とすることで、a に BufRead も実装したものとして利用することができる。
  • BufWriter
    • BufReader と同様にバッファを用いることで、write() を用いて繰り返し書き込む際に毎回システムコールを呼ばないようにするための構造体。BufRead に対応した BufWrite というトレイトがありそうだが、これは存在しない。BufRead のように追加のメソッドを必要としないためである。

標準入力

標準入力に関する実装を追っていく。

UNIX 系の OS においてファイルからメモリへバイト列を読み込みたい場合、通常 read システムコールを用いる。これを使うことで、裏で動いているファイルシステムやハードウェアの詳細に依存する処理をカーネルが受け持ってくれるようになる。Rust の入力でもどこかでシステムコールが呼ばれているはずだから、どういった流れで read システムコールが呼ばれるのかを探る。

std::io::Stdin

Stdin in std::io - Rust

library/src/io/stdio.rs に実装されている。

std::io::Stdin

以後Stdin と書く。

Stdin は、inner として Mutex<BufReader<StdinRaw>> への &'static な参照をもつ。

Mutex排他制御のために用いられるスマートポインタである。StdinRaw については後ほど説明する。

std::io::stdin() によって Stdin 型の値が得られる。

Stdin には標準入力のための Read が実装されている。 Stdin において、Read の各メソッドは自身の inner に対する lock を取って StdinLock の対応するメソッドを呼び出しているだけである。

StdinLock に頼り切りであることがよく分かる図

Stdin::lock によって明示的に StdinLock 型の値を得ることもできる。StdinLock には Read および BufRead が実装されている。

Stdin には lock して read_line を呼び出すだけの read_line メソッドが実装されている。std::io::stdin().read_line(&mut buf) はこれを呼び出している。

std::io::Stdin::read_line

次に、StdinLock について説明する。

StdinLock

StdinLock in std::io - Rust

library/std/src/io/stdio.rs に実装されている。

std::io::StdinLock

StdinLock は BufReader<StdinRaw> を MutexGuard でくるんだものを inner としてもつ。

各実装は inner のメソッドを呼び出しているだけである。MutexGuard はMutex に対して lock() を呼び出したときに返ってくる型で、 Deref 及び DerefMut を実装しているから、実質 BufReader<StdinRaw> のメソッドが呼ばれている。

StdinRaw に頼り切りであることがよくわかる図

次に、StdinRawについて説明する。

StdinRaw

StdinRaw in std::io::stdio - Rust

library/std/src/io/stdio.rs に実装されている。

std::io::StdinRaw

std::sys::pal::{環境に対応したモジュール}::stdio::Stdin をinner として持つ。ややこしいが、最初に出てきた std::io::Stdin とは異なる。StdinRaw は公開されていない。

library/std/src/io/stdio.rs の中で use crate::sys::stdio としている。これは実際には library/std/src/sys/pal/mod.rs 中でターゲットOS向けに use されたモジュールを指す。以降、UNIX 環境であることを前提とする。(余談だが、2024/01/14 あたりで sys 周りのコードを sys/pal に移す動きがあったらしく、記事を書いてる途中で git pull してみたら全然違うディレクトリ構造になっていて驚いた)

対応するモジュールを定義して、その下にあるものを全て use している

各実装はターゲットOSに対応する stdio の実装を呼び出して、帰ってきた エラーが EBADF の場合は handle_ebadf を用いてOkに変換する。なぜかはわからない(ご存知の方がいれば教えてください...)EBADF は errno = 9 に対応するエラーで、 Bad file number の意味。書き込み専用に開いたファイルに read() システムコールを呼んだ場合などに発生するものらしい。

次に、std::sys::pal::unix::stdio::Stdin について説明する。

std::sys::pal::unix::stdio::Stdin

Stdin in std::sys::unix::stdio - Rust(注: おそらくドキュメントのリンクはそのうち変わる。上記の変更によって sys が sys/pal になるはず。以降貼るリンクも同様。)

library/std/src/sys/pal/unix/stdio.rsに実装されている。

この構造体はユニット型構造体(フィールドを一つも持たない構造体)である。

各メソッドは以下のように実装される。

Stdin

ManuallyDrop はスコープから抜けたときに Drop しないようにするために用いるスマートポインタである。(Deref と DerefMut が実装されている。) UNIX の場合、FileDesc には Drop が実装されていないため、これを用いる。

FileDesc::from_raw_fd は、FramRawFd トレイトを実装した際に定義された関数であり、ファイルディスクリプタの値を受け取ってFileDesc 型の構造体を返す関数である。ファイルディスクリプタとはOSがファイルを扱うときに用いる番号で、libc::STDIN_FILENO は 標準入力に対応する。 (POSIX により 0 と定められていて、実際に中身は整数の0である。)

この関数が unsafe なのは、File::from_raw_fd を使うときの事情らしい (https://github.com/rust-lang/rfcs/issues/1043)

次は std::sys::pal::unix::fd::FileDesc について説明する。

std::sys::pal::unix::fd::FileDesc

FileDesc in std::sys::unix::fd - Rust

library/std/src/sys/pal/unix/fd.rs に実装されている。

FileDesc::read の実装を見ると libc::read を呼び出している。これは read システムコールに対応する。cvt という関数によって、システムコールでエラーが起こった際に適切なエラーを返すようになっている。

まとめ

この記事では、 Rust において入出力がどのように実装されているかをシステムコールに着目して読み進めた。 最初は標準出力/標準エラー出力や、ファイル入出力についても書くつもりだったけれど、そんなに変わらないのでこの記事では書かないことにした。そのうちまとめるかも...

Rust の標準ライブラリは大部分が Rust 自身で実装されており、非常に読みやすかった。VSCode の rust-analyzer を使いたいので手元でビルドしたが、Rust Compiler Development Guide を読めばそこまで苦しまずに環境構築できた。

今後も気になった標準ライブラリの実装には目を通していきたい。

AA(A) をハードした

INFINITAS で十段になってからほぼ2年が経ちました。(もう2年!?)(追記: このブログを公開するころには二年半が経とうとしています)
md19970824.hatenablog.com

弐寺はぼちぼち続けていて、AA(A)をハードしたので一つの節目としてブログを書きます。

サボったり練習したりを繰り返していてあまり地力が上がっている感覚はないのですが、振り返るとクリアできる曲は少しずつ増えていて、成長はしているのかなと思っています。

2022/11/17 : INFINITASの中伝に合格しました

2022/12/01 : 心が折れました

2023/06/18 : お菓子曲に全部易ランプをつけました

2023/06/21 : SCREW // owo // SCREW 易


2023/06/21 : quell ~ the seventh slave ~ 易

2023/06/22 : AA をハードしました

この他、BEAT PRESONER やバドマニなどの 地力A譜面に易ランプをつけました

半年ほど放置しているため、もう一度再開する所存...

大学生活で読んだ専門書

ふと思い立ったので、大学在学中に読んだ本を並べます。(2024/01 追記 : 今頃になって発掘した。下書き程度だけれどせっかくなので公開する。)

あまり授業には行けず、授業資料と講義内容に対応する本で勉強して試験を受けるような人間だったけれど、勉強すればなんとかなる大学だったのが救いでした。東大に行っていたら今頃情報科学は学んでいないと思います。

B1

入学してすぐにスキーサークルに入り、そちらで遊びつつ、単位を回収しながらふらふらと数学をしていた。

入門 Python3

正確には入学前に読んだ。プログラミング人生の始まり。情報学科に入る前に基本的な概念(代入、list, dictionary, class など)をざっと眺めた。一回生の前期に「プログラミング入門」の授業があったのでわからないことはそちらで理解しよう、と言う気持ちで、難しいところは飛ばしながら読んだ。ファイル操作のあたりで詰まったような記憶がある。

解析入門I

調子に乗った一回生が読むことで有名な本。例に漏れず調子に乗っていたので読んだ。微積の講義がとてもわかりやすかったため、そちらで理解を追いつかせながら授業と同じくらいのペースで読みすすめた。本の演習はあまりやらなかったが、授業の演習課題が普通に難しくていい練習になったのを覚えている。

線形代数講義 現代数学への誘い

高校の頃になんとなくマセマの線形代数の本を読んでおり、具体的な計算は経験があったので、もう少し抽象的な取り扱いについて書いてある本として読んだ。あんまり有名じゃないかも。

集合と位相

「自然現象と数学」という名前にもかかわらずガッツリ集合と位相の話をする謎の科目があり、対応する本として読んだ。とても難しく、商位相が出てきたあたりで挫折した。(選択公理Zorn補題、整列可能定理が互いに同値であることの証明も追いきれなかった記憶がある。)位相空間の知識はあまり使っていないけれど、幾何をやると出てきたりするんだろうか。

群論入門

数学ガールを読んでいたら群についての話が出てきて、こういう話題もあるんだなーと思い、あまり前提知識のいらない「応用代数学」の講義を上回履修してさっさと回収することにした。講義に対応する本として読んだ。(上回履修をする理由として、3回生時点の負担を軽くしたいというのがあった。数回休んだら単位が認められない英語リーディングなどの必修が回収できず、その目論見はあまりうまくいかなかった。)本としては具体例が豊富で、証明も行間がほぼなかったので、あまり混乱せずに走りきれた。

現代論理学

人文・社会科目群の論理学の講義の教科書だった。数学が好きなので、論理学のことについて知らないわけには行かないと思い、「論理学I」, 「論理学II」 ともに履修した。きちんと読んだかと言われるとあやしい。

苦しんで覚える C 言語

学んだことのあるプログラミング言語が上に書いたPythonと、「プログラミング入門」の講義でやった Java だけだったので、なにかやろうと思って C言語の本に手を伸ばした。PythonJava もそんなにマニアックなことをやっていなかったので、C もそんなに変わらないなあと思ったのを覚えている。(今思うと全然そんなことはない。)

暗号技術入門

セキュリティの知識は大事らしいと聞き、当時の自分に想像のつく暗号の話を抑えようと思って読んだ。数学ガールと同じ作者さんで、とても丁寧な説明でわかりやすかった。

B2

数学ばかりやっていたが、情報学科くんだりまで来て数学ばかりやっているのでは面白くないと思い(個人の感想です)、計算機科学コースを選んだ。

統計学入門

確率論や統計の話に対応するために読んだ。情報学の人間としてはとてもよい本だと思う。今でも度々参照する。

論理回路

「論理システム」の講義の教科書。論理関数の諸性質について述べたあとに、与えられた論理関数を計算するような論理回路を設計する手法が書かれている。

コンピュータの構成と設計 第5版

パタヘネの略称で有名。「計算機の構成」や「計算機アーキテクチャ」の講義であったり、計算機科学実験でCPUを作成したときにとてもお世話になった。 現代の計算技術は魔法のようだけど、人間が作ったものなんだなあと感じられる。ヘネパタは読んでいない。

計算理論とオートマトン言語理論

「言語・オートマトン」の講義に対応する本。

電気電子回路

「電気電子回路入門」の講義に対応する本。

マスタリング TCP/IP

「コンピュータネットワーク」の講義に対応する本。とりあえずここに書いてある内容を理解していれば、Webシステムなどの通信を伴うソフトウェアを作るときに見通しが良くなると思う。

グラフ理論 基本とアルゴリズム

グラフ理論」の講義の教科書。ぼちぼち競プロをやっていて簡単なグラフアルゴリズムは知っていたので、すらすら読めた。グラフという概念に慣れるのにおすすめの本。

多様体の基礎

幾何も少しはやっておこうということで読んだ。結局それから幾何の知識を使うことはなく、あまり真面目に読まずに写経していたこともあって、多様体の話はすっかり忘れてしまった。

基本情報技術者の本

なにか資格でも取ろうかなと思って読んだ。情報学科の人間としてはもうしっている内容が大半で、応用情報技術者をとればいいかと思ってこちらは受けなかった。

B3

夏頃に競プロを真面目にやり始め、そちらにのめり込んだ。また、型システムを扱う研究室に行きたいなと思って講義とは別に勉強していた。(結局配属に失敗したが...)

プログラミングコンテストチャレンジブック

競プロは一回生のときにKMCを通して知り、時々やってみたりはしていたが、あまり真面目にやっていなかったので茶色あたりで止まっていた。 周りの友人や先輩方がタダで東京に行っているのを見て、自分も行けたら面白そうだなと思ったのがちゃんとやり始めた動機だったと思う。 ネトゲを楽しんでいたつもりが、タダで東京に行けたり、ICPCベトナムに行ったり、インターンに行けたりしてしまった。

はじめてのパターン認識

機械学習の話題についていくために読んだ。

オペレーティングシステムの基礎

OSの講義に対応する本として読んだ。今思うとこの時点でもっと詳細に書かれている本を読んでおけばよかったなあと感じる。

Types and Programming Languages

型システムの本。友人と輪講をした。ある程度読んだところで、自分が配属に失敗してあえなく終了となった。

計算理論の基礎

言語理論や計算理論についての入門書。第三巻でチューリングマシンを導入して、計算可能性や計算複雑性について取り扱う。「アルゴリズム論」の講義に対応する本として読んだ。

応用情報技術者の本

応用技術者を受けるために読んだ。B4の10月頃に取得した。

独習 C++

競プロをC++でやっているわりにC++の本をちゃんと読んだことがなかったので、さっと読んだ。

B4

Introduction to Algorithms

院試のアルゴリズムパートに対策するために読んだ。DPや貪欲法、最短経路など、個々の手法については知っていたが、そういった手法の正当性を証明する方法をちゃんと学んだのはこのときが初めて。(それまでは競プロの解説を頼りにしていた。)

OS自作入門

一度くらいはOSを作ってみようと思って読みつつ実装した。

SQL実践入門

SQL自体は授業でしっていたが、もう少し詳しく知りたくなって読んだ。

M1, 休学中

Combinatorial Optimization

アルゴリズムの専門ということで、ちゃんと読んだ。結局一般マッチングくらいまでしか読めていない。(その後が面白いらしいが...)

Graph Theory

グラフ理論もやろうということで maspy さんが募集していた輪読に参加した。どこかのタイミングで離脱した気がする。

線形代数I (東京大学出版)

なんやかんや線形代数は使うので復習した。

プログラミング言語の基礎概念

プログラム意味論の講義に対応する本。導出が正しいかどうかをチェックしてくれるオンライン演習システムがあって面白かった(たしか講義の評価にも使われている)

ネスペの本

ネットワークスペシャリストを受験するため、一通り勉強した。結局落ちてしまった。(今考えると午後が対策不足すぎた)

試して理解 Linux の仕組み

簡単なコマンドくらいは叩けるけどよく知らない概念(プロセスとか)について知りたいなと思い、読んだ。

Effective Modern C++

ChromiumC++ を使っていたので読んでみた。C++は魔境だなあとわからされた。

実践 Rust プログラミング入門

Rustが流行っているらしいと聞いて一通り読んだ。 所有権の概念自体は C++ で触れた事があったため、こんなものだろうという気持ちで理解することができた。

シェルスクリプト基本リファレンス

検索しながら適当に書いているシェルスクリプトについて理解を含めたいと感じて、通して読んだ。 リファレンスとしてもかなり優秀だと思う。

超高速グラフ列挙アルゴリズム

ZDDについて解説されている本。修論ではZDDを使わなかったが、所属研究室の話題なのでこれくらいは理解しておこうと思って読んだ。

M2

JavaScript 第2版

JSくらいは一通り理解しておこうと思って読んだ。

しっかり学ぶ数理最適化

梅谷先生が書いた数理最適化の本。連続最適化の話題は授業で聞いたことはあったがあまり真面目にやっていなかったため、よい復習になった。

大学生活の振り返り

大学院を卒業する際に振り返ろうとして下書きを書いたまま放置されているブログを発見した。せっかくなので公開する。 当時使っていた iPhone を紛失してしまい、あまり写真が残っていないのがとても悔やまれる...

学部一回生

2016年4月、京都大学工学部情報学科に入学した。自分の学校からは京大へ進学する人が毎年50人程度いるので、何かあっても知り合いはいるだろうとあまり緊張はしていなかった。 それよりも、初めて一人暮らしできることややっと受験勉強から開放されることにワクワクしていた。 情報学科らしく Twitter をやっている人間がとても多く、Twitter 上でコミュニケーションをとることが多かった。(今でもそう)

当時は数学に傾倒していて、かなり真面目に取り組んだ記憶がある。 一方で、スキーサークルに入り、そちらの人間ともよく遊んでいた。 冬になるまではあんまりやることがないから、家が広い人間の家によく集まっていた。B1らしいムーブである。 スキーにはお金がかかるのでサークルの先輩の紹介でアルバイトも始めた。焼肉屋のキッチンの仕事で、週3~4回ほど出勤していた。 夜中まで仕事があるので徐々に朝起きられなくなり、板書がある講義にしか出なくなっていった。(元々人の話をただ聞くのがそんなに得意ではなかった。)

冬になり、サークルの合宿に参加したり、白馬五竜の飯森館という宿で居候生活をしていた。 合宿のある12/23あたりから1/8頃までと、期末試験直後(2/5頃)から3月中旬までずっと滑りっぱなしだった。 6時に起きて9時ごろまで配膳や部屋づくりなどの仕事をして、10時から16時まで滑り、16時半から20時ごろまで仕事をする生活だった。当然車などないから夜行ける店は徒歩20分のコンビニだけという状況だったが、友人や先輩方がたくさんいたのでとても楽しかった。

学部二回生

授業はこなしつつ、サークルのことやアルバイトをやったり、自分が読みたい本を読んでいた。 この年は夏も3, 4週間ほどスキーをやった。ピスラボという、スキー場に敷かれたマットの上を滑るものである。 当然それ専用の板が必要だったし、ブーツも硬いものに新調したので、アルバイトで稼いでいるわりには貧乏生活をしていた。 用事がないときは街にいってもできることがないので部屋に引きこもり、ずっと専門書を読んでいたように思う。

冬は当然のように雪山にこもっていた。夏冬合わせると年100日ほどスキーをしていた。

学部三回生

CPU実験をやったのが記憶に残っている。パタヘネを読みつつ 5段パイプラインを実装した。 この夏に蟻本を読んだりして、競プロを真面目にやり始めた。ある程度テクニックを知ったことですんなり水色まで上がった。 いくつかオンサイトにも行けたりした。東京に行く良い機会となった。

この頃アルバイト先の人間が自動麻雀卓を購入したため、0時ごろにまかないを食べ終わった後、その人の家に入り浸って朝までひたすら麻雀をやっていた。

冬になり、さあスキーをやるぞと思っていたのだが、最初の合宿の2日目か3日目に、コケた拍子に開放したスキー板で膝を切る大怪我をしてしまった。 この冬はサークルを引退する年でもあり気合が入っていたのだが、復帰することが出来ないまま引退となってしまった。

学部四回生

型システムやプログラミング言語の研究をする研究室に入りたいと思っていたのだが、起床が苦手なこともあり成績がよいほうではなかったので、あえなく敗退した。 院試で入りたい研究室に入るぞということで、5月ごろからひたすら対策をしていた。友人と集まって過去問を解いたりしているうちに、大抵の問題は解けるようになった。 院試は無事第一志望の研究室に入れたが、開示が8割程度だったにもかかわらずボーダーだったようで、怖いなあと思ったりした。

夏はF社 でインターンをした。会社が一ヶ月ほど東京のマンスリーマンションを借りてくれて、そこから通勤していた。(まだリモートの概念はあまりない時代である。)

12月ごろにベトナムで開催された ICPCアジア大会に飛び込みで参加した。(日本のアジア大会と違って 国内予選がないため) ちゃんと海外旅行をするのは初めてで、この直後にCOVID-19でなかなか海外へ行けなくなってしまったこともふまえるととてもよい経験になった。

春休みの間にR社でインターンをした。夏と同じように東京のマンスリーマンションからの通勤で、3月の間一ヶ月ほどの期間だったが、ちょうどこのころ COVID-19 が流行し始めた。(ダイヤモンドプリンセス号が2月) もう一度ちゃんとスキーをやろうと思いスキー板のチームに入って何度か合宿にも参加していたのだが、COVID-19 のため大会はなくなってしまった。

修士一回生(前半)

京都大学情報学研究科に入学した。 アルゴリズム分野の研究室で、競プロの気持ちになりつつ論文を読み漁った。

最後のICPCということで結構真剣に練習した。 結果は22位で敗退だった。(10位以内に入らなければ通過することはできなかった...)

休学

コロナで人と喋る機会もないし、あまり研究も進まないように感じたので、モラトリアムを延長した。

機会に恵まれ、G社でインターンシップをさせて頂いた。運悪くコロナの真っ只中でオフィスにお邪魔することは叶わなかった。人生で一度くらいはあの食堂に行ってみたかった...

修士一回生(後半)

単位を集めたり研究を進めたりしつつ、就活を進めた。

D進もいいなあと思ってはいたが、このときは特に考えていなかった。

修士二回生

よく喋っていた友人たちがほとんど東京に行ってしまって困った。学科の後輩やサークルの友人とよくつるんでいたように思う。 京大のいいところは大体の友人が自転車で集まれる範囲に住んでいて、今日飯を食いに行こうと行けばすぐに行けたことなのだが、そういう機会はなくなってしまった。

金銭的な支援を獲得できたらD進しようと思ったがあえなく失敗。 選考を待って頂いていたR社に就職した。

振り返り

あんまり多くのことは出来なかったなと思いつつ、書き出してみると7年でたくさんの経験をしたなあと感じる。 ぼちぼちやりたいことをやりつつ生きていきたい。

弐寺のSP十段になった

今年の2月頃から beatmania iidx を始めて、本日十段になりました。
中伝まではかなり時間がかかると思われるため、今までの振り返りを文章にして残そうと思います。

なぜ始めた?

社築という VTuber が音楽をフルコンする動画を見たのがきっかけです。

www.youtube.com

彼の歓喜の叫びを聞いて、一機種くらい真剣に音ゲーをやってみようかなという気持ちになりました。 音ゲー経験は太鼓の達人PSPでやっていた程度で、縦向きにノーツが降ってくるタイプの音ゲーをしっかりやるのはこれが初めてです。

六段まで

始めるにあたって、迷わず INFINITAS に登録して PS2 専コンをメルカリで買いました。
アーケードではなく INFINITAS をメインにしたのは、 お金と時間の面でメリットが大きいと考えたからです。 (実際にかかったお金と、プレー曲数 * 100 / 3 で比較すると、今のところ10万円ほど得しています)

最初の数十曲は鍵盤と画面の対応に慣れるためにLv1 ~ 3をひたすらやりました。 紆余曲折はありながらも楽しみながら進めて、六段に受かるころにはLv9くらいまではそこそこできるようになっていたと思います。

七段

  • V (H)
  • mosaic (H)
  • Anisakis -somatic mutation type"Forza"- (H)
  • THE SAFARI (H)

時間がかかることを覚悟していましたが、意外と一ヶ月程度ですんなり抜けました。
V の後半と THE SAFARI のテレテレテッテだけは譜面をある程度覚えて餡蜜で処理しました。

八段

  • AA (H)
  • 灼熱Beach Side Bunny (H)
  • moon_child (H)
  • gigadelic (H)

AA の乱をたくさんやった記憶があります。 灼熱の皿をある程度覚えてeasy ランプがつくようになったあたりで受けたら通りました。

この頃には解放済みのLv10 がだいたいクリアできるようになっていました。

ここからしばらく伸び悩みます。
Lv11 に入ると一気に密度が上がりますが、難しい譜面になると認識ができても全然うまく拾えません。

自分の場合はPS2コントローラを使っているのが原因でした。 改造済みでボタンハマりや皿と鍵盤の距離といった問題はないのですが、 やはり十年以上前のコントローラということもあって反応が悪いです。 どれくらい反応が悪いかというと、薬指で7鍵を押してもほぼ反応しないため4567鍵を人親薬小で取っていました。 鍵盤も重いため、密度が上がると全然対応できない状況が続いていました。

高難易度ができない分しばらくの間はLv8までのエクハ埋めやLv9~10のハード埋めをして遊んでいました。 また、ふらっとゲーセンにいってSP九段に撃沈したりDP初段を取ったりしていました。 (この間に右手を普通の 1048 式に矯正しました。)

エクハ埋めにも詰まり始めた頃、 まとまったお金が入る機会があったため意を決して PHOENIX WAN を購入しました。

九段

  • Xepher (A)
  • Spica (A)
  • 旅人リラン (A)
  • moon_child (A)

PHOENIX WAN を導入した次の日、無事九段に受かりました。

十段

九段に受かった二日後(!?)、なんと十段に受かりました。 コントローラーの不調に悩まされている間にいつの間にか地力が上がっていたようです。

練習するときに意識したこと

(こういう話、かなり難しめだったり記事自体が古くて困った記憶があるんだけど、十段を取る頃には最初何に詰まっていたか忘れている...)

  • 曲を楽しむ
    一番大事です。

  • 乱、同時押し、皿複合、連皿をまんべんなく練習する
    自分が上手くプレーできる曲に偏りすぎずに選曲することを意識しました。(ランダム選曲も多用しました)

  • ノーツがどの拍で降ってきているかをしっかり認識する
    ゲージの仕様を考えるとクリアするためにもスコアは必要です。(例えばHARD ゲージの場合、判定がGOODだとゲージが回復しません) ならスコア練をしよう!と考えてもよいのですが、クリアできるかどうかの曲をクリアすることとスコアを上げることを両立するのはなかなか難しいと思います。 自分はもう少しハードルを下げて、難しめの譜面が降ってきても雑に餡蜜せずに4分、8分、16分などの拍に合わせて押すくらいの意識でやっていました。 これは曲を楽しむのにも役立つと思っています。

これから

引き続き中伝を目指します
まずは AA(A) をクリアしたい

(2023/02/08 追記) INFINITAS で中伝になりました。たしか去年の秋頃? 修論をはさんでしばらくやっていなかったため地力も落ちてしまいましたが、少しずつ練習していこうと思います。 アケの中伝がとれるのはまだまだ先になりそうです。(p†p と天空、どっちも抜けれる気がしない!)

Google でインターンシップしてきます

COVID-19 のほとぼりが冷めるまで一年くらい休学して、好きなように勉強やバイトをしながら過ごすつもりだったのですが、運良く拾って頂きました。

応募

B4 と M1 のときも応募していましたが、落ちたり COVID-19 の影響で選考が打ち切られたりしていました。 また、受かっても出来ることがないかもなーと思って今年は応募自体をやめておくつもりでした。

ところが、ふらっとでた Google Kick Start の結果を見て、今までの選考でもお世話になったリクルーターさんから4月上旬に連絡を頂き、それならばと応募することにしました。

競技プログラミングが就活の役に立ちました。

選考

面接

日本語と英語でコーディング面接をしました。 英語やべーーーと思ってたんですが、リスニングを頑張っていたおかげか意外と喋れました。 (むしろ日本語の面接でかなり失敗した。なんで?)

特別になにか対策したかというとそんなにしてなくて、 LeetCode はあんまりやってないし Pramp とかの面接練習もやりませんでした。 競技プログラミングは好きなので、たくさんやっていました。

解いた問題数

Cracking the Coding Interview は1, 2年前に最初のほうをしっかり読んだのと、問題パートもぱっと見てわからなさそうなものはちゃんと考えた記憶があります。 本を見る限り、問題自体は AtCodercodeforces の黄色くらいであればそんなに難しくないものが多いと思います。

いろんな人のブログを読んだりして、コミュニケーションが大事なんだな~と感じたので

  • 制約や入力形式をちゃんと確認する
  • 簡単な解法を最初に言う(これ本当に大事です)
  • 困ったらどういうふうに困ってるか口に出す

あたりを意識しました。

また、当たり前かもしれませんが、プログラムはきれいに書いたほうが印象がよいと思います。 自分はC++を使っていて、

  • 2, 3秒立ち止まって変数名を考える
  • 参照渡しはconstならconstとつける
  • グローバルにむやみに変数を置かない
  • std::を省略するなら一言言う

などを意識しました。

Hiring Committee

面接の結果を元に本社の方で判断されるらしいので、待ちます。
一週間ぐらいで通過しましたと連絡を頂きました。

Host Matching

受け入れ先を見つけるパートです。 フォームに記入して待ちます。
ホストとマッチしない可能性が普通にあるので、GWがとても長かったです。 5月下旬にマッチしましたと連絡を頂きました。

他にやったこと

インターンでどんなことがしたいかはある程度想像していました。

細かいタスクまではわからなくても、

careers.google.com

こういうページを読むと東京オフィスにどんなチームがあって、何ができそうか、なんとなく想像がつくと思います。(これ自体はもしかしたら古い情報かもしれません)

自分はブラウザの中で何が起きているかよくわからずに使っているので、 Chrome ブラウザの開発に携われたら理解が深まって楽しそうだな、などと考えていました。

インターンでやること

公開できる内容になりそうなので、終わったらブログに書こうと思っています。

おわりに

競プロもCSも楽しいので、みんなやりましょう~

もしかしたら就活の役に立つかもしれません。

AtCoder黄色になりました。

今日は12月13日。クリスマスまであと12日ですね!
この記事は、「色変記事Advent Calendar Advent Calendar 2020」の13日目になります。

adventar.org

結果

見事達成です。

f:id:mdyh2a380824:20210115170935p:plain
達成おめでとう

感想

もちろん嬉しいのですが、それよりも3月中には黄色くなっていなければならなかったという気持ちのほうが強いです。結果的にそこから1年弱費やしてしまいました。 AOJ-ICPCをがんばっている間あまり算数をやらなかったことが、AtCoderのレートが伸びなかった一つの原因かもしれません。
精進量はこんな感じ。

f:id:mdyh2a380824:20210115170539p:plain
2730問

今後

コンテストに出ることは続けるつもりですが、精進よりも専門書や論文を読むほうに注力したいと思います。 (あとネスペ)