OmniAICreator/Qiita-1.07M huggingface dataset:
汎用的ServiceLocatorを作ろうとしたときの注意点

# はじめに
お手軽に作れてサービスを集約させることのできる「ServiceLocator」ですが、登録と取得、削除のみでは使いづらいと思って関数を追加する人も多いと思います。その時に起きがちなミスを紹介します。

# 通常のServiceLocator
一番スタンダードなServiceLocatorの組み方はこのようになると思います。
```cs
public static class ServiceLocator
{
    private static Dictionary<Type, object> _dic = new();

    /// <summary>
    /// サービスロケーターに登録する
    /// </summary>
    public static void Register<T>(T instance)
    {
        if (_dic.ContainsKey(typeof(T)))
        {
            _dic[typeof(T)] = instance;
        }
        else
        {
            _dic.Add(typeof(T), instance);
        }
    }

    /// <summary>
    /// サービスロケーターからインスタンスを取得する
    /// </summary>
    public static T Get<T>()
    {
        return (T)_dic[typeof(T)];
    }

    /// <summary>
    /// サービスロケーターから登録解除する
    /// </summary>
    public static void Unregister<T>()
    {
        if (_dic.ContainsKey(typeof(T)))
        {
            _dic.Remove(typeof(T));
        }
    }
}
```
`Register<T>`でインスタンスを登録し、`Get<T>`で取得、`Unregister<T>`で登録解除するシンプルな構造です。
Getで取得できない場合に明示的なエラーを出すかnullを返すかすべきですが今回は省略します。

# 設計
そもそもServiceLocator自体がアンチパターンと言われることが多いです。
コードからクラスの依存関係を判断しづらいことや、依存関係の検証が実行時に行われるためnull参照が起こりやすいなど、依存関係にかなりの難があるからです。
プロジェクトの規模によってはこれを使う判断をしてもいいと思います。ただし、汎用性を上げようとして、Getメソッドの中に生成を含めたコードを書くのはアウトです。
設計の知識はそこまで豊富なわけじゃないのでこんなこと書くつもりなかったのですが生成を含んだServiceLocatorを見てしまったので書いておきます。
どういうことかというと、下のコードのようにGetメソッドを実行したときにインスタンスが登録されていなければ生成するというもの。
```cs
public static T Get<T>() where T : class
{
    if (_dic.ContainsKey(typeof(T)))
    {
        return (T)_dic[typeof(T)];
    }
    return Activator.CreateInstance(typeof(T)) as T;
}
```
おそらく目的は取得したいときにエラーが出てしまったから出ないように生成するというものでしょう。
やってはいけない理由は次のことが挙げられます。
- 単一責任の原則に反する
- 登録の順序によってはインスタンスが異なるため処理の内容が変わってしまう
- 引数付きコンストラクタの生成ができない
後ろ二つは特に、設計関係なくバグが発生する原因にもなる理由なのでServiceLocatorに生成を含めるのは控えましょう

# メモリ
過去にサービスロケーターを作ったとき、クラスにジェネリック引数をつけていました
```
public static class ServiceLocator<T> // ここで登録する型を書いてしまう
{
    private static Dictionary<Type, T> _dic = new();

// ・・・省略
```
使うときは次のような感じ。
```
ServiceLocator<ClassA>.Register(new ClassA());
```
これは一見何も問題ないように見えますが、メモリに無駄が生じます。
静的クラスは参照が発生するとアプリの終了まで常にメモリに存在し続けます。
これがジェネリック引数をつけるとその引数に指定した型の数だけ別々のメモリアドレスが割り当てられるそうです。
つまり、`ClassA`を登録した場合`ServiceLocator<ClassA>`として、`ClassB`を登録した場合`ServiceLocator<ClassB>`としてメモリに保存されます。
また、サービスロケーター内で定義している`_dic`は常に一つのクラスしか保存されないです(_dic.Countが常に1になる)。

# パフォーマンス
サービスロケーターを作る側は対策できないことですが、サービスロケーターに値型を登録するとボックス化され、取得する際にもアンボックス化されます。これはメモリ確保のオーバーヘッドになります。
<details><summary>用語</summary>

### 値型
対となる参照型は値への参照が保存されるのに対し、値型はメモリ内に直接保存されます。
intやfloatなどがこれに当たります。

### ボックス化
値型が参照型へ変換されることをボックス化といいます。
特にobject型にしたりinterfaceにしたりすると発生します。
今回では`Register<T>(T instance)`で登録する際、ここにstruct(構造体)で定義した`MyStruct`を登録しようとした場合、サービスロケーター内のDictionaryが`<Type, object>`で定義されているため、object型にボックス化されると表現できます。

### アンボックス化
ボックス化の逆の操作で、先ほどの例を使うと登録された`MyStruct`を取り出す際、object型からMyStruct型に変換するとき参照型から値型に変換されます。

</details>

# まとめ
今回はこれまでの経験をもとにServiceLocatorを作る際の注意点を「設計」「メモリ」「パフォーマンス」の項目に分けて説明しましたが、このように拡張しようとしているということは現在のサービスロケーターが不便に感じているのだと思います。
少し学習コストは高くなりますが「DependencyInjection」通称`DI`について学んでみるのがいいと思います。
SEO対策で、JSON-LDを導入してみた

## はじめに
SEO対策でJSON-LDを導入してみたので、導入手順等まとめておきます。

途中私の解釈も書いていますが、正確な最新情報はぜひ各ドキュメントをご参照ください！

## JSON-LDとは
構造化マークアップの形式の一つで、Googleが利用を推奨しています。
ページごとの構造に合わせて、適切な構造をクローラーに伝えられる代物です。
構造の例）記事、商品、FAQ、組織、求人、レシピ、口コミ抜粋 etc

## その他の構造化マークアップ導入形式
- microdata
- RDFa

というものがあるそうです。
ただ、Google先生いわく、
> 一般的に、Google はサイトの設定で許容されている限り、JSON-LD を構造化データに使用することを推奨します。これは、ウェブサイトの所有者が実装と管理を最も容易に行うことができる（つまり、ユーザーエラーの発生する可能性が低い）ソリューションであるためです。

とのこと。

何かしらの事情でHTMLタグを使って構造を記述したい場合は、JSON-LD以外のものが選択肢になりそうです。

## JSON-LD導入のメリット
主に以下2点と認識しています。
### リッチリザルト
Googleの検索結果の画面で、"リッチ"に出ます。

商品情報やFAQ、レビュー情報などがサイトに遷移せずとも見られるというものです。密度の高い情報を検索結果画面で届けることで、サイトへの流入やクリック率がアップする可能性があります。

### SEO効果
クローラーが正確に情報を認識しやすくなります。
具体的な成果の事例は、Googleが以下のように記載していました。
>- Rotten Tomatoes では、構造化データを 10 万ページに追加した結果、構造化データを含むページでのクリック率が、構造化データのないページに比べ 25% 増加しました。
>- The Food Network では、全ページの 80% で検索結果の機能を有効にした結果、アクセス数が 35% 増加しました。
>- 楽天では、構造化データを実装したページでのユーザーの滞在時間が、構造化データのないページに比べ 1.5 倍長くなりました。また、検索機能がある AMP ページでのインタラクション率は、検索機能がない AMP ページに比べ 3.6 倍高くなっています。
>- Nestlé では、検索でリッチリザルトを表示するページのクリック率が、表示しないページに比べ 82% 高くなっています。

## JSON-LDの導入の仕方
私は以下の流れで導入を行いました。

### どの構造を使うか決める
以下の3つを参考にします。
- schema.org
- Google検索セントラル
- SEOに力入れている他社事例

最低でもGoogleが"必須"と言及しているプロパティを漏れなく対応することが大事かなと。エラーになるとリッチリザルト自体表示されない可能性がありますので。

### 各サイトの構造で使えるプロパティを確定する
たくさんあるので、導入するページが強調したい内容に合わせて、適切にプロパティの構成を決定する必要があります。

:::note info
ちなみにここが一番時間かかりまました。。。どのページで、どの構造/プロパティを使うのか使わないのか、みたいな判断をしないといけない数が多いです。
:::

私の判断軸としては、以下の3つです。
- schema.orgの仕様に沿っている
- Googleの必須、推奨具合
- プロダクトのユーザーにとっての重要な情報かどうか

### 実装する
Googleが提示するサンプルでは、以下のような形式でサイトに挿入するように記載があります。ここをページの構造ごとにカスタマイズしていく形です。
(これはレシピサイトの例のようです)
```
<script type="application/ld+json">
{
  "@context": "https://schema.org/",
  "@type": "Recipe",
  "name": "Banana Bread Recipe",
  "description": "The best banana bread recipe you'll ever find! Learn how to use up all those extra bananas.",
  "aggregateRating": {
    "@type": "AggregateRating",
    "ratingValue": 4.7,
    "ratingCount": 123
  },
  "video": {
    "@type": "VideoObject",
    "name": "How To Make Banana Bread",
    "description": "This is how you make banana bread, in 5 easy steps.",
    "contentUrl": "https://www.example.com/video123.mp4"
   }
}
</script>
```

