OmniAICreator/Qiita-1.07M huggingface dataset:
Attention の行列計算を大雑把に見ていく

# Attention の行列計算
Attention 機構では Query, Key, Value として扱われる行列に対して以下の式で計算が行われる
$${\rm Attention}(Q,K,V)={\rm softmax}\left(\frac{QK^\top}{\sqrt{d}}\right)V$$

# 前提
Query, Key, Value は横向きのベクトルを集めて行列にしたものであり、内積は $xy^\top$, テンソル積は $x^\top y$ で表される

# Query と Key の類似度を求める
クエリ(Query) と キー(Key) の類似度を求めよう
類似度は内積を取ることで求められる

$$Q K^\top = \begin{bmatrix}\boldsymbol{q}_1\\\ \boldsymbol{q}_2\\\ \boldsymbol{q}_3\\\ \boldsymbol{q}_4\end{bmatrix}\\begin{bmatrix}\boldsymbol{k}_1^\top\  \boldsymbol{k}_2^\top\ \boldsymbol{k}_3^\top\ \boldsymbol{k}_4^\top\end{bmatrix}$$

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2676125/d19f9d27-d1d3-45c2-8b89-ea760d3795d1.png)

# Value に重み付けをする
Value に重み付け(weight)をしよう
重み付けはテンソル積を取ることで求められる

$$W^\top Q=\begin{bmatrix}w_1^\top\ w_2^\top\ w_3^\top\ w_4^\top\end{bmatrix}\begin{bmatrix}v_1\\\v_2\\\v_3\\\v_4\end{bmatrix}=w_1\otimes v_1+w_2\otimes v_2+w_3\otimes v_3+w_4\otimes v_4$$

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2676125/23f05f6f-a755-442b-b558-5bb871f3c327.png)

# Query, Key の類似度で Value に重み付けをする
全部まとめると Query, Key の類似度を用いて Value に重み付けできる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2676125/f58eea08-9249-4b2b-bb8f-86b27a8fc5c4.png)

このときに重みを正規化したり $\left(\frac{1}{\sqrt{d}}\right)$ 確率的に表したり (softmax) する
$$\therefore {\rm Attention}(Q,K,V)={\rm softmax}\left(\frac{QK^\top}{\sqrt{d}}\right)V$$
Pulumiについて勉強してみた（①基礎知識編）

# 1. はじめに
IaCツールの１種「Pulumi」について勉強したため、備忘録的に記事を作成。
クラウドインフラの構築や運用をコードで管理する「Infrastructure as Code（IaC）」は、モダンなシステム開発・運用の現場において不可欠な手法である。IaCを導入することで、インフラ構成の再現性が高まり、変更履歴の追跡や自動化、CI/CDパイプラインとの統合などが可能になる。
本記事で紹介する「Pulumi」は、IaCツールの中でも PythonやTypeScriptなどの一般的なプログラミング言語でインフラを記述できる、よりモダンなツールである。

# 2. IaCとは
Infrastructure as Code（IaC） とは、サーバーやストレージ、ネットワークといったインフラ構成をコードで記述し、自動的に構築・管理できるようにする手法である。
従来はGUIや手作業で行われていたクラウドリソースの作成・設定を、IaCによって再現性のあるコードとして管理することができる。

【IaCを活用するメリット】
- インフラの構成をバージョン管理できる
- 設定ミスを減らせる
- テスト・CI/CDと統合できる
- 複数人でレビューや再利用がしやすくなる

# 3. IaCツールの分類とPulumiの立ち位置
IaCツールはさまざまな種類がありますが、次の2つの観点で分類すると理解しやすくなる。
- 構成管理方式による分類：エージェントベース vs エージェントレス
- 記述スタイルによる分類：宣言型 vs 命令型
## エージェントベース vs エージェントレス
| 分類 | 説明 |
|:-|:-|
| エージェントベース  | 管理対象のサーバーに常駐型エージェントソフトウェアをインストールし、そのエージェントを通じて設定や監視を行う方式。  オンプレミス環境や、継続的な構成管理・監視が必要な大規模構成に適している。  |
| エージェントレス  | クラウドAPIやSSH接続などを通じて、エージェントなしで直接構成を適用する方式。クラウド環境との相性が良く、セットアップの手軽さや自動化のしやすさから、近年はこちらが主流。  |
## 宣言型 vs 命令型
| 分類 | 説明 |
|:-|:-|
| 宣言型  | 「最終的にどうなってほしいか（desired state）」 を記述し、ツール側が現在の状態との差分を解決してくれる方式。TerraformやCloudFormationが代表的。  |
| 命令型  | 「どのように構成するか（手順）」 を逐次的に記述する方式。AnsibleやPulumiのようにプログラミング言語を用いて柔軟な処理が可能。  |
## ツールごとの分類マッピング
|  | エージェントベース | エージェントレス |
|:-:|:-:|:-:|
| 宣言型 |  - | Terraform, CloudFormation, **Pulumi（※）**  |
| 命令型 | Puppet, Chef  | Ansible, **Pulumi（※）**  |

:::note info
※ Pulumiは命令型の言語（Python、TypeScriptなど）で記述する一方、実行時には「意図された状態（desired state）」を解析し、差分を適用するという宣言型の挙動を持つ。
そのためPulumiは、「命令型スタイルで書ける宣言型IaCツール」とも言える、ハイブリッドな特性を持ったツールである。
:::


# 4. Pulumiが適している場面
Pulumiは、以下のような場面で特に力を発揮する：

- **アプリケーションとインフラを一体化して管理したいとき**
インフラとアプリを別管理せず、同じコードベースで定義・デプロイしたい

- **動的なインフラ構成が求められるとき**
条件分岐やループ、関数、モジュールなどを駆使して柔軟に記述したい

- **宣言型ツールでは柔軟性が足りないと感じたとき**
外部サービスや設定ファイルを使って構成を動的に生成したい

- **マルチクラウド構成を1つのコードで管理したいとき**
AWS、Azure、GCPなどをまたぐ構成を統一的に記述したい

# 5. Pulumiのユースケース例
Pulumiのユースケース例として、「アプリとインフラを同一言語で、同じコードの中で記述・管理できる」という点を強調したユースケースを示す。
> Pythonで開発したデータ処理アプリケーションと、その実行環境であるAWS Lambda、トリガー用のEventBridgeルール、入力データを保持するS3バケットなどを、すべてPythonコードの中で構成・デプロイできる。
> このような統合によって、アプリケーションとインフラの整合性がとれ、変更や保守も容易になる。従来はツールやリポジトリを分けて管理していたインフラとアプリの境界を、Pulumiは自然に統合する。

# 6. 終わりに
次の投稿（リンク）で、Pulumiの活用フローとPulumiプロジェクト内の最適なフォルダ構成について説明する。
WordPressでカテゴリを基にしたパンくずリストを作成する方法

WordPressの `single.php` に、カテゴリを基にしたパンくずリストを自作する方法をまとめました。
今回は、以下の URL 形式に対応するパンくずリストを作成します。

```
http://test.local/blog/?tab_main=news
```

このURLでは、`tab_main` に最初のカテゴリ、`tab_sub` に2番目のカテゴリを設定します。
最初のカテゴリを押下した場合は `tab_sub=all` になり、2番目のカテゴリを押下した場合は `tab_main` が最初のカテゴリ、`tab_sub` が2番目のカテゴリになります。

# 1. パンくずリストのHTML構造
まず、`single.php` に以下のコードを追加します。

```PHP
<div class="breadcrumb">
    <a href="<?php echo home_url(); ?>">ホーム</a> &gt;

    <?php
    $categories = get_the_category();
    
    if ($categories) {
        $tab_main = isset($categories[0]) ? $categories[0]->slug : '';
        $tab_main_name = isset($categories[0]) ? $categories[0]->name : '';

        // カテゴリのURLを作成
        $tab_main_url = home_url('/blog/') . "?tab_main={$tab_main}";

        echo '<a href="' . esc_url($tab_main_url) . '">' . esc_html($tab_main_name) . '</a>';
    }

    // 記事タイトル
    echo " &gt; <span>" . get_the_title() . "</span>";
    ?>
</div>
```

# 2. コードの説明
1\. `get_the_category()` を使用して記事のカテゴリを取得します。

2\. `$categories[0]` を取得し、スラッグを `tab_main` のパラメータに設定します。

3\. `home_url('/blog/')` を基に `tab_main` を含むURLを作成します。

4\. パンくずリストとして、カテゴリと記事タイトルを表示します。

# 3. 出力例
例 1: 記事が「ニュース」カテゴリの場合
```HTML
<a href="http://test.local/blog/?tab_main=news">ニュース</a> > 記事タイトル
```

例 2: 記事が「イベント」カテゴリの場合
```HTML
<a href="http://test.local/blog/?tab_main=event">イベント</a> > 記事タイトル
```
# 4. カスタマイズ

区切りを / に変更
```PHP
echo " / ";
```
CSS でデザイン調整
```CSS
.breadcrumb {
    font-size: 14px;
    color: #666;
}

.breadcrumb a {
    text-decoration: none;
    color: #0073aa;
}

.breadcrumb a:hover {
    text-decoration: underline;
}
```
# まとめ

この方法を使うことで、WordPress のカテゴリを基にした URL 形式のパンくずリストを簡単に作成できます。
備忘録として活用し、必要に応じてカスタマイズしてください！
web.php に書くルーティングの基礎と書き方まとめ

# はじめに

Laravelでは、**ルーティング（Routing）** によって「URLと処理（コントローラやビュー）」を結びつけます。  
その中でも `routes/web.php` は、**主にWeb画面に関係するルーティング**を記述する重要なファイルです。

この記事では、`web.php` に記述する**基本的なルーティングの構文やルール**をまとめていきます。

---

# ①基本のルーティング構文

```php
Route::get('/', function () {
    return view('welcome');
});
```
- Route::get() → HTTPのGETメソッドに対応（URLにアクセスしたとき）
- '/' → URLのパス（例：http://localhost/）
- function () { ... } → 実行する処理（クロージャ）
- view('welcome') → resources/views/welcome.blade.php を返す

# ②HTTPメソッドごとの書き方

![IMG_3734.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2246240/dfb3a127-69fa-414b-b896-8f1e79eb051f.jpeg)

# ③名前付きルート（->name()）
```php
Route::get('/contact', [ContactController::class, 'index'])->name('contact.index');
```

- name('contact.index') としてルートに名前をつけることで、ビューやコントローラー内でルートを簡単に呼び出せる

