OmniAICreator/Qiita-1.07M huggingface dataset:
C_TS422_2021 SAP Certified Application Associate SAP S/4HANA Production Planning and Manufacturing対策（75/100）

【75日目】
トピック 8：SAPS/4HANAの製造指図（7/15）

≪問題75≫
一括指図の目的は何ですか。
□製造指図ではなく原価コレクタに製造原価を転記すること
□連産品と副産物の指図管理を主要製品と組み合わせること
□指図確認ありの単一バックフラッシュとして構成品目引落を転記すること
□複数レベルにある最終製品全体の製造指図を管理すること

≪解答≫
□製造指図ではなく原価コレクタに製造原価を転記すること
□連産品と副産物の指図管理を主要製品と組み合わせること
□指図確認ありの単一バックフラッシュとして構成品目引落を転記すること
■複数レベルにある最終製品全体の製造指図を管理すること

≪解説≫
◆一括指図は、最終製品全体の製造指図を多段階で一括管理するための唯一のオプションであり、指図の複数のレベル（指図間）に対してさまざまな機能を使用することができます。
◆品目マスタに特殊調達キー52（直接生産/一括指図）が設定されているBOM構成品目に対して、個別のサブ指図が登録されます。
◆一括指図の利点は、以下の通りです。
（1）指図の計画、管理、および更新に必要な労力が少なくなります。
（2）一括指図の個別のレベル間での自動在庫移動が可能となります。
（3）以下のビジネス機能を実行することができます。
　- 日付および数量の変更
　- 利用可能在庫の確認
　- 指図の発行
　- 確認
Sliding Window アルゴリズムを利用した問題解決

## LeetCode 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3824062/2916d7f2-414e-ad35-e982-f90b651560e0.png)

https://leetcode.com/problems/longest-substring-without-repeating-characters/

#### 目的
与えられた文字列において、重複する文字がない最長部分文字列の長さを求めるアルゴリズムを改善します。このためにスライディングウィンドウ手法を使用します。

#### 初期コードの問題点
初期コードでは、重複する文字が見つかるたびに`left`ポインタを重複する文字が位置するインデックスの次の位置に移動させる方式で最長部分文字列を計算しています。しかし、この過程で`left`ポインタが非効率的に移動する可能性があります。

#### 改善されたアルゴリズム
改善されたアルゴリズムは、重複する文字が見つかった場合、`left`ポインタを一度にジャンプさせて移動することで効率を向上させます。

#### アルゴリズムの詳細な説明

1. **ポインタおよび変数の初期化**:
    - `left`と`right`ポインタをそれぞれ文字列の開始位置（0）に初期化します。
    - `max`変数を0に初期化して最長部分文字列の長さを保存します。
    - 各文字の最後の位置を保存するために`map`を使用します。

2. **スライディングウィンドウ**:
    - `right`ポインタが文字列の末尾に達するまでループします。
    - 現在の文字が`map`に既に存在する場合、`left`ポインタを重複する文字の次の位置に移動させます。このために`left = Math.max(left, map.get(currentChar) + 1)`を使用します。
    - 現在の文字の位置を`map`に更新します。
    - 現在のウィンドウの長さ（`right - left + 1`）と比較して`max`値を更新します。
    - `right`ポインタを増加させます。

3. **結果の返却**:
    - 最終的に計算された`max`値を返します。

#### コード
```java
public static int lengthOfLongestSubString(String s) {
    HashMap<Character, Integer> map = new HashMap<>();
    int left = 0;
    int right = 0;
    int max = 0;

    while (right < s.length()) {
        char currentChar = s.charAt(right);
        if (map.containsKey(currentChar)) {
            // leftを現在の値とcurrentCharの最後の出現の次の位置の最大値に更新
            left = Math.max(left, map.get(currentChar) + 1);
        }
        // 現在の文字のインデックスでmapを更新
        map.put(currentChar, right);
        // 見つかった最大の長さを更新
        max = Math.max(max, right - left + 1);
        right++;
    }

    return max;
}
```

#### 改善された部分
1. **ポインタ移動の最適化**:
    - `left`ポインタが重複する文字の次の位置に一度にジャンプして移動します。
    - `Math.max(left, map.get(currentChar) + 1)`を使用して`left`ポインタが非効率的に移動するのを防ぎます。

2. **効率的なメモリ管理**:
    - `map`を使用して各文字の最後の位置を記録し、重複する文字の検査を効率的に行います。

3. **時間計算量**:
    - このアルゴリズムは文字列を一度だけ巡回するので、時間計算量はO(n)です。

この改善されたアルゴリズムは、重複する文字がない最長部分文字列の長さを効率的に計算し、スライディングウィンドウとハッシュマップを活用して性能を最適化しています。
Next.jsのtutorialをやるDockerの環境が欲しい

# やりたいこと

https://nextjs.org/learn/dashboard-app/getting-started

これを始めようと思ったけど、とにかく自分のパソコン（以下ホストマシン）でnodeやらnpm i などやら実行するのが嫌なので、Dockerでコンテナを立てるまでの記録です。
めちゃくちゃ簡易に作成したものなので色々不足はありますが最低限の構築として。

## 目標
Getting Startedの以下のコマンドをコンテナ内で実行する
```
npx create-next-app@latest nextjs-dashboard --example "https://github.com/vercel/next-learn/tree/main/dashboard/starter-example" --use-pnpm
```

## 手順
### 構成の準備
```
nextjs-dashboard
├── Dockerfile
└── docker-compose.yml
```


``` Dockerfile:Dockerfile
FROM node:18.17.1

WORKDIR /app
```

``` yaml:docker-compose.yaml
version: '3'
services:
  app:
    build:
      context: .
    volumes:
      - .:/app
    tty: true
    ports:
      - "3000:3000"

```

このtty: true が肝なんですよね。今回run devとかしないでコンテナ内で色々やりたいので、これを書かないと起動した瞬間終了してしまいます。
初めて使うけど、本来の用途なのかは不明です。とりあえず「コンテナ内で仮想ターミナルを有効にして、コンテナが終了しないようにする設定」という認識でいいと思います。

### コマンド

こちらの記事を参考にさせていただきました。

https://zenn.dev/tanaka_gaku/articles/7eb377dc3b1703

```
docker-compose build
docker-compose run --rm app sh
```
これは「一時的にコンテナを起動して、shシェルを実行し、終了後にそのコンテナを自動的に削除するよ」という事です。
シェルに入ると思うので、その中で以下実行します。

```
npm install -g pnpm
npx create-next-app@latest nextjs-dashboard --example "https://github.com/vercel/next-learn/tree/main/dashboard/starter-example" --use-pnpm
```

以上で完了です。

## まとめ
ホストマシンに何も入れたくない自分みたいな人間は割とよくやる事になりそうな手順でしたので、備忘録までに投稿しました。
tty: true くんはこの後どうなるのでしょうか。そして彼の行方を知る者はどこにも居ませんでした。
WireGuardで最適なMTU値はいくつなのか？

# 結論
ISP超えるなら1400、網内折り返しならそれ以上いける(と思われる)。

# 理由
下記条件で測定しまくった結果です。
大阪:フレッツ光クロス 10G(終端2.5G収容/自作OpenWrtルータ) ISP:21ip 固定IP
神戸:NURO光 2G(終端1G収容/FortiGate 50E OpenWrtルータ)
MTUあたり10回iperf3測定した平均値を使用

| MTU値 | 速度 |
|:-:|:-:|
| 1500 | 27Mbps |
| 1450 | 61Mbps |
| 1420 | 392Mbps |
| 1410 | 348Mbps |
| 1400 | 413Mbps |
| 1390 | 403Mbps |
| 1380 | 371Mbps |
| 1300 | 365Mbps |

インターネット直結状態で(WireGuardを通さないで)測定した場合常に800Mbps以上出たので暗号化・復号化処理でCPUが足を引っ張っているのかな…
[国外でも似たような結果が出ている](https://gist.github.com/nitred/f16850ca48c48c79bf422e90ee5b9d95
)ので1400が最適っぽい気がする。
【Python3】みんなでしりとり (paizaランク B 相当)をやってみた

https://paiza.jp/works/mondai/b_rank_skillcheck_archive/word_chain

```python
# coding: utf-8

# 入力を受け取る
N, K, M = [int(i) for i in input().split()]  # しりとりをする人数、単語リストの数、しりとりの発言数を取得
d_dict = {input() for i in range(K)}  # 単語リストをセットに格納
m_list = [input() for i in range(M)]  # しりとりの発言ログをリストに格納
n_list = [i + 1 for i in range(N)]  # プレイヤーの番号リストを作成

n = 0  # 現在のプレイヤーのインデックス
flg = 0  # 直前のプレイヤーがルールを破ったかどうかを示すフラグ

# しりとりの発言を順番に処理する
for i in range(len(m_list)):
    z = ""  # ルールを破ったプレイヤーの番号を格納する変数
    if m_list[i] in d_dict:
        d_dict.remove(m_list[i])  # 発言された単語を単語リストから削除
        if m_list[i][-1:] == "z":  # 発言が "z" で終わる場合
            z = n_list[n]
            flg = 0
        elif flg == 1 and m_list[i-1][-1:] != m_list[i][:1]:  # 前の単語の末尾と現在の単語の先頭が一致しない場合
            z = n_list[n]
            flg = 0
        elif flg == 0:  # ルールに従っている場合
            flg = 1
    else:
        z = n_list[n]  # 単語がリストに存在しない場合
        flg = 0

    # 次のプレイヤーに移動
    if flg == 1 or n == len(n_list) - 1:
        if n >= len(n_list) - 1:
            n = 0
        else:
            n += 1

    # ルールを破ったプレイヤーをリストから削除
    if z != "":
        n_list.remove(z)

# 最後に残ったプレイヤーの数と番号を出力
print(len(n_list))
for i in n_list:
    print(i)
```

