2025年1月振り返り 卒業論文タイムアタック/沖縄/音楽活動

2024年12月に卒業論文の息抜きに2025年の感想を先に書いておこうという企画を実施したのですが、それの1月分の答え合わせをしていこうと思います。

先行振り返り

1月

年末年始を沖縄は石垣島で迎えつつ、卒業論文をなんとかギリギリで書き終えたのが一番の偉業だと思います。テーマが本当になかなか決まらず、他のラボメンに2~3ヶ月遅れて開始した卒論ですが、気合いと教授やラボメンの協力により期日までになんとか仕上げることができ、無事3月に卒業することができました。これでストレートで大学卒業まで来たことになります。色々ありましたけど、ストレートで卒業出来たことにかなり安心を覚えます。学費や進路のことを考えるとなるべく留年したくなかったですし。

また、音楽のほうもなかなか充実してました。サークルの先輩のバンドのライブにサポートで入って出演したり、初めて bol4 のライブに行ったり、元々カッコイイなと思っていたバンドの人と一緒にセッションしたりできました。

インターンも変わらず継続していました。インターンでは予定外のことはあったものの概ね順調に進んだのではないかと思います。

振り返り

答え合わせ

年末年始を沖縄は石垣島で迎えつつ

なんと小学4年生の1月に日本に帰国するときの上海旅行以来12年ぶりの家族旅行を親がいきなり提案したので12月末から家族で沖縄は石垣島に滞在していました。この先行振り返りは石垣島で書いていたのでここは規定路線なので、当然正解です。

卒業論文をなんとかギリギリで書き終えたのが一番の偉業だと思います。

これも当たっています。卒業論文、前日に書き終えました。とはいえ自分の普段のレポートの書きようから言うと思っていたよりはギリギリではなくて、推敲を重ねる余裕がありました。まあでも結局前日までは全然完成していなくて前日にラボに籠って同期のK川くんとずっとお笑いを語りながら書き上げたという感じなので、ギリギリと言って良いでしょう。本当に偉業でした。他の人が早くて7月、遅くても10月とかにテーマが決まってたんですが自分だけ12月まで決まらずに、12月3日の研究室内の講評会で出せるものがなく、他の人の発表を横目に先輩と話しててようやく思いついたアイデアがテーマになりました。他の人はもう作品が出来ててあとちょっと実験したりして論文書いたら終わりってところだったのに、ようやくテーマが決まって、そこから具体的に何作るか決めて作って実験するなどして論文書くのを全部やらなきゃいけないわけですよ。結構ギリギリな状態だったんですが、それでもそれまでのテーマがいつまで経っても決まらない7ヶ月に比べるともう天国みたいな気分でした。たむらかえさんのケーキの話で言うと、周りがもうケーキのレシピが決まって材料も揃っててあともう作るだけ(=論文書くだけ)みたいな状態なのに、ようやくケーキのコンセプトが決まったみたいな感じです。でももうコンセプト決まったら、あとはやるだけじゃないですか。研究室に行ったら明らかに明るいって言われるし、もうとにかくなんとかして終わらせるぞって気持ちでした。年内の最終ミーティングで教授に年越し沖縄に居ることを伝えたら苦笑いされましたけど。結局爆速で試作して、作るものを決めて、爆速で作って、物が全部完成したのが1/6かな?卒論提出日が1/24だったのでまあギリギリもギリギリです。うちの学科は研究説明書という2ページのアブストみたいなやつの提出が定められていて、弊ラボではこれを先に完成させることで卒業論文を楽に完成させようという方針でやってます。私はこれを結構磨きあげて、他の人が第9稿とかまで行ってるなか第3稿が最終版になるくらい完成度高くもっていきました。これが功を奏してだいぶ卒論本体が進めやすくなり、毎週のように徹夜して早朝にラボに行きラボで仮眠を取ってミーティングという生活をしながら想定より早く進めることができました。1月3週目くらいからTwitterのユーザーネームに卒論の文字数を入れていたのですが、1/17にはTwitterの作業スペースで1日7000字くらい書いてツイッターのユザネの数字が爆増し、突然終わりが見えてきました。最終的に同期を数人追い越して卒論を終わらせ、無事提出することができました。皆さんありがとうございます。 卒論終わってからしばらくは何したら良いかわからなくて、とりあえず1日休もうと美容院に行きました。最後に切ったのは2024/7/23らしいです。実に半年ぶりの来店、美容師の方にもめちゃくちゃ久しぶりだねと言われました。もう10cmくらいバッサリ切って、髪もブルーブラックに染めてかなり真っ黒に仕上がって大変満足しました。髪質に不満があったんですが、ただ単に伸びた部分が痛んでただけみたいで切ったらかなり調子が良いです。最高!午後は山手線のエキュートでバイトしてる高校の友達を冷やかして帰りました。元々の髪が長すぎたせいで、10cmも切ったのに人に髪を切ったことを気付いてもらえなくて面白かったです。あれだけ毎日のように顔を合わせてたラボメンが最初気付かなかったのでもう誰も気付かないと思います。初めてストレートでヘアセットしてもらったらめっちゃ良かったので、翌日にヘアアイロンを買いました。今季はストレートメインになりそうです。

他のラボメンに2~3ヶ月遅れて開始した卒論ですが、気合いと教授やラボメンの協力により期日までになんとか仕上げることができ、

皆さん本当にありがとうございます。ここでは教授やラボメンと書いてますが、中高やツイッターの友人の方々にもだいぶお世話になりました。

無事3月に卒業することができました。これでストレートで大学卒業まで来たことになります。

1年の振り返りを先行して書いているのでこういうことになっています。実際はもしかしたら履修登録ミスって留年という可能性も万に一くらいはあるので確定はしていないんですが、もうほぼ確定と言える段階ではあります。ストレート大卒も確定として良いんじゃないですかね。

色々ありましたけど、ストレートで卒業出来たことにかなり安心を覚えます。

本当にこう思います。だって実際卒業できるかわかんなかったもん、10月とか11月とか。ラボ内ではみんなの卒業見送り役として自虐をやってました、ご迷惑お掛けしました。早稲田大学は一都三県からの進学だと学費以外は良い大学と言えるんですが、学費だけはもう駄目です。1年留年となると170万円追加で必要になる上に就職活動が水泡に帰す可能性まであるわけですから、本当に回避できて良かった。

学費や進路のことを考えるとなるべく留年したくなかったですし。

というわけなんですよ。これも今でも全く変わってない。

また、音楽のほうもなかなか充実してました。

そうなんですよ、お前卒論テーマギリギリで決めときながら何やってんだって話なんですが、かなり充実していました。

サークルの先輩のバンドのライブにサポートで入って出演したり

1/27(月) TiDE のサポートで Spotify O-nest に出演しました。驚き!あの渋谷のゲートウェイから程近い、いつも人が溜まってるところですよ。あそこは Spotify 系が複数あってその中では多分一番小さい箱なんですが、それでも結構広いし内音も外音も良くてかなりやりやすかったです。メンバーの半分は社会人で、今回は結構直前の出演決定だったのでベースの方が出演できずサポート2人編成だったんですが、新しく人と仲良くなれて良かったです。今回のライブに向けて練習を重ねていたので、1日朝から研究室行って授業受けた後にスタジオ入ったりとかしてました。ライブは個人的な感触としては結構上手く行って、ライブ聴き返したりしてたんですが過去最高レベルで身悶えせず聴いてられる良いライブだったと思います。次も頑張るぞ〜。

初めて bol4 のライブに行ったり

