OmniAICreator/Qiita-1.07M huggingface dataset:
[インフォグラフィック] ハイライト | 2025年2月のデータベース新機能

> 本記事は[こちらのブログ](https://www.alibabacloud.com/blog/infographic-highlights-%7C-database-new-features-in-feburary-2025_602092?spm=a2c65.11461433.0.0.4ee35355bCemAJ)を参考にしています。
> 翻訳にはアリババクラウドの[ModelStudio](https://www.alibabacloud.com/en/product/modelstudio)([Qwen](https://www.alibabacloud.com/en/solutions/generative-ai/qwen))を使用しております。

# ApsaraDB RDS for MySQLおよびAnalyticDB for MySQLのアップデート情報

1. **ApsaraDB RDS for MySQL ストレージ圧縮機能のリリース**  
   特長: データを元のサイズの半分に圧縮し、バックアップスペースを2倍無料で提供し、ストレージコストを最大60%削減します。  
   ドキュメント: [https://www.alibabacloud.com/help/rds/apsaradb-rds-for-mysql/storage-compression](https://www.alibabacloud.com/help/rds/apsaradb-rds-for-mysql/storage-compression)

2. **ApsaraDB RDS for MySQL 一貫性レベル設定のサポート**  
   特長: 必要に応じて一貫性レベルをカスタマイズでき、最終的、セッション、またはグローバル一貫性の中から選択できます。この柔軟性により、ビジネスは運用要件に応じてパフォーマンスと信頼性を最適化できます。  
   ドキュメント: [https://www.alibabacloud.com/help/rds/apsaradb-rds-for-mysql/configure-consistency-levels](https://www.alibabacloud.com/help/rds/apsaradb-rds-for-mysql/configure-consistency-levels)

3. **AnalyticDB for MySQL エンタープライズ版およびベーシック版のリリース**  
   特長: 以前の提供内容を統合し、2つの明確なエディションにすることで、AnalyticDB for MySQLはデータベースソリューションの選択プロセスを簡素化し、ビジネスニーズに最適なものを簡単に特定して実装できるようにしました。  
   ドキュメント: [https://www.alibabacloud.com/help/analyticdb/analyticdb-for-mysql/product-overview/editions](https://www.alibabacloud.com/help/analyticdb/analyticdb-for-mysql/product-overview/editions)

![1](https://img.alicdn.com/imgextra/i3/O1CN01Mln4Ks1jQkN19be3R_!!6000000004543-2-tps-2000-8580.png)
git／githubの基本的な操作


## Gitとは？GitHubとは？

###  Gitとは？

Gitは「バージョン管理システム」の一つで、ソースコードの変更履歴を管理できます。開発の現場では、複数人での開発やコードの管理に欠かせないツールです。

### GitHubとは？

GitHubは、Gitを利用したコードのホスティングサービスです。リモートリポジトリを管理し、チーム開発やオープンソースプロジェクトで活用されます。


###  Gitの基本コマンド

#### リポジトリの作成

ローカルでGitを使うには、まずリポジトリを作成します。

~~~
$ bash  git init
~~~

このコマンドを実行すると、`.git`というフォルダが作成され、Gitでの管理が開始されます。

#### ステージングとコミット

ファイルを追加・編集した後、Gitに変更を記録する流れは以下の通りです。
~~~example.sh
git add ファイル名   # 変更をステージング（準備）
git commit -m "コミットメッセージ"  # 変更を確定
~~~
#### 変更履歴の確認
~~~
$ bash git log
~~~
過去のコミット履歴を確認できます。

### GitHubとの連携

#### GitHubにリポジトリを作成する
1.	GitHubで新しいリポジトリを作成
2.	作成したリポジトリのURLをコピー

#### ローカルリポジトリをGitHubに接続

リモートリポジトリとしてGitHubを追加し、変更をプッシュします。

~~~.sh
git remote add origin リポジトリのURL
git branch -M main  # メインブランチを指定
git push -u origin main
~~~
JavaScriptにおける型安全設計：JSDocとTypeScriptによる静的検査と漸進的導入の戦略


## 概要

JavaScriptは本来、**動的型付き言語**であり、実行時まで型の検査が行われない。  
その柔軟性の裏には、「**いつでも何でも通ってしまう**」という危険が潜んでいる。

この問題に対して、以下のような手法が有効である：

- **JSDoc** によるコメント型注釈とエディタ補完
- **TypeScript** による静的型チェックの導入
- 既存のJavaScriptコードに対する**漸進的型適用戦略**

本稿では、型安全をコードにどう“設計として”組み込むかを体系的に示す。

---

## JSDocによる型定義

```js
/**
 * @param {string} name
 * @param {number} age
 * @returns {string}
 */
function greet(name, age) {
  return `Hello, ${name}. You are ${age}.`;
}
```

- ✅ VSCode等のIDEで補完と型チェックが有効
- ✅ 設計意図がコメントで可視化される
- ❌ 実行時には型チェックされない（あくまで補助）

---

## JSDocで型エイリアスを作る

```js
/**
 * @typedef {Object} User
 * @property {string} id
 * @property {string} name
 */

/**
 * @param {User} user
 */
function showUser(user) {
  console.log(user.name);
}
```

→ ✅ オブジェクト構造を再利用可能に

---

## TypeScriptでの静的型定義

```ts
type User = {
  id: string;
  name: string;
};

function showUser(user: User): void {
  console.log(user.name);
}
```

- ✅ コンパイル時に型エラーを検出
- ✅ 型定義が第一級市民になる（=設計が明示される）

---

## TypeScriptを「漸進的に」導入する方法

### ✅ 方法①：`.js` ファイル + `// @ts-check` + JSDoc

```js
// @ts-check

/**
 * @param {number} a
 * @param {number} b
 */
function add(a, b) {
  return a + b;
}
```

→ ✅ JavaScript のまま TypeScript の静的検査を部分的に使える

---

### ✅ 方法②：一部ファイルのみ `.ts` で書く

- 既存プロジェクトをそのままに、一部 `.ts` で型安全強化
- `tsconfig.json` に `allowJs: true` を指定

---

### ✅ 方法③：型定義ファイル（`.d.ts`）を追加する

- ライブラリや共通型だけ別管理可能
- `.js` のロジックはそのまま → 型だけ強化

---

## 型安全における“設計”の意義

| 意図                  | 型の設計戦略                            |
|-----------------------|-----------------------------------------|
| 関数の契約を明確化     | JSDoc / TS関数定義                      |
| データ構造を標準化     | typedef / type / interface              |
| 予期しない型の混入防止 | `strictNullChecks`, `noImplicitAny`     |
| オプションの型制御     | `Partial<T>`, `Pick<T, K>`, `Omit<T, K>` |
| 自己文書化             | 型そのものが「意図の表現」になる        |

---

## よくあるミスと対策

### ❌ JSDocだけで安心してしまう

→ ✅ 実行時チェックはされない → 静的解析 + テストが必要

---

### ❌ `any` の乱用

```ts
function doSomething(data: any) { ... }
```

→ ✅ `any` は型安全を破壊する → `unknown` や明示的な型を使うべき

---

### ❌ 型エラーを `as` で潰す

```ts
const user = response as User; // ❌ 信頼性ゼロ
```

→ ✅ バリデーションロジックを必ず通す

---

## 型安全設計の導入判断フロー

```text
① 補完と簡易型チェックだけ欲しい？ → JSDoc

② 既存プロジェクトで徐々に強化したい？ → // @ts-check + allowJs

③ 本格的に型を管理したい？ → TypeScript本導入

④ API/データ構造に揺らぎが多い？ → 型ガード・Zod等で実行時型検証

⑤ ライブラリの外部型を補完したい？ → DefinitelyTyped / .d.ts 導入
```

---

## 結語

型とは「制約」ではない。  
それは、**コードに対する“設計者の意図”を明示するための言語**である。

- JSDocは“コメントによる設計”
- TypeScriptは“構文そのものによる設計”
- 型安全とは、事故を防ぐ“構文的な安全装置”であり、
- 意図を共有するための“構造的ドキュメント”でもある

**読めて、壊れず、安心して変更できるコード。型設計はそのためにある。**
JavaScriptにおけるクリーンコード設計：読める・変えられる・壊れないコードの原則と実践



## 概要

クリーンコードとは、**「読む人」にとって明確な構造を持ち、予測可能かつ修正しやすいコード**である。  
技術的な正しさではなく、**構文と設計に「意味と意図」が現れているか**が重要となる。

本記事では、以下の視点から JavaScript におけるクリーンな設計を体系化する：

- 意図を伝える変数・関数命名
- 関数の単一責務と分割
- ネストとフロー制御の最小化
- 副作用の分離
- 条件式の明示化
- “直感的に読める構造”のデザイン戦略

---

## 1. 意図を表す変数・関数名

```js
// ❌ NG
let d = new Date();
let t = d.getTime();

// ✅ OK
const now = new Date();
const timestamp = now.getTime();
```

- ✅ 名前で型を表す（`count`, `isVisible`, `userList` など）
- ✅ 抽象名でなく「意味のあるラベル」にする

```js
// ❌ doStuff() ❌ handleData()
// ✅ parseResponse(), updateUI(), fetchUserList()
```

---

## 2. 関数は“何をするか”が一文で言えるか

```js
// ❌ Bad: 複数責務を持つ関数
function validateAndSubmit(formData) {
  if (!formData.name) throw Error();
  // ...
  sendToServer(formData);
}
```

→ ✅ `validate()` と `submit()` に分離すべき

---

## 3. ネストの制御と早期リターン

```js
// ❌ 多重ネスト
function process(user) {
  if (user) {
    if (user.active) {
      return save(user);
    }
  }
  return null;
}

// ✅ フローを明示
function process(user) {
  if (!user || !user.active) return null;
  return save(user);
}
```

---

## 4. 副作用を分離する

```js
// ❌ 副作用を含んだ処理
function addItemAndUpdateUI(item) {
  list.push(item);
  renderList(); // UI更新（副作用）
}
```

→ ✅ 純粋関数と副作用の分離

```js
function addItem(list, item) {
  return [...list, item]; // 不変性 + 副作用なし
}
```

---

## 5. 条件式は“読む人の頭の中”を助けるために書く

```js
// ❌ 意味が不明
if (!x || !y && z) {}

// ✅ 意図が明確
const isValid = !x || (!y && z);
if (isValid) {}
```

- ✅ 「条件に名前をつける」ことで思考負荷を下げる

---

## 6. 魔法の数値・文字列を排除する

```js
// ❌ Bad
setTimeout(fn, 3000);

// ✅ Good
const THREE_SECONDS = 3000;
setTimeout(fn, THREE_SECONDS);
```

→ ✅ 意図が見える → 修正も簡単

---

## 7. 構造を“見れば理解できる”ようにする

```js
function fetchUserData(id) {
  return fetch(`/api/users/${id}`)
    .then(res => res.json())
    .then(user => {
      updateUserUI(user);
      return user;
    });
}
```

- ✅ 関数名と処理の流れが一致
- ✅ promiseチェーンを明確に順序づけ
- ✅ UI更新が副作用として明示されている

---

## 8. “短い関数”が正義ではない

```js
// ❌ 分割しすぎて読めない
renderUI();
updateState();
logResult();

// ✅ コンテキストが伝わる関数構造
function submitApplication() {
  validateInput();
  sendRequest();
  showSuccessModal();
}
```

→ ✅ 関数の“長さ”より、“意図”を伝える構造が優先

---

## クリーンコードの設計判断フロー

```text
① この関数は「何をする関数か」が一文で言えるか？

② 名前を見ただけで型と意味が分かるか？

③ ネストが深くなっていないか？早期returnは可能か？

④ 状態変更・副作用が予測しやすい位置にあるか？

⑤ 条件・ループの意図が読み取れるか？

⑥ 数値や文字列に“意味の名札”をつけているか？

⑦ コード全体が“読むことに抵抗を感じない”か？
```

---

## 結語

クリーンコードとは、「構文を正しく書くこと」ではない。  
それは「**読む人が何も考えずに理解できるように書く**」ことである。

- 意図を名前に刻む
- 情報の流れを整理する
- 状態と副作用を分離する
- 読む人を迷わせないために“設計する”

**良いコードは、黙っていても伝わるドキュメントである。**  
それがクリーンコードの本質である。
WeakMapとWeakSetの記憶と消滅：JavaScriptのガーベジコレクションとメモリ安全な設計戦略


## 概要

JavaScriptではメモリの管理が自動的に行われるが、**“保持しすぎること”によるメモリリークのリスク**は開発者側にある。  
この課題に対し、`WeakMap` および `WeakSet` は**弱参照**という概念で解決を提供する。

- `Map` / `Set` は値を「保持」する
- `WeakMap` / `WeakSet` は値を「参照」する

本稿では、この特性を活かした設計例と、**メモリリーク回避・隠蔽状態管理・キャッシュ設計**への応用方法を示す。

---

## 1. WeakMapとは何か？

```js
const wm = new WeakMap();
const obj = { name: 'Toto' };

wm.set(obj, 'secret');
console.log(wm.get(obj)); // 'secret'
```

- ✅ **キーはオブジェクト限定**
- ✅ **弱参照**：`obj` がGCで消えれば、`wm` のデータも自動削除
- ❌ キー列挙・サイズ取得は不可能（`wm.keys()` や `.size` は存在しない）

---

## 2. WeakSetとは何か？

```js
const ws = new WeakSet();
const o = { id: 1 };

ws.add(o);
console.log(ws.has(o)); // true
```

- ✅ **オブジェクトのみ格納可**
- ✅ 同様にGCで自動解放される

---

## なぜ「弱参照」なのか？

```text
通常の Map:
  キー = 強参照 → GCの対象にならない

WeakMap:
  キー = 弱参照 → オブジェクトがどこからも参照されなければGCされる
```

→ ✅ **“知らないうちにリーク”を防ぐ仕組み**

---

## 使用ユースケース①：プライベートデータの隠蔽

```js
const privateData = new WeakMap();

class User {
  constructor(name) {
    privateData.set(this, { name });
  }

  getName() {
    return privateData.get(this).name;
  }
}

const u = new User('Toto');
u.getName(); // 'Toto'
```

- ✅ 外部からアクセス不能
- ✅ ユーザーが削除されれば、**プライベートデータも自動消滅**

---

## 使用ユースケース②：DOMノードへのメタ情報紐付け（メモリセーフ）

```js
const cache = new WeakMap();

function bindMeta(domNode, meta) {
  cache.set(domNode, meta);
}

function getMeta(domNode) {
  return cache.get(domNode);
}
```

→ ✅ DOMが削除されたら、`cache`も自動解放 → メモリリークを回避

---

## 使用ユースケース③：内部キャッシュ（GC安全なメモ）

```js
const results = new WeakMap();

function heavyCalc(input) {
  if (results.has(input)) return results.get(input);

  const output = /* ... heavy computation ... */;
  results.set(input, output);
  return output;
}
```

→ ✅ キャッシュは存在する限り利用され、不要になれば解放される

---

## 制約と注意点

| 特性                     | WeakMap / WeakSet                       |
|--------------------------|------------------------------------------|
| キー/値はオブジェクトのみ | ✅（プリミティブ不可）                   |
| キー列挙                  | ❌ 不可（セキュリティ/GCのため）          |
| サイズ取得               | ❌ 不可                                  |
| メモリ管理               | ✅ 自動GCで安全                          |

---

## 設計判断フロー

```text
① 状態を“外から見せたくない”？ → WeakMap に格納

② DOMや一時的なオブジェクトに紐づく情報を持ちたい？ → WeakMap を使う

③ GCとともに自動的にデータを破棄したい？ → WeakMap/WeakSet を選択

④ プリミティブなキーを使いたい？ → Map を使う（WeakMapでは不可）

⑤ データ一覧が必要？ → Map / Set を選択（Weak系では不可）
```

---

## よくある誤解

### ❌ WeakMapは“弱いセキュリティ”を提供する？

→ ❌ 違います。**セキュリティ目的ではなく、メモリ安全のため**

---

### ❌ WeakMapに入れたら明示的に削除できない？

→ ✅ `.delete(key)` は可能。ただし不要な場合はGCに任せてよい

---

## 結語

`WeakMap` / `WeakSet` は、データを「保持する」のではなく、「**忘れることを許す**」構造である。

- オブジェクトのライフサイクルに寄り添い、
- メモリリークを構造的に防ぎ、
- 外部から不可視な状態を安全に設計できる

**“見えない記憶、忘れられる設計”。それが Weak な構造の本質である。**
EventEmitterの設計戦略：JavaScriptにおける独自イベント駆動構造と責務分離のための通信モデル


## 概要

JavaScript（特にNode.js）において、`EventEmitter` は**カスタムイベントを中心にした通信インターフェース**として利用される。  
これにより、モジュールやレイヤー間の**疎結合な双方向通信**が可能となり、**UIコンポーネントの再利用性、非同期処理の柔軟性、責務の明確な分離**を実現できる。

本稿では以下を扱う：

- `EventEmitter` の基本APIと構造
- イベント購読・発火・解除の流れ
- クラスベースでのカスタム実装
- DOMのイベントと明確に分けた抽象化の意義
- アーキテクチャ設計上の使い所と注意点

---

## Node.jsのEventEmitter基本構文

```js
const EventEmitter = require('events');
const emitter = new EventEmitter();

emitter.on('login', user => {
  console.log(`${user} logged in`);
});

emitter.emit('login', 'toto'); // "toto logged in"
```

- ✅ `on(event, listener)` → イベント購読
- ✅ `emit(event, data)` → イベント発火
- ✅ `off(event, listener)` → イベント解除（Node 10以降）

---

## onceで一度きりのリスナー設計

```js
emitter.once('init', () => {
  console.log('Initialized');
});
```

→ ✅ 初回のみ有効 → 初期化処理、初回ロード検出などに有効

---

## リスナーの解除

```js
function handler() {
  console.log('Logout event');
}

emitter.on('logout', handler);
emitter.off('logout', handler);
```

→ ✅ 明示的な解除でメモリリーク防止

---

## イベントを内包するクラス構造（カスタムラッパー）

```js
class AuthService extends EventEmitter {
  login(user) {
    // ログイン処理...
    this.emit('login', user);
  }

  logout() {
    this.emit('logout');
  }
}

const auth = new AuthService();
auth.on('login', u => console.log(`${u} is online`));
auth.login('toto');
```

→ ✅ イベントの設計単位をクラスの責務に内包

---

## DOMイベントとの明確な違い

| 項目             | EventEmitter                     | DOMイベント                       |
|------------------|----------------------------------|------------------------------------|
| 発火元           | 任意のオブジェクト               | DOMノード                         |
| イベント名       | 自由な文字列                     | 固定されたDOMイベント（click等）  |
| バブリング/キャプチャ | ❌ なし                         | ✅ あり                            |
| ライフサイクル制御 | ✅ メソッドで明示的に管理         | ❌ 暗黙的                          |

---

## イベント駆動設計の責務分離パターン

```text
[UI Layer] ── on('submit') → [FormService] ── emit('submitted') → [Logger/Analytics]
```

- ✅ 複数のリスナーが独立に反応
- ✅ UI・処理・ログなどの責務を「イベント」で中継可能
- ✅ テスト容易・柔軟な構成変更が可能

---

## イベントバス（event bus）としての活用

```js
const EventBus = new EventEmitter();

// グローバル通信ハブとしてUI間を接続
EventBus.on('notify', msg => alert(msg));
EventBus.emit('notify', '登録に成功しました');
```

→ ✅ シンプルなグローバルメッセージング構造

---

## よくある注意点

### ❌ メモリリーク（過剰なリスナー）

```js
emitter.setMaxListeners(10); // 超えると警告
```

→ ✅ `removeListener`, `off`, `once` で制御必須

---

### ❌ 同一イベント名の曖昧さ

→ ✅ イベント名は明示的にドメイン命名：`user:login`, `system:shutdown` など

---

## 設計判断フロー

```text
① オブジェクト間を疎結合でつなぎたい？ → EventEmitter

② 特定の処理後に任意数のリスナーを通知したい？ → emitパターン

③ モジュールごとにイベント定義したい？ → クラス継承 + EventEmitter

④ グローバル通信が欲しい？ → EventBus設計

⑤ イベント数が多い？ → イベント名を明示的に命名（名前空間風）
```

---

## 結語

`EventEmitter` は「**状態に反応するという設計思想**」を、構文として提供する。  
それは単なるAPIではなく、「**責務の通知可能な抽象化**」である。

- 情報の流れを疎結合に制御し、
- 処理の分岐を設計的に明示し、
- 再利用可能でテストしやすい構造を作る

**関数を呼ぶのではなく、反応させる。**  
それがイベント駆動設計の本質であり、`EventEmitter` の力である。
Object.freezeによる不変性設計：構造共有とミューテーション防止戦略の基礎と限界


## 概要

JavaScriptではオブジェクトの変更がデフォルトで許可されているが、**意図せぬミューテーション（変更）**は予期せぬバグの温床になる。  
この問題を制御するために導入されるのが、**不変性（immutability）の概念**。

`Object.freeze()` を使うことでオブジェクトを**ミューテーション不可能**にできるが、実はこれには**浅い制約しか与えられない。**

本稿では以下の観点から、不変性を“設計”として導入する方法を提示する：

- `Object.freeze()` の正しい理解と限界
- 深いネスト構造における凍結の再帰処理
- 状態管理における構造共有戦略（Structural Sharing）
- ライブラリを用いた実用的な不変性管理（Immer, Immutable.js）

---

## Object.freeze() の基本挙動

```js
const obj = {
  name: 'Toto'
};

Object.freeze(obj);

obj.name = 'Changed'; // ❌ 無視される（strictならエラー）
console.log(obj.name); // 'Toto'
```

- ✅ プロパティの変更・追加・削除が不可
- ✅ `Object.isFrozen(obj)` で凍結状態を判定可能
- ❌ ネストされたオブジェクトは対象外（**浅い凍結**）

---

## 浅い vs 深い凍結

```js
const deep = {
  outer: {
    inner: 'value'
  }
};

Object.freeze(deep);

deep.outer.inner = 'changed'; // ✅ 変更される（freezeの対象外）
```

→ ✅ 深い構造では再帰的に凍結する必要あり

---

## 再帰的なディープフリーズの実装

```js
function deepFreeze(obj) {
  Object.freeze(obj);
  for (const key of Object.keys(obj)) {
    const val = obj[key];
    if (typeof val === 'object' && val !== null && !Object.isFrozen(val)) {
      deepFreeze(val);
    }
  }
  return obj;
}
```

→ ✅ オブジェクト全体を凍結する安全な関数

---

## 不変性の設計的メリット

| 効果                     | 説明                                                   |
|--------------------------|----------------------------------------------------------|
| 副作用の制御              | 状態が変更不可 → 安全な関数設計が可能                     |
| デバッグ容易              | どこかで書き換えられた問題が原理的に起きない              |
| パフォーマンス最適化      | 構造共有により shallow compare が可能 → React等で有効   |
| テストの一貫性            | オブジェクトが状態を変えないため、再現性の高いテスト設計が可能 |

---

## 状態管理における構造共有戦略（Structural Sharing）

```js
const state1 = { a: 1, b: 2 };
const state2 = { ...state1, b: 3 };

console.log(state1 === state2); // false
console.log(state1.a === state2.a); // true（構造共有）
```

→ ✅ ミューテーションせず、新しいオブジェクトを作る  
→ ✅ React, Redux, Vuex などでの変更検知に最適

---

## ライブラリ活用：Immerによる不変性の“開発体験改善”

```js
import { produce } from 'immer';

const base = { count: 0 };

const next = produce(base, draft => {
  draft.count += 1;
});

console.log(base.count); // 0
console.log(next.count); // 1
```

- ✅ `draft` を書き換えるように書いても、元オブジェクトは不変
- ✅ 内部的に構造比較＋差分追跡 → 効率的な新状態を生成

---

## Immutable.jsによる完全な不変コレクション

```js
import { Map } from 'immutable';

const map1 = Map({ a: 1, b: 2 });
const map2 = map1.set('b', 3);

console.log(map1.get('b')); // 2
console.log(map2.get('b')); // 3
```

- ✅ 内部的に構造共有された不変コレクション
- ❌ 学習コストと専用メソッドの多さがデメリット

---

## 設計判断フロー

```text
① 明示的に変更をブロックしたい？ → Object.freeze

② 深い構造も含めて凍結したい？ → deepFreeze関数を導入

③ 状態のミューテーションを避けつつ操作性を保ちたい？ → Immer

④ 大規模な不変データ管理が必要？ → Immutable.js

⑤ リアクティブな変更検知を最適化したい？ → 構造共有の実装
```

---

## よくある誤解

### ❌ Object.freeze() で全ての変更がブロックされる？

→ ❌ ネストされたオブジェクトはそのまま変更可能  
→ ✅ `deepFreeze()` を使う or ライブラリ利用が安全

---

### ❌ Object.freeze() はセキュリティ機構？

→ ❌ いいえ、**設計的ガード**であり、**完全な秘匿化ではない**  
→ プロパティは `Object.getOwnPropertyDescriptors()` で依然可視

---

## 結語

`Object.freeze()` は、単なる構文ではない。  
それは「**データが書き換わらないという保証**」を**設計上に持ち込むための契約**である。

- ミューテーションの副作用からロジックを解放し、
- 状態の変化を構造として明確に定義し、
- アプリケーションの一貫性と予測性を高める

**不変性とは、変わらないという“前提”をコードに刻むことで、信頼できる設計を作る技法である。**
Symbolによるユニーク性と隠蔽戦略：JavaScriptにおけるプロパティ衝突を防ぐ識別子設計


## 概要

JavaScriptの `Symbol` は、**一意かつ衝突のないプロパティキー**を生成するためのプリミティブ型である。  
これは以下のような構造的課題を解決するために導入された：

- オブジェクトに“他人に見えないプロパティ”を定義したい
- ライブラリ間の命名衝突を完全に防ぎたい
- 内部的に使うデータを安全に封じたい
- フレームワーク・ランタイムがオーバーライドされない設計を実現したい

この記事では、**Symbolの基本構文・設計目的・ユースケース・ビルトインSymbolの正体**を網羅的に整理する。

---

## 1. Symbolの基本構文と性質

```js
const sym = Symbol('description');
```

- ✅ `Symbol` は **一意性を保証する識別子**
- ✅ 同じ説明でも別物

```js
Symbol('x') === Symbol('x'); // false
```

---

## 2. オブジェクトに衝突のないプロパティを定義

```js
const secret = Symbol('secret');

const user = {
  name: 'Toto',
  [secret]: 'classified'
};

console.log(user[secret]); // classified
console.log(user.secret);  // undefined
```

- ✅ 他コードから偶発的に `secret` にアクセスされることはない
- ✅ `for...in`, `Object.keys`, `JSON.stringify` では列挙不可

---

## 3. グローバルSymbolレジストリの利用

```js
const a = Symbol.for('shared');
const b = Symbol.for('shared');

console.log(a === b); // true
```

- ✅ `Symbol.for()` を使うとグローバルに共有される
- ✅ 同じ文字列で生成されたSymbolは同一と見なされる

```js
Symbol.keyFor(a); // 'shared'
```

---

## 4. 設計ユースケース：衝突回避と設計隔離

### ✅ ライブラリ間でプロパティ名が重複しても衝突しない

```js
const internal = Symbol('internal');

function enhance(obj) {
  obj[internal] = { status: 'hidden' };
}
```

### ✅ クラスの内部状態を保護する設計

```js
const _status = Symbol('status');

class Secure {
  constructor() {
    this[_status] = 'locked';
  }

  getStatus() {
    return this[_status];
  }
}

const s = new Secure();
console.log(s._status); // undefined
```

→ ✅ `Symbol` によって“外から見えない状態”を保有できる

---

## 5. ビルトインSymbol：言語仕様を拡張・カスタム可能にする

| Symbol名             | 用途例                                         |
|----------------------|------------------------------------------------|
| `Symbol.iterator`    | `for...of` 対応                               |
| `Symbol.toPrimitive` | オブジェクトをプリミティブ変換する際の挙動制御 |
| `Symbol.toStringTag` | `Object.prototype.toString.call(obj)` の表示名 |
| `Symbol.hasInstance` | `instanceof` の振る舞いをカスタマイズ         |
| `Symbol.isConcatSpreadable` | `Array.prototype.concat` の動作制御      |

---

### 例：`Symbol.iterator`

```js
const iterable = {
  *[Symbol.iterator]() {
    yield 1;
    yield 2;
  }
};

for (const val of iterable) {
  console.log(val); // 1, 2
}
```

---

### 例：`Symbol.toPrimitive`

```js
const obj = {
  value: 42,
  [Symbol.toPrimitive](hint) {
    if (hint === 'number') return this.value;
    return null;
  }
};

console.log(+obj); // 42
```

---

## 設計判断フロー

```text
① 名前衝突を完全に防ぎたい → Symbol

② プロパティを“列挙不可かつ非公開”にしたい → Symbol

③ 複数スクリプトで同一キーを共有したい → Symbol.for()

④ オブジェクトの動作を定義・カスタムしたい → ビルトインSymbol

⑤ オブジェクトを独自のiterableにしたい → Symbol.iterator 実装
```

---

## よくある誤解

### ❌ Symbolはセキュリティ機能ではない

→ 隠されているが、`Object.getOwnPropertySymbols()` で取得可能

---

### ❌ Symbol('x') === Symbol('x') は true？

```js
Symbol('x') === Symbol('x'); // false ❌
Symbol.for('x') === Symbol.for('x'); // true ✅
```

---

## 結語

`Symbol` は、単なる“変わったキー”ではない。  
それは **プロパティ設計における衝突回避と、オブジェクトの意味を拡張する構文的手段**である。

- 名前空間ではなく、一意性を持つ構造的記号
- カスタム動作を担う**語彙のようなメタプロパティ**
- 設計意図をコードに埋め込む「**構文的ドメイン言語**」

**“見えない設計”を実現する。それがSymbolの力である。**
SeeedStudio製 Wio BG770AとSORACOM SIMで試す！簡単セルラー通信

# SeeedStudio製 Wio BG770Aとは？

https://soracom.jp/store/30926/

Wio BG770Aは、Seeed株式会社が開発したLTE-M・NB-IoTのセルラー通信に対応したボードです。詳しくは上記のサイトから。今回は、こちらを使用してセルラー通信を試してみたいと思います。


# 使用するデバイス
- Wio BG770A v1.0
- SORACOM Air for セルラー（SIMカード）

https://soracom.jp/store/30926/

https://soracom.jp/start/


# SORACOM SIMでセルラー通信をやってみる

Wio BG770Aの開発環境の構築は以下にまとめています。Arduino IDE を使用できるので、環境構築は簡単にできると思います。良かったら参考にしてください。
この記事では、ボードへの書き込みがちゃんとできている前提で、このボードの特徴であるセルラー通信を試してみた内容について書いていきたいと思います。

https://qiita.com/yukima77/items/e45a44720cd7fffade3d

<br>

# SORACOMと通信できるサンプルスケッチを選ぶ

Wio BG770A用のサンプルスケッチはいろいろ用意されているのですが、今回は簡単にセルラー通信を試すことを目標にSORACOM SIMを使っての通信を試します。

セルラー通信のサンプルスケッチも複数用意されていますが、今回は、BG770Aの特徴として、省電力機能があるので、早速ですが、その機能が使えそうなサンプルを試します。

『soracom-uptime-psm』というサンプルスケッチが良さそうです。
説明には以下のように記載されているので、たぶんちょうどいいはず。

```
稼働時間をSORACOM Unified Endpointへ送信します。PSM機能を使って電力消費を抑止しています。
```

<br>

https://github.com/SeeedJP/wio_cellular/tree/main/examples/soracom/soracom-uptime-psm



# 実際にやってみる

Wio BG770Aの開発環境は、Arduino IDEを使うことができます。
まずは、サンプルのスケッチを開きます。今回は、『soracom-uptime-psm』というサンプルスケッチを使用します。
※SORACOMのSIMは事前に準備しておいてください！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21408/2c9bc145-6aef-4a53-ac3f-0b137ce6577b.png)


サンプルのスケッチブックを開きました。
次に、さっそく書き込んでみます。これで完了。これで、SORACOMプラットフォームとのセルラー通信が始まります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21408/a8c9e558-26c6-48ec-9bfa-d3d383be6dcc.png)


# SORACOMプラットフォームで通信を確認

ボード側は通信ができている（はず）なので、SORACOMのプラットフォームに作業環境を移動します。
ちゃんと通信できてる？と思いながら、「SIM管理」の画面から通信しているSIMを探します。自分の場合は、たまたまオンラインのデバイスが１つだけだったので簡単に見つかりました！

「MSISDN」やSIMカードに記載されている「製造番号」などを確認すれば、より確実だと思います。
以下のようにオンラインなっていたらセルラー通信は成功しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21408/e15da378-d222-4f6d-850b-798aa525b41e.png)



<br>

SORACOM Harvest Data でもデータ受信を確認してみます。
SORACOM Harvest Data自体は事前に設定しておく必要がありますが、実際にサンプルスケッチでアップロードされたデータがこのように確認することもできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21408/8b20194a-5c8b-4da5-b8c3-1e39dc4e367c.png)


# ボードの挙動をいま一度確認する
とりあえず、何も考えずにサンプルスケッチを書き込んだだけなので、実際にどう動いているのかを確認するために、しばらくボードを眺めてみます。
PSMの機能を使っていて、省電力を実現するために、ボードのLEDもOFFにしているサンプルなので、見るタイミングによっては電源が入っていないように思えます(笑) というか、
ですが、しばらくずっと眺めていると、たまにLEDがチカチカ光ります。
たまに光っていたら正しく動かせていて、そのタイミングでセルラー通信していることになります。

こちらで一旦、SORACOMのSIMを使って通信できるところまで確認できました！


# 参考リンク

https://seeedjp.github.io/Wiki/Wio_BG770A/home.html

https://qiita.com/yukima77/items/45793e72b2347ecbb18b



# おまけ

![段落テキスト.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21408/f6d84dc3-ae9a-4a9e-b81f-dbf632442461.jpeg)
JavaScriptのシリアライズ設計：JSONの限界と構造保持のためのカスタム復元戦略


## 概要

JavaScriptでデータを保存・送受信・復元する際に使われるのが **シリアライズ（serialize）** と **デシリアライズ（deserialize）** である。  
標準的には `JSON.stringify()` / `JSON.parse()` が使われるが、これは **万能ではない。**

特に以下のような構造は、JSONでは正しく保存・復元できない：

- `Date` オブジェクト → 文字列化される
- `Map`, `Set`, `RegExp` → 通常のObjectになる
- 関数 → 保存されない
- クラスインスタンス → プロトタイプ消失
- 循環参照 → `TypeError`

この記事では、**JSONの限界を乗り越える設計パターンと代替手段、カスタム復元戦略**を体系化する。

---

## JSON.stringify の基本仕様

```js
const obj = {
  name: 'Toto',
  created: new Date(),
  greet: () => 'hi',
};

console.log(JSON.stringify(obj));
```

出力例：

```json
{"name":"Toto","created":"2025-03-30T12:00:00.000Z"}
```

- ✅ Date → ISO8601文字列になる
- ❌ 関数 → 無視される
- ❌ プロトタイプ情報 → 消失

---

## 限界①：関数・クラスインスタンスが失われる

```js
class User {
  constructor(name) {
    this.name = name;
  }

  greet() {
    return `Hi, ${this.name}`;
  }
}

const u = new User('Toto');
const json = JSON.stringify(u);
const parsed = JSON.parse(json);

parsed.greet(); // ❌ TypeError: parsed.greet is not a function
```

→ ✅ `greet()` メソッドはプロトタイプにあり、JSON化では失われる

---

## 限界②：循環参照は保存できない

```js
const a = {};
a.self = a;
JSON.stringify(a); // ❌ TypeError: Converting circular structure to JSON
```

---

## 解決①：カスタム toJSON 実装による制御

```js
class User {
  constructor(name) {
    this.name = name;
    this.created = new Date();
  }

  toJSON() {
    return {
      name: this.name,
      created: this.created.toISOString(),
      __type: 'User'
    };
  }
}
```

→ ✅ 特定の型としてシリアライズ可能

---

## 解決②：カスタム reviver による復元処理

```js
const str = JSON.stringify(u);

const revived = JSON.parse(str, (key, value) => {
  if (value?.__type === 'User') {
    const user = new User(value.name);
    user.created = new Date(value.created);
    return user;
  }
  return value;
});
```

→ ✅ `JSON.parse` 第2引数で「復元処理」を実装可能  
→ ✅ 型付きデータの**保存→復元**を安全に設計できる

---

## 解決③：構造保存向きの代替手段

| ライブラリ / 手法       | 特徴                                     |
|--------------------------|------------------------------------------|
| `flatted`                | 循環参照をサポートするJSON互換フォーマット |
| `superjson`              | Date, Map, Set, RegExpなどの復元に対応    |
| `structuredClone()`      | DOM標準・複製のみ（永続化には使えない）  |
| `msgpack` / `protobuf`   | バイナリフォーマット・構造保持に優れる   |

---

## 再設計の戦略：何を残し、何を捨てるか

### ✅ 状態だけ残す：

```js
const snapshot = JSON.stringify(instance); // → DB保存 / API送信用
```

### ✅ 振る舞い（メソッド）も復元したい：

```js
// toJSON / reviver または class構造 + factory関数
```

### ✅ 構造そのまま複製したい：

```js
// structuredClone() or flatted
```

---

## よくある落とし穴

### ❌ Dateをそのまま比較する

```js
JSON.parse(json).created instanceof Date; // ❌ false
```

→ ✅ `new Date(value)` で復元が必要

---

### ❌ メソッドが復元されると思っている

→ メソッドは保存されない → prototype再構築が必要

---

## 設計判断フロー

```text
① データだけ保存？ → JSONで十分

② メソッドや型情報も保存？ → toJSON + reviver

③ Map/Set/Date/RegExpも使う？ → superjson or flatted

④ 循環参照あり？ → flatted or custom traversal

⑤ バイナリで高速化したい？ → msgpack / protobuf
```

---

## 結語

シリアライズは、単なる文字列変換ではない。  
それは「**どの情報を残し、どの構造を捨てるか**」という**設計的決断のプロセス**である。

- JSONは軽くて早いが、構造は失う
- toJSON / reviver は**保存と復元を設計に取り込む術**
- データの“意味”を維持するためには、**保存形式の設計こそが最重要**

**構造を残すのか、値だけ残すのか――それを選ぶのは、設計者である。**
JavaScriptのイベントループ完全理解：非同期処理を制御するタスクキューと実行モデルの本質



## 概要

JavaScriptの非同期処理は、**イベントループ（Event Loop）という実行モデルの上で動いている。**  
この仕組みを正しく理解することで、以下のような非同期設計が可能になる：

- **なぜ `Promise` の `.then()` は `setTimeout` より先に呼ばれるのか？**
- **UIが固まる処理を、どうすれば回避できるのか？**
- **ループ内の非同期処理は、なぜ意図通りに動かないのか？**

この記事では、イベントループの構造・マイクロタスクとマクロタスクの違い・UIと非同期の干渉などを整理し、**非同期処理の裏側を設計視点で読み解く。**

---

## イベントループの基本構造

```text
[Call Stack] ← 同期処理

[Task Queue] ← マクロタスク：setTimeout, setInterval, I/O

[Microtask Queue] ← マイクロタスク：Promise, queueMicrotask

Event Loop:
  1. Call Stack が空になるのを待つ
  2. Microtask Queue を全て実行
  3. 次に Task Queue の先頭を 1 件実行
  4. 繰り返す
```

---

## タスクの種類

| タイプ        | 実行タイミング              | 代表API                        |
|---------------|-----------------------------|--------------------------------|
| マクロタスク   | 各イベントループの最後      | `setTimeout`, `setInterval`, `setImmediate`, `MessageChannel`, I/O |
| マイクロタスク | 各イベントループの中間      | `Promise.then`, `catch`, `finally`, `queueMicrotask` |

---

## 実行順の違い：コードで検証

```js
setTimeout(() => console.log('timeout'), 0);
Promise.resolve().then(() => console.log('promise'));
console.log('sync');
```

出力順：

```
sync
promise
timeout
```

### ✅ 理由

- `console.log('sync')`: Call Stack 上の同期処理
- `.then(...)`: Microtask Queue に追加
- `setTimeout`: Task Queue に追加
- Event Loop は、**同期 → Microtask → Task** の順で実行

---

## Microtask の優先度

```js
Promise.resolve().then(() => {
  console.log('first');
  Promise.resolve().then(() => console.log('second'));
});
```

出力順：

```
first
second
```

→ ✅ Microtask は**Event Loop内で完全に消化されるまで続く**

---

## `queueMicrotask` の使いどころ

```js
queueMicrotask(() => {
  console.log('executed last (but before setTimeout)');
});
```

→ ✅ UIをブロックせず、“でも極力早く”実行したいときに使える

---

## UIとイベントループ：ブロッキング設計を避ける

### ❌ 悪い例（同期処理でUIを固める）

```js
document.getElementById('btn').addEventListener('click', () => {
  // 長い処理
  for (let i = 0; i < 1e9; i++) {}
  alert('done');
});
```

→ ✅ イベント処理中は Call Stack が詰まるため、UI更新も遅延する

---

### ✅ 解決策：非同期化して分割実行

```js
document.getElementById('btn').addEventListener('click', () => {
  setTimeout(() => {
    for (let i = 0; i < 1e9; i++) {}
    alert('done');
  }, 0);
});
```

---

## 設計におけるベストプラクティス

| 目的                                     | 推奨戦略                          |
|------------------------------------------|----------------------------------|
| 優先度の高い非同期処理                   | `Promise.then` / `queueMicrotask` |
| 長い処理でUIを固めないようにしたい        | `setTimeout(..., 0)` で分割      |
| イベント後に直ちに実行（でも非同期）     | `queueMicrotask()`               |
| 複数非同期ステップを順序制御したい       | `async/await` + `Promise`        |

---

## よくある誤解

### ❌ `setTimeout(..., 0)` は“すぐに実行”される？

→ ❌ 違います。**“最速でも1ループ後”**  
→ ✅ Microtask (`Promise`) の方が先に処理される

---

### ❌ Promise の中に setTimeout を入れても Microtask にはならない

```js
new Promise(resolve => {
  setTimeout(() => {
    resolve('done');
  }, 0);
});
```

→ `setTimeout` はマクロタスク。Promise内でも Microtask にはならない

---

## 結語

JavaScriptの非同期処理は、**構文ではなく“タイミングの設計”である。**  
その制御の基盤となるのが、イベントループとタスクキューである。

- 同期 → Microtask → Macrotask の流れを理解することで、
- 非同期の「なぜ今動かない？」を制御できるようになり、
- UIとロジックの衝突を避けた**洗練された設計**が可能になる

**構文を知っていても、タイミングを知らなければ設計はできない。**  
イベントループとは、「時間の構文」である。
JavaScriptにおける再帰処理の設計戦略：末尾再帰・メモ化・分割統治の実装パターンと注意点


## 概要

再帰とは、**自己参照的に問題を解くアルゴリズム設計**である。  
単なるループの代替手段ではなく、以下のような場面で絶大な威力を発揮する：

- 再帰的データ構造（ツリー・グラフ・ネスト）  
- 分割統治アルゴリズム（クイックソートなど）  
- 動的計画法（DP）  
- メモ化によるパフォーマンス改善  
- 探索系アルゴリズム（DFS/BFS/バックトラック）

本記事では、JavaScriptでの再帰設計を**パターンベースで整理**し、**安全性・最適性・保守性**を両立する戦略を構築する。

---

## 1. 基本的な再帰構造

```js
function factorial(n) {
  if (n <= 1) return 1;
  return n * factorial(n - 1);
}

factorial(5); // 120
```

- ✅ ベースケース（終了条件）を必ず設定
- ✅ 漸進的に問題を小さくする構造

---

## 2. 末尾再帰（Tail Recursion）

```js
function factorialTail(n, acc = 1) {
  if (n <= 1) return acc;
  return factorialTail(n - 1, acc * n);
}
```

### ✅ 特徴

- 計算結果をそのまま返す構文 → **末尾再帰**
- 理論的にはスタックを消費しない
- ❌ JavaScriptでは**公式に最適化されていない（2025現在）**

→ 大規模な末尾再帰は**スタックオーバーフローを引き起こす**可能性あり

---

## 3. メモ化による高速化（Memoization）

```js
function fibMemo() {
  const cache = {};
  return function f(n) {
    if (n <= 1) return n;
    if (cache[n]) return cache[n];
    return cache[n] = f(n - 1) + f(n - 2);
  };
}

const fib = fibMemo();
fib(40); // 高速計算
```

- ✅ **重複計算を排除**
- ✅ 動的計画法（DP）との相性が良い
- ✅ 一度計算した結果を保持して再利用する設計

---

## 4. 分割統治の設計：クイックソート実装

```js
function quickSort(arr) {
  if (arr.length <= 1) return arr;

  const pivot = arr[0];
  const left = arr.slice(1).filter(x => x < pivot);
  const right = arr.slice(1).filter(x => x >= pivot);

  return [...quickSort(left), pivot, ...quickSort(right)];
}
```

- ✅ 再帰的にデータを分割して解く → **分割統治法**
- ❌ メモリ効率は非効率（slice/filterによるコピー）
- ✅ 関数型設計との親和性が高い

---

## 5. 再帰的データ構造の探索（ツリー）

```js
function walkTree(node) {
  console.log(node.value);
  for (const child of node.children) {
    walkTree(child);
  }
}
```

- ✅ ネスト構造を処理する王道パターン
- ✅ 再帰以外では冗長になりがち

---

## 再帰処理の設計判断フロー

```text
① データ構造がツリー状か？ → 再帰で走査

② 部分問題に分割して解けるか？ → 分割統治

③ 重複計算があるか？ → メモ化を導入

④ 再帰が深すぎてスタック限界に近い？ → ループ or Stackで置き換える

⑤ 計算の末尾で再帰している？ → 末尾再帰化して安全化（ただし最適化は期待できない）
```

---

## よくある落とし穴

### ❌ 無限再帰（終了条件の欠落）

```js
function recurse() {
  return recurse(); // ❌ StackOverflow
}
```

→ 🔧 常に「ベースケース」と「縮小構造」を明確に

---

### ❌ スタックオーバーフロー（深すぎる再帰）

```js
function count(n) {
  if (n === 0) return;
  count(n - 1);
}
count(100_000); // ❌ RangeError
```

→ 🔧 代替策：ループ / 自作スタック / setTimeoutによる分割実行

---

## 結語

再帰とは、「**構造の中に構造がある問題を、その構造のまま解く方法**」である。  
そしてそれは、単なる構文ではなく、**問題そのものの再定義**でもある。

- 末尾再帰：構文的安全性  
- メモ化：計算の最適性  
- 分割統治：設計の抽象性  
- スタック管理：実装の現実性

**設計された再帰は、あらゆる複雑さを最小構成に還元する。**  
それこそが、再帰の本質である。
クロージャの本質と設計戦略：状態保持とリークの境界を制するJavaScriptの関数設計

## 概要

クロージャ（Closure）は、JavaScriptの関数が**スコープ外の変数を保持し続ける能力**を指す。  
それは「関数の外で定義された変数が、関数の内側で使える」という表面的な便利さを超え、**状態と関数の統合（=関数による状態のカプセル化）**を実現する。

本記事では、クロージャの本質・使い所・メリット・設計上の注意点を構造的に整理し、**ただ使うだけでなく、使いこなすための戦略**を提示する。

---

## クロージャとは何か？

```js
function createCounter() {
  let count = 0;
  return function () {
    count++;
    return count;
  };
}

const counter = createCounter();
counter(); // 1
counter(); // 2
```

- ✅ `count` は `createCounter()` のスコープ内で定義された変数
- ✅ 内部関数が `count` を“捕捉（close over）”して保持している

→ これがクロージャ

---

## クロージャが使われる代表的パターン

### ✅ 状態のカプセル化（データの隠蔽）

```js
function userFactory(name) {
  let secret = 'classified';

  return {
    getName: () => name,
    getSecret: () => secret,
    setSecret: (s) => { secret = s; }
  };
}

const u = userFactory('toto');
u.getSecret();       // 'classified'
u.setSecret('X');    // 更新可
```

→ ✅ `secret` は外部から直接アクセスできず、関数経由でのみ操作可能

---

### ✅ 関数ファクトリ（設定を固定した関数を生成）

```js
function multiplier(factor) {
  return (n) => n * factor;
}

const double = multiplier(2);
double(5); // 10
```

→ ✅ パラメータを持った「関数の雛形」が生成できる

---

### ✅ コールバック内での状態保持

```js
function setupLogger() {
  let logs = [];
  return function (msg) {
    logs.push(msg);
    console.log(logs.join(' / '));
  };
}

const logger = setupLogger();
logger('A'); // A
logger('B'); // A / B
```

---

## クロージャを使うメリット

| 効果                | 説明                                       |
|---------------------|--------------------------------------------|
| データの隠蔽         | 直接アクセスできない変数として保持         |
| 状態の永続化         | 関数が実行された後も値が保持され続ける     |
| 高度な再利用性       | パラメータを記憶した関数を生成できる       |
| コールバックの文脈維持 | `setTimeout`, `Promise` 内などで状態を維持可能 |

---

## 設計上の注意点

### ❌ 意図しないメモリ保持（メモリリーク）

```js
function leak() {
  let huge = new Array(1_000_000).fill('x');
  return () => huge;
}
```

- ✅ `huge` はGCされない → 無駄にメモリを消費
- ❌ 呼び出されない関数でも変数を保持し続ける

→ 🔧 対策：**スコープの寿命を最小限に設計**

---

### ❌ クロージャで値が“固定”されていない場合の誤解

```js
let funcs = [];
for (var i = 0; i < 3; i++) {
  funcs.push(() => i);
}

funcs[0](); // 3 ❌
funcs[1](); // 3 ❌
```

→ 🔧 対策：`let` or IIFEでスコープを分離

```js
for (let i = 0; i < 3; i++) {
  funcs.push(() => i); // ✅ 0, 1, 2
}
```

---

## クロージャの使用判断フロー

```text
① 状態を外部から隠したい？ → クロージャでカプセル化

② 関数に設定を埋め込みたい？ → クロージャで関数ファクトリ

③ コールバック内で値を保持したい？ → クロージャで値を囲い込む

④ 状態が巨大 / 不定多数？ → クロージャは避け、構造体や外部記憶を使う
```

---

## 結語

クロージャは、単なる便利な“テクニック”ではない。  
それは「**関数に状態を持たせ、設計に責任を与える構文**」である。

- 関数が“値を記憶する”ことで、**一貫性と隠蔽性を同時に実現**
- 外部から見えないスコープが、**ロジックの防御壁**となる
- ただし、“覚えてしまう”がゆえに、**適切な開放・スコープ設計が不可欠**

**クロージャとは、“設計された記憶”である。**
【第１１回 Serverworks 井出真悠子さん】2024 Japan AWS Jr. Champions インタビュー企画

こんにちは！2024 Japan AWS Jr. Championsの[@yakisobapan](https://qiita.com/yakisobapan)です。

AWS Japanが6月に開催したAWS Summit Japanにて、2024 Japan AWS Jr. Championsが発表されました。Jr.Championsは、AWSを積極的に学び、アクションを起こし、周囲に影響を与えている若手エンジニア向けの表彰プログラムとなっております。Jr.Championsについて多くの方に知ってもらいたいため、表彰された方々にインタビューをしていきます。
第11回目は、Serverworks 井出真悠子さんです！

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2737731/98a52000-70e4-49f3-97a0-b5e67240e51b.jpeg">


https://aws.amazon.com/jp/blogs/psa/2024-japan-aws-jr-champions/


# 質問１：これまでの経歴、現在の業務、AWSを知った経緯を教えてください。
2021年にServerworksへ新卒入社し、インフラストラクチャの構築、運用を行ってきました。特にSRE(Site Reliability Engineering)の業務は、現在まで継続して従事しています。最近は改善活動として、CI/CDパイプラインの導入やCDKを用いたIaC、セキュリティ強化にも携わっています。
（2025年3月 よりセキュリティ専門のチームで業務をしています）
AWSは、就職活動中にIT業界について調べている過程で知り、学び始めました。

# 質問２：Jr.Championsを目指した理由、選出につながったと考える活動があれば教えてください。
きっかけは上長よりJr.Championsのプログラムを薦められたことです。選出されたらアウトプット活動の場を広げられると思ったため、Jr.Championsを目指しました。

選出につながったと思う活動の一つとして、JAWS CDK支部のイベントで登壇をしたことがあります。年に一度の大きなイベントということもあり、大人数の前での発表となりました。失敗するにしても若いうちのほうがいいと思いチャレンジしました（笑）周りの方からのフォローをもらいつつやり切り、それが大きな経験となりました。

# 質問３：Jr.Championsとして現在どのような活動をしていますか。
自身のアウトプット活動を行いつつ、Jr.Champions内の運営活動を行っています。Jr.Champions内勉強会の企画・運営や、アウトプット活動を促すようなイベントの開催を行っています！運営として活動することで、自身のアウトプット機会の創出にもなっています。

# 質問４：Jr.Championsに選出されてよかったことはありますか。
Jr.Champions活動を通して社外の方と交流できるため、普段業務で関わらない領域を知ることができます。また、具体的な他社事例なども交えて聞けることがよかったことです！

# 質問５：Jr.Championsの活動で大変だったことはありますか。
アウトプット活動とともに運営活動も複数行っているため、少し忙しい時期もありました。ただ、皆さんと交流できるので、楽しめて活動できています！

# 質問６：今後の夢や目標はありますか。
基本的には、「おもしろそう」「興味深い」と思った方に向かって進んでいます（笑）その過程で障壁が出てくることはありますが、チャレンジする精神でいます！
また、Jr.Championsとして活動している中で、Top Engineers選出を視野に入れ始めたので、それに向けてアウトプット活動を続けていきたいと思います。

# 質問７：Jr.Championsを目指す若手に向けてメッセージをお願いします。
登壇をする機会や、社外コミュニティへの参加など、何かチャレンジするチャンスがあったら、飛び込んでしまった方がいいことあると思います！

# 質問８：全体を通しての質問
## 好きなAWSサービスはなんですか。
CDKですね。
インフラストラクチャをプログラミング言語で記述し管理できるため、各業務領域の壁を取り払うことができるかなと思います。
あと、単純に便利だなあと（笑）

## re:Invent2024 で印象に残っていることはありますか。
AWS GameDayとAWS Jamに現地で参加したことです。コンテンツを通してエンジニアと交流し、スキルの使い方や仕事の仕方などを勉強させてもらいました。思い出深いです！

# 最後に
井出さんは、Jr.Championsコミュニティの中でもマルチに活動されていて、幅広い方と交流している印象があります。

また、業務で培ったIaCのスキルを強みとし大規模イベントで登壇するなど、その分野で地位を確立されていると感じます。

新しいことやチャレンジをいとわないマインドを持っているので、今後もどんどん活動の場を広げていくのではと思います！

次回のインタビューもお楽しみに！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2737731/03028be3-748e-4c93-afe0-0988ef473dc8.png)
【ネットワーク】socket connect

# はじめに

こんにちは。アメリカに住みながら独学でエンジニアを目指しているTairaです。

「ネットワークはなぜつながるのか」を使用してネットワークを学習しています。
現在第2章まで進んでいて、Httpのsocketのつながり方を学習しているので整理するために記事を書きたいと思います

## 1. ソケットの作成

アプリケーションはまず、通信インターフェースであるソケットを作成します。Unix系システムでは、`socket()` システムコールを使ってソケットを生成します。

```c
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
```

- `AF_INET`: IPv4を使用することを示す
- `SOCK_STREAM`: TCPを使用する（接続指向型）
- `0`: プロトコルはデフォルト（TCP）を使用

カーネル内にソケット用のリソースが確保され、ファイルディスクリプタ（`sockfd`）が返されます。

## 2. connectシステムコールで接続要求

次に、アプリケーションは`connect()`を呼び出し、相手サーバーのIPアドレスやポート番号をプロトコル・スタックに知らせます。

```c
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(80); // HTTPのポート例
inet_pton(AF_INET, "192.168.1.1", &server_addr.sin_addr);

connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
```

`connect()`により、プロトコル・スタックに相手サーバーの情報が渡され、TCP接続の確立が開始されます。

### プロトコル・スタックから相手サーバーへの接続の流れ

1. **ソケット情報の登録**: カーネル内で送信元ポート、宛先ポート、送信元IP、宛先IPなどがソケットに関連づけられます。
2. **TCPセグメントの生成**: TCPヘッダーに制御情報（SYNビットなど）を含むセグメントが作成されます。
3. **IPパケットの生成と送出**: TCPセグメントはIP層でIPパケットにカプセル化され、送信インターフェースを通じてネットワークに送信されます。
4. **ルーティングと転送**: IPパケットはルータを経由して、宛先サーバーまで到達します。
5. **サーバー側での受信と応答**: サーバーがSYNを受信し、SYN+ACKを返すことで応答します。

このように、`connect()`を呼ぶことで、カーネルのプロトコル・スタックが動作し、実際にネットワークを通じて相手サーバーとの接続が開始されます。

## 3. 制御情報の役割

制御情報はクライアントとサーバー間の通信を管理するために必要なもので、TCPヘッダーには以下のような重要な情報が含まれています。

- **送信元ポート番号**: クライアント側のポート番号を示します。
- **宛先ポート番号**: サーバー側のポート番号を示します。
- **シーケンス番号**: 送信されるデータの順序を管理するための番号。
- **ACK番号**: 正しく受信したことを相手に通知するための番号。
- **コントロール・ビット**: SYN、ACK、FINなど通信制御のためのフラグ。

これらの情報はソケットに記録され、プロトコル・スタックの動作を適切にコントロールする役割も果たしています。

---

## まとめ

アプリケーションからTCP/IPスタックを介してサーバーへ接続する流れは以下の通りです。

1. `socket()`でソケット作成
2. `connect()`でIP・ポート番号などをプロトコル・スタックに通知し、接続要求
3. プロトコル・スタックがTCP/IPパケットを生成・送信し、サーバーに到達
4. 接続確立後、データ通信が可能になる
結局、SQLの実行計画って何が嬉しいのって話 その1 ~基本とSQLパフォーマンスの初歩~

## はじめに
「SQLのパフォーマンスがよくないので実行計画を確認してください。」とは言われても……
何を確認してどうSQLをチューニングすればいいの？実行計画の何が嬉しいんだ？
そもそも実行計画ってなに？って感じなので、
本記事では、<b>実行計画とは何か、EXPLAINを使った実行計画の見方、SQLの最適化方法</b>についてまとめます。

<br>

## そもそも実行計画ってなに？
>実行計画とは、SQLクエリを実行するための「手順書」のようなものです。具体的には、データベースがどのような手法でクエリを実行し、どのリソースをどの順番で利用するかを示した計画です。言い換えれば、実行計画はデータベースが「どのようにしたら最も効率的にクエリを実行できるか」を計算して導き出した方法をまとめたものと言えます。

つまり、データベースが判断したパフォーマンスの高いSQLを具体的に確認することができて、どうしたらより短い時間でSQLを実行できるか、具体的な方法をまとめたもの？

<br>

## 実行計画を確認する目的
実行計画を確認する目的は、クエリが意図した通りに実行されているか、
またはどの部分でパフォーマンスの低下が生じているかを確認すること。
具体的には、以下のような情報を得ることができる。

### テーブルのスキャン方法
テーブルを「フルスキャン」しているのか、それともインデックスを利用して効率よくデータを検索しているのか。

### 命令のコスト
命令の開始コスト（スキャン対象の行数に関わらずかかるコスト）や、命令の終了コスト（スキャン対象行数が増えると増えるコスト）。

### 推定行数
実行計画に基づいてデータベースが予測するスキャン対象となる行数。

<br>

## EXPLAINってどうつかうのよ
普段使用するSQLの先頭に<b>EXPALIN</b>をつけるだけでいいらしい
実行するとどのようにインデックスが利用され、どのテーブルがスキャンされるのかがわかる
```
// SQL
EXPLAIN SELECT * FROM users WHERE age > 10;

// 実行結果
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+
|  1 | SIMPLE      | users | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    1 |   100.00 | NULL  |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+
```

### EXPLAINの出力内容
| 項目名             | 意味                                      |
| --------------- | --------------------------------------- |
| `id`            | クエリ内での実行ステップの識別子（サブクエリなどで分かれる）          |
| `select_type`   | クエリの種類（SIMPLE, PRIMARY, SUBQUERY など）    |
| `table`         | 対象のテーブル名                                |
| `type`          | **結合タイプ（アクセス方法）**。パフォーマンスに重要な指標         |
| `possible_keys` | 使用可能なインデックス候補                           |
| `key`           | 実際に使われたインデックス                           |
| `key_len`       | インデックスの長さ（バイト）                          |
| `rows`          | 検索対象となった行数の見積もり                         |
| `Extra`         | その他の実行上の情報（Using index, Using where など） |


### type(データへのアクセス方法)による性能の目安
| `type`             | 説明                  | 性能目安    |
| ------------------ | ------------------- | ------- |
| `const` / `eq_ref` | インデックス1件一致（理想）      | ◎ 非常に高速 |
| `ref`              | インデックスで部分一致         | ○ 高速    |
| `range`            | 範囲検索（BETWEEN, >, <） | ○ 良い    |
| `index`            | 全インデックススキャン         | △ 遅め    |
| `ALL`              | **フルテーブルスキャン**      | ❌ 非効率   |


<br>

## まとめ
・SQLクエリのパフォーマンスを最適化するためには、実行計画を確認することが大切
・EXPLAINを使用することで、SQLがどのように実行されるかを把握し、インデックスの利用状況やテーブルスキャンの方法を確認できる
・クエリの最適化を行うことで、アプリケーションのパフォーマンスを大きく改善することができる

その2は具体的に実行計画を利用した、SQLパフォーマンスの改善方法
について書こうと思います
[結局、SQLの実行計画って何が嬉しいのって話 その2 ~クエリの最適化とパフォーマンス改善~](https://qiita.com/minorin_/items/a353567375c1a120b76a)
rubocopのプラグインの呼び出し方が変更されていた

## はじめに
先日rubocopとその拡張機能であるrubocop-rspecのgemを現在の最新版にアップデートし、rubocopを実行したところ、以下のメッセージが表示されました（rubocopは1.75.1、rubocop-rspecは3.5.0）。

```
$ rubocop
rubocop-rspec extension supports plugin, specify `plugins: rubocop-rspec` instead of `require: rubocop-rspec` in /xxxxx/.rubocop.yml.
```

## なにこれ？

rubocop 1.72 からプラグインシステムが導入されたそうです。
https://docs.rubocop.org/rubocop/plugin_migration_guide.html

上記のガイドから、その目的をブラウザの日本語翻訳機能で翻訳して抜粋します。
>RuboCop 拡張機能の改良された API (プラグインと呼ばれる) が導入され、RuboCop を拡張するための公式に文書化された方法が提供されます。この API はlint_rollerライブラリによって提供され、必要に迫られて登場した以前の文書化されていない非公式の方法を置き換えることを目的としています。

つまり非公式だった拡張機能を公式にしたので、呼び出し方も変えた感じでしょうか。

## このメッセージの消し方は？

.rubocop.ymlで拡張機能の呼び出し方を変更すればOK。
というか、requireをpluginsにするだけで簡単。

### before
```.rubocop.yml
require: rubocop-rspec
```

### after
```.rubocop.yml
plugins: rubocop-rspec
```

※複数の設定が必要なら以下の様な感じ
```.rubocop.yml
plugins:
 - rubocop-rspec
 - rubocop-performance
```

以下も参考になります
https://docs.rubocop.org/rubocop-rspec/usage.html
Google Cloud Storageまとめ

# Google Cloud Storage（GCS）とは

Google Cloud Storage (GCS) は、Google Cloud が提供する**グローバルで安全かつスケーラブルなオブジェクトストレージサービス**です。 画像データ、テキストデータ、動画データ、音声ファイルなど、あらゆる種類の普遍的なデータを保管するために利用できます。Amazon S3 や Azure Blob Storage といった他のクラウドストレージサービスと同様の目的で提供されています。

# GCS でのデータの保存方法

GCS では、**バケットと呼ばれる箱のようなもの**を作成し、その中に**オブジェクト（データ）**を保存します。データを保存する際には、まずバケットを作成する必要があります。

## バケットの作成と命名

バケットを作成する際には、**グローバルで一意な名前**をつける必要があります。世界中でまだ使われていない名前を選択する必要があり、もし既存の名前を使用しようとするとエラーが表示されます。バケット名には日付などを加えることで、一意性を確保する方法があります。

## ロケーションタイプの選択

バケットの作成時には、**データをどこに保存するか**というロケーションタイプを選択する必要があります。ロケーションタイプには、主に**リージョン、マルチリージョン、デュアルリージョン**の3つがあります。

*   **リージョン**: 単一のリージョン内のデータセンターにデータを保存するタイプです。東京や大阪といった特定のリージョンを選択できます。**レイテンシが最も低い**という特徴がありますが、そのリージョンで障害が発生した場合、データの可用性が懸念されます。
*   **マルチリージョン**: 複数のリージョンにあるデータセンターにデータを保存することで、**高い可用性**を実現します。アジアや EU、US など、エリアを選択する形となり、ユーザーはどのリージョンにデータが保存されているかを指定したり把握したりすることはできません。
*   **デュアルリージョン**: **2つの指定したリージョン**にデータを保存し、高い可用性を保ちます。どのリージョンにデータを保存するかを指定できるのが特徴です。現在、選択できる組み合わせは限られており、例えば東京と大阪といった組み合わせが可能です。国内にデータを保管する必要があり、かつ保存場所を把握しておきたい場合に適しています。

## ストレージクラスの選択

バケットの作成時には、**ストレージクラス**を選択します。ストレージクラスは、データへのアクセス頻度や保存期間によって使い分けることが推奨されており、主に**スタンダード、ニアライン、ゴールドライン、アーカイブ**の4つがあります。

*   **スタンダード**: **頻繁にデータへアクセスする場合**に適しています。
*   **ニアライン**: **月に1回未満**の頻度でデータへアクセスする場合に適しています。
*   **ゴールドライン**: **四半期に1回未満**の頻度でデータへアクセスする場合に適しています。
*   **アーカイブ**: **年に1回も満たない**頻度でしかデータへアクセスしない場合に適しています。

**保存料金は、スタンダードクラスが最も高く、ニアライン、ゴールドライン、アーカイブと順に安くなります**。しかし、**データ取得にかかる料金は、保存料金とは逆にアーカイブクラスが最も高く**なります。そのため、アクセス頻度と料金のバランスを考慮してストレージクラスを選択することが重要です。

# データのアップロードと確認

バケットを作成後、そのバケットにファイルをアップロードすることができます。Google Cloud コンソールの画面から、ファイルのアップロードを選択し、ローカルにあるデータをGCSのバケットに保存できます。アップロードしたデータはコンソール画面から確認することが可能です。

# GCS の活用例

GCS は、以下のような様々な用途で活用できます:

*   Web サービス提供のための画像や動画などの**コンテンツの保存**。
*   **データ分析**のためのデータの保管。
*   **障害復旧**のためのバックアップデータの保管。

GCS を利用することで、多様なデータを簡単かつ安全に保存し、必要に応じてアクセスすることが可能になります。
【学習】Perlでフォーム修正！DBのIDで職業と飲み物を管理したみた

## はじめに
前回？職業と飲み物のテーブル構造で`id`を使用して管理するようにしました。

https://qiita.com/wa-chan222/items/5794b40c458e9d943f3c


ですのでフォーム側で**データベースのIDを使って管理できるように修正する**という作業が必要になります。

修正前と後、簡単なことですが、IDを使用しない方法と使用する方法でどんなコードになるのか把握するためにも記事にして残しておきたいと思います


👇確認ページは「ID表示」から「名前表示」に修正済み

https://qiita.com/wa-chan222/items/72fa9cffd927ac3da4ea




## 職業の選択フォーム
```.修正前
<select name="occupation" class="form-control" required>
    <option value="">選択してください</option>
    <option value="会社員">会社員</option>
    <option value="学生">学生</option>
    <option value="主婦（夫）">主婦（夫）</option>
    <option value="その他">その他</option>
</select>
```

```.修正後
<select name="occupation_id" class="form-control" required>
    <option value="">選択してください</option>
    <option value="1">会社員</option>
    <option value="2">学生</option>
    <option value="3">主婦（夫）</option>
    <option value="4">その他</option>
</select>
```

- データベースのoccupation_idと対応させる
- valueに職業のIDをセットするように変更（例：会社員は1）


## 飲み物の選択フォーム
```.修正前
<input class="form-check-input drink-checkbox" type="checkbox" name="drink" value="水" id="water">
<label class="form-check-label" for="beer">水</label>
```

```.修正後
<input class="form-check-input" type="radio" name="drink_id" value="3" id="water">
<label class="form-check-label" for="water">水</label>
```

- valueを飲み物のIDに変更（例：水は3）


👇Laravelですが参考記事。

https://onebitious.net/laravel_checkbox/#google_vignette


## サーバー側の変更
フォームの修正後、サーバー側ではoccupation_idとdrink_idを正しくデータベースに保存するように変更する必要があります。
今回は下記のように修正を行いました

```
my $occupation_id = $c->param('occupation_id');

my @drink_id = $c->param('drink_id');

```


## さいごに
もっといいコードの書き方があるのかもしれませんが、一応目標は達成されたので、ここまで。
今回の記事が何か参考になれば幸いです。
新人エンジニアがAWS Certified Cloud Practitionerに合格した話

## 1. 受けようと思った理由

完全未経験＆ド文系から、エンジニアという職に就かせていただいて早9ヶ月。開発過程を広く浅く経験してきたのですが、このタイミングで資格取得を目的に、何か体系的な知識を身につけたいと思うようになりました。そこで、インフラの知識がないことがネックになって仕事が進まないことが１つの悩みだったので、まずは会社で使っているawsの勉強から始めてみよう！ということで、入門試験のCCPから取り組んでみました。

## 2. 勉強ツール

主に使った勉強ツールはこんな感じです↓

- [AWS Skill Builder](https://aws.amazon.com/jp/training/digital/)：AWS公式の無料学習動画を見られる。使ったコースは、「**AWS Cloud Practitioner Essentials (日本語)」。**
- [AWS認定資格試験テキスト AWS認定 クラウドプラクティショナー](https://www.amazon.co.jp/AWS%E8%AA%8D%E5%AE%9A%E8%B3%87%E6%A0%BC%E8%A9%A6%E9%A8%93%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88-AWS%E8%AA%8D%E5%AE%9A-%E3%82%AF%E3%83%A9%E3%82%A6%E3%83%89%E3%83%97%E3%83%A9%E3%82%AF%E3%83%86%E3%82%A3%E3%82%B7%E3%83%A7%E3%83%8A%E3%83%BC-%E6%94%B9%E8%A8%82%E7%AC%AC3%E7%89%88-%EF%BC%A1%EF%BC%B7%EF%BC%B3%E8%AA%8D%E5%AE%9A%E8%B3%87%E6%A0%BC%E8%A9%A6%E9%A8%93%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88-%E5%B1%B1%E4%B8%8B%E5%85%89%E6%B4%8B/dp/4815625387/ref=asc_df_4815625387?mcid=dbb67c83bc76327db6993fb05dea0b92&th=1&psc=1&tag=jpgo-22&linkCode=df0&hvadid=707442440817&hvpos=&hvnetw=g&hvrand=15247524776338909918&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=9198804&hvtargid=pla-2284462936951&psc=1&gad_source=1)：いわゆる緑本。
- [【CLF-C02版】この問題だけで合格可能！AWS 認定クラウドプラクティショナー 模擬試験問題集（6回分390問）](https://www.udemy.com/course/aws-4260/?couponCode=25BBPMXACCAGE2)：Udemyで、一番評価が高そうだった模擬問題集。テキストで見たことないサービスがわんさか出てきて最初はびっくりしました。

## 3. 勉強手順

0 . 勉強前の筆者のAWS経験はこんな感じでした。
    - Cloud Watchでアプリのログを見る
    - LambdaでアプリのログをSlackに流す処理を作成する
    - S3にファイルを入れたり出したり、boto3で操作したりする
    - Secrets Managerで環境変数を管理する
    - Cloud9でプログラミングする
    - 既存のCDを使ってECSにデプロイする（ECSという言葉は知っていた）
    - など…

1. まず、skill builderの無料動画を一通り見ました。早送りしたりして、年末年始、1日2~3時間使えば見切れるくらいの量でした。
2. 次に、Udemyの模擬試験を解きました。と言っても、この頃にはなぜか1月末に差し掛かってました。
3. ↑が難しすぎてびびったので、いわゆる緑本を読み始めました。
4. 次に、skill builderに戻って、要点整理をしました。
5. 再度、Udemyの模擬試験を解き直しました。

## 4. 勉強してよかったなと思うこと

一番は、これまでハテナだらけだったインフラ関係の会話で、話が通じる機会が増えたことです。丁度この勉強をしている頃に、WAFのSQLインジェクション対策のルールについて話すことがあり、「あ！ここCLF-C02でやったところだ！」と某DMに封入されてる漫画の主人公の気分になれました()。

基本情報tキーワードにも触れられたことも良かったです。

## 5. へぇ！とか、面白いと思ったポイントまとめ

一番驚いたのは、AWSサービスの守備範囲の広さでした。勉強する前は、AWSはwebサービスを支えるサービスだと思っていましたが、機械学習やIoT、さらには衛星からデータを受信して処理するサービスまで…多分使わないんだろうけど、面白そうなサービスがたくさんありました。

それから、AWS CAFなど、クラウド導入を進める上での技術的・組織的なベストプラクティスが提供されていることも新鮮でした。ユーザー任せ、エンジニア任せのクラウド導入でなく、非技術的な面までサポート体制が整っていて感動しました。こちらも、個人開発ではあまり意識することのない視点だったので、CCPを勉強して良かったなーと思います。

もちろん、普段の開発で使っているサービスをより詳しくしれたのも良い機会でした！

## 6. まとめ

「資格試験なんて意味がない！実務実務！」というお声もよく聞きますが、個人的に、資格取得目的で体系的な知識を身につけることは、とても有意義でした。実務と座学のバランスをとって、精進していきたいと思います。
ちなみに、CLF-C02に合格した現在は、スペシャリスト系なら計算が少ない＆応用情報の過去問暗記で対応できることを知り、データベーススペシャリストの勉強をしています。多分、来年くらいに受けてみます（宣言）。
非同期処理と非同期通信の違い

非同期処理と非同期通信の違いについて。

## そもそも非同期とは
非同期とは、 **連続する事象があった場合に、前の事象の完了を待たずに次の事象が実行される** こと。

まだまだ抽象的ですが、これを踏まえて非同期処理と非同期通信についても見ていきましょう。

## 非同期処理とは
非同期処理とは、 **ソースコード上の前の処理の完了を待たずに次の処理が実行される** こと。

## 非同期通信とは
非同期通信とは、 **通信が完了するのを待たずに、他のあらゆる処理(UI操作や新たなリクエストなど)を実行できる** こと。

JavaScriptで非同期通信を実装する場合、fetchやXMLHttpRequest等のwebAPIを使う必要があります。fetchは非同期処理を行う関数(非同期関数)のため、非同期通信は、非同期処理を使って実装される。

## 参考資料
https://zenn.dev/estra/books/js-async-promise-chain-event-loop/viewer/f-epasync-asynchronous-apis#%E3%80%8C%E9%9D%9E%E5%90%8C%E6%9C%9F%E3%80%8D%E3%81%A8%E3%81%84%E3%81%86%E6%A6%82%E5%BF%B5