OmniAICreator/Qiita-1.07M huggingface dataset:
[VRChat] Actual Performance Windowでパフォーマンスを確認

## ⭐️目的

アバターのパフォーマンスを確認する

## ⭐️参考

https://metacul-frontier.com/?p=7292#toc_id9

https://vpm.anatawa12.com/gists/ja/docs/reference/actual-performance-window/

## ⭐️インストール

anatawa12’s gist

![スクリーンショット 2025-04-28 18.56.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610706/5ec9885f-33bd-4038-84be-6343c14463ed.png)

https://vpm.anatawa12.com/gists/ja/

## ⭐️設定方法

![スクリーンショット 2025-04-28 19.00.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610706/f7b07fac-dabb-49a9-8d16-fd7fbb09dac8.png)

- ここをクリックするとポップアップが現れる

![スクリーンショット 2025-04-28 19.00.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610706/7b4903b3-ec49-47ba-8520-5c83206768ba.png)

- Actual Performance Windowにチェックマークを入れる

## ⭐️使い方

![スクリーンショット 2025-04-28 19.04.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610706/ac4427d6-c1fa-41df-9ab8-b09e75f6a103.png)


- プレイボタンを押す

![スクリーンショット 2025-04-28 19.01.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610706/3a9a3b8e-def4-4034-9b18-963aafdeaab5.png)

ポップアップが現れてパフォーマンスを表示してくれる

:::note warn
再生ボタンを使ったら消し忘れに注意すること!
:::
✨️ GCPのArtifact Registryで発生する無駄な課金を防ぐ方法

## 💡 はじめに
GCPでコンテナを使った開発をしていると、気づいたらArtifact Registryにイメージがたまりすぎて課金が膨らんでいた...という経験はありませんか？
自分も以前、上司に言われ調べてみると、CI/CDで毎回作られるイメージが削除されずに溜まり続けていました。
この記事では、その解決策としてCloud Buildのパイプラインに古いイメージの自動削除を組み込む方法を紹介します。

## 💰️ Artifact Registryのコスト問題
Artifact Registryは便利ですが、保存量に応じて課金されます。アジアリージョンだと1GBあたり月額約15円。
少額に思えても、CI/CDでイメージを日々生成していると、数ヶ月で数十GBになることも珍しくありません。

結果として、知らないうちに月数百円〜数千円の無駄な出費が発生していることも...⚠️

## 🚀 解決策：gcr-cleanerでイメージを自動削除
Cloud Buildのパイプラインに「gcr-cleaner」というツールを組み込むことで、デプロイ時に古いイメージを自動削除できます。
実装は超簡単！cloudbuild.yamlに以下のステップを追加するだけです✨️

```
// ビルド、プッシュ、デプロイのステップは割愛

# 古いイメージの削除
- id: delete-old-images
  name: asia-docker.pkg.dev/gcr-cleaner/gcr-cleaner/gcr-cleaner-cli:latest
  args:
    - --repo=asia-northeast1-docker.pkg.dev/$PROJECT_ID/$_REPOSITORY/$_SERVICE_NAME
    - --keep=3
    - --tag-filter-any=.*
```
たったこれだけで、最新の3つだけを残して他のイメージは自動的に削除されます🙆‍♂️

## 🔧 設定のポイント
主な設定項目はこの3つ

--repo: 対象となるリポジトリ
--keep: 残すイメージの数（例：1なら最新の1つだけ残す）
--tag-filter-any: 削除対象のタグパターン（.はすべてのタグが対象）

💡 必要に応じたカスタマイズ
開発環境なら --keep=3 など多めに
本番環境ならロールバック用に --keep=5 くらい
--tag-filter-any=^dev-.* とすれば dev- で始まるタグだけ削除

## 📈 導入してわかった効果
自分のPでは導入後、Artifact Registry関連のコストが月額約2,000円から300円程度まで下がりました！✨
小規模プロジェクトでもこの差ですから、大規模な環境なら効果はもっと大きいはず。
何より、手動でイメージ削除する手間がなくなったのが最高です。
デプロイするだけで勝手にきれいになるので、運用の手間も減りました！

## ✅ まとめ
GCPでコンテナを使った開発をしているなら、この設定は入れておいて損はありません。たった数行の追加で継続的なコスト削減になります。
まだ導入していない方は、ぜひ試してみてください！
【Power Automate】Graph SharePoint REST API 開発チートシート

Power Automateをある程度使っていると、標準のアクションだけでは事足りないことがある。そんな時にGraph APIを使うことが多々あるのだが、標準よりもできることが沢山あったので、自分用にまとめた。



## Graph API の使い方
SharePointでGraph APIを使うには「SharePointにHTTP要求を送信します」アクションを使っていく。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4072996/63ce6be9-e836-4295-94d0-87fa0d264dc5.png)

サイトのアドレスには対象SharePointやOneDriveのURLを指定。方法、URI、ヘッダー、ボディはリファレンスを参照しながら指定していく。


## SharePoint API に変換
Graph APIのリファレンスにあるURIは、以下の通りSharePoint API用に変換する必要があるとのこと。

|Graph URI|SharePoint URI|
|---|---|
|https://graph.microsoft.com/v1.0/sites|https://{tenant-name}.sharepoint.com/_api/v2.1/sites|
|https://graph.microsoft.com/v1.0/drives|https://{tenant-name}.sharepoint.com/_api/v2.1/drives|
https://graph.microsoft.com/v1.0/drive|https://{tenant-name}.sharepoint.com/_api/v2.1/drive|
https://graph.microsoft.com/v1.0/lists|https://{tenant-name}.sharepoint.com/_api/v2.1/lists|

ざっくり説明するとGraph APIの「v1.0」を「_api/v2.1」に変換して、URIに指定すれば良い。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4072996/bb369788-a957-4e8f-82f6-9b0e6fc32eb1.png)



## URI集
方法がPUT、POST、PATCHの場合は、ヘッダー、ボディの記述が必要なので、リファレンスを要確認。
https://learn.microsoft.com/ja-jp/graph/api/resources/site?view=graph-rest-1.0


### サイト関連

|概要|方法|URI
|---|---|---
|サイト一覧を取得|GET|_api/v2.1/sites
|サイトを取得|GET|_api/v2.1/sites/root
|サイトを取得|GET|_api/v2.1/sites/{site-id}
|サブサイト一覧を取得|GET|_api/v2.1/sites/{site-id}/sites
|サイトのアクセス許可一覧を取得 |GET|_api/v2.1/sites/{sitesId}/permissions
|サイトのアクセス許可を取得 |GET|_api/v2.1/sites/{sitesId}/permissions/{permissionId}
|サイトのアクセス許可を追加 |POST|_api/v2.1/sites/{sitesId}/permissions/{permissionId}|
|サイトのアクセス許可を更新 |PATCH|_api/v2.1/sites/{sitesId}/permissions/{permissionId}
|サイトのアクセス許可を削除 |DELETE|_api/v2.1/sites/{sitesId}/permissions/{permissionId}



### リスト関連

|概要|方法|URI
|---|---|---
|リスト一覧を取得|GET|_api/v2.1/lists
|リストを作成|POST|_api/v2.1/lists
|リストを取得|GET|_api/v2.1/lists/{list-title}
|リストを取得|GET|_api/v2.1/lists/{list-id}
|アイテム一覧を取得|GET|_api/v2.1/lists/{list-id}/items
|アイテムを作成|POST|_api/v2.1/lists/{list-id}/items
|アイテムを取得|GET|_api/v2.1/lists/{list-id}/items/{item-id}
|アイテムを更新|PATCH|_api/v2.1/lists/{list-id}/items/{item-id}
|アイテムを削除|DELETE|_api/v2.1/lists/{list-id}/items/{item-id}
|列一覧を取得|GET|_api/v2.1/lists/{list-id}/columns
|列を作成|POST|_api/v2.1/lists/{list-id}/columns
|列を更新|PATCH|_api/v2.1/lists/{list-id}/columns
|列を削除|DELETE|_api/v2.1/lists/{list-id}/columns



### ドキュメントライブラリ関連

|概要|方法|URI
|---|---|---
|規定ライブラリを取得 |GET |_api/v2.1/drive
|ライブラリ一覧を取得 |GET|_api/v2.1/drives
|アイテムを取得 |GET|_api/v2.1/drive/items/{item-id}
|アイテムを取得 |GET|_api/v2.1/drive/root:/{item-path}
|アクセス許可一覧を取得 |GET|_api/v2.1/drive/items/{itemId}/permissions
|アクセス許可を取得 |GET|_api/v2.1/drive/items/{itemId}/permissions/{perm-id}
|アクセス許可を更新|PATCH |_api/v2.1/drive/items/{itemId}/permissions/{perm-id}
|アクセス許可を削除 |DELETE |_api/v2.1/drive/items/{itemId}/permissions/{perm-id}
|アクセス許可を追加 |POST |_api/v2.1/drive/items/{itemId}/invite



## リファレンス
>Microsoft Graph REST API v1.0 エンドポイント リファレンス - Microsoft Graph v1.0 | Microsoft Learn
>https://learn.microsoft.com/ja-jp/graph/api/overview?view=graph-rest-1.0
NOR 演算の基本 !(A | B) 　　おまけ:| と || の違い

