OmniAICreator/Qiita-1.07M huggingface dataset:
VPCエンドポイントとNAT Gatewayの本気コスト＆セキュリティ対決

ネット上には「VPCエンドポイント vs NAT Gateway」に関する記事が多数存在しています。「NAT Gatewayは古い技術、VPCエンドポイントは新しい技術で安全性が高い」といった意見も見受けられます。
本記事では、eコマースプラットフォームを想定した具体的な構成例をもとに、コスト・セキュリティ・運用の観点から両者を徹底比較します。

# 1. アプリケーション概要
今回想定するのは、以下のような機能を持つ大規模eコマースプラットフォームです。
1. 商品カタログ：S3（画像）
1. 商品情報: DynamoDB
1. ログ管理・分析：CloudWatch
1. システム監視・メンテナンス：Systems Manager
1. 注文処理：SQS
1. プッシュ通知：SNS
1. ユーザー認証・管理：Secrets Manager

# 2. VPCエンドポイント方式
## 概要
- Private SubnetのEC2 → VPCエンドポイント（Gateway型/Interface型） → AWSサービス
- S3/DynamoDBはGateway型（無料）
- その他はInterface型（有料）
- 通信は完全にAWS内部ネットワークで完結、パブリックIP不要

## 必要なVPCエンドポイント数（例）
- S3（Gateway）：1
- DynamoDB（Gateway）：1
- CloudWatch（logs, monitoring）：2
- Systems Manager（ssm, ssmmessages, ec2messages）：3
- SQS：1
- SNS：1
- Secrets Manager：1
- 合計：10個（うち2つはGateway型）

## コスト（東京リージョン例）
- Interfaceエンドポイント：8 × $0.014/時 × 730時間 ≒ $81.76/月
- データ処理料金：$0.01/GB
- Gateway型（S3/DynamoDB）：無料

## メリット
- 通信がAWS内部で完結し、セキュリティが高い
- IAMリソースポリシーやエンドポイントポリシーで細かなアクセス制御が可能
- セキュリティグループ適用可（Interface型）

## デメリット
- サービスごとにエンドポイントを作成する必要があり、数が増えるとコスト増
- PrivateLink未対応サービスには利用不可


# 3. NAT Gateway方式
## 概要
- Private SubnetのEC2 → NAT Gateway（パブリックサブネット/EIP付き） → AWSサービスのパブリックエンドポイント
- NAT GatewayはElastic IP（EIP）が必須
- 通信はAWSグローバルネットワーク内で完結（<font color="red">インターネット経由ではないが、NAT GatewayのパブリックIPを利用</red>）

## コスト（東京リージョン例）
- 利用料金：$0.062/時 × 730時間 ≒ $45.26/月
- データ処理料金：$0.062/GB
- EIP料金：通常はNAT Gatewayに割り当てている間は無料

## メリット
- 初期構築がシンプル
- どんなAWSサービスや外部SaaSにもアクセス可能

## デメリット
- データ転送量が増えるとコスト高
- セキュリティグループやNACLによる制御のみ
- IAMやリソースポリシーによる細粒度制御不可


## コスト比較まとめ
| 方式 | 時間料金/月 | データ転送料金 |主な特徴|
|------------|--------------|-------------|-------------|
|NAT Gateway|	$45.26|	$0.062/GB|	初期費用安、転送量多で高額化|
|VPCエンドポイント|	$81.76|	$0.01/GB|セキュリティ高、細粒度制御可|

# 4. セキュリティ比較
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28664/abd25c3a-1041-4f21-83bb-c6fb29e4d99a.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28664/beaa69ad-1721-4f96-baa3-b1dbab2b91a6.png)
##  NAT Gateway
- パブリックIP（EIP）経由だが、通信はAWS内部ネットワークで完結
- IAMやエンドポイントポリシーによる細粒度制御不可
- セキュリティグループ/NACLでの制御のみ
## VPCエンドポイント
- パブリックIP不要、完全プライベート通信
- IAMポリシーやエンドポイントポリシーでサービス単位のアクセス制御
- 監査証跡やゼロトラスト設計にも有利

# 5. どちらを選ぶべきか？
選択基準の例：
- コスト優先・小規模・外部SaaS利用あり：NAT Gateway
- セキュリティ重視・監査要件・大規模/高トラフィック：VPCエンドポイント
- 段階的移行：初期はNAT Gateway、成長に合わせてVPCエンドポイントへ
---

# 6. まとめ
NAT GatewayもVPCエンドポイントも、AWS内部ネットワークでセキュアに通信できますが、「どちらが最適か」はユースケース・セキュリティ要件・コスト見積もりによって変わります。
セキュリティや運用要件が厳しい場合はVPCエンドポイント、柔軟性やコスト重視ならNAT Gatewayという使い分けが現実的です。

https://zenn.dev/simpleform_blog/articles/f048edb9efd2b2

https://aws.amazon.com/jp/vpc/faqs/

::: note info
2 つのインスタンスがパブリック IP アドレスを使用して通信する場合、またはインスタンスがパブリックな AWS のサービスエンドポイントと通信する場合、トラフィックはインターネットを経由しますか?
→いいえ。パブリック IP アドレスを使用する場合、AWS でホストされているインスタンスとサービス間のすべての通信は AWS のプライベートネットワークを使用します。AWS ネットワークから発信され、AWS ネットワーク上の送信先を持つパケットは、AWS 中国リージョンとの間のトラフィックを除いて、AWS グローバルネットワークにとどまります。
さらに、データセンターとリージョンを相互接続する AWS グローバルネットワークを流れるすべてのデータは、安全性が保証された施設を離れる前に、物理レイヤーで自動的に暗号化されます。すべての VPC クロスリージョンピアリングトラフィックや、カスタマーまたはサービス間のトランスポート層セキュリティ (TLS) 接続などといった追加の暗号化レイヤーもあります。 


:::
MOSFETのアナログモデル（小信号解析）


## ✅ドレイン電流（非飽和領域）

$$
I_D = \mu \cdot C_{\text{ox}} \cdot \frac{W}{L} \left[(V_{GS} - V_T)V_{DS} - \frac{V_{DS}^2}{2}\right]
$$

### 🔍意味：

* \*\*MOSFETが非飽和領域（線形領域）\*\*にあるときのドレイン電流。
* $V_{GS} > V_T$、かつ $V_{DS} < V_{GS} - V_T$

### 🧠解説：

* $\mu$：キャリア移動度（NMOS: 電子, PMOS: 正孔）
* $C_{\text{ox}}$：ゲート酸化膜容量（単位面積あたり）
* $W/L$：トランジスタの幅/長さ比（ドレイン電流の規模を決める）
* $V_T$：しきい値電圧
* $V_{GS}$：ゲート–ソース間電圧
* $V_{DS}$：ドレイン–ソース間電圧

---

## ✅ゲート酸化膜容量

$$
C_{\text{ox}} = \frac{\varepsilon_0 \cdot \varepsilon_{\text{ox}}}{t_{\text{ox}}}
$$

### 🔍意味：

* 単位面積あたりの**ゲート酸化膜の容量**。

### 🧠解説：

* $\varepsilon_0$：真空の誘電率
* $\varepsilon_{\text{ox}}$：酸化膜の相対誘電率（SiO₂: 約3.9）
* $t_{\text{ox}}$：酸化膜の厚さ

---

## ✅ゲート容量の数値例

$$
C_{\text{ox}} = \frac{8.854 \times 10^{-14} \cdot 3.9}{270 \times 10^{-8}} = 1.279 \times 10^{-7} \ \mathrm{F/cm}^2
$$

### 🧠解説：

* 実際の値に代入して、1cm²あたりのゲート容量を求めたもの。
* 例えば、100µm × 100µmなら約12.8pFになります。

---

## ✅ドレイン電流（飽和領域）

$$
I_D = \frac{1}{2} \mu \cdot C_{\text{ox}} \cdot \frac{W}{L} (V_{GS} - V_T)^2 (1 + \lambda V_{DS})
$$

### 🔍意味：

* \*\*飽和領域（チャネルピンチオフ）\*\*でのドレイン電流
* $V_{DS} \geq V_{GS} - V_T$

### 🧠補足：

* $\lambda$：チャネル長変調（channel length modulation）係数

  * $\lambda = 0$ なら理想飽和
  * $\lambda > 0$ なら$I_D$が$V_{DS}$でわずかに増える（非理想）

---

## ✅λ = 0 のときの簡易式

$$
I_D = \frac{1}{2} \mu \cdot C_{\text{ox}} \cdot \frac{W}{L} (V_{GS} - V_T)^2
$$

---

## ✅トランスコンダクタンス（gm）

$$
g_m = \frac{\partial I_D}{\partial V_{GS}} = \mu \cdot C_{\text{ox}} \cdot \frac{W}{L} (V_{GS} - V_T)(1 + \lambda V_{DS})
$$

### 🧠解説：

* $g_m$：**入力（ゲート電圧）の微小変化**に対する**出力電流の変化率**
* アナログ回路の利得や帯域に影響する重要パラメータ

---

## ✅λ=0 の場合の簡略式

$$
g_m = 2 \mu C_{\text{ox}} \frac{W}{L} (V_{GS} - V_T)
$$

---

## ✅ドレイン・コンダクタンス（gd）

$$
g_d = \frac{\partial I_D}{\partial V_{DS}} = \lambda \cdot I_D
$$

---

## ✅出力抵抗（ro）

$$
r_o = \frac{1}{g_d}
$$

---
メモ

### 前書き
多すぎるんだよね。
最近のAI関連ツール（AIと相性いいとか言われてるやつも含める）
忘れちゃうから超雑に最近気に入ってるor気になってるAI系ツールやMCP等についてまとめる

### まとめてく
- Cursor
    - 細かいところ確認しながら修正するのに便利で結構使ってる
    - なるべくこれみないでClaude Codeで完結する方が効率えぇんやろなって思いながらしょうがなく使ってる
- Claude Code
    - これがないと生きていけない体になった
    - 開発がすでにこれありきの速度になってしまっているので、会社は僕に早く200ドル経費で渡すべき
- OpenHands CLI
    - Claude Codeの代替え品がきたなって思ってる
    - まだ使ってない
    - Claude Codeよりも使いやすいってTwitterで話題になったら乗り換えるかも
- Codex
    - 体験非常に良かったけどClaude Codeでいいやって最近なってる
    - なんかこうコーディングする力が違うねんな
- Figma Dev MCP
    - 待望の公式MCP
    - Dev以上じゃないと使えんのでまだ使ってない
- Figma Context MCP
    - 非公式版
    - 無料なので使うが、公式と比べてどうなんだろう感が常にあってちょっと不満あり