```php
<a href="{{ route('contact.index') }}">お問い合わせ</a>
```

# ④コントローラーを指定するルート
```php
use App\Http\Controllers\PostController;

Route::get('/posts', [PostController::class, 'index']);
Route::post('/posts', [PostController::class, 'store']);
Route::get('/posts/{id}', [PostController::class, 'show']);
```
- [クラス名, メソッド名] 形式で、コントローラーを割り当てる
- Route::resource() を使うともっと簡略化も可能（後述）

# ⑤ルートパラメータ（{id}など）

```php
Route::get('/users/{id}', [UserController::class, 'show']);
```
- {id} の部分は、リクエストされたURLからパラメータとして取得可能
- コントローラー内で受け取る：

```php
public function show($id)
{
    // $id を使って処理
}
```

# ⑥リソースコントローラー（Route::resource）
よくあるCRUD処理（一覧、詳細、作成、保存、編集、更新、削除）を自動でまとめてくれる便利な方法：
```php
Route::resource('posts', PostController::class);
```

これで以下のようなルートが自動生成されます:
![IMG_3735.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2246240/46a69b32-30e3-4e39-bd19-2cdc42c4273b.jpeg)

# ⑦ルートグループ（共通のprefixやmiddlewareをまとめる）
```php
Route::prefix('admin')->middleware('auth')->group(function () {
    Route::get('/dashboard', [AdminController::class, 'dashboard']);
});
```
- /admin/dashboard のようなURLが作れる
- auth ミドルウェアを共通で適用できる

# ⑧よくある注意点
- web.php に書いたルートはすべて **ウェブブラウザ向け**（セッション・CSRF保護あり）
- **APIルートは routes/api.php に記述**（stateless）

# ⑧まとめ
![IMG_3736.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2246240/d581a8e0-a279-46b7-8444-103ed7d65b7e.jpeg)

Laravelにおいてルーティングは**アプリの入口**。
しっかりと構文とルールを理解しておくと、後のコントローラー・ビュー連携もスムーズに書けるようになります！
達人に学ぶDB設計徹底指南書の学び

ここまでなんとなく先輩の設計をもとに真似してDB設計をしていたが、改めて学び直し、普段触れてこなかった部分を含めて認識をアップデートした箇所をまとめた。

参考：

https://www.amazon.co.jp/%E9%81%94%E4%BA%BA%E3%81%AB%E5%AD%A6%E3%81%B6DB%E8%A8%AD%E8%A8%88-%E5%BE%B9%E5%BA%95%E6%8C%87%E5%8D%97%E6%9B%B8-%E5%88%9D%E7%B4%9A%E8%80%85%E3%81%A7%E7%B5%82%E3%82%8F%E3%82%8A%E3%81%9F%E3%81%8F%E3%81%AA%E3%81%84%E3%81%82%E3%81%AA%E3%81%9F%E3%81%B8-%E3%83%9F%E3%83%83%E3%82%AF/dp/4798124702

# データベースの役割
> 「データ」を整合的に保持して、いつでも簡単に利用可能な状態にしておくためのシステムが、私たちが本書でその設計技法を学ぶ「データベース」です（上記参考書籍 p.3)

日常的に扱っている情報を集約するにあたって欠かせないのが、データ。
それらを適切に標準化し、運用できるように整理して構造に落とし込むこと（機能要件）と、安定的に素早く供給するためのパフォーマンス設計（非機能要件）が価値提供に強く紐づいている。

# 三層スキーマモデル
データ設計をする時に考えるべきスキーマは大きく三つに分けられる。
- 外部スキーマ：ユーザーから見えるビューの世界
- 概念スキーマ：テーブルの世界
論理設計と言われる部分。

- 内部スキーマ：ファイルの世界
設計では物理設計と言われる部分。
普段ビジネスロジックとクエリ、エンティティ部分だけ実装していた自分は意識してこなかった部分を扱っている。

## 物理設計詳細
### サイジング：ストレージサイズ、CPUやメモリの性能の設定を行う。
性能問題の大半はここのI/Oネックによって引き起こされる。(p.35)

### ストレージの冗長構成
RAIDという技術で定義されている。
データを失っても復旧できる仕組み。
ほとんどのレベルで、データを分散して保持しているため、システムの性能のボトルネックとなるI/Oも分散されることでパフォーマンス向上にもつながっている。
深掘りしてもそこまで今は必要なさそうだったので細かいのは割愛する。

### データベースファイルの物理的な配置
・ログファイル：データ復旧と性能向上目的で、データファイルへのアクセスを一度ここを介して処理している。
・データファイル：データを保持する。
・インデックスファイル：使用するかどうかはこの内部で決められているため、開発者が意識することはない。
・システムファイル（設定ファイル）
・一時ファイル：サブクエリやgroup byなど一時処理のために使用。処理終了後に削除される。

# インデックス
レコードを効率的に特定するための概念。劇的な処理の性能向上寄与している。
漠然とDDLを実行する時に書いていたが、その裏側の構造はよくわかっていなかった。
データをフルスキャンするとO(n)だが、インデックスを用いるとO(logn)となる。

### どういうデータに設定すべきか？
1. 検索条件や結合条件に頻繁に使われているカラム
Where句やjoin句に使われるカラムにインデックスを貼ると、その条件にマッチするレコードを高速に検索できる。
注意：検索は裸のデータで行われないとインデックスが適用されないので注意。
 反例：where col_1 * 1.1 > 100 やname like ‘%soukimu%’ など
 修正例：where col_1 > 100/1.1, name like 'soukimu%'（前方一致ならOK）
2. 更新頻度の低いカラム
更新される列値が更新されるとインデックスの値も更新する必要がある。そのため、更新時の性能が劣化してしまう。
よって、更新が頻繁なカラムにインデックスを貼るのは逆効果。
3. カーディナリティの高い（値の種類が多い）カラム
    1. 値のバリエーションが多いほど、インデックスが絞り込みに効く。
    2. 例：ユーザーIDやメールアドレスは○。性別や都道府県は絞り込み効果が低いので△。
4. テーブル全体で分散しているカラム
    1. 特定の値に偏らず、全体的に均等にデータが分布していると、インデックスがより効果的に働く。

特にインデックスは万能ではなく、
読み取りと書き込み性能がトレードオフの関係になっているのは特に気づきとして重要だと思った。

# データクレンジング
業務で利用されているデータをデータベースに落とし込める状態にする作業を指す。
まだシステムに落とされてない業務をシステム化する際にデータ設計の前に行う。

### 必要なこと
- 一意キーの特定
データを集計する際に、同じユーザーなのに異なるデータとして扱われていると実態と乖離してしまう。

- 名寄せ
異なる場所で同じデータを異なる名称で管理している場合に統一する必要がある。
表記揺れの発生する名称、電話番号、住所などをシステムで扱う時にルールを作る。
システム化に際して、定義を明確にすること、その抜け漏れを無くさないと困ってしまう。

# 具体的な経験に照らし合わせたデータ設計の意義
本を読みながら実務と照らし合わせてみて、要求としては全てに対応できる完璧なシステムを要求されるのだが、標準化としてのシステムであるため、目的に応じた必要なデータ、標準化から外すデータを分ける必要があると感じている。

例えば、今取り組んでいる、納品チームの行なっているサービス利用状況レポーティング業務の自動化。
元々はレポートによって、体裁が異なっていたり、使用される用語にブレがあった。引き継ぎのたびに説明が必要だが、標準化されていないため、対応する人が増えていく現状に際して、今まで行ってきた人が業務引き継ぐために負荷が集中してしまう。
それをレポートを統一し、出力するまでを一貫して自動で行われるようにした。これによって、誰でも同じ結果を出せる業務の再現性と安定性を生み出し、一貫した業務引き継ぎを行うことができる。

それと同時に、手作業の業務ではレポーティングする際に、別のデータ分析を目的としても使える体裁となっていたが、目的が異なるため、システム化に際しては対象から外した。

ここで改めてデータ設計をする意義をまとめると
単なるスキーマ定義ではなく、
価値ある情報を、いつでも、誰でも、同じように、確実に引き出せる状態を作ることだと捉えられた。
HomeAssistantとtp-link decoを接続する

## はじめに
私の自宅では、スマート照明としてIKEAの電球とハブを使用して、スマートホーム化を図っている。
Home Assistantを導入するにあたり、IKEA照明との接続方法の日本語記事がなかったので、簡単に記していく。

## 自宅に導入しているデバイス
- HomeAssistant
- tp-link X50

## 準備したもの
- Home Assistant
Proxmoxの仮想環境の上に、Home Assistant OSを構築した
- tp-link X50
- iPhone 16 pro
    - decoアプリ 
## 手順
1.　Home Assistantに HACS(Home Assistant Community Store)を導入する。導入は以下のブログを参考に行った。

https://savoia-s21.hatenablog.jp/entry/2024/06/21/095237

2.　Home Assistantを再起動すると、画面左メニューに「HACS」が追加されているので、それを選択する
3.　「TP-Link Deco」を検索窓から検索し、選択する
![スクリーンショット 2025-03-23 21.24.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919555/fbdd4245-f7fd-45c5-9752-2c397d22542b.png)
4. 右下の「DOWNLOAD」からダウンロード
5. 「設定」から「Restert required」をクリック
![スクリーンショット 2025-03-23 21.29.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919555/c7ff3dd7-4f25-48aa-ac66-cb3a45f5f93d.png)

6.「設定」「デバイスとサービス」「統合を追加」からdeco選択する
7. 以下のように入力をする
|欄|入力する文字|
|:-----------|------------:|
|Username|admin|
|Password|decoのアプリで設定したパスワード|
|Host|decoのipアドレス|
そのほかの値はデフォルトのままにしています。


![スクリーンショット 2025-03-23 21.37.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919555/cc71f0cc-2900-47c3-af39-0e956d2b98af.png)
Datadog Learning Center ー １

Datadogの勉強コースを試しに受けてみた
ほとんど無料で７０コースぐらいある

# 参考

https://learn.datadoghq.com/

## Introduction to Cluster Checks and Endpoint Checks を受けた

表示される言語は英語で言語切り替えはない？

期限が切れるから早くやれみたいに言われて、ちょっと面倒

### 途中でちょっと手順と違ったところ

http_checkがあるとか手順で記載があったような気がしたが、
コマンド結果を見てもなかった
※f -> i の間にhttp_checkはたぶんあるはず

