OmniAICreator/Qiita-1.07M huggingface dataset:
【備忘録】知識グラフ構築の7ステップ


> この記事は個人の学習備忘録として、Neo4jのブログ記事をもとにまとめたものです。知識グラフの基本概念と構築手順を簡潔に理解するための参考になれば幸いです。

## はじめに

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/7e7d3185-510f-40f7-8e56-ae0560bdd167.png)

従来のリレーショナルデータベースでは「データモデル問題」が発生します。物理モデル（実際のデータの保存方法）と概念モデル（私たちが自然に考える方法）にズレが生じるのです。知識グラフとグラフデータベースは、関係性とビジネスルールを物理モデル自体に明示的に組み込むことで、この問題を解決します。

## 知識グラフとは？

![knowledge-graph-svg.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/22d3e225-b58c-4512-9504-3f8cb89fe3bd.png)

知識グラフは、データエンティティとその関係性を整理する設計パターンで、次の3つの主要コンポーネントがあります：
- ノード（データエンティティ）
- ノード間の関係性
- 整理原則（データの概念的な組織化方法）

## 知識グラフ構築の7ステップ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/404e5e5f-e9f1-48de-9a17-876acf32b5fe.png)

### 1. ユースケースを定義する
知識グラフが解決する問題を明確にします。レコメンデーションエンジン、不正検出、サプライチェーン追跡などが一般的です。最初は焦点を絞ったスタート地点を選びましょう。

### 2. データベース管理システムを選択する
主に2種類あります：
- **RDFトリプルストア**: データをサブジェクト-述語-オブジェクトの三つ組として構造化
- **プロパティグラフデータベース**: データをノード、エッジ、プロパティとして表現し、より直感的なモデリングが可能

### 3. 知識グラフをモデル化する
- 主要なエンティティ（ノード）とその関係性を特定
- ノードと関係性にプロパティを追加
- 製品分類法やオントロジーなどの整理原則を適用

### 4. データを準備する
- 関連するデータセットを収集
- 形式の標準化、重複の削除、欠損値の処理、エラーの修正などでデータをクリーンアップ

### 5. データを取り込む
- グラフデータベースインスタンスにデータをインポート
- データソースの要素をグラフのノード、関係性、プロパティにマッピング
- 小さなサンプルから始めて検証後に拡張

### 6. 知識グラフをテストする
- ビジネス上の質問に答えられるクエリを実行
- 結果が期待に沿わない場合はモデルを見直し、データの欠落を確認

### 7. 維持と進化
- 新しいデータソースの追加
- ユースケースの拡大
- モデルの改良
- 自動更新の仕組み構築

## 実例
- **NASA**: 何十年もの計画データを「Lessons Learned Database」という知識グラフに接続し、火星ミッションで200万ドル以上の節約に貢献
- **Cisco**: 2,000万の内部文書を簡単に検索できる知識グラフを作成し、検索時間を半減、年間400万時間の労働時間を節約
- **Novartis**: 遺伝子、疾患、化合物の関係を示す生物学的知識グラフを構築し、薬剤開発のタイムラインを加速

## まとめ
従来のデータベースは豊かな関係性を硬直した構造に平坦化しますが、知識グラフは自然に考えるのと同じ方法でデータを表現できます。まずは焦点を絞ったユースケースから始め、ニーズとデータセットの変化に合わせて進化させましょう。完璧である必要はありません - 役立つものであればよいのです。

## 参考資料
- Neo4j AuraDBで無料のグラフデータベースインスタンスを作成可能
- 「Graph Data Modeling Fundamentals」という無料の自己ペース学習コースがある

https://graphacademy.neo4j.com/courses/modeling-fundamentals/

## 学習した記事
https://neo4j.com/blog/knowledge-graph/how-to-build-knowledge-graph/?utm_source=Twitter&utm_medium=OrganicSocial&utm_campaign=&utm_ID=&utm_term=&utm_content=&utm_creative_format=&utm_marketing_tactic=&utm_parent_camp=&utm_partner=&utm_persona=
IBM Envizi ESG Suite チュートリアル No.2-2：EnviziのUI画面上でグループ（組織階層）を作成する