- Layermate
    - デザイン起こしてくれるFigmaの非公式MCP
    - 小規模ならもうデザイナーいらんくねって思ってる
- Playwright MCP
    - これとFigma Dev MCP組み合わせたらQA工数めっちゃ減りそう
- Context7
    - ちょっとまだ試せてない
    - https://mcpverified.com/doc-generators/ja/github-powered-servers
        - ここみてる限りすげーなーって思ってる
- NotebookLM
    - ラジオおもろい
    - 会議録音しといて、録音した内容あげたらAI付き議事録が完成する
    - 無料である程度使えるの助かる
- Veo3
    - ASMR動画作らせてバズってるなって印象
    - これでいい感じの動画作ってyoutubeにあげるの僕もやってみたい
- LangChain
    - えぇ感じなAI系のあれこれやりたいなーって思った時に使う必要がある
    - 最近はこれで遊ぼうとしてる
- ccusage
    - 僕はあまり使ってない
        - 何を成したかが重要であって、token消費量は別にどうでも良くないか？って感覚がある
    - blocksコマンドが便利そうだなって観測してる
    - https://x.com/ryoppippi/status/1934985456246206747
- Convex 
    - 使ったけど、そんなに好きじゃなかった
- 開発効率
    - 並列でAIいい感じに動かすのが効率的になるのは明白なんだが、3つ並列が限界かなーとは思ったりする
        - ３つ目頼んでる最中に１つ目の完了報告くるし、それに対応してたら２つ目のやつが完了報告くるんだよな
            - 僕がまだAIよりもだいぶ遅いのが問題
        - なのでtmuxとworktreeで何画面も開いているのにはあまり惹かれてない
        - その上で気になってる記事が以下、後で実践したい
            - https://memotty-obsidian.pages.dev/202506151218-claude-code%E3%81%A8github-issue%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%9F%E5%85%A8%E8%87%AA%E5%8B%95%E9%96%8B%E7%99%BA%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6/


### あとがき
Twitterのブックマークを元にどんどん更新予定
良さげなツールやMCPあったらぜひコメントしてください。
リストに追加します
[PenTestSecJP] Web脆弱性診断からペンテスターへ：キャリアチェンジのリアルと学び

:::note info
今更ですが当時参加したことを思い出しながら投稿します
:::

# Web脆弱性診断からペンテスターへ：キャリアチェンジのリアルと学び

GMOサイバーセキュリティ byイエラエで働く井上大誠（@1am_nek0）さんが語った、**Web脆弱性診断員からペネトレーションテスター（以下、PT）へのキャリアチェンジ体験談**がとても実践的だったので、参加レポートとしてまとめます

---

## 🔁 キャリアチェンジのきっかけ

新卒でWebセキュリティの診断業務に就き、2年ほど経験した井上さん  
やりがいは感じつつも、こう思うようになったそうです：

> 「ブラックボックス診断もホワイトボックス診断も、別に“仕事じゃなくても”できるんじゃないか？」

ちょうどその頃、**社内の部署異動制度が新設**されたことをきっかけに、ペネトレーションテスト部門への異動を決意

異動が決まってからは、
- CRTO
- OSEP
- OSED  
といった資格・演習でスキルを磨き、準備を進めたそうです（※上司曰く「やる気があればOK」とのことだったとか）

---

## 🛠️ ペネトレーションテスターとしての日々

### 1. 外部PT：攻撃者としての視点での侵入調査

> 目的：インターネット経由で社内システムに侵入できるかを検証する

#### アプローチ
- **Passive Recon**
  - サブドメイン列挙、Google Dorking、ASNマッピングなど
- **Active Recon**
  - ポートスキャン、ディレクトリ探索など
- **Vulnerability Identification**
  - 認証突破、SSRF、自サインアップのような「比較的見つけやすい脆弱性」もあれば、インジェクション系のような「見つけにくい脆弱性」も

OSSベースのシステムは、**既知の脆弱性が埋まっている“宝の山”**  
ブラックボックスではなく、ソースコードが手に入ることで難易度が変わる点が面白いポイントでした

---

### 2. 内部PT：マルウェア感染後の被害拡大を想定した演習

> 目的：社員が感染した場合、ドメイン支配や情報流出が可能か調査

- ゴール：ドメイン管理者権限の奪取、サプライチェーンリスクの評価
- 環境：Active Directory を含む社内ネットワーク

#### 学びと葛藤
- 本番環境では一つひとつの操作が命取りになるため、**慎重になりすぎて手が動かないことも**
- 「分かっているはずの攻撃手法」が、**環境依存で思わぬ事故につながる怖さ**
- ベテランの先輩でも「知らないことはちゃんと調べる」姿勢が印象的だったそうです

この経験から、**検証環境の自作**や**ログ観察・ツール解析**の重要性に目覚めたとのこと  
ツールを“使うだけ”では得られない、本質理解が深まったそうです

---

## 🔄 Web診断とPT業務の違い

| 項目 | Web脆弱性診断 | ペネトレーションテスト |
|------|----------------|---------------------------|
| PDCAサイクル | 短くて回転が早い | 長くて抽象的なテーマが多い |
| 分析対象 | 決まった画面やAPI | 見えてないものを想像して検証する |
| 工夫の余地 | やや限定的 | 検証環境や再現アプローチなど無限にある |

PT業務では「見えないものをどう仮定し、どう突破口を見出すか」が鍵

その分、**「Plan → Do」のハードルが格段に高くなる**と語っていました

---

## 🎓 まとめ：キャリアチェンジを考えている方へ

井上さんの話から学べることは以下の通りです：

- ペンテストは**一見派手に見えて、実は地味で繊細な仕事**
- わからないことに素直になり、**ちゃんと試す・調べる・記録する姿勢**が大事
- 自分の手で環境を作って試すことで、**“わかった気”から“本当にわかる”へ**

そして何より、
> 「やる気があるなら、やれる。やりながら学べる」  

というリアルなメッセージが響きました

---

## ✍️ あとがき

PTの世界は興味がありつつ「別の世界」と思っていた部分がありました  
今回の話を聞いて、その境界線は思ったよりも低く、乗り越えるための道もちゃんとあることに気づかされました
副作用って何？Reactでの3つのルールで理解しよう！

# はじめに

Reactを使っていると、`useEffect` や `localStorage`、API呼び出しなど、いわゆる **副作用（side effect）** にぶつかることが多くなります。

でも、副作用をちゃんと整理できていないと…

* 無駄な再レンダリングが増える
* 初期表示がバグる
* サーバーサイドレンダリング（SSR）でエラーになる

などのトラブルにつながります。

この記事では、Reactで副作用を扱うときに大事な**3つのルール**を、**簡単な例とともに**紹介します。

# 1️⃣描画中に副作用を実行しない

**❌ ダメな例**
> localStorageから直接読み込む
```tsx
const [name, setName] = useState(localStorage.getItem("name") || "")
```

**🧨 なにが問題？**

* `localStorage.getItem()` は副作用（外部の状態を読む）
* それを **`useState` の初期値として直接使う**と、Reactがコンポーネントを**描画するたびに副作用が実行される**
* SSR環境では `localStorage` がないため、**エラーになる**

**✅ 解決策**
> useEffectを使う

```tsx
const [name, setName] = useState("")

useEffect(() => {
  const stored = localStorage.getItem("name")
  if (stored) {
    setName(stored)
  }
}, [])
```

副作用は **useEffect の中で、描画のあとに実行**することで回避できます。

# 2️⃣副作用は発生源（イベント）の中に置く

**❌ ダメな例**
> 値の保存をuseEffectでやってしまう

```tsx
useEffect(() => {
  localStorage.setItem("count", count)
}, [count])
```

**🧨 なにが問題？**

* 状態が変わるたびに **副作用が再実行**される
* 毎回保存が走るので、**無駄が多い**
* 本来は「ユーザーが何かしたとき」に保存したいのに、**変更のたびに保存されてしまう**

**✅ 解決策**
> イベントの中で処理する

```tsx
const handleClick = () => {
  const newCount = count + 1
  setCount(newCount)
  localStorage.setItem("count", String(newCount))
}
```

これなら：

* 状態を更新するタイミングと副作用の発生が一致
* 副作用が **自然な場所（イベント内）** に置かれていて、意図が明確

# 3️⃣外部との同期は useEffect に書く

**❌ ダメな例**
> APIリクエストをレンダリング中に実行しようとする

```tsx
function Message() {
  const data = fetch("/api/message").then(res => res.json())

  return <p>{/* ここにデータを表示したい */}</p>
}
```

**🧨 なにが問題？**

* **`fetch()` が毎回レンダリング中に実行される**
* レンダリング中に副作用が走ってしまっている
* 実行タイミングも予測しづらく、状態と合わなくなる

**✅ 解決策**
> useEffectで処理する

```tsx
function Message() {
  const [text, setText] = useState("")

  useEffect(() => {
    fetch("/api/message")
      .then(res => res.json())
      .then(data => setText(data.text))
  }, [])

  return <p>{text}</p>
}
```

これなら：

* 副作用（API通信）は**描画後に1回だけ実行**
* `message` を状態にセットすれば、Reactが再描画してくれる

# おわりに

副作用の扱い方は、Reactの中でもつまずきやすいポイントですが、
**この3つのルール**を覚えておくだけで、かなり安全でわかりやすいコードが書けるようになります。

> 副作用をどこに書くか迷ったら、
> 「描画中？ useEffect？ イベント中？」
> と自問してみてください！
#0173（2025/06/18）`np.arctan()` と `np.arctan2()` の違い

# `np.arctan()` と `np.arctan2()` の違い

## はじめに

数値計算やロボット・画像処理などで「角度」を扱う場面は多々あります。その際、`np.arctan()` と `np.arctan2()` のどちらを使うべきかで迷った経験はありませんか？本記事では **象限情報が必要かどうか** を軸に、両者の違いと選び方を実践的にまとめます。

---

## 結論早見表

* **片方の値しかなく、±90° 以内で十分** → `np.arctan()`
* **2D ベクトルの完全な向き（0°〜360°）が欲しい** → `np.arctan2()`
* **x が 0 になる可能性がある** → 迷わず `np.arctan2()`

---

## 1. `np.arctan()` の基礎

* **シグネチャ**: `np.arctan(x)`
* **引数**: 比 `y/x`（実数）を 1 つ渡す
* **戻り値の範囲**: $-\frac{\pi}{2},\;\frac{\pi}{2}$（−90°〜+90°）
* **用途**: 勾配や単純な傾きを取りたいとき

> **ポイント**: x の符号情報が欠落するため、(−1,−1) と (1,1) の区別がつかない。