![タイトルなし.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3751407/b8cf1672-2860-4c01-be95-1d5b6f29e350.png)


### Ctrl+Cを押すタイミングで悩んだところ

手順ではCtrl+Cを押せと書いてあるが、
Wait until the clusterchecks pod is running and ready
が完了したタイミングがわかりずらい
READYが 1/1 になったときに押したが、間違っていたかもしれない

![タイトルなし2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3751407/3c673569-dee7-4d99-b884-0012fca3e357.png)


### http_checkが復活した

後の手順でhttp_checkが復活した
これは手順が間違っていたのか、それともどこかで準備完了したのが表示されたのかは分からなかった

![タイトルなし3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3751407/5599ac29-fd43-4143-8b30-3fad9c529177.png)


## 総評

とりあえず、１コース受けた。
時間もそんなにかからないし、アカウントが勝手に作られてDatadogとか見れるから
まぁまぁ面白い

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3751407/d90eaa44-cf46-4331-b6c7-34a65e0ad847.png)
TCP/IP、HTTP/2、スイッチ・ルータの仕組み

## 概要
ネットワーク通信の仕組みを理解することは、応用情報技術者試験の午後問題で高得点を取るために重要です。本記事では、TCP/IP、HTTP/2の通信、スライディングウィンドウ、VLAN、L3スイッチとルータの役割について解説します。
試験対策だけでなく、実務にも役立つ知識を整理しましたので、効率的な学習に活用してください。

## 1. TCPコネクションとソケットの関係
Q: TCPコネクションが確立されるとソケットが1つ消費されるのか？
✅ はい、TCPコネクションごとに1つのソケットが確保されます。
・ソケット（Socket）は、IPアドレス＋ポート番号の組み合わせで識別される。
・クライアントとサーバ間でTCPコネクションを確立すると、サーバ側は1つのソケットを割り当てる。
・サーバの同時接続数が多くなると、利用可能なソケットが枯渇し、新たな接続ができなくなる可能性がある。

Q: サーバのソケットが枯渇するとどうなる？
✅ 新規TCPコネクションの確立ができなくなる。
・OSやアプリケーションの設定により、最大接続数が決まる。
・接続を適切に管理（タイムアウト設定、Keep-Aliveの制御など）し、ソケット枯渇を防ぐことが重要。

## 2. HTTP/2とTCPコネクション
Q: HTTP/2ではブラウザが1つのサーバに確立するTCPコネクションは1つだけ？
✅ 基本的に1つのTCPコネクションを使う。
・HTTP/1.1では、リクエストごとに新しいTCPコネクションを作ることが多かった。
・HTTP/2では1つのTCPコネクション内で複数のストリームを並列処理できるため、効率的な通信が可能。

Q: HTTP/2のストリームとは？
✅ ハンドシェイク不要の仮想的なTCPソケットのようなもの。
・1つのTCPコネクション内で複数のリクエストを同時処理できる。
・ヘッドオブラインブロッキング（Head-of-Line Blocking）の問題を解消。

## 3. TCP/IPのスライディングウィンドウとは？
Q: スライディングウィンドウはどこにある？
✅ TCPヘッダ内に「ウィンドウサイズ」として存在する。
・TCPの流れ制御の仕組みで、受信側が処理可能なデータ量を送信側に通知する。
・ウィンドウサイズが大きいほど一度に送れるデータ量が増える。

## 4. VLANとRADIUSの関係
Q: VLANは通信パケットに付与されるもの？
✅ はい、VLANタグ（IEEE 802.1Q）としてイーサネットフレームに付与される。
・VLANタグによって、ネットワークを論理的に分割可能。

Q: RADIUSサーバがVLANを付与する？
✅ RADIUSはユーザ認証時にVLANを動的に割り当てる。
・企業ネットワークでは、RADIUS認証でユーザの所属VLANを動的に設定することが可能。

## 5. L3スイッチとルータの役割
Q: L3スイッチがあるならルータは不要？
✅ L3スイッチはLAN内ルーティング、ルータはWANとの通信を担当。
| 機器 | 役割 |
|:-:|:-:|
| L3スイッチ  | VLAN間ルーティング（社内ネットワーク）  |
| ルータ  | インターネットや異なるネットワークとの通信  |

・L3スイッチは高速なVLAN間通信を提供。
・ルータはWANとの接続、NAT、ファイアウォール機能を担当。

Q: 社内PCのデフォルトゲートウェイはどこ？
✅ L3スイッチをデフォルトゲートウェイに設定するのが一般的。
| VLAN | デフォルトゲートウェイ |
|:-:|:-:|
| VLAN 10（営業部）  | 192.168.10.1（L3スイッチ）  |
| VLAN 20（開発部）  | 192.168.20.1（L3スイッチ）|

・VLAN間通信はL3スイッチが処理。
・インターネット通信は、L3スイッチのデフォルトルートをルータに向ける。

[PC] ---> (L3スイッチ) ---> (ルータ) ---> (インターネット)

## 6. スイッチとルータのOSI参照モデル
Q: スイッチはL2だけ、ルータはL3だけを見る？
✅ いいえ、それぞれ下位層も処理する。
| 機器 | 物理層 (L1) | データリンク層 (L2) | ネットワーク層 (L3) |
|:-:|:-:|:-:|:-:|
| L2スイッチ  | ✅  | ✅（MACアドレス）  | ❌  |
| L3スイッチ  | ✅  | ✅  | ✅（IPアドレスでルーティング）  |
| ルータ  | ✅  | ✅  | ✅（IPアドレスでルーティング）  |

・スイッチはMACアドレスをもとに転送。
・ルータはIPアドレスをもとにルーティング。
・どちらも下位層の処理（L1・L2）を行う。

## まとめ
✅ TCPコネクションごとにソケットを消費する
✅ HTTP/2は1つのTCPコネクション内で複数のストリームを処理
✅ スライディングウィンドウはTCPの流れ制御に利用される
✅ VLANはイーサネットフレームにタグとして付与される
✅ L3スイッチはLAN内ルーティング、ルータはWAN通信を担当
✅ スイッチ・ルータはそれぞれL1～L3
クライアント・サーバーモデル

# はじめに
Webアプリケーションを扱う際によく「クライアント・サーバーモデル」という言葉を目にします。
実は私たちがWebページを閲覧する際には、このモデルに基づいてシステムが構築されており、システム開発においても重要な仕組みであり、概念です。
現代のコンピュータネットワークにおいて非常に重要な仕組みであるクライアント・サーバーモデルの基本を理解することを、本記事のゴールにします。

## クライアント・サーバーモデルとは？
![Image 2025-03-22 at 16.22.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3907600/1f837731-cf7d-4f25-899e-045eff22d296.jpeg)

クライアント・サーバーモデルは、コンピュータネットワークにおいて広く使われている基本的な仕組みの一つです。このモデルでは、サービスを利用する「クライアント」とサービスを提供する「サーバー」、が明確に分かれています。

私たちが見たいWebページをGoogle ChromeやSafari、Arcなどのブラウザで見るためには、使用しているWebブラウザからデータが保存されているサーバーに問い合わせ、サーバー側で処理がされてからデータを受け取り、結果を画面に表示しています。


## クライアントとサーバーの役割
![Image 2025-03-22 at 16.18.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3907600/2c6b9da2-e52c-420e-a88c-f166a0933c46.jpeg)

登場人物は、①ユーザ ②クライアント ③サーバー の3体。
私たち①がPC上でGoogle Chromeのようなウェブブラウザ②を使用して、データを保存・生成してくれる③に問い合わせを行なっています。

#### ① ユーザ
実際にクライアント（ブラウザ）を使用する人です。
私たちが直接サーバーに問い合わせるのではなく、クライアントを経由してデータを取得します。

#### ② クライアント
サービスを利用する側のコンピュータやアプリケーションを指します。
例えば、ウェブブラウザ（Google ChromeやSafariなど）はクライアントの一種です。ユーザーがブラウザを使ってウェブサイトにアクセスするとき、ブラウザはサーバーにリクエストを送信し、サーバーからの応答を受け取ります。

#### ③ サーバー
サービスを提供する側のコンピュータやアプリケーションを指します。
サーバーは、クライアントからのリクエストに応じてデータやサービスを提供します。
例えば、ウェブサーバーはクライアントからのリクエストに応じてウェブページのデータを送信します。

このように、リクエストとレスポンスという形式で、クライアントとサーバがコミュニケーションをとっています。

## クライアント・サーバーモデルの仕組み
クライアント・サーバーモデルでは、以下のような流れで通信が行われます。

![Image 2025-03-22 at 16.20.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3907600/0d5c01f0-ad42-49ab-ae26-a54ec8e63d5c.jpeg)


**1. リクエスト**
クライアントがサーバーに対して何らかの要求（リクエスト）を送信します。
例えば、ウェブブラウザが「このページを表示したいのでデータをください！」というリクエストをサーバーに送信します。

**2. 処理**
サーバーはクライアントからのリクエストを受け取り、必要な処理を行ないます。
例えば、ウェブサーバーはリクエストされたページのデータを準備します。

**3. レスポンス**
サーバーは処理結果をクライアントに返信（レスポンス）します。
例えば、ウェブサーバーはページのデータをブラウザに送信します。

**4. 表示**
クライアントはサーバーからのレスポンスを受け取り、結果を表示します。
例えば、ブラウザは受け取ったデータを元にウェブページを表示します。

## 身近なクライアント・サーバーモデルの例
**ウェブブラウジング**
ウェブブラウザ（クライアント）がウェブサーバーにリクエストを送信し、ウェブページのデータを受け取ります。

**メール**
メールクライアント（OutlookやGmailアプリなど）がメールサーバーにリクエストを送信し、メールの送受信を行ないます。

# まとめ
私たちが検索した結果を使用しているPCやスマホなどの端末で見ることができるのは、使用している端末内のブラウザとサーバーがお互いにデータのやり取りをネットワーク（インターネット）を行なっているからです。
使用している端末でレスポンス結果を表示するために、データはさまざまなルートを辿る旅に出ます。ブラウザから目的地であるサーバーにどのようにデータが送られるのか、ネットワークやHTTPの仕組み、サーバー側で実際に行われている処理などを理解することで、より理解を深めることができます。
こうした仕組みについても、今後まとめていきたいと思います。

今回の記事が理解の一助になれば幸いです。
また、誤った情報を記載していた場合には、遠慮なく教えてください。ASAPで修正します。

最後までお読みいただき、ありがとうございました。


