Web系エンジニア5年目にやったこと

去年のは[こちら](https://qiita.com/yokoto/items/796f5c309bcee1f76479
)。

# 2023年振り返り
## 1 ~ 6月

### 新しい現場
1月から新たな現場に入った。
アプリケーションのエンジニアとして、担当領域はバックエンド/フロントエンドの境がなく、どちらかというとフロントの比重の方が多くなった。

バックエンドはこれまでも経験していたRailsではあったが、
フロントエンドはReact 18、TypeScript、デザインシステム、アクセシビリティと、色々と新たな学びがあった。

一方で、アプリケーションのエンジニアはインフラの新規リソースを構築したり改善を行う機会が無さそう（基本的にはインフラチームが責務を持ち分業されている形）だったため、そういう機会が欲しいと感じるところがあった。

インフラの新規リソースを構築したり改善を行う機会が欲しいと感じるようになった理由は後述。

### 情報科学基礎の学習
#### 動機

もうエンジニアとして働き始めて5年目に入るが、うち3年はフリーランスとして活動しているので、自分のキャリアやスキルについて（同時期にエンジニアを始めた友人と話をすることはあるものの、）アドバイスをくれる上司やメンターがいるわけではなく、5年目相当のスキルが身についているか、や、単価が今の自分の技術力の割に高めではないか、というあたりで少し不安を感じているところがあった。

Twitterで色々な方の発信を物色するうち、有名企業の面接に合格できるような経験を積む・知識をつけることによって不安が解消されるのではないかと思うようになった（考え方としてよりビジネス寄りの人であれば、働き方を変えてマネタイズを考える人もいると思うが、自分としてはエンジニアとしてより知識を身につけたり、技術力的なものを高めていく方に関心があった）。

#### 学習内容