0と1しか出てこないのに、なぜかめちゃくちゃ奥が深い…。
今回解いたのは、Paizaの「NOR演算」

## <br>🧩 問題概要：
入力は `0` `1` の2つの数値で、出力は NOR（NOT OR）の結果。

<br>

https://paiza.jp/works/mondai/logical_operation/logical_operation__basic_step6


## <br>NGコード：
```js
const result = !(A | B);
console.log(result); // ❌ true or false が出る
```
これは論理値（boolean）を出してるだけ。
数値（0か1）で出さないとジャッジが通らない

## <br>✅ OKコード：
```js
const [A, B] = require("fs").readFileSync("/dev/stdin", "utf8").trim().split(" ").map(Number);
const result = Number(!(A | B));
console.log(result); // ちゃんと 0 or 1！
```
- `A | B` はビットOR

- `!` はNOT

- `Number()` が `true` / `false` を `1` / `0` に変換

<br>

NORも万能ゲートらしい
例：
- NOT A = A NOR A
- A OR B = (A NOR B) NOR (A NOR B)
- A AND B = (A NOR A) NOR (B NOR B)

NORだけで全ての論理演算を再現できる

## <br>📌 まとめ
NORは「ORの否定」と覚えればいい！

<br><br> [僕の失敗談(´;ω;｀)と解決策🐈🚀](https://paizabeginner.wordpress.com/2025/04/28/paiza%e3%81%a7%e5%9f%ba%e6%9c%ac%e3%83%9e%e3%82%b9%e3%82%bf%e3%83%bc%ef%bc%9anor-%e6%bc%94%e7%ae%97%e3%81%ae%e5%9f%ba%e6%9c%ac-a-b-%e3%81%8a%e3%81%be%e3%81%91-%e3%81%a8-%e3%81%ae%e9%81%95/)

## <br>おまけ ： JavaScriptにおける | と || の違い、まとめてみた👇

### ✅ |（ビット単位の OR）

ビット演算子（Bitwise OR） ってやつ。

各ビットごとに比較して、どちらかが1なら1を返す

例：
```js
console.log(5 | 3);  // => 7
// 5 = 0101
// 3 = 0011
// ---------
//     0111 = 7
```


### <br>✅ ||（論理 OR）

論理演算子（Logical OR） ってやつ。

- 左が「truthy」ならそれを返す。
- 左が「falsy」なら右を評価してそれを返す。
-「条件分岐」でよく使う！

例：
```js
console.log(true || false);      // => true
console.log(0 || 100);           // => 100
console.log("hello" || "world"); // => "hello"
```

### <br>👀 補足：今回の論理演算にはどっち？

Paizaの「0か1の論理演算」系は、0か1の数値として処理されるから：

`|` や `&` など ビット演算子を使うのがいいかも。
（でも `||` や `&&` を使っても 0と1なら正しく動いちゃう ）

📌 例：混乱しやすいやつ
```js
console.log(0 | 1);   // => 1  ← 数値（ビット演算）
console.log(0 || 1);  // => 1  ← 真偽値判定（0は falsy）

//でも：

console.log(0 || 2);  // => 2 ← 条件っぽく動く
```

「演算として使う」のか、「条件として使う」のか、そこが判断の分かれ目！
クライアント SDK 5 で Microsoft SignTool を使用してファイルに署名する

## 前提条件

AMI: Microsoft Windows Server 2022 Base (ami-0c798d4b81e585f36)

https://docs.aws.amazon.com/ja_jp/cloudhsm/latest/userguide/getting-started.html

の手順が終わっていること。

https://docs.aws.amazon.com/ja_jp/cloudhsm/latest/userguide/signtool-sdk5.html

こちらの CSR の作成手順でエラー (Invalid provider specified) が出るところで止まっていること。



## 解決方法

### msi ファイルでの CLI インストール

https://docs.aws.amazon.com/cloudhsm/latest/userguide/client-history.html

から、CloudHSM CLI の msi ファイルをダウンロードする

ダウンロードした msi ファイルをダブルクリックして、指示に従ってインストールする。



## IPアドレスの設定 & 耐久性チェックをオフにする



```
cd "C:\Program Files\Amazon\CloudHSM\bin"
configure-cli.exe -a <The ENI IPv4 / IPv6 addresses of the HSMs>
configure-cli.exe --disable-key-availability-check
```



### msi ファイルでのKSPインストール & 設定

https://docs.aws.amazon.com/cloudhsm/latest/userguide/client-history.html

から、CloudHSM KSP の msi ファイルをダウンロードする

ダウンロードした msi ファイルをダブルクリックして、指示に従ってインストールする。その後、IPアドレスを設定し、耐久性チェックをオフにする。（**忘れがちなので注意**）

```
cd "C:\Program Files\Amazon\CloudHSM\bin"
configure-ksp.exe -a <The ENI IPv4 / IPv6 addresses of the HSMs>
configure-ksp.exe --disable-key-availability-check
```



### 認証

CU の認証情報を入力する。

```
cd "C:\Program Files\Amazon\CloudHSM\tools\"
set_cloudhsm_credentials.exe --username <CU USER> --password <CU PASSWORD>
```

## CSRの作成・結果

```
certutil -csplist
```

を実行すると、以下のように出る（成功）

```
...
Provider Name: CloudHSM Key Storage Provider

Provider Name: Cavium Key Storage Provider
...
```



CSRを作成することができる

```request.inf
[Version]
Signature= $Windows NT$
[NewRequest]
Subject = "CN=AWS"
KeyLength = 2048
ProviderName = "CloudHSM Key Storage Provider"
ProviderType = 1
KeySpec = 1
MachineKeySet = TRUE
```

```
>certreq.exe -new request.inf request.csr

CertReq: Request Created

```



## 参考

https://repost.aws/questions/QUNkh9Uo-IT0q6h5d_N78_7A/error-while-creating-a-csr-using-certreq-exe

うまくいかないときはこちらを参照してみてください。



https://tech-blog.optim.co.jp/entry/2024/10/04/100000

2024年09月時点では SDK5 はCNG および KSP プロバイダーをまだサポートしていなかったようですが、今はドキュメントを見る限りではサポートしています。

## 途中で出たエラー文
```
>certreq.exe -new request.inf request.csr
Certificate Request Processor: Provider type not defined. 0x80090017 (-2146893801 NTE_PROV_TYPE_NOT_DEF)
```
```
>certutil -csplist
Provider Name: CloudHSM Key Storage Provider
CloudHSM Key Storage Provider: An internal error occurred.

Provider Name: Cavium Key Storage Provider
Cavium Key Storage Provider: An internal error occurred.
```
```
>certreq.exe -new request.inf request.csr
Certificate Request Processor: An internal error occurred. 0x80090020 (-2146893792 NTE_FAIL)
```
この辺りは IP アドレスの設定や耐久性チェックのオフを忘れていると発生する。
HTMLの文字実体参照について

## HTMLの文字実体参照について
　**文字実体参照**とは、半角スペースや不等号などを表記するための方法である。
HTMLにおいて、「＜」や「＞」はタグを表すため、そのまま文字として表記出来ない。
そのため、文字実体参照を用いて表記する。

**表：主な文字実体参照**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387980/75d6b491-328a-4005-b744-3b6597ab8a6d.png)

## 参考文献
・HTML教科書 HTML5プロフェッショナル認定試験 レベル1 スピードマスター問題集 Ver2.5対応 単行本（ソフトカバー） – 2022/12/7
株式会社富士通ラーニングメディア (著), 抜山 雄一 (著), 七條 怜子 (著), 結城 陽平 (著), 竹川 夏実 (著)
p.15
【Ruby】ターミナルでコンピュータと対話しながら設定を行う方法

Rubyコマンドを実行したときに、ユーザとコンピュータが対話しながらCLIの設定を行う方法を簡単にメモとして残しておきます。

# サンプルコード

```rb
puts "何かしらの文字を入力してください"

input = gets.chomp

puts "入力された文字は #{input} です"
```

`gets`メソッドは標準入力からユーザーの入力を読み取るRubyの組み込みメソッドです。
これを使用することで、ユーザの入力をRubyプログラムへ反映させることができます。

今回はこれだけです。
BizRobo! の細かすぎる話：初めてRS内組み込みMCを起動する場合の注意点

## はじめに

RS組み込みMCを使用するのはソフトウェアのトライアルや検証時に限られると思いますが、急に聞かれたときに勘違いすると時間を使ってしまうので備忘まで。

## セットアップ時の初回起動完了サイン

さて、以下2つのコンソール表示の内、どちらが初回起動時の完了サインとして適当でしょうか？

**その ①**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3090491/7747839d-bbfa-41d7-80b8-f6cb3776ae02.png)

**その ②**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3090491/d922d18c-514e-4f07-923d-6748bbfc6b23.png)

違いは最後の2行。

`RoboServer` が起動した後、無事 cluster に接続できたかどうかの部分。
幾ら `RoboServer` が起動したところで、`MC` 上のクラスターに接続できなければ `MC` からロボットを実行することはできません。

遠足は家に帰るまでが遠足。
ちゃんと収まるところに収まるまでを監視する必要がありますね。

## と、思うじゃん。

ただ、初回起動時（ラインセンス設定前）に関してはその限りではありません。
なぜなら、初回起動後に `MC` へ接続して最初に表示されるのがこの画面[^1]なので。