### 実装した内容をテストする
テストの方法は2つあります。
- [schema.orgの構造化データテスト](https://validator.schema.org/)
- [Googleのリッチリザルトテスト](https://search.google.com/test/rich-results?hl=ja)

両方でエラーがないこと、Googleのリッチリザルトで狙った項目が拾われていることを確認します。

特にGoogleのリッチリザルトテストツールは、推奨項目がないワーニングを出してくれるので、抜けている項目がないかをチェックできて有益でした。

:::note warn
ただし、このツールで検出できないエラーもあるので、テスト通ったから必ずリッチリザルトが表示されるというものでもないそうです。
:::

## まとめ
これからSEO結果にどのような影響があるのか、楽しみです！

## 参考記事
https://developers.google.com/search/docs/appearance/structured-data/intro-structured-data?hl=ja

https://schema.org/
猿でもわかるAIビジネス活用シリーズ 🐵📊 | [第1回] AIを使うべき業界・使うべきでない業界とは？



## 1. はじめに：AIはどこでも使える？いや、使えない場所もある！

最近、どの業界も "AI導入しています！" と言い出す時代になりました。しかし、実際には「AIが得意な業界」と「AIを入れてもコスパ最悪な業界」が存在します。今回は、AIを業務に活用するべき業界と、あまり向いていない業界について、リアルな事例とコード付きで紐解いていきます。

> 🤔 エンジニアの皆さん、クライアントに「AIやりたいんだけど」と言われた時、適切な助言ができますか？

このブログでは、導入効果が高い業界・逆に滑りやすい業界の違いと、実際にどんなAIソリューションを使えるのかを、実務視点でお届けします。

---

## 2. AIが向いている業界とそうでない業界

### ✅ 向いている業界

- **製造業**：異常検知、需要予測、在庫最適化
- **小売・EC**：レコメンド、パーソナライズド広告、需要予測
- **金融業界**：不正検出、信用スコアリング、チャットボット

### ❌ 向いていない業界（現時点では）

- **高コンテクストの接客業**：人間の感情・文脈を強く読む必要がある業務（例：高級ホテルのコンシェルジュ）
- **中小企業で明確なKPIがない部門**：AI導入しても成果を評価しづらいケース
- **人海戦術で十分な単純作業**：自動化コスト > 人件費 の場合

> ⚠️注意：向いていない = 永遠に使えない、という意味ではない。技術進化や業務設計次第で変わります！

---

## 3. 製造業でのAI導入：異常検知の実例

### 🎯 課題
製造ラインでセンサーデータを監視し、機器の異常を早期に検知したい。

### 💡 解決アプローチ
教師なし学習（例：AutoEncoder）を用いた異常検知システムの構築

```python
import numpy as np
from sklearn.preprocessing import StandardScaler
from keras.models import Model
from keras.layers import Input, Dense

# センサーデータ読み込み（ダミー）
data = np.random.normal(0, 1, (1000, 20))
scaler = StandardScaler()
data_scaled = scaler.fit_transform(data)

# AutoEncoder モデル定義
input_dim = data_scaled.shape[1]
input_layer = Input(shape=(input_dim,))
encoded = Dense(10, activation='relu')(input_layer)
decoded = Dense(input_dim, activation='linear')(encoded)
autoencoder = Model(inputs=input_layer, outputs=decoded)
autoencoder.compile(optimizer='adam', loss='mse')

# 学習
autoencoder.fit(data_scaled, data_scaled, epochs=10, batch_size=32)

# 再構成誤差を計算し、閾値以上なら異常と判定
reconstructions = autoencoder.predict(data_scaled)
mse = np.mean(np.square(data_scaled - reconstructions), axis=1)
thresh = np.percentile(mse, 95)
anomalies = mse > thresh
print(f"異常検知数: {np.sum(anomalies)}")
```

### 🧠 解説
AutoEncoderは正常データの再現に優れるが、異常データには弱い。この性質を利用して、再構成誤差が大きいものを「異常」と判定します。

---

## 4. 実務でのポイントとよくある落とし穴

### ✅ 実務Tips
- 業務理解が最重要（ドメイン知識なしのAI導入は事故る）
- データ収集段階からAI導入を見据えて設計する
- 小さく始めて仮説検証を繰り返す

### ⚠️ よくある失敗
- 精度90%でも使えない？→ 業務上必要な閾値は文脈依存
- 分類ではなく回帰が効く場合も多い（例：売上予測）
- モデル精度より“使われる仕組み”の方が大事

---

## 5. 発展：AutoEncoder × Streamingデータ

工場のセンサーデータはリアルタイム。Batch処理では間に合わないケースも。

→ Kafka × Spark Streaming × AutoEncoder の構成でリアルタイム異常検知も可能

![streaming_architecture](https://example.com/streaming_architecture.png)

---

## 6. まとめ：バナナを拾う前に、滑らない設計を！

### ✅ AI導入の成否は「どこに・なぜ使うか」で8割決まる
- 適切な業務なら、AIは強力な武器になる
- 向いていない場所では、むしろコスト増のリスクも

### 🔭 今後の展望
- 大規模言語モデル（LLM）との連携による業務自動化拡大
- エッジAI化による現場への直接導入
- 分野特化モデル（Vertical AI）の台頭

---
個人的備忘録：ハッカソン作成中の「さぶちゃん日記」のpage.tsxについてコード全体を整理してみた

## はじめに

ここでは、Next.js を用いて作成されたトップページコンポーネントのコードを解説します。

:::note info
**個人の備忘録程度の走り書きとなっておりますが、温かい目で見守っていただければ幸いです。**
:::

主に、FastAPI バックエンドと連携しつつ、ユーザー登録やログインページへのリンクを提供する構成になっています。

https://github.com/2025SpringTeamA/frontend/blob/feature/login-flow/src/app/page.tsx

## コード全体の概要

このコンポーネントは以下の要素で構成されています：

- FastAPI サーバーからのメッセージ取得
- 取得したメッセージの表示
- 一般ユーザー登録・管理者登録・ログイン画面へのリンク
- Tailwind CSS を用いたスタイリング

## クライアントコンポーネント指定

```js
"use client";
```
Next.js の App Router 機能を使う際、コンポーネントがクライアントサイドで動作することを明示するために必要な宣言です。

## インポート文

```js
import { useEffect, useState } from "react";
import Image from "next/image";
import Link from "next/link";
```
- `useEffect` と `useState` は React の基本的なフックです。
- `Image` は未使用ですが、Next.js の画像最適化コンポーネントです。
- `Link` はページ遷移に使用する Next.js 固有のコンポーネントです。

## ステートと副作用

```js
const [message, setMessage] = useState("Loading...");

useEffect(() => {
  fetch("http://localhost:8000/")
    .then((res) => res.json())
    .then((data) => setMessage(data.message))
    .catch(() => setMessage("Error fetching message from FastAPI."));
}, []);
```
- 初期状態は "Loading..."。
- コンポーネントの初回レンダリング時に FastAPI サーバーへリクエスト。
- レスポンスの `message` プロパティをステートに反映。
- エラー時はエラーメッセージを表示。

## JSX 構成とスタイリング

```jsx
<main className="flex flex-col items-center justify-center min-h-screen bg-[#0a0a0a] text-white p-8 gap-10">
```
- 縦方向に並べて中央配置
- 背景は黒、文字は白

### タイトル

```jsx
<h1 className="text-3xl font-bold bg-gray-200 text-black px-10 py-4 rounded">
  さぶちゃん日記
</h1>
```
- 太字の大きな見出し
- 白背景・黒文字・角丸

### メッセージ表示

```jsx
<p className="text-blue-400 font-semibold">{message}</p>
```
- FastAPI から取得したメッセージを青色で表示

### リンク群

```jsx
<Link href="/register" className="...">一般ユーザー登録</Link>
<Link href="/admin-register" className="...">管理者登録</Link>
<Link href="/login" className="...">ログイン</Link>
```
- 各ページへのリンク
- マウスホバー時に背景色が変わるなど、ユーザーインタラクションあり

## 補足

- `Image` のインポートは現時点で使用されていません。
- 本番環境では `fetch("http://localhost:8000/")` を環境変数に置き換えるのが推奨されます。

## まとめ

この Home コンポーネントは、Next.js を使って Web アプリのトップページを実装する際に最低限必要な構成が詰まっていると感じました。

API との連携やルーティング処理がシンプルにまとまっていて、プロトタイプ作成や基本的な動作確認にも使いやすと思っています...！
asciidocのhtml->PDF変換で(リンク)表示を消す

# やりたいこと

asciidocが生成したhtmlをPDFに変換するときに
後ろにリンク表示をしない

これを
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3786381/e5a89c81-097f-4612-9fe1-559d9cdb1f7d.png)

こうしたい
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3786381/a0e9e1bf-2804-4cd0-8b04-d81ef67331d0.png)

# 手順

htmlをテキストエディタで開いて `@media print`を探す

これを
```
@media print{*{box-shadow:none!important;text-shadow:none!important}
html{font-size:80%}
a{color:inherit!important;text-decoration:underline!important}
a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important}
a[href^="http:"]:not(.bare)::after,a[href^="https:"]:not(.bare)::after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em}
```

こうする

```
@media print{*{box-shadow:none!important;text-shadow:none!important}
html{font-size:80%}
a{color:inherit!important;text-decoration:underline!important}
a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important}
a[href^="http:"]:not(.bare)::after,a[href^="https:"]:not(.bare)::after{content:"";display:inline-block;font-size:.875em;padding-left:.25em}
```

差分をdiff形式で表示するとこんな感じ
```diff
404c404
< a[href^="http:"]:not(.bare)::after,a[href^="https:"]:not(.bare)::after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em}
---
> a[href^="http:"]:not(.bare)::after,a[href^="https:"]:not(.bare)::after{content:"";display:inline-block;font-size:.875em;padding-left:.25em}
```

つまり `after{content:` で指定されているのでそれを削除する

あとは今までと同じようにブラウザで開いて印刷->PDF

# 都度修正するのが面倒な場合

大元のcssを変更する
fedoraでvscodeのasciidoc extensionを使っている場合は以下にある

`${HOME}/.vscode/extensions/asciidoctor.asciidoctor-vscode-3.4.2/media/asciidoctor-default.css`

他の環境でも大体似たような場所にあると思う

やることは一緒

```diff
@@ -2006,41 +2006,41 @@
 @media print {
     * {
         box-shadow: none !important;
         text-shadow: none !important
     }
 
     html {
         font-size: 80%
     }
 
     a {
         color: inherit !important;
         text-decoration: underline !important
     }
 
     a.bare, a[href^="#"], a[href^="mailto:"] {
         text-decoration: none !important
     }
 
     a[href^="http:"]:not(.bare)::after, a[href^="https:"]:not(.bare)::after {
-        content: "(" attr(href) ")";
+        content: ""; 
         display: inline-block;
         font-size: .875em;
```
PythonのSortedContainersで一番大きい要素にアクセスしたいときは-1でアクセスした方がいい

# 結論
PythonのSortedContainersで最大の要素にアクセスしたいときは、`SortedSet[-1]`とアクセスするのが高速です。

# 計算量

## -1でアクセスを行ったとき
`SortedSet[-1]`のようにアクセスを行った場合は、$O(1)$で最大の値を取得することができます。
[SortedListのソースコード](https://github.com/grantjenks/python-sortedcontainers/blob/master/src/sortedcontainers/sortedlist.py#L817)を見ると、`index`が`0`と`-1`のときに高速に取得ができるようになっています。

## size - 1でアクセスを行ったとき
`SortedSet[len(SortedSet) - 1]`のようにアクセスを行った場合は、一般のランダムアクセスと同様の計算量になります。
計算量は$M$をSortedListの内部の値である内部の値`_load`とすると、$O(\log(\frac{N}{M}))$になります。

## max関数を利用したとき
`max`関数で最大値を取得しようとすると、SortedListやSortedSetの`__iter__`が呼ばれ、これを走査するため$O(N)$かかります。

# 実測
### プログラム
以下のようなプログラムで100000回最大値を取得するのにかかる時間の平均値を測定します。
`max`については遅すぎるためここでは測定しません。

```python
from sortedcontainers import SortedSet, SortedList, SortedDict
from random import randint
from time import time

times_1 = []
times_2 = []

for i in range(100):
    st = SortedSet()

    # 適当な値を500000個入れる。
    for j in range(500000):
        st.add(randint(1,10**9))

    # 100000回最大値を取得する時間を計測する
    start = time()
    for j in range(100000):
        st[-1]
    times_1.append(time() - start)
    start = time()
    
    for j in range(100000):
        st[len(st)-1]
    
    times_2.append(time() - start)
    start = time()
    

print('SortedSet[-1]:', sum(times_1) / len(times_1))
print('SortedSet[len(st)-1]:', sum(times_2) / len(times_2))
```

### 結果

#### CPython(3.10.6)
```
SortedSet[-1]: 0.037901742458343504
SortedSet[len(st)-1]: 0.23942818403244018
```

#### PyPy(7.3.11)
```
SortedSet[-1]: 0.0003316068649291992
SortedSet[len(st)-1]: 0.013397564888000488
```
初めてAnsibleを使ってみた②　プレイブック動作検証

作成したお試し環境でプレイブックを作成して試していきます。
前回の記事

https://qiita.com/starroadkoichi1128/items/eb2b45ddf1ad3e6a823f

# プレイブックとは

Ansibleを使って実行させる処理をyaml形式のファイルにまとめたもの。
シェルやスクリプトみたいなものということで理解しました。
yamlはAWSのCFnで少しかじったことあるので何となく知っています。

# プレイブック作成
調べていたら良く登場するSLコマンドのインストールをやってみます。
Ansibleサーバー側でtest.ymlを作成します。

    # vi test.yml

内容はこちら

    - hosts: all
      tasks:
        - name: slインストール
          yum: name=sl

hostsのところに対象ホストを記載する
　Ansibleインベントリに記載している全ホストの場合は all
　他にグループ名や各ホスト名でも可能
　今回の検証環境では testgまたはcliでもよい

tasksに名前と動作を記載する
　名前はプレイブック実行時に表示されるのでわかりやすい名前を付ける(無くてもよい)

# 作成したプレイブックの文法チェック
作成したファイルの文法チェックを実施

    # ansible-playbook --syntax-check 作成したファイル.yml

何も表示されなければ良いみたい
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3857934/abcedeec-a9eb-4ee8-9585-4fe63da42fad.png)

ちなみにエラー時はこんな感じ
わざとインデントをずらしてます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3857934/59ce3d46-90a7-4e70-b3e4-df80565ef5b8.png)