皆さん知ってますか?bol4/赤頬思春期/볼빨간사춘기 というアーティストを。韓国の歌手の方なんですが、これが本当に良くて。大学1年くらいの頃から知ってたんですが、去年かなりハマってずっと聴いてて、そしたら来日するって言うんですよ。石垣島に居るときにライブ情報を認識して、Zepp Diversity Tokyo でちょっと高かったし卒論追い込みの時期だったんで行くか迷ってたんですね。そしたらうちの母親が「ライブなんて迷ったら行けば良い。若いうちに行けるだけ行っとけ」と言い始めたので思い切って取りました。最高でした。ライブって良いですね。もうあの散々聴いた音源の本人が歌ってて、しかも1回めちゃくちゃ近くまで来てくれたんですよ。ほんと最高でした。もう4年くらい韓国語を勉強しているわけですが、韓国人アーティストのライブに来るのはこれが初めてだったんですね。そしたらもうMCの内容がわかるわかる、ビックリしました。こんなに韓国語勉強してきて良かったって思ったことないかもしれません。今韓国語の授業ってどこも自己紹介で推しのアイドルを言うくらいに推しのために韓国語を勉強する人の割合が多くて自分みたいな韓国アイドル全然わからない勢は肩身が狭かったんですが、推しのために韓国語を勉強する人々の気持ちがちょっとわかった気がしました。だって直でわかるんですもの。ライブ会場の人たちも結構わかるみたいで、冗談言ったら通訳さんが話す前にちょっと笑いが起きたりしてました。ああいうの見ると勉強したくなるでしょうね。まだまだ勉強しますよ。 bol4 はそれからもっとハマって、卒論の作業の半分はbol4聴いてたんじゃないかってくらい聴いてました。是非聴いてください。

youtu.be

元々カッコイイなと思っていたバンドの人と一緒にセッションしたりできました

これもやりましたね〜。この日はラボで講評会があって、先輩や後輩の発表を聞いて、お昼は参加者を募ってたら15人以上になってしまったのでちょっとチーム分割しながら元々狙ってた韓国料理屋に行って、その足で会社行って、で19時くらいに上がって渋谷でセッションですよ。なんて充実した1日!元々サークルの後輩に紹介されたカッコイイバンドとしてちょいちょい聴いてたんですけど、なんとたまたまサポートで入ってるバンドのメンバー(サークルの先輩)がそのバンドのメンバーと友達で、みんなでセッションしようよ〜ってことになったんです。楽しかった〜!セッションってやつに久しく行ってなくて、もう忘れちゃったな〜なんて思いながらやってたんですけどめちゃくちゃ楽しかったです。その後皆で渋谷の中華料理食べに行って音楽の話したりして、やっぱいいな〜って思いました。2月は海外に居るので行けないんですけど、3月のために練習重ねますよ。 サークルのキーボードの後輩が来てたんですが、もう上手いのなんのって。悔しいですよ!卒論で全然練習してなかったとはいえ、もう本当に悔しい。頑張ります。

インターンも変わらず継続していました

実はそうなんですよ。12月から内定者アルバイトって形でインターンをやってて、だいたい週20時間働きながら卒論作業をしながら音楽やってました。これで教授にいつもラボに居て偉いって言われるの、無意識のうちに教授評価ハック最高効率でやってるとしか思えない。

インターンは概ね順調に進んだのではないかと思います。

公開情報ではないのでふわふわタイム。自分用のやつにはもうちょっと詳しく書いてあるんですが、かなり当たってましたね。まあでも元々半年インターンしていたところでもあるのですっかり馴染み、楽しく仕事できています。パソコン楽しいですね〜。まだまだ能力足りてないなと思うのでやっていきますよ〜!

追加

お笑いにハマりました。いろんなところでず〜っとお笑いの話してるし、卒論作業中に聴いてたもう半分は真空ジェシカのラジオ父ちゃんです。M-1からお笑いにハマってずっとお笑いにハマってますね。人を笑わせるのってカッコいい!

以上、2025年1月振り返りでした!また来月〜。

2025年の抱負

曇天の石垣島からこんにちは、@takabayap です。2025年、抱負の表明兼進路報告です。

卒業する

大学を卒業します。卒業論文は実質執筆中なのですが、提出日が1/24なのでそこまでにはなんとしても完成させ、ストレートで学士を取得してやります。絶対にやります。卒業できないと今後の進路に影響が生じたり、学費が追加で170万円かかったりしてなにかと面倒です。絶対卒業します、見ててください。

両立する

さて進路についての話です。2025年3月に学部を卒業した後、4月からフルタイムで正社員としてソフトウェアエンジニアをやりながら、現在の研究室に継続して在籍し修士号の取得を目指すいわゆる社会人大学院生をやっていく予定です。なかなか珍しい進路だと思います。これが実現可能な研究室と職場両方が必要になってきますし、好き好んでこんな苦労をする人もまあいないですからね。片手落ちになることなく、両方を十分にやっていくというのが今年の大きな目標です。

ドカドカ仕事する

就職します。就職するので、ドカドカ仕事していきたいと思います。インターン・内定者アルバイトから継続で働くので一般的な新入社員よりはギャップが少ないと思うんですが、それでも正社員とアルバイトでは権限や責任に大きな差があるので、やっぱガリガリコード読んで書いて自分がどんどん良くしていくぞ!くらいのフレッシュな気持ちでやっていきたいと思います。まだまだやれることは沢山ありますから、遠慮せずどんどんやっていきますよ。

テーマを決める

修論のテーマを決めたいです。卒業論文では合計8ヶ月くらいテーマが決まらず提出期限ギリギリを走り続けているので、修論ではこの反省を活かしなるべく早めに納得できるテーマを決めたいです。そのためにはやはりインプットや普段の思考が大事になってきます。頭を柔らかく保ちながらインプットするっていうのはなかなか難しい部分がありますが、やっていくしかないのでやっていきましょう。外出が億劫になりがちですが、美術展にも積極的に足を運びます。

音楽を続ける

大学では2年時からどこかしらのサークルに所属してずっと楽器をやっていたのですが、そういう機会がないとなかなか楽器の練習が続かないようになってしまいました。忙しいとサボりがちなんですが、やっぱりコツコツやって上手になって色々できるようになりたいので、音楽をまずは続けることを抱負としていきたいと思います。あとはオリジナルバンドをやりたいという話をずっとしているけど、ついぞ曲が完成したことがないのでそれもやっていきたいですね。

語学を続ける

辞めなければ上達します。韓国語と中国語、少なくても日常的に触れることを意識していきたいですね。英語もコツコツ上達していきます。資格試験もどれか挑戦できたら良いな。

やってみる

これはずっと言ってるけど、何かに誘われたりとかしたときに迷ったらとりあえずやってみるっていうのを今年も大事にしていきたいと思います。毎年これで予定がパンパンになって苦労しているので程度は見極めたいんですが、それでも色々見境なくやってきた結果今があるしそれが楽しいので、上手に見極められる気はしませんね。倒れない程度にやっていきます。

今年もよろしくお願いします。面白そうなイベントなどありましたら是非お声掛けください。@takabayap でした。

2023年 振り返り

2024年、始まりましたね。始まってしまいましたが、熱を出していて2023年内に振り返りが終わらなかったので2024年頭に2023年振り返りをやっていきます。

今年なにやったか

色々やりましたね、色々やりすぎて1年間とは信じられないくらい。振り返っていきましょう。

アプリ

アプリ出しました、詳しくはこちら:

takabayap.hateblo.jp

一人でバックエンドからアプリまで書いて、ユーザーは今6000人超えてます。みんなありがとう!

このアプリは去年の9月から本格的に作り始めて、リリースの3月10日までひたすら作り続けていました。4万行くらい書いてるみたいです。はじめてまともなサービス作ったので最後まで本当にできるかどうかわからなかったし、不安が大きい部分もかなりあったのでうまくできてよかったです。経験としてもめちゃくちゃ大きくて、これでかなり技術力も伸びたし就活の面接では最強のエピソードなので擦り続けています。

バイト

今年の前半はバイト色々やってました。夏休み過ぎてからはインターンメインになったのでやめてしまいましたが。母校のチューターのバイトは中高生相手にすっかり触らなくなってしまった数学を頑張って教えたりとか、たまに英語の話したりしていてやっぱり人になにかを教えるのって難しいけど良い営みだな〜って思うなどしました。同じように大学で情報系の質問対応のバイトをやっていたんですが、こっちは人が全然来ないし得意分野なので楽でしたね。

 