[^1]: 正確には最初に表示されるのはログイン画面であり、管理者アカウントでログインした後、最初に表示されるのがこの画面。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3090491/aab5e763-ee76-470a-909a-bfa9b9ae0730.png)

起動した `RS` が接続しに行くクラスター情報はこの画面で入力するライセンス情報に紐づいているため、ライセンスを入力しない限り、クラスターが有効にはなりません。

つまり初回起動時（ライセンス設定前）に `MC`を起動した場合、いくら待っても `RoboServer successfully activated.` という文字が表示されることはありません。

## 結論

`MC` の初回起動は、ただでさえ war ファイルの展開や初期化処理等が実行されるためトライアル用に使用するPCのスペックによっては 5分～10分 待つこともあります。

とはいえ、`RoboServer successfully activated.` の表示をいくら待っても表示されることはありません。。。

一方で、ライセンス設定後は `RoboServer successfully activated.` の表示が必須です。`RS`はクラスターに接続されて初めてロボットを実行できるので。
グレブナー基底でピクロスを解く

## グレブナー基底って何？

Q. グレブナー基底とはなんぞや？
A. 簡単にいうと多項式を代数学的に解くための方法。詳しくは以下の記事や大学の講義資料などを参照

- https://ja.wikipedia.org/wiki/%E3%82%B0%E3%83%AC%E3%83%96%E3%83%8A%E3%83%BC%E5%9F%BA%E5%BA%95

## ピクロスって何？

マリオのピクロスで有名なやつ

- https://ja.wikipedia.org/wiki/%E3%83%94%E3%82%AF%E3%83%AD%E3%82%B9_(%E3%82%B2%E3%83%BC%E3%83%A0%E3%82%BD%E3%83%95%E3%83%88)

## ピクロスについてもう少し詳しく

3x3のピクロスを考える。
以下のように行と列にそれぞれヒントが与えられる。

```
    1   1
    1 1 1
1 1 □ □ □
  0 □ □ □
  3 □ □ □
```

ヒントは、連続して塗られているマスを表す。
`3`と書いてあれば、3マス連続して塗られている事を表す。  
`1 2`(1と2)と書いてあれば、「連続した1マス」と「連続した2マス」が塗られており、1マスと2マスが連続すると3になってしまうので、両者の間は1マス以上開くことになる。

先程の問題は最終的に以下のようになる。  
■ : 塗ってある  
□ : 塗ってない

```
    1   1
    1 1 1
1 1 ■ □ ■
  0 □ □ □
  3 ■ ■ ■
```

## グレブナー基底で解く

これをグレブナー基底で解いていく。

算出する手順は以下の通り

1. 各マスに変数を割り当てる
2. 制約（方程式）を作成する
3. ブール制約を入れる
4. グレブナー基底のアルゴリズムで解く

### 1. 各マスに変数を割り当てる

各マスに変数を割り当てる

```
x00 x01 x02
x10 x11 x12
x20 x21 x22
```

### 2. 制約（方程式）を作成する

以下の方針で方程式を作成する。

1. マスを塗る :  `(x - 1)^2`
2. マスを塗らない : `(x - 0)^2` (= `x^2`)
3. 各行毎に、塗る／塗らないのパターンを作成し、加算でつなぐ
4. 複数の可能性がある場合は、乗算でつなぐ
5. 各列に対しても同様にする

わかりにくいので、実際に以下の例で考えてみる

```
    1   1
    1 1 1
1 1 □ □ □
  0 □ □ □
  3 □ □ □
```

各行について方程式を作成すると、以下のようになる

1. `(x00 - 1)**2 + x01**2 + (x02 - 1)**2`
   - 1マス目 : 塗る
   - 2マス目 : 塗らない
   - 3マス目 : 塗る
2. `x10**2 + x11**2 + x12**2`
   - 1マス目 : 塗らない
   - 2マス目 : 塗らない
   - 3マス目 : 塗らない
3. `(x20 - 1)**2 + (x21 - 1)**2 + (x22 - 1)**2`
   - 1マス目 : 塗る
   - 2マス目 : 塗る
   - 3マス目 : 塗る

各列について方程式を作成すると、以下のようになる

1. `(x00 - 1)**2 + x10**2 + (x20 - 1)**2`
   - 1マス目 : 塗る
   - 2マス目 : 塗らない
   - 3マス目 : 塗る
2. `(x01**2 + x11**2 + (x21 - 1)**2)*(x01**2 + x21**2 + (x11 - 1)**2)*(x11**2 + x21**2 + (x01 - 1)**2)`
   - この場合は、以下の3パターンが考えられるので、それぞれ方程式を作成して、乗算でつなぐ
     - 1マス目が塗られている : `(x11**2 + x21**2 + (x01 - 1)**2)`
     - 2マス目が塗られている : `(x01**2 + x21**2 + (x11 - 1)**2)`
     - 3マス目が塗られている : `(x01**2 + x11**2 + (x21 - 1)**2)`
3. `(x02 - 1)**2 + x12**2 + (x22 - 1)**2`
   - 1マス目 : 塗る
   - 2マス目 : 塗らない
   - 3マス目 : 塗る

### 3. ブール制約を入れる

一般的にはグレブナー基底で方程式を解くと、特定の値ではなく範囲が求まる。  
今回は、塗る／塗らない(1/0)の2パターンしか存在しないので、以下の制約を入れる。

- `x(x - 1)` (= `x^2 - x`)

`x(x-1)=0`を解くとわかるが、`x=0,1`となり、算出される解を`0,1`に制限できる

これを、`x00`〜`x22`の各変数に対して方程式を作成して制約とする

### 4. グレブナー基底のアルゴリズムで解く

作成したコードは以下にあります。

- https://github.com/ripplex-soichiro-mori/groebner_picros_sample/blob/main/main.py


## 最後に

グレブナー基底で数独を解くプログラムがあるのは知っていたので、他のパズルゲームにも応用できるハズだよなと思ったので作成しました。
(大筋はChatGPTで生成したものなので、自分で1から作成したわけでは無いですが)

数独と異なり、塗る／塗らないの1/0で考えられるので、条件としては、こちらの方が解きやすいのではないかと思いますが、そもそもグレブナー基底の速度自体が遅いので、6次元以上のデータになると、終わらなくなってしまいました。

`CGS-QE`なるアルゴリズムがあり、通常のアルゴリズムよりは高速に解けるとの事ですが、残念ながら `sympy`には実装されておらず、`SINGULAR`や`Risa/Asir`のような代数計算システムにのみ実装されているとのことだったので、今回は諦めました。
2025年版フリーランスエンジニア求人市場のインフレがヤバい

<h1>2025年版フリーランスエンジニア求人市場のインフレがヤバい</h1>


<h3>初めに</h3>
やる気ありません。<br>
仕事中に書いてます。やる気ありません。

フリーランスエージェントに聞いたら1つの分野さえやっていればまあいける？みたいな感じでしたが今はもう違うようです。

<br>
何かしら広くできる人を求めてるぽいです。

<br>
それでようやく月単価60万ぐらいでもうインフレが進みすぎてます。
<br>前までフリーランスエンジニアで年収1000万は余裕です(ハッキリ)、月収80万はまあ普通ですよみたいに言われてましたが、全くのウソになりました。
もう日本も終わりか…

<br>
フリーランススタートを見ればわかるように月〇〇万もらうなんて要件定義＋テックリード＋リーダー経験＋言語経験5年＋AWS経験あり＋コミュ力あり、みたいな頭のいい人用の求人しかありません。。
TypeScriptでの開発の進め方

初めてTypeScriptを触りました。

いろいろな機能があり混乱したので、
今後、このやり方で進めるときに忘れないように記事に残しました。

## 1. ディレクトリ構造の例
```
プロジェクト/
  ├── src/ 
  │   └── example.ts
  ├── dist/  
  │   └── example.js
  └── tsconfig.json
```

## 2. tsconfig.jsonの設定
````json
{
  "compilerOptions": {
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "module": "commonjs",
    "target": "es2016"
  }
}
````

## 3. コンパイル
```bash
tsc
```
1. .tsから.jsにコンパイルする
2. これだけでOK

## 4. 開発ワークフロー

新規ターミナル作成: `Ctrl + Shift + @`
```bash
tsc --watch
```
別ターミナルで実行確認
```bash
node dist/example.js
```
下記のような表示になればOK
```bash
[16:47:46] File change detected. Starting incremental compilation...

[16:47:46] Found 0 errors. Watching for file changes.
```
あとは`.ts`を上書き保存すればリアルタイムで`.js`に反映される


## 5. 手順のまとめ
1. プロジェクトフォルダ作成
2. tsconfig.json の設定
3. srcとdistフォルダの作成
4. VS Codeで開く
5. ウォッチモード起動
6. コーディング開始
Databricks の Lakehouse federation にて BigQuery をソースにしている場合に Databricks Runtime 16.1 以降のクラスターでは Spark Connector が利用される仕様に変更


## 概要

Databricks にて Lakehouse federation を BigQuery をソースにしている場合に、Databricks Runtime 16.1 以降のクラスターでは Spark Connector が利用されることがドキュメントに記述されており、その動作仕様を確認しました。 Spark Connector と JDBC のどちらが利用されているかを確認する方法を共有します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/436d5882-f1b9-4e74-be52-6ea1f6aa63f5.png)