### 説明
1. **入力の取得**
   - `N`, `K`, `M`を取得し、それぞれしりとりをする人数、単語リストの数、しりとりの発言数を示します。
   - `d_dict`は単語リストをセットとして格納します。
   - `m_list`はしりとりの発言ログをリストに格納します。
   - `n_list`はプレイヤーの番号リストを作成します。

2. **しりとりの進行**
   - しりとりの発言を順番に処理します。
   - 各発言が単語リストに含まれているかを確認し、含まれていればセットから削除します。
   - ルールに従っているかどうかをチェックし、従っていない場合はプレイヤーをリストから削除します。

3. **プレイヤーの管理**
   - 現在のプレイヤーのインデックス`n`を管理し、次のプレイヤーに移動します。
   - ルールを破ったプレイヤーの番号をリストから削除します。

4. **結果の出力**
   - 最後に残ったプレイヤーの数と番号を出力します。

このプログラムは、しりとりのルールに基づいてプレイヤーが脱落する過程をシミュレートし、最終的に残ったプレイヤーのリストを表示します。
RustでC++のoverrideみたいなこと

トレイトのprovidedなmethodを書き換えられることに気づきました。この書き換えはC++のoverrideと同様に利用できそうです。
```rust:main.rs
trait Base {
	fn func_a(&self) {
		println!("func_a from BaseClass");
	}
	fn func_b(&self) {
		println!("func_b from BaseClass");
	}
	fn call_functions(&self){
		self.func_a();
		self.func_b();
	}
}
struct BaseStructure{}
impl Base for BaseStructure{}

impl Base for DerivedStructure {
	fn func_a(&self) {
		println!("func_a from DerivedClass");
	}
}
struct DerivedStructure {}

fn main() {
	let base = BaseStructure {};
	base.func_a();
	base.func_b();
	base.call_functions();
	let derived = DerivedStructure {};
	derived.func_a();//func Aだけ書き換えられる．
	derived.func_b();
	derived.call_functions();
}

```

```shell_session
$ cargo run main
func_a from BaseClass
func_b from BaseClass
func_a from BaseClass
func_b from BaseClass
func_a from DerivedClass
func_b from BaseClass
func_a from DerivedClass
func_b from BaseClass
```
GitHub Organizationのprivate repositoryのみクローンやプッシュができない