---

## 2. `np.arctan2()` の基礎

* **シグネチャ**: `np.arctan2(y, x)`
* **引数**: ベクトルの $y$, $x$ を別々に渡す
* **戻り値の範囲**: (-\pi,;\pi]（−180°〜+180°）
* **用途**: ロボットのヨー角、方位角、回転行列↔オイラー角変換など
* **メリット**: x と y の符号を見て象限を判定。x=0 でも安全。

---

## 3. コード例で違いを体感

```python
import numpy as np

# 4 つのベクトル (x, y)
x = np.array([-1, -1,  1, 1])
y = np.array([-1,  1, -1, 1])

# arctan は y/x を直接渡す
theta_atan  = np.degrees(np.arctan(y / x))
# arctan2 は (y, x) を渡す
theta_atan2 = np.degrees(np.arctan2(y, x))

print(theta_atan)   # [-45. -45. -45.  45.]
print(theta_atan2)  # [-135.  135.  -45.   45.]
```

**出力解説**

* `arctan` は全て ±45°。象限情報が失われています。
* `arctan2` は左下を −135°、左上を +135° と正しく判定します。

---

## 4. よくある落とし穴

* **ゼロ割り**: `y/x` で x=0 のケース → `arctan2` を使う
* **180° と −180° の扱い**: `arctan2` は範囲が (−π, π] なので、必要に応じて 0〜360° に正規化しましょう。

```python
theta = np.degrees(np.arctan2(y, x))
angle360 = (theta + 360) % 360  # 0〜360° に変換
```

---

## 5. 現場シナリオ別の選択ガイド

### ロボット／ドローンの姿勢推定

* **必須情報**: 機体がどの象限を向いているか → `arctan2`

### 画像処理でのエッジ方向解析

* 勾配ベクトルの向き（0〜360°）が必要 → `arctan2`

### 線形回帰の傾きチェック

* 傾き tanθ を arctan で直接角度へ → `arctan`

---

## 6. まとめ

* **象限を意識しない** 一変数の逆正接 → `np.arctan()`
* **象限を意識した** 2D 角度計算 → `np.arctan2()`
terraformとansibleの違いについて



##### なぜこの疑問が生まれたのか
現在私が働いている現場では、構成管理ツールとしてterraformとansibleを利用しています。
ですが私の中でこの二つの技術がごっちゃになってしまい、お互いどの様な部分で強みを持っているのかを知る必要があると考えまとめてみました。

### terraformについて
##### 主な特徴と自分なりの理解:
- 宣言型:インフラの状態をコードで記述。terraformがその状態になるよう自動で構築
- 不変インフラ:変更時は新しいリソースをデプロイし置き換え。環境の差異を防ぎやすい
- 状態管理: .tfstateファイルでインフラの現在の状態を把握。コードとの差分を検知できる
- プロバイダーエコシステム: AWS, Azure, GCPなど多様なクラウドサービスを一元管理できる
- 実行計画（terraform plan）: 適用前に変更内容を詳細に確認でき、意図しないミスを防ぐことができる

### ansibleについて
##### 主な特徴と自分なりの理解:
- エージェントレス: 管理対象サーバーにSSHで直接操作できる
- 冪等性: 何度実行しても常に同じ結果。二重実行による問題を防ぐ
- YAMLベース: Playbookは読みやすく書きやすいYAML形式で記述する

### terraformとasnibleの違い
terraformとansibleは、どちらもIaCのツールですが、その役割と得意とする領域に違いがあります。
terraformは主にインフラの環境構築（プロビジョニング）と管理に特化しています。ざっくりいうとシステムを動かすために必要な「土台」を「準備して使えるようにすること」に特化しているということです。
クラウドやオンプレ、ネットワーク、データベース、ストレージといった基盤となるリソースの新規構築、変更、削除を得意としています。
インフラの「こういう形にしたい！」ということをコードで書くと、Terraformがその通りに環境を作ってくれるというがメインの役割になります。

一方、AnsibleはOSやミドルウェアの構成管理、およびアプリケーションのデプロイに特化しています。trraformで作成した仮想マシンやサーバーに対して、OSの初期設定、必要なソフトウェアパッケージのインストール、サービスの起動・停止、ユーザー管理、アプリケーションのデプロイといった、より細かい粒度での設定や操作を行います。

大まかに、terraformはインフラの構成管理、ansibleはOS・ミドルウェアの構成管理に利用される、と言うことです。


#### 参考文献
https://www.lac.co.jp/lacwatch/service/20201216_002380.html

https://www.redhat.com/ja/topics/open-source/ansible-toterraform-noweiitoha
【業務自動化】Linuxでdf -kのディスク使用状況を週１メール送信して自動化した（cron＋sh＋sendmail）

※紹介するディレクトリや名前などは例なので自分用に置き換えてください

# 背景と目的
システム運用の現場で、「サーバの空き容量チェックを毎日にしてるけど、手動で毎日やるのは面倒だな…」と思っていました。
そこで今回は、Linuxのdf -kを毎朝自動取得し、その結果をメールで送信する仕組みを作ってみました。

cron＋sh＋sendmailの組み合わせで、ログの生成とメール送信まで完全自動化しています。

# ディレクトリ構成と処理の概要
```
/home/username/scripts/
              ├── df_report.sh        ← cronで実行されるsh
              ├── send_mail.sh
              └── logs/
              └── df_report.log     ← 日付付きで保存されるdf結果ログ

```

# df_report.sh の中身
取得した日付とディスク使用量がdf_report.logに記載される
``` df_report.sh
#!/bin/bash

LOG_DIR="/home/username/logs"

LOGFILE="$LOG_DIR/df_report.log"

# ログ追記(ログは追記で更新される
{
  echo "=== $(date '+%Y-%m-%d %H:%M:%S') ==="
  df -k
  echo ""
} >> "$LOGFILE"
```

# send_mail.sh
df_report.shで作成したdf_report.logを添付メールとして送信
``` df_report.sh
#!/bin/bash

TO="someone@example.com"
FROM="yourname@example.com"
SUBJECT="XXXサーバーのディスクログ"
LOGFILE="/home/username/logs/df_report.log"
BOUNDARY="====$(date +%s)===="

# ログファイルが存在すれば送信
if [ -f "$LOGFILE" ]; then
  (
    echo "To: $TO"
    echo "From: $FROM"
    echo "Subject: $SUBJECT"
    echo "MIME-Version: 1.0"
    echo "Content-Type: multipart/mixed; boundary=\"$BOUNDARY\""
    echo
    echo "--$BOUNDARY"
    echo "Content-Type: text/plain; charset=UTF-8"
    echo
    echo "ログを添付いたします。"
    echo
    echo "--$BOUNDARY"
    echo "Content-Type: text/plain; name=\"$(basename "$LOGFILE")\""
    echo "Content-Transfer-Encoding: base64"
    echo "Content-Disposition: attachment; filename=\"$(basename "$LOGFILE")\""
    echo
    base64 "$LOGFILE"
    echo "--$BOUNDARY--"
  ) | /usr/sbin/sendmail -f "$FROM" -t
else
  echo "[INFO] ログファイルが存在しないため送信スキップ：$LOGFILE"
fi
```

# shを使用するには権限をつける（例）
``` bash
chmod +x df_report.sh
chmod +x send_mail.sh
```

# cronの設定（例）
``` cron
# 月~金の朝9時にdf_report.logにdf -kの結果を記載
0 9 * * 1-5 /home/username/scripts/df_report.sh

# 月曜日の朝８時にdf_report.logを添付メールとして送信
0 8 * * 1 /home/username/scripts/send_mail.sh
```

# まとめ
ほんのちょっとのシェルスクリプトとcron設定で、日常の確認作業を自動化できました。
小さなことですが少しの楽の積み重ねが大事だと思います
【Amazon Q CLI】アクションゲームを作ってみた

## はじめに
Amazon Q CLIでゲームを作成して応募すると、Tシャツがもらえるキャンペーンが開催中です！Tシャツに釣られてゲームを作成してみました

## キャンペーン概要
https://aws.amazon.com/jp/blogs/news/build-games-with-amazon-q-cli-and-score-a-t-shirt/

開催期間は 2025 年 5 月 20 日から 6 月 30 日まで。Amazon Q CLIを使ったことが無い方でも、30分程度で簡単なゲームを動かすところまでいけるので、まだの方はぜひ試してみてください！

## Amzon Q CLIを使ってみよう
https://docs.aws.amazon.com/ja_jp/amazonq/latest/qdeveloper-ug/command-line-installing.html

こちらの手順に沿ってコマンドライン用のAmazon Qをインストールします
インストールできたら、ターミナルでチャットモードを開始しましょう

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4114182/26f40e92-31d4-47b2-8014-d0489a07ce02.png)

今回はアクションゲームを作ることにしました
日本語で以下のように指示を出してみます

~~~
> 下記条件でゲームを制作して欲しい
# ゲームの概要
- ジャンル: アクションゲーム
- 使用技術: HTML + JavaScript
- 対象プラットフォーム: ブラウザ

# ゲームの仕様
- 横にスクロール - 敵に衝突したり、敵の攻撃が当たったりするとゲームオーバー
- 得点は倒した敵の数で計算される
- ゴールに辿り着いたらクリア
- 敵キャラクターは3種類
 
# リクエスト内容
- このゲームを実装するコードを生成して
~~~

待つこと数分...あっという間にブラウザで遊べるゲームが出来上がりました！
ゲームの特徴や操作方法も分かりやすくまとめてくれています

~~~
横スクロールアクションゲームを作成しました！ファイルは /Users/xxx/action-game.html に保存されています。

## ゲームの特徴

• 横スクロールアクションゲーム
• 3種類の敵キャラクター（歩く敵、ジャンプする敵、弾を撃つ敵）
• プレイヤーは攻撃して敵を倒すことでスコアを獲得
• ゴールに到達するとゲームクリア
• 敵に接触したり敵の弾に当たるとダメージを受け、体力がなくなるとゲームオーバー

## 操作方法

• 矢印キー左右: 移動
• 矢印キー上またはスペースキー: ジャンプ
• Zキー: 攻撃
• タッチデバイスでも操作可能（画面左側タッチでジャンプ、右側タッチで攻撃、スワイプで移動）

## ゲームの詳細

1. プレイヤー:
   • 青い四角形の体と黄色い丸い頭を持つキャラクター
   • 3つのハートで表される体力システム
   • 攻撃時には黄色い攻撃エフェクトが表示される

2. 敵キャラクター:
   • 赤い四角形の「歩く敵」: 単純に左に移動
   • 緑の三角形の「ジャンプする敵」: 左に移動しながらランダムにジャンプ
   • 青い円形の「撃つ敵」: プレイヤーが近づくと弾を発射