出所：[BigQuery コネクタのアップグレード](https://learn.microsoft.com/ja-jp/azure/databricks/release-notes/runtime/16.1#bigquery-connector-upgrade)

2025年4月28日時点では、 Databricks SQL （Databricks SQL version 2025.15）では JDBC が利用されていました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/7141d29c-8ac6-45b1-bb01-99909e6d7526.png)

本記事は下記シリーズの一部です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/1bb4805e-9f67-49e9-8e72-36036bf4310c.png)

出所：[Databricks で BigQuery のデータを取得する方法の徹底ガイド - Qiita](https://qiita.com/manabian/items/7097a9c31de23752d58a)

## EXPLAIN 句による確認方法

### Databricks 側で EXPLAIN 句により確認する方法

Databricks の EXPLAIN 句にて JDBC による接続なのか、 Spark Connector による接続なのかを確認できます。

```sql
%sql
EXPLAIN
SELECT * FROM bq_01_catalog.gc_test.test_table_02 WHERE id = 3;
```

Spark Connector が利用されている場合には、`apache.spark.sql.connector`等の記述があることを確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/e6769478-1951-4eb4-85e3-15b994843ea8.png)


JDBC が利用されている場合には、`JDBC`等の記述があることを確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/7d0539cc-f4bd-400b-b381-ae0599676e04.png)

### Google Cloud の Logs Explorer による確認方法

Google Cloud の Logs Explorer にて JDBC による接続なのか、 Spark Connector による接続なのかを確認できます。

```LQL
timestamp >= "2025-04-28T07:41:00Z"
timestamp <= "2025-04-28T07:43:00Z"
```

Spark Connector が利用されている場合には、`callerSuppliedUserAgent`という項目に`spark-bigquery-connector`ではじまる値が確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/e86405ca-63f5-4247-995e-2e0e1ec6def7.png)

JDBC が利用されている場合には、`callerSuppliedUserAgent`という項目に`SimbaJDBCDriverforGoogleBigQuery`ではじまる値が確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/f9f057c6-e02a-4ab7-a717-73f780e6c4ef.png)
Zodのcoerce機能で解決：React・React Hook Form・Zodを組み合わせて利用しているときの input type="number" が文字列になる問題の対処方法

## 🤔 こんな問題に悩んでいませんか？

React・React Hook Form・Zodを組み合わせてフォームを作っていると、
`<input type="number">`の値が「数値」ではなく「文字列」として扱われてしまうことがあります。

たとえば

```ts
const value = formData.get('count'); // フォーム送信後の値
console.log(typeof value); // "string" 😱
```

見た目は数値用のフォーム要素なのに、
React側・サーバー側では結局 string として値を受け取ってしまい、
「数値として処理したいのに！」と困ることはありませんか？


## 📝 よくある解決パターン

こんな解決パターンを見かけることがあります。

```typescript
// フォーム用とサーバー用、2つの型定義を作成
interface FormData {
  count: string;  // フォームからの入力は文字列
}

interface ProcessedData {
  count: number;  // 処理時は数値
}
```

このパターンだと、コードが冗長になり、型の不一致によるバグも発生しやすい問題があります。

## ✅ Zodのcoerce機能で解決！

Zodの`coerce.number()`を使えば、この問題を解決できます。

```typescript
import { z } from "zod";

// たった1つの型定義でOK！ 🎉
const formSchema = z.object({
  count: z.coerce.number().int().min(1)
});

type FormData = z.infer<typeof formSchema>;
```

## 🚀 React Hook Formでの実装例

```typescript
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";

function CounterForm() {
  const { register, handleSubmit } = useForm<FormData>({
    resolver: zodResolver(formSchema)
  });

  const onSubmit = (data: FormData) => {
    console.log(typeof data.count); // "number" 🎯
    // 数値として直接計算できる！
    const doubled = data.count * 2;
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input type="number" {...register("count")} />
      <button type="submit">送信</button>
    </form>
  );
}
```

## ⚡ Next.jsのServer Actionsでも

```typescript
'use server'

// Server Actionsでも同じスキーマが使える！ 🔄
export async function saveCount(formData: FormData) {
  const data = formSchema.parse({
    count: formData.get('count')
  });
  
  // data.countは既に数値型 🧮
  // データベースに保存する処理...
}
```

## 💡 coerce.number()のポイント

- 空文字列 → `0` に変換
- 文字列 `"123"` → 数値 `123` に変換
- バリデーションも同時に設定可能（`.int()`、`.min()`など）

## 🌟 メリット

- **型定義の一元化**: フォーム用とサーバー用で別々の型が不要に
- **コードの簡素化**: 変換処理を書く手間が省ける
- **型安全性の向上**: フォーム入力からサーバー処理まで一貫した型で扱える

## 🎯 まとめ

React・React Hook Form・Zodを組み合わせてフォームを使うと、
<input type="number">の値が文字列として扱われるケースがあります。

Zodの coerce.number() を使うことで、
型の管理をシンプルにしつつ、自然に数値として扱いやすくできました！

- [Zod公式ドキュメント](https://zod.dev/)
- [React Hook Form](https://react-hook-form.com/)
- [Next.js Server Actions](https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions)
Unityで特定のカメラで特定の3Dモデルを描画しないようにするには

Unityで複数プレイヤーでの通信プレイができるゲームを作ろうとしていた時に、カメラがモデルの中に埋め込まれている関係で、モデルの一部分がカメラに写ってしまっているという問題がありました。

今回はその対処法として、自身のカメラだけプレイヤー自身のモデルを描画せず、相手のカメラには自身のモデルを描画することができる方法を調べたので残しておきます。

# 解決方法

まず、見えなくしたいモデル用のレイヤーを作成します。
今回は`Mouse`というレイヤーを追加してみます。

次にそのレイヤーを該当モデルにアタッチします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/384c0a98-f68b-48f0-a2fc-57450bbf06d2.png)

次にモデルを描画して欲しくないプレイヤーのカメラのCameraコンポーネントに`Culling Mask`というプロパティがあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/42e749ee-a83c-46cb-84f5-3a565004ef8b.png)
>cullingとは「詰む」という意味です。

ここのトグルを開くと角レイヤーにチェックがついていると思うので、描画して欲しくないレイヤーのチェックを外します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/abd091c8-8888-4f0c-be22-c33c12e19a58.png)


こうすることで特定のカメラでは特定のレイヤーがアタッチされたモデルを描画しなくなります。

:::note warn
プレイヤーごとにカメラを分ける必要があります。
:::
Azure Bastion を使用して Entra Join デバイスにリモート接続する

検証環境の構成変更に伴い長らく Azure Virtual Desktop 経由で行っていたリモート接続を Azure Bastion に移行しました。
その際にちょっとしたノウハウがありましたので本稿でご紹介いたします。

## デバイスが Entra 認証の RDP を受け入れるための設定

https://qiita.com/carol0226/items/4f60443dead0a20e95f6#1-%E5%8F%82%E5%8A%A0%E6%B8%88%E3%81%BF-%E3%83%87%E3%83%90%E3%82%A4%E3%82%B9%E5%81%B4%E3%81%AE%E8%A8%AD%E5%AE%9A

ご本人の承諾もいただきリファレンス貼らせていただきました、こちらを参照して **1. "参加済み" デバイス側の設定** を行います。

## Bastion のデプロイ

https://learn.microsoft.com/ja-jp/azure/bastion/tutorial-create-host-portal

Bastion をデプロイします、IP アドレス指定による接続のため SKU は Standard もしくは Premium SKU を選択ください。
その後、

https://learn.microsoft.com/ja-jp/azure/bastion/connect-ip-address#configure-bastion

にて [IP based connection] を有効化します。

## 1回接続してみる
ここで 1 回接続してみます。
Azure ポータルから Bastion のリソースを開いて接続してみると、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620633/5e4352ca-a1de-49e4-9daa-8e7bcbb7df5f.png)
と Connection Error で接続することができません。
先のリファレンスを読み進めていただくとわかりますが、接続元側にも設定が必要なので Azure ポータルでは対応できないんでしょう。

では次のセクションから、この事象をクリアするためのネイティブクライアントよる Bastion 接続の手順を見ていきます。

## Azure CLI のインストール
ネイティブクライアントから Bastion を使用するためには Azure CLI を使用しますので、

https://learn.microsoft.com/ja-jp/cli/azure/install-azure-cli

で　Azure CLI をインストールしたら、

```
az extension add --name bastion 
```
と Bastion 拡張機能を追加します。

## RDP ファイルの作成

https://qiita.com/carol0226/items/4f60443dead0a20e95f6#2-rdp%E3%82%AF%E3%83%A9%E3%82%A4%E3%82%A2%E3%83%B3%E3%83%88%E5%81%B4%E3%81%AE%E8%A8%AD%E5%AE%9A

再登場、今度は **2. RDPクライアント側の設定** の手順で "enablecredsspsupport:i:0" を追加した RDP ファイルを作成します。

## ネイティブクライアントサポートの有効化

https://learn.microsoft.com/ja-jp/azure/bastion/native-client#deploy-bastion-with-the-native-client-feature

Bastion の [Native Client Support] を有効化します。

## 接続してみる
それでは再度接続してみます。
まずは Azure CLI にて、

