OmniAICreator/Qiita-1.07M huggingface dataset:
GithubからBigQueryへの自動リリース

## GitHubからBigQueryへデータを自動反映する方法: ネットワーク設定と手順

データのリアルタイム分析や自動化が重要視される現代において、GitHubからGoogle Cloud Platform（GCP）のBigQueryへデータを自動反映する方法は、効率的なデータパイプラインを確立する上で有益です。この記事では、必要なネットワーク設定と手順を詳しく解説します。

### 必要な準備

1. **Google Cloud Platform (GCP) プロジェクトの設定**
   - GCPのコンソールでプロジェクトを作成し、BigQueryで使用するデータセットとテーブルを準備します。

2. **サービスアカウントの作成とキーの生成**
   - GCPのIAM & Adminからサービスアカウントを作成し、「BigQuery Data Editor」など適切なロールを割り当てます。
   - サービスアカウントのJSONキーを生成し、ダウンロードします。

3. **GitHubリポジトリのセットアップ**
   - 自動化スクリプトやワークフローを含むGitHubリポジトリを作成します。

### GitHub Actionsを使用した自動化

GitHub Actionsを活用して、定期的にデータをBigQueryにアップロードする自動化を設定します。以下はその手順です。

#### 1. GitHub Secretsにサービスアカウントキーを追加

GitHubリポジトリの設定ページで、サービスアカウントのJSONキーをGitHub Secretsに追加します。これにより、安全に認証情報を保護し、ワークフローからアクセスできるようにします。

#### 2. GitHub Actionsのワークフローファイルを作成

GitHub Actionsのワークフローファイルを作成し、BigQueryへのデータアップロードを自動化します。以下は、例として使用できる基本的なワークフローの設定です。

```yaml
name: Upload to BigQuery

on:
  push:
    branches:
      - main  # 変更が発生したブランチ

jobs:
  upload:
    runs-on: ubuntu-latest

    steps:
    - name: Checkout code
      uses: actions/checkout@v2

    - name: Set up Google Cloud SDK
      uses: google-github-actions/setup-gcloud@v1
      with:
        project_id: your-gcp-project-id
        service_account_key: ${{ secrets.GCP_SERVICE_ACCOUNT_KEY }}

    - name: Authorize Docker to push to GCR
      run: gcloud auth configure-docker

    - name: Upload data to BigQuery
      run: |
        bq --location=us load --autodetect --replace --source_format=CSV your_dataset.your_table path/to/your/data.csv
```

### ネットワーク設定とセキュリティ

GitHub Actionsは通常、特別なネットワーク設定を必要としませんが、特定のIPレンジやFirewall設定を追加することでアクセス制御を強化できます。これにより、セキュリティを確保しつつデータの安全な移動を実現できます。

#### 4.1 APIの有効化

1. **GCPコンソール**で「API & Services」 > 「Dashboard」に移動。
2. 「Enable APIs and Services」をクリック。
3. 「BigQuery API」を検索し、有効化します。

#### 4.2 ファイアウォールの設定

1. **社内ネットワークからのアクセスのみ許可**:
   - **VPCネットワーク** > **Firewall rules**に移動し、新しいファイアウォールルールを作成。
   - **インバウンドルール**として、社内ネットワークのIPレンジ（例: `192.168.1.0/24`）を許可。

2. **特定のIPアドレスからのアクセスを許可**:
   - **VPCネットワーク** > **Firewall rules**に移動し、新しいファイアウォールルールを作成。
   - **インバウンドルール**として、特定の静的IPアドレス（例: `203.0.113.0`）を許可。

#### 4.3 Private Google Accessの設定

- **VPCネットワーク** > **VPC networks**に移動し、対象のVPCネットワークを選択。
- 「Private Google Access」を有効にし、プライベートIPアドレスからGoogleのAPIやサービスにアクセスできるように設定。

### テストとモニタリング

1. **ワークフローのトリガー**: コードをプッシュしてワークフローが正しくトリガーされるか確認します。
2. **ログの確認**: GitHub Actionsのログをチェックし、認証やクエリ実行に問題がないか確認します。
3. **デプロイのモニタリング**: デプロイ後にBigQueryデータセットやテーブルが正しく更新されているか確認します。

### チームでの運用

#### 7.1 コミュニケーションとコラボレーション

- **定期的なレビュー**: プルリクエストを通じてコードのレビューを実施します。
- **ドキュメント整備**: READMEやWikiを利用してプロジェクトの情報を共有します。

#### 7.2 アクセス権限の管理

- **GitHubリポジトリのチーム管理**: 必要なメンバーに適切な権限を付与します。
- **GCPプロジェクトのIAM管理**: 必要なメンバーに適切な役割を付与します。

### おわりに

GitHubからBigQueryへのデータ自動反映は、ビジネスやプロジェクトにおいてデータ活用の重要な一環です。適切な設定と手順を踏むことで、データの流れを効率化し、リアルタイムの分析や洞察を容易にすることが可能です。

この記事を参考にして、あなたのデータパイプラインを強化し、ビジネスの成長に貢献するGitHubとBigQueryの統合を実現しましょう。
【Git】Git管理下のディレクトリ名を小文字から大文字に変更する

# 初めに
Components/atomsディレクトリを作成しました。

git pushし複数のPRを経て、ディレクトリ名はatomsではなくAtomsで作成すべきだったことに気づきました。
# 問題
ローカルのディレクトリ名を変更しコミット。

```npm run build```でビルドした際、importのパスが合わずエラー。


どうやらデフォルトだと`git config core.ignorecase`がtrueのため、ファイル名の大文字と小文字の変更コミットはGitに反映されないようです。
```zsh
core.ignoreCase
If true, this option enables various workarounds to enable Git to work better on filesystems that are not case sensitive, like FAT. For example, if a directory listing finds "makefile" when Git expects "Makefile", Git will assume it is really the same file, and continue to remember it as "Makefile".
The default is false, except git-clone[1] or git-init[1] will probe and set core.ignoreCase true if appropriate when the repository is created.
```
[Gitの公式](https://git-scm.com/docs/git-config/2.14.6#Documentation/git-config.txt-coreignoreCase:embed)

# 解決方法
まずは設定の変更です。


gitのconfig設定にはグローバルとローカルの2種類あり、`git config --local --list`でローカルのconfig一覧を出力できます。

今後プロジェクトで大文字・小文字の変更を検知する設定にしたい場合は、`git config core.ignorecase false`のコマンドで変更できます。（今回だけ対応したいのであれば設定変更は必須ではありません）
```
$ git config core.ignorecase true # 大文字と小文字を区別しない（デフォルト）
$ git config core.ignorecase false # 大文字と小文字を区別する
```


そして、既にgit追跡済みのファイルの対応が必要です。

### **ディレクトリ名の小文字を大文字に変更したのをgit管理に反映させる**
ex): components/atoms　→　Components/Atoms

**```git rm --cached```を使う**

- 1, ファイル名を変更

- 2, ```git rm --cached```で古いファイル名を削除

- 3, 変更したファイル名を```git add```し``` git commit```をすると、Gitの追跡しているファイル名が変わります。

```zsh
mv exampleFile.txt ExampleFile.txt
git rm --cached exampleFile.txt
git add ExampleFile.txt
git commit -m "ファイル名の変更"
```
これで、ファイルの中身を編集せずにファイル名のみ小文字→大文字の変更をGitに反映させることができました。
# 参考

[【Git】ファイル名の大文字小文字を変更する(Zenn記事)](https://zenn.dev/aki_artisan/articles/f7a6ff22215d4c)
20230709_ユースケース図

@startuml
left to right direction
actor "システム管理者" as Admin
actor "共通認証システム" as AuthSystem
rectangle "反映送信処理システム" {
  usecase "1. データ反映" as UC1
  usecase "1.1 新規部店追加" as UC1_1
  usecase "1.2 部店名称変更" as UC1_2
  usecase "1.3 部店廃止" as UC1_3
  usecase "2. 一括反映" as UC2
  usecase "2.1 休職・本部詰め対象処理" as UC2_1
  usecase "2.2 子部店・常駐元部店名称反映" as UC2_2
  usecase "2.3 履歴DB処理" as UC2_3
  usecase "3. 送信処理" as UC3
  usecase "3.1 CSVファイル作成" as UC3_1
  usecase "3.2 ファイル送信前validation" as UC3_2
  usecase "3.3 ファイル送信" as UC3_3
}
Admin --> UC1
Admin --> UC2
Admin --> UC3
UC1 ..> UC1_1 : <<include>>
UC1 ..> UC1_2 : <<include>>
UC1 ..> UC1_3 : <<include>>
UC2 ..> UC2_1 : <<include>>
UC2 ..> UC2_2 : <<include>>
UC2 ..> UC2_3 : <<include>>
UC3 ..> UC3_1 : <<include>>
UC3 ..> UC3_2 : <<include>>
UC3 ..> UC3_3 : <<include>>
UC3_3 --> AuthSystem
@enduml


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3782003/ad3b17b8-f1e5-f7fa-c2fa-58ce6f54fdaa.png)
polacodeに貼り付けすると内容が消える

## 現象

VS Codeプラグイン「Polacode」にプレーンテキストを貼り付けるとプレビューが空になります。
コンソールの内容をコピペしても同様にプレビューが空になります。

### 再現する環境 1
- **OS**: ZorinOS 17.1 Core
- **CPU**: AMD® Ryzen 9 4900h with radeon graphics × 16
- **エディタ**: Cursor 0.035.0
- **Polacode**: 識別子`pnp.polacode` v0.3.4