### 参考URL・画像引用元
https://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%A9%E3%82%A4%E3%82%A2%E3%83%B3%E3%83%88_%28%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%82%BF%29

https://developer.mozilla.org/ja/docs/Learn_web_development/Extensions/Server-side/First_steps/Client-Server_overview

https://envader.plus/article/27

https://medium-company.com/%E3%82%AF%E3%83%A9%E3%82%A4%E3%82%A2%E3%83%B3%E3%83%88%E3%82%B5%E3%83%BC%E3%83%90%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0/

https://it-biz.online/it-skills/client-server/
cssでアイコンとテキストを横並びにする方法

## はじめに
cssでアイコンとテキストを横並びにする方法で躓いたので，備忘録としてまとめます．

## 前提
以下のようなコンポーネントで，ボタンの中にアイコンとテキストを横並びにすることを考えています．（jsxの書き方となっています．）
```jsx
<button className="icon-button" onClick={onClick}>
  <span className="icon">{icon}</span>
  <span className="label">{label}</span>
</button>
```
## display:flexを使用する
親要素に`display:flex`をあて，`align-items: center;`とすることで，ボタンの中身のアイコンと文字を横並びで垂直方向を揃えることができます．

```scss
.icon-button {
  display: flex;
  align-items: center;
  
  .icon {
    display: flex;
    align-items: center;
  }
}
```
時間計算量（Runtime Complexity）と空間計算量（Space Complexity）について

# データ構造とアルゴリズム

コーディング面接対策をしている中ですっきりと理解できない概念があったのでそれをまとめさせていただいます。

コーディング面接において注視されるのが、アルゴリズムの計算量とメモリ量が最適であるか。ということ。それを表したものが下記2点である。

・時間計算量(Runtime Complexity)
・空間計算量(Space Complexity)

## 時間計算量(Runtime Complexity)
アルゴリズムが入力サイズnに対してどれくらいの時間（計算ステップ数）がかかるかを表します。
通常、下記のようにBig-O記法 で表されます。

<table>
  <thead>
    <tr>
      <th>計算量</th> 
      <th>Big-O</th>
      <th>例</th>
    </tr>
  </thead>
  <tr>
    <td>定数時間</td> 
    <td>O(1)</td>
    <td>配列の要素を1つ取得（ arr[i] ）</td>
  </tr>
  <tr>
    <td>対数時間</td> 
    <td>O(log n)</td>
    <td>二分探索</td>
  </tr>
  <tr>
    <td>線形時間</td>
    <td>O(n)</td>
    <td>配列を1回ループする</td>
  </tr>
  <tr>
    <td>線形対数時間</td>
    <td>O(n log n)</td>
    <td>クイックソート、マージソート</td>
  </tr>
  <tr>
    <td>二次時間</td>
    <td>O(n2乗)</td>
    <td>ネストしたループ(バブルソート)</td>
  </tr>
  <tr>
    <td>指数時間</td>
    <td>O(2n乗)</td>
    <td>再帰的な組み合わせ探索（ナイーブなフィボナッチ計算）</td>
  </tr>
  <tr>
    <td>階乗時間</td>
    <td>O(n!)</td>
    <td>全順列の探索（巡回セールスマン問題の全探索）</td>
  </tr>
</table>

0(n)の例 -配列の要素の合計を計算 ↓
```
int sum(int[] nums){
    int total = 0;
    for (int num : nums){
        total += num;
    }
    return total;
}
```
→配列の長さnに比例してループ回数が増えるので O(n)。

0(n2乗)の例 -2重ループ ↓
```
void printPairs(int[] arr) {
    for (int i = 0; i < arr.length; i++){
        for (int j = 0; j < arr.length;j++) {
            System.out.println(arr[i] + ", " + arr[j]);
        }
    }
}
```
→二重ループなので O(n²)。


## 空間計算量（Space Complexity)
アルゴリズムが使うメモリ量を入力サイズnの関数として表し、入力サイズnに対して、追加のメモリをどれだけ使うか を評価します。

※追加のメモリ
　→　入力とは別に確保するメモリのこと

<table>
  <thead>
    <tr>
      <th>空間計算量</th> 
      <th>Big-O</th>
      <th>例</th>
    </tr>
  </thead>
  <tr>
    <td>定数空間</td> 
    <td>O(1)</td>
    <td>追加のメモリを使わない</td>
  </tr>
  <tr>
    <td>線形空間</td> 
    <td>O(n)</td>
    <td>配列やリストを作る</td>
  </tr>
  <tr>
    <td>二次空間</td> 
    <td>O(n2乗)</td>
    <td>2D配列を使う</td>
  </tr>
  <tr>
    <td>指数空間</td> 
    <td>O(2n乗)</td>
    <td>再起的なバックトラッキング</td>
  </tr>
</table>

例 O(1)の空間計算量
```
int findMax(int[] arr) {
    int max = arr[0];
    for (int num : arr) {
        if (num > max) {
            max = num;
        }
    }
    return max;
}
```
→ 配列とは別に変数 max しか使っていないので O(1)。

O(n)の空間計算量
```
List<Integer> numsList(int[] arr){
    List<Integer> newList = new ArrayList<>();
    for(int num : arr){
        newList.add(num);
    }

    return newList;
}
```
→ 入力サイズnに比例して新しいリストができるので O(n)。

## まとめ
・時間計算量は「処理時間が入力サイズに対してどれくらい増えるか」
・空間計算量は「追加のメモリがどれくらい必要か」
[SharePoint]スクリプトでリスト・ライブラリー定義を作成してみた

## 背景
SharePoint Online（以下、SPO）でリストを多く扱っていると、**手動で列を1つずつ登録するのが非常に面倒**になります。
「いやいや、GUIでもテンプレート機能あるでしょ？」と思うかもしれませんが、**列の微調整やリストの再利用性を高めたい時に限界を感じることも多いです。**
そこで今回は、**PowerShellを使って、リストの定義スクリプトを作ってみた話**を紹介します。