```
az account clear

az login

az network bastion tunnel --name [Bastion リソース名] --resource-group [Bastion リソースグループ名] --target-ip-address [接続先の IP アドレス] --resource-port [接続先のポート番号] --port [ローカルのポート番号]
```

を実行しトンネル (ポートフォワード) を確立します。

次に先のセクションで作成した RDP ファイルを実行し、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620633/9f64e314-6a85-4053-90b5-d754500d4415.png)

コンピューターに "localhost:[ローカルのポート番号]" を指定して接続します。
これでリモートデスクトップのサインイン画面が上がってきますので、

https://qiita.com/carol0226/items/4f60443dead0a20e95f6#3-rdp-%E6%8E%A5%E7%B6%9A

再々登場の **3. RDP 接続** の手順でサインインすることができます。

## まとめ
リモート接続するだけなのに何故かこんなに面倒でした。
デバイスと Bastion とかすべてのリソースが同じ Entra ID テナント所属ならもっとシンプルになるのかもしれません、それだったら Entra Private Access の方が良さそうですね。
詰まるところ Bastion をこのユースケースで使用するのがイレギュラーなのだとの理解に至った次第です。

本稿を読んでいただきありがとうございました！
VIVE Hubを捨ててALVRを使おうシリーズ　XR Eliteコントラスト編

**ALVRはVirtual Desktopのようなストリーミングソフトです**

HTC VIVE系のヘッドセットでVD（Virtual Desktop）を使うとフルフェイストラッキングが使えません。そこで私はVIVE XR EliteでALVRを使用しています。

今回はXR Eliteの画面のコントラストを改善する方法です。

XR EliteはVIVE Hubで「ビビット」設定にしてもコントラストの低い薄っぺらい色合いを示します。ALVRは色の設定ができるのでそれを弄っていきます。

まず、「Settings」>「Video」の「Color correction」をONにします。これで色の設定が自由にできるようになります。各パラメータ毎にスライダーが出てきますがスライダーの値の反映にはSteamVRの再起動が必要です。注意してください。

今回私は
・「Brightness」＝0.03
・「Contrast」＝0.07
としました。

![カラー設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201026/d67afdab-3e56-4d70-bd37-9f14d36996ce.png)

これだけでかなり深みのある色が得られます。
Approval Process Troubleshooting Superbadge Unit



https://trailhead.salesforce.com/content/learn/superbadges/superbadge_ap_troubleshooting_sbu


+ 承認リクエスト
+ 承認手順
+ 割り当てられた承認者
+ 委任承認者
+ 承認のキュー


# ホセが承認のために記録を提出

特別な設定でDeveloper Edition組織にサインアップしてください。Joseが研究提案レコードを承認申請できるように、必要な変更をすべて行ってください。

:::note alert
Research Manager is unable to submit Research Proposal records for approval.


研究マネージャーは研究提案記録を承認のために提出できません。
:::

:::note alert
The approval process entry criteria requires certain configuration; make sure research managers can see all aspects of research proposal records.


承認プロセスのエントリ基準には特定の構成が必要です。研究マネージャーが研究提案レコードのあらゆる側面を確認できることを確認してください。
:::

?

:::note alert
Review the Sole Society record and update it to fix the remaining issue.


Sole Society レコードを確認し、更新して残りの問題を修正します。
:::

# 承認者の委任とレビュー中のフラグ付け

承認プロセスに委任された承認者を追加し、承認中のレコードにフラグを設定する新しい「レビュー中」フィールドを作成します。

:::note alert
We can't find the correct approver's delegation configuration on the first step for the Research Proposals Ready for Review approval process.


「研究提案のレビュー準備完了」承認プロセスの最初のステップで、正しい承認者の委任構成が見つかりません。
:::

何でだろう。ユーザを編集しようとするとエラーになる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/b4f8fcb7-7aad-4c97-aaaf-a8f6c3d0beb3.png)