### 再現する環境 2
- **OS**: Windows 11 Home 23h2 
- **CPU**: 12th Gen Intel(R) Core(TM) i7-12650H   2.30 GHz
- **エディタ**: VS Code 1.91.0
- **Polacode**: 識別子`jeff-hykin.polacode-2019` v0.6.1

## 対策（回避方法）

新しいテキストファイルを開き、一度プレビューしたいテキストを貼り付けます。
その後、新しく開いたテキストファイルタブの言語モードを「プレーンテキスト」以外にしてからコピーします。
polacodeに貼り付けるとプレビューに反映され、ファイルに保存してもテキスト部分が空になりません。
QiitaCLIで投稿マラソンに参加していて気付いた、仕様による致命的な課題と解決アプローチ


## 本稿でいいたいこと
QiitaCLIを使ってQiita投稿イベントに記事を投稿する時は、Webエディタが必須になるためupdated_atが必ず更新される事を認識しておこう

### なぜか？
- QiitaCLIで完結できず、Webエディタでの操作が必須
- QiitaCLIで投稿イベントへの紐付けができない
- Webエディタで本文もタグもタイトルも変えずに、イベントを追加する更新をしただけでも、 `npx qiita pull` でコンフリクトを起こしてしまう

## 当初想定と罠
QiitaCLIで記事を書けばGitHubのコントリビューションにも反映されるし、Qiitaにも投稿できるしでメリットしかない！という発想だった。
ZennもCLIを使っているので、その感覚で考えていたところもある。

ここに、Webエディタでも編集できることの問題に気付くのは今日まで時間がかかってしまっていた。
いや、違和感はあったがなんとか付き合っていこうと考えていた。

が、どうしても受け入れられなくなった。
「QiitaCLIで出来ないことをWebエディタでフォローすれば大丈夫でしょ」という感覚だったが、Webエディタを使うとどう足掻いてもコンフリクトを起こしてしまう
回避する手段もあるが、現実的ではない。

## 仕様を確認する
### QiitaCLI
QiitaCLI-CIで新規に記事を投稿する場合、updated_atとidを空欄にしておくと、新しく記事の投稿情報が得られる
具体的には以下

- `npx qiita push` 時に記事が投稿され、同時にupdated_atとidが更新される
- QiitaCLI-CIは、更新された後の情報を適用するようにgitにコミットする

ここだけ切り取ると、何もおかしなところはない。それどころか、元記事を修正しやすいように自動的に当該記事のフロントフォーマッター部分を追記してくれる。
神がかってるな！と、当時の私は考えていた。なんなら「イベントに登録できないのはしょうがないか」ぐらいに考えていた。

### QiitaのWebエディタで編集をすると、QiitaCLIでコンフリクトを起こす原因と、躓きやすいポイント
ここでは、QiitaCLI上で管理している項目に対して、一切の変更を加えることなく操作ができる、という思い込みが問題であることを言及しておく。
まず、Webエディタで編集をする。記事の内容もタイトルもタグも変えない。やったのは、エンジニアフェスタのキャンペーンに登録する。それだけだ。
先述した通り、これだけの作業でも必ずフロントフォーマッター部分は更新されるようになっている。具体的には `updated_at` である。
見た目上何もしなくても更新ボタンが押せてしまう事が、まさかこんな問題になるとは、この時は思いもしなかった。

私の頭の中は「何も変更していないので差分はなし。ただし、キャンペーンには後から登録できる」という考えだった。
上記の通り、差分は必ず発生する。

### QiitaCLIで編集する
さて、Webエディタで編集したので、本来であればQiitaCLIで `npx qiita pull` しなければならないが、毎度のこと「あの記事を更新したから、編集する前にpullしよう」なんて思わない。
なんなら「とりあえずqiita pushしておいて、後から編集で追記すればいいよね」とまで考えている。

ここで、

- QiitaCLI: updated_atが差し替えられていない状態で、本文などが変更された内容を保持する履歴
- Webエディタ: updated_atだけが更新されている状態の、その他は前回のコミットから全く変更されていない履歴

がそれぞれに存在する。

当然、それぞれの履歴が異なるが同一ファイルを編集しているという扱いのためにコンフリクトを起こしてしまう。

