OmniAICreator/Qiita-1.07M huggingface dataset:
ObsidianのCSSスニペットを使ってメモを見やすく！


Obsidianを使っていると基本的には見やすいけどh3とh4の見出しの見分けがしにくく、困ったりするのがあるあるだと思います。
この問題は設定の「外観>テーマ」から適切なテーマを適用すれば、メモを見やすくすることができます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3853726/3c528723-239b-472f-8032-3b251111d4d3.png" width="50%"><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3853726/d0442fca-5166-4ab1-8a7e-9e7f703633e5.png" width="50%">

ただ、テーマを適用すると動作が重くなったり、所々バグったりすることがあったのであまりおすすめできません。(なんでそうなるの？？？)

そこで、CSSを適用することにしました。と言っても友達がいつのまにか作っていたCSSを少し改良しただけなので、私は大したことしてないです()
その友達が「Qiitaの記事にしないの？」と言ってくれたので記事にしました。
N君諸々ありがとう！

CSSを適用する手順に行く前に、どんな風に装飾されるのかを見てみましょう。

### 適用前と適用後でどう違うのか

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3853726/9cc5ea64-0132-4eb8-ba7a-4f643c65a060.png" width="50%"><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3853726/620b5d45-2acc-4ae6-89ec-a91e5af391f5.png" width="50%">

左が適用前で右が適用後です。
- ファイル名とメモ本文の間に線が入っている
- 行番号、数字リストが赤色になっている
- H1~h6見出しの横にバラバラの色でわかりやすく表示している
- 表の一行目、偶数行目の背景色が変わっている
などかなり見やすくなっています。

使ってみてわかったんですが、Calendarプラグインにも表の背景色を変えるCSSが適用されてて、こっちは見にくくなってますね...
Calendarプラグインに適用されないようにする方法わかんないです...すみません...

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3853726/313c24e8-8d3f-4576-83a3-c1d556679435.png" width="50%">

その問題はひとまず置いておいて、CSSを適用してみましょう。

### GitHubからダウンロード
↓私のGitHubのページからダウンロードしてください。

https://github.com/Kei-Adachi0709/CSS_snippets

ダウンロードは下の図を参考にしてください。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3853726/fff2c60a-7152-411a-bbed-61a06b628cba.png" width="50%">

### ファイルを解凍して適用
まずダウンロードしたCSSファイルを解凍します。
次にObsidianを開き設定のCSSスニペットを有効にします。


<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3853726/fc1ec1a1-feea-4134-87ac-4a317d2695fe.png" width="50%">

あとはダウンロードしたCSSファイルを`保管庫名\.obsidian\snippets\`ディレクトリに置きます。
これでCSSが適用されるはずです。最終的に下の画像のようになっていればOKです。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3853726/fc1ec1a1-feea-4134-87ac-4a317d2695fe.png" width="50%">

CSSで自分好みに見やすくできるよ！ということを伝えたかっただけなので、色々書き換えてより見やすくしてみてください！
よりよいObsidianライフを！
論理的なコミュニケーション

## 論理的なコミュニケーション

### 分かりやすい「伝え方」の三つポイント
- 伝える動機
- 伝えるべき中身
- 伝えるための技術

### 伝えるとはどういうことか

#### 1. うまく伝わらない４つの理由    
- 相手の立場に立っていない
- 話に意図がない
- 「分かってくれるだろう」という甘えがある
- 「事実」と「意見」が混在する

#### 2. 伝えるための３要素
- 伝える動機を明確する
- 話す中身を選定/整理する
- 伝えるための表現方法を決める

#### 3. 事前準備
- 伝える相手を確認する
- 伝える目的を明確にする
- 伝えるための表現方法を決める

### 話の組み立てを考える

#### 1. 伝えたいことを構造化する 
   
要素同士の間をつなぐ「関係性」を明らかにしておくこと

#### 2. 「構造化のパターン」
- 並列
- 包含
- 順列
- 因果
- 対立

#### 3. 階層的に整理する

ロジックツリー

### 話の展開を考える

#### 1. 結論の位置を決める

相手の目的を応じて、結論の位置を変える

#### 2. 「型」を活用する

PREP
- Point：結論
- Reason：理由、根拠
- Example：具体例
- Point：結論

#### 3. 「帰納法」「演繹法」を活用する

帰納法：具体的な事例、事象から一般的な法則を導く

### 書くことで伝える

#### 1. 「書くこと」特有の難しさ
- 準備に時間がかかる
- 相手の反応におじて調整できない
    - 相手のことを事前に調べる
    - 自分が言いたいことは何かを明確する
    - しっかりと準備をする

#### 2. 「書くこと」の基本と組み立て
- 表題
- 項目
- 本文

#### 3. 「表題」「項目」「本文」のポイント
- 表題：わかりやすく表現する
- 項目：過不足なく洗い出す
- 本文：項目と的確に紐づける

#### 4. わかりやすい文章のポイント
- 一文４０〜５０字にする
- 全体の文量を考慮する
- 重要でなければ削る
- 主語と述語の関係を明確にする
- 内容は具体的にする
- わかりやすい言葉を使う

### 話すことで伝える

#### 1. 「話すこと」特有の難しさ
- 「持つ時間」という制約がある
- 相手の反応に応じた調整が必要

#### 2. 本番までの３ステップ
- シナリオを書く
- リハーサルを行う
- 事前に調整する

#### 3. 話し方のポイント
- 姿勢、態度、表情
- 声
- 間の取り方
- 話すスピード
addをファイル・差分単位で操作したいときの技

ローカルだけで変更を保存しておきたいファイル・差分があるときに使えるのではと思う。

## ファイル単位でaddしたい時
```
$ git add <filePath>
```
## 差分単位でaddしたい時

まずはこれを実行。
```
$ git add -p <filePath>
```
すると、こちらの記事のように、差分単位でaddするかどうか聞いてくれる。
https://qiita.com/miyohide/items/79ab0ff3b3852289a6be
それを1つ1つy(yes)やn(no)で答えるだけ。
すべて答え終わったら、自動的にこの質問モードから抜けられる。
ITエンジニアが語る！なぜボランティアでテックブログを書くのか？

![tech0001.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4006596/9f64785b-d349-42c3-9012-14a553853ccb.jpeg)


## はじめに

日々の業務に追われながらも、なぜあえてボランティアでテックブログを書くのか。  
この問いに対する答えは、単なる自己表現や承認欲求に留まらず、エンジニアとしてのキャリア形成や働き方の戦略にも深く関わっています。  
この記事では、私の過去の経験や転職の軌跡、そして今の会社で感じる現実を交えながら、ボランティア活動としてのテックブログ執筆に込めた思いを語っていきます。

---

## 1. ボランティアでテックブログを書く理由

テックブログを書く動機は一言で言えば「自己表現」ですが、以下のような背景があります。

- **業務外の自由な発信**  
  会社からのきっかけはあったものの、残業代が支給されるわけでもなく、業務の一環とも言えないため、完全なボランティアとしての側面があります。  
- **文章を書くことの楽しさと承認欲求**  
  昔から文章を書くことが得意で、執筆を通じて自分の考えや知識を発信することに大きなやりがいを感じています。

---

## 2. 転職とキャリアの軌跡

過去の経験から見えてくるのは、会社のカルチャーが必ずしも自分のアイデアを全面的に受け入れるわけではないという現実です。

- **オリジナルキャラ提案の失敗**  
  以前勤めていた会社では、オリジナルキャラの提案も真剣に取り組んでもらえず、IT系の現場よりも広報や秘書課の方がウケていたという経験があります。  
- **キャリアの見直しと転職**  
  結局、本業がITエンジニアであることを再認識し、キャラデザインやブランディングの方向転換がなされることなく趣味の範囲で終始し、同時期に給料が頭打ちとなったため、転職したこともありました。

---

## 3. 今の会社で感じる現実と戦略

今の会社、[KANGEN](https://qiita.com/organizations/kangen-holdings)では、エンジニアとしての実力が直接給与に反映される仕組みが採用されており、その環境がキャリア戦略にも影響を与えています。

- **新しい働き方の実践**  
  アバターでボイスチェンジしながらのオンラインMTGなど、ユニークな取り組みを許容する風土があり、従来の枠にとらわれないコミュニケーションが実現されています。  
- **給与テーブルと人間関係のジレンマ**  
  SESエンジニアとして単価がそのまま給与に影響するため、現場の存在感を維持しながら昇給を狙う必要があります。  
  ― 結果として、営業コストをかけずに成果を出し、安定的に昇給できる土台作りが求められています。

---

## 4. 働き方への思いと今後の展望

こうした経験を経て、帰属意識ややりがい、そして「社畜」という言葉が頭をよぎることもありますが、それでもなお、新しい挑戦への意欲は尽きません。

- **ボランティア活動の意義**  
  ボランティアでのテックブログ執筆は単なる自己満足ではなく、会社全体の成長にも貢献できる一要素として捉えています。  
- **会社設立の夢？**  
  一方で、「じゃあ会社を立ち上げたら？」という疑問も湧き上がりますが、今はあえて会社員として安定したポジションを維持しながら、自分の活動を続けるという選択をしています。
  趣味の範囲のプラスアルファ、みたいな感覚です。

---

## まとめ

ボランティアでテックブログを書く理由は、単なる個人の趣味や承認欲求だけではなく、キャリア形成や働き方の戦略と深く結びついています。  
多様な経験を通して得た知見を今後も発信し、同じような悩みを持つエンジニア仲間と共感や知見を共有できればと考えています。
せっかくなので会社の力も使いつつ、自己表現のプラスにできたら、シナジーも期待できると思っています。

要するに、楽しんでやってたら無駄にはならない、ということでしょうか

この記事が、皆さん自身の働き方やキャリアの見直しの一助となれば幸いです。

---

*※これは私の個人的な経験と考察に基づいた独り言的な投稿です。*
AWS CDKでEKSクラスタ削除/作成のロールバックができない時はGuardDutyが原因かも

## 起きたこと
AWS CDKを使ってEKSクラスタを含むインフラの構成管理を試している際、`cdk destroy`が正常に通らなかったり、VPC作成を含む変更が失敗した際にロールバックも失敗する問題が発生しました。

調査したところ、身に覚えのないVPCエンドポイントが作成されており、それがCDKの管理外であるため削除されず、結果として以下のリソースの削除を阻害していました。

1. **ネットワークインターフェースの削除失敗**
2. **サブネットの削除失敗**
3. **VPCの削除失敗**

## 原因

この問題の原因は、AWSアカウントでランタイムモニタリングを有効にしていて、EKSの自動エージェント設定を有効にしていると**GuardDutyのVPCエンドポイントが自動的に作成されること**にあります。

AWS CDKでEKSクラスタを構築する際、AWSアカウントでGuardDutyを利用していると、GuardDutyが自動的にVPCエンドポイントを作成します。このVPCエンドポイントはCDKの管理外であり、`cdk destroy`時に削除されないため、結果的にVPC全体の削除が妨げられるという問題が発生しました。

参考ドキュメント:  
[Using AWS CloudFormation and other Infrastructure as Code (IaC) tools with Amazon GuardDuty](https://docs.aws.amazon.com/ja_jp/guardduty/latest/ug/using-iac-with-gdu-automated-agents-runtime-monitoring.html)

## 対処法
この問題を回避するためには、**GuardDuty用のVPCエンドポイントをCDKで作成し、CDKの管理下に置く**ことが有効です。

#### 具体的な対処方法：**CDKでGuardDuty用のVPCエンドポイントを明示的に作成**

```typescript
import * as cdk from "aws-cdk-lib";
import * as ec2 from "aws-cdk-lib/aws-ec2";
import * as eks from "aws-cdk-lib/aws-eks";