時系列順に1年間見ていったやつです。

1月

年末は課題のために映画を見ていた

NARUTO読んでた

1月はちょうど作ってたアプリのアプリ側に手をつけはじめた時期で、年末年始もずっとコード書いてたような気がする

成人式があったけど面倒だったので行かなくて、中高の同窓会だけ行った

がんばってるね

1/14は3サークルくらい合同のフュージョン合同ライブというのが調布であり、ありえんくらい上手い人達に囲まれながら音楽をやっていました

これは高校の同級生たちと初詣に行ったときのやつ こいつらとなんだかんだまだ仲良くやってるので、良いなという気持ち

もうこの気持ちはだいぶ忘れているので、反省しています 喉元すぎればあつさを忘れる

品川水族館に行ってるね これは初詣したメンバーのうちの数人といったやつ

SFプロトタイピングの講義を聞けるやつに行った 今はSFプロトタイピングなんて名前までつけてなんでもかんでも"実学"にもってこうとすんじゃないよっていう気持のほうが強いですが、どんな形でもSFへの入口が増えるならそれはそれで嬉しいかもという複雑な気持ちでいます

受講者はSFぜんぜん知らない人ばっかりで、こういう人がSFプロトタイピングって言葉に踊らされる人びとなんだなあと思いました

これはかわってないです(後述)

1月はレポートにけっこう追われてたっぽい

 

1月はアプリやる、ライブやる、レポートでおわりだね まだ必修の授業のこってたからいろいろあったね

 

2月

ラーゲリみてる

これは映画の授業のレポート用で、教授が珍しく良い映画だっていってたから見に行った 良かったよ 今はサブスクでも見れるから見てみてね

二宮さんって戦争映画の日本兵が似合う気がするね 硫黄島も見たけど全然違和感ない

今でもこれ使ってるけど、本当買って良かった 奮発したね

進路選択、今のところは成功したと思っていますよ

これ、結局このあの Blackmagic の学生向けライセンス無料配布でライセンス頂いたので本当に適切な選択でした 

これこの時期にやってたんだっけ?記憶ないな

これね アプリつくりおわってあとやるだけとおもったら大間違いよ

くしゃみするふくろう

サポーターズでただ焼き肉!結局ずっとお世話になってますね

おもしろすぎ

森美にもいったね すごいボリュームでかなりおもしろかった

告知が出てて、いよいよ後戻りできない様子

これはサークルのイベントで原宿のスイパラ貸し切ったとき よかったね

3月

これわかる〜 バグとプライドファイトって我ながら上手いこと言うな

出せました、よかったね

東方三社巡りをしました よかったね

TOEFLうけてきました

Go + Flutter でモバイルアプリを開発しリリースした話 - 天才性の証明

ブログ書いたよ 読んでね

実はこのときにインターンの話を聞いて結構モチベ上がった結果今があるので、大変感謝しています

実はこの時期はサークルの新歓真っ只中で、4個くらい掛け持ちしていたので大変でしたね 

3月29日から高山に行ってるので、練習して合わせてライブ行ってついでにアプリのアプデして終わってすぐ旅行 みたいなスケジュールでしたね なんだかずっと忙しいな

4月

旅行から帰って次の日に渋谷でライブして、しかもそれが初合わせだったの思いだした ほんまごめん でも上手くできたからよかったよ

これ今でも思う、ほんま難しいもんな

これも今でも思うねんけど、どこいってもコード書くのとかアウトプットが速いっていわれるのでそんなことないんじゃないかという方向に認知を修正しようとしているよ

今年は1年を通して山崎亜希子先生の授業を取っていたんですが、これが面白いのなんのって おかげで留学まで行っちゃいましたよ(後述)

そういえば個人事業主になんったんですよ

他にはバンドのサークルで4個くらい掛けたり(まだ新歓続いてたからね)、toconoma のライブにいったりしました たのしかったね

5月

OSSコミッターになりました

これ今でも思うな 質問に答えるのってマジで超高難度なんですよ

この時期は業務委託で働いたりとかとにかく金がなかったのでバイトのシフト入れまくったりとかしていて、それにサークルも合わさってかなり忙しくしていました

6月

美術館にも行ってて良いね

この頃に8月の韓国留学に行くことを決めたんですが、パスポートを引き伸ばしまくってたらギリギリになって岐阜の市役所に電話する羽目になりました 結局なんとかなったけど、みんなパスポートはそもそも切らさないようにしようね

この頃には色々受けていて、行ったところだと Knowledgework とか サイボウズ、あとWantedly とかもこの時期でしたね。

基本的に大きいアカウントでインターンの選考状況とか言うのちょっとな〜とおもっていたので言ってなかったんですが、この日は立て続けに合格の連絡を頂いて、Cybozu さんから連絡頂いてすぐあとに Wantedly さんから (しかも当日!) 合格のお知らせを頂いたので超喜んでツイートしてしまいました。これで夏休みの留学以外の5週間が全て埋まって、それ以外の会社全部お断わりしましたね。アプリ作ってる期間はバイト全然やってなくてこのアプリの開発を金にしてやるという心持ちでやっていたんですが、当然ながらアプリ開発を一人でやってユーザーが5000人いるなんてのはどこで話してもめちゃうちゃウケがいいので超高効率で換金できました。金欠脱出の見込みも立ち、ついに業務のコードが見れるぞ!とワクワクしていました。それまで全部独学だったので。

これ今でも思ってます、連絡お待ちしています。

なんとかなりました、良かったね。

今でもこれ思ってる、来年情報の授業いっぱいとろうかな

そうだね

ナレッジワークさんでインターンしました、マジで世の中すげえ人が居るんだなと何の質問しても返事返ってくることで実感しました

ブログも書きました みてね 

takabayap.hateblo.jp

実際には年の後半はめちゃくちゃインターンに時間使うことになります。だって楽しいもん

思想強くてビックリしちゃった これからどういうふうに人生生きていくのか注目です

ついに金欠を脱出するツイート 口座に1万しか無い時もありましたね

7月

箱根に行ったらいろんなものが悪天候で止まってて全然だめでした

この頃は大学の授業の一環でロボット作るやつをやってた

 

本当は OpenCV で位置推定とかやって自立走行させたかったんだけど時間が足らずに事前にプログラムしたルートしか走れなくなっちゃった でも学びは多かったので良しとしようか

この頃は家で感染症が大流行していて、濃厚接触者になる前に祖父母宅に逃げ込んでいたので動画は祖父母宅で撮られたものですね 懐かしい

Flexispot は最高なので皆買おう!この頃から引っ越す話が出ていたので、新居で使う用にサマーセールで購入しました

お前はいつもそう

音楽仲間とボルダリングした後にご飯食べにいった これで銭湯行けたら最高だなという会話をした覚えがあるので、それもやっていきたいね

PC新調した!これも良かったな〜

荷造りギリギリ芸人

8月

韓国へ!これは長くなるから別セクションでやる

韓国から面談してた図

帰国しました

これ伏線です、一昨日年金払いました

韓国に居る間にGPUを買ったので、返ってすぐ組み込んでました めっちゃいいね

休みになるとすぐ熱だす 今日も熱だしてたからね

9月

ほんまにそう でも結果やってよかったと思う

9月

これは飯田橋の水上カフェで演奏したとき インターンフルタイムでやりながらこれやってるの凄いけど、正直過去に戻ってもっと練習して挑みたいね

まじでこれな、いつかえればいい?

Cybozu さんにお邪魔しました 超おもしろかった

書け

これ今年やってよかったことの一つ、ぶっこわして良い環境で作業するほうが安心だからね

今年の BIG EVENT の1つ、9月に引っ越しました!弟と2人暮らし

理工とは思えない時間割で後期はやっていきました

この気持ち、忘れないでやっていきたい

そうだね

 

基本的に9月は平日インターンして、休日に母校の文化祭いったり引っ越したりしてたら終わってたね 総合して夏休みは全然休めてない

