OmniAICreator/Qiita-1.07M huggingface dataset:
【ドメイン駆動設計入門】-ファクトリについて解説

# はじめに
本記事では、ドメイン駆動設計のパターンとして用いられるファクトリについて、初心者向けに解説したものです。

https://qiita.com/yoron0122/items/789e71cb277434be7bad
# 対象読者層
- **ドメイン駆動設計初心者**  
- **オブジェクト指向プログラミングに慣れている方**  
- **複雑なビジネスロジックを扱うシステム開発者**  

# ファクトリの目的
ファクトリは、**複雑なオブジェクト生成の責務を専用のクラスに委譲する**ためのパターンです。  
DDDでは、エンティティや値オブジェクト、集約などの生成過程において、以下の目的があります。

## 生成処理の分離
ドメインオブジェクトの生成ロジックを専用クラスに切り出すことで、ドメインモデル自体をシンプルに保ちます。

## ビジネスルールの適用
オブジェクト生成時に、業務上のルール（例：初期状態の整合性チェックや制約の検証）を適用し、不整合な状態を防ぎます。

## 変更への柔軟な対応
オブジェクト生成ロジックが集中管理されるため、仕様変更があった場合でもファクトリ側を修正すれば済み、保守性が向上します。

また、ファクトリクラスは開発者にとって重要な役割を担うため、専用のパッケージ（例：`com.example.factory`）に配置するなど、**開発者がその存在に気付けるよう工夫する**ことが望まれます。

# サンプルコード
以下は、Javaを例にしたシンプルなファクトリ実装例です。  
ここでは、`Product`（商品）オブジェクトの生成を、別クラスの`ProductFactory`で担っています。

## Product クラス
```java
package com.example.domain;

public class Product {
    private String name;
    private double price;

    // コンストラクタは直接のインスタンス生成を避けるため、利用には注意が必要です。
    // ※完全に隠蔽するためには、同一パッケージ内でのみアクセス可能なパッケージプライベートや
    // protected にする方法もありますが、今回はファクトリクラスを別パッケージに配置するため、public としています。
    public Product(String name, double price) {
        this.name = name;
        this.price = price;
    }

    // getterメソッドなどのドメインロジックを追加可能
    public String getName() {
        return name;
    }
    
    public double getPrice() {
        return price;
    }
}
```

## ProductFactory クラス

```java:ProductFactory.java
package com.example.factory;

import com.example.domain.Product;

public class ProductFactory {
    // Productオブジェクトを生成するメソッド
    public static Product createProduct(String name, double price) {
        // ビジネスルールのチェック（例：価格は0以上でなければならない）
        if (price < 0) {
            throw new IllegalArgumentException("価格は0以上でなければなりません。");
        }
        return new Product(name, price);
    }
}
```

この例では、ProductFactory を独立したクラスとして定義し、別パッケージ（com.example.factory）に配置することで、コードベース内でファクトリの存在や役割が明確になり、開発者が利用すべき場所として認識しやすくなっています。

# ファクトリの注意事項
ファクトリを利用する際には、いくつかのポイントに注意する必要があります。

## 必要以上の抽象化を避ける
単純なオブジェクト生成であれば、無理にファクトリを導入する必要はありません。複雑な生成ロジックや複数の依存関係がある場合に使用しましょう。

## ビジネスロジックの混在に注意
**ファクトリはオブジェクト生成に特化するべき**で、他のビジネスロジックを組み込みすぎると責務が曖昧になります。生成に必要なルールのみを実装するよう心がけましょう。

## テストの容易さを考慮する
ファクトリ内の処理が複雑になる場合、ユニットテストで生成処理が正しく動作するかを検証することが重要です。特に、例外処理や境界条件のチェックは十分にテストしましょう。

## パッケージ設計の工夫
ファクトリクラスは、その役割が明確になるよう、専用のパッケージに配置することが推奨されます。これにより、プロジェクト全体の構造が整理され、他の開発者も**ここにファクトリクラスがある**と直感的に理解できるにすることが大切です。

# まとめ
ファクトリパターンは、DDDにおいてドメインオブジェクトの生成責務を明確に分離し、整合性や保守性を向上させるための有用な手法です。

本記事ではドメイン駆動設計入門 として解説しましたが、ドメイン駆動設計ではない開発現場でも有効です。
※元々は、[デザインパターン-ファクトリーパターン](https://ja.wikipedia.org/wiki/Factory_Method_%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3) から来ています。

とはいえ、全てのインスタンス生成でファクトリを採用する必要はありません。
大切なのは、**このインスタンス生成は、ファクトリにすることができないか**常に考えることです。

常にアンテナを張ることで、複雑なインスタンス生成に対し敏感になることができます。

インスタンスの生成に複雑なルールが存在する場合は、ファクトリを採用してみてください。
【2025年】Proxmoxインストール:isoイメージをUSBメモリに書き込む【balenaEtcher】

## はじめに

Proxmoxを使用しなくなったPCにインストールするため、isoイメージをUSBメモリに書き込んでインストールメディアを作成していきます。

数GBのisoイメージを書き込むので、8GB程度のUSBメモリを準備して、手順を実施するPCに接続しておきます。

## 手順

1. Proxmoxイメージのダウンロード
2. balenaEtcherのダウンロード
3. balenaEtcherを実行してインストールメディアを作成
4. インストールメディアを使用してProxmoxを起動

## 1.Proxmoxイメージのダウンロード

以下の公式からisoインストーラーを取得します。
最新リリースを確認して、ダウンロードを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692063/9ac125af-20d9-0288-6e39-0446afe8d120.png)

https://www.proxmox.com/en/downloads

## 2.balenaEtcherのダウンロード

以下の公式リンクから環境に応じたbalenaEtcherをダウンロードします。

https://etcher.balena.io/

## 3.balenaEtcherを実行してインストールメディアを作成

balenaEtcherを開きます。
画面に従って、左から進めます。

1. ダウンロードしておいたisoイメージを選択
2. USBメモリを選択
3. Flashを選択
    a. PWを聞かれたらPCのPWを入力

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692063/4b3e6153-c706-d09d-22ec-a688965655ca.png)

isoイメージの書き込みが始まります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692063/9fab512f-3a42-28b3-1ccc-2ca559d83eb7.png)

完了しました！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692063/d38accea-7610-1fa6-ab67-95d7429ff289.png)

## 4.インストールメディアを使用してProxmoxを起動

USBメモリを取り外して、ProxmoxをインストールするPCに接続して起動します。
起動中にOptionキーを押せばbootdiskを選択できますので、disk名にpmxとあるものを選び起動します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692063/ec6d35d4-0589-49e0-84be-1852fa3724e3.png)

以下のような画面になるので、有線LANにつながれていることを確認して、Install Proxmox VEを選択するとインストールに進みます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692063/e75bb3c6-8bbe-41e2-9651-0152a00caab3.png)

あとは、ガイドに沿って設定を済ませてインストールを進めていきましょう！
SAP Databricksのご紹介