で、 `npx qiita pull` はコンフリクトの解消はしてくれない。git pull(git merge）とは違うようだ。
人間の感覚としては「そんなもん、それぞれの前回の履歴と比較して変わっているところだけをそれぞれから抽出してくれよ」と思ってしまうわけだが、これが出来ないのでgitのような感覚でqiita pullを使うと危険である。

さらに、QiitaCLI-CIを使って初めて `npx qiita push` に失敗する事に気付けるので、直前までWebエディタ側の更新を誰も把握できないことになってしまう。
CIで運用する以上、トリガーとなる要素はpushやスケジュールを想定していると思われるため、このタイミングでは既にgitの履歴としてみた場合でも違う歴史になってしまう。

### コンフリクトを解消する
やり方は単純で、今あるGitHubでの最後のBotのコミット履歴に戻ってqiita pullした後に今回の変更を適用するしかない。
コンフリクトが発生した履歴は消すか戻すかのどちらかで対応する必要がある。

その上で、updated_atを修正してコミットする。
決め打ちでupdated_atを差し替える事で半自動化は可能だが、問題の解消にはやはり運用対処が必要になってしまうだろう。

## ポイントまとめ
- QiitaCLIを使うことでGitHubのコントリビューションに反映することができる
- QiitaCLIを使って記事のバージョン管理をしたいなら、Webエディタは使えない　→ 使ってはならない
- Webエディタを使った場合、コミットする前にqiita pullする

これでGitHubとWebエディタを併用しながらQiitaCLIを使う事ができる
「超高速起動！OrbStackを使ってDocker Desktopからスムーズに移行する方法」

## はじめに
超高速で起動できるらしいので、OrbStackを使ってみました！
Docker Desktopを普段は使用しているのですが、移行がとても簡単でした。
Docker Desktopが入ったままでも導入できたので、私が導入した手順を紹介しようと思います。
ドキュメント読むのに抵抗ある人は、同じように導入していただけたら新しいことを覚えることもなく、高速でコンテナを起動できると思います！

UIはMacOSのような雰囲気でカッコよかったです。
![Screenshot 2024-07-08 at 23.14.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3815234/e28d5d78-5b2b-1e7a-5ac4-73ef4f67b5a2.png)

## インストール
次のコマンドでインストールできます。
```bash
brew install orbstack
```
こちらからもインストール可能です。
https://orbstack.dev/download

## Docker Desktopからの移行
Docker Desktopのコンテナ、ボリューム、イメージなどを含むデータを移行します。
データの移行は、OrbStackのGUIでMigrateボタンが表示されていると思うので、そこからもデータの移行が可能です。
```bash
orb migrate docker
```
Docker DesktopからOrbStackに切り替える
```bash
docker context use orbstack
```
Docker Desktopに戻す時は、次のコマンドで
```bash
docker context use desktop-linux
```
これだけで、dockerを使えるようになります！

また、OrbStackの起動は、次のコマンドで起動できます。
```bash
orb
```
## 使用感
今まで使用していた`docker compose`コマンドなどが、そのまま使用できるので導入も含めとても簡単でした！
最近使用しているコンテナの起動をしてみると、Docker Desktopでは1分ほどかかったのに対し、OrbStackでは3秒ほどで起動しました。(追記:メモリなどの条件が違かったことや、キャッシュなどが残っていた可能性があるのでもう少し時間がかかると思います)快適...!

## おわりに
使用感に違和感はないので、しばらく使用してみたいと思います。
私自身が環境構築に使用した内容しか記載していないので、詳しくは公式のドキュメントを確認してみてください！

## 参考
https://docs.orbstack.dev/
paiza.ioでelixir その296

# 概要
paiza.ioでelixirやってみた。
練習問題やってみた。

# 練習問題
ElixirでAtcoderをspawnを使って解け。

# 参考にしたページ

https://qiita.com/RyoWakabayashi/items/ad2eaa6aabca8cce896b


# サンプルコード

```

defmodule Main do
	def main do
		IO.read(:line)
		|> String.trim()
		|> solve()
		|> IO.puts()
	end
	def solve(s) do
		me = self()
		String.codepoints(s)
		|> Enum.map(fn n ->
			spawn fn -> 
				(send me, { :ok, String.to_integer(n) }) 
			end
		end)
		|> Enum.map(fn _ ->
			receive do {:ok, res} -> 
				res 
			end
		end)
		|> Enum.sum()
	end
end

Main.main()

Main.main()




```

# 成果物


https://paiza.io/projects/eJjogOaNKCCfnGQBuVhDvA?language=elixir


以上。
【Laravel】ファイル作成コマンドまとめ

## はじめに
お疲れ様です！
久しぶりにLaravelで開発するってなると所々コマンドを忘れてしまう私です。
その度に調べて、、、
それも十分ありですが、参考サイトを何度も行ったり来たりするのは面倒！なので備忘録も兼ねてよく使えるような簡単で便利なコマンドをまとめました。


### この記事でわかる・できること

- php artisan make:~　の基本的なコマンドが分かる
- 便利なオプションが分かる


### この記事の対象者

- Laravel初心者
- 私と同じように毎回調べてる人


### 動作環境・使用するツールや言語

- Windows11
- Ubuntu
- Laravel8

## まずは基本的な形から

```Ubuntu:PHPコンテナ内
php artisan make:A ～～
```
「php artisan make:」は固定

- 上記**A**には、どこのディレクトリに作成したいのかが入ります。
（作成したいファイル場所の親ディレクトリ）

- 上記**～～**には、作成したいファイル名（拡張子なし）が入ります。

例えば、、、

```Ubuntu:コントローラーを作成したい
php artisan make:controller Sample
```

```Ubuntu:モデルを作成したい
php artisan make:model SampleController
```

```Ubuntu:マイグレーションを作成したい
php artisan make:migration create_samples_table
```

```Ubuntu:シーダーを作成したい
php artisan make:seeder SamplesTableSeeder
```

こんな感じでファイルの作成が可能です。
ただ、いちいち「php artisan make:A ～～」ってやるのは、面倒かつ効率が悪いですよね！
コピペだったとしても！！
そこで！オプションをつけることで一度コマンドを打つだけで複数のファイルが
作成可能となります。


## 複数ファイル作成オプション

一度で複数ファイルを作成するオプションは、**モデル**を基準に作成していきます！

```Ubuntu:モデル作成
php artisan make:model SampleController
```

- **-c**
    - モデル＋**コントローラ**を作成

- **-r**
    - モデル＋**リソースコントローラ**を作成
    （典型的なCRUD操作を含むメソッドが記述されているコントローラ）

- **-m**
    - モデル＋**マイグレーション**を作成

- **-s**
    - モデル＋**シーダー**を作成

- **-f**
    - モデル＋**ファクトリ**を作成

組み合わせると！
```Ubuntu:モデル作成
php artisan make:model Sample -m -c -r -f -s
```
適宜組み合わせることで、欲しいファイルが一気に作成できちゃいます！
そんなに難しいことをせず、作業効率大幅に向上！！！


## おわりに・まとめ

すぐに実践できるLaravelの簡単なファイル作成コマンドを紹介しました！

環境構築でやや時間をとられてしまう私ですが、すこしでも効率良くしていきたいと考える中で、
特段覚えることが少なく、感覚的に実行できるコマンドは、ぜひとも使っていきたいですね！！
Mac VSCodeのターミナルで$PATHが二重になる問題の対策

# 原因

macOSのVSCodeが起動されるとログインシェルが起動され、さらにターミナルを起動するときもう一度ログインシェルが起動されるので、~/.zprofile等が2回読み込まれるらしい。

>This can happen on macOS because of how the terminal launches using VS Code's environment. When VS Code launches for the first time, to source your "development environment," it launches your configured shell as a login shell, which runs your ~/.profile/~/.bash_profile/~/.zprofile scripts. Now when the terminal launches, it also runs as a login shell, which will put the standard paths to the front (for example, /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin) and reinitialize your shell environment.

https://code.visualstudio.com/docs/terminal/profiles#_why-are-there-duplicate-paths-in-the-terminals-path-environment-variable-andor-why-are-they-reversed-on-macos

# 対策
## 1. ~/.zshenvで$PATHを空にしておく方法

zshの初期化ファイル読み込み順は

```
# 1. /etc/zshenv
# 2. ~/.zshenv
# 3. [login mode]
#      i. /etc/zprofile
#     ii. ~/.zprofile
# 4. [interactive]
#      i. /etc/zshrc
#     ii. ~/.zshrc
# 5. [login mode]
#      i. /etc/zlogin
#     ii. ~/.zlogin
```

であり、/etc/zshenvは存在しないので、~/.zshenvで$PATHを空にしておけば良い。


```~/.zshenv
# ターミナルエミュレータがVSCodeかつzshがログインシェル
if [ "$TERM_PROGRAM" = "vscode" ] && [[ -o login ]]; then
  PATH=
fi
```

## 2. inheritEnv: falseにする方法
VSCode公式ドキュメントに
>There are two direct fixes for this. The first is to set "terminal.integrated.inheritEnv": false, which will strip most environment variables from the terminal's environment, except for some important ones (like HOME, SHELL, TMPDIR, etc.).

とあったので
```
"terminal.integrated.inheritEnv": false
```
を設定してみたが、自分の環境ではうまくいかなかった。


## 3. VSCodeターミナル内で起動するシェルを非ログインシェルにする方法
`args`の中の`"-l"`を消すことで非ログインシェルにする方法もある。
こうするとターミナル起動時に~/.zprofile等が実行されなくなることには注意。
非ログインシェルでも~/.zshrcは読み込まれるので、その中でPATHを追加していたら二重になることに注意。
```
    "terminal.integrated.profiles.osx": {
...
        "zsh": {
            "path": "zsh",
            "args": [],  // -l を消した
        },
```
【スキル】エンジニアになって認識した必要な5つのこと

## はじめに
エンジニアになって数年が経つのですが、新しい現場やチームに配属されるとなると未だにわくわくよりも不安の方が勝ります。
（**まだ**数年、と言うのが正しいかもしれない:beginner:）

「雰囲気はどんな感じだろう。。」
「うまくコミュニケーション取れるかな。。」

業務内容ももちろん大事ですが、なによりも周りの方々と円滑に業務を遂行できるかの方に私は重きを置いています。
この点は配属されてからでないとわからないため、新しい環境に飛び込むことが多いエンジニアになって認識した必要なスキルについて、私なりの見解を述べようと思います。

## 私が考える必要なスキル

### 1. 適応能力
現場やチームはそれぞれ**色**があります。
コミュニケーションが活発、最低限のコミュニケーションのみで黙々と作業をこなすなどなど。。配属先ごとにやり方論があるので、<font color="Red">**まずは知ることから始めその環境にあったやり方でやってみることが馴染む一歩になる**</font>と感じました。
※あきらかにおかしいやり方論であった場合はもちろん除きます。

私はある現場にてチーム異動~~をさせられること~~が多く各所から合わないとクレームがあったのかなと勝手に悲しんでいたのですが、当時チーム編成を考えていた方に後日談として「あなたはどのチームに入れてもうまくやってくれるから足りないところに入れてたんだ～」と軽く言われました。
（不安になりながら、毎回時間をかけて人間観察からやってたのに！）

しかし追加で「なんならあなたをチームから外さないでくれって各リーダーから言われてたよ」というお言葉をいただけたからこそ、私の地道な行動は実ってたかもしれないと思うようになれました。

### 2. 再現力
SESとなるとチームだけでなく現場異動も多いかと思いますが、<font color="Red">**自身の経験則がぶち壊される**</font>ことも多々あります。
今まではこのやり方でやってこれたけどだめなのか。。と何回もなったことがあり私が未だに苦戦するところで、経験不足だと実感しています。
（自分はできるやつ！と天狗にならないだけましかもしれません:japanese_goblin:）

他で積み重ねてきた実績が新しい環境で再現できるかは、かなり重要だなと思っています。

### 3. 愛嬌
同じ所属会社から複数人で配属されることは当たり前ではなく、ひとりでやっていかなければならないときに特に重要な要素だと感じます。
私は周りがすでに所属会社で固まっている中にひとり参画することが多く、懐に入るチャンスをずっと伺っていました。
関係性が築けると協力し合う仲になれ、困ったときに手を差し伸べてくれるようになるので、周りと信頼関係をつくっておくのは良いことしかないです。

ちなみに舐められないように私が心掛けていることは、"<font color="Red">**Giverばかりでなく、たまにはTakerにもなる**</font>"です。

### 4. 主体性
特に配属直後だと右も左もわからない状態だと思いますが、<font color="Red">**教えてもらえるものだと思わず自分から情報を得ようとする姿勢**</font>も大切です。

「指示されていないので指示をもらえるまで待ってました。」
「時間があいたので自分で情報を探してやってみました。」

重大な責任が伴うものであれば前者が正しいときもありますが、ほとんどの場合は後者の方が周りにとって助かるかと思います。
教えることに注力できるほど暇な方はほとんどいらっしゃらないので、手が空いたときにどのように動くことができるかで信頼度も変わってきます。
これは教える立場、教わる立場両方経験してきたからこそかなり実感しています。

### 5. なんでもやってみる精神
年齢を重ねるごとに経験外のことに踏み込むのは勇気のいることですが、<font color="Red">**チャンスが巡ってきたときに思い切ってやってみる気持ち**</font>も大切だと最近感じ始めています。
（これはスキルというよりマインドですね。）

私は最近実務経験がないことを任されやっていけるか不安に思っていたのですが、日々勉強なのはエンジニアの特性であり経験・未経験関係ないので、なんとかなることもあると肌で感じます。
とはいっても、周りにご迷惑かけるんじゃないかとやっぱり不安になりますよね。
私も鋼の気持ちを持ちます。

## 最後に
今回は、私が思うエンジニアが必要なスキルについてお話いたしました。
環境がころころ変わる経験をしてきたからこその視点も多少あるかと思うので、少しでも参考になったら幸いです。

最後までお読みいただき、ありがとうございました:fireworks:
応用情報を参考書を買わずに合格するために

# 挨拶
どうも皆さんこんにちは！！
イケてる社会人を目指す新卒エンジニアのやぴ丸です。
令和6年度春季応用情報技術者試験に合格したので、備忘録として残そうと思います。

# 応用情報技術者試験とは
おそらく知っている方がほとんどだとは思うのですが一応知らない人のために
「応用情報技術者試験（おうようじょうほうぎじゅつしゃしけん、Applied Information Technology Engineer Examination、略号AP）は、情報処理の促進に関する法律第29条第1項の規定に基づき経済産業大臣が行う国家試験である情報処理技術者試験の一区分。」[wikipedia参照](https://ja.wikipedia.org/wiki/%E5%BF%9C%E7%94%A8%E6%83%85%E5%A0%B1%E6%8A%80%E8%A1%93%E8%80%85%E8%A9%A6%E9%A8%93)
情報処理推進機構(IPA)が試験を行ってくれていて、応用情報のページのいっちゃん最初に
**ワンランク上のITエンジニア**
って書いてあります。これをとれば書類上は「ワンランク上のITエンジニア」になれるかも？
[公式サイト参照](https://www.ipa.go.jp/shiken/kubun/ap.html)

# 実際どんな試験？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3820752/1a8cc193-ad5f-cc08-7dd6-8cbd7b3ff6f1.png)
試験時間・出題形式・問題数はこんな感じです。
午前午後、合わせて5時間あります。めちゃくちゃ長いです(笑)

**午前試験**では
80問中50問が**テクノロジ系**の問題
80問中10問が**マネジメント系**の問題
80問中20問が**ストラテジ系**の問題
が出題されます。

**午後試験**では
問1．情報セキュリティ
問2．経営戦略
問3．プログラミング
問4．システムアーキテクチャ
問5．ネットワーク
問6．データベース
問7．組込みシステム開発
問8．情報システム開発
問9．プロジェクトマネジメント
問10．サービスマネジメント
問11．システム監査
の中から**5問選択**して解答します。
[詳しくはこちら](https://www.ap-siken.com/aphani.html)

### この試験を午前午後どちらも**6割以上**取れれば晴れて合格となります！

# 勉強の仕方
### 午前
午前の勉強法はシンプルです。ひたすらに過去問を解きましょう。
応用情報技術者では[応用情報技術者試験ドットコム](https://www.ap-siken.com/apkakomon.php)という素晴らしいサイトがあります。ここでひたすらに過去問を解きましょう！

私の体感の話になりますが、午前は問題の**五割**が過去に出題された問題、**二から三割**が過去問に変更を加えた問題、残りが新しい問題といった構成になっています。

そのため過去問を解けるようになれば午前は突破できます！
おすすめは直近５回分解いてみて安定して７割とれるようならおそらく問題ないと思われるので、午後問題に注力してしまいましょう！
### 午後
午後は人によって勉強の仕方が全然違うと思うので私のおすすめをお話します。

1. 過去3-5回分すべての大問を解いて自分が勉強する分野を決める(おすすめは7-8問に絞る)
   私は**1,2,4,7,9,10,11**の7問を勉強しました。なぜこの問題を選んだかというと全体的に文章を読むことで知識がない部分に関してもこたえられる割合の大きい問題が多かったからです。
2. YouTubeでも何でもいいので午後問題の解き方や考え方に対して人の視点を取り入れてください。自分にとって有用だと思えるものだけでいいです。(会社でUdemyなどを契約していたらそれらも活用しましょう！)
個人的に有用だと思ったのは現代文や英語の文章問題と同じように**始めにざっくりと全体を読んで問題を確認し、次に重要そうな単語にしるしをつけながら読み、最後にこれまでの情報から問題に必要な部分を探す**というやり方です。
このやり方は非常にやりやすかったのでぜひ試してみてください。
2. あとは午前と同じように過去問を解きましょう。
その際に意識していただきたいのは問題に出てきた**わからない知識や考え方をしっかりインプットすること、問題の傾向を把握する**ことの二つです。これができていれば10回分解くころには安定して7割以上とることができるようになっていると思います！

# 終わりに
今回は応用情報技術者試験について参考書や塾に通わずともできる勉強法について話してみました！
勉強法というよりは心構えに近い内容になってしまいましたが…(笑)
勉強法は正解が十人十色なものだと思うので、これを読んでくださった人のために少しでもなれば幸いです。

これからもイケてる社会人目指して邁進してまいりますのでこれからもよろしくお願いします！！！
それではまたお会いしましょう！
マークダウンを変換する時にあれ？と思った話。実は知らないマークダウンのほんとのところ

Markdownに対して勘違いをしていたのとMarkdownを変換する際に注意したいことを記事にします。

## プレーンだと思ってたMarkdownは拡張されたもの
もともとMarkdownには仕様がなく、それを不便に思った人たちで作られたのが**CommonMark**だそうです。

https://commonmark.org/

一般的によく知られているであれろうGithubの「GitHub Flavored Markdown (GFM)」はテーブル記法に対応していますが、CommonMarkにはありません。

:::note
Qiitaのマークダウンは`:::note`などの特殊な記法ができるようにさらに拡張されています！
:::

上記の仕様を知らなかったため、Markdownを変換しようとした時に変換されず「あれ？」となりました。

:::note warn
table記法は標準の仕様ではないので、変換するためのプラグインが対応していないことがあります…。
:::

## Next.js環境でMarkdownにMDXを仕込みたい

Next.js環境にてMarkdownで書かれたものをJSXに変換したい場合下記のプラグインを利用します。

https://github.com/hashicorp/next-mdx-remote

ただ、`next-mdx-remote`はテーブル記法の変換は対応していません…。

https://mdxjs.com/table-of-components/

なのでGFMのプラグインを併用するなどして対応されていないMarkdownを置き換えられるようにします。

https://github.com/remarkjs/remark-gfm

## まとめ
Markdownを変換する処理は、Markdownを利用して記事を書くようなHeadressCMSなどで必要になってくると思います。

:::note
実際の処理は、Markdown文字列を`unified`を利用してAST(抽象構文木)というプログラムで処理しやすいデータに変換しするなども必要になることもあります。
:::

基本的な知識ですが、知らなかったことによって手間取りました…。
基本を押さえておかないと思わしくない実装をしてしまう恐れもあるので注意したいと思いました。
[備忘録]　IT用語について分かったことをまとめてみた ~ver.6

# はじめに
こんにちは，Umamusume22です．今回もIT用語について分かったことをまとめてアウトプットしていきます．

# 備忘録
#### セマフォ[1]
- 排他制御のための仕組み
- 同時に使える人の数が決まっているものに割り当てられた「あと何人の人が使えるよ」を表した数字
    - あと何人使えますよを表す数字
- 共有資源に対するアクセス可能な数を示す値
- セマフォの値が0になったらアクセス不可
- セマフォは同期処理に使われる場合もある

#### スレッド[2]
- プログラムの処理の実行単位
- 処理開始から処理終了までの流れを線で引いてその線一本一本がスレッドに該当する
- 1つの処理をシングルスレッド
- 複数の処理をマルチスレッドと呼ぶ



# 最後に
今回も記事の内容が短くて申し訳ありません．
引き続きIT用語について分かったことをアウトプットしていきます
読んでいただきありがとございました!

※ウマ娘の声をフーリエ変換した記事や水栓の開閉判定をLineに通知する記事も書いています．suzuが私です．興味がある方はぜひご覧ください！
https://vigne-cla.com/31-1/#toc5

※noteも始めました．
https://note.com/madoka235/n/nbba2153326e1

ぜひフォローよろしくお願いします!

# 参考文献
[1] “「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典”
https://wa3.i-3-i.info/word13357.html

[2] “「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典”
https://wa3.i-3-i.info/word12453.html
【検証記事】 QiitaCLIで記事を書く前にqiita pullを手動実行する運用対処は可能か？

【検証結果は後ほど編集で差し替える】

通常手順としてはFrontFormatterのupdated_atだけが変更される修正にすべきだが、わかりやすさ重視でWebエディタから記事の本文を書き換えておく

Workflowからコミットメッセージを書き換える対応をしたが、反映されるかテスト
Flow sample 2024/07/09


+ [Update criteria based auto number for related records - Based on the different checkboxes](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007cmImr)

# Overall picture

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/425d0a8f-94cd-1161-4f19-05f563583ac8.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/f0d3e12e-e976-b794-4d8a-0c051ad0caa8.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/090dc9b9-a613-624e-0079-9acacfe83e34.png)


# screen : select check

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/f6de5dff-db75-1ce6-2081-cdb9864376cd.png)


# Decision : is_A 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/d052ea6f-a8d6-a4b1-87b6-e1ff967f8f0d.png)

# Assignment : Count_up_A

+ Variable : Counter

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/16981dc3-1764-ac9b-7d14-42f35b2e2ce2.png)

+ Variable : A_Auto_number

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/eb4a7fbf-d837-2e6b-b6b3-a02c7da6d7d7.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/6b7f8be3-dfeb-069d-c84f-ce4769039417.png)


# Assignment : Count_up_B

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/f5383aea-976b-3ad7-61c5-376351437714.png)