あとこの時期に11月からのインターンの合格頂いて、めちゃくちゃ2社で迷ったんだけど決めた先のところで今も楽しくやっています これが決まったので7月までやっていたバイトを全部辞めてきた

 

10月

美容院にいってぶち上がるなどした

 

あと箱根いった!晴れてたらめっちゃいい場所

今でもそう思う 謙虚さを褒められることけっこうあるけど、この状態で自信もってできます!って言うことなんて出来ないでしょ っておもう

この時期は Young Sheldon をずっと見てた 韓国ではナビレラを見ていて、そのあとも色々韓国ドラマを見てたけど英語に行った形

めちゃくちゃ奮発して高い椅子を買った 後悔してないですよ

なんかおもしろいこといってんね

そうだね

11月

インターン先です!今もここにいます 最高です

この時期は週20時間くらい働き、サークルの引退ライブに出て、美術館や展示にも行き、本選考の面接が始まりと結構忙しくやってました そのせいかツイートが少ない

12月

働いたり、TOEICうけたりライブしたり韓国語勉強したりしてました
一昨日休みに入れたと思ったら即日熱を出したので、全然連絡返せてないです。年始に返します。これ書いてる間にぶり返してきた……

Arch Linux で fcitx5 の skk が突然SKK(Not available)表記になり動かなくなった

解決方法

yay -S libskk-git として libskklibskk-git で置き換えれば、最新の修正が反映されて正常に動作するようになる。

何が起きたか

システムアップグレードをしたらSKK入力が出来なくなった。画面のように入力方式の選択は可能だが実際は動作しておらず英数字のみの入力が出来る状態。

トラブルシュート

まず fcitx5コマンドラインから走らせてみると skk のアドオンのロードに失敗している様子が伺える。パッケージ fcitx5-skk を再インストールしてみるなどするも効果なし。

どうしたものかと思っていたら skk コマンドというのを発見。libskk 由来で、内部ではこれを叩いて利用してるっぽい。こちらを走らせてみるとパースエラーが出現。

/usr/share/libskk/rules/default/rom-kana/default.json になにやらパース出来ない行があるらしい。110行目にエラーがあるというので覗いてみたところ "n\'": ["", "ん" ], という行が怪しく、この変換ルールを利用したことがないので削除しても問題ないだろうと思いこの行を削除したら動作した。

このままでも動作するのでこれで放置でも良いのだけど、ちょっとモヤモヤするので追加で見ていく。 どうもこれは libskk に問題がありそうだと GitHub の issue を見に行ったら、先週クローズした issue を発見。

github.com

これに対する対応がちょうど10日前にマージされている。

github.com

感謝!ただこちらは Arch Linuxlibskk パッケージにはまだ反映されてないようで、代わりに libskk-git を利用すると解決できるというコメントを発見。

github.com

本家のパッケージに反映されていない修正を利用したいときに *-git をAURから利用するのって確かにあるあるだよね〜

yay -S libskk-git とするとインストール中に以下のように libskk を置き換えるかどうか聞かれるので、これに y と返答すれば無事 libskk-git が利用されるようになり、元の default.json でも問題なく動作するようになった。

https://github.com/ueno/libskk/issues/89

解決。

快適な開発環境の構築のためにQEMUのVMをLAN内に置いたり、DNSサーバーを建てたりリバースプロキシを構築したり

やったこと

  • PPPoEに切り替える
  • バーチャルブリッジ作って全部そこにつなげる
  • 独自ドメイン買ってラズパイでDDNSする
  • ポート開放(いつもの)
  • 内部用のDNSサーバーをdnsmasqで建ててローカルでもドメイン名でアクセスできるようにする
  • リバースプロキシをnginxで作ることによって複数のドメイン(サブドメイン)を同一IP上でホストする

開発環境について

今まではローカルにいちいち開発環境を構築していたが、マシンごとに環境が違っていたりせっかく性能の良いマシンが家にあるのにノートのスペックが足りず満足行かなかったりした。企業のサマーインターンに伺った際に vscodessh を繋いでそのマシンの中で開発ができることを知り、まずはそれを自宅のマシンで実現するために ssh 接続を便利にできるようにした。さらに適当に使っても良い開発環境を用意するために、元々用意してあったQEMUVMをネットワークブリッジを作成することでLAN内からアクセス可能にし、Raspberry Pi 4B を踏み台として外部から接続できるようにした。

やったこと

PPPoE に切り替える

最近引っ越したばかりなのだが、新居では IPoE で接続していたのでポート開放ができなかった(設定画面上でできているように見えても接続できなかった)。これを解消するためにPPPoE接続に切り替えることが必要だった。レイテンシや速度を多少犠牲とするようだが、元々大した数値じゃなったから実用上問題は無かった。今時わざわざログインIDやらパスワードやら入力してPPPoEで接続するよりIPoEで回線認証したほうが楽なのでPPPoEユーザーはあんまりいないのかもしれない。

バーチャルネットワークブリッジを作成し、VMのネットワークインターフェースを変更

QEMUエミュレータを作成した際はデフォルトで作られていた virbr0 というネットワークブリッジを指定していたけれど、これだとVMのホスト以外からアクセスすることができない。どうもVMのホストのネットワークの中にある扱いになるようなので。なので新たに br0 というブリッジを作成した上でこちらを外にも繋げてしまうことでルーターから直でローカルIPアドレスが振られるようになって、LAN内の他のデバイスからもアクセスできるようになった。原理については正直よくわかっていない。 実現方法は様々あるようだが、セットアップの際に systemd-networkd で全ての設定を済ませているので今回もそこをいじることにした。 元々は 50-wired.network で enp4s0 インターフェース(有線LAN)を下記のように設定していた

[Match]
Name=enp4s0

[Network]
DHCP=yes

(/etc/systemd/network/50-wired.network)

これを

[Match]
Name=enp4s0

[Network]
Bridge=br0

(/etc/systemd/network/50-wired.network) (enp4s0 の部分は使っているネットワークインターフェース名 ip a とかで見れる)

というように変更する。ブリッジは

[NetDev]
Name=br0
Kind=bridge

(/etc/systmed/network/bridge0.netdev)

で設定。最後に

[Match]
Name=br0

[Network]
DHCP=yes

(/etc/systemd/network/bridge0.network)

というように設定すると br0 に DHCPサーバーからIPアドレスが降ってくるようになる(んだと思う)。これでルーターのデバイス一覧からもVMが確認できるようになり、もちろん他のマシンからもアクセスできるようになる。sudo virsh edit からインターフェースを変更するとVMのインターフェースを切り替えられる。MACアドレスを設定している行とかよくわからんの色々あるけど、ああいうの設定ファイルに書いてなくても自動で生成して付け足してくれるから気にする必要なし。

WakeOnLan の設定

現在持ってるマシンはこんな感じ。

  • Raspberry Pi 4B RAM 8GB
  • メイン機
    • CPU: Ryzen9 3900X (12C24T)
    • RAM: DDR4-3200 32GBx2
    • GPU: NVIDIA RTX3080 8GB
  • サブ機(元メイン機) 今回の話には関係ないけど
    • CPU: Ryzen5 2600
    • RAM: DDR4-2666 16GB
    • GPU: NVIDIA GTX1660ti
  • ノート
    • CPU: Ryzen7 5700U
    • RAM: 16GB
    • GPU: 内蔵のやつ

メイン機はメモリをガン積みしCPUも良い感じなので基本的に性能面で文句はない。ノートPCも普段使いには全く問題ないのだが、開発のためにVMやモバイルエミュレータを立ち上げたりし始めるとメモリがだいぶ厳しくなってしまい快適とはあまり言えなくなってしまうこともある。自宅のメイン機に接続して開発したくなってくるわけだけど、起動しっぱなしにするには電気代や部品の耐久性という点で少々不安が残る(Mini-ITXなのでなおさら)。そこで今回は Raspberry Pi を常時起動のサーバーとして、使いたくなったときはそこから WakeOnLan でマシンを起こしてあげるという方法を取ることにした。 メイン機は Arch Linux で動いているので、比較的簡単に WakeOnLan を設定できる。wol-systemd という AURパッケージを用いることでとても簡単に実現できる。BIOSの設定でWoLを有効にした上で