class EksClusterStack extends cdk.Stack {
  constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
    super(scope, id, props);
    const vpc = new ec2.Vpc(stack, "Vpc", {
      ipAddresses: ec2.IpAddresses.cidr("10.0.0.0/16"),
      availabilityZones: ["ap-northeast-1b", "ap-northeast-1c"],
      natGateways: 1,
      ipProtocol: ec2.IpProtocol.DUAL_STACK,
      subnetConfiguration: [
        {
          name: "PublicSubnet",
          subnetType: ec2.SubnetType.PUBLIC,
          cidrMask: 24,
          ipv6AssignAddressOnCreation: true,
        },
        {
          name: "PrivateSubnet",
          subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,
          cidrMask: 24,
          ipv6AssignAddressOnCreation: true,
        },
      ],
    });
    const guardDutySecurityGroup = new ec2.SecurityGroup(
      stack,
      "GuardDutyVpcEndpointSG",
      {
        vpc,
        description: "Allow inbound traffic for GuardDuty VPC Endpoint",
        allowAllOutbound: true,
      }
    );

    // GuardDuty VPC エンドポイントの作成
    const guardDutyVpcEndpoint = vpc.addInterfaceEndpoint(
      "GuardDutyDataEndpoint",
      {
        service: ec2.InterfaceVpcEndpointAwsService.GUARDDUTY_DATA,
        privateDnsEnabled: true,
        securityGroups: [guardDutySecurityGroup],
        subnets: { subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS },
      }
    );

