OmniAICreator/Qiita-1.07M huggingface dataset:
分離記述の原則（Isolated Definition Principle / IDP）

## **分離記述の原則（Isolated Definition Principle / IDP）**

**分離記述の原則**とは、「一つの実装・仕様は一つのファイルに記述する」ことで、他の機能や責務と混在させず、独立性の高いコード構成を保つべきという原則です。  
特に、**AIエージェントにコーディングを任せる場合**には、この原則の重要性が一層高まります。  
頭文字を取って **IDP（Isolated Definition Principle）** とも呼びます。

---

### **【分離記述の原則のポイント】**

- 各ファイル・モジュールは1つの仕様・機能に特化させ、それ以外の責務を持たない  
- 実装や仕様は、他と依存しない形で定義・管理する  
- コードの分割単位が明確であることで、AIエージェントが誤って関係ない部分を変更するリスクを抑制できる  
- 各コンポーネントの境界を明確にすることで、意図しない副作用の発生を防ぐ

---

### **【分離記述の原則のメリット】**

- **AIとの協調開発が安定する**  
　→ AIが特定の仕様や機能だけを対象にしてコード生成・修正を行えるため、意図しない全体変更が発生しにくくなる

- **予測可能なコード修正が可能になる**  
　→ 「この仕様を変えたいならこのファイルを見ればいい」といった対応が明確になる

- **再利用性とテスト性の向上**  
　→ 機能単位でのユニットテストや再利用がしやすくなる

- **保守性の向上**  
　→ 複雑な仕様をまたぐ変更の必要が減り、開発者やレビュー担当者も仕様の全体像を把握しやすくなる

---

### **【分離記述の原則の適用例】**

- 1つの機能やAPI仕様につき、専用のファイルやディレクトリを用意する  
　（例：`auth/login_handler.dart`, `user/update_profile_service.dart`）

- 各仕様・ロジック・UIを明確に分離したディレクトリ構成にする  
　（例：`features/`, `services/`, `presentation/`, `domain/` などのレイヤー分離）

- 既存機能に対して変更が必要な場合、そのファイルの範囲内で完結する設計を心がける

---

## **まとめ**

AIエージェントにコーディングを任せる時代においては、**コードの独立性と責務の明確さが品質を守る鍵**になります。  
「分離記述の原則（IDP）」を守ることで、予期せぬバグや仕様破壊のリスクを回避し、**人とAIの共存を前提とした健全な開発体制**を築くことができます。  
将来的な拡張や保守も視野に入れるなら、この原則はプロジェクト成功の土台となる重要な指針です。
AWS Kinesis Data Firehoseとは？


AWSを使っていると、「Kinesis Data Firehose（キネシス データ ファイアホース）」というサービス名を耳にすることがあります。  

この記事では、  
- Kinesis Data Firehoseとは何か  
- どんな場面で使えるのか  
- 他のサービスとの違い  
について初心者向けにわかりやすく解説します！

---

## 🔥 Kinesis Data Firehoseとは？

**Amazon Kinesis Data Firehose** は、  
**リアルタイムでストリーミングデータを自動的に受け取り、S3やRedshift、Elasticsearch、Datadogなどに転送するマネージドサービス**です。

ざっくりいうと：

> 「データを集めて、自動で保存・分析できる場所へ流してくれるホース（Firehose）」のような存在です。

---

## 🔧 主な特徴

| 特徴 | 内容 |
|------|------|
| フルマネージド | サーバーの管理不要。スケーリングも自動。 |
| リアルタイム処理 | 数秒以内にデータを保存先へ送信。 |
| 変換処理も可能 | Lambdaでデータを整形・加工してから保存。 |
| バッファリング対応 | 一定のサイズ・時間までデータを貯めてから送信可能。 |

---

## 🗂 どこにデータを送れるの？

Firehoseは以下のようなサービスにデータを自動転送できます：

- Amazon S3（データレイク）
- Amazon Redshift（DWH）
- Amazon OpenSearch（旧Elasticsearch）
- Datadog、Splunk など外部サービス
- HTTPエンドポイント

※ 事前に各サービスとの連携設定が必要です。

---

## 🔄 他のKinesisサービスとの違いは？

AWSのKinesisにはいくつか種類がありますが、Firehoseは**最もシンプルに使える**のが特徴です。

| サービス名 | 主な用途 | 特徴 |
|------------|----------|------|
| Kinesis Data Streams | 自作アプリで細かくストリーミング処理 | 柔軟だが少し難しい |
| Kinesis Data Firehose | 保存・分析基盤への自動転送 | シンプルで初心者向け |
| Kinesis Data Analytics | ストリーミングデータのSQL分析 | SQLでのリアルタイム処理が可能 |

---

## 💡 どんなシーンで使える？

- **アプリのログ収集をS3に保存**
- **IoTデバイスのセンサーデータをリアルタイムに可視化**
- **WebアクセスログをRedshiftに連携しBIで分析**
- **Lambda関数で整形してOpenSearchに保存→Kibanaで可視化**

など、**リアルタイム性が求められるログ収集やETL処理に最適**です。

---

## ✅ まとめ

Amazon Kinesis Data Firehoseは、

- 簡単にリアルタイムデータを保存・分析基盤に送信したい
- サーバー管理したくない
- AWS初心者でも使いやすいサービスが欲しい

という方にぴったりのサービスです！

ログ収集やIoTデータの蓄積を考えている方は、まずFirehoseの導入を検討してみてはいかがでしょうか？

---
Spring Data Jpa | JpaRepositoryを継承したInterfaceだけでCRUDができる理由

## 概要

SpringBootではJpaRepositoryを継承したInterfaceを作っただけなのにCRUDのメソッドたちを使えます。

```
public interface MemberRepository extends JpaRepository<Member, Long> {
	
}
```

一般的にInterfaceを実装した実装クラスがないと動作しないはず。
→結論、SpringDataJpaが動作するようにしてくれました！


## SpringDataJpaがMemberRepositoryの実装クラスを作る

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3256444/dba03154-f00e-4324-8ff7-ad9400373ce5.png)

SpringDataJpaはJpaRepositoryを継承したInterfaceを探し、実装クラスを生成してくれます。
Proxyクラスを生成してくれた？

## テストで実験してみよう

```
    @Autowired
    MemberRepository memberRepository;

    @Test
    public void test() {
        System.out.println(memberRepository.getClass());
        System.out.println(memberRepository.getClass().getName);
    }
```

```
// 結果
class com.sun.proxy.$Proxy123 // Proxyオブジェクト！
org.springframework.data.jpa.repository.support.SimpleJpaRepository // ClassName
```
Proxyオブジェクトが生成され、SimpleJpaRepositoryを基に動作していることがわかりました。

### SimpleJpaRepository（JpaRepositoryの実装クラス）

```
@Repository
@Transactional(
    readOnly = true
)
public class SimpleJpaRepository<T, ID> implements JpaRepositoryImplementation<T, ID> {
    public List<T> findAll() {
        return this.getQuery((Specification)null,(Sort)Sort.unsorted()).getResultList();
    }


    @Transactional
    public <S extends T> S save(S entity) {
        Assert.notNull(entity, "Entity must not be null");
        if (this.entityInformation.isNew(entity)) {
            this.entityManager.persist(entity);
            return entity;
        } else {
            return (S)this.entityManager.merge(entity);
        }
    }

    @Transactional
    public void delete(T entity) {
        Assert.notNull(entity, "Entity must not be null");
        if (!this.entityInformation.isNew(entity)) {
            Class<?> type = ProxyUtils.getUserClass(entity);
            T existing = (T)this.entityManager.find(type, this.entityInformation.getId(entity));
            if (existing != null) {
                this.entityManager.remove(this.entityManager.contains(entity) ? entity : this.entityManager.merge(entity));
            }
        }
    }

    ...
```

SimpleJpaRepositoryはCRUD機能を含め、JpaRepositoryの実装をしていることがわかりました。
結局`EntityManager`使って実装していますね。
つまり、純粋Jpaで実装されていて、PersistenceContextを活用していることがわかります。
おかげで開発者はEntity管理の面倒をしなくてもJpaの強さを丸ごと使って開発ができます。


## HibernateもProxyオブジェクトを使う
https://qiita.com/yosub-shim/items/e762fe00fa624715f92b
GoogleCloud Associate Cloud Engineer（GCP ACE）受験記※身分証2点お忘れなく！

## はじめに
GoogleCloudの認定資格のひとつであるAssociate Cloud Engineer（ACE）を受験しました。学習方法や試験について記録していきます。点数などは開示されていません
### 筆者について
- GoogleCloudの実務経験はなし
- 社会人3年目文系卒SE、普段はWebアプリケーションの開発を行っている
- 過去取得資格
  - Azure(AZ-900,AI-900,DP-900,AZ-104)
  - AWS(CDF,SAA)
  - GCP(CDL)
  - 基本情報技術者試験、セキュリティマネジメント試験、ITIL4、salesforce初級、SAFeSM

- 受験の動機
  - 3大クラウドの中級レベルまで資格を取得して、それぞれのクラウドサービスの特徴など掴むことを目標にしていたため。（今回のGCP試験で完了！）