# いざ実行

の前にクライアント側でslが入っていないことを確認しておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3857934/9c7a05a3-2787-4fa2-adff-399e27e77c0e.png)

はいありません。

ではサーバ側から実行してみます。

    # ansible-playbook test.yml

最後にOKが出ているのでよさそうです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3857934/2f4cc36b-4705-4658-8bef-6be42ffaf403.png)

クライアント側でslコマンドを試してみます。

    # sl

電車が走り始めました。インストール上手くいきました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3857934/92e95ffd-34ad-4301-92c9-97c26eed9fa4.png)

実行結果の内容はこちらに凄くきれいにまとめられています。

https://qiita.com/YumaInaura/items/3a9282f3e7eee9ca2af3

# 冪等性の確認

Ansibleと言えば冪等性
冪等性と言えばAnsibleなので試してみました。

もう一度ansible-playbookを実行したところ
変更点0でOKになっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3857934/09a66560-7303-461d-8ca4-7bced1cd4ad1.png)

クライアント側でslをアンインストールして再度実行したところ
変更点1でOKになっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3857934/61a0e98c-08be-4e31-917b-94b239185477.png)

結果は同じ状態になっているので冪等性を担保されているということですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3857934/7c16264c-e4d0-4855-9026-af6d8f6245b3.png)

次回はもう少し細かくプレイブックを検証してみようと思います。

https://qiita.com/starroadkoichi1128/items/a02712df95bdb7e351e5
初めてAnsibleを使ってみた①　初期設定

# 初めてのAnsible
これまでインフラ関係の構築等をやってきていますがLinux関係はほとんど関りがなく
Linux関係の構築とか運用でAnsibleってワードが出てくる度に敬遠してました。

サービス開始時期を逃したMMORPGみたいな感じでなかなか手を出せなくなっていて
↓　みたいなイメージ

* なんかコードで設定するやつだよねぇ・・・
* ちょっと乗り遅れた感じあるなぁ・・・
* 一からコードとか文法を覚えるのもう無理じゃね・・・

Ansibleってワードが出てくる度に未経験です。っていうのもなかなか辛いので
一念発起して勉強をやっていこうと思っています。


# Ansibleとは
簡単にいうとコンピューターの初期設定を設定ファイルに従って自動でやってくれるもの
パソコンキッティングで良くやるホスト名とかソフトインストールとか

勝手な思い込みでLinuxオンリーかと思ってたけどwindowsもいけるみたいですね。


# お試し環境作ってみる
 ざっくり構成図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3857934/302b7a62-faa1-4951-90a4-a9d72997716c.png)


* 自分のパソコンにVirtualBox入れてCentOSサーバを２台作成
* VirtualBoxのネットワーク設定はVM間で通信させたいのでブリッジアダプター
* VMをそれぞれ設定する側(サーバ、コントローラ)と設定される側(クライアント)とする

