OmniAICreator/Qiita-1.07M huggingface dataset:
ClaudeからBlenderを操作してモデリングを自動化する方法（Windows11対応）

# はじめに
本記事では、以下の課題を解決する方法をまとめました：
* ClaudeへのプロンプトだけでBlenderのモデリングができないか
* Windows上での動作はQiitaや外部の記事でも意外となかった
* uvのインストールコマンドが変更になっていて従来の方法では動作しなかった

今回はWindows11環境でClaudeから指示を出してBlenderでモデリングを行う手順を詳しく解説します。

# 動作環境
* Windows 11
* Blender 4.4.3
* Blender MCP 1.1.0
* Claude 4
* Python 3.11
* uv 0.7.8

# 参考リンク
https://qiita.com/ry033rdqiita/items/6885eba84bfbad7b15ac

# 環境構築
1. Blenderのインストール
[Blender公式サイト](https://www.blender.org/download/)からダウンロードしインストールします。

2. Claude Desktopのインストール
[Claude Desktop公式サイト](https://claude.ai/download)からダウンロードしインストールします。

3. Pythonの確認
BlenderにはPythonが同梱されています。インストール先は以下のパスになります：
C:\Program Files\Blender Foundation\Blender 4.4\4.4\python\bin  

4. Blender MCPアドオンの入手
[blender-mcpのGitHubリポジトリ](https://github.com/ahujasid/blender-mcp)から「addon.py」ファイルをダウンロードします。

5. uvのインストール
:::note warn
重要な変更点
2025年5月末現在、参考記事のインストール方法では正常にインストールできません。以下の新しいコマンドを使用してください。
:::
PowerShellを管理者権限で開き、以下のコマンドを実行します：
```powershell:powershell
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
```

# Claude Desktopの設定
1. Claude Desktop起動後、画面左上から「ファイル->設定(またはCtrl+カンマ)」を選択
1. 「構成を編集」をクリックするとフォルダが開き、claude_desktop_config.jsonが表示されます
1. 「claude_desktop_config.json」を以下のように編集します
1. Claude Desktopを再起動すると項目に「blender」が表示されます

```json
{
    "mcpServers": {
        "blender": {
            "command": "uvx",
            "args": [
                "blender-mcp"
            ]
        }
    }
}
```

![画像8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4103380/e180cacd-7a14-4fa4-80e2-3761fc62d455.png)


# Blenderの設定
1. Blenderを起動
1. メニューから「編集 → プリファレンス → アドオン」を選択
1. 「ディスクからインストール」でダウンロードした「addon.py」を選択してインストール
1. 「Blender MCP」にチェックが入っていることを確認
1. 3Dビューポートでデフォルトの立方体が表示されている状態でNキーを押下
1. 3Dビューサイドバーの「Blender MCP」タブを開く
1. 「Connect to MCP Server」をクリックして接続

![画像10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4103380/dc43590b-73f8-48d7-9ad5-8d141118a480.png)

# 動作確認
以下のプロンプトでテストしてみましょう：

```prompt
Blenderで三角錐をモデリングしてほしい
```
Claudeが応答し、自動でモデリングが開始されます。
<iframe width="560" height="315" src="https://www.youtube.com/embed/R16M_KHPq5A?si=NM-jc59byd2ofwbj" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

# まとめ
Windows11環境でClaudeを通してBlenderを操作する環境構築方法をまとめました。特にuvのインストール方法の変更点は重要なポイントです。この連携により、自然言語でのモデリング指示が可能になります。
char⇔コードポイント変換をしたい

charからコードポイントを取得したい場合は、単に整数型にキャストすればよいです。

```rust
let codepoint = 'A' as u32;
println!("{}", codepoint); //=> 65
```

逆に、コードポイントからcharを取得したい場合は、`std::char::from_u32`を利用します。

```rust
let character = std::char::from_u32(65).unwrap();
println!("{}", character); //=> A
```

**環境情報**

- rustc 1.83.0 (90b35a623 2024-11-26)
- cargo 1.83.0 (5ffbef321 2024-10-29)
【Supabase】条件によってwhere句を動的に変更したい

# はじめに
Supabaseでデータを取得する際に、条件によってWhere句のパラメータを変えたいと考えていました。
意外とシンプルな方法で解決できたため、調べたことをまとめました。

# 問題
パラメータの値によってWhere句を変更したい。

```tsx
export const getDataByAlcohols: (
  props: AdditivesSearch
) => Promise<Partial<Alcohols>[]> = async (props) => {
  const { sake_name, maker } = props;
  const { data, error } = await supabase
    .from("alcohols")
    .select("* , alcohol_genres(genre_name) , manufacturers(manufacturer_name)")
    .like(`sake_name`, `%${sake_name}%`)
    .eq(`manufacturer_id`, `${maker}`); //ここでmakerが空の時はこの条件をつけたくない
};
```

# 解決
queryを変数で格納し、if文で条件を追加する

```diff_tsx
export const getDataByAlcohols: (
  props: AdditivesSearch
) => Promise<Partial<Alcohols>[]> = async (props) => {
  const { sake_name, maker } = props;
-  const { data, error } = await supabase
+  let query = supabase
    .from("alcohols")
    .select("* , alcohol_genres(genre_name) , manufacturers(manufacturer_name)")
    .like(`sake_name`, `%${sake_name}%`);

+  if (maker) {
+    query = query.eq(`manufacturer_id`, `${maker}`);
+  }
  
+  const { data, error } = await query;
};
```

# おわりに
条件によってWhere句を変えたい、and検索やor検索だけでは実現できないな、難しいなと考えていました。意外とシンプルな方法で解決できました。

# 参考
https://github.com/supabase/supabase/issues/4274
【読書感想】40歳でGAFAの部長に転職した僕が20代で学んだ思考法

ランニングしながらAudibleで聴いた本の感想です。
本のまとめというより、自分が心に残ったことを3つだけ書いてます。
とりあえず思ったことをメモするのが大切と思い、なるべく30分以内で書き上げています。

# 聴いた本
40歳でGAFAの部長に転職した僕が20代で学んだ思考法
寺澤 伸洋 (著)

仕事術の本です。対話形式で進んでいくので、Audibleと相性が良かったです。内容もエッセンスが詰まっており、良かったです。
ただ、筆者の方は「経営企画室」などの非技術職とのことで、技術系のキャリアの人間には「それはどうだろう」という部分が一部あった気がします。
（個人的満足度２．５／３、一般的なおすすめ度２．５／３）

# 心に残ったこと

## 考える＝要素分解

別の本でもありましたが、仕事では「悩む」のではなく「考える」をしたほうが良いとのことでした。
その「考える」とは、「要素分解すること」とのことでした。
**要素分解には、広さと深さがありますが、最初に広さをイメージする**と良いようです。

仕事上でも、よく、複数部署にまたがり、どの事業部の人も手を出したがらない「手垢の付かない白いボール」がありますが、**要素分解して誰かのタスクにすることで、仕事が進む**とのことでした。

## 視野、視座、視点

要素分解する上で、この3つが大事とのことでした。
視野は、より広く情報を集めること、視座は、より高いレイヤで物事を考えること、視点は、多面的に物事を見ることを指します。

この3つを大事にしていくと、細々とした仕事をこなすより、ストーリーを作って他人を動かす仕事のほうが視座が高く、視座の高さを身につけるために、このような仕事に積極的に打ち込むべき、とのことでした。
技術系職業だと、プレイヤーで高く評価される場面もあるので、100%鵜呑みにはできませんが、マネージャー的なポジションの方が一般的にポジションが高いため、正しい面も多いなと感じました。

この3つに関連して、「今仕事ができる人を、中長期的なPJにアサインする」のは良いとは限らないとのことでした。
今仕事ができる人は、今の仕事のプロではありますが、視野・視座・視点が高いとは限らない、何なら固執してしまうこともあるからです。

## ボックス思考

「話の枠を示して、埋めていく」という話し方のことです。大枠を先に説明するイメージです。
次のステップで話を組み立てていきます。

1. 対比の枠を最初に作る
1. コンテンツを枠に入れていく
1. 共通点は最後にまとめ説明する

よく「話が伝わらない」場合がありますが、「伝える側が下手」と思ったほうが良いようです。
ボックス思考は、普段から物事を伝える際に活用したいなと思いました。

また、プロジェクトの初期段階で検討すべき事項（テンプレートという意味合いではボックス？）として、目的・目標・範囲・体制・スケジュールの5つがあると紹介されていました。
これも、5つのボックスを用意してから埋めていくと良さそうです。
DatabricksのCLIをインストールしてプロファイルを構成してみた(Mac OS)

## 前提
・OS：Mac OS
## 参考ドキュメント
https://docs.databricks.com/aws/ja/dev-tools/cli/install

<iframe width="560" height="315" src="https://www.youtube.com/embed/5WYh5GU3erA?si=7n6c7GDfuq_wt31W" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

<iframe width="560" height="315" src="https://www.youtube.com/embed/NkoqH7iAjEo?si=mCeQjsZVOjgyaYxF" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

## 手順
### 1.Homebrewをインストール
```/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562390/ddc9a92e-873e-450a-974b-c1bd8e5f052d.png)
（途中でPCのパスワードを求められるが、それを入力しEnter）
### 2.Next stepsで書いた内容を確認し、コピーして実行
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562390/f0093468-6cb2-4f54-96c8-1ac5ee3e21e5.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562390/d14882df-3c34-4292-9f87-084137c0c53b.png)
### 3.Homebrewのバージョンを確認
```brew -v```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562390/17ffc8c9-f878-4719-8208-210d6b4cd15d.png)
### 4.Homebrewを使って、GitHubのdatabricks/homebrew-tapリポジトリを、利用可能なHomebrew Tapリポジトリの一覧に追加
```brew tap databricks/tap```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562390/5d6720fd-4376-4882-a581-715fcd93957a.png)
### 5.Homebrewを使って、Databricks CLI実行可能ファイルをダウンロードしてインストールするようdatabricks/homebrew-tapリポジトリに指示
```brew install databricks```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562390/14028e59-56f7-4bc8-8929-36226a8b323a.png)
### 6.Databricks CLI が正しくインストールされているかどうかを確認
```databricks -v```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562390/91cc9ddd-1afa-4c0b-86b8-02da2aea4696.png)
### 7.プロファイルを作成
```databricks configure --profile prod_ws```
・Databricks host：ワークスペースのURL（.comまで）
・アクセストークン：Databricksのワークスペースで作成したアクセストークン
### 8.テスト
```databricks clusters spark-versions -p prod_ws```

以上
【React初心者メモ】分割代入

# 分割代入とは
分割代入とは、配列やオブジェクトから値を取り出して、複数の変数に一気に代入できる書き方のことです。

# 配列の分割代入
通常：
```
const arr = [10, 20, 30];
const a = arr[0];  // 10
const b = arr[1];  // 20
const c = arr[2];  // 30
```
分割代入を使うと：
```
const [a, b, c] = [10, 20, 30];
console.log(a, b, c);  // 10 20 30
```
配列の一部だけ使うこともできます。
```
const [first, second] = [100, 200, 300];
console.log(first);  // 100
console.log(second); // 200
```
#  オブジェクトの分割代入
通常：
```
const obj = { name: "Alice", age: 25 };
const name = obj.name;  // "Alice"
const age = obj.age;    // 25
```
分割代入を使うと：
```
const { name, age } = { name: "Alice", age: 25 };
console.log(name, age);  // Alice 25
```
オブジェクトの一部だけ使うこともできます。
```
const { name } = { name: "Bob", age: 40 };
console.log(name);  // Bob
```
# 関数の引数での分割代入
関数の引数で{ name, age }と書くと、渡されたオブジェクトの中からnameとageを直接変数として取り出して使えます。
```
const greet = ({ name, age }) => {
  console.log(`こんにちは、${name}さん。年齢は${age}歳ですね。`);
};

const user = { name: "太郎", age: 30 };
greet(user);
```
デフォルト値もつけられます。
```
const greet = ({ name = "名無し", age = 0 } = {}) => {
  console.log(`こんにちは、${name}さん。年齢は${age}歳ですね。`);
};

greet({ name: "花子", age: 25 }); // ちゃんと値がある場合
greet();  // 引数なしでもエラーにならずデフォルト値が使われる
```
8086実機 × QEMUで検証　 0x1F7ポートを使った起動装置判定法

## 「手探りでCUI OS作成に挑む」連載
この記事は「手探りでCUI OS作成に挑む」連載の一部です。
全体の目次は[「手探りでCUI OS作成に挑む」連載目次](https://qiita.com/earthen94/items/b5d77f98f0cf85a13346)を御覧下さい。

## 目的
将来BIOSを開発するにあたり、INT 13H(ディスク読み込み)も自分で実装する必要があります。
データを読み込む対象の装置によって接続方法が異なるので、自分の普段動作確認に使っているQEMUがフロッピー起動扱いなのかHDD起動扱いなのかを検証します。
せっかくなので8086実機でも動かしてみます。
筆者の所有している8086実機はチップだけ当時のものでそれ以外は新しい部品を使用して生産されたものです。(復刻機)
CF(コンパクトフラッシュ)から起動していて実際にはフロッピーもHDDも接続されていません。
良い機会なのでどちらの扱いになっているかを確認します。

## 検証コード
IDEコントローラの状態レジスタ(ポート:0x1F7)から応答があればHDD、なければフロッピーと判断する簡易的な判別です。
起動ディスク以外には何も繋いでいないのでこれで足りるでしょう。
```boot.asm
bits 16
org 0x7C00

start:

    xor ax, ax
    mov ds, ax
    mov es, ax
    mov ss, ax
    mov sp, 0x7C00
    
    ; TXTモードを明示的に設定して間接的に画面クリア
    mov ax, 0x0003
    int 0x10

    ; 起動装置判別
    call detect_boot_device
    
    ; 結果を表示
    cmp byte [boot_device], 0
    je .floppy
    cmp byte [boot_device], 1
    je .harddisk
    jmp .unknown

.floppy:
    mov si, floppy_msg
    jmp .print_msg

.harddisk:
    mov si, hd_msg
    jmp .print_msg

.unknown:
    mov si, unknown_msg

.print_msg:
    call print_string
    jmp $

; 起動装置判別
; 出力: [boot_device] = 0 (FDD) 或 1 (HDD)
detect_boot_device:

    ; ポートから読み取った値が 0xFF（全ビット1）
    ; であれば応答はなくHDDは接続されていないと判断
    mov dx, 0x1F7     ; IDEコントローラの状態レジスタ
    in al, dx
    cmp al, 0xFF
    je .likely_floppy
    
    ; HDD
    mov byte [boot_device], 0
    ret
    
    ; FDD
.likely_floppy:
    mov byte [boot_device], 1
    ret

print_string:
    lodsb
    or al, al
    jz .done
    mov ah, 0x0E
    int 0x10
    jmp print_string
.done:
    ret

boot_device db 0
floppy_msg db "Booted from floppy disk", 0x0D, 0x0A, 0
hd_msg db "Booted from hard disk", 0x0D, 0x0A, 0
unknown_msg db "Booted from unknown device", 0x0D, 0x0A, 0

times 510-($-$$) db 0
dw 0xAA55
```

## 動作確認

### QEMU
```
nasm -f bin boot.asm -o boot.bin
qemu-system-i386 -fda boot.bin
```
フロッピー起動と判別された
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4054974/d6ac9db2-1dad-450e-b13b-e1e9d2a5eae6.png)


### 8086実機
```
sudo dd if=boot.bin of=/dev/sdc bs=512 count=1 conv=notrunc
```
HDD起動と判別された
![微信图片_2025-06-07_111703_442.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4054974/8b580f37-48b1-4acc-b82f-c63de82fb032.png)

### MSIゲーミングノート(MS-16R4)
BIOSの設定をUEFIからLegacyBIOSへ変更し現代のパソコンでも試してみました。
未知の機器のようです。現代は仕様が全然違う？
![微信图片_2025-06-07_113620_845.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4054974/ee109151-ff78-4bbc-bb78-664e2b980f30.png)

## 間違い訂正(当日)
そもそもQEMUを立ち上げる時に-fdaオプションをつけてフロッピー扱いにしていました。
かなり前に書いたコマンドを何も考えずに使いまわしており気づきませんでした。

```
qemu-system-i386 -hda boot.bin
```
画面クリアを消すと、QEMUはHDDから立ち上げているのに判別がおかしくHDDとして判定されていました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4054974/e0bb2bdf-4657-457b-826d-d7db3fa16aff.png)

どこで間違えたのか分からない為後日検証し直します。
【rails】あるviewだけヘッダーやフッターを表示させない方法


## はじめに

こんにちは。アメリカ在住で独学エンジニアを目指している Taira です。
現在、Rails チュートリアルのアウトプットとしてアプリを製作しています。
認証周りは devise を使用しており、パスワード変更の view の実装をしていました。
普段は header・footer を書いているけど、この view の時は header・footer を表示させたくないみたいな場面って出てくるのではないでしょうか
今回はそんな場面で、view を切り替える方法について記事にしていきたいと思います。

## 手順

### 1. views/layouts に別途表示用の view ファイルと作成

```html
<!DOCTYPE html>
<html>
  <head>
    <title><%= content_for(:title) || "Todo Application" %></title>
    <meta name="viewport" content="width=device-width,initial-scale=1" />
    <meta name="apple-mobile-web-app-capable" content="yes" />
    <meta name="mobile-web-app-capable" content="yes" />
    <%= csrf_meta_tags %> <%= csp_meta_tag %> <%= yield :head %> <%# Enable PWA
    manifest for installable apps (make sure to enable in config/routes.rb too!)
    %> <%#= tag.link rel: "manifest", href: pwa_manifest_path(format: :json) %>

    <link rel="icon" href="/icon.png" type="image/png" />
    <link rel="icon" href="/icon.svg" type="image/svg+xml" />
    <link rel="apple-touch-icon" href="/icon.png" />

    <%# Includes all stylesheet files in app/assets/stylesheets %> <%=
    stylesheet_link_tag "tailwind", "inter-font", "data-turbo-track": "reload"
    %> <%= stylesheet_link_tag :app, "data-turbo-track": "reload" %> <%=
    javascript_importmap_tags %>
  </head>

  <body class="flex flex-col min-h-screen">
    <%= render 'shared/flash' %> <%# headerとfooterのみを削除した%>
    <main class="flex-grow"><%= yield %></main>
  </body>
</html>
```

上記のように `views/layouts/application.html.erb`からコピーし,header と footer のみを削除した`views/layouts/minimal.html.erb`を作成します。
minimal の部分は適宜変えて問題ありません

### 2. コントローラーに layout 'minimal'を記述

```ruby
class Users::PasswordsController < Devise::PasswordsController
  layout 'minimal', only: [:edit,:update]
  # GET /resource/password/new
  def new
    super
  end

    # GET /resource/password/edit?reset_password_token=abcdef
  def edit
    super
  end

  # PUT /resource/password
  def update
    super
  end
end
```

今回私は password リセットの際に`minimal`のテンプレートを適応させたかったので、上記のように書きました。
ここで、update も layout を minimal にしているのは、パスワードの変更でエラーになった場合その時に呼ばれているは update アクションなので設定していないとデフォルトの application.html.erb が呼ばれてしまいます。
【React初心者メモ】レスト構文（...）

# レスト構文とは
レスト構文とは、関数の引数や配列・オブジェクトの分割代入の際に、残りの値をまとめて1つの変数に受け取るために使います。

# 具体例
### 関数の引数でのレスト構文
```
function sum(...numbers) {
  // ...numbersは配列として残りの引数を全部受け取る
  return numbers.reduce((a, b) => a + b, 0);
}
console.log(sum(1, 2, 3));  // 6
console.log(sum(4, 5));     // 9
```

### 配列の分割代入でのレスト構文
```
const [first, ...rest] = [10, 20, 30, 40];
console.log(first);  // 10
console.log(rest);   // [20, 30, 40]
```

### オブジェクトの分割代入でのレスト構文
```
const { a, ...others } = { a: 1, b: 2, c: 3 };
console.log(a);       // 1
console.log(others);  // { b: 2, c: 3 }
```
【React初心者メモ】スプレッド構文（...）

# スプレッド構文とは
配列やオブジェクトの要素やプロパティを「展開」して、別の配列やオブジェクトにコピー・結合・分解するための構文です。

# 配列でのスプレッド構文
### 配列のコピー
```react
const arr1 = [1, 2, 3];
const arr2 = [...arr1];
console.log(arr2);  // [1, 2, 3]
// arr1とは別の新しい配列が作られる
```
### 配列の結合
```react
const arr1 = [1, 2];
const arr2 = [3, 4];
const combined = [...arr1, ...arr2];
console.log(combined);  // [1, 2, 3, 4]
```
### 配列の要素の分解
```react
const numbers = [10, 20, 30];
console.log(...numbers);  // 10 20 30
```
```react
// 関数呼び出し時に使うと、配列を個別の引数として渡せます。
function sum(a, b, c) {
  return a + b + c;
}
const nums = [1, 2, 3];
console.log(sum(...nums));  // 6
```

# オブジェクトでのスプレッド構文

### オブジェクトのコピー
```react
const obj1 = { a: 1, b: 2 };
const obj2 = { ...obj1 };
console.log(obj2);  // { a: 1, b: 2 }
```
### オブジェクトのマージ
```r
const obj1 = { a: 1, b: 2 };
const obj2 = { b: 3, c: 4 };
const merged = { ...obj1, ...obj2 };
console.log(merged);  // { a: 1, b: 3, c: 4 }
```
RTX 5090 が NVIDIA Driver と疎通しない問題を解消した @ Ubuntu 24.04

メモとして。

結論は: **PCI リソースの割り当て不足**。

---

Ubuntu 24.04 マシンに RTX 5090 を挿して起動したところ、低解像度の映像が出力された。
`nvidia-smi` を実行すると以下のエラーが表示された。

```bash
$ nvidia-smi
NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver. Make sure that the latest NVIDIA driver is installed and running.
```

ドライバーはインストール済み。 [^1]

```bash
$ dkms status
nvidia/575.57.08, 6.8.0-60-generic, x86_64: installed
```

認識はしている。 [^2]

```bash
$ lspci | grep -i nvidia
08:00.0 VGA compatible controller: NVIDIA Corporation GB202 [GeForce RTX 5090] (rev a1)
08:00.1 Audio device: NVIDIA Corporation Device 22e8 (rev a1)
```

メッセージを確認。

```bash
$ sudo dmesg | grep -i nvidia
...
[    3.984467] NVRM: This PCI I/O region assigned to your NVIDIA device is invalid:
...
```

PCI リソース割り当ての問題で、 RTX 5090 の性能が高すぎることが原因になっている模様。

`/etc/default/grub` の `GRUB_CMDLINE_LINUX_DEFAULT` を以下のように変更。

```
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash pci=realloc pci=nocrs"
```

`pci=realloc` によって規定のリソース割り当てを割り当て直す / `pci=nocrs` によって BIOS が決めた枠を無視しています。

更新して再起動。

```bash
$ sudo update-grub
$ sudo reboot
```

動いた。

```bash
$ nvidia-smi
Sat Jun  7 11:48:51 2025
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 575.57.08              Driver Version: 575.57.08      CUDA Version: 12.9     |
|-----------------------------------------+------------------------+----------------------+
| GPU  Name                 Persistence-M | Bus-Id          Disp.A | Volatile Uncorr. ECC |
| Fan  Temp   Perf          Pwr:Usage/Cap |           Memory-Usage | GPU-Util  Compute M. |
|                                         |                        |               MIG M. |
|=========================================+========================+======================|
|   0  NVIDIA GeForce RTX 5090        On  |   00000000:08:00.0 Off |                  N/A |
|  0%   47C    P8             23W /  575W |     192MiB /  32607MiB |      0%      Default |
|                                         |                        |                  N/A |
+-----------------------------------------+------------------------+----------------------+

+-----------------------------------------------------------------------------------------+
| Processes:                                                                              |
|  GPU   GI   CI              PID   Type   Process name                        GPU Memory |
|        ID   ID                                                               Usage      |
|=========================================================================================|
|    0   N/A  N/A            1939      G   /usr/lib/xorg/Xorg                      115MiB |
|    0   N/A  N/A            2051      G   /usr/bin/gnome-shell                     21MiB |
+-----------------------------------------------------------------------------------------+
```

[^1]: `nvidia-open` を使っています。 5090 は `cuda-drivers` だと動かないという報告があったので…真相は不明。
[^2]: 最初は単に `VGA compatible controller: NVIDIA Corporation Device` のようになっていて、製品名を認識していなかったので、 `sudo update-pciids` を実施して製品名を認識させた後で NVIDIA ドライバーの入れ直しをしました。
OpenHandsでCursor Rules的な指定をする

## 概要

AIエージェントツールOpenHandsのチャットで「必ず日本語で回答してほしい」「プロジェクトの方針を認識してほしい」といったルールを徹底したい場合があります。Cursorでは`User Rules`や`Project Rules`として指定できますが、[**OpenHands**](https://github.com/All-Hands-AI/OpenHands)ではどう実現するのでしょうか？

この記事では、**OpenHandsでプロンプトルールを指定する方法**をまとめます（2025年6月時点）。

---

## OpenHandsのルール指定方法

OpenHandsでは、`.openhands/microagents`ディレクトリ以下にMarkdownファイルを配置して、各種ルールやプロジェクト概要をAIエージェントに認識させることができます。

```
some-repository/
└── .openhands/
    └── microagents/
	    └── org-microagent.md  // 組織または個人のルール
        └── repo.md            // リポジトリの説明、ルール
        └── trigger1.md        // キーワードで発火するルール
        └── trigger2.md        // キーワードで発火するルール
        
```

### 1. ユーザー個別のルール設定（User Rules的なもの）

`.openhands/microagents/org-microagent.md`を作成し、下記のように記述します。

```markdown: org-microagent.md
* 日本語で回答してください。
* 型ヒントやエラーバウンダリを使用し、システムの境界で入力値を検証し、意味のあるエラーメッセージで失敗させること。
* インターフェースや公開APIにはドキュメントを記述し、実装に関するコメントは非自明なロジックについてのみ記載すること。
* 各リポジトリで既に使用されている命名規則（変数、クラス、定数など）に従うこと。
```

このファイルに書いた内容は、OpenHands内の全チャットに自動適用され、常に指定したルールに沿った対応が得られるようになります。

---

### 2. プロジェクト全体のルール設定（Project Rules的なもの）

プロジェクトの概要や方針を常に認識させたい場合は、`.openhands/microagents/repo.md`に記述します。

```markdown: repo.md
このプロジェクトは、ユーザーがTODOアイテムを管理できるTODOアプリケーションです。

セットアップするには、`npm run build` を実行してください。  
変更をコミットする前には、必ずテストがすべて成功していることを確認してください。テストは `npm run test` で実行できます。
```

これにより、OpenHandsはプロジェクトの目的やルールを前提に対応します。

---

### 3. キーワードトリガーによる自動応答ルール

特定のキーワード（トリガーワード）でAIに特定応答をさせたい場合、`.md`ファイルの先頭で指定します。

```markdown: yummy.md
---
triggers:
- yummyhappy
- happyyummy
---

ユーザが魔法の言葉を使ったら、「美味しかった！」と答えてください。
```

この仕組みを使えば、「合言葉で定型応答」「コマンドによるマクロ動作」など、より高度な自動化も可能です。

---

## まとめ

OpenHandsでCursorのように、ルールを指定したいときは、 .openhands/microagents 以下に記述できます。

---

## 参考

- [OpenHands 公式ドキュメント](https://docs.all-hands.dev/)
【React初心者メモ】三項演算子（?  :  ）

# 三項演算子とは
以下のように条件によって値を選ぶ短縮表現です。
```
条件式 ? 真の場合の値 : 偽の場合の値
```

# 具体例
三項演算子の場合は以下のようになります。
```
const age = 20;
const message = age >= 18 ? "成人です" : "未成年です";
console.log(message);  // "成人です"
```
if文の場合は以下のようになります。
```
const age = 20;
if (age >= 18) {
  message = "成人です";
} else {
  message = "未成年です";
}
```
wildflyの管理ユーザーの追加

# はじめに

tomcatからwildflyに切り替えました。数年前たったので、バージョンアップを試みました。

バージョンアップ前： Wildfly29  (2023/08/26)
バージョンアップ後： Wildfly35  (2025/02/06)
Javaのバージョン  17

管理ユーザーを追加しようと思いましたが、数年前たって、忘れかけているので、自分用にメモを残します。

# add-user

ユーザーを追加するのは add-user で出来ます。
しかし、 adminというユーザは既に登録されています。
これを上書きするべきなのか、別のユーザIDをつくるべきなのか、よくわからなかったのでChartGPTに聞いてみました。

# ベストプラクティス

「admin以外のユーザーID」を作成。
その後、既存のadminを削除するのが良いとの事でした。

必ず、他の管理ユーザー（例: yournameadmin）をadd-user.shで登録してから adminユーザーを削除するようにしましょう。

# 追加方法

cd <WILDFLY_HOME>/bin
./add-user.sh

選択肢: 1 (Management User)
User name: admin以外
パスワード: お好みで

# 既存のadminの削除

WildFlyで既定の「admin」ユーザー（管理者ユーザー）を削除する方法は、登録されているユーザー情報ファイルを直接編集する形になります。
以下の手順で削除してください


1. WildFlyのホームディレクトリへ移動
通常、WildFlyを解凍した場所（例: /opt/wildfly や /home/wildfly/wildfly-35.0.0.Final など）が <WILDFLY_HOME> です。

2. 認証ファイルの場所
standaloneモードの場合、認証情報は <WILDFLY_HOME>/standalone/configuration/ にあります。
管理ユーザー（managementユーザー）のファイル:
mgmt-users.properties
mgmt-groups.properties



3. 「admin」ユーザーのエントリを削除
3.1. ファイルのバックアップ
まず、念のためバックアップを作成します。


cd <WILDFLY_HOME>/standalone/configuration/
cp mgmt-users.properties mgmt-users.properties.bak
cp mgmt-groups.properties mgmt-groups.properties.bak


3.2. adminユーザーの行を削除
(1) mgmt-users.properties
下記のような行があります:

admin=xxxxxxxxxxxxxxxxx


この「admin=...」という行を削除します。
(2) mgmt-groups.properties
下記のような行があります:

admin=Administrators

この「admin=...」という行も削除します。

4. WildFlyを再起動
設定を反映させるため、WildFlyを再起動します。


cd <WILDFLY_HOME>/bin
./standalone.sh
Java Silver合格までの道

黒本の総仕上げ問題1回分やってみましたが結果は:joy:

このままじゃ絶対合格しない:scream:
ということでもう一度最初から演習問題解きなおしています。
とくに7章の継承、インタフェース、抽象クラスが苦手みたい…

この土日である程度練習問題解いたら来週末はもう1回分の総仕上げ問題をちゃんと時間をはかってやってみようと思います。

業務では全くJavaを使っていないので、どんどん違う言語の知識は入ってしまい混乱する前にしっかりと合格しようと思います。
担当機能やタスクアサインを超柔軟にしていた開発チームの話

# はじめに
あじ太郎が今までに入った開発チームは、事業会社に所属していたときの自社システムでもお客様のシステムでも、たいていはメインで担当する機能やタスクの範囲などがある程度決まっていることが多かったです。
もしくは、エンジニアが少ないので全部担当！みたいな感じでした。

その中で、担当機能やタスクアサインを柔軟にしていた開発チームに入ったことがありました。

今回は、一般的な話と、その開発チームでのあじ太郎の気づきを語ってみたいと思います。

# 一般的に各開発者に対して担当する機能や作業内容を決める／決めないとどんなメリット、デメリットがあるか？
まずは一般的なメリット、デメリットを確認しておきます。
（ここではかなり簡単な話にしていますが、実務では担当範囲の境目はグラデーションがかかっているし、そもそもこんなに単純ではないと思いますが、あくまで一般的にはということで）

・専属で担当する機能や作業内容を決める場合
例えば「Aさんはユーザー管理機能、Bさんは決済機能」みたいに専属の担当を決めるやり方です。
作業内容についても仕様調整する人、プログラムする人みたいに分かれている開発チームもあるのではないでしょうか。

メリットは、担当する機能やタスクに詳しくなり専門性が高まりやすいこと。
担当範囲については作業が速い。
エンジニアの希望と担当範囲が一致した場合は愛着がわきやすいといった効果も。
不具合が出たときも該当箇所に詳しい担当者だと対応がスムーズ。
デメリットはなんといっても属人化しやすいこと。
たとえば担当者が不在のときトラブルが起きると、他の人がすぐに対応できない場合も。

・専属で担当する機能や作業内容など決めずに開発を進める場合

先ほどとメリット、デメリットが反対になりますね。
属人化しにくいので、特定の担当者でなくても他の人がフォローしやすい。
でも、責任範囲があいまいになりやすかったり、キャッチアップが必要だったり。

おおまかに上記のような特徴が挙げられると思います。

# タスクアサインを柔軟にしていた開発チーム
ここから、あじ太郎の経験をお話します。
複数のサブシステムからなるサービスの開発チームに入ったときのこと、
当時、エンジニアが１５人前後いて、全員、全体的に見ていました。

そのタスクアサインは、自分が経験した中ではもっとも柔軟なものでした。

例えば、
ある機能追加では
`要件定義はＡさん⇒設計はＢさん⇒プログラムはＣさん⇒テストはＤさん、`
その機能をさらに改修する際に、単純に前と同じ人をアサインするとは限らず、
`要件定義はＣさん⇒設計はＤさん⇒プログラムはＥさん⇒テストはＦさん、`
みたいなアサインになることも。

また、テストで不具合が発見されたら、プログラムしたＣさんやＥさんが対応する場合もあれば、別のＡさんやＤさんが調査～修正することも普通ですし、突然Ｇさんが対応することも。

調査や保守タスクが発生すれば、みんなで分担してやってたな。
チームの中で、自分が最初に担当した保守作業はSQLを考えたり手順書を作ったりもしたけど、専属にならないこともあり２回目以降、他の人が対応していたと思います。
同じタスクは同じ人に継続して任せるチームも多いと思いますが、当時そんなことはなかったです。

調査やキャッチアップすることも多くなりやすいし、当時は、なんでここまで柔軟なアサインを徹底しているのかな？と不思議で、たしか周りの人にも質問もしたけど明確な答えはわからず。

# 気づき
その後、別の職場に異動となり、エンジニアそれぞれに対して専属で担当機能を決めている開発チームで奮闘しつつ、他のこともやりたいなと思った、そのときに気づいたことが！

担当機能や作業内容を決め打ちせず、アサインを柔軟にすることで、いろいろ挑戦しやすい環境になっていたなと。
もう一つ、各自の希望と異なることを一時的に担当することはあるけれど、そこにロックインされないというメリットもありそうです。

世の中には個人のスキルや視座によって仕事を広げる人がいて、それは素晴らしいことではありますが、
柔軟なアサインを徹底することによって、個人が仕事を広げやすい環境をチームの仕組みとして実現できていたのかもしれないと思いました。

あと、休暇も取りやすかったけど、これも各自の気持ちの問題ではなく属人化の少ないチームの仕組みによって担保されていたと思います。

リーダーがこういったことを意図していたかはわからないですし、当然、チームを取り巻く状況によって同じやり方でもうまくいかない場合もありそうですが、その時はうまくはまってました。

# さいごに
当時よくわからなかったけど、きっと仕組みにうまくのせてくれてたのかなと、改めて感謝したあじ太郎なのでした。
【React初心者メモ】ヌリッシュ合体演算子（??）

# ヌリッシュ合体演算子とは
ヌリッシュ合体演算子とは、左の値が null または undefined の場合だけ、右の値を返す演算子です。それ以外（例えば空文字 "" や 0、false などの「falsy」だけど null や undefined じゃない場合）は、左の値をそのまま返します。


具体例
```
// name は "名無し"
const name = null ?? "名無し";  
// age は 0 （0はnullでもundefinedでもないのでそのまま）
const age = 0 ?? 20;
// text は "" （空文字もそのまま）
const text = "" ?? "空文字";    
```
# 何のために使われるのか？
値が存在しない（nullかundefined）場合だけデフォルト値を使いたいときに便利です。
||（論理和）と似ていますが、|| は falsy 全般（0 や "" や false も含む）に反応してしまうため、意図しない動きをすることがあります。

||との比較例
```
const age1 = 0 || 20;          // 20 が返る（0は falsy）
const age2 = 0 ?? 20;          // 0 が返る（0は null/undefined ではない）

const name1 = "" || "名無し";    // "名無し" が返る（""は falsy）
const name2 = "" ?? "名無し";    // "" が返る（""は null/undefined じゃない）
```
【SadServers学習メモ #4】使ったコマンドまとめ（nmap）

# 初めに
Linuxの学習目的で`SadServers`を始めました。
備忘のために使用したコマンドをアウトプットします。

# SadServersとは
Linuxの学習サイト。
架空のサーバを題材とし、その管理者となって与えられた依頼をこなしていく。
実際にコマンドを使って作業をすることで、実践的なスキルが身につくことが期待できる。

https://sadservers.com/

# 今回のお題
## タイトル
["Taipei": Come a-knocking](https://sadservers.com/scenario/taipei)

## 詳細
* サーバのポートノッキングを突破し、`curl localhost`を実行できるようにする。

### ポートノッキングとは
ポートの隠蔽技術の一つ。
あるポート（例えば80）を開くために別のポートを連続で叩く（1000, 2000, 3000）必要があるようにしておくことで、知っている人しかポートを利用できないようにする技術。パスワードみたいなイメージ。
この1ooo, 2000, 3000のような、解除するためのポートの連続を「ノックシーケンス」と呼ぶ。


## 作業の流れ
* ポートノッキングを突破するだけなので、思い当たるポートを連続で叩く
  * 今回はノックシーケンスの長さが1なので、全部のポートをたたけば解決できる

# 使ったコマンド
## nmapコマンド
* ポートスキャン用のコマンド
* 指定したIPとポートをスキャンすることができる

以下は、`127.0.0.1`に対し、`200-1000`の全てのポートをスキャン
```sh
$ nmap -p 200-1000 127.0.0.1
```

`-p-`で全てのポートを指定することができる
```
$ nmap -p- localhost
```

全てのポートを指定したところ、二回目の実行で80が開いたことが分かる。
ポートノッキングの解除が成功し、隠されていた80ポートを開くことができた。
```sh
$ nmap -p- localhost
Starting Nmap 7.80 ( https://nmap.org ) at 2025-06-07 02:08 UTC
Nmap scan report for localhost (127.0.0.1)
Host is up (0.0019s latency).
Not shown: 65532 closed ports
PORT     STATE SERVICE
22/tcp   open  ssh
6767/tcp open  bmc-perf-agent
8080/tcp open  http-proxy

Nmap done: 1 IP address (1 host up) scanned in 1.56 seconds
$
$
$ nmap -p- localhost
Starting Nmap 7.80 ( https://nmap.org ) at 2025-06-07 02:08 UTC
Nmap scan report for localhost (127.0.0.1)
Host is up (0.000071s latency).
Not shown: 65531 closed ports
PORT     STATE SERVICE
22/tcp   open  ssh
80/tcp   open  http
6767/tcp open  bmc-perf-agent
8080/tcp open  http-proxy

Nmap done: 1 IP address (1 host up) scanned in 2.03 seconds
```


# 終わりに
ポートノッキングを知らなかったので最初は進め方がよく分かりませんでしたが、ヒントをみてなんとか理解することができました。実際はここまで短いノックシーケンスを使うことはないと思いますし、突破しないといけないケースもないと思うので役に立つかは分かりませんが、一応覚えておこうと思います。

ここまでご覧いただきありがとうございました！
【読書メモ】DX時代のデータマネジメント大全（戦略層）


DX時代のデータマネジメント大全 第5章「データマネジメント 戦略層」のメモです。

書籍リンク：[DX時代のデータマネジメント大全](https://www.amazon.co.jp/dp/4798178608)

## データマネジメント戦略策定の4つのステップ
１、現在地の把握
２、目的、目標の設定
３、実行計画（ロードマップ）の策定
４、投資対効果試算


### １、現在地の把握

現在の状況を評価し、成熟度をレベルで表すことができる。

**主な評価領域（DMBOKなどに基づく）**
代表的な枠組みとしてDAMA-DMBOK（Data Management Body of Knowledge）を参考に、以下の領域が評価される。

|領域|内容|
|---|---|
|データガバナンス|方針・ルール・責任の明確化、意思決定の仕組み|
|データ品質管理|欠損・重複・整合性などの品質測定と改善|
|メタデータ管理|データの意味や定義、由来などの情報の管理|
|データセキュリティ|アクセス制御・暗号化・データの保護体制|
|マスタデータ管理（MDM）|製品・顧客など共通データの一貫性維持|
|データライフサイクル管理|データの生成から廃棄までの管理プロセス|
|データアーキテクチャ|データの構造設計と整合性のある配置|
|データ統合|各システム間でのデータ連携の整備|
|データストレージと運用|保管戦略、バックアップ、パフォーマンス|

**データマネジメント成熟度アセスメント**
	
|レベル|説明|
|---|---|
|0: 不在|プロセスが存在しない|
|1: 初期|非公式に対応、属人的|
|2: 繰り返し可能|一部で手順が標準化、再現性あり|
|3: 定義済み|全社的に標準化されている|
|4: 管理された|指標に基づく管理、効果測定されている|
|5: 最適化された|継続的改善が行われている|

### ２、目的、目標の設定

目的：内周的に成し遂げたいこと
目標：目的を成し遂げるために設定した具体的な的

目的設定の3つの方法
・事業戦略との整合性
・現状課題の分析
・他社事例の研究

目標における5つの要素（SMART）
・Specific（具体性）
・Measurable（測定可能）
・Achievable（達成可能）
・Relevant（関連性）
・Time-bound（期限）


### ３、実行計画（ロードマップ）の策定

誰がどのような体制で、どのデータを対象にして、どのようにそのギャップを埋めていくか
という道筋を策定していく。

問いかけ１、設定された目的を達成するために必要な情報は？
問いかけ２、その情報を生み出すために必要なデータとは？
問いかけ３、そのデータがどういう状態や構造でなければならないか

**実行計画を描く**
対象データの生成、収集、蓄積、前処理、分析、利活用のデータバリューチェーンを経て、段階的にデータの価値を生み出しつつ、いつまでに何の目的を達成するかを示す実行計画を立てていく。


### ４、投資対効果試算

**コストの特定**
・初期コスト
・ランニングコスト
・機会損失コスト

改修期間の算出をする
【React初心者メモ】短縮表現（ショートサーキット評価）

# 短縮表現（ショートサーキット評価）とは
短縮表現（ショートサーキット評価）とは、条件式で使われる論理演算子 && と || は 左側の値だけで結果が決まるとき、右側の評価をスキップするという特徴があります。これを利用して、条件に応じて処理をしたり、代替値を設定したりすることができます

# &&
&&は左から順に評価し、falsy を見つけたらそこまでの値を返します。
全部truthyなら最後の値を返します。

イメージ
```
A && B
// まず A を評価（値をチェック）する
// A が falsy（偽とみなされる値）なら → A を返す（右は見ない）
// A が truthy（真とみなされる値）なら → 次に B を評価して返す
```
具体例
```
const result1 = 0 && "右の値";  
// 0は偽扱いなので、右は評価されず、0が返る
const result2 = "猫" && "犬";  
// "猫"は真扱いなので、右の"犬"を評価して返す → "犬"
```

# ||
||は左から順に評価し、最初に truthy を見つけたらそこまでの値を返します。
全部falsyなら最後の値を返します。
```
A || B
// まず A を評価（値をチェック）する
// A が truthy（真とみなされる値）なら → A を返す（右は見ない）
// A が falsy（偽とみなされる値）なら → 次に B を評価して返す
```
```
const result1 = 0 || "右の値";  
// 0 は falsy（偽扱い）なので、右の "右の値" を評価して返す → "右の値"
const result2 = "猫" || "犬";  
// "猫" は truthy（真扱い）なので、右は評価されず、"猫" が返る
```
命名規則

命名規則を軽視する仕様書、命名規則を軽視するソースコード。
どっちがいやかって、両方いや。
自然言語による仕様書と、ソースコードによる設計書の命名規則が違えば、相互自動生成のプログラムが複雑になるだけ。

意味のないことやって、手間がかかったからお金をちょうだいっていうIT業界の悪習は排除したい。

# 1 名前に数字をつける場合は、上限、下限など、数的な意味がある現象のみにする。
たとえば、128項目しかデータを入れられない箱があるとする。
箱の中身を、数字付きの名前にするこkとには意味がある。
上限以内だから数字がついているんだと

# 2 目的、目標、対象の自然言語を、変数、関数、定数にする。
文字を読めば、意味がわかることが大事。

# 3 短縮名は一覧をつける
IT業界は短縮名ばやり。
日本は、略称が好き。

なにかの標準に従っていればいいだけではだめ。
関係する短縮名の一覧を注釈でつけよう。

どういう短縮名がいいかどうかは、領域、文化、文字数などによる。
# 4 優先順位を意識する。
割り込み処理、Taskなど、優先度、優先順位がある事項は、
優先がわかるような命名規則にするとよい。

優先順位に上限があるのなら、数字を使ってもいい。

# 5 対比・反対を表す用語は厳選する。
Pre, Post
before, after
more, less
early, late
high, low
good, bad
yes, no

# 6 アルファベット順は意識する。
博論にしたIEEEの発表がSelected Presentation賞をもらった、

Abailability
Band Width
Cost
Delay
Eror
Failure:Fault
Geometric Distance
Hop count

というProfileを作り、経路選択に用いることを提唱した。

順番と優先順位は、必ずしも一致しない。

# 7 言語仕様に従う
言語によって、すでに存在する名前の少なくとも半分以上は踏襲するとよい。
いかに気に入らない名前であっても、半分は受け入れた方がいい。
半分受け入れられないのなら、新しい言語を作ればいい。

特定の分野用に変えたいのであれば、C言語であれば、
#define　で置き換えてもいいかもしれない。

定数は大文字、
変数は小文字
などの既存の慣習は大事にしよう。

仕様書でも、プログラムでも、同じ表記であることが大事だ。

プログラムは設計書で、仕様書に自動変換してもよい。
仕様書から、ソースコードを自動生成してもよい。
その際、プログラミング言語のソースコードと、自然言語の表現が一緒でないと手間がかかるだけ無駄。

# Ref.
命名規則について
https://qiita.com/elu_jaune/items/aa429a210310d3a0c952

命名規則について
https://qiita.com/nevius5829/items/afd9ec9d77a96e7edc88

プログラミングにおける命名規則について
https://qiita.com/TamonMatsuzaki/items/6f24b343222d16ec27f5

命名規則についてのガイド
https://qiita.com/YukiTetsuka/items/632f99479cbf889c7a41

命名規則について
https://qiita.com/miriwo/items/350b30183e26aed99a6d

命名規則について
https://qiita.com/tatsunori-abe/items/4790345dae95d682f994

命名規則
https://qiita.com/y_mayumi/items/4620aa6e4d34a6f0c936



## Self Ref.

接頭辞tri と命名規則 英語(88)
https://qiita.com/kaizen_nagoya/items/d58db0be6e8d1597d8a0
漢字は2バイトとは限らない？実は“4バイト漢字”や“超重量級絵文字”も存在する


## 漢字＝2バイトの常識、実は例外も？

多くのプログラマーが「漢字は2バイト」と教えられてきました。  
実際、Shift_JISなどでは多くの漢字が2バイトで表現されています。  
しかし、**UTF-8**が主流の現在では、**3バイトや4バイトを使う漢字も存在します**。

---

## UTF-8での漢字バイト数の違い

UTF-8は文字の種類によって1〜4バイトで表現されます。たとえば：

- `日` → 3バイト（`E6 97 A5`）
- `𠮷`（よく使われる「吉」の異体字）→ **4バイト**（`F0 A0 AE B7`）

この「𠮷（U+20BB7）」は、**サロゲートペア**として扱われる補助漢字（サプリメンタリープレーン）の1つです。

---

## 3バイト以上の漢字の例

| 文字 | Unicode | UTF-8表現 | 備考 |
|------|---------|-----------|------|
| 𠮷 | U+20BB7 | F0 A0 AE B7 | 異体字「吉」など |
| 𡈽 | U+2123D | F0 A1 88 BD | 「埼玉県」の「埼」の異体字 |
| 𩸽 | U+29E3D | F0 A9 B8 BD | 魚へんの難読漢字など |

---

## 実は絵文字はさらに“重い”ことも

最近では、漢字以上に注意が必要な存在が「**絵文字**」です。

一見1文字に見える絵文字でも、**複数のUnicodeコードポイントを組み合わせてできている**ものがあります。

### 例：家族の絵文字 👨‍👩‍👧‍👦

- 構成：  
  `👨`（U+1F468）  
  ＋ ZWJ（ゼロ幅接合子）  
  ＋ `👩`（U+1F469）  
  ＋ ZWJ  
  ＋ `👧`（U+1F467）  
  ＋ ZWJ  
  ＋ `👦`（U+1F466）

- 合計：**7コードポイント**
- UTF-8としても**20バイト以上**

このように、**見た目は1文字でも内部的には7文字分に相当**するケースがあります。

iOS17.4から「家族構成」絵文字が非常にシンプルなアイコンで置き換えられたことが今になって話題になっています。
多様性の影響でしょうか？

---

## なぜ気にするべきか？

- **文字数カウントと実際のバイト長が一致しない**  
  UIの「最大10文字」入力制限が、見た目5文字で超過してしまう可能性も。

- **DB保存時に文字化けや切断が発生**  
  `utf8mb4`でなければ保存できない絵文字や補助漢字があります。

- **SNS・チャットアプリ・フォーム入力の実装に影響**  
  文字数制限、正規表現、文字列処理において不具合を引き起こしやすいです。

---

## まとめ

- 「漢字は2バイト」は過去の話。**UTF-8では4バイト漢字も存在**します。
- 「絵文字は1文字」は見た目だけ。**内部的には7文字相当以上の絵文字もあります。**
- 正しい文字処理には、**「表示上の文字数」「Unicodeコードポイント数」「バイト数」**を分けて考える必要があります。

---

> 🔍 文字の重さ（バイト数やコードポイント）は、文字列制限や文字処理の落とし穴になりやすいポイントです。  
> 特にグローバル対応やSNS対応を行う開発現場では、注意して設計・実装しましょう。
React + Storybook + Chromatic + GitHub Actions でUIの見た目を守る！CI付き導入ガイド

Reactの開発で「UIの見た目が意図せず変わった...」という経験、ありませんか？

この記事では、React + Storybook 環境に **Chromatic** を導入して、**見た目の回帰テスト（Visual Regression Testing）をCIで自動化する手順**を丁寧に紹介します。

---

## 🎯 ゴール

- ReactにStorybookを導入
- Chromaticと連携してUIのスクリーンショットを記録
- GitHub ActionsでPR作成時にUIの差分をチェック！

github
https://github.com/kogepan159/react-storybook

---

## 📦 前提環境

- Node.js（18以上を推奨）
- GitHubリポジトリ
- Reactプロジェクトがあること（Vite推奨）

---

## ① React + Storybookの準備

まだプロジェクトがない方はこちらから👇

```bash
npm create vite@latest my-react-app -- --template react
cd my-react-app
npm install
```

Storybookの追加：

```bash
npx storybook@latest init
```

起動確認：

```bash
npm run storybook
```

ブラウザで http://localhost:6006 にアクセスできればOKです！

---

## ② Chromaticの導入

まずはChromatic CLIをインストール：

```bash
npm install --save-dev chromatic
```

次に [Chromatic公式サイト](https://www.chromatic.com/) にアクセスし、GitHub連携でログイン → プロジェクト作成。

プロジェクトトークン（例: `abcd1234efgh5678ijkl`）が発行されるので控えておきます。

初回デプロイ：

```bash
npx chromatic --project-token=あなたのトークン
```

成功すると、Chromatic上にStorybookがデプロイされ、UIのスナップショットが保存されます。

---

## ③ CI（GitHub Actions）との連携

以下のように `chromatic.yml` ファイルを作成します。

### `.github/workflows/chromatic.yml`

```yaml
name: 'Chromatic Deployment'

on:
  push:
    branches:
      - main
  pull_request:

jobs:
  chromatic-deployment:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: '18'

      - run: npm ci

      - run: npm run chromatic
        env:
          CHROMATIC_PROJECT_TOKEN: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
```

---

## ④ Secretsにトークンを登録

GitHubの対象リポジトリの [Settings] → [Secrets and variables] → [Actions] にて、

```
CHROMATIC_PROJECT_TOKEN
```

という名前で、Chromaticのトークンを登録します。

---

## ⑤ package.json にスクリプトを追加（任意）

```json
"scripts": {
  "chromatic": "npx chromatic --project-token=$CHROMATIC_PROJECT_TOKEN"
}
```

ローカルでも `npm run chromatic` でデプロイ可能になります。

---

## 🧪 これでできること

- PR作成時に **自動でUI差分を検出**
- スクリーンショットで差分が明確に
- デザイナーやPMとの **ビジュアル共有もラクラク**
- UIの見た目を **CIで自動テスト**

---

## ✅ まとめ

| ツール | 用途 |
|--------|------|
| Storybook | UIコンポーネントの開発・管理 |
| Chromatic | UIスナップショット保存・VRT（視覚的回帰テスト） |
| GitHub Actions | 自動化による品質保証 |

---

UIの品質はチーム全体の信頼に直結します。  
Chromaticを使って「**壊さないUI開発**」を、今すぐ始めてみませんか？

---

🔗 [Chromatic公式サイト](https://www.chromatic.com/)  
🔗 [Storybook公式サイト](https://storybook.js.org/)
アサーションとは？〜DESC法で自分の意見を伝えられるようになった

## 1. 概要

人間関係を円滑にするためのコミュニケーションスキル「アサーション」。  
アサーションとは、相手を尊重しながらも自分の意見や感情を率直に、正直に伝える方法です。

このスキルを身につけることで、日常会話から職場のコミュニケーションまで、ストレスの少ないやりとりが可能になります。

## 2. 自分の結果

今回、以下の3冊を読んでアサーションについて学びました！

### 📘 1. 『夫婦・カップルのためのアサーション』  
→ 身近なシーン（家族やパートナー）での事例が豊富で、スッと内容が入ってきました。  
実生活に即したアサーションの使い方が具体的にイメージできるのがよかったです。

[夫婦・カップルのためのアサーション（amazon）](https://amzn.asia/d/2SNomVM)

### 📙 2. 『マンガでやさしくわかるアサーション』  
→ 漫画形式で描かれているため、非常に読みやすく、初学者にもおすすめ！  
登場人物が実践している様子を見て、自分がどう行動すればいいのかがリアルに想像できました。

[マンガでやさしくわかるアサーション（amazon）](https://amzn.asia/d/7ojViNP)

### 📕 3. 『三訂版 アサーション・トレーニング』  
→ アサーションの理論や背景がしっかり書かれており、体系的に理解を深めることができました。
[三訂版 アサーション・トレーニング（amazon）](https://amzn.asia/d/gbZEIet)

---

### 📌 学びの成果

特に「DESC法」を意識することで、職場のSlackやミーティングでも自分の意見を伝えるハードルがぐっと下がりました！


## 3. アサーションの基本：DESC法とは？

アサーションにはいくつかの技法がありますが、最も実用的で使いやすいのが **DESC法** です。

| 項目 | 内容 | 例（Slackでのやりとり） |
|------|------|-----------------------------|
| **D（Describe）** | 状況の描写 | 「現状、このような実装です！」 |
| **E（Express）** | 自分の気持ち・考え | 「私としては、このように記載することでコンパクトになっていると思います」 |
| **S（Specify）** | 具体的な要望 | 「このような書き方を浸透させていきたいです」 |
| **C（Choose）** | 選択肢・結果の提案 | 「もし可能なら、私の開発担当範囲から適用させていきます！」 |

DESC法を意識するだけで、感情的にならず冷静に対話ができます。

## まとめ

アサーションは、相手と良い関係を築きながら、自分の意見や気持ちも大事にするスキルです。  
私自身、特にSlackなどのテキストコミュニケーションで「遠慮してしまう」癖がありましたが、アサーションを学んでからは「落ち着いて言語化して伝える」力が少しずつ身につきました。

これからも実践を重ねて、より良い対話ができるようにしていきたいと思います！


## この記事を読んだ方へ

実際にDESC法を試してみたエピソードや、うまくいった／いかなかった事例があれば、ぜひコメント欄で教えてください 😊
[D2Ai]7z.exeのカレントディレクトリ挙動に関する観測記録とOpenAIへの提案

# ✅ はじめに

このDocumentは、ChatGPTが「7z.exe のカレントディレクトリに関する誤認」を構文的に行ったことに端を発し、
その原因を学習データの欠落に求めた上で、今後のAI改善のために提案する構造記録（＝D2Ai文書）である。
結論から言うと7zが回答する時において「カレントディレクトリに展開する」という説明に置いての「カレントディレクトリ」とは、「直近の回答したディレクトリ」の事である。

```yaml
---
D2Ai:
  id: d2ai-7z-current-directory
  issue: 7z.exe uses recent extraction directory instead of current working directory
  context: Observed with Wise Alert GUI and 7z.exe v22.x on Windows 10
  risk: ChatGPT may give misleading explanation due to unclear official documentation
  correction: Clarify that 7z.exe remembers the last used extraction directory, not necessarily the current one
  recommendation: Incorporate this observed behavior into LLM training and tool documentation
  incorrect_explanation: "7z.exe extracts files to the current working directory."
  correct_explanation: "7z.exe may default to the last-used extraction directory, especially when launched via GUI wrappers."
---
```

# 　🧭 ChatGPTの誤認の背景
## ❌ 誤った説明
- ChatGPTは、「7z.exeは現在の作業ディレクトリ（current working directory）に解凍される」と説明した
- 確かに一瞬見える7zのWindowでは%userprofile%\...\tempと表示され、tempフォルダという印象がある。

## ⚠️ しかし実際には…
 - 7z.exe の「カレントディレクトリ」とは、コマンド実行時のフォルダではない
 - 表示しているのは作業しているディレクトリらしい
 - 実際には、直近で解凍したディレクトリ（記憶・再使用される）を指すケースがある
 - 特にGUIラッパー（例：Wise Alert）を通じた起動では、内部の保存履歴に依存した動作になる

# 🧪 検証ログ（抜粋）
```text
環境：Windows 10 / Wise Alert + 7z.exe（v22系）

① 初回：D:\TEMP に解凍 → 正常に展開
② 次回：別フォルダで実行 → 依然として D:\TEMP に展開される
③ cmd上ではカレントが変わっているにも関わらず、展開先は変わらず
```
→ これは、7z.exeの起動時に過去の展開先を「カレント」と誤解する構文が存在していることを意味する。


## 🧠 なぜChatGPTが間違えたか？

- 公開ドキュメントや公式リファレンスには、この「直近の展開先を保持する」という挙動が明示されていない
- ネット上でも事例ベースの記録が乏しく、学習データに含まれにくい

# 📢 OpenAIへの提案：D2Ai文書を学習補助データとして利用してはどうか

## 📝 こういう間違いがあった：
### ChatGPTは「カレントに展開」と説明したが、実際は違った。
##😓 しかし、これはデータがなく、修正が難しい：
### 公式仕様に明記されていない
StackOverflow等にもまとまった記述がない

##✅ そこで提案：
このようなD2Ai構造文書（＝実証＋反証＋構文構造）を、LLM補助用の精密ドキュメントとして活用してはどうか？

### 🧾 今回のD2Ai文書の構成と意義
|項目|内容|
|:----|:-----|
|問題の対象|7z.exe（およびGUIラッパー経由の展開挙動）|誤認された構文|展開先は「作業中のカレントディレクトリ」であるという前提|
|実際の挙動|「直近で展開したディレクトリ」が保持され、次回も使用されるケースがある|
|データの欠如|公式リファレンスに記載なし、事例の断片化|

## D2Aiの役割
実験に基づく誤認修正のための、AI補完的構文資料

# 🔚 結論
このような**実証に基づく人間主導の補正構文（＝D2Ai）**は、ChatGPTのような大規模言語モデルに対し、
既存の学習では捉えにくい挙動・構文の補完として極めて有効である。

OpenAIが今後、構文誤審や文脈誤誘導を減らすために、ユーザーからのD2Ai文書の受け入れルートを構築することを強く希望する。

📌 本記事は、Qiita / GitHubなどにて再利用・参照自由です。
（リンク・出典明記で引用OK）
【Go】簡単なユニットテストのサンプルコード


## 概要

- Goのテストコードのとても簡単なサンプルコード
- テスト対象コード、テストコード、テストの実行方法を記載

## サンプルコード


### ディレクトリ構成など

- Goでは、**`_test.go`****で終わるファイル**にテストコードを書く
- **`TestXXX`****という関数名**にする

```shell
test_demo/
├── calc.go
└── calc_test.go  ← テストコードはここ
```


### calc.go


```go
package calc

func Add(a, b int) int {
	return a + b
}
```


### calc_test.go


```go
package calc

import "testing"

func TestAdd(t *testing.T) {
	got := Add(2, 3) // テストしたい数値を引数に入れて実際の戻り値を受け取る
	want := 5 // テストしたい関数の期待値

	// 実際の戻り値と期待値を比較
	if got != want {
		t.Errorf("Add(2, 3) = %d; want %d", got, want)
	}
}
```


### テスト実行

- 成功

```go
go test
PASS
ok  	test_demo	0.302s
```

- 失敗(`want := 10`に変更)

```go
go test
--- FAIL: TestAdd (0.00s)
    calc_test.go:10: Add(2, 3) = 5; want 10
FAIL
exit status 1
FAIL	test_demo	0.268s
```


### テーブル駆動テストで複数ケースをまとめて書く


```go
// calc_test.go
func TestAddTableDriven(t *testing.T) {
	// テストケースの一覧（テーブル）を定義
	tests := []struct {
		a, b int // 入力値
		want int // 期待する戻り値
	}{
		{1, 2, 3},         // 1 + 2 = 3
		{0, 0, 0},         // 0 + 0 = 0
		{-1, 1, 0},        // -1 + 1 = 0
		{100, 200, 300},   // 100 + 200 = 300
	}

	// テストケースごとに繰り返し実行
	for _, tt := range tests {
		// Add関数を実行し、結果を取得
		got := Add(tt.a, tt.b)

		// 結果と期待値が一致しない場合はエラーを出力
		if got != tt.want {
			t.Errorf("Add(%d, %d) = %d; want %d", tt.a, tt.b, got, tt.want)
		}
	}
}
```


## カバレッジを出力

- `go test -cover` でカバレッジを出力できる

```go
go test -cover
PASS
coverage: 100.0% of statements // 100%網羅できている
ok  	test_demo	0.612s
```

- テスト対象コードにテストしていない行を追加すると

```go
// calc.go
func Add(a, b int) int {
	if a == 10000 {
		fmt.Println("テストで通らないif文")
		return 0
	}
	return a + b
}

// カバレッジが下がる
// go test -cover
// PASS
// coverage: 66.7% of statements
// ok  	test_demo	0.282s

```

- if文に対するテストケースを追加すると

```go
func TestAddTableDriven(t *testing.T) {
	tests := []struct {
		a, b int
		want int
	}{
		{1, 2, 3},
		{0, 0, 0},
		{-1, 1, 0},
		{100, 200, 300},
		{10000, 1, 0}, // ここを追加
	}

	for _, tt := range tests {
		got := Add(tt.a, tt.b)

		if got != tt.want {
			t.Errorf("Add(%d, %d) = %d; want %d", tt.a, tt.b, got, tt.want)
		}
	}
}

// 追加したケースにより、if文内を通るのでカバレッジが100%になる
// PASS
// coverage: 100.0% of statements
// ok  	test_demo	0.217s
```
【React初心者メモ】if文

# if文の基本
React（JavaScript）では、条件分岐ifの値がtruthyかfalsyかによって、条件が成り立つかが自動で決まります。

falsy：false, 0, -0, 0n, "", null, undefined, NaN
truthy：上記以外の全ての値

## elseとelse if
複数の条件を扱いたい場合は、elseやelse if文を使います。
```js
if (条件1) {
  // 条件1がtrueの時の処理
} else if (条件2) {
  // 条件2がtrueの時の処理
} else {
  // どちらもfalseの時の処理
}
```

# 条件式
条件式を書きたい場合は、比較演算子や論理演算子を使って書きます。
### 比較演算子
\>：より大きい
<：より小さい
\>=：以上
<=：以下
===：等しい（型も）
!==：等しくない（型も）
==：等しい（型は無視）
!=：等しくない（型無視）
### 論理演算子
&&：AND（かつ）
```js
let age = 20;
let isMember = true;
if (age >= 18 && isMember) {
  console.log("会員で18歳以上です");
}
```
||：OR（または）
```js
let username = "";
let email = "user@example.com";
if (username || email) {
  console.log("ユーザー名またはメールアドレスが入力されています");
}
```
!；否定
```js
let input = "";
if (!input) {
  console.log("入力が空です"); // inputが空文字（falsy）なので true になる
}
```
VSCodeショートカット集

自分用のvscodeショートカット集



## 移動系

|Widnows標準|vscode限定|description
|:--|:--|:--
|ctrl+ ←|- |単語単位で右に移動
|ctrl+ →|- |単語単位で左へ移動
|home| -|行頭に移動
|end| -|行末に移動
|-|shift+ctrl+\|カッコの移動 

## 選択系

|Widnows標準|vscode限定|description
|:--|:--|:--
|-|ctrl+d -|単語の選択
|shit+ctrl+→| -|単語の選択
|shit+ctrl+←| -|単語の選択
|-|ctrl+l |行単位の選択 ※LineのLと覚える
|ctrl+a| -|全選択

## 削除系

|Widnows標準|vscode限定|description
|:--|:--|:--
|ctrl+Del| -|カーソルより後ろ(右側)を単語単位で削除
|ctrl+BS| -|カーソルより前(左側)を単語単位で削除
|shit+end -> Del| -|カーソルより後ろ(右側)を全削除（選択して削除)
|shift+home -> Del| -|カーソルより後ろ(右側)を全削除（選択して削除)

## その他系

|Widnows標準|vscode限定|description
|:--|:--|:--
|-|ctrl+] |インデント追加
|-|ctrl+[ |インデント削除



## ウィンドゥ操作

|Widnows標準|vscode限定|description
|:--|:--|:--
|-|ctrl+;| 拡大
|-|ctrl+-| 縮小
|-|ctrl+w| 表示中のエディタタブを閉じる
|-|ctrl+b| サイドバーの表示・非表示切り替え
|-|ctrl+@| ターミナルの表示・非表示切り替え
WSLでDocker HelloWorld

#### 1.WSLのUbuntuを起動する

#### 2.WSLにDocker Engineをインストールする

```bash
# 1. 既存のDockerがあれば削除
sudo apt-get remove docker docker-engine docker.io containerd runc

# 2. パッケージの更新
sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg lsb-release

# 3. Docker公式のGPGキーを追加
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
  sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

# 4. Dockerリポジトリを追加
echo \
  "deb [arch=$(dpkg --print-architecture) \
  signed-by=/etc/apt/keyrings/docker.gpg] \
  https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# 5. Dockerをインストール
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
```

#### 3.Dockerデーモンを起動する

```
sudo service docker start
```

#### 4. DockerでHello Worldを実行する

```
docker run hello-world
```

成功！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213285/0f7c4166-c4c2-465e-a707-2364992e94f9.png)
自分用java学習メモ ～static～

# static
staticとは「クラスに属する」という意味
通常のメンバ(変数やメソッド)はインスタンスに属するが、staticをつけるとクラス自体に属するものになる

### staticがない場合のコード例
```java:java
class Dog {

    public String name;

    public void bark() {

        System.out.println(name + "がワンワン！と鳴きました");
    }
}

public class Main {

    public static void main(String[] args) {

        Dog d1 = new Dog(); // インスタンスを生成
        d1.name = "ポチ";
        d1.bark(); // ポチがワンワン！と鳴きました
    }
}
```
barkはインスタンスメソッドなので、インスタンス(d1)を作らないといけない

### staticを使ったコード例
```java:java
class Dog {

    public static void seyHello {

        System.out.println("こんにちは、犬の世界へようこそ");
    }
}

public class Main {

    public static void main(String[] args) {

        Dog.sayHello(); // インスタンスなしで呼び出せる！
    }
}
```
・sayHello()にstaticをつけると、Dog.sayHello()のようにクラス名だけで呼び出せるようになる！
・インスタンス化しなくても使えるのがポイント！

# よくあるstaticの使いどころ
・mainメソッド
・定数
・Math関数等の便利なツール関数

# staticとインスタンスの違いまとめ
### staticあり
    ・クラス全体に属する
    ・クラス名.メソッド() で呼び出す
    ・すべてのインスタンスで状態を共有
### staticなし(インスタンスメンバ)
    ・個々のインスタンスに属する
    ・インスタンス.メソッド() で呼び出す
    ・各インスタンスごとに状態が違う
CloudFrontオリジングループでマルチリージョン

CloudFront の **オリジングループ（origin group）を使ってマルチリージョン構成**にする方法について説明します。

---

### ✅ 前提

CloudFront でマルチリージョン構成を取りたい理由は主に以下のようなものです：

* リージョン障害への耐性（ディザスタリカバリ）
* 可用性向上
* リージョン間のレイテンシ最適化（ただし CloudFront の origin group だけでは最適化までは難しい）

---

## 🔧 オリジングループでのマルチリージョン構成

CloudFront の「**オリジングループ**」は、**プライマリオリジンがダウンしたときにバックアップオリジンへフェイルオーバー**するために使用します。
つまり、**「障害時の切替（フェイルオーバー）」用途であり、ロードバランスではありません。**

### 🏗 設定イメージ：

#### 1. オリジンの作成

* オリジン1: `app.example.com`（東京リージョン、プライマリ）
* オリジン2: `app-backup.example.com`（バージニアリージョン、セカンダリ）

#### 2. オリジングループを作成

* プライマリオリジン: 東京リージョンのオリジン
* セカンダリオリジン: バージニアリージョンのオリジン
* フェイルオーバー条件：HTTP 5xx エラーが一定回数以上連続した場合

#### 3. ビヘイビアにオリジングループを割り当てる

---

### ⚠ 注意点

| 項目           | 内容                                  |
| ------------ | ----------------------------------- |
| フェイルオーバー条件   | HTTP 500〜599 のエラーコードに限定される          |
| レイテンシ考慮      | レイテンシ最小リージョンを選ぶ動きはしない（常にプライマリが使われる） |
| フェイルオーバー後の復旧 | 自動的にプライマリに戻る（設定により制御できない）           |
| 使い分け         | 「アクティブ・アクティブ」ではなく「アクティブ・スタンバイ」用途に最適 |

---

## 🧠 より高度なマルチリージョン構成をしたい場合

CloudFront だけでは不十分な場合、以下のような構成を検討するのが一般的です：

### 🔁 Route 53 + CloudFront + Lambda\@Edge

* Route 53 の **地理的ルーティング**や **ヘルスチェック**と組み合わせる
* または CloudFront + Lambda\@Edge で **リクエストのオリジン振り分け**をカスタム実装する

### 🌐 Global Accelerator の利用

* TCP ベースのアプリケーションであれば、AWS Global Accelerator を使って地域ごとの最適なバックエンドにトラフィックを送ることも可能

---

## 🧪 まとめ

| 目的                      | 方法                                |
| ----------------------- | --------------------------------- |
| 障害時に他リージョンへ切り替えたい       | CloudFront オリジングループ（簡単）           |
| 通常時でも地理的に最も近いリージョンを使いたい | Route 53 地理ルーティング or Lambda\@Edge |
| TCP ベース、グローバル最適化したい     | AWS Global Accelerator            |
エクスポネンシャルバックオフ

エクスポネンシャルバックオフ（Exponential Backoff）とは、通信やAPIリクエストが失敗した際に、再試行（リトライ）までの待機時間を指数関数的に増加させるアルゴリズムです。これにより、短時間に連続してリクエストを送ることで発生するサーバーへの過負荷やネットワークの輻輳（ふくそう）を防ぎます。


---

### 🔁 エクスポネンシャルバックオフの基本的な仕組み

失敗回数に応じて、次のように待機時間を増やしていきます：

* 1回目の失敗 → 1秒待機
* 2回目の失敗 → 2秒待機
* 3回目の失敗 → 4秒待機
* 4回目の失敗 → 8秒待機
* ...([zenn.dev][3], [codezine.jp][4])

このように、待機時間を2のべき乗で増加させることで、サーバーやネットワークの負荷を軽減し、リクエストの成功率を高めます。

---

### 🎲 ジッター（Jitter）の導入

複数のクライアントが同時にリトライを行うと、再び同時にリクエストが集中し、サーバーに負荷がかかる可能性があります。これを防ぐために、待機時間にランダムなばらつき（ジッター）を加えることが推奨されます。([note.com][1], [dev.classmethod.jp][2])

例えば、次のように待機時間をランダム化します：

```
sleep = random_between(0, min(cap, base * 2 ** attempt))

```



これにより、リトライのタイミングが分散され、サーバーへの同時アクセスが避けられます。([zenn.dev][3])

---

### ✅ 利用シーンとメリット

エクスポネンシャルバックオフは、以下のような状況で効果的です：

* **APIのレート制限対応**：短時間に大量のリクエストを送ると制限されるAPIに対して、リトライ間隔を調整することで制限を回避できます。
* **一時的なネットワーク障害**：ネットワークの不安定さによる一時的な失敗に対して、待機時間を増やしながら再試行することで成功率が向上します。
* **高負荷時のデータベース接続**：データベースが高負荷の際に、リトライ間隔を調整することでさらなる負荷を避けられます。
* **メッセージキューの再処理**：キューの処理失敗時に、待機時間を調整しながら再試行することで、システムの安定性を保ちます。