    // GuardDuty のセキュリティグループに EKS, RDS, OpenSearch などからのアクセスを許可
    guardDutySecurityGroup.addIngressRule(
      ec2.Peer.anyIpv4(),
      ec2.Port.tcp(443),
      "Allow GuardDuty data traffic"
    );
  }
}
```
   
これにより、CDKの管理下でGuardDuty用のVPCエンドポイントが作成され、`cdk destroy`時に適切に削除されるようになります。

ちなみに、VPC作成時に明示的にAZを指定しているのにも理由があります。
ap-northeast-1リージョンでは、**NATゲートウェイを作れないAZがあるのです。**

実はアカウントごとにAZを表すa,b,c,dと物理的なAZの対応関係は異なっているので、どのAZがハズレなのかはやってみないとわからないのですが、我々の環境ではap-northeast-1aがハズレAZでした。

## まとめ
AWS CDKを使ってEKSクラスタを構成管理する際、**GuardDutyが自動でVPCエンドポイントを作成することで、CDKの管理外リソースが発生し、削除やロールバックに失敗する問題がある**ことがわかりました。

この問題を防ぐためには、**GuardDuty用のVPCエンドポイントを明示的にCDKで作成し、CDK管理下に置く**ことが重要です。これにより、`cdk destroy`時の削除エラーやロールバック失敗を防ぐことができます。
CloudFront+API Gateway連携時の注意点

# はじめに

CloudFrontとAPI Gatewayを連携させる際、思わぬ問題に遭遇することがあります。
CloudFrontからAPI Gatewayへのルーティングで「Host ヘッダー」「パスの不一致」によって発生する問題と、その解決策について解説します。

# 問題の現象

CloudFrontで以下のような設定をした場合：
- defaultBehavior: S3 Origin
- additionalBehaviors: '/api/*': API Gateway Origin

次のような症状が発生しました：
- `/api/*` パターンに一致するリクエストが、API Gatewayではなく**S3にルーティング**される
- エラーメッセージ: `404 Not Found, Code: NoSuchKey, Key: prod/api/test`

# 原因

この問題の核心は**API Gatewayのエッジ最適化エンドポイント**と**Hostヘッダーの扱い**にありました。

## 発生メカニズム

1. CloudFrontで「全てのビューワーヘッダー」設定を使用すると、**Hostヘッダー**も転送される
2. エッジ最適化API Gateway（例：`test.execute-api.ap-northeast-1.amazonaws.com`）は**内部的にCloudFrontを使用**している
3. HostヘッダーにCloudFrontのドメイン（例：`test.cloudfront.net`）が含まれると、API Gatewayの内部CloudFrontが**元のCloudFrontを呼び出してしまう**
4. 結果的にリクエストが**ループ**し、最終的にデフォルトのS3オリジンにルーティングされる

# 解決策

オリジンリクエストポリシーのヘッダー設定を「**全てのビューワーヘッダー**」から「**なし**」に変更することで解決します。

これにより、API Gatewayへのリクエスト時にHostヘッダーが転送されなくなり、適切にルーティングされるようになります。

# もう一つの問題：パスの不一致

問題を解決した後、今度は別のエラーが発生することがあります：
- エラーメッセージ: `{"message":"Missing Authentication Token"}`

## 具体的な不一致の例

この問題は、CloudFrontとAPI Gatewayのパス設定の不一致から発生しています。具体的な例を見てみましょう：

### CloudFrontの設定
- オリジン: `test.execute-api.ap-northeast-1.amazonaws.com/prod`
- パスパターン: `/api/*`

### API Gatewayの設定
- ステージ: `prod`
- リソース: `/test`（GETメソッド設定済み）

### リクエストの流れ
1. ユーザーが `https://test.cloudfront.net/api/test` にアクセス
2. CloudFrontは `/api/*` パターンに一致し、API Gatewayにリクエストを転送
3. **重要**: このとき、CloudFrontは `https://test.execute-api.ap-northeast-1.amazonaws.com/prod/api/test` にリクエストを送信
4. しかし、API Gatewayには `/api/test` というリソースは定義されておらず、`/test` リソースのみ存在
5. 結果として「Missing Authentication Token」エラーが返される

直接 `https://test.execute-api.ap-northeast-1.amazonaws.com/prod/test` にアクセスすると正常に動作するのに、CloudFront経由では失敗する理由はここにあります。

## 解決策

この問題を解決するには2つの方法があります：

1. **API Gateway側の対応**:
   - API Gatewayに `/api/test` リソースを追加する
   - これにより、CloudFrontから転送されるパスと一致するようになる

2. **CloudFront側の対応**:
   - オリジンパスの設定を変更する（例：`/prod/api` の代わりに `/prod` を指定）
   - ビヘイビアのパスパターンを API Gateway のリソース構造に合わせて調整する（例：`/api/*` から `/test` に変更）

# まとめ

エッジ最適化API Gatewayをオリジンとして使用する場合は：
1. **Hostヘッダーを転送しない**設定にする
2. **パスの一致**を確認する
   - CloudFrontのパスパターンとAPI Gatewayのリソース構造が整合していることを確認
   - オリジンパス設定が正しいことを確認
   - ※エッジ最適化API Gatewayが直接的な原因ではない
VirtualDesktopのVRアプリを終了させた時、SteamVRも終了させたい

VirtualDesktopでVRアプリを利用していると、アプリが終了したタイミングでSteamVRのプロセスも自動で終了させたいというニーズがあります。（主に右手コントローラだけで操作できるがメニューボタンが無くてVRを終了できない時など！）

今回は、PowerShellとWMIイベントを使って、特定のプロセス（ここではVRアプリ）終了時にSteamVRのプロセス（vrmonitor.exe）を終了する方法を紹介します。

## 背景

OpenXR対応のVRアプリで緊急終了した場合、SteamVRがそのまま動作し続けるとデスクトップに戻れず困りますね。ボスが間もなくドアを開けるというのに！  
そこで、対象のVRアプリが終了したことを検知して、SteamVRに関連するプロセスを自動終了させる仕組みを構築します。

## 実現方法

PowerShellのWMIイベント（__InstanceDeletionEvent）を利用すると、プロセスの終了（オブジェクトの削除）イベントを監視できます。  
監視対象のプロセスが終了した際に、指定したアクションを実行するように設定します。

## サンプルコード

以下は、監視対象のプロセス名を `DepthVideoPlayerVR.exe` とし、そのプロセスが終了したら SteamVR のプロセス `vrmonitor.exe` を taskkill コマンドで終了する例です。

```powershell
# monitor.ps1
$processName = 'DepthVideoPlayerVR.exe'
$global:done = $false

# 対象プロセスのみを監視するクエリ
$query = "SELECT * FROM __InstanceDeletionEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_Process' AND TargetInstance.Name = '$processName'"

Register-WmiEvent -Query $query -Action {
    $proc = $Event.SourceEventArgs.NewEvent.TargetInstance
    Write-Host "終了したプロセス: $($proc.Name) (PID: $($proc.ProcessId))"
    
    # SteamVRのプロセス（ここでは vrmonitor.exe ）を終了させる
    Start-Process -FilePath "C:\Windows\System32\cmd.exe" -ArgumentList "/C", "taskkill /IM vrmonitor.exe /f"
    
    # グローバルフラグを設定してメインループで終了を検知
    $global:done = $true
} | Out-Null

Write-Host "プロセス終了の監視を開始しています。"

# 監視ループ。対象プロセスが終了すると、グローバルフラグでループ終了
while (-not $global:done) {
    Start-Sleep -Seconds 1
}
Write-Host "監視スクリプトを終了します。"
```

## コード解説

1. **監視対象プロセスの設定**  
   `$processName` に対象とするVRアプリのプロセス名（例: DepthVideoPlayerVR.exe）を設定します。

2. **WMIクエリの定義**  
   クエリ内で `TargetInstance.Name` を指定して、対象プロセスの終了イベントのみを監視するようにしています。

3. **イベント登録とアクション**  
   `Register-WmiEvent` でイベントを登録し、対象プロセスが終了したときにアクションブロック内で以下を実行します。  
   - 終了したプロセス名とPIDを表示  
   - `Start-Process` を利用して、cmd.exe 経由で `taskkill /IM vrmonitor.exe /f` を実行し、SteamVRのプロセスを終了  
   - グローバル変数 `$global:done` を `true` に設定し、メインの監視ループを終了させる

4. **監視ループ**  
   `while` ループで `$global:done` が `true` になるまで待機し、監視を継続します。

## 実行方法

VRアプリの起動と同時にこの監視スクリプトを非表示モードで実行する場合は、以下のようなバッチファイルを用いると便利です。

```batch
@echo off
rem VRアプリ（DepthVideoPlayerVR.exe）を起動
start "" "C:\Path\to\DepthVideoPlayerVR.exe"

rem 監視用の PowerShell スクリプトを非表示で起動
start "" powershell.exe -WindowStyle Hidden -NoProfile -File "%~dp0monitor.ps1"
```

このバッチファイルを実行すると、VRアプリと監視スクリプトが同時に起動し、VRアプリが終了した際に SteamVR のプロセスも自動的に終了します。

## 注意点

- **WMIイベントの動作:**  
  WMIイベントは別の実行コンテキストで動作するため、イベント内の `exit` ではなくグローバル変数を使ってメインループを制御しています。

- **プロセス名の一致:**  
  対象プロセス名は正確に記述する必要があります。実際の環境に合わせて適宜変更してください。

- **管理者権限:**  
  一部のプロセスの監視や終了には管理者権限が必要となる場合があります。必要に応じて管理者権限で実行してください。

## まとめ

PowerShellとWMIイベントを活用することで、特定のVRアプリが終了した際に自動でSteamVRのプロセスも終了させる仕組みを構築できます。  
今回のサンプルでは、DepthVideoPlayerVR.exeの終了を検知して、vrmonitor.exe（SteamVR関連プロセス）を taskkill コマンドで終了させる例を紹介しました。  
この仕組みを利用して、サボりVRをより安全かつスマートに実現してください！

（※大体LLMにお願いして記事書いてもらいました）
Cherry-pickの基本的な使い方

## Cherry-pickとは
特定のコミットを指定して、その差分だけブランチに取り込める操作のこと。
別ブランチに取り込みたい差分があるけど、ブランチをマージしたくない！！
そんなときに便利。

## コマンド
取り込み先の作業ブランチに移動して、下記のコマンドを叩く。

```
$ git cherry-pick [取り込むコミットID（短縮系でも可）]
```


## コミットIDの確認方法
これで確認できる。
```
$ git log
```
短縮系のコミットIDでもいいから、より多くのコミットを一度に確認したい！というときは...
```
$ git log --oneline
```
初めてのServerlessアプリ実装での 迷い&詰まり&学びポイント その１

# この記事について
Serverless初心者（WorkShopで触ったことはあるが、実際のアプリは作ったことがない人）がちょっとしたアプリの実装をやってみた際の迷い、詰まり、学びをつらつらと書きます。
Lambda多めかなと思って最初Lambdaのタイトルにしていましたが、Serverless全般の方が書きやすいなと思ったのでタイトルを変えました。

# 作っているもの
Googleカレンダーのその日の予定を確認し、お昼ご飯が食べられる時間をずんだもんが教えてくれるBot。
お昼ご飯が食べられないとかなしいのだ。

### 構成図（計画性低）

![ずんだもんBot.drawio (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1126770/93d3d965-81d6-4e1f-b86e-35605a21b676.png)

とりあえずここまで実装してみました。

# 迷い&詰まり&学びポイント

## Lambda-Layersをどう構成するか？

https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/chapter-layers.html

Lambdaのランタイムはサイズを小さくするために必要最小限の構成になっています。
そのため必要なライブラリやパッケージは自分でLambda-Layersに配置する必要があります。

今回の実装ではPythonを利用しましたが、Pythonの場合はpipでインストールしたパッケージをzipに固めてLambda-Layersにアップロードし、関数に関連付けをする必要があります。
また実装の内容としてはGoogleCalendarから空き時間を取得して計算するため、GoogleのAPIを扱うライブラリやタイムゾーンを扱うパッケージが必要でした。

GoogleのAPIはともかくタイムゾーンにも必要だとほとんどの実装で配置することになりそうなので、zipに固めてアップするという手順はやや面倒に感じました。
また今回のような小さな実装では特に問題はなかったですが、たくさんのLambdaを組み合わせて大きな実装をする際にはどのような構成にするか迷いそうだな、と感じました。

１つの関数に関連付けできるLambda-Layersは５つまでとなっており、Lambda-Layers内のパッケージは重複してもエラーになることは無いようだったので、用途に応じたパッケージの固まりをLambda-Layersにしておいて、利用するのが良いのかなと思いました。

参考

https://dev.classmethod.jp/articles/multiple-lambda-layers-have-folders-with-the-same-name/


例）
- Google Calendarを利用する関数で使うパッケージのLambda-Layers
    - Googleの認証用のパッケージ
    - Google Calendar用のパッケージ
- Google Driveを利用する関数で使うパッケージのLambda-Layers
    - Googleの認証用のパッケージ
    - Google Drive用のパッケージ

認証用のパッケージは重複するが気にしない

## コンテナを利用したLambda
今回の実装ではずんだもんに喋ってもらうため実行環境にVOICEVOXが必要でした。
通常のLambdaのランタイムではできないため、VOICEVOXをインストールしたコンテナイメージを作成し、そのイメージをLambdaで実行する形にしました。

こちらは先人がいらっしゃったため、かなりすんなり進みました。
大変助かりました！ありがとうございます！！

https://qiita.com/wanwan_fox/items/b384fe5947a6f8ead53e

ただ私の知識不足からいくつか詰まったポイントがあったので恥ずかしながら記載します。

### ECRのPublic registryとPrivate registryの違い
料金を確認したところPublic registryの方が安かったため、イメージはPublic registryに配置しようと思いました。

しかしそもそも**LambdaではPublic registryのイメージは利用できません**でした。
これを知らず、Lambdaの実装を聞いたコンテキストがある状態で、ChatGPTに「ECRへのイメージの配置方法を教えて」と聞きながら実装を進めていました。
そのためPrivate registryへの配置と判断され、なかなかうまくいきませんでした。

ただ何度かやりとりをしてPublic registryにイメージを配置したいことが伝わると、コマンドが違うことを強調して教えてくれたりして、助かりました。
思い込みもあったのですが、個人的にはコマンドが違うことにはちょっとおどろきました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1126770/99c666e4-d936-4cd5-a8d0-6cda3684d668.png)

その後Lambdaでイメージを指定しようとしてできなかった時。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1126770/01b82a32-c25c-44ee-8f02-bfbf7ef7be04.png)

Public registryとPrivate registryの違いを学習できました。

#### Public registry
- CLIのコマンドは `aws ecr-public` 
- IAMポリシーのPrefixは `ecr-public`
- Regionは `us-east-1` のみ
- Lambdaの実行イメージとしては使えない
- 料金はほぼかからない
#### Private registry
- CLIのコマンドは `aws ecr`
- IAMポリシーのPrefixは `ecr` 
- Regionは任意のリージョンを選択できる
- Lambdaの実行イメージとして使える
- 料金はちょっとかかる（4GBのイメージで月50円ぐらい）

ちゃんとマニュアルを読みましょう。

## 初期タイムアウト設定は3秒
これはWorkShopやJAMイベントでも頻出なので、進研ゼミでやったやつだ！
という感じですが、Lambdaの初期タイムアウト時間は3秒です。
音声ファイルを扱ったりするバッチ処理的なものだとほぼタイムアウトするため伸ばす必要があります。

つづく。


追記：続きです

https://qiita.com/gengen0719/items/78039695fe1a2e6c90d3
Figma CodeConnectを試してみて詰まったところ


## 背景

Figma CodeConnectを試すにあたり、少し手こずったところをがあったので記載する。


## CodeConnect試した内容

Figmaでチュートリアルが用意されているので、それをもとにやった。
[Getting started with Code Connect](https://www.figma.com/code-connect-docs/quickstart-guide/)

このドキュメント通りにやってみたが、publish時にエラーが発生した。

## publishするときに404エラーが出る

「[Use the interactive setup](https://www.figma.com/code-connect-docs/quickstart-guide/#use-the-interactive-setup)」を実行し、
CodeConnectのファイルをAIマッピングで自動生成を実施。

その次に「[Publish Code Connect files](https://www.figma.com/code-connect-docs/quickstart-guide/#publish-code-connect-files)」に進み、以下コマンドを実行。

```
npx figma connect publish --token=PERSONAL_ACCESS_TOKEN
```

すると、以下のエラーが発生。

```
Validating Code Connect files...
Failed to to fetch node info (ERR_BAD_REQUEST): 404 Not found
Please raise any bugs or feedback at https://github.com/figma/code-connect/issues.
```

node-idの情報が間違っていそうなので、FigmaのURLを変えたりしてみたが、解決せず。


### 解決方法

とりあえず、CodeConnectのファイルは自動生成せず、自作してみることにした。
チュートリアルに記載されている、[Simple Design System](https://github.com/figma/sds)だと自動生成されるCodeConnectファイルが多く、何が原因でエラー出ているかわかりづらかったため。
  
[Simple Design System](https://github.com/figma/sds)や[code-connect-demo](https://github.com/jake-figma/code-connect-demo)のCodeConnectファイルを参考に作成した。

AIマッピングを実行することでCodeConnectファイルを自動生成してくれるが、データの受け渡しあたり(propsあたり)を色々修正する必要があったため、自作でもそこまで作業時間は変わらなそうだとも思った。


そしてURLは以下のように指定。node-idの値は、400エラーが出たときと同じ値にした。

```
https://figma.com/design/[ファイルID]?node-id=XXXX-XXX
```

普通にFigmaファイルからURLコピーしてくるともっと長いURLになるが、これだけの情報で良いみたい。



この状態でpublishを実行すると、404のエラーなく成功。


CodeConnectを使うためにやったこととしては、以下のみ。
- CodeConnectのファイルを自作する
- figma.config.jsonを作成  
```json
// figma.config.json
{
    "codeConnect": {
      "parser": "react",
      "include": ["src/**/*.tsx"],
    }
  }