参考にさせて頂いた記事

https://qiita.com/sksmnagisa/items/0c46b10e9048ee92e513

https://qiita.com/feifo/items/0fde474005589afcff68

名前とIPは以下の通り 
お互い通信できてインターネットにもいけます。SSHも可能。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3857934/be4bef63-cfa6-43aa-82c4-409f99eb9b13.png)


# Ansibleサーバ構築
AnsibleサーバにSSHで接続して以下を実行

    # yum install epel-release
    # yum install ansible

正常にインストールできました。最初は結構前にダウンロードしてたCentOS8で試したらパッケージの依存関係云々出てきたのでCentOS stream9で実施しました。
インストールは最小構成で実施。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3857934/5da469f9-08de-46e6-9a18-a307f5fcb40b.png)

お試し環境にはDNSが無いのでhostsファイルに以下追加します。

    # vi /etc/hosts
    
192.168.0.14 srv
192.168.0.16 cli

同じ内容をansibleクライアント側にも追加します。

# Ansibleインベントリ作成

Ansibleサーバ上で構築対象ホストの設定ファイル(インベントリ)を作成します。
設定ファイルのパスはこれ(/etc/ansible/hosts)。 
インストール直後は書き方の例が記載されているだけなので
とりあえず一番下に追加していきます。
書き方はこんな感じです。

[グループ名]
グループに所属するホスト名1またはIP
グループに所属するホスト名2またはIP

こんな感じに設定してみました。１台しかないのでグループ化のメリットないですけど・・
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3857934/1ee51720-997f-4b10-bb52-5105fabf6498.png)

# インベントリ設定確認

一応この状態で設定が問題ないかを確認するためにpingコマンドが通るか確認してみます。

    # ansible (グループまたはホスト) -k -m ping

一旦は-k オプション入れてパスワードを都度指定。
SUCCESSと出ているので問題なさそうです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3857934/8340b22d-f4f5-4f2d-9bbc-3d7e2e1257d6.png)

ちなみに今回はAnsibleインベントリにホスト名で登録しているので
IPを指定するとエラーになります。インベントリにIPで登録すれば問題ない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3857934/19f707f5-5998-412b-b5eb-f607e8ddc22e.png)



参考にさせて頂いた記事

https://genchan.net/it/programming/ansible/6097/

一応鍵認証も試してみます。
ssh鍵を作成します。

    # ssh-keygen
    
途中はすべて空白のままエンターを押します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3857934/82548514-b3e0-4dd9-8585-21b4d249497a.png)
    
ssh公開鍵をansibleクライアントにコピーします。

    ssh-copy-id cli
    
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3857934/42422f4c-bc49-471f-84d4-9cba31591acb.png)

コピーできたようなので-kオプション無しでできるか試してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3857934/850b8941-4faf-47da-b323-aa466ef8746c.png)

パスワードを聞かれずにできました。
これでAnsibleを使用できる状態になりました。

次は実際にクライアント上で何を設定するかをまとめたプレイブックなるものを作成して
動作を試してみます。

https://qiita.com/starroadkoichi1128/items/83598d0e41d27c57f68a
個人的備忘録：MySQL 8.4.4 を50ユーザー規模向けにチューニングするための情報を整理してみた

## はじめに
本記事は、MySQL 8.4.4 の RDS 環境において、想定利用者数が約50人のWebアプリケーション向けに、適切なカスタムパラメーターグループの設定を整理した個人用の備忘録です。

:::note info
**個人の備忘録程度の走り書きとなっておりますが、温かい目で見守っていただければ幸いです。**
:::

あくまで参考値として活用し、実運用ではモニタリングと併せて適宜調整が必要です。

## 想定環境
- 利用者数：同時接続最大50名程度
- 使用用途：一般的な読み書きありのWebアプリケーション
- インスタンスタイプ：t3.medium〜t3.large（メモリ4GB〜8GB程度）
- データベースエンジン：MySQL 8.4.4（MySQL 8.0ファミリー）

## 推奨カスタムパラメーター一覧

| パラメーター名                   | 推奨値        | 備考 |
|--------------------------------|-------------|------|
| `max_connections`             | `100`       | 同時接続数の2倍程度で余裕を確保 |
| `innodb_buffer_pool_size`     | `1G〜4G`    | メモリの70〜80%程度が目安（例：t3.largeなら4G）|
| `innodb_log_file_size`        | `256M〜512M`| 書き込み量が多い場合に大きめ推奨 |
| `innodb_flush_log_at_trx_commit` | `2`       | パフォーマンス優先（整合性より速度）|
| `table_open_cache`            | `512`       | 頻繁にアクセスされるテーブル数に応じて調整 |
| `tmp_table_size`              | `64M`       | 一時テーブルが多い場合に増加推奨 |
| `max_allowed_packet`          | `64M`       | 大きなデータ送受信がある場合の上限調整 |
| `sort_buffer_size`            | `2M〜4M`    | ORDER BY多用時に調整 |
| `join_buffer_size`            | `2M〜4M`    | JOINの多いクエリ用に調整 |

## 設定例（AWS CLI）
```bash
aws rds create-db-parameter-group \
  --db-parameter-group-name custom-mysql-844 \
  --db-parameter-group-family mysql8.0 \
  --description "Custom parameter group for MySQL 8.4.4"

aws rds modify-db-parameter-group \
  --db-parameter-group-name custom-mysql-844 \
  --parameters \
  "ParameterName=max_connections,ParameterValue=100,ApplyMethod=immediate" \
  "ParameterName=innodb_buffer_pool_size,ParameterValue=1073741824,ApplyMethod=immediate"
# 上記: 1073741824 = 1GB
```

**参考画像**

![Screenshot 2025-04-24 at 10.14.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/927dccf5-40c2-4c7f-b5e9-cc1054603ddc.png)


## メモ
- `innodb_buffer_pool_size` は性能に直結する最重要パラメーター。

https://dev.mysql.com/doc/refman/8.0/ja/innodb-buffer-pool-resize.html

- `max_connections` を超過すると接続エラー（エラー1040）になるので注意。

https://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/tuning-postgresql-parameters/introduction.html

- `slow_query_log` を有効にし、定期的にスロークエリを確認すると改善ポイントが見つかる。

https://dev.mysql.com/doc/refman/8.0/ja/slow-query-log.html

## まとめ
利用人数が限定された中小規模のシステムでは、MySQL の初期設定をそのまま使うのではなく、アプリケーションの特性やインスタンスのスペックに応じてチューニングすることで、応答速度や安定性が大きく向上します。

:::note warn
特に `innodb_buffer_pool_size` と `max_connections` の調整は最初に検討すべきポイントです。
:::

本記事はその一例として記録したものであり、実際の負荷状況に応じて適宜見直してみてください...！
[writeup] picoCTF "Includes"

# 今回の問題
picoCTFより"Includes"を解いていきます。

# 実際に解いていく
### 1. 問題文にあるWebサイトに移動する
![Includes_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3945501/26ceb24f-6946-41aa-ad65-958b1206fbd2.png)
インクルードについて記述されています。
インクルードとは、ざっくりいうと「あるファイルの中に、別のファイルを入れて使えるようにすること」ですかね。

### 2. 下にあるボタンを押してみる
![Includes_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3945501/02b36bde-361d-4ffd-b216-95823eeab8d7.png)
[Say hello]というボタンを押してみました。
なになに...このコードは分かれたファイルからできている？？
つまり、インクルードされていると推測しました。

### 3. Webインスペクタを開く
![Includes_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3945501/be596346-b27d-4ee9-8a8f-3acffab7acf6.png)
ソースコードを見てみると、HTMLファイルの中に、style.cssとscript.jsがインクルードされていますね。

### 4. style.cssとscript.jsを見てみる
![Includes_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3945501/adcb6bed-95f2-4a5c-94ef-6aa12d650654.png)
![Includes_5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3945501/18bbf1fe-edc9-4f84-95a1-9ec40fd0cb46.png)
[Elements]から[Sources]に移動します。すると、このWebサイトの構成が確認できます。
それぞれのファイルにFLAGがコメントアウトされています。
これにてFLAGを獲得しました！

# 補足
特になし
【Reactアプリ100本ノック】02 Counter

## はじめに
ゆかっしゅです。
2021年に事務職からデザイナー/コーダーにジョブチェンジをし、現在はフロントエンドエンジニアにスキルアップするべく、モダンフロントエンドを学習しています。

ReactやTypeScriptの基礎学習は終了したのに、なかなか0から自分だけでアプリを作れないので手を動かすべく「Reactアプリ100本ノック」 に挑戦してみようと思います。

https://qiita.com/Sicut_study/items/82059f9cbb5b2996e5b3