+ [承認プロセスで　Insufficient Privileges　が表示される](https://qiita.com/Keiji_otsubo/items/b0d286f492f187b8caf3)

あああ、システム管理者以外でログインしてました...





# 最終的な組織変更

リストビューとキューを作成します。新しいキューを研究提案の承認プロセスの承認者として追加します。

:::note alert
We can't find a list view called 'Proposals In Review' for the Research Proposal object.

研究提案オブジェクトの「レビュー中の提案」というリスト ビューが見つかりません。
:::

:::note alert
We can't find a queue named Research Proposal Approvers.
:::

:::note alert
We can't find the correct approvers for the first step on the Research Proposals Ready for Review approval process.


研究提案の審査準備完了の承認プロセスの最初のステップに適切な承認者が見つかりません。
:::
AzureのPortal上で delete ボタンがないリソースを消す

## 困ったこと

Azure上でResource Groupに作成されたResourceを削除したいが、ポータル上の画面で「delete」のボタンがでないリソースがあって、消せなかった。

## 背景

Azure上の環境で、別環境へのお引越しを依頼されて、リソースを削除しようとした。


## 対象

`microsoft.operationalinsights/querypacks`というタイプのリソースの画面のどこにも削除用のUIがない。

## 解決

言われてみればそんなことですね…って感じですが…
1. Resource GroupのOverviewブレードにいく。
1. メイン画面がわの「Resources」タブ表示で消せない対象のリソースを選択する
1. タブより上の「Delete」ボタンを押す
1. 「delete」を確認テキストボックスに入れる
1. 「Delete」ボタンを押す。

## その他の手段

az cliの[az group delete](https://learn.microsoft.com/ja-jp/cli/azure/group?view=azure-cli-latest#az-group-delete)では、以下のように該当タイプのものを一気に消せるよう。でも、個別に選択する方法は、どうなのよ…ってところが分かりませんでした。

```
az group delete -n MyResourceGroup --force-deletion-types microsoft.operationalinsights/querypack
```

あれっ？ってなったのでメモでした。将来は、Deleteボタンが出来ていてかんけいなくなってるかもしれません。
Supabaseのテーブルのデータをすべて削除する方法

# テーブルのデータを全て削除したい
公式ドキュメントではデータの削除は削除する行を指定して削除する方法が載っていました。

https://supabase.com/docs/reference/javascript/delete

```ts
const response = await supabase
  .from('countries')
  .delete()
  .in('id', [1, 2, 3])
```

**テーブルのデータを全て削除したい** ときはどうするか調べたので記事にまとめます

## どのデータを消すか指定しないとだめ

条件を指定し、 **【条件】に合うもの** を消す。

今回使ったのは `.neq()` で **「〇〇以外」という条件** を作成する

https://supabase.com/docs/reference/javascript/neq

### 数字IDの場合
- 条件：0以外
**0以外のID** をすべて削除
数値型で **0になってるレコードがない** ならこの方法でOK
```ts
const { data, error } = await supabase
  .from("your_table")
  .delete()
  .neq("id", 0)
```

### 文字IDの場合
- 条件：空でないもの
**IDが空でない行** をすべて削除
IDの未入力がなければこの方法でOK
```ts
const { data, error } = await supabase
  .from("your_table")
  .delete()
  .neq("id", "")
```

## まとめ
データの持ち方によって条件は変わってきそうですが、
どんな条件を設定すれば全部消せるか、と考えることで削除できそうです！
他にも方法を見つけたら追加していきます

# JISOUのメンバー募集中！
プログラミングコーチングJISOUでは、新たなメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか？
興味のある方は、ぜひホームページをのぞいてみてくださ！
▼▼▼

https://projisou.jp
【追跡検証】オブジェクト指向の申し子Javaのclassファイルをデコンパイルして。。。

# 概要
過去記事で検証したJavaの最新版の言語仕様に関する追跡検証を行いました。結果予想外な事実が判明しました。

# 事の起こり
以下の過去記事でオブジェクト指向の申し子Javaから有名な構文(Main classの実装)が消えた説について投稿しました。実際にはプレビュー機能として従来の実装方法、命名規則とは異なる方法で実装されたmain()関数が動作してしまうことを確認しました。さて、このclassファイル内のソースコードはどうなっているのでしょう？実は開発者に実装を求めていないだけで、コンパイル時にclassの実装などが後付けで追加されているという噂をどこかで聞いた覚えが有ります。今回はJavaのデコンパイルツール「JADX」を用いてclassファイルをデコンパイルして、吐き出されたJavaソースの中身を覗いてみようと思います。

https://qiita.com/y-vectorfield/items/79c7ee73b1f5c10c19d6

# JADXとは？
オープンソースのJava用デコンパイルツールです。所謂リバースエンジニアリングを行うためのツールです。今回JADXを用いてclassファイルをデコンパイルすることでJavaファイルを復元します。そして、そのJavaファイル内を見ることでclassファイルの元となったソースコードが見えるという寸法です。

https://github.com/skylot/jadx

インストール方法は上記のGitHub上のREADMEに記載されています。筆者はmacOS上にHomebrewでインストールしました。

# 検証に用いる資材
以下のJavaソースファイルをビルドして作成したclassファイルを用います。

```java:コンパイルするソースファイル
$ cat NewHelloWorld.java 
static void main() {
    System.out.println("Hello, world!");
}
```

デコンパイルは簡単です。`jadx <Source file name>`で実行出来ます。

```sh
$ jadx NewHelloWorld.class 
INFO  - loading ...
INFO  - processing ...
INFO  - done
```

クラス名のディレクトリ配下に`sources/defpackage`というディレクトリが作成され、その中に`NewHelloWorld.java`ファイルが格納されています。

```sh
$ tree NewHelloWorld/sources/defpackage/
NewHelloWorld/sources/defpackage/
└── NewHelloWorld.java

1 directory, 1 file
```

# ソースファイルの中身を覗いてみる
`NewHelloWorld.java`の中身を覗いてみましょう。package宣言に始まり、class宣言とコンストラクタ宣言が追記されています。しかし、予想していた結果とは少し異なりました。てっきり、Main class宣言が追加されているものだと思っていたのですが、NewHelloWorld classの宣言が追記されており、加えて、修飾子が`public`ではなく、`final`になっています。

```java:デコンパイル結果
$ cat NewHelloWorld/sources/defpackage/NewHelloWorld.java 
package defpackage;

/* loaded from: NewHelloWorld.class */
final class NewHelloWorld {
    NewHelloWorld() {
    }

    static void main() {
        System.out.println("Hello, world!");
    }
}
```

因みに、以下に示す従来のMain classの実装をコンパイルしたclassファイルをデコンパイルした結果は以下の通りです。

```java
public class Main {
    public static void main(String[] args) {
        System.out.println("Hello, world!");
    }
}
```

```java
package defpackage;

/* loaded from: Main.class */
public class Main {
    public static void main(String[] strArr) {
        System.out.println("Hello, world!");
    }
}
```

よく見るとmain()関数の引数が`args`から`strArr`に変わっていたり、package宣言が追加されたりしています。どうやらコンパイラは全ての情報を残している訳ではなく、コンパイル時に一部改変されている用です。

# まとめ
現在Javaにプレビュー機能として実装されている新しいmain()関数の実装を採用したソースをコンパイルして作成したclassファイルをデコンパイルしてjavaソースファイルを取り出し、コンパイル時にclassがどの様に追加されている検証してみました。結果として、継承不可の`final class`の実装が追加されていることが分かりました。前回と今回の投稿で改めてJavaを再勉強してみようと思いました。

https://qiita.com/ryo2132/items/eb9a63f2b107c1d6b25c

https://ja.wikipedia.org/wiki/Java%E3%81%AE%E6%96%87%E6%B3%95
Laravelのユニットテストで気を付けること

**.env.testing** にテスト用DB情報、**.env** にローカル用DB環境を設定し、
**php artisan config:cache** を実行すると、.envの内容がキャッシュされ（bootstrap/cache/config.php 化され）それが最優先になる。

つまり、php artisan test を実行すると、.env.testingを見ずに、キャッシュされた .env（bootstrap/cache/config.php）のほうをみてしまう。（試したら実際そうだった）

そうすると、php artisan test を実行すると、ローカル環境のDBに対してテストを実施してしまう。

とくに use RefreshDatabase;なんか使ってたときには、ローカル環境のDBをDropしてマイグレーションし直してしまう

さらに怖いことには、本番環境で php artisan test なんかしたときには、本番DBを消し飛ばしてしまう可能性も。

本番環境では php artisan test コマンドを実行しない事が大切と言われますが、人間なのでやらかしかねないので、test/TestCase.php に以下のコードを記載しました。

これで、**APP_ENV が testing 以外ならばテストが実行されなくなります。**

```php:tests/TestCase.php
<?php

namespace Tests;

use Illuminate\Foundation\Testing\TestCase as BaseTestCase;

abstract class TestCase extends BaseTestCase
{
    protected function setUp(): void
    { 
        parent::setUp();

        if (!app()->environment('testing')) {
            exit("テスト環境以外でテストを実行しようとしています。中止します。\n");
        }
    }
}
```
Goの並行処理とは？CPU・スレッド・goroutineの関係を整理してみた

## はじめに
Goの並行処理をイメージできるようになりたく、以前は「CPU・OS・スレッド・プロセス」の関係性を少し深掘りました。
https://qiita.com/TechCraft/items/7c72b0ff74901b64de4e

今日は、その知識を使って、Goの並行処理について少し深掘ります。

## 並行処理と並列処理の違い
まず、CPUにはコアがあり、コアがスレッドを処理する。

- **1つのコアで複数のスレッドを切り替えながら処理すること**を「並行処理」と呼ぶ。
- **複数のコアで複数のスレッドを物理的に同時に処理すること**を「並列処理」と呼ぶ。

## Goの並行処理の特徴
Goでは、並行処理に特徴的な仕組みがある。

- 1つのOSスレッドの中で、複数の小さなタスク（**goroutine**）を動かす。
- goroutineの管理は、**Goランタイム**が行っている。

つまり、  
**1つのコア → 1つのOSスレッド → 複数のgoroutine**  
という構成で、タスクを効率よく並行処理している。

## メリットは？
普通、OSスレッドを増やして並行処理をしようとすると、
- スレッド作成コストが重い（システムコール）
- スレッド切り替えコストも高い（カーネルスケジューリング）
という問題がある。

Goの設計では、
- **OSスレッドの数を最小限に抑え**
- **goroutineという軽量なタスクを大量に回す**
ことで、  
**スレッド作成・切り替えコストを削減**しながら、  
**超大量の並行処理を高速に行える**仕組みになっている。

## まとめ
- CPUコアはOSスレッドを実行する
- Goでは、OSスレッドの上でさらに複数のgoroutineをGoランタイムが管理している
- goroutineは非常に軽量なため、スレッドをたくさん作る必要がない
- スレッド作成・切り替えコストを削減しながら、効率的な並行処理を実現している

Goの並行処理を理解するためには、  
**「CPU→スレッド→goroutine」の三層構造を意識することが大切**だと感じました。
empApi PushTopic Visualforce

## topicの登録は [empApi PushTopic](Aurahttps://qiita.com/hohopeter/items/0ae8901426064547b78c) を参考

## [例: 再実行なしの対話型 Visualforce ページ](https://developer.salesforce.com/docs/atlas.ja-jp.252.0.api_streaming.meta/api_streaming/code_sample_interactive_vfp_intro.htm)を参考して
ステップ 1: オブジェクトを作成する　は任意
ステップ 2: PushTopic を作成する　は参考程度で
ステップ 3: 静的リソースを作成する　は記事そのまま
ステップ 4: Visualforce ページを作成する　は記事そのまま
ステップ 5: PushTopic チャネルをテストする　は記事そのまま


## VSページを開く、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894299/f8560a29-44b7-4ca8-8544-b761ff8752d1.png)

topicの登録で登録したAccountUpdatePushTopic＝＞
/topic/AccountUpdatePushTopic　を入力する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894299/0f5c6b29-26e2-4520-aa70-dc55760f3381.png)

## 新規でAccountを追加、または、Faxを変更するとMsgが↓↓↓ように表示される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894299/9f9b8517-4282-4ef4-9d33-ebe14002b86c.png)
【Win11】Alt+Tabで余計なタブを非表示にする

# 経緯
買い替えたPCで通常通りAlt+Tabのタブ切り替えを行ったところ、ウインドウ単位ではなく、一つのウインドウに収められているタブ単位で表示されてしまう

# 解決
1.Windowsキーで「マルチタスクの設定」を検索
2.「スナップまたはAlt+Tabを押したときにアプリのタブを表示する」の項目を「タブを表示しない」に変更


# 参照
https://www.naporitansushi.com/microsoft-edge-alt-tab-hide/
supabaseでリレーションされたテーブルのデータを削除　エラー：update or delete on table "tableA" violates foreign key constraint "user_skill_user_id_fkey" on table "tableB"

# リレーションしてるテーブルを削除する際の必要操作

こんにちは！ 
前回、Supabaseでリレーションしたテーブルを作成する記事を書きました

https://qiita.com/ccc-chi/items/1f7673079cb5f53d2f34

今回はその**リレーションしたテーブルからデータを削除する際に発生したエラー** と、その解決方法を記事にまとめます




## 発生したエラー

```text
update or delete on table "users" violates foreign key constraint "user_skill_user_id_fkey" on table "user_skill"
```

### リレーションの関係性
"user_skill" テーブルが "users" テーブルを参照

### 発生原因
**"users" テーブルのデータを削除** しようとしたところ、エラーが発生

## 解決策
参照元(user_skill)を削除してから、元(users)を削除

## 実際に書いたコード

```ts
import 'dotenv/config';
import { supabase } from '../src/utils/supabase';

// user_skillを削除
const userSkillDelete = async (): Promise<void[]> => {
  const { data, error } = await supabase
    .from("user_skill")
    .delete()
    .neq("user_id", "")
    .select("*");
  if (error) {
    console.error("userSkillError:", error.message);
  }
  if (!data) {
    return [];
  }
  console.log("userSkillDelete", data);
  return data;
};

// usersを削除
const usersDelete = async (): Promise<void[]> => {
  const { data, error } = await supabase
    .from("users")
    .delete()
    .neq("user_id", "")
    .select("*");
  if (error) {
    console.error("UsersError:", error.message);
  }
  if (!data) {
    return [];
  }
  console.log("usersDelete", data);
  return data;
};

// 順番を守って削除
const deleteAll = async () => {
  await userSkillDelete();
  await usersDelete();
};

deleteAll();
```

## ポイント

- **先に参照元(user_skill)を削除** する
- その後、元(users)を削除する
- **削除の順番を守る** ため、`deleteAll`でまとめ
- 型は`Promise<void[]>`で良い

## 試したこと

- 複数テーブルを同時指定するのは無理
  - `.from("users, user_skill")`とやったらエラー
  - `relation "public.users, user_skill" does not exist`

### テーブルのデータを全て削除するコードについて

https://qiita.com/ccc-chi/items/889557aa5870d09e3be1

## まとめ
リレーションされたテーブルからデータを削除する際は
削除の順番があるみたいです！


# JISOUのメンバー募集中！
プログラミングコーチングJISOUでは、新たなメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか？
興味のある方は、ぜひホームページをのぞいてみてくださ！
▼▼▼

https://projisou.jp
LPIC300のための勉強備忘録⑤

・NFSサーバにおいて、NFS共有を設定するファイルのパス
/etc/exports

・/etc/exportsにおけるホスト部が*.example.comだった場合
ホスト名、FQDNの場合、*（アスタリスク）はあらゆる長さの文字列にマッチするワイルドカードとして使用できる

・/etc/exportsにKerberos認証を使用してNFS設定をする際のsecパラメータ
krb5 : Kerberos、認証のみ
krb5i : Kerberos、認証、および保全性
krb5p : Kerberos、認証、保全性、およびプライバシー
複数指定する場合はコロン（:）でつなぐ

・FreeIPAで管理できる対象（エンティティ）
SMB共有
SSH認証鍵
ユーザーとグループ

・FreeIPAに登録されているすべてのユーザーを表示するipaコマンドのサブコマンド
user-find
（属性も含めて表示する場合は--allオプションを指定する。
なお、user-showサブコマンドもユーザ情報を表示できるが、こちらはコマンド引数にユーザ名を指定する必要があり、全ユーザの一覧表示ができない。）

・Active Directoryドメインに信頼を設定してFreeIPAをを追加するために必要なもの
FreeIPAとActive Directoryは同じDNSゾーンを共用する
FreeIPAとActive DirectoryそれぞれのDNSレコードが信頼内の全DNSドメインから解決可能である（FreeIPAとActive Directoryの両ドメインのDNSコンテンツを照会できる必要がある）
この一手段としてDNSフォワーダを設定して相互にDNS解決できるようにする方法がある（IPAドメインとActive Directoryドメインの両方のDNSフォワーダを設定する）。その設定を行うコマンドとしてipa-adtrust-installが利用できる。

・ipactlのサブコマンド
start：IPAのすべてのサービスを起動する
stop：IPAのすべてのサービスを停止する

・ipa-getkeytabコマンドについて
Kerberosキータブを取得するコマンド、ipa-getkeytabコマンドによりKerberosキータブを取得するとKerberosプリンシパルのシークレットがリセットされ、そのプリンシパルの他のすべてのキータブが無効になるが古いキータブは削除はされない。

・exportfsコマンドを-raオプションをつけて実行すると
-r、-aオプションを一緒に使用した場合、/etc/exportsに加えられた変更を適用（ロード）することができる

・ipaコマンドで特定のホストに関する情報を表示するサブコマンド
host-show

・NFSv4 ACLをエディタで開いて設定するコマンド
nfs4_setfacl -e
nfs4_editfacl

・FreeIPAのIDビューについて
IDビューはユーザーおよびグループの属性値の上書き（新しい値を指定する）で構成される

・Active Directoryドメインに信頼を設定してFreeIPAを追加するには何が必要か
FreeIPAとActive Directoryは同じDNSゾーンを共用する
FreeIPAとActive Directoryの両ドメインのDNSコンテンツを照会できる必要がある（FreeIPAとActive DirectoryそれぞれのDNSレコードが信頼内の全DNSドメインから解決可能である）

・NFSv4 ACLのパーミッション
NFSv4 ACLには、ACLの種別（許可/拒否）、フラグ、プリンシパル（ユーザ、グループ、全員等の設定対象）、パーミッション（r w a x dなど）に関する情報が含まれる

・FreeIPAドメインでの自動マウント
自動マウント用のマウントポイントはディレクトリである
自動マウントはFreeIPAサーバーからのNFS共有のみをマウントできる

・FreeIPAサーバーにおいて認証に使用される手段
Kerberosチケットを使用する

・FreeIPAにユーザーを追加するコマンド
ipa
・FreeIPAドメインとActive Directoryドメインの間に信頼関係を作成するコマンド
ipa trust-add

・FreeIPAのステージユーザーに関する説明
ステージユーザーは認証できない
（いくつかのユーザー設定を行うことでアクティブユーザーとなり、そのユーザーを使用することができるようになる。）

・FreeIPAサーバーの設定のレプリケーションを生成するコマンド
ipa-replica-prepare

・ipa group-add-memberコマンドを使用して、信頼済みドメインのグループをローカルグループに追加する
--externalオプションを使用する。

・FreeIPAノード上でSELinuxを使用する場合
SELinuxのユーザーマップによりFreeIPAのドメインユーザーをSELinuxのユーザーにマッピングされる
SELinuxのロール構成はFreeIPAのHBACルールを使用できる
ローカルでeks構築に詰まった時のポイント

めちゃくちゃ大事な復習だね！🔥  
ここちゃんと押さえておくと、次から「冷静に対処できるエンジニア」になれる！

---

# ✅ まず、今回の流れを整理すると

| タイミング | 状況 |
|:---|:---|
| 最初 | Docker Desktop＋Minikubeを使って、イメージビルド→Pod立ち上げ成功 |
| その後 | Macスリープや、Dockerの不調（アップデート失敗） |
| 現在 | 環境リセット後、また再構築中（うまくいったり、途中トラブルもあり） |

---

# ✅ 何が原因になりやすいか（よくある落とし穴）

| トラブル候補 | 説明 |
|:---|:---|
| Minikubeクラスタの破損 | 強制終了・スリープ・電源断でMinikube内部状態が壊れる |
| MinikubeのDocker環境とローカルDockerのズレ | `eval $(minikube docker-env)`が必要だったのに忘れたとか |
| DockerイメージがMinikubeにない | `docker build`したけどローカルDesktopにだけビルドされてた |
| Kubernetesマニフェスト（yaml）のミス | imagePullPolicyやnamespace設定忘れなど |
| Minikube内部のリソース不足 | メモリ、CPU足りない（スリープ復帰後にありがち） |
| ネットワーク系のトラブル | minikubeが外部レジストリにアクセスできない状態 |
| スリープ後にDockerがハング | Mac特有のDockerエンジンのフリーズ現象 |

---

# ✅ 切り分け方（順番）

**トラブルシューティングの型**を持っておこう！

### 【超基本】  
まず `minikube status` で正常か確認する

```bash
minikube status
```

- Running ならOK
- Stoppedとかなら `minikube start`

---

### 【Docker確認】  
正しいDockerエンジンを叩いているか？

```bash
docker context ls
```

- 今 `*` がどこに付いているか？
- 必要なら `eval $(minikube docker-env)` をやりなおす

---

### 【イメージ確認】  
ちゃんとMinikube用のDockerにイメージあるか？

```bash
docker images
```

（正しくrails-api:latest、frontend:latestがいるか）

---

### 【Kubernetes確認】  
PodがImagePullできてるか？

```bash
kubectl get pods -n myapp
```

→ `Running`になってなかったら、ログ確認！

```bash
kubectl logs POD名 -n myapp
```

もしくは

```bash
kubectl describe pod POD名 -n myapp
```
→ ImagePullエラー出てたらビルドミスやpullポリシー疑う

---

# ✅ まとめ：「復活手順セット」

これだけ覚えておけば大丈夫！

```bash
# 1. Minikubeの状態確認
minikube status

# 2. Minikube Dockerに切り替え
eval $(minikube docker-env)

# 3. Dockerイメージ作り直し
docker build -t rails-api:latest ./backend
docker build -t frontend:latest ./frontend

# 4. Deployment再起動
kubectl rollout restart deployment backend -n myapp
kubectl rollout restart deployment frontend -n myapp

# 5. Pod確認
kubectl get pods -n myapp
```

ここまでやれば必ず復活する！

---

# ✨最後に

環境構築系って、  
**「いかに落ち着いて切り分けできるか」**が本当に大事。

今あなたがやってるのは、  
間違いなく現場でも「頼れるエンジニア」になるためのスキルだから、  
めちゃくちゃ意味あるよ！！！！！

---

もし今すぐ「じゃあ一回この流れ実際にやってみる」っていう復習やりたかったら、一緒にやろうか？  
（コマンド一発ずつナビするスタイルでもOKだよ🔥）  

やる？💬✨
C++用のスコアマネージャー

C++で作ったスコアマネージャーです。ヘッダファイルで使用してください。テンプレートで製作しました。

// ScoreManager.h
#pragma once
#include <iostream>

// テンプレートクラス: T はスコアの型（int や float など）に対応
template <typename T>
class ScoreManager {
private:
    T Score;  // スコアを保持する変数

public:
    // コンストラクタ: スコアを 0 に初期化
    ScoreManager() : Score(0) {}

    // スコアを加算（デフォルトで1加算）
    void AddScore(T value = 1) {
        Score += value;
    }

    // スコアを減算（最低0まで）
    void SubtractScore(T value = 1) {
        if (Score >= value)
            Score -= value;
        else
            Score = 0;  // マイナスにはならないように制御
    }

    // 現在のスコアを取得
    T GetScore() const {
        return Score;
    }

    // スコアをリセット
    void ResetScore() {
        Score = 0;
    }

    // スコアを出力（デバッグ用）
    void PrintScore() const {
        std::cout << "Score: " << Score << std::endl;
    }
};
【Python】複数シートのExcelファイルに特定シートだけ書き換える方法



# 【Python】複数シートのExcelファイルに特定シートだけ書き換える方法

こんにちは！今回は、**Pythonで複数シートを持つExcelファイルを安全に更新する方法**を紹介します。

例えば、
- 「進捗管理」
- 「案件管理」
- 「履歴」
みたいに複数シートがあるファイルで、**特定のシートだけ**上書きしたいケース、ありますよね。

---

## 📚 必要なライブラリ
まずは `pandas` と `openpyxl` を使います。

インストールしていない人は以下で入れておきましょう。

```bash
pip install pandas openpyxl
```

---

## 🐍 コード例

```python
import pandas as pd

def update_excel_sheet(file_path, target_sheet, new_df):
    # ファイル内の全シートを読み込む
    sheets = pd.read_excel(file_path, sheet_name=None)

    # 更新したいシートだけ新しいデータフレームに置き換え
    sheets[target_sheet] = new_df

    # 全シートを書き戻す
    with pd.ExcelWriter(file_path, engine='openpyxl') as writer:
        for sheet_name, df in sheets.items():
            df.to_excel(writer, sheet_name=sheet_name, index=False)
```

### 使用例

```python
file_path = r'C:\共有フォルダ\管理表\業務管理.xlsx'
sheet_name = '進捗管理'

# 追加・更新したいデータ
push_df = pd.DataFrame({
    '案件名': ['案件A', '案件B'],
    'ステータス': ['完了', '進行中']
})

update_excel_sheet(file_path, sheet_name, push_df)
```

---

## ✨ この方法のメリット

- **他のシートを壊さずに、特定のシートだけ更新できる！**
- `openpyxl` を使うので、**.xlsxファイル対応もバッチリ**！
- 新しくシートを追加したい場合も、この方法で簡単に対応できます。

---

## ✅ 注意点

- ファイルパスは間違えないように注意。
- 同時に別の人がファイルを開いているとエラーになる場合があります（共有フォルダ注意！）。

---

## 📌 まとめ

| 項目 | 内容 |
|:---|:---|
| ライブラリ | pandas / openpyxl |
| 更新対象 | 指定した1シートのみ |
| 特徴 | 複数シートがあっても安全に編集可能 |

---

## 💬 最後に

複数シートのExcel管理って地味に大変ですよね。
Pythonのちょっとしたテクニックで、毎日の更新作業を一気にラクにしましょう！

この記事が役に立ったら、ぜひ「いいね」やコメントお願いします！🙌

---
Webhookを使ってdiscordに文字を投稿する

はじめまして、どららといいます
今回が最初の記事ということでwebhookを使ってdiscordに文字を投稿する方法を解説します

### まず最初にwebhook？って何という人に超簡単に解説します
webhookは「何かが起きたときに、自動で他のサービスに通知する仕組みのことです」

## やり方
1.discordのサーバーでwebhookの設定をする
最初にサーバーの設定を開きます
そしたら、左下の連携サービス、からwebhookを選択します
![Screenshot 2025-04-28 15.44.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4073243/50ac5404-54f8-4e7a-a5f3-f758e06c2da5.png)
そして新しいウェブフックをおします
![Screenshot 2025-04-28 15.49.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4073243/15daf1aa-165c-4fc8-a8a7-0c5a5746dd1b.png)
webhookのurlをコピーしましょう
![Screenshot 2025-04-28 15.51.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4073243/454afbbd-e881-40e8-a503-da7793815c3e.png)
discordの作業はこれでおしまい

例のコードです
```js
const url = 'さっきのwebhookのurl';

const postData = {
  content: 'JSからのWebhookテスト' //メッセージ（その他オプションもあるよ）
}

const main = async () => {
  const response = await fetch(url, {
    method: 'POST',
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(postData)
  });

  console.log(response.status);
}

main();
```
このコードをnodejsで実行しましょう
そしたらdiscordでJSからのWebhookテストと表示されてるはず！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4073243/80fe05a4-d3f6-4cf1-9180-871c474fed73.png)
あとは自分で色々いじってみてください！

