2022年4月振り返り

今年4月に行ったことを振り返る記事です。

エンジニア養成機関、42Tokyo で取り組んでいる課題や、開催されたイベント、課題外の活動について振り返ります。

やったこと

TypeScriptでオンラインゲームを作るチーム課題

API定義(openapi.yaml)、バックエンド、フロントエンドと幅広く触らせてもらっています。

現在はChat機能のDB設計、API設計をした後、Chatの画面を作っています。

Goの入門課題

Goを学ぶというよりは、Goを通じてプログラミングを学ぶような課題です。

任意参加で期間が長いので、のんびり取り組もうと思います。

Tuning the Backend Contestに参加

42Tokyoと協賛企業ドリーム・アーツとのイベントです。

42時間耐久でバックエンドのパフォーマンスチューニングを、学生3人1チームの計34チームで競いました。

自分たちのチームは、あまりスコアが伸びず悔しい結果となりました。
他のチームのコードや取り組み方を参考に、学びを深めたりチームの取り組み方を改善したりできたらと思います。

統計WEBの輪読会(2021年10月から継続)

統計について学べるサイト、統計WEBの 統計学の時間 の輪読会です。

4月はStep1. 基礎編の「16. 標本と抽出法」まで進みました。
自分の発表週では、「15-6. 2変数の期待値と分散」と「16-1. 母集団と標本」を担当しました。

朝の読書会

早起きできたときに参加しました。学生が集まって1時間読書した後、学んだことをそれぞれ発表する会です。
他の学生から質問を受けることで説明する力が身についたり、説明することで自分が理解できていない箇所に気づけたりして、良い会だと思います。

読書会では『りあクト! TypeScriptで始めるつらくないReact開発 第3.1版【Ⅰ. 言語・環境編】』を読みました。

oukayuka.booth.pm

全3冊構成の1冊目で、React、JavaScript、TypeScript、関数型プログラミングについて書かれています。歴史的経緯から説明されているので、理解しやすかったです。

読んでいて特に面白いと思ったのは、関数型プログラミングについての章です。カリー化はこんな書き方ができるのかと驚きましたし、関数の部分適用はインターフェースの実装を関数型プログラミングで実現するように思えて面白かったです。

コミット時間

今月のコミット時間は169時間19分、1日平均5時間36分でした。

コミット時間の推移は以下です。

コミット時間、付け方が割と適当なので、今後はトピックごとのコミット時間を記載するよう変更するかもしれません。

今後やること

今やっている42Tokyoの課題を引き続き行いたいと思います。

また、42Tokyoの基礎的な部分、First Circle(海外だとCommon Coreと呼ばれています)を修了するのにExamという試験が必須なので、そろそろExamを受けたいと思います。

C++でHTTPサーバを作った話

エンジニア養成機関 42Tokyo の課題で、WebサーバをC++で作る課題に取り組みました。

この記事では課題で学んだこと、取り組みについて振り返ります。

課題の概要

NGINXのようなWebサーバをC++98で作る課題です。

「NGINXのような」というのは以下のような意味です。

  • HTTP/1.1に準拠していること。
    • といっても完全準拠ではありません。
    • 対応するメソッドは GET, POST, DELETE だけです。
  • I/O多重化によって複数のリクエストをさばくこと。
    • I/O多重化については、以下の記事が分かりやすいです。 christina04.hatenablog.com
    • I/O多重化に使う関数は select, poll, epoll, kqueue から選択できます。
  • Configファイルによってサーバの設定を読み込むこと。
    ※Configファイルの記法はNGINXに完全に準拠する必要はありません。
    • バーチャルホスト
    • リダイレクト
    • 許可するメソッド
    • リクエストボディのサイズの最大値
    • indexとして使用するファイル(例:URLの末尾が / で終わる時に index.html を使用する)
    • autoindex(indexが無い場合のディレクトリ内一覧表示)
    • デフォルトのエラーページ
      など

以下はNGINXと異なります。

  • 直接のCGI実行
  • POSTでのファイルアップロード

成果物

github.com

以下スクリーンショットです。

f:id:nafuka11:20220413144509p:plain:h240
ファイルをレスポンスとして返す

f:id:nafuka11:20220413144552p:plain:w400
ディレクトリ内のファイル一覧をレスポンスとして返す(autoindex)

f:id:nafuka11:20220208011758p:plain:w400
ステータスコードに応じたエラーレスポンスの返却