[Introducing SAP Databricks \| Databricks Blog](https://www.databricks.com/blog/introducing-sap-databricks)の翻訳です。

:::note warn
本書は著者が手動で翻訳したものであり内容の正確性を保証するものではありません。正確な内容に関しては原文を参照ください。
:::

:::note info
**サマリー**
- このパートナーシップによって、お客様はエージェントシステムを含む高度な分析とAIユースケースで、SAPデータとその他の企業データをインテグレーションできるようになります。
- SAP DatabricksはSAP Business Data Cloudのネイティブのコンポーネントとなります。
- SAP Databricksによって、お客様はSAP Databricksと自身の企業環境間で双方向でデータを共有しつつも、SAPデータがそのセマンティクスを維持できるようになります。
:::

本日、我々は自身の業界のゲームジェンジャーとなりうると考える、SAPとのディープなパートナーシップを発表します。簡単に言えば、企業全体において最も重要なビジネスデータ(SAPデータ)と市場でベストなデータプラットフォーム(Databricks)との結婚と言えます。我々の新たなオファリングであるSAP Databricksは、Azure、AWS、GCPの[SAP Business Data Cloud](https://news.sap.com/?p=231445)の一部として販売されます。SAP Databricksは、お客様に対してUnity Catalogによってすべてが管理される、人工知能、データウェアハウス、データエンジニアリングの機能を提供します。

過去数年においてDatabricksは、データエンジニアリング、データウェアハウス、ガバナンス、BI、AIに渡るデータとAIの領域をより広くカバーしようと自身の製品ポートフォリオを拡張し続けていました。我々のお客様にこれらの拡張を発表する都度、お客様からは「SAPデータはどうなっているの？これに対する計画は？」との質問をいただており、お客様の多くが肯定するを目撃していました。これは、SAPを活用しているFortune 500の企業の90%にとって、ビジネス計画のためのERP、調達のためのAriba、HRのためのSuccessFactorsを支えるSAPデータによるものです。SAP外のモダンデータプラットフォームでこの重要なデータを活用することはうんざりすることであり、困難なことでした。

だからこそ、我々はこのパートナーシップは我々のカスタマーベースに大きなインパクトを与えると考えているのです。SAP Databricksは、データウェアハウスからデータに基づいた推論を行うことができるAIエージェントの構築に渡るすべてに活用でき、補強された適切なデータセットのすべてを保有することになります。私たちはこれを汎用インテリジェンスではなく、この重要なビジネスデータに対して推論を行えるAIとしtデータインテリジェンスと呼びます。

![](https://www.databricks.com/sites/default/files/inline-images/databricks-sap-launch-blogimage.png?v=1739433257)

このパートナーシップの背後にある真の魔法は、企業は容易に自身のSAPデータを自分の他の企業データと組み合わせることができるということです。SAP Business Data Cloudは、お客様がSAP DatabricksとDelta Sharingを通じたすべての既存Databricksデプロイメント新規デプロイメントに存在するコンテキストが豊富なSAPデータから洞察とビジネス価値を解放する手助けをします。これによって、チームがこれらのデータセットを活用しようとする際の生産性を劇的に増加させることを期待しています。

Databricksにおいては、ちょうど[$15Bのファンドレイズ](https://www.databricks.com/company/newsroom/press-releases/databricks-announces-15B-financing-ai-talent-global-expansion)を完了したところです。我々は、デプロイメント、移行、最終的にはSAPデータで計り知れないビジネス価値を得られるように、SAP Databricksでお客様やSIパートナーが成功裡に遂行できる手助けをするために$250Mを投資するつもりです。

我は、この長期にわたるパートナーシップを嬉しく思っており、SAP Databricksでこのようなビジネスデータすべての価値を解放できることを楽しみにしています。

[SAP Databricksのウェイトリストに登録](https://www.databricks.com/resources/others/sap-databricks)

### はじめてのDatabricks

[はじめてのDatabricks](https://qiita.com/taka_yayoi/items/8dc72d083edb879a5e5d)

### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)
今さらだけど、DDos攻撃について学び直してみた

### 今さら学び直そうと思ったきっかけ
AWS Certified Security - Specialty　の学習をしているときに下記３つのサービスが出てきた
* AWS Shield Standard
* AWS Shield Advanced
* AWS WAF

その中で**AWS Shield Standard**と**AWS Shield Advanced**は**ネットワーク層（レイヤー3）**及び**トランスポート層（Layer 4）**への攻撃に対応し、**WAF**が**アプリケーション層（Layer 7）** への攻撃に対応するとあった。

DDos攻撃には対象のレイヤーが３つあって、それぞれどんな攻撃なのかを調べてみた

## DDos攻撃とは？
**DDOS攻撃** とは、「Distributed Denial of Service attack（分散型サービス拒否攻撃）」のこと

多数のコンピュータを使って特定のサーバやネットワークに大量のリクエストを送りつけ、サービスを一時的に利用不能にする攻撃手法である

## なぜ攻撃を行うのか？
DDoS攻撃を受けると、以下のような影響が考えられます：

* サーバーのダウンやレスポンスの低下
* 競争相手の妨害
* 金融機関への攻撃による経済的損失
* 特定の組織や政府への抗議活動


## 各レイヤーへの攻撃詳細
### ネットワーク層（Layer 3）に対する攻撃
ネットワーク帯域やルーティングを狙って、WEBサーバへのトラフィックを妨害する

#### 攻撃例

* ##### ICMPフラッド
攻撃者が大量のICMP（Internet Control Message Protocol）エコー要求パケットを送信し、ターゲットのネットワークを圧迫する。これにより、ネットワーク帯域が埋まり、サービスが利用不能やレスポンスを低下させる。

* ##### Smurf攻撃
攻撃者が偽装された送信元アドレスを使用してブロードキャストアドレスにICMPエコー要求を送信し、ターゲットに大量の応答を送らせることで、ネットワークを圧迫する。

### トランスポート層（Layer 4）に対する攻撃
トランスポートプロトコルを利用して、WEBサーバへの接続を妨害する

#### 攻撃例

* ##### SYNフラッド
攻撃者が大量のTCP接続要求（SYNパケット）を送信し、ターゲットのサーバが接続を確立するためのリソースを使い果たすようにする。これにより、正当な接続要求を処理できなくなる。

* ##### UDPフラッド
攻撃者が大量のUDP（User Datagram Protocol）パケットを送信し、ターゲットのネットワーク帯域を消耗させる。

### アプリケーション層（Layer 7）に対する攻撃
WEBサーバ自体のリソースを狙って直接的にサービスを妨害する

#### 攻撃例
* ##### HTTPフラッド
攻撃者が大量のHTTPリクエストを送信し、ウェブサーバの処理能力を圧迫する。これにより、正当なユーザーがウェブサイトにアクセスできなくなる。

* ##### Slowloris攻撃
攻撃者がHTTPヘッダーを非常にゆっくりと送信し、サーバの接続を長時間占有することで、他の接続を妨げる。これにより、サーバのリソースが枯渇する。

## 現実世界の例えで理解する
:::note info
A店とB店が存在します。A店はとても人気で、みんながA店に行きます。B店はA店を邪魔して、自分の店に来てもらうことを目的としてA店を攻撃します。  
:::  
* **ネットワーク層（Layer 3） への攻撃** : A店に繋がる道路に大量の車を走らせて渋滞を発生させ、他の客がA店にたどり着けないようにする。   
<br>

* **トランスポート層（Layer 4）への攻撃** : A店に大量の偽の予約を入れ、実際の客が予約できないようにする。
<br>

* **アプリケーション層（Layer 7）への攻撃**: A店にたくさんの人で押しかけ満員にして他の顧客が入れないようにする、または店員に話しかけ続けて他の顧客の対応を妨げる。
Nextjs on Lambdaで気を付ける点

## 概要
以前動いたコードが動かなくて3時間つぶしたので、忘れないように記載する

## 内容

https://qiita.com/murodon/items/d6a94c448caea9111bc6

基本的にこれに従えばよい。ほかの記事へのリンクなどもしっかりあるのでわかりやすい。

今回問題となった事象は次の通りである。

1. デプロイされたURLにアクセスしたところ空のファイルがダウンロードされてしまう
1. run.shの起動スクリプトがこけていることがCloud Watchのログから判明。
1. 参考サイトコピペであるので正しいはずである。
1. どうやら、改行コードが違うらしい。＜ー解決

改行コードがLFになることで解決可能である。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3125890/8f77f225-eab2-47a9-915f-1f6fedc9f301.png)

このような表示になっている場合は、同じ解決策が使える可能性があるため、改行コードを修正するとよい
Raspberry Piのrpi-rgb-led-matrixで上手くいかないときのトラブルシュート

Raspberry Piで電光掲示板（RGB LEDマトリックス）を制御できる、`rpi-rgb-led-matrix`で、上手くデモの四角を表示できなかったときのトラブルシュートメモです。

https://github.com/hzeller/rpi-rgb-led-matrix

（環境：Raspberry Pi 4 + Raspberry Pi OS）

# 想定される問題

想定される問題は、大きく分けて以下の2つかなと思います。
（ジャンパワイヤなどの配線自体の不良も考えられますが、、基本的にはそこまで発生しやすいものではないかなと思います。）

## HW: 配線ミス

人間が配線を繋いでいるので、もっともありうるのはこちらでしょう。
ひたすらニラメッコするしかないです。左右反転して勘違いしていたりすることも稀にあります。。

## SW: コマンドが間違っている

指定する必要があるオプションが漏れているか、指定しなくて良いオプションをしているケースなどがあります。
変なLEDを買わなければ、基本的にネットで落ちているコマンドで動くかなと思います。

# 具体的な事例

## 動くは動くが、帯状で表示されない部分がある

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3789636/8582748c-fb18-4a1f-bc90-da0a0888764f.png)

私はこれでした。1日くらい悩みましたが、**--led-colsの指定ミス**でした。
16x32のLEDマトリックスを使っていると勘違いしていましたが、よくよくドット数を数えると32x64でした・・・

## 光るが、全く想定通りでない

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3789636/628a9556-92f3-41de-a049-c7cc566d3b7f.png)


ネットではこうなっている方も見つけました。
考えられる原因としては以下がありそうです。
- 配線が一部正しくなっていない（特に、A/B/C/Dなどの制御系の線）
- LEDマトリックスが特殊なもので専用のコマンドが必要。（ただし、特殊なパネルは全体からすると割合は低いと思います）

## 一部の色が出ない

これは中々無いと思いますが、RGBの3原色でカラフルにしているため、特定の色の接続を切るとその色が出なくなります。

# Enjoy rotating square !

上手く行った例

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3789636/66053808-22d0-407e-8970-9424db4933da.png)
react-hook-form×yupでユーザー名の重複チェックを行う

# はじめに
現在TypeScript×Next.js×Rails APIでSNSアプリを作成しています。
**ユーザー名の重複チェックをフロント側でできないだろうか、とググっていた時にreact-hook-form×yupで実装できるようなので**やってみました。

### yupとは
バリデーションチェックのためのライブラリです。
スキーマを定義して、バリデーションのルールや表示するエラーメッセージを自由に設定・適用できます。

https://github.com/jquense/yup

# 手順

入力値に対してバリデーションを実行するスキーマを定義し、バリデーションをカスタマイズしていきます。

https://github.com/jquense/yup?tab=readme-ov-file#validation-tests

react-hook-formとyupの統合には`Resolver`を使います。

https://react-hook-form.com/advanced-usage#CustomHookwithResolver

これらを踏まえて作成したサンプルコードは下記です。
※入力項目は複数ありますが、ユーザー名の処理のみ抜粋
```page.tsx
interface IFormInput {
  username: string;
}

// バリデーションスキーマを定義
const postSchema = yup.object().shape({
  username: yup
    .string()
    .required(`ユーザー名は必須です`)
    .test("sameusername", "ユーザー名が重複しています", async (input) => {
      const response = await getPosts();
      return !response.some((post: any) => post.username === input);
    }),
});

export default function Page() {

  const router = useRouter();
  const {
    register,
    handleSubmit,
    reset,
    formState: { errors },
  } = useForm<IFormInput>({
    resolver: yupResolver(postSchema), // yupを使ったバリデーションを設定
  });

  //（バックエンドとの連携部分）
  const postPostFunc = async (post: IFormInput) => {
    await postPost(post);
    if (router) {
      router.push("/posts");
    }
  };

  const onSubmit: SubmitHandler<IFormInput> = async (data) => {
    postPostFunc(data);
    reset();
  };

  return (
    <div>
      <h2 className="text-2xl font-bold text-indigo-800 dark:text-white mb-4">
        投稿作成
      </h2>
      <form onSubmit={handleSubmit(onSubmit)}>
        <div>
          <label className="block mb-2 text-indigo-500">ユーザー名</label>
          <input
            className="w-full p-2 mb-2 text-indigo-700 border-b-2 border-indigo-500 outline-none focus:bg-gray-300"
            type="text"
            {...register("username")}
          />
          {errors.username && (
            <p className="text-red-500">{errors.username.message}</p>
          )}{" "}
        </div>

        <button
          className="w-full bg-indigo-700 hover:bg-pink-700 text-white font-bold py-2 px-4 mb-6 rounded"
          type="submit"
          disabled={Object.keys(errors).length > 0} // エラーがある場合は無効化
        >
          投稿
        </button>
      </form>
    </div>
  );
}

```
# おわりに
今回yupの存在を初めて知りました。
最初はバックエンドでもバリデーションを実装して。。みたいな流れも考えていましたが、フロント側で完結できるのがありがたかったです。

# 参考

https://qiita.com/shin_k_2281/items/00174a6b754f31de9f37
個人的備忘録：Go言語の構造体について理解が追いつかない部分があったため、JSONのエンコード・デコードを試してみた

## はじめに

ITスクールのハッカソンでGo言語を使った開発に取り組んでいます。

:::note info
**その中で、データを効率的に管理できる構造体（struct）の活用が重要だと感じました。**
:::

本記事では、Goの構造体の基本と実践的な使い方を紹介します。

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

ハッカソンを通じて、Goの構造体の特徴や活用法を深く理解したいと考えました。

***特に、メソッドの定義やJSONとの相互変換など、実務にも役立つ知識を整理します。***

## Go言語の構造体（Structs）について

### 構造体とは？

Go言語における構造体（struct）は、異なる型のフィールドを1つのデータ型としてまとめる仕組みです。

https://www.sejuku.net/blog/24473

これにより、関連するデータを整理し、扱いやすくすることができます。

### 構造体の定義と使用例

```go
package main

import "fmt"

// Person構造体の定義
type Person struct {
    Name string  // 名前
    Age  int     // 年齢
}

func main() {
    // Person構造体のインスタンスを作成
    p := Person{Name: "Taro", Age: 30}
    fmt.Println(p) // 出力: {Taro 30}
}
```

### メソッドの定義

Goの構造体は、レシーバを定義することでメソッドを持つことができます。

```go
// Rectangle構造体の定義
type Rectangle struct {
    Width, Height float64  // 幅と高さ
}

// 面積を計算するメソッド
func (r Rectangle) Area() float64 {
    return r.Width * r.Height
}

func main() {
    // Rectangleのインスタンスを作成
    rect := Rectangle{Width: 10, Height: 5}
    fmt.Println("面積:", rect.Area()) // 出力: 面積: 50
}
```

### ポインタレシーバを用いたフィールド変更

```go
// Counter構造体の定義
type Counter struct {
    Count int  // カウント
}

// 値をインクリメントするメソッド（ポインタレシーバ）
func (c *Counter) Increment() {
    c.Count++
}

func main() {
    // Counterのインスタンスを作成
    c := Counter{Count: 0}
    c.Increment()
    fmt.Println("カウント:", c.Count) // 出力: カウント: 1
}
```

### 構造体の埋め込み（擬似的な継承）

```go
// Animal構造体の定義
type Animal struct {
    Name string  // 名前
}

// Speakメソッドの定義（動物が鳴く）
func (a Animal) Speak() {
    fmt.Println(a.Name, "が鳴く")
}

// Dog構造体の定義（Animalを埋め込み）
type Dog struct {
    Animal
    Breed string  // 犬種
}

func main() {
    // Dogのインスタンスを作成
    d := Dog{Animal: Animal{Name: "Pochi"}, Breed: "Shiba"}
    d.Speak() // 出力: Pochi が鳴く
}
```

## 実際に使ってみた

環境構築がまだの方は、過去の記事で紹介していますので参考にしてください。

https://qiita.com/free-honda/items/b3672e2ccfedbb14773a

Goの構造体を使って、JSONのエンコード・デコードを試してみました。

```main.go
package main

import (
    "encoding/json"
    "fmt"
)

// User構造体の定義
type User struct {
    Name  string `json:"name"`   // ユーザー名
    Email string `json:"email"` // メールアドレス
}

func main() {
    // Userのインスタンスを作成
    u := User{Name: "Taro", Email: "taro@example.com"}
    
    // JSONにエンコード
    jsonData, _ := json.Marshal(u)
    fmt.Println(string(jsonData)) // 出力: {"name":"Taro","email":"taro@example.com"}
}
```

ターミナルで `main.go` があるディレクトリへ移動し、以下のコマンドを実行  

```sh
go run main.go
```

**実際のターミナル画面**

![Screenshot 2025-02-13 at 20.55.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/b0c710b8-ea08-4ec0-b486-8c160a43923a.png)


JSONとの相互変換が非常にシンプルに行えるため、API開発にも役立ちそうです。

## まとめ

- 構造体を使うことで、異なる型のデータを整理できる。
- メソッドを定義することで、データ構造に振る舞いを追加可能。
- ポインタレシーバを利用すると、フィールドの変更が可能。
- 埋め込みを使うことで、コードの再利用性を高められる。
- `encoding/json` を活用してJSONのエンコード・デコードが簡単にできる。

Goの構造体はシンプルながら強力な機能を持っており、実際の開発で非常に役立つものです。今回の記事を通じて、Goの構造体の使い方が少しでも理解しやすくなれば幸いです。
AOT vs JIT Compiler: Understanding the Differences

Compilers play a crucial role in converting human-written code into machine-executable instructions. Among the various types of compilers, [Ahead-of-Time (AOT) and Just-in-Time (JIT) compilation](https://www.monarch-innovation.com/aot-vs-jit-compiler-in-angular) are two commonly used methods. Both have distinct approaches and advantages, depending on the requirements of the application.
## What is AOT Compilation?
Ahead-of-Time (AOT) compilation translates code into machine code before execution. This method is commonly used in languages like C and C++, where the entire program is compiled before running. In modern frameworks like Angular, AOT compiles the code during the build process, optimizing the application for faster execution.
### Advantages of AOT:
- Faster runtime performance as code is already compiled
- Improved security by reducing runtime code manipulation
- Better optimization, leading to enhanced efficiency
### Disadvantages:
- Slower initial compilation time
- Larger file sizes due to precompiled binaries
## What is JIT Compilation?
Just-in-Time (JIT) compilation compiles code during execution, meaning that parts of the program are compiled as needed. This method is used in languages like Java (via the JVM) and JavaScript (in browsers). JIT compilers analyze runtime behavior and optimize performance dynamically.
### Advantages of JIT:
- Faster development and debugging process
- Dynamic optimizations based on runtime conditions
- Reduces initial build time
### Disadvantages:
- Slower startup time due to real-time compilation
- Higher memory consumption
- Potential security risks from runtime code execution
## AOT vs JIT: Which One to Choose?
The choice between AOT and JIT depends on the use case:
- For performance-critical applications (e.g., Angular, C/C++ apps), AOT is preferred because it enhances speed and security.
- For dynamic applications (e.g., Java, JavaScript), JIT is ideal as it provides flexibility and runtime optimizations.

Both methods have their place in [software development](https://www.monarch-innovation.com/web-app-development) and modern compilers often use a mix of both to achieve the best results.
【C#】手っ取り早くNLogを導入する(3分)

超ざっくり手順。
初心者の方でこの記事にたどり着いてしまった方はすみません、戻って別の記事を読んでください。

## 手順
(1)NugetでNLogをインストールする。
(2)NLog.configを追加する
(3)NLog.configに次の内容を全コピペする。
~~~NLog.config
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      autoReload="true"
      throwExceptions="true"
      internalLogLevel="Off" internalLogFile="./logs/nlog_internal.log">

	<targets>
		<!-- ファイル -->
		<target name="logFile"
                xsi:type="File"
                encoding="UTF-8"
                writeBom="true"
                lineEnding="Default"
                layout="${longdate} ${level:uppercase=true:padding=-5} [${threadid}] ${logger} - ${message} ${exception:format=tostring}"
                fileName="./logs/${processname}.log"
                archiveFileName="./logs/backup/${processname}_{###}.log"
                archiveEvery="Day"
                archiveNumbering="Sequence"
                maxArchiveFiles="20" />
	</targets>
	<rules>
		<logger name="*" minlevel="Trace" writeTo="logFile" />
	</rules>
</nlog>
~~~
(4)NLogを使いたいクラスのメンバー変数として以下を追加する。
~~~NLogUsed.cs
static NLog.Logger _logger = NLog.LogManager.GetCurrentClassLogger();
~~~
(5)上記の_loggerの適当なメソッドを呼べばログを吐く。
~~~NLogUsed.cs
_logger.Info("やったぜ！");
~~~

## 忘備録
使用する他のプロジェクトでもNLogを使用したい場合、
そのプロジェクトでもNLogのインストールは必要だが、NLog.configの作成はしなくてよい。
NLog.configはエントリーポイントがあるプロジェクトで、設定値が1度だけ読み込まれる。
Macbook Proの環境構築

# はじめに
自分用の記録として書いてます

# 設定

**スクロール:**
`Accessibility`>`Pointer Control`>`Trackpad Options`>`Scroll speed`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3115402/6ead3f4c-af23-410c-b00c-d833e5323e5b.png)

**トラッキングスピード**
`Trackpad`>`Point & Click`>`Tracking speed`

**クリックの強さ**
`Trackpad`>`Point & Click`>`Click`

**ブラウザバック**
`Trackpad`>`More Gestures`>`Swipe between pages`

**スクリーンの移動**
`Trackpad`>`More Gestures`>`Swipe between full-screen applications`


# Homebrew
Homebrewは、Macでのソフトウェアインストールを簡単にするパッケージマネージャです。

**インストールコマンド:**
```
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```

**パスの設定:**
```
echo >> /Users/[ユーザー名]/.zprofile
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> /Users/[ユーザー名]/.zprofile
eval "$(/opt/homebrew/bin/brew shellenv)"
```

# ソフトウェア
- git
- slack
- discord
- microsoft-teams
- powerpoint
- word
- outlook
- excel
- zoom
- windsurf
- rectangle
- Arc
- Notion Calendar
- AWS CLI
- MySQL Workbench

```
brew install git
brew install slack
brew install --cask discord
brew install microsoft-teams
brew install --cask microsoft-powerpoint
brew install --cask microsoft-excel
brew install --cask microsoft-word
brew install --cask microsoft-outlook
brew install zoom
brew install --cask windsurf
brew install --cask rectangle
brew install --cask arc
brew install --cask notion-calendar
brew install awscli
brew install --cask mysqlworkbench
```
時系列データのベイズ推定アルゴリズム(モクモク開発)

とりあえずMemo：

```math

\displaylines{
Z(t) \sim N(HX(t),{\sigma}_{1}^{2}I), X(t)\sim N(FX(t-1),I)を考えるとき, \\
単純のため, X(t)=\sum_{k=1}^{m} a_{k} X(t-k)+w, w \sim N(0,1)\\
           Z(t)=\beta X(t) +v, v\sim N(0,{\sigma}_{1}^{2}) \\
として, 各パラメータが\beta \sim N(1,1), (a_{1}, ... , a_{m}) \sim N(0,{\sigma}_{1}^{2}I),\\
{\sigma}_{1} \sim Invgamma(\sigma, 3, 2) 
に従うとして, 計算すると, 尤度部分が\\
\frac{N}{\sqrt{2 \pi (\beta^{2}+\sigma_{1}^{2})}} \prod_{t}^{N} exp(-\frac{(Z(t)-\beta \sum_{k=1}^{m} a_{k} X(t-k))^{2}}{2(\beta^{2}+\sigma_{1}^{2})})\\
となる(はず). 各パラメータの分布から事前分布を考えてメトロポリスヘイスティ\\
ング法を行って計算した. Z(t), X(t)はデータとして得られている構想.\\
}


```
おっ、なんかとりあえず使えそう（笑）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230981/3056f5e8-3ca1-475f-885f-4758297788b6.png)

回帰パラメータの事前分布の平均が０にしてあるから、尤度の影響が少ないパラメータは事前分布を優先して勝手に０になっているところがよろし。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230981/ae079faf-b738-4ca5-afac-9bc65658db9d.png)


```r
data("EuStockMarkets")
dat=EuStockMarkets

Z=dat[,1]
X=dat[,2]

Y=as.numeric(Z)

#特徴量と目的変数を編集
p=6
y=c()
Xn=array(0,dim=c(length(Y)-p,p))
for(j in 1:nrow(Xn)){
val=Z[length(Y)-j+1]  
y=c(y,val)
vec=X[(length(Y)-j):(length(Y)-j-p+1)]
Xn[j,]=vec  
}
N=length(y)
Y=y



#確率勾配法にて最尤推定した値を初期値としてベイズ推定
#メトロポリスヘイスティング法
library(MCMCpack)
sigma=1

#逆ガンマ分布のパラメータ
v=3 #Scale
w=2*sigma #Shape
n=ncol(Xn)

posterior=function(x){
aa=x[1:(n)];x=x[-c(1:n)]
bb=x[1];x=x[-c(1)]
ss=x
likelihood=-length(Y)*log(2*pi*(bb^2+ss^2))/2-sum((y-bb*Xn%*%aa)^2)/(2*(bb^2+ss^2))
return(likelihood+sum(log(dnorm(aa,0,1)))+sum(log(dnorm(bb,1,1)))+sum(log(dinvgamma(ss^2,v,w))))
}


ite=6000
eta=10^(-1)
posterior_values=c()
A=(solve(t(Xn)%*%Xn)%*%t(Xn)%*%Y)
B=1
S=1

for(l in 1:ite){


for(j in 1:length(A)){
  
#Aの更新
a0=rnorm(1,A[j],1)  
A0=A;A0[j]=a0
r=min(c(1,exp((posterior(c(A0,B,S))-log(dnorm(a0,A[j],1)))-(posterior(c(A,B,S))-log(dnorm(A[j],a0,1))))))
val=sample(c(0:1),1,prob=c(r,1-r))
#if(val==0){A=A0}
#if(val==0){A=A*(1-r)+A0*r}
if(val==0){A=A*(1-eta)+A0*eta}
A[A<0]=10^(-5)
}

#Bの更新
b0=rnorm(1,B,1)  
B0=B;B0=b0
r=min(c(1,exp((posterior(c(A,B0,S))-log(dnorm(b0,B,1)))-(posterior(c(A,B,S))-log(dnorm(B,b0,1))))))
val=sample(c(0:1),1,prob=c(r,1-r))
#if(val==0){B=B0}
#if(val==0){B=B*(1-r)+B0*r}
if(val==0){B=B*(1-eta)+B0*eta}  
  
#Sの更新
s0=rnorm(1,S,1)  
S0=S;S0=s0
r=min(c(1,exp((posterior(c(A,B,S0))-log(dnorm(s0,S,1)))-(posterior(c(A,B,S))-log(dnorm(S,s0,1))))))
val=sample(c(0:1),1,prob=c(r,1-r))
#if(val==0){S=S0}
#if(val==0){S=S*(1-r)+S0*r}
if(val==0){S=S*(1-eta)+S0*eta}


print(posterior(c(A,B,S)))
posterior_values=c(posterior_values,posterior(c(A,B,S)))

}

plot(posterior_values)
cor(Y,B*Xn%*%A)

```
OS（オーエス）とは

OS（オーエス）とは？
**OS（Operating System：オペレーティングシステム）** は、コンピュータを動かすための「基本プログラム」のこと。

例えば、iPhone（モノ）を持っていたとして、その中には基本プログラム（OS）が、入っています。モノだけがあっても、プログラムが入っていないとただの動かないモノになっちゃうのです。

セットで考えます
例えば、iPhoneには、`iOS`という基本プログラムが入っていて、MacBookなどには、`MacOS`という基本プログラムが入っています。
iPhone以外のスマホには、`Android`という基本プログラムが入っています。この`iOS`、`MacOS`、`Android`が、基本プログラム（OS）です。

---
📌 代表的なOSの種類
1. **Windows** - Microsoft製。一般的なPC向けで、企業や家庭で広く使われる。  
    （例：Windows 10, Windows 11）
2. **macOS** - Apple製。Mac専用で、デザインや開発者に人気。  
    （例：macOS Ventura）
3. **Linux** - オープンソース（無料）。サーバー用途や開発者向けが多い
    （例：Ubuntu, CentOS など）
4. iOS / Android - スマホのOS
   - **Android**（Google製、スマホ・タブレット向け）  
   - **iOS**（Apple製、iPhone・iPad向け）  



---

### 💻 代表的なパソコンメーカーと基本OS  

| 会社名 | 主なブランド・シリーズ（モノ） | 基本プログラム（OS） | 特徴 |
|--------|-----------------|--------|------|
| **Apple（アップル）** | MacBook, iMac | **macOS** | デザインが洗練されていて、Apple独自のOSを搭載 |
| **Dell（デル）** | XPS, Inspiron, Alienware | **Windows / Linux** | ビジネス向けからゲーミングPCまで幅広い |
| **HP（ヒューレット・パッカード）** | Pavilion, Spectre, EliteBook | **Windows / Linux** | デザイン性とコスパのバランスが良い |
| **Lenovo（レノボ）** | ThinkPad, IdeaPad, Legion | **Windows / Linux** | 特にThinkPadシリーズはビジネス用途で人気 |
| **ASUS（エイスース）** | ZenBook, ROG, VivoBook | **Windows / Linux** | ゲーミングPCやクリエイター向けPCが強い |
| **Acer（エイサー）** | Aspire, Predator, Swift | **Windows / Linux** | コスパの良いモデルが多い |
| **Microsoft（マイクロソフト）** | Surfaceシリーズ | **Windows** | タブレットとノートPCの中間のような製品が多い |
| **MSI（エムエスアイ）** | Stealth, Raider, Modern | **Windows / Linux** | ゲーミングPCやクリエイター向けPCが人気 |
| **富士通（ふじつう）** | FMVシリーズ | **Windows** | 日本国内向けのモデルが多い |
| **NEC（エヌイーシー）** | LAVIEシリーズ | **Windows** | 日本市場向けに安定したモデルを展開 |
| **Panasonic（パナソニック）** | Let’s note | **Windows** | 軽くて頑丈なビジネス向けノートPC |

💡 **補足**  
- **Apple** は **macOS** を独自搭載（WindowsやLinuxは基本的に非対応）  
- ほとんどのメーカーは **Windows** を標準搭載  
- 一部のメーカー（Dell, HP, Lenovo, ASUS, MSI, Acerなど）は **Linux搭載モデル** もある  


---


### 📱 代表的なスマホメーカーと基本OS  

| 会社名 | 主なブランド・シリーズ（モノ） | 基本プログラム（OS） | 特徴 |
|--------|-----------------|--------|------|
| **Apple（アップル）** | iPhoneシリーズ | **iOS** | Apple独自のOSを搭載し、シンプルで使いやすい |
| **Samsung（サムスン）** | Galaxyシリーズ | **Android** | 世界シェアNo.1のスマホメーカー、高性能モデルが多い |
| **Google（グーグル）** | Pixelシリーズ | **Android（純正）** | 最新のAndroidがすぐ使える、カメラ性能が強み |
| **Sony（ソニー）** | Xperiaシリーズ | **Android** | 日本メーカーで、音楽・映像機能に強い |
| **SHARP（シャープ）** | AQUOSシリーズ | **Android** | 日本国内向け、防水・省エネ性能に優れる |
| **OPPO（オッポ）** | Reno, Find, Aシリーズ | **Android** | コスパの良いモデルが多く、日本市場にも進出 |
| **Xiaomi（シャオミ）** | Mi, Redmi, POCOシリーズ | **Android** | 高性能＆低価格で人気、コスパ最強クラス |
| **Huawei（ファーウェイ）** | P, Mateシリーズ | **HarmonyOS / Android** | 独自OS「HarmonyOS」搭載モデルもあり |
| **ASUS（エイスース）** | ROG Phone, Zenfone | **Android** | ゲーミングスマホが人気、ハイスペックモデル多め |
| **Motorola（モトローラ）** | motoシリーズ | **Android** | シンプルで安価なスマホが多い |
| **Nothing（ナッシング）** | Nothing Phone | **Android** | 透明デザインが特徴的な新興ブランド |

---

💡 **補足**  
- **iPhoneはiOS** で統一（Apple製品との連携が強い）  
- **Androidはほとんどのメーカーが採用**（カスタマイズ可能で自由度が高い）  
- **Huaweiは独自OS（HarmonyOS）** を搭載したモデルもある  
- **Google Pixel** は最新のAndroidが最速で使える
stunnel 経由でリモート デスクトップ

以下の環境でクラウドにリモート デスクトップ接続したい場合を想定して、stunnel の利用法を確認してみました。

- クライアントからクラウドのポート 3389 には接続できない
- クライアントからクラウドのポート 80 に RDP では接続できない
- クライアントからインターネットのポート 443 への SSL 接続はできる
- ポート 443 で SSL 接続した先が HTTP ではなく RDP でも接続できる
    - SSH でも接続できると便利なんですが…
- SSL MITM Proxy が導入されていて、クライアント証明書を使えない
- stunnel サーバーは Ubuntu Server 24.04 LTS


## 注意

- パスワードは強力なものにしてください
- クラウドのセキュリティー設定も組み合わせてください
- 以下では省きましたが [Authentication](https://www.stunnel.org/auth.html) の PSK の設定も実施してください


## サーバー (Ubuntu) 側

### 証明書などの配置

ZeroSSL で IP アドレスの証明書を発行されているので、以下のページを参考に certificate.crt と ca_bundle.crt、/etc/ssl/private/ に private.key を配置しました。

https://help.zerossl.com/hc/en-us/articles/360060120373-Installing-SSL-Certificate-on-Ubuntu

しかし、stunnel には中間証明書を末端の証明書と別に指定する方法がないようなので、以下のように concatenate しておきます。key は root しか読めなくしておきます。

```console
$ sudo cat /etc/ssl/certificate.crt /etc/ssl/ca_bundle.crt > /etc/ssl/chained.crt
$ sudo chown root:root /etc/ssl/private/private.key
$ sudo chmod o-r /etc/ssl/private/private.key
```

### インストールと設定

インストールと設定を行います。まずはサンプルをコピーして配置し、編集を開始します。

```console
$ sudo apt install stunnel4
$ sudo cp -i /usr/share/doc/stunnel4/examples/stunnel.conf-sample /etc/stunnel/stunnel.conf
$ sudo vim /etc/stunnel/stunnel.conf
```

以下の部分はコメントを外します。

```conf:stunnel.conf
setuid = stunnel4
setgid = stunnel4
```

以下の部分はコメントを外して、stunnel4 を挿入します。

```conf:stunnel.conf
pid = /var/run/stunnel4/stunnel.pid
```

以下のセクションを追加します。

rdp-server と書いた部分は適切な IP アドレスなどに置き換えてください。

```conf:stunnel.conf
[RDP over SSL]
accept  = 443
connect = rdp-server:3389
cert = /etc/ssl/chained.crt
key  = /etc/ssl/private/private.key
TIMEOUTclose = 0
```

ここでは動作確認しかしないのでサンプルのクライアント設定を残しましたが、運用時は不要な設定を削除することを推奨します。

```console
$ sudo systemctl start stunnel4.service
```

再起動後も動くようにするには以下のようにします。

```console
$ sudo systemctl enable stunnel4.service
```


## クライアント (Windows) 側

### インストール

以下の設定でインストールし、実行しました。

- Install just for me
- Tools > openssl.exe もチェックしたままにしました
    - トラブルシューティングで使います
    - これによりインストーラーが証明書を作ろうとしますが、Ctrl+C で中断できます

### 証明書の配置

`%LOCALAPPDATA%\Programs\stunnel\config` フォルダーに SSL MITM Proxy で使われる証明書 (MITM.pem) を配置します。

### 設定

以下のセクションを追加し、トレイ アイコンの Reload Configuration を実行し、Show Log Window で LOG5 より低い数字のものが出ていないことを確認します。

my-ip と書いた部分はパブリック IP に置き換えてください。

```conf:stunnel.conf
[RDP over SSL]
client = yes
accept = 3389
connect = my-ip:443
verifyChain = yes
CAfile = MITM.pem
checkIP = my-ip
```

ここでもサンプルのクライアント設定を残しましたが、運用時は不要な設定を削除することを推奨します。

### 接続

リモート デスクトップの接続先として localhost と入力してください。MITM が認めてくれていれば接続できるでしょう。


## トラブルシューティング

OpenSSL で接続できるか確かめてみると良いようです。

```console
$ openssl s_client -CAfile MITM.pem -connect my-ip:443 -showcerts -status
```
アコーディオンメニューの.next()、.siblings()、.nextAll()メソッドについて

```html
<div class="js-accordion">クリックで開閉</div>
<div class="content">ここが開閉される</div>
<div class="other">これは影響しない</div>
```

```jsx
jQuery(".js-accordion").on("click", function () {
  jQuery(this).next().slideToggle();
});
```
`.js-accordion`をクリックすると、その直後の`.content`が開閉される。

### .slideToggle

```jsx
jQuery(selector).slideToggle(speed, easing, callback);
```

- speed（省略可）: アニメーションの速さ（"slow", "fast" もしくはミリ秒）
- easing（省略可）: 動きの変化（一般的には "swing" や "linear"）
- callback（省略可）: アニメーション完了後に実行する関数

`.slideToggle()`は、対象の要素の`display`プロパティを`none`⇄`block`に切り替える。

※要素の`display`が`block`以外（例:`inline-block`,`flex`など）の場合、アニメーション後に `display: block;`になってしまう点に注意が必要。
この場合は、`.slideToggle()`の後に`css("display", "flex")`などを指定すると元のレイアウトを維持できる。

### .next()

`.next()`はデフォルトで直後の兄弟要素を取得する。

※引数にセレクターを入れることで、直後の兄弟要素の中で条件に合うものだけ取得することができる。

### .siblings()

```jsx
jQuery(".js-accordion").on("click", function () {
  jQuery(this).siblings(".other").slideToggle();
});
```

`.other`を開きたい場合は、`.siblings()`を使う。

`.siblings()`ですべての兄弟要素を取得できる。`.siblings(".other")`というふうにセレクタを`.other`と指定することで、兄弟要素の中の`.other`のみを取得。

### .nextAll()

`.nextAll()`も後続の兄弟要素をすべて取得できるため、`.nextAll(".other")`と指定すれば、`.other`を開閉できる。

※補足
`.siblings()`との違いは、`.siblings()`は前後含めたすべての兄弟要素を取得できるが、`.nextAll()`は、後続のすべての兄弟要素を取得する。（前は含まない）
<br>
ちなみに、これでも`.other`を開閉することができる。
```jsx
jQuery(".js-accordion").on("click", function () {
  jQuery(this).next().next().slideToggle();
});
```
ベクトルデータベース備忘録

噂には聞くベクトルデータベース。なかなか使う機会がないのですが、なにやらとてもよさそうなのでちょっと調べたり試したりしてみました。

なおおためしのコードは `Milvus` を使いましたが、 [ほとんどClineに書いてもらいました](https://qiita.com/robitan/items/770e7796a93eb3441515)＾＾

https://github.com/robitan/sample-vector-database

# わかったこと

 - ベクトルデータベースは「ベクトルで管理しているデータの検索を容易にする」ことを主な目的として使用するもの
 - ベクトル検索できる主なメリットは（ベクトル化の基準による）近傍検索。つまり（ベクトル化の基準による）似たデータ探し
 - ということは、大量のデータの、ベクトル化した値を、永続的に保持して活用したい場合に使用するとよさそう
 - ベクトル化をデータベース側がやってくれるわけ**ではない**。格納データのベクトル化はアプリケーション側で行う
 - 似たデータを探すのが得意、といえばOpenSearchだが、それとの差別化は？→OpenSearchにもベクトル検索機能はある（らしい）が、ベクトル検索**だけ**を使うならベクトルデータベースのほうが早い（らしい）
 - ベクトルデータベースで一番有名なのは `Milvus` のようだが、データベースの特性に応じて得意分野がありそう。

## 製品比較

| 製品名       | OSS       | ホスティング形態                                 | 特徴                                                                                                       |
|------------|-----------|--------------------------------------------------|------------------------------------------------------------------------------------------------------------|
| Milvus     | Yes       | 自前ホスティング / マネージド（Zilliz Cloud）    | 分散型で水平スケーリングが可能。IVF、PQ、HNSWなど複数のインデックスタイプをサポートし、非構造化データに最適。 |
| Qdrant     | Yes       | 自前ホスティング / SaaS（Qdrant Cloud）          | Rust製の高速な類似度検索エンジン。Docker対応で迅速な展開が可能。                                             |
| Weaviate   | Yes       | 自前ホスティング / マネージド（Weaviate Cloud）   | グラフベースのアプローチとGraphQLインターフェースを採用。メタデータ統合が容易で柔軟なデータ管理が可能。         |
| Pinecone   | No        | マネージドサービスのみ                           | 完全管理型サービス。インフラ管理の負担がなく、シンプルなAPI統合と高いスケーラビリティを実現。                   |
| ChromaDB   | Yes       | 自前ホスティング                                  | LangChainやLlamaIndexとの統合が容易。シンプルなAPIにより迅速なプロトタイピングや小～中規模プロジェクト向け。        |


※この内容の調査と表化はChatGPTにやってもらいました。Dockerで使えるのは `Qdrant` だけであるかのような記述になっていますが、オープンソースのものはすべてDocker上で動かそうと思えば動かせると思います。なおサンプルコードでは `Milvus` をDocker上で動かしています。

# 参考サイト

 - https://myscale.com/blog/milvus-vs-opensearch-performance-analysis-2024/
 - https://zilliz.com/jp/comparison/milvus-vs-opensearch
 - https://zilliz.com/jp/vector-database-benchmark-tool

# 所感

 - 現時点ではベクトル検索をやるなら「ベクトルデータベース」を名乗るものに１日の長がありそうです。ただなんでもできるというのは強いので、今後OpenSearchがベクトル検索機能を強化していった場合はどうなるかわからないですね。実際に使うタイミングでその時の状況を改めて調べるのがよさそうです
CodeRabbit を実際に数ヶ月使用してみた感想


少し前から、自作のオープンソースプロジェクトに [Coderabbit](https://coderabbit.ai) を導入してみました  
その結果、コードレビューの質と効率が大幅に向上し、非常に満足しているので  
実際に使用してみた感想を共有したいと思います

## 見落としを減らせるのが嬉しい

### 細かな問題点の検出

コードを書いていると、どうしても見落としてしまう部分があります  
CodeRabbit は、デバッグ用コードの残存やハードコーディングされた値など、  
機械的に判定可能な点を的確に指摘してくれます

### 効率化されたレビュー体験

自動で細部にわたるチェックを行うことで、  
レビュー時間の短縮と見落としの削減に大きく貢献してくれています

## PRの要約機能が便利

### 変更内容の要約

プルリクエスト（PR）作成時に、どのファイルにどのような変更が加えられたのかを自動で要約してくれるため、全体像が一目で把握できます

### レビュー準備の効率化

要約機能により、レビュー前の情報整理が自動化され、より迅速で効率的なレビュー作業が可能になりました

## AI によるレビューで心理的負担の軽減

### 自動検出による安心感

AI がタイポ、エラーハンドリングの有無、デバッグ用コードの残存などを検出し、  
人間同士のレビューで生じる心理的な負担を軽減してくれます（多分）

### 建設的なフィードバック促進

機械的な指摘により、感情的な対立を避け、改善点に焦点を当てた建設的なレビューが実現されています

## 何より無料！

### オープンソースプロジェクト向け無料利用

オープンソースプロジェクトの場合はこのクオリティのコードレビューを無料で利用することができます！
詳細は [こちら](https://www.coderabbit.ai/pricing) をご参照ください

### コスト削減のメリット

特にリソースが限られるオープンソースコミュニティにとって、  
無料で利用できる点は大きなメリットとなっていると感じます

## 顔文字やポエムが可愛い & 面白い

余談ですが、Coderabbit の絵文字やポエムが可愛くて面白いです

### ユニークな表現方法

レビュー中に登場する絵文字が地味に可愛く、  
ちょっとした和みポイントになっています

### 技術と芸術の融合

AI のポエムが、技術レビューに詩的な表現を加えることで、  
従来のツールにはない独特の魅力を演出しています

## ちょっと気になる点

### ウェブ操作のレスポンス

唯一の課題として、ウェブ上での操作が少し遅い点が挙げられます
実際の使用中に感じるレスポンス改善が期待されます

### 改善への期待

それでも、全体の機能と無料利用のメリットを考慮すれば、  
これは些細な問題と言えるでしょう

## まとめ

OSS 開発者にとって、CodeRabbit はコードレビューの質を向上させる  
強力なツールです

まだ使ったことがない方は、ぜひ一度試してみる価値があると思います！
→ [Coderabbit AI](https://coderabbit.ai)
Go言語で文字列から文字を取得する方法を解説！Rubyとの違いも徹底比較

## はじめに

Go言語を学んでいると、「文字列から特定の文字を取得する方法」に戸惑うことはありませんか？Rubyでは直感的に操作できますが、Goでは少し異なります。本記事では、GoとRubyの違いに注目しながら、Go言語で文字列を扱う基本的な方法を解説します。

## Rubyではどうやって文字列から文字を取得する？

Rubyの場合、文字列は配列のように扱えます。以下の例をご覧ください。

```ruby
str = "こんにちは"
puts str[0]  # => "こ"
```

非常にシンプルで、インデックスを指定するだけで文字が取得できます。また、負のインデックスも使えるので、末尾からの取得も可能です。

```ruby
puts str[-1]  # => "は"
```

## Goではどうする？

一方、Go言語では文字列は**バイト列**として扱われます。そのため、単純にインデックスを指定しても、意図した文字が取得できない場合があります。具体例を見てみましょう。

```go
package main

import "fmt"

func main() {
    str := "こんにちは"
    fmt.Println(string(str[0]))  // => � (意図した結果ではない)
}
```

### 理由：Goの文字列はASCIIコード（バイト単位）

Goの文字列はUTF-8エンコーディングで格納されていますが、インデックス指定でアクセスする場合は**ASCIIコード**（バイト単位）の値が返されます。そのため、この値を「文字」として出力するには、**string型での型変換**が必要です。

```go
package main

import "fmt"

func main() {
    str := "こんにちは"
    fmt.Println(str[0])          // => 227 (ASCIIコード)
    fmt.Println(string(str[0]))  // => � (意図と異なる文字)
}
```

ただし、上記の方法では日本語のようなマルチバイト文字を正しく取得することはできません。

### 正しい方法：ルーン（rune）を使う

Goでは、`rune`型を使って文字列をUnicodeスカラー値として扱うことができます。以下のコードで正しい方法を確認しましょう。

```go
package main

import "fmt"

func main() {
    str := "こんにちは"
    runes := []rune(str)
    fmt.Println(runes[0])          // => 12371 (Unicodeスカラー値)
    fmt.Println(string(runes[0]))  // => "こ"
}
```

この例では、`[]rune`に変換することで、文字列をUnicodeの文字単位で扱えるようになります。

## Rubyとの大きな違い

Rubyでは、文字列はあくまで「文字の集合体」として扱えます。一方で、Go言語では文字列を「バイト列」として扱う設計思想が基本です。この違いを理解することで、両言語での文字列操作に対するアプローチが明確になります。

| 特徴            | Ruby                          | Go                          |
|----------------|-------------------------------|-----------------------------|
| 文字列の扱い    | 文字の配列                    | バイト列                   |
| マルチバイト対応 | 標準で対応                    | `rune`に変換が必要         |
| インデックス指定 | そのまま文字を取得可能        | ASCIIコードの値を`string`型に変換する必要 |

## おわりに

Go言語では、文字列を扱う際に「バイト列」として処理される点を意識する必要があります。また、ASCIIコードを理解し、`string`型での型変換や`rune`を活用することで、日本語を含むマルチバイト文字も正しく操作できます。一方、Rubyは初心者にも扱いやすい設計です。それぞれの特徴を理解して使いこなせるようになりましょう。

この記事が皆さんのGo言語学習の一助となれば幸いです！
FreeBSD14 初期設定 ~公開鍵認証でSSHするまで~

# はじめに
何回も調べるのがめんどいのでメモ程度にまとめておく

# 初期設定
### suコマンドでrootになれるように
~~~ sh:
pw groupmod wheel -m hoge
~~~
hogeのところを自分のユーザー名にする
### rootのシェルをtcshに変更
~~~ sh:
chsh -s /bin/tcsh
~~~

### vimインストール
~~~ sh:
pkg update
pkg install -y vim
~~~
初回だと
~~~ sh:
The package management tool is not yet installed on your system.
Do you want to fetch and install it now? [y/N]: 
~~~
と聞かれるので y でインストールしておく

### Ports Collectionのインストール
gitを用いてports collectionをインストールするためにgitをインストールする。
~~~ sh:
pkg install -y git
~~~

ports collectionのインストール
~~~ sh:
git clone https://git.FreeBSD.org/ports.git /usr/ports
~~~
/usr/portsを更新
~~~ sh:
git -C /usr/ports pull
~~~

### portsのアップグレード
portupgradeを使う
~~~ sh:
cd /usr/ports/ports-mgmt/portupgrade
make install clean
~~~

### NTPの設定
適当なntpサーバーを追加
~~~ sh:/etc/ntp.conf 追記
server ntp.nict.jp
server ntp1.jst.mfeed.ad.jp
server ntp2.jst.mfeed.ad.jp
server ntp3.jst.mfeed.ad.jp 
~~~
起動時にntpが自動できどうするように
~~~ sh:/etc/rc.conf 追記
ntpd_enable="YES"
ntpd_sync_on_start="YES"
~~~
### ファイアウォール設定
ipfwを使う [このサイトを参考にさせて頂いた](https://korodes.com/freebsd14_03/)
ssh(22), dns(53)を開けとく
~~~ sh:/usr/local/etc/ipfw.rules 新規作成
#! /bin/sh
#
 
IPF="ipfw -q add"
ipfw -q -f flush
 
#loopback
$IPF 10 allow all from any to any via lo0
$IPF 20 deny all from any to 127.0.0.0/8
$IPF 30 deny all from 127.0.0.0/8 to any
$IPF 40 deny tcp from any to any frag
 
# statefull
$IPF 50 check-state
$IPF 60 allow tcp from any to any established
$IPF 70 allow all from any to any out keep-state
$IPF 80 allow icmp from any to any
 
$IPF 100 allow tcp from any to any 22 in
$IPF 110 allow tcp from any to any 22 out
$IPF 120 allow udp from any to any 53 in
$IPF 125 allow tcp from any to any 53 in
$IPF 130 allow udp from any to any 53 out
$IPF 135 allow tcp from any to any 53 out
~~~
起動時にipfwを有効化
~~~ sh:/etc/rc.conf 追記
firewall_enable="YES"
firewall_logging="YES"
firewall_script="/usr/local/etc/ipfw.rules"
~~~

### SSHの設定
既存のコンフィグファイルがあるからバックアップ
~~~ sh:
mv /etc/ssh/sshd_config /etc/ssh/sshd_config.org
~~~

~~~ sh:/etc/ssh/sshd_config 新規作成
Port 22
PermitRootLogin no
PubkeyAuthentication yes
AuthorizedKeysFile	.ssh/authorized_keys
PasswordAuthentication no
PermitEmptyPasswords no
KbdInteractiveAuthentication no
UseDNS no
Subsystem	sftp	/usr/libexec/sftp-server        
~~~
以下、鍵を作成したい一般ユーザーで実行
~~~ sh:
ssh-keygen -t ed25519
cat ~/.ssh/id_ed25519.pub >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
chmod 700 ~/.ssh/
~~~
作成した秘密鍵はクライアント端末によしなに
CI/CDの基本をまとめた

## はじめに
CI/CD は、**アプリの開発からデプロイまでを自動化する仕組み**のことです。
エンジニアが手作業でやっていたテストやデプロイを自動化し、**開発スピードを上げる**ことが目的です。



## CI/CD とは？

CI/CD は 「継続的インテグレーション（Continuous Integration）」と「継続的デリバリー（Continuous Delivery)」の略です。

| 用語 | 意味 |
|------|------|
| CI（継続的インテグレーション） | コードを変更するたびに **自動でビルド・テスト** を行い、問題がないか確認する仕組み |
| CD（継続的デリバリー） | CI の後に、**本番環境にデプロイできる状態まで自動化** すること |


**CI/CD のメリット**
- 手作業のミスを減らせる
- 開発スピードが上がる
- チーム開発がスムーズになる


## CI/CD の仕組み

CI/CD は、一般的に **GitHub Actions** や **CircleCI** などの **CI/CD ツール** を使って実現します。

### **1. CI（継続的インテグレーション）**
1. 開発者がコードを Git に Push
2. CI ツールが自動でビルド & テストを実行
3. テストに合格したらマージ可能に

### **2. CD（継続的デリバリー / デプロイメント）**
1. CI が成功したら、本番環境にデプロイ可能な状態に
2. （継続的デプロイメントの場合）自動で本番環境へデプロイ



## **GitHub Actions を使った CI/CD の例**

📌 **手順**
1. `.github/workflows/main.yml` を作成
2. `main.yml` に以下のような設定を書く

```yaml
name: CI/CD Pipeline

on:
  push:
    branches:
      - main

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v2

      - name: Setup Node.js
        uses: actions/setup-node@v2
        with:
          node-version: "18"

      - name: Install dependencies
        run: npm install

      - name: Run tests
        run: npm test

  deploy:
    needs: build
    runs-on: ubuntu-latest
    steps:
      - name: Deploy to Firebase
        run: npm run deploy
```

📌 **このワークフローの流れ**
1. `main` ブランチにコードを Push
2. GitHub Actions が **ビルド & テストを自動実行**
3. テストが成功したら、**Firebase にデプロイ**


## **まとめ**

✅ CI/CD とは開発・テスト・デプロイを自動化する仕組み
✅ CI（継続的インテグレーション）はコード変更時に自動テストすること
✅ CD（継続的デリバリー）はデプロイまで自動化すること


### **参考リンク**
https://firebase.google.com/docs/hosting/github-integration?hl=ja

https://docs.github.com/ja/actions

https://qiita.com/Teach/items/d2c4d7bec98228df1807
Combineと弱参照：安全な非同期処理のためのメモリ管理

Combineは、Swiftにおける非同期イベント処理のための強力なフレームワークです。非同期処理が絡むと、メモリ管理の問題―特に循環参照によるメモリリーク―が発生するリスクも高まります。この記事では、Combineと弱参照（weak reference）の関係について詳しく解説し、どのようにして安全なコードを書くかを紹介します。

# ARCと循環参照の問題
Swiftでは、ARC（自動参照カウント）がメモリ管理を担っています。オブジェクトは、どこからも参照されなくなった時点で解放される仕組みになっています。しかし、もし複数のオブジェクトが互いに強参照（strong reference）しあっている場合、参照カウントが0にならず、使われなくなったオブジェクトがメモリ上に残り続ける循環参照が発生してしまいます。

例えば、以下のようなコードでは、AとBがお互いを強参照しているため、doブロックを抜けても解放されません。

``` swift
class A {
    var b: B?
}

class B {
    var a: A?
}

do {
    let a = A()
    let b = B()
    a.b = b
    b.a = a
} // ここでaとbは互いに強参照しているため解放されない
```

# Combineにおける弱参照の必要性
Combineを利用する際、よく使われるオペレーターにはsinkやassign(to: on:)などがあります。これらのオペレーターは、内部でクロージャを用いてイベントを処理します。クロージャ内でself（親クラス）を直接参照すると、クロージャがselfを強参照してしまい、self自身もクロージャ（またはその管理下にあるAnyCancellable）を保持してしまいます。結果として、双方が解放されず、メモリリークを引き起こす原因となります。

## 例：sinkオペレーター内での弱参照の実装
以下のコードは、MyViewModelクラス内でCombineのsinkオペレーターを使い、selfを弱参照（[weak self]）でキャプチャする例です。

``` swift
import Combine

class MyViewModel {
    private var cancellable: AnyCancellable?
    
    func startListening() {
        cancellable = somePublisher
            .sink { [weak self] value in
                guard let self = self else { return }
                self.handle(value)
            }
    }
    
    private func handle(_ value: SomeType) {
        // 値に応じた処理
    }
}
```

この例では、クロージャ内でselfを弱参照としてキャプチャすることで、MyViewModelが不要になったときに正しく解放されるようにしています。

## 例：ObservableObjectとCombineで弱参照を利用する
Combineでは、SwiftUIと連携してObservableObjectを用いることも多いです。以下は、ObservableObjectに準拠したクラスが、Timerを使って定期的に値を更新する例です。

``` swift
import Combine
import Foundation

// 発行するデータの型
struct SomeType {
    let value: String
}

// ObservableObjectに準拠したパブリッシャークラス
class SomePublisher: ObservableObject {
    // 値が更新されるたびに購読者に通知される
    @Published var currentValue: SomeType = SomeType(value: "Initial Value")
    
    private var timerSubscription: AnyCancellable?
    
    init() {
        // Timerパブリッシャーを用いて1秒ごとにSomeTypeを発行する
        timerSubscription = Timer.publish(every: 1.0, on: .main, in: .common)
            .autoconnect() // タイマーを自動で接続
            .map { _ in
                SomeType(value: "Updated at \(Date())")
            }
            .assign(to: \.currentValue, on: self)
    }
    
    deinit {
        timerSubscription?.cancel()
    }
}
```
この例では、SomePublisherが1秒ごとに新しい値を生成し、@Publishedプロパティを通じてSwiftUIのViewなどに通知します。ここでも、内部的にはCombineの仕組みが働いており、必要に応じて弱参照や適切なキャプチャ方法を用いることで、循環参照を防ぐことが可能です。





# まとめ
Combineを利用する際、非同期イベントを扱うクロージャ内でselfを参照するときは、必ず弱参照を意識しましょう。以下がポイントです。

#### ARCと循環参照の基本：
ARCは参照カウントが0になった時点でオブジェクトを解放しますが、互いに強参照し合うと解放されず、メモリリークの原因となります。

#### Combineでの弱参照の実践：
Combineのsinkやassign(to: on:)などのオペレーターを使う際、クロージャ内でselfを強参照してしまわないよう、明示的に[weak self]や[unowned self]を用います。

#### デバッグと確認：
コード実装後は、Memory Graph Debuggerなどのツールで循環参照が発生していないか確認し、安全なメモリ管理が行われているかをチェックしましょう。

#

このように、適切な弱参照の設定は、Combineを使ったアプリケーションにおいても安全かつ効率的なメモリ管理のための重要なテクニックとなります。ぜひ、今回のポイントを参考に、クリーンなコードを書いてください！
GA4のイベントパラメータ名には「-」（ハイフン）の利用を避ける

## はじめに

実務で、GA4のイベントパラメータ名に「```-```」（ハイフン）を利用したところ
思わぬ落とし穴があったため、その内容を共有することにします。

※ユーザープロパティ名も同様です。

## 結論

以下の通り、GA4プロパティ上でイベントパラメータ名をカスタムディメンション登録する際に「```-```」（ハイフン）は利用できないため、「```_```」（アンダースコア）を利用する（スネークケースで命名する）ことをおすすめします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2290540/d3cea8da-18ce-4774-bb79-7ff864d74b90.png)

GA4のデフォルトで送信されるイベントパラメータ名を確認すると、命名がスネークケースのものが散見されるため、暗黙的にスネークケースの利用が推奨されているのかもしれません。（※あくまで私の推測となります。）

補足となりますが、イベント名に関する命名規則はアナリティクスヘルプに記載があり、英数字と「```_```」（アンダースコア）のみ使用可能とのことでした。

https://support.google.com/analytics/answer/13316687

## 落とし穴

前提として、対象サイトではGA4のログ送信にGoogle Tag Managerを利用してGA4イベントタグを配信していました。

GTMのGA4イベントタグのイベントパラメータ設定には、問題なく「```-```」（ハイフン）が利用できるのですが、GA4プロパティ側のカスタムディメンション登録には利用できませんでした。（落とし穴）

実際に、GTMのGA4イベントタグのイベントパラメータ名の設定には以下のような形で「```-```」（ハイフン）が利用できていました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2290540/ab88de39-3526-47f0-93ea-211db85acc2d.png)

## おまけ

試しに、Google ChromeのDeveloper ToolのNetworkパネルでGA4ログの疎通を確認したところ、「```-```」（ハイフン）ありで問題なく送信されていました。（ただ、GA4プロパティ側でカスタムディメンション登録できません。）

![スクリーンショット 2025-02-13 11.38.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2290540/a1938154-c13f-41c0-a0ac-8087c09f01b7.png)

BigQueryのGA4テーブルにも「```-```」（ハイフン）ありで送信されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2290540/e9916658-9ac3-453b-a616-4752be5dfdf4.png)

## 最後に

今回、GA4のイベントパラメータ名/ユーザープロパティ名に、「```-```」（ハイフン）が含まれているとGA4プロパティ側でカスタムディメンション登録できない事象に遭遇しました。

そのため、今後の命名は「```_```」（アンダースコア）を利用し、スネークケースで命名した方がよさそうです。

ただ、「```-```」（ハイフン）が含まれている場合でも、BigQueryでは問題なくデータを扱えるようでした。

日頃GA4やGTMを利用していますが、まだまだ把握できていない仕様があると感じました。本記事がどなたかの一助となれば、幸いです。
【備忘録】Next.js + prisma AppをVercelデプロイ時に「PrismaClientInitializationError」が発生

# はじめに
Next.jsでPrismaを利用したアプリケーションを構築し、
Vercelにデプロイしたところ、以下のエラーが表示されました。
この問題の原因と対処法を備忘録として残します。

```
[cause]: Error [PrismaClientInitializationError]: Prisma has detected
that this project was built on Vercel, which caches dependencies. 
This leads to an outdated Prisma Client 
because Prisma's auto-generation isn't triggered.
To fix this, make sure to run the `prisma generate` command
during the build process.
```

# 原因
エラーメッセージに記載されている通り、Vercelはライブラリなどの依存関係を
キャッシュするため、Prisma Clientの自動生成が正しく実行されません。
この問題を解決するには、ビルドプロセス中にPrisma Clientを生成するコマンドを
実行するよう設定する必要があります。

# 対処法
`package.jsonの`scriptsセクションに以下の設定を追記または編集します
```package.json
"scripts": {
    "build": "prisma generate && next build",
},
```
この設定により、ビルドプロセス中にprisma generateコマンドが実行され、
Prisma Clientが正しく生成されるようになります。
VS Code標準機能でindent-rainbow

この記事は、[VS Codeのindent-rainbowは不要になりました！@qita](https://qiita.com/htcd/items/21266f6472ac2c39933e)様の記事を
丸パクリです。

個人的に超有用なので、作者様のページが万が一消えても問題ないように、
備忘録させて頂きました。

## 前提
Visual Studio Code [July 2023 (version 1.81)](https://code.visualstudio.com/updates/v1_81) 以上

## 設定方法
settings.jsonを開く（参考：[VS Codeのsettings.jsonの開き方](https://qiita.com/y-w/items/614843b259c04bb91495)）。

↓を追記する。
```settings.json
"workbench.colorCustomizations": {
    "editorIndentGuide.background1": "#b22222",
    "editorIndentGuide.background2": "#ff4500",
    "editorIndentGuide.background3": "#ffd700",
    "editorIndentGuide.background4": "#228b22",
    "editorIndentGuide.background5": "#000080",
    "editorIndentGuide.background6": "#8b008b",
    "editorIndentGuide.activeBackground1": "#fff",
    "editorIndentGuide.activeBackground2": "#fff",
    "editorIndentGuide.activeBackground3": "#fff",
    "editorIndentGuide.activeBackground4": "#fff",
    "editorIndentGuide.activeBackground5": "#fff",
    "editorIndentGuide.activeBackground6": "#fff"
}
```
↑の色は虹色のパターンです。

これを指定すると↓のような感じでブロックごとにハイライトされるようになります。
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987509/e430eba6-3fed-4428-b447-3e933d311645.png"/>

ちゃんと空改行でも途切れてない！

<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987509/5971f127-c645-455c-87fa-4abe0eddb5de.png"/>

## ちょっと詳しく

6色まで設定できます。指定した個数以上のインデントレベルは指定した色がループします。

`editorIndentGuide.background` がラインの色、
`editorIndentGuide.activeBackground` がカーソルがあるブロックのラインの色です。

`editorIndentGuide.background` と `editorIndentGuide.activeBackground` はセットで指定する必要があります。

v1.81より前のバージョンの場合、

```settings.json
"workbench.colorCustomizations": {
    "editorIndentGuide.background": "#f00",
    "editorIndentGuide.activeBackground": "#fff"
}
```
のように一色しか指定できません。