有名企業の面接に合格できるような知識は、
情報処理技術者試験の範囲を[対策本](https://amzn.asia/d/7FA7FAw)を見たり、
外資面接対策ガイドの [InterviewCat](https://x.com/InterviewCat582) 
を買って学習範囲の目処を立てた。

新たな現場では採用技術やドメイン知識のキャッチアップをするかたわら、プライベートで情報科学基礎的な学習を進めていった。

##### DB・分散システム

[30分でわかるデータ指向アプリケーションデザイン](https://forkwell.connpass.com/event/269125/) のLTを聴講したのをきっかけに、

* [分散データシステム入門の決定版『データ指向アプリケーションデザイン』をたった30分で学んでみた](https://dev.classmethod.jp/articles/report-on-designing-data-intensive-applications/)
* [MIXIの新卒DB研修のスライド](https://speakerdeck.com/mixi_engineers/2022-database-training)

を参考に、以下の記事を書いた。

* [データベース入門（アーキテクチャ・分散のさわり） - Qiita](https://qiita.com/yokoto/items/45294617d0e348d454b5)

2023年は、ネットワークやOSの勉強と比べるとDB・分散システムに時間をかけて勉強することができていなかったように感じるので、2024年はもう少し比重を上げたい。ACIDやトランザクション分離レベルを説明できるように復習するところから。

##### アルゴリズム

* [問題解決力を鍛える!アルゴリズムとデータ構造](https://amzn.asia/d/bkw88qR)
* [問題解決のための「アルゴリズム×数学」が基礎からしっかり身につく本](https://amzn.asia/d/70RVgzs)

を、それぞれ1/3程度読んだ。

「問題解決力を鍛える!〜」を読み進めながら、（自分の基礎学力的な問題で）理解が難しかった部分は「問題解決のための「アルゴリズム×数学」〜」を読むことで、理解ができたように思う。
後者の本は自分のように高校数学がほぼわからないレベルでも、アルゴリズムの本が読めるレベルまでの知識を埋めてくれる、非常にありがたい本だった。

ただ、疲れてしまい1/3程度しか読み進められなかったので、来年はもう少し読み進めたい。

計算量の話がコードレビューでできるようになったのは、今年の進歩だったなと思う（例えば、ここがO(n^2)なので、ハッシュ（マップ）を使ってO(1)にしましょう、など）。

##### ネットワーク

* [マスタリングTCP/IP　入門編（第6版）](https://www.ohmsha.co.jp/book/9784274224478/)
* [Amazon Web Services 基礎からのネットワーク＆サーバー構築　改訂版](https://bookplus.nikkei.com/atcl/catalog/17/261530/)
* [ByteByteGoのYouTube](https://www.youtube.com/@ByteByteGo)

などを参考に、

* [ネットワーク（TCP/IP）入門 - Qiita](https://qiita.com/yokoto/items/3b7dc79b750dcf6fc810)

を書いた。

恥ずかしながらOSI参照モデルを始めて学んだのが2023年だった（それまでは聞いたことがあるレベルだった）。これを知らないとネットワーク（TCP/IP）の全体像が掴めるようにはならない概念であることを理解した。
「Amazon Web Services 基礎からのネットワーク＆サーバー構築」は（AWS環境で仕事をしている人にとっては特に）ネットワークの説明がわかりやすいおすすめの本。3wayハンドシェイクや、DNSの名前解決の仕組み（ルートサーバー→TLDサーバー→権威サーバー）まで言及がある。

##### OS

* [詳解 システム・パフォーマンス 第2版](https://www.oreilly.co.jp/books/9784814400072/)

などを参考に、

* [Linuxシステム入門 - Qiita](https://qiita.com/yokoto/items/a2536bd1b81b42479bba)

を書いた。

OS（Linux）の学習を始めるにあたって、前提となるハードウェアとしてのコンピュータのアーキテクチャについての知識が無かったし、必要だったなと感じる。
[コンピュータの構成と設計 第6版（上・下）](https://bookplus.nikkei.com/atcl/catalog/21/S70090/)などの本をさらっと読んだりGoogle検索して出てきたブログ等を読むことで「コンピュータの5大装置」などから学んでいった。

それによって初めてLinuxについての学習も頭に入ってくるようになったし、実務でも「CPU使用率」や「メモリ使用率」などのメトリクスが表しているものが、自分の理解としてより明確になった。

##### セキュリティ

Rails特化ではあるが、
* [Railsセキュリティガイド](https://railsguides.jp/security.html)

を参考に、
* [Railsセキュリティガイドのサマリ - Qiita](https://qiita.com/yokoto/items/ff0ec48775b5dc63f24a)

これは、12月に受けた面接で、「セッションとはなんですか？」「Cookieのセキュリティを高めるためにどのようなことが必要ですか？」といった質問に十分に答えられなかったため復習する意図で書いた。

そんなにいいねはついていないが、個人的には割といいまとめになっていると思う。
一方で、このセキュリティガイド自体がSPAやマイクロサービスのトレンドを踏まえると内容が古く感じるので、Railsという角度から以外でもセキュリティを学ばないといけないとは感じる。

#### 学習スタイル

これまでは、

* 読みたい本を1冊決める
* 1日に読み進める範囲（30ページ/1章など）を決める
* どれくらいの期間で読み終えるか（2ヶ月/半年など）を決める
* 自分専用ノート（Qiitaなど）に書き出しながら読み進める

という形で進めていたが、進めるのに気合いが必要だった。
今年は形を変え、以下のように進めていた。

* 学習したい分野（上述のような）を決める。
* 学習したい分野に関連する本を大量に（3 ~ 10冊くらい）買う。
* 購入した本の同じ内容についての説明を比較しながら、説明を取捨選択する
    * いつまでに終えるかを具体的には決めず、できるだけ時間をかける
    * 頭から読まない。目次を参照することが多くなる。
    * 複数の本に記述されている内容は重要であることが認識できる
    * 理解が合っているかはChatGPT4に適宜質問
* 自分専用ノート（Qiitaなど）に重要なところから書き出しながらまとめる
    * 説明がおかしくないかはChatGPT4に適宜質問

今年の方法だと、こっちの本ではこういう説明だが、こっちの本ではそういう説明なのか、という風に複数の本を眺める中で自然に記憶されていき楽しく進められるのと、複数の本の目次や見出しを繰り返し比較していると体系が意識されるようになり、定着しやすい感覚があった。
あとは、いつまでに終えるかといった細かい学習計画を立てないようになった。むしろ、早く終わらせようとせずに、時間を多くかけて納得感を大事にしながら進めるようにした。こうすることで学習に着手するプレッシャーやストレスがかからないようになり、楽しく学習できるようになったし、継続する分結果として学習効率も良くなったと思う。
元々、自分専用ノート（Qiitaなど）に書き出しながらでないと学習が進められなかったが、金銭的に余裕も出てきて書き出し元を1冊から複数冊にしてみたことで、このような学習スタイルに辿り着いた。
本の購入費用がかさむようにはなったが、続けやすいので、今後もこの学習スタイルで続けてみようと思う。

個人的にコペルニクス的転回だったので、紹介してみました。

## 7 ~ 12月

### 新しい現場

先述の有名企業の面接について調べる中で、ソフトウェアエンジニアの採用面接で、"システムデザイン（システム設計）"を課している企業は、ソフトウェアエンジニアに（単にアプリケーションのコードを書くだけではなく）インフラの新規リソースを構築したり改善ができるスキルを求めていると思ったし、自分にはそういうスキル・経験が不足しているように感じていた。

そこで、前職の同僚が声をかけてくれた会社に参画することにした（先の現場は、結果としては自分最速の半年で退場することになった）。
新しい現場は、サーバーレスベースのマイクロサービス環境で、新規のプロダクトが早いペース（3~6ヶ月に1個くらい）で立ち上がり、1人1プロダクトくらいの大きな裁量でフルサイクルに開発をしているので、システム設計のスキルが高められる環境だと感じた。

今年は、Webアプリケーションの基本的なインフラ構成を通貫して触ることができた。
触ったAWSリソースは以下の通り。

Webアプリケーションの基本的なインフラ構成として

* Route53
* WAF
* S3
* CloudFront
* API Gateway
* Lambda / ECS（Fargate）
* RDS Proxy
* RDS Aurora（PostgreSQL）

その他

* IAM
* EventBridge
* SQS
* Cognito
* CodePipeline
* CodeBuild
* CloudWatch Logs / Metrics
* Secret Manager
* System Manager（Parameter Store）
* KMS
* CDK
* CloudFormation

あとは自分のフルスタック志向を尊重してもらって、さまざまなプロダクトのさまざまな言語（バックエンドGo / Rails、フロントエンドNuxt.js / Next.js ）で開発に携わることができた。

Next.jsについてはApp Router採用等でチームで議論があったので、Reactアプリケーションについての翻訳記事も書いたりした。

- [React再レンダリングガイド: 一度に全て理解する - Qiita](https://qiita.com/yokoto/items/ee3ed0b3ca905b9016d3)
- [Next.jsのプロジェクト構成とファイルコロケーション - Qiita](https://qiita.com/yokoto/items/c3b0145fe0990948e1ec)

React関連では、割と最近の（※変化が速いため何をもって最近とするかは難しいが）色々なライブラリに触ることができて良かった。
e.g. react-hook-form, yup, swr, recoil, jotai, apollo/client

また、AWSリソースも色々と触ることができたので、AWS関連の記事も書けると良かったなと思う。

とくに、IDaaS（Cognito）を使用した認証が何をやっているのかは、既存プロダクトの仕様理解のうち自分にとっては結構苦労した点で、「[Auth屋さんと学ぶ 仕様が読めるようになる OAuthとOpenID Connect 入門](https://offers.connpass.com/event/295782/)」に参加することで初めて理解できた気がするような体験もあり、何かしら記事としてまとめられれば良かった。

今回の現場を踏まえて、システム設計力を効率良く伸ばす環境選びという点では、「マイクロサービス」「裁量が大きい（フルサイクル）」「開発生産性が高い（新規プロダクトの立ち上げペースが速い）」あたりがキーになりそうかなと感じた。

来年も引き続きお世話になるので、裁量の大きさは責任の大きさだと認識して、引き続き気を引き締めて頑張っていかないとなと思う。

### ISUCON

駆け出し時代の友人と一緒に、11月にあったISUCON13に参加した。
自分は去年に続き2回目の参加だった。
去年同様、準備・対策として開催日の1ヶ月前くらいから、過去問を解いてみたり、「[達人が教えるWebパフォーマンスチューニング 〜ISUCONから学ぶ高速化の実践](https://gihyo.jp/book/2022/978-4-297-12846-3)」の気になる章を読み進めた（若干余談だが、この本のうちOSのチューニングの章などいくつかの章は、自分の基礎知識不足でなかなか読み進められなかった。が、大会後に情報科学基礎の学習を進めたあとで読んだとき、頭に入ってくるようになり自分の成長を感じたりした）。

大会のスコアは5,778だった（去年は3,999）。

終わってみて、もう少し良いスコアが取れたら良かったなとは思う。
[ISUCON13の解説](https://isucon.net/archives/58001272.html)によると、DBに必要なインデックスを追加するだけで10,000は超えたはずなので、必要なインデックスを全て把握できなかったということだし、これくらいは出来ていたかった。

また、インデックス追加以外では、GoのN+1解消をメインでやっていて、去年よりは（7月からの現場ではバックエンドのメイン言語として触っていることもあり）Go力の向上を感じたが、もう少し実装力・コードリーディング力があれば競技時間内に解消できる箇所がまだいくつかあったなと感じる。

とはいえ気負いすぎると疲弊するので、来年も記念参加したい。

去年と比べた成長点

* alp でのアクセスログ解析ができた
* git 管理するようになった
* Goの実装力が向上した

来年やりたいこと

* EC2でのエディタの初期設定の簡略化
* より高いGoの実装力をもっての参加
* サーバー分割
    * 近年のISUCONでは3台のEC2が用意されるため、
CPU使用率を見て、例えばAPサーバー2台、DBサーバー1台というようにサーバー分割を行えるとスコアが大きく向上するらしい。

なお、今回のISUCONでは[DNS水責め](https://b.hatena.ne.jp/entry/s/kazeburo.hatenablog.com/entry/2023/12/02/235258#bbutton)が話題になっていましたが、自分はそれを話題にする以前のレベルだったので、次回はそういった話題に共感できるくらいに健闘できたら万々歳だなと感じている。。

# 最後に

今年は自分のエンジニアスキルとして不安に感じていたシステムデザイン的な分野のイメージが7月からの現場で経験を積ませてもらったことで少しつくようになったり、情報科学基礎の学習を始められたりしたことで、脱ジュニア・ミドルレベルの一歩を踏み出せた年だったと思う。

来年は今年の継続で、今年学習した内容や経験をより深めていくのが大事かなと感じる（42tokyoの体験談とかを見ると、C言語の勉強もいいなとか感じる。が今だけかも）。

あとは、余裕があれば自分の力試しとして、情報処理技術者試験やAWSの認定試験、企業面接も受けてみたりしてもいいかなと思う（AWS SAAは[3年前](https://qiita.com/yokoto/items/161d749fbb169de53e73)に受けたが、丸暗記スタイルで受けたせいでほぼ内容を覚えていない）。

おまけで、今年受けた面接で聞かれた質問を書いておきます（他にもあった気がするが忘れてしまった）

* NoSQLの経験はありますか
    * key-valueストアだけでなく、ドキュメント指向のNoSQLの経験はありますか
* RDBとNoSQLの違いについて教えてください
    * メリットとデメリットはなんですか
    * どうするのが良いと思いますか
* DDDについての経験はありますか