# Screen : result

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/af30844d-dd7c-4a42-268a-5791ee91f5ee.png)
オープンソースソフトウェアの脆弱性を監視する方法：クラウドサービスを活用した実践ガイド


## はじめに

オープンソースソフトウェア（OSS）は、コスト削減や開発スピードの向上など、多くのメリットを提供します。しかし、その一方で脆弱性のリスクも伴います。特に、OSSの脆弱性が悪用されると、システム全体のセキュリティが脅かされる可能性があります。そこで今回は、クラウドサービスを活用してOSSの脆弱性を監視する方法について解説します。

## なぜOSSの脆弱性監視が重要なのか

OSSは多くの開発者によってメンテナンスされていますが、その分、脆弱性が発見される頻度も高いです。脆弱性が放置されると、以下のようなリスクが生じます：

- **データ漏洩**：脆弱性を悪用されると、機密情報が漏洩する可能性があります。
- **サービス停止**：攻撃によってサービスが停止し、ビジネスに大きな影響を与えることがあります。
- **法的リスク**：データ漏洩やサービス停止が発生すると、法的な問題に発展することもあります。

## クラウドサービスを活用した脆弱性監視のメリット

クラウドサービスを利用することで、脆弱性監視の効率が大幅に向上します。以下はその主なメリットです：