```
- CodeConnectのファイルをpublishする  





## おまけ:CodeConnect微妙だと思ったところ

検証してみて、少し導入に手間がかかると感じたところを記載。


- **CodeConnectファイルの中にロジック書けない**  
ReactコードとCodeConnectファイル、どちらも構造を変えずに済むように、CodeConnect内で値を変換してReactコンポーネントに渡すようにしたかったが、CodeConnectファイル内ではロジックはかけない模様。
コードは文字列として認識されるので、そのままCodeConnectにロジックの状態で反映されてしまう。  
以下の記事でそのことを知った。  
[入社10ヶ月で行った Turtle デザインシステムの開発と関連する取り組み](https://developersblog.dmm.com/entry/2024/12/02/110000)


- **CodeConnectファイルの運用面**  
実装に変更があったら、CodeConnectファイルも変更しなきゃいけないし、動作確認もしなきゃいけないので単純に作業が増える。あとCodeConnectでエラーが出てないかや、CodeConnectとして表示されるコードが正常に動くかもテストしなければいけない。何か良い方法あるのかな？

- **エラーのデバッグ方法がわからない**  
  以前確認したときにFigmaのCodeConnect画面でエラーが出たが、エラー内容を確認することができなかった。  
  もしかしたら何か確認する方法があるのかもしれない



単にコンポーネントをコピーできるくらいだと、運用する労力の方が大きいかなという印象。
今後このCodeConnectを使ったことにより、よりデザイン・開発作業の効率化につながる機能が出ることを期待！


## 参考
- [入社10ヶ月で行った Turtle デザインシステムの開発と関連する取り組み](https://developersblog.dmm.com/entry/2024/12/02/110000)
MS Learn への Contribute をやってみた

# 背景

ちょうど Azure Functions を試し始めた際に、Document のミスを見つけた。
で、会社の人に、Contribute Chance だ！って言われたので、やってみた記録

# やったこと

これを追えばいいという話なので・・

https://learn.microsoft.com/ja-jp/contribute/content/how-to-write-quick-edits

1. MS-Learn で鉛筆マークを押す
   ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/03dcc585-9ef7-4785-ae99-61db75786130.png)
   あれ？ない。

1. English からの自動翻訳だから？と思い、英語版にするとあったので、押す
   ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/eb650bb0-39df-4195-aa76-f6b7c102057d.png)

1. GitHub で、Edit へ
   ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/7f610f84-249b-46a8-8c73-63f9f383b514.png)

1.  Fork を勧められるので、そのまま go
   ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/4adac993-f25e-419d-8383-c87812c2a200.png)

1.  編集しろってことなので編集を
    1.  あれ？編集しようとしたところが見つからない
    1.  別ファイルってことに気付いて飛ぶ
       ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/909b257e-747d-47d6-9890-f8dd3b4c4b81.png)

    1. 必要な行を追加して、Preview 確認
       ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/e32b4339-c89c-4d9b-bdc8-dc2381cc5a47.png)
       [3.12 が対応されたという、Azure Updates はここ](https://azure.microsoft.com/en-us/updates?id=481333)
       [Python の EOL はここ](https://devguide.python.org/versions/)
    1. で、変更の提案を
       ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/1d62f7a5-1fe6-4914-930f-6ed9983da2f7.png)
    1. あとは、待つのみ
       ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/cb3a2078-821a-4375-973a-aee6dea894ab.png)

# あとがき

日本語をドキュメントは自動生成だから直せないってことがよくわかった :laughing:
PDF結合するツールを作っておこうと思う

# はじめに
大したことではないんですが、皆さんPDFの結合ってどうされてますか？
自宅ならいくらでもオンラインのフリーウェアを使えばいいと思いますが、機密情報たっぷりの業務資料ではそんなことできないと思います。かといってAdobeのreaderを使おうとしても有料プランだったりするわけでいちいち手続きを踏むの大変ですよね。試しにChatGPTにつくってもらったらそこそこ使えるツールができたので一応公開しておきます。

# ツールの要件
シンプルにシンプルに...
- GUIで直感的に操作できること
- インプットしたファイルがオンライン上にアップロードされないこと
- ページ番号を振ってくれること
- サイズの違うPDFも結合可能なこと
- 入力されたファイルは名前順にソートしてけつごうするすること


# ソースコード
githubにて公開しています。

https://github.com/kttmu/PDFMerger/tree/main

# 使い方
白枠に対象のPDFファイルをドロップすれば結合できます。出力ファイル名はダイアログが表示されたらそこで指定してあげてください。
※昇順にソートされるので注意

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4014720/54b55c75-55d3-441e-a993-63e3a6d0eced.png)


# EXE化手順
以下コマンドでexe化可能です。デスクトップ等に配置してご利用ください。

```
pyinstaller src/PDFMerger.py --onefile -icon ./icon/icon.png --collect-data tkinterdnd2
```

# さいごに
問題があればgithubのissueに投稿ください。
#0060（2024/02/28）VLMとViTの違い

# VLMとViTの違い

## ViT (Vision Transformer)
- **概要:**  
  ViTは、画像認識タスクのために開発されたトランスフォーマーアーキテクチャをベースとしたモデルです。  
  画像を小さなパッチに分割し、それぞれをトークンとして扱い、従来の自然言語処理で用いられる自己注意機構（Self-Attention）を用いて特徴抽出を行います。

- **原理:**  
  1. **パッチ分割:** 入力画像を固定サイズのパッチ（例えば16×16ピクセル）に分割します。  
  2. **パッチの埋め込み:** 各パッチをフラット化し、線形変換（全結合層）で高次元の埋め込みベクトルに変換します。  
  3. **位置エンコーディング:** パッチの順序情報を保持するため、各埋め込みに位置エンコーディングを加えます。  
  4. **トランスフォーマーエンコーダ:** これらの埋め込みを複数のトランスフォーマー層に入力し、自己注意機構で画像全体の文脈を学習します。  
  5. **出力:** 最終的な表現を用いて画像分類などのタスクを実行します。

## VLM (Vision-Language Model)
- **概要:**  
  VLMは、画像（ビジョン）とテキスト（ランゲージ）という異なるモダリティを統合して扱うモデルです。  
  これにより、画像キャプション生成、画像検索、視覚質問応答（VQA）など、視覚と言語の両方の情報を必要とするタスクに応用されます。

- **原理:**  
  1. **視覚エンコーダ:**  
     - 画像部分は、ViTや従来のCNNなどを利用して特徴抽出が行われます。  
     - ViTが採用される場合、画像はパッチに分割され、自己注意機構により全体の文脈が学習されます。
  2. **言語エンコーダ:**  
     - テキスト部分は、BERTやGPTなどのトランスフォーマーベースのモデルでエンコードされます。  
     - 文章や単語の意味的な特徴を抽出します。
  3. **融合・アライメント:**  
     - 視覚特徴とテキスト特徴を同一空間にマッピングし、クロスモーダルな関連性を学習します。  
     - たとえば、CLIPのようなモデルでは、画像とテキストの埋め込みを対照学習（contrastive learning）で整列させ、相互の類似度を計算します。

## 関係性と違い
- **ViT:**  
  - **対象:** 画像データのみ  
  - **目的:** 画像認識や分類タスク  
  - **特徴:** 自己注意機構により画像のグローバルな文脈を把握

- **VLM:**  
  - **対象:** 画像とテキストという複数のモダリティ  
  - **目的:** 視覚と言語の統合タスク（例：画像キャプション、画像検索、VQA）  
  - **特徴:** 視覚エンコーダ（しばしばViTを利用）とテキストエンコーダを組み合わせ、クロスモーダルなアライメントを行う

- **まとめ:**  
  - **ViT**は、画像認識のためのトランスフォーマーアーキテクチャであり、単一のモダリティ（画像）の処理に特化しています。  
  - **VLM**は、画像とテキストという異なる情報を統合するためのモデル群であり、その一部としてViTが視覚エンコーダとして利用されることもありますが、VLM自体はより広い用途（クロスモーダルな理解）を目的としています。
CORSって何だっけ？

# はじめに

はじめまして！ノベルワークス入社2年目のそうまです！

今回はCORSについて調査した内容を纏めています！


# 概要
CORS（Cross-Origin Resource Sharing） とは、異なるオリジン間でのリソース共有制限を緩和するための仕組み です。

通常、ブラウザは セキュリティ上の制約（同一オリジンポリシー）により、異なるオリジンのリソースにはアクセスできません。
例えば、ある ウェブページが提供元とは異なるサーバーの API にリクエストを送信しても、デフォルトではリソースの共有はブロックされます。
しかし、サーバー側で CORS を適切に設定することで、特定のオリジンからのアクセスを許可できます。

:::note info
オリジン 
ここで言っているオリジンとは、ドメイン・プロトコル・ポートを指します。
:::

# 何故必要なのか

異なるオリジン間でリソースの共有を可能にするためです！
公開APIではCORSを用いてリソースを共有する事で実現しています。(しかし、その代わりにセキュリティは落ちるので認証をしっかり実装する必要がある)

では、そもそもCORSを用いないとリソースの共有が出来ない **同一オリジンポリシー** は何故必要なのか？

## 同一オリジンポリシーの必要性
例えば、以下のような**個人情報を盗む攻撃**が可能になってしまいます。

1. ユーザーが `https://example.bank.com` にログインする(クッキーに認証情報が保存する)
1. ユーザーが `https://akuyousimasu.com` にアクセスする
1. `https://akuyousimasu.com` のスクリプトが勝手に `https://example.bank.com/v1/user` にリクエストを送る
1. 銀行のAPIは「ログイン済みのユーザー」と判断し、個人情報を返してしまう