## ゴール
PowerShellスクリプトを使って、**SPOリストの定義をスクリプト化し、繰り返し展開できるようにする**ことを目指します。
## 前提条件
PowerShell7が使用できる環境。
## 手順
### 1. SPOテナントでアプリ登録を行う
PnP PowerShellを使ってSPOに接続するには、**アプリの登録が必要**です。
公式手順はこちら → [Register an Azure AD app](https://learn.microsoft.com/en-us/sharepoint/dev/solution-guidance/security-apponly-azuread)
- **権限:** `Sites.ReadWrite.All`など、必要な範囲で設定してください。
- **認証方式:** クライアントID＋シークレット認証

以下コードをPowerShellで実行すると、シングルテナント、指定したアプリ名でアプリ登録してくれます。
```powershell
Register-PnPEntraIDAppForInteractiveLogin -ApplicationName $アプリ名$ -Tenant
```
一発で以下ができあがります。管理権限者に承認してもらうことも忘れないようにしてください。意外と強い権限が必要ですね。
![アプリ登録ポータル画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987347/327c6ded-232d-4507-b179-644106dbee29.png)

### 2. PowerShell 7をインストール
Windows PowerShell（v5）ではなく、**PowerShell 7（Core）**を使います。
```powershell
winget install --id Microsoft.Powershell --source winget
```
### 3. モジュールのインストール
以下の2つのモジュールをインストールします。
```powershell
Install-Module PnP.PowerShell -Scope CurrentUser
Install-Module ImportExcel -Scope CurrentUser
```
- **PnP.PowerShell:** SharePoint Online の操作に使用
- **ImportExcel:** Excelファイルからリスト・ライブラリー定義を読み込むために使用

### 4. スクリプト、エクセルを以下からダウンロードし、設定値を更新
https://github.com/tsushoji/document/tree/main/002_%E3%83%84%E3%83%BC%E3%83%AB/002_PowerShell/001_SPO
- **CreateSPOList.ps1:** SharePoint Online の操作に使用（設定値を更新）
- **CreateSPOList.xlsx:** Excelファイルからリスト・ライブラリー定義を読み込むために使用（作成する定義を更新）

### 5. 以下階層でメインスクリプトを実行
📂
├── CreateSPOList.ps1  ← メインスクリプト
├── CreateSPOList.xlsx ← 列定義ファイル（Excel）

## 作成したスクリプト列タイプとSPO列型の対応
**Number:** 数値
**Text:** 1行テキスト
**Note**: 複数行テキスト
**Choice**: 選択肢
**Boolean**: はい/いいえ
**User**: 利用者
**UserGroup**: 利用者グループ
**Lookup**: ルックアップ
**LookupAdd**: ルックアップ（複数）
**Date**: 日付
**DateTime**: 日付と時刻
**URL**: ハイパーリンク
**Currency**: 通貨
**Thumbnail**: 画像

## まとめ
このような感じで便利ツールを作成してみました。日々時間見つけて、**作業が楽になるように他のツールを作っていったり、既存のツールをブラッシュアップしていこう**と考えております。
**何かツールの要望ありましたら、コメントいただけると幸いです。**
上記で展開したスクリプトファイルに課題ありましたら、**githubでisuueあげていただけると幸いです。**
この記事をご覧いただきありがとうございます。
React19+viteのmanualChunkで思った効果が出なかったメモ

# 概要
viteのチャンクサイズが大きくて警告が出たので分割をしようとしたら思った挙動と違ったのでメモ。
結論から言うと、manualChunksで指定する文字列が`react-dom`ではなく`react-dom/client`の指定が必要だった。


[ソースコード](https://github.com/hibohiboo/odyssage/blob/ea67842afa2c7ea75357287ad968aba8df83aee7/apps/frontend/vite.config.ts)

# 環境

ライブラリ|バージョン
--|--
vite|6.2.2
react|19.0.0

# 何が起きたか
## 期待していた挙動
indexからreactのコードが抜かれている

```
$ bun run build
$ tsc -b && bunx --bun vite build
vite v6.2.2 building for production...
dist/assets/index-DIa45wLs.js     18.24 kB │ gzip:  6.98 kB
dist/assets/react-D0zjqeK7.js    260.53 kB │ gzip: 87.88 kB
✓ built in 1.91s
```

## 実際に起きた挙動

index.jsの中にreactのコードも入っている。

```
$ bun run build
$ tsc -b && bunx --bun vite build
vite v6.2.2 building for production...
dist/assets/react-IIfN_Pv2.js     86.48 kB │ gzip: 30.86 kB
dist/assets/index-oaeOqy8N.js    191.19 kB │ gzip: 64.28 kB
✓ built in 1.82s
```

index-oaeOqy8N.jsには下記のようなコメントで始まるソースも入っていた。

```
/**
 * @license React
 * scheduler.production.js
```


このときの設定は下記であった。

```ts:vite.config.ts
// 省略
export default defineConfig({
  // 省略
  build: {
    rollupOptions: {
      output: {
        manualChunks: {
          react: ['react', 'react-router', 'react-dom'],
          // 省略
        },
      },
    },
  },
});
```

# 対応
[この記事](https://github.com/vercel/next.js/discussions/49795)で'react-dom/serverをexcludeしているのをみて、下記のように修正したら期待通りの動作になった。

```diff:vite.config.ts
// 省略
export default defineConfig({
  // 省略
  build: {
    rollupOptions: {
      output: {
        manualChunks: {
-          react: ['react', 'react-router', 'react-dom'],
+          react: [
+            'react',
+            'react-router',
+            'react-dom/client',
+          ],
          // 省略
        },
      },
    },
  },
});

```

実際にソースコードでも下記のようにimportしている。コードで書いている形式にのっとる必要があった模様。

```ts:main.tsx
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import App from './app/App.tsx';


createRoot(root).render(
  <StrictMode>
    <App />
  </StrictMode>,
);
```
Kotlinでべき乗(累乗)

# べき乗とは


>同じ数を自身に何度も繰り返し掛け算する計算方法を「冪乗（べきじょう）」または「累乗（るいじょう）」といいます
冪乗は「an」のように表記し、「aをn回掛ける」という計算を表します。﻿

# pow


powはDouble型かFloat型を使う。

```
    val doubleX = 2.0
    val doubleY = 3.0
    val result = doubleX.pow(doubleY) 
    println(result) // 8.0

    val floatX = 2.0f
    val floatY = 3.0f
    val result = floatX.pow(floatY)
    println(result) // 8.0
```

Intをべき乗する際もtoDouble()でDouble型に変換しながらべき乗を行えば問題ない。
```
    val intX = 2
    val intY = 3
    val result = intX.toDouble().pow(intY).toInt()
    println(result) // 8
```



    

# Mathクラスを使わない方法
```
fun main() {
    val intX = 2
    val intY = 3

    var result = 1
    for (i in 1..intY) {
       result *= intX
    }
    println(result) // Output: 8
}
```
Snowflake認定資格 SnowPro® Core合格体験記


2025年3月1日にSnowflakeの認定資格であるSnowPro® Core（以下Core）を受験し、合格しました。

それなりに学習計画を立てて試験に臨んだので、その経緯や所感などを記事に残します。

# Snowpro Core とは
Snowflakeの基本的な機能や仕様について理解していることを証明する資格です。認定試験に合格することで取得できます。
Snowflakeにはいろいろな認定試験がありますが、このCoreが最も初心者向けでベーシックな内容になります。

# 自分が受験した試験の概要
- バージョン：COF-CO2
- 問題数：100
- 制限時間：115分
- 合格点：750点
- 問題形式：4択（複数回答も含む、記述はなし）
- 言語：日本語 （英語 と 韓国語も選択可）
- 試験会場：PEASON VUEテストセンター（自宅も可）

＊問題数は100問ですが一部採点に使用されない問題もあるため、75問ぴったり正解が合格ボーダーになるとは限らないみたいです。点の配分方式は公開されていません。

# 受験にいたる背景
身も蓋もないですがSnowflakeの知識が業務で必須だからというのが受験の大きな動機です。

現職には昨年の8月に転職してきて、研修を終えたのち9月の下旬から現場配属となりました。
もともとデータエンジニアリングの仕事はしていましたが、そこではSnowflakeはあまり使っておらず、ウェアハウスが何なのかすらよくわかっていない状態でした。

今いる現場では開発プロダクトがSnowflake上で動くデータ基盤であるため、キャッチアップとその目標設定としてCoreを受けることにしました。

# 勉強方法
利用したのはUdemyの下記２コースでどちらも問題集です。
前提として2025年2月現在、Coreの公式の問題集などは存在せず、大半の方がUdemyなどの有志による試験対策コンテンツを利用することになるかと思います。

1. [Snowflake SnowPro Core Certification Practice Tests COF-C02](https://www.udemy.com/course/snowflake-snowpro-core-certification-practice-exams/?srsltid=AfmBOorNXyEQQJseZpREuxB_penTIDCxENhVvql6OCrCD2fKgdp3u8rT&couponCode=V2JPLETSLEARN)
        - 問題数700問以上（120問前後の模擬試験×6）
        - 解説に公式ドキュメントのリンクがあり勉強しやすい
        - 本番と同等かそれ以下の難易度という印象
1. [Smart way to prepare for latest [COF-C02] Snowflake SnowPro Core Certification exam. Trusted by 22,000+ Students. ](https://www.udemy.com/course/snowflake-snowpro-core-certification-exam-practice-sets/?srsltid=AfmBOoqfhLDtUDbOo-Ni7avepA6uTuJI8G79aSDv7-is_9onAAiwi-Is&couponCode=V2JPLETSLEARN)
        - 問題数おおよそ300問（模擬試験は6つあるが、うち3つは他の試験と重複）
        - 難易度は概ね1つ同じ


基本的には問題を解く → 不明点を公式ドキュメントを読んで解消というサイクルを繰り返して知識の定着を図りました。


時折誤植もあるので正解した問題でも公式ドキュメントのチェックは必須です。後でも書きますが結果的にはここのチェックで拾い上げた知識が当日の得点を伸ばすのに大いに貢献した気がしています。

自分は1のコースを満点取れるレベルまで繰り返しやったところで、腕試しとして2のコースをやりました。
2コースも平均で70～80％の正答率だったので、このタイミングで受験の決断をしました。ここで正答率が低かったら他の問題集を探してまた腕試しをしていたと思います。
        
# 試験当日
### 試験前
試験は新橋の試験センターで受けました。自宅でも受けられますが準備の面倒や回線不安もあるのでセンターを選びました。

持ち物は身分証が2種類必要です。詳しくは[ピアソンVueの公式サイト](https://www.pearsonvue.com/jp/ja/snowflake.html)を確認してください。
自分は運転免許証とマイナンバーカードを持っていきました。

### 試験中
試験は席に着いた後は操作方法や注意事項などの画面が表示された後に始まります。
「採点に利用されない問題もある」の話はこの注意事項の画面で書かれていました。

試験の言語表示について、日本語で受験申し込みをしていた場合でも原文の英語と機械翻訳された日本語を自由に切り替えることができます。
日本語の機械翻訳はかなりガバいので（「てにおは」すらめちゃくちゃなこともある）、英語の文で受験する心構えもしておくのも良いのかなと思います。

### 試験後
試験は制限時間が尽きるか自分で終了ボタンを押すことで終了します。
いくつかアンケートに回答した後に合否が画面に表示されます。あまり記憶が定かでないですが「あなたは合格しました」という簡素な文章だったと思います。

点数は試験部屋を出た後に受付でもらえるスコアレポートに記載されています。

# 振り返り
先ほども書いた通り、個人的には本番の試験はUdemyの模擬試験よりも踏み込んだ問題が多かった印象です。

パッと見で「何だこれ？」となるような問題は体感半分以上あったのですが、よくよく読むと「あーあれのこと聞いてるのか」と気づいたり、消去法で回を絞り出せる問題がほとんどでした。
ただ消去法するにも他の選択肢が不正解である根拠を知っておく必要があるので、やはり公式ドキュメントの読み込みで知識の守備範囲を広げていたのは大きかったのかなと思います。

また、日頃の業務でSnowflakeを使っている人はなるべくSnowsightの画面を触って、今のアカウントのエディションや自分のロールでできることできないことを把握しておくのもおすすめの勉強法です。

拙い文章でしたがこの記事が読んだ人の合格に少しでも貢献できれば幸いです。
ご拝読ありがとうございました。
formのdisabled要素はsubmitされない

当たり前な話かも知れないが、知らなかったのでメモする。

## 私がやりたかったこと

フォーム要素は「Aドロップダウンリスト」と「Bテキストボックス」二つ。

仕様上、上記フォーム要素は関連があって、
Aドロップダウンリストから特定の要素を選択すると、Bテキストボックスの値に固定値０を埋める。

固定値なので、Bテキストボックスを非活性化し、ユーザーがいじれないようにしたい。

最後に送信ボタンを押すとAドロップダウンリストの選択肢とBテキストボックスの値を送信する。

## しかし、

disabled 属性がついたフォーム要素は、submit送信されなかった。

## 解決方法
### disabledの代わりにreadonlyを使う
例
```
<input type="text" name="B" id="B">
<script>
  ...
  // Aドロップダウンリストから特定の要素を選択したとき
  document.getElementById("B").value = "0";
  document.getElementById("B").readOnly = true;
  ...
</script>
```

### hiddenのinputを追加する
例
```
<input type="text" id="B">
// ドロップダウンリストから特定の要素を選択したとき
<script>
  ...
  // Aドロップダウンリストから特定の要素を選択したとき
  document.getElementById("B").value = "0";
  document.getElementById("B").disabled = true;
  ...
</script>
<script>
  // フォーム送信時にhiddenのinputを追加
  document.getElementById("myForm").addEventListener("submit", function(event) {
    var hiddenInput = '<input type="hidden" name="B" value="0">';
    document.getElementById("myForm").insertAdjacentHTML('beforeend', hiddenInput);
  });
</script>
```
ユーザーにはdisabledで編集不可のテキストボックスを見せて実際の値はhiddenのinputで送信する。

### JavaScriptで送信前にdisabledを解除
例
```
<input type="text" id="B" name="B">
// ドロップダウンリストから特定の要素を選択したとき
<script>
  ...
  // Aドロップダウンリストから特定の要素を選択したとき
  document.getElementById("B").value = "0";
  document.getElementById("B").disabled = true;
  ...
</script>
<script>
  // フォーム送信時にdisabledを解除
  document.getElementById("myForm").addEventListener("submit", function(event) {
    // Bテキストボックスのdisabled属性を解除
    document.getElementById("B").disabled = false;
  });
</script>
```

### 固定値おならバックエンドで処理してもOK

####（　・。。・　）🖐

間違っている内容がありましたら、教えて頂ければ喜びます。
React コンポーネントのpropsの型を取得する方法

## はじめに
Reactのコンポーネントのpropsの型を取得する方法について備忘録として書いておきます．
使い所としては，別ファイルにコンポーネントだけがexportされており，そのコンポーネントの型がエクスポートされていないときに，型を取得したい場合等です．

## 方法
まず，方法としては`React.ComponentProps<T>`を使用します．

## 例
あるファイルで以下のように`Button`コンポーネントが定義されています．
```jsx
type ButtonProps = {
  label: string;
  onClick: () => void;
};

export const Button = ({ label, onClick }: ButtonProps) => {
  return <button onClick={onClick}>{label}</button>;
};
```
そこで以下のコードのように，
`Button`コンポーネントの型は，`React.ComponentProps<T>`を使用して，
`React.ComponentProps<typeof Button>` で取得できます．
これにより，Buttonをラップしたコンポーネントは，Buttonコンポーネントの型を受け付けることができるようになります．

```jsx
// 型を取得する
type WrappedButtonProps = React.ComponentProps<typeof Button>;

const WrappedButton = (props: WrappedButtonProps) => {
  return <Button {...props} />;
};
```

## メリット
- 上記のように型の再利用が可能
- `Omit`や`Pick`と組み合わせることで柔軟に型を作成可能

例えば，2つ目については以下のようにすることで特定のpropsを除いて型を再利用できます．
```jsx
type PropsWithoutOnChange = Omit<React.ComponentProps<typeof Button>, "onChange">;
```

## 付録
refの有無で型を作成したいときは，`React.ComponentPropsWithRef`や`React.ComponentPropsWithoutRef`があります．

```jsx
type InputPropsWithoutRef = React.ComponentPropsWithoutRef<'input'>;
```
とすることで，`input`タグのrefのない型を作成できます．
Node.jsにおけるシングルトン


## そもそもシングルトンとは？

インスタンスが必ず一つであることを保証するようなデザインパターンの一つです。

## Node.js におけるシングルトンの実装方法

node.js では、インスタンスをエクスポートするだけでシングルトンを実現できるみたいです。

```javascript
class SignletonClass {
  item: number;

  constructor() {
    this.item = 0;
  }

  get() {
    return this.item;
  }
}

const singletonClass = new SignletonClass();

// クラスではなく、インスタンスをエクスポート
export default singletonClass;
```

Node.js のドキュメントでは、`Caching`にて以下のような説明がなされています。

> Modules are cached after the first time they are loaded. This means (among other things) that every call to require('foo') will get exactly the same object returned, if it would resolve to the same file.

翻訳すると、

> モジュールは、最初にロードされた後にキャッシュされます。これは、(とりわけ) require('foo') を呼び出すたびに、同じファイル名の場合、まったく同じオブジェクトが返されることを意味します。

なので一度インスタンスにしてしまってエクスポートしてしまえば、インポートするたびに新たなインスタンスは作成されず、最初に作成されたインスタンスが使いまわされるっぽいです。

引用: https://nodejs.org/api/modules.html#caching

使いまわしたくない場合は、クラスをエクスポートして、インポート先でインスタンス化するようにしましょう。

## まとめ

Node.js 環境では、インスタンスをエクスポートして使いまわせばシングルトンのように扱うことができる。

まちがってたらごめんなさい。
フィッシング対策には、まずパスワードマネージャーの自動入力を使おう

# フィッシング対策として現実的に最も有効な方法は、パスワードマネージャーの自動入力機能です
パスワードの入力時には必ずパスワードマネージャーの自動入力を利用するようにするだけで、フィッシング詐欺の大半が防げます。
もしもパスワード入力時に自動入力機能が動作しない場合は異常事態です。フィッシング詐欺に引っ掛かりそうになっている可能性がかなりあります。（サーバートラブル、サーバー移転などの事もああります。）

これがユーザができるフィッシング防止で最も大事だと考えます。なぜそう考えるかについて詳しく書きますね。

### フィッシングサイト対策で最も重要な事は何でしょうか。
フィッシングサイトには絶対にID/パスワードを入力しない事、逆に正しいサイトにはID/パスワードを入力できる事が最も重要です。
このためには、<b>アクセスしたサイトの正誤の判定が重要</b>です。
金融機関を含め多くサイトではURLを目視して正しいかどうか確認するよう案内されていますが、現実的には様々なURL偽装手法があり、それらの偽装をすべて目視で見破るのは困難です。

一方で、<b>パスワードマネージャーは、サイトが本来のサービスドメインと一致しているかを正確に判定し、正しい場合のみ自動入力してくれます。</b>ユーザーができる防止策として、簡単で有効なのはこの自動入力を利用する事です。

### おすすめソフト
1Password、Bitwarden、iCloudなど、様々な優れたパスワードマネージャーがありますのでこれらの有名で信頼できそうなものを使いましょう。
ブラウザ付属のパスワードマネージャーでもかまいません。利用する事でかなり安全になります。


# その他の重要な対策

## パスワードマネージャーを使ったコピペ（手動入力）はダメ。
パスワードマネージャーの自動入力を使わず、パスワードマネージャーのサイト一覧からパスワードを探してコピー＆ペーストするのは、URLの一致確認機能が機能しませんので意味がありません。
自動入力を使いましょう。

## ブラウザの警告を無視しない
ブラウザに警告やエラーが表示されたら注意しましょう。特に証明書エラーなどの警告が出ているサイトにはログインしないでください。

（この記事の目的からはずれますが、過去にサイト側の都合で、ブラウザ警告やエラーを無視して続行する方法をユーザーに案内していた事例が多数ありました。
ユーザーに誤った操作方法を、正しいかのように誤認させてしまったという点で、とても罪深い問題だと思っています。大手サイトや公的なサイトでも多数のじれいありました。）

## 強固で一意のパスワードを使用する

各サイトには十分な長さの固有パスワードを使用し、使い回しを避けましょう。可能であればパスワードマネージャーに生成してもらうことをお勧めします。

## パスワードマネージャーのマスターパスワードを安全に管理する

パスワードマネージャーのマスターパスワードは十分に長いものにし、電子データとして保存しないでください。
覚えられないからと言ってパソコンやスマホ保存するのは避けましょう。それよりは紙に書いて安全な場所に保管する方がまだ安全です。そしてパスワードマネージャーへの日常的なログインは生体認証やPINコードを使いましょう。

## 信頼できるブラウザを使用する

Chrome、Edge、Safariなど有名なブラウザの最新版を使用しましょう。
更新が停止しているマイナーなブラウザや、製作元が不明なブラウザアプリでログインが必要なサイトを利用するのは避けてください。
また、ブラウザ機能拡張も注意が必要です。特に、すべてのサイトに有効な拡張の利用は注意深くなりましょう。

## 迷惑メールフィルタが優秀なメールサービスを使う。
インターネットプロバイダから提供されているメールアドレスや、企業や学校が独自で構築されているメールアドレスでは、フィッシングメールのフィルタの精度が非常に低い事があります。
毎日多数のメールが来る中で、フィッシングメールを人力で判定するのは大変です。フィルタ精度が低いサービスではフィッシングに引っ掛かってしまうリスクがどうしても高くなります。できるだけ迷惑メールフィルタ精度が高いメールサービスを利用しましょう。
私が利用した範囲では、Gmailは迷惑メールフィルタの精度が高いと感じています。

## 二要素認証などが利用可能なら設定する
サービスごとに変わりますが、可能な追加設定があったら検討しましょう

--------

以下思う事を書いておきます。

# URL偽装の目視確認は困難

URLの偽装は、サブドメインを利用した偽装、多言語URLでのキリル文字使用、URLのID/パスワード部分に正規サイトアドレスを埋め込む手法([参考リンク](https://prtimes.jp/main/html/rd/p/000000374.000021207.html))など、様々な方法でURL偽装が行われています。リンクの表示テキストとリンク先が異なるという単純な方法でも意外と効果があります。
今後も予想外の方法でURL偽装は行われるでしょう。


## 正しいURLを覚えておくことは困難
また利用しているサービスのドメインをすべて覚えておくことは、ユーザーにとって現実的ではありません。
例えば、www.netbk.co.jp、www.daiwa.jp、direct.jp-bank.jp.jpnpost.jpが、それぞれ正しいURLかどうか、すぐに判断できるでしょうか？(最後のみ誤りです）
これらを目視で確認して判断するのは困難です。

## 目視に頼るのは危険
検索サイトの広告でフィッシングサイトが表示されることもあります。フィッシングメールは頻繁に来ています。そしてURLの誤認は一度しただけで、大きな金銭的な損害が生じる事があります。
<b>一般ユーザーにURLの正誤の判断を不確実な目視で行わせて、一度でも間違っただけで大きな損害をユーザーの責任とするのは適切ではないと考えます。</b>

人には難しく、コンピューターには簡単なこの確認作業は、目視ではなくパスワードマネージャーに任せるのが良いと思います。

# SSLとか、Free wifiとか、
最近のブラウザはSSL認証されていないURL画面でID/パスワードを入力しようとすると警告が出ます。
また現実的な環境でSSL認証エラーが出ていない場合、途中の経路でID/パスワードを盗むのは難しいと考えます。

# それ以外にも色んな大事な事があるよね。
はい。その通りです。
でも、とても大事なドメイン一致の確認に、目視という危うい方法が推奨されているって、セキュリティ対策全体から見るとアンバランスだと思いませんか？

# まさかりが飛んできたらどうするの
素直に土下座します。ごめんなさい。
でも金融機関のフィッシング対策の案内で、目視確認が重要視され、パスワードマネージャーの利用は全く案内されないのはどうなんだろうと強く思ったので書きました。


# 結論

「フィッシングサイトにID/パスワードを誤って入力しない」という目的においては、パスワードマネージャーの自動入力機能が最も現実的で効果的な対策と考えます。目視によるURL確認という脆弱な方法に頼るよりも、より確実な技術的解決策を活用することが重要と考えます。
【備忘録】sqlcmd

## slqcmdとは
Microsoft SQL Serverに対して、
コマンドラインから操作を行うためのツール

sqlcmdを使って、SQLクエリやスクリプト実行をして、データ取得や更新をかけたり、
バッチファイルにまとめることも可能となります。


## インストール

> [Microsoftの公式サイト](https://learn.microsoft.com/ja-jp/sql/tools/sqlcmd/sqlcmd-utility?view=sql-server-ver16&tabs=go%2Cwindows&pivots=cs1-bash)からダウンロードが可能です。

## 

## DBに接続
```
sqlcmd -S ＜サーバー名＞ -U ＜ユーザー名＞ -P ＜パスワード＞
```
接続が成功すると、1>というプロンプトが表示されます。


## クエリの実行
```
sqlcmd -S ＜サーバー名＞ -U ＜ユーザー名＞ -P ＜パスワード＞ -Q "SELECT * FROM ＜テーブル名＞"
```



## まとめ
sqlcmdはバッチファイルの作成などに、使用すると便利かと思いますが、
SQL Serverに接続できるかの確認で使用する際に使ってみました。
ChatGPTが別チャットの内容を引き継ぐ？ その原因と解決法

# ChatGPTが別チャットの内容を引き継ぐ問題と対処法

## 📝 はじめに
最近、**ChatGPTが過去のチャット内容や指示を新しいチャットに引き継いでしまう**という報告が増えています。  
例えば、「簡潔に話して」と一度指示したら、それ以降の新しいチャットでも簡潔な回答になる、あるいは自分の職業情報を覚えているケースです。  

この記事では、  
- **ChatGPTが指示を引き継いでしまう原因**  
- **実際に起きた事例**  
- **OpenAIの公式見解と設定方法**  
- **問題を解消するための対処法**  
について詳しく解説します。  

---

## 🚨 ChatGPTのメモリ機能と指示引き継ぎの背景
2023年以降、OpenAIは**「メモリ機能」**をChatGPTに導入しました。  
このメモリ機能により、ChatGPTは**ユーザーの好みや過去の指示**を覚えて会話の中で活用します。  

**OpenAIの公式説明**によると：
- メモリ機能は**ChatGPT Plusユーザー**向けに段階的に展開  
- 2024年9月以降、**無料版ユーザーにもメモリ機能**を導入  
- ユーザーは**メモリ機能をオン・オフ可能**  
- メモリ機能で保存された内容は「パーソナライズ設定」で確認・管理可能  

---

## 🔎 実際に起きた事例
### ① **前回の口調や指示が引き継がれた**
> 新規チャットなのに「ひろゆき」口調で話し出した。以前にひろゆき風に話すように指示した覚えがあるが、新しいチャットでその影響が残っていた。  

**➡️ 原因：** メモリ機能が有効で、過去の指示をChatGPTが自動的に保存していたため。  

---

### ② **別チャットの情報が混在**
> 1つ目のチャットでは「未婚で犬を飼っている」と設定したが、別のチャットでは「既婚で猫を飼っている」にした。それなのに新しいチャットでは「犬を飼っている」と回答してきた。  

**➡️ 原因：** メモリ機能がアカウント単位で働いており、チャットごとの設定が分離されていなかったため。  

---

### ③ **自分の職業や個人情報を引き継いだ**
> 新規チャットで自分の職業を言った覚えがないのに、「エンジニアとして働いているのだから…」と話し始めた。  

**➡️ 原因：** 以前のチャット内容がメモリに記憶されていた可能性がある。  

---

## 📌 発生環境
| 環境 | 状況 |
|-------|-------|
| **ChatGPT Plus (GPT-4/GPT-4.5)** | メモリ機能有効、引き継ぎ問題が発生しやすい |
| **ChatGPT Free (GPT-3.5)** | 2024年9月からメモリ機能利用可能（デフォルト無効） |
| **ChatGPT アプリ版 (iOS, Android)** | メモリ機能はブラウザ版と同様に動作 |
| **欧州・韓国ユーザー** | 2024年4月まではメモリ機能対象外だった |

---

## 🏢 OpenAIの公式説明
OpenAIによると、メモリ機能は次のように説明されています：

- ユーザーが**「これを覚えて」**と指示しなくても、自動的に記憶されることがある  
- メモリの状態や保存内容は「**パーソナライズ設定**」から確認可能  
- メモリ機能をオフにすると、**チャット間の情報引き継ぎは無効化**される  

---

## 💡 具体的な対処法
### ✅ **① メモリ機能を無効にする**
1. ChatGPTの設定を開く  
2. 「**パーソナライズ**」を選択  
3. 「**メモリ**」をオフにする  

---

### ✅ **② メモリ内容をクリアする**
1. 設定 → パーソナライズ  
2. 「**メモリをクリア**」をクリック  
3. 確認画面で「削除」を選択  

---

### ✅ **③ 一時チャットを使う**
- 一時チャットモードを使用すると、**記憶が保存されない**  
- 一時チャットは「新規チャット」ボタンから選択可能  

---

### ✅ **④ カスタム指示をリセット**
- カスタム指示（「自分の職業」「回答スタイル」など）を見直す  
- 不要な場合はカスタム指示欄を空にして保存  

---

## 🔥 まとめ
ChatGPTのメモリ機能は非常に便利ですが、**意図しない引き継ぎ**が発生すると困るケースがあります。  
その場合は：  
✅ **メモリ機能をオフにする**  
✅ **メモリ内容をクリアする**  
✅ **一時チャットを使う**  
✅ **カスタム指示を見直す**  

これらを試すことで、ChatGPTを自分に最適な状態に調整できます。  
トラブルシューティングに役立ててください！ 😎  

---

## 🎯 参考リンク
- [OpenAI公式ブログ](https://openai.com)  
- [ChatGPTのメモリ管理ガイド](https://help.openai.com)  

---

## 🙌 最後に
役に立ったと思ったら「**LGTM**」ボタンを押してもらえると嬉しいです！  
質問や意見があればコメントで教えてください！  

---
FullCalendarでカレンダーを簡単に作成（React + vite）

### はじめに
React を使ってカレンダー機能を実装したいときに便利なのが [FullCalendar](https://fullcalendar.io/)
GoogleカレンダーのようなUIを簡単に組み込み可能

今回は設定がシンプルで高速なViteとReactを使って月/週/日ビューに切り替え可能なカレンダーを表示するアプリを最小構成で作成


### 開発環境
- Windows 11
- Vite 6.2.0
- React 19.0.0
- JavaScript


#### 1. Viteで簡単にプロジェクト作成
```bash
npm create vite@latest my-fullcalendar-app --template react
cd my-fullcalendar-app
```
#### 2. Fullcalendarをインストール
```bash
npm install @fullcalendar/react @fullcalendar/daygrid @fullcalendar/timegrid
```



### カレンダー表示

#### `src/App.jsx`
月/週/日ビューに対応した以下最小コードの構成

```jsx
import React from "react";
import FullCalendar from "@fullcalendar/react";
import dayGridPlugin from "@fullcalendar/daygrid";
import timeGridPlugin from "@fullcalendar/timegrid";
import allLocales from "@fullcalendar/core/locales-all";

function App() {
  return (
    <div>
      <FullCalendar
        locales={allLocales}
        locale="ja"
        plugins={[dayGridPlugin, timeGridPlugin]}
        initialView="dayGridMonth"
        height="auto"
        headerToolbar={{
          left: "prev,next today",
          center: "title",
          right: "dayGridMonth,timeGridWeek,timeGridDay",
        }}
        views={{
          dayGridMonth: { buttonText: '月' },
          timeGridWeek: { buttonText: '週' },
          timeGridDay: { buttonText: '日' },
        }}
      />
    </div>
  );
}

export default App;
```


### 起動
```bash
npm run dev
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3655530/eb043d0e-8ecc-4be2-be53-36ed1d31ae7e.png)



### まとめ
FullCalendarで月・週・日ビューの切り替えのカレンダーをシンプルに導入できる初期ビューやボタン表示のカスタマイズも簡単
Hibernateはどうやって遅延ローディングを実現できた？

### はじめに
自分的には遅延ローディングをLazyLoadingに書いた方が可読性の良い文章に見えるn、以下LazyLodingと書きます。

## 概要

HibernateはLazyLoadingを提供するために、`Proxyオブジェクト`を使います。
つまり、実際のEntityを呼び出すのではなく、必要な時だけEntityをロードすることで性能を最適化します。

## Proxyオブジェクトとは？

Proxyオブジェクトは、元のオブジェクトの代理として機能するオブジェクトです。
つまり、代わりに動作してくれる偽物オブジェクトです。

LazyLodingをするためにはリレーションデータが必要な時までロードを後回ししないといけないです。
でも、リレーション関係Entityのフィールドにnullを入れるわけにもいけないので、HibernateはリレーションEntityにProxyオブジェクトを注入することで実際のオブジェクトが存在しているように動作します。

## 例

Userは複数のAddreessを持っていると仮定します。

### Entity

```
@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    @OneToMany(fetch = FetchType.LAZY) // 遅延ローディング設定
    private List<Address> addresses = new ArrayList<>();
}

@Entity
public class Address {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String city;
}
```
`@OneToMany(fetch = FetchType.LAZY)`でLazyLoadingを設定します。

```
// SELECT * FROM user WHERE id = 1;
// Addressはロードしないが、Proxyオブジェクトが注入される。
User user = userRepository.findById(userId).orElseThrow();

// getAddresses()でAddressにアクセスする瞬間、Addressロードされます。（LazyLoading）
// Addressはこの時点でもProxyオブジェクトですが、実際のAddressEntityを参照します。
List<Address> addresses = user.getAddresses();
```


## Proxyは実際Entityの継承オブジェクトだ！

Proxyはどうやって実際のオブジェクトのように動作できるのでしょうか？
Proxyが実際のオブジェクトを継承したタイプを持っているからです。
そのため、実際のオブジェクトへの参照を保持していて、Proxyオブジェクトのメソッドが呼ばれると、実際のオブジェクトのメソッドが呼ばれます。

なので！
`AddressProxy`タイプであるはずなのに`Address`として使われても問題ないのです。


## Jpa Entity定義で必ず従うこと2つ
Proxyオブジェクトが実際のオブジェクトの継承クラスであることで以下の2つは必ず守るべきです。

1. **デフォルトコンストラクタは`private`アクセス制限で宣言してはいけない**
2. **Entityクラスは`final`で定義してはいけない**


Proxy生成時に`super`を呼び出すことができず、Entityを`final`として宣言すれば継承が不可能になるからです。
Google Chromeではdisplay: grid以外の要素の中でもjustify-selfが有効になってしまう

## この記事の概要

タイトルで完結している気もしますが、ブラウザによってjustify-selfの挙動が違うので備忘録がてらまとめた記事です。

なお、この情報は2025年3月23日時点のものです。

## 前提の確認

`justify-self`はGridの中で配置を制御するプロパティです。

CSS Gridを使う場合、多くは親要素から子要素の配置方法を指定するのですが、子要素が自分自身の配置を制御することもできます。

その、自分自身を制御するときに使うプロパティの1つが`justify-self`です。

グリッドのセルの、インライン方向中心[^1]に配置します。

[^1]: ざっくり言えば水平方向の中心です。しかし厳密に言えば違うので、ここでは正しさを優先した記載にしています。

https://developer.mozilla.org/ja/docs/Web/CSS/justify-self

## 起きる事象

以下の条件で、各ブラウザで表示の違いを確認します。

- `display: block`と`display: grid`のコンテナを作成する
- それぞれのコンテナの中に3つずつ要素を配置する
- 1つ目の要素に`justify-self: center`を指定する

<details><summary>実際のコード</summary>
<div>

```html
<div class="container block">
  <p class="item center">Block item</p>
  <p class="item">Block item</p>
  <p class="item">Block item</p>
</div>

<div class="container grid">
  <p class="item center">Grid item</p>
  <p class="item">Grid item</p>
  <p class="item">Grid item</p>
</div>
```

```css
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  font-family: sans-serif;
  padding: 2rem;
}

.container {
  background-color: #ddd;
  padding: 1rem;
  
  & + .container {
    margin-top: 1rem;
  }
}

.block {
  display: block;
}

.grid {
  display: grid;
}

.item {
  background-color: #eee;
  padding: 0.5rem;
  
  & + .item {
    margin-top: 0.5rem;
  }
}

.center {
  justify-self: center;
}

```

</div>
</details>

結果はこのように、Google Chromeだけは`display: block`の中でもインライン方向中央に配置されています。

| ブラウザ | スクリーンショット |
| - | - |
| Google Chrome | ![Chrome.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/bb186ba6-5e0c-4b24-afe8-541017e3a9eb.png) |
| Firefox | ![Firefox.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/7a460352-0a84-46ed-af48-331cb37c19c0.png) |
| Safari | ![Safari.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/5d960773-c6d6-46f9-891c-2c7d2a1cc91f.png) |

`block`が特別なわけでもなく、大抵のもの（たとえば`list-item`などでも）で`justify-self: center`が有効になってしまっていました。

## 気をつけた方が良いかもしれないこと

マークアップ・スタイリングをしている中で、このような流れはあり得るかと思います。

- 最初に`display: grid`を指定してスタイリングをする
- 途中で`flex`や`block`など違うものに変える

あるいは次のようなパターンも。

- `grid`直下の要素に`justify-self`を指定する
- 間の階層に`grid`でない`div`などが挟まる

このような場合、最初は正しく`justify-self`が効いているものの、後から意図せぬ表示になってしまいます。
Google Chromeをメインに開発をしていると、こういった場合に気づきづらいです。

もちろんすべてのブラウザで表示確認をしたりVRTを通すようにしていれば良いのですが、軽微な変更で気が緩むこともなくはないのではと思いました。

（というか、上記は私が個人的に開発している小さなプロジェクトで実際に起こした問題です。「気をつけとけアホが」という指摘はごもっともです。）

## まとめ

- Google Chromeでは`display: grid`以外の要素の中でも`justify-self`が有効になってしまう
- 一見すると正しくレイアウトできていても、他のブラウザで崩れている可能性がある
- マークアップを変更した際など、一応気をつけておいた方が良い
#0075（2024/03/23）DockerのContext

# DockerのContext（コンテキスト）とは？

Dockerでイメージをビルドする際に頻繁に使われる用語のひとつが **Context（コンテキスト）** です。本記事では、Dockerのコンテキストとは何か、どのような役割を持つのかについて詳しく解説します。

---

## 🔹 DockerのContextとは？

Dockerにおける **Context（コンテキスト）** は、DockerイメージをビルドするときにDockerデーモンに送信される「ファイルやディレクトリ群」を指します。

Dockerイメージのビルドコマンドの基本的な形は以下です。

```bash
docker build [option] <コンテキストのパス>
```

この「コンテキストのパス」に指定されたディレクトリ以下のファイル群が、Dockerデーモンに送信され、ビルド処理に使用されます。

## 🔹 Dockerデーモンとは？

Dockerデーモン（Docker Daemon）とは、Dockerのコマンドを処理し、コンテナやイメージの作成、管理、実行などを担うバックグラウンドプロセスです。ユーザーはDockerクライアントを通じてDockerデーモンと通信し、さまざまな処理を指示します。

- **主な役割**：
  - Dockerイメージのビルド
  - Dockerコンテナの起動・停止・管理
  - Dockerネットワークやボリュームの管理

Dockerの動作には必ずDockerデーモンが必要であり、通常、システム起動時に自動的に起動します。


---

## 🔹 Contextが必要な理由

Dockerfileに記述する命令（`COPY`や`ADD`）では、コンテキスト内のファイルだけが対象になります。これによりDockerビルドプロセスは、必要なファイルのみを明確に識別し、安全かつ効率的にイメージを作成できます。

**主なメリット：**

- 明示的に利用可能なファイルを指定し、安全なビルドが可能。
- 不要なファイルがイメージに含まれるのを防ぎ、効率的に管理。

---

## 🔹 Contextの具体的な例

例えば、以下のようなプロジェクトディレクトリがあるとします。

```
myapp/
├── Dockerfile
├── app.py
├── requirements.txt
└── static/
    └── logo.png
```

この場合、`myapp`ディレクトリをコンテキストに指定し、Dockerビルドを実行できます。

```bash
docker build -t myimage ./myapp
```

このときDockerfileの中では次のように記述します。

```dockerfile
FROM python:3.11

WORKDIR /app

COPY requirements.txt .
RUN pip install -r requirements.txt

COPY app.py .
COPY static/logo.png static/logo.png

CMD ["python", "app.py"]
```

Dockerfile内の各ファイルは、コンテキスト内に存在する必要があります。

---

## 🔹 コンテキストを設定する際の注意点

- **サイズを抑える**：コンテキストが大きすぎるとDockerデーモンへの送信が遅くなり、ビルド時間が増えます。
- **セキュリティを考慮**：重要な認証情報や環境変数などを不用意にコンテキストに含めないよう注意します。
- 不要なファイルを除外するためには、`.dockerignore`ファイルを使用します。

### `.dockerignore`の例

```
*.log
__pycache__
node_modules
.env
```

---

## 🔹 まとめ

Dockerのコンテキストとは、Dockerイメージを作成する際にDockerfileから参照可能なファイルやディレクトリの範囲を定義する重要な概念です。正しいコンテキスト設定により、Dockerイメージのビルドを安全かつ効率的に行うことができます。
ローカル文書に聞いたら答えてくれるQAアプリを作ってみた【Python × Streamlit × LLM】 

## きっかけ

こんにちは！
最近、RAG（Retrieval-Augmented Generation）の動きをちゃんと理解してみたくていろいろ調べているのですが、クラウドサービスが主流の中、なかなかイメージしづらいものがありますよね。

で、どうせならローカルのPDFとかテキストに質問できるようなアプリにしたら面白そうだなと。
そうして作ったのが、LocalQA というWebアプリです。

手元のファイルを読み込んで、AIに「これどういうこと？」って聞いたら、ちゃんと中身を読んで答えてくれる。
実際に動かしてみると、思った以上に便利でびっくりしました。

---

## できること

LocalQAでは、以下のようなことができます。

- PDFやTXT、DOCXファイルをアップロードしてデータベース化  
- 文書の内容を自然言語で質問し、AIが回答  
- 回答の出典（元文書の一部）を表示  
- 関連する質問を自動で提案  
- データベースごとの統計やチャンク分布を可視化  

---

## セットアップ

Python環境で動きます。以下で起動できます。

```
git clone https://github.com/your_username/localqa.git
cd localqa
pip install -r requirements.txt
```

次に、`.env` ファイルを作成して、OpenAIのAPIキーを設定します。
```
OPENAI_API_KEY=your_api_key_here
```

アプリ起動：
```
streamlit run app.py
```

ブラウザが開いてWebアプリが立ち上がります。

---

## データベースの作成と管理

サイドバーから「データベース管理」を選びます。

- **新しいデータベースを作成**  
- **既存のデータベースを選択（ラジオボタン）**  
- **削除や初期化**も可能です。

ファイルは複数同時にアップロード可能。対応フォーマットは `PDF`, `TXT`, `DOCX`。

アップロードが完了すると、自動でチャンク分割（500文字 + オーバーラップ100文字）が行われ、埋め込み処理が始まります。

---

## 質問してみる

「質問応答」タブを開き、使用するデータベースを選びます。

質問を入力し、「質問する」ボタンをクリックすると、以下の情報が返ってきます。

- **AIによる回答**
- **出典テキスト（チャンク）**
- **関連質問の提案**

---

## データベース分析機能

アップロードされた文書やチャンクの状況をグラフと表で確認できます。

- 総チャンク数  
- 総ファイル数  
- 総文字数  
- 平均チャンク長  
- チャンク長の分布  
- ファイルごとのチャンク数・文字数など  

---

## 技術スタック

LocalQA は以下の技術で構成されています。

- **Python 3.9+**  
- **Streamlit**：UI構築  
- **OpenAI**：埋め込み＆質問応答  
- **FAISS / ChromaDB**：ベクトル検索  
- **PyMuPDF, python-docx**：ファイル読み込み  
- **LangChain / LlamaIndex**：一部機能に使用可能（拡張予定）

プロジェクト構成は以下の通りです：
```
local_qa/
├── app.py # Streamlitアプリの本体
├── file_loader.py # ファイル読み込み
├── embedder.py # 埋め込み処理
├── vector_store.py # ベクトルDB管理
├── qa_engine.py # 質問応答ロジック
├── config.py # 各種設定
├── logger.py # ログ出力
├── logs/ # ログ保存先
├── data/ # アップロードファイル格納
├── index/ # ベクトルDB格納先
├── requirements.txt
└── README.md
```

---

## 注意点

- OpenAI APIキーが必要（`.env`ファイルで管理）  
- ファイルサイズ上限は200MBまで  
- チャンク分割は自動（変更可能）  
- データベース削除は復元不可なので注意  
- 音声ではなく、テキストベースの応答です（音声対応は検討中）

---

## GitHub

コードは以下で公開しています：

📎 https://github.com/mtrtrdev/localqa  

スターしてもらえると嬉しいです！

---

日々のファイル整理と知識活用に、AIとの自然なやりとりができるLocalQA。  
業務でも趣味でも、ローカルデータの新しい活かし方として、ぜひ使ってみてください。