## 学習記録
### 期間
- 2週間前の休日から
- 想定より時間が取れず15hほど。月初にAzure試験を受けていたため少し参考になりました（感覚的に）
### 学習について
- 参考書をメモしながら読む → 流し読み → Udemyの問題集(3回分)　という流れ
- GCP初級資格も取得はしているが、時間がたっているため、GCP自体の事前知識は0から
- 問題集では合格ラインとは程遠い正答率で、合格は厳しいかなーという状態で試験に臨んでしまっています
### 教材
- 参考書：[徹底攻略 Google Cloud認定資格 Associate Cloud Engineer教科書](https://www.amazon.co.jp/%E6%A8%A1%E6%93%AC%E5%95%8F%E9%A1%8C%E4%BB%98%E3%81%8D-Google-Cloud%E8%AA%8D%E5%AE%9A%E8%B3%87%E6%A0%BC-Associate-Engineer%E6%95%99%E7%A7%91%E6%9B%B8/dp/4295017639)
  - リソースについて復習もかねてメモしながらネットワークあたりの章まで読み、あとはざっと流し読み
  - 後半のリソースの使い分けに関する章はすごくわかりやすく試験対策にはもってこいでした
- Udemy問題集：[これだけで合格！Google Cloud Associate Cloud Engineer模擬試験問題集（4回200問）](https://www.udemy.com/course/google-cloud-associate-cloud-engineer4200/?srsltid=AfmBOorX_q8L5bLn2AjJNITv2eHFel9grVeheCin6N1DAFstCo3weH89)
  -  3回分解きましたが、どれも30％くらいの正答率で絶望しました
  -  完全に同じ問題が本番に出ることはなかったですが、問題の傾向を掴んだり、「この聞かれ方をしたら、答えは2択に絞れるな、、」とか、そういった受験にあたっての勘所が掴めたので、おすすめの教材です
## まとめ
GCPのリソースについて詳しく学んだり、ハンズオンは飛ばして、試験に受かることだけを目標にしていたので、業務が落ち着いたらハンズオンやGCPを実際に使ってみたいと思っています。
dアニメをFirefoxで視聴するときエラーコード40013が出る時の対処方法

# はじめに
Firefoxは滅びない。

# 背景
dアニメにこんなお知らせが来ていた。
エラーコードが出て見れないとの問い合わせが多かったのだろう。
だが，個人的に非常に使いにくい「他ブラウザ（Chrome/Microsoft Edge）」を使うのは論外なので解決策を共有します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3992520/daf6dd45-cce0-4213-be32-0bc82b3eb263.png)

# 対応方法①
設定→プライバシーとセキュリティ→HTTPS-Onlyモードにて
「すべてのウィンドウで HTTPS-Only モードを有効にする」に変更
その後，Firefoxを再起動

# 対応方法②
設定→プライバシーとセキュリティ→HTTPS-Onlyモードにて
「HTTPS-Only モードを有効にしない」（このモードがデフォルトだったはず）にして使用する場合
以下の画像のように
例外を管理→ウェブサイトのアドレスに以下を入力→オフにする→変更を保存
「 https://animestore.docomo.ne.jp 」
その後，Firefoxを再起動

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3992520/a4f04497-4507-4bcb-859f-3d68a910e20d.png)

# おわりに
基本は対応方法①でいいと思うが，HTTPS-Onlyを使いたくない場合は対応方法②を選ぶといい。
HTTPS-Onlyは名前の通りだが，気になる方は自分で調べてください。
良いアニメライフを。
二分探索の意味と実装

計算量を大幅に縮小できる便利なアルゴリズムとして、二分探索がある。
Pythonではbisectという標準モジュールが便利だが、具体的にどうやって計算しているのかを整理した。

# 計算量について
平均的な計算回数はlognで、扱うデータ量が多くなればなるほど、その恩恵を受けることができる。
詳細はどこでも説明されているので割愛。
図としてはこんなのをよくみる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2932592/fbb523ff-570a-4a5c-bf2a-28937797a7d8.png)

￼
参考：

https://qiita.com/Pro_ktmr/items/8946723fe08ba29a977c

# bisectモジュール
bisectモジュールは配列データの要素の検索と挿入モジュール。
ざっくり三つのメソッドに切り分けられる。
1. 一致
2. 検索値以上の値が初めて出る箇所
配列の中で最初に2以上の値が出るインデックスは1
![Pasted Graphic 17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2932592/c1211457-881a-4253-8994-7cd43da88324.png)

3. 検索値より大きい値が初めて出る箇所
配列の中で最初に2より大きい値が出るインデックスは3のある4
![Pasted Graphic 18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2932592/69ebc731-7fc3-4cba-a0a5-8da273711ae2.png)

参考

https://qiita.com/seigot/items/5091499d75a11cc77e41



# 一致検索, bisect.left, bisect.rightの実装
Gptに聞いて教えてもらっていたが、しばらく理解できなかったので要点をまとめる。
まずはコードを眺める。
```python
def binary_search(arr, x):
    left = 0
    right = len(arr)-1
    while left <= right:
        mid = (left + right)//2
        if arr[mid] == x:
            return mid
        elif arr[mid] < x:
            left = mid + 1
        else:
            right = mid -1
    return -1

def lower_bound(arr, x):
    left = 0
    right = len(arr)
    while left < right:
        mid = (left + right)//2
        if arr[mid] < x:
            left = mid + 1
        else:
            right = mid
    return left
            
def upper_bound(arr, x):
    left = 0
    right = len(arr)
    while left < right:
        mid = (left + right)//2
        if arr[mid] <= x:
            left = mid + 1
        else:
            right = mid
    return left
```

コード上での違いからは何の差なのか全然わからない
|関数名|最初のrightの値|検索の実行条件|leftとrightを寄せる条件|rightの寄せ方|
|-|-|-|-|-|
|binary_search|len(arr) - 1|left <= right| 等号と不等号は別             | mid - 1        |
| lower_bound    | len(arr)           | left < right   | left を寄せるほうが不等号     | mid            |
| upper_bound    | len(arr)           | left < right   | right を寄せるほうが不等号  | mid            |


# 理屈で考えてみる
### rightの初期値
ピッタリしないものがある可能性があって、そのためにひと枠増やしておくためにlen()-1ではなく、len()としている

### 検索条件
`binary_search()`は「**値そのもの**を探す」検索。
そのため`left==right`の時にも値を確認する必要がある。
→よって、`while left<=right`という条件式に`=` が含まれている。

一方、`lower_bound()`, `upper_bound()`は
「**条件を満たす境界の位置**を探す検索」。
値との一致を直接チェックする必要はない。
→このためループの実行条件は`left < right`とし、
`left = right`となった時点で**候補が尽きた状態＝答えが見つかった状態**と判断できる。

つまり、
`binary_search`は「一致する値があるかどうか」が重要。`<=`が必要。
`lower_bound()`, `upper_bound()`は「値が入るべき位置」が重要。`==`の比較は必要なく、`<`のみでOK。

### left, rightの寄せる条件と方法
1: Lower
`x <= arr[mid]` のときは、
最初にx以上の値が出るidxを探す目的に対して、
arr[mid]がxを含む可能性があるので、rightをmidまで寄せる。
→`right = mid`
```python
# 例：
arr = [1, 2, 2, 2, 3, 4]
x = 2

# arr[mid] = 2 のとき、その位置は2以上なので「条件に合ってる」→残す（right = mid）
```

2: Upper
`arr[mid] <= x`のときは、
xより大きい最初の値のあるidxを探す目的に対して、arr[mid]は条件を満たさないので取得範囲を狭めたい。
→midをスキップして、`left = mid+1`とする
```python
# 例：
arr = [1, 2, 2, 2, 3, 4]
x = 2

# arr[mid] = 2 のとき、その位置は「x以下」なので対象外 → 左を寄せる（left = mid + 1）
```

# 感想：
計算アルゴリズムとして優秀だとされる二分探索をとりあえず描けるようになったのはでかい！
こういう基礎を引き続き勉強していきたい
VPCゲートウェイエンドポイントとは？

AWSでプライベートサブネットを使う際、「S3にアクセスできない！」といった経験はありませんか？  
これは、インターネットを経由しないとS3などのサービスにアクセスできない構成になっているからです。

そんなときに活躍するのが **VPCゲートウェイエンドポイント**。

### 端的に言うと？

> **VPCからS3やDynamoDBなどに、インターネットを経由せず、安全にアクセスするための仕組み**です。

### 特徴
- **インターネットを介さない**ため、NAT Gatewayやインターネットゲートウェイが不要
- **コスト削減**（NAT Gatewayの料金がかからない）
- **セキュリティ強化**（プライベートな通信が可能）
- **対応サービス**：S3、DynamoDBのみ（※2025年3月時点）

---
HeliScriptの個人的なコーディング規約

Hikky所属のうめじです。
Vket Cloudでコンテンツ開発を始めて、1年になろうとしています。
その中で、個人的なコーディング規約をコツコツと書き溜めまてきました。  
その内容が少しはお役に立つかもと思い公開します。