yay -S wol-systemd
sudo systemctl enable wol@enp4s0
sudo systemctl start wol@enp4s0

(enp4s0 の部分は使っているネットワークインターフェース名)

というようにすることでWoLの設定を永続的にすることができる。この上でRaspi上から

sudo apt install wakeonlan
wakeonlan {メイン機MACアドレス}

とするとラズパイからメイン機が起動できるようになる。ラズパイの消費電力は大したことないので、これでだいぶ電気代を節約できる。このラズパイに外部から接続できるようにすれば、外部からメイン機の電源が入れられるようになる。

DDNS設定

PPPoE にしてポート開放してさて ssh で繋ごうと外部から接続しようとしてもどうも上手くいかない。どうも1日毎程度の頻度でグローバルIPアドレスが変わっているようだ。実家ではそんな頻繁に変わるものでもなかったのでサボっていたけれど、ここまで頻度が高いと設定するほかないのでDDNSを設定することにした。 まずは Cloudflareでドメインを購入し、DNSレコードを追加してドメインと自宅のIPアドレスを紐づける。ここで Proxy をオフにしないと上手くいかないので注意。nslookup とかで自宅のIPを示していることを確認したら、外部から sshドメイン指定でも繋がることを確認する。LAN内からだと上手くいかないので(後述)、テザリングなどで接続するのが良い。次にラズパイに ddclient を導入し、IPアドレスが変わっても自動的に Cloudflare のDNSレコードを変更してもらうようにする。

zenn.dev

この記事を参考にすれば大体上手く行くが、ddclient のバージョンの問題は現在解決しているので気にする必要はない。ちゃんと設定できているかは sudo ddclient -v -force などとすると確認することができる。cron が好きではなく systemd が好き(なんとなく)なので sudo systemctl enable ddclient && sudo systemctl start ddclient としてデーモンとして走ってもらうことにした。sudo journalctl -xeu ddclient と打つとログが見れて5分おきにIPアドレスを更新しに行ってる様子が見れる。最悪の場合5分のダウンタイムが発生するが、そもそも個人宅のサーバーで運用するようなサービスは5分落ちようと大した問題にはならないだろうからまあいいだろう。

内部用のDNSサーバーを建てる

LAN内からドメイン指定でアクセスしようとしてもうまく行かないのはドメインがローカルのアドレスを指していてルーターに行っちゃったりするからだった気がする。内部のものは内部で解決してあげるのが都合が良い。/etc/hosts にドメインとローカルIPアドレスの関連を書いてあげればうまく接続することができるけど、何個もあるマシン全部の /etc/hosts をいじるのも微妙だし統一するのも微妙なので今回はDNSサーバーを建てることにした。 自分で持ってるドメインは自分で解決して、それ以外を 1.1.1.1 とか 8.8.8.8 にお任せすればよろしい。これをうまいことやってくれる dnsmasq というソフトがあるので、これをラズパイ上で走らせる。

sudo apt install dnsmasq
sudo vim /etc/dnsmasq.conf

コメントアウトを剥がしたりして

domain-needed
bogus-priv
resolv-file=/etc/resolv_dnsmasq.conf
strict-order

などとして /etc/resolv.conf を

nameserver 127.0.0.1

/etc/resolv_dnsmasq.conf を

nameserver 1.1.1.1 (お好みで)

などとしてあげる。ルーターでラズパイのIPアドレスDNSサーバーとして指定してあげたり、メイン機のresolv.confにそのIPアドレスを指定したりするとラズパイをDNSサーバーとして使ってくれるようになる。解決したいドメインは /etc/hosts に記載する。IPアドレスドメインを空白区切りにした行を追加して sudo systemctl restart dnsmasq すると設定が反映されてローカルからホストしてるドメインにアクセスしてもちゃんと接続できるようになる。

nginx を使ってリバースプロキシを構築し、複数のドメインを扱う

サブドメインは何個作っても無料なのでなるだけ使いたいという気持ちになるが、普通にやろうとすると1ドメインに対して1IPアドレスしか指定できないので上手くいかない。そこで nginx を用いてリバースプロキシを構築し、ドメインごとにマシン分けたりポート分けたりするとうまいこと複数のドメインを1つのグローバルIPアドレスで扱うことができる。 眠いので詳細は後日追記するけど、ドメインごとに設定ファイルを作ってそれぞれlistenしてるドメインごとに proxy_pass に別のマシンのIPアドレスなりポートなりを設定すればうまいことできる。/etc/hosts では全てラズパイを指定する。DNSのレベルでは全てラズパイに集められて、そこからリバースプロキシで様々なマシンやポートに分配していくという形になるので。開放するポートも一旦ラズパイに流すよう設定すれば良い。 例として、hi.takabayap.com と hello.takabayap.com を同じマシンの別のポートで扱ってみた。こんな感じになる。

上が実家のラズパイ、下が自宅のラズパイ。どちらの場合も上手くいってることがわかる。

こうすることによって例えば ssh.example.comssh 用に使ったりとかそういうちょっと贅沢なことができるようになる。それ以外でも色んなサブドメインを一つのマシンで使えることは結構嬉しい。アプリのテスト用サーバーを用意するときなんかに使うことになると思う。

ドメインを追加するとき

/etc/hosts にドメイン名を追加して dnsmasq を再起動するとローカルから解決できるようになる。Cloudflare のDNSに登録し、nginx の設定ファイルを/etc/nginx/sites-available に作成し /etc/nginx/sites-enabled へリンクを張って nginx を restart することでリバースプロキシが動作するようになる。飛ばす先でサーバーを動作させれば無事接続することができるようになる。

おわり

DNSなどのネットワークまわりは一旦了解しても時間が経つとわからなくなりがち。定期的にTCP/IPに入門したりしないとこういうところで苦労するようになるので、こうやって苦労したことは書き残していこうと思った。QEMUをまともに走らせるのにも結構苦労した覚えがあるから、まだギリギリ記憶があるうちに history から書き起こしていきたい。明日からはどこにいようと自宅のマシンに接続して開発ができるので、作業が進みそうだけど、もしかしたら勉強する前に勉強机を丁寧に掃除したりするのと同じ心理が働いているだけかもしれない。今後注視していきます。

Enablement Internship for Gophers (6/21~6/23) に参加しました

早稲田大学基幹理工学部表現工学科3年の@takabayapと申します。このたびナレッジワーク社のEnablement Internship for Gophersに参加してきました。

なにしてきたか

プログラミング自体は小学生の頃からやっており、今11年目(!)。Goは高校のときにちょっとだけ触って、本格的に勉強しはじめたのは2021年なので2年目くらい。ハッカソンアプリ開発で利用しています。

github.com

技育CAMP vol.9で作ったウェブアプリ。参加記録を書こうと思ってもう半年が経ったため、引用するブログ記事がありません。

takabayap.hateblo.jp

リリースしたアプリ。バックエンドは全部Goでできてます。

Goはシンプルで、好みが分かれがちではありますが私はかなり好きです。今回のインターンシップはピッタリでした。

Enablement Internship for Gophersとは何か

Enablement Internship for Gophersとはナレッジワーク社が実施してる3daysインターンシップです。
ナレッジワーク社はtoBクラウドサービスを展開している企業で、2020年4月創業とまだ創業して間もない企業であるにもかかわらず製品は誰もが知る日本を代表する企業に導入されています。

knowledgework.cloud

メインとなっている製品はセールスイネーブルメントに焦点を当てたものですが、会社としてエンジニアイネーブルメントにも取り組んでいます。イネーブルメントとは直訳が難しいけど「ひとりひとりの成果・能力の向上」のようなニュアンスでナレッジワーク社は特にGoに力を入れており、今回のインターンシップもその活動の一環と言えるでしょう。