f:id:nafuka11:20220208011927p:plain:w400
ステータスコードに応じてファイルをレスポンスとして返す(NGINXのerror_page)

かかった時間

  • 期間:約98日(2021/11/09〜2022/02/14)
  • 時間:約197時間

開発の流れ

echoサーバを作ったあと、

  • HTTPリクエストのパース
  • I/O多重化対応
  • Configファイル読み込み

など、少しずつ機能追加をしていきました。

実装

大まかなフロー

f:id:nafuka11:20220413002015p:plain

Configファイルを読み込み、開くポート毎にSocket(ServerSocket)を作成し、bind()とlisten()して接続を受け付けるようにします。

ServerSocketのディスクリプタをイベント(kevent)に登録し、クライアントからの接続を検知できるようにします。

その後イベントループに入ります。イベントが発生したら、発生したイベントに応じてSocketのメンバ関数を実行します。

  • イベントは void * のユーザデータを持てるので、そこにオブジェクトのポインタをセットしています。
  • ServerSocketは、クライアントから接続があったら、accept()して新たなSocket(ClientSocket)を作成します。
  • ClientSocketは状態を持ちます。最初はHTTPリクエストを受信する状態です。 この状態に応じてイベントを登録・登録解除し、HTTPリクエストの受信、ファイルの読み込み、HTTPレスポンスの送信をしていきます。

I/O多重化の関数選定

課題の概要 で説明したように、I/O多重化の関数は select, poll, epoll, kqueue から選ぶことができます。

自分たちのチームはkqueueを採用しました。

理由はselect, pollに比べ、パフォーマンスが優れているためです。

  • 各関数のパフォーマンスについては、 libevent のBenchmarkが参考になります。
    • select, poll, epoll, kqueueのベンチマークが載っています。
    • 画像サイズが小さいですが、URLの benchmarksbenchmark に変更すると、サイズの大きい画像にアクセスできます。

epollも候補でしたが、epollの場合はVMでレビューをする必要がありました。
VMはレビュー時に安定せず、レビューでの負荷テストに耐えられない可能性があったため、kqueueを選択しました。

パース方法

HTTPリクエストのパースは調べたところ、3つ方法があるようでした。

  1. 文字ごとに状態を持たせる
  2. 行ごとに状態を持たせる
    • リクエスト行、ヘッダ、ボディと、行ごとに状態を持たせる方法です。
  3. "\r\n\r\n" を見つけたら一気にパースする
    • ヘッダとボディの間の空行まで読み込んだら、リクエスト行とヘッダを一気にパースする方法です。

自分たちのチームは、行ごとに状態を持たせてパースする方法を採用しました。

NGINXと挙動を合わせたかったのですが、文字ごとに状態を持たせるのは大変そうだったので、行ごととしました。

テスト

HTTPリクエスト・レスポンスのテスト

f:id:nafuka11:20220413002945p:plain

Python + pytest + HTTPConnection を使って作成しました。

もう少しテストケースを追加しやすい作りにすればよかったな……と後になって思いました。

Configファイルのテスト

f:id:nafuka11:20220413003245p:plain

ShellScriptで作成しました。不正なConfigファイルを読み込ませ、その出力と想定されるエラーメッセージとのdiffを取って結果を表示します。

Configファイルのテストは自分がベースを作り、チームメイトにメンテしていただきました。

チーム

この課題は2-3人で取り組むことができます。

課題に取り組み始めて1ヶ月は2人で、その後は1人入っていただき3人で取り組みました。

役割分担は以下のようになっていました。

コミュニケーション

チームのコミュニケーションは試行錯誤をしていました。

  • 1日2時間もくもく作業し、終了時に成果報告
  • 週1で進捗報告
  • 毎日5-10分で進捗報告 + timesで適宜つぶやく

最終的に一番下の方法でコミュニケーションを取っていました。

その他

チーム3人だけだと分からないことがあったりしたので、他の学生が別の課題で行っていた「P2P勉強会」を開催しました。

P2P勉強会は、週2-3回決まった時間に、課題に取り組んでいる学生が集まって進捗や困っていることを報告する会です。

他の方に聞くことで疑問点が解消されたり、モチベーションがアップしたりしたので、開催してよかったです。

大変だったこと