3. ステージ:
   • 茶色の地面とプラットフォーム
   • 背景には空、雲、山の風景
   • 右端には金色の旗のあるゴール

4. ゲームシステム:
   • 敵を倒すとポイント獲得（歩く敵:10点、ジャンプする敵:20点、撃つ敵:30点）
   • 敵に接触するとダメージを受け、ノックバックする
   • 敵の弾に当たるとダメージを受ける
   • 体力がなくなるとゲームオーバー
   • ゴールに到達するとゲームクリア

ブラウザで action-game.html ファイルを開いて、「ゲーム開始」ボタンをクリックするとプレイできます。
~~~

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4114182/5ea6419d-4292-43aa-aa0e-00e43dca76f8.png)

試しにプレイしてみましたがちゃんと遊べるレベルになっていました
改良を重ねれば面白いゲームが作れるかもしれないですね！

## まとめ
このような感じで、簡単にゲームが作れました
ゲーム開発以外にも広く活用できると思うので、これを期に色々と試してみようと思います
App Router dynamic routing時のparamsエラーの対応

# これは何？

Next.jsのApp Routerにて、dynamic routingページでSSRをしたかった時のエラー対応メモです。

> dynamic routing?
`app/[id]/page.js` ⬅︎こういうのです

## paramsをそのまま使用するとエラー

以下のように SSR の中で `params.id` を直接参照すると、エラーになりました。

```jsx
export default async function UserProfile({ params }: {params : {id: string}}) {
  const id = params.id; // ここでエラー
  let profile = null;
  try {
    const res = await apiClient.get(`profile/${id}`);
    profile = res.data;
  ...
```

出たエラーはこちら

```config
Error: Route "/profile/[id]" used `params.id`. `params` should be awaited before using its properties. Learn more: https://nextjs.org/docs/messages/sync-dynamic-apis
    at UserProfile (src/app/profile/[id]/page.tsx:10:20)
```

要するに、paramsはPromiseになっているので、awaitが必要とのこと。(そうなんだ)

##  Next.js 公式ドキュメントを読む