# はじめに
こんにちは、hatomato([@hatomato0920](https://x.com/hatomato0920))です。
今回はprivate repositoryのcloneごときで3日を費やしたお話をします。

## 発覚した経緯
今回私は所属サークルで行ったCTFの問題をGitHubに上げるため、自身がorganizationのオーナーである状態で、自身で作成したorganization private repositoryをcloneしようとしたところ、permission deniedと言われ弾かれました。

ちなみにそのリポジトリはこれです。
https://github.com/IPFactory/WelcomeCTF2024

## 結論
**認証ができていない**のが問題だと思います。

私は認証のために参照するssh鍵が間違ってました
```
id_rsa_github => id_rsa
```
![github org1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348724/01f3011e-abb9-9d95-db1a-1741c29a91a1.png)
![github org2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348724/bff68a32-899d-dbac-f1de-c32c84eff3d5.png)

同じような症状の人はとりあえずここ一回確認してみるといいと思います。

これはgithubがいらなかったという書き方の問題ではなく、私は鍵を複数作成しており、`id_rsa_github`はAPIキーの鍵でした。

![スクリーンショット (591).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348724/84448591-3342-0464-ab86-98b7abf1f9f0.png)
<font color="gray">Settings/Developer Settingsから飛べる、APIキーの発行</font>

![github org3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348724/36778819-7ca9-98e4-26b2-b336dbe79fb3.png)
<font color="gray">本来参照すべき鍵はこっち</font>

<details><summary>その他試したこと&当時のメモ</summary>
publicのOrgリポジトリのクローン〇,
 他人のprivateリポジトリのクローン〇,
 vscode本体のみ削除×,
 git for win 削除×,
 git本体 & vscode全削除×,
 git & vscode全削除　PC再起を求められるも失敗,
 でも自分のデスクトップPCならクローンできた,
 ほかのcolaboraterは正常にクローン出来ている,
 毎回以下のコードを入れないと、Git bashでもpermission deniedと言われる

```bash
$ eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_rsa
```
</details>

## 終わりに

ちなみにIDとpasswdをつけての接続はできました。
なのでcloneもpushもできないことはなかったのですがやはりわざわざつけるのも、CLIのみでの操作になるのは面倒だったので解決させました。

今回のことがあって、逆にssh認証していなくてもOrganizationのprivate repository以外はcloneやpushができるとわかりました。
私のサークルOrgの設定の問題なのでしょうか。

これ本当に初期に作った覚えはあったのですがconfigに追加した覚えはなかったので解決まで長引きました。
この後APIキーは特に使っていなかったので消しました。
【Python3】神経衰弱 (paizaランク B 相当)をやってみた

https://paiza.jp/works/mondai/b_rank_skillcheck_archive/concentration

**問題**:
神経衰弱と呼ばれるトランプゲームのシミュレーションを行います。数字が書かれたトランプを縦 H 枚、横 W 枚の長方形の形に並べた状態でスタートします。トランプには1〜13の数字のうちどれかが書かれており、同じ数字のトランプが複数存在します。プレイヤーが N 人おり、各プレイヤーがトランプをめくっていき、めくった2枚のトランプに同じ数字が書かれていればそのトランプを取り除きます。ゲームの初期状態とトランプの記録が与えられるので、各プレイヤーが取り除いたトランプの枚数を求めます。

**入力値**:
```
H W N
t_{1,1} t_{1,2} ... t_{1,W}
t_{2,1} t_{2,2} ... t_{2,W}
...
t_{H,1} t_{H,W}
L
a_1 b_1 A_1 B_1
a_2 b_2 A_2 B_2
...
a_L b_L A_L B_L
```

**期待される出力値**:
```
各プレイヤーが取り除いたトランプの枚数を出力してください
```

**条件**:
- 1 ≦ H, W ≦ 13
- H × W は52以下の2の倍数
- 2 ≦ N ≦ 10
- t_{i,j} は 1 〜 13 のいずれか
- トランプには同じ数字が2枚または4枚存在
- 1 ≦ L ≦ 200
- 1 ≦ a_i, A_i ≦ H
- 1 ≦ b_i, B_i ≦ W
- (a_i, b_i) ≠ (A_i, B_i)

**Pythonプログラム**:
```python
import sys
input = sys.stdin.read

def main():
    # 入力を読み込む
    data = input().strip().split()
    index = 0

    # H: 縦の枚数, W: 横の枚数, N: プレイヤーの数
    H = int(data[index])
    W = int(data[index + 1])
    N = int(data[index + 2])
    index += 3

    # トランプの状態を読み込む
    cards = []
    for i in range(H):
        row = []
        for j in range(W):
            row.append(int(data[index]))
            index += 1
        cards.append(row)

    # L: 記録の長さ
    L = int(data[index])
    index += 1

    # 各プレイヤーが取り除いたトランプの枚数
    removed_counts = [0] * N

    # ゲームの記録を処理する
    current_player = 0
    for _ in range(L):
        a, b, A, B = map(lambda x: int(x) - 1, data[index:index + 4])
        index += 4

        # 取り除いたトランプの値を確認
        if cards[a][b] == cards[A][B]:
            # 同じ値のトランプを取り除く
            removed_counts[current_player] += 2
            cards[a][b] = -1  # -1 は取り除かれたことを示す
            cards[A][B] = -1
        else:
            # 異なる値のトランプの場合は次のプレイヤーに移る
            current_player = (current_player + 1) % N

    # 各プレイヤーの取り除いたトランプの枚数を出力
    for count in removed_counts:
        print(count)

if __name__ == "__main__":
    main()
```

**コードの説明**:
1. **入力値の読み込み**:
    ```python
    import sys
    input = sys.stdin.read
    ```

2. **main 関数**:
    ```python
    def main():
        data = input().strip().split()
        index = 0
        H = int(data[index])
        W = int(data[index + 1])
        N = int(data[index + 2])
        index += 3

        cards = []
        for i in range(H):
            row = []
            for j in range(W):
                row.append(int(data[index]))
                index += 1
            cards.append(row)

        L = int(data[index])
        index += 1

        removed_counts = [0] * N
        current_player = 0
        for _ in range(L):
            a, b, A, B = map(lambda x: int(x) - 1, data[index:index + 4])
            index += 4
            if cards[a][b] == cards[A][B]:
                removed_counts[current_player] += 2
                cards[a][b] = -1
                cards[A][B] = -1
            else:
                current_player = (current_player + 1) % N

        for count in removed_counts:
            print(count)
    ```

**実行方法**:
このプログラムは、標準入力からのデータを処理し、各プレイヤーが取り除いたトランプの枚数を標準出力に出力します。
簡単に高速で進数変換をやる方法

# はじめに
今回は簡単に高速で進数変換をする方法を紹介していきます(唐突)。
# さっそくやってみる
文字だけだとわかりづらいと思うので簡単に途中式もノートに書いていきます(ipad欲しい)!
なるべく直感的にわかりやすく書くようにします。
### 10進数→2進数
(1)8つの丸を書いてそれぞれ1~128まで倍にした数を書く
(2)1~128までの丸のうち、合計が218(画像の場合)になるように黒く塗る
(3)黒く塗られている箇所を1、それ以外を0とすると11011010(2)となる
![スクリーンショット 2023-12-31 19.47.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3279945/1d8df6c8-d253-6b2e-f071-30393330f1b9.png)
### 10進数→8進数
(1)まず上で説明したやり方で10進数から2進数にする
(2)2進数の値を3つずつで区切って、それぞれ1~4まで倍にした数を書く
(3)あとは画像のように計算する(急に適当)
![スクリーンショット 2023-12-31 19.57.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3279945/13d86341-4364-520a-7253-5ec00c7cc73a.png)
### 10進数→16進数
(1)同じくまた2進数にする
(2)さっきは3つずつで区切ったけど、今回は4つずつで区切って1~8まで倍にした数を書く
(3)あとは画像のように計算
![スクリーンショット 2023-12-31 20.07.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3279945/52daf4ac-ce64-876f-a079-d88ec7298f79.png)
### 8進数→16進数
(1)315(8)のそれぞれの桁の数を3つに分けて、1~4まで倍にした数を書く
(2)画像のやり方で2進数を求める
(3)あとはさっきもやった2進数から16進数にする方法で求める
![スクリーンショット 2023-12-31 20.15.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3279945/a7756c86-f692-62fe-d493-d6a4dfc4ed89.png)
### 16進数→2進数
(1)さっきはそれぞれの桁の数を3つで区切ったけど、今回は4つで区切って1~8まで倍にした数をそれぞれ書く
(2)画像のように該当箇所を黒く塗って2進数を得る
![スクリーンショット 2023-12-31 20.22.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3279945/f8be09b4-7a82-6cca-e687-b85cfc6e00f4.png)
### 16進数→8進数
(1)さっきやった方法でまず16進数から2進数にする
(2)2進数の値を画像のように3つで区切って計算する
![スクリーンショット 2023-12-31 20.29.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3279945/74491c12-1e46-9952-8a87-d0e8a7c8fa32.png)
### 16進数→10進数
10進数への変換に関しては、重みを使って全て簡単に計算できます。今回は16進数から10進数なので16を基数として計算します
![スクリーンショット 2023-12-31 20.36.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3279945/70e43352-bff6-a018-f17c-0ad740bf9ac2.png)
### 8進数→10進数
8進数から10進数なので、8を基数で計算
![スクリーンショット 2023-12-31 20.42.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3279945/939e008a-f855-60e0-a1ac-aad868edfc1b.png)
### 2進数→10進数
2進数から10進数の場合は、画像のように丸を書くやり方で求めれます
![スクリーンショット 2023-12-31 20.57.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3279945/1435f81c-b3ab-895c-f821-bf188019b67e.png)

一旦ここまでできたら下のように自由自在に進数変換できるようになってると思います。
![スクリーンショット 2023-12-31 21.00.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3279945/4d47026e-efb8-a062-dc8b-32e4dfeb3901.png)

# おわりに
普段進数変換なんてやる機会ないと思いますが、基本情報とか受ける方には少しは参考になったのではないかと思います。ここまで読んでくださりありがとうございました。
CompTIA Server+勉強メモ

ハートビート：定期的に監視端末へデータを送り、そのデバイスが生きていることを示すこと
https://e-words.jp/w/%E3%83%8F%E3%83%BC%E3%83%88%E3%83%93%E3%83%BC%E3%83%88.html

フェールオーバー：故障した時、自動的に予備機(パッシブノード)へ切り替わること
フェールバック：予備機が動いている最中に元のマシン(アクティブノード)が復旧したらそちらに移ること
https://www.miraclejob.com/recommend/detail?cd=2134
https://wa3.i-3-i.info/word12588.html

RTO：Recovery Time Objective  事業継続のために停止から復旧までの許容時間。
RPO：Recovery Point Objective 障害発生時にどのタイミングの状態に戻すか。これを元にバックアップ頻度とか考える。

オンサイト：現地。現場。
オフサイト：オフィスとは離れた場所。地震や津波対策でオフィス以外の場所にストレージを置いたりする。
https://wa3.i-3-i.info/word18284.html

コールドサイト：


ポートスキャン　コマンド　(nc netstat dig nbtstat)
ホットスワップ
SFP：Small Form Factor Pluggableの略。長距離をつなぐのに使われる(反対にツイストペアは短距離)

SSLサーバー証明書
・「通信データの暗号化」と「サイト運営者の情報の承認」
・HTTPSが使えるようになる（証明書に共通鍵、公開鍵が含まれるので）
https://jp.globalsign.com/ssl/about/
・ドメイン認証⇒このドメイン使っていいよ
・企業実在認証⇒このドメイン使っていいよ。あっ、あなたの企業はちゃんと実在してるね。物理的にあるかは知らんけど。
・EV認証⇒このドメイン使っていいよ。そしてあなたの企業は法的にも物理的にも存在しているね。承認者と署名者はこの人だね

仮想NIC：
・NAT⇒複数の仮想マシン(ゲストOS)で同じ外部IPを共有する。ゲストOSとホストOSはつながらない。
・ブリッジ⇒各ゲストOSが別々の外部IPを持つ。ゲストOSとホストOSは並行して存在するイメージ。ゲストOSとホストOSはつながる。
・ホストオンリー⇒ゲストとホストだけつながる。ゲストは外部と通信できない。
https://qiita.com/pink/items/2416cd5f440bf9d6b4ca

バックアップ
「フル」「差分」「増分」「永久増分」の4種
フル：全部
差分：前回のフルからの変更点分をバックアップする
増分：前回のバックアップからの変更点分をバックアップする

https://www.networld.co.jp/solution/learn_first/backup/1st/01_basis/05_type/

アーカイブ：利用頻度の低いデータを別メディアに移行すること。バックアップとは別。

仮想スイッチ
・仮想マシンどうしをつなぐ
・仮想マシンと物理ネットワークをつなぐ

https://licensecounter.jp/engineer-voice/blog/articles/20240725_kiso_hyper-v_2_switch.html


L2スイッチとL3スイッチ
データリンク層(2)<->ネットワーク層(3)
同じネットワーク間<->違うネットワーク間
MACアドレス参照<->IPアドレス参照
https://panasonic.co.jp/ew/pewnw/product/column/010.html

netstat
・通信状況を確認するコマンド
・どのアドレスから外部のどのアドレスへつながっていて、プロトコルは何か確認できる

https://network-beginners-handbook.com/netstat/

dig
・ドメイン名からIPアドレスを調べる

https://qiita.com/hypermkt/items/610b5042d290348a9dfa

https://www.ois-yokohama.co.jp/oisblog2018/archives/6339

nbtstat
・windowsネットワークにつながってるパソコンのコンピュータ名(NetBIOS名)やIPアドレスなどがわかる

https://xtech.nikkei.com/it/article/COLUMN/20100526/348451/

ネットワークトラブルシューティング系問題
・停止していたら応答帰ってこない！(例:
tracertでデフォルトゲートウェイまでしか到達できない=デフォルトゲートウェイは生きてる)
・OSI参照モデルの下層から確認していく

route
GPO
重複排除
ディスククォータ
HCL
アーカイブ　オープンファイル
権限って具体的に何ができて何ができない？(chmodの話)
chmodの数字
NICチーミング リンクアグリゲーション　ラウンドロビン
RAID
ベアメタル
Active directory Kerberos認証　RADIUS
GPT　テンプレート　P2V
TPI：Two persin Integrity 機密性の高いシステムへアクセスするには二人で行う必要があること
エンドツーエンド
Telnet XCOPY SCP Robocopy
ホスト名　ドメイン名　
APIPA　VLAN
インバンド管理　アウトオブバンド管理
HVAC
GPT形式　UEFI
デフォルトゲートウェイ　バックボーンスイッチ
hosts.allow
ログローテーション　ログリテンション
RPO BIA
仮想NIC　NAT
コンソール接続
SATA　SAS
SMARTエラー
コンパレータ
エンクロージャー
SAML


HCI
プロビジョニング
ワークロード
RAID整理
フォールトレランス
レプリケート
データストライピング
raid 1+0
オーバーヘッド
raid5と6、それぞれディスクのどれだけを保存に使えるか
raid6にはハードウェアraidがいる？
raid10は結局早いの？
Which of the following is not a SAN layer?　A:network layer
powershellとコマンドラインの違い
サーバーコア
MSIコンソール
ヘッドレスサーバー
Sconfig
Minshell
dism
アクティブディレクトリ
win pe

ベアメタルは自分の家を持つこと、パブくらは賃貸
占有できる仮想サーバー？PaaS?
chrootkit rkhunter clamav

ハイパーバイザー
paravirtualization <-> full virtualization
タイプ1ハイパーバイザ、タイプ2ハイパーバイザ
テンプレート
プロビジョニング
RSAT
スナップイン
8/23 クローンとスナップショットを作ってみる
ボリュームベース、ディスクベース、リンクドクローン
UEFI
ローカルインストール、クライアントサーバーインストール
vmware vcenter converter standalone
ダイナミックディスク
フォール地レランと
ボリュームとディスクの違い
ファイルシステム
エラー対処　Assertion failed on expression: 'IsFinite

## Assertion failed on expression: 'IsFiniteのエラーが出た時の対処法

unityでScriptsにも異常がなく、「さあ、デバック開始、ポチっ」と再生モードに入るとき、
以下のようなエラーが大量に出続けることがあります。

Assertion failed on expression: 'IsFinite(distanceForSort)'
Assertion failed on expression: 'IsFinite(distanceAlongView)'

エラー文も短く、どこに問題があるか特定するのが非常に困難ですが、私のスクリプトの例で対処した方法を備忘録として残します。

#### 原因と解決

以下のスクリプトに原因がありました。
```
private void Execute(Entity entity, ref TargetEntity targetEntity, LocalTransform transform,
            in EnemySearchRange targetRadius, ref UnitBrain brain, [ChunkIndexInQuery] int sortKey)
        {

            if (brain.LastEnemySearchTime <= currentTime + brain.EnemySearchCooldownTime) return; //クールダウンタイム中ならリターン
```
一番下の行のIf節が、永遠にTrueが返ってくる構文になっていました。
※本当はcurrentTime = (float)SystemAPI.Time.ElapsedTimeで、時間経過とともにTrueになったりFalseになったりするscriptにしたかったのですが、間違っていました。
エラーにはならない内容だけど、間違ってるよ、っていうのを教えてくれていたみたいです。

以下のように直して、エラーはでなくなりました。
```
if (brain.LastEnemySearchTime + brain.EnemySearchCooldownTime > currentTime ) return; //クールダウンタイム中ならリターン
```

エラーを吐き出すなら、原因となるスクリプトの場所ぐらいは教えてほしいですね。
react-routerのページ遷移でstateが渡せない

# 今回記事を書こうと考えた背景
* react-router v6でuseLocationのStateの値を渡す実装をするのに嵌ってしまったためです。
またStateの値がnullでconsoleに表示されていたためです。

# 原因
* StateをdetailAにLinkで渡しているところの書き方を間違えていたからです。
※detailAは親RouteであるPage1からネストしたページです。

# 問題のファイル
```Page1.jsx
export const Page1 = () => {
    const arr = [...Array(100).keys()];
    console.log(arr);
    return(
        <div>
            <h1>Page1ページです</h1>
            <nav>
                <Link to={{ pathname: "detailA", state: arr }}>DetailA</Link>
            <br/>
                <Link to="detailB">DetailB</Link>
            </nav>
            <Outlet />
        </div>
    );
};

```
# 実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3789688/9a0f8246-4a7b-0f78-89d3-bf1d61198b21.png)

#　修正したコード

```Page1.jsx
export const Page1 = () => {
    const arr = [...Array(100).keys()];
    console.log(arr);
    return(
        <div>
            <h1>Page1ページです</h1>
            <nav>
                <Link to="detailA" state={{arry: arr }}>DetailA</Link>
            <br/>
                <Link to="detailB">DetailB</Link>
            </nav>
            <Outlet />
        </div>
    );
};

```
# 実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3789688/76602df6-0818-c7c4-18e5-ce7b11cd4e9b.png)

# 参考にしたページ
「State」の項目を参照しました。
https://reactrouter.com/en/main/components/link#state

## おわりに
バージョンが異なるときには公式ドキュメントを見てドキュメントに書いてある通りに正しい書き方での実装をしてみることが大切であると感じました。
学習記録 react

### ドラッグ＆ドロップのテスト
掴んで離すだけ。このままで要素を増やしても、状態管理が効いてないので元の場所に戻ってしまう。

https://gyazo.com/8537bce2d9a14305ed001056d4046682


### 複数ドラッグ＆ドロップ
useStateを利用した状態管理による、複数の要素のドラッグ＆ドロップ

https://gyazo.com/d380d9ad131c3754e24fabf68646dd52
これ知らないとガチでやばい‼︎GitHubで機密情報を上げた時に、警告がくる‼︎(GitHubでpublicからprivateに変更する方法を解説)

# GitHubはセキュリティ面で優秀
GitHubでは、***credentikalや秘密鍵など上げたらやばいデータをpushしたりすると警告、アラートメール***がきます。それくらいGitHubは優秀です。セキュリティの対策も取られています。こんな感じのメールがきます。
```
[アカウント名/リポジトリ名] Generic High Entropy Secret exposed on GitHub

GitGuardian has detected the following Generic High Entropy Secret exposed within your GitHub account.
Details
- Secret type: Generic High Entropy Secret
- Repository: アカウント名/リポジトリ名
- Pushed date: 日付
```

# publicからprivateに変える方法
1.***GitHubのsettingをクリック***


2.***下にスクロールするとDanger Zone***

![スクリーンショット 2024-07-21 18.06.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1748789/bd33b86b-e1d1-effc-9ce1-cbbef7caa7ae.png)

3.Change repository visibilityをクリック(ここでprivateに変更できます)

下の画像はpublicになってますが、これはprivateの状態です。
publicの時はここがprivateになります。

![スクリーンショット 2024-07-21 18.11.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1748789/065f02e2-1e05-3f32-d01e-a05b02960017.png)





# privateになった確認する方法
***他の端末(スマホなど)から、privateにしたリポジトリが見ることできないかをチェック***してください。ログインしている状態だと下のようにprivateになっていると鍵マークがつきます。
![スクリーンショット 2024-07-21 18.13.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1748789/0b2b3e90-0d66-67dc-fd75-f07c30f32363.png)

スマホから確認してみました。(ログインしていない)
こんな感じで見ることができなくなります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1748789/1b69512f-8de3-dd07-f3f6-be65d2f2ac24.png)
ITパスポート データ利活用と問題解決

・データ利活用
・母集団
調べる対象になる集団

・標本抽出
全体の一部のサンプル（標本）を対象として調査する

・単純無作為抽出法
母集団から完全にランダムで標本を抽出する

・クラスター抽出法
母集団の中からランダムに小集団を選び、その小集団を全数調査する

・相関関係
２種類のデータの間に関連があること

・因果関係
２種類のデータが原因と結果の関係にあること

・主成分分析
データの分析の際、関係する要素の種類を減らし、大きく影響を与える要素（主成分）に置き換えて分析すること

・仮説検定
主張したい仮説（対立仮説）に対して、否定したい仮説（帰無仮説）を設定し、帰無仮説を棄却することで対立仮説を採択すること

・帰納推論
様々な事象の共通点から、結論を導き出す方法

・演繹推論
既に知られている法則や一般論から、具体的事象の結論を導き出す方法

・クロスセクションデータ
ある時点における複数の項目を集めたデータ

・回帰分析
結果となる数値（目的変数）と要因となる数値（説明変数）の関係を調べて、それぞれの関係を明らかにする統計的手法

・問題解決手法
・ブレーンストーミング
複数人が集まってより多くのアイデアを口頭で出し合う手法

・ブレーンライティング
複数人が集まってより多くのアイデアを紙に書きだす手法

・ファシリテータ
中立な立場から会議を運営する進行役
翻訳ファイルの反映を確認するときはサーバーを再起動するのが基本だろ？

新しく翻訳ファイルを追加したbranchを開いた際、viewに翻訳が反映されなかったので原因を4時間ほど探っていました。

- ファイルの場所
- ファイルの命名
- 設定の書き方
- ymlの書き方

多くの可能性を探りました。

しかし、ある記事を見た際に

'gemをインストールしたらサーバーを再起動するのは基本中の基本です。'
という文言を見かけました。

今回の場合はgemをインストールしていたわけではないですが、以前取り組んだ教材に'翻訳ファイルに文言を追加した際はサーバーを再起動しよう！'みたいな文言があったことを思い出しました。

4時間という貴重な時間を割いた代償としてこの結論を得たのは不服ですが、解決したので今回は良しとしましょう。
React Snippets, React Hooks Snippets まとめ


:::note
参考: [React Snippets](https://marketplace.visualstudio.com/items?itemName=NicholasHsiang.vscode-react-snippet)
:::
:::note
参考: [React Hooks Snippets](https://marketplace.visualstudio.com/items?itemName=AlDuncanson.react-hooks-snippets)
:::

## <font color="Blue">Function Component</font>
### rafce
```tsx
import React from 'react'

const aaa = () => {
  return (
    <div>aaa</div>
  )
}

export default aaa
```

### rafc
```tsx
import React from 'react'

export const aaa = () => {
  return (
    <div>aaa</div>
  )
}
```

### rfce
```tsx
import React from 'react'

function aaa() {
  return (
    <div>aaa</div>
  )
}

export default aaa
```

### rfc
```tsx
import React from 'react'

export default function aaa() {
  return (
    <div>aaa</div>
  )
}
```


## <font color="Blue">useState Hook
</font>

### ush

```tsx
const [, set] = useState();
```

## <font color="Blue">useEffect Hook
</font>

### ueh

```tsx
useEffect(() => {
    
    return cleanUp = () => {
        
    }
}, []);
```

## <font color="Blue">useContext Hook
</font>

### uch

```tsx
const  = useContext();
```

## <font color="Blue">useReducer Hook
</font>

### urdh

```tsx
const [state, dispatch] = useReducer(reducer, initialArg, init);
```

## <font color="Blue">useRef Hook
</font>

### urh

```tsx
const  = useRef();
```

## <font color="Blue">useMemo Hook
</font>

### urh

```tsx
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
```

## <font color="Blue">useCallback Hook
</font>

### ucbh

```tsx
const memoizedCallback = useCallback(
    () => {
        doSomething(a, b)
    },
    [a, b],
);
```

## <font color="Blue">useSelector Hook
</font>

### uss

```tsx
const  = useSelector(state => state.);
```

## <font color="Blue">useDispatch Hook
</font>

### usdf

```tsx
const  = useDispatch();
```
【Rails7】Ruby on Rails7で日付のフォーマットをDRYに書きなおす際につまずいた話

# 概要
備忘録として残してRuby on Rails7での日付をフォーマット形式で書き直し、\
重複のないコードにする際につまずいたため記録する。

# 経緯
Ruby on Rails5のプログラムをRuby on Rails7に書きなおすときに、\
# 前準備
以下のファイルを作成しサーバーを再起動
```ruby:config/initializers/time_formats.rb
Time::DATE_FORMATS[:datetime_jp] = '%Y年 %m月 %d日 %H時 %M分'
```
## エラー
日付フォーマットがうまく適用できずエラーになってしまった。
```erb: index.html.erb
<td><%= board.created_at.to_s(:datetime_jp) %></td>
<td><%= board.updated_at.to_s(:datetime_jp) %></td>
 ⇒ wrong number of arguments (given 1, expected 0)
```

# 解決策
[【Rails7】Railsで数値を３桁で区切る \#Rails \- Qiita](https://qiita.com/Hassan/items/c529ac0cd641e9be5a67)の記事より \
`to_formatted_s(:datetime_jp)`とすることで解決した。

```erb: index.html.erb
<td><%= board.created_at.to_formatted_s(:datetime_jp) %></td>
<td><%= board.updated_at.to_formatted_s(:datetime_jp) %></td>
```
どうやらruby3.1でパフォーマンスチューニングがあり、railsでto_sメソッドでのシンボルの受け渡しが非推奨になったっぽい？
- https://github.com/rails/rails/pull/43772
- https://github.com/ruby/ruby/commit/b08dacfea39ad8da3f1fd7fdd0e4538cc892ec44
WSL上のdockerコマンドをsudoを付けずに実行できるようにしてみる

[Windows11(WSL2)上のUbuntuにDocker EngineをインストールしてLinuxコンテナを実行してみる](https://qiita.com/SAITO_Keita/items/069715dde090f6584c33)

上記記事でWindows上のWSL2にdockerをインストールして環境構築の記事を書きましたが。

上記記事ではdockerコマンドを実行する際にsudoする必要がありました。

本記事では非管理者ユーザーで実行できるように設定していきます。

## ドキュメント

[Manage Docker as a non-root user](https://docs.docker.com/engine/install/linux-postinstall/#manage-docker-as-a-non-root-user)

## 今回利用する環境

- Windows 11 23H2
- WSL2上のUbuntu 22.04
- Docker Engine - Community 27.0.3

## 対応方法は2パターン

dockerコマンドをrootユーザー以外で実行するためには下記2パータンの方法があるようです。

- ①パッケージインストール時に作成されるdockerグループへユーザーを登録する（登録したユーザーはルート相当の権限を持つ）
- ②DockerのRootless モードを利用する

本記事では①のdockerグループにユーザーを登録する方法で、sudoを付けずにdockerコマンドを実行できるように調整していきます。

なおdockerグループにユーザーを登録する事で、rootレベルの権限をユーザーへ付与する事なります。
またこれがセキュリティリスクについてどのように影響するかは下記のようなドキュメントが公開されています。

[Docker daemon attack surface](https://docs.docker.com/engine/security/#docker-daemon-attack-surface)

## DockerのRootlessモードについて

[Run the Docker daemon as a non-root user (Rootless mode)](https://docs.docker.com/engine/security/rootless/)

本記事では実施しませんが、DockerではRootlessモードが用意されており、こちらを利用する事でもsudoを付けずにdockerコマンドを実行できるようになります。

RootlessモードはDockerデーモンとコンテナをroot以外のユーザーが実行する機能となるようです。

Rootlessモード登場当初は実験的な機能としてリリースされていたようですが、Docker 20.10から正式機能に昇格しているようです。

なお、Rootlessモードについては、通常のdockerに比べていくつかの制約があるようなので、利用する際には注意が必要なようです。

## グループの確認

前回紹介した記事では、パッケージからdockerをインストールしているため、すでにdockerグループが用意されているとの事なのでグループを確認してみます。

```bash
cat /etc/group | grep docker
```

確認すると既にグループが作成されている事がわかります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/e217b17c-2442-c3b1-c137-71d3a5ca0dd8.png)

##　ユーザーの登録 & ログアウト

```bash
# dockerグループに実行ユーザーを登録
sudo usermod -aG docker $USER
# 一度ログオフ
exit 
 ```

上記のコマンドでdockerグループに実行ユーザーを登録します。

また登録後にユーザーをログオフして、再ログインする事でグループ設定を再評価します。

なおドキュメントには仮想マシンでLinuxを実行している場合、再起動が必要になる場合があると記載されていましたが、本環境では仮想マシンの再起動までは必要ありませんでした。

## sudoなしでhelloworldを実行

```bash
 docker run hello-world
 ```

 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/9b945cbb-3fac-2105-dd5b-b9675f752204.png)

sudoなしでhelloworldが実行できました。

## 総評

dockerグループにユーザーを追加するだけなので対した作業ではありませんが。

dcokerをroot以外で利用させる部分について。

セキュリティリスクまで考慮して利用となると、色々と確認点が多く深い世界になりそうです。
Pythonマルチスレッド検証

## PythonのマルチスレッドでSQLite３からデータを取得する検証
### マルチスレッドでSQLite3からデータを取得する
#### 1.参照するテーブルのレイアウト
+ test_db.sqlite3.large_data

| 列名 | データ・タイプ |
|:-:|:-:|
| id | INT |
| col1 | INT |
| col2 | TEXT |
| 〜 |  |
| col15 | TEXT |

#### 2.検証用コード
+ あらかじめ dataset をインストールしておくこと
```
pip install dataset
```
```sqlite3_multi_thread.py
import concurrent.futures
import datetime
import traceback
import dataset

# 取得条件
CONDITIONS = [
    {'db': '1', 'min': '1', 'max': '1000000'},
    {'db': '2', 'min': '1000001', 'max': '1500000'},
    {'db': '3', 'min': '1500001', 'max': '3000000'},
    {'db': '4', 'min': '3000001', 'max': '4000000'},
    {'db': '5', 'min': '4000001', 'max': '5000000'}
]
# 取得条件要素数
ELEMENT_COUNT = len(CONDITIONS)
# DBパス
DB_PATH = '/Users/user/Documents/SQL/SQLite/3/'
# DBファイル名
DB_NAME = 'test_db.sqlite3'
# DBファイルパス
DB_STR = DB_PATH + DB_NAME
# テーブル名
TABLE_NAME = 'large_data'


def find_by_condition(arg):
    '''
    データベースから条件に基づきリストを取得する
    '''
    # DBに接続
    db = dataset.connect(f'sqlite:///{DB_STR}')
    # テーブル接続
    tbl = db[TABLE_NAME]

    print(datetime.datetime.now(), 'DB名', CONDITIONS[arg].get('db'), '：開始')
    print(datetime.datetime.now(), 'DB名', CONDITIONS[arg].get(
        'db'), '処理行数', CONDITIONS[arg].get('min'), 'から', CONDITIONS[arg].get('max'))

    # テーブルから条件に基づきリスト取得
    large_data_list = list(tbl.find(
        id={'between': (CONDITIONS[arg].get('min'), CONDITIONS[arg].get('max'))}))
    db.close()

    print(datetime.datetime.now(), 'DB名', CONDITIONS[arg].get(
        'db'), '処理データ件数：', len(large_data_list))
    print(datetime.datetime.now(), 'DB名', CONDITIONS[arg].get('db'), '：終了')

    return large_data_list


def main():
    '''
    主処理
    '''
    print('処理開始：', datetime.datetime.now())
    print('---------------')
    print('マルチプロセス開始：', datetime.datetime.now())
    print(ELEMENT_COUNT)

    # マルチプロセスで処理実行
    with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
        futures = {executor.submit(
            find_by_condition, arg): arg for arg in range(0, ELEMENT_COUNT, 1)}

        for future in concurrent.futures.as_completed(futures):
            print(future.result()[0])

    print('マルチプロセス終了：', datetime.datetime.now())
    print('---------------')
    print('処理終了：', datetime.datetime.now())


try:
    if __name__ == "__main__":
        main()

except Exception:
    print('処理終了：', datetime.datetime.now())
    traceback.print_exc()
```
tcpdump の結果が表示されないときに追加すべきオプション

tcpdump するときの問題点

## 結論
```sh
tcpdump -i enp1s0.2110 -l -n
```

## やること
Ubuntu 22.04 の Intel の ミニPC 上で tcpdump をして標準出力で結果をリアルタイムで見る。
特定の I/F を capture したいが、そこのインターネット疎通性はない (PC自体の疎通性はある)。


## 問題点
1. すぐに結果が表示されない。Ctrl + C) を押してようやっと表示される
2. Kernel drop 率高すぎ

## 解決法
1.  -l オプションを押すと標準出力を行ごとにフラッシュできる。これで表示された
2.  -n オプションで名前解決をなくしたところ Kernel drop がなくなった [1] (インターネット接続できないので名前解決に失敗している？)

## 参考
[1] https://yoru9zine.hatenablog.com/entry/2016/06/15/053105
Rakeタスクの使い方

## 経緯
本番環境へあげる際に、rails db:migrateの順番が複雑化したことがありました。その結果、本番環境へデプロイする担当者が手間取ってしまうことが多々ありました。そこで、Rakeタスクを利用してマイグレーション順を自動化し、誰でも簡単にデプロイできるようにする方法を紹介します。


## Rakeタスクの基本
まず、Rakeタスクの基本的な作成方法を説明します。Rakeタスクは、Railsのプロジェクト内のlib/tasksディレクトリに配置します。

Rakeタスクのファイル作成
以下のようなファイルをlib/tasksディレクトリに作成します。
```
touch lib/tasks/db_migrate.rake
```
Rakeタスクのファイル作成
以下のようなファイルをlib/tasksディレクトリに作成します。

```
# lib/tasks/db_migrate.rake

namespace :task do
  desc "Custom DB Migrate"
  task migrate_custom: :environment do
    puts "Running migrations in custom order..."

    system("rails db:migrate:up VERSION=20220101010101")

    #別の処理
    
    system("rails db:migrate:up VERSION=20220101010201")

    #別の処理
    
    system("rails db:migrate:up VERSION=20220101010301")

    puts "All migrations completed."
  end
end
```
上記のように好きな順番でマイグレーションの順番を設定できます。
具体的な例として、複数のテーブル作成と既存テーブルへのカラム追加を行うマイグレーションを順番に実行するRakeタスクを作成します。

上記のタスクでは、以下の順番でマイグレーションファイルを作成します。

実際に打ち込まれるコマンド：
```
rails generate migration CreateUsers name:string email:string
rails generate migration AddAgeToUsers age:integer
rails generate migration CreatePosts title:string body:text user:references
```

マイグレーションファイル：
```
# db/migrate/20220101010101_create_users.rb
class CreateUsers < ActiveRecord::Migration[6.0]
  def change
    create_table :users do |t|
      t.string :name
      t.string :email

      t.timestamps
    end
  end
end

# db/migrate/20220101010201_add_age_to_users.rb
class AddAgeToUsers < ActiveRecord::Migration[6.0]
  def change
    add_column :users, :age, :integer
  end
end

# db/migrate/20220101010301_create_posts.rb
class CreatePosts < ActiveRecord::Migration[6.0]
  def change
    create_table :posts do |t|
      t.string :title
      t.text :body
      t.references :user, foreign_key: true

      t.timestamps
    end
  end
end
```
## Rakeタスクの実行
Rakeタスクを実行するには、以下のコマンドを使用します。

```
bundle exec rake task:migrate_custom
```
このコマンドを実行することで、指定した順番でマイグレーションが実行されます。
またマイグレーションによっては、up,downの設定も必要になるかもしれません。

up,downについての参考記事：
https://qiita.com/sinke_123/items/d12494a70ac00b8096ef

これにより、指定したマイグレーションを順番に実行し、その間に必要な追加の処理を行うことができます。

## まとめ
Rakeタスクを使うことで、マイグレーションの順番を明確に設定し、本番環境へのデプロイを容易にすることができます。また、個別のマイグレーションファイルを指定して手動で実行することも可能です。今回の記事では、具体的な例として複数のテーブル作成と既存テーブルへのカラム追加を順番に実行する方法を紹介しました。これにより、本番環境へのデプロイ時の手間を大幅に減らすことができます。
いろんな意味で話題のCrowdstrikeって何？

## はじめに

2024年7月19日、世界中のWindowsシステムで相次いで
ブルースクリーンが発生するという事件が発生しました。
世界中の空港、鉄道、医療、銀行、その他もろもろが全部この現象に陥りました。

原因はセキュリティ企業Crowdstrikeによる欠陥を含んだコンテンツアップデートが原因であり、
多くのシステムがダウンする事態に至ったことで大きな注目を集めました。

**ところでCrowdstrikeって何？**

https://x.com/okash1n/status/1814490524520473081

## どんな会社？どんなサービス？
サービスの保護プラットフォームを提供する、
米国拠点の会社。
McAFeeやMicrosoftを抜き3年連続で市場シェア1位を獲得しているらしい。
**知らんかったぞ。**

日本でも`株式会社NTTデータ`や`サッポロホールディングス株式会社`が導入。
~~つまりこれらの企業は例の事件では被害者なのか...~~

主力製品は**Falcon Platform**。
今回の事件の原因はこれ。

組織内のネットワークにあるエンドポイントからログデータを収集し、不審な挙動や攻撃を検知・防御してくれるセキュリティソリューション。

- クラウド上で動作するため、最新の脅威に対応するためのアップデートが迅速に行なうことができ、
従来のオンプレミス型のセキュリティ製品に比べて柔軟性がある。
（例の事件はこの利点が裏目に出たわけか）
- 人工知能と機械学習を組み合わせることで、従来では見逃しやすい未知の脅威にも対応できる。
- 複数のセキュリティ製品を統合するのではなく、単一のプラットフォームでエンドポイントを保護できるため、管理が容易。

あとこいつは**アップデートが降ってくると自動更新する**らしい。
そういうことか...

## ウイルスバスターと何が違うんですか

| ポイント | ウイルスバスター | Crowdstrike |
|:-:|:-:|:-:|
| アーキテクチャ | クラウドネイティブのアーキテクチャを採用。軽量なエージェント（Sensor）がエンドポイントに常駐し、クラウドと連携して動作。 | 従来型のクライアント・サーバーモデルを基本としつつ、クラウド機能も統合。エンドポイントに比較的重いエージェントをインストール。 |
| 検出方法 | 振る舞い分析とAI/機械学習を中心とした検出方法。ファイルレスマルウェアなどの高度な脅威にも対応。 | シグネチャベースの検出に加え、ヒューリスティック分析やAI技術も採用。幅広い脅威に対応。 |
| リアルタイム保護 | クラウドベースの分析により、ほぼリアルタイムでの脅威検知と対応が可能。 | ローカルの検査とクラウドベースの保護を組み合わせて、リアルタイム保護を提供。 |
| 管理とデプロイメント | クラウドベースの管理コンソールを通じて一元管理。デプロイメントが比較的容易。 | オンプレミスまたはクラウドベースの管理コンソールを提供。大規模環境向けの高度な管理機能を備える。 |
| 価格帯 | 一般的に高価格帯。高度な機能と専門的なサポートを反映。というかそもそも個人向けじゃない。 | 比較的手頃な価格帯から高機能版まで幅広い製品ラインナップを提供。 |

全体的にCrowdstrikeはクラウドを積極的に活用して対策する
企業向けセキュリティ対策ソリューションってことみたいです。

## にしては知名度が低い気が...

CrowdStrikeは個人向けに提供していないし、
日本でも企業での導入が基本だから取引は主に代理店が請け負っている様子。

個人の域には絶対に降りてこない代物だし、
多分一般の方に「Linuxって知ってますか？」って聞くと「？」ってなるのと同じなのかな...


## おまけ

https://x.com/yamato_ik/status/1814211150772666384

情シスの皆さん、本当にお疲れ様です...
git hub pages　使い方　URLを指定してhtmlを表示させよう

git hub pagesの使い方を共有します。

# この記事で伝えたいこと

1.作成したファイルを公開する手順
2.どのファイルを表示させるのかはURLで指定するということ

# 準備
まず公開したいhtmlファイルをリモートリポジトリに置いてください
ブランチや、フォルダ構成はなんでも構いません

今回は 「git_test」リポジトリの中のmasterブランチに「gitPages」
![スクリーンショット 2024-07-21 16.48.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958989/eb06dedb-060c-4029-59b1-0af128420e33.png)



というフォルダを置きました。
表示させたいのは このフォルダの中のindex.htmlです


それではgit hub のフォルダを配置したリモートリポジトリに行きます


# 使い方



　setting をクリック

![qiita_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958989/867c3407-5d02-1118-cb6f-b7d0a8c0708f.png)

 Pagesをクリック

![スクリーンショット 2024-07-21 161432.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958989/253c4ad7-d72a-28a1-57a2-49002ac39cec.png)

1-　「None」をクリック
2-  　ファイルを配置したブランチを選択
3-　「save」をクリック

![スクリーンショット 2024-07-21 162057.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958989/ddcab87d-cd72-521e-2256-bc246b8ca39d.png)

※フォルダは「root」です

![スクリーンショット 2024-07-21 162410.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958989/3dc4e3f9-ad3d-27a2-b8e9-c21e08a4302b.png)


しばらく待ってからページをリロードすると URLが表示されますので
URLをクリックします

![スクリーンショット 2024-07-21 162637.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958989/92835198-f5d9-8b3d-6345-f488a4a3e25b.png)

404　Not Found

![スクリーンショット 2024-07-21 162748.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958989/f4e86af0-2378-c450-fad0-e36d9e512725.png)

はい。これはURLが間違っているためにこうなっています

この時のURLは
```
https://jefuo.github.io/git_test/
```

です。
これは　　

https:// + 「アカウント名」 + .github.io/ + 「リポジトリ名」/ +「ファイルパス」　

で記述されているのですが、「ファイルパス」の部分が記述されていないため、ルートフォルダ直下のhtmlファイルを探しに行ってしまいます。ルートフォルダ直下には「gitPages」フォルダしかありませんのでエラーとなるわけです。


ですので先述のフォルダ構成の写真
を参考に、　今回正しいURLは

```
https://jefuo.github.io/git_test/gitPages/
```

になります。

またhtmlファイルの名前が「index.html」の場合、githubが自動で読み込みます。
なので

```
https://jefuo.github.io/git_test/gitPages/index.html
```
と、ファイル名まで書かなくても良いことになります。　仮にファイル名が違う場合は
ファイル名までパスを記述してください

無事サイトが表示されたと思います。

ちなみに
![スクリーンショット 2024-07-21 17.06.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958989/8f239c79-854f-3bd5-9661-89087eb04293.png)

この /docs　ですが、これはURLの「ファイルパス」部分に 「/docs」　と記述されているのと同じ扱いになります。
なので実際に「docs」フォルダをこちらで用意し、その中にindex.htmlファイルを置けば
URLの「ファイルパス」の部分は省略してもサイトが表示されます。


以上です。
配列同士の共通部分を見つける

## array_intersect()

- 配列の共通部分を見つけるために使用される
- 複数の配列を渡すことで、それらの配列全てに共通する要素を抽出できる
- 結果の配列のキーは、最初の配列のキーを保持する

### 使用例

```php
// 配列を定義
$array1 = array("a" => "green", "b" => "brown", "c" => "blue", "0" => "red");
$array2 = array("a" => "green", "0" => "yellow", "1" => "red");

// 共通する値を持つ要素を取得
$result = array_intersect($array1, $array2);

// 結果を出力
print_r($result);

```


### 出力
```php
Array
(
    [a] => green
    [0] => red
)
```


## array_intersect_key()

- 2つ以上の配列のキーに基づいて交差（共通するキーの要素）を返す
- 最初の配列のキーを基準にして、他のすべての配列で同じキーを持つ要素を返す


### 使用例

```php
$array1 = [
    'a' => 1,
    'b' => 2,
    'c' => 3,
    'd' => 4
];

$array2 = [
    'a' => 10,
    'c' => 30,
    'e' => 50
];

$result = array_intersect_key($array1, $array2);

print_r($result);
```

### 出力
```php

Array
(
    [a] => 1
    [c] => 3
)
```


## 感想

見つけたい共有部分がkeyなのかvalueなのかで使い分けができるのは良いと思ったが、まだ経験の浅い自分には使う場面があまりなさそう。
（今回使ってみたが、コードレビューにて少し冗長になるがみやすいコードに変更した。）
また、自分のチームではあまり使われていなかった。
現在のルート名やipを取得する

業務中にipアドレスやルートの名前によって処理を分ける必要があり、調べたのでメモ。

## route()
- 現在のルートに関する情報を返す

## getName()
- 現在のルートの名前を取得する

## ip()
- クライアントのIPアドレスを取得する

### 使用例

```php
Route::get('/example', [ExampleController::class, 'show'])->name('example.route');

// メソッド内で$requestを使えるようにする
public function showDetail(Request $request){
    $request->route()->getName()
    $request->ip()
}


```
[JavaScript] オブジェクトリテラル、配列リテラルについて

# 目次

# オブジェクトリテラル

# 配列リテラル

# 参考リンク
- [オブジェクトリテラル (object literal)](https://typescriptbook.jp/reference/values-types-variables/object/object-literal)
- [配列リテラル (array literal)](https://typescriptbook.jp/reference/values-types-variables/array/array-literal)
Kotlin Map型の特徴

Kotlin言語におけるMapの特徴や扱い方をまとめる。
```kotlin
val weightList: MutableMap<String, Int> = mutableMapOf<String,Int>()
```
値の追加方法。キーを設定する方法と、演算子の方法がある。同じキーを入力すると値が上書きされる。（リストは新しく追加される点で違いがある）

```kotlin
weightList["African Elephant"] = 7000
weightList += "zebra" to 250

println(weightList)
// {African Elephant=7000, zebra=250}

weightList["African Elephant"] = 6000
println(weightList)
// {African Elephant=6000, zebra=250}
```

値を削除する場合はremoveを使用する。存在しないキーを消去した場合は何も起こらない。
```kotlin
weightList["camel"] = 450
weightList["rhino"] = 1500

weightList.remove("camel")
weightList.remove("deer")

println(weightList)
// {rhino=1500}
```

まとめて追加するにはmapを使用する。削除するにはclearを使用する。
```kotlin
weightList += mapOf("flamingo" to 200, "cheetah" to 35, "hyena" to 50)
println(weightList)
// {flamingo=200, cheetah=35, hyena=50}
weightList.clear()
println(weightList)
// {}
```
値を順番に取り出すにはfor文が便利。
```kotlin
weightList += mapOf("flamingo" to 200, "cheetah" to 35, "hyena" to 50)

for ((name, weight) in weightList) {
    println("${name}の体重は${weight}kgです")
}
// flamingoの体重は200kgです
// cheetahの体重は35kgです
// hyenaの体重は50kgです
```

#### 参考

https://www.choge-blog.com/programming/kotlinmapitemforloop/
Access 2019 Expertに合格したので勉強法をまとめる

こんにちは。カラガラです。
先日Access 2019 Expertに合格することができました。勉強期間は1か月ほどでした。
そこで今回は、自分が試験に向けて行った勉強についてまとめたいと思います。
結論から申し上げますと、[『MOS Access 365&2019 Expert 対策テキスト&問題集』](https://www.amazon.co.jp/Access-2019-Expert-%E5%AF%BE%E7%AD%96%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88-%E3%82%88%E3%81%8F%E3%82%8F%E3%81%8B%E3%82%8B%E3%83%9E%E3%82%B9%E3%82%BF%E3%83%BC/dp/4938927322)の内容に取り組んでいれば合格できます。

# なぜAccess 2019 Expertに取り組んだのか

私は6月にIT系の会社に転職しました。
そして今の会社でシステムの開発に使われているのがAccessでした。
恥ずかしながら私はAccessの存在は知らなかったので、システム開発をしているところを見学しても、何をやっているのかチンプンカンプンでした。
「このままではマズい……」と感じ、今回の受験を決意しました

# どのように勉強したのか
勉強用の参考書として、[『MOS Access 365&2019 Expert 対策テキスト&問題集』](https://www.amazon.co.jp/Access-2019-Expert-%E5%AF%BE%E7%AD%96%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88-%E3%82%88%E3%81%8F%E3%82%8F%E3%81%8B%E3%82%8B%E3%83%9E%E3%82%B9%E3%82%BF%E3%83%BC/dp/4938927322)を購入しました。
この本には、2つのメリットがあります。
1. **「解説を読む」→「練習問題を解く」というサイクルになっている**
1. **模擬試験プログラムに「ランダム試験」がある**

#### 1. 「解説を読む」→「練習問題を解く」というサイクルになっている
世の中には色々な勉強法がありますが、科学的根拠のある勉強法といえば**検索学習**です。

https://yuchrszk.blogspot.com/2016/11/blog-post_30.html

検索学習というと聞きなれないと思いますが、テストや単語カードなど、勉強した内容を思い出す要素の入った勉強法です。
『MOS Access 365&2019 Expert 対策テキスト&問題集』では、テーブルやクエリなどの各機能について、「解説を読む」→「練習問題を解く」という流れで進んでいきます。
この構成のおかげか、一通り解説と練習問題を解いた段階で、模擬試験では7割ほどの点数を取ることができました。

#### 2. 模擬試験プログラムに「ランダム試験」がある
学習効果が大きいとされる勉強法に**交互学習**があります。

https://www.kobegakushuin.com/blog/about/%E5%8A%B9%E6%9E%9C%E3%81%AE%E5%A4%A7%E3%81%8D%E3%81%AA%E5%AD%A6%E7%BF%92%E6%B3%95%E3%81%A7/

私達が勉強といって思い浮かべるのは、**ブロック練習**です。
ブロック練習は一つのことや、ある章について徹底的に勉強する方法です。
このブロック練習には、「さも身についていると錯覚してしまう」という恐ろしい副作用があります。
本番のテストもブロックごとに出題されるならいいのですが、ほとんどのテストと同じように、Access 2019 Expertも「この時はこの機能を使う」、「この時は別の機能を使う」というように、色々な知識を問う問題がごちゃごちゃになっています。
ともすれば本番で大事なのは、「この問題ではどんな種類の機能を使うべきか」という判断力です。
この判断力を身に付けるには、同じことばかり勉強するブロック練習ではなく、交互練習が必要なのです。

そして、交互練習にうってつけの機能が、模擬試験プログラム搭載された「ランダム試験」です。
ランダム試験は、第1～3回までの模擬試験問題からランダムに問題をピックアップして出題する機能です。
私は一通り本の内容を読んだ後は、このランダム試験を1日1プロジェクト（6問前後）回答し、間違えた操作や忘れていた知識を単語帳に書き込んで、暗唱できるようになるまで毎日単語帳をやるという勉強法を行っていました。
![image-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3842645/037d0d68-41e2-ab2e-89a1-748efb6b300f.png)
その結果、なかなか良い点でAccess 2019 Expertに合格できました。
# まとめ
+ 6月に転職した会社がAccessを使っていたのでAccess 2019 Expertを取ろうと決意し
+ 『MOS Access 365&2019 Expert 対策テキスト&問題集』で検索学習と交互練習を意識したら
+ 1か月で合格できた

というお話でした。
個人的には、模擬試験プログラムのために契約したMicrosoft 365 Personalの無料お試し期間で合格できたのがありがたかったです。
「Accessを使わなきゃいけないけどよくわからない」という方は、Access 2019 Expertを受けなくとも、今回書いた内容で勉強していただければ十二分に知識が身に着くと思うので、参考にしていただければ幸いです。
それではさようなら。
Railsにおけるエラーメッセージの日本語化

# 【課題】
### エラーメッセージをわかりやすい日本語に設定したい
#### 英語表記ではユーザーが視覚的に判断しにくい
#### エラーメッセージが出現した際に、パッと見で何でエラーが起きで弾かれてるのかを判断しやすくしたい


# 【実装】
①Gemファイルへの記述
```ruby:Gemfile
gem 'rails-i18n'
```

②gemを設定したのでここでbundle instalを行う
```ruby:ターミナル
$ bundle install
```
③config/application.rbのファイルを編集
```ruby:config/application.rb
module BoardApp
  class Application < Rails::Application
    config.time_zone = 'Tokyo'
    config.active_record.default_timezone = :local

    # デフォルトのlocaleを日本語(:ja)にする設定
    config.i18n.default_locale = :ja

    config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}').to_s]

  end
end  
```
ここまでの記述で
can't be blank、is invalid、Include both letters and numbersなどが日本語表記になることを確認。
このままではカラム名がまだ英語表記のままになっている

④config/locales/ja.ymlのファイルを作成
```ruby:config/locales/ja.yml
ja:
  activerecord:
    models:
      user: ユーザー
    attributes:
      user:
        nickname: ニックネーム
        email: Eメール
        password: パスワード
        password_confirmation: パスワード（確認用）
        family_name: 名字
        first_name: 名前
        family_name_kana: 名字（カナ）
        first_name_kana: 名前（カナ）
        gender: 性別
        birth_day: 生年月日
  errors:
    messages:
      blank: "を入力してください"
      taken: "はすでに存在します"
      invalid: "は有効でありません"
      too_short: "は%{count}文字以上で入力してください"
      not_a_number: "は数値で入力してください"
      inclusion: "は一覧にありません"
      confirmation: "とパスワード（確認用）が一致しません"
      # カスタムエラーメッセージ
      invalid_password: "は英数字混合で入力してください"
  devise:
    failure:
      user:
        invalid: "メールアドレスまたはパスワードが正しくありません。"
```
![1faad78017bae5aae1f65239469bb4f9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780755/d1ff89a9-8070-63c3-20c5-487a8459f78b.png)

![1d07a84ffe94667e9c5ce15ba9146b91.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780755/c1258ce4-9903-2347-a67a-d9885f23fbb5.png)

無事、全てを日本語表記にすることができました
Spring BootのWebフレームワーク一覧

### はじめに
バックエンドエンジニアを務めていると、Spring BootにおいてWebアプリケーションを構築しようとした際に、どのWebフレームワーク・ライブラリを選択すればよいか迷ったことが一度はあるかと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/418105/0144da04-8514-41f8-92d7-f3ebd6081099.png)
今回は、Spring Initializrにて選択できる各Webフレームワークおよびライブラリの違いをChatGPTに整理してもらいました。

### 1. Spring Web (Spring MVC)
- **目的**: 同期的なWebアプリケーションを構築。
- **特徴**: Model-View-Controller (MVC) パターン。HTTPリクエストを同期的に処理。
- **使用例**: 通常のWebアプリケーション、フォームベースのアプリケーション。

### 2. Spring Reactive Web (Spring WebFlux)
- **目的**: 非同期かつリアクティブなWebアプリケーションを構築。
- **特徴**: リアクティブプログラミングモデル、Project Reactorを使用。非同期リクエスト処理。
- **使用例**: 高パフォーマンスが求められるアプリケーション、リアルタイムデータストリーミング。

### 3. Spring for GraphQL
- **目的**: GraphQL APIの構築を簡単に。
- **特徴**: GraphQLクエリとデータフェッチを効率的に行う。Spring Bootと統合。
- **使用例**: クライアントが必要なデータのみをリクエストするAPI。

### 4. Spring Data REST Repositories
- **目的**: Spring DataリポジトリをRESTfulリソースとしてエクスポート。
- **特徴**: 自動的にCRUDリポジトリからRESTエンドポイントを生成。
- **使用例**: データベース操作を簡単にWeb APIとして公開。

### 5. Spring Session
- **目的**: セッション管理の向上。
- **特徴**: 分散セッション管理、複数のデータストア（Redis、Hazelcastなど）サポート。
- **使用例**: 分散アプリケーションでのセッション管理。

### 6. Spring Data REST HAL Explorer
- **目的**: Spring Data REST APIの探索ツール。
- **特徴**: HAL (Hypertext Application Language) 形式でAPIを表示。リンクとリソースの関係を視覚化。
- **使用例**: REST APIのナビゲーションとデバッグ。

### 7. Spring HATEOAS
- **目的**: REST APIにHATEOAS (Hypermedia as the Engine of Application State) を追加。
- **特徴**: リンクとリソースの関係を定義し、クライアントがAPIをナビゲートしやすくする。
- **使用例**: リッチなREST API設計。

### 8. Spring Web Services (Spring WS)
- **目的**: SOAPベースのWebサービスを構築。
- **特徴**: SOAPメッセージング、WS-*規格のサポート（セキュリティ、トランザクション管理など）。
- **使用例**: 企業間システム統合、大規模なビジネスアプリケーション。

### 9. Jersey
- **目的**: RESTful Webサービスの構築。
- **特徴**: JAX-RS (Java API for RESTful Web Services) のリファレンス実装。Java EEとの統合が容易。
- **使用例**: REST API開発。

### 10. Vaadin
- **目的**: リッチなWebアプリケーションを構築。
- **特徴**: サーバーサイドのUIフレームワーク。JavaでUIコンポーネントを定義。
- **使用例**: 業務アプリケーション、ダッシュボード。

### 11. Netflix DGS (Domain Graph Service)
- **目的**: GraphQL APIの構築。
- **特徴**: NetflixによるGraphQLフレームワーク。ドメイン駆動設計（DDD）をサポート。
- **使用例**: マイクロサービスアーキテクチャにおけるGraphQL API。

### まとめ
- **Spring Web (Spring MVC)**: 同期的なWebアプリケーション。
- **Spring Reactive Web (Spring WebFlux)**: 非同期・リアクティブなWebアプリケーション。
- **Spring for GraphQL**: GraphQL APIの構築。
- **Spring Data REST Repositories**: RESTfulリソースとしてのデータリポジトリ。
- **Spring Session**: 分散セッション管理。
- **Spring Data REST HAL Explorer**: REST APIの探索ツール。
- **Spring HATEOAS**: REST APIにHATEOASを追加。
- **Spring Web Services (Spring WS)**: SOAPベースのWebサービス。
- **Jersey**: RESTful WebサービスのJAX-RS実装。
- **Vaadin**: リッチなWebアプリケーションのサーバーサイドUIフレームワーク。
- **Netflix DGS**: GraphQL APIの構築フレームワーク。