3つ大変だったことがありました。

  1. 機能追加による設計変更

    echoサーバから機能を少しずつ追加したので、考慮できていないことがあり、後で設計を変更する必要がありました。

    • I/O多重化:クラスを入れ子にした実装だったのですが、メインループでイベントを受け取って関数を実行する都合上、入れ子にしない作りに変更しました。
    • CGI:標準出力をHTTPレスポンスとしてパースする必要があり、パース方法をどう使い回すかで悩みました。HTTPパーサのクラスを継承してCGIパーサを実装しました。
    • バーチャルホスト対応:ポート1つに対しサーバ設定が複数になるので、Configの持たせ方を変更する必要がありました。具体的には std::vector<Config> から std::map<int, std::vector<Config> > に変更しました。
  2. URIのルーティング

    考慮できてないパターンが見つかり修正を複数回行いました。フローチャートを作った方がいいかもしれません。

  3. siegeでのリクエスト詰まり

    HTTPサーバは、siegeを使った負荷テストで一定のAvailabilityを保つ必要があります。

    私達が作成したHTTPサーバは、siegeを使うと初めは動くのですが、しばらくするとリクエストが詰まり、時間を置くと解消されて、また詰まって……という動作をしました。時にはタイムアウトもしていました。

    他のチームのselectを使ったプログラムでは、同事象は発生しないようでした。

    selectのように動作が遅くなるよう、試しにイベントの発生毎に1msスリープすると、リクエストの詰まりは解消されました。

    根本的な原因が分からず、kqueueの良さを打ち消す対処しかできなかったのが悔やまれます。

参考書籍・URL

HTTP全般

Webサーバの実装

HTTPパーサ

I/O多重化

2022年3月振り返り

今年3月行ったことを振り返る記事です。

エンジニア養成機関、42Tokyo で取り組んでいる課題や、開催されたイベント、課題外の活動について振り返ります。

やったこと

TypeScriptでオンラインゲームを作るチーム課題

Pong というゲームをオンラインで遊べるWebサイトを作る課題です。

自分は以下を行いました。

  • ユーザページにフォロワー一覧を表示
  • APIのレスポンスからパスワードを除去
  • フォーマッターの設定を追加

今はレスポンシブ対応をしています。

実例で学ぶレジリエンスプログラミング教室

42Tokyoの協賛企業、株式会社ドリーム・アーツ のイベント「実例で学ぶプログラミング教室」に参加しました。

内容については以下の記事にまとめてあります。

nafuka.hatenablog.com

統計WEBの輪読会(2021年10月から継続)

統計について学べるサイト、統計WEBの 統計学の時間 の輪読会です。

今月はStep1. 基礎編の 15.4. 連続一様分布2 まで進みました。

自分の発表週では、正規分布の再生性と標準正規分布を担当しました。

OSS-DB Silverの勉強会

OSS教科書 OSS-DB Silver を輪読会形式で読み進めていく勉強会です。

今月は「第3章 インストール」まで行いました。データベースクラスタの話が特に面白かったです。

本ではPostgreSQLソースコードコンパイルしてインストールするようになっていたのですが、環境を汚したくなかったのでDockerを使って環境を作りました。

コミット時間

今月のコミット時間は131時間21分、1日平均4時間14分でした。

コミット時間の推移は以下です。

f:id:nafuka11:20220404173926p:plain

今後やること

TypeScriptでオンラインゲームを作る課題を引き続き進めていきたいと思います。

「実例で学ぶレジリエンスプログラミング教室」に参加しました

2022年3月9日に、42Tokyoの協賛企業、株式会社ドリーム・アーツ のイベント「実例で学ぶレジリエンスプログラミング教室」が、42Tokyo校舎およびZoomにて開催されました。

システムを安定稼働させるためのコツであるレジリエンスプログラミングについて、スライドとハンズオン形式で学ぶイベントでした。

本記事は、このイベントの参加レポートです。

内容

株式会社ドリーム・アーツのCTO石田さんが、レジリエンスプログラミングについてスライドで説明した後、ハンズオンを行いました。

レジリエンスプログラミング

株式会社ドリーム・アーツは、SmartDBShopらん など、企業向けのSaaSを提供しています。

サービスを運用してきた中で学んだ、サービスを安定稼働させるためのコツがレジリエンスプログラミングだそうです。

レジリエンスが無いと、どんな問題が発生するか、例を用いて説明してくださいました。