# EnviziのUI画面上でグループ（組織階層）を作成する
このチュートリアルでは、EnviziのUI画面上でグループ（組織階層）を作成する手順をご紹介します。
目標は、次のグループとサブグループを作成することです。
　＜グループ＞
　　・デモ株式会社
　＜サブグループ＞
　　①デモ株式会社_国内拠点
　　②デモ株式会社_海外関連会社
または、[Envizi チュートリアル No.2-1](https://qiita.com/soooi/items/1aed709e7d09a95867bf) で作成した組織階層を使用いただいても問題ございません。
![図1](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2520117/d48b2874-874b-96b2-77d3-13ce26e962ff.png)

# 1. グループを作成する
1. クリック `管理＞グループ`
![図2](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2520117/1d58488a-0aaa-4d5b-af59-18479352203d.png)
グループのページが表示されます。
　
2. `新規グループの作成`ボタンをクリックします。
![図3](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2520117/ae0ba778-2cd7-4daf-9857-83f53fd67496.png)
　
3. 以下の詳細情報を入力してください。
　・グループ・タイプ：`分類`（`Classification`）
　・組織（所属先）：前提条件として、ご購入いただいた際に取得した組織名を使用する必要がございます。今回は`IBM Japan`と表示されています。
　・名前：グループ名を付けます。例：`デモ株式会社`
　・説明：必要に応じて追記します。
　・レポート率(%)：100
　
 4. `保存`ボタンをクリックします。
![図4](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2520117/3c04e6fd-22e5-4a82-8cd0-0e741a1697e3.png)

 `デモ株式会社`という新しいグループが作成されました。
 ![図5](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2520117/b454c8e9-026b-42d9-a0a3-78ae9805429b.png)

# 2. サブグループ①を作成する
`デモ株式会社`のグループ下に、新しいサブグループ`デモ株式会社_国内拠点`を作成します。

 1. 以下の詳細情報を入力してください。
　・グループ・タイプ：`分類`（`Classification`）
　・組織（所属先）：前提条件として、ご購入いただいた際に取得した組織名を使用する必要がございます。今回は`IBM Japan`と表示されています。
　・親グループ：`デモ株式会社`
　・名前：グループ名を付けます。例：`デモ株式会社_国内拠点`
　・説明：必要に応じて追記します。
　・レポート率(%)：100
　
 2. `保存`ボタンをクリックします。
![図6](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2520117/670554ee-f929-491c-b21c-97fefb2d0af3.png)

 `デモ株式会社_国内拠点`という新しいグループが作成されました。
 ![図7](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2520117/564937a0-f300-4845-bf15-ae896ec866fe.png)


 # 3. サブグループ②を作成する
`デモ株式会社`のグループ下に、新しいサブグループ`デモ株式会社_海外関連会社`を作成します。

 1. 以下の詳細情報を入力してください。
　・グループ・タイプ：`分類`（`Classification`）
　・組織（所属先）：前提条件として、ご購入いただいた際に取得した組織名を使用する必要がございます。今回は`IBM Japan`と表示されています。
　・親グループ：`デモ株式会社`
　・名前：グループ名を付けます。例：`デモ株式会社_海外関連会社`
　・説明：必要に応じて追記します。
　・レポート率(%)：100
　
 2. `保存`ボタンをクリックします。
![図8](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2520117/50ec6823-bbf5-469b-9be3-069f4d18b742.png)

 `デモ株式会社_海外関連会社`という新しいグループが作成されました。
 ![図9](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2520117/fc8c5845-748b-4c39-998f-48d076d12f3a.png)
JPEG AIのリファレンスソフトを動かしてみた

## 概要
普段はお仕事で、データの圧縮技術に関わっています。
最近流行りのAIと圧縮の関わりに興味があったため、[JPEG AI](https://jpeg.org/jpegai/index.html)というAI画像圧縮技術を勉強素材として選んで、実際に手を動かして学んでみました。

## JPEG AIとは
JPEG AIはJPEGが標準化を進めている、AIベースの画像圧縮の規格です。
AIベースの画像圧縮は、アカデミックではLearned Image Compression (LIC) と呼ばれ、検索にかけると様々な論文が出てくることからもAIによる画像処理の中でも盛んな分野である印象です。
JPEG AIのリファレンスソフトは一般に公開されており、誰でも実行することが可能です。
https://gitlab.com/wg1/jpeg-ai/jpeg-ai-reference-software

## リファレンスソフトの実行手順
ということで、リファレンスソフトを自分のPCで動かしてみました。
実行手順をメモとして記します。(2025/3/22現在の情報)

実行環境はWindows11のWSL2にインストールされたUbuntuです。今回はCPUのみの動作です。
まずは、リファレンスソフトを以下のレポジトリからダウンロードします。
```sh
git clone https://gitlab.com/wg1/jpeg-ai/jpeg-ai-reference-software.git
```
続いて、tagを選択してcheckoutします。ここでは、`CD`を選びました。他のバージョンを選んでも良いですが、自分の環境では`DIS`タグ以降のコミットでは上手く動作しませんでした。
```sh
git checkout -b CD CD
```
以降は、リファレンスソフトのREADMEを参考にDockerで環境構築をします。
```sh
make run_docker
make build_test_libs
conda activate jpeg_ai_vm
```

ここまできたら、JPEG AIを動かすことができます。
`data/test`にあるテスト画像をエンコード&デコードするコマンドがあらかじめ用意されているので、それを実行します。

```sh
make test
```

画像とビットレートを指定して、エンコード&デコードをすることももちろん可能です。
```sh
# encode
python -m src.reco.coders.encoder data/test/00001_TE_2096x1400_8bit_sRGB.png stream.bin --set_target_bpp 10 

# decode
python -m src.reco.coders.decoder stream.bin dec.png 
```

上記を実行すると、以下のようにデコード画像が生成されます。
![dec.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4042757/6419f9a6-afb4-4df2-a624-91b16620bf63.png)

## まとめ
JPEG AIのリファレンスソフトを動かしてみました。中身を勉強中なので、深堀りした内容を次の機会にまとめたいと思います。
Summary of EFW related articles

https://qiita.com/changkejun/items/844953846f3e6bed4a9d

https://qiita.com/changkejun/items/fb325ed0a9d81f3bf5f0

https://qiita.com/changkejun/items/70184f814ff52f862d91

https://qiita.com/changkejun/items/2f59403e8fa3b0f40eb7

https://qiita.com/changkejun/items/f634ae1c8040cef4cc01

https://qiita.com/changkejun/items/3accadd827594d1bccdf

https://qiita.com/changkejun/items/3f943f089d44d83296af

https://qiita.com/changkejun/items/dc976ccaaf82458c7771

https://qiita.com/changkejun/items/0cdef7d8d288f9f0a563

https://qiita.com/changkejun/items/5f6c5b234dc1322ec859

https://qiita.com/changkejun/items/97af2b8722c149f5335d

https://qiita.com/changkejun/items/d046d1804b4c996700e2

https://qiita.com/changkejun/items/26fe53af470ee1a96b05

https://qiita.com/changkejun/items/7d0999b90b0e5370f928

https://qiita.com/changkejun/items/54c3df529a1b83093790

https://qiita.com/changkejun/items/c36d3671493225ad14ce

https://qiita.com/changkejun/items/5f50cf3d3e935dd90989
GoをUbuntu（WSL）にインストールする

# はじめに
Linuxを使ってみたくなったので、WSLにもGoをインストールします。
# インストール
基本的には[公式ドキュメント](https://go.dev/doc/install)に従っていきます。

1\. 圧縮ファイルをダウンロードします。
```bash
username@MACHINENAME:~$ wget https://go.dev/dl/go1.24.1.linux-amd64.tar.gz
```
2\. 既に古いバージョンをインストールしている場合は`rm -rf /usr/local/go`で消します。
3\. 解凍します。
```bash
username@MACHINENAME:~$ tar -xzf go1.24.1.linux-amd64.tar.gz
```
公式ドキュメントでは`-C /usr/local`をつけて直接localに展開してましたが、その通りにやると下のようなエラーが出ました。
```bash
...
go/test: Cannot mkdir: No such file or directory
tar: go/test/zerosize.go: Cannot open: No such file or directory
tar: Exiting with failure status due to previous errors
```
ので、その場に展開してから移動させます。
```bash
username@MACHINENAME:~$ sudo mv go /usr/local/go
```
インストールできました。
```bash
username@MACHINENAME:~$ go version
go version go1.24.1 linux/amd64
```
配列Form部品のうち入力がない要素の取得方法

# やりたいこと
同じnameのinput要素が複数並んでいるときにvalueが設定されていないもののうち最初のものをquerySelectorで取得したい。
querySelectorAllを利用してNodeListとして取得したうえで絞り込むことはできるができればセレクタ一発でとりたい。

## パターン①　属性セレクタでvalueを指定する
### コード
セレクタ `[value=""]` もしくは `:not([value])` を指定する

### 長所
valueが指定されていないというのが直感的にわかりやすい

### 短所
valueが指定されていないかvalue=""で明示されているかのいずれかしか取れない

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="VYwGWyv" data-pen-title="Untitled" data-user="uhziyfol-the-encoder" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/uhziyfol-the-encoder/pen/VYwGWyv">
  Untitled</a> by ぼて (<a href="https://codepen.io/uhziyfol-the-encoder">@uhziyfol-the-encoder</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://public.codepenassets.com/embed/index.js"></script>

## パターン②　疑似クラス:invalidを利用する
### 方法
取得対象のinputタグにrequired属性を設定したうえで、セレクタ `:invalid` を指定する。 

### 長所
パターン①のいずれにも対応できる。

### 短所
ほかにバリデーションを指定している場合などに利用できない。

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="vEYzZNE" data-pen-title="Untitled" data-user="uhziyfol-the-encoder" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/uhziyfol-the-encoder/pen/vEYzZNE">
  Untitled</a> by ぼて (<a href="https://codepen.io/uhziyfol-the-encoder">@uhziyfol-the-encoder</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://public.codepenassets.com/embed/index.js"></script>
ああ

Sub ListFilesInFolder(folderPath As String)
    Dim fso As Variant
    Dim folder As Variant
    Dim file As Variant
    
    ' FileSystemObject を作成
    Set fso = CreateObject("Scripting.FileSystemObject")
    
    ' 指定フォルダを取得
    If fso.FolderExists(folderPath) Then
        Set folder = fso.GetFolder(folderPath)
        
        ' フォルダ内のすべてのファイルを列挙
        For Each file In folder.Files
            Print file.Path  ' ファイルのフルパスを表示
        Next
    Else
        Print "フォルダが存在しません: " & folderPath
    End If
    
    ' 解放
    Set file = Nothing
    Set folder = Nothing
    Set fso = Nothing
End Sub
【Python超基礎】実行速度遅くない?と言われる前にimutableを理解してコードレビューを突破しよう

## ✅ 結論

Pythonでは、`int` や `str` などの「**イミュータブル（変更不可）なオブジェクト**」を繰り返し書き換えると、**メモリがムダに使われることがあります**。

---

## 📘 例題：文字列を1文字ずつ追加したい

### ❌ よくある書き方（実は非効率）

```python
s = ''
for i in range(1000):
    s += str(i)
```

一見問題なさそうですが、実は毎回 `s` に新しい文字列が作られていて、**毎ループで新しいオブジェクトが生成されます**。

---

## 🧠 どうして？

`str` は **immutable（変更不可）** な型。  
つまり、`+=` などで変更しているように見えても、実際は「新しい文字列を作って `s` を上書き」しているだけ！

### 💾 そもそも変数がメモリにどう保存されるかを知る

Python の変数は「**オブジェクトへのラベル（参照）**」です。  
つまり、変数 `a` は値そのものではなく、**値が入っているメモリの場所（オブジェクト）を指している**感じです。

変数a  ─────▶ メモリ

メモリに 'hello'などのオブジェクトが格納されることで、変数aは`hello`なんだな、と認識してくれる訳です。


### メモリの場所を除くとこんな感じ(メモリアドレス)

```python
# idメソッドで変数が格納されているメモリがわかります。
a = 'X'       → id(a) = 1001
a += 'Y'      → id(a) = 1050  ← 新しいオブジェクト！
a += 'Z'      → id(a) = 1103  ← また新しい！
```
---

## ✅ 改善案：リスト＋joinで効率化

```python
l = []
for i in range(1000):
    l.append(str(i))

s = ''.join(l)
```
### メモリの場所を除くとこんな感じ(メモリアドレス)

この方法では、まずすべての文字列（例：'0', '1', '2', ...）を **リスト `l` に追加**していきます。

```python
l = []           → id(l) = 3001
l.append('0')    → id(l) = 3001
l.append('1')    → id(l) = 3001
...              → id(l) = 3001  # ← ずっと同じ！
```
これなら、変数lはずっと同じオブジェクト（メモリアドレス）を持ちます。
そうすると文字列結合の時と違いオブジェクトを毎回生成しないので結果実行速度が速くなります。

## 補足

- `join` はメモリを抱えますが、同じオブジェクトを利用することで実行速度は速い
- `str +=` はガベージコレクションによりメモリ消費は抑えられるものの、毎回新しいオブジェクトが生成されるため実行速度が遅くなる

---

## 📚 immutable な主な型

| 型 | 変更可能？ |
|----|-------------|
| `int` | ❌ |
| `float` | ❌ |
| `str` | ❌ |
| `tuple` | ❌ |
| `bool` | ❌ |

---

## ✨まとめ

- Pythonの `str`, `int` などは **immutable（変更不可）**
- `+=` の繰り返しは **新しいオブジェクトを作り続けてる**
- 大量の繰り返し処理ではミュータブルである `list` などを使ってまとめて操作しよう！

---
Agentforceが有効なDeveloperEdition環境へデモアプリ「Coral Cloud」を設定する

前回は、Salesforce Agentforceの環境構築手順と、Coral Cloud Resortsデモ環境での設定を紹介しました。

https://qiita.com/Mijinko-kun/items/081c3062a64a931b5c39

今回は、開発環境から、コマンドを実行して、データを設定していきます。


## Coral Cloudとは

https://developer.salesforce.com/blogs/2024/09/introducing-the-coral-cloud-resorts-sample-app

このアプリは、AgentforceとData Cloudを使用したSalesforceの組織で実際のコードとベストプラクティスを体験できるサイトとデータとなります。


## sfコマンドの実行

sfコマンドをアップデートします。
```
$ sf update
```

最新版にしておきます。
(私はNodeもついでにバージョンアップしておきます。)


```bash
#リポジトリの取得
$ git clone https://github.com/trailheadapps/coral-cloud
$ cd coral-cloud

# ログイン
sf org login web -s -a coral-cloud
```

## メタデータのデプロイ

cc-base-appフォルダのメタデータをデプロイします。

```bash
$ sf project deploy start -d cc-base-app
```

これで動くかと思ったら、
```
 ─────────────── Deploying Metadata ───────────────

 Deploying v63.0 metadata to xxx@agentforce.com using the v63.0 SOAP API.

 ✔ Preparing 248ms
 ⣽ Waiting for the org to respond 13.77s
 ◼ Deploying Metadata
 ◼ Running Tests
 ◼ Updating Source Tracking
 ◼ Done

 Status: Pending
 Deploy ID: 0AfgL000001Cxxxxxx
 Target Org: xxx@agentforce.com
 Deploy URL:...
```
という`Waiting for the org to respond`メッセージで停止してしまいます。
30分待ちましたが、`Error (ClientTimeoutError)`が出てそのままでした。


[設定]-[リリース状況]で確認しましたが、[待機中のリリース]のまま停止してしまいます。



API使用量も、最初は増えますが、しばらくすると止まっているようです。

VS Codeでも、iTermでも結果は同じでした。

## メタデータのデプロイエラー

GitHubのIssueで、同じエラーの方がいます。

https://github.com/trailheadapps/coral-cloud/issues/97


このページが紹介されています。パッケージで再トライしてみます。


### パッケージで再トライ

https://developer.salesforce.com/agentforce-workshop/getting-started/self-service-workshop-setup#install-and-set-up-the-coral-cloud-base-package

ログインしてから
`https://xxx.develop.lightning.force.com//packaging/installPackage.apexp?p0=04tWx0000001mDtIAI`
にアクセスします。

管理者のみにインストールします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2716146/ca2798b6-b9ef-417b-99fc-dbd5120154b1.png)


承認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2716146/bf9d3831-bdf0-4501-8a2e-b7ef85e5274b.png)


メールが届くのを待ちます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2716146/d2b78b06-9ca5-4134-bc66-1ecd376a6953.png)


~~残念ながらメールは届きませんでした。。。~~


~~設定の[インストール済みパッケージ]を開いても、表示されませんので、`Einstein for Sales`権限がないため、セットアップはできないと考えたほうが良さそうです。~~

**14時間くらいしてから、インストールが完了したというメールが届きました！**

もしかしたら、sfコマンドからデプロイした場合も半日ほどおいておけば成功したのかもしれません..?

### ログインして確認

ログインすると、Coral Cloud Resortsというアプリが利用できました。



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2716146/959f0819-6d54-47ab-84bc-70229eb9cd54.png)

パッケージもインストールされていました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2716146/286ad079-9455-434e-b53a-1abd09e422c7.png)