## Reactアプリ100本ノックルール
- 主要なライブラリやフレームワークはReactである必要がありますが、その他のツールやライブラリ（例: Redux, Next.js, Styled Componentsなど）を組み合わせて使用することは自由
- TypeScriptを利用する
- なるべくChatGPTなどのAIツールに頼らない（自分独自ルール）

## 02. Counter
![スクリーンショット 2025-04-24 101542.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4068307/d9f2f1d2-bbe2-49bd-94b1-54ced95da8e3.png)

## 問題
カウンターを作成する

## 目的
React の基本を理解する: カウンターアプリは、ステート管理やイベントハンドリングなど、React の基本的な機能を学ぶのに適しています。初心者にとっては、これらの概念の理解を深める良いスタートポイントとなります。

## 達成条件
1\.表示領域: 数字を表示するエリアが存在する。
2\.インクリメントボタン: このボタンをクリックすると、表示されている数字が 1 増える。
3\.デクリメントボタン: このボタンをクリックすると、表示されている数字が 1 減る。
4\.初期表示: アプリを起動した際の数字は 0 である。
5\.ステート管理: React の useState や useReducer を使って、カウントの数字を管理する。

## 実際に解いてみた
### 利用技術
- React(19.0.0)
- TypeScript(5.0)
- Next.js(15.3.1)
- Tailwindcss(4.0)
- Vercel

解答時間:15分

見た目部分10分、useStateの部分5分といったくらいの配分でした。
まだまだ、Tailwind CSS慣れない…。
チートシートをよく利用させてもらってます。

https://www.creative-tim.com/twcomponents/cheatsheet/

## リンク

https://react-app-100.vercel.app/

### 終わりに
useReducerなかなか難しくて使う気にならないのですが、もし今後使う機会があったらStateではなくReducerで書いてみたいと思います。Reduxも勉強しなきゃ...。
スケーラビリティを学んでたら、非同期処理の本質に辿り着いた話

## この記事について

スケーラビリティを学ぶ中で「APIが重い」「外部APIが遅い」といった話題が出てきました。

「非同期にすれば軽くなる」という言葉もよく目にしましたが、正直ピンときませんでした。

今回は、僕自身がそこから疑問を掘り下げていった中で

「**非同期処理の本質ってそういうことか！**」とストンと理解できた流れをまとめた記事です。

---

## スケーラビリティを学んで湧いた最初の疑問

- サーバーが「重い」ってどういうこと？
- APIやDBが「重い」って実際どんな状態？
- 「外部APIの呼び出しがボトルネックになる」って何が起きてるの？

これらを追いかける中で、「非同期処理で解決することがある」と知り、さらに疑問が…。

---

## 非同期処理って、何がいいの？

最初は「重い処理を非同期にすれば軽くなる」と思っていました。

でも、ふとこう思ったんです。

> 「すぐ結果が必要な処理を非同期にしたら、意味なくない？」
> 

たとえばログイン処理。これを非同期にして「あとでログイン結果を返す」って、普通に使えない（笑）

---

## そこから見えてきた本質

そこで整理できたのが、次の結論。

### 非同期処理の本質はこれだった：

> 「今すぐ結果を返す必要がない処理」を後回しにする設計。
> 

---

## 非同期に向いている処理（今すぐじゃなくていい）

- メール送信
- Slack通知
- 投稿後のSNS連携
- 画像のリサイズや動画の変換
- 行動ログの記録

→ 共通するのは「**ユーザーにすぐ結果を返さなくても困らない**」という点。

---

## 非同期にすべきではない処理（今すぐ必要）

- ログイン
- 支払い完了判定
- パスワード変更

→ すぐに成功・失敗が分からないと、**UXもセキュリティも破綻する**。

---

## 自分なりの判断基準

非同期でいいかどうか、迷ったらこの問いを立てるようにしました：

> 「この処理、今終わらなくてもユーザーは困らないか？」
> 

---

## まとめ：今回の学び

- 非同期処理は、**処理が重いかどうか**ではなく、**今すぐ必要な処理かどうか**で判断すべき
- すぐに必要な処理は**同期処理で保証**し、そうでないものは**非同期で分散**
- 技術的な話に見えて、実は**設計の考え方**が一番大事だった

---

## 最後に

この記事は、自分の中で「重い処理=非同期処理」みたいな印象を持っていたところから、

「設計上の判断」だと理解できたプロセスを言語化したものです。

同じようにモヤモヤしている人の参考になれば嬉しいです！

質問・感想・アドバイスなども気軽にどうぞ！
ディレクトリトラバーサル

# ディレクトリトラバーサル
Webアプリケーションなどの脆弱性を突いて、本来はアクセスできないディレクトリ(ファイル)に不正アクセスすること。

## 脆弱性の突き方

`http://example.com`というwebがあったとします。
webを立ち上げたことがある人は理解していると思いますが、URLはディレクトリと同じ構造になっています。
例えば、`http://example.com/img`や`http://example.com/users`など、そのディレクトリが存在していればアクセスすることができます。

しかし、それらのディレクトリが存在するかどうかはわかりません。ここで、代表的な辞書攻撃を紹介します。

### GoBuster
用途は様々ありますが、今回はディレクトリを探す方法を記載します。

```bash
gobuster dir -u http://example.com/ -w /usr/share/wordlists/dirb/common.txt
```

これは、`http://example.com/`の直下にwordlistsをあてはめ、存在するディレクトリを探します。
詳しく知りたい方は、調べてください。沢山情報が出てきます。
もしここにユーザアカウント情報が格納されているディレクトリが存在すれば危険ですね。

他にも、自ら脆弱性を生み出す手法も存在します。

### アップロードを悪用
例えば、`http://example.com`でファイルをアップロードでき、そのファイルはサニタイズされていないとします。
また、`hogehoge.png`をアップロードしたとき、`http://example.com/data/hogehoge.png`のように保存されるとします。

`hogehoge.png`をアップロードしただけでは、何も起こりません。
しかし、その場で実行可能なファイルを作り、アップロード出来るしたらどうでしょうか。

```php
hogehoge.php
<?php
echo "<pre>";
system("sudo ls -a /root");
echo "</pre>";
?>
```
正直な話、OSコマンドを操作できる権限をユーザに付与していることはめったにありませんが、条件が揃えば、上記のようなコマンドを実行できてしまいます。

メインとなるのは、`system("sudo ls -a /root")`です。
Linuxなどでおなじみのlsコマンドです。上記は`/root`にあるファイルを一覧できます。
-a は`.himitu.txt`のような隠しファイルを表示させるためのオプションです。

`system("sudo cat /root/.himitu.txt")`とすれば、`.himitu.txt`の内容を表示することができます。

# まとめ
webアプリケーションの脆弱性を突いた攻撃の紹介でした。
悪用禁止でｓ
【YouTubeチャネルのテーマ曲作成】Theme from Yamanaka-Ya YouTube Channel #1 - Hiphop, Jazz, Piano, Ballad【Suno AIで作曲】【動画 3分04秒】【YouTubeチャンネルからの転記です】

この記事は、わたしの[YouTubeチャンネル](https://bit.ly/Yamanaka-YouTube "Living without things. 持たない生き方 手放す生き方")にある公開動画を転記しております。
( どこかのタイミングで、プログラミング-Google Apps Script or iPaaS-Zapier をつかって自動転記させる予定です )

転記のための時間コストを少なくしたいので、文字装飾( Markdown記法 )を極力つかわずに書いております。

こちらが動画内容です👇

***

![02 YouTubeサムネイル & 再生中の画像 Suno AI _ Theme from Yamanaka-Ya YouTube Channel #1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386308/9052502f-6ccd-4e52-99a8-b088e208e0c8.png)




* # 動画URL
    * https://youtu.be/m1XfmsYh_04

<br>

* # 動画タイトル
    * Theme from Yamanaka-Ya YouTube Channel #1 - Hiphop, Jazz, Piano, Ballad【Suno AIで作曲】【動画 3分04秒】

<br>

* # 動画の説明欄(一部を抜粋)

撮影日 = 2025-04-24(木)

Suno AIとは、文章から音楽を生成することができるAIサービス(Text-to-Music-AI)です。
わたしは、2024-04-02(火)に初めてSuno AIで有償プランを契約してから、時々楽曲をつくって遊んでいます。

🎦【Suno AI】文章から音楽を生成するAI( Text-to-Music-AI )で、3分間で2曲、6分間で4曲作りました【試聴可能】1)伴侶の曲 2)税理士の曲【動画 16分11秒】
https://youtu.be/QKfhk4HgQ_g

🎦“Suno AIでつくった楽曲”シリーズ
https://www.youtube.com/playlist?list=PLpQhBHT4oghMLdiSVqwvSs_Z5y0H4VGOe

🎦“効果的にSuno AIを活用するヒント”シリーズ
https://www.youtube.com/playlist?list=PLpQhBHT4oghPuaNOVZn-N53wVvsBkeHdI


今回は、Suno AIで作曲し、 WAV 出力した楽曲を動画に仕上げました。