例は、Nginxが複数のサーバをリバースプロキシし、複数サーバが1つのDBにアクセスする構成で、処理時間がかかるクエリが発生した場合に、サービスが止まってしまうというものでした。

レジリエンスの大切さについて説明いただいた後、システムを安定させるためのデザインパターンを6つ紹介してくださいました。

  1. サーキットブレーカー
  2. リトライ&フォールバック
  3. レートリミッター
  4. イムリミッター
  5. バルクヘッド
  6. キャッシュ

これらデザインパターンは『Release It!』という本に載っているそうです。

ハンズオン

github.com

レジリエンスプログラミングの説明の後は、上記リポジトリを使ったハンズオンが行われました。

GoとJavaでマイクロサービスを作成し、お互いに呼び出すようになっています。

Goでは gobreaker を使ってサーキットブレーカーパターンが実装されており、Javaでは resilience4j を使ってサーキットブレーカー、リトライ&フォールバック、レートリミッターパターンが実装されています。

校舎のPCでハンズオンをしようとしたのですが、残念ながらJavaがインストールされておらず、後日家で試しました(現在、校舎のPCにはJavaが入っているようです)。

試した内容は、以下のリポジトリにあります。

github.com

ハンズオンの後は、質疑応答、校舎限定の懇親会が行われました。

参加した感想

  • 耐障害性を高めるプログラミング手法は、42Tokyoの課題では得られない知識であり、勉強になりました。
  • 待ち行列の話が出てきたのですが、そこでポアソン分布が出てきて、統計WEB の輪読会に参加していて良かったと思いました。
  • 石田さんが楽しそうに話されていたのが印象的でした。

来月には株式会社ドリーム・アーツ主催のハッカソンが開催されるそうで、そちらも楽しみです!

2022年2月振り返り

今年2月行ったことについて振り返る記事です。

エンジニア養成機関、42Tokyo で取り組んでいる課題や、開催されたイベント、課題外の活動について振り返ります。

やったこと

42Tokyoの課題

C++98でWebサーバを作る課題

C++98でHTTP/1.1に準拠したWebサーバを作る課題です。

2月で課題をクリアしました。

この課題については書くことが多いので、いずれ振り返り記事を書く予定です。

TypeScriptでオンラインゲームを作る課題

Pong というゲームをオンラインで遊べるWebサイトを作る課題です。

3人でチームを組んでいます。他の2人は数ヶ月先行して取り組んで下さっているので、キャッチアップを頑張りたいです。

イベント

2月は特に参加していません。

3Dオブジェクトを回転させる課題を解くイベントや、自己分析をするイベントが開催されていました。

その他の活動

統計WEBの輪読会(2021年10月から継続)

今月はStep1. 基礎編の「13. いろいろな確率分布1」まで進みました。

自分の発表週では、二項分布を担当しました。

二項分布は期待値・分散を導出できたのですが、ポアソン分布と幾何分布は今の自分には難しそうでした……。

OSS-DB Silverの勉強会

OSS教科書 OSS-DB Silver』を輪読会形式で読み進めていく勉強会です。

自分の発表週では、「第2章 データベースの基礎知識」を担当しました。

発表の際はER図を用いて説明したのですが、Notionに新しく追加されたMermaidを使ってER図を描いてみました。

erDiagramだとEntity名に日本語が使えなかったりattributeの表示が崩れたりするので、classDiagramをER図として使いました。

f:id:nafuka11:20220304182618p:plain

コミット時間

今月のコミット時間は142時間54分、1日平均5時間06分でした。

コミット時間の推移は以下です。

f:id:nafuka11:20220304181446p:plain

今後やること

TypeScriptでオンラインゲームを作る課題を進めていきたいと思います。

2022年1月振り返り

今年1月行ったことについて振り返る記事です。

エンジニア養成機関、42Tokyo で取り組んでいる課題や、開催されたイベント、課題外の活動について振り返ります。

やったこと

42Tokyoの課題

C++98でWebサーバを作る課題

C++98でHTTP/1.1に準拠したWebサーバを作る課題です。

設定ファイルからWebサーバの設定を読み取り、HTTPリクエストからレスポンスを返せるようになりました。

f:id:nafuka11:20220208010858p:plain:w400
ファイルをレスポンスとして返せるようになったり

f:id:nafuka11:20220208011156p:plain:w400
設定によってディレクトリ内のファイル一覧をレスポンスとして返せるようにしたり(autoindex)