prtimes.jp

今回はGoの主要な機能の1つである並行処理をメインテーマとしていて、講義を行ったあとに個人でOSSとしてなにか1つ関連したものを作るという内容のインターンシップでした。

参加するまで

元々ハッカソンで登録していたサポーターズさんから今回のインターンへの招待が来ていたことが切っ掛けで申し込みました。まず面談を実施し、コーディングテスト、面接を経て参加という流れでした。
面談では会社や製品の概要、大事にしている価値観など丁寧にお話し頂いて大変良かったです。インターンの面接自体初めてだったので緊張していたけれど、初めてがこれで本当に良かったと思っています。ただエンジニアが少数精鋭という雰囲気で非常にレベルが高そうで、今回のインターンシップもGo上級者向けと銘打っているので要求されている能力に対する自分のレベルが少し不安になりました。
実施されたワークショップの動画を見てコーディングテストに備え、コーディングテストは相変らず締切3時間くらい前に開始。内容は聞いていたようにかなり難易度が高く、正直落ちても全然不思議ではないと思っていました。
面接を受けたらまた自分の勉強不足を実感し、ここでも落ちてても全然不思議じゃないという手応えでした。合格できて良かったです。初めてのインターン合格でした。

なにしたか

  • 1日目
    • 講義
    • チーム開発
    • 発表
  • 2日目
    • 講義 sync.Onceのruntime.Goexit()での挙動やGoDebugの話など
    • 個人開発
  • 3日目
    • 個人開発
    • 発表
    • 懇親会

チーム開発

課題

チーム開発で選べる課題は2つあって、1つがsync.Onceに関連するもの、もう1つがcontext.AfterFuncに関連するものでした。うちのチームはせっかくなのでより難しそうなcontext.AfterFuncのほうを選びました。

github.com

Dialしてnet.Connを得るときにcontextを渡してcancelできるように、DialWithContext関数を実装しようという課題です。まずGo 1.21で追加予定のcontext.AfterFuncを利用して実装し、これが出来たので次にAfterFuncを使用しない実装を試みました。シンプルにctx.Done()を受けとってnet.ConnをCloseするようにしていただけだったけれど、これだとWithCancelのcancelを使わずにDialWithContextで得たnet.ConnをCloseするとctx.Done()を監視しているgoroutineが終了することなくリークしてしまう。そこでcancelFuncを返すようにしてconn.CloseしたあとこのcancelFuncを呼び出すと監視しているgoroutineを終了できるようにしました。実装としてはcancelFuncが呼び出されるとDialWithContext内で開けたchanをcloseします。この終了を伝えるchanをctx.Done()と並行して監視し、returnしgoroutineを終了するようにすることでgoroutineリークを無くすことができました。runtime.NumGoroutineを関数実行前後などで呼び出し、goroutineの数が正しく元に戻っていることが確認できました。

func DialWithContext(network, address string, ctx context.Context) (net.Conn, func(), error) {
    conn, err := net.Dial(network, address)
    if err != nil {
        return nil, func() {}, err
    }

    done := make(chan struct{})

    go func() {
        select {
        case <-ctx.Done():
            conn.Close()
        case <-done:
            return
        }
    }()

    return conn, sync.OnceFunc(func() {
        close(done)
    }), nil
}

(tenntennさんからのご指摘により一部コードを修正しています)

感想

まずモブプログラミングという手法を体験するのが初めてでした。自分が理解できたことがなかなかつたわらないともどかしいし、かといって自分が書く側に回ると自分が書きたいコードを勝手に書くわけにもいかないというところに難しさを感じました。結果的には人に説明することで自分の理解も深まるし、書く側が理解できていなかったとしても書く過程で理解が要求されるのでチーム内の理解を半ば強制的に同じ水準まで引き上げるという効果があり、長期的な生産性の向上に繋がるのだろうと納得しました。
GoのRelease Candidateなんて入れたことなかったのでそこも新鮮でした。そもそも普段開発してるときにバージョンほとんど意識してないですし。goroutineの数を意識した開発もしたことがなかったので勉強になりましたが、自分が作ったサービスのコードのどこかでgoroutineがリークしてたらどうしようとちょっと怖くなったのでこれから手を入れていきたいです。

個人開発

github.com

課題

個人開発の課題は以下の3つのいずれかです。

  1. 並行処理のテストツール
  2. Goroutine/channel の可視化ツール
  3. 同期ライブラリ

まず自分で実際に使うようなものを作ろうという気持ちがあり、そこから考えていきました。
テストツールで並行処理の順番を制御し全ての組み合わせでテストして実行順に関係なく動作することを保証しようとしたけれど、goroutineの動く順番のみならず内部の処理の順番も制御しなくてはならず、関数の外側から気軽にテストするものはできそうになく悩んでいました。tenntennさんに相談したところ全部列挙してテストすることに拘らなくても良いのではないかという助言を受けたので、可視化ツールとして1回1回の実行順を可視化する方向を考え始めました。実行順によって問題が発生しそうなものを考えてみたらいいんじゃないと言われたときに、Mutexのロックとアクセスを可視化できたら便利かもしれないと思ったのでMutexの可視化ツールへと舵を切りました。授業でロボットを作り、ロボットのフィールド上の位置を状態として持ちMutexを用いて管理する予定だったので、自分で使うようなものを作るという目標にも適しています。
可視化するにはどうすればいいかというのも問題でしたが、他の方のワークシートをチラチラみていったらGraphvizという便利そうなものを知れたのでそれを使うこととして一旦可視化は後回しに。Mutexのインターフェースを持ち、追加でRead/Setを持つMutexVisualiserという構造体を用意してこの構造体に関する全てのアクセスのログを取り可視化に用いることにしました。

type Mutex[T any] interface {
    sync.Locker
    Set(T)
    Read() T
}

type MutexVisualiser[T any] struct {
    m       sync.Mutex
    actions []action
    value   T
}

どんな型でも値に用いたかったのでジェネリクスを初めて使うことに。Mutexのアクセスを全部持っておくのはそこまで難しくなくて、runtimeから呼び出し元の関数名やgoroutine IDを取得したりtimeを取ったりと結構順調でした。可視化の段階に入って、go-graphvizを使おうと思ったけどこれがなかなか難しく、rankの設定やsubgraphの使い方がドキュメントになかった上に使っている人も見つからなかったので使うのを諦め、他にも色々ないか探したうえで結局graphvizが使いやすそうだということになったのでtemplateを用いてgraphvizを直接書いていくことにしました。ここにかなり時間を使って、なんとか上手く可視化できたところで開発時間が終了しました。

生成されるグラフ

感想

発表ではグラフの見た目が特に評判が良かったです。クラフトマンシップを感じると言われ、拘ってよかったと思いました。メンターの方には手が速いという評価を頂き、自分は手が遅いほうだと思っていたので結構自信に繋がりました。ワークシートに事前に必要そうなナレッジを表として整理した上で計画的に調べ物をして、最後にコーディングをしていくという手法がかなり強力だったので、これからも使っていこうと思います。今までは無計画に調べ物をして満足してしまうことが多々ありました。 他のチームの方で時間内に丁寧なREADMEを書いていらっしゃる方がいて、READMEを含むドキュメントに全然力を割いていなかったので、そこの重要性を再確認しました。

まとめ

全体を通して大変楽しかったです。講義で触れられるものは知らないことばかりでしたし、歩くGoDocことtenntennさんはあらゆる質問に答えてくれるという安心感がありました。気軽に質問できる体制が整っており、コミュニケーションコストが高いというオンラインのインターンシップの弱みがだいぶ薄れていた印象です。
懇親会も含め話した参加者の方は全員修士課程在学中でした。普段Goを書かないという人も参加していましたが、急速にGoを吸収していっていたのでレベルはやっぱり高かったです。