今回つくった楽曲は、自分自身のYouTubeチャネルのテーマ曲です。
もともとは、Erik Satie “Gymnopédie No.1”のような、落ち着いた3拍子のピアノ曲を作ろうと考えていました。
しかし、Suno AIが提案してきた候補を聴いていく中で、Gymnopédie + 演歌をためしたり、Gymnopédie + Hiphopをためしたりして、そしてこの曲に心を惹かれ、最終的に採用することにしました。

編集や公開作業の合間に感じていた空気感、発信を続けてきた過程で見えてきた想い、それらをひとつの音楽に凝縮しました。
動画の世界観、温度感、そして届けたい想いを意識しながら、旋律を組み立てています。

ぜひこの楽曲を聴いていただき、わたしのチャネルの世界観を感じていただければ嬉しいです。
そして、自分自身のメディアや表現の場を持っている方は、ぜひその想いを音楽にしてみてください。
言葉では言い尽くせない魅力や温度を、音が伝えてくれるかもしれません。

作曲日:
2025-04-23(水)

Suno AI 契約の種類:
Pro Plan

Suno AI Version:
v4

楽曲の正式名称:
Theme from Yamanaka-Ya YouTube Channel #1

Suno AI Library URL:
https://bit.ly/YamanakaYa-YT-Theme-01

Custom Mode: On

Audio Inputs: Not Used

Instrumental:


---


Suno AIへの指示文章( プロンプト/Prompt ): Custom Modeの場合は”Style of Music”を指定します。


🇬🇧English

[Hiphop][Jazz][Piano][Ballad][Outro]


🇯🇵日本語訳

[ヒップホップ][ジャズ][ピアノ][バラード][アウトロ]


---


Suno AI 公式URL
https://accounts.suno.ai


---


🎥この動画と関連が強いわたしの動画
・“効果的にSuno AIを活用するヒント”シリーズ
https://www.youtube.com/playlist?list=PLpQhBHT4oghPuaNOVZn-N53wVvsBkeHdI


・“Suno AIでつくった楽曲”シリーズ
https://www.youtube.com/playlist?list=PLpQhBHT4oghMLdiSVqwvSs_Z5y0H4VGOe


・“山中一司のYouTubeチャネルテーマ曲”シリーズ
https://www.youtube.com/playlist?list=PLpQhBHT4oghOIRQJWN40VqpHBcb_8jnM8


・“YouTubeチャンネルを活用するヒント”シリーズ
https://www.youtube.com/playlist?list=PLpQhBHT4oghPU-6b7_38byuhYDiOYCLW6


🎥Shortened URL for this video | この動画の短縮URL
https://bit.ly/4jRrgND
AWS Certified Machine Learning Engineer - Associate 合格体験記