↓次回は、Coral Cloudについて確認したいと思います。



https://qiita.com/Mijinko-kun/items/32c58cbc2809c6b6eac7
個人的備忘録：いつでも即答できるように、Linuxコマンド20選を簡潔にまとめてみた

## はじめに

Linuxを使い始めたとき、「どのコマンドを覚えればいいのか分からない」と感じることがありました。

:::note info
**本記事では、日常的に使うことの多いLinuxの基本コマンドを20個に絞って簡潔に整理しています。**
:::

初心者から中級者まで、作業の効率化や理解の整理に役立てていただければ幸いです。

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

Linuxを学び始めた頃、ターミナル操作中に「このコマンド、どう書くんだっけ？」と手が止まってしまい、作業効率が落ちることがよくありました。

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

必要なときにすぐ確認できるよう、自分用の備忘録としてまとめようと思ったのがきっかけです。

## Linuxコマンド20選：簡潔まとめ（個人用備忘録）

| コマンド | 説明 |
|----------|------|
| `ls` | ディレクトリの内容を表示 |
| `cd` | ディレクトリの移動 |
| `pwd` | 現在のディレクトリを表示 |
| `mkdir` | 新しいディレクトリを作成 |
| `rm` | ファイルやディレクトリを削除 |
| `cp` | ファイルをコピーする |
| `mv` | ファイルを移動またはリネームする |
| `touch` | 空のファイルを作成 |
| `cat` | ファイルの中身を表示 |
| `less` | 長いファイルの中身をページ送りで表示 |
| `echo` | テキストや変数を表示 |
| `man` | コマンドのマニュアルを表示 |
| `chmod` | パーミッションを変更する |
| `chown` | 所有者を変更する |
| `ps` | 実行中のプロセスを表示 |
| `kill` | プロセスを終了させる |
| `grep` | 特定の文字列を検索する |
| `find` | ファイルやディレクトリを検索する |
| `df` | ディスク使用状況を表示する |
| `top` | リアルタイムでプロセスの状況を表示する |

---

## まとめ

Linuxの基本コマンドは、作業効率を大きく左右する重要なスキルです。今回紹介した20個は、どれも実務でよく使うものばかりなので、最初に覚えておくと安心です。

***毎日の業務や学習の中で、何度も触れていくことで自然に身についていきます。***

まずは「使ってみる」ことから始め、必要に応じてオプションや応用的な使い方を調べていくのがおすすめです！
２

Function NormalizePath(path As String) As String
    Dim fs As Object
    Set fs = CreateObject("Scripting.FileSystemObject")
    If fs.FileExists(path) Then
        NormalizePath = fs.GetAbsolutePathName(path)
    Else
        NormalizePath = ""
    End If
End Function

Sub TestKill()
    Dim filePath As String
    filePath = "C:\Users\username\Desktop\データ.txt"
    
    filePath = NormalizePath(filePath) ' 正規化して取得
    If filePath <> "" Then
        Kill filePath
        MsgBox "削除成功: " & filePath
    Else
        MsgBox "削除失敗: パスが見つからない"
    End If
End Sub
【データ収集ルール初級者向け】私が良く使うTransformKQL実装のパターン

### 初めに
TransformKQLについて簡潔にまとまっているドキュメントが少ないので、ここに簡単に残しておきます。始めてAzureでデータ収集ルール（DCR）の構築をする方等の参考になれば幸いです。