完全オンラインで仕事をするというのがどんな感じなのかというのも体感できて良かったです。基本的に自室で一日が完結してしまうのでストレスに感じてしまう人もいらっしゃるでしょうが、私にとってはとても快適でした。メンターの方も含め会社の方も非常に話しやすく、安心して取り組むことができました。次回も是非参加したいですし、特にGoが好きな方にとてもオススメできるインターンシップでした。

Go + Flutter でモバイルアプリを開発しリリースした話

この度所属している大学の大学生向けアプリを開発し AppleApp StoreGoogle の Play Store にリリースしました。

play.google.com

マイルストーン

マイルストーン

  • MILESTONE HENSHUKAI, GENERAL INC. ASSOCIATION
  • 教育
  • 無料

apps.apple.com

アプリのダウンロード数などのグラフを示している。合計DL数が3800程度。

リリースから1週間経った時点でのアプリストアでのダウンロード数などのグラフです。自分が思った以上に使われていますね。

思えば生まれて初めてこういった形で自分の書いたコードで実際に人に使われるものが作れたなと感慨深いです。この記事ではアプリの開発の裏側、利用している技術や開発過程などを説明していきます。

マイルストーンとは

マイルストーンエクスプレスは、早稲田大学の非公認サークル「マイルストーン編集会*1」が発行している学生向け雑誌で、学生からのアンケートに基づいた授業の評価をまとめた逆評定を掲載しています。

今回作製したアプリでは、マイルストーンエクスプレスに掲載されている逆評定のデータを検索し、お気に入りに登録することができます。ただし利用には書籍購入時に付属しているシリアルコードをアプリで利用するアカウントに紐付ける必要があります。

iOSAndroid双方で利用可能で、開発期間は去年の9月頃から始まり、3/10の書籍発売に合わせリリースできました。相方はコードはあまり書けないのですが、サークルに連絡を取ったり、リリースに必要な文章や利用規約の準備等事務作業を全て担当してくれました。そもそもアプリの制作という話をサークルに持ちかけたのも彼なので、彼無しでは完成しなかったどころか始まってすらいなかったでしょう。バックエンドは全て私が担当し、フロントエンドのデザインは相方に任せそれ以外を担当しました。

利用している技術

OpenAPI(Swagger)

今回最も使ってよかった技術の一つです。アクセスポイントをyamljsonで定義することができるのですが、このファイルをもとにしてコードの自動生成が可能になります。またここに記述したサンプルを返すモックサーバーが簡単に建てられるので、フロントエンドとバックエンドを並行して開発することが用意になります。今回は私が両方やってるので恩恵は受けられませんでしたが、このようにしてAPIを定義しておくことで大変管理がしやすくなりました。

Go

なんだか流行ってますよね、Go。コードがわかりやすいし、速いので大変好みです。

中高では Javascript をメインで書いていたのですが、いかんせん node.js が好きじゃなく代替を探したときに出会ったのが Go でした。といっても当時は殆ど先に進むことはなく学ぶのを辞めてしまったのですが、その経験があるので大学でバックエンドサーバーを何で書くか迷ったときに真っ先に候補に挙がったのが Go でした。実際に触ってみると非常にシンプルで、コードが複雑になりにくいところが大きな利点であると感じました。他の言語と大きく異なり、エラーが例外ではなく値によって返却されるという点も好みでした。無論 err!=nil がコードに大量発生するという汚点はあるのですが、わかりやすさはこの欠点を上回ります。

学習するにあたり Go言語実践開発入門と Go Programming Blueprints を読みましたが、他の言語での開発経験がある場合は不要だと思います。ネット上の文書が大変充実しているのでそもそも技術書を買う必要は無いと言う人もいますが、私は書籍の消化が得意なのでスピード重視で書籍を購入し、結果的に買って良かったと考えています。使用したパッケージなどを説明していきます。

Clean Archiecture, DI (wire)

コードを書く際には依存性を分離することを意識し、また依存性の注入(DI)を行うことで単体テストをしやすくしています。具体的にはDBなど外の要素にアクセスするレイヤー(infra *2 )、これを組み合わせてやりたい操作を実現するレイヤー(usecase)、さらにサーバーへのアクセスを解釈し usecase を用いて望みの操作を実現するレイヤー(handler)を用意しそれぞれ1つ下のレイヤーにのみ関心を持つことでコードの複雑さを下げています。DI は wire を用いて一括で行っています。

あんまり覚えてないですが、確かツイッターで「企業の面接を受けたらアーキテクチャの話をされて全然わからなかった」みたいな記事を読んだのがきっかけでアーキテクチャについて調べ始めて、意識するようになったはずです。思い返してみればそれまではほんとにスパゲッティコードを書いてたので本当にありがたい出会いでした。

Testing (mockgen, gotests, kin-openapi)

依存性を注入した部分のテストには mockgen を利用しています。使うのにちょっと手間がかかるので gotests と組み合わせて、mockgenを利用するための準備の部分を自動生成できるようにしています。DBにアクセスする部分のテストはモックを用意するのが面倒だったのでシェルを叩いて毎回テスト用にDBを用意するコードとサンプルデータを入れるsqlファイルを用意しこれらをテスト実行時に走らせてテストしていました。ポコポコDBを作ったり消したりするのあんまり良くないんじゃないかという気がしてるので別の方法を考えています。APIのレスポンス検証をkin-openapiを用いたテストで行っています(後述)。

ORM (sqlboiler, sql-migrate)

ORMには sqlboiler を採用しました。当初は GORM を利用していたのですが、テーブルを JOIN する際に手間取ったり、struct を自分で用意するのが面倒になったので既存のDBスキーマから自動でマップする構造体などを生成してくれる sqlboiler へと乗り換えました。これにより事前に生成されたコードを用いるのでGORMより速く、 JOIN や複雑なクエリの発行も GORM に比べて簡単に、また殆どの処理を型安全に書くことができるようになりました。DBスキーマsql-migrate を利用して管理し、もしスキーマが変更されコードを書き直す必要が生じた場合は再生成後静的解析により警告が表示されるようになります。この移行は結構手間がかかりましたが、やって良かったです。DIを行なっていたために他のレイヤーのコードには一切手をつけることなく移行が完了したので、コードを丁寧に書いててよかったと思いました。

Handling errors (標準のerrors)

エラーハンドリングにはカスタムエラーパッケージを用意し、error を Wrap するごとに呼び出し元の関数の情報を追加していったり独自のエラーコードを用いて発生したエラーによる条件分岐を可能にしたりしています。基本的には上の階層に受け渡されていき、一番上の handler 層で適切な HTTP Status Code と共にエラーとしてクライアント側に返却されます。独自エラー型はIsメソッドを持っておりerrors.Isの際にエラーコードが同じかどうかで比較をしています。エラーコード型はエラーコードの文字列を返すメソッドとステータスコードを返すメソッドを持っており、必ず403を返すerr403とエラーコードの文字列の組み合わせなどで表されています。呼び出し関数の取得はruntime.Callerから得られた文字列を/や.で区切っていじることで取得しており、もう少しきれいなやり方はないかと思いつつ動いてるのでまあいいかとそのままにしてあります。

API (oapi-codegen, kin-openapi)

oapi-codegenを利用しており、定義したAPIを自動でサーブするためのインターフェースを用意しパラメータを自動でパースしてくれたり返却する際JSONにMarshallするための構造体も自動で生成してくれるので大変助かりました。テストはkin-openapiのレスポンス検証を使っており、もし定義と異なるレスポンスが帰ってきた場合はテストが通らないので定義通りに実装されているかが確認できます。

認証

GoogleAppleでのソーシャルログインに対応しています。外部の認証サーバーからトークンを受け取ってこっちのサーバー側で検証したらそのサービス固有のIDと一緒にユーザー登録してJWTを発行しています。このときJWTに所持している本の情報も入れているため以後アクセストークンが有効であればユーザーDBアクセスなしで検索可能*3となります。アクセストークンの有効期限は15分ほどで切れた場合はリフレッシュトークンを用いてリフレッシュすることが必要です。この際に外部サーバーのトークンが有効かどうか確認することでアプリの利用を停止されてないか確かめています。