...でも認証をしっかりしておけば必要無いのでは？と思ってしまうんですが、セキュリティを緩和して不要な抜け道を作るよりかは、必要無ければ最初から絶対に通さない仕組みを採用すべきって事なんですかね？

ここに関しては別で調査します。

# 勘違いしていた事
同一オリジンポリシーは、`GET・POST・PUT` 等のリクエスト自体を制限する物だと思っていましたが、実際にはレスポンスの受け取りを制限するものなので**リクエスト自体は通ってしまいます**。

なので、`POST・PUT・DELETE` は成功可否を受け取れずともサーバー側では処理してしまっているといった状態になります。

しかし、リクエスト自体も通らないケースがあるような気がする...。
それは実際のリクエストを送る前に**プリフライトリクエスト**なるものを送っているからです！

## プリフライトリクエストとは？

実際のリクエストを送る前にCORSの許可を確認し、問題があればリクエストをやめるような仕組みです。

![頭整理.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1100170/73ca84f2-2912-4db2-8d36-c7ef11583a8f.png)

プリフライトリクエストは `OPTION` メソッドで送信します。
開発者ツールを開いた事のある人であれば、誰しも見た事のあるこれです ↓

![スクリーンショット 2025-02-28 22.07.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1100170/75ef26e5-8564-4fd1-a9b5-5d0c58287597.png)

プリフライトリクエストをリクエスト時に強制するには、以下の設定が必要となります！
- API に `Authorization` ヘッダーを必須にする
- Content-Type を application/json にする
- `PUT` , `DELETE` , `PATCH` メソッドを使用する

# 纏め
何かと詰まりやすいCORSの存在ですが、今回調査した事で存在意義がある程度理解出来たため、今後は顔馴染み程度にはなれそうです！

ただ、認証と同一ポリシーの関係性についてはまだ掘り下げる必要がありそうなので、次回以降の課題にしようと思います！
【2週間で合格】AWS Certified AI Practitioner受けてみた

AWS Certified AI Practitionerに合格したので、勉強方法などを共有します。

## 筆者のスペック
- AWS CLF、AWS SAAを1年ほど前に取得
- AWSの実務経験なし
- AIに関する知識なし
    - CopilotやChatGPTを使う程度

## 試験概要
- 試験時間：90分
- 問題数：65問
- 合格ライン：700点
- 出題範囲
    - AI/機械学習の基本概念
    - AWSのAI/機械学習の関連サービス（SageMaker, Bedrock, Rekognitin, Transcribe, Comprehendなど）
    - AIの倫理やユースケース

## 勉強時間・試験結果

2週間で合計20時間程度勉強しました。
結果は795点でした（700点以上で合格）。

## 勉強方法
Udemyの講座を２つ利用しました。

１. **【最新】AWS認定AIプラクティショナー試験突破講座＋模擬試験２回分付き！**

https://www.udemy.com/course/aws-ai-practitioner/?srsltid=AfmBOornlxCsws-LpQBBd9LJR1qeqm4pTjjv3CCRTb1I5xjmnCHq4b0s

動画を一通りみて基礎知識を学びました。
模擬試験はそれぞれ３周しました。
<br>

２. **AIF-C01 / AWS Certified AI Practitioner 対策テスト4回＋補足問題**

https://www.udemy.com/course/aws-certified-ai-practitioner-certification-55-4/

対策テストをそれぞれ３周ずつやりました。
補足問題は時間がなく実施できませんでした。
<br>

公式ドキュメント等は確認できずにこの２つのみで勉強しましたが、本番試験の難易度もほぼ同じくらいだと感じました。

## 受験した感想
AWSのサービスだけでなく、AIや機械学習の基礎について学ぶことができたのが良かったです。教師あり/なし学習の違いやそれぞれの手法といったものから、プロンプトの書き方の種類など、日常でも活かせそうな知識を学ぶことができました。

AIって話題になってるけど何から始めたらいいかわからないといった人にもおすすめできる試験だと思います。

受験を考えている方の参考になれば嬉しいです。

---
参考
- https://aws.amazon.com/jp/certification/certified-ai-practitioner/
bigintを用いてgoogolを表現しよう！！→BigInt(1e100)じゃないの？

# はじめに
今回はbigintについて学んでいた時に自分が間違った解釈をしていたことを共有したいと思います


# 実践
まず簡単に表記できる1e100から使ってみましょう
```
const googol: bigint = BigInt(1e100);
console.log(googol);
```
出力
```
10000000000000000159028911097599180468360808563945281389781327557747838772170381060813469985856815104n
```
となります。
BigIntって誤差ないはずじゃないの？？
なぜ？？

実は1e100自体はIEEE 754なのです。
したがって、次のような挙動で1e100をBigInt型にしているのです。
```
BigInt(1e100)
↓
BigInt(10000000000000000159028911097599180468360808563945281389781327557747838772170381060813469985856815104)
↓
10000000000000000159028911097599180468360808563945281389781327557747838772170381060813469985856815104n
```

丸め誤差が生じているものをBigInt型にしていることになるんですね〜

それではどうやって表現するのか？

# 正確な10^100を得る方法

1. **文字列を使用**:
```javascript
BigInt('1' + '0'.repeat(100))
```

2. **BigIntの累乗を使用**:
```javascript
10n ** 100n
BigInt(10) ** BigInt(100)
```
BigInt型どうしを計算する

# 教訓
大きな数値を扱う場合は
   - 文字列として入力する
   - または BigInt の演算を使用する
   - 浮動小数点数を経由しない
データを識別する番号や記号について

### はじめに
運転免許証番号、マイナンバー、社会保険の番号など
トランザクションデータの採番に関するメモです。

## 番号の定義
例えばログイン時に利用するユーザIDや社員番号
ワークフローシステムにおける申請番号など

システム設計時の観点としては
利用者目線での考えと
プログラム上の処理やテーブル設計などの視点で検討します。

以下の観点で検討する

## フォーマット
１．数値のみ
　数値のみでシンプルです。

　例：電話番号

２．数値とアルファベット
　アルファベットを含めると
　番号に意味を持たせることが可能です

　例：社会保険番号や車のナンバープレート、ゆうちょ銀行の口座番号
３．数値とアルファベット、記号
　番号に複雑性が増します。
　データのバリエーションが増えますが
　文字種が多すぎる場合、利便性が悪くなります。

４．桁数
　データが増加し、桁数超過するとシステム障害につながるため
　該当するシステムを利用する期間を考慮し
　十分な桁数を保持しましょう。

## 採番ルール
・連番の是非
通常だと数値で、連番にするケースが多いでしょう。
ただ、ケースによっては危険な場合もあるため
対象データの特性を意識し決める必要があります。

・番号に意味を持たせるか
意味を持たせた場合、

★悪い例
・ログインに利用するユーザIDを連番にする場合
　サイバー攻撃を受けた際に被害に遭う可能性が高い。
　
## 項目名称

同義語が多数ある。
番号、記号、No、ID。
システム開発会社などでは命名規則があるでしょうが
混乱しないように整理しておきましょう。

通常だと
番号、Noの場合は数値
記号、IDの場合は文字列
になるかな。
Brainf*ck による言語処理系 第3回 〜bool化, 等値比較〜

今回も前回に引き続き、算術演算命令を実装します。
- `boolean`
  - スタックトップをポップして、それが 0 以外ならば 1 を、0 ならば 0 をプッシュ
  - `((bool)value)` に相当
- `boolnot`
  - スタックトップをポップして、それが 0 ならば 1 を、それ以外ならば 0 をプッシュ
  - `!value` に相当
- `notequal`
  - スタックトップの 2 数をポップして、それらが等しくなければ 1 を、さもなくば 0 をプッシュ
  - `!=` に相当
- `equal`
  - スタックトップの 2 数をポップして、それらが等しければ 1 を、さもなくば 0 をプッシュ
  - `==` に相当
  
# Brainf\*ck における条件分岐
`boolean` を実装する前に、Brainf\*ck における if の実装について触れておきます。
Brainf\*ck で条件分岐を行うためにはループを用いるのが唯一の方法です。
以下のコードを実行すると実行開始前の番地が 0 でなければ `then` が一度だけ実行されます。

```brainfuck
[[-]then]
```

実行開始前の番地が 0 以外ならば外側のループに入り、その場所は 0 でクリアされます。
外側のループを抜ける際には、`]` に至ったときにそこが 0 でなければなりません。
そのために実行開始番地を 0 でクリアして、その場所を利用してループを抜けます。

# `boolean` 命令
if を使うと以下のように実装できます。

```brainfuck
[-]<     ; 現在の場所をクリアしてスタックトップに移動
[[-]>+<] ; スタックトップが 0 以外ならば、一つ右を 1 にする
>        ; 結果が入った位置に移動
[-<+>]   ; スタックトップに結果を移動
```