- **自動化**：脆弱性のスキャンやレポート生成を自動化できます。
- **リアルタイム監視**：最新の脆弱性情報をリアルタイムで取得し、即座に対応できます。
- **スケーラビリティ**：大規模なシステムでもスケーラブルに対応可能です。

## 実践ガイド：クラウドサービスを使った脆弱性監視

### 1. AWS Security Hub

AWS Security Hubは、AWS環境全体のセキュリティ状況を一元管理できるサービスです。以下の手順で設定します：

1. **Security Hubの有効化**：AWSマネジメントコンソールからSecurity Hubを有効化します。
2. **脆弱性スキャンの設定**：Amazon Inspectorなどの脆弱性スキャンツールを連携させます。
3. **アラート設定**：脆弱性が検出された際に通知を受け取るように設定します。

### 2. Azure Security Center

Azure Security Centerは、Azure環境のセキュリティを強化するためのサービスです。以下の手順で設定します：

1. **Security Centerの有効化**：AzureポータルからSecurity Centerを有効化します。
2. **脆弱性スキャンの設定**：Azure Defenderを有効化し、脆弱性スキャンを設定します。
3. **アラート設定**：脆弱性が検出された際に通知を受け取るように設定します。

### 3. Google Cloud Security Command Center

Google Cloud Security Command Centerは、Google Cloud環境のセキュリティを一元管理するためのサービスです。以下の手順で設定します：

1. **Security Command Centerの有効化**：Google CloudコンソールからSecurity Command Centerを有効化します。
2. **脆弱性スキャンの設定**：Container AnalysisやWeb Security Scannerを連携させます。
3. **アラート設定**：脆弱性が検出された際に通知を受け取るように設定します。

## まとめ

OSSの脆弱性を監視することは、システムのセキュリティを維持するために非常に重要です。クラウドサービスを活用することで、効率的かつ効果的に脆弱性を監視し、迅速に対応することが可能です。ぜひ、今回紹介した方法を参考にして、あなたのシステムのセキュリティを強化してください。

## 参考リンク