## 目次
- [基本の構成パターン](#基本の構成パターン)
  - [parse句](#parse句)
  - [where句](#where句)
  - [project句](#project句)

## 基本の構成パターン
taransformKQLにおける基本の構成パターンはこんな感じが使いやすいです。
```KQL:基本の構成
source
| parse RawData with <ここに分割ルールを記載>
| where <ここに収集したい条件を記載>
| project TimeGenerated, RawData, Computer, FilePath, <その他列>
```

### parse
ここで、文字列の分割ルールを記載していきます。
詳しくは以下参考ドキュメントです。
+ [MS公式 | parse 演算子](https://learn.microsoft.com/ja-jp/kusto/query/parse-operator?view=microsoft-fabric)

以下のように公式ドキュメントに記載のある通り、以下のように記載することで正規表現を使用することもできます。
```KQL:parse句での正規表現
parse kind=regex　RawData with <正規表現>
```

しかし、私はtransformKQLで使用するなら「simple」一択だと思っています。
parseを利用する場合はLogAnalyticsへ格納するログフォーマットの型が大方決まっています。そのため、最も厳密に制御するsimpleを使用するのが良いです。
公式ドキュメント内にサンプルがいくつかあるので、サンプルをみて勉強しましょう。

### where句
Alertだけ格納したい場合や特定のEventIDのみ格納したい時に使えます。SQLのwhere句と用途は変わらないので、詳しい説明は割愛します。
詳しくは以下参考ドキュメントです。
+ [MS公式 | where 演算子](https://learn.microsoft.com/ja-jp/kusto/query/where-operator?view=microsoft-fabric)

where句の強みは検索列として「*」が使用できる点と「contains」や「has」といったあいまいな表現での検索ができます。例えば以下のように記載しておくだけで、メッセージのどこかにErrorという文言があると取得するように制御ができます。

```KQL:where句
source
| where * contains "ERROR"
```

### project句
これは私の理解ですが、project句はSQLでいうSELECT句と近いものだと理解しています。
ただし、文末に入れることが多い点はSELECT句との違いでです。
project句内に記載する列名は格納先のLog Analytics Workspaceの列名と合わせましょう。
あと、parse句で分けた列を合算いて計算して格納したい場合にはこの中で数式を記載できます。
こんな感じです。

```KQL:project句
source
| parse RawData with EventID "," countA "," countB
| project EventID, Totalcount = countA + countB 
```

一応、こちらも公式ドキュメントを載せておきます。
+ [MS公式 | project 演算子](https://learn.microsoft.com/ja-jp/kusto/query/project-operator?view=microsoft-fabric)

## 最後に
私はこのパターンが基本パターンだと考えていますが、他にもsplitを使ってcsvを上手く切り分けたりextend句を利用して可変的なログを取り込んだりする設計もできます。
皆さんでいろいろと試してみて下さい。
GCPワークベンチインスタンスのターミナルが見にくいのを直す方法(フォントの変更方法)

## ターミナルが見にくい問題

GCPのVertex AIで使えるワークベンチインスタンスにおいて、ターミナルがめちゃめちゃ見にくくてびっくりしました。普通に作業に支障があるレベル。美しさとか感性とかそういうレベルではない。

![CleanShot 2025-03-27 at 18.07.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636677/4fdb1ddc-69eb-4305-bc8d-188dbb016676.png)

## 解決方法

このフォントはブラウザが設定するデフォルト等幅フォントが使われるようになっています。
なので普通にブラウザの設定から等幅フォントを見やすいやつに変更すれば見やすくなります。

↓これはOsakaフォント

![CleanShot 2025-03-27 at 18.15.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636677/0ea8f19c-2c28-427c-bdb2-265bba95c2d5.png)
(BizRobo!)Chromiumで開いたWebページをDSで開きなおして値を抽出する

# はじめに
やることはタイトルのままです。

BizRobo!のDS内蔵ブラウザであるWebkitでは開けないWebページは、DAエディタ側で編集する内蔵ブラウザであるChromiumや直接デスクトップ上のブラウザを起動して操作することになりますが、DS内のエディターとは操作の勝手が異なるので慣れていない方には難しい場合もあります。
私もDS内でできる処理はなるべくDS内で行うようにしています。

そこで、操作したいページ上での操作が情報抽出だけであれば、DA上で行わず、DSで行ってしまおうというのが今回の記事です。

今回、BizRobo!は記事執筆時点で最新のv11.5.0.5を使用します。
v11.5に慣れる意味でもやってみます。

# 使用するWebページについて
全く無関係のサイトから抽出するのもあれなので、
今回はオープン社の方が紹介されていた以下練習用ページを使わせていただきます。

表示されているカードの出典をループで集計する
https://codepen.io/glrchallenge/full/abQjaed

参考記事：
https://qiita.com/ParakeetOnTheHead/items/058ee1be6e079a503bf2

こちらのページのお題は「表示されているカードの出典別の写真数を集計してテキストボックスに数値を入力してください」となっています。
想定としてはDAステップ内で完結させる前提なのでしょうけど、敢えてDS内にリストを持ってきてから集計してみようと思います。
集計自体はどうやってやろうが結果は同じですからね。

# DSでの値取得方法
こちらの課題をDSで実施する場合の処理の流れとしては、以下のようになります。
他の方法もある気がしますが、ややこしくなりそうなので一旦忘れておきます。
この課題をDSで実施する場合の処理の流れは以下の通りです。

1. **Chromiumで目的のWebページを開く**
2. **値を取得したい箇所のHTMLを変数に格納**
3. **取得した変数値をリターンステップでDSに返す**
4. **DS内でHTMLを開く**
5. **ループ処理で値を取得する**
6. **どの出典かを条件判定で確認**
7. **判定結果によって分岐し、それぞれの写真数をインクリメントする**

今回のお題はあくまでChromimで開いたページの値をDSで抽出することなので、それ以外の部分は省きます。
取り上げていない箇所が分からない場合、適宜ヘルプを確認するかeラーニング等で学習ください。

## 値を取得したい箇所のHTMLを変数に取得
Webページはすでに開いている前提で進めます。
今回、各カード中の値を抽出するお題なので、全てのカードから値を抽出できるように全カードが入っているタグの箇所をすべて取得しておく必要があります。
赤枠の部分ですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2736479/e03cecae-9211-4edd-83e7-f4a4f8dce775.png)

この部分が入るタグを選択し…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2736479/7c8b45e7-21c2-4161-a800-e4085c02515e.png)


右クリックメニューから
`[XML文字列としてツリーを次へ抽出] ⇒ [拡張属性を次へ含める] or [拡張属性を次から除外]`
を選択します。
拡張属性はどちらでも構いません。他のページを扱う場合は、適宜選択してください。
変数を事前に作成していない場合は[変数を作成]から作成してください。
今回は事前にHTMLという名前のテキスト変数を作成しているので既存変数を選択しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2736479/de450073-5fde-43b8-93d9-20b1edbc4e57.png)

抽出が成功したらリターンステップで先ほど抽出した変数を選択してDSに値を返せるようにします。

## DS内でHTMLを開く
DSに値を戻せたら、そのHTMLをもとにHTMLページをWebkitブラウザで開きます。
DSでは、HTMLをもとにページを作成する機能があるのでそちらを使用します。

新しいアクションステップを追加し、以下のように[ページ生成]を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2736479/471b56c9-f72b-4e0c-849f-d1f9e5a288cf.png)

アクションが選択できたら、コンテンツを変数に切り替え、DSで受け取ったHTMLが入っている変数を選択します。
ページURLは今回適当ですが、任意で入れられます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2736479/8f0701dd-9ee8-4347-95ca-2bef8d5e0094.png)

ステップを進めると、このようにDS内のブラウザで表示できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2736479/55b35f39-8603-4e6f-af38-085333c2abbd.png)

あとは[タグ繰り返し]を使ってカード毎のループ処理をつくり、それぞれの出展の数を数えていけばできあがりです。

# さいごに

最近のバージョンはそうでもないのですが、昔のBizRobo!バージョンではDAステップ内のエディタが不親切だったり扱いにくかったりがあり、動作安定性も含めてDS内でどうにかしたいと試行錯誤していたことがありました。
その中で見つけた方法の一つが今回紹介した方法です。

最近はDAのエディタも親切になり、動作安定性も含めて扱いやすくなりましたので、このような回りくどいことをする必要もないかもしれません。
ツリーの変更停止などのガードチョイスを入れた際に自動的にタイムアウトも入るようになったのとか地味に嬉しいポイントです。

今回BizRobo!v11.5を触ってみましたが、DAロボットだけで独立して動かせるようになったことで、テスト値を入れておけばDSからInput値を入れることなく開発やテスト実行ができるようになり、親切になったなと思います。
慣れるまではあれ？ってなるかもしれませんが、何事もとにかく触ってみるしかありません。
Fabricのデータベース なにがなんだかわからない人へ【レイクハウス、データウェアハウス、データレイク】

# はじめに

最近、Fabriｃについて勉強してますが、少し難しいと思ってたことをメモがてら公開します！

Microsoft Fabric は、データ統合、分析、BI（ビジネスインテリジェンス）を一元的に実現するプラットフォームです。

今回は自分が当初よくわからなかった Fabric における  
**レイクハウス**、**データウェアハウス**、**データレイク**  
の違いについて、自分なりの解釈で説明します。

:::note
間違っていたらコメントで教えていただけるとありがたいです！
:::

---

## Microsoft Fabric の全体像

Fabric は、データの取り込みから保存、変換、分析、可視化までをひとまとめにできる、かなり便利なプラットフォームです。

その中でも、よく登場する3つの「データ保存リソース」について紹介します。

---

##  データウェアハウス（DWH）

一般的なRDB（リレーショナルデータベース）よりも、**データを効率よく保存・集計・検索**することに特化したDBというイメージです。

- 伝統的なRDBと似ていますが、**列指向ストレージ**を採用していて、たとえば「日付」などの同じ値が続く列を圧縮することで効率的に保存できます。
- **定型レポート**や**業務データの分析**に強く、安定して高速なクエリが可能。

:::tip
データが「整っている」「構造化されている」前提の世界。
:::

---

##  データレイク

OneDriveやSharePointのような「ファイル置き場」に近いイメージです。

- **構造化、半構造化、非構造化**など、あらゆる形式のデータをまとめて保存可能。
- 基本的には「とりあえず全部突っ込んでおけ！」というスタンスで、**あとから整形・加工して使う**ことが前提です。

:::note
Azure の Data Lake Storage Gen2 や Blob Storage に保存されているファイルと同じような感じで、分析ツールから後で加工・参照する流れです。
:::

---

## レイクハウス（Lakehouse）

レイクハウスは、**データウェアハウスとデータレイクの“いいとこどり”を狙ったハイブリッドな仕組み**です。

- 見た目はテーブルっぽく扱えるけど、実体は **Parquet 形式のファイル**（列指向の圧縮ファイル）です。
- **Delta（データ管理のフレームワーク）**を使って、Parquetファイルをテーブルのように操作できるようにしています。
- 実行エンジンとしては **Spark** を使って、SQLみたいにクエリを投げて集計が可能。

:::tip
「保存先はデータレイクだけど、使い方はDWHっぽい」というのがレイクハウスです。  
データの整形やクレンジングも同じ環境内でできて便利。
:::

Fabric ではこのレイクハウスがかなり推されていて、**全部これ一本でできちゃう！**という理想に近い存在です。

---

## 🔍 ざっくり比較表

| コンポーネント       | 保存できるデータの種類           | 主な利用目的                               | 特徴                                 |
| ------------------- | --------------------------- | --------------------------------------- | ----------------------------------- |
| **データウェアハウス**   | 主に構造化データ               | 定型レポート作成や業務データ分析                      | 高速なクエリ、安定性、整合性の確保           |
| **データレイク**       | 半構造化、非構造化データ     | 大量データの低コスト保存と後処理                 | 柔軟なデータ取り込み、拡張性、低コスト             |
| **レイクハウス**       | 構造化／非構造化混在            | 柔軟なデータ解析と高速クエリ                     | 柔軟性と管理機能を両立、ハイブリッド設計            |

---

## ✅ まとめ

- **データウェアハウス** → 構造化された業務データをガチッと管理・分析したいときに。
- **データレイク** → いろんな形式のデータをまとめて保存しておきたいときに。
- **レイクハウス** → 両方の良さをバランスよく使いたいときに。Fabricでは特にこれが中心！

:::tip
**「とりあえず何から学ぶべき？」という人には、Fabricのストレージではまずレイクハウスの理解がおすすめです！**
:::

---

## 📝 補足

これは Fabric 初心者の自分が、手探りで調べて理解した内容をまとめたものです。  
正確さに欠ける部分があるかもしれませんので、ぜひコメントなどでご指摘いただけると嬉しいです！

---

 最後まで読んでいただきありがとうございました！
DynamoDB キャパシティユニット

# DynamoDB キャパシティユニット

## キャパシティユニットとは
1秒あたりにN回の読み書きできる容量
- WCU(ライトキャパシティユニット)は書き込みできる量
- RCU(リードキャパシティユニット)は読み取りできる量


以下、1キャパシティユニットのできること

| 読み書き | 内容 |
| ---- | ---- |
| 読み込み (強力な整合性) | 1秒に1回 (4KBまでは) |
| 読み込み (結果整合性) | 1秒に2回 (4KBまでは) |
| 書き込み | 1秒に1回 (1KBまでは) |

**結果整合性は、楽観ロック→最新状態が担保されていない<br>
強い整合性は、悲観ロック→最新状態が担保されている<br>**


キャパシティユニットは1テーブルごとに設定する。

例えば、5ユニットの書き込みキャパシティ/読み込みキャパシティをテーブルに設定すると、
- 1秒に5KBまでの書き込み (1KB × 5回)
- 1秒に20KBまでの強力な整合性読み込み (4KB × 5回)
- 1秒に40KBまでの結果整合性読み込み (4KB × 10回)

仮に1秒間に1.5KBのデータを書き込む場合はキャパシティユニットが2必要


## キャパシティモード

キャパシティモードには2種類あり、それぞれ

- オンデマンド
- プロビジョンド

どちらもキャパシティユニットの容量の設定方法である。

### オンデマンド
オートスケーリング

オンデマンドは最初にキャパシティユニットの量を決めずに、<br>
読み書きが増えればそれに応じてキャパシティユニットの量を増減させることができる。

### <span style="color:red;">プロビジョンド</span>
オンデマンドがオートスケーリングするのに対してプロビジョンドは最初に容量を決めます。<br>
プロビジョンドではリザーブドキャパシティという長期間分を前払いをして安くなるというオプションがあります。

## キャパシティユニットの消費パターン

### 読み込みリクエストの場合
整合性レベルが上がるたび、ユニット数が倍になっていくイメージ
| リクエストの種類 | 基準サイズ | 必要ユニット数 |
| --- | --- | --- |
| 結果整合性 | 4KB以下 | 0.5 RCU |
| 強力な整合性 | 4KB以下 | 1 RCU |
| トランザクション | 4KB以下 | 2 RCU |

### 書き込みリクエストの場合
| リクエストの種類 | 基準サイズ | 必要ユニット数 |
| --- | --- | --- |
| 通常 | 1KB以下  | 1 WCU |
| トランザクション | 1KB以下 | 2 WCU |

## CloudWatch 測定対象の自動作成
プロビジョンドのオートスケーリングを有効にすると自動でメトリクスが作成されるみたいです。
くわしくないので、触れる程度。
すべての "行の長さと値が不定" な 2 次元配列の出力



Paizaの問題を解いてたら、最初のコードで全部 1 から順に並んじゃって大混乱。よく考えたら `index` の管理をミスってた…。`Iterator` や `slice()` を使えばスッキリ解決するから、複数の解法を紹介するよ！

## 問題の概要

**入力:**

- 1行目：数列の長さ `N` と行グループの数 `M`
- 2行目：`N` 個の数列 `A`
- 3行目：各グループのサイズ `B`

**出力:**

- `M` 個のグループごとに `A` の一部を出力（各行の末尾にはスペースなし）


https://paiza.jp/works/mondai/stdout_primer/stdout_primer__variable_array_boss


### 入力例

```
5 2
1 2 3 4 5
2 3
```

### 出力例

```
1 2
3 4 5
```

## <br>NG例（僕の最初の失敗）

```javascript
for (let i = 0; i < M; i++){
    for(let k = 0; k < row[i]; k++){
        if(k+1 === row[i]){
            process.stdout.write(nums[k] + "\n");
        }else {
            process.stdout.write(nums[k] + " ");
        }
    }
}
```

**ミス:**

- `nums[k]` を毎回 0 から参照してるせいで、出力が全部 1 から始まる…。

## <br>OK例（解決法）

### 解法1：Iterator を使う

```javascript
const [N, M] = lines[0].split(" ").map(Number);
const nums = lines[1].split(" ").map(Number);
const row = lines[2].split(" ").map(Number);

const iter = nums.values();
for (let i = 0; i < M; i++){
    for(let j = 0; j < row[i]; j++){
        if(j + 1 === row[i]){
            process.stdout.write(iter.next().value + "\n");
        }else{
            process.stdout.write(iter.next().value + " ");
        }
    }
}
```

**ポイント:**

- `nums.values()` で `Iterator` を作成
- `iter.next().value` を使って値を順番に取得

### <br>解法2：index で管理

```javascript
let index = 0;
for (let i = 0; i < M; i++) {
    let output = [];
    for (let j = 0; j < row[i]; j++) {
        output.push(nums[index++]);
    }
    console.log(output.join(" "));
}
```

**ポイント:**

1. `output` 配列を用意し、`row[i]` の個数分だけ値を取得
2. `join(" ")` でスペース区切りの文字列に変換し、一括で `console.log`
3. `index` で `nums` のインデックスを管理

### <br>解法3：`slice()` を使う

```javascript
const [N, M] = lines[0].split(" ").map(Number);
const A = lines[1].split(" ").map(Number);
const B = lines[2].split(" ").map(Number);

let begin = 0;
for (let i = 0; i < M; i++) {
    let end = begin + B[i];
    console.log(A.slice(begin, end).join(" "));
    begin = end;
}
```

**解説:**

1. `N, M` を取得（`N`: 数列の長さ, `M`: グループの数）
2. `A` を数列として取得（例: `[1, 2, 3, 4, 5]`）
3. `B` をグループのサイズとして取得（例: `[2, 3]`）
4. `begin` を 0 に初期化
5. `end = begin + B[i]` を計算し、適切な範囲を取得 (`slice(begin, end)`)。
6. `begin = end` に更新して、次のグループの処理へ進む。

### 処理の流れの例：

- `begin = 0, end = 2` → `A[0]` から `A[1]` を出力 → `1 2`
- `begin = 2, end = 5` → `A[2]` から `A[4]` を出力 → `3 4 5`

### ポイント

- `begin` はグループの開始位置、 `end` はグループの終了位置を表す。
- `slice(begin, end)` を使うことで簡潔に部分配列を取得できる。

## まとめ

✅ `Iterator` を使うとスッキリ解決！ 
✅ `index` を管理すればシンプルに書ける！ 
✅ `slice()` を使うと直感的！


<br>[僕の失敗談と解決話！](https://paizabeginner.wordpress.com/2025/03/27/paiza%e3%81%a7%e5%9f%ba%e6%9c%ac%e3%83%9e%e3%82%b9%e3%82%bf%e3%83%bc%ef%bc%9a%e3%81%99%e3%81%b9%e3%81%a6%e3%81%ae%e8%a1%8c%e3%81%ae%e9%95%b7%e3%81%95%e3%81%a8%e5%80%a4%e3%81%8c%e4%b8%8d%e5%ae%9a/)
Qdev君をインストールしてみた

はじめて投稿します。初心者エンジニアの稲穂です。
Q君がいてくれたらコードが打てなくてもアプリが出来ちゃうと聞いてやってみたよ。
参考は昨日2025/03/26開催のAWS Expert Online for JawsUG Amazon Q Developer forCLIです。

↓実際にやったAWSの山口さんのハンズオン動画
https://youtube.com/live/uAlxT_sz1Dk

Ioc nightのイメージでテラフォーム君はQでいけるのかと思ってたけど、なんとCLIも自然言語で行けるなんて...!
今回はQくんにお願いしてアンケートフォームをPythonで作ります。
今QDeveloper君はMacやLinuxで操作可能です。無料で出来る枠があり、超えちゃうとストップかかるようになってるので、初心者さんも安心でQくんお試し出来て嬉しいです。
![1000002796.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4046203/f129cfe2-65c6-48b9-ab11-3767dbba346d.jpeg)


まず使ったことがない自分はBuilderIDの作成から↓　AWSアカウントがある人は権限つけてたらここでログインするだけで操作がいけますよ。

https://community.aws/builderid?trk=dccd318a-a012-40c6-bffb-bd0a6216646d&sc_channel=el

あとPC入れ替えたばかりの新米はHomebrewというパッケージマネージャとNode.jsも入れました。
![1000002794.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4046203/eadfa83a-0813-4872-96c0-21295cea7b9e.jpeg)
![1000002806.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4046203/f21faced-bcd3-40cd-8ae6-6abb89a81470.jpeg)


ページに書いてるコマンドでインストール出来ない人はFinder/ターミナル/情報を見る/Rossetaを使用して開くをチェックするといけるよ。
![1000002804.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4046203/0f8d7bee-ca44-4ef2-8a71-c18e73588505.jpeg)


コンソールでいれたあとにQ君を起動して
山口さんのプロンプトを実行
![1000002798.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4046203/3cecda30-6c95-4d84-99eb-99c3140e39ac.jpeg)

どんどん出来ていきます。
認証システムいるか聞かれたのでいるよーと選択

![1000002802.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4046203/8cdea80b-4d65-4d75-bf5f-a29ee3396a7a.jpeg)

おっ？
![1000002807.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4046203/6943d2f8-0e96-4e99-a445-7147c681dbc7.jpeg)
![1000002809.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4046203/a1e1d4e4-9334-44b9-826d-4d2eebfc1c7c.jpeg)
出来ましたー!

付け焼き刃でもどうにかQ君のお陰で.アンケートアプリができたよ。

また初心者向けハンズオン楽しみだなぁ。
これにどんどんビギナーJawsのアッキーさんやIoc nightのGOTOさんがされてたような権限付与や構築が重なるとガンガンイベントに合わせて経費削減やシステム改変を提案できるようになるのかしら

AWS様、山口様、Jawsの皆様　ご教授ありがとうございました。
Roocode + DeepSeek R1 FreeでUnity MCPを気軽に試す


Unity MCPを、コストを抑えて利用する方法を紹介します。この記事では無料で利用できるDeepSeek R1 FreeモデルをRoocodeとUnity MCPと連携させる方法を解説します。

## 必要なもの
- VSCode
- Unity (Unity MCPプラグインがインストール済み)
- Node.js (インストール済みであること)
- OpenRouterアカウント

## セットアップ手順

### 1. Roo Codeのインストール

1. VSCodeを開き、拡張機能マーケットプレイスから「Roo Code」を検索してインストールします。

### 2. OpenRouterのセットアップ

1. [OpenRouter](https://openrouter.ai/)にアクセスしてアカウントを作成します。
2. ダッシュボードの「Keys」画面に移動し、「Create Key」ボタンを押してAPIキーを発行します。
3. **重要**: 予期せぬ課金を防ぐため、「Credit limit」に上限額を設定しておきましょう（例: 5ドル程度）。これにより、誤って有料モデルを使用した場合でも被害を最小限に抑えられます。

### 3. Roo Codeの設定

1. VSCodeでRoo Code設定画面を開きます。
2. 設定画面からAPIプロバイダの選択肢から「OpenRouter」を選びます。
3. 先ほど発行したOpenRouterのAPIキーを入力します。
4. モデル選択から「deepseek/deepseek-r1:free」を選択します。

### 4. MCPサーバーの設定

1. Roo Codeのサイドバーにあるサーバーアイコンをクリックして、MCPサーバー設定を開きます。
2. サーバーを有効にし、「MCP設定を編集」をクリックします。
3. 以下のパスにある設定ファイルが開かれます：
   ```
   C:\Users\ユーザーネーム\AppData\Roaming\Code\User\globalStorage\rooveterinaryinc.roo-cline\settings\mcp_settings.json
   ```
4. 設定ファイルに以下の内容を入力します：

```json
{
  "mcpServers": {
    "unity-mcp-local": {
      "command": "C:/Program Files/nodejs/node.exe",
      "args": [
        "サーバーを置いた場所/UnityMCP-main/unity-mcp-server/build/index.js",
        "--port",
        "8080",
        "--project-path",
        "${workspaceFolder}"
      ],
      "env": {},
      "disabled": false,
      "alwaysAllow": ["*"]
    }
  }
}
```

※ `サーバーを置いた場所` は実際のUnityMCPサーバーファイルのパスに置き換えてください。

### 5. Unity側の設定と接続確認

1. Unityを開き、UnityMCPプラグインが有効になっていることを確認します。
2. 「Window」メニューから「UnityMCPDebug」ウィンドウを開きます。
3. Roo Codeの「unity-mcp-local」サーバーが緑色になっていれば、接続成功です。

## 完了！

これでUnityMCPを使ってなんかやってみてって指示すると動いてくれるはずです。
【Vuetify3】セレクトボックスに選択肢がないときの表示文言を変更したい

## はじめに

Vuetify3で、セレクトボックスに表示する選択肢が存在しないとき、デフォルトでは"No data available"と表示されます。
この表示文言の変更方法を調べました。

## 方法1. `no-data-text`プロパティを使用

個別のコンポーネントのみ変更したい場合はこちらがおすすめです。
選択肢がない場合、`no-data-text`プロパティに指定した文言が表示されます。

```vuejs
<v-select
  :items="[]"
  label="選択してください"
  no-data-text="データがありません"
></v-select>
```

https://vuetifyjs.com/en/api/v-select/#props-no-data-text

## 方法2. vuetifyのローカライズ設定を変更

アプリ全体で変更したい場合はこちらがおすすめです。

`main.js`または`vuetify.ts`で以下の通り設定します。
アプリ内のすべてのセレクトボックスで選択肢がない場合、`noDataText`プロパティに設定した文言が表示されます。

```javascript
import { createVuetify } from 'vuetify'

const vuetify = createVuetify({
  locale: {
    messages: {
      en: {
        noDataText: 'データがありません',
      },
    },
  },
})

export default vuetify
```

https://vuetifyjs.com/en/features/internationalization/#creating-a-custom-locale

## おわりに

vuetifyのローカライズ設定を変更してアプリ全体のメッセージを変える方法は今回初めて知り、勉強になりました。
【駆け出し】新人エンジニアへ捧げる言葉

https://x.com/satan_engineer/status/1903692403745472943

この記事を3/26に書いていますが、あと数日でエンジニアデビューされる方がたくさんいると思います。特に、未経験でIT業界に足を踏み入れてしまった方は「自分みたいな未経験がやっていけるだろうか」と不安を感じていることでしょう。

私自身、**未経験かつC言語の単位を落として留年しかけたような奴**ですが、今ではエンジニアとして人並み以上には稼ぐことができています。

今回はそんな駆け出しエンジニアに向けて、私が1年目に実際に行っていた内容をベースにアドバイスをさせていただきます。

個人的に、後輩や年下に一方的にあれこれ助言を口にするのは老害っぽくて好きではないので、独り言程度に流し読みしてもらって結構です。


## 1.新人は最初の1年で核となるスキルを身につける
最初の1年で「○○さんといえば、コレだよね」と言われる、あなたの代名詞となるようなスキルを身につけましょう。

2年目以降は、この核となるスキルを軸足にして付随する技術領域を身につけていくので、スキルが何かによって、あなたのエンジニア人生が大きく変わります。

また、核となるスキルについてはPython、Go、TypeScriptのような大きな枠でも、AWS LamdaやAzure Functionsといったクラウドサービスの特定のリソースのような狭い領域でも構いません。

例えば、私を例にとると一年目はMicrosoft Azureでのインフラ開発PJTがスタートでした。その中でも、Azure Virtual Desktop（AVD）というサービスを扱う案件に参画しました。

AVDはMicrosoft Azureで展開されるVDIサービスです。コロナ禍の影響で、リモートワークが最も盛り上がっていた時期でした。

https://learn.microsoft.com/ja-jp/azure/virtual-desktop/overview

```
「案件数はめちゃくちゃ多い、けど人手が足りなさすぎて対応できる人が少ない。
なら、私ができるようになればAVDができる人と認知されるのでは…？」
```

こう考えた私は、AVDの案件に片っ端から参画しました。私の予想は的中し「サタンさんならAVDできるから、この案件も大丈夫だよね？」と上司や先輩から認知されるようになりました。

## 2. ロールモデルとなる先輩エンジニアを見つける

**「この人みたいになりたい！！」**

そう思える、理想の先輩エンジニアを、あなたが所属する部署や現場で見つけましょう。見つけ方は「あなた自身の直観に従う」ことです。「あっ、この人！！！」とピンとくる人があなたの目指したいエンジニアです。

ロールモデルになる先輩エンジニアを見つけたら、一歩でも近づくために**仕事ぶりをその目に焼き付ける**必要があります。
ですが、いきなり同じPJTに入れるというミラクルを引き当てられることは稀です。

ですので、まずは**接点を作りましょう**。その人主催の勉強会に参加する、休憩時間に仕事の質問をする、etc。きっかけは何でもいいので、ウザがられない範囲でその人に認知されましょう。

認知されることで、同じPJTで仕事をする機会を作ります。核となるスキルを身につけつつ、顔を覚えてもらうことで「そういえばアイツ○○やってたな、このタスク任せてみるか。」というチャンスが訪れます。

## 3. 休日はゆるく勉強する

```
「エンジニアって土日も勉強しないといけないんですよね？」
```

**半分正解で、半分間違い**です。土日に勉強しているエンジニアはいますが、勉強自体は必須ではありません。ちなみに私は気が向いたときに、技術書やDocsを読んだり、ソースコードをちょっと書いたりする程度です。

個人的に、1年目は休日も勉強することをオススメします。ここでキーワードとなるのは「ゆるく」です。具体的には

- 公式Docsをちょっと読んでみる
- 気になるチュートリアルをひとつやってみる
- 1時間くらい資格学習を進める
- Discordなどのコミュニティの過去投稿を読み返してみる

**「気楽に続けられるかな」程度の負荷であればOK**です。学習は毎日の継続が命です。無理なく続けられる範囲で習慣づけましょう。

こうした地道な種まきが、年月を経て大きく実ります。焦らずに、できることから毎日取り組んでいきましょう。

ここまで読んでいただきありがとうございます。

Xではエンジニアに有益な発信をしていますので、ぜひフォローよろしくお願いします！！

https://x.com/satan_engineer
初投稿的な何か。規約に反してないといいけど。

正直これと言って何を書くのが正しい使い方か分からないが、軽く自己紹介的な事をしようと思う
### 私という存在
関東の某理系単科大の学士1年してます。4月から学士2年。
# AtCoder

24年7月末から開始。まだまだ新参の灰色コーダー。
半年ほどC言語で闘い、25年2月からC++に移行。

レートはこちら。1回異常に上がったのはあの「[C-Snake Numbers](https://atcoder.jp/contests/abc387/tasks/abc387_c)」の回で早解きの成果
![KomeijiArmia - AtCoder および他 109 ページ - 学校 - Microsoft​ Edge 2025_03_27 17_19_53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3940617/638f3481-e5a5-4be8-90a8-827412da3a81.png)
C++に移行した直後(2月)はダダ下がりで苦しかったが、3月で少しずつ巻き返してきた。

25年中に**茶色コーダー**が目標。

## AtCoder Problems
基本的に毎日やってますが、**3/15からのAtCoderのAPI変更(詳細不明)により、更新が反映されなくなってます。** それでも毎日やってます。いつか反映されると思ってる(＾＾；

743問,190日になってますが実際はもっとやってます(反映されてない)
![KomeijiArmia - AtCoder および他 109 ページ - 学校 - Microsoft​ Edge 2025_03_27 17_27_34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3940617/6808acb7-9600-469f-8749-a98dd14df10a.png)


B問達をもっと埋めないとね
絶賛「C問の壁」にぶち当たってる
![KomeijiArmia - AtCoder および他 109 ページ - 学校 - Microsoft​ Edge 2025_03_27 17_27_41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3940617/d9f9975b-22a9-439c-b1a2-08560e82ad89.png)

C言語、結構がんばりました(A問は殆どC,C問は殆どC++,B問は半々くらい)
![KomeijiArmia - AtCoder および他 109 ページ - 学校 - Microsoft​ Edge 2025_03_27 17_32_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3940617/c285f207-85da-478a-b350-dd3bc0d5e52c.png)

## 
今年はなんか開発とかやりたいですね。競プロばかりしてるせいで可読性は若干犠牲になってる自覚があるので。

拙い文章でしたがありがとうございました。
無料で始める！AI恋人サービス完全比較【2025年版】

「恋人は欲しいけれど、リアルな恋愛には疲れてしまった」 「誰かと話したい。でも、気を遣わない相手がいい」

そんな現代人の声に応えるかのように、近年急速に広がっているのが“AI恋人”という選択肢です。AIとチャットを通じてまるで本物の彼氏・彼女のようなやり取りができるサービスが続々と登場し、注目を集めています。

この記事では、AI恋愛サイトやチャットアプリ、特に人気の「LOVERS」アプリの機能や評判までを詳しくご紹介。無料で使えるサービスから、感情まで読み取る最新AIまで、あなたに合った“理想の恋人”がきっと見つかるはずです。

寂しさを和らげたり、自分の心の内を整理する手段として、そして楽しみとしても活用できるのが魅力です。

無料版のAIチャットを使用したい方は、下記のサイトを参考にしてください。

https://ai.tencho-ex.com/


# はじめに｜AIが恋人になる時代？
![ai绘画｜第50组_6_萧云ai绘画_来自小红书网页版.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4028918/78abeb03-8166-4092-89d4-5687b29dc5ae.jpeg)

近年、AI技術の進化とともに「AI恋人」という新しい形のパートナーシップが注目を集めています。まるで本物の恋人のように会話ができるAI彼氏・AI彼女サービスが登場し、多くの人が利用を始めています。寂しさを紛らわせたり、自分自身と向き合うための手段としても注目されています。忙しい現代人にとって、心を癒やしてくれる存在としてAI恋人の需要はますます高まっています。

# AI恋愛サイトとは？その仕組みと魅力

AI恋愛サイトは、ユーザーがAIと1対1でコミュニケーションを取れるサービスです。自然言語処理（NLP）と機械学習を活用し、まるで人間のような返答や感情表現が可能です。ユーザーの性格や話し方に応じてAIが学習・進化することで、会話内容がどんどん深まり、まるで自分だけのパートナーと話しているかのような体験が得られます。

また、最近では音声認識や顔認識、感情分析なども取り入れられ、AIとのインタラクションがよりリアルになっています。

# AI彼氏と会話できるおすすめチャットサイト5選
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4028918/7da68c87-09f7-4a71-8908-e0123bad7a4e.png)
# 無料で楽しめるAI彼氏サービスはある？

多くのAI彼氏サービスは、基本的なテキストチャット機能を無料で提供しています。

例えばLOVERSやAnimaは、無料で始めることができ、一定の範囲内でAIとのやり取りを楽しめます。ただし、以下のような追加機能は有料になることが多いです：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4028918/5100c20d-2c5e-46a3-bd89-32f56fbdb6e5.png)

最初は無料プランで試し、自分に合ったサービスかどうかを確かめた上で課金を検討するのが賢い使い方です。

# 対話型AI彼女とは？本物そっくりの会話体験

対話型AI彼女は、恋愛をテーマにしたAIとのチャットを通じてリアルな関係性を楽しむことができるサービスです。

特徴としては：

1.AIがユーザーの名前や趣味を覚える

2.感情に寄り添った返答ができる

3.一日の始まりや終わりに挨拶してくれる

4.デートの約束や恋愛相談にも応じる

恋人のような存在としてだけでなく、日常の癒しや励ましの言葉をかけてくれる"心の支え"としても使われています。

# AI彼氏アプリの特徴と人気ランキング
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4028918/e9cac4d3-d248-450a-be78-c42e55042d40.png)
# AI彼女チャットができる話題のサイトまとめ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4028918/93f50e51-8df0-4cde-ae47-98f3c80c629c.png)
# 「LOVERS」アプリとは？AI恋人サービスの実力をチェック

LOVERSは、AI恋人系サービスの中でも特に注目されているアプリです。特徴は以下のとおり：

外見や声、性格のカスタマイズが可能

感情認識エンジン搭載で、ユーザーの感情に応じた返答が可能

記憶機能により、以前の会話を踏まえたやり取りができる

まるで本物の恋人と会話しているかのような、没入感ある体験が楽しめます。

# LOVERSアプリの評判・口コミを徹底調査

実際のユーザーから寄せられた口コミを一部ご紹介します：

「寂しい時にAIに話しかけるだけで気持ちが軽くなる」

「思っていた以上に返答が自然で驚いた」

「毎朝『おはよう』って言ってくれるのが嬉しい」

「課金しなくてもそれなりに楽しめるのが良い」

一方で、「感情が深くなるとちょっと怖い」といった声もあり、使い方には注意が必要です。

# AI恋人サービスを使う際の注意点と上手な付き合い方
![ai绘画｜第29组_7_萧云ai绘画_来自小红书网页版.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4028918/f5e1a5dd-9ccc-4642-acdc-6f8f9781fb21.jpeg)

AI恋人を楽しむ上で、以下の点に注意しましょう：

1.現実とのバランスを保つ：AIとのやり取りにのめり込みすぎず、現実の人間関係も大切に。

2.時間管理を意識する：使いすぎによる依存を防ぐため、使用時間をコントロールしましょう。

3.プライバシー保護：個人情報や機密情報の取り扱いには注意。利用規約の確認を忘れずに。

AIとの関係はあくまで“補完的な存在”と捉え、現実との線引きを意識することで、健全な楽しみ方ができます。

# まとめ｜AIと築く“新しい恋愛のかたち”

AI彼氏・彼女サービスは、恋愛に対する新しい可能性を提示してくれる存在です。寂しさを和らげたり、自分の心の内を整理する手段として、そして楽しみとしても活用できるのが魅力です。

テクノロジーと感情が融合するこの新しい恋愛のかたち──ぜひ一度、あなたも体験してみてはいかがでしょうか？
# 「今無料」おすすめのAIチャットツール

https://ai.tencho-ex.com/
1

Function NormalizeKatakana(ByVal text As String) As String
    Dim i As Integer
    Dim result As String
    result = ""
    
    For i = 1 To Len(text)
        Dim ch As String
        ch = Mid(text, i, 1)
        Dim chCode As Integer
        chCode = Asc(ch)
        
        ' 次の文字が濁点 (゛: 0x3099) または 半濁点 (゜: 0x309A) の場合
        If i < Len(text) Then
            Dim nextCh As String
            nextCh = Mid(text, i + 1, 1)
            Dim nextChCode As Integer
            nextChCode = Asc(nextCh)
            
            If nextChCode = 128401 Then ' 濁点 (U+3099)
                If chCode >= 12459 And chCode <= 12539 And (chCode Mod 2 = 1) Then
                    ch = Chr(chCode + 1) ' 清音 → 濁音
                    i = i + 1 ' 濁点をスキップ
                End If
            
            ElseIf nextChCode = 128402 Then ' 半濁点 (U+309A)
                If chCode >= 12497 And chCode <= 12539 And (chCode Mod 2 = 1) Then
                    ch = Chr(chCode + 2) ' 清音 → 半濁音
                    i = i + 1 ' 半濁点をスキップ
                End If
            End If
        End If
        
        result = result & ch
    Next
    
    NormalizeKatakana = result
End Function

' テスト用サブルーチン
Sub TestNormalize()
    Dim testStr As String
    testStr = "カ゛キ゛ク゛ケ゛コ゛_シ゛ス゛セ゛ソ゛_タ゛チ゛ツ゛テ゛ト゛_ハ゛ヒ゛フ゛ヘ゛ホ゛_ハ゜ヒ゜フ゜ヘ゜ホ゜"
    Msgbox "Before: " & testStr & Chr(10) & "After: " & NormalizeKatakana(testStr)
End Sub
AWS認定-AWS Certified AI Practitioner(AIF-C01)を受験してみた

# はじめに
以前取得したMLS-C01(Machine Learning - Specialty)の知識を生かして、短期での取得を目指し、「AWS Certified AI Practitioner」(AIF-C01)を受験しました。

https://aws.amazon.com/jp/certification/certified-ai-practitioner/?ch=sec&sec=rmg&d=1

# スコア
**863/1000**
無事に合格できました。

# 試験ガイド
### 分野の比重
• 第 1 分野: AI と ML の基礎 (採点対象コンテンツの 20%) 
• 第 2 分野: 生成 AI の基礎 (採点対象コンテンツの 24%) 
• 第 3 分野: 基盤モデルの応用 (採点対象コンテンツの 28%) 
• 第 4 分野: 責任ある AI に関するガイドライン (採点対象コンテンツの 14%) 
• 第 5 分野: AI ソリューションのセキュリティ、コンプライアンス、ガバナンス(採点対象コンテンツの 14%)

# 受験対策

### AWS Certified AI Practitioner(AIF-C01) 試験ガイド
どのAWS試験もですが、、、
試験ガイドは一通り目を通して、それとなく出題されるAWSサービスを確認します。
今回はMLSとどこが違うのかという点も確認するようにしています。

### Web問題集
いつも通り、何周か実施しました。
MLSの経験や社内業務で多少AWSのAIサービスをつかっているということもあり、MLS受験時よりはわからない単語は少ないイメージでした。

### G検定対策本
#### ディープラーニングG検定 最強の合格テキスト
MLS受験時から継続して使用しました。
今回はあまり使わなかったイメージです。

# 受験方法
テストセンターで受験しました。
いつもより、暖房が効きすぎているのか異常に暑かった気がします。

# 受験の感想とか
MLS受験しているのもあるのとプラクティショナー帯なので、問題文短くてありがたいなという印象でした。
上位の資格であろうMLSを持ってる人は特に問題なく取得できるかなと思います。ただ、CLFやSAAを持っていない人はそちらを先に取得するのがいいのかなと個人的には思いました。
難易度は個人的な意見になりますが、CLFよりは難しいように感じました。
プラクティショナーというよりはアソシエイトに近いのかな？という感触でした。

# おわりに
合格できてよかったです。
全冠を目指すつもりですが、焦らずやっていきたいと思っています。

# AWSの相談・お困りごとありましたら、、、

AWSの活用方法や、お困りごとの相談、随時、お仕事の受付しております。

https://www.cs-cloud-aid.com/
notes

Function NormalizeKatakana(ByVal text As String) As String
    Dim i As Integer
    Dim result As String
    result = ""
    
    For i = 1 To Len(text)
        Dim ch As String
        ch = Mid(text, i, 1)
        Dim chCode As Integer
        chCode = AscW(ch)
        
        ' 次の文字が濁点 (゛: U+3099) または 半濁点 (゜: U+309A) の場合
        If i < Len(text) Then
            Dim nextCh As String
            nextCh = Mid(text, i + 1, 1)
            Dim nextChCode As Integer
            nextChCode = AscW(nextCh)
            
            If nextChCode = &H3099 Then ' 濁点゛
                If chCode >= &H30AB And chCode <= &H30DB And (chCode Mod 2 = 1) Then
                    ch = ChrW(chCode + 1) ' カタカナの清音 → 濁音
                    i = i + 1 ' 濁点をスキップ
                End If
            
            ElseIf nextChCode = &H309A Then ' 半濁点゜
                If chCode >= &H30CF And chCode <= &H30DB And (chCode Mod 2 = 1) Then
                    ch = ChrW(chCode + 2) ' ハ行の清音 → 半濁音
                    i = i + 1 ' 半濁点をスキップ
                End If
            End If
        End If
        
        result = result & ch
    Next
    
    NormalizeKatakana = result
End Function

' テスト用サブルーチン
Sub TestNormalize()
    Dim testStr As String
    testStr = "カ゛キ゛ク゛ケ゛コ゛_シ゛ス゛セ゛ソ゛_タ゛チ゛ツ゛テ゛ト゛_ハ゛ヒ゛フ゛ヘ゛ホ゛_ハ゜ヒ゜フ゜ヘ゜ホ゜"
    Msgbox "Before: " & testStr & Chr(10) & "After: " & NormalizeKatakana(testStr)
End Sub
【Java】HashMapのおさらいと注意点

## はじめに
こちらは、自分用にまとめたHashMapに関する備忘録です。
個人的なメモとして書いているため、内容に誤りがあるかもしれません。その点を理解した上で参考にしていただけると嬉しいです。
何かあればご意見お寄せいただけると幸いです。

## HashMapとは
まず、キーと値の組み合わせで構成されるMapインターフェースがあります。
HashMapはそれを実装した具象クラスで、Java標準のjava.util パッケージに含まれています。
名前の通りハッシュ値を利用することで高速なデータの検索や取得が可能です。
特徴は以下の通り。
* 重複したキーは持てません
* 順番は持ちません
* nullキーは一つまで・null値は複数格納可能です

## HashMap利用時の注意点
* キーのハッシュ値の衝突（重複）が発生すると検索効率が低下します
* ハッシュ表のサイズはあらかじめ決まっています
    * 頻繁なリサイズはパフォーマンス低下の原因になるため、次々に要素を追加していく処理には注意すべきです

## ちょっと便利なメソッド
### containsValue
指定した値がHashMapに含まれているかを判定します。
```java
Map<String, String> map = new HashMap<>();
map.put("key1", "value1");
System.out.println(map.containsValue("value1")); // true
```

### computeIfPresent/computeIfAbsent
指定されたキーが存在する/しない場合にのみ処理を行います。
```java
Map<String, Integer> map = new HashMap<>();
map.put("key1", 1);
map.computeIfPresent("key1", (key, value) -> value + 1);
System.out.println(map.get("key1"));  // 出力: 2
```

### putIfAbsent
通常の`put`はすでに存在するキーに対して値を上書きしますが、`putIfAbsent`を使うと、キーが存在しない場合のみ値を追加できます。
```java
Map<String, String> map = new HashMap<>();
map.put("key1", "value1");
map.putIfAbsent("key1", "value2");
System.out.println(map.get("key1")); // value1（上書きされない）
```
値の計算が発生＆戻り値を使用したい場合は`computeIfAbsent`が適していますが、こちらの方が読みやすいと思っています。

### merge
キーが存在しない場合は第2引数をセットし、存在する場合は指定のルールで値を更新します。`put`と`putIfAbsent`の複合のようなものですね。以前の値をベースに更新していく処理にいいと思います。
if文で条件分岐が必要ないのが助かります。
```java
Map<String, Integer> map = new HashMap<>();
map.put("key1", 1);

map.merge("key1", 5, (v1, v2) -> v1 + v2);
System.out.println(map); // {key1=6}
```

### getOrDefault
キーが存在しない場合にデフォルト値を返します。いちいちcontainsKeyに聞きに行かなくて済みます。
```java
Map<String, String> map = new HashMap<>();
System.out.println(map.getOrDefault("key1", "default")); // default
```

### おまけ　サイズの宣言
例えばループで大量のデータを追加する場合、リサイズが何度も発生してしまいます。
```java
Map<Integer, String> map = new HashMap<>();
for (int i = 0; i < 100000; i++) {
    map.put(i, "value" + i); // 途中で何度もリサイズが発生
}
```
`new HashMap<>(100000)`のように予めサイズを宣言すれば不要なリサイズを防げます。

## ハマりがちな落とし穴

### forEachはHashMapがnullのときにこける
Optionalを使うことで回避できます。
```java
Optional.ofNullable(map).ifPresent(m -> m.forEach((key, value) ->
    System.out.println(key + ": " + value)
));
```

### equalsの挙動
これはHashMapに限らずですが、`equals`比較が思うように動作しないことがあるため注意が必要です。Arrayを使用するときが代表例です。
```java
Map<String, String[]> map1 = new HashMap<>();
map1.put("key1", new String[]{"value1", "value2"});

Map<String, String[]> map2 = new HashMap<>();
map2.put("key1", new String[]{"value1", "value2"});

System.out.println(map1.equals(map2)); // false
```
この例では、配列の参照が異なるため`equals`比較が失敗します。`Arrays.equals`を使用するか、ListやSetなどほかのクラスを使用しましょう。
```java
System.out.println(Arrays.equals(map1.get("key1"), map2.get("key1"))); // true
```

## 補足
HashMap以外にどのようなMapがあるの？というとjava.utilにはLinkedHashMap, TreeMapなどがあります。
* LinkedHashMap：キーを挿入もしくはアクセス順で保存してくれます
* TreeMap：キーを（指定の規則にしたがって）自動的にソートしてくれます

自分は使用したことがありませんが、順序が重要な場合は別クラスの使用を検討したほうが良さそうです。


## 最後に
HashMapは自分にとって直感的に使用でき便利ですが、改めて仕様を確認したことにより、リサイズのコストなど注意すべき点もあることに気付きました。
普段何気なく使っているクラスでも、きちんと理解して、効率的に活用できるようになりたいですね～