自動生成するコードは以下です。データポインタの位置は命令実行後に変化しません。

```python
def boolean(self):
    assert 0 < self.dp
    return '[-]<[[-]>+<]>[-<+>]'
```

# `boolnot` 命令
`boolean` 命令の出力を反転させたものが `boolnot` 命令です。

```brainfuck
[-]+<    ; 現在の場所をクリアして予め 1 にしておく
[[-]>-<] ; スタックトップが 0 以外ならば、一つ右を 0 にする
>        ; 以下同じ
[-<+>]   ;
```

自動生成するコードは以下です。

```python
def boolnot(self):
    assert 0 < self.dp
    return '[-]+<[[-]>-<]>[-<+>]'
```

# `notequal` 命令
ここまでくれば `notequal` の実装は簡単です。
スタックトップの 2 数の片方から片方を引くと、等しければ 0 に、さもなくばそれ以外になるので、これに `boolean` を適用すると `notequal` となります。

```python
def notequal(self):
    assert 1 < self.dp
    code = '<[-<->]' # スタックの 2 番目からスタックトップを引く
    self.dp -= 1 # 二項演算なので、データポインタは 1 引く
    code += self.boolean()
    return code
```


# `equal` 命令
同様に、引いた結果に `boolnot` を適用すると `equal` となります。

```python
def equal(self):
    assert 1 < self.dp
    code += '<[-<->]'
    self.dp -= 1
    code += self.boolnot()
    return code
```

# まとめ
今回は Brainf\*ck における if イディオムと、それを使った以下の命令を説明しました。
- `boolean`: スタックトップの bool 化
- `boolnot`: スタックトップの bool 化の後、not
- `notequal`: スタックトップの 2 数の不等値比較
- `equal`: スタックトップの 2 数の等値比較

次回は比較命令とそれを使った除算、剰余算命令を解説します。

# リポジトリ
- https://github.com/void-hoge/brainfuck

