# Backend Engineer Roadmap ## インターネット ネットワークはなぜつながるのかの内容を簡単に咀嚼してまとめる ### 第1章 keyword: URL, プロトコル, HTTP, IPアドレス, ネットマスク, リクエストとレスポンス, DNSサーバー, ドメイン, Socketライブラリ, プロトコル・スタック, ソケット - URLの要素 - https://www.it.toshin-correction.com/nippo - httpsはプロトコル - www.it.toshin-correction.comはWebサーバー名(ドメイン名) - /nippoはデータのパス - HTTPメソッド - GETとかPOSTとか - リクエスト・メッセージに書くURLは一つだけ - 複数ファイル読み出すときは別々にリクエスト・メッセージをWebサーバーに送る - ex. あるホームページに画像が2つ必要な場合はhtml1つ,jpg2つの計3回リクエストを送ることになる - 作られたメッセージはOSがWebサーバーに送信する - IPアドレス - ドメイン名と対応したアドレス - 直感的には〇〇丁目△△番地のように住所を表す - ◯◯丁目 -> ネットワーク番号,△△番地 -> ホスト番号 - 32ビット(8ビット x 4)で表され、10進数表記を用いることが多い - ex. 10.11.12.13 (00001010.00001011.00001100.00001101) - ネットマスクを使ってどこまでがネットワーク番号で,どこからがホスト番号かを示す - ex. 255.255.255.0 (11111111.11111111.11111111.00000000) - DNSサーバー - (req)ドメイン名 -> (res)IPアドレスを行う - 流れ - Webブラウザ - Socketライブラリを呼ぶ - Socketライブラリ - DNSサーバーへのメッセージを作る - OSのプロトコル・スタックを利用 - OS内部のプロトコル・スタック - LANアダプタを介してメッセージ送信 - DNSサーバー - レスポンス(IPアドレス)を返す - 帰りは行きの逆順でデータを伝達 - ドメインの階層により情報を分散 - www.it.toshin-correction.com - Webサーバー名はドットで階層が分かれていて,それぞれがドメイン - 右にある方が上位のドメイン - ex. comドメインの中のtoshin-correctionドメインの中のitドメインの中にwwwがある - comはcommercialの略で誰でも使える - co.jpは日本の企業,ac.jpは日本の大学等教育機関が使える - 実はcomやjpの上にルート・ドメイン(.)が存在する - 流れ - ルート・ドメイン(.)のDNSサーバーがcomのIPアドレスを持つ - comのDNSサーバーがtoshin-correctionのIPアドレスを持つ - toshin-correctionのDNSサーバーがitのIPアドレスを持つ - itのDNSサーバーがwwwのIPアドレス(欲しいやつ)を持つ - キャッシュにより素早く回答 - データ送受信の流れ - ソケットを作る - Socketライブラリのsocket関数 - ディスクリプタというsocketのIDが返ってくる - サーバー側のソケットにパイプをつなぐ - Socketライブラリのconnect関数 - 入力はディスクリプタ、WebサーバーのIPアドレスとポート番号 - ポート番号によってWebサーバー側のソケットを識別できる - データを送受信する - Socketライブラリのwrite, read関数 - パイプを外してソケットを抹消する - Socketライブラリのclose関数 ### 第2章 keyword: TCP, UDP, MTU, MSS, TCPヘッダー, シーケンス番号, ACK番号, ウィンドウ制御方式 - TCPとUDP - TCP - ブラウザやメールなどの通常のアプリケーションのデータ送受信 - UDP - DNSサーバーへの問い合わせなど短い制御用のデータ送受信 - TCPヘッダー - ヘッダー - パケットの先頭部分に配置する制御情報を記載したもの - フォーマット - 送信先,宛先ポート番号 - シーケンス番号,ACK番号 - ウィンドウ - MTUとMSS - 要旨 - OSのプロトコル・スタックではネットワーク効率を担保するためにできるだけ多くのデータを1回で送ろうとする - そのために内部のバッファ・メモリーに一時的に貯める - MTU - 1つのパケットで運べるデータの最大長のこと - イーサネットでは,通常1500byte - MSS - ヘッダーを除いて,1つのパケットで運べるデータの最大長 - シーケンス番号とACK番号 - 要旨 - TCPの受信応答確認 - 送信側がシーケンス番号を,受信側がACK番号を交互に変更しながらパケットを運んでいく - シーケンス番号 - データを分割して送る際に何byte送ったかを表す - ACK番号 - データを何byte受け取ったかを表す - ウィンドウ制御方式 - 要旨 - TCPヘッダーのウィンドウで受信側が予めメモリー領域を送っておく - 送信側はACK番号を受け取る前にウィンドウの範囲内で連続で送ることが可能 - 無駄なタイムロスを減らす - 受信側はACK番号とウィンドウを相乗りさせることで無駄なパケットを送らずに済む - これをしない方式をピンポン方式と呼ぶ - ### 第3章 ### 第4章 ### 第5章 ### 第6章 [1. ネットワークはなぜつながるのか](www.amazon.co.jp/dp/4822283119) ## OSの基本的な知識 ## プログラミング言語 ### Go - 特徴 - C++以外の置き換え - コンパイラ言語のC++は言語使用が複雑すぎてバグりがち - コンパイルが速い - 文法がシンプルなので誰が書いてもほぼ同じようになる - 並列処理に強い - 文法 - ポインタ - & アドレス演算子 - 16進数のメモリアドレス(ポインタ)を取得 - `0x00000120` - 構造体の時は中身が見える - `&{"aaa", [1, 2, 3]}` - 使いどころ - 参照渡しをしたいとき - ```go n := 123 change1(n) // n = 123, 値渡し change2(&n) // n = 246, 参照渡し func change1(n int) { n *= 2 } func change2(n *int) { *n *= 2 } ``` - 構造体 - 構造体の参照渡し - 値渡しを繰り返していると巨大な構造体が量産されてメモリが尽きる - 基本参照渡しで設計するとよさそう - new - 値を生成し、そのポインタを返す - ```go type Data struct { A string B []int } d := new(Data) fmt.Println(d) // d = &{ []} ``` - make - 配列・スライス、マップ、チャンネルの初期化 - インターフェイス - 特徴 - メソッドを定義しておく - ある構造体がインターフェイスに合致していればインターフェイスに合っているとみなす - 振り分けアプリでいうAPIはBFFServiceServerインターフェイス(api_grpc.pb.go)に合致するようにgRPCメソッドを実装している - interface{} 空のインターフェイス - どんな値も保管できる型 - Anyみたいな感じ - 型アサーション - interface{}型から元の型に戻すこと - .(型)でいける - `b := a.(string)` - 並行処理 - Goルーチン - 関数の前にgoを付けて行うと別スレッドで処理を行う - スレッド間の値のやり取り - 共有メモリ - 別スレッド間で値を共有して使う - 関数が呼ばれたときの値を使う - チャンネル - 型を指定してどの型の値を保管するか決める必要がある - `ch := make(chan 型)` - 値の追加 - ch <- 値 - 共有メモリとは違い、チャンネルから値を取得するとき、値が送られてくるまで処理を待つ - チャンネルは一方通行 - 双方向にする場合は、二つチャンネルを用意 - スレッドの排他処理 - あるスレッドが変数にアクセスしているときに、別のスレッドがその変数を書き換えないようにロックすること - sync.Mutexを利用 - 中井さんのライブコーディングではsync.RWMutexを利用してた ### 3つのパラダイム - 構造化プログラミング - 直接的な制御の移行に規律を課す - goto文の廃止 - 順次、選択、反復に機能分割できる ![](https://i.imgur.com/JVzzN3L.png) - オブジェクト指向プログラミング - 間接的な制御の移行に規律を課す - 関数ポインタの使い方に規律を課している - ポリモーフィズムが大事 - 依存性逆転 ![](https://i.imgur.com/Jvf1nIu.png) - 関数型プログラミング - 代入に規律を課す - 代入による副作用を抑止 ### 参考リンク [1. Go言語ハンズオン](https://amzn.to/3VXI35q) [2. Clean Architecture](https://amzn.to/3PbfoHW) [3. 構造化プログラミング](https://yaminokurao.com/main/?p=535) [4. 依存性逆転](https://zenn.dev/naas/articles/c743a3d046fa78) ## リレーショナルデータベース ## NoSQLデータベース ## データベースをより詳しく ## API ## キャッシュ ## WEBのセキュリティ ## テスト ## CI/CD ## デザインと開発の原理 中間レベル(関数やクラスレベル),コンポーネントレベル,アーキテクチャレベルの3つのレベルでの原理を紹介する ### SOLIDの原則 以下の性質を持つ中間レベルのソフトウェア構造を作るガイドライン - 変更に強い - 理解しやすい - コンポーネントの基盤として,多くのソフトウェアで利用できる #### 単一責任の原則(SRP) 1つのクラスは1つの役割 アクターの異なるコードは分割すべき #### オープン・クローズドの原則(OCP) クラスは拡張にはオープンで、変更にはクローズドであるべき 上位レベルのコンポーネントが下位レベルのコンポーネントの変更の影響を受けないように #### リスコフの置換原則(LSP) 子クラスは親クラスと同じ動作ができるべき 有名な違反例 -> 正方形・長方形問題 これに違反すると特別な仕組み(例えばif文)が必要になってしまう #### インターフェース分離の原則(ISP) インターフェースは可能な限り小さい単位に分離する 必要ないお荷物を抱えたものに依存すると予期せぬトラブルにつながる #### 依存性逆転の法則(DIP) 上位モジュールは下位モジュールに依存せず、それぞれ抽象に依存すべき ### KISSの原則 - Keep It Short and Simple - コードはとにかくシンプルに ### YAGNIの原則 - You Aren't Going to Need It - コードは必要になってから実装する ### DRYの原則 - Don't Repeat Yourself - 同じコードは重複して書かない ### PIEの原則 - Program Intently and Expressivery - コードは書いた意図を明確にしながら書く ### 参考リンク [1. ソフトウェア開発における原則](https://zenn.dev/cohky/articles/development-principles) [2. SOLID原則](https://umatomakun.hatenablog.com/entry/2018/12/06/233610) ## アーキテクチャパターン ### モノリシック - 特徴 - アプリケーションを1つのコードベースで構築 - 従来型のモデル - メリット - 開発速度が速い - デプロイが簡単 - デバッグが簡単 - デメリット - 大規模になると開発速度が遅い - スケーラビリティ - 信頼性 - フレームワークや言語の変更のしづらい - 少しの変更で全部デプロイし直す必要 ### マイクロサービス - 特徴 - 別々の目標を持つサービスという単位ごとにコードベースを構築 - メリット - 柔軟なスケーリング - 継続的なデプロイ - 新機能の投入のしやすさ - 個々のサービスの障害やバグの特定性 - 独立デプロイ - 高い信頼性 - デメリット - モノリスより複雑 - インフラコストの指数関数的増加 - 組織的なオーバーヘッドの増加 - 標準化の欠如 - サービス所有権の欠如 ### モジュラーモノリス - 特徴 - 独立して作業可能なモジュールという単位で構成され、デプロイ時に結合 - モノリスとマイクロサービスの良さを両立 - モノリスの良さ - 単一のデプロイラインで - マイクロサービスの良さ - システムのモジュール化・独立性 - メリット - モジュールの境界が明確であれば独立して作業可能 - マイクロサービスの複雑性、コスト面でのデメリットの緩和 - 将来的なマイクロサービス移行容易性 - デメリット - デプロイ・デリバリー衝突 - 境界違反がマイクロサービスより容易 - E2Eテストの実行時間の増大 - DB共有によりDB周りのモジュール性が失われる可能性 ### BFF - 特徴 - クライアントとバックエンドの中間で、双方の複雑性を吸収するためのサーバー - メリット - APIの集約化 - バックエンドの仕様の差異を吸収 - フロントエンドとバックエンドの分離 - デメリット - 追加された分のサーバーの開発と保守の手間 - 通信料の増大と遅延 - コードの冗長化 ### 参考リンク [1. モノリシック vs マイクロサービス](https://www.atlassian.com/ja/microservices/microservices-architecture/microservices-vs-monolith) [2. モジュラーモノリスについてまとめる](https://r-kaga.com/blog/what-is-modular-monolith) [3. BFFとはなんなのか?](https://qiita.com/souhei-etou/items/d5de99bb8cba1c59d393) ## GraphQL ### GraphQLの基本 - 特徴 - クエリをPOSTしてデータを取得 - RESTでいうリソースをGETすることにあたる - グラフで関連するデータを1回で取得可能 - クエリには、「構造」と「構文」がある - ステータスコードは常に200、エラーはレスポンスボディを参照 - メリット - 過剰取得の回避 - API呼び出し頻度の抑制 - セルフドキュメンテーション - デメリット - 比較的新しいため情報量が少ない - キャッシュが複雑になる ### 参考リンク [1. GraphQLとRESTの比較](https://hasura.io/learn/ja/graphql/intro-graphql/graphql-vs-rest/) ## webサーバー ## インフラ ## AWS ### Amazon SNS - 特徴 - フルマネージドなPub/Subメッセージングサービス - Publisher -> Topic -> Subscribers - 機能/非機能 - Pub/Sub機能 - メッセージフィルタリング - アクセスコントロール - IAMやリソースポリシーで権限を制御 - リトライ処理 - メリット - 非常に多くのメッセージを安全かつ確実、柔軟に多くの宛先に配信可能 - デメリット - 受信したメッセージを即座に宛先に配信 - Pubが高速、Subが低速の場合に大問題 ### Amazon SQS - 特徴 - フルマネージドなキューサービス - Producer -> Queue -> Consumers - 機能/非機能 - キューとしての機能 - 標準キュー - ショートポーリング - ロングポーリング - FIFOキュー - デッドレターキュー - 一定回数以上連続して失敗したメッセージの墓場 - 別の方法で処理、処理に失敗した原因を分析 - 可視性タイムアウト - 二重処理防止策 - 遅延キュー/メッセージタイマー - enqueue後、遅延させてからConsumerに渡す - 事前準備の機関の確保が必要な場合に利用 - アクセス制御 - IAMまたはSQSのリソースポリシーを用いて権限制御 - Producer・Consumer両方制御可能 - メッセージ暗号化 - メリット - メッセージのバッファリング - キューで処理待ち - 並列性の向上による処理性能向上 - Amazon SNSと組み合わせてリトライ可能な非同期処理を作れる ### AWS Lambda - 特徴 - イベント駆動で起動して処理を実行 - 機能/非機能 - コードの実行環境を提供 - 高スケーラビリティ、高耐障害性 - ゼロメンテナンス、高コスト効率 - メリット - EC2と比べて手軽 - 起動パターン - Request Responseベース - 非同期イベントベース - Stream Pollingベース - Queue Pollingベース - 考慮すべき点 - リトライ、同時実行数、コールドスタート - 冪等性 - at least oneなので稀に2回以上呼ばれる ## GCP ### cloud pub sub ### 参考リンク [1. Amazon SNSとAmazon SQS](https://speakerdeck.com/recruitengineers/awsyan-xiu-amazon-snstoamazon-sqs) [2. SQSについて徹底解説](https://ya6mablog.com/aws-sqs/) [3. Amazon SQSを使用したLambdaの非同期処理](https://business.ntt-east.co.jp/content/cloudsolution/column-try-22.html) [4. AWS Lambda](https://speakerdeck.com/recruitengineers/awsyan-xiu-aws-lambda) ## 監視 ### インフラ監視 ### アプリケーション監視 ### ログ管理 ## スクラム - 5つのイベント - スプリント - スプリントプランニング - デイリースクラム - スプリントレビュー - スプリントレトロスペクティブ - 3つのロール - プロダクトオーナー - 開発チーム - スクラムマスター - 3つの作成物 - プロダクトバックログ - スプリントバックログ - インクリメント ## フロント ### React - 3つのコアコンセプト - Components - LEGOブロックのように扱える - 関数として定義 - Props - Componentsの引数 - 読み取り専用の情報 - State - 時間の経過とともに変化する情報 ``` const [likes, setLikes] = React.useState(0); ``` ### Next.js Reactフレームワーク