f:id:nafuka11:20220208011758p:plain:w400
ファイルが見つからなかったりした場合はエラーレスポンスを生成して返したり

f:id:nafuka11:20220208011927p:plain:w400
設定によってはステータスコードに応じたファイルを返すようにしたりしました(Nginxのerror_pageに相当)

TypeScriptでオンラインゲームを作る課題

Pong というゲームをオンラインで遊べるWebサイトを作る課題です。

Webサーバを作る課題をメインで取り組んでおり、こちらの課題はあまりコミットできておりません……。

イベント

DeNA CTO座談会

レバテックのポートフォリオ作成ガイダンス」に参加した学生を対象にしたイベントです。

DeNAのCTO、小林 篤さんによる特別講義とコードレビューが行われました。

特別講義は、去年の技育祭のセッション「飛躍的な成長を遂げるエンジニアに共通する3つの絶対法則」を改定したもののようでした。

コードレビューでは、学生が事前に四目並べを作り、そのコードをレビューいただきました。

自分は以下のコードを提出しました。

github.com

レビューを受けたのは2人で、残念ながら自分は選ばれませんでした。ですが、スライドでレビュー観点を紹介いただき、勉強になりました。

mixi git challenge番外編

mixiのエンジニア、藤田 朱門さんにGitのコアな部分を知れるクイズを出題いただきました。

問題は難しく、事前学習したものの4問中1問しか解けなかったです。Gitの内部構造を知れて、とても勉強になりました。

イベントの詳細な内容はJUNさんがブログに書かれていますので、そちらを参照いただければと思います。

jun-networks.hatenablog.com

書き初め大会

校舎で書き初めをしました。「四二東京」を書きました。

その他の活動

統計WEBの輪読会(2021年10月から継続)

今月はStep1. 基礎編の「12. 累積分布関数と確率変数の期待値・分散」まで進みました。

OSS-DB Silverの勉強会

42Tokyo外の活動で、今月末からOSS-DB Silverの勉強会に参加することにしました。

内容は『OSS教科書 OSS-DB Silver』を輪読会形式で読み進めていくというものです。

オンラインゲームを作る課題でPostgreSQLを触ることになるので、参加を決めました。

コミット時間

今月のコミット時間は153時間53分、1日平均4時間57分でした。

コミット時間の推移は以下です。

f:id:nafuka11:20220208005407p:plain

今後やること

Webサーバを作る課題を引き続きやっていきます。2月中に完成できたらと思っています。

2021年振り返り

この記事では今年やったことの振り返りをします。

やったこと

42Tokyo

カリキュラム

42Tokyoのカリキュラムでは以下の課題に取り組みました。

勉強会

数学本の輪読会に参加し、以下の本を読みました。数学は高校数学の途中までしか学べなかったので、とても勉強になりました。

  • 人工知能プログラミングのための数学が分かる本

現在は以下のサイトの輪読会に参加しています。

  • 統計WEB

アウトプット

今年から毎月の振り返り記事を書き始めました。

nafuka.hatenablog.com

あとはQiitaにたまに記事を書いてました。

qiita.com

qiita.com

課題用のスライドも作ってました。

nafuka11.github.io

その他作ったもの

ポートフォリオ的なサイトを作ってみたり、

nafuka11.github.io

課題のテスターやビジュアライザを作ってみたりしました。

テスターとビジュアライザに関しては、以下の記事にまとめてあります。

nafuka.hatenablog.com

読んだ本

以下の記事にまとめました。

nafuka.hatenablog.com

去年の目標を達成できたか

2020年振り返り - Nafuka Lines より、去年の抱負を引用します。

  • 42Tokyoの除籍システム、通称ブラックホールに吸い込まれることなく、来年中に基礎的な学習を終え、インターンに参加できるレベルに到達したいです。
  • 42Tokyoに入って、便利なツールを作ったり、データを集め眺めて分析のようなことをするのが好きと気づきました。今の環境でできることをやっていきたいです。

基礎的な学習は終えられませんでした。現在、基礎的な学習の最後の一つ手前の課題に取り組んでいます。来年には基礎的な学習を終えられるかなと思います。

便利なツールを作ったり、データを集めて分析をしたり、は継続してできているかなと思います。

終わりに

ここまで読んでくださってありがとうございます。

今年も残り短いですが、良いお年をお迎えください。

来年も頑張ります。