# 記事リンク
- 第 0 回: [Brainf\*ck による言語処理系](https://qiita.com/voidhoge/items/672d56a512eaa4c0e7b9)
- 第 1 回: [値のロードとストア](https://qiita.com/voidhoge/items/d9b9fcc6efe1017a0a7b)
- 第 2 回: [加算, 減算, 乗算](https://qiita.com/voidhoge/items/e175a5b19793c6711ec2)
- 第 3 回: [bool化, 等値比較](https://qiita.com/voidhoge/items/c414a0791ed53da3db70)
- 第 4 回: [非破壊分岐, 比較, 除算, 剰余算](https://qiita.com/voidhoge/items/317ee453d0cbe0339939)
- 第 5 回: [while, if, スコープ内変数](https://qiita.com/voidhoge/items/ebf91788b953b900cfac)
- 第 6 回: [配列, 多次元配列](https://qiita.com/voidhoge/items/3374976e70976705b523)
- 第 7 回: [コンパイラと言語仕様](https://qiita.com/voidhoge/items/e553220edc255c7fb508)
Brainf*ck による言語処理系 第2回 〜加算, 減算, 乗算〜

今回は基本的な算術演算命令を実装します。
これらは前回説明した値の移動などのテクニックを使って実装できます.
- `add`
  - スタックトップの 2 数をポップし、その和をプッシュ
- `subtract`
  - スタックトップの 2 数をポップし、2 番目から 1 番目を引いたものをプッシュ
- `multiply`
  - スタックトップの 2 数をポップし、その積をプッシュ
  
# `add` 命令
前回説明した足し算を用いて実装します。

```brainfuck
<       ; スタックトップに移動
[-<+>]  ; スタックトップの値をスタックの 2 番目に加算
```

自動生成するコードは以下です。データポインタは差し引き 1 減ります。

```python
def add(self):
    assert 1 < self.dp
    self.dp -= 1
    return '<[-<+>]'
```

# `subtract` 命令
足し算を引き算にするだけで実装できます。

```brainfuck
<       ; スタックトップに移動
[-<->]  ; スタックトップの値をスタックの2番目に対して減算
```

自動生成するコードもほぼ同じです。

```python
def mul(self):
    assert 1 < self.dp
    self.dp -= 1
    return '<[-<->]'
```

# `multiply` 命令

`multiply` 命令は、スタックトップの 2 数をポップした上、その積をプッシュします。

ここでは、以下の状態を初期状態とし、A * B を計算します。
2 番地と 3 番地を一時領域として使用するので 0 で初期化しておきます。

| addr | 0 | 1 | (2) | 3 |
|------|---|---|-----|---|
| data | A | B | 0   | 0 |

ステップ 1: 以下のステップ 2, 3 を 1 番地が 0 になるまで繰り返します。

ステップ 2: まず B から 1 引いて A を 2 番地と 3 番地に加算します。

| addr | 0 | 1   | 2 | 3 |
|------|---|-----|---|---|
| data | 0 | B-1 | A | A |

ステップ 3: 次に A を 3 番地から 0 番地に戻します。

| addr | 0 | 1   | 2 | 3 |
|------|---|-----|---|---|
| data | A | B-1 | A | 0 |

以上 2 ステップを 1 番地が 0 になるまで行うと 2 番地に積が格納されます。

| addr | 0 | 1 | 2     | 3 |
|------|---|---|-------|---|
| data | A | 0 | A * B | 0 |

ステップ 4: 0 番地を 0 でクリアして、2 番地の値を移動すると完了です。

| addr | 0     | (1) | 2 | 3 |
|------|-------|-----|---|---|
| data | A * B | 0   | 0 | 0 |


```brainfuck
[-]>[-]            ; 一時領域のクリア
<<                 ; スタックトップに移動
[                  ; ステップ 1: スタックトップが 0 でない間実行
    -              ; ステップ 2: スタックトップを 1 減らす
    <              ; ステップ 2: スタックの 2 番目に移動
    [->>+>+<<<]    ; ステップ 2: スタックトップの隣 2 つにに値を加算
    >>>            ; ステップ 3: 一時領域に移動
    [-<<<+>>>]     ; ステップ 3: スタックの 2 番目に値を復元
    <<             ; スタックトップに移動
]                  ; ステップ 1: スタックトップが 0 ならば終了
<                  ; ステップ 4: スタックの 2 番目に移動
[-]                ; ステップ 4: 結果を格納するためにスタックの 2 番目だった場所をクリア
>>                 ; ステップ 4: 結果が格納されている場所に移動
[-<<+>>]           ; ステップ 4: 結果を移動
<                  ; 新しいスタックトップの一つ隣に移動
```

自動生成するコードは以下のようになります。

```python
def multiply(self, debug=False):
    assert 1 < self.dp
    self.dp -= 1
    return '[-]>[-]<<[-<[->>+>+<<<]>>>[-<<<+>>>]<<]<[-]>>[-<<+>>]<'
```

# まとめ
今回は以下の命令を説明しました。
- `add`: 加算
- `subtract`: 減算
- `multiply`: 乗算

次回は除算ではなく、先に bool 命令と等値比較について説明します。

# リポジトリ
- https://github.com/void-hoge/brainfuck

# 記事リンク
- 第 0 回: [Brainf\*ck による言語処理系](https://qiita.com/voidhoge/items/672d56a512eaa4c0e7b9)
- 第 1 回: [値のロードとストア](https://qiita.com/voidhoge/items/d9b9fcc6efe1017a0a7b)
- 第 2 回: [加算, 減算, 乗算](https://qiita.com/voidhoge/items/e175a5b19793c6711ec2)
- 第 3 回: [bool化, 等値比較](https://qiita.com/voidhoge/items/c414a0791ed53da3db70)
- 第 4 回: [非破壊分岐, 比較, 除算, 剰余算](https://qiita.com/voidhoge/items/317ee453d0cbe0339939)
- 第 5 回: [while, if, スコープ内変数](https://qiita.com/voidhoge/items/ebf91788b953b900cfac)
- 第 6 回: [配列, 多次元配列](https://qiita.com/voidhoge/items/3374976e70976705b523)
- 第 7 回: [コンパイラと言語仕様](https://qiita.com/voidhoge/items/e553220edc255c7fb508)
【Vite】npm run buildするとReferenceError: env is not definedエラーが出る

# はじめに
process.envで環境変数を読み込めるようにvite.config.jsを修正したところエラーになったので、戒めをこめて記事にします。

# 問題
process.envで環境変数を読み込めるようにvite.config.jsを修正したところReferenceError: env is not definedエラーとなりビルドできない。

```javascript:vite.config.js
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

// https://vite.dev/config/
export default defineConfig({
  plugins: [react(),
		env({ prefix: "VITE",  mountedPath: "process.env" }) 
	]
})
```

# 解決方法
vite-plugin-env-compatibleをimportできていなかった。

```diff_javascript:vite.config.js
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
+ import env from "vite-plugin-env-compatible";

// https://vite.dev/config/
export default defineConfig({
  plugins: [react(),
		env({ prefix: "VITE",  mountedPath: "process.env" }) 
	]
})
```
ライブラリのインストールもできていなかったため、インストール
```
$ npm i --save-dev vite-plugin-env-compatible
```

# おわりに
importを忘れるという、ちょっと恥ずかしいエラーでした。

# 参考

https://qiita.com/Sicut_study/items/d48bec20fa8b082a2368
マルチクラウドデータベース管理

皆さん、こんにちは。

今日は「マルチクラウドデータベース」についてご紹介します。

マルチクラウドデータベース管理は、複数のクラウドプロバイダーを活用して、データベースのパフォーマンス、可用性、拡張性、コスト効率を向上させるアーキテクチャの概念です。

これにより、企業は異なるクラウド環境間でデータベースを分散し、冗長性を確保し、ベンダーロックインを避けることができます。

# アーキテクチャ概念

- データ分散
データを複数のクラウドプロバイダーに分散させ、各クラウドの特性に合わせた管理を行います。例えば、Amazon Web Services (AWS)、Google Cloud Platform (GCP)、Microsoft Azureの異なるサービスを使って、地域別やアプリケーション別にデータベースを分散させることができます。

- 冗長性と高可用性
マルチクラウド環境において、データベースの冗長性を確保することで、障害発生時にも迅速に切り替えが可能となり、高可用性を維持できます。各クラウドのリージョン間でレプリケーションを行い、災害復旧計画（DRP）も構築します。

- データ移行と統合
複数のクラウドにまたがるデータベース管理では、データの移行、統合、同期が重要です。これには、データベースレプリケーションツールやデータ統合プラットフォームが利用されます。

- パフォーマンスの最適化
異なるクラウドプロバイダーが提供するサービスのパフォーマンス特性（例えば、ストレージの速度や計算リソース）に応じて、データベースのワークロードを最適化することが求められます。

- セキュリティとコンプライアンス
各クラウドサービスには異なるセキュリティ基準とコンプライアンス要件があります。マルチクラウド環境でデータベースを管理する際は、データの暗号化、アクセス制御、監査ログなどを各クラウドに適した形で実装し、セキュリティを強化します。

# マルチクラウドの実例

- Hybrid Cloud (ハイブリッドクラウド)
AWS + Azure：ある企業がデータベースの一部をAWSで運用し、他の部分をAzureで運用するケースです。例えば、計算リソースはAWSのEC2インスタンスで実行し、データストレージはAzure Blob Storageに格納する場合です。

- クラウド間レプリケーション
Google Cloud + AWS：Google Cloud PlatformのCloud Spannerを使用し、AWSのAuroraとレプリケーションを行う例です。これにより、アプリケーションが稼働しているAWS環境でデータベースのバックアップやレプリケーションを行い、Google Cloud上で災害復旧や異なる地域への拡張を実現できます。

- データ同期
Microsoft Azure + Google Cloud：企業がGoogle CloudのBigQueryを使って大規模データ分析を行い、Microsoft AzureのSQL Databaseを使ってトランザクションデータを管理するケースです。データは両クラウド間でリアルタイムに同期され、異なるクラウドのデータベースを一元的に管理することができます。

- データベースマネジメントツール
CockroachDB：マルチクラウド環境をサポートするデータベースで、ユーザーは複数のクラウドプロバイダーにまたがるデータベースを管理することができます。CockroachDBは、クラウド環境間で自動的にデータのレプリケーションと同期を行い、可用性を高めます。

- レプリケーションとバックアップ
MongoDB Atlas：MongoDB Atlasでは、AWS、Azure、Google Cloudの複数のクラウドプロバイダー間でデータベースのレプリケーションを実施できます。これにより、バックアップやデータの整合性が複数のクラウド環境で維持されます。

# メリットと課題

## メリット

- 可用性の向上：一つのクラウドに障害が発生した場合でも、他のクラウドに切り替えることでサービスのダウンタイムを最小限に抑えることができます。
- コスト効率：異なるクラウドプロバイダーの価格競争を活用し、コストを最適化できます。
- 柔軟性：必要に応じて最適なクラウドサービスを選択でき、業務に最も適したリソースを選ぶことができます。

## 課題

- 複雑性：複数のクラウドを管理することは技術的に複雑で、異なるクラウドサービス間でのデータ管理やセキュリティの調整が必要です。
- データ転送コスト：クラウド間でデータを転送する際にコストがかかる場合があり、大量のデータ転送が必要な場合はコストがかさむ可能性があります。

マルチクラウドデータベース管理は、高可用性、冗長性、柔軟性を提供する一方で、管理の複雑性やコストの問題も伴います。適切なクラウドサービスとデータベース管理ツールを選択し、運用することが成功の鍵となります。

参考：
https://cloud.google.com/architecture/multi-cloud-database-management?hl=ja

今日は以上です。

ありがとうございました。
よろしくお願いいたします。
Git 運用における注意点

## Git 運用における注意点



### 1. ブランチの運用と【`git checkout`】の注意点

- **背景:**
  Gitでは【`git checkout`】などのコマンドを使ってブランチを切り替えたり新しいブランチを作成します。チームでCI/CD（継続的インテグレーション／継続的デリバリー）を実施している場合、Gitリポジトリの状態がそのまま自動デプロイに影響するため、誤ったブランチで作業すると予期せぬ本番反映などの大きなトラブルにつながる可能性があります。

- **具体的な注意点:**
  - **作業用のブランチを必ず新たに作成する:**
    直接master（またはmain）ブランチで作業を開始すると、CI/CDが即座に反応してしまうリスクがあります。新しい機能や修正は必ず個別のブランチ（例：`feature/○○`、`bugfix/○○`など）で行い、十分なテストが終わった段階でmasterに統合するのが望ましいです。
  - **他のチームメンバーへの影響を避ける:**
    誤ったブランチ操作で本番環境に影響を与えないよう、作業開始前に必ず現在のブランチ状況を確認し、意図したブランチ上で作業することが大切です。

---

### 2. force pushの禁止（特にmasterブランチで）

- **背景:**
  `git push --force`（force push）はリモートリポジトリの履歴を書き換えるコマンドです。これにより、他のメンバーのコミット内容が失われたり、全体の履歴が混乱する危険があります。特に、デプロイ対象となるmasterブランチに対してforce pushを行うと、本番環境に不整合なコードが反映されるリスクが高まります。

- **具体的な注意点:**
  - **履歴の上書きリスク:**
    force pushは一度プッシュされたコミット履歴を強制的に書き換えるため、他のメンバーの作業や修正が上書きされ、後で原因究明やロールバックが困難になります。
  - **自動デプロイとの連動:**
    masterブランチが自動デプロイのトリガーになっている場合、force pushにより意図しない変更が本番環境に反映される恐れがあります。
  - **代替策:**
    必要な場合にのみforce pushを行うならば、一時的なブランチで試すか、保護ブランチの設定を有効にして誤操作を防ぐようにしましょう。

---

### 3. リポジトリに機密情報（APIキー、パスワード、認証情報など）を直接コミットしない

- **背景:**
  機密情報がGitリポジトリに含まれてしまうと、そのリポジトリへのアクセス権を持つ全員が情報を閲覧でき、万が一リポジトリが漏洩した場合にはセキュリティリスクが非常に高まります。特に自動デプロイや連携サービスが多い場合、不正アクセスやサービス停止などの大事故に繋がる可能性があります。

- **具体的な注意点:**
  - **外部公開リスク:**
    プライベートリポジトリであっても、万が一アクセス権の管理に問題があると、情報が外部に流出する恐れがあります。
  - **安全な管理方法:**
    機密情報はGitHub ActionsのSecrets機能、AWS Secrets Manager、環境変数など専用の仕組みを利用して管理し、コードベースには含めないようにしましょう。
  - **コミット後の対策:**
    もし誤って機密情報をコミットしてしまった場合は、速やかにコミット履歴から削除するツール（例：BFG Repo-Cleaner）を使い、パスワードの再発行などの対応が必要です。
【初学者向け】ネットワークインターフェースとは　Azure


## ネットワークインターフェースとは？

:::note
仮想マシン（VM）がネットワークと通信するための「窓口」
:::


## 1. ネットワークインターフェースの役割

Azure 上の仮想マシン（VM）をインターネットや他のネットワークに接続するためには、ネットワークインターフェース（NIC: Network Interface Card）が必要です。

:::note
💬 **イメージ**  
実際の PC やサーバーにおける「LAN ポート」や「Wi-Fi アダプタ」に相当します。  
これがないと、仮想マシンはネットワークに接続できません。
:::

### ✅ Azure NIC の主な役割

1. 仮想マシンがインターネットに接続する（パブリック IP を持たせる）
2. 仮想マシン同士を接続する（同じ仮想ネットワーク内で通信）
3. ファイアウォールやルーティング設定を適用する（NSG を割り当てる）



## 2. ネットワークインターフェースの構成

Azure のネットワークインターフェースは、以下のような構成要素を持ちます。

### ◆ プライベート IP アドレス（必須）

- 仮想ネットワーク（VNet）内で VM を識別する IP アドレス  
- 他の VM と通信する際に利用されます  

### ◆ パブリック IP アドレス（任意）

- インターネットからアクセスするための IP アドレス  
- 外部から VM に直接アクセスできるようになります  

### ◆ ネットワークセキュリティグループ（NSG）

- 通信ルールを定義するファイアウォールのようなもの  
- 例えば「この VM には外部からアクセスできるか？」などの制御が可能  

### ◆ サブネット

- 仮想ネットワーク（VNet）内でのネットワーク範囲を定義  
- VM がどの範囲のネットワークと通信できるかが決まります  

### ◆ ロードバランサーとの関連付け（オプション）

- 複数 VM に対してトラフィックを分散する場合に利用します  



## 3. ネットワークインターフェースの使い方

仮想マシンに対して、1つ以上の NIC を割り当てることが可能です。

### ● 単一 NIC（基本形）

- 1つのネットワークに接続する VM  

### ● 複数 NIC（高度な構成）

- 2つのネットワークにまたがる VM（例: インターネットとプライベートネットワークを分離）

> 💬   
> 社内ネットワークとインターネットの両方に接続する VM を作りたい → NIC を2つ持たせる



## 📝 まとめ

### ● ネットワークインターフェースとは？

> 仮想マシンがネットワークと通信するための「接続ポート」

### ● どんな役割？

- 仮想マシンがネットワーク（インターネット・社内）に接続するための窓口  
- プライベート IP・パブリック IP を設定可能  
- NSG（ネットワークセキュリティグループ）で通信制御ができる  

### 🚀 一言で言うと…

> 仮想マシンがインターネットや社内ネットワークに接続するための**ネットワークポート**
DOMの変更を検知!! MutationObserverAPI

## MutationObserver
MutationObserverは、DOMの変更を検知できるブラウザ標準のAPIです。

> MutationObserver インターフェイスは、 DOM ツリーへ変更が加えられたことを監視することができる機能を提供します。
> https://developer.mozilla.org/ja/docs/Web/API/MutationObserver

かなり昔から使えるようなのですが（2015年くらいには整っていそう）、自分は活用したことがなく
今回便利だな～という出来事があったので、紹介します。

## いつ使ったか
Shopifyを使っているサイトで、アプリ（プラグイン的なやつ）によって商品のおすすめ機能が実装されていました。
その内容をいじりたかったのですが、アプリによって動的に追加される商品要素が
どのタイミングでDOMに追加されるかが分からず困っていました。

力ずくでやるとしたら、スクロールイベントやIntersectionObserverを使って
その要素が画面にあるかを確認し続ける……という方法などが考えられます。
まあそれっぽい感じの実装にはなりますが、適切とは言い難いですね。

### コード
```javascript
// 非表示にしたい商品のハンドルを指定
const targetHandle = "handle-hoge";

// 監視対象の要素を指定
const targetNode = document.querySelector('#hoge-wrapper');

// 監視対象の子要素追加を監視
const callback = (mutationsList, observer) => {
  mutationsList.forEach(mutation => {
    if (mutation.type === 'childList') {
      // 非表示にしたいハンドルを含んだ商品は削除
      $.each($("#hoge-wrapper a"), function() {
        const href = $(this).attr('href');
        if(href.includes(targetHandle)) {
          $(this).closest('.hoge-product').remove();
        }
      });
    }
  });
};

const observer = new MutationObserver(callback);
observer.observe(targetNode, {
  childList: true, //子要素の追加/削除を監視
  subtree: true, //子孫要素も監視対象にする
});
```

### やった内容
動的に追加される要素は、`#hoge-wrapper`というdivに囲まれていたので、
それを監視対象にしています。

MutationObserverのオプションで、`subtree: true`とすると
直下の子要素だけでなく、子孫要素全体を監視対象に含められます。

これにより、指定のdivに要素が追加されたら、任意の処理をする
という想定通りの挙動を実装できました。

便利!!

## 補足
監視対象の要素に動的な要素を追加した場合、
それを検知してまた要素が追加され
さらにまたそれが検知され……
と、無限ループに陥る可能性があるので注意が必要です。

処理の内容に気をつけるのはもちろんながら、
監視を一時的に停止できる `disconnect()` メソッドも役に立ちそうです。

その他にも、変更を検知したら対象のDOMツリーを返してくれるなど
かなりありがたみの強い機能があるので、見てみると結構面白いです!

今回は監視対象に `childList` を指定し、監視対象の子要素に対して使いましたが
`attributes` を指定すると属性値の変更を検知できます。
クラスやdata属性を動的に切り替えるライブラリなどもたくさんあるので、
それに対してなにかしたいときに役立つかもしれません。

## おわりに
今まで使ってなかった理由でもあるのですが、自前で機能を実装している場合は
なにか処理が終わったら……とかレスポンスが返ってきたら……など
最も適切な実行タイミングを自分で指定できるんですよね。

今回のように、第三者が書いたコードであったり、サービスに元々付いている機能だったり
直接処理を追加できない場合は、DOMを頼りにする手法がマッチするかと思います!

ここぞというときに使いましょ!!

ではでは～

## 参考
[MutationObserver - Web API | MDN](https://developer.mozilla.org/ja/docs/Web/API/MutationObserver)
[MutationObserver: observe() メソッド - Web API | MDN](https://developer.mozilla.org/ja/docs/Web/API/MutationObserver/observe)
[MutationObserver: disconnect() メソッド - Web API | MDN](https://developer.mozilla.org/ja/docs/Web/API/MutationObserver/disconnect)
[MutationRecord - Web API | MDN](https://developer.mozilla.org/ja/docs/Web/API/MutationRecord)
[MutationObserver について理解を深める](https://zenn.dev/dotdotdot/articles/94683f6dad45aa)
【初心者】NFS（Network File System）を端的にすっきりまとめる。

### ずばり・・・
主にUNIXOSで利用されている分散ファイルシステムである。IPネットワーク上で使われている。
標準のポート番号はTCPの2049番ポートである。
ネットワークを介して別のコンピューターの外部記憶装置上のファイルシステムをマウントすることができて、そこに保存されているファイルなどをあたかも手元にあるかのように扱うことができる。（AWSとかのEFSとかがイメージしやすい。）

### ほうほう・・・
**NFSサーバー**：ストレージを他のコンピューターに提供するサーバー
**NFSクライアント**：サーバーの持つストレージにアクセスして利用する側のコンピューター

:::note info
豆知識！もともと「ONE RPC」という呼び出し規約が用いられている。これは動的にポート番号を割り振る仕組みだった。しかし、NFS v4ではNFS本体の仕様に組み込まれ、2049番ポートのみで通信が完結するようになった。
:::

### 参考文献（参照日2025年2月28日）

https://e-words.jp/w/NFS.html
アルゴリズム、アーキテクチャ、モデルの違いについて

# アルゴリズム、アーキテクチャ、モデルの違いについて
機械学習やAIについて学んでいる中で、**『アーキテクチャ』**、**『アルゴリズム』**、
**『モデル』**　という用語が度々使われているのを目にしました。
しかし、それぞれの意味や、違いをよく理解せずに学習を進めてしまっていました。

よって、本記事は、これら3つの用語の意味や違いを整理し、
これからの学習をスムーズにすることが目的です。
また、本記事により、皆様の学習の一助となれば幸いです。

## 1.アルゴリズム（Algorithm）とは?

アルゴリズムとは、**問題を解決するための計算手順や学習方法のこと**です。
機械学習では、データのパターンを学習するための方法として使われます。

| アルゴリズム名| 説明 |
|:-:|:-:|
|  勾配降下法（Gradient Descent） |  モデルの誤差を最小化するためにパラメータを更新する方法 |
|  ランダムフォレスト（Random Forest） |  複数の決定木を組み合わせて精度を向上させる手法 |
| K-means  | データをK個のクラスタに分類するクラスタリング手法 |

**ポイント:eye:**
* アルゴリズムとは、計算の手順や学習方法を定めるもの
* どのアーキテクチャでも異なるアルゴリズムを適用可能

## 2.アーキテクチャ（Architecture）とは？

アーキテクチャとは、**ニューラルネットワークや機械学習モデルの設計・構造のこと**です。どのような層（レイヤー）を持ち、どのようにデータを処理するかを決めます。

| アーキテクチャ名 | 説明 |
|:-:|:-:|
| MLP（Multi-Layer Perceptron）  |  全結合層のみのシンプルなニューラルネットワーク |
|  CNN（Convolutional Neural Network） |  画像認識に適した畳み込み層を持つネットワーク |
|  RNN（Recurrent Neural Network） | 時系列データを扱う再帰的なネットワーク  |
| Transformer  |  自然言語処理（NLP）に強いモデル構造 |

**ポイント:eye:**
* アーキテクチャとは、モデルの「設計図」にあたる
* 異なるアーキテクチャを用いることで、モデルの性能や用途が変わる

## 3.アーキテクチャとアルゴリズムの違い
ここでアーキテクチャとアルゴリズムの違いについて、詳しく解説します。
アルゴリズムとアーキテクチャは相互に依存する関係にあります。アルゴリズムは、学習の方法やデータの処理手順を定めるが、その実装にはアーキテクチャが必要です。一方で、アーキテクチャはネットワークの構造を決めますが、学習や推論のためには適切なアルゴリズムが必要になります。

例えば、畳み込みニューラルネットワーク（CNN）を用いた画像認識モデルでは、勾配降下法を用いた誤差最適化（アルゴリズム）が必要です。また、リカレントニューラルネットワーク（RNN）を時系列データに適用する場合、バックプロパゲーション・スルー・タイム（BPTT）というアルゴリズムが学習に用いられます。

このように、アルゴリズムとアーキテクチャは独立した概念ではなく、相互に補完し合う関係にあります。

## 4. モデル（Model）とは？
モデルとは、特定のアルゴリズムとアーキテクチャを使って学習された具体的なものです。学習済みの重み（パラメータ）を持ち、新しいデータに対して予測を行います。

| モデル名 | 説明 |
|:-:|:-:|
|  ResNet-50 |  CNNアーキテクチャを使った画像認識モデル |
| GPT-4  |  Transformerアーキテクチャを使用した大規模言語モデル |
| BERT  |  NLP向けの事前学習済みモデル　 |
|  YOLO（You Only Look Once） | 物体検出に特化したモデル  |

**ポイント:eye:**
* モデルは学習済みの重みを持ち、実際に利用できる状態
* 同じアーキテクチャでも、学習データやチューニングによって異なるモデルになる

## まとめ
    アルゴリズム 　 → 学習の方法(例:勾配降下法)
    アーキテクチャ　→ モデルの設計(例:CNN、Transformer)
    モデル         → 学習済みの実体(例:ResNet-50、chatgpt)

例えば、GPT-4はTransformerアーキテクチャを用い、自己回帰型のアルゴリズムで学習されたモデルです。
【備忘録】Next.js 15で外部ホストの画像利用時にエラーが発生

# はじめに
Next.js 15で`unsplash`の画像を引用した際に以下のエラーが発生した。

```
Error: Invalid src prop (https://images.unsplash.com/photo-1544947950-fa07a98d237f?auto=format&fit=crop&q=80&w=200) on `next/image`, hostname "images.unsplash.com" is not configured under images in your `next.config.js`
See more info: https://nextjs.org/docs/messages/next-image-unconfigured-host
```

# 原因
Next.jsではセキュリティ上の理由から、
外部画像を読み込む際に使用するホスト名を明示的に許可する必要がある。

# 対処方
`next/image`コンポーネントを使用する際、外部ホスト名を`next.config.js`に定義する。

+ `next.config.js` を編集
```config:next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  images: {
    remotePatterns: [
      {
        protocol: 'https',
        hostname: 'images.unsplash.com',
        port: '',
        pathname: '/**',
      },
    ],
  },
};

export default nextConfig;
```

以上です