- [AWS Security Hub](https://aws.amazon.com/jp/security-hub/)
- [Azure Security Center](https://azure.microsoft.com/ja-jp/services/security-center/)
- [Google Cloud Security Command Center](https://cloud.google.com/security-command-center)
コンテナイメージのセキュリティを確保するためのベストプラクティス


## はじめに

こんにちは、皆さん！今日はコンテナイメージのセキュリティを確保するためのベストプラクティスについてお話ししたいと思います。クラウドネイティブなアプリケーション開発が進む中で、コンテナ技術はますます重要になっています。しかし、セキュリティを無視してしまうと大きなリスクを抱えることになります。そこで、今回はコンテナイメージのセキュリティを確保するための具体的な方法を紹介します。

## 1. ベースイメージの選定

まず最初に、信頼できるベースイメージを選定することが重要です。公式のリポジトリから提供されるベースイメージを使用することで、セキュリティリスクを最小限に抑えることができます。例えば、Docker Hubの公式イメージや、各クラウドベンダーが提供するベースイメージを利用することをお勧めします。

## 2. イメージの最小化

次に、コンテナイメージを最小化することが重要です。不要なパッケージやツールを含めると、攻撃の対象が増えるだけでなく、脆弱性も増加します。最小限のパッケージで構成されたイメージを作成し、セキュリティリスクを低減しましょう。

## 3. セキュリティスキャンの実施

コンテナイメージをビルドした後は、セキュリティスキャンを実施することが重要です。例えば、ClairやTrivyなどのツールを使用して、イメージ内の脆弱性を検出することができます。定期的にスキャンを行い、脆弱性が発見された場合は速やかに対策を講じましょう。

## 4. イメージの署名と検証

コンテナイメージの署名と検証も重要なステップです。NotaryやCosignなどのツールを使用して、イメージの署名を行い、信頼性を確保しましょう。署名されたイメージは、デプロイ前に検証することで、改ざんされていないことを確認できます。

## 5. ランタイムセキュリティの強化

最後に、コンテナのランタイムセキュリティを強化することも忘れないでください。SeccompやAppArmor、SELinuxなどのセキュリティ機能を活用して、コンテナの動作を制限し、攻撃のリスクを低減しましょう。また、Kubernetesを使用している場合は、Pod Security PoliciesやNetwork Policiesを適用することで、セキュリティをさらに強化できます。

## まとめ

コンテナイメージのセキュリティを確保するためには、ベースイメージの選定、イメージの最小化、セキュリティスキャン、イメージの署名と検証、ランタイムセキュリティの強化といった複数のステップが必要です。これらのベストプラクティスを実践することで、セキュアなコンテナ環境を構築し、安心してクラウドネイティブなアプリケーションを開発することができます。

皆さんもぜひ、これらの方法を取り入れて、セキュアなコンテナ開発を目指してください！
markdown AIでフォントを変える方法

# はじめに
本記事では [markdown AI](https://mdown.ai/content?id=335b81b2-bcb0-4dbb-83d0-531aa132181f) で**フォントを変更する方法**を解説します。

:::note
**markdown AI とは？**
Markdown 記法を用いて、簡単に Web ページの作成、公開を行うことができる Web サービスです。
:::


markdown AI は以下のリンクから **Google アカウント**のみで**無料**で利用できます。

https://mdown.ai/ 

markdown AI の使用方法は Qiita にも多くの記事があるので割愛させていただきます。

# フォントを変える方法
markdown AI では **HTML の要素を直接書き込む**ことができるため、**自由度が高い** Web ページを作成することが可能です。

以下に、フォントを変更するための具体的な手順を説明します。

## CSS の導入
markdown AI では、CSS を使ってフォントを変更することができます。例えば、以下のようにスタイルを定義します。
```html
<style>
* {
  font-family: 'Arial';
}
</style>
```
このコードを Markdown ドキュメントに追加することで、全体のフォントが `Arial` に変わります。

さらに、細かくフォントを定義したい場合は、`*` の部分を `h1` や `p` などの HTML 要素に変更します。

```html
<style>
h1 {
  font-family: Georgia;
}

h2 {
  font-family: cursive;
}
</style>
```
このコードを Markdown ドキュメントに追加することで、`# `で始めた要素(`h1`)のフォントが `Georgia` に変わります。また、、`## `で始めた要素(`h2`)のフォント は `cursive` に変わります。


`font-family` について詳しくは以下の記事を参照してください。

https://developer.mozilla.org/ja/docs/Web/CSS/font-family

Web ブラウザによって、`font-family` で指定できるフォントの種類が異なります。

## Google Fonts を利用
Google Fonts を使うことで、さらに多様なフォントを利用することができます。以下に手順を示します。

1. [Google Fonts](https://fonts.google.com/) にアクセスし、使用したいフォントを選択します。
2. 「Get font」と書かれたボタンをクリックします。
3. 「Get embed code」と書かれたボタンをクリックします。
4. 画面右側に表示される `Web` の欄で `<link>` を選択し、`Embed code in the <head> of your html` の項目のリンクをコピーします。
   例えば、以下のようなリンクです。
    ```html
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap" rel="stylesheet">
    
    <!-- 
    1, 2 行目: Google Fonts のパフォーマンスを向上させるために使用される
    3 行目: Google Fonts からフォントを取得するために使用される
    -->
    ```
5. markdown AI のドキュメントにこのリンクを追加し、スタイルを定義します。
    ```html
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap" rel="stylesheet">
    
    <style>
    * {
      font-family: 'Roboto';
    }
    </style>
    ```

これで、全体のフォントが（この場合は `Roboto` に）変わります。

※ Google Fonts で利用できるフォントは基本的に無料ですが、各フォントの `About & license` の項目でライセンスを確認してから使用するようにしてください。


# まとめ
markdown AI では、HTML と CSS を駆使することで、簡単にフォントを変更することができます。Google Fonts などのフォントサービスを利用することで、多様なフォントスタイルを利用することができるので、ぜひ試してみてください。
【Go言語】n進数

## はじめに

```go
func main() {
	sum := 100 + 020
	fmt.Println(sum)
}
```

これを実行すると、**120**ではなく、 **116** が出力されます。
Goでは、0から始まる数字は8進数とみなされます。

:::note info
ちなみに余談ですが、javascriptはもっと奇妙な動作をします。気になる方は
[【超難問】絶対に解けないJavaScriptクイズ8選](https://qiita.com/twrcd1227/items/a64c3f22da46ff2c0fbd)
:::

## 2進数(バイナリ)

`0b`、`0B`のprefixつける。(e.g. 0b1010)

以下はビット演算の例。

```go
func main() {
    var a uint8 = 0b1010
    var b uint8 = 0b0110

    fmt.Printf("a AND b = %08b\n", a & b)
    fmt.Printf("a OR b = %08b\n", a | b)
    fmt.Printf("a XOR b = %08b\n", a ^ b)
    fmt.Printf("a << 1 = %08b\n", a << 1)
    fmt.Printf("a >> 1 = %08b\n", a >> 1)
}
```

## 8進数

`0`, `0o`のprefixをつける。(e.g. 012)

ファイルにパーミッションを付与する際によく用いられる。([os](https://pkg.go.dev/os))

```go
func main() {
    file, err := os.OpenFile("example.txt", os.O_CREATE|os.O_WRONLY, 0666)
    if err != nil {
        panic(err)
    }
    defer file.Close()
    file.WriteString("Hello, World!")
}
```

## 16進数

`0x`、`0X`のprefixをつける。(e.g. 0x3F)

ちなみにポインタは16進数です。他にもカラーコードでも16進数が使われます。

```go
func main() {
	n := 42
	fmt.Printf("n: %p\n", &n)
}
```

## 複素数

iのsuffixをつけると虚数となります。(e.g. 3+4i)
複素数は`complex128`と`complex64`として宣言することが可能です。

```go
func main() {
	var z1 complex128 = 1 + 2i
	z2 := 3 + 4i

	fmt.Printf("Sum: %v\n", z1+z2) // Sum: (4+6i)
	fmt.Printf("Mutli: %v\n", z1*z2) // Mutli: (-5+10i)
	fmt.Printf("Abs: %v\n", cmplx.Abs(z1)) // Abs: 2.23606797749979
}
```

## アンダースコア

数字を読みやすくするために、区切り文字として`_`を使える。
例えば、1億は`100_000_000`とかける。また、10進数以外でも使用可能。

## スライド

<script defer class="speakerdeck-embed" data-id="1d6bca3fb6a0404a8f9e1a2800b3422f" data-ratio="1.7777777777777777" src="//speakerdeck.com/assets/embed.js"></script>
Javaで「文字列の一部を別の文字や文字列に置換する」の動作を確認してみた

# 概要

Javaで「文字列の一部を別の文字や文字列に置換する」の動作を確認してみました。
以下のページを参考にしました。

https://www.javadrive.jp/start/string/index16.html

# 実装

以下のファイルを作成しました。
```JSample16_1.java
class JSample16_1{
  public static void main(String[] args){
    String str1 = "Herro Java";
    System.out.println(str1);
    System.out.println(str1.replace('r', 'l'));

    String str2= "東京都港区";
    System.out.println(str2);
    System.out.println(str2.replace("港区", "中央区"));
  }
}
```

以下のコマンドを実行しました。
```
$ javac JSample16_1.java 
$ java JSample16_1 
Herro Java
Hello Java
東京都港区
東京都中央区
```

# まとめ

何かの役に立てばと。
誰のPCでもダウンロードフォルダを指定するPath指定方法【 Power Automate Desktop 】

## フォルダPath指定変更無しでどのPCでも動作するよう設定


ダウンロードファイル、ドキュメントファイルなどで操作するファイルがあるとして、
C:\Users\〇〇\Downloadsと〇〇のところを
フォルダPathの指定を操作するPCが変更Orフローを渡した人に変更してもらう話をするのは
面倒…:innocent:で、何かないかと思いついたのが下記方法です。

## フローの作り方
システム-Windowsの環境変数を取得アクションを追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3111714/08c13e76-bb8a-20e8-99ba-77031882bad6.png)

①環境変数名をUSERNAMEを指定し、
EnviromentVariableValueの変数に入れる
![image.pあじｒng](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3111714/2fd82fc5-1f94-c94d-7a9a-d16f5bb4d3c4.png)

②変数の設定でC:\Users\〇〇\Downloadsと入力した後、
〇〇の所をEnviromentVariableValue変数に変更する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3111714/dd68221e-25dc-5072-fea4-431992ae83ea.png)


こうすることによって、どのPCでもダウンロードフォルダの中で操作できるようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3111714/1cbf5933-e6c1-237b-8c2b-dcf8e53e952f.png)

Pathの指定変更はできるだけ少ない方がミスが少ないと思いますので…。
2024/7/9主にITとかセキュリティの記事

警察・学校・医療機関も標的に…ロシア系ハッカー集団“暗躍”のワケ　KADOKAWA　サイバー攻撃で深刻被害【サンデーモーニング】(7/7)
https://newsdig.tbs.co.jp/articles/-/1278905?page=2

米国 MITRE AI規制を通じてAIのセキュリティと安全性を確保する(7/7)
http://maruyama-mitsuhiko.cocolog-nifty.com/security/2024/07/post-532a45.html

能動的サイバー防御、監視は「国外からの通信」に限定へ(7/7)
https://www.nikkei.com/article/DGXZQOUA03BH10T00C24A7000000/

企業のサードパーティリスク管理とセキュリティ対策の重要性とは？
https://cybersecurity-park.com/1782/

（社説）KADOKAWAへの攻撃を他山の石に(7/7)
https://www.nikkei.com/article/DGKKZO81916860W4A700C2EA1000/

自衛隊「特定秘密」の不適切な取り扱い発覚で米国との協力関係に影響も？対策が急務(7/7)
https://news.ntv.co.jp/category/politics/e7856bb5f572415489b040d5b643a5e7

「iPhone がハッキングされています」と表示が……本当にハッキングされてしまったのでしょうか？(7/5)
https://news.infoseek.co.jp/article/allabout_109240/

Virtioと完全仮想化・準仮想化(7/7)
https://zenn.dev/junjunjunjun/articles/27ede76931cc85

電子マネー５万円分詐欺被害　四日市の女性、ウイルス対策名目(7/7)
https://www.isenp.co.jp/2024/07/07/112974/

身に覚えのない”当選通知”相次ぐ…名古屋市「プレミアム商品券」なぜ？原因わからず市は”お手上げ”状態(7/7)
https://news.yahoo.co.jp/articles/177efc3d640300c5e37be87b3dc8989d517c9299

システム障害 福井銀行 ネットバンキング一時利用できず(7/6)
https://www3.nhk.or.jp/lnews/fukui/20240706/3050018260.html

間違っているランサムウェア対策(7/7)
https://news.yahoo.co.jp/expert/articles/d973699a81bf83ecb559cd566031acd89928712f

ランサム攻撃で「ニコニコ」停止　身代金を支払うもデータ復旧できずKADOKAWA(7/8)
https://xtech.nikkei.com/atcl/nxt/mag/nc/18/020600011/070400159/

トリアージ（Triage）(7/8)
https://xtech.nikkei.com/atcl/nxt/mag/nc/18/020600009/070400172/

システム化か運用でカバーするか、その分かれ目を台湾で考えてみた(7/8)
https://xtech.nikkei.com/atcl/nxt/column/18/01111/070400056/

「めちゃコミ」と「楽天トラベル」　出自を巡る意外過ぎる共通点(7/8)
https://xtech.nikkei.com/atcl/nxt/mag/nc/18/020600007/062800169/

メガファーマに挑む創薬AI「DAIIA」の実力(7/8)
https://xtech.nikkei.com/atcl/nxt/mag/nc/18/020600014/070300181/
[svelte-preprocess] Encountered type error を解決する

## 状況
Svelte でアプリケーション開発を行っている中で次のようなエラーが出ています。

![encountered-type-error.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2038389/22cd599e-021e-13c9-e7a4-992f2480ad5d.png)


## 解決方法
### ✅ `svelte-preprocess` を更新しよう！

```bash
npm update svelte-preprocess@latest
# or
yarn upgrade svelte-preprocess@latest
```

```diff_json: package.json (一部抜粋)
"devDependencies": {
  "svelte": "^4.2.18",
  "svelte-check": "^3.8.4",
-  "svelte-preprocess": "^4.10.4",
+  "svelte-preprocess": "^6.0.1",
}
```

私の場合は上記のようにアップグレードすることで解決しました。

### バージョン移行に関して
バージョン更新における移行については下記のリンクを参照して下さい。`v3` から `v4`、`v5` から `v6` への移行について簡潔にまとまっています。

https://github.com/sveltejs/svelte-preprocess/blob/main/docs/migration-guide.md

## それでもエラーが解決しない！
svelte-preprocess で `<script lang=ts>` を処理しています。

そのため `rollup.config.js` または `vite.config.js` で `sveltePreprocess` を設定できているかを確認してみましょう。以下は設定例です。


```js: rollup.config.js
import svelte from "rollup-plugin-svelte";
import commonjs from '@rollup/plugin-commonjs';
import { sveltePreprocess } from 'svelte-preprocess';

export default {
  plugins: [
    svelte({
      preprocess: sveltePreprocess()
    })
  ]
};
```

```js: vite.config.js
import { defineConfig } from 'vite';
import { svelte } from '@sveltejs/vite-plugin-svelte';
import { sveltePreprocess } from 'svelte-preprocess';

export default defineConfig({
  plugins: [
    svelte({
      preprocess: sveltePreprocess(),
    }),
  ],
});
```

そのほか config の詳しい設定方法については [Rollup の公式ドキュメント](https://rollupjs.org/configuration-options/)や [Vite の公式ドキュメント](https://vitejs.dev/config/)を参考にしてください。


## Svelte Preprocess とは

PostCSS、SCSS、Less、Stylus、CoffeeScript、TypeScript、Pug などをサポートしているプリプロセッサです。めっちゃ便利！

https://github.com/sveltejs/svelte-preprocess

---

この記事が役に立ったら 🩷 を頂けると嬉しいです！
WebGL でティザーサイトっぽい背景を作った

## この記事の概要

WebGL をいじっていて、結構良さそうな表現が作れたので記事にしました。

https://qiita.com/xrxoxcxox/items/3c63b165b84a4929b199

上記の記事の構成と同じで、バンドラーに Vite を使い、シェーダーファイルは分けてあります。

## 完成形

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/8c0c5982-95f5-9652-fb92-2b6657c23511.gif)

万華鏡っぽい柄が中心から広がるようにアニメーションしています。
タイトル文字などを載せれば、ティザーサイトやイベントサイトの背景などに使えそうな気がしています。

## コード

```glsl
#version 300 es

precision mediump float;

uniform float uTime;
uniform vec2 uResolution;
out vec4 fragColor;

#define PI 3.14159265359

vec2 hexagonalGrid(vec2 uv) {
    vec2 r = vec2(1.0, sqrt(3.0));
    vec2 h = r * 0.5;
    vec2 a = mod(uv, r) - h;
    vec2 b = mod(uv - h, r) - h;
    return dot(a, a) < dot(b, b) ? a : b;
}

void main() {
    vec2 uv = (gl_FragCoord.xy * 2.0 - uResolution.xy) / min(uResolution.x, uResolution.y);
    uv *= 5.0; // Scale up the pattern

    // Rotate the UV coordinates
    float rotation = uTime * -0.1;
    mat2 rotationMatrix = mat2(cos(rotation), -sin(rotation), sin(rotation), cos(rotation));
    uv = rotationMatrix * uv;

    vec2 id = floor(uv);
    vec2 gv = hexagonalGrid(uv);
    
    float d = length(gv);
    float size = sin(-uTime + length(id) * 0.5) * 0.2 + 0.7; // Pulsating size
    d = smoothstep(size, size + 0.05, d);

    // Create color based on position and time
    float hue = atan(gv.y, gv.x) / (2.0 * PI) + 0.5 + uTime * 0.1;
    vec3 color = hsl2rgb(vec3(hue, 0.7, 0.5));

    // Add some variation based on distance from center
    float distFromCenter = length(uv / 5.0);
    color *= 1.0 - distFromCenter * 0.5;

    // Mix with background color
    vec3 bgColor = vec3(0.1, 0.1, 0.1);
    color = mix(bgColor, color, d);

    fragColor = vec4(color, 1.0);
}
```

あわよくば X の`つぶやきGLSL`に出してみたいな、などと思っていましたが、文字数を削るのに断念したためここで供養します。
機械学習の概念について

### 機械学習の数式とそろそろ向き合いたいよね
というわけでシリーズ化していこうかと。
　まずは、序章「機械学習のそもそもの概念」についてまとめます。
 ご安心ください。本記事の内容はまだ数学ではありません。
# 対象読者
　結局のところ、機械学習って何やねん！の民に向けて。
# 機械学習とは
　一言でいうと「データに潜むパターンを見つけ出す」こと。

 　ややこしい言い方をすれば、計算機アルゴリズムを通じて、データの中の規則性を自動的に見つけ出し、さらにその規則性を使ってデータを異なるカテゴリに分類することです。

 ## 数字認識の例を挙げて

 　以下のような手書き文字の認識を例に挙げて考えてみましょう。 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3725276/5243de97-62ea-5e8e-5d0e-7978db2e979b.png)　　
　ここでいうベクトル x とは、28×28 の各数字のピクセル画像からなる、784 次元の実数値であることに注意。
 
 ### やりたいこと
　ベクトル x を入力として受け取り、それが 0~9 のどの数字を表すのかを出力する機械を作ること。

## 機械学習のアプローチ
### 入出力について
　**訓練集合**（training set）と呼ぶ N 個の手書き数字の大きな集合 
```math
\lbrace {x}_{1}, ... , {x}_{N} \rbrace
```
　画像 x のそれぞれに対して、あらかじめ人間が手で 1 つ 1 つの数字に対応するカテゴリを設定した**目標ベクトル**（target vector）**t** が対応する。
 
 　機械学習のアルゴリズムによって得られるのは関数 **y(x)** 。
  → 入力：数字の画像 x 
  　出力：目標ベクトルと符号化の仕方が等しい出力ベクトル y 
   
  　訓練データを用いて、関数 y(x) の詳細な形を求める段階は、**訓練**（training）段階または**学習**（learning）段階と呼ばれています。
### 学習を行うと
　**テスト集合**（test set）＝ 新たな入力 に対してカテゴリを決めることができるようになります。
 　訓練時に使用したものとは異なる、新たな事例を分類する能力は**汎化**（generalization）と呼ばれます。
## 実際の応用
　もともとの入力変数は**前処理**（preprocessing）によって新たな変数に変換されます。問題をより解きやすくするためです。この前処理の段階は**特徴抽出**（属性抽出 ; feature extraction）とも呼ばれます。
    　なお、新たなテストデータにも、訓練データと同様の前処理を行う必要があります。
 ### 数字認識の例では
　数字画像の平行移動、拡大縮小によって、固定した大きさの箱に収まるように変換します。数字の場所と大きさを揃えることで、各数字クラスの多様性が大きく減少し、前処理後にクラスを識別するのが格段に易しくなるためです。

 ## 教師あり学習（supervised learning）
 　訓練データが入力ベクトルとそれに対応する目標ベクトルの事例で構成される場合に用います。以下、例。
* **クラス分類（classification）問題**
　各入力ベクトルを有限個の離散カテゴリの1つに割り当てる。
* **回帰（regression）**
　求める出力が1つないしそれ以上の連続変数であるような場合。
 　具体的には、反応物の濃度や温度・圧力などを入力とした、化学プラントにおける生成物の量の予測など。
## 教師なし学習（unsupervised learning）
　訓練データが入力ベクトル x のみで、対応する目標値が存在しないパターン認識問題に用います。以下、例。
 * **クラスタリング（clustering）**
 　類似した事例のグループを見つける。
 * **密度推定（density estimation）**
 　入力空間におけるデータの分布を求める。
  　具体的には、視覚化（visualization）のために高次元のデータを2個あるいは3個の次元に射影するなどである。

## 強化学習（reinforcement learning）
　ある与えられた状況下で、報酬を最大にするような適当な行動を見つける問題に用います。次の動作を繰り返します。
 * **探査（exploration）**
 　新しい種類の行動がどれくらい有効であるかを示す。
 * **知識利用（exploration）**
 　高い報酬が得られることがわかっている行動をとる。
## 参考文献
「パターン認識と機械学習 ベイズ理論による統計的予測」
    　　C.M.ビショップ 著
    　　元田 浩／栗田 多喜夫／樋口 知之／松本 裕治／村田 昇 監訳
  
  　また、本記事では大まかな概念のみ紹介したが、画像認識の詳しいソースコードは以下を参照されたい。
[ゼロから作るDeep Learning](https://github.com/oreilly-japan/deep-learning-from-scratch/tree/master/ch03)
### 次回は多項式曲線フィッティングについてまとめます。
任意のT型に含まれるobjectを再帰的に調べ、それら全てを含むunion型(共用体)を作るメタ関数

最近TypeScriptを使うようになったので備忘録。
下記のメタ関数はarray.flatmap()と似ており、ネストしたオブジェクトの中からobjectを全て取り出す。

```ts
type ReomoveArray<T> = T extends unknown[] ? T[number] : T;

type ExtractObject<T> = Extract<ReomoveArray<T>, object>;

type Pack<T> = (x: T) => void;

export type FlatObject<T> = T extends object
  ? Pack<T> | FlatObject<ExtractObject<T[keyof T]>>
  : never;
```
上記の内容でメタ関数を作成できる。
使い方は以下の通り。
```ts
export interface Person {
  name: string;
  age: number;
}
export interface Family {
  member: Person[];
  address: string;
}
//FlatObject<Family> と書いた場合、それはPack<Family> | Pack<Person>になる。
```

本当は[Family,Person]が欲しかったのだが、複雑そうなので取りやめ。
[タプルで取得する方法自体は存在する](https://qiita.com/ryokat3/items/23d69a0ecb758a3cbe50 "TypesScript の Union 型から Tuple 型へ変換")ので、時間がある時に再チャレンジするかもしれない。
[Rails] controllerで、configというメソッド名は使用するな！

# はじめに
`Controller`を実装中に、以下のエラーに遭遇しました。
`※ 多少表示を変えています。`

```sh
undefined method `allow_forgery_protection' for #<ActiveSupport::HashWithIndifferentAccess:0x0000000e00abc000>
```

心当たりのないエラーだったので、どのように解消するか悩みました。
今回は解消内容をアウトプットいたします。

# エラー原因
`Controller`内で`config`というメソッド名は、使用できませんでした。

https://qiita.com/ironsand/items/2834496d23380dc3f65d

今回自分が作成したメソッドは以下になります。

```rb
def config
  @config ||= Rails.application.config_for(:test)
end
```

ymlファイルを呼び出すのをメモ化するために作成したメソッドの命名を、`config`にしていました。
それが、今回のエラーの原因となっていることが判明いたしました。

# 解消方法
単純で、`config`以外のメソッド名を使用するようにしましょう。


# まとめ
もしかすると、Rails側の実装と被ってしまった可能性はあるかもと思いました。

https://railsdoc.com/page/config_action_controller_allow_forgery_protectio

今回は予約語とは違うと思っていますが、可能性はあるので、常に頭の片隅に入れておこうと思いました。
今回の内容が、参考になれば幸いです。

最後までご覧いただき、ありがとうございました。
DBMSの「スキーマ」とは

# スキーマとは
- 「概要、要旨」といった意味を持つ言葉
- DBの構造や仕様を定義するもの
　(↑データの性質、形式、他のデータの関連などのデータ定義の集合)

# 3層スキーマ
- 標準的に使用されている、ANSI/X3/SPARC(Standards Planning And Requirements Committee)規格では、3層スキーマ構造をとっている
(ANSI：アンシー、SPARC：スパーク)
- 以下の3層に定義を分けることで、データの独立性を高めている
  - 外部スキーマ
  - 概念スキーマ
  - 内部スキーマ

![20240709_004215_Original.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2330584/cf1c3b39-33cb-d843-2992-4fd636db7673.jpeg)

## 外部スキーマ
- <font color="red">**SELECT結果**</font>がこれに当たるイメージ
- <INS>**ビュー表**</INS>がこれに該当する
- 利用者(個々のプログラムやユーザ)の必要とする<INS>データの見方</INS>を表現する
- プログラムやユーザに対して必要なデータだけを提供
- プログラムに加えた変更は、このスキーマまでしか影響しない

## 概念スキーマ
- DBの表の定義(<font color="red">**テーブル**</font>)がこれに当たるイメージ
- 対象となる外界の事象を抽象化してデータの論理的な構造を定義する
→要するに**DB本体**のこと
- データの論理的<INS>関係</INS>(←ER図で表せるようなやつ)を表現する
- プログラムからも、ハードウェアからも切り離されているため、どこにも依存せず、**データの独立性**が保たれている

## 内部スキーマ
- DBに登録しているデータの<font color="red">**物理ファイル**</font>(<font color="red">**コミット、保存したデータ**</font>)のイメージ
(**実ファイル、ハードディスク上に書いてある情報のこと**)
- データの<INS>物理的</INS>関係を表現する
- 物理的にどう記憶させるかの定義をする
- ハードウェア的な変更はこのスキーマで影響を吸収する

## データの独立性
- ビュー(外部スキーマ、**SELECT結果**)を弄っても、DBのデータ格納方法(概念スキーマ、**テーブル**)は変わらない
(↑プログラムに加えた変更は、外部スキーマまでしか影響しない)
- 物理的に記憶(内部スキーマ、**コミット、保存したデータ**)させている<INS>ハードウェアが変わって</INS>も、プログラムの修正は必要ない
(↑ハードウェア的な変更は、内部スキーマで影響を吸収する)

# 備考
- 上記の「スキーマ」は、A5Mk2に表示される「カレントスキーマ」とは別物
- Oracleの場合は、
**1つのOracleDBの中に、いくつもDBが立てられる**。
この、ぽこぽこ立てたDBのことを、「スキーマ」と**製品上は**呼んでいる。
そのため、A5Mk2で出ている「カレントスキーマ」とは、OracleDBやMySQL上に立てた**複数のDBのうち、どれを見ているのか**を表している！！
  →**スキーマ = DBオブジェクト**
- MySQLの場合は、スキーマではなく「データベース」と呼んでいる。
この辺りは、製品によって呼び方がまちまち。


# 参考サイト
https://codezine.jp/article/detail/12519
> MySQLでは「データベース」という言葉は「スキーマ」と同じ意味で使われています。
PlanetScaleでリードレプリカに接続できるようになった話

# PlanetScaleでリードレプリカに接続できるようになった話

## 概要
PlanetScaleでは、リードレプリカを使用することで、データベースのパフォーマンス向上と可用性の向上を実現できます。リードレプリカは、データベースのクエリを分散し、プライマリノードへの負荷を軽減するための強力なツールです。

## リードレプリカの理解
リードレプリカはデータベースの継続的に更新されるコピーです。以下の2つの主要な目的があります：
- データをクエリするための追加のソースを提供する。
- メンテナンスや予期しない障害の際に、迅速なフェイルオーバーを可能にすることでデータベースの可用性を高める。

:::note warn
負荷を軽減するためにレプリカを利用する前に、トレードオフを理解することが重要です。
:::

## リードレプリカへのクエリ方法

### グローバルレプリカクレデンシャルの作成
グローバルレプリカクレデンシャルを使用すると、クエリを自動的にブランチのレプリカやリードオンリーリージョンにルーティングできます。

#### 手順:
1. PlanetScaleダッシュボードで新しいクレデンシャルを作成し、接続タイプとして「レプリカ」を選択します。
2. 新しいクレデンシャルの接続文字列を使用して、レプリカ専用のデータベース接続を設定します。

![Screenshot 2024-07-09 at 1.14.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1946561/3782c6a8-b0ea-e0ba-6291-a243b851152c.png)


## 高可用性
PlanetScaleのレプリカはデータベースの高可用性を実現するために使用されます。プライマリノードが障害を起こした場合、自動的に利用可能なレプリカから新しいプライマリノードが選出され、トラフィックが新しいプライマリにリルートされます。

## 複数のアベイラビリティゾーン
クラウドアーキテクチャでは、リージョンはさらにアベイラビリティゾーン（AZ）と呼ばれるデータセンターに分けられます。たとえば、AWSのus-east-1リージョンには6つのデフォルトAZがあります。PlanetScaleのスケーラープロおよびエンタープライズデータベースのインフラは、3つのAZに分散されています。AZ障害が発生した場合、データベースは利用可能なAZに自動フェイルオーバーします。

## データの一貫性とレプリケーションラグ
プライマリノードでデータが更新されると、その変更はすぐにレプリカに同期されますが、少しの遅延があります。この遅延をレプリケーションラグと呼びます。レプリカからデータをクエリする際には、レプリケーションラグを考慮することが重要です。

## いつレプリカを使用するべきか
レプリカは、読み込みが多いワークロードをプライマリノードからオフロードするのに役立ちます。例えば、スケジュールされたジョブ、分析ジョブ、検索機能、集計クエリなどでレプリカを使用できます。

## PlanetScaleでのレプリカの使用
PlanetScaleでは、すべてのプロダクションデータベースブランチにレプリカが使用されています。データベースのプランによってレプリカの数は異なります。

- **Scaler Pro:** 各プロダクションブランチに2つのレプリカが含まれ、複数のAZに分散されています。
- **Enter Prise:** カスタマイズ可能で、必要に応じて任意の数のレプリカを持つことができます。

:::note warn
開発ブランチにはレプリカがありません。開発ブランチは開発目的のみで使用され、プロダクションブランチと同じレジリエンスを持ちません。
:::


## まとめ
PlanetScaleのリードレプリカを使用することで、データベースのパフォーマンスと可用性を大幅に向上させることができます。特に読み込みが多いワークロードに対して有効であり、データの一貫性とレプリケーションラグに注意を払いながら使用することが重要です。ぜひPlanetScaleのリードレプリカを試してみてください。
[TypeScript] LINE Messaging APIを使うときは署名を検証しよう

# LINE Messaging APIの署名の検証とは

LINE Messaging APIについて、公式サイトには以下のような記述があります。

> ## 署名を検証する
> リクエストがLINEプラットフォームから送られたことを確認するために、ボットサーバーでリクエストヘッダーの`x-line-signature`に含まれる署名を検証します。
>
> 検証の手順は以下のとおりです。
>
> 1. リクエストボディのダイジェストを計算します。チャネルシークレットを秘密鍵としてHMAC-SHA256アルゴリズムを使用します。
> 1. ダイジェストをBase64エンコードし、リクエストヘッダーの`x-line-signature`に含まれる署名と一致するかどうかを確認します。
>
> https://developers.line.biz/ja/reference/messaging-api/#signature-validation

上記のように、webhookのPOSTリクエストが本当にLINEから送られてきたものかを確かめる必要があります。これが署名の検証と呼ばれる処理です。

TypeScript(JavaScript)を用いて署名の検証を行う方法には、以下の2つがあります。

# 署名の検証方法1: expressミドルウェアを使う

LINEは[公式のTypeScript SDK](https://line.github.io/line-bot-sdk-nodejs/)を提供しています。
この公式SDKの中に、expressミドルウェアとして使うことができる関数があります。

```ts
// https://line.github.io/line-bot-sdk-nodejs/guide/webhook.html
import express from 'express'
import { middleware } from '@line/bot-sdk'

const app = express()

const config = {
  channelSecret: 'YOUR_CHANNEL_SECRET'
}

app.post('/webhook', middleware(config), (req, res) => {
  req.body.events // webhook event objects from LINE Platform
  req.body.destination // user ID of the bot
  ...
})

app.listen(8080)
```

# 方法2: express以外で署名の検証をする

expressを使っている場合は方法1のミドルウェアでよいのですが、express以外のライブラリを使ってサーバーを立てている場合は、同じく公式SDKの中にある`validateSignature`関数を使います。

```ts
import {
  messagingApi,
  SignatureValidationFailed,
  validateSignature,
  type WebhookRequestBody,
} from "npm:@line/bot-sdk@9.2.2";

// チャネル基本設定の「チャネルシークレット」の値
const CHANNEL_SECRET = process.env.CHANNEL_SECRET;

app.post("/webhook", req => {

  // POSTのrequest bodyを文字列で取得
  const body = await await req.text();
  // x-line-signatureヘッダーを取得
  const signature = req.header("x-line-signature")!;
  // 署名を検証し、LINEから送られたものではないと判断したらエラーを投げる
  if (!validateSignature(body, CHANNEL_SECRET, signature)) {
    throw new SignatureValidationFailed("signature validation failed", {
      signature,
    });
  }

  // 以下、返信処理など
  const data = JSON.parse(body);
  ...
});
```

まず`validateSignature`関数を呼びだし、署名の検証を行います。
引数は

- `body`（リクエスト本文）
- `CHANNEL_SECRET`（LINEから提供されるチャネルシークレット）
- `signature`（`x-line-signature`ヘッダーの値）

です。
この関数は署名の検証に成功した場合`true`を、失敗した場合`false`を返します。

署名の検証に失敗した場合はエラーにします。LINEのSDKは、署名に失敗した場合のエラーを表す`SignatureValidationFailed`エラーを提供しているので、これをthrowしてあげるようにします。

# まとめ

LINE Messaging APIを使うときは、webhookが本当にLINEから送信されたものかを検証するために、署名の検証が必要です。
公式のSDKを使うと実装が楽になるのでおすすめです！