また、[C# のコーディング規約](https://learn.microsoft.com/ja-jp/dotnet/csharp/fundamentals/coding-style/coding-conventions)を元にしているので、C#ユーザーは一読するだけでもC#との違いがイメージしやすくなると思います。

:::note warn 
個人的ルールなので、適用する必要は全くありません。
また2025/3現在のHeliScript仕様にもとづいた記事となります。
:::


# 基本設定
#### アクセス修飾子のprivate は省略する
HeliScriptはデフォルトがprivateのため
#### クラスのフィールドは、定数以外はpublicにしない
カプセル化の促進のため
#### グローバル変数とグローバル関数はなるべく使わない
HeliScriptではクラスの外で変数と関数の定義が可能です。
追跡が困難になるため、なるべく使わない

# 記法
#### メンバー変数 `_fieldMember`は _付きのローワーキャメルケース

#### 定数名 `HogeName`はパスカルケースをつかう

#### readonlyな変数 `_HogeName`は _付きのパスカルケースにします。
HeliScriptはreadonlyに非対応のため、命名規則として変更すべきでない変数を扱います。

:::note warn 
Heliscriptでは型と同じ変数名で宣言できないため、_をプレフィックスします
```c#
HogeClass HogeClass; //コンパイルエラー
HogeClass _HogeClass //ok
```
:::

#### グローバル変数は`g_`をプレフィックスする 
const変数 の場合は`g_`付きのパスカルケース
可変変数は`g_`付きのキャメルケース

#### グローバル関数の先頭の文字は`小文字`にする
sdkが用意しているユーティティ関数も先頭は小文字になっています
例: `hsSystemWriteLine()`

#### delegate型の名前には、前に`f`と後ろに`Callback`をつける
コールバック関数 `function Callback` 由来です。
また、`f`と`Callback`の間に`パラメーター名`を入れる
```
delegate void fJsValCallback(JsVal);
fJsValCallback callback;
```

# 命名
#### Item型の変数名はタイプをいれる `xxItem`
HeliscriptはItemという型で[多くの種類を宣言](https://vrhikky.github.io/VketCloudSDK_Documents/latest/hs/hs_item_types_functions.html)できるため、変数名にタイプをつけると分かりやすくなります。

例: Field TypeのItemなら`fieldItem`、Object Typeなら`objectItem`

#### コンポーネントクラスの命名は`_Component`をサフィックスする
HeliScriptは通常のClassの他に[Component](https://vrhikky.github.io/VketCloudSDK_Documents/latest/hs/hs_component.html)の定義が可能です。
Classと同じように使用できるため、`_Component`をサフィックスすることで判別がつきやすくなります。

```C#
component SomeGimmick_Component
{
    public SomeGimmick_Component()
    {
        Wall = new Wall();
    }
}

class Wall
{
}
```
#### 引数付きでクラスを初期化したいときのメソッド名は `Construct`
:::note warn 
HeliScriptではパラメーター付きのコンストラクタを定義できません。
そこで通常のメソッドで初期化用のデータを渡す必要があります
:::

# コーディングガイドライン
規約ほど厳密に管理していないものです

#### グローバルな関数や変数を記述するファイル名はキャメルケースにする

例：helApi.hs

#### アプリケーション層のクラスの命名

Canvasを使わないケース: `〇〇Gimmick_Component`
Canvasを使うケース: `〇〇Presenter_Component`

#### hsItemGetを使って取得したくなるようなItemはクラス化する

クラス化しないとアプリケーション層のクラスが肥大化しがちになります
UI操作も可能なEntityクラスとして位置付けると便利です。（ただし、通常のEntityと見分けるためにUIをプレフィックスします）

#### Canvasを使用するギミックは全てアクティビティにする
GUIを実装するときは[アクティビティを活用](https://vrhikky.github.io/VketCloudSDK_Documents/latest/WorldMakingGuide/ActivityWithCanvasUI.html)すると便利です。
また、メインシーンとアクティビティとの疎通は文字列での指定になるため、アクティビティで完結させた方が結果的に工数が減る印象です。

#### hsItemGetよりhsItemGetOwnSceneを使う

hsItemGet はアクティビティからメインシーンのアイテムを取得するときにも使えます

hsItemGetOwnScene を使用することで同じVM(仮想マシン)のItemを取得している意図がわかりやすいです


#### 疑似的なstaticメソッドとして、St-をプレフィックスする

:::note warn 
現状HeliScriptでstatic記法は使えません。
:::
自作のユーティリティ関数の実装コストが高くなってしまうため、クラス内に疑似的なstaticメソッドを置くことを許容します。
```C#
void StSystemAssert(bool condition, string errorMessage)
{
    if (!hsSystemIsDebugMode()) return; 
    if (condition) return;
    hsSystemWriteLine("Error: %s" % errorMessage);
}
```
vimtutorを使用してvimの学習

vimを学習するため、vimtutorをやってみたので学んだことを記載していきます。

vimの特徴はマウスを使わずにキーボード操作のみで内容を記述していくことです。
この文章はvscodeでvimを使って書いてみました。

vimには色々なコマンドがありますが多すぎて最初から全部覚えるのは不可能なので、ここではこの文章を書く際に使用したコマンドを順々に書いていこうと思います。

## カーソルの移動
キーボードの`H ,J ,K ,Lキー`で行います。
Hキーは左に、Jキーは下に、Kキーは上に、Lキーは右に移動します。
矢印キーでも移動可能ですが、速い操作をするならキーボードのホームポジションに近いこれらのキーを使うのが良さそうでした。

## 文字の削除
`xキー`を押すとカーソルの位置の文字が削除されます。
また、`dキー`を2回押すとカーソルの行全体が削除されます。

## 行の追加
`oキー`を押すとカーソルの次の行に新しい行が追加されます。
また、
`Oキー`を押すとカーソルの前の行に新しい行が追加されます。
`「ゼロ」ではなく、「大文字のオー」です。（shift+o）`

## 文字の挿入
`iキー`を押すとカーソルの位置に文字を挿入できます。
また、
`aキー`を押すとカーソルの次の位置に文字を挿入できます。
例えば、
ありがとうござます。という文章があるとして、
ありがとうございます。という文章に直したい場合は、
`「ま」にカーソルを合わせてiを押す`か、`「ざ」にカーソルを合わせてaを押す`といった操作で修正できるようになります。
### モードについて
`この文字の挿入ができる状態のことをインサートモード`といって、この状態になっていないと文字の挿入ができません。
そのためには、iかaを押してモードを切り替える必要があるということになります。

ちなみに`何もしていない状態をノーマルモード`といいます。
`escキー`を押すことでどのようなモードからでも、ノーマルモードに戻ることができます。
この状態だと文字の入力ができないので、上に書いたH,J,K,Lキーでカーソルの移動ができるようになります。
(インサートモードで`H ,J ,K ,Lキー`を押すと文字が入力されてしまう。移動はできない。)

## コピーとペースト
yyというように、`yキー`を２回押すとカーソルの位置の行がコピーされます。
(vimではコピーのことをヤンクというので、yキーでヤンクというのは覚えやすいと思いました)

`pキー`を押すとカーソルの位置にコピーした行がペーストされます。
この文章を書いている時は全然使わなかったですけど、実際にコードなどを書くときは使うことが多くなるかと思います。

## やり直し
`uキー`を押すと一つ前の操作を取り消すことができます。
間違って削除した際などにuキーを押すことでやり直すことができます。

## ファイルの保存
`:`を押すとコマンドモードになります。
続けて、`wq`と入力するとファイルを保存して終了することができます。
(wはwriteのwで保存、qはquitのqで終了を意味しています。)

## 検索
`/`を押すと検索モードになります。
検索したい文字列を入力すると、その文字列が見つかります。
`nキー`を押すと次の検索結果に移動します。

## まとめ
vimtutorをやってみることで基本的な操作を一通りやってみることができました。
この文章を書き始めた時点では、文字の入力をしたいのにノーマルモードのままだったり、カーソルを移動したいのにインサートモードだったりと苦戦しましたが、ここまで書いてると結構慣れてきて少しは楽しいと感じられるようになりました。

基本操作は他にもありますが、本記事では使用したコマンドを中心に書きました。
vimを使いこなすためには、実際に使ってみることが一番だと思うので、まずはvimtutorをやってみることをおすすめします。
vimtutorはターミナルを起動してvimtutorと入力して実行することで始めることができます。
3桁区切りを極める！正規表現 vs forループ

Paizaの問題を解いていたら、「数字を3桁ごとにカンマ区切りする」という場面に遭遇。
最初は直感でforループを書いたけど、「もっとスマートな方法あるのでは？」と気づいたので、いくつかの解法を比較してみる。

## <br>問題概要

入力例:
```
123456789  
```
出力例:
```
123,456,789  
```
数値を3桁ごとにカンマ区切りで出力する。入力される数値は3の倍数。

https://paiza.jp/works/mondai/stdout_primer/stdout_primer__specific_split_step6


## <br>解法①: 正規表現  `.match()` を使う
```js
const result = input.match(/.{1,3}/g).join(",");
console.log(result);  // 123,456,789
```

🔍 ポイント
- `/` で囲まれた部分が正規表現
- `.{1,3}` で1〜3文字のグループを作る
- `g` はグローバルフラグで、文字列全体に対してマッチを繰り返す

この方法のポイントは、余った文字（この例では最後の “j”）もそのまま結果に含まれる点。
    
`.match()` で配列化し、`.join(",")` でカンマを挿入・結合

<br>✅ メリット: シンプルで短いコード
❌ デメリット: 数の先頭から3文字ずつ切るので、`1,234,567` みたいなフォーマットにはならない

## <br>解法②: `for`ループで手動処理
```js
let result = "";

for (let i = 0; i < input.length; i++) {
    if (i % 3 === 0 && i !== 0) result += ",";
    result += input[i];
}

console.log(result);  // 123,456,789
```
🔍 ポイント
- 3文字ごとに `if` でカンマを挿入
- シンプルで可読性が高い

✅ メリット: 直感的で理解しやすい
❌ デメリット: カスタマイズ性が低い

## <br>解法③: `.split()` と `.map()` を活用
```js

const result = input.split("").map((char, index) => 
    (index % 3 === 0 && index !== 0 ? "," : "") + char).join("");

console.log(result);  // 123,456,789
```

🔍 ポイント
- `.split("")` で配列化し、.map() でカンマを追加
- `.join("")` で連結

✅ メリット: 配列操作に慣れている人なら直感的
❌ デメリット: ちょっと冗長

### <br> まとめ
短さ優先 → `match()` を使う
初心者向け → `for`ループ で素直に書く
応用力重視 → `split()` & `map()` を使う

[僕の失敗談と解決話！](https://paizabeginner.wordpress.com/2025/03/23/paiza%e3%81%a7%e5%9f%ba%e6%9c%ac%e3%83%9e%e3%82%b9%e3%82%bf%e3%83%bc-%e6%95%b0%e5%ad%97%e3%81%ae%e3%82%ab%e3%83%b3%e3%83%9e%e5%8c%ba%e5%88%87%e3%82%8a-%e6%ad%a3%e8%a6%8f%e8%a1%a8%e7%8f%be%e3%81%a7/)
TextMeshProでMaterialPresetを作成する

「Create Material Preset」メニューを見つけにくくて苦労したので備忘録として。

1.　シーン中のTextMeshProコンポーネントを選択
2.　InspectorからMainSettings → FontAssetをクリックし、Projectタブから該当するものを選択
![スクリーンショット 2025-03-23 16.01.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22207/62101918-1565-4e03-884c-8e73d168eaae.png)

3.　ProjectタブのFontAssetの下位にあるMaterialを選択
![スクリーンショット 2025-03-23 16.01.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22207/0ed3557e-a69a-40d7-a033-f325d64fe744.png)

4.　Inspectorのケバブメニュー（点が3つ並んでるやつ）から「Create Material Preset」を選択
![スクリーンショット 2025-03-23 16.02.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22207/25434c76-0a25-48f1-acd9-6d1d01d2d02f.png)

5.　新しく作成されたMaterialを選択し、フォントの設定を変更する
6.　シーン中のTextMeshProコンポーネントを選択
7.　InspectorからMainSettings → MaterialPresetを選択、作成したものを選択する
![スクリーンショット 2025-03-23 16.07.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22207/da0df732-23cf-489f-8b37-6357514157a1.png)
Promise.prototype.thenはいつ実行されるのか


Promise、then、setTimeoutについて理解があいまいだったのでまとめてみました。

## thenはいつ実行される？

いきなりですが、以下のコードの実行順序について考えてみます。

```javascript
console.log("A");
new Promise((resolve, reject) => {
  resolve();
  console.log("B");
}).then(() => console.log("C"));
console.log("D");
```

上記を実行すると`A`→`B`→`D`→`C`の順で出力されます。
まず`A`出力され、次にPromiseのコンストラクタに渡された関数内のresolve()が実行され、`B`が出力されます。（Promiseは非同期処理を扱うためのものですが、Promiseのコンストラクタに渡された関数は同期的に実行されます）そして、コンストラクタから返されたfulfilledの状態のPromiseオブジェクトで`.then`が呼ばれます。すでにresolve()が実行されているので、`C`がすぐに出力されそうですが、実際は`D`の後に出力されます。なぜすぐに実行されないのでしょうか？それにはJavaScriptの非同期処理について理解する必要があります。
## JavaScriptの非同期処理
JavaScriptは基本的にシングルスレッドで実行さるので、処理が同時に実行されることはありません。同時に実行されているように見えるのは、イベントループにより実行を遅らせたり分割したりするからです。イベントループとは以下のような繰り返しです。

1. キューからタスクを取り出す（なければ待機）
2. 実行する

キューには2種類あり**タスクキュー**と**マイクロタスクキュー**があります。setTimoutを使うと処理はタスクキューに追加されます。Promiseのthenを使うと処理はマイクロタスクキューに追加されます。実行される順番は以下のようになります。

1. タスクキューからタスクを取り出し実行する
2. マイクロタスクキューが**空になるまで**マイクロタスクを実行する（その間新しく追加されたとしても）
3. 必要であればレンダリングする

## 非同期処理の例

もう一度先ほどのコードに戻ります。

```javascript
console.log("A");
new Promise((resolve, reject) => {
  resolve();
  console.log("B");
}).then(() => console.log("C")); // マイクロタスキューに追加される
console.log("D");
```

まず、プログラムがタスクとして読み込まれ、同期的に`A`→`B`→`D`に出力されます。最後に非同期で`C`が出力されるのは、**thenの処理はマイクロタスクとして現在のタスクが完了した後に実行される**からです。

Promiseの部分は以下のように書き換えることができます。

```javascript
Promise.resolve().then(() => console.log("Microtask"));
```
そして上記のコードはマイクロタスキューに追加しているだけなので、さらに以下のように書き換えることができます。

```javascript
queueMicrotask(() => console.log("Microtask"));
```
`queueMicrotask()`は`setTimeout()`のような**タスクよりも先に実行**されます。
実行順序は以下の通りです。

```javascript
console.log("A");
setTimeout(() => console.log("Task"));
queueMicrotask(() => console.log("Microtask1"));
queueMicrotask(() => {
  console.log("Microtask2");
  queueMicrotask(() => console.log("Microtask3"));
});
console.log("B");
```

```console:結果
A
B
Microtask1
Microtask2
Microtask3
Task
```

まず、同期的に`A`と`B`が出力されます。そしてレンダリングや次のタスクの前にマイクロタスクが実行されるので`Microtask1`と`Microtask2`が出力されます。その後マイクロタスク内でさらにマイクロタスクを追加しています。途中で追加されたマイクロタスクも実行され`Microtask3`と出力されます。差後にsetTimeoutでタスキューに追加されたタスクが実行され`Task`と出力されます。この順番はマイクロタスクの処理にどれほど時間がかかったとしても変わりません。マイクロタスクが追加され続けると画面の更新処理が行えず、画面が固まってしまうので気を付ける必要があります。
Bedrock Access Gatewayで埋め込みモデルが使えない時に確認すること

# 初めに
OpenWebUIでAmazon Bedrockの埋め込みモデルを使用したときにはまった話です。
※Docker環境です。
OpenWebUI + Amazon Bedrockの接続は[公式ドキュメント](https://docs.openwebui.com/tutorials/integrations/amazon-bedrock/)を参考にしてください

# エラー内容
埋め込みモデルをtitan text embeddings v2に指定してナレッジベースを作成。
ナレッジベースにファイルアップロードしたらこのようなエラーが発生しました
![スクリーンショット 2025-03-23 172407.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3842266/5e2e7577-71d2-40b4-9306-4be8dcff2727.png)
Bedrock Access Gatewayコンテナのログにはこのように表示されていました
![スクリーンショット 2025-03-23 172450.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3842266/4202f473-3aab-4ca0-b791-5d02d72f501f.png)
ナレッジベースの作成に失敗した理由はログの通りでBedrock Access Gatewayでサポートされていないモデルなのでエラーが返ってきます。

# 解決方法
それではサポートされているモデルはどれなんだ?と思ってソースコードを辿っていたら、[サポートされているモデルIDの一覧](https://github.com/aws-samples/bedrock-access-gateway/blob/4f1a75b49fd6c30aec1f3682fd53ee6b73aa5d90/src/api/models/bedrock.py#L67)があったのでそのモデルIDに変更したところ、ナレッジベースの作成が出来るようになりました。
抜粋↓
```py:bedrock.py
SUPPORTED_BEDROCK_EMBEDDING_MODELS = {
    "cohere.embed-multilingual-v3": "Cohere Embed Multilingual",
    "cohere.embed-english-v3": "Cohere Embed English",
    # Disable Titan embedding.
    # "amazon.titan-embed-text-v1": "Titan Embeddings G1 - Text",
    # "amazon.titan-embed-image-v1": "Titan Multimodal Embeddings G1"
}
```
現時点(2025/03/23)では、Bedrock Access Gatewayで埋め込みモデルとして使用できるのはcohereの提供するモデルだけでした。
この1年のやらかしと反省


## はじめに
システム開発をしていると、しょうもないことが原因で障害につながることがあります。本記事では、私が担当する業務でこの1年間で経験した障害事例とその対応、そして「こうしておけばよかった」という改善点を共有します。

同じような障害を未然に防ぐための参考になれば幸いです。

---

## 1. データベース移行試験時のデータ消失事故
### **背景**
データベースの移行計画の一環として、新規DBの性能試験を実施。本番環境で一部のアプリケーションサーバをロードバランサから切り離し、性能試験を行った。

### **起こったこと**
性能試験後、新規DBのデータをクリアしたが、別システムから当該実際には別システムがアプリケーションサーバのIP（RIP）に直接リクエストを送っていたため、試験後の新規DB削除により登録されたデータが消失。

### **影響範囲**
- 一部のリクエストデータが失われ、復旧不可。

### **こうしておけばよかった**
- 設定で変更可能なため、アプリケーションのリクエスト受付ポートを変更して性能試験以外のリクエストを受け付けられないようにする。
-  データクリア前にログのgrepや簡単なクエリで、試験以外のリクエストが混入していないかを確認する。

---

## 2. バッチ処理の期待完了時刻の設定ミス
### **背景**
外部システムからのバッチ処理リクエストをファイル経由で受け付ける仕組みで、一部のシステムに事情があり、バッチ処理に必要な処理完了期待時刻のパラメータを指定できなかったため、そのようなファイルは当該項目を受信側で埋め込むような処理を追加。

### **起こったこと**
当日の18:00を期待完了時刻として付与するようにしたが、フロントシステムの処理遅延で18:00以降にファイルが連携されることがあり、ファイルを受信した時刻と完了期待時刻が逆転しエラーが発生。


### **影響範囲**
- 一部のバッチ処理がエラーで停止。
- 後続処理にも影響。

### **対応**
- 完了時刻が現在時刻以降になるように影響範囲のファイルを手作業で修正し、取り込み。
- 恒久対応として、ファイルの到着時刻が遅れる可能性を考慮し、期待完了時刻の設定ルールを見直し再リリース。

### **こうしておけばよかった**
- 事前にファイル連携のタイミングを確認  

---

## 3. ALTER TABLE によるシステムダウン
### **背景**
PostgreSQLのテーブルにカラムを追加する ALTER TABLE を実施。

### **起こったこと**
当該テーブルは大量のレコードを保持し、主要なトランザクションの多くで参照されるテーブルだった。長期間のテーブルロックが発生し、APIのレスポンスがタイムアウト。その結果、フロントのリトライ処理によりDBコネクション数が高騰し、システム全体がダウン。

(PostgreSQLではALTER TABLEを行う際にテーブルロックがかかり、そのテーブルの読み取り、更新SQLはALTER TABLEの完了を待ってから処理される知見はあったものの、ALTER TABLEにかかる処理時間を見誤っていて、障害に発展。)

### **影響範囲**
- フロントからのリクエストがほぼ全てタイムアウト。
- システム全体の処理に影響。

### **対応**
- 失敗した非同期処理は可能な限りリカバリ。
- 影響範囲をフロントシステムに共有し、必要に応じて再送依頼。
- 以後、テーブル定義変更時の影響を事前に検討するルールを策定。

### **こうしておけばよかった**
- (私が担当するシステムは24/365システムなので現実的ではないところもありますが、)大量レコードを持つテーブルにALTER TABLE が必要な場合はシステム全断によるメンテナンスを検討する。
- テーブル設計時点でカラム追加が不要なデータの持ち方を検討するべきだった。

---

## 4. 誤ったデータパッチ適用によるエラー
### **背景**
業務改善に伴い、特定のレコードのデータ形式を変更する必要があったが、対象のレコードは自システム内では判別できず、外部システムに依頼し、対象レコードのIDを抽出してもらいデータパッチを適用。

### **起こったこと**
抽出作業のミスで不要なレコードまで変更され、オンライン処理でエラーが発生。


### **影響範囲**
- 一部オンライン処理がエラーで停止。

### **対応**
- パッチを切り戻し。
- 影響データを抽出し、失敗した処理はリカバリ、またはフロントに再送依頼。
- 対象となるデータを再抽出してもらい、後述する検証プロセスを追加したうえでパッチを再実施。

### **こうしておけばよかった**
- (確実な方法ではないものの)データパッチ対象はこちらでは抽出できないものの、確実にパッチしてはいけないデータはこちらで出すことはできたため、突合せによる検証を行うことでパッチしてはいけないデータへのパッチを防げた。

---

## 5. SimpleDateFormat のフォーマットミス
### **背景**
非同期処理の結果を返却するAPIを提供し、その応答項目に処理が完了した時刻を返却。

### **起こったこと**
当該項目の日付から文字列への整形をJavaの SimpleDateFormatで行っていましたが、API仕様上 `yyyyMMddHHmmss` を指定すべきだったところ、誤って `yyyyMMddhhmmss` を指定してしまい、午前・午後の区別がつかなくなるバグが発生。


### **影響範囲**
- APIのレスポンスで時刻情報が誤った形で表示。

### **対応策**
- フォーマットを修正し再リリース。

### **こうしておけばよかった**
- 13時以降のデータを含めたテストケースを用意するべきだった。
- 日付フォーマットは定数化し、実装者が個別に設定しないようにするべきだった。

---

## まとめ
本記事で紹介した障害は、後から考えれば、障害が起こる可能性があったにもかかわらずそのリスクを見誤っていたものばかりでした。非常にバカバカしく、起こると悲惨な障害の種はどこにでも潜んでいます。この記事をご覧の皆さんは、私の失敗を笑っていただいてもいいので、同じようなミスから発生する障害を避けていただけたら幸いです。
Amazon Kinesis Producer Library (KPL)とは？

# Amazon Kinesis Producer Library (KPL)とは
Kinesis専用の高速データ送信ライブラリ

## メリット
- **高スループット対応**
    - レコードの集約とバッチ送信で効率的にデータ送信できる
- **再試行やエラーハンドリングが自動**
    - 送信失敗時の処理を自動で実行してくれる
- **CloudWatch連携による監視が簡単**
    - 送信状況やエラーを自動で可視化できる

## デメリット
- **Java専用ライブラリ**
    - Java以外の言語からは直接利用できない
- **一定の送信遅延がある**
    - バッファリングにより数百ms〜数秒の遅延が発生する場合がある
- **導入・設定がやや複雑**
    - 依存ライブラリや設定項目が多く、環境構築に手間がかかる

## Kinesis の主なサービス種別と役割

| サービス名                | 役割                                     | KPLとの関係           |
|---------------------------|------------------------------------------|------------------------|
| Kinesis Data Streams      | ストリーミングデータを高速で取り込む基盤 | ✅ KPLはこれ専用       |
| Kinesis Data Firehose     | データをS3やRedshiftへ自動配送           | ❌ 対応していない      |
| Kinesis Data Analytics    | ストリーミングデータをリアルタイム分析   | ❌ 対応していない      |
| Kinesis Video Streams     | 映像データの取り込み・保存用             | ❌ 関係なし            |

## KPL導入前

```mermaid
sequenceDiagram
    participant Kafka as オンプレKafkaクラスター
    participant EC2 as EC2インスタンス
    participant SDK as 自前実装（AWS SDKなど）
    participant KDS as Kinesis Data Streams

    Kafka->>EC2: メッセージを取り込み
    EC2->>SDK: 1件ずつ手動で送信処理
    SDK->>KDS: Kinesisへ逐次送信（非効率）
```

## KPL導入後

```mermaid
sequenceDiagram
    participant Kafka as オンプレKafkaクラスター
    participant EC2 as EC2 Auto Scalingグループ
    participant KPL as Kinesis Producer Library(KPL)
    participant KDS as Kinesis Data Streams

    Kafka->>EC2: メッセージを取り込み
    EC2->>KPL: データをKPLで処理
    KPL->>KDS: データをKinesisへ送信
```
Pythonの算術演算子について

## はじめに
Pythonの算術演算子についてまとめてみました。

## 演算子(operator)、算術演算子とは
　Pythonのコードで、コンピュータに計算をさせるために用いる記号を**演算子**(**operator**)という。特に、+や-などの数値の四則演算（足す・引く・掛ける・割る）をするための演算子を**算術演算子**という。

## 算術演算子の種類
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387980/2b1e164d-c33a-4ad8-b9af-fff358ca86bc.png)



## おわりに
ここまで読んでいただきありがとうございます！

## 参考文献
・スッキリわかるPython入門 第2版 (スッキリわかる入門シリーズ) 単行本（ソフトカバー） – 2023/11/6
国本 大悟 (著), 須藤 秋良 (著), 株式会社フレアリンク (監修)
p.35
SwiftUI 入力可能なアラートの実装

文字入力可能なアラートの実装例です。

```AlertText.swift
struct AlertText: View {

    @State private var inputText: String = ""
    @State private var showAlert: Bool = false

    var body: some View {
        ZStack {
            Button("アラート表示") {
                self.inputText = ""
                self.showAlert = true
            }
            .alert("入力してください", isPresented: $showAlert) {
                TextField("入力", text: $inputText)
                Button("完了") {}
                Button("キャンセル", role: .cancel, action: {})
            }
        }
    }
}
```

この様になります。

![Simulator Screenshot - iPhone 16 Pro - 2025-03-23 at 17.59.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274615/e20dcdc6-14b4-4c29-917d-ccccc2f13e7d.png)
kindでDocker Hubのレートリミットを回避する設定

Kubernetesの学習やローカル開発で使われる「kind」を利用しているとき、Docker Hubのレートリミットによってコンテナイメージがうまくpullできない経験はありませんか？特に繰り返しクラスターを作成・削除するような場合、すぐにレート制限に引っかかってしまいます。本稿では、kindでレートリミットを回避するための設定方法をご紹介します。

## はじめに

### Docker Hubレートリミットの現状と変更予定

Docker Hubでは、イメージのpull回数に制限があります。2025年4月1日から、この制限が以下のように変更される予定です。

- **未認証ユーザー**: 1時間あたり10回まで（IPアドレス単位で計算）
- **認証済み無料ユーザー**: 1時間あたり100回まで（これまでの40回から増加）
- **有料プランユーザー（Pro, Team, Business）**: 無制限（フェアユースポリシー適用）

認証すれば100回までpullできますが、Helm Chartを複数インストールしたり、環境を何度も作り直したりする開発フローでは、あっという間にこの制限に達してしまいそうです。

### kindにおける問題

kind（Kubernetes IN Docker）は、Dockerコンテナを使ってKubernetesクラスターをローカルで簡単に構築できるツールです。しかし、クラスターを作成するたびに必要なイメージをDocker Hubからpullするため、レートリミットに悩まされることがあります。

特に以下のようなエラーに見覚えはありませんか？

```
ImagePullBackOff: Back-off pulling image "docker.io/library/nginx:latest"
```

「なぜイメージがpullできないのか」と悩んだとき、Docker Hubのレートリミットが原因であることが少なくありません。

## 解決策：ミラーの設定

### 結論：レジストリミラーを使ってレートリミットを回避する

結論から言うと、Google Container Registry (GCR) のミラーを設定することで、Docker Hubのレートリミットを簡単に回避できます。kindクラスター作成時にcontainerdの設定をパッチすることで実現できます。

以下が設定の核心部分です：

```yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
containerdConfigPatches:
  - |-
    [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
      endpoint = ["https://mirror.gcr.io", "https://registry-1.docker.io"]
```

この設定により、Docker Hubからのイメージpull要求が自動的にGCRのミラーにリダイレクトされ、レートリミットを気にせずコンテナを起動できるようになります。

## 詳細な設定方法

### ステップ1：設定ファイルの作成

まず、上記の設定を含む`kind-config.yaml`ファイルを作成します：

```yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4

# ... 他の設定は中略 ...

containerdConfigPatches:
  - |-
    [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
      endpoint = ["https://mirror.gcr.io", "https://registry-1.docker.io"]
```

### ステップ2：設定ファイルを使ってクラスターを作成

作成した設定ファイルを使って、kindクラスターを作成します：

```bash
kind create cluster --name mirror-cluster --config kind-config.yaml
```

これだけで、Docker Hubへのイメージpullリクエストは自動的にGCRのミラーに転送されるようになります。

### ステップ3：動作確認

設定が正しく機能しているか確認するために、いくつかのPodをデプロイしてみましょう：

```bash
kubectl create deployment nginx --image=nginx
kubectl create deployment redis --image=redis
```

以前レートリミットで失敗していた場合でも、これらのデプロイメントが正常に動作するはずです。

## 仕組みの解説

### containerdのレジストリミラー機能

この設定が機能する仕組みを理解しておくと、他の環境でも応用できるでしょう。

containerdは、コンテナランタイムの一つで、kindクラスター内でコンテナを管理しています。containerdには「レジストリミラー」という機能があり、特定のレジストリへのリクエストを別のエンドポイントにリダイレクトできます。

今回の設定では：

1. `docker.io`（Docker Hub）へのリクエストに対して
2. 最初に`https://mirror.gcr.io`にアクセスを試み
3. 失敗した場合は`https://registry-1.docker.io`（オリジナルのDocker Hub）にフォールバック

という動作をします。Google Container Registry (GCR) のミラーは、Docker Hubの公開イメージをキャッシュしており、レートリミットなしで利用できるため、非常に便利です。

## まとめ

本稿では、kindクラスターでDocker Hubのレートリミットを回避するためのレジストリミラー設定方法をご紹介しました。シンプルなYAML設定を追加するだけで、開発中のImagePullBackOffエラーから解放され、よりスムーズにKubernetes開発に集中できるようになります。

レジストリミラーは、ローカル開発環境だけでなく、CIパイプラインや本番環境でもレートリミット対策やパフォーマンス向上のために活用できるテクニックです。ぜひ自分の環境に合わせてカスタマイズしてみてください。

最後までお読みくださりありがとうございました。
[Python][Financial Engineering][Energy Engineering] 金融モデリングとエネルギーモデリングの違い

**1. モデルの種類と目的の違い**

- **エネルギーモデリング**:
  - **目的**: エネルギー市場の価格動向や需給バランスを予測し、効率的なエネルギー供給と消費を実現すること。
  - **使用されるモデル**: 需給予測モデル、価格予測モデル、リスク評価モデルなど。

- **金融モデリング**:
  - **目的**: 金融商品の価格動向やリスクを評価し、最適な投資戦略やリスク管理を実現すること。
  - **使用されるモデル**: 資産評価モデル、リスク管理モデル、ポートフォリオ最適化モデルなど。

**2. 使用する手法の違い**

- **エネルギーモデリング**:
  - **手法**:
    - 統計的手法（回帰分析、時系列分析）
    - シミュレーションモデリング（モンテカルロシミュレーションなど）
    - 最適化手法（線形計画法、非線形計画法）
    - 機械学習アルゴリズム（ランダムフォレスト、サポートベクターマシン）

- **金融モデリング**:
  - **手法**:
    - 確率論的手法（ブラック-ショールズモデルなど）
    - 統計的手法（GARCHモデル、ARIMAモデル）
    - 数値解析手法（モンテカルロシミュレーション、有限差分法）
    - 機械学習アルゴリズム（ニューラルネットワーク、決定木）

**3. 評価指標の違い**

- **エネルギーモデリング**:
  - **評価指標**:
    - エネルギー効率（エネルギー消費量/生産量）
    - コスト削減額
    - 環境影響評価（CO₂排出量削減）
    - 需給バランス指標（供給能力 vs 需要量）

- **金融モデリング**:
  - **評価指標**:
    - リターン（投資収益率）
    - リスク指標（ボラティリティ、VaR）
    - シャープレシオ（リスク調整後リターン）
    - 最大ドローダウン（投資額の最大減少率）

**4. 特有の課題と解決策の違い**

- **エネルギーモデリング**:
  - **課題**:
    - エネルギー需要の予測精度の向上。
    - 再生可能エネルギーの不確実性の取り扱い。
    - 政策変更や規制の影響の評価。
  - **解決策**:
    - 高頻度データの収集と分析による需要予測モデルの精度向上。
    - 気象データや季節性を考慮した再生可能エネルギー予測モデルの構築。
    - 政策シナリオ分析を通じた政策変更の影響評価。

- **金融モデリング**:
  - **課題**:
    - 市場の非効率性や異常値の影響。
    - モデルの過適合（オーバーフィッティング）による予測性能の低下。
    - 外生的ショック（経済危機、パンデミック）の影響評価。
  - **解決策**:
    - ロバストなモデル設計と異常値処理技術の導入。
    - クロスバリデーションや正則化手法を用いたモデルの汎化性能向上。
    - ストレステストやシナリオ分析を通じた外的ショックの影響評価。

**5. システム実装と自動化の違い**

- **エネルギーモデリング**:
  - **実装と自動化**:
    - エネルギー管理システム（EMS）の導入によるリアルタイムデータ収集と分析。
    - 需給予測モデルの自動更新とアラート機能の実装。
    - 再生可能エネルギーの予測精度向上のための機械学習モデルの活用。

- **金融モデリング**:
  - **実装と自動化**:
    - トレーディングアルゴリズムの自動化による取引戦略の実行。
    - リスク管理システムの導入によるポートフォリオのリアルタイム監視。
Pythonの予約語(keyword)について

## はじめに
Pythonの予約語についてまとめてみました。

## 予約語とは
　Pythonには、**識別子**(**identifier**)として使用出来ない単語が35個程あり、これらは**予約語**(**keyword**)という。例えば、ifやfor、globalやwithなどは予約語であり、これらを変数名として利用することは出来ない。
 ※**識別子**・・・変数などの名前として使う文字や数字の並びのこと。

## 予約語を調べてみる
Pythonの予約語は次のコードで調べることが出来る。

```Python
import keyword
print(keyword.kwlist)
```

```Python:出力結果

['False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']
```

## 予約語の一覧
False
None
True
and
as
assert
async
await
break
class
continue
def
del
elif
else
except
finally
for
from
global
if
import
in
is
lambda
nonlocal
not
or
pass
raise
return
try
while
with
yield

## おわりに
ここまで読んでいただきありがとうございます！

## 参考文献
・スッキリわかるPython入門 第2版 (スッキリわかる入門シリーズ) 単行本（ソフトカバー） – 2023/11/6
国本 大悟 (著), 須藤 秋良 (著), 株式会社フレアリンク (監修)
p.52, 55
Windows + Java 21環境で、Eclipse + WebSphere Libertyを使用するときのコンソールログの文字化け対策

# 概要
Windows + Java 21の環境で、開発用途でEclipseとWebSphere Libertyを使用したとき、LibertyがEclipseのコンソールに出力したログが文字化けしてしまいました。

以下の記事で書かれているように、Liberty のサーバディレクトリにファイル `jvm.options`を作成し、`-Dfile.encoding=UTF-8` を設定したものの改善されませんでした。

[参考記事]
- [LibertyによるWebサービスアプリ開発メモ: (1)環境構築](https://qiita.com/tomotagwork/items/3a63ac7955d053a4feb4#liberty%E3%81%AE%E3%83%AD%E3%82%B0%E3%82%92utf-8%E3%81%AB%E5%A4%89%E6%9B%B4)
- [Bluemix Liberty for Javaの開発環境を整える（1/3）](https://qiita.com/asmanabu/items/a95dec97aabddd69acd8#was-liberty%E3%81%A7%E6%89%B1%E3%81%86%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E6%96%87%E5%AD%97%E3%82%B3%E3%83%BC%E3%83%89%E3%82%92utf-8%E3%81%AB%E5%A4%89%E6%9B%B4%E3%81%99%E3%82%8B)

Java 21では別の設定が必要であったため、その内容を以下記載します。

# 前提環境

- OS：Windows 11
- Java 21（IBM Semeru Runtime）
- WebSphere Liberty 25.0.0.2
- Eclipse 2024-06
- IBM Liberty Developer Toolsプラグイン 24.1
- EclipseのWorkspaceの Text file encoding として `UTF-8` を設定済み（EclipseのメニューバーのWindow -> Preferences -> General -> Workspace -> Text file encoding)


# 設定内容
（IBM Liberty Developer Toolsプラグインなどで）Libertyのサーバを作成すると、WebSphere Libertyをインストールしたディレクトリに、`usr/servers/<サーバ名>` というディレクトリが作成されます。

このディレクトリに `jvm.options` というファイルを作成し、そのファイルに以下を記述します。

```
-Dstdout.encoding=UTF-8
-Dstderr.encoding=UTF-8
```

これにより、標準出力、標準エラーの文字エンコーディングがUTF-8となり、LibertyがEclipseコンソールに出力するログが文字化けしなくなります。
謎のフレーム落ち問題がグラフィックドライバの更新で改善した話

# はじめに

以前、自作ゲームがフレーム落ちする問題を取り上げました。

[【C#】謎のフレーム落ち問題を解消したくタイマーを自作した話](https://qiita.com/abetakahiro123/items/ef46a34f175edb96dc01)

今回は、これがグラフィックドライバの更新で改善したことの報告です。

## 詳細

AMD Software: Adrenalin Edition バージョン 25.3.1(2025/02/25)  
このバージョンから AMD Install Manager や AMD Chipset Software が導入されました。

垂直同期がカクつく問題(Radeon 680M)が改善しました。タイマーで 60FPS 固定にしても稀にコマ落ちが発生して悩んでいたので大変助かりました。

おまけの報告として、動画再生時にしばらくマウス操作しない場合に動画のフレームレートが落ちる問題(Radeon 780M)が改善しました。これの原因はよくわかりません。別の PC でこの現象が発生していたので Radeon 780M 特有のものか、おま環かもしれません。いずれにせよ改善したので👍️

## あれこれ

なんの根拠もない考えですが、この手のフレーム落ちは省電力機能の影響かもしれません。一般的なアプリだとフレーム落ちしても気づかないことが多く、レンダリングを省略してバッテリーを節約していると見ています。

特にノート PC やモバイルではバッテリーの持ちはかなり重要なセールスポイントです。近年は Intel や AMD ほかのモバイル系 CPU が強力になっています。  
特にモバイル系の組み込み GPU の描画能力は飛躍的に強化されていて、その分ソフト的に複雑になったのかもしれません。  
CPU/GPU には AI 用の機能のあるモデルもあり、どんどん複雑になっています。

主要 CPU スコア <https://pcfreebook.com/article/458629156.html>  
主要 GPU スコア <https://pcfreebook.com/article/458753320.html>

## 自作したタイマーは今後も使いそう

```cs
var waiter = new ValueFpsWaiter();
waiter.Fps = 60f;

for (; ; )
{
    this.DoWork();
    waiter.Wait();
}
```

そもそもゲームエンジンを 60FPS 前提で作ってしまったため、フレームレートの高いモニター(90Hz とか 120Hz とか)では正常に動作しませんでした。アプリ側でわざわざフレームレートを落とす必要があるという・・・

## おわりに

この手の不具合は環境ごとに違うため、大変だなという感想です。大手の PC ゲームも「ゲームが起動しない」「フレームレートが安定しない」ことがあることを目にしますが、自分で踏んでみて「ああ大変なんだな」と実感しました。

ある種の割り切りも必要で、**動けばいい**を方針になるべく沼らないようにしようと思います。
[Python] 教師あり学習、教師なし学習、強化学習

### **教師あり学習（Supervised Learning）**  
教師あり学習とは、入力データ（特徴量）と正解ラベル（目的変数）のセットを用いてモデルを学習させる手法です。新しいデータに対して正しい出力を予測できるようにします。  

1. **線形回帰分析（Linear Regression）**  
   - 連続値を予測する回帰モデルの一種。入力データ \(X\) に対して重み \(w\) を学習し、  
     ```math
     y = wX + b
     ```
     の形で予測する。  

2. **ロジスティック回帰分析（Logistic Regression）**  
   - 分類問題に用いられる回帰モデルで、シグモイド関数を用いて出力を確率として解釈する。  
     ```math
     P(y=1|X) = \frac{1}{1+e^{-(wX + b)}}
     ``` 

3. **サポートベクターマシン（Support Vector Machine, SVM）**  
   - マージンを最大化する分類モデル。線形・非線形のデータ分類に適用可能。  

4. **決定木（Decision Tree）**  
   - 入力特徴量を用いてデータを条件分岐し、予測を行うモデル。回帰や分類に利用される。  

5. **k近傍法（k-Nearest Neighbors, k-NN）**  
   - 新しいデータが与えられたとき、最も近い \(k\) 個のデータのラベルに基づいて分類する。  

6. **アンサンブル学習（Ensemble Learning）**  
   - 複数のモデルを組み合わせて性能を向上させる手法。ランダムフォレストや勾配ブースティングなどが代表例。  

7. **パーセプトロン（Perceptron）**  
   - 単純なニューラルネットワークの一種で、線形分離可能な分類問題を解くことができる。  

8. **ニューラルネットワーク（Neural Network）**  
   - 多層構造を持ち、非線形なデータに対しても学習可能なモデル。  

9. **ディープラーニング（Deep Learning）**  
   - 多層ニューラルネットワーク（DNN）を用いた学習方法で、画像・音声・テキストなどの複雑なデータに適用される。  

10. **畳み込みニューラルネットワーク（Convolutional Neural Network, CNN）**  
    - 画像認識などに特化したニューラルネットワークで、畳み込み層を用いる。  

11. **画像認識（Image Recognition）**  
    - CNNなどを利用し、画像内の特徴を捉えて分類や識別を行うタスク。  

12. **自然言語処理（Natural Language Processing, NLP）**  
    - テキストデータを対象とした機械学習タスクで、分類や翻訳、生成などを含む。  


---

### **教師なし学習（Unsupervised Learning）**  
教師なし学習は、正解ラベルなしでデータの構造を学習する手法です。  

1. **階層的クラスター分析（Hierarchical Clustering）**  
   - データの類似性に基づいて階層的にクラスタを形成する手法。  

2. **非階層クラスター分析（Non-Hierarchical Clustering）**  
   - 事前に決めたクラスタ数に基づいてデータを分類する手法。  

3. **k-means法（k-means Clustering）**  
   - データを \(k\) 個のクラスタに分割し、各クラスタの重心を反復的に更新する手法。  

4. **主成分分析（Principal Component Analysis, PCA）**  
   - 高次元データを低次元に圧縮し、重要な情報を抽出する次元削減手法。  

---

### **強化学習（Reinforcement Learning）**  
強化学習は、エージェントが環境と相互作用しながら報酬を最大化するように学習する手法です。
ubuntu20.04 mysqlのデータベース(外部サーバ)を定期的に取る。覚書

バックアップ元サーバの設定条件。
バックアップする、サーバのアドレスを（今回はrootユーザ）バックアップするデータベースのユーザとして
追加しておく。
```
mysql -u root -p
 
mysql> select user, host from mysql.user;
+------------------+----------------+
| user             | host           |
+------------------+----------------+
| sample_user      | %              |
| root             | 133.xxx.xxx.xxx|この追加が必要。
| debian-sys-maint | localhost      |
| mysql.infoschema | localhost      |
| mysql.session    | localhost      |
| mysql.sys        | localhost      |
| root             | localhost      |
+------------------+----------------+
```
上記の設定にて外部サーバよりアクセス可能となり、
mysql -h 133.xxx.xxx.xxx -u root -p等で接続できるようになります。
この条件下で外部サーバにてバックアップを取るには。
```
mysqldump -h 133.***.***.*** -u root -p sample_db > sample_db_bkup.sql

```
更に、定期的バックアップは、 
crontab -e
または
vi /var/spool/cron/crontabs/root
にてcrontabファイルを編集して、バックアップスケジュールや、定期実行する処理等のシェルを作成し、
crontabファイルに記述して、自動実行させます。
下記は、毎日23:00にバックアップ処理シェルを実行する例です。
まずはシェル.shファイルを作成。
vi sample_bkup.sh
```
#!/bin/bash
/usr/bin/mysqldump -h 133.***.***.*** -u root -p sample_db > sample_db_bkup.sql
//記述後shファイルに実行権付与
chmod +x sample_bkup.sh
vi /var/spool/cron/crontabs/root
//にて最終行に追加記述。
#back up sample
MAILTO='' #ubuntuのcrontabファイルではこれが必要。！！
00 23 * * * ./sample_bkup.sh #23:00に実行。
```

以上ubuntuにて外部サーバへのバックアップ処理覚書です。
外部キー制約とテーブル設計の基礎

# はじめに

Laravelを使ってアプリ開発を進める中で、避けて通れないのが**テーブル設計**と　**リレーション（関連）** の考え方。  
その中でも「**外部キー制約（foreign key）**」は、データの整合性を保つためにとても重要です。

この記事では、外部キー制約の基本や、Laravelでの実装方法を自分用の備忘録としてまとめます。

---

# ①外部キー制約とは？

外部キーとは、**あるテーブルのカラムが、別のテーブルの主キーとつながっている関係性**のこと。

例：
- `posts` テーブルの `user_id` は、`users` テーブルの `id` を参照する

このような関係を定義することで、**間違ったデータが登録されるのを防げる**ようになります。

---

# ②Laravelでの外部キー制約の書き方

## 基本構文（Laravel 7以降推奨）

```php
$table->foreignId('user_id')->constrained();
```
これで以下のような制約が自動で付加されます。

- user_id は unsignedBigInteger 型になる
- 参照先は users.id
- 外部キー制約が自動的に張られる

# ③もっと詳しく指定したい場合

```php
$table->foreignId('category_id')
      ->constrained('categories')
      ->onDelete('cascade');
```

# ④よく使うオプション

![IMG_7725.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2246240/f39dae72-1d33-46c6-ac94-861f423fd9a8.jpeg)

# ⑤具体例：postsテーブルでの外部キー設定

```php
Schema::create('posts', function (Blueprint $table) {
    $table->id();
    $table->string('title');
    $table->text('body');
    $table->foreignId('user_id')->constrained()->onDelete('cascade');
    $table->timestamps();
});
```
このようにすることで
- user_id に存在しない users.id は登録できなくなる
- 親ユーザーが削除されると、その人の投稿も削除される

---

補足：本当に `onDelete('cascade')` でいいのか？

実務で多くのデータを扱うようになると、「親データを消したら自動で子も削除される」という `cascade` の動きが、**想定外のデータ消失**を引き起こすリスクになることがあります。

例えば、「退会したユーザーの投稿は残しておきたい」といったケースでは、`SET NULL` や `RESTRICT` を使う方が適しています。

### よく使うオプション比較

| オプション | 動作 | 主な用途 |
|------------|------|----------|
| `cascade` | 親を削除すると子も削除 | テストデータ、一時的な関係 |
| `set null` | 子の外部キーを null にする | 履歴データを残したい場合 |
| `restrict` | 子が残っていたら削除できない | データ保全が最優先の場面 |

### 書き方の例：

```php
$table->foreignId('user_id')
      ->nullable()
      ->constrained()
      ->onDelete('set null');
```
※ set null を使うときは nullable() を忘れずに！
```php
$table->foreignId('user_id')
      ->constrained()
      ->onDelete('restrict');
```
**経験からの教訓:**
- cascade を安易に使うと、意図しない大量削除の原因になる
- 削除連鎖は便利だけど、**明示的に「削除する責任」をコードで持つ設計**の方が安全
- **set null や restrict を使う習慣を身に付けておくと、設計力が一段上がる**


# ⑥よくあるエラー：外部キー制約違反
**例）「Integrity constraint violation」エラー**

このエラーは、以下のような状況で発生します

- posts.user_id = 3 に対して、users.id = 3 が存在しない
- 親を削除しようとしても、まだ子テーブルにデータが残っている

**対策:**
- onDelete('cascade') などの設定を見直す
- データの削除順序を調整する（子→親)

# ⑦外部キー制約を使うメリット
![IMG_7726.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2246240/e008e429-d21f-4cce-8e04-58eeb76f4fc6.jpeg)

# ⑧まとめ
- 外部キー制約は、　**データベース設計における「交通ルール」** のようなもの
- Laravelでは foreignId()->constrained() を使えば簡単に設定できる
- 実務でも、データの整合性を保つために積極的に活用したい
続: Android上でTermuxやUserLAndを使わずにVSCodeを動かす。

前記事：https://qiita.com/shun_nishi/items/8cc2bcd34fb192dc215b

前記事で書いたとおりPixelなど一部のAndroidの機種でLinuxターミナルが使えるようになりました。
しかしながらGUIアプリは起動できずcode-serverで代替していました。
# VNC Serverを立てればcode-server使わなくてもいけるんじゃないか

前回の記事に @trinos0909 さんからコメントいただきました。
https://qiita.com/shun_nishi/items/8cc2bcd34fb192dc215b#comment-4ff4b97c473622fcfbc1

> termuxにならえば、
guiについては、
vncserverを立てるとかでどうでしょうね。

こちらを試してみました。

# 今回使ったソフトウェア

### VNC サーバー
* [TigerVNC Server](https://tigervnc.org/)

### VNC クライアント
* [RealVNC Viewer: Remote Desktop](https://play.google.com/store/apps/details?id=com.realvnc.viewer.android&hl=ja&gl=US&pli=1)

# インストールしていく
まず、AndroidのLinuxターミナルに TigerVNC Serverとmate-sessionを入れます。あとから気づいたのですがVNCクライアント経由でアクセスした場合にターミナルソフトが何も入っていなかったのでxtermも一緒に入れます。

```bash
sudo apt -y install tigervnc-standalone-server mate-session-manager xterm
```

## VSCodeも予めインストールしておく
前回の記事の手順を参考に VSCodeもインストールしておきます。
```
sudo apt install xdg-utils
curl -L "https://code.visualstudio.com/sha/download?build=stable&os=linux-deb-arm64" -o vscode.deb
sudo dpkg -i ./vscode.deb
```

## VNC Serverのセットアップと起動
まずVNC Serverのパスワードを設定します
```bash
vncpasswd
```
その後起動します
```bash
tigervncserver -xstartup /usr/bin/mate-session -geometry 800x600 -localhost no
```
起動するとポートを許可していいかのポップアップが表示されるので許可をします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294409/98638266-0566-4328-858b-cae205633961.png)


# VNCクライアントからアクセスする
RealVNC Viewer を起動し、右下の `+` ボタンから新規接続先を登録します。
設定する内容は以下です
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294409/b7bb609a-fe25-463e-bcf8-2058ab480cad.png)

|項目|値|
|---|---|
|Address|localhost:5901|
|Name|適当に入れる。私はpixel-foldとしました|

そのあと下のほうにある Connect をタップして接続します

`Unencrypted connection` と警告が表示されますがローカル間での通信なので無視してOKをタップします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294409/eec1c6d1-f87b-4f97-bf72-a32cbd8bc12d.png)



### パスワードの入力
TigerVNC Serverインストール後に vncpasswd コマンドで設定したパスワードを入力します。

## 無事デスクトップ画面が表示される

こんな感じでデスクトップ画面が表示されました。
![Screenshot_20250323-164811.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294409/55700485-3ee9-40ef-a935-811b00361f6c.png)





# VSCodeは起動するのか
左上メニューの Application から Programing を選択すると Visual Studio Codeと表示されているのがわかります。
![Screenshot_20250323-165020.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294409/4a6ee413-4396-4475-8a68-47c972196703.png)



## 起動できたので適当にコード書いてみる。
無事起動できました。
インストールさえできてしまえば特に問題なく動く様子です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294409/ea23b522-6ee2-47dd-a555-06210a95a928.png)


# 実際使ってみてどう？
[前回記事](https://qiita.com/shun_nishi/items/8cc2bcd34fb192dc215b)で紹介したcode-serverを使うほうが軽快に動く気がします。

VNC経由となる分やや動きが遅くなってしまうのかもしれません。
AndroidのLinuxエミュレータがバージョンアップされて直接GUIアプリを動かせるようになるのを期待したいところです。

# 宣伝
[別記事](https://qiita.com/shun_nishi/items/08bc726b8d1b0cf74666)で書いたのですが私の所属するスティールパンバンド pangie が大阪で開催されるSuperOTONA Fes.2025本戦出場に向けて現在2次審査中です。

YouTubeの動画へのいいね数の上位5組が出場となるのですが、3/23現在8位と苦戦中です。
よければこちらの動画にいいねをよろしくお願いします。

https://www.youtube.com/watch?v=O0eDCZpEJpE
Azure App Service

初心者のAzure cloud 紹介
App Serviceは便利。

驚くほど簡単です。OS以下管理不要。PaaSと思われます。
デプロイは２通りやり方があります。
・開発したコードをstagingにコピー、確認後、本番にスイッチする。
・VS CodeでAzureにログインして、リソースグループとAppServiceを作って、warファイルをデプロイする。
（パスワードの入力以外、基盤のキも知らなくてよいです。）

まさに、プログラマーはビジネスロジックだけ集中してよい構成です。

OS = Linux
Container = Tomcat 
Java = 17

プラン　＞　App Service

MSのサイトを参考できます。
説明：
https://code.visualstudio.com/docs/java/java-webapp
10Gbase-T 相性問題

## 概要
今回、auひかり5Gbpsの契約を行い、家庭内ネットワーク高速化のため10Gbpsのポートを持ったネットワークスイッチ/ルータを購入した。目指したネットワークの構成は、図1のようなものである。ここで、BL3000HMはauひかりのレンタル機材、WN-7T94XRは購入したI/Oデータの製品である。また、途中のケーブルは、CAT5eもしくはCAT6aであり、仕様上5Gbpsまでは通る。検証用の端末からネットワーク測定サイトまでの経路で一番細いのは2.5Gbpsになる。

![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355409/b574f28e-7b3a-4da6-8560-6c8eea894cdf.png)
図1 構成したかったネットワーク

実際に組んでみると、10Gbps対応ポートどうしを直接接続した場合、BL3000HMとWN-7T94XRの間を5Gbps以上で通そうとすると、download側の性能が2.5Gbpsに比べてはるかにおそい性能しか出なかったため、記録として残しておく。
検証にあたり、I/Oデータのサポートセンターには大変お世話になりました。

## 内容詳細
いろいろテストしたところ、以下の3つのどれかが原因と思われた。
1. BL3000HMの故障
2. WN-7T94XRの故障
3. BL3000HMとWN-7T94XRの組み合わせ

切り分けのため、以下のテストパターンで測定を行った。測定結果は末尾に載せる。

# テストパターン1 : BL3000HMとWN-7T94XRを10Gbpsポートどうしで結線した場合
これが、目指していたパターンであり、問題となったパターン。構成図としては、図2のようになる。BL3000HMの10Gbpsポートの設定として、以下のすべてを試した。
1. 自動設定
2. 10Gbps固定
3. 5Gbps固定
4. 2.5Gbps固定
テスト実施時、テスト端末のインターフェースとしては、2.5Gbpsが最速だった。
![図2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355409/c5310162-ab76-4f90-98bb-04b7ecfad905.png)
図2 BL3000HMとWN-7T94XRを10Gbpsポートどうしで結線した場合

# テストパターン2 : BL3000HMの10GbpsポートとWN-7T94XRの2.5Gbpsポートを結線した場合
構成図としては、図3のようになる。テスト実施時、テスト端末のインターフェースとしては、2.5Gbpsが最速だった。この構成では、複数端末からの同時アクセス時にBL3000HMとWN-7T94XRの間がボトルネックになるため、避けたい構成。
![図3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355409/2a8c26e9-535c-491b-9bdb-3e86ae92521a.png)
図3 BL3000HMへつなぐWN-7T94XRの2.5Gbpsポートに結線した場合


# テストパターン3 : BL3000HMの10GbpsポートとWN-7T94XRの10Gbpsポートの間に、別の10Gbpsスイッチを挟んだ場合
構成図としては、図4のようになる。テスト実施時、テスト端末のインターフェースとして、5Gbpsが利用できるようになった。
![図4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355409/4f87d930-6a09-41ea-8deb-8263445e9627.png)
図3 FNS-1200P 10GbasepT (SFP+モジュール入り)を介したBL3000HMとWN-7T94XRの2.5Gbpsポートに結線した場合

# 速度まとめ
|テストパターン|download速度 (Mbps)|upload速度 (Mbps)|BL3000HMポート (Gbps)|WN7T94XRポート (Gbps)|他の10Gbase-T経由)|
|--|--|--|--|--|--|
|1|610.92|2372.00|10 (auto)|10|なし|
|1|582.44|2370.53|10 (固定)|10|なし|
|1|1704.76|2370.90|5 (固定)|10|なし|
|1|2363.93|2370.88|2.5 (固定)|10|なし|
|2|1795.31|2372.70|10 (auto)|2.5|なし|
|3|2222.28|2367.93|10 (auto)|10|あり|

なお、測定には、[Speedtest CLI](https://www.speedtest.net/apps/cli)を利用。

## 原因について推測
* テストパターン3から、BL3000HMとWN-7T94XRの双方は、5Gbps以上での接続が可能であり、どちらかの故障が原因というわけではなさそう。
* テストパターン1と2から、BL3000HMとWN-7T94XRの間の通信速度を最大2.5Gbpsとした場合は、2.5Gbpsでつながる。BL3000HM側の設定で2.5Gbpsにしたほうが速い。
* テストパターン1から、BL3000HMとWN-7T94XRの相性問題で、5Gbps以上の接続をしようとすると、2.5Gbpsでの接続時より実効で遅い速度でしかつながらなくなる。5Gbps接続時のほうがまだましで、10Gbps接続時は1Gbpsに負ける速度。
* BL3000HMとWN-7T94XRのどちらも何等かの処理が足りておらず、相性問題として見えていることが疑われる。FNS-1200Pはおそらくきちんと処理できたので、10Gbpsでつながったのではないか。

## そのほか
* Meshや今回のような相性問題は、買う前に注意できるような仕組みが欲しい。
* テストパターン3で導入した機材ができた時点でWN-7T94XRがなくても、目指すネットワークが組めるようになってしまった。WN-7T94XRは現在お蔵入り。(Wi-Fi 7は楽しそうだが、メッシュが使えないためうちでは役に立たない)
* FNS-1200Pには、Xicomの10Gbase-TのSFP+モジュールを2個搭載した。安価であり、耐久性は不明だが、今のところよく動いている。ただし、SFP+モジュールは触れないくらいに熱い。