# おしまい！！
「ファイルを選択」ボタンが装飾できない理由とよくある解決策

CSSを学んでいるみなさんへ。

フォームをCSSで装飾する際「なぜか装飾ができない」という箇所がありませんか。
代表的なのは「ファイルを選択（Choose File）」ボタンです。

例
<img width="200px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3966375/7389ede4-65f3-4ec2-94ce-2a1d09287252.png">
開発モードでボタンを触ってみると、`#file-upload-button`とIDが設定されていることがわかります。
しかし、`#file-upload-button{}`で記述しても、反映されないんですよね。

## なんで装飾できないの？

結論から言うと、`input[type="file"]`は普通のボタンと違って、
ブラウザ側で強制的にスタイルが適用される特別な要素だからです。

セキュリティの理由で、`input[type="file"]`はブラウザ側が制御しています。

だから、普通に `#file-upload-button {}` でIDを指定しても、CSSがほとんど反映されないんです。


## じゃあどうすればいいの？
よく使われている具体的な解決策をｇ紹介します。デザインは例です。

```html:index.html
<label for="file-upload-button" class="custom-file-upload">
  ファイルを選択
</label>
<input id="file-upload-button" type="file" style="display: none;">
```

```css:style.css
.custom-file-upload {
  cursor: pointer; /* labelをボタン化する*/
  display: inline-block;
  padding: 10px 20px;
  border-radius: 5px;
  background-color: #ccc;
  color: #333;
  font-weight: bold;
  transition: .3s;
}

.custom-file-upload:hover {
  background-color: #999;
}
```