Flutter (フロントエンド)

フロントエンドには Flutter を採用しました。iOSAndroid 双方で利用できるようにする必要があったのでクロスプラットフォームなフロントエンドフレームワークを探したのですが、まず私がWeb技術、特にHTMLとCSSが苦手なため React Native などの Web技術ベースのフレームワークは却下となり、他のフレームワークと比較した結果情報量が多く、また個人的に C より Java に比較的馴染みがあるので Flutter を採用することにしました。

実際に使ってみるとプラットフォーム間の差異を殆ど気にすることなく開発を行うことができ、ツールも充実しているためかなり満足度が高いです。普段は Linux を用いているのですが、Linux ネイティブでも Android エミュレータと同じものが動くことに大変驚きました。今回のアプリ開発では私が Mac を持っていないために最後のひと月以外は全て Android のみで動作確認していたのですが、全く問題なく iOS でも動作してくれました。

Flutter の経験は1週間程でしたが、随分その経験が活きたように思います。

github.com

2021年12月末から翌年1月、大学1年の冬休みは Flutter と Go を書いて過ごしていたのですが、大学が始まってから全く触っていないので本当にこのレポジトリにあるものが全てです。

状態管理 (riverpod)

上に出したレポジトリではChangeNotifierを用いてMVVMっぽく書いていましたが、現在は Riverpod 2.0の Code Generationを用いています。中身はNotifierProviderとAsyncNotifierProviderで、特にAsyncNotifierが非同期処理を扱う際にはとても便利です。殆どのWidgetをStatelessにしてViewModelで一括でステートを保持しています。ChangeNotifierを使っている部分もあるためすべてRiverpod 2.0に統一したいです。

最初はMVVMっぽくだいたい全ての画面に対応するViewModelを用意していましたが、最近は無駄が多い気もしています。ルーティング用のProviderを用意したらVMは取っ払っちゃって今その一個下にあるレイヤーを画面から直接呼んじゃうのもありかなという気がしています。そうなるとGoでやってる階層構造とあんまり変わりませんね。

DI, Routing (GetX)

一番下のレイヤー、RepositoryのDIとルーティングにGetXを用いていますが、全てRiverpodに統一できるはずなので置き換えようかな〜と思いつつも特に困ったことがないためそのままになっています。色々見てるとちょっと評判悪いみたいです。置き換えて比べてみようと思います。

API叩く部分 (openapi-codegen, dio)

openapi-codegendioのコードを自動生成しており、通信部分は全く自力で書いていません。めちゃめちゃ楽で定義を更新して再生成すると静的解析により対応が必要な部分がわかるのも大変良いです。あんまり情報が見つからなかったのが難点といえば難点でしょうか。

認証

ログイン処理では外部のOauth認証サーバーにアクセスし、もらってきたトークンをバックエンドに送り有効であると確かめられた場合にトークンが返却されるのでそれをSecure Storageに保管しています。Flutter側でもトークンの情報を活用することは考えましたが、トークンの形式を変更するかもしれないことを考えてFlutter側では完全にノータッチで、仮にJWT以外に置き換えたとしてもフロント側のアプデは一切必要ないようにしています。

トークン有効期限切れで403エラーが返ってきた際に時にdioのinterceptorで上の階層から見えないようにトークンをリフレッシュしてリトライする処理がちょっと難しかったです。リポジトリのディスカッションなどを参考に実装しました。

DB (PostgreSQL)

特に文句ありません。現在は基本的な機能しか使っていないので当然といえば当然ですが、これからpg_bigmを用いた類似度検索などを実装しようと思っているので、そこで高機能さにお世話になるかもしれません。

DB設計なんてもちろん初めてだったので達人DBを読みました。日雇いのバイトに持ってって休憩中に読んでたら社員の人に褒められて、後でジュースとお菓子おごってもらいました。達人DBはめっちゃわかりやすくてかつ読みやすいので超オススメです。読んだことなかったら騙されたと思って買ってみてほしいです。

Deploy (render.com)

日本ではあまり知名度がないみたいですが、使いやすいPaaSです。友達が使ってたので使ってみたら本当に便利で離れられなくなりました。無料枠もあるので気軽に試せますし、GitHubのレポジトリを選択するだけでデプロイができます。無料版であってもPR previewというプルリクエスト毎にプレビュー版をデプロイしてくれる機能もあり、コミットがあれば自動でビルド・デプロイしてくれます。難点といえば日本サーバーがなくシンガポールサーバーを使わざるを得ない点ですが、そこまでレスポンスは悪くないので問題ないかなと思います。DBもこのサービス上にデプロイしていて、24時間毎の自動バックアップには助けられました。

コード管理 (GitHub)

コードは基本GitHubで管理していました。途中まではバックエンドとフロントエンドで分けていましたが途中からリポジトリを合体させモノレポにしました。これは開発中に出てたハッカソンで友達が同じようにモノレポで収めていたのを参考にしてやったはずです。Issueを立ててバグの原因特定してそれがバックエンドでもフロントエンドでもブランチ切って同じリポジトリで対応できたり、ある時点でのフロントとバックのコードが簡単に取得できたりとメリットが多かったです。ブランチはリリース前は初期状態のmain、developと都度のfeatureブランチのみで、リリース時にreleaseブランチを切って調節した後にmainにマージしてmainブランチをrender.comでデプロイしました。今はgit flowのとおりに基本的にはやっていて、リリースバージョンごとのタグもつけいます。バグや機能追加毎にIssueを立ててブランチを作り、マイルストーン*4によって次に出すバージョンに含める機能を管理しています。依存性を分離することで複数のファイルを編集することをあまりせずに共同作業ができたので、フロントの見た目だけをいじる相方と裏のロジックをいじる自分でコンフリクトを多少避けることができたのも良い点でした。ただ結局見た目のコードもかなり手を入れたので、コンフリクトしてたことも多々ありめんどくさかったです。

今後やりたいこと

まずフロントのエラーハンドリングが適当なので改善したいです。ずっとGoのerror as a valueを扱ってた結果例外をthrowするDartに慣れないままとりあえず動く状態にしてリリースになんとか間に合わせたという状況なので、全然エラーをうまくハンドルすることができていません。実際エラーが出ないことでストアのレビューに低評価が出てしまったので早急に対応したいところです。

あとユーザーに関係ない部分になってしまいますが、管理画面を作ろうと思っています。サービスリリースして初日にユーザー数を確認しようとSQL叩いたら、ミスってDBのユーザーテーブルを全部飛ばしてしまったのでなるべく生で触りたくないです。

機能の追加も随時やっていきます。今はリリースに必要な最低限の機能だけでリリースしているので、所持している本を確認したりより詳細な検索条件を設定したり、シラバスを参照できるようにしたり、記事を配信できるようにしたりとやりたいことはたくさんあります。あと忘れちゃいけないのが広告で、例えば早稲田通りでティッシュ配ってる企業なんかはこういう早稲田生しか使わないようなアプリに広告出したいんじゃないかな〜と思うのでうまく広告を取り入れて費用を回収していきたいですね*5

最後に

アプリを使ってくれている人々、どうもありがとうございます。科目登録期間に旅行に行くことになってしまったが、アプリのおかげで旅行先に本を持っていかなくて良くなったという声や、弟・先輩の友達が実際に使っていたなどの話も聞けて大変嬉しく思っています。初めてのアプリ開発でしたが、無事にリリースできてまずは一安心です。

設計からリリースまで全部やったのはとても良い経験になりましたし、めちゃくちゃ大変でしたがその分大きな自信に繋がりました。これからもアプリに限らず色々作って、色々やっていくので、応援よろしくお願いします。 ;) 

*1:マイルストーン編集会とは – e-mile

*2:こう呼んでいますが、これが一般的かはわかりません 他も同様です

*3:ただし、トークンが発行されたあとにシリアルコードを紐付けると反映に時間がかかる

*4:アプリではなくGitHubの機能の方

*5:今は無給!!