# はじめに
[AWS Certified Machine Learning Engineer - Associate](https://aws.amazon.com/jp/certification/certified-machine-learning-engineer-associate/)の試験を受けてきたのでその体験記を記録として残しておきたいと思います。

https://aws.amazon.com/jp/certification/certified-machine-learning-engineer-associate/

# 保有資格と経験
AWS サービスにはインフラエンジニアとして 10 年以上触れています。
ですが、ML/AI 関連は全く経験なしです。これから学んでいきたいと思い *AWS Certified AI Practitioner* は先日取得しました。
- [AWS Certified Solutions Architect - Professional](https://aws.amazon.com/jp/certification/certified-solutions-architect-professional/)
- [AWS Certified Security - Specialty](https://aws.amazon.com/jp/certification/certified-security-specialty/)
- [AWS Certified Advanced Networking - Specialty](https://aws.amazon.com/jp/certification/certified-advanced-networking-specialty/)
- [AWS Certified AI Practitioner](https://aws.amazon.com/jp/certification/certified-ai-practitioner/)
- [生成AIパスポート](https://guga.or.jp/generativeaiexam/)

# 試験結果
試験結果は `受験スコア：954` でした。 *AWS Certified AI Practitioner* には及びませんでしたが、かなり高得点かと思います。
![AWS Certified Machine Learning Engineer - Associate.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82090/8b6955f8-7a9b-470e-95bd-49878b3bf863.png)

https://www.credly.com/badges/ba9aecd4-6688-40fe-b9cf-ab66667a6672/public_url

# 試験を受けたきっかけ
この試験の前に AWS Certified AI Practitioner の資格を取得したのですが、このまま ML/AI 関連の勉強を続けたいなと思ったのがきっかけでした。
はじめは [G検定](https://www.jdla.org/certificate/general/) を目標に学習しようと思ったのですが、その際に知り合いから **AWS Certified Machine Learning Engineer - Associate** もあるというのを教えてもらったため、せっかくなら同じ AWS 関連の資格を取得したいなと思い受験しました。

# 学習期間
だいたい 3 週間程度です。
この試験を受ける前に AWS Certified AI Practitioner を受験していたので、それと合わせると 6 週間くらいかなと思います。

# 教材と勉強方法
AWS Certified AI Practitioner の際に登録した Cloud License がまだ使えたので問題をひたすら解きました。
範囲もかなり被っているので 2 つ同時に受験してしまっても良かったなと受けた後に感じました。

https://cloud-license.com/exam/mla/

# 受けた感想
*AWS Certified AI Practitioner* と難易度は変わらない感じがしました。ひと通り解き終わって合格できる自信があったので、そのまま試験を終えました。
内容としては **Amazon SageMaker** 関連の問題がより多く出題されているので、そこはしっかり抑えておくと良さそうです。

# おわりに
少しずつではありますが AI/ML の勉強は進められているかなと思います。
どんどん新しい技術が出てきているので少しずつでもペースを上げて行けたらなと思います。


### 参考

https://qiita.com/kooohei/items/b7a360aaddfb5a97f360
S3 Glacierファミリー3種比較

# 前置き
AWSのS3は非常に価格の安いデータ保存先ですよね。
ライフサイクルポリシーを使って、長期間使わないデータはGlacierに移行するのが一般的かと思います。

# S3 Glacierファミリー3種比較
S3のGlacierにも種類がいくつかあるので、生成AI君に比較させました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4021557/b0a5be28-6b93-4238-a474-9b40792426c4.png)

段階的に移行する感じなら以下のような感じでしょうか。
例）
S3 Standard（30日）
　↓
S3 Standard-IA（60日）
　↓
Glacier Instant Retrieval（90日）
　↓
Glacier（180日）
　↓
Deep Archive（365日〜）
統計検定1級　2023　統計数理　問2　解説

![img20250423_10452380.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/15e7d6d6-6b07-40df-9c51-2c5bf313ff71.jpeg)
![img20250423_10455565.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/329e4928-2ef6-400e-9ca0-f1b57005c8f7.jpeg)
統計検定　1級　2024　統計数理　問3　[3][4]解説

ギブアップしていた問題です。Hatena Blog  jiku logさんを見て、何とか解答にもっていけました。
![img20250422_13035872.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/7559fdcc-8f41-474b-9fb5-8144f5fc2a30.jpeg)
![img20250422_13043240.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/32d9f2bd-5675-4c3d-adc9-3f36687c8ab4.jpeg)
CSS中央寄せガイド！margin/text-align/Flexboxの違い・使い分け・メリットデメリットのまとめ

# はじめに
「要素を画面の真ん中にもっていきたい」ーー
CSSで一番よく使うテクニックの一つ、それが中央寄せ。

方法はいくつかあり、
- `margin: 0 auto;`
- `text-align: center;`
- `Flexbox`
この３つはどれを使えばよいか迷う方も多いかと思います。

# ①margin: 0 auto;の中央寄せ
## コード例
```css
.box {
    width: 300px;
    margin: 0 auto;
}
```

**特徴**
- ブロック要素の**横方向**の中央寄せに使用
- widthを明示的に指定する必要がある

## メリット
- 記述がシンプルでわかりやすい
- 古いブラウザでも確実に動く
- フォームや画像のセンタリングで定番

## デメリット
- 縦方向の中央揃えはできない
- 要素のwidth指定が必須(なければ効かない)

## 実務での使用例
- ログインフォーム
- 固定サイズのモーダルウィンドウ
- バナー画像や横幅300pxのボックス

# ②text-align: center;の中央寄せ
**コード例**
```css
.wrapper {
    text-align: center;
}
```
```html
<div class="wrapper">
    <img src="logo.png" alt="ロゴ">
</div>
```

## 特徴
- 親要素に対してtext-align: centerを設定すると、**子要素(インラインやinline-block)が中央寄せされる**

## メリット
- インライン要素(文字・画像)の中央寄せが簡単
- 非常に軽量・使い勝手がいい

## デメリット
- ブロック要素は効かない
- 中央寄せしたい要素がinlineまたはinline-blockである必要がある

## 実務での使用例
- ロゴやバナー画像の配置
- テキストリンクの中央寄せ
- アイコン + 文字のインラインレイアウト

# ③Flexboxを使った中央寄せ

**コード例(縦・横ともに中央揃え)**
```css
.center-box {
    display: flex;
    justify-content: center; /* 横 */
    align-items: center;  /* 縦 */
    height: 300px;
}
```
```html
<div>
    <div>中央表示される内容</div>
</div>
```

## 特徴
- 横だけでなく縦の中央揃えも可能
- 要素の位置や並び順も柔軟に調整可能(+ レスポンシブ対応にも強い)

## メリット
- **縦横同時に中央寄せできる唯一の方法**
- レスポンシブ対応・動的なコンテンツにも強い
- gap、order、wrapなども併用できて拡張性が高い

## デメリット
- display: flex;を親要素に設定する必要がある
- シンプルな目的に使うにはやや記述が冗長に感じることも

## 実務での使用例
- ログイン画面のセンター寄せ
- アイコンとテキストの横並び
- ヘッダー内でロゴとナビメニューを両端に配置(space-between)

# 中央寄せ手法の比較まとめ
![IMG_7822.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2246240/6600ed83-1e32-4035-b73f-e4d252d33a93.jpeg)

# 最後に：どれを使うべき？
**中央寄せは「要素の種類」と「縦 or 横」で判断！**

- 文字・画像を横に中央揃え → **text-align: center**
- 固定幅ボックスを横に中央揃え → **margin: 0 auto;**
- 縦横両方・レスポンシブ含めて完全対応 → **Flexbox**
【エラー解決ログ】gitlabからのfetchで行き詰った

初学者のため、何か間違いがございましたらご指摘ください。
# 直面したエラー
リモートリポジトリから最新のブランチ情報を取得しようとして`git fetch`を行うと以下のようなエラーが出て上手く行かない
```
remote: Enumerating objects: 107, done.
remote: Counting objects: 100% (87/87), done.
remote: Compressing objects: 100% (53/53), done.
remote: Total 60 (delta 25), reused 0 (delta 0), pack-reused 0 (from 0)
error: insufficient permission for adding an object to repository database .git/objects
fatal: failed to write object
fatal: unpack-objects failed
```
# 解決策
- `chmod -R u+rwX .git/objects`で`.git/objects`の権限を修正
- `sudo chown -R ユーザー名 .git`で所有者を自分のユーザーに変更
# エラーになっていた原因
使用していたユーザーが`.git/objects`ディレクトリに対するファイルの書き込み権限を持っていなかった。
そのため、ユーザーに対して権限を付与する必要があった
【AWS EC2 × Docker】docker build で「Exec format error」が出た時の対処法

## 発生したエラー
AWS EC2（Ubuntu）上で docker build . を実行したところ、次のようなエラーが発生
```
863150K .......... .......... .......... .......... .......... 99% 18.8M 0s
863200K .......... .......... .......... .......... .......... 99% 55.7M 0s
863250K .......... .......... .......... .......... .......... 99% 82.4M 0s
863300K .......... .......... .......... .......... .......... 99% 97.0M 0s
863350K .......... .......... .......... .......... .......... 99%  388M 0s
863400K .......... .......... .......... .......... .......... 99%  368M 0s
863450K ......                                                100% 12.3T=11s
2025-04-24 00:10:22 (74.4 MB/s) - 'Anaconda3-2024.10-1-Linux-aarch64.sh' saved [884179536/884179536]

PREFIX=/opt/anaconda3

Unpacking payload ...
/opt/Anaconda3-2024.10-1-Linux-aarch64.sh: 468: /opt/anaconda3/_conda: Exec format error
The command '/bin/sh -c wget https://repo.anaconda.com/archive/Anaconda3-2024.10-1-Linux-aarch64.sh &&   sh /opt/Anaconda3-2024.10-1-Linux-aarch64.sh -b -p /opt/anaconda3 &&   rm -f Anaconda3-2024.10-1-Linux-aarch64.sh' returned a non-zero code: 126
```

Dockerfile内でAnacondaのインストーラーを使っていたらこのエラーに遭遇するかもしれません。

## 原因
Dockerfileで使用していたAnacondaインストーラーが**異なるCPUアーキテクチャ向け（ARM）**だったため、実行に失敗しました。
```
Anaconda3-2024.10-1-Linux-aarch64.sh
aarch64 → ARM向け（Apple M1/M2、Gravitonなど）
```
EC2（t2/t3など）では x86_64 なので非対応！

結果として「Exec format error」が出た、というわけです。

## 解決法
### ① CPUアーキテクチャを確認する
まず、EC2インスタンスがどんなCPUか確認：


uname -m
x86_64 → Intel/AMD系 → この場合、aarch64版はNG！

aarch64 → ARM系

### ② Dockerfile を修正
aarch64.sh を x86_64.sh に変えて、正しいアーキテクチャ用インストーラーを使います。

dockerfile
```
RUN wget https://repo.anaconda.com/archive/Anaconda3-2024.10-1-Linux-x86_64.sh && \
    bash Anaconda3-2024.10-1-Linux-x86_64.sh -b -p /opt/anaconda3 && \
    rm -f Anaconda3-2024.10-1-Linux-x86_64.sh
```
### ③ 再ビルド
Dockerイメージを再ビルドして完了！
docker build .
DuckDBでSELECTを実行したときに長い文字列をすべて表示したい

DuckDBをコマンドラインから実行してselect文を発行するときに、デフォルトの出力フォーマットでは列に保存されている文字列が長すぎて省略されてしまうことがあります。MySQLでは、select文の最後の";"を"\G"に置き換えることで出力フォーマットを変更できますが、DuckDBでも同様の機能が用意されています。
select文の出力フォーマットを変えるには`.mode`ドットコマンドが使えます。事前にコマンドを実行して出力フォーマットを変えてからselect文を実行すると、出力フォーマットが変わります。

```sql
D select view_name, sql from duckdb_views() where view_name='vending_machine';
┌─────────────────┬────────────────────────────────────────────────────────────────────────────────────────────────────┐
│    view_name    │                                                sql                                                 │
│     varchar     │                                              varchar                                               │
├─────────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ vending_machine │ CREATE VIEW sales_report_warehouse.vending_machine AS WITH final AS (SELECT CAST(id AS INTEGER) …  │
└─────────────────┴────────────────────────────────────────────────────────────────────────────────────────────────────┘
D .mode line
D select view_name, sql from duckdb_views() where view_name='vending_machine';
view_name = vending_machine
      sql = CREATE VIEW sales_report_warehouse.vending_machine AS WITH final AS (SELECT CAST(id AS INTEGER) AS id, "name", address FROM dev.sales_report_source.vending_machine)SELECT * FROM final;
D
```

なお、デフォルトの出力フォーマットに戻したい時には`.mode duckbox`を実行します。

参考URL
[Output Formats](https://duckdb.org/docs/stable/clients/cli/output_formats.html)
個人的備忘録：AWS CLIでRunTaskを実行し、DBマイグレーションができるか調べた内容をメモしてみた

## はじめに

本記事は、**個人の調べ**と**備忘録**としてまとめたものであり、正確性については今後さらに検証・調査していく予定です。

**個人の備忘録程度の走り書きとなっておりますが、温かい目で見守っていただければ幸いです。**

## 書こうと思ったきっかけ

AWS 上でのアプリケーションデプロイにおいて、**DB マイグレーションの一時的な実行**方法を調べていた際、`RunTask` を使うことで効率的に実現できそうだと感じたため、手順を整理することにしました。

## RunTask を使った DB Migration の概要

一時的にマイグレーションを実行する方法として、ECS/Fargate 上で `RunTask` を用いることができます。

**参考文献**

https://dev.classmethod.jp/articles/tsnote-amazon-ecs-choices-for-how-to-launch-tasks/

Web アプリとは分離された形でマイグレーションを実行できるため、CI/CD パイプラインに組み込みやすい点も利点です。

### 想定構成

- 環境: AWS ECS（Fargate）
- 用途: DB マイグレーション用に `RunTask` で一時タスクを起動
- 例: Django の `python manage.py migrate`、Alembic の `alembic upgrade head` など

## 手順の概要

### 1. Docker イメージの準備

DB マイグレーション用の Docker イメージを作成し、ECR に登録します。

### 2. ECS タスク定義を作成

Web アプリ用とは別に、マイグレーション専用のタスク定義を用意します。

- イメージ: マイグレーション専用 Docker イメージ
- コマンド例: `python manage.py migrate`
- 環境変数: DB 接続情報など

### 3. RunTask コマンドでタスク実行例（自分調べ：サンプルコマンド）

```bash
aws ecs run-task \
  --cluster your-cluster-name \
  --launch-type FARGATE \
  --task-definition your-migration-task-def \
  --network-configuration "awsvpcConfiguration={subnets=[subnet-abc123],securityGroups=[sg-xyz456],assignPublicIp=DISABLED}" \
  --platform-version "LATEST"
```

### 4. ログの確認と後処理

- CloudWatch Logs に出力されたログを確認
- 必要に応じてロールバック対応や通知処理を実装

## まとめ

`RunTask` を用いた一時的なマイグレーションの実行は、以下のような場面に便利です：

- 本番前のマイグレーション実行
- CI/CD パイプラインに組み込む際の分離実行

なお、この記事の内容はあくまで調査ベースの備忘録であり、構成やパラメータの正確性は今後の実証を通じてアップデートしていく予定です...！
アップロードした画像をパズルにする

画像をアップロードするとそれをパズルにするwebアプリを作りました。
作り方をご紹介します！
制作には主にpythonを使用しています。

![puzzle_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4069757/2534c4dd-46d6-4073-a5fe-796194cdc490.png)

## パズルの仕様
・基本の分割は10×10
・ピースがシャッフルされた状態でスタート
・ドラッグ&ドロップでピースを移動する
・ピースを正しい場所にすべて配置すると完成メッセージを出す

## 実装
pythonのstreamlitとPILを主に用いて実装しました。


### 分割

```
def split_image(image, rows=10, cols=10):
    width, height = image.size
    piece_w = width // cols
    piece_h = height // rows
    pieces = []
    for i in range(rows):
        for j in range(cols):
            box = (j * piece_w, i * piece_h, (j + 1) * piece_w, (i + 1) * piece_h)
            piece = image.crop(box)
            buf = io.BytesIO()
            piece.save(buf, format="PNG")
            base64_str = base64.b64encode(buf.getvalue()).decode()
            pieces.append({
                "id": i * cols + j,
                "data": f"data:image/png;base64,{base64_str}"
            })
    return pieces, piece_w, piece_h
```

box: (left, upper, right, lower) 形式で座標指定し
image.crop() でその部分を切り出しています。

切り出したピースを一時的にPNG形式で保存し、それをBase64エンコード
.decode()はバイナリ→文字列変換（JSで埋め込みやすくするため）

各ピースはユニークなID（左上→右下へ0から順に）と画像データを持つ辞書にしてリスト化して管理しています。

### 画像を描画

```
function render() {{
            container.innerHTML = "";
            order.forEach((piece, index) => {{
                const img = document.createElement("img");
                img.src = piece.src;
                img.draggable = true;
                img.className = "piece";
                img.dataset.index = index;
                container.appendChild(img);
            }});
        }}
```

orderの順番通りにピース画像を並べます。
data-indexは後でドラッグ時の入れ替えに使用しています！

### ドラッグ & ドロップ

```
    let draggedIndex = null;
    
    container.addEventListener("dragstart", e => {{
        draggedIndex = e.target.dataset.index;
    }});
```
どのピースがドラッグされたか記録し


```    
    container.addEventListener("drop", e => {{
        const targetIndex = e.target.dataset.index;
        if (draggedIndex !== null && targetIndex !== null) {{
            [order[draggedIndex], order[targetIndex]] = [order[targetIndex], order[draggedIndex]];
            render();
            checkCompletion();
        }}
    }});
```
ドロップ先のピースと位置を交換し、render()で再描画しています。

checkCompletion()は完成チェックの関数です。


## 実際の画面
実際に作成した画面はこんな感じです
便宜上パズルを4×4にしてます

![puzzle_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4069757/7da7f5f3-2c0c-4fe6-8fae-1fa6aaf62da6.png)

![puzzle_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4069757/2534c4dd-46d6-4073-a5fe-796194cdc490.png)

![画面収録 2025-04-24 2.05.22.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4069757/8b4db0b5-021a-4f44-8287-1ea225940884.gif)

![puzzle_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4069757/e7b62659-b01e-4e8f-89b5-f782965db8f9.png)
flutterでFlutter/Release.xcconfigのエラー

# pod isntall時のエラー
- `pod install`でエラーになった

```
Pod installation complete! There are 5 dependencies from the Podfile and 5 total pods installed.

[!] CocoaPods did not set the base configuration of your project because your project already has a custom config set. In order for CocoaPods integration to work at all, please either set the base configurations of the target `Runner` to `Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig` or include the `Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig` in your build configuration (`Flutter/Release.xcconfig`).
```

- メッセージ通り`Flutter/Release.xcconfig`を以下のように設定したらエラーなくなった
```conf
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig"
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"
```


- ちなみにcursorに修正方法を聞くと`?`を削除するように言われた。。。もちろん直らない😇

```
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig"
```

- 今までちゃんと動いてたので
iphoneを13から16eに機種変して、iosを18.4.1にバージョンアップして色々環境変わった時に消えた？
まぁinstall出来て良かった！
Java解説 20250424

### 代入
| 演算子 |　記述例 | 説明　|
| ---- | ---- | ---- |
| = | a = b | aにbを代入する |
| += | a += b | aにbを加えた値を代入する |
| -= | a -= b | aからbを引いた値を代入する |
### 関係演算子
| 演算子 |　記述例 | 説明　|
| ---- | ---- | ---- |
| == | a == b | aとbの値が等しければtrue、異なればfalse |
| != | a != b | aとbの値が異なればtrue、等しけれればfalse |
| && | a && b | aとbの両方がtrueのときtrue、異なればfalse|
| \|\| | a \|\| b | aとbいずれかがtrueならtrue、異なればfalse |
<br>

[オラクル認定資格教科書 Javaプログラマ Bronze SE(試験番号1Z0-818)](https://www.amazon.co.jp/%E3%82%AA%E3%83%A9%E3%82%AF%E3%83%AB%E8%AA%8D%E5%AE%9A%E8%B3%87%E6%A0%BC%E6%95%99%E7%A7%91%E6%9B%B8-Java%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E-Bronze-SE-%E8%A9%A6%E9%A8%93%E7%95%AA%E5%8F%B71Z0-818/dp/479816206X/ref=pd_lpo_d_sccl_1/357-5313211-9846263?pd_rd_w=VQCzo&content-id=amzn1.sym.855d8f70-df76-4181-80b0-56e48ae3bb9b&pf_rd_p=855d8f70-df76-4181-80b0-56e48ae3bb9b&pf_rd_r=JRR4W9RKV32K4AXF1WRZ&pd_rd_wg=l7VoD&pd_rd_r=1d465f85-0562-4b51-b523-77f8486c1508&pd_rd_i=479816206X&psc=1 "オラクル認定資格教科書 Javaプログラマ Bronze SE(試験番号1Z0-818)")
Your Prompt Template(フロー)でのUIのエラー



+ [Add a Flow to Your Prompt Template](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000PYz9S)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/8874ade2-f623-4a28-b56a-9feaa92a23ac.png)


:::note
I appreciate your help. Actually I was getting the error due to some JS code ingestion browser extension that I was working on. Switching to another browser helps me. 


https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007ZB9KYSA1
:::

# 2番のType add and select the Add Prompt Instructions element to add to the flow.が機能しない

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/2cffd529-82af-4eec-b7b5-2e8113d4fae0.png)

+ [i couldnt able to find Add Prompt Instructions in add section anyone help me in completing this process](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000TkegS)

:::note
Please make sure you have enabled this flow
:::
【A Tour of Go】Go言語のポインタをわかりやすく解説！


先日、Go言語のインターンに参加する機会がありました。そのため、その復習も兼ねて、Go公式チュートリアルの「A Tour of Go」に取り組んでいます。

今回はその中でも「More types: structs, slices, and maps.」の章を進める中で、ポインタの仕組みについて、分かりにくいと感じた部分を中心にまとめました。

間違いや勘違いがあればぜひコメントで教えていただけると嬉しいです🙇
Go初学者の方の参考になれば幸いです！
# Pointers
ポインタとは、「ある変数がメモリ上のどこにあるか（住所）」を表す値です。
今回はポインタを家、住所に例えてコード例を用いながら解説します。

ポインタを用いたコードの例
```Go
package main

import "fmt"

func main() {
    x := 42         // x は int 型
    p := &x         // pにxのアドレスを代入すると、pはintのポインタ型 になる
    
    fmt.Println(x)  // 42（普通に出力される）
    fmt.Println(p)  // 0xc000014088（xのメモリアドレス）
    fmt.Println(*p) // 42（ポインタが指す先の値を出力）
}
```

このコードをわかりやすく解説します！

```
        ~~~~~~~~~
       /         \    
      /___________\   
     |             |   
     |   x = 42    |   x = 42という家がある(実体)
     |_____________| 　
           ↑
    ポインタ変数pを辿って、x=42にアクセスできる
           ↑
    &xで xの住所0xc000014088を取得する

```
:::note info
x = 42 という「家」がある。
&x で「この家の住所」を取得する。
p は「その家の住所を記録したメモ」。
*p を使うと、住所をたどって「家の中にある値(42)」を取り出せる。
:::

Goではポインタを比較的シンプルに使うことができます。
わからないと思っていた人も、この記事で理解してくれたらうれしいです！