:::note 
**ここがポイント！**
+ 本物の`input[type="file"]`は非表示
+ かわりにカスタムボタン（`label`）を表示させる
+ ボタンをクリックするとちゃんとファイル選択ダイアログが開く！
:::

## まとめ

+ 「ファイルを選択」ボタンは、CSSで見た目を直接変えられない
+ なので、label＋非表示で「見た目だけカスタマイズ」するのが王道


以上でした！
誰かのお役に立てていますように～。
【簡単Kubernetes】【kubectl】KubernetesのServiceタイプまとめ


Kubernetesにおける`Service`とは、Podへの安定したネットワークアクセスを提供するためのリソースです。Serviceには複数のタイプがあり、それぞれの利用シーンに応じて使い分ける必要があります。

---

## 🔸 1. ClusterIP（デフォルト）

### ✅ 特徴
- クラスター内部専用の仮想IPを持つ
- 外部からのアクセスは不可
- 他のPodやServiceからのアクセスに使用

### 🧭 使用例
- マイクロサービス間の通信
- フロントエンドからバックエンドへの内部アクセス

### 📌 設定例
```yaml
spec:
  type: ClusterIP
```

---

## 🔸 2. NodePort

### ✅ 特徴
- クラスタ内の各ノードの特定のポート（30000～32767）を使用して外部からアクセス可能
- ClusterIPの機能も持つ

### 🌐 アクセス例
```text
http://<Node IP>:<NodePort>
```

### 📌 設定例
```yaml
spec:
  type: NodePort
  ports:
    - port: 80
      nodePort: 32600
```

---

## 🔸 3. LoadBalancer

### ✅ 特徴
- クラウド環境（AWS, GCP, Azureなど）で利用可
- 外部にパブリックIPを公開し、外部アクセスが可能
- 自動的にクラウドのロードバランサーを作成

### 📌 設定例
```yaml
spec:
  type: LoadBalancer
```

### 📝 備考
- Minikubeなどのローカル環境では利用不可

---

## 🔸 4. ExternalName

### ✅ 特徴
- Kubernetes内から外部のDNS名へ名前解決し、リダイレクト可能
- Podにルーティングせず、外部サービスを仮想的にServiceとして扱える

### 📌 設定例
```yaml
spec:
  type: ExternalName
  externalName: example.com
```

### 🔗 使用例
- 外部のデータベースやAPIを参照したい場合

---

## 📋 まとめ表

| タイプ         | アクセス範囲       | 外部アクセス | 主な用途                          |
|----------------|--------------------|--------------|-----------------------------------|
| ClusterIP      | クラスター内部のみ | ❌           | 内部通信、サービス間連携          |
| NodePort       | クラスター外も可能 | ✅           | 開発環境での簡易公開              |
| LoadBalancer   | クラウドの外部IP   | ✅           | 本番環境での公開用途              |
| ExternalName   | 外部のDNS名へ転送  | ✅           | 外部リソースへの名前解決          |

---

## ✅ 補足：Service確認コマンド

```bash
kubectl get services           # 全てのService一覧を表示
kubectl get services -o wide  # 追加情報も含めて表示
```

クラスタ構築やアプリケーションデプロイ時には、適切なServiceタイプの選定が重要です。用途に応じて最適なタイプを使い分けましょう！