サンプルソースに対応の方法が記述されていました。
[Dynamic APIs are Asynchronous](https://nextjs.org/docs/messages/sync-dynamic-apis)

```jsx
// サンプル引用
async function Page({ params }) {
  // asynchronous access of `params.id`.
  const { id } = await params
  return <p>ID: {id}</p>
}
```

## エラーを修正する

型定義も、わかりやすくtypeに切り出してしまいましょう！

```jsx

type PageProps = {
  params: { id: string }
};

export default async function UserProfile({ params }: PageProps) {
  const { id } = await params; 
  let profile = null;
  try {
    const res = await apiClient.get(`profile/${id}`);
    profile = res.data;
  ...
```

これで無事に動作しました！

## 所感

もちろんドキュメントを先に読むのも大切ですが、
実際に手を動かしてエラーと向き合いながら学ぶほうが、理解が深まりますね！！
FWFW - Find Websites From World

![og.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3908420/3506c735-4958-42cc-9d1f-f15190500107.png)

  
  # FWFW - Find Websites From World
  
  <h3>🌍 世界中の素晴らしいウェブサイトとツールを発見</h3>
  <p><strong>地域別ナビゲーション • お好みの支払い • 高速リリース</strong></p>
</div>

---

## 📖 プロジェクト概要

**FWFW (Find Websites From World)** は、世界中の優秀なウェブサイト、アプリケーション、デジタルツールを探索するためのグローバルな発見プラットフォームです。私たちの使命は、地理的分類を通じて、世界中の高品質なリソースの発見をシンプルで楽しいものにすることです。

## ✨ コア機能

### 🗺️ **地域別スマートナビゲーション**
- **大陸別カテゴリ**：アジア、ヨーロッパ、アメリカなどの大陸でコンテンツを整理
- **国別細分化**：特定の国や地域のローカライズされたツールを深く探索
- **地域の特色**：異なる地域独特のイノベーションソリューションを発見
- **文化的多様性**：グローバルテクノロジーエコシステムの豊かさを展示

### 💰 **Pay What You Want 柔軟な価格設定**
- **自由価格**：$0-$10 の範囲で任意の支払い金額を選択
- **無料投稿**：$0 無料投稿（手動レビューが必要）
- **即時公開**：有料コンテンツは待機なしで即座に公開
- **公正で透明**：隠れた費用なし、価格は完全にあなた次第

### 🚀 **高速プロダクトローンチ**
- **ワンクリック投稿**：簡素化された公開プロセス、数分で完了
- **スマートカテゴライゼーション**：最適なカテゴリとタグを自動マッチング
- **即時有効**：有料コンテンツをユーザーにリアルタイムで表示
- **SEO最適化**：検索エンジンフレンドリーなページを自動生成

### 🔍 **発見ツールエコシステム**
- **多次元検索**：カテゴリ、タグ、地域による多重フィルタリング
- **精密な推奨**：ユーザーの好みに基づいたスマート推奨
- **トレンドインサイト**：リアルタイムの人気ツールとウェブサイトランキング
- **コミュニティ駆動**：ユーザー評価と推奨システム

## 🛠️ 技術特徴

### モダンテクノロジースタック
- **フロントエンドフレームワーク**：Next.js 14 + React 18
- **コンテンツ管理**：Sanity CMS統合
- **スタイルシステム**：Tailwind CSS + Radix UI
- **認証システム**：NextAuth.js
- **決済統合**：Stripe
- **デプロイ最適化**：Docker + Vercel

### 高性能アーキテクチャ
- **サーバーサイドレンダリング**：SEOフレンドリーなSSR/SSG
- **画像最適化**：Next.js自動画像最適化
- **キャッシュ戦略**：アクセス速度向上のための多層キャッシュ
- **レスポンシブデザイン**：すべてのデバイスに完璧に適応

## 🌟 使用ケース

### 👨‍💻 **開発者**
- 新しい開発ツールとフレームワークを発見
- 異なる地域の技術トレンドを学習
- オープンソースプロジェクトを宣伝
- 技術コラボレーションパートナーを見つける

### 🏢 **起業家**
- プロダクトをローンチして早期ユーザーを獲得
- グローバル市場の競争環境を調査
- インスピレーションと起業機会を見つける
- 新製品の低コストプロモーション

### 🎨 **デザイナー**
- 優秀なデザインツールを発見
- グローバルなデザインインスピレーションを収集
- 個人ポートフォリオを展示
- デザイントレンドを把握

### 📊 **マーケティング専門家**
- グローバルマーケティングツールを調査
- 異なる地域のユーザー好みを分析
- マーケティングサービスを宣伝
- ブランド影響力を構築

## 🚀 クイックスタート

### ユーザーガイド
1. **ブラウズ・発見**：[fwfw.app](https://fwfw.app) にアクセスして探索を開始
2. **地域フィルタリング**：興味のある大陸や国を選択
3. **カテゴリブラウジング**：ツールタイプでコンテンツをフィルタリング
4. **詳細情報**：ツールをクリックして詳細情報を表示

### プロダクト公開
1. **アカウント登録**：無料アカウントを作成
2. **情報送信**：プロダクトの詳細情報を入力
3. **価格選択**：支払い金額を決定（$0-$10）
4. **即座に公開**：有料コンテンツが即座に公開

## 📈 プロジェクトビジョン

私たちは**真にグローバルなツール発見プラットフォーム**の構築に取り組んでおり、世界中の優秀なイノベーションが地理的境界に制限されないことを保証します。以下を通じて：

- **情報バリアの排除**：グローバルユーザーが最高のツールを発見できるように
- **文化交流の促進**：テクノロジーツールを通じて異なる文化を理解
- **イノベーション・起業の支援**：小規模チームに低コストプロモーションチャネルを提供
- **オープンエコシステムの構築**：包括的で多様なテクノロジーコミュニティを創造

## 🤝 貢献

あらゆる形の貢献を歓迎します：

- 🐛 **バグレポート**：問題の発見と修正をサポート
- ✨ **機能提案**：新機能のアイデアを提案
- 🌍 **コンテンツ貢献**：高品質のツールとウェブサイトを推奨
- 💻 **コード貢献**：開発と最適化に参加
- 📖 **ドキュメント**：プロジェクトドキュメントの改善

## 📞 お問い合わせ

- **ウェブサイト**：[fwfw.app](https://fwfw.app)
- **メール**：support@fwfw.app
- **GitHub**：[find-websites-from-world](https://github.com/Selenium39/find-websites-from-world)
- **Twitter**：[@yuxing39](https://x.com/yuxing39)

---

<div align="center">
  <p><strong>🌍 世界の素晴らしさを手の届く範囲に 🌍</strong></p>
  <p><em>FWFW - Find Websites From World</em></p>
</div>
競プロ日記#25/06/18

# 競技プログラミングの鉄則

[B51 - Bracket](https://atcoder.jp/contests/tessoku-book/tasks/tessoku_book_dx)
- Stackを用いた応用問題。
- Stackの中に「'('」や「')'」を入れるのではなくてあくまでも「'('」のインデックスだけをpushしていくというのが重要なポイントだったように感じた

[B52 - Ball Simulation](https://atcoder.jp/contests/tessoku-book/tasks/tessoku_book_dy)
- Queueを用いた応用問題。
- そもそもの問題設定を理解するのに時間がかかってしまった。
- 結局のところボールが並んでいることと問題文中に出てくる「キュー」は別物として解釈して問題文通り実装すれば答えは簡単に出せる。「pos-1」の範囲を確認しないと壊れてしまうので注意。

[B39 - Taro's Job](https://atcoder.jp/contests/tessoku-book/tasks/tessoku_book_dl)
- 優先度付きキューでこの問題を解く際にi日目からできるようになる仕事の賃金リストを作成するのが肝っぽい（以下コードでいう配列G）
- それに対して日ごとに範囲forでpushとpopを行っていく

```
    for (long long i = 1; i <= N; i++) {
        cin >> X[i] >> Y[i];
        G[X[i]].push_back(Y[i]);
    }

    priority_queue<long long> pq;
    for (long long i = 1; i <=D; i++) {
        for (int j: G[i]){
            pq.push(j);
        }

        if (!pq.empty()) {
            ans += pq.top();
            pq.pop();
        } 
    }
```

[A54 - Map](https://atcoder.jp/contests/tessoku-book/tasks/tessoku_book_bb)
- Mapを使えば一撃で解ける問題

[B54 - Counting Same Values](https://atcoder.jp/contests/tessoku-book/tasks/tessoku_book_ea)
- Mapで各値をKeyとして管理する。Valueはその値がA全体の中に何個出てくるかの数値
- そして範囲forでKeyごとの値に対してValue個から2つ選ぶ組合せを求めてその合計を答えとした。これであってるのか？という気分だった
→ACしてしまった...
- ちなみに解説の方はリアルタイム加算をする方法でやっていた

```



// nPmの順列(階乗や0!にも対応)
long long funcPermutation(int N,int M){
    if (N == 0 && M == 0){
        return 1;
    }
    long long ans = 1;
    for (int i = 0;i < M;i++){
        
        ans = ans * (N - i);
        
    }
    return ans;
}



// nCmの組合せ(funcPermutationを使う)
long long funcCombination(int N,int M){
    return funcPermutation(N,M) / funcPermutation(M,M);
}


int main() {
    long long N;
    cin >> N;
    map<long long,long long> mp;

    long long ans = 0;

    for (long long i = 1;i <= N; i++){
        long long A;
        cin >> A;
        mp[A]++;
    }

    for (auto it = mp.begin(); it != mp.end(); it++){
        long long key = it->first;
        long long value = it->second;
        ans += funcCombination(value, 2);
    }

    cout << ans << endl;
}
```
闘魂Phoenix道場：PostgreSQLをDockerで立ち上げるッ！！！（devcontainer付き） Phoenixアプリから使わせていただく

いよいよはじまりました！
[Qiita Tech Festa](https://qiita.com/tech-festa/2025) :tada::tada::tada: 

https://qiita.com/tech-festa/2025


# はじめに

こんにちは、ElixirとPhoenixをこよなく愛する闘魂プログラマーです。  
つまりAIプログラマーです。あっ、AIとは、**A**ntonio **I**nokiさん、つまり猪木さんのことです。  

本記事は、[みんなでPostgreSQLの知見を共有しよう](https://qiita.com/official-events/96a5d14a8908bfca8b8f) への参加記事です。


https://qiita.com/official-events/96a5d14a8908bfca8b8f

# PhoenixのデフォルトDBはPostgreSQL

[Phoenix](https://www.phoenixframework.org/) では、プロジェクトを作成する際にPostgreSQLがデフォルトで使われます。

```bash
mix phx.new hello
# => デフォルトでPostgreSQLが選ばれます
```

[Phoenix](https://www.phoenixframework.org/)とは、Elixir製の**すんごいWebアプリケーションフレームワーク**のことです。

# DockerでPostgreSQLを立ち上げる

新しいPCを新調するたびに、自分のローカルにPostgreSQLを入れるのは面倒ですし、慎重派の私はDockerコンテナで立ち上げています。

```bash
docker run -d --rm -p 5432:5432 -e POSTGRES_USER=postgres  \
-e POSTGRES_PASSWORD=postgres postgres
```

`POSTGRES_USER`と`POSTGRES_PASSWORD`には、`config/dev.exs`にデータベースへの接続情報が以下のように作られるのでそれにあわせて、`postgres`をセットしています。


```elixir:config/dev.exs
config :hello, Hello.Repo,
  username: "postgres",
  password: "postgres",
  hostname: "localhost",
  database: "hello_dev",
  stacktrace: true,
  show_sensitive_data_on_connection_error: true,
  pool_size: 10
```

# devcontainerでも起動してます

私がメンテしている [phx_devcontainer](https://github.com/TORIFUKUKaiou/phx_devcontainer) というdevcontainer定義でもPostgreSQLが入っています。

こちらを使うと、Elixir + Phoenix + PostgreSQL の開発環境が短時間で整います。
devcontainerですので、つまりは所謂ひとつのCodespaceでも開発ができます。
別記事で紹介していますので、よければご覧ください。

https://qiita.com/torifukukaiou/items/5dd716cb04db9b46bc92

# おわりに

PhoenixとPostgreSQLは、最初から相性がいいです。意識しなくてもPostgreSQLと共に開発が始まります。  

PostgreSQLキャンペーンをきっかけに、象さんのアイコンを思い出しました。  

闘魂とは、己に打ち克つこと。そしてPhoenixアプリケーションの裏にPostgreSQLあり。

**元氣ですかーーーッ！！！**
サブクエリ

についても---

### サブクエリ（副問い合わせ）とは？

- サブクエリとは、「クエリ（問い合わせ）」の中に、さらに別のクエリを含める書き方のこと。
- 主にSELECT文内やWHERE句、FROM句などで使われる。
- サブクエリの結果がメインのクエリの条件やデータとして利用される。

---

### サブクエリの主な使い方

1. **WHERE句での利用**
   - 例：特定の条件に合致するデータのみを抽出する際に使う  
   ```sql
   SELECT * FROM users WHERE id IN (SELECT user_id FROM orders WHERE total > 10000);
   ```
2. **FROM句での利用（インラインビュー）**
   - サブクエリの結果を一時的なテーブルのように利用  
   ```sql
   SELECT name, total FROM (SELECT user_id, SUM(amount) AS total FROM orders GROUP BY user_id) AS t;
   ```
3. **SELECT句での利用**
   - 各行に対してサブクエリを評価し、列として値を返す  
   ```sql
   SELECT name, (SELECT COUNT(*) FROM orders WHERE user_id = users.id) as order_count FROM users;
   ```

---

### サブクエリの種類

- **スカラーサブクエリ**  
  1件だけ値を返すサブクエリ

- **行サブクエリ**  
  1件のレコード（複数列）を返すサブクエリ

- **テーブルサブクエリ**  
  複数行・複数列の結果を返すサブクエリ

---

### サブクエリ利用時の注意点

- サブクエリはネストが深い場合、パフォーマンスが低下しやすい
- 場合によってはJOINやWITH句（共通テーブル式）の方が最適なケースもある
- インデックスの効き方に影響が出る場合がある

---

### まとめ

- サブクエリは複雑なデータ抽出や集計に便利
- 使いすぎによるパフォーマンス低下に注意
- 時と場合によって使い分けが必要

---
GoでFIZZBUZZを解く

勉強がてらGo言語でFIZZBUZZ問題を解いてみました。

最初は一の位に着目してFIZZBUZZの出力判定をしてみようとしか考えていませんでした。
それが書いている内にせっかくだし色々と捻ってみようと方向転換したのが運の尽き。
最終的に我ながらよく分からないことをやってるなぁと感じる出来になってしまいました。

```main.go
package main

import (
    sc "strconv"
    f "fmt"
    m "math"
)

const (
    FIZZ = "3692581470"
    BUZZ = "50"
)

type fizzBuzz struct {
    FCnt int
    BCnt int
}

// 出力する文字列の取得
func (fb *fizzBuzz)getFizzBuzz(num int) string {
    ret := sc.Itoa(num)

    // 次にFIZZを出力する値を求める
    fNum, _ := sc.Atoi(sc.Itoa((fb.FCnt - num / 31) / 3) + string(FIZZ[fb.FCnt % 10]))
    // 次にBUZZを出力する値を求める
    bNum, _ := sc.Atoi(sc.Itoa(fb.BCnt / 2 + fb.BCnt % 2) + string(BUZZ[fb.BCnt % 2]))

    // 引数が上で求めた値の場合、FIZZを出力文字列に追加する
    if  num == fNum {
        ret += "FIZZ"
        fb.FCnt++
    }

    // 引数が上で求めた値の場合、BUZZを出力文字列に追加する
    if num == bNum {
        ret += "BUZZ"
        fb.BCnt++
    }

    // 数字のみの場合はそのまま、そうでなければ数字部分を除外した文字列を返却する
    sub := len(ret) - len(sc.Itoa(num))
    return ret[sub >> int(m.Logb(float64(sub + 1))) * len(sc.Itoa(num)):]
}

func main(){
    var fb fizzBuzz
    for i := 1; i <= 100; i++ {
        f.Println(fb.getFizzBuzz(i))
    }
}
```
AWS_SAA合格体験記

 ## 概要
<!--
この記事で何を取り上げるのかを簡潔に説明します。
背景や読者の想定、全体の流れもここに軽く触れると親切です。
-->
AWS_SAAの資格対策で実際に学習期間や実際に学習に使用したサイトなどをご紹介いたします。

## AWS_SAAとは
AmazonWebService（AWS）が提供しているベンダー資格の中の一つ、中級レベルの試験です。
AWS 認定ソリューションアーキテクト – アソシエイト（AWS Certified Solutions Architect – Associate）」の略称

## 試験内容
試験コード：SAA-C03（2024年時点）
形式：選択式・複数選択式（CBT: コンピューター試験）
時間：130分
### 試験範囲
1. 設計の回復性	フォールトトレランス、災害対策など：30%
2. 高パフォーマンスなアーキテクチャ設計	負荷分散・スケーラビリティ：28%
3. セキュアなアーキテクチャ設計	IAM、暗号化、ネットワーク制御など：24%
4. コスト最適化設計	コスト見積、請求、料金体系理解など：18％
## 合格ライン
1000点中720点で合格です。
私の場合は２回目で779点をとり、合格できました。

## 学習期間
小さい子持ちの社会人で、時間目いっぱい使用して1日平均2時間、約1ヶ月での学習を行いました。
1度目は学習から2週間の時点で受けて、あと1問程度で落ちてしまいました。。。
そこから13日間は再受験不可なので、ちょうど2週間を空けて再受験しました。
Webで調べたところ学習期間の平均は1ヶ月ぐらいであったので、平均で取れてホっとしてます。

## やったこと
<!--
実施した作業や試した内容の概要をリスト形式などでまとめます。  
その下の各「実施内容」で詳細に説明します。
-->

### (やったことその1)
動画学習：Youtube
AWS資格 対策講座（https://www.youtube.com/@AWS_course）
SAAの試験に出てくるサービスの概要を短時間で知るために利用しました。
実際に各サービスのアイコンを見ることが出来ます。視覚的にどのサービスがどのアイコンなのか知り、サービスの特徴をビジュアルで認識できます。はじめて学習する方にはこちらを参照することをお勧めします。
家事の隙間時間や寝る前などにも簡単な復習で見てました。
### (やったことその2)
<!-- 
実施した作業や調査、実装の二つ目を詳しく説明します。  
必要に応じて分けてください。 
-->
学習と試験対策：Cloudlicense
※有料の問題集サイトになります。
URL：https://cloud-license.com/
こちらの問題を50セクション、2周して合格することが出来ました。
他の記事などで、30セクション3周で問題なく合格できるなど見かけました。私は集会の回数より数多くの問題をなるべく多く解いておくことをお勧めします。

性格の問題もあると思うので、下記の内容が良いと思ったら実践してみてください。
※合致しない方は、参考程度に見てってください。

・1周目の時には、とにかく一個一個のサービスの内容や実際に間違いとなる部分を徹底して押さえて学習する
例）Lambdaは使い勝手がいいが、15分の制約やオーバーヘッドには不向き→どんな質問の時に選ばれるのか？？
・時には似たサービスの比較をChatGPTに訊いたりして学習すると効率的に勉強できます。
例）ChatGPTへの質問内容：オンプレからAWSへ移行するときのデータの送り方が複数あるがどんなユースケースの時にどのサービスが選ばれるのか、詳しい説明と比較も載せて説明して
・時間に余裕がある場合はAWSのコンソール画面で簡単に作成しようとしてください。
様々な項目が必要で、その内容を質問されるので良い学習になります。


## 最後に
SAAの学習をしたことで、AWSサービスを網羅的に学ぶことが出来ました。AWSのベストプラクティスを知り、セキュアでコスト効率を考慮した設計を学ぶことが出来たので、今後の業務に生かしていきます。

ここまで読んでいただきありがとうございました。
皆さんの合格を願っております。
【初心者向け】make initでDocker環境構築に失敗した話とその対処法

# はじめに

DockerとMakefileを使ってFuelPHPのシステム環境を構築しようとしたところ、`make init` 実行時にエラーが発生し、環境構築に失敗しました。

最終的には、**Makefileの処理を1行ずつ実行することで原因を突き止めることができた**ため、今回はその過程と学びを共有します。

# `make init`とは？

`make init` はMakefileで定義された初期化処理を一括で実行するコマンドです。  
主に、以下のような処理をまとめて行います：

- `.env` ファイルのコピー
- Dockerコンテナのビルド・起動
- マイグレーションの実行 など

チーム開発で環境構築の手順を統一するのに便利ですが、トラブル時は中の処理を理解する必要があります。

## Makefileの例（抜粋）

```make
init:
	cp .env.example .env
	docker-compose build
	docker-compose up -d
	php artisan migrate
```

# 発生した問題
以下のような現象が発生し、make init が途中で失敗しました。

- php artisan migrate の実行でエラーが発生
- 必要なDBコンテナがビルド直後に停止
- 不要なDBコンテナがなぜか立ち上がっている
- .env を手動で修正しても、再度上書きされてしまう
- ビルドが完了しないため、アプリを立ち上げられない

# 原因と対処
## 原因の特定方法
make init で行っている処理を 1行ずつ手動で実行し、どこで問題が発生しているかを確認しました。

特に注目したのは以下の点：
- .env.example を上書きコピーしているせいで、自分で編集した .env が毎回リセットされていた
- .env の COMPOSE_FILE に適切な値が設定されていなかった

## COMPOSE_FILE によるYAML切り替え
このプロジェクトでは、docker-compose.db.yml や docker-compose.app.yml のように、用途別に Compose ファイルが分かれており、.env の中の COMPOSE_FILE 変数で どのYAMLファイルを使うかを切り替える運用 になっていました。

```env
# .envの例
COMPOSE_FILE=docker-compose.app.yml
```
しかし、make init の最初で .env.example を強制的に上書きしていたため、手動で設定した COMPOSE_FILE が毎回リセットされ、想定していないコンテナ構成でビルド・起動していたことが、環境構築失敗の大きな原因でした。


## 解決方法
.env.example を事前に正しく修正し、make initを実行する。
本番環境などで見られてはいけない情報を .env に含める場合は、make init から cp .env.example .env を削除する



# 学びと反省
- まずはエラーメッセージの原因を切り分ける：一気に全部実行せず、1ステップずつ確認が有効
- AIに投げる前に現状を整理する：ChatGPTなどに相談する際も、何が起きているかを把握してから
- Makefileや.envの仕組みを理解することがトラブル対応の鍵になる

# おわりに
一見便利な make init ですが、何をしているのかを把握せずに使うとトラブル対応に時間がかかります。
トラブルシュートの第一歩は、「どこで」「何が」起きているかを冷静に確認することだと、今回の件で痛感しました。
【Mac】システム設定をopenコマンドで表示する方法

## システム設定を表示

ターミナルからシステム設定を表示するには以下のコマンドを実行します。

```terminal
open -a "System Settings"
```

または

```terminal
open "/System/Applications/System Settings.app"
```

システム設定の「一般」パネルが表示されます。

## 特定のパネルを開く

以下のようにすると特定のパネルを指定して表示できます。

```terminal
open "/System/Library/PreferencePanes/パネル.prefPane"
```

「外観」パネルを表示するには次のようになります。

```terminal
open "/System/Library/PreferencePanes/Appearance.prefPane"
```

指定できるパネルの一覧は`ls /System/Library/PreferencePanes/`で取得できます。

```terminal
$ ls /System/Library/PreferencePanes/
Accounts.prefPane/                 Mouse.prefPane/
Appearance.prefPane/               Network.prefPane/
AppleIDPrefPane.prefPane/          Notifications.prefPane/
Battery.prefPane/                  Passwords.prefPane/
Bluetooth.prefPane/                PrintAndFax.prefPane/
ClassKitPreferencePane.prefPane/   PrintAndScan.prefPane/
ClassroomSettings.prefPane/        Profiles.prefPane/
DateAndTime.prefPane/              ScreenTime.prefPane/
DesktopScreenEffectsPref.prefPane/ Security.prefPane/
DigiHubDiscs.prefPane/             SharingPref.prefPane/
Displays.prefPane/                 SoftwareUpdate.prefPane/
Dock.prefPane/                     Sound.prefPane/
EnergySaver.prefPane/              Speech.prefPane/
EnergySaverPref.prefPane/          Spotlight.prefPane/
Expose.prefPane/                   StartupDisk.prefPane/
Extensions.prefPane/               TimeMachine.prefPane/
FamilySharingPrefPane.prefPane/    TouchID.prefPane/
InternetAccounts.prefPane/         Trackpad.prefPane/
Keyboard.prefPane/                 UniversalAccessPref.prefPane/
Localization.prefPane/             Wallet.prefPane/

```
GhPythonで緯度経度を平面直角座標に変換する

# はじめに
4年前には[**「GhPythonで平面直角座標を緯度経度に変換する」**](https://qiita.com/reisyu/items/bca9d5025ee495783420)をやったけど今回は逆に緯度経度を平面直角座標に変換したくなった

前回と同じく[**「緯度経度と平面直角座標の相互変換をPythonで実装する」**](https://qiita.com/sw1227/items/e7a590994ad7dcd0e8ab)を参考にしてます。**@sw1227** さんありがとうございます！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433170/e89f6cb7-5868-4986-aaff-15602e40b1b6.png)

# 変えたところ
GhPython では numpy を使えないので・・・
　・math で使える関数に置き換えた
　・np.array をリストに置き換えた
　・np.dot を for文で書き直した
といったあたりを変更

# GhPythonで作成
Type hint はすべて float にする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433170/b3fb6bbc-f9a6-7b36-9a16-d3176d51cab2.png)

コードはこちら

```python
import math

""" 緯度経度を平面直角座標に変換する
- input:
    (lat_deg, lon_deg): 変換したい緯度・経度[度]（分・秒でなく小数であることに注意）
    (lat0_deg, lon0_deg): 平面直角座標系原点の緯度・経度[度]（分・秒でなく小数であることに注意）
- output:
    x: 変換後の平面直角座標[m]
    y: 変換後の平面直角座標[m]
"""
# 緯度経度・平面直角座標系原点をラジアンに直す
phi_rad = math.radians(lat_deg)
lambda_rad = math.radians(lon_deg)
phi0_rad = math.radians(lat0_deg)
lambda0_rad = math.radians(lon0_deg)

# 補助関数
def A_array(n):
    A0 = 1 + (n**2)/4. + (n**4)/64.
    A1 = -     (3./2)*( n - (n**3)/8. - (n**5)/64. ) 
    A2 =     (15./16)*( n**2 - (n**4)/4. )
    A3 = -   (35./48)*( n**3 - (5./16)*(n**5) )
    A4 =   (315./512)*( n**4 )
    A5 = -(693./1280)*( n**5 )
    return [A0, A1, A2, A3, A4, A5]

def alpha_array(n):
    a0 = None # dummy
    a1 = (1./2)*n - (2./3)*(n**2) + (5./16)*(n**3) + (41./180)*(n**4) - (127./288)*(n**5)
    a2 = (13./48)*(n**2) - (3./5)*(n**3) + (557./1440)*(n**4) + (281./630)*(n**5)
    a3 = (61./240)*(n**3) - (103./140)*(n**4) + (15061./26880)*(n**5)
    a4 = (49561./161280)*(n**4) - (179./168)*(n**5)
    a5 = (34729./80640)*(n**5)
    return [a0, a1, a2, a3, a4, a5]

# 定数 (a, F: 世界測地系-測地基準系1980（GRS80）楕円体)
m0 = 0.9999 
a = 6378137.
F = 298.257222101

# (1) n, A_i, alpha_iの計算
n = 1. / (2*F - 1)
A_array = A_array(n)
alpha_array = alpha_array(n)
    
# (2), S, Aの計算
A_ = ( (m0*a)/(1.+n) )*A_array[0]
S_ = ( (m0*a)/(1.+n) ) * (A_array[0]*phi0_rad + sum([A_array[j]*(math.sin(2*phi0_rad*j)) for j in range(1,6)]))

# (3) lambda_c, lambda_sの計算
lambda_c = math.cos(lambda_rad - lambda0_rad)
lambda_s = math.sin(lambda_rad - lambda0_rad)

# (4) t, t_の計算
t = math.sinh( math.atanh(math.sin(phi_rad)) - ((2*math.sqrt(n)) / (1+n))*math.atanh(((2*math.sqrt(n)) / (1+n)) * math.sin(phi_rad)) )
t_ = math.sqrt(1 + t*t)

# (5) xi', eta'の計算
xi2  = math.atan(t / lambda_c) # [rad]
eta2 = math.atanh(lambda_s / t_)

# (6) x, yの計算
x = A_ * (xi2 + sum(
    alpha_array[n] * math.sin(2 * xi2 * n) * math.cosh(2 * eta2 * n)
    for n in range(1, 6))) - S_

y = A_ * (eta2 + sum(
    alpha_array[n] * math.cos(2 * xi2 * n) * math.sinh(2 * eta2 * n)
    for n in range(1, 6)))


```

# 参考
[緯度経度と平面直角座標の相互変換をPythonで実装する](https://qiita.com/sw1227/items/e7a590994ad7dcd0e8ab)
[緯度経度と平面直角座標の相互変換を実装するための数式](https://qiita.com/sw1227/items/e7a590994ad7dcd0e8ab)
Flask × Nginx でWebサーバを構築してみた｜シリーズ概要と完成形の紹介【第1回】

## Flask × Nginx でWebサーバを構築してみた
今回は、自宅Linuxサーバ上で Flask + Nginx 構成のWebサーバを構築した記録を、シリーズ記事として残していきます。

この第1回では、完成形の概要を共有し、次回以降で導入技術ごとの詳細を解説します。

### 本シリーズの目標
- Nginxリバースプロキシを通してFlaskアプリを外部公開
- セキュリティ対策として UFW を活用したポート制限
- HTTPS（443）を Let’s Encrypt などで実装

## なぜWebページを公開したのか？

今回Webサーバを外部に公開したのは、自分が学んだことを“見える化”したいと考えたからです。

最近キャリアを見直す中で、「転職活動を意識するなら、自分が勉強してきた内容をアウトプットとして残しておくことが大事」だと感じました。
Qiita記事やコードだけでなく、実際に動作するWebページを公開することで、自分の技術力をよりリアルに伝えられると考えたのが背景です。

また、公開することでモチベーションも上がり、今後はより面白い機能やUI改善なども取り入れて自分の技術力と同時に成長するWebサーバーとして活用できると思いました。


## 実際に動いているページ紹介
WebページURL：
http://termnix-it.tplinkdns.com


- 公開環境：自宅サーバ（Ubuntu）で常時稼働中
- 公開ポート：HTTP（80番）にてアクセス可能
- セキュリティ：UFW にて制限あり、HTTPSは後日対応予定
- メンテナンス予定：不定期（開発中のため、稼働が一時的に止まることがあります）

## 使用した技術スタック
|要素|詳細|
|---|---|
|OS|Ubuntu系Linux|
|Webサーバ|Flask (localhost:5000)|
|プロキシ|Nginx (ポート80/443)|
|Firewall|UFW（80番ポートのみ許可）|
|ルーター|TP-Link Archer AX23（ポート転送使用）|

## 構成図
下図が今回の構成になります。
![スクリーンショット 2025-06-18 221244.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4092000/3b952d9d-e44d-4cc9-94a8-ab7202e49bdc.png)

外部（スマホ/PC）から HTTPリクエストをルーター経由で転送し、NginxがFlaskアプリに渡す構成です。現在はHTTP（ポート80）のみ開放しており、HTTPSは後日対応予定です。

## 今後の記事予定（リンクは随時追加）
- 第2回	【Flask編】Pythonで簡単Webアプリ構築
- 第3回	【Nginx編】Flaskアプリを外部公開する方法
- 第4回	【Firewall/ポート設定編】安全に公開するための基本設定

## まとめ
構築系の記事は一度に書こうとすると情報量が多くなるため、完成形を見せた上で分割解説する形式を取ります。
次回は【Flask編】として、ローカルで簡単なWebアプリを立ち上げるところから始めていきます！

>追記（執筆者メモ）
>作業環境：Ubuntu Server / VSCode Remote / ローカル開発→本番反映の2段構成
>使用エディタ：Cursor（VSCodeベースのAI対応エディタ）
>最終更新：2025年6月18日
SharePointサイトページが編集中かどうかをチェック

本日はSharePointサイトをPowerAutomateを使用して管理するときに役立つ（かもしれない）小ネタ。

# Problem

SharePointサイトのサイトページ（SitePages）の項目が誰かしらによって編集中かどうかを知りたい。
PowerAutomateを使って当該項目（サイトのページ）のプロパティを編集する必要があり、その編集のときに他のユーザーの編集と競合をするのを避けたいがため。

# Solution

バージョン番号の値で判断する。

バージョン番号は 小数で表される。例えば `1.0` とか `1.3` とか `10.2` とか `21.0` とか。
小数部が `0` のものはメジャーバージョンと言われ、サイトのページでいうと公開前の変更がない状態。
逆に小数部が `0` でないものはマイナーバージョンと言われ、公開前の変更がある状態。下書きが存在していたり、チェックアウトがされている状態。コンテンツにはまったく変更がない状態でも、下書き保存やチェックアウトをすると自動的にマイナーバージョンが発生する。

SharePointコネクターの「項目の取得」アクションや「複数の項目の取得」アクションで得られた値から判断するのであれば、`{VersionNumber}`（動的コンテンツの表示名としては「バージョン番号」）を利用。「複数の項目の取得」アクションで得られた値を絞り込むなら「アレイのフィルター」で `endsWith(item()['{VersionNumber}'], '.0')` みたいな式を記述することになる。

アクションのイメージ：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/aab19010-a5fe-479a-aa73-bcde61ab7757.png)

レスポンスのイメージ：
```json
{
    "statusCode": 200,
    "headers": {
        ...
    },
    "body": {
        "value": [
            {
                ...
            },
            {
                ...
                "ItemInternalId": "22",
                "ID": 22,
                "Title": "Example",
                "PromotedState": 0,
                "{VersionNumber}": "38.3",
                ...
            },
            {
                ...
            },
        ]
    }
}
```

「複数の項目の取得」アクションの入力パラメーターであるフィルタークエリーで条件指定する場合 `OData__UIVersionString` 列を利用して `OData__UIVersionString eq '1.0'`などと記述することになる。しかしPowerAutomateの場合 `endswith`演算子に対応していないようなので柔軟性に欠ける。

SharePointコネクターの「SharePointにHTTP要求を送信します」アクションでREST APIに直接データを要求する場合は `_api/web/lists/GetByTitle('サイトのページ')/items({id})/File` エンドポイントを利用し、プロパティ `UIVersionLabel` や `MinorVersion` を利用。前者は小数の文字列表現で、後者は小数部のみの整数表現。

アクションのイメージ：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/4e54d882-640e-4d1e-b5cb-d458096f6fef.png)

レスポンスのイメージ：
```json
{
    "statusCode": 200,
    "headers": {
        ...
    },
    "body": {
        "d": {
        　  ...
            "MajorVersion": 38,
            "MinorVersion": 3,
            "Name": "CollabHome.aspx",
            "Title": "Example",
            "UIVersion": 19459,
            "UIVersionLabel": "38.3",
            ...
        }
    }
}
```

`_api/web/lists/GetByTitle('サイトのページ')/items({id})` エンドポイントを利用してもよいが、その場合はプロパティ `OData__UIVersionString` を利用。

アクションのイメージ：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/13b2a276-b8c9-4fc9-b158-a62822d83fef.png)

レスポンスのイメージ：
```json
{
    "statusCode": 200,
    "headers": {
        ...
    },
    "body": {
        "d": {
            ...
            "Id": 22,
            "Title": "Example",
            "PromotedState": 0,
            "FirstPublishedDate": null,
            "OData__UIVersionString": "38.3",
            ...
        }
    }
}
```

# Yodan

この解決策を見つけ出すために Microsoft365 Copilotに山程質問をしてたくさんのヒントを貰いました。
SharePointのサイトページの仕様、ライブラリーやリストの仕様、そしてそれらにアクセスするREST APIの仕様・・・Web上に散在していてどこにあるかもわからないアレヤコレヤをまとめてロジカルに説明してくれるのには大変助かりました。いい時代になりましたね。。
マイクロソフトCEOが言った”AIでSaaSアプリの消滅する”に関して

マイクロソフトのCEOであるサティア・ナデラ氏が、SaaS（Software as a Service）アプリケーションの未来について衝撃的な発言をしました。彼の発言の要点は以下の通りです。

多くのアプリケーションを保有しているマイクロソフトナデラCEOが現在保有しているアプリケーションEXCELやWordなどが消えるという話です。その強烈な危機感を伝えるメッセージなのでとても印象深いです。

# SaaSアプリケーションの「終焉」とAIエージェントの台頭
- **SaaSは「死んだ」？** : ナデラ氏は挑発的に「SaaSは死んだ」と発言しましたが、これはSaaSが文字通り消滅するという意味ではなく、その形態が大きく進化するということを強調しています。彼は、AIエージェントの台頭によって、従来のビジネスアプリケーションが根本的に変革されると言ってます。
- ビジネスロジックのAI層への移行** : 従来のSaaSアプリケーションは、GUI（グラフィカルユーザーインターフェース）を持つCRUD（Create, Read, Update, Delete）データベースにビジネスロジックが組み込まれたものだとナデラ氏は指摘してるんです。しかし、今後はこのビジネスロジックがAI層に移行し、AIエージェントが複数のデータベースやアプリケーションを横断してロジックを管理するようになると予測しています。私も個人的に同意します。
- **バックエンドシステムの崩壊** : AIがロジックの中心となることで、従来のバックエンドシステムは「崩壊」し、AIエージェントがマルチリポジトリのCRUD操作を複数のデータベースにわたって処理するようになります。これにより、ユーザーは個々のアプリケーションにログインすることなく、よりシームレスなワークフローを利用できます。これもAIエージェントの実現可能な領域です。
- **インターフェースの不要化** : AIエージェントが直接データベースとやり取りできるようになるため、人間が操作するためのGUIすら不要になる可能性があると示唆しています。すなわち既存のインターフェースは消滅するってことなんです。
- **「エージェント・ファースト」の時代** : 今後数年で、AIエージェントはスプレッドシートのように日常的に構築・利用されるようになり、あらゆるビジネスプロセスに不可欠な存在になるとナデラ氏は述べています。ググるの代わりにエアルってこと？

# SaaS企業への影響と機会
- **既存SaaSビジネスへの攻撃** : ナデラ氏は、このAIエージェントへのシフトは、既存のSaaS企業にとって大きな「攻撃ベクトル」となり得ると警告しています。AIエージェントを積極的に取り入れるSaaS企業は、大きな機会を得るでしょう。はやくAI化しないと生き残れないよってことですね。
- **課金などビジネスモデルの再考** : 従来のSaaSのライセンスモデル（ユーザー数やシート数ベース）から、AIエージェントがタスクをこなすことによるシステム全体の効率や成果に基づいた消費ベースのモデルへと変化していく可能性があります。課金モデルも柔軟に変化しないと生き残れないよとも言ってる。
- **AIネイティブSaaSの台頭** : 彼の発言は、「SaaS is Dead」論として業界に大きな波紋を広げましたが、SaaS業界自体は引き続き成長すると予測されており、AI機能を中核に据えた「AIネイティブSaaS」が増加すると予測してます。ナデラ氏のメッセージは、AIがビジネスアプリケーションの「オペレーティングシステム」そのものとなり、ソフトウェアの利用、管理、ライセンスのあり方を根本的に変えるという、パラダイムシフトの始まりを告げるものです。企業や開発者は、この変化に適応し、AIエージェントを活用した新たな価値創造に注力する必要があるとしています。
- 
OSやSaaSアプリを提供しているマイクロソフトCEOのメッセージはメチャ説得力があったので要約して伝えることにしました。

  **Initial KA**
C#入門・勉強しながらアウトプット #01

# C#とは？

様々な言語がある中の一つであり、Microsoftが開発したオブジェクト指向のプログラミング言語です。
よく、C言語やC++と一緒に話題に上がる（気がします）が、全くの別物といっても過言ではありません。

### C言語
  C言語は、コンピューターに近い「低級（低レベル）」言語です。
  主に組み込みシステムやOS、ソフトウェアの開発に使用されます。
  
### C++(シープラプラ・シープラ)
  C++は、C言語にオブジェクト指向の要素を追加した言語で、C言語より効率的に開発を行うことができます。
  C言語との互換性が高く、軽量かつ高速なアプリケーションの開発に適しています。
  よく知られている使用例としては、Unreal Engine（ゲーム開発エンジン）などがあります。
  高速な処理が必要な場面で利用されることが多いです。

### C#(CSharp・シーシャープ)
  C++をさらに改良し、より高級（高水準）な言語として設計されたのがC#です。
  C++とは互換性がありません。
  低級言語のC言語に比べて、よりスピーディーかつ効率的な開発が可能となっています。
  Unity（ゲーム開発エンジン）を使ったゲーム制作や、.NETを用いたアプリケーション開発などに利用されます。


:::note info
プログラミング言語でよく耳にする「低級言語（低レベル言語）」や「高級言語（高水準言語）」とは、「難しい／簡単」といった意味ではなく、
コンピューター（機械語）に近いか、人間にとって読み書きしやすいかという違いを表す表現です。
「低レベル」と言われても、決して簡単な言語というわけではありません。
:::

C言語やC++が使えるからといってC#が使えるとは限りませんし、逆にC#ができるからといってC言語やC++が扱えるようになるわけでもありません。
メモリ管理の考え方などが大きく異なるため、C#に慣れているとC言語やC++は不便に感じることがあるかもしれませんし、
逆にC言語やC++に慣れていると、C#はとても便利な言語だと感じるでしょう。
（そもそも、使用用途が全然違うので比べることはないのですが・・・）

## なぜC#を選んだのか
私自身、HSPやVBA,VBと言ったVB関連の言語を触ることが多かったのですが、
ドキュメントの多さ・言語の将来性を考えたときに、やはりC#が良いのではと感じました。
一昔前は、C#について調べると、一緒にVBのコードも載せていることが多かったのですが、最近では、C#のみのコードが記載されることも多くなってきました。
VBは、新しい機能の追加はなくなり言語としての発展はないことが宣言されています。
（参考：[Visual Basic Blog](https://devblogs.microsoft.com/vbteam/visual-basic-support-planned-for-net-5-0/)）
サポートはされるものの、今後自身のキャリアや将来性を考えたとき、今のうちにC#へ乗り移ろうと考えた次第です。
また、マルチプラットフォーム・Webアプリケーション・ゲーム開発など多岐にわたって行うことができます。
…あと、会社の標準言語がC#だったというのも理由の一つです（笑）


## C#を使うと何がいいのか
Microsoftが開発したということもあり、結構ドキュメントがそろっています。
公式も、個人ブログも併せて調べればたいていのことは検索に引っかかります。
また、前述でもしたように、C言語/C++のさらなる進化を遂げたのが、C#となっており、
C言語やC++と違って、メモリの管理を自動で行ってくれます。
このメモリの管理は結構大事で、これを行わないと[メモリーリーク](https://wa3.i-3-i.info/word16066.html)を起こします。

これらに意識を向けなくても開発が行えることは最大のメリットでしょう。
そもそも、高級言語は言語レベルでメモリ管理をしてくれるため低級言語を触らない限りは
意識しなくてもよい問題です。

余談ですが、C言語にプラスされたのが C++、
C++にさらにプラスされたものが C#(C++++プラスが4つあることを表現している)と聞いたことがあります。

また、Visual Studioという統合開発ツールで開発をすることができ開発者はスピーディーに開発を行うことができます。
最近は、GitHub CopilotというAIを駆使して開発が行うことができ、よりスピーディーなコーディングが可能となっています。


## 環境構築はすごく楽
ほかの言語に比べて、環境構築はとても楽になっていると感じています。
[Visual Studio](https://visualstudio.microsoft.com/ja/)をインストールすることで、すぐにC#のコーディング・実行が可能です。
Visual Studio Community を使用すれば無料で開発統合ツールを使用することができます。

## まとめ。
多岐にわたる開発が可能で、統合開発ツールが無料で使用できる。
ドキュメントやコミュニティが多く、情報の収集には事欠かない。
これが、C#を選ぶ最大のメリットでしょうか。

最近はGitHub Copilotで開発の速度を格段に上げることができます。

次回は、コーディングの基礎などをお伝えできればと思います。

まだまだ勉強の身ですので何か間違いがあればご指摘いただければ幸いです。
【知らんでも死にはせん】けど知っといたほうがいい「トランザクション署名」の話

---

【知らんでも死にはせん】けど知っといたほうがいい「トランザクション署名」の話

> AWSやと“当たり前”みたいに出てくるけど、
よくよく考えたら「…それってどういう意味なん？」ってなるやつ、ありますよね。



そのひとつがトランザクション署名。

「署名」って聞いたら、
「HMAC-SHA256でハッシュとって…秘密鍵と組み合わせて…まぁなんかセキュアになるんやろ？」
──そう思ってるあなた（昔の僕）、いったん深呼吸してください。


---

✅ この記事でわかること

トランザクション署名って、そもそも何のためにあるん？

AWSでの使われ方（特にAPIリクエスト周り）

「どうセキュアなのか」って、人に説明できる？

ややこしそうに見えるけど、意外とスッと入ってくる構造の話



---

🍵 そもそも「署名」って何のためにやるん？

何かデータ送るときに、「ほんまにこの人から送られてきたもんやで」って証明するための仕組みですね。
ちょっと大げさに言えば、「このメッセージ、誰にも書き換えられてへんで」っていう“データの正当性の証明”みたいなもん。


---

🧾 トランザクション署名って何やねん

AWSでよく見るのが「SigV4（署名バージョン4）」
例えばaws s3 lsみたいなコマンド、
裏側ではHTTPリクエストに「署名ヘッダ」がくっついてます。

ここでいう「トランザクション」ってのは、
簡単に言うと「APIリクエスト」そのもののこと。


---

🔒 なんでそこまでして署名すんの？

悪意ある人が偽のリクエスト送ってきたら困るからです。
リクエストの中身（メソッド、エンドポイント、パラメータ、時刻…）を全部まとめてハッシュ化して、
それに秘密鍵（IAMユーザーのやつ）で署名しておけば、

誰が送ったか

中身が途中で書き換えられてへんか


がチェックできる。めっちゃ地味やけど、めっちゃ大事なやつ。


---

🧠 イメージしづらいときのたとえ話（ざっくり）

友達に「この手紙ほんまに俺が書いたんやで」って証明したかったら、
手紙にサイン書いて、印鑑も押して、封筒にロウで封して送る…みたいな。

→ 読み手（AWS側）は「これ、ちゃんと正しい鍵で署名されてるな。OK通してよし」ってなる。


---

✅ まとめ

トランザクション署名＝「APIリクエストに対して本人確認と改ざん防止のために署名する仕組み」

AWSのCLIやSDKは裏でこれを自動でやってくれてる（から普段あんま意識しない）

でも仕組みを知っておくと、トラブルのときに強い



---

🎯 ちょっと確認してみる？

「トランザクション署名、何のためにやってる？」
→ 「本人確認と改ざん防止」

「署名って、何に対して行う？」
→ 「APIリクエスト全体」


---

もしよかったら、次は**「S3署名付きURL」**とかもセットで読むと理解深まりますよ。
[Linux] クロック設定_NTP, ntpdate, ntpd, /etc/ntp.conf

# /etc/ntp.conf
* `ntpd` による **NTP（Network Time Protocol）** の設定ファイル
* システムクロックをインターネット上やローカルネットワークの時刻サーバと同期するために使用される
* [解説](https://qiita.com/Jochun/items/6ac664fe2f41ef79e9c2#%E3%82%AF%E3%83%AD%E3%83%83%E3%82%AF%E8%A8%AD%E5%AE%9Antp)

## `/etc/ntp.conf` の記載例（`pool.ntp.org`使用）

```plaintext:/etc/ntp.conf
driftfile /var/lib/ntp/ntp.drift

pool 0.pool.ntp.org iburst
pool 1.pool.ntp.org iburst
pool 2.pool.ntp.org iburst
pool 3.pool.ntp.org iburst

restrict default nomodify notrap nopeer noquery
restrict 127.0.0.1
restrict ::1
```



## 各行の説明（修正後）

| 行                                                                     | 説明                                                         |
| :-------------------------------------------------------------------- | :--------------------------------------------------------- |
| `driftfile /var/lib/ntp/ntp.drift`                                    | クロックの誤差（ドリフト）を保存するファイル                                     |
| `pool 0.pool.ntp.org iburst`<br>`...`<br>`pool 3.pool.ntp.org iburst` | 複数の NTP サーバプールを指定<br>可用性や負荷分散に優れる |
| `restrict default nomodify notrap nopeer noquery`                     | 外部からのNTP操作を制限<br>`query`・`modify` などの操作を禁止             |
| `restrict 127.0.0.1`<br>`restrict ::1`                                | ローカルホストからのアクセスを許可                                      |



# 補足：NTPパッケージ
- CentOS, RHEL: `ntp` パッケージ（`/etc/ntp.conf` を読み込み）
- Ubuntu: `ntp` パッケージ（`/etc/ntp.conf` を読み込み）
- CentOS 8 以降: `chrony` パッケージ(`/etc/chrony.conf` を読み込み)


# 参考リンク
- [[Linux][directory] ディレクトリ一覧_LPIC-1 102](https://qiita.com/Jochun/items/6ac664fe2f41ef79e9c2#%E3%82%AF%E3%83%AD%E3%83%83%E3%82%AF%E8%A8%AD%E5%AE%9Antp)

# Ping-t
- [4777_ntpd](https://mondai.ping-t.com/question_subjects/32/question_sessions/33867186/progressing_questions/518471900)
- [4805_/etc/ntp.conf](https://mondai.ping-t.com/question_subjects/32/question_sessions/33866047/progressing_questions/518453899)
- [4808_/etc/ntp.conf, pool.ntp.org](https://mondai.ping-t.com/question_subjects/32/question_sessions/34